Skip to content

feat(harness-pi): pass the harness session to extension factories - #23100

Merged
felixarntz merged 3 commits into
vercel:mainfrom
gdaybrice:gdaybrice/pi-extension-session
Oct 14, 2026
Merged

felixarntz merged 3 commits into
vercel:mainfrom
gdaybrice:gdaybrice/pi-extension-session

Conversation

@gdaybrice

@gdaybrice gdaybrice commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Background

An extensionFactories entry received only Pi's ExtensionAPI, so an extension could not reach the sandbox the session runs against or the instructions the caller set for the turn. A Task-style tool that runs a child Pi session against the parent's sandbox with the parent's instructions had no way to get either. #23103 also builds on this: it removes the host copy of the workspace, which leaves session.sandboxSession as the only way an extension can read project files.

Summary

  • Each factory now receives a second argument, PiHarnessExtensionSession: the restricted sandboxSession (the same view the builtin tools use), the sessionWorkDir, and an instructions() getter.
  • Instructions arrive per turn and the factory runs before the first turn, so the getter reads the session's current instructions rather than a value captured at creation.
  • Existing (pi) => void factories stay assignable and keep working unchanged.

End-to-End Verification

Run against the real Pi runtime through HarnessAgent, with a local just-bash sandbox and Claude Haiku 4.5 over the AI Gateway. The same scenario was run on main as the control.

  • Registered an extension factory that records its second argument and ran a turn with instructions containing a token. On main the factory receives nothing. On this branch it receives the session work directory, a sandbox session, and instructions() returns the turn's instructions including the token.

Checklist

  • All commits are signed (PRs with unsigned commits cannot be merged)
  • Tests have been added / updated (for bug fixes / features)
  • Documentation has been added / updated (for bug fixes / features)
  • A patch changeset for relevant packages has been added (for bug fixes / features - run pnpm changeset in the project root)
  • I have reviewed this pull request (self-review)

Related Issues

Split out of #22289.

An `extensionFactories` entry received only Pi's `ExtensionAPI`, so an
extension could not reach the sandbox the session runs against or the
instructions the caller set for the turn. A Task-style tool that runs a
child Pi session against the parent's sandbox with the parent's
instructions had no way to get either.

Each factory now gets a second argument, `PiHarnessExtensionSession`:
the restricted sandbox session (the same view the builtin tools use), the
session work directory, and an `instructions()` getter. Instructions
arrive per turn and the factory runs before the first turn, so a getter
over the session's current instructions is the only shape that stays
correct. A second argument keeps every existing `(pi) => void` factory
assignable; the session wraps each factory in a one-line adapter before
handing the list to Pi's resource loader.
@ai-sdk-factory

Copy link
Copy Markdown
Contributor

Feature review

Outcome: changes-required

Implements feature

Status: partially-implements

The implementation correctly passes a restricted sandbox session, sessionWorkDir, and live instructions() getter to factories, but the required user-facing documentation is incomplete.

Concerns:

  • Update content/providers/02-ai-sdk-harnesses/03-pi.mdx, whose Inline Extensions section still documents only the one-argument factory API. Also correct the README example: it says the example uses all three session fields but never uses session.sandboxSession or demonstrates the described child-session use case.

Side effects

Risk: low

Caller factories are wrapped once per harness session before being passed to Pi; existing extension lifecycle and resource-reload behavior remains unchanged.

Concerns: none.

Performance

Risk: low

The change adds one small adapter closure per configured factory and an O(1) instructions getter, with no material per-turn resource cost.

Concerns: none.

Backwards compatibility

Risk: low

Existing one-argument ExtensionFactory values remain structurally assignable, are exercised by runtime and type tests, and retain their previous invocation behavior.

Concerns: none.

Breaking changes

Risk: none

The public setting is broadened to session-aware factories without removing exports, narrowing accepted inputs, changing defaults, or altering persisted formats; existing factories still compile and run.

Concerns: none.

Architecture

Risk: low

The public session abstraction remains owned by @ai-sdk/harness-pi and reuses the existing getRestrictedSandboxSession boundary; no cross-package src imports or dependency-direction violations were introduced.

Concerns: none.

Change scope

Status: minimal

All seven changed files directly implement, export, test, document, or release-note the extension-session API; no unrelated code or generated artifacts are included.

