@morphllm/morphsdk 0.2.145 → 0.2.146

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 (205) hide show
  1. package/dist/{chunk-HBIW2XV2.js → chunk-4PBUB77N.js} +2 -2
  2. package/dist/{chunk-SUE4GYA2.js → chunk-BDHKL3MT.js} +2 -2
  3. package/dist/{chunk-S54SPKX3.js → chunk-BIQ7234U.js} +2 -2
  4. package/dist/{chunk-I3J46TSB.js → chunk-DKODF3YG.js} +4 -5
  5. package/dist/chunk-DKODF3YG.js.map +1 -0
  6. package/dist/{chunk-MRPASJBX.js → chunk-E45FW5EK.js} +2 -2
  7. package/dist/{chunk-BXRJYLRS.js → chunk-E4YKEKGW.js} +2 -2
  8. package/dist/{chunk-G23BI5CQ.js → chunk-EU7OLX4Z.js} +2 -2
  9. package/dist/chunk-EUHNJMWL.js +409 -0
  10. package/dist/chunk-EUHNJMWL.js.map +1 -0
  11. package/dist/{chunk-HE7K2QNQ.js → chunk-FBOJJ3UY.js} +17 -17
  12. package/dist/{chunk-HYRHI2UL.js → chunk-FIVYDIHX.js} +1 -1
  13. package/dist/{chunk-GXM3G7Z4.js → chunk-FYO46OT6.js} +2 -2
  14. package/dist/{chunk-GHPQYSSF.js → chunk-GJUB3ECP.js} +2 -2
  15. package/dist/{chunk-4Y2NM6JD.js → chunk-HZOTLGJH.js} +2 -42
  16. package/dist/chunk-HZOTLGJH.js.map +1 -0
  17. package/dist/{chunk-MTJ3PR4M.js → chunk-I7SFRYTX.js} +2 -2
  18. package/dist/{chunk-PX7ODEML.js → chunk-J2HIK4GB.js} +2 -2
  19. package/dist/{chunk-RZXS4ADX.js → chunk-JSWNBCGS.js} +2 -2
  20. package/dist/{chunk-GXCWKYGU.js → chunk-KYKRRF7E.js} +2 -2
  21. package/dist/{chunk-N7TTZIBK.js → chunk-MMBQKN4G.js} +2 -2
  22. package/dist/{chunk-B3AKP3RA.js → chunk-NF2QWJDY.js} +2 -31
  23. package/dist/chunk-NF2QWJDY.js.map +1 -0
  24. package/dist/{chunk-JMUAQQJU.js → chunk-NKUSUSVI.js} +3 -3
  25. package/dist/{chunk-VRV5UYTN.js → chunk-OV57JBMB.js} +2 -2
  26. package/dist/{chunk-EPIOAODF.js → chunk-Q36MNOFA.js} +2 -2
  27. package/dist/{chunk-JRBU4UNP.js → chunk-QRSWXP4K.js} +2 -2
  28. package/dist/{chunk-KELRCMA6.js → chunk-SJYAKVSS.js} +2 -2
  29. package/dist/{chunk-KELRCMA6.js.map → chunk-SJYAKVSS.js.map} +1 -1
  30. package/dist/{chunk-IRWHN55G.js → chunk-T564HFSH.js} +1 -1
  31. package/dist/{chunk-6CFKWZK3.js → chunk-UVNENJ6H.js} +3 -3
  32. package/dist/{chunk-5FCXLQJU.js → chunk-UYPWKQKV.js} +2 -2
  33. package/dist/{chunk-BAF33L6C.js → chunk-V73GO5AJ.js} +2 -2
  34. package/dist/chunk-VCKJ22DX.js +131 -0
  35. package/dist/chunk-VCKJ22DX.js.map +1 -0
  36. package/dist/{chunk-XL7R3XN5.js → chunk-VZ6VYRQB.js} +2 -2
  37. package/dist/{chunk-4LWMPKSB.js → chunk-YIETFYCL.js} +44 -71
  38. package/dist/chunk-YIETFYCL.js.map +1 -0
  39. package/dist/client.cjs +438 -426
  40. package/dist/client.cjs.map +1 -1
  41. package/dist/client.js +27 -26
  42. package/dist/edge.cjs +1 -1
  43. package/dist/edge.cjs.map +1 -1
  44. package/dist/edge.js +4 -4
  45. package/dist/{finish-Ddj1MPGt.d.ts → finish-DBKuo8yj.d.ts} +1 -1
  46. package/dist/index.cjs +438 -445
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.js +29 -29
  49. package/dist/modelrouter/core.cjs +1 -1
  50. package/dist/modelrouter/core.cjs.map +1 -1
  51. package/dist/modelrouter/core.js +3 -3
  52. package/dist/modelrouter/index.cjs +1 -1
  53. package/dist/modelrouter/index.cjs.map +1 -1
  54. package/dist/modelrouter/index.js +3 -3
  55. package/dist/subagents/anthropic.cjs +434 -422
  56. package/dist/subagents/anthropic.cjs.map +1 -1
  57. package/dist/subagents/anthropic.js +9 -8
  58. package/dist/subagents/vercel.cjs +434 -422
  59. package/dist/subagents/vercel.cjs.map +1 -1
  60. package/dist/subagents/vercel.js +9 -8
  61. package/dist/tools/browser/anthropic.cjs +1 -1
  62. package/dist/tools/browser/anthropic.cjs.map +1 -1
  63. package/dist/tools/browser/anthropic.js +5 -5
  64. package/dist/tools/browser/core.cjs +1 -1
  65. package/dist/tools/browser/core.cjs.map +1 -1
  66. package/dist/tools/browser/core.js +4 -4
  67. package/dist/tools/browser/index.cjs +1 -1
  68. package/dist/tools/browser/index.cjs.map +1 -1
  69. package/dist/tools/browser/index.js +7 -7
  70. package/dist/tools/browser/openai.cjs +1 -1
  71. package/dist/tools/browser/openai.cjs.map +1 -1
  72. package/dist/tools/browser/openai.js +5 -5
  73. package/dist/tools/browser/profiles/core.cjs +1 -1
  74. package/dist/tools/browser/profiles/core.cjs.map +1 -1
  75. package/dist/tools/browser/profiles/core.js +3 -3
  76. package/dist/tools/browser/profiles/index.cjs +1 -1
  77. package/dist/tools/browser/profiles/index.cjs.map +1 -1
  78. package/dist/tools/browser/profiles/index.js +3 -3
  79. package/dist/tools/browser/vercel.cjs +1 -1
  80. package/dist/tools/browser/vercel.cjs.map +1 -1
  81. package/dist/tools/browser/vercel.js +5 -5
  82. package/dist/tools/codebase_search/anthropic.cjs +1 -1
  83. package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
  84. package/dist/tools/codebase_search/anthropic.js +4 -4
  85. package/dist/tools/codebase_search/core.cjs +1 -1
  86. package/dist/tools/codebase_search/core.cjs.map +1 -1
  87. package/dist/tools/codebase_search/core.js +3 -3
  88. package/dist/tools/codebase_search/index.cjs +1 -1
  89. package/dist/tools/codebase_search/index.cjs.map +1 -1
  90. package/dist/tools/codebase_search/index.js +6 -6
  91. package/dist/tools/codebase_search/openai.cjs +1 -1
  92. package/dist/tools/codebase_search/openai.cjs.map +1 -1
  93. package/dist/tools/codebase_search/openai.js +4 -4
  94. package/dist/tools/codebase_search/vercel.cjs +1 -1
  95. package/dist/tools/codebase_search/vercel.cjs.map +1 -1
  96. package/dist/tools/codebase_search/vercel.js +4 -4
  97. package/dist/tools/fastapply/anthropic.cjs +1 -1
  98. package/dist/tools/fastapply/anthropic.cjs.map +1 -1
  99. package/dist/tools/fastapply/anthropic.js +4 -4
  100. package/dist/tools/fastapply/apply.cjs +1 -1
  101. package/dist/tools/fastapply/apply.cjs.map +1 -1
  102. package/dist/tools/fastapply/apply.js +2 -2
  103. package/dist/tools/fastapply/core.cjs +1 -1
  104. package/dist/tools/fastapply/core.cjs.map +1 -1
  105. package/dist/tools/fastapply/core.js +3 -3
  106. package/dist/tools/fastapply/index.cjs +1 -1
  107. package/dist/tools/fastapply/index.cjs.map +1 -1
  108. package/dist/tools/fastapply/index.js +6 -6
  109. package/dist/tools/fastapply/openai.cjs +1 -1
  110. package/dist/tools/fastapply/openai.cjs.map +1 -1
  111. package/dist/tools/fastapply/openai.js +4 -4
  112. package/dist/tools/fastapply/vercel.cjs +1 -1
  113. package/dist/tools/fastapply/vercel.cjs.map +1 -1
  114. package/dist/tools/fastapply/vercel.js +4 -4
  115. package/dist/tools/index.cjs +1 -1
  116. package/dist/tools/index.cjs.map +1 -1
  117. package/dist/tools/index.js +6 -6
  118. package/dist/tools/utils/resilience.cjs +1 -1
  119. package/dist/tools/utils/resilience.cjs.map +1 -1
  120. package/dist/tools/utils/resilience.js +2 -2
  121. package/dist/tools/warp_grep/agent/config.cjs +3 -4
  122. package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
  123. package/dist/tools/warp_grep/agent/config.d.ts +1 -2
  124. package/dist/tools/warp_grep/agent/config.js +1 -1
  125. package/dist/tools/warp_grep/agent/parser.cjs +121 -52
  126. package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
  127. package/dist/tools/warp_grep/agent/parser.d.ts +5 -12
  128. package/dist/tools/warp_grep/agent/parser.js +3 -7
  129. package/dist/tools/warp_grep/agent/runner.cjs +416 -335
  130. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  131. package/dist/tools/warp_grep/agent/runner.d.ts +3 -6
  132. package/dist/tools/warp_grep/agent/runner.js +6 -5
  133. package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
  134. package/dist/tools/warp_grep/agent/types.d.ts +3 -22
  135. package/dist/tools/warp_grep/anthropic.cjs +434 -422
  136. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  137. package/dist/tools/warp_grep/anthropic.js +9 -8
  138. package/dist/tools/warp_grep/client.cjs +434 -422
  139. package/dist/tools/warp_grep/client.cjs.map +1 -1
  140. package/dist/tools/warp_grep/client.js +8 -7
  141. package/dist/tools/warp_grep/gemini.cjs +434 -422
  142. package/dist/tools/warp_grep/gemini.cjs.map +1 -1
  143. package/dist/tools/warp_grep/gemini.js +8 -7
  144. package/dist/tools/warp_grep/gemini.js.map +1 -1
  145. package/dist/tools/warp_grep/harness.cjs +176 -164
  146. package/dist/tools/warp_grep/harness.cjs.map +1 -1
  147. package/dist/tools/warp_grep/harness.d.ts +38 -17
  148. package/dist/tools/warp_grep/harness.js +14 -15
  149. package/dist/tools/warp_grep/harness.js.map +1 -1
  150. package/dist/tools/warp_grep/index.cjs +434 -441
  151. package/dist/tools/warp_grep/index.cjs.map +1 -1
  152. package/dist/tools/warp_grep/index.d.ts +1 -1
  153. package/dist/tools/warp_grep/index.js +10 -10
  154. package/dist/tools/warp_grep/openai.cjs +434 -422
  155. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  156. package/dist/tools/warp_grep/openai.js +9 -8
  157. package/dist/tools/warp_grep/providers/local.cjs +2 -43
  158. package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
  159. package/dist/tools/warp_grep/providers/local.d.ts +1 -5
  160. package/dist/tools/warp_grep/providers/local.js +2 -2
  161. package/dist/tools/warp_grep/providers/remote.cjs +2 -32
  162. package/dist/tools/warp_grep/providers/remote.cjs.map +1 -1
  163. package/dist/tools/warp_grep/providers/remote.d.ts +1 -9
  164. package/dist/tools/warp_grep/providers/remote.js +2 -2
  165. package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
  166. package/dist/tools/warp_grep/providers/types.d.ts +1 -14
  167. package/dist/tools/warp_grep/vercel.cjs +434 -422
  168. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  169. package/dist/tools/warp_grep/vercel.js +9 -8
  170. package/dist/version.cjs +1 -1
  171. package/dist/version.cjs.map +1 -1
  172. package/dist/version.js +1 -1
  173. package/package.json +1 -1
  174. package/dist/chunk-4LWMPKSB.js.map +0 -1
  175. package/dist/chunk-4Y2NM6JD.js.map +0 -1
  176. package/dist/chunk-B3AKP3RA.js.map +0 -1
  177. package/dist/chunk-CMSHXALI.js +0 -60
  178. package/dist/chunk-CMSHXALI.js.map +0 -1
  179. package/dist/chunk-I3J46TSB.js.map +0 -1
  180. package/dist/chunk-OPEQQGST.js +0 -396
  181. package/dist/chunk-OPEQQGST.js.map +0 -1
  182. /package/dist/{chunk-HBIW2XV2.js.map → chunk-4PBUB77N.js.map} +0 -0
  183. /package/dist/{chunk-SUE4GYA2.js.map → chunk-BDHKL3MT.js.map} +0 -0
  184. /package/dist/{chunk-S54SPKX3.js.map → chunk-BIQ7234U.js.map} +0 -0
  185. /package/dist/{chunk-MRPASJBX.js.map → chunk-E45FW5EK.js.map} +0 -0
  186. /package/dist/{chunk-BXRJYLRS.js.map → chunk-E4YKEKGW.js.map} +0 -0
  187. /package/dist/{chunk-G23BI5CQ.js.map → chunk-EU7OLX4Z.js.map} +0 -0
  188. /package/dist/{chunk-HE7K2QNQ.js.map → chunk-FBOJJ3UY.js.map} +0 -0
  189. /package/dist/{chunk-HYRHI2UL.js.map → chunk-FIVYDIHX.js.map} +0 -0
  190. /package/dist/{chunk-GXM3G7Z4.js.map → chunk-FYO46OT6.js.map} +0 -0
  191. /package/dist/{chunk-GHPQYSSF.js.map → chunk-GJUB3ECP.js.map} +0 -0
  192. /package/dist/{chunk-MTJ3PR4M.js.map → chunk-I7SFRYTX.js.map} +0 -0
  193. /package/dist/{chunk-PX7ODEML.js.map → chunk-J2HIK4GB.js.map} +0 -0
  194. /package/dist/{chunk-RZXS4ADX.js.map → chunk-JSWNBCGS.js.map} +0 -0
  195. /package/dist/{chunk-GXCWKYGU.js.map → chunk-KYKRRF7E.js.map} +0 -0
  196. /package/dist/{chunk-N7TTZIBK.js.map → chunk-MMBQKN4G.js.map} +0 -0
  197. /package/dist/{chunk-JMUAQQJU.js.map → chunk-NKUSUSVI.js.map} +0 -0
  198. /package/dist/{chunk-VRV5UYTN.js.map → chunk-OV57JBMB.js.map} +0 -0
  199. /package/dist/{chunk-EPIOAODF.js.map → chunk-Q36MNOFA.js.map} +0 -0
  200. /package/dist/{chunk-JRBU4UNP.js.map → chunk-QRSWXP4K.js.map} +0 -0
  201. /package/dist/{chunk-IRWHN55G.js.map → chunk-T564HFSH.js.map} +0 -0
  202. /package/dist/{chunk-6CFKWZK3.js.map → chunk-UVNENJ6H.js.map} +0 -0
  203. /package/dist/{chunk-5FCXLQJU.js.map → chunk-UYPWKQKV.js.map} +0 -0
  204. /package/dist/{chunk-BAF33L6C.js.map → chunk-V73GO5AJ.js.map} +0 -0
  205. /package/dist/{chunk-XL7R3XN5.js.map → chunk-VZ6VYRQB.js.map} +0 -0
