| 115 | const registry = ctx.ports.agentAdapterRegistry |
| 116 | // onProgress closure: the backend loop accumulates token/tool counts -> emits an agent_progress event (carrying agentId for association) |
| 117 | const onProgress = (update: AgentProgressUpdate): void => { |
| 118 | emit({ type: 'agent_progress', agentId, label, phase, ...update }) |
| 119 | } |
| 120 | // Inject agent-level AbortController register/unregister: the backend creates the controller then calls |
| 121 | // registerAgentAbort to inject ports-layer bindings; service.kill(runId, agentId) uses this to |
| 122 | // precisely abort a single agent. When the registry is absent (agentRunner fallback path), there is no backend middle layer, |