@@ -937,6 +937,7 @@ function createRuntime() {
937937 } ) ) ,
938938 finalizeRun : vi . fn ( ( ) => ( { finalized : true , blockers : [ ] , finalStatus : "succeeded" } ) ) ,
939939 cancelRunGracefully : vi . fn ( async ( { runId } : any ) => ( { cancelled : true , runId } ) ) ,
940+ resumeRun : vi . fn ( async ( { runId } : any ) => ( { id : runId , status : "running" } ) ) ,
940941 steerMission : vi . fn ( ( { missionId } : any ) => ( { acknowledged : true , appliedAt : new Date ( ) . toISOString ( ) } ) ) ,
941942 getWorkerStates : vi . fn ( ( { runId } : any ) => [
942943 { attemptId : "a-1" , stepId : "s-1" , runId, state : "running" }
@@ -1242,6 +1243,7 @@ describe("adeRpcServer", () => {
12421243 "report_validation" ,
12431244 "delegate_to_subagent" ,
12441245 "delegate_parallel" ,
1246+ "message_worker" ,
12451247 "get_worker_output" ,
12461248 "list_workers" ,
12471249 "read_mission_status" ,
@@ -1257,7 +1259,6 @@ describe("adeRpcServer", () => {
12571259 "revise_plan" ,
12581260 "request_specialist" ,
12591261 "set_current_phase" ,
1260- "message_worker" ,
12611262 "update_tool_profiles" ,
12621263 ] )
12631264 ) ;
@@ -2704,6 +2705,127 @@ describe("adeRpcServer", () => {
27042705 } ) ;
27052706 } ) ;
27062707
2708+ it ( "queues message_worker handoffs for get_pending_messages when live delivery is unavailable" , async ( ) => {
2709+ await withEnv ( { ADE_RUN_ID : "run-1" } , async ( ) => {
2710+ const fixture = createRuntime ( ) ;
2711+ fixture . runtime . orchestratorService . getRunGraph = vi . fn ( ( ) => ( {
2712+ run : { id : "run-1" , missionId : "mission-1" , status : "running" , metadata : { } } ,
2713+ steps : [
2714+ {
2715+ id : "step-a" ,
2716+ runId : "run-1" ,
2717+ missionStepId : null ,
2718+ stepKey : "worker-a" ,
2719+ stepIndex : 0 ,
2720+ title : "Worker A" ,
2721+ laneId : "lane-1" ,
2722+ status : "running" ,
2723+ joinPolicy : "all_success" ,
2724+ quorumCount : null ,
2725+ dependencyStepIds : [ ] ,
2726+ retryLimit : 1 ,
2727+ retryCount : 0 ,
2728+ lastAttemptId : "attempt-a" ,
2729+ createdAt : new Date ( ) . toISOString ( ) ,
2730+ updatedAt : new Date ( ) . toISOString ( ) ,
2731+ startedAt : new Date ( ) . toISOString ( ) ,
2732+ completedAt : null ,
2733+ metadata : { }
2734+ } ,
2735+ {
2736+ id : "step-b" ,
2737+ runId : "run-1" ,
2738+ missionStepId : null ,
2739+ stepKey : "worker-b" ,
2740+ stepIndex : 1 ,
2741+ title : "Worker B" ,
2742+ laneId : "lane-1" ,
2743+ status : "running" ,
2744+ joinPolicy : "all_success" ,
2745+ quorumCount : null ,
2746+ dependencyStepIds : [ ] ,
2747+ retryLimit : 1 ,
2748+ retryCount : 0 ,
2749+ lastAttemptId : "attempt-b" ,
2750+ createdAt : new Date ( ) . toISOString ( ) ,
2751+ updatedAt : new Date ( ) . toISOString ( ) ,
2752+ startedAt : new Date ( ) . toISOString ( ) ,
2753+ completedAt : null ,
2754+ metadata : { }
2755+ }
2756+ ] ,
2757+ attempts : [
2758+ { id : "attempt-a" , stepId : "step-a" , status : "running" , createdAt : new Date ( ) . toISOString ( ) , executorSessionId : "session-a" } ,
2759+ { id : "attempt-b" , stepId : "step-b" , status : "running" , createdAt : new Date ( ) . toISOString ( ) , executorSessionId : "session-b" }
2760+ ] ,
2761+ claims : [ ] ,
2762+ contextSnapshots : [ ] ,
2763+ handoffs : [ ] ,
2764+ timeline : [ ] ,
2765+ runtimeEvents : [ ] ,
2766+ completionEvaluation : null
2767+ } ) ) ;
2768+
2769+ const senderHandler = createAdeRpcRequestHandler ( { runtime : fixture . runtime , serverVersion : "test" } ) ;
2770+ await initialize ( senderHandler , {
2771+ callerId : "attempt-a" ,
2772+ role : "agent" ,
2773+ missionId : "mission-1" ,
2774+ runId : "run-1" ,
2775+ stepId : "step-a" ,
2776+ attemptId : "attempt-a"
2777+ } ) ;
2778+ const sent = await callTool ( senderHandler , "message_worker" , {
2779+ toWorkerId : "worker-b" ,
2780+ content : "contract is ready" ,
2781+ } ) ;
2782+
2783+ expect ( sent ?. isError ) . toBeUndefined ( ) ;
2784+ expect ( sent . structuredContent . ok ) . toBe ( true ) ;
2785+ expect ( sent . structuredContent . delivered ) . toBe ( false ) ;
2786+ expect ( sent . structuredContent . reason ) . toBe ( "queued_for_polling" ) ;
2787+ expect ( fixture . runtime . aiOrchestratorService . sendAgentMessage ) . toHaveBeenCalledWith (
2788+ expect . objectContaining ( {
2789+ missionId : "mission-1" ,
2790+ fromAttemptId : "attempt-a" ,
2791+ toAttemptId : "attempt-b" ,
2792+ content : "contract is ready" ,
2793+ metadata : expect . objectContaining ( {
2794+ source : "message_worker" ,
2795+ fromWorkerId : "worker-a" ,
2796+ toWorkerId : "worker-b" ,
2797+ queuedForPolling : true
2798+ } )
2799+ } )
2800+ ) ;
2801+
2802+ const recipientHandler = createAdeRpcRequestHandler ( { runtime : fixture . runtime , serverVersion : "test" } ) ;
2803+ await initialize ( recipientHandler , {
2804+ callerId : "attempt-b" ,
2805+ role : "agent" ,
2806+ missionId : "mission-1" ,
2807+ runId : "run-1" ,
2808+ stepId : "step-b" ,
2809+ attemptId : "attempt-b"
2810+ } ) ;
2811+ const pending = await callTool ( recipientHandler , "get_pending_messages" , { } ) ;
2812+
2813+ expect ( pending ?. isError ) . toBeUndefined ( ) ;
2814+ expect ( pending . structuredContent . messages ) . toEqual (
2815+ expect . arrayContaining ( [
2816+ expect . objectContaining ( {
2817+ role : "agent" ,
2818+ content : "contract is ready" ,
2819+ metadata : expect . objectContaining ( {
2820+ source : "message_worker" ,
2821+ interAgentDelivery : true
2822+ } )
2823+ } )
2824+ ] )
2825+ ) ;
2826+ } ) ;
2827+ } ) ;
2828+
27072829 it ( "surfaces native terminal rollups through get_pending_messages after report_result" , async ( ) => {
27082830 await withEnv ( { ADE_RUN_ID : "run-1" } , async ( ) => {
27092831 const fixture = createRuntime ( ) ;
@@ -3625,6 +3747,28 @@ describe("adeRpcServer", () => {
36253747 expect ( layoutGet . structuredContent . result ) . toEqual ( { left : 100 , right : 0 } ) ;
36263748 } ) ;
36273749
3750+ it ( "binds service method context when invoking dynamic ADE actions" , async ( ) => {
3751+ const fixture = createRuntime ( ) ;
3752+ const missionService = fixture . runtime . missionService as any ;
3753+ missionService . create = vi . fn ( function ( this : { get : ( missionId : string ) => unknown } , args : { prompt : string } ) {
3754+ expect ( args . prompt ) . toBe ( "smoke mission" ) ;
3755+ return this . get ( "mission-new" ) ;
3756+ } ) ;
3757+ const handler = createAdeRpcRequestHandler ( { runtime : fixture . runtime , serverVersion : "test" } ) ;
3758+ await initialize ( handler , { callerId : "agent-1" , role : "agent" } ) ;
3759+
3760+ const response = await callTool ( handler , "run_ade_action" , {
3761+ domain : "mission" ,
3762+ action : "create" ,
3763+ args : { prompt : "smoke mission" } ,
3764+ } ) ;
3765+
3766+ expect ( response ?. isError ) . toBeUndefined ( ) ;
3767+ expect ( missionService . create ) . toHaveBeenCalledWith ( { prompt : "smoke mission" } ) ;
3768+ expect ( response . structuredContent . result ) . toMatchObject ( { id : "mission-new" , status : "running" } ) ;
3769+ expect ( response . structuredContent . statusHints . missionId ) . toBe ( "mission-new" ) ;
3770+ } ) ;
3771+
36283772 it ( "does not expose unlisted service methods through dynamic ADE actions" , async ( ) => {
36293773 const fixture = createRuntime ( ) ;
36303774 const handler = createAdeRpcRequestHandler ( { runtime : fixture . runtime , serverVersion : "test" } ) ;
@@ -4245,7 +4389,7 @@ describe("adeRpcServer", () => {
42454389 ) ;
42464390 } ) ;
42474391
4248- it ( "routes resume_mission to orchestratorService .resumeRun" , async ( ) => {
4392+ it ( "routes resume_mission through aiOrchestratorService .resumeRun so coordinator runtime restarts " , async ( ) => {
42494393 const fixture = createRuntime ( ) ;
42504394 const handler = createAdeRpcRequestHandler ( { runtime : fixture . runtime , serverVersion : "test" } ) ;
42514395
@@ -4255,7 +4399,7 @@ describe("adeRpcServer", () => {
42554399 expect ( response ?. isError ) . toBeUndefined ( ) ;
42564400 expect ( response . structuredContent . run . id ) . toBe ( "run-1" ) ;
42574401 expect ( response . structuredContent . run . status ) . toBe ( "running" ) ;
4258- expect ( fixture . runtime . orchestratorService . resumeRun ) . toHaveBeenCalledWith ( { runId : "run-1" } ) ;
4402+ expect ( fixture . runtime . aiOrchestratorService . resumeRun ) . toHaveBeenCalledWith ( { runId : "run-1" } ) ;
42594403 } ) ;
42604404
42614405 it ( "routes cancel_mission to aiOrchestratorService.cancelRunGracefully" , async ( ) => {
@@ -4411,6 +4555,23 @@ describe("adeRpcServer", () => {
44114555 it ( "routes get_worker_states to aiOrchestratorService.getWorkerStates" , async ( ) => {
44124556 const fixture = createRuntime ( ) ;
44134557 const handler = createAdeRpcRequestHandler ( { runtime : fixture . runtime , serverVersion : "test" } ) ;
4558+ fixture . runtime . orchestratorService . getRunGraph . mockReturnValueOnce ( {
4559+ run : { id : "run-1" , missionId : "mission-1" , status : "running" } ,
4560+ steps : [
4561+ { id : "step-1" , stepKey : "step-a" , laneId : "lane-1" , title : "Worker" , status : "completed" , retryCount : 0 , metadata : { } } ,
4562+ { id : "task-1" , stepKey : "task-a" , laneId : null , title : "Display task" , status : "pending" , retryCount : 0 , metadata : { isTask : true } } ,
4563+ { id : "system-1" , stepKey : "system-a" , laneId : null , title : "System" , status : "pending" , retryCount : 0 , metadata : { systemManaged : true } } ,
4564+ { id : "tracker-1" , stepKey : "tracker-a" , laneId : null , title : "Tracker" , status : "pending" , retryCount : 0 , metadata : { plannerLaunchTracker : true } } ,
4565+ { id : "planner-1" , stepKey : "__planner__" , laneId : null , title : "Planner" , status : "succeeded" , retryCount : 0 , metadata : { } } ,
4566+ ] ,
4567+ attempts : [ { id : "attempt-1" , stepId : "step-1" , status : "completed" } ] ,
4568+ claims : [ ] ,
4569+ contextSnapshots : [ ] ,
4570+ handoffs : [ ] ,
4571+ timeline : [ ] ,
4572+ runtimeEvents : [ ] ,
4573+ completionEvaluation : null ,
4574+ } ) ;
44144575
44154576 await initialize ( handler , { role : "external" } ) ;
44164577 const response = await callTool ( handler , "get_worker_states" , { runId : "run-1" } ) ;
@@ -4419,7 +4580,15 @@ describe("adeRpcServer", () => {
44194580 expect ( response . structuredContent . runId ) . toBe ( "run-1" ) ;
44204581 expect ( response . structuredContent . workers ) . toHaveLength ( 1 ) ;
44214582 expect ( response . structuredContent . workers [ 0 ] . state ) . toBe ( "running" ) ;
4583+ expect ( response . structuredContent . runWorkers ) . toHaveLength ( 1 ) ;
4584+ expect ( response . structuredContent . runWorkers [ 0 ] ) . toMatchObject ( {
4585+ workerId : "step-a" ,
4586+ status : "completed" ,
4587+ } ) ;
44224588 expect ( fixture . runtime . aiOrchestratorService . getWorkerStates ) . toHaveBeenCalledWith ( { runId : "run-1" } ) ;
4589+ expect ( fixture . runtime . orchestratorService . getRunGraph ) . toHaveBeenCalledWith (
4590+ expect . objectContaining ( { runId : "run-1" , timelineLimit : 0 } )
4591+ ) ;
44234592 } ) ;
44244593
44254594 it ( "routes get_timeline to orchestratorService.listTimeline" , async ( ) => {
0 commit comments