@averyyy/pi-coding-agent 0.80.3-piclient.9 → 0.80.6-piclient.4

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 (171) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +2 -2
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +4 -4
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli/config-selector.d.ts +4 -2
  7. package/dist/cli/config-selector.d.ts.map +1 -1
  8. package/dist/cli/config-selector.js +1 -1
  9. package/dist/cli/config-selector.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +20 -4
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +95 -22
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/auth-storage.d.ts.map +1 -1
  15. package/dist/core/auth-storage.js +13 -5
  16. package/dist/core/auth-storage.js.map +1 -1
  17. package/dist/core/cache-stats.d.ts +49 -0
  18. package/dist/core/cache-stats.d.ts.map +1 -0
  19. package/dist/core/cache-stats.js +101 -0
  20. package/dist/core/cache-stats.js.map +1 -0
  21. package/dist/core/compaction/compaction.d.ts +1 -2
  22. package/dist/core/compaction/compaction.d.ts.map +1 -1
  23. package/dist/core/compaction/compaction.js +56 -81
  24. package/dist/core/compaction/compaction.js.map +1 -1
  25. package/dist/core/extensions/index.d.ts +1 -1
  26. package/dist/core/extensions/index.d.ts.map +1 -1
  27. package/dist/core/extensions/index.js.map +1 -1
  28. package/dist/core/extensions/loader.d.ts.map +1 -1
  29. package/dist/core/extensions/loader.js +6 -0
  30. package/dist/core/extensions/loader.js.map +1 -1
  31. package/dist/core/extensions/runner.d.ts +5 -3
  32. package/dist/core/extensions/runner.d.ts.map +1 -1
  33. package/dist/core/extensions/runner.js +38 -0
  34. package/dist/core/extensions/runner.js.map +1 -1
  35. package/dist/core/extensions/types.d.ts +33 -11
  36. package/dist/core/extensions/types.d.ts.map +1 -1
  37. package/dist/core/extensions/types.js.map +1 -1
  38. package/dist/core/index.d.ts +1 -1
  39. package/dist/core/index.d.ts.map +1 -1
  40. package/dist/core/index.js.map +1 -1
  41. package/dist/core/keybindings.d.ts.map +1 -1
  42. package/dist/core/keybindings.js +3 -6
  43. package/dist/core/keybindings.js.map +1 -1
  44. package/dist/core/model-registry.d.ts +4 -6
  45. package/dist/core/model-registry.d.ts.map +1 -1
  46. package/dist/core/model-registry.js +34 -8
  47. package/dist/core/model-registry.js.map +1 -1
  48. package/dist/core/model-resolver.d.ts +10 -0
  49. package/dist/core/model-resolver.d.ts.map +1 -1
  50. package/dist/core/model-resolver.js +14 -17
  51. package/dist/core/model-resolver.js.map +1 -1
  52. package/dist/core/package-manager.d.ts +4 -1
  53. package/dist/core/package-manager.d.ts.map +1 -1
  54. package/dist/core/package-manager.js +68 -26
  55. package/dist/core/package-manager.js.map +1 -1
  56. package/dist/core/pi-server-client.d.ts.map +1 -1
  57. package/dist/core/pi-server-client.js +122 -5
  58. package/dist/core/pi-server-client.js.map +1 -1
  59. package/dist/core/provider-attribution.d.ts.map +1 -1
  60. package/dist/core/provider-attribution.js +0 -10
  61. package/dist/core/provider-attribution.js.map +1 -1
  62. package/dist/core/resource-loader.d.ts +2 -2
  63. package/dist/core/resource-loader.d.ts.map +1 -1
  64. package/dist/core/resource-loader.js +6 -7
  65. package/dist/core/resource-loader.js.map +1 -1
  66. package/dist/core/sdk.d.ts +1 -1
  67. package/dist/core/sdk.d.ts.map +1 -1
  68. package/dist/core/sdk.js +8 -1
  69. package/dist/core/sdk.js.map +1 -1
  70. package/dist/core/session-manager.d.ts +20 -1
  71. package/dist/core/session-manager.d.ts.map +1 -1
  72. package/dist/core/session-manager.js +97 -68
  73. package/dist/core/session-manager.js.map +1 -1
  74. package/dist/core/settings-manager.d.ts +9 -3
  75. package/dist/core/settings-manager.d.ts.map +1 -1
  76. package/dist/core/settings-manager.js +10 -1
  77. package/dist/core/settings-manager.js.map +1 -1
  78. package/dist/core/slash-commands.d.ts +1 -0
  79. package/dist/core/slash-commands.d.ts.map +1 -1
  80. package/dist/core/slash-commands.js +3 -3
  81. package/dist/core/slash-commands.js.map +1 -1
  82. package/dist/core/tools/edit.d.ts.map +1 -1
  83. package/dist/core/tools/edit.js +2 -2
  84. package/dist/core/tools/edit.js.map +1 -1
  85. package/dist/index.d.ts +3 -2
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2 -1
  88. package/dist/index.js.map +1 -1
  89. package/dist/main.d.ts +2 -2
  90. package/dist/main.d.ts.map +1 -1
  91. package/dist/main.js +1 -0
  92. package/dist/main.js.map +1 -1
  93. package/dist/modes/interactive/components/config-selector.d.ts +34 -3
  94. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  95. package/dist/modes/interactive/components/config-selector.js +280 -25
  96. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  97. package/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  98. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -0
  99. package/dist/modes/interactive/components/custom-entry.js +52 -0
  100. package/dist/modes/interactive/components/custom-entry.js.map +1 -0
  101. package/dist/modes/interactive/components/footer.d.ts +4 -0
  102. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  103. package/dist/modes/interactive/components/footer.js +1 -1
  104. package/dist/modes/interactive/components/footer.js.map +1 -1
  105. package/dist/modes/interactive/components/oauth-selector.d.ts +3 -1
  106. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  107. package/dist/modes/interactive/components/oauth-selector.js +17 -6
  108. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  109. package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  110. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/settings-selector.js +12 -1
  112. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  113. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  114. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  115. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  116. package/dist/modes/interactive/interactive-mode.d.ts +15 -3
  117. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  118. package/dist/modes/interactive/interactive-mode.js +302 -61
  119. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  120. package/dist/modes/interactive/theme/dark.json +1 -0
  121. package/dist/modes/interactive/theme/light.json +1 -0
  122. package/dist/modes/interactive/theme/theme-schema.json +6 -2
  123. package/dist/modes/interactive/theme/theme.d.ts +3 -2
  124. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  125. package/dist/modes/interactive/theme/theme.js +10 -3
  126. package/dist/modes/interactive/theme/theme.js.map +1 -1
  127. package/dist/modes/print-mode.d.ts.map +1 -1
  128. package/dist/modes/print-mode.js +1 -1
  129. package/dist/modes/print-mode.js.map +1 -1
  130. package/dist/modes/rpc/rpc-client.d.ts +6 -6
  131. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  132. package/dist/modes/rpc/rpc-client.js +3 -3
  133. package/dist/modes/rpc/rpc-client.js.map +1 -1
  134. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  135. package/dist/modes/rpc/rpc-mode.js +4 -1
  136. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  137. package/dist/package-manager-cli.d.ts +2 -2
  138. package/dist/package-manager-cli.d.ts.map +1 -1
  139. package/dist/package-manager-cli.js +71 -17
  140. package/dist/package-manager-cli.js.map +1 -1
  141. package/dist/utils/clipboard-image.d.ts.map +1 -1
  142. package/dist/utils/clipboard-image.js +1 -1
  143. package/dist/utils/clipboard-image.js.map +1 -1
  144. package/docs/custom-provider.md +4 -3
  145. package/docs/extensions.md +75 -18
  146. package/docs/models.md +49 -8
  147. package/docs/packages.md +2 -2
  148. package/docs/rpc.md +15 -5
  149. package/docs/sdk.md +51 -1
  150. package/docs/session-format.md +18 -8
  151. package/docs/settings.md +3 -2
  152. package/docs/themes.md +5 -3
  153. package/docs/tui.md +1 -1
  154. package/docs/usage.md +2 -2
  155. package/examples/extensions/README.md +1 -0
  156. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  157. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  158. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  159. package/examples/extensions/entry-renderer.ts +41 -0
  160. package/examples/extensions/gondolin/package-lock.json +2 -2
  161. package/examples/extensions/gondolin/package.json +1 -1
  162. package/examples/extensions/preset.ts +2 -2
  163. package/examples/extensions/question.ts +1 -0
  164. package/examples/extensions/reload-runtime.ts +2 -2
  165. package/examples/extensions/sandbox/package-lock.json +2 -2
  166. package/examples/extensions/sandbox/package.json +1 -1
  167. package/examples/extensions/with-deps/package-lock.json +2 -2
  168. package/examples/extensions/with-deps/package.json +1 -1
  169. package/examples/sdk/12-full-control.ts +1 -1
  170. package/examples/sdk/README.md +1 -1
  171. package/package.json +4 -4
@@ -151,6 +151,9 @@ export class AgentSession {
151
151
  // Event subscription state
152
152
  _unsubscribeAgent;
153
153
  _eventListeners = [];
154
+ _isAgentRunActive = false;
155
+ _idleWaitPromise;
156
+ _resolveIdleWait;
154
157
  /** Tracks pending steering messages for UI display. Removed when delivered. */
155
158
  _steeringMessages = [];
156
159
  /** Tracks pending follow-up messages for UI display. Removed when delivered. */
@@ -430,6 +433,33 @@ export class AgentSession {
430
433
  followUp: [...this._followUpMessages],
431
434
  });
432
435
  }
436
+ _getIdleWaitPromise() {
437
+ if (!this._idleWaitPromise) {
438
+ this._idleWaitPromise = new Promise((resolve) => {
439
+ this._resolveIdleWait = resolve;
440
+ });
441
+ }
442
+ return this._idleWaitPromise;
443
+ }
444
+ _resolveIdleWaitIfIdle() {
445
+ if (this._isAgentRunActive || !this._resolveIdleWait) {
446
+ return;
447
+ }
448
+ const resolve = this._resolveIdleWait;
449
+ this._idleWaitPromise = undefined;
450
+ this._resolveIdleWait = undefined;
451
+ resolve();
452
+ }
453
+ async _emitAgentSettled() {
454
+ this._isAgentRunActive = false;
455
+ try {
456
+ await this._extensionRunner.emit({ type: "agent_settled" });
457
+ this._emit({ type: "agent_settled" });
458
+ }
459
+ finally {
460
+ this._resolveIdleWaitIfIdle();
461
+ }
462
+ }
433
463
  // Track last assistant message for auto-compaction check
