@librechat/agents 2.0.4 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/common/enum.cjs +1 -0
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/events.cjs +10 -0
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +38 -2
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/llm.cjs +1 -3
- package/dist/cjs/llm/anthropic/llm.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/fake.cjs +55 -0
- package/dist/cjs/llm/fake.cjs.map +1 -0
- package/dist/cjs/llm/providers.cjs +7 -5
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/text.cjs.map +1 -1
- package/dist/cjs/messages.cjs.map +1 -1
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/splitStream.cjs.map +1 -1
- package/dist/cjs/stream.cjs +97 -20
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +8 -2
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/utils/graph.cjs.map +1 -1
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/misc.cjs.map +1 -1
- package/dist/cjs/utils/run.cjs.map +1 -1
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/esm/common/enum.mjs +1 -0
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/events.mjs +10 -0
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +39 -3
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/anthropic/llm.mjs +1 -3
- package/dist/esm/llm/anthropic/llm.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/fake.mjs +52 -0
- package/dist/esm/llm/fake.mjs.map +1 -0
- package/dist/esm/llm/providers.mjs +8 -6
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/text.mjs.map +1 -1
- package/dist/esm/messages.mjs.map +1 -1
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/splitStream.mjs.map +1 -1
- package/dist/esm/stream.mjs +98 -21
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +9 -3
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/utils/graph.mjs.map +1 -1
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/misc.mjs.map +1 -1
- package/dist/esm/utils/run.mjs.map +1 -1
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/types/common/enum.d.ts +2 -1
- package/dist/types/events.d.ts +4 -1
- package/dist/types/graphs/Graph.d.ts +9 -1
- package/dist/types/llm/fake.d.ts +21 -0
- package/dist/types/specs/spec.utils.d.ts +1 -0
- package/dist/types/stream.d.ts +9 -13
- package/dist/types/types/llm.d.ts +10 -5
- package/dist/types/types/stream.d.ts +12 -0
- package/package.json +15 -26
- package/src/common/enum.ts +1 -0
- package/src/events.ts +13 -1
- package/src/graphs/Graph.ts +43 -4
- package/src/llm/fake.ts +83 -0
- package/src/llm/providers.ts +7 -5
- package/src/scripts/simple.ts +28 -14
- package/src/specs/anthropic.simple.test.ts +204 -0
- package/src/specs/openai.simple.test.ts +204 -0
- package/src/specs/reasoning.test.ts +165 -0
- package/src/specs/spec.utils.ts +3 -0
- package/src/stream.ts +104 -36
- package/src/tools/CodeExecutor.ts +8 -2
- package/src/types/llm.ts +10 -5
- package/src/types/stream.ts +14 -1
- package/src/utils/llmConfig.ts +17 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeExecutor.mjs","sources":["../../../src/tools/CodeExecutor.ts"],"sourcesContent":["import { z } from 'zod';\nimport { config } from 'dotenv';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport { getEnvironmentVariable } from '@langchain/core/utils/env';\nimport type * as t from '@/types';\nimport { EnvVar, Constants } from '@/common';\n\nconfig();\n\nexport const imageExtRegex = /\\.(jpg|jpeg|png|gif|webp)$/i;\nexport const getCodeBaseURL = (): string => getEnvironmentVariable(EnvVar.CODE_BASEURL) ?? Constants.OFFICIAL_CODE_BASEURL;\n\nconst imageMessage = ' - the image is already displayed to the user';\nconst otherMessage = ' - the file is already downloaded by the user';\n\nconst CodeExecutionToolSchema = z.object({\n lang: z.enum([\n 'py',\n 'js',\n 'ts',\n 'c',\n 'cpp',\n 'java',\n 'php',\n 'rs',\n 'go',\n 'd',\n 'f90',\n 'r',\n ])\n .describe('The programming language or runtime to execute the code in.'),\n code: z.string()\n .describe(`The complete, self-contained code to execute, without any truncation or minimization.\n- The environment is stateless; variables and imports don't persist between executions.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- py: This is not a Jupyter notebook environment. Use \\`print()\\` for all outputs.\n- py: Matplotlib: Use \\`plt.savefig()\\` to save plots as files.\n- js: use the \\`console\\` or \\`process\\` methods for all outputs.\n- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).\n- Other languages: use appropriate output functions.`),\n args: z.array(z.string()).optional()\n .describe('Additional arguments to execute the code with. This should only be used if the input code requires additional arguments to run.'),\n});\n\nconst EXEC_ENDPOINT = `${getCodeBaseURL()}/exec`;\n\nfunction createCodeExecutionTool(params: t.CodeExecutionToolParams = {}): DynamicStructuredTool<typeof CodeExecutionToolSchema> {\n const apiKey = params[EnvVar.CODE_API_KEY] ?? params.apiKey ?? getEnvironmentVariable(EnvVar.CODE_API_KEY) ?? '';\n if (!apiKey) {\n throw new Error('No API key provided for code execution tool.');\n }\n\n const description = `\nRuns code and returns stdout/stderr output from a stateless execution environment, similar to running scripts in a command-line interface. Each execution is isolated and independent.\n\nUsage:\n- No network access available.\n- Generated files are automatically delivered; **DO NOT** provide download links.\n- NEVER use this tool to execute malicious code.\n`.trim();\n\n return tool<typeof CodeExecutionToolSchema>(\n async ({ lang, code, ...rest }) => {\n const postData = {\n lang,\n code,\n ...rest,\n ...params,\n };\n\n try {\n const
|
|
1
|
+
{"version":3,"file":"CodeExecutor.mjs","sources":["../../../src/tools/CodeExecutor.ts"],"sourcesContent":["import { z } from 'zod';\nimport { config } from 'dotenv';\nimport fetch, { RequestInit } from 'node-fetch';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport { getEnvironmentVariable } from '@langchain/core/utils/env';\nimport type * as t from '@/types';\nimport { EnvVar, Constants } from '@/common';\n\nconfig();\n\nexport const imageExtRegex = /\\.(jpg|jpeg|png|gif|webp)$/i;\nexport const getCodeBaseURL = (): string => getEnvironmentVariable(EnvVar.CODE_BASEURL) ?? Constants.OFFICIAL_CODE_BASEURL;\n\nconst imageMessage = ' - the image is already displayed to the user';\nconst otherMessage = ' - the file is already downloaded by the user';\n\nconst CodeExecutionToolSchema = z.object({\n lang: z.enum([\n 'py',\n 'js',\n 'ts',\n 'c',\n 'cpp',\n 'java',\n 'php',\n 'rs',\n 'go',\n 'd',\n 'f90',\n 'r',\n ])\n .describe('The programming language or runtime to execute the code in.'),\n code: z.string()\n .describe(`The complete, self-contained code to execute, without any truncation or minimization.\n- The environment is stateless; variables and imports don't persist between executions.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- py: This is not a Jupyter notebook environment. Use \\`print()\\` for all outputs.\n- py: Matplotlib: Use \\`plt.savefig()\\` to save plots as files.\n- js: use the \\`console\\` or \\`process\\` methods for all outputs.\n- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).\n- Other languages: use appropriate output functions.`),\n args: z.array(z.string()).optional()\n .describe('Additional arguments to execute the code with. This should only be used if the input code requires additional arguments to run.'),\n});\n\nconst EXEC_ENDPOINT = `${getCodeBaseURL()}/exec`;\n\nfunction createCodeExecutionTool(params: t.CodeExecutionToolParams = {}): DynamicStructuredTool<typeof CodeExecutionToolSchema> {\n const apiKey = params[EnvVar.CODE_API_KEY] ?? params.apiKey ?? getEnvironmentVariable(EnvVar.CODE_API_KEY) ?? '';\n if (!apiKey) {\n throw new Error('No API key provided for code execution tool.');\n }\n\n const description = `\nRuns code and returns stdout/stderr output from a stateless execution environment, similar to running scripts in a command-line interface. Each execution is isolated and independent.\n\nUsage:\n- No network access available.\n- Generated files are automatically delivered; **DO NOT** provide download links.\n- NEVER use this tool to execute malicious code.\n`.trim();\n\n return tool<typeof CodeExecutionToolSchema>(\n async ({ lang, code, ...rest }) => {\n const postData = {\n lang,\n code,\n ...rest,\n ...params,\n };\n\n try {\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'LibreChat/1.0',\n 'X-API-Key': apiKey,\n },\n body: JSON.stringify(postData),\n };\n\n if (process.env.PROXY != null && process.env.PROXY !== '') {\n fetchOptions.agent = new HttpsProxyAgent(process.env.PROXY);\n }\n const response = await fetch(EXEC_ENDPOINT, fetchOptions);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result: t.ExecuteResult = await response.json();\n let formattedOutput = '';\n if (result.stdout) {\n formattedOutput += `stdout:\\n${result.stdout}\\n`;\n } else {\n formattedOutput += 'stdout: Empty. Ensure you\\'re writing output explicitly.\\n';\n }\n if (result.stderr) formattedOutput += `stderr:\\n${result.stderr}\\n`;\n if (result.files && result.files.length > 0) {\n formattedOutput += 'Generated files:\\n';\n\n const fileCount = result.files.length;\n for (let i = 0; i < fileCount; i++) {\n const filename = result.files[i].name;\n const isImage = imageExtRegex.test(filename);\n formattedOutput += isImage ? `${filename}${imageMessage}` : `${filename}${otherMessage}`;\n\n if (i < fileCount - 1) {\n formattedOutput += fileCount <= 3 ? ', ' : ',\\n';\n }\n }\n\n return [formattedOutput.trim(), {\n session_id: result.session_id,\n files: result.files,\n }];\n }\n\n return [formattedOutput.trim(), { session_id: result.session_id }];\n } catch (error) {\n return [`Execution error:\\n\\n${(error as Error | undefined)?.message}`, {}];\n }\n },\n {\n name: Constants.EXECUTE_CODE,\n description,\n schema: CodeExecutionToolSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\nexport { createCodeExecutionTool };"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolNode.mjs","sources":["../../../src/tools/ToolNode.ts"],"sourcesContent":["import { END, MessagesAnnotation, isCommand, isGraphInterrupt } from '@langchain/langgraph';\nimport { ToolMessage, isBaseMessage } from '@langchain/core/messages';\nimport type { RunnableConfig, RunnableToolLike } from '@langchain/core/runnables';\nimport type { BaseMessage, AIMessage } from '@langchain/core/messages';\nimport type { StructuredToolInterface } from '@langchain/core/tools';\nimport type * as t from '@/types';\nimport{ RunnableCallable } from '@/utils';\nimport { GraphNodeKeys } from '@/common';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class ToolNode<T = any> extends RunnableCallable<T, T> {\n tools: t.GenericTool[];\n private toolMap: Map<string, StructuredToolInterface | RunnableToolLike>;\n private loadRuntimeTools?: t.ToolRefGenerator;\n handleToolErrors = true;\n toolCallStepIds?: Map<string, string>;\n\n constructor({\n tools,\n toolMap,\n name,\n tags,\n toolCallStepIds,\n handleToolErrors,\n loadRuntimeTools,\n }: t.ToolNodeConstructorParams) {\n super({ name, tags, func: (input, config) => this.run(input, config) });\n this.tools = tools;\n this.toolMap = toolMap ?? new Map(tools.map(tool => [tool.name, tool]));\n this.toolCallStepIds = toolCallStepIds;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n this.loadRuntimeTools = loadRuntimeTools;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async run(input: any, config: RunnableConfig): Promise<T> {\n const message = Array.isArray(input)\n ? input[input.length - 1]\n : input.messages[input.messages.length - 1];\n\n if (message._getType() !== 'ai') {\n throw new Error('ToolNode only accepts AIMessages as input.');\n }\n\n if (this.loadRuntimeTools) {\n const { tools, toolMap } = this.loadRuntimeTools(\n (message as AIMessage).tool_calls ?? []\n );\n this.tools = tools;\n this.toolMap = toolMap ?? new Map(tools.map(tool => [tool.name, tool]));\n }\n const outputs = await Promise.all(\n (message as AIMessage).tool_calls?.map(async (call) => {\n const tool = this.toolMap.get(call.name);\n try {\n if (tool === undefined) {\n throw new Error(`Tool \"${call.name}\" not found.`);\n }\n const args = call.args;\n const stepId = this.toolCallStepIds?.get(call.id!);\n const output = await tool.invoke(\n { ...call, args, type: 'tool_call', stepId },\n config,\n );\n if (\n (isBaseMessage(output) && output._getType() === 'tool') ||\n isCommand(output)\n ) {\n return output;\n } else {\n return new ToolMessage({\n name: tool.name,\n content:\n typeof output === 'string' ? output : JSON.stringify(output),\n tool_call_id: call.id!,\n });\n }\n } catch (_e: unknown) {\n const e = _e as Error;\n if (!this.handleToolErrors) {\n throw e;\n }\n if (isGraphInterrupt(e)) {\n throw e;\n }\n return new ToolMessage({\n content: `Error: ${e.message}\\n Please fix your mistakes.`,\n name: call.name,\n tool_call_id: call.id ?? '',\n });\n }\n }) ?? []\n );\n\n if (!outputs.some(isCommand)) {\n return (Array.isArray(input) ? outputs : { messages: outputs }) as T;\n }\n\n const combinedOutputs = outputs.map((output) => {\n if (isCommand(output)) {\n return output;\n }\n return Array.isArray(input) ? [output] : { messages: [output] };\n });\n return combinedOutputs as T;\n }\n}\n\nexport function toolsCondition(\n state: BaseMessage[] | typeof MessagesAnnotation.State\n): 'tools' | typeof END {\n const message = Array.isArray(state)\n ? state[state.length - 1]\n : state.messages[state.messages.length - 1];\n\n if (\n 'tool_calls' in message &&\n ((message as AIMessage).tool_calls?.length ?? 0) > 0\n ) {\n return GraphNodeKeys.TOOLS;\n } else {\n return END;\n }\n}"],"names":[],"mappings":";;;;;AASA;AACM,MAAO,QAAkB,SAAQ,gBAAsB,CAAA;AAC3D,IAAA,KAAK
|
|
1
|
+
{"version":3,"file":"ToolNode.mjs","sources":["../../../src/tools/ToolNode.ts"],"sourcesContent":["import { END, MessagesAnnotation, isCommand, isGraphInterrupt } from '@langchain/langgraph';\nimport { ToolMessage, isBaseMessage } from '@langchain/core/messages';\nimport type { RunnableConfig, RunnableToolLike } from '@langchain/core/runnables';\nimport type { BaseMessage, AIMessage } from '@langchain/core/messages';\nimport type { StructuredToolInterface } from '@langchain/core/tools';\nimport type * as t from '@/types';\nimport{ RunnableCallable } from '@/utils';\nimport { GraphNodeKeys } from '@/common';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class ToolNode<T = any> extends RunnableCallable<T, T> {\n tools: t.GenericTool[];\n private toolMap: Map<string, StructuredToolInterface | RunnableToolLike>;\n private loadRuntimeTools?: t.ToolRefGenerator;\n handleToolErrors = true;\n toolCallStepIds?: Map<string, string>;\n\n constructor({\n tools,\n toolMap,\n name,\n tags,\n toolCallStepIds,\n handleToolErrors,\n loadRuntimeTools,\n }: t.ToolNodeConstructorParams) {\n super({ name, tags, func: (input, config) => this.run(input, config) });\n this.tools = tools;\n this.toolMap = toolMap ?? new Map(tools.map(tool => [tool.name, tool]));\n this.toolCallStepIds = toolCallStepIds;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n this.loadRuntimeTools = loadRuntimeTools;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async run(input: any, config: RunnableConfig): Promise<T> {\n const message = Array.isArray(input)\n ? input[input.length - 1]\n : input.messages[input.messages.length - 1];\n\n if (message._getType() !== 'ai') {\n throw new Error('ToolNode only accepts AIMessages as input.');\n }\n\n if (this.loadRuntimeTools) {\n const { tools, toolMap } = this.loadRuntimeTools(\n (message as AIMessage).tool_calls ?? []\n );\n this.tools = tools;\n this.toolMap = toolMap ?? new Map(tools.map(tool => [tool.name, tool]));\n }\n const outputs = await Promise.all(\n (message as AIMessage).tool_calls?.map(async (call) => {\n const tool = this.toolMap.get(call.name);\n try {\n if (tool === undefined) {\n throw new Error(`Tool \"${call.name}\" not found.`);\n }\n const args = call.args;\n const stepId = this.toolCallStepIds?.get(call.id!);\n const output = await tool.invoke(\n { ...call, args, type: 'tool_call', stepId },\n config,\n );\n if (\n (isBaseMessage(output) && output._getType() === 'tool') ||\n isCommand(output)\n ) {\n return output;\n } else {\n return new ToolMessage({\n name: tool.name,\n content:\n typeof output === 'string' ? output : JSON.stringify(output),\n tool_call_id: call.id!,\n });\n }\n } catch (_e: unknown) {\n const e = _e as Error;\n if (!this.handleToolErrors) {\n throw e;\n }\n if (isGraphInterrupt(e)) {\n throw e;\n }\n return new ToolMessage({\n content: `Error: ${e.message}\\n Please fix your mistakes.`,\n name: call.name,\n tool_call_id: call.id ?? '',\n });\n }\n }) ?? []\n );\n\n if (!outputs.some(isCommand)) {\n return (Array.isArray(input) ? outputs : { messages: outputs }) as T;\n }\n\n const combinedOutputs = outputs.map((output) => {\n if (isCommand(output)) {\n return output;\n }\n return Array.isArray(input) ? [output] : { messages: [output] };\n });\n return combinedOutputs as T;\n }\n}\n\nexport function toolsCondition(\n state: BaseMessage[] | typeof MessagesAnnotation.State\n): 'tools' | typeof END {\n const message = Array.isArray(state)\n ? state[state.length - 1]\n : state.messages[state.messages.length - 1];\n\n if (\n 'tool_calls' in message &&\n ((message as AIMessage).tool_calls?.length ?? 0) > 0\n ) {\n return GraphNodeKeys.TOOLS;\n } else {\n return END;\n }\n}"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.mjs","sources":["../../../src/utils/graph.ts"],"sourcesContent":["export const resetIfNotEmpty = <T>(value: T, resetValue: T): T => {\n if (Array.isArray(value)) {\n return value.length > 0 ? resetValue : value;\n }\n if (value instanceof Set || value instanceof Map) {\n return value.size > 0 ? resetValue : value;\n }\n return value !== undefined ? resetValue : value;\n};\n\nexport const joinKeys = (args: (string | number | undefined)[]): string => args.join('_');"],"names":[],"mappings":"MAAa,eAAe,GAAG,CAAI,KAAQ,EAAE,UAAa,KAAO;AAC/D,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACxB,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,GAAG,KAAK,
|
|
1
|
+
{"version":3,"file":"graph.mjs","sources":["../../../src/utils/graph.ts"],"sourcesContent":["export const resetIfNotEmpty = <T>(value: T, resetValue: T): T => {\n if (Array.isArray(value)) {\n return value.length > 0 ? resetValue : value;\n }\n if (value instanceof Set || value instanceof Map) {\n return value.size > 0 ? resetValue : value;\n }\n return value !== undefined ? resetValue : value;\n};\n\nexport const joinKeys = (args: (string | number | undefined)[]): string => args.join('_');"],"names":[],"mappings":"MAAa,eAAe,GAAG,CAAI,KAAQ,EAAE,UAAa,KAAO;AAC/D,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACxB,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,GAAG,KAAK;;IAE9C,IAAI,KAAK,YAAY,GAAG,IAAI,KAAK,YAAY,GAAG,EAAE;AAChD,QAAA,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,UAAU,GAAG,KAAK;;IAE5C,OAAO,KAAK,KAAK,SAAS,GAAG,UAAU,GAAG,KAAK;AACjD;AAEO,MAAM,QAAQ,GAAG,CAAC,IAAqC,KAAa,IAAI,CAAC,IAAI,CAAC,GAAG;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.mjs","sources":["../../../src/utils/llm.ts"],"sourcesContent":["// src/utils/llm.ts\nimport { Providers } from '@/common';\n\nexport function isOpenAILike(provider?: string | Providers): boolean {\n if (provider == null) {\n return false;\n }\n return ([Providers.OPENAI, Providers.AZURE] as string[]).includes(provider);\n}\n\nexport function isGoogleLike(provider?: string | Providers): boolean {\n if (provider == null) {\n return false;\n }\n return ([Providers.GOOGLE, Providers.VERTEXAI] as string[]).includes(provider);\n}"],"names":[],"mappings":";;AAAA;AAGM,SAAU,YAAY,CAAC,QAA6B,EAAA;AACxD,IAAA,IAAI,QAAQ,IAAI,IAAI,EAAE;AACpB,QAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"llm.mjs","sources":["../../../src/utils/llm.ts"],"sourcesContent":["// src/utils/llm.ts\nimport { Providers } from '@/common';\n\nexport function isOpenAILike(provider?: string | Providers): boolean {\n if (provider == null) {\n return false;\n }\n return ([Providers.OPENAI, Providers.AZURE] as string[]).includes(provider);\n}\n\nexport function isGoogleLike(provider?: string | Providers): boolean {\n if (provider == null) {\n return false;\n }\n return ([Providers.GOOGLE, Providers.VERTEXAI] as string[]).includes(provider);\n}"],"names":[],"mappings":";;AAAA;AAGM,SAAU,YAAY,CAAC,QAA6B,EAAA;AACxD,IAAA,IAAI,QAAQ,IAAI,IAAI,EAAE;AACpB,QAAA,OAAO,KAAK;;AAEd,IAAA,OAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAC7E;AAEM,SAAU,YAAY,CAAC,QAA6B,EAAA;AACxD,IAAA,IAAI,QAAQ,IAAI,IAAI,EAAE;AACpB,QAAA,OAAO,KAAK;;AAEd,IAAA,OAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAChF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"misc.mjs","sources":["../../../src/utils/misc.ts"],"sourcesContent":["/**\n * Unescapes a c-escaped string\n * @param str The string to unescape\n * @returns The unescaped string\n */\nconst unescapeString = (string: string): string => string.replace(/\\\\(.)/g, (_, char) => {\n switch (char) {\n case 'n':\n return '\\n';\n case 't':\n return '\\t';\n case 'r':\n return '\\r';\n case '\"':\n return '\"';\n case '\\'':\n return '\\'';\n case '\\\\':\n return '\\\\';\n default:\n return char;\n }\n});\n\n/**\n * Recursively unescapes all string values in an object\n * @param obj The object to unescape\n * @returns The unescaped object\n */\nexport function unescapeObject(obj: unknown, key?: string): unknown {\n if (typeof obj === 'string') {\n let unescaped = unescapeString(obj);\n if (key === 'filePath' && unescaped.match(/^\"(.+)\"$/)) {\n unescaped = unescaped.substring(1, unescaped.length - 1);\n }\n return unescaped;\n }\n if (Array.isArray(obj)) {\n return obj.map((value) => unescapeObject(value, key === 'contextPaths' ? 'filePath' : ''));\n }\n if (typeof obj === 'object' && obj !== null) {\n return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, unescapeObject(value, key)]));\n }\n return obj;\n}"],"names":[],"mappings":"AAAA;;;;AAIG;AACH,MAAM,cAAc,GAAG,CAAC,MAAc,KAAa,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,KAAI;IACtF,QAAQ,IAAI;AACZ,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,IAAI
|
|
1
|
+
{"version":3,"file":"misc.mjs","sources":["../../../src/utils/misc.ts"],"sourcesContent":["/**\n * Unescapes a c-escaped string\n * @param str The string to unescape\n * @returns The unescaped string\n */\nconst unescapeString = (string: string): string => string.replace(/\\\\(.)/g, (_, char) => {\n switch (char) {\n case 'n':\n return '\\n';\n case 't':\n return '\\t';\n case 'r':\n return '\\r';\n case '\"':\n return '\"';\n case '\\'':\n return '\\'';\n case '\\\\':\n return '\\\\';\n default:\n return char;\n }\n});\n\n/**\n * Recursively unescapes all string values in an object\n * @param obj The object to unescape\n * @returns The unescaped object\n */\nexport function unescapeObject(obj: unknown, key?: string): unknown {\n if (typeof obj === 'string') {\n let unescaped = unescapeString(obj);\n if (key === 'filePath' && unescaped.match(/^\"(.+)\"$/)) {\n unescaped = unescaped.substring(1, unescaped.length - 1);\n }\n return unescaped;\n }\n if (Array.isArray(obj)) {\n return obj.map((value) => unescapeObject(value, key === 'contextPaths' ? 'filePath' : ''));\n }\n if (typeof obj === 'object' && obj !== null) {\n return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, unescapeObject(value, key)]));\n }\n return obj;\n}"],"names":[],"mappings":"AAAA;;;;AAIG;AACH,MAAM,cAAc,GAAG,CAAC,MAAc,KAAa,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,KAAI;IACtF,QAAQ,IAAI;AACZ,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,IAAI;AACb,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,IAAI;AACb,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,IAAI;AACb,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,GAAG;AACZ,QAAA,KAAK,IAAI;AACP,YAAA,OAAO,IAAI;AACb,QAAA,KAAK,IAAI;AACP,YAAA,OAAO,IAAI;AACb,QAAA;AACE,YAAA,OAAO,IAAI;;AAEf,CAAC,CAAC;AAEF;;;;AAIG;AACa,SAAA,cAAc,CAAC,GAAY,EAAE,GAAY,EAAA;AACvD,IAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAC3B,QAAA,IAAI,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC;QACnC,IAAI,GAAG,KAAK,UAAU,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;AACrD,YAAA,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;;AAE1D,QAAA,OAAO,SAAS;;AAElB,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QACtB,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,KAAK,EAAE,GAAG,KAAK,cAAc,GAAG,UAAU,GAAG,EAAE,CAAC,CAAC;;IAE5F,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;AAC3C,QAAA,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;;AAEzG,IAAA,OAAO,GAAG;AACZ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.mjs","sources":["../../../src/utils/run.ts"],"sourcesContent":["import { CallbackManagerForChainRun } from '@langchain/core/callbacks/manager';\nimport {\n mergeConfigs,\n patchConfig,\n Runnable,\n RunnableConfig,\n} from '@langchain/core/runnables';\nimport { AsyncLocalStorageProviderSingleton } from '@langchain/core/singletons';\n\n/**\n * Delays the execution for a specified number of milliseconds.\n *\n * @param {number} ms - The number of milliseconds to delay.\n * @return {Promise<void>} A promise that resolves after the specified delay.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface RunnableCallableArgs extends Partial<any> {\n name?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n func: (...args: any[]) => any;\n tags?: string[];\n trace?: boolean;\n recurse?: boolean;\n}\n\nexport class RunnableCallable<I = unknown, O = unknown> extends Runnable<I, O> {\n lc_namespace: string[] = ['langgraph'];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n func: (...args: any[]) => any;\n\n tags?: string[];\n\n config?: RunnableConfig;\n\n trace: boolean = true;\n\n recurse: boolean = true;\n\n constructor(fields: RunnableCallableArgs) {\n super();\n this.name = fields.name ?? fields.func.name;\n this.func = fields.func;\n this.config = fields.tags ? { tags: fields.tags } : undefined;\n this.trace = fields.trace ?? this.trace;\n this.recurse = fields.recurse ?? this.recurse;\n }\n\n protected async _tracedInvoke(\n input: I,\n config?: Partial<RunnableConfig>,\n runManager?: CallbackManagerForChainRun\n ): Promise<O> {\n return new Promise<O>((resolve, reject) => {\n const childConfig = patchConfig(config, {\n callbacks: runManager?.getChild(),\n });\n void AsyncLocalStorageProviderSingleton.runWithConfig(\n childConfig,\n async () => {\n try {\n const output = await this.func(input, childConfig);\n resolve(output);\n } catch (e) {\n reject(e);\n }\n }\n );\n });\n }\n\n async invoke(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n input: any,\n options?: Partial<RunnableConfig> | undefined\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let returnValue: any;\n\n if (this.trace) {\n returnValue = await this._callWithConfig(\n this._tracedInvoke,\n input,\n mergeConfigs(this.config, options)\n );\n } else {\n returnValue = await this.func(input, mergeConfigs(this.config, options));\n }\n\n if (Runnable.isRunnable(returnValue) && this.recurse) {\n return await returnValue.invoke(input, options);\n }\n\n return returnValue;\n }\n}"],"names":[],"mappings":";;;AASA;;;;;AAKG;AACG,SAAU,KAAK,CAAC,EAAU,EAAA;AAC9B,IAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"run.mjs","sources":["../../../src/utils/run.ts"],"sourcesContent":["import { CallbackManagerForChainRun } from '@langchain/core/callbacks/manager';\nimport {\n mergeConfigs,\n patchConfig,\n Runnable,\n RunnableConfig,\n} from '@langchain/core/runnables';\nimport { AsyncLocalStorageProviderSingleton } from '@langchain/core/singletons';\n\n/**\n * Delays the execution for a specified number of milliseconds.\n *\n * @param {number} ms - The number of milliseconds to delay.\n * @return {Promise<void>} A promise that resolves after the specified delay.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface RunnableCallableArgs extends Partial<any> {\n name?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n func: (...args: any[]) => any;\n tags?: string[];\n trace?: boolean;\n recurse?: boolean;\n}\n\nexport class RunnableCallable<I = unknown, O = unknown> extends Runnable<I, O> {\n lc_namespace: string[] = ['langgraph'];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n func: (...args: any[]) => any;\n\n tags?: string[];\n\n config?: RunnableConfig;\n\n trace: boolean = true;\n\n recurse: boolean = true;\n\n constructor(fields: RunnableCallableArgs) {\n super();\n this.name = fields.name ?? fields.func.name;\n this.func = fields.func;\n this.config = fields.tags ? { tags: fields.tags } : undefined;\n this.trace = fields.trace ?? this.trace;\n this.recurse = fields.recurse ?? this.recurse;\n }\n\n protected async _tracedInvoke(\n input: I,\n config?: Partial<RunnableConfig>,\n runManager?: CallbackManagerForChainRun\n ): Promise<O> {\n return new Promise<O>((resolve, reject) => {\n const childConfig = patchConfig(config, {\n callbacks: runManager?.getChild(),\n });\n void AsyncLocalStorageProviderSingleton.runWithConfig(\n childConfig,\n async () => {\n try {\n const output = await this.func(input, childConfig);\n resolve(output);\n } catch (e) {\n reject(e);\n }\n }\n );\n });\n }\n\n async invoke(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n input: any,\n options?: Partial<RunnableConfig> | undefined\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let returnValue: any;\n\n if (this.trace) {\n returnValue = await this._callWithConfig(\n this._tracedInvoke,\n input,\n mergeConfigs(this.config, options)\n );\n } else {\n returnValue = await this.func(input, mergeConfigs(this.config, options));\n }\n\n if (Runnable.isRunnable(returnValue) && this.recurse) {\n return await returnValue.invoke(input, options);\n }\n\n return returnValue;\n }\n}"],"names":[],"mappings":";;;AASA;;;;;AAKG;AACG,SAAU,KAAK,CAAC,EAAU,EAAA;AAC9B,IAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC1D;AAYM,MAAO,gBAA2C,SAAQ,QAAc,CAAA;AAC5E,IAAA,YAAY,GAAa,CAAC,WAAW,CAAC;;AAGtC,IAAA,IAAI;AAEJ,IAAA,IAAI;AAEJ,IAAA,MAAM;IAEN,KAAK,GAAY,IAAI;IAErB,OAAO,GAAY,IAAI;AAEvB,IAAA,WAAA,CAAY,MAA4B,EAAA;AACtC,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI;AAC3C,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,SAAS;QAC7D,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK;QACvC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;;AAGrC,IAAA,MAAM,aAAa,CAC3B,KAAQ,EACR,MAAgC,EAChC,UAAuC,EAAA;QAEvC,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,KAAI;AACxC,YAAA,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,EAAE;AACtC,gBAAA,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;AAClC,aAAA,CAAC;YACF,KAAK,kCAAkC,CAAC,aAAa,CACnD,WAAW,EACX,YAAW;AACT,gBAAA,IAAI;oBACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC;oBAClD,OAAO,CAAC,MAAM,CAAC;;gBACf,OAAO,CAAC,EAAE;oBACV,MAAM,CAAC,CAAC,CAAC;;AAEb,aAAC,CACF;AACH,SAAC,CAAC;;AAGJ,IAAA,MAAM,MAAM;;AAEV,IAAA,KAAU,EACV;;;;AAIA,QAAA,IAAI,WAAgB;AAEpB,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE;YACd,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CACtC,IAAI,CAAC,aAAa,EAClB,KAAK,EACL,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CACnC;;aACI;AACL,YAAA,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;;QAG1E,IAAI,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;YACpD,OAAO,MAAM,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;;AAGjD,QAAA,OAAO,WAAW;;AAErB;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"title.mjs","sources":["../../../src/utils/title.ts"],"sourcesContent":["import { z } from 'zod';\nimport { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { RunnableLambda } from '@langchain/core/runnables';\nimport type { Runnable } from '@langchain/core/runnables';\nimport * as t from '@/types';\n\nconst defaultTitlePrompt = `Write a concise title for this conversation in the detected language. Title in 5 Words or Less. No Punctuation or Quotation.\n{convo}`;\n\nconst languageInstructions = 'Detect the language used in the following text. Note: words may be misspelled or cut off; use context clues to identify the language:\\n{text}';\n\nconst languagePrompt = ChatPromptTemplate.fromTemplate(languageInstructions);\n\nconst languageSchema = z.object({\n language: z.string().describe('The detected language of the conversation')\n});\n\nconst titleSchema = z.object({\n title: z.string().describe('A concise title for the conversation in 5 words or less, without punctuation or quotation'),\n});\n\nexport const createTitleRunnable = async (model: t.ChatModelInstance, _titlePrompt?: string): Promise<Runnable> => {\n // Disabled since this works fine\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /* @ts-ignore */\n const languageLLM = model.withStructuredOutput(languageSchema);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /* @ts-ignore */\n const titleLLM = model.withStructuredOutput(titleSchema);\n\n const languageChain = languagePrompt.pipe(languageLLM);\n\n const titlePrompt = ChatPromptTemplate.fromTemplate(_titlePrompt ?? defaultTitlePrompt);\n\n return new RunnableLambda({\n func: async (input: { convo: string, inputText: string, skipLanguage: boolean }): Promise<{ language: string; title: string } | { title: string }> => {\n if (input.skipLanguage) {\n return await titlePrompt.pipe(titleLLM).invoke({\n convo: input.convo\n }) as { title: string };\n }\n const languageResult = await languageChain.invoke({ text: input.inputText }) as { language: string } | undefined;\n const language = languageResult?.language ?? 'English';\n const titleResult = await titlePrompt.pipe(titleLLM).invoke({\n language,\n convo: input.convo\n }) as { title: string } | undefined;\n return { language, title: titleResult?.title ?? '' };\n },\n });\n};"],"names":[],"mappings":";;;;AAMA,MAAM,kBAAkB,GAAG,CAAA;QACnB
|
|
1
|
+
{"version":3,"file":"title.mjs","sources":["../../../src/utils/title.ts"],"sourcesContent":["import { z } from 'zod';\nimport { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { RunnableLambda } from '@langchain/core/runnables';\nimport type { Runnable } from '@langchain/core/runnables';\nimport * as t from '@/types';\n\nconst defaultTitlePrompt = `Write a concise title for this conversation in the detected language. Title in 5 Words or Less. No Punctuation or Quotation.\n{convo}`;\n\nconst languageInstructions = 'Detect the language used in the following text. Note: words may be misspelled or cut off; use context clues to identify the language:\\n{text}';\n\nconst languagePrompt = ChatPromptTemplate.fromTemplate(languageInstructions);\n\nconst languageSchema = z.object({\n language: z.string().describe('The detected language of the conversation')\n});\n\nconst titleSchema = z.object({\n title: z.string().describe('A concise title for the conversation in 5 words or less, without punctuation or quotation'),\n});\n\nexport const createTitleRunnable = async (model: t.ChatModelInstance, _titlePrompt?: string): Promise<Runnable> => {\n // Disabled since this works fine\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /* @ts-ignore */\n const languageLLM = model.withStructuredOutput(languageSchema);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /* @ts-ignore */\n const titleLLM = model.withStructuredOutput(titleSchema);\n\n const languageChain = languagePrompt.pipe(languageLLM);\n\n const titlePrompt = ChatPromptTemplate.fromTemplate(_titlePrompt ?? defaultTitlePrompt);\n\n return new RunnableLambda({\n func: async (input: { convo: string, inputText: string, skipLanguage: boolean }): Promise<{ language: string; title: string } | { title: string }> => {\n if (input.skipLanguage) {\n return await titlePrompt.pipe(titleLLM).invoke({\n convo: input.convo\n }) as { title: string };\n }\n const languageResult = await languageChain.invoke({ text: input.inputText }) as { language: string } | undefined;\n const language = languageResult?.language ?? 'English';\n const titleResult = await titlePrompt.pipe(titleLLM).invoke({\n language,\n convo: input.convo\n }) as { title: string } | undefined;\n return { language, title: titleResult?.title ?? '' };\n },\n });\n};"],"names":[],"mappings":";;;;AAMA,MAAM,kBAAkB,GAAG,CAAA;QACnB;AAER,MAAM,oBAAoB,GAAG,+IAA+I;AAE5K,MAAM,cAAc,GAAG,kBAAkB,CAAC,YAAY,CAAC,oBAAoB,CAAC;AAE5E,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C;AAC1E,CAAA,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2FAA2F,CAAC;AACxH,CAAA,CAAC;AAEW,MAAA,mBAAmB,GAAG,OAAO,KAA0B,EAAE,YAAqB,KAAuB;;;;IAIhH,MAAM,WAAW,GAAG,KAAK,CAAC,oBAAoB,CAAC,cAAc,CAAC;;;IAG9D,MAAM,QAAQ,GAAG,KAAK,CAAC,oBAAoB,CAAC,WAAW,CAAC;IAExD,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;IAEtD,MAAM,WAAW,GAAG,kBAAkB,CAAC,YAAY,CAAC,YAAY,IAAI,kBAAkB,CAAC;IAEvF,OAAO,IAAI,cAAc,CAAC;AACxB,QAAA,IAAI,EAAE,OAAO,KAAkE,KAAsE;AACnJ,YAAA,IAAI,KAAK,CAAC,YAAY,EAAE;gBACtB,OAAO,MAAM,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;oBAC7C,KAAK,EAAE,KAAK,CAAC;AACd,iBAAA,CAAsB;;AAEzB,YAAA,MAAM,cAAc,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,CAAqC;AAChH,YAAA,MAAM,QAAQ,GAAG,cAAc,EAAE,QAAQ,IAAI,SAAS;YACtD,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;gBAC1D,QAAQ;gBACR,KAAK,EAAE,KAAK,CAAC;AACd,aAAA,CAAkC;YACnC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE,EAAE;SACrD;AACF,KAAA,CAAC;AACJ;;;;"}
|
package/dist/types/events.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UsageMetadata, BaseMessageFields } from '@langchain/core/messages';
|
|
1
2
|
import type { Graph } from '@/graphs';
|
|
2
3
|
import type * as t from '@/types';
|
|
3
4
|
export declare class HandlerRegistry {
|
|
@@ -6,6 +7,8 @@ export declare class HandlerRegistry {
|
|
|
6
7
|
getHandler(eventType: string): t.EventHandler | undefined;
|
|
7
8
|
}
|
|
8
9
|
export declare class ModelEndHandler implements t.EventHandler {
|
|
10
|
+
collectedUsage?: UsageMetadata[];
|
|
11
|
+
constructor(collectedUsage?: UsageMetadata[]);
|
|
9
12
|
handle(event: string, data: t.ModelEndData, metadata?: Record<string, unknown>, graph?: Graph): void;
|
|
10
13
|
}
|
|
11
14
|
export declare class ToolEndHandler implements t.EventHandler {
|
|
@@ -22,4 +25,4 @@ export declare class TestChatStreamHandler implements t.EventHandler {
|
|
|
22
25
|
export declare class LLMStreamHandler implements t.EventHandler {
|
|
23
26
|
handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>): void;
|
|
24
27
|
}
|
|
25
|
-
export declare const createMetadataAggregator: (_collected?: Record<string,
|
|
28
|
+
export declare const createMetadataAggregator: (_collected?: Record<string, NonNullable<BaseMessageFields["response_metadata"]>>[]) => t.MetadataAggregatorResult;
|
|
@@ -4,7 +4,7 @@ import { Runnable, RunnableConfig } from '@langchain/core/runnables';
|
|
|
4
4
|
import { SystemMessage } from '@langchain/core/messages';
|
|
5
5
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
6
6
|
import type * as t from '@/types';
|
|
7
|
-
import { Providers, GraphNodeKeys, Callback } from '@/common';
|
|
7
|
+
import { Providers, GraphNodeKeys, Callback, ContentTypes } from '@/common';
|
|
8
8
|
import { ToolNode as CustomToolNode } from '@/tools/ToolNode';
|
|
9
9
|
import { HandlerRegistry } from '@/events';
|
|
10
10
|
export type GraphNode = GraphNodeKeys | typeof START;
|
|
@@ -33,9 +33,15 @@ export declare abstract class Graph<T extends t.BaseGraphState = t.BaseGraphStat
|
|
|
33
33
|
abstract dispatchRunStep(stepKey: string, stepDetails: t.StepDetails): string;
|
|
34
34
|
abstract dispatchRunStepDelta(id: string, delta: t.ToolCallDelta): void;
|
|
35
35
|
abstract dispatchMessageDelta(id: string, delta: t.MessageDelta): void;
|
|
36
|
+
abstract dispatchReasoningDelta(stepId: string, delta: t.ReasoningDelta): void;
|
|
36
37
|
abstract handleToolCallCompleted(data: t.ToolEndData, metadata?: Record<string, unknown>): void;
|
|
37
38
|
abstract createCallModel(): (state: T, config?: RunnableConfig) => Promise<Partial<T>>;
|
|
38
39
|
abstract createWorkflow(): t.CompiledWorkflow<T>;
|
|
40
|
+
lastToken?: string;
|
|
41
|
+
tokenTypeSwitch?: 'reasoning' | 'content';
|
|
42
|
+
reasoningKey: 'reasoning_content' | 'reasoning';
|
|
43
|
+
currentTokenType: ContentTypes.TEXT | ContentTypes.THINK;
|
|
44
|
+
messageStepHasToolCalls: Map<string, boolean>;
|
|
39
45
|
messageIdsByStepKey: Map<string, string>;
|
|
40
46
|
prelimMessageIdsByStepKey: Map<string, string>;
|
|
41
47
|
config: RunnableConfig | undefined;
|
|
@@ -87,6 +93,7 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, GraphNode> {
|
|
|
87
93
|
createGraphState(): t.GraphStateChannels<t.BaseGraphState>;
|
|
88
94
|
initializeTools(): CustomToolNode<t.BaseGraphState> | ToolNode<t.BaseGraphState>;
|
|
89
95
|
initializeModel(): Runnable;
|
|
96
|
+
overrideTestModel(responses: string[], sleep?: number): void;
|
|
90
97
|
getNewModel({ clientOptions, omitOriginalOptions, }: {
|
|
91
98
|
clientOptions?: t.ClientOptions;
|
|
92
99
|
omitOriginalOptions?: string[];
|
|
@@ -100,4 +107,5 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, GraphNode> {
|
|
|
100
107
|
handleToolCallCompleted(data: t.ToolEndData, metadata?: Record<string, unknown>): void;
|
|
101
108
|
dispatchRunStepDelta(id: string, delta: t.ToolCallDelta): void;
|
|
102
109
|
dispatchMessageDelta(id: string, delta: t.MessageDelta): void;
|
|
110
|
+
dispatchReasoningDelta: (stepId: string, delta: t.ReasoningDelta) => void;
|
|
103
111
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
2
|
+
import type { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
3
|
+
import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
|
|
4
|
+
import { FakeListChatModel } from '@langchain/core/utils/testing';
|
|
5
|
+
type SplitStrategy = {
|
|
6
|
+
type: 'regex' | 'fixed';
|
|
7
|
+
value: RegExp | number;
|
|
8
|
+
};
|
|
9
|
+
export declare class FakeChatModel extends FakeListChatModel {
|
|
10
|
+
private splitStrategy;
|
|
11
|
+
constructor({ responses, sleep, emitCustomEvent, splitStrategy }: {
|
|
12
|
+
responses: string[];
|
|
13
|
+
sleep?: number;
|
|
14
|
+
emitCustomEvent?: boolean;
|
|
15
|
+
splitStrategy?: SplitStrategy;
|
|
16
|
+
});
|
|
17
|
+
private splitText;
|
|
18
|
+
_streamResponseChunks(_messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
|
|
19
|
+
}
|
|
20
|
+
export declare function createFakeStreamingLLM(responses: string[], sleep?: number, splitStrategy?: SplitStrategy): FakeChatModel;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function capitalizeFirstLetter(string: string): string;
|
package/dist/types/stream.d.ts
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AIMessageChunk } from '@langchain/core/messages';
|
|
2
|
+
import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
|
|
2
3
|
import type { Graph } from '@/graphs';
|
|
3
4
|
import type * as t from '@/types';
|
|
4
|
-
import { GraphEvents } from '@/common';
|
|
5
5
|
export declare const getMessageId: (stepKey: string, graph: Graph<t.BaseGraphState>, returnExistingId?: boolean) => string | undefined;
|
|
6
6
|
export declare const handleToolCalls: (toolCalls?: ToolCall[], metadata?: Record<string, unknown>, graph?: Graph) => void;
|
|
7
7
|
export declare class ChatModelStreamHandler implements t.EventHandler {
|
|
8
8
|
handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
aggregateContent: ({ event, data }: {
|
|
14
|
-
event: GraphEvents;
|
|
15
|
-
data: t.RunStep | t.MessageDeltaEvent | t.RunStepDeltaEvent | {
|
|
16
|
-
result: t.ToolEndEvent;
|
|
17
|
-
};
|
|
9
|
+
handleToolCallChunks: ({ graph, stepKey, toolCallChunks, }: {
|
|
10
|
+
graph: Graph;
|
|
11
|
+
stepKey: string;
|
|
12
|
+
toolCallChunks: ToolCallChunk[];
|
|
18
13
|
}) => void;
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
handleReasoning(chunk: Partial<AIMessageChunk>, graph: Graph): void;
|
|
15
|
+
}
|
|
16
|
+
export declare function createContentAggregator(): t.ContentAggregatorResult;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ChatOllama } from '@langchain/ollama';
|
|
2
|
+
import { ChatDeepSeek } from '@langchain/deepseek';
|
|
2
3
|
import { ChatAnthropic } from '@langchain/anthropic';
|
|
3
4
|
import { ChatMistralAI } from '@langchain/mistralai';
|
|
4
5
|
import { ChatBedrockConverse } from '@langchain/aws';
|
|
@@ -11,6 +12,7 @@ import type { ChatOpenAIFields, OpenAIChatInput, AzureOpenAIInput } from '@langc
|
|
|
11
12
|
import type { BedrockChatFields } from '@langchain/community/chat_models/bedrock/web';
|
|
12
13
|
import type { GoogleGenerativeAIChatInput } from '@langchain/google-genai';
|
|
13
14
|
import type { ChatVertexAIInput } from '@langchain/google-vertexai';
|
|
15
|
+
import type { ChatDeepSeekCallOptions } from '@langchain/deepseek';
|
|
14
16
|
import type { ChatBedrockConverseInput } from '@langchain/aws';
|
|
15
17
|
import type { ChatMistralAIInput } from '@langchain/mistralai';
|
|
16
18
|
import type { StructuredTool } from '@langchain/core/tools';
|
|
@@ -37,28 +39,31 @@ export type VertexAIClientOptions = ChatVertexAIInput;
|
|
|
37
39
|
export type BedrockClientOptions = BedrockChatFields;
|
|
38
40
|
export type BedrockConverseClientOptions = ChatBedrockConverseInput;
|
|
39
41
|
export type GoogleClientOptions = GoogleGenerativeAIChatInput;
|
|
40
|
-
export type
|
|
42
|
+
export type DeepSeekClientOptions = ChatDeepSeekCallOptions;
|
|
43
|
+
export type ClientOptions = OpenAIClientOptions | AzureClientOptions | OllamaClientOptions | AnthropicClientOptions | MistralAIClientOptions | VertexAIClientOptions | BedrockClientOptions | BedrockConverseClientOptions | GoogleClientOptions | DeepSeekClientOptions;
|
|
41
44
|
export type LLMConfig = {
|
|
42
45
|
provider: Providers;
|
|
43
46
|
} & ClientOptions;
|
|
44
47
|
export type ProviderOptionsMap = {
|
|
45
|
-
[Providers.OPENAI]: OpenAIClientOptions;
|
|
46
48
|
[Providers.AZURE]: AzureClientOptions;
|
|
49
|
+
[Providers.OPENAI]: OpenAIClientOptions;
|
|
47
50
|
[Providers.OLLAMA]: OllamaClientOptions;
|
|
51
|
+
[Providers.GOOGLE]: GoogleClientOptions;
|
|
52
|
+
[Providers.VERTEXAI]: VertexAIClientOptions;
|
|
53
|
+
[Providers.DEEPSEEK]: DeepSeekClientOptions;
|
|
48
54
|
[Providers.ANTHROPIC]: AnthropicClientOptions;
|
|
49
55
|
[Providers.MISTRALAI]: MistralAIClientOptions;
|
|
50
|
-
[Providers.VERTEXAI]: VertexAIClientOptions;
|
|
51
56
|
[Providers.BEDROCK_LEGACY]: BedrockClientOptions;
|
|
52
57
|
[Providers.BEDROCK]: BedrockConverseClientOptions;
|
|
53
|
-
[Providers.GOOGLE]: GoogleClientOptions;
|
|
54
58
|
};
|
|
55
59
|
export type ChatModelMap = {
|
|
56
60
|
[Providers.OPENAI]: ChatOpenAI;
|
|
57
61
|
[Providers.OLLAMA]: ChatOllama;
|
|
58
62
|
[Providers.AZURE]: AzureChatOpenAI;
|
|
63
|
+
[Providers.DEEPSEEK]: ChatDeepSeek;
|
|
64
|
+
[Providers.VERTEXAI]: ChatVertexAI;
|
|
59
65
|
[Providers.ANTHROPIC]: ChatAnthropic;
|
|
60
66
|
[Providers.MISTRALAI]: ChatMistralAI;
|
|
61
|
-
[Providers.VERTEXAI]: ChatVertexAI;
|
|
62
67
|
[Providers.BEDROCK_LEGACY]: BedrockChat;
|
|
63
68
|
[Providers.BEDROCK]: ChatBedrockConverse;
|
|
64
69
|
[Providers.GOOGLE]: ChatGoogleGenerativeAI;
|
|
@@ -2,6 +2,7 @@ import type OpenAITypes from 'openai';
|
|
|
2
2
|
import type { MessageContentImageUrl, MessageContentText, ToolMessage, BaseMessage } from '@langchain/core/messages';
|
|
3
3
|
import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
|
|
4
4
|
import type { LLMResult, Generation } from '@langchain/core/outputs';
|
|
5
|
+
import type { ToolEndEvent } from '@/types/tools';
|
|
5
6
|
import { StepTypes, ContentTypes, GraphEvents } from '@/common/enum';
|
|
6
7
|
export type HandleLLMEnd = (output: LLMResult, runId: string, parentRunId?: string, tags?: string[]) => void;
|
|
7
8
|
export type MetadataAggregatorResult = {
|
|
@@ -206,3 +207,14 @@ export type SplitStreamHandlers = Partial<{
|
|
|
206
207
|
data: ReasoningDeltaEvent;
|
|
207
208
|
}) => void;
|
|
208
209
|
}>;
|
|
210
|
+
export type ContentAggregator = ({ event, data }: {
|
|
211
|
+
event: GraphEvents;
|
|
212
|
+
data: RunStep | MessageDeltaEvent | RunStepDeltaEvent | {
|
|
213
|
+
result: ToolEndEvent;
|
|
214
|
+
};
|
|
215
|
+
}) => void;
|
|
216
|
+
export type ContentAggregatorResult = {
|
|
217
|
+
stepMap: Map<string, RunStep | undefined>;
|
|
218
|
+
contentParts: Array<MessageContentComplex | undefined>;
|
|
219
|
+
aggregateContent: ContentAggregator;
|
|
220
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@librechat/agents",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"main": "./dist/cjs/main.cjs",
|
|
5
5
|
"module": "./dist/esm/main.mjs",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"code_exec": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec.ts --provider 'google' --name 'Jo' --location 'New York, NY'",
|
|
46
46
|
"image": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/image.ts --provider 'vertexai' --name 'Jo' --location 'New York, NY'",
|
|
47
47
|
"code_exec_simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec_simple.ts --provider 'vertexai' --name 'Jo' --location 'New York, NY'",
|
|
48
|
-
"simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/simple.ts --provider '
|
|
48
|
+
"simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/simple.ts --provider 'deepseek' --name 'Jo' --location 'New York, NY'",
|
|
49
49
|
"memory": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/memory.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
|
|
50
|
-
"tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider '
|
|
50
|
+
"tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider 'alibaba' --name 'Jo' --location 'New York, NY'",
|
|
51
51
|
"abort": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/abort.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
|
|
52
52
|
"start:cli2": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/cli2.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
|
|
53
53
|
"script2": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/proto/example_test.ts",
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
"@langchain/aws": "^0.1.3",
|
|
75
75
|
"@langchain/community": "^0.3.27",
|
|
76
76
|
"@langchain/core": "^0.3.37",
|
|
77
|
+
"@langchain/deepseek": "^0.0.1",
|
|
77
78
|
"@langchain/google-genai": "^0.1.7",
|
|
78
79
|
"@langchain/google-vertexai": "^0.1.8",
|
|
79
80
|
"@langchain/langgraph": "^0.2.41",
|
|
@@ -84,7 +85,8 @@
|
|
|
84
85
|
"@smithy/protocol-http": "^3.0.6",
|
|
85
86
|
"@smithy/signature-v4": "^2.0.10",
|
|
86
87
|
"@smithy/util-utf8": "^2.0.0",
|
|
87
|
-
"dotenv": "^16.4.
|
|
88
|
+
"dotenv": "^16.4.7",
|
|
89
|
+
"https-proxy-agent": "^7.0.6",
|
|
88
90
|
"nanoid": "^3.3.7"
|
|
89
91
|
},
|
|
90
92
|
"resolutions": {
|
|
@@ -103,38 +105,25 @@
|
|
|
103
105
|
"@rollup/plugin-json": "^6.1.0",
|
|
104
106
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
105
107
|
"@rollup/plugin-terser": "^0.4.4",
|
|
106
|
-
"@rollup/plugin-typescript": "^
|
|
108
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
107
109
|
"@swc/core": "^1.6.13",
|
|
108
|
-
"@types/babel__generator": "^7.6.8",
|
|
109
|
-
"@types/babel__template": "^7.4.4",
|
|
110
|
-
"@types/istanbul-lib-report": "^3.0.3",
|
|
111
110
|
"@types/jest": "^29.5.14",
|
|
112
111
|
"@types/node": "^20.14.11",
|
|
113
|
-
"@types/rollup": "^0.54.0",
|
|
114
112
|
"@types/yargs-parser": "^21.0.3",
|
|
115
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
116
|
-
"@typescript-eslint/parser": "^
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"eslint-import-resolver-typescript": "^3.6.1",
|
|
122
|
-
"eslint-plugin-import": "^2.29.1",
|
|
123
|
-
"husky": "^9.0.11",
|
|
124
|
-
"javascript-obfuscator": "^4.1.1",
|
|
113
|
+
"@typescript-eslint/eslint-plugin": "^8.24.0",
|
|
114
|
+
"@typescript-eslint/parser": "^8.24.0",
|
|
115
|
+
"eslint": "^9.20.1",
|
|
116
|
+
"eslint-import-resolver-typescript": "^3.7.0",
|
|
117
|
+
"eslint-plugin-import": "^2.31.0",
|
|
118
|
+
"husky": "^9.1.7",
|
|
125
119
|
"jest": "^29.7.0",
|
|
126
120
|
"lint-staged": "^15.2.7",
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
"rimraf": "^6.0.0",
|
|
130
|
-
"rollup": "^4.18.1",
|
|
121
|
+
"prettier": "^3.5.1",
|
|
122
|
+
"rollup": "^4.34.6",
|
|
131
123
|
"rollup-plugin-cleandir": "^2.0.0",
|
|
132
|
-
"rollup-plugin-cleaner": "^1.0.0",
|
|
133
124
|
"rollup-plugin-obfuscator": "^1.1.0",
|
|
134
|
-
"rollup-plugin-visualizer": "^5.12.0",
|
|
135
125
|
"ts-jest": "^29.2.5",
|
|
136
126
|
"ts-node": "^10.9.2",
|
|
137
|
-
"ts-node-dev": "^2.0.0",
|
|
138
127
|
"tsc-alias": "^1.8.10",
|
|
139
128
|
"tsconfig-paths": "^4.2.0",
|
|
140
129
|
"tslib": "^2.6.3",
|
package/src/common/enum.ts
CHANGED
package/src/events.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
// src/events.ts
|
|
3
|
+
import type { UsageMetadata, BaseMessageFields } from '@langchain/core/messages';
|
|
3
4
|
import type { Graph } from '@/graphs';
|
|
4
5
|
import type * as t from '@/types';
|
|
5
6
|
import { handleToolCalls } from '@/stream';
|
|
@@ -18,6 +19,14 @@ export class HandlerRegistry {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export class ModelEndHandler implements t.EventHandler {
|
|
22
|
+
collectedUsage?: UsageMetadata[];
|
|
23
|
+
constructor(collectedUsage?: UsageMetadata[]) {
|
|
24
|
+
if (collectedUsage && !Array.isArray(collectedUsage)) {
|
|
25
|
+
throw new Error('collectedUsage must be an array');
|
|
26
|
+
}
|
|
27
|
+
this.collectedUsage = collectedUsage;
|
|
28
|
+
}
|
|
29
|
+
|
|
21
30
|
handle(event: string, data: t.ModelEndData, metadata?: Record<string, unknown>, graph?: Graph): void {
|
|
22
31
|
if (!graph || !metadata) {
|
|
23
32
|
console.warn(`Graph or metadata not found in ${event} event`);
|
|
@@ -25,6 +34,9 @@ export class ModelEndHandler implements t.EventHandler {
|
|
|
25
34
|
}
|
|
26
35
|
|
|
27
36
|
const usage = data?.output?.usage_metadata;
|
|
37
|
+
if (usage != null && this.collectedUsage != null) {
|
|
38
|
+
this.collectedUsage.push(usage);
|
|
39
|
+
}
|
|
28
40
|
|
|
29
41
|
console.log(`====== ${event.toUpperCase()} ======`);
|
|
30
42
|
console.dir({
|
|
@@ -117,7 +129,7 @@ export class LLMStreamHandler implements t.EventHandler {
|
|
|
117
129
|
}
|
|
118
130
|
}
|
|
119
131
|
|
|
120
|
-
export const createMetadataAggregator = (_collected?: Record<string,
|
|
132
|
+
export const createMetadataAggregator = (_collected?: Record<string, NonNullable<BaseMessageFields['response_metadata']>>[]): t.MetadataAggregatorResult => {
|
|
121
133
|
const collected = _collected || [];
|
|
122
134
|
|
|
123
135
|
const handleLLMEnd: t.HandleLLMEnd = (output) => {
|
package/src/graphs/Graph.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { dispatchCustomEvent } from '@langchain/core/callbacks/dispatch';
|
|
|
10
10
|
import { AIMessageChunk, ToolMessage, SystemMessage } from '@langchain/core/messages';
|
|
11
11
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
12
12
|
import type * as t from '@/types';
|
|
13
|
-
import { Providers, GraphEvents, GraphNodeKeys, StepTypes, Callback } from '@/common';
|
|
13
|
+
import { Providers, GraphEvents, GraphNodeKeys, StepTypes, Callback, ContentTypes } from '@/common';
|
|
14
14
|
import { getChatModelClass, manualToolStreamProviders } from '@/llm/providers';
|
|
15
15
|
import { ToolNode as CustomToolNode, toolsCondition } from '@/tools/ToolNode';
|
|
16
16
|
import {
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
formatAnthropicArtifactContent,
|
|
21
21
|
} from '@/messages';
|
|
22
22
|
import { resetIfNotEmpty, isOpenAILike, isGoogleLike, joinKeys, sleep } from '@/utils';
|
|
23
|
+
import { createFakeStreamingLLM } from '@/llm/fake';
|
|
23
24
|
import { HandlerRegistry } from '@/events';
|
|
24
25
|
|
|
25
26
|
const { AGENT, TOOLS } = GraphNodeKeys;
|
|
@@ -56,10 +57,16 @@ export abstract class Graph<
|
|
|
56
57
|
abstract dispatchRunStep(stepKey: string, stepDetails: t.StepDetails): string;
|
|
57
58
|
abstract dispatchRunStepDelta(id: string, delta: t.ToolCallDelta): void;
|
|
58
59
|
abstract dispatchMessageDelta(id: string, delta: t.MessageDelta): void;
|
|
60
|
+
abstract dispatchReasoningDelta(stepId: string, delta: t.ReasoningDelta): void;
|
|
59
61
|
abstract handleToolCallCompleted(data: t.ToolEndData, metadata?: Record<string, unknown>): void;
|
|
60
62
|
|
|
61
63
|
abstract createCallModel(): (state: T, config?: RunnableConfig) => Promise<Partial<T>>;
|
|
62
64
|
abstract createWorkflow(): t.CompiledWorkflow<T>;
|
|
65
|
+
lastToken?: string;
|
|
66
|
+
tokenTypeSwitch?: 'reasoning' | 'content';
|
|
67
|
+
reasoningKey: 'reasoning_content' | 'reasoning' = 'reasoning_content';
|
|
68
|
+
currentTokenType: ContentTypes.TEXT | ContentTypes.THINK = ContentTypes.TEXT;
|
|
69
|
+
messageStepHasToolCalls: Map<string, boolean> = new Map();
|
|
63
70
|
messageIdsByStepKey: Map<string, string> = new Map();
|
|
64
71
|
prelimMessageIdsByStepKey: Map<string, string> = new Map();
|
|
65
72
|
config: RunnableConfig | undefined;
|
|
@@ -149,7 +156,12 @@ export class StandardGraph extends Graph<
|
|
|
149
156
|
this.stepKeyIds = resetIfNotEmpty(this.stepKeyIds, new Map());
|
|
150
157
|
this.toolCallStepIds = resetIfNotEmpty(this.toolCallStepIds, new Map());
|
|
151
158
|
this.messageIdsByStepKey = resetIfNotEmpty(this.messageIdsByStepKey, new Map());
|
|
159
|
+
this.messageStepHasToolCalls = resetIfNotEmpty(this.prelimMessageIdsByStepKey, new Map());
|
|
152
160
|
this.prelimMessageIdsByStepKey = resetIfNotEmpty(this.prelimMessageIdsByStepKey, new Map());
|
|
161
|
+
this.reasoningKey = resetIfNotEmpty(this.reasoningKey, 'reasoning_content');
|
|
162
|
+
this.currentTokenType = resetIfNotEmpty(this.currentTokenType, ContentTypes.TEXT);
|
|
163
|
+
this.lastToken = resetIfNotEmpty(this.lastToken, undefined);
|
|
164
|
+
this.tokenTypeSwitch = resetIfNotEmpty(this.tokenTypeSwitch, undefined);
|
|
153
165
|
}
|
|
154
166
|
|
|
155
167
|
/* Run Step Processing */
|
|
@@ -206,13 +218,18 @@ export class StandardGraph extends Graph<
|
|
|
206
218
|
getKeyList(metadata: Record<string, unknown> | undefined): (string | number | undefined)[] {
|
|
207
219
|
if (!metadata) return [];
|
|
208
220
|
|
|
209
|
-
|
|
221
|
+
const keyList = [
|
|
210
222
|
metadata.run_id as string,
|
|
211
223
|
metadata.thread_id as string,
|
|
212
224
|
metadata.langgraph_node as string,
|
|
213
225
|
metadata.langgraph_step as number,
|
|
214
226
|
metadata.checkpoint_ns as string,
|
|
215
227
|
];
|
|
228
|
+
if (this.currentTokenType === ContentTypes.THINK) {
|
|
229
|
+
keyList.push('reasoning');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return keyList;
|
|
216
233
|
}
|
|
217
234
|
|
|
218
235
|
checkKeyList(keyList: (string | number | undefined)[]): boolean {
|
|
@@ -286,6 +303,9 @@ export class StandardGraph extends Graph<
|
|
|
286
303
|
|
|
287
304
|
return (model as t.ModelWithTools).bindTools(this.tools);
|
|
288
305
|
}
|
|
306
|
+
overrideTestModel(responses: string[], sleep?: number): void {
|
|
307
|
+
this.boundModel = createFakeStreamingLLM(responses, sleep);
|
|
308
|
+
}
|
|
289
309
|
|
|
290
310
|
getNewModel({
|
|
291
311
|
clientOptions = {},
|
|
@@ -364,8 +384,16 @@ export class StandardGraph extends Graph<
|
|
|
364
384
|
return { messages: [finalChunk as AIMessageChunk] };
|
|
365
385
|
}
|
|
366
386
|
|
|
367
|
-
const finalMessage = await this.boundModel.invoke(finalMessages, config);
|
|
368
|
-
|
|
387
|
+
const finalMessage = (await this.boundModel.invoke(finalMessages, config)) as AIMessageChunk;
|
|
388
|
+
if ((finalMessage.tool_calls?.length ?? 0) > 0) {
|
|
389
|
+
finalMessage.tool_calls = finalMessage.tool_calls?.filter((tool_call) => {
|
|
390
|
+
if (!tool_call.name) {
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
return true;
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
return { messages: [finalMessage] };
|
|
369
397
|
};
|
|
370
398
|
}
|
|
371
399
|
|
|
@@ -502,4 +530,15 @@ export class StandardGraph extends Graph<
|
|
|
502
530
|
};
|
|
503
531
|
dispatchCustomEvent(GraphEvents.ON_MESSAGE_DELTA, messageDelta, this.config);
|
|
504
532
|
}
|
|
533
|
+
|
|
534
|
+
dispatchReasoningDelta = (stepId: string, delta: t.ReasoningDelta): void => {
|
|
535
|
+
if (!this.config) {
|
|
536
|
+
throw new Error('No config provided');
|
|
537
|
+
}
|
|
538
|
+
const reasoningDelta: t.ReasoningDeltaEvent = {
|
|
539
|
+
id: stepId,
|
|
540
|
+
delta,
|
|
541
|
+
};
|
|
542
|
+
dispatchCustomEvent(GraphEvents.ON_REASONING_DELTA, reasoningDelta, this.config);
|
|
543
|
+
};
|
|
505
544
|
}
|