Concerns: none.

Security

Risk: low

Factories receive toolSafeSandboxSession rather than the network sandbox handle, preventing access to sandbox lifecycle and network-policy operations; documentation continues to identify inline extensions as trusted host code.

Concerns: none.

Testing

Status: appropriate

Tests verify the restricted sandbox and work directory, observe different instructions across two turns, and type-check both plain Pi factories and session-aware factories.

Concerns: none.

Verification

Inspected the full origin/main...HEAD diff and surrounding session lifecycle code. pnpm --filter @ai-sdk/harness-pi test:node passed 270 tests, package type-check and build passed, pnpm type-check:full passed, pnpm check reported no formatting or lint errors, git diff --check passed, and changeset status recognized the patch release.

gdaybrice and others added 2 commits October 13, 2026 16:14
Review found the provider docs page still described one-argument
extension factories, and the README example claimed to use all three
session fields while using two.

The provider page now lists `sandboxSession`, `sessionWorkDir` and
`instructions()` with an example, and both examples run a command in the
session's sandbox so each field appears. The example type-checks against
`createPi`.

`extensionSession` moves above the comment about MCP servers, which it
had been inserted beneath.
@ai-sdk-factory

Copy link
Copy Markdown
Contributor

Feature review

Outcome: approved

Implements feature

Status: fully-implements

Each configured factory is adapted to receive a PiHarnessExtensionSession containing getRestrictedSandboxSession(input.sandboxSession), sessionWorkDir, and a live instructions() closure updated before each turn. The new types are publicly exported, and both provider documentation and the package README document all three fields.

Concerns: none.

Side effects

Risk: low

The change adds one adapter closure per caller-supplied factory while preserving the existing extension runtime, resource-reload behavior, MCP factory handling, and factory ordering.

Concerns: none.

Performance

Risk: low

Runtime overhead is limited to one small closure per extension factory and an O(1) instructions getter; no additional sandbox operations or per-event allocations are introduced.

Concerns: none.

Backwards compatibility

Risk: low

Existing one-argument Pi ExtensionFactory values remain assignable to PiHarnessExtensionFactory and continue to run unchanged, as verified by the type test and existing runtime factory test.

Concerns: none.

Breaking changes

Risk: none

No exports, settings, defaults, errors, persisted formats, or accepted factory inputs are removed or narrowed. The callback contract is extended with a second argument while ordinary one-argument JavaScript and TypeScript callbacks remain valid.

Concerns: none.

Architecture

Risk: low

The session-aware abstraction is owned and exported by @ai-sdk/harness-pi, reuses the established @ai-sdk/harness getRestrictedSandboxSession boundary, and introduces no cross-package src imports or dependency-direction violations.

Concerns: none.

Change scope

Status: minimal

All eight changed files directly provide the implementation, public exports and types, runtime and type tests, user-facing documentation, or the required patch changeset.

Concerns: none.

Security

Risk: low

Factories receive the restricted sandbox surface used by harness tooling rather than the network sandbox's lifecycle and policy-management capabilities; documentation also continues to identify inline extensions as trusted host code.

Concerns: none.

Testing

Status: appropriate

Tests cover the session object, work directory, restricted sandbox result, changing instructions across two turns, single factory initialization, and compatibility with plain Pi factories. README and provider-doc examples demonstrate all three session fields.

Concerns: none.

Verification

Inspected the complete origin/main...HEAD diff, surrounding Pi session lifecycle and resource-reload code, public exports, sandbox restriction helper, and Pi's upstream ExtensionFactory definition. pnpm --filter @ai-sdk/harness-pi test:node passed 301 tests; package type-check and build passed; pnpm type-check:full and pnpm check passed; git diff --check passed; and changeset status recognized @ai-sdk/harness-pi for a patch release.

@felixarntz
felixarntz merged commit d10fa3e into vercel:main Oct 14, 2026
58 of 59 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Published in:

