@averyyy/pi-coding-agent 0.80.6-piclient.9 → 0.80.10-piclient.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +96 -1
  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 +4 -6
  17. package/dist/core/agent-session-services.d.ts.map +1 -1
  18. package/dist/core/agent-session-services.js +11 -9
  19. package/dist/core/agent-session-services.js.map +1 -1
  20. package/dist/core/agent-session.d.ts +9 -7
  21. package/dist/core/agent-session.d.ts.map +1 -1
  22. package/dist/core/agent-session.js +64 -35
  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/compaction/branch-summarization.d.ts +1 -1
  33. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  34. package/dist/core/compaction/branch-summarization.js.map +1 -1
  35. package/dist/core/extensions/loader.d.ts.map +1 -1
  36. package/dist/core/extensions/loader.js +8 -2
  37. package/dist/core/extensions/loader.js.map +1 -1
  38. package/dist/core/extensions/runner.d.ts +1 -0
  39. package/dist/core/extensions/runner.d.ts.map +1 -1
  40. package/dist/core/extensions/runner.js +3 -0
  41. package/dist/core/extensions/runner.js.map +1 -1
  42. package/dist/core/extensions/types.d.ts +9 -2
  43. package/dist/core/extensions/types.d.ts.map +1 -1
  44. package/dist/core/extensions/types.js.map +1 -1
  45. package/dist/core/model-config.d.ts +512 -0
  46. package/dist/core/model-config.d.ts.map +1 -0
  47. package/dist/core/model-config.js +243 -0
  48. package/dist/core/model-config.js.map +1 -0
  49. package/dist/core/model-registry.d.ts +13 -123
  50. package/dist/core/model-registry.d.ts.map +1 -1
  51. package/dist/core/model-registry.js +44 -733
  52. package/dist/core/model-registry.js.map +1 -1
  53. package/dist/core/model-resolver.d.ts +6 -6
  54. package/dist/core/model-resolver.d.ts.map +1 -1
  55. package/dist/core/model-resolver.js +19 -18
  56. package/dist/core/model-resolver.js.map +1 -1
  57. package/dist/core/model-runtime.d.ts +77 -0
  58. package/dist/core/model-runtime.d.ts.map +1 -0
  59. package/dist/core/model-runtime.js +418 -0
  60. package/dist/core/model-runtime.js.map +1 -0
  61. package/dist/core/models-store.d.ts +17 -0
  62. package/dist/core/models-store.d.ts.map +1 -0
  63. package/dist/core/models-store.js +45 -0
  64. package/dist/core/models-store.js.map +1 -0
  65. package/dist/core/package-manager.d.ts.map +1 -1
  66. package/dist/core/package-manager.js +7 -2
  67. package/dist/core/package-manager.js.map +1 -1
  68. package/dist/core/provider-composer.d.ts +55 -0
  69. package/dist/core/provider-composer.d.ts.map +1 -0
  70. package/dist/core/provider-composer.js +375 -0
  71. package/dist/core/provider-composer.js.map +1 -0
  72. package/dist/core/radius.d.ts +2 -0
  73. package/dist/core/radius.d.ts.map +1 -0
  74. package/dist/core/radius.js +2 -0
  75. package/dist/core/radius.js.map +1 -0
  76. package/dist/core/remote-catalog-provider.d.ts +5 -0
  77. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  78. package/dist/core/remote-catalog-provider.js +83 -0
  79. package/dist/core/remote-catalog-provider.js.map +1 -0
  80. package/dist/core/runtime-credentials.d.ts +15 -0
  81. package/dist/core/runtime-credentials.d.ts.map +1 -0
  82. package/dist/core/runtime-credentials.js +36 -0
  83. package/dist/core/runtime-credentials.js.map +1 -0
  84. package/dist/core/sdk.d.ts +5 -6
  85. package/dist/core/sdk.d.ts.map +1 -1
  86. package/dist/core/sdk.js +38 -33
  87. package/dist/core/sdk.js.map +1 -1
  88. package/dist/core/system-prompt.d.ts.map +1 -1
  89. package/dist/core/system-prompt.js +1 -11
  90. package/dist/core/system-prompt.js.map +1 -1
  91. package/dist/index.d.ts +2 -1
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +2 -2
  94. package/dist/index.js.map +1 -1
  95. package/dist/main.d.ts.map +1 -1
  96. package/dist/main.js +11 -13
  97. package/dist/main.js.map +1 -1
  98. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  99. package/dist/modes/interactive/components/assistant-message.js +22 -10
  100. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  101. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/footer.js +1 -1
  103. package/dist/modes/interactive/components/footer.js.map +1 -1
  104. package/dist/modes/interactive/components/login-dialog.d.ts +4 -8
  105. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  106. package/dist/modes/interactive/components/login-dialog.js +14 -12
  107. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  108. package/dist/modes/interactive/components/model-selector.d.ts +11 -4
  109. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  110. package/dist/modes/interactive/components/model-selector.js +72 -41
  111. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  112. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
  113. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  114. package/dist/modes/interactive/components/oauth-selector.js +14 -27
  115. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  116. package/dist/modes/interactive/interactive-mode.d.ts +6 -3
  117. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  118. package/dist/modes/interactive/interactive-mode.js +158 -144
  119. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  120. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  121. package/dist/modes/rpc/rpc-mode.js +2 -2
  122. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  123. package/dist/package-manager-cli.d.ts.map +1 -1
  124. package/dist/package-manager-cli.js +67 -5
  125. package/dist/package-manager-cli.js.map +1 -1
  126. package/docs/custom-provider.md +8 -11
  127. package/docs/extensions.md +22 -1
  128. package/docs/models.md +4 -0
  129. package/docs/packages.md +1 -0
  130. package/docs/providers.md +13 -1
  131. package/docs/sdk.md +40 -50
  132. package/docs/usage.md +1 -0
  133. package/examples/extensions/README.md +1 -0
  134. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  135. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  136. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  137. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  138. package/examples/extensions/gondolin/package-lock.json +2 -2
  139. package/examples/extensions/gondolin/package.json +1 -1
  140. package/examples/extensions/kimi-deferred-tools.ts +61 -0
  141. package/examples/extensions/sandbox/package-lock.json +2 -2
  142. package/examples/extensions/sandbox/package.json +1 -1
  143. package/examples/extensions/with-deps/package-lock.json +2 -2
  144. package/examples/extensions/with-deps/package.json +1 -1
  145. package/examples/sdk/02-custom-model.ts +5 -8
  146. package/examples/sdk/09-api-keys-and-oauth.ts +13 -31
  147. package/examples/sdk/12-full-control.ts +7 -12
  148. package/examples/sdk/README.md +14 -18
  149. package/package.json +4 -4
  150. package/dist/core/provider-display-names.d.ts +0 -2
  151. package/dist/core/provider-display-names.d.ts.map +0 -1
  152. package/dist/core/provider-display-names.js +0 -36
  153. package/dist/core/provider-display-names.js.map +0 -1
