Skip to content

feat(pi-embed): @agentic-kit/pi-embed — one pi embedding for local and cloud runs - #1728

Merged
pyramation merged 6 commits into
mainfrom
feat/pi-embed
Aug 14, 2026
Merged

feat(pi-embed): @agentic-kit/pi-embed — one pi embedding for local and cloud runs#1728
pyramation merged 6 commits into
mainfrom
feat/pi-embed

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Last of the six additive @agentic-kit/* packages: the piece that makes "local run" and "cloud run" a difference in values, not code paths. It composes the four pi extensions from the earlier PRs (#1724 log, #1725 gateway metering, #1726 self-reported metering, #1727 approvals) into one session, so there is exactly one agent loop to reason about.

const embedded = await startRun({
  runId,
  pi,                                        // await import('@earendil-works/pi-coding-agent')
  cwd: workspace,
  log: { store },
  metering: { mode: 'gateway', gatewayUrl, identity, models },
  gate: { policy, approvals },
  extensions: [createDbTools(host)]          // the host's own tools
});
await embedded.close();

A laptop run is the same call with metering: { mode: 'self-report', … } and a file store.

Decisions worth knowing, since they are not obvious from the code:

  • metering is a discriminated union, not two flags. gateway is authoritative (the gateway meters what it proxies); self-report is the own-provider-key lane. Enabling both would double-count the same tokens, so the type makes it unrepresentable.
  • Lanes load before the host's extensions, so a host tool call is already gated and already logged by the time it happens; runId is threaded into every lane that records against a run.
  • pi is injected, not imported. pi is ESM-only ("type": "module", exports with import only), so a static import would make this package un-require-able from its own CJS build — and every host already imports pi dynamically (desktop does it in bootstrap(), before PI_CODING_AGENT_DIR is resolved). PiModule is the three-member slice actually used.
  • Extensions reach pi through a ResourceLoader, not createAgentSession — so startRun builds one (DefaultResourceLoader + the required reload()) and lets a host pass createResourceLoader to layer the lanes onto its own (the desktop harness's loader carries skills/prompts/templates).
  • close() flushes, disposes, then rethrows, and flush() drains the log before usage: a delivery failure never costs the transcript, never leaks the session, and is never swallowed into a clean-looking shutdown.
  • Lane misconfiguration (a gateway URL already ending in /v1, a policy that can ask with nowhere to ask) surfaces at composeRun, not at the first model call or the first sensitive tool.

composeRun is exported on its own for a host that already owns session creation and only wants the ordered extension list plus flush().

No transport, no new server, no second agent loop. Nothing outside agentic/pi-embed/ changes except the CI package matrix and the lockfile importer. 15 tests; pnpm test, pnpm build, pnpm lint and pnpm install --frozen-lockfile all pass locally.

Link to Devin session: https://app.devin.ai/sessions/450ce6d6659c47759c184ae6ec19a2a8
Requested by: @pyramation

A pi extension that drains pi's append-only session into an
@agentic-kit/run-log store — verbatim, in order, same code locally and in
the cloud (only runId and the store differ).

Draining is index-based because the session is append-only; the read
position is keyed to the session header id so a switch/fork re-mirrors and
the store's idempotency absorbs the duplicates. A drain advances only after
a successful append, and store failures are rethrown into pi's dispatch by
default rather than silently dropping entries.
@pyramation pyramation self-assigned this Aug 14, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit e2ba522 into main Aug 14, 2026
37 checks passed
@pyramation
pyramation deleted the feat/pi-embed branch August 14, 2026 05:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant