@mariozechner/pi-coding-agent 0.52.9 → 0.52.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +20 -1
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +7 -1
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +80 -5
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/extensions/index.d.ts +1 -1
  10. package/dist/core/extensions/index.d.ts.map +1 -1
  11. package/dist/core/extensions/index.js.map +1 -1
  12. package/dist/core/extensions/runner.d.ts.map +1 -1
  13. package/dist/core/extensions/runner.js +1 -0
  14. package/dist/core/extensions/runner.js.map +1 -1
  15. package/dist/core/extensions/types.d.ts +58 -7
  16. package/dist/core/extensions/types.d.ts.map +1 -1
  17. package/dist/core/extensions/types.js.map +1 -1
  18. package/dist/core/model-resolver.d.ts +29 -1
  19. package/dist/core/model-resolver.d.ts.map +1 -1
  20. package/dist/core/model-resolver.js +94 -4
  21. package/dist/core/model-resolver.js.map +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/main.d.ts.map +1 -1
  26. package/dist/main.js +35 -14
  27. package/dist/main.js.map +1 -1
  28. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  29. package/dist/modes/interactive/components/footer.js +9 -16
  30. package/dist/modes/interactive/components/footer.js.map +1 -1
  31. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  32. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  33. package/dist/modes/interactive/interactive-mode.js +18 -0
  34. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  35. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  36. package/dist/modes/rpc/rpc-mode.js +4 -0
  37. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  38. package/dist/utils/git.d.ts +5 -1
  39. package/dist/utils/git.d.ts.map +1 -1
  40. package/dist/utils/git.js +14 -3
  41. package/dist/utils/git.js.map +1 -1
  42. package/dist/utils/tools-manager.d.ts.map +1 -1
  43. package/dist/utils/tools-manager.js +1 -1
  44. package/dist/utils/tools-manager.js.map +1 -1
  45. package/docs/extensions.md +44 -1
  46. package/docs/packages.md +5 -7
  47. package/docs/rpc.md +1 -1
  48. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  49. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  50. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  51. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  52. package/examples/extensions/trigger-compact.ts +1 -1
  53. package/examples/extensions/with-deps/package-lock.json +2 -2
  54. package/examples/extensions/with-deps/package.json +1 -1
  55. package/package.json +4 -4
@@ -26,6 +26,7 @@ import { exportSessionToHtml } from "./export-html/index.js";
26
26
  import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
27
27
  import { ExtensionRunner, wrapRegisteredTools, wrapToolsWithExtensions, } from "./extensions/index.js";
28
28
  import { expandPromptTemplate } from "./prompt-templates.js";
29
+ import { getLatestCompactionEntry } from "./session-manager.js";
29
30
  import { BUILTIN_SLASH_COMMANDS } from "./slash-commands.js";
30
31
  import { buildSystemPrompt } from "./system-prompt.js";
31
32
  import { createAllTools } from "./tools/index.js";
@@ -264,6 +265,57 @@ export class AgentSession {
264
265
  await this._extensionRunner.emit(extensionEvent);
265
266
  this._turnIndex++;
266
267
  }
268
+ else if (event.type === "message_start") {
269
+ const extensionEvent = {
270
+ type: "message_start",
271
+ message: event.message,
272
+ };
273
+ await this._extensionRunner.emit(extensionEvent);
274
+ }
275
+ else if (event.type === "message_update") {
276
+ const extensionEvent = {
277
+ type: "message_update",
278
+ message: event.message,
279
+ assistantMessageEvent: event.assistantMessageEvent,
280
+ };
281
+ await this._extensionRunner.emit(extensionEvent);
282
+ }
283
+ else if (event.type === "message_end") {
284
+ const extensionEvent = {
285
+ type: "message_end",
286
+ message: event.message,
287
+ };
288
+ await this._extensionRunner.emit(extensionEvent);
289
+ }
290
+ else if (event.type === "tool_execution_start") {
291
+ const extensionEvent = {
292
+ type: "tool_execution_start",
293
+ toolCallId: event.toolCallId,
294
+ toolName: event.toolName,
295
+ args: event.args,
296
+ };
297
+ await this._extensionRunner.emit(extensionEvent);
298
+ }
299
+ else if (event.type === "tool_execution_update") {
300
+ const extensionEvent = {
301
+ type: "tool_execution_update",
302
+ toolCallId: event.toolCallId,
303
+ toolName: event.toolName,
304
+ args: event.args,
305
+ partialResult: event.partialResult,
306
+ };
307
+ await this._extensionRunner.emit(extensionEvent);
308
+ }
309
+ else if (event.type === "tool_execution_end") {
310
+ const extensionEvent = {
311
+ type: "tool_execution_end",
312
+ toolCallId: event.toolCallId,
313
+ toolName: event.toolName,
314
+ result: event.result,
315
+ isError: event.isError,
316
+ };
317
+ await this._extensionRunner.emit(extensionEvent);
318
+ }
267
319
  }
