@x-otto/orchestrator 0.0.1-alpha.4 → 0.1.0-alpha.9
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/README.md +29 -19
- package/dist/index.d.ts +100 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -8,11 +8,11 @@ Manages the creation, scheduling, retry, and lifecycle of multi-agent tasks. Pro
|
|
|
8
8
|
|
|
9
9
|
| Module | Function |
|
|
10
10
|
| ----------------- | -------------------------------------------------------------- |
|
|
11
|
-
| TaskStore | Task CRUD + status tracking (pending/running/completed/failed) |
|
|
11
|
+
| TaskStore | Task CRUD + status tracking (pending/running/completed/failed) + event history (RFC-398 M2) |
|
|
12
12
|
| TaskExecutor | Mixed sync/background scheduling + concurrency limiting |
|
|
13
|
-
| RetryPolicy | Exponential backoff
|
|
14
|
-
| CircuitBreaker | Circuit breaker (CLOSED/OPEN
|
|
15
|
-
| Orchestrator | Business-level API (dispatchTask/callAgent/getTask/updateTask) |
|
|
13
|
+
| RetryPolicy | Exponential backoff retry (implements RetryStrategy interface, RFC-398 M5) |
|
|
14
|
+
| CircuitBreaker | Circuit breaker (CLOSED/OPEN, auto-reset after timeout) |
|
|
15
|
+
| Orchestrator | Business-level API (dispatchTask/callAgent/getTask/updateTask) + dumpConfig (RFC-398 M4) |
|
|
16
16
|
| BackgroundManager | Background async task lifecycle |
|
|
17
17
|
|
|
18
18
|
## Installation
|
|
@@ -25,39 +25,49 @@ pnpm add @x-otto/orchestrator
|
|
|
25
25
|
|
|
26
26
|
```ts
|
|
27
27
|
import { Orchestrator, TaskStore } from '@x-otto/orchestrator'
|
|
28
|
+
import { createHookRegistry } from '@x-otto/hooks'
|
|
28
29
|
|
|
29
|
-
const store = new TaskStore()
|
|
30
30
|
const orchestrator = new Orchestrator({
|
|
31
|
-
hookRegistry,
|
|
32
|
-
runSession: async ({
|
|
33
|
-
text: await runSubAgent(
|
|
31
|
+
hookRegistry: createHookRegistry(),
|
|
32
|
+
runSession: async ({ agentName, prompt }) => ({
|
|
33
|
+
text: await runSubAgent(agentName, prompt),
|
|
34
|
+
sessionId: 's1',
|
|
35
|
+
durationMs: 100,
|
|
34
36
|
}),
|
|
35
37
|
})
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
// sync mode
|
|
40
|
+
const result = await orchestrator.dispatchTask({
|
|
39
41
|
prompt: 'Search for all unused imports in src/',
|
|
42
|
+
subagent: 'explore',
|
|
43
|
+
mode: 'sync',
|
|
40
44
|
})
|
|
45
|
+
// result: { ok: true, value: { id, status, output } }
|
|
41
46
|
|
|
42
|
-
//
|
|
43
|
-
await orchestrator.dispatchTask({
|
|
44
|
-
|
|
47
|
+
// background mode
|
|
48
|
+
const bgResult = await orchestrator.dispatchTask({
|
|
49
|
+
prompt: 'Analyze architecture',
|
|
50
|
+
subagent: 'explore',
|
|
51
|
+
mode: 'background',
|
|
52
|
+
})
|
|
53
|
+
// bgResult: { ok: true, value: { id, status: 'pending', output } }
|
|
54
|
+
const task = await orchestrator.getTask(bgResult.ok ? bgResult.value.id : '')
|
|
45
55
|
```
|
|
46
56
|
|
|
47
57
|
## Directory Overview
|
|
48
58
|
|
|
49
59
|
```
|
|
50
60
|
src/
|
|
51
|
-
types.ts # core types
|
|
52
|
-
task-store.ts # task storage (TaskStore)
|
|
61
|
+
types.ts # core types (TaskInputBase / TaskInput / SwarmMemberTaskInput / AnyTaskInput)
|
|
62
|
+
task-store.ts # task storage (TaskStore + event history)
|
|
53
63
|
executor.ts # execution engine (TaskExecutor)
|
|
54
|
-
retry.ts # RetryPolicy + CircuitBreaker
|
|
55
|
-
orchestrator.ts # top-level coordinator
|
|
64
|
+
retry.ts # RetryStrategy interface + RetryPolicy + CircuitBreaker
|
|
65
|
+
orchestrator.ts # top-level coordinator (+ dumpConfig)
|
|
56
66
|
background-manager.ts # background management
|
|
57
67
|
semaphore.ts # concurrency semaphore
|
|
58
|
-
swarm/ # swarm execution (swarm / concurrent / strategy / strategies / router / handoff / errors)
|
|
68
|
+
swarm/ # swarm execution (swarm / concurrent / strategy + withStep / strategies / router / handoff / errors)
|
|
59
69
|
index.ts
|
|
60
|
-
tests/ #
|
|
70
|
+
tests/ # 13 test files / 153 tests
|
|
61
71
|
```
|
|
62
72
|
|
|
63
73
|
## Development Commands
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { CallAgent, CancelBackground, GetBackgroundOutput, GetTask, ListTasks, M
|
|
|
2
2
|
import { AgentError } from "@x-otto/shared";
|
|
3
3
|
import * as _$_x_otto_hooks0 from "@x-otto/hooks";
|
|
4
4
|
import { HookRegistry } from "@x-otto/hooks";
|
|
5
|
-
import { Model, ThinkingLevel } from "@x-otto/ai";
|
|
6
5
|
import { AgentMessage } from "@x-otto/hook-contracts";
|
|
7
6
|
import { AgentTool } from "@x-otto/interchange";
|
|
8
7
|
|
|
@@ -13,10 +12,26 @@ interface RetryConfig {
|
|
|
13
12
|
backoffMs: number;
|
|
14
13
|
backoffMultiplier: number;
|
|
15
14
|
}
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* RFC-398 M5:重试策略 seam(最小接口)。
|
|
17
|
+
*
|
|
18
|
+
* orchestrator 不再依赖具体类 RetryPolicy,而是依赖此接口。
|
|
19
|
+
* 默认实现是 RetryPolicy(指数退避);宿主可注入自定义实现(如按任务类型差异化重试)。
|
|
20
|
+
*
|
|
21
|
+
* **如实标注**:当前全仓无「换 RetryPolicy 实现」的真实消费方——此 seam 为终局形态收口
|
|
22
|
+
* (RetryPolicy 是唯一用具体类注入的治理组件,与 CircuitBreakerRegistry 的 factory seam 不对称)。
|
|
23
|
+
* 价值是「为未来差异化重试策略预留 seam」,不是当前有需求。
|
|
24
|
+
*/
|
|
25
|
+
interface RetryStrategy {
|
|
26
|
+
shouldRetry(attempt: number): boolean;
|
|
27
|
+
getBackoff(attempt: number): number;
|
|
28
|
+
readonly maxAttempts: number;
|
|
29
|
+
}
|
|
30
|
+
declare class RetryPolicy implements RetryStrategy {
|
|
17
31
|
private readonly config;
|
|
18
32
|
constructor(config?: Partial<RetryConfig>);
|
|
19
33
|
shouldRetry(attempt: number): boolean;
|
|
34
|
+
get maxAttempts(): number;
|
|
20
35
|
getBackoff(attempt: number): number;
|
|
21
36
|
static fromWorkflowOptions(wf?: WorkflowOptions$1): RetryPolicy;
|
|
22
37
|
}
|
|
@@ -40,24 +55,56 @@ declare class CircuitBreaker {
|
|
|
40
55
|
}
|
|
41
56
|
//#endregion
|
|
42
57
|
//#region src/task-store.d.ts
|
|
58
|
+
/**
|
|
59
|
+
* RFC-398 M2:TaskStore 事件流(append-only)。
|
|
60
|
+
* Map 仍为唯一事实源;事件数组只作**状态机历史快照**(测试断言用),不参与状态重建。
|
|
61
|
+
* 事件 cap 跟随 Map 容量驱逐(evicted 事件本身是驱逐信号)——避免「任务被驱逐但事件还在」的投影/日志矛盾。
|
|
62
|
+
* 不暴露 onEvent 订阅:顶层可观测性已由 executor 的 hookRegistry.emit('task.*') 提供,本数组唯一不可替代价值是测试断言。
|
|
63
|
+
*/
|
|
64
|
+
type TaskStoreEvent = {
|
|
65
|
+
type: 'task.created';
|
|
66
|
+
taskId: string;
|
|
67
|
+
at: number;
|
|
68
|
+
} | {
|
|
69
|
+
type: 'task.status-changed';
|
|
70
|
+
taskId: string;
|
|
71
|
+
from: TaskStatus;
|
|
72
|
+
to: TaskStatus;
|
|
73
|
+
at: number;
|
|
74
|
+
} | {
|
|
75
|
+
type: 'task.output-written';
|
|
76
|
+
taskId: string;
|
|
77
|
+
at: number;
|
|
78
|
+
} | {
|
|
79
|
+
type: 'task.evicted';
|
|
80
|
+
taskId: string;
|
|
81
|
+
at: number;
|
|
82
|
+
};
|
|
43
83
|
declare class TaskStore {
|
|
44
84
|
private readonly tasks;
|
|
85
|
+
private readonly events;
|
|
45
86
|
private nextId;
|
|
46
87
|
/**
|
|
47
88
|
* 容量上限(默认 1000)。store 只收 task_delegate 落库的真任务,但终态任务只增不减——
|
|
48
89
|
* 故加「终态优先 LRU 驱逐」兜底治裸 Map 无界增长(确定性、无时钟依赖,区别于 TTL)。
|
|
49
90
|
*/
|
|
50
|
-
private readonly
|
|
91
|
+
private readonly _maxStoredTasks;
|
|
51
92
|
private readonly clock;
|
|
52
93
|
constructor(maxStoredTasks?: number, clock?: Clock);
|
|
94
|
+
/** 容量上限(dumpConfig 用)。 */
|
|
95
|
+
get maxStoredTasks(): number;
|
|
96
|
+
/** 只读事件历史快照(测试断言用)。 */
|
|
97
|
+
get eventHistory(): readonly TaskStoreEvent[];
|
|
98
|
+
private recordEvent;
|
|
53
99
|
private generateId;
|
|
54
|
-
create(input:
|
|
100
|
+
create(input: AnyTaskInput, maxAttempts?: number): Promise<Task>;
|
|
55
101
|
/** 清空全部任务档案(dispose 用)。单线程内存语义下同步清空,API 仍保持 async 形态。 */
|
|
56
102
|
clear(): Promise<void>;
|
|
57
103
|
/**
|
|
58
104
|
* 容量回收:新建前若已达上限,按「终态优先 + 最旧先弃」驱逐至腾出一席。
|
|
59
105
|
* 驱逐优先级:仅终态(completed/failed/cancelled),按 completedAt ?? createdAt 升序(最旧先弃)。
|
|
60
106
|
* pending/running 在飞任务绝不驱逐——若只剩在飞仍超上限,则越界保活 + warn(绝不丢在飞的活儿)。
|
|
107
|
+
* 事件流同步驱逐:被驱逐的 task 对应事件从数组中移除,并发 task.evicted 事件。
|
|
61
108
|
*/
|
|
62
109
|
private evictForCapacity;
|
|
63
110
|
get(id: string): Promise<Task | undefined>;
|
|
@@ -109,8 +156,7 @@ interface RunSessionOptions {
|
|
|
109
156
|
};
|
|
110
157
|
systemPrompt?: string;
|
|
111
158
|
tools?: AgentToolDef[];
|
|
112
|
-
|
|
113
|
-
thinkingLevel?: ThinkingLevel$1;
|
|
159
|
+
thinkingLevel?: ThinkingLevel;
|
|
114
160
|
maxTokens?: number;
|
|
115
161
|
temperature?: number;
|
|
116
162
|
maxToolTurns?: number;
|
|
@@ -174,24 +220,24 @@ interface CoreToolDescriptor {
|
|
|
174
220
|
};
|
|
175
221
|
}
|
|
176
222
|
/** 思考深度(本地 minimal type,避免 orchestrator 核心依赖 @x-otto/ai)。 */
|
|
177
|
-
type ThinkingLevel
|
|
223
|
+
type ThinkingLevel = 'low' | 'medium' | 'high';
|
|
178
224
|
/** swarm member turn 入参(B+ 门禁①:经 TaskExecutor 治理)。 */
|
|
179
225
|
interface AgentTurnInput {
|
|
180
226
|
agentId: string;
|
|
181
227
|
prompt: string;
|
|
182
228
|
systemPrompt?: string;
|
|
183
229
|
tools?: AgentToolDef[];
|
|
230
|
+
/** RFC-332 M1:core 工具纯数据描述符——leaf 的受限 core resolver 据此构造真实工具。 */
|
|
231
|
+
coreTools?: CoreToolDescriptor[];
|
|
184
232
|
/**
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
233
|
+
* RFC-332 D3:废弃的旧工具元数据通道(AgentToolDef 投影,无法承载执行闭包)。
|
|
234
|
+
* 保留类型仅为运行期 fail-closed 诊断——旧调用方仍传时 leaf 会 warn + 忽略;
|
|
235
|
+
* 合法工具来源是 coreTools。新代码禁止使用。
|
|
188
236
|
*/
|
|
189
237
|
extraTools?: AgentToolDef[];
|
|
190
|
-
/** RFC-332 M1:core 工具纯数据描述符——leaf 的受限 core resolver 据此构造真实工具。 */
|
|
191
|
-
coreTools?: CoreToolDescriptor[];
|
|
192
238
|
model?: string;
|
|
193
239
|
maxToolTurns?: number;
|
|
194
|
-
thinkingLevel?: ThinkingLevel
|
|
240
|
+
thinkingLevel?: ThinkingLevel;
|
|
195
241
|
maxTokens?: number;
|
|
196
242
|
temperature?: number;
|
|
197
243
|
signal?: AbortSignal;
|
|
@@ -224,10 +270,8 @@ interface AgentTurnResult {
|
|
|
224
270
|
};
|
|
225
271
|
durationMs: number;
|
|
226
272
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
* 缺省等价于 'task'(向后兼容 task_delegate/agent_call 路径)。 */
|
|
230
|
-
kind?: 'task' | 'swarm_member';
|
|
273
|
+
/** 任务输入基类——公共字段(task_delegate / agent_call / swarm_member 共享)。 */
|
|
274
|
+
interface TaskInputBase {
|
|
231
275
|
/** 发给 subagent 的提示 */
|
|
232
276
|
prompt: string;
|
|
233
277
|
/** 指定 agent 名称 — 对齐 task_delegate.subagent / agent_call.agent */
|
|
@@ -252,18 +296,27 @@ interface TaskInput {
|
|
|
252
296
|
* 供 orchestrator 在任务终态时释放该 parent 的活跃计数。
|
|
253
297
|
*/
|
|
254
298
|
parentTaskId?: string;
|
|
299
|
+
}
|
|
300
|
+
/** 标准任务输入(task_delegate / agent_call 路径)。kind 缺省等价 'task'。 */
|
|
301
|
+
interface TaskInput {
|
|
302
|
+
/** 任务类别判别字段。缺省等价 'task'(向后兼容 task_delegate/agent_call 路径)。 */
|
|
303
|
+
kind?: 'task';
|
|
304
|
+
}
|
|
305
|
+
/** swarm member turn 任务输入(swarm 路径)。 */
|
|
306
|
+
interface SwarmMemberTaskInput extends TaskInputBase {
|
|
307
|
+
/** 任务类别判别字段:'swarm_member' 走轻量 Agent 创建。 */
|
|
308
|
+
kind: 'swarm_member';
|
|
255
309
|
/** swarm 成员自定义 system prompt(覆盖默认)。 */
|
|
256
310
|
systemPrompt?: string;
|
|
257
311
|
tools?: AgentToolDef[];
|
|
258
|
-
/** 本轮额外工具(如 handoff 工具)。@deprecated RFC-332:见 AgentTurnInput.extraTools。 */
|
|
259
|
-
extraTools?: AgentToolDef[];
|
|
260
312
|
/** RFC-332 M1:core 工具纯数据描述符(swarm_member 专用)。 */
|
|
261
313
|
coreTools?: CoreToolDescriptor[];
|
|
262
|
-
thinkingLevel?: ThinkingLevel
|
|
314
|
+
thinkingLevel?: ThinkingLevel;
|
|
263
315
|
maxTokens?: number;
|
|
264
316
|
temperature?: number;
|
|
265
317
|
maxToolTurns?: number;
|
|
266
318
|
}
|
|
319
|
+
interface TaskInput extends TaskInputBase {}
|
|
267
320
|
interface TaskOutput {
|
|
268
321
|
text: string;
|
|
269
322
|
summary?: string;
|
|
@@ -287,6 +340,8 @@ interface TaskError {
|
|
|
287
340
|
message: string;
|
|
288
341
|
retriable: boolean;
|
|
289
342
|
}
|
|
343
|
+
/** 判别联合——Task.input / TaskUnit.input 用此类型。 */
|
|
344
|
+
type AnyTaskInput = TaskInput | SwarmMemberTaskInput;
|
|
290
345
|
interface Task {
|
|
291
346
|
id: string;
|
|
292
347
|
status: TaskStatus$1;
|
|
@@ -294,14 +349,14 @@ interface Task {
|
|
|
294
349
|
sessionId?: string;
|
|
295
350
|
attempts: number;
|
|
296
351
|
maxAttempts: number;
|
|
297
|
-
input:
|
|
352
|
+
input: AnyTaskInput;
|
|
298
353
|
output?: TaskOutput;
|
|
299
354
|
error?: TaskError;
|
|
300
355
|
createdAt: number;
|
|
301
356
|
completedAt?: number;
|
|
302
357
|
}
|
|
303
358
|
interface TaskUnit {
|
|
304
|
-
input:
|
|
359
|
+
input: AnyTaskInput;
|
|
305
360
|
}
|
|
306
361
|
interface TaskResult {
|
|
307
362
|
taskId: string;
|
|
@@ -375,6 +430,11 @@ declare class Orchestrator {
|
|
|
375
430
|
*/
|
|
376
431
|
private readonly heldBackgroundSlots;
|
|
377
432
|
constructor(options: OrchestratorOptions);
|
|
433
|
+
/**
|
|
434
|
+
* RFC-398 M4:dumpConfig 调试出口——打印当前生效的治理参数。
|
|
435
|
+
* 用于排查「用户配了不生效」类问题。
|
|
436
|
+
*/
|
|
437
|
+
dumpConfig(): Record<string, unknown>;
|
|
378
438
|
dispatchTask: TaskDispatch;
|
|
379
439
|
/**
|
|
380
440
|
* 派发单元内核(sync/background 单源):fan-out 闸 + executor 建档/执行。
|
|
@@ -415,6 +475,15 @@ declare class Orchestrator {
|
|
|
415
475
|
}
|
|
416
476
|
//#endregion
|
|
417
477
|
//#region src/swarm/types.d.ts
|
|
478
|
+
/**
|
|
479
|
+
* 本地 minimal Model 类型(替代 `@x-otto/ai` 的 `Model`)。
|
|
480
|
+
* swarm 层唯一消费是 `member.model?.id`(swarm.ts:199),不访问 name 之外字段。
|
|
481
|
+
* 声明 `name?` 保持结构兼容(coding 侧构造的 `Model` 含 name)。
|
|
482
|
+
*/
|
|
483
|
+
interface SwarmModel {
|
|
484
|
+
id: string;
|
|
485
|
+
name?: string;
|
|
486
|
+
}
|
|
418
487
|
type SwarmAgentId = string;
|
|
419
488
|
interface SwarmMemberCommon {
|
|
420
489
|
/** 唯一标识 */
|
|
@@ -430,7 +499,7 @@ interface SwarmAgentMember extends SwarmMemberCommon {
|
|
|
430
499
|
kind: 'agent';
|
|
431
500
|
systemPrompt: string;
|
|
432
501
|
/** 模型配置(缺省时继承 Swarm 默认模型) */
|
|
433
|
-
model?:
|
|
502
|
+
model?: SwarmModel;
|
|
434
503
|
/**
|
|
435
504
|
* 成员声明的工具**元数据**(RFC-332 M3:从 `AgentTool[]` 收窄为纯数据 `AgentToolDef[]`)。
|
|
436
505
|
*
|
|
@@ -485,8 +554,6 @@ interface RouteRule {
|
|
|
485
554
|
}
|
|
486
555
|
interface RouterConfig {
|
|
487
556
|
strategy: RoutingStrategy;
|
|
488
|
-
/** LLM 路由时使用的模型 */
|
|
489
|
-
routerModel?: Model;
|
|
490
557
|
/** 规则路由 */
|
|
491
558
|
rules?: RouteRule[];
|
|
492
559
|
/** 自定义路由函数 */
|
|
@@ -522,8 +589,6 @@ interface SwarmConfig {
|
|
|
522
589
|
name: string;
|
|
523
590
|
/** 参与的 Agent 定义列表 */
|
|
524
591
|
agents: SwarmAgentDef[];
|
|
525
|
-
/** 默认 LLM 模型 */
|
|
526
|
-
defaultModel: Model;
|
|
527
592
|
/** 编排模式 */
|
|
528
593
|
pattern: OrchestrationPattern;
|
|
529
594
|
/** Swarm 成员所处的委托深度;传 Agent 构造器闭合递归护栏。 */
|
|
@@ -636,6 +701,8 @@ interface StrategyContext {
|
|
|
636
701
|
router?: Router;
|
|
637
702
|
/** AbortSignal。 */
|
|
638
703
|
signal: AbortSignal;
|
|
704
|
+
/** 时钟端口(D13:策略内禁裸 Date.now,一律经此取时间戳)。 */
|
|
705
|
+
clock: Clock;
|
|
639
706
|
/** 配置快照。 */
|
|
640
707
|
config: StrategyConfig;
|
|
641
708
|
}
|
|
@@ -665,7 +732,9 @@ interface StrategyResult {
|
|
|
665
732
|
}
|
|
666
733
|
declare class StrategyRegistry {
|
|
667
734
|
private readonly strategies;
|
|
668
|
-
register(strategy: OrchestrationStrategy): void;
|
|
735
|
+
register(strategy: OrchestrationStrategy): () => void;
|
|
736
|
+
/** 删除已注册策略(disposer 的等价直接调用)。 */
|
|
737
|
+
unregister(name: string): boolean;
|
|
669
738
|
get(name: string): OrchestrationStrategy | undefined;
|
|
670
739
|
has(name: string): boolean;
|
|
671
740
|
names(): string[];
|
|
@@ -694,8 +763,8 @@ declare class Swarm {
|
|
|
694
763
|
constructor(config: SwarmConfig);
|
|
695
764
|
getAgents(): SwarmAgentDef[];
|
|
696
765
|
getAgent(id: SwarmAgentId): SwarmAgentDef | undefined;
|
|
697
|
-
/** 注册/替换策略(§4-12:host
|
|
698
|
-
registerStrategy(strategy: OrchestrationStrategy): void;
|
|
766
|
+
/** 注册/替换策略(§4-12:host 可追加新模式,不碰核心)。返回 disposer 用于注销。 */
|
|
767
|
+
registerStrategy(strategy: OrchestrationStrategy): () => void;
|
|
699
768
|
/** 获取已注册策略名列表。 */
|
|
700
769
|
getStrategyNames(): string[];
|
|
701
770
|
private emitEvent;
|
|
@@ -835,5 +904,5 @@ declare class SwarmConfigError extends AgentError {
|
|
|
835
904
|
constructor(message: string);
|
|
836
905
|
}
|
|
837
906
|
//#endregion
|
|
838
|
-
export { AgentNotFoundError, type AgentToolDef, type AgentTurnInput, type AgentTurnResult, CircuitBreaker, type CircuitBreakerConfig, type ConcurrentOptions, type CoreToolDescriptor, HANDOFF_STRATEGY, HIERARCHICAL_STRATEGY, HandoffDepthError, type HandoffRequest, type HandoffTargetInfo, type HierarchicalTask, type OrchestrationPattern, type OrchestrationStrategy, Orchestrator, type OrchestratorOptions, PARALLEL_STRATEGY, ROUTER_STRATEGY, type RetryConfig, RetryPolicy, type RouteRule, type RouterConfig, type RoutingDecision, RoutingError, type RoutingStrategy, type RunSessionOptions, type RunSessionResult, SEQUENTIAL_STRATEGY, type StepResult, type StrategyConfig, type StrategyContext, StrategyRegistry, type StrategyResult, Swarm, type SwarmAgentDef, type SwarmAgentId, type SwarmAgentMember, type SwarmConfig, SwarmConfigError, type SwarmEvent, type SwarmEventHandler, SwarmRouter, type SwarmRunResult, type SwarmTeamMember, type SwarmTurnResult, type Task, type TaskError, type TaskInput, type TaskOutput, TaskRejectedError, type TaskResult, type TaskStatus, TaskStore, type TaskUnit, type WorkflowOptions, createDefaultStrategyRegistry, createHandoffTool, createSwarm, runConcurrent, validateHandoff };
|
|
907
|
+
export { AgentNotFoundError, type AgentToolDef, type AgentTurnInput, type AgentTurnResult, type AnyTaskInput, CircuitBreaker, type CircuitBreakerConfig, type ConcurrentOptions, type CoreToolDescriptor, HANDOFF_STRATEGY, HIERARCHICAL_STRATEGY, HandoffDepthError, type HandoffRequest, type HandoffTargetInfo, type HierarchicalTask, type OrchestrationPattern, type OrchestrationStrategy, Orchestrator, type OrchestratorOptions, PARALLEL_STRATEGY, ROUTER_STRATEGY, type RetryConfig, RetryPolicy, type RetryStrategy, type RouteRule, type RouterConfig, type RoutingDecision, RoutingError, type RoutingStrategy, type RunSessionOptions, type RunSessionResult, SEQUENTIAL_STRATEGY, type StepResult, type StrategyConfig, type StrategyContext, StrategyRegistry, type StrategyResult, Swarm, type SwarmAgentDef, type SwarmAgentId, type SwarmAgentMember, type SwarmConfig, SwarmConfigError, type SwarmEvent, type SwarmEventHandler, type SwarmMemberTaskInput, SwarmRouter, type SwarmRunResult, type SwarmTeamMember, type SwarmTurnResult, type Task, type TaskError, type TaskInput, type TaskOutput, TaskRejectedError, type TaskResult, type TaskStatus, TaskStore, type TaskStoreEvent, type TaskUnit, type WorkflowOptions, createDefaultStrategyRegistry, createHandoffTool, createSwarm, runConcurrent, validateHandoff };
|
|
839
908
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/retry.ts","../src/task-store.ts","../src/executor.ts","../src/types.ts","../src/orchestrator.ts","../src/swarm/types.ts","../src/swarm/strategy.ts","../src/swarm/swarm.ts","../src/swarm/concurrent.ts","../src/swarm/strategies/handoff.ts","../src/swarm/strategies/sequential.ts","../src/swarm/strategies/parallel.ts","../src/swarm/strategies/hierarchical.ts","../src/swarm/strategies/router.ts","../src/swarm/strategies/index.ts","../src/swarm/router.ts","../src/swarm/handoff.ts","../src/swarm/errors.ts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/retry.ts","../src/task-store.ts","../src/executor.ts","../src/types.ts","../src/orchestrator.ts","../src/swarm/types.ts","../src/swarm/strategy.ts","../src/swarm/swarm.ts","../src/swarm/concurrent.ts","../src/swarm/strategies/handoff.ts","../src/swarm/strategies/sequential.ts","../src/swarm/strategies/parallel.ts","../src/swarm/strategies/hierarchical.ts","../src/swarm/strategies/router.ts","../src/swarm/strategies/index.ts","../src/swarm/router.ts","../src/swarm/handoff.ts","../src/swarm/errors.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{checkDelegationDepth as e}from"@x-otto/orchestration-contracts";import{AgentError as t,createLogger as n}from"@x-otto/shared";import{z as r}from"zod";const i={now:()=>Date.now()};var a=class extends Error{constructor(e,t){super(e),this.reason=t,this.name=`TaskRejectedError`}};const o=new Set([`completed`,`failed`,`cancelled`]);var s=class{tasks=new Map;nextId=1;maxStoredTasks;clock;constructor(e=1e3,t=i){this.maxStoredTasks=Math.max(1,e),this.clock=t}generateId(){return`task_${this.clock.now()}_${this.nextId++}`}async create(e){this.evictForCapacity();let t={id:this.generateId(),status:`pending`,sessionPolicy:e.sessionMode??`ephemeral`,attempts:0,maxAttempts:3,input:e,createdAt:this.clock.now()};return this.tasks.set(t.id,t),t}async clear(){this.tasks.clear()}evictForCapacity(){let e=this.tasks.size-this.maxStoredTasks+1;if(e<=0)return;let t=[...this.tasks.values()].filter(e=>o.has(e.status)).sort((e,t)=>(e.completedAt??e.createdAt)-(t.completedAt??t.createdAt));for(let n of t){if(e<=0)break;this.tasks.delete(n.id),e--}e>0&&console.warn(`[TaskStore] capacity ${this.maxStoredTasks} exceeded by ${e} in-flight task(s); no terminal tasks left to evict — keeping in-flight tasks (will exceed cap).`)}async get(e){return this.tasks.get(e)}async list(e){let t=[...this.tasks.values()];return e?.status&&(t=t.filter(t=>t.status===e.status)),t}async update(e,t){let n=this.tasks.get(e);if(!n)throw Error(`Task not found: ${e}`);Object.assign(n,t)}async delete(e){return this.tasks.delete(e)}};const c={enabled:!0,maxAttempts:3,backoffMs:1e3,backoffMultiplier:2};var l=class e{config;constructor(e){this.config={...c,...e}}shouldRetry(e){return this.config.enabled&&e<this.config.maxAttempts}getBackoff(e){return this.config.backoffMs*this.config.backoffMultiplier**(e-1)}static fromWorkflowOptions(t){let n=t?.retry;return new e({enabled:n?.enabled??!0,maxAttempts:n?.maxAttempts??3})}};const u={enabled:!0,failureThreshold:5,resetTimeoutMs:6e4};var d=class{enabled;failureThreshold;resetTimeoutMs;clock;consecutiveFailures=0;openedAt=null;constructor(e,t=i){let n={...u,...e};this.enabled=n.enabled,this.failureThreshold=n.failureThreshold,this.resetTimeoutMs=n.resetTimeoutMs,this.clock=t}isOpen(){return!this.enabled||this.openedAt===null?!1:this.clock.now()-this.openedAt>=this.resetTimeoutMs?(this.openedAt=null,this.consecutiveFailures=0,!1):!0}success(){this.consecutiveFailures=0,this.openedAt=null}failure(){this.consecutiveFailures++,this.consecutiveFailures>=this.failureThreshold&&(this.openedAt=this.clock.now())}reset(){this.consecutiveFailures=0,this.openedAt=null}},f=class e{breakers=new Map;constructor(e){this.factory=e}forTarget(e){let t=this.breakers.get(e);return t||(t=this.factory(),this.breakers.set(e,t)),t}resetAll(){for(let e of this.breakers.values())e.reset()}static perTarget(t,n=i){return new e(()=>new d(t,n))}static single(t){return new e(()=>t)}static fromWorkflowOptions(t,n=i){let r=t?.circuitBreaker;return e.perTarget({enabled:r?.enabled??!0,failureThreshold:r?.failureThreshold??5,resetTimeoutMs:r?.timeoutMs??6e4},n)}};function p(){let e=Error(`Semaphore acquire aborted`);return e.name=`AbortError`,e}var m=class{active=0;waiters=[];constructor(e){this.max=e}async acquire(e){if(e?.aborted)throw p();if(this.active<this.max){this.active+=1;return}await new Promise((t,n)=>{let r={resolve:t,reject:n,cleanup:()=>{}},i=()=>{let e=this.waiters.indexOf(r);e>=0&&this.waiters.splice(e,1),r.cleanup(),n(p())};r.cleanup=()=>e?.removeEventListener(`abort`,i),this.waiters.push(r),e?.addEventListener(`abort`,i,{once:!0})})}release(){let e=this.waiters.shift();e?(e.cleanup(),e.resolve()):--this.active}drain(){let e=this.waiters.splice(0);for(let t of e)t.cleanup(),t.reject(p())}async run(e,t){await this.acquire(t);try{return await e()}finally{this.release()}}get activeCount(){return this.active}get pendingCount(){return this.waiters.length}get capacity(){return this.max}},h=class{constructor(e,t,n,r,a,o,s,c=i){this.taskStore=e,this.hookRegistry=t,this.retryPolicy=n,this.circuitBreakers=r,this.runSession=a,this.semaphore=o,this.runAgentTurn=s,this.clock=c}breakerFor(e){return this.circuitBreakers.forTarget(e??`default`)}async runTask(e,t){this.assertCircuit(e.input.subagent);let n=await this.register(e);return this.runScheduled(n.id,t)}assertCircuit(e){if(this.breakerFor(e).isOpen())throw new a(`Circuit breaker is open due to repeated failures. Try again later.`,`circuit_open`)}async runScheduled(e,t){return this.semaphore.run(()=>this.executeToCompletion(e,t),t)}async isCancelled(e){return(await this.taskStore.get(e))?.status===`cancelled`}async register(e){let t=await this.taskStore.create(e.input);return this.hookRegistry.emit(`task.created`,{task:t}),t}async startTask(e){this.assertCircuit(e.input.subagent);let t=await this.register(e),n=this.runScheduled(t.id).then(()=>void 0,async e=>{await this.taskStore.update(t.id,{status:`failed`,error:{code:`EXECUTION_FAILED`,message:e instanceof Error?e.message:String(e),retriable:!1},completedAt:this.clock.now()}).catch(()=>{})});return{id:t.id,completion:n}}async executeToCompletion(e,t){let n=await this.taskStore.get(e);if(!n)return{taskId:e,status:`failed`,error:{code:`TASK_NOT_FOUND`,message:`Task not found: ${e}`,retriable:!1}};let r=n.attempts+1;try{await this.taskStore.update(e,{status:`running`,attempts:r}),this.hookRegistry.emit(`task.started`,{task:{...n,status:`running`},agent:n.input.subagent??`default`});let i=n.input.kind===`swarm_member`,a;if(i&&this.runAgentTurn){let e=await this.runAgentTurn({agentId:n.input.subagent??`agent`,prompt:n.input.prompt,systemPrompt:n.input.systemPrompt,tools:n.input.tools,extraTools:n.input.extraTools,coreTools:n.input.coreTools,model:n.input.model,maxToolTurns:n.input.maxToolTurns,thinkingLevel:n.input.thinkingLevel,maxTokens:n.input.maxTokens,temperature:n.input.temperature,sessionId:n.input.sessionId,depth:n.input.depth,parentTaskId:n.input.parentTaskId,signal:t});a={text:e.text,sessionId:n.input.sessionId??``,tokenUsage:e.tokenUsage,durationMs:e.durationMs,messages:e.messages,handoff:e.handoff}}else a=await this.runSession({prompt:n.input.prompt,sessionId:n.input.sessionId,sessionMode:n.sessionPolicy,agentName:n.input.subagent,slot:n.input.slot,model:n.input.model,category:n.input.category,depth:n.input.depth,parentTaskId:n.input.parentTaskId,taskId:e,signal:t,readOnly:n.input.mode===`background`,systemPrompt:n.input.systemPrompt,tools:n.input.tools,extraTools:n.input.extraTools,thinkingLevel:n.input.thinkingLevel,maxTokens:n.input.maxTokens,temperature:n.input.temperature,maxToolTurns:n.input.maxToolTurns});if(await this.isCancelled(e))return{taskId:e,status:`cancelled`};let o={text:a.text,tokenUsage:a.tokenUsage,durationMs:a.durationMs,...a.messages?{messages:a.messages}:{},...a.handoff?{handoff:a.handoff}:{}};return await this.taskStore.update(e,{status:`completed`,output:o,sessionId:a.sessionId,completedAt:this.clock.now()}),this.breakerFor(n.input.subagent).success(),this.hookRegistry.emit(`task.completed`,{task:{...n,status:`completed`,output:o},result:o}),{taskId:e,status:`completed`,output:o}}catch(r){let i=r instanceof Error?r.message:String(r);if(await this.isCancelled(e))return{taskId:e,status:`cancelled`};if(this.retryPolicy.shouldRetry(n.attempts)&&!t?.aborted&&(await g(this.retryPolicy.getBackoff(n.attempts),t),!t?.aborted))return this.executeToCompletion(e,t);this.breakerFor(n.input.subagent).failure();let a={code:`EXECUTION_FAILED`,message:i,retriable:!1};return await this.taskStore.update(e,{status:`failed`,error:a,completedAt:this.clock.now()}),this.hookRegistry.emit(`task.failed`,{task:{...n,status:`failed`},error:a}),{taskId:e,status:`failed`,error:a}}}};function g(e,t){return t?.aborted?Promise.resolve():new Promise(n=>{let r,i=()=>{clearTimeout(r),n()};r=setTimeout(()=>{t?.removeEventListener(`abort`,i),n()},e),t?.addEventListener(`abort`,i,{once:!0})})}var _=class{constructor(e,t,n=i){this.taskStore=e,this.abortTask=t,this.clock=n}async getOutput(e){let t=await this.taskStore.get(e);return t?t.status===`completed`?{ok:!0,value:{status:`completed`,output:t.output?.text}}:t.status===`failed`?{ok:!1,error:t.error?.message??`Task failed`}:{ok:!0,value:{status:t.status}}:{ok:!1,error:`Task not found id: ${e}`}}async cancel(e){let t=await this.taskStore.get(e);return t?t.status===`completed`||t.status===`failed`||t.status===`cancelled`?{ok:!1,error:`Task already in terminal state: ${t.status}, id: ${e}`}:(await this.taskStore.update(e,{status:`cancelled`,completedAt:this.clock.now()}),this.abortTask&&this.abortTask(e),{ok:!0,value:void 0}):{ok:!1,error:`Task not found id: ${e}`}}},v=class{taskStore;executor;backgroundManager;hookRegistry;circuitBreakers;delegationGate;runSession;maxDelegationDepth;abortTask;fanOutCounts=new Map;maxFanOutPerParent;heldBackgroundSlots=new Set;constructor(e){let{hookRegistry:t,runSession:n,runAgentTurn:r,abortTask:a,workflowConfig:o,maxActiveTasks:c=10,maxStoredTasks:u,maxDelegationDepth:d=1}=e;this.hookRegistry=t,this.runSession=n,this.maxDelegationDepth=d,this.maxFanOutPerParent=e.maxFanOutPerParent??Math.max(1,Math.floor(c/2)),this.abortTask=a;let p=e.clock??i;this.taskStore=new s(u,p);let g=l.fromWorkflowOptions(o);this.circuitBreakers=f.fromWorkflowOptions(o,p),this.delegationGate=new m(c),this.executor=new h(this.taskStore,t,g,this.circuitBreakers,n,this.delegationGate,r,p),this.backgroundManager=new _(this.taskStore,a,p)}dispatchTask=async t=>{let{childDepth:n,exceeded:r}=e(t.depth,this.maxDelegationDepth);if(r)return b(`Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`);let i={prompt:t.prompt,subagent:t.subagent,category:t.category,sessionId:t.sessionId,sessionMode:t.sessionMode??`ephemeral`,mode:t.mode,slot:t.slot,model:t.model,depth:n,...t.parentTaskId===void 0?{}:{parentTaskId:t.parentTaskId}};return this.dispatchUnit(i,t.signal)};async dispatchUnit(e,t){let n={input:e};if((e.mode??`sync`)===`background`){let t=e.parentTaskId;if(t!==void 0&&!this.acquireFanOutSlot(t))return b(`Fan-out limit (${this.maxFanOutPerParent}) reached for parent task "${t}" — wait for in-flight subtasks to complete before delegating more.`);let r=t!==void 0;return x(async()=>{let{id:e,completion:i}=await this.executor.startTask(n).catch(e=>{throw r&&this.releaseFanOutSlot(t),e});return r&&(this.heldBackgroundSlots.add(e),i.finally(()=>{this.releaseBackgroundSlot(e,t)})),{id:e,status:`pending`,output:`Background task created: ${e}`}})}if(!this.acquireFanOutSlot(e.parentTaskId))return b(`Fan-out limit (${this.maxFanOutPerParent}) reached for parent task "${e.parentTaskId}" — wait for in-flight subtasks to complete before delegating more.`);try{let e=await this.executor.runTask(n,t);return e.status===`completed`?y({id:e.taskId,status:e.status,output:e.output?.text}):b(e.error?.message??`Unknown error`)}catch(e){return b(e)}finally{this.releaseFanOutSlot(e.parentTaskId)}}callAgent=async(t,n,r)=>{let{childDepth:i,exceeded:a}=e(r?.depth,this.maxDelegationDepth);if(a)return b(`Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`);let o=this.circuitBreakers.forTarget(t);return o.isOpen()?b(`Circuit breaker is open due to repeated failures. Try again later.`):this.acquireFanOutSlot(r?.parentTaskId)?this.delegationGate.run(async()=>{try{let e=await this.runSession({prompt:n,sessionMode:`ephemeral`,agentName:t,slot:r?.slot,model:r?.model,depth:i,parentTaskId:r?.parentTaskId,signal:r?.signal});return o.success(),y(e.text)}catch(e){return o.failure(),b(e)}},r?.signal).finally(()=>{this.releaseFanOutSlot(r?.parentTaskId)}):b(`Fan-out limit (${this.maxFanOutPerParent}) reached for parent task "${r?.parentTaskId}" — wait for in-flight subtasks to complete before delegating more.`)};async runAgentTurn(e){let t={input:{kind:`swarm_member`,prompt:e.prompt,subagent:e.agentId,systemPrompt:e.systemPrompt,tools:e.tools,extraTools:e.extraTools,coreTools:e.coreTools,model:e.model,maxToolTurns:e.maxToolTurns,thinkingLevel:e.thinkingLevel,maxTokens:e.maxTokens,temperature:e.temperature,sessionMode:`ephemeral`,sessionId:e.sessionId,depth:e.depth,parentTaskId:e.parentTaskId}},n=await this.executor.runTask(t,e.signal);if(n.status===`completed`)return{agentId:e.agentId,text:n.output?.text??``,messages:n.output?.messages,handoff:n.output?.handoff,tokenUsage:n.output?.tokenUsage,durationMs:n.output?.durationMs??0};throw Error(n.error?.message??`Swarm member turn failed: ${n.status}`)}getTask=async e=>{let t=await this.taskStore.get(e);return t?y({id:t.id,status:t.status,prompt:t.input.prompt,output:t.output?.text,error:t.error?.message}):b(`Task not found: ${e}`)};listTasks=async e=>{let t=e&&e!==`all`?{status:e}:void 0;return y((await this.taskStore.list(t)).map(e=>({id:e.id,prompt:e.input.prompt,status:e.status})))};updateTask=async(e,t)=>{let n=await this.taskStore.get(e);if(!n)return b(`Task not found: ${e}`);if(t===`cancel`){let t=await this.backgroundManager.cancel(e);return t.ok?(await this.hookRegistry.emit(`task.cancelled`,{taskId:e}),y(`Task ${e} cancelled`)):b(t.error)}if(t===`retry`){if(n.status!==`failed`)return b(`Can only retry failed tasks. Current status: ${n.status}`);let e=await this.dispatchUnit(n.input);return e.ok?y(e.value.output??`Retry completed`):b(e.error)}return b(`Unknown action: ${t}`)};getBackgroundOutput=async e=>this.backgroundManager.getOutput(e);cancelBackground=async e=>{let t=await this.backgroundManager.cancel(e);if(t.ok){let t=await this.taskStore.get(e);this.releaseBackgroundSlot(e,t?.input.parentTaskId)}return t};async dispose(){this.circuitBreakers.resetAll(),this.fanOutCounts.clear(),this.heldBackgroundSlots.clear();let e=await this.taskStore.list();for(let t of e)if(t.status===`pending`||t.status===`running`)try{this.abortTask?.(t.id)}catch{}await this.taskStore.clear(),this.delegationGate.drain()}acquireFanOutSlot(e){if(e===void 0)return!0;let t=this.fanOutCounts.get(e)??0;return t>=this.maxFanOutPerParent?!1:(this.fanOutCounts.set(e,t+1),!0)}releaseFanOutSlot(e){if(e===void 0)return;let t=this.fanOutCounts.get(e);t!==void 0&&(t<=1?this.fanOutCounts.delete(e):this.fanOutCounts.set(e,t-1))}releaseBackgroundSlot(e,t){this.heldBackgroundSlots.delete(e)&&this.releaseFanOutSlot(t)}};function y(e){return{ok:!0,value:e}}function b(e){return{ok:!1,error:S(e)}}async function x(e){try{return y(await e())}catch(e){return b(e)}}function S(e){return e instanceof Error?e.message:String(e)}var C=class extends t{depth;maxDepth;constructor(e,t){super(`Handoff depth ${e} exceeds max ${t}`,{code:`SWARM_HANDOFF_DEPTH_EXCEEDED`}),this.name=`HandoffDepthError`,this.depth=e,this.maxDepth=t}},w=class extends t{constructor(e){super(e,{code:`SWARM_ROUTING_ERROR`}),this.name=`RoutingError`}},T=class extends t{agentId;constructor(e){super(`Agent "${e}" not found in swarm`,{code:`SWARM_AGENT_NOT_FOUND`}),this.name=`AgentNotFoundError`,this.agentId=e}},E=class extends t{constructor(e){super(e,{code:`SWARM_CONFIG_ERROR`}),this.name=`SwarmConfigError`}},D=class{config;roundRobinIndex=0;constructor(e){if(e.strategy===`llm`&&!e.customRouter)throw new w(`Routing strategy 'llm' requires a customRouter (inject the real LLM routing call).`);this.config=e}async route(e,t){let{strategy:n}=this.config;switch(n){case`rule`:return this.routeByRule(e,t);case`round-robin`:return this.routeRoundRobin(t);case`random`:return this.routeRandom(t);case`llm`:return this.routeByLlm(e,t);default:throw new w(`Unknown routing strategy: ${n}`)}}routeByRule(e,t){let n=this.config.rules??[],r=e.toLowerCase(),i=[...n].sort((e,t)=>(t.priority??0)-(e.priority??0));for(let e of i)if(this.matchRule(e,r)){let n=t.find(t=>t.id===e.agentId);if(n)return{agentId:e.agentId,reason:`Matched rule for "${n.name}"`,confidence:1}}return this.fallback(t,`No rule matched`)}routeRoundRobin(e){let t=e[this.roundRobinIndex%e.length];return this.roundRobinIndex++,{agentId:t.id,reason:`Round-robin selection (index ${this.roundRobinIndex-1})`,confidence:1}}routeRandom(e){let t=this.config.random?.random??Math.random;return{agentId:e[Math.floor(t()*e.length)].id,reason:`Random selection`,confidence:1/e.length}}async routeByLlm(e,t){let{customRouter:n}=this.config;if(!n)throw new w(`Routing strategy 'llm' requires a customRouter.`);return n(e,t)}fallback(e,t){let n=this.config.fallbackAgentId??e[0]?.id;if(!n)throw new w(`${t} and no fallback agent configured`);return{agentId:n,reason:`${t} — using fallback agent`,confidence:0}}matchRule(e,t){return e.match instanceof RegExp?e.match.test(t):e.match.some(e=>t.includes(e.toLowerCase()))}},O=class{strategies=new Map;register(e){if(this.strategies.has(e.name))throw Error(`Orchestration strategy "${e.name}" is already registered`);this.strategies.set(e.name,e)}get(e){return this.strategies.get(e)}has(e){return this.strategies.has(e)}names(){return[...this.strategies.keys()]}};function k(e,t,n){let i=t.map(e=>`- "${e.id}": ${e.name} — ${e.description}`).join(`
|
|
2
|
-
`),a=t.map(e=>e.id);return{name:`handoff_to_agent`,description:`Transfer control to another agent in the swarm. Available targets:\n${i}`,parameters:r.object({target_agent_id:r.string().describe(`The ID of the agent to hand off to. Must be one of: ${a.join(`, `)}`),reason:r.string().describe(`Why you are transferring to this agent — will be provided as context.`),summary:r.string().optional().describe(`Optional summary of work done so far to provide context to the target agent.`)}),
|
|
1
|
+
import{checkDelegationDepth as e}from"@x-otto/orchestration-contracts";import{AgentError as t,createLogger as n}from"@x-otto/shared";import{z as r}from"zod";const i={now:()=>Date.now()};var a=class extends Error{constructor(e,t){super(e),this.reason=t,this.name=`TaskRejectedError`}};const o=new Set([`completed`,`failed`,`cancelled`]);var s=class{tasks=new Map;events=[];nextId=1;_maxStoredTasks;clock;constructor(e=1e3,t=i){this._maxStoredTasks=Math.max(1,e),this.clock=t}get maxStoredTasks(){return this._maxStoredTasks}get eventHistory(){return this.events}recordEvent(e){this.events.push(e)}generateId(){return`task_${this.clock.now()}_${this.nextId++}`}async create(e,t=3){this.evictForCapacity();let n={id:this.generateId(),status:`pending`,sessionPolicy:e.sessionMode??`ephemeral`,attempts:0,maxAttempts:t,input:e,createdAt:this.clock.now()};return this.tasks.set(n.id,n),this.recordEvent({type:`task.created`,taskId:n.id,at:n.createdAt}),n}async clear(){this.tasks.clear(),this.events.length=0}evictForCapacity(){let e=this.tasks.size-this.maxStoredTasks+1;if(e<=0)return;let t=[...this.tasks.values()].filter(e=>o.has(e.status)).sort((e,t)=>(e.completedAt??e.createdAt)-(t.completedAt??t.createdAt));for(let n of t){if(e<=0)break;this.tasks.delete(n.id);let t=this.clock.now();for(let e=this.events.length-1;e>=0;e--)this.events[e].taskId===n.id&&this.events.splice(e,1);this.recordEvent({type:`task.evicted`,taskId:n.id,at:t}),e--}e>0&&console.warn(`[TaskStore] capacity ${this.maxStoredTasks} exceeded by ${e} in-flight task(s); no terminal tasks left to evict — keeping in-flight tasks (will exceed cap).`)}async get(e){return this.tasks.get(e)}async list(e){let t=[...this.tasks.values()];return e?.status&&(t=t.filter(t=>t.status===e.status)),t}async update(e,t){let n=this.tasks.get(e);if(!n)throw Error(`Task not found: ${e}`);let r=n.status,i=t.output!==void 0;Object.assign(n,t);let a=this.clock.now();t.status!==void 0&&t.status!==r&&this.recordEvent({type:`task.status-changed`,taskId:e,from:r,to:t.status,at:a}),i&&this.recordEvent({type:`task.output-written`,taskId:e,at:a})}async delete(e){let t=this.tasks.delete(e);if(t)for(let t=this.events.length-1;t>=0;t--)this.events[t].taskId===e&&this.events.splice(t,1);return t}};const c={enabled:!0,maxAttempts:3,backoffMs:1e3,backoffMultiplier:2};var l=class e{config;constructor(e){this.config={...c,...e}}shouldRetry(e){return this.config.enabled&&e<this.config.maxAttempts}get maxAttempts(){return this.config.maxAttempts}getBackoff(e){return this.config.backoffMs*this.config.backoffMultiplier**(e-1)}static fromWorkflowOptions(t){let n=t?.retry;return new e({enabled:n?.enabled??!0,maxAttempts:n?.maxAttempts??3,backoffMs:n?.backoffMs,backoffMultiplier:n?.backoffMultiplier})}};const u={enabled:!0,failureThreshold:5,resetTimeoutMs:6e4};var d=class{enabled;failureThreshold;resetTimeoutMs;clock;consecutiveFailures=0;openedAt=null;constructor(e,t=i){let n={...u,...e};this.enabled=n.enabled,this.failureThreshold=n.failureThreshold,this.resetTimeoutMs=n.resetTimeoutMs,this.clock=t}isOpen(){return!this.enabled||this.openedAt===null?!1:this.clock.now()-this.openedAt>=this.resetTimeoutMs?(this.openedAt=null,this.consecutiveFailures=0,!1):!0}success(){this.consecutiveFailures=0,this.openedAt=null}failure(){this.consecutiveFailures++,this.consecutiveFailures>=this.failureThreshold&&(this.openedAt=this.clock.now())}reset(){this.consecutiveFailures=0,this.openedAt=null}},f=class e{breakers=new Map;constructor(e){this.factory=e}forTarget(e){let t=this.breakers.get(e);return t||(t=this.factory(),this.breakers.set(e,t)),t}resetAll(){for(let e of this.breakers.values())e.reset()}static perTarget(t,n=i){return new e(()=>new d(t,n))}static single(t){return new e(()=>t)}static fromWorkflowOptions(t,n=i){let r=t?.circuitBreaker;return e.perTarget({enabled:r?.enabled??!0,failureThreshold:r?.failureThreshold??5,resetTimeoutMs:r?.timeoutMs??6e4},n)}};function p(){let e=Error(`Semaphore acquire aborted`);return e.name=`AbortError`,e}var m=class{active=0;waiters=[];constructor(e){this.max=e}async acquire(e){if(e?.aborted)throw p();if(this.active<this.max){this.active+=1;return}await new Promise((t,n)=>{let r={resolve:t,reject:n,cleanup:()=>{}},i=()=>{let e=this.waiters.indexOf(r);e>=0&&this.waiters.splice(e,1),r.cleanup(),n(p())};r.cleanup=()=>e?.removeEventListener(`abort`,i),this.waiters.push(r),e?.addEventListener(`abort`,i,{once:!0})})}release(){let e=this.waiters.shift();e?(e.cleanup(),e.resolve()):--this.active}drain(){let e=this.waiters.splice(0);for(let t of e)t.cleanup(),t.reject(p())}async run(e,t){await this.acquire(t);try{return await e()}finally{this.release()}}get activeCount(){return this.active}get pendingCount(){return this.waiters.length}get capacity(){return this.max}},h=class{constructor(e,t,n,r,a,o,s,c=i){this.taskStore=e,this.hookRegistry=t,this.retryPolicy=n,this.circuitBreakers=r,this.runSession=a,this.semaphore=o,this.runAgentTurn=s,this.clock=c}breakerFor(e){return this.circuitBreakers.forTarget(e??`default`)}async runTask(e,t){this.assertCircuit(e.input.subagent);let n=await this.register(e);return this.runScheduled(n.id,t)}assertCircuit(e){if(this.breakerFor(e).isOpen())throw new a(`Circuit breaker is open due to repeated failures. Try again later.`,`circuit_open`)}async runScheduled(e,t){return this.semaphore.run(()=>this.executeToCompletion(e,t),t)}async isCancelled(e){return(await this.taskStore.get(e))?.status===`cancelled`}async register(e){let t=await this.taskStore.create(e.input,this.retryPolicy.maxAttempts);return this.hookRegistry.emit(`task.created`,{task:t}),t}async startTask(e){this.assertCircuit(e.input.subagent);let t=await this.register(e),n=this.runScheduled(t.id).then(()=>void 0,async e=>{await this.taskStore.update(t.id,{status:`failed`,error:{code:`EXECUTION_FAILED`,message:e instanceof Error?e.message:String(e),retriable:!1},completedAt:this.clock.now()}).catch(()=>{})});return{id:t.id,completion:n}}async executeToCompletion(e,t){let n=await this.taskStore.get(e);if(!n)return{taskId:e,status:`failed`,error:{code:`TASK_NOT_FOUND`,message:`Task not found: ${e}`,retriable:!1}};let r=n.attempts+1;try{await this.taskStore.update(e,{status:`running`,attempts:r}),this.hookRegistry.emit(`task.started`,{task:{...n,status:`running`},agent:n.input.subagent??`default`});let i;if(n.input.kind===`swarm_member`&&this.runAgentTurn){let e=n.input,r=await this.runAgentTurn({agentId:e.subagent??`agent`,prompt:e.prompt,systemPrompt:e.systemPrompt,tools:e.tools,coreTools:e.coreTools,model:e.model,maxToolTurns:e.maxToolTurns,thinkingLevel:e.thinkingLevel,maxTokens:e.maxTokens,temperature:e.temperature,sessionId:e.sessionId,depth:e.depth,parentTaskId:e.parentTaskId,signal:t});i={text:r.text,sessionId:n.input.sessionId??``,tokenUsage:r.tokenUsage,durationMs:r.durationMs,messages:r.messages,handoff:r.handoff}}else{let r=n.input;i=await this.runSession({prompt:r.prompt,sessionId:r.sessionId,sessionMode:n.sessionPolicy,agentName:r.subagent,slot:r.slot,model:r.model,category:r.category,depth:r.depth,parentTaskId:r.parentTaskId,taskId:e,signal:t,readOnly:r.mode===`background`,systemPrompt:r.systemPrompt,tools:r.tools,thinkingLevel:r.thinkingLevel,maxTokens:r.maxTokens,temperature:r.temperature,maxToolTurns:r.maxToolTurns})}if(await this.isCancelled(e))return{taskId:e,status:`cancelled`};let a={text:i.text,tokenUsage:i.tokenUsage,durationMs:i.durationMs,...i.messages?{messages:i.messages}:{},...i.handoff?{handoff:i.handoff}:{}};return await this.taskStore.update(e,{status:`completed`,output:a,sessionId:i.sessionId,completedAt:this.clock.now()}),this.breakerFor(n.input.subagent).success(),this.hookRegistry.emit(`task.completed`,{task:{...n,status:`completed`,output:a},result:a}),{taskId:e,status:`completed`,output:a}}catch(r){let i=r instanceof Error?r.message:String(r);if(await this.isCancelled(e))return{taskId:e,status:`cancelled`};if(this.retryPolicy.shouldRetry(n.attempts)&&!t?.aborted&&(await g(this.retryPolicy.getBackoff(n.attempts),t),!t?.aborted))return this.executeToCompletion(e,t);this.breakerFor(n.input.subagent).failure();let a={code:`EXECUTION_FAILED`,message:i,retriable:!1};return await this.taskStore.update(e,{status:`failed`,error:a,completedAt:this.clock.now()}),this.hookRegistry.emit(`task.failed`,{task:{...n,status:`failed`},error:a}),{taskId:e,status:`failed`,error:a}}}};function g(e,t){return t?.aborted?Promise.resolve():new Promise(n=>{let r,i=()=>{clearTimeout(r),n()};r=setTimeout(()=>{t?.removeEventListener(`abort`,i),n()},e),t?.addEventListener(`abort`,i,{once:!0})})}var _=class{constructor(e,t,n=i){this.taskStore=e,this.abortTask=t,this.clock=n}async getOutput(e){let t=await this.taskStore.get(e);return t?t.status===`completed`?{ok:!0,value:{status:`completed`,output:t.output?.text}}:t.status===`failed`?{ok:!1,error:t.error?.message??`Task failed`}:{ok:!0,value:{status:t.status}}:{ok:!1,error:`Task not found id: ${e}`}}async cancel(e){let t=await this.taskStore.get(e);return t?t.status===`completed`||t.status===`failed`||t.status===`cancelled`?{ok:!1,error:`Task already in terminal state: ${t.status}, id: ${e}`}:(await this.taskStore.update(e,{status:`cancelled`,completedAt:this.clock.now()}),this.abortTask&&this.abortTask(e),{ok:!0,value:void 0}):{ok:!1,error:`Task not found id: ${e}`}}},v=class{taskStore;executor;backgroundManager;hookRegistry;circuitBreakers;delegationGate;runSession;maxDelegationDepth;abortTask;fanOutCounts=new Map;maxFanOutPerParent;heldBackgroundSlots=new Set;constructor(e){let{hookRegistry:t,runSession:n,runAgentTurn:r,abortTask:a,workflowConfig:o}=e,c=o?.orchestration,u=e.maxActiveTasks??c?.maxActiveTasks??10,d=e.maxStoredTasks??c?.maxStoredTasks,p=e.maxDelegationDepth??c?.maxDelegationDepth??1;this.hookRegistry=t,this.runSession=n,this.maxDelegationDepth=p,this.maxFanOutPerParent=e.maxFanOutPerParent??c?.maxFanOutPerParent??Math.max(1,Math.floor(u/2)),this.abortTask=a;let g=e.clock??i;this.taskStore=new s(d,g);let v=l.fromWorkflowOptions(o);this.circuitBreakers=f.fromWorkflowOptions(o,g),this.delegationGate=new m(u),this.executor=new h(this.taskStore,t,v,this.circuitBreakers,n,this.delegationGate,r,g),this.backgroundManager=new _(this.taskStore,a,g)}dumpConfig(){return{maxActiveTasks:this.delegationGate.capacity,maxFanOutPerParent:this.maxFanOutPerParent,maxDelegationDepth:this.maxDelegationDepth,maxStoredTasks:this.taskStore.maxStoredTasks}}dispatchTask=async t=>{let{childDepth:n,exceeded:r}=e(t.depth,this.maxDelegationDepth);if(r)return b(`Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`);let i={prompt:t.prompt,subagent:t.subagent,category:t.category,sessionId:t.sessionId,sessionMode:t.sessionMode??`ephemeral`,mode:t.mode,slot:t.slot,model:t.model,depth:n,...t.parentTaskId===void 0?{}:{parentTaskId:t.parentTaskId}};return this.dispatchUnit(i,t.signal)};async dispatchUnit(e,t){let n={input:e};if((e.mode??`sync`)===`background`){let t=e.parentTaskId;if(t!==void 0&&!this.acquireFanOutSlot(t))return b(`Fan-out limit (${this.maxFanOutPerParent}) reached for parent task "${t}" — wait for in-flight subtasks to complete before delegating more.`);let r=t!==void 0;return x(async()=>{let{id:e,completion:i}=await this.executor.startTask(n).catch(e=>{throw r&&this.releaseFanOutSlot(t),e});return r&&(this.heldBackgroundSlots.add(e),i.finally(()=>{this.releaseBackgroundSlot(e,t)})),{id:e,status:`pending`,output:`Background task created: ${e}`}})}if(!this.acquireFanOutSlot(e.parentTaskId))return b(`Fan-out limit (${this.maxFanOutPerParent}) reached for parent task "${e.parentTaskId}" — wait for in-flight subtasks to complete before delegating more.`);try{let e=await this.executor.runTask(n,t);return e.status===`completed`?y({id:e.taskId,status:e.status,output:e.output?.text}):b(e.error?.message??`Unknown error`)}catch(e){return b(e)}finally{this.releaseFanOutSlot(e.parentTaskId)}}callAgent=async(t,n,r)=>{let{childDepth:i,exceeded:a}=e(r?.depth,this.maxDelegationDepth);if(a)return b(`Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`);let o=this.circuitBreakers.forTarget(t);return o.isOpen()?b(`Circuit breaker is open due to repeated failures. Try again later.`):this.acquireFanOutSlot(r?.parentTaskId)?this.delegationGate.run(async()=>{try{let e=await this.runSession({prompt:n,sessionMode:`ephemeral`,agentName:t,slot:r?.slot,model:r?.model,depth:i,parentTaskId:r?.parentTaskId,signal:r?.signal});return o.success(),y(e.text)}catch(e){return o.failure(),b(e)}},r?.signal).finally(()=>{this.releaseFanOutSlot(r?.parentTaskId)}):b(`Fan-out limit (${this.maxFanOutPerParent}) reached for parent task "${r?.parentTaskId}" — wait for in-flight subtasks to complete before delegating more.`)};async runAgentTurn(e){let t={input:{kind:`swarm_member`,prompt:e.prompt,subagent:e.agentId,systemPrompt:e.systemPrompt,tools:e.tools,coreTools:e.coreTools,model:e.model,maxToolTurns:e.maxToolTurns,thinkingLevel:e.thinkingLevel,maxTokens:e.maxTokens,temperature:e.temperature,sessionMode:`ephemeral`,sessionId:e.sessionId,depth:e.depth,parentTaskId:e.parentTaskId}},n=await this.executor.runTask(t,e.signal);if(n.status===`completed`)return{agentId:e.agentId,text:n.output?.text??``,messages:n.output?.messages,handoff:n.output?.handoff,tokenUsage:n.output?.tokenUsage,durationMs:n.output?.durationMs??0};throw Error(n.error?.message??`Swarm member turn failed: ${n.status}`)}getTask=async e=>{let t=await this.taskStore.get(e);return t?y({id:t.id,status:t.status,prompt:t.input.prompt,output:t.output?.text,error:t.error?.message}):b(`Task not found: ${e}`)};listTasks=async e=>{let t=e&&e!==`all`?{status:e}:void 0;return y((await this.taskStore.list(t)).map(e=>({id:e.id,prompt:e.input.prompt,status:e.status})))};updateTask=async(e,t)=>{let n=await this.taskStore.get(e);if(!n)return b(`Task not found: ${e}`);if(t===`cancel`){let t=await this.backgroundManager.cancel(e);return t.ok?(await this.hookRegistry.emit(`task.cancelled`,{taskId:e}),y(`Task ${e} cancelled`)):b(t.error)}if(t===`retry`){if(n.status!==`failed`)return b(`Can only retry failed tasks. Current status: ${n.status}`);let e=await this.dispatchUnit(n.input);return e.ok?y(e.value.output??`Retry completed`):b(e.error)}return b(`Unknown action: ${t}`)};getBackgroundOutput=async e=>this.backgroundManager.getOutput(e);cancelBackground=async e=>{let t=await this.backgroundManager.cancel(e);if(t.ok){let t=await this.taskStore.get(e);this.releaseBackgroundSlot(e,t?.input.parentTaskId)}return t};async dispose(){this.circuitBreakers.resetAll(),this.fanOutCounts.clear(),this.heldBackgroundSlots.clear();let e=await this.taskStore.list();for(let t of e)if(t.status===`pending`||t.status===`running`)try{this.abortTask?.(t.id)}catch{}await this.taskStore.clear(),this.delegationGate.drain()}acquireFanOutSlot(e){if(e===void 0)return!0;let t=this.fanOutCounts.get(e)??0;return t>=this.maxFanOutPerParent?!1:(this.fanOutCounts.set(e,t+1),!0)}releaseFanOutSlot(e){if(e===void 0)return;let t=this.fanOutCounts.get(e);t!==void 0&&(t<=1?this.fanOutCounts.delete(e):this.fanOutCounts.set(e,t-1))}releaseBackgroundSlot(e,t){this.heldBackgroundSlots.delete(e)&&this.releaseFanOutSlot(t)}};function y(e){return{ok:!0,value:e}}function b(e){return{ok:!1,error:S(e)}}async function x(e){try{return y(await e())}catch(e){return b(e)}}function S(e){return e instanceof Error?e.message:String(e)}var C=class extends t{depth;maxDepth;constructor(e,t){super(`Handoff depth ${e} exceeds max ${t}`,{code:`SWARM_HANDOFF_DEPTH_EXCEEDED`}),this.name=`HandoffDepthError`,this.depth=e,this.maxDepth=t}},w=class extends t{constructor(e){super(e,{code:`SWARM_ROUTING_ERROR`}),this.name=`RoutingError`}},T=class extends t{agentId;constructor(e){super(`Agent "${e}" not found in swarm`,{code:`SWARM_AGENT_NOT_FOUND`}),this.name=`AgentNotFoundError`,this.agentId=e}},E=class extends t{constructor(e){super(e,{code:`SWARM_CONFIG_ERROR`}),this.name=`SwarmConfigError`}},D=class{config;roundRobinIndex=0;constructor(e){if(e.strategy===`llm`&&!e.customRouter)throw new w(`Routing strategy 'llm' requires a customRouter (inject the real LLM routing call).`);this.config=e}async route(e,t){let{strategy:n}=this.config;switch(n){case`rule`:return this.routeByRule(e,t);case`round-robin`:return this.routeRoundRobin(t);case`random`:return this.routeRandom(t);case`llm`:return this.routeByLlm(e,t);default:throw new w(`Unknown routing strategy: ${n}`)}}routeByRule(e,t){let n=this.config.rules??[],r=e.toLowerCase(),i=[...n].sort((e,t)=>(t.priority??0)-(e.priority??0));for(let e of i)if(this.matchRule(e,r)){let n=t.find(t=>t.id===e.agentId);if(n)return{agentId:e.agentId,reason:`Matched rule for "${n.name}"`,confidence:1}}return this.fallback(t,`No rule matched`)}routeRoundRobin(e){let t=e[this.roundRobinIndex%e.length];return this.roundRobinIndex++,{agentId:t.id,reason:`Round-robin selection (index ${this.roundRobinIndex-1})`,confidence:1}}routeRandom(e){let t=this.config.random?.random??Math.random;return{agentId:e[Math.floor(t()*e.length)].id,reason:`Random selection`,confidence:1/e.length}}async routeByLlm(e,t){let{customRouter:n}=this.config;if(!n)throw new w(`Routing strategy 'llm' requires a customRouter.`);return n(e,t)}fallback(e,t){let n=this.config.fallbackAgentId??e[0]?.id;if(!n)throw new w(`${t} and no fallback agent configured`);return{agentId:n,reason:`${t} — using fallback agent`,confidence:0}}matchRule(e,t){return e.match instanceof RegExp?e.match.test(t):e.match.some(e=>t.includes(e.toLowerCase()))}};async function O(e,t,n,r,i){e.emit({type:`agent.start`,agentId:t});let a=e.clock.now();try{let o=await e.createStepRunner(e.config.agents.get(t),n,i),s=e.clock.now()-a;return e.emit({type:`agent.end`,agentId:t,durationMs:s}),r.push({agentId:t,output:o,durationMs:s}),o}catch(n){throw e.emit({type:`error`,agentId:t,error:n instanceof Error?n:Error(String(n))}),n}}var k=class{strategies=new Map;register(e){if(this.strategies.has(e.name))throw Error(`Orchestration strategy "${e.name}" is already registered`);return this.strategies.set(e.name,e),()=>{this.strategies.delete(e.name)}}unregister(e){return this.strategies.delete(e)}get(e){return this.strategies.get(e)}has(e){return this.strategies.has(e)}names(){return[...this.strategies.keys()]}};function A(e,t,n){let i=t.map(e=>`- "${e.id}": ${e.name} — ${e.description}`).join(`
|
|
2
|
+
`),a=t.map(e=>e.id);return{name:`handoff_to_agent`,description:`Transfer control to another agent in the swarm. Available targets:\n${i}`,parameters:r.object({target_agent_id:r.string().describe(`The ID of the agent to hand off to. Must be one of: ${a.join(`, `)}`),reason:r.string().describe(`Why you are transferring to this agent — will be provided as context.`),summary:r.string().optional().describe(`Optional summary of work done so far to provide context to the target agent.`)}),execute:async t=>{let{target_agent_id:r,reason:i,summary:o}=t.params;return a.includes(r)?(n({from:e,to:r,reason:o?`${i}\n\nContext: ${o}`:i}),{content:[{type:`text`,text:`Handoff initiated to "${r}". Reason: ${i}`}]}):{content:[{type:`text`,text:`Invalid target agent "${r}". Available targets: ${a.join(`, `)}`}],isError:!0}}}}function j(e,t){let n=t.get(e.from),r=t.get(e.to);return n?r?n.kind===`agent`&&n.handoffTargets&&n.handoffTargets.length>0&&!n.handoffTargets.includes(e.to)?{valid:!1,error:`Agent "${e.from}" is not allowed to handoff to "${e.to}". Allowed: [${n.handoffTargets.join(`, `)}]`}:{valid:!0}:{valid:!1,error:`Target agent "${e.to}" not found`}:{valid:!1,error:`Source agent "${e.from}" not found`}}const M={name:`handoff`,async execute(e,t){let n=[...t.config.agents.values()],r=t.config.entryAgentId??n[0]?.id;if(!r)return{steps:[],output:``};let i=t.config.maxHandoffDepth??10,a=r,o=e,s=[];for(let e=0;e<i&&!t.signal.aborted;e++){let e=t.config.agents.get(a);if(!e)throw new T(a);let r=n.filter(e=>e.id!==a);if(e.kind===`agent`&&e.handoffTargets&&e.handoffTargets.length>0){let t=e.handoffTargets;r=r.filter(e=>t.includes(e.id))}let i=r.length>0?{source:`core`,name:`handoff_to_agent`,context:{from:a,allowedTargets:r.map(e=>({id:e.id,name:e.name,description:e.description}))}}:null,c=await O(t,a,o,s,{signal:t.signal,coreTools:i?[i]:void 0}),l=c.handoff;if(l){let e=l;if(!j(e,new Map(n.map(e=>[e.id,e]))).valid)return{steps:s,output:c.text};t.emit({type:`handoff`,from:e.from,to:e.to,reason:e.reason}),a=e.to,o=e.reason;continue}return{steps:s,output:c.text}}throw new C(i,i)}},N={name:`sequential`,async execute(e,t){let n=t.config.pipeline??[...t.config.agents.values()].map(e=>e.id),r=[],i=e;for(let e of n){if(t.signal.aborted)break;t.config.agents.has(e)&&(i=(await O(t,e,i,r,{signal:t.signal})).text,t.emit({type:`pipeline.step`,step:r.length-1,agentId:e}))}let a=r[r.length-1];return a?{steps:r,output:a.output.text}:{steps:[],output:``}}};async function P(e,t){let{cap:n,executor:r,signal:i,onProgress:a}=t;if(e.length===0)return;let o=Number.isFinite(n)&&n>=1?Math.floor(n):1,s=e.length,c=[...e],l=new Set,u=0,d=0,f,p=!1,m=new AbortController,h=()=>m.abort();i&&(i.aborted?m.abort():i.addEventListener(`abort`,h,{once:!0}));try{for(;c.length>0||l.size>0;){for((m.signal.aborted||p)&&(c.length=0);l.size<o&&c.length>0;){let e=c.shift(),t=d++,n;n=(async()=>{try{await r(e,t,m.signal)}catch(e){p||=(f=e,!0),m.abort()}finally{l.delete(n),u++,a?.(u,s)}})(),l.add(n)}l.size>0&&await Promise.race(l)}}finally{l.size>0&&await Promise.allSettled(l),i&&i.removeEventListener(`abort`,h)}if(p)throw f}const F={name:`parallel`,async execute(e,t){let n=[...t.config.agents.values()],r=t.config.maxConcurrency??n.length,i=n.map(t=>({agentId:t.id,input:e})),a=Array(i.length);t.emit({type:`parallel.fanOut`,agentIds:n.map(e=>e.id)}),await P(i,{cap:r,executor:async(e,n)=>{if(!t.config.agents.has(e.agentId))return;let r=[];await O(t,e.agentId,e.input,r,{signal:t.signal}),a[n]=r[0]},signal:t.signal,onProgress:(e,n)=>{t.emit({type:`parallel.fanIn`,completedCount:e,totalCount:n})}});let o=a.filter(e=>e!==void 0);return{steps:o,output:o.map(e=>`## ${e.agentId}\n${e.output.text}`).join(`
|
|
3
3
|
|
|
4
|
-
`)}}},
|
|
4
|
+
`)}}},I=n(`otto:orchestrator:strategies:hierarchical`),L=r.object({description:r.string(),assignedTo:r.string().optional()});function R(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=L.safeParse(n);e.success&&t.push(e.data)}return t}function z(e){try{let t=R(JSON.parse(e.trim()));if(t.length>0)return t}catch{}let t=e.match(/\[[\s\S]*\]/);if(t)try{let e=R(JSON.parse(t[0]));if(e.length>0)return e}catch{}return I.warn({textPreview:e.slice(0,200)},`hierarchical supervisor plan parse failed, degrading to single task`),[]}const B={name:`hierarchical`,async execute(e,t){let n=t.config.supervisorId??[...t.config.agents.values()][0]?.id??``;if(!n)return{steps:[],output:``};let r=t.config.agents.get(n);if(!r||r.kind!==`agent`)return{steps:[],output:``};t.emit({type:`agent.start`,agentId:n}),t.emit({type:`hierarchy.delegate`,supervisor:n,worker:``,task:`planning`});let i=t.clock.now(),a=await t.createStepRunner(r,`You are the supervisor. Break down this task into subtasks:\n\n${e}\n\nFor each subtask, specify:\n1. A clear description\n2. Which agent should execute it (choose from: ${[...t.config.agents.values()].map(e=>e.id).join(`, `)})\n\nRespond with a JSON array of {description, assignedTo}. Output only the JSON array, no other text.`,{signal:t.signal}),o=t.clock.now()-i;t.emit({type:`agent.end`,agentId:n,durationMs:o});let s=[{agentId:n,output:a,durationMs:o}],c=z(a.text);c.length===0&&(c=[{description:e,assignedTo:void 0}]);let l=[],u=[...t.config.agents.values()].find(e=>e.id!==n)?.id??n,d=c.map(e=>({...e,agentId:e.assignedTo??u}));await P(d,{cap:t.config.maxConcurrency??d.length,executor:async e=>{try{let r=t.config.agents.get(e.agentId);if(!r)return;t.emit({type:`agent.start`,agentId:e.agentId}),t.emit({type:`hierarchy.delegate`,supervisor:n,worker:e.agentId,task:e.description});let i=t.clock.now(),a=await t.createStepRunner(r,e.description,{signal:t.signal}),o=t.clock.now()-i;t.emit({type:`agent.end`,agentId:e.agentId,durationMs:o}),l.push({task:e,agentId:e.agentId,output:a,durationMs:o})}catch(n){throw t.emit({type:`error`,agentId:e.agentId,error:n instanceof Error?n:Error(String(n))}),n}},signal:t.signal});for(let e of l)s.push({agentId:e.agentId,output:e.output,durationMs:e.durationMs});let f=l.map(e=>`## ${e.task.description} (by ${e.agentId})\n${e.output.text}`),p=[`The subtasks have been completed. Here are the results:`,``,...f,``,`Synthesize these results into a final coherent response for the original task:`,e].join(`
|
|
5
5
|
`);if(t.signal.aborted)return{steps:s,output:f.join(`
|
|
6
6
|
|
|
7
|
-
`)};t.emit({type:`agent.start`,agentId:n});let m=
|
|
7
|
+
`)};t.emit({type:`agent.start`,agentId:n});let m=t.clock.now(),h=await t.createStepRunner(r,p,{signal:t.signal}),g=t.clock.now()-m;return t.emit({type:`agent.end`,agentId:n,durationMs:g}),s.push({agentId:n,output:h,durationMs:g}),{steps:s,output:h.text}}},V={name:`router`,async execute(e,t){if(!t.router)throw new E(`Router not configured`);let n=[...t.config.agents.values()],r=await t.router.route(e,n);if(!t.config.agents.has(r.agentId))throw new T(r.agentId);t.emit({type:`routing.decision`,decision:r});let i=[];return{steps:i,output:(await O(t,r.agentId,e,i,{signal:t.signal})).text}}};function H(){let e=new k;return e.register(M),e.register(N),e.register(F),e.register(B),e.register(V),e}var U=class{config;agents;router;registry;clock;constructor(e){this.validateConfig(e),this.config=e,this.agents=new Map,this.clock=e.clock??i;for(let t of e.agents)this.agents.set(t.id,t);this.router=e.router?new D(e.router):null,this.registry=H()}getAgents(){return[...this.agents.values()]}getAgent(e){return this.agents.get(e)}registerStrategy(e){return this.registry.register(e)}getStrategyNames(){return this.registry.names()}emitEvent(e){this.config.onSwarmEvent?.(e)}buildStrategyContext(e){return{createStepRunner:(t,n,r)=>this.executeMemberTurn(t,n,r?.signal??e,r?.coreTools),emit:e=>this.emitEvent(e),router:this.router,signal:e,clock:this.clock,config:{name:this.config.name,agents:this.agents,entryAgentId:this.config.entryAgentId,pipeline:this.config.pipeline,supervisorId:this.config.supervisorId,maxHandoffDepth:this.config.maxHandoffDepth,maxConcurrency:this.config.maxConcurrency}}}async run(e,t){let n=t?.signal??new AbortController().signal,r=this.clock.now(),i=e=>this.emitEvent(e);i({type:`swarm.start`,pattern:this.config.pattern,agentCount:this.agents.size});let a=this.registry.get(this.config.pattern);if(!a)throw new E(`Unknown pattern: "${this.config.pattern}". Registered strategies: ${this.registry.names().join(`, `)}`);try{let t=this.buildStrategyContext(n),o=await a.execute(e,t);return i({type:`swarm.end`,totalDurationMs:this.clock.now()-r}),{pattern:this.config.pattern,steps:o.steps,output:o.output,durationMs:this.clock.now()-r}}catch(e){throw i({type:`swarm.end`,totalDurationMs:this.clock.now()-r}),e}}async executeMemberTurn(e,t,n,r){if(e.kind===`team`)return r?.length&&this.config.onSwarmEvent?.({type:`error`,agentId:e.id,error:Error(`Nested team "${e.id}" does not support core tools (${r.map(e=>e.name).join(`, `)}); descriptors dropped`)}),e.runNested(t,n);let i=e,a=await this.config.runAgentTurn({agentId:i.id,prompt:t,systemPrompt:i.systemPrompt,tools:i.tools,coreTools:r,model:i.model?.id,maxToolTurns:i.maxToolTurns,thinkingLevel:i.thinkingLevel,maxTokens:i.maxTokens,temperature:i.temperature,sessionId:this.config.runId,depth:this.config.depth,parentTaskId:this.config.parentTaskId,signal:n});return{agentId:a.agentId,messages:a.messages??[],text:a.text,handoff:a.handoff,tokenUsage:a.tokenUsage??{input:0,output:0,cacheRead:0},durationMs:a.durationMs}}validateConfig(e){if(!e.name)throw new E(`Swarm name is required`);if(!e.agents||e.agents.length===0)throw new E(`At least one agent is required`);if(!e.runAgentTurn)throw new E(`runAgentTurn factory is required`);let t=new Set;for(let n of e.agents){if(t.has(n.id))throw new E(`Duplicate agent ID: "${n.id}"`);t.add(n.id)}for(let n of e.agents)if(n.kind===`agent`&&n.handoffTargets){for(let e of n.handoffTargets)if(!t.has(e))throw new E(`Agent "${n.id}" references unknown handoff target "${e}"`)}}};function W(e){return new U(e)}export{T as AgentNotFoundError,d as CircuitBreaker,M as HANDOFF_STRATEGY,B as HIERARCHICAL_STRATEGY,C as HandoffDepthError,v as Orchestrator,F as PARALLEL_STRATEGY,V as ROUTER_STRATEGY,l as RetryPolicy,w as RoutingError,N as SEQUENTIAL_STRATEGY,k as StrategyRegistry,U as Swarm,E as SwarmConfigError,D as SwarmRouter,a as TaskRejectedError,s as TaskStore,H as createDefaultStrategyRegistry,A as createHandoffTool,W as createSwarm,P as runConcurrent,j as validateHandoff};
|
|
8
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/types.ts","../src/task-store.ts","../src/retry.ts","../src/semaphore.ts","../src/executor.ts","../src/background-manager.ts","../src/orchestrator.ts","../src/swarm/errors.ts","../src/swarm/router.ts","../src/swarm/strategy.ts","../src/swarm/handoff.ts","../src/swarm/strategies/handoff.ts","../src/swarm/strategies/sequential.ts","../src/swarm/concurrent.ts","../src/swarm/strategies/parallel.ts","../src/swarm/strategies/hierarchical.ts","../src/swarm/strategies/router.ts","../src/swarm/strategies/index.ts","../src/swarm/swarm.ts"],"sourcesContent":["import type { HookRegistry } from '@x-otto/hooks'\nimport type {\n ModelSlotName,\n SessionMode,\n TaskMode,\n TaskStatus,\n WorkflowOptions,\n} from '@x-otto/orchestration-contracts'\nimport type { RunSessionOptions, RunSessionResult } from './executor'\n\nexport type { TaskStatus } from '@x-otto/orchestration-contracts'\nexport type { WorkflowOptions } from '@x-otto/orchestration-contracts'\n\n/**\n * 时钟端口(D13:引擎核心禁裸 Date.now,经注入时钟取时间戳)。\n * 形状与 `@x-otto/agent` 的 `ClockPort` 结构兼容(`{ now(): number }`),\n * 便于宿主把同一时钟注入 agent 与 orchestrator 两套确定性重放端口。\n */\nexport interface Clock {\n now(): number\n}\n\n/** 系统缺省时钟(D13):非确定性重放下由测试以 fake clock 替换。 */\nexport const systemClock: Clock = { now: () => Date.now() }\n\n/** 工具定义(本地 minimal type,避免 orchestrator 核心依赖 @x-otto/interchange)。 */\nexport interface AgentToolDef {\n name: string\n description: string\n parameters: Record<string, unknown>\n}\n\n/** handoff 目标的纯数据信息(RFC-332 M1:跨边界只传可序列化数据)。 */\nexport interface HandoffTargetInfo {\n id: string\n name: string\n description: string\n}\n\n/**\n * RFC-332 M1:swarm core 工具的纯数据描述符。\n *\n * `extraTools`(AgentToolDef 元数据投影)无法承载 core 工具的执行闭包——旧路径在 leaf\n * 被补成 throw stub(模型可见但必坏)。本描述符替代之:orchestrator 策略只声明\n * 「请 leaf 暴露哪个已注册 core 能力 + 可序列化上下文」,coding leaf 的受限 core\n * resolver 据此构造真实 `AgentTool`。描述符不得含 execute/函数/闭包。\n *\n * 当前唯一注册名是 `handoff_to_agent`;新增 core 工具须同步扩展 leaf resolver 白名单。\n */\nexport interface CoreToolDescriptor {\n source: 'core'\n name: 'handoff_to_agent'\n context: {\n /** 发起方 member id——leaf 校验其与当前 turn 的 agentId 一致(origin 校验)。 */\n from: string\n /** 策略计算后的目标白名单;leaf 只能收窄不能放宽。空数组 = 不暴露工具。 */\n allowedTargets: readonly HandoffTargetInfo[]\n }\n}\n\n/** 思考深度(本地 minimal type,避免 orchestrator 核心依赖 @x-otto/ai)。 */\nexport type ThinkingLevel = 'low' | 'medium' | 'high'\n\n/** swarm member turn 入参(B+ 门禁①:经 TaskExecutor 治理)。 */\nexport interface AgentTurnInput {\n agentId: string\n prompt: string\n systemPrompt?: string\n tools?: AgentToolDef[]\n /**\n * @deprecated RFC-332:额外工具的元数据投影无法承载执行闭包(leaf 曾以 throw stub 补洞)。\n * core 工具(handoff)改走 `coreTools` 描述符 + leaf 受限 resolver;本字段在 M2 策略\n * 切换后删除。leaf 对该字段 fail closed(忽略并诊断),不再生成 stub。\n */\n extraTools?: AgentToolDef[]\n /** RFC-332 M1:core 工具纯数据描述符——leaf 的受限 core resolver 据此构造真实工具。 */\n coreTools?: CoreToolDescriptor[]\n model?: string\n maxToolTurns?: number\n thinkingLevel?: ThinkingLevel\n maxTokens?: number\n temperature?: number\n signal?: AbortSignal\n /** swarm 执行标识(用于权限/审计归属,映射到 toolHookExecutor.sessionId)。 */\n sessionId?: string\n /** 委托深度(递归护栏,映射到 Agent 构造器)。 */\n depth?: number\n /**\n * RFC-371 M-A:父任务锚点(透传面)。swarm member turn 的 TaskInput.parentTaskId\n * 透传至此,经 AgentTurnInput → Agent 构造器 → ToolExecutor 回流 fan-out 闸。\n */\n parentTaskId?: string\n}\n\n/** swarm member turn 结果(B+ 门禁①)。 */\nexport interface AgentTurnResult {\n agentId: string\n text: string\n /** 完整消息历史(handoff/hierarchical 策略需要)。 */\n messages?: unknown[]\n /** handoff 请求(handoff 策略需要)。 */\n handoff?: { from: string; to: string; reason: string }\n tokenUsage?: { input: number; output: number; cacheRead: number }\n durationMs: number\n}\n\nexport interface TaskInput {\n /** 任务类别判别字段:'task' 走标准 Session 创建,'swarm_member' 走轻量 Agent 创建。\n * 缺省等价于 'task'(向后兼容 task_delegate/agent_call 路径)。 */\n kind?: 'task' | 'swarm_member'\n /** 发给 subagent 的提示 */\n prompt: string\n /** 指定 agent 名称 — 对齐 task_delegate.subagent / agent_call.agent */\n subagent?: string\n /** 任务类别 — 对齐 task_delegate.category */\n category?: string\n /** 复用的 session ID */\n sessionId?: string\n /** session 策略 — 对齐 task_delegate.sessionMode */\n sessionMode?: SessionMode\n /** 执行模式 — 对齐 task_delegate.mode */\n mode?: TaskMode\n /** 模型槽位 — 对齐 task_delegate.slot / agent_call.slot */\n slot?: ModelSlotName\n /** 显式模型 id(subagent 按能力选型)——优先于 slot。 */\n model?: string\n /** 该任务所处委托深度(root 派发的任务 depth=1)。 */\n depth?: number\n /**\n * RFC-371 S3:发起此任务的父任务 id(用于 per-parent 活跃扇出计数)。\n * 缺省 undefined = root 层委派。由 `dispatchTask` 从 `args.parentTaskId` 透传,\n * 供 orchestrator 在任务终态时释放该 parent 的活跃计数。\n */\n parentTaskId?: string\n // ── swarm member turn 扩展字段(全部可选,向后兼容 task_delegate/agent_call) ──\n /** swarm 成员自定义 system prompt(覆盖默认)。 */\n systemPrompt?: string\n tools?: AgentToolDef[]\n /** 本轮额外工具(如 handoff 工具)。@deprecated RFC-332:见 AgentTurnInput.extraTools。 */\n extraTools?: AgentToolDef[]\n /** RFC-332 M1:core 工具纯数据描述符(swarm_member 专用)。 */\n coreTools?: CoreToolDescriptor[]\n thinkingLevel?: ThinkingLevel\n maxTokens?: number\n temperature?: number\n maxToolTurns?: number\n}\n\nexport interface TaskOutput {\n text: string\n summary?: string\n tokenUsage?: { input: number; output: number; cacheRead: number }\n durationMs?: number\n // ── swarm member turn 专用(RFC-332 M1:handoff 结果是纯数据,经 Task 链路回传) ──\n /** 完整消息历史(handoff/hierarchical 策略消费;非 swarm 任务恒缺省)。 */\n messages?: unknown[]\n /** leaf 捕获的 handoff intent(orchestrator 策略二次验证后才切换)。 */\n handoff?: { from: string; to: string; reason: string }\n}\n\nexport interface TaskError {\n code: string\n message: string\n retriable: boolean\n}\n\nexport interface Task {\n id: string\n status: TaskStatus\n sessionPolicy: SessionMode\n sessionId?: string\n attempts: number\n maxAttempts: number\n input: TaskInput\n output?: TaskOutput\n error?: TaskError\n createdAt: number\n completedAt?: number\n}\n\nexport interface TaskUnit {\n input: TaskInput\n}\n\nexport interface TaskResult {\n taskId: string\n status: TaskStatus\n output?: TaskOutput\n error?: TaskError\n}\n\nexport class TaskRejectedError extends Error {\n constructor(\n message: string,\n readonly reason: 'circuit_open',\n ) {\n super(message)\n this.name = 'TaskRejectedError'\n }\n}\n\nexport interface OrchestratorOptions {\n hookRegistry: HookRegistry\n /** 由 App 注入:创建子 session → prompt → 提取输出文本(task_delegate/agent_call 路径)。 */\n runSession: (options: RunSessionOptions) => Promise<RunSessionResult>\n /** B+ 门禁①:swarm member turn 执行回调(经 TaskExecutor 获得治理,但用轻量 Agent 创建)。\n * 未提供时 runAgentTurn 回退到 runSession(兼容旧路径)。 */\n runAgentTurn?: (input: AgentTurnInput) => Promise<AgentTurnResult>\n /** 可选:外部 abort 回调 */\n abortTask?: (taskId: string) => void\n workflowConfig?: WorkflowOptions\n maxActiveTasks?: number\n /**\n * TaskStore 容量上限(默认 1000)。store 满时按「终态优先 + 最旧先弃」LRU\n * 驱逐已完成/失败/取消的任务档;pending/running 在飞任务绝不驱逐。治裸 Map 无界增长,\n * 确定性、无时钟依赖(区别于 TTL)。透传 `new TaskStore(maxStoredTasks)`。\n */\n maxStoredTasks?: number\n /** RFC-371 S3:per-parent 扇出上限的选项。 */\n maxFanOutPerParent?: number\n /** 委托深度上限(默认 1)。root(0)→child1 放行;depth1→child2>1 拒。swarm 深层可经此放宽。 */\n maxDelegationDepth?: number\n /** 时钟端口(D13)。缺省 systemClock,透传至 TaskStore/Executor/CircuitBreaker/BackgroundManager。 */\n clock?: Clock\n}\n","import type { Clock, Task, TaskInput, TaskStatus } from './types'\nimport { systemClock } from './types'\n\n/**\n * 内存任务档案:**单线程内存语义**——API 形态 async 是为未来\n * 换异步后端预留,但读-改-写(get → update merge → set)非原子。在 Node 单线程\n * 事件循环 + 纯内存 Map 下安全(无 await 横跨读写间隙);若替换为真实异步后端\n * (文件/网络),update 必须先加 CAS/版本号,否则 cancel 与终态写入会竞态覆写。\n */\nconst TERMINAL_STATUSES: ReadonlySet<TaskStatus> = new Set<TaskStatus>([\n 'completed',\n 'failed',\n 'cancelled',\n])\n\nexport class TaskStore {\n private readonly tasks = new Map<string, Task>()\n private nextId = 1\n\n /**\n * 容量上限(默认 1000)。store 只收 task_delegate 落库的真任务,但终态任务只增不减——\n * 故加「终态优先 LRU 驱逐」兜底治裸 Map 无界增长(确定性、无时钟依赖,区别于 TTL)。\n */\n private readonly maxStoredTasks: number\n private readonly clock: Clock\n\n constructor(maxStoredTasks = 1000, clock: Clock = systemClock) {\n this.maxStoredTasks = Math.max(1, maxStoredTasks)\n this.clock = clock\n }\n\n private generateId(): string {\n return `task_${this.clock.now()}_${this.nextId++}`\n }\n\n async create(input: TaskInput): Promise<Task> {\n this.evictForCapacity()\n\n const task: Task = {\n id: this.generateId(),\n status: 'pending',\n sessionPolicy: input.sessionMode ?? 'ephemeral',\n attempts: 0,\n maxAttempts: 3,\n input,\n createdAt: this.clock.now(),\n }\n\n this.tasks.set(task.id, task)\n return task\n }\n\n /** 清空全部任务档案(dispose 用)。单线程内存语义下同步清空,API 仍保持 async 形态。 */\n async clear(): Promise<void> {\n this.tasks.clear()\n }\n\n /**\n * 容量回收:新建前若已达上限,按「终态优先 + 最旧先弃」驱逐至腾出一席。\n * 驱逐优先级:仅终态(completed/failed/cancelled),按 completedAt ?? createdAt 升序(最旧先弃)。\n * pending/running 在飞任务绝不驱逐——若只剩在飞仍超上限,则越界保活 + warn(绝不丢在飞的活儿)。\n */\n private evictForCapacity(): void {\n let overflow = this.tasks.size - this.maxStoredTasks + 1\n if (overflow <= 0) {\n return\n }\n\n const terminalOldestFirst = [...this.tasks.values()]\n .filter((t) => TERMINAL_STATUSES.has(t.status))\n .sort((a, b) => (a.completedAt ?? a.createdAt) - (b.completedAt ?? b.createdAt))\n\n for (const task of terminalOldestFirst) {\n if (overflow <= 0) {\n break\n }\n this.tasks.delete(task.id)\n overflow--\n }\n\n if (overflow > 0) {\n console.warn(\n `[TaskStore] capacity ${this.maxStoredTasks} exceeded by ${overflow} in-flight task(s); ` +\n `no terminal tasks left to evict — keeping in-flight tasks (will exceed cap).`,\n )\n }\n }\n\n async get(id: string): Promise<Task | undefined> {\n return this.tasks.get(id)\n }\n\n async list(filter?: { status?: TaskStatus }): Promise<Task[]> {\n let result = [...this.tasks.values()]\n if (filter?.status) {\n result = result.filter((t) => t.status === filter.status)\n }\n return result\n }\n\n async update(\n id: string,\n patch: Partial<\n Pick<Task, 'status' | 'output' | 'error' | 'attempts' | 'completedAt' | 'sessionId'>\n >,\n ): Promise<void> {\n const task = this.tasks.get(id)\n if (!task) {\n throw new Error(`Task not found: ${id}`)\n }\n\n Object.assign(task, patch)\n }\n\n async delete(id: string): Promise<boolean> {\n return this.tasks.delete(id)\n }\n}\n","import type { WorkflowOptions } from '@x-otto/orchestration-contracts'\n\nimport type { Clock } from './types'\nimport { systemClock } from './types'\n\nexport interface RetryConfig {\n enabled: boolean\n maxAttempts: number\n backoffMs: number\n backoffMultiplier: number\n}\n\nconst DEFAULT_RETRY: RetryConfig = {\n enabled: true,\n maxAttempts: 3,\n backoffMs: 1000,\n backoffMultiplier: 2,\n}\n\nexport class RetryPolicy {\n private readonly config: RetryConfig\n\n constructor(config?: Partial<RetryConfig>) {\n this.config = { ...DEFAULT_RETRY, ...config }\n }\n\n shouldRetry(attempt: number): boolean {\n return this.config.enabled && attempt < this.config.maxAttempts\n }\n\n getBackoff(attempt: number): number {\n return this.config.backoffMs * this.config.backoffMultiplier ** (attempt - 1)\n }\n\n static fromWorkflowOptions(wf?: WorkflowOptions): RetryPolicy {\n const retry = wf?.retry\n\n return new RetryPolicy({\n enabled: retry?.enabled ?? true,\n maxAttempts: retry?.maxAttempts ?? 3,\n })\n }\n}\n\nexport interface CircuitBreakerConfig {\n enabled: boolean\n failureThreshold: number\n resetTimeoutMs: number\n}\n\nconst DEFAULT_CIRCUIT_BREAKER: CircuitBreakerConfig = {\n enabled: true,\n failureThreshold: 5,\n resetTimeoutMs: 60_000,\n}\n\nexport class CircuitBreaker {\n private readonly enabled: boolean\n private readonly failureThreshold: number\n private readonly resetTimeoutMs: number\n private readonly clock: Clock\n private consecutiveFailures = 0\n private openedAt: number | null = null\n\n constructor(config?: Partial<CircuitBreakerConfig>, clock: Clock = systemClock) {\n const resolvedConfig = { ...DEFAULT_CIRCUIT_BREAKER, ...config }\n\n this.enabled = resolvedConfig.enabled\n this.failureThreshold = resolvedConfig.failureThreshold\n this.resetTimeoutMs = resolvedConfig.resetTimeoutMs\n this.clock = clock\n }\n\n isOpen(): boolean {\n if (!this.enabled) {\n return false\n }\n if (this.openedAt === null) {\n return false\n }\n\n if (this.clock.now() - this.openedAt >= this.resetTimeoutMs) {\n this.openedAt = null\n this.consecutiveFailures = 0\n return false\n }\n\n return true\n }\n\n success(): void {\n this.consecutiveFailures = 0\n this.openedAt = null\n }\n\n failure(): void {\n this.consecutiveFailures++\n if (this.consecutiveFailures >= this.failureThreshold) {\n this.openedAt = this.clock.now()\n }\n }\n\n reset(): void {\n this.consecutiveFailures = 0\n this.openedAt = null\n }\n}\n\n/**\n * H5/RFC-016 步骤1:按 target(子代理名)分桶的熔断器。单例全局熔断器在并行委托下会把\n * 不相关 target 的失败计进同一个 consecutiveFailures——一个 flaky 子代理就能熔断全部委托。\n * 按 target 分桶后,各 target 独立计数/熔断,互不污染。\n */\nexport class CircuitBreakerRegistry {\n private readonly breakers = new Map<string, CircuitBreaker>()\n\n constructor(private readonly factory: () => CircuitBreaker) {}\n\n forTarget(target: string): CircuitBreaker {\n let breaker = this.breakers.get(target)\n if (!breaker) {\n breaker = this.factory()\n this.breakers.set(target, breaker)\n }\n return breaker\n }\n\n resetAll(): void {\n for (const breaker of this.breakers.values()) {\n breaker.reset()\n }\n }\n\n /** 每个 target 一个独立熔断器(生产路径)。 */\n static perTarget(\n config?: Partial<CircuitBreakerConfig>,\n clock: Clock = systemClock,\n ): CircuitBreakerRegistry {\n return new CircuitBreakerRegistry(() => new CircuitBreaker(config, clock))\n }\n\n /** 所有 target 共用同一个熔断器实例——保留旧的全局语义(测试/向后兼容用)。 */\n static single(breaker: CircuitBreaker): CircuitBreakerRegistry {\n return new CircuitBreakerRegistry(() => breaker)\n }\n\n static fromWorkflowOptions(\n wf?: WorkflowOptions,\n clock: Clock = systemClock,\n ): CircuitBreakerRegistry {\n const circuit = wf?.circuitBreaker\n return CircuitBreakerRegistry.perTarget(\n {\n enabled: circuit?.enabled ?? true,\n failureThreshold: circuit?.failureThreshold ?? 5,\n resetTimeoutMs: circuit?.timeoutMs ?? 60_000,\n },\n clock,\n )\n }\n}\n","/**\n * H5/RFC-016 步骤1:并发闸(信号量)。把委托并发上限做成可共享的单一对象——\n * callAgent 与 TaskExecutor 注入同一个实例,使 agent_call + task_delegate 走**同一个**全局\n * 上限(之前 callAgent 旁路 executor 的内部计数,无任何闸)。\n *\n * 计数同步、交接式释放(有等待者直接转交槽位,active 不减),无 TOCTOU。\n */\nfunction abortError(): Error {\n const err = new Error('Semaphore acquire aborted')\n err.name = 'AbortError'\n return err\n}\n\ninterface Waiter {\n resolve: () => void\n reject: (err: Error) => void\n cleanup: () => void\n}\n\nexport class Semaphore {\n private active = 0\n private readonly waiters: Waiter[] = []\n\n constructor(private readonly max: number) {}\n\n /**\n * 获取一个槽位:满则排队,空出后被 release 直接交接。\n *\n * 可选 `signal`:排队等待期间若 signal abort,则把该等待者从队列摘除并 reject(AbortError)——否则\n * 一个卡死的持票者永不 release 时,被 abort 的排队委托会**永久停在这里唤不醒**(RFC:委托信号量\n * 票泄漏冻全局)。abort 只作用于「尚在排队」阶段;已拿到槽位后的中断由调用方(run 的 finally)负责。\n */\n async acquire(signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n throw abortError()\n }\n if (this.active < this.max) {\n this.active += 1\n return\n }\n await new Promise<void>((resolve, reject) => {\n const waiter: Waiter = { resolve, reject, cleanup: () => {} }\n const onAbort = (): void => {\n const idx = this.waiters.indexOf(waiter)\n if (idx >= 0) {\n this.waiters.splice(idx, 1)\n }\n waiter.cleanup()\n reject(abortError())\n }\n waiter.cleanup = () => signal?.removeEventListener('abort', onAbort)\n this.waiters.push(waiter)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n }\n\n /** 释放一个槽位:有等待者则把槽位交接给它(active 不变),否则 active--。 */\n release(): void {\n const next = this.waiters.shift()\n if (next) {\n next.cleanup()\n next.resolve()\n } else {\n this.active -= 1\n }\n }\n\n /** 清空全部排队等待者(dispose 用):逐个 reject(AbortError),不触碰 active 持票者。 */\n drain(): void {\n const drained = this.waiters.splice(0)\n for (const waiter of drained) {\n waiter.cleanup()\n waiter.reject(abortError())\n }\n }\n\n /**\n * 在一个槽位内执行(含排队等待),完成/抛错后释放。\n * 传 `signal` 时,排队阶段被 abort 会抛 AbortError 且**不**进入 fn、**不**释放(从未获得槽位)。\n */\n async run<T>(fn: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n await this.acquire(signal)\n try {\n return await fn()\n } finally {\n this.release()\n }\n }\n\n /** 当前占用的槽位数(含已交接给等待者的),用于观测/测试。 */\n get activeCount(): number {\n return this.active\n }\n\n /** 排队等待中的数量。 */\n get pendingCount(): number {\n return this.waiters.length\n }\n\n get capacity(): number {\n return this.max\n }\n}\n","import { TaskRejectedError, systemClock } from './types'\nimport { CircuitBreaker, CircuitBreakerRegistry } from './retry'\nimport { Semaphore } from './semaphore'\n\nimport type { HookRegistry } from '@x-otto/hooks'\nimport type { Clock, TaskInput, TaskOutput, TaskResult, TaskUnit } from './types'\nimport type { TaskStore } from './task-store'\nimport type { RetryPolicy } from './retry'\n\nexport interface RunSessionOptions {\n prompt: string\n sessionId?: string\n sessionMode: 'ephemeral' | 'sticky'\n agentName?: string\n slot?: TaskInput['slot']\n /** 显式模型 id(subagent 按能力选型)——优先于 slot。 */\n model?: string\n /** 任务类别(task_delegate.category)——委派子会话据此走 category→slot 智能默认。 */\n category?: string\n /** 子会话承接的委托深度——使其 toolCtx.depth = 该深度,递归闭合护栏。 */\n depth?: number\n /**\n * RFC-371 M-A:父任务锚点。子会话透传给 Agent → ToolExecutor,再经\n * task_delegate/agent_call 回流 orchestrator 的 per-parent fan-out 闸。\n * 与 `taskId` 的语义区别:taskId 是「本任务」的锚点(cancel 用),\n * parentTaskId 是「派发本任务的父任务」锚点(fan-out 计数用)。\n */\n parentTaskId?: string\n /**\n * 任务锚点:宿主据此登记 taskId→活动会话,使 cancel(updateTask/\n * background cancel → abortTask 回调)能中断正在执行的子会话。callAgent 等\n * 非任务路径不携带。\n */\n taskId?: string\n /** 父会话 AbortSignal(旁路,不进 TaskInput/store)——串联中断 in-flight 子会话。 */\n signal?: AbortSignal\n /**\n * Phase 0(task_delegate/job 统一):只读委托——宿主据此从子会话工具集剔除文件改动工具\n * (edit/write/lsp_rename/bash)。background 委托脱离父对话且无审计边界,禁其改主 worktree;\n * 改动型后台活走 /job(worktree 隔离 + diff 审计)。详见 docs/design/task-delegate-job-unification.md。\n */\n readOnly?: boolean\n promptContext?: {\n taskTitle?: string\n taskDescription?: string\n taskFiles?: string[]\n }\n // ── swarm member turn 扩展字段(全部可选) ──\n systemPrompt?: string\n tools?: import('./types').AgentToolDef[]\n extraTools?: import('./types').AgentToolDef[]\n thinkingLevel?: import('./types').ThinkingLevel\n maxTokens?: number\n temperature?: number\n maxToolTurns?: number\n}\n\nexport interface RunSessionResult {\n text: string\n sessionId: string\n tokenUsage?: { input: number; output: number; cacheRead: number }\n durationMs: number\n /** swarm member turn: 完整消息历史(handoff 策略需要检查 tool_calls)。 */\n messages?: unknown[]\n /** swarm member turn: leaf 捕获的 handoff intent(RFC-332 M1 纯数据回传)。 */\n handoff?: { from: string; to: string; reason: string }\n}\n\n/**\n * 纯执行单元内核:只说 TaskUnit/TaskResult/异常三种语言——\n * runTask(同步跑到终态)与 startTask(建档即返、异步跑到终态)。\n * 工具回调形态({success, output, error} 软错误字典)的适配归 Orchestrator。\n */\nexport class TaskExecutor {\n constructor(\n private readonly taskStore: TaskStore,\n private readonly hookRegistry: HookRegistry,\n private readonly retryPolicy: RetryPolicy,\n private readonly circuitBreakers: CircuitBreakerRegistry,\n private readonly runSession: (options: RunSessionOptions) => Promise<RunSessionResult>,\n private readonly semaphore: Semaphore,\n /** B+ 门禁①:swarm member turn 的轻量执行器(有 swarm 字段时优先此而非 runSession)。 */\n private readonly runAgentTurn?: (\n input: import('./types').AgentTurnInput,\n ) => Promise<import('./types').AgentTurnResult>,\n /** 时钟端口(D13)。缺省 systemClock。 */\n private readonly clock: Clock = systemClock,\n ) {}\n\n private breakerFor(subagent?: string): CircuitBreaker {\n return this.circuitBreakers.forTarget(subagent ?? 'default')\n }\n\n /**\n * 执行单元:封装并发闸/熔断准入 + 建档 + 重试 + store + 事件,\n * 经注入的 runSession 触达引擎 pipeline,跑到终态后返回 TaskResult。\n * orchestrator.dispatchTask 的 sync 路径走此(background 走 startTask)。\n */\n async runTask(unit: TaskUnit, signal?: AbortSignal): Promise<TaskResult> {\n this.assertCircuit(unit.input.subagent)\n const task = await this.register(unit)\n return this.runScheduled(task.id, signal)\n }\n\n /**\n * 熔断准入(快速失败,不排队):该 target 的熔断打开时抛 TaskRejectedError。\n * 并发上限不在此拒绝——交由 Semaphore 排队(槽位排队)。\n */\n private assertCircuit(subagent?: string): void {\n if (this.breakerFor(subagent).isOpen()) {\n throw new TaskRejectedError(\n 'Circuit breaker is open due to repeated failures. Try again later.',\n 'circuit_open',\n )\n }\n }\n\n /** 占用一个并发槽位执行到终态,终态后释放(含排队等待) */\n private async runScheduled(taskId: string, signal?: AbortSignal): Promise<TaskResult> {\n // B8:signal 必须传给 semaphore.run——否则父 abort 时仍在**排队**的任务不会被摘除,\n // 槽位被挂死的子会话占满 → 排队的 sync task_delegate 永不唤醒(无槽位释放)→ 全局冻死。\n // callAgent 走 delegationGate.run(fn, signal) 已是此契约;此处对齐。\n return this.semaphore.run(() => this.executeToCompletion(taskId, signal), signal)\n }\n\n /** 终态写入前的 cancel 检查(updateTask/background cancel 置 cancelled 后不可覆写)。 */\n private async isCancelled(taskId: string): Promise<boolean> {\n const current = await this.taskStore.get(taskId)\n return current?.status === 'cancelled'\n }\n\n /**\n * 建立 Task 记录并广播 task.created。\n * RFC-143 M0:emit 改为 fire-and-forget——task 记录已落盘,调用方只需要 task id 立即返回,\n * 不应被挂起的插件 hook 拖慢任务创建路径。HookRegistry.emit() 自身已有超时兜底(5s)。\n */\n private async register(unit: TaskUnit): Promise<{ id: string }> {\n const task = await this.taskStore.create(unit.input)\n void this.hookRegistry.emit('task.created', { task })\n return task\n }\n\n /**\n * 后台执行单元:建档后立即返回 id,\n * 执行在并发槽位内异步跑到终态。准入同 runTask(熔断打开抛 TaskRejectedError)。\n *\n * executeToCompletion 已把一切异常转终态(不 reject);此 .catch 是防御性外网——\n * 若未来在 try 边界外再引入抛错路径(如 executeToCompletion 首行 store.get),最后一搏\n * 写 failed 终态而非静默僵死 pending + unhandled rejection。\n */\n async startTask(unit: TaskUnit): Promise<{ id: string; completion: Promise<void> }> {\n this.assertCircuit(unit.input.subagent)\n const task = await this.register(unit)\n // RFC-371 修复(元评审 2026-08-13):后台执行链以 `completion` promise 形式暴露给调用方——\n // 此前是纯 fire-and-forget(`void this.runScheduled(...)`),orchestrator 无法观测终态,\n // 导致 background 任务的 per-parent 扇出槽位只 acquire 不 release(正常完成/失败路径\n // 永不释放,同一 parent 的计数单调增长直至永久拒绝委派)。\n // `completion` 永不 reject(异常路径已内部吸收为 failed 终态写入),调用方可安全 `.finally()`。\n const completion = this.runScheduled(task.id).then(\n () => undefined,\n async (error) => {\n await this.taskStore\n .update(task.id, {\n status: 'failed',\n error: {\n code: 'EXECUTION_FAILED',\n message: error instanceof Error ? error.message : String(error),\n retriable: false,\n },\n completedAt: this.clock.now(),\n })\n .catch(() => {})\n },\n )\n return { id: task.id, completion }\n }\n\n /** 执行单元内核:跑到终态(含重试循环),返回终态 TaskResult */\n private async executeToCompletion(taskId: string, signal?: AbortSignal): Promise<TaskResult> {\n const task = await this.taskStore.get(taskId)\n if (!task) {\n return {\n taskId,\n status: 'failed',\n error: { code: 'TASK_NOT_FOUND', message: `Task not found: ${taskId}`, retriable: false },\n }\n }\n\n const attempt = task.attempts + 1\n\n try {\n await this.taskStore.update(taskId, { status: 'running', attempts: attempt })\n // RFC-143 M0:fire-and-forget——task 执行链路(下方 runSession/runAgentTurn)不应被\n // 挂起的插件 hook 阻塞在 running 状态判定之前。\n void this.hookRegistry.emit('task.started', {\n task: { ...task, status: 'running' },\n agent: task.input.subagent ?? 'default',\n })\n\n // B+ 门禁①:swarm member turn 走轻量 Agent 创建(非 session 创建)。\n // kind 判别替换旧字段嗅探 heuristic(RFC-107 D1 / M-N6)。\n const isSwarmTurn = task.input.kind === 'swarm_member'\n\n let result: RunSessionResult\n if (isSwarmTurn && this.runAgentTurn) {\n const agentResult = await this.runAgentTurn({\n agentId: task.input.subagent ?? 'agent',\n prompt: task.input.prompt,\n systemPrompt: task.input.systemPrompt,\n tools: task.input.tools,\n extraTools: task.input.extraTools,\n coreTools: task.input.coreTools,\n model: task.input.model,\n maxToolTurns: task.input.maxToolTurns,\n thinkingLevel: task.input.thinkingLevel,\n maxTokens: task.input.maxTokens,\n temperature: task.input.temperature,\n sessionId: task.input.sessionId,\n depth: task.input.depth,\n parentTaskId: task.input.parentTaskId,\n signal,\n })\n result = {\n text: agentResult.text,\n sessionId: task.input.sessionId ?? '',\n tokenUsage: agentResult.tokenUsage,\n durationMs: agentResult.durationMs,\n messages: agentResult.messages,\n handoff: agentResult.handoff,\n }\n } else {\n result = await this.runSession({\n prompt: task.input.prompt,\n sessionId: task.input.sessionId,\n sessionMode: task.sessionPolicy,\n agentName: task.input.subagent,\n slot: task.input.slot,\n model: task.input.model,\n category: task.input.category,\n depth: task.input.depth,\n parentTaskId: task.input.parentTaskId,\n taskId,\n signal,\n readOnly: task.input.mode === 'background',\n systemPrompt: task.input.systemPrompt,\n tools: task.input.tools,\n extraTools: task.input.extraTools,\n thinkingLevel: task.input.thinkingLevel,\n maxTokens: task.input.maxTokens,\n temperature: task.input.temperature,\n maxToolTurns: task.input.maxToolTurns,\n })\n }\n\n if (await this.isCancelled(taskId)) {\n return { taskId, status: 'cancelled' }\n }\n\n const output: TaskOutput = {\n text: result.text,\n tokenUsage: result.tokenUsage,\n durationMs: result.durationMs,\n ...(result.messages ? { messages: result.messages } : {}),\n ...(result.handoff ? { handoff: result.handoff } : {}),\n }\n\n await this.taskStore.update(taskId, {\n status: 'completed',\n output,\n sessionId: result.sessionId,\n completedAt: this.clock.now(),\n })\n\n this.breakerFor(task.input.subagent).success()\n\n // RFC-143 M0:fire-and-forget——task 已到达 completed 终态(taskStore.update 已写入),\n // 调用方(startTask/runTask)不应被挂起的插件 hook 阻塞在终态返回之前。\n void this.hookRegistry.emit('task.completed', {\n task: { ...task, status: 'completed', output },\n result: output,\n })\n\n return {\n taskId,\n status: 'completed',\n output,\n }\n } catch (error) {\n const errMsg = error instanceof Error ? error.message : String(error)\n\n if (await this.isCancelled(taskId)) {\n return { taskId, status: 'cancelled' }\n }\n\n // 重试须保持 abort 感知:父 signal 贯穿递归 + 退避可被 abort 打断,\n // 否则被中断的 sync 任务会占着信号量槽位把 maxAttempts 次重试跑完、无视父 abort。\n const canRetry = this.retryPolicy.shouldRetry(task.attempts) && !signal?.aborted\n if (canRetry) {\n const backoff = this.retryPolicy.getBackoff(task.attempts)\n await sleep(backoff, signal)\n if (!signal?.aborted) {\n return this.executeToCompletion(taskId, signal)\n }\n }\n\n this.breakerFor(task.input.subagent).failure()\n\n const taskError = {\n code: 'EXECUTION_FAILED',\n message: errMsg,\n retriable: false,\n }\n\n await this.taskStore.update(taskId, {\n status: 'failed',\n error: taskError,\n completedAt: this.clock.now(),\n })\n\n // RFC-143 M0:fire-and-forget——task 已到达 failed 终态,catch 块中若 emit 挂起会让\n // executeToCompletion 卡在错误路径里,永远到不了下面的 return,比正常路径更需要不阻塞。\n void this.hookRegistry.emit('task.failed', {\n task: { ...task, status: 'failed' },\n error: taskError,\n })\n\n return {\n taskId,\n status: 'failed',\n error: taskError,\n }\n }\n }\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) return Promise.resolve()\n return new Promise((resolve) => {\n let timer: ReturnType<typeof setTimeout>\n const onAbort = (): void => {\n clearTimeout(timer)\n resolve()\n }\n timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n","import type { BackgroundOutput, Result } from '@x-otto/orchestration-contracts'\nimport type { Clock } from './types'\nimport { systemClock } from './types'\nimport type { TaskStore } from './task-store'\n\nexport class BackgroundManager {\n constructor(\n private readonly taskStore: TaskStore,\n private readonly abortTask?: (taskId: string) => void,\n private readonly clock: Clock = systemClock,\n ) {}\n\n async getOutput(id: string): Promise<Result<BackgroundOutput>> {\n const task = await this.taskStore.get(id)\n if (!task) {\n return { ok: false, error: `Task not found id: ${id}` }\n }\n\n if (task.status === 'completed') {\n return { ok: true, value: { status: 'completed', output: task.output?.text } }\n }\n\n if (task.status === 'failed') {\n return { ok: false, error: task.error?.message ?? 'Task failed' }\n }\n\n return { ok: true, value: { status: task.status } }\n }\n\n async cancel(id: string): Promise<Result<void>> {\n const task = await this.taskStore.get(id)\n\n if (!task) {\n return { ok: false, error: `Task not found id: ${id}` }\n }\n\n if (task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled') {\n return { ok: false, error: `Task already in terminal state: ${task.status}, id: ${id}` }\n }\n\n await this.taskStore.update(id, {\n status: 'cancelled',\n completedAt: this.clock.now(),\n })\n\n if (this.abortTask) {\n this.abortTask(id)\n }\n\n return { ok: true, value: undefined }\n }\n}\n","import type { HookRegistry } from '@x-otto/hooks'\nimport type {\n GetTask,\n ListTasks,\n UpdateTask,\n TaskDispatch,\n CallAgent,\n GetBackgroundOutput,\n CancelBackground,\n Result,\n DispatchOutcome,\n} from '@x-otto/orchestration-contracts'\nimport { checkDelegationDepth } from '@x-otto/orchestration-contracts'\nimport { systemClock } from './types'\nimport type {\n OrchestratorOptions,\n TaskUnit,\n TaskInput,\n AgentTurnInput,\n AgentTurnResult,\n} from './types'\nimport type { RunSessionOptions, RunSessionResult } from './executor'\n\nimport { TaskStore } from './task-store'\nimport { TaskExecutor } from './executor'\nimport { BackgroundManager } from './background-manager'\nimport { RetryPolicy, CircuitBreakerRegistry } from './retry'\nimport { Semaphore } from './semaphore'\n\nexport class Orchestrator {\n readonly taskStore: TaskStore\n private readonly executor: TaskExecutor\n private readonly backgroundManager: BackgroundManager\n private readonly hookRegistry: HookRegistry\n private readonly circuitBreakers: CircuitBreakerRegistry\n private readonly delegationGate: Semaphore\n private readonly runSession: (options: RunSessionOptions) => Promise<RunSessionResult>\n private readonly maxDelegationDepth: number\n /** 外部 abort 回调(dispose 清退在飞任务用;与 BackgroundManager 共用同一回调)。 */\n private readonly abortTask?: (taskId: string) => void\n /**\n * RFC-371 S3:per-parent 活跃扇出计数。key=parentTaskId,value=该 parent 当前在跑的子任务数。\n *\n * 为什么需要它(review S3):`Semaphore(maxActiveTasks)` 是全局的——它限制「同时在跑\n * 的子任务总数」,不限制「同一个父派了多少个」。一个 buggy/贪心的 agent 可以在\n * depth 许可内塞满整个并发闸,挤占其他 agent 的配额。这是资源公平/治理问题(不是\n * 安全漏洞——depth=1 的子任务权限等同父),自迭代高频委派场景下尤为突出。\n *\n * 语义:计数随任务进入 running 态 +1,随终态(completed/failed/cancelled)-1。\n * 不累计——一个 agent 完成一个子任务后可以继续派新的,只限制同时在跑。\n * 上限 `maxFanOutPerParent` 默认 = maxActiveTasks / 2(同一父最多占一半并发配额,\n * 留出另一半给其他 agent)。undefined parentTaskId = root 层委派,不受 per-parent\n * 限制(只受全局闸约束)。\n */\n private readonly fanOutCounts = new Map<string, number>()\n private readonly maxFanOutPerParent: number\n /**\n * RFC-371 修复(元评审 2026-08-13):background 任务的「扇出槽位仍被持有」集合。\n * key=taskId。释放有两条竞争路径——①任务自然到达终态(startTask 返回的 completion\n * settle)②cancelBackground 显式取消。两条路径都会尝试释放;用 Set.delete 的返回值\n * 做一次性令牌,保证同一任务的槽位恰好释放一次(否则 cancel 后 completion settle\n * 会二次递减,把其他在跑任务的计数也吃掉)。\n */\n private readonly heldBackgroundSlots = new Set<string>()\n\n constructor(options: OrchestratorOptions) {\n const {\n hookRegistry,\n runSession,\n runAgentTurn,\n abortTask,\n workflowConfig,\n maxActiveTasks = 10,\n maxStoredTasks,\n maxDelegationDepth = 1,\n } = options\n\n this.hookRegistry = hookRegistry\n this.runSession = runSession\n this.maxDelegationDepth = maxDelegationDepth\n this.maxFanOutPerParent =\n options.maxFanOutPerParent ?? Math.max(1, Math.floor(maxActiveTasks / 2))\n this.abortTask = abortTask\n const clock = options.clock ?? systemClock\n this.taskStore = new TaskStore(maxStoredTasks, clock)\n const retryPolicy = RetryPolicy.fromWorkflowOptions(workflowConfig)\n this.circuitBreakers = CircuitBreakerRegistry.fromWorkflowOptions(workflowConfig, clock)\n this.delegationGate = new Semaphore(maxActiveTasks)\n\n this.executor = new TaskExecutor(\n this.taskStore,\n hookRegistry,\n retryPolicy,\n this.circuitBreakers,\n runSession,\n this.delegationGate,\n runAgentTurn,\n clock,\n )\n\n this.backgroundManager = new BackgroundManager(this.taskStore, abortTask, clock)\n }\n\n dispatchTask: TaskDispatch = async (args) => {\n const { childDepth, exceeded } = checkDelegationDepth(args.depth, this.maxDelegationDepth)\n if (exceeded) {\n return fail(\n `Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`,\n )\n }\n\n const input: TaskInput = {\n prompt: args.prompt,\n subagent: args.subagent,\n category: args.category,\n sessionId: args.sessionId,\n sessionMode: args.sessionMode ?? 'ephemeral',\n mode: args.mode,\n slot: args.slot,\n model: args.model,\n depth: childDepth,\n ...(args.parentTaskId !== undefined ? { parentTaskId: args.parentTaskId } : {}),\n }\n\n return this.dispatchUnit(input, args.signal)\n }\n\n /**\n * 派发单元内核(sync/background 单源):fan-out 闸 + executor 建档/执行。\n * dispatchTask(工具入口)与 updateTask('retry') 共用——retry 需要把 TaskInput 全字段\n * (parentTaskId/kind/swarm 字段)原样透传,不能经 TaskDispatch 的收窄入参重建。\n */\n private async dispatchUnit(\n input: TaskInput,\n signal?: AbortSignal,\n ): Promise<Result<DispatchOutcome>> {\n const unit: TaskUnit = { input }\n const mode = input.mode ?? 'sync'\n\n if (mode === 'background') {\n const parentTaskId = input.parentTaskId\n // RFC-371 S3(S-1 TOCTOU 修复):acquire 前置到 startTask 之前——check+increment 在\n // acquireFanOutSlot 内部同步完成(无 await 间隔),消除「顶部 check 与 acquire 之间\n // 隔着 await startTask」的 TOCTOU。false = 已超限,直接 fail 且不建档。\n if (parentTaskId !== undefined && !this.acquireFanOutSlot(parentTaskId)) {\n return fail(\n `Fan-out limit (${this.maxFanOutPerParent}) reached for parent task \"${parentTaskId}\" — ` +\n `wait for in-flight subtasks to complete before delegating more.`,\n )\n }\n\n const acquired = parentTaskId !== undefined\n return attempt(async () => {\n const { id, completion } = await this.executor.startTask(unit).catch((error: unknown) => {\n // startTask 抛错(熔断打开 / 建档失败)时拿不到 id,无法走 completion settle\n // 释放——立即回滚已 acquire 的槽位,避免泄漏。\n if (acquired) this.releaseFanOutSlot(parentTaskId)\n throw error\n })\n\n // background 任务一旦建档即计入 per-parent 活跃计数(acquire 已在上方完成)。\n // 终态释放(元评审 2026-08-13 修复):任务自然到达终态(completion settle)或\n // cancelBackground 显式取消——两条路径经 releaseBackgroundSlot 的一次性令牌\n // 恰好释放一次。\n if (acquired) {\n this.heldBackgroundSlots.add(id)\n void completion.finally(() => {\n this.releaseBackgroundSlot(id, parentTaskId)\n })\n }\n return { id, status: 'pending' as const, output: `Background task created: ${id}` }\n })\n }\n\n // RFC-371 S3:sync 任务——执行前 acquire(check+increment 原子),执行后(无论成败)release。\n if (!this.acquireFanOutSlot(input.parentTaskId)) {\n return fail(\n `Fan-out limit (${this.maxFanOutPerParent}) reached for parent task \"${input.parentTaskId}\" — ` +\n `wait for in-flight subtasks to complete before delegating more.`,\n )\n }\n try {\n const result = await this.executor.runTask(unit, signal)\n return result.status === 'completed'\n ? ok({ id: result.taskId, status: result.status, output: result.output?.text })\n : fail(result.error?.message ?? 'Unknown error')\n } catch (error) {\n return fail(error)\n } finally {\n this.releaseFanOutSlot(input.parentTaskId)\n }\n }\n\n /**\n * agent 直调——**旁路任务内核**:不建档、不进 store、不重试,\n * 直连宿主 runSession 的轻量探询语义(agent_call)。**但仍受治理**:\n * 共享同一并发闸 delegationGate + per-target 熔断(与 task_delegate 同一 CircuitBreakerRegistry)\n * + 委托深度护栏——agent_call 不是无治理通道,只是不走任务建档/重试。\n */\n callAgent: CallAgent = async (agent, prompt, options) => {\n const { childDepth, exceeded } = checkDelegationDepth(options?.depth, this.maxDelegationDepth)\n if (exceeded) {\n return fail(\n `Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`,\n )\n }\n\n const breaker = this.circuitBreakers.forTarget(agent)\n if (breaker.isOpen()) {\n return fail('Circuit breaker is open due to repeated failures. Try again later.')\n }\n\n // RFC-371 S3:agent_call 同样受 per-parent 扇出闸约束(不建档但占并发)——acquire 前置\n // (check+increment 原子,无 await 间隔),false 直接 fail。\n if (!this.acquireFanOutSlot(options?.parentTaskId)) {\n return fail(\n `Fan-out limit (${this.maxFanOutPerParent}) reached for parent task \"${options?.parentTaskId}\" — ` +\n `wait for in-flight subtasks to complete before delegating more.`,\n )\n }\n\n return this.delegationGate\n .run(async () => {\n try {\n const result = await this.runSession({\n prompt,\n sessionMode: 'ephemeral',\n agentName: agent,\n slot: options?.slot,\n model: options?.model,\n depth: childDepth,\n parentTaskId: options?.parentTaskId,\n signal: options?.signal,\n })\n breaker.success()\n return ok(result.text)\n } catch (error) {\n breaker.failure()\n return fail(error)\n }\n }, options?.signal)\n .finally(() => {\n this.releaseFanOutSlot(options?.parentTaskId)\n })\n }\n\n /**\n * swarm member turn — 经 TaskExecutor 执行(B+ 门禁①:成员 turn Task 化)。\n * TaskExecutor 检测 swarm 字段时走 runAgentTurn 轻量回调,否则走 runSession。\n */\n async runAgentTurn(input: AgentTurnInput): Promise<AgentTurnResult> {\n const unit = {\n input: {\n kind: 'swarm_member' as const,\n prompt: input.prompt,\n subagent: input.agentId,\n systemPrompt: input.systemPrompt,\n tools: input.tools,\n extraTools: input.extraTools,\n coreTools: input.coreTools,\n model: input.model,\n maxToolTurns: input.maxToolTurns,\n thinkingLevel: input.thinkingLevel,\n maxTokens: input.maxTokens,\n temperature: input.temperature,\n sessionMode: 'ephemeral' as const,\n sessionId: input.sessionId,\n depth: input.depth,\n // RFC-371 M-A(元评审 2026-08-13 补接线):swarm member turn 的父任务锚点透传。\n // types.ts:AgentTurnInput.parentTaskId 的文档承诺\"透传至 TaskInput\",此前此处遗漏,\n // 导致 team 拓扑下成员再委派时 per-parent 扇出治理断链。\n parentTaskId: input.parentTaskId,\n },\n }\n\n const result = await this.executor.runTask(unit, input.signal)\n\n if (result.status === 'completed') {\n return {\n agentId: input.agentId,\n text: result.output?.text ?? '',\n messages: result.output?.messages,\n handoff: result.output?.handoff,\n tokenUsage: result.output?.tokenUsage,\n durationMs: result.output?.durationMs ?? 0,\n }\n }\n\n throw new Error(result.error?.message ?? `Swarm member turn failed: ${result.status}`)\n }\n\n getTask: GetTask = async (id) => {\n const task = await this.taskStore.get(id)\n if (!task) {\n return fail(`Task not found: ${id}`)\n }\n\n return ok({\n id: task.id,\n status: task.status,\n prompt: task.input.prompt,\n output: task.output?.text,\n error: task.error?.message,\n })\n }\n\n listTasks: ListTasks = async (status) => {\n const filter = status && status !== 'all' ? { status } : undefined\n\n const tasks = await this.taskStore.list(filter)\n\n return ok(\n tasks.map((t) => ({\n id: t.id,\n prompt: t.input.prompt,\n status: t.status,\n })),\n )\n }\n\n updateTask: UpdateTask = async (id, action) => {\n const task = await this.taskStore.get(id)\n if (!task) {\n return fail(`Task not found: ${id}`)\n }\n\n if (action === 'cancel') {\n // cancel 机制(终态护栏 + 置 cancelled + abortTask)单源在 BackgroundManager;\n // updateTask 仅在其上叠加 task.cancelled 钩子与可读返回。\n const cancelled = await this.backgroundManager.cancel(id)\n if (!cancelled.ok) {\n return fail(cancelled.error)\n }\n await this.hookRegistry.emit('task.cancelled', { taskId: id })\n return ok(`Task ${id} cancelled`)\n }\n\n if (action === 'retry') {\n if (task.status !== 'failed') {\n return fail(`Can only retry failed tasks. Current status: ${task.status}`)\n }\n // RFC-353 S4 + 架构修复 M1:retry 保留原任务全量 provenance——depth、parentTaskId、\n // kind 与全部 swarm 字段(systemPrompt/tools/extraTools/coreTools/thinkingLevel/\n // maxTokens/temperature/maxToolTurns)。此前经 dispatchTask 的 TaskDispatch 收窄入参\n // 重建会丢 parentTaskId(retry 回到 root 层绕过 per-parent 扇出上限)与 swarm 字段\n // (swarm member 重试退化成普通子代理)。改为直接复用 task.input 经 dispatchUnit\n // 派发——depth 已是 childDepth,dispatchUnit 不再 +1 重算,无需 preservedCallerDepth\n // 抵消。dispatchTask 首派仍走 checkDelegationDepth 的 depth 护栏;retry 在已验证的\n // 原 depth 上重跑,不回退护栏。\n const result = await this.dispatchUnit(task.input)\n return result.ok ? ok(result.value.output ?? 'Retry completed') : fail(result.error)\n }\n\n return fail(`Unknown action: ${action}`)\n }\n\n getBackgroundOutput: GetBackgroundOutput = async (id) => {\n return this.backgroundManager.getOutput(id)\n }\n\n cancelBackground: CancelBackground = async (id) => {\n const result = await this.backgroundManager.cancel(id)\n // RFC-371 S3:background 任务被 cancel → 释放 per-parent 活跃槽位。\n // 经一次性令牌(heldBackgroundSlots)与 completion settle 路径互斥,防双重递减。\n if (result.ok) {\n const task = await this.taskStore.get(id)\n this.releaseBackgroundSlot(id, task?.input.parentTaskId)\n }\n return result\n }\n\n async dispose(): Promise<void> {\n this.circuitBreakers.resetAll()\n this.fanOutCounts.clear()\n this.heldBackgroundSlots.clear()\n\n // 架构修复 M6:清退在飞任务——abort 仍 pending/running 的子会话(经与 BackgroundManager\n // 共用的 abortTask 回调;不破坏 BackgroundManager 的 cancel 语义,这里只触发 abort 不写\n // 终态),再清 taskStore、排空 Semaphore 等待队列,避免后台任务半途泄漏(子会话 + 槽位)。\n const tasks = await this.taskStore.list()\n for (const task of tasks) {\n if (task.status === 'pending' || task.status === 'running') {\n try {\n this.abortTask?.(task.id)\n } catch {\n // best-effort:单个 abort 回调抛错不阻断清退其余在飞任务。\n }\n }\n }\n\n await this.taskStore.clear()\n this.delegationGate.drain()\n }\n\n // ── RFC-371 S3:per-parent 扇出计数 helpers ──────────────────────────────\n\n /**\n * RFC-371 S3(S-1 TOCTOU 修复):check+increment 合并在同一同步段完成,返回是否拿到槽位。\n * 本方法内无 await,读-改-写原子(Node 单线程),消除「顶部 check 与 acquire 之间隔 await」\n * 的 TOCTOU。undefined parentTaskId = root 层,恒返回 true(不受 per-parent 限制)。\n */\n private acquireFanOutSlot(parentTaskId: string | undefined): boolean {\n if (parentTaskId === undefined) return true\n const current = this.fanOutCounts.get(parentTaskId) ?? 0\n if (current >= this.maxFanOutPerParent) return false\n this.fanOutCounts.set(parentTaskId, current + 1)\n return true\n }\n\n private releaseFanOutSlot(parentTaskId: string | undefined): void {\n if (parentTaskId === undefined) return\n const current = this.fanOutCounts.get(parentTaskId)\n if (current === undefined) return\n if (current <= 1) {\n this.fanOutCounts.delete(parentTaskId)\n } else {\n this.fanOutCounts.set(parentTaskId, current - 1)\n }\n }\n\n /**\n * background 任务槽位的一次性释放(元评审 2026-08-13):completion settle 与\n * cancelBackground 两条路径竞争,Set.delete 返回 false = 已被另一路径释放过,跳过。\n */\n private releaseBackgroundSlot(taskId: string, parentTaskId: string | undefined): void {\n if (!this.heldBackgroundSlots.delete(taskId)) return\n this.releaseFanOutSlot(parentTaskId)\n }\n}\n\nfunction ok<T>(value: T): Result<T> {\n return { ok: true, value }\n}\n\nfunction fail(error: unknown): { ok: false; error: string } {\n return { ok: false, error: errorMessage(error) }\n}\n\nasync function attempt<T>(fn: () => Promise<T>): Promise<Result<T>> {\n try {\n return ok(await fn())\n } catch (error) {\n return fail(error)\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n","import { AgentError } from '@x-otto/shared'\n\nexport class HandoffDepthError extends AgentError {\n readonly depth: number\n readonly maxDepth: number\n\n constructor(depth: number, maxDepth: number) {\n super(`Handoff depth ${depth} exceeds max ${maxDepth}`, {\n code: 'SWARM_HANDOFF_DEPTH_EXCEEDED',\n })\n this.name = 'HandoffDepthError'\n this.depth = depth\n this.maxDepth = maxDepth\n }\n}\n\nexport class RoutingError extends AgentError {\n constructor(message: string) {\n super(message, { code: 'SWARM_ROUTING_ERROR' })\n this.name = 'RoutingError'\n }\n}\n\nexport class AgentNotFoundError extends AgentError {\n readonly agentId: string\n\n constructor(agentId: string) {\n super(`Agent \"${agentId}\" not found in swarm`, {\n code: 'SWARM_AGENT_NOT_FOUND',\n })\n this.name = 'AgentNotFoundError'\n this.agentId = agentId\n }\n}\n\nexport class SwarmConfigError extends AgentError {\n constructor(message: string) {\n super(message, { code: 'SWARM_CONFIG_ERROR' })\n this.name = 'SwarmConfigError'\n }\n}\n","import type { RouterConfig, RoutingDecision, RouteRule, SwarmAgentDef } from './types'\nimport { RoutingError } from './errors'\n\nexport class SwarmRouter {\n private readonly config: RouterConfig\n private roundRobinIndex = 0\n\n constructor(config: RouterConfig) {\n if (config.strategy === 'llm' && !config.customRouter) {\n throw new RoutingError(\n \"Routing strategy 'llm' requires a customRouter (inject the real LLM routing call).\",\n )\n }\n this.config = config\n }\n\n async route(input: string, agents: SwarmAgentDef[]): Promise<RoutingDecision> {\n const { strategy } = this.config\n\n switch (strategy) {\n case 'rule':\n return this.routeByRule(input, agents)\n case 'round-robin':\n return this.routeRoundRobin(agents)\n case 'random':\n return this.routeRandom(agents)\n case 'llm':\n return this.routeByLlm(input, agents)\n default:\n throw new RoutingError(`Unknown routing strategy: ${strategy as string}`)\n }\n }\n\n /** 基于规则路由 */\n private routeByRule(input: string, agents: SwarmAgentDef[]): RoutingDecision {\n const rules = this.config.rules ?? []\n const lowerInput = input.toLowerCase()\n\n const sorted = [...rules].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n\n for (const rule of sorted) {\n if (this.matchRule(rule, lowerInput)) {\n const agent = agents.find((a) => a.id === rule.agentId)\n if (agent) {\n return {\n agentId: rule.agentId,\n reason: `Matched rule for \"${agent.name}\"`,\n confidence: 1.0,\n }\n }\n }\n }\n\n return this.fallback(agents, 'No rule matched')\n }\n\n /** 轮转路由 */\n private routeRoundRobin(agents: SwarmAgentDef[]): RoutingDecision {\n const agent = agents[this.roundRobinIndex % agents.length]!\n this.roundRobinIndex++\n\n return {\n agentId: agent.id,\n reason: `Round-robin selection (index ${this.roundRobinIndex - 1})`,\n confidence: 1.0,\n }\n }\n\n /** 随机路由 */\n private routeRandom(agents: SwarmAgentDef[]): RoutingDecision {\n const rand = this.config.random?.random ?? Math.random\n const index = Math.floor(rand() * agents.length)\n const agent = agents[index]!\n\n return {\n agentId: agent.id,\n reason: 'Random selection',\n confidence: 1.0 / agents.length,\n }\n }\n\n /**\n * LLM 路由 —— 委托宿主注入的 customRouter(真实 LLM 调用)。\n * 旧 'custom' 枚举值已坍缩归入此路径(两者语义相同:host-injected 函数)。\n */\n private async routeByLlm(input: string, agents: SwarmAgentDef[]): Promise<RoutingDecision> {\n const { customRouter } = this.config\n if (!customRouter) {\n throw new RoutingError(\"Routing strategy 'llm' requires a customRouter.\")\n }\n return customRouter(input, agents)\n }\n\n /** Fallback 到默认 Agent */\n private fallback(agents: SwarmAgentDef[], reason: string): RoutingDecision {\n const fallbackId = this.config.fallbackAgentId ?? agents[0]?.id\n if (!fallbackId) {\n throw new RoutingError(`${reason} and no fallback agent configured`)\n }\n\n return {\n agentId: fallbackId,\n reason: `${reason} — using fallback agent`,\n confidence: 0,\n }\n }\n\n /** 匹配单条规则 */\n private matchRule(rule: RouteRule, input: string): boolean {\n if (rule.match instanceof RegExp) {\n return rule.match.test(input)\n }\n\n return rule.match.some((keyword) => input.includes(keyword.toLowerCase()))\n }\n}\n","import type { SwarmAgentDef, SwarmEventHandler, SwarmTurnResult } from './types'\n\nexport interface StepResult {\n agentId: string\n output: SwarmTurnResult\n durationMs: number\n}\n\nexport interface StrategyContext {\n /**\n * 轻量 step 执行器——经 createStepRunner 派发。\n * team 成员的 runNested 由策略自行分派(agentDef.kind === 'team')。\n * 并发由策略直接 import `runConcurrent`(intra-team 扇出原语)组织——非经 ctx 字段。\n */\n createStepRunner: (\n agentDef: import('./types').SwarmAgentDef,\n input: string,\n options?: { signal?: AbortSignal; coreTools?: import('../types').CoreToolDescriptor[] },\n ) => Promise<import('./types').SwarmTurnResult>\n /** 事件总线。 */\n emit: SwarmEventHandler\n /** 可选路由器(handoff/router pattern 用)。 */\n router?: Router\n /** AbortSignal。 */\n signal: AbortSignal\n /** 配置快照。 */\n config: StrategyConfig\n}\n\nexport interface StrategyConfig {\n name: string\n agents: Map<string, SwarmAgentDef>\n entryAgentId?: string\n pipeline?: string[]\n supervisorId?: string\n maxHandoffDepth?: number\n maxConcurrency?: number\n}\n\n\nexport interface OrchestrationStrategy {\n /** 策略名(注册表 key)。 */\n readonly name: string\n /**\n * 执行编排。ctx 由 Swarm.run() 从 config + runtime 构造。\n * 策略内经 ctx.createStepRunner 派单步、直接 import runConcurrent 组织 intra-team 并发。\n */\n execute(input: string, ctx: StrategyContext): Promise<StrategyResult>\n}\n\nexport interface StrategyResult {\n /** 所有 step 的执行记录。 */\n steps: StepResult[]\n /** 最终输出文本。 */\n output: string\n}\n\nexport class StrategyRegistry {\n private readonly strategies = new Map<string, OrchestrationStrategy>()\n\n register(strategy: OrchestrationStrategy): void {\n if (this.strategies.has(strategy.name)) {\n throw new Error(`Orchestration strategy \"${strategy.name}\" is already registered`)\n }\n this.strategies.set(strategy.name, strategy)\n }\n\n get(name: string): OrchestrationStrategy | undefined {\n return this.strategies.get(name)\n }\n\n has(name: string): boolean {\n return this.strategies.has(name)\n }\n\n names(): string[] {\n return [...this.strategies.keys()]\n }\n}\n\nexport interface Router {\n route(\n input: string,\n agents: SwarmAgentDef[],\n ): Promise<{ agentId: string; reason: string; confidence: number }>\n}\n","import type { AgentTool, ToolResult } from '@x-otto/interchange'\nimport type { ZodType } from '@x-otto/ai'\nimport { z } from 'zod'\nimport type { HandoffRequest, SwarmAgentDef, SwarmAgentId } from './types'\n\n/**\n * 创建 handoff 工具 — 注入到每个 SwarmAgent 的工具列表中,\n * 允许 Agent 通过工具调用发起 handoff。\n *\n * 灵感来自 OpenAI Swarm 的 handoff 模式:\n * Agent 在对话过程中自行决定何时、向谁交接控制权。\n *\n * RFC-332 M1:参数从 `SwarmAgentDef[]` 收窄为最小纯数据结构(本函数只消费\n * id/name/description)——使 coding leaf 的 core resolver 能用可序列化的\n * `HandoffTargetInfo[]`(经 `CoreToolDescriptor` 跨边界传输)直接构造真实工具。\n */\nexport function createHandoffTool(\n currentAgentId: SwarmAgentId,\n availableTargets: readonly { id: SwarmAgentId; name: string; description: string }[],\n onHandoff: (request: HandoffRequest) => void,\n): AgentTool {\n const targetDescriptions = availableTargets\n .map((t) => `- \"${t.id}\": ${t.name} — ${t.description}`)\n .join('\\n')\n\n const targetIds = availableTargets.map((t) => t.id)\n\n return {\n name: 'handoff_to_agent',\n description: `Transfer control to another agent in the swarm. Available targets:\\n${targetDescriptions}`,\n parameters: z.object({\n target_agent_id: z\n .string()\n .describe(`The ID of the agent to hand off to. Must be one of: ${targetIds.join(', ')}`),\n reason: z\n .string()\n .describe('Why you are transferring to this agent — will be provided as context.'),\n summary: z\n .string()\n .optional()\n .describe('Optional summary of work done so far to provide context to the target agent.'),\n }) as ZodType,\n readonly: true,\n execute: async (ctx): Promise<ToolResult> => {\n const { target_agent_id, reason, summary } = ctx.params as {\n target_agent_id: string\n reason: string\n summary?: string\n }\n\n if (!targetIds.includes(target_agent_id)) {\n return {\n content: [\n {\n type: 'text',\n text: `Invalid target agent \"${target_agent_id}\". Available targets: ${targetIds.join(', ')}`,\n },\n ],\n isError: true,\n }\n }\n\n const request: HandoffRequest = {\n from: currentAgentId,\n to: target_agent_id,\n reason: summary ? `${reason}\\n\\nContext: ${summary}` : reason,\n }\n\n onHandoff(request)\n\n return {\n content: [\n {\n type: 'text',\n text: `Handoff initiated to \"${target_agent_id}\". Reason: ${reason}`,\n },\n ],\n }\n },\n }\n}\n\nexport function validateHandoff(\n request: HandoffRequest,\n agents: Map<string, SwarmAgentDef>,\n): { valid: boolean; error?: string } {\n const fromAgent = agents.get(request.from)\n const toAgent = agents.get(request.to)\n\n if (!fromAgent) {\n return { valid: false, error: `Source agent \"${request.from}\" not found` }\n }\n\n if (!toAgent) {\n return { valid: false, error: `Target agent \"${request.to}\" not found` }\n }\n\n if (\n fromAgent.kind === 'agent' &&\n fromAgent.handoffTargets &&\n fromAgent.handoffTargets.length > 0 &&\n !fromAgent.handoffTargets.includes(request.to)\n ) {\n return {\n valid: false,\n error: `Agent \"${request.from}\" is not allowed to handoff to \"${request.to}\". Allowed: [${fromAgent.handoffTargets.join(', ')}]`,\n }\n }\n\n return { valid: true }\n}\n","import { validateHandoff } from '../handoff'\nimport { AgentNotFoundError, HandoffDepthError } from '../errors'\n\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\nimport type { HandoffRequest } from '../types'\nimport type { CoreToolDescriptor } from '../../types'\n\nexport const HANDOFF_STRATEGY: OrchestrationStrategy = {\n name: 'handoff',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n const agents = [...ctx.config.agents.values()]\n const entryId = ctx.config.entryAgentId ?? agents[0]?.id\n if (!entryId) {\n return { steps: [], output: '' }\n }\n\n const maxDepth = ctx.config.maxHandoffDepth ?? 10\n let currentAgentId = entryId\n let currentInput = input\n const steps: StrategyResult['steps'] = []\n\n for (let depth = 0; depth < maxDepth; depth++) {\n if (ctx.signal.aborted) break\n\n const agentDef = ctx.config.agents.get(currentAgentId)\n if (!agentDef) throw new AgentNotFoundError(currentAgentId)\n\n let handoffTargets = agents.filter((a) => a.id !== currentAgentId)\n if (\n agentDef.kind === 'agent' &&\n agentDef.handoffTargets &&\n agentDef.handoffTargets.length > 0\n ) {\n const allowed = agentDef.handoffTargets\n handoffTargets = handoffTargets.filter((a) => allowed.includes(a.id))\n }\n\n // RFC-332 M1:策略只声明纯数据 descriptor(不再创建 AgentTool 闭包穿越边界)。\n // leaf 的 core resolver 据此构造真实 handoff 工具;intent 经 result.handoff 纯数据回传。\n const handoffDescriptor: CoreToolDescriptor | null =\n handoffTargets.length > 0\n ? {\n source: 'core',\n name: 'handoff_to_agent',\n context: {\n from: currentAgentId,\n allowedTargets: handoffTargets.map((t) => ({\n id: t.id,\n name: t.name,\n description: t.description,\n })),\n },\n }\n : null\n\n ctx.emit({ type: 'agent.start', agentId: currentAgentId })\n const start = Date.now()\n\n // team 与 member 的分派统一经 createStepRunner→executeMemberTurn(team→runNested,\n // 不支持 core 工具并诊断)单源;handoff descriptor 仅对 member 有意义。\n const output = await ctx.createStepRunner(agentDef, currentInput, {\n signal: ctx.signal,\n coreTools: handoffDescriptor ? [handoffDescriptor] : undefined,\n })\n\n const dur = Date.now() - start\n ctx.emit({ type: 'agent.end', agentId: currentAgentId, durationMs: dur })\n steps.push({ agentId: currentAgentId, output, durationMs: dur })\n\n // RFC-332 M1:handoff intent 从 result 纯数据读取(leaf 已按 descriptor 白名单校验,\n // 此处 orchestrator 二次验证——leaf 校验不能替代策略终审)。\n const pendingHandoff = output.handoff\n if (pendingHandoff) {\n const handoff: HandoffRequest = pendingHandoff\n const validation = validateHandoff(handoff, new Map(agents.map((a) => [a.id, a])))\n if (!validation.valid) {\n return { steps, output: output.text }\n }\n\n ctx.emit({\n type: 'handoff',\n from: handoff.from,\n to: handoff.to,\n reason: handoff.reason,\n })\n\n currentAgentId = handoff.to\n currentInput = handoff.reason\n continue\n }\n\n return { steps, output: output.text }\n }\n\n throw new HandoffDepthError(maxDepth, maxDepth)\n },\n}\n","import type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\n\nexport const SEQUENTIAL_STRATEGY: OrchestrationStrategy = {\n name: 'sequential',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n const pipeline = ctx.config.pipeline ?? [...ctx.config.agents.values()].map((a) => a.id)\n const steps: StrategyResult['steps'] = []\n let currentInput = input\n\n for (const agentId of pipeline) {\n if (ctx.signal.aborted) break\n\n const agentDef = ctx.config.agents.get(agentId)\n if (!agentDef) continue\n\n ctx.emit({ type: 'agent.start', agentId })\n const startTime = Date.now()\n\n const output = await ctx.createStepRunner(agentDef, currentInput, { signal: ctx.signal })\n\n const durationMs = Date.now() - startTime\n ctx.emit({ type: 'agent.end', agentId, durationMs })\n\n steps.push({ agentId, output, durationMs })\n\n currentInput = output.text\n ctx.emit({ type: 'pipeline.step', step: steps.length - 1, agentId })\n }\n\n const finalStep = steps[steps.length - 1]\n if (!finalStep) {\n return { steps: [], output: '' }\n }\n\n return { steps, output: finalStep.output.text }\n },\n}\n","export interface ConcurrentOptions<T> {\n /** 并发上限。 */\n cap: number\n /**\n * 单步执行器。第三参 `signal` 在「兄弟失败」或「外部 signal abort」时触发——执行器可据此取消\n * 在途工作(不取消也无妨:仍不会启动新任务、且失败会上抛)。\n */\n executor: (step: T, index: number, signal: AbortSignal) => Promise<void>\n /** 可选外部 AbortSignal——阻止新任务启动;经内部控制器转发给执行器(可中断在途)。 */\n signal?: AbortSignal\n /**\n * 可选进度回调:每次一个任务完成(或出错)时调用。\n * 调用方可在此 emit fan-in 事件(如 `{type:'parallel.fanIn',completedCount,totalCount}`)。\n */\n onProgress?: (completedCount: number, totalCount: number) => void\n}\n\n/**\n * 全仓唯一并发池原语(M24-02)。\n *\n * endgame review 修复(弃跑兄弟):旧实现 `await Promise.race(running)` 在某成员 reject 时直接外抛,\n * 其余在途任务变成**无 await 的孤儿** → 后续 reject 触发 unhandledRejection、且谁也不取消它们。\n * 现在:① 每个任务包成**永不 reject** 的 wrapper(race 不再因兄弟失败而抛,所有任务都被排空);\n * ② 首个失败记录 firstError 并 abort 内部控制器(转发给执行器取消在途)+ 清空 pending(不再启动新任务);\n * ③ finally 里 allSettled 排空残余,确保无孤儿;④ 全部结束后再上抛 firstError。\n * 顺带修了旧实现的一个潜伏 bug:外部 signal abort 且仍有 pending 时,旧循环会空转(running 排空后\n * pending 非空、canStart=false、无 await → CPU busy loop)——现在 abort/fail 都清 pending、干净退出。\n */\nexport async function runConcurrent<T>(\n steps: readonly T[],\n options: ConcurrentOptions<T>,\n): Promise<void> {\n const { cap, executor, signal, onProgress } = options\n if (steps.length === 0) return\n\n const safeCap = Number.isFinite(cap) && cap >= 1 ? Math.floor(cap) : 1\n\n const total = steps.length\n const pending = [...steps]\n const running = new Set<Promise<void>>()\n let completed = 0\n let i = 0\n let firstError: unknown\n let failed = false\n\n const internal = new AbortController()\n const onExternalAbort = (): void => internal.abort()\n if (signal) {\n if (signal.aborted) internal.abort()\n else signal.addEventListener('abort', onExternalAbort, { once: true })\n }\n\n try {\n while (pending.length > 0 || running.size > 0) {\n if (internal.signal.aborted || failed) {\n pending.length = 0\n }\n\n while (running.size < safeCap && pending.length > 0) {\n const step = pending.shift()!\n const idx = i++\n let p!: Promise<void>\n p = (async () => {\n try {\n await executor(step, idx, internal.signal)\n } catch (err) {\n if (!failed) {\n firstError = err\n failed = true\n }\n internal.abort()\n } finally {\n running.delete(p)\n completed++\n onProgress?.(completed, total)\n }\n })()\n running.add(p)\n }\n\n if (running.size > 0) {\n await Promise.race(running)\n }\n }\n } finally {\n if (running.size > 0) await Promise.allSettled(running)\n if (signal) signal.removeEventListener('abort', onExternalAbort)\n }\n\n if (failed) {\n throw firstError\n }\n}\n","import { runConcurrent } from '../concurrent'\n\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\n\nexport const PARALLEL_STRATEGY: OrchestrationStrategy = {\n name: 'parallel',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n const agents = [...ctx.config.agents.values()]\n const cap = ctx.config.maxConcurrency ?? agents.length\n const tasks = agents.map((a) => ({ agentId: a.id, input }))\n const slots: Array<StrategyResult['steps'][number] | undefined> = new Array(tasks.length)\n\n ctx.emit({ type: 'parallel.fanOut', agentIds: agents.map((a) => a.id) })\n\n await runConcurrent(tasks, {\n cap,\n executor: async (task, index) => {\n try {\n const agentDef = ctx.config.agents.get(task.agentId)\n if (!agentDef) return\n\n ctx.emit({ type: 'agent.start', agentId: task.agentId })\n const start = Date.now()\n\n // team 与 member 的分派统一经 createStepRunner→executeMemberTurn(team→runNested)单源。\n const output = await ctx.createStepRunner(agentDef, task.input, { signal: ctx.signal })\n\n const dur = Date.now() - start\n ctx.emit({ type: 'agent.end', agentId: task.agentId, durationMs: dur })\n slots[index] = { agentId: task.agentId, output, durationMs: dur }\n } catch (err) {\n ctx.emit({\n type: 'error',\n agentId: task.agentId,\n error: err instanceof Error ? err : new Error(String(err)),\n })\n // 架构修复 M2:emit 后必须 rethrow,否则 runConcurrent 的 firstError 永不触发,\n // 全成员失败仍返回 success(fail-fast 失效)。\n throw err\n }\n },\n signal: ctx.signal,\n onProgress: (completed, total) => {\n ctx.emit({ type: 'parallel.fanIn', completedCount: completed, totalCount: total })\n },\n })\n\n const results = slots.filter((s): s is StrategyResult['steps'][number] => s !== undefined)\n const combined = results.map((r) => `## ${r.agentId}\\n${r.output.text}`).join('\\n\\n')\n return { steps: results, output: combined }\n },\n}\n","import { createLogger } from '@x-otto/shared'\nimport { z } from 'zod'\n\nimport { runConcurrent } from '../concurrent'\n\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\nimport type { HierarchicalTask, SwarmTurnResult } from '../types'\n\nconst logger = createLogger('otto:orchestrator:strategies:hierarchical')\n\nconst taskSchema = z.object({\n description: z.string(),\n assignedTo: z.string().optional(),\n})\n\n/**\n * 对未知值做逐元素 zod 校验过滤,而非整数组校验(整数组校验会因单个坏元素全盘拒绝)。\n */\nfunction parseAndFilterTasks(raw: unknown): HierarchicalTask[] {\n if (!Array.isArray(raw)) return []\n const tasks: HierarchicalTask[] = []\n for (const item of raw) {\n const result = taskSchema.safeParse(item)\n if (result.success) {\n tasks.push(result.data)\n }\n }\n return tasks\n}\n\nexport function parsePlanOutput(text: string): HierarchicalTask[] {\n // 优先:整体 JSON.parse\n try {\n const parsed = JSON.parse(text.trim())\n const direct = parseAndFilterTasks(parsed)\n if (direct.length > 0) {\n return direct\n }\n } catch {\n // 继续降级\n }\n\n // 兜底:正则匹配 + zod 逐元素校验\n const jsonMatch = text.match(/\\[[\\s\\S]*\\]/)\n if (jsonMatch) {\n try {\n const parsed = JSON.parse(jsonMatch[0])\n const fallback = parseAndFilterTasks(parsed)\n if (fallback.length > 0) {\n return fallback\n }\n } catch {\n // 继续降级\n }\n }\n\n // 最终兜底:warn + 空数组(调用方 tasks.length === 0 分支走既有单任务兜底)\n logger.warn(\n { textPreview: text.slice(0, 200) },\n 'hierarchical supervisor plan parse failed, degrading to single task',\n )\n return []\n}\n\nexport const HIERARCHICAL_STRATEGY: OrchestrationStrategy = {\n name: 'hierarchical',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n const supervisorId: string =\n ctx.config.supervisorId ?? [...ctx.config.agents.values()][0]?.id ?? ''\n if (!supervisorId) {\n return { steps: [], output: '' }\n }\n\n const supervisorDef = ctx.config.agents.get(supervisorId)\n if (!supervisorDef || supervisorDef.kind !== 'agent') {\n return { steps: [], output: '' }\n }\n\n ctx.emit({ type: 'agent.start', agentId: supervisorId })\n ctx.emit({ type: 'hierarchy.delegate', supervisor: supervisorId, worker: '', task: 'planning' })\n const planStart = Date.now()\n\n const planOutput = await ctx.createStepRunner(\n supervisorDef,\n `You are the supervisor. Break down this task into subtasks:\\n\\n${input}\\n\\nFor each subtask, specify:\\n1. A clear description\\n2. Which agent should execute it (choose from: ${[...ctx.config.agents.values()].map((a) => a.id).join(', ')})\\n\\nRespond with a JSON array of {description, assignedTo}. Output only the JSON array, no other text.`,\n { signal: ctx.signal },\n )\n\n const planDur = Date.now() - planStart\n ctx.emit({ type: 'agent.end', agentId: supervisorId, durationMs: planDur })\n const steps: StrategyResult['steps'] = [\n { agentId: supervisorId, output: planOutput, durationMs: planDur },\n ]\n\n let tasks = parsePlanOutput(planOutput.text)\n\n if (tasks.length === 0) {\n tasks = [{ description: input, assignedTo: undefined }]\n }\n\n const taskResults: Array<{\n task: HierarchicalTask\n agentId: string\n output: SwarmTurnResult\n durationMs: number\n }> = []\n\n const fallbackWorker =\n [...ctx.config.agents.values()].find((a) => a.id !== supervisorId)?.id ?? supervisorId\n const assignedTasks = tasks.map((t) => ({\n ...t,\n agentId: t.assignedTo ?? fallbackWorker,\n }))\n\n const cap = ctx.config.maxConcurrency ?? assignedTasks.length\n\n await runConcurrent(assignedTasks, {\n cap,\n executor: async (task) => {\n try {\n const workerDef = ctx.config.agents.get(task.agentId)\n if (!workerDef) return\n\n ctx.emit({ type: 'agent.start', agentId: task.agentId })\n ctx.emit({\n type: 'hierarchy.delegate',\n supervisor: supervisorId,\n worker: task.agentId,\n task: task.description,\n })\n const start = Date.now()\n\n const output = await ctx.createStepRunner(workerDef, task.description, {\n signal: ctx.signal,\n })\n\n const dur = Date.now() - start\n ctx.emit({ type: 'agent.end', agentId: task.agentId, durationMs: dur })\n taskResults.push({ task, agentId: task.agentId, output, durationMs: dur })\n } catch (err) {\n ctx.emit({\n type: 'error',\n agentId: task.agentId,\n error: err instanceof Error ? err : new Error(String(err)),\n })\n // 架构修复 M2:emit 后必须 rethrow,否则 runConcurrent 的 firstError 永不触发,\n // 全部 worker 失败仍返回 success(fail-fast 失效)。\n throw err\n }\n },\n signal: ctx.signal,\n })\n\n for (const tr of taskResults) {\n steps.push({ agentId: tr.agentId, output: tr.output, durationMs: tr.durationMs })\n }\n\n const summaryParts = taskResults.map(\n (r) => `## ${r.task.description} (by ${r.agentId})\\n${r.output.text}`,\n )\n const synthesis = [\n 'The subtasks have been completed. Here are the results:',\n '',\n ...summaryParts,\n '',\n 'Synthesize these results into a final coherent response for the original task:',\n input,\n ].join('\\n')\n\n if (ctx.signal.aborted) {\n return { steps, output: summaryParts.join('\\n\\n') }\n }\n\n ctx.emit({ type: 'agent.start', agentId: supervisorId })\n const synStart = Date.now()\n\n const synOutput = await ctx.createStepRunner(supervisorDef, synthesis, { signal: ctx.signal })\n\n const synDur = Date.now() - synStart\n ctx.emit({ type: 'agent.end', agentId: supervisorId, durationMs: synDur })\n steps.push({ agentId: supervisorId, output: synOutput, durationMs: synDur })\n\n return { steps, output: synOutput.text }\n },\n}\n","import { AgentNotFoundError, SwarmConfigError } from '../errors'\n\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\n\nexport const ROUTER_STRATEGY: OrchestrationStrategy = {\n name: 'router',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n if (!ctx.router) {\n throw new SwarmConfigError('Router not configured')\n }\n\n const agents = [...ctx.config.agents.values()]\n const decision = await ctx.router.route(input, agents)\n\n const agentDef = ctx.config.agents.get(decision.agentId)\n if (!agentDef) {\n throw new AgentNotFoundError(decision.agentId)\n }\n\n ctx.emit({ type: 'routing.decision', decision })\n\n ctx.emit({ type: 'agent.start', agentId: decision.agentId })\n const start = Date.now()\n\n // team 与 member 的分派统一经 createStepRunner→executeMemberTurn(team→runNested)单源。\n const output = await ctx.createStepRunner(agentDef, input, { signal: ctx.signal })\n\n const dur = Date.now() - start\n ctx.emit({ type: 'agent.end', agentId: decision.agentId, durationMs: dur })\n\n return {\n steps: [{ agentId: decision.agentId, output, durationMs: dur }],\n output: output.text,\n }\n },\n}\n","import { StrategyRegistry } from '../strategy'\nimport { HANDOFF_STRATEGY } from './handoff'\nimport { SEQUENTIAL_STRATEGY } from './sequential'\nimport { PARALLEL_STRATEGY } from './parallel'\nimport { HIERARCHICAL_STRATEGY } from './hierarchical'\nimport { ROUTER_STRATEGY } from './router'\n\nexport function createDefaultStrategyRegistry(): StrategyRegistry {\n const registry = new StrategyRegistry()\n registry.register(HANDOFF_STRATEGY)\n registry.register(SEQUENTIAL_STRATEGY)\n registry.register(PARALLEL_STRATEGY)\n registry.register(HIERARCHICAL_STRATEGY)\n registry.register(ROUTER_STRATEGY)\n return registry\n}\n\nexport { HANDOFF_STRATEGY } from './handoff'\nexport { SEQUENTIAL_STRATEGY } from './sequential'\nexport { PARALLEL_STRATEGY } from './parallel'\nexport { HIERARCHICAL_STRATEGY } from './hierarchical'\nexport { ROUTER_STRATEGY } from './router'\n","import { SwarmRouter } from './router'\nimport { createDefaultStrategyRegistry } from './strategies'\nimport { SwarmConfigError } from './errors'\n\nimport type {\n SwarmAgentDef,\n SwarmAgentId,\n SwarmAgentMember,\n SwarmConfig,\n SwarmEvent,\n SwarmEventHandler,\n SwarmTurnResult,\n} from './types'\nimport type { AgentTurnInput, Clock, CoreToolDescriptor } from '../types'\nimport { systemClock } from '../types'\nimport type { TaskHookInfo } from '@x-otto/hook-contracts'\nimport type {\n OrchestrationStrategy,\n StrategyContext,\n StrategyResult,\n Router,\n StepResult,\n} from './strategy'\nimport type { StrategyRegistry } from './strategy'\n\n/**\n * Swarm — 多 Agent 协作框架(策略引擎化)。\n *\n * OrchestrationStrategy 取代封闭枚举+switch——新模式 = 实现接口 + registry.register(),\n * 不碰 Swarm.run()、不碰核心结果类型。\n */\nexport class Swarm {\n private readonly config: SwarmConfig\n private readonly agents: Map<string, SwarmAgentDef>\n private readonly router: SwarmRouter | null\n private readonly registry: StrategyRegistry\n private readonly clock: Clock\n\n constructor(config: SwarmConfig) {\n this.validateConfig(config)\n\n this.config = config\n this.agents = new Map()\n this.clock = config.clock ?? systemClock\n\n for (const agent of config.agents) {\n this.agents.set(agent.id, agent)\n }\n\n this.router = config.router ? new SwarmRouter(config.router) : null\n\n this.registry = createDefaultStrategyRegistry()\n }\n\n getAgents(): SwarmAgentDef[] {\n return [...this.agents.values()]\n }\n\n getAgent(id: SwarmAgentId): SwarmAgentDef | undefined {\n return this.agents.get(id)\n }\n\n /** 注册/替换策略(§4-12:host 可追加新模式,不碰核心)。 */\n registerStrategy(strategy: OrchestrationStrategy): void {\n this.registry.register(strategy)\n }\n\n /** 获取已注册策略名列表。 */\n getStrategyNames(): string[] {\n return this.registry.names()\n }\n\n private emitEvent(event: SwarmEvent): void {\n // 私有回调(向后兼容,RFC-107 D1 / M-N6 保留)\n this.config.onSwarmEvent?.(event)\n // hookRegistry 桥接(RFC-107 D1 / M-N6):swarm 事件映射至既有 task.* HookTiming。\n // 构造合成 TaskHookInfo 承载 SwarmEventPayload;不新建 swarm.* timing 家族。\n if (this.config.hookRegistry) {\n const taskInfo: TaskHookInfo = {\n id: `swarm:${this.config.runId ?? this.config.name}`,\n status: 'running',\n attempts: 0,\n maxAttempts: 1,\n createdAt: this.clock.now(),\n swarmEvent: event as TaskHookInfo['swarmEvent'],\n }\n // task.started 是 task.* 家族中最合适的挂接点:swarm 成员 turn 本已经过\n // TaskExecutor 产生 task.created→task.started→task.completed,swarm 级\n // 编排事件在此之上叠 swarmEvent 上下文,下游 hook 据此区分普通 task 与\n // swarm 编排事件并消费路由/编组元数据。\n void this.config.hookRegistry.emit('task.started', {\n task: taskInfo,\n agent: `swarm:${this.config.name}`,\n })\n }\n }\n\n /** 构建 StrategyContext——每次 run() 全新构造(context/signal 属单次运行)。 */\n private buildStrategyContext(signal: AbortSignal): StrategyContext {\n const emit: SwarmEventHandler = (event) => this.emitEvent(event)\n\n const createStepRunner: StrategyContext['createStepRunner'] = (agentDef, input, opts) =>\n this.executeMemberTurn(agentDef, input, opts?.signal ?? signal, opts?.coreTools)\n\n const ctx: StrategyContext = {\n createStepRunner,\n emit,\n router: this.router as Router,\n signal,\n config: {\n name: this.config.name,\n agents: this.agents,\n entryAgentId: this.config.entryAgentId,\n pipeline: this.config.pipeline,\n supervisorId: this.config.supervisorId,\n maxHandoffDepth: this.config.maxHandoffDepth,\n maxConcurrency: this.config.maxConcurrency,\n },\n }\n\n return ctx\n }\n\n /**\n * 运行 Swarm — 从注册表取策略并执行。\n */\n async run(input: string, options?: { signal?: AbortSignal }): Promise<SwarmRunResult> {\n const signal = options?.signal ?? new AbortController().signal\n const startTime = Date.now()\n const emit: SwarmEventHandler = (event) => this.emitEvent(event)\n\n emit({\n type: 'swarm.start',\n pattern: this.config.pattern,\n agentCount: this.agents.size,\n })\n\n const strategy = this.registry.get(this.config.pattern)\n if (!strategy) {\n throw new SwarmConfigError(\n `Unknown pattern: \"${this.config.pattern}\". Registered strategies: ${this.registry.names().join(', ')}`,\n )\n }\n\n try {\n const ctx = this.buildStrategyContext(signal)\n const result: StrategyResult = await strategy.execute(input, ctx)\n\n emit({ type: 'swarm.end', totalDurationMs: Date.now() - startTime })\n\n return {\n pattern: this.config.pattern,\n steps: result.steps,\n output: result.output,\n durationMs: Date.now() - startTime,\n }\n } catch (error) {\n emit({ type: 'swarm.end', totalDurationMs: Date.now() - startTime })\n throw error\n }\n }\n\n /**\n * 执行单个 swarm 成员的 agent turn(B+ 门禁①:经 TaskExecutor 执行)。\n * team 成员走 runNested(递归子 swarm)。\n */\n private async executeMemberTurn(\n agentDef: SwarmAgentDef,\n input: string,\n signal: AbortSignal,\n coreTools?: CoreToolDescriptor[],\n ): Promise<SwarmTurnResult> {\n if (agentDef.kind === 'team') {\n // RFC-332 M1:nested team 语义显式化——core 工具(handoff)对子团队整体无意义\n // (子 swarm 有自己的策略状态机),descriptor 不透传,记录诊断而非静默丢弃。\n if (coreTools?.length) {\n this.config.onSwarmEvent?.({\n type: 'error',\n agentId: agentDef.id,\n error: new Error(\n `Nested team \"${agentDef.id}\" does not support core tools (${coreTools.map((d) => d.name).join(', ')}); descriptors dropped`,\n ),\n })\n }\n return agentDef.runNested(input, signal)\n }\n\n const member = agentDef as SwarmAgentMember\n // M-B2: 类型安全调用——config.runAgentTurn 已是 AgentTurnInput → AgentTurnResult,\n // 经 Orchestrator.runAgentTurn → TaskExecutor 获得重试/熔断/并发闸/深度护栏。\n // RFC-332 M3:member.tools 已是纯数据 AgentToolDef[],无需再做 execute 剥离投影\n // (剥离发生在宿主解析层构造 SwarmAgentDef 时,orchestrator 全程不见 AgentTool)。\n const result = await this.config.runAgentTurn({\n agentId: member.id,\n prompt: input,\n systemPrompt: member.systemPrompt,\n tools: member.tools,\n coreTools,\n model: member.model?.id,\n maxToolTurns: member.maxToolTurns,\n thinkingLevel: member.thinkingLevel as AgentTurnInput['thinkingLevel'],\n maxTokens: member.maxTokens,\n temperature: member.temperature,\n sessionId: this.config.runId,\n depth: this.config.depth,\n // RFC-371 M-A(元评审 2026-08-13 补接线):父任务锚点随成员 turn 透传。\n parentTaskId: this.config.parentTaskId,\n signal,\n })\n\n return {\n agentId: result.agentId,\n messages: (result.messages ?? []) as SwarmTurnResult['messages'],\n text: result.text,\n handoff: result.handoff,\n tokenUsage: result.tokenUsage ?? { input: 0, output: 0, cacheRead: 0 },\n durationMs: result.durationMs,\n }\n }\n\n private validateConfig(config: SwarmConfig): void {\n if (!config.name) {\n throw new SwarmConfigError('Swarm name is required')\n }\n\n if (!config.agents || config.agents.length === 0) {\n throw new SwarmConfigError('At least one agent is required')\n }\n\n if (!config.runAgentTurn) {\n throw new SwarmConfigError('runAgentTurn factory is required')\n }\n\n const ids = new Set<string>()\n for (const agent of config.agents) {\n if (ids.has(agent.id)) {\n throw new SwarmConfigError(`Duplicate agent ID: \"${agent.id}\"`)\n }\n ids.add(agent.id)\n }\n\n for (const agent of config.agents) {\n if (agent.kind === 'agent' && agent.handoffTargets) {\n for (const targetId of agent.handoffTargets) {\n if (!ids.has(targetId)) {\n throw new SwarmConfigError(\n `Agent \"${agent.id}\" references unknown handoff target \"${targetId}\"`,\n )\n }\n }\n }\n }\n }\n}\n\nexport interface SwarmRunResult {\n /** 模式名(保留判别字段,service/CLI 据此消费)。 */\n pattern: string\n /** 所有 step 的执行记录。 */\n steps: StepResult[]\n /** 最终输出文本。 */\n output: string\n durationMs: number\n}\n\nexport function createSwarm(config: SwarmConfig): Swarm {\n return new Swarm(config)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/types.ts","../src/task-store.ts","../src/retry.ts","../src/semaphore.ts","../src/executor.ts","../src/background-manager.ts","../src/orchestrator.ts","../src/swarm/errors.ts","../src/swarm/router.ts","../src/swarm/strategy.ts","../src/swarm/handoff.ts","../src/swarm/strategies/handoff.ts","../src/swarm/strategies/sequential.ts","../src/swarm/concurrent.ts","../src/swarm/strategies/parallel.ts","../src/swarm/strategies/hierarchical.ts","../src/swarm/strategies/router.ts","../src/swarm/strategies/index.ts","../src/swarm/swarm.ts"],"sourcesContent":["import type { HookRegistry } from '@x-otto/hooks'\nimport type {\n ModelSlotName,\n SessionMode,\n TaskMode,\n TaskStatus,\n WorkflowOptions,\n} from '@x-otto/orchestration-contracts'\nimport type { RunSessionOptions, RunSessionResult } from './executor'\n\nexport type { TaskStatus } from '@x-otto/orchestration-contracts'\nexport type { WorkflowOptions } from '@x-otto/orchestration-contracts'\n\n/**\n * 时钟端口(D13:引擎核心禁裸 Date.now,经注入时钟取时间戳)。\n * 形状与 `@x-otto/agent` 的 `ClockPort` 结构兼容(`{ now(): number }`),\n * 便于宿主把同一时钟注入 agent 与 orchestrator 两套确定性重放端口。\n */\nexport interface Clock {\n now(): number\n}\n\n/** 系统缺省时钟(D13):非确定性重放下由测试以 fake clock 替换。 */\nexport const systemClock: Clock = { now: () => Date.now() }\n\n/** 工具定义(本地 minimal type,避免 orchestrator 核心依赖 @x-otto/interchange)。 */\nexport interface AgentToolDef {\n name: string\n description: string\n parameters: Record<string, unknown>\n}\n\n/** handoff 目标的纯数据信息(RFC-332 M1:跨边界只传可序列化数据)。 */\nexport interface HandoffTargetInfo {\n id: string\n name: string\n description: string\n}\n\n/**\n * RFC-332 M1:swarm core 工具的纯数据描述符。\n *\n * `extraTools`(AgentToolDef 元数据投影)无法承载 core 工具的执行闭包——旧路径在 leaf\n * 被补成 throw stub(模型可见但必坏)。本描述符替代之:orchestrator 策略只声明\n * 「请 leaf 暴露哪个已注册 core 能力 + 可序列化上下文」,coding leaf 的受限 core\n * resolver 据此构造真实 `AgentTool`。描述符不得含 execute/函数/闭包。\n *\n * 当前唯一注册名是 `handoff_to_agent`;新增 core 工具须同步扩展 leaf resolver 白名单。\n */\nexport interface CoreToolDescriptor {\n source: 'core'\n name: 'handoff_to_agent'\n context: {\n /** 发起方 member id——leaf 校验其与当前 turn 的 agentId 一致(origin 校验)。 */\n from: string\n /** 策略计算后的目标白名单;leaf 只能收窄不能放宽。空数组 = 不暴露工具。 */\n allowedTargets: readonly HandoffTargetInfo[]\n }\n}\n\n/** 思考深度(本地 minimal type,避免 orchestrator 核心依赖 @x-otto/ai)。 */\nexport type ThinkingLevel = 'low' | 'medium' | 'high'\n\n/** swarm member turn 入参(B+ 门禁①:经 TaskExecutor 治理)。 */\nexport interface AgentTurnInput {\n agentId: string\n prompt: string\n systemPrompt?: string\n tools?: AgentToolDef[]\n /** RFC-332 M1:core 工具纯数据描述符——leaf 的受限 core resolver 据此构造真实工具。 */\n coreTools?: CoreToolDescriptor[]\n /**\n * RFC-332 D3:废弃的旧工具元数据通道(AgentToolDef 投影,无法承载执行闭包)。\n * 保留类型仅为运行期 fail-closed 诊断——旧调用方仍传时 leaf 会 warn + 忽略;\n * 合法工具来源是 coreTools。新代码禁止使用。\n */\n extraTools?: AgentToolDef[]\n model?: string\n maxToolTurns?: number\n thinkingLevel?: ThinkingLevel\n maxTokens?: number\n temperature?: number\n signal?: AbortSignal\n /** swarm 执行标识(用于权限/审计归属,映射到 toolHookExecutor.sessionId)。 */\n sessionId?: string\n /** 委托深度(递归护栏,映射到 Agent 构造器)。 */\n depth?: number\n /**\n * RFC-371 M-A:父任务锚点(透传面)。swarm member turn 的 TaskInput.parentTaskId\n * 透传至此,经 AgentTurnInput → Agent 构造器 → ToolExecutor 回流 fan-out 闸。\n */\n parentTaskId?: string\n}\n\n/** swarm member turn 结果(B+ 门禁①)。 */\nexport interface AgentTurnResult {\n agentId: string\n text: string\n /** 完整消息历史(handoff/hierarchical 策略需要)。 */\n messages?: unknown[]\n /** handoff 请求(handoff 策略需要)。 */\n handoff?: { from: string; to: string; reason: string }\n tokenUsage?: { input: number; output: number; cacheRead: number }\n durationMs: number\n}\n\n/** 任务输入基类——公共字段(task_delegate / agent_call / swarm_member 共享)。 */\ninterface TaskInputBase {\n /** 发给 subagent 的提示 */\n prompt: string\n /** 指定 agent 名称 — 对齐 task_delegate.subagent / agent_call.agent */\n subagent?: string\n /** 任务类别 — 对齐 task_delegate.category */\n category?: string\n /** 复用的 session ID */\n sessionId?: string\n /** session 策略 — 对齐 task_delegate.sessionMode */\n sessionMode?: SessionMode\n /** 执行模式 — 对齐 task_delegate.mode */\n mode?: TaskMode\n /** 模型槽位 — 对齐 task_delegate.slot / agent_call.slot */\n slot?: ModelSlotName\n /** 显式模型 id(subagent 按能力选型)——优先于 slot。 */\n model?: string\n /** 该任务所处委托深度(root 派发的任务 depth=1)。 */\n depth?: number\n /**\n * RFC-371 S3:发起此任务的父任务 id(用于 per-parent 活跃扇出计数)。\n * 缺省 undefined = root 层委派。由 `dispatchTask` 从 `args.parentTaskId` 透传,\n * 供 orchestrator 在任务终态时释放该 parent 的活跃计数。\n */\n parentTaskId?: string\n}\n\n/** 标准任务输入(task_delegate / agent_call 路径)。kind 缺省等价 'task'。 */\nexport interface TaskInput {\n /** 任务类别判别字段。缺省等价 'task'(向后兼容 task_delegate/agent_call 路径)。 */\n kind?: 'task'\n}\n\n/** swarm member turn 任务输入(swarm 路径)。 */\nexport interface SwarmMemberTaskInput extends TaskInputBase {\n /** 任务类别判别字段:'swarm_member' 走轻量 Agent 创建。 */\n kind: 'swarm_member'\n /** swarm 成员自定义 system prompt(覆盖默认)。 */\n systemPrompt?: string\n tools?: AgentToolDef[]\n /** RFC-332 M1:core 工具纯数据描述符(swarm_member 专用)。 */\n coreTools?: CoreToolDescriptor[]\n thinkingLevel?: ThinkingLevel\n maxTokens?: number\n temperature?: number\n maxToolTurns?: number\n}\n\n// TaskInput 也继承基类——用 declaration merging 让 TaskInput 含 TaskInputBase 字段\n// 这样 `kind?: 'task'` 与基类字段合并在同一接口,外部消费方不传 kind 仍走 task 分支。\nexport interface TaskInput extends TaskInputBase {}\n\nexport interface TaskOutput {\n text: string\n summary?: string\n tokenUsage?: { input: number; output: number; cacheRead: number }\n durationMs?: number\n // ── swarm member turn 专用(RFC-332 M1:handoff 结果是纯数据,经 Task 链路回传) ──\n /** 完整消息历史(handoff/hierarchical 策略消费;非 swarm 任务恒缺省)。 */\n messages?: unknown[]\n /** leaf 捕获的 handoff intent(orchestrator 策略二次验证后才切换)。 */\n handoff?: { from: string; to: string; reason: string }\n}\n\nexport interface TaskError {\n code: string\n message: string\n retriable: boolean\n}\n\n/** 判别联合——Task.input / TaskUnit.input 用此类型。 */\nexport type AnyTaskInput = TaskInput | SwarmMemberTaskInput\n\nexport interface Task {\n id: string\n status: TaskStatus\n sessionPolicy: SessionMode\n sessionId?: string\n attempts: number\n maxAttempts: number\n input: AnyTaskInput\n output?: TaskOutput\n error?: TaskError\n createdAt: number\n completedAt?: number\n}\n\nexport interface TaskUnit {\n input: AnyTaskInput\n}\n\nexport interface TaskResult {\n taskId: string\n status: TaskStatus\n output?: TaskOutput\n error?: TaskError\n}\n\nexport class TaskRejectedError extends Error {\n constructor(\n message: string,\n readonly reason: 'circuit_open',\n ) {\n super(message)\n this.name = 'TaskRejectedError'\n }\n}\n\nexport interface OrchestratorOptions {\n hookRegistry: HookRegistry\n /** 由 App 注入:创建子 session → prompt → 提取输出文本(task_delegate/agent_call 路径)。 */\n runSession: (options: RunSessionOptions) => Promise<RunSessionResult>\n /** B+ 门禁①:swarm member turn 执行回调(经 TaskExecutor 获得治理,但用轻量 Agent 创建)。\n * 未提供时 runAgentTurn 回退到 runSession(兼容旧路径)。 */\n runAgentTurn?: (input: AgentTurnInput) => Promise<AgentTurnResult>\n /** 可选:外部 abort 回调 */\n abortTask?: (taskId: string) => void\n workflowConfig?: WorkflowOptions\n maxActiveTasks?: number\n /**\n * TaskStore 容量上限(默认 1000)。store 满时按「终态优先 + 最旧先弃」LRU\n * 驱逐已完成/失败/取消的任务档;pending/running 在飞任务绝不驱逐。治裸 Map 无界增长,\n * 确定性、无时钟依赖(区别于 TTL)。透传 `new TaskStore(maxStoredTasks)`。\n */\n maxStoredTasks?: number\n /** RFC-371 S3:per-parent 扇出上限的选项。 */\n maxFanOutPerParent?: number\n /** 委托深度上限(默认 1)。root(0)→child1 放行;depth1→child2>1 拒。swarm 深层可经此放宽。 */\n maxDelegationDepth?: number\n /** 时钟端口(D13)。缺省 systemClock,透传至 TaskStore/Executor/CircuitBreaker/BackgroundManager。 */\n clock?: Clock\n}\n","import type { Clock, AnyTaskInput, Task, TaskStatus } from './types'\nimport { systemClock } from './types'\n\n/**\n * 内存任务档案:**单线程内存语义**——API 形态 async 是为未来\n * 换异步后端预留,但读-改-写(get → update merge → set)非原子。在 Node 单线程\n * 事件循环 + 纯内存 Map 下安全(无 await 横跨读写间隙);若替换为真实异步后端\n * (文件/网络),update 必须先加 CAS/版本号,否则 cancel 与终态写入会竞态覆写。\n */\nconst TERMINAL_STATUSES: ReadonlySet<TaskStatus> = new Set<TaskStatus>([\n 'completed',\n 'failed',\n 'cancelled',\n])\n\n/**\n * RFC-398 M2:TaskStore 事件流(append-only)。\n * Map 仍为唯一事实源;事件数组只作**状态机历史快照**(测试断言用),不参与状态重建。\n * 事件 cap 跟随 Map 容量驱逐(evicted 事件本身是驱逐信号)——避免「任务被驱逐但事件还在」的投影/日志矛盾。\n * 不暴露 onEvent 订阅:顶层可观测性已由 executor 的 hookRegistry.emit('task.*') 提供,本数组唯一不可替代价值是测试断言。\n */\nexport type TaskStoreEvent =\n | { type: 'task.created'; taskId: string; at: number }\n | { type: 'task.status-changed'; taskId: string; from: TaskStatus; to: TaskStatus; at: number }\n | { type: 'task.output-written'; taskId: string; at: number }\n | { type: 'task.evicted'; taskId: string; at: number }\n\nexport class TaskStore {\n private readonly tasks = new Map<string, Task>()\n private readonly events: TaskStoreEvent[] = []\n private nextId = 1\n\n /**\n * 容量上限(默认 1000)。store 只收 task_delegate 落库的真任务,但终态任务只增不减——\n * 故加「终态优先 LRU 驱逐」兜底治裸 Map 无界增长(确定性、无时钟依赖,区别于 TTL)。\n */\n private readonly _maxStoredTasks: number\n private readonly clock: Clock\n\n constructor(maxStoredTasks = 1000, clock: Clock = systemClock) {\n this._maxStoredTasks = Math.max(1, maxStoredTasks)\n this.clock = clock\n }\n\n /** 容量上限(dumpConfig 用)。 */\n get maxStoredTasks(): number {\n return this._maxStoredTasks\n }\n\n /** 只读事件历史快照(测试断言用)。 */\n get eventHistory(): readonly TaskStoreEvent[] {\n return this.events\n }\n\n private recordEvent(event: TaskStoreEvent): void {\n this.events.push(event)\n }\n\n private generateId(): string {\n return `task_${this.clock.now()}_${this.nextId++}`\n }\n\n async create(input: AnyTaskInput, maxAttempts = 3): Promise<Task> {\n this.evictForCapacity()\n\n const task: Task = {\n id: this.generateId(),\n status: 'pending',\n sessionPolicy: input.sessionMode ?? 'ephemeral',\n attempts: 0,\n maxAttempts,\n input,\n createdAt: this.clock.now(),\n }\n\n this.tasks.set(task.id, task)\n this.recordEvent({ type: 'task.created', taskId: task.id, at: task.createdAt })\n return task\n }\n\n /** 清空全部任务档案(dispose 用)。单线程内存语义下同步清空,API 仍保持 async 形态。 */\n async clear(): Promise<void> {\n this.tasks.clear()\n this.events.length = 0\n }\n\n /**\n * 容量回收:新建前若已达上限,按「终态优先 + 最旧先弃」驱逐至腾出一席。\n * 驱逐优先级:仅终态(completed/failed/cancelled),按 completedAt ?? createdAt 升序(最旧先弃)。\n * pending/running 在飞任务绝不驱逐——若只剩在飞仍超上限,则越界保活 + warn(绝不丢在飞的活儿)。\n * 事件流同步驱逐:被驱逐的 task 对应事件从数组中移除,并发 task.evicted 事件。\n */\n private evictForCapacity(): void {\n let overflow = this.tasks.size - this.maxStoredTasks + 1\n if (overflow <= 0) {\n return\n }\n\n const terminalOldestFirst = [...this.tasks.values()]\n .filter((t) => TERMINAL_STATUSES.has(t.status))\n .sort((a, b) => (a.completedAt ?? a.createdAt) - (b.completedAt ?? b.createdAt))\n\n for (const task of terminalOldestFirst) {\n if (overflow <= 0) {\n break\n }\n this.tasks.delete(task.id)\n // 事件流同步驱逐:删该 task 的全部事件,记录 evicted。\n const evictAt = this.clock.now()\n for (let i = this.events.length - 1; i >= 0; i--) {\n if (this.events[i]!.taskId === task.id) {\n this.events.splice(i, 1)\n }\n }\n this.recordEvent({ type: 'task.evicted', taskId: task.id, at: evictAt })\n overflow--\n }\n\n if (overflow > 0) {\n console.warn(\n `[TaskStore] capacity ${this.maxStoredTasks} exceeded by ${overflow} in-flight task(s); ` +\n `no terminal tasks left to evict — keeping in-flight tasks (will exceed cap).`,\n )\n }\n }\n\n async get(id: string): Promise<Task | undefined> {\n return this.tasks.get(id)\n }\n\n async list(filter?: { status?: TaskStatus }): Promise<Task[]> {\n let result = [...this.tasks.values()]\n if (filter?.status) {\n result = result.filter((t) => t.status === filter.status)\n }\n return result\n }\n\n async update(\n id: string,\n patch: Partial<\n Pick<Task, 'status' | 'output' | 'error' | 'attempts' | 'completedAt' | 'sessionId'>\n >,\n ): Promise<void> {\n const task = this.tasks.get(id)\n if (!task) {\n throw new Error(`Task not found: ${id}`)\n }\n\n const prevStatus = task.status\n const hasOutput = patch.output !== undefined\n\n Object.assign(task, patch)\n\n // 事件记录:status 变化发 status-changed;output 写入发 output-written(二者可同时发生)。\n const now = this.clock.now()\n if (patch.status !== undefined && patch.status !== prevStatus) {\n this.recordEvent({\n type: 'task.status-changed',\n taskId: id,\n from: prevStatus,\n to: patch.status,\n at: now,\n })\n }\n if (hasOutput) {\n this.recordEvent({ type: 'task.output-written', taskId: id, at: now })\n }\n }\n\n async delete(id: string): Promise<boolean> {\n const deleted = this.tasks.delete(id)\n if (deleted) {\n for (let i = this.events.length - 1; i >= 0; i--) {\n if (this.events[i]!.taskId === id) {\n this.events.splice(i, 1)\n }\n }\n }\n return deleted\n }\n}\n","import type { WorkflowOptions } from '@x-otto/orchestration-contracts'\n\nimport type { Clock } from './types'\nimport { systemClock } from './types'\n\nexport interface RetryConfig {\n enabled: boolean\n maxAttempts: number\n backoffMs: number\n backoffMultiplier: number\n}\n\nconst DEFAULT_RETRY: RetryConfig = {\n enabled: true,\n maxAttempts: 3,\n backoffMs: 1000,\n backoffMultiplier: 2,\n}\n\n/**\n * RFC-398 M5:重试策略 seam(最小接口)。\n *\n * orchestrator 不再依赖具体类 RetryPolicy,而是依赖此接口。\n * 默认实现是 RetryPolicy(指数退避);宿主可注入自定义实现(如按任务类型差异化重试)。\n *\n * **如实标注**:当前全仓无「换 RetryPolicy 实现」的真实消费方——此 seam 为终局形态收口\n * (RetryPolicy 是唯一用具体类注入的治理组件,与 CircuitBreakerRegistry 的 factory seam 不对称)。\n * 价值是「为未来差异化重试策略预留 seam」,不是当前有需求。\n */\nexport interface RetryStrategy {\n shouldRetry(attempt: number): boolean\n getBackoff(attempt: number): number\n readonly maxAttempts: number\n}\n\nexport class RetryPolicy implements RetryStrategy {\n private readonly config: RetryConfig\n\n constructor(config?: Partial<RetryConfig>) {\n this.config = { ...DEFAULT_RETRY, ...config }\n }\n\n shouldRetry(attempt: number): boolean {\n return this.config.enabled && attempt < this.config.maxAttempts\n }\n\n get maxAttempts(): number {\n return this.config.maxAttempts\n }\n\n getBackoff(attempt: number): number {\n return this.config.backoffMs * this.config.backoffMultiplier ** (attempt - 1)\n }\n\n static fromWorkflowOptions(wf?: WorkflowOptions): RetryPolicy {\n const retry = wf?.retry\n\n return new RetryPolicy({\n enabled: retry?.enabled ?? true,\n maxAttempts: retry?.maxAttempts ?? 3,\n backoffMs: retry?.backoffMs,\n backoffMultiplier: retry?.backoffMultiplier,\n })\n }\n}\n\nexport interface CircuitBreakerConfig {\n enabled: boolean\n failureThreshold: number\n resetTimeoutMs: number\n}\n\nconst DEFAULT_CIRCUIT_BREAKER: CircuitBreakerConfig = {\n enabled: true,\n failureThreshold: 5,\n resetTimeoutMs: 60_000,\n}\n\nexport class CircuitBreaker {\n private readonly enabled: boolean\n private readonly failureThreshold: number\n private readonly resetTimeoutMs: number\n private readonly clock: Clock\n private consecutiveFailures = 0\n private openedAt: number | null = null\n\n constructor(config?: Partial<CircuitBreakerConfig>, clock: Clock = systemClock) {\n const resolvedConfig = { ...DEFAULT_CIRCUIT_BREAKER, ...config }\n\n this.enabled = resolvedConfig.enabled\n this.failureThreshold = resolvedConfig.failureThreshold\n this.resetTimeoutMs = resolvedConfig.resetTimeoutMs\n this.clock = clock\n }\n\n isOpen(): boolean {\n if (!this.enabled) {\n return false\n }\n if (this.openedAt === null) {\n return false\n }\n\n if (this.clock.now() - this.openedAt >= this.resetTimeoutMs) {\n this.openedAt = null\n this.consecutiveFailures = 0\n return false\n }\n\n return true\n }\n\n success(): void {\n this.consecutiveFailures = 0\n this.openedAt = null\n }\n\n failure(): void {\n this.consecutiveFailures++\n if (this.consecutiveFailures >= this.failureThreshold) {\n this.openedAt = this.clock.now()\n }\n }\n\n reset(): void {\n this.consecutiveFailures = 0\n this.openedAt = null\n }\n}\n\n/**\n * H5/RFC-016 步骤1:按 target(子代理名)分桶的熔断器。单例全局熔断器在并行委托下会把\n * 不相关 target 的失败计进同一个 consecutiveFailures——一个 flaky 子代理就能熔断全部委托。\n * 按 target 分桶后,各 target 独立计数/熔断,互不污染。\n */\nexport class CircuitBreakerRegistry {\n private readonly breakers = new Map<string, CircuitBreaker>()\n\n constructor(private readonly factory: () => CircuitBreaker) {}\n\n forTarget(target: string): CircuitBreaker {\n let breaker = this.breakers.get(target)\n if (!breaker) {\n breaker = this.factory()\n this.breakers.set(target, breaker)\n }\n return breaker\n }\n\n resetAll(): void {\n for (const breaker of this.breakers.values()) {\n breaker.reset()\n }\n }\n\n /** 每个 target 一个独立熔断器(生产路径)。 */\n static perTarget(\n config?: Partial<CircuitBreakerConfig>,\n clock: Clock = systemClock,\n ): CircuitBreakerRegistry {\n return new CircuitBreakerRegistry(() => new CircuitBreaker(config, clock))\n }\n\n /** 所有 target 共用同一个熔断器实例——保留旧的全局语义(测试/向后兼容用)。 */\n static single(breaker: CircuitBreaker): CircuitBreakerRegistry {\n return new CircuitBreakerRegistry(() => breaker)\n }\n\n static fromWorkflowOptions(\n wf?: WorkflowOptions,\n clock: Clock = systemClock,\n ): CircuitBreakerRegistry {\n const circuit = wf?.circuitBreaker\n return CircuitBreakerRegistry.perTarget(\n {\n enabled: circuit?.enabled ?? true,\n failureThreshold: circuit?.failureThreshold ?? 5,\n resetTimeoutMs: circuit?.timeoutMs ?? 60_000,\n },\n clock,\n )\n }\n}\n","/**\n * H5/RFC-016 步骤1:并发闸(信号量)。把委托并发上限做成可共享的单一对象——\n * callAgent 与 TaskExecutor 注入同一个实例,使 agent_call + task_delegate 走**同一个**全局\n * 上限(之前 callAgent 旁路 executor 的内部计数,无任何闸)。\n *\n * 计数同步、交接式释放(有等待者直接转交槽位,active 不减),无 TOCTOU。\n */\nfunction abortError(): Error {\n const err = new Error('Semaphore acquire aborted')\n err.name = 'AbortError'\n return err\n}\n\ninterface Waiter {\n resolve: () => void\n reject: (err: Error) => void\n cleanup: () => void\n}\n\nexport class Semaphore {\n private active = 0\n private readonly waiters: Waiter[] = []\n\n constructor(private readonly max: number) {}\n\n /**\n * 获取一个槽位:满则排队,空出后被 release 直接交接。\n *\n * 可选 `signal`:排队等待期间若 signal abort,则把该等待者从队列摘除并 reject(AbortError)——否则\n * 一个卡死的持票者永不 release 时,被 abort 的排队委托会**永久停在这里唤不醒**(RFC:委托信号量\n * 票泄漏冻全局)。abort 只作用于「尚在排队」阶段;已拿到槽位后的中断由调用方(run 的 finally)负责。\n */\n async acquire(signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n throw abortError()\n }\n if (this.active < this.max) {\n this.active += 1\n return\n }\n await new Promise<void>((resolve, reject) => {\n const waiter: Waiter = { resolve, reject, cleanup: () => {} }\n const onAbort = (): void => {\n const idx = this.waiters.indexOf(waiter)\n if (idx >= 0) {\n this.waiters.splice(idx, 1)\n }\n waiter.cleanup()\n reject(abortError())\n }\n waiter.cleanup = () => signal?.removeEventListener('abort', onAbort)\n this.waiters.push(waiter)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n }\n\n /** 释放一个槽位:有等待者则把槽位交接给它(active 不变),否则 active--。 */\n release(): void {\n const next = this.waiters.shift()\n if (next) {\n next.cleanup()\n next.resolve()\n } else {\n this.active -= 1\n }\n }\n\n /** 清空全部排队等待者(dispose 用):逐个 reject(AbortError),不触碰 active 持票者。 */\n drain(): void {\n const drained = this.waiters.splice(0)\n for (const waiter of drained) {\n waiter.cleanup()\n waiter.reject(abortError())\n }\n }\n\n /**\n * 在一个槽位内执行(含排队等待),完成/抛错后释放。\n * 传 `signal` 时,排队阶段被 abort 会抛 AbortError 且**不**进入 fn、**不**释放(从未获得槽位)。\n */\n async run<T>(fn: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n await this.acquire(signal)\n try {\n return await fn()\n } finally {\n this.release()\n }\n }\n\n /** 当前占用的槽位数(含已交接给等待者的),用于观测/测试。 */\n get activeCount(): number {\n return this.active\n }\n\n /** 排队等待中的数量。 */\n get pendingCount(): number {\n return this.waiters.length\n }\n\n get capacity(): number {\n return this.max\n }\n}\n","import { TaskRejectedError, systemClock } from './types'\nimport { CircuitBreaker, CircuitBreakerRegistry } from './retry'\nimport type { RetryStrategy } from './retry'\nimport { Semaphore } from './semaphore'\n\nimport type { HookRegistry } from '@x-otto/hooks'\nimport type { Clock, TaskInput, TaskOutput, TaskResult, TaskUnit } from './types'\nimport type { SwarmMemberTaskInput } from './types'\nimport type { TaskStore } from './task-store'\n\nexport interface RunSessionOptions {\n prompt: string\n sessionId?: string\n sessionMode: 'ephemeral' | 'sticky'\n agentName?: string\n slot?: TaskInput['slot']\n /** 显式模型 id(subagent 按能力选型)——优先于 slot。 */\n model?: string\n /** 任务类别(task_delegate.category)——委派子会话据此走 category→slot 智能默认。 */\n category?: string\n /** 子会话承接的委托深度——使其 toolCtx.depth = 该深度,递归闭合护栏。 */\n depth?: number\n /**\n * RFC-371 M-A:父任务锚点。子会话透传给 Agent → ToolExecutor,再经\n * task_delegate/agent_call 回流 orchestrator 的 per-parent fan-out 闸。\n * 与 `taskId` 的语义区别:taskId 是「本任务」的锚点(cancel 用),\n * parentTaskId 是「派发本任务的父任务」锚点(fan-out 计数用)。\n */\n parentTaskId?: string\n /**\n * 任务锚点:宿主据此登记 taskId→活动会话,使 cancel(updateTask/\n * background cancel → abortTask 回调)能中断正在执行的子会话。callAgent 等\n * 非任务路径不携带。\n */\n taskId?: string\n /** 父会话 AbortSignal(旁路,不进 TaskInput/store)——串联中断 in-flight 子会话。 */\n signal?: AbortSignal\n /**\n * Phase 0(task_delegate/job 统一):只读委托——宿主据此从子会话工具集剔除文件改动工具\n * (edit/write/lsp_rename/bash)。background 委托脱离父对话且无审计边界,禁其改主 worktree;\n * 改动型后台活走 /job(worktree 隔离 + diff 审计)。详见 docs/design/task-delegate-job-unification.md。\n */\n readOnly?: boolean\n promptContext?: {\n taskTitle?: string\n taskDescription?: string\n taskFiles?: string[]\n }\n // ── swarm member turn 扩展字段(全部可选) ──\n systemPrompt?: string\n tools?: import('./types').AgentToolDef[]\n thinkingLevel?: import('./types').ThinkingLevel\n maxTokens?: number\n temperature?: number\n maxToolTurns?: number\n}\n\nexport interface RunSessionResult {\n text: string\n sessionId: string\n tokenUsage?: { input: number; output: number; cacheRead: number }\n durationMs: number\n /** swarm member turn: 完整消息历史(handoff 策略需要检查 tool_calls)。 */\n messages?: unknown[]\n /** swarm member turn: leaf 捕获的 handoff intent(RFC-332 M1 纯数据回传)。 */\n handoff?: { from: string; to: string; reason: string }\n}\n\n/**\n * 纯执行单元内核:只说 TaskUnit/TaskResult/异常三种语言——\n * runTask(同步跑到终态)与 startTask(建档即返、异步跑到终态)。\n * 工具回调形态({success, output, error} 软错误字典)的适配归 Orchestrator。\n */\nexport class TaskExecutor {\n constructor(\n private readonly taskStore: TaskStore,\n private readonly hookRegistry: HookRegistry,\n private readonly retryPolicy: RetryStrategy,\n private readonly circuitBreakers: CircuitBreakerRegistry,\n private readonly runSession: (options: RunSessionOptions) => Promise<RunSessionResult>,\n private readonly semaphore: Semaphore,\n /** B+ 门禁①:swarm member turn 的轻量执行器(有 swarm 字段时优先此而非 runSession)。 */\n private readonly runAgentTurn?: (\n input: import('./types').AgentTurnInput,\n ) => Promise<import('./types').AgentTurnResult>,\n /** 时钟端口(D13)。缺省 systemClock。 */\n private readonly clock: Clock = systemClock,\n ) {}\n\n private breakerFor(subagent?: string): CircuitBreaker {\n return this.circuitBreakers.forTarget(subagent ?? 'default')\n }\n\n /**\n * 执行单元:封装并发闸/熔断准入 + 建档 + 重试 + store + 事件,\n * 经注入的 runSession 触达引擎 pipeline,跑到终态后返回 TaskResult。\n * orchestrator.dispatchTask 的 sync 路径走此(background 走 startTask)。\n */\n async runTask(unit: TaskUnit, signal?: AbortSignal): Promise<TaskResult> {\n this.assertCircuit(unit.input.subagent)\n const task = await this.register(unit)\n return this.runScheduled(task.id, signal)\n }\n\n /**\n * 熔断准入(快速失败,不排队):该 target 的熔断打开时抛 TaskRejectedError。\n * 并发上限不在此拒绝——交由 Semaphore 排队(槽位排队)。\n */\n private assertCircuit(subagent?: string): void {\n if (this.breakerFor(subagent).isOpen()) {\n throw new TaskRejectedError(\n 'Circuit breaker is open due to repeated failures. Try again later.',\n 'circuit_open',\n )\n }\n }\n\n /** 占用一个并发槽位执行到终态,终态后释放(含排队等待) */\n private async runScheduled(taskId: string, signal?: AbortSignal): Promise<TaskResult> {\n // B8:signal 必须传给 semaphore.run——否则父 abort 时仍在**排队**的任务不会被摘除,\n // 槽位被挂死的子会话占满 → 排队的 sync task_delegate 永不唤醒(无槽位释放)→ 全局冻死。\n // callAgent 走 delegationGate.run(fn, signal) 已是此契约;此处对齐。\n return this.semaphore.run(() => this.executeToCompletion(taskId, signal), signal)\n }\n\n /** 终态写入前的 cancel 检查(updateTask/background cancel 置 cancelled 后不可覆写)。 */\n private async isCancelled(taskId: string): Promise<boolean> {\n const current = await this.taskStore.get(taskId)\n return current?.status === 'cancelled'\n }\n\n /**\n * 建立 Task 记录并广播 task.created。\n * RFC-143 M0:emit 改为 fire-and-forget——task 记录已落盘,调用方只需要 task id 立即返回,\n * 不应被挂起的插件 hook 拖慢任务创建路径。HookRegistry.emit() 自身已有超时兜底(5s)。\n */\n private async register(unit: TaskUnit): Promise<{ id: string }> {\n const task = await this.taskStore.create(unit.input, this.retryPolicy.maxAttempts)\n void this.hookRegistry.emit('task.created', { task })\n return task\n }\n\n /**\n * 后台执行单元:建档后立即返回 id,\n * 执行在并发槽位内异步跑到终态。准入同 runTask(熔断打开抛 TaskRejectedError)。\n *\n * executeToCompletion 已把一切异常转终态(不 reject);此 .catch 是防御性外网——\n * 若未来在 try 边界外再引入抛错路径(如 executeToCompletion 首行 store.get),最后一搏\n * 写 failed 终态而非静默僵死 pending + unhandled rejection。\n */\n async startTask(unit: TaskUnit): Promise<{ id: string; completion: Promise<void> }> {\n this.assertCircuit(unit.input.subagent)\n const task = await this.register(unit)\n // RFC-371 修复(元评审 2026-08-13):后台执行链以 `completion` promise 形式暴露给调用方——\n // 此前是纯 fire-and-forget(`void this.runScheduled(...)`),orchestrator 无法观测终态,\n // 导致 background 任务的 per-parent 扇出槽位只 acquire 不 release(正常完成/失败路径\n // 永不释放,同一 parent 的计数单调增长直至永久拒绝委派)。\n // `completion` 永不 reject(异常路径已内部吸收为 failed 终态写入),调用方可安全 `.finally()`。\n const completion = this.runScheduled(task.id).then(\n () => undefined,\n async (error) => {\n await this.taskStore\n .update(task.id, {\n status: 'failed',\n error: {\n code: 'EXECUTION_FAILED',\n message: error instanceof Error ? error.message : String(error),\n retriable: false,\n },\n completedAt: this.clock.now(),\n })\n .catch(() => {})\n },\n )\n return { id: task.id, completion }\n }\n\n /** 执行单元内核:跑到终态(含重试循环),返回终态 TaskResult */\n private async executeToCompletion(taskId: string, signal?: AbortSignal): Promise<TaskResult> {\n const task = await this.taskStore.get(taskId)\n if (!task) {\n return {\n taskId,\n status: 'failed',\n error: { code: 'TASK_NOT_FOUND', message: `Task not found: ${taskId}`, retriable: false },\n }\n }\n\n const attempt = task.attempts + 1\n\n try {\n await this.taskStore.update(taskId, { status: 'running', attempts: attempt })\n // RFC-143 M0:fire-and-forget——task 执行链路(下方 runSession/runAgentTurn)不应被\n // 挂起的插件 hook 阻塞在 running 状态判定之前。\n void this.hookRegistry.emit('task.started', {\n task: { ...task, status: 'running' },\n agent: task.input.subagent ?? 'default',\n })\n\n // B+ 门禁①:swarm member turn 走轻量 Agent 创建(非 session 创建)。\n // RFC-398 M6:判别联合窄化——kind='swarm_member' 分支内 task.input 自动窄化为 SwarmMemberTaskInput。\n let result: RunSessionResult\n if (task.input.kind === 'swarm_member' && this.runAgentTurn) {\n const swarmInput = task.input\n const agentResult = await this.runAgentTurn({\n agentId: swarmInput.subagent ?? 'agent',\n prompt: swarmInput.prompt,\n systemPrompt: swarmInput.systemPrompt,\n tools: swarmInput.tools,\n coreTools: swarmInput.coreTools,\n model: swarmInput.model,\n maxToolTurns: swarmInput.maxToolTurns,\n thinkingLevel: swarmInput.thinkingLevel,\n maxTokens: swarmInput.maxTokens,\n temperature: swarmInput.temperature,\n sessionId: swarmInput.sessionId,\n depth: swarmInput.depth,\n parentTaskId: swarmInput.parentTaskId,\n signal,\n })\n result = {\n text: agentResult.text,\n sessionId: task.input.sessionId ?? '',\n tokenUsage: agentResult.tokenUsage,\n durationMs: agentResult.durationMs,\n messages: agentResult.messages,\n handoff: agentResult.handoff,\n }\n } else {\n // 非 swarm 路径:task.input 窄化为 TaskInput(含 TaskInputBase 字段)。\n // runSession 回退路径仍可能收到 swarm 字段(旧调用点兼容),用交叉类型安全访问。\n const input = task.input as TaskInput & Partial<SwarmMemberTaskInput>\n result = await this.runSession({\n prompt: input.prompt,\n sessionId: input.sessionId,\n sessionMode: task.sessionPolicy,\n agentName: input.subagent,\n slot: input.slot,\n model: input.model,\n category: input.category,\n depth: input.depth,\n parentTaskId: input.parentTaskId,\n taskId,\n signal,\n readOnly: input.mode === 'background',\n systemPrompt: input.systemPrompt,\n tools: input.tools,\n thinkingLevel: input.thinkingLevel,\n maxTokens: input.maxTokens,\n temperature: input.temperature,\n maxToolTurns: input.maxToolTurns,\n })\n }\n\n if (await this.isCancelled(taskId)) {\n return { taskId, status: 'cancelled' }\n }\n\n const output: TaskOutput = {\n text: result.text,\n tokenUsage: result.tokenUsage,\n durationMs: result.durationMs,\n ...(result.messages ? { messages: result.messages } : {}),\n ...(result.handoff ? { handoff: result.handoff } : {}),\n }\n\n await this.taskStore.update(taskId, {\n status: 'completed',\n output,\n sessionId: result.sessionId,\n completedAt: this.clock.now(),\n })\n\n this.breakerFor(task.input.subagent).success()\n\n // RFC-143 M0:fire-and-forget——task 已到达 completed 终态(taskStore.update 已写入),\n // 调用方(startTask/runTask)不应被挂起的插件 hook 阻塞在终态返回之前。\n void this.hookRegistry.emit('task.completed', {\n task: { ...task, status: 'completed', output },\n result: output,\n })\n\n return {\n taskId,\n status: 'completed',\n output,\n }\n } catch (error) {\n const errMsg = error instanceof Error ? error.message : String(error)\n\n if (await this.isCancelled(taskId)) {\n return { taskId, status: 'cancelled' }\n }\n\n // 重试须保持 abort 感知:父 signal 贯穿递归 + 退避可被 abort 打断,\n // 否则被中断的 sync 任务会占着信号量槽位把 maxAttempts 次重试跑完、无视父 abort。\n const canRetry = this.retryPolicy.shouldRetry(task.attempts) && !signal?.aborted\n if (canRetry) {\n const backoff = this.retryPolicy.getBackoff(task.attempts)\n await sleep(backoff, signal)\n if (!signal?.aborted) {\n return this.executeToCompletion(taskId, signal)\n }\n }\n\n this.breakerFor(task.input.subagent).failure()\n\n const taskError = {\n code: 'EXECUTION_FAILED',\n message: errMsg,\n retriable: false,\n }\n\n await this.taskStore.update(taskId, {\n status: 'failed',\n error: taskError,\n completedAt: this.clock.now(),\n })\n\n // RFC-143 M0:fire-and-forget——task 已到达 failed 终态,catch 块中若 emit 挂起会让\n // executeToCompletion 卡在错误路径里,永远到不了下面的 return,比正常路径更需要不阻塞。\n void this.hookRegistry.emit('task.failed', {\n task: { ...task, status: 'failed' },\n error: taskError,\n })\n\n return {\n taskId,\n status: 'failed',\n error: taskError,\n }\n }\n }\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) return Promise.resolve()\n return new Promise((resolve) => {\n let timer: ReturnType<typeof setTimeout>\n const onAbort = (): void => {\n clearTimeout(timer)\n resolve()\n }\n timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n","import type { BackgroundOutput, Result } from '@x-otto/orchestration-contracts'\nimport type { Clock } from './types'\nimport { systemClock } from './types'\nimport type { TaskStore } from './task-store'\n\nexport class BackgroundManager {\n constructor(\n private readonly taskStore: TaskStore,\n private readonly abortTask?: (taskId: string) => void,\n private readonly clock: Clock = systemClock,\n ) {}\n\n async getOutput(id: string): Promise<Result<BackgroundOutput>> {\n const task = await this.taskStore.get(id)\n if (!task) {\n return { ok: false, error: `Task not found id: ${id}` }\n }\n\n if (task.status === 'completed') {\n return { ok: true, value: { status: 'completed', output: task.output?.text } }\n }\n\n if (task.status === 'failed') {\n return { ok: false, error: task.error?.message ?? 'Task failed' }\n }\n\n return { ok: true, value: { status: task.status } }\n }\n\n async cancel(id: string): Promise<Result<void>> {\n const task = await this.taskStore.get(id)\n\n if (!task) {\n return { ok: false, error: `Task not found id: ${id}` }\n }\n\n if (task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled') {\n return { ok: false, error: `Task already in terminal state: ${task.status}, id: ${id}` }\n }\n\n await this.taskStore.update(id, {\n status: 'cancelled',\n completedAt: this.clock.now(),\n })\n\n if (this.abortTask) {\n this.abortTask(id)\n }\n\n return { ok: true, value: undefined }\n }\n}\n","import type { HookRegistry } from '@x-otto/hooks'\nimport type {\n GetTask,\n ListTasks,\n UpdateTask,\n TaskDispatch,\n CallAgent,\n GetBackgroundOutput,\n CancelBackground,\n Result,\n DispatchOutcome,\n} from '@x-otto/orchestration-contracts'\nimport { checkDelegationDepth } from '@x-otto/orchestration-contracts'\nimport { systemClock } from './types'\nimport type {\n OrchestratorOptions,\n TaskUnit,\n TaskInput,\n AnyTaskInput,\n AgentTurnInput,\n AgentTurnResult,\n} from './types'\nimport type { RunSessionOptions, RunSessionResult } from './executor'\n\nimport { TaskStore } from './task-store'\nimport { TaskExecutor } from './executor'\nimport { BackgroundManager } from './background-manager'\nimport { RetryPolicy, CircuitBreakerRegistry } from './retry'\nimport { Semaphore } from './semaphore'\n\nexport class Orchestrator {\n readonly taskStore: TaskStore\n private readonly executor: TaskExecutor\n private readonly backgroundManager: BackgroundManager\n private readonly hookRegistry: HookRegistry\n private readonly circuitBreakers: CircuitBreakerRegistry\n private readonly delegationGate: Semaphore\n private readonly runSession: (options: RunSessionOptions) => Promise<RunSessionResult>\n private readonly maxDelegationDepth: number\n /** 外部 abort 回调(dispose 清退在飞任务用;与 BackgroundManager 共用同一回调)。 */\n private readonly abortTask?: (taskId: string) => void\n /**\n * RFC-371 S3:per-parent 活跃扇出计数。key=parentTaskId,value=该 parent 当前在跑的子任务数。\n *\n * 为什么需要它(review S3):`Semaphore(maxActiveTasks)` 是全局的——它限制「同时在跑\n * 的子任务总数」,不限制「同一个父派了多少个」。一个 buggy/贪心的 agent 可以在\n * depth 许可内塞满整个并发闸,挤占其他 agent 的配额。这是资源公平/治理问题(不是\n * 安全漏洞——depth=1 的子任务权限等同父),自迭代高频委派场景下尤为突出。\n *\n * 语义:计数随任务进入 running 态 +1,随终态(completed/failed/cancelled)-1。\n * 不累计——一个 agent 完成一个子任务后可以继续派新的,只限制同时在跑。\n * 上限 `maxFanOutPerParent` 默认 = maxActiveTasks / 2(同一父最多占一半并发配额,\n * 留出另一半给其他 agent)。undefined parentTaskId = root 层委派,不受 per-parent\n * 限制(只受全局闸约束)。\n */\n private readonly fanOutCounts = new Map<string, number>()\n private readonly maxFanOutPerParent: number\n /**\n * RFC-371 修复(元评审 2026-08-13):background 任务的「扇出槽位仍被持有」集合。\n * key=taskId。释放有两条竞争路径——①任务自然到达终态(startTask 返回的 completion\n * settle)②cancelBackground 显式取消。两条路径都会尝试释放;用 Set.delete 的返回值\n * 做一次性令牌,保证同一任务的槽位恰好释放一次(否则 cancel 后 completion settle\n * 会二次递减,把其他在跑任务的计数也吃掉)。\n */\n private readonly heldBackgroundSlots = new Set<string>()\n\n constructor(options: OrchestratorOptions) {\n const {\n hookRegistry,\n runSession,\n runAgentTurn,\n abortTask,\n workflowConfig,\n } = options\n\n const orch = workflowConfig?.orchestration\n const maxActiveTasks = options.maxActiveTasks ?? orch?.maxActiveTasks ?? 10\n const maxStoredTasks = options.maxStoredTasks ?? orch?.maxStoredTasks\n const maxDelegationDepth = options.maxDelegationDepth ?? orch?.maxDelegationDepth ?? 1\n\n this.hookRegistry = hookRegistry\n this.runSession = runSession\n this.maxDelegationDepth = maxDelegationDepth\n this.maxFanOutPerParent =\n options.maxFanOutPerParent ?? orch?.maxFanOutPerParent ?? Math.max(1, Math.floor(maxActiveTasks / 2))\n this.abortTask = abortTask\n const clock = options.clock ?? systemClock\n this.taskStore = new TaskStore(maxStoredTasks, clock)\n const retryPolicy = RetryPolicy.fromWorkflowOptions(workflowConfig)\n this.circuitBreakers = CircuitBreakerRegistry.fromWorkflowOptions(workflowConfig, clock)\n this.delegationGate = new Semaphore(maxActiveTasks)\n\n this.executor = new TaskExecutor(\n this.taskStore,\n hookRegistry,\n retryPolicy,\n this.circuitBreakers,\n runSession,\n this.delegationGate,\n runAgentTurn,\n clock,\n )\n\n this.backgroundManager = new BackgroundManager(this.taskStore, abortTask, clock)\n }\n\n /**\n * RFC-398 M4:dumpConfig 调试出口——打印当前生效的治理参数。\n * 用于排查「用户配了不生效」类问题。\n */\n dumpConfig(): Record<string, unknown> {\n return {\n maxActiveTasks: this.delegationGate.capacity,\n maxFanOutPerParent: this.maxFanOutPerParent,\n maxDelegationDepth: this.maxDelegationDepth,\n maxStoredTasks: this.taskStore.maxStoredTasks,\n }\n }\n\n dispatchTask: TaskDispatch = async (args) => {\n const { childDepth, exceeded } = checkDelegationDepth(args.depth, this.maxDelegationDepth)\n if (exceeded) {\n return fail(\n `Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`,\n )\n }\n\n const input: TaskInput = {\n prompt: args.prompt,\n subagent: args.subagent,\n category: args.category,\n sessionId: args.sessionId,\n sessionMode: args.sessionMode ?? 'ephemeral',\n mode: args.mode,\n slot: args.slot,\n model: args.model,\n depth: childDepth,\n ...(args.parentTaskId !== undefined ? { parentTaskId: args.parentTaskId } : {}),\n }\n\n return this.dispatchUnit(input, args.signal)\n }\n\n /**\n * 派发单元内核(sync/background 单源):fan-out 闸 + executor 建档/执行。\n * dispatchTask(工具入口)与 updateTask('retry') 共用——retry 需要把 TaskInput 全字段\n * (parentTaskId/kind/swarm 字段)原样透传,不能经 TaskDispatch 的收窄入参重建。\n */\n private async dispatchUnit(\n input: AnyTaskInput,\n signal?: AbortSignal,\n ): Promise<Result<DispatchOutcome>> {\n const unit: TaskUnit = { input }\n const mode = input.mode ?? 'sync'\n\n if (mode === 'background') {\n const parentTaskId = input.parentTaskId\n // RFC-371 S3(S-1 TOCTOU 修复):acquire 前置到 startTask 之前——check+increment 在\n // acquireFanOutSlot 内部同步完成(无 await 间隔),消除「顶部 check 与 acquire 之间\n // 隔着 await startTask」的 TOCTOU。false = 已超限,直接 fail 且不建档。\n if (parentTaskId !== undefined && !this.acquireFanOutSlot(parentTaskId)) {\n return fail(\n `Fan-out limit (${this.maxFanOutPerParent}) reached for parent task \"${parentTaskId}\" — ` +\n `wait for in-flight subtasks to complete before delegating more.`,\n )\n }\n\n const acquired = parentTaskId !== undefined\n return attempt(async () => {\n const { id, completion } = await this.executor.startTask(unit).catch((error: unknown) => {\n // startTask 抛错(熔断打开 / 建档失败)时拿不到 id,无法走 completion settle\n // 释放——立即回滚已 acquire 的槽位,避免泄漏。\n if (acquired) this.releaseFanOutSlot(parentTaskId)\n throw error\n })\n\n // background 任务一旦建档即计入 per-parent 活跃计数(acquire 已在上方完成)。\n // 终态释放(元评审 2026-08-13 修复):任务自然到达终态(completion settle)或\n // cancelBackground 显式取消——两条路径经 releaseBackgroundSlot 的一次性令牌\n // 恰好释放一次。\n if (acquired) {\n this.heldBackgroundSlots.add(id)\n void completion.finally(() => {\n this.releaseBackgroundSlot(id, parentTaskId)\n })\n }\n return { id, status: 'pending' as const, output: `Background task created: ${id}` }\n })\n }\n\n // RFC-371 S3:sync 任务——执行前 acquire(check+increment 原子),执行后(无论成败)release。\n if (!this.acquireFanOutSlot(input.parentTaskId)) {\n return fail(\n `Fan-out limit (${this.maxFanOutPerParent}) reached for parent task \"${input.parentTaskId}\" — ` +\n `wait for in-flight subtasks to complete before delegating more.`,\n )\n }\n try {\n const result = await this.executor.runTask(unit, signal)\n return result.status === 'completed'\n ? ok({ id: result.taskId, status: result.status, output: result.output?.text })\n : fail(result.error?.message ?? 'Unknown error')\n } catch (error) {\n return fail(error)\n } finally {\n this.releaseFanOutSlot(input.parentTaskId)\n }\n }\n\n /**\n * agent 直调——**旁路任务内核**:不建档、不进 store、不重试,\n * 直连宿主 runSession 的轻量探询语义(agent_call)。**但仍受治理**:\n * 共享同一并发闸 delegationGate + per-target 熔断(与 task_delegate 同一 CircuitBreakerRegistry)\n * + 委托深度护栏——agent_call 不是无治理通道,只是不走任务建档/重试。\n */\n callAgent: CallAgent = async (agent, prompt, options) => {\n const { childDepth, exceeded } = checkDelegationDepth(options?.depth, this.maxDelegationDepth)\n if (exceeded) {\n return fail(\n `Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`,\n )\n }\n\n const breaker = this.circuitBreakers.forTarget(agent)\n if (breaker.isOpen()) {\n return fail('Circuit breaker is open due to repeated failures. Try again later.')\n }\n\n // RFC-371 S3:agent_call 同样受 per-parent 扇出闸约束(不建档但占并发)——acquire 前置\n // (check+increment 原子,无 await 间隔),false 直接 fail。\n if (!this.acquireFanOutSlot(options?.parentTaskId)) {\n return fail(\n `Fan-out limit (${this.maxFanOutPerParent}) reached for parent task \"${options?.parentTaskId}\" — ` +\n `wait for in-flight subtasks to complete before delegating more.`,\n )\n }\n\n return this.delegationGate\n .run(async () => {\n try {\n const result = await this.runSession({\n prompt,\n sessionMode: 'ephemeral',\n agentName: agent,\n slot: options?.slot,\n model: options?.model,\n depth: childDepth,\n parentTaskId: options?.parentTaskId,\n signal: options?.signal,\n })\n breaker.success()\n return ok(result.text)\n } catch (error) {\n breaker.failure()\n return fail(error)\n }\n }, options?.signal)\n .finally(() => {\n this.releaseFanOutSlot(options?.parentTaskId)\n })\n }\n\n /**\n * swarm member turn — 经 TaskExecutor 执行(B+ 门禁①:成员 turn Task 化)。\n * TaskExecutor 检测 swarm 字段时走 runAgentTurn 轻量回调,否则走 runSession。\n */\n async runAgentTurn(input: AgentTurnInput): Promise<AgentTurnResult> {\n const unit = {\n input: {\n kind: 'swarm_member' as const,\n prompt: input.prompt,\n subagent: input.agentId,\n systemPrompt: input.systemPrompt,\n tools: input.tools,\n coreTools: input.coreTools,\n model: input.model,\n maxToolTurns: input.maxToolTurns,\n thinkingLevel: input.thinkingLevel,\n maxTokens: input.maxTokens,\n temperature: input.temperature,\n sessionMode: 'ephemeral' as const,\n sessionId: input.sessionId,\n depth: input.depth,\n // RFC-371 M-A(元评审 2026-08-13 补接线):swarm member turn 的父任务锚点透传。\n // types.ts:AgentTurnInput.parentTaskId 的文档承诺\"透传至 TaskInput\",此前此处遗漏,\n // 导致 team 拓扑下成员再委派时 per-parent 扇出治理断链。\n parentTaskId: input.parentTaskId,\n },\n }\n\n const result = await this.executor.runTask(unit, input.signal)\n\n if (result.status === 'completed') {\n return {\n agentId: input.agentId,\n text: result.output?.text ?? '',\n messages: result.output?.messages,\n handoff: result.output?.handoff,\n tokenUsage: result.output?.tokenUsage,\n durationMs: result.output?.durationMs ?? 0,\n }\n }\n\n throw new Error(result.error?.message ?? `Swarm member turn failed: ${result.status}`)\n }\n\n getTask: GetTask = async (id) => {\n const task = await this.taskStore.get(id)\n if (!task) {\n return fail(`Task not found: ${id}`)\n }\n\n return ok({\n id: task.id,\n status: task.status,\n prompt: task.input.prompt,\n output: task.output?.text,\n error: task.error?.message,\n })\n }\n\n listTasks: ListTasks = async (status) => {\n const filter = status && status !== 'all' ? { status } : undefined\n\n const tasks = await this.taskStore.list(filter)\n\n return ok(\n tasks.map((t) => ({\n id: t.id,\n prompt: t.input.prompt,\n status: t.status,\n })),\n )\n }\n\n updateTask: UpdateTask = async (id, action) => {\n const task = await this.taskStore.get(id)\n if (!task) {\n return fail(`Task not found: ${id}`)\n }\n\n if (action === 'cancel') {\n // cancel 机制(终态护栏 + 置 cancelled + abortTask)单源在 BackgroundManager;\n // updateTask 仅在其上叠加 task.cancelled 钩子与可读返回。\n const cancelled = await this.backgroundManager.cancel(id)\n if (!cancelled.ok) {\n return fail(cancelled.error)\n }\n await this.hookRegistry.emit('task.cancelled', { taskId: id })\n return ok(`Task ${id} cancelled`)\n }\n\n if (action === 'retry') {\n if (task.status !== 'failed') {\n return fail(`Can only retry failed tasks. Current status: ${task.status}`)\n }\n // RFC-353 S4 + 架构修复 M1:retry 保留原任务全量 provenance——depth、parentTaskId、\n // kind 与全部 swarm 字段(systemPrompt/tools/extraTools/coreTools/thinkingLevel/\n // maxTokens/temperature/maxToolTurns)。此前经 dispatchTask 的 TaskDispatch 收窄入参\n // 重建会丢 parentTaskId(retry 回到 root 层绕过 per-parent 扇出上限)与 swarm 字段\n // (swarm member 重试退化成普通子代理)。改为直接复用 task.input 经 dispatchUnit\n // 派发——depth 已是 childDepth,dispatchUnit 不再 +1 重算,无需 preservedCallerDepth\n // 抵消。dispatchTask 首派仍走 checkDelegationDepth 的 depth 护栏;retry 在已验证的\n // 原 depth 上重跑,不回退护栏。\n const result = await this.dispatchUnit(task.input)\n return result.ok ? ok(result.value.output ?? 'Retry completed') : fail(result.error)\n }\n\n return fail(`Unknown action: ${action}`)\n }\n\n getBackgroundOutput: GetBackgroundOutput = async (id) => {\n return this.backgroundManager.getOutput(id)\n }\n\n cancelBackground: CancelBackground = async (id) => {\n const result = await this.backgroundManager.cancel(id)\n // RFC-371 S3:background 任务被 cancel → 释放 per-parent 活跃槽位。\n // 经一次性令牌(heldBackgroundSlots)与 completion settle 路径互斥,防双重递减。\n if (result.ok) {\n const task = await this.taskStore.get(id)\n this.releaseBackgroundSlot(id, task?.input.parentTaskId)\n }\n return result\n }\n\n async dispose(): Promise<void> {\n this.circuitBreakers.resetAll()\n this.fanOutCounts.clear()\n this.heldBackgroundSlots.clear()\n\n // 架构修复 M6:清退在飞任务——abort 仍 pending/running 的子会话(经与 BackgroundManager\n // 共用的 abortTask 回调;不破坏 BackgroundManager 的 cancel 语义,这里只触发 abort 不写\n // 终态),再清 taskStore、排空 Semaphore 等待队列,避免后台任务半途泄漏(子会话 + 槽位)。\n const tasks = await this.taskStore.list()\n for (const task of tasks) {\n if (task.status === 'pending' || task.status === 'running') {\n try {\n this.abortTask?.(task.id)\n } catch {\n // best-effort:单个 abort 回调抛错不阻断清退其余在飞任务。\n }\n }\n }\n\n await this.taskStore.clear()\n this.delegationGate.drain()\n }\n\n // ── RFC-371 S3:per-parent 扇出计数 helpers ──────────────────────────────\n\n /**\n * RFC-371 S3(S-1 TOCTOU 修复):check+increment 合并在同一同步段完成,返回是否拿到槽位。\n * 本方法内无 await,读-改-写原子(Node 单线程),消除「顶部 check 与 acquire 之间隔 await」\n * 的 TOCTOU。undefined parentTaskId = root 层,恒返回 true(不受 per-parent 限制)。\n */\n private acquireFanOutSlot(parentTaskId: string | undefined): boolean {\n if (parentTaskId === undefined) return true\n const current = this.fanOutCounts.get(parentTaskId) ?? 0\n if (current >= this.maxFanOutPerParent) return false\n this.fanOutCounts.set(parentTaskId, current + 1)\n return true\n }\n\n private releaseFanOutSlot(parentTaskId: string | undefined): void {\n if (parentTaskId === undefined) return\n const current = this.fanOutCounts.get(parentTaskId)\n if (current === undefined) return\n if (current <= 1) {\n this.fanOutCounts.delete(parentTaskId)\n } else {\n this.fanOutCounts.set(parentTaskId, current - 1)\n }\n }\n\n /**\n * background 任务槽位的一次性释放(元评审 2026-08-13):completion settle 与\n * cancelBackground 两条路径竞争,Set.delete 返回 false = 已被另一路径释放过,跳过。\n */\n private releaseBackgroundSlot(taskId: string, parentTaskId: string | undefined): void {\n if (!this.heldBackgroundSlots.delete(taskId)) return\n this.releaseFanOutSlot(parentTaskId)\n }\n}\n\nfunction ok<T>(value: T): Result<T> {\n return { ok: true, value }\n}\n\nfunction fail(error: unknown): { ok: false; error: string } {\n return { ok: false, error: errorMessage(error) }\n}\n\nasync function attempt<T>(fn: () => Promise<T>): Promise<Result<T>> {\n try {\n return ok(await fn())\n } catch (error) {\n return fail(error)\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n","import { AgentError } from '@x-otto/shared'\n\nexport class HandoffDepthError extends AgentError {\n readonly depth: number\n readonly maxDepth: number\n\n constructor(depth: number, maxDepth: number) {\n super(`Handoff depth ${depth} exceeds max ${maxDepth}`, {\n code: 'SWARM_HANDOFF_DEPTH_EXCEEDED',\n })\n this.name = 'HandoffDepthError'\n this.depth = depth\n this.maxDepth = maxDepth\n }\n}\n\nexport class RoutingError extends AgentError {\n constructor(message: string) {\n super(message, { code: 'SWARM_ROUTING_ERROR' })\n this.name = 'RoutingError'\n }\n}\n\nexport class AgentNotFoundError extends AgentError {\n readonly agentId: string\n\n constructor(agentId: string) {\n super(`Agent \"${agentId}\" not found in swarm`, {\n code: 'SWARM_AGENT_NOT_FOUND',\n })\n this.name = 'AgentNotFoundError'\n this.agentId = agentId\n }\n}\n\nexport class SwarmConfigError extends AgentError {\n constructor(message: string) {\n super(message, { code: 'SWARM_CONFIG_ERROR' })\n this.name = 'SwarmConfigError'\n }\n}\n","import type { RouterConfig, RoutingDecision, RouteRule, SwarmAgentDef } from './types'\nimport { RoutingError } from './errors'\n\nexport class SwarmRouter {\n private readonly config: RouterConfig\n private roundRobinIndex = 0\n\n constructor(config: RouterConfig) {\n if (config.strategy === 'llm' && !config.customRouter) {\n throw new RoutingError(\n \"Routing strategy 'llm' requires a customRouter (inject the real LLM routing call).\",\n )\n }\n this.config = config\n }\n\n async route(input: string, agents: SwarmAgentDef[]): Promise<RoutingDecision> {\n const { strategy } = this.config\n\n switch (strategy) {\n case 'rule':\n return this.routeByRule(input, agents)\n case 'round-robin':\n return this.routeRoundRobin(agents)\n case 'random':\n return this.routeRandom(agents)\n case 'llm':\n return this.routeByLlm(input, agents)\n default:\n throw new RoutingError(`Unknown routing strategy: ${strategy as string}`)\n }\n }\n\n /** 基于规则路由 */\n private routeByRule(input: string, agents: SwarmAgentDef[]): RoutingDecision {\n const rules = this.config.rules ?? []\n const lowerInput = input.toLowerCase()\n\n const sorted = [...rules].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n\n for (const rule of sorted) {\n if (this.matchRule(rule, lowerInput)) {\n const agent = agents.find((a) => a.id === rule.agentId)\n if (agent) {\n return {\n agentId: rule.agentId,\n reason: `Matched rule for \"${agent.name}\"`,\n confidence: 1.0,\n }\n }\n }\n }\n\n return this.fallback(agents, 'No rule matched')\n }\n\n /** 轮转路由 */\n private routeRoundRobin(agents: SwarmAgentDef[]): RoutingDecision {\n const agent = agents[this.roundRobinIndex % agents.length]!\n this.roundRobinIndex++\n\n return {\n agentId: agent.id,\n reason: `Round-robin selection (index ${this.roundRobinIndex - 1})`,\n confidence: 1.0,\n }\n }\n\n /** 随机路由 */\n private routeRandom(agents: SwarmAgentDef[]): RoutingDecision {\n const rand = this.config.random?.random ?? Math.random\n const index = Math.floor(rand() * agents.length)\n const agent = agents[index]!\n\n return {\n agentId: agent.id,\n reason: 'Random selection',\n confidence: 1.0 / agents.length,\n }\n }\n\n /**\n * LLM 路由 —— 委托宿主注入的 customRouter(真实 LLM 调用)。\n * 旧 'custom' 枚举值已坍缩归入此路径(两者语义相同:host-injected 函数)。\n */\n private async routeByLlm(input: string, agents: SwarmAgentDef[]): Promise<RoutingDecision> {\n const { customRouter } = this.config\n if (!customRouter) {\n throw new RoutingError(\"Routing strategy 'llm' requires a customRouter.\")\n }\n return customRouter(input, agents)\n }\n\n /** Fallback 到默认 Agent */\n private fallback(agents: SwarmAgentDef[], reason: string): RoutingDecision {\n const fallbackId = this.config.fallbackAgentId ?? agents[0]?.id\n if (!fallbackId) {\n throw new RoutingError(`${reason} and no fallback agent configured`)\n }\n\n return {\n agentId: fallbackId,\n reason: `${reason} — using fallback agent`,\n confidence: 0,\n }\n }\n\n /** 匹配单条规则 */\n private matchRule(rule: RouteRule, input: string): boolean {\n if (rule.match instanceof RegExp) {\n return rule.match.test(input)\n }\n\n return rule.match.some((keyword) => input.includes(keyword.toLowerCase()))\n }\n}\n","import type { SwarmAgentDef, SwarmEventHandler, SwarmTurnResult } from './types'\nimport type { Clock } from '../types'\n\nexport interface StepResult {\n agentId: string\n output: SwarmTurnResult\n durationMs: number\n}\n\nexport interface StrategyContext {\n /**\n * 轻量 step 执行器——经 createStepRunner 派发。\n * team 成员的 runNested 由策略自行分派(agentDef.kind === 'team')。\n * 并发由策略直接 import `runConcurrent`(intra-team 扇出原语)组织——非经 ctx 字段。\n */\n createStepRunner: (\n agentDef: import('./types').SwarmAgentDef,\n input: string,\n options?: { signal?: AbortSignal; coreTools?: import('../types').CoreToolDescriptor[] },\n ) => Promise<import('./types').SwarmTurnResult>\n /** 事件总线。 */\n emit: SwarmEventHandler\n /** 可选路由器(handoff/router pattern 用)。 */\n router?: Router\n /** AbortSignal。 */\n signal: AbortSignal\n /** 时钟端口(D13:策略内禁裸 Date.now,一律经此取时间戳)。 */\n clock: Clock\n /** 配置快照。 */\n config: StrategyConfig\n}\n\nexport interface StrategyConfig {\n name: string\n agents: Map<string, SwarmAgentDef>\n entryAgentId?: string\n pipeline?: string[]\n supervisorId?: string\n maxHandoffDepth?: number\n maxConcurrency?: number\n}\n\n\nexport interface OrchestrationStrategy {\n /** 策略名(注册表 key)。 */\n readonly name: string\n /**\n * 执行编排。ctx 由 Swarm.run() 从 config + runtime 构造。\n * 策略内经 ctx.createStepRunner 派单步、直接 import runConcurrent 组织 intra-team 并发。\n */\n execute(input: string, ctx: StrategyContext): Promise<StrategyResult>\n}\n\nexport interface StrategyResult {\n /** 所有 step 的执行记录。 */\n steps: StepResult[]\n /** 最终输出文本。 */\n output: string\n}\n\n/**\n * RFC-398 M7:withStep——统一 step 执行样板(计时/事件/steps 收集/错误传播)。\n * 消除 5 个策略里重复的 `emit(agent.start) → clock.now() → createStepRunner → clock.now()-start → emit(agent.end) → push step` 样板。\n * 错误传播:catch 后 emit('error') 再 rethrow(防 M2 类 fail-fast 失效)。\n */\nexport async function withStep(\n ctx: StrategyContext,\n agentId: string,\n input: string,\n steps: StepResult[],\n options?: { signal?: AbortSignal; coreTools?: import('../types').CoreToolDescriptor[] },\n): Promise<import('./types').SwarmTurnResult> {\n ctx.emit({ type: 'agent.start', agentId })\n const start = ctx.clock.now()\n try {\n const output = await ctx.createStepRunner(\n ctx.config.agents.get(agentId)!,\n input,\n options,\n )\n const durationMs = ctx.clock.now() - start\n ctx.emit({ type: 'agent.end', agentId, durationMs })\n steps.push({ agentId, output, durationMs })\n return output\n } catch (err) {\n ctx.emit({\n type: 'error',\n agentId,\n error: err instanceof Error ? err : new Error(String(err)),\n })\n throw err\n }\n}\n\nexport class StrategyRegistry {\n private readonly strategies = new Map<string, OrchestrationStrategy>()\n\n register(strategy: OrchestrationStrategy): () => void {\n if (this.strategies.has(strategy.name)) {\n throw new Error(`Orchestration strategy \"${strategy.name}\" is already registered`)\n }\n this.strategies.set(strategy.name, strategy)\n // RFC-398 M5:成对 API(register→disposer)——插件卸载时调用返回的 disposer 移除策略。\n return () => {\n this.strategies.delete(strategy.name)\n }\n }\n\n /** 删除已注册策略(disposer 的等价直接调用)。 */\n unregister(name: string): boolean {\n return this.strategies.delete(name)\n }\n\n get(name: string): OrchestrationStrategy | undefined {\n return this.strategies.get(name)\n }\n\n has(name: string): boolean {\n return this.strategies.has(name)\n }\n\n names(): string[] {\n return [...this.strategies.keys()]\n }\n}\n\nexport interface Router {\n route(\n input: string,\n agents: SwarmAgentDef[],\n ): Promise<{ agentId: string; reason: string; confidence: number }>\n}\n","import type { AgentTool, ToolResult } from '@x-otto/interchange'\nimport { z, type ZodType } from 'zod'\nimport type { HandoffRequest, SwarmAgentDef, SwarmAgentId } from './types'\n\n/**\n * 创建 handoff 工具 — 注入到每个 SwarmAgent 的工具列表中,\n * 允许 Agent 通过工具调用发起 handoff。\n *\n * 灵感来自 OpenAI Swarm 的 handoff 模式:\n * Agent 在对话过程中自行决定何时、向谁交接控制权。\n *\n * RFC-332 M1:参数从 `SwarmAgentDef[]` 收窄为最小纯数据结构(本函数只消费\n * id/name/description)——使 coding leaf 的 core resolver 能用可序列化的\n * `HandoffTargetInfo[]`(经 `CoreToolDescriptor` 跨边界传输)直接构造真实工具。\n */\nexport function createHandoffTool(\n currentAgentId: SwarmAgentId,\n availableTargets: readonly { id: SwarmAgentId; name: string; description: string }[],\n onHandoff: (request: HandoffRequest) => void,\n): AgentTool {\n const targetDescriptions = availableTargets\n .map((t) => `- \"${t.id}\": ${t.name} — ${t.description}`)\n .join('\\n')\n\n const targetIds = availableTargets.map((t) => t.id)\n\n return {\n name: 'handoff_to_agent',\n description: `Transfer control to another agent in the swarm. Available targets:\\n${targetDescriptions}`,\n parameters: z.object({\n target_agent_id: z\n .string()\n .describe(`The ID of the agent to hand off to. Must be one of: ${targetIds.join(', ')}`),\n reason: z\n .string()\n .describe('Why you are transferring to this agent — will be provided as context.'),\n summary: z\n .string()\n .optional()\n .describe('Optional summary of work done so far to provide context to the target agent.'),\n }) as ZodType,\n execute: async (ctx): Promise<ToolResult> => {\n const { target_agent_id, reason, summary } = ctx.params as {\n target_agent_id: string\n reason: string\n summary?: string\n }\n\n if (!targetIds.includes(target_agent_id)) {\n return {\n content: [\n {\n type: 'text',\n text: `Invalid target agent \"${target_agent_id}\". Available targets: ${targetIds.join(', ')}`,\n },\n ],\n isError: true,\n }\n }\n\n const request: HandoffRequest = {\n from: currentAgentId,\n to: target_agent_id,\n reason: summary ? `${reason}\\n\\nContext: ${summary}` : reason,\n }\n\n onHandoff(request)\n\n return {\n content: [\n {\n type: 'text',\n text: `Handoff initiated to \"${target_agent_id}\". Reason: ${reason}`,\n },\n ],\n }\n },\n }\n}\n\nexport function validateHandoff(\n request: HandoffRequest,\n agents: Map<string, SwarmAgentDef>,\n): { valid: boolean; error?: string } {\n const fromAgent = agents.get(request.from)\n const toAgent = agents.get(request.to)\n\n if (!fromAgent) {\n return { valid: false, error: `Source agent \"${request.from}\" not found` }\n }\n\n if (!toAgent) {\n return { valid: false, error: `Target agent \"${request.to}\" not found` }\n }\n\n if (\n fromAgent.kind === 'agent' &&\n fromAgent.handoffTargets &&\n fromAgent.handoffTargets.length > 0 &&\n !fromAgent.handoffTargets.includes(request.to)\n ) {\n return {\n valid: false,\n error: `Agent \"${request.from}\" is not allowed to handoff to \"${request.to}\". Allowed: [${fromAgent.handoffTargets.join(', ')}]`,\n }\n }\n\n return { valid: true }\n}\n","import { withStep } from '../strategy'\nimport { validateHandoff } from '../handoff'\nimport { AgentNotFoundError, HandoffDepthError } from '../errors'\n\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\nimport type { HandoffRequest } from '../types'\nimport type { CoreToolDescriptor } from '../../types'\n\nexport const HANDOFF_STRATEGY: OrchestrationStrategy = {\n name: 'handoff',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n const agents = [...ctx.config.agents.values()]\n const entryId = ctx.config.entryAgentId ?? agents[0]?.id\n if (!entryId) {\n return { steps: [], output: '' }\n }\n\n const maxDepth = ctx.config.maxHandoffDepth ?? 10\n let currentAgentId = entryId\n let currentInput = input\n const steps: StrategyResult['steps'] = []\n\n for (let depth = 0; depth < maxDepth; depth++) {\n if (ctx.signal.aborted) break\n\n const agentDef = ctx.config.agents.get(currentAgentId)\n if (!agentDef) throw new AgentNotFoundError(currentAgentId)\n\n let handoffTargets = agents.filter((a) => a.id !== currentAgentId)\n if (\n agentDef.kind === 'agent' &&\n agentDef.handoffTargets &&\n agentDef.handoffTargets.length > 0\n ) {\n const allowed = agentDef.handoffTargets\n handoffTargets = handoffTargets.filter((a) => allowed.includes(a.id))\n }\n\n // RFC-332 M1:策略只声明纯数据 descriptor(不再创建 AgentTool 闭包穿越边界)。\n // leaf 的 core resolver 据此构造真实 handoff 工具;intent 经 result.handoff 纯数据回传。\n const handoffDescriptor: CoreToolDescriptor | null =\n handoffTargets.length > 0\n ? {\n source: 'core',\n name: 'handoff_to_agent',\n context: {\n from: currentAgentId,\n allowedTargets: handoffTargets.map((t) => ({\n id: t.id,\n name: t.name,\n description: t.description,\n })),\n },\n }\n : null\n\n const output = await withStep(ctx, currentAgentId, currentInput, steps, {\n signal: ctx.signal,\n coreTools: handoffDescriptor ? [handoffDescriptor] : undefined,\n })\n\n // RFC-332 M1:handoff intent 从 result 纯数据读取(leaf 已按 descriptor 白名单校验,\n // 此处 orchestrator 二次验证——leaf 校验不能替代策略终审)。\n const pendingHandoff = output.handoff\n if (pendingHandoff) {\n const handoff: HandoffRequest = pendingHandoff\n const validation = validateHandoff(handoff, new Map(agents.map((a) => [a.id, a])))\n if (!validation.valid) {\n return { steps, output: output.text }\n }\n\n ctx.emit({\n type: 'handoff',\n from: handoff.from,\n to: handoff.to,\n reason: handoff.reason,\n })\n\n currentAgentId = handoff.to\n currentInput = handoff.reason\n continue\n }\n\n return { steps, output: output.text }\n }\n\n throw new HandoffDepthError(maxDepth, maxDepth)\n },\n}\n","import { withStep } from '../strategy'\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\n\nexport const SEQUENTIAL_STRATEGY: OrchestrationStrategy = {\n name: 'sequential',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n const pipeline = ctx.config.pipeline ?? [...ctx.config.agents.values()].map((a) => a.id)\n const steps: StrategyResult['steps'] = []\n let currentInput = input\n\n for (const agentId of pipeline) {\n if (ctx.signal.aborted) break\n if (!ctx.config.agents.has(agentId)) continue\n\n const output = await withStep(ctx, agentId, currentInput, steps, { signal: ctx.signal })\n currentInput = output.text\n ctx.emit({ type: 'pipeline.step', step: steps.length - 1, agentId })\n }\n\n const finalStep = steps[steps.length - 1]\n if (!finalStep) {\n return { steps: [], output: '' }\n }\n\n return { steps, output: finalStep.output.text }\n },\n}\n","export interface ConcurrentOptions<T> {\n /** 并发上限。 */\n cap: number\n /**\n * 单步执行器。第三参 `signal` 在「兄弟失败」或「外部 signal abort」时触发——执行器可据此取消\n * 在途工作(不取消也无妨:仍不会启动新任务、且失败会上抛)。\n */\n executor: (step: T, index: number, signal: AbortSignal) => Promise<void>\n /** 可选外部 AbortSignal——阻止新任务启动;经内部控制器转发给执行器(可中断在途)。 */\n signal?: AbortSignal\n /**\n * 可选进度回调:每次一个任务完成(或出错)时调用。\n * 调用方可在此 emit fan-in 事件(如 `{type:'parallel.fanIn',completedCount,totalCount}`)。\n */\n onProgress?: (completedCount: number, totalCount: number) => void\n}\n\n/**\n * 全仓唯一并发池原语(M24-02)。\n *\n * endgame review 修复(弃跑兄弟):旧实现 `await Promise.race(running)` 在某成员 reject 时直接外抛,\n * 其余在途任务变成**无 await 的孤儿** → 后续 reject 触发 unhandledRejection、且谁也不取消它们。\n * 现在:① 每个任务包成**永不 reject** 的 wrapper(race 不再因兄弟失败而抛,所有任务都被排空);\n * ② 首个失败记录 firstError 并 abort 内部控制器(转发给执行器取消在途)+ 清空 pending(不再启动新任务);\n * ③ finally 里 allSettled 排空残余,确保无孤儿;④ 全部结束后再上抛 firstError。\n * 顺带修了旧实现的一个潜伏 bug:外部 signal abort 且仍有 pending 时,旧循环会空转(running 排空后\n * pending 非空、canStart=false、无 await → CPU busy loop)——现在 abort/fail 都清 pending、干净退出。\n */\nexport async function runConcurrent<T>(\n steps: readonly T[],\n options: ConcurrentOptions<T>,\n): Promise<void> {\n const { cap, executor, signal, onProgress } = options\n if (steps.length === 0) return\n\n const safeCap = Number.isFinite(cap) && cap >= 1 ? Math.floor(cap) : 1\n\n const total = steps.length\n const pending = [...steps]\n const running = new Set<Promise<void>>()\n let completed = 0\n let i = 0\n let firstError: unknown\n let failed = false\n\n const internal = new AbortController()\n const onExternalAbort = (): void => internal.abort()\n if (signal) {\n if (signal.aborted) internal.abort()\n else signal.addEventListener('abort', onExternalAbort, { once: true })\n }\n\n try {\n while (pending.length > 0 || running.size > 0) {\n if (internal.signal.aborted || failed) {\n pending.length = 0\n }\n\n while (running.size < safeCap && pending.length > 0) {\n const step = pending.shift()!\n const idx = i++\n let p!: Promise<void>\n p = (async () => {\n try {\n await executor(step, idx, internal.signal)\n } catch (err) {\n if (!failed) {\n firstError = err\n failed = true\n }\n internal.abort()\n } finally {\n running.delete(p)\n completed++\n onProgress?.(completed, total)\n }\n })()\n running.add(p)\n }\n\n if (running.size > 0) {\n await Promise.race(running)\n }\n }\n } finally {\n if (running.size > 0) await Promise.allSettled(running)\n if (signal) signal.removeEventListener('abort', onExternalAbort)\n }\n\n if (failed) {\n throw firstError\n }\n}\n","import { runConcurrent } from '../concurrent'\nimport { withStep } from '../strategy'\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult, StepResult } from '../strategy'\n\nexport const PARALLEL_STRATEGY: OrchestrationStrategy = {\n name: 'parallel',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n const agents = [...ctx.config.agents.values()]\n const cap = ctx.config.maxConcurrency ?? agents.length\n const tasks = agents.map((a) => ({ agentId: a.id, input }))\n const slots: Array<StepResult | undefined> = new Array(tasks.length)\n\n ctx.emit({ type: 'parallel.fanOut', agentIds: agents.map((a) => a.id) })\n\n await runConcurrent(tasks, {\n cap,\n executor: async (task, index) => {\n if (!ctx.config.agents.has(task.agentId)) return\n const steps: StepResult[] = []\n await withStep(ctx, task.agentId, task.input, steps, { signal: ctx.signal })\n slots[index] = steps[0]!\n },\n signal: ctx.signal,\n onProgress: (completed, total) => {\n ctx.emit({ type: 'parallel.fanIn', completedCount: completed, totalCount: total })\n },\n })\n\n const results = slots.filter((s): s is StepResult => s !== undefined)\n const combined = results.map((r) => `## ${r.agentId}\\n${r.output.text}`).join('\\n\\n')\n return { steps: results, output: combined }\n },\n}\n","import { createLogger } from '@x-otto/shared'\nimport { z } from 'zod'\n\nimport { runConcurrent } from '../concurrent'\n\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\nimport type { HierarchicalTask, SwarmTurnResult } from '../types'\n\nconst logger = createLogger('otto:orchestrator:strategies:hierarchical')\n\nconst taskSchema = z.object({\n description: z.string(),\n assignedTo: z.string().optional(),\n})\n\n/**\n * 对未知值做逐元素 zod 校验过滤,而非整数组校验(整数组校验会因单个坏元素全盘拒绝)。\n */\nfunction parseAndFilterTasks(raw: unknown): HierarchicalTask[] {\n if (!Array.isArray(raw)) return []\n const tasks: HierarchicalTask[] = []\n for (const item of raw) {\n const result = taskSchema.safeParse(item)\n if (result.success) {\n tasks.push(result.data)\n }\n }\n return tasks\n}\n\nexport function parsePlanOutput(text: string): HierarchicalTask[] {\n // 优先:整体 JSON.parse\n try {\n const parsed = JSON.parse(text.trim())\n const direct = parseAndFilterTasks(parsed)\n if (direct.length > 0) {\n return direct\n }\n } catch {\n // 继续降级\n }\n\n // 兜底:正则匹配 + zod 逐元素校验\n const jsonMatch = text.match(/\\[[\\s\\S]*\\]/)\n if (jsonMatch) {\n try {\n const parsed = JSON.parse(jsonMatch[0])\n const fallback = parseAndFilterTasks(parsed)\n if (fallback.length > 0) {\n return fallback\n }\n } catch {\n // 继续降级\n }\n }\n\n // 最终兜底:warn + 空数组(调用方 tasks.length === 0 分支走既有单任务兜底)\n logger.warn(\n { textPreview: text.slice(0, 200) },\n 'hierarchical supervisor plan parse failed, degrading to single task',\n )\n return []\n}\n\nexport const HIERARCHICAL_STRATEGY: OrchestrationStrategy = {\n name: 'hierarchical',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n const supervisorId: string =\n ctx.config.supervisorId ?? [...ctx.config.agents.values()][0]?.id ?? ''\n if (!supervisorId) {\n return { steps: [], output: '' }\n }\n\n const supervisorDef = ctx.config.agents.get(supervisorId)\n if (!supervisorDef || supervisorDef.kind !== 'agent') {\n return { steps: [], output: '' }\n }\n\n ctx.emit({ type: 'agent.start', agentId: supervisorId })\n ctx.emit({ type: 'hierarchy.delegate', supervisor: supervisorId, worker: '', task: 'planning' })\n const planStart = ctx.clock.now()\n\n const planOutput = await ctx.createStepRunner(\n supervisorDef,\n `You are the supervisor. Break down this task into subtasks:\\n\\n${input}\\n\\nFor each subtask, specify:\\n1. A clear description\\n2. Which agent should execute it (choose from: ${[...ctx.config.agents.values()].map((a) => a.id).join(', ')})\\n\\nRespond with a JSON array of {description, assignedTo}. Output only the JSON array, no other text.`,\n { signal: ctx.signal },\n )\n\n const planDur = ctx.clock.now() - planStart\n ctx.emit({ type: 'agent.end', agentId: supervisorId, durationMs: planDur })\n const steps: StrategyResult['steps'] = [\n { agentId: supervisorId, output: planOutput, durationMs: planDur },\n ]\n\n let tasks = parsePlanOutput(planOutput.text)\n\n if (tasks.length === 0) {\n tasks = [{ description: input, assignedTo: undefined }]\n }\n\n const taskResults: Array<{\n task: HierarchicalTask\n agentId: string\n output: SwarmTurnResult\n durationMs: number\n }> = []\n\n const fallbackWorker =\n [...ctx.config.agents.values()].find((a) => a.id !== supervisorId)?.id ?? supervisorId\n const assignedTasks = tasks.map((t) => ({\n ...t,\n agentId: t.assignedTo ?? fallbackWorker,\n }))\n\n const cap = ctx.config.maxConcurrency ?? assignedTasks.length\n\n await runConcurrent(assignedTasks, {\n cap,\n executor: async (task) => {\n try {\n const workerDef = ctx.config.agents.get(task.agentId)\n if (!workerDef) return\n\n ctx.emit({ type: 'agent.start', agentId: task.agentId })\n ctx.emit({\n type: 'hierarchy.delegate',\n supervisor: supervisorId,\n worker: task.agentId,\n task: task.description,\n })\n const start = ctx.clock.now()\n\n const output = await ctx.createStepRunner(workerDef, task.description, {\n signal: ctx.signal,\n })\n\n const dur = ctx.clock.now() - start\n ctx.emit({ type: 'agent.end', agentId: task.agentId, durationMs: dur })\n taskResults.push({ task, agentId: task.agentId, output, durationMs: dur })\n } catch (err) {\n ctx.emit({\n type: 'error',\n agentId: task.agentId,\n error: err instanceof Error ? err : new Error(String(err)),\n })\n // 架构修复 M2:emit 后必须 rethrow,否则 runConcurrent 的 firstError 永不触发,\n // 全部 worker 失败仍返回 success(fail-fast 失效)。\n throw err\n }\n },\n signal: ctx.signal,\n })\n\n for (const tr of taskResults) {\n steps.push({ agentId: tr.agentId, output: tr.output, durationMs: tr.durationMs })\n }\n\n const summaryParts = taskResults.map(\n (r) => `## ${r.task.description} (by ${r.agentId})\\n${r.output.text}`,\n )\n const synthesis = [\n 'The subtasks have been completed. Here are the results:',\n '',\n ...summaryParts,\n '',\n 'Synthesize these results into a final coherent response for the original task:',\n input,\n ].join('\\n')\n\n if (ctx.signal.aborted) {\n return { steps, output: summaryParts.join('\\n\\n') }\n }\n\n ctx.emit({ type: 'agent.start', agentId: supervisorId })\n const synStart = ctx.clock.now()\n\n const synOutput = await ctx.createStepRunner(supervisorDef, synthesis, { signal: ctx.signal })\n\n const synDur = ctx.clock.now() - synStart\n ctx.emit({ type: 'agent.end', agentId: supervisorId, durationMs: synDur })\n steps.push({ agentId: supervisorId, output: synOutput, durationMs: synDur })\n\n return { steps, output: synOutput.text }\n },\n}\n","import { withStep } from '../strategy'\nimport { AgentNotFoundError, SwarmConfigError } from '../errors'\n\nimport type { OrchestrationStrategy, StrategyContext, StrategyResult } from '../strategy'\n\nexport const ROUTER_STRATEGY: OrchestrationStrategy = {\n name: 'router',\n\n async execute(input: string, ctx: StrategyContext): Promise<StrategyResult> {\n if (!ctx.router) {\n throw new SwarmConfigError('Router not configured')\n }\n\n const agents = [...ctx.config.agents.values()]\n const decision = await ctx.router.route(input, agents)\n\n if (!ctx.config.agents.has(decision.agentId)) {\n throw new AgentNotFoundError(decision.agentId)\n }\n\n ctx.emit({ type: 'routing.decision', decision })\n\n const steps: StrategyResult['steps'] = []\n const output = await withStep(ctx, decision.agentId, input, steps, { signal: ctx.signal })\n\n return { steps, output: output.text }\n },\n}\n","import { StrategyRegistry } from '../strategy'\nimport { HANDOFF_STRATEGY } from './handoff'\nimport { SEQUENTIAL_STRATEGY } from './sequential'\nimport { PARALLEL_STRATEGY } from './parallel'\nimport { HIERARCHICAL_STRATEGY } from './hierarchical'\nimport { ROUTER_STRATEGY } from './router'\n\nexport function createDefaultStrategyRegistry(): StrategyRegistry {\n const registry = new StrategyRegistry()\n registry.register(HANDOFF_STRATEGY)\n registry.register(SEQUENTIAL_STRATEGY)\n registry.register(PARALLEL_STRATEGY)\n registry.register(HIERARCHICAL_STRATEGY)\n registry.register(ROUTER_STRATEGY)\n return registry\n}\n\nexport { HANDOFF_STRATEGY } from './handoff'\nexport { SEQUENTIAL_STRATEGY } from './sequential'\nexport { PARALLEL_STRATEGY } from './parallel'\nexport { HIERARCHICAL_STRATEGY } from './hierarchical'\nexport { ROUTER_STRATEGY } from './router'\n","import { SwarmRouter } from './router'\nimport { createDefaultStrategyRegistry } from './strategies'\nimport { SwarmConfigError } from './errors'\n\nimport type {\n SwarmAgentDef,\n SwarmAgentId,\n SwarmAgentMember,\n SwarmConfig,\n SwarmEvent,\n SwarmEventHandler,\n SwarmTurnResult,\n} from './types'\nimport type { AgentTurnInput, Clock, CoreToolDescriptor } from '../types'\nimport { systemClock } from '../types'\nimport type {\n OrchestrationStrategy,\n StrategyContext,\n StrategyResult,\n Router,\n StepResult,\n} from './strategy'\nimport type { StrategyRegistry } from './strategy'\n\n/**\n * Swarm — 多 Agent 协作框架(策略引擎化)。\n *\n * OrchestrationStrategy 取代封闭枚举+switch——新模式 = 实现接口 + registry.register(),\n * 不碰 Swarm.run()、不碰核心结果类型。\n */\nexport class Swarm {\n private readonly config: SwarmConfig\n private readonly agents: Map<string, SwarmAgentDef>\n private readonly router: SwarmRouter | null\n private readonly registry: StrategyRegistry\n private readonly clock: Clock\n\n constructor(config: SwarmConfig) {\n this.validateConfig(config)\n\n this.config = config\n this.agents = new Map()\n this.clock = config.clock ?? systemClock\n\n for (const agent of config.agents) {\n this.agents.set(agent.id, agent)\n }\n\n this.router = config.router ? new SwarmRouter(config.router) : null\n\n this.registry = createDefaultStrategyRegistry()\n }\n\n getAgents(): SwarmAgentDef[] {\n return [...this.agents.values()]\n }\n\n getAgent(id: SwarmAgentId): SwarmAgentDef | undefined {\n return this.agents.get(id)\n }\n\n /** 注册/替换策略(§4-12:host 可追加新模式,不碰核心)。返回 disposer 用于注销。 */\n registerStrategy(strategy: OrchestrationStrategy): () => void {\n return this.registry.register(strategy)\n }\n\n /** 获取已注册策略名列表。 */\n getStrategyNames(): string[] {\n return this.registry.names()\n }\n\n private emitEvent(event: SwarmEvent): void {\n // 私有回调(RFC-107 D1 / M-N6 保留)\n this.config.onSwarmEvent?.(event)\n // RFC-398 M6:删 swarmEvent 死桥接——swarmEvent 字段全仓零消费方,\n // 把编排事件塞进 task.started 是语义错位(编排事件 ≠ 任务事件)。\n // 沿用 RFC-107 D1 定稿决策「不新建 swarm.* HookTiming」,直接删桥接(YAGNI)。\n // onSwarmEvent 私有回调保留(合法的事件通道,有真实消费方时用)。\n }\n\n /** 构建 StrategyContext——每次 run() 全新构造(context/signal 属单次运行)。 */\n private buildStrategyContext(signal: AbortSignal): StrategyContext {\n const emit: SwarmEventHandler = (event) => this.emitEvent(event)\n\n const createStepRunner: StrategyContext['createStepRunner'] = (agentDef, input, opts) =>\n this.executeMemberTurn(agentDef, input, opts?.signal ?? signal, opts?.coreTools)\n\n const ctx: StrategyContext = {\n createStepRunner,\n emit,\n router: this.router as Router,\n signal,\n clock: this.clock,\n config: {\n name: this.config.name,\n agents: this.agents,\n entryAgentId: this.config.entryAgentId,\n pipeline: this.config.pipeline,\n supervisorId: this.config.supervisorId,\n maxHandoffDepth: this.config.maxHandoffDepth,\n maxConcurrency: this.config.maxConcurrency,\n },\n }\n\n return ctx\n }\n\n /**\n * 运行 Swarm — 从注册表取策略并执行。\n */\n async run(input: string, options?: { signal?: AbortSignal }): Promise<SwarmRunResult> {\n const signal = options?.signal ?? new AbortController().signal\n const startTime = this.clock.now()\n const emit: SwarmEventHandler = (event) => this.emitEvent(event)\n\n emit({\n type: 'swarm.start',\n pattern: this.config.pattern,\n agentCount: this.agents.size,\n })\n\n const strategy = this.registry.get(this.config.pattern)\n if (!strategy) {\n throw new SwarmConfigError(\n `Unknown pattern: \"${this.config.pattern}\". Registered strategies: ${this.registry.names().join(', ')}`,\n )\n }\n\n try {\n const ctx = this.buildStrategyContext(signal)\n const result: StrategyResult = await strategy.execute(input, ctx)\n\n emit({ type: 'swarm.end', totalDurationMs: this.clock.now() - startTime })\n\n return {\n pattern: this.config.pattern,\n steps: result.steps,\n output: result.output,\n durationMs: this.clock.now() - startTime,\n }\n } catch (error) {\n emit({ type: 'swarm.end', totalDurationMs: this.clock.now() - startTime })\n throw error\n }\n }\n\n /**\n * 执行单个 swarm 成员的 agent turn(B+ 门禁①:经 TaskExecutor 执行)。\n * team 成员走 runNested(递归子 swarm)。\n */\n private async executeMemberTurn(\n agentDef: SwarmAgentDef,\n input: string,\n signal: AbortSignal,\n coreTools?: CoreToolDescriptor[],\n ): Promise<SwarmTurnResult> {\n if (agentDef.kind === 'team') {\n // RFC-332 M1:nested team 语义显式化——core 工具(handoff)对子团队整体无意义\n // (子 swarm 有自己的策略状态机),descriptor 不透传,记录诊断而非静默丢弃。\n if (coreTools?.length) {\n this.config.onSwarmEvent?.({\n type: 'error',\n agentId: agentDef.id,\n error: new Error(\n `Nested team \"${agentDef.id}\" does not support core tools (${coreTools.map((d) => d.name).join(', ')}); descriptors dropped`,\n ),\n })\n }\n return agentDef.runNested(input, signal)\n }\n\n const member = agentDef as SwarmAgentMember\n // M-B2: 类型安全调用——config.runAgentTurn 已是 AgentTurnInput → AgentTurnResult,\n // 经 Orchestrator.runAgentTurn → TaskExecutor 获得重试/熔断/并发闸/深度护栏。\n // RFC-332 M3:member.tools 已是纯数据 AgentToolDef[],无需再做 execute 剥离投影\n // (剥离发生在宿主解析层构造 SwarmAgentDef 时,orchestrator 全程不见 AgentTool)。\n const result = await this.config.runAgentTurn({\n agentId: member.id,\n prompt: input,\n systemPrompt: member.systemPrompt,\n tools: member.tools,\n coreTools,\n model: member.model?.id,\n maxToolTurns: member.maxToolTurns,\n thinkingLevel: member.thinkingLevel as AgentTurnInput['thinkingLevel'],\n maxTokens: member.maxTokens,\n temperature: member.temperature,\n sessionId: this.config.runId,\n depth: this.config.depth,\n // RFC-371 M-A(元评审 2026-08-13 补接线):父任务锚点随成员 turn 透传。\n parentTaskId: this.config.parentTaskId,\n signal,\n })\n\n return {\n agentId: result.agentId,\n messages: (result.messages ?? []) as SwarmTurnResult['messages'],\n text: result.text,\n handoff: result.handoff,\n tokenUsage: result.tokenUsage ?? { input: 0, output: 0, cacheRead: 0 },\n durationMs: result.durationMs,\n }\n }\n\n private validateConfig(config: SwarmConfig): void {\n if (!config.name) {\n throw new SwarmConfigError('Swarm name is required')\n }\n\n if (!config.agents || config.agents.length === 0) {\n throw new SwarmConfigError('At least one agent is required')\n }\n\n if (!config.runAgentTurn) {\n throw new SwarmConfigError('runAgentTurn factory is required')\n }\n\n const ids = new Set<string>()\n for (const agent of config.agents) {\n if (ids.has(agent.id)) {\n throw new SwarmConfigError(`Duplicate agent ID: \"${agent.id}\"`)\n }\n ids.add(agent.id)\n }\n\n for (const agent of config.agents) {\n if (agent.kind === 'agent' && agent.handoffTargets) {\n for (const targetId of agent.handoffTargets) {\n if (!ids.has(targetId)) {\n throw new SwarmConfigError(\n `Agent \"${agent.id}\" references unknown handoff target \"${targetId}\"`,\n )\n }\n }\n }\n }\n }\n}\n\nexport interface SwarmRunResult {\n /** 模式名(保留判别字段,service/CLI 据此消费)。 */\n pattern: string\n /** 所有 step 的执行记录。 */\n steps: StepResult[]\n /** 最终输出文本。 */\n output: string\n durationMs: number\n}\n\nexport function createSwarm(config: SwarmConfig): Swarm {\n return new Swarm(config)\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x-otto/orchestrator",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0-alpha.9",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist"
|
|
6
6
|
],
|
|
@@ -20,12 +20,11 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"zod": "^3.24.4",
|
|
23
|
-
"@x-otto/
|
|
24
|
-
"@x-otto/
|
|
25
|
-
"@x-otto/orchestration-contracts": "0.0
|
|
26
|
-
"@x-otto/
|
|
27
|
-
"@x-otto/
|
|
28
|
-
"@x-otto/shared": "0.1.0-alpha.6"
|
|
23
|
+
"@x-otto/hook-contracts": "0.1.0-alpha.9",
|
|
24
|
+
"@x-otto/hooks": "0.1.0-alpha.9",
|
|
25
|
+
"@x-otto/orchestration-contracts": "0.1.0-alpha.9",
|
|
26
|
+
"@x-otto/shared": "0.1.0-alpha.9",
|
|
27
|
+
"@x-otto/interchange": "0.1.0-alpha.9"
|
|
29
28
|
},
|
|
30
29
|
"scripts": {
|
|
31
30
|
"build": "tsdown",
|