@@ -423,22 +423,15 @@ export namespace SessionPrompt {
423423 // so the next resolveTools() call (once per LLM turn) naturally picks up fresh
424424 // tools without any extra work here. This subscription makes the session layer
425425 // explicitly aware of the reconnect and logs it so it is traceable in prod.
426- let toolsNeedRefresh = false
427426 const unsubscribeToolsChanged = Bus . subscribe ( MCP . ToolsChanged , ( event ) => {
428427 log . info ( "MCP.ToolsChanged received — tools will refresh on next turn" , {
429428 server : event . properties . server ,
430429 sessionID,
431430 } )
432- toolsNeedRefresh = true
433431 } )
434432 using _unsubToolsChanged = defer ( unsubscribeToolsChanged )
435433 // altimate_change end
436434 while ( true ) {
437- // altimate_change start — log when a ToolsChanged event was received since last turn
438- if ( toolsNeedRefresh ) {
439- log . info ( "refreshing MCP tools after ToolsChanged event" , { sessionID } )
440- toolsNeedRefresh = false
441- }
442435 // altimate_change end
443436 // altimate_change start — SessionStatus.set became async in v1.4.0; await so busy state flushes before LLM call
444437 await SessionStatus . set ( sessionID , { type : "busy" } )
@@ -2592,6 +2585,33 @@ NOTE: At any point in time through this workflow you should feel free to ask the
25922585
25932586 // altimate_change start — /mcps enable/disable: direct handler bypasses LLM
25942587 if ( input . command === "mcps" ) {
2588+
2589+ // Helper: build and persist an assistant reply for a command shortcut.
2590+ async function respond (
2591+ parentID : string ,
2592+ responseText : string ,
2593+ ) : Promise < MessageV2 . WithParts > {
2594+ const now = Date . now ( )
2595+ const assistantMsg : MessageV2 . Assistant = {
2596+ id : MessageID . ascending ( ) , role : "assistant" , sessionID : input . sessionID ,
2597+ parentID, modelID : model . modelID , providerID : model . providerID ,
2598+ mode : "builder" , agent : "builder" ,
2599+ path : { cwd : Instance . directory , root : Instance . worktree } ,
2600+ cost : 0 , tokens : { total : 0 , input : 0 , output : 0 , reasoning : 0 , cache : { read : 0 , write : 0 } } ,
2601+ finish : "stop" , time : { created : now , completed : now } ,
2602+ }
2603+ await Session . updateMessage ( assistantMsg )
2604+ const textPart : MessageV2 . TextPart = {
2605+ id : PartID . ascending ( ) , sessionID : input . sessionID , messageID : assistantMsg . id ,
2606+ type : "text" , text : responseText , time : { start : now , end : now } ,
2607+ }
2608+ await Session . updatePart ( textPart )
2609+ Bus . publish ( Command . Event . Executed , {
2610+ name : input . command , sessionID : input . sessionID ,
2611+ arguments : input . arguments , messageID : assistantMsg . id ,
2612+ } )
2613+ return { info : assistantMsg , parts : [ textPart ] } as MessageV2 . WithParts
2614+ }
25952615 const trimmed = input . arguments . trim ( )
25962616
25972617 if ( ! trimmed ) {
@@ -2608,7 +2628,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
26082628 const icon = s . status === "connected" ? "\u2713" : "\u25cb"
26092629 const label =
26102630 s . status === "failed"
2611- ? icon + " " + s . status + " (" + ( s as any ) . error + ")"
2631+ ? icon + " " + s . status + " (" + s . error + ")"
26122632 : icon + " " + s . status
26132633 return "| `" + srv + "` | " + label + " |"
26142634 } )
@@ -2617,26 +2637,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
26172637 ? "MCP servers:\n\n| Server | Status |\n|---|---|\n" + rows
26182638 : "No MCP servers configured."
26192639
2620- const now = Date . now ( )
2621- const assistantMsg : MessageV2 . Assistant = {
2622- id : MessageID . ascending ( ) , role : "assistant" , sessionID : input . sessionID ,
2623- parentID : userMsg . info . id , modelID : model . modelID , providerID : model . providerID ,
2624- mode : "builder" , agent : "builder" ,
2625- path : { cwd : Instance . directory , root : Instance . worktree } ,
2626- cost : 0 , tokens : { total : 0 , input : 0 , output : 0 , reasoning : 0 , cache : { read : 0 , write : 0 } } ,
2627- finish : "stop" , time : { created : now , completed : now } ,
2628- }
2629- await Session . updateMessage ( assistantMsg )
2630- const textPart : MessageV2 . TextPart = {
2631- id : PartID . ascending ( ) , sessionID : input . sessionID , messageID : assistantMsg . id ,
2632- type : "text" , text : responseText , time : { start : now , end : now } ,
2633- }
2634- await Session . updatePart ( textPart )
2635- Bus . publish ( Command . Event . Executed , {
2636- name : input . command , sessionID : input . sessionID ,
2637- arguments : input . arguments , messageID : assistantMsg . id ,
2638- } )
2639- return { info : assistantMsg , parts : [ textPart ] } as MessageV2 . WithParts
2640+ return respond ( userMsg . info . id , responseText )
26402641 }
26412642
26422643 const subMatch = trimmed . match ( / ^ ( e n a b l e | d i s a b l e ) \s + ( \S + ) / )
@@ -2660,33 +2661,15 @@ NOTE: At any point in time through this workflow you should feel free to ask the
26602661 if ( entry ?. status === "connected" ) {
26612662 responseText = `MCP server **${ name } ** enabled. Status: connected.`
26622663 } else {
2663- responseText = `Attempted to enable MCP server **${ name } **. Status: ${ entry ?. status ?? "unknown" } ${ ( entry as any ) ?. error ? " — " + ( entry as any ) . error : "." } .`
2664+ const errSuffix = entry ?. status === "failed" ? " — " + entry . error : ""
2665+ responseText = `Attempted to enable MCP server **${ name } **. Status: ${ entry ?. status ?? "unknown" } ${ errSuffix } .`
26642666 }
26652667 } else {
26662668 await MCP . disconnect ( name )
26672669 responseText = `MCP server **${ name } ** disabled.`
26682670 }
26692671
2670- const now = Date . now ( )
2671- const assistantMsg : MessageV2 . Assistant = {
2672- id : MessageID . ascending ( ) , role : "assistant" , sessionID : input . sessionID ,
2673- parentID : userMsg . info . id , modelID : model . modelID , providerID : model . providerID ,
2674- mode : "builder" , agent : "builder" ,
2675- path : { cwd : Instance . directory , root : Instance . worktree } ,
2676- cost : 0 , tokens : { total : 0 , input : 0 , output : 0 , reasoning : 0 , cache : { read : 0 , write : 0 } } ,
2677- finish : "stop" , time : { created : now , completed : now } ,
2678- }
2679- await Session . updateMessage ( assistantMsg )
2680- const textPart : MessageV2 . TextPart = {
2681- id : PartID . ascending ( ) , sessionID : input . sessionID , messageID : assistantMsg . id ,
2682- type : "text" , text : responseText , time : { start : now , end : now } ,
2683- }
2684- await Session . updatePart ( textPart )
2685- Bus . publish ( Command . Event . Executed , {
2686- name : input . command , sessionID : input . sessionID ,
2687- arguments : input . arguments , messageID : assistantMsg . id ,
2688- } )
2689- return { info : assistantMsg , parts : [ textPart ] } as MessageV2 . WithParts
2672+ return respond ( userMsg . info . id , responseText )
26902673 }
26912674 }
26922675 // altimate_change end
0 commit comments