@earendil-works/pi-coding-agent 0.87.0 → 0.87.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +25 -711
- package/dist/bundle/chunks/{anthropic-messages-MYU5ZMRF.js → anthropic-messages-J5WXPPPC.js} +1 -1
- package/dist/bundle/chunks/{chunk-GV2E3GBU.js → chunk-65HAU2C5.js} +1 -1
- package/dist/bundle/chunks/{chunk-4DKZACXI.js → chunk-OJP47DM6.js} +13 -13
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{openai-completions-XHML6MTL.js → openai-completions-OBX42CLD.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-BNWPZYDH.js → virtual-modules-VHMJYYWQ.js} +1 -1
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +14 -4
- package/dist/cli/args.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +9 -9
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/docs/cli-integration.md +106 -0
- package/docs/cli.md +268 -0
- package/docs/compaction.md +22 -22
- package/docs/configuration.md +45 -0
- package/docs/containerization.md +109 -82
- package/docs/custom-provider.md +132 -784
- package/docs/docs.json +139 -99
- package/docs/environment-variables.md +3 -5
- package/docs/extensions.md +134 -3020
- package/docs/how-pi-works.md +49 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/index.md +24 -69
- package/docs/json.md +193 -65
- package/docs/keybindings.md +57 -102
- package/docs/llama-cpp.md +3 -3
- package/docs/message-types.md +261 -0
- package/docs/models.md +55 -565
- package/docs/packages.md +66 -167
- package/docs/prompt-templates.md +31 -68
- package/docs/providers.md +102 -240
- package/docs/quickstart.md +61 -106
- package/docs/rpc-commands.md +854 -0
- package/docs/rpc-extension-ui.md +200 -0
- package/docs/rpc.md +129 -1556
- package/docs/sdk.md +76 -1171
- package/docs/security.md +70 -32
- package/docs/session-format.md +10 -214
- package/docs/sessions.md +35 -141
- package/docs/settings.md +109 -387
- package/docs/shell-aliases.md +85 -5
- package/docs/skills.md +51 -190
- package/docs/slash-commands.md +60 -0
- package/docs/terminal-setup.md +105 -78
- package/docs/termux.md +74 -83
- package/docs/themes.md +68 -280
- package/docs/tmux.md +31 -39
- package/docs/tui.md +69 -923
- package/docs/usage.md +54 -272
- package/docs/windows.md +43 -17
- package/examples/README.md +13 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-client.ts +35 -0
- package/examples/rpc-extension-ui.ts +25 -5
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +20 -20
- package/package.json +8 -8
- package/docs/development.md +0 -90
package/docs/compaction.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Compaction
|
|
1
|
+
# Compaction Reference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This reference describes automatic compaction, branch summarization, persisted entries, and extension hooks. For the user workflow, see [Sessions and Context](sessions.md#manage-conversation-context).
|
|
4
4
|
|
|
5
5
|
**Source files** ([pi](https://github.com/earendil-works/pi)):
|
|
6
6
|
- [`packages/coding-agent/src/core/compaction/compaction.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) - Auto-compaction logic
|
|
@@ -20,7 +20,7 @@ Pi has two summarization mechanisms:
|
|
|
20
20
|
| Compaction | Context exceeds threshold, or `/compact` | Summarize old messages to free up context |
|
|
21
21
|
| Branch summarization | `/tree` navigation | Preserve context when switching branches |
|
|
22
22
|
|
|
23
|
-
Both use
|
|
23
|
+
Both use closely related structured formats and track file operations cumulatively. Summarization requests disable prompt-cache writes because these one-off prompts are unlikely to be reused.
|
|
24
24
|
|
|
25
25
|
## Compaction
|
|
26
26
|
|
|
@@ -97,14 +97,14 @@ persist final assistant response
|
|
|
97
97
|
|
|
98
98
|
If recovery compaction fails or is cancelled, Pi keeps the omission edits, appends no compaction, and schedules no internal retry. Existing queued work remains governed by ordinary steering and follow-up rules. `agent_before_settle` sees the repaired projection after recovery processing. Raw transcript history, exports, billing totals, and history-search extensions can still inspect the omitted attempt.
|
|
99
99
|
|
|
100
|
-
### Split
|
|
100
|
+
### Split user-message spans
|
|
101
101
|
|
|
102
|
-
A
|
|
102
|
+
A user-message span starts with a user message and includes all turns until the next user message. Normally, compaction cuts at user-message boundaries.
|
|
103
103
|
|
|
104
|
-
When
|
|
104
|
+
When one user-message span exceeds `keepRecentTokens`, the cut point lands within that span at an assistant message. This is a split user-message span:
|
|
105
105
|
|
|
106
106
|
```
|
|
107
|
-
Split
|
|
107
|
+
Split user-message span (one span exceeds budget):
|
|
108
108
|
|
|
109
109
|
entry: 0 1 2 3 4 5 6 7 8
|
|
110
110
|
┌─────┬─────┬─────┬──────┬─────┬──────┬──────┬─────┬──────┐
|
|
@@ -117,13 +117,13 @@ Split turn (one huge turn exceeds budget):
|
|
|
117
117
|
└── kept (7-8)
|
|
118
118
|
|
|
119
119
|
isSplitTurn = true
|
|
120
|
-
messagesToSummarize = [] (no
|
|
120
|
+
messagesToSummarize = [] (no earlier user-message spans)
|
|
121
121
|
turnPrefixMessages = [usr, ass, tool, ass, tool, tool]
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
For split
|
|
124
|
+
For split user-message spans, Pi generates two summaries and merges them:
|
|
125
125
|
1. **History summary**: Previous context (if any)
|
|
126
|
-
2. **
|
|
126
|
+
2. **User-message-span prefix summary**: The early part of the split user-message span
|
|
127
127
|
|
|
128
128
|
### Cut Point Rules
|
|
129
129
|
|
|
@@ -145,8 +145,8 @@ Defined in [`session-manager.ts`](https://github.com/earendil-works/pi/blob/main
|
|
|
145
145
|
interface CompactionEntry<T = unknown> {
|
|
146
146
|
type: "compaction";
|
|
147
147
|
id: string;
|
|
148
|
-
parentId: string;
|
|
149
|
-
timestamp:
|
|
148
|
+
parentId: string | null;
|
|
149
|
+
timestamp: string;
|
|
150
150
|
summary: string;
|
|
151
151
|
firstKeptEntryId: string;
|
|
152
152
|
tokensBefore: number;
|
|
@@ -199,11 +199,9 @@ After navigation with summary:
|
|
|
199
199
|
|
|
200
200
|
### Cumulative File Tracking
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
- Tool calls in the messages being summarized
|
|
204
|
-
- Previous compaction or branch summary `details` (if any)
|
|
202
|
+
Default compaction and branch summarization track files cumulatively. Both extract file operations from tool calls in the messages being summarized. Compaction also carries file lists from the previous Pi-generated compaction. Branch summarization carries file lists from Pi-generated branch summaries in the entries it summarizes.
|
|
205
203
|
|
|
206
|
-
|
|
204
|
+
File tracking therefore accumulates across default compactions and nested default branch summaries. Pi does not automatically carry file lists from extension-generated summaries whose `fromHook` field is `true`; extensions manage their own `details` format.
|
|
207
205
|
|
|
208
206
|
### BranchSummaryEntry Structure
|
|
209
207
|
|
|
@@ -213,8 +211,8 @@ Defined in [`session-manager.ts`](https://github.com/earendil-works/pi/blob/main
|
|
|
213
211
|
interface BranchSummaryEntry<T = unknown> {
|
|
214
212
|
type: "branch_summary";
|
|
215
213
|
id: string;
|
|
216
|
-
parentId: string;
|
|
217
|
-
timestamp:
|
|
214
|
+
parentId: string | null;
|
|
215
|
+
timestamp: string;
|
|
218
216
|
summary: string;
|
|
219
217
|
fromId: string; // Entry we navigated from
|
|
220
218
|
usage?: Usage; // LLM usage that generated the summary
|
|
@@ -235,7 +233,9 @@ See [`collectEntriesForBranchSummary()`](https://github.com/earendil-works/pi/bl
|
|
|
235
233
|
|
|
236
234
|
## Summary Format
|
|
237
235
|
|
|
238
|
-
Both
|
|
236
|
+
Both formats include Goal, Constraints & Preferences, Progress, Key Decisions, and Next Steps. Compaction summaries also include Critical Context. Branch summaries stop after Next Steps. Pi appends file lists to either format when relevant.
|
|
237
|
+
|
|
238
|
+
Compaction summaries use this format:
|
|
239
239
|
|
|
240
240
|
```markdown
|
|
241
241
|
## Goal
|
|
@@ -302,7 +302,7 @@ pi.on("session_before_compact", async (event, ctx) => {
|
|
|
302
302
|
const { preparation, branchEntries, customInstructions, reason, willRetry, signal } = event;
|
|
303
303
|
|
|
304
304
|
// preparation.messagesToSummarize - messages to summarize
|
|
305
|
-
// preparation.turnPrefixMessages -
|
|
305
|
+
// preparation.turnPrefixMessages - user-message-span prefix (if isSplitTurn)
|
|
306
306
|
// preparation.previousSummary - previous compaction summary
|
|
307
307
|
// preparation.fileOps - extracted file operations
|
|
308
308
|
// preparation.tokensBefore - context tokens before compaction
|
|
@@ -376,7 +376,7 @@ pi.on("session_compact_failed", async (event, ctx) => {
|
|
|
376
376
|
const { reason, errorMessage, aborted, willRetry, fromExtension } = event;
|
|
377
377
|
// reason - "manual" (/compact), "threshold", or "overflow"
|
|
378
378
|
// errorMessage - present for non-abort failures
|
|
379
|
-
// aborted - true for
|
|
379
|
+
// aborted - true for canceled/aborted compactions
|
|
380
380
|
// willRetry - whether the aborted turn would have retried after compaction
|
|
381
381
|
// fromExtension - whether extension-provided compaction content was being used
|
|
382
382
|
});
|
|
@@ -460,4 +460,4 @@ Keys are exact, case-sensitive `provider/modelId` values, including any slashes
|
|
|
460
460
|
|
|
461
461
|
These resolved values are used for manual compaction, all automatic threshold checks, overflow recovery, and extension-visible `preparation.settings`. Model switches affect subsequent checks and compactions without changing ordinary settings. Compaction already in progress uses the model and settings captured for that operation. Branch summarization settings are unaffected.
|
|
462
462
|
|
|
463
|
-
Overrides work in both global and project settings. The files merge recursively before lookup, so a global model-specific value beats a project-wide fallback; a project must override that model entry to change it. See [
|
|
463
|
+
Overrides work in both global and project settings. The files merge recursively before lookup, so a global model-specific value beats a project-wide fallback; a project must override that model entry to change it. See [Settings](settings.md#per-model-compaction-overrides) for details.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Pi supports user-level and project configuration. User-level configuration lives in the agent directory, which defaults to `~/.pi/agent`. Project configuration lives in `.pi` under the working directory and loads after [project trust](security.md#understand-project-trust) is granted. The only exception is `sessionDir`, which Pi reads before resolving trust so it can locate sessions.
|
|
4
|
+
|
|
5
|
+
In interactive mode, use `/settings` to change common preferences. For other options, ask Pi to update the configuration or edit the relevant files directly. Run `/reload` after manually changing settings, keybindings, instructions, or resources.
|
|
6
|
+
|
|
7
|
+
## Agent directory
|
|
8
|
+
|
|
9
|
+
The agent directory is shown as `<agent-dir>` below. Set its location with the `PI_CODING_AGENT_DIR` environment variable or the SDK's [`agentDir`](sdk.md) option.
|
|
10
|
+
|
|
11
|
+
| Path | Responsibility |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `<agent-dir>/settings.json` | User-level [settings](settings.md), including preferences, defaults, resource paths, and Pi package declarations. |
|
|
14
|
+
| `<agent-dir>/keybindings.json` | Custom terminal UI and application [keybindings](keybindings.md). |
|
|
15
|
+
| `<agent-dir>/models.json` | [Compatible endpoints, models, and model overrides](models.md#configure-a-compatible-endpoint). |
|
|
16
|
+
| `<agent-dir>/auth.json` | Saved API keys and OAuth credentials. |
|
|
17
|
+
| `<agent-dir>/AGENTS.override.md`, `AGENTS.md`, `AGENTS.MD`, `CLAUDE.md`, or `CLAUDE.MD` | User instructions applied across working directories. |
|
|
18
|
+
| `<agent-dir>/SYSTEM.md` | Replaces Pi’s default system prompt. |
|
|
19
|
+
| `<agent-dir>/APPEND_SYSTEM.md` | Adds instructions to Pi’s system prompt. |
|
|
20
|
+
| `<agent-dir>/extensions/` | User [extensions](extensions.md). |
|
|
21
|
+
| `<agent-dir>/skills/` | User [skills](skills.md) and supporting files. |
|
|
22
|
+
| `<agent-dir>/prompts/` | User [prompt templates](prompt-templates.md) exposed as slash commands. |
|
|
23
|
+
| `<agent-dir>/themes/` | User [theme](themes.md) files. |
|
|
24
|
+
|
|
25
|
+
## Project `.pi` directory
|
|
26
|
+
|
|
27
|
+
| Path | Responsibility |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `.pi/settings.json` | Project-level [settings](settings.md), resource paths, and Pi package declarations. |
|
|
30
|
+
| `.pi/SYSTEM.md` | Replaces the system prompt for the project. |
|
|
31
|
+
| `.pi/APPEND_SYSTEM.md` | Adds project-specific instructions to the system prompt. |
|
|
32
|
+
| `.pi/extensions/` | Project extensions. |
|
|
33
|
+
| `.pi/skills/` | Project skills and supporting files. |
|
|
34
|
+
| `.pi/prompts/` | Project prompt templates exposed as slash commands. |
|
|
35
|
+
| `.pi/themes/` | Project theme files. |
|
|
36
|
+
|
|
37
|
+
For `SYSTEM.md` and `APPEND_SYSTEM.md`, the trusted project file takes precedence over the corresponding agent-directory file. Files with the same name are not combined.
|
|
38
|
+
|
|
39
|
+
## Context files
|
|
40
|
+
|
|
41
|
+
Context files are separate from project `.pi` configuration. Pi loads them from the agent directory, the working directory, and its parent directories. A context file applies whenever Pi runs in its directory or anywhere below it.
|
|
42
|
+
|
|
43
|
+
An `AGENTS.override.md` replaces `AGENTS.md` or `CLAUDE.md` only in the same directory. It does not suppress context files from the agent directory or other directories.
|
|
44
|
+
|
|
45
|
+
Context-file discovery does not require project trust.
|
package/docs/containerization.md
CHANGED
|
@@ -1,53 +1,39 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Run Pi in an isolated environment
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use an isolated environment to limit the files, credentials, processes, and network services that generated commands can access or affect.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
1. run the whole `pi` process inside an isolated environment, or
|
|
7
|
-
2. run `pi` on the host and route tool execution into an isolated environment.
|
|
5
|
+
You can isolate the complete Pi process or keep Pi on the host and route selected tools into an isolated environment.
|
|
8
6
|
|
|
9
|
-
## Choose
|
|
7
|
+
## Choose an isolation method
|
|
10
8
|
|
|
11
|
-
|
|
|
12
|
-
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
| OpenShell |
|
|
16
|
-
|
|
|
9
|
+
| Method | Where Pi runs | What is isolated | Credential handling | Best for |
|
|
10
|
+
|---|---|---|---|---|
|
|
11
|
+
| Plain Docker | Container | Pi, built-in tools, `!` commands, and extensions | Credentials passed into the container | A straightforward local container boundary |
|
|
12
|
+
| Docker Sandboxes | Managed sandbox | Pi, built-in tools, `!` commands, and extensions | Provider credentials remain on the host and are substituted by the proxy | Managed local isolation without exposing the real provider key |
|
|
13
|
+
| OpenShell | Local or remote sandbox | Pi, built-in tools, `!` commands, and extensions | Policy-controlled credentials and inference routing | Filesystem, process, network, and credential policies |
|
|
14
|
+
| Gondolin extension | Host | Built-in tools and `!` commands | Stored Pi credentials remain on the host, but commands inherit host environment variables | A local micro-VM for tool execution while retaining the host interface |
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
The method changes where extensions run. When the complete Pi process runs inside an isolated environment, its extensions run there too. When host Pi delegates built-in tools through Gondolin, other extension tools still run on the host unless they also delegate their work.
|
|
19
17
|
|
|
20
|
-
##
|
|
18
|
+
## Decide what Pi can access
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
Use the [example extension](../examples/extensions/gondolin) when you want `pi` on the host but all built-in tools routed into the VM.
|
|
20
|
+
An isolated process can still affect resources you expose to it:
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
- A read-write host mount lets Pi modify those host files.
|
|
23
|
+
- Mounting `~/.pi/agent` exposes your Pi credentials, settings, extensions, and sessions.
|
|
24
|
+
- Environment variables passed into a container are available to processes inside it.
|
|
25
|
+
- Network access may allow code or tool output to leave the environment.
|
|
26
|
+
- Tool-only isolation does not constrain the host Pi process or extension tools that do not use the isolated backend.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
cp -R packages/coding-agent/examples/extensions/gondolin ~/.pi/agent/extensions/gondolin
|
|
29
|
-
cd ~/.pi/agent/extensions/gondolin
|
|
30
|
-
npm install --ignore-scripts
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Run from the project you want mounted:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
cd /path/to/project
|
|
37
|
-
pi -e ~/.pi/agent/extensions/gondolin
|
|
38
|
-
```
|
|
28
|
+
Expose only the working folder, credentials, and network destinations needed for the task. Use read-only mounts or copy files into and out of the environment when you do not want writes to affect the host.
|
|
39
29
|
|
|
40
|
-
|
|
41
|
-
User `!` commands are routed into the VM, as well.
|
|
42
|
-
File changes under `/workspace` write through to the host.
|
|
30
|
+
## Run Pi in plain Docker
|
|
43
31
|
|
|
44
|
-
|
|
32
|
+
Plain Docker provides the simplest whole-process container boundary.
|
|
45
33
|
|
|
46
|
-
|
|
34
|
+
### Build the image
|
|
47
35
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
`Dockerfile.pi`:
|
|
36
|
+
Create `Dockerfile.pi`:
|
|
51
37
|
|
|
52
38
|
```dockerfile
|
|
53
39
|
FROM node:24-bookworm-slim
|
|
@@ -61,11 +47,17 @@ WORKDIR /workspace
|
|
|
61
47
|
ENTRYPOINT ["pi"]
|
|
62
48
|
```
|
|
63
49
|
|
|
64
|
-
Build
|
|
50
|
+
Build it from the directory containing the file:
|
|
65
51
|
|
|
66
52
|
```bash
|
|
67
53
|
docker build -t pi-sandbox -f Dockerfile.pi .
|
|
54
|
+
```
|
|
68
55
|
|
|
56
|
+
### Start Pi
|
|
57
|
+
|
|
58
|
+
From the working folder you want Pi to access, run:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
69
61
|
docker run --rm -it \
|
|
70
62
|
-e ANTHROPIC_API_KEY \
|
|
71
63
|
-v "$PWD:/workspace" \
|
|
@@ -73,84 +65,119 @@ docker run --rm -it \
|
|
|
73
65
|
pi-sandbox
|
|
74
66
|
```
|
|
75
67
|
|
|
76
|
-
|
|
68
|
+
Replace `ANTHROPIC_API_KEY` with the credential required by your provider. The named `pi-agent-home` volume keeps container-local settings, credentials, and sessions between runs.
|
|
69
|
+
|
|
70
|
+
Do not mount the host's `~/.pi/agent` unless the container should have access to your host Pi configuration and credentials.
|
|
71
|
+
|
|
72
|
+
### Verify the workspace
|
|
73
|
+
|
|
74
|
+
Inside Pi, run:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
!pwd
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The command should report `/workspace`. Changes under `/workspace` write through to the mounted host folder. Remove the bind mount or use a read-only mount when that is not acceptable.
|
|
81
|
+
|
|
82
|
+
## Run Pi with Docker Sandboxes
|
|
77
83
|
|
|
78
|
-
|
|
84
|
+
[Docker Sandboxes](https://docs.docker.com/ai/sandboxes/) runs the complete Pi process inside a managed sandbox. Its proxy can keep the real provider credential on the host and substitute it when requests leave the sandbox.
|
|
79
85
|
|
|
80
|
-
|
|
86
|
+
Configure credentials before creating the sandbox. Do not run `/login` inside the sandbox because that writes a real credential into it.
|
|
81
87
|
|
|
82
|
-
Use
|
|
83
|
-
OpenShell can run sandboxes through a local gateway backed by Docker, Podman, or a VM runtime, or through a remote Kubernetes gateway.
|
|
88
|
+
### Use a Claude Pro or Max token
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
Register and select one before creating a sandbox:
|
|
90
|
+
Generate the token with `claude setup-token` on a machine with Claude Code. If an `anthropic` secret is already configured, remove it first so the proxy does not add an API-key header alongside the bearer token:
|
|
87
91
|
|
|
88
92
|
```bash
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
sbx secret rm anthropic
|
|
94
|
+
|
|
95
|
+
sbx secret set-custom \
|
|
96
|
+
--host api.anthropic.com \
|
|
97
|
+
--env ANTHROPIC_OAUTH_TOKEN \
|
|
98
|
+
--placeholder 'sk-ant-oat01-{rand}'
|
|
91
99
|
```
|
|
92
100
|
|
|
93
|
-
|
|
101
|
+
`sbx secret set-custom` reads the real token from standard input. The sandbox receives an OAuth-shaped placeholder, which the proxy replaces only for requests to the configured host.
|
|
102
|
+
|
|
103
|
+
For an Anthropic API key, use `sbx secret set anthropic` instead.
|
|
104
|
+
|
|
105
|
+
### Start Pi
|
|
106
|
+
|
|
107
|
+
Run this from the working folder you want mounted:
|
|
94
108
|
|
|
95
109
|
```bash
|
|
96
|
-
|
|
110
|
+
sbx run --kit "docker.io/sbx/pi-kit:latest" pi
|
|
97
111
|
```
|
|
98
112
|
|
|
99
|
-
|
|
100
|
-
Built-in tools, `!` commands, and extension tools execute inside the OpenShell boundary.
|
|
101
|
-
|
|
102
|
-
If the gateway is remote, project files are not bind-mounted from the host, meaning writes in the sandbox are not reflected on your machine.
|
|
103
|
-
Clone the repository inside the sandbox or use OpenShell file transfer commands:
|
|
113
|
+
For an existing sandbox, run Pi non-interactively with:
|
|
104
114
|
|
|
105
115
|
```bash
|
|
106
|
-
|
|
107
|
-
openshell sandbox download pi-sandbox /workspace/repo ./repo-out
|
|
116
|
+
sbx exec <sandbox-name> -- pi -p "list the failing tests"
|
|
108
117
|
```
|
|
109
118
|
|
|
110
|
-
|
|
111
|
-
When inference routing is configured, code inside the sandbox can call `https://inference.local`, and the gateway injects the configured provider credentials upstream.
|
|
112
|
-
Configure Pi to use the corresponding OpenAI-compatible or Anthropic-compatible endpoint if you want model traffic to use this route.
|
|
119
|
+
See the [Pi kit documentation](https://github.com/docker/sbx-kits-contrib/tree/main/pi) for other providers, troubleshooting, and image pinning.
|
|
113
120
|
|
|
114
|
-
##
|
|
121
|
+
## Run Pi with OpenShell
|
|
115
122
|
|
|
116
|
-
[
|
|
117
|
-
It is one of the container boundaries [No Built-in Sandbox](security.md#no-built-in-sandbox) points to.
|
|
123
|
+
[NVIDIA OpenShell](https://docs.nvidia.com/openshell/about/overview) provides local or remote sandboxes with filesystem, process, network, credential, and inference policies.
|
|
118
124
|
|
|
119
|
-
|
|
120
|
-
The sandbox receives a sentinel value instead, and the `sbx` proxy substitutes the real credential on egress to `api.anthropic.com`.
|
|
121
|
-
Credentials are wired at creation time, so store yours on the host before you create the sandbox.
|
|
125
|
+
### Select a gateway
|
|
122
126
|
|
|
123
|
-
|
|
124
|
-
If an `anthropic` secret is already bound, remove it first: otherwise the proxy adds an `x-api-key` header alongside the Bearer token and Anthropic rejects the request.
|
|
125
|
-
`sbx secret set-custom` reads the token from stdin, so it stays out of shell history.
|
|
127
|
+
Every sandbox requires an active gateway:
|
|
126
128
|
|
|
127
129
|
```bash
|
|
128
|
-
|
|
130
|
+
openshell gateway add <gateway-url> --name <name>
|
|
131
|
+
openshell gateway select <name>
|
|
132
|
+
```
|
|
129
133
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
### Create the sandbox
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
openshell sandbox create --name pi-sandbox --from pi -- pi
|
|
134
138
|
```
|
|
135
139
|
|
|
136
|
-
|
|
140
|
+
Pi, its built-in tools, `!` commands, and extension tools run inside the OpenShell boundary.
|
|
137
141
|
|
|
138
|
-
|
|
142
|
+
### Transfer files to a remote sandbox
|
|
139
143
|
|
|
140
|
-
|
|
144
|
+
A remote gateway does not bind-mount your host working folder. Clone the repository inside the sandbox or transfer files explicitly:
|
|
141
145
|
|
|
142
146
|
```bash
|
|
143
|
-
|
|
147
|
+
openshell sandbox upload pi-sandbox ./working-folder /workspace
|
|
148
|
+
openshell sandbox download pi-sandbox /workspace/working-folder ./working-folder-out
|
|
144
149
|
```
|
|
145
150
|
|
|
146
|
-
|
|
151
|
+
OpenShell inference routing can keep raw model credentials outside the sandbox. When configured, point Pi at the corresponding OpenAI-compatible or Anthropic-compatible endpoint exposed by the gateway.
|
|
152
|
+
|
|
153
|
+
## Route tools through Gondolin
|
|
154
|
+
|
|
155
|
+
[Gondolin](https://github.com/earendil-works/gondolin) is a local Linux micro-VM. Its example extension keeps the Pi process and file-based provider credentials on the host while routing the built-in tools and user `!` commands into the VM.
|
|
156
|
+
|
|
157
|
+
Commands inside the VM inherit the host process environment. Provider keys supplied through environment variables can therefore be visible inside the VM. Do not use this pattern as a credential boundary unless you remove sensitive variables or change the extension's environment handling.
|
|
147
158
|
|
|
148
|
-
|
|
159
|
+
Gondolin requires Node.js 23.6 or newer and QEMU installed through your operating-system package manager.
|
|
149
160
|
|
|
150
|
-
|
|
161
|
+
### Install the extension
|
|
162
|
+
|
|
163
|
+
From a Pi source checkout:
|
|
151
164
|
|
|
152
165
|
```bash
|
|
153
|
-
|
|
166
|
+
mkdir -p ~/.pi/agent/extensions
|
|
167
|
+
cp -R packages/coding-agent/examples/extensions/gondolin ~/.pi/agent/extensions/gondolin
|
|
168
|
+
cd ~/.pi/agent/extensions/gondolin
|
|
169
|
+
npm install --ignore-scripts
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Start Pi
|
|
173
|
+
|
|
174
|
+
Run Pi from the working folder you want mounted:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
cd /path/to/working-folder
|
|
178
|
+
pi -e ~/.pi/agent/extensions/gondolin
|
|
154
179
|
```
|
|
155
180
|
|
|
156
|
-
|
|
181
|
+
The extension mounts the host working folder at `/workspace` in the VM and overrides `read`, `write`, `edit`, `bash`, `grep`, `find`, and `ls`. File changes under `/workspace` write through to the host.
|
|
182
|
+
|
|
183
|
+
Other extension tools still run on the host unless they explicitly delegate their operations. Review the [Gondolin example](../examples/extensions/gondolin/) before adding tools that could bypass the VM boundary.
|