fix(tasks): use --expect-final for agent dispatch and Aegis review
The two-step agent → agent.wait pattern used in dispatchAssignedTasks and runAegisReviews only returns lifecycle metadata (runId, status, timestamps). The agent's actual response text is only available via --expect-final on the initial agent call, which blocks until completion and returns the full payload including result.payloads[0].text. Without this fix: - Task resolution is stored as the raw wait JSON instead of the agent's response - Aegis cannot parse a VERDICT from the resolution, so it always defaults to rejected - Tasks are permanently stuck in a reject/retry loop and never complete Fix: replace the two-call pattern with a single --expect-final call in both dispatchAssignedTasks and runAegisReviews. Also improve sessionId extraction to use the agentMeta path from the final payload. Co-authored-by: Tom Watts <tom@techteamup.com>
This commit is contained in:
parent
4fa1cbd3a5
commit
5d7b05b4f6
|
|
@ -215,22 +215,18 @@ export async function runAegisReviews(): Promise<{ ok: boolean; message: string
|
|||
idempotencyKey: `aegis-review-${task.id}-${Date.now()}`,
|
||||
deliver: false,
|
||||
}
|
||||
const invokeResult = await runOpenClaw(
|
||||
['gateway', 'call', 'agent', '--timeout', '10000', '--params', JSON.stringify(invokeParams), '--json'],
|
||||
{ timeoutMs: 12_000 }
|
||||
)
|
||||
const acceptedPayload = parseGatewayJson(invokeResult.stdout)
|
||||
?? parseGatewayJson(String((invokeResult as any)?.stderr || ''))
|
||||
const runId = acceptedPayload?.runId
|
||||
if (!runId) throw new Error('Gateway did not return a runId for Aegis review')
|
||||
|
||||
const waitResult = await runOpenClaw(
|
||||
['gateway', 'call', 'agent.wait', '--timeout', '120000', '--params', JSON.stringify({ runId, timeoutMs: 115_000 }), '--json'],
|
||||
// Use --expect-final to block until the agent completes and returns the full
|
||||
// response payload (payloads[0].text). The two-step agent → agent.wait pattern
|
||||
// only returns lifecycle metadata (runId/status/timestamps) and never includes
|
||||
// the agent's actual text, so Aegis could never parse a verdict.
|
||||
const finalResult = await runOpenClaw(
|
||||
['gateway', 'call', 'agent', '--expect-final', '--timeout', '120000', '--params', JSON.stringify(invokeParams), '--json'],
|
||||
{ timeoutMs: 125_000 }
|
||||
)
|
||||
const waitPayload = parseGatewayJson(waitResult.stdout)
|
||||
const finalPayload = parseGatewayJson(finalResult.stdout)
|
||||
?? parseGatewayJson(String((finalResult as any)?.stderr || ''))
|
||||
const agentResponse = parseAgentResponse(
|
||||
waitPayload?.result ? JSON.stringify(waitPayload.result) : waitResult.stdout
|
||||
finalPayload?.result ? JSON.stringify(finalPayload.result) : finalResult.stdout
|
||||
)
|
||||
if (!agentResponse.text) {
|
||||
throw new Error('Aegis review returned empty response')
|
||||
|
|
@ -382,28 +378,21 @@ export async function dispatchAssignedTasks(): Promise<{ ok: boolean; message: s
|
|||
idempotencyKey: `task-dispatch-${task.id}-${Date.now()}`,
|
||||
deliver: false,
|
||||
}
|
||||
const invokeResult = await runOpenClaw(
|
||||
['gateway', 'call', 'agent', '--timeout', '10000', '--params', JSON.stringify(invokeParams), '--json'],
|
||||
{ timeoutMs: 12_000 }
|
||||
)
|
||||
const acceptedPayload = parseGatewayJson(invokeResult.stdout)
|
||||
?? parseGatewayJson(String((invokeResult as any)?.stderr || ''))
|
||||
const runId = acceptedPayload?.runId
|
||||
if (!runId) throw new Error('Gateway did not return a runId for task dispatch')
|
||||
|
||||
// Step 2: Wait for completion
|
||||
const waitResult = await runOpenClaw(
|
||||
['gateway', 'call', 'agent.wait', '--timeout', '120000', '--params', JSON.stringify({ runId, timeoutMs: 115_000 }), '--json'],
|
||||
// Use --expect-final to block until the agent completes and returns the full
|
||||
// response payload (result.payloads[0].text). The two-step agent → agent.wait
|
||||
// pattern only returns lifecycle metadata and never includes the agent's text.
|
||||
const finalResult = await runOpenClaw(
|
||||
['gateway', 'call', 'agent', '--expect-final', '--timeout', '120000', '--params', JSON.stringify(invokeParams), '--json'],
|
||||
{ timeoutMs: 125_000 }
|
||||
)
|
||||
const waitPayload = parseGatewayJson(waitResult.stdout)
|
||||
const finalPayload = parseGatewayJson(finalResult.stdout)
|
||||
?? parseGatewayJson(String((finalResult as any)?.stderr || ''))
|
||||
|
||||
const agentResponse = parseAgentResponse(
|
||||
waitPayload?.result ? JSON.stringify(waitPayload.result) : waitResult.stdout
|
||||
finalPayload?.result ? JSON.stringify(finalPayload.result) : finalResult.stdout
|
||||
)
|
||||
// Capture sessionId from the wait payload if not in the parsed response
|
||||
if (!agentResponse.sessionId && waitPayload?.sessionId) {
|
||||
agentResponse.sessionId = waitPayload.sessionId
|
||||
if (!agentResponse.sessionId && finalPayload?.result?.meta?.agentMeta?.sessionId) {
|
||||
agentResponse.sessionId = finalPayload.result.meta.agentMeta.sessionId
|
||||
}
|
||||
|
||||
if (!agentResponse.text) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue