my-durable 0.0.0-stage → 0.0.2
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/.env.example +7 -0
- package/LICENSE +21 -0
- package/README.md +328 -2
- package/ai_docs/durable_pi/announcement.md +860 -0
- package/ai_docs/durable_pi/changelog.md +51 -0
- package/ai_docs/durable_pi/chord-delta-findings.md +362 -0
- package/ai_docs/durable_pi/coding-agent-integration.md +70 -0
- package/ai_docs/durable_pi/pico-v5-chord-usage.md +391 -0
- package/ai_docs/durable_pi/pico-v5-handoff.md +921 -0
- package/ai_docs/durable_pi/readme.md +617 -0
- package/ai_docs/durable_pi/sources.md +22 -0
- package/ai_docs/durable_pi/spec.md +4696 -0
- package/ai_docs/durable_pi/vacation-planner.md +57 -0
- package/ai_docs/pi/chord.md +268 -0
- package/ai_docs/pi/cli-integration.md +110 -0
- package/ai_docs/pi/cli.md +325 -0
- package/ai_docs/pi/codemode.md +211 -0
- package/ai_docs/pi/compaction.md +467 -0
- package/ai_docs/pi/configuration.md +51 -0
- package/ai_docs/pi/containerization.md +187 -0
- package/ai_docs/pi/custom-provider.md +177 -0
- package/ai_docs/pi/environment-variables.md +102 -0
- package/ai_docs/pi/extensions.md +278 -0
- package/ai_docs/pi/how-pi-works.md +53 -0
- package/ai_docs/pi/index.md +43 -0
- package/ai_docs/pi/json.md +230 -0
- package/ai_docs/pi/keybindings.md +198 -0
- package/ai_docs/pi/llama-cpp.md +118 -0
- package/ai_docs/pi/mcp.md +274 -0
- package/ai_docs/pi/message-types.md +265 -0
- package/ai_docs/pi/models.md +209 -0
- package/ai_docs/pi/overview.md +166 -0
- package/ai_docs/pi/packages.md +133 -0
- package/ai_docs/pi/pi-agent-core.md +568 -0
- package/ai_docs/pi/pi-ai.md +1942 -0
- package/ai_docs/pi/prompt-templates.md +63 -0
- package/ai_docs/pi/providers.md +204 -0
- package/ai_docs/pi/quickstart.md +140 -0
- package/ai_docs/pi/readme.md +99 -0
- package/ai_docs/pi/rpc-commands.md +864 -0
- package/ai_docs/pi/rpc-extension-ui.md +204 -0
- package/ai_docs/pi/rpc.md +197 -0
- package/ai_docs/pi/sdk.md +151 -0
- package/ai_docs/pi/security.md +103 -0
- package/ai_docs/pi/session-format.md +297 -0
- package/ai_docs/pi/sessions.md +70 -0
- package/ai_docs/pi/settings.md +173 -0
- package/ai_docs/pi/shell-aliases.md +97 -0
- package/ai_docs/pi/skills.md +97 -0
- package/ai_docs/pi/slash-commands.md +64 -0
- package/ai_docs/pi/sources.md +57 -0
- package/ai_docs/pi/terminal-setup.md +223 -0
- package/ai_docs/pi/termux.md +121 -0
- package/ai_docs/pi/themes.md +140 -0
- package/ai_docs/pi/tmux.md +59 -0
- package/ai_docs/pi/toolkit.md +168 -0
- package/ai_docs/pi/tui.md +129 -0
- package/ai_docs/pi/usage.md +98 -0
- package/ai_docs/pi/virtual-models.md +118 -0
- package/ai_docs/pi/windows.md +71 -0
- package/apps/dpi-backend/.nvmrc +1 -0
- package/apps/dpi-backend/API.md +99 -0
- package/apps/dpi-backend/README.md +119 -0
- package/apps/dpi-backend/deploy/backend.env.example +9 -0
- package/apps/dpi-backend/deploy/dpi-backend.plist +26 -0
- package/apps/dpi-backend/deploy/dpi-backend.service +22 -0
- package/apps/dpi-backend/package.json +33 -0
- package/apps/dpi-backend/prompts/one_sentence.md +3 -0
- package/apps/dpi-backend/prompts/smart_ass_opus_fix.md +169 -0
- package/apps/dpi-backend/scripts/check-contract.mjs +151 -0
- package/apps/dpi-backend/scripts/migrate-playground.ts +66 -0
- package/apps/dpi-backend/scripts/record-nested-fixture.mts +154 -0
- package/apps/dpi-backend/scripts/token.ts +57 -0
- package/apps/dpi-backend/src/addons.ts +139 -0
- package/apps/dpi-backend/src/auth.ts +20 -0
- package/apps/dpi-backend/src/config.ts +54 -0
- package/apps/dpi-backend/src/contract-check.ts +118 -0
- package/apps/dpi-backend/src/errors.ts +50 -0
- package/apps/dpi-backend/src/extensions.ts +510 -0
- package/apps/dpi-backend/src/faux.ts +80 -0
- package/apps/dpi-backend/src/history.ts +165 -0
- package/apps/dpi-backend/src/idempotency.ts +20 -0
- package/apps/dpi-backend/src/jev.ts +43 -0
- package/apps/dpi-backend/src/jobs.ts +790 -0
- package/apps/dpi-backend/src/main.ts +76 -0
- package/apps/dpi-backend/src/model-catalog.ts +180 -0
- package/apps/dpi-backend/src/pairing-files.ts +142 -0
- package/apps/dpi-backend/src/pairing.ts +459 -0
- package/apps/dpi-backend/src/routes.ts +217 -0
- package/apps/dpi-backend/src/shared-state.ts +85 -0
- package/apps/dpi-backend/src/store.ts +1240 -0
- package/apps/dpi-backend/src/streams.ts +256 -0
- package/apps/dpi-backend/src/tunnel.ts +955 -0
- package/apps/dpi-backend/tsconfig.json +13 -0
- package/apps/dpi-playground/README.md +83 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-CFGc7lHT.js +77 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/assets/index-DFdKpwm_.css +1 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/anthropic.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/deepseek.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/durable-pi.svg +14 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/gemini.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/grok.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/kimi.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/lab.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/meta.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/minimax.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/openai.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/qwen.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/xiaomi.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/icons/zai.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/dist/index.html +16 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/index.html +15 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/package.json +5 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/anthropic.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/deepseek.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/durable-pi.svg +14 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/gemini.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/grok.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/kimi.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/lab.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/meta.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/minimax.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/openai.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/qwen.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/xiaomi.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/public/icons/zai.png +0 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/App.vue +180 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/commands.ts +119 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/composables.ts +129 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/hub.ts +40 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/icon-path.ts +7 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/ids.ts +2 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/jobs.ts +80 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/link-policy.ts +16 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/markdown-policy.ts +115 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/markdown.ts +60 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/pair-close.ts +23 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/pair-handoff.ts +56 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/pair.ts +166 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/qrcode.ts +323 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/signature.ts +146 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/store.ts +373 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/client/stream.ts +183 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/AgentView.vue +342 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/Composer.vue +198 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/ContextBar.vue +254 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/DeviceCredentialsDialog.vue +40 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/DeviceIcon.vue +56 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/DirBrowser.vue +95 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/ExtensionsPanel.vue +96 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/HelpDialog.vue +69 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/Inspector.vue +425 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/JobCard.vue +221 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/MobileNav.vue +39 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/ModelPicker.vue +71 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/NetworkSidebar.vue +236 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/NewSessionDialog.vue +114 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/OfflinePanel.vue +128 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/PairDeviceWizard.vue +433 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/PromptDialog.vue +89 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/StateEditor.vue +179 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TasksPanel.vue +280 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/Toast.vue +11 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TokenManager.vue +175 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TopBar.vue +114 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TranscriptItem.vue +152 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TreeRow.vue +195 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/components/TunnelStatusBar.vue +107 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/extensions.css +105 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/jobs.css +655 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/main.ts +22 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/network.css +675 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/src/style.css +3203 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/tsconfig.json +16 -0
- package/apps/dpi-playground/apps/dpi-playground-fe/vite.config.ts +14 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/package.json +5 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/audit.ts +406 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/client-ip.ts +72 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/credentials.ts +265 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/guard.ts +43 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/http-errors.ts +156 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/identity.ts +60 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/limiter.ts +165 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/main.ts +460 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/monitor.ts +320 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/mux.ts +277 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/pairing.ts +816 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/proxy.ts +128 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/rotation.ts +583 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/seed.ts +11 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/transport.ts +108 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/tunnel-token.ts +11 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/tunnel-transport.ts +560 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/src/tunnel.ts +873 -0
- package/apps/dpi-playground/apps/dpi-playground-hub/tsconfig.json +13 -0
- package/apps/dpi-playground/package.json +37 -0
- package/apps/dpi-sdk/README.md +74 -0
- package/apps/dpi-sdk/package.json +20 -0
- package/apps/dpi-sdk/scripts/net.ts +73 -0
- package/apps/dpi-sdk/src/api.ts +631 -0
- package/apps/dpi-sdk/src/app-state.ts +111 -0
- package/apps/dpi-sdk/src/client.ts +330 -0
- package/apps/dpi-sdk/src/errors.ts +16 -0
- package/apps/dpi-sdk/src/jobs.ts +99 -0
- package/apps/dpi-sdk/src/models.ts +472 -0
- package/apps/dpi-sdk/src/node/chunk.ts +488 -0
- package/apps/dpi-sdk/src/node/config.ts +175 -0
- package/apps/dpi-sdk/src/node/drivers.ts +402 -0
- package/apps/dpi-sdk/src/node/ops.ts +114 -0
- package/apps/dpi-sdk/src/node/private-dir.ts +48 -0
- package/apps/dpi-sdk/src/node/registry-migration.ts +549 -0
- package/apps/dpi-sdk/src/node/registry.ts +390 -0
- package/apps/dpi-sdk/src/node/sse-writer.ts +151 -0
- package/apps/dpi-sdk/src/protocol/backoff.ts +31 -0
- package/apps/dpi-sdk/src/protocol/limits.ts +199 -0
- package/apps/dpi-sdk/src/protocol/pairing.ts +311 -0
- package/apps/dpi-sdk/src/protocol/rest-routes.ts +105 -0
- package/apps/dpi-sdk/src/protocol/tunnel.ts +331 -0
- package/apps/dpi-sdk/src/sse.ts +117 -0
- package/apps/dpi-sdk/src/transcript.ts +291 -0
- package/apps/dpi-sdk/tsconfig.json +13 -0
- package/apps/dpi-sdk/w +20 -0
- package/apps/dpi-tui/README.md +54 -0
- package/apps/dpi-tui/bin/dpi-tui.mjs +5 -0
- package/apps/dpi-tui/package.json +20 -0
- package/apps/dpi-tui/src/app.ts +433 -0
- package/apps/dpi-tui/src/commands.ts +151 -0
- package/apps/dpi-tui/src/main.ts +122 -0
- package/apps/dpi-tui/src/pairing.ts +287 -0
- package/apps/dpi-tui/src/pickers.ts +238 -0
- package/apps/dpi-tui/src/render.ts +164 -0
- package/apps/dpi-tui/src/theme.ts +57 -0
- package/apps/dpi-tui/tsconfig.json +14 -0
- package/bin/device.mjs +5 -0
- package/bin/hub.mjs +5 -0
- package/bin/tui.mjs +5 -0
- package/deploy/Caddyfile +120 -0
- package/docs/verification.md +102 -0
- package/dpi-network.example.yaml +62 -0
- package/images/01_durable_agent_network.svg +185 -0
- package/images/02_pi_made_durable.svg +204 -0
- package/images/03_restart_mid_tool.svg +168 -0
- package/images/07_one_api_every_client.svg +123 -0
- package/images/08_device_session_agent.svg +123 -0
- package/images/09_compact_keep_history.svg +143 -0
- package/images/10_shared_app_state.svg +177 -0
- package/images/11_durable_jobs_wait.svg +141 -0
- package/images/12_tools_change_mid_run.svg +231 -0
- package/images/13_hook_blocks_tool.svg +122 -0
- package/images/14_fork_at_any_entry.svg +119 -0
- package/images/15_web_client.png +0 -0
- package/images/16_terminal_client.svg +43 -0
- package/images/17_devices_are_data.svg +182 -0
- package/images/18_should_every_agent_be_durable.svg +118 -0
- package/images/19_sqlite_on_every_device.svg +155 -0
- package/images/20_admission_and_effects.svg +134 -0
- package/justfile +33 -0
- package/package.json +41 -4
- package/scripts/verify.mjs +210 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
> Source: [packages/coding-agent/docs/cli.md](https://github.com/earendil-works/pi/blob/b78e6a9085343ec0f308c3d377da72528b4cf7ee/packages/coding-agent/docs/cli.md)
|
|
2
|
+
> Retrieved with Firecrawl: 2026-10-05. Repository snapshot: `b78e6a9085343ec0f308c3d377da72528b4cf7ee`.
|
|
3
|
+
> Relative documentation links point to local copies where available, otherwise to the source snapshot.
|
|
4
|
+
|
|
5
|
+
<a id="cli-and-modes-reference"></a>
|
|
6
|
+
|
|
7
|
+
# Command Line
|
|
8
|
+
|
|
9
|
+
This page documents Pi's built-in command-line commands and options. Run `pi --help` or append `--help` to a command for the exact interface in your installed version. The top-level help also includes options registered by loaded extensions.
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
pi [options] [--] [@files...] [messages...]
|
|
13
|
+
pi install <source> [options]
|
|
14
|
+
pi remove <source> [options]
|
|
15
|
+
pi uninstall <source> [options]
|
|
16
|
+
pi update [target] [options]
|
|
17
|
+
pi list
|
|
18
|
+
pi config [options]
|
|
19
|
+
pi auth <check|print-api-key|print-bearer-token> [options]
|
|
20
|
+
pi mcp <list|login|logout> [options]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
<a id="modes"></a>
|
|
24
|
+
|
|
25
|
+
## Invocation and output
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pi
|
|
29
|
+
pi --print "Summarize this repository"
|
|
30
|
+
git diff | pi --print "Review this change"
|
|
31
|
+
pi --mode json "Inspect this repository" > events.jsonl
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
With terminal stdin and stdout, Pi opens the terminal UI unless `--print`, `--mode json`, or `--mode rpc` selects another interface. When either stream is redirected and neither JSON nor RPC mode is selected, Pi uses print mode. See [CLI Integration](cli-integration.md) for choosing between interactive, print, JSON, RPC, and SDK integration.
|
|
35
|
+
|
|
36
|
+
| Input | Behavior |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `message` | Provide an initial prompt |
|
|
39
|
+
| `@path` | Include a text file or image in the first prompt |
|
|
40
|
+
| Piped stdin | Prepend its contents to the first prompt |
|
|
41
|
+
| `--` | Stop option parsing so a prompt can begin with `-` |
|
|
42
|
+
|
|
43
|
+
Pi resolves `@path` from the current working directory. The working directory also controls project configuration, resource discovery, and session grouping.
|
|
44
|
+
|
|
45
|
+
`--print` controls whether Pi runs once and exits. `--mode` selects the output interface. `--mode text` does not force one-shot execution when stdin and stdout are terminals; use `--print` for that behavior.
|
|
46
|
+
|
|
47
|
+
| Option | Behavior |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `-p`, `--print` | Run the supplied prompts, write the final assistant text to stdout, then exit |
|
|
50
|
+
| `--mode text` | Select text output; still open the terminal UI when stdin and stdout are terminals |
|
|
51
|
+
| `--mode json` | Run the supplied prompts, write JSONL events to stdout, then exit |
|
|
52
|
+
| `--mode rpc` | Read JSONL commands from stdin and write responses and events to stdout until shutdown |
|
|
53
|
+
| `--export <input> [output]` | Export a session file to HTML and exit; derive the destination when `output` is omitted |
|
|
54
|
+
|
|
55
|
+
RPC mode rejects `@file` arguments. JSON and RPC modes reserve stdout for protocol records. See [JSON Event Stream](json.md) and [RPC Protocol](rpc.md).
|
|
56
|
+
|
|
57
|
+
<a id="model-options"></a>
|
|
58
|
+
|
|
59
|
+
## Models
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
pi --model sonnet:high
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
See [Choose a Model](models.md) for model selection and [Providers](providers.md) for credentials.
|
|
66
|
+
|
|
67
|
+
- `--provider <name>`<br>
|
|
68
|
+
Restricts `--model` lookup to one provider. It requires `--model`.
|
|
69
|
+
- `--model <pattern>`<br>
|
|
70
|
+
Selects by exact ID or fuzzy ID/name match. It accepts `provider/id` and an optional `:<thinking>` suffix.
|
|
71
|
+
- `--api-key <key>`<br>
|
|
72
|
+
Uses a non-persistent API-key override. It requires a model selected through `--model` or `--models`.
|
|
73
|
+
- `--thinking <level>`<br>
|
|
74
|
+
Sets `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. It overrides a `--model` suffix and is clamped to the model's capabilities.
|
|
75
|
+
- `--models <patterns>`<br>
|
|
76
|
+
Sets a comma-separated scope for startup and cycling. It accepts exact IDs, fuzzy matches, case-insensitive globs, and optional `:<thinking>` suffixes.
|
|
77
|
+
- `--list-models [search]`<br>
|
|
78
|
+
Lists available models, optionally filtered by a fuzzy search, then exits.
|
|
79
|
+
|
|
80
|
+
<a id="session-options"></a>
|
|
81
|
+
|
|
82
|
+
## Sessions
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
pi --continue
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
See [Sessions and Context](sessions.md) for resuming, forking, naming, and storing sessions.
|
|
89
|
+
|
|
90
|
+
- `-c`, `--continue`<br>
|
|
91
|
+
Continues the most recent session for the current project.
|
|
92
|
+
- `-r`, `--resume`<br>
|
|
93
|
+
Opens the session selector.
|
|
94
|
+
- `--session <path|id>`<br>
|
|
95
|
+
Opens by file path, exact ID, or partial ID. Pi searches the current project first and offers to fork a cross-project match.
|
|
96
|
+
- `--session-id <id>`<br>
|
|
97
|
+
Opens the exact project session ID or creates it if absent. IDs accept letters, numbers, `.`, `_`, and `-`.
|
|
98
|
+
- `--fork <path|id>`<br>
|
|
99
|
+
Forks an existing session into a new session for the current project.
|
|
100
|
+
- `--session-dir <dir>`<br>
|
|
101
|
+
Overrides storage and lookup. It takes precedence over `PI_CODING_AGENT_SESSION_DIR` and the `sessionDir` setting.
|
|
102
|
+
- `--no-session`<br>
|
|
103
|
+
Uses an in-memory session that is not persisted.
|
|
104
|
+
- `-n`, `--name <name>`<br>
|
|
105
|
+
Sets the session display name.
|
|
106
|
+
|
|
107
|
+
Constraints:
|
|
108
|
+
|
|
109
|
+
- Session IDs must start and end with a letter or number.
|
|
110
|
+
- `--fork` cannot be combined with `--session`, `--continue`, `--resume`, or `--no-session`.
|
|
111
|
+
- `--session-id` cannot be combined with `--session`, `--continue`, or `--resume`. Combine it with `--fork` to choose the new ID.
|
|
112
|
+
|
|
113
|
+
<a id="tool-options"></a>
|
|
114
|
+
|
|
115
|
+
## Tools
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
pi --tools read,grep,find,ls --print "Review this project"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
See [Settings](settings.md#tools) for configuring the default tool selection.
|
|
122
|
+
|
|
123
|
+
- `-t`, `--tools <list>`<br>
|
|
124
|
+
Replaces the default selection with a comma-separated allowlist of built-in, extension, or custom tools.
|
|
125
|
+
- `-xt`, `--exclude-tools <list>`<br>
|
|
126
|
+
Disables comma-separated tool names after all other selection options.
|
|
127
|
+
- `-nbt`, `--no-builtin-tools`<br>
|
|
128
|
+
Disables default built-in tools while retaining extension and custom tools.
|
|
129
|
+
- `-nt`, `--no-tools`<br>
|
|
130
|
+
Starts with all built-in, extension, and custom tools disabled.
|
|
131
|
+
|
|
132
|
+
Default enabled tools are `read`, `bash`, `edit`, and `write`, unless `defaultTools` changes them. `--tools` replaces the whole selection, so name every tool you want; `defaultTools` also accepts `+name` and `-name` to change the defaults instead.
|
|
133
|
+
|
|
134
|
+
| Built-in | Purpose |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `read` | Read text files and supported images |
|
|
137
|
+
| `bash` | Run shell commands |
|
|
138
|
+
| `powershell` | Run PowerShell commands on Windows |
|
|
139
|
+
| `edit` | Apply exact text replacements to an existing file |
|
|
140
|
+
| `write` | Create or overwrite a file |
|
|
141
|
+
| `grep` | Search file contents |
|
|
142
|
+
| `find` | Find paths using glob patterns |
|
|
143
|
+
| `ls` | List directory contents |
|
|
144
|
+
|
|
145
|
+
Built-in extensions add two more tools. They are off by default; the MCP extension turns them on when an MCP server needs them (see [MCP](mcp.md#exposure)). To enable them yourself, name them in `--tools` or `defaultTools`.
|
|
146
|
+
|
|
147
|
+
| Built-in extension | Purpose |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `codemode` | Run JavaScript that calls the other tools, for example in parallel with `Promise.allSettled`; only the script's output reaches the model |
|
|
150
|
+
| `tool_search` | Search tools that are not declared to the model (`codemode` and `deferred` exposure, such as MCP tools) and declare the matches for the next call |
|
|
151
|
+
|
|
152
|
+
### Enable codemode
|
|
153
|
+
|
|
154
|
+
To turn on `codemode` for every session, add it to the default tools in `~/.pi/agent/settings.json` or a project's `.pi/settings.json`:
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"defaultTools": ["+codemode"]
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
This keeps `read`, `bash`, `edit`, and `write` and adds `codemode`. For one invocation, list every tool, since `--tools` replaces the selection:
|
|
163
|
+
|
|
164
|
+
```sh
|
|
165
|
+
pi --tools read,bash,edit,write,codemode
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Codemode is useful without MCP: scripts can run several tool calls in parallel, filter large output before it reaches the model, call classifier models such as TypeSafe's Jev through `models.classify()` (see [Classifier models](models.md#use-classifier-models)), and generate images through `models.generateImages()` (see [Image models](models.md#use-image-models)).
|
|
169
|
+
|
|
170
|
+
### How codemode works
|
|
171
|
+
|
|
172
|
+
Scripts run in a QuickJS sandbox and reach the other tools through `tools.<name>(args)`. [Codemode](codemode.md) describes the script API, how tools are listed and found, the `store()` and `models` globals, and the limits.
|
|
173
|
+
|
|
174
|
+
### Tool search
|
|
175
|
+
|
|
176
|
+
`tool_search` is off by default; enable it with `"defaultTools": ["+tool_search"]` or `--tools`. It uses the same ranking as `searchTools()` over tools that are not declared yet and declares the matches for the next model call. Loaded tools are recorded in the session like other tool changes, so they stay declared on that branch.
|
|
177
|
+
|
|
178
|
+
<a id="resource-options"></a>
|
|
179
|
+
|
|
180
|
+
## Resources
|
|
181
|
+
|
|
182
|
+
```sh
|
|
183
|
+
pi --extension ./review.ts
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
See [Configuration](configuration.md) for conventional directories and project trust, [Settings](settings.md#resources) for configured paths, and [Pi Packages](packages.md) for package sources.
|
|
187
|
+
|
|
188
|
+
- `-e`, `--extension <path>`<br>
|
|
189
|
+
Loads an extension file or directory, or a built-in extension such as `builtin:mcp`, and is repeatable.
|
|
190
|
+
- `-ne`, `--no-extensions`<br>
|
|
191
|
+
Disables discovered, configured, and built-in extensions. Explicit `-e` paths still load, so `pi -ne -e builtin:mcp` keeps only the built-in MCP support.
|
|
192
|
+
- `--skill <path>`<br>
|
|
193
|
+
Loads a skill file or directory and is repeatable.
|
|
194
|
+
- `-ns`, `--no-skills`<br>
|
|
195
|
+
Disables discovered and configured skills. Explicit `--skill` paths still load.
|
|
196
|
+
- `--prompt-template <path>`<br>
|
|
197
|
+
Loads a prompt-template file or directory and is repeatable.
|
|
198
|
+
- `-np`, `--no-prompt-templates`<br>
|
|
199
|
+
Disables discovered and configured templates. Explicit `--prompt-template` paths still load.
|
|
200
|
+
- `--theme <path>`<br>
|
|
201
|
+
Loads a theme file or directory and is repeatable.
|
|
202
|
+
- `--use-theme <name[/name]>`<br>
|
|
203
|
+
Selects the initial interactive theme for this run.
|
|
204
|
+
- `--no-themes`<br>
|
|
205
|
+
Disables discovered and configured themes. Explicit `--theme` paths still load.
|
|
206
|
+
- `-nc`, `--no-context-files`<br>
|
|
207
|
+
Disables `AGENTS.md` and `CLAUDE.md` discovery.
|
|
208
|
+
|
|
209
|
+
Resource paths apply only to the current process. Relative paths resolve from the current working directory.
|
|
210
|
+
|
|
211
|
+
<a id="prompt-and-display-options"></a>
|
|
212
|
+
|
|
213
|
+
## Prompts and process
|
|
214
|
+
|
|
215
|
+
```sh
|
|
216
|
+
pi --append-system-prompt ./instructions.md
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
See [Configuration](configuration.md) for saved configuration, [Security](security.md#understand-project-trust) for project trust, and [Environment Variables](environment-variables.md) for process controls.
|
|
220
|
+
|
|
221
|
+
- `--system-prompt <text|path>`<br>
|
|
222
|
+
Replaces the default system prompt with text or the contents of an existing file.
|
|
223
|
+
- `--append-system-prompt <text|path>`<br>
|
|
224
|
+
Appends text or an existing file to the system prompt and is repeatable.
|
|
225
|
+
- `--tui-mode <mode>`<br>
|
|
226
|
+
Uses `fullscreen` (default) or `regular` terminal mode.
|
|
227
|
+
- `--verbose`<br>
|
|
228
|
+
Shows verbose interactive startup information, overriding `quietStartup`.
|
|
229
|
+
- `-a`, `--approve`<br>
|
|
230
|
+
Trusts project-local configuration and resources for this process.
|
|
231
|
+
- `-na`, `--no-approve`<br>
|
|
232
|
+
Ignores trust-gated project-local configuration and resources for this process.
|
|
233
|
+
- `--offline`<br>
|
|
234
|
+
Disables automatic network activity, including model catalog refreshes. Equivalent to `PI_OFFLINE=1`.
|
|
235
|
+
- `-h`, `--help`<br>
|
|
236
|
+
Shows help, including flags registered by loaded extensions, then exits.
|
|
237
|
+
- `-v`, `--version`<br>
|
|
238
|
+
Shows the Pi version, then exits.
|
|
239
|
+
|
|
240
|
+
Extensions may register additional long-form options. Unknown short options are rejected.
|
|
241
|
+
|
|
242
|
+
## Package commands
|
|
243
|
+
|
|
244
|
+
```sh
|
|
245
|
+
pi install npm:@scope/package
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
See [Pi Packages](packages.md) for source formats, filtering, installation, and project scope.
|
|
249
|
+
|
|
250
|
+
### Common tasks
|
|
251
|
+
|
|
252
|
+
| Task | Command |
|
|
253
|
+
|---|---|
|
|
254
|
+
| Install a package | `pi install <source>` |
|
|
255
|
+
| List configured packages | `pi list` |
|
|
256
|
+
| Remove a package and its settings entry | `pi remove <source>` |
|
|
257
|
+
| Configure which package resources load | `pi config` |
|
|
258
|
+
|
|
259
|
+
Add `--local` or `-l` to `install`, `remove`, `uninstall`, or `config` to use project settings instead of global settings.
|
|
260
|
+
|
|
261
|
+
### Update Pi or packages
|
|
262
|
+
|
|
263
|
+
Running `pi update` without a target updates Pi itself.
|
|
264
|
+
|
|
265
|
+
| Task | Command |
|
|
266
|
+
|---|---|
|
|
267
|
+
| Update Pi | `pi update` |
|
|
268
|
+
| Update all installed packages | `pi update --extensions` |
|
|
269
|
+
| Update one installed package | `pi update <source>` |
|
|
270
|
+
| Refresh model catalogs | `pi update --models` |
|
|
271
|
+
| Update Pi and all installed packages | `pi update --all` |
|
|
272
|
+
|
|
273
|
+
Add `--force` to reinstall Pi when the selected update includes Pi.
|
|
274
|
+
|
|
275
|
+
`pi update` cannot update Pi when another package manager provides it, such as Nix. Update Pi with that package manager, for example `nix profile upgrade pi`. Package and model catalog updates still work.
|
|
276
|
+
|
|
277
|
+
### Aliases and command options
|
|
278
|
+
|
|
279
|
+
- `pi uninstall <source>` is an alias for `pi remove <source>`.
|
|
280
|
+
- `pi update --self`, `pi update self`, and `pi update pi` are aliases for `pi update`.
|
|
281
|
+
- `pi update --extension <source>` is an alias for `pi update <source>`.
|
|
282
|
+
- `-a`, `--approve` trusts project-local files for one command. `-na`, `--no-approve` ignores trust-gated project-local files.
|
|
283
|
+
- Append `-h` or `--help` to a command for its exact usage and option constraints.
|
|
284
|
+
|
|
285
|
+
## Credential commands
|
|
286
|
+
|
|
287
|
+
```sh
|
|
288
|
+
pi auth check --provider openai --json
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Authentication commands require `--provider <provider>` or `--model <model>`. See [Providers](providers.md) for supported methods.
|
|
292
|
+
|
|
293
|
+
| Command | Description |
|
|
294
|
+
|---|---|
|
|
295
|
+
| `pi auth check` | Print `ready`, `not_ready`, or `invalid`; exit with status `0`, `1`, or `2`, respectively |
|
|
296
|
+
| `pi auth print-api-key` | Print the resolved API key |
|
|
297
|
+
| `pi auth print-bearer-token` | Print a resolved OAuth bearer token |
|
|
298
|
+
|
|
299
|
+
| Option | Applies to | Description |
|
|
300
|
+
|---|---|---|
|
|
301
|
+
| `--provider <provider>` | All | Resolve credentials for a provider |
|
|
302
|
+
| `--model <model>` | All | Resolve credentials from a model; may be combined with `--provider` |
|
|
303
|
+
| `--json` | `auth check` | Write the structured result as JSON |
|
|
304
|
+
| `--credentials` | `auth check` | Emit the resolved credential when ready |
|
|
305
|
+
| `--no-refresh` | `auth check` | Do not refresh expired OAuth credentials; refresh is the default |
|
|
306
|
+
| `--min-expiry <duration>` | `print-bearer-token` | Require remaining token lifetime using `ms`, `s`, `m`, or `h`, such as `30m` |
|
|
307
|
+
|
|
308
|
+
Credential-printing commands write secrets to stdout.
|
|
309
|
+
|
|
310
|
+
## MCP commands
|
|
311
|
+
|
|
312
|
+
These commands work outside a session, so agents can run them through `bash`. See [MCP Servers](mcp.md).
|
|
313
|
+
|
|
314
|
+
| Command | Description |
|
|
315
|
+
|---|---|
|
|
316
|
+
| `pi mcp add <server> [options] -- <command> [args...]` | Add or replace a stdio server in `mcp.json`; `--env KEY=VALUE` (repeatable) and `--cwd <dir>` set its environment and working directory. Arguments after the command are passed to it |
|
|
317
|
+
| `pi mcp add <server> [options] --url <url>` | Add or replace a streamable HTTP server; `--header KEY=VALUE` (repeatable), `--bearer-token-env-var <NAME>` (sends `Authorization: Bearer ${NAME}`), `--oauth-client-id`, `--oauth-client-secret`, `--oauth-callback-port`, and `--oauth-client-name` configure authentication |
|
|
318
|
+
| `pi mcp remove <server>` | Remove a server from `mcp.json`; stored OAuth credentials are kept |
|
|
319
|
+
| `pi mcp list [--json]` | Connect to every enabled server and print its state, tools, and errors; exit with `1` when a config entry is invalid or an enabled server is not connected |
|
|
320
|
+
| `pi mcp login <server> [--timeout <seconds>]` | Sign in to an OAuth server: open the authorization page and wait for the browser (default 300 seconds); a terminal also accepts the pasted redirect URL |
|
|
321
|
+
| `pi mcp logout <server>` | Delete the stored OAuth credentials of a server |
|
|
322
|
+
|
|
323
|
+
`add` and `remove` change `~/.pi/agent/mcp.json`, or `.pi/mcp.json` in the current directory with `--local` (`-l`). `add` also takes `--exposure <mode>` (see [Exposure](mcp.md#exposure)) and `--description <text>` and does not connect; run `pi mcp list` to check the server.
|
|
324
|
+
|
|
325
|
+
Project `.pi/mcp.json` files are only read for projects that are already trusted.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
> Source: [packages/coding-agent/docs/codemode.md](https://github.com/earendil-works/pi/blob/b78e6a9085343ec0f308c3d377da72528b4cf7ee/packages/coding-agent/docs/codemode.md)
|
|
2
|
+
> Retrieved with Firecrawl: 2026-10-05. Repository snapshot: `b78e6a9085343ec0f308c3d377da72528b4cf7ee`.
|
|
3
|
+
> Relative documentation links point to local copies where available, otherwise to the source snapshot.
|
|
4
|
+
|
|
5
|
+
# Codemode
|
|
6
|
+
|
|
7
|
+
The `codemode` tool lets the model write a JavaScript script that calls pi's other tools and runs non-LLM models, such as classifiers and image models. Only the script's output reaches the model, so a script can run calls in parallel and filter large results before the model sees them. To turn it on, see [Enable codemode](cli.md#enable-codemode).
|
|
8
|
+
|
|
9
|
+
## Scripts
|
|
10
|
+
|
|
11
|
+
The tool input is raw JavaScript source, not JSON and not a markdown code fence. It runs as the body of an async function in a QuickJS sandbox, so top-level `await` and `return` work. The sandbox has no Node APIs, file system, network, or timers; scripts reach the outside world only through tools and `models`.
|
|
12
|
+
|
|
13
|
+
A script may start with an options line:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
// @options: {"max_output_tokens": 2000, "timeout_ms": 60000}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- `max_output_tokens` (default 10000) limits the output. Longer output keeps its start and end, and the full text is written to a temp file whose path is included in the result. A script fails when its output passes 16777216 characters of text and base64 image data or 100000 `text()`, `image()`, and `console` calls; write large data to a file with a tool instead.
|
|
20
|
+
- `timeout_ms` is a hard deadline for the whole script. It is unset by default. Image generation can take minutes, so do not set a short deadline for scripts that generate images.
|
|
21
|
+
|
|
22
|
+
The result starts with `Script completed` or `Script failed`, the wall time, and the output. A failed script keeps its partial output, followed by `Script error:` and the error. Tool calls are real: calls made before a failure are not undone. Calls still running when the script ends are cancelled, and unawaited promises are discarded.
|
|
23
|
+
|
|
24
|
+
## Globals
|
|
25
|
+
|
|
26
|
+
| Global | Purpose |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `tools.<name>(args)` | Call a tool. See [Call tools](#call-tools). |
|
|
29
|
+
| `text(value)` | Add a text item to the output. Strings are added as is, other values as JSON. |
|
|
30
|
+
| `image(value)` | Add an image to the output: a base64 `data:` URL, an `{ image_url }` object, or an image block `{ type: "image", data, mimeType }` such as those returned by MCP tools and `models.generateImages()`. Remote URLs are not supported. PNG, JPEG, GIF, and WebP are accepted. Each image is also saved to a temp file, and the result names the path before the image. |
|
|
31
|
+
| `console.log(...)` | Like `text()`; `info`, `warn`, `error`, and `debug` do the same. |
|
|
32
|
+
| `return value` | A top-level `return` adds the value like `text()`. |
|
|
33
|
+
| `exit()` | End the script successfully. |
|
|
34
|
+
| `store(key, value)` / `load(key)` | Keep small JSON values across `codemode` calls. See [Store values](#store-values). |
|
|
35
|
+
| `ALL_TOOLS` | Every callable tool as `{ name, description }`, including tools the description does not list. |
|
|
36
|
+
| `searchTools(query, { limit?, namespace? })` | Rank callable tools by relevance (BM25, default limit 8). Resolves to `{ name, description }[]`. |
|
|
37
|
+
| `describeTool(name)` | Resolves to a tool's description and TypeScript declaration, or `undefined`. |
|
|
38
|
+
| `describeNamespace(name)` | Resolves to `{ name, description?, instructions?, tools }` for a namespace such as an MCP server, or `undefined`. |
|
|
39
|
+
| `models` | List and run non-LLM models. See [Models](#models). |
|
|
40
|
+
|
|
41
|
+
## Call tools
|
|
42
|
+
|
|
43
|
+
Every tool the session can call is a method of `tools`, named by its identifier: characters that are not valid in a JavaScript identifier become `_`, so the MCP tool `mcp__dev-radius__search` is `tools.mcp__dev_radius__search`. Each method takes one object with the tool's arguments.
|
|
44
|
+
|
|
45
|
+
What a call resolves to depends on the tool:
|
|
46
|
+
|
|
47
|
+
- Tools with an output schema resolve to a structured value. `bash` resolves to `{ output, truncated, full_output_path?, exit_code, wall_time_seconds }`, also for non-zero exit codes. Its `output` is not limited to the 2000 lines or 50KB the model sees: it holds up to 1 MiB, and longer output keeps its first and last 512 KiB around an omission marker, with `truncated` set and the full output in `full_output_path`.
|
|
48
|
+
- MCP tools resolve to their `CallToolResult`, including `isError` and `structuredContent`.
|
|
49
|
+
- Other tools, such as `read`, `edit`, and `write`, resolve to their text output.
|
|
50
|
+
|
|
51
|
+
A call that fails, is blocked, or gets invalid arguments rejects with an `Error` that carries the tool's error text. Use `Promise.allSettled()` to keep the results of the calls that succeed.
|
|
52
|
+
|
|
53
|
+
The `codemode` description lists tools with their TypeScript declarations, grouped by namespace (for example one MCP server). Tools with `deferred` exposure, which includes MCP tools with the default `codemode` exposure, are not listed, so the description stays the same while MCP servers connect. Listed declarations share a budget of 3000 estimated tokens (`codemode.inlineBudget` in [settings](settings.md#tools)). Scripts find the other tools with `searchTools()`, `describeTool()`, `describeNamespace()`, or by filtering `ALL_TOOLS`.
|
|
54
|
+
|
|
55
|
+
While `codemode` is active, `codemode.mode` in [settings](settings.md#tools) decides how the other tools are presented. With `on` (default) declared tools stay declared, and their descriptions say how to call them from scripts. With `only` they are hidden from the model and listed in the `codemode` description instead, so the model calls them through scripts.
|
|
56
|
+
|
|
57
|
+
## Store values
|
|
58
|
+
|
|
59
|
+
`store(key, value)` keeps a JSON value under a string key for later `codemode` calls; storing `undefined` deletes the key. `load(key)` returns the value, or `undefined`. Writes are kept only when the script succeeds: each successful script that stores values appends a `codemode-store` custom entry to the session, so resumed sessions keep the values and each branch sees only the values written on its path.
|
|
60
|
+
|
|
61
|
+
The store is for small state such as IDs, cursors, or summaries. One value may have at most 262144 characters of JSON and all values together at most 1048576. Do not store image data; show images with `image()`, which also saves them to a temp file.
|
|
62
|
+
|
|
63
|
+
## Models
|
|
64
|
+
|
|
65
|
+
`models` reaches the model catalog and runs non-LLM models with the session's credentials: classifiers, which answer typed questions about JSON state, and image models, which generate images. Chat models are listed but cannot be run from scripts. Which classifier and image models exist is described in [Use classifier models](models.md#use-classifier-models) and [Use image models](models.md#use-image-models).
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
type ModelType = "chat" | "image" | "classifier";
|
|
69
|
+
|
|
70
|
+
/** A catalog entry. `provider` and `id` identify it; other fields depend on the type. */
|
|
71
|
+
interface ModelInfo {
|
|
72
|
+
type?: ModelType;
|
|
73
|
+
provider: string;
|
|
74
|
+
id: string;
|
|
75
|
+
name: string;
|
|
76
|
+
api: string;
|
|
77
|
+
input: ("text" | "image")[];
|
|
78
|
+
contextWindow?: number;
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare const models: {
|
|
83
|
+
/** Every known model of a type, optionally for one provider. */
|
|
84
|
+
getModelsOfType(type: ModelType, provider?: string): Promise<ModelInfo[]>;
|
|
85
|
+
/** Models of a type whose provider has working credentials. */
|
|
86
|
+
getAvailableOfType(type: ModelType, provider?: string): Promise<ModelInfo[]>;
|
|
87
|
+
/** One catalog entry, or undefined. */
|
|
88
|
+
getModelOfType(type: ModelType, provider: string, id: string): Promise<ModelInfo | undefined>;
|
|
89
|
+
/** Answer `context.questions` about `context.state`; answers are in `result.answers` by question ID. */
|
|
90
|
+
classify(model: ModelInfo, context: ClassifierContext): Promise<ClassifierResult>;
|
|
91
|
+
/** Generate images from `context.input` text and image blocks; show `result.output` blocks with image(). Can take minutes. */
|
|
92
|
+
generateImages(model: ModelInfo, context: ImagesContext): Promise<ImagesResult>;
|
|
93
|
+
};
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`classify()` and `generateImages()` use only the `provider` and `id` of `model`, so `{ provider, id }` works as well. They do not throw on provider errors: check `stopReason` and `errorMessage`. At most four such calls run at once per script; more calls wait for a free slot, so `Promise.all()` over many items is fine. Their usage is added to the `codemode` tool result and counts toward the session cost.
|
|
97
|
+
|
|
98
|
+
Model IDs differ between providers, for example `typesafe/jev-latest` and `openrouter/typesafe/jev-1.13`. Use `models.getAvailableOfType(type)` to find the IDs that work with the current credentials.
|
|
99
|
+
|
|
100
|
+
### Classify
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
interface ClassifierContext {
|
|
104
|
+
/** The data to classify. */
|
|
105
|
+
state: Record<string, unknown>;
|
|
106
|
+
/** Questions by ID. One call answers all of them. */
|
|
107
|
+
questions: Record<string, ClassifierQuestion>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
type ClassifierQuestion =
|
|
111
|
+
/** Pick one label. `criteria` maps each label to what it means. */
|
|
112
|
+
| { type: "choice"; instructions: string; criteria: Record<string, string> }
|
|
113
|
+
/** Score on an ordered scale. `criteria` describes each level, lowest first. */
|
|
114
|
+
| { type: "score"; instructions: string; criteria: string[] }
|
|
115
|
+
/** Yes or no. */
|
|
116
|
+
| { type: "bool"; instructions: string; criteria: { true: string; false: string } };
|
|
117
|
+
|
|
118
|
+
interface ClassifierResult {
|
|
119
|
+
provider: string;
|
|
120
|
+
model: string;
|
|
121
|
+
/** Answers by question ID. */
|
|
122
|
+
answers: Record<string, ClassifierAnswer>;
|
|
123
|
+
usage?: ModelUsage;
|
|
124
|
+
stopReason: "stop" | "error" | "aborted";
|
|
125
|
+
errorMessage?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
type ClassifierAnswer =
|
|
129
|
+
| { type: "choice"; choice: string; probabilities: Record<string, number>; confidence: number }
|
|
130
|
+
/** `score` is the expected level index, from 0 to `criteria.length - 1`. */
|
|
131
|
+
| { type: "score"; score: number; confidence: number }
|
|
132
|
+
/** Probability of `true`. */
|
|
133
|
+
| { type: "bool"; probability: number };
|
|
134
|
+
|
|
135
|
+
/** Token counts and cost in USD, when the service reports them. */
|
|
136
|
+
type ModelUsage = { input: number; output: number; totalTokens: number; cost: { total: number } };
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Classify several items by calling `classify()` once per item. This script sorts feedback messages, for example ones a tool returned earlier in the script:
|
|
140
|
+
|
|
141
|
+
```js
|
|
142
|
+
const jev = await models.getModelOfType("classifier", "typesafe", "jev-latest");
|
|
143
|
+
const results = await Promise.all(
|
|
144
|
+
messages.map((message) =>
|
|
145
|
+
models.classify(jev, {
|
|
146
|
+
state: { message },
|
|
147
|
+
questions: {
|
|
148
|
+
sentiment: {
|
|
149
|
+
type: "choice",
|
|
150
|
+
instructions: "How does the user feel about the product?",
|
|
151
|
+
criteria: { positive: "Satisfied or happy", negative: "Unhappy or frustrated", neutral: "Neither" },
|
|
152
|
+
},
|
|
153
|
+
urgency: {
|
|
154
|
+
type: "score",
|
|
155
|
+
instructions: "How urgently does this need a reply?",
|
|
156
|
+
criteria: ["no reply needed", "reply this week", "reply today"],
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
}),
|
|
160
|
+
),
|
|
161
|
+
);
|
|
162
|
+
return results.map((result, i) =>
|
|
163
|
+
result.stopReason === "stop"
|
|
164
|
+
? { message: messages[i], sentiment: result.answers.sentiment.choice, urgency: result.answers.urgency.score }
|
|
165
|
+
: { message: messages[i], error: result.errorMessage },
|
|
166
|
+
);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Generate images
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
interface ImagesContext {
|
|
173
|
+
/** The prompt as text blocks, plus image blocks to edit or use as references. */
|
|
174
|
+
input: (TextBlock | ImageBlock)[];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
interface ImagesResult {
|
|
178
|
+
provider: string;
|
|
179
|
+
model: string;
|
|
180
|
+
/** Generated images, and text blocks for models that also return text. */
|
|
181
|
+
output: (TextBlock | ImageBlock)[];
|
|
182
|
+
usage?: ModelUsage;
|
|
183
|
+
stopReason: "stop" | "error" | "aborted";
|
|
184
|
+
errorMessage?: string;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
type TextBlock = { type: "text"; text: string };
|
|
188
|
+
/** `data` is base64. */
|
|
189
|
+
type ImageBlock = { type: "image"; data: string; mimeType: string };
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Show generated images with `image(block)`. Do not print `data` with `text()`, `console`, or `return`: it is large and the model cannot read it as text. `image()` also saves each image to a temp file and puts its path in the result, so a later turn can copy or move the file.
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
// @options: {"timeout_ms": 300000}
|
|
196
|
+
const painter = await models.getModelOfType("image", "openrouter", "google/gemini-2.5-flash-image");
|
|
197
|
+
const result = await models.generateImages(painter, {
|
|
198
|
+
input: [{ type: "text", text: "A red fox in the snow, watercolor" }],
|
|
199
|
+
});
|
|
200
|
+
if (result.stopReason !== "stop") return result.errorMessage;
|
|
201
|
+
for (const block of result.output) {
|
|
202
|
+
if (block.type === "image") image(block);
|
|
203
|
+
else text(block.text);
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Limits
|
|
208
|
+
|
|
209
|
+
- A script's VM has 256 MB of memory. Running out throws `InternalError: out of memory`; filter or aggregate large data instead of accumulating it.
|
|
210
|
+
- A script that waits on a promise that can never settle (no tool call pending) fails immediately, since there are no timers.
|
|
211
|
+
- Scripts cannot start other `codemode` scripts.
|