@x-otto/orchestrator 0.0.1-alpha.0 → 0.0.1-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,27 +1,27 @@
1
1
  # @x-otto/orchestrator
2
2
 
3
- ## 模块定位
3
+ ## Module Purpose
4
4
 
5
- 管理多 Agent 任务的创建、调度、重试与生命周期。提供 TaskStore + TaskExecutor + CircuitBreaker 组合。
5
+ Manages the creation, scheduling, retry, and lifecycle of multi-agent tasks. Provides a combined TaskStore + TaskExecutor + CircuitBreaker.
6
6
 
7
- ## 核心功能
7
+ ## Core Features
8
8
 
9
- | 模块 | 功能 |
9
+ | Module | Function |
10
10
  | ----------------- | -------------------------------------------------------------- |
11
- | TaskStore | 任务 CRUD + 状态追踪(pending/running/completed/failed |
12
- | TaskExecutor | 同步/后台混合调度 + 并发限制 |
13
- | RetryPolicy | 指数退避 + 抖动重试策略 |
14
- | CircuitBreaker | 断路器(CLOSED/OPEN/HALF_OPEN |
15
- | Orchestrator | 业务级 APIdispatchTask/callAgent/getTask/updateTask |
16
- | BackgroundManager | 后台异步任务生命周期 |
11
+ | TaskStore | Task CRUD + status tracking (pending/running/completed/failed) |
12
+ | TaskExecutor | Mixed sync/background scheduling + concurrency limiting |
13
+ | RetryPolicy | Exponential backoff + jitter retry strategy |
14
+ | CircuitBreaker | Circuit breaker (CLOSED/OPEN/HALF_OPEN) |
15
+ | Orchestrator | Business-level API (dispatchTask/callAgent/getTask/updateTask) |
16
+ | BackgroundManager | Background async task lifecycle |
17
17
 
18
- ## 安装
18
+ ## Installation
19
19
 
20
20
  ```bash
21
21
  pnpm add @x-otto/orchestrator
22
22
  ```
23
23
 
24
- ## 快速开始
24
+ ## Quick Start
25
25
 
26
26
  ```ts
27
27
  import { Orchestrator, createTaskStore } from '@x-otto/orchestrator'
@@ -34,27 +34,27 @@ const taskId = await orchestrator.dispatchTask({
34
34
  prompt: 'Search for all unused imports in src/',
35
35
  })
36
36
 
37
- // 后台模式
37
+ // Background mode
38
38
  await orchestrator.dispatchTask({ ...opts, mode: 'background' })
39
39
  const result = await orchestrator.waitFor(taskId)
40
40
  ```
41
41
 
42
- ## 目录概览
42
+ ## Directory Overview
43
43
 
44
44
  ```
45
45
  src/
46
- types.ts # 核心类型
47
- task-store.ts # 任务存储
48
- task-executor.ts # 执行引擎
49
- retry-policy.ts # 重试策略
50
- circuit-breaker.ts # 断路器
51
- orchestrator.ts # 顶层协调器
52
- background-manager.ts # 后台管理
46
+ types.ts # core types
47
+ task-store.ts # task storage
48
+ task-executor.ts # execution engine
49
+ retry-policy.ts # retry policy
50
+ circuit-breaker.ts # circuit breaker
51
+ orchestrator.ts # top-level coordinator
52
+ background-manager.ts # background management
53
53
  index.ts
54
- tests/ # 7 个测试文件
54
+ tests/ # 7 test files
55
55
  ```
56
56
 
57
- ## 开发命令
57
+ ## Development Commands
58
58
 
59
59
  ```bash
60
60
  pnpm --filter @x-otto/orchestrator build
@@ -62,6 +62,6 @@ pnpm --filter @x-otto/orchestrator typecheck
62
62
  pnpm --filter @x-otto/orchestrator clean
63
63
  ```
64
64
 
65
- ## 关联包
65
+ ## Related Packages
66
66
 
67
- `@x-otto/agent`、`@x-otto/shared`、`@x-otto/env`
67
+ `@x-otto/agent`, `@x-otto/shared`, `@x-otto/env`
package/dist/index.d.ts CHANGED
@@ -77,6 +77,13 @@ interface RunSessionOptions {
77
77
  category?: string;
78
78
  /** 子会话承接的委托深度——使其 toolCtx.depth = 该深度,递归闭合护栏。 */
79
79
  depth?: number;
80
+ /**
81
+ * RFC-371 M-A:父任务锚点。子会话透传给 Agent → ToolExecutor,再经
82
+ * task_delegate/agent_call 回流 orchestrator 的 per-parent fan-out 闸。
83
+ * 与 `taskId` 的语义区别:taskId 是「本任务」的锚点(cancel 用),
84
+ * parentTaskId 是「派发本任务的父任务」锚点(fan-out 计数用)。
85
+ */
86
+ parentTaskId?: string;
80
87
  /**
81
88
  * 任务锚点:宿主据此登记 taskId→活动会话,使 cancel(updateTask/
82
89
  * background cancel → abortTask 回调)能中断正在执行的子会话。callAgent 等
@@ -180,6 +187,11 @@ interface AgentTurnInput {
180
187
  sessionId?: string;
181
188
  /** 委托深度(递归护栏,映射到 Agent 构造器)。 */
182
189
  depth?: number;
190
+ /**
191
+ * RFC-371 M-A:父任务锚点(透传面)。swarm member turn 的 TaskInput.parentTaskId
192
+ * 透传至此,经 AgentTurnInput → Agent 构造器 → ToolExecutor 回流 fan-out 闸。
193
+ */
194
+ parentTaskId?: string;
183
195
  }
184
196
  /** swarm member turn 结果(B+ 门禁①)。 */
185
197
  interface AgentTurnResult {
@@ -222,6 +234,12 @@ interface TaskInput {
222
234
  model?: string;
223
235
  /** 该任务所处委托深度(root 派发的任务 depth=1)。 */
224
236
  depth?: number;
237
+ /**
238
+ * RFC-371 S3:发起此任务的父任务 id(用于 per-parent 活跃扇出计数)。
239
+ * 缺省 undefined = root 层委派。由 `dispatchTask` 从 `args.parentTaskId` 透传,
240
+ * 供 orchestrator 在任务终态时释放该 parent 的活跃计数。
241
+ */
242
+ parentTaskId?: string;
225
243
  /** swarm 成员自定义 system prompt(覆盖默认)。 */
226
244
  systemPrompt?: string;
227
245
  tools?: AgentToolDef[];
@@ -300,6 +318,8 @@ interface OrchestratorOptions {
300
318
  * 确定性、无时钟依赖(区别于 TTL)。透传 `new TaskStore(maxStoredTasks)`。
301
319
  */
302
320
  maxStoredTasks?: number;
321
+ /** RFC-371 S3:per-parent 扇出上限的选项。 */
322
+ maxFanOutPerParent?: number;
303
323
  /** 委托深度上限(默认 1)。root(0)→child1 放行;depth1→child2>1 拒。swarm 深层可经此放宽。 */
304
324
  maxDelegationDepth?: number;
305
325
  }
@@ -314,6 +334,22 @@ declare class Orchestrator {
314
334
  private readonly delegationGate;
315
335
  private readonly runSession;
316
336
  private readonly maxDelegationDepth;
337
+ /**
338
+ * RFC-371 S3:per-parent 活跃扇出计数。key=parentTaskId,value=该 parent 当前在跑的子任务数。
339
+ *
340
+ * 为什么需要它(review S3):`Semaphore(maxActiveTasks)` 是全局的——它限制「同时在跑
341
+ * 的子任务总数」,不限制「同一个父派了多少个」。一个 buggy/贪心的 agent 可以在
342
+ * depth 许可内塞满整个并发闸,挤占其他 agent 的配额。这是资源公平/治理问题(不是
343
+ * 安全漏洞——depth=1 的子任务权限等同父),自迭代高频委派场景下尤为突出。
344
+ *
345
+ * 语义:计数随任务进入 running 态 +1,随终态(completed/failed/cancelled)-1。
346
+ * 不累计——一个 agent 完成一个子任务后可以继续派新的,只限制同时在跑。
347
+ * 上限 `maxFanOutPerParent` 默认 = maxActiveTasks / 2(同一父最多占一半并发配额,
348
+ * 留出另一半给其他 agent)。undefined parentTaskId = root 层委派,不受 per-parent
349
+ * 限制(只受全局闸约束)。
350
+ */
351
+ private readonly fanOutCounts;
352
+ private readonly maxFanOutPerParent;
317
353
  constructor(options: OrchestratorOptions);
318
354
  dispatchTask: TaskDispatch;
319
355
  /**
@@ -334,6 +370,8 @@ declare class Orchestrator {
334
370
  getBackgroundOutput: GetBackgroundOutput;
335
371
  cancelBackground: CancelBackground;
336
372
  dispose(): void;
373
+ private acquireFanOutSlot;
374
+ private releaseFanOutSlot;
337
375
  }
338
376
  //#endregion
339
377
  //#region src/swarm/types.d.ts
@@ -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,4 +1,4 @@
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";var i=class extends Error{constructor(e,t){super(e),this.reason=t,this.name=`TaskRejectedError`}};const a=new Set([`completed`,`failed`,`cancelled`]);var o=class{tasks=new Map;nextId=1;maxStoredTasks;constructor(e=1e3){this.maxStoredTasks=Math.max(1,e)}generateId(){return`task_${Date.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:Date.now()};return this.tasks.set(t.id,t),t}evictForCapacity(){let e=this.tasks.size-this.maxStoredTasks+1;if(e<=0)return;let t=[...this.tasks.values()].filter(e=>a.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 s={enabled:!0,maxAttempts:3,backoffMs:1e3,backoffMultiplier:2};var c=class e{config;constructor(e){this.config={...s,...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 l={enabled:!0,failureThreshold:5,resetTimeoutMs:6e4};var u=class{enabled;failureThreshold;resetTimeoutMs;consecutiveFailures=0;openedAt=null;constructor(e){let t={...l,...e};this.enabled=t.enabled,this.failureThreshold=t.failureThreshold,this.resetTimeoutMs=t.resetTimeoutMs}isOpen(){return!this.enabled||this.openedAt===null?!1:Date.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=Date.now())}reset(){this.consecutiveFailures=0,this.openedAt=null}},d=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){return new e(()=>new u(t))}static single(t){return new e(()=>t)}static fromWorkflowOptions(t){let n=t?.circuitBreaker;return e.perTarget({enabled:n?.enabled??!0,failureThreshold:n?.failureThreshold??5,resetTimeoutMs:n?.timeoutMs??6e4})}};function f(){let e=Error(`Semaphore acquire aborted`);return e.name=`AbortError`,e}var p=class{active=0;waiters=[];constructor(e){this.max=e}async acquire(e){if(e?.aborted)throw f();if(this.active<this.max){this.active+=1;return}await new Promise((t,n)=>{let r=()=>{a(),t()},i=()=>{let e=this.waiters.indexOf(r);e>=0&&this.waiters.splice(e,1),a(),n(f())},a=()=>e?.removeEventListener(`abort`,i);this.waiters.push(r),e?.addEventListener(`abort`,i,{once:!0})})}release(){let e=this.waiters.shift();e?e():--this.active}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}},m=class{constructor(e,t,n,r,i,a,o){this.taskStore=e,this.hookRegistry=t,this.retryPolicy=n,this.circuitBreakers=r,this.runSession=i,this.semaphore=a,this.runAgentTurn=o}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 i(`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);return this.runScheduled(t.id).catch(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:Date.now()}).catch(()=>{})}),{id:t.id}}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,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,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:Date.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 h(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:Date.now()}),this.hookRegistry.emit(`task.failed`,{task:{...n,status:`failed`},error:a}),{taskId:e,status:`failed`,error:a}}}};function h(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 g=class{constructor(e,t){this.taskStore=e,this.abortTask=t}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:Date.now()}),this.abortTask&&this.abortTask(e),{ok:!0,value:void 0}):{ok:!1,error:`Task not found id: ${e}`}}},_=class{taskStore;executor;backgroundManager;hookRegistry;circuitBreakers;delegationGate;runSession;maxDelegationDepth;constructor(e){let{hookRegistry:t,runSession:n,runAgentTurn:r,abortTask:i,workflowConfig:a,maxActiveTasks:s=10,maxStoredTasks:l,maxDelegationDepth:u=1}=e;this.hookRegistry=t,this.runSession=n,this.maxDelegationDepth=u,this.taskStore=new o(l);let f=c.fromWorkflowOptions(a);this.circuitBreakers=d.fromWorkflowOptions(a),this.delegationGate=new p(s),this.executor=new m(this.taskStore,t,f,this.circuitBreakers,n,this.delegationGate,r),this.backgroundManager=new g(this.taskStore,i)}dispatchTask=async t=>{let{childDepth:n,exceeded:r}=e(t.depth,this.maxDelegationDepth);if(r)return y(`Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`);let i={input:{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}};if(t.mode===`background`)return b(async()=>{let{id:e}=await this.executor.startTask(i);return{id:e,status:`pending`,output:`Background task created: ${e}`}});try{let e=await this.executor.runTask(i,t.signal);return e.status===`completed`?v({id:e.taskId,status:e.status,output:e.output?.text}):y(e.error?.message??`Unknown error`)}catch(e){return y(e)}};callAgent=async(t,n,r)=>{let{childDepth:i,exceeded:a}=e(r?.depth,this.maxDelegationDepth);if(a)return y(`Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`);let o=this.circuitBreakers.forTarget(t);return o.isOpen()?y(`Circuit breaker is open due to repeated failures. Try again later.`):this.delegationGate.run(async()=>{try{let e=await this.runSession({prompt:n,sessionMode:`ephemeral`,agentName:t,slot:r?.slot,model:r?.model,depth:i,signal:r?.signal});return o.success(),v(e.text)}catch(e){return o.failure(),y(e)}},r?.signal)};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}},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?v({id:t.id,status:t.status,prompt:t.input.prompt,output:t.output?.text,error:t.error?.message}):y(`Task not found: ${e}`)};listTasks=async e=>{let t=e&&e!==`all`?{status:e}:void 0;return v((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 y(`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}),v(`Task ${e} cancelled`)):y(t.error)}if(t===`retry`){if(n.status!==`failed`)return y(`Can only retry failed tasks. Current status: ${n.status}`);let e=await this.dispatchTask({prompt:n.input.prompt,subagent:n.input.subagent,category:n.input.category,mode:n.input.mode??`sync`,sessionId:n.input.sessionId,sessionMode:n.input.sessionMode,slot:n.input.slot,model:n.input.model});return e.ok?v(e.value.output??`Retry completed`):y(e.error)}return y(`Unknown action: ${t}`)};getBackgroundOutput=async e=>this.backgroundManager.getOutput(e);cancelBackground=async e=>this.backgroundManager.cancel(e);dispose(){this.circuitBreakers.resetAll()}};function v(e){return{ok:!0,value:e}}function y(e){return{ok:!1,error:x(e)}}async function b(e){try{return v(await e())}catch(e){return y(e)}}function x(e){return e instanceof Error?e.message:String(e)}var S=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}},C=class extends t{constructor(e){super(e,{code:`SWARM_ROUTING_ERROR`}),this.name=`RoutingError`}},w=class extends t{agentId;constructor(e){super(`Agent "${e}" not found in swarm`,{code:`SWARM_AGENT_NOT_FOUND`}),this.name=`AgentNotFoundError`,this.agentId=e}},T=class extends t{constructor(e){super(e,{code:`SWARM_CONFIG_ERROR`}),this.name=`SwarmConfigError`}},E=class{config;roundRobinIndex=0;constructor(e){if(e.strategy===`llm`&&!e.customRouter)throw new C(`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 C(`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 C(`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 C(`${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()))}},D=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 O(e,t,n){let i=t.map(e=>`- "${e.id}": ${e.name} — ${e.description}`).join(`
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";var i=class extends Error{constructor(e,t){super(e),this.reason=t,this.name=`TaskRejectedError`}};const a=new Set([`completed`,`failed`,`cancelled`]);var o=class{tasks=new Map;nextId=1;maxStoredTasks;constructor(e=1e3){this.maxStoredTasks=Math.max(1,e)}generateId(){return`task_${Date.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:Date.now()};return this.tasks.set(t.id,t),t}evictForCapacity(){let e=this.tasks.size-this.maxStoredTasks+1;if(e<=0)return;let t=[...this.tasks.values()].filter(e=>a.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 s={enabled:!0,maxAttempts:3,backoffMs:1e3,backoffMultiplier:2};var c=class e{config;constructor(e){this.config={...s,...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 l={enabled:!0,failureThreshold:5,resetTimeoutMs:6e4};var u=class{enabled;failureThreshold;resetTimeoutMs;consecutiveFailures=0;openedAt=null;constructor(e){let t={...l,...e};this.enabled=t.enabled,this.failureThreshold=t.failureThreshold,this.resetTimeoutMs=t.resetTimeoutMs}isOpen(){return!this.enabled||this.openedAt===null?!1:Date.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=Date.now())}reset(){this.consecutiveFailures=0,this.openedAt=null}},d=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){return new e(()=>new u(t))}static single(t){return new e(()=>t)}static fromWorkflowOptions(t){let n=t?.circuitBreaker;return e.perTarget({enabled:n?.enabled??!0,failureThreshold:n?.failureThreshold??5,resetTimeoutMs:n?.timeoutMs??6e4})}};function f(){let e=Error(`Semaphore acquire aborted`);return e.name=`AbortError`,e}var p=class{active=0;waiters=[];constructor(e){this.max=e}async acquire(e){if(e?.aborted)throw f();if(this.active<this.max){this.active+=1;return}await new Promise((t,n)=>{let r=()=>{a(),t()},i=()=>{let e=this.waiters.indexOf(r);e>=0&&this.waiters.splice(e,1),a(),n(f())},a=()=>e?.removeEventListener(`abort`,i);this.waiters.push(r),e?.addEventListener(`abort`,i,{once:!0})})}release(){let e=this.waiters.shift();e?e():--this.active}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}},m=class{constructor(e,t,n,r,i,a,o){this.taskStore=e,this.hookRegistry=t,this.retryPolicy=n,this.circuitBreakers=r,this.runSession=i,this.semaphore=a,this.runAgentTurn=o}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 i(`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);return this.runScheduled(t.id).catch(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:Date.now()}).catch(()=>{})}),{id:t.id}}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:Date.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 h(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:Date.now()}),this.hookRegistry.emit(`task.failed`,{task:{...n,status:`failed`},error:a}),{taskId:e,status:`failed`,error:a}}}};function h(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 g=class{constructor(e,t){this.taskStore=e,this.abortTask=t}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:Date.now()}),this.abortTask&&this.abortTask(e),{ok:!0,value:void 0}):{ok:!1,error:`Task not found id: ${e}`}}},_=class{taskStore;executor;backgroundManager;hookRegistry;circuitBreakers;delegationGate;runSession;maxDelegationDepth;fanOutCounts=new Map;maxFanOutPerParent;constructor(e){let{hookRegistry:t,runSession:n,runAgentTurn:r,abortTask:i,workflowConfig:a,maxActiveTasks:s=10,maxStoredTasks:l,maxDelegationDepth:u=1}=e;this.hookRegistry=t,this.runSession=n,this.maxDelegationDepth=u,this.maxFanOutPerParent=e.maxFanOutPerParent??Math.max(1,Math.floor(s/2)),this.taskStore=new o(l);let f=c.fromWorkflowOptions(a);this.circuitBreakers=d.fromWorkflowOptions(a),this.delegationGate=new p(s),this.executor=new m(this.taskStore,t,f,this.circuitBreakers,n,this.delegationGate,r),this.backgroundManager=new g(this.taskStore,i)}dispatchTask=async t=>{let{childDepth:n,exceeded:r}=e(t.depth,this.maxDelegationDepth);if(r)return y(`Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`);if(t.parentTaskId!==void 0&&(this.fanOutCounts.get(t.parentTaskId)??0)>=this.maxFanOutPerParent)return y(`Fan-out limit (${this.maxFanOutPerParent}) reached for parent task "${t.parentTaskId}" — wait for in-flight subtasks to complete before delegating more.`);let i={input:{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}}};if(t.mode===`background`)return b(async()=>{let{id:e}=await this.executor.startTask(i);return this.acquireFanOutSlot(t.parentTaskId),{id:e,status:`pending`,output:`Background task created: ${e}`}});this.acquireFanOutSlot(t.parentTaskId);try{let e=await this.executor.runTask(i,t.signal);return e.status===`completed`?v({id:e.taskId,status:e.status,output:e.output?.text}):y(e.error?.message??`Unknown error`)}catch(e){return y(e)}finally{this.releaseFanOutSlot(t.parentTaskId)}};callAgent=async(t,n,r)=>{let{childDepth:i,exceeded:a}=e(r?.depth,this.maxDelegationDepth);if(a)return y(`Delegation depth limit (${this.maxDelegationDepth}) reached — complete this subtask yourself instead of delegating further.`);if(r?.parentTaskId!==void 0&&(this.fanOutCounts.get(r.parentTaskId)??0)>=this.maxFanOutPerParent)return y(`Fan-out limit (${this.maxFanOutPerParent}) reached for parent task "${r.parentTaskId}" — wait for in-flight subtasks to complete before delegating more.`);let o=this.circuitBreakers.forTarget(t);return o.isOpen()?y(`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(),v(e.text)}catch(e){return o.failure(),y(e)}},r?.signal).finally(()=>{this.releaseFanOutSlot(r?.parentTaskId)}))};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}},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?v({id:t.id,status:t.status,prompt:t.input.prompt,output:t.output?.text,error:t.error?.message}):y(`Task not found: ${e}`)};listTasks=async e=>{let t=e&&e!==`all`?{status:e}:void 0;return v((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 y(`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}),v(`Task ${e} cancelled`)):y(t.error)}if(t===`retry`){if(n.status!==`failed`)return y(`Can only retry failed tasks. Current status: ${n.status}`);let e=n.input.depth===void 0?void 0:n.input.depth-1,t=await this.dispatchTask({prompt:n.input.prompt,subagent:n.input.subagent,category:n.input.category,mode:n.input.mode??`sync`,sessionId:n.input.sessionId,sessionMode:n.input.sessionMode,slot:n.input.slot,model:n.input.model,depth:e});return t.ok?v(t.value.output??`Retry completed`):y(t.error)}return y(`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.releaseFanOutSlot(t?.input.parentTaskId)}return t};dispose(){this.circuitBreakers.resetAll(),this.fanOutCounts.clear()}acquireFanOutSlot(e){e!==void 0&&this.fanOutCounts.set(e,(this.fanOutCounts.get(e)??0)+1)}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))}};function v(e){return{ok:!0,value:e}}function y(e){return{ok:!1,error:x(e)}}async function b(e){try{return v(await e())}catch(e){return y(e)}}function x(e){return e instanceof Error?e.message:String(e)}var S=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}},C=class extends t{constructor(e){super(e,{code:`SWARM_ROUTING_ERROR`}),this.name=`RoutingError`}},w=class extends t{agentId;constructor(e){super(`Agent "${e}" not found in swarm`,{code:`SWARM_AGENT_NOT_FOUND`}),this.name=`AgentNotFoundError`,this.agentId=e}},T=class extends t{constructor(e){super(e,{code:`SWARM_CONFIG_ERROR`}),this.name=`SwarmConfigError`}},E=class{config;roundRobinIndex=0;constructor(e){if(e.strategy===`llm`&&!e.customRouter)throw new C(`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 C(`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 C(`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 C(`${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()))}},D=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 O(e,t,n){let i=t.map(e=>`- "${e.id}": ${e.name} — ${e.description}`).join(`
2
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.`)}),readonly:!0,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 k(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 A={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 w(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;t.emit({type:`agent.start`,agentId:a});let c=Date.now(),l=await t.createStepRunner(e,o,{signal:t.signal,coreTools:i?[i]:void 0}),u=Date.now()-c;t.emit({type:`agent.end`,agentId:a,durationMs:u}),s.push({agentId:a,output:l,durationMs:u});let d=l.handoff;if(d){let e=d;if(!k(e,new Map(n.map(e=>[e.id,e]))).valid)return{steps:s,output:l.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:l.text}}throw new S(i,i)}},j={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;let n=t.config.agents.get(e);if(!n)continue;t.emit({type:`agent.start`,agentId:e});let a=Date.now(),o=await t.createStepRunner(n,i,{signal:t.signal}),s=Date.now()-a;t.emit({type:`agent.end`,agentId:e,durationMs:s}),r.push({agentId:e,output:o,durationMs:s}),i=o.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 M(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 N={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 M(i,{cap:r,executor:async(e,n)=>{try{let r=t.config.agents.get(e.agentId);if(!r)return;t.emit({type:`agent.start`,agentId:e.agentId});let i=Date.now(),o=await t.createStepRunner(r,e.input,{signal:t.signal}),s=Date.now()-i;t.emit({type:`agent.end`,agentId:e.agentId,durationMs:s}),a[n]={agentId:e.agentId,output:o,durationMs:s}}catch(n){t.emit({type:`error`,agentId:e.agentId,error:n instanceof Error?n:Error(String(n))})}},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
  `)}}},P=n(`otto:orchestrator:strategies:hierarchical`),F=r.object({description:r.string(),assignedTo:r.string().optional()});function I(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=F.safeParse(n);e.success&&t.push(e.data)}return t}function L(e){try{let t=I(JSON.parse(e.trim()));if(t.length>0)return t}catch{}let t=e.match(/\[[\s\S]*\]/);if(t)try{let e=I(JSON.parse(t[0]));if(e.length>0)return e}catch{}return P.warn({textPreview:e.slice(0,200)},`hierarchical supervisor plan parse failed, degrading to single task`),[]}const R={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=Date.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=Date.now()-i;t.emit({type:`agent.end`,agentId:n,durationMs:o});let s=[{agentId:n,output:a,durationMs:o}],c=L(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 M(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=Date.now(),a=await t.createStepRunner(r,e.description,{signal:t.signal}),o=Date.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){t.emit({type:`error`,agentId:e.agentId,error:n instanceof Error?n:Error(String(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(`
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/** 工具定义(本地 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\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 // ── 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 /** 委托深度上限(默认 1)。root(0)→child1 放行;depth1→child2>1 拒。swarm 深层可经此放宽。 */\n maxDelegationDepth?: number\n}\n","import type { Task, TaskInput, TaskStatus } 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\n constructor(maxStoredTasks = 1000) {\n this.maxStoredTasks = Math.max(1, maxStoredTasks)\n }\n\n private generateId(): string {\n return `task_${Date.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: Date.now(),\n }\n\n this.tasks.set(task.id, task)\n return task\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\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 consecutiveFailures = 0\n private openedAt: number | null = null\n\n constructor(config?: Partial<CircuitBreakerConfig>) {\n const resolvedConfig = { ...DEFAULT_CIRCUIT_BREAKER, ...config }\n\n this.enabled = resolvedConfig.enabled\n this.failureThreshold = resolvedConfig.failureThreshold\n this.resetTimeoutMs = resolvedConfig.resetTimeoutMs\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 (Date.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 = Date.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(config?: Partial<CircuitBreakerConfig>): CircuitBreakerRegistry {\n return new CircuitBreakerRegistry(() => new CircuitBreaker(config))\n }\n\n /** 所有 target 共用同一个熔断器实例——保留旧的全局语义(测试/向后兼容用)。 */\n static single(breaker: CircuitBreaker): CircuitBreakerRegistry {\n return new CircuitBreakerRegistry(() => breaker)\n }\n\n static fromWorkflowOptions(wf?: WorkflowOptions): CircuitBreakerRegistry {\n const circuit = wf?.circuitBreaker\n return CircuitBreakerRegistry.perTarget({\n enabled: circuit?.enabled ?? true,\n failureThreshold: circuit?.failureThreshold ?? 5,\n resetTimeoutMs: circuit?.timeoutMs ?? 60_000,\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\nexport class Semaphore {\n private active = 0\n private readonly waiters: Array<() => void> = []\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 = (): void => {\n cleanup()\n resolve()\n }\n const onAbort = (): void => {\n const idx = this.waiters.indexOf(waiter)\n if (idx >= 0) {\n this.waiters.splice(idx, 1)\n }\n cleanup()\n reject(abortError())\n }\n const cleanup = (): void => 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()\n } else {\n this.active -= 1\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 } from './types'\nimport { CircuitBreaker, CircuitBreakerRegistry } from './retry'\nimport { Semaphore } from './semaphore'\n\nimport type { HookRegistry } from '@x-otto/hooks'\nimport type { 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 * 任务锚点:宿主据此登记 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?: (input: import('./types').AgentTurnInput) => Promise<import('./types').AgentTurnResult>,\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 }> {\n this.assertCircuit(unit.input.subagent)\n const task = await this.register(unit)\n void this.runScheduled(task.id).catch(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: Date.now(),\n })\n .catch(() => {})\n })\n return { id: task.id }\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 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 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: Date.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: Date.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 { TaskStore } from './task-store'\n\nexport class BackgroundManager {\n constructor(\n private readonly taskStore: TaskStore,\n private readonly abortTask?: (taskId: string) => void,\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: Date.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} from '@x-otto/orchestration-contracts'\nimport { checkDelegationDepth } from '@x-otto/orchestration-contracts'\nimport type { OrchestratorOptions, TaskUnit, AgentTurnInput, AgentTurnResult } 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\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.taskStore = new TaskStore(maxStoredTasks)\n const retryPolicy = RetryPolicy.fromWorkflowOptions(workflowConfig)\n this.circuitBreakers = CircuitBreakerRegistry.fromWorkflowOptions(workflowConfig)\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 )\n\n this.backgroundManager = new BackgroundManager(this.taskStore, abortTask)\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 unit: TaskUnit = {\n input: {\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 },\n }\n\n if (args.mode === 'background') {\n return attempt(async () => {\n const { id } = await this.executor.startTask(unit)\n return { id, status: 'pending' as const, output: `Background task created: ${id}` }\n })\n }\n\n try {\n const result = await this.executor.runTask(unit, args.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 }\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 return this.delegationGate.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 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 }\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 },\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(\n result.error?.message ?? `Swarm member turn failed: ${result.status}`,\n )\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 const result = await this.dispatchTask({\n prompt: task.input.prompt,\n subagent: task.input.subagent,\n category: task.input.category,\n mode: task.input.mode ?? 'sync',\n sessionId: task.input.sessionId,\n sessionMode: task.input.sessionMode,\n slot: task.input.slot,\n model: task.input.model,\n })\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 return this.backgroundManager.cancel(id)\n }\n\n dispose(): void {\n this.circuitBreakers.resetAll()\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 }\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(\n (s): s is StrategyResult['steps'][number] => s !== undefined,\n )\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 }\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, CoreToolDescriptor } 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\n constructor(config: SwarmConfig) {\n this.validateConfig(config)\n\n this.config = config\n this.agents = new Map()\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: Date.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 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":"6JAwKA,IAAa,EAAb,cAAuC,KAAM,CAC3C,YACE,EACA,EACA,CACA,MAAM,EAAQ,CAFL,KAAA,OAAA,EAGT,KAAK,KAAO,sBCtKhB,MAAM,EAA6C,IAAI,IAAgB,CACrE,YACA,SACA,YACD,CAAC,CAEF,IAAa,EAAb,KAAuB,CACrB,MAAyB,IAAI,IAC7B,OAAiB,EAMjB,eAEA,YAAY,EAAiB,IAAM,CACjC,KAAK,eAAiB,KAAK,IAAI,EAAG,EAAe,CAGnD,YAA6B,CAC3B,MAAO,QAAQ,KAAK,KAAK,CAAC,GAAG,KAAK,WAGpC,MAAM,OAAO,EAAiC,CAC5C,KAAK,kBAAkB,CAEvB,IAAM,EAAa,CACjB,GAAI,KAAK,YAAY,CACrB,OAAQ,UACR,cAAe,EAAM,aAAe,YACpC,SAAU,EACV,YAAa,EACb,QACA,UAAW,KAAK,KAAK,CACtB,CAGD,OADA,KAAK,MAAM,IAAI,EAAK,GAAI,EAAK,CACtB,EAQT,kBAAiC,CAC/B,IAAI,EAAW,KAAK,MAAM,KAAO,KAAK,eAAiB,EACvD,GAAI,GAAY,EACd,OAGF,IAAM,EAAsB,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CACjD,OAAQ,GAAM,EAAkB,IAAI,EAAE,OAAO,CAAC,CAC9C,MAAM,EAAG,KAAO,EAAE,aAAe,EAAE,YAAc,EAAE,aAAe,EAAE,WAAW,CAElF,IAAK,IAAM,KAAQ,EAAqB,CACtC,GAAI,GAAY,EACd,MAEF,KAAK,MAAM,OAAO,EAAK,GAAG,CAC1B,IAGE,EAAW,GACb,QAAQ,KACN,wBAAwB,KAAK,eAAe,eAAe,EAAS,kGAErE,CAIL,MAAM,IAAI,EAAuC,CAC/C,OAAO,KAAK,MAAM,IAAI,EAAG,CAG3B,MAAM,KAAK,EAAmD,CAC5D,IAAI,EAAS,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CAIrC,OAHI,GAAQ,SACV,EAAS,EAAO,OAAQ,GAAM,EAAE,SAAW,EAAO,OAAO,EAEpD,EAGT,MAAM,OACJ,EACA,EAGe,CACf,IAAM,EAAO,KAAK,MAAM,IAAI,EAAG,CAC/B,GAAI,CAAC,EACH,MAAU,MAAM,mBAAmB,IAAK,CAG1C,OAAO,OAAO,EAAM,EAAM,CAG5B,MAAM,OAAO,EAA8B,CACzC,OAAO,KAAK,MAAM,OAAO,EAAG,GClGhC,MAAM,EAA6B,CACjC,QAAS,GACT,YAAa,EACb,UAAW,IACX,kBAAmB,EACpB,CAED,IAAa,EAAb,MAAa,CAAY,CACvB,OAEA,YAAY,EAA+B,CACzC,KAAK,OAAS,CAAE,GAAG,EAAe,GAAG,EAAQ,CAG/C,YAAY,EAA0B,CACpC,OAAO,KAAK,OAAO,SAAW,EAAU,KAAK,OAAO,YAGtD,WAAW,EAAyB,CAClC,OAAO,KAAK,OAAO,UAAY,KAAK,OAAO,oBAAsB,EAAU,GAG7E,OAAO,oBAAoB,EAAmC,CAC5D,IAAM,EAAQ,GAAI,MAElB,OAAO,IAAI,EAAY,CACrB,QAAS,GAAO,SAAW,GAC3B,YAAa,GAAO,aAAe,EACpC,CAAC,GAUN,MAAM,EAAgD,CACpD,QAAS,GACT,iBAAkB,EAClB,eAAgB,IACjB,CAED,IAAa,EAAb,KAA4B,CAC1B,QACA,iBACA,eACA,oBAA8B,EAC9B,SAAkC,KAElC,YAAY,EAAwC,CAClD,IAAM,EAAiB,CAAE,GAAG,EAAyB,GAAG,EAAQ,CAEhE,KAAK,QAAU,EAAe,QAC9B,KAAK,iBAAmB,EAAe,iBACvC,KAAK,eAAiB,EAAe,eAGvC,QAAkB,CAchB,MAbI,CAAC,KAAK,SAGN,KAAK,WAAa,KACb,GAGL,KAAK,KAAK,CAAG,KAAK,UAAY,KAAK,gBACrC,KAAK,SAAW,KAChB,KAAK,oBAAsB,EACpB,IAGF,GAGT,SAAgB,CACd,KAAK,oBAAsB,EAC3B,KAAK,SAAW,KAGlB,SAAgB,CACd,KAAK,sBACD,KAAK,qBAAuB,KAAK,mBACnC,KAAK,SAAW,KAAK,KAAK,EAI9B,OAAc,CACZ,KAAK,oBAAsB,EAC3B,KAAK,SAAW,OASP,EAAb,MAAa,CAAuB,CAClC,SAA4B,IAAI,IAEhC,YAAY,EAAgD,CAA/B,KAAA,QAAA,EAE7B,UAAU,EAAgC,CACxC,IAAI,EAAU,KAAK,SAAS,IAAI,EAAO,CAKvC,OAJK,IACH,EAAU,KAAK,SAAS,CACxB,KAAK,SAAS,IAAI,EAAQ,EAAQ,EAE7B,EAGT,UAAiB,CACf,IAAK,IAAM,KAAW,KAAK,SAAS,QAAQ,CAC1C,EAAQ,OAAO,CAKnB,OAAO,UAAU,EAAgE,CAC/E,OAAO,IAAI,MAA6B,IAAI,EAAe,EAAO,CAAC,CAIrE,OAAO,OAAO,EAAiD,CAC7D,OAAO,IAAI,MAA6B,EAAQ,CAGlD,OAAO,oBAAoB,EAA8C,CACvE,IAAM,EAAU,GAAI,eACpB,OAAO,EAAuB,UAAU,CACtC,QAAS,GAAS,SAAW,GAC7B,iBAAkB,GAAS,kBAAoB,EAC/C,eAAgB,GAAS,WAAa,IACvC,CAAC,GCzIN,SAAS,GAAoB,CAC3B,IAAM,EAAU,MAAM,4BAA4B,CAElD,MADA,GAAI,KAAO,aACJ,EAGT,IAAa,EAAb,KAAuB,CACrB,OAAiB,EACjB,QAA8C,EAAE,CAEhD,YAAY,EAA8B,CAAb,KAAA,IAAA,EAS7B,MAAM,QAAQ,EAAqC,CACjD,GAAI,GAAQ,QACV,MAAM,GAAY,CAEpB,GAAI,KAAK,OAAS,KAAK,IAAK,CAC1B,KAAK,QAAU,EACf,OAEF,MAAM,IAAI,SAAe,EAAS,IAAW,CAC3C,IAAM,MAAqB,CACzB,GAAS,CACT,GAAS,EAEL,MAAsB,CAC1B,IAAM,EAAM,KAAK,QAAQ,QAAQ,EAAO,CACpC,GAAO,GACT,KAAK,QAAQ,OAAO,EAAK,EAAE,CAE7B,GAAS,CACT,EAAO,GAAY,CAAC,EAEhB,MAAsB,GAAQ,oBAAoB,QAAS,EAAQ,CACzE,KAAK,QAAQ,KAAK,EAAO,CACzB,GAAQ,iBAAiB,QAAS,EAAS,CAAE,KAAM,GAAM,CAAC,EAC1D,CAIJ,SAAgB,CACd,IAAM,EAAO,KAAK,QAAQ,OAAO,CAC7B,EACF,GAAM,CAEN,OAAK,OAQT,MAAM,IAAO,EAAsB,EAAkC,CACnE,MAAM,KAAK,QAAQ,EAAO,CAC1B,GAAI,CACF,OAAO,MAAM,GAAI,QACT,CACR,KAAK,SAAS,EAKlB,IAAI,aAAsB,CACxB,OAAO,KAAK,OAId,IAAI,cAAuB,CACzB,OAAO,KAAK,QAAQ,OAGtB,IAAI,UAAmB,CACrB,OAAO,KAAK,MCrBH,EAAb,KAA0B,CACxB,YACE,EACA,EACA,EACA,EACA,EACA,EAEA,EACA,CARiB,KAAA,UAAA,EACA,KAAA,aAAA,EACA,KAAA,YAAA,EACA,KAAA,gBAAA,EACA,KAAA,WAAA,EACA,KAAA,UAAA,EAEA,KAAA,aAAA,EAGnB,WAAmB,EAAmC,CACpD,OAAO,KAAK,gBAAgB,UAAU,GAAY,UAAU,CAQ9D,MAAM,QAAQ,EAAgB,EAA2C,CACvE,KAAK,cAAc,EAAK,MAAM,SAAS,CACvC,IAAM,EAAO,MAAM,KAAK,SAAS,EAAK,CACtC,OAAO,KAAK,aAAa,EAAK,GAAI,EAAO,CAO3C,cAAsB,EAAyB,CAC7C,GAAI,KAAK,WAAW,EAAS,CAAC,QAAQ,CACpC,MAAM,IAAI,EACR,qEACA,eACD,CAKL,MAAc,aAAa,EAAgB,EAA2C,CAIpF,OAAO,KAAK,UAAU,QAAU,KAAK,oBAAoB,EAAQ,EAAO,CAAE,EAAO,CAInF,MAAc,YAAY,EAAkC,CAE1D,OADgB,MAAM,KAAK,UAAU,IAAI,EAAO,GAChC,SAAW,YAQ7B,MAAc,SAAS,EAAyC,CAC9D,IAAM,EAAO,MAAM,KAAK,UAAU,OAAO,EAAK,MAAM,CAEpD,OADK,KAAK,aAAa,KAAK,eAAgB,CAAE,OAAM,CAAC,CAC9C,EAWT,MAAM,UAAU,EAAyC,CACvD,KAAK,cAAc,EAAK,MAAM,SAAS,CACvC,IAAM,EAAO,MAAM,KAAK,SAAS,EAAK,CActC,OAbK,KAAK,aAAa,EAAK,GAAG,CAAC,MAAM,KAAO,IAAU,CACrD,MAAM,KAAK,UACR,OAAO,EAAK,GAAI,CACf,OAAQ,SACR,MAAO,CACL,KAAM,mBACN,QAAS,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAC/D,UAAW,GACZ,CACD,YAAa,KAAK,KAAK,CACxB,CAAC,CACD,UAAY,GAAG,EAClB,CACK,CAAE,GAAI,EAAK,GAAI,CAIxB,MAAc,oBAAoB,EAAgB,EAA2C,CAC3F,IAAM,EAAO,MAAM,KAAK,UAAU,IAAI,EAAO,CAC7C,GAAI,CAAC,EACH,MAAO,CACL,SACA,OAAQ,SACR,MAAO,CAAE,KAAM,iBAAkB,QAAS,mBAAmB,IAAU,UAAW,GAAO,CAC1F,CAGH,IAAM,EAAU,EAAK,SAAW,EAEhC,GAAI,CACF,MAAM,KAAK,UAAU,OAAO,EAAQ,CAAE,OAAQ,UAAW,SAAU,EAAS,CAAC,CAGxE,KAAK,aAAa,KAAK,eAAgB,CAC1C,KAAM,CAAE,GAAG,EAAM,OAAQ,UAAW,CACpC,MAAO,EAAK,MAAM,UAAY,UAC/B,CAAC,CAIF,IAAM,EAAc,EAAK,MAAM,OAAS,eAEpC,EACJ,GAAI,GAAe,KAAK,aAAc,CACpC,IAAM,EAAc,MAAM,KAAK,aAAa,CAC1C,QAAS,EAAK,MAAM,UAAY,QAChC,OAAQ,EAAK,MAAM,OACnB,aAAc,EAAK,MAAM,aACzB,MAAO,EAAK,MAAM,MAClB,WAAY,EAAK,MAAM,WACvB,UAAW,EAAK,MAAM,UACtB,MAAO,EAAK,MAAM,MAClB,aAAc,EAAK,MAAM,aACzB,cAAe,EAAK,MAAM,cAC1B,UAAW,EAAK,MAAM,UACtB,YAAa,EAAK,MAAM,YACxB,UAAW,EAAK,MAAM,UACtB,MAAO,EAAK,MAAM,MAClB,SACD,CAAC,CACF,EAAS,CACP,KAAM,EAAY,KAClB,UAAW,EAAK,MAAM,WAAa,GACnC,WAAY,EAAY,WACxB,WAAY,EAAY,WACxB,SAAU,EAAY,SACtB,QAAS,EAAY,QACtB,MAED,EAAS,MAAM,KAAK,WAAW,CAC7B,OAAQ,EAAK,MAAM,OACnB,UAAW,EAAK,MAAM,UACtB,YAAa,EAAK,cAClB,UAAW,EAAK,MAAM,SACtB,KAAM,EAAK,MAAM,KACjB,MAAO,EAAK,MAAM,MAClB,SAAU,EAAK,MAAM,SACrB,MAAO,EAAK,MAAM,MAClB,SACA,SACA,SAAU,EAAK,MAAM,OAAS,aAC9B,aAAc,EAAK,MAAM,aACzB,MAAO,EAAK,MAAM,MAClB,WAAY,EAAK,MAAM,WACvB,cAAe,EAAK,MAAM,cAC1B,UAAW,EAAK,MAAM,UACtB,YAAa,EAAK,MAAM,YACxB,aAAc,EAAK,MAAM,aAC1B,CAAC,CAGJ,GAAI,MAAM,KAAK,YAAY,EAAO,CAChC,MAAO,CAAE,SAAQ,OAAQ,YAAa,CAGxC,IAAM,EAAqB,CACzB,KAAM,EAAO,KACb,WAAY,EAAO,WACnB,WAAY,EAAO,WACnB,GAAI,EAAO,SAAW,CAAE,SAAU,EAAO,SAAU,CAAG,EAAE,CACxD,GAAI,EAAO,QAAU,CAAE,QAAS,EAAO,QAAS,CAAG,EAAE,CACtD,CAkBD,OAhBA,MAAM,KAAK,UAAU,OAAO,EAAQ,CAClC,OAAQ,YACR,SACA,UAAW,EAAO,UAClB,YAAa,KAAK,KAAK,CACxB,CAAC,CAEF,KAAK,WAAW,EAAK,MAAM,SAAS,CAAC,SAAS,CAIzC,KAAK,aAAa,KAAK,iBAAkB,CAC5C,KAAM,CAAE,GAAG,EAAM,OAAQ,YAAa,SAAQ,CAC9C,OAAQ,EACT,CAAC,CAEK,CACL,SACA,OAAQ,YACR,SACD,OACM,EAAO,CACd,IAAM,EAAS,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAErE,GAAI,MAAM,KAAK,YAAY,EAAO,CAChC,MAAO,CAAE,SAAQ,OAAQ,YAAa,CAMxC,GADiB,KAAK,YAAY,YAAY,EAAK,SAAS,EAAI,CAAC,GAAQ,UAGvE,MAAM,EADU,KAAK,YAAY,WAAW,EAAK,SAAS,CACrC,EAAO,CACxB,CAAC,GAAQ,SACX,OAAO,KAAK,oBAAoB,EAAQ,EAAO,CAInD,KAAK,WAAW,EAAK,MAAM,SAAS,CAAC,SAAS,CAE9C,IAAM,EAAY,CAChB,KAAM,mBACN,QAAS,EACT,UAAW,GACZ,CAeD,OAbA,MAAM,KAAK,UAAU,OAAO,EAAQ,CAClC,OAAQ,SACR,MAAO,EACP,YAAa,KAAK,KAAK,CACxB,CAAC,CAIG,KAAK,aAAa,KAAK,cAAe,CACzC,KAAM,CAAE,GAAG,EAAM,OAAQ,SAAU,CACnC,MAAO,EACR,CAAC,CAEK,CACL,SACA,OAAQ,SACR,MAAO,EACR,IAKP,SAAS,EAAM,EAAY,EAAqC,CAE9D,OADI,GAAQ,QAAgB,QAAQ,SAAS,CACtC,IAAI,QAAS,GAAY,CAC9B,IAAI,EACE,MAAsB,CAC1B,aAAa,EAAM,CACnB,GAAS,EAEX,EAAQ,eAAiB,CACvB,GAAQ,oBAAoB,QAAS,EAAQ,CAC7C,GAAS,EACR,EAAG,CACN,GAAQ,iBAAiB,QAAS,EAAS,CAAE,KAAM,GAAM,CAAC,EAC1D,CCpUJ,IAAa,EAAb,KAA+B,CAC7B,YACE,EACA,EACA,CAFiB,KAAA,UAAA,EACA,KAAA,UAAA,EAGnB,MAAM,UAAU,EAA+C,CAC7D,IAAM,EAAO,MAAM,KAAK,UAAU,IAAI,EAAG,CAazC,OAZK,EAID,EAAK,SAAW,YACX,CAAE,GAAI,GAAM,MAAO,CAAE,OAAQ,YAAa,OAAQ,EAAK,QAAQ,KAAM,CAAE,CAG5E,EAAK,SAAW,SACX,CAAE,GAAI,GAAO,MAAO,EAAK,OAAO,SAAW,cAAe,CAG5D,CAAE,GAAI,GAAM,MAAO,CAAE,OAAQ,EAAK,OAAQ,CAAE,CAX1C,CAAE,GAAI,GAAO,MAAO,sBAAsB,IAAM,CAc3D,MAAM,OAAO,EAAmC,CAC9C,IAAM,EAAO,MAAM,KAAK,UAAU,IAAI,EAAG,CAmBzC,OAjBK,EAID,EAAK,SAAW,aAAe,EAAK,SAAW,UAAY,EAAK,SAAW,YACtE,CAAE,GAAI,GAAO,MAAO,mCAAmC,EAAK,OAAO,QAAQ,IAAM,EAG1F,MAAM,KAAK,UAAU,OAAO,EAAI,CAC9B,OAAQ,YACR,YAAa,KAAK,KAAK,CACxB,CAAC,CAEE,KAAK,WACP,KAAK,UAAU,EAAG,CAGb,CAAE,GAAI,GAAM,MAAO,IAAA,GAAW,EAhB5B,CAAE,GAAI,GAAO,MAAO,sBAAsB,IAAM,GCThD,EAAb,KAA0B,CACxB,UACA,SACA,kBACA,aACA,gBACA,eACA,WACA,mBAEA,YAAY,EAA8B,CACxC,GAAM,CACJ,eACA,aACA,eACA,YACA,iBACA,iBAAiB,GACjB,iBACA,qBAAqB,GACnB,EAEJ,KAAK,aAAe,EACpB,KAAK,WAAa,EAClB,KAAK,mBAAqB,EAC1B,KAAK,UAAY,IAAI,EAAU,EAAe,CAC9C,IAAM,EAAc,EAAY,oBAAoB,EAAe,CACnE,KAAK,gBAAkB,EAAuB,oBAAoB,EAAe,CACjF,KAAK,eAAiB,IAAI,EAAU,EAAe,CAEnD,KAAK,SAAW,IAAI,EAClB,KAAK,UACL,EACA,EACA,KAAK,gBACL,EACA,KAAK,eACL,EACD,CAED,KAAK,kBAAoB,IAAI,EAAkB,KAAK,UAAW,EAAU,CAG3E,aAA6B,KAAO,IAAS,CAC3C,GAAM,CAAE,aAAY,YAAa,EAAqB,EAAK,MAAO,KAAK,mBAAmB,CAC1F,GAAI,EACF,OAAO,EACL,2BAA2B,KAAK,mBAAmB,2EACpD,CAGH,IAAM,EAAiB,CACrB,MAAO,CACL,OAAQ,EAAK,OACb,SAAU,EAAK,SACf,SAAU,EAAK,SACf,UAAW,EAAK,UAChB,YAAa,EAAK,aAAe,YACjC,KAAM,EAAK,KACX,KAAM,EAAK,KACX,MAAO,EAAK,MACZ,MAAO,EACR,CACF,CAED,GAAI,EAAK,OAAS,aAChB,OAAO,EAAQ,SAAY,CACzB,GAAM,CAAE,MAAO,MAAM,KAAK,SAAS,UAAU,EAAK,CAClD,MAAO,CAAE,KAAI,OAAQ,UAAoB,OAAQ,4BAA4B,IAAM,EACnF,CAGJ,GAAI,CACF,IAAM,EAAS,MAAM,KAAK,SAAS,QAAQ,EAAM,EAAK,OAAO,CAC7D,OAAO,EAAO,SAAW,YACrB,EAAG,CAAE,GAAI,EAAO,OAAQ,OAAQ,EAAO,OAAQ,OAAQ,EAAO,QAAQ,KAAM,CAAC,CAC7E,EAAK,EAAO,OAAO,SAAW,gBAAgB,OAC3C,EAAO,CACd,OAAO,EAAK,EAAM,GAUtB,UAAuB,MAAO,EAAO,EAAQ,IAAY,CACvD,GAAM,CAAE,aAAY,YAAa,EAAqB,GAAS,MAAO,KAAK,mBAAmB,CAC9F,GAAI,EACF,OAAO,EACL,2BAA2B,KAAK,mBAAmB,2EACpD,CAGH,IAAM,EAAU,KAAK,gBAAgB,UAAU,EAAM,CAKrD,OAJI,EAAQ,QAAQ,CACX,EAAK,qEAAqE,CAG5E,KAAK,eAAe,IAAI,SAAY,CACzC,GAAI,CACF,IAAM,EAAS,MAAM,KAAK,WAAW,CACnC,SACA,YAAa,YACb,UAAW,EACX,KAAM,GAAS,KACf,MAAO,GAAS,MAChB,MAAO,EACP,OAAQ,GAAS,OAClB,CAAC,CAEF,OADA,EAAQ,SAAS,CACV,EAAG,EAAO,KAAK,OACf,EAAO,CAEd,OADA,EAAQ,SAAS,CACV,EAAK,EAAM,GAEnB,GAAS,OAAO,EAOrB,MAAM,aAAa,EAAiD,CAClE,IAAM,EAAO,CACX,MAAO,CACL,KAAM,eACN,OAAQ,EAAM,OACd,SAAU,EAAM,QAChB,aAAc,EAAM,aACpB,MAAO,EAAM,MACb,WAAY,EAAM,WAClB,UAAW,EAAM,UACjB,MAAO,EAAM,MACb,aAAc,EAAM,aACpB,cAAe,EAAM,cACrB,UAAW,EAAM,UACjB,YAAa,EAAM,YACnB,YAAa,YACb,UAAW,EAAM,UACjB,MAAO,EAAM,MACd,CACF,CAEK,EAAS,MAAM,KAAK,SAAS,QAAQ,EAAM,EAAM,OAAO,CAE9D,GAAI,EAAO,SAAW,YACpB,MAAO,CACL,QAAS,EAAM,QACf,KAAM,EAAO,QAAQ,MAAQ,GAC7B,SAAU,EAAO,QAAQ,SACzB,QAAS,EAAO,QAAQ,QACxB,WAAY,EAAO,QAAQ,WAC3B,WAAY,EAAO,QAAQ,YAAc,EAC1C,CAGH,MAAU,MACR,EAAO,OAAO,SAAW,6BAA6B,EAAO,SAC9D,CAGH,QAAmB,KAAO,IAAO,CAC/B,IAAM,EAAO,MAAM,KAAK,UAAU,IAAI,EAAG,CAKzC,OAJK,EAIE,EAAG,CACR,GAAI,EAAK,GACT,OAAQ,EAAK,OACb,OAAQ,EAAK,MAAM,OACnB,OAAQ,EAAK,QAAQ,KACrB,MAAO,EAAK,OAAO,QACpB,CAAC,CATO,EAAK,mBAAmB,IAAK,EAYxC,UAAuB,KAAO,IAAW,CACvC,IAAM,EAAS,GAAU,IAAW,MAAQ,CAAE,SAAQ,CAAG,IAAA,GAIzD,OAAO,GAFO,MAAM,KAAK,UAAU,KAAK,EAAO,EAGvC,IAAK,IAAO,CAChB,GAAI,EAAE,GACN,OAAQ,EAAE,MAAM,OAChB,OAAQ,EAAE,OACX,EAAE,CACJ,EAGH,WAAyB,MAAO,EAAI,IAAW,CAC7C,IAAM,EAAO,MAAM,KAAK,UAAU,IAAI,EAAG,CACzC,GAAI,CAAC,EACH,OAAO,EAAK,mBAAmB,IAAK,CAGtC,GAAI,IAAW,SAAU,CAGvB,IAAM,EAAY,MAAM,KAAK,kBAAkB,OAAO,EAAG,CAKzD,OAJK,EAAU,IAGf,MAAM,KAAK,aAAa,KAAK,iBAAkB,CAAE,OAAQ,EAAI,CAAC,CACvD,EAAG,QAAQ,EAAG,YAAY,EAHxB,EAAK,EAAU,MAAM,CAMhC,GAAI,IAAW,QAAS,CACtB,GAAI,EAAK,SAAW,SAClB,OAAO,EAAK,gDAAgD,EAAK,SAAS,CAE5E,IAAM,EAAS,MAAM,KAAK,aAAa,CACrC,OAAQ,EAAK,MAAM,OACnB,SAAU,EAAK,MAAM,SACrB,SAAU,EAAK,MAAM,SACrB,KAAM,EAAK,MAAM,MAAQ,OACzB,UAAW,EAAK,MAAM,UACtB,YAAa,EAAK,MAAM,YACxB,KAAM,EAAK,MAAM,KACjB,MAAO,EAAK,MAAM,MACnB,CAAC,CACF,OAAO,EAAO,GAAK,EAAG,EAAO,MAAM,QAAU,kBAAkB,CAAG,EAAK,EAAO,MAAM,CAGtF,OAAO,EAAK,mBAAmB,IAAS,EAG1C,oBAA2C,KAAO,IACzC,KAAK,kBAAkB,UAAU,EAAG,CAG7C,iBAAqC,KAAO,IACnC,KAAK,kBAAkB,OAAO,EAAG,CAG1C,SAAgB,CACd,KAAK,gBAAgB,UAAU,GAInC,SAAS,EAAM,EAAqB,CAClC,MAAO,CAAE,GAAI,GAAM,QAAO,CAG5B,SAAS,EAAK,EAA8C,CAC1D,MAAO,CAAE,GAAI,GAAO,MAAO,EAAa,EAAM,CAAE,CAGlD,eAAe,EAAW,EAA0C,CAClE,GAAI,CACF,OAAO,EAAG,MAAM,GAAI,CAAC,OACd,EAAO,CACd,OAAO,EAAK,EAAM,EAItB,SAAS,EAAa,EAAwB,CAC5C,OAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CCvR/D,IAAa,EAAb,cAAuC,CAAW,CAChD,MACA,SAEA,YAAY,EAAe,EAAkB,CAC3C,MAAM,iBAAiB,EAAM,eAAe,IAAY,CACtD,KAAM,+BACP,CAAC,CACF,KAAK,KAAO,oBACZ,KAAK,MAAQ,EACb,KAAK,SAAW,IAIP,EAAb,cAAkC,CAAW,CAC3C,YAAY,EAAiB,CAC3B,MAAM,EAAS,CAAE,KAAM,sBAAuB,CAAC,CAC/C,KAAK,KAAO,iBAIH,EAAb,cAAwC,CAAW,CACjD,QAEA,YAAY,EAAiB,CAC3B,MAAM,UAAU,EAAQ,sBAAuB,CAC7C,KAAM,wBACP,CAAC,CACF,KAAK,KAAO,qBACZ,KAAK,QAAU,IAIN,EAAb,cAAsC,CAAW,CAC/C,YAAY,EAAiB,CAC3B,MAAM,EAAS,CAAE,KAAM,qBAAsB,CAAC,CAC9C,KAAK,KAAO,qBCnCH,EAAb,KAAyB,CACvB,OACA,gBAA0B,EAE1B,YAAY,EAAsB,CAChC,GAAI,EAAO,WAAa,OAAS,CAAC,EAAO,aACvC,MAAM,IAAI,EACR,qFACD,CAEH,KAAK,OAAS,EAGhB,MAAM,MAAM,EAAe,EAAmD,CAC5E,GAAM,CAAE,YAAa,KAAK,OAE1B,OAAQ,EAAR,CACE,IAAK,OACH,OAAO,KAAK,YAAY,EAAO,EAAO,CACxC,IAAK,cACH,OAAO,KAAK,gBAAgB,EAAO,CACrC,IAAK,SACH,OAAO,KAAK,YAAY,EAAO,CACjC,IAAK,MACH,OAAO,KAAK,WAAW,EAAO,EAAO,CACvC,QACE,MAAM,IAAI,EAAa,6BAA6B,IAAqB,EAK/E,YAAoB,EAAe,EAA0C,CAC3E,IAAM,EAAQ,KAAK,OAAO,OAAS,EAAE,CAC/B,EAAa,EAAM,aAAa,CAEhC,EAAS,CAAC,GAAG,EAAM,CAAC,MAAM,EAAG,KAAO,EAAE,UAAY,IAAM,EAAE,UAAY,GAAG,CAE/E,IAAK,IAAM,KAAQ,EACjB,GAAI,KAAK,UAAU,EAAM,EAAW,CAAE,CACpC,IAAM,EAAQ,EAAO,KAAM,GAAM,EAAE,KAAO,EAAK,QAAQ,CACvD,GAAI,EACF,MAAO,CACL,QAAS,EAAK,QACd,OAAQ,qBAAqB,EAAM,KAAK,GACxC,WAAY,EACb,CAKP,OAAO,KAAK,SAAS,EAAQ,kBAAkB,CAIjD,gBAAwB,EAA0C,CAChE,IAAM,EAAQ,EAAO,KAAK,gBAAkB,EAAO,QAGnD,MAFA,MAAK,kBAEE,CACL,QAAS,EAAM,GACf,OAAQ,gCAAgC,KAAK,gBAAkB,EAAE,GACjE,WAAY,EACb,CAIH,YAAoB,EAA0C,CAC5D,IAAM,EAAO,KAAK,OAAO,QAAQ,QAAU,KAAK,OAIhD,MAAO,CACL,QAHY,EADA,KAAK,MAAM,GAAM,CAAG,EAAO,OAAO,EAI/B,GACf,OAAQ,mBACR,WAAY,EAAM,EAAO,OAC1B,CAOH,MAAc,WAAW,EAAe,EAAmD,CACzF,GAAM,CAAE,gBAAiB,KAAK,OAC9B,GAAI,CAAC,EACH,MAAM,IAAI,EAAa,kDAAkD,CAE3E,OAAO,EAAa,EAAO,EAAO,CAIpC,SAAiB,EAAyB,EAAiC,CACzE,IAAM,EAAa,KAAK,OAAO,iBAAmB,EAAO,IAAI,GAC7D,GAAI,CAAC,EACH,MAAM,IAAI,EAAa,GAAG,EAAO,mCAAmC,CAGtE,MAAO,CACL,QAAS,EACT,OAAQ,GAAG,EAAO,yBAClB,WAAY,EACb,CAIH,UAAkB,EAAiB,EAAwB,CAKzD,OAJI,EAAK,iBAAiB,OACjB,EAAK,MAAM,KAAK,EAAM,CAGxB,EAAK,MAAM,KAAM,GAAY,EAAM,SAAS,EAAQ,aAAa,CAAC,CAAC,GCxDjE,EAAb,KAA8B,CAC5B,WAA8B,IAAI,IAElC,SAAS,EAAuC,CAC9C,GAAI,KAAK,WAAW,IAAI,EAAS,KAAK,CACpC,MAAU,MAAM,2BAA2B,EAAS,KAAK,yBAAyB,CAEpF,KAAK,WAAW,IAAI,EAAS,KAAM,EAAS,CAG9C,IAAI,EAAiD,CACnD,OAAO,KAAK,WAAW,IAAI,EAAK,CAGlC,IAAI,EAAuB,CACzB,OAAO,KAAK,WAAW,IAAI,EAAK,CAGlC,OAAkB,CAChB,MAAO,CAAC,GAAG,KAAK,WAAW,MAAM,CAAC,GC5DtC,SAAgB,EACd,EACA,EACA,EACW,CACX,IAAM,EAAqB,EACxB,IAAK,GAAM,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,KAAK,EAAE,cAAc,CACvD,KAAK;EAAK,CAEP,EAAY,EAAiB,IAAK,GAAM,EAAE,GAAG,CAEnD,MAAO,CACL,KAAM,mBACN,YAAa,uEAAuE,IACpF,WAAY,EAAE,OAAO,CACnB,gBAAiB,EACd,QAAQ,CACR,SAAS,uDAAuD,EAAU,KAAK,KAAK,GAAG,CAC1F,OAAQ,EACL,QAAQ,CACR,SAAS,wEAAwE,CACpF,QAAS,EACN,QAAQ,CACR,UAAU,CACV,SAAS,+EAA+E,CAC5F,CAAC,CACF,SAAU,GACV,QAAS,KAAO,IAA6B,CAC3C,GAAM,CAAE,kBAAiB,SAAQ,WAAY,EAAI,OA0BjD,OApBK,EAAU,SAAS,EAAgB,EAkBxC,EANgC,CAC9B,KAAM,EACN,GAAI,EACJ,OAAQ,EAAU,GAAG,EAAO,eAAe,IAAY,EACxD,CAEiB,CAEX,CACL,QAAS,CACP,CACE,KAAM,OACN,KAAM,yBAAyB,EAAgB,aAAa,IAC7D,CACF,CACF,EA1BQ,CACL,QAAS,CACP,CACE,KAAM,OACN,KAAM,yBAAyB,EAAgB,wBAAwB,EAAU,KAAK,KAAK,GAC5F,CACF,CACD,QAAS,GACV,EAoBN,CAGH,SAAgB,EACd,EACA,EACoC,CACpC,IAAM,EAAY,EAAO,IAAI,EAAQ,KAAK,CACpC,EAAU,EAAO,IAAI,EAAQ,GAAG,CAsBtC,OApBK,EAIA,EAKH,EAAU,OAAS,SACnB,EAAU,gBACV,EAAU,eAAe,OAAS,GAClC,CAAC,EAAU,eAAe,SAAS,EAAQ,GAAG,CAEvC,CACL,MAAO,GACP,MAAO,UAAU,EAAQ,KAAK,kCAAkC,EAAQ,GAAG,eAAe,EAAU,eAAe,KAAK,KAAK,CAAC,GAC/H,CAGI,CAAE,MAAO,GAAM,CAfb,CAAE,MAAO,GAAO,MAAO,iBAAiB,EAAQ,GAAG,aAAc,CAJjE,CAAE,MAAO,GAAO,MAAO,iBAAiB,EAAQ,KAAK,aAAc,CCnF9E,MAAa,EAA0C,CACrD,KAAM,UAEN,MAAM,QAAQ,EAAe,EAA+C,CAC1E,IAAM,EAAS,CAAC,GAAG,EAAI,OAAO,OAAO,QAAQ,CAAC,CACxC,EAAU,EAAI,OAAO,cAAgB,EAAO,IAAI,GACtD,GAAI,CAAC,EACH,MAAO,CAAE,MAAO,EAAE,CAAE,OAAQ,GAAI,CAGlC,IAAM,EAAW,EAAI,OAAO,iBAAmB,GAC3C,EAAiB,EACjB,EAAe,EACb,EAAiC,EAAE,CAEzC,IAAK,IAAI,EAAQ,EAAG,EAAQ,GACtB,GAAI,OAAO,QADqB,IAAS,CAG7C,IAAM,EAAW,EAAI,OAAO,OAAO,IAAI,EAAe,CACtD,GAAI,CAAC,EAAU,MAAM,IAAI,EAAmB,EAAe,CAE3D,IAAI,EAAiB,EAAO,OAAQ,GAAM,EAAE,KAAO,EAAe,CAClE,GACE,EAAS,OAAS,SAClB,EAAS,gBACT,EAAS,eAAe,OAAS,EACjC,CACA,IAAM,EAAU,EAAS,eACzB,EAAiB,EAAe,OAAQ,GAAM,EAAQ,SAAS,EAAE,GAAG,CAAC,CAKvE,IAAM,EACJ,EAAe,OAAS,EACpB,CACE,OAAQ,OACR,KAAM,mBACN,QAAS,CACP,KAAM,EACN,eAAgB,EAAe,IAAK,IAAO,CACzC,GAAI,EAAE,GACN,KAAM,EAAE,KACR,YAAa,EAAE,YAChB,EAAE,CACJ,CACF,CACD,KAEN,EAAI,KAAK,CAAE,KAAM,cAAe,QAAS,EAAgB,CAAC,CAC1D,IAAM,EAAQ,KAAK,KAAK,CAIlB,EAAS,MAAM,EAAI,iBAAiB,EAAU,EAAc,CAChE,OAAQ,EAAI,OACZ,UAAW,EAAoB,CAAC,EAAkB,CAAG,IAAA,GACtD,CAAC,CAEI,EAAM,KAAK,KAAK,CAAG,EACzB,EAAI,KAAK,CAAE,KAAM,YAAa,QAAS,EAAgB,WAAY,EAAK,CAAC,CACzE,EAAM,KAAK,CAAE,QAAS,EAAgB,SAAQ,WAAY,EAAK,CAAC,CAIhE,IAAM,EAAiB,EAAO,QAC9B,GAAI,EAAgB,CAClB,IAAM,EAA0B,EAEhC,GAAI,CADe,EAAgB,EAAS,IAAI,IAAI,EAAO,IAAK,GAAM,CAAC,EAAE,GAAI,EAAE,CAAC,CAAC,CAAC,CAClE,MACd,MAAO,CAAE,QAAO,OAAQ,EAAO,KAAM,CAGvC,EAAI,KAAK,CACP,KAAM,UACN,KAAM,EAAQ,KACd,GAAI,EAAQ,GACZ,OAAQ,EAAQ,OACjB,CAAC,CAEF,EAAiB,EAAQ,GACzB,EAAe,EAAQ,OACvB,SAGF,MAAO,CAAE,QAAO,OAAQ,EAAO,KAAM,CAGvC,MAAM,IAAI,EAAkB,EAAU,EAAS,EAElD,CC/FY,EAA6C,CACxD,KAAM,aAEN,MAAM,QAAQ,EAAe,EAA+C,CAC1E,IAAM,EAAW,EAAI,OAAO,UAAY,CAAC,GAAG,EAAI,OAAO,OAAO,QAAQ,CAAC,CAAC,IAAK,GAAM,EAAE,GAAG,CAClF,EAAiC,EAAE,CACrC,EAAe,EAEnB,IAAK,IAAM,KAAW,EAAU,CAC9B,GAAI,EAAI,OAAO,QAAS,MAExB,IAAM,EAAW,EAAI,OAAO,OAAO,IAAI,EAAQ,CAC/C,GAAI,CAAC,EAAU,SAEf,EAAI,KAAK,CAAE,KAAM,cAAe,UAAS,CAAC,CAC1C,IAAM,EAAY,KAAK,KAAK,CAEtB,EAAS,MAAM,EAAI,iBAAiB,EAAU,EAAc,CAAE,OAAQ,EAAI,OAAQ,CAAC,CAEnF,EAAa,KAAK,KAAK,CAAG,EAChC,EAAI,KAAK,CAAE,KAAM,YAAa,UAAS,aAAY,CAAC,CAEpD,EAAM,KAAK,CAAE,UAAS,SAAQ,aAAY,CAAC,CAE3C,EAAe,EAAO,KACtB,EAAI,KAAK,CAAE,KAAM,gBAAiB,KAAM,EAAM,OAAS,EAAG,UAAS,CAAC,CAGtE,IAAM,EAAY,EAAM,EAAM,OAAS,GAKvC,OAJK,EAIE,CAAE,QAAO,OAAQ,EAAU,OAAO,KAAM,CAHtC,CAAE,MAAO,EAAE,CAAE,OAAQ,GAAI,EAKrC,CCTD,eAAsB,EACpB,EACA,EACe,CACf,GAAM,CAAE,MAAK,WAAU,SAAQ,cAAe,EAC9C,GAAI,EAAM,SAAW,EAAG,OAExB,IAAM,EAAU,OAAO,SAAS,EAAI,EAAI,GAAO,EAAI,KAAK,MAAM,EAAI,CAAG,EAE/D,EAAQ,EAAM,OACd,EAAU,CAAC,GAAG,EAAM,CACpB,EAAU,IAAI,IAChB,EAAY,EACZ,EAAI,EACJ,EACA,EAAS,GAEP,EAAW,IAAI,gBACf,MAA8B,EAAS,OAAO,CAChD,IACE,EAAO,QAAS,EAAS,OAAO,CAC/B,EAAO,iBAAiB,QAAS,EAAiB,CAAE,KAAM,GAAM,CAAC,EAGxE,GAAI,CACF,KAAO,EAAQ,OAAS,GAAK,EAAQ,KAAO,GAAG,CAK7C,KAJI,EAAS,OAAO,SAAW,KAC7B,EAAQ,OAAS,GAGZ,EAAQ,KAAO,GAAW,EAAQ,OAAS,GAAG,CACnD,IAAM,EAAO,EAAQ,OAAO,CACtB,EAAM,IACR,EACJ,GAAK,SAAY,CACf,GAAI,CACF,MAAM,EAAS,EAAM,EAAK,EAAS,OAAO,OACnC,EAAK,CACZ,AAEE,KADA,EAAa,EACJ,IAEX,EAAS,OAAO,QACR,CACR,EAAQ,OAAO,EAAE,CACjB,IACA,IAAa,EAAW,EAAM,KAE9B,CACJ,EAAQ,IAAI,EAAE,CAGZ,EAAQ,KAAO,GACjB,MAAM,QAAQ,KAAK,EAAQ,SAGvB,CACJ,EAAQ,KAAO,GAAG,MAAM,QAAQ,WAAW,EAAQ,CACnD,GAAQ,EAAO,oBAAoB,QAAS,EAAgB,CAGlE,GAAI,EACF,MAAM,ECtFV,MAAa,EAA2C,CACtD,KAAM,WAEN,MAAM,QAAQ,EAAe,EAA+C,CAC1E,IAAM,EAAS,CAAC,GAAG,EAAI,OAAO,OAAO,QAAQ,CAAC,CACxC,EAAM,EAAI,OAAO,gBAAkB,EAAO,OAC1C,EAAQ,EAAO,IAAK,IAAO,CAAE,QAAS,EAAE,GAAI,QAAO,EAAE,CACrD,EAAgE,MAAM,EAAM,OAAO,CAEzF,EAAI,KAAK,CAAE,KAAM,kBAAmB,SAAU,EAAO,IAAK,GAAM,EAAE,GAAG,CAAE,CAAC,CAExE,MAAM,EAAc,EAAO,CACzB,MACA,SAAU,MAAO,EAAM,IAAU,CAC/B,GAAI,CACF,IAAM,EAAW,EAAI,OAAO,OAAO,IAAI,EAAK,QAAQ,CACpD,GAAI,CAAC,EAAU,OAEf,EAAI,KAAK,CAAE,KAAM,cAAe,QAAS,EAAK,QAAS,CAAC,CACxD,IAAM,EAAQ,KAAK,KAAK,CAGlB,EAAS,MAAM,EAAI,iBAAiB,EAAU,EAAK,MAAO,CAAE,OAAQ,EAAI,OAAQ,CAAC,CAEjF,EAAM,KAAK,KAAK,CAAG,EACzB,EAAI,KAAK,CAAE,KAAM,YAAa,QAAS,EAAK,QAAS,WAAY,EAAK,CAAC,CACvE,EAAM,GAAS,CAAE,QAAS,EAAK,QAAS,SAAQ,WAAY,EAAK,OAC1D,EAAK,CACZ,EAAI,KAAK,CACP,KAAM,QACN,QAAS,EAAK,QACd,MAAO,aAAe,MAAQ,EAAU,MAAM,OAAO,EAAI,CAAC,CAC3D,CAAC,GAGN,OAAQ,EAAI,OACZ,YAAa,EAAW,IAAU,CAChC,EAAI,KAAK,CAAE,KAAM,iBAAkB,eAAgB,EAAW,WAAY,EAAO,CAAC,EAErF,CAAC,CAEF,IAAM,EAAU,EAAM,OACnB,GAA4C,IAAM,IAAA,GACpD,CAED,MAAO,CAAE,MAAO,EAAS,OADR,EAAQ,IAAK,GAAM,MAAM,EAAE,QAAQ,IAAI,EAAE,OAAO,OAAO,CAAC,KAAK;;EAAO,CAC1C,EAE9C,CC3CK,EAAS,EAAa,4CAA4C,CAElE,EAAa,EAAE,OAAO,CAC1B,YAAa,EAAE,QAAQ,CACvB,WAAY,EAAE,QAAQ,CAAC,UAAU,CAClC,CAAC,CAKF,SAAS,EAAoB,EAAkC,CAC7D,GAAI,CAAC,MAAM,QAAQ,EAAI,CAAE,MAAO,EAAE,CAClC,IAAM,EAA4B,EAAE,CACpC,IAAK,IAAM,KAAQ,EAAK,CACtB,IAAM,EAAS,EAAW,UAAU,EAAK,CACrC,EAAO,SACT,EAAM,KAAK,EAAO,KAAK,CAG3B,OAAO,EAGT,SAAgB,EAAgB,EAAkC,CAEhE,GAAI,CAEF,IAAM,EAAS,EADA,KAAK,MAAM,EAAK,MAAM,CAAC,CACI,CAC1C,GAAI,EAAO,OAAS,EAClB,OAAO,OAEH,EAKR,IAAM,EAAY,EAAK,MAAM,cAAc,CAC3C,GAAI,EACF,GAAI,CAEF,IAAM,EAAW,EADF,KAAK,MAAM,EAAU,GAAG,CACK,CAC5C,GAAI,EAAS,OAAS,EACpB,OAAO,OAEH,EAUV,OAJA,EAAO,KACL,CAAE,YAAa,EAAK,MAAM,EAAG,IAAI,CAAE,CACnC,sEACD,CACM,EAAE,CAGX,MAAa,EAA+C,CAC1D,KAAM,eAEN,MAAM,QAAQ,EAAe,EAA+C,CAC1E,IAAM,EACJ,EAAI,OAAO,cAAgB,CAAC,GAAG,EAAI,OAAO,OAAO,QAAQ,CAAC,CAAC,IAAI,IAAM,GACvE,GAAI,CAAC,EACH,MAAO,CAAE,MAAO,EAAE,CAAE,OAAQ,GAAI,CAGlC,IAAM,EAAgB,EAAI,OAAO,OAAO,IAAI,EAAa,CACzD,GAAI,CAAC,GAAiB,EAAc,OAAS,QAC3C,MAAO,CAAE,MAAO,EAAE,CAAE,OAAQ,GAAI,CAGlC,EAAI,KAAK,CAAE,KAAM,cAAe,QAAS,EAAc,CAAC,CACxD,EAAI,KAAK,CAAE,KAAM,qBAAsB,WAAY,EAAc,OAAQ,GAAI,KAAM,WAAY,CAAC,CAChG,IAAM,EAAY,KAAK,KAAK,CAEtB,EAAa,MAAM,EAAI,iBAC3B,EACA,kEAAkE,EAAM,yGAAyG,CAAC,GAAG,EAAI,OAAO,OAAO,QAAQ,CAAC,CAAC,IAAK,GAAM,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,yGAC7O,CAAE,OAAQ,EAAI,OAAQ,CACvB,CAEK,EAAU,KAAK,KAAK,CAAG,EAC7B,EAAI,KAAK,CAAE,KAAM,YAAa,QAAS,EAAc,WAAY,EAAS,CAAC,CAC3E,IAAM,EAAiC,CACrC,CAAE,QAAS,EAAc,OAAQ,EAAY,WAAY,EAAS,CACnE,CAEG,EAAQ,EAAgB,EAAW,KAAK,CAExC,EAAM,SAAW,IACnB,EAAQ,CAAC,CAAE,YAAa,EAAO,WAAY,IAAA,GAAW,CAAC,EAGzD,IAAM,EAKD,EAAE,CAED,EACJ,CAAC,GAAG,EAAI,OAAO,OAAO,QAAQ,CAAC,CAAC,KAAM,GAAM,EAAE,KAAO,EAAa,EAAE,IAAM,EACtE,EAAgB,EAAM,IAAK,IAAO,CACtC,GAAG,EACH,QAAS,EAAE,YAAc,EAC1B,EAAE,CAIH,MAAM,EAAc,EAAe,CACjC,IAHU,EAAI,OAAO,gBAAkB,EAAc,OAIrD,SAAU,KAAO,IAAS,CACxB,GAAI,CACF,IAAM,EAAY,EAAI,OAAO,OAAO,IAAI,EAAK,QAAQ,CACrD,GAAI,CAAC,EAAW,OAEhB,EAAI,KAAK,CAAE,KAAM,cAAe,QAAS,EAAK,QAAS,CAAC,CACxD,EAAI,KAAK,CACP,KAAM,qBACN,WAAY,EACZ,OAAQ,EAAK,QACb,KAAM,EAAK,YACZ,CAAC,CACF,IAAM,EAAQ,KAAK,KAAK,CAElB,EAAS,MAAM,EAAI,iBAAiB,EAAW,EAAK,YAAa,CACrE,OAAQ,EAAI,OACb,CAAC,CAEI,EAAM,KAAK,KAAK,CAAG,EACzB,EAAI,KAAK,CAAE,KAAM,YAAa,QAAS,EAAK,QAAS,WAAY,EAAK,CAAC,CACvE,EAAY,KAAK,CAAE,OAAM,QAAS,EAAK,QAAS,SAAQ,WAAY,EAAK,CAAC,OACnE,EAAK,CACZ,EAAI,KAAK,CACP,KAAM,QACN,QAAS,EAAK,QACd,MAAO,aAAe,MAAQ,EAAU,MAAM,OAAO,EAAI,CAAC,CAC3D,CAAC,GAGN,OAAQ,EAAI,OACb,CAAC,CAEF,IAAK,IAAM,KAAM,EACf,EAAM,KAAK,CAAE,QAAS,EAAG,QAAS,OAAQ,EAAG,OAAQ,WAAY,EAAG,WAAY,CAAC,CAGnF,IAAM,EAAe,EAAY,IAC9B,GAAM,MAAM,EAAE,KAAK,YAAY,OAAO,EAAE,QAAQ,KAAK,EAAE,OAAO,OAChE,CACK,EAAY,CAChB,0DACA,GACA,GAAG,EACH,GACA,iFACA,EACD,CAAC,KAAK;EAAK,CAEZ,GAAI,EAAI,OAAO,QACb,MAAO,CAAE,QAAO,OAAQ,EAAa,KAAK;;EAAO,CAAE,CAGrD,EAAI,KAAK,CAAE,KAAM,cAAe,QAAS,EAAc,CAAC,CACxD,IAAM,EAAW,KAAK,KAAK,CAErB,EAAY,MAAM,EAAI,iBAAiB,EAAe,EAAW,CAAE,OAAQ,EAAI,OAAQ,CAAC,CAExF,EAAS,KAAK,KAAK,CAAG,EAI5B,OAHA,EAAI,KAAK,CAAE,KAAM,YAAa,QAAS,EAAc,WAAY,EAAQ,CAAC,CAC1E,EAAM,KAAK,CAAE,QAAS,EAAc,OAAQ,EAAW,WAAY,EAAQ,CAAC,CAErE,CAAE,QAAO,OAAQ,EAAU,KAAM,EAE3C,CClLY,EAAyC,CACpD,KAAM,SAEN,MAAM,QAAQ,EAAe,EAA+C,CAC1E,GAAI,CAAC,EAAI,OACP,MAAM,IAAI,EAAiB,wBAAwB,CAGrD,IAAM,EAAS,CAAC,GAAG,EAAI,OAAO,OAAO,QAAQ,CAAC,CACxC,EAAW,MAAM,EAAI,OAAO,MAAM,EAAO,EAAO,CAEhD,EAAW,EAAI,OAAO,OAAO,IAAI,EAAS,QAAQ,CACxD,GAAI,CAAC,EACH,MAAM,IAAI,EAAmB,EAAS,QAAQ,CAGhD,EAAI,KAAK,CAAE,KAAM,mBAAoB,WAAU,CAAC,CAEhD,EAAI,KAAK,CAAE,KAAM,cAAe,QAAS,EAAS,QAAS,CAAC,CAC5D,IAAM,EAAQ,KAAK,KAAK,CAGlB,EAAS,MAAM,EAAI,iBAAiB,EAAU,EAAO,CAAE,OAAQ,EAAI,OAAQ,CAAC,CAE5E,EAAM,KAAK,KAAK,CAAG,EAGzB,OAFA,EAAI,KAAK,CAAE,KAAM,YAAa,QAAS,EAAS,QAAS,WAAY,EAAK,CAAC,CAEpE,CACL,MAAO,CAAC,CAAE,QAAS,EAAS,QAAS,SAAQ,WAAY,EAAK,CAAC,CAC/D,OAAQ,EAAO,KAChB,EAEJ,CC7BD,SAAgB,GAAkD,CAChE,IAAM,EAAW,IAAI,EAMrB,OALA,EAAS,SAAS,EAAiB,CACnC,EAAS,SAAS,EAAoB,CACtC,EAAS,SAAS,EAAkB,CACpC,EAAS,SAAS,EAAsB,CACxC,EAAS,SAAS,EAAgB,CAC3B,ECgBT,IAAa,EAAb,KAAmB,CACjB,OACA,OACA,OACA,SAEA,YAAY,EAAqB,CAC/B,KAAK,eAAe,EAAO,CAE3B,KAAK,OAAS,EACd,KAAK,OAAS,IAAI,IAElB,IAAK,IAAM,KAAS,EAAO,OACzB,KAAK,OAAO,IAAI,EAAM,GAAI,EAAM,CAGlC,KAAK,OAAS,EAAO,OAAS,IAAI,EAAY,EAAO,OAAO,CAAG,KAE/D,KAAK,SAAW,GAA+B,CAGjD,WAA6B,CAC3B,MAAO,CAAC,GAAG,KAAK,OAAO,QAAQ,CAAC,CAGlC,SAAS,EAA6C,CACpD,OAAO,KAAK,OAAO,IAAI,EAAG,CAI5B,iBAAiB,EAAuC,CACtD,KAAK,SAAS,SAAS,EAAS,CAIlC,kBAA6B,CAC3B,OAAO,KAAK,SAAS,OAAO,CAG9B,UAAkB,EAAyB,CAKzC,GAHA,KAAK,OAAO,eAAe,EAAM,CAG7B,KAAK,OAAO,aAAc,CAC5B,IAAM,EAAyB,CAC7B,GAAI,SAAS,KAAK,OAAO,OAAS,KAAK,OAAO,OAC9C,OAAQ,UACR,SAAU,EACV,YAAa,EACb,UAAW,KAAK,KAAK,CACrB,WAAY,EACb,CAKI,KAAK,OAAO,aAAa,KAAK,eAAgB,CACjD,KAAM,EACN,MAAO,SAAS,KAAK,OAAO,OAC7B,CAAC,EAKN,qBAA6B,EAAsC,CAsBjE,MAhB6B,CAC3B,kBAJ6D,EAAU,EAAO,IAC9E,KAAK,kBAAkB,EAAU,EAAO,GAAM,QAAU,EAAQ,GAAM,UAAU,CAIhF,KAP+B,GAAU,KAAK,UAAU,EAAM,CAQ9D,OAAQ,KAAK,OACb,SACA,OAAQ,CACN,KAAM,KAAK,OAAO,KAClB,OAAQ,KAAK,OACb,aAAc,KAAK,OAAO,aAC1B,SAAU,KAAK,OAAO,SACtB,aAAc,KAAK,OAAO,aAC1B,gBAAiB,KAAK,OAAO,gBAC7B,eAAgB,KAAK,OAAO,eAC7B,CACF,CAQH,MAAM,IAAI,EAAe,EAA6D,CACpF,IAAM,EAAS,GAAS,QAAU,IAAI,iBAAiB,CAAC,OAClD,EAAY,KAAK,KAAK,CACtB,EAA2B,GAAU,KAAK,UAAU,EAAM,CAEhE,EAAK,CACH,KAAM,cACN,QAAS,KAAK,OAAO,QACrB,WAAY,KAAK,OAAO,KACzB,CAAC,CAEF,IAAM,EAAW,KAAK,SAAS,IAAI,KAAK,OAAO,QAAQ,CACvD,GAAI,CAAC,EACH,MAAM,IAAI,EACR,qBAAqB,KAAK,OAAO,QAAQ,4BAA4B,KAAK,SAAS,OAAO,CAAC,KAAK,KAAK,GACtG,CAGH,GAAI,CACF,IAAM,EAAM,KAAK,qBAAqB,EAAO,CACvC,EAAyB,MAAM,EAAS,QAAQ,EAAO,EAAI,CAIjE,OAFA,EAAK,CAAE,KAAM,YAAa,gBAAiB,KAAK,KAAK,CAAG,EAAW,CAAC,CAE7D,CACL,QAAS,KAAK,OAAO,QACrB,MAAO,EAAO,MACd,OAAQ,EAAO,OACf,WAAY,KAAK,KAAK,CAAG,EAC1B,OACM,EAAO,CAEd,MADA,EAAK,CAAE,KAAM,YAAa,gBAAiB,KAAK,KAAK,CAAG,EAAW,CAAC,CAC9D,GAQV,MAAc,kBACZ,EACA,EACA,EACA,EAC0B,CAC1B,GAAI,EAAS,OAAS,OAYpB,OATI,GAAW,QACb,KAAK,OAAO,eAAe,CACzB,KAAM,QACN,QAAS,EAAS,GAClB,MAAW,MACT,gBAAgB,EAAS,GAAG,iCAAiC,EAAU,IAAK,GAAM,EAAE,KAAK,CAAC,KAAK,KAAK,CAAC,wBACtG,CACF,CAAC,CAEG,EAAS,UAAU,EAAO,EAAO,CAG1C,IAAM,EAAS,EAKT,EAAS,MAAM,KAAK,OAAO,aAAa,CAC5C,QAAS,EAAO,GAChB,OAAQ,EACR,aAAc,EAAO,aACrB,MAAO,EAAO,MACd,YACA,MAAO,EAAO,OAAO,GACrB,aAAc,EAAO,aACrB,cAAe,EAAO,cACtB,UAAW,EAAO,UAClB,YAAa,EAAO,YACpB,UAAW,KAAK,OAAO,MACvB,MAAO,KAAK,OAAO,MACnB,SACD,CAAC,CAEF,MAAO,CACL,QAAS,EAAO,QAChB,SAAW,EAAO,UAAY,EAAE,CAChC,KAAM,EAAO,KACb,QAAS,EAAO,QAChB,WAAY,EAAO,YAAc,CAAE,MAAO,EAAG,OAAQ,EAAG,UAAW,EAAG,CACtE,WAAY,EAAO,WACpB,CAGH,eAAuB,EAA2B,CAChD,GAAI,CAAC,EAAO,KACV,MAAM,IAAI,EAAiB,yBAAyB,CAGtD,GAAI,CAAC,EAAO,QAAU,EAAO,OAAO,SAAW,EAC7C,MAAM,IAAI,EAAiB,iCAAiC,CAG9D,GAAI,CAAC,EAAO,aACV,MAAM,IAAI,EAAiB,mCAAmC,CAGhE,IAAM,EAAM,IAAI,IAChB,IAAK,IAAM,KAAS,EAAO,OAAQ,CACjC,GAAI,EAAI,IAAI,EAAM,GAAG,CACnB,MAAM,IAAI,EAAiB,wBAAwB,EAAM,GAAG,GAAG,CAEjE,EAAI,IAAI,EAAM,GAAG,CAGnB,IAAK,IAAM,KAAS,EAAO,OACzB,GAAI,EAAM,OAAS,SAAW,EAAM,oBAC7B,IAAM,KAAY,EAAM,eAC3B,GAAI,CAAC,EAAI,IAAI,EAAS,CACpB,MAAM,IAAI,EACR,UAAU,EAAM,GAAG,uCAAuC,EAAS,GACpE,IAkBb,SAAgB,EAAY,EAA4B,CACtD,OAAO,IAAI,EAAM,EAAO"}
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/** 工具定义(本地 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}\n","import type { Task, TaskInput, TaskStatus } 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\n constructor(maxStoredTasks = 1000) {\n this.maxStoredTasks = Math.max(1, maxStoredTasks)\n }\n\n private generateId(): string {\n return `task_${Date.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: Date.now(),\n }\n\n this.tasks.set(task.id, task)\n return task\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\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 consecutiveFailures = 0\n private openedAt: number | null = null\n\n constructor(config?: Partial<CircuitBreakerConfig>) {\n const resolvedConfig = { ...DEFAULT_CIRCUIT_BREAKER, ...config }\n\n this.enabled = resolvedConfig.enabled\n this.failureThreshold = resolvedConfig.failureThreshold\n this.resetTimeoutMs = resolvedConfig.resetTimeoutMs\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 (Date.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 = Date.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(config?: Partial<CircuitBreakerConfig>): CircuitBreakerRegistry {\n return new CircuitBreakerRegistry(() => new CircuitBreaker(config))\n }\n\n /** 所有 target 共用同一个熔断器实例——保留旧的全局语义(测试/向后兼容用)。 */\n static single(breaker: CircuitBreaker): CircuitBreakerRegistry {\n return new CircuitBreakerRegistry(() => breaker)\n }\n\n static fromWorkflowOptions(wf?: WorkflowOptions): CircuitBreakerRegistry {\n const circuit = wf?.circuitBreaker\n return CircuitBreakerRegistry.perTarget({\n enabled: circuit?.enabled ?? true,\n failureThreshold: circuit?.failureThreshold ?? 5,\n resetTimeoutMs: circuit?.timeoutMs ?? 60_000,\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\nexport class Semaphore {\n private active = 0\n private readonly waiters: Array<() => void> = []\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 = (): void => {\n cleanup()\n resolve()\n }\n const onAbort = (): void => {\n const idx = this.waiters.indexOf(waiter)\n if (idx >= 0) {\n this.waiters.splice(idx, 1)\n }\n cleanup()\n reject(abortError())\n }\n const cleanup = (): void => 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()\n } else {\n this.active -= 1\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 } from './types'\nimport { CircuitBreaker, CircuitBreakerRegistry } from './retry'\nimport { Semaphore } from './semaphore'\n\nimport type { HookRegistry } from '@x-otto/hooks'\nimport type { 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?: (input: import('./types').AgentTurnInput) => Promise<import('./types').AgentTurnResult>,\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 }> {\n this.assertCircuit(unit.input.subagent)\n const task = await this.register(unit)\n void this.runScheduled(task.id).catch(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: Date.now(),\n })\n .catch(() => {})\n })\n return { id: task.id }\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: Date.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: Date.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 { TaskStore } from './task-store'\n\nexport class BackgroundManager {\n constructor(\n private readonly taskStore: TaskStore,\n private readonly abortTask?: (taskId: string) => void,\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: Date.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} from '@x-otto/orchestration-contracts'\nimport { checkDelegationDepth } from '@x-otto/orchestration-contracts'\nimport type { OrchestratorOptions, TaskUnit, AgentTurnInput, AgentTurnResult } 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 /**\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 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 = options.maxFanOutPerParent ?? Math.max(1, Math.floor(maxActiveTasks / 2))\n this.taskStore = new TaskStore(maxStoredTasks)\n const retryPolicy = RetryPolicy.fromWorkflowOptions(workflowConfig)\n this.circuitBreakers = CircuitBreakerRegistry.fromWorkflowOptions(workflowConfig)\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 )\n\n this.backgroundManager = new BackgroundManager(this.taskStore, abortTask)\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 // RFC-371 S3:per-parent 活跃扇出闸。undefined parentTaskId = root 层,不受限。\n if (args.parentTaskId !== undefined) {\n const current = this.fanOutCounts.get(args.parentTaskId) ?? 0\n if (current >= this.maxFanOutPerParent) {\n return fail(\n `Fan-out limit (${this.maxFanOutPerParent}) reached for parent task \"${args.parentTaskId}\" — ` +\n `wait for in-flight subtasks to complete before delegating more.`,\n )\n }\n }\n\n const unit: TaskUnit = {\n input: {\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\n if (args.mode === 'background') {\n return attempt(async () => {\n const { id } = await this.executor.startTask(unit)\n // RFC-371 S3:background 任务一旦建档即计入 per-parent 活跃计数。\n // 终态释放经 `releaseFanOutSlot` 在 taskStore 状态变更回调里处理(见 cleanup)。\n this.acquireFanOutSlot(args.parentTaskId)\n return { id, status: 'pending' as const, output: `Background task created: ${id}` }\n })\n }\n\n // RFC-371 S3:sync 任务——执行前 acquire,执行后(无论成败)release。\n this.acquireFanOutSlot(args.parentTaskId)\n try {\n const result = await this.executor.runTask(unit, args.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(args.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 // RFC-371 S3:agent_call 同样受 per-parent 扇出闸约束(不建档但占并发)。\n if (options?.parentTaskId !== undefined) {\n const current = this.fanOutCounts.get(options.parentTaskId) ?? 0\n if (current >= this.maxFanOutPerParent) {\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\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 this.acquireFanOutSlot(options?.parentTaskId)\n return this.delegationGate.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).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 },\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(\n result.error?.message ?? `Swarm member turn failed: ${result.status}`,\n )\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: retry 必须保留原任务的 delegation depth(provenance),不能重置为\n // root(depth=0)。task.input.depth 已经是该任务的 childDepth(dispatchTask 首次\n // 派发时算出的值);dispatchTask 的 args.depth 语义是\"调用方 depth\",内部会再 +1\n // 算 childDepth——故此处传 (task.input.depth ?? 1) - 1 抵消掉这次重算,使 retry 后\n // 的任务落在与原任务相同的 depth,而非从 root 重新计起(此前错误地完全省略 depth,\n // 导致 retry 一个深层委派任务会重置委托深度护栏,可能允许比原策略更深的执行链)。\n const preservedCallerDepth = task.input.depth !== undefined ? task.input.depth - 1 : undefined\n const result = await this.dispatchTask({\n prompt: task.input.prompt,\n subagent: task.input.subagent,\n category: task.input.category,\n mode: task.input.mode ?? 'sync',\n sessionId: task.input.sessionId,\n sessionMode: task.input.sessionMode,\n slot: task.input.slot,\n model: task.input.model,\n depth: preservedCallerDepth,\n })\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 if (result.ok) {\n const task = await this.taskStore.get(id)\n this.releaseFanOutSlot(task?.input.parentTaskId)\n }\n return result\n }\n\n dispose(): void {\n this.circuitBreakers.resetAll()\n this.fanOutCounts.clear()\n }\n\n // ── RFC-371 S3:per-parent 扇出计数 helpers ──────────────────────────────\n\n private acquireFanOutSlot(parentTaskId: string | undefined): void {\n if (parentTaskId === undefined) return\n this.fanOutCounts.set(parentTaskId, (this.fanOutCounts.get(parentTaskId) ?? 0) + 1)\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\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 }\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(\n (s): s is StrategyResult['steps'][number] => s !== undefined,\n )\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 }\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, CoreToolDescriptor } 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\n constructor(config: SwarmConfig) {\n this.validateConfig(config)\n\n this.config = config\n this.agents = new Map()\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: Date.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 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.1-alpha.0",
3
+ "version": "0.0.1-alpha.2",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -19,13 +19,13 @@
19
19
  "tag": "alpha"
20
20
  },
21
21
  "dependencies": {
22
- "@x-otto/ai": "0.0.1-alpha.0",
23
- "@x-otto/hook-contracts": "0.0.1-alpha.0",
24
- "@x-otto/hooks": "0.0.1-alpha.0",
25
- "@x-otto/orchestration-contracts": "0.0.1-alpha.0",
26
- "@x-otto/interchange": "0.1.0-alpha.1",
27
- "@x-otto/shared": "0.1.0-alpha.1",
28
- "zod": "^3.24.4"
22
+ "zod": "^3.24.4",
23
+ "@x-otto/ai": "0.0.1-alpha.1",
24
+ "@x-otto/orchestration-contracts": "0.0.1-alpha.1",
25
+ "@x-otto/hooks": "0.0.1-alpha.1",
26
+ "@x-otto/interchange": "0.1.0-alpha.2",
27
+ "@x-otto/hook-contracts": "0.0.1-alpha.1",
28
+ "@x-otto/shared": "0.1.0-alpha.5"
29
29
  },
30
30
  "scripts": {
31
31
  "build": "tsdown",