@librechat/agents 1.9.5 → 1.9.7
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/llm/anthropic/llm.cjs +61 -5
- package/dist/cjs/llm/anthropic/llm.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +2 -1
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/esm/llm/anthropic/llm.mjs +61 -5
- package/dist/esm/llm/anthropic/llm.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +2 -1
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/types/llm/anthropic/llm.d.ts +11 -0
- package/dist/types/llm/anthropic/types.d.ts +28 -0
- package/package.json +3 -3
- package/src/llm/anthropic/llm.ts +71 -5
- package/src/llm/anthropic/types.ts +33 -1
- package/src/tools/ToolNode.ts +2 -1
- package/src/utils/llmConfig.ts +3 -2
|
@@ -46,19 +46,56 @@ function cloneChunk(text, tokenType, chunk) {
|
|
|
46
46
|
}
|
|
47
47
|
class CustomAnthropic extends anthropic.ChatAnthropicMessages {
|
|
48
48
|
_lc_stream_delay;
|
|
49
|
+
message_start;
|
|
50
|
+
message_delta;
|
|
51
|
+
tools_in_params;
|
|
52
|
+
emitted_usage;
|
|
49
53
|
constructor(fields) {
|
|
50
54
|
super(fields);
|
|
51
55
|
this._lc_stream_delay = fields._lc_stream_delay ?? 25;
|
|
52
56
|
}
|
|
53
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Get stream usage as returned by this client's API response.
|
|
59
|
+
* @returns {AnthropicStreamUsage} The stream usage object.
|
|
60
|
+
*/
|
|
61
|
+
getStreamUsage() {
|
|
62
|
+
if (this.emitted_usage === true) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const inputUsage = (this.message_start?.message)?.usage;
|
|
66
|
+
const outputUsage = this.message_delta?.usage;
|
|
67
|
+
if (!outputUsage) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const totalUsage = {
|
|
71
|
+
total_tokens: (inputUsage?.input_tokens ?? 0)
|
|
72
|
+
+ (inputUsage?.output_tokens ?? 0)
|
|
73
|
+
+ (inputUsage?.cache_creation_input_tokens ?? 0)
|
|
74
|
+
+ (inputUsage?.cache_read_input_tokens ?? 0)
|
|
75
|
+
+ (outputUsage.input_tokens ?? 0)
|
|
76
|
+
+ (outputUsage.output_tokens ?? 0)
|
|
77
|
+
+ (outputUsage.cache_creation_input_tokens ?? 0)
|
|
78
|
+
+ (outputUsage.cache_read_input_tokens ?? 0),
|
|
79
|
+
};
|
|
80
|
+
this.emitted_usage = true;
|
|
81
|
+
return Object.assign(totalUsage, inputUsage, outputUsage);
|
|
82
|
+
}
|
|
83
|
+
resetTokenEvents() {
|
|
84
|
+
this.message_start = undefined;
|
|
85
|
+
this.message_delta = undefined;
|
|
86
|
+
this.emitted_usage = undefined;
|
|
87
|
+
this.tools_in_params = undefined;
|
|
88
|
+
}
|
|
89
|
+
createGenerationChunk({ token, chunk, usageMetadata, shouldStreamUsage, }) {
|
|
90
|
+
const usage_metadata = shouldStreamUsage ? usageMetadata ?? chunk.usage_metadata : undefined;
|
|
54
91
|
return new outputs.ChatGenerationChunk({
|
|
55
92
|
message: new messages.AIMessageChunk({
|
|
56
93
|
// Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().
|
|
57
94
|
content: chunk.content,
|
|
58
95
|
additional_kwargs: chunk.additional_kwargs,
|
|
59
96
|
tool_call_chunks: chunk.tool_call_chunks,
|
|
60
|
-
usage_metadata: shouldStreamUsage ? chunk.usage_metadata : undefined,
|
|
61
97
|
response_metadata: chunk.response_metadata,
|
|
98
|
+
usage_metadata,
|
|
62
99
|
id: chunk.id,
|
|
63
100
|
}),
|
|
64
101
|
text: token ?? '',
|
|
@@ -67,11 +104,12 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
|
|
|
67
104
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
68
105
|
const params = this.invocationParams(options);
|
|
69
106
|
const formattedMessages = message_inputs._convertMessagesToAnthropicPayload(messages);
|
|
70
|
-
|
|
107
|
+
this.tools_in_params = _toolsInParams({
|
|
71
108
|
...params,
|
|
72
109
|
...formattedMessages,
|
|
73
110
|
stream: false,
|
|
74
111
|
});
|
|
112
|
+
const coerceContentToString = !this.tools_in_params;
|
|
75
113
|
const stream = await this.createStreamWithRetry({
|
|
76
114
|
...params,
|
|
77
115
|
...formattedMessages,
|
|
@@ -79,12 +117,23 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
|
|
|
79
117
|
}, {
|
|
80
118
|
headers: options.headers,
|
|
81
119
|
});
|
|
120
|
+
const shouldStreamUsage = this.streamUsage ?? options.streamUsage;
|
|
82
121
|
for await (const data of stream) {
|
|
83
122
|
if (options.signal?.aborted === true) {
|
|
84
123
|
stream.controller.abort();
|
|
85
124
|
throw new Error('AbortError: User aborted the request.');
|
|
86
125
|
}
|
|
87
|
-
const
|
|
126
|
+
const type = data.type ?? '';
|
|
127
|
+
if (type === 'message_start') {
|
|
128
|
+
this.message_start = data;
|
|
129
|
+
}
|
|
130
|
+
else if (type === 'message_delta') {
|
|
131
|
+
this.message_delta = data;
|
|
132
|
+
}
|
|
133
|
+
let usageMetadata;
|
|
134
|
+
if (this.tools_in_params !== true && this.emitted_usage !== true) {
|
|
135
|
+
usageMetadata = this.getStreamUsage();
|
|
136
|
+
}
|
|
88
137
|
const result = message_outputs._makeMessageChunkFromAnthropicEvent(data, {
|
|
89
138
|
streamUsage: shouldStreamUsage,
|
|
90
139
|
coerceContentToString,
|
|
@@ -93,10 +142,11 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
|
|
|
93
142
|
continue;
|
|
94
143
|
const { chunk } = result;
|
|
95
144
|
const [token = '', tokenType] = extractToken(chunk);
|
|
96
|
-
if (!tokenType || tokenType === 'input') {
|
|
145
|
+
if (!tokenType || tokenType === 'input' || (token === '' && usageMetadata)) {
|
|
97
146
|
const generationChunk = this.createGenerationChunk({
|
|
98
147
|
token,
|
|
99
148
|
chunk,
|
|
149
|
+
usageMetadata,
|
|
100
150
|
shouldStreamUsage,
|
|
101
151
|
});
|
|
102
152
|
yield generationChunk;
|
|
@@ -111,13 +161,18 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
|
|
|
111
161
|
});
|
|
112
162
|
const generator = textStream.generateText();
|
|
113
163
|
try {
|
|
164
|
+
let emittedUsage = false;
|
|
114
165
|
for await (const currentToken of generator) {
|
|
115
166
|
const newChunk = cloneChunk(currentToken, tokenType, chunk);
|
|
116
167
|
const generationChunk = this.createGenerationChunk({
|
|
117
168
|
token: currentToken,
|
|
118
169
|
chunk: newChunk,
|
|
170
|
+
usageMetadata: emittedUsage ? undefined : usageMetadata,
|
|
119
171
|
shouldStreamUsage,
|
|
120
172
|
});
|
|
173
|
+
if (usageMetadata && !emittedUsage) {
|
|
174
|
+
emittedUsage = true;
|
|
175
|
+
}
|
|
121
176
|
yield generationChunk;
|
|
122
177
|
await runManager?.handleLLMNewToken(token, undefined, undefined, undefined, undefined, { chunk: generationChunk });
|
|
123
178
|
}
|
|
@@ -126,6 +181,7 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
|
|
|
126
181
|
await generator.return();
|
|
127
182
|
}
|
|
128
183
|
}
|
|
184
|
+
this.resetTokenEvents();
|
|
129
185
|
}
|
|
130
186
|
}
|
|
131
187
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.cjs","sources":["../../../../src/llm/anthropic/llm.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { AnthropicMessageCreateParams } from '@/llm/anthropic/types';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { _convertMessagesToAnthropicPayload } from './utils/message_inputs';\nimport { TextStream } from '@/llm/text';\n\nfunction _toolsInParams(params: AnthropicMessageCreateParams): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n\nfunction extractToken(chunk: AIMessageChunk): [string, 'string' | 'input' | 'content'] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n return [chunk.content[0].text, 'content'];\n }\n return [undefined];\n}\n\nfunction cloneChunk(text: string, tokenType: string, chunk: AIMessageChunk): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (tokenType === 'content' && content.type === 'text') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n } else if (tokenType === 'content' && content.type === 'text_delta') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n }\n\n return chunk;\n}\n\nexport type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number };\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n constructor(fields: CustomAnthropicInput) {\n super(fields);\n this._lc_stream_delay = fields._lc_stream_delay ?? 25;\n }\n\n private createGenerationChunk({\n token,\n chunk,\n shouldStreamUsage,\n }: {\n token?: string,\n chunk: AIMessageChunk,\n shouldStreamUsage: boolean\n }): ChatGenerationChunk {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().\n content: chunk.content,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: chunk.tool_call_chunks,\n usage_metadata: shouldStreamUsage ? chunk.usage_metadata : undefined,\n response_metadata: chunk.response_metadata,\n id: chunk.id,\n }),\n text: token ?? '',\n });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const coerceContentToString = !_toolsInParams({\n ...params,\n ...formattedMessages,\n stream: false,\n });\n\n const stream = await this.createStreamWithRetry(\n {\n ...params,\n ...formattedMessages,\n stream: true,\n },\n {\n headers: options.headers,\n }\n );\n\n for await (const data of stream) {\n if (options.signal?.aborted === true) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n\n const shouldStreamUsage = this.streamUsage ?? options.streamUsage;\n const result = _makeMessageChunkFromAnthropicEvent(data, {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n });\n if (!result) continue;\n\n const { chunk } = result;\n const [token = '', tokenType] = extractToken(chunk);\n\n if (!tokenType || tokenType === 'input') {\n const generationChunk = this.createGenerationChunk({\n token,\n chunk,\n shouldStreamUsage,\n });\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n continue;\n }\n\n const textStream = new TextStream(token, {\n delay: this._lc_stream_delay,\n firstWordChunk: true,\n minChunkSize: 4,\n maxChunkSize: 8,\n });\n\n const generator = textStream.generateText();\n try {\n for await (const currentToken of generator) {\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n const generationChunk = this.createGenerationChunk({\n token: currentToken,\n chunk: newChunk,\n shouldStreamUsage,\n });\n yield generationChunk;\n\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n }\n } finally {\n await generator.return();\n }\n }\n }\n}"],"names":["AIMessageChunk","ChatAnthropicMessages","ChatGenerationChunk","_convertMessagesToAnthropicPayload","_makeMessageChunkFromAnthropicEvent","TextStream"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"llm.cjs","sources":["../../../../src/llm/anthropic/llm.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { AnthropicMessageCreateParams, AnthropicStreamUsage, AnthropicMessageStartEvent, AnthropicMessageDeltaEvent } from '@/llm/anthropic/types';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { _convertMessagesToAnthropicPayload } from './utils/message_inputs';\nimport { TextStream } from '@/llm/text';\n\nfunction _toolsInParams(params: AnthropicMessageCreateParams): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n\nfunction extractToken(chunk: AIMessageChunk): [string, 'string' | 'input' | 'content'] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n return [chunk.content[0].text, 'content'];\n }\n return [undefined];\n}\n\nfunction cloneChunk(text: string, tokenType: string, chunk: AIMessageChunk): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (tokenType === 'content' && content.type === 'text') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n } else if (tokenType === 'content' && content.type === 'text_delta') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n }\n\n return chunk;\n}\n\nexport type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number };\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n private message_start: AnthropicMessageStartEvent | undefined;\n private message_delta: AnthropicMessageDeltaEvent | undefined;\n private tools_in_params?: boolean;\n private emitted_usage?: boolean;\n constructor(fields: CustomAnthropicInput) {\n super(fields);\n this._lc_stream_delay = fields._lc_stream_delay ?? 25;\n }\n\n /**\n * Get stream usage as returned by this client's API response.\n * @returns {AnthropicStreamUsage} The stream usage object.\n */\n getStreamUsage(): AnthropicStreamUsage | undefined {\n if (this.emitted_usage === true) {\n return;\n }\n const inputUsage = (this.message_start?.message)?.usage as undefined | AnthropicStreamUsage;\n const outputUsage = this.message_delta?.usage as undefined | Partial<AnthropicStreamUsage>;\n if (!outputUsage) {\n return;\n }\n const totalUsage = {\n total_tokens: (inputUsage?.input_tokens ?? 0)\n + (inputUsage?.output_tokens ?? 0)\n + (inputUsage?.cache_creation_input_tokens ?? 0)\n + (inputUsage?.cache_read_input_tokens ?? 0)\n + (outputUsage.input_tokens ?? 0)\n + (outputUsage.output_tokens ?? 0)\n + (outputUsage.cache_creation_input_tokens ?? 0)\n + (outputUsage.cache_read_input_tokens ?? 0),\n };\n\n this.emitted_usage = true;\n return Object.assign(totalUsage, inputUsage, outputUsage);\n }\n\n resetTokenEvents(): void {\n this.message_start = undefined;\n this.message_delta = undefined;\n this.emitted_usage = undefined;\n this.tools_in_params = undefined;\n }\n\n private createGenerationChunk({\n token,\n chunk,\n usageMetadata,\n shouldStreamUsage,\n }: {\n token?: string,\n chunk: AIMessageChunk,\n shouldStreamUsage: boolean\n usageMetadata?: AnthropicStreamUsage,\n }): ChatGenerationChunk {\n const usage_metadata = shouldStreamUsage ? usageMetadata ?? chunk.usage_metadata : undefined;\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().\n content: chunk.content,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: chunk.tool_call_chunks,\n response_metadata: chunk.response_metadata,\n usage_metadata,\n id: chunk.id,\n }),\n text: token ?? '',\n });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n this.tools_in_params = _toolsInParams({\n ...params,\n ...formattedMessages,\n stream: false,\n });\n const coerceContentToString = !this.tools_in_params;\n\n const stream = await this.createStreamWithRetry(\n {\n ...params,\n ...formattedMessages,\n stream: true,\n },\n {\n headers: options.headers,\n }\n );\n\n const shouldStreamUsage = this.streamUsage ?? options.streamUsage;\n\n for await (const data of stream) {\n if (options.signal?.aborted === true) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n\n const type = data.type ?? '';\n if (type === 'message_start') {\n this.message_start = data as AnthropicMessageStartEvent;\n } else if (type === 'message_delta') {\n this.message_delta = data as AnthropicMessageDeltaEvent;\n }\n\n let usageMetadata: AnthropicStreamUsage | undefined;\n if (this.tools_in_params !== true && this.emitted_usage !== true) {\n usageMetadata = this.getStreamUsage();\n }\n\n const result = _makeMessageChunkFromAnthropicEvent(data, {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n });\n if (!result) continue;\n\n const { chunk } = result;\n const [token = '', tokenType] = extractToken(chunk);\n\n if (!tokenType || tokenType === 'input' || (token === '' && usageMetadata)) {\n const generationChunk = this.createGenerationChunk({\n token,\n chunk,\n usageMetadata,\n shouldStreamUsage,\n });\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n continue;\n }\n\n const textStream = new TextStream(token, {\n delay: this._lc_stream_delay,\n firstWordChunk: true,\n minChunkSize: 4,\n maxChunkSize: 8,\n });\n\n const generator = textStream.generateText();\n try {\n let emittedUsage = false;\n for await (const currentToken of generator) {\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n\n const generationChunk = this.createGenerationChunk({\n token: currentToken,\n chunk: newChunk,\n usageMetadata: emittedUsage ? undefined : usageMetadata,\n shouldStreamUsage,\n });\n\n if (usageMetadata && !emittedUsage) {\n emittedUsage = true;\n }\n yield generationChunk;\n\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n }\n } finally {\n await generator.return();\n }\n }\n\n this.resetTokenEvents();\n }\n}"],"names":["AIMessageChunk","ChatAnthropicMessages","ChatGenerationChunk","_convertMessagesToAnthropicPayload","_makeMessageChunkFromAnthropicEvent","TextStream"],"mappings":"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"}
|
|
@@ -38,7 +38,8 @@ class ToolNode extends run.RunnableCallable {
|
|
|
38
38
|
if (tool === undefined) {
|
|
39
39
|
throw new Error(`Tool "${call.name}" not found.`);
|
|
40
40
|
}
|
|
41
|
-
const
|
|
41
|
+
const provider = config.metadata?.provider;
|
|
42
|
+
const args = provider === _enum.Providers.GOOGLE || provider === _enum.Providers.VERTEXAI ? misc.unescapeObject(call.args) : call.args;
|
|
42
43
|
const output = await tool.invoke({ ...call, args, type: 'tool_call' }, config);
|
|
43
44
|
if ((messages.isBaseMessage(output) && output._getType() === 'tool') ||
|
|
44
45
|
langgraph.isCommand(output)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolNode.cjs","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, unescapeObject } from '@/utils';\nimport { GraphNodeKeys, Providers } 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\n constructor({\n tools,\n toolMap,\n name,\n tags,\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.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
|
|
1
|
+
{"version":3,"file":"ToolNode.cjs","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, unescapeObject } from '@/utils';\nimport { GraphNodeKeys, Providers } 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\n constructor({\n tools,\n toolMap,\n name,\n tags,\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.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 provider = config.metadata?.provider;\n const args = provider === Providers.GOOGLE || provider === Providers.VERTEXAI ? unescapeObject(call.args) : call.args;\n const output = await tool.invoke(\n { ...call, args, type: 'tool_call' },\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":["RunnableCallable","Providers","unescapeObject","isBaseMessage","isCommand","ToolMessage","isGraphInterrupt","GraphNodeKeys","END"],"mappings":"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"}
|
|
@@ -44,19 +44,56 @@ function cloneChunk(text, tokenType, chunk) {
|
|
|
44
44
|
}
|
|
45
45
|
class CustomAnthropic extends ChatAnthropicMessages {
|
|
46
46
|
_lc_stream_delay;
|
|
47
|
+
message_start;
|
|
48
|
+
message_delta;
|
|
49
|
+
tools_in_params;
|
|
50
|
+
emitted_usage;
|
|
47
51
|
constructor(fields) {
|
|
48
52
|
super(fields);
|
|
49
53
|
this._lc_stream_delay = fields._lc_stream_delay ?? 25;
|
|
50
54
|
}
|
|
51
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Get stream usage as returned by this client's API response.
|
|
57
|
+
* @returns {AnthropicStreamUsage} The stream usage object.
|
|
58
|
+
*/
|
|
59
|
+
getStreamUsage() {
|
|
60
|
+
if (this.emitted_usage === true) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const inputUsage = (this.message_start?.message)?.usage;
|
|
64
|
+
const outputUsage = this.message_delta?.usage;
|
|
65
|
+
if (!outputUsage) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const totalUsage = {
|
|
69
|
+
total_tokens: (inputUsage?.input_tokens ?? 0)
|
|
70
|
+
+ (inputUsage?.output_tokens ?? 0)
|
|
71
|
+
+ (inputUsage?.cache_creation_input_tokens ?? 0)
|
|
72
|
+
+ (inputUsage?.cache_read_input_tokens ?? 0)
|
|
73
|
+
+ (outputUsage.input_tokens ?? 0)
|
|
74
|
+
+ (outputUsage.output_tokens ?? 0)
|
|
75
|
+
+ (outputUsage.cache_creation_input_tokens ?? 0)
|
|
76
|
+
+ (outputUsage.cache_read_input_tokens ?? 0),
|
|
77
|
+
};
|
|
78
|
+
this.emitted_usage = true;
|
|
79
|
+
return Object.assign(totalUsage, inputUsage, outputUsage);
|
|
80
|
+
}
|
|
81
|
+
resetTokenEvents() {
|
|
82
|
+
this.message_start = undefined;
|
|
83
|
+
this.message_delta = undefined;
|
|
84
|
+
this.emitted_usage = undefined;
|
|
85
|
+
this.tools_in_params = undefined;
|
|
86
|
+
}
|
|
87
|
+
createGenerationChunk({ token, chunk, usageMetadata, shouldStreamUsage, }) {
|
|
88
|
+
const usage_metadata = shouldStreamUsage ? usageMetadata ?? chunk.usage_metadata : undefined;
|
|
52
89
|
return new ChatGenerationChunk({
|
|
53
90
|
message: new AIMessageChunk({
|
|
54
91
|
// Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().
|
|
55
92
|
content: chunk.content,
|
|
56
93
|
additional_kwargs: chunk.additional_kwargs,
|
|
57
94
|
tool_call_chunks: chunk.tool_call_chunks,
|
|
58
|
-
usage_metadata: shouldStreamUsage ? chunk.usage_metadata : undefined,
|
|
59
95
|
response_metadata: chunk.response_metadata,
|
|
96
|
+
usage_metadata,
|
|
60
97
|
id: chunk.id,
|
|
61
98
|
}),
|
|
62
99
|
text: token ?? '',
|
|
@@ -65,11 +102,12 @@ class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
65
102
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
66
103
|
const params = this.invocationParams(options);
|
|
67
104
|
const formattedMessages = _convertMessagesToAnthropicPayload(messages);
|
|
68
|
-
|
|
105
|
+
this.tools_in_params = _toolsInParams({
|
|
69
106
|
...params,
|
|
70
107
|
...formattedMessages,
|
|
71
108
|
stream: false,
|
|
72
109
|
});
|
|
110
|
+
const coerceContentToString = !this.tools_in_params;
|
|
73
111
|
const stream = await this.createStreamWithRetry({
|
|
74
112
|
...params,
|
|
75
113
|
...formattedMessages,
|
|
@@ -77,12 +115,23 @@ class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
77
115
|
}, {
|
|
78
116
|
headers: options.headers,
|
|
79
117
|
});
|
|
118
|
+
const shouldStreamUsage = this.streamUsage ?? options.streamUsage;
|
|
80
119
|
for await (const data of stream) {
|
|
81
120
|
if (options.signal?.aborted === true) {
|
|
82
121
|
stream.controller.abort();
|
|
83
122
|
throw new Error('AbortError: User aborted the request.');
|
|
84
123
|
}
|
|
85
|
-
const
|
|
124
|
+
const type = data.type ?? '';
|
|
125
|
+
if (type === 'message_start') {
|
|
126
|
+
this.message_start = data;
|
|
127
|
+
}
|
|
128
|
+
else if (type === 'message_delta') {
|
|
129
|
+
this.message_delta = data;
|
|
130
|
+
}
|
|
131
|
+
let usageMetadata;
|
|
132
|
+
if (this.tools_in_params !== true && this.emitted_usage !== true) {
|
|
133
|
+
usageMetadata = this.getStreamUsage();
|
|
134
|
+
}
|
|
86
135
|
const result = _makeMessageChunkFromAnthropicEvent(data, {
|
|
87
136
|
streamUsage: shouldStreamUsage,
|
|
88
137
|
coerceContentToString,
|
|
@@ -91,10 +140,11 @@ class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
91
140
|
continue;
|
|
92
141
|
const { chunk } = result;
|
|
93
142
|
const [token = '', tokenType] = extractToken(chunk);
|
|
94
|
-
if (!tokenType || tokenType === 'input') {
|
|
143
|
+
if (!tokenType || tokenType === 'input' || (token === '' && usageMetadata)) {
|
|
95
144
|
const generationChunk = this.createGenerationChunk({
|
|
96
145
|
token,
|
|
97
146
|
chunk,
|
|
147
|
+
usageMetadata,
|
|
98
148
|
shouldStreamUsage,
|
|
99
149
|
});
|
|
100
150
|
yield generationChunk;
|
|
@@ -109,13 +159,18 @@ class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
109
159
|
});
|
|
110
160
|
const generator = textStream.generateText();
|
|
111
161
|
try {
|
|
162
|
+
let emittedUsage = false;
|
|
112
163
|
for await (const currentToken of generator) {
|
|
113
164
|
const newChunk = cloneChunk(currentToken, tokenType, chunk);
|
|
114
165
|
const generationChunk = this.createGenerationChunk({
|
|
115
166
|
token: currentToken,
|
|
116
167
|
chunk: newChunk,
|
|
168
|
+
usageMetadata: emittedUsage ? undefined : usageMetadata,
|
|
117
169
|
shouldStreamUsage,
|
|
118
170
|
});
|
|
171
|
+
if (usageMetadata && !emittedUsage) {
|
|
172
|
+
emittedUsage = true;
|
|
173
|
+
}
|
|
119
174
|
yield generationChunk;
|
|
120
175
|
await runManager?.handleLLMNewToken(token, undefined, undefined, undefined, undefined, { chunk: generationChunk });
|
|
121
176
|
}
|
|
@@ -124,6 +179,7 @@ class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
124
179
|
await generator.return();
|
|
125
180
|
}
|
|
126
181
|
}
|
|
182
|
+
this.resetTokenEvents();
|
|
127
183
|
}
|
|
128
184
|
}
|
|
129
185
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.mjs","sources":["../../../../src/llm/anthropic/llm.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { AnthropicMessageCreateParams } from '@/llm/anthropic/types';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { _convertMessagesToAnthropicPayload } from './utils/message_inputs';\nimport { TextStream } from '@/llm/text';\n\nfunction _toolsInParams(params: AnthropicMessageCreateParams): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n\nfunction extractToken(chunk: AIMessageChunk): [string, 'string' | 'input' | 'content'] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n return [chunk.content[0].text, 'content'];\n }\n return [undefined];\n}\n\nfunction cloneChunk(text: string, tokenType: string, chunk: AIMessageChunk): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (tokenType === 'content' && content.type === 'text') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n } else if (tokenType === 'content' && content.type === 'text_delta') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n }\n\n return chunk;\n}\n\nexport type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number };\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n constructor(fields: CustomAnthropicInput) {\n super(fields);\n this._lc_stream_delay = fields._lc_stream_delay ?? 25;\n }\n\n private createGenerationChunk({\n token,\n chunk,\n shouldStreamUsage,\n }: {\n token?: string,\n chunk: AIMessageChunk,\n shouldStreamUsage: boolean\n }): ChatGenerationChunk {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().\n content: chunk.content,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: chunk.tool_call_chunks,\n usage_metadata: shouldStreamUsage ? chunk.usage_metadata : undefined,\n response_metadata: chunk.response_metadata,\n id: chunk.id,\n }),\n text: token ?? '',\n });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const coerceContentToString = !_toolsInParams({\n ...params,\n ...formattedMessages,\n stream: false,\n });\n\n const stream = await this.createStreamWithRetry(\n {\n ...params,\n ...formattedMessages,\n stream: true,\n },\n {\n headers: options.headers,\n }\n );\n\n for await (const data of stream) {\n if (options.signal?.aborted === true) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n\n const shouldStreamUsage = this.streamUsage ?? options.streamUsage;\n const result = _makeMessageChunkFromAnthropicEvent(data, {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n });\n if (!result) continue;\n\n const { chunk } = result;\n const [token = '', tokenType] = extractToken(chunk);\n\n if (!tokenType || tokenType === 'input') {\n const generationChunk = this.createGenerationChunk({\n token,\n chunk,\n shouldStreamUsage,\n });\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n continue;\n }\n\n const textStream = new TextStream(token, {\n delay: this._lc_stream_delay,\n firstWordChunk: true,\n minChunkSize: 4,\n maxChunkSize: 8,\n });\n\n const generator = textStream.generateText();\n try {\n for await (const currentToken of generator) {\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n const generationChunk = this.createGenerationChunk({\n token: currentToken,\n chunk: newChunk,\n shouldStreamUsage,\n });\n yield generationChunk;\n\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n }\n } finally {\n await generator.return();\n }\n }\n }\n}"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"llm.mjs","sources":["../../../../src/llm/anthropic/llm.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { AnthropicMessageCreateParams, AnthropicStreamUsage, AnthropicMessageStartEvent, AnthropicMessageDeltaEvent } from '@/llm/anthropic/types';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { _convertMessagesToAnthropicPayload } from './utils/message_inputs';\nimport { TextStream } from '@/llm/text';\n\nfunction _toolsInParams(params: AnthropicMessageCreateParams): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n\nfunction extractToken(chunk: AIMessageChunk): [string, 'string' | 'input' | 'content'] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n return [chunk.content[0].text, 'content'];\n }\n return [undefined];\n}\n\nfunction cloneChunk(text: string, tokenType: string, chunk: AIMessageChunk): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (tokenType === 'content' && content.type === 'text') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n } else if (tokenType === 'content' && content.type === 'text_delta') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n }\n\n return chunk;\n}\n\nexport type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number };\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n private message_start: AnthropicMessageStartEvent | undefined;\n private message_delta: AnthropicMessageDeltaEvent | undefined;\n private tools_in_params?: boolean;\n private emitted_usage?: boolean;\n constructor(fields: CustomAnthropicInput) {\n super(fields);\n this._lc_stream_delay = fields._lc_stream_delay ?? 25;\n }\n\n /**\n * Get stream usage as returned by this client's API response.\n * @returns {AnthropicStreamUsage} The stream usage object.\n */\n getStreamUsage(): AnthropicStreamUsage | undefined {\n if (this.emitted_usage === true) {\n return;\n }\n const inputUsage = (this.message_start?.message)?.usage as undefined | AnthropicStreamUsage;\n const outputUsage = this.message_delta?.usage as undefined | Partial<AnthropicStreamUsage>;\n if (!outputUsage) {\n return;\n }\n const totalUsage = {\n total_tokens: (inputUsage?.input_tokens ?? 0)\n + (inputUsage?.output_tokens ?? 0)\n + (inputUsage?.cache_creation_input_tokens ?? 0)\n + (inputUsage?.cache_read_input_tokens ?? 0)\n + (outputUsage.input_tokens ?? 0)\n + (outputUsage.output_tokens ?? 0)\n + (outputUsage.cache_creation_input_tokens ?? 0)\n + (outputUsage.cache_read_input_tokens ?? 0),\n };\n\n this.emitted_usage = true;\n return Object.assign(totalUsage, inputUsage, outputUsage);\n }\n\n resetTokenEvents(): void {\n this.message_start = undefined;\n this.message_delta = undefined;\n this.emitted_usage = undefined;\n this.tools_in_params = undefined;\n }\n\n private createGenerationChunk({\n token,\n chunk,\n usageMetadata,\n shouldStreamUsage,\n }: {\n token?: string,\n chunk: AIMessageChunk,\n shouldStreamUsage: boolean\n usageMetadata?: AnthropicStreamUsage,\n }): ChatGenerationChunk {\n const usage_metadata = shouldStreamUsage ? usageMetadata ?? chunk.usage_metadata : undefined;\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().\n content: chunk.content,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: chunk.tool_call_chunks,\n response_metadata: chunk.response_metadata,\n usage_metadata,\n id: chunk.id,\n }),\n text: token ?? '',\n });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n this.tools_in_params = _toolsInParams({\n ...params,\n ...formattedMessages,\n stream: false,\n });\n const coerceContentToString = !this.tools_in_params;\n\n const stream = await this.createStreamWithRetry(\n {\n ...params,\n ...formattedMessages,\n stream: true,\n },\n {\n headers: options.headers,\n }\n );\n\n const shouldStreamUsage = this.streamUsage ?? options.streamUsage;\n\n for await (const data of stream) {\n if (options.signal?.aborted === true) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n\n const type = data.type ?? '';\n if (type === 'message_start') {\n this.message_start = data as AnthropicMessageStartEvent;\n } else if (type === 'message_delta') {\n this.message_delta = data as AnthropicMessageDeltaEvent;\n }\n\n let usageMetadata: AnthropicStreamUsage | undefined;\n if (this.tools_in_params !== true && this.emitted_usage !== true) {\n usageMetadata = this.getStreamUsage();\n }\n\n const result = _makeMessageChunkFromAnthropicEvent(data, {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n });\n if (!result) continue;\n\n const { chunk } = result;\n const [token = '', tokenType] = extractToken(chunk);\n\n if (!tokenType || tokenType === 'input' || (token === '' && usageMetadata)) {\n const generationChunk = this.createGenerationChunk({\n token,\n chunk,\n usageMetadata,\n shouldStreamUsage,\n });\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n continue;\n }\n\n const textStream = new TextStream(token, {\n delay: this._lc_stream_delay,\n firstWordChunk: true,\n minChunkSize: 4,\n maxChunkSize: 8,\n });\n\n const generator = textStream.generateText();\n try {\n let emittedUsage = false;\n for await (const currentToken of generator) {\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n\n const generationChunk = this.createGenerationChunk({\n token: currentToken,\n chunk: newChunk,\n usageMetadata: emittedUsage ? undefined : usageMetadata,\n shouldStreamUsage,\n });\n\n if (usageMetadata && !emittedUsage) {\n emittedUsage = true;\n }\n yield generationChunk;\n\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n }\n } finally {\n await generator.return();\n }\n }\n\n this.resetTokenEvents();\n }\n}"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,8 @@ class ToolNode extends RunnableCallable {
|
|
|
36
36
|
if (tool === undefined) {
|
|
37
37
|
throw new Error(`Tool "${call.name}" not found.`);
|
|
38
38
|
}
|
|
39
|
-
const
|
|
39
|
+
const provider = config.metadata?.provider;
|
|
40
|
+
const args = provider === Providers.GOOGLE || provider === Providers.VERTEXAI ? unescapeObject(call.args) : call.args;
|
|
40
41
|
const output = await tool.invoke({ ...call, args, type: 'tool_call' }, config);
|
|
41
42
|
if ((isBaseMessage(output) && output._getType() === 'tool') ||
|
|
42
43
|
isCommand(output)) {
|
|
@@ -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, unescapeObject } from '@/utils';\nimport { GraphNodeKeys, Providers } 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\n constructor({\n tools,\n toolMap,\n name,\n tags,\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.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
|
|
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, unescapeObject } from '@/utils';\nimport { GraphNodeKeys, Providers } 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\n constructor({\n tools,\n toolMap,\n name,\n tags,\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.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 provider = config.metadata?.provider;\n const args = provider === Providers.GOOGLE || provider === Providers.VERTEXAI ? unescapeObject(call.args) : call.args;\n const output = await tool.invoke(\n { ...call, args, type: 'tool_call' },\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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"}
|
|
@@ -3,12 +3,23 @@ import { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
|
3
3
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
4
4
|
import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
|
|
5
5
|
import type { AnthropicInput } from '@langchain/anthropic';
|
|
6
|
+
import type { AnthropicStreamUsage } from '@/llm/anthropic/types';
|
|
6
7
|
export type CustomAnthropicInput = AnthropicInput & {
|
|
7
8
|
_lc_stream_delay?: number;
|
|
8
9
|
};
|
|
9
10
|
export declare class CustomAnthropic extends ChatAnthropicMessages {
|
|
10
11
|
_lc_stream_delay: number;
|
|
12
|
+
private message_start;
|
|
13
|
+
private message_delta;
|
|
14
|
+
private tools_in_params?;
|
|
15
|
+
private emitted_usage?;
|
|
11
16
|
constructor(fields: CustomAnthropicInput);
|
|
17
|
+
/**
|
|
18
|
+
* Get stream usage as returned by this client's API response.
|
|
19
|
+
* @returns {AnthropicStreamUsage} The stream usage object.
|
|
20
|
+
*/
|
|
21
|
+
getStreamUsage(): AnthropicStreamUsage | undefined;
|
|
22
|
+
resetTokenEvents(): void;
|
|
12
23
|
private createGenerationChunk;
|
|
13
24
|
_streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
|
|
14
25
|
}
|
|
@@ -8,6 +8,8 @@ export type AnthropicToolResponse = {
|
|
|
8
8
|
input: Record<string, any>;
|
|
9
9
|
};
|
|
10
10
|
export type AnthropicMessageParam = Anthropic.MessageParam;
|
|
11
|
+
export type AnthropicMessageDeltaEvent = Anthropic.MessageDeltaEvent;
|
|
12
|
+
export type AnthropicMessageStartEvent = Anthropic.MessageStartEvent;
|
|
11
13
|
export type AnthropicMessageResponse = Anthropic.ContentBlock | AnthropicToolResponse;
|
|
12
14
|
export type AnthropicMessageCreateParams = Anthropic.MessageCreateParamsNonStreaming;
|
|
13
15
|
export type AnthropicStreamingMessageCreateParams = Anthropic.MessageCreateParamsStreaming;
|
|
@@ -22,3 +24,29 @@ export type AnthropicTextBlockParam = Anthropic.Messages.TextBlockParam;
|
|
|
22
24
|
export type AnthropicImageBlockParam = Anthropic.Messages.ImageBlockParam;
|
|
23
25
|
export type AnthropicToolUseBlockParam = Anthropic.Messages.ToolUseBlockParam;
|
|
24
26
|
export type AnthropicToolResultBlockParam = Anthropic.Messages.ToolResultBlockParam;
|
|
27
|
+
/**
|
|
28
|
+
* Stream usage information for Anthropic API calls
|
|
29
|
+
* @see https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching#pricing
|
|
30
|
+
*/
|
|
31
|
+
export interface AnthropicStreamUsage {
|
|
32
|
+
/**
|
|
33
|
+
* The number of input tokens used in the request
|
|
34
|
+
*/
|
|
35
|
+
input_tokens: number;
|
|
36
|
+
/**
|
|
37
|
+
* The number of cache creation input tokens used (write operations)
|
|
38
|
+
*/
|
|
39
|
+
cache_creation_input_tokens?: number;
|
|
40
|
+
/**
|
|
41
|
+
* The number of cache input tokens used (read operations)
|
|
42
|
+
*/
|
|
43
|
+
cache_read_input_tokens?: number;
|
|
44
|
+
/**
|
|
45
|
+
* The number of output tokens generated in the response
|
|
46
|
+
*/
|
|
47
|
+
output_tokens: number;
|
|
48
|
+
/**
|
|
49
|
+
* The total number of tokens generated in the response
|
|
50
|
+
*/
|
|
51
|
+
total_tokens: number;
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@librechat/agents",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.7",
|
|
4
4
|
"main": "./dist/cjs/main.cjs",
|
|
5
5
|
"module": "./dist/esm/main.mjs",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"start:cli": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/cli.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
|
|
43
43
|
"content": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/content.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
|
|
44
44
|
"stream": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/stream.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
|
|
45
|
-
"code_exec": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec.ts --provider '
|
|
45
|
+
"code_exec": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec.ts --provider 'vertexai' --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 'anthropic' --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 'anthropic' --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 'vertexai' --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
50
|
"tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider 'anthropic' --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'",
|
package/src/llm/anthropic/llm.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
|
4
4
|
import type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';
|
|
5
5
|
import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
|
|
6
6
|
import type { AnthropicInput } from '@langchain/anthropic';
|
|
7
|
-
import type { AnthropicMessageCreateParams } from '@/llm/anthropic/types';
|
|
7
|
+
import type { AnthropicMessageCreateParams, AnthropicStreamUsage, AnthropicMessageStartEvent, AnthropicMessageDeltaEvent } from '@/llm/anthropic/types';
|
|
8
8
|
import { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';
|
|
9
9
|
import { _convertMessagesToAnthropicPayload } from './utils/message_inputs';
|
|
10
10
|
import { TextStream } from '@/llm/text';
|
|
@@ -54,28 +54,70 @@ export type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number
|
|
|
54
54
|
|
|
55
55
|
export class CustomAnthropic extends ChatAnthropicMessages {
|
|
56
56
|
_lc_stream_delay: number;
|
|
57
|
+
private message_start: AnthropicMessageStartEvent | undefined;
|
|
58
|
+
private message_delta: AnthropicMessageDeltaEvent | undefined;
|
|
59
|
+
private tools_in_params?: boolean;
|
|
60
|
+
private emitted_usage?: boolean;
|
|
57
61
|
constructor(fields: CustomAnthropicInput) {
|
|
58
62
|
super(fields);
|
|
59
63
|
this._lc_stream_delay = fields._lc_stream_delay ?? 25;
|
|
60
64
|
}
|
|
61
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Get stream usage as returned by this client's API response.
|
|
68
|
+
* @returns {AnthropicStreamUsage} The stream usage object.
|
|
69
|
+
*/
|
|
70
|
+
getStreamUsage(): AnthropicStreamUsage | undefined {
|
|
71
|
+
if (this.emitted_usage === true) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const inputUsage = (this.message_start?.message)?.usage as undefined | AnthropicStreamUsage;
|
|
75
|
+
const outputUsage = this.message_delta?.usage as undefined | Partial<AnthropicStreamUsage>;
|
|
76
|
+
if (!outputUsage) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const totalUsage = {
|
|
80
|
+
total_tokens: (inputUsage?.input_tokens ?? 0)
|
|
81
|
+
+ (inputUsage?.output_tokens ?? 0)
|
|
82
|
+
+ (inputUsage?.cache_creation_input_tokens ?? 0)
|
|
83
|
+
+ (inputUsage?.cache_read_input_tokens ?? 0)
|
|
84
|
+
+ (outputUsage.input_tokens ?? 0)
|
|
85
|
+
+ (outputUsage.output_tokens ?? 0)
|
|
86
|
+
+ (outputUsage.cache_creation_input_tokens ?? 0)
|
|
87
|
+
+ (outputUsage.cache_read_input_tokens ?? 0),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
this.emitted_usage = true;
|
|
91
|
+
return Object.assign(totalUsage, inputUsage, outputUsage);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
resetTokenEvents(): void {
|
|
95
|
+
this.message_start = undefined;
|
|
96
|
+
this.message_delta = undefined;
|
|
97
|
+
this.emitted_usage = undefined;
|
|
98
|
+
this.tools_in_params = undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
62
101
|
private createGenerationChunk({
|
|
63
102
|
token,
|
|
64
103
|
chunk,
|
|
104
|
+
usageMetadata,
|
|
65
105
|
shouldStreamUsage,
|
|
66
106
|
}: {
|
|
67
107
|
token?: string,
|
|
68
108
|
chunk: AIMessageChunk,
|
|
69
109
|
shouldStreamUsage: boolean
|
|
110
|
+
usageMetadata?: AnthropicStreamUsage,
|
|
70
111
|
}): ChatGenerationChunk {
|
|
112
|
+
const usage_metadata = shouldStreamUsage ? usageMetadata ?? chunk.usage_metadata : undefined;
|
|
71
113
|
return new ChatGenerationChunk({
|
|
72
114
|
message: new AIMessageChunk({
|
|
73
115
|
// Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().
|
|
74
116
|
content: chunk.content,
|
|
75
117
|
additional_kwargs: chunk.additional_kwargs,
|
|
76
118
|
tool_call_chunks: chunk.tool_call_chunks,
|
|
77
|
-
usage_metadata: shouldStreamUsage ? chunk.usage_metadata : undefined,
|
|
78
119
|
response_metadata: chunk.response_metadata,
|
|
120
|
+
usage_metadata,
|
|
79
121
|
id: chunk.id,
|
|
80
122
|
}),
|
|
81
123
|
text: token ?? '',
|
|
@@ -89,11 +131,12 @@ export class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
89
131
|
): AsyncGenerator<ChatGenerationChunk> {
|
|
90
132
|
const params = this.invocationParams(options);
|
|
91
133
|
const formattedMessages = _convertMessagesToAnthropicPayload(messages);
|
|
92
|
-
|
|
134
|
+
this.tools_in_params = _toolsInParams({
|
|
93
135
|
...params,
|
|
94
136
|
...formattedMessages,
|
|
95
137
|
stream: false,
|
|
96
138
|
});
|
|
139
|
+
const coerceContentToString = !this.tools_in_params;
|
|
97
140
|
|
|
98
141
|
const stream = await this.createStreamWithRetry(
|
|
99
142
|
{
|
|
@@ -106,13 +149,26 @@ export class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
106
149
|
}
|
|
107
150
|
);
|
|
108
151
|
|
|
152
|
+
const shouldStreamUsage = this.streamUsage ?? options.streamUsage;
|
|
153
|
+
|
|
109
154
|
for await (const data of stream) {
|
|
110
155
|
if (options.signal?.aborted === true) {
|
|
111
156
|
stream.controller.abort();
|
|
112
157
|
throw new Error('AbortError: User aborted the request.');
|
|
113
158
|
}
|
|
114
159
|
|
|
115
|
-
const
|
|
160
|
+
const type = data.type ?? '';
|
|
161
|
+
if (type === 'message_start') {
|
|
162
|
+
this.message_start = data as AnthropicMessageStartEvent;
|
|
163
|
+
} else if (type === 'message_delta') {
|
|
164
|
+
this.message_delta = data as AnthropicMessageDeltaEvent;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let usageMetadata: AnthropicStreamUsage | undefined;
|
|
168
|
+
if (this.tools_in_params !== true && this.emitted_usage !== true) {
|
|
169
|
+
usageMetadata = this.getStreamUsage();
|
|
170
|
+
}
|
|
171
|
+
|
|
116
172
|
const result = _makeMessageChunkFromAnthropicEvent(data, {
|
|
117
173
|
streamUsage: shouldStreamUsage,
|
|
118
174
|
coerceContentToString,
|
|
@@ -122,10 +178,11 @@ export class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
122
178
|
const { chunk } = result;
|
|
123
179
|
const [token = '', tokenType] = extractToken(chunk);
|
|
124
180
|
|
|
125
|
-
if (!tokenType || tokenType === 'input') {
|
|
181
|
+
if (!tokenType || tokenType === 'input' || (token === '' && usageMetadata)) {
|
|
126
182
|
const generationChunk = this.createGenerationChunk({
|
|
127
183
|
token,
|
|
128
184
|
chunk,
|
|
185
|
+
usageMetadata,
|
|
129
186
|
shouldStreamUsage,
|
|
130
187
|
});
|
|
131
188
|
yield generationChunk;
|
|
@@ -149,13 +206,20 @@ export class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
149
206
|
|
|
150
207
|
const generator = textStream.generateText();
|
|
151
208
|
try {
|
|
209
|
+
let emittedUsage = false;
|
|
152
210
|
for await (const currentToken of generator) {
|
|
153
211
|
const newChunk = cloneChunk(currentToken, tokenType, chunk);
|
|
212
|
+
|
|
154
213
|
const generationChunk = this.createGenerationChunk({
|
|
155
214
|
token: currentToken,
|
|
156
215
|
chunk: newChunk,
|
|
216
|
+
usageMetadata: emittedUsage ? undefined : usageMetadata,
|
|
157
217
|
shouldStreamUsage,
|
|
158
218
|
});
|
|
219
|
+
|
|
220
|
+
if (usageMetadata && !emittedUsage) {
|
|
221
|
+
emittedUsage = true;
|
|
222
|
+
}
|
|
159
223
|
yield generationChunk;
|
|
160
224
|
|
|
161
225
|
await runManager?.handleLLMNewToken(
|
|
@@ -171,5 +235,7 @@ export class CustomAnthropic extends ChatAnthropicMessages {
|
|
|
171
235
|
await generator.return();
|
|
172
236
|
}
|
|
173
237
|
}
|
|
238
|
+
|
|
239
|
+
this.resetTokenEvents();
|
|
174
240
|
}
|
|
175
241
|
}
|
|
@@ -12,6 +12,8 @@ export type AnthropicToolResponse = {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
export type AnthropicMessageParam = Anthropic.MessageParam;
|
|
15
|
+
export type AnthropicMessageDeltaEvent= Anthropic.MessageDeltaEvent;
|
|
16
|
+
export type AnthropicMessageStartEvent= Anthropic.MessageStartEvent;
|
|
15
17
|
export type AnthropicMessageResponse =
|
|
16
18
|
| Anthropic.ContentBlock
|
|
17
19
|
| AnthropicToolResponse;
|
|
@@ -35,4 +37,34 @@ export type AnthropicTextBlockParam = Anthropic.Messages.TextBlockParam;
|
|
|
35
37
|
export type AnthropicImageBlockParam = Anthropic.Messages.ImageBlockParam;
|
|
36
38
|
export type AnthropicToolUseBlockParam = Anthropic.Messages.ToolUseBlockParam;
|
|
37
39
|
export type AnthropicToolResultBlockParam =
|
|
38
|
-
Anthropic.Messages.ToolResultBlockParam;
|
|
40
|
+
Anthropic.Messages.ToolResultBlockParam;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Stream usage information for Anthropic API calls
|
|
44
|
+
* @see https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching#pricing
|
|
45
|
+
*/
|
|
46
|
+
export interface AnthropicStreamUsage {
|
|
47
|
+
/**
|
|
48
|
+
* The number of input tokens used in the request
|
|
49
|
+
*/
|
|
50
|
+
input_tokens: number;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The number of cache creation input tokens used (write operations)
|
|
54
|
+
*/
|
|
55
|
+
cache_creation_input_tokens?: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The number of cache input tokens used (read operations)
|
|
59
|
+
*/
|
|
60
|
+
cache_read_input_tokens?: number;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The number of output tokens generated in the response
|
|
64
|
+
*/
|
|
65
|
+
output_tokens: number;
|
|
66
|
+
/**
|
|
67
|
+
* The total number of tokens generated in the response
|
|
68
|
+
*/
|
|
69
|
+
total_tokens: number;
|
|
70
|
+
}
|
package/src/tools/ToolNode.ts
CHANGED
|
@@ -53,7 +53,8 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
53
53
|
if (tool === undefined) {
|
|
54
54
|
throw new Error(`Tool "${call.name}" not found.`);
|
|
55
55
|
}
|
|
56
|
-
const
|
|
56
|
+
const provider = config.metadata?.provider;
|
|
57
|
+
const args = provider === Providers.GOOGLE || provider === Providers.VERTEXAI ? unescapeObject(call.args) : call.args;
|
|
57
58
|
const output = await tool.invoke(
|
|
58
59
|
{ ...call, args, type: 'tool_call' },
|
|
59
60
|
config
|
package/src/utils/llmConfig.ts
CHANGED
|
@@ -31,10 +31,11 @@ const llmConfigs: Record<string, t.LLMConfig | undefined> = {
|
|
|
31
31
|
},
|
|
32
32
|
[Providers.VERTEXAI]: {
|
|
33
33
|
provider: Providers.VERTEXAI,
|
|
34
|
-
modelName: 'gemini-
|
|
34
|
+
modelName: 'gemini-2.0-flash-exp',
|
|
35
35
|
streaming: true,
|
|
36
36
|
streamUsage: true,
|
|
37
|
-
|
|
37
|
+
keyFile: process.env.VERTEXAI_KEY_FILE,
|
|
38
|
+
} as t.VertexAIClientOptions & t.LLMConfig,
|
|
38
39
|
[Providers.GOOGLE]: {
|
|
39
40
|
provider: Providers.GOOGLE,
|
|
40
41
|
model: 'gemini-2.0-flash-exp',
|