@mariozechner/pi-coding-agent 0.57.1 → 0.58.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +2 -0
  3. package/dist/core/agent-session.d.ts +9 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +57 -9
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/extensions/index.d.ts +1 -1
  8. package/dist/core/extensions/index.d.ts.map +1 -1
  9. package/dist/core/extensions/index.js +1 -1
  10. package/dist/core/extensions/index.js.map +1 -1
  11. package/dist/core/extensions/wrapper.d.ts +4 -11
  12. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  13. package/dist/core/extensions/wrapper.js +4 -78
  14. package/dist/core/extensions/wrapper.js.map +1 -1
  15. package/dist/core/index.d.ts +1 -1
  16. package/dist/core/index.d.ts.map +1 -1
  17. package/dist/core/index.js +1 -1
  18. package/dist/core/index.js.map +1 -1
  19. package/dist/core/session-manager.d.ts +1 -0
  20. package/dist/core/session-manager.d.ts.map +1 -1
  21. package/dist/core/session-manager.js +1 -1
  22. package/dist/core/session-manager.js.map +1 -1
  23. package/dist/core/system-prompt.d.ts.map +1 -1
  24. package/dist/core/system-prompt.js +5 -15
  25. package/dist/core/system-prompt.js.map +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/utils/exif-orientation.d.ts +5 -0
  31. package/dist/utils/exif-orientation.d.ts.map +1 -0
  32. package/dist/utils/exif-orientation.js +158 -0
  33. package/dist/utils/exif-orientation.js.map +1 -0
  34. package/dist/utils/image-convert.d.ts.map +1 -1
  35. package/dist/utils/image-convert.js +5 -1
  36. package/dist/utils/image-convert.js.map +1 -1
  37. package/dist/utils/image-resize.d.ts.map +1 -1
  38. package/dist/utils/image-resize.js +6 -1
  39. package/dist/utils/image-resize.js.map +1 -1
  40. package/docs/extensions.md +16 -5
  41. package/docs/terminal-setup.md +10 -2
  42. package/examples/extensions/antigravity-image-gen.ts +5 -4
  43. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  44. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  45. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  46. package/examples/extensions/custom-provider-gitlab-duo/test.ts +2 -2
  47. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  48. package/examples/extensions/preset.ts +2 -3
  49. package/examples/extensions/sandbox/index.ts +2 -3
  50. package/examples/extensions/tool-override.ts +2 -3
  51. package/examples/extensions/with-deps/package-lock.json +2 -2
  52. package/examples/extensions/with-deps/package.json +1 -1
  53. package/package.json +4 -4
@@ -24,7 +24,7 @@ import { calculateContextTokens, collectEntriesForBranchSummary, compact, estima
24
24
  import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
25
25
  import { exportSessionToHtml } from "./export-html/index.js";
26
26
  import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
27
- import { ExtensionRunner, wrapRegisteredTools, wrapToolsWithExtensions, } from "./extensions/index.js";
27
+ import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
28
28
  import { expandPromptTemplate } from "./prompt-templates.js";
29
29
  import { getLatestCompactionEntry } from "./session-manager.js";
30
30
  import { BUILTIN_SLASH_COMMANDS } from "./slash-commands.js";
@@ -122,6 +122,7 @@ export class AgentSession {
122
122
  // Always subscribe to agent events for internal handling
123
123
  // (session persistence, extensions, auto-compaction, retry logic)
124
124
  this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
125
+ this._installAgentToolHooks();
125
126
  this._buildRuntime({
126
127
  activeToolNames: this._initialActiveToolNames,
127
128
  includeAllExtensionTools: true,
@@ -131,6 +132,59 @@ export class AgentSession {
131
132
  get modelRegistry() {
132
133
  return this._modelRegistry;
133
134
  }
135
+ /**
136
+ * Install tool hooks once on the Agent instance.
137
+ *
138
+ * The callbacks read `this._extensionRunner` at execution time, so extension reload swaps in the
139
+ * new runner without reinstalling hooks. Extension-specific tool wrappers are still used to adapt
140
+ * registered tool execution to the extension context. Tool call and tool result interception now
141
+ * happens here instead of in wrappers.
142
+ */
143
+ _installAgentToolHooks() {
144
+ this.agent.setBeforeToolCall(async ({ toolCall, args }) => {
145
+ const runner = this._extensionRunner;
146
+ if (!runner?.hasHandlers("tool_call")) {
147
+ return undefined;
148
+ }
149
+ await this._agentEventQueue;
150
+ try {
151
+ return await runner.emitToolCall({
152
+ type: "tool_call",
153
+ toolName: toolCall.name,
154
+ toolCallId: toolCall.id,
155
+ input: args,
156
+ });
157
+ }
158
+ catch (err) {
159
+ if (err instanceof Error) {
160
+ throw err;
161
+ }
162
+ throw new Error(`Extension failed, blocking execution: ${String(err)}`);
163
+ }
164
+ });
165
+ this.agent.setAfterToolCall(async ({ toolCall, args, result, isError }) => {
166
+ const runner = this._extensionRunner;
167
+ if (!runner?.hasHandlers("tool_result")) {
168
+ return undefined;
169
+ }
170
+ const hookResult = await runner.emitToolResult({
171
+ type: "tool_result",
172
+ toolName: toolCall.name,
173
+ toolCallId: toolCall.id,
174
+ input: args,
175
+ content: result.content,
176
+ details: isError ? undefined : result.details,
177
+ isError,
178
+ });
179
+ if (!hookResult || isError) {
180
+ return undefined;
181
+ }
182
+ return {
183
+ content: hookResult.content,
184
+ details: hookResult.details,
185
+ };
186
+ });
187
+ }
134
188
  // =========================================================================
135
189
  // Event Subscription
136
190
  // =========================================================================
@@ -1719,13 +1773,7 @@ export class AgentSession {
1719
1773
  for (const tool of wrappedExtensionTools) {
1720
1774
  toolRegistry.set(tool.name, tool);
1721
1775
  }
1722
- if (this._extensionRunner) {
1723
- const wrappedAllTools = wrapToolsWithExtensions(Array.from(toolRegistry.values()), this._extensionRunner);
1724
- this._toolRegistry = new Map(wrappedAllTools.map((tool) => [tool.name, tool]));
1725
- }
1726
- else {
1727
- this._toolRegistry = toolRegistry;
1728
- }
1776
+ this._toolRegistry = toolRegistry;
1729
1777
  const nextActiveToolNames = options?.activeToolNames
1730
1778
  ? [...options.activeToolNames]
1731
1779
  : [...previousActiveToolNames];
@@ -1817,7 +1865,7 @@ export class AgentSession {
1817
1865
  return false;
1818
1866
  const err = message.errorMessage;
1819
1867
  // Match: overloaded_error, rate limit, 429, 500, 502, 503, 504, service unavailable, connection errors, fetch failed, terminated, retry delay exceeded
1820
- return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server error|internal error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay/i.test(err);
1868
+ return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay/i.test(err);
1821
1869
  }
1822
1870
  /**
1823
1871
  * Handle retryable errors with exponential backoff.