@linnlabs/linnkit 0.8.0
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/CHANGELOG.md +84 -0
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/README.zh-CN.md +182 -0
- package/dist/agent-invocation-BHcNfrBV.d.cts +30 -0
- package/dist/agent-invocation-BznDaXDs.d.ts +30 -0
- package/dist/agentEvents-DEB7Fy_J.d.cts +81 -0
- package/dist/agentEvents-DEB7Fy_J.d.ts +81 -0
- package/dist/agentSpec-EkmviZjy.d.cts +2621 -0
- package/dist/agentSpec-EkmviZjy.d.ts +2621 -0
- package/dist/ai-engine.types-BpeU_XQG.d.cts +158 -0
- package/dist/ai-engine.types-vZRnQcJa.d.ts +158 -0
- package/dist/audit-BaRUGaqv.d.cts +307 -0
- package/dist/audit-BaRUGaqv.d.ts +307 -0
- package/dist/audit-CtcfART1.d.ts +33 -0
- package/dist/audit-LeOrm2hX.d.cts +33 -0
- package/dist/checkpointMarker-DAI3wUQu.d.cts +8 -0
- package/dist/checkpointMarker-DAI3wUQu.d.ts +8 -0
- package/dist/cli.cjs +8028 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +4 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +8025 -0
- package/dist/cli.js.map +1 -0
- package/dist/context-manager.cjs +8704 -0
- package/dist/context-manager.cjs.map +1 -0
- package/dist/context-manager.d.cts +2190 -0
- package/dist/context-manager.d.ts +2190 -0
- package/dist/context-manager.js +8650 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/context-trace-DRi5M4lX.d.ts +239 -0
- package/dist/context-trace-HE2qY5Q-.d.cts +239 -0
- package/dist/contracts.cjs +1333 -0
- package/dist/contracts.cjs.map +1 -0
- package/dist/contracts.d.cts +8 -0
- package/dist/contracts.d.ts +8 -0
- package/dist/contracts.js +1214 -0
- package/dist/contracts.js.map +1 -0
- package/dist/defaultGraphExecutor-BBswR8wn.d.ts +624 -0
- package/dist/defaultGraphExecutor-BIjJj7WF.d.cts +624 -0
- package/dist/execution-CAIypb41.d.cts +129 -0
- package/dist/execution-CAIypb41.d.ts +129 -0
- package/dist/index-CHqwkvGp.d.ts +149 -0
- package/dist/index-CJeWHopy.d.ts +584 -0
- package/dist/index-Cm-JbzTH.d.cts +1450 -0
- package/dist/index-Cvr23YCl.d.cts +23 -0
- package/dist/index-DDzuSb0n.d.ts +23 -0
- package/dist/index-DO4dQgf2.d.cts +584 -0
- package/dist/index-DRBWi1fy.d.ts +1450 -0
- package/dist/index-Dl5PLgAv.d.cts +149 -0
- package/dist/index.cjs +9577 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +89 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.js +9563 -0
- package/dist/index.js.map +1 -0
- package/dist/messages-XthmnHZ3.d.cts +8007 -0
- package/dist/messages-XthmnHZ3.d.ts +8007 -0
- package/dist/ports-DaatKJXp.d.cts +90 -0
- package/dist/ports-DnLuKfpE.d.ts +90 -0
- package/dist/ports.cjs +4 -0
- package/dist/ports.cjs.map +1 -0
- package/dist/ports.d.cts +7 -0
- package/dist/ports.d.ts +7 -0
- package/dist/ports.js +3 -0
- package/dist/ports.js.map +1 -0
- package/dist/quickstart.cjs +7697 -0
- package/dist/quickstart.cjs.map +1 -0
- package/dist/quickstart.d.cts +24 -0
- package/dist/quickstart.d.ts +24 -0
- package/dist/quickstart.js +7691 -0
- package/dist/quickstart.js.map +1 -0
- package/dist/runAgent-CPj_9e58.d.ts +88 -0
- package/dist/runAgent-HYKlXbVr.d.cts +88 -0
- package/dist/runHandle-CyXvzgzk.d.ts +239 -0
- package/dist/runHandle-D3gPsD7B.d.cts +239 -0
- package/dist/runtime-kernel/events.cjs +1485 -0
- package/dist/runtime-kernel/events.cjs.map +1 -0
- package/dist/runtime-kernel/events.d.cts +8 -0
- package/dist/runtime-kernel/events.d.ts +8 -0
- package/dist/runtime-kernel/events.js +1475 -0
- package/dist/runtime-kernel/events.js.map +1 -0
- package/dist/runtime-kernel.cjs +8656 -0
- package/dist/runtime-kernel.cjs.map +1 -0
- package/dist/runtime-kernel.d.cts +19 -0
- package/dist/runtime-kernel.d.ts +19 -0
- package/dist/runtime-kernel.js +8568 -0
- package/dist/runtime-kernel.js.map +1 -0
- package/dist/sse-vPyrOPa0.d.cts +1687 -0
- package/dist/sse-vPyrOPa0.d.ts +1687 -0
- package/dist/testkit.cjs +10613 -0
- package/dist/testkit.cjs.map +1 -0
- package/dist/testkit.d.cts +284 -0
- package/dist/testkit.d.ts +284 -0
- package/dist/testkit.js +10593 -0
- package/dist/testkit.js.map +1 -0
- package/dist/todo-B1PmDlp3.d.cts +2253 -0
- package/dist/todo-B1PmDlp3.d.ts +2253 -0
- package/dist/tokenizer-DFL4I7-I.d.ts +28 -0
- package/dist/tokenizer-DH_JXv-H.d.cts +28 -0
- package/dist/toolContracts-Blll0241.d.ts +463 -0
- package/dist/toolContracts-CLkQmhTG.d.cts +463 -0
- package/docs/README.md +76 -0
- package/docs/integration/01-installation.md +94 -0
- package/docs/integration/02-quickstart.md +104 -0
- package/docs/integration/README.md +223 -0
- package/docs/integration/agent-registration-guide.md +330 -0
- package/docs/integration/audit.md +64 -0
- package/docs/integration/child-runs.md +87 -0
- package/docs/integration/constraints-and-pitfalls.md +87 -0
- package/docs/integration/context-engineering.md +650 -0
- package/docs/integration/context-fences.md +289 -0
- package/docs/integration/glossary.md +69 -0
- package/docs/integration/llm-provider.md +76 -0
- package/docs/integration/persistence.md +44 -0
- package/docs/integration/realtime.md +76 -0
- package/docs/integration/run-supervisor.md +69 -0
- package/docs/integration/telemetry.md +48 -0
- package/docs/integration/testing.md +95 -0
- package/docs/integration/tool-development-guide.md +362 -0
- package/docs/integration/tool-history.md +202 -0
- package/docs/integration/tools.md +188 -0
- package/package.json +115 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
import { a as EventStore, P as PersistedEvent, E as EventRangeOptions, m as RunRegistryStore, l as RunRecord, L as ListRunsFilter, n as RunRequestSnapshot, b as EventBus, f as RunCostCollector, h as RunHandle, k as RunObserveFilter, C as CancelOpts, R as RunAwaitingUserPatch, j as RunMeta } from './runHandle-D3gPsD7B.cjs';
|
|
2
|
+
import { p as AgentSpecSystemReminderPolicy, t as AgentSpecToolObservationGovernancePolicy, a as AgentSpec } from './agentSpec-EkmviZjy.cjs';
|
|
3
|
+
import { e as RuntimeEvent } from './todo-B1PmDlp3.cjs';
|
|
4
|
+
import { A as AgentAiEngine, b as AuditPort } from './audit-LeOrm2hX.cjs';
|
|
5
|
+
import { A as AgentInvocationRequest } from './agent-invocation-BHcNfrBV.cjs';
|
|
6
|
+
import { A as AnyAgentEvent } from './agentEvents-DEB7Fy_J.cjs';
|
|
7
|
+
import { T as ToolCall, c as LlmRetryConfig, a as LlmRequestMessage, L as LlmCallOptions, e as ToolCallExtraContent } from './ai-engine.types-BpeU_XQG.cjs';
|
|
8
|
+
import { T as ToolExecutionContext } from './toolContracts-CLkQmhTG.cjs';
|
|
9
|
+
import { h as ToolRuntimePort, O as ObservationPreviewPort } from './ports-DaatKJXp.cjs';
|
|
10
|
+
|
|
11
|
+
type NormalizedLlmUsage = {
|
|
12
|
+
promptTokens: number;
|
|
13
|
+
completionTokens: number;
|
|
14
|
+
totalTokens: number;
|
|
15
|
+
};
|
|
16
|
+
type LLMTelemetryContext = {
|
|
17
|
+
/**
|
|
18
|
+
* 预留:用于业务侧注入“聚合维度”。
|
|
19
|
+
*
|
|
20
|
+
* 中文备注:
|
|
21
|
+
* - 该字段不进入模型上下文、不落库,仅用于本地统计/审计聚合;
|
|
22
|
+
* - 建议只放稳定标识(如 conversationId/turnId/runId 等),避免塞入大对象。
|
|
23
|
+
*/
|
|
24
|
+
scope?: {
|
|
25
|
+
conversationId?: string;
|
|
26
|
+
turnId?: string;
|
|
27
|
+
runId?: string;
|
|
28
|
+
stepId?: string;
|
|
29
|
+
stepIndex?: number;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
type LlmCallTelemetry = {
|
|
33
|
+
modelId: string;
|
|
34
|
+
stream: boolean;
|
|
35
|
+
startedAt: number;
|
|
36
|
+
durationMs: number;
|
|
37
|
+
usage?: NormalizedLlmUsage;
|
|
38
|
+
};
|
|
39
|
+
declare function withLLMTelemetryContext<T>(ctx: LLMTelemetryContext, fn: () => Promise<T>): Promise<{
|
|
40
|
+
value: T;
|
|
41
|
+
calls: LlmCallTelemetry[];
|
|
42
|
+
}>;
|
|
43
|
+
|
|
44
|
+
declare const TELEMETRY_EVENT_KINDS: readonly ["llm_call", "tool_call", "graph_node", "run_lifecycle"];
|
|
45
|
+
type TelemetryEventKind = (typeof TELEMETRY_EVENT_KINDS)[number];
|
|
46
|
+
|
|
47
|
+
type TelemetryScope = {
|
|
48
|
+
conversationId?: string;
|
|
49
|
+
runId?: string;
|
|
50
|
+
parentRunId?: string;
|
|
51
|
+
turnId?: string;
|
|
52
|
+
stepId?: string;
|
|
53
|
+
};
|
|
54
|
+
type TelemetryEvent = {
|
|
55
|
+
kind: Extract<TelemetryEventKind, 'llm_call'>;
|
|
56
|
+
modelId: string;
|
|
57
|
+
stream: boolean;
|
|
58
|
+
durationMs: number;
|
|
59
|
+
usage?: NormalizedLlmUsage;
|
|
60
|
+
scope: TelemetryScope;
|
|
61
|
+
} | {
|
|
62
|
+
kind: Extract<TelemetryEventKind, 'tool_call'>;
|
|
63
|
+
toolName: string;
|
|
64
|
+
durationMs: number;
|
|
65
|
+
ok: boolean;
|
|
66
|
+
errorCode?: string;
|
|
67
|
+
scope: TelemetryScope;
|
|
68
|
+
} | {
|
|
69
|
+
kind: Extract<TelemetryEventKind, 'graph_node'>;
|
|
70
|
+
nodeId: string;
|
|
71
|
+
durationMs: number;
|
|
72
|
+
scope: TelemetryScope;
|
|
73
|
+
} | {
|
|
74
|
+
kind: Extract<TelemetryEventKind, 'run_lifecycle'>;
|
|
75
|
+
runId: string;
|
|
76
|
+
phase: 'spawned' | 'completed' | 'failed' | 'cancelled';
|
|
77
|
+
scope: TelemetryScope;
|
|
78
|
+
};
|
|
79
|
+
interface TelemetryPort {
|
|
80
|
+
emit(event: TelemetryEvent): void;
|
|
81
|
+
flush?(): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* ToolContext patch 的最小合同
|
|
86
|
+
*
|
|
87
|
+
* 中文备注:
|
|
88
|
+
* - 这里表达的是“宿主/产品层希望追加到 ToolContext 上的增量字段”;
|
|
89
|
+
* - 它不是完整 ToolContext,也不承诺 runtime-owned capability;
|
|
90
|
+
* - 迁移期仍允许任意键,但调用方必须接受 runtime reserved keys 会被过滤。
|
|
91
|
+
*/
|
|
92
|
+
type ToolContextPatch = Record<string, unknown>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @file src/agent/runtime-kernel/llm/policies/types.ts
|
|
96
|
+
*
|
|
97
|
+
* @description
|
|
98
|
+
* LLM Policy 是对“供应商/模型组合差异”的封装。
|
|
99
|
+
* 主链路只调用 PolicyEngine,不再内联 provider-specific 逻辑。
|
|
100
|
+
*/
|
|
101
|
+
type LLMPolicyMatchContext = {
|
|
102
|
+
/** 逻辑模型 ID(如 google/gemini-3-pro-preview) */
|
|
103
|
+
modelId?: string;
|
|
104
|
+
/** 供应商/网关的 base url(如 https://openrouter.ai/api/v1) */
|
|
105
|
+
apiBase?: string;
|
|
106
|
+
/** 实际请求体中的 model 字段(如 google/gemini-3-pro-preview) */
|
|
107
|
+
requestModelName?: string;
|
|
108
|
+
};
|
|
109
|
+
type LLMPolicyRequestContext = LLMPolicyMatchContext & {
|
|
110
|
+
endpoint: string;
|
|
111
|
+
requestData: unknown;
|
|
112
|
+
headers?: Record<string, string>;
|
|
113
|
+
};
|
|
114
|
+
type LLMPolicyResponseContext = LLMPolicyMatchContext & {
|
|
115
|
+
endpoint: string;
|
|
116
|
+
responseData: unknown;
|
|
117
|
+
};
|
|
118
|
+
type LLMPolicyErrorDecision = {
|
|
119
|
+
action: 'none';
|
|
120
|
+
} | {
|
|
121
|
+
action: 'retry';
|
|
122
|
+
delayMs?: number;
|
|
123
|
+
} | {
|
|
124
|
+
action: 'switch_model';
|
|
125
|
+
reason: string;
|
|
126
|
+
};
|
|
127
|
+
interface LLMPolicy {
|
|
128
|
+
/** 名称仅用于日志/调试 */
|
|
129
|
+
name: string;
|
|
130
|
+
/** 是否匹配当前请求上下文 */
|
|
131
|
+
match(ctx: LLMPolicyMatchContext): boolean;
|
|
132
|
+
/** 发送前:可修改 requestData / headers(必须保持幂等) */
|
|
133
|
+
beforeRequest?(ctx: LLMPolicyRequestContext): {
|
|
134
|
+
requestData?: unknown;
|
|
135
|
+
headers?: Record<string, string>;
|
|
136
|
+
};
|
|
137
|
+
/** 收到后(非流式):可修改 responseData(必须保持幂等) */
|
|
138
|
+
afterResponse?(ctx: LLMPolicyResponseContext): {
|
|
139
|
+
responseData?: unknown;
|
|
140
|
+
};
|
|
141
|
+
/** 错误处理:给主链路一个“是否需要切模型/重试”的建议 */
|
|
142
|
+
onError?(error: Error, ctx: LLMPolicyMatchContext): LLMPolicyErrorDecision;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @file src/agent/runtime-kernel/llm/modelCatalog.ts
|
|
147
|
+
*
|
|
148
|
+
* @description
|
|
149
|
+
* Agent runtime 对“模型目录”的最小协议定义。
|
|
150
|
+
* runtime-kernel 只依赖这些查询能力,不直接依赖 app 的 model-registry 实现。
|
|
151
|
+
*/
|
|
152
|
+
interface ModelCatalogEntry {
|
|
153
|
+
id: string;
|
|
154
|
+
enabled?: boolean;
|
|
155
|
+
api_key?: string;
|
|
156
|
+
api_base?: string;
|
|
157
|
+
billing_mode?: 'byok' | 'cloud';
|
|
158
|
+
/**
|
|
159
|
+
* 是否允许客户端侧重试。
|
|
160
|
+
*
|
|
161
|
+
* 说明:
|
|
162
|
+
* - runtime-kernel 会基于该字段与 billing_mode 决定重试策略;
|
|
163
|
+
* - 该字段来自上层 model-registry(对齐 `src/model-registry/contracts.ts`),避免在 runtime 侧出现类型漂移。
|
|
164
|
+
*/
|
|
165
|
+
enable_client_retry?: boolean;
|
|
166
|
+
model_name?: string;
|
|
167
|
+
provider?: string;
|
|
168
|
+
capabilities?: readonly string[];
|
|
169
|
+
ui_visibility?: readonly string[];
|
|
170
|
+
}
|
|
171
|
+
interface ModelCatalogLike {
|
|
172
|
+
getModelById(id: string): ModelCatalogEntry | undefined;
|
|
173
|
+
getModelsByCapability(capability: string): ModelCatalogEntry[];
|
|
174
|
+
getModelsByUIVisibility(visibility: string): ModelCatalogEntry[];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
interface ModelResolverOptions {
|
|
178
|
+
fallbackModelPreferredOrder?: readonly string[];
|
|
179
|
+
modelCatalog?: ModelCatalogLike;
|
|
180
|
+
}
|
|
181
|
+
interface ModelResolverLike {
|
|
182
|
+
resolveModelId(requestedModelId?: string): string;
|
|
183
|
+
pickFallbackChatModel(excludedModelIds: Set<string>): string | null;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* 模型解析职责单独收口,避免 caller / executor stage 混入 registry 选模细节。
|
|
187
|
+
*/
|
|
188
|
+
declare class ModelResolver implements ModelResolverLike {
|
|
189
|
+
private readonly fallbackModelPreferredOrder;
|
|
190
|
+
private readonly modelCatalog;
|
|
191
|
+
constructor(options?: ModelResolverOptions);
|
|
192
|
+
resolveModelId(requestedModelId?: string): string;
|
|
193
|
+
/**
|
|
194
|
+
* 选模规则(严格、可解释):
|
|
195
|
+
* - “默认聊天模型”应来自主对话下拉(ui_visibility: 'chat'),而不是“任何具备 chat capability 的模型”。
|
|
196
|
+
*
|
|
197
|
+
* 根因说明:
|
|
198
|
+
* - default_models.json 中存在 mock-chat(capabilities: ['chat'],但 ui_visibility 是 'chat1');
|
|
199
|
+
* - 若按 capability='chat' 取第一个,会导致内部流程(如 deep_search 子 Agent)默认落到 mock 模型,
|
|
200
|
+
* 从而无法产生 tool_calls / final_answer(只会 yield thought)。
|
|
201
|
+
*/
|
|
202
|
+
private getDefaultChatModel;
|
|
203
|
+
/**
|
|
204
|
+
* 选择一个可用的“策略切模备用聊天模型”:
|
|
205
|
+
* - 必须具备 chat 能力
|
|
206
|
+
* - 必须已解析到 api_key(否则必然失败)
|
|
207
|
+
* - 尽量避开 openrouter(减少被路由到受限上游的概率)
|
|
208
|
+
*/
|
|
209
|
+
pickFallbackChatModel(excludedModelIds: Set<string>): string | null;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
interface LlmCallerOptions {
|
|
213
|
+
maxRetries?: number;
|
|
214
|
+
enableEmptyResponseRetry?: boolean;
|
|
215
|
+
retryDelayMs?: number;
|
|
216
|
+
fallbackModelPreferredOrder?: readonly string[];
|
|
217
|
+
modelResolver?: ModelResolverLike;
|
|
218
|
+
modelCatalog?: ModelCatalogLike;
|
|
219
|
+
policyEngine?: {
|
|
220
|
+
decideOnError(error: Error, ctx: LLMPolicyMatchContext): LLMPolicyErrorDecision;
|
|
221
|
+
};
|
|
222
|
+
aiEngine: AgentAiEngine;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
type LlmCallResult = string | {
|
|
226
|
+
content: string;
|
|
227
|
+
tool_calls?: ToolCall[];
|
|
228
|
+
reasoning_details?: unknown[];
|
|
229
|
+
usage?: unknown;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @file src/agent/runtime-kernel/llm/caller.ts
|
|
234
|
+
*
|
|
235
|
+
* @brief LLM 调用器 - 统一管理 LLM 调用、流式适配与重试编排
|
|
236
|
+
*
|
|
237
|
+
* @description
|
|
238
|
+
* 这个文件只保留 orchestrator 职责:
|
|
239
|
+
* - 构造依赖;
|
|
240
|
+
* - 暴露 call / callStream / callWithRetries 公共方法;
|
|
241
|
+
* - 把具体实现委托给 request-builder / streaming-adapter / retry-fallback 等模块。
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* LLM 调用器。
|
|
246
|
+
*
|
|
247
|
+
* 中文备注:
|
|
248
|
+
* - 具体策略实现拆到同目录小模块,避免 caller.ts 再次膨胀;
|
|
249
|
+
* - public method 签名保持原样,保护现有 host / testkit 调用方。
|
|
250
|
+
*/
|
|
251
|
+
declare class LlmCaller {
|
|
252
|
+
private readonly deps;
|
|
253
|
+
private readonly modelResolver;
|
|
254
|
+
constructor(options?: Partial<LlmRetryConfig> | LlmCallerOptions);
|
|
255
|
+
/**
|
|
256
|
+
* 非流式 LLM 调用。
|
|
257
|
+
*/
|
|
258
|
+
call(modelId: string, messages: LlmRequestMessage[], options?: LlmCallOptions, signal?: AbortSignal): Promise<LlmCallResult>;
|
|
259
|
+
/**
|
|
260
|
+
* 流式 LLM 调用。
|
|
261
|
+
*/
|
|
262
|
+
callStream(modelId: string, messages: LlmRequestMessage[], options: LlmCallOptions | undefined, eventHandler: (event: AnyAgentEvent) => void, signal?: AbortSignal): Promise<LlmCallResult>;
|
|
263
|
+
/**
|
|
264
|
+
* 带智能重试和模型降级的 LLM 调用。
|
|
265
|
+
*/
|
|
266
|
+
callWithRetries(modelId: string, messages: LlmRequestMessage[], options?: LlmCallOptions, eventHandler?: (event: AnyAgentEvent) => void, signal?: AbortSignal, onCloudQuotaFallbackApplied?: (fallbackModelId: string) => void, onModelFallbackApplied?: (info: {
|
|
267
|
+
fromModelId: string;
|
|
268
|
+
toModelId: string;
|
|
269
|
+
reason: string;
|
|
270
|
+
policy: 'policy-switch' | 'cloud-quota';
|
|
271
|
+
}) => void): Promise<LlmCallResult>;
|
|
272
|
+
/**
|
|
273
|
+
* 获取或使用默认模型 ID。
|
|
274
|
+
*/
|
|
275
|
+
resolveModelId(requestedModelId?: string): string;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
interface ExecutorLocalState {
|
|
279
|
+
stepCount: number;
|
|
280
|
+
phase?: 'running' | 'force_final_answer' | 'force_tools' | string;
|
|
281
|
+
maxSteps?: number;
|
|
282
|
+
remainingSteps?: number;
|
|
283
|
+
finalStepPolicy?: 'final_answer' | 'force_tools';
|
|
284
|
+
finalStepForcedTools?: string[];
|
|
285
|
+
lastStepsHintThreshold?: number;
|
|
286
|
+
systemReminderPolicy?: AgentSpecSystemReminderPolicy;
|
|
287
|
+
toolObservationPolicy?: AgentSpecToolObservationGovernancePolicy;
|
|
288
|
+
contextCheckpointToolName?: string;
|
|
289
|
+
runLockedModelId?: string;
|
|
290
|
+
}
|
|
291
|
+
interface EngineLocalState extends Record<string, unknown> {
|
|
292
|
+
conversationId?: string;
|
|
293
|
+
turnId?: string;
|
|
294
|
+
request?: Record<string, unknown>;
|
|
295
|
+
toolContext?: ToolExecutionContext;
|
|
296
|
+
history?: RuntimeEvent[];
|
|
297
|
+
newEvents?: RuntimeEvent[];
|
|
298
|
+
executorLocal?: ExecutorLocalState;
|
|
299
|
+
pendingToolCalls?: StandardToolCall[];
|
|
300
|
+
pendingInteractionSpec?: Record<string, unknown>;
|
|
301
|
+
lastToolResult?: Record<string, unknown>;
|
|
302
|
+
finalAnswer?: string;
|
|
303
|
+
answerId?: string;
|
|
304
|
+
chunkSeq?: number;
|
|
305
|
+
signal?: AbortSignal;
|
|
306
|
+
sseSink?: (evt: unknown) => RuntimeEvent[] | void;
|
|
307
|
+
summarizationCallbacks?: {
|
|
308
|
+
onSummarizationStart?: () => void;
|
|
309
|
+
onSummarizationEnd?: (summaryInfo: unknown) => void;
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
declare const ENGINE_STATE_SCHEMA_VERSION = 1;
|
|
313
|
+
interface EngineState {
|
|
314
|
+
nodeId: string;
|
|
315
|
+
/**
|
|
316
|
+
* 顶层 schema version,供持久化后端在不解读 local 结构时也能快速判断版本。
|
|
317
|
+
*
|
|
318
|
+
* 当前 save 路径会统一写入该字段;类型先保持向后兼容,直到旧测试/fixture 全部收敛。
|
|
319
|
+
*/
|
|
320
|
+
schemaVersion?: number;
|
|
321
|
+
local?: EngineLocalState;
|
|
322
|
+
}
|
|
323
|
+
interface NodeResult {
|
|
324
|
+
kind: 'route' | 'yield' | 'pause';
|
|
325
|
+
nextNodeId?: string;
|
|
326
|
+
events?: RuntimeEvent[];
|
|
327
|
+
}
|
|
328
|
+
interface GraphNode {
|
|
329
|
+
id: string;
|
|
330
|
+
run(state: EngineState): Promise<NodeResult>;
|
|
331
|
+
}
|
|
332
|
+
interface StandardToolCall {
|
|
333
|
+
id: string;
|
|
334
|
+
type: 'function';
|
|
335
|
+
function: {
|
|
336
|
+
name: string;
|
|
337
|
+
arguments: string;
|
|
338
|
+
};
|
|
339
|
+
extra_content?: ToolCallExtraContent;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* @file checkpointer/base.ts
|
|
344
|
+
* @description Engine-state Checkpointer 接口定义。
|
|
345
|
+
*
|
|
346
|
+
* ## 术语:这里说的 "Checkpointer" 是哪个 checkpoint?
|
|
347
|
+
*
|
|
348
|
+
* 在 agent 生态里,"checkpoint" 是个被严重重载的词。这个接口指的是
|
|
349
|
+
* **graph engine 的执行状态快照**——也就是 `EngineState`:
|
|
350
|
+
*
|
|
351
|
+
* - `nodeId`: 图执行当前停在哪个节点
|
|
352
|
+
* - `pendingToolCalls`: 已发出还未回收的 tool call
|
|
353
|
+
* - `executorLocal.stepCount`: 循环步数计数
|
|
354
|
+
* - `local`: 节点间共享的中间字典(含 history、checkpointCount 等)
|
|
355
|
+
*
|
|
356
|
+
* 这是 **执行控制层** 的概念:让一次 run 在被打断后能从断点恢复继续推理,
|
|
357
|
+
* 让宿主能查询"我现在停在哪个节点、还欠几个 tool call"。
|
|
358
|
+
*
|
|
359
|
+
* ### 这个 Checkpointer **不是**:
|
|
360
|
+
*
|
|
361
|
+
* - **不是** 应用层的"对话总结 / 上下文裁剪 checkpoint"。那是上下文工程
|
|
362
|
+
* 领域的概念,通常由宿主自己实现成一个 LLM tool(让模型主动写阶段总结,
|
|
363
|
+
* 下一轮上下文构建时把摘要点之前的旧消息从 LLM context window 里裁掉)。
|
|
364
|
+
* 那种产出本质上是一个 RuntimeEvent,落在宿主的 EventStore 里,跟本接口
|
|
365
|
+
* 毫无关系。
|
|
366
|
+
*
|
|
367
|
+
* - **不是** RuntimeEvent 持久化。事件流的持久化由 `EventStore` 接口负责。
|
|
368
|
+
*
|
|
369
|
+
* - **不是** Run 元数据持久化。Run 注册由 `RunRegistryStore` 负责。
|
|
370
|
+
*
|
|
371
|
+
* 名字相同语义不同,是历史遗留。如果你在文档里同时看到 "checkpoint",
|
|
372
|
+
* 请按上下文区分:本接口语境下的 checkpoint 永远指 EngineState 快照。
|
|
373
|
+
*/
|
|
374
|
+
|
|
375
|
+
type CheckpointMeta = {
|
|
376
|
+
conversationId: string;
|
|
377
|
+
schemaVersion: number;
|
|
378
|
+
savedAt: number;
|
|
379
|
+
currentNode?: string;
|
|
380
|
+
iterations?: number;
|
|
381
|
+
hasPendingToolCalls: boolean;
|
|
382
|
+
};
|
|
383
|
+
type CheckpointListFilter = {
|
|
384
|
+
savedAfter?: number;
|
|
385
|
+
limit?: number;
|
|
386
|
+
cursor?: string;
|
|
387
|
+
};
|
|
388
|
+
type CheckpointSummary = CheckpointMeta;
|
|
389
|
+
interface Checkpointer {
|
|
390
|
+
load(conversationId: string): Promise<EngineState | null>;
|
|
391
|
+
save(conversationId: string, state: EngineState): Promise<void>;
|
|
392
|
+
clear(conversationId: string): Promise<void>;
|
|
393
|
+
peekMeta?(conversationId: string): Promise<CheckpointMeta | null>;
|
|
394
|
+
list?(filter?: CheckpointListFilter): Promise<CheckpointSummary[]>;
|
|
395
|
+
}
|
|
396
|
+
declare function summarizeCheckpoint(conversationId: string, state: EngineState, savedAt: number): CheckpointSummary;
|
|
397
|
+
|
|
398
|
+
interface GraphExecutorConfig {
|
|
399
|
+
maxSteps?: number;
|
|
400
|
+
maxCheckpoints?: number;
|
|
401
|
+
/**
|
|
402
|
+
* 可选:宿主提供的 TelemetryPort 实现。
|
|
403
|
+
* 不传时使用 noopTelemetry(observability 默认关闭,零业务影响)。
|
|
404
|
+
*/
|
|
405
|
+
telemetryPort?: TelemetryPort;
|
|
406
|
+
}
|
|
407
|
+
declare class GraphExecutor {
|
|
408
|
+
private readonly checkpointer;
|
|
409
|
+
private nodes;
|
|
410
|
+
private ephemeralLocals;
|
|
411
|
+
private readonly config;
|
|
412
|
+
private readonly telemetryPort;
|
|
413
|
+
constructor(checkpointer: Checkpointer, config?: GraphExecutorConfig);
|
|
414
|
+
registerNode(node: GraphNode): void;
|
|
415
|
+
peekCheckpoint(conversationId: string): Promise<EngineState | null>;
|
|
416
|
+
private sanitize;
|
|
417
|
+
prime(conversationId: string, local: Record<string, unknown>, nodeId?: string): Promise<void>;
|
|
418
|
+
setNode(conversationId: string, nodeId: string, localPatch?: Record<string, unknown>): Promise<void>;
|
|
419
|
+
runUntilYield(conversationId: string): Promise<{
|
|
420
|
+
events: RuntimeEvent[];
|
|
421
|
+
checkpoint: EngineState;
|
|
422
|
+
stepCount: number;
|
|
423
|
+
}>;
|
|
424
|
+
private runUntilYieldInternal;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
declare class MemoryEventStore implements EventStore {
|
|
428
|
+
private readonly store;
|
|
429
|
+
append(conversationId: string, event: PersistedEvent): Promise<void>;
|
|
430
|
+
range(conversationId: string, opts?: EventRangeOptions): Promise<PersistedEvent[]>;
|
|
431
|
+
latestEventId(conversationId: string): Promise<string | null>;
|
|
432
|
+
truncate(conversationId: string, opts: {
|
|
433
|
+
beforeEventId?: string;
|
|
434
|
+
beforeMs?: number;
|
|
435
|
+
}): Promise<void>;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
declare class MemoryRunRegistryStore implements RunRegistryStore {
|
|
439
|
+
private readonly store;
|
|
440
|
+
save(record: RunRecord): Promise<void>;
|
|
441
|
+
load(runId: string): Promise<RunRecord | null>;
|
|
442
|
+
list(filter?: ListRunsFilter): Promise<{
|
|
443
|
+
runs: RunRecord[];
|
|
444
|
+
nextCursor?: string;
|
|
445
|
+
}>;
|
|
446
|
+
delete(runId: string): Promise<void>;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
type RunTerminalStatus = Extract<RunRecord['status'], 'completed' | 'failed' | 'cancelled'>;
|
|
450
|
+
type RunTerminalError = {
|
|
451
|
+
errorCode: string;
|
|
452
|
+
message: string;
|
|
453
|
+
recoverable: boolean;
|
|
454
|
+
};
|
|
455
|
+
interface RunOutcome {
|
|
456
|
+
runId: string;
|
|
457
|
+
status: RunTerminalStatus;
|
|
458
|
+
completedAt: number;
|
|
459
|
+
currentNode?: string;
|
|
460
|
+
iterationsUsed?: number;
|
|
461
|
+
error?: RunTerminalError;
|
|
462
|
+
metadata?: Record<string, unknown>;
|
|
463
|
+
}
|
|
464
|
+
interface RunSnapshot extends RunMeta {
|
|
465
|
+
metadata?: Record<string, unknown>;
|
|
466
|
+
}
|
|
467
|
+
interface RunTerminalEvent {
|
|
468
|
+
runId: string;
|
|
469
|
+
status: RunTerminalStatus;
|
|
470
|
+
outcome: RunOutcome;
|
|
471
|
+
}
|
|
472
|
+
interface RunWaitForTerminalOptions {
|
|
473
|
+
timeoutMs?: number;
|
|
474
|
+
signal?: AbortSignal;
|
|
475
|
+
}
|
|
476
|
+
interface FindActiveByConversationOptions {
|
|
477
|
+
includeChildren?: boolean;
|
|
478
|
+
agentSpecId?: string;
|
|
479
|
+
}
|
|
480
|
+
interface RunExecutionContext<TRequest extends RunRequestSnapshot = RunRequestSnapshot> {
|
|
481
|
+
runId: string;
|
|
482
|
+
parentRunId?: string;
|
|
483
|
+
conversationId: string;
|
|
484
|
+
agentSpec: AgentSpec;
|
|
485
|
+
request: TRequest;
|
|
486
|
+
signal: AbortSignal;
|
|
487
|
+
eventBus: EventBus;
|
|
488
|
+
eventStore: EventStore;
|
|
489
|
+
costCollector: RunCostCollector;
|
|
490
|
+
query?: string;
|
|
491
|
+
contextFences?: readonly unknown[];
|
|
492
|
+
wakeSource?: string;
|
|
493
|
+
ephemeral?: Record<string, unknown>;
|
|
494
|
+
metadata?: Record<string, unknown>;
|
|
495
|
+
}
|
|
496
|
+
interface RunExecutorPort<TRequest extends RunRequestSnapshot = RunRequestSnapshot> {
|
|
497
|
+
execute(context: RunExecutionContext<TRequest>): Promise<RunOutcome | void>;
|
|
498
|
+
}
|
|
499
|
+
interface RunRegistrationSpec<TRequest extends RunRequestSnapshot = RunRequestSnapshot> {
|
|
500
|
+
runId?: string;
|
|
501
|
+
parentRunId?: string;
|
|
502
|
+
parentSignal?: AbortSignal;
|
|
503
|
+
conversationId: string;
|
|
504
|
+
agentSpec: AgentSpec;
|
|
505
|
+
request: TRequest;
|
|
506
|
+
eventBus: EventBus;
|
|
507
|
+
eventStore: EventStore;
|
|
508
|
+
costCollector: RunCostCollector;
|
|
509
|
+
iterationBudget?: RunRecord['iterationBudget'];
|
|
510
|
+
query?: string;
|
|
511
|
+
contextFences?: readonly unknown[];
|
|
512
|
+
wakeSource?: string;
|
|
513
|
+
ephemeral?: Record<string, unknown>;
|
|
514
|
+
metadata?: Record<string, unknown>;
|
|
515
|
+
}
|
|
516
|
+
interface RunSupervisor<TRequest extends RunRequestSnapshot = RunRequestSnapshot> {
|
|
517
|
+
registerRun(spec: RunRegistrationSpec<TRequest>): Promise<RunHandle<TRequest>>;
|
|
518
|
+
spawnDetached(spec: RunRegistrationSpec<TRequest>): Promise<RunHandle<TRequest>>;
|
|
519
|
+
observeRun(runId: string, filter?: RunObserveFilter): AsyncIterable<RuntimeEvent>;
|
|
520
|
+
cancel(runId: string, opts: CancelOpts): Promise<void>;
|
|
521
|
+
markAwaitingUser(runId: string, patch?: RunAwaitingUserPatch): Promise<void>;
|
|
522
|
+
list(filter?: ListRunsFilter): Promise<{
|
|
523
|
+
runs: RunMeta[];
|
|
524
|
+
nextCursor?: string;
|
|
525
|
+
}>;
|
|
526
|
+
peek(runId: string): Promise<RunMeta | null>;
|
|
527
|
+
waitForTerminal(runId: string, opts?: RunWaitForTerminalOptions): Promise<RunOutcome>;
|
|
528
|
+
findActiveByConversation(conversationId: string, opts?: FindActiveByConversationOptions): Promise<RunSnapshot[]>;
|
|
529
|
+
drain(opts?: RunWaitForTerminalOptions): Promise<RunOutcome[]>;
|
|
530
|
+
recoverOnBoot(reason?: string): Promise<RunOutcome[]>;
|
|
531
|
+
pause(runId: string, reason?: string): Promise<never>;
|
|
532
|
+
resume(runId: string): Promise<never>;
|
|
533
|
+
runTree(rootRunId: string): Promise<never>;
|
|
534
|
+
handleFailure(runId: string, error: unknown): Promise<never>;
|
|
535
|
+
}
|
|
536
|
+
interface DefaultRunSupervisorOptions<TRequest extends RunRequestSnapshot = RunRequestSnapshot> {
|
|
537
|
+
registryStore: RunRegistryStore;
|
|
538
|
+
auditPort?: AuditPort;
|
|
539
|
+
executor?: RunExecutorPort<TRequest>;
|
|
540
|
+
runIdFactory?: () => string;
|
|
541
|
+
now?: () => number;
|
|
542
|
+
}
|
|
543
|
+
declare class DefaultRunSupervisor<TRequest extends RunRequestSnapshot = RunRequestSnapshot> implements RunSupervisor<TRequest> {
|
|
544
|
+
private readonly registryStore;
|
|
545
|
+
private readonly auditPort?;
|
|
546
|
+
private readonly executor?;
|
|
547
|
+
private readonly runIdFactory;
|
|
548
|
+
private readonly now;
|
|
549
|
+
private readonly handles;
|
|
550
|
+
private readonly controllers;
|
|
551
|
+
private readonly inFlight;
|
|
552
|
+
private readonly terminalOutcomes;
|
|
553
|
+
private readonly terminalWaiters;
|
|
554
|
+
constructor(options: DefaultRunSupervisorOptions<TRequest>);
|
|
555
|
+
registerRun(spec: RunRegistrationSpec<TRequest>): Promise<RunHandle<TRequest>>;
|
|
556
|
+
spawnDetached(spec: RunRegistrationSpec<TRequest>): Promise<RunHandle<TRequest>>;
|
|
557
|
+
observeRun(runId: string, filter?: RunObserveFilter): AsyncIterable<RuntimeEvent>;
|
|
558
|
+
cancel(runId: string, opts: CancelOpts): Promise<void>;
|
|
559
|
+
markAwaitingUser(runId: string, patch?: RunAwaitingUserPatch): Promise<void>;
|
|
560
|
+
list(filter?: ListRunsFilter): Promise<{
|
|
561
|
+
runs: RunMeta[];
|
|
562
|
+
nextCursor?: string;
|
|
563
|
+
}>;
|
|
564
|
+
peek(runId: string): Promise<RunMeta | null>;
|
|
565
|
+
waitForTerminal(runId: string, opts?: RunWaitForTerminalOptions): Promise<RunOutcome>;
|
|
566
|
+
findActiveByConversation(conversationId: string, opts?: FindActiveByConversationOptions): Promise<RunSnapshot[]>;
|
|
567
|
+
drain(opts?: RunWaitForTerminalOptions): Promise<RunOutcome[]>;
|
|
568
|
+
recoverOnBoot(reason?: string): Promise<RunOutcome[]>;
|
|
569
|
+
pause(_runId: string, _reason?: string): Promise<never>;
|
|
570
|
+
resume(_runId: string): Promise<never>;
|
|
571
|
+
runTree(_rootRunId: string): Promise<never>;
|
|
572
|
+
handleFailure(_runId: string, _error: unknown): Promise<never>;
|
|
573
|
+
private executeDetachedRun;
|
|
574
|
+
private persistExecutorOutcome;
|
|
575
|
+
private getTerminalWaiters;
|
|
576
|
+
private notifyTerminalWaiters;
|
|
577
|
+
private getHandle;
|
|
578
|
+
private watchAwaitingUserEvents;
|
|
579
|
+
private toRunMeta;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
interface GraphLoopLlmNodeFactoryParams {
|
|
583
|
+
llmCaller: LlmCaller;
|
|
584
|
+
toolRuntime: ToolRuntimePort;
|
|
585
|
+
}
|
|
586
|
+
interface GraphLoopHarnessOptions {
|
|
587
|
+
conversationId: string;
|
|
588
|
+
turnId: string;
|
|
589
|
+
query: string;
|
|
590
|
+
request: AgentInvocationRequest;
|
|
591
|
+
toolContext: ToolExecutionContext;
|
|
592
|
+
llmCaller: LlmCaller;
|
|
593
|
+
toolRuntime: ToolRuntimePort;
|
|
594
|
+
observationPreview: ObservationPreviewPort;
|
|
595
|
+
createLlmNode: (params: GraphLoopLlmNodeFactoryParams) => GraphNode;
|
|
596
|
+
executorLocal?: ExecutorLocalState;
|
|
597
|
+
history?: RuntimeEvent[];
|
|
598
|
+
maxSteps?: number;
|
|
599
|
+
signal?: AbortSignal;
|
|
600
|
+
auditPort?: AuditPort;
|
|
601
|
+
telemetryPort?: TelemetryPort;
|
|
602
|
+
sseSink?: (evt: unknown) => RuntimeEvent[] | void;
|
|
603
|
+
}
|
|
604
|
+
interface GraphLoopHarnessRunResult {
|
|
605
|
+
checkpointNodeId: string;
|
|
606
|
+
stepCount: number;
|
|
607
|
+
}
|
|
608
|
+
interface GraphLoopHarness {
|
|
609
|
+
run(): Promise<GraphLoopHarnessRunResult>;
|
|
610
|
+
}
|
|
611
|
+
declare function createGraphLoopHarness(options: GraphLoopHarnessOptions): GraphLoopHarness;
|
|
612
|
+
|
|
613
|
+
interface DefaultGraphExecutorOptions {
|
|
614
|
+
llmNode: GraphNode;
|
|
615
|
+
toolRuntime: ToolRuntimePort;
|
|
616
|
+
observationPreview: ObservationPreviewPort;
|
|
617
|
+
maxSteps?: number;
|
|
618
|
+
checkpointer?: Checkpointer;
|
|
619
|
+
auditPort?: AuditPort;
|
|
620
|
+
telemetryPort?: TelemetryPort;
|
|
621
|
+
}
|
|
622
|
+
declare function createDefaultGraphExecutor(options: DefaultGraphExecutorOptions): GraphExecutor;
|
|
623
|
+
|
|
624
|
+
export { type RunTerminalError as A, type RunTerminalEvent as B, type Checkpointer as C, DefaultRunSupervisor as D, type ExecutorLocalState as E, type FindActiveByConversationOptions as F, type GraphNode as G, type RunTerminalStatus as H, type RunWaitForTerminalOptions as I, TELEMETRY_EVENT_KINDS as J, type TelemetryEvent as K, type LlmCallTelemetry as L, type ModelCatalogEntry as M, type NodeResult as N, type TelemetryScope as O, type DefaultGraphExecutorOptions as P, type GraphLoopHarness as Q, type RunExecutionContext as R, type StandardToolCall as S, type TelemetryPort as T, type GraphLoopHarnessOptions as U, type GraphLoopHarnessRunResult as V, type GraphLoopLlmNodeFactoryParams as W, createDefaultGraphExecutor as X, createGraphLoopHarness as Y, type LLMPolicy as a, type LLMPolicyRequestContext as b, type LLMPolicyResponseContext as c, type LLMPolicyMatchContext as d, type LLMPolicyErrorDecision as e, LlmCaller as f, type ModelCatalogLike as g, ModelResolver as h, type ModelResolverLike as i, type EngineState as j, type CheckpointMeta as k, type CheckpointListFilter as l, type CheckpointSummary as m, ENGINE_STATE_SCHEMA_VERSION as n, GraphExecutor as o, MemoryEventStore as p, type ToolContextPatch as q, type DefaultRunSupervisorOptions as r, summarizeCheckpoint as s, MemoryRunRegistryStore as t, type RunExecutorPort as u, type RunOutcome as v, withLLMTelemetryContext as w, type RunRegistrationSpec as x, type RunSnapshot as y, type RunSupervisor as z };
|