@@ -90,9 +90,7 @@ func (cmd *AgentWorkerCMD) Run(ctx *cliContext.Context) error {
9090
9191 // Start heartbeat
9292 heartbeatInterval , _ := time .ParseDuration (cmd .HeartbeatInterval )
93- if heartbeatInterval == 0 {
94- heartbeatInterval = 10 * time .Second
95- }
93+ heartbeatInterval = cmp .Or (heartbeatInterval , 10 * time .Second )
9694 // Context cancelled on shutdown — used by heartbeat and other background goroutines
9795 shutdownCtx , shutdownCancel := context .WithCancel (context .Background ())
9896 defer shutdownCancel ()
@@ -145,8 +143,8 @@ func (cmd *AgentWorkerCMD) Run(ctx *cliContext.Context) error {
145143 // Subscribe to MCP CI job execution (load-balanced across agent workers).
146144 // In distributed mode, MCP CI jobs are routed here because the frontend
147145 // cannot create MCP sessions (e.g., stdio servers using docker).
148- natsClient .QueueSubscribe (messaging .SubjectJobsNew , messaging .QueueWorkers , func (data []byte ) {
149- handleMCPCIJob (data , apiURL , cmd .APIToken , natsClient )
146+ natsClient .QueueSubscribe (messaging .SubjectMCPCIJobsNew , messaging .QueueWorkers , func (data []byte ) {
147+ handleMCPCIJob (shutdownCtx , data , apiURL , cmd .APIToken , natsClient )
150148 })
151149
152150 // Subscribe to backend stop events to clean up cached MCP sessions.
@@ -171,11 +169,7 @@ func (cmd *AgentWorkerCMD) Run(ctx *cliContext.Context) error {
171169 xlog .Info ("Shutting down agent worker" )
172170 dispatcher .Stop ()
173171 mcpTools .CloseAllMCPSessions ()
174- if err := regClient .Deregister (context .Background (), nodeID ); err != nil {
175- xlog .Warn ("Failed to deregister" , "error" , err )
176- } else {
177- xlog .Info ("Deregistered from frontend" )
178- }
172+ regClient .GracefulDeregister (nodeID )
179173 return nil
180174}
181175
@@ -279,7 +273,9 @@ func sendMCPDiscoveryReply(reply func([]byte), servers []mcpRemote.MCPServerInfo
279273 reply (data )
280274}
281275
282- // natsClientAdapter wraps messaging.Client to satisfy NATSClient interface.
276+ // natsClientAdapter wraps messaging.Client to satisfy agents.NATSClient.
277+ // The concrete Client.QueueSubscribe returns *nats.Subscription; this adapter
278+ // widens it to messaging.Subscription so it matches the interface.
283279type natsClientAdapter struct {
284280 client * messaging.Client
285281}
@@ -288,13 +284,13 @@ func (a *natsClientAdapter) Publish(subject string, data any) error {
288284 return a .client .Publish (subject , data )
289285}
290286
291- func (a * natsClientAdapter ) QueueSubscribe (subject , queue string , handler func (data []byte )) (agents. NATSSub , error ) {
287+ func (a * natsClientAdapter ) QueueSubscribe (subject , queue string , handler func (data []byte )) (messaging. Subscription , error ) {
292288 return a .client .QueueSubscribe (subject , queue , handler )
293289}
294290
295291// handleMCPCIJob processes an MCP CI job on the agent worker.
296292// The agent worker can create MCP sessions (has docker) and call the LocalAI API for inference.
297- func handleMCPCIJob (data []byte , apiURL , apiToken string , natsClient * messaging.Client ) {
293+ func handleMCPCIJob (shutdownCtx context. Context , data []byte , apiURL , apiToken string , natsClient * messaging.Client ) {
298294 var evt jobs.JobEvent
299295 if err := json .Unmarshal (data , & evt ); err != nil {
300296 xlog .Error ("Failed to unmarshal job event" , "error" , err )
@@ -370,7 +366,7 @@ func handleMCPCIJob(data []byte, apiURL, apiToken string, natsClient *messaging.
370366 llm := clients .NewLocalAILLM (task .Model , apiToken , apiURL )
371367
372368 // Build cogito options
373- ctx , cancel := context .WithTimeout (context . Background () , 10 * time .Minute )
369+ ctx , cancel := context .WithTimeout (shutdownCtx , 10 * time .Minute )
374370 defer cancel ()
375371
376372 // Update job status to running in DB
0 commit comments