diff --git a/apps/dojo/e2e/tests/langchainTests/agenticChatPage.spec.ts b/apps/dojo/e2e/tests/langchainTests/agenticChatPage.spec.ts new file mode 100644 index 000000000..3cdddaa46 --- /dev/null +++ b/apps/dojo/e2e/tests/langchainTests/agenticChatPage.spec.ts @@ -0,0 +1,115 @@ +import { + test, + expect, + waitForAIResponse, + retryOnAIFailure, +} from "../../test-isolation-helper"; +import { AgenticChatPage } from "../../featurePages/AgenticChatPage"; + +test("[LangChain] Agentic Chat sends and receives a message", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto( + "/langchain/feature/agentic_chat" + ); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.isVisible; + await chat.sendMessage("Hi, I am duaa"); + + await waitForAIResponse(page); + await chat.assertUserMessageVisible("Hi, I am duaa"); + await chat.assertAgentReplyVisible(/Hello/i); + }); +}); + +test("[LangChain] Agentic Chat changes background on message and reset", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto( + "/langchain/feature/agentic_chat" + ); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + // Store initial background color + const backgroundContainer = page.locator('[data-testid="background-container"]') + const initialBackground = await backgroundContainer.evaluate(el => getComputedStyle(el).backgroundColor); + console.log("Initial background color:", initialBackground); + + // 1. Send message to change background to blue + await chat.sendMessage("Hi change the background color to blue"); + await chat.assertUserMessageVisible( + "Hi change the background color to blue" + ); + await waitForAIResponse(page); + + await expect(backgroundContainer).not.toHaveCSS('background-color', initialBackground, { timeout: 7000 }); + const backgroundBlue = await backgroundContainer.evaluate(el => getComputedStyle(el).backgroundColor); + // Check if background is blue (string color name or contains blue) + expect(backgroundBlue.toLowerCase()).toMatch(/blue|rgb\(.*,.*,.*\)|#[0-9a-f]{6}/); + + // 2. Change to pink + await chat.sendMessage("Hi change the background color to pink"); + await chat.assertUserMessageVisible( + "Hi change the background color to pink" + ); + await waitForAIResponse(page); + + await expect(backgroundContainer).not.toHaveCSS('background-color', backgroundBlue, { timeout: 7000 }); + const backgroundPink = await backgroundContainer.evaluate(el => getComputedStyle(el).backgroundColor); + // Check if background is pink (string color name or contains pink) + expect(backgroundPink.toLowerCase()).toMatch(/pink|rgb\(.*,.*,.*\)|#[0-9a-f]{6}/); + }); +}); + +test("[LangChain] Agentic Chat retains memory of user messages during a conversation", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto( + "/langchain/feature/agentic_chat" + ); + + const chat = new AgenticChatPage(page); + await chat.openChat(); + await chat.agentGreeting.click(); + + await chat.sendMessage("Hey there"); + await chat.assertUserMessageVisible("Hey there"); + await waitForAIResponse(page); + await chat.assertAgentReplyVisible(/how can I assist you/i); + + const favFruit = "Mango"; + await chat.sendMessage(`My favorite fruit is ${favFruit}`); + await chat.assertUserMessageVisible(`My favorite fruit is ${favFruit}`); + await waitForAIResponse(page); + await chat.assertAgentReplyVisible(new RegExp(favFruit, "i")); + + await chat.sendMessage("and I love listening to Kaavish"); + await chat.assertUserMessageVisible("and I love listening to Kaavish"); + await waitForAIResponse(page); + await chat.assertAgentReplyVisible(/Kaavish/i); + + await chat.sendMessage("tell me an interesting fact about Moon"); + await chat.assertUserMessageVisible( + "tell me an interesting fact about Moon" + ); + await waitForAIResponse(page); + await chat.assertAgentReplyVisible(/Moon/i); + + await chat.sendMessage("Can you remind me what my favorite fruit is?"); + await chat.assertUserMessageVisible( + "Can you remind me what my favorite fruit is?" + ); + await waitForAIResponse(page); + await chat.assertAgentReplyVisible(new RegExp(favFruit, "i")); + }); +}); diff --git a/apps/dojo/e2e/tests/langchainTests/toolBasedGenUIPage.spec.ts b/apps/dojo/e2e/tests/langchainTests/toolBasedGenUIPage.spec.ts new file mode 100644 index 000000000..d6d7e1e09 --- /dev/null +++ b/apps/dojo/e2e/tests/langchainTests/toolBasedGenUIPage.spec.ts @@ -0,0 +1,38 @@ +import { test, expect } from "@playwright/test"; +import { ToolBaseGenUIPage } from "../../featurePages/ToolBaseGenUIPage"; + +const pageURL = + "/langchain/feature/tool_based_generative_ui"; + +test('[LangChain] Haiku generation and display verification', async ({ + page, +}) => { + await page.goto(pageURL); + + const genAIAgent = new ToolBaseGenUIPage(page); + + await expect(genAIAgent.haikuAgentIntro).toBeVisible(); + await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); + await genAIAgent.checkGeneratedHaiku(); + await genAIAgent.checkHaikuDisplay(page); +}); + +test('[LangChain] Haiku generation and UI consistency for two different prompts', async ({ + page, +}) => { + await page.goto(pageURL); + + const genAIAgent = new ToolBaseGenUIPage(page); + + await expect(genAIAgent.haikuAgentIntro).toBeVisible(); + + const prompt1 = 'Generate Haiku for "I will always win"'; + await genAIAgent.generateHaiku(prompt1); + await genAIAgent.checkGeneratedHaiku(); + await genAIAgent.checkHaikuDisplay(page); + + const prompt2 = 'Generate Haiku for "The moon shines bright"'; + await genAIAgent.generateHaiku(prompt2); + await genAIAgent.checkGeneratedHaiku(); + await genAIAgent.checkHaikuDisplay(page); +}); \ No newline at end of file diff --git a/apps/dojo/package.json b/apps/dojo/package.json index 1e2d14faa..e7ad4aaea 100644 --- a/apps/dojo/package.json +++ b/apps/dojo/package.json @@ -19,6 +19,7 @@ "@ag-ui/agno": "workspace:*", "@ag-ui/crewai": "workspace:*", "@ag-ui/langgraph": "workspace:*", + "@ag-ui/langchain": "workspace:*", "@ag-ui/llamaindex": "workspace:*", "@ag-ui/mastra": "workspace:*", "@ag-ui/middleware-starter": "workspace:*", @@ -37,6 +38,7 @@ "@copilotkitnext/react": "0.0.19-alpha.0", "@copilotkitnext/runtime": "0.0.19-alpha.0", "@copilotkitnext/agent": "0.0.19-alpha.0", + "@langchain/openai": "1.0.0", "@mastra/client-js": "^0.15.2", "@mastra/core": "^0.20.2", "@mastra/dynamodb": "^0.15.6", diff --git a/apps/dojo/src/agents.ts b/apps/dojo/src/agents.ts index 3521d1ef8..55e36428f 100644 --- a/apps/dojo/src/agents.ts +++ b/apps/dojo/src/agents.ts @@ -22,6 +22,7 @@ import { A2AMiddlewareAgent } from "@ag-ui/a2a-middleware"; import { AWSStrandsAgent } from "@ag-ui/aws-strands-integration"; import { A2AAgent } from "@ag-ui/a2a"; import { A2AClient } from "@a2a-js/sdk/client"; +import { LangChainAgent } from "@ag-ui/langchain"; const envVars = getEnvVars(); export const agentsIntegrations: AgentIntegrationConfig[] = [ @@ -264,6 +265,35 @@ export const agentsIntegrations: AgentIntegrationConfig[] = [ }; }, }, + { + id: "langchain", + agents: async () => { + return { + agentic_chat: new LangChainAgent({ + chainFn: async ({ messages, tools, threadId }) => { + // @ts-ignore + const { ChatOpenAI } = await import("@langchain/openai"); + const chatOpenAI = new ChatOpenAI({ model: "gpt-4o" }); + const model = chatOpenAI.bindTools(tools, { + strict: true, + }); + return model.stream(messages, { tools, metadata: { conversation_id: threadId } }); + }, + }), + tool_based_generative_ui: new LangChainAgent({ + chainFn: async ({ messages, tools, threadId }) => { + // @ts-ignore + const { ChatOpenAI } = await import("@langchain/openai"); + const chatOpenAI = new ChatOpenAI({ model: "gpt-4o" }); + const model = chatOpenAI.bindTools(tools, { + strict: true, + }); + return model.stream(messages, { tools, metadata: { conversation_id: threadId } }); + }, + }), + } + }, + }, { id: "agno", agents: async () => { diff --git a/apps/dojo/src/menu.ts b/apps/dojo/src/menu.ts index 059215919..7ae22c92b 100644 --- a/apps/dojo/src/menu.ts +++ b/apps/dojo/src/menu.ts @@ -44,6 +44,14 @@ export const menuIntegrations: MenuIntegrationConfig[] = [ "subgraphs", ], }, + { + id: "langchain", + name: "LangChain", + features: [ + "agentic_chat", + "tool_based_generative_ui", + ], + }, { id: "mastra", name: "Mastra", diff --git a/integrations/langchain/typescript/.gitignore b/integrations/langchain/typescript/.gitignore new file mode 100644 index 000000000..0ccb8df8d --- /dev/null +++ b/integrations/langchain/typescript/.gitignore @@ -0,0 +1,141 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.* +!.env.example + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist +.output + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Sveltekit cache directory +.svelte-kit/ + +# vitepress build output +**/.vitepress/dist + +# vitepress cache directory +**/.vitepress/cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# Firebase cache directory +.firebase/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v3 +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# Vite files +vite.config.js.timestamp-* +vite.config.ts.timestamp-* +.vite/ diff --git a/integrations/langchain/typescript/.npmignore b/integrations/langchain/typescript/.npmignore new file mode 100644 index 000000000..ea7bb08e6 --- /dev/null +++ b/integrations/langchain/typescript/.npmignore @@ -0,0 +1,13 @@ +.turbo +.DS_Store +.git +.gitignore +.idea +.vscode +.env +__tests__ +src +tsup.config.ts +tsconfig.json +jest.config.js +example diff --git a/integrations/langchain/typescript/README.md b/integrations/langchain/typescript/README.md new file mode 100644 index 000000000..58a8d6e61 --- /dev/null +++ b/integrations/langchain/typescript/README.md @@ -0,0 +1,30 @@ +# @ag-ui/langchain + +Implementation of the AG-UI protocol for LangChain. + +## Installation + +```bash +npm install @ag-ui/langchain +pnpm add @ag-ui/langchain +yarn add @ag-ui/langchain +``` + +## Usage + +```ts +import { LangChainAgent } from "@ag-ui/langchain"; + +// Create an AG-UI compatible agent +const agent = new LangChainAgent({ + chainFn: async ({ messages, tools, threadId }) => { + // Your chosen llm model + const { ChatOpenAI } = await import("@langchain/openai"); + const chatOpenAI = new ChatOpenAI({ model: "gpt-4o" }); + const model = chatOpenAI.bindTools(tools, { + strict: true, + }); + return model.stream(messages, { tools, metadata: { conversation_id: threadId } }); + }, +}) +``` diff --git a/integrations/langchain/typescript/jest.config.js b/integrations/langchain/typescript/jest.config.js new file mode 100644 index 000000000..0521f8d91 --- /dev/null +++ b/integrations/langchain/typescript/jest.config.js @@ -0,0 +1,10 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", + testMatch: ["**/*.test.ts"], + passWithNoTests: true, + moduleNameMapper: { + "^@/(.*)$": "/src/$1", + }, +}; diff --git a/integrations/langchain/typescript/package.json b/integrations/langchain/typescript/package.json new file mode 100644 index 000000000..136740ed5 --- /dev/null +++ b/integrations/langchain/typescript/package.json @@ -0,0 +1,45 @@ +{ + "name": "@ag-ui/langchain", + "version": "0.0.1", + "license": "Apache-2.0", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "sideEffects": false, + "private": false, + "publishConfig": { + "access": "public" + }, + "files": [ + "dist/**", + "README.md" + ], + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "clean": "rm -rf dist .turbo node_modules", + "typecheck": "tsc --noEmit", + "test": "jest", + "link:global": "pnpm link --global", + "unlink:global": "pnpm unlink --global" + }, + "dependencies": { + "@langchain/core": "^0.3.79", + "rxjs": "7.8.1" + }, + "peerDependencies": { + "@ag-ui/core": ">=0.0.42", + "@ag-ui/client": ">=0.0.42", + "zod": "^3.25.67" + }, + "devDependencies": { + "@ag-ui/core": "workspace:*", + "@ag-ui/client": "workspace:*", + "@types/jest": "^29.5.14", + "@types/node": "^20.11.19", + "jest": "^29.7.0", + "ts-jest": "^29.1.2", + "tsup": "^8.0.2", + "typescript": "^5.3.3" + } +} diff --git a/integrations/langchain/typescript/src/agent.ts b/integrations/langchain/typescript/src/agent.ts new file mode 100644 index 000000000..638c5e0d6 --- /dev/null +++ b/integrations/langchain/typescript/src/agent.ts @@ -0,0 +1,264 @@ +import { + AbstractAgent, + BaseEvent, + RunAgentInput, + EventType, + RunStartedEvent, + RunFinishedEvent, + RunErrorEvent, +} from "@ag-ui/client"; +import { BaseChatModel } from "@langchain/core/language_models/chat_models"; +import { BaseMessage } from "@langchain/core/messages"; +import { DynamicStructuredTool } from "@langchain/core/tools"; +import { LangChainResponse, streamLangChainResponse } from "./streaming"; +import { convertAGUIToolsToLangChain } from "./tools"; +import { Observable } from "rxjs"; +import { convertAGUIMessagesToLangChain } from "./messages"; + +/** + * Parameters passed to chainFn callback + */ +export interface ChainFnParams { + /** + * Converted LangChain messages + */ + messages: BaseMessage[]; + /** + * Converted LangChain tools + */ + tools: DynamicStructuredTool[]; + /** + * Application state (can be edited via state tools) + */ + state?: any; + /** + * Application context + */ + context: Array<{ description: string; value: string }>; + /** + * Thread ID + */ + threadId: string; + /** + * Run ID + */ + runId: string; +} + +/** + * Configuration for advanced usage with custom LangChain logic + */ +export interface LangChainAgentChainFnConfig { + /** + * Custom function that handles LangChain execution + * This allows full control over chains, graphs, and custom logic + */ + chainFn: (params: ChainFnParams) => Promise | LangChainResponse; +} + +/** + * Configuration for simple usage with direct model + */ +export interface LangChainAgentModelConfig { + /** + * LangChain chat model instance + */ + model: BaseChatModel; + /** + * Optional system prompt + */ + prompt?: string; + /** + * Options to pass to bindTools() + */ + bindToolsOptions?: Record; +} + +/** + * Dual configuration: either chainFn OR model + */ +export type LangChainAgentConfig = LangChainAgentChainFnConfig | LangChainAgentModelConfig; + +/** + * Type guard to check if config uses chainFn pattern + */ +function isChainFnConfig(config: LangChainAgentConfig): config is LangChainAgentChainFnConfig { + return "chainFn" in config; +} + +/** + * LangChain Agent - bridges AG-UI and LangChain ecosystems + * + * Supports two usage patterns: + * + * 1. Advanced (chainFn): Full control over LangChain execution + * ```typescript + * new LangChainAgent({ + * chainFn: async ({ messages, tools }) => { + * const model = new ChatOpenAI({ model: "gpt-4" }); + * return model.bindTools(tools).stream(messages); + * } + * }) + * ``` + * + * 2. Simple (model): Direct model usage with automatic plumbing + * ```typescript + * new LangChainAgent({ + * model: new ChatOpenAI({ model: "gpt-4" }), + * prompt: "You are a helpful assistant" + * }) + * ``` + */ +export class LangChainAgent extends AbstractAgent { + private abortController?: AbortController; + + constructor(private config: LangChainAgentConfig) { + super(); + } + + public run(input: RunAgentInput): Observable { + return new Observable((subscriber) => { + // Emit RUN_STARTED + const startEvent: RunStartedEvent = { + type: EventType.RUN_STARTED, + threadId: input.threadId, + runId: input.runId, + }; + subscriber.next(startEvent); + + // Set up abort controller + const abortController = new AbortController(); + this.abortController = abortController; + + // Execute async logic + (async () => { + try { + // Convert AG-UI messages to LangChain messages + const langchainMessages = convertAGUIMessagesToLangChain(input.messages); + + // Add system message if using model config with prompt + if (!isChainFnConfig(this.config) && this.config.prompt) { + const systemPrompt = this.buildSystemPrompt( + this.config.prompt, + input.context, + input.state + ); + langchainMessages.unshift({ + content: systemPrompt, + getType: () => "system", + } as BaseMessage); + } + + // Convert AG-UI tools to LangChain tools + const langchainTools = convertAGUIToolsToLangChain(input.tools as any[]); + + let response: LangChainResponse; + + // Execute based on configuration pattern + if (isChainFnConfig(this.config)) { + // Pattern A: User-provided chainFn + response = await this.config.chainFn({ + messages: langchainMessages, + tools: langchainTools, + state: input.state, + context: input.context, + threadId: input.threadId, + runId: input.runId, + }); + } else { + // Pattern B: Direct model usage + const modelConfig = this.config as LangChainAgentModelConfig; + const boundModel = modelConfig.bindToolsOptions + ? modelConfig.model.bindTools?.(langchainTools, modelConfig.bindToolsOptions) + : modelConfig.model.bindTools?.(langchainTools); + + const model = boundModel || modelConfig.model; + response = await model.stream(langchainMessages, { + signal: abortController.signal, + }); + } + + // Stream the response and emit AG-UI events + for await (const event of streamLangChainResponse(response)) { + if (abortController.signal.aborted) { + break; + } + subscriber.next(event); + } + + // Emit RUN_FINISHED if not aborted + if (!abortController.signal.aborted) { + const finishedEvent: RunFinishedEvent = { + type: EventType.RUN_FINISHED, + threadId: input.threadId, + runId: input.runId, + }; + subscriber.next(finishedEvent); + } + + subscriber.complete(); + } catch (error) { + if (!abortController.signal.aborted) { + const errorEvent: RunErrorEvent = { + type: EventType.RUN_ERROR, + message: error instanceof Error ? error.message : String(error), + }; + subscriber.next(errorEvent); + subscriber.error(error); + } else { + subscriber.complete(); + } + } finally { + this.abortController = undefined; + } + })(); + + // Cleanup function + return () => { + abortController.abort(); + }; + }); + } + + /** + * Build system prompt with context and state + */ + private buildSystemPrompt( + prompt: string, + context: Array<{ description: string; value: string }>, + state?: any + ): string { + const parts: string[] = [prompt]; + + // Add context if present + if (context && context.length > 0) { + parts.push("\n## Context from the application\n"); + for (const ctx of context) { + parts.push(`${ctx.description}:\n${ctx.value}\n`); + } + } + + // Add state if present + if (state !== undefined && state !== null) { + const hasState = + typeof state !== "object" || Object.keys(state).length > 0; + if (hasState) { + parts.push( + "\n## Application State\n" + + "This is state from the application.\n" + + `\`\`\`json\n${JSON.stringify(state, null, 2)}\n\`\`\`\n` + ); + } + } + + return parts.join(""); + } + + clone(): LangChainAgent { + return new LangChainAgent(this.config); + } + + abortRun(): void { + this.abortController?.abort(); + } +} diff --git a/integrations/langchain/typescript/src/index.ts b/integrations/langchain/typescript/src/index.ts new file mode 100644 index 000000000..0e9df98d1 --- /dev/null +++ b/integrations/langchain/typescript/src/index.ts @@ -0,0 +1 @@ +export * from './agent' \ No newline at end of file diff --git a/integrations/langchain/typescript/src/messages.ts b/integrations/langchain/typescript/src/messages.ts new file mode 100644 index 000000000..2a82522c6 --- /dev/null +++ b/integrations/langchain/typescript/src/messages.ts @@ -0,0 +1,67 @@ +import { Message } from "@ag-ui/client"; +import { + BaseMessage, + HumanMessage, + AIMessage, + SystemMessage, + ToolMessage, +} from "@langchain/core/messages"; + +/** + * Converts AG-UI Message to LangChain BaseMessage + */ +export function convertAGUIMessageToLangChain(message: Message): BaseMessage { + // User message + if (message.role === "user") { + // Handle string content + if (typeof message.content === "string") { + return new HumanMessage(message.content); + } + // Handle array content (extract text parts) + if (Array.isArray(message.content)) { + const textContent = message.content + .filter((part: any) => part.type === "text") + .map((part: any) => part.text) + .join("\n"); + return new HumanMessage(textContent); + } + return new HumanMessage(""); + } + + // Assistant message + if (message.role === "assistant") { + const toolCalls = message.toolCalls?.map((tc) => ({ + id: tc.id, + name: tc.function.name, + args: JSON.parse(tc.function.arguments), + })) || []; + + return new AIMessage({ + content: message.content || "", + tool_calls: toolCalls.length > 0 ? toolCalls : undefined, + }); + } + + // Tool/Function result message + if (message.role === "tool") { + return new ToolMessage({ + content: message.content, + tool_call_id: message.toolCallId, + }); + } + + // System message + if (message.role === "system") { + return new SystemMessage(message.content as string); + } + + // Fallback - treat as human message + return new HumanMessage(String(message.content || "")); +} + +/** + * Converts array of AG-UI Messages to LangChain BaseMessages + */ +export function convertAGUIMessagesToLangChain(messages: Message[]): BaseMessage[] { + return messages.map(convertAGUIMessageToLangChain); +} diff --git a/integrations/langchain/typescript/src/streaming.ts b/integrations/langchain/typescript/src/streaming.ts new file mode 100644 index 000000000..4f3555ca0 --- /dev/null +++ b/integrations/langchain/typescript/src/streaming.ts @@ -0,0 +1,274 @@ +import { + EventType, + TextMessageChunkEvent, + ToolCallStartEvent, + ToolCallArgsEvent, + ToolCallEndEvent, + ToolCallResultEvent, + BaseEvent, +} from "@ag-ui/client"; +import { + AIMessage, + AIMessageChunk, + BaseMessageChunk, +} from "@langchain/core/messages"; +import { IterableReadableStream } from "@langchain/core/utils/stream"; +import { randomUUID } from "crypto"; + +/** + * LangChain response types that can be returned from chainFn + */ +export type LangChainResponse = + | string + | AIMessage + | AIMessageChunk + | BaseMessageChunk + | IterableReadableStream + | IterableReadableStream; + +/** + * Helper type guards + */ +function isAIMessage(obj: any): obj is AIMessage { + return obj?.constructor?.name === "AIMessage"; +} + +function isAIMessageChunk(obj: any): obj is AIMessageChunk { + return obj?.constructor?.name === "AIMessageChunk"; +} + +function isBaseMessageChunk(obj: any): obj is BaseMessageChunk { + return obj?.constructor?.name === "BaseMessageChunk"; +} + +function isStream(obj: any): obj is IterableReadableStream { + return obj && typeof obj.getReader === "function"; +} + +/** + * Converts LangChain response to AG-UI events + */ +export async function* streamLangChainResponse( + response: LangChainResponse +): AsyncGenerator { + // 1. Handle string response + if (typeof response === "string") { + const messageId = randomUUID(); + yield { + type: EventType.TEXT_MESSAGE_CHUNK, + role: "assistant", + messageId, + delta: response, + } as TextMessageChunkEvent; + return; + } + + // 2. Handle AIMessage (complete message with content and tool calls) + if (isAIMessage(response)) { + const messageId = randomUUID(); + + // Emit text content if present + if (response.content) { + yield { + type: EventType.TEXT_MESSAGE_CHUNK, + role: "assistant", + messageId, + delta: String(response.content), + } as TextMessageChunkEvent; + } + + // Emit tool calls if present + if (response.tool_calls && response.tool_calls.length > 0) { + for (const toolCall of response.tool_calls) { + const toolCallId = toolCall.id || randomUUID(); + + yield { + type: EventType.TOOL_CALL_START, + parentMessageId: messageId, + toolCallId, + toolCallName: toolCall.name, + } as ToolCallStartEvent; + + yield { + type: EventType.TOOL_CALL_ARGS, + toolCallId, + delta: JSON.stringify(toolCall.args), + } as ToolCallArgsEvent; + + yield { + type: EventType.TOOL_CALL_END, + toolCallId, + } as ToolCallEndEvent; + } + } + return; + } + + // 3. Handle BaseMessageChunk (single chunk) + if (isBaseMessageChunk(response)) { + if (response.content) { + const messageId = randomUUID(); + yield { + type: EventType.TEXT_MESSAGE_CHUNK, + role: "assistant", + messageId, + delta: String(response.content), + } as TextMessageChunkEvent; + } + return; + } + + // 4. Handle streaming responses + if (isStream(response)) { + const reader = response.getReader(); + let mode: "text" | "tool" | null = null; + let currentMessageId = randomUUID(); + let currentToolCallId: string | undefined; + let currentToolCallName: string | undefined; + + // Tool call tracking + const toolCallState = { + id: null as string | null, + name: null as string | null, + index: null as number | null, + prevIndex: null as number | null, + }; + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + let hasToolCall = false; + let toolCallId: string | undefined; + let toolCallName: string | undefined; + let toolCallArgs: string | undefined; + let textContent = ""; + + // Extract content from the chunk + if (value && value.content) { + textContent = Array.isArray(value.content) + ? ((value.content[0] as any)?.text ?? "") + : String(value.content); + } + + // Check for tool calls in AIMessageChunk + if (isAIMessageChunk(value)) { + const chunk = value.tool_call_chunks?.[0]; + if (chunk) { + hasToolCall = true; + toolCallArgs = chunk.args; + if (chunk.name) toolCallState.name = chunk.name; + if (chunk.index != null) { + toolCallState.index = chunk.index; + if (toolCallState.prevIndex == null) { + toolCallState.prevIndex = chunk.index; + } + } + if (chunk.id) { + toolCallState.id = + chunk.index != null ? `${chunk.id}-idx-${chunk.index}` : chunk.id; + } + toolCallName = toolCallState.name || undefined; + toolCallId = toolCallState.id || undefined; + } + } + // Check for tool calls in BaseMessageChunk + else if (isBaseMessageChunk(value)) { + const chunk = (value as any).additional_kwargs?.tool_calls?.[0]; + if (chunk?.function) { + hasToolCall = true; + toolCallName = chunk.function.name; + toolCallId = chunk.id; + toolCallArgs = chunk.function.arguments; + } + } + + // Mode transitions + if (mode === "text" && (hasToolCall || done)) { + mode = null; + } else if (mode === "tool" && (!hasToolCall || done)) { + if (currentToolCallId) { + yield { + type: EventType.TOOL_CALL_END, + toolCallId: currentToolCallId, + } as ToolCallEndEvent; + } + mode = null; + } + + // Start new mode + if (mode === null) { + if (hasToolCall && toolCallId && toolCallName) { + mode = "tool"; + currentToolCallId = toolCallId; + currentToolCallName = toolCallName; + + yield { + type: EventType.TOOL_CALL_START, + parentMessageId: currentMessageId, + toolCallId, + toolCallName, + } as ToolCallStartEvent; + } else if (textContent) { + mode = "text"; + // Text chunks don't need explicit start event in AG-UI + } + } + + // Emit content + if (mode === "text" && textContent) { + yield { + type: EventType.TEXT_MESSAGE_CHUNK, + role: "assistant", + messageId: currentMessageId, + delta: textContent, + } as TextMessageChunkEvent; + } else if (mode === "tool" && toolCallArgs) { + // Handle multiple tool calls with different indices + if ( + toolCallState.index !== toolCallState.prevIndex && + currentToolCallId + ) { + yield { + type: EventType.TOOL_CALL_END, + toolCallId: currentToolCallId, + } as ToolCallEndEvent; + + currentToolCallId = toolCallId; + yield { + type: EventType.TOOL_CALL_START, + parentMessageId: currentMessageId, + toolCallId: currentToolCallId!, + toolCallName: currentToolCallName!, + } as ToolCallStartEvent; + + toolCallState.prevIndex = toolCallState.index; + } + + yield { + type: EventType.TOOL_CALL_ARGS, + toolCallId: currentToolCallId!, + delta: toolCallArgs, + } as ToolCallArgsEvent; + } + } + + // Final cleanup + if (mode === "tool" && currentToolCallId) { + yield { + type: EventType.TOOL_CALL_END, + toolCallId: currentToolCallId, + } as ToolCallEndEvent; + } + } finally { + reader.releaseLock(); + } + return; + } + + // Unsupported type - throw error + throw new Error( + `Unsupported LangChain response type: ${typeof response}` + ); +} diff --git a/integrations/langchain/typescript/src/tools.ts b/integrations/langchain/typescript/src/tools.ts new file mode 100644 index 000000000..27d5846ea --- /dev/null +++ b/integrations/langchain/typescript/src/tools.ts @@ -0,0 +1,97 @@ +import { DynamicStructuredTool } from "@langchain/core/tools"; +import { z } from "zod"; + +/** + * JSON Schema type definition + */ +interface JsonSchema { + type: "object" | "string" | "number" | "boolean" | "array"; + description?: string; + properties?: Record; + required?: string[]; + items?: JsonSchema; +} + +/** + * AG-UI Tool definition + */ +interface AGUITool { + name: string; + description: string; + parameters: JsonSchema; +} + +/** + * Converts JSON Schema to Zod schema + */ +function convertJsonSchemaToZod(jsonSchema: JsonSchema, required: boolean): z.ZodSchema { + if (jsonSchema.type === "object") { + const spec: { [key: string]: z.ZodSchema } = {}; + + if (!jsonSchema.properties || !Object.keys(jsonSchema.properties).length) { + return !required ? z.object(spec).optional() : z.object(spec); + } + + for (const [key, value] of Object.entries(jsonSchema.properties)) { + spec[key] = convertJsonSchemaToZod( + value, + jsonSchema.required ? jsonSchema.required.includes(key) : false + ); + } + let schema = z.object(spec).describe(jsonSchema.description ?? ""); + return required ? schema : schema.optional(); + } else if (jsonSchema.type === "string") { + let schema = z.string().describe(jsonSchema.description ?? ""); + return required ? schema : schema.optional(); + } else if (jsonSchema.type === "number") { + let schema = z.number().describe(jsonSchema.description ?? ""); + return required ? schema : schema.optional(); + } else if (jsonSchema.type === "boolean") { + let schema = z.boolean().describe(jsonSchema.description ?? ""); + return required ? schema : schema.optional(); + } else if (jsonSchema.type === "array") { + if (!jsonSchema.items) { + throw new Error("Array type must have items property"); + } + let itemSchema = convertJsonSchemaToZod(jsonSchema.items, true); + let schema = z.array(itemSchema).describe(jsonSchema.description ?? ""); + return required ? schema : schema.optional(); + } + throw new Error("Invalid JSON schema"); +} + +export type LangChainToolWithName = { + type: "function"; + name?: string; + function: { + name: string; + description: string; + parameters: any; + }, +} + +/** + * Converts AG-UI Tool to LangChain DynamicStructuredTool + */ +export function convertAGUIToolToLangChain(tool: AGUITool): DynamicStructuredTool { + const schema = convertJsonSchemaToZod(tool.parameters, true) as z.ZodTypeAny; + + // Use explicit type annotation to avoid TS2589 "Type instantiation is excessively deep" + // caused by DynamicStructuredTool's complex generic inference + const toolInstance: DynamicStructuredTool = new (DynamicStructuredTool as any)({ + name: tool.name, + description: tool.description, + schema: schema, + func: async () => { + return ""; + }, + }); + return toolInstance; +} + +/** + * Converts array of AG-UI Tools to LangChain DynamicStructuredTools + */ +export function convertAGUIToolsToLangChain(tools: AGUITool[]): DynamicStructuredTool[] { + return tools.map(convertAGUIToolToLangChain); +} diff --git a/integrations/langchain/typescript/tsconfig.json b/integrations/langchain/typescript/tsconfig.json new file mode 100644 index 000000000..d12ec063d --- /dev/null +++ b/integrations/langchain/typescript/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "esnext", + "lib": ["dom", "dom.iterable", "esnext"], + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "moduleResolution": "node", + "skipLibCheck": true, + "strict": true, + "jsx": "react-jsx", + "esModuleInterop": true, + "resolveJsonModule": true, + "isolatedModules": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "stripInternal": true + }, + "include": ["src"], + "exclude": ["node_modules", "dist"] +} diff --git a/integrations/langchain/typescript/tsup.config.ts b/integrations/langchain/typescript/tsup.config.ts new file mode 100644 index 000000000..12b69b8fb --- /dev/null +++ b/integrations/langchain/typescript/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["cjs", "esm"], + dts: true, + splitting: false, + sourcemap: true, + clean: true, + minify: true, +}); diff --git a/integrations/langgraph/typescript/src/types.ts b/integrations/langgraph/typescript/src/types.ts index 4a8dd3d0e..7068d517d 100644 --- a/integrations/langgraph/typescript/src/types.ts +++ b/integrations/langgraph/typescript/src/types.ts @@ -1,4 +1,4 @@ -import { AssistantGraph, Message as LangGraphMessage, } from "@langchain/langgraph-sdk"; +import { AssistantGraph, Message as LangGraphMessage } from "@langchain/langgraph-sdk"; import { MessageType } from "@langchain/core/messages"; import { RunAgentInput } from "@ag-ui/core"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index beb88efcf..6e717bec3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -96,6 +96,9 @@ importers: '@ag-ui/encoder': specifier: workspace:* version: link:../../sdks/typescript/packages/encoder + '@ag-ui/langchain': + specifier: workspace:* + version: link:../../integrations/langchain/typescript '@ag-ui/langgraph': specifier: workspace:* version: link:../../integrations/langgraph/typescript @@ -153,6 +156,9 @@ importers: '@copilotkitnext/runtime': specifier: 0.0.19-alpha.0 version: 0.0.19-alpha.0(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/openai': + specifier: 1.0.0 + version: 1.0.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) '@mastra/client-js': specifier: ^0.15.2 version: 0.15.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76) @@ -515,14 +521,51 @@ importers: specifier: ^5.3.3 version: 5.9.3 + integrations/langchain/typescript: + dependencies: + '@langchain/core': + specifier: ^0.3.79 + version: 0.3.79(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)) + rxjs: + specifier: 7.8.1 + version: 7.8.1 + zod: + specifier: ^3.25.67 + version: 3.25.76 + devDependencies: + '@ag-ui/client': + specifier: workspace:* + version: link:../../../sdks/typescript/packages/client + '@ag-ui/core': + specifier: workspace:* + version: link:../../../sdks/typescript/packages/core + '@types/jest': + specifier: ^29.5.14 + version: 29.5.14 + '@types/node': + specifier: ^20.11.19 + version: 20.19.21 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.19.21) + ts-jest: + specifier: ^29.1.2 + version: 29.4.5(@babel/core@7.28.4)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.4))(jest-util@29.7.0)(jest@29.7.0)(typescript@5.9.3) + tsup: + specifier: ^8.0.2 + version: 8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + typescript: + specifier: ^5.3.3 + version: 5.9.3 + integrations/langgraph/typescript: dependencies: '@langchain/core': specifier: ^0.3.66 - version: 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + version: 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)) '@langchain/langgraph-sdk': specifier: ^0.1.2 - version: 0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) partial-json: specifier: ^0.1.7 version: 0.1.7 @@ -593,7 +636,7 @@ importers: version: 1.2.11(zod@3.25.76) '@copilotkit/runtime': specifier: ^1.10.5 - version: 1.10.6(2d84bc8b2f0c11711d75d851e921b921) + version: 1.10.6(04b824f403157fd091aba9308bdad00d) '@mastra/client-js': specifier: ^0.15.2 version: 0.15.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76) @@ -1054,8 +1097,8 @@ packages: '@ag-ui/core@0.0.40-alpha.10': resolution: {integrity: sha512-VczUym5UTwVdvJPD95z4cqSEnrygjINqrqZX4ru1gnNlf8PPmhElNPdE/ZiFEgmZAXaxzK6rI+LB6iDx5NltQA==} - '@ag-ui/core@0.0.41': - resolution: {integrity: sha512-yRSh7fweajRGAJxm2IBpC+hfkXleqq0mQOXntMk/UMEgPKWfSRMt7qHL+3mtrGEaeL4fA/rcE41cVSjFDnYSoQ==} + '@ag-ui/core@0.0.42': + resolution: {integrity: sha512-C2hMg4Gs5oiUDgK9cA2RsTwSSmFZdIsqPklDrFw/Ue+quH6EU3vKp5YoOq7nuaQYO4pO8Em+Z+l5/M5PpcvP1g==} '@ag-ui/encoder@0.0.35': resolution: {integrity: sha512-Ym0h0ZKIiD1Ld3+e3v/WQSogY62xs72ysoEBW1kt+dDs79QazBsW5ZlcBBj2DelEs9NrczQLxTVEvrkcvhrHqA==} @@ -1063,14 +1106,14 @@ packages: '@ag-ui/encoder@0.0.40-alpha.10': resolution: {integrity: sha512-aoBhFIcX+SGWzvw/FAK4+mHY6NIz5YA7DchjRCBWAyAGWrdSEObKRgPRifahOrl3hhKgSZo0MYwOin9Q33B+rg==} - '@ag-ui/encoder@0.0.41': - resolution: {integrity: sha512-eg+NUppqC/VQVIEDGD1slNEaRZ7YNVWAhfamntwyPYQnAugcY+Q14XIbROWsZ7YNipfX0cO5yb1WxFrgv1YZrw==} + '@ag-ui/encoder@0.0.42': + resolution: {integrity: sha512-97B5MMCSs82t/y41uk2NrLBYFhbvn4kYsKQHMCfy8tjSWubyxh3zP7N9yHo8zJeSPe3WvzTvclyXNiGxSOsorg==} - '@ag-ui/langgraph@0.0.19-alpha.1': - resolution: {integrity: sha512-rX8Y4LSxTXWUMFzCspO0c42b6YWGTuciP69Okrh7Lw3kpGsmFq/zmXoBLFz654Yuii2zLHl5mZvkBJ5a3nI6lA==} + '@ag-ui/langgraph@0.0.20': + resolution: {integrity: sha512-MQ35S8IUt5xwhA+NdinVJxBq3AHgpaeDrS92undC9Y3UX09HOUUojZcG46WGgZrxxqdFZNaZcupS4Opuf02DsA==} peerDependencies: - '@ag-ui/client': 0.0.40-alpha.7 - '@ag-ui/core': 0.0.40-alpha.7 + '@ag-ui/client': '>=0.0.42' + '@ag-ui/core': '>=0.0.42' '@ag-ui/proto@0.0.35': resolution: {integrity: sha512-+rz3LAYHcR3D2xVgRKa7QE5mp+cwmZs6j+1XxG5dT7HNdg51uKea12L57EVY2bxE3JzpAvCIgOjFEmQCNH82pw==} @@ -1078,8 +1121,8 @@ packages: '@ag-ui/proto@0.0.40-alpha.10': resolution: {integrity: sha512-d7FzAIjWyQzaMEZyMkTMgIyW+qK7LUg2T/MpjAGqWjjcrWGk2Zh6DU/rNMwMbYnK/YlXS3Ljo5a5gI95SrLS+Q==} - '@ag-ui/proto@0.0.41': - resolution: {integrity: sha512-YlVmS8e53EZuMG68WvjNqzxoa/8NYCy3a8yoWsogPf1iZXa1RZ2WbQTi80xGzUnzluwxGSULlg7m7a1/8eXkkA==} + '@ag-ui/proto@0.0.42': + resolution: {integrity: sha512-NDUwSgMnGEqxZGkWIJ1ge5t3Q7Kiddj360x2JAWaIfv9w+7tDJ0pmgyzf3/SXp605aY2wZiDLBtJ6jKZeg1lFg==} '@ai-sdk/anthropic@2.0.23': resolution: {integrity: sha512-ZEBiiv1UhjGjBwUU63pFhLK5LCSlNDb1idY9K1oZHm5/Fda1cuTojf32tOp0opH0RPbPAN/F8fyyNjbU33n9Kw==} @@ -2749,6 +2792,10 @@ packages: resolution: {integrity: sha512-Nn0x9erQlK3zgtRU1Z8NUjLuyW0gzdclMsvLQ6wwLeDqV91pE+YKl6uQb+L2NUDs4F0N7c2Zncgz46HxrvPzuA==} engines: {node: '>=18'} + '@langchain/core@0.3.79': + resolution: {integrity: sha512-ZLAs5YMM5N2UXN3kExMglltJrKKoW7hs3KMZFlXUnD7a5DFKBYxPFMeXA4rT+uvTxuJRZPCYX0JKI5BhyAWx4A==} + engines: {node: '>=18'} + '@langchain/google-common@0.1.8': resolution: {integrity: sha512-8auqWw2PMPhcHQHS+nMN3tVZrUPgSLckUaFeOHDOeSBiDvBd4KCybPwyl2oCwMDGvmyIxvOOckkMdeGaJ92vpQ==} engines: {node: '>=18'} @@ -2798,6 +2845,12 @@ packages: peerDependencies: '@langchain/core': '>=0.3.68 <0.4.0' + '@langchain/openai@1.0.0': + resolution: {integrity: sha512-olKEUIjb3HBOiD/NR056iGJz4wiN6HhQ/u65YmGWYadWWoKOcGwheBw/FE0x6SH4zDlI3QmP+vMhuQoaww19BQ==} + engines: {node: '>=20'} + peerDependencies: + '@langchain/core': ^1.0.0 + '@langchain/textsplitters@0.1.0': resolution: {integrity: sha512-djI4uw9rlkAb5iMhtLED+xJebDdAG935AdP4eRTB02R7OB/act55Bj9wsskhZsvuyQRpO4O1wQOp85s6T6GWmw==} engines: {node: '>=18'} @@ -8628,6 +8681,18 @@ packages: zod: optional: true + openai@6.10.0: + resolution: {integrity: sha512-ITxOGo7rO3XRMiKA5l7tQ43iNNu+iXGFAcf2t+aWVzzqRaS0i7m1K2BhxNdaveB+5eENhO0VY1FkiZzhBk4v3A==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} @@ -10434,7 +10499,7 @@ snapshots: rxjs: 7.8.1 zod: 3.25.76 - '@ag-ui/core@0.0.41': + '@ag-ui/core@0.0.42': dependencies: rxjs: 7.8.1 zod: 3.25.76 @@ -10449,17 +10514,17 @@ snapshots: '@ag-ui/core': 0.0.40-alpha.10 '@ag-ui/proto': 0.0.40-alpha.10 - '@ag-ui/encoder@0.0.41': + '@ag-ui/encoder@0.0.42': dependencies: - '@ag-ui/core': 0.0.41 - '@ag-ui/proto': 0.0.41 + '@ag-ui/core': 0.0.42 + '@ag-ui/proto': 0.0.42 - '@ag-ui/langgraph@0.0.19-alpha.1(@ag-ui/client@sdks+typescript+packages+client)(@ag-ui/core@sdks+typescript+packages+core)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@ag-ui/langgraph@0.0.20(@ag-ui/client@sdks+typescript+packages+client)(@ag-ui/core@sdks+typescript+packages+core)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@ag-ui/client': link:sdks/typescript/packages/client '@ag-ui/core': link:sdks/typescript/packages/core - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - '@langchain/langgraph-sdk': 0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@langchain/core': 0.3.79(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/langgraph-sdk': 0.1.10(@langchain/core@0.3.79(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) partial-json: 0.1.7 rxjs: 7.8.1 transitivePeerDependencies: @@ -10481,9 +10546,9 @@ snapshots: '@bufbuild/protobuf': 2.9.0 '@protobuf-ts/protoc': 2.11.1 - '@ag-ui/proto@0.0.41': + '@ag-ui/proto@0.0.42': dependencies: - '@ag-ui/core': 0.0.41 + '@ag-ui/core': 0.0.42 '@bufbuild/protobuf': 2.9.0 '@protobuf-ts/protoc': 2.11.1 @@ -11483,14 +11548,14 @@ snapshots: - encoding - utf-8-validate - '@browserbasehq/stagehand@1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@5.12.2(ws@8.18.3)(zod@3.25.76))(zod@3.25.76)': + '@browserbasehq/stagehand@1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@6.10.0(ws@8.18.3)(zod@3.25.76))(zod@3.25.76)': dependencies: '@anthropic-ai/sdk': 0.27.3 '@browserbasehq/sdk': 2.6.0 '@playwright/test': 1.56.0 deepmerge: 4.3.1 dotenv: 16.6.1 - openai: 5.12.2(ws@8.18.3)(zod@3.25.76) + openai: 6.10.0(ws@8.18.3)(zod@3.25.76) ws: 8.18.3 zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) @@ -11576,22 +11641,22 @@ snapshots: - encoding - graphql - '@copilotkit/runtime@1.10.6(2d84bc8b2f0c11711d75d851e921b921)': + '@copilotkit/runtime@1.10.6(04b824f403157fd091aba9308bdad00d)': dependencies: '@ag-ui/client': link:sdks/typescript/packages/client '@ag-ui/core': link:sdks/typescript/packages/core - '@ag-ui/encoder': 0.0.41 - '@ag-ui/langgraph': 0.0.19-alpha.1(@ag-ui/client@sdks+typescript+packages+client)(@ag-ui/core@sdks+typescript+packages+core)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@ag-ui/proto': 0.0.41 + '@ag-ui/encoder': 0.0.42 + '@ag-ui/langgraph': 0.0.20(@ag-ui/client@sdks+typescript+packages+client)(@ag-ui/core@sdks+typescript+packages+core)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@ag-ui/proto': 0.0.42 '@anthropic-ai/sdk': 0.57.0 '@copilotkit/shared': 1.10.6 '@graphql-yoga/plugin-defer-stream': 3.16.0(graphql-yoga@5.16.0(graphql@16.11.0))(graphql@16.11.0) - '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))) - '@langchain/community': 0.3.57(8d705aac09841dc81e24dfe2c773558d) + '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))) + '@langchain/community': 0.3.57(f13a6a44921299c86b5247826d9d158d) '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - '@langchain/google-gauth': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76) - '@langchain/langgraph-sdk': 0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react@19.2.0) - '@langchain/openai': 0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) + '@langchain/google-gauth': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76) + '@langchain/langgraph-sdk': 0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(react@19.2.0) + '@langchain/openai': 0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) '@scarf/scarf': 1.4.0 class-transformer: 0.5.1 class-validator: 0.14.2 @@ -11600,7 +11665,7 @@ snapshots: graphql-scalars: 1.24.2(graphql@16.11.0) graphql-yoga: 5.16.0(graphql@16.11.0) groq-sdk: 0.5.0 - langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3) + langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3) openai: 4.104.0(ws@8.18.3)(zod@3.25.76) partial-json: 0.1.7 pino: 9.13.1 @@ -12753,29 +12818,19 @@ snapshots: transitivePeerDependencies: - aws-crt - '@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))': - dependencies: - '@aws-sdk/client-bedrock-agent-runtime': 3.910.0 - '@aws-sdk/client-bedrock-runtime': 3.910.0 - '@aws-sdk/client-kendra': 3.910.0 - '@aws-sdk/credential-provider-node': 3.910.0 - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - transitivePeerDependencies: - - aws-crt - - '@langchain/community@0.3.57(8d705aac09841dc81e24dfe2c773558d)': + '@langchain/community@0.3.57(a6f05470c76b31786172bd3244671918)': dependencies: - '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@5.12.2(ws@8.18.3)(zod@3.25.76))(zod@3.25.76) + '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(zod@3.25.76) '@ibm-cloud/watsonx-ai': 1.7.0 - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) - '@langchain/weaviate': 0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) + '@langchain/weaviate': 0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))) binary-extensions: 2.3.0 expr-eval: 2.0.2 flat: 5.0.2 ibm-cloud-sdk-core: 5.4.3 js-yaml: 4.1.0 - langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3) + langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3) langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) openai: 4.104.0(ws@8.18.3)(zod@3.25.76) uuid: 10.0.0 @@ -12820,9 +12875,9 @@ snapshots: - handlebars - peggy - '@langchain/community@0.3.57(a6f05470c76b31786172bd3244671918)': + '@langchain/community@0.3.57(f13a6a44921299c86b5247826d9d158d)': dependencies: - '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(zod@3.25.76) + '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@6.10.0(ws@8.18.3)(zod@3.25.76))(zod@3.25.76) '@ibm-cloud/watsonx-ai': 1.7.0 '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) @@ -12897,14 +12952,14 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))': + '@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76))': dependencies: '@cfworker/json-schema': 4.1.1 ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -12917,17 +12972,29 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/google-common@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76)': + '@langchain/core@0.3.79(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@cfworker/json-schema': 4.1.1 + ansi-styles: 5.2.0 + camelcase: 6.3.0 + decamelize: 1.2.0 + js-tiktoken: 1.0.21 + langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)) + mustache: 4.2.0 + p-queue: 6.6.2 + p-retry: 4.6.2 uuid: 10.0.0 + zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: - - zod + - '@opentelemetry/api' + - '@opentelemetry/exporter-trace-otlp-proto' + - '@opentelemetry/sdk-trace-base' + - openai - '@langchain/google-common@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76)': + '@langchain/google-common@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76)': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) uuid: 10.0.0 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: @@ -12943,16 +13010,6 @@ snapshots: - supports-color - zod - '@langchain/google-gauth@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76)': - dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - '@langchain/google-common': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76) - google-auth-library: 8.9.0 - transitivePeerDependencies: - - encoding - - supports-color - - zod - '@langchain/langgraph-sdk@0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(react@19.2.0)': dependencies: '@types/json-schema': 7.0.15 @@ -12963,24 +13020,25 @@ snapshots: '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) react: 19.2.0 - '@langchain/langgraph-sdk@0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react@19.2.0)': + '@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@types/json-schema': 7.0.15 p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)) react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - '@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.79(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@types/json-schema': 7.0.15 p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.79(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) @@ -12995,17 +13053,6 @@ snapshots: - encoding - ws - '@langchain/openai@0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': - dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - js-tiktoken: 1.0.21 - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) - zod: 3.25.76 - zod-to-json-schema: 3.24.6(zod@3.25.76) - transitivePeerDependencies: - - encoding - - ws - '@langchain/openai@0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': dependencies: '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) @@ -13015,11 +13062,11 @@ snapshots: transitivePeerDependencies: - ws - '@langchain/openai@0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': + '@langchain/openai@1.0.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) js-tiktoken: 1.0.21 - openai: 5.12.2(ws@8.18.3)(zod@3.25.76) + openai: 6.10.0(ws@8.18.3)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - ws @@ -13029,11 +13076,6 @@ snapshots: '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) js-tiktoken: 1.0.21 - '@langchain/textsplitters@0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))': - dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - js-tiktoken: 1.0.21 - '@langchain/weaviate@0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))': dependencies: '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) @@ -13042,14 +13084,6 @@ snapshots: transitivePeerDependencies: - encoding - '@langchain/weaviate@0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))': - dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - uuid: 10.0.0 - weaviate-client: 3.9.0 - transitivePeerDependencies: - - encoding - '@libsql/client@0.15.15': dependencies: '@libsql/core': 0.15.15 @@ -18345,7 +18379,7 @@ snapshots: isstream: 0.1.2 jsonwebtoken: 9.0.2 mime-types: 2.1.35 - retry-axios: 2.6.0(axios@1.12.2) + retry-axios: 2.6.0(axios@1.12.2(debug@4.4.3)) tough-cookie: 4.1.4 transitivePeerDependencies: - supports-color @@ -19130,31 +19164,6 @@ snapshots: - openai - ws - langchain@0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3): - dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) - '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))) - js-tiktoken: 1.0.21 - js-yaml: 4.1.0 - jsonpointer: 5.0.1 - langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - openapi-types: 12.1.3 - p-retry: 4.6.2 - uuid: 10.0.0 - yaml: 2.8.1 - zod: 3.25.76 - optionalDependencies: - '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))) - axios: 1.12.2(debug@4.4.3) - handlebars: 4.7.8 - transitivePeerDependencies: - - '@opentelemetry/api' - - '@opentelemetry/exporter-trace-otlp-proto' - - '@opentelemetry/sdk-trace-base' - - openai - - ws - langium@3.3.1: dependencies: chevrotain: 11.0.3 @@ -19178,7 +19187,7 @@ snapshots: '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) openai: 4.104.0(ws@8.18.3)(zod@3.25.76) - langsmith@0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)): + langsmith@0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@6.10.0(ws@8.18.3)(zod@3.25.76)): dependencies: '@types/uuid': 10.0.0 chalk: 4.1.2 @@ -19191,7 +19200,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/exporter-trace-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) - openai: 5.12.2(ws@8.18.3)(zod@3.25.76) + openai: 6.10.0(ws@8.18.3)(zod@3.25.76) language-subtag-registry@0.3.23: {} @@ -19340,7 +19349,7 @@ snapshots: log-symbols@5.1.0: dependencies: - chalk: 5.2.0 + chalk: 5.6.2 is-unicode-supported: 1.3.0 long@5.3.2: {} @@ -20391,6 +20400,11 @@ snapshots: ws: 8.18.3 zod: 3.25.76 + openai@6.10.0(ws@8.18.3)(zod@3.25.76): + optionalDependencies: + ws: 8.18.3 + zod: 3.25.76 + openapi-types@12.1.3: {} optionator@0.9.4: @@ -21236,7 +21250,7 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 - retry-axios@2.6.0(axios@1.12.2): + retry-axios@2.6.0(axios@1.12.2(debug@4.4.3)): dependencies: axios: 1.12.2(debug@4.4.3)