@librechat/agents 4.0.2 → 4.0.4
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 +3 -2
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/decisions/structuredChat.cjs +2 -8
- package/dist/cjs/decisions/structuredChat.cjs.map +1 -1
- package/dist/cjs/decisions/structuredOutput.cjs +18 -0
- package/dist/cjs/decisions/structuredOutput.cjs.map +1 -0
- package/dist/cjs/graphs/Graph.cjs +25 -9
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs +1 -1
- package/dist/cjs/llm/invoke.cjs +34 -12
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +7 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/providerTextBoundary.cjs +355 -0
- package/dist/cjs/llm/providerTextBoundary.cjs.map +1 -0
- package/dist/cjs/llm/providerTextChunk.cjs +14 -0
- package/dist/cjs/llm/providerTextChunk.cjs.map +1 -0
- package/dist/cjs/llm/providerTextControls.cjs +236 -0
- package/dist/cjs/llm/providerTextControls.cjs.map +1 -0
- package/dist/cjs/llm/stream/smoother.cjs +2 -1
- package/dist/cjs/llm/stream/smoother.cjs.map +1 -1
- package/dist/cjs/main.cjs +18 -1
- package/dist/cjs/protection/providerText.cjs +224 -0
- package/dist/cjs/protection/providerText.cjs.map +1 -0
- package/dist/cjs/protection/providerTextInput.cjs +25 -0
- package/dist/cjs/protection/providerTextInput.cjs.map +1 -0
- package/dist/cjs/run.cjs +7 -1
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +42 -14
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +26 -8
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/GitHubCompare.cjs +181 -0
- package/dist/cjs/tools/GitHubCompare.cjs.map +1 -0
- package/dist/cjs/tools/SubagentTool.cjs +11 -3
- package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +6 -5
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs +2 -2
- package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +66 -16
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentReplay.cjs +4 -2
- package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -1
- package/dist/cjs/tools/subagent/childGraphConfig.cjs +3 -1
- package/dist/cjs/tools/subagent/childGraphConfig.cjs.map +1 -1
- package/dist/cjs/tools/subagent/diagnostics.cjs +48 -5
- package/dist/cjs/tools/subagent/diagnostics.cjs.map +1 -1
- package/dist/cjs/tools/subagent/hostArgs.cjs +214 -0
- package/dist/cjs/tools/subagent/hostArgs.cjs.map +1 -0
- package/dist/cjs/tools/subagent/index.cjs +1 -0
- package/dist/cjs/tools/toolErrorContent.cjs +1 -1
- package/dist/esm/agents/AgentContext.mjs +3 -2
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/decisions/structuredChat.mjs +2 -8
- package/dist/esm/decisions/structuredChat.mjs.map +1 -1
- package/dist/esm/decisions/structuredOutput.mjs +18 -0
- package/dist/esm/decisions/structuredOutput.mjs.map +1 -0
- package/dist/esm/graphs/Graph.mjs +25 -9
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs +1 -1
- package/dist/esm/llm/invoke.mjs +34 -12
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +7 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/providerTextBoundary.mjs +355 -0
- package/dist/esm/llm/providerTextBoundary.mjs.map +1 -0
- package/dist/esm/llm/providerTextChunk.mjs +13 -0
- package/dist/esm/llm/providerTextChunk.mjs.map +1 -0
- package/dist/esm/llm/providerTextControls.mjs +230 -0
- package/dist/esm/llm/providerTextControls.mjs.map +1 -0
- package/dist/esm/llm/stream/smoother.mjs +2 -1
- package/dist/esm/llm/stream/smoother.mjs.map +1 -1
- package/dist/esm/main.mjs +6 -3
- package/dist/esm/protection/providerText.mjs +218 -0
- package/dist/esm/protection/providerText.mjs.map +1 -0
- package/dist/esm/protection/providerTextInput.mjs +24 -0
- package/dist/esm/protection/providerTextInput.mjs.map +1 -0
- package/dist/esm/run.mjs +7 -1
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +42 -14
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +26 -8
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/GitHubCompare.mjs +175 -0
- package/dist/esm/tools/GitHubCompare.mjs.map +1 -0
- package/dist/esm/tools/SubagentTool.mjs +11 -3
- package/dist/esm/tools/SubagentTool.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +6 -5
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs +2 -2
- package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +66 -16
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentReplay.mjs +4 -2
- package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -1
- package/dist/esm/tools/subagent/childGraphConfig.mjs +3 -1
- package/dist/esm/tools/subagent/childGraphConfig.mjs.map +1 -1
- package/dist/esm/tools/subagent/diagnostics.mjs +46 -6
- package/dist/esm/tools/subagent/diagnostics.mjs.map +1 -1
- package/dist/esm/tools/subagent/hostArgs.mjs +207 -0
- package/dist/esm/tools/subagent/hostArgs.mjs.map +1 -0
- package/dist/esm/tools/subagent/index.mjs +1 -0
- package/dist/esm/tools/toolErrorContent.mjs +1 -1
- package/dist/types/decisions/structuredChat.d.ts +3 -2
- package/dist/types/decisions/structuredOutput.d.ts +4 -0
- package/dist/types/graphs/Graph.d.ts +6 -3
- package/dist/types/index.d.ts +3 -0
- package/dist/types/llm/invoke.d.ts +4 -1
- package/dist/types/llm/providerTextBoundary.d.ts +4 -0
- package/dist/types/llm/providerTextChunk.d.ts +7 -0
- package/dist/types/llm/providerTextControls.d.ts +18 -0
- package/dist/types/protection/providerText.d.ts +77 -0
- package/dist/types/protection/providerTextInput.d.ts +3 -0
- package/dist/types/run.d.ts +1 -0
- package/dist/types/tools/BashExecutor.d.ts +4 -0
- package/dist/types/tools/CodeExecutor.d.ts +4 -0
- package/dist/types/tools/GitHubCompare.d.ts +104 -0
- package/dist/types/tools/ReadFile.d.ts +4 -0
- package/dist/types/tools/SkillTool.d.ts +4 -0
- package/dist/types/tools/SubagentTool.d.ts +2 -0
- package/dist/types/tools/ToolSearch.d.ts +4 -0
- package/dist/types/tools/search/schema.d.ts +4 -0
- package/dist/types/tools/subagent/SubagentExecutionRegistry.d.ts +2 -0
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +10 -2
- package/dist/types/tools/subagent/SubagentReplay.d.ts +3 -1
- package/dist/types/tools/subagent/diagnostics.d.ts +27 -3
- package/dist/types/tools/subagent/hostArgs.d.ts +57 -0
- package/dist/types/tools/subagent/index.d.ts +3 -2
- package/dist/types/types/graph.d.ts +36 -0
- package/dist/types/types/run.d.ts +4 -2
- package/dist/types/types/tools.d.ts +2 -0
- package/package.json +4 -4
- package/src/agents/AgentContext.ts +3 -2
- package/src/decisions/structuredChat.ts +9 -15
- package/src/decisions/structuredOutput.ts +25 -0
- package/src/graphs/Graph.ts +53 -9
- package/src/index.ts +8 -0
- package/src/llm/invoke.ts +48 -7
- package/src/llm/openai/index.ts +8 -0
- package/src/llm/providerTextBoundary.ts +446 -0
- package/src/llm/providerTextChunk.ts +15 -0
- package/src/llm/providerTextControls.ts +173 -0
- package/src/llm/stream/smoother.ts +4 -2
- package/src/protection/providerText.ts +325 -0
- package/src/protection/providerTextInput.ts +21 -0
- package/src/run.ts +9 -0
- package/src/stream.ts +33 -7
- package/src/summarization/node.ts +32 -14
- package/src/tools/GitHubCompare.ts +319 -0
- package/src/tools/SubagentTool.ts +14 -3
- package/src/tools/ToolNode.ts +7 -3
- package/src/tools/subagent/SubagentExecutionRegistry.ts +6 -2
- package/src/tools/subagent/SubagentExecutor.ts +145 -18
- package/src/tools/subagent/SubagentReplay.ts +10 -3
- package/src/tools/subagent/childGraphConfig.ts +12 -1
- package/src/tools/subagent/diagnostics.ts +98 -6
- package/src/tools/subagent/hostArgs.ts +413 -0
- package/src/tools/subagent/index.ts +9 -0
- package/src/types/graph.ts +41 -0
- package/src/types/run.ts +4 -2
- package/src/types/tools.ts +6 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
2
|
+
|
|
3
|
+
export type DecisionOutputMethod = 'jsonSchema' | 'functionCalling';
|
|
4
|
+
|
|
5
|
+
/** Binds only verified enforcement paths; a model profile alone is not a strict-output guarantee. */
|
|
6
|
+
export function withDecisionStructuredOutput(
|
|
7
|
+
model: BaseChatModel,
|
|
8
|
+
schema: Record<string, unknown>,
|
|
9
|
+
method: DecisionOutputMethod
|
|
10
|
+
): ReturnType<BaseChatModel['withStructuredOutput']> {
|
|
11
|
+
const options = {
|
|
12
|
+
name: 'DecideQuestions',
|
|
13
|
+
method,
|
|
14
|
+
includeRaw: true as const,
|
|
15
|
+
};
|
|
16
|
+
const adapter = model._llmType();
|
|
17
|
+
if (
|
|
18
|
+
adapter === 'openai' ||
|
|
19
|
+
adapter === 'azure_openai' ||
|
|
20
|
+
(adapter === 'anthropic' && method === 'functionCalling')
|
|
21
|
+
) {
|
|
22
|
+
return model.withStructuredOutput(schema, { ...options, strict: true });
|
|
23
|
+
}
|
|
24
|
+
throw new Error('unverified strict decision model adapter');
|
|
25
|
+
}
|
package/src/graphs/Graph.ts
CHANGED
|
@@ -131,6 +131,10 @@ import {
|
|
|
131
131
|
resolveLangfuseConfig,
|
|
132
132
|
resolveToolOutputTracingConfig,
|
|
133
133
|
} from '@/langfuseConfig';
|
|
134
|
+
import {
|
|
135
|
+
ProviderTextProtectionError,
|
|
136
|
+
validateProviderTextProtection,
|
|
137
|
+
} from '@/protection/providerText';
|
|
134
138
|
import {
|
|
135
139
|
annotateMessagesForLLM,
|
|
136
140
|
ToolOutputReferenceRegistry,
|
|
@@ -139,6 +143,10 @@ import {
|
|
|
139
143
|
InvalidModelToolCallError,
|
|
140
144
|
snapshotAcceptedModelResponse,
|
|
141
145
|
} from './acceptedModelResponse';
|
|
146
|
+
import {
|
|
147
|
+
collectSubagentHostArgNames,
|
|
148
|
+
pickSubagentHostArgInput,
|
|
149
|
+
} from '@/tools/subagent/hostArgs';
|
|
142
150
|
import {
|
|
143
151
|
prepareProviderRequest,
|
|
144
152
|
usesNativeOpenAIResponses,
|
|
@@ -1378,6 +1386,8 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1378
1386
|
* these on every streamed chunk event.
|
|
1379
1387
|
*/
|
|
1380
1388
|
streamLimits: ResolvedStreamLimits;
|
|
1389
|
+
/** Default-off mandatory provider prose release. */
|
|
1390
|
+
providerTextProtection?: t.StandardGraphInput['providerTextProtection'];
|
|
1381
1391
|
/**
|
|
1382
1392
|
* Cumulative streamed argument bytes per in-flight tool call, keyed by
|
|
1383
1393
|
* generation key + chunk index (see `resolveGenerationKey`). Per-run
|
|
@@ -1423,25 +1433,31 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1423
1433
|
* attempt lease; spans resets on purpose. */
|
|
1424
1434
|
activeStreamLimitGenerations?: Set<string>;
|
|
1425
1435
|
|
|
1426
|
-
/** The
|
|
1436
|
+
/** The safety error behind an already-fired breaker, whether this
|
|
1427
1437
|
* graph's own controller tripped or a parent run's breaker arrived through
|
|
1428
1438
|
* the composed constructor signal (child graphs own separate controllers).
|
|
1429
1439
|
* Providers can translate either abort into a generic error, and recovery
|
|
1430
1440
|
* paths must not run in that state. */
|
|
1431
1441
|
protected resolveTrippedBreakerReason(
|
|
1432
1442
|
breakerSignal: AbortSignal = this.breakerAbort.signal
|
|
1433
|
-
):
|
|
1443
|
+
):
|
|
1444
|
+
| StreamLimitExceededError
|
|
1445
|
+
| PreparedSubagentError
|
|
1446
|
+
| ProviderTextProtectionError
|
|
1447
|
+
| undefined {
|
|
1434
1448
|
if (
|
|
1435
1449
|
breakerSignal.aborted &&
|
|
1436
1450
|
(breakerSignal.reason instanceof StreamLimitExceededError ||
|
|
1437
|
-
breakerSignal.reason instanceof PreparedSubagentError
|
|
1451
|
+
breakerSignal.reason instanceof PreparedSubagentError ||
|
|
1452
|
+
breakerSignal.reason instanceof ProviderTextProtectionError)
|
|
1438
1453
|
) {
|
|
1439
1454
|
return breakerSignal.reason;
|
|
1440
1455
|
}
|
|
1441
1456
|
if (
|
|
1442
1457
|
this.signal?.aborted === true &&
|
|
1443
1458
|
(this.signal.reason instanceof StreamLimitExceededError ||
|
|
1444
|
-
this.signal.reason instanceof PreparedSubagentError
|
|
1459
|
+
this.signal.reason instanceof PreparedSubagentError ||
|
|
1460
|
+
this.signal.reason instanceof ProviderTextProtectionError)
|
|
1445
1461
|
) {
|
|
1446
1462
|
return this.signal.reason;
|
|
1447
1463
|
}
|
|
@@ -1551,6 +1567,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1551
1567
|
onSubagentResolutionFailure,
|
|
1552
1568
|
preemption,
|
|
1553
1569
|
streamLimits,
|
|
1570
|
+
providerTextProtection,
|
|
1554
1571
|
toolExecution,
|
|
1555
1572
|
clientDelegatedToolNames,
|
|
1556
1573
|
}: t.StandardGraphInput,
|
|
@@ -1580,8 +1597,14 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1580
1597
|
this.onSubagentResolutionFailure = onSubagentResolutionFailure;
|
|
1581
1598
|
this.preemption = preemption;
|
|
1582
1599
|
this.streamLimits = resolveStreamLimits(streamLimits);
|
|
1600
|
+
if (providerTextProtection != null)
|
|
1601
|
+
validateProviderTextProtection(providerTextProtection);
|
|
1602
|
+
this.providerTextProtection = providerTextProtection;
|
|
1583
1603
|
this.toolExecution = toolExecution;
|
|
1584
|
-
if (
|
|
1604
|
+
if (
|
|
1605
|
+
clientDelegatedToolNames != null &&
|
|
1606
|
+
clientDelegatedToolNames.length > 0
|
|
1607
|
+
) {
|
|
1585
1608
|
if (agents.length !== 1) {
|
|
1586
1609
|
throw new Error('Client tool delegation requires a single-agent graph');
|
|
1587
1610
|
}
|
|
@@ -4404,7 +4427,12 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4404
4427
|
* succeeding fallback would resolve a run the public contract says
|
|
4405
4428
|
* must reject. Rethrow before any recovery path.
|
|
4406
4429
|
*/
|
|
4407
|
-
if (
|
|
4430
|
+
if (
|
|
4431
|
+
primaryError instanceof InvalidModelToolCallError ||
|
|
4432
|
+
primaryError instanceof ProviderTextProtectionError
|
|
4433
|
+
) {
|
|
4434
|
+
if (primaryError instanceof ProviderTextProtectionError)
|
|
4435
|
+
attemptBreaker.abort(primaryError);
|
|
4408
4436
|
throw primaryError;
|
|
4409
4437
|
}
|
|
4410
4438
|
if (
|
|
@@ -4747,7 +4775,12 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4747
4775
|
})
|
|
4748
4776
|
);
|
|
4749
4777
|
} catch (fallbackError) {
|
|
4750
|
-
if (
|
|
4778
|
+
if (
|
|
4779
|
+
fallbackError instanceof InvalidModelToolCallError ||
|
|
4780
|
+
fallbackError instanceof ProviderTextProtectionError
|
|
4781
|
+
) {
|
|
4782
|
+
if (fallbackError instanceof ProviderTextProtectionError)
|
|
4783
|
+
attemptBreaker.abort(fallbackError);
|
|
4751
4784
|
throw fallbackError;
|
|
4752
4785
|
}
|
|
4753
4786
|
if (
|
|
@@ -5347,6 +5380,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
5347
5380
|
subagentContext: this.subagentContext,
|
|
5348
5381
|
onResolutionFailure: this.onSubagentResolutionFailure,
|
|
5349
5382
|
streamLimits: this.streamLimits,
|
|
5383
|
+
providerTextProtection: this.providerTextProtection,
|
|
5350
5384
|
humanInTheLoop: this.humanInTheLoop,
|
|
5351
5385
|
checkpointer: this.compileOptions?.checkpointer,
|
|
5352
5386
|
maxDepth: effectiveSubagentDepth,
|
|
@@ -5361,6 +5395,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
5361
5395
|
): GraphFactory => snapshotChildGraphFactory(parentHandlerRegistry),
|
|
5362
5396
|
});
|
|
5363
5397
|
this.registerSubagentExecutor(executor);
|
|
5398
|
+
const hostArgNames = collectSubagentHostArgNames(executableConfigs);
|
|
5364
5399
|
|
|
5365
5400
|
const subagentTool = tool(
|
|
5366
5401
|
async (rawInput, config) => {
|
|
@@ -5370,6 +5405,10 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
5370
5405
|
subagent_thread_id?: string;
|
|
5371
5406
|
run_in_background?: boolean;
|
|
5372
5407
|
};
|
|
5408
|
+
const hostArgInput = pickSubagentHostArgInput(input, hostArgNames);
|
|
5409
|
+
if (!hostArgInput.ok) {
|
|
5410
|
+
return hostArgInput.message;
|
|
5411
|
+
}
|
|
5373
5412
|
const description =
|
|
5374
5413
|
typeof input.description === 'string' &&
|
|
5375
5414
|
input.description.trim().length > 0
|
|
@@ -5426,6 +5465,9 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
5426
5465
|
parentConfigurable: config.configurable as
|
|
5427
5466
|
| Record<string, unknown>
|
|
5428
5467
|
| undefined,
|
|
5468
|
+
...(hostArgInput.hostArgs == null
|
|
5469
|
+
? {}
|
|
5470
|
+
: { hostArgs: hostArgInput.hostArgs }),
|
|
5429
5471
|
};
|
|
5430
5472
|
if (input.run_in_background === true) {
|
|
5431
5473
|
return executor.executeInBackground({
|
|
@@ -5556,8 +5598,10 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
5556
5598
|
const delegatedNames = this.clientDelegatedToolNames;
|
|
5557
5599
|
if (delegatedNames != null && delegatedNames.size > 0) {
|
|
5558
5600
|
const { messages } = state as t.BaseGraphState;
|
|
5559
|
-
const last = messages[messages.length - 1] as
|
|
5560
|
-
|
|
5601
|
+
const last = messages[messages.length - 1] as
|
|
5602
|
+
| AIMessageChunk
|
|
5603
|
+
| undefined;
|
|
5604
|
+
const calls = last?.getType() === 'ai' ? (last.tool_calls ?? []) : [];
|
|
5561
5605
|
if (calls.some((call) => delegatedNames.has(call.name))) {
|
|
5562
5606
|
if (
|
|
5563
5607
|
calls.some(
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './summarization';
|
|
|
16
16
|
|
|
17
17
|
/* Tools */
|
|
18
18
|
export * from './tools/Calculator';
|
|
19
|
+
export * from './tools/GitHubCompare';
|
|
19
20
|
export * from './tools/CodeExecutor';
|
|
20
21
|
export * from './tools/BashExecutor';
|
|
21
22
|
export * from './tools/ProgrammaticToolCalling';
|
|
@@ -121,3 +122,10 @@ export type {
|
|
|
121
122
|
} from './llm/streamLimits';
|
|
122
123
|
export * from './decisions';
|
|
123
124
|
export * from './rerank';
|
|
125
|
+
|
|
126
|
+
export { PROVIDER_TEXT_PROTECTION_VERSION, ProviderTextProtectionError } from './protection/providerText';
|
|
127
|
+
export type {
|
|
128
|
+
ProviderTextProtection,
|
|
129
|
+
ProviderTextProtectionResult,
|
|
130
|
+
ProviderTextProtectionErrorCode,
|
|
131
|
+
} from './protection/providerText';
|
package/src/llm/invoke.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { ToolCall } from '@langchain/core/messages/tool';
|
|
|
14
14
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
15
15
|
import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
|
|
16
16
|
import type { PreparedProviderRequest } from '@/llm/prepareProviderRequest';
|
|
17
|
+
import type { ProviderTextProtection } from '@/protection/providerText';
|
|
17
18
|
import type { ContextOverflowContext } from '@/utils/errors';
|
|
18
19
|
import type { StreamLimitState } from '@/llm/streamLimits';
|
|
19
20
|
import type { PreemptAction } from '@/llm/preempt';
|
|
@@ -28,6 +29,12 @@ import {
|
|
|
28
29
|
STREAM_LIMIT_REDISPATCH_KEY,
|
|
29
30
|
STREAM_LIMIT_ATTEMPT_KEY,
|
|
30
31
|
} from '@/llm/streamLimits';
|
|
32
|
+
import {
|
|
33
|
+
validateProviderTextProtection,
|
|
34
|
+
ProviderTextProtectionError,
|
|
35
|
+
createProviderTextRestartCancellation,
|
|
36
|
+
isProviderTextRestartCancellation,
|
|
37
|
+
} from '@/protection/providerText';
|
|
31
38
|
import {
|
|
32
39
|
inspectProviderMessageProjection,
|
|
33
40
|
ProviderMessageProjectionInvariantError,
|
|
@@ -56,6 +63,7 @@ import {
|
|
|
56
63
|
} from '@/llm/providers';
|
|
57
64
|
import { ChatModelStreamHandler, dispatchesChatModelStream } from '@/stream';
|
|
58
65
|
import { Constants, ContentTypes, GraphEvents, Providers } from '@/common';
|
|
66
|
+
import { withProviderTextBoundary } from '@/llm/providerTextBoundary';
|
|
59
67
|
import { PreparedSubagentError } from '@/tools/preparedSubagents';
|
|
60
68
|
import { assertNotTruncatedToolCall } from '@/llm/truncation';
|
|
61
69
|
import { resolveClientOptionsModel } from '@/llm/request';
|
|
@@ -623,6 +631,7 @@ function appendStreamChunk({
|
|
|
623
631
|
*/
|
|
624
632
|
interface AttemptInvokeCommonParams {
|
|
625
633
|
context?: InvokeContext;
|
|
634
|
+
providerTextProtection?: ProviderTextProtection;
|
|
626
635
|
onChunk?: OnChunk;
|
|
627
636
|
/**
|
|
628
637
|
* The agent lane this attempt belongs to, as the model node names it. Only
|
|
@@ -697,6 +706,9 @@ export async function attemptInvoke(
|
|
|
697
706
|
params: AttemptInvokeParams,
|
|
698
707
|
config?: RunnableConfig
|
|
699
708
|
): Promise<Partial<t.BaseGraphState>> {
|
|
709
|
+
const policy =
|
|
710
|
+
params.providerTextProtection ?? params.context?.providerTextProtection;
|
|
711
|
+
if (policy != null) validateProviderTextProtection(policy);
|
|
700
712
|
const provider = resolveAttemptProvider(params);
|
|
701
713
|
const providerStampedConfig: RunnableConfig = {
|
|
702
714
|
...config,
|
|
@@ -707,7 +719,14 @@ export async function attemptInvoke(
|
|
|
707
719
|
resolvedProvider: provider,
|
|
708
720
|
},
|
|
709
721
|
};
|
|
710
|
-
const
|
|
722
|
+
const preparedRequest = resolveAttemptRequest(params, providerStampedConfig);
|
|
723
|
+
const request =
|
|
724
|
+
policy == null
|
|
725
|
+
? preparedRequest
|
|
726
|
+
: {
|
|
727
|
+
...preparedRequest,
|
|
728
|
+
model: withProviderTextBoundary(preparedRequest.model, policy, provider),
|
|
729
|
+
};
|
|
711
730
|
const configuredModel =
|
|
712
731
|
providerStampedConfig.metadata?.[Constants.INVOKED_MODEL];
|
|
713
732
|
const modelId =
|
|
@@ -763,6 +782,7 @@ export async function attemptInvoke(
|
|
|
763
782
|
context: params.context,
|
|
764
783
|
onChunk: params.onChunk,
|
|
765
784
|
preemptAgentId: params.preemptAgentId,
|
|
785
|
+
providerTextProtection: policy,
|
|
766
786
|
},
|
|
767
787
|
stampedConfig
|
|
768
788
|
);
|
|
@@ -775,6 +795,16 @@ export async function attemptInvoke(
|
|
|
775
795
|
prepared?.finish(preparedAttempt, calls);
|
|
776
796
|
return result;
|
|
777
797
|
} catch (error) {
|
|
798
|
+
if (policy != null && config?.signal?.aborted === true) {
|
|
799
|
+
const reason: unknown = config.signal.reason;
|
|
800
|
+
if (reason instanceof StreamLimitExceededError || reason instanceof PreparedSubagentError) {
|
|
801
|
+
prepared?.finish(preparedAttempt, undefined, reason);
|
|
802
|
+
throw reason;
|
|
803
|
+
}
|
|
804
|
+
const cancelled = new ProviderTextProtectionError(reason instanceof ProviderTextProtectionError ? reason.code : 'cancelled');
|
|
805
|
+
prepared?.finish(preparedAttempt, undefined, cancelled);
|
|
806
|
+
throw cancelled;
|
|
807
|
+
}
|
|
778
808
|
prepared?.finish(preparedAttempt, undefined, error);
|
|
779
809
|
throw error;
|
|
780
810
|
} finally {
|
|
@@ -799,9 +829,10 @@ async function attemptInvokeBody(
|
|
|
799
829
|
context,
|
|
800
830
|
onChunk,
|
|
801
831
|
preemptAgentId,
|
|
832
|
+
providerTextProtection,
|
|
802
833
|
}: Pick<
|
|
803
834
|
AttemptInvokeCommonParams,
|
|
804
|
-
'context' | 'onChunk' | 'preemptAgentId'
|
|
835
|
+
'context' | 'onChunk' | 'preemptAgentId' | 'providerTextProtection'
|
|
805
836
|
> & {
|
|
806
837
|
request: PreparedProviderRequest;
|
|
807
838
|
},
|
|
@@ -1068,7 +1099,7 @@ async function attemptInvokeBody(
|
|
|
1068
1099
|
notePreemptRestartedRun(sealedRunId, finalChunk);
|
|
1069
1100
|
}
|
|
1070
1101
|
restartRoute = 'aborted';
|
|
1071
|
-
restartController.abort();
|
|
1102
|
+
restartController.abort(providerTextProtection == null ? undefined : createProviderTextRestartCancellation());
|
|
1072
1103
|
return true;
|
|
1073
1104
|
};
|
|
1074
1105
|
const unsubscribeWake =
|
|
@@ -1085,7 +1116,8 @@ async function attemptInvokeBody(
|
|
|
1085
1116
|
if (
|
|
1086
1117
|
signal?.aborted === true &&
|
|
1087
1118
|
(signal.reason instanceof StreamLimitExceededError ||
|
|
1088
|
-
signal.reason instanceof PreparedSubagentError
|
|
1119
|
+
signal.reason instanceof PreparedSubagentError ||
|
|
1120
|
+
signal.reason instanceof ProviderTextProtectionError)
|
|
1089
1121
|
) {
|
|
1090
1122
|
throw signal.reason;
|
|
1091
1123
|
}
|
|
@@ -1334,6 +1366,7 @@ async function attemptInvokeBody(
|
|
|
1334
1366
|
restartRoute === 'aborted' &&
|
|
1335
1367
|
!(error instanceof StreamLimitExceededError) &&
|
|
1336
1368
|
!(error instanceof PreparedSubagentError) &&
|
|
1369
|
+
(!(error instanceof ProviderTextProtectionError) || isProviderTextRestartCancellation(error)) &&
|
|
1337
1370
|
config.signal?.aborted !== true;
|
|
1338
1371
|
if (!ownAbort) {
|
|
1339
1372
|
throw error;
|
|
@@ -1561,6 +1594,7 @@ export async function tryFallbackProviders({
|
|
|
1561
1594
|
context,
|
|
1562
1595
|
onChunk,
|
|
1563
1596
|
streamLimitState,
|
|
1597
|
+
providerTextProtection,
|
|
1564
1598
|
preemptAgentId,
|
|
1565
1599
|
overflowContext,
|
|
1566
1600
|
prepareProviderRequest: prepareFallbackRequest,
|
|
@@ -1576,6 +1610,7 @@ export async function tryFallbackProviders({
|
|
|
1576
1610
|
/** Accounting-lease owner forwarded to each fallback attempt (see
|
|
1577
1611
|
* `AttemptInvokeParams.streamLimitState`). */
|
|
1578
1612
|
streamLimitState?: StreamLimitState;
|
|
1613
|
+
providerTextProtection?: ProviderTextProtection;
|
|
1579
1614
|
/** Forwarded so a fallback-served attempt records a discarded turn in the
|
|
1580
1615
|
* SAME lane the primary would have (see
|
|
1581
1616
|
* `AttemptInvokeParams.preemptAgentId`). Dropping it here would leave the
|
|
@@ -1610,6 +1645,7 @@ export async function tryFallbackProviders({
|
|
|
1610
1645
|
config?: RunnableConfig;
|
|
1611
1646
|
}) => BaseMessage[] | Promise<BaseMessage[]>;
|
|
1612
1647
|
}): Promise<Partial<t.BaseGraphState> | undefined> {
|
|
1648
|
+
if (primaryError instanceof ProviderTextProtectionError) throw primaryError;
|
|
1613
1649
|
const isOverflow = (
|
|
1614
1650
|
error: unknown,
|
|
1615
1651
|
contextOverride = overflowContext
|
|
@@ -1686,7 +1722,8 @@ export async function tryFallbackProviders({
|
|
|
1686
1722
|
if (
|
|
1687
1723
|
config?.signal?.aborted === true &&
|
|
1688
1724
|
(config.signal.reason instanceof StreamLimitExceededError ||
|
|
1689
|
-
config.signal.reason instanceof PreparedSubagentError
|
|
1725
|
+
config.signal.reason instanceof PreparedSubagentError ||
|
|
1726
|
+
config.signal.reason instanceof ProviderTextProtectionError)
|
|
1690
1727
|
) {
|
|
1691
1728
|
throw config.signal.reason;
|
|
1692
1729
|
}
|
|
@@ -1697,6 +1734,7 @@ export async function tryFallbackProviders({
|
|
|
1697
1734
|
context,
|
|
1698
1735
|
onChunk,
|
|
1699
1736
|
streamLimitState,
|
|
1737
|
+
providerTextProtection,
|
|
1700
1738
|
preemptAgentId,
|
|
1701
1739
|
},
|
|
1702
1740
|
fbConfig
|
|
@@ -1710,6 +1748,7 @@ export async function tryFallbackProviders({
|
|
|
1710
1748
|
context,
|
|
1711
1749
|
onChunk,
|
|
1712
1750
|
streamLimitState,
|
|
1751
|
+
providerTextProtection,
|
|
1713
1752
|
preemptAgentId,
|
|
1714
1753
|
},
|
|
1715
1754
|
fbConfig
|
|
@@ -1723,7 +1762,8 @@ export async function tryFallbackProviders({
|
|
|
1723
1762
|
if (
|
|
1724
1763
|
e instanceof StreamLimitExceededError ||
|
|
1725
1764
|
e instanceof PreparedSubagentError ||
|
|
1726
|
-
e instanceof InvalidModelToolCallError
|
|
1765
|
+
e instanceof InvalidModelToolCallError ||
|
|
1766
|
+
e instanceof ProviderTextProtectionError
|
|
1727
1767
|
) {
|
|
1728
1768
|
throw e;
|
|
1729
1769
|
}
|
|
@@ -1734,7 +1774,8 @@ export async function tryFallbackProviders({
|
|
|
1734
1774
|
if (
|
|
1735
1775
|
config?.signal?.aborted === true &&
|
|
1736
1776
|
(config.signal.reason instanceof StreamLimitExceededError ||
|
|
1737
|
-
config.signal.reason instanceof PreparedSubagentError
|
|
1777
|
+
config.signal.reason instanceof PreparedSubagentError ||
|
|
1778
|
+
config.signal.reason instanceof ProviderTextProtectionError)
|
|
1738
1779
|
) {
|
|
1739
1780
|
throw config.signal.reason;
|
|
1740
1781
|
}
|
package/src/llm/openai/index.ts
CHANGED
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
hasToolCallChunks,
|
|
64
64
|
getReasoningKwargsText,
|
|
65
65
|
} from '@/llm/stream/chunkAdapters';
|
|
66
|
+
import { registerProviderTextChunkConstructor } from '@/llm/providerTextChunk';
|
|
66
67
|
import { isReasoningModel, _convertMessagesToOpenAIParams } from './utils';
|
|
67
68
|
import { smoothStream, resolveStreamDelay } from '@/llm/stream/smoother';
|
|
68
69
|
import { INTENT_ARG, isIntentLabelProperty } from '@/tools/intentArg';
|
|
@@ -855,6 +856,8 @@ class ResponsesReplayAIMessageChunk extends AIMessageChunk {
|
|
|
855
856
|
}
|
|
856
857
|
}
|
|
857
858
|
|
|
859
|
+
registerProviderTextChunkConstructor(ResponsesReplayAIMessageChunk);
|
|
860
|
+
|
|
858
861
|
function makeResponsesReplayAggregationSafe(
|
|
859
862
|
chunk: ChatGenerationChunk
|
|
860
863
|
): ChatGenerationChunk {
|
|
@@ -2923,6 +2926,11 @@ export class AzureChatOpenAI extends OriginalAzureChatOpenAI {
|
|
|
2923
2926
|
super(fields);
|
|
2924
2927
|
this.completions = new LibreChatAzureOpenAICompletions(fields);
|
|
2925
2928
|
this.responses = new LibreChatAzureOpenAIResponses(fields);
|
|
2929
|
+
this.fields = {
|
|
2930
|
+
...this.fields,
|
|
2931
|
+
completions: this.completions,
|
|
2932
|
+
responses: this.responses,
|
|
2933
|
+
};
|
|
2926
2934
|
this._lc_stream_delay = resolveStreamDelay(fields?._lc_stream_delay);
|
|
2927
2935
|
this.firstPartyEndpoint = fields?.firstPartyEndpoint;
|
|
2928
2936
|
}
|