268
320
  /**
269
321
  * Subscribe to agent events.
@@ -1190,8 +1242,8 @@ export class AgentSession {
1190
1242
  // The error shouldn't trigger another compaction since we already compacted.
1191
1243
  // Example: opus fails → switch to codex → compact → switch back to opus → opus error
1192
1244
  // is still in context but shouldn't trigger compaction again.
1193
- const compactionEntry = this.sessionManager.getBranch().find((e) => e.type === "compaction");
1194
- const errorIsFromBeforeCompaction = compactionEntry && assistantMessage.timestamp < new Date(compactionEntry.timestamp).getTime();
1245
+ const compactionEntry = getLatestCompactionEntry(this.sessionManager.getBranch());
1246
+ const errorIsFromBeforeCompaction = compactionEntry !== null && assistantMessage.timestamp < new Date(compactionEntry.timestamp).getTime();
1195
1247
  // Case 1: Overflow - LLM returned context overflow error
1196
1248
  if (sameModel && !errorIsFromBeforeCompaction && isContextOverflow(assistantMessage, contextWindow)) {
1197
1249
  // Remove the error message from agent state (it IS saved to session for history,
@@ -2186,15 +2238,38 @@ export class AgentSession {
2186
2238
  const contextWindow = model.contextWindow ?? 0;
2187
2239
  if (contextWindow <= 0)
2188
2240
  return undefined;
2241
+ // After compaction, the last assistant usage reflects pre-compaction context size.
2242
+ // We can only trust usage from an assistant that responded after the latest compaction.
2243
+ // If no such assistant exists, context token count is unknown until the next LLM response.
2244
+ const branchEntries = this.sessionManager.getBranch();
2245
+ const latestCompaction = getLatestCompactionEntry(branchEntries);
2246
+ if (latestCompaction) {
2247
+ // Check if there's a valid assistant usage after the compaction boundary
2248
+ const compactionIndex = branchEntries.lastIndexOf(latestCompaction);
2249
+ let hasPostCompactionUsage = false;
2250
+ for (let i = branchEntries.length - 1; i > compactionIndex; i--) {
2251
+ const entry = branchEntries[i];
2252
+ if (entry.type === "message" && entry.message.role === "assistant") {
2253
+ const assistant = entry.message;
2254
+ if (assistant.stopReason !== "aborted" && assistant.stopReason !== "error") {
2255
+ const contextTokens = calculateContextTokens(assistant.usage);
2256
+ if (contextTokens > 0) {
2257
+ hasPostCompactionUsage = true;
2258
+ }
2259
+ break;
2260
+ }
2261
+ }
2262
+ }
2263
+ if (!hasPostCompactionUsage) {
2264
+ return { tokens: null, contextWindow, percent: null };
2265
+ }
2266
+ }
2189
2267
  const estimate = estimateContextTokens(this.messages);
2190
2268
  const percent = (estimate.tokens / contextWindow) * 100;
2191
2269
  return {
2192
2270
  tokens: estimate.tokens,
2193
2271
  contextWindow,
2194
2272
  percent,
2195
- usageTokens: estimate.usageTokens,
2196
- trailingTokens: estimate.trailingTokens,
2197
- lastUsageIndex: estimate.lastUsageIndex,
2198
2273
  };
2199
2274
  }
2200
2275
  /**