@librechat/agents 2.3.1 → 2.3.3
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/graphs/Graph.cjs +6 -6
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/llm.cjs +7 -7
- package/dist/cjs/llm/anthropic/llm.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +6 -6
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +24 -24
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/fake.cjs.map +1 -1
- package/dist/cjs/llm/text.cjs.map +1 -1
- package/dist/cjs/main.cjs +3 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +6 -6
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +11 -9
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +155 -205
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +7 -7
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +1 -1
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +3 -3
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +6 -6
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/anthropic/llm.mjs +7 -7
- package/dist/esm/llm/anthropic/llm.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +6 -6
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +24 -24
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/fake.mjs.map +1 -1
- package/dist/esm/llm/text.mjs.map +1 -1
- package/dist/esm/main.mjs +1 -1
- package/dist/esm/messages/core.mjs +6 -6
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +11 -9
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +153 -206
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +7 -7
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +1 -1
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +3 -3
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/messages/format.d.ts +1 -2
- package/dist/types/messages/prune.d.ts +31 -2
- package/dist/types/types/stream.d.ts +2 -2
- package/dist/types/utils/tokens.d.ts +1 -1
- package/package.json +4 -3
- package/src/graphs/Graph.ts +8 -8
- package/src/llm/anthropic/llm.ts +7 -8
- package/src/llm/anthropic/types.ts +4 -4
- package/src/llm/anthropic/utils/message_inputs.ts +6 -6
- package/src/llm/anthropic/utils/message_outputs.ts +39 -39
- package/src/llm/fake.ts +2 -2
- package/src/llm/text.ts +1 -1
- package/src/messages/core.ts +9 -9
- package/src/messages/format.ts +43 -42
- package/src/messages/formatAgentMessages.test.ts +35 -35
- package/src/messages/formatAgentMessages.tools.test.ts +30 -30
- package/src/messages/prune.ts +182 -255
- package/src/messages/shiftIndexTokenCountMap.test.ts +18 -18
- package/src/mockStream.ts +1 -1
- package/src/run.ts +2 -2
- package/src/specs/prune.test.ts +89 -89
- package/src/specs/reasoning.test.ts +1 -1
- package/src/specs/thinking-prune.test.ts +265 -261
- package/src/specs/tool-error.test.ts +16 -17
- package/src/stream.ts +21 -18
- package/src/tools/ToolNode.ts +1 -1
- package/src/types/stream.ts +4 -3
- package/src/utils/tokens.ts +12 -12
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
UsageMetadata,
|
|
8
8
|
AIMessageChunk,
|
|
9
9
|
} from '@langchain/core/messages';
|
|
10
|
-
import type { ToolCallChunk } from
|
|
10
|
+
import type { ToolCallChunk } from '@langchain/core/messages/tool';
|
|
11
11
|
import { ToolCall } from '@langchain/core/messages/tool';
|
|
12
12
|
import { ChatGeneration } from '@langchain/core/outputs';
|
|
13
13
|
import { AnthropicMessageResponse } from '../types.js';
|
|
@@ -92,18 +92,18 @@ export function _makeMessageChunkFromAnthropicEvent(
|
|
|
92
92
|
}),
|
|
93
93
|
};
|
|
94
94
|
} else if (
|
|
95
|
-
data.type ===
|
|
96
|
-
[
|
|
95
|
+
data.type === 'content_block_start' &&
|
|
96
|
+
['tool_use', 'document'].includes(data.content_block.type)
|
|
97
97
|
) {
|
|
98
98
|
const contentBlock = data.content_block;
|
|
99
99
|
let toolCallChunks: ToolCallChunk[];
|
|
100
|
-
if (contentBlock.type ===
|
|
100
|
+
if (contentBlock.type === 'tool_use') {
|
|
101
101
|
toolCallChunks = [
|
|
102
102
|
{
|
|
103
103
|
id: contentBlock.id,
|
|
104
104
|
index: data.index,
|
|
105
105
|
name: contentBlock.name,
|
|
106
|
-
args:
|
|
106
|
+
args: '',
|
|
107
107
|
},
|
|
108
108
|
];
|
|
109
109
|
} else {
|
|
@@ -112,28 +112,28 @@ export function _makeMessageChunkFromAnthropicEvent(
|
|
|
112
112
|
return {
|
|
113
113
|
chunk: new AIMessageChunk({
|
|
114
114
|
content: fields.coerceContentToString
|
|
115
|
-
?
|
|
115
|
+
? ''
|
|
116
116
|
: [
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
{
|
|
118
|
+
index: data.index,
|
|
119
|
+
...data.content_block,
|
|
120
|
+
input: '',
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
123
|
additional_kwargs: {},
|
|
124
124
|
tool_call_chunks: toolCallChunks,
|
|
125
125
|
}),
|
|
126
126
|
};
|
|
127
127
|
} else if (
|
|
128
|
-
data.type ===
|
|
128
|
+
data.type === 'content_block_delta' &&
|
|
129
129
|
[
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
'text_delta',
|
|
131
|
+
'citations_delta',
|
|
132
|
+
'thinking_delta',
|
|
133
|
+
'signature_delta',
|
|
134
134
|
].includes(data.delta.type)
|
|
135
135
|
) {
|
|
136
|
-
if (fields.coerceContentToString &&
|
|
136
|
+
if (fields.coerceContentToString && 'text' in data.delta) {
|
|
137
137
|
return {
|
|
138
138
|
chunk: new AIMessageChunk({
|
|
139
139
|
content: data.delta.text,
|
|
@@ -142,30 +142,30 @@ export function _makeMessageChunkFromAnthropicEvent(
|
|
|
142
142
|
} else {
|
|
143
143
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
144
144
|
const contentBlock: Record<string, any> = data.delta;
|
|
145
|
-
if (
|
|
145
|
+
if ('citation' in contentBlock) {
|
|
146
146
|
contentBlock.citations = [contentBlock.citation];
|
|
147
147
|
delete contentBlock.citation;
|
|
148
148
|
}
|
|
149
149
|
if (
|
|
150
|
-
contentBlock.type ===
|
|
151
|
-
contentBlock.type ===
|
|
150
|
+
contentBlock.type === 'thinking_delta' ||
|
|
151
|
+
contentBlock.type === 'signature_delta'
|
|
152
152
|
) {
|
|
153
153
|
return {
|
|
154
154
|
chunk: new AIMessageChunk({
|
|
155
|
-
content: [{ index: data.index, ...contentBlock, type:
|
|
155
|
+
content: [{ index: data.index, ...contentBlock, type: 'thinking' }],
|
|
156
156
|
}),
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
return {
|
|
161
161
|
chunk: new AIMessageChunk({
|
|
162
|
-
content: [{ index: data.index, ...contentBlock, type:
|
|
162
|
+
content: [{ index: data.index, ...contentBlock, type: 'text' }],
|
|
163
163
|
}),
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
166
|
} else if (
|
|
167
|
-
data.type ===
|
|
168
|
-
data.delta.type ===
|
|
167
|
+
data.type === 'content_block_delta' &&
|
|
168
|
+
data.delta.type === 'input_json_delta'
|
|
169
169
|
) {
|
|
170
170
|
return {
|
|
171
171
|
chunk: new AIMessageChunk({
|
|
@@ -208,19 +208,19 @@ export function _makeMessageChunkFromAnthropicEvent(
|
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
210
|
} else if (
|
|
211
|
-
data.type ===
|
|
212
|
-
data.content_block.type ===
|
|
211
|
+
data.type === 'content_block_start' &&
|
|
212
|
+
data.content_block.type === 'redacted_thinking'
|
|
213
213
|
) {
|
|
214
214
|
return {
|
|
215
215
|
chunk: new AIMessageChunk({
|
|
216
216
|
content: fields.coerceContentToString
|
|
217
|
-
?
|
|
217
|
+
? ''
|
|
218
218
|
: [{ index: data.index, ...data.content_block }],
|
|
219
219
|
}),
|
|
220
220
|
};
|
|
221
221
|
} else if (
|
|
222
|
-
data.type ===
|
|
223
|
-
data.content_block.type ===
|
|
222
|
+
data.type === 'content_block_start' &&
|
|
223
|
+
data.content_block.type === 'thinking'
|
|
224
224
|
) {
|
|
225
225
|
const content = data.content_block.thinking;
|
|
226
226
|
return {
|
|
@@ -241,17 +241,17 @@ export function anthropicResponseToChatMessages(
|
|
|
241
241
|
): ChatGeneration[] {
|
|
242
242
|
const usage: Record<string, number> | null | undefined =
|
|
243
243
|
additionalKwargs.usage as Record<string, number> | null | undefined;
|
|
244
|
-
|
|
244
|
+
const usageMetadata =
|
|
245
245
|
usage != null
|
|
246
246
|
? {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
247
|
+
input_tokens: usage.input_tokens ?? 0,
|
|
248
|
+
output_tokens: usage.output_tokens ?? 0,
|
|
249
|
+
total_tokens: (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
|
|
250
|
+
input_token_details: {
|
|
251
|
+
cache_creation: usage.cache_creation_input_tokens,
|
|
252
|
+
cache_read: usage.cache_read_input_tokens,
|
|
253
|
+
},
|
|
254
|
+
}
|
|
255
255
|
: undefined;
|
|
256
256
|
if (messages.length === 1 && messages[0].type === 'text') {
|
|
257
257
|
return [
|
package/src/llm/fake.ts
CHANGED
|
@@ -63,7 +63,7 @@ export class FakeChatModel extends FakeListChatModel {
|
|
|
63
63
|
},
|
|
64
64
|
})),
|
|
65
65
|
} : undefined,
|
|
66
|
-
|
|
66
|
+
})});
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
async *_streamResponseChunks(
|
|
@@ -102,7 +102,7 @@ export class FakeChatModel extends FakeListChatModel {
|
|
|
102
102
|
args: JSON.stringify(toolCall.args),
|
|
103
103
|
id: toolCall.id,
|
|
104
104
|
type: 'tool_call_chunk',
|
|
105
|
-
|
|
105
|
+
} as ToolCallChunk;
|
|
106
106
|
});
|
|
107
107
|
const responseChunk = this._createResponseChunk('', toolCallChunks);
|
|
108
108
|
yield responseChunk;
|
package/src/llm/text.ts
CHANGED
package/src/messages/core.ts
CHANGED
|
@@ -69,7 +69,7 @@ const modifyContent = ({
|
|
|
69
69
|
});
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
-
type ContentBlock = t.BedrockReasoningContentText | t.MessageDeltaUpdate;
|
|
72
|
+
type ContentBlock = Partial<t.BedrockReasoningContentText> | t.MessageDeltaUpdate;
|
|
73
73
|
|
|
74
74
|
function reduceBlocks(blocks: ContentBlock[]): ContentBlock[] {
|
|
75
75
|
const reduced: ContentBlock[] = [];
|
|
@@ -78,20 +78,20 @@ function reduceBlocks(blocks: ContentBlock[]): ContentBlock[] {
|
|
|
78
78
|
const lastBlock = reduced[reduced.length - 1];
|
|
79
79
|
|
|
80
80
|
// Merge consecutive 'reasoning_content'
|
|
81
|
-
if (block.type === 'reasoning_content' && lastBlock
|
|
81
|
+
if (block.type === 'reasoning_content' && lastBlock.type === 'reasoning_content') {
|
|
82
82
|
// append text if exists
|
|
83
|
-
if (block.reasoningText?.text) {
|
|
84
|
-
lastBlock.reasoningText.text = (lastBlock.reasoningText
|
|
83
|
+
if (block.reasoningText?.text != null && block.reasoningText.text) {
|
|
84
|
+
(lastBlock.reasoningText as t.BedrockReasoningContentText['reasoningText']).text = (lastBlock.reasoningText?.text ?? '') + block.reasoningText.text;
|
|
85
85
|
}
|
|
86
86
|
// preserve the signature if exists
|
|
87
|
-
if (block.reasoningText?.signature) {
|
|
88
|
-
lastBlock.reasoningText.signature = block.reasoningText.signature;
|
|
87
|
+
if (block.reasoningText?.signature != null && block.reasoningText.signature) {
|
|
88
|
+
(lastBlock.reasoningText as t.BedrockReasoningContentText['reasoningText']).signature = block.reasoningText.signature;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
// Merge consecutive 'text'
|
|
92
|
-
else if (block.type === 'text' && lastBlock
|
|
92
|
+
else if (block.type === 'text' && lastBlock.type === 'text') {
|
|
93
93
|
lastBlock.text += block.text;
|
|
94
|
-
}
|
|
94
|
+
}
|
|
95
95
|
// add a new block as it's a different type or first element
|
|
96
96
|
else {
|
|
97
97
|
// deep copy to avoid mutation of original
|
|
@@ -155,7 +155,7 @@ export function formatAnthropicMessage(message: AIMessageChunk): AIMessage {
|
|
|
155
155
|
input: toolCall.args as unknown as string
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
|
-
} catch
|
|
158
|
+
} catch {
|
|
159
159
|
if (extendedItem.input) {
|
|
160
160
|
acc.push({ type: 'text', text: extendedItem.input });
|
|
161
161
|
}
|
package/src/messages/format.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import { HumanMessage, AIMessage, SystemMessage, getBufferString } from '@langchain/core/messages';
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { ToolMessage, BaseMessage , HumanMessage, AIMessage, SystemMessage, getBufferString } from '@langchain/core/messages';
|
|
3
3
|
import type { MessageContentImageUrl } from '@langchain/core/messages';
|
|
4
4
|
import type { ToolCall } from '@langchain/core/messages/tool';
|
|
5
5
|
import type { MessageContentComplex, ToolCallPart, TPayload, TMessage } from '@/types';
|
|
@@ -38,17 +38,17 @@ export const formatVisionMessage = ({ message, image_urls, endpoint }: VisionMes
|
|
|
38
38
|
...message,
|
|
39
39
|
content: [] as MessageContentComplex[]
|
|
40
40
|
};
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
if (endpoint === Providers.ANTHROPIC) {
|
|
43
43
|
result.content = [
|
|
44
|
-
...image_urls,
|
|
44
|
+
...image_urls,
|
|
45
45
|
{ type: ContentTypes.TEXT, text: message.content }
|
|
46
46
|
] as MessageContentComplex[];
|
|
47
47
|
return result;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
result.content = [
|
|
51
|
-
{ type: ContentTypes.TEXT, text: message.content },
|
|
51
|
+
{ type: ContentTypes.TEXT, text: message.content },
|
|
52
52
|
...image_urls
|
|
53
53
|
] as MessageContentComplex[];
|
|
54
54
|
|
|
@@ -87,13 +87,14 @@ interface FormattedMessage {
|
|
|
87
87
|
* @param {FormatMessageParams} params - The parameters for formatting.
|
|
88
88
|
* @returns {FormattedMessage | HumanMessage | AIMessage | SystemMessage} - The formatted message.
|
|
89
89
|
*/
|
|
90
|
-
export const formatMessage = ({
|
|
91
|
-
message,
|
|
92
|
-
userName,
|
|
93
|
-
assistantName,
|
|
94
|
-
endpoint,
|
|
95
|
-
langChain = false
|
|
90
|
+
export const formatMessage = ({
|
|
91
|
+
message,
|
|
92
|
+
userName,
|
|
93
|
+
assistantName,
|
|
94
|
+
endpoint,
|
|
95
|
+
langChain = false
|
|
96
96
|
}: FormatMessageParams): FormattedMessage | HumanMessage | AIMessage | SystemMessage => {
|
|
97
|
+
// eslint-disable-next-line prefer-const
|
|
97
98
|
let { role: _role, _name, sender, text, content: _content, lc_id } = message;
|
|
98
99
|
if (lc_id && lc_id[2] && !langChain) {
|
|
99
100
|
const roleMapping: Record<string, string> = {
|
|
@@ -103,7 +104,7 @@ export const formatMessage = ({
|
|
|
103
104
|
};
|
|
104
105
|
_role = roleMapping[lc_id[2]] || _role;
|
|
105
106
|
}
|
|
106
|
-
const role = _role ?? (sender && sender
|
|
107
|
+
const role = _role ?? (sender != null && sender && sender.toLowerCase() === 'user' ? 'user' : 'assistant');
|
|
107
108
|
const content = _content ?? text ?? '';
|
|
108
109
|
const formattedMessage: FormattedMessage = {
|
|
109
110
|
role,
|
|
@@ -122,19 +123,19 @@ export const formatMessage = ({
|
|
|
122
123
|
});
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
if (_name) {
|
|
126
|
+
if (_name != null && _name) {
|
|
126
127
|
formattedMessage.name = _name;
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
if (userName && formattedMessage.role === 'user') {
|
|
130
|
+
if (userName != null && userName && formattedMessage.role === 'user') {
|
|
130
131
|
formattedMessage.name = userName;
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
if (assistantName && formattedMessage.role === 'assistant') {
|
|
134
|
+
if (assistantName != null && assistantName && formattedMessage.role === 'assistant') {
|
|
134
135
|
formattedMessage.name = assistantName;
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
if (formattedMessage.name) {
|
|
138
|
+
if (formattedMessage.name != null && formattedMessage.name) {
|
|
138
139
|
// Conform to API regex: ^[a-zA-Z0-9_-]{1,64}$
|
|
139
140
|
// https://community.openai.com/t/the-format-of-the-name-field-in-the-documentation-is-incorrect/175684/2
|
|
140
141
|
formattedMessage.name = formattedMessage.name.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
@@ -165,7 +166,7 @@ export const formatMessage = ({
|
|
|
165
166
|
* @returns {Array<HumanMessage | AIMessage | SystemMessage>} - The array of formatted LangChain messages.
|
|
166
167
|
*/
|
|
167
168
|
export const formatLangChainMessages = (
|
|
168
|
-
messages: Array<MessageInput>,
|
|
169
|
+
messages: Array<MessageInput>,
|
|
169
170
|
formatOptions: Omit<FormatMessageParams, 'message' | 'langChain'>
|
|
170
171
|
): Array<HumanMessage | AIMessage | SystemMessage> => {
|
|
171
172
|
return messages.map((msg) => {
|
|
@@ -237,7 +238,7 @@ function formatAssistantMessage(message: Partial<TMessage>): Array<AIMessage | T
|
|
|
237
238
|
content: part.text || '',
|
|
238
239
|
});
|
|
239
240
|
formattedMessages.push(lastAIMessage);
|
|
240
|
-
} else if (part
|
|
241
|
+
} else if (part.type === ContentTypes.TOOL_CALL) {
|
|
241
242
|
if (!lastAIMessage) {
|
|
242
243
|
throw new Error('Invalid tool call structure: No preceding AIMessage with tool_call_ids');
|
|
243
244
|
}
|
|
@@ -251,7 +252,7 @@ function formatAssistantMessage(message: Partial<TMessage>): Array<AIMessage | T
|
|
|
251
252
|
if (typeof _args === 'string') {
|
|
252
253
|
args = JSON.parse(_args);
|
|
253
254
|
}
|
|
254
|
-
} catch
|
|
255
|
+
} catch {
|
|
255
256
|
if (typeof _args === 'string') {
|
|
256
257
|
args = { input: _args };
|
|
257
258
|
}
|
|
@@ -290,7 +291,7 @@ function formatAssistantMessage(message: Partial<TMessage>): Array<AIMessage | T
|
|
|
290
291
|
return acc;
|
|
291
292
|
}, '')
|
|
292
293
|
.trim();
|
|
293
|
-
|
|
294
|
+
|
|
294
295
|
if (content) {
|
|
295
296
|
formattedMessages.push(new AIMessage({ content }));
|
|
296
297
|
}
|
|
@@ -310,7 +311,7 @@ function formatAssistantMessage(message: Partial<TMessage>): Array<AIMessage | T
|
|
|
310
311
|
* @returns {Object} - Object containing formatted messages and updated indexTokenCountMap if provided.
|
|
311
312
|
*/
|
|
312
313
|
export const formatAgentMessages = (
|
|
313
|
-
payload: TPayload,
|
|
314
|
+
payload: TPayload,
|
|
314
315
|
indexTokenCountMap?: Record<number, number>,
|
|
315
316
|
tools?: Set<string>
|
|
316
317
|
): {
|
|
@@ -332,11 +333,11 @@ export const formatAgentMessages = (
|
|
|
332
333
|
message.content = [{ type: ContentTypes.TEXT, [ContentTypes.TEXT]: message.content }];
|
|
333
334
|
}
|
|
334
335
|
if (message.role !== 'assistant') {
|
|
335
|
-
messages.push(formatMessage({
|
|
336
|
-
message: message as MessageInput,
|
|
337
|
-
langChain: true
|
|
336
|
+
messages.push(formatMessage({
|
|
337
|
+
message: message as MessageInput,
|
|
338
|
+
langChain: true
|
|
338
339
|
}) as HumanMessage | AIMessage | SystemMessage);
|
|
339
|
-
|
|
340
|
+
|
|
340
341
|
// Update the index mapping for this message
|
|
341
342
|
indexMapping[i] = [messages.length - 1];
|
|
342
343
|
continue;
|
|
@@ -350,12 +351,12 @@ export const formatAgentMessages = (
|
|
|
350
351
|
// First, check if this message contains tool calls
|
|
351
352
|
let hasToolCalls = false;
|
|
352
353
|
let hasInvalidTool = false;
|
|
353
|
-
|
|
354
|
-
|
|
354
|
+
const toolNames: string[] = [];
|
|
355
|
+
|
|
355
356
|
const content = message.content;
|
|
356
357
|
if (content && Array.isArray(content)) {
|
|
357
358
|
for (const part of content) {
|
|
358
|
-
if (part
|
|
359
|
+
if (part.type === ContentTypes.TOOL_CALL) {
|
|
359
360
|
hasToolCalls = true;
|
|
360
361
|
if (tools.size === 0) {
|
|
361
362
|
hasInvalidTool = true;
|
|
@@ -369,17 +370,17 @@ export const formatAgentMessages = (
|
|
|
369
370
|
}
|
|
370
371
|
}
|
|
371
372
|
}
|
|
372
|
-
|
|
373
|
+
|
|
373
374
|
// If this message has tool calls and at least one is invalid, we need to convert it
|
|
374
375
|
if (hasToolCalls && hasInvalidTool) {
|
|
375
376
|
// We need to collect all related messages (this message and any subsequent tool messages)
|
|
376
377
|
const toolSequence: BaseMessage[] = [];
|
|
377
378
|
let sequenceEndIndex = i;
|
|
378
|
-
|
|
379
|
+
|
|
379
380
|
// Process the current assistant message to get the AIMessage with tool calls
|
|
380
381
|
const formattedMessages = formatAssistantMessage(message);
|
|
381
382
|
toolSequence.push(...formattedMessages);
|
|
382
|
-
|
|
383
|
+
|
|
383
384
|
// Look ahead for any subsequent assistant messages that might be part of this tool sequence
|
|
384
385
|
let j = i + 1;
|
|
385
386
|
while (j < payload.length && payload[j].role === 'assistant') {
|
|
@@ -388,13 +389,13 @@ export const formatAgentMessages = (
|
|
|
388
389
|
const content = payload[j].content;
|
|
389
390
|
if (content && Array.isArray(content)) {
|
|
390
391
|
for (const part of content) {
|
|
391
|
-
if (part
|
|
392
|
+
if (part.type === ContentTypes.TOOL_CALL) {
|
|
392
393
|
isToolResponse = true;
|
|
393
394
|
break;
|
|
394
395
|
}
|
|
395
396
|
}
|
|
396
397
|
}
|
|
397
|
-
|
|
398
|
+
|
|
398
399
|
if (isToolResponse) {
|
|
399
400
|
// This is part of the tool sequence, add it
|
|
400
401
|
const nextMessages = formatAssistantMessage(payload[j]);
|
|
@@ -406,20 +407,20 @@ export const formatAgentMessages = (
|
|
|
406
407
|
break;
|
|
407
408
|
}
|
|
408
409
|
}
|
|
409
|
-
|
|
410
|
+
|
|
410
411
|
// Convert the sequence to a string
|
|
411
412
|
const bufferString = getBufferString(toolSequence);
|
|
412
413
|
messages.push(new AIMessage({ content: bufferString }));
|
|
413
|
-
|
|
414
|
+
|
|
414
415
|
// Skip the messages we've already processed
|
|
415
416
|
i = sequenceEndIndex;
|
|
416
|
-
|
|
417
|
+
|
|
417
418
|
// Update the index mapping for this sequence
|
|
418
419
|
const resultIndices = [messages.length - 1];
|
|
419
420
|
for (let k = i; k >= i && k <= sequenceEndIndex; k++) {
|
|
420
421
|
indexMapping[k] = resultIndices;
|
|
421
422
|
}
|
|
422
|
-
|
|
423
|
+
|
|
423
424
|
continue;
|
|
424
425
|
}
|
|
425
426
|
}
|
|
@@ -427,7 +428,7 @@ export const formatAgentMessages = (
|
|
|
427
428
|
// Process the assistant message using the helper function
|
|
428
429
|
const formattedMessages = formatAssistantMessage(message);
|
|
429
430
|
messages.push(...formattedMessages);
|
|
430
|
-
|
|
431
|
+
|
|
431
432
|
// Update the index mapping for this assistant message
|
|
432
433
|
// Store all indices that were created from this original message
|
|
433
434
|
const endMessageIndex = messages.length;
|
|
@@ -443,7 +444,7 @@ export const formatAgentMessages = (
|
|
|
443
444
|
for (let originalIndex = 0; originalIndex < payload.length; originalIndex++) {
|
|
444
445
|
const resultIndices = indexMapping[originalIndex] || [];
|
|
445
446
|
const tokenCount = indexTokenCountMap[originalIndex];
|
|
446
|
-
|
|
447
|
+
|
|
447
448
|
if (tokenCount !== undefined) {
|
|
448
449
|
if (resultIndices.length === 1) {
|
|
449
450
|
// Simple 1:1 mapping
|
|
@@ -506,7 +507,7 @@ export const formatContentStrings = (payload: Array<BaseMessage>): Array<BaseMes
|
|
|
506
507
|
/**
|
|
507
508
|
* Adds a value at key 0 for system messages and shifts all key indices by one in an indexTokenCountMap.
|
|
508
509
|
* This is useful when adding a system message at the beginning of a conversation.
|
|
509
|
-
*
|
|
510
|
+
*
|
|
510
511
|
* @param indexTokenCountMap - The original map of message indices to token counts
|
|
511
512
|
* @param instructionsTokenCount - The token count for the system message to add at index 0
|
|
512
513
|
* @returns A new map with the system message at index 0 and all other indices shifted by 1
|
|
@@ -518,12 +519,12 @@ export function shiftIndexTokenCountMap(
|
|
|
518
519
|
// Create a new map to avoid modifying the original
|
|
519
520
|
const shiftedMap: Record<number, number> = {};
|
|
520
521
|
shiftedMap[0] = instructionsTokenCount;
|
|
521
|
-
|
|
522
|
+
|
|
522
523
|
// Shift all existing indices by 1
|
|
523
524
|
for (const [indexStr, tokenCount] of Object.entries(indexTokenCountMap)) {
|
|
524
525
|
const index = Number(indexStr);
|
|
525
526
|
shiftedMap[index + 1] = tokenCount;
|
|
526
527
|
}
|
|
527
|
-
|
|
528
|
+
|
|
528
529
|
return shiftedMap;
|
|
529
530
|
}
|