11import { IAgent } from "../interfaces/Agent.interface" ;
22import { IOperatorParams } from "../interfaces/Operator.interface" ;
33import { ExecutionMode } from "../interfaces/Session.interface" ;
4- import { sleep , Subject } from "functools-kit" ;
4+ import { getErrorMessage , sleep , Subject } from "functools-kit" ;
55import { GLOBAL_CONFIG } from "../config/params" ;
6+ import { errorSubject } from "../config/emitters" ;
67
78/**
89 * Type definition for dispose function.
@@ -49,7 +50,17 @@ class OperatorSignal {
4950 if ( this . _disposeRef ) {
5051 const disposeRef = this . _disposeRef ;
5152 this . _disposeRef = null ;
52- disposeRef ( ) ;
53+ try {
54+ disposeRef ( ) ;
55+ } catch ( error ) {
56+ // A throwing user dispose must not prevent the next signal from
57+ // opening — the previous one is torn down on a best-effort basis.
58+ console . error (
59+ `agent-swarm operator signal dispose error agentName=${
60+ this . params . agentName
61+ } clientId=${ this . params . clientId } error=${ getErrorMessage ( error ) } `
62+ ) ;
63+ }
5364 }
5465 this . _disposeRef = this . _signalFactory ( message , next ) ;
5566 }
@@ -65,7 +76,17 @@ class OperatorSignal {
6576 if ( this . _disposeRef ) {
6677 const disposeRef = this . _disposeRef ;
6778 this . _disposeRef = null ;
68- await disposeRef ( ) ;
79+ try {
80+ await disposeRef ( ) ;
81+ } catch ( error ) {
82+ // dispose is awaited from waitForOutput's timeout path: a throwing
83+ // user dispose would reject waitForOutput and hang the swarm race.
84+ console . error (
85+ `agent-swarm operator signal dispose error agentName=${
86+ this . params . agentName
87+ } clientId=${ this . params . clientId } error=${ getErrorMessage ( error ) } `
88+ ) ;
89+ }
6990 }
7091 }
7192}
@@ -124,7 +145,20 @@ export class ClientOperator implements IAgent {
124145 `ClientOperator agentName=${ this . params . agentName } clientId=${ this . params . clientId } execute tool mode forwarded to operator`
125146 ) ;
126147 }
127- this . _operatorSignal . sendMessage ( input , this . _outgoingSubject . next ) ;
148+ try {
149+ this . _operatorSignal . sendMessage ( input , this . _outgoingSubject . next ) ;
150+ } catch ( error ) {
151+ // execute is fired without await from ClientSession.execute: a throwing
152+ // operator connector would surface as an unhandled rejection and crash
153+ // the host process. Surface the error instead; the pending waitForOutput
154+ // resolves through the operator timeout.
155+ console . error (
156+ `agent-swarm operator connector error agentName=${
157+ this . params . agentName
158+ } clientId=${ this . params . clientId } error=${ getErrorMessage ( error ) } `
159+ ) ;
160+ await errorSubject . next ( [ this . params . clientId , error as Error ] ) ;
161+ }
128162 GLOBAL_CONFIG . CC_LOGGER_ENABLE_DEBUG &&
129163 this . params . logger . debug (
130164 `ClientOperator agentName=${ this . params . agentName } clientId=${ this . params . clientId } execute end` ,
0 commit comments