mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-29 12:42:57 +00:00
Show completed edxeth Pi children as finished, live and after restart (#8176)
* fix(pi): settle edxeth subagent lifecycle events * test(pi): preserve completed children when restoring captured histories Verify the completed child and assistant transcript through history replay and the store consumed by clients. Both captured completion protocols otherwise leave a running descriptor. Co-authored-by: Zeno_ <lin1071833138@gmail.com> --------- Co-authored-by: Zeno_ <lin1071833138@gmail.com> Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
+8
@@ -0,0 +1,8 @@
|
||||
{"type": "session", "version": 3, "id": "e56a0006-f421-45be-9aef-e4019db1cf24", "timestamp": "2026-10-21T13:05:57.384Z", "cwd": "/tmp/paseo-edxeth-fixture/lean/workspace", "name": "[marker] Fixture marker verification", "parentSession": "/tmp/paseo-edxeth-fixture/lean/sessions/2026-10-21T13-05-53-085Z_01a15e91-73bd-7282-82c6-d3974711a941.jsonl"}
|
||||
{"type": "custom", "customType": "pi-subagents_launch_metadata", "data": {"version": 1, "timestamp": "2026-10-21T13:05:57.385Z", "name": "fixture-marker", "title": "Fixture marker verification", "sessionTitle": "[marker] Fixture marker verification", "agent": "marker", "mode": "background", "sessionMode": "lineage-only", "autoExit": true, "parentClosePolicy": "terminate", "reportContextUsage": true, "async": true, "model": "openai-codex/gpt-5.6-sol", "thinking": "high", "modelRef": "openai-codex/gpt-5.6-sol:high", "definitionModel": "openai-codex/gpt-5.6-sol", "definitionThinking": "high", "allowModelOverride": true, "modelSource": "agent", "tools": "read", "denyTools": ["subagent", "subagent_resume", "subagent_kill"], "spawnableAgents": [], "spawnBudget": null, "extensions": [], "noContextFiles": false, "inheritAppendSystem": false, "noSession": false, "trustProject": false, "agentConfigDir": "/tmp/paseo-edxeth-fixture/lean/agent", "cwd": "/tmp/paseo-edxeth-fixture/lean/workspace", "boundarySystemPrompt": false}, "id": "57355eeb", "parentId": null, "timestamp": "2026-10-21T13:05:57.386Z"}
|
||||
{"type": "session_info", "id": "847415e4", "parentId": "57355eeb", "timestamp": "2026-10-21T13:05:57.566Z", "name": "[marker] Fixture marker verification"}
|
||||
{"type": "model_change", "id": "d4ad59be", "parentId": "847415e4", "timestamp": "2026-10-21T13:05:57.672Z", "provider": "openai-codex", "modelId": "gpt-5.6-sol"}
|
||||
{"type": "thinking_level_change", "id": "7f6bf9d2", "parentId": "d4ad59be", "timestamp": "2026-10-21T13:05:57.672Z", "thinkingLevel": "high"}
|
||||
{"type": "message", "id": "737b762e", "parentId": "6b436446", "timestamp": "2026-10-21T13:05:57.679Z", "message": {"role": "user", "content": [{"type": "text", "text": "<file name=\"/home/pi-user/.pi/history/workspace/artifacts/01a15e91-73bd-7282-82c6-d3974711a941/context/fixture-marker-2026-10-21T13-05-57.md\">\n\n\nReturn only the exact marker supplied by the user. Do not use tools.\n\nComplete your task autonomously.\n\nReturn only PASEO_EDXETH_LEAN_OK\n\nYour FINAL assistant message should summarize what you accomplished.\n</file>\n"}], "timestamp": 1792587957678}}
|
||||
{"type": "message", "id": "100b110d", "parentId": "737b762e", "timestamp": "2026-10-21T13:06:02.050Z", "message": {"role": "assistant", "content": [{"type": "text", "text": "PASEO_EDXETH_LEAN_OK"}], "api": "openai-codex-responses", "provider": "openai-codex", "model": "gpt-5.6-sol", "usage": {"input": 1713, "output": 13, "cacheRead": 0, "cacheWrite": 0, "reasoning": 0, "totalTokens": 1726, "cost": {"input": 0.006852, "output": 0.00026000000000000003, "cacheRead": 0, "cacheWrite": 0, "total": 0.007111999999999999}}, "stopReason": "stop", "timestamp": 1792587957684, "responseId": "resp_0bc8bfaee079148a016ad8b8b7edb08191924676ed8dcfd447", "rawStopReason": "completed"}}
|
||||
{"type": "custom", "customType": "pi-subagent-completion", "data": {"reason": "normal"}, "id": "80bbd3bb", "parentId": "100b110d", "timestamp": "2026-10-21T13:06:02.054Z"}
|
||||
+263
@@ -0,0 +1,263 @@
|
||||
{
|
||||
"provenance": {
|
||||
"package": "Zeno2019/pi-subagents-lean",
|
||||
"version": "2.9.2-lean.1",
|
||||
"sourceCommit": "e10fe855808abcae193a205ea98f8ccd70d25620",
|
||||
"piVersion": "0.87.1",
|
||||
"captureDate": "2026-10-21"
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"type": "tool_execution_start",
|
||||
"toolCallId": "call_f28b261de3c6440b953f0f56c3fec7d0|fc_0d35cf51b3ed48b9016ad8b8b4a63c81918a55903d0a4f12cb",
|
||||
"toolName": "subagent",
|
||||
"args": {
|
||||
"agent": "marker",
|
||||
"name": "fixture-marker",
|
||||
"title": "Fixture marker verification",
|
||||
"task": "Return only PASEO_EDXETH_LEAN_OK"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "tool_execution_end",
|
||||
"toolCallId": "call_f28b261de3c6440b953f0f56c3fec7d0|fc_0d35cf51b3ed48b9016ad8b8b4a63c81918a55903d0a4f12cb",
|
||||
"toolName": "subagent",
|
||||
"result": {
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Sub-agent \"fixture-marker\" launched async with id 1bfdf3b3. Results will be delivered automatically as a steer message when it finishes. Use this exact id if you need to resume or stop this child.\n\nActivity: /home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/activity.jsonl\nRun evidence: /home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/result.json\nRead these on demand for progress or failure diagnosis; activity is evidence, not a completion verdict."
|
||||
}
|
||||
],
|
||||
"details": {
|
||||
"evidence": {
|
||||
"runId": "1bfdf3b3",
|
||||
"cwd": "/tmp/paseo-edxeth-fixture/lean/workspace",
|
||||
"activityFile": "/home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/activity.jsonl",
|
||||
"resultFile": "/home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/result.json"
|
||||
},
|
||||
"id": "1bfdf3b3",
|
||||
"name": "fixture-marker",
|
||||
"title": "Fixture marker verification",
|
||||
"task": "Return only PASEO_EDXETH_LEAN_OK",
|
||||
"agent": "marker",
|
||||
"sessionFile": "/tmp/paseo-edxeth-fixture/background/child-session.jsonl",
|
||||
"noSession": false,
|
||||
"status": "started",
|
||||
"mode": "background",
|
||||
"deliveryState": "detached",
|
||||
"parentClosePolicy": "terminate",
|
||||
"async": true,
|
||||
"autoExit": true
|
||||
}
|
||||
},
|
||||
"isError": false
|
||||
},
|
||||
{
|
||||
"type": "message_end",
|
||||
"message": {
|
||||
"role": "custom",
|
||||
"customType": "subagent_result",
|
||||
"content": "Sub-agent \"fixture-marker\" completed (7s).\n\nPASEO_EDXETH_LEAN_OK\n\nSession: /tmp/paseo-edxeth-fixture/background/child-session.jsonl\nResume: pi --session /tmp/paseo-edxeth-fixture/background/child-session.jsonl\n\nSub-agent context: 2K/372K tokens (0%) used at finish.\n\nActivity: /home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/activity.jsonl\nRun evidence: /home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/result.json\nRead these on demand for progress or failure diagnosis; activity is evidence, not a completion verdict.",
|
||||
"display": true,
|
||||
"details": {
|
||||
"evidence": {
|
||||
"runId": "1bfdf3b3",
|
||||
"cwd": "/tmp/paseo-edxeth-fixture/lean/workspace",
|
||||
"activityFile": "/home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/activity.jsonl",
|
||||
"resultFile": "/home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/result.json",
|
||||
"finalized": true
|
||||
},
|
||||
"id": "1bfdf3b3",
|
||||
"name": "fixture-marker",
|
||||
"task": "Return only PASEO_EDXETH_LEAN_OK",
|
||||
"agent": "marker",
|
||||
"mode": "background",
|
||||
"status": "completed",
|
||||
"deliveryState": "detached",
|
||||
"parentClosePolicy": "terminate",
|
||||
"async": true,
|
||||
"exitCode": 0,
|
||||
"elapsed": 7,
|
||||
"outputTokens": 13,
|
||||
"contextTokens": 1775,
|
||||
"contextWindow": 372000,
|
||||
"sessionFile": "/tmp/paseo-edxeth-fixture/background/child-session.jsonl"
|
||||
},
|
||||
"timestamp": 1792587964414
|
||||
}
|
||||
}
|
||||
],
|
||||
"messages": [
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "toolCall",
|
||||
"id": "call_f28b261de3c6440b953f0f56c3fec7d0|fc_0d35cf51b3ed48b9016ad8b8b4a63c81918a55903d0a4f12cb",
|
||||
"name": "subagent",
|
||||
"arguments": {
|
||||
"agent": "marker",
|
||||
"name": "fixture-marker",
|
||||
"title": "Fixture marker verification",
|
||||
"task": "Return only PASEO_EDXETH_LEAN_OK"
|
||||
}
|
||||
}
|
||||
],
|
||||
"api": "openai-codex-responses",
|
||||
"provider": "openai-codex",
|
||||
"model": "gpt-5.6-sol",
|
||||
"usage": {
|
||||
"input": 2020,
|
||||
"output": 43,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"reasoning": 0,
|
||||
"totalTokens": 2063,
|
||||
"cost": {
|
||||
"input": 0.00808,
|
||||
"output": 0.0008600000000000001,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"total": 0.00894
|
||||
}
|
||||
},
|
||||
"stopReason": "toolUse",
|
||||
"timestamp": 1792587953256,
|
||||
"responseId": "resp_0d35cf51b3ed48b9016ad8b8b3698481918f82962b6eaf2788",
|
||||
"rawStopReason": "completed"
|
||||
},
|
||||
{
|
||||
"role": "toolResult",
|
||||
"toolCallId": "call_f28b261de3c6440b953f0f56c3fec7d0|fc_0d35cf51b3ed48b9016ad8b8b4a63c81918a55903d0a4f12cb",
|
||||
"toolName": "subagent",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Sub-agent \"fixture-marker\" launched async with id 1bfdf3b3. Results will be delivered automatically as a steer message when it finishes. Use this exact id if you need to resume or stop this child.\n\nActivity: /home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/activity.jsonl\nRun evidence: /home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/result.json\nRead these on demand for progress or failure diagnosis; activity is evidence, not a completion verdict."
|
||||
}
|
||||
],
|
||||
"details": {
|
||||
"evidence": {
|
||||
"runId": "1bfdf3b3",
|
||||
"cwd": "/tmp/paseo-edxeth-fixture/lean/workspace",
|
||||
"activityFile": "/home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/activity.jsonl",
|
||||
"resultFile": "/home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/result.json",
|
||||
"finalized": true
|
||||
},
|
||||
"id": "1bfdf3b3",
|
||||
"name": "fixture-marker",
|
||||
"title": "Fixture marker verification",
|
||||
"task": "Return only PASEO_EDXETH_LEAN_OK",
|
||||
"agent": "marker",
|
||||
"sessionFile": "/tmp/paseo-edxeth-fixture/background/child-session.jsonl",
|
||||
"noSession": false,
|
||||
"status": "started",
|
||||
"mode": "background",
|
||||
"deliveryState": "detached",
|
||||
"parentClosePolicy": "terminate",
|
||||
"async": true,
|
||||
"autoExit": true
|
||||
},
|
||||
"isError": false,
|
||||
"timestamp": 1792587957399
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "thinking",
|
||||
"thinking": "**Identifying need for await keyword**"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"text": "DONE"
|
||||
}
|
||||
],
|
||||
"api": "openai-codex-responses",
|
||||
"provider": "openai-codex",
|
||||
"model": "gpt-5.6-sol",
|
||||
"usage": {
|
||||
"input": 2258,
|
||||
"output": 18,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"reasoning": 11,
|
||||
"totalTokens": 2276,
|
||||
"cost": {
|
||||
"input": 0.009032,
|
||||
"output": 0.00036,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"total": 0.009392
|
||||
}
|
||||
},
|
||||
"stopReason": "stop",
|
||||
"timestamp": 1792587957402,
|
||||
"responseId": "resp_0d35cf51b3ed48b9016ad8b8b602108191a8e8f7fd77fbe5b5",
|
||||
"rawStopReason": "completed"
|
||||
},
|
||||
{
|
||||
"role": "custom",
|
||||
"customType": "subagent_result",
|
||||
"content": "Sub-agent \"fixture-marker\" completed (7s).\n\nPASEO_EDXETH_LEAN_OK\n\nSession: /tmp/paseo-edxeth-fixture/background/child-session.jsonl\nResume: pi --session /tmp/paseo-edxeth-fixture/background/child-session.jsonl\n\nSub-agent context: 2K/372K tokens (0%) used at finish.\n\nActivity: /home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/activity.jsonl\nRun evidence: /home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/result.json\nRead these on demand for progress or failure diagnosis; activity is evidence, not a completion verdict.",
|
||||
"display": true,
|
||||
"details": {
|
||||
"evidence": {
|
||||
"runId": "1bfdf3b3",
|
||||
"cwd": "/tmp/paseo-edxeth-fixture/lean/workspace",
|
||||
"activityFile": "/home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/activity.jsonl",
|
||||
"resultFile": "/home/pi-user/.pi/history/workspace/artifacts/2026-10-21T13-05-57-380Z_db802a71-7bb32177-573971ee-535c/subagents/1bfdf3b3/result.json",
|
||||
"finalized": true
|
||||
},
|
||||
"id": "1bfdf3b3",
|
||||
"name": "fixture-marker",
|
||||
"task": "Return only PASEO_EDXETH_LEAN_OK",
|
||||
"agent": "marker",
|
||||
"mode": "background",
|
||||
"status": "completed",
|
||||
"deliveryState": "detached",
|
||||
"parentClosePolicy": "terminate",
|
||||
"async": true,
|
||||
"exitCode": 0,
|
||||
"elapsed": 7,
|
||||
"outputTokens": 13,
|
||||
"contextTokens": 1775,
|
||||
"contextWindow": 372000,
|
||||
"sessionFile": "/tmp/paseo-edxeth-fixture/background/child-session.jsonl"
|
||||
},
|
||||
"timestamp": 1792587964414
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "DONE"
|
||||
}
|
||||
],
|
||||
"api": "openai-codex-responses",
|
||||
"provider": "openai-codex",
|
||||
"model": "gpt-5.6-sol",
|
||||
"usage": {
|
||||
"input": 389,
|
||||
"output": 5,
|
||||
"cacheRead": 2176,
|
||||
"cacheWrite": 0,
|
||||
"reasoning": 0,
|
||||
"totalTokens": 2570,
|
||||
"cost": {
|
||||
"input": 0.0015559999999999999,
|
||||
"output": 0.0001,
|
||||
"cacheRead": 0.0008704000000000001,
|
||||
"cacheWrite": 0,
|
||||
"total": 0.0025264
|
||||
}
|
||||
},
|
||||
"stopReason": "stop",
|
||||
"timestamp": 1792587964417,
|
||||
"responseId": "resp_0d35cf51b3ed48b9016ad8b8bd0c548191bddd1fe3410a1c82",
|
||||
"rawStopReason": "completed"
|
||||
}
|
||||
]
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{"type": "session", "version": 3, "id": "afbea6e0-7858-4ecf-8ef1-e26af9b7d6e0", "timestamp": "2026-10-21T13:05:17.628Z", "cwd": "/tmp/paseo-edxeth-fixture/upstream/workspace", "name": "[marker] Fixture marker verification", "parentSession": "/tmp/paseo-edxeth-fixture/upstream/sessions/2026-10-21T13-05-12-212Z_01a15e90-d414-7243-a701-4eb4b0bec880.jsonl"}
|
||||
{"type": "custom", "customType": "pi-subagents_launch_metadata", "data": {"version": 1, "timestamp": "2026-10-21T13:05:17.628Z", "name": "fixture-marker", "title": "Fixture marker verification", "sessionTitle": "[marker] Fixture marker verification", "agent": "marker", "mode": "background", "sessionMode": "lineage-only", "autoExit": true, "parentClosePolicy": "terminate", "reportContextUsage": true, "async": false, "model": "openai-codex/gpt-5.6-sol", "thinking": "high", "modelRef": "openai-codex/gpt-5.6-sol:high", "definitionModel": "openai-codex/gpt-5.6-sol", "definitionThinking": "high", "allowModelOverride": true, "modelSource": "agent", "tools": "read", "denyTools": ["subagent", "subagent_resume", "subagent_kill"], "spawnableAgents": [], "spawnBudget": null, "extensions": [], "noContextFiles": false, "inheritAppendSystem": false, "noSession": false, "trustProject": false, "agentConfigDir": "/tmp/paseo-edxeth-fixture/upstream/agent", "cwd": "/tmp/paseo-edxeth-fixture/upstream/workspace", "boundarySystemPrompt": false}, "id": "3f7d3c3f", "parentId": null, "timestamp": "2026-10-21T13:05:17.629Z"}
|
||||
{"type": "session_info", "id": "6e198450", "parentId": "3f7d3c3f", "timestamp": "2026-10-21T13:05:17.825Z", "name": "[marker] Fixture marker verification"}
|
||||
{"type": "model_change", "id": "94bf4c0b", "parentId": "6e198450", "timestamp": "2026-10-21T13:05:17.962Z", "provider": "openai-codex", "modelId": "gpt-5.6-sol"}
|
||||
{"type": "thinking_level_change", "id": "57cc6428", "parentId": "94bf4c0b", "timestamp": "2026-10-21T13:05:17.962Z", "thinkingLevel": "high"}
|
||||
{"type": "message", "id": "a9e47f08", "parentId": "8c186624", "timestamp": "2026-10-21T13:05:17.970Z", "message": {"role": "user", "content": [{"type": "text", "text": "<file name=\"/home/pi-user/.pi/history/workspace/artifacts/01a15e90-d414-7243-a701-4eb4b0bec880/context/fixture-marker-2026-10-21T13-05-17.md\">\n\n\nReturn only the exact marker supplied by the user. Do not use tools.\n\nComplete your task autonomously.\n\nReturn only PASEO_EDXETH_UPSTREAM_OK\n\nYour FINAL assistant message should summarize what you accomplished.\n</file>\n"}], "timestamp": 1792587917968}}
|
||||
{"type": "message", "id": "bc221a13", "parentId": "a9e47f08", "timestamp": "2026-10-21T13:05:23.476Z", "message": {"role": "assistant", "content": [{"type": "thinking", "thinking": "**Following user file marker exactly**"}, {"type": "text", "text": "PASEO_EDXETH_UPSTREAM_OK"}], "api": "openai-codex-responses", "provider": "openai-codex", "model": "gpt-5.6-sol", "usage": {"input": 1673, "output": 49, "cacheRead": 0, "cacheWrite": 0, "reasoning": 34, "totalTokens": 1722, "cost": {"input": 0.006692, "output": 0.0009800000000000002, "cacheRead": 0, "cacheWrite": 0, "total": 0.007672}}, "stopReason": "stop", "timestamp": 1792587917974, "responseId": "resp_09445c1733d532e7016ad8b8909c908191ba803c059497945e", "rawStopReason": "completed"}}
|
||||
{"type": "custom", "customType": "pi-subagent-completion", "data": {"reason": "normal"}, "id": "832fc8c9", "parentId": "bc221a13", "timestamp": "2026-10-21T13:05:23.477Z"}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"provenance": {
|
||||
"package": "edxeth/pi-subagents",
|
||||
"version": "2.9.2",
|
||||
"sourceCommit": "cf6dbf41c17986f3882e6804a68e8fb8282d25e6",
|
||||
"piVersion": "0.87.1",
|
||||
"captureDate": "2026-10-21"
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"type": "tool_execution_start",
|
||||
"toolCallId": "call_0bc6fc2213cd49aa92950947bde5dd8a|fc_0a0ca4aa78cd296a016ad8b88d018481919eadbf09eb191a1a",
|
||||
"toolName": "subagent",
|
||||
"args": {
|
||||
"agent": "marker",
|
||||
"name": "fixture-marker",
|
||||
"title": "Fixture marker verification",
|
||||
"task": "Return only PASEO_EDXETH_UPSTREAM_OK"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "tool_execution_end",
|
||||
"toolCallId": "call_0bc6fc2213cd49aa92950947bde5dd8a|fc_0a0ca4aa78cd296a016ad8b88d018481919eadbf09eb191a1a",
|
||||
"toolName": "subagent",
|
||||
"result": {
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Sub-agent \"fixture-marker\" completed (7s).\n\nPASEO_EDXETH_UPSTREAM_OK\n\nSession: /tmp/paseo-edxeth-fixture/foreground/child-session.jsonl\nResume: pi --session /tmp/paseo-edxeth-fixture/foreground/child-session.jsonl\n\nSub-agent context: 2K/372K tokens (0%) used at finish."
|
||||
}
|
||||
],
|
||||
"details": {
|
||||
"id": "dd7f94e8",
|
||||
"name": "fixture-marker",
|
||||
"agent": "marker",
|
||||
"status": "completed",
|
||||
"mode": "background",
|
||||
"parentClosePolicy": "terminate",
|
||||
"deliveryState": "awaited",
|
||||
"async": false,
|
||||
"autoExit": true,
|
||||
"exitCode": 0,
|
||||
"elapsed": 7,
|
||||
"outputTokens": 49,
|
||||
"contextTokens": 1777,
|
||||
"contextWindow": 372000,
|
||||
"summary": "PASEO_EDXETH_UPSTREAM_OK",
|
||||
"sessionFile": "/tmp/paseo-edxeth-fixture/foreground/child-session.jsonl"
|
||||
}
|
||||
},
|
||||
"isError": false
|
||||
}
|
||||
],
|
||||
"messages": [
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "toolCall",
|
||||
"id": "call_0bc6fc2213cd49aa92950947bde5dd8a|fc_0a0ca4aa78cd296a016ad8b88d018481919eadbf09eb191a1a",
|
||||
"name": "subagent",
|
||||
"arguments": {
|
||||
"agent": "marker",
|
||||
"name": "fixture-marker",
|
||||
"title": "Fixture marker verification",
|
||||
"task": "Return only PASEO_EDXETH_UPSTREAM_OK"
|
||||
}
|
||||
}
|
||||
],
|
||||
"api": "openai-codex-responses",
|
||||
"provider": "openai-codex",
|
||||
"model": "gpt-5.6-sol",
|
||||
"usage": {
|
||||
"input": 3256,
|
||||
"output": 43,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"reasoning": 0,
|
||||
"totalTokens": 3299,
|
||||
"cost": {
|
||||
"input": 0.013023999999999999,
|
||||
"output": 0.0008600000000000001,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0,
|
||||
"total": 0.013883999999999999
|
||||
}
|
||||
},
|
||||
"stopReason": "toolUse",
|
||||
"timestamp": 1792587912428,
|
||||
"responseId": "resp_0a0ca4aa78cd296a016ad8b88bd52881918cbb9b8326b3060a",
|
||||
"rawStopReason": "completed"
|
||||
},
|
||||
{
|
||||
"role": "toolResult",
|
||||
"toolCallId": "call_0bc6fc2213cd49aa92950947bde5dd8a|fc_0a0ca4aa78cd296a016ad8b88d018481919eadbf09eb191a1a",
|
||||
"toolName": "subagent",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Sub-agent \"fixture-marker\" completed (7s).\n\nPASEO_EDXETH_UPSTREAM_OK\n\nSession: /tmp/paseo-edxeth-fixture/foreground/child-session.jsonl\nResume: pi --session /tmp/paseo-edxeth-fixture/foreground/child-session.jsonl\n\nSub-agent context: 2K/372K tokens (0%) used at finish."
|
||||
}
|
||||
],
|
||||
"details": {
|
||||
"id": "dd7f94e8",
|
||||
"name": "fixture-marker",
|
||||
"agent": "marker",
|
||||
"status": "completed",
|
||||
"mode": "background",
|
||||
"parentClosePolicy": "terminate",
|
||||
"deliveryState": "awaited",
|
||||
"async": false,
|
||||
"autoExit": true,
|
||||
"exitCode": 0,
|
||||
"elapsed": 7,
|
||||
"outputTokens": 49,
|
||||
"contextTokens": 1777,
|
||||
"contextWindow": 372000,
|
||||
"summary": "PASEO_EDXETH_UPSTREAM_OK",
|
||||
"sessionFile": "/tmp/paseo-edxeth-fixture/foreground/child-session.jsonl"
|
||||
},
|
||||
"isError": false,
|
||||
"timestamp": 1792587924671
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "DONE"
|
||||
}
|
||||
],
|
||||
"api": "openai-codex-responses",
|
||||
"provider": "openai-codex",
|
||||
"model": "gpt-5.6-sol",
|
||||
"usage": {
|
||||
"input": 388,
|
||||
"output": 5,
|
||||
"cacheRead": 3072,
|
||||
"cacheWrite": 0,
|
||||
"reasoning": 0,
|
||||
"totalTokens": 3465,
|
||||
"cost": {
|
||||
"input": 0.001552,
|
||||
"output": 0.0001,
|
||||
"cacheRead": 0.0012288000000000002,
|
||||
"cacheWrite": 0,
|
||||
"total": 0.0028808
|
||||
}
|
||||
},
|
||||
"stopReason": "stop",
|
||||
"timestamp": 1792587924675,
|
||||
"responseId": "resp_0a0ca4aa78cd296a016ad8b896af2c81919c0ef586dd50f2f0",
|
||||
"rawStopReason": "completed"
|
||||
}
|
||||
]
|
||||
}
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { createPiExtensionHost } from "../index.js";
|
||||
import { readSubagentFixture, verifySubagentFixture } from "../subagent-fixture-test.js";
|
||||
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { edxethPiSubagents } from "./index.js";
|
||||
import { streamPiHistory } from "../../history-mapper.js";
|
||||
import { ProviderSubagentStore } from "../../../../provider-subagents/store.js";
|
||||
|
||||
const args = {
|
||||
agent: "scout",
|
||||
name: "status-scout",
|
||||
title: "Check child status",
|
||||
task: "Return the completion marker",
|
||||
};
|
||||
|
||||
describe("edxeth/pi-subagents adapter", () => {
|
||||
test.each(["tool", "notification"])("ends a child that requested help via %s", (delivery) => {
|
||||
const host = createPiExtensionHost();
|
||||
const call = { callId: "spawn-1", toolName: "subagent", args, status: "completed" as const };
|
||||
host.mapToolCall({
|
||||
...call,
|
||||
result: { details: { id: "run-1", name: args.name, status: "started" } },
|
||||
});
|
||||
const details = { id: "run-1", name: args.name, message: "Please clarify the task" };
|
||||
const result =
|
||||
delivery === "tool"
|
||||
? host.mapToolCall({ ...call, result: { details: { ...details, status: "pinged" } } })
|
||||
: host.mapCustomMessage({
|
||||
role: "custom",
|
||||
customType: "subagent_ping",
|
||||
content: "Child requested help and exited",
|
||||
details,
|
||||
});
|
||||
expect(result?.subagents).toEqual([
|
||||
expect.objectContaining({
|
||||
type: "upsert",
|
||||
id: "spawn-1",
|
||||
status: "canceled",
|
||||
subtitle: "Needs help",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
test("leaves unrelated tools and other subagent protocols to their adapters", () => {
|
||||
const host = createPiExtensionHost(undefined, [edxethPiSubagents]);
|
||||
const call = { callId: "other", toolName: "subagent", args, status: "completed" as const };
|
||||
for (const details of [null, {}, { mode: "single", results: [] }, { id: "run-1" }]) {
|
||||
expect(host.mapToolCall({ ...call, result: { details } })).toBeUndefined();
|
||||
}
|
||||
expect(
|
||||
host.mapToolCall({
|
||||
...call,
|
||||
toolName: "unrelated",
|
||||
result: { details: { id: "run-1", name: args.name, status: "completed" } },
|
||||
}),
|
||||
).toBeUndefined();
|
||||
for (const details of [{ id: "run-1" }, { id: "run-1", status: "unknown" }]) {
|
||||
expect(
|
||||
host.mapCustomMessage({
|
||||
role: "custom",
|
||||
customType: "subagent_result",
|
||||
content: "Unrecognized result",
|
||||
details,
|
||||
}),
|
||||
).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
test("waits for cancellation after a kill acknowledgement reports stopping", () => {
|
||||
const host = createPiExtensionHost();
|
||||
host.mapToolCall({
|
||||
callId: "spawn-1",
|
||||
toolName: "subagent",
|
||||
args,
|
||||
status: "completed",
|
||||
result: { details: { id: "run-1", name: args.name, status: "started" } },
|
||||
});
|
||||
const stopping = host.mapToolCall({
|
||||
callId: "kill-1",
|
||||
toolName: "subagent_kill",
|
||||
args: { id: "run-1" },
|
||||
status: "completed",
|
||||
result: { details: { id: "run-1", name: args.name, status: "stopping" } },
|
||||
});
|
||||
expect(stopping?.subagents ?? []).toEqual([]);
|
||||
expect(
|
||||
host.mapCustomMessage({
|
||||
role: "custom",
|
||||
customType: "subagent_result",
|
||||
content: "Cancelled",
|
||||
details: { id: "run-1", status: "cancelled" },
|
||||
})?.subagents,
|
||||
).toEqual([{ type: "upsert", id: "spawn-1", status: "canceled" }]);
|
||||
});
|
||||
|
||||
test("preserves a completion that arrives before its launch acknowledgement", () => {
|
||||
const host = createPiExtensionHost();
|
||||
const early = host.mapCustomMessage({
|
||||
role: "custom",
|
||||
customType: "subagent_result",
|
||||
content: "Already done",
|
||||
details: { id: "fast-run", status: "completed" },
|
||||
});
|
||||
expect(early?.subagents ?? []).toEqual([]);
|
||||
const started = host.mapToolCall({
|
||||
callId: "fast-call",
|
||||
toolName: "subagent",
|
||||
args,
|
||||
status: "completed",
|
||||
result: {
|
||||
details: { id: "fast-run", name: args.name, agent: args.agent, status: "started" },
|
||||
},
|
||||
});
|
||||
expect(started?.subagents).toEqual([
|
||||
{
|
||||
type: "upsert",
|
||||
id: "fast-call",
|
||||
title: "scout",
|
||||
description: args.task,
|
||||
toolCallId: "fast-call",
|
||||
status: "completed",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ details: { status: "completed" }, expected: "completed" },
|
||||
{ details: { status: "failed" }, expected: "failed" },
|
||||
{ details: { status: "cancelled" }, expected: "canceled" },
|
||||
{ details: { error: "Child watcher exited unexpectedly" }, expected: "failed" },
|
||||
])("maps completion $details to $expected", ({ details, expected }) => {
|
||||
const host = createPiExtensionHost();
|
||||
host.mapToolCall({
|
||||
callId: "spawn-1",
|
||||
toolName: "subagent",
|
||||
args,
|
||||
status: "completed",
|
||||
result: { details: { id: "run-1", name: args.name, status: "started" } },
|
||||
});
|
||||
expect(
|
||||
host.mapCustomMessage({
|
||||
role: "custom",
|
||||
customType: "subagent_result",
|
||||
content: "Child result",
|
||||
details: { id: "run-1", ...details },
|
||||
})?.subagents,
|
||||
).toEqual([{ type: "upsert", id: "spawn-1", status: expected }]);
|
||||
});
|
||||
|
||||
test("a resume gets its own run and reads the retained child session", async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), "paseo-edxeth-resume-"));
|
||||
const file = join(dir, "child.jsonl");
|
||||
const host = createPiExtensionHost();
|
||||
try {
|
||||
await writeFile(
|
||||
file,
|
||||
JSON.stringify({
|
||||
type: "message",
|
||||
message: { role: "assistant", content: [{ type: "text", text: "RESUMED" }] },
|
||||
}) + "\n",
|
||||
);
|
||||
const original = host.mapToolCall({
|
||||
callId: "spawn-1",
|
||||
toolName: "subagent",
|
||||
args,
|
||||
status: "completed",
|
||||
result: {
|
||||
details: { id: "run-1", name: args.name, status: "completed", sessionFile: file },
|
||||
},
|
||||
});
|
||||
await original?.hydration;
|
||||
const resumed = host.mapToolCall({
|
||||
callId: "resume-1",
|
||||
toolName: "subagent_resume",
|
||||
args: { sessionFile: file, task: "Continue" },
|
||||
status: "completed",
|
||||
result: {
|
||||
details: { id: "run-2", name: args.name, status: "started", sessionFile: file },
|
||||
},
|
||||
});
|
||||
expect(resumed?.childSessions).toEqual([{ id: "resume-1", file }]);
|
||||
expect(await resumed?.hydration).toEqual([
|
||||
{
|
||||
type: "provider_subagent",
|
||||
provider: "pi",
|
||||
event: {
|
||||
type: "timeline",
|
||||
id: "resume-1",
|
||||
item: expect.objectContaining({ type: "assistant_message", text: "RESUMED" }),
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(
|
||||
host.mapCustomMessage({
|
||||
role: "custom",
|
||||
customType: "subagent_result",
|
||||
content: "Resumed run complete",
|
||||
details: { id: "run-2", status: "completed", sessionFile: file },
|
||||
})?.subagents,
|
||||
).toEqual([{ type: "upsert", id: "resume-1", status: "completed" }]);
|
||||
} finally {
|
||||
host.close();
|
||||
await rm(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("settles each batched child by run id without creating a parent-call card", () => {
|
||||
const host = createPiExtensionHost();
|
||||
const result = host.mapToolCall({
|
||||
callId: "batch-1",
|
||||
toolName: "subagent",
|
||||
args: { children: [args, { ...args, agent: "reviewer", name: "status-reviewer" }] },
|
||||
status: "completed",
|
||||
result: {
|
||||
details: {
|
||||
status: "batch",
|
||||
children: [
|
||||
{ id: "run-1", ...args, mode: "background", status: "completed" },
|
||||
{ id: "run-2", name: "status-reviewer", agent: "reviewer", status: "started" },
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(result?.subagents).toEqual([
|
||||
{
|
||||
type: "upsert",
|
||||
id: "batch-1:0",
|
||||
title: "scout",
|
||||
description: args.task,
|
||||
toolCallId: "batch-1",
|
||||
status: "completed",
|
||||
},
|
||||
{
|
||||
type: "upsert",
|
||||
id: "batch-1:1",
|
||||
title: "reviewer",
|
||||
description: undefined,
|
||||
toolCallId: "batch-1",
|
||||
status: "running",
|
||||
},
|
||||
]);
|
||||
expect(
|
||||
host.mapCustomMessage({
|
||||
role: "custom",
|
||||
customType: "subagent_result",
|
||||
content: "Done",
|
||||
details: { id: "run-2", status: "completed" },
|
||||
})?.subagents,
|
||||
).toEqual([{ type: "upsert", id: "batch-1:1", status: "completed" }]);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ mode: "foreground", statuses: ["running", "completed"] },
|
||||
{ mode: "background", statuses: ["running", "running", "completed"] },
|
||||
])("settles the captured $mode run live and on replay", async ({ mode, statuses }) => {
|
||||
const fixture = readSubagentFixture(new URL(`./fixtures/${mode}.json`, import.meta.url), {
|
||||
from: `/tmp/paseo-edxeth-fixture/${mode}/child-session.jsonl`,
|
||||
to: fileURLToPath(new URL(`./fixtures/${mode}-child-session.jsonl`, import.meta.url)),
|
||||
});
|
||||
const events = await verifySubagentFixture(fixture);
|
||||
const updates = events.flatMap(({ event }) => (event.type === "upsert" ? [event] : []));
|
||||
expect(updates.map((event) => event.status)).toEqual(statuses);
|
||||
expect(new Set(updates.map((event) => event.id)).size).toBe(1);
|
||||
expect(events.some(({ event }) => event.type === "timeline")).toBe(true);
|
||||
});
|
||||
|
||||
test.each(["foreground", "background"])(
|
||||
"restores a completed %s child and its transcript to the consumer store",
|
||||
async (mode) => {
|
||||
const fixture = readSubagentFixture(new URL(`./fixtures/${mode}.json`, import.meta.url), {
|
||||
from: `/tmp/paseo-edxeth-fixture/${mode}/child-session.jsonl`,
|
||||
to: fileURLToPath(new URL(`./fixtures/${mode}-child-session.jsonl`, import.meta.url)),
|
||||
});
|
||||
const store = new ProviderSubagentStore();
|
||||
for await (const event of streamPiHistory("pi", fixture.messages)) {
|
||||
if (event.type === "provider_subagent") store.apply("parent", "pi", event.event);
|
||||
}
|
||||
const children = store.list("parent");
|
||||
expect(children).toEqual([expect.objectContaining({ status: "completed", title: "marker" })]);
|
||||
const transcript = store.fetchTimeline("parent", children[0]!.id);
|
||||
expect(transcript.rows).toContainEqual(
|
||||
expect.objectContaining({
|
||||
item: expect.objectContaining({
|
||||
type: "assistant_message",
|
||||
text: mode === "foreground" ? "PASEO_EDXETH_UPSTREAM_OK" : "PASEO_EDXETH_LEAN_OK",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test("settles a synchronous result on the card created when the tool started", () => {
|
||||
const host = createPiExtensionHost();
|
||||
const call = { callId: "spawn-1", toolName: "subagent", args };
|
||||
const start = host.mapToolCall({ ...call, status: "running", result: null });
|
||||
expect(start?.subagents).toEqual([
|
||||
{
|
||||
type: "upsert",
|
||||
id: "spawn-1",
|
||||
title: "scout",
|
||||
description: args.task,
|
||||
toolCallId: "spawn-1",
|
||||
status: "running",
|
||||
},
|
||||
]);
|
||||
const end = host.mapToolCall({
|
||||
...call,
|
||||
status: "completed",
|
||||
result: {
|
||||
content: [{ type: "text", text: "DONE" }],
|
||||
details: {
|
||||
id: "run-1",
|
||||
name: args.name,
|
||||
agent: args.agent,
|
||||
mode: "background",
|
||||
status: "completed",
|
||||
deliveryState: "awaited",
|
||||
exitCode: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(end?.subagents).toEqual([
|
||||
{
|
||||
type: "upsert",
|
||||
id: "spawn-1",
|
||||
title: "scout",
|
||||
description: args.task,
|
||||
toolCallId: "spawn-1",
|
||||
status: "completed",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
import { z } from "zod";
|
||||
import { extractTextFromToolResult } from "../../tool-call-mapper.js";
|
||||
import type { PiChildSessionFile, PiExtension } from "../contract.js";
|
||||
import type { ProviderSubagentInputEvent } from "../../../../provider-subagents/store.js";
|
||||
|
||||
const Run = z
|
||||
.object({
|
||||
id: z.string().trim().min(1),
|
||||
name: z.string().trim().min(1),
|
||||
agent: z.string().trim().min(1).optional(),
|
||||
task: z.string().optional(),
|
||||
status: z.enum(["started", "completed", "failed", "cancelled", "pinged"]),
|
||||
sessionFile: z.string().trim().min(1).optional(),
|
||||
})
|
||||
.passthrough();
|
||||
const Args = z.object({ task: z.string().optional() }).passthrough();
|
||||
const Batch = z.object({ status: z.enum(["started", "batch"]), children: z.array(Run).min(1) });
|
||||
const Completion = z
|
||||
.object({
|
||||
id: z.string().trim().min(1),
|
||||
status: z.enum(["completed", "failed", "cancelled", "pinged"]).optional(),
|
||||
error: z.string().optional(),
|
||||
sessionFile: z.string().trim().min(1).optional(),
|
||||
})
|
||||
.passthrough();
|
||||
const Ping = Completion.extend({ message: z.string() });
|
||||
|
||||
function childStatus(status: z.infer<typeof Run>["status"]) {
|
||||
if (status === "started") return "running";
|
||||
// A ping ends the child process and needs a new resume run. It is not success.
|
||||
if (status === "cancelled" || status === "pinged") return "canceled";
|
||||
return status;
|
||||
}
|
||||
|
||||
export const edxethPiSubagents: PiExtension = {
|
||||
id: "edxeth/pi-subagents",
|
||||
createSession: () => {
|
||||
const callsByRun = new Map<string, string>();
|
||||
const completions = new Map<string, z.infer<typeof Completion>>();
|
||||
const readSessions = new Map<string, string>();
|
||||
const childSession = (id: string, file: string | undefined): PiChildSessionFile[] => {
|
||||
if (!file || readSessions.get(id) === file) return [];
|
||||
readSessions.set(id, file);
|
||||
return [{ id, file }];
|
||||
};
|
||||
const completeRun = (result: z.infer<typeof Completion>) => {
|
||||
const status = result.status ?? (result.error === undefined ? undefined : "failed");
|
||||
if (!status) return undefined;
|
||||
// A fast child can finish before the tool returns its run id. Keep the
|
||||
// terminal outcome so a later "started" acknowledgement cannot regress it.
|
||||
completions.set(result.id, { ...result, status });
|
||||
const id = callsByRun.get(result.id);
|
||||
if (!id) return undefined;
|
||||
const subagents: ProviderSubagentInputEvent[] = [
|
||||
{
|
||||
type: "upsert",
|
||||
id,
|
||||
status: childStatus(status),
|
||||
...(status === "pinged" ? { subtitle: "Needs help" } : {}),
|
||||
},
|
||||
];
|
||||
return { subagents, childSessions: childSession(id, result.sessionFile) };
|
||||
};
|
||||
return {
|
||||
mapToolCall(call) {
|
||||
const isLaunch = call.toolName === "subagent" || call.toolName === "subagent_resume";
|
||||
if (!isLaunch || call.status === "running") return undefined;
|
||||
const details = typeof call.result === "object" ? call.result?.details : null;
|
||||
const single = Run.safeParse(details);
|
||||
let runs: z.infer<typeof Run>[];
|
||||
if (single.success) {
|
||||
runs = [single.data];
|
||||
} else {
|
||||
const batch = Batch.safeParse(details);
|
||||
if (!batch.success) return undefined;
|
||||
runs = batch.data.children;
|
||||
}
|
||||
const args = Args.safeParse(call.args);
|
||||
const description = args.success ? args.data.task : undefined;
|
||||
const subagents: ProviderSubagentInputEvent[] = [];
|
||||
const childSessions: PiChildSessionFile[] = [];
|
||||
for (const [index, run] of runs.entries()) {
|
||||
const id = runs.length === 1 ? call.callId : `${call.callId}:${index}`;
|
||||
const completion = completions.get(run.id);
|
||||
const status = completion?.status ?? run.status;
|
||||
callsByRun.set(run.id, id);
|
||||
subagents.push({
|
||||
type: "upsert",
|
||||
id,
|
||||
title: run.agent ?? run.name,
|
||||
description: run.task ?? description,
|
||||
toolCallId: call.callId,
|
||||
status: childStatus(status),
|
||||
...(status === "pinged" ? { subtitle: "Needs help" } : {}),
|
||||
});
|
||||
childSessions.push(...childSession(id, completion?.sessionFile ?? run.sessionFile));
|
||||
}
|
||||
return {
|
||||
detail: {
|
||||
type: "sub_agent",
|
||||
description,
|
||||
log: extractTextFromToolResult(call.result)?.trim() ?? "",
|
||||
},
|
||||
subagents,
|
||||
childSessions,
|
||||
};
|
||||
},
|
||||
mapCustomMessage(message) {
|
||||
if (message.customType === "subagent_ping") {
|
||||
const ping = Ping.safeParse(message.details);
|
||||
return ping.success ? completeRun({ ...ping.data, status: "pinged" }) : undefined;
|
||||
}
|
||||
if (message.customType !== "subagent_result") return undefined;
|
||||
const parsed = Completion.safeParse(message.details);
|
||||
return parsed.success ? completeRun(parsed.data) : undefined;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
import { piAskUser } from "./pi-ask-user/index.js";
|
||||
import { piSubagents } from "./pi-subagents/index.js";
|
||||
import { edxethPiSubagents } from "./edxeth-pi-subagents/index.js";
|
||||
import { piMcpAdapter } from "./pi-mcp-adapter/index.js";
|
||||
import { rpivTodo } from "./rpiv-todo/index.js";
|
||||
import { piExampleTodo } from "./pi-example-todo/index.js";
|
||||
@@ -10,6 +11,7 @@ import { rpivAskUserQuestion } from "./rpiv-ask-user-question/index.js";
|
||||
|
||||
export const piExtensions = [
|
||||
piAskUser, // Dialog correlation
|
||||
edxethPiSubagents, // Structured results before the generic subagent tool matcher
|
||||
piSubagents, // Delegation calls
|
||||
tintinwebPiSubagents,
|
||||
gotgenesPiSubagents,
|
||||
|
||||
Reference in New Issue
Block a user