@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
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import type { ToolCall, ToolMessage } from '@langchain/core/messages/tool';
|
|
2
2
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
3
|
-
import type { ToolOutputReferenceState } from '@/tools/toolOutputReferences';
|
|
4
|
-
import type { ToolApprovalReplaySnapshot } from '@/hooks';
|
|
5
3
|
import type {
|
|
6
4
|
FadingTier,
|
|
7
5
|
FadingTiers,
|
|
8
6
|
RunStepResumeState,
|
|
9
7
|
ToolSessionContext,
|
|
10
8
|
} from '@/types';
|
|
11
|
-
import {
|
|
9
|
+
import type { ToolOutputReferenceState } from '@/tools/toolOutputReferences';
|
|
10
|
+
import type { ToolApprovalReplaySnapshot } from '@/hooks';
|
|
12
11
|
import {
|
|
13
12
|
attachRunStepResumeState,
|
|
14
13
|
getRunStepResumeState,
|
|
15
14
|
isRunStepResumeState,
|
|
16
15
|
stripRunStepResumeState,
|
|
17
16
|
} from '@/tools/runStepResume';
|
|
17
|
+
import { isFadingTier, isLegacyFadingTier } from '@/messages/fading';
|
|
18
18
|
|
|
19
19
|
export const SUBAGENT_RESUME_MANIFEST_CONFIG_KEY =
|
|
20
20
|
'__librechat_subagent_resume_manifest';
|
|
@@ -35,6 +35,7 @@ const SUBAGENT_RESUME_PRIVATE_PAYLOAD_KEYS = [
|
|
|
35
35
|
SUBAGENT_RESUME_WRAPPER_VERSION_KEY,
|
|
36
36
|
] as const;
|
|
37
37
|
const MAX_RESUME_MANIFEST_DEPTH = 32;
|
|
38
|
+
const HOST_ARGS_DIGEST_PATTERN = /^[a-f0-9]{64}$/;
|
|
38
39
|
|
|
39
40
|
export interface SubagentCheckpointReference {
|
|
40
41
|
threadId: string;
|
|
@@ -83,6 +84,8 @@ export interface SubagentResumeExecution {
|
|
|
83
84
|
subagentType?: string;
|
|
84
85
|
/** Lazy child revision bound when this execution first resolved. */
|
|
85
86
|
configId?: string;
|
|
87
|
+
/** SHA-256 identity of the host arguments bound to this execution; never the values. */
|
|
88
|
+
hostArgsDigest?: string;
|
|
86
89
|
approvalExecutionScope: string;
|
|
87
90
|
checkpoints: SubagentCheckpointReference[];
|
|
88
91
|
graphState: SubagentGraphResumeState;
|
|
@@ -354,6 +357,7 @@ function isSubagentResumeExecution(
|
|
|
354
357
|
const childRunId = execution.childRunId;
|
|
355
358
|
const subagentType = execution.subagentType;
|
|
356
359
|
const configId = execution.configId;
|
|
360
|
+
const hostArgsDigest = execution.hostArgsDigest;
|
|
357
361
|
const approvalExecutionScope = execution.approvalExecutionScope;
|
|
358
362
|
const checkpoints = execution.checkpoints;
|
|
359
363
|
const graphState = execution.graphState;
|
|
@@ -363,6 +367,9 @@ function isSubagentResumeExecution(
|
|
|
363
367
|
!isString(childRunId) ||
|
|
364
368
|
(subagentType != null && !isString(subagentType)) ||
|
|
365
369
|
(configId != null && !isString(configId)) ||
|
|
370
|
+
(hostArgsDigest != null &&
|
|
371
|
+
(typeof hostArgsDigest !== 'string' ||
|
|
372
|
+
!HOST_ARGS_DIGEST_PATTERN.test(hostArgsDigest))) ||
|
|
366
373
|
!isString(approvalExecutionScope) ||
|
|
367
374
|
!Array.isArray(checkpoints) ||
|
|
368
375
|
checkpoints.length === 0 ||
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
MAX_GRAPH_SUBAGENT_MEMBERS,
|
|
16
16
|
MAX_GRAPH_SUBAGENT_TURNS,
|
|
17
17
|
} from './runtimeLimits';
|
|
18
|
+
import { getSubagentHostArgSpecs } from './hostArgs';
|
|
18
19
|
|
|
19
20
|
const RESERVED_GRAPH_MEMBER_IDS = new Set([
|
|
20
21
|
'__start__',
|
|
@@ -69,6 +70,7 @@ type GraphSubagentConfigCandidate = {
|
|
|
69
70
|
configId?: unknown;
|
|
70
71
|
agentInputs?: unknown;
|
|
71
72
|
resolveAgentInputs?: unknown;
|
|
73
|
+
hostArgs?: unknown;
|
|
72
74
|
self?: unknown;
|
|
73
75
|
};
|
|
74
76
|
|
|
@@ -156,10 +158,11 @@ function assertGraphSubagentConfigShape(
|
|
|
156
158
|
candidate.agentInputs !== undefined ||
|
|
157
159
|
candidate.resolveAgentInputs !== undefined ||
|
|
158
160
|
candidate.configId !== undefined ||
|
|
161
|
+
candidate.hostArgs !== undefined ||
|
|
159
162
|
candidate.self !== undefined
|
|
160
163
|
) {
|
|
161
164
|
throw new Error(
|
|
162
|
-
`Graph subagent "${configType}" cannot define agentInputs or self, or lazy fields configId/resolveAgentInputs.`
|
|
165
|
+
`Graph subagent "${configType}" cannot define agentInputs or self, or lazy fields configId/resolveAgentInputs/hostArgs.`
|
|
163
166
|
);
|
|
164
167
|
}
|
|
165
168
|
}
|
|
@@ -482,6 +485,14 @@ function normalizeSingleAgentConfig(
|
|
|
482
485
|
`Subagent "${config.type}" cannot combine self with resolveAgentInputs.`
|
|
483
486
|
);
|
|
484
487
|
}
|
|
488
|
+
if (
|
|
489
|
+
getSubagentHostArgSpecs(config).length > 0 &&
|
|
490
|
+
(config.resolveAgentInputs == null || config.agentInputs != null)
|
|
491
|
+
) {
|
|
492
|
+
throw new Error(
|
|
493
|
+
`Subagent "${config.type}" declares hostArgs, which only a lazy resolveAgentInputs config without eager agentInputs can receive.`
|
|
494
|
+
);
|
|
495
|
+
}
|
|
485
496
|
if (config.agentInputs != null) {
|
|
486
497
|
return config as ResolvedSingleAgentSubagentConfig;
|
|
487
498
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SubagentHostArgs } from '@/types/graph';
|
|
1
2
|
import {
|
|
2
3
|
SubagentSettlementBindingError,
|
|
3
4
|
SubagentDefinitionBindingError,
|
|
@@ -5,11 +6,39 @@ import {
|
|
|
5
6
|
SubagentExecutionInvalidatedError,
|
|
6
7
|
} from './SubagentExecutionRegistry';
|
|
7
8
|
import { describeCodeApiError } from '@/tools/diagnostics';
|
|
9
|
+
import { isSubagentHostArgName } from './hostArgs';
|
|
8
10
|
|
|
9
11
|
/** Which step of child start-up failed: execution identity, then host config resolution. */
|
|
10
12
|
export type SubagentResolutionPhase = 'identity' | 'config';
|
|
11
13
|
|
|
14
|
+
/** Why a host resolver refused a declared host argument value. */
|
|
15
|
+
export type SubagentHostArgumentRejection = 'unavailable' | 'not_allowed';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Thrown by a lazy resolver to refuse one declared host argument value. The
|
|
19
|
+
* parent model receives a fixed message naming the argument; the value and
|
|
20
|
+
* any error text stay private.
|
|
21
|
+
*/
|
|
22
|
+
export class SubagentHostArgumentError extends Error {
|
|
23
|
+
readonly argument: string;
|
|
24
|
+
readonly rejection: SubagentHostArgumentRejection;
|
|
25
|
+
|
|
26
|
+
constructor(argument: string, rejection: SubagentHostArgumentRejection) {
|
|
27
|
+
super('Subagent host argument was rejected.');
|
|
28
|
+
this.name = 'SubagentHostArgumentError';
|
|
29
|
+
this.argument = argument;
|
|
30
|
+
this.rejection = rejection;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Safe host-argument refusal retained across the detached delivery boundary. */
|
|
35
|
+
export type SubagentHostArgumentFailure = {
|
|
36
|
+
argument: string;
|
|
37
|
+
rejection: SubagentHostArgumentRejection;
|
|
38
|
+
};
|
|
39
|
+
|
|
12
40
|
const SUBAGENT_ERROR_TYPES = [
|
|
41
|
+
['SubagentHostArgumentError', SubagentHostArgumentError],
|
|
13
42
|
['SubagentExecutionInvalidatedError', SubagentExecutionInvalidatedError],
|
|
14
43
|
['SubagentDefinitionBindingError', SubagentDefinitionBindingError],
|
|
15
44
|
['SubagentInvocationBindingError', SubagentInvocationBindingError],
|
|
@@ -20,18 +49,132 @@ type SubagentErrorLabel =
|
|
|
20
49
|
| (typeof SUBAGENT_ERROR_TYPES)[number][0]
|
|
21
50
|
| ReturnType<typeof describeCodeApiError>['type'];
|
|
22
51
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
52
|
+
const SUBAGENT_RESOLUTION_MESSAGES = {
|
|
53
|
+
workspace_unavailable:
|
|
54
|
+
'Subagent error: Workspace unavailable. Retry later or choose another workspace.',
|
|
55
|
+
agent_unavailable: 'Subagent error: Agent not found or not accessible.',
|
|
56
|
+
model_unavailable: 'Subagent error: Model or provider unavailable.',
|
|
57
|
+
configuration_changed:
|
|
58
|
+
'Subagent error: Subagent configuration changed. Start a new execution.',
|
|
59
|
+
host_argument_rejected:
|
|
60
|
+
'Subagent error: A requested subagent argument is not available. Omit it to let the host choose, or pass a different value.',
|
|
61
|
+
unknown: 'Subagent error: Unable to initialize the selected subagent.',
|
|
62
|
+
} as const;
|
|
63
|
+
|
|
64
|
+
/** Host classifications accepted at the public failure boundary. */
|
|
65
|
+
export type SubagentResolutionCause = keyof typeof SUBAGENT_RESOLUTION_MESSAGES;
|
|
66
|
+
|
|
67
|
+
export type SubagentResolutionContext = {
|
|
68
|
+
parentRunId: string;
|
|
69
|
+
parentAgentId?: string;
|
|
70
|
+
parentToolCallId?: string;
|
|
71
|
+
threadId?: string;
|
|
72
|
+
childRunId: string;
|
|
73
|
+
childThreadId: string;
|
|
74
|
+
taskId?: string;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** No received error text, writable error names, or stacks enter this payload. */
|
|
29
78
|
export type SubagentResolutionDiagnostic = {
|
|
30
79
|
phase: SubagentResolutionPhase;
|
|
31
80
|
subagentType: string;
|
|
32
81
|
aborted: boolean;
|
|
33
82
|
type: SubagentErrorLabel;
|
|
34
|
-
|
|
83
|
+
cause: SubagentResolutionCause;
|
|
84
|
+
message: (typeof SUBAGENT_RESOLUTION_MESSAGES)[SubagentResolutionCause];
|
|
85
|
+
} & Partial<SubagentResolutionContext>;
|
|
86
|
+
|
|
87
|
+
/** The original error is private. Return a classification, never error text. */
|
|
88
|
+
export type SubagentResolutionFailureHandler = (
|
|
89
|
+
detail: Readonly<SubagentResolutionDiagnostic>,
|
|
90
|
+
error: unknown
|
|
91
|
+
) => SubagentResolutionCause | void;
|
|
92
|
+
|
|
93
|
+
function normalizeResolutionCause(
|
|
94
|
+
cause: SubagentResolutionCause | void
|
|
95
|
+
): SubagentResolutionCause {
|
|
96
|
+
switch (cause) {
|
|
97
|
+
case 'workspace_unavailable':
|
|
98
|
+
case 'agent_unavailable':
|
|
99
|
+
case 'model_unavailable':
|
|
100
|
+
case 'configuration_changed':
|
|
101
|
+
case 'host_argument_rejected':
|
|
102
|
+
return cause;
|
|
103
|
+
default:
|
|
104
|
+
return 'unknown';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function getSubagentResolutionFailureMessage(
|
|
109
|
+
cause: SubagentResolutionCause
|
|
110
|
+
): SubagentResolutionDiagnostic['message'] {
|
|
111
|
+
return SUBAGENT_RESOLUTION_MESSAGES[normalizeResolutionCause(cause)];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Returns a resolver's typed host-argument refusal when its name is safe to show. */
|
|
115
|
+
export function getSubagentHostArgumentFailure(
|
|
116
|
+
error: unknown,
|
|
117
|
+
suppliedHostArgs: SubagentHostArgs | undefined
|
|
118
|
+
): SubagentHostArgumentFailure | undefined {
|
|
119
|
+
try {
|
|
120
|
+
if (
|
|
121
|
+
!(error instanceof SubagentHostArgumentError) ||
|
|
122
|
+
suppliedHostArgs == null
|
|
123
|
+
) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
const { argument, rejection } = error;
|
|
127
|
+
if (
|
|
128
|
+
typeof argument !== 'string' ||
|
|
129
|
+
!isSubagentHostArgName(argument) ||
|
|
130
|
+
!Object.prototype.hasOwnProperty.call(suppliedHostArgs, argument)
|
|
131
|
+
) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
argument,
|
|
136
|
+
rejection: rejection === 'unavailable' ? 'unavailable' : 'not_allowed',
|
|
137
|
+
};
|
|
138
|
+
} catch {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Model-facing message for a refused host argument. */
|
|
144
|
+
export function getSubagentHostArgumentFailureMessage(
|
|
145
|
+
failure: SubagentHostArgumentFailure
|
|
146
|
+
): string {
|
|
147
|
+
const { argument } = failure;
|
|
148
|
+
const omit = `Omit "${argument}" to let the host choose, or pass a different value.`;
|
|
149
|
+
return failure.rejection === 'unavailable'
|
|
150
|
+
? `Subagent error: The requested "${argument}" is unavailable right now. ${omit}`
|
|
151
|
+
: `Subagent error: The requested "${argument}" is not allowed for this subagent. ${omit}`;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Safe typed failure retained when detached execution crosses the host boundary. */
|
|
155
|
+
export class SubagentResolutionError extends Error {
|
|
156
|
+
readonly phase: SubagentResolutionPhase;
|
|
157
|
+
readonly resolutionCause: SubagentResolutionCause;
|
|
158
|
+
readonly hostArgument?: SubagentHostArgumentFailure;
|
|
159
|
+
|
|
160
|
+
constructor(
|
|
161
|
+
phase: SubagentResolutionPhase,
|
|
162
|
+
cause: SubagentResolutionCause,
|
|
163
|
+
hostArgument?: SubagentHostArgumentFailure
|
|
164
|
+
) {
|
|
165
|
+
super(
|
|
166
|
+
hostArgument == null
|
|
167
|
+
? getSubagentResolutionFailureMessage(cause)
|
|
168
|
+
: getSubagentHostArgumentFailureMessage(hostArgument)
|
|
169
|
+
);
|
|
170
|
+
this.name = 'SubagentResolutionError';
|
|
171
|
+
this.phase = phase;
|
|
172
|
+
this.resolutionCause = normalizeResolutionCause(cause);
|
|
173
|
+
if (hostArgument != null) {
|
|
174
|
+
this.hostArgument = hostArgument;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
35
178
|
|
|
36
179
|
function describeSubagentError(error: unknown): SubagentErrorLabel {
|
|
37
180
|
try {
|
|
@@ -50,14 +193,42 @@ export function logSubagentResolutionFailure(
|
|
|
50
193
|
phase: SubagentResolutionPhase,
|
|
51
194
|
subagentType: string,
|
|
52
195
|
signal: AbortSignal,
|
|
53
|
-
error: unknown
|
|
54
|
-
|
|
196
|
+
error: unknown,
|
|
197
|
+
context?: SubagentResolutionContext,
|
|
198
|
+
onResolutionFailure?: SubagentResolutionFailureHandler,
|
|
199
|
+
suppliedHostArgs?: SubagentHostArgs
|
|
200
|
+
): SubagentResolutionDiagnostic {
|
|
55
201
|
const detail: SubagentResolutionDiagnostic = {
|
|
202
|
+
...context,
|
|
56
203
|
phase,
|
|
57
204
|
subagentType,
|
|
58
205
|
aborted: signal.aborted,
|
|
59
206
|
type: describeSubagentError(error),
|
|
207
|
+
cause: 'unknown',
|
|
208
|
+
message: SUBAGENT_RESOLUTION_MESSAGES.unknown,
|
|
60
209
|
};
|
|
210
|
+
const hostArgumentRejected =
|
|
211
|
+
getSubagentHostArgumentFailure(error, suppliedHostArgs) != null;
|
|
212
|
+
if (hostArgumentRejected) {
|
|
213
|
+
detail.cause = 'host_argument_rejected';
|
|
214
|
+
detail.message = SUBAGENT_RESOLUTION_MESSAGES.host_argument_rejected;
|
|
215
|
+
}
|
|
216
|
+
if (onResolutionFailure != null) {
|
|
217
|
+
try {
|
|
218
|
+
const reported = onResolutionFailure(Object.freeze({ ...detail }), error);
|
|
219
|
+
const cause = hostArgumentRejected
|
|
220
|
+
? detail.cause
|
|
221
|
+
: normalizeResolutionCause(reported);
|
|
222
|
+
return {
|
|
223
|
+
...detail,
|
|
224
|
+
cause,
|
|
225
|
+
message: getSubagentResolutionFailureMessage(cause),
|
|
226
|
+
};
|
|
227
|
+
} catch {
|
|
228
|
+
// A broken diagnostic sink must not replace or expose the original failure.
|
|
229
|
+
}
|
|
230
|
+
}
|
|
61
231
|
// eslint-disable-next-line no-console
|
|
62
232
|
console.warn('[SubagentExecutor] Subagent resolution failed', detail);
|
|
233
|
+
return detail;
|
|
63
234
|
}
|