@zmzai/agent-framework 0.8.0 → 0.12.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/dist/adapters/openai-provider.d.ts +6 -3
- package/dist/adapters/openai-provider.d.ts.map +1 -1
- package/dist/adapters/openai-provider.js +1 -1
- package/dist/adapters/openai-provider.js.map +1 -1
- package/dist/core/events/manifest.d.ts +19 -1
- package/dist/core/events/manifest.d.ts.map +1 -1
- package/dist/core/events/manifest.js +15 -0
- package/dist/core/events/manifest.js.map +1 -1
- package/dist/core/runtime/active-run-registry.d.ts +34 -0
- package/dist/core/runtime/active-run-registry.d.ts.map +1 -0
- package/dist/core/runtime/active-run-registry.js +44 -0
- package/dist/core/runtime/active-run-registry.js.map +1 -0
- package/dist/core/runtime/attempt-executor.d.ts +67 -0
- package/dist/core/runtime/attempt-executor.d.ts.map +1 -0
- package/dist/core/runtime/attempt-executor.js +683 -0
- package/dist/core/runtime/attempt-executor.js.map +1 -0
- package/dist/core/runtime/command-service.d.ts +48 -0
- package/dist/core/runtime/command-service.d.ts.map +1 -0
- package/dist/core/runtime/command-service.js +148 -0
- package/dist/core/runtime/command-service.js.map +1 -0
- package/dist/core/runtime/compaction.d.ts +30 -6
- package/dist/core/runtime/compaction.d.ts.map +1 -1
- package/dist/core/runtime/compaction.js +5 -4
- package/dist/core/runtime/compaction.js.map +1 -1
- package/dist/core/runtime/context-builder.d.ts +66 -0
- package/dist/core/runtime/context-builder.d.ts.map +1 -0
- package/dist/core/runtime/context-builder.js +187 -0
- package/dist/core/runtime/context-builder.js.map +1 -0
- package/dist/core/runtime/run-scheduler.d.ts +44 -0
- package/dist/core/runtime/run-scheduler.d.ts.map +1 -0
- package/dist/core/runtime/run-scheduler.js +136 -0
- package/dist/core/runtime/run-scheduler.js.map +1 -0
- package/dist/core/runtime/runner.d.ts +25 -178
- package/dist/core/runtime/runner.d.ts.map +1 -1
- package/dist/core/runtime/runner.js +105 -1403
- package/dist/core/runtime/runner.js.map +1 -1
- package/dist/core/runtime/task-lifecycle.d.ts +165 -0
- package/dist/core/runtime/task-lifecycle.d.ts.map +1 -0
- package/dist/core/runtime/task-lifecycle.js +424 -0
- package/dist/core/runtime/task-lifecycle.js.map +1 -0
- package/dist/core/session/sqlite-store.d.ts.map +1 -1
- package/dist/core/session/sqlite-store.js +110 -1
- package/dist/core/session/sqlite-store.js.map +1 -1
- package/dist/core/session/store.d.ts +9 -1
- package/dist/core/session/store.d.ts.map +1 -1
- package/dist/core/session/types.d.ts +16 -0
- package/dist/core/session/types.d.ts.map +1 -1
- package/dist/core/session/workflow.d.ts +49 -2
- package/dist/core/session/workflow.d.ts.map +1 -1
- package/dist/core/session/workflow.js.map +1 -1
- package/dist/core/subagents/coordinator.d.ts +140 -0
- package/dist/core/subagents/coordinator.d.ts.map +1 -0
- package/dist/core/subagents/coordinator.js +355 -0
- package/dist/core/subagents/coordinator.js.map +1 -0
- package/dist/core/subagents/parked.d.ts +50 -0
- package/dist/core/subagents/parked.d.ts.map +1 -0
- package/dist/core/subagents/parked.js +75 -0
- package/dist/core/subagents/parked.js.map +1 -0
- package/dist/core/subagents/tools.d.ts +29 -0
- package/dist/core/subagents/tools.d.ts.map +1 -0
- package/dist/core/subagents/tools.js +163 -0
- package/dist/core/subagents/tools.js.map +1 -0
- package/dist/core/subagents/types.d.ts +107 -0
- package/dist/core/subagents/types.d.ts.map +1 -0
- package/dist/core/subagents/types.js +44 -0
- package/dist/core/subagents/types.js.map +1 -0
- package/dist/core/task/completion.d.ts +11 -1
- package/dist/core/task/completion.d.ts.map +1 -1
- package/dist/core/task/completion.js +40 -2
- package/dist/core/task/completion.js.map +1 -1
- package/dist/core/task/contract.d.ts +10 -4
- package/dist/core/task/contract.d.ts.map +1 -1
- package/dist/core/task/contract.js +23 -9
- package/dist/core/task/contract.js.map +1 -1
- package/dist/core/task/index.d.ts +2 -2
- package/dist/core/task/index.d.ts.map +1 -1
- package/dist/core/task/index.js +1 -1
- package/dist/core/task/index.js.map +1 -1
- package/dist/core/task/plan.d.ts +39 -9
- package/dist/core/task/plan.d.ts.map +1 -1
- package/dist/core/task/plan.js +54 -23
- package/dist/core/task/plan.js.map +1 -1
- package/dist/core/task/types.d.ts +28 -0
- package/dist/core/task/types.d.ts.map +1 -1
- package/dist/core/task/types.js.map +1 -1
- package/dist/core/tools/adapter.d.ts.map +1 -1
- package/dist/core/tools/adapter.js +87 -61
- package/dist/core/tools/adapter.js.map +1 -1
- package/dist/core/tools/builtins.d.ts.map +1 -1
- package/dist/core/tools/builtins.js +12 -1
- package/dist/core/tools/builtins.js.map +1 -1
- package/dist/core/tools/context.d.ts +1 -0
- package/dist/core/tools/context.d.ts.map +1 -1
- package/dist/core/tools/def.d.ts +25 -0
- package/dist/core/tools/def.d.ts.map +1 -1
- package/dist/core/tools/def.js.map +1 -1
- package/dist/core/tools/git.d.ts.map +1 -1
- package/dist/core/tools/git.js +4 -0
- package/dist/core/tools/git.js.map +1 -1
- package/dist/core/tools/patch.d.ts.map +1 -1
- package/dist/core/tools/patch.js +1 -0
- package/dist/core/tools/patch.js.map +1 -1
- package/dist/core/tools/qa-check.d.ts +2 -2
- package/dist/core/tools/qa-check.d.ts.map +1 -1
- package/dist/core/tools/qa-check.js +1 -0
- package/dist/core/tools/qa-check.js.map +1 -1
- package/dist/core/tools/repomap.d.ts.map +1 -1
- package/dist/core/tools/repomap.js +1 -0
- package/dist/core/tools/repomap.js.map +1 -1
- package/dist/core/tools/task-block.d.ts.map +1 -1
- package/dist/core/tools/task-block.js +1 -0
- package/dist/core/tools/task-block.js.map +1 -1
- package/dist/core/tools/task-deliver.d.ts +55 -0
- package/dist/core/tools/task-deliver.d.ts.map +1 -0
- package/dist/core/tools/task-deliver.js +99 -0
- package/dist/core/tools/task-deliver.js.map +1 -0
- package/dist/core/tools/task.d.ts.map +1 -1
- package/dist/core/tools/task.js +3 -0
- package/dist/core/tools/task.js.map +1 -1
- package/dist/core/tools/terminal.d.ts.map +1 -1
- package/dist/core/tools/terminal.js +5 -0
- package/dist/core/tools/terminal.js.map +1 -1
- package/dist/core/tools/webfetch.d.ts.map +1 -1
- package/dist/core/tools/webfetch.js +1 -0
- package/dist/core/tools/webfetch.js.map +1 -1
- package/dist/core/tools/websearch.d.ts.map +1 -1
- package/dist/core/tools/websearch.js +1 -0
- package/dist/core/tools/websearch.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/server/create-agent-runtime.d.ts +3 -1
- package/dist/server/create-agent-runtime.d.ts.map +1 -1
- package/dist/server/create-agent-runtime.js +8 -1
- package/dist/server/create-agent-runtime.js.map +1 -1
- package/dist/server/create-server.d.ts +6 -0
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +9 -0
- package/dist/server/create-server.js.map +1 -1
- package/package.json +12 -11
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { AgentRegistry } from "../agent/registry.js";
|
|
3
|
+
import { createFrameworkSession } from "../runtime/runner.js";
|
|
4
|
+
import { writePathGuardRules } from "../permission/write-path.js";
|
|
5
|
+
import { isSubagentTerminal, newSubagentRecord } from "./types.js";
|
|
6
|
+
export const DEFAULT_LIMITS = { perRoot: 3, global: 6 };
|
|
7
|
+
/** spawn payload 指纹:同 spawnRequestId 重试时校验 payload 一致性。
|
|
8
|
+
* SpawnInput(subagentType)与 ChildSessionFactory 输入(agentType)是同一
|
|
9
|
+
* 字段的两种形态,归一后取 hash——协调器与工厂两侧必须得到相同指纹。 */
|
|
10
|
+
function spawnPayloadHashOf(input) {
|
|
11
|
+
return createHash("sha256")
|
|
12
|
+
.update(JSON.stringify({ description: input.description, prompt: input.prompt, subagentType: input.subagentType ?? input.agentType, mode: input.mode ?? "read_only" }))
|
|
13
|
+
.digest("hex");
|
|
14
|
+
}
|
|
15
|
+
/** 确定性子会话 id:同 spawnRequestId 的创建中断重试落到同一 id(PC04 崩溃窗口)。 */
|
|
16
|
+
export function childSessionIdFor(spawnRequestId) {
|
|
17
|
+
return `ses_sub_${createHash("sha256").update(spawnRequestId).digest("hex").slice(0, 20)}`;
|
|
18
|
+
}
|
|
19
|
+
/** 框架默认 ChildSessionFactory:真实 registry + 父 Session 派生创建。
|
|
20
|
+
* - 权限上限:read_only 继承父权限(空集圈禁写路径);workspace_write 追加
|
|
21
|
+
* preset writePaths 圈禁(白名单 allow + 全局 deny 兜底)。
|
|
22
|
+
* - 模型/身份继承:preset model ?? 父会话模型;userId/workspaceId 继承父
|
|
23
|
+
* (凭据引用随父用户,不复制凭据内容)。
|
|
24
|
+
* - 幂等:子 id 与 creationRequestId 均从 spawnRequestId 派生——创建中断后
|
|
25
|
+
* 重试命中 store 的既有会话(同键同 hash no-op),不产生第二个 childSession。 */
|
|
26
|
+
export function createDefaultChildSessionFactory(deps) {
|
|
27
|
+
return async (input) => {
|
|
28
|
+
const registry = await deps.registryFor(input.parent);
|
|
29
|
+
const subagent = registry.get(input.agentType);
|
|
30
|
+
if (!subagent || (subagent.mode !== "subagent" && subagent.mode !== "all")) {
|
|
31
|
+
throw new Error(`未知或非子代理类型:${input.agentType}`);
|
|
32
|
+
}
|
|
33
|
+
const guard = input.mode === "read_only" ? [] : writePathGuardRules(subagent.writePaths ?? []);
|
|
34
|
+
return createFrameworkSession({
|
|
35
|
+
store: deps.store,
|
|
36
|
+
userId: input.parent.userId,
|
|
37
|
+
workspaceId: input.parent.workspaceId,
|
|
38
|
+
id: childSessionIdFor(input.spawnRequestId),
|
|
39
|
+
agent: input.agentType,
|
|
40
|
+
model: subagent.model ?? input.parent.model,
|
|
41
|
+
prompt: input.prompt,
|
|
42
|
+
parentId: input.parent.id,
|
|
43
|
+
title: input.description,
|
|
44
|
+
permission: [...input.parent.permission, ...guard],
|
|
45
|
+
...(input.mode !== "read_only" && subagent.writePaths?.length ? { writePaths: subagent.writePaths } : {}),
|
|
46
|
+
creationRequestId: input.spawnRequestId,
|
|
47
|
+
creationPayloadHash: spawnPayloadHashOf(input),
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export class SubagentCoordinator {
|
|
52
|
+
deps;
|
|
53
|
+
limits;
|
|
54
|
+
queue = [];
|
|
55
|
+
/** 活跃子 run 的取消句柄(childId → abort)。 */
|
|
56
|
+
active = new Map();
|
|
57
|
+
/** wait 的轮询唤醒(子终态时 resolve)。 */
|
|
58
|
+
waiters = new Set();
|
|
59
|
+
/** createServer 绑定的运行期服务(会话级 registry + 深度)。 */
|
|
60
|
+
bound = null;
|
|
61
|
+
createChildSession;
|
|
62
|
+
constructor(deps) {
|
|
63
|
+
this.deps = deps;
|
|
64
|
+
this.limits = deps.limits ?? DEFAULT_LIMITS;
|
|
65
|
+
this.createChildSession = deps.createChildSession
|
|
66
|
+
?? createDefaultChildSessionFactory({ store: deps.store, registryFor: (session) => this.resolveRegistry(session) });
|
|
67
|
+
}
|
|
68
|
+
get store() {
|
|
69
|
+
if (!this.deps.store.subagents)
|
|
70
|
+
throw new Error("SUBAGENTS_UNSUPPORTED(store 未提供 subagents 面)");
|
|
71
|
+
return this.deps.store.subagents;
|
|
72
|
+
}
|
|
73
|
+
get subagentDepth() {
|
|
74
|
+
return this.bound?.subagentDepth ?? this.deps.subagentDepth ?? 1;
|
|
75
|
+
}
|
|
76
|
+
/** 会话级 registry 解析:绑定(createServer,含 workspace Agent)> 宿主注入 >
|
|
77
|
+
* 静态基线 > 空注册表。 */
|
|
78
|
+
async resolveRegistry(session) {
|
|
79
|
+
if (this.bound)
|
|
80
|
+
return this.bound.registryFor(session);
|
|
81
|
+
if (this.deps.registryFor)
|
|
82
|
+
return this.deps.registryFor(session);
|
|
83
|
+
if (this.deps.registry)
|
|
84
|
+
return this.deps.registry;
|
|
85
|
+
return new AgentRegistry();
|
|
86
|
+
}
|
|
87
|
+
/** createServer 装配时绑定 runner 同源的运行期服务。重复绑定拒绝——
|
|
88
|
+
* 多 runner 场景共享一个协调器时换源必须显式,不能悄悄生效。 */
|
|
89
|
+
bindRuntimeServices(services) {
|
|
90
|
+
if (this.bound)
|
|
91
|
+
throw new Error("SUBAGENT_SERVICES_ALREADY_BOUND:协调器运行期服务已绑定");
|
|
92
|
+
this.bound = { registryFor: services.registryFor, subagentDepth: services.subagentDepth };
|
|
93
|
+
}
|
|
94
|
+
/** 父身份解析(spec §4.1:禁止只有 id 的伪 Session 抵达创建工厂)。
|
|
95
|
+
* 工具层只带 { id }(ToolContext 没有 SessionInfo 全量);缺失身份时从
|
|
96
|
+
* store 解析完整父会话——userId 为 undefined 的伪 Session 会让 SQLite
|
|
97
|
+
* 参数绑定直接崩(实测 "Provided value cannot be bound to SQLite parameter")。 */
|
|
98
|
+
async resolveParent(parentRef) {
|
|
99
|
+
const ref = parentRef;
|
|
100
|
+
if (ref.userId != null && ref.workspaceId != null)
|
|
101
|
+
return parentRef;
|
|
102
|
+
const stored = await this.deps.store.getSession(parentRef.id);
|
|
103
|
+
if (!stored)
|
|
104
|
+
throw new Error(`父会话不存在或不可解析:${parentRef.id}`);
|
|
105
|
+
return stored;
|
|
106
|
+
}
|
|
107
|
+
/** 父链深度:服务端从 store 解析(不信任调用方声明,spec §4.1)。 */
|
|
108
|
+
async parentDepth(session) {
|
|
109
|
+
let depth = 0;
|
|
110
|
+
let current = session;
|
|
111
|
+
while (current?.parentId) {
|
|
112
|
+
depth += 1;
|
|
113
|
+
current = await this.deps.store.getSession(current.parentId);
|
|
114
|
+
}
|
|
115
|
+
return depth;
|
|
116
|
+
}
|
|
117
|
+
/** agent_spawn:父身份解析 → 幂等校验 → 深度/类型检查 → 唯一工厂创建 →
|
|
118
|
+
* 登记(幂等)→ 入队 → 立即返回 childId(不等待执行)。 */
|
|
119
|
+
async spawn(parentRef, parentTaskId, rootTaskId, input) {
|
|
120
|
+
const parent = await this.resolveParent(parentRef);
|
|
121
|
+
const spawnRequestId = input.spawnRequestId ?? `spawn:${randomUUID()}`;
|
|
122
|
+
const spawnPayloadHash = spawnPayloadHashOf(input);
|
|
123
|
+
const prior = await this.store.findSubagentBySpawnRequest(parent.id, spawnRequestId);
|
|
124
|
+
if (prior) {
|
|
125
|
+
if (prior.spawnPayloadHash && prior.spawnPayloadHash !== spawnPayloadHash) {
|
|
126
|
+
throw new Error(`SPAWN_PAYLOAD_MISMATCH:spawnRequestId=${spawnRequestId} 已用于不同 payload 的派生,拒绝重放`);
|
|
127
|
+
}
|
|
128
|
+
return prior; // A14:重试返回同一 child
|
|
129
|
+
}
|
|
130
|
+
const depth = await this.parentDepth(parent);
|
|
131
|
+
if (depth >= this.subagentDepth)
|
|
132
|
+
throw new Error(`子代理嵌套深度超过限制(${this.subagentDepth})`);
|
|
133
|
+
// 类型守卫(对所有工厂生效):agentType 必须是 registry 声明的子代理类型,
|
|
134
|
+
// 模型编造的类型在这里拒绝(spec §4.1 不能信任模型给任意 childId/类型)。
|
|
135
|
+
const registry = await this.resolveRegistry(parent);
|
|
136
|
+
const subagent = registry.get(input.subagentType);
|
|
137
|
+
if (!subagent || (subagent.mode !== "subagent" && subagent.mode !== "all")) {
|
|
138
|
+
throw new Error(`未知或非子代理类型:${input.subagentType}`);
|
|
139
|
+
}
|
|
140
|
+
const child = await this.createChildSession({
|
|
141
|
+
parent,
|
|
142
|
+
agentType: input.subagentType,
|
|
143
|
+
prompt: input.prompt,
|
|
144
|
+
description: input.description,
|
|
145
|
+
mode: input.mode ?? "read_only",
|
|
146
|
+
spawnRequestId,
|
|
147
|
+
});
|
|
148
|
+
const record = {
|
|
149
|
+
...newSubagentRecord({
|
|
150
|
+
childSessionId: child.id,
|
|
151
|
+
parentSessionId: parent.id,
|
|
152
|
+
rootTaskId,
|
|
153
|
+
parentTaskId,
|
|
154
|
+
spawnRequestId,
|
|
155
|
+
agentType: input.subagentType,
|
|
156
|
+
goal: input.description,
|
|
157
|
+
mode: input.mode ?? "read_only",
|
|
158
|
+
workspaceId: child.workspaceId,
|
|
159
|
+
traceId: randomUUID(),
|
|
160
|
+
}),
|
|
161
|
+
spawnPayloadHash,
|
|
162
|
+
};
|
|
163
|
+
const created = await this.createSubagentIdempotent(record);
|
|
164
|
+
this.queue.push({ childId: created.childId, rootTaskId, prompt: input.prompt });
|
|
165
|
+
this.pump();
|
|
166
|
+
return created;
|
|
167
|
+
}
|
|
168
|
+
/** 登记幂等:并发同键 spawn 撞唯一索引(parent_session_id, spawn_request_id)
|
|
169
|
+
* 时回落到既有记录,不重复入队。 */
|
|
170
|
+
async createSubagentIdempotent(record) {
|
|
171
|
+
try {
|
|
172
|
+
return await this.store.createSubagent(record);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
const prior = await this.store.findSubagentBySpawnRequest(record.parentSessionId, record.spawnRequestId).catch(() => null);
|
|
176
|
+
if (prior)
|
|
177
|
+
return prior;
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** agent_list:当前树内子代理 + 最近进度。 */
|
|
182
|
+
async list(rootTaskId) {
|
|
183
|
+
const all = await this.store.listSubagents({ rootTaskId });
|
|
184
|
+
return all.map((r) => ({ ...r }));
|
|
185
|
+
}
|
|
186
|
+
/** agent_send:幂等投递;waiting_input 唤醒;终态拒绝(CHILD_TERMINAL)。 */
|
|
187
|
+
async send(childId, payload, kind = "constraint", messageId = randomUUID()) {
|
|
188
|
+
const rec = await this.store.getSubagent(childId);
|
|
189
|
+
if (!rec)
|
|
190
|
+
return { delivered: false, reason: "CHILD_NOT_FOUND" };
|
|
191
|
+
if (isSubagentTerminal(rec.status))
|
|
192
|
+
return { delivered: false, reason: "CHILD_TERMINAL" }; // 不复活旧子代理(spec §8.2)
|
|
193
|
+
await this.store.appendMessage({ messageId, childId, direction: "to_child", kind, payload, createdAt: new Date().toISOString() });
|
|
194
|
+
return { delivered: true };
|
|
195
|
+
}
|
|
196
|
+
/** agent_wait:最多 timeoutMs;等首个终态或需处理状态;无变化返回仍在运行。
|
|
197
|
+
* 非 async 挂死——用活跃 run 的 done promise + 轮询兜底。 */
|
|
198
|
+
async wait(childIds, timeoutMs = 30_000) {
|
|
199
|
+
const deadline = Date.now() + timeoutMs;
|
|
200
|
+
const read = async () => {
|
|
201
|
+
const out = [];
|
|
202
|
+
for (const id of childIds) {
|
|
203
|
+
const r = await this.store.getSubagent(id);
|
|
204
|
+
if (r)
|
|
205
|
+
out.push(r);
|
|
206
|
+
}
|
|
207
|
+
return out;
|
|
208
|
+
};
|
|
209
|
+
const isSettled = (records) => records.some((r) => isSubagentTerminal(r.status) || r.status === "waiting_permission" || r.status === "waiting_input" || r.status === "waiting_external" || r.status === "blocked");
|
|
210
|
+
for (;;) {
|
|
211
|
+
const records = await read();
|
|
212
|
+
if (isSettled(records))
|
|
213
|
+
return { changed: records, anyTerminal: records.some((r) => isSubagentTerminal(r.status)) };
|
|
214
|
+
if (Date.now() >= deadline)
|
|
215
|
+
return { changed: records, anyTerminal: false };
|
|
216
|
+
{
|
|
217
|
+
let wake = () => { };
|
|
218
|
+
const notified = new Promise((resolve) => { wake = resolve; this.waiters.add(wake); });
|
|
219
|
+
const poll = new Promise((resolve) => setTimeout(resolve, 500)); // 轮询兜底
|
|
220
|
+
await Promise.race([notified, poll]).finally(() => this.waiters.delete(wake));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/** agent_cancel:幂等标记 cancelling → 停止 admission → 取消 run 与后代 →
|
|
225
|
+
* 终态确认由状态回调落 cancelled。返回已登记。 */
|
|
226
|
+
async cancel(childId) {
|
|
227
|
+
for (;;) {
|
|
228
|
+
const rec = await this.store.getSubagent(childId);
|
|
229
|
+
if (!rec)
|
|
230
|
+
return { cancelling: false, reason: "CHILD_NOT_FOUND" };
|
|
231
|
+
if (isSubagentTerminal(rec.status))
|
|
232
|
+
return { cancelling: false, reason: `CHILD_TERMINAL:${rec.status}` };
|
|
233
|
+
if (rec.status === "cancelling")
|
|
234
|
+
return { cancelling: true };
|
|
235
|
+
try {
|
|
236
|
+
await this.store.updateSubagent(childId, rec.revision, { status: "cancelling" });
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
if (/SUBAGENT_REVISION_CONFLICT/.test(String(error)))
|
|
241
|
+
continue; // CAS 重试
|
|
242
|
+
throw error;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// 出队未启动的
|
|
246
|
+
const qi = this.queue.findIndex((q) => q.childId === childId);
|
|
247
|
+
if (qi >= 0) {
|
|
248
|
+
this.queue.splice(qi, 1);
|
|
249
|
+
const rec = await this.store.getSubagent(childId);
|
|
250
|
+
if (rec)
|
|
251
|
+
await this.store.updateSubagent(childId, rec.revision, { status: "cancelled" }).catch(() => undefined);
|
|
252
|
+
this.notifyWaiters();
|
|
253
|
+
return { cancelling: true };
|
|
254
|
+
}
|
|
255
|
+
// 活跃的:abort 子 run(终态回调会落 cancelled)
|
|
256
|
+
const entry = this.active.get(childId);
|
|
257
|
+
if (entry) {
|
|
258
|
+
await this.deps.abortChild(childId);
|
|
259
|
+
await entry.done.catch(() => undefined);
|
|
260
|
+
return { cancelling: true };
|
|
261
|
+
}
|
|
262
|
+
// waiting_*(无活跃 run):直接落终态
|
|
263
|
+
const rec = await this.store.getSubagent(childId);
|
|
264
|
+
if (rec && !isSubagentTerminal(rec.status)) {
|
|
265
|
+
await this.store.updateSubagent(childId, rec.revision, { status: "cancelled" }).catch(() => undefined);
|
|
266
|
+
}
|
|
267
|
+
this.notifyWaiters();
|
|
268
|
+
return { cancelling: true };
|
|
269
|
+
}
|
|
270
|
+
/** 根 Task 取消(§8.4 父取消→全部后代):递归取消树。 */
|
|
271
|
+
async cancelTree(rootTaskId) {
|
|
272
|
+
const children = await this.store.listSubagents({ rootTaskId });
|
|
273
|
+
for (const child of children) {
|
|
274
|
+
if (!isSubagentTerminal(child.status) && child.status !== "cancelling") {
|
|
275
|
+
await this.cancel(child.childId).catch(() => undefined);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// ---- 调度 ----
|
|
280
|
+
/** 队列泵:按根轮转取额度可用的 child 启动。 */
|
|
281
|
+
pump() {
|
|
282
|
+
void (async () => {
|
|
283
|
+
for (;;) {
|
|
284
|
+
const running = await this.store.listSubagents({ statuses: ["running", "waiting_permission", "waiting_input", "waiting_external"] });
|
|
285
|
+
if (running.length >= this.limits.global)
|
|
286
|
+
return;
|
|
287
|
+
const next = this.pickNext(running);
|
|
288
|
+
if (!next)
|
|
289
|
+
return;
|
|
290
|
+
this.queue.splice(this.queue.indexOf(next), 1);
|
|
291
|
+
void this.launch(next);
|
|
292
|
+
}
|
|
293
|
+
})().catch(() => undefined);
|
|
294
|
+
}
|
|
295
|
+
/** 根间轮转 + 根内 FIFO:优先选「当前运行数最少」的根的队头。 */
|
|
296
|
+
pickNext(running) {
|
|
297
|
+
const perRoot = new Map();
|
|
298
|
+
for (const r of running)
|
|
299
|
+
perRoot.set(r.rootTaskId, (perRoot.get(r.rootTaskId) ?? 0) + 1);
|
|
300
|
+
let candidates = this.queue.filter((q) => (perRoot.get(q.rootTaskId) ?? 0) < this.limits.perRoot);
|
|
301
|
+
if (candidates.length === 0)
|
|
302
|
+
return undefined;
|
|
303
|
+
// 根间轮转:按根分组取各组队头,再选运行数最少的根
|
|
304
|
+
const heads = new Map();
|
|
305
|
+
for (const q of candidates)
|
|
306
|
+
if (!heads.has(q.rootTaskId))
|
|
307
|
+
heads.set(q.rootTaskId, q);
|
|
308
|
+
const ordered = [...heads.values()].sort((a, b) => (perRoot.get(a.rootTaskId) ?? 0) - (perRoot.get(b.rootTaskId) ?? 0));
|
|
309
|
+
return ordered[0];
|
|
310
|
+
}
|
|
311
|
+
async launch(item) {
|
|
312
|
+
let rec = await this.store.getSubagent(item.childId);
|
|
313
|
+
if (!rec || isSubagentTerminal(rec.status) || rec.status === "cancelling")
|
|
314
|
+
return;
|
|
315
|
+
rec = await this.store.updateSubagent(item.childId, rec.revision, { status: "running", times: { ...rec.times, startedAt: new Date().toISOString() } });
|
|
316
|
+
let settle;
|
|
317
|
+
const done = new Promise((resolve) => { settle = resolve; });
|
|
318
|
+
this.active.set(item.childId, { abort: () => undefined, done });
|
|
319
|
+
try {
|
|
320
|
+
const state = await this.deps.runChild(item.childId, item.prompt);
|
|
321
|
+
const latest = await this.store.getSubagent(item.childId);
|
|
322
|
+
if (!latest)
|
|
323
|
+
return;
|
|
324
|
+
if (latest.status === "cancelling") {
|
|
325
|
+
await this.store.updateSubagent(item.childId, latest.revision, { status: "cancelled", times: { ...latest.times, endedAt: new Date().toISOString() } });
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
const outcome = state === "completed" ? "completed" : state === "cancelled" ? "cancelled" : "failed";
|
|
329
|
+
await this.store.updateSubagent(item.childId, latest.revision, {
|
|
330
|
+
status: outcome,
|
|
331
|
+
times: { ...latest.times, endedAt: new Date().toISOString() },
|
|
332
|
+
...(outcome === "completed" ? {} : { blockerReason: state === "failed" ? `子运行失败(${state})` : undefined }),
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
const latest = await this.store.getSubagent(item.childId);
|
|
338
|
+
if (latest && !isSubagentTerminal(latest.status)) {
|
|
339
|
+
await this.store.updateSubagent(item.childId, latest.revision, { status: "failed", blockerReason: error instanceof Error ? error.message : String(error) }).catch(() => undefined);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
finally {
|
|
343
|
+
this.active.delete(item.childId);
|
|
344
|
+
settle();
|
|
345
|
+
this.notifyWaiters();
|
|
346
|
+
this.pump(); // 腾出的额度给下一个排队者
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
notifyWaiters() {
|
|
350
|
+
for (const w of this.waiters)
|
|
351
|
+
w();
|
|
352
|
+
this.waiters.clear();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
//# sourceMappingURL=coordinator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../../src/core/subagents/coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { SubagentStore, SubagentRecord } from "./types.js";
|
|
2
|
+
/** parked/mailbox/父唤醒(spec §8.2 调度状态,M3-S19)。
|
|
3
|
+
*
|
|
4
|
+
* 【为什么是独立模块而不是塞进 TaskLifecycle】parked 是**调度语义**(释放
|
|
5
|
+
* 父模型并发槽、由 RunScheduler 认领续跑),TaskLifecycle 只需在 Attempt
|
|
6
|
+
* 循环的 continue 分支问一句「该不该 park」;唤醒合并的幂等水位在
|
|
7
|
+
* mailbox 表上——本模块把两侧粘起来,TaskLifecycle/RunScheduler 经
|
|
8
|
+
* collaborators 注入,不反向依赖。
|
|
9
|
+
*
|
|
10
|
+
* 【核心不变量】子结果入邮箱与父唤醒意图**同事务**(spec §8.2);
|
|
11
|
+
* 多个子同时完成最多产生一个待执行父唤醒(水位幂等合并)。 */
|
|
12
|
+
export type ParkControllerDeps = {
|
|
13
|
+
subagents: SubagentStore;
|
|
14
|
+
/** TaskStore CAS 面(TaskRecord patch)。 */
|
|
15
|
+
casTask(taskId: string, expectedRevision: number, patch: Record<string, unknown>): Promise<unknown>;
|
|
16
|
+
getTask(taskId: string): Promise<{
|
|
17
|
+
id: string;
|
|
18
|
+
revision: number;
|
|
19
|
+
status: string;
|
|
20
|
+
rootRequestId?: string;
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
} | null>;
|
|
23
|
+
/** 唤醒登记(RunScheduler.requestResume 或等价内部续跑入口)。 */
|
|
24
|
+
requestInternalResume(sessionId: string): void;
|
|
25
|
+
/** 根 Task 的 sessionId 查询(子 → 父会话映射;B0 子代理同 session 树)。 */
|
|
26
|
+
sessionOfTask?(taskId: string): Promise<string | undefined>;
|
|
27
|
+
};
|
|
28
|
+
/** 判定:父轮次结束时是否应 park(必要子代理尚未全部终态)。
|
|
29
|
+
* TaskLifecycle 的 continue 分支在再次 Attempt 前调用;park=true 时
|
|
30
|
+
* TaskLifecycle 不再发起下一轮 Attempt,而是落 parked 并释放并发槽。 */
|
|
31
|
+
export declare function shouldPark(deps: ParkControllerDeps, rootTaskId: string, requiredChildIds?: string[]): Promise<boolean>;
|
|
32
|
+
/** 落 parked:TaskRecord 保持 running(调度状态不是第二套生命周期),
|
|
33
|
+
* 经 marker 字段标记;发布由 caller(TaskLifecycle)负责。 */
|
|
34
|
+
export declare function parkParent(deps: ParkControllerDeps, taskId: string): Promise<void>;
|
|
35
|
+
/** 子终态回调:结果入邮箱(to_parent)+ 唤醒意图——合并语义靠
|
|
36
|
+
* requestInternalResume 的幂等(RunScheduler.resumeRequests 是 Set,
|
|
37
|
+
* 重复 add 天然合并为一个)。 */
|
|
38
|
+
export declare function onChildTerminal(deps: ParkControllerDeps, child: SubagentRecord, parentSessionId: string): Promise<void>;
|
|
39
|
+
/** 父唤醒时的未消费结果读取 + 水位推进(A28:仅纳入一次)。 */
|
|
40
|
+
export declare function drainParentMailbox(deps: ParkControllerDeps, rootTaskId: string): Promise<{
|
|
41
|
+
results: {
|
|
42
|
+
childId: string;
|
|
43
|
+
outcome: string;
|
|
44
|
+
summary: string;
|
|
45
|
+
}[];
|
|
46
|
+
clearedPark: boolean;
|
|
47
|
+
}>;
|
|
48
|
+
/** 终态根 Task 拒绝自动唤醒(A29:取消/失败/已交付的父不复活)。 */
|
|
49
|
+
export declare function canAutoResume(taskStatus: string): boolean;
|
|
50
|
+
//# sourceMappingURL=parked.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parked.d.ts","sourceRoot":"","sources":["../../../src/core/subagents/parked.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGhE;;;;;;;;;mCASmC;AACnC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,aAAa,CAAC;IACzB,yCAAyC;IACzC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACtI,kDAAkD;IAClD,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,0DAA0D;IAC1D,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CAC7D,CAAC;AAEF;;uDAEuD;AACvD,wBAAsB,UAAU,CAAC,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAM5H;AAED;iDACiD;AACjD,wBAAsB,UAAU,CAAC,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWxF;AAED;;uBAEuB;AACvB,wBAAsB,eAAe,CAAC,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa7H;AAED,sCAAsC;AACtC,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,CAoB1L;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEzD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { isSubagentTerminal } from "./types.js";
|
|
2
|
+
/** 判定:父轮次结束时是否应 park(必要子代理尚未全部终态)。
|
|
3
|
+
* TaskLifecycle 的 continue 分支在再次 Attempt 前调用;park=true 时
|
|
4
|
+
* TaskLifecycle 不再发起下一轮 Attempt,而是落 parked 并释放并发槽。 */
|
|
5
|
+
export async function shouldPark(deps, rootTaskId, requiredChildIds) {
|
|
6
|
+
const children = await deps.subagents.listSubagents({ rootTaskId });
|
|
7
|
+
const pending = children.filter((c) => !isSubagentTerminal(c.status));
|
|
8
|
+
if (pending.length === 0)
|
|
9
|
+
return false;
|
|
10
|
+
if (!requiredChildIds)
|
|
11
|
+
return true; // 存在未终态子代理即 park(宽松语义:模型没显式弃权的都等)
|
|
12
|
+
return requiredChildIds.some((id) => pending.some((c) => c.childId === id));
|
|
13
|
+
}
|
|
14
|
+
/** 落 parked:TaskRecord 保持 running(调度状态不是第二套生命周期),
|
|
15
|
+
* 经 marker 字段标记;发布由 caller(TaskLifecycle)负责。 */
|
|
16
|
+
export async function parkParent(deps, taskId) {
|
|
17
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
18
|
+
const task = await deps.getTask(taskId);
|
|
19
|
+
if (!task)
|
|
20
|
+
return;
|
|
21
|
+
try {
|
|
22
|
+
await deps.casTask(taskId, task.revision, { parkedReason: "children" });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (!/TASK_REVISION_CONFLICT/.test(String(error)))
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** 子终态回调:结果入邮箱(to_parent)+ 唤醒意图——合并语义靠
|
|
32
|
+
* requestInternalResume 的幂等(RunScheduler.resumeRequests 是 Set,
|
|
33
|
+
* 重复 add 天然合并为一个)。 */
|
|
34
|
+
export async function onChildTerminal(deps, child, parentSessionId) {
|
|
35
|
+
const messageId = `result_${child.childId}_${child.revision}`;
|
|
36
|
+
await deps.subagents.appendMessage({
|
|
37
|
+
messageId,
|
|
38
|
+
childId: child.childId,
|
|
39
|
+
direction: "to_parent",
|
|
40
|
+
kind: "result",
|
|
41
|
+
payload: JSON.stringify({ outcome: child.result?.outcome ?? child.status, summary: child.result?.summary ?? "", childId: child.childId }),
|
|
42
|
+
createdAt: new Date().toISOString(),
|
|
43
|
+
});
|
|
44
|
+
// 幂等:同 messageId 重复回调(重启重放等)不产生第二封邮件;
|
|
45
|
+
// 唤醒意图同事务登记(requestResume 的 Set 语义 = 水位合并)
|
|
46
|
+
deps.requestInternalResume(parentSessionId);
|
|
47
|
+
}
|
|
48
|
+
/** 父唤醒时的未消费结果读取 + 水位推进(A28:仅纳入一次)。 */
|
|
49
|
+
export async function drainParentMailbox(deps, rootTaskId) {
|
|
50
|
+
const children = await deps.subagents.listSubagents({ rootTaskId });
|
|
51
|
+
const results = [];
|
|
52
|
+
for (const child of children) {
|
|
53
|
+
const messages = await deps.subagents.listMessages(child.childId);
|
|
54
|
+
for (const msg of messages) {
|
|
55
|
+
if (msg.direction === "to_parent" && msg.kind === "result" && !msg.consumedByParent) {
|
|
56
|
+
try {
|
|
57
|
+
const parsed = JSON.parse(msg.payload);
|
|
58
|
+
results.push({ childId: parsed.childId, outcome: parsed.outcome, summary: parsed.summary });
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
results.push({ childId: child.childId, outcome: "unknown", summary: msg.payload.slice(0, 200) });
|
|
62
|
+
}
|
|
63
|
+
await deps.subagents.markMessagesConsumedByParent(child.childId, msg.createdAt);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// 全部终态且结果已消费 → 清 parked 标记
|
|
68
|
+
const allTerminal = children.every((c) => isSubagentTerminal(c.status));
|
|
69
|
+
return { results, clearedPark: allTerminal };
|
|
70
|
+
}
|
|
71
|
+
/** 终态根 Task 拒绝自动唤醒(A29:取消/失败/已交付的父不复活)。 */
|
|
72
|
+
export function canAutoResume(taskStatus) {
|
|
73
|
+
return taskStatus === "running"; // parked 的父保持 running;终态/等待态一律拒绝
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=parked.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parked.js","sourceRoot":"","sources":["../../../src/core/subagents/parked.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ToolDef } from "../tools/def.js";
|
|
2
|
+
import type { SubagentCoordinator } from "./coordinator.js";
|
|
3
|
+
/** agent_* 工具族(spec §8.1,M3-S20):经 SubagentCoordinator 的持久协调,
|
|
4
|
+
* 不在工具实现里另建调度器。ToolContext.subagents 由 runner 注入——
|
|
5
|
+
* 宿主未启用(无 store.subagents)时五工具不可见(execute 抛
|
|
6
|
+
* SUBAGENTS_UNSUPPORTED),旧 task 工具保持兼容。
|
|
7
|
+
*
|
|
8
|
+
* read_only 子代理的工具白名单在 spawn 侧(coordinator 依赖的
|
|
9
|
+
* createChildSession)实施——工具层不重复判定。 */
|
|
10
|
+
export type SubagentToolContext = {
|
|
11
|
+
subagents?: {
|
|
12
|
+
coordinator: SubagentCoordinator;
|
|
13
|
+
rootTaskId: string;
|
|
14
|
+
parentTaskId: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare const agentSpawnTool: ToolDef;
|
|
18
|
+
export declare const agentListTool: ToolDef;
|
|
19
|
+
export declare const agentSendTool: ToolDef;
|
|
20
|
+
export declare const agentWaitTool: ToolDef;
|
|
21
|
+
export declare const agentCancelTool: ToolDef;
|
|
22
|
+
export declare const subagentTools: ToolDef[];
|
|
23
|
+
/** 旧 task 工具的兼容封装(spec §8.1:spawn+wait 保留原返回形态)。 */
|
|
24
|
+
export declare function makeLegacyTaskTool(coordinatorGetter: (ctx: unknown) => {
|
|
25
|
+
coordinator: SubagentCoordinator;
|
|
26
|
+
rootTaskId: string;
|
|
27
|
+
parentTaskId: string;
|
|
28
|
+
} | undefined): ToolDef;
|
|
29
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/core/subagents/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG5D;;;;;;uCAMuC;AAEvC,MAAM,MAAM,mBAAmB,GAAG;IAAE,SAAS,CAAC,EAAE;QAAE,WAAW,EAAE,mBAAmB,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAajI,eAAO,MAAM,cAAc,EAAE,OAoC5B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,OAc3B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,OAoB3B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,OAoB3B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,OAiB7B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,OAAO,EAAmF,CAAC;AAEvH,oDAAoD;AACpD,wBAAgB,kBAAkB,CAAC,iBAAiB,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK;IAAE,WAAW,EAAE,mBAAmB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAAG,OAAO,CAkC3K"}
|