@earendil-works/pi-coding-agent 0.80.7 → 0.80.9

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.
Files changed (145) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +6 -6
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js +2 -0
  5. package/dist/bun/cli.js.map +1 -1
  6. package/dist/cli/args.d.ts.map +1 -1
  7. package/dist/cli/args.js +1 -1
  8. package/dist/cli/args.js.map +1 -1
  9. package/dist/cli/list-models.d.ts +2 -2
  10. package/dist/cli/list-models.d.ts.map +1 -1
  11. package/dist/cli/list-models.js +3 -3
  12. package/dist/cli/list-models.js.map +1 -1
  13. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  14. package/dist/core/agent-session-runtime.js +3 -0
  15. package/dist/core/agent-session-runtime.js.map +1 -1
  16. package/dist/core/agent-session-services.d.ts +3 -6
  17. package/dist/core/agent-session-services.d.ts.map +1 -1
  18. package/dist/core/agent-session-services.js +10 -9
  19. package/dist/core/agent-session-services.js.map +1 -1
  20. package/dist/core/agent-session.d.ts +5 -6
  21. package/dist/core/agent-session.d.ts.map +1 -1
  22. package/dist/core/agent-session.js +57 -30
  23. package/dist/core/agent-session.js.map +1 -1
  24. package/dist/core/auth-storage.d.ts +15 -99
  25. package/dist/core/auth-storage.d.ts.map +1 -1
  26. package/dist/core/auth-storage.js +46 -259
  27. package/dist/core/auth-storage.js.map +1 -1
  28. package/dist/core/cache-stats.d.ts +2 -2
  29. package/dist/core/cache-stats.d.ts.map +1 -1
  30. package/dist/core/cache-stats.js +1 -1
  31. package/dist/core/cache-stats.js.map +1 -1
  32. package/dist/core/extensions/loader.d.ts.map +1 -1
  33. package/dist/core/extensions/loader.js +8 -2
  34. package/dist/core/extensions/loader.js.map +1 -1
  35. package/dist/core/extensions/runner.d.ts +1 -0
  36. package/dist/core/extensions/runner.d.ts.map +1 -1
  37. package/dist/core/extensions/runner.js +3 -0
  38. package/dist/core/extensions/runner.js.map +1 -1
  39. package/dist/core/extensions/types.d.ts +9 -2
  40. package/dist/core/extensions/types.d.ts.map +1 -1
  41. package/dist/core/extensions/types.js.map +1 -1
  42. package/dist/core/model-config.d.ts +512 -0
  43. package/dist/core/model-config.d.ts.map +1 -0
  44. package/dist/core/model-config.js +243 -0
  45. package/dist/core/model-config.js.map +1 -0
  46. package/dist/core/model-registry.d.ts +13 -123
  47. package/dist/core/model-registry.d.ts.map +1 -1
  48. package/dist/core/model-registry.js +44 -747
  49. package/dist/core/model-registry.js.map +1 -1
  50. package/dist/core/model-resolver.d.ts +6 -6
  51. package/dist/core/model-resolver.d.ts.map +1 -1
  52. package/dist/core/model-resolver.js +18 -18
  53. package/dist/core/model-resolver.js.map +1 -1
  54. package/dist/core/model-runtime.d.ts +77 -0
  55. package/dist/core/model-runtime.d.ts.map +1 -0
  56. package/dist/core/model-runtime.js +418 -0
  57. package/dist/core/model-runtime.js.map +1 -0
  58. package/dist/core/models-store.d.ts +17 -0
  59. package/dist/core/models-store.d.ts.map +1 -0
  60. package/dist/core/models-store.js +45 -0
  61. package/dist/core/models-store.js.map +1 -0
  62. package/dist/core/provider-composer.d.ts +55 -0
  63. package/dist/core/provider-composer.d.ts.map +1 -0
  64. package/dist/core/provider-composer.js +375 -0
  65. package/dist/core/provider-composer.js.map +1 -0
  66. package/dist/core/radius.d.ts +0 -19
  67. package/dist/core/radius.d.ts.map +1 -1
  68. package/dist/core/radius.js +0 -28
  69. package/dist/core/radius.js.map +1 -1
  70. package/dist/core/remote-catalog-provider.d.ts +5 -0
  71. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  72. package/dist/core/remote-catalog-provider.js +83 -0
  73. package/dist/core/remote-catalog-provider.js.map +1 -0
  74. package/dist/core/runtime-credentials.d.ts +15 -0
  75. package/dist/core/runtime-credentials.d.ts.map +1 -0
  76. package/dist/core/runtime-credentials.js +36 -0
  77. package/dist/core/runtime-credentials.js.map +1 -0
  78. package/dist/core/sdk.d.ts +3 -6
  79. package/dist/core/sdk.d.ts.map +1 -1
  80. package/dist/core/sdk.js +14 -25
  81. package/dist/core/sdk.js.map +1 -1
  82. package/dist/index.d.ts +2 -1
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +2 -2
  85. package/dist/index.js.map +1 -1
  86. package/dist/main.d.ts.map +1 -1
  87. package/dist/main.js +11 -13
  88. package/dist/main.js.map +1 -1
  89. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  90. package/dist/modes/interactive/components/assistant-message.js +22 -10
  91. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  92. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  93. package/dist/modes/interactive/components/footer.js +1 -1
  94. package/dist/modes/interactive/components/footer.js.map +1 -1
  95. package/dist/modes/interactive/components/login-dialog.d.ts +4 -8
  96. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  97. package/dist/modes/interactive/components/login-dialog.js +14 -12
  98. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  99. package/dist/modes/interactive/components/model-selector.d.ts +11 -4
  100. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  101. package/dist/modes/interactive/components/model-selector.js +72 -41
  102. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  103. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
  104. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  105. package/dist/modes/interactive/components/oauth-selector.js +14 -27
  106. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  107. package/dist/modes/interactive/interactive-mode.d.ts +6 -3
  108. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  109. package/dist/modes/interactive/interactive-mode.js +157 -143
  110. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  111. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  112. package/dist/modes/rpc/rpc-mode.js +2 -2
  113. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  114. package/dist/package-manager-cli.d.ts.map +1 -1
  115. package/dist/package-manager-cli.js +67 -5
  116. package/dist/package-manager-cli.js.map +1 -1
  117. package/docs/custom-provider.md +6 -11
  118. package/docs/extensions.md +22 -1
  119. package/docs/models.md +2 -0
  120. package/docs/packages.md +1 -0
  121. package/docs/providers.md +13 -1
  122. package/docs/sdk.md +40 -50
  123. package/docs/usage.md +1 -0
  124. package/examples/extensions/README.md +1 -0
  125. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  126. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  127. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  128. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  129. package/examples/extensions/gondolin/package-lock.json +2 -2
  130. package/examples/extensions/gondolin/package.json +1 -1
  131. package/examples/extensions/kimi-deferred-tools.ts +61 -0
  132. package/examples/extensions/sandbox/package-lock.json +2 -2
  133. package/examples/extensions/sandbox/package.json +1 -1
  134. package/examples/extensions/with-deps/package-lock.json +2 -2
  135. package/examples/extensions/with-deps/package.json +1 -1
  136. package/examples/sdk/02-custom-model.ts +5 -8
  137. package/examples/sdk/09-api-keys-and-oauth.ts +13 -31
  138. package/examples/sdk/12-full-control.ts +7 -12
  139. package/examples/sdk/README.md +14 -18
  140. package/npm-shrinkwrap.json +12 -12
  141. package/package.json +4 -4
  142. package/dist/core/provider-display-names.d.ts +0 -2
  143. package/dist/core/provider-display-names.d.ts.map +0 -1
  144. package/dist/core/provider-display-names.js +0 -37
  145. package/dist/core/provider-display-names.js.map +0 -1