Package Version
ai 7.0.141 github npm
@ai-sdk/alibaba 2.0.67 github npm
@ai-sdk/amazon-bedrock 5.0.116 github npm
@ai-sdk/angular 3.0.141 github npm
@ai-sdk/anthropic 4.0.80 github npm
@ai-sdk/anthropic-aws 2.0.73 github npm
@ai-sdk/assemblyai 3.0.60 github npm
@ai-sdk/azure 4.0.102 github npm
@ai-sdk/baseten 2.1.47 github npm
@ai-sdk/black-forest-labs 2.0.61 github npm
@ai-sdk/bytedance 2.0.63 github npm
@ai-sdk/cartesia 3.0.55 github npm
@ai-sdk/cerebras 3.0.69 github npm
@ai-sdk/code-mode 1.0.98 github npm
@ai-sdk/cohere 4.0.61 github npm
@ai-sdk/deepgram 3.1.31 github npm
@ai-sdk/deepinfra 3.0.69 github npm
@ai-sdk/deepseek 3.0.65 github npm
@ai-sdk/devtools 1.0.44 github npm
@ai-sdk/elevenlabs 3.0.61 github npm
@ai-sdk/fal 3.0.61 github npm
@ai-sdk/fireworks 3.0.72 github npm
@ai-sdk/fish-audio 3.0.38 github npm
@ai-sdk/gateway 4.0.114 github npm
@ai-sdk/gladia 3.0.60 github npm
@ai-sdk/gmicloud 3.0.40 github npm
@ai-sdk/google 4.0.96 github npm
@ai-sdk/google-vertex 5.0.112 github npm
@ai-sdk/groq 4.0.61 github npm
@ai-sdk/harness 1.0.152 github npm
@ai-sdk/harness-acp 1.0.91 github npm
@ai-sdk/harness-claude-code 1.0.156 github npm
@ai-sdk/harness-cline 1.0.79 github npm
@ai-sdk/harness-codex 1.0.154 github npm
@ai-sdk/harness-cursor 1.0.66 github npm
@ai-sdk/harness-deepagents 1.0.152 github npm
@ai-sdk/harness-fx 1.0.66 github npm
@ai-sdk/harness-github-copilot 1.0.48 github npm
@ai-sdk/harness-grok-build 1.0.90 github npm
@ai-sdk/harness-opencode 1.0.154 github npm
@ai-sdk/harness-pi 1.0.154 github npm
@ai-sdk/heygen 3.0.2 github npm
@ai-sdk/huggingface 2.0.69 github npm
@ai-sdk/hume 3.0.60 github npm
@ai-sdk/klingai 4.0.62 github npm
@ai-sdk/langchain 3.0.141 github npm
@ai-sdk/llamaindex 3.0.141 github npm
@ai-sdk/luma 3.0.61 github npm
@ai-sdk/mcp 2.0.75 github npm
@ai-sdk/minimax 3.0.57 github npm
@ai-sdk/mistral 4.0.64 github npm
@ai-sdk/moonshotai 3.0.69 github npm
@ai-sdk/open-responses 2.0.65 github npm
@ai-sdk/openai 4.0.94 github npm
@ai-sdk/openai-compatible 3.0.69 github npm
@ai-sdk/otel 1.0.141 github npm
@ai-sdk/perplexity 5.0.12 github npm
@ai-sdk/policy-opa 1.0.141 github npm
@ai-sdk/prodia 2.0.61 github npm
@ai-sdk/provider-utils 5.0.60 github npm
@ai-sdk/quiverai 2.0.61 github npm
@ai-sdk/react 4.0.144 github npm
@ai-sdk/replicate 3.0.61 github npm
@ai-sdk/revai 3.0.60 github npm
@ai-sdk/rsc 3.0.141 github npm
@ai-sdk/sandbox-just-bash 1.0.152 github npm
@ai-sdk/sandbox-vercel 1.0.152 github npm
@ai-sdk/svelte 5.0.141 github npm
@ai-sdk/togetherai 3.0.70 github npm
@ai-sdk/topaz 3.0.7 github npm
@ai-sdk/tui 1.0.142 github npm
@ai-sdk/typesafe-ai 3.0.19 github npm
@ai-sdk/valibot 3.0.60 github npm
@ai-sdk/voyage 2.0.60 github npm
@ai-sdk/vue 4.0.141 github npm
@ai-sdk/workflow 2.0.73 github npm
@ai-sdk/workflow-harness 1.0.152 github npm
@ai-sdk/xai 5.0.22 github npm
@ai-sdk/zai 3.0.31 github npm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants