@astralyn/pi 0.85.3 → 0.86.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/dist/bundle/chunks/anthropic-messages-R2LYJUDD.js +6 -0
- package/dist/bundle/chunks/azure-openai-responses-HS35BQV6.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +36 -32
- package/dist/bundle/chunks/{chunk-S2DJQQI2.js → chunk-2IO5GDBS.js} +10 -1
- package/dist/bundle/chunks/chunk-DAEM5JIZ.js +2 -0
- package/dist/bundle/chunks/{chunk-LB4P77SH.js → chunk-GTBMYBFG.js} +777 -762
- package/dist/bundle/chunks/{chunk-7LO5Z4WE.js → chunk-I5IVW2WS.js} +1 -1
- package/dist/bundle/chunks/chunk-JI4WGISU.js +2 -0
- package/dist/bundle/chunks/chunk-LPQCB2VJ.js +44 -0
- package/dist/bundle/chunks/chunk-NW5FIDD7.js +11 -0
- package/dist/bundle/chunks/chunk-PJVFYVHE.js +42 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/google-generative-ai-NOVAJBFC.js +2 -0
- package/dist/bundle/chunks/google-vertex-4VHCZJV5.js +2 -0
- package/dist/bundle/chunks/https-proxy-agent-JOOPB4RE.js +16 -0
- package/dist/bundle/chunks/jiti-loader-BFSSLU7G.js +21 -0
- package/dist/bundle/chunks/jiti-static-loader-CLT3YR3B.js +2 -0
- package/dist/bundle/chunks/mistral-conversations-WC6A2WCJ.js +5 -0
- package/dist/bundle/chunks/{node-G4XOIDPH.js → node-CXWYTK2I.js} +1 -1
- package/dist/bundle/chunks/openai-codex-responses-XCDG75W2.js +10 -0
- package/dist/bundle/chunks/openai-completions-6SMWQWQN.js +7 -0
- package/dist/bundle/chunks/openai-responses-UT6XFKC7.js +2 -0
- package/dist/bundle/chunks/{pi-messages-PE6B42TG.js → pi-messages-MQMPIPNC.js} +1 -1
- package/dist/bundle/chunks/virtual-modules-OHUZ2T7X.js +2 -0
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js +13 -11
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +56 -14
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +305 -176
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bug-report-upload.d.ts +12 -0
- package/dist/core/bug-report-upload.d.ts.map +1 -0
- package/dist/core/bug-report-upload.js +22 -0
- package/dist/core/bug-report-upload.js.map +1 -0
- package/dist/core/bug-report.d.ts +176 -0
- package/dist/core/bug-report.d.ts.map +1 -0
- package/dist/core/bug-report.js +292 -0
- package/dist/core/bug-report.js.map +1 -0
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js +12 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/cache-warmer.d.ts +102 -0
- package/dist/core/cache-warmer.d.ts.map +1 -0
- package/dist/core/cache-warmer.js +333 -0
- package/dist/core/cache-warmer.js.map +1 -0
- package/dist/core/compaction/branch-summarization.js +2 -2
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +14 -9
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +30 -23
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/settings.d.ts +17 -20
- package/dist/core/compaction/settings.d.ts.map +1 -1
- package/dist/core/compaction/settings.js +19 -26
- package/dist/core/compaction/settings.js.map +1 -1
- package/dist/core/context-snapshot.d.ts +16 -5
- package/dist/core/context-snapshot.d.ts.map +1 -1
- package/dist/core/context-snapshot.js +20 -10
- package/dist/core/context-snapshot.js.map +1 -1
- package/dist/core/crash-log.d.ts +22 -0
- package/dist/core/crash-log.d.ts.map +1 -0
- package/dist/core/crash-log.js +71 -0
- package/dist/core/crash-log.js.map +1 -0
- package/dist/core/experimental.d.ts +0 -4
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +0 -4
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/jiti-loader.d.ts +2 -0
- package/dist/core/extensions/jiti-loader.d.ts.map +1 -0
- package/dist/core/extensions/jiti-loader.js +4 -0
- package/dist/core/extensions/jiti-loader.js.map +1 -0
- package/dist/core/extensions/jiti-static-loader.d.ts +2 -0
- package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -0
- package/dist/core/extensions/jiti-static-loader.js +4 -0
- package/dist/core/extensions/jiti-static-loader.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +38 -51
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +10 -7
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +85 -67
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +60 -50
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts +3 -0
- package/dist/core/extensions/virtual-modules.d.ts.map +1 -0
- package/dist/core/extensions/virtual-modules.js +39 -0
- package/dist/core/extensions/virtual-modules.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +1 -20
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.js +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +1 -0
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts +101 -20
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +25 -18
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +8 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +2 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +5 -3
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/provider-composer.d.ts +3 -2
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +2 -0
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/radius.d.ts +3 -0
- package/dist/core/radius.d.ts.map +1 -1
- package/dist/core/radius.js +6 -0
- package/dist/core/radius.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +46 -18
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +6 -2
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.js +14 -13
- package/dist/core/session-export.js.map +1 -1
- package/dist/core/session-manager.d.ts +29 -6
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +159 -96
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +31 -4
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +65 -8
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +49 -6
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +121 -92
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +6 -3
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +1 -2
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/shell-execution.js +2 -2
- package/dist/core/tools/shell-execution.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +1 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/usage-totals.d.ts +1 -1
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +4 -1
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/extensions/background/schema.d.ts +1 -1
- package/dist/extensions/btw/agent.d.ts.map +1 -1
- package/dist/extensions/btw/agent.js +3 -2
- package/dist/extensions/btw/agent.js.map +1 -1
- package/dist/extensions/llama/client.d.ts +2 -0
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +7 -3
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +20 -5
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/provider/compat-fields.d.ts.map +1 -1
- package/dist/extensions/provider/compat-fields.js +5 -2
- package/dist/extensions/provider/compat-fields.js.map +1 -1
- package/dist/extensions/provider/ui/app.js +2 -2
- package/dist/extensions/provider/ui/app.js.map +1 -1
- package/dist/extensions/todo/schema.d.ts +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +13 -9
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +2 -2
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/bug-report.d.ts +16 -0
- package/dist/modes/interactive/bug-report.d.ts.map +1 -0
- package/dist/modes/interactive/bug-report.js +206 -0
- package/dist/modes/interactive/bug-report.js.map +1 -0
- package/dist/modes/interactive/chat-viewport.js +1 -1
- package/dist/modes/interactive/chat-viewport.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +0 -5
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +2 -3
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +12 -5
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +12 -5
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts +6 -13
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +15 -51
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +4 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +7 -2
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts +2 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +6 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +1 -2
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +4 -2
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +5 -8
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +72 -95
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +11 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +11 -4
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts +2 -2
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +7 -7
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/tool-chrome.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-chrome.js +4 -1
- package/dist/modes/interactive/components/tool-chrome.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +4 -3
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -10
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +4 -51
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +15 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +234 -91
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts +2 -0
- package/dist/modes/interactive/session-share.d.ts.map +1 -1
- package/dist/modes/interactive/session-share.js +8 -4
- package/dist/modes/interactive/session-share.js.map +1 -1
- package/dist/modes/interactive/tui-renderer.js +2 -2
- package/dist/modes/interactive/tui-renderer.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/clipboard-command.d.ts +7 -0
- package/dist/utils/clipboard-command.d.ts.map +1 -0
- package/dist/utils/clipboard-command.js +45 -0
- package/dist/utils/clipboard-command.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +53 -81
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +111 -121
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/wsl.d.ts +3 -0
- package/dist/utils/wsl.d.ts.map +1 -0
- package/dist/utils/wsl.js +15 -0
- package/dist/utils/wsl.js.map +1 -0
- package/dist/utils/zip.d.ts +7 -0
- package/dist/utils/zip.d.ts.map +1 -0
- package/dist/utils/zip.js +60 -0
- package/dist/utils/zip.js.map +1 -0
- package/docs/compaction.md +32 -11
- package/docs/custom-provider.md +19 -8
- package/docs/environment-variables.md +1 -0
- package/docs/extensions.md +50 -34
- package/docs/models.md +38 -3
- package/docs/providers.md +9 -1
- package/docs/sdk.md +4 -2
- package/docs/session-format.md +63 -24
- package/docs/sessions.md +28 -1
- package/docs/settings.md +58 -4
- package/docs/termux.md +0 -1
- package/docs/tui.md +2 -0
- package/docs/usage.md +1 -0
- package/examples/extensions/README.md +0 -1
- package/examples/extensions/custom-provider-anthropic/index.ts +18 -12
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -2
- package/examples/extensions/prompt-customizer.ts +19 -67
- package/npm-shrinkwrap.json +275 -1028
- package/package.json +17 -23
- package/dist/bundle/chunks/anthropic-messages-IHRRITCV.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-QXBIDYXO.js +0 -2
- package/dist/bundle/chunks/chunk-JSJPY26N.js +0 -2
- package/dist/bundle/chunks/chunk-KI6LC764.js +0 -42
- package/dist/bundle/chunks/chunk-OWESLY5T.js +0 -11
- package/dist/bundle/chunks/chunk-RRBI7OUG.js +0 -50
- package/dist/bundle/chunks/chunk-YZJWMPUI.js +0 -2
- package/dist/bundle/chunks/google-generative-ai-NBOR3IQR.js +0 -2
- package/dist/bundle/chunks/google-vertex-VTHX3SUB.js +0 -2
- package/dist/bundle/chunks/https-proxy-agent-2VXB7436.js +0 -13
- package/dist/bundle/chunks/mistral-conversations-NO4ANAA5.js +0 -5
- package/dist/bundle/chunks/openai-codex-responses-5S3T3HMA.js +0 -10
- package/dist/bundle/chunks/openai-completions-CXRRTRWE.js +0 -7
- package/dist/bundle/chunks/openai-responses-CV3MH6VP.js +0 -2
- package/dist/utils/clipboard-native.d.ts +0 -11
- package/dist/utils/clipboard-native.d.ts.map +0 -1
- package/dist/utils/clipboard-native.js +0 -20
- package/dist/utils/clipboard-native.js.map +0 -1
- package/examples/extensions/kimi-deferred-tools.ts +0 -61
package/docs/session-format.md
CHANGED
|
@@ -8,7 +8,7 @@ Sessions are stored as JSONL (JSON Lines) files. Each line is a JSON object with
|
|
|
8
8
|
~/.pi/agent/sessions/--<encoded-cwd>--/<timestamp>_<uuid>.jsonl
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Pi resolves the working directory to an absolute path, removes one leading `/` or `\`, replaces every `/`, `\`, and `:` with `-`, then wraps the result in `--`. For example, `/path/to/project` is stored under `--path-to-project--`; `C:\Users\me\project` is stored under `--C--Users-me-project--`.
|
|
11
|
+
Pi resolves the working directory to an absolute path, removes one leading `/` or `\`, replaces every `/`, `\`, and `:` with `-`, then wraps the result in `--`. For example, `/path/to/project` is stored under `--path-to-project--`; `C:\Users\me\project` is stored under `--C--Users-me-project--`. By default the session ID is a UUID; callers can supply their own through the SDK or `--session-id`.
|
|
12
12
|
|
|
13
13
|
## Deleting Sessions
|
|
14
14
|
|
|
@@ -92,12 +92,21 @@ interface ToolCall {
|
|
|
92
92
|
name: string;
|
|
93
93
|
arguments: Record<string, any>;
|
|
94
94
|
thoughtSignature?: string;
|
|
95
|
+
namespace?: string;
|
|
95
96
|
}
|
|
96
97
|
```
|
|
97
98
|
|
|
98
99
|
### Base Message Types (`@earendil-works/pi-ai`)
|
|
99
100
|
|
|
100
101
|
```typescript
|
|
102
|
+
interface SystemMessage {
|
|
103
|
+
role: "system";
|
|
104
|
+
content: string | TextContent[];
|
|
105
|
+
toolsAdded?: Tool[];
|
|
106
|
+
toolsRemoved?: Array<{ name: string }>;
|
|
107
|
+
timestamp: number; // Unix ms
|
|
108
|
+
}
|
|
109
|
+
|
|
101
110
|
interface UserMessage {
|
|
102
111
|
role: "user";
|
|
103
112
|
content: string | (TextContent | ImageContent)[];
|
|
@@ -112,10 +121,14 @@ interface AssistantMessage {
|
|
|
112
121
|
model: string;
|
|
113
122
|
responseModel?: string;
|
|
114
123
|
responseId?: string;
|
|
124
|
+
providerThinkingLevel?: string;
|
|
115
125
|
diagnostics?: AssistantMessageDiagnostic[];
|
|
116
126
|
usage: Usage;
|
|
117
|
-
stopReason: "stop" | "length" | "toolUse" | "error" | "aborted";
|
|
127
|
+
stopReason: "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred";
|
|
128
|
+
deferred?: DeferredHandle;
|
|
118
129
|
errorMessage?: string;
|
|
130
|
+
rawStopReason?: string;
|
|
131
|
+
endTurn?: boolean;
|
|
119
132
|
timestamp: number;
|
|
120
133
|
}
|
|
121
134
|
|
|
@@ -149,7 +162,7 @@ interface Usage {
|
|
|
149
162
|
}
|
|
150
163
|
```
|
|
151
164
|
|
|
152
|
-
The exported pi-ai `StopReason` type also includes `"pending"`, but that value is reserved for partial messages in streaming events. Terminal `done` or `error` events replace it with a final completion reason before Pi persists the assistant message, so `"pending"` must never appear in session JSONL.
|
|
165
|
+
The exported pi-ai `StopReason` type also includes `"pending"`, but that value is reserved for partial messages in streaming events. Terminal `done` or `error` events replace it with a final completion reason before Pi persists the assistant message, so `"pending"` must never appear in session JSONL. `"deferred"` is a terminal reason for a provider response that will complete later; its `deferred` handle carries the provider data needed to retrieve that response.
|
|
153
166
|
|
|
154
167
|
### Pi-Specific `AgentMessage` Roles
|
|
155
168
|
|
|
@@ -178,7 +191,7 @@ interface CustomMessage<T = unknown> {
|
|
|
178
191
|
interface BranchSummaryMessage {
|
|
179
192
|
role: "branchSummary";
|
|
180
193
|
summary: string;
|
|
181
|
-
fromId: string;
|
|
194
|
+
fromId: string | null; // Previous leaf whose abandoned path was summarized
|
|
182
195
|
timestamp: number;
|
|
183
196
|
}
|
|
184
197
|
|
|
@@ -192,7 +205,7 @@ interface CompactionSummaryMessage {
|
|
|
192
205
|
|
|
193
206
|
### `AgentMessage`
|
|
194
207
|
|
|
195
|
-
`AgentMessage` is the `Message` union from `@earendil-works/pi-ai` plus roles registered through `CustomAgentMessages` in `@earendil-works/pi-agent-core`. Pi registers the four roles above; extensions may register additional roles.
|
|
208
|
+
`AgentMessage` is the `Message` union from `@earendil-works/pi-ai` plus roles registered through `CustomAgentMessages` in `@earendil-works/pi-agent-core`. Pi registers the four roles above alongside the base `system`, `user`, `assistant`, and `toolResult` roles; extensions may register additional roles.
|
|
196
209
|
|
|
197
210
|
## Entry Base
|
|
198
211
|
|
|
@@ -201,9 +214,9 @@ All entries (except `SessionHeader`) extend `SessionEntryBase`:
|
|
|
201
214
|
```typescript
|
|
202
215
|
interface SessionEntryBase {
|
|
203
216
|
type: string;
|
|
204
|
-
id: string;
|
|
205
|
-
parentId: string | null; // Parent entry ID (null for
|
|
206
|
-
timestamp: string;
|
|
217
|
+
id: string; // Usually an 8-char hex ID; may fall back to a full UUID
|
|
218
|
+
parentId: string | null; // Parent entry ID (null for a root entry)
|
|
219
|
+
timestamp: string; // ISO timestamp
|
|
207
220
|
}
|
|
208
221
|
```
|
|
209
222
|
|
|
@@ -225,11 +238,18 @@ For sessions with a parent (created via `/fork`, `/clone`, or `newSession({ pare
|
|
|
225
238
|
|
|
226
239
|
### SessionMessageEntry
|
|
227
240
|
|
|
228
|
-
A message in the conversation. The `message` field contains an `AgentMessage`. These examples include the required message fields; optional fields from the message shapes above may also be present.
|
|
241
|
+
A message in the conversation. The `message` field contains an `AgentMessage`. These examples include the required message fields; optional fields from the message shapes above may also be present. System messages carry the prompt and tool loadout: the first request of a session persists one with every prompt section and tool declaration, and later changes persist as system messages that patch `sections` by name (`null` removes one) and list `toolsAdded`/`toolsRemoved`. Replaying them in order yields the current prompt and tools; there is no separate prompt state entry.
|
|
229
242
|
|
|
230
243
|
```json
|
|
231
|
-
{"type":"message","id":"
|
|
232
|
-
{"type":"message","id":"
|
|
244
|
+
{"type":"message","id":"a0b1c2d3","parentId":null,"timestamp":"2024-12-03T14:00:00.000Z","message":{"role":"system","content":"","sections":{"preamble":"You are an expert coding assistant...","tools":"<tools>\n- read: ...\n</tools>","cwd":"/project"},"toolsAdded":[{"name":"read","description":"...","parameters":{}}],"timestamp":1733234400000}}
|
|
245
|
+
{"type":"message","id":"d4e5f6g7","parentId":"c3d4e5f6","timestamp":"2024-12-03T14:04:00.000Z","message":{"role":"system","content":"","sections":{"skills":"<skills>...</skills>"},"toolsRemoved":[{"name":"write"}],"timestamp":1733234640000}}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Sessions created before system messages existed have no leading system message; the first request declares the current prompt as a later system message, which replays the same way.
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{"type":"message","id":"a1b2c3d4","parentId":"prev1234","timestamp":"2024-12-03T14:00:01.000Z","message":{"role":"user","content":"Hello","timestamp":1733234401000}}
|
|
252
|
+
{"type":"message","id":"b2c3d4e5","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:00:02.000Z","message":{"role":"assistant","content":[{"type":"text","text":"Hi!"}],"api":"anthropic-messages","provider":"anthropic","model":"claude-sonnet-4-5","usage":{...},"stopReason":"stop","timestamp":1733234402000}}
|
|
233
253
|
{"type":"message","id":"c3d4e5f6","parentId":"b2c3d4e5","timestamp":"2024-12-03T14:00:03.000Z","message":{"role":"toolResult","toolCallId":"call_123","toolName":"bash","content":[{"type":"text","text":"output"}],"isError":false,"timestamp":1733234403000}}
|
|
234
254
|
```
|
|
235
255
|
|
|
@@ -249,15 +269,28 @@ Emitted when the user changes the thinking/reasoning level.
|
|
|
249
269
|
{"type":"thinking_level_change","id":"e5f60718","parentId":"d4e5f607","timestamp":"2024-12-03T14:06:00.000Z","thinkingLevel":"high"}
|
|
250
270
|
```
|
|
251
271
|
|
|
272
|
+
### UsageEntry
|
|
273
|
+
|
|
274
|
+
Records model-attributed usage that is not an assistant message and does not participate in LLM context. `kind` is an arbitrary string identifying the operation; for example, cache warming uses `"cache_warm"`.
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{"type":"usage","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:08:00.000Z","kind":"cache_warm","provider":"anthropic","model":"claude-sonnet-4-5","usage":{"input":0,"output":0,"cacheRead":50000,"cacheWrite":0,"totalTokens":50000,"cost":{"input":0,"output":0,"cacheRead":0.015,"cacheWrite":0,"total":0.015}}}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Usage entries contribute to session token and cost totals. Pi hides them from the conversation tree. Consumers should treat unknown `kind` values as normal usage rather than rejecting them.
|
|
281
|
+
|
|
252
282
|
### CompactionEntry
|
|
253
283
|
|
|
254
|
-
Created when context is compacted. Stores a summary of earlier messages. `firstKeptEntryId` is required and identifies the earliest pre-compaction path entry retained alongside the summary.
|
|
284
|
+
Created when context is compacted. Stores a summary of earlier messages and a complete system prompt/tool checkpoint. `firstKeptEntryId` is required and identifies the earliest pre-compaction path entry retained alongside the summary.
|
|
255
285
|
|
|
256
286
|
```json
|
|
257
|
-
{"type":"compaction","id":"
|
|
287
|
+
{"type":"compaction","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:10:00.000Z","summary":"User discussed X, Y, Z...","firstKeptEntryId":"c3d4e5f6","tokensBefore":50000,"systemMessage":{"role":"system","content":"You are a coding assistant.","toolsAdded":[],"timestamp":1733235000000}}
|
|
258
288
|
```
|
|
259
289
|
|
|
290
|
+
`firstKeptEntryId` is required. It identifies the first entry retained from before the compaction entry. When rebuilding context, Pi replaces older summarized entries with the compaction summary and keeps the range beginning at this entry.
|
|
291
|
+
|
|
260
292
|
Optional fields:
|
|
293
|
+
- `systemMessage`: The replayed prompt sections and tool declarations at the compaction boundary; it becomes the leading system message of the compacted context, and system messages among the kept entries are dropped in its favor. It is absent on older session entries.
|
|
261
294
|
- `usage`: LLM usage from generating the summary; included in session token and cost totals
|
|
262
295
|
- `details`: Implementation-specific data (e.g., `{ readFiles: string[], modifiedFiles: string[] }` for default, or custom data for extensions)
|
|
263
296
|
- `fromHook`: `true` if generated by an extension, `false`/`undefined` if pi-generated (legacy field name)
|
|
@@ -270,6 +303,8 @@ Created when switching branches via `/tree` with an LLM generated summary of the
|
|
|
270
303
|
{"type":"branch_summary","id":"0718293a","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:15:00.000Z","fromId":"f6071829","summary":"Branch explored approach A..."}
|
|
271
304
|
```
|
|
272
305
|
|
|
306
|
+
`parentId` is the entry from which the new branch continues. `fromId` is the previous leaf whose abandoned path was summarized.
|
|
307
|
+
|
|
273
308
|
Optional fields:
|
|
274
309
|
- `usage`: LLM usage from generating the summary; included in session token and cost totals
|
|
275
310
|
- `details`: File tracking data (`{ readFiles: string[], modifiedFiles: string[] }`) for default, or custom data for extensions
|
|
@@ -378,11 +413,12 @@ The session name is displayed in the session selector (`/resume`) instead of the
|
|
|
378
413
|
|
|
379
414
|
## Tree Structure
|
|
380
415
|
|
|
381
|
-
Entries form
|
|
382
|
-
-
|
|
383
|
-
- Each
|
|
416
|
+
Entries normally form one tree, but navigation APIs can create multiple roots:
|
|
417
|
+
- A root entry has `parentId: null`; the first entry is initially the root
|
|
418
|
+
- Each non-root entry points to its parent via `parentId`
|
|
384
419
|
- Branching creates new children from an earlier entry
|
|
385
420
|
- The "leaf" is the current position in the tree
|
|
421
|
+
- Calling `resetLeaf()` or `branchWithSummary(null, ...)` allows a later entry to become another root
|
|
386
422
|
|
|
387
423
|
```
|
|
388
424
|
[user msg] ─── [assistant] ─── [user msg] ─── [assistant] ─┬─ [user msg] ← current leaf
|
|
@@ -395,7 +431,7 @@ Entries form a tree:
|
|
|
395
431
|
`buildContextEntries()` follows the active path from root to the current leaf. If the path has no compaction entry, it returns that path unchanged. Otherwise it uses only the latest `CompactionEntry` and returns entries in this order:
|
|
396
432
|
|
|
397
433
|
1. The latest compaction entry itself.
|
|
398
|
-
2.
|
|
434
|
+
2. Non-system path entries starting at that compaction's required `firstKeptEntryId` and ending immediately before the compaction entry.
|
|
399
435
|
3. Every path entry after the compaction entry.
|
|
400
436
|
|
|
401
437
|
Earlier summarized entries are omitted. Non-message entries in the selected ranges remain in the returned list for rendering and state handling. If a malformed session's `firstKeptEntryId` is not found before the compaction entry, step 2 contributes no entries.
|
|
@@ -405,10 +441,10 @@ Earlier summarized entries are omitted. Non-message entries in the selected rang
|
|
|
405
441
|
1. It determines `thinkingLevel` and `model` from the entire active path, including entries omitted by compaction. A `model_change` sets the model, and an assistant message later on the path sets it from that message's `provider` and `model`.
|
|
406
442
|
2. It projects the selected entries to `AgentMessage[]` in the order above:
|
|
407
443
|
- `message` → the stored `AgentMessage`; parsed user, assistant, or tool-result messages with null or missing `content` are copied with `content: []`.
|
|
408
|
-
- `compaction` → `CompactionSummaryMessage`.
|
|
444
|
+
- `compaction` → its complete system checkpoint followed by a `CompactionSummaryMessage`. Pre-compaction system messages are folded into that checkpoint rather than replayed from the retained range.
|
|
409
445
|
- `branch_summary` → `BranchSummaryMessage`.
|
|
410
446
|
- `custom_message` → `CustomMessage`.
|
|
411
|
-
- `custom`, model/thinking changes, labels, and session-info entries → no message.
|
|
447
|
+
- `usage`, `custom`, model/thinking changes, labels, and session-info entries → no message.
|
|
412
448
|
|
|
413
449
|
Use `convertToLlm()` from `@astralyn/pi` when provider-ready `Message[]` are required. It passes base user, assistant, and tool-result messages through; it converts Pi-specific context roles to user messages and omits `bashExecution` messages marked `excludeFromContext`.
|
|
414
450
|
|
|
@@ -435,6 +471,9 @@ for (const line of lines) {
|
|
|
435
471
|
case "branch_summary":
|
|
436
472
|
console.log(`[${entry.id}] Branch from ${entry.fromId}`);
|
|
437
473
|
break;
|
|
474
|
+
case "usage":
|
|
475
|
+
console.log(`[${entry.id}] Usage (${entry.kind}): ${entry.usage.totalTokens} tokens`);
|
|
476
|
+
break;
|
|
438
477
|
case "custom":
|
|
439
478
|
console.log(`[${entry.id}] Custom (${entry.customType}): ${JSON.stringify(entry.data)}`);
|
|
440
479
|
break;
|
|
@@ -463,16 +502,16 @@ Import `SessionManager` and its session types from `@astralyn/pi` as shown above
|
|
|
463
502
|
- `SessionManager.create(cwd: string, sessionDir?: string, options?: NewSessionOptions): SessionManager` — create a persisted session.
|
|
464
503
|
- `SessionManager.open(path: string, sessionDir?: string, cwdOverride?: string): SessionManager` — open a session file. `cwdOverride` takes precedence over the header's `cwd`.
|
|
465
504
|
- `SessionManager.continueRecent(cwd: string, sessionDir?: string): SessionManager` — open the most recent session or create one.
|
|
466
|
-
- `SessionManager.inMemory(cwd?: string, options?: NewSessionOptions): SessionManager` — create a non-persisted session.
|
|
505
|
+
- `SessionManager.inMemory(cwd?: string, options?: NewSessionOptions, entries?: FileEntry[]): SessionManager` — create a non-persisted session, optionally initialized from entries.
|
|
467
506
|
- `SessionManager.forkFrom(sourcePath: string, targetCwd: string, sessionDir?: string, options?: NewSessionOptions): SessionManager` — fork into another working directory.
|
|
468
507
|
|
|
469
508
|
### Static Listing Methods
|
|
470
509
|
|
|
471
|
-
The optional progress callback has type `(loaded: number, total: number) => void`.
|
|
510
|
+
The optional progress callback has type `SessionListProgress`: `(loaded: number, total: number, partialSessions?: readonly SessionInfo[]) => void`. Periodic updates carry the sessions loaded so far, sorted by activity. The optional `AbortSignal` cancels outstanding transcript reads.
|
|
472
511
|
|
|
473
|
-
- `SessionManager.list(cwd: string, sessionDir?: string, onProgress?:
|
|
474
|
-
- `SessionManager.listAll(onProgress?:
|
|
475
|
-
- `SessionManager.listAll(sessionDir?: string, onProgress?:
|
|
512
|
+
- `SessionManager.list(cwd: string, sessionDir?: string, onProgress?: SessionListProgress, signal?: AbortSignal): Promise<SessionInfo[]>` — list sessions for a directory.
|
|
513
|
+
- `SessionManager.listAll(onProgress?: SessionListProgress, signal?: AbortSignal): Promise<SessionInfo[]>` — list all default session directories.
|
|
514
|
+
- `SessionManager.listAll(sessionDir?: string, onProgress?: SessionListProgress, signal?: AbortSignal): Promise<SessionInfo[]>` — list one supplied session directory. This is an overload of the previous form.
|
|
476
515
|
|
|
477
516
|
### Instance Methods — Session Management
|
|
478
517
|
|
package/docs/sessions.md
CHANGED
|
@@ -33,6 +33,7 @@ For the JSONL file format and SessionManager API, see [Session Format](session-f
|
|
|
33
33
|
| `/compact [prompt]` | Summarize older context; see [Compaction](compaction.md) |
|
|
34
34
|
| `/export [file]` | Export session to HTML |
|
|
35
35
|
| `/share` | Upload as private GitHub gist with shareable HTML link |
|
|
36
|
+
| `/bug [description]` | Report a bug to the Pi developers; see [Reporting Bugs](#reporting-bugs) |
|
|
36
37
|
|
|
37
38
|
## Resuming and Deleting Sessions
|
|
38
39
|
|
|
@@ -68,7 +69,7 @@ Named sessions are easier to find in `/resume` and `pi -r`.
|
|
|
68
69
|
|
|
69
70
|
## Branching with `/tree`
|
|
70
71
|
|
|
71
|
-
Sessions are stored as trees. Every entry has an `id` and `parentId`, and the current position is the active leaf. `/tree` lets you jump to any previous point and continue from there without creating a new file.
|
|
72
|
+
Sessions are stored as trees. Every entry has an `id` and `parentId`, and the current position is the active leaf. `/tree` lets you jump to any previous point and continue from there without creating a new file. Selecting a point while the model is responding cancels that response. Navigation cannot proceed while compaction or another tree navigation is still running; wait for it to finish and retry.
|
|
72
73
|
|
|
73
74
|
<p align="center"><img src="images/tree-view.png" alt="Tree View" width="600"></p>
|
|
74
75
|
|
|
@@ -138,6 +139,32 @@ When prompted, choose one of:
|
|
|
138
139
|
|
|
139
140
|
See [Compaction](compaction.md) for branch summarization internals and extension hooks.
|
|
140
141
|
|
|
142
|
+
## Reporting Bugs
|
|
143
|
+
|
|
144
|
+
`/bug [description]` collects a bug report for the Pi developers. The report is not shared publicly. The dialog asks for an optional description and whether to include the session transcript. If you decline the transcript, pi offers to have the current model write a summary of what went wrong instead; the transcript is sent to your provider with your credentials, and only the summary is attached.
|
|
145
|
+
|
|
146
|
+
The last step chooses where the report goes:
|
|
147
|
+
|
|
148
|
+
- **Upload Report** sends it to the Pi developers through `radius.pi.dev`. No login is required; if you are logged into Radius, the report is attributed to your account so the developers can follow up. If the upload fails, pi offers to export the zip instead.
|
|
149
|
+
- **Export as Zip** writes a zip archive to the current directory. Attach it to an issue or send it to the developers yourself.
|
|
150
|
+
|
|
151
|
+
Both contain the same files:
|
|
152
|
+
|
|
153
|
+
| File | Content |
|
|
154
|
+
|------|---------|
|
|
155
|
+
| `report.json` | pi version, runtime, OS, terminal, current model and provider configuration, loaded extensions, and settings. API keys, header values, URL credentials, and the analytics tracking id are never included. |
|
|
156
|
+
| `diagnostics.json` | Provider and runtime error diagnostics attached to assistant messages across the whole session (failed or aborted turns, retries, error messages), plus any recorded crashes. Always included; message content is not. |
|
|
157
|
+
| `session.jsonl` | The current branch of the session, only when you chose to include it. It contains file contents and command output read during the session. |
|
|
158
|
+
| `summary.md` | The model-written summary, only when you chose to generate one. |
|
|
159
|
+
|
|
160
|
+
Each report has a UUID. pi shows it after upload or export and records it in the session as a `pi.bug-report` entry so you can refer to it later.
|
|
161
|
+
|
|
162
|
+
Set `PI_RADIUS_GATEWAY` to upload to a different Radius deployment.
|
|
163
|
+
|
|
164
|
+
### Crashes
|
|
165
|
+
|
|
166
|
+
When pi exits because of an uncaught exception or a fatal runtime error, it stores the error message and stack trace in `~/.pi/agent/crashes.json` (the newest five). The next interactive start shows a warning once; running `/bug` attaches the stored crashes to `diagnostics.json` and removes the file after the report is uploaded or exported. Resume the crashed session with `pi -r` first if you want the transcript in the report.
|
|
167
|
+
|
|
141
168
|
## Session Format
|
|
142
169
|
|
|
143
170
|
Session files are JSONL and contain message entries, model changes, thinking-level changes, labels, compactions, branch summaries, and extension entries.
|
package/docs/settings.md
CHANGED
|
@@ -32,8 +32,31 @@ Use `/trust` in interactive mode to save a project trust decision for future ses
|
|
|
32
32
|
| `defaultThinkingLevel` | string | - | Global fallback: `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`, or `"max"` |
|
|
33
33
|
| `modelThinkingLevels` | object | - | Per-model default thinking levels keyed by `provider/modelId`; set through `/thinking` Ctrl+S or `/settings` |
|
|
34
34
|
| `hideThinkingBlock` | boolean | `false` | Hide thinking blocks in output |
|
|
35
|
-
| `showCacheMissNotices` | boolean | `false` | Show transcript notices for significant prompt-cache misses
|
|
35
|
+
| `showCacheMissNotices` | boolean | `false` | Show transcript notices for significant prompt-cache misses, successful cache-warming usage, compaction or branch-summary usage, and provider recovery diagnostics such as dropped Anthropic thinking blocks |
|
|
36
36
|
| `thinkingBudgets` | object | - | Custom token budgets per thinking level. Anthropic, Google, and Bedrock use these natively. OpenAI-compatible models use them when `compat.thinkingTokenBudgetField` (or `supportsThinkingTokenBudget`) is set. |
|
|
37
|
+
| `cacheWarming` | string | `"streaming"` | Prompt cache-warming mode: `"off"`, `"streaming"`, or `"idle"`. Global setting only. |
|
|
38
|
+
|
|
39
|
+
#### Cache Warming
|
|
40
|
+
|
|
41
|
+
Providers drop a prompt cache entry after a period of inactivity, so the first request after a pause pays full input price again. Cache warming re-sends the last request with a one-token output budget shortly before expiry:
|
|
42
|
+
|
|
43
|
+
- `"off"` disables warming.
|
|
44
|
+
- `"streaming"` protects expensive prefixes during long tool executions and stops as soon as the agent settles.
|
|
45
|
+
- `"idle"` also considers refreshes while waiting for your next prompt, using a fixed 15% continuation probability measured from real usage.
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"cacheWarming": "idle"
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A refresh is sent only when the expected avoided cache-miss cost, minus the cost of the refresh, leaves at least $0.05 of expected savings. Active agent runs use 100% continuation probability. `/session` shows the next decision, continuation probability, expected savings, threshold, and estimated costs. When cache miss notices are enabled, each successful refresh appears in the transcript with its cost; notices identify extension overrides.
|
|
54
|
+
|
|
55
|
+
Warming stops when the context changes (model switch, compaction, branch navigation). Idle warming stops no later than 30 minutes after the last real provider request; warming during an active agent run stops after 60 minutes. Extensions can override each decision through the [`cache_warming_decision`](extensions.md#cache_warming_decision) event.
|
|
56
|
+
|
|
57
|
+
Each refresh is billed as a cache read of the full context plus one output token. Usage and cost show up in session totals but never enter model context. Pi schedules candidates at 90% of the cache lifetime while leaving at least ten seconds before expiry.
|
|
58
|
+
|
|
59
|
+
Warming needs a known cache lifetime for the model and the retention tier the request used (`short`, or `long` with `PI_CACHE_RETENTION=long`). The built-in catalog carries lifetimes for direct Anthropic; custom models and other providers can declare theirs with `promptCache` in `models.json` (see [Prompt Cache Lifetimes](models.md#prompt-cache-lifetimes)). Claude models that use budget-based rather than adaptive thinking are skipped while thinking is on, because Anthropic derives the thinking budget from `max_tokens` and keys the message cache on it, so a one-token request cannot reproduce the entry.
|
|
37
60
|
|
|
38
61
|
Selecting a model or thinking level with Enter changes only the current session. Ctrl+S in `/model` saves `defaultProvider` and `defaultModel`; Ctrl+S in `/thinking` saves the level under `modelThinkingLevels` for the active model. A per-model value takes precedence over `defaultThinkingLevel`.
|
|
39
62
|
|
|
@@ -119,7 +142,9 @@ Version checks read the latest `@astralyn/pi` version from npm. Set `PI_SKIP_VER
|
|
|
119
142
|
|---------|------|---------|-------------|
|
|
120
143
|
| `compaction.enabled` | boolean | `true` | Enable auto-compaction |
|
|
121
144
|
| `compaction.triggerPercent` | number | `85` | Percentage of the context window that triggers auto-compaction (clamped to 20–95) |
|
|
122
|
-
| `compaction.
|
|
145
|
+
| `compaction.reserveTokens` | number | derived | Fixed reserve below the context window; overrides `triggerPercent` |
|
|
146
|
+
| `compaction.keepRecentTokens` | number | `20000` | Recent-message retention target, capped at half the trigger line when the reserve is derived |
|
|
147
|
+
| `compaction.modelOverrides` | object | - | Per-model `reserveTokens` / `keepRecentTokens` overrides keyed by exact `"provider/modelId"` |
|
|
123
148
|
|
|
124
149
|
```json
|
|
125
150
|
{
|
|
@@ -131,9 +156,34 @@ Version checks read the latest `@astralyn/pi` version from npm. Set `PI_SKIP_VER
|
|
|
131
156
|
}
|
|
132
157
|
```
|
|
133
158
|
|
|
134
|
-
|
|
159
|
+
Compaction triggers at `contextWindow − reserveTokens`. Unless `reserveTokens` is set, the reserve is derived from `triggerPercent` for the active model's window, so large-window models compact at 85% usage instead of upstream's ~98%. Setting `reserveTokens` restores a fixed reserve.
|
|
160
|
+
|
|
161
|
+
The retention target shrinks with a derived reserve without changing the saved settings. Whole messages and tool-call/result groups can exceed the retention target. See [Compaction](compaction.md#how-it-works) for the budget rules and examples.
|
|
162
|
+
|
|
163
|
+
#### Per-model compaction overrides
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"compaction": {
|
|
168
|
+
"enabled": true,
|
|
169
|
+
"triggerPercent": 85,
|
|
170
|
+
"keepRecentTokens": 20000,
|
|
171
|
+
"modelOverrides": {
|
|
172
|
+
"some-provider/big-model": {
|
|
173
|
+
"keepRecentTokens": 150000
|
|
174
|
+
},
|
|
175
|
+
"local/small-model": {
|
|
176
|
+
"reserveTokens": 2048,
|
|
177
|
+
"keepRecentTokens": 4096
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Keys match exact, case-sensitive `provider/modelId` values, not names or glob patterns. Model IDs may contain slashes (for example, `openrouter/anthropic/claude-sonnet-4`).
|
|
135
185
|
|
|
136
|
-
|
|
186
|
+
Each token setting resolves independently: matching model override → ordinary `compaction` setting → built-in default. A model override's `reserveTokens` replaces the percentage-derived reserve for that model only. Token values must be non-negative safe integers. Invalid values in the matching model override produce an error when read; only omitted fields fall back to the ordinary setting. Model override entries must be objects. Invalid ordinary token settings produce an error when read, even if the active model has a valid override. Zero is accepted and keeps no recent messages beyond the cut point's own message group. `enabled` and `triggerPercent` stay global.
|
|
137
187
|
|
|
138
188
|
### Branch Summary
|
|
139
189
|
|
|
@@ -149,10 +199,13 @@ Retention and summary budgets shrink for small windows or low trigger percentage
|
|
|
149
199
|
| `retry.enabled` | boolean | `true` | Enable automatic agent-level retry on transient errors |
|
|
150
200
|
| `retry.maxRetries` | number | `3` | Maximum agent-level retry attempts |
|
|
151
201
|
| `retry.baseDelayMs` | number | `2000` | Base delay for agent-level exponential backoff (2s, 4s, 8s) |
|
|
202
|
+
| `retry.maxAgentDelayMs` | number | `60000` | Max agent-level retry delay (60s) |
|
|
152
203
|
| `retry.provider.timeoutMs` | number | SDK default | Provider/SDK request timeout in milliseconds |
|
|
153
204
|
| `retry.provider.maxRetries` | number | `0` | Provider/SDK retry attempts |
|
|
154
205
|
| `retry.provider.maxRetryDelayMs` | number | `60000` | Max server-requested delay before failing (60s) |
|
|
155
206
|
|
|
207
|
+
Agent-level retries use exponential backoff capped by `retry.maxAgentDelayMs`, so long retry runs stay responsive after prolonged outages.
|
|
208
|
+
|
|
156
209
|
When a provider requests a retry delay longer than `retry.provider.maxRetryDelayMs`, the request fails immediately with an informative error instead of waiting silently. Set it to `0` to disable the limit.
|
|
157
210
|
|
|
158
211
|
Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explicitly needed. Setting it above `0` can make SDK/provider retries handle out-of-usage-limit errors before Pi sees them, which may block the agent until the provider quota resets in some circumstances.
|
|
@@ -163,6 +216,7 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
|
|
|
163
216
|
"enabled": true,
|
|
164
217
|
"maxRetries": 3,
|
|
165
218
|
"baseDelayMs": 2000,
|
|
219
|
+
"maxAgentDelayMs": 60000,
|
|
166
220
|
"provider": {
|
|
167
221
|
"timeoutMs": 3600000,
|
|
168
222
|
"maxRetries": 0,
|
package/docs/termux.md
CHANGED
|
@@ -96,7 +96,6 @@ termux-camera-photo out.jpg # Take photo
|
|
|
96
96
|
## Limitations
|
|
97
97
|
|
|
98
98
|
- **No image clipboard**: Termux clipboard API only supports text
|
|
99
|
-
- **No native binaries**: Some optional native dependencies (like the clipboard module) are unavailable on Android ARM64 and are skipped during installation
|
|
100
99
|
- **Storage access**: To access files in `/storage/emulated/0` (Downloads, etc.), run `termux-setup-storage` once to grant permissions
|
|
101
100
|
|
|
102
101
|
## Troubleshooting
|
package/docs/tui.md
CHANGED
|
@@ -803,6 +803,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
803
803
|
|
|
804
804
|
Pass `undefined` to `ctx.ui.setEditorComponent()` to restore Pi's default editor.
|
|
805
805
|
|
|
806
|
+
Custom editors keep standalone status rows by default. Pass `{ embedWorkingStatus: true }` as the fourth `CustomEditor` constructor argument to embed the working, compaction, branch summarization, and retry spinners in the editor border instead.
|
|
807
|
+
|
|
806
808
|
**Examples:** [modal-editor.ts](../examples/extensions/modal-editor.ts)
|
|
807
809
|
|
|
808
810
|
## Debug Logging
|
package/docs/usage.md
CHANGED
|
@@ -56,6 +56,7 @@ Type `/` in the editor to open command completion. Extensions can register custo
|
|
|
56
56
|
| `/export [file]` | Export session to HTML or JSONL |
|
|
57
57
|
| `/import <file>` | Import and resume a session from a JSONL file |
|
|
58
58
|
| `/share` | Upload as private GitHub gist with shareable HTML link |
|
|
59
|
+
| `/bug [description]` | Report a bug to the Pi developers; see [Sessions](sessions.md#reporting-bugs) |
|
|
59
60
|
| `/reload` | Reload keybindings, extensions, skills, prompts, themes, and context files |
|
|
60
61
|
| `/hotkeys` | Show all keyboard shortcuts |
|
|
61
62
|
| `/changelog` | Display version history |
|
|
@@ -37,7 +37,6 @@ cp permission-gate.ts ~/.pi/agent/extensions/
|
|
|
37
37
|
| `tool-override.ts` | Override built-in tools (e.g., add logging/access control to `read`) |
|
|
38
38
|
| `bash-spawn-hook.ts` | Wraps bash to adjust the command, cwd, and environment before execution |
|
|
39
39
|
| `dynamic-tools.ts` | Register tools after startup (`session_start`) and at runtime via command, with prompt snippets and tool-specific prompt guidelines |
|
|
40
|
-
| `kimi-deferred-tools.ts` | Search for and progressively activate tools for Kimi's deferred-tool loading protocol |
|
|
41
40
|
| `structured-output.ts` | Final structured-output tool that returns `terminate: true` so the agent can end on the tool call |
|
|
42
41
|
| `built-in-tool-renderer.ts` | Custom compact rendering for built-in tools (read, bash, edit, write) while keeping original behavior |
|
|
43
42
|
| `minimal-mode.ts` | Override built-in tool rendering for minimal display (only tool calls, no output in collapsed mode) |
|
|
@@ -28,9 +28,11 @@ import {
|
|
|
28
28
|
type Api,
|
|
29
29
|
type AssistantMessage,
|
|
30
30
|
type AssistantMessageEventStream,
|
|
31
|
-
type Context,
|
|
32
31
|
calculateCost,
|
|
32
|
+
collapseSystemMessages,
|
|
33
33
|
createAssistantMessageEventStream,
|
|
34
|
+
getCurrentSystemPrompt,
|
|
35
|
+
getCurrentTools,
|
|
34
36
|
type ImageContent,
|
|
35
37
|
type Message,
|
|
36
38
|
type Model,
|
|
@@ -43,6 +45,7 @@ import {
|
|
|
43
45
|
type Tool,
|
|
44
46
|
type ToolCall,
|
|
45
47
|
type ToolResultMessage,
|
|
48
|
+
type TranscriptContext,
|
|
46
49
|
} from "@earendil-works/pi-ai";
|
|
47
50
|
|
|
48
51
|
// =============================================================================
|
|
@@ -334,10 +337,15 @@ function mapStopReason(reason: string): StopReason {
|
|
|
334
337
|
|
|
335
338
|
function streamCustomAnthropic(
|
|
336
339
|
model: Model<Api>,
|
|
337
|
-
context:
|
|
340
|
+
context: TranscriptContext,
|
|
338
341
|
options?: SimpleStreamOptions,
|
|
339
342
|
): AssistantMessageEventStream {
|
|
340
343
|
const stream = createAssistantMessageEventStream();
|
|
344
|
+
// The transcript carries the prompt and tools in its system messages. This provider sends
|
|
345
|
+
// one top-level system prompt, so fold later system messages into the leading one first.
|
|
346
|
+
const transcript = collapseSystemMessages(context);
|
|
347
|
+
const systemPrompt = getCurrentSystemPrompt(transcript.messages);
|
|
348
|
+
const tools = getCurrentTools(transcript.messages);
|
|
341
349
|
|
|
342
350
|
(async () => {
|
|
343
351
|
const output: AssistantMessage = {
|
|
@@ -393,7 +401,7 @@ function streamCustomAnthropic(
|
|
|
393
401
|
// Build request params
|
|
394
402
|
const params: MessageCreateParamsStreaming = {
|
|
395
403
|
model: model.id,
|
|
396
|
-
messages: convertMessages(
|
|
404
|
+
messages: convertMessages(transcript.messages, isOAuth, tools),
|
|
397
405
|
max_tokens: options?.maxTokens || Math.floor(model.maxTokens / 3),
|
|
398
406
|
stream: true,
|
|
399
407
|
};
|
|
@@ -407,25 +415,25 @@ function streamCustomAnthropic(
|
|
|
407
415
|
cache_control: { type: "ephemeral" },
|
|
408
416
|
},
|
|
409
417
|
];
|
|
410
|
-
if (
|
|
418
|
+
if (systemPrompt) {
|
|
411
419
|
params.system.push({
|
|
412
420
|
type: "text",
|
|
413
|
-
text: sanitizeSurrogates(
|
|
421
|
+
text: sanitizeSurrogates(systemPrompt),
|
|
414
422
|
cache_control: { type: "ephemeral" },
|
|
415
423
|
});
|
|
416
424
|
}
|
|
417
|
-
} else if (
|
|
425
|
+
} else if (systemPrompt) {
|
|
418
426
|
params.system = [
|
|
419
427
|
{
|
|
420
428
|
type: "text",
|
|
421
|
-
text: sanitizeSurrogates(
|
|
429
|
+
text: sanitizeSurrogates(systemPrompt),
|
|
422
430
|
cache_control: { type: "ephemeral" },
|
|
423
431
|
},
|
|
424
432
|
];
|
|
425
433
|
}
|
|
426
434
|
|
|
427
|
-
if (
|
|
428
|
-
params.tools = convertTools(
|
|
435
|
+
if (tools.length > 0) {
|
|
436
|
+
params.tools = convertTools(tools, isOAuth);
|
|
429
437
|
}
|
|
430
438
|
|
|
431
439
|
// Handle thinking/reasoning
|
|
@@ -474,9 +482,7 @@ function streamCustomAnthropic(
|
|
|
474
482
|
output.content.push({
|
|
475
483
|
type: "toolCall",
|
|
476
484
|
id: event.content_block.id,
|
|
477
|
-
name: isOAuth
|
|
478
|
-
? fromClaudeCodeName(event.content_block.name, context.tools)
|
|
479
|
-
: event.content_block.name,
|
|
485
|
+
name: isOAuth ? fromClaudeCodeName(event.content_block.name, tools) : event.content_block.name,
|
|
480
486
|
arguments: {},
|
|
481
487
|
partialJson: "",
|
|
482
488
|
index: event.index,
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
type Api,
|
|
15
15
|
type AssistantMessageEventStream,
|
|
16
16
|
anthropicMessagesApi,
|
|
17
|
-
type Context,
|
|
18
17
|
createAssistantMessageEventStream,
|
|
19
18
|
type Model,
|
|
20
19
|
type OAuthCredentials,
|
|
@@ -22,6 +21,7 @@ import {
|
|
|
22
21
|
openAIResponsesApi,
|
|
23
22
|
type SimpleStreamOptions,
|
|
24
23
|
type ThinkingLevelMap,
|
|
24
|
+
type TranscriptContext,
|
|
25
25
|
} from "@earendil-works/pi-ai/compat";
|
|
26
26
|
|
|
27
27
|
// =============================================================================
|
|
@@ -306,7 +306,7 @@ async function refreshGitLabToken(credentials: OAuthCredentials, signal: AbortSi
|
|
|
306
306
|
|
|
307
307
|
export function streamGitLabDuo(
|
|
308
308
|
model: Model<Api>,
|
|
309
|
-
context:
|
|
309
|
+
context: TranscriptContext,
|
|
310
310
|
options?: SimpleStreamOptions,
|
|
311
311
|
): AssistantMessageEventStream {
|
|
312
312
|
const stream = createAssistantMessageEventStream();
|