refactor(agent): WIP functional runner contracts - #1293
Conversation
…on contracts
runAgent(config, input, {onProgress?, interaction?, signal?}) returns a
RunResult and never rejects. RunConfig and RunInput replace the session
reads, AgentProgress replaces the getUI() calls, an optional AgentInteraction
replaces the getUI() answerer, and every former wizardAbort returns as a
failure with the same fields. An unexpected throw returns as outcome
'crashed' with the original error attached.
Gates, authenticate, token refresh, flag fetch, binding resolution and the
exit move to src/lib/programs/run-agent-legacy.ts, which maps each progress
event to one WizardUI call so every existing caller keeps its output.
authenticate moves to programs unchanged. The allowlist architecture test is
removed; import enforcement lands with the A2 move.
Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
🧙 Wizard CIRun the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands: Test all apps:
Test all apps in a directory:
Test an individual app:
Show more apps
Test against a Context Mill branch:
Add Results will be posted here when complete. |
Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
…the cut Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
Restore detection progress, isolate progress observers, and preserve completion and cleanup ordering. Type run outcomes and share status history handling; cover harness, sequence, and adapter boundaries. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Track pending requests in the ask bridge and pass its accessor to both Anthropic harness paths. This restores the permission guard against Write/Edit calls racing an unanswered wizard_ask request. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Cover delayed answers across both sequences and harness bindings, plus completion when questions are disabled. Production behavior is unchanged. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Self-reviewCurrent head: Open for reviewRun cancellation scope. The incomplete cancellation surface was removed because it never reached active harness execution. The callable currently accepts Architecture ledger. The note on
Verification
Live fixtures asked no questions, so deterministic regressions cover delayed answers and the question/write race. The recorder freezes Evidence index: Addressed historyCompleted fixes and superseded progress updates are preserved below. The cancellation scope decision above remains open. stale 1: initial baseline verification and headless run logOriginal update: 2026-09-21T22:14:19Z. Verified locally on ebee145, not waiting on CI.
Headless run log, 133 linesstale 2: runner contract fixes and earlier validationOriginal update: 2026-09-21T22:57:21Z. Review fixes in
Validation: typecheck, full build/test (188 files, 3,138 tests), lint (zero errors; 482 existing warnings), and CI build pass. No golden files regenerated. Live Pi/orchestrator Express CI snapshots are running; results will follow. Open scope decision: this draft removes the incomplete cancellation surface, which never reached active harness execution. The fuller plan includes end-to-end cancellation in A1′; keeping it deferred versus implementing it here remains pending. The current callable options are stale 3: interim Pi live-run reportOriginal update: 2026-09-21T23:02:47Z. Live CI snapshot run completed on Reviewed the generated diff and separately exercised CRUD/error responses plus real SDK delivery of three lifecycle events to a local receiver; all passed. Created dashboard and setup notebook. Evidence is retained locally at A follow-up is underway for the confirmed pending-question Write/Edit guard regression; this live run predates that fix. stale 4: pending-question Write/Edit guard fixedOriginal update: 2026-09-21T23:07:39Z. Confirmed and fixed the pending-question write guard in The shared ask bridge now exposes pending state synchronously, before invoking the answerer. Both Anthropic execution paths pass that accessor to Regression coverage checks the actual harness initialization callback and permission predicate for answer, cancellation, rejection, timeout, overlapping requests, and absent answerer. Typecheck and scoped lint pass; full build/test passes 189 files / 3,150 tests. Production change is 11 added lines across two files. The PR remains draft. The completed Pi/orchestrator live snapshot evidence is above; an explicit Anthropic/Sonnet linear run is underway. stale 5: completed live verification and earlier CI statusOriginal update: 2026-09-21T23:15:36Z. Final verification on
Both runs exited 0, reached The initial Anthropic attempt inherited an incompatible OpenAI model from the feature-flag binding; its gateway rejection is preserved. The successful rerun explicitly selected Sonnet. The recorder’s first-outro snapshot freezes The Anthropic live run includes the pending-question fix; deterministic regressions cover the question/write race because this fixture needed no questions. Complete evidence index: stale 6: question-wait behavior confirmed and regression-testedOriginal update: 2026-09-21T23:41:22Z. Confirmed existing question-wait behavior against the pre-refactor implementation. No additional production change was needed: the asking agent awaits its answer, independent orchestrator tasks may continue, and disabled questions do not block. Existing timeout behavior is preserved. Added regression coverage in d214216 for delayed answers across both sequence arms and harness bindings, plus disabled questions. These standalone runner tests use the real sequences and ask bridge with a fake harness. The existing harness/tool permission tests also pass. Validation: 195 tests across five focused files passed, plus typecheck, scoped ESLint, and Prettier. This follow-up changes only tests. The PR remains draft. |
Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Keep the diagram as native Mermaid in the PR description. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
|
/wizard-ci basic-integration/next-js |
🧙 Wizard CI ResultsTrigger ID:
Configuration
|
|
/wizard-ci ai-observability |
🧙 Wizard CI ResultsTrigger ID:
Configuration
|
|
☝️ those actually passed but GitHub hella flaky |
| await Promise.race(running.values()); | ||
| } finally { | ||
| // No queue or skill cleanup may run while a sibling still uses them. | ||
| await Promise.allSettled(running.values()); |
There was a problem hiding this comment.
we need to cancel sibling tasks when the first RunTaskFatal is recorded
robot says we can be waiting up to 20min if a task like wizard_ask is still running. we should call interaction.cancelAsk?.() or create a util cancelAll() function that clears stuff before Promise.allSettled
There was a problem hiding this comment.
Fixed in #1303: the first fatal now calls onFatal, which aborts the run controller so running task sessions and open asks cancel before the drain joins them:
wizard/src/agent/runner/sequence/orchestrator/executor.ts
Lines 139 to 155 in 200961f
Brings in the eight main fixes since beccc79 (#1275, #1280, #1284, #1294, #1295, #1301, #1302, #1305). One conflict: agentic detection keeps main's two-attempt retry loop from #1305 and adds A1's progress emitter to the agent it initializes. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
…hutdown to the host
`AgentInteraction.ask` and `taskNotice` now take `{ signal }`, as §4.3 of the
plan specifies. The ask bridge and the seeded-task offer each own one
AbortController per request, and a timeout aborts only that request.
`cancelAsk` and `cancelTaskNotice` are gone. The host adapter dismisses the
overlay when the signal aborts, catches and logs anything the dismissal
throws, and detaches once the request settles.
The agent no longer calls `analytics.shutdown('success')`. The legacy
adapter, the only `runAgent` caller at this layer, sends it after a
non-composed run succeeds. Failure and abort still shut down through
wizardAbort. A long-lived host can now decide when terminal analytics go
out, instead of the first run deciding for it.
Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
…ush fails
After a non-composed success the legacy adapter awaits
analytics.shutdown('success'). posthog-core can reject that on its flush
timeout, and the rejection turned a finished run into a TUI error outro and
exit 1, or into a headless wizardAbort. The adapter now logs the failure and
moves on. There is still exactly one terminal shutdown, because the first
status latches.
Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Brings in #1235 and the 2.77.0 release. One conflict: the seed prompt keeps A1's emitter and takes main's excluded-types note. #1235's orchestrator code read the session and ProgramConfig, which the agent no longer sees, so the program's excludedTaskTypes mapping now arrives on RunConfig, and the drained queue's outcomes go back through a recordTaskOutcomes hook that the legacy adapter writes to frameworkContext for the e2e harness. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Brings in #1319. No conflicts. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Release A landed on main as squash commits (#1293, #1297, #1299, #1303). B1 already carries that content through the A3 branch, so the merge keeps B1's tree and adds #1334, the one change main has beyond A3, with B1 import paths. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Make
runAgentcallable through typed input, result, progress, and interaction contracts while preserving existing runner output and cleanup ordering.flowchart TB subgraph host["run-agent-legacy · temporary adapter"] direction LR rpa["<div style='width:180px'>runProgramAgent</div>"]:::temp reducer["<div style='width:180px'>createUiReducer</div>"]:::new interaction["<div style='width:180px'>uiInteraction</div>"]:::new end subgraph agent["agent · runAgent boundary"] direction TB subgraph runner["<div style='width:180px'>runner</div>"] direction LR run["<div style='width:180px'>runAgent</div>"]:::new collector["<div style='width:180px'>createProgressCollector</div>"]:::new end subgraph sequence["<div style='width:180px'>sequence</div>"] direction LR linear["<div style='width:180px'>runLinearProgram</div>"] orchestrator["<div style='width:180px'>runOrchestrator</div>"] askbridge["<div style='width:180px'>createAskBridge</div>"]:::new end subgraph harness["<div style='width:180px'>harness</div>"] direction LR anthropic["<div style='width:180px'>anthropicBackend</div>"] pi["<div style='width:180px'>piBackend</div>"] end end subgraph tools["wizard-tools MCP"] ask["<div style='width:180px'>wizard_ask</div>"] end rpa -->|"config, input, options"| run run --> linear run --> orchestrator linear --> anthropic orchestrator --> pi anthropic -->|tool call| ask pi -->|tool call| ask run -. RunResult .-> rpa harness -. emit .-> runner runner -. onProgress .-> host tools -. askBridge .-> sequence sequence -.->|"interaction.ask"| host classDef new fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a classDef temp fill:#fef3c7,stroke:#b45309,color:#78350f,stroke-dasharray:5 3 style agent fill:transparent,stroke:#1d4ed8,stroke-width:2px style host stroke:#b45309,stroke-dasharray:5 3Flow is top down. Solid is a call, dotted is a callback or an event, and each dotted edge lands on the tier that owns the receiver.
runAgentowns. Never reads a session, a UI, or a store.runner,sequence,harnessrunAgentcontract,createProgressCollector,createAskBridge,createUiReducer,uiInteractionrunLinearProgram,runOrchestrator,anthropicBackend,piBackend,wizard_askrun-agent-legacyrebuilds today's session-driven behavior on top of the contract, and programs replace it in Release B.runProgramAgentImportant stuff for review
sequence/linear.ts
orchestrator-runner.ts
harness/anthropic/index.ts
harness/pi/index.ts
harness/pi/task.ts
agent-interface.ts
runner/shared/types.ts
run-wizard.ts
run-non-interactive.ts
posthog-integration/index.ts
progress-collector.ts
runner/shared/ask.ts
wizard-ask-bridge.ts
wizard-tools/mcp.ts
harness/pi/tools.ts
ui/wizard-ui.ts
ui/tui/ink-ui.ts
ui/tui/store.ts
Progress is optional and best effort. Questions await the injected answerer, preserving existing timeout and cancellation behavior.
Created with PostHog Desktop