feat: inject dependency results into cascade prompts and forward model option#7
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses subagent RPC robustness and task-execution ergonomics in pi-tasks, primarily to fix Issue #6 (spawn failures due to RPC envelope mismatches and ping handling), and to improve cascading execution by forwarding prerequisite outputs and model overrides.
Changes:
- Make
rpcCall()accept both{ success, data }envelopes and legacy bare payload replies. - Improve
checkSubagentsVersion()by ignoring malformed ping replies and debouncing concurrent checks. - Enhance cascade execution by injecting dependency results into prompts and forwarding
modelto spawned subagents.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/index.ts
Outdated
| if (!subagentsAvailable) { | ||
| pendingWarning = | ||
| "@tintinweb/pi-subagents is outdated — please update for task execution support."; | ||
| } else if (remoteVersion > PROTOCOL_VERSION) { | ||
| "@tintinweb/pi-subagents did not respond with a compatible RPC envelope. " + | ||
| "Ensure the extension is loaded and up to date."; | ||
| } |
There was a problem hiding this comment.
The timeout warning text no longer matches the existing behavior/tests for legacy handlers that reply with {} (no version). Current tests expect a warning mentioning that pi-subagents is outdated, but this now sets a different message on timeout. Either preserve the previous wording for the legacy/no-version case or update the test expectations + any user-facing docs accordingly.
src/index.ts
Outdated
| @@ -160,8 +184,32 @@ export default function (pi: ExtensionAPI) { | |||
| pi.events.on("subagents:ready", () => checkSubagentsVersion()); | |||
|
|
|||
| /** Build a prompt for a task being executed by a subagent. */ | |||
There was a problem hiding this comment.
There are two consecutive JSDoc headers for buildTaskPrompt (the old single-line one plus the new multi-line one). Please remove the duplicate so the documentation isn’t repeated in generated docs / editor hovers.
| /** Build a prompt for a task being executed by a subagent. */ |
| // Inject completed dependency results so cascaded agents have full context | ||
| if (task.blockedBy && task.blockedBy.length > 0) { | ||
| const depResults: string[] = []; | ||
| for (const depId of task.blockedBy) { | ||
| const dep = store.get(depId); | ||
| if (dep?.metadata?.result) { | ||
| const result = dep.metadata.result.length > 4000 | ||
| ? dep.metadata.result.slice(0, 4000) + "\n\n[... truncated — use TaskGet for full output]" | ||
| : dep.metadata.result; | ||
| depResults.push(`### Task #${depId}: ${dep.subject}\n${result}`); | ||
| } | ||
| } | ||
| if (depResults.length > 0) { | ||
| prompt += `\n\n## Prerequisite task results\n\n${depResults.join("\n\n")}`; | ||
| } |
There was a problem hiding this comment.
New behavior here (injecting prerequisite results into prompts) isn’t covered by the existing integration tests. Please add a test that completes a dependency task with a metadata.result and verifies the cascaded spawn prompt includes the injected prerequisite section (and truncation behavior for long results).
src/index.ts
Outdated
| if (versionCheckInFlight) return; | ||
| versionCheckInFlight = true; | ||
| const requestId = randomUUID(); | ||
| const timer = setTimeout(() => { unsub(); }, 5_000); | ||
| const unsub = pi.events.on(`subagents:rpc:ping:reply:${requestId}`, (raw: unknown) => { | ||
| unsub(); clearTimeout(timer); | ||
| const remoteVersion = (raw as any)?.data?.version as number | undefined; | ||
| if (remoteVersion === undefined) { | ||
| const channel = `subagents:rpc:ping:reply:${requestId}`; | ||
| const timer = setTimeout(() => { | ||
| unsub(); | ||
| versionCheckInFlight = false; | ||
| if (!subagentsAvailable) { | ||
| pendingWarning = | ||
| "@tintinweb/pi-subagents is outdated — please update for task execution support."; | ||
| } else if (remoteVersion > PROTOCOL_VERSION) { | ||
| "@tintinweb/pi-subagents did not respond with a compatible RPC envelope. " + | ||
| "Ensure the extension is loaded and up to date."; | ||
| } | ||
| }, 5_000); |
There was a problem hiding this comment.
versionCheckInFlight prevents subagents:ready from triggering a new ping if an earlier ping is already in-flight (e.g., extension loads after init ping was sent but before the 5s timeout). In that case the ready event is effectively dropped and subagentsAvailable can stay false until another ready event happens. Consider queueing a follow-up check (e.g., versionCheckQueued flag) or restarting the ping when subagents:ready arrives during an in-flight check.
|
please help me double check it @tintinweb. thanks |
…l option - Inject completed dependency results (up to 4KB per dep) into buildTaskPrompt - Forward model option to direct spawn and auto-cascade spawn calls - Add integration tests covering injected prerequisite context and truncation All tests pass.
a47d534 to
c8e75b0
Compare
|
Thanks — I reviewed your issue comment and narrowed the PR accordingly. You were right: the RPC failure was caused by my local environment (multiple handlers / custom bridge), not by The PR now only contains two feature additions that should be useful independently in a clean upstream setup:
I also kept targeted integration tests for the cascade prompt behavior. Current verification:
Sorry again for the initial misattribution. |
Summary
Per issue discussion, I narrowed this PR to keep only the changes that are useful in a clean upstream environment.
The earlier RPC fallback work was solving problems caused by my local multi-handler setup (competing subagent packages + custom bridge), not by
pi-tasksitself, so that part has been removed.Changes kept
1. Cascade data flow
buildTaskPrompt()now injects completed dependency results into cascaded agent prompts.This helps dependent tasks consume prerequisite outputs directly without needing to call
TaskGet.Behavior:
## Prerequisite task resultssection when blocked-by tasks havemetadata.resultTaskGetfor full output2. Model forwarding
Passes
modelfromTaskExecuteparams /cascadeConfigthrough to:TaskExecutespawnsThis makes model selection consistent for both manually launched and cascaded task executions.
Tests
Added integration coverage for:
Verification
npx vitest run→ 148 passing testsnpx tsc --noEmit→ passes