@@ -232,9 +232,42 @@ const toolDefinitions: ToolDefinition[] = [
232232 }
233233 }
234234 } ,
235- { name : "template_list" , description : "List templates." , inputSchema : { type : "object" } } ,
236- { name : "template_get" , description : "Get template by ID." , inputSchema : { type : "object" , required : [ "template_id" ] } } ,
237- { name : "template_create" , description : "Create a template." , inputSchema : { type : "object" , required : [ "id" , "name" ] } } ,
235+ {
236+ name : "template_list" ,
237+ description : "List templates." ,
238+ inputSchema : {
239+ type : "object" ,
240+ properties : { } ,
241+ additionalProperties : false
242+ }
243+ } ,
244+ {
245+ name : "template_get" ,
246+ description : "Get template by ID." ,
247+ inputSchema : {
248+ type : "object" ,
249+ required : [ "template_id" ] ,
250+ properties : {
251+ template_id : { type : "string" , description : "Template ID to fetch." }
252+ } ,
253+ additionalProperties : false
254+ }
255+ } ,
256+ {
257+ name : "template_create" ,
258+ description : "Create a template." ,
259+ inputSchema : {
260+ type : "object" ,
261+ required : [ "id" , "name" ] ,
262+ properties : {
263+ id : { type : "string" , description : "Unique template ID." } ,
264+ name : { type : "string" , description : "Human-readable template name." } ,
265+ description : { type : "string" , description : "Optional template description." } ,
266+ system_prompt : { type : "string" , description : "Optional system prompt body." } ,
267+ metadata : { type : "object" , description : "Optional template metadata." }
268+ }
269+ }
270+ } ,
238271 {
239272 name : "agent_register" ,
240273 description : "Register an agent onto the bus. The display name is auto-generated as 'IDE (Model)' — e.g. 'Cursor (GPT-4)'. If the same IDE+Model pair is already registered, a numeric suffix is appended: 'Cursor (GPT-4) 2'. Optional `display_name` can be provided as a human-friendly alias. Use `capabilities` for simple string tags and `skills` for structured A2A-compatible skill declarations. Returns agent_id and a secret token for subsequent calls." ,
@@ -266,14 +299,141 @@ const toolDefinitions: ToolDefinition[] = [
266299 }
267300 }
268301 } ,
269- { name : "agent_heartbeat" , description : "Heartbeat an agent." , inputSchema : { type : "object" , required : [ "agent_id" , "token" ] } } ,
270- { name : "agent_resume" , description : "Resume an agent." , inputSchema : { type : "object" , required : [ "agent_id" , "token" ] } } ,
271- { name : "agent_unregister" , description : "Unregister an agent." , inputSchema : { type : "object" , required : [ "agent_id" , "token" ] } } ,
272- { name : "agent_list" , description : "List agents." , inputSchema : { type : "object" } } ,
273- { name : "agent_update" , description : "Update an agent's profile. Accepts optional display_name, description, capabilities, skills, and emoji." , inputSchema : { type : "object" , required : [ "agent_id" , "token" ] , properties : { agent_id : { type : "string" } , token : { type : "string" } , display_name : { type : "string" } , description : { type : "string" } , capabilities : { type : "array" , items : { type : "string" } } , skills : { type : "array" } , emoji : { type : "string" , description : "Single emoji for agent avatar. Must be a valid emoji character." } } } } ,
274- { name : "agent_set_typing" , description : "Set typing indicator." , inputSchema : { type : "object" , required : [ "thread_id" , "agent_id" , "is_typing" ] } } ,
275- { name : "msg_react" , description : "React to a message." , inputSchema : { type : "object" , required : [ "message_id" , "agent_id" , "reaction" ] } } ,
276- { name : "msg_unreact" , description : "Remove a reaction from a message." , inputSchema : { type : "object" , required : [ "message_id" , "agent_id" , "reaction" ] } } ,
302+ {
303+ name : "agent_heartbeat" ,
304+ description : "Heartbeat an agent." ,
305+ inputSchema : {
306+ type : "object" ,
307+ required : [ "agent_id" , "token" ] ,
308+ properties : {
309+ agent_id : { type : "string" , description : "Agent ID to heartbeat." } ,
310+ token : { type : "string" , description : "Agent token." }
311+ } ,
312+ additionalProperties : false
313+ }
314+ } ,
315+ {
316+ name : "agent_resume" ,
317+ description : "Resume an agent." ,
318+ inputSchema : {
319+ type : "object" ,
320+ required : [ "agent_id" , "token" ] ,
321+ properties : {
322+ agent_id : { type : "string" , description : "Agent ID to resume." } ,
323+ token : { type : "string" , description : "Agent token." }
324+ } ,
325+ additionalProperties : false
326+ }
327+ } ,
328+ {
329+ name : "agent_unregister" ,
330+ description : "Unregister an agent." ,
331+ inputSchema : {
332+ type : "object" ,
333+ required : [ "agent_id" , "token" ] ,
334+ properties : {
335+ agent_id : { type : "string" , description : "Agent ID to unregister." } ,
336+ token : { type : "string" , description : "Agent token." }
337+ } ,
338+ additionalProperties : false
339+ }
340+ } ,
341+ {
342+ name : "agent_list" ,
343+ description : "List agents." ,
344+ inputSchema : {
345+ type : "object" ,
346+ properties : { } ,
347+ additionalProperties : false
348+ }
349+ } ,
350+ {
351+ name : "agent_update" ,
352+ description : "Update an agent's profile. Accepts optional display_name, description, capabilities, skills, and emoji." ,
353+ inputSchema : {
354+ type : "object" ,
355+ required : [ "agent_id" , "token" ] ,
356+ properties : {
357+ agent_id : { type : "string" , description : "Agent ID to update." } ,
358+ token : { type : "string" , description : "Agent token." } ,
359+ display_name : { type : "string" , description : "Optional human-friendly alias shown in UI and message labels." } ,
360+ description : { type : "string" , description : "Optional short description of this agent's role." } ,
361+ capabilities : {
362+ type : "array" ,
363+ items : { type : "string" } ,
364+ description : "Simple capability tags for fast matching."
365+ } ,
366+ skills : {
367+ type : "array" ,
368+ description : "Structured skill declarations (A2A AgentCard compatible)." ,
369+ items : {
370+ type : "object" ,
371+ properties : {
372+ id : { type : "string" , description : "Machine-readable skill identifier." } ,
373+ name : { type : "string" , description : "Human-readable skill name." } ,
374+ description : { type : "string" , description : "What this skill does." } ,
375+ tags : {
376+ type : "array" ,
377+ items : { type : "string" } ,
378+ description : "Additional tags for routing."
379+ } ,
380+ examples : {
381+ type : "array" ,
382+ items : { type : "string" } ,
383+ description : "Example prompts."
384+ }
385+ } ,
386+ required : [ "id" , "name" ] ,
387+ additionalProperties : false
388+ }
389+ } ,
390+ emoji : { type : "string" , description : "Single emoji for agent avatar. Must be a valid emoji character." }
391+ } ,
392+ additionalProperties : false
393+ }
394+ } ,
395+ {
396+ name : "agent_set_typing" ,
397+ description : "Set typing indicator." ,
398+ inputSchema : {
399+ type : "object" ,
400+ required : [ "thread_id" , "agent_id" , "is_typing" ] ,
401+ properties : {
402+ thread_id : { type : "string" , description : "Thread ID." } ,
403+ agent_id : { type : "string" , description : "Agent ID." } ,
404+ is_typing : { type : "boolean" , description : "Typing indicator state." }
405+ } ,
406+ additionalProperties : false
407+ }
408+ } ,
409+ {
410+ name : "msg_react" ,
411+ description : "React to a message." ,
412+ inputSchema : {
413+ type : "object" ,
414+ required : [ "message_id" , "agent_id" , "reaction" ] ,
415+ properties : {
416+ message_id : { type : "string" , description : "Message ID." } ,
417+ agent_id : { type : "string" , description : "Agent ID." } ,
418+ reaction : { type : "string" , description : "Reaction content." }
419+ } ,
420+ additionalProperties : false
421+ }
422+ } ,
423+ {
424+ name : "msg_unreact" ,
425+ description : "Remove a reaction from a message." ,
426+ inputSchema : {
427+ type : "object" ,
428+ required : [ "message_id" , "agent_id" , "reaction" ] ,
429+ properties : {
430+ message_id : { type : "string" , description : "Message ID." } ,
431+ agent_id : { type : "string" , description : "Agent ID." } ,
432+ reaction : { type : "string" , description : "Reaction content." }
433+ } ,
434+ additionalProperties : false
435+ }
436+ } ,
277437 {
278438 name : "bus_connect" ,
279439 description : "One-step connect: register an agent and join (or create) a thread. Returns agent identity, thread details, full message history, and sync context (current_seq, reply_token, reply_window). Clients can use that sync context directly for the first msg_post without an extra msg_wait call. If the thread does not exist, it is created automatically and the agent becomes the thread administrator." ,
@@ -311,10 +471,54 @@ const toolDefinitions: ToolDefinition[] = [
311471 }
312472 }
313473 } ,
314- { name : "bus_get_config" , description : "Get bus config." , inputSchema : { type : "object" } } ,
315- { name : "msg_search" , description : "Search messages." , inputSchema : { type : "object" , required : [ "query" ] } } ,
316- { name : "msg_edit" , description : "Edit a message." , inputSchema : { type : "object" , required : [ "message_id" , "new_content" ] } } ,
317- { name : "msg_edit_history" , description : "Get message edit history." , inputSchema : { type : "object" , required : [ "message_id" ] } }
474+ {
475+ name : "bus_get_config" ,
476+ description : "Get bus config." ,
477+ inputSchema : {
478+ type : "object" ,
479+ properties : { } ,
480+ additionalProperties : false
481+ }
482+ } ,
483+ {
484+ name : "msg_search" ,
485+ description : "Search messages." ,
486+ inputSchema : {
487+ type : "object" ,
488+ required : [ "query" ] ,
489+ properties : {
490+ query : { type : "string" , description : "Search query." }
491+ } ,
492+ additionalProperties : false
493+ }
494+ } ,
495+ {
496+ name : "msg_edit" ,
497+ description : "Edit a message." ,
498+ inputSchema : {
499+ type : "object" ,
500+ required : [ "message_id" , "new_content" ] ,
501+ properties : {
502+ message_id : { type : "string" , description : "Message ID to edit." } ,
503+ new_content : { type : "string" , description : "Replacement message content." } ,
504+ agent_id : { type : "string" , description : "Agent ID performing the edit." } ,
505+ token : { type : "string" , description : "Agent token used for authentication." }
506+ } ,
507+ additionalProperties : false
508+ }
509+ } ,
510+ {
511+ name : "msg_edit_history" ,
512+ description : "Get message edit history." ,
513+ inputSchema : {
514+ type : "object" ,
515+ required : [ "message_id" ] ,
516+ properties : {
517+ message_id : { type : "string" , description : "Message ID." }
518+ } ,
519+ additionalProperties : false
520+ }
521+ }
318522] ;
319523
320524export function listTools ( ) : ToolDefinition [ ] {
@@ -323,6 +527,7 @@ export function listTools(): ToolDefinition[] {
323527
324528type ToolCallContext = {
325529 sessionId ?: string ;
530+ abortSignal ?: AbortSignal ;
326531} ;
327532
328533const toolCallContext = new AsyncLocalStorage < ToolCallContext > ( ) ;
@@ -401,6 +606,10 @@ function setConnectionAgent(agentId: string, token: string): void {
401606 connectionAgents . set ( sessionId , { agentId, token } ) ;
402607}
403608
609+ function getToolAbortSignal ( ) : AbortSignal | undefined {
610+ return toolCallContext . getStore ( ) ?. abortSignal ;
611+ }
612+
404613function toPythonUtcIsoString ( value : string ) : string {
405614 const zuluMatch = value . match ( / ^ ( .+ ?) (?: \. ( \d + ) ) ? Z $ / ) ;
406615 if ( zuluMatch ) {
@@ -479,7 +688,8 @@ export async function withToolCallContext<T>(
479688 context : ToolCallContext ,
480689 fn : ( ) => Promise < T >
481690) : Promise < T > {
482- return await toolCallContext . run ( context , fn ) ;
691+ const parent = toolCallContext . getStore ( ) || { } ;
692+ return await toolCallContext . run ( { ...parent , ...context } , fn ) ;
483693}
484694
485695export async function callTool ( name : string , args : Record < string , unknown > ) : Promise < unknown > {
@@ -686,7 +896,8 @@ export async function callTool(name: string, args: Record<string, unknown>): Pro
686896 agents_waiting : Object . entries ( threadWaitStates ) . map ( ( [ agentId , ws ] ) => ( {
687897 agent_id : agentId ,
688898 entered_at : ws . entered_at ,
689- timeout_ms : ws . timeout_ms
899+ timeout_ms : ws . timeout_ms ,
900+ wait_call_id : ws . wait_call_id
690901 } ) ) ,
691902 count : Object . keys ( threadWaitStates ) . length
692903 } ;
@@ -724,7 +935,7 @@ export async function callTool(name: string, args: Record<string, unknown>): Pro
724935
725936 // Fix #6: Exit wait state for the posting agent
726937 if ( authorAgentId ) {
727- getStore ( ) . exitWaitState ( threadId , authorAgentId ) ;
938+ getStore ( ) . exitWaitState ( threadId , authorAgentId , undefined , "msg_post" ) ;
728939 }
729940
730941 const postPayload : Record < string , unknown > = {
@@ -1066,7 +1277,8 @@ export async function callTool(name: string, args: Record<string, unknown>): Pro
10661277 agentId,
10671278 agentToken : verifiedAgent ? token : undefined ,
10681279 timeoutMs : effectiveTimeoutMs ,
1069- forAgent
1280+ forAgent,
1281+ abortSignal : getToolAbortSignal ( )
10701282 } ) ;
10711283
10721284 // Match Python dispatch.py L1279-1296: support blocks return format
0 commit comments