@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.
- package/dist/{chunk-HBIW2XV2.js → chunk-4PBUB77N.js} +2 -2
- package/dist/{chunk-SUE4GYA2.js → chunk-BDHKL3MT.js} +2 -2
- package/dist/{chunk-S54SPKX3.js → chunk-BIQ7234U.js} +2 -2
- package/dist/{chunk-I3J46TSB.js → chunk-DKODF3YG.js} +4 -5
- package/dist/chunk-DKODF3YG.js.map +1 -0
- package/dist/{chunk-MRPASJBX.js → chunk-E45FW5EK.js} +2 -2
- package/dist/{chunk-BXRJYLRS.js → chunk-E4YKEKGW.js} +2 -2
- package/dist/{chunk-G23BI5CQ.js → chunk-EU7OLX4Z.js} +2 -2
- package/dist/chunk-EUHNJMWL.js +409 -0
- package/dist/chunk-EUHNJMWL.js.map +1 -0
- package/dist/{chunk-HE7K2QNQ.js → chunk-FBOJJ3UY.js} +17 -17
- package/dist/{chunk-HYRHI2UL.js → chunk-FIVYDIHX.js} +1 -1
- package/dist/{chunk-GXM3G7Z4.js → chunk-FYO46OT6.js} +2 -2
- package/dist/{chunk-GHPQYSSF.js → chunk-GJUB3ECP.js} +2 -2
- package/dist/{chunk-4Y2NM6JD.js → chunk-HZOTLGJH.js} +2 -42
- package/dist/chunk-HZOTLGJH.js.map +1 -0
- package/dist/{chunk-MTJ3PR4M.js → chunk-I7SFRYTX.js} +2 -2
- package/dist/{chunk-PX7ODEML.js → chunk-J2HIK4GB.js} +2 -2
- package/dist/{chunk-RZXS4ADX.js → chunk-JSWNBCGS.js} +2 -2
- package/dist/{chunk-GXCWKYGU.js → chunk-KYKRRF7E.js} +2 -2
- package/dist/{chunk-N7TTZIBK.js → chunk-MMBQKN4G.js} +2 -2
- package/dist/{chunk-B3AKP3RA.js → chunk-NF2QWJDY.js} +2 -31
- package/dist/chunk-NF2QWJDY.js.map +1 -0
- package/dist/{chunk-JMUAQQJU.js → chunk-NKUSUSVI.js} +3 -3
- package/dist/{chunk-VRV5UYTN.js → chunk-OV57JBMB.js} +2 -2
- package/dist/{chunk-EPIOAODF.js → chunk-Q36MNOFA.js} +2 -2
- package/dist/{chunk-JRBU4UNP.js → chunk-QRSWXP4K.js} +2 -2
- package/dist/{chunk-KELRCMA6.js → chunk-SJYAKVSS.js} +2 -2
- package/dist/{chunk-KELRCMA6.js.map → chunk-SJYAKVSS.js.map} +1 -1
- package/dist/{chunk-IRWHN55G.js → chunk-T564HFSH.js} +1 -1
- package/dist/{chunk-6CFKWZK3.js → chunk-UVNENJ6H.js} +3 -3
- package/dist/{chunk-5FCXLQJU.js → chunk-UYPWKQKV.js} +2 -2
- package/dist/{chunk-BAF33L6C.js → chunk-V73GO5AJ.js} +2 -2
- package/dist/chunk-VCKJ22DX.js +131 -0
- package/dist/chunk-VCKJ22DX.js.map +1 -0
- package/dist/{chunk-XL7R3XN5.js → chunk-VZ6VYRQB.js} +2 -2
- package/dist/{chunk-4LWMPKSB.js → chunk-YIETFYCL.js} +44 -71
- package/dist/chunk-YIETFYCL.js.map +1 -0
- package/dist/client.cjs +438 -426
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +27 -26
- package/dist/edge.cjs +1 -1
- package/dist/edge.cjs.map +1 -1
- package/dist/edge.js +4 -4
- package/dist/{finish-Ddj1MPGt.d.ts → finish-DBKuo8yj.d.ts} +1 -1
- package/dist/index.cjs +438 -445
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +29 -29
- package/dist/modelrouter/core.cjs +1 -1
- package/dist/modelrouter/core.cjs.map +1 -1
- package/dist/modelrouter/core.js +3 -3
- package/dist/modelrouter/index.cjs +1 -1
- package/dist/modelrouter/index.cjs.map +1 -1
- package/dist/modelrouter/index.js +3 -3
- package/dist/subagents/anthropic.cjs +434 -422
- package/dist/subagents/anthropic.cjs.map +1 -1
- package/dist/subagents/anthropic.js +9 -8
- package/dist/subagents/vercel.cjs +434 -422
- package/dist/subagents/vercel.cjs.map +1 -1
- package/dist/subagents/vercel.js +9 -8
- package/dist/tools/browser/anthropic.cjs +1 -1
- package/dist/tools/browser/anthropic.cjs.map +1 -1
- package/dist/tools/browser/anthropic.js +5 -5
- package/dist/tools/browser/core.cjs +1 -1
- package/dist/tools/browser/core.cjs.map +1 -1
- package/dist/tools/browser/core.js +4 -4
- package/dist/tools/browser/index.cjs +1 -1
- package/dist/tools/browser/index.cjs.map +1 -1
- package/dist/tools/browser/index.js +7 -7
- package/dist/tools/browser/openai.cjs +1 -1
- package/dist/tools/browser/openai.cjs.map +1 -1
- package/dist/tools/browser/openai.js +5 -5
- package/dist/tools/browser/profiles/core.cjs +1 -1
- package/dist/tools/browser/profiles/core.cjs.map +1 -1
- package/dist/tools/browser/profiles/core.js +3 -3
- package/dist/tools/browser/profiles/index.cjs +1 -1
- package/dist/tools/browser/profiles/index.cjs.map +1 -1
- package/dist/tools/browser/profiles/index.js +3 -3
- package/dist/tools/browser/vercel.cjs +1 -1
- package/dist/tools/browser/vercel.cjs.map +1 -1
- package/dist/tools/browser/vercel.js +5 -5
- package/dist/tools/codebase_search/anthropic.cjs +1 -1
- package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
- package/dist/tools/codebase_search/anthropic.js +4 -4
- package/dist/tools/codebase_search/core.cjs +1 -1
- package/dist/tools/codebase_search/core.cjs.map +1 -1
- package/dist/tools/codebase_search/core.js +3 -3
- package/dist/tools/codebase_search/index.cjs +1 -1
- package/dist/tools/codebase_search/index.cjs.map +1 -1
- package/dist/tools/codebase_search/index.js +6 -6
- package/dist/tools/codebase_search/openai.cjs +1 -1
- package/dist/tools/codebase_search/openai.cjs.map +1 -1
- package/dist/tools/codebase_search/openai.js +4 -4
- package/dist/tools/codebase_search/vercel.cjs +1 -1
- package/dist/tools/codebase_search/vercel.cjs.map +1 -1
- package/dist/tools/codebase_search/vercel.js +4 -4
- package/dist/tools/fastapply/anthropic.cjs +1 -1
- package/dist/tools/fastapply/anthropic.cjs.map +1 -1
- package/dist/tools/fastapply/anthropic.js +4 -4
- package/dist/tools/fastapply/apply.cjs +1 -1
- package/dist/tools/fastapply/apply.cjs.map +1 -1
- package/dist/tools/fastapply/apply.js +2 -2
- package/dist/tools/fastapply/core.cjs +1 -1
- package/dist/tools/fastapply/core.cjs.map +1 -1
- package/dist/tools/fastapply/core.js +3 -3
- package/dist/tools/fastapply/index.cjs +1 -1
- package/dist/tools/fastapply/index.cjs.map +1 -1
- package/dist/tools/fastapply/index.js +6 -6
- package/dist/tools/fastapply/openai.cjs +1 -1
- package/dist/tools/fastapply/openai.cjs.map +1 -1
- package/dist/tools/fastapply/openai.js +4 -4
- package/dist/tools/fastapply/vercel.cjs +1 -1
- package/dist/tools/fastapply/vercel.cjs.map +1 -1
- package/dist/tools/fastapply/vercel.js +4 -4
- package/dist/tools/index.cjs +1 -1
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.js +6 -6
- package/dist/tools/utils/resilience.cjs +1 -1
- package/dist/tools/utils/resilience.cjs.map +1 -1
- package/dist/tools/utils/resilience.js +2 -2
- package/dist/tools/warp_grep/agent/config.cjs +3 -4
- package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/config.d.ts +1 -2
- package/dist/tools/warp_grep/agent/config.js +1 -1
- package/dist/tools/warp_grep/agent/parser.cjs +121 -52
- package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/parser.d.ts +5 -12
- package/dist/tools/warp_grep/agent/parser.js +3 -7
- package/dist/tools/warp_grep/agent/runner.cjs +416 -335
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.d.ts +3 -6
- package/dist/tools/warp_grep/agent/runner.js +6 -5
- package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/types.d.ts +3 -22
- package/dist/tools/warp_grep/anthropic.cjs +434 -422
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.js +9 -8
- package/dist/tools/warp_grep/client.cjs +434 -422
- package/dist/tools/warp_grep/client.cjs.map +1 -1
- package/dist/tools/warp_grep/client.js +8 -7
- package/dist/tools/warp_grep/gemini.cjs +434 -422
- package/dist/tools/warp_grep/gemini.cjs.map +1 -1
- package/dist/tools/warp_grep/gemini.js +8 -7
- package/dist/tools/warp_grep/gemini.js.map +1 -1
- package/dist/tools/warp_grep/harness.cjs +176 -164
- package/dist/tools/warp_grep/harness.cjs.map +1 -1
- package/dist/tools/warp_grep/harness.d.ts +38 -17
- package/dist/tools/warp_grep/harness.js +14 -15
- package/dist/tools/warp_grep/harness.js.map +1 -1
- package/dist/tools/warp_grep/index.cjs +434 -441
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.d.ts +1 -1
- package/dist/tools/warp_grep/index.js +10 -10
- package/dist/tools/warp_grep/openai.cjs +434 -422
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.js +9 -8
- package/dist/tools/warp_grep/providers/local.cjs +2 -43
- package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/local.d.ts +1 -5
- package/dist/tools/warp_grep/providers/local.js +2 -2
- package/dist/tools/warp_grep/providers/remote.cjs +2 -32
- package/dist/tools/warp_grep/providers/remote.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/remote.d.ts +1 -9
- package/dist/tools/warp_grep/providers/remote.js +2 -2
- package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/types.d.ts +1 -14
- package/dist/tools/warp_grep/vercel.cjs +434 -422
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.js +9 -8
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4LWMPKSB.js.map +0 -1
- package/dist/chunk-4Y2NM6JD.js.map +0 -1
- package/dist/chunk-B3AKP3RA.js.map +0 -1
- package/dist/chunk-CMSHXALI.js +0 -60
- package/dist/chunk-CMSHXALI.js.map +0 -1
- package/dist/chunk-I3J46TSB.js.map +0 -1
- package/dist/chunk-OPEQQGST.js +0 -396
- package/dist/chunk-OPEQQGST.js.map +0 -1
- /package/dist/{chunk-HBIW2XV2.js.map → chunk-4PBUB77N.js.map} +0 -0
- /package/dist/{chunk-SUE4GYA2.js.map → chunk-BDHKL3MT.js.map} +0 -0
- /package/dist/{chunk-S54SPKX3.js.map → chunk-BIQ7234U.js.map} +0 -0
- /package/dist/{chunk-MRPASJBX.js.map → chunk-E45FW5EK.js.map} +0 -0
- /package/dist/{chunk-BXRJYLRS.js.map → chunk-E4YKEKGW.js.map} +0 -0
- /package/dist/{chunk-G23BI5CQ.js.map → chunk-EU7OLX4Z.js.map} +0 -0
- /package/dist/{chunk-HE7K2QNQ.js.map → chunk-FBOJJ3UY.js.map} +0 -0
- /package/dist/{chunk-HYRHI2UL.js.map → chunk-FIVYDIHX.js.map} +0 -0
- /package/dist/{chunk-GXM3G7Z4.js.map → chunk-FYO46OT6.js.map} +0 -0
- /package/dist/{chunk-GHPQYSSF.js.map → chunk-GJUB3ECP.js.map} +0 -0
- /package/dist/{chunk-MTJ3PR4M.js.map → chunk-I7SFRYTX.js.map} +0 -0
- /package/dist/{chunk-PX7ODEML.js.map → chunk-J2HIK4GB.js.map} +0 -0
- /package/dist/{chunk-RZXS4ADX.js.map → chunk-JSWNBCGS.js.map} +0 -0
- /package/dist/{chunk-GXCWKYGU.js.map → chunk-KYKRRF7E.js.map} +0 -0
- /package/dist/{chunk-N7TTZIBK.js.map → chunk-MMBQKN4G.js.map} +0 -0
- /package/dist/{chunk-JMUAQQJU.js.map → chunk-NKUSUSVI.js.map} +0 -0
- /package/dist/{chunk-VRV5UYTN.js.map → chunk-OV57JBMB.js.map} +0 -0
- /package/dist/{chunk-EPIOAODF.js.map → chunk-Q36MNOFA.js.map} +0 -0
- /package/dist/{chunk-JRBU4UNP.js.map → chunk-QRSWXP4K.js.map} +0 -0
- /package/dist/{chunk-IRWHN55G.js.map → chunk-T564HFSH.js.map} +0 -0
- /package/dist/{chunk-6CFKWZK3.js.map → chunk-UVNENJ6H.js.map} +0 -0
- /package/dist/{chunk-5FCXLQJU.js.map → chunk-UYPWKQKV.js.map} +0 -0
- /package/dist/{chunk-BAF33L6C.js.map → chunk-V73GO5AJ.js.map} +0 -0
- /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-
|
|
15
|
+
} from "../../chunk-NKUSUSVI.js";
|
|
16
16
|
import "../../chunk-63VHBANJ.js";
|
|
17
|
-
import "../../chunk-
|
|
17
|
+
import "../../chunk-EUHNJMWL.js";
|
|
18
18
|
import "../../chunk-GVGJIXV2.js";
|
|
19
|
-
import "../../chunk-
|
|
20
|
-
import "../../chunk-
|
|
21
|
-
import "../../chunk-
|
|
22
|
-
import "../../chunk-
|
|
23
|
-
import "../../chunk-
|
|
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
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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 +
|
|
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 = `
|
|
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
|
|
272
|
-
|
|
273
|
-
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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
|
-
|
|
354
|
-
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
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
|
|
382
|
-
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
|
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
|
|
574
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
525
575
|
function resolveUnderRepo(repoRoot, targetPath) {
|
|
526
|
-
const absRoot =
|
|
527
|
-
const resolved =
|
|
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 =
|
|
533
|
-
if (rel.startsWith("..") ||
|
|
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
|
|
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(
|
|
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
|
|
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 ===
|
|
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 =
|
|
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
|
-
|
|
932
|
-
parseReadLines,
|
|
945
|
+
parseToolCalls,
|
|
933
946
|
readFinishFiles,
|
|
934
947
|
resolveFinishFiles,
|
|
935
|
-
toolGlob,
|
|
936
948
|
toolGrep,
|
|
937
949
|
toolListDirectory,
|
|
938
950
|
toolRead
|