@librechat/agents 4.0.1 → 4.0.2
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/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 +178 -0
- package/dist/cjs/decisions/structuredChat.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 +4 -1
- 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/main.cjs +39 -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 +4 -0
- package/dist/cjs/run.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 +11 -0
- package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +87 -14
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/tools/subagent/diagnostics.cjs +45 -2
- package/dist/cjs/tools/subagent/diagnostics.cjs.map +1 -1
- package/dist/cjs/tools/subagent/index.cjs +1 -0
- 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 +178 -0
- package/dist/esm/decisions/structuredChat.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 +4 -1
- 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/main.mjs +13 -1
- 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 +4 -0
- package/dist/esm/run.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 +11 -0
- package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +88 -15
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/tools/subagent/diagnostics.mjs +44 -3
- package/dist/esm/tools/subagent/diagnostics.mjs.map +1 -1
- package/dist/esm/tools/subagent/index.mjs +1 -0
- 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 +16 -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 +2 -1
- package/dist/types/index.d.ts +2 -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 +1 -0
- package/dist/types/tools/search/types.d.ts +3 -1
- package/dist/types/tools/subagent/SubagentExecutionRegistry.d.ts +4 -0
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +13 -0
- package/dist/types/tools/subagent/diagnostics.d.ts +32 -8
- package/dist/types/tools/subagent/index.d.ts +2 -0
- package/dist/types/types/graph.d.ts +3 -0
- package/dist/types/types/run.d.ts +2 -0
- package/package.json +1 -1
- 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 +364 -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 +4 -0
- package/src/index.ts +2 -0
- package/src/langfuseToolOutputTracing.ts +8 -1
- 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 +4 -0
- 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 +21 -0
- package/src/tools/subagent/SubagentExecutor.ts +190 -22
- package/src/tools/subagent/diagnostics.ts +88 -9
- package/src/tools/subagent/index.ts +11 -0
- package/src/types/graph.ts +3 -0
- package/src/types/run.ts +2 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { DecisionCredential } from './types';
|
|
2
|
+
export type DecisionFetch = (input: string, init: {
|
|
3
|
+
method: string;
|
|
4
|
+
headers: Record<string, string>;
|
|
5
|
+
body: string;
|
|
6
|
+
signal: AbortSignal;
|
|
7
|
+
redirect: 'error';
|
|
8
|
+
}) => Promise<Pick<Response, 'ok' | 'status' | 'headers' | 'body'>>;
|
|
9
|
+
export interface TransportOptions {
|
|
10
|
+
providerId: string;
|
|
11
|
+
apiKey?: DecisionCredential;
|
|
12
|
+
requiresAuth?: boolean;
|
|
13
|
+
/** Full URL, not a base path. */
|
|
14
|
+
endpoint: string;
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
maxRetries?: number;
|
|
17
|
+
fetch?: DecisionFetch;
|
|
18
|
+
sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
19
|
+
/** Called only after the response parses, with no state, answers, or credentials. */
|
|
20
|
+
onAnswered?: (label: string, ms: number) => void;
|
|
21
|
+
}
|
|
22
|
+
export type Transport = <T>(prepare: () => {
|
|
23
|
+
payload: string;
|
|
24
|
+
parse: (body: string) => T;
|
|
25
|
+
}, signal: AbortSignal | undefined, label: string, timeoutOverrideMs?: number) => Promise<T>;
|
|
26
|
+
export declare function failureForStatus(status: number): 'unauthorized' | 'rate_limited' | 'server_error' | 'bad_request';
|
|
27
|
+
export declare function retryAfterMs(header: string | null): number | undefined;
|
|
28
|
+
/** One immutable transport; every call owns its signal, deadline, and credentials. */
|
|
29
|
+
export declare function createTransport(options: TransportOptions): Transport;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/** Typed decisions over content, independent of the model that makes them. */
|
|
2
|
+
export type DecisionJson = string | number | boolean | null | DecisionJson[] | {
|
|
3
|
+
[key: string]: DecisionJson;
|
|
4
|
+
};
|
|
5
|
+
export type DecisionText = string | DecisionJson[] | {
|
|
6
|
+
[key: string]: DecisionJson;
|
|
7
|
+
};
|
|
8
|
+
export type DecisionState = DecisionText;
|
|
9
|
+
export interface BooleanCriteria {
|
|
10
|
+
true?: DecisionText;
|
|
11
|
+
false?: DecisionText;
|
|
12
|
+
}
|
|
13
|
+
/** A string criterion describes the yes side of a yes/no question. */
|
|
14
|
+
export interface BooleanQuestion {
|
|
15
|
+
type: 'boolean';
|
|
16
|
+
instructions: DecisionText;
|
|
17
|
+
criteria?: BooleanCriteria | string;
|
|
18
|
+
}
|
|
19
|
+
export interface ChoiceQuestion {
|
|
20
|
+
type: 'choice';
|
|
21
|
+
instructions: DecisionText;
|
|
22
|
+
criteria: Record<string, DecisionText | null>;
|
|
23
|
+
}
|
|
24
|
+
/** The measured answer is an expected level, which may fall between two rubric levels. */
|
|
25
|
+
export interface ScoreQuestion {
|
|
26
|
+
type: 'score';
|
|
27
|
+
instructions: DecisionText;
|
|
28
|
+
criteria: DecisionText[];
|
|
29
|
+
}
|
|
30
|
+
export type DecisionQuestion = BooleanQuestion | ChoiceQuestion | ScoreQuestion;
|
|
31
|
+
/** `null` is an unmeasured decision, not a probability of zero. */
|
|
32
|
+
export type BooleanAnswer = {
|
|
33
|
+
type: 'boolean';
|
|
34
|
+
probability: number;
|
|
35
|
+
decision?: never;
|
|
36
|
+
} | {
|
|
37
|
+
type: 'boolean';
|
|
38
|
+
probability: null;
|
|
39
|
+
decision: boolean;
|
|
40
|
+
};
|
|
41
|
+
export interface ChoiceAnswer {
|
|
42
|
+
type: 'choice';
|
|
43
|
+
choice: string;
|
|
44
|
+
/** Backend-specific concentration measure; Jev and Laya use different definitions. */
|
|
45
|
+
confidence: number | null;
|
|
46
|
+
/** `null` when no distribution was measured; never substitute an empty distribution. */
|
|
47
|
+
probabilities: Record<string, number> | null;
|
|
48
|
+
}
|
|
49
|
+
export interface ScoreAnswer {
|
|
50
|
+
type: 'score';
|
|
51
|
+
/** Expected value over rubric levels, not an LLM's selection of one level. */
|
|
52
|
+
score: number;
|
|
53
|
+
/** Backend-specific concentration measure; do not transfer thresholds between checkpoints. */
|
|
54
|
+
confidence: number | null;
|
|
55
|
+
probabilities: Record<string, number> | null;
|
|
56
|
+
}
|
|
57
|
+
export type DecisionAnswer = BooleanAnswer | ChoiceAnswer | ScoreAnswer;
|
|
58
|
+
/** Unknown counts are omitted, never inferred from an answer or replaced by zero. */
|
|
59
|
+
export interface DecisionUsage {
|
|
60
|
+
inputTokens?: number;
|
|
61
|
+
outputTokens?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface DecisionRequest {
|
|
64
|
+
state: DecisionState;
|
|
65
|
+
questions: Record<string, DecisionQuestion>;
|
|
66
|
+
signal?: AbortSignal;
|
|
67
|
+
label?: string;
|
|
68
|
+
/** Overrides the provider's timeout for this request alone. */
|
|
69
|
+
timeoutMs?: number;
|
|
70
|
+
}
|
|
71
|
+
export interface DecisionResult {
|
|
72
|
+
model: string;
|
|
73
|
+
/** A requested answer can be omitted; callers must handle `undefined` explicitly. */
|
|
74
|
+
answers: Record<string, DecisionAnswer | undefined>;
|
|
75
|
+
usage: DecisionUsage | null;
|
|
76
|
+
}
|
|
77
|
+
export interface DecisionModel {
|
|
78
|
+
readonly id: string;
|
|
79
|
+
readonly model: string;
|
|
80
|
+
decide(request: DecisionRequest): Promise<DecisionResult>;
|
|
81
|
+
}
|
|
82
|
+
export type DecisionDialect = 'port' | 'systemone';
|
|
83
|
+
/** A bearer key, or a per-request token minter; a 401 requests one fresh token for that call. */
|
|
84
|
+
export type DecisionCredential = string | ((options: {
|
|
85
|
+
refresh: boolean;
|
|
86
|
+
signal?: AbortSignal;
|
|
87
|
+
}) => Promise<string>);
|
|
88
|
+
export interface DecisionProviderSettings {
|
|
89
|
+
/** Full URL of the decision endpoint, not a base path. */
|
|
90
|
+
baseURL?: string;
|
|
91
|
+
model?: string;
|
|
92
|
+
dialect?: DecisionDialect;
|
|
93
|
+
requestKey?: string;
|
|
94
|
+
responseKey?: string;
|
|
95
|
+
timeoutMs?: number;
|
|
96
|
+
maxRetries?: number;
|
|
97
|
+
/** Auth is required by default; self-hosted Laya can be unauthenticated. */
|
|
98
|
+
requiresAuth?: boolean;
|
|
99
|
+
apiKeyEnv?: string;
|
|
100
|
+
}
|
|
101
|
+
export type DecisionFailure = 'timeout' | 'aborted' | 'rate_limited' | 'unauthorized' | 'bad_request' | 'server_error' | 'network' | 'unsupported_question' | 'unsupported_mode' | 'malformed_response';
|
|
102
|
+
export declare class DecisionError extends Error {
|
|
103
|
+
readonly failure: DecisionFailure;
|
|
104
|
+
readonly provider: string;
|
|
105
|
+
readonly status?: number;
|
|
106
|
+
retryAfterMs?: number;
|
|
107
|
+
constructor(failure: DecisionFailure, message: string, options?: {
|
|
108
|
+
provider?: string;
|
|
109
|
+
status?: number;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/** A JSON boundary guard; never trust a parsed response's declared TypeScript type. */
|
|
113
|
+
export declare function isDecisionObject(value: unknown): value is {
|
|
114
|
+
[key: string]: unknown;
|
|
115
|
+
};
|
|
116
|
+
export declare function readDecisionUsage(raw: unknown): DecisionUsage | null;
|
|
117
|
+
export declare function isBooleanAnswer(answer: DecisionAnswer | undefined): answer is BooleanAnswer;
|
|
118
|
+
export declare function isChoiceAnswer(answer: DecisionAnswer | undefined): answer is ChoiceAnswer;
|
|
119
|
+
export declare function isScoreAnswer(answer: DecisionAnswer | undefined): answer is ScoreAnswer;
|
|
@@ -305,6 +305,7 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
|
|
|
305
305
|
/** See {@link t.StandardGraphInput.subagentExecutionContext}. */
|
|
306
306
|
readonly subagentExecutionContext?: t.SubagentExecutionContext;
|
|
307
307
|
private readonly subagentContext?;
|
|
308
|
+
private readonly onSubagentResolutionFailure?;
|
|
308
309
|
/** See {@link t.StandardGraphInput.preemption}. */
|
|
309
310
|
preemption?: t.StreamPreemption;
|
|
310
311
|
/**
|
|
@@ -441,7 +442,7 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
|
|
|
441
442
|
* from a discard.
|
|
442
443
|
*/
|
|
443
444
|
private preemptRestartPending;
|
|
444
|
-
constructor({ runId, signal, agents, langfuse, tokenCounter, indexTokenCountMap, calibrationRatio, fadingTier, fadingTiers, subagentUsageSink, subagentTasks, subagentScope, subagentExecutionContext, subagentContext, preemption, streamLimits, toolExecution, clientDelegatedToolNames, }: t.StandardGraphInput, dependencies?: GraphFactoryDependencies);
|
|
445
|
+
constructor({ runId, signal, agents, langfuse, tokenCounter, indexTokenCountMap, calibrationRatio, fadingTier, fadingTiers, subagentUsageSink, subagentTasks, subagentScope, subagentExecutionContext, subagentContext, onSubagentResolutionFailure, preemption, streamLimits, toolExecution, clientDelegatedToolNames, }: t.StandardGraphInput, dependencies?: GraphFactoryDependencies);
|
|
445
446
|
/**
|
|
446
447
|
* A compaction applies its remove-all inside the agent subgraph, so the
|
|
447
448
|
* subgraph's result carries only the retained tail, and an outer reducer
|
package/dist/types/index.d.ts
CHANGED
|
@@ -59,3 +59,5 @@ export { canSealPreempt } from './llm/preempt';
|
|
|
59
59
|
export { isThinkingEnabled, getMaxOutputTokensKey } from './llm/request';
|
|
60
60
|
export { DEFAULT_MAX_TOOL_CALL_ARG_BYTES, StreamLimitExceededError, resolveStreamLimits, } from './llm/streamLimits';
|
|
61
61
|
export type { StreamedToolCallArgTally, ResolvedStreamLimits, StreamLimitState, StreamLimitKind, } from './llm/streamLimits';
|
|
62
|
+
export * from './decisions';
|
|
63
|
+
export * from './rerank';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Logger, SearchReranker } from '@/tools/search/types';
|
|
2
|
+
import type { Reranker } from './types';
|
|
3
|
+
/** Adapts index-based rankings to web-search highlights and its existing metrics/fallback policy. */
|
|
4
|
+
export declare function createWebSearchReranker(reranker: Reranker, options?: {
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
logger?: Logger;
|
|
7
|
+
}): SearchReranker;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Reranker } from './types';
|
|
2
|
+
import type { DecisionModel } from '@/decisions';
|
|
3
|
+
export interface SystemOneRerankerOptions {
|
|
4
|
+
/** Inject a configured Jev/Laya HTTP decision model; chat cannot produce expected scores. */
|
|
5
|
+
model: DecisionModel;
|
|
6
|
+
/** Relevance levels from least to most relevant; evaluate this rubric for the checkpoint. */
|
|
7
|
+
rubric: readonly string[];
|
|
8
|
+
/** Reject oversized batches instead of silently dropping candidates. Defaults to 128. */
|
|
9
|
+
maxDocuments?: number;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}
|
|
12
|
+
/** One shared query/candidate state and one score question per candidate, in one request. */
|
|
13
|
+
export declare function createSystemOneReranker(options: SystemOneRerankerOptions): Reranker;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DecisionUsage } from '@/decisions';
|
|
2
|
+
export interface RerankRequest {
|
|
3
|
+
query: string;
|
|
4
|
+
documents: readonly string[];
|
|
5
|
+
topK?: number;
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface RankedDocument {
|
|
10
|
+
/** Index into the submitted documents, not an identity derived from text. */
|
|
11
|
+
index: number;
|
|
12
|
+
/** Provider-specific relevance score, ordered descending; not a portable threshold. */
|
|
13
|
+
score: number;
|
|
14
|
+
}
|
|
15
|
+
export interface RerankResult {
|
|
16
|
+
results: RankedDocument[];
|
|
17
|
+
model: string;
|
|
18
|
+
usage: DecisionUsage | null;
|
|
19
|
+
}
|
|
20
|
+
/** Rankings retain candidate identity; failures reject rather than fabricate scores. */
|
|
21
|
+
export interface Reranker {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
rerank(request: RerankRequest): Promise<RerankResult>;
|
|
24
|
+
}
|
package/dist/types/run.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
24
24
|
private streamLimits?;
|
|
25
25
|
private subagentTasks?;
|
|
26
26
|
private subagentContext?;
|
|
27
|
+
private onSubagentResolutionFailure?;
|
|
27
28
|
private indexTokenCountMap?;
|
|
28
29
|
calibrationRatio: number;
|
|
29
30
|
fadingTier?: t.FadingTier;
|
|
@@ -239,6 +239,8 @@ export interface ScrapeResult {
|
|
|
239
239
|
references?: References;
|
|
240
240
|
highlights?: Highlight[];
|
|
241
241
|
}
|
|
242
|
+
/** Host implementations need only the public ranking seam, not BaseReranker's private state. */
|
|
243
|
+
export type SearchReranker = Pick<BaseReranker, 'provider' | 'rerank'>;
|
|
242
244
|
export interface ProcessSourcesConfig {
|
|
243
245
|
topResults?: number;
|
|
244
246
|
/** Max chars of scraped content stored per source and passed to the
|
|
@@ -258,7 +260,7 @@ export interface ProcessSourcesConfig {
|
|
|
258
260
|
separatorExpandBy?: number;
|
|
259
261
|
strategies?: string[];
|
|
260
262
|
filterContent?: boolean;
|
|
261
|
-
reranker?:
|
|
263
|
+
reranker?: SearchReranker;
|
|
262
264
|
logger?: Logger;
|
|
263
265
|
}
|
|
264
266
|
export interface FirecrawlConfig {
|
|
@@ -98,6 +98,7 @@ export declare class SubagentSettlementBindingError extends Error {
|
|
|
98
98
|
export declare class SubagentExecutionRecord<TResult, TResolvedConfig, TActiveRun, TSettledOutput = never> {
|
|
99
99
|
readonly address: SubagentExecutionAddress;
|
|
100
100
|
private identityValue?;
|
|
101
|
+
private attemptedIdentityValue?;
|
|
101
102
|
private bindingValue?;
|
|
102
103
|
private bindingAuthority?;
|
|
103
104
|
private invocationValue?;
|
|
@@ -118,6 +119,9 @@ export declare class SubagentExecutionRecord<TResult, TResolvedConfig, TActiveRu
|
|
|
118
119
|
constructor(address: SubagentExecutionAddress, resumeExecution?: SubagentResumeExecution);
|
|
119
120
|
get snapshot(): ExecutionSnapshot<TResult, TResolvedConfig, TActiveRun>;
|
|
120
121
|
get identity(): SubagentExecutionIdentity | undefined;
|
|
122
|
+
/** Correlation only; never committed identity or resume authority. */
|
|
123
|
+
get attemptedIdentity(): SubagentExecutionIdentity | undefined;
|
|
124
|
+
recordIdentityAttempt(identity: SubagentExecutionIdentity): void;
|
|
121
125
|
get binding(): SubagentDefinitionBinding | undefined;
|
|
122
126
|
get resumeExecution(): SubagentResumeExecution | undefined;
|
|
123
127
|
get invocation(): SubagentInvocationBinding | undefined;
|
|
@@ -3,6 +3,7 @@ import type { RunnableConfig } from '@langchain/core/runnables';
|
|
|
3
3
|
import type { ToolCall } from '@langchain/core/messages/tool';
|
|
4
4
|
import type { MultiAgentGraphState, HumanInTheLoopConfig, StandardGraphInput, ExecutableSubagentConfigEntry, SubagentExecutionContext, SubagentContextAdapter, SubagentContextResult, SubagentTaskConfig, SubagentTaskRuntime, SubagentUsageSink, TokenCounter } from '@/types';
|
|
5
5
|
import type { SubagentResumeManifest, SettledSubagentToolOutput } from './SubagentReplay';
|
|
6
|
+
import type { SubagentResolutionPhase, SubagentResolutionCause, SubagentResolutionFailureHandler } from './diagnostics';
|
|
6
7
|
import type { GraphFactory } from '@/graphs/graphFactory';
|
|
7
8
|
import type { StandardGraph } from '@/graphs/Graph';
|
|
8
9
|
import { HookRegistry } from '@/hooks';
|
|
@@ -74,6 +75,11 @@ export type SubagentExecuteParams = {
|
|
|
74
75
|
export type SubagentExecuteResult = SubagentContextResult & {
|
|
75
76
|
/** Tagged internal failure; foreground callers retain the legacy content. */
|
|
76
77
|
error?: string;
|
|
78
|
+
/** Safe startup classification retained for detached host delivery. */
|
|
79
|
+
resolutionFailure?: {
|
|
80
|
+
phase: SubagentResolutionPhase;
|
|
81
|
+
cause: SubagentResolutionCause;
|
|
82
|
+
};
|
|
77
83
|
/** Completed child work whose host projection must be retried without re-execution. */
|
|
78
84
|
retryableDelivery?: true;
|
|
79
85
|
};
|
|
@@ -161,6 +167,8 @@ export type SubagentExecutorOptions = {
|
|
|
161
167
|
/** Host-owned process-local task namespace for detached execution. */
|
|
162
168
|
taskConfig?: SubagentTaskConfig;
|
|
163
169
|
subagentContext?: SubagentContextAdapter;
|
|
170
|
+
/** Host diagnostic sink and safe cause classifier for startup failures. */
|
|
171
|
+
onResolutionFailure?: SubagentResolutionFailureHandler;
|
|
164
172
|
};
|
|
165
173
|
export declare class SubagentExecutor {
|
|
166
174
|
private readonly configs;
|
|
@@ -189,6 +197,7 @@ export declare class SubagentExecutor {
|
|
|
189
197
|
private readonly usageSink?;
|
|
190
198
|
private readonly taskConfig?;
|
|
191
199
|
private readonly subagentContext?;
|
|
200
|
+
private readonly onResolutionFailure?;
|
|
192
201
|
private readonly executions;
|
|
193
202
|
private replayCheckpointWorkflow?;
|
|
194
203
|
private readonly resolveParentHandlerRegistry?;
|
|
@@ -264,9 +273,13 @@ export declare class SubagentExecutor {
|
|
|
264
273
|
clearHeavyState(): void;
|
|
265
274
|
private getResumeCheckpointMarker;
|
|
266
275
|
getSettledToolOutput(call: ToolCall, config: RunnableConfig): Promise<SettledSubagentToolOutput | undefined>;
|
|
276
|
+
private restoreSettledToolOutput;
|
|
267
277
|
persistSettledToolOutput(call: ToolCall, config: RunnableConfig, settled: SettledSubagentToolOutput): Promise<void>;
|
|
268
278
|
private persistChildCheckpointMarker;
|
|
269
279
|
execute(params: SubagentExecuteParams): Promise<SubagentExecuteResult>;
|
|
280
|
+
private getReplaySignal;
|
|
281
|
+
private createReplayResolutionError;
|
|
282
|
+
private createResolutionFailure;
|
|
270
283
|
private executeOnce;
|
|
271
284
|
private completeHostContext;
|
|
272
285
|
/**
|
|
@@ -4,17 +4,41 @@ import { describeCodeApiError } from '@/tools/diagnostics';
|
|
|
4
4
|
export type SubagentResolutionPhase = 'identity' | 'config';
|
|
5
5
|
declare const SUBAGENT_ERROR_TYPES: readonly [readonly ["SubagentExecutionInvalidatedError", typeof SubagentExecutionInvalidatedError], readonly ["SubagentDefinitionBindingError", typeof SubagentDefinitionBindingError], readonly ["SubagentInvocationBindingError", typeof SubagentInvocationBindingError], readonly ["SubagentSettlementBindingError", typeof SubagentSettlementBindingError]];
|
|
6
6
|
type SubagentErrorLabel = (typeof SUBAGENT_ERROR_TYPES)[number][0] | ReturnType<typeof describeCodeApiError>['type'];
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
declare const SUBAGENT_RESOLUTION_MESSAGES: {
|
|
8
|
+
readonly workspace_unavailable: "Subagent error: Workspace unavailable. Retry later or choose another workspace.";
|
|
9
|
+
readonly agent_unavailable: "Subagent error: Agent not found or not accessible.";
|
|
10
|
+
readonly model_unavailable: "Subagent error: Model or provider unavailable.";
|
|
11
|
+
readonly configuration_changed: "Subagent error: Subagent configuration changed. Start a new execution.";
|
|
12
|
+
readonly unknown: "Subagent error: Unable to initialize the selected subagent.";
|
|
13
|
+
};
|
|
14
|
+
/** Host classifications accepted at the public failure boundary. */
|
|
15
|
+
export type SubagentResolutionCause = keyof typeof SUBAGENT_RESOLUTION_MESSAGES;
|
|
16
|
+
export type SubagentResolutionContext = {
|
|
17
|
+
parentRunId: string;
|
|
18
|
+
parentAgentId?: string;
|
|
19
|
+
parentToolCallId?: string;
|
|
20
|
+
threadId?: string;
|
|
21
|
+
childRunId: string;
|
|
22
|
+
childThreadId: string;
|
|
23
|
+
taskId?: string;
|
|
24
|
+
};
|
|
25
|
+
/** No received error text, writable error names, or stacks enter this payload. */
|
|
13
26
|
export type SubagentResolutionDiagnostic = {
|
|
14
27
|
phase: SubagentResolutionPhase;
|
|
15
28
|
subagentType: string;
|
|
16
29
|
aborted: boolean;
|
|
17
30
|
type: SubagentErrorLabel;
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
cause: SubagentResolutionCause;
|
|
32
|
+
message: (typeof SUBAGENT_RESOLUTION_MESSAGES)[SubagentResolutionCause];
|
|
33
|
+
} & Partial<SubagentResolutionContext>;
|
|
34
|
+
/** The original error is private. Return a classification, never error text. */
|
|
35
|
+
export type SubagentResolutionFailureHandler = (detail: Readonly<SubagentResolutionDiagnostic>, error: unknown) => SubagentResolutionCause | void;
|
|
36
|
+
export declare function getSubagentResolutionFailureMessage(cause: SubagentResolutionCause): SubagentResolutionDiagnostic['message'];
|
|
37
|
+
/** Safe typed failure retained when detached execution crosses the host boundary. */
|
|
38
|
+
export declare class SubagentResolutionError extends Error {
|
|
39
|
+
readonly phase: SubagentResolutionPhase;
|
|
40
|
+
readonly resolutionCause: SubagentResolutionCause;
|
|
41
|
+
constructor(phase: SubagentResolutionPhase, cause: SubagentResolutionCause);
|
|
42
|
+
}
|
|
43
|
+
export declare function logSubagentResolutionFailure(phase: SubagentResolutionPhase, subagentType: string, signal: AbortSignal, error: unknown, context?: SubagentResolutionContext, onResolutionFailure?: SubagentResolutionFailureHandler): SubagentResolutionDiagnostic;
|
|
20
44
|
export {};
|
|
@@ -2,3 +2,5 @@ export { DEFAULT_SUBAGENT_DESCRIPTION, SubagentExecutor, filterSubagentResult, f
|
|
|
2
2
|
export type { SubagentExecuteParams, SubagentExecuteResult, SubagentExecutorOptions, ChildGraphFactory, } from './SubagentExecutor';
|
|
3
3
|
export { InMemorySubagentTaskStore } from './InMemorySubagentTaskStore';
|
|
4
4
|
export type { InMemorySubagentTaskStoreOptions } from './InMemorySubagentTaskStore';
|
|
5
|
+
export { SubagentResolutionError, getSubagentResolutionFailureMessage, } from './diagnostics';
|
|
6
|
+
export type { SubagentResolutionPhase, SubagentResolutionCause, SubagentResolutionContext, SubagentResolutionDiagnostic, SubagentResolutionFailureHandler, } from './diagnostics';
|
|
@@ -8,6 +8,7 @@ import type { RunStep, ModelResponseEvent, ModelToolsClaimedEvent, RunStepDeltaE
|
|
|
8
8
|
import type { SummarizationNodeInput, SummarizeCompleteEvent, CompactionSemanticIndex, SummarizationConfig, SummarizeStartEvent, SummarizeDeltaEvent } from '@/types/summarize';
|
|
9
9
|
import type { ToolMap, ToolSessionMap, ToolEndEvent, GenericTool, LCTool, ToolExecutionConfig, ToolExecuteBatchRequest } from '@/types/tools';
|
|
10
10
|
import type { TokenCounter, StreamLimits, StreamPreemption, TokenBudgetBreakdown } from '@/types/run';
|
|
11
|
+
import type { SubagentResolutionFailureHandler } from '@/tools/subagent/diagnostics';
|
|
11
12
|
import type { SubagentTaskConfig } from '@/types/subagentTasks';
|
|
12
13
|
import type { StandardGraph, MultiAgentGraph } from '@/graphs';
|
|
13
14
|
import type { ProviderClientOptionsConfig } from '@/types/llm';
|
|
@@ -320,6 +321,8 @@ export type StandardGraphInput = {
|
|
|
320
321
|
subagentTasks?: SubagentTaskConfig;
|
|
321
322
|
/** Host-owned context and result projection for each isolated child execution. */
|
|
322
323
|
subagentContext?: SubagentContextAdapter;
|
|
324
|
+
/** Receives private startup errors; returns only an SDK-owned public cause. */
|
|
325
|
+
onSubagentResolutionFailure?: SubagentResolutionFailureHandler;
|
|
323
326
|
/**
|
|
324
327
|
* True when this graph IS a subagent child run (set by `SubagentExecutor`
|
|
325
328
|
* when it constructs the child graph). Drives the hook-input `agentId`
|
|
@@ -281,6 +281,8 @@ export type RunConfig = {
|
|
|
281
281
|
subagentTasks?: SubagentTaskConfig;
|
|
282
282
|
/** Authorizes and supplies host-owned context to isolated child runs. */
|
|
283
283
|
subagentContext?: g.SubagentContextAdapter;
|
|
284
|
+
/** Host diagnostic sink for foreground, detached, and nested startup failures. */
|
|
285
|
+
onSubagentResolutionFailure?: g.StandardGraphInput['onSubagentResolutionFailure'];
|
|
284
286
|
/**
|
|
285
287
|
* Pre-constructed hook registry for this run. Hooks fire at lifecycle
|
|
286
288
|
* points in `processStream` (RunStart, UserPromptSubmit, Stop,
|
package/package.json
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { DecisionError } from './types';
|
|
2
|
+
|
|
3
|
+
export type AwaitWithinDeadline = <T>(task: Promise<T>) => Promise<T>;
|
|
4
|
+
|
|
5
|
+
/** Bounds even non-cooperative credential minters, fetches, body reads, and model calls. */
|
|
6
|
+
export async function withDecisionDeadline<T>(
|
|
7
|
+
provider: string,
|
|
8
|
+
timeoutMs: number,
|
|
9
|
+
callerSignal: AbortSignal | undefined,
|
|
10
|
+
operation: (signal: AbortSignal, waitFor: AwaitWithinDeadline) => Promise<T>
|
|
11
|
+
): Promise<T> {
|
|
12
|
+
if (
|
|
13
|
+
!Number.isSafeInteger(timeoutMs) ||
|
|
14
|
+
timeoutMs <= 0 ||
|
|
15
|
+
timeoutMs > 3_600_000
|
|
16
|
+
) {
|
|
17
|
+
throw new DecisionError('bad_request', 'invalid decision model timeout', {
|
|
18
|
+
provider,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
if (callerSignal?.aborted === true) {
|
|
22
|
+
throw new DecisionError('aborted', 'caller aborted the request', {
|
|
23
|
+
provider,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const expiresAt = performance.now() + timeoutMs;
|
|
28
|
+
const deadline = new AbortController();
|
|
29
|
+
const signal = callerSignal
|
|
30
|
+
? AbortSignal.any([callerSignal, deadline.signal])
|
|
31
|
+
: deadline.signal;
|
|
32
|
+
const timer = setTimeout(() => deadline.abort(), timeoutMs);
|
|
33
|
+
const expired = (): boolean => {
|
|
34
|
+
if (performance.now() >= expiresAt) {
|
|
35
|
+
deadline.abort();
|
|
36
|
+
}
|
|
37
|
+
return signal.aborted;
|
|
38
|
+
};
|
|
39
|
+
const abortError = (): DecisionError => {
|
|
40
|
+
if (callerSignal?.aborted === true) {
|
|
41
|
+
return new DecisionError('aborted', 'caller aborted the request', {
|
|
42
|
+
provider,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return new DecisionError('timeout', 'decision model deadline exceeded', {
|
|
46
|
+
provider,
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const waitFor: AwaitWithinDeadline = <U>(task: Promise<U>): Promise<U> =>
|
|
51
|
+
new Promise<U>((resolve, reject) => {
|
|
52
|
+
if (expired()) {
|
|
53
|
+
void task.catch(() => {});
|
|
54
|
+
reject(abortError());
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const onAbort = (): void => {
|
|
58
|
+
signal.removeEventListener('abort', onAbort);
|
|
59
|
+
reject(abortError());
|
|
60
|
+
};
|
|
61
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
62
|
+
if (expired()) {
|
|
63
|
+
onAbort();
|
|
64
|
+
}
|
|
65
|
+
task.then(
|
|
66
|
+
(value) => {
|
|
67
|
+
signal.removeEventListener('abort', onAbort);
|
|
68
|
+
if (expired()) {
|
|
69
|
+
reject(abortError());
|
|
70
|
+
} else {
|
|
71
|
+
resolve(value);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
(error: unknown) => {
|
|
75
|
+
signal.removeEventListener('abort', onAbort);
|
|
76
|
+
reject(expired() ? abortError() : error);
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
return await waitFor(operation(signal, waitFor));
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (expired()) {
|
|
85
|
+
throw abortError();
|
|
86
|
+
}
|
|
87
|
+
throw error;
|
|
88
|
+
} finally {
|
|
89
|
+
expired();
|
|
90
|
+
clearTimeout(timer);
|
|
91
|
+
}
|
|
92
|
+
}
|