mu-agent 0.1.8 → 0.1.13
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 +121 -0
- package/README.md +34 -30
- package/dist/bundle/chunks/anthropic-messages-4PAJY4R6.js +6 -0
- package/dist/bundle/chunks/anthropic.js +1 -1
- package/dist/bundle/chunks/azure-openai-responses-Y4BBWQ3N.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +12 -9
- package/dist/bundle/chunks/{chunk-NG4PO5FP.js → chunk-3J3HSHLX.js} +128 -110
- package/dist/bundle/chunks/{chunk-TRDNDS6A.js → chunk-3V45WARH.js} +6 -3
- package/dist/bundle/chunks/{chunk-S3GGRYIO.js → chunk-5AGIVGSV.js} +1 -1
- package/dist/bundle/chunks/chunk-6QGV3IWD.js +6 -0
- package/dist/bundle/chunks/{chunk-4OBXYPH4.js → chunk-6Z2347ML.js} +1 -1
- package/dist/bundle/chunks/{chunk-F5ZABL6Z.js → chunk-7CBJINYJ.js} +2 -2
- package/dist/bundle/chunks/{chunk-DRQDKNXA.js → chunk-7DDKXS2Q.js} +1 -1
- package/dist/bundle/chunks/{chunk-H3QXYIF7.js → chunk-CF5GWZHW.js} +1 -1
- package/dist/bundle/chunks/{chunk-RLZVFGW4.js → chunk-DYTENXHX.js} +29 -92
- package/dist/bundle/chunks/{chunk-NTSWBG4X.js → chunk-FLHKNMLQ.js} +1 -1
- package/dist/bundle/chunks/chunk-FTJT2X6E.js +2 -0
- package/dist/bundle/chunks/{chunk-4L3WN2XY.js → chunk-JXWJOIH4.js} +1 -1
- package/dist/bundle/chunks/{chunk-TAOL3JFA.js → chunk-KIDDRTZP.js} +4 -4
- package/dist/bundle/chunks/chunk-LHRPMXVI.js +2 -0
- package/dist/bundle/chunks/chunk-LMNWTX2L.js +11 -0
- package/dist/bundle/chunks/chunk-LPXNMA2W.js +2 -0
- package/dist/bundle/chunks/chunk-LT2C56HV.js +130 -0
- package/dist/bundle/chunks/{chunk-6CYCI3EJ.js → chunk-LVVZS2NO.js} +1 -1
- package/dist/bundle/chunks/chunk-MF3VB62R.js +91 -0
- package/dist/bundle/chunks/chunk-NN4BEPYX.js +2 -0
- package/dist/bundle/chunks/{chunk-LD2P6SFZ.js → chunk-PMRZO46Y.js} +1 -1
- package/dist/bundle/chunks/chunk-R4VPBBDS.js +2 -0
- package/dist/bundle/chunks/chunk-RDZVAGPR.js +2 -0
- package/dist/bundle/chunks/chunk-TMTOQ7H7.js +2 -0
- package/dist/bundle/chunks/chunk-UKVNB6C4.js +2 -0
- package/dist/bundle/chunks/chunk-URBBMV3M.js +9 -0
- package/dist/bundle/chunks/chunk-WCGU75WO.js +11 -0
- package/dist/bundle/chunks/chunk-WCJNJQO5.js +9 -0
- package/dist/bundle/chunks/chunk-WDURT4ZM.js +2 -0
- package/dist/bundle/chunks/{cli-AOVD3SSZ.js → cli-M4YBZZ6Q.js} +4 -4
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-MEZHQVNP.js +2 -0
- package/dist/bundle/chunks/codemode-worker.js +117 -13
- package/dist/bundle/chunks/easter-egg-3d-VFY3YRQR.js +2 -0
- package/dist/bundle/chunks/execute-FKI7Y4XR.js +499 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{google-generative-ai-XMFHGQC5.js → google-generative-ai-D2VJQBTK.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-4XRRNP74.js → google-vertex-SQG2BO6C.js} +1 -1
- package/dist/bundle/chunks/https-proxy-agent-LVOO5TPL.js +13 -0
- package/dist/bundle/chunks/image-resize-worker.js +1 -1
- package/dist/bundle/chunks/{jiti-loader-C3NU2SDH.js → jiti-loader-GL4HJFAD.js} +1 -1
- package/dist/bundle/chunks/{jiti-static-loader-E6ANQD5T.js → jiti-static-loader-2RCDI6B4.js} +1 -1
- package/dist/bundle/chunks/{lib-TEDK3E5I.js → lib-4AVRLBHM.js} +1 -1
- package/dist/bundle/chunks/{llama-cpp-classify-XT44PI3C.js → llama-cpp-classify-5YHLY3RC.js} +2 -2
- package/dist/bundle/chunks/mistral-conversations-BDARVJTT.js +5 -0
- package/dist/bundle/chunks/{multipart-parser-SQ6GDJL7.js → multipart-parser-FMGQ7342.js} +1 -1
- package/dist/bundle/chunks/{node-TWVVAGPO.js → node-AUOGOBCN.js} +1 -1
- package/dist/bundle/chunks/{node-N5BSDOA5.js → node-KCMANYC2.js} +1 -1
- package/dist/bundle/chunks/openai-chatgpt.js +1 -1
- package/dist/bundle/chunks/openai-codex-responses-CECGTDYD.js +10 -0
- package/dist/bundle/chunks/openai-codex.js +1 -1
- package/dist/bundle/chunks/openai-completions-UOA7MELD.js +7 -0
- package/dist/bundle/chunks/openai-decisions-HLM372N6.js +5 -0
- package/dist/bundle/chunks/openai-responses-TII7ZY5X.js +3 -0
- package/dist/bundle/chunks/{openrouter-images-ZVXWCSIM.js → openrouter-images-7T452AS5.js} +1 -1
- package/dist/bundle/chunks/{pi-messages-TM5SOOIW.js → pi-messages-2UDKLKOO.js} +1 -1
- package/dist/bundle/chunks/runtime-IKE5OQIW.js +2 -0
- package/dist/bundle/chunks/{src-UK77SYZE.js → src-QKGKDFSU.js} +1 -1
- package/dist/bundle/chunks/typesafe-system-one-KNCICMO5.js +2 -0
- package/dist/bundle/chunks/virtual-modules-TJPHLTRT.js +2 -0
- 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/core/export-html/template.js +21 -16
- package/dist/modes/interactive/theme/dark.json +1 -1
- package/dist/modes/interactive/theme/light.json +1 -1
- package/dist/modes/interactive/theme/theme-schema.d.ts +28 -0
- package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-schema.js +105 -0
- package/dist/modes/interactive/theme/theme-schema.js.map +1 -0
- package/dist/modes/interactive/theme/theme-tokens.d.ts +257 -0
- package/dist/modes/interactive/theme/theme-tokens.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-tokens.js +94 -0
- package/dist/modes/interactive/theme/theme-tokens.js.map +1 -0
- package/dist/modes/interactive/theme/theme.d.ts +13 -16
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +22 -29
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/docs/cli-integration.md +1 -1
- package/docs/cli.md +22 -10
- package/docs/codemode.md +29 -6
- package/docs/compaction.md +5 -5
- package/docs/custom-provider.md +53 -1
- package/docs/docs.json +8 -0
- package/docs/environment-variables.md +3 -1
- package/docs/extensions.md +122 -13
- package/docs/json.md +3 -3
- package/docs/keybindings.md +5 -4
- package/docs/llama-cpp.md +9 -2
- package/docs/mcp.md +4 -2
- package/docs/message-types.md +22 -4
- package/docs/models-configuration.md +187 -0
- package/docs/models.md +18 -2
- package/docs/nvidia-rtx-llama-cpp.md +96 -0
- package/docs/providers.md +47 -0
- package/docs/sessions.md +1 -1
- package/docs/settings.md +9 -6
- package/docs/terminal-setup.md +14 -0
- package/docs/themes.md +4 -2
- package/docs/tui.md +71 -1
- package/docs/usage.md +1 -1
- package/examples/README.md +0 -3
- 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/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +4 -5
- package/examples/extensions/overlay-test.ts +2 -2
- package/examples/extensions/plan-mode/index.ts +6 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/index.ts +4 -6
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/judge/dist/auth.js +91 -35
- package/judge/dist/chrome.js +2 -2
- package/judge/dist/import.js +852 -175
- package/judge/dist/setup.js +240 -153
- package/judge/manifest.json +2512 -546
- package/judge/mu/chunk-3NQ5BIBI.js +4773 -0
- package/judge/mu/chunk-SKGYWHW6.js +51 -0
- package/judge/mu/chunk-WQM4MV6L.js +58 -0
- package/judge/mu/cloud-code-V7FOGB4J.js +22802 -0
- package/judge/mu/dist-75PS4OC4.js +1283 -0
- package/judge/{dist/kyrn-judge.js → mu/index.js} +5365 -32809
- package/judge/mu/multipart-parser-ZDXVIOOP.js +372 -0
- package/judge/mu/src-TVVA5ZK2.js +1409 -0
- package/judge/themes/mu-dark.json +80 -0
- package/judge/themes/mu-light.json +80 -0
- package/kyrn/bin/kyrn-doctor +44 -19
- package/kyrn/bin/kyrn-judge-local +43 -14
- package/kyrn/bin/kyrn-ledger +16 -1
- package/kyrn/bin/mu.mjs +142 -61
- package/kyrn/local-judge/server.py +26 -14
- package/package.json +8 -6
- package/dist/bundle/chunks/anthropic-messages-MI4QHRXW.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-E3QGN4VN.js +0 -2
- package/dist/bundle/chunks/chunk-33KL6IIQ.js +0 -20
- package/dist/bundle/chunks/chunk-A3JYRWB6.js +0 -2
- package/dist/bundle/chunks/chunk-C47CLQZK.js +0 -2
- package/dist/bundle/chunks/chunk-HQHD6PZI.js +0 -2
- package/dist/bundle/chunks/chunk-KJUDFE6Y.js +0 -11
- package/dist/bundle/chunks/chunk-TE3GUV6H.js +0 -9
- package/dist/bundle/chunks/chunk-VIV3CWXG.js +0 -2
- package/dist/bundle/chunks/chunk-WE4MXUQS.js +0 -11
- package/dist/bundle/chunks/chunk-Y2PP32XV.js +0 -2
- package/dist/bundle/chunks/chunk-YLY6CKPK.js +0 -132
- package/dist/bundle/chunks/chunk-ZE5FMF3V.js +0 -99
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-NM3JRRWQ.js +0 -2
- package/dist/bundle/chunks/easter-egg-3d-G2LUBEMZ.js +0 -2
- package/dist/bundle/chunks/execute-MZVUC6BB.js +0 -388
- package/dist/bundle/chunks/https-proxy-agent-2VXB7436.js +0 -13
- package/dist/bundle/chunks/mistral-conversations-Q22M3IBG.js +0 -5
- package/dist/bundle/chunks/openai-codex-responses-4MYQSO5E.js +0 -10
- package/dist/bundle/chunks/openai-completions-OSRCWAAA.js +0 -7
- package/dist/bundle/chunks/openai-responses-UHF3DHNG.js +0 -3
- package/dist/bundle/chunks/runtime-VJMMDLVH.js +0 -2
- package/dist/bundle/chunks/typesafe-system-one-PRR5K6CI.js +0 -2
- package/dist/bundle/chunks/virtual-modules-RJXJGCPI.js +0 -2
- package/dist/modes/interactive/theme/theme-json.d.ts +0 -85
- package/dist/modes/interactive/theme/theme-json.d.ts.map +0 -1
- package/dist/modes/interactive/theme/theme-json.js +0 -132
- package/dist/modes/interactive/theme/theme-json.js.map +0 -1
- package/dist/modes/interactive/theme/theme-schema.json +0 -361
- package/examples/plugins/pi-example-plugin/README.md +0 -38
- package/examples/plugins/pi-example-plugin/package.json +0 -10
- package/examples/plugins/pi-example-plugin/src/contract.ts +0 -13
- package/examples/plugins/pi-example-plugin/src/session.ts +0 -24
- package/examples/plugins/pi-example-plugin/src/tui.ts +0 -31
package/docs/custom-provider.md
CHANGED
|
@@ -29,7 +29,59 @@ Prefer a complete provider for new integrations that own more than static endpoi
|
|
|
29
29
|
|
|
30
30
|
Registering only `baseUrl` or `headers` for an existing provider preserves its built-in models. Supplying `models` in the legacy form replaces that provider's models across chat, image, and classifier operations. An omitted `type` means `"chat"`; image and classifier models require explicit discriminants and implementations keyed by their `api` values through the `images` and `classifiers` fields.
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
### Redirect an existing provider
|
|
33
|
+
|
|
34
|
+
Register only the fields that should change. This keeps the provider's built-in catalog, authentication, API implementation, and compatibility settings:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
38
|
+
|
|
39
|
+
export default function (pi: ExtensionAPI) {
|
|
40
|
+
pi.registerProvider("anthropic", {
|
|
41
|
+
baseUrl: "https://gateway.example.com/anthropic",
|
|
42
|
+
headers: {
|
|
43
|
+
"X-Gateway-Key": "$GATEWAY_API_KEY",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Use this form for a proxy or gateway that preserves the upstream protocol. Do not copy the built-in model list into the extension because doing so turns a small endpoint override into a catalog replacement that can drift.
|
|
50
|
+
|
|
51
|
+
### Register a compatible endpoint
|
|
52
|
+
|
|
53
|
+
When a service implements a supported protocol but has its own model catalog, register the endpoint and only the models the service actually exposes:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
57
|
+
|
|
58
|
+
export default function (pi: ExtensionAPI) {
|
|
59
|
+
pi.registerProvider("acme", {
|
|
60
|
+
name: "Acme AI",
|
|
61
|
+
baseUrl: "https://api.acme.example/v1",
|
|
62
|
+
apiKey: "$ACME_API_KEY",
|
|
63
|
+
api: "openai-completions",
|
|
64
|
+
models: [
|
|
65
|
+
{
|
|
66
|
+
type: "chat",
|
|
67
|
+
id: "acme-chat",
|
|
68
|
+
name: "Acme Chat",
|
|
69
|
+
reasoning: false,
|
|
70
|
+
input: ["text"],
|
|
71
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
72
|
+
contextWindow: 128000,
|
|
73
|
+
maxTokens: 8192,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Prefer `models.json` for this case when no executable extension behavior is needed. Use an extension when registration depends on runtime discovery, custom authentication, or code shared with other extension features.
|
|
81
|
+
|
|
82
|
+
### Register mixed-operation models
|
|
83
|
+
|
|
84
|
+
A mixed-operation provider can register non-chat models and their implementations together:
|
|
33
85
|
|
|
34
86
|
```typescript
|
|
35
87
|
pi.registerProvider("media-tools", {
|
package/docs/docs.json
CHANGED
|
@@ -47,6 +47,10 @@
|
|
|
47
47
|
"title": "Run Local Models",
|
|
48
48
|
"path": "llama-cpp.md"
|
|
49
49
|
},
|
|
50
|
+
{
|
|
51
|
+
"title": "Run Local Models on NVIDIA RTX",
|
|
52
|
+
"path": "nvidia-rtx-llama-cpp.md"
|
|
53
|
+
},
|
|
50
54
|
{
|
|
51
55
|
"title": "Configure Your Terminal",
|
|
52
56
|
"path": "terminal-setup.md"
|
|
@@ -148,6 +152,10 @@
|
|
|
148
152
|
"title": "Settings",
|
|
149
153
|
"path": "settings.md"
|
|
150
154
|
},
|
|
155
|
+
{
|
|
156
|
+
"title": "Models Configuration",
|
|
157
|
+
"path": "models-configuration.md"
|
|
158
|
+
},
|
|
151
159
|
{
|
|
152
160
|
"title": "Environment Variables",
|
|
153
161
|
"path": "environment-variables.md"
|
|
@@ -86,9 +86,11 @@ These variables are read by Pi itself:
|
|
|
86
86
|
| `PI_TELEMETRY` | Override install/update telemetry and provider attribution headers: `1`/`true`/`yes` or `0`/`false`/`no` |
|
|
87
87
|
| `PI_CACHE_RETENTION` | Set to `long` for extended provider prompt caching where supported |
|
|
88
88
|
| `PI_SHARE_VIEWER_URL` | Override the base URL used by `/share` |
|
|
89
|
-
| `PI_RADIUS_GATEWAY` | Override the Radius gateway origin used by `/bug` uploads
|
|
89
|
+
| `PI_RADIUS_GATEWAY` | Override the Radius gateway origin used by `/bug` uploads |
|
|
90
90
|
| `PI_HARDWARE_CURSOR` | Set to `1` to show the hardware cursor; see [Terminal setup](terminal-setup.md) |
|
|
91
|
+
| `PI_CLIPBOARD_OSC52` | Set to `1` to also send copied text to the terminal with OSC 52 after the local clipboard write, as Pi does over SSH. Use it when a remote client reaches Pi without SSH variables, such as a multiplexer attached from another machine or a remote IDE daemon |
|
|
91
92
|
| `PI_HYPERLINKS` | Override OSC 8 hyperlink detection with `1`, `0`, or `auto` |
|
|
93
|
+
| `PI_PROGRAM_STATUS` | Override OSC 7501 program status detection: `1` always reports, `0` never reports; otherwise Pi reports only after the terminal confirms support. See [Terminal setup](terminal-setup.md#program-status) |
|
|
92
94
|
| `PI_IMAGE_PROTOCOL` | Override inline image detection with `kitty`, `iterm2`, `none`, or `auto` |
|
|
93
95
|
| `PI_TRUE_COLOR` | Override truecolor detection with `1`, `0`, or `auto` |
|
|
94
96
|
| `PI_TUI_ESC_TIMEOUT` | How long to wait after a lone ESC before treating it as Escape, in milliseconds; defaults to `100` over SSH and `10` otherwise. Increase if Alt-key input is misread as Escape |
|
package/docs/extensions.md
CHANGED
|
@@ -51,7 +51,7 @@ Reload replaces the extension runtime, so code after `await ctx.reload()` must n
|
|
|
51
51
|
|
|
52
52
|
<a id="understand-the-lifecycle"></a>
|
|
53
53
|
|
|
54
|
-
##
|
|
54
|
+
## Understand the runtime lifecycle
|
|
55
55
|
|
|
56
56
|
The factory can be synchronous or asynchronous. Pi waits for an asynchronous factory before startup continues, allowing it to fetch configuration or register providers needed during startup.
|
|
57
57
|
|
|
@@ -59,12 +59,95 @@ Do not start processes, sockets, watchers, or timers in the factory because some
|
|
|
59
59
|
Start long-lived resources from `session_start` or from the command or tool that needs them.
|
|
60
60
|
Close session-scoped resources from an idempotent `session_shutdown` handler.
|
|
61
61
|
|
|
62
|
-
A
|
|
63
|
-
|
|
62
|
+
A normal prompt follows this hook sequence:
|
|
63
|
+
|
|
64
|
+
```mermaid
|
|
65
|
+
flowchart TD
|
|
66
|
+
Input["input"] --> Before["before_agent_start"]
|
|
67
|
+
Before --> AgentStart["agent_start"]
|
|
68
|
+
AgentStart --> TurnStart["turn_start"]
|
|
69
|
+
TurnStart --> Context["context"]
|
|
70
|
+
Context --> ContextSystem["context_with_system"]
|
|
71
|
+
ContextSystem --> Headers["before_provider_headers"]
|
|
72
|
+
Headers --> Request["before_provider_request"]
|
|
73
|
+
Request --> Response["after_provider_response"]
|
|
74
|
+
Response --> Stream["provider_stream_event and assistant message events"]
|
|
75
|
+
Stream --> ToolDecision{"Assistant requested tools?"}
|
|
76
|
+
ToolDecision -->|yes| ToolStart["tool_execution_start"]
|
|
77
|
+
ToolStart --> ToolCall["tool_call"]
|
|
78
|
+
ToolCall --> Execute["execute and tool_execution_update"]
|
|
79
|
+
Execute --> ToolResult["tool_result"]
|
|
80
|
+
ToolResult --> ToolEnd["tool_execution_end"]
|
|
81
|
+
ToolEnd --> TurnEnd["turn_end"]
|
|
82
|
+
ToolDecision -->|no| TurnEnd
|
|
83
|
+
TurnEnd --> MoreTurns{"Another model turn required?"}
|
|
84
|
+
MoreTurns -->|yes| TurnStart
|
|
85
|
+
MoreTurns -->|no| AgentEnd["agent_end"]
|
|
86
|
+
AgentEnd --> MoreRuns{"Retry, recovery, compaction retry, or queued work?"}
|
|
87
|
+
MoreRuns -->|yes| AgentStart
|
|
88
|
+
MoreRuns -->|no| BeforeSettle["agent_before_settle"]
|
|
89
|
+
BeforeSettle --> Continue{"Continuation requested?"}
|
|
90
|
+
Continue -->|yes| AgentStart
|
|
91
|
+
Continue -->|no| Settled["agent_settled"]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The lifecycle involves these event groups:
|
|
95
|
+
|
|
96
|
+
| Area | Events |
|
|
97
|
+
|---|---|
|
|
98
|
+
| Input preparation | `input`, `before_agent_start` |
|
|
99
|
+
| Agent run | `agent_start`, `agent_end` |
|
|
100
|
+
| Model turn | `turn_start`, `context`, `context_with_system`, `turn_end` |
|
|
101
|
+
| Provider call | `before_provider_headers`, `before_provider_request`, `after_provider_response`, `provider_stream_event` |
|
|
102
|
+
| Message lifecycle | `message_start`, `message_update`, `message_end` |
|
|
103
|
+
| Tool execution | `tool_execution_start`, `tool_call`, `tool_execution_update`, `tool_result`, `tool_execution_end` |
|
|
104
|
+
| Settlement | `agent_before_settle`, `agent_settled` |
|
|
105
|
+
|
|
106
|
+
Pi counts as busy while a run starts, including the compaction check and `before_agent_start`, so messages sent meanwhile go into the starting run. Message lifecycle events also cover user and tool-result messages; the diagram places only the assistant stream where it occurs in each model turn.
|
|
107
|
+
|
|
108
|
+
Tool hooks run for each tool call, and one assistant response can start another turn by returning tool calls. Provider hooks run only when that transport exposes the corresponding stage. See the exported declarations in [`extensions/types.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/extensions/types.ts) for exact event payloads and result types.
|
|
109
|
+
|
|
110
|
+
Session startup and replacement follow a separate lifecycle:
|
|
111
|
+
|
|
112
|
+
```mermaid
|
|
113
|
+
flowchart TD
|
|
114
|
+
Startup["Process startup"] --> Trust["project_trust when needed"]
|
|
115
|
+
Trust --> SessionStart["session_start"]
|
|
116
|
+
Switch["/new or /resume"] --> BeforeSwitch["session_before_switch"]
|
|
117
|
+
Fork["/fork or /clone"] --> BeforeFork["session_before_fork"]
|
|
118
|
+
BeforeSwitch --> Shutdown["session_shutdown"]
|
|
119
|
+
BeforeFork --> Shutdown
|
|
120
|
+
Reload["reload"] --> Shutdown
|
|
121
|
+
Shutdown --> Replacing{"Replacing the runtime?"}
|
|
122
|
+
Replacing -->|yes| Replacement["load replacement extension runtime"]
|
|
123
|
+
Replacement --> SessionStart
|
|
124
|
+
Replacing -->|no| Stop["process exits"]
|
|
125
|
+
SessionStart --> Discover["resources_discover"]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`project_trust` runs before trusted project resources load and can run again when session replacement enters a new working directory. Retries, recovery, compaction, and queued messages can start another agent run after `agent_end`, so `agent_end` is not a final-idle signal. Reload and session replacement invalidate the old runtime. Code after `await ctx.reload()` still belongs to the old runtime and must not reuse its session-bound state.
|
|
129
|
+
|
|
130
|
+
### Choose an event by intent
|
|
131
|
+
|
|
132
|
+
| Goal | Event |
|
|
133
|
+
|---|---|
|
|
134
|
+
| Inspect, transform, or consume raw user input | `input` |
|
|
135
|
+
| Change prompt sections, active tools, or add context before a run | `before_agent_start` |
|
|
136
|
+
| Observe one low-level agent run | `agent_start`, `agent_end` |
|
|
137
|
+
| Act after one model response and its tool calls | `turn_end` |
|
|
138
|
+
| Filter conversation messages for one provider request | `context` |
|
|
139
|
+
| Transform the complete transcript, including system messages | `context_with_system` |
|
|
140
|
+
| Change request headers or the serialized provider payload | `before_provider_headers`, `before_provider_request` |
|
|
141
|
+
| Observe provider response metadata or parsed stream events | `after_provider_response`, `provider_stream_event` |
|
|
142
|
+
| Authorize or modify a tool call | `tool_call` |
|
|
143
|
+
| Redact, annotate, or replace a tool result | `tool_result` |
|
|
144
|
+
| Append final entries or request one last continuation | `agent_before_settle` |
|
|
145
|
+
| Run notification work after automatic processing has stopped | `agent_settled` |
|
|
146
|
+
| Initialize or release session-scoped resources | `session_start`, `session_shutdown` |
|
|
147
|
+
|
|
64
148
|
<a id="agent_start--agent_end--agent_before_settle--agent_settled"></a>
|
|
65
149
|
|
|
66
|
-
`agent_before_settle`
|
|
67
|
-
`agent_settled` is final and notification-only; use it when an integration needs to know Pi will not continue automatically.
|
|
150
|
+
Use `agent_before_settle` when an extension must append entries or request one final continuation. Use `agent_settled` for notification-only work that should run after Pi has no automatic continuation remaining.
|
|
68
151
|
|
|
69
152
|
<a id="extensionapi-methods"></a>
|
|
70
153
|
|
|
@@ -100,7 +183,20 @@ Use each event’s declared result type rather than assuming every return value
|
|
|
100
183
|
|
|
101
184
|
Events cover resource discovery, sessions, agent and message lifecycle, providers, tools, and raw input.
|
|
102
185
|
|
|
103
|
-
|
|
186
|
+
#### Understand handler composition
|
|
187
|
+
|
|
188
|
+
| Pattern | Behavior |
|
|
189
|
+
|---|---|
|
|
190
|
+
| Notification | Return values are ignored. Use the event for observation only. |
|
|
191
|
+
| In-place mutation | Later handlers see changes to values such as `before_provider_headers.headers`, `before_agent_start.systemPromptOptions`, and `tool_call.input`. |
|
|
192
|
+
| Chained transformation | Later handlers receive the value returned by earlier `input`, `context`, `context_with_system`, `message_end`, `tool_result`, and `before_provider_request` handlers. |
|
|
193
|
+
| Gate | A handled input, blocked tool call, cancelled session operation, or handled `user_bash` command stops that operation's normal fallback path. |
|
|
194
|
+
| Actionable boundary | Each `turn_end` or `agent_before_settle` handler sees the entries and continuation decision proposed so far. |
|
|
195
|
+
| Last override | The last `cache_warming_decision` handler that returns an action wins. |
|
|
196
|
+
|
|
197
|
+
Notification handlers should not perform slow work on a streaming event. Transform handlers should preserve fields they do not intentionally own, and gate handlers should fail closed when their safety decision cannot be made.
|
|
198
|
+
|
|
199
|
+
`before_agent_start` exposes both the current prompt and its structured `systemPromptOptions`. `event.messageType` says what started the run: `"user"` for a prompt or `pi.sendUserMessage()`, with `prompt` and `images`; `"custom"` for `pi.sendMessage(..., { triggerTurn: true })`, with the starting `message` and no `prompt`. A returned `message` is added to either kind of run; check `messageType` to skip runs started by custom messages. Prefer changing prompt sections, selected tools, or guidelines so Pi can append a transcript delta. Returning `systemPrompt`, or setting `forceSystemPrompt`, replaces the whole prompt for that run while the transcript continues recording the structured sections. Providers receive the forced text as their leading system prompt.
|
|
104
200
|
|
|
105
201
|
`message_end` can replace a finalized message while preserving its role. `tool_call` can mutate input or block execution. `tool_result` handlers compose, with each handler seeing prior changes.
|
|
106
202
|
|
|
@@ -159,9 +255,9 @@ See [`hello.ts`](../examples/extensions/hello.ts), [`todo.ts`](../examples/exten
|
|
|
159
255
|
- `deferred`: like `codemode`, but codemode tools do not list it; `tool_search` can find and activate it.
|
|
160
256
|
- `hidden`: registered but unreachable. Re-register a tool with `exposure: "hidden"` to withdraw it, since tools cannot be unregistered.
|
|
161
257
|
|
|
162
|
-
`namespace: { name, description, instructions }` groups related tools, as MCP servers do. Codemode tools list a namespace under one heading with its `description`. `instructions` holds longer usage guidance; it is not listed, and codemode scripts read it with `describeNamespace(name)`.
|
|
258
|
+
`namespace: { name, aliases, description, instructions }` groups related tools, as MCP servers do. Codemode tools list a namespace under one heading with its `description`. `instructions` holds longer usage guidance; it is not listed, and codemode scripts read it with `describeNamespace(name)`. `aliases` are other names scripts may look the namespace up by, for example the server name `docs` for `mcp__docs`; a name and the same name as a script identifier (`my-docs`, `my_docs`) match alike.
|
|
163
259
|
|
|
164
|
-
Registering a `direct` or `model-only` tool activates it; the other exposures are not activated on registration. The active set (`pi.getActiveTools()`, `pi.setActiveTools()`) is the set of tools declared to the model. `pi.getAllTools()` reports each tool's `exposure`, `namespace`, and `
|
|
260
|
+
Registering a `direct` or `model-only` tool activates it; the other exposures are not activated on registration. The active set (`pi.getActiveTools()`, `pi.setActiveTools()`) is the set of tools declared to the model. `pi.getAllTools()` reports each tool's `exposure`, `namespace`, `annotations`, and `reachesTools`.
|
|
165
261
|
|
|
166
262
|
`annotations` are hints about what a tool does, with the meaning of MCP tool annotations: `readOnlyHint`, `destructiveHint`, `idempotentHint`, and `openWorldHint`. MCP tools carry the hints their server declares. Missing hints take the MCP defaults: a tool is not read-only, and may be destructive and reach an open world. The hints are not verified, but a permission extension can use them to decide which calls to confirm. This confirms the calls Codex asks approval for:
|
|
167
263
|
|
|
@@ -177,7 +273,9 @@ pi.on("tool_call", async (event, ctx) => {
|
|
|
177
273
|
});
|
|
178
274
|
```
|
|
179
275
|
|
|
180
|
-
A tool that orchestrates other tools can adjust what the model sees while it is active with `prepareLoadout(loadout)`. It runs whenever the active tools change and receives the declared tools, the callable tools, and every registered tool with its exposure and
|
|
276
|
+
A tool that orchestrates other tools can adjust what the model sees while it is active with `prepareLoadout(loadout)`. It runs whenever the active tools change and receives the declared tools, the callable tools, and every registered tool with its exposure, namespace, and prompt guidelines. It returns replacement `descriptions` for declared tools (including its own) and `hiddenDeclarations`: active tools whose declarations requests leave out while they stay active and callable. The default system prompt leaves hidden tools out of its tool list and rules, and names no tool in the skills hint when the file reader is hidden, so the orchestrating tool should present their guidelines itself. `codemode` uses only this hook, `exposure`, `reachesTools`, and `ctx.executeTool()`, so another tool can implement the same behavior under a different name.
|
|
277
|
+
|
|
278
|
+
A tool that reaches other tools declares which ones a call may reach with `reachesTools(input)`: `"all"`, or the words of the input that may name them, where a word refers to every tool or namespace whose name it contains. `codemode` returns `"all"` for scripts that search or list tools and the words of the script otherwise; `tool_search` always returns `"all"`. Extensions that register tools late use it from their `tool_call` handler to finish registering the tools a call needs before it runs, as the MCP extension does for servers that are still connecting. The MCP extension also activates `codemode` or `tool_search` for MCP tools only when the tool of that name declares `reachesTools`.
|
|
181
279
|
|
|
182
280
|
### Activate tools dynamically
|
|
183
281
|
|
|
@@ -268,7 +366,18 @@ Use `ctx.shutdown()` to request an orderly process shutdown.
|
|
|
268
366
|
|
|
269
367
|
## Examples and reference
|
|
270
368
|
|
|
271
|
-
The checked [extension examples](../examples/extensions/)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
369
|
+
The checked [extension examples](../examples/extensions/) are the implementation reference. Start with the smallest example matching the behavior you need:
|
|
370
|
+
|
|
371
|
+
| Goal | Start with | Why |
|
|
372
|
+
|---|---|---|
|
|
373
|
+
| Confirm or block tool calls | [`permission-gate.ts`](../examples/extensions/permission-gate.ts) | Combines `tool_call`, mode-aware UI, and fail-closed behavior. |
|
|
374
|
+
| Modify prompt sections for a run | [`prompt-customizer.ts`](../examples/extensions/prompt-customizer.ts) | Uses structured prompt options instead of replacing the complete prompt. |
|
|
375
|
+
| Keep branch-aware tool state | [`todo.ts`](../examples/extensions/todo.ts) | Reconstructs state from persisted entries and renders it in the TUI. |
|
|
376
|
+
| Register tools after startup | [`dynamic-tools.ts`](../examples/extensions/dynamic-tools.ts) | Shares registration logic between lifecycle and command handlers. |
|
|
377
|
+
| Run cancellable model work from a command | [`qna.ts`](../examples/extensions/qna.ts) | Combines nested model calls, cancellation, and custom UI. |
|
|
378
|
+
| Replace the main editor | [`modal-editor.ts`](../examples/extensions/modal-editor.ts) | Extends `CustomEditor` while preserving application controls. |
|
|
379
|
+
| Run finalization at shutdown | [`auto-commit-on-exit.ts`](../examples/extensions/auto-commit-on-exit.ts) | Uses the session shutdown hook for finalization work. |
|
|
380
|
+
| Route built-in tools to another machine | [`ssh.ts`](../examples/extensions/ssh.ts) | Reuses tool operation interfaces instead of recreating tool contracts. |
|
|
381
|
+
| Add OAuth and provider-specific streaming | [`custom-provider-gitlab-duo/`](../examples/extensions/custom-provider-gitlab-duo/) | Shows a complete provider integration while delegating supported protocols. |
|
|
382
|
+
|
|
383
|
+
Use [Custom Providers](custom-provider.md) for model-service integrations, [Terminal UI](tui.md) for custom components, and [Pi Packages](packages.md) to install or distribute extensions with other resources. Use the exported declarations for exact signatures, payloads, and result schemas; this guide focuses on lifecycle choices, composition, and durable implementation patterns.
|
package/docs/json.md
CHANGED
|
@@ -42,7 +42,7 @@ A basic run produces records like these:
|
|
|
42
42
|
{"type":"message_end","message":{"role":"assistant","...":"..."}}
|
|
43
43
|
{"type":"turn_end","message":{"role":"assistant","...":"..."},"toolResults":[]}
|
|
44
44
|
{"type":"agent_end","messages":[{"...":"..."}],"willRetry":false}
|
|
45
|
-
{"type":"agent_settled"}
|
|
45
|
+
{"type":"agent_settled","aborted":false}
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
`agent_end` closes one low-level agent run. Automatic retry, overflow recovery, compaction retry, steering, or follow-up work can still continue. `agent_settled` means Pi has no remaining automatic work for that session-level run.
|
|
@@ -53,7 +53,7 @@ A basic run produces records like these:
|
|
|
53
53
|
|---|---|---|
|
|
54
54
|
| `agent_start` | None | A low-level agent run started. |
|
|
55
55
|
| `agent_end` | `messages`, `willRetry` | That low-level run ended. `messages` contains messages generated by the run. |
|
|
56
|
-
| `agent_settled` |
|
|
56
|
+
| `agent_settled` | `aborted` | Pi will not continue automatically through retries, compaction recovery, or queued messages. `aborted` is `true` when the run ended because it was aborted. |
|
|
57
57
|
| `turn_start` | None | One assistant turn started. |
|
|
58
58
|
| `turn_end` | `message`, `toolResults` | One assistant response and its resulting tool calls finished. |
|
|
59
59
|
|
|
@@ -104,7 +104,7 @@ The top-level `usage` is the latest cumulative provider-reported usage for the a
|
|
|
104
104
|
|---|---|---|
|
|
105
105
|
| `tool_execution_start` | `toolCallId`, `toolName`, `args` | Tool execution started. |
|
|
106
106
|
| `tool_execution_update` | `toolCallId`, `toolName`, `args`, `partialResult` | The tool reported a partial result. |
|
|
107
|
-
| `tool_execution_end` | `toolCallId`, `toolName`, `result`, `isError` | Tool execution finished. |
|
|
107
|
+
| `tool_execution_end` | `toolCallId`, `toolName`, `result`, `isError`, `durationMs` | Tool execution finished. `durationMs` is how long the tool's `execute()` took, measured with a monotonic clock; absent when the tool did not run. |
|
|
108
108
|
|
|
109
109
|
Use `toolCallId` to correlate the lifecycle. `partialResult` is the latest partial result supplied by the tool. Whether it replaces or extends an earlier update depends on that tool's result contract.
|
|
110
110
|
|
package/docs/keybindings.md
CHANGED
|
@@ -12,6 +12,7 @@ Map each action identifier to one key or a list of keys:
|
|
|
12
12
|
|
|
13
13
|
```json
|
|
14
14
|
{
|
|
15
|
+
"$schema": "https://pi.dev/schemas/keybindings.schema.json",
|
|
15
16
|
"app.session.new": "ctrl+shift+n",
|
|
16
17
|
"app.session.tree": ["ctrl+shift+t", "alt+shift+t"]
|
|
17
18
|
}
|
|
@@ -57,8 +58,8 @@ Examples: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `super+k`, `ctrl+sup
|
|
|
57
58
|
| `tui.editor.cursorRight` | `right`, `ctrl+f` | Move cursor right |
|
|
58
59
|
| `tui.editor.cursorWordLeft` | `alt+left`, `ctrl+left`, `alt+b` | Move cursor word left |
|
|
59
60
|
| `tui.editor.cursorWordRight` | `alt+right`, `ctrl+right`, `alt+f` | Move cursor word right |
|
|
60
|
-
| `tui.editor.cursorLineStart` | `home`, `ctrl+
|
|
61
|
-
| `tui.editor.cursorLineEnd` | `end`, `ctrl+
|
|
61
|
+
| `tui.editor.cursorLineStart` | `home`, `ctrl+a` | Move to line start |
|
|
62
|
+
| `tui.editor.cursorLineEnd` | `end`, `ctrl+e` | Move to line end |
|
|
62
63
|
| `tui.editor.jumpForward` | `ctrl+]` | Jump forward to character |
|
|
63
64
|
| `tui.editor.jumpBackward` | `ctrl+alt+]` | Jump backward to character |
|
|
64
65
|
| `tui.editor.pageUp` | `pageUp`, `ctrl+pageUp` | Scroll up by page |
|
|
@@ -113,8 +114,8 @@ In fullscreen mode, these actions control the transcript and take precedence ove
|
|
|
113
114
|
| `tui.altScreen.searchNext` | `enter`, `ctrl+g` | Select the next search match while searching |
|
|
114
115
|
| `tui.altScreen.searchPrevious` | `shift+enter`, `ctrl+shift+g` | Select the previous search match while searching |
|
|
115
116
|
| `tui.altScreen.searchClose` | `escape` | Close transcript search |
|
|
116
|
-
| `tui.altScreen.top` | `home` | Scroll to the beginning of the transcript |
|
|
117
|
-
| `tui.altScreen.bottom` | `end` | Scroll to the transcript end and follow new output |
|
|
117
|
+
| `tui.altScreen.top` | `ctrl+home` | Scroll to the beginning of the transcript |
|
|
118
|
+
| `tui.altScreen.bottom` | `ctrl+end` | Scroll to the transcript end and follow new output |
|
|
118
119
|
|
|
119
120
|
### Application
|
|
120
121
|
|
package/docs/llama-cpp.md
CHANGED
|
@@ -41,7 +41,7 @@ A single-file model can sit directly in the model directory. Put multimodal and
|
|
|
41
41
|
└── large-model-Q4_K_M-00003-of-00003.gguf
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Restart the router after manually adding files. For per-model context sizes and other options, use [llama.cpp model presets](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md#model-presets).
|
|
44
|
+
Restart the router after manually adding files. For per-model context sizes and other options, use [llama.cpp model presets](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md#model-presets). For settings tuned to a specific NVIDIA GPU and model, see [Run Pi with NVIDIA RTX and llama.cpp](nvidia-rtx-llama-cpp.md).
|
|
45
45
|
|
|
46
46
|
## Configure Pi
|
|
47
47
|
|
|
@@ -88,7 +88,14 @@ If the router disconnects, `/llama` shows **Retry** and **Close**. Retry reconne
|
|
|
88
88
|
|
|
89
89
|
## Classification
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
Classifier models answer typed `choice`, `bool`, and `score` questions about JSON state, like TypeSafe's Jev models. The model reaches them from [`codemode`](cli.md#enable-codemode) scripts, and extensions through `ctx.modelRegistry.classify()`; see [Classifier models](models.md#use-classifier-models). Pi lists llama.cpp models as classifiers in two ways:
|
|
92
|
+
|
|
93
|
+
- **Decision models** such as [Julia-1, Laya, Kev, lev, and OpenJev](https://huggingface.co/collections/ggml-org/decision-models-6abf80cca3c83f127060a769) answer natively through llama.cpp's `/v1/systemone` endpoint. They appear only as classifiers, with the `typesafe-system-one` API, and not in `/model`.
|
|
94
|
+
- **Chat models** are also listed as classifiers with the same ID and the `llama-cpp-classify` API, which reads answers from next-token probabilities as described below.
|
|
95
|
+
|
|
96
|
+
llama.cpp 0.6.0 and later report decision models in the router's model list: their `architecture.output_modalities` contains `decisions`. The router reads this from the GGUF metadata without loading the model, so Pi recognizes unloaded and sleeping decision models too. Older llama.cpp builds do not report it, and Pi lists their decision models as chat models.
|
|
97
|
+
|
|
98
|
+
### Chat models as classifiers
|
|
92
99
|
|
|
93
100
|
The model does not generate an answer. Each question becomes one chat prompt: the state, every question of the request, the state again, and then the question with its answers under single-token labels. Labels are letters for a choice (up to 62 options), `Yes`/`No` for a bool, and digits for a score (up to 10 levels). The second copy of the state is read with the questions in view, which improved accuracy on JevBench with small models. Pi reads the probabilities of the labels as the next token and normalizes them. A choice returns every option's probability and a confidence of `(n * peak - 1) / (n - 1)`; a score returns the expected level.
|
|
94
101
|
|
package/docs/mcp.md
CHANGED
|
@@ -225,6 +225,8 @@ Pi activates `codemode` when a server with `codemode` exposure connects. It acti
|
|
|
225
225
|
|
|
226
226
|
Tools with `codemode` or `deferred` exposure can be reached through either indirect mechanism: codemode scripts can call them, and `tool_search` can load them. Codemode calls do not depend on the active tool set, so they remain available after `/tree`, resume, and fork. Tools loaded by `tool_search` are recorded in the transcript and remain declared on that branch.
|
|
227
227
|
|
|
228
|
+
`--tools` does not remove MCP tools unless one of its entries starts with `mcp__`; `pi --tools read,codemode,'mcp__radius__*'` keeps only the tools of `radius`. `--exclude-tools` accepts the same patterns, and `--no-mcp` disables MCP for one run (see [Tools](cli.md#mcp-tools)).
|
|
229
|
+
|
|
228
230
|
To keep `codemode` active without MCP servers, add `"defaultTools": ["+codemode"]` to [settings](settings.md#tools). To prevent automatic codemode activation, set `"autoEnableCodemode": false` beside `mcpServers`. A project value overrides the user-level value. Pi warns once when neither `codemode` nor `tool_search` is active and non-direct tools cannot be called.
|
|
229
231
|
|
|
230
232
|
Text results over 20 KB reach the model with their middle removed around a `…N chars truncated…` marker. The full text is saved to a temporary file named in the result. Codemode scripts receive the complete result and can reduce it before returning output to the model.
|
|
@@ -261,9 +263,9 @@ Changes to enabled state or exposure apply only to the current session. A file-c
|
|
|
261
263
|
|
|
262
264
|
### Replace the built-in MCP support
|
|
263
265
|
|
|
264
|
-
An installed extension that registers `/mcp`, such as `pi-mcp-adapter`, replaces the built-in MCP support for sessions. Pi then does not read `mcp.json` or connect its servers in a session, and `/mcp` belongs to the extension. Remove the extension to restore the built-in behavior. To disable built-in MCP support without a replacement, disable `mcp` under Built-in in `pi config`, or set `"extensions": ["-builtin:mcp"]` in [settings](settings.md#resources).
|
|
266
|
+
An installed extension that registers `/mcp`, such as `pi-mcp-adapter`, replaces the built-in MCP support for sessions. Pi then does not read `mcp.json` or connect its servers in a session, and `/mcp` belongs to the extension. Remove the extension to restore the built-in behavior. To disable built-in MCP support without a replacement, disable `mcp` under Built-in in `pi config`, or set `"extensions": ["-builtin:mcp"]` in [settings](settings.md#resources). `--no-mcp` disables it for one run.
|
|
265
267
|
|
|
266
|
-
An extension that registers `codemode` or `tool_search` similarly replaces the built-in tool with that name. Shell-level `pi mcp` commands always use the built-in implementation.
|
|
268
|
+
An extension that registers `codemode` or `tool_search` similarly replaces the built-in tool with that name. Pi activates the replacement for MCP servers and waits for the servers its calls need only when it declares [`reachesTools`](extensions.md#tool-exposure). Shell-level `pi mcp` commands always use the built-in implementation.
|
|
267
269
|
|
|
268
270
|
### Use MCP from the SDK
|
|
269
271
|
|
package/docs/message-types.md
CHANGED
|
@@ -100,12 +100,11 @@ interface SystemMessage {
|
|
|
100
100
|
sections?: Record<string, string | null>;
|
|
101
101
|
toolsAdded?: Tool[];
|
|
102
102
|
toolsRemoved?: ToolReference[];
|
|
103
|
-
replace?: boolean;
|
|
104
103
|
timestamp: number;
|
|
105
104
|
}
|
|
106
105
|
```
|
|
107
106
|
|
|
108
|
-
The leading system message declares the initial prompt and tools. Later system messages can append instructions, replace or remove named prompt sections, and add or remove tools. Replaying them in order yields the current state.
|
|
107
|
+
The leading system message declares the initial prompt and tools. Later system messages can append instructions, replace or remove named prompt sections, and add or remove tools. Replaying them in order yields the current state.
|
|
109
108
|
|
|
110
109
|
### UserMessage
|
|
111
110
|
|
|
@@ -129,6 +128,7 @@ interface AssistantMessage {
|
|
|
129
128
|
responseModel?: string;
|
|
130
129
|
responseId?: string;
|
|
131
130
|
providerThinkingLevel?: string;
|
|
131
|
+
thinkingLevel?: ModelThinkingLevel;
|
|
132
132
|
diagnostics?: AssistantMessageDiagnostic[];
|
|
133
133
|
usage: Usage;
|
|
134
134
|
stopReason: "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred";
|
|
@@ -140,7 +140,7 @@ interface AssistantMessage {
|
|
|
140
140
|
}
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
`responseModel` records a concrete provider response model when it differs from the requested model. `responseId`, `providerThinkingLevel`, `diagnostics`, and `rawStopReason` preserve provider or runtime details.
|
|
143
|
+
`responseModel` records a concrete provider response model when it differs from the requested model. `responseId`, `providerThinkingLevel`, `thinkingLevel`, `diagnostics`, and `rawStopReason` preserve provider or runtime details.
|
|
144
144
|
|
|
145
145
|
`"pending"` is used for a partial assistant message while it streams. The completed message in `message_end` has a terminal stop reason, and Pi does not persist `"pending"` assistant messages in session JSONL.
|
|
146
146
|
|
|
@@ -168,12 +168,30 @@ interface ToolResultMessage<TDetails = any> {
|
|
|
168
168
|
content: (TextContent | ImageContent)[];
|
|
169
169
|
details?: TDetails;
|
|
170
170
|
usage?: Usage;
|
|
171
|
+
nestedCalls?: NestedToolCalls;
|
|
171
172
|
isError: boolean;
|
|
172
173
|
timestamp: number;
|
|
173
174
|
}
|
|
174
175
|
```
|
|
175
176
|
|
|
176
|
-
`details` is tool-specific. Optional `usage` reports nested model work performed by the tool and contributes to full-session statistics, but it is not part of the main model-call usage.
|
|
177
|
+
`details` is tool-specific. Optional `usage` reports nested model work performed by the tool and contributes to full-session statistics, but it is not part of the main model-call usage. `nestedCalls` records bounded metadata about calls this tool made to other tools:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
interface NestedToolCalls {
|
|
181
|
+
calls: NestedToolCallRecord[];
|
|
182
|
+
complete: boolean;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
interface NestedToolCallRecord {
|
|
186
|
+
id: string;
|
|
187
|
+
name: string;
|
|
188
|
+
arguments?: JsonObject;
|
|
189
|
+
argumentsBytes?: number;
|
|
190
|
+
status: "ok" | "error" | "unfinished";
|
|
191
|
+
durationMs?: number;
|
|
192
|
+
error?: string;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
177
195
|
|
|
178
196
|
## Coding-agent messages
|
|
179
197
|
|