@@ -12,15 +12,16 @@ import {
12
12
  executeToolCall,
13
13
  formatGitHubReadFileResult,
14
14
  formatResult
15
- } from "../../chunk-JMUAQQJU.js";
15
+ } from "../../chunk-NKUSUSVI.js";
16
16
  import "../../chunk-63VHBANJ.js";
17
- import "../../chunk-OPEQQGST.js";
17
+ import "../../chunk-EUHNJMWL.js";
18
18
  import "../../chunk-GVGJIXV2.js";
19
- import "../../chunk-B3AKP3RA.js";
20
- import "../../chunk-4LWMPKSB.js";
21
- import "../../chunk-CMSHXALI.js";
22
- import "../../chunk-I3J46TSB.js";
23
- import "../../chunk-KELRCMA6.js";
19
+ import "../../chunk-NF2QWJDY.js";
20
+ import "../../chunk-YIETFYCL.js";
21
+ import "../../chunk-QRXG5CAZ.js";
22
+ import "../../chunk-VCKJ22DX.js";
23
+ import "../../chunk-DKODF3YG.js";
24
+ import "../../chunk-SJYAKVSS.js";
24
25
  import "../../chunk-PZ5AY32C.js";
25
26
 
26
27
  // tools/warp_grep/gemini.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../tools/warp_grep/gemini.ts"],"sourcesContent":["/**\n * Google Gemini SDK adapter for morph-warp-grep tool\n * \n * Requires @google/generative-ai as a peer dependency.\n * Install with: npm install @google/generative-ai\n */\n\nimport type { FunctionDeclaration, FunctionDeclarationSchema } from '@google/generative-ai';\nimport { executeToolCall, formatResult, WarpGrepClient, executeGitHubReadFile, formatGitHubReadFileResult } from './client.js';\nimport { WARP_GREP_DESCRIPTION, WARP_GREP_TOOL_NAME, GITHUB_SEARCH_TOOL_NAME, GITHUB_SEARCH_DESCRIPTION, GITHUB_READ_FILE_TOOL_NAME, GITHUB_READ_FILE_DESCRIPTION, GITHUB_READ_FILE_INPUT_SCHEMA } from './prompts.js';\nimport type { WarpGrepToolConfig, WarpGrepResult, GitHubSearchToolConfig, GitHubReadFileInput, GitHubReadFileResult, GitHubReadFileToolConfig } from './types.js';\n\n// Use plain object to avoid runtime import of SchemaType enum\nconst TOOL_PARAMETERS = {\n type: 'OBJECT',\n properties: {\n search_term: { \n type: 'STRING', \n description: 'Search problem statement that this subagent is supposed to research for' \n },\n },\n required: ['search_term'],\n} as unknown as FunctionDeclarationSchema;\n\n/**\n * Gemini-native warp grep function declaration\n * \n * @example\n * ```typescript\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n * import { warpGrepFunctionDeclaration, execute } from '@morphllm/morphsdk/tools/warp-grep/gemini';\n * \n * const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);\n * const model = genAI.getGenerativeModel({\n * model: 'gemini-2.0-flash',\n * tools: [{ functionDeclarations: [warpGrepFunctionDeclaration] }]\n * });\n * \n * const chat = model.startChat();\n * const result = await chat.sendMessage('Find authentication middleware');\n * \n * // Handle function call\n * const call = result.response.functionCalls()?.[0];\n * if (call) {\n * const searchResult = await execute(call.args, { repoRoot: '.' });\n * console.log(searchResult);\n * }\n * ```\n */\nexport const warpGrepFunctionDeclaration: FunctionDeclaration = {\n name: WARP_GREP_TOOL_NAME,\n description: WARP_GREP_DESCRIPTION,\n parameters: TOOL_PARAMETERS,\n};\n\n/**\n * Execute warp grep search\n * \n * @param input - Tool input with search_term\n * @param config - Configuration with repoRoot and optional provider\n * @returns Search results\n */\nexport async function execute(\n input: { search_term: string } | string,\n config: WarpGrepToolConfig\n): Promise<WarpGrepResult> {\n return executeToolCall(input, config);\n}\n\nexport { formatResult };\n\n/**\n * Gemini tool with execute method attached\n */\nexport interface GeminiWarpGrepTool extends FunctionDeclaration {\n execute: (input: unknown) => Promise<WarpGrepResult>;\n formatResult: (result: WarpGrepResult) => string;\n}\n\n/**\n * Create a custom warp grep tool with configuration and methods\n * \n * @param config - Configuration options\n * @returns Function declaration with execute and formatResult methods\n * \n * @example Local usage\n * ```typescript\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n * import { createMorphWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/gemini';\n * \n * const tool = createMorphWarpGrepTool({ repoRoot: '.' });\n * \n * const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);\n * const model = genAI.getGenerativeModel({\n * model: 'gemini-2.0-flash',\n * tools: [{ functionDeclarations: [tool] }]\n * });\n * \n * const chat = model.startChat();\n * const result = await chat.sendMessage('Find authentication middleware');\n * \n * // Handle function call\n * const call = result.response.functionCalls()?.[0];\n * if (call && call.name === tool.name) {\n * const searchResult = await tool.execute(call.args);\n * console.log(tool.formatResult(searchResult));\n * \n * // Send result back to model\n * await chat.sendMessage([{\n * functionResponse: {\n * name: call.name,\n * response: { result: tool.formatResult(searchResult) }\n * }\n * }]);\n * }\n * ```\n * \n * @example Remote sandbox (E2B, Modal, etc.)\n * ```typescript\n * const tool = createMorphWarpGrepTool({\n * repoRoot: '/home/repo',\n * remoteCommands: {\n * grep: async (pattern, path) => (await sandbox.run(`rg '${pattern}' '${path}'`)).stdout,\n * read: async (path, start, end) => (await sandbox.run(`sed -n '${start},${end}p' '${path}'`)).stdout,\n * listDir: async (path, maxDepth) => (await sandbox.run(`find '${path}' -maxdepth ${maxDepth}`)).stdout,\n * },\n * });\n * ```\n */\nexport function createWarpGrepTool(config: WarpGrepToolConfig): GeminiWarpGrepTool {\n const declaration: FunctionDeclaration = {\n name: config.name ?? WARP_GREP_TOOL_NAME,\n description: config.description ?? WARP_GREP_DESCRIPTION,\n parameters: TOOL_PARAMETERS,\n };\n\n return Object.assign(declaration, {\n execute: async (input: unknown): Promise<WarpGrepResult> => {\n return executeToolCall(input as { search_term: string } | string, config);\n },\n formatResult: (result: WarpGrepResult): string => {\n return formatResult(result);\n },\n });\n}\n\n// Legacy alias for backwards compatibility\nexport const createMorphWarpGrepTool = createWarpGrepTool;\n\nconst GITHUB_SEARCH_PARAMETERS = {\n type: 'OBJECT',\n properties: {\n search_term: { type: 'STRING', description: 'Search problem statement that this subagent is supposed to research for' },\n github_url: { type: 'STRING', description: 'GitHub repository URL to search (e.g. \"https://github.com/vercel/next.js\"). You must provide either github_url or owner_repo.' },\n owner_repo: { type: 'STRING', description: 'Repository owner/repo shorthand (e.g. \"vercel/next.js\"). You must provide either github_url or owner_repo.' },\n branch: { type: 'STRING', description: 'Branch to search (defaults to repo default branch)' },\n },\n required: ['search_term'],\n} as unknown as FunctionDeclarationSchema;\n\n/**\n * Create a GitHub search tool for Google Gemini SDK\n *\n * @param config - Configuration options (morphApiKey, morphApiUrl, codeSearchUrl, timeout)\n * @returns Gemini FunctionDeclaration with execute and formatResult methods\n *\n * @example\n * ```typescript\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n * import { createGitHubSearchTool } from '@morphllm/morphsdk/tools/warp-grep/gemini';\n *\n * const tool = createGitHubSearchTool({ morphApiKey: process.env.MORPH_API_KEY });\n *\n * const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);\n * const model = genAI.getGenerativeModel({\n * model: 'gemini-2.0-flash',\n * tools: [{ functionDeclarations: [tool] }]\n * });\n *\n * // Execute\n * const result = await tool.execute({ search_term: 'auth middleware', github_url: 'https://github.com/vercel/next.js' });\n * console.log(tool.formatResult(result));\n * ```\n */\nexport function createGitHubSearchTool(config: GitHubSearchToolConfig) {\n const client = new WarpGrepClient(config);\n\n const declaration: FunctionDeclaration = {\n name: GITHUB_SEARCH_TOOL_NAME,\n description: GITHUB_SEARCH_DESCRIPTION,\n parameters: GITHUB_SEARCH_PARAMETERS,\n };\n\n return Object.assign(declaration, {\n execute: async (input: { search_term: string; github_url?: string; owner_repo?: string; branch?: string }): Promise<WarpGrepResult> => {\n const github = input.github_url || input.owner_repo;\n if (!github) {\n throw new Error('Please provide github search url or owner/repo id');\n }\n return client.searchGitHub({ searchTerm: input.search_term, github, branch: input.branch });\n },\n formatResult: (result: WarpGrepResult): string => {\n return formatResult(result);\n },\n });\n}\n\nconst GITHUB_READ_FILE_PARAMETERS = {\n type: 'OBJECT',\n properties: {\n github: { type: 'STRING', description: 'owner/repo shorthand (e.g., \"vercel/next.js\")' },\n path: { type: 'STRING', description: 'File path within the repository' },\n startLine: { type: 'NUMBER', description: 'Start line number (1-based)' },\n endLine: { type: 'NUMBER', description: 'End line number (1-based, inclusive)' },\n branch: { type: 'STRING', description: 'Branch to read from (defaults to repo default branch)' },\n },\n required: ['github', 'path'],\n} as unknown as FunctionDeclarationSchema;\n\n/**\n * Create a GitHub read file tool for Google Gemini SDK\n *\n * @param config - Optional configuration (timeout)\n * @returns Gemini FunctionDeclaration with execute and formatResult methods\n *\n * @example\n * ```typescript\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n * import { createGitHubReadFileTool } from '@morphllm/morphsdk/tools/warp-grep/gemini';\n *\n * const tool = createGitHubReadFileTool();\n *\n * const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);\n * const model = genAI.getGenerativeModel({\n * model: 'gemini-2.0-flash',\n * tools: [{ functionDeclarations: [tool] }]\n * });\n *\n * const result = await tool.execute({ github: 'vercel/next.js', path: 'package.json' });\n * console.log(tool.formatResult(result));\n * ```\n */\nexport function createGitHubReadFileTool(config?: GitHubReadFileToolConfig) {\n const declaration: FunctionDeclaration = {\n name: GITHUB_READ_FILE_TOOL_NAME,\n description: GITHUB_READ_FILE_DESCRIPTION,\n parameters: GITHUB_READ_FILE_PARAMETERS,\n };\n\n return Object.assign(declaration, {\n execute: async (input: GitHubReadFileInput): Promise<GitHubReadFileResult> => {\n return executeGitHubReadFile(input, config);\n },\n formatResult: (result: GitHubReadFileResult): string => {\n return formatGitHubReadFileResult(result);\n },\n });\n}\n\nexport default warpGrepFunctionDeclaration;\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,YAAY;AAAA,IACV,aAAa;AAAA,MACX,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,UAAU,CAAC,aAAa;AAC1B;AA2BO,IAAM,8BAAmD;AAAA,EAC9D,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AACd;AASA,eAAsB,QACpB,OACA,QACyB;AACzB,SAAO,gBAAgB,OAAO,MAAM;AACtC;AA8DO,SAAS,mBAAmB,QAAgD;AACjF,QAAM,cAAmC;AAAA,IACvC,MAAM,OAAO,QAAQ;AAAA,IACrB,aAAa,OAAO,eAAe;AAAA,IACnC,YAAY;AAAA,EACd;AAEA,SAAO,OAAO,OAAO,aAAa;AAAA,IAChC,SAAS,OAAO,UAA4C;AAC1D,aAAO,gBAAgB,OAA2C,MAAM;AAAA,IAC1E;AAAA,IACA,cAAc,CAAC,WAAmC;AAChD,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;AAGO,IAAM,0BAA0B;AAEvC,IAAM,2BAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,YAAY;AAAA,IACV,aAAa,EAAE,MAAM,UAAU,aAAa,0EAA0E;AAAA,IACtH,YAAY,EAAE,MAAM,UAAU,aAAa,gIAAgI;AAAA,IAC3K,YAAY,EAAE,MAAM,UAAU,aAAa,6GAA6G;AAAA,IACxJ,QAAQ,EAAE,MAAM,UAAU,aAAa,qDAAqD;AAAA,EAC9F;AAAA,EACA,UAAU,CAAC,aAAa;AAC1B;AA0BO,SAAS,uBAAuB,QAAgC;AACrE,QAAM,SAAS,IAAI,eAAe,MAAM;AAExC,QAAM,cAAmC;AAAA,IACvC,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AAEA,SAAO,OAAO,OAAO,aAAa;AAAA,IAChC,SAAS,OAAO,UAAuH;AACrI,YAAM,SAAS,MAAM,cAAc,MAAM;AACzC,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,mDAAmD;AAAA,MACrE;AACA,aAAO,OAAO,aAAa,EAAE,YAAY,MAAM,aAAa,QAAQ,QAAQ,MAAM,OAAO,CAAC;AAAA,IAC5F;AAAA,IACA,cAAc,CAAC,WAAmC;AAChD,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;AAEA,IAAM,8BAA8B;AAAA,EAClC,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ,EAAE,MAAM,UAAU,aAAa,gDAAgD;AAAA,IACvF,MAAM,EAAE,MAAM,UAAU,aAAa,kCAAkC;AAAA,IACvE,WAAW,EAAE,MAAM,UAAU,aAAa,8BAA8B;AAAA,IACxE,SAAS,EAAE,MAAM,UAAU,aAAa,uCAAuC;AAAA,IAC/E,QAAQ,EAAE,MAAM,UAAU,aAAa,wDAAwD;AAAA,EACjG;AAAA,EACA,UAAU,CAAC,UAAU,MAAM;AAC7B;AAyBO,SAAS,yBAAyB,QAAmC;AAC1E,QAAM,cAAmC;AAAA,IACvC,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AAEA,SAAO,OAAO,OAAO,aAAa;AAAA,IAChC,SAAS,OAAO,UAA8D;AAC5E,aAAO,sBAAsB,OAAO,MAAM;AAAA,IAC5C;AAAA,IACA,cAAc,CAAC,WAAyC;AACtD,aAAO,2BAA2B,MAAM;AAAA,IAC1C;AAAA,EACF,CAAC;AACH;AAEA,IAAO,iBAAQ;","names":[]}