package/docs/sdk.md CHANGED
@@ -16,16 +16,12 @@ See [examples/sdk/](../examples/sdk/) for working examples from minimal to full
16
16
  ## Quick Start
17
17
 
18
18
  ```typescript
19
- import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@earendil-works/pi-coding-agent";
20
-
21
- // Set up credential storage and model registry
22
- const authStorage = AuthStorage.create();
23
- const modelRegistry = ModelRegistry.create(authStorage);
19
+ import { createAgentSession, ModelRuntime, SessionManager } from "@earendil-works/pi-coding-agent";
24
20
 
21
+ const modelRuntime = await ModelRuntime.create();
25
22
  const { session } = await createAgentSession({
26
23
  sessionManager: SessionManager.inMemory(),
27
- authStorage,
28
- modelRegistry,
24
+ modelRuntime,
29
25
  });
30
26
 
31
27
  session.subscribe((event) => {
@@ -369,10 +365,9 @@ When you pass a custom `ResourceLoader`, `cwd` and `agentDir` no longer control
369
365
 
370
366
  ```typescript
371
367
  import { getModel } from "@earendil-works/pi-ai";
372
- import { AuthStorage, ModelRegistry } from "@earendil-works/pi-coding-agent";
368
+ import { ModelRuntime } from "@earendil-works/pi-coding-agent";
373
369
 
