@oh-my-pi/pi-coding-agent 13.18.0 → 14.0.2

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 (235) hide show
  1. package/CHANGELOG.md +316 -1
  2. package/package.json +86 -24
  3. package/scripts/format-prompts.ts +2 -2
  4. package/src/autoresearch/apply-contract-to-state.ts +24 -0
  5. package/src/autoresearch/contract.ts +0 -44
  6. package/src/autoresearch/dashboard.ts +1 -2
  7. package/src/autoresearch/git.ts +116 -30
  8. package/src/autoresearch/helpers.ts +49 -0
  9. package/src/autoresearch/index.ts +28 -187
  10. package/src/autoresearch/prompt.md +26 -9
  11. package/src/autoresearch/state.ts +0 -6
  12. package/src/autoresearch/tools/init-experiment.ts +202 -117
  13. package/src/autoresearch/tools/log-experiment.ts +123 -178
  14. package/src/autoresearch/tools/run-experiment.ts +48 -10
  15. package/src/autoresearch/types.ts +2 -2
  16. package/src/capability/index.ts +4 -2
  17. package/src/cli/file-processor.ts +3 -3
  18. package/src/cli/grep-cli.ts +8 -8
  19. package/src/cli/grievances-cli.ts +78 -0
  20. package/src/cli/read-cli.ts +67 -0
  21. package/src/cli/setup-cli.ts +4 -4
  22. package/src/cli/update-cli.ts +3 -3
  23. package/src/cli.ts +2 -0
  24. package/src/commands/grep.ts +6 -1
  25. package/src/commands/grievances.ts +20 -0
  26. package/src/commands/read.ts +33 -0
  27. package/src/commit/agentic/agent.ts +5 -8
  28. package/src/commit/agentic/index.ts +22 -26
  29. package/src/commit/agentic/tools/analyze-file.ts +3 -3
  30. package/src/commit/agentic/tools/git-file-diff.ts +3 -6
  31. package/src/commit/agentic/tools/git-hunk.ts +3 -3
  32. package/src/commit/agentic/tools/git-overview.ts +6 -9
  33. package/src/commit/agentic/tools/index.ts +6 -8
  34. package/src/commit/agentic/tools/propose-commit.ts +4 -7
  35. package/src/commit/agentic/tools/recent-commits.ts +3 -3
  36. package/src/commit/agentic/tools/split-commit.ts +4 -4
  37. package/src/commit/agentic/validation.ts +1 -1
  38. package/src/commit/analysis/conventional.ts +4 -4
  39. package/src/commit/analysis/summary.ts +3 -3
  40. package/src/commit/changelog/generate.ts +4 -4
  41. package/src/commit/changelog/index.ts +5 -9
  42. package/src/commit/map-reduce/map-phase.ts +4 -4
  43. package/src/commit/map-reduce/reduce-phase.ts +4 -4
  44. package/src/commit/pipeline.ts +13 -16
  45. package/src/config/keybindings.ts +7 -6
  46. package/src/config/prompt-templates.ts +44 -226
  47. package/src/config/resolve-config-value.ts +4 -2
  48. package/src/config/settings-schema.ts +98 -2
  49. package/src/config/settings.ts +25 -26
  50. package/src/dap/client.ts +674 -0
  51. package/src/dap/config.ts +150 -0
  52. package/src/dap/defaults.json +211 -0
  53. package/src/dap/index.ts +4 -0
  54. package/src/dap/session.ts +1255 -0
  55. package/src/dap/types.ts +600 -0
  56. package/src/debug/log-viewer.ts +3 -2
  57. package/src/discovery/builtin.ts +1 -2
  58. package/src/discovery/codex.ts +2 -2
  59. package/src/discovery/github.ts +2 -1
  60. package/src/discovery/helpers.ts +2 -2
  61. package/src/discovery/opencode.ts +2 -2
  62. package/src/edit/diff.ts +818 -0
  63. package/src/edit/index.ts +309 -0
  64. package/src/edit/line-hash.ts +67 -0
  65. package/src/edit/modes/chunk.ts +454 -0
  66. package/src/{patch → edit/modes}/hashline.ts +741 -361
  67. package/src/{patch/applicator.ts → edit/modes/patch.ts} +420 -117
  68. package/src/{patch/fuzzy.ts → edit/modes/replace.ts} +519 -197
  69. package/src/{patch → edit}/normalize.ts +97 -76
  70. package/src/{patch/shared.ts → edit/renderer.ts} +181 -108
  71. package/src/exec/bash-executor.ts +4 -2
  72. package/src/exec/idle-timeout-watchdog.ts +126 -0
  73. package/src/exec/non-interactive-env.ts +5 -0
  74. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +6 -18
  75. package/src/extensibility/custom-commands/bundled/review/index.ts +45 -43
  76. package/src/extensibility/custom-commands/loader.ts +1 -2
  77. package/src/extensibility/custom-tools/loader.ts +34 -11
  78. package/src/extensibility/custom-tools/types.ts +1 -1
  79. package/src/extensibility/extensions/loader.ts +9 -4
  80. package/src/extensibility/extensions/runner.ts +24 -1
  81. package/src/extensibility/extensions/types.ts +4 -2
  82. package/src/extensibility/hooks/loader.ts +5 -6
  83. package/src/extensibility/hooks/types.ts +2 -2
  84. package/src/extensibility/plugins/doctor.ts +2 -1
  85. package/src/extensibility/plugins/marketplace/fetcher.ts +2 -57
  86. package/src/extensibility/plugins/marketplace/source-resolver.ts +4 -4
  87. package/src/extensibility/slash-commands.ts +3 -7
  88. package/src/index.ts +3 -1
  89. package/src/internal-urls/docs-index.generated.ts +11 -11
  90. package/src/ipy/executor.ts +58 -17
  91. package/src/ipy/gateway-coordinator.ts +6 -4
  92. package/src/ipy/kernel.ts +45 -22
  93. package/src/ipy/runtime.ts +2 -2
  94. package/src/lsp/client.ts +7 -4
  95. package/src/lsp/clients/lsp-linter-client.ts +4 -4
  96. package/src/lsp/config.ts +2 -2
  97. package/src/lsp/defaults.json +688 -154
  98. package/src/lsp/index.ts +234 -45
  99. package/src/lsp/lspmux.ts +2 -2
  100. package/src/lsp/startup-events.ts +13 -0
  101. package/src/lsp/types.ts +12 -1
  102. package/src/lsp/utils.ts +8 -1
  103. package/src/main.ts +125 -47
  104. package/src/memories/index.ts +4 -5
  105. package/src/modes/acp/acp-agent.ts +563 -163
  106. package/src/modes/acp/acp-event-mapper.ts +9 -1
  107. package/src/modes/acp/acp-mode.ts +4 -2
  108. package/src/modes/components/agent-dashboard.ts +3 -4
  109. package/src/modes/components/diff.ts +6 -7
  110. package/src/modes/components/footer.ts +9 -29
  111. package/src/modes/components/hook-editor.ts +3 -3
  112. package/src/modes/components/hook-selector.ts +6 -1
  113. package/src/modes/components/read-tool-group.ts +6 -12
  114. package/src/modes/components/session-observer-overlay.ts +472 -0
  115. package/src/modes/components/settings-defs.ts +24 -0
  116. package/src/modes/components/status-line.ts +15 -61
  117. package/src/modes/components/tool-execution.ts +1 -1
  118. package/src/modes/components/welcome.ts +1 -1
  119. package/src/modes/controllers/btw-controller.ts +2 -2
  120. package/src/modes/controllers/command-controller.ts +4 -2
  121. package/src/modes/controllers/event-controller.ts +59 -2
  122. package/src/modes/controllers/extension-ui-controller.ts +1 -0
  123. package/src/modes/controllers/input-controller.ts +15 -8
  124. package/src/modes/controllers/selector-controller.ts +26 -0
  125. package/src/modes/index.ts +20 -2
  126. package/src/modes/interactive-mode.ts +278 -69
  127. package/src/modes/rpc/host-tools.ts +186 -0
  128. package/src/modes/rpc/rpc-client.ts +178 -13
  129. package/src/modes/rpc/rpc-mode.ts +73 -3
  130. package/src/modes/rpc/rpc-types.ts +53 -1
  131. package/src/modes/session-observer-registry.ts +146 -0
  132. package/src/modes/shared.ts +0 -42
  133. package/src/modes/theme/theme.ts +80 -8
  134. package/src/modes/types.ts +4 -2
  135. package/src/modes/utils/keybinding-matchers.ts +9 -0
  136. package/src/prompts/system/custom-system-prompt.md +5 -0
  137. package/src/prompts/system/system-prompt.md +8 -1
  138. package/src/prompts/tools/chunk-edit.md +219 -0
  139. package/src/prompts/tools/debug.md +43 -0
  140. package/src/prompts/tools/grep.md +3 -0
  141. package/src/prompts/tools/lsp.md +5 -5
  142. package/src/prompts/tools/read-chunk.md +17 -0
  143. package/src/prompts/tools/read.md +19 -5
  144. package/src/sdk.ts +216 -165
  145. package/src/secrets/index.ts +1 -1
  146. package/src/secrets/obfuscator.ts +25 -17
  147. package/src/session/agent-session.ts +381 -286
  148. package/src/session/agent-storage.ts +12 -12
  149. package/src/session/compaction/branch-summarization.ts +3 -3
  150. package/src/session/compaction/compaction.ts +5 -6
  151. package/src/session/compaction/utils.ts +3 -3
  152. package/src/session/history-storage.ts +62 -19
  153. package/src/session/messages.ts +3 -3
  154. package/src/session/session-dump-format.ts +203 -0
  155. package/src/session/session-manager.ts +15 -5
  156. package/src/session/session-storage.ts +4 -2
  157. package/src/session/streaming-output.ts +1 -1
  158. package/src/session/tool-choice-queue.ts +213 -0
  159. package/src/slash-commands/builtin-registry.ts +56 -8
  160. package/src/ssh/connection-manager.ts +2 -2
  161. package/src/ssh/sshfs-mount.ts +5 -5
  162. package/src/stt/downloader.ts +4 -4
  163. package/src/stt/recorder.ts +4 -4
  164. package/src/stt/transcriber.ts +2 -2
  165. package/src/system-prompt.ts +25 -13
  166. package/src/task/agents.ts +5 -6
  167. package/src/task/commands.ts +2 -5
  168. package/src/task/executor.ts +32 -4
  169. package/src/task/index.ts +91 -82
  170. package/src/task/template.ts +2 -2
  171. package/src/task/types.ts +25 -0
  172. package/src/task/worktree.ts +131 -149
  173. package/src/tools/ask.ts +2 -3
  174. package/src/tools/ast-edit.ts +7 -7
  175. package/src/tools/ast-grep.ts +7 -7
  176. package/src/tools/auto-generated-guard.ts +36 -41
  177. package/src/tools/await-tool.ts +2 -2
  178. package/src/tools/bash.ts +5 -23
  179. package/src/tools/browser.ts +4 -5
  180. package/src/tools/calculator.ts +2 -3
  181. package/src/tools/cancel-job.ts +2 -2
  182. package/src/tools/checkpoint.ts +3 -3
  183. package/src/tools/debug.ts +1007 -0
  184. package/src/tools/exit-plan-mode.ts +3 -3
  185. package/src/tools/fetch.ts +67 -3
  186. package/src/tools/find.ts +4 -5
  187. package/src/tools/fs-cache-invalidation.ts +5 -0
  188. package/src/tools/gemini-image.ts +13 -5
  189. package/src/tools/gh.ts +130 -308
  190. package/src/tools/grep.ts +57 -9
  191. package/src/tools/index.ts +44 -22
  192. package/src/tools/inspect-image.ts +4 -4
  193. package/src/tools/output-meta.ts +1 -1
  194. package/src/tools/python.ts +19 -6
  195. package/src/tools/read.ts +211 -146
  196. package/src/tools/render-mermaid.ts +2 -3
  197. package/src/tools/render-utils.ts +20 -6
  198. package/src/tools/renderers.ts +3 -1
  199. package/src/tools/report-tool-issue.ts +80 -0
  200. package/src/tools/resolve.ts +70 -39
  201. package/src/tools/search-tool-bm25.ts +2 -2
  202. package/src/tools/ssh.ts +2 -2
  203. package/src/tools/todo-write.ts +2 -2
  204. package/src/tools/tool-timeouts.ts +1 -0
  205. package/src/tools/write.ts +5 -6
  206. package/src/tui/tree-list.ts +3 -1
  207. package/src/utils/clipboard.ts +80 -0
  208. package/src/utils/commit-message-generator.ts +2 -3
  209. package/src/utils/edit-mode.ts +49 -0
  210. package/src/utils/external-editor.ts +11 -5
  211. package/src/utils/file-display-mode.ts +6 -5
  212. package/src/utils/file-mentions.ts +8 -7
  213. package/src/utils/git.ts +1400 -0
  214. package/src/utils/image-loading.ts +98 -0
  215. package/src/utils/title-generator.ts +2 -3
  216. package/src/utils/tools-manager.ts +6 -6
  217. package/src/web/scrapers/choosealicense.ts +1 -1
  218. package/src/web/search/index.ts +3 -3
  219. package/src/web/search/render.ts +6 -4
  220. package/src/autoresearch/command-initialize.md +0 -34
  221. package/src/commit/git/errors.ts +0 -9
  222. package/src/commit/git/index.ts +0 -210
  223. package/src/commit/git/operations.ts +0 -54
  224. package/src/patch/diff.ts +0 -433
  225. package/src/patch/index.ts +0 -888
  226. package/src/patch/parser.ts +0 -532
  227. package/src/patch/types.ts +0 -292
  228. package/src/prompts/agents/oracle.md +0 -77
  229. package/src/tools/gh-cli.ts +0 -125
  230. package/src/tools/pending-action.ts +0 -49
  231. package/src/utils/child-process.ts +0 -88
  232. package/src/utils/frontmatter.ts +0 -117
  233. package/src/utils/image-input.ts +0 -274
  234. package/src/utils/mime.ts +0 -53
  235. package/src/utils/prompt-format.ts +0 -170
@@ -1,8 +1,7 @@
1
1
  import * as fs from "node:fs/promises";
2
2
  import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
3
- import { isEnoent } from "@oh-my-pi/pi-utils";
3
+ import { isEnoent, prompt } from "@oh-my-pi/pi-utils";
4
4
  import { type Static, Type } from "@sinclair/typebox";
5
- import { renderPromptTemplate } from "../config/prompt-templates";
6
5
  import exitPlanModeDescription from "../prompts/tools/exit-plan-mode.md" with { type: "text" };
7
6
  import type { ToolSession } from ".";
8
7
  import { resolvePlanPath } from "./plan-mode-guard";
@@ -46,9 +45,10 @@ export class ExitPlanModeTool implements AgentTool<typeof exitPlanModeSchema, Ex
46
45
  readonly description: string;
47
46
  readonly parameters = exitPlanModeSchema;
48
47
  readonly strict = true;
48
+ readonly concurrency = "exclusive";
49
49
 
50
50
  constructor(private readonly session: ToolSession) {
51
- this.description = renderPromptTemplate(exitPlanModeDescription);
51
+ this.description = prompt.render(exitPlanModeDescription);
52
52
  }
53
53
 
54
54
  async execute(
@@ -4,7 +4,7 @@ import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
4
4
  import type { ImageContent, TextContent } from "@oh-my-pi/pi-ai";
5
5
  import { htmlToMarkdown } from "@oh-my-pi/pi-natives";
6
6
  import { type Component, Text } from "@oh-my-pi/pi-tui";
7
- import { ptree, truncate } from "@oh-my-pi/pi-utils";
7
+ import { $which, ptree, truncate } from "@oh-my-pi/pi-utils";
8
8
  import { parseHTML } from "linkedom";
9
9
  import type { Settings } from "../config/settings";
10
10
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
@@ -23,7 +23,7 @@ import { convertWithMarkit, fetchBinary } from "../web/scrapers/utils";
23
23
  import { applyListLimit } from "./list-limit";
24
24
  import { formatStyledArtifactReference, type OutputMeta } from "./output-meta";
25
25
  import { formatExpandHint, getDomain } from "./render-utils";
26
- import { ToolAbortError } from "./tool-errors";
26
+ import { ToolAbortError, ToolError } from "./tool-errors";
27
27
  import { toolResult } from "./tool-result";
28
28
  import { clampTimeout } from "./tool-timeouts";
29
29
 
@@ -94,7 +94,7 @@ const MAX_INLINE_IMAGE_OUTPUT_BYTES = 0.75 * 1024 * 1024;
94
94
  * Check if a command exists (cross-platform)
95
95
  */
96
96
  function hasCommand(cmd: string): boolean {
97
- return Boolean(Bun.which(cmd));
97
+ return Boolean($which(cmd));
98
98
  }
99
99
 
100
100
  /**
@@ -137,6 +137,70 @@ export function isReadableUrlPath(value: string): boolean {
137
137
  return /^https?:\/\//i.test(value) || /^www\./i.test(value);
138
138
  }
139
139
 
140
+ const URL_LINE_RANGE_RE = /^L(\d+)(?:-L?(\d+))?$/i;
141
+
142
+ export interface ParsedReadUrlTarget {
143
+ path: string;
144
+ raw: boolean;
145
+ offset?: number;
146
+ limit?: number;
147
+ }
148
+
149
+ export function parseReadUrlTarget(readPath: string, sel?: string): ParsedReadUrlTarget | null {
150
+ const embedded = sel ? undefined : tryExtractEmbeddedUrlSelector(readPath);
151
+ const urlPath = embedded?.path ?? readPath;
152
+ if (!isReadableUrlPath(urlPath)) {
153
+ return null;
154
+ }
155
+
156
+ const selector = sel ?? embedded?.sel;
157
+ const raw = selector === "raw";
158
+ const lineMatch = selector ? URL_LINE_RANGE_RE.exec(selector) : null;
159
+ if (lineMatch) {
160
+ const startLine = Number.parseInt(lineMatch[1]!, 10);
161
+ if (startLine < 1) {
162
+ throw new ToolError("L0 is invalid; lines are 1-indexed. Use sel=L1.");
163
+ }
164
+ const endLine = lineMatch[2] ? Number.parseInt(lineMatch[2], 10) : undefined;
165
+ if (endLine !== undefined && endLine < startLine) {
166
+ throw new ToolError(`Invalid range L${startLine}-L${endLine}: end must be >= start.`);
167
+ }
168
+ return {
169
+ path: urlPath,
170
+ raw: false,
171
+ offset: startLine,
172
+ limit: endLine !== undefined ? endLine - startLine + 1 : undefined,
173
+ };
174
+ }
175
+
176
+ return { path: urlPath, raw };
177
+ }
178
+
179
+ function tryExtractEmbeddedUrlSelector(readPath: string): { path: string; sel?: string } | null {
180
+ const lastColonIndex = readPath.lastIndexOf(":");
181
+ if (lastColonIndex <= 0) {
182
+ return null;
183
+ }
184
+
185
+ const candidateSelector = readPath.slice(lastColonIndex + 1);
186
+ const isEmbeddedSelector = candidateSelector === "raw" || URL_LINE_RANGE_RE.test(candidateSelector);
187
+ if (!isEmbeddedSelector) {
188
+ return null;
189
+ }
190
+
191
+ const basePath = readPath.slice(0, lastColonIndex);
192
+ if (!isReadableUrlPath(basePath)) {
193
+ return null;
194
+ }
195
+
196
+ try {
197
+ new URL(basePath.startsWith("http://") || basePath.startsWith("https://") ? basePath : `https://${basePath}`);
198
+ return { path: basePath, sel: candidateSelector };
199
+ } catch {
200
+ return null;
201
+ }
202
+ }
203
+
140
204
  /**
141
205
  * Normalize MIME type (lowercase, strip charset/params)
142
206
  */
package/src/tools/find.ts CHANGED
@@ -4,10 +4,9 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
4
4
  import { FileType, type GlobMatch, glob } from "@oh-my-pi/pi-natives";
5
5
  import type { Component } from "@oh-my-pi/pi-tui";
6
6
  import { Text } from "@oh-my-pi/pi-tui";
7
- import { isEnoent, untilAborted } from "@oh-my-pi/pi-utils";
7
+ import { isEnoent, prompt, untilAborted } from "@oh-my-pi/pi-utils";
8
8
  import type { Static } from "@sinclair/typebox";
9
9
  import { Type } from "@sinclair/typebox";
10
- import { renderPromptTemplate } from "../config/prompt-templates";
11
10
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
12
11
  import type { Theme } from "../modes/theme/theme";
13
12
  import findDescription from "../prompts/tools/find.md" with { type: "text" };
@@ -86,7 +85,7 @@ export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
86
85
  options?: FindToolOptions,
87
86
  ) {
88
87
  this.#customOps = options?.operations;
89
- this.description = renderPromptTemplate(findDescription);
88
+ this.description = prompt.render(findDescription);
90
89
  }