@@ -27,6 +27,7 @@ import { exportSessionToHtml } from "./export-html/index.js";
27
27
  import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
28
28
  import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
29
29
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
30
+ import { ModelRegistry } from "./model-registry.js";
30
31
  import { compactPiServer, syncPiServerTree, } from "./pi-server-client.js";
31
32
  import { expandPromptTemplate } from "./prompt-templates.js";
32
33
  import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
@@ -50,6 +51,14 @@ export function parseSkillBlock(text) {
50
51
  userMessage: match[4]?.trim() || undefined,
51
52
  };
52
53
  }
54
+ // ============================================================================
55
+ // Types
56
+ // ============================================================================
57
+ function withoutDeletedHeaders(headers) {
58
+ return headers
59
+ ? Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] !== null))
60
+ : undefined;
61
+ }
53
62
  function estimateMessagesTokens(messages) {
54
63
  let tokens = 0;
55
64
  for (const message of messages) {
@@ -195,9 +204,9 @@ export class AgentSession {
195
204
  _extensionShutdownHandler;
196
205
  _extensionErrorListener;
197
206
  _extensionErrorUnsubscriber;
207
+ _autoSessionNameEnabled;
198
208
  _autoSessionNameAttempted = false;
199
- // Model registry for API key resolution
200
- _modelRegistry;
209
+ _modelRuntime;
201
210
  // Tool registry for extension getTools/setTools
202
211
  _toolRegistry = new Map();
203
212
  _toolDefinitions = new Map();
@@ -215,13 +224,14 @@ export class AgentSession {
215
224
  this._resourceLoader = config.resourceLoader;
216
225
  this._customTools = config.customTools ?? [];
217
226
  this._cwd = config.cwd;
218
- this._modelRegistry = config.modelRegistry;
227
+ this._modelRuntime = config.modelRuntime;
219
228
  this._extensionRunnerRef = config.extensionRunnerRef;
220
229
  this._initialActiveToolNames = config.initialActiveToolNames;
221
230
  this._allowedToolNames = config.allowedToolNames ? new Set(config.allowedToolNames) : undefined;
222
231
  this._excludedToolNames = config.excludedToolNames ? new Set(config.excludedToolNames) : undefined;
223
232
  this._baseToolsOverride = config.baseToolsOverride;
224
233
  this._sessionStartEvent = config.sessionStartEvent ?? { type: "session_start", reason: "startup" };
234
+ this._autoSessionNameEnabled = config.autoSessionName ?? true;
225
235
  if (isPiServerMode()) {
226
236
  this._detachPiServerTerminalAssistantFailure();
227
237
  }
@@ -235,9 +245,8 @@ export class AgentSession {
235
245
  includeAllExtensionTools: true,
236
246
  });
237
247
  }
238
- /** Model registry for API key resolution and model discovery */
239
- get modelRegistry() {
240
- return this._modelRegistry;
248
+ get modelRuntime() {
249
+ return this._modelRuntime;
241
250
  }
242
251
  reconcilePiServerHistory(snapshot) {
243
252
  this.sessionManager.replaceTree(snapshot.entries, snapshot.leafId);
@@ -250,17 +259,25 @@ export class AgentSession {
250
259
  });
251
260
  }
252
261
  async _getRequiredRequestAuth(model) {
253
- const result = await this._modelRegistry.getApiKeyAndHeaders(model);
254
- if (!result.ok) {
255
- if (result.error.startsWith("No API key found")) {
262
+ let result;
263
+ try {
264
+ result = await this._modelRuntime.getAuth(model);
265
+ }
266
+ catch (error) {
267
+ const cause = error instanceof Error ? error.cause : undefined;
268
+ if (cause instanceof Error && cause.message === "authHeader requires a resolved API key") {
256
269
  throw new Error(formatNoApiKeyFoundMessage(model.provider));
257
270
  }
258
- throw new Error(result.error);
271
+ throw error;
259
272
  }
260
- if (result.apiKey) {
261
- return { apiKey: result.apiKey, headers: result.headers, env: result.env };
273
+ if (result?.auth.apiKey) {
274
+ return {
275
+ apiKey: result.auth.apiKey,
276
+ headers: withoutDeletedHeaders(result.auth.headers),
277
+ env: result.env,
278
+ };
262
279
  }
263
- const isOAuth = this._modelRegistry.isUsingOAuth(model);
280
+ const isOAuth = this._modelRuntime.isUsingOAuth(model.provider);
264
281
  if (isOAuth) {
265
282
  throw new Error(`Authentication failed for "${model.provider}". ` +
266
283
  `Credentials may have expired or network is unavailable. ` +
@@ -268,12 +285,19 @@ export class AgentSession {
268
285
  }
269
286
  throw new Error(formatNoApiKeyFoundMessage(model.provider));
270
287
  }
271
- async _getCompactionRequestAuth(model) {
288
+ async _getSummarizationRequestAuth(model) {
272
289
  if (this.agent.streamFn === streamSimple) {
273
290
  return this._getRequiredRequestAuth(model);
274
291
  }
275
- const result = await this._modelRegistry.getApiKeyAndHeaders(model);
276
- return result.ok ? { apiKey: result.apiKey, headers: result.headers, env: result.env } : {};
292
+ try {
293
+ const result = await this._modelRuntime.getAuth(model);
294
+ return result
295
+ ? { apiKey: result.auth.apiKey, headers: withoutDeletedHeaders(result.auth.headers), env: result.env }
296
+ : {};
297
+ }
298
+ catch {
299
+ return {};
300
+ }
277
301
  }
278
302
  _resetValidationHintState() {
279
303
  this._validationModifiedFiles.clear();
@@ -1001,7 +1025,7 @@ export class AgentSession {
1001
1025
  return transcript ? truncateForSessionNameInput(transcript) : undefined;
1002
1026
  }
1003
1027
  _shouldGenerateSessionName() {
1004
- if (this._autoSessionNameAttempted || this._sessionHasInfoEntry())
1028
+ if (!this._autoSessionNameEnabled || this._autoSessionNameAttempted || this._sessionHasInfoEntry())
1005
1029
  return false;
1006
1030
  const userMessages = this.agent.state.messages.filter((message) => message.role === "user");
1007
1031
  if (userMessages.length !== 1)
@@ -1142,8 +1166,10 @@ export class AgentSession {
1142
1166
  if (!this.model) {
1143
1167
  throw new Error(formatNoModelSelectedMessage());
1144
1168
  }
1145
- if (!this._modelRegistry.hasConfiguredAuth(this.model)) {
1146
- const isOAuth = this._modelRegistry.isUsingOAuth(this.model);
1169
+ const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
1170
+ (await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
1171
+ if (!hasConfiguredAuth) {
1172
+ const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
1147
1173
  if (isOAuth) {
1148
1174
  throw new Error(`Authentication failed for "${this.model.provider}". ` +
1149
1175
  `Credentials may have expired or network is unavailable. ` +
@@ -1491,7 +1517,7 @@ export class AgentSession {
1491
1517
  * @throws Error if no auth is configured for the model
1492
1518
  */
1493
1519
  async setModel(model) {
1494
- if (!this._modelRegistry.hasConfiguredAuth(model)) {
1520
+ if (!(await this._modelRuntime.checkAuth(model.provider))) {
1495
1521
  throw new Error(`No API key for ${model.provider}/${model.id}`);
1496
1522
  }
1497
1523
  if (this.isStreaming) {
@@ -1519,7 +1545,11 @@ export class AgentSession {
1519
1545
  return this._cycleAvailableModel(direction);
1520
1546
  }
1521
1547
  async _cycleScopedModel(direction) {
1522
- const scopedModels = this._scopedModels.filter((scoped) => this._modelRegistry.hasConfiguredAuth(scoped.model));
1548
+ const checks = await Promise.all(this._scopedModels.map(async (scoped) => ({
1549
+ scoped,
1550
+ auth: await this._modelRuntime.checkAuth(scoped.model.provider),
1551
+ })));
1552
+ const scopedModels = checks.filter(({ auth }) => auth !== undefined).map(({ scoped }) => scoped);
1523
1553
  if (scopedModels.length <= 1)
1524
1554
  return undefined;
1525
1555
  const currentModel = this.model;
@@ -1543,7 +1573,7 @@ export class AgentSession {
1543
1573
  return { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
1544
1574
  }
1545
1575
  async _cycleAvailableModel(direction) {
1546
- const availableModels = await this._modelRegistry.getAvailable();
1576
+ const availableModels = await this._modelRuntime.getAvailable();
1547
1577
  if (availableModels.length <= 1)
1548
1578
  return undefined;
1549
1579
  const currentModel = this.model;
@@ -1691,7 +1721,7 @@ export class AgentSession {
1691
1721
  if (!this.model) {
1692
1722
  throw new Error(formatNoModelSelectedMessage());
1693
1723
  }
1694
- const { apiKey, headers, env } = await this._getCompactionRequestAuth(this.model);
1724
+ const { apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model);
1695
1725
  if (isPiServerMode()) {
1696
1726
  this._detachPiServerTerminalAssistantFailure();
1697
1727
  const piServerResult = await compactPiServer(this.model, {
@@ -1951,16 +1981,15 @@ export class AgentSession {
1951
1981
  let headers;
1952
1982
  let env;
1953
1983
  if (this.agent.streamFn === streamSimple) {
1954
- const authResult = await this._modelRegistry.getApiKeyAndHeaders(this.model);
1955
- if (!authResult.ok || !authResult.apiKey) {
1984
+ const authResult = await this._modelRuntime.getAuth(this.model);
1985
+ if (!authResult?.auth.apiKey)
1956
1986
  return false;
1957
- }
1958
- apiKey = authResult.apiKey;
1959
- headers = authResult.headers;
1987
+ apiKey = authResult.auth.apiKey;
1988
+ headers = withoutDeletedHeaders(authResult.auth.headers);
1960
1989
  env = authResult.env;
1961
1990
  }
1962
1991
  else {
1963
- ({ apiKey, headers, env } = await this._getCompactionRequestAuth(this.model));
1992
+ ({ apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model));
1964
1993
  }
1965
1994
  if (isPiServerMode()) {
1966
1995
  this._emit({ type: "compaction_start", reason });
@@ -2247,7 +2276,7 @@ export class AgentSession {
2247
2276
  if (!currentModel) {
2248
2277
  return;
2249
2278
  }
2250
- const refreshedModel = this._modelRegistry.find(currentModel.provider, currentModel.id);
2279
+ const refreshedModel = this._modelRuntime.getModel(currentModel.provider, currentModel.id);
2251
2280
  if (!refreshedModel || refreshedModel === currentModel) {
2252
2281
  return;
2253
2282
  }
@@ -2316,7 +2345,7 @@ export class AgentSession {
2316
2345
  refreshTools: () => this._refreshToolRegistry(),
2317
2346
  getCommands,
2318
2347
  setModel: async (model) => {
2319
- if (!this.modelRegistry.hasConfiguredAuth(model))
2348
+ if (!this._modelRuntime.hasConfiguredAuth(model.provider))
2320
2349
  return false;
2321
2350
  await this.setModel(model);
2322
2351
  return true;
@@ -2356,11 +2385,11 @@ export class AgentSession {
2356
2385
  getSystemPromptOptions: () => this._baseSystemPromptOptions,
2357
2386
  }, {
2358
2387
  registerProvider: (name, config) => {
2359
- this._modelRegistry.registerProvider(name, config);
2388
+ this._modelRuntime.registerProvider(name, config);
2360
2389
  this._refreshCurrentModelFromRegistry();
2361
2390
  },
2362
2391
  unregisterProvider: (name) => {
2363
- this._modelRegistry.unregisterProvider(name);
2392
+ this._modelRuntime.unregisterProvider(name);
2364
2393
  this._refreshCurrentModelFromRegistry();
2365
2394
  },
2366
2395
  });
@@ -2462,7 +2491,7 @@ export class AgentSession {
2462
2491
  extensionsResult.runtime.flagValues.set(name, value);
2463
2492
  }
2464
2493
  }
2465
- this._extensionRunner = new ExtensionRunner(extensionsResult.extensions, extensionsResult.runtime, this._cwd, this.sessionManager, this._modelRegistry);
2494
+ this._extensionRunner = new ExtensionRunner(extensionsResult.extensions, extensionsResult.runtime, this._cwd, this.sessionManager, new ModelRegistry(this._modelRuntime));
2466
2495
  if (this._extensionRunnerRef) {
2467
2496
  this._extensionRunnerRef.current = this._extensionRunner;
2468
2497
  }
@@ -2786,7 +2815,7 @@ export class AgentSession {
2786
2815
  let summaryDetails;
2787
2816
  if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
2788
2817
  const model = this.model;
2789
- const { apiKey, headers, env } = await this._getRequiredRequestAuth(model);
2818
+ const { apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
2790
2819
  const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
2791
2820
  const result = await generateBranchSummary(entriesToSummarize, {
2792
2821
  model,