374
- const authStorage = AuthStorage.create();
375
- const modelRegistry = ModelRegistry.create(authStorage);
370
+ const modelRuntime = await ModelRuntime.create();
376
371
 
377
372
  // Find specific built-in model (doesn't check if API key exists)
378
373
  const opus = getModel("anthropic", "claude-opus-4-5");
@@ -380,10 +375,10 @@ if (!opus) throw new Error("Model not found");
380
375
 
381
376
  // Find any model by provider/id, including custom models from models.json
382
377
  // (doesn't check if API key exists)
383
- const customModel = modelRegistry.find("my-provider", "my-model");
378
+ const customModel = modelRuntime.getModel("my-provider", "my-model");
384
379
 
385
- // Get only models that have valid API keys configured
386
- const available = await modelRegistry.getAvailable();
380
+ // Get only models that have valid authentication configured
381
+ const available = await modelRuntime.getAvailable();
387
382
 
388
383
  const { session } = await createAgentSession({
389
384
  model: opus,
@@ -395,8 +390,7 @@ const { session } = await createAgentSession({
395
390
  { model: haiku, thinkingLevel: "off" },
396
391
  ],
397
392
 
398
- authStorage,
399
- modelRegistry,
393
+ modelRuntime,
400
394
  });
401
395
  ```
402
396
 
@@ -415,14 +409,14 @@ import {
415
409
 
416
410
  const cliModel = resolveCliModel({
417
411
  cliModel: "anthropic/claude-opus-4-5:high",
418
- modelRegistry,
412
+ modelRuntime,
419
413
  });
420
414
  if (cliModel.error) throw new Error(cliModel.error);
421
415
  if (cliModel.warning) console.warn(cliModel.warning);
422
416
 
423
417
  const { scopedModels, diagnostics } = await resolveModelScopeWithDiagnostics(
424
418
  ["anthropic/*:high", "gpt-5"],
425
- modelRegistry,
419
+ modelRuntime,
426
420
  );
427
421
  for (const diagnostic of diagnostics) {
428
422
  console.warn(diagnostic.message);
@@ -435,40 +429,41 @@ for (const diagnostic of diagnostics) {
435
429
 
436
430
  ### API Keys and OAuth
437
431
 
438
- API key resolution priority (handled by AuthStorage):
432
+ Authentication resolution priority (handled by `ModelRuntime`):
439
433
  1. Runtime overrides (via `setRuntimeApiKey`, not persisted)
440
434
  2. Stored credentials in `auth.json` (API keys or OAuth tokens)
441
435
  3. Environment variables (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, etc.)
442
436
  4. Fallback resolver (for custom provider keys from `models.json`)
443
437
 
444
438
  ```typescript
445
- import { AuthStorage, ModelRegistry } from "@earendil-works/pi-coding-agent";
439
+ import { InMemoryCredentialStore } from "@earendil-works/pi-ai";
440
+ import { createAgentSession, ModelRuntime } from "@earendil-works/pi-coding-agent";
446
441
 
447
442
  // Default: uses ~/.pi/agent/auth.json and ~/.pi/agent/models.json
448
- const authStorage = AuthStorage.create();
449
- const modelRegistry = ModelRegistry.create(authStorage);
443
+ const modelRuntime = await ModelRuntime.create();
450
444
 
451
- const { session } = await createAgentSession({
452
- sessionManager: SessionManager.inMemory(),
453
- authStorage,
454
- modelRegistry,
455
- });
445
+ // Provider-owned auth methods and current status
446
+ for (const provider of modelRuntime.getProviders()) {
447
+ const status = await modelRuntime.checkAuth(provider.id);
448
+ console.log(provider.name, provider.auth, status);
449
+ }
456
450
 
457
451
  // Runtime API key override (not persisted to disk)
458
- authStorage.setRuntimeApiKey("anthropic", "sk-my-temp-key");
452
+ modelRuntime.setRuntimeApiKey("anthropic", "sk-my-temp-key");
453
+
454
+ // Custom credential and model locations
455
+ const customRuntime = await ModelRuntime.create({
456
+ authPath: "/my/app/auth.json",
457
+ modelsPath: "/my/app/models.json",
458
+ });
459
459
 
460
- // Custom auth storage location
461
- const customAuth = AuthStorage.create("/my/app/auth.json");
462
- const customRegistry = ModelRegistry.create(customAuth, "/my/app/models.json");
460
+ // Or inject any pi-ai CredentialStore
461
+ const credentials = new InMemoryCredentialStore();
462
+ const inMemoryRuntime = await ModelRuntime.create({ credentials });
463
463
 
464
464
  const { session } = await createAgentSession({
465
- sessionManager: SessionManager.inMemory(),
466
- authStorage: customAuth,
467
- modelRegistry: customRegistry,
465
+ modelRuntime: customRuntime,
468
466
  });
469
-
470
- // No custom models.json (built-in models only)
471
- const simpleRegistry = ModelRegistry.inMemory(authStorage);
472
467
  ```
473
468
 
474
469
  > See [examples/sdk/09-api-keys-and-oauth.ts](../examples/sdk/09-api-keys-and-oauth.ts)
@@ -927,26 +922,22 @@ interface LoadExtensionsResult {
927
922
  import { getModel } from "@earendil-works/pi-ai";
928
923
  import { Type } from "typebox";
929
924
  import {
930
- AuthStorage,
931
925
  createAgentSession,
932
926
  DefaultResourceLoader,
933
927
  defineTool,
934
- ModelRegistry,
928
+ ModelRuntime,
935
929
  SessionManager,
936
930
  SettingsManager,
937
931
  } from "@earendil-works/pi-coding-agent";
938
932
 
939
- // Set up auth storage (custom location)
940
- const authStorage = AuthStorage.create("/custom/agent/auth.json");
941
-
942
- // Runtime API key override (not persisted)
933
+ const modelRuntime = await ModelRuntime.create({
934
+ authPath: "/custom/agent/auth.json",
935
+ modelsPath: "/custom/agent/models.json",
936
+ });
943
937
  if (process.env.MY_KEY) {
944
- authStorage.setRuntimeApiKey("anthropic", process.env.MY_KEY);
938
+ modelRuntime.setRuntimeApiKey("anthropic", process.env.MY_KEY);
945
939
  }
946
940
 
947
- // Model registry (no custom models.json)
948
- const modelRegistry = ModelRegistry.create(authStorage);
949
-
950
941
  // Inline tool
951
942
  const statusTool = defineTool({
952
943
  name: "status",
@@ -982,8 +973,7 @@ const { session } = await createAgentSession({
982
973
 
983
974
  model,
984
975
  thinkingLevel: "off",
985
- authStorage,
986
- modelRegistry,
976
+ modelRuntime,
987
977
 
988
978
  tools: ["read", "bash", "status"],
989
979
  customTools: [statusTool],
@@ -1149,8 +1139,8 @@ createAgentSessionRuntime
1149
1139
  AgentSessionRuntime
1150
1140
 
1151
1141
  // Auth and Models
1152
- AuthStorage
1153
- ModelRegistry
1142
+ ModelRuntime // implements pi-ai Models and owns credential storage
1143
+ ModelRegistry // synchronous extension compatibility facade
1154
1144
  resolveCliModel
1155
1145
  resolveModelScopeWithDiagnostics
1156
1146
 
package/docs/usage.md CHANGED
@@ -151,6 +151,7 @@ pi uninstall <source> [-l] # Alias for remove
151
151
  pi update [source|self|pi] # Update pi only, or one package source
152
152
  pi update --all # Update pi and packages; reconcile pinned git refs
153
153
  pi update --extensions # Update packages only; reconcile pinned git refs
154
+ pi update --models # Refresh model catalogs only
154
155
  pi update --self # Update pi only
155
156
  pi update --extension <src> # Update one package
156
157
  pi list # List installed packages
@@ -36,6 +36,7 @@ cp permission-gate.ts ~/.pi/agent/extensions/
36
36
  | `questionnaire.ts` | Multi-question input with tab bar navigation between questions |
37
37
  | `tool-override.ts` | Override built-in tools (e.g., add logging/access control to `read`) |
38
38
  | `dynamic-tools.ts` | Register tools after startup (`session_start`) and at runtime via command, with prompt snippets and tool-specific prompt guidelines |
39
+ | `kimi-deferred-tools.ts` | Search for and progressively activate tools for Kimi's deferred-tool loading protocol |
39
40
  | `structured-output.ts` | Final structured-output tool that returns `terminate: true` so the agent can end on the tool call |
40
41
  | `built-in-tool-renderer.ts` | Custom compact rendering for built-in tools (read, bash, edit, write) while keeping original behavior |
41
42
  | `minimal-mode.ts` | Override built-in tool rendering for minimal display (only tool calls, no output in collapsed mode) |
@@ -46,7 +46,7 @@ import {
46
46
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
47
47
 
48
48
  // =============================================================================
49
- // OAuth Implementation (copied from packages/ai/src/utils/oauth/anthropic.ts)
49
+ // OAuth implementation adapted for the legacy extension compatibility interface.
50
50
  // =============================================================================
51
51
 
52
52
  const decode = (s: string) => atob(s);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider",
3
- "version": "0.80.7",
3
+ "version": "0.80.9",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-custom-provider",
9
- "version": "0.80.7",
9
+ "version": "0.80.9",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.52.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.80.7",
4
+ "version": "0.80.9",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.80.7",
4
+ "version": "0.80.9",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-gondolin",
3
- "version": "0.80.7",
3
+ "version": "0.80.9",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-gondolin",
9
- "version": "0.80.7",
9
+ "version": "0.80.9",
10
10
  "dependencies": {
11
11
  "@earendil-works/gondolin": "0.12.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-gondolin",
3
3
  "private": true,
4
- "version": "0.80.7",
4
+ "version": "0.80.9",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Minimal Kimi deferred-tool loading demo.
3
+ *
4
+ * pi -e ./kimi-deferred-tools.ts
5
+ * example prompt: Use the available tools to calculate 100 + 500. Do not calculate it yourself.
6
+ */
7
+
8
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
9
+ import { Type } from "typebox";
10
+
11
+ function calculate(_expr: string): string {
12
+ return "42";
13
+ }
14
+
15
+ export default function (pi: ExtensionAPI): void {
16
+ pi.registerTool({
17
+ name: "Calculator",
18
+ label: "Calculator",
19
+ description: "Evaluate a simple arithmetic expression.",
20
+ parameters: Type.Object({
21
+ expr: Type.String({ description: "An expression such as 100 + 500" }),
22
+ }),
23
+ async execute(_toolCallId, params) {
24
+ return {
25
+ content: [{ type: "text", text: calculate(params.expr) }],
26
+ details: {},
27
+ };
28
+ },
29
+ });
30
+
31
+ pi.registerTool({
32
+ name: "tool_search",
33
+ label: "Tool Search",
34
+ description: "Find and activate tools for a capability.",
35
+ promptSnippet: "Search for additional tools when the active tools cannot perform the task",
36
+ parameters: Type.Object({
37
+ query: Type.String({ description: "Capability to search for" }),
38
+ }),
39
+ async execute(_toolCallId, params) {
40
+ if (!params.query.toLowerCase().includes("calc")) {
41
+ return {
42
+ content: [{ type: "text", text: "The relevant tools do not exist." }],
43
+ details: { matches: [], added: [] },
44
+ };
45
+ }
46
+
47
+ const active = pi.getActiveTools();
48
+ const added = active.includes("Calculator") ? [] : ["Calculator"];
49
+ if (added.length > 0) pi.setActiveTools([...active, ...added]);
50
+
51
+ return {
52
+ content: [{ type: "text", text: "Success. Found 1 matching tool(s)" }],
53
+ details: { matches: ["Calculator"], added },
54
+ };
55
+ },
56
+ });
57
+
58
+ pi.on("session_start", () => {
59
+ pi.setActiveTools(["tool_search"]);
60
+ });
61
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
- "version": "1.10.7",
3
+ "version": "1.10.9",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-sandbox",
9
- "version": "1.10.7",
9
+ "version": "1.10.9",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sandbox-runtime": "^0.0.26"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
3
  "private": true,
4
- "version": "1.10.7",
4
+ "version": "1.10.9",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
- "version": "0.80.7",
3
+ "version": "0.80.9",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-with-deps",
9
- "version": "0.80.7",
9
+ "version": "0.80.9",
10
10
  "dependencies": {
11
11
  "ms": "^2.1.3"
12
12
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
3
  "private": true,
4
- "version": "0.80.7",
4
+ "version": "0.80.9",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -5,11 +5,9 @@
5
5
  */
6
6
 
7
7
  import { getModel } from "@earendil-works/pi-ai/compat";
8
- import { AuthStorage, createAgentSession, ModelRegistry } from "@earendil-works/pi-coding-agent";
8
+ import { createAgentSession, ModelRuntime } from "@earendil-works/pi-coding-agent";
9
9
 
10
- // Set up auth storage and model registry
11
- const authStorage = AuthStorage.create();
12
- const modelRegistry = ModelRegistry.create(authStorage);
10
+ const modelRuntime = await ModelRuntime.create();
13
11
 
14
12
  // Option 1: Find a specific built-in model by provider/id
15
13
  const opus = getModel("anthropic", "claude-opus-4-5");
@@ -18,13 +16,13 @@ if (opus) {
18
16
  }
19
17
 
20
18
  // Option 2: Find model via registry (includes custom models from models.json)
21
- const customModel = modelRegistry.find("my-provider", "my-model");
19
+ const customModel = modelRuntime.getModel("my-provider", "my-model");
22
20
  if (customModel) {
23
21
  console.log(`Found custom model: ${customModel.provider}/${customModel.id}`);
24
22
  }
25
23
 
26
24
  // Option 3: Pick from available models (have valid API keys)
27
- const available = await modelRegistry.getAvailable();
25
+ const available = await modelRuntime.getAvailable();
28
26
  console.log(
29
27
  "Available models:",
30
28
  available.map((m) => `${m.provider}/${m.id}`),
@@ -34,8 +32,7 @@ if (available.length > 0) {
34
32
  const { session } = await createAgentSession({
35
33
  model: available[0],
36
34
  thinkingLevel: "medium", // off, low, medium, high
37
- authStorage,
38
- modelRegistry,
35
+ modelRuntime,
39
36
  });
40
37
 
41
38
  try {
@@ -1,52 +1,34 @@
1
1
  /**
2
2
  * API Keys and OAuth
3
3
  *
4
- * Configure API key resolution via AuthStorage and ModelRegistry.
4
+ * Configure provider auth through ModelRuntime.
5
5
  */
6
6
 
7
- import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@earendil-works/pi-coding-agent";
8
-
9
- // Default: AuthStorage uses ~/.pi/agent/auth.json
10
- // ModelRegistry loads built-in + custom models from ~/.pi/agent/models.json
11
- const authStorage = AuthStorage.create();
12
- const modelRegistry = ModelRegistry.create(authStorage);
7
+ import { createAgentSession, ModelRuntime, SessionManager } from "@earendil-works/pi-coding-agent";
13
8
 
9
+ const modelRuntime = await ModelRuntime.create();
14
10
  const { session: defaultAuthSession } = await createAgentSession({
15
11
  sessionManager: SessionManager.inMemory(),
16
- authStorage,
17
- modelRegistry,
12
+ modelRuntime,
18
13
  });
19
- console.log("Session with default auth storage and model registry");
14
+ console.log("Session with default model runtime");
20
15
  defaultAuthSession.dispose();
21
16
 
22
- // Custom auth storage location
23
- const customAuthStorage = AuthStorage.create("/tmp/my-app/auth.json");
24
- const customModelRegistry = ModelRegistry.create(customAuthStorage, "/tmp/my-app/models.json");
25
-
17
+ const customRuntime = await ModelRuntime.create({
18
+ authPath: "/tmp/my-app/auth.json",
19
+ modelsPath: "/tmp/my-app/models.json",
20
+ });
26
21
  const { session: customAuthSession } = await createAgentSession({
27
22
  sessionManager: SessionManager.inMemory(),
28
- authStorage: customAuthStorage,
29
- modelRegistry: customModelRegistry,
23
+ modelRuntime: customRuntime,
30
24
  });
31
- console.log("Session with custom auth storage location");
25
+ console.log("Session with custom auth and models locations");
32
26
  customAuthSession.dispose();
33
27
 
34
- // Runtime API key override (not persisted to disk)
35
- authStorage.setRuntimeApiKey("anthropic", "sk-my-temp-key");
28
+ modelRuntime.setRuntimeApiKey("anthropic", "sk-my-temp-key");
36
29
  const { session: runtimeKeySession } = await createAgentSession({
37
30
  sessionManager: SessionManager.inMemory(),
38
- authStorage,
39
- modelRegistry,
31
+ modelRuntime,
40
32
  });
41
33
  console.log("Session with runtime API key override");
42
34
  runtimeKeySession.dispose();
43
-
44
- // No models.json - only built-in models
45
- const simpleRegistry = ModelRegistry.inMemory(authStorage);
46
- const { session: builtInModelsSession } = await createAgentSession({
47
- sessionManager: SessionManager.inMemory(),
48
- authStorage,
49
- modelRegistry: simpleRegistry,
50
- });
51
- console.log("Session with only built-in models");
52
- builtInModelsSession.dispose();
@@ -6,26 +6,22 @@
6
6
 
7
7
  import { getModel } from "@earendil-works/pi-ai/compat";
8
8
  import {
9
- AuthStorage,
10
9
  createAgentSession,
11
10
  createExtensionRuntime,
12
- ModelRegistry,
11
+ ModelRuntime,
13
12
  type ResourceLoader,
14
13
  SessionManager,
15
14
  SettingsManager,
16
15
  } from "@earendil-works/pi-coding-agent";
17
16
 
18
- // Custom auth storage location
19
- const authStorage = AuthStorage.create("/tmp/my-agent/auth.json");
20
-
21
- // Runtime API key override (not persisted)
17
+ const modelRuntime = await ModelRuntime.create({
18
+ authPath: "/tmp/my-agent/auth.json",
19
+ modelsPath: "/tmp/my-agent/models.json",
20
+ });
22
21
  if (process.env.MY_ANTHROPIC_KEY) {
23
- authStorage.setRuntimeApiKey("anthropic", process.env.MY_ANTHROPIC_KEY);
22
+ modelRuntime.setRuntimeApiKey("anthropic", process.env.MY_ANTHROPIC_KEY);
24
23
  }
25
24
 
26
- // Model registry with no custom models.json
27
- const modelRegistry = ModelRegistry.inMemory(authStorage);
28
-
29
25
  const model = getModel("anthropic", "claude-sonnet-4-5");
30
26
  if (!model) throw new Error("Model not found");
31
27
 
@@ -55,8 +51,7 @@ const { session } = await createAgentSession({
55
51
  agentDir: "/tmp/my-agent",
56
52
  model,
57
53
  thinkingLevel: "off",
58
- authStorage,
59
- modelRegistry,
54
+ modelRuntime,
60
55
  resourceLoader,
61
56
  tools: ["read", "bash"],
62
57
  sessionManager: SessionManager.inMemory(cwd),
@@ -34,46 +34,44 @@ npx tsx examples/sdk/01-minimal.ts
34
34
  ```typescript
35
35
  import { getModel } from "@earendil-works/pi-ai";
36
36
  import {
37
- AuthStorage,
38
37
  createAgentSession,
39
38
  DefaultResourceLoader,
40
- ModelRegistry,
39
+ ModelRuntime,
41
40
  SessionManager,
42
41
  SettingsManager,
43
42
  } from "@earendil-works/pi-coding-agent";
44
43
 
45
- // Auth and models setup
46
- const authStorage = AuthStorage.create();
47
- const modelRegistry = ModelRegistry.create(authStorage);
44
+ const modelRuntime = await ModelRuntime.create();
48
45
 
49
46
  // Minimal
50
- const { session } = await createAgentSession({ authStorage, modelRegistry });
47
+ const { session } = await createAgentSession({ modelRuntime });
51
48
 
52
49
  // Custom model
53
50
  const model = getModel("anthropic", "claude-opus-4-5");
54
- const { session } = await createAgentSession({ model, thinkingLevel: "high", authStorage, modelRegistry });
51
+ const { session } = await createAgentSession({ model, thinkingLevel: "high", modelRuntime });
55
52
 
56
53
  // Modify prompt
57
54
  const loader = new DefaultResourceLoader({
58
55
  systemPromptOverride: (base) => `${base}\n\nBe concise.`,
59
56
  });
60
57
  await loader.reload();
61
- const { session } = await createAgentSession({ resourceLoader: loader, authStorage, modelRegistry });
58
+ const { session } = await createAgentSession({ resourceLoader: loader, modelRuntime });
62
59
 
63
60
  // Read-only
64
- const { session } = await createAgentSession({ tools: ["read", "grep", "find", "ls"], authStorage, modelRegistry });
61
+ const { session } = await createAgentSession({ tools: ["read", "grep", "find", "ls"], modelRuntime });
65
62
 
66
63
  // In-memory
67
64
  const { session } = await createAgentSession({
68
65
  sessionManager: SessionManager.inMemory(),
69
- authStorage,
70
- modelRegistry,
66
+ modelRuntime,
71
67
  });
72
68
 
73
69
  // Full control
74
- const customAuth = AuthStorage.create("/my/app/auth.json");
75
- customAuth.setRuntimeApiKey("anthropic", process.env.MY_KEY!);
76
- const customRegistry = ModelRegistry.create(customAuth);
70
+ const customRuntime = await ModelRuntime.create({
71
+ authPath: "/my/app/auth.json",
72
+ modelsPath: "/my/app/models.json",
73
+ });
74
+ customRuntime.setRuntimeApiKey("anthropic", process.env.MY_KEY!);
77
75
 
78
76
  const resourceLoader = new DefaultResourceLoader({
79
77
  systemPromptOverride: () => "You are helpful.",
@@ -86,8 +84,7 @@ await resourceLoader.reload();
86
84
 
87
85
  const { session } = await createAgentSession({
88
86
  model,
89
- authStorage: customAuth,
90
- modelRegistry: customRegistry,
87
+ modelRuntime: customRuntime,
91
88
  resourceLoader,
92
89
  tools: ["read", "bash", "my_tool"],
93
90
  customTools: [myTool],
@@ -108,8 +105,7 @@ await session.prompt("Hello");
108
105
 
109
106
  | Option | Default | Description |
110
107
  |--------|---------|-------------|
111
- | `authStorage` | `AuthStorage.create()` | Credential storage |
112
- | `modelRegistry` | `ModelRegistry.create(authStorage)` | Model registry |
108
+ | `modelRuntime` | Runtime using `agentDir/auth.json` and `models.json` | Canonical model and authentication runtime |
113
109
  | `cwd` | `process.cwd()` | Working directory |
114
110
  | `agentDir` | `~/.pi/agent` | Config directory |
115
111
  | `model` | From settings/first available | Model to use |