434
464
  _lastAssistantMessage = undefined;
435
465
  /** Internal handler for agent events - shared by subscribe and reconnect */
@@ -654,7 +684,16 @@ export class AgentSession {
654
684
  };
655
685
  const replacement = await this._extensionRunner.emitMessageEnd(extensionEvent);
656
686
  if (replacement) {
657
- this._replaceMessageInPlace(event.message, replacement);
687
+ // Untyped extension handlers can return messages with null/missing content;
688
+ // normalize so it never enters agent state or session history.
689
+ const normalized = (replacement.role === "user" ||
690
+ replacement.role === "assistant" ||
691
+ replacement.role === "toolResult" ||
692
+ replacement.role === "custom") &&
693
+ replacement.content == null
694
+ ? { ...replacement, content: [] }
695
+ : replacement;
696
+ this._replaceMessageInPlace(event.message, normalized);
658
697
  }
659
698
  }
660
699
  else if (event.type === "tool_execution_start") {
@@ -757,9 +796,13 @@ export class AgentSession {
757
796
  get thinkingLevel() {
758
797
  return this.agent.state.thinkingLevel;
759
798
  }
760
- /** Whether agent is currently streaming a response */
799
+ /** Whether the session is currently processing an agent run or post-run continuation. */
761
800
  get isStreaming() {
762
- return this.agent.state.isStreaming;
801
+ return this._isAgentRunActive;
802
+ }
803
+ /** Whether the session has no active agent run, retry, auto-compaction, or queued continuation. */
804
+ get isIdle() {
805
+ return !this._isAgentRunActive;
763
806
  }
764
807
  /** Current effective system prompt (includes any per-turn extension modifications) */
765
808
  get systemPrompt() {
@@ -912,6 +955,7 @@ export class AgentSession {
912
955
  // =========================================================================
913
956
  async _runAgentPrompt(messages) {
914
957
  this._resetValidationHintState();
958
+ this._isAgentRunActive = true;
915
959
  try {
916
960
  await this.agent.prompt(messages);
917
961
  while (await this._handlePostAgentRun()) {
@@ -937,6 +981,7 @@ export class AgentSession {
937
981
  finally {
938
982
  this._systemPromptOverride = undefined;
939
983
  this._flushPendingBashMessages();
984
+ await this._emitAgentSettled();
940
985
  }
941
986
  }
942
987
  _sessionHasInfoEntry() {
@@ -1140,7 +1185,8 @@ export class AgentSession {
1140
1185
  messages.push({
1141
1186
  role: "custom",
1142
1187
  customType: msg.customType,
1143
- content: msg.content,
1188
+ // Untyped extensions can pass null/missing content; normalize at ingestion.
1189
+ content: msg.content ?? [],
1144
1190
  display: msg.display,
1145
1191
  details: msg.details,
1146
1192
  timestamp: Date.now(),
@@ -1319,7 +1365,8 @@ export class AgentSession {
1319
1365
  const appMessage = {
1320
1366
  role: "custom",
1321
1367
  customType: message.customType,
1322
- content: message.content,
1368
+ // Untyped extensions can pass null/missing content; normalize at ingestion.
1369
+ content: message.content ?? [],
1323
1370
  display: message.display,
1324
1371
  details: message.details,
1325
1372
  timestamp: Date.now(),
@@ -1417,7 +1464,13 @@ export class AgentSession {
1417
1464
  async abort() {
1418
1465
  this.abortRetry();
1419
1466
  this.agent.abort();
1420
- await this.agent.waitForIdle();
1467
+ await this.waitForIdle();
1468
+ }
1469
+ async waitForIdle() {
1470
+ if (this.isIdle) {
1471
+ return;
1472
+ }
1473
+ await this._getIdleWaitPromise();
1421
1474
  }
1422
1475
  // =========================================================================
1423
1476
  // Model Management
@@ -2245,7 +2298,11 @@ export class AgentSession {
2245
2298
  });
2246
2299
  },
2247
2300
  appendEntry: (customType, data) => {
2248
- this.sessionManager.appendCustomEntry(customType, data);
2301
+ const entryId = this.sessionManager.appendCustomEntry(customType, data);
2302
+ const entry = this.sessionManager.getEntry(entryId);
2303
+ if (entry) {
2304
+ this._emit({ type: "entry_appended", entry });
2305
+ }
2249
2306
  },
2250
2307
  setSessionName: (name) => {
2251
2308
  this.setSessionName(name);
@@ -2271,7 +2328,7 @@ export class AgentSession {
2271
2328
  setThinkingLevel: (level) => this.setThinkingLevel(level),
2272
2329
  }, {
2273
2330
  getModel: () => this.model,
2274
- isIdle: () => !this.isStreaming,
2331
+ isIdle: () => this.isIdle,
2275
2332
  isProjectTrusted: () => this.settingsManager.isProjectTrusted(),
2276
2333
  getSignal: () => this.agent.signal,
2277
2334
  abort: () => {
@@ -2863,28 +2920,44 @@ export class AgentSession {
2863
2920
  return "";
2864
2921
  }
2865
2922
  /**
2866
- * Get session statistics.
2923
+ * Get session statistics. Aggregates over ALL session entries (including
2924
+ * history that was compacted away), so token/cost totals reflect what was
2925
+ * actually billed across the session.
2867
2926
  */
2868
2927
  getSessionStats() {
2869
- const state = this.state;
2870
- const userMessages = state.messages.filter((m) => m.role === "user").length;
2871
- const assistantMessages = state.messages.filter((m) => m.role === "assistant").length;
2872
- const toolResults = state.messages.filter((m) => m.role === "toolResult").length;
2928
+ let userMessages = 0;
2929
+ let assistantMessages = 0;
2930
+ let toolResults = 0;
2931
+ let totalMessages = 0;
2873
2932
  let toolCalls = 0;
2874
2933
  let totalInput = 0;
2875
2934
  let totalOutput = 0;
2876
2935
  let totalCacheRead = 0;
2877
2936
  let totalCacheWrite = 0;
2878
2937
  let totalCost = 0;
2879
- for (const message of state.messages) {
2880
- if (message.role === "assistant") {
2938
+ for (const entry of this.sessionManager.getEntries()) {
2939
+ if (entry.type !== "message")
2940
+ continue;
2941
+ totalMessages++;
2942
+ const message = entry.message;
2943
+ if (message.role === "user") {
2944
+ userMessages++;
2945
+ }
2946
+ else if (message.role === "toolResult") {
2947
+ toolResults++;
2948
+ }
2949
+ else if (message.role === "assistant") {
2950
+ assistantMessages++;
2881
2951
  const assistantMsg = message;
2882
- toolCalls += assistantMsg.content.filter((c) => c.type === "toolCall").length;
2883
- totalInput += assistantMsg.usage.input;
2884
- totalOutput += assistantMsg.usage.output;
2885
- totalCacheRead += assistantMsg.usage.cacheRead;
2886
- totalCacheWrite += assistantMsg.usage.cacheWrite;
2887
- totalCost += assistantMsg.usage.cost.total;
2952
+ if (Array.isArray(assistantMsg.content)) {
2953
+ toolCalls += assistantMsg.content.filter((c) => c.type === "toolCall").length;
2954
+ }
2955
+ const usage = assistantMsg.usage;
2956
+ totalInput += usage.input;
2957
+ totalOutput += usage.output;
2958
+ totalCacheRead += usage.cacheRead;
2959
+ totalCacheWrite += usage.cacheWrite;
2960
+ totalCost += usage.cost.total;
2888
2961
  }
2889
2962
  }
2890
2963
  return {
@@ -2894,7 +2967,7 @@ export class AgentSession {
2894
2967
  assistantMessages,
2895
2968
  toolCalls,
2896
2969
  toolResults,
2897
- totalMessages: state.messages.length,
2970
+ totalMessages,
2898
2971
  tokens: {
2899
2972
  input: totalInput,
2900
2973
  output: totalOutput,