@morphllm/morphsdk 0.2.143 → 0.2.145
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-YIETFYCL.js → chunk-4LWMPKSB.js} +71 -44
- package/dist/chunk-4LWMPKSB.js.map +1 -0
- package/dist/{chunk-HZOTLGJH.js → chunk-4Y2NM6JD.js} +42 -2
- package/dist/chunk-4Y2NM6JD.js.map +1 -0
- package/dist/{chunk-YTPYQAIO.js → chunk-5FCXLQJU.js} +3 -3
- package/dist/{chunk-KQ6QSAE7.js → chunk-6CFKWZK3.js} +3 -3
- package/dist/{chunk-NF2QWJDY.js → chunk-B3AKP3RA.js} +31 -2
- package/dist/chunk-B3AKP3RA.js.map +1 -0
- package/dist/{chunk-ALY5S4XC.js → chunk-BAF33L6C.js} +2 -2
- package/dist/{chunk-TRPJAKAS.js → chunk-BXRJYLRS.js} +2 -2
- package/dist/chunk-CMSHXALI.js +60 -0
- package/dist/chunk-CMSHXALI.js.map +1 -0
- package/dist/{chunk-X5IVORU2.js → chunk-EPIOAODF.js} +2 -2
- package/dist/{chunk-T53IMLYK.js → chunk-G23BI5CQ.js} +2 -2
- package/dist/{chunk-FZQZZP3R.js → chunk-GHPQYSSF.js} +2 -2
- package/dist/{chunk-7POOJWBR.js → chunk-GXCWKYGU.js} +2 -2
- package/dist/{chunk-PBOKDQR3.js → chunk-GXM3G7Z4.js} +3 -3
- package/dist/{chunk-OSQ2EMUP.js → chunk-HBIW2XV2.js} +2 -2
- package/dist/{chunk-FJVYE6ZX.js → chunk-HE7K2QNQ.js} +17 -17
- package/dist/{chunk-FIVYDIHX.js → chunk-HYRHI2UL.js} +1 -1
- package/dist/{chunk-DKODF3YG.js → chunk-I3J46TSB.js} +5 -4
- package/dist/chunk-I3J46TSB.js.map +1 -0
- package/dist/{chunk-F6JGAEK5.js → chunk-IRWHN55G.js} +1 -1
- package/dist/{chunk-QFCED636.js → chunk-JHYH3NEP.js} +2 -2
- package/dist/chunk-JHYH3NEP.js.map +1 -0
- package/dist/{chunk-YJG2KRXY.js → chunk-JMUAQQJU.js} +3 -3
- package/dist/{chunk-W27OOF55.js → chunk-JRBU4UNP.js} +2 -2
- package/dist/{chunk-DN3WS37U.js → chunk-KELRCMA6.js} +2 -2
- package/dist/{chunk-DN3WS37U.js.map → chunk-KELRCMA6.js.map} +1 -1
- package/dist/{chunk-TLPFEK5S.js → chunk-MRPASJBX.js} +2 -2
- package/dist/{chunk-RMBIT3I3.js → chunk-MTJ3PR4M.js} +2 -2
- package/dist/{chunk-VFGM343D.js → chunk-N7TTZIBK.js} +2 -2
- package/dist/chunk-OPEQQGST.js +396 -0
- package/dist/chunk-OPEQQGST.js.map +1 -0
- package/dist/{chunk-Z5APBTQP.js → chunk-PX7ODEML.js} +2 -2
- package/dist/{chunk-OOZZE5BQ.js → chunk-RZXS4ADX.js} +2 -2
- package/dist/{chunk-VBSO32I2.js → chunk-S54SPKX3.js} +3 -3
- package/dist/{chunk-ENLZ45ZZ.js → chunk-SUE4GYA2.js} +2 -2
- package/dist/{chunk-TXOUDREW.js → chunk-VRV5UYTN.js} +2 -2
- package/dist/{chunk-ZGJLA2O6.js → chunk-XL7R3XN5.js} +2 -2
- package/dist/client.cjs +427 -439
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +27 -28
- package/dist/edge.cjs +1 -1
- package/dist/edge.cjs.map +1 -1
- package/dist/edge.js +4 -4
- package/dist/{finish-DBKuo8yj.d.ts → finish-Ddj1MPGt.d.ts} +1 -1
- package/dist/index.cjs +446 -439
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +30 -30
- 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 +422 -434
- package/dist/subagents/anthropic.cjs.map +1 -1
- package/dist/subagents/anthropic.js +8 -9
- package/dist/subagents/vercel.cjs +422 -434
- package/dist/subagents/vercel.cjs.map +1 -1
- package/dist/subagents/vercel.js +8 -9
- 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 +4 -3
- package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/config.d.ts +2 -1
- package/dist/tools/warp_grep/agent/config.js +1 -1
- package/dist/tools/warp_grep/agent/parser.cjs +52 -121
- package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/parser.d.ts +12 -5
- package/dist/tools/warp_grep/agent/parser.js +7 -3
- package/dist/tools/warp_grep/agent/runner.cjs +335 -416
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.d.ts +6 -3
- package/dist/tools/warp_grep/agent/runner.js +5 -6
- package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/types.d.ts +22 -3
- package/dist/tools/warp_grep/anthropic.cjs +423 -435
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.js +9 -10
- package/dist/tools/warp_grep/client.cjs +422 -434
- package/dist/tools/warp_grep/client.cjs.map +1 -1
- package/dist/tools/warp_grep/client.js +7 -8
- package/dist/tools/warp_grep/gemini.cjs +423 -435
- package/dist/tools/warp_grep/gemini.cjs.map +1 -1
- package/dist/tools/warp_grep/gemini.js +8 -9
- package/dist/tools/warp_grep/gemini.js.map +1 -1
- package/dist/tools/warp_grep/harness.cjs +164 -176
- package/dist/tools/warp_grep/harness.cjs.map +1 -1
- package/dist/tools/warp_grep/harness.d.ts +17 -38
- package/dist/tools/warp_grep/harness.js +15 -14
- package/dist/tools/warp_grep/harness.js.map +1 -1
- package/dist/tools/warp_grep/index.cjs +442 -435
- 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 +11 -11
- package/dist/tools/warp_grep/openai.cjs +423 -435
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.js +9 -10
- package/dist/tools/warp_grep/providers/local.cjs +43 -2
- package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/local.d.ts +5 -1
- package/dist/tools/warp_grep/providers/local.js +2 -2
- package/dist/tools/warp_grep/providers/remote.cjs +32 -2
- package/dist/tools/warp_grep/providers/remote.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/remote.d.ts +9 -1
- 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 +14 -1
- package/dist/tools/warp_grep/vercel.cjs +423 -435
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.js +9 -10
- 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-DKODF3YG.js.map +0 -1
- package/dist/chunk-HZOTLGJH.js.map +0 -1
- package/dist/chunk-NF2QWJDY.js.map +0 -1
- package/dist/chunk-QFCED636.js.map +0 -1
- package/dist/chunk-SSQYLUKI.js +0 -409
- package/dist/chunk-SSQYLUKI.js.map +0 -1
- package/dist/chunk-VCKJ22DX.js +0 -131
- package/dist/chunk-VCKJ22DX.js.map +0 -1
- package/dist/chunk-YIETFYCL.js.map +0 -1
- /package/dist/{chunk-YTPYQAIO.js.map → chunk-5FCXLQJU.js.map} +0 -0
- /package/dist/{chunk-KQ6QSAE7.js.map → chunk-6CFKWZK3.js.map} +0 -0
- /package/dist/{chunk-ALY5S4XC.js.map → chunk-BAF33L6C.js.map} +0 -0
- /package/dist/{chunk-TRPJAKAS.js.map → chunk-BXRJYLRS.js.map} +0 -0
- /package/dist/{chunk-X5IVORU2.js.map → chunk-EPIOAODF.js.map} +0 -0
- /package/dist/{chunk-T53IMLYK.js.map → chunk-G23BI5CQ.js.map} +0 -0
- /package/dist/{chunk-FZQZZP3R.js.map → chunk-GHPQYSSF.js.map} +0 -0
- /package/dist/{chunk-7POOJWBR.js.map → chunk-GXCWKYGU.js.map} +0 -0
- /package/dist/{chunk-PBOKDQR3.js.map → chunk-GXM3G7Z4.js.map} +0 -0
- /package/dist/{chunk-OSQ2EMUP.js.map → chunk-HBIW2XV2.js.map} +0 -0
- /package/dist/{chunk-FJVYE6ZX.js.map → chunk-HE7K2QNQ.js.map} +0 -0
- /package/dist/{chunk-FIVYDIHX.js.map → chunk-HYRHI2UL.js.map} +0 -0
- /package/dist/{chunk-F6JGAEK5.js.map → chunk-IRWHN55G.js.map} +0 -0
- /package/dist/{chunk-YJG2KRXY.js.map → chunk-JMUAQQJU.js.map} +0 -0
- /package/dist/{chunk-W27OOF55.js.map → chunk-JRBU4UNP.js.map} +0 -0
- /package/dist/{chunk-TLPFEK5S.js.map → chunk-MRPASJBX.js.map} +0 -0
- /package/dist/{chunk-RMBIT3I3.js.map → chunk-MTJ3PR4M.js.map} +0 -0
- /package/dist/{chunk-VFGM343D.js.map → chunk-N7TTZIBK.js.map} +0 -0
- /package/dist/{chunk-Z5APBTQP.js.map → chunk-PX7ODEML.js.map} +0 -0
- /package/dist/{chunk-OOZZE5BQ.js.map → chunk-RZXS4ADX.js.map} +0 -0
- /package/dist/{chunk-VBSO32I2.js.map → chunk-S54SPKX3.js.map} +0 -0
- /package/dist/{chunk-ENLZ45ZZ.js.map → chunk-SUE4GYA2.js.map} +0 -0
- /package/dist/{chunk-TXOUDREW.js.map → chunk-VRV5UYTN.js.map} +0 -0
- /package/dist/{chunk-ZGJLA2O6.js.map → chunk-XL7R3XN5.js.map} +0 -0
package/dist/chunk-SSQYLUKI.js
DELETED
|
@@ -1,409 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildInitialState,
|
|
3
|
-
calculateContextBudget,
|
|
4
|
-
enforceContextLimit,
|
|
5
|
-
formatTurnMessage,
|
|
6
|
-
readFinishFiles,
|
|
7
|
-
toolGrep,
|
|
8
|
-
toolListDirectory,
|
|
9
|
-
toolRead
|
|
10
|
-
} from "./chunk-YIETFYCL.js";
|
|
11
|
-
import {
|
|
12
|
-
formatAgentToolOutput
|
|
13
|
-
} from "./chunk-QRXG5CAZ.js";
|
|
14
|
-
import {
|
|
15
|
-
LLMResponseParser
|
|
16
|
-
} from "./chunk-VCKJ22DX.js";
|
|
17
|
-
import {
|
|
18
|
-
AGENT_CONFIG,
|
|
19
|
-
DEFAULT_MODEL
|
|
20
|
-
} from "./chunk-DKODF3YG.js";
|
|
21
|
-
import {
|
|
22
|
-
SDK_VERSION
|
|
23
|
-
} from "./chunk-DN3WS37U.js";
|
|
24
|
-
|
|
25
|
-
// tools/warp_grep/agent/runner.ts
|
|
26
|
-
import OpenAI from "openai";
|
|
27
|
-
import path from "path";
|
|
28
|
-
var parser = new LLMResponseParser();
|
|
29
|
-
var DEFAULT_API_URL = "https://api.morphllm.com";
|
|
30
|
-
async function callModel(messages, model, options = {}) {
|
|
31
|
-
const baseUrl = options.morphApiUrl || DEFAULT_API_URL;
|
|
32
|
-
const apiKey = options.morphApiKey || process.env.MORPH_API_KEY || "";
|
|
33
|
-
const timeoutMs = options.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
|
|
34
|
-
const parsedUrl = new URL(baseUrl);
|
|
35
|
-
const baseURL = parsedUrl.pathname === "/" ? `${baseUrl}/v1` : baseUrl;
|
|
36
|
-
const client = new OpenAI({
|
|
37
|
-
apiKey,
|
|
38
|
-
baseURL,
|
|
39
|
-
maxRetries: options.retryConfig?.maxRetries,
|
|
40
|
-
timeout: timeoutMs,
|
|
41
|
-
defaultHeaders: { "X-Morph-SDK-Version": SDK_VERSION }
|
|
42
|
-
});
|
|
43
|
-
const MAX_EMPTY_RETRIES = 1;
|
|
44
|
-
for (let attempt = 0; attempt <= MAX_EMPTY_RETRIES; attempt++) {
|
|
45
|
-
let data;
|
|
46
|
-
try {
|
|
47
|
-
data = await client.chat.completions.create({
|
|
48
|
-
model,
|
|
49
|
-
temperature: 0,
|
|
50
|
-
max_tokens: 1024,
|
|
51
|
-
messages,
|
|
52
|
-
...options.search_type ? { search_type: options.search_type } : {}
|
|
53
|
-
});
|
|
54
|
-
} catch (error) {
|
|
55
|
-
if (error instanceof OpenAI.APIError && error.status === 404) {
|
|
56
|
-
const defaultMsg = "The endpoint you are trying to call is likely deprecated. Please update with: npm cache clean --force && npx -y @morphllm/morphmcp@latest or visit: https://morphllm.com/mcp";
|
|
57
|
-
const errorText = error.message?.trim();
|
|
58
|
-
throw new Error(errorText || defaultMsg);
|
|
59
|
-
}
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
|
-
const choice = data?.choices?.[0];
|
|
63
|
-
const content = choice?.message?.content;
|
|
64
|
-
if (content && typeof content === "string") {
|
|
65
|
-
return content;
|
|
66
|
-
}
|
|
67
|
-
if (attempt === MAX_EMPTY_RETRIES) {
|
|
68
|
-
const finishReason = choice?.finish_reason ?? "unknown";
|
|
69
|
-
const hasToolCalls = Array.isArray(choice?.message?.tool_calls) && choice.message.tool_calls.length > 0;
|
|
70
|
-
const choicesLen = data?.choices?.length ?? 0;
|
|
71
|
-
const contentType = content === null ? "null" : content === void 0 ? "undefined" : typeof content;
|
|
72
|
-
throw new Error(
|
|
73
|
-
`Invalid response from model: content=${contentType}, finish_reason=${finishReason}, has_tool_calls=${hasToolCalls}, choices_length=${choicesLen}`
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
77
|
-
}
|
|
78
|
-
throw new Error("Invalid response from model");
|
|
79
|
-
}
|
|
80
|
-
async function runWarpGrep(config) {
|
|
81
|
-
const totalStart = Date.now();
|
|
82
|
-
const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
|
|
83
|
-
const timings = { turns: [], timeout_ms: timeoutMs };
|
|
84
|
-
const repoRoot = path.resolve(config.repoRoot || process.cwd());
|
|
85
|
-
const model = config.model || DEFAULT_MODEL;
|
|
86
|
-
const messages = [];
|
|
87
|
-
const maxTurns = AGENT_CONFIG.MAX_TURNS;
|
|
88
|
-
const initialStateStart = Date.now();
|
|
89
|
-
const initialState = await buildInitialState(repoRoot, config.searchTerm, config.provider, { search_type: config.search_type });
|
|
90
|
-
timings.initial_state_ms = Date.now() - initialStateStart;
|
|
91
|
-
messages.push({ role: "user", content: initialState });
|
|
92
|
-
const provider = config.provider;
|
|
93
|
-
const errors = [];
|
|
94
|
-
let finishMeta;
|
|
95
|
-
let terminationReason = "terminated";
|
|
96
|
-
for (let turn = 1; turn <= maxTurns; turn += 1) {
|
|
97
|
-
const turnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };
|
|
98
|
-
enforceContextLimit(messages);
|
|
99
|
-
const modelCallStart = Date.now();
|
|
100
|
-
const assistantContent = await callModel(messages, model, {
|
|
101
|
-
morphApiKey: config.morphApiKey,
|
|
102
|
-
morphApiUrl: config.morphApiUrl,
|
|
103
|
-
retryConfig: config.retryConfig,
|
|
104
|
-
timeout: timeoutMs,
|
|
105
|
-
search_type: config.search_type
|
|
106
|
-
}).catch((e) => {
|
|
107
|
-
const errMsg = e instanceof Error ? e.message : String(e);
|
|
108
|
-
console.error(`[warp_grep] Morph API call failed on turn ${turn}:`, errMsg);
|
|
109
|
-
errors.push({ message: errMsg });
|
|
110
|
-
return "";
|
|
111
|
-
});
|
|
112
|
-
turnMetrics.morph_api_ms = Date.now() - modelCallStart;
|
|
113
|
-
if (!assistantContent) {
|
|
114
|
-
console.error(`[warp_grep] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);
|
|
115
|
-
timings.turns.push(turnMetrics);
|
|
116
|
-
break;
|
|
117
|
-
}
|
|
118
|
-
messages.push({ role: "assistant", content: assistantContent });
|
|
119
|
-
const toolCalls = parser.parse(assistantContent);
|
|
120
|
-
if (toolCalls.length === 0) {
|
|
121
|
-
console.error(`[warp_grep] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));
|
|
122
|
-
errors.push({ message: "No tool calls produced by the model. Your MCP is likely out of date! Update it by running: rm -rf ~/.npm/_npx && npm cache clean --force && npx -y @morphllm/morphmcp@latest" });
|
|
123
|
-
terminationReason = "terminated";
|
|
124
|
-
timings.turns.push(turnMetrics);
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
const finishCalls = toolCalls.filter((c) => c.name === "finish");
|
|
128
|
-
const grepCalls = toolCalls.filter((c) => c.name === "grep");
|
|
129
|
-
const listDirCalls = toolCalls.filter((c) => c.name === "list_directory");
|
|
130
|
-
const readCalls = toolCalls.filter((c) => c.name === "read");
|
|
131
|
-
const skipCalls = toolCalls.filter((c) => c.name === "_skip");
|
|
132
|
-
const formatted = [];
|
|
133
|
-
for (const c of skipCalls) {
|
|
134
|
-
const msg = c.arguments?.message || "Command skipped due to parsing error";
|
|
135
|
-
formatted.push(msg);
|
|
136
|
-
}
|
|
137
|
-
const allPromises = [];
|
|
138
|
-
for (const c of grepCalls) {
|
|
139
|
-
const args = c.arguments ?? {};
|
|
140
|
-
allPromises.push(
|
|
141
|
-
toolGrep(provider, args).then(
|
|
142
|
-
({ output }) => formatAgentToolOutput("grep", args, output),
|
|
143
|
-
(err) => formatAgentToolOutput("grep", args, String(err), { isError: true })
|
|
144
|
-
)
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
for (const c of listDirCalls) {
|
|
148
|
-
const args = c.arguments ?? {};
|
|
149
|
-
allPromises.push(
|
|
150
|
-
toolListDirectory(provider, args).then(
|
|
151
|
-
(p) => formatAgentToolOutput("list_directory", args, p),
|
|
152
|
-
(err) => formatAgentToolOutput("list_directory", args, String(err), { isError: true })
|
|
153
|
-
)
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
for (const c of readCalls) {
|
|
157
|
-
const args = c.arguments ?? {};
|
|
158
|
-
allPromises.push(
|
|
159
|
-
toolRead(provider, args).then(
|
|
160
|
-
(p) => formatAgentToolOutput("read", args, p),
|
|
161
|
-
(err) => formatAgentToolOutput("read", args, String(err), { isError: true })
|
|
162
|
-
)
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
const toolExecStart = Date.now();
|
|
166
|
-
const allResults = await Promise.all(allPromises);
|
|
167
|
-
turnMetrics.local_tools_ms = Date.now() - toolExecStart;
|
|
168
|
-
for (const result of allResults) {
|
|
169
|
-
formatted.push(result);
|
|
170
|
-
}
|
|
171
|
-
if (formatted.length > 0) {
|
|
172
|
-
const turnMessage = formatTurnMessage(turn, maxTurns);
|
|
173
|
-
const contextBudget = calculateContextBudget(messages);
|
|
174
|
-
messages.push({ role: "user", content: formatted.join("\n") + turnMessage + "\n" + contextBudget });
|
|
175
|
-
}
|
|
176
|
-
timings.turns.push(turnMetrics);
|
|
177
|
-
if (finishCalls.length) {
|
|
178
|
-
const fc = finishCalls[0];
|
|
179
|
-
const files = fc.arguments?.files ?? [];
|
|
180
|
-
const textResult = fc.arguments?.textResult;
|
|
181
|
-
finishMeta = { files };
|
|
182
|
-
terminationReason = "completed";
|
|
183
|
-
if (files.length === 0) {
|
|
184
|
-
const payload2 = textResult || "No relevant code found.";
|
|
185
|
-
timings.turns.push(turnMetrics);
|
|
186
|
-
timings.total_ms = Date.now() - totalStart;
|
|
187
|
-
return {
|
|
188
|
-
terminationReason: "completed",
|
|
189
|
-
messages,
|
|
190
|
-
finish: { payload: payload2, metadata: finishMeta },
|
|
191
|
-
timings
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
if (terminationReason !== "completed" || !finishMeta) {
|
|
198
|
-
timings.total_ms = Date.now() - totalStart;
|
|
199
|
-
return { terminationReason, messages, errors, timings };
|
|
200
|
-
}
|
|
201
|
-
const parts = ["Relevant context found:"];
|
|
202
|
-
for (const f of finishMeta.files) {
|
|
203
|
-
const ranges = f.lines === "*" ? "*" : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(", ") : "*";
|
|
204
|
-
parts.push(`- ${f.path}: ${ranges}`);
|
|
205
|
-
}
|
|
206
|
-
const payload = parts.join("\n");
|
|
207
|
-
const finishResolutionStart = Date.now();
|
|
208
|
-
const fileReadErrors = [];
|
|
209
|
-
const resolved = await readFinishFiles(
|
|
210
|
-
repoRoot,
|
|
211
|
-
finishMeta.files,
|
|
212
|
-
async (p, s, e) => {
|
|
213
|
-
try {
|
|
214
|
-
const rr = await provider.read({ path: p, start: s, end: e });
|
|
215
|
-
return rr.lines.map((l) => {
|
|
216
|
-
const idx = l.indexOf("|");
|
|
217
|
-
return idx >= 0 ? l.slice(idx + 1) : l;
|
|
218
|
-
});
|
|
219
|
-
} catch (err) {
|
|
220
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
221
|
-
fileReadErrors.push({ path: p, error: errorMsg });
|
|
222
|
-
console.error(`[warp_grep] Failed to read file: ${p} - ${errorMsg}`);
|
|
223
|
-
return [`[couldn't find: ${p}]`];
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
);
|
|
227
|
-
timings.finish_resolution_ms = Date.now() - finishResolutionStart;
|
|
228
|
-
if (fileReadErrors.length > 0) {
|
|
229
|
-
errors.push(...fileReadErrors.map((e) => ({ message: `File read error: ${e.path} - ${e.error}` })));
|
|
230
|
-
}
|
|
231
|
-
timings.total_ms = Date.now() - totalStart;
|
|
232
|
-
return {
|
|
233
|
-
terminationReason: "completed",
|
|
234
|
-
messages,
|
|
235
|
-
finish: { payload, metadata: finishMeta, resolved },
|
|
236
|
-
timings
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
async function* runWarpGrepStreaming(config) {
|
|
240
|
-
const totalStart = Date.now();
|
|
241
|
-
const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
|
|
242
|
-
const timings = { turns: [], timeout_ms: timeoutMs };
|
|
243
|
-
const repoRoot = path.resolve(config.repoRoot || process.cwd());
|
|
244
|
-
const model = config.model || DEFAULT_MODEL;
|
|
245
|
-
const messages = [];
|
|
246
|
-
const maxTurns = AGENT_CONFIG.MAX_TURNS;
|
|
247
|
-
const initialStateStart = Date.now();
|
|
248
|
-
const initialState = await buildInitialState(repoRoot, config.searchTerm, config.provider, { search_type: config.search_type });
|
|
249
|
-
timings.initial_state_ms = Date.now() - initialStateStart;
|
|
250
|
-
messages.push({ role: "user", content: initialState });
|
|
251
|
-
const provider = config.provider;
|
|
252
|
-
const errors = [];
|
|
253
|
-
let finishMeta;
|
|
254
|
-
let terminationReason = "terminated";
|
|
255
|
-
for (let turn = 1; turn <= maxTurns; turn += 1) {
|
|
256
|
-
const turnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };
|
|
257
|
-
enforceContextLimit(messages);
|
|
258
|
-
const modelCallStart = Date.now();
|
|
259
|
-
const assistantContent = await callModel(messages, model, {
|
|
260
|
-
morphApiKey: config.morphApiKey,
|
|
261
|
-
morphApiUrl: config.morphApiUrl,
|
|
262
|
-
retryConfig: config.retryConfig,
|
|
263
|
-
timeout: timeoutMs,
|
|
264
|
-
search_type: config.search_type
|
|
265
|
-
}).catch((e) => {
|
|
266
|
-
const errMsg = e instanceof Error ? e.message : String(e);
|
|
267
|
-
console.error(`[warp_grep:stream] Morph API call failed on turn ${turn}:`, errMsg);
|
|
268
|
-
errors.push({ message: errMsg });
|
|
269
|
-
return "";
|
|
270
|
-
});
|
|
271
|
-
turnMetrics.morph_api_ms = Date.now() - modelCallStart;
|
|
272
|
-
if (!assistantContent) {
|
|
273
|
-
console.error(`[warp_grep:stream] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);
|
|
274
|
-
timings.turns.push(turnMetrics);
|
|
275
|
-
break;
|
|
276
|
-
}
|
|
277
|
-
messages.push({ role: "assistant", content: assistantContent });
|
|
278
|
-
const toolCalls = parser.parse(assistantContent);
|
|
279
|
-
if (toolCalls.length === 0) {
|
|
280
|
-
console.error(`[warp_grep:stream] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));
|
|
281
|
-
errors.push({ message: "No tool calls produced by the model. Your MCP is likely out of date! Update it by running: rm -rf ~/.npm/_npx && npm cache clean --force && npx -y @morphllm/morphmcp@latest" });
|
|
282
|
-
terminationReason = "terminated";
|
|
283
|
-
timings.turns.push(turnMetrics);
|
|
284
|
-
break;
|
|
285
|
-
}
|
|
286
|
-
yield {
|
|
287
|
-
turn,
|
|
288
|
-
toolCalls: toolCalls.map((c) => ({
|
|
289
|
-
name: c.name,
|
|
290
|
-
arguments: c.arguments ?? {}
|
|
291
|
-
}))
|
|
292
|
-
};
|
|
293
|
-
const finishCalls = toolCalls.filter((c) => c.name === "finish");
|
|
294
|
-
const grepCalls = toolCalls.filter((c) => c.name === "grep");
|
|
295
|
-
const listDirCalls = toolCalls.filter((c) => c.name === "list_directory");
|
|
296
|
-
const readCalls = toolCalls.filter((c) => c.name === "read");
|
|
297
|
-
const skipCalls = toolCalls.filter((c) => c.name === "_skip");
|
|
298
|
-
const formatted = [];
|
|
299
|
-
for (const c of skipCalls) {
|
|
300
|
-
const msg = c.arguments?.message || "Command skipped due to parsing error";
|
|
301
|
-
formatted.push(msg);
|
|
302
|
-
}
|
|
303
|
-
const allPromises = [];
|
|
304
|
-
for (const c of grepCalls) {
|
|
305
|
-
const args = c.arguments ?? {};
|
|
306
|
-
allPromises.push(
|
|
307
|
-
toolGrep(provider, args).then(
|
|
308
|
-
({ output }) => formatAgentToolOutput("grep", args, output),
|
|
309
|
-
(err) => formatAgentToolOutput("grep", args, String(err), { isError: true })
|
|
310
|
-
)
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
for (const c of listDirCalls) {
|
|
314
|
-
const args = c.arguments ?? {};
|
|
315
|
-
allPromises.push(
|
|
316
|
-
toolListDirectory(provider, args).then(
|
|
317
|
-
(p) => formatAgentToolOutput("list_directory", args, p),
|
|
318
|
-
(err) => formatAgentToolOutput("list_directory", args, String(err), { isError: true })
|
|
319
|
-
)
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
for (const c of readCalls) {
|
|
323
|
-
const args = c.arguments ?? {};
|
|
324
|
-
allPromises.push(
|
|
325
|
-
toolRead(provider, args).then(
|
|
326
|
-
(p) => formatAgentToolOutput("read", args, p),
|
|
327
|
-
(err) => formatAgentToolOutput("read", args, String(err), { isError: true })
|
|
328
|
-
)
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
const toolExecStart = Date.now();
|
|
332
|
-
const allResults = await Promise.all(allPromises);
|
|
333
|
-
turnMetrics.local_tools_ms = Date.now() - toolExecStart;
|
|
334
|
-
for (const result of allResults) {
|
|
335
|
-
formatted.push(result);
|
|
336
|
-
}
|
|
337
|
-
if (formatted.length > 0) {
|
|
338
|
-
const turnMessage = formatTurnMessage(turn, maxTurns);
|
|
339
|
-
const contextBudget = calculateContextBudget(messages);
|
|
340
|
-
messages.push({ role: "user", content: formatted.join("\n") + turnMessage + "\n" + contextBudget });
|
|
341
|
-
}
|
|
342
|
-
timings.turns.push(turnMetrics);
|
|
343
|
-
if (finishCalls.length) {
|
|
344
|
-
const fc = finishCalls[0];
|
|
345
|
-
const files = fc.arguments?.files ?? [];
|
|
346
|
-
const textResult = fc.arguments?.textResult;
|
|
347
|
-
finishMeta = { files };
|
|
348
|
-
terminationReason = "completed";
|
|
349
|
-
if (files.length === 0) {
|
|
350
|
-
const payload2 = textResult || "No relevant code found.";
|
|
351
|
-
timings.total_ms = Date.now() - totalStart;
|
|
352
|
-
return {
|
|
353
|
-
terminationReason: "completed",
|
|
354
|
-
messages,
|
|
355
|
-
finish: { payload: payload2, metadata: finishMeta },
|
|
356
|
-
timings
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
break;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
if (terminationReason !== "completed" || !finishMeta) {
|
|
363
|
-
timings.total_ms = Date.now() - totalStart;
|
|
364
|
-
return { terminationReason, messages, errors, timings };
|
|
365
|
-
}
|
|
366
|
-
const parts = ["Relevant context found:"];
|
|
367
|
-
for (const f of finishMeta.files) {
|
|
368
|
-
const ranges = f.lines === "*" ? "*" : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(", ") : "*";
|
|
369
|
-
parts.push(`- ${f.path}: ${ranges}`);
|
|
370
|
-
}
|
|
371
|
-
const payload = parts.join("\n");
|
|
372
|
-
const finishResolutionStart = Date.now();
|
|
373
|
-
const fileReadErrors = [];
|
|
374
|
-
const resolved = await readFinishFiles(
|
|
375
|
-
repoRoot,
|
|
376
|
-
finishMeta.files,
|
|
377
|
-
async (p, s, e) => {
|
|
378
|
-
try {
|
|
379
|
-
const rr = await provider.read({ path: p, start: s, end: e });
|
|
380
|
-
return rr.lines.map((l) => {
|
|
381
|
-
const idx = l.indexOf("|");
|
|
382
|
-
return idx >= 0 ? l.slice(idx + 1) : l;
|
|
383
|
-
});
|
|
384
|
-
} catch (err) {
|
|
385
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
386
|
-
fileReadErrors.push({ path: p, error: errorMsg });
|
|
387
|
-
console.error(`[warp_grep] Failed to read file: ${p} - ${errorMsg}`);
|
|
388
|
-
return [`[couldn't find: ${p}]`];
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
);
|
|
392
|
-
timings.finish_resolution_ms = Date.now() - finishResolutionStart;
|
|
393
|
-
if (fileReadErrors.length > 0) {
|
|
394
|
-
errors.push(...fileReadErrors.map((e) => ({ message: `File read error: ${e.path} - ${e.error}` })));
|
|
395
|
-
}
|
|
396
|
-
timings.total_ms = Date.now() - totalStart;
|
|
397
|
-
return {
|
|
398
|
-
terminationReason: "completed",
|
|
399
|
-
messages,
|
|
400
|
-
finish: { payload, metadata: finishMeta, resolved },
|
|
401
|
-
timings
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
export {
|
|
406
|
-
runWarpGrep,
|
|
407
|
-
runWarpGrepStreaming
|
|
408
|
-
};
|
|
409
|
-
//# sourceMappingURL=chunk-SSQYLUKI.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../tools/warp_grep/agent/runner.ts"],"sourcesContent":["import { AGENT_CONFIG, DEFAULT_MODEL } from './config.js';\nimport type { AgentRunResult, ChatMessage, SessionConfig, AgentFinish, WarpGrepExecutionMetrics, WarpGrepTurnMetrics, WarpGrepStep } from './types.js';\nimport { LLMResponseParser } from './parser.js';\nimport type { WarpGrepProvider } from '../providers/types.js';\nimport { toolGrep } from './tools/grep.js';\nimport { toolRead } from './tools/read.js';\nimport { toolListDirectory } from './tools/list_directory.js';\nimport { readFinishFiles } from './tools/finish.js';\nimport type { RetryConfig } from '../../utils/resilience.js';\nimport { formatAgentToolOutput } from './formatter.js';\nimport { formatTurnMessage, calculateContextBudget, buildInitialState, enforceContextLimit } from './helpers.js';\nimport OpenAI from 'openai';\nimport { SDK_VERSION } from '../../../version.js';\nimport path from 'path';\n\ntype EventName =\n | 'initial_state'\n | 'round_start'\n | 'round_end'\n | 'finish'\n | 'error';\n\nexport type EventCallback = (name: EventName, payload: Record<string, unknown>) => void;\n\nconst parser = new LLMResponseParser();\n\nconst DEFAULT_API_URL = 'https://api.morphllm.com';\n\ninterface CallModelOptions {\n morphApiKey?: string;\n morphApiUrl?: string;\n retryConfig?: RetryConfig;\n timeout?: number;\n search_type?: string;\n}\n\nasync function callModel(\n messages: ChatMessage[],\n model: string,\n options: CallModelOptions = {}\n): Promise<string> {\n const baseUrl = options.morphApiUrl || DEFAULT_API_URL;\n const apiKey = options.morphApiKey || process.env.MORPH_API_KEY || '';\n const timeoutMs = options.timeout ?? AGENT_CONFIG.TIMEOUT_MS;\n\n // If the URL has a custom path (e.g. /api/gateway), use it as-is as the\n // OpenAI-compatible baseURL. Otherwise append /v1 for the standard Morph API.\n const parsedUrl = new URL(baseUrl);\n const baseURL = parsedUrl.pathname === '/' ? `${baseUrl}/v1` : baseUrl;\n\n const client = new OpenAI({\n apiKey,\n baseURL,\n maxRetries: options.retryConfig?.maxRetries,\n timeout: timeoutMs,\n defaultHeaders: { 'X-Morph-SDK-Version': SDK_VERSION },\n });\n\n const MAX_EMPTY_RETRIES = 1;\n\n for (let attempt = 0; attempt <= MAX_EMPTY_RETRIES; attempt++) {\n let data;\n try {\n data = await client.chat.completions.create({\n model,\n temperature: 0.0,\n max_tokens: 1024,\n messages,\n ...(options.search_type ? { search_type: options.search_type } as Record<string, unknown> : {}),\n });\n } catch (error) {\n if (error instanceof OpenAI.APIError && error.status === 404) {\n const defaultMsg =\n 'The endpoint you are trying to call is likely deprecated. Please update with: npm cache clean --force && npx -y @morphllm/morphmcp@latest or visit: https://morphllm.com/mcp';\n const errorText = error.message?.trim();\n throw new Error(errorText || defaultMsg);\n }\n throw error;\n }\n\n const choice = data?.choices?.[0];\n const content = choice?.message?.content;\n\n if (content && typeof content === 'string') {\n return content;\n }\n\n // Last attempt — throw with diagnostics\n if (attempt === MAX_EMPTY_RETRIES) {\n const finishReason = choice?.finish_reason ?? 'unknown';\n const hasToolCalls = Array.isArray(choice?.message?.tool_calls) && choice.message.tool_calls.length > 0;\n const choicesLen = data?.choices?.length ?? 0;\n const contentType = content === null ? 'null' : content === undefined ? 'undefined' : typeof content;\n\n throw new Error(\n `Invalid response from model: content=${contentType}, finish_reason=${finishReason}, ` +\n `has_tool_calls=${hasToolCalls}, choices_length=${choicesLen}`\n );\n }\n\n // Retry — brief pause before next attempt\n await new Promise(resolve => setTimeout(resolve, 200));\n }\n\n // Unreachable, but satisfies TypeScript\n throw new Error('Invalid response from model');\n}\n\nexport async function runWarpGrep(config: SessionConfig & { provider: WarpGrepProvider }): Promise<AgentRunResult> {\n const totalStart = Date.now();\n const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;\n const timings: Partial<WarpGrepExecutionMetrics> = { turns: [], timeout_ms: timeoutMs };\n\n const repoRoot = path.resolve(config.repoRoot || process.cwd());\n const model = config.model || DEFAULT_MODEL;\n const messages: ChatMessage[] = [];\n\n const maxTurns = AGENT_CONFIG.MAX_TURNS;\n\n const initialStateStart = Date.now();\n const initialState = await buildInitialState(repoRoot, config.searchTerm, config.provider, { search_type: config.search_type });\n timings.initial_state_ms = Date.now() - initialStateStart;\n\n messages.push({ role: 'user', content: initialState });\n\n const provider = config.provider;\n const errors: Array<{ message: string }> = [];\n\n let finishMeta: AgentFinish | undefined;\n let terminationReason: AgentRunResult['terminationReason'] = 'terminated';\n\n for (let turn = 1; turn <= maxTurns; turn += 1) {\n const turnMetrics: WarpGrepTurnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };\n\n // Enforce hard context limit before calling model\n enforceContextLimit(messages);\n\n // call model\n const modelCallStart = Date.now();\n const assistantContent = await callModel(messages, model, {\n morphApiKey: config.morphApiKey,\n morphApiUrl: config.morphApiUrl,\n retryConfig: config.retryConfig,\n timeout: timeoutMs,\n search_type: config.search_type,\n }).catch((e: unknown) => {\n const errMsg = e instanceof Error ? e.message : String(e);\n console.error(`[warp_grep] Morph API call failed on turn ${turn}:`, errMsg);\n errors.push({ message: errMsg });\n return '';\n });\n turnMetrics.morph_api_ms = Date.now() - modelCallStart;\n\n if (!assistantContent) {\n console.error(`[warp_grep] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);\n timings.turns!.push(turnMetrics);\n break;\n }\n messages.push({ role: 'assistant', content: assistantContent });\n\n // parse tool calls\n const toolCalls = parser.parse(assistantContent);\n if (toolCalls.length === 0) {\n console.error(`[warp_grep] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));\n errors.push({ message: 'No tool calls produced by the model. Your MCP is likely out of date! Update it by running: rm -rf ~/.npm/_npx && npm cache clean --force && npx -y @morphllm/morphmcp@latest' });\n terminationReason = 'terminated';\n timings.turns!.push(turnMetrics);\n break;\n }\n\n const finishCalls = toolCalls.filter(c => c.name === 'finish');\n const grepCalls = toolCalls.filter(c => c.name === 'grep');\n const listDirCalls = toolCalls.filter(c => c.name === 'list_directory');\n const readCalls = toolCalls.filter(c => c.name === 'read');\n const skipCalls = toolCalls.filter(c => c.name === '_skip');\n\n const formatted: string[] = [];\n\n // Surface any skipped commands as feedback to the LLM\n for (const c of skipCalls) {\n const msg = (c.arguments as { message?: string })?.message || 'Command skipped due to parsing error';\n formatted.push(msg);\n }\n\n const allPromises: Array<Promise<string>> = [];\n\n for (const c of grepCalls) {\n const args = (c.arguments ?? {}) as { pattern: string; path: string; glob?: string; context_lines?: number; case_sensitive?: boolean };\n allPromises.push(\n toolGrep(provider, args).then(\n ({ output }) => formatAgentToolOutput('grep', args, output),\n err => formatAgentToolOutput('grep', args, String(err), { isError: true })\n )\n );\n }\n\n for (const c of listDirCalls) {\n const args = (c.arguments ?? {}) as { path: string; pattern?: string | null };\n allPromises.push(\n toolListDirectory(provider, args).then(\n p => formatAgentToolOutput('list_directory', args, p),\n err => formatAgentToolOutput('list_directory', args, String(err), { isError: true })\n )\n );\n }\n\n for (const c of readCalls) {\n const args = (c.arguments ?? {}) as { path: string; start?: number; end?: number; lines?: Array<[number, number]> };\n allPromises.push(\n toolRead(provider, args).then(\n p => formatAgentToolOutput('read', args, p),\n err => formatAgentToolOutput('read', args, String(err), { isError: true })\n )\n );\n }\n\n const toolExecStart = Date.now();\n const allResults = await Promise.all(allPromises);\n turnMetrics.local_tools_ms = Date.now() - toolExecStart;\n\n for (const result of allResults) {\n formatted.push(result);\n }\n\n if (formatted.length > 0) {\n const turnMessage = formatTurnMessage(turn, maxTurns);\n const contextBudget = calculateContextBudget(messages);\n messages.push({ role: 'user', content: formatted.join('\\n') + turnMessage + '\\n' + contextBudget });\n }\n\n timings.turns!.push(turnMetrics);\n\n if (finishCalls.length) {\n const fc = finishCalls[0];\n const files = ((fc.arguments as any)?.files ?? []) as AgentFinish['files'];\n const textResult = (fc.arguments as any)?.textResult as string | undefined;\n finishMeta = { files };\n terminationReason = 'completed';\n\n // Text-only finish: model returned a text response instead of file references\n if (files.length === 0) {\n const payload = textResult || 'No relevant code found.';\n timings.turns!.push(turnMetrics);\n timings.total_ms = Date.now() - totalStart;\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta },\n timings: timings as WarpGrepExecutionMetrics,\n };\n }\n\n break;\n }\n }\n\n if (terminationReason !== 'completed' || !finishMeta) {\n timings.total_ms = Date.now() - totalStart;\n return { terminationReason, messages, errors, timings: timings as WarpGrepExecutionMetrics };\n }\n\n // Build finish payload\n const parts: string[] = ['Relevant context found:'];\n for (const f of finishMeta.files) {\n const ranges = f.lines === '*' ? '*'\n : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(', ')\n : '*';\n parts.push(`- ${f.path}: ${ranges}`);\n }\n const payload = parts.join('\\n');\n\n // Resolve file contents for returned ranges\n const finishResolutionStart = Date.now();\n const fileReadErrors: Array<{ path: string; error: string }> = [];\n const resolved = await readFinishFiles(\n repoRoot,\n finishMeta.files,\n async (p: string, s?: number, e?: number) => {\n try {\n const rr = await provider.read({ path: p, start: s, end: e });\n return rr.lines.map(l => {\n const idx = l.indexOf('|');\n return idx >= 0 ? l.slice(idx + 1) : l;\n });\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n fileReadErrors.push({ path: p, error: errorMsg });\n console.error(`[warp_grep] Failed to read file: ${p} - ${errorMsg}`);\n return [`[couldn't find: ${p}]`];\n }\n }\n );\n\n timings.finish_resolution_ms = Date.now() - finishResolutionStart;\n\n if (fileReadErrors.length > 0) {\n errors.push(...fileReadErrors.map(e => ({ message: `File read error: ${e.path} - ${e.error}` })));\n }\n\n timings.total_ms = Date.now() - totalStart;\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta, resolved },\n timings: timings as WarpGrepExecutionMetrics,\n };\n}\n\n/**\n * Streaming version of runWarpGrep that yields step information after each turn.\n * Yields WarpGrepStep with tool calls for each turn, then returns the final AgentRunResult.\n */\nexport async function* runWarpGrepStreaming(\n config: SessionConfig & { provider: WarpGrepProvider }\n): AsyncGenerator<WarpGrepStep, AgentRunResult, undefined> {\n const totalStart = Date.now();\n const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;\n const timings: Partial<WarpGrepExecutionMetrics> = { turns: [], timeout_ms: timeoutMs };\n\n const repoRoot = path.resolve(config.repoRoot || process.cwd());\n const model = config.model || DEFAULT_MODEL;\n const messages: ChatMessage[] = [];\n\n const maxTurns = AGENT_CONFIG.MAX_TURNS;\n\n const initialStateStart = Date.now();\n const initialState = await buildInitialState(repoRoot, config.searchTerm, config.provider, { search_type: config.search_type });\n timings.initial_state_ms = Date.now() - initialStateStart;\n\n messages.push({ role: 'user', content: initialState });\n\n const provider = config.provider;\n const errors: Array<{ message: string }> = [];\n\n let finishMeta: AgentFinish | undefined;\n let terminationReason: AgentRunResult['terminationReason'] = 'terminated';\n\n for (let turn = 1; turn <= maxTurns; turn += 1) {\n const turnMetrics: WarpGrepTurnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };\n\n // Enforce hard context limit before calling model\n enforceContextLimit(messages);\n\n // call model\n const modelCallStart = Date.now();\n const assistantContent = await callModel(messages, model, {\n morphApiKey: config.morphApiKey,\n morphApiUrl: config.morphApiUrl,\n retryConfig: config.retryConfig,\n timeout: timeoutMs,\n search_type: config.search_type,\n }).catch((e: unknown) => {\n const errMsg = e instanceof Error ? e.message : String(e);\n console.error(`[warp_grep:stream] Morph API call failed on turn ${turn}:`, errMsg);\n errors.push({ message: errMsg });\n return '';\n });\n turnMetrics.morph_api_ms = Date.now() - modelCallStart;\n\n if (!assistantContent) {\n console.error(`[warp_grep:stream] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);\n timings.turns!.push(turnMetrics);\n break;\n }\n messages.push({ role: 'assistant', content: assistantContent });\n\n // parse tool calls\n const toolCalls = parser.parse(assistantContent);\n if (toolCalls.length === 0) {\n console.error(`[warp_grep:stream] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));\n errors.push({ message: 'No tool calls produced by the model. Your MCP is likely out of date! Update it by running: rm -rf ~/.npm/_npx && npm cache clean --force && npx -y @morphllm/morphmcp@latest' });\n terminationReason = 'terminated';\n timings.turns!.push(turnMetrics);\n break;\n }\n\n // Yield step with tool calls (before execution)\n yield {\n turn,\n toolCalls: toolCalls.map(c => ({\n name: c.name,\n arguments: c.arguments ?? {}\n }))\n };\n\n const finishCalls = toolCalls.filter(c => c.name === 'finish');\n const grepCalls = toolCalls.filter(c => c.name === 'grep');\n const listDirCalls = toolCalls.filter(c => c.name === 'list_directory');\n const readCalls = toolCalls.filter(c => c.name === 'read');\n const skipCalls = toolCalls.filter(c => c.name === '_skip');\n\n const formatted: string[] = [];\n\n // Surface any skipped commands as feedback to the LLM\n for (const c of skipCalls) {\n const msg = (c.arguments as { message?: string })?.message || 'Command skipped due to parsing error';\n formatted.push(msg);\n }\n\n const allPromises: Array<Promise<string>> = [];\n\n for (const c of grepCalls) {\n const args = (c.arguments ?? {}) as { pattern: string; path: string; glob?: string; context_lines?: number; case_sensitive?: boolean };\n allPromises.push(\n toolGrep(provider, args).then(\n ({ output }) => formatAgentToolOutput('grep', args, output),\n err => formatAgentToolOutput('grep', args, String(err), { isError: true })\n )\n );\n }\n\n for (const c of listDirCalls) {\n const args = (c.arguments ?? {}) as { path: string; pattern?: string | null };\n allPromises.push(\n toolListDirectory(provider, args).then(\n p => formatAgentToolOutput('list_directory', args, p),\n err => formatAgentToolOutput('list_directory', args, String(err), { isError: true })\n )\n );\n }\n\n for (const c of readCalls) {\n const args = (c.arguments ?? {}) as { path: string; start?: number; end?: number; lines?: Array<[number, number]> };\n allPromises.push(\n toolRead(provider, args).then(\n p => formatAgentToolOutput('read', args, p),\n err => formatAgentToolOutput('read', args, String(err), { isError: true })\n )\n );\n }\n\n const toolExecStart = Date.now();\n const allResults = await Promise.all(allPromises);\n turnMetrics.local_tools_ms = Date.now() - toolExecStart;\n\n for (const result of allResults) {\n formatted.push(result);\n }\n\n if (formatted.length > 0) {\n const turnMessage = formatTurnMessage(turn, maxTurns);\n const contextBudget = calculateContextBudget(messages);\n messages.push({ role: 'user', content: formatted.join('\\n') + turnMessage + '\\n' + contextBudget });\n }\n\n timings.turns!.push(turnMetrics);\n\n if (finishCalls.length) {\n const fc = finishCalls[0];\n const files = ((fc.arguments as any)?.files ?? []) as AgentFinish['files'];\n const textResult = (fc.arguments as any)?.textResult as string | undefined;\n finishMeta = { files };\n terminationReason = 'completed';\n\n // Text-only finish\n if (files.length === 0) {\n const payload = textResult || 'No relevant code found.';\n timings.total_ms = Date.now() - totalStart;\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta },\n timings: timings as WarpGrepExecutionMetrics,\n };\n }\n\n break;\n }\n }\n\n if (terminationReason !== 'completed' || !finishMeta) {\n timings.total_ms = Date.now() - totalStart;\n return { terminationReason, messages, errors, timings: timings as WarpGrepExecutionMetrics };\n }\n\n // Build finish payload\n const parts: string[] = ['Relevant context found:'];\n for (const f of finishMeta.files) {\n const ranges = f.lines === '*' ? '*'\n : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(', ')\n : '*';\n parts.push(`- ${f.path}: ${ranges}`);\n }\n const payload = parts.join('\\n');\n\n // Resolve file contents for returned ranges\n const finishResolutionStart = Date.now();\n const fileReadErrors: Array<{ path: string; error: string }> = [];\n const resolved = await readFinishFiles(\n repoRoot,\n finishMeta.files,\n async (p: string, s?: number, e?: number) => {\n try {\n const rr = await provider.read({ path: p, start: s, end: e });\n return rr.lines.map(l => {\n const idx = l.indexOf('|');\n return idx >= 0 ? l.slice(idx + 1) : l;\n });\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n fileReadErrors.push({ path: p, error: errorMsg });\n console.error(`[warp_grep] Failed to read file: ${p} - ${errorMsg}`);\n return [`[couldn't find: ${p}]`];\n }\n }\n );\n\n timings.finish_resolution_ms = Date.now() - finishResolutionStart;\n\n if (fileReadErrors.length > 0) {\n errors.push(...fileReadErrors.map(e => ({ message: `File read error: ${e.path} - ${e.error}` })));\n }\n\n timings.total_ms = Date.now() - totalStart;\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta, resolved },\n timings: timings as WarpGrepExecutionMetrics,\n };\n}\n"],"mappings":"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","names":["payload"]}
|
package/dist/chunk-VCKJ22DX.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
// tools/warp_grep/agent/parser.ts
|
|
2
|
-
var VALID_COMMANDS = ["list_directory", "ripgrep", "read", "finish"];
|
|
3
|
-
function isValidCommand(name) {
|
|
4
|
-
return VALID_COMMANDS.includes(name);
|
|
5
|
-
}
|
|
6
|
-
function parseQwen3ToolCalls(text) {
|
|
7
|
-
const tools = [];
|
|
8
|
-
const toolCallRegex = /<tool_call>\s*<function=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/function>\s*<\/tool_call>/gi;
|
|
9
|
-
let match;
|
|
10
|
-
while ((match = toolCallRegex.exec(text)) !== null) {
|
|
11
|
-
const funcName = match[1].toLowerCase();
|
|
12
|
-
const body = match[2];
|
|
13
|
-
if (!isValidCommand(funcName)) continue;
|
|
14
|
-
const params = {};
|
|
15
|
-
const paramRegex = /<parameter=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/parameter>/gi;
|
|
16
|
-
let paramMatch;
|
|
17
|
-
while ((paramMatch = paramRegex.exec(body)) !== null) {
|
|
18
|
-
params[paramMatch[1].toLowerCase()] = paramMatch[2].trim();
|
|
19
|
-
}
|
|
20
|
-
if (funcName === "ripgrep") {
|
|
21
|
-
const pattern = params.pattern;
|
|
22
|
-
if (!pattern) continue;
|
|
23
|
-
const args = {
|
|
24
|
-
pattern,
|
|
25
|
-
path: params.path || ".",
|
|
26
|
-
...params.glob && { glob: params.glob },
|
|
27
|
-
...params.context_lines && { context_lines: parseInt(params.context_lines, 10) },
|
|
28
|
-
...params.case_sensitive && { case_sensitive: params.case_sensitive === "true" }
|
|
29
|
-
};
|
|
30
|
-
tools.push({ name: "grep", arguments: args });
|
|
31
|
-
} else if (funcName === "list_directory") {
|
|
32
|
-
const command = params.command;
|
|
33
|
-
const directPath = params.path;
|
|
34
|
-
let dirPath = directPath || ".";
|
|
35
|
-
if (!directPath && command) {
|
|
36
|
-
const tokens = command.trim().split(/\s+/);
|
|
37
|
-
const pathTokens = tokens.slice(1).filter((t) => !t.startsWith("-") && !t.startsWith("|") && !t.startsWith("\\("));
|
|
38
|
-
if (pathTokens.length > 0) {
|
|
39
|
-
dirPath = pathTokens[0];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
tools.push({ name: "list_directory", arguments: { path: dirPath, pattern: params.pattern || null } });
|
|
43
|
-
} else if (funcName === "read") {
|
|
44
|
-
const filePath = params.path;
|
|
45
|
-
if (!filePath) continue;
|
|
46
|
-
const args = { path: filePath };
|
|
47
|
-
const linesStr = params.lines;
|
|
48
|
-
if (linesStr) {
|
|
49
|
-
const ranges = [];
|
|
50
|
-
for (const rangeStr of linesStr.split(",")) {
|
|
51
|
-
const trimmed = rangeStr.trim();
|
|
52
|
-
if (!trimmed) continue;
|
|
53
|
-
const [s, e] = trimmed.split("-").map((v) => parseInt(v.trim(), 10));
|
|
54
|
-
if (Number.isFinite(s) && Number.isFinite(e)) {
|
|
55
|
-
ranges.push([s, e]);
|
|
56
|
-
} else if (Number.isFinite(s)) {
|
|
57
|
-
ranges.push([s, s]);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (ranges.length === 1) {
|
|
61
|
-
args.start = ranges[0][0];
|
|
62
|
-
args.end = ranges[0][1];
|
|
63
|
-
} else if (ranges.length > 1) {
|
|
64
|
-
args.lines = ranges;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
tools.push({ name: "read", arguments: args });
|
|
68
|
-
} else if (funcName === "finish") {
|
|
69
|
-
if (params.result && !params.files) {
|
|
70
|
-
tools.push({ name: "finish", arguments: { files: [], textResult: params.result } });
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
const filesStr = params.files;
|
|
74
|
-
if (!filesStr) {
|
|
75
|
-
tools.push({ name: "finish", arguments: { files: [], textResult: "No relevant code found." } });
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
const files = [];
|
|
79
|
-
for (const line of filesStr.split("\n")) {
|
|
80
|
-
const trimmed = line.trim();
|
|
81
|
-
if (!trimmed) continue;
|
|
82
|
-
const colonIdx = trimmed.indexOf(":");
|
|
83
|
-
if (colonIdx === -1) {
|
|
84
|
-
files.push({ path: trimmed, lines: "*" });
|
|
85
|
-
} else {
|
|
86
|
-
const filePath = trimmed.slice(0, colonIdx);
|
|
87
|
-
const rangesPart = trimmed.slice(colonIdx + 1);
|
|
88
|
-
const ranges = [];
|
|
89
|
-
for (const rangeStr of rangesPart.split(",")) {
|
|
90
|
-
const rt = rangeStr.trim();
|
|
91
|
-
if (!rt || rt === "*") {
|
|
92
|
-
files.push({ path: filePath, lines: "*" });
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
const [s, e] = rt.split("-").map((v) => parseInt(v.trim(), 10));
|
|
96
|
-
if (Number.isFinite(s) && Number.isFinite(e)) {
|
|
97
|
-
ranges.push([s, e]);
|
|
98
|
-
} else if (Number.isFinite(s)) {
|
|
99
|
-
ranges.push([s, s]);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (ranges.length > 0) {
|
|
103
|
-
files.push({ path: filePath, lines: ranges });
|
|
104
|
-
} else if (!files.some((f) => f.path === filePath)) {
|
|
105
|
-
files.push({ path: filePath, lines: "*" });
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (files.length > 0) {
|
|
110
|
-
tools.push({ name: "finish", arguments: { files } });
|
|
111
|
-
} else {
|
|
112
|
-
tools.push({ name: "finish", arguments: { files: [], textResult: filesStr } });
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return tools;
|
|
117
|
-
}
|
|
118
|
-
var LLMResponseParser = class {
|
|
119
|
-
parse(text) {
|
|
120
|
-
if (typeof text !== "string") {
|
|
121
|
-
throw new TypeError("Command text must be a string.");
|
|
122
|
-
}
|
|
123
|
-
const withoutThink = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
|
|
124
|
-
return parseQwen3ToolCalls(withoutThink);
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
export {
|
|
129
|
-
LLMResponseParser
|
|
130
|
-
};
|
|
131
|
-
//# sourceMappingURL=chunk-VCKJ22DX.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../tools/warp_grep/agent/parser.ts"],"sourcesContent":["// Parses assistant lines into structured tool calls (Qwen3-Coder-Next format only)\nimport type { ToolCall } from './types.js';\n\nconst VALID_COMMANDS = ['list_directory', 'ripgrep', '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\n/**\n * Parse Qwen3-Coder-Next native XML tool call format:\n * <tool_call><function=NAME><parameter=KEY>VALUE</parameter></function></tool_call>\n */\nfunction parseQwen3ToolCalls(text: string): ToolCall[] {\n const tools: ToolCall[] = [];\n const toolCallRegex = /<tool_call>\\s*<function=([a-z_][a-z0-9_]*)>([\\s\\S]*?)<\\/function>\\s*<\\/tool_call>/gi;\n let match;\n\n while ((match = toolCallRegex.exec(text)) !== null) {\n const funcName = match[1].toLowerCase();\n const body = match[2];\n\n if (!isValidCommand(funcName)) continue;\n\n // Extract all <parameter=KEY>VALUE</parameter> pairs\n const params: Record<string, string> = {};\n const paramRegex = /<parameter=([a-z_][a-z0-9_]*)>([\\s\\S]*?)<\\/parameter>/gi;\n let paramMatch;\n while ((paramMatch = paramRegex.exec(body)) !== null) {\n params[paramMatch[1].toLowerCase()] = paramMatch[2].trim();\n }\n\n if (funcName === 'ripgrep') {\n const pattern = params.pattern;\n if (!pattern) continue;\n const args: Record<string, unknown> = {\n pattern,\n path: params.path || '.',\n ...(params.glob && { glob: params.glob }),\n ...(params.context_lines && { context_lines: parseInt(params.context_lines, 10) }),\n ...(params.case_sensitive && { case_sensitive: params.case_sensitive === 'true' }),\n };\n tools.push({ name: 'grep', arguments: args });\n } else if (funcName === 'list_directory') {\n // Extract path from command parameter (best effort: look for target directory)\n const command = params.command;\n const directPath = params.path;\n let dirPath = directPath || '.';\n if (!directPath && command) {\n // Try to extract a meaningful path from the command string\n // Common patterns: \"find <path> ...\", \"ls <path>\", \"ls -la <path>\"\n // Skip the command name and any flags (tokens starting with -, \\(, |)\n const tokens = command.trim().split(/\\s+/);\n const pathTokens = tokens.slice(1).filter(t => !t.startsWith('-') && !t.startsWith('|') && !t.startsWith('\\\\('));\n if (pathTokens.length > 0) {\n dirPath = pathTokens[0];\n }\n }\n tools.push({ name: 'list_directory', arguments: { path: dirPath, pattern: params.pattern || null } });\n } else if (funcName === 'read') {\n const filePath = params.path;\n if (!filePath) continue;\n const args: Record<string, unknown> = { path: filePath };\n const linesStr = params.lines;\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 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 } else if (funcName === 'finish') {\n // If the model used \"result\" parameter instead of \"files\", treat as text-only finish\n if (params.result && !params.files) {\n tools.push({ name: 'finish', arguments: { files: [], textResult: params.result } });\n continue;\n }\n const filesStr = params.files;\n if (!filesStr) {\n tools.push({ name: 'finish', arguments: { files: [], textResult: 'No relevant code found.' } });\n continue;\n }\n // Parse flat string format: \"path:start-end\\npath\" or \"path\\npath:start-end\"\n const files: Array<{ path: string; lines: '*' | Array<[number, number]> }> = [];\n for (const line of filesStr.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) {\n // No colon — whole file\n files.push({ path: trimmed, lines: '*' });\n } else {\n const filePath = trimmed.slice(0, colonIdx);\n const rangesPart = trimmed.slice(colonIdx + 1);\n const ranges: Array<[number, number]> = [];\n for (const rangeStr of rangesPart.split(',')) {\n const rt = rangeStr.trim();\n if (!rt || rt === '*') {\n // Whole file marker\n files.push({ path: filePath, lines: '*' });\n break;\n }\n const [s, e] = rt.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\n ranges.push([s, s]);\n }\n }\n if (ranges.length > 0) {\n files.push({ path: filePath, lines: ranges });\n } else if (!files.some(f => f.path === filePath)) {\n files.push({ path: filePath, lines: '*' });\n }\n }\n }\n if (files.length > 0) {\n tools.push({ name: 'finish', arguments: { files } });\n } else {\n tools.push({ name: 'finish', arguments: { files: [], textResult: filesStr } });\n }\n }\n }\n\n return tools;\n}\n\nexport class LLMResponseParser {\n parse(text: string): ToolCall[] {\n if (typeof text !== 'string') {\n throw new TypeError('Command text must be a string.');\n }\n\n // Strip <think> blocks\n const withoutThink = text.replace(/<think>[\\s\\S]*?<\\/think>/gi, '');\n\n // Parse Qwen3 <tool_call><function=...> format\n return parseQwen3ToolCalls(withoutThink);\n }\n}\n"],"mappings":"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","names":[]}
|