@librechat/agents 3.3.9 → 3.3.11
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/agents/AgentContext.cjs +4 -0
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +21 -2
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +228 -16
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
- package/dist/cjs/llm/init.cjs +1 -1
- package/dist/cjs/llm/invoke.cjs +14 -7
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +188 -11
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +4 -3
- package/dist/cjs/messages/core.cjs +592 -27
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/run.cjs +11 -1
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +2 -2
- package/dist/cjs/tools/ToolNode.cjs +1 -1
- package/dist/cjs/tools/search/tool.cjs +1 -1
- package/dist/cjs/utils/index.cjs +1 -1
- package/dist/esm/agents/AgentContext.mjs +4 -0
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +21 -2
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +228 -16
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
- package/dist/esm/llm/init.mjs +1 -1
- package/dist/esm/llm/invoke.mjs +14 -7
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +190 -13
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +5 -5
- package/dist/esm/messages/core.mjs +592 -28
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/run.mjs +11 -1
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +2 -2
- package/dist/esm/tools/ToolNode.mjs +1 -1
- package/dist/esm/tools/search/tool.mjs +1 -1
- package/dist/esm/utils/index.mjs +1 -1
- package/dist/types/agents/AgentContext.d.ts +2 -0
- package/dist/types/graphs/Graph.d.ts +5 -0
- package/dist/types/langfuseToolOutputTracing.d.ts +1 -0
- package/dist/types/llm/invoke.d.ts +1 -1
- package/dist/types/messages/core.d.ts +11 -6
- package/dist/types/run.d.ts +7 -0
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +5 -0
- package/src/graphs/Graph.ts +39 -0
- package/src/langfuseToolOutputTracing.ts +410 -14
- package/src/llm/custom-chat-models.smoke.test.ts +747 -0
- package/src/llm/invoke.test.ts +98 -0
- package/src/llm/invoke.ts +34 -23
- package/src/llm/openai/index.ts +334 -25
- package/src/llm/openai/llm.spec.ts +107 -6
- package/src/messages/core.ts +1290 -42
- package/src/messages/formatAgentMessages.test.ts +2623 -0
- package/src/run.ts +15 -0
- package/src/specs/discovered-tools.test.ts +217 -0
- package/src/specs/langfuse-tool-output-tracing.test.ts +887 -0
- package/src/specs/preemptSeal.test.ts +374 -5
|
@@ -82,6 +82,17 @@ type CompletionsStreamDelegate = {
|
|
|
82
82
|
) => AsyncGenerator<ChatGenerationChunk>;
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
+
type ResponsesStreamDelegate = {
|
|
86
|
+
completionWithRetry: (
|
|
87
|
+
request: OpenAIClient.Responses.ResponseCreateParamsStreaming
|
|
88
|
+
) => Promise<AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>>;
|
|
89
|
+
_streamResponseChunks: (
|
|
90
|
+
messages: BaseMessage[],
|
|
91
|
+
options: Record<string, unknown>,
|
|
92
|
+
runManager?: CallbackManagerForLLMRun
|
|
93
|
+
) => AsyncGenerator<ChatGenerationChunk>;
|
|
94
|
+
};
|
|
95
|
+
|
|
85
96
|
type InvocationParamsDelegate = {
|
|
86
97
|
invocationParams: (
|
|
87
98
|
options: Record<string, unknown>,
|
|
@@ -109,6 +120,9 @@ function completionsDelegateOf(model: ChatOpenAI): CompletionsDelegate {
|
|
|
109
120
|
const completionsOf = <T>(model: ChatOpenAI): T =>
|
|
110
121
|
(model as unknown as { completions: T }).completions;
|
|
111
122
|
|
|
123
|
+
const responsesOf = <T>(model: ChatOpenAI): T =>
|
|
124
|
+
(model as unknown as { responses: T }).responses;
|
|
125
|
+
|
|
112
126
|
function newOpenAI(): ChatOpenAI {
|
|
113
127
|
return new ChatOpenAI({ model: 'gpt-4o-mini', apiKey: 'test-key' });
|
|
114
128
|
}
|
|
@@ -1080,6 +1094,90 @@ describe('ChatOpenAICompletions streaming usage_metadata callback', () => {
|
|
|
1080
1094
|
});
|
|
1081
1095
|
});
|
|
1082
1096
|
|
|
1097
|
+
describe('ChatOpenAIResponses streaming callback dispatch', () => {
|
|
1098
|
+
it('emits the callback before a consumer stops at the yielded chunk', async () => {
|
|
1099
|
+
const model = new ChatOpenAI({
|
|
1100
|
+
model: 'gpt-5',
|
|
1101
|
+
apiKey: 'test-key',
|
|
1102
|
+
useResponsesApi: true,
|
|
1103
|
+
});
|
|
1104
|
+
const responses = responsesOf<ResponsesStreamDelegate>(model);
|
|
1105
|
+
responses.completionWithRetry = async () =>
|
|
1106
|
+
(async function* () {
|
|
1107
|
+
yield {
|
|
1108
|
+
type: 'response.output_text.delta',
|
|
1109
|
+
sequence_number: 0,
|
|
1110
|
+
output_index: 0,
|
|
1111
|
+
content_index: 0,
|
|
1112
|
+
item_id: 'msg_callback',
|
|
1113
|
+
delta: 'visible chunk',
|
|
1114
|
+
logprobs: [],
|
|
1115
|
+
} as OpenAIClient.Responses.ResponseStreamEvent;
|
|
1116
|
+
})();
|
|
1117
|
+
|
|
1118
|
+
const events: string[] = [];
|
|
1119
|
+
const runManager = {
|
|
1120
|
+
handleLLMNewToken(token: string): void {
|
|
1121
|
+
events.push(`callback:${token}`);
|
|
1122
|
+
},
|
|
1123
|
+
} as unknown as CallbackManagerForLLMRun;
|
|
1124
|
+
|
|
1125
|
+
for await (const chunk of responses._streamResponseChunks(
|
|
1126
|
+
[new HumanMessage('test')],
|
|
1127
|
+
{},
|
|
1128
|
+
runManager
|
|
1129
|
+
)) {
|
|
1130
|
+
events.push(`yield:${chunk.text}`);
|
|
1131
|
+
break;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
expect(events).toEqual(['callback:visible chunk', 'yield:visible chunk']);
|
|
1135
|
+
});
|
|
1136
|
+
|
|
1137
|
+
it('propagates an abort received with the next buffered event', async () => {
|
|
1138
|
+
const model = new ChatOpenAI({
|
|
1139
|
+
model: 'gpt-5',
|
|
1140
|
+
apiKey: 'test-key',
|
|
1141
|
+
useResponsesApi: true,
|
|
1142
|
+
});
|
|
1143
|
+
const responses = responsesOf<ResponsesStreamDelegate>(model);
|
|
1144
|
+
const controller = new AbortController();
|
|
1145
|
+
const abortReason = new Error('buffered Responses stream aborted');
|
|
1146
|
+
responses.completionWithRetry = async () =>
|
|
1147
|
+
(async function* () {
|
|
1148
|
+
yield {
|
|
1149
|
+
type: 'response.output_text.delta',
|
|
1150
|
+
sequence_number: 0,
|
|
1151
|
+
output_index: 0,
|
|
1152
|
+
content_index: 0,
|
|
1153
|
+
item_id: 'msg_abort',
|
|
1154
|
+
delta: 'partial',
|
|
1155
|
+
logprobs: [],
|
|
1156
|
+
} as OpenAIClient.Responses.ResponseStreamEvent;
|
|
1157
|
+
controller.abort(abortReason);
|
|
1158
|
+
yield {
|
|
1159
|
+
type: 'response.output_text.delta',
|
|
1160
|
+
sequence_number: 1,
|
|
1161
|
+
output_index: 0,
|
|
1162
|
+
content_index: 0,
|
|
1163
|
+
item_id: 'msg_abort',
|
|
1164
|
+
delta: ' must not complete normally',
|
|
1165
|
+
logprobs: [],
|
|
1166
|
+
} as OpenAIClient.Responses.ResponseStreamEvent;
|
|
1167
|
+
})();
|
|
1168
|
+
|
|
1169
|
+
const stream = responses._streamResponseChunks([new HumanMessage('test')], {
|
|
1170
|
+
signal: controller.signal,
|
|
1171
|
+
});
|
|
1172
|
+
|
|
1173
|
+
await expect(stream.next()).resolves.toMatchObject({
|
|
1174
|
+
done: false,
|
|
1175
|
+
value: { text: 'partial' },
|
|
1176
|
+
});
|
|
1177
|
+
await expect(stream.next()).rejects.toBe(abortReason);
|
|
1178
|
+
});
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1083
1181
|
describe('ChatOpenAICompletions reasoning_content compatibility', () => {
|
|
1084
1182
|
it('should preserve reasoning_content on streamed assistant chunks', async () => {
|
|
1085
1183
|
const model = new ChatOpenAI({
|
|
@@ -1237,11 +1335,15 @@ describe('ChatOpenAICompletions strict tools for structured output', () => {
|
|
|
1237
1335
|
}) as unknown as {
|
|
1238
1336
|
tools?: { function: { parameters: { properties: object } } }[];
|
|
1239
1337
|
};
|
|
1240
|
-
return Object.keys(
|
|
1338
|
+
return Object.keys(
|
|
1339
|
+
params.tools?.[0]?.function.parameters.properties ?? {}
|
|
1340
|
+
);
|
|
1241
1341
|
}
|
|
1242
1342
|
|
|
1243
1343
|
it('drops the optional label when strict is auto-enabled (invalid otherwise)', () => {
|
|
1244
|
-
expect(
|
|
1344
|
+
expect(
|
|
1345
|
+
toolProperties({ response_format: jsonSchemaResponseFormat })
|
|
1346
|
+
).toEqual(['query']);
|
|
1245
1347
|
});
|
|
1246
1348
|
|
|
1247
1349
|
it('keeps the label on non-strict requests', () => {
|
|
@@ -1305,10 +1407,9 @@ describe('ChatOpenAICompletions strict tools for structured output', () => {
|
|
|
1305
1407
|
}) as unknown as {
|
|
1306
1408
|
tools?: { function: { parameters: { properties: object } } }[];
|
|
1307
1409
|
};
|
|
1308
|
-
expect(
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
]);
|
|
1410
|
+
expect(
|
|
1411
|
+
Object.keys(params.tools?.[0]?.function.parameters.properties ?? {})
|
|
1412
|
+
).toEqual(['intent', 'title']);
|
|
1312
1413
|
});
|
|
1313
1414
|
});
|
|
1314
1415
|
});
|