githubnext/chopinPublic

Let's compose rich plans together

Return Pi structured output from a terminating extension tool

Replace the Pi wrapper's host result tool with an inline Pi extension,
following Pi's structured-output example. The tool runs inside Pi's own
agent loop and returns terminate: true, so the turn ends on that call
without a host round trip or a follow-up model request. This removes the
setTimeout(0) wait for Pi to register a pending host result.

Each session's extension offers the tool only when the turn's system
prompt carries the structured-result instruction, and blocks it on every
other turn; the wrapper keeps the result tool's parts out of the stream
either way. The output schema moves into the turn's instructions, and
HarnessAgent still validates the parsed result.

Pin @earendil-works/pi-coding-agent 0.85.1 and typebox 1.3.7, the
versions the lockfile already resolved, so the extension imports them
directly.

Assistant-model: Claude Opus 5.5
Assistant-workflow: inline
Assistant-duration: 10m converged, estimated 1-2h
Assistant-verification: Bun Pi contract passed: 6/6 against the real createPi() agent loop and a local model stub
Assistant-verification: Bun Pi contract red check passed: against the previous adapter, a structured turn made 2 model requests instead of 1, and a result-tool call on a plain turn leaked 3 parts into the stream
Assistant-verification: Bun Pi adapter unit passed: 9/9, including the extension gating and blocking with a fake ExtensionAPI
Assistant-verification: bun run ci passed: dprint, oxlint, tokens
Assistant-verification: bun run types passed: all workspaces and E2E
Assistant-verification: bun test passed: 1598 pass, 2 PostgreSQL skips, 0 fail
Assistant-verification: Playwright E2E passed: CI=1 locked bun run e2e with no mise on PATH, 229 passed and 2 flaky that passed on retry (responsive-workspace.e2e.ts:110, :186)
User-preference: Prefer an upstream-supported extension point over working around third-party adapter races
Co-authored-by: Alex Lavaee <lavaman131@github.com>
ALAlex Lavaee authored
28b65efPatch
Parent4b48675
8 files changed+328-130
StackedSplit
apps/server/package.json+2 โˆ’0
apps/server/src/harness/pi.contract.test.ts+63 โˆ’1
apps/server/src/harness/pi/adapter.test.ts+118 โˆ’36
apps/server/src/harness/pi/adapter.ts+101 โˆ’63
apps/server/src/harness/pi/model-stub.ts+13 โˆ’3
bun.lock+21 โˆ’17
docs/self-hosting.md+8 โˆ’10
package.json+2 โˆ’0