@@ -2,7 +2,11 @@ import { randomBytes, randomUUID } from "node:crypto";
22import fs from "node:fs/promises" ;
33import path from "node:path" ;
44import { afterEach , describe , expect , it } from "vitest" ;
5- import { clearRuntimeConfigSnapshot , type OpenClawConfig } from "../config/config.js" ;
5+ import {
6+ clearRuntimeConfigSnapshot ,
7+ getRuntimeConfig ,
8+ type OpenClawConfig ,
9+ } from "../config/config.js" ;
610import { callGateway as realCallGateway } from "../gateway/call.js" ;
711import { GatewayClient } from "../gateway/client.js" ;
812import { dispatchGatewayMethodInProcess as realDispatchGatewayMethodInProcess } from "../gateway/server-plugins.js" ;
@@ -18,6 +22,7 @@ import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-cha
1822import { isLiveTestEnabled } from "./live-test-helpers.js" ;
1923import { __testing as subagentAnnounceDeliveryTesting } from "./subagent-announce-delivery.js" ;
2024import { __testing as subagentAnnounceTesting } from "./subagent-announce.js" ;
25+ import { resolveSubagentController , steerControlledSubagentRun } from "./subagent-control.js" ;
2126import { listSubagentRunsForRequester } from "./subagent-registry.js" ;
2227
2328const LIVE = isLiveTestEnabled ( ) && isTruthyEnvValue ( process . env . OPENCLAW_LIVE_SUBAGENT_E2E ) ;
@@ -458,13 +463,7 @@ describeLive("subagent announce live", () => {
458463 context : "isolated" ,
459464 runTimeoutSeconds : 300 ,
460465 } ) } .`,
461- `Step 2: after spawn returns status="accepted", call subagents with exactly this JSON input: ${ JSON . stringify (
462- {
463- action : "steer" ,
464- target : "steered_child" ,
465- message : steerToken ,
466- } ,
467- ) } .`,
466+ 'Step 2: after spawn returns status="accepted", do not call the subagents tool; the test harness will steer the child.' ,
468467 `Step 3: call sessions_yield with message="waiting for ${ childToken } " and wait for the child completion event.` ,
469468 `Step 4: after the completion event arrives, reply exactly ${ parentToken } .` ,
470469 "Do not reply with the parent token until the child completion event is visible." ,
@@ -476,6 +475,23 @@ describeLive("subagent announce live", () => {
476475 initialError = error ;
477476 } ) ;
478477
478+ const spawnedRun = await waitFor ( "steered child spawn" , ( ) => {
479+ if ( initialError ) {
480+ throw initialError ;
481+ }
482+ return listSubagentRunsForRequester ( sessionKey ) . find (
483+ ( run ) => run . taskName === "steered_child" && ! run . endedAt ,
484+ ) ;
485+ } ) ;
486+ const cfg = getRuntimeConfig ( ) ;
487+ const steerResult = await steerControlledSubagentRun ( {
488+ cfg,
489+ controller : resolveSubagentController ( { cfg, agentSessionKey : sessionKey } ) ,
490+ entry : spawnedRun ,
491+ message : steerToken ,
492+ } ) ;
493+ expect ( steerResult . status ) . toBe ( "accepted" ) ;
494+
479495 const steeredRun = await waitFor ( "steered child completion" , ( ) => {
480496 if ( initialError ) {
481497 throw initialError ;
0 commit comments