mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 01:32:40 +00:00
fix(pi): remove running rows for refused subagent resumes (#7369)
A text-only refusal finishes successfully without identifying a child. Remove its provisional subagent row when the tool completes, while retaining the refusal in the tool timeline. Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
+68
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"provenance": {
|
||||
"package": "@gotgenes/pi-subagents",
|
||||
"version": "23.4.0",
|
||||
"sourceCommit": "63476ff869efd8ea339040f496fa734048b89e70",
|
||||
"piVersion": "0.84.4",
|
||||
"captureDate": "2026-10-19"
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"type": "tool_execution_start",
|
||||
"toolCallId": "resume-call",
|
||||
"toolName": "subagent",
|
||||
"args": {
|
||||
"subagent_type": "general-purpose",
|
||||
"description": "resume",
|
||||
"prompt": "Continue",
|
||||
"resume": "expired-child",
|
||||
"run_in_background": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "tool_execution_end",
|
||||
"toolCallId": "resume-call",
|
||||
"toolName": "subagent",
|
||||
"result": {
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Agent \"expired-child\" had its session released after its retention window; resume is unavailable, but its result is still retrievable via get_subagent_result."
|
||||
}
|
||||
]
|
||||
},
|
||||
"isError": false
|
||||
}
|
||||
],
|
||||
"messages": [
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "toolCall",
|
||||
"id": "resume-call",
|
||||
"name": "subagent",
|
||||
"arguments": {
|
||||
"subagent_type": "general-purpose",
|
||||
"description": "resume",
|
||||
"prompt": "Continue",
|
||||
"resume": "expired-child",
|
||||
"run_in_background": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "toolResult",
|
||||
"toolCallId": "resume-call",
|
||||
"toolName": "subagent",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Agent \"expired-child\" had its session released after its retention window; resume is unavailable, but its result is still retrievable via get_subagent_result."
|
||||
}
|
||||
],
|
||||
"isError": false
|
||||
}
|
||||
]
|
||||
}
|
||||
+26
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { ProviderSubagentStore } from "../../../../provider-subagents/store.js";
|
||||
import { createPiExtensionHost } from "../index.js";
|
||||
import { readSubagentFixture, verifySubagentFixture } from "../subagent-fixture-test.js";
|
||||
import { streamPiHistory } from "../../history-mapper.js";
|
||||
@@ -25,6 +26,31 @@ function publishService(agents: Array<{ id: string; outputFile?: string }>): voi
|
||||
}
|
||||
|
||||
describe("@gotgenes/pi-subagents adapter", () => {
|
||||
test.each([true, false])(
|
||||
"removes a refused resume from live and replayed subagents (background=%s)",
|
||||
async (background) => {
|
||||
// The result came from 23.4.0's real AgentTool and SubagentManager after releaseSession().
|
||||
// The child session was a fake; releaseSession replaced waiting for the retention sweep.
|
||||
const fixture = readSubagentFixture(
|
||||
new URL("./fixtures/refused-resume.json", import.meta.url),
|
||||
);
|
||||
const start = fixture.events[0]!;
|
||||
if (start.type !== "tool_execution_start") throw new Error("Expected a tool start");
|
||||
start.args = { ...(start.args as object), run_in_background: background };
|
||||
const assistant = fixture.messages[0]!;
|
||||
if (assistant.role !== "assistant") throw new Error("Expected an assistant tool call");
|
||||
for (const block of assistant.content) {
|
||||
if (block.type === "toolCall") block.arguments = start.args;
|
||||
}
|
||||
const events = await verifySubagentFixture(fixture);
|
||||
const store = new ProviderSubagentStore();
|
||||
store.apply("parent", "pi", { type: "upsert", id: "previous-child", status: "completed" });
|
||||
for (const event of events) store.apply("parent", "pi", event.event);
|
||||
expect(events.map(({ event }) => event.type)).toEqual(["upsert", "remove"]);
|
||||
expect(store.list("parent")).toMatchObject([{ id: "previous-child", status: "completed" }]);
|
||||
},
|
||||
);
|
||||
|
||||
test("reports a child's file after the child republishes the gotgenes service", async () => {
|
||||
const notifications: string[] = [];
|
||||
const emit = loadRuntimeBridge();
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ export const gotgenesPiSubagents: PiExtension = {
|
||||
detail,
|
||||
subagents: [{ type: "upsert" as const, id: call.callId, status: "failed" as const }],
|
||||
}
|
||||
: { detail };
|
||||
: { detail, subagents: [{ type: "remove" as const, id: call.callId }] };
|
||||
callsByAgent.set(details.data.agentId, call.callId);
|
||||
const file =
|
||||
outputFileFromToolResult(call.result) ?? pendingFilesByAgent.get(details.data.agentId);
|
||||
|
||||
Reference in New Issue
Block a user