@librechat/agents 4.0.1 → 4.0.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/agents/AgentContext.cjs +3 -2
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/decisions/deadline.cjs +52 -0
- package/dist/cjs/decisions/deadline.cjs.map +1 -0
- package/dist/cjs/decisions/dialect.cjs +88 -0
- package/dist/cjs/decisions/dialect.cjs.map +1 -0
- package/dist/cjs/decisions/http.cjs +77 -0
- package/dist/cjs/decisions/http.cjs.map +1 -0
- package/dist/cjs/decisions/index.cjs +7 -0
- package/dist/cjs/decisions/presets.cjs +82 -0
- package/dist/cjs/decisions/presets.cjs.map +1 -0
- package/dist/cjs/decisions/questions.cjs +70 -0
- package/dist/cjs/decisions/questions.cjs.map +1 -0
- package/dist/cjs/decisions/structuredChat.cjs +172 -0
- package/dist/cjs/decisions/structuredChat.cjs.map +1 -0
- package/dist/cjs/decisions/structuredOutput.cjs +18 -0
- package/dist/cjs/decisions/structuredOutput.cjs.map +1 -0
- package/dist/cjs/decisions/traceMarker.cjs +6 -0
- package/dist/cjs/decisions/traceMarker.cjs.map +1 -0
- package/dist/cjs/decisions/transport.cjs +166 -0
- package/dist/cjs/decisions/transport.cjs.map +1 -0
- package/dist/cjs/decisions/types.cjs +44 -0
- package/dist/cjs/decisions/types.cjs.map +1 -0
- package/dist/cjs/graphs/Graph.cjs +28 -9
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +6 -1
- package/dist/cjs/langfuseToolOutputTracing.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 +49 -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/rerank/index.cjs +2 -0
- package/dist/cjs/rerank/search.cjs +45 -0
- package/dist/cjs/rerank/search.cjs.map +1 -0
- package/dist/cjs/rerank/systemone.cjs +70 -0
- package/dist/cjs/rerank/systemone.cjs.map +1 -0
- package/dist/cjs/run.cjs +11 -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/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/search/rerankers.cjs +1 -0
- package/dist/cjs/tools/search/search.cjs +3 -3
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +4 -3
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs +13 -2
- package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +149 -26
- 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 +88 -2
- 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 +2 -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/deadline.mjs +52 -0
- package/dist/esm/decisions/deadline.mjs.map +1 -0
- package/dist/esm/decisions/dialect.mjs +87 -0
- package/dist/esm/decisions/dialect.mjs.map +1 -0
- package/dist/esm/decisions/http.mjs +75 -0
- package/dist/esm/decisions/http.mjs.map +1 -0
- package/dist/esm/decisions/index.mjs +8 -0
- package/dist/esm/decisions/presets.mjs +77 -0
- package/dist/esm/decisions/presets.mjs.map +1 -0
- package/dist/esm/decisions/questions.mjs +67 -0
- package/dist/esm/decisions/questions.mjs.map +1 -0
- package/dist/esm/decisions/structuredChat.mjs +172 -0
- package/dist/esm/decisions/structuredChat.mjs.map +1 -0
- package/dist/esm/decisions/structuredOutput.mjs +18 -0
- package/dist/esm/decisions/structuredOutput.mjs.map +1 -0
- package/dist/esm/decisions/traceMarker.mjs +6 -0
- package/dist/esm/decisions/traceMarker.mjs.map +1 -0
- package/dist/esm/decisions/transport.mjs +164 -0
- package/dist/esm/decisions/transport.mjs.map +1 -0
- package/dist/esm/decisions/types.mjs +39 -0
- package/dist/esm/decisions/types.mjs.map +1 -0
- package/dist/esm/graphs/Graph.mjs +28 -9
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +6 -1
- package/dist/esm/langfuseToolOutputTracing.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 +16 -2
- 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/rerank/index.mjs +3 -0
- package/dist/esm/rerank/search.mjs +45 -0
- package/dist/esm/rerank/search.mjs.map +1 -0
- package/dist/esm/rerank/systemone.mjs +70 -0
- package/dist/esm/rerank/systemone.mjs.map +1 -0
- package/dist/esm/run.mjs +11 -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/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/search/rerankers.mjs +1 -1
- package/dist/esm/tools/search/search.mjs +3 -3
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +4 -3
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs +13 -2
- package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +149 -26
- 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 +84 -3
- 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 +2 -0
- package/dist/esm/tools/toolErrorContent.mjs +1 -1
- package/dist/types/decisions/deadline.d.ts +3 -0
- package/dist/types/decisions/dialect.d.ts +11 -0
- package/dist/types/decisions/http.d.ts +22 -0
- package/dist/types/decisions/index.d.ts +10 -0
- package/dist/types/decisions/presets.d.ts +17 -0
- package/dist/types/decisions/questions.d.ts +8 -0
- package/dist/types/decisions/structuredChat.d.ts +17 -0
- package/dist/types/decisions/structuredOutput.d.ts +4 -0
- package/dist/types/decisions/traceMarker.d.ts +2 -0
- package/dist/types/decisions/transport.d.ts +29 -0
- package/dist/types/decisions/types.d.ts +119 -0
- package/dist/types/graphs/Graph.d.ts +7 -3
- package/dist/types/index.d.ts +4 -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/rerank/index.d.ts +4 -0
- package/dist/types/rerank/search.d.ts +7 -0
- package/dist/types/rerank/systemone.d.ts +13 -0
- package/dist/types/rerank/types.d.ts +24 -0
- package/dist/types/run.d.ts +2 -0
- package/dist/types/tools/BashExecutor.d.ts +4 -0
- package/dist/types/tools/CodeExecutor.d.ts +4 -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/search/types.d.ts +3 -1
- package/dist/types/tools/subagent/SubagentExecutionRegistry.d.ts +6 -0
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +22 -1
- package/dist/types/tools/subagent/SubagentReplay.d.ts +3 -1
- package/dist/types/tools/subagent/diagnostics.d.ts +56 -8
- package/dist/types/tools/subagent/hostArgs.d.ts +57 -0
- package/dist/types/tools/subagent/index.d.ts +3 -0
- package/dist/types/types/graph.d.ts +39 -0
- package/dist/types/types/run.d.ts +6 -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/deadline.ts +92 -0
- package/src/decisions/dialect.ts +200 -0
- package/src/decisions/http.ts +175 -0
- package/src/decisions/index.ts +14 -0
- package/src/decisions/presets.ts +111 -0
- package/src/decisions/questions.ts +128 -0
- package/src/decisions/structuredChat.ts +358 -0
- package/src/decisions/structuredOutput.ts +25 -0
- package/src/decisions/traceMarker.ts +2 -0
- package/src/decisions/transport.ts +335 -0
- package/src/decisions/types.ts +193 -0
- package/src/graphs/Graph.ts +57 -9
- package/src/index.ts +9 -0
- package/src/langfuseToolOutputTracing.ts +8 -1
- 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/rerank/index.ts +4 -0
- package/src/rerank/search.ts +85 -0
- package/src/rerank/systemone.ts +140 -0
- package/src/rerank/types.ts +28 -0
- package/src/run.ts +13 -0
- package/src/stream.ts +33 -7
- package/src/summarization/node.ts +32 -14
- package/src/tools/SubagentTool.ts +14 -3
- package/src/tools/ToolNode.ts +7 -3
- package/src/tools/search/search.ts +4 -4
- package/src/tools/search/tool.ts +27 -25
- package/src/tools/search/types.ts +4 -1
- package/src/tools/subagent/SubagentExecutionRegistry.ts +27 -2
- package/src/tools/subagent/SubagentExecutor.ts +323 -28
- package/src/tools/subagent/SubagentReplay.ts +10 -3
- package/src/tools/subagent/childGraphConfig.ts +12 -1
- package/src/tools/subagent/diagnostics.ts +180 -9
- package/src/tools/subagent/hostArgs.ts +413 -0
- package/src/tools/subagent/index.ts +20 -0
- package/src/types/graph.ts +44 -0
- package/src/types/run.ts +6 -2
- package/src/types/tools.ts +6 -1
|
@@ -60,6 +60,7 @@ import type {
|
|
|
60
60
|
SubagentTaskConfig,
|
|
61
61
|
SubagentTaskRuntime,
|
|
62
62
|
SubagentResolveConfigurable,
|
|
63
|
+
SubagentHostArgs,
|
|
63
64
|
SubagentResolveRequestContext,
|
|
64
65
|
SubagentResolveUserContext,
|
|
65
66
|
StepCompleted,
|
|
@@ -80,6 +81,12 @@ import type {
|
|
|
80
81
|
SubagentExecutionPreparationLease,
|
|
81
82
|
SubagentExecutionRecord,
|
|
82
83
|
} from './SubagentExecutionRegistry';
|
|
84
|
+
import type {
|
|
85
|
+
SubagentResolutionPhase,
|
|
86
|
+
SubagentResolutionCause,
|
|
87
|
+
SubagentHostArgumentFailure,
|
|
88
|
+
SubagentResolutionFailureHandler,
|
|
89
|
+
} from './diagnostics';
|
|
83
90
|
import type {
|
|
84
91
|
SubagentResumeExecution,
|
|
85
92
|
SubagentResumeManifest,
|
|
@@ -92,6 +99,7 @@ import type {
|
|
|
92
99
|
PreemptBoundaryHookOutput,
|
|
93
100
|
ToolApprovalReplaySnapshot,
|
|
94
101
|
} from '@/hooks';
|
|
102
|
+
import type { RunBreakerScope } from '@/llm/streamLimits';
|
|
95
103
|
import type { GraphFactory } from '@/graphs/graphFactory';
|
|
96
104
|
import type { StandardGraph } from '@/graphs/Graph';
|
|
97
105
|
import {
|
|
@@ -108,6 +116,18 @@ import {
|
|
|
108
116
|
SUBAGENT_RESUME_ATTEMPT_CONFIG_KEY,
|
|
109
117
|
SUBAGENT_RESUME_MANIFEST_CONFIG_KEY,
|
|
110
118
|
} from './SubagentReplay';
|
|
119
|
+
import {
|
|
120
|
+
logSubagentResolutionFailure,
|
|
121
|
+
SubagentResolutionError,
|
|
122
|
+
getSubagentHostArgumentFailure,
|
|
123
|
+
getSubagentHostArgumentFailureMessage,
|
|
124
|
+
} from './diagnostics';
|
|
125
|
+
import {
|
|
126
|
+
getSubagentHostArgSpecs,
|
|
127
|
+
resolveSubagentHostArgs,
|
|
128
|
+
pickSubagentHostArgInput,
|
|
129
|
+
getSubagentHostArgsDigest,
|
|
130
|
+
} from './hostArgs';
|
|
111
131
|
import {
|
|
112
132
|
rebindToolBatchReplayScope,
|
|
113
133
|
rebindToolBatchReplayPayload,
|
|
@@ -137,11 +157,11 @@ import {
|
|
|
137
157
|
createChildGraphPlan,
|
|
138
158
|
isGraphSubagentConfig,
|
|
139
159
|
} from './childGraphConfig';
|
|
160
|
+
import { ProviderTextProtectionError } from '@/protection/providerText';
|
|
140
161
|
import { stripRunStepResumeState } from '@/tools/runStepResume';
|
|
141
162
|
import { seedAgentInitialSessions } from '@/utils/toolSessions';
|
|
142
163
|
import { stableStringify } from '@/tools/eagerEventExecution';
|
|
143
164
|
import { convertInjectedMessages } from '@/messages/injected';
|
|
144
|
-
import { logSubagentResolutionFailure } from './diagnostics';
|
|
145
165
|
import { resolveClientOptionsModel } from '@/llm/request';
|
|
146
166
|
import { isBackgroundDenyMode } from '@/types/hitl';
|
|
147
167
|
import { composeAbortSignals } from '@/utils/misc';
|
|
@@ -162,13 +182,23 @@ const MAX_QUEUED_SUBAGENT_UPDATES = 64;
|
|
|
162
182
|
const MAX_BACKGROUND_SUBAGENT_SEALS = 32;
|
|
163
183
|
const SUBAGENT_UPDATE_HANDLER_TIMEOUT_MS = 5_000;
|
|
164
184
|
const TEXT_DELTA_CONTENT_TYPE = `${ContentTypes.TEXT}_delta`;
|
|
165
|
-
const SUBAGENT_RESOLUTION_ERROR_MESSAGE =
|
|
166
|
-
'Subagent error: Unable to initialize the selected subagent.';
|
|
167
185
|
const SUBAGENT_CONFIG_CHANGED_MESSAGE =
|
|
168
186
|
'Subagent error: Subagent configuration changed since this execution was paused.';
|
|
169
187
|
const SUBAGENT_INVOCATION_CHANGED_MESSAGE =
|
|
170
188
|
'Subagent error: Subagent invocation changed for this execution.';
|
|
171
189
|
|
|
190
|
+
function isSubagentResolutionControlFlow(error: unknown): boolean {
|
|
191
|
+
try {
|
|
192
|
+
return (
|
|
193
|
+
error instanceof StreamLimitExceededError ||
|
|
194
|
+
error instanceof ProviderTextProtectionError ||
|
|
195
|
+
isGraphInterrupt(error)
|
|
196
|
+
);
|
|
197
|
+
} catch {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
172
202
|
function seedChildGraphSessions(
|
|
173
203
|
childGraph: StandardGraph,
|
|
174
204
|
agents: AgentInputs[]
|
|
@@ -663,7 +693,8 @@ function getSettlementFingerprint(output: PersistedToolOutput): string {
|
|
|
663
693
|
function getBackgroundTaskFingerprint(
|
|
664
694
|
description: string,
|
|
665
695
|
subagentType: string,
|
|
666
|
-
threadId?: string
|
|
696
|
+
threadId?: string,
|
|
697
|
+
hostArgsDigest?: string
|
|
667
698
|
): string {
|
|
668
699
|
return createHash('sha256')
|
|
669
700
|
.update(
|
|
@@ -671,11 +702,29 @@ function getBackgroundTaskFingerprint(
|
|
|
671
702
|
description,
|
|
672
703
|
subagentType,
|
|
673
704
|
...(threadId == null || threadId === '' ? {} : { threadId }),
|
|
705
|
+
...(hostArgsDigest == null ? {} : { hostArgsDigest }),
|
|
674
706
|
})
|
|
675
707
|
)
|
|
676
708
|
.digest('hex');
|
|
677
709
|
}
|
|
678
710
|
|
|
711
|
+
/** Host-argument digest of persisted lifecycle args, when they are well formed. */
|
|
712
|
+
function getHostArgsDigestFromArgs(
|
|
713
|
+
config: ExecutableSubagentConfigEntry | undefined,
|
|
714
|
+
args: unknown
|
|
715
|
+
): string | undefined {
|
|
716
|
+
if (config == null || !isObjectLike(args)) {
|
|
717
|
+
return undefined;
|
|
718
|
+
}
|
|
719
|
+
const names = new Set(getSubagentHostArgSpecs(config).map(([name]) => name));
|
|
720
|
+
const picked = pickSubagentHostArgInput(args, names);
|
|
721
|
+
if (!picked.ok) {
|
|
722
|
+
return undefined;
|
|
723
|
+
}
|
|
724
|
+
const resolved = resolveSubagentHostArgs(config, picked.hostArgs);
|
|
725
|
+
return resolved.ok ? getSubagentHostArgsDigest(resolved.hostArgs) : undefined;
|
|
726
|
+
}
|
|
727
|
+
|
|
679
728
|
function getBackgroundTaskHookSessionId(
|
|
680
729
|
sourceHookSessionId: string,
|
|
681
730
|
taskId: string
|
|
@@ -862,11 +911,22 @@ export type SubagentExecuteParams = {
|
|
|
862
911
|
taskRuntime?: SubagentTaskRuntime;
|
|
863
912
|
/** Host-restored child transcript for a fresh continuation run. @internal */
|
|
864
913
|
initialMessages?: BaseMessage[];
|
|
914
|
+
/**
|
|
915
|
+
* Values for the selected subagent's declared `hostArgs`. Checked against
|
|
916
|
+
* the declaration before an execution opens, then bound to it.
|
|
917
|
+
*/
|
|
918
|
+
hostArgs?: SubagentHostArgs;
|
|
865
919
|
};
|
|
866
920
|
|
|
867
921
|
export type SubagentExecuteResult = SubagentContextResult & {
|
|
868
922
|
/** Tagged internal failure; foreground callers retain the legacy content. */
|
|
869
923
|
error?: string;
|
|
924
|
+
/** Safe startup classification retained for detached host delivery. */
|
|
925
|
+
resolutionFailure?: {
|
|
926
|
+
phase: SubagentResolutionPhase;
|
|
927
|
+
cause: SubagentResolutionCause;
|
|
928
|
+
hostArgument?: SubagentHostArgumentFailure;
|
|
929
|
+
};
|
|
870
930
|
/** Completed child work whose host projection must be retried without re-execution. */
|
|
871
931
|
retryableDelivery?: true;
|
|
872
932
|
};
|
|
@@ -937,6 +997,7 @@ export type SubagentExecutorOptions = {
|
|
|
937
997
|
* graph's own resolved limits; without this the child would silently
|
|
938
998
|
* revert to the defaults.
|
|
939
999
|
*/
|
|
1000
|
+
providerTextProtection?: StandardGraphInput['providerTextProtection'];
|
|
940
1001
|
streamLimits?: StandardGraphInput['streamLimits'];
|
|
941
1002
|
humanInTheLoop?: HumanInTheLoopConfig;
|
|
942
1003
|
/** Shared durable saver used to recover outer tool lifecycle results before
|
|
@@ -986,6 +1047,8 @@ export type SubagentExecutorOptions = {
|
|
|
986
1047
|
/** Host-owned process-local task namespace for detached execution. */
|
|
987
1048
|
taskConfig?: SubagentTaskConfig;
|
|
988
1049
|
subagentContext?: SubagentContextAdapter;
|
|
1050
|
+
/** Host diagnostic sink and safe cause classifier for startup failures. */
|
|
1051
|
+
onResolutionFailure?: SubagentResolutionFailureHandler;
|
|
989
1052
|
};
|
|
990
1053
|
|
|
991
1054
|
type DurableExecutionRecord = SubagentExecutionRecord<
|
|
@@ -1012,6 +1075,7 @@ export class SubagentExecutor {
|
|
|
1012
1075
|
private readonly executionContext: SubagentExecutionContext;
|
|
1013
1076
|
private readonly langfuse?: StandardGraphInput['langfuse'];
|
|
1014
1077
|
private readonly tokenCounter?: TokenCounter;
|
|
1078
|
+
private readonly providerTextProtection?: StandardGraphInput['providerTextProtection'];
|
|
1015
1079
|
private readonly streamLimits?: StandardGraphInput['streamLimits'];
|
|
1016
1080
|
private readonly humanInTheLoop?: HumanInTheLoopConfig;
|
|
1017
1081
|
private readonly checkpointer?: BaseCheckpointSaver;
|
|
@@ -1024,6 +1088,7 @@ export class SubagentExecutor {
|
|
|
1024
1088
|
private readonly usageSink?: SubagentUsageSink;
|
|
1025
1089
|
private readonly taskConfig?: SubagentTaskConfig;
|
|
1026
1090
|
private readonly subagentContext?: SubagentContextAdapter;
|
|
1091
|
+
private readonly onResolutionFailure?: SubagentResolutionFailureHandler;
|
|
1027
1092
|
private readonly executions: SubagentExecutionRegistry<
|
|
1028
1093
|
SubagentExecuteResult,
|
|
1029
1094
|
ResolvedSubagentConfig,
|
|
@@ -1051,6 +1116,7 @@ export class SubagentExecutor {
|
|
|
1051
1116
|
this.langfuse = options.langfuse;
|
|
1052
1117
|
this.tokenCounter = options.tokenCounter;
|
|
1053
1118
|
this.streamLimits = options.streamLimits;
|
|
1119
|
+
this.providerTextProtection = options.providerTextProtection;
|
|
1054
1120
|
this.humanInTheLoop = options.humanInTheLoop;
|
|
1055
1121
|
this.checkpointer = isCheckpointSaver(options.checkpointer)
|
|
1056
1122
|
? options.checkpointer
|
|
@@ -1069,6 +1135,7 @@ export class SubagentExecutor {
|
|
|
1069
1135
|
this.usageSink = options.usageSink;
|
|
1070
1136
|
this.taskConfig = options.taskConfig;
|
|
1071
1137
|
this.subagentContext = options.subagentContext;
|
|
1138
|
+
this.onResolutionFailure = options.onResolutionFailure;
|
|
1072
1139
|
const rawRegistry = options.parentHandlerRegistry;
|
|
1073
1140
|
if (typeof rawRegistry === 'function') {
|
|
1074
1141
|
this.resolveParentHandlerRegistry = rawRegistry;
|
|
@@ -1124,6 +1191,18 @@ export class SubagentExecutor {
|
|
|
1124
1191
|
message: `Unknown subagent type "${params.subagentType}".`,
|
|
1125
1192
|
});
|
|
1126
1193
|
}
|
|
1194
|
+
const hostArgResult = resolveSubagentHostArgs(
|
|
1195
|
+
executableConfig,
|
|
1196
|
+
params.hostArgs
|
|
1197
|
+
);
|
|
1198
|
+
if (!hostArgResult.ok) {
|
|
1199
|
+
return JSON.stringify({
|
|
1200
|
+
status: 'rejected',
|
|
1201
|
+
tool: Constants.SUBAGENT,
|
|
1202
|
+
message: hostArgResult.message,
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
const { hostArgs } = hostArgResult;
|
|
1127
1206
|
if (this.maxDepth <= 0) {
|
|
1128
1207
|
return JSON.stringify({
|
|
1129
1208
|
status: 'rejected',
|
|
@@ -1189,7 +1268,8 @@ export class SubagentExecutor {
|
|
|
1189
1268
|
requestFingerprint: getBackgroundTaskFingerprint(
|
|
1190
1269
|
params.description,
|
|
1191
1270
|
params.subagentType,
|
|
1192
|
-
subagentThreadId
|
|
1271
|
+
subagentThreadId,
|
|
1272
|
+
getSubagentHostArgsDigest(hostArgs)
|
|
1193
1273
|
),
|
|
1194
1274
|
...(subagentThreadId == null || subagentThreadId === ''
|
|
1195
1275
|
? {}
|
|
@@ -1204,6 +1284,7 @@ export class SubagentExecutor {
|
|
|
1204
1284
|
this.executeDetached(
|
|
1205
1285
|
{
|
|
1206
1286
|
...params,
|
|
1287
|
+
hostArgs,
|
|
1207
1288
|
...(initialMessages == null ? {} : { initialMessages }),
|
|
1208
1289
|
},
|
|
1209
1290
|
runtime,
|
|
@@ -1318,7 +1399,9 @@ export class SubagentExecutor {
|
|
|
1318
1399
|
tokenCounter: this.tokenCounter,
|
|
1319
1400
|
usageSink: this.usageSink,
|
|
1320
1401
|
subagentContext: this.subagentContext,
|
|
1402
|
+
onResolutionFailure: this.onResolutionFailure,
|
|
1321
1403
|
streamLimits: this.streamLimits,
|
|
1404
|
+
providerTextProtection: this.providerTextProtection,
|
|
1322
1405
|
humanInTheLoop:
|
|
1323
1406
|
this.humanInTheLoop?.enabled === true ||
|
|
1324
1407
|
this.humanInTheLoop?.backgroundPausePolicy === 'deny'
|
|
@@ -1369,6 +1452,13 @@ export class SubagentExecutor {
|
|
|
1369
1452
|
result = await executeAttempt();
|
|
1370
1453
|
}
|
|
1371
1454
|
if (result.error != null) {
|
|
1455
|
+
if (result.resolutionFailure != null) {
|
|
1456
|
+
throw new SubagentResolutionError(
|
|
1457
|
+
result.resolutionFailure.phase,
|
|
1458
|
+
result.resolutionFailure.cause,
|
|
1459
|
+
result.resolutionFailure.hostArgument
|
|
1460
|
+
);
|
|
1461
|
+
}
|
|
1372
1462
|
throw new Error(result.error);
|
|
1373
1463
|
}
|
|
1374
1464
|
if (this.humanInTheLoop?.enabled === true) {
|
|
@@ -1430,6 +1520,7 @@ export class SubagentExecutor {
|
|
|
1430
1520
|
threadId?: string;
|
|
1431
1521
|
parentToolCallId?: string;
|
|
1432
1522
|
parentConfigurable?: Record<string, unknown>;
|
|
1523
|
+
hostArgs?: SubagentHostArgs;
|
|
1433
1524
|
}
|
|
1434
1525
|
): Promise<ResolvedSubagentConfigEntry> {
|
|
1435
1526
|
if (isGraphSubagentConfig(config) || config.agentInputs != null) {
|
|
@@ -1458,6 +1549,9 @@ export class SubagentExecutor {
|
|
|
1458
1549
|
context.parentConfigurable == null
|
|
1459
1550
|
? undefined
|
|
1460
1551
|
: sanitizeResolverConfigurable(context.parentConfigurable),
|
|
1552
|
+
...(context.hostArgs == null
|
|
1553
|
+
? {}
|
|
1554
|
+
: { hostArgs: context.hostArgs }),
|
|
1461
1555
|
}),
|
|
1462
1556
|
context.childSignal
|
|
1463
1557
|
).then(
|
|
@@ -1662,13 +1756,6 @@ export class SubagentExecutor {
|
|
|
1662
1756
|
),
|
|
1663
1757
|
});
|
|
1664
1758
|
}
|
|
1665
|
-
const sourceCheckpoints =
|
|
1666
|
-
await this.getLatestCheckpointSnapshot(baseChildThreadId);
|
|
1667
|
-
if (sourceCheckpoints.length === 0) {
|
|
1668
|
-
throw new Error(
|
|
1669
|
-
`Cannot fork subagent checkpoint thread "${baseChildThreadId}" without a checkpoint ID.`
|
|
1670
|
-
);
|
|
1671
|
-
}
|
|
1672
1759
|
const childRunId = persistedChildRunId ?? currentChildRunId;
|
|
1673
1760
|
const identity = {
|
|
1674
1761
|
childRunId,
|
|
@@ -1678,6 +1765,14 @@ export class SubagentExecutor {
|
|
|
1678
1765
|
resumeAttemptId
|
|
1679
1766
|
),
|
|
1680
1767
|
};
|
|
1768
|
+
execution.recordIdentityAttempt(identity);
|
|
1769
|
+
const sourceCheckpoints =
|
|
1770
|
+
await this.getLatestCheckpointSnapshot(baseChildThreadId);
|
|
1771
|
+
if (sourceCheckpoints.length === 0) {
|
|
1772
|
+
throw new Error(
|
|
1773
|
+
`Cannot fork subagent checkpoint thread "${baseChildThreadId}" without a checkpoint ID.`
|
|
1774
|
+
);
|
|
1775
|
+
}
|
|
1681
1776
|
const lease = this.executions.beginIdentityPreparation(execution, identity);
|
|
1682
1777
|
await this.prepareCheckpointFork(
|
|
1683
1778
|
sourceCheckpoints,
|
|
@@ -1905,7 +2000,7 @@ export class SubagentExecutor {
|
|
|
1905
2000
|
}
|
|
1906
2001
|
const executions: SubagentResumeExecution[] = [];
|
|
1907
2002
|
for (const record of records) {
|
|
1908
|
-
const { identity, binding, activeRun } = record.snapshot;
|
|
2003
|
+
const { identity, binding, invocation, activeRun } = record.snapshot;
|
|
1909
2004
|
if (identity == null) {
|
|
1910
2005
|
continue;
|
|
1911
2006
|
}
|
|
@@ -1949,6 +2044,9 @@ export class SubagentExecutor {
|
|
|
1949
2044
|
? {}
|
|
1950
2045
|
: { subagentType: binding.subagentType }),
|
|
1951
2046
|
...(binding?.configId == null ? {} : { configId: binding.configId }),
|
|
2047
|
+
...(invocation?.hostArgsDigest == null
|
|
2048
|
+
? {}
|
|
2049
|
+
: { hostArgsDigest: invocation.hostArgsDigest }),
|
|
1952
2050
|
approvalExecutionScope: identity.approvalExecutionScope,
|
|
1953
2051
|
checkpoints,
|
|
1954
2052
|
graphState,
|
|
@@ -2083,9 +2181,10 @@ export class SubagentExecutor {
|
|
|
2083
2181
|
config: RunnableConfig
|
|
2084
2182
|
): Promise<SettledSubagentToolOutput | undefined> {
|
|
2085
2183
|
const parentToolCallId = call.id;
|
|
2184
|
+
const checkpointer = this.checkpointer;
|
|
2086
2185
|
if (
|
|
2087
2186
|
this.humanInTheLoop?.enabled !== true ||
|
|
2088
|
-
|
|
2187
|
+
checkpointer == null ||
|
|
2089
2188
|
parentToolCallId == null ||
|
|
2090
2189
|
parentToolCallId === ''
|
|
2091
2190
|
) {
|
|
@@ -2100,6 +2199,44 @@ export class SubagentExecutor {
|
|
|
2100
2199
|
parentToolCallId,
|
|
2101
2200
|
parentConfigurable,
|
|
2102
2201
|
});
|
|
2202
|
+
const signal = this.getReplaySignal(config);
|
|
2203
|
+
try {
|
|
2204
|
+
return await this.restoreSettledToolOutput(
|
|
2205
|
+
call,
|
|
2206
|
+
parentConfigurable,
|
|
2207
|
+
parentToolCallId,
|
|
2208
|
+
execution,
|
|
2209
|
+
checkpointer
|
|
2210
|
+
);
|
|
2211
|
+
} catch (error) {
|
|
2212
|
+
if (isSubagentResolutionControlFlow(error)) throw error;
|
|
2213
|
+
const failure = this.createReplayResolutionError(
|
|
2214
|
+
call,
|
|
2215
|
+
config,
|
|
2216
|
+
execution,
|
|
2217
|
+
signal,
|
|
2218
|
+
error
|
|
2219
|
+
);
|
|
2220
|
+
if (signal.aborted) throw failure;
|
|
2221
|
+
return {
|
|
2222
|
+
output: new ToolMessage({
|
|
2223
|
+
content: failure.message,
|
|
2224
|
+
name: call.name,
|
|
2225
|
+
tool_call_id: parentToolCallId,
|
|
2226
|
+
status: 'error',
|
|
2227
|
+
}),
|
|
2228
|
+
additionalContexts: [],
|
|
2229
|
+
};
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
private async restoreSettledToolOutput(
|
|
2234
|
+
call: ToolCall,
|
|
2235
|
+
parentConfigurable: Record<string, unknown> | undefined,
|
|
2236
|
+
parentToolCallId: string,
|
|
2237
|
+
execution: DurableExecutionRecord,
|
|
2238
|
+
checkpointer: BaseCheckpointSaver
|
|
2239
|
+
): Promise<SettledSubagentToolOutput | undefined> {
|
|
2103
2240
|
const { resumeExecution } = execution;
|
|
2104
2241
|
const inProcessSettledOutput = execution.settledOutput;
|
|
2105
2242
|
if (inProcessSettledOutput != null) {
|
|
@@ -2158,7 +2295,7 @@ export class SubagentExecutor {
|
|
|
2158
2295
|
const { childThreadId } =
|
|
2159
2296
|
await this.resolveChildExecutionIdentity(execution);
|
|
2160
2297
|
if (marker == null) {
|
|
2161
|
-
const checkpoint = await
|
|
2298
|
+
const checkpoint = await checkpointer.getTuple({
|
|
2162
2299
|
configurable: { thread_id: childThreadId },
|
|
2163
2300
|
});
|
|
2164
2301
|
messages = getCheckpointMessages(
|
|
@@ -2262,6 +2399,22 @@ export class SubagentExecutor {
|
|
|
2262
2399
|
) {
|
|
2263
2400
|
return;
|
|
2264
2401
|
}
|
|
2402
|
+
const resolvedHostArgsDigest =
|
|
2403
|
+
settled.resolvedArgs == null
|
|
2404
|
+
? undefined
|
|
2405
|
+
: getHostArgsDigestFromArgs(
|
|
2406
|
+
this.configs.get(
|
|
2407
|
+
resolvedSubagentType ?? execution.binding?.subagentType ?? ''
|
|
2408
|
+
),
|
|
2409
|
+
settled.resolvedArgs
|
|
2410
|
+
);
|
|
2411
|
+
if (
|
|
2412
|
+
boundInvocation != null &&
|
|
2413
|
+
settled.resolvedArgs != null &&
|
|
2414
|
+
resolvedHostArgsDigest !== boundInvocation.hostArgsDigest
|
|
2415
|
+
) {
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2265
2418
|
const description =
|
|
2266
2419
|
boundInvocation?.description ??
|
|
2267
2420
|
resolvedDescription ??
|
|
@@ -2293,10 +2446,15 @@ export class SubagentExecutor {
|
|
|
2293
2446
|
return;
|
|
2294
2447
|
}
|
|
2295
2448
|
const persistedOutput = serializeToolOutput(settled);
|
|
2449
|
+
const hostArgsDigest =
|
|
2450
|
+
settled.resolvedArgs == null
|
|
2451
|
+
? getHostArgsDigestFromArgs(executableConfig, call.args)
|
|
2452
|
+
: resolvedHostArgsDigest;
|
|
2296
2453
|
const invocation = boundInvocation ?? {
|
|
2297
2454
|
description,
|
|
2298
2455
|
subagentType,
|
|
2299
2456
|
...(configId == null ? {} : { configId }),
|
|
2457
|
+
...(hostArgsDigest == null ? {} : { hostArgsDigest }),
|
|
2300
2458
|
};
|
|
2301
2459
|
try {
|
|
2302
2460
|
await execution.settle(
|
|
@@ -2310,8 +2468,20 @@ export class SubagentExecutor {
|
|
|
2310
2468
|
},
|
|
2311
2469
|
persistedOutput,
|
|
2312
2470
|
async (): Promise<void> => {
|
|
2313
|
-
|
|
2314
|
-
|
|
2471
|
+
let identity: SubagentExecutionIdentity;
|
|
2472
|
+
try {
|
|
2473
|
+
identity = await this.resolveChildExecutionIdentity(execution);
|
|
2474
|
+
} catch (error) {
|
|
2475
|
+
if (isSubagentResolutionControlFlow(error)) throw error;
|
|
2476
|
+
throw this.createReplayResolutionError(
|
|
2477
|
+
call,
|
|
2478
|
+
config,
|
|
2479
|
+
execution,
|
|
2480
|
+
this.getReplaySignal(config),
|
|
2481
|
+
error
|
|
2482
|
+
);
|
|
2483
|
+
}
|
|
2484
|
+
const { childRunId, childThreadId } = identity;
|
|
2315
2485
|
const activeChildRun = execution.activeRun;
|
|
2316
2486
|
if (activeChildRun != null) {
|
|
2317
2487
|
await this.persistChildCheckpointMarker(
|
|
@@ -2401,6 +2571,15 @@ export class SubagentExecutor {
|
|
|
2401
2571
|
)
|
|
2402
2572
|
);
|
|
2403
2573
|
}
|
|
2574
|
+
const hostArgResult = resolveSubagentHostArgs(
|
|
2575
|
+
executableConfig,
|
|
2576
|
+
params.hostArgs
|
|
2577
|
+
);
|
|
2578
|
+
if (!hostArgResult.ok) {
|
|
2579
|
+
return Promise.resolve(createSubagentFailure(hostArgResult.message));
|
|
2580
|
+
}
|
|
2581
|
+
const { hostArgs } = hostArgResult;
|
|
2582
|
+
const hostArgsDigest = getSubagentHostArgsDigest(hostArgs);
|
|
2404
2583
|
if (this.maxDepth <= 0) {
|
|
2405
2584
|
return Promise.resolve(
|
|
2406
2585
|
createSubagentFailure('Error: Maximum subagent nesting depth exceeded.')
|
|
@@ -2439,8 +2618,10 @@ export class SubagentExecutor {
|
|
|
2439
2618
|
...(executableConfig.configId == null
|
|
2440
2619
|
? {}
|
|
2441
2620
|
: { configId: executableConfig.configId }),
|
|
2621
|
+
...(hostArgsDigest == null ? {} : { hostArgsDigest }),
|
|
2442
2622
|
},
|
|
2443
|
-
() =>
|
|
2623
|
+
() =>
|
|
2624
|
+
this.executeOnce({ ...params, hostArgs }, execution, executableConfig)
|
|
2444
2625
|
);
|
|
2445
2626
|
} catch (error) {
|
|
2446
2627
|
if (error instanceof SubagentDefinitionBindingError) {
|
|
@@ -2457,6 +2638,103 @@ export class SubagentExecutor {
|
|
|
2457
2638
|
}
|
|
2458
2639
|
}
|
|
2459
2640
|
|
|
2641
|
+
private getReplaySignal(config: RunnableConfig): AbortSignal {
|
|
2642
|
+
const scope = config.configurable?.[RUN_BREAKER_SCOPE_CONFIG_KEY] as
|
|
2643
|
+
| RunBreakerScope
|
|
2644
|
+
| undefined;
|
|
2645
|
+
return this.composeChildSignal(
|
|
2646
|
+
scope?.controller ?? this.resolveBreakerController(),
|
|
2647
|
+
config.signal
|
|
2648
|
+
);
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
private createReplayResolutionError(
|
|
2652
|
+
call: ToolCall,
|
|
2653
|
+
config: RunnableConfig,
|
|
2654
|
+
execution: DurableExecutionRecord,
|
|
2655
|
+
signal: AbortSignal,
|
|
2656
|
+
error: unknown
|
|
2657
|
+
): SubagentResolutionError {
|
|
2658
|
+
const selectedType =
|
|
2659
|
+
execution.binding?.subagentType ??
|
|
2660
|
+
execution.resumeExecution?.subagentType ??
|
|
2661
|
+
getSubagentType(call);
|
|
2662
|
+
const threadId = config.configurable?.thread_id;
|
|
2663
|
+
const failure = this.createResolutionFailure(
|
|
2664
|
+
'identity',
|
|
2665
|
+
{
|
|
2666
|
+
subagentType:
|
|
2667
|
+
selectedType == null
|
|
2668
|
+
? 'unknown'
|
|
2669
|
+
: (this.configs.get(selectedType)?.type ?? 'unknown'),
|
|
2670
|
+
description: DEFAULT_SUBAGENT_DESCRIPTION,
|
|
2671
|
+
parentToolCallId: call.id,
|
|
2672
|
+
threadId: typeof threadId === 'string' ? threadId : undefined,
|
|
2673
|
+
},
|
|
2674
|
+
execution,
|
|
2675
|
+
signal,
|
|
2676
|
+
error
|
|
2677
|
+
);
|
|
2678
|
+
return new SubagentResolutionError(
|
|
2679
|
+
'identity',
|
|
2680
|
+
failure.resolutionFailure?.cause ?? 'unknown'
|
|
2681
|
+
);
|
|
2682
|
+
}
|
|
2683
|
+
|
|
2684
|
+
private createResolutionFailure(
|
|
2685
|
+
phase: SubagentResolutionPhase,
|
|
2686
|
+
params: SubagentExecuteParams,
|
|
2687
|
+
execution: DurableExecutionRecord,
|
|
2688
|
+
signal: AbortSignal,
|
|
2689
|
+
error: unknown
|
|
2690
|
+
): SubagentExecuteResult {
|
|
2691
|
+
const identity = execution.identity ?? execution.attemptedIdentity;
|
|
2692
|
+
const resumeExecution =
|
|
2693
|
+
this.humanInTheLoop?.enabled === true && this.checkpointer != null
|
|
2694
|
+
? execution.resumeExecution
|
|
2695
|
+
: undefined;
|
|
2696
|
+
const detail = logSubagentResolutionFailure(
|
|
2697
|
+
phase,
|
|
2698
|
+
params.subagentType,
|
|
2699
|
+
signal,
|
|
2700
|
+
error,
|
|
2701
|
+
{
|
|
2702
|
+
parentRunId: this.parentRunId,
|
|
2703
|
+
parentAgentId: this.parentAgentId,
|
|
2704
|
+
parentToolCallId: params.parentToolCallId,
|
|
2705
|
+
threadId: params.threadId,
|
|
2706
|
+
childRunId:
|
|
2707
|
+
identity?.childRunId ??
|
|
2708
|
+
resumeExecution?.childRunId ??
|
|
2709
|
+
execution.address.currentChildRunId,
|
|
2710
|
+
childThreadId:
|
|
2711
|
+
identity?.childThreadId ??
|
|
2712
|
+
(resumeExecution == null
|
|
2713
|
+
? execution.address.baseChildThreadId
|
|
2714
|
+
: execution.address.branchChildThreadId),
|
|
2715
|
+
taskId: params.taskRuntime?.taskId,
|
|
2716
|
+
},
|
|
2717
|
+
this.onResolutionFailure,
|
|
2718
|
+
params.hostArgs
|
|
2719
|
+
);
|
|
2720
|
+
const hostArgument =
|
|
2721
|
+
phase === 'config'
|
|
2722
|
+
? getSubagentHostArgumentFailure(error, params.hostArgs)
|
|
2723
|
+
: undefined;
|
|
2724
|
+
if (hostArgument != null) {
|
|
2725
|
+
return {
|
|
2726
|
+
...createSubagentFailure(
|
|
2727
|
+
getSubagentHostArgumentFailureMessage(hostArgument)
|
|
2728
|
+
),
|
|
2729
|
+
resolutionFailure: { phase, cause: detail.cause, hostArgument },
|
|
2730
|
+
};
|
|
2731
|
+
}
|
|
2732
|
+
return {
|
|
2733
|
+
...createSubagentFailure(detail.message),
|
|
2734
|
+
resolutionFailure: { phase, cause: detail.cause },
|
|
2735
|
+
};
|
|
2736
|
+
}
|
|
2737
|
+
|
|
2460
2738
|
private async executeOnce(
|
|
2461
2739
|
params: SubagentExecuteParams,
|
|
2462
2740
|
execution: DurableExecutionRecord,
|
|
@@ -2485,21 +2763,29 @@ export class SubagentExecutor {
|
|
|
2485
2763
|
this.executions.remove(execution);
|
|
2486
2764
|
return createSubagentFailure(SUBAGENT_CONFIG_CHANGED_MESSAGE);
|
|
2487
2765
|
}
|
|
2766
|
+
if (
|
|
2767
|
+
resumeExecution != null &&
|
|
2768
|
+
resumeExecution.hostArgsDigest !==
|
|
2769
|
+
getSubagentHostArgsDigest(params.hostArgs)
|
|
2770
|
+
) {
|
|
2771
|
+
this.executions.remove(execution);
|
|
2772
|
+
return createSubagentFailure(SUBAGENT_INVOCATION_CHANGED_MESSAGE);
|
|
2773
|
+
}
|
|
2488
2774
|
let identity: SubagentExecutionIdentity;
|
|
2489
2775
|
try {
|
|
2490
2776
|
identity = await this.resolveChildExecutionIdentity(execution);
|
|
2491
2777
|
execution.assertUsable(childSignal);
|
|
2492
2778
|
} catch (error) {
|
|
2493
|
-
if (error
|
|
2779
|
+
if (isSubagentResolutionControlFlow(error)) {
|
|
2494
2780
|
throw error;
|
|
2495
2781
|
}
|
|
2496
|
-
|
|
2782
|
+
return this.createResolutionFailure(
|
|
2497
2783
|
'identity',
|
|
2498
|
-
|
|
2784
|
+
params,
|
|
2785
|
+
execution,
|
|
2499
2786
|
childSignal,
|
|
2500
2787
|
error
|
|
2501
2788
|
);
|
|
2502
|
-
return createSubagentFailure(SUBAGENT_RESOLUTION_ERROR_MESSAGE);
|
|
2503
2789
|
}
|
|
2504
2790
|
const { childRunId, childThreadId, approvalExecutionScope } = identity;
|
|
2505
2791
|
const bound = this.bindExecutionDefinition(
|
|
@@ -2523,19 +2809,20 @@ export class SubagentExecutor {
|
|
|
2523
2809
|
threadId,
|
|
2524
2810
|
parentToolCallId,
|
|
2525
2811
|
parentConfigurable: params.parentConfigurable,
|
|
2812
|
+
hostArgs: params.hostArgs,
|
|
2526
2813
|
});
|
|
2527
2814
|
execution.assertUsable(childSignal);
|
|
2528
2815
|
} catch (error) {
|
|
2529
|
-
if (error
|
|
2816
|
+
if (isSubagentResolutionControlFlow(error)) {
|
|
2530
2817
|
throw error;
|
|
2531
2818
|
}
|
|
2532
|
-
|
|
2819
|
+
return this.createResolutionFailure(
|
|
2533
2820
|
'config',
|
|
2534
|
-
|
|
2821
|
+
params,
|
|
2822
|
+
execution,
|
|
2535
2823
|
childSignal,
|
|
2536
2824
|
error
|
|
2537
2825
|
);
|
|
2538
|
-
return createSubagentFailure(SUBAGENT_RESOLUTION_ERROR_MESSAGE);
|
|
2539
2826
|
}
|
|
2540
2827
|
|
|
2541
2828
|
const parentRegistry = this.getParentHandlerRegistry();
|
|
@@ -2664,9 +2951,11 @@ export class SubagentExecutor {
|
|
|
2664
2951
|
langfuse: this.langfuse,
|
|
2665
2952
|
tokenCounter: this.tokenCounter,
|
|
2666
2953
|
streamLimits: this.streamLimits,
|
|
2954
|
+
providerTextProtection: this.providerTextProtection,
|
|
2667
2955
|
subagentScope: true,
|
|
2668
2956
|
subagentExecutionContext: childExecutionContext,
|
|
2669
2957
|
subagentContext: this.subagentContext,
|
|
2958
|
+
onSubagentResolutionFailure: this.onResolutionFailure,
|
|
2670
2959
|
...(resumeExecution?.graphState.fadingTier == null
|
|
2671
2960
|
? {}
|
|
2672
2961
|
: { fadingTier: resumeExecution.graphState.fadingTier }),
|
|
@@ -3109,7 +3398,10 @@ export class SubagentExecutor {
|
|
|
3109
3398
|
* quota for that entire interval. Trips the ENTRY-captured controller:
|
|
3110
3399
|
* after a reset, a straggler must break its own dead run, not the
|
|
3111
3400
|
* current one. */
|
|
3112
|
-
if (
|
|
3401
|
+
if (
|
|
3402
|
+
error instanceof StreamLimitExceededError ||
|
|
3403
|
+
error instanceof ProviderTextProtectionError
|
|
3404
|
+
) {
|
|
3113
3405
|
childBreaker.abort(error);
|
|
3114
3406
|
}
|
|
3115
3407
|
const errorMessage = truncateErrorMessage(error);
|
|
@@ -3148,7 +3440,10 @@ export class SubagentExecutor {
|
|
|
3148
3440
|
* fired. Rethrown here and passed through ToolNode's error conversion,
|
|
3149
3441
|
* so the parent run rejects with the child's limit error.
|
|
3150
3442
|
*/
|
|
3151
|
-
if (
|
|
3443
|
+
if (
|
|
3444
|
+
error instanceof StreamLimitExceededError ||
|
|
3445
|
+
error instanceof ProviderTextProtectionError
|
|
3446
|
+
) {
|
|
3152
3447
|
throw error;
|
|
3153
3448
|
}
|
|
3154
3449
|
return createSubagentFailure(
|