@mariozechner/pi-coding-agent 0.63.2 → 0.65.0
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 +120 -0
- package/README.md +11 -5
- package/dist/cli/args.d.ts +7 -4
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +37 -15
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +83 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -0
- package/dist/core/agent-session-runtime.js +232 -0
- package/dist/core/agent-session-runtime.js.map +1 -0
- package/dist/core/agent-session-services.d.ts +86 -0
- package/dist/core/agent-session-services.d.ts.map +1 -0
- package/dist/core/agent-session-services.js +116 -0
- package/dist/core/agent-session-services.js.map +1 -0
- package/dist/core/agent-session.d.ts +10 -42
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +58 -237
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts +2 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +2 -2
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +20 -28
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +10 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +5 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +70 -8
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +14 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +13 -14
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-registry.d.ts +3 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +7 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/package-manager.d.ts +20 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +32 -0
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +21 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +5 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +13 -6
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +2 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +15 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +2 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +205 -427
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +20 -0
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +14 -3
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +1 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +4 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +4 -2
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +48 -15
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +12 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +146 -96
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +6 -11
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +2 -2
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +41 -36
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +2 -2
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +95 -64
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts +4 -0
- package/dist/package-manager-cli.d.ts.map +1 -0
- package/dist/package-manager-cli.js +234 -0
- package/dist/package-manager-cli.js.map +1 -0
- package/docs/compaction.md +4 -2
- package/docs/extensions.md +133 -40
- package/docs/json.md +5 -2
- package/docs/keybindings.md +2 -0
- package/docs/rpc.md +21 -7
- package/docs/sdk.md +239 -83
- package/docs/settings.md +1 -1
- package/docs/tree.md +6 -3
- 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/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/hello.ts +18 -17
- package/examples/extensions/hidden-thinking-label.ts +53 -0
- package/examples/extensions/rpc-demo.ts +3 -9
- package/examples/extensions/sandbox/index.ts +4 -0
- package/examples/extensions/status-line.ts +0 -8
- package/examples/extensions/todo.ts +0 -2
- package/examples/extensions/tools.ts +0 -5
- package/examples/extensions/widget-placement.ts +4 -12
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/02-custom-model.ts +1 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +3 -3
- package/examples/sdk/12-full-control.ts +1 -1
- package/examples/sdk/13-session-runtime.ts +67 -0
- package/examples/sdk/README.md +7 -4
- package/package.json +4 -4
package/docs/sdk.md
CHANGED
|
@@ -20,7 +20,7 @@ import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "
|
|
|
20
20
|
|
|
21
21
|
// Set up credential storage and model registry
|
|
22
22
|
const authStorage = AuthStorage.create();
|
|
23
|
-
const modelRegistry =
|
|
23
|
+
const modelRegistry = ModelRegistry.create(authStorage);
|
|
24
24
|
|
|
25
25
|
const { session } = await createAgentSession({
|
|
26
26
|
sessionManager: SessionManager.inMemory(),
|
|
@@ -49,7 +49,7 @@ The SDK is included in the main package. No separate installation needed.
|
|
|
49
49
|
|
|
50
50
|
### createAgentSession()
|
|
51
51
|
|
|
52
|
-
The main factory function
|
|
52
|
+
The main factory function for a single `AgentSession`.
|
|
53
53
|
|
|
54
54
|
`createAgentSession()` uses a `ResourceLoader` to supply extensions, skills, prompt templates, themes, and context files. If you do not provide one, it uses `DefaultResourceLoader` with standard discovery.
|
|
55
55
|
|
|
@@ -69,61 +69,117 @@ const { session } = await createAgentSession({
|
|
|
69
69
|
|
|
70
70
|
### AgentSession
|
|
71
71
|
|
|
72
|
-
The session manages
|
|
72
|
+
The session manages agent lifecycle, message history, model state, compaction, and event streaming.
|
|
73
73
|
|
|
74
74
|
```typescript
|
|
75
75
|
interface AgentSession {
|
|
76
76
|
// Send a prompt and wait for completion
|
|
77
|
-
// If streaming, requires streamingBehavior option to queue the message
|
|
78
77
|
prompt(text: string, options?: PromptOptions): Promise<void>;
|
|
79
|
-
|
|
78
|
+
|
|
80
79
|
// Queue messages during streaming
|
|
81
|
-
steer(text: string): Promise<void>;
|
|
82
|
-
followUp(text: string): Promise<void>;
|
|
83
|
-
|
|
80
|
+
steer(text: string): Promise<void>;
|
|
81
|
+
followUp(text: string): Promise<void>;
|
|
82
|
+
|
|
84
83
|
// Subscribe to events (returns unsubscribe function)
|
|
85
84
|
subscribe(listener: (event: AgentSessionEvent) => void): () => void;
|
|
86
|
-
|
|
85
|
+
|
|
87
86
|
// Session info
|
|
88
|
-
sessionFile: string | undefined;
|
|
87
|
+
sessionFile: string | undefined;
|
|
89
88
|
sessionId: string;
|
|
90
|
-
|
|
89
|
+
|
|
91
90
|
// Model control
|
|
92
91
|
setModel(model: Model): Promise<void>;
|
|
93
92
|
setThinkingLevel(level: ThinkingLevel): void;
|
|
94
93
|
cycleModel(): Promise<ModelCycleResult | undefined>;
|
|
95
94
|
cycleThinkingLevel(): ThinkingLevel | undefined;
|
|
96
|
-
|
|
95
|
+
|
|
97
96
|
// State access
|
|
98
97
|
agent: Agent;
|
|
99
98
|
model: Model | undefined;
|
|
100
99
|
thinkingLevel: ThinkingLevel;
|
|
101
100
|
messages: AgentMessage[];
|
|
102
101
|
isStreaming: boolean;
|
|
103
|
-
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// Forking
|
|
109
|
-
fork(entryId: string): Promise<{ selectedText: string; cancelled: boolean }>; // Creates new session file
|
|
110
|
-
navigateTree(targetId: string, options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string }): Promise<{ editorText?: string; cancelled: boolean }>; // In-place navigation
|
|
111
|
-
|
|
112
|
-
// Hook message injection
|
|
113
|
-
sendHookMessage(message: HookMessage, triggerTurn?: boolean): Promise<void>;
|
|
114
|
-
|
|
102
|
+
|
|
103
|
+
// In-place tree navigation within the current session file
|
|
104
|
+
navigateTree(targetId: string, options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string }): Promise<{ editorText?: string; cancelled: boolean }>;
|
|
105
|
+
|
|
115
106
|
// Compaction
|
|
116
107
|
compact(customInstructions?: string): Promise<CompactionResult>;
|
|
117
108
|
abortCompaction(): void;
|
|
118
|
-
|
|
109
|
+
|
|
119
110
|
// Abort current operation
|
|
120
111
|
abort(): Promise<void>;
|
|
121
|
-
|
|
112
|
+
|
|
122
113
|
// Cleanup
|
|
123
114
|
dispose(): void;
|
|
124
115
|
}
|
|
125
116
|
```
|
|
126
117
|
|
|
118
|
+
Session replacement APIs such as new-session, resume, fork, and import live on `AgentSessionRuntime`, not on `AgentSession`.
|
|
119
|
+
|
|
120
|
+
### createAgentSessionRuntime() and AgentSessionRuntime
|
|
121
|
+
|
|
122
|
+
Use the runtime API when you need to replace the active session and rebuild cwd-bound runtime state.
|
|
123
|
+
This is the same layer used by the built-in interactive, print, and RPC modes.
|
|
124
|
+
|
|
125
|
+
`createAgentSessionRuntime()` takes a runtime factory plus the initial cwd/session target. The factory closes over process-global fixed inputs, recreates cwd-bound services for the effective cwd, resolves session options against those services, and returns a full runtime result.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import {
|
|
129
|
+
type CreateAgentSessionRuntimeFactory,
|
|
130
|
+
createAgentSessionFromServices,
|
|
131
|
+
createAgentSessionRuntime,
|
|
132
|
+
createAgentSessionServices,
|
|
133
|
+
getAgentDir,
|
|
134
|
+
SessionManager,
|
|
135
|
+
} from "@mariozechner/pi-coding-agent";
|
|
136
|
+
|
|
137
|
+
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
|
|
138
|
+
const services = await createAgentSessionServices({ cwd });
|
|
139
|
+
return {
|
|
140
|
+
...(await createAgentSessionFromServices({
|
|
141
|
+
services,
|
|
142
|
+
sessionManager,
|
|
143
|
+
sessionStartEvent,
|
|
144
|
+
})),
|
|
145
|
+
services,
|
|
146
|
+
diagnostics: services.diagnostics,
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const runtime = await createAgentSessionRuntime(createRuntime, {
|
|
151
|
+
cwd: process.cwd(),
|
|
152
|
+
agentDir: getAgentDir(),
|
|
153
|
+
sessionManager: SessionManager.create(process.cwd()),
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`AgentSessionRuntime` owns replacement of the active runtime across:
|
|
158
|
+
|
|
159
|
+
- `newSession()`
|
|
160
|
+
- `switchSession()`
|
|
161
|
+
- `fork()`
|
|
162
|
+
- `importFromJsonl()`
|
|
163
|
+
|
|
164
|
+
Important behavior:
|
|
165
|
+
|
|
166
|
+
- `runtime.session` changes after those operations
|
|
167
|
+
- event subscriptions are attached to a specific `AgentSession`, so re-subscribe after replacement
|
|
168
|
+
- if you use extensions, call `runtime.session.bindExtensions(...)` again for the new session
|
|
169
|
+
- creation returns diagnostics on `runtime.diagnostics`
|
|
170
|
+
- if runtime creation or replacement fails, the method throws and the caller decides how to handle it
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
let session = runtime.session;
|
|
174
|
+
let unsubscribe = session.subscribe(() => {});
|
|
175
|
+
|
|
176
|
+
await runtime.newSession();
|
|
177
|
+
|
|
178
|
+
unsubscribe();
|
|
179
|
+
session = runtime.session;
|
|
180
|
+
unsubscribe = session.subscribe(() => {});
|
|
181
|
+
```
|
|
182
|
+
|
|
127
183
|
### Prompting and Message Queueing
|
|
128
184
|
|
|
129
185
|
The `prompt()` method handles prompt templates, extension commands, and message sending:
|
|
@@ -171,10 +227,15 @@ const state = session.agent.state;
|
|
|
171
227
|
// state.model: Model - current model
|
|
172
228
|
// state.thinkingLevel: ThinkingLevel - current thinking level
|
|
173
229
|
// state.systemPrompt: string - system prompt
|
|
174
|
-
// state.tools:
|
|
230
|
+
// state.tools: AgentTool[] - available tools
|
|
231
|
+
// state.streamingMessage?: AgentMessage - current partial assistant message
|
|
232
|
+
// state.errorMessage?: string - latest assistant error
|
|
233
|
+
|
|
234
|
+
// Replace messages (useful for branching or restoration)
|
|
235
|
+
session.agent.state.messages = messages; // copies the top-level array
|
|
175
236
|
|
|
176
|
-
// Replace
|
|
177
|
-
session.agent.
|
|
237
|
+
// Replace tools
|
|
238
|
+
session.agent.state.tools = tools; // copies the top-level array
|
|
178
239
|
|
|
179
240
|
// Wait for agent to finish processing
|
|
180
241
|
await session.agent.waitForIdle();
|
|
@@ -232,9 +293,12 @@ session.subscribe((event) => {
|
|
|
232
293
|
// event.toolResults: tool results from this turn
|
|
233
294
|
break;
|
|
234
295
|
|
|
235
|
-
// Session events (
|
|
236
|
-
case "
|
|
237
|
-
|
|
296
|
+
// Session events (queue, compaction, retry)
|
|
297
|
+
case "queue_update":
|
|
298
|
+
console.log(event.steering, event.followUp);
|
|
299
|
+
break;
|
|
300
|
+
case "compaction_start":
|
|
301
|
+
case "compaction_end":
|
|
238
302
|
case "auto_retry_start":
|
|
239
303
|
case "auto_retry_end":
|
|
240
304
|
break;
|
|
@@ -286,7 +350,7 @@ import { getModel } from "@mariozechner/pi-ai";
|
|
|
286
350
|
import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
287
351
|
|
|
288
352
|
const authStorage = AuthStorage.create();
|
|
289
|
-
const modelRegistry =
|
|
353
|
+
const modelRegistry = ModelRegistry.create(authStorage);
|
|
290
354
|
|
|
291
355
|
// Find specific built-in model (doesn't check if API key exists)
|
|
292
356
|
const opus = getModel("anthropic", "claude-opus-4-5");
|
|
@@ -334,7 +398,7 @@ import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
|
334
398
|
|
|
335
399
|
// Default: uses ~/.pi/agent/auth.json and ~/.pi/agent/models.json
|
|
336
400
|
const authStorage = AuthStorage.create();
|
|
337
|
-
const modelRegistry =
|
|
401
|
+
const modelRegistry = ModelRegistry.create(authStorage);
|
|
338
402
|
|
|
339
403
|
const { session } = await createAgentSession({
|
|
340
404
|
sessionManager: SessionManager.inMemory(),
|
|
@@ -347,7 +411,7 @@ authStorage.setRuntimeApiKey("anthropic", "sk-my-temp-key");
|
|
|
347
411
|
|
|
348
412
|
// Custom auth storage location
|
|
349
413
|
const customAuth = AuthStorage.create("/my/app/auth.json");
|
|
350
|
-
const customRegistry =
|
|
414
|
+
const customRegistry = ModelRegistry.create(customAuth, "/my/app/models.json");
|
|
351
415
|
|
|
352
416
|
const { session } = await createAgentSession({
|
|
353
417
|
sessionManager: SessionManager.inMemory(),
|
|
@@ -356,7 +420,7 @@ const { session } = await createAgentSession({
|
|
|
356
420
|
});
|
|
357
421
|
|
|
358
422
|
// No custom models.json (built-in models only)
|
|
359
|
-
const simpleRegistry =
|
|
423
|
+
const simpleRegistry = ModelRegistry.inMemory(authStorage);
|
|
360
424
|
```
|
|
361
425
|
|
|
362
426
|
> See [examples/sdk/09-api-keys-and-oauth.ts](../examples/sdk/09-api-keys-and-oauth.ts)
|
|
@@ -444,21 +508,21 @@ const { session } = await createAgentSession({
|
|
|
444
508
|
|
|
445
509
|
```typescript
|
|
446
510
|
import { Type } from "@sinclair/typebox";
|
|
447
|
-
import { createAgentSession,
|
|
511
|
+
import { createAgentSession, defineTool } from "@mariozechner/pi-coding-agent";
|
|
448
512
|
|
|
449
513
|
// Inline custom tool
|
|
450
|
-
const myTool
|
|
514
|
+
const myTool = defineTool({
|
|
451
515
|
name: "my_tool",
|
|
452
516
|
label: "My Tool",
|
|
453
517
|
description: "Does something useful",
|
|
454
518
|
parameters: Type.Object({
|
|
455
519
|
input: Type.String({ description: "Input value" }),
|
|
456
520
|
}),
|
|
457
|
-
execute: async (
|
|
521
|
+
execute: async (_toolCallId, params) => ({
|
|
458
522
|
content: [{ type: "text", text: `Result: ${params.input}` }],
|
|
459
523
|
details: {},
|
|
460
524
|
}),
|
|
461
|
-
};
|
|
525
|
+
});
|
|
462
526
|
|
|
463
527
|
// Pass custom tools directly
|
|
464
528
|
const { session } = await createAgentSession({
|
|
@@ -466,6 +530,8 @@ const { session } = await createAgentSession({
|
|
|
466
530
|
});
|
|
467
531
|
```
|
|
468
532
|
|
|
533
|
+
Use `defineTool()` for standalone definitions and arrays like `customTools: [myTool]`. Inline `pi.registerTool({ ... })` already infers parameter types correctly.
|
|
534
|
+
|
|
469
535
|
Custom tools passed via `customTools` are combined with extension-registered tools. Extensions loaded by the ResourceLoader can also register tools via `pi.registerTool()`.
|
|
470
536
|
|
|
471
537
|
> See [examples/sdk/05-tools.ts](../examples/sdk/05-tools.ts)
|
|
@@ -594,7 +660,15 @@ const { session } = await createAgentSession({ resourceLoader: loader });
|
|
|
594
660
|
Sessions use a tree structure with `id`/`parentId` linking, enabling in-place branching.
|
|
595
661
|
|
|
596
662
|
```typescript
|
|
597
|
-
import {
|
|
663
|
+
import {
|
|
664
|
+
type CreateAgentSessionRuntimeFactory,
|
|
665
|
+
createAgentSession,
|
|
666
|
+
createAgentSessionFromServices,
|
|
667
|
+
createAgentSessionRuntime,
|
|
668
|
+
createAgentSessionServices,
|
|
669
|
+
getAgentDir,
|
|
670
|
+
SessionManager,
|
|
671
|
+
} from "@mariozechner/pi-coding-agent";
|
|
598
672
|
|
|
599
673
|
// In-memory (no persistence)
|
|
600
674
|
const { session } = await createAgentSession({
|
|
@@ -602,12 +676,12 @@ const { session } = await createAgentSession({
|
|
|
602
676
|
});
|
|
603
677
|
|
|
604
678
|
// New persistent session
|
|
605
|
-
const { session } = await createAgentSession({
|
|
679
|
+
const { session: persisted } = await createAgentSession({
|
|
606
680
|
sessionManager: SessionManager.create(process.cwd()),
|
|
607
681
|
});
|
|
608
682
|
|
|
609
683
|
// Continue most recent
|
|
610
|
-
const { session, modelFallbackMessage } = await createAgentSession({
|
|
684
|
+
const { session: continued, modelFallbackMessage } = await createAgentSession({
|
|
611
685
|
sessionManager: SessionManager.continueRecent(process.cwd()),
|
|
612
686
|
});
|
|
613
687
|
if (modelFallbackMessage) {
|
|
@@ -615,26 +689,42 @@ if (modelFallbackMessage) {
|
|
|
615
689
|
}
|
|
616
690
|
|
|
617
691
|
// Open specific file
|
|
618
|
-
const { session } = await createAgentSession({
|
|
692
|
+
const { session: opened } = await createAgentSession({
|
|
619
693
|
sessionManager: SessionManager.open("/path/to/session.jsonl"),
|
|
620
694
|
});
|
|
621
695
|
|
|
622
|
-
// List
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
696
|
+
// List sessions
|
|
697
|
+
const currentProjectSessions = await SessionManager.list(process.cwd());
|
|
698
|
+
const allSessions = await SessionManager.listAll(process.cwd());
|
|
699
|
+
|
|
700
|
+
// Session replacement API for /new, /resume, /fork, and import flows.
|
|
701
|
+
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
|
|
702
|
+
const services = await createAgentSessionServices({ cwd });
|
|
703
|
+
return {
|
|
704
|
+
...(await createAgentSessionFromServices({
|
|
705
|
+
services,
|
|
706
|
+
sessionManager,
|
|
707
|
+
sessionStartEvent,
|
|
708
|
+
})),
|
|
709
|
+
services,
|
|
710
|
+
diagnostics: services.diagnostics,
|
|
711
|
+
};
|
|
712
|
+
};
|
|
627
713
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
714
|
+
const runtime = await createAgentSessionRuntime(createRuntime, {
|
|
715
|
+
cwd: process.cwd(),
|
|
716
|
+
agentDir: getAgentDir(),
|
|
717
|
+
sessionManager: SessionManager.create(process.cwd()),
|
|
631
718
|
});
|
|
632
719
|
|
|
633
|
-
//
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
720
|
+
// Replace the active session with a fresh one
|
|
721
|
+
await runtime.newSession();
|
|
722
|
+
|
|
723
|
+
// Replace the active session with another saved session
|
|
724
|
+
await runtime.switchSession("/path/to/session.jsonl");
|
|
725
|
+
|
|
726
|
+
// Replace the active session with a fork from a specific entry
|
|
727
|
+
await runtime.fork("entry-id");
|
|
638
728
|
```
|
|
639
729
|
|
|
640
730
|
**SessionManager tree API:**
|
|
@@ -642,6 +732,10 @@ const { session } = await createAgentSession({
|
|
|
642
732
|
```typescript
|
|
643
733
|
const sm = SessionManager.open("/path/to/session.jsonl");
|
|
644
734
|
|
|
735
|
+
// Session listing
|
|
736
|
+
const currentProjectSessions = await SessionManager.list(process.cwd());
|
|
737
|
+
const allSessions = await SessionManager.listAll(process.cwd());
|
|
738
|
+
|
|
645
739
|
// Tree traversal
|
|
646
740
|
const entries = sm.getEntries(); // All entries (excludes header)
|
|
647
741
|
const tree = sm.getTree(); // Full tree structure
|
|
@@ -766,14 +860,14 @@ import { getModel } from "@mariozechner/pi-ai";
|
|
|
766
860
|
import { Type } from "@sinclair/typebox";
|
|
767
861
|
import {
|
|
768
862
|
AuthStorage,
|
|
863
|
+
bashTool,
|
|
769
864
|
createAgentSession,
|
|
770
865
|
DefaultResourceLoader,
|
|
866
|
+
defineTool,
|
|
771
867
|
ModelRegistry,
|
|
868
|
+
readTool,
|
|
772
869
|
SessionManager,
|
|
773
870
|
SettingsManager,
|
|
774
|
-
readTool,
|
|
775
|
-
bashTool,
|
|
776
|
-
type ToolDefinition,
|
|
777
871
|
} from "@mariozechner/pi-coding-agent";
|
|
778
872
|
|
|
779
873
|
// Set up auth storage (custom location)
|
|
@@ -785,10 +879,10 @@ if (process.env.MY_KEY) {
|
|
|
785
879
|
}
|
|
786
880
|
|
|
787
881
|
// Model registry (no custom models.json)
|
|
788
|
-
const modelRegistry =
|
|
882
|
+
const modelRegistry = ModelRegistry.create(authStorage);
|
|
789
883
|
|
|
790
884
|
// Inline tool
|
|
791
|
-
const statusTool
|
|
885
|
+
const statusTool = defineTool({
|
|
792
886
|
name: "status",
|
|
793
887
|
label: "Status",
|
|
794
888
|
description: "Get system status",
|
|
@@ -797,7 +891,7 @@ const statusTool: ToolDefinition = {
|
|
|
797
891
|
content: [{ type: "text", text: `Uptime: ${process.uptime()}s` }],
|
|
798
892
|
details: {},
|
|
799
893
|
}),
|
|
800
|
-
};
|
|
894
|
+
});
|
|
801
895
|
|
|
802
896
|
const model = getModel("anthropic", "claude-opus-4-5");
|
|
803
897
|
if (!model) throw new Error("Model not found");
|
|
@@ -851,20 +945,39 @@ The SDK exports run mode utilities for building custom interfaces on top of `cre
|
|
|
851
945
|
Full TUI interactive mode with editor, chat history, and all built-in commands:
|
|
852
946
|
|
|
853
947
|
```typescript
|
|
854
|
-
import {
|
|
948
|
+
import {
|
|
949
|
+
type CreateAgentSessionRuntimeFactory,
|
|
950
|
+
createAgentSessionFromServices,
|
|
951
|
+
createAgentSessionRuntime,
|
|
952
|
+
createAgentSessionServices,
|
|
953
|
+
getAgentDir,
|
|
954
|
+
InteractiveMode,
|
|
955
|
+
SessionManager,
|
|
956
|
+
} from "@mariozechner/pi-coding-agent";
|
|
855
957
|
|
|
856
|
-
const
|
|
958
|
+
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
|
|
959
|
+
const services = await createAgentSessionServices({ cwd });
|
|
960
|
+
return {
|
|
961
|
+
...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
|
|
962
|
+
services,
|
|
963
|
+
diagnostics: services.diagnostics,
|
|
964
|
+
};
|
|
965
|
+
};
|
|
966
|
+
const runtime = await createAgentSessionRuntime(createRuntime, {
|
|
967
|
+
cwd: process.cwd(),
|
|
968
|
+
agentDir: getAgentDir(),
|
|
969
|
+
sessionManager: SessionManager.create(process.cwd()),
|
|
970
|
+
});
|
|
857
971
|
|
|
858
|
-
const mode = new InteractiveMode(
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
initialMessages: [], // Additional startup prompts
|
|
972
|
+
const mode = new InteractiveMode(runtime, {
|
|
973
|
+
migratedProviders: [],
|
|
974
|
+
modelFallbackMessage: undefined,
|
|
975
|
+
initialMessage: "Hello",
|
|
976
|
+
initialImages: [],
|
|
977
|
+
initialMessages: [],
|
|
865
978
|
});
|
|
866
979
|
|
|
867
|
-
await mode.run();
|
|
980
|
+
await mode.run();
|
|
868
981
|
```
|
|
869
982
|
|
|
870
983
|
### runPrintMode
|
|
@@ -872,15 +985,35 @@ await mode.run(); // Blocks until exit
|
|
|
872
985
|
Single-shot mode: send prompts, output result, exit:
|
|
873
986
|
|
|
874
987
|
```typescript
|
|
875
|
-
import {
|
|
988
|
+
import {
|
|
989
|
+
type CreateAgentSessionRuntimeFactory,
|
|
990
|
+
createAgentSessionFromServices,
|
|
991
|
+
createAgentSessionRuntime,
|
|
992
|
+
createAgentSessionServices,
|
|
993
|
+
getAgentDir,
|
|
994
|
+
runPrintMode,
|
|
995
|
+
SessionManager,
|
|
996
|
+
} from "@mariozechner/pi-coding-agent";
|
|
876
997
|
|
|
877
|
-
const
|
|
998
|
+
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
|
|
999
|
+
const services = await createAgentSessionServices({ cwd });
|
|
1000
|
+
return {
|
|
1001
|
+
...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
|
|
1002
|
+
services,
|
|
1003
|
+
diagnostics: services.diagnostics,
|
|
1004
|
+
};
|
|
1005
|
+
};
|
|
1006
|
+
const runtime = await createAgentSessionRuntime(createRuntime, {
|
|
1007
|
+
cwd: process.cwd(),
|
|
1008
|
+
agentDir: getAgentDir(),
|
|
1009
|
+
sessionManager: SessionManager.create(process.cwd()),
|
|
1010
|
+
});
|
|
878
1011
|
|
|
879
|
-
await runPrintMode(
|
|
880
|
-
mode: "text",
|
|
881
|
-
initialMessage: "Hello",
|
|
882
|
-
initialImages: [],
|
|
883
|
-
messages: ["Follow up"],
|
|
1012
|
+
await runPrintMode(runtime, {
|
|
1013
|
+
mode: "text",
|
|
1014
|
+
initialMessage: "Hello",
|
|
1015
|
+
initialImages: [],
|
|
1016
|
+
messages: ["Follow up"],
|
|
884
1017
|
});
|
|
885
1018
|
```
|
|
886
1019
|
|
|
@@ -889,11 +1022,31 @@ await runPrintMode(session, {
|
|
|
889
1022
|
JSON-RPC mode for subprocess integration:
|
|
890
1023
|
|
|
891
1024
|
```typescript
|
|
892
|
-
import {
|
|
1025
|
+
import {
|
|
1026
|
+
type CreateAgentSessionRuntimeFactory,
|
|
1027
|
+
createAgentSessionFromServices,
|
|
1028
|
+
createAgentSessionRuntime,
|
|
1029
|
+
createAgentSessionServices,
|
|
1030
|
+
getAgentDir,
|
|
1031
|
+
runRpcMode,
|
|
1032
|
+
SessionManager,
|
|
1033
|
+
} from "@mariozechner/pi-coding-agent";
|
|
893
1034
|
|
|
894
|
-
const
|
|
1035
|
+
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
|
|
1036
|
+
const services = await createAgentSessionServices({ cwd });
|
|
1037
|
+
return {
|
|
1038
|
+
...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
|
|
1039
|
+
services,
|
|
1040
|
+
diagnostics: services.diagnostics,
|
|
1041
|
+
};
|
|
1042
|
+
};
|
|
1043
|
+
const runtime = await createAgentSessionRuntime(createRuntime, {
|
|
1044
|
+
cwd: process.cwd(),
|
|
1045
|
+
agentDir: getAgentDir(),
|
|
1046
|
+
sessionManager: SessionManager.create(process.cwd()),
|
|
1047
|
+
});
|
|
895
1048
|
|
|
896
|
-
await runRpcMode(
|
|
1049
|
+
await runRpcMode(runtime);
|
|
897
1050
|
```
|
|
898
1051
|
|
|
899
1052
|
See [RPC documentation](rpc.md) for the JSON protocol.
|
|
@@ -926,6 +1079,8 @@ The main entry point exports:
|
|
|
926
1079
|
```typescript
|
|
927
1080
|
// Factory
|
|
928
1081
|
createAgentSession
|
|
1082
|
+
createAgentSessionRuntime
|
|
1083
|
+
AgentSessionRuntime
|
|
929
1084
|
|
|
930
1085
|
// Auth and Models
|
|
931
1086
|
AuthStorage
|
|
@@ -937,6 +1092,7 @@ type ResourceLoader
|
|
|
937
1092
|
createEventBus
|
|
938
1093
|
|
|
939
1094
|
// Helpers
|
|
1095
|
+
defineTool
|
|
940
1096
|
|
|
941
1097
|
// Session management
|
|
942
1098
|
SessionManager
|
package/docs/settings.md
CHANGED
|
@@ -137,7 +137,7 @@ When a provider requests a retry delay longer than `maxDelayMs` (e.g., Google's
|
|
|
137
137
|
{ "sessionDir": ".pi/sessions" }
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
When multiple sources specify a session directory, `--session-dir` CLI flag takes precedence
|
|
140
|
+
When multiple sources specify a session directory, `--session-dir` CLI flag takes precedence over `sessionDir` in settings.json.
|
|
141
141
|
|
|
142
142
|
### Model Cycling
|
|
143
143
|
|
package/docs/tree.md
CHANGED
|
@@ -13,7 +13,7 @@ Sessions are stored as trees where each entry has an `id` and `parentId`. The "l
|
|
|
13
13
|
| View | Flat list of user messages | Full tree structure |
|
|
14
14
|
| Action | Extracts path to **new session file** | Changes leaf in **same session** |
|
|
15
15
|
| Summary | Never | Optional (user prompted) |
|
|
16
|
-
| Events | `session_before_fork` / `
|
|
16
|
+
| Events | `session_before_fork` / `session_start` (`reason: "fork"`) | `session_before_tree` / `session_tree` |
|
|
17
17
|
|
|
18
18
|
## Tree UI
|
|
19
19
|
|
|
@@ -35,6 +35,8 @@ Sessions are stored as trees where each entry has an `id` and `parentId`. The "l
|
|
|
35
35
|
| ↑/↓ | Navigate (depth-first order) |
|
|
36
36
|
| ←/→ | Page up/down |
|
|
37
37
|
| Ctrl+←/Ctrl+→ or Alt+←/Alt+→ | Fold/unfold and jump between branch segments |
|
|
38
|
+
| Shift+L | Set or clear a label on the selected node |
|
|
39
|
+
| Shift+T | Toggle label timestamps |
|
|
38
40
|
| Enter | Select node |
|
|
39
41
|
| Escape/Ctrl+C | Cancel |
|
|
40
42
|
| Ctrl+U | Toggle: user messages only |
|
|
@@ -49,11 +51,12 @@ Sessions are stored as trees where each entry has an `id` and `parentId`. The "l
|
|
|
49
51
|
- Height: half terminal height
|
|
50
52
|
- Current leaf marked with `← active`
|
|
51
53
|
- Labels shown inline: `[label-name]`
|
|
54
|
+
- `Shift+T` shows the latest label-change timestamp next to labeled nodes
|
|
52
55
|
- Foldable branch starts show `⊟` in the connector. Folded branches show `⊞`
|
|
53
56
|
- Active path marker `•` appears after the fold indicator when applicable
|
|
54
57
|
- Search and filter changes reset all folds
|
|
55
58
|
- Default filter hides `label` and `custom` entries (shown in Ctrl+O mode)
|
|
56
|
-
-
|
|
59
|
+
- At each branch point, the active subtree is shown first; other sibling branches are sorted by timestamp (oldest first)
|
|
57
60
|
|
|
58
61
|
## Selection Behavior
|
|
59
62
|
|
|
@@ -141,7 +144,7 @@ Flow:
|
|
|
141
144
|
4. Fire `session_before_tree` event (hook can cancel or provide summary)
|
|
142
145
|
5. Run default summarizer if needed
|
|
143
146
|
6. Switch leaf via `branch()` or `branchWithSummary()`
|
|
144
|
-
7. Update agent: `agent.
|
|
147
|
+
7. Update agent: `agent.state.messages = sessionManager.buildSessionContext().messages`
|
|
145
148
|
8. Fire `session_tree` event
|
|
146
149
|
9. Notify custom tools via session event
|
|
147
150
|
10. Return result with `editorText` if user message was selected
|
|
@@ -52,6 +52,7 @@ cp permission-gate.ts ~/.pi/agent/extensions/
|
|
|
52
52
|
| `qna.ts` | Extracts questions from last response into editor via `ctx.ui.setEditorText()` |
|
|
53
53
|
| `status-line.ts` | Shows turn progress in footer via `ctx.ui.setStatus()` with themed colors |
|
|
54
54
|
| `widget-placement.ts` | Shows widgets above and below the editor via `ctx.ui.setWidget()` placement |
|
|
55
|
+
| `hidden-thinking-label.ts` | Customizes the collapsed thinking label via `ctx.ui.setHiddenThinkingLabel()` |
|
|
55
56
|
| `model-status.ts` | Shows model changes in status bar via `model_select` hook |
|
|
56
57
|
| `snake.ts` | Snake game with custom UI, keyboard handling, and session persistence |
|
|
57
58
|
| `send-user-message.ts` | Demonstrates `pi.sendUserMessage()` for sending user messages from extensions |
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-custom-provider",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-custom-provider",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.16.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.52.0"
|
|
12
12
|
}
|