@morphllm/morphsdk 0.2.60 → 0.2.62
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-YV75OQTE.js → chunk-3M4DOG6N.js} +2 -26
- package/dist/chunk-3M4DOG6N.js.map +1 -0
- package/dist/{chunk-ILJ3J5IA.js → chunk-44GS4GJJ.js} +3 -3
- package/dist/{chunk-TPP2UGQP.js → chunk-563RLKFC.js} +21 -7
- package/dist/chunk-563RLKFC.js.map +1 -0
- package/dist/chunk-5FUTL2UF.js +22 -0
- package/dist/{chunk-IUG2FHNN.js → chunk-BHNJEBQJ.js} +2 -2
- package/dist/{chunk-6N6ZYZYD.js → chunk-GZ7TJ7UB.js} +3 -3
- package/dist/{chunk-QZNGKOCZ.js → chunk-IXNSTNS7.js} +2 -2
- package/dist/{chunk-ZO4PPFCZ.js → chunk-JNOZPU44.js} +2 -2
- package/dist/{chunk-4VGOBA2J.js → chunk-LHKFRPUO.js} +3 -3
- package/dist/{chunk-5QIWYEHJ.js → chunk-PKPJWARB.js} +2 -2
- package/dist/{chunk-374N3GIA.js → chunk-S3RCM32V.js} +3 -3
- package/dist/{chunk-FN4EP3WY.js → chunk-XWSKUQVQ.js} +8 -8
- package/dist/{chunk-2CASO3ZO.js → chunk-Y7CPJGLU.js} +2 -2
- package/dist/{chunk-3IQIT6MC.js → chunk-Z75HCPIE.js} +3 -3
- package/dist/client.cjs +33 -31
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +13 -13
- package/dist/git/client.js +1 -1
- package/dist/git/config.js +1 -1
- package/dist/git/index.js +1 -1
- package/dist/index.cjs +33 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -14
- package/dist/lib-GEPX5Y3T.js +14 -0
- package/dist/lib-GEPX5Y3T.js.map +1 -0
- package/dist/modelrouter/core.js +1 -1
- package/dist/modelrouter/index.js +1 -1
- package/dist/tools/browser/anthropic.js +1 -1
- package/dist/tools/browser/core.js +1 -1
- package/dist/tools/browser/index.js +1 -1
- package/dist/tools/browser/live.js +1 -1
- package/dist/tools/browser/openai.js +1 -1
- package/dist/tools/browser/prompts.js +1 -1
- package/dist/tools/browser/vercel.js +1 -1
- package/dist/tools/codebase_search/anthropic.js +1 -1
- package/dist/tools/codebase_search/core.js +1 -1
- package/dist/tools/codebase_search/index.js +1 -1
- package/dist/tools/codebase_search/openai.js +1 -1
- package/dist/tools/codebase_search/prompts.js +1 -1
- package/dist/tools/codebase_search/vercel.js +1 -1
- package/dist/tools/fastapply/anthropic.js +2 -2
- package/dist/tools/fastapply/core.js +1 -1
- package/dist/tools/fastapply/index.js +4 -4
- package/dist/tools/fastapply/openai.js +2 -2
- package/dist/tools/fastapply/prompts.js +1 -1
- package/dist/tools/fastapply/vercel.js +2 -2
- package/dist/tools/index.js +4 -4
- package/dist/tools/utils/resilience.js +1 -1
- package/dist/tools/warp_grep/agent/config.js +1 -1
- package/dist/tools/warp_grep/agent/formatter.js +1 -1
- package/dist/tools/warp_grep/agent/parser.cjs +1 -25
- package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/parser.js +2 -2
- package/dist/tools/warp_grep/agent/prompt.js +1 -1
- package/dist/tools/warp_grep/agent/runner.cjs +1 -25
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.js +3 -3
- package/dist/tools/warp_grep/anthropic.cjs +33 -31
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.js +7 -7
- package/dist/tools/warp_grep/client.cjs +33 -31
- package/dist/tools/warp_grep/client.cjs.map +1 -1
- package/dist/tools/warp_grep/client.js +6 -6
- package/dist/tools/warp_grep/gemini.cjs +33 -31
- package/dist/tools/warp_grep/gemini.cjs.map +1 -1
- package/dist/tools/warp_grep/gemini.js +7 -7
- package/dist/tools/warp_grep/harness.cjs +33 -31
- package/dist/tools/warp_grep/harness.cjs.map +1 -1
- package/dist/tools/warp_grep/harness.js +4 -4
- package/dist/tools/warp_grep/index.cjs +33 -31
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.js +10 -10
- package/dist/tools/warp_grep/openai.cjs +33 -31
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.js +7 -7
- package/dist/tools/warp_grep/providers/local.cjs +32 -6
- package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/local.js +3 -3
- package/dist/tools/warp_grep/providers/remote.js +1 -1
- package/dist/tools/warp_grep/utils/files.js +1 -1
- package/dist/tools/warp_grep/utils/paths.js +1 -1
- package/dist/tools/warp_grep/utils/ripgrep.cjs +42 -6
- package/dist/tools/warp_grep/utils/ripgrep.cjs.map +1 -1
- package/dist/tools/warp_grep/utils/ripgrep.js +2 -2
- package/dist/tools/warp_grep/vercel.cjs +33 -31
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.js +7 -7
- package/package.json +5 -3
- package/dist/chunk-PZ5AY32C.js +0 -10
- package/dist/chunk-TPP2UGQP.js.map +0 -1
- package/dist/chunk-YV75OQTE.js.map +0 -1
- /package/dist/{chunk-ILJ3J5IA.js.map → chunk-44GS4GJJ.js.map} +0 -0
- /package/dist/{chunk-PZ5AY32C.js.map → chunk-5FUTL2UF.js.map} +0 -0
- /package/dist/{chunk-IUG2FHNN.js.map → chunk-BHNJEBQJ.js.map} +0 -0
- /package/dist/{chunk-6N6ZYZYD.js.map → chunk-GZ7TJ7UB.js.map} +0 -0
- /package/dist/{chunk-QZNGKOCZ.js.map → chunk-IXNSTNS7.js.map} +0 -0
- /package/dist/{chunk-ZO4PPFCZ.js.map → chunk-JNOZPU44.js.map} +0 -0
- /package/dist/{chunk-4VGOBA2J.js.map → chunk-LHKFRPUO.js.map} +0 -0
- /package/dist/{chunk-5QIWYEHJ.js.map → chunk-PKPJWARB.js.map} +0 -0
- /package/dist/{chunk-374N3GIA.js.map → chunk-S3RCM32V.js.map} +0 -0
- /package/dist/{chunk-FN4EP3WY.js.map → chunk-XWSKUQVQ.js.map} +0 -0
- /package/dist/{chunk-2CASO3ZO.js.map → chunk-Y7CPJGLU.js.map} +0 -0
- /package/dist/{chunk-3IQIT6MC.js.map → chunk-Z75HCPIE.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import "./chunk-ISWL67SF.js";
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-44GS4GJJ.js";
|
|
3
3
|
import {
|
|
4
4
|
AnthropicToolFactory,
|
|
5
5
|
MorphClient,
|
|
6
6
|
OpenAIToolFactory,
|
|
7
7
|
VercelToolFactory
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-XWSKUQVQ.js";
|
|
9
|
+
import "./chunk-Z75HCPIE.js";
|
|
10
|
+
import "./chunk-GZ7TJ7UB.js";
|
|
11
|
+
import "./chunk-LHKFRPUO.js";
|
|
12
12
|
import "./chunk-KW7OEGZK.js";
|
|
13
13
|
import {
|
|
14
14
|
WarpGrepClient
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-S3RCM32V.js";
|
|
16
|
+
import "./chunk-Y7CPJGLU.js";
|
|
17
17
|
import "./chunk-527P5X2E.js";
|
|
18
18
|
import "./chunk-6Y5JB4JC.js";
|
|
19
19
|
import "./chunk-APP75CBN.js";
|
|
20
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-3M4DOG6N.js";
|
|
21
21
|
import "./chunk-Q5AHGIQO.js";
|
|
22
22
|
import {
|
|
23
23
|
LocalRipgrepProvider
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-JNOZPU44.js";
|
|
25
25
|
import "./chunk-G2RSY56Q.js";
|
|
26
26
|
import "./chunk-SMGZ6A64.js";
|
|
27
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-563RLKFC.js";
|
|
28
28
|
import "./chunk-XT5ZO6ES.js";
|
|
29
29
|
import "./chunk-UBX7QYBD.js";
|
|
30
30
|
import "./chunk-GJU7UOFL.js";
|
|
@@ -33,9 +33,9 @@ import {
|
|
|
33
33
|
CodebaseSearchClient
|
|
34
34
|
} from "./chunk-WM77HRKO.js";
|
|
35
35
|
import "./chunk-YQMPVJ2L.js";
|
|
36
|
-
import "./chunk-
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import "./chunk-
|
|
36
|
+
import "./chunk-BHNJEBQJ.js";
|
|
37
|
+
import "./chunk-PKPJWARB.js";
|
|
38
|
+
import "./chunk-IXNSTNS7.js";
|
|
39
39
|
import {
|
|
40
40
|
FastApplyClient,
|
|
41
41
|
applyEdit
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
RawRouter
|
|
57
57
|
} from "./chunk-CP4NZGRY.js";
|
|
58
58
|
import "./chunk-4VWJFZVS.js";
|
|
59
|
-
import "./chunk-
|
|
59
|
+
import "./chunk-5FUTL2UF.js";
|
|
60
60
|
export {
|
|
61
61
|
AnthropicRouter,
|
|
62
62
|
AnthropicToolFactory,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__commonJS,
|
|
3
|
+
__require
|
|
4
|
+
} from "./chunk-5FUTL2UF.js";
|
|
5
|
+
|
|
6
|
+
// node_modules/@vscode/ripgrep/lib/index.js
|
|
7
|
+
var require_lib = __commonJS({
|
|
8
|
+
"node_modules/@vscode/ripgrep/lib/index.js"(exports, module) {
|
|
9
|
+
var path = __require("path");
|
|
10
|
+
module.exports.rgPath = path.join(__dirname, `../bin/rg${process.platform === "win32" ? ".exe" : ""}`);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
export default require_lib();
|
|
14
|
+
//# sourceMappingURL=lib-GEPX5Y3T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../node_modules/@vscode/ripgrep/lib/index.js"],"sourcesContent":["'use strict';\n\nconst path = require('path');\n\nmodule.exports.rgPath = path.join(__dirname, `../bin/rg${process.platform === 'win32' ? '.exe' : ''}`);"],"mappings":";;;;;;AAAA;AAAA;AAEA,QAAM,OAAO,UAAQ,MAAM;AAE3B,WAAO,QAAQ,SAAS,KAAK,KAAK,WAAW,YAAY,QAAQ,aAAa,UAAU,SAAS,EAAE,EAAE;AAAA;AAAA;","names":[]}
|
package/dist/modelrouter/core.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "../../chunk-LVY5LPEX.js";
|
|
7
7
|
import "../../chunk-SQN4DUQS.js";
|
|
8
8
|
import "../../chunk-4VWJFZVS.js";
|
|
9
|
-
import "../../chunk-
|
|
9
|
+
import "../../chunk-5FUTL2UF.js";
|
|
10
10
|
|
|
11
11
|
// tools/browser/vercel.ts
|
|
12
12
|
import { tool as createTool } from "ai";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
CODEBASE_SEARCH_SYSTEM_PROMPT
|
|
16
16
|
} from "../../chunk-YQMPVJ2L.js";
|
|
17
17
|
import "../../chunk-4VWJFZVS.js";
|
|
18
|
-
import "../../chunk-
|
|
18
|
+
import "../../chunk-5FUTL2UF.js";
|
|
19
19
|
export {
|
|
20
20
|
CODEBASE_SEARCH_DESCRIPTION,
|
|
21
21
|
CODEBASE_SEARCH_SYSTEM_PROMPT,
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
execute,
|
|
5
5
|
formatResult,
|
|
6
6
|
getSystemPrompt
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-BHNJEBQJ.js";
|
|
8
8
|
import "../../chunk-CKTA4AXM.js";
|
|
9
9
|
import "../../chunk-63WE2C5R.js";
|
|
10
10
|
import "../../chunk-4VWJFZVS.js";
|
|
11
|
-
import "../../chunk-
|
|
11
|
+
import "../../chunk-5FUTL2UF.js";
|
|
12
12
|
export {
|
|
13
13
|
createEditFileTool,
|
|
14
14
|
editFileTool,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "../../chunk-X2K57BH6.js";
|
|
2
2
|
import {
|
|
3
3
|
anthropic_exports
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-BHNJEBQJ.js";
|
|
5
5
|
import {
|
|
6
6
|
openai_exports
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-PKPJWARB.js";
|
|
8
8
|
import {
|
|
9
9
|
vercel_exports
|
|
10
|
-
} from "../../chunk-
|
|
10
|
+
} from "../../chunk-IXNSTNS7.js";
|
|
11
11
|
import {
|
|
12
12
|
applyEdit,
|
|
13
13
|
countChanges,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
EDIT_FILE_TOOL_DESCRIPTION
|
|
20
20
|
} from "../../chunk-63WE2C5R.js";
|
|
21
21
|
import "../../chunk-4VWJFZVS.js";
|
|
22
|
-
import "../../chunk-
|
|
22
|
+
import "../../chunk-5FUTL2UF.js";
|
|
23
23
|
export {
|
|
24
24
|
EDIT_FILE_SYSTEM_PROMPT,
|
|
25
25
|
EDIT_FILE_TOOL_DESCRIPTION,
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
formatResult,
|
|
6
6
|
getSystemPrompt,
|
|
7
7
|
openai_default
|
|
8
|
-
} from "../../chunk-
|
|
8
|
+
} from "../../chunk-PKPJWARB.js";
|
|
9
9
|
import "../../chunk-CKTA4AXM.js";
|
|
10
10
|
import "../../chunk-63WE2C5R.js";
|
|
11
11
|
import "../../chunk-4VWJFZVS.js";
|
|
12
|
-
import "../../chunk-
|
|
12
|
+
import "../../chunk-5FUTL2UF.js";
|
|
13
13
|
export {
|
|
14
14
|
createEditFileTool,
|
|
15
15
|
openai_default as default,
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
editFileTool,
|
|
4
4
|
getSystemPrompt,
|
|
5
5
|
vercel_default
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-IXNSTNS7.js";
|
|
7
7
|
import "../../chunk-CKTA4AXM.js";
|
|
8
8
|
import "../../chunk-63WE2C5R.js";
|
|
9
9
|
import "../../chunk-4VWJFZVS.js";
|
|
10
|
-
import "../../chunk-
|
|
10
|
+
import "../../chunk-5FUTL2UF.js";
|
|
11
11
|
export {
|
|
12
12
|
createEditFileTool,
|
|
13
13
|
vercel_default as default,
|
package/dist/tools/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "../chunk-X2K57BH6.js";
|
|
2
2
|
import {
|
|
3
3
|
anthropic_exports
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-BHNJEBQJ.js";
|
|
5
5
|
import {
|
|
6
6
|
openai_exports
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-PKPJWARB.js";
|
|
8
8
|
import {
|
|
9
9
|
vercel_exports
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-IXNSTNS7.js";
|
|
11
11
|
import {
|
|
12
12
|
applyEdit,
|
|
13
13
|
countChanges,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
EDIT_FILE_TOOL_DESCRIPTION
|
|
20
20
|
} from "../chunk-63WE2C5R.js";
|
|
21
21
|
import "../chunk-4VWJFZVS.js";
|
|
22
|
-
import "../chunk-
|
|
22
|
+
import "../chunk-5FUTL2UF.js";
|
|
23
23
|
export {
|
|
24
24
|
EDIT_FILE_SYSTEM_PROMPT,
|
|
25
25
|
EDIT_FILE_TOOL_DESCRIPTION,
|
|
@@ -120,33 +120,9 @@ function parseNestedXmlTools(text) {
|
|
|
120
120
|
return tools;
|
|
121
121
|
}
|
|
122
122
|
function preprocessText(text) {
|
|
123
|
-
|
|
123
|
+
const processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "").replace(/<\/?tool_call>/gi, "");
|
|
124
124
|
const nestedTools = parseNestedXmlTools(processed);
|
|
125
|
-
const openingTagRegex = /<tool_call>|<tool>/gi;
|
|
126
|
-
const closingTagRegex = /<\/tool_call>|<\/tool>/gi;
|
|
127
|
-
const openingMatches = processed.match(openingTagRegex) || [];
|
|
128
|
-
const closingMatches = processed.match(closingTagRegex) || [];
|
|
129
|
-
if (openingMatches.length > closingMatches.length) {
|
|
130
|
-
const lastClosingMatch = /<\/tool_call>|<\/tool>/gi;
|
|
131
|
-
let lastClosingIndex = -1;
|
|
132
|
-
let match;
|
|
133
|
-
while ((match = lastClosingMatch.exec(processed)) !== null) {
|
|
134
|
-
lastClosingIndex = match.index + match[0].length;
|
|
135
|
-
}
|
|
136
|
-
if (lastClosingIndex > 0) {
|
|
137
|
-
processed = processed.slice(0, lastClosingIndex);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
125
|
const toolCallLines = [];
|
|
141
|
-
const toolTagRegex = /<tool_call>([\s\S]*?)<\/tool_call>|<tool>([\s\S]*?)<\/tool>/gi;
|
|
142
|
-
let tagMatch;
|
|
143
|
-
while ((tagMatch = toolTagRegex.exec(processed)) !== null) {
|
|
144
|
-
const content = (tagMatch[1] || tagMatch[2] || "").trim();
|
|
145
|
-
if (content) {
|
|
146
|
-
const lines = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l);
|
|
147
|
-
toolCallLines.push(...lines);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
126
|
const allLines = processed.split(/\r?\n/).map((l) => l.trim());
|
|
151
127
|
for (const line of allLines) {
|
|
152
128
|
if (!line) continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../tools/warp_grep/agent/parser.ts"],"sourcesContent":["// Parses assistant lines into structured tool calls\nimport type { ToolCall } from './types.js';\n\nconst VALID_COMMANDS = ['list_directory', 'grep', 'read', 'finish'] as const;\ntype ValidCommand = typeof VALID_COMMANDS[number];\n\nfunction isValidCommand(name: string): name is ValidCommand {\n return VALID_COMMANDS.includes(name as ValidCommand);\n}\n\nfunction getXmlElementText(xml: string, tagName: string): string | null {\n const regex = new RegExp(`<${tagName}>([\\\\s\\\\S]*?)</${tagName}>`, 'i');\n const match = xml.match(regex);\n return match ? match[1].trim() : null;\n}\n\nfunction parseNestedXmlTools(text: string): ToolCall[] {\n const tools: ToolCall[] = [];\n \n // Match any XML tool tags - this allows graceful handling of unknown tools\n // that might be added in future versions (they are simply ignored)\n const toolRegex = /<([a-z_][a-z0-9_]*)>([\\s\\S]*?)<\\/\\1>/gi;\n let match;\n \n while ((match = toolRegex.exec(text)) !== null) {\n const rawToolName = match[1].toLowerCase();\n const content = match[2];\n \n // Skip unknown tools silently - enables forward compatibility\n if (!isValidCommand(rawToolName)) continue;\n \n const toolName = rawToolName;\n \n if (toolName === 'list_directory') {\n const path = getXmlElementText(content, 'path');\n const pattern = getXmlElementText(content, 'pattern');\n if (path) {\n tools.push({ name: 'list_directory', arguments: { path, pattern } });\n }\n } else if (toolName === 'grep') {\n const pattern = getXmlElementText(content, 'pattern');\n const subDir = getXmlElementText(content, 'sub_dir');\n const glob = getXmlElementText(content, 'glob');\n if (pattern) {\n tools.push({ \n name: 'grep', \n arguments: { \n pattern, \n path: subDir || '.', \n ...(glob && { glob }) \n } \n });\n }\n } else if (toolName === 'read') {\n const path = getXmlElementText(content, 'path');\n const linesStr = getXmlElementText(content, 'lines');\n if (path) {\n const args: Record<string, unknown> = { path };\n if (linesStr) {\n const ranges: Array<[number, number]> = [];\n for (const rangeStr of linesStr.split(',')) {\n const trimmed = rangeStr.trim();\n if (!trimmed) continue;\n const [s, e] = trimmed.split('-').map(v => parseInt(v.trim(), 10));\n if (Number.isFinite(s) && Number.isFinite(e)) {\n ranges.push([s, e]);\n } else if (Number.isFinite(s)) {\n // Single line like \"100\"\n ranges.push([s, s]);\n }\n }\n if (ranges.length === 1) {\n args.start = ranges[0][0];\n args.end = ranges[0][1];\n } else if (ranges.length > 1) {\n args.lines = ranges;\n }\n }\n tools.push({ name: 'read', arguments: args });\n }\n } else if (toolName === 'finish') {\n // Parse nested <file> elements\n const fileRegex = /<file>([\\s\\S]*?)<\\/file>/gi;\n const files: Array<{ path: string; lines: Array<[number, number]> }> = [];\n let fileMatch;\n \n while ((fileMatch = fileRegex.exec(content)) !== null) {\n const fileContent = fileMatch[1];\n const filePath = getXmlElementText(fileContent, 'path');\n const linesStr = getXmlElementText(fileContent, 'lines');\n \n if (filePath && linesStr) {\n const ranges: Array<[number, number]> = [];\n for (const rangeStr of linesStr.split(',')) {\n if (rangeStr.trim() === '*') {\n ranges.push([1, 999999]); // Entire file\n } else {\n const [s, e] = rangeStr.split('-').map(v => parseInt(v.trim(), 10));\n if (Number.isFinite(s) && Number.isFinite(e)) {\n ranges.push([s, e]);\n }\n }\n }\n if (ranges.length > 0) {\n files.push({ path: filePath, lines: ranges });\n }\n }\n }\n \n if (files.length > 0) {\n tools.push({ name: 'finish', arguments: { files } });\n }\n }\n }\n \n return tools;\n}\n\nfunction preprocessText(text: string): { lines: string[]; nestedTools: ToolCall[] } {\n let processed = text.replace(/<think>[\\s\\S]*?<\\/think>/gi, '');\n const nestedTools = parseNestedXmlTools(processed);\n const openingTagRegex = /<tool_call>|<tool>/gi;\n const closingTagRegex = /<\\/tool_call>|<\\/tool>/gi;\n \n const openingMatches = processed.match(openingTagRegex) || [];\n const closingMatches = processed.match(closingTagRegex) || [];\n \n if (openingMatches.length > closingMatches.length) {\n const lastClosingMatch = /<\\/tool_call>|<\\/tool>/gi;\n let lastClosingIndex = -1;\n let match;\n while ((match = lastClosingMatch.exec(processed)) !== null) {\n lastClosingIndex = match.index + match[0].length;\n }\n if (lastClosingIndex > 0) {\n processed = processed.slice(0, lastClosingIndex);\n }\n }\n const toolCallLines: string[] = [];\n const toolTagRegex = /<tool_call>([\\s\\S]*?)<\\/tool_call>|<tool>([\\s\\S]*?)<\\/tool>/gi;\n let tagMatch;\n \n while ((tagMatch = toolTagRegex.exec(processed)) !== null) {\n const content = (tagMatch[1] || tagMatch[2] || '').trim();\n if (content) {\n const lines = content.split(/\\r?\\n/).map(l => l.trim()).filter(l => l);\n toolCallLines.push(...lines);\n }\n }\n \n // Also extract raw tool calls (lines starting with valid commands)\n const allLines = processed.split(/\\r?\\n/).map(l => l.trim());\n for (const line of allLines) {\n if (!line) continue;\n if (line.startsWith('<')) continue;\n \n const firstWord = line.split(/\\s/)[0];\n if (VALID_COMMANDS.includes(firstWord as ValidCommand)) {\n if (!toolCallLines.includes(line)) {\n toolCallLines.push(line);\n }\n }\n }\n \n return { lines: toolCallLines, nestedTools };\n}\n\nexport class LLMResponseParser {\n private readonly finishSpecSplitRe = /,(?=[^,\\s]+:)/;\n\n parse(text: string): ToolCall[] {\n if (typeof text !== 'string') {\n throw new TypeError('Command text must be a string.');\n }\n \n // Preprocess to handle XML tags\n const { lines, nestedTools } = preprocessText(text);\n \n // Start with nested XML tools (new format)\n const commands: ToolCall[] = [...nestedTools];\n let finishAccumulator: Map<string, number[][]> | null = null;\n\n lines.forEach((line) => {\n if (!line || line.startsWith('#')) return;\n const parts = this.splitLine(line);\n if (parts.length === 0) return;\n const cmd = parts[0];\n \n switch (cmd) {\n case 'list_directory':\n this.handleListDirectory(parts, line, commands);\n break;\n case 'grep':\n this.handleGrep(parts, line, commands);\n break;\n case 'read':\n this.handleRead(parts, line, commands);\n break;\n case 'finish':\n finishAccumulator = this.handleFinish(parts, line, commands, finishAccumulator);\n break;\n default:\n // Silently ignore unknown commands\n break;\n }\n });\n\n if (finishAccumulator) {\n const map = finishAccumulator as Map<string, number[][]>;\n const entries = [...map.entries()];\n const filesPayload = entries.map(([path, ranges]) => ({\n path,\n lines: [...ranges].sort((a, b) => a[0] - b[0]) as Array<[number, number]>,\n }));\n commands.push({ name: 'finish', arguments: { files: filesPayload } });\n }\n return commands;\n }\n\n private splitLine(line: string): string[] {\n // Split by whitespace but keep quoted blocks as one\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n for (let i = 0; i < line.length; i++) {\n const ch = line[i];\n if (ch === \"'\" && line[i - 1] !== '\\\\') {\n inSingle = !inSingle;\n current += ch;\n } else if (!inSingle && /\\s/.test(ch)) {\n if (current) {\n parts.push(current);\n current = '';\n }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n }\n\n /** Helper to create a _skip tool call with an error message */\n private skip(message: string): ToolCall {\n return { name: '_skip', arguments: { message } };\n }\n\n private handleListDirectory(parts: string[], rawLine: string, commands: ToolCall[]) {\n // list_directory <path> [pattern]\n if (parts.length < 2) {\n commands.push(this.skip(\n `[SKIPPED] Your command \"${rawLine}\" is missing a path. ` +\n `Correct format: list_directory <path> [pattern]. Example: list_directory src/`\n ));\n return;\n }\n const path = parts[1];\n const pattern = parts[2]?.replace(/^\"|\"$/g, '') ?? null;\n commands.push({ name: 'list_directory', arguments: { path, pattern } });\n }\n\n private handleGrep(parts: string[], rawLine: string, commands: ToolCall[]) {\n // grep '<pattern>' <path>\n if (parts.length < 3) {\n commands.push(this.skip(\n `[SKIPPED] Your command \"${rawLine}\" is missing arguments. ` +\n `Correct format: grep '<pattern>' <path>. Example: grep 'TODO' src/`\n ));\n return;\n }\n let pat = parts[1];\n // Be lenient: accept unquoted patterns by treating the first arg as the pattern\n if (pat.startsWith(\"'\") && pat.endsWith(\"'\")) {\n pat = pat.slice(1, -1);\n }\n // If pattern is empty after processing, skip\n if (!pat) {\n commands.push(this.skip(\n `[SKIPPED] Your command \"${rawLine}\" has an empty pattern. ` +\n `Provide a non-empty search pattern. Example: grep 'function' src/`\n ));\n return;\n }\n commands.push({ name: 'grep', arguments: { pattern: pat, path: parts[2] } });\n }\n\n private handleRead(parts: string[], rawLine: string, commands: ToolCall[]) {\n // read <path>[:start-end]\n if (parts.length < 2) {\n commands.push(this.skip(\n `[SKIPPED] Your command \"${rawLine}\" is missing a path. ` +\n `Correct format: read <path> or read <path>:<start>-<end>. Example: read src/index.ts:1-50`\n ));\n return;\n }\n const spec = parts[1];\n const rangeIdx = spec.indexOf(':');\n if (rangeIdx === -1) {\n commands.push({ name: 'read', arguments: { path: spec } });\n return;\n }\n const filePath = spec.slice(0, rangeIdx);\n const range = spec.slice(rangeIdx + 1);\n const [s, e] = range.split('-').map(v => parseInt(v, 10));\n // If range is invalid, fallback to reading the whole file\n if (!Number.isFinite(s) || !Number.isFinite(e)) {\n commands.push({ name: 'read', arguments: { path: filePath } });\n return;\n }\n commands.push({ name: 'read', arguments: { path: filePath, start: s, end: e } });\n }\n\n private handleFinish(parts: string[], rawLine: string, commands: ToolCall[], acc: Map<string, number[][]> | null) {\n // finish file1:1-10,20-30 file2:5-7\n const map = acc ?? new Map<string, number[][]>();\n const args = parts.slice(1);\n for (const token of args) {\n const [filePath, rangesText] = token.split(':', 2);\n if (!filePath || !rangesText) {\n // Skip this malformed token, continue processing others\n commands.push(this.skip(\n `[SKIPPED] Invalid finish token \"${token}\". ` +\n `Correct format: finish <path>:<start>-<end>. Example: finish src/index.ts:1-50`\n ));\n continue;\n }\n const rangeSpecs = rangesText.split(',').filter(Boolean);\n for (const spec of rangeSpecs) {\n const [s, e] = spec.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {\n // Skip this invalid range, continue with others\n commands.push(this.skip(\n `[SKIPPED] Invalid range \"${spec}\" in \"${token}\". ` +\n `Ranges must be <start>-<end> where start <= end. Example: 1-50`\n ));\n continue;\n }\n const arr = map.get(filePath) ?? [];\n arr.push([s, e]);\n map.set(filePath, arr);\n }\n }\n return map;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../tools/warp_grep/agent/parser.ts"],"sourcesContent":["// Parses assistant lines into structured tool calls\nimport type { ToolCall } from './types.js';\n\nconst VALID_COMMANDS = ['list_directory', 'grep', 'read', 'finish'] as const;\ntype ValidCommand = typeof VALID_COMMANDS[number];\n\nfunction isValidCommand(name: string): name is ValidCommand {\n return VALID_COMMANDS.includes(name as ValidCommand);\n}\n\nfunction getXmlElementText(xml: string, tagName: string): string | null {\n const regex = new RegExp(`<${tagName}>([\\\\s\\\\S]*?)</${tagName}>`, 'i');\n const match = xml.match(regex);\n return match ? match[1].trim() : null;\n}\n\nfunction parseNestedXmlTools(text: string): ToolCall[] {\n const tools: ToolCall[] = [];\n \n // Match any XML tool tags. Unknown tools are silently ignored for forward-compatibility:\n // if we add new tools (e.g. <search>) to the model, old clients won't break.\n const toolRegex = /<([a-z_][a-z0-9_]*)>([\\s\\S]*?)<\\/\\1>/gi;\n let match;\n \n while ((match = toolRegex.exec(text)) !== null) {\n const rawToolName = match[1].toLowerCase();\n const content = match[2];\n \n // Skip unknown tools silently - enables forward compatibility\n if (!isValidCommand(rawToolName)) continue;\n \n const toolName = rawToolName;\n \n if (toolName === 'list_directory') {\n const path = getXmlElementText(content, 'path');\n const pattern = getXmlElementText(content, 'pattern');\n if (path) {\n tools.push({ name: 'list_directory', arguments: { path, pattern } });\n }\n } else if (toolName === 'grep') {\n const pattern = getXmlElementText(content, 'pattern');\n const subDir = getXmlElementText(content, 'sub_dir');\n const glob = getXmlElementText(content, 'glob');\n if (pattern) {\n tools.push({ \n name: 'grep', \n arguments: { \n pattern, \n path: subDir || '.', \n ...(glob && { glob }) \n } \n });\n }\n } else if (toolName === 'read') {\n const path = getXmlElementText(content, 'path');\n const linesStr = getXmlElementText(content, 'lines');\n if (path) {\n const args: Record<string, unknown> = { path };\n if (linesStr) {\n const ranges: Array<[number, number]> = [];\n for (const rangeStr of linesStr.split(',')) {\n const trimmed = rangeStr.trim();\n if (!trimmed) continue;\n const [s, e] = trimmed.split('-').map(v => parseInt(v.trim(), 10));\n if (Number.isFinite(s) && Number.isFinite(e)) {\n ranges.push([s, e]);\n } else if (Number.isFinite(s)) {\n // Single line like \"100\"\n ranges.push([s, s]);\n }\n }\n if (ranges.length === 1) {\n args.start = ranges[0][0];\n args.end = ranges[0][1];\n } else if (ranges.length > 1) {\n args.lines = ranges;\n }\n }\n tools.push({ name: 'read', arguments: args });\n }\n } else if (toolName === 'finish') {\n // Parse nested <file> elements\n const fileRegex = /<file>([\\s\\S]*?)<\\/file>/gi;\n const files: Array<{ path: string; lines: Array<[number, number]> }> = [];\n let fileMatch;\n \n while ((fileMatch = fileRegex.exec(content)) !== null) {\n const fileContent = fileMatch[1];\n const filePath = getXmlElementText(fileContent, 'path');\n const linesStr = getXmlElementText(fileContent, 'lines');\n \n if (filePath && linesStr) {\n const ranges: Array<[number, number]> = [];\n for (const rangeStr of linesStr.split(',')) {\n if (rangeStr.trim() === '*') {\n ranges.push([1, 999999]); // Entire file\n } else {\n const [s, e] = rangeStr.split('-').map(v => parseInt(v.trim(), 10));\n if (Number.isFinite(s) && Number.isFinite(e)) {\n ranges.push([s, e]);\n }\n }\n }\n if (ranges.length > 0) {\n files.push({ path: filePath, lines: ranges });\n }\n }\n }\n \n if (files.length > 0) {\n tools.push({ name: 'finish', arguments: { files } });\n }\n }\n }\n \n return tools;\n}\n\nfunction preprocessText(text: string): { lines: string[]; nestedTools: ToolCall[] } {\n // Strip <think> blocks (reasoning) and <tool_call> wrappers (model hallucination).\n // NOTE: Only strip exact <tool_call> tags - NOT <tool> or <tool_xyz> which could be valid future tools.\n const processed = text\n .replace(/<think>[\\s\\S]*?<\\/think>/gi, '')\n .replace(/<\\/?tool_call>/gi, '');\n const nestedTools = parseNestedXmlTools(processed);\n \n // Extract raw line-based tool calls (legacy format: `grep 'pattern' path`)\n const toolCallLines: string[] = [];\n const allLines = processed.split(/\\r?\\n/).map(l => l.trim());\n for (const line of allLines) {\n if (!line) continue;\n if (line.startsWith('<')) continue;\n \n const firstWord = line.split(/\\s/)[0];\n if (VALID_COMMANDS.includes(firstWord as ValidCommand)) {\n if (!toolCallLines.includes(line)) {\n toolCallLines.push(line);\n }\n }\n }\n \n return { lines: toolCallLines, nestedTools };\n}\n\nexport class LLMResponseParser {\n private readonly finishSpecSplitRe = /,(?=[^,\\s]+:)/;\n\n parse(text: string): ToolCall[] {\n if (typeof text !== 'string') {\n throw new TypeError('Command text must be a string.');\n }\n \n // Preprocess to handle XML tags\n const { lines, nestedTools } = preprocessText(text);\n \n // Start with nested XML tools (new format)\n const commands: ToolCall[] = [...nestedTools];\n let finishAccumulator: Map<string, number[][]> | null = null;\n\n lines.forEach((line) => {\n if (!line || line.startsWith('#')) return;\n const parts = this.splitLine(line);\n if (parts.length === 0) return;\n const cmd = parts[0];\n \n switch (cmd) {\n case 'list_directory':\n this.handleListDirectory(parts, line, commands);\n break;\n case 'grep':\n this.handleGrep(parts, line, commands);\n break;\n case 'read':\n this.handleRead(parts, line, commands);\n break;\n case 'finish':\n finishAccumulator = this.handleFinish(parts, line, commands, finishAccumulator);\n break;\n default:\n // Silently ignore unknown commands\n break;\n }\n });\n\n if (finishAccumulator) {\n const map = finishAccumulator as Map<string, number[][]>;\n const entries = [...map.entries()];\n const filesPayload = entries.map(([path, ranges]) => ({\n path,\n lines: [...ranges].sort((a, b) => a[0] - b[0]) as Array<[number, number]>,\n }));\n commands.push({ name: 'finish', arguments: { files: filesPayload } });\n }\n return commands;\n }\n\n private splitLine(line: string): string[] {\n // Split by whitespace but keep quoted blocks as one\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n for (let i = 0; i < line.length; i++) {\n const ch = line[i];\n if (ch === \"'\" && line[i - 1] !== '\\\\') {\n inSingle = !inSingle;\n current += ch;\n } else if (!inSingle && /\\s/.test(ch)) {\n if (current) {\n parts.push(current);\n current = '';\n }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n }\n\n /** Helper to create a _skip tool call with an error message */\n private skip(message: string): ToolCall {\n return { name: '_skip', arguments: { message } };\n }\n\n private handleListDirectory(parts: string[], rawLine: string, commands: ToolCall[]) {\n // list_directory <path> [pattern]\n if (parts.length < 2) {\n commands.push(this.skip(\n `[SKIPPED] Your command \"${rawLine}\" is missing a path. ` +\n `Correct format: list_directory <path> [pattern]. Example: list_directory src/`\n ));\n return;\n }\n const path = parts[1];\n const pattern = parts[2]?.replace(/^\"|\"$/g, '') ?? null;\n commands.push({ name: 'list_directory', arguments: { path, pattern } });\n }\n\n private handleGrep(parts: string[], rawLine: string, commands: ToolCall[]) {\n // grep '<pattern>' <path>\n if (parts.length < 3) {\n commands.push(this.skip(\n `[SKIPPED] Your command \"${rawLine}\" is missing arguments. ` +\n `Correct format: grep '<pattern>' <path>. Example: grep 'TODO' src/`\n ));\n return;\n }\n let pat = parts[1];\n // Be lenient: accept unquoted patterns by treating the first arg as the pattern\n if (pat.startsWith(\"'\") && pat.endsWith(\"'\")) {\n pat = pat.slice(1, -1);\n }\n // If pattern is empty after processing, skip\n if (!pat) {\n commands.push(this.skip(\n `[SKIPPED] Your command \"${rawLine}\" has an empty pattern. ` +\n `Provide a non-empty search pattern. Example: grep 'function' src/`\n ));\n return;\n }\n commands.push({ name: 'grep', arguments: { pattern: pat, path: parts[2] } });\n }\n\n private handleRead(parts: string[], rawLine: string, commands: ToolCall[]) {\n // read <path>[:start-end]\n if (parts.length < 2) {\n commands.push(this.skip(\n `[SKIPPED] Your command \"${rawLine}\" is missing a path. ` +\n `Correct format: read <path> or read <path>:<start>-<end>. Example: read src/index.ts:1-50`\n ));\n return;\n }\n const spec = parts[1];\n const rangeIdx = spec.indexOf(':');\n if (rangeIdx === -1) {\n commands.push({ name: 'read', arguments: { path: spec } });\n return;\n }\n const filePath = spec.slice(0, rangeIdx);\n const range = spec.slice(rangeIdx + 1);\n const [s, e] = range.split('-').map(v => parseInt(v, 10));\n // If range is invalid, fallback to reading the whole file\n if (!Number.isFinite(s) || !Number.isFinite(e)) {\n commands.push({ name: 'read', arguments: { path: filePath } });\n return;\n }\n commands.push({ name: 'read', arguments: { path: filePath, start: s, end: e } });\n }\n\n private handleFinish(parts: string[], rawLine: string, commands: ToolCall[], acc: Map<string, number[][]> | null) {\n // finish file1:1-10,20-30 file2:5-7\n const map = acc ?? new Map<string, number[][]>();\n const args = parts.slice(1);\n for (const token of args) {\n const [filePath, rangesText] = token.split(':', 2);\n if (!filePath || !rangesText) {\n // Skip this malformed token, continue processing others\n commands.push(this.skip(\n `[SKIPPED] Invalid finish token \"${token}\". ` +\n `Correct format: finish <path>:<start>-<end>. Example: finish src/index.ts:1-50`\n ));\n continue;\n }\n const rangeSpecs = rangesText.split(',').filter(Boolean);\n for (const spec of rangeSpecs) {\n const [s, e] = spec.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {\n // Skip this invalid range, continue with others\n commands.push(this.skip(\n `[SKIPPED] Invalid range \"${spec}\" in \"${token}\". ` +\n `Ranges must be <start>-<end> where start <= end. Example: 1-50`\n ));\n continue;\n }\n const arr = map.get(filePath) ?? [];\n arr.push([s, e]);\n map.set(filePath, arr);\n }\n }\n return map;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -424,33 +424,9 @@ function parseNestedXmlTools(text) {
|
|
|
424
424
|
return tools;
|
|
425
425
|
}
|
|
426
426
|
function preprocessText(text) {
|
|
427
|
-
|
|
427
|
+
const processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "").replace(/<\/?tool_call>/gi, "");
|
|
428
428
|
const nestedTools = parseNestedXmlTools(processed);
|
|
429
|
-
const openingTagRegex = /<tool_call>|<tool>/gi;
|
|
430
|
-
const closingTagRegex = /<\/tool_call>|<\/tool>/gi;
|
|
431
|
-
const openingMatches = processed.match(openingTagRegex) || [];
|
|
432
|
-
const closingMatches = processed.match(closingTagRegex) || [];
|
|
433
|
-
if (openingMatches.length > closingMatches.length) {
|
|
434
|
-
const lastClosingMatch = /<\/tool_call>|<\/tool>/gi;
|
|
435
|
-
let lastClosingIndex = -1;
|
|
436
|
-
let match;
|
|
437
|
-
while ((match = lastClosingMatch.exec(processed)) !== null) {
|
|
438
|
-
lastClosingIndex = match.index + match[0].length;
|
|
439
|
-
}
|
|
440
|
-
if (lastClosingIndex > 0) {
|
|
441
|
-
processed = processed.slice(0, lastClosingIndex);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
429
|
const toolCallLines = [];
|
|
445
|
-
const toolTagRegex = /<tool_call>([\s\S]*?)<\/tool_call>|<tool>([\s\S]*?)<\/tool>/gi;
|
|
446
|
-
let tagMatch;
|
|
447
|
-
while ((tagMatch = toolTagRegex.exec(processed)) !== null) {
|
|
448
|
-
const content = (tagMatch[1] || tagMatch[2] || "").trim();
|
|
449
|
-
if (content) {
|
|
450
|
-
const lines = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l);
|
|
451
|
-
toolCallLines.push(...lines);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
430
|
const allLines = processed.split(/\r?\n/).map((l) => l.trim());
|
|
455
431
|
for (const line of allLines) {
|
|
456
432
|
if (!line) continue;
|