@averyyy/pi-coding-agent 0.80.3-piclient.8 → 0.80.6-piclient.10
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 +104 -0
- package/README.md +5 -3
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +4 -4
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts +4 -2
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/core/agent-session.d.ts +21 -5
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +100 -30
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +13 -5
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/cache-stats.d.ts +49 -0
- package/dist/core/cache-stats.d.ts.map +1 -0
- package/dist/core/cache-stats.js +101 -0
- package/dist/core/cache-stats.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +1 -2
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +56 -81
- package/dist/core/compaction/compaction.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/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +6 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +6 -3
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +43 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +33 -11
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +22 -3
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +8 -3
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +10 -9
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-registry.d.ts +4 -6
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +39 -9
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +10 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +14 -17
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +75 -28
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-client-runtime-update.d.ts +14 -0
- package/dist/core/pi-client-runtime-update.d.ts.map +1 -0
- package/dist/core/pi-client-runtime-update.js +27 -0
- package/dist/core/pi-client-runtime-update.js.map +1 -0
- package/dist/core/pi-server-client.d.ts.map +1 -1
- package/dist/core/pi-server-client.js +122 -5
- package/dist/core/pi-server-client.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +0 -10
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/resource-loader.d.ts +2 -2
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +6 -7
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +8 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +20 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +97 -68
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +9 -3
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +10 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts +1 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +3 -3
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +2 -2
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +2 -2
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +34 -3
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +280 -25
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts +19 -0
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-entry.js +52 -0
- package/dist/modes/interactive/components/custom-entry.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +4 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +4 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +9 -2
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +3 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +17 -6
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +12 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +5 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +49 -12
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +16 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +368 -97
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -0
- package/dist/modes/interactive/theme/light.json +1 -0
- package/dist/modes/interactive/theme/theme-schema.json +6 -2
- package/dist/modes/interactive/theme/theme.d.ts +3 -2
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +10 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +6 -6
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -3
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +4 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts +2 -2
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +71 -17
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +1 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +13 -0
- package/dist/utils/clipboard.js.map +1 -1
- package/docs/custom-provider.md +6 -3
- package/docs/extensions.md +213 -18
- package/docs/keybindings.md +1 -0
- package/docs/models.md +51 -8
- package/docs/packages.md +2 -2
- package/docs/providers.md +3 -0
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +15 -5
- package/docs/sdk.md +51 -1
- package/docs/session-format.md +18 -8
- package/docs/settings.md +3 -2
- package/docs/themes.md +5 -3
- package/docs/tui.md +1 -1
- package/docs/usage.md +3 -2
- package/examples/extensions/README.md +1 -0
- 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/entry-renderer.ts +41 -0
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/preset.ts +2 -2
- package/examples/extensions/question.ts +1 -0
- package/examples/extensions/reload-runtime.ts +2 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/12-full-control.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/package.json +8 -4
package/docs/extensions.md
CHANGED
|
@@ -47,6 +47,7 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
|
|
|
47
47
|
- [ExtensionAPI Methods](#extensionapi-methods)
|
|
48
48
|
- [State Management](#state-management)
|
|
49
49
|
- [Custom Tools](#custom-tools)
|
|
50
|
+
- [Dynamic Tool Loading](#dynamic-tool-loading)
|
|
50
51
|
- [Custom UI](#custom-ui)
|
|
51
52
|
- [Error Handling](#error-handling)
|
|
52
53
|
- [Mode Behavior](#mode-behavior)
|
|
@@ -294,6 +295,7 @@ user sends prompt ────────────────────
|
|
|
294
295
|
│ │ │ │
|
|
295
296
|
│ ├─► turn_start │ │
|
|
296
297
|
│ ├─► context (can modify messages) │ │
|
|
298
|
+
│ ├─► before_provider_headers (can mutate headers) |
|
|
297
299
|
│ ├─► before_provider_request (can inspect or replace payload)
|
|
298
300
|
│ ├─► after_provider_response (status + headers, before stream consume)
|
|
299
301
|
│ │ │ │
|
|
@@ -306,7 +308,8 @@ user sends prompt ────────────────────
|
|
|
306
308
|
│ │ │ │
|
|
307
309
|
│ └─► turn_end │ │
|
|
308
310
|
│ │
|
|
309
|
-
|
|
311
|
+
├─► agent_end │
|
|
312
|
+
└─► agent_settled (no retry/compaction/follow-up left) │
|
|
310
313
|
│
|
|
311
314
|
user sends another prompt ◄────────────────────────────────┘
|
|
312
315
|
|
|
@@ -545,15 +548,19 @@ The `systemPromptOptions` field gives extensions access to the same structured d
|
|
|
545
548
|
|
|
546
549
|
Inside `before_agent_start`, `event.systemPrompt` and `ctx.getSystemPrompt()` both reflect the chained system prompt as of the current handler. Later `before_agent_start` handlers can still modify it again.
|
|
547
550
|
|
|
548
|
-
#### agent_start / agent_end
|
|
551
|
+
#### agent_start / agent_end / agent_settled
|
|
549
552
|
|
|
550
|
-
|
|
553
|
+
`agent_start` fires when a low-level agent run begins. `agent_end` fires when that run ends, but Pi may still auto-retry, auto-compact and retry, or continue with queued follow-up messages. Use `agent_settled` for status integrations that need to know Pi will not continue running automatically.
|
|
551
554
|
|
|
552
555
|
```typescript
|
|
553
556
|
pi.on("agent_start", async (_event, ctx) => {});
|
|
554
557
|
|
|
555
558
|
pi.on("agent_end", async (event, ctx) => {
|
|
556
|
-
// event.messages - messages from this
|
|
559
|
+
// event.messages - messages from this low-level run
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
pi.on("agent_settled", async (_event, ctx) => {
|
|
563
|
+
// ctx.isIdle() is true here unless another extension started a new run.
|
|
557
564
|
});
|
|
558
565
|
```
|
|
559
566
|
|
|
@@ -643,6 +650,24 @@ pi.on("context", async (event, ctx) => {
|
|
|
643
650
|
});
|
|
644
651
|
```
|
|
645
652
|
|
|
653
|
+
#### before_provider_headers
|
|
654
|
+
|
|
655
|
+
Fired after the outgoing HTTP headers are assembled. Use it to add, override, or remove request headers.
|
|
656
|
+
|
|
657
|
+
Handlers mutate `event.headers` in place. Set a key to a string to add or override it, or to `null` to delete it.
|
|
658
|
+
|
|
659
|
+
```typescript
|
|
660
|
+
pi.on("before_provider_headers", (event, ctx) => {
|
|
661
|
+
// Add or override — e.g. a session id for gateway tracing/attribution
|
|
662
|
+
event.headers["x-session-id"] = ctx.sessionManager.getSessionId();
|
|
663
|
+
|
|
664
|
+
// Drop a tracking header pi adds for this call
|
|
665
|
+
event.headers["X-OpenRouter-Title"] = null;
|
|
666
|
+
});
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
Runs once per provider request; retries reuse the same headers rather than re-firing the hook.
|
|
670
|
+
|
|
646
671
|
#### before_provider_request
|
|
647
672
|
|
|
648
673
|
Fired after the provider-specific payload is built, right before the request is sent. Handlers run in extension load order. Returning `undefined` keeps the payload unchanged. Returning any other value replaces the payload for later handlers and for the actual request.
|
|
@@ -944,9 +969,10 @@ Read-only access to session state. See [Session Format](session-format.md) for t
|
|
|
944
969
|
For `tool_call`, this state is synchronized through the current assistant message before handlers run. In parallel tool execution mode it is still not guaranteed to include sibling tool results from the same assistant message.
|
|
945
970
|
|
|
946
971
|
```typescript
|
|
947
|
-
ctx.sessionManager.getEntries()
|
|
948
|
-
ctx.sessionManager.getBranch()
|
|
949
|
-
ctx.sessionManager.
|
|
972
|
+
ctx.sessionManager.getEntries() // All entries
|
|
973
|
+
ctx.sessionManager.getBranch() // Current branch
|
|
974
|
+
ctx.sessionManager.buildContextEntries() // Active branch entries with compaction applied
|
|
975
|
+
ctx.sessionManager.getLeafId() // Current leaf entry ID
|
|
950
976
|
```
|
|
951
977
|
|
|
952
978
|
### ctx.modelRegistry / ctx.model
|
|
@@ -980,7 +1006,7 @@ pi.on("tool_result", async (event, ctx) => {
|
|
|
980
1006
|
|
|
981
1007
|
### ctx.isIdle() / ctx.abort() / ctx.hasPendingMessages()
|
|
982
1008
|
|
|
983
|
-
Control flow helpers.
|
|
1009
|
+
Control flow helpers. `ctx.isIdle()` is false while Pi is processing an agent run, automatic retry, auto-compaction retry, or queued continuation.
|
|
984
1010
|
|
|
985
1011
|
### ctx.shutdown()
|
|
986
1012
|
|
|
@@ -1062,7 +1088,7 @@ This reports the current base prompt inputs. It does not include per-turn `befor
|
|
|
1062
1088
|
|
|
1063
1089
|
### ctx.waitForIdle()
|
|
1064
1090
|
|
|
1065
|
-
Wait for the agent to
|
|
1091
|
+
Wait for the agent to fully settle, including automatic retries, auto-compaction retries, and queued continuations:
|
|
1066
1092
|
|
|
1067
1093
|
```typescript
|
|
1068
1094
|
pi.registerCommand("my-cmd", {
|
|
@@ -1243,7 +1269,7 @@ Run the same reload flow as `/reload`.
|
|
|
1243
1269
|
|
|
1244
1270
|
```typescript
|
|
1245
1271
|
pi.registerCommand("reload-runtime", {
|
|
1246
|
-
description: "Reload extensions, skills, prompts, and
|
|
1272
|
+
description: "Reload extensions, skills, prompts, themes, and context files",
|
|
1247
1273
|
handler: async (_args, ctx) => {
|
|
1248
1274
|
await ctx.reload();
|
|
1249
1275
|
return;
|
|
@@ -1271,7 +1297,7 @@ import { Type } from "typebox";
|
|
|
1271
1297
|
|
|
1272
1298
|
export default function (pi: ExtensionAPI) {
|
|
1273
1299
|
pi.registerCommand("reload-runtime", {
|
|
1274
|
-
description: "Reload extensions, skills, prompts, and
|
|
1300
|
+
description: "Reload extensions, skills, prompts, themes, and context files",
|
|
1275
1301
|
handler: async (_args, ctx) => {
|
|
1276
1302
|
await ctx.reload();
|
|
1277
1303
|
return;
|
|
@@ -1281,7 +1307,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1281
1307
|
pi.registerTool({
|
|
1282
1308
|
name: "reload_runtime",
|
|
1283
1309
|
label: "Reload Runtime",
|
|
1284
|
-
description: "Reload extensions, skills, prompts, and
|
|
1310
|
+
description: "Reload extensions, skills, prompts, themes, and context files",
|
|
1285
1311
|
parameters: Type.Object({}),
|
|
1286
1312
|
async execute() {
|
|
1287
1313
|
pi.sendUserMessage("/reload-runtime", { deliverAs: "followUp" });
|
|
@@ -1352,7 +1378,7 @@ pi.registerTool({
|
|
|
1352
1378
|
|
|
1353
1379
|
### pi.sendMessage(message, options?)
|
|
1354
1380
|
|
|
1355
|
-
Inject a custom message into the session.
|
|
1381
|
+
Inject a custom message into the session. Custom messages participate in LLM context. For durable TUI-only content that should not be sent to the LLM, use [`pi.appendEntry()`](#piappendentrycustomtype-data) with [`pi.registerEntryRenderer()`](#piregisterentryrenderercustomtype-renderer).
|
|
1356
1382
|
|
|
1357
1383
|
```typescript
|
|
1358
1384
|
pi.sendMessage({
|
|
@@ -1403,10 +1429,11 @@ See [send-user-message.ts](../examples/extensions/send-user-message.ts) for a co
|
|
|
1403
1429
|
|
|
1404
1430
|
### pi.appendEntry(customType, data?)
|
|
1405
1431
|
|
|
1406
|
-
Persist extension
|
|
1432
|
+
Persist extension data. Custom entries do NOT participate in LLM context. In interactive mode, they can also render inside the chat transcript when paired with `pi.registerEntryRenderer()`.
|
|
1407
1433
|
|
|
1408
1434
|
```typescript
|
|
1409
1435
|
pi.appendEntry("my-state", { count: 42 });
|
|
1436
|
+
pi.appendEntry("status-card", { title: "Indexed files", count: 17 });
|
|
1410
1437
|
|
|
1411
1438
|
// Restore on reload
|
|
1412
1439
|
pi.on("session_start", async (_event, ctx) => {
|
|
@@ -1524,7 +1551,27 @@ mode and would not execute if sent via `prompt`.
|
|
|
1524
1551
|
|
|
1525
1552
|
### pi.registerMessageRenderer(customType, renderer)
|
|
1526
1553
|
|
|
1527
|
-
Register a custom TUI renderer for messages with your `customType`. See [Custom UI](#custom-ui).
|
|
1554
|
+
Register a custom TUI renderer for custom messages with your `customType`. Custom messages are created with `pi.sendMessage()` and participate in LLM context. See [Custom UI](#custom-ui).
|
|
1555
|
+
|
|
1556
|
+
### pi.registerEntryRenderer(customType, renderer)
|
|
1557
|
+
|
|
1558
|
+
Register a custom TUI renderer for custom entries with your `customType`. Custom entries are created with `pi.appendEntry()` and do not participate in LLM context.
|
|
1559
|
+
|
|
1560
|
+
```typescript
|
|
1561
|
+
import { Box, Text } from "@earendil-works/pi-tui";
|
|
1562
|
+
|
|
1563
|
+
pi.registerEntryRenderer("status-card", (entry, { expanded }, theme) => {
|
|
1564
|
+
const data = entry.data as { title: string; count: number };
|
|
1565
|
+
const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
|
|
1566
|
+
box.addChild(new Text(`${theme.bold(data.title)}: ${data.count}`));
|
|
1567
|
+
if (expanded) {
|
|
1568
|
+
box.addChild(new Text(theme.fg("dim", JSON.stringify(data, null, 2))));
|
|
1569
|
+
}
|
|
1570
|
+
return box;
|
|
1571
|
+
});
|
|
1572
|
+
|
|
1573
|
+
pi.appendEntry("status-card", { title: "Indexed files", count: 17 });
|
|
1574
|
+
```
|
|
1528
1575
|
|
|
1529
1576
|
### pi.registerShortcut(shortcut, options)
|
|
1530
1577
|
|
|
@@ -1611,7 +1658,7 @@ if (model) {
|
|
|
1611
1658
|
Get or set the thinking level. Level is clamped to model capabilities (non-reasoning models always use "off"). Changes emit `thinking_level_select`.
|
|
1612
1659
|
|
|
1613
1660
|
```typescript
|
|
1614
|
-
const current = pi.getThinkingLevel(); // "off" | "minimal" | "low" | "medium" | "high" | "xhigh"
|
|
1661
|
+
const current = pi.getThinkingLevel(); // "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max"
|
|
1615
1662
|
pi.setThinkingLevel("high");
|
|
1616
1663
|
```
|
|
1617
1664
|
|
|
@@ -2183,6 +2230,143 @@ If a slot renderer is not defined or throws:
|
|
|
2183
2230
|
- `renderCall`: Shows the tool name
|
|
2184
2231
|
- `renderResult`: Shows raw text from `content`
|
|
2185
2232
|
|
|
2233
|
+
### Dynamic Tool Loading
|
|
2234
|
+
|
|
2235
|
+
Extensions can register many tools while keeping only a small initial set active. A tool can then add more tools with `pi.setActiveTools()` during execution. Pi detects purely additive changes, records the newly available tool names on that tool result, and applies the updated active set before the next model request.
|
|
2236
|
+
|
|
2237
|
+
This works with every model. Models with native deferred-loading support preserve the stable prompt prefix and load the new definitions at the tool-result position. Other models use the fallback described below.
|
|
2238
|
+
|
|
2239
|
+
The lifecycle is:
|
|
2240
|
+
|
|
2241
|
+
1. Register every tool with `pi.registerTool()` so it appears in `pi.getAllTools()`.
|
|
2242
|
+
2. Keep loader tools, such as `search_tools`, active and leave searchable tools inactive.
|
|
2243
|
+
3. During loader execution, call `pi.setActiveTools([...currentTools, ...matchingTools])`. The change must be additive: do not remove currently active tools in the same call.
|
|
2244
|
+
4. Pi records which tools were added on the loader's tool result.
|
|
2245
|
+
5. Before the next model response, Pi exposes the added definitions using native deferred loading when supported, or the normal active tool list otherwise.
|
|
2246
|
+
|
|
2247
|
+
You do not need to return provider-specific tool references or mark the loader as a special search tool. The active-tool change is the signal. Names passed to `pi.setActiveTools()` must already be registered; unknown names are ignored.
|
|
2248
|
+
|
|
2249
|
+
#### Models with native deferred loading
|
|
2250
|
+
|
|
2251
|
+
- **Anthropic**
|
|
2252
|
+
- **Models:** Sonnet, Opus, Fable version 4.5 or newer (without Haiku)
|
|
2253
|
+
- **Native representation:** Deferred definitions use `defer_loading`; the load point uses `tool_reference` content.
|
|
2254
|
+
- **OpenAI**
|
|
2255
|
+
- **Models:** `gpt-5.4` and newer family
|
|
2256
|
+
- **Native representation:** Pi adds completed client `tool_search_call` and `tool_search_output` items at the load point.
|
|
2257
|
+
|
|
2258
|
+
For a verified custom model or proxy, native handling can be enabled with `compat.supportsToolReferences: true` for `anthropic-messages`, or `compat.supportsToolSearch: true` for `openai-responses` and `openai-codex-responses`. Leave these disabled unless the endpoint and model accept the corresponding native protocol.
|
|
2259
|
+
|
|
2260
|
+
#### Fallback behavior
|
|
2261
|
+
|
|
2262
|
+
For all other models and providers, dynamic activation still works: Pi sends the complete current active tool list normally on the next request. The model can call the newly activated tools, but adding their definitions may invalidate the provider's cached prompt prefix.
|
|
2263
|
+
|
|
2264
|
+
Pi also uses this safe fallback when the active set is not purely additive, such as replacing one group of tools with another. Tool removals therefore work, but they do not use deferred loading.
|
|
2265
|
+
|
|
2266
|
+
For the best cache behavior, keep the loader tool active for the whole session and add tools instead of replacing the active set. Also note that activating a tool with `promptSnippet` or `promptGuidelines` rebuilds the system prompt; that system-prompt change can invalidate the prefix even when the provider supports deferred schemas. Lazily loaded tools should usually rely on their tool `description` and omit active-only prompt metadata.
|
|
2267
|
+
|
|
2268
|
+
#### Search tool example
|
|
2269
|
+
|
|
2270
|
+
The following extension registers two searchable tools, removes them from the initial active set, and keeps only `search_tools` as their loader. The example uses simple keyword matching, but the search implementation could use BM25, embeddings, a remote catalog, or project-specific routing.
|
|
2271
|
+
|
|
2272
|
+
```typescript
|
|
2273
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2274
|
+
import { Type } from "typebox";
|
|
2275
|
+
|
|
2276
|
+
const SEARCHABLE_TOOL_NAMES = new Set(["lookup_weather", "search_issues"]);
|
|
2277
|
+
|
|
2278
|
+
export default function (pi: ExtensionAPI) {
|
|
2279
|
+
pi.registerTool({
|
|
2280
|
+
name: "lookup_weather",
|
|
2281
|
+
label: "Lookup Weather",
|
|
2282
|
+
description: "Look up the current weather for a city",
|
|
2283
|
+
parameters: Type.Object({ city: Type.String() }),
|
|
2284
|
+
async execute(_toolCallId, params) {
|
|
2285
|
+
return {
|
|
2286
|
+
content: [{ type: "text", text: `Weather for ${params.city}: sunny` }],
|
|
2287
|
+
details: {},
|
|
2288
|
+
};
|
|
2289
|
+
},
|
|
2290
|
+
});
|
|
2291
|
+
|
|
2292
|
+
pi.registerTool({
|
|
2293
|
+
name: "search_issues",
|
|
2294
|
+
label: "Search Issues",
|
|
2295
|
+
description: "Search project issues by keyword",
|
|
2296
|
+
parameters: Type.Object({ query: Type.String() }),
|
|
2297
|
+
async execute(_toolCallId, params) {
|
|
2298
|
+
return {
|
|
2299
|
+
content: [{ type: "text", text: `No open issues matching ${params.query}` }],
|
|
2300
|
+
details: {},
|
|
2301
|
+
};
|
|
2302
|
+
},
|
|
2303
|
+
});
|
|
2304
|
+
|
|
2305
|
+
pi.registerTool({
|
|
2306
|
+
name: "search_tools",
|
|
2307
|
+
label: "Search Tools",
|
|
2308
|
+
description: "Search for and enable tools relevant to a task",
|
|
2309
|
+
promptSnippet: "Search for additional tools when the active tools cannot perform the task",
|
|
2310
|
+
promptGuidelines: [
|
|
2311
|
+
"Use search_tools when a task requires a capability that is not currently available.",
|
|
2312
|
+
],
|
|
2313
|
+
parameters: Type.Object({
|
|
2314
|
+
query: Type.String({ description: "Capability or task to search for" }),
|
|
2315
|
+
limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 10 })),
|
|
2316
|
+
}),
|
|
2317
|
+
async execute(_toolCallId, params) {
|
|
2318
|
+
const terms = params.query.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
2319
|
+
const matches = pi.getAllTools()
|
|
2320
|
+
.filter((tool) => SEARCHABLE_TOOL_NAMES.has(tool.name))
|
|
2321
|
+
.map((tool) => ({
|
|
2322
|
+
tool,
|
|
2323
|
+
score: terms.reduce(
|
|
2324
|
+
(score, term) =>
|
|
2325
|
+
score + (`${tool.name} ${tool.description}`.toLowerCase().includes(term) ? 1 : 0),
|
|
2326
|
+
0,
|
|
2327
|
+
),
|
|
2328
|
+
}))
|
|
2329
|
+
.filter((match) => match.score > 0)
|
|
2330
|
+
.sort((a, b) => b.score - a.score)
|
|
2331
|
+
.slice(0, params.limit ?? 3)
|
|
2332
|
+
.map((match) => match.tool.name);
|
|
2333
|
+
|
|
2334
|
+
if (matches.length === 0) {
|
|
2335
|
+
return {
|
|
2336
|
+
content: [{ type: "text", text: `No tools found for: ${params.query}` }],
|
|
2337
|
+
details: { matches: [] },
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
const active = pi.getActiveTools();
|
|
2342
|
+
const added = matches.filter((name) => !active.includes(name));
|
|
2343
|
+
pi.setActiveTools([...new Set([...active, ...added])]);
|
|
2344
|
+
|
|
2345
|
+
return {
|
|
2346
|
+
content: [{
|
|
2347
|
+
type: "text",
|
|
2348
|
+
text: added.length > 0
|
|
2349
|
+
? `Loaded tools: ${added.join(", ")}`
|
|
2350
|
+
: `Matching tools already active: ${matches.join(", ")}`,
|
|
2351
|
+
}],
|
|
2352
|
+
details: { matches, added },
|
|
2353
|
+
};
|
|
2354
|
+
},
|
|
2355
|
+
});
|
|
2356
|
+
|
|
2357
|
+
pi.on("session_start", () => {
|
|
2358
|
+
// Keep searchable tools registered but initially inactive. Preserve built-ins
|
|
2359
|
+
// and tools owned by other extensions, and keep the loader itself active.
|
|
2360
|
+
const initialTools = pi.getActiveTools().filter(
|
|
2361
|
+
(name) => !SEARCHABLE_TOOL_NAMES.has(name),
|
|
2362
|
+
);
|
|
2363
|
+
pi.setActiveTools([...new Set([...initialTools, "search_tools"])]);
|
|
2364
|
+
});
|
|
2365
|
+
}
|
|
2366
|
+
```
|
|
2367
|
+
|
|
2368
|
+
When `search_tools` adds a match, the model receives that definition on the immediately following request. On a native-capable model the definition is anchored after the search result without changing the initial tool-schema prefix. On other models it appears in the normal tool list on that same following request.
|
|
2369
|
+
|
|
2186
2370
|
## Custom UI
|
|
2187
2371
|
|
|
2188
2372
|
Extensions can interact with users via `ctx.ui` methods and customize how messages/tools render.
|
|
@@ -2528,9 +2712,9 @@ ctx.ui.setEditorComponent((tui, theme, keybindings) =>
|
|
|
2528
2712
|
|
|
2529
2713
|
See [tui.md](tui.md) Pattern 7 for a complete example with mode indicator.
|
|
2530
2714
|
|
|
2531
|
-
### Message Rendering
|
|
2715
|
+
### Message and Entry Rendering
|
|
2532
2716
|
|
|
2533
|
-
Register a custom renderer for messages with your `customType
|
|
2717
|
+
Register a custom renderer for messages with your `customType`. Use message renderers for content that should participate in LLM context:
|
|
2534
2718
|
|
|
2535
2719
|
```typescript
|
|
2536
2720
|
import { Text } from "@earendil-works/pi-tui";
|
|
@@ -2559,6 +2743,16 @@ pi.sendMessage({
|
|
|
2559
2743
|
});
|
|
2560
2744
|
```
|
|
2561
2745
|
|
|
2746
|
+
For TUI-only content that should not be sent to the LLM, render custom entries instead:
|
|
2747
|
+
|
|
2748
|
+
```typescript
|
|
2749
|
+
pi.registerEntryRenderer("my-card", (entry, options, theme) => {
|
|
2750
|
+
return new Text(theme.fg("accent", JSON.stringify(entry.data)));
|
|
2751
|
+
});
|
|
2752
|
+
|
|
2753
|
+
pi.appendEntry("my-card", { status: "done" });
|
|
2754
|
+
```
|
|
2755
|
+
|
|
2562
2756
|
### Theme Colors
|
|
2563
2757
|
|
|
2564
2758
|
All render functions receive a `theme` object. See [themes.md](themes.md) for creating custom themes and the full color palette.
|
|
@@ -2685,6 +2879,7 @@ All examples in [examples/extensions/](../examples/extensions/).
|
|
|
2685
2879
|
| `custom-provider-gitlab-duo/` | GitLab Duo integration | `registerProvider` with OAuth |
|
|
2686
2880
|
| **Messages & Communication** |||
|
|
2687
2881
|
| `message-renderer.ts` | Custom message rendering | `registerMessageRenderer`, `sendMessage` |
|
|
2882
|
+
| `entry-renderer.ts` | TUI-only custom entry rendering | `registerEntryRenderer`, `appendEntry` |
|
|
2688
2883
|
| `event-bus.ts` | Inter-extension events | `pi.events` |
|
|
2689
2884
|
| **Session Metadata** |||
|
|
2690
2885
|
| `session-name.ts` | Name sessions for selector | `setSessionName`, `getSessionName` |
|
package/docs/keybindings.md
CHANGED
|
@@ -119,6 +119,7 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `ctrl+1
|
|
|
119
119
|
| Keybinding id | Default | Description |
|
|
120
120
|
|--------|---------|-------------|
|
|
121
121
|
| `app.tools.expand` | `ctrl+o` | Collapse or expand tool output |
|
|
122
|
+
| `app.message.copy` | `ctrl+x` | Copy the last assistant message, or the selected message in `/tree` |
|
|
122
123
|
| `app.message.followUp` | `alt+enter` | Queue follow-up message |
|
|
123
124
|
| `app.message.dequeue` | `alt+up` | Restore queued messages to editor |
|
|
124
125
|
|
package/docs/models.md
CHANGED
|
@@ -139,7 +139,7 @@ Set `api` at provider level (default for all models) or model level (override pe
|
|
|
139
139
|
| `headers` | Custom headers (see value resolution below) |
|
|
140
140
|
| `authHeader` | Set `true` to add `Authorization: Bearer <apiKey>` automatically |
|
|
141
141
|
| `models` | Array of model configurations |
|
|
142
|
-
| `modelOverrides` | Per-model overrides for built-in models on this provider |
|
|
142
|
+
| `modelOverrides` | Per-model overrides for built-in or extension-registered models on this provider |
|
|
143
143
|
|
|
144
144
|
For providers with `models`, non-built-in provider configs need `baseUrl` and an `api` value at either provider or model level. `apiKey` is not required to load the file: models become available when auth is configured through `/login`/`auth.json`, CLI `--api-key`, or provider `apiKey`. If no auth is configured, the models load but stay unavailable in `/model` and `--list-models`.
|
|
145
145
|
|
|
@@ -205,22 +205,44 @@ If your command is slow, expensive, rate-limited, or should keep using a previou
|
|
|
205
205
|
| `input` | No | `["text"]` | Input types: `["text"]` or `["text", "image"]` |
|
|
206
206
|
| `contextWindow` | No | `128000` | Context window size in tokens |
|
|
207
207
|
| `maxTokens` | No | `16384` | Maximum output tokens |
|
|
208
|
-
| `cost` | No | all zeros |
|
|
208
|
+
| `cost` | No | all zeros | Per-million-token rates with optional request-wide input pricing tiers |
|
|
209
209
|
| `compat` | No | provider `compat` | Provider compatibility overrides. Merged with provider-level `compat` when both are set. |
|
|
210
210
|
|
|
211
|
+
A cost tier supplies a complete alternate rate set and applies to the full request when total input usage (`input + cacheRead + cacheWrite`) exceeds `inputTokensAbove`. When multiple tiers match, the highest threshold wins.
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"cost": {
|
|
216
|
+
"input": 5,
|
|
217
|
+
"output": 30,
|
|
218
|
+
"cacheRead": 0.5,
|
|
219
|
+
"cacheWrite": 6.25,
|
|
220
|
+
"tiers": [
|
|
221
|
+
{
|
|
222
|
+
"inputTokensAbove": 272000,
|
|
223
|
+
"input": 10,
|
|
224
|
+
"output": 45,
|
|
225
|
+
"cacheRead": 1,
|
|
226
|
+
"cacheWrite": 12.5
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
211
233
|
Current behavior:
|
|
212
234
|
- `/model`, `--list-models`, and the interactive footer display entries by model `id`.
|
|
213
235
|
- The configured `name` is used for model matching and secondary model detail text. It does not replace the footer/status-bar model id.
|
|
214
236
|
|
|
215
237
|
### Thinking Level Map
|
|
216
238
|
|
|
217
|
-
Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are pi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`.
|
|
239
|
+
Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are pi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`. Maps may contain holes; for example, a model can expose `high` and `max` without exposing `xhigh`.
|
|
218
240
|
|
|
219
241
|
Values are tristate:
|
|
220
242
|
|
|
221
243
|
| Value | Meaning |
|
|
222
244
|
|-------|---------|
|
|
223
|
-
| omitted |
|
|
245
|
+
| omitted | Standard levels through `high` use the provider's default mapping; extended `xhigh` and `max` levels are unsupported |
|
|
224
246
|
| string | Level is supported and this value is sent to the provider |
|
|
225
247
|
| `null` | Level is unsupported and hidden/skipped/clamped away |
|
|
226
248
|
|
|
@@ -235,7 +257,8 @@ Example for a model that only supports off, high, and max reasoning:
|
|
|
235
257
|
"low": null,
|
|
236
258
|
"medium": null,
|
|
237
259
|
"high": "high",
|
|
238
|
-
"xhigh":
|
|
260
|
+
"xhigh": null,
|
|
261
|
+
"max": "max"
|
|
239
262
|
}
|
|
240
263
|
}
|
|
241
264
|
```
|
|
@@ -293,7 +316,7 @@ Merge semantics:
|
|
|
293
316
|
|
|
294
317
|
## Per-model Overrides
|
|
295
318
|
|
|
296
|
-
Use `modelOverrides` to customize
|
|
319
|
+
Use `modelOverrides` to customize built-in models and matching extension-registered models without replacing the provider's full model list.
|
|
297
320
|
|
|
298
321
|
```json
|
|
299
322
|
{
|
|
@@ -314,10 +337,28 @@ Use `modelOverrides` to customize specific built-in models without replacing the
|
|
|
314
337
|
}
|
|
315
338
|
```
|
|
316
339
|
|
|
317
|
-
`modelOverrides` supports these fields per model: `name`, `reasoning`, `input`, `cost` (partial), `contextWindow`, `maxTokens`, `headers`, `compat`.
|
|
340
|
+
`modelOverrides` supports these fields per model: `name`, `reasoning`, `thinkingLevelMap`, `input`, `cost` (partial), `contextWindow`, `maxTokens`, `headers`, `compat`.
|
|
341
|
+
|
|
342
|
+
Direct OpenAI GPT-5.6 Sol, Terra, and Luna default to a `272000` context window so requests remain within OpenAI's short-context pricing tier. To opt into OpenAI's 1.05M context window, increase it for each model you use:
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
{
|
|
346
|
+
"providers": {
|
|
347
|
+
"openai": {
|
|
348
|
+
"modelOverrides": {
|
|
349
|
+
"gpt-5.6-sol": {
|
|
350
|
+
"contextWindow": 1050000
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
The override preserves the built-in pricing metadata. Requests with more than 272K total input tokens use GPT-5.6's long-context rates for the entire request. Apply the same override to `gpt-5.6-terra` or `gpt-5.6-luna` when needed.
|
|
318
359
|
|
|
319
360
|
Behavior notes:
|
|
320
|
-
- `modelOverrides` are applied to built-in provider models.
|
|
361
|
+
- `modelOverrides` are applied to built-in provider models and matching extension-registered provider models.
|
|
321
362
|
- Unknown model IDs are ignored.
|
|
322
363
|
- You can combine provider-level `baseUrl`/`headers` with `modelOverrides`.
|
|
323
364
|
- Overriding `name` changes model matching and secondary detail text only; the footer and primary model lists continue to show the model `id`.
|
|
@@ -404,6 +445,8 @@ For providers with partial OpenAI compatibility, use the `compat` field.
|
|
|
404
445
|
| `thinkingFormat` | Use `reasoning_effort`, `openrouter`, `deepseek`, `together`, `zai`, `qwen`, `chat-template`, or `qwen-chat-template` thinking parameters |
|
|
405
446
|
| `chatTemplateKwargs` | `chat_template_kwargs` values for `thinkingFormat: "chat-template"`; use `{ "$var": "thinking.enabled" }` or `{ "$var": "thinking.effort" }` for pi-controlled thinking values |
|
|
406
447
|
| `cacheControlFormat` | Use Anthropic-style `cache_control` markers on the system prompt, last tool definition, and last user/assistant text content. Currently only `anthropic` is supported. |
|
|
448
|
+
| `sendSessionAffinityHeaders` | For `openai-completions`, send session-affinity headers from the session id when caching is enabled. Default: `false`. |
|
|
449
|
+
| `sessionAffinityFormat` | For `openai-completions` and `openai-responses`, the session-affinity header format: `openai` sends `session_id`/`x-client-request-id` (completions also `x-session-affinity`), `openai-nosession` omits the underscore-containing `session_id` header, `openrouter` sends `x-session-id`. Does not affect the `prompt_cache_key` body param. Default: auto-detected. |
|
|
407
450
|
| `supportsStrictMode` | Include the `strict` field in tool definitions |
|
|
408
451
|
| `supportsLongCacheRetention` | Whether the provider accepts long cache retention when cache retention is `long`: `prompt_cache_retention: "24h"` for OpenAI prompt caching, or `cache_control.ttl: "1h"` when `cacheControlFormat` is `anthropic`. Default: `true`. |
|
|
409
452
|
| `openRouterRouting` | OpenRouter provider routing preferences. This object is sent as-is in the `provider` field of the [OpenRouter API request](https://openrouter.ai/docs/guides/routing/provider-selection). |
|
package/docs/packages.md
CHANGED
|
@@ -216,11 +216,11 @@ Filter what a package loads using the object form in settings:
|
|
|
216
216
|
|
|
217
217
|
## Enable and Disable Resources
|
|
218
218
|
|
|
219
|
-
Use `pi config` to enable or disable extensions, skills, prompt templates, and themes from installed packages and local directories.
|
|
219
|
+
Use `pi config` to enable or disable extensions, skills, prompt templates, and themes from installed packages and local directories. `pi config` starts in global settings (`~/.pi/agent/settings.json`); press Tab to switch between global and project-local modes. Use `pi config -l` to start in project overrides (`.pi/settings.json`) with inherited global resources dimmed.
|
|
220
220
|
|
|
221
221
|
## Scope and Deduplication
|
|
222
222
|
|
|
223
|
-
Packages can appear in both global and project settings. If the same package appears in both, the project entry wins. Identity is determined by:
|
|
223
|
+
Packages can appear in both global and project settings. If the same package appears in both, the project entry wins unless the project entry has `autoload: false`, in which case it is applied as a delta over the global entry. Identity is determined by:
|
|
224
224
|
|
|
225
225
|
- npm: package name
|
|
226
226
|
- git: repository URL without ref
|
package/docs/providers.md
CHANGED
|
@@ -55,6 +55,7 @@ pi
|
|
|
55
55
|
| DeepSeek | `DEEPSEEK_API_KEY` | `deepseek` |
|
|
56
56
|
| NVIDIA NIM | `NVIDIA_API_KEY` | `nvidia` |
|
|
57
57
|
| Google Gemini | `GEMINI_API_KEY` | `google` |
|
|
58
|
+
| Amazon Bedrock | `AWS_BEARER_TOKEN_BEDROCK` | `amazon-bedrock` |
|
|
58
59
|
| Mistral | `MISTRAL_API_KEY` | `mistral` |
|
|
59
60
|
| Groq | `GROQ_API_KEY` | `groq` |
|
|
60
61
|
| Cerebras | `CEREBRAS_API_KEY` | `cerebras` |
|
|
@@ -170,6 +171,8 @@ export AZURE_OPENAI_DEPLOYMENT_NAME_MAP=gpt-4=my-gpt4,gpt-4o=my-gpt4o
|
|
|
170
171
|
|
|
171
172
|
### Amazon Bedrock
|
|
172
173
|
|
|
174
|
+
Use `/login amazon-bedrock` to store a Bedrock API key, or configure one of the ambient AWS credential sources below:
|
|
175
|
+
|
|
173
176
|
```bash
|
|
174
177
|
# Option 1: AWS Profile
|
|
175
178
|
export AWS_PROFILE=your-profile
|
package/docs/quickstart.md
CHANGED
|
@@ -113,7 +113,7 @@ pi @README.md "Summarize this"
|
|
|
113
113
|
pi @src/app.ts @src/app.test.ts "Review these together"
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
Images can be pasted with Ctrl+V (Alt+V on Windows)
|
|
116
|
+
Images or text can be pasted with Ctrl+V (Alt+V on Windows); images can also be dragged into supported terminals.
|
|
117
117
|
|
|
118
118
|
### Run shell commands
|
|
119
119
|
|
package/docs/rpc.md
CHANGED
|
@@ -286,9 +286,9 @@ Set the reasoning/thinking level for models that support it.
|
|
|
286
286
|
{"type": "set_thinking_level", "level": "high"}
|
|
287
287
|
```
|
|
288
288
|
|
|
289
|
-
Levels: `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`
|
|
289
|
+
Levels: `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`, `"max"`
|
|
290
290
|
|
|
291
|
-
|
|
291
|
+
`"xhigh"` and `"max"` are exposed only when supported by the selected model. Some models, including GPT-5.6, expose both.
|
|
292
292
|
|
|
293
293
|
Response:
|
|
294
294
|
```json
|
|
@@ -808,7 +808,8 @@ Events are streamed to stdout as JSON lines during agent operation. Events do NO
|
|
|
808
808
|
| Event | Description |
|
|
809
809
|
|-------|-------------|
|
|
810
810
|
| `agent_start` | Agent begins processing |
|
|
811
|
-
| `agent_end` |
|
|
811
|
+
| `agent_end` | One low-level agent run completes (may still be followed by retry, compaction, or queued continuations) |
|
|
812
|
+
| `agent_settled` | Agent run is fully settled; no automatic retry, compaction retry, or queued continuation remains |
|
|
812
813
|
| `turn_start` | New turn begins |
|
|
813
814
|
| `turn_end` | Turn completes (includes assistant message and tool results) |
|
|
814
815
|
| `message_start` | Message begins |
|
|
@@ -834,15 +835,24 @@ Emitted when the agent begins processing a prompt.
|
|
|
834
835
|
|
|
835
836
|
### agent_end
|
|
836
837
|
|
|
837
|
-
Emitted when
|
|
838
|
+
Emitted when one low-level agent run completes. Contains all messages generated during this run. If `willRetry` is true, an automatic retry will follow.
|
|
838
839
|
|
|
839
840
|
```json
|
|
840
841
|
{
|
|
841
842
|
"type": "agent_end",
|
|
842
|
-
"messages": [...]
|
|
843
|
+
"messages": [...],
|
|
844
|
+
"willRetry": false
|
|
843
845
|
}
|
|
844
846
|
```
|
|
845
847
|
|
|
848
|
+
### agent_settled
|
|
849
|
+
|
|
850
|
+
Emitted after the full session-level run settles. At this point Pi will not continue automatically through retry, compaction retry, or queued follow-up messages.
|
|
851
|
+
|
|
852
|
+
```json
|
|
853
|
+
{"type": "agent_settled"}
|
|
854
|
+
```
|
|
855
|
+
|
|
846
856
|
### turn_start / turn_end
|
|
847
857
|
|
|
848
858
|
A turn consists of one assistant response plus any resulting tool calls and results.
|