1
+ {"version":3,"sources":["../../../tools/warp_grep/gemini.ts"],"sourcesContent":["/**\n * Google Gemini SDK adapter for morph-warp-grep tool\n * \n * Requires @google/generative-ai as a peer dependency.\n * Install with: npm install @google/generative-ai\n */\n\nimport type { FunctionDeclaration, FunctionDeclarationSchema } from '@google/generative-ai';\nimport { executeToolCall, formatResult, WarpGrepClient, executeGitHubReadFile, formatGitHubReadFileResult } from './client.js';\nimport { WARP_GREP_DESCRIPTION, WARP_GREP_TOOL_NAME, GITHUB_SEARCH_TOOL_NAME, GITHUB_SEARCH_DESCRIPTION, GITHUB_READ_FILE_TOOL_NAME, GITHUB_READ_FILE_DESCRIPTION, GITHUB_READ_FILE_INPUT_SCHEMA } from './prompts.js';\nimport type { WarpGrepToolConfig, WarpGrepResult, GitHubSearchToolConfig, GitHubReadFileInput, GitHubReadFileResult, GitHubReadFileToolConfig } from './types.js';\n\n// Use plain object to avoid runtime import of SchemaType enum\nconst TOOL_PARAMETERS = {\n type: 'OBJECT',\n properties: {\n search_term: { \n type: 'STRING', \n description: 'Search problem statement that this subagent is supposed to research for' \n },\n },\n required: ['search_term'],\n} as unknown as FunctionDeclarationSchema;\n\n/**\n * Gemini-native warp grep function declaration\n * \n * @example\n * ```typescript\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n * import { warpGrepFunctionDeclaration, execute } from '@morphllm/morphsdk/tools/warp-grep/gemini';\n * \n * const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);\n * const model = genAI.getGenerativeModel({\n * model: 'gemini-2.0-flash',\n * tools: [{ functionDeclarations: [warpGrepFunctionDeclaration] }]\n * });\n * \n * const chat = model.startChat();\n * const result = await chat.sendMessage('Find authentication middleware');\n * \n * // Handle function call\n * const call = result.response.functionCalls()?.[0];\n * if (call) {\n * const searchResult = await execute(call.args, { repoRoot: '.' });\n * console.log(searchResult);\n * }\n * ```\n */\nexport const warpGrepFunctionDeclaration: FunctionDeclaration = {\n name: WARP_GREP_TOOL_NAME,\n description: WARP_GREP_DESCRIPTION,\n parameters: TOOL_PARAMETERS,\n};\n\n/**\n * Execute warp grep search\n * \n * @param input - Tool input with search_term\n * @param config - Configuration with repoRoot and optional provider\n * @returns Search results\n */\nexport async function execute(\n input: { search_term: string } | string,\n config: WarpGrepToolConfig\n): Promise<WarpGrepResult> {\n return executeToolCall(input, config);\n}\n\nexport { formatResult };\n\n/**\n * Gemini tool with execute method attached\n */\nexport interface GeminiWarpGrepTool extends FunctionDeclaration {\n execute: (input: unknown) => Promise<WarpGrepResult>;\n formatResult: (result: WarpGrepResult) => string;\n}\n\n/**\n * Create a custom warp grep tool with configuration and methods\n * \n * @param config - Configuration options\n * @returns Function declaration with execute and formatResult methods\n * \n * @example Local usage\n * ```typescript\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n * import { createMorphWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/gemini';\n * \n * const tool = createMorphWarpGrepTool({ repoRoot: '.' });\n * \n * const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);\n * const model = genAI.getGenerativeModel({\n * model: 'gemini-2.0-flash',\n * tools: [{ functionDeclarations: [tool] }]\n * });\n * \n * const chat = model.startChat();\n * const result = await chat.sendMessage('Find authentication middleware');\n * \n * // Handle function call\n * const call = result.response.functionCalls()?.[0];\n * if (call && call.name === tool.name) {\n * const searchResult = await tool.execute(call.args);\n * console.log(tool.formatResult(searchResult));\n * \n * // Send result back to model\n * await chat.sendMessage([{\n * functionResponse: {\n * name: call.name,\n * response: { result: tool.formatResult(searchResult) }\n * }\n * }]);\n * }\n * ```\n * \n * @example Remote sandbox (E2B, Modal, etc.)\n * ```typescript\n * const tool = createMorphWarpGrepTool({\n * repoRoot: '/home/repo',\n * remoteCommands: {\n * grep: async (pattern, path) => (await sandbox.run(`rg '${pattern}' '${path}'`)).stdout,\n * read: async (path, start, end) => (await sandbox.run(`sed -n '${start},${end}p' '${path}'`)).stdout,\n * listDir: async (path, maxDepth) => (await sandbox.run(`find '${path}' -maxdepth ${maxDepth}`)).stdout,\n * },\n * });\n * ```\n */\nexport function createWarpGrepTool(config: WarpGrepToolConfig): GeminiWarpGrepTool {\n const declaration: FunctionDeclaration = {\n name: config.name ?? WARP_GREP_TOOL_NAME,\n description: config.description ?? WARP_GREP_DESCRIPTION,\n parameters: TOOL_PARAMETERS,\n };\n\n return Object.assign(declaration, {\n execute: async (input: unknown): Promise<WarpGrepResult> => {\n return executeToolCall(input as { search_term: string } | string, config);\n },\n formatResult: (result: WarpGrepResult): string => {\n return formatResult(result);\n },\n });\n}\n\n// Legacy alias for backwards compatibility\nexport const createMorphWarpGrepTool = createWarpGrepTool;\n\nconst GITHUB_SEARCH_PARAMETERS = {\n type: 'OBJECT',\n properties: {\n search_term: { type: 'STRING', description: 'Search problem statement that this subagent is supposed to research for' },\n github_url: { type: 'STRING', description: 'GitHub repository URL to search (e.g. \"https://github.com/vercel/next.js\"). You must provide either github_url or owner_repo.' },\n owner_repo: { type: 'STRING', description: 'Repository owner/repo shorthand (e.g. \"vercel/next.js\"). You must provide either github_url or owner_repo.' },\n branch: { type: 'STRING', description: 'Branch to search (defaults to repo default branch)' },\n },\n required: ['search_term'],\n} as unknown as FunctionDeclarationSchema;\n\n/**\n * Create a GitHub search tool for Google Gemini SDK\n *\n * @param config - Configuration options (morphApiKey, morphApiUrl, codeSearchUrl, timeout)\n * @returns Gemini FunctionDeclaration with execute and formatResult methods\n *\n * @example\n * ```typescript\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n * import { createGitHubSearchTool } from '@morphllm/morphsdk/tools/warp-grep/gemini';\n *\n * const tool = createGitHubSearchTool({ morphApiKey: process.env.MORPH_API_KEY });\n *\n * const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);\n * const model = genAI.getGenerativeModel({\n * model: 'gemini-2.0-flash',\n * tools: [{ functionDeclarations: [tool] }]\n * });\n *\n * // Execute\n * const result = await tool.execute({ search_term: 'auth middleware', github_url: 'https://github.com/vercel/next.js' });\n * console.log(tool.formatResult(result));\n * ```\n */\nexport function createGitHubSearchTool(config: GitHubSearchToolConfig) {\n const client = new WarpGrepClient(config);\n\n const declaration: FunctionDeclaration = {\n name: GITHUB_SEARCH_TOOL_NAME,\n description: GITHUB_SEARCH_DESCRIPTION,\n parameters: GITHUB_SEARCH_PARAMETERS,\n };\n\n return Object.assign(declaration, {\n execute: async (input: { search_term: string; github_url?: string; owner_repo?: string; branch?: string }): Promise<WarpGrepResult> => {\n const github = input.github_url || input.owner_repo;\n if (!github) {\n throw new Error('Please provide github search url or owner/repo id');\n }\n return client.searchGitHub({ searchTerm: input.search_term, github, branch: input.branch });\n },\n formatResult: (result: WarpGrepResult): string => {\n return formatResult(result);\n },\n });\n}\n\nconst GITHUB_READ_FILE_PARAMETERS = {\n type: 'OBJECT',\n properties: {\n github: { type: 'STRING', description: 'owner/repo shorthand (e.g., \"vercel/next.js\")' },\n path: { type: 'STRING', description: 'File path within the repository' },\n startLine: { type: 'NUMBER', description: 'Start line number (1-based)' },\n endLine: { type: 'NUMBER', description: 'End line number (1-based, inclusive)' },\n branch: { type: 'STRING', description: 'Branch to read from (defaults to repo default branch)' },\n },\n required: ['github', 'path'],\n} as unknown as FunctionDeclarationSchema;\n\n/**\n * Create a GitHub read file tool for Google Gemini SDK\n *\n * @param config - Optional configuration (timeout)\n * @returns Gemini FunctionDeclaration with execute and formatResult methods\n *\n * @example\n * ```typescript\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n * import { createGitHubReadFileTool } from '@morphllm/morphsdk/tools/warp-grep/gemini';\n *\n * const tool = createGitHubReadFileTool();\n *\n * const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);\n * const model = genAI.getGenerativeModel({\n * model: 'gemini-2.0-flash',\n * tools: [{ functionDeclarations: [tool] }]\n * });\n *\n * const result = await tool.execute({ github: 'vercel/next.js', path: 'package.json' });\n * console.log(tool.formatResult(result));\n * ```\n */\nexport function createGitHubReadFileTool(config?: GitHubReadFileToolConfig) {\n const declaration: FunctionDeclaration = {\n name: GITHUB_READ_FILE_TOOL_NAME,\n description: GITHUB_READ_FILE_DESCRIPTION,\n parameters: GITHUB_READ_FILE_PARAMETERS,\n };\n\n return Object.assign(declaration, {\n execute: async (input: GitHubReadFileInput): Promise<GitHubReadFileResult> => {\n return executeGitHubReadFile(input, config);\n },\n formatResult: (result: GitHubReadFileResult): string => {\n return formatGitHubReadFileResult(result);\n },\n });\n}\n\nexport default warpGrepFunctionDeclaration;\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,YAAY;AAAA,IACV,aAAa;AAAA,MACX,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,UAAU,CAAC,aAAa;AAC1B;AA2BO,IAAM,8BAAmD;AAAA,EAC9D,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AACd;AASA,eAAsB,QACpB,OACA,QACyB;AACzB,SAAO,gBAAgB,OAAO,MAAM;AACtC;AA8DO,SAAS,mBAAmB,QAAgD;AACjF,QAAM,cAAmC;AAAA,IACvC,MAAM,OAAO,QAAQ;AAAA,IACrB,aAAa,OAAO,eAAe;AAAA,IACnC,YAAY;AAAA,EACd;AAEA,SAAO,OAAO,OAAO,aAAa;AAAA,IAChC,SAAS,OAAO,UAA4C;AAC1D,aAAO,gBAAgB,OAA2C,MAAM;AAAA,IAC1E;AAAA,IACA,cAAc,CAAC,WAAmC;AAChD,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;AAGO,IAAM,0BAA0B;AAEvC,IAAM,2BAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,YAAY;AAAA,IACV,aAAa,EAAE,MAAM,UAAU,aAAa,0EAA0E;AAAA,IACtH,YAAY,EAAE,MAAM,UAAU,aAAa,gIAAgI;AAAA,IAC3K,YAAY,EAAE,MAAM,UAAU,aAAa,6GAA6G;AAAA,IACxJ,QAAQ,EAAE,MAAM,UAAU,aAAa,qDAAqD;AAAA,EAC9F;AAAA,EACA,UAAU,CAAC,aAAa;AAC1B;AA0BO,SAAS,uBAAuB,QAAgC;AACrE,QAAM,SAAS,IAAI,eAAe,MAAM;AAExC,QAAM,cAAmC;AAAA,IACvC,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AAEA,SAAO,OAAO,OAAO,aAAa;AAAA,IAChC,SAAS,OAAO,UAAuH;AACrI,YAAM,SAAS,MAAM,cAAc,MAAM;AACzC,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,mDAAmD;AAAA,MACrE;AACA,aAAO,OAAO,aAAa,EAAE,YAAY,MAAM,aAAa,QAAQ,QAAQ,MAAM,OAAO,CAAC;AAAA,IAC5F;AAAA,IACA,cAAc,CAAC,WAAmC;AAChD,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;AAEA,IAAM,8BAA8B;AAAA,EAClC,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ,EAAE,MAAM,UAAU,aAAa,gDAAgD;AAAA,IACvF,MAAM,EAAE,MAAM,UAAU,aAAa,kCAAkC;AAAA,IACvE,WAAW,EAAE,MAAM,UAAU,aAAa,8BAA8B;AAAA,IACxE,SAAS,EAAE,MAAM,UAAU,aAAa,uCAAuC;AAAA,IAC/E,QAAQ,EAAE,MAAM,UAAU,aAAa,wDAAwD;AAAA,EACjG;AAAA,EACA,UAAU,CAAC,UAAU,MAAM;AAC7B;AAyBO,SAAS,yBAAyB,QAAmC;AAC1E,QAAM,cAAmC;AAAA,IACvC,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AAEA,SAAO,OAAO,OAAO,aAAa;AAAA,IAChC,SAAS,OAAO,UAA8D;AAC5E,aAAO,sBAAsB,OAAO,MAAM;AAAA,IAC5C;AAAA,IACA,cAAc,CAAC,WAAyC;AACtD,aAAO,2BAA2B,MAAM;AAAA,IAC1C;AAAA,EACF,CAAC;AACH;AAEA,IAAO,iBAAQ;","names":[]}
@@ -32,19 +32,17 @@ var harness_exports = {};
32
32
  __export(harness_exports, {
33
33
  AGENT_CONFIG: () => AGENT_CONFIG,
34
34
  DEFAULT_EXCLUDES: () => DEFAULT_EXCLUDES,
35
+ LLMResponseParser: () => LLMResponseParser,
35
36
  LocalRipgrepProvider: () => LocalRipgrepProvider,
36
37
  buildInitialState: () => buildInitialState,
37
38
  calculateContextBudget: () => calculateContextBudget,
38
- extractPathFromCommand: () => extractPathFromCommand,
39
39
  formatListDirectoryTree: () => formatListDirectoryTree,
40
40
  formatToolResult: () => formatAgentToolOutput,
41
41
  formatTurnMessage: () => formatTurnMessage,
42
42
  normalizeFinishFiles: () => normalizeFinishFiles,
43
- parseFinishFiles: () => parseFinishFiles,
44
- parseReadLines: () => parseReadLines,
43
+ parseToolCalls: () => parseToolCalls,
45
44
  readFinishFiles: () => readFinishFiles,
46
45
  resolveFinishFiles: () => resolveFinishFiles,
47
- toolGlob: () => toolGlob,
48
46
  toolGrep: () => toolGrep,
49
47
  toolListDirectory: () => toolListDirectory,
50
48
  toolRead: () => toolRead
@@ -52,58 +50,131 @@ __export(harness_exports, {
52
50
  module.exports = __toCommonJS(harness_exports);
53
51
 
54
52
  // tools/warp_grep/agent/parser.ts
55
- function parseReadLines(linesStr) {
56
- const ranges = [];
57
- for (const rangeStr of linesStr.split(",")) {
58
- const trimmed = rangeStr.trim();
59
- if (!trimmed) continue;
60
- const parts = trimmed.split("-").map((v) => parseInt(v.trim(), 10));
61
- if (parts.length >= 2 && Number.isFinite(parts[0]) && Number.isFinite(parts[1])) {
62
- ranges.push([parts[0], parts[1]]);
63
- } else if (Number.isFinite(parts[0])) {
64
- ranges.push([parts[0], parts[0]]);
65
- }
66
- }
67
- if (ranges.length === 1) return { start: ranges[0][0], end: ranges[0][1] };
68
- if (ranges.length > 1) return { lines: ranges };
69
- return {};
53
+ var VALID_COMMANDS = ["list_directory", "ripgrep", "read", "finish"];
54
+ function isValidCommand(name) {
55
+ return VALID_COMMANDS.includes(name);
70
56
  }
71
- function parseFinishFiles(filesStr) {
72
- const files = [];
73
- for (const line of filesStr.trim().split(/\s+/)) {
74
- const trimmed = line.trim();
75
- if (!trimmed) continue;
76
- const colonIdx = trimmed.indexOf(":");
77
- if (colonIdx === -1) {
78
- files.push({ path: trimmed, lines: "*" });
79
- continue;
80
- }
81
- const filePath = trimmed.slice(0, colonIdx);
82
- const rangesPart = trimmed.slice(colonIdx + 1);
83
- if (!rangesPart.trim() || rangesPart.trim() === "*") {
84
- files.push({ path: filePath, lines: "*" });
85
- continue;
86
- }
87
- const ranges = [];
88
- for (const rangeStr of rangesPart.split(",")) {
89
- const rt = rangeStr.trim();
90
- if (!rt) continue;
91
- const parts = rt.split("-").map((v) => parseInt(v.trim(), 10));
92
- if (parts.length >= 2 && Number.isFinite(parts[0]) && Number.isFinite(parts[1])) {
93
- ranges.push([parts[0], parts[1]]);
94
- } else if (Number.isFinite(parts[0])) {
95
- ranges.push([parts[0], parts[0]]);
57
+ function parseQwen3ToolCalls(text) {
58
+ const tools = [];
59
+ const toolCallRegex = /<tool_call>\s*<function=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/function>\s*<\/tool_call>/gi;
60
+ let match;
61
+ while ((match = toolCallRegex.exec(text)) !== null) {
62
+ const funcName = match[1].toLowerCase();
63
+ const body = match[2];
64
+ if (!isValidCommand(funcName)) continue;
65
+ const params = {};
66
+ const paramRegex = /<parameter=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/parameter>/gi;
67
+ let paramMatch;
68
+ while ((paramMatch = paramRegex.exec(body)) !== null) {
69
+ params[paramMatch[1].toLowerCase()] = paramMatch[2].trim();
70
+ }
71
+ if (funcName === "ripgrep") {
72
+ const pattern = params.pattern;
73
+ if (!pattern) continue;
74
+ const args = {
75
+ pattern,
76
+ path: params.path || ".",
77
+ ...params.glob && { glob: params.glob },
78
+ ...params.context_lines && { context_lines: parseInt(params.context_lines, 10) },
79
+ ...params.case_sensitive && { case_sensitive: params.case_sensitive === "true" }
80
+ };
81
+ tools.push({ name: "grep", arguments: args });
82
+ } else if (funcName === "list_directory") {
83
+ const command = params.command;
84
+ const directPath = params.path;
85
+ let dirPath = directPath || ".";
86
+ if (!directPath && command) {
87
+ const tokens = command.trim().split(/\s+/);
88
+ const pathTokens = tokens.slice(1).filter((t) => !t.startsWith("-") && !t.startsWith("|") && !t.startsWith("\\("));
89
+ if (pathTokens.length > 0) {
90
+ dirPath = pathTokens[0];
91
+ }
92
+ }
93
+ tools.push({ name: "list_directory", arguments: { path: dirPath, pattern: params.pattern || null } });
94
+ } else if (funcName === "read") {
95
+ const filePath = params.path;
96
+ if (!filePath) continue;
97
+ const args = { path: filePath };
98
+ const linesStr = params.lines;
99
+ if (linesStr) {
100
+ const ranges = [];
101
+ for (const rangeStr of linesStr.split(",")) {
102
+ const trimmed = rangeStr.trim();
103
+ if (!trimmed) continue;
104
+ const [s, e] = trimmed.split("-").map((v) => parseInt(v.trim(), 10));
105
+ if (Number.isFinite(s) && Number.isFinite(e)) {
106
+ ranges.push([s, e]);
107
+ } else if (Number.isFinite(s)) {
108
+ ranges.push([s, s]);
109
+ }
110
+ }
111
+ if (ranges.length === 1) {
112
+ args.start = ranges[0][0];
113
+ args.end = ranges[0][1];
114
+ } else if (ranges.length > 1) {
115
+ args.lines = ranges;
116
+ }
117
+ }
118
+ tools.push({ name: "read", arguments: args });
119
+ } else if (funcName === "finish") {
120
+ if (params.result && !params.files) {
121
+ tools.push({ name: "finish", arguments: { files: [], textResult: params.result } });
122
+ continue;
123
+ }
124
+ const filesStr = params.files;
125
+ if (!filesStr) {
126
+ tools.push({ name: "finish", arguments: { files: [], textResult: "No relevant code found." } });
127
+ continue;
128
+ }
129
+ const files = [];
130
+ for (const line of filesStr.split("\n")) {
131
+ const trimmed = line.trim();
132
+ if (!trimmed) continue;
133
+ const colonIdx = trimmed.indexOf(":");
134
+ if (colonIdx === -1) {
135
+ files.push({ path: trimmed, lines: "*" });
136
+ } else {
137
+ const filePath = trimmed.slice(0, colonIdx);
138
+ const rangesPart = trimmed.slice(colonIdx + 1);
139
+ const ranges = [];
140
+ for (const rangeStr of rangesPart.split(",")) {
141
+ const rt = rangeStr.trim();
142
+ if (!rt || rt === "*") {
143
+ files.push({ path: filePath, lines: "*" });
144
+ break;
145
+ }
146
+ const [s, e] = rt.split("-").map((v) => parseInt(v.trim(), 10));
147
+ if (Number.isFinite(s) && Number.isFinite(e)) {
148
+ ranges.push([s, e]);
149
+ } else if (Number.isFinite(s)) {
150
+ ranges.push([s, s]);
151
+ }
152
+ }
153
+ if (ranges.length > 0) {
154
+ files.push({ path: filePath, lines: ranges });
155
+ } else if (!files.some((f) => f.path === filePath)) {
156
+ files.push({ path: filePath, lines: "*" });
157
+ }
158
+ }
159
+ }
160
+ if (files.length > 0) {
161
+ tools.push({ name: "finish", arguments: { files } });
162
+ } else {
163
+ tools.push({ name: "finish", arguments: { files: [], textResult: filesStr } });
96
164
  }
97
165
  }
98
- files.push({ path: filePath, lines: ranges.length > 0 ? ranges : "*" });
99
166
  }
100
- return files;
101
- }
102
- function extractPathFromCommand(command) {
103
- const tokens = command.trim().split(/\s+/);
104
- const pathTokens = tokens.slice(1).filter((t) => !t.startsWith("-") && !t.startsWith("|") && !t.startsWith("\\("));
105
- return pathTokens[0] || ".";
167
+ return tools;
106
168
  }
169
+ var LLMResponseParser = class {
170
+ parse(text) {
171
+ if (typeof text !== "string") {
172
+ throw new TypeError("Command text must be a string.");
173
+ }
174
+ const withoutThink = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
175
+ return parseQwen3ToolCalls(withoutThink);
176
+ }
177
+ };
107
178
 
108
179
  // tools/warp_grep/agent/formatter.ts
109
180
  var ToolOutputFormatter = class {
@@ -137,12 +208,11 @@ var parseEnvTimeout = (envValue, defaultMs) => {
137
208
  return isNaN(parsed) || parsed <= 0 ? defaultMs : parsed;
138
209
  };
139
210
  var AGENT_CONFIG = {
140
- MAX_TURNS: 6,
211
+ MAX_TURNS: 4,
141
212
  /** Default timeout for model calls. Can be overridden via MORPH_WARP_GREP_TIMEOUT env var (in ms) */
142
213
  TIMEOUT_MS: parseEnvTimeout(process.env.MORPH_WARP_GREP_TIMEOUT, 3e4),
143
- MAX_CONTEXT_CHARS: 321600,
214
+ MAX_CONTEXT_CHARS: 54e4,
144
215
  MAX_OUTPUT_LINES: 200,
145
- MAX_LIST_RESULTS: 500,
146
216
  MAX_READ_LINES: 800,
147
217
  MAX_LIST_DEPTH: 3,
148
218
  LIST_TIMEOUT_MS: 2e3
@@ -229,17 +299,6 @@ var BUILTIN_EXCLUDES = [
229
299
  var DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || "").split(",").map((s) => s.trim()).filter(Boolean).concat(BUILTIN_EXCLUDES);
230
300
 
231
301
  // tools/warp_grep/agent/helpers.ts
232
- function getMessageSize(m) {
233
- if (m.role === "tool") return m.content.length;
234
- if (m.role === "assistant") {
235
- let size = typeof m.content === "string" ? m.content.length : 0;
236
- if (m.tool_calls) {
237
- size += m.tool_calls.reduce((s, tc) => s + tc.function.name.length + tc.function.arguments.length, 0);
238
- }
239
- return size;
240
- }
241
- return m.content.length;
242
- }
243
302
  function formatTurnMessage(turnsUsed, maxTurns) {
244
303
  const turnsRemaining = maxTurns - turnsUsed;
245
304
  if (turnsRemaining === 1) {
@@ -250,7 +309,7 @@ You have used ${turnsUsed} turns, you only have 1 turn remaining. You have run o
250
309
  You have used ${turnsUsed} turn${turnsUsed === 1 ? "" : "s"} and have ${turnsRemaining} remaining`;
251
310
  }
252
311
  function calculateContextBudget(messages) {
253
- const totalChars = messages.reduce((sum, m) => sum + getMessageSize(m), 0);
312
+ const totalChars = messages.reduce((sum, m) => sum + m.content.length, 0);
254
313
  const maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS;
255
314
  const percent = Math.round(totalChars / maxChars * 100);
256
315
  const usedK = Math.round(totalChars / 1e3);
@@ -259,21 +318,24 @@ function calculateContextBudget(messages) {
259
318
  }
260
319
  async function buildInitialState(repoRoot, searchTerm, provider, options) {
261
320
  const budget = calculateContextBudget([]);
262
- const turnTag = `You have used 0 turns and have ${AGENT_CONFIG.MAX_TURNS} remaining`;
321
+ const turnTag = `Turn 0/${AGENT_CONFIG.MAX_TURNS}`;
263
322
  const treeDepth = options?.search_type === "node_modules" ? 1 : 2;
264
- const absRoot = import_path.default.resolve(repoRoot);
265
323
  try {
266
324
  const entries = await provider.listDirectory({
267
325
  path: ".",
268
326
  maxResults: AGENT_CONFIG.MAX_OUTPUT_LINES,
269
327
  maxDepth: treeDepth
270
328
  });
271
- const lines = [absRoot];
272
- for (const e of entries) {
273
- lines.push(import_path.default.join(absRoot, e.path));
274
- }
329
+ const treeLines = entries.map((e) => {
330
+ const indent = " ".repeat(e.depth);
331
+ const name = e.type === "dir" ? `${e.name}/` : e.name;
332
+ return `${indent}${name}`;
333
+ });
334
+ const repoName = import_path.default.basename(repoRoot);
335
+ const treeOutput = treeLines.length > 0 ? `${repoName}/
336
+ ${treeLines.join("\n")}` : `${repoName}/`;
275
337
  return `<repo_structure>
276
- ${lines.join("\n")}
338
+ ${treeOutput}
277
339
  </repo_structure>
278
340
 
279
341
  <search_string>
@@ -282,8 +344,9 @@ ${searchTerm}
282
344
  ${budget}
283
345
  ${turnTag}`;
284
346
  } catch {
347
+ const repoName = import_path.default.basename(repoRoot);
285
348
  return `<repo_structure>
286
- ${absRoot}
349
+ ${repoName}/
287
350
  </repo_structure>
288
351
 
289
352
  <search_string>
@@ -350,42 +413,29 @@ async function toolRead(provider, args) {
350
413
  }
351
414
 
352
415
  // tools/warp_grep/agent/tools/list_directory.ts
353
- var import_path2 = __toESM(require("path"), 1);
354
- async function toolListDirectory(provider, args, repoRoot) {
355
- const maxResults = args.maxResults ?? AGENT_CONFIG.MAX_LIST_RESULTS;
356
- const maxDepth = args.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;
357
- const entries = await provider.listDirectory({
358
- path: args.path,
359
- pattern: args.pattern ?? null,
360
- maxResults,
361
- maxDepth
362
- });
363
- if (!entries.length) return "empty";
364
- if (repoRoot) {
365
- const absRoot = import_path2.default.resolve(repoRoot);
366
- const lines = entries.map((e) => import_path2.default.join(absRoot, e.path));
367
- return lines.join("\n");
368
- }
369
- return entries.map((e) => e.path).join("\n");
370
- }
371
-
372
- // tools/warp_grep/agent/tools/glob.ts
373
- async function toolGlob(provider, args) {
374
- const res = await provider.glob(args);
375
- if (res.error) {
376
- return res.error;
377
- }
378
- if (!res.files.length) {
379
- return "no matches";
416
+ async function toolListDirectory(provider, args) {
417
+ const maxResults = args.maxResults ?? AGENT_CONFIG.MAX_OUTPUT_LINES;
418
+ const initialDepth = args.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;
419
+ async function getListRecursive(currentDepth) {
420
+ const entries = await provider.listDirectory({
421
+ path: args.path,
422
+ pattern: args.pattern ?? null,
423
+ maxResults,
424
+ maxDepth: currentDepth
425
+ });
426
+ if (entries.length >= maxResults && currentDepth > 0) {
427
+ return getListRecursive(currentDepth - 1);
428
+ }
429
+ return { entries };
380
430
  }
381
- const header = `Found ${res.totalFound} file(s) matching "${args.pattern}" within ${res.searchDir}, sorted by modification time (newest first):`;
382
- const body = res.files.join("\n");
383
- const truncated = res.totalFound > res.files.length ? `
384
- [${res.totalFound - res.files.length} files truncated]` : "";
385
- return `${header}
386
- ---
387
- ${body}
388
- ---${truncated}`;
431
+ const { entries: list } = await getListRecursive(initialDepth);
432
+ if (!list.length) return "empty";
433
+ const tree = list.map((e) => {
434
+ const indent = " ".repeat(e.depth);
435
+ const name = e.type === "dir" ? `${e.name}/` : e.name;
436
+ return `${indent}${name}`;
437
+ }).join("\n");
438
+ return tree;
389
439
  }
390
440
 
391
441
  // tools/warp_grep/agent/tools/finish.ts
@@ -456,7 +506,7 @@ function mergeRanges(ranges) {
456
506
 
457
507
  // tools/warp_grep/providers/local.ts
458
508
  var import_promises2 = __toESM(require("fs/promises"), 1);
459
- var import_path4 = __toESM(require("path"), 1);
509
+ var import_path3 = __toESM(require("path"), 1);
460
510
 
461
511
  // tools/warp_grep/utils/ripgrep.ts
462
512
  var import_child_process = require("child_process");
@@ -521,21 +571,21 @@ async function runRipgrep(args, opts) {
521
571
 
522
572
  // tools/warp_grep/utils/paths.ts
523
573
  var import_fs = __toESM(require("fs"), 1);
524
- var import_path3 = __toESM(require("path"), 1);
574
+ var import_path2 = __toESM(require("path"), 1);
525
575
  function resolveUnderRepo(repoRoot, targetPath) {
526
- const absRoot = import_path3.default.resolve(repoRoot);
527
- const resolved = import_path3.default.resolve(absRoot, targetPath);
576
+ const absRoot = import_path2.default.resolve(repoRoot);
577
+ const resolved = import_path2.default.resolve(absRoot, targetPath);
528
578
  ensureWithinRepo(absRoot, resolved);
529
579
  return resolved;
530
580
  }
531
581
  function ensureWithinRepo(repoRoot, absTarget) {
532
- const rel = import_path3.default.relative(import_path3.default.resolve(repoRoot), import_path3.default.resolve(absTarget));
533
- if (rel.startsWith("..") || import_path3.default.isAbsolute(rel)) {
582
+ const rel = import_path2.default.relative(import_path2.default.resolve(repoRoot), import_path2.default.resolve(absTarget));
583
+ if (rel.startsWith("..") || import_path2.default.isAbsolute(rel)) {
534
584
  throw new Error(`Path outside repository root: ${absTarget}`);
535
585
  }
536
586
  }
537
587
  function toRepoRelative(repoRoot, absPath) {
538
- return import_path3.default.relative(import_path3.default.resolve(repoRoot), import_path3.default.resolve(absPath));
588
+ return import_path2.default.relative(import_path2.default.resolve(repoRoot), import_path2.default.resolve(absPath));
539
589
  }
540
590
  function isSymlink(p) {
541
591
  try {
@@ -546,7 +596,7 @@ function isSymlink(p) {
546
596
  }
547
597
  }
548
598
  function fixPathRepetition(fullPath) {
549
- const segments = fullPath.split(import_path3.default.sep).filter(Boolean);
599
+ const segments = fullPath.split(import_path2.default.sep).filter(Boolean);
550
600
  if (segments.length < 2) return null;
551
601
  for (let len = Math.floor(segments.length / 2); len >= 1; len--) {
552
602
  for (let i = 0; i <= segments.length - 2 * len; i++) {
@@ -554,7 +604,7 @@ function fixPathRepetition(fullPath) {
554
604
  const second = segments.slice(i + len, i + 2 * len);
555
605
  if (first.every((seg, idx) => seg === second[idx])) {
556
606
  const fixed = [...segments.slice(0, i), ...segments.slice(i + len)];
557
- return import_path3.default.sep + fixed.join(import_path3.default.sep);
607
+ return import_path2.default.sep + fixed.join(import_path2.default.sep);
558
608
  }
559
609
  }
560
610
  }
@@ -693,7 +743,7 @@ var LocalRipgrepProvider = class {
693
743
  }
694
744
  const stat = await import_promises2.default.stat(abs).catch(() => null);
695
745
  if (!stat) return { lines: [] };
696
- const targetArg = abs === import_path4.default.resolve(this.repoRoot) ? "." : toRepoRelative(this.repoRoot, abs);
746
+ const targetArg = abs === import_path3.default.resolve(this.repoRoot) ? "." : toRepoRelative(this.repoRoot, abs);
697
747
  const contextLines = params.context_lines !== void 0 ? String(params.context_lines) : "1";
698
748
  const args = [
699
749
  "--no-config",
@@ -848,7 +898,7 @@ Details: ${res.stderr}` : ""}`
848
898
  if (timedOut || results.length >= maxResults) break;
849
899
  if (shouldSkip(entry.name, allowNames)) continue;
850
900
  if (regex && !regex.test(entry.name)) continue;
851
- const full = import_path4.default.join(dir, entry.name);
901
+ const full = import_path3.default.join(dir, entry.name);
852
902
  const isDir = entry.isDirectory();
853
903
  results.push({
854
904
  name: entry.name,
@@ -864,49 +914,13 @@ Details: ${res.stderr}` : ""}`
864
914
  await walk(abs, 0);
865
915
  return results;
866
916
  }
867
- async glob(params) {
868
- let abs;
869
- try {
870
- abs = params.path ? resolveUnderRepo(this.repoRoot, params.path) : this.repoRoot;
871
- } catch (err) {
872
- return { files: [], searchDir: this.repoRoot, totalFound: 0, error: `[PATH ERROR] ${err instanceof Error ? err.message : String(err)}` };
873
- }
874
- const stat = await import_promises2.default.stat(abs).catch(() => null);
875
- if (!stat || !stat.isDirectory()) {
876
- return { files: [], searchDir: abs, totalFound: 0, error: `[PATH ERROR] Directory not found: ${params.path || "."}` };
877
- }
878
- const targetArg = abs === import_path4.default.resolve(this.repoRoot) ? "." : toRepoRelative(this.repoRoot, abs);
879
- const args = [
880
- "--no-config",
881
- "--files",
882
- "--color=never",
883
- "-g",
884
- params.pattern,
885
- ...this.excludes.filter((e) => !this.allowNames?.has(e)).flatMap((e) => ["-g", `!${e}`]),
886
- targetArg || "."
887
- ];
888
- const res = await runRipgrep(args, { cwd: this.repoRoot });
889
- if (res.exitCode === -1) {
890
- return { files: [], searchDir: abs, totalFound: 0, error: `[RIPGREP NOT AVAILABLE] ripgrep (rg) is required for glob search.` };
891
- }
892
- if (res.exitCode !== 0 && res.exitCode !== 1) {
893
- return { files: [], searchDir: abs, totalFound: 0, error: `[GLOB ERROR] glob failed with exit code ${res.exitCode}${res.stderr ? `: ${res.stderr}` : ""}` };
894
- }
895
- const absRoot = import_path4.default.resolve(this.repoRoot);
896
- const relFiles = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
897
- const absFiles = relFiles.map((f) => import_path4.default.resolve(absRoot, f));
898
- const withMtime = [];
899
- for (const f of absFiles) {
900
- const s = await import_promises2.default.stat(f).catch(() => null);
901
- withMtime.push({ file: f, mtime: s?.mtimeMs ?? 0 });
902
- }
903
- withMtime.sort((a, b) => b.mtime - a.mtime);
904
- const totalFound = withMtime.length;
905
- return { files: withMtime.slice(0, 100).map((f) => f.file), searchDir: abs, totalFound };
906
- }
907
917
  };
908
918
 
909
919
  // tools/warp_grep/harness.ts
920
+ var parser = new LLMResponseParser();
921
+ function parseToolCalls(text) {
922
+ return parser.parse(text);
923
+ }
910
924
  async function resolveFinishFiles(provider, files) {
911
925
  return readFinishFiles("", files, async (p, s, e) => {
912
926
  const r = await provider.read({ path: p, start: s, end: e });
@@ -920,19 +934,17 @@ async function resolveFinishFiles(provider, files) {
920
934
  0 && (module.exports = {
921
935
  AGENT_CONFIG,
922
936
  DEFAULT_EXCLUDES,
937
+ LLMResponseParser,
923
938
  LocalRipgrepProvider,
924
939
  buildInitialState,
925
940
  calculateContextBudget,
926
- extractPathFromCommand,
927
941
  formatListDirectoryTree,
928
942
  formatToolResult,
929
943
  formatTurnMessage,
930
944
  normalizeFinishFiles,
931
- parseFinishFiles,
932
- parseReadLines,
945
+ parseToolCalls,
933
946
  readFinishFiles,
934
947
  resolveFinishFiles,
935
- toolGlob,
936
948
  toolGrep,
937
949
  toolListDirectory,
938
950
  toolRead