91
90
 
92
91
  async execute(
@@ -234,8 +233,8 @@ export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
234
233
  });
235
234
  };
236
235
  const onMatch = onUpdate
237
- ? (match: GlobMatch | null) => {
238
- if (signal?.aborted || !match) return;
236
+ ? (err: Error | null, match: GlobMatch | null) => {
237
+ if (err || signal?.aborted || !match) return;
239
238
  let relativePath = match.path;
240
239
  if (!relativePath) return;
241
240
  if (match.fileType === FileType.Dir && !relativePath.endsWith("/")) {
@@ -1,10 +1,12 @@
1
1
  import { invalidateFsScanCache } from "@oh-my-pi/pi-natives";
2
+ import { invalidateChunkCache } from "../edit/modes/chunk";
2
3
 
3
4
  /**
4
5
  * Invalidate shared filesystem scan caches after a content write/update.
5
6
  */
6
7
  export function invalidateFsScanAfterWrite(path: string): void {
7
8
  invalidateFsScanCache(path);
9
+ invalidateChunkCache(path);
8
10
  }
9
11
 
10
12
  /**
@@ -12,6 +14,7 @@ export function invalidateFsScanAfterWrite(path: string): void {
12
14
  */
13
15
  export function invalidateFsScanAfterDelete(path: string): void {
14
16
  invalidateFsScanCache(path);
17
+ invalidateChunkCache(path);
15
18
  }
16
19
 
17
20
  /**
@@ -22,7 +25,9 @@ export function invalidateFsScanAfterDelete(path: string): void {
22
25
  */
23
26
  export function invalidateFsScanAfterRename(oldPath: string, newPath: string): void {
24
27
  invalidateFsScanCache(oldPath);
28
+ invalidateChunkCache(oldPath);
25
29
  if (newPath !== oldPath) {
26
30
  invalidateFsScanCache(newPath);
31
+ invalidateChunkCache(newPath);
27
32
  }
28
33
  }
@@ -1,13 +1,20 @@
1
1
  import * as os from "node:os";
2
2
  import * as path from "node:path";
3
3
  import { getAntigravityHeaders, getEnvApiKey, StringEnum } from "@oh-my-pi/pi-ai";
4
- import { $env, isEnoent, ptree, readSseJson, Snowflake, untilAborted } from "@oh-my-pi/pi-utils";
4
+ import {
5
+ $env,
6
+ isEnoent,
7
+ parseImageMetadata,
8
+ prompt,
9
+ ptree,
10
+ readSseJson,
11
+ Snowflake,
12
+ untilAborted,
13
+ } from "@oh-my-pi/pi-utils";
5
14
  import { type Static, Type } from "@sinclair/typebox";
6
15
  import type { ModelRegistry } from "../config/model-registry";
7
- import { renderPromptTemplate } from "../config/prompt-templates";
8
16
  import type { CustomTool } from "../extensibility/custom-tools/types";
9
17
  import geminiImageDescription from "../prompts/tools/gemini-image.md" with { type: "text" };
10
- import { detectSupportedImageMimeTypeFromFile } from "../utils/mime";
11
18
  import { resolveReadPath } from "./path-utils";
12
19
 
13
20
  const DEFAULT_MODEL = "gemini-3-pro-image-preview";
@@ -417,7 +424,8 @@ async function loadImageFromPath(imagePath: string, cwd: string): Promise<Inline
417
424
  throw new Error(`Image file too large: ${imagePath}`);
418
425
  }
419
426
 
420
- const mimeType = await detectSupportedImageMimeTypeFromFile(resolved);
427
+ const metadata = parseImageMetadata(buffer);
428
+ const mimeType = metadata?.mimeType;
421
429
  if (!mimeType) {
422
430
  throw new Error(`Unsupported image type: ${imagePath}`);
423
431
  }
@@ -599,7 +607,7 @@ async function parseAntigravitySseForImage(response: Response, signal?: AbortSig
599
607
  export const geminiImageTool: CustomTool<typeof geminiImageSchema, GeminiImageToolDetails> = {
600
608
  name: "generate_image",
601
609
  label: "GenerateImage",
602
- description: renderPromptTemplate(geminiImageDescription),
610
+ description: prompt.render(geminiImageDescription),
603
611
  parameters: geminiImageSchema,
604
612
  async execute(_toolCallId, params, _onUpdate, ctx, signal) {
605
613
  return untilAborted(signal, async () => {