@morphllm/morphsdk 0.2.50 → 0.2.52
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-4MELBN55.js → chunk-FYQUSDOE.js} +4 -4
- package/dist/{chunk-Z2FBMSNE.js → chunk-HQO45BAJ.js} +5 -1
- package/dist/chunk-HQO45BAJ.js.map +1 -0
- package/dist/{chunk-NRWVMX4O.js → chunk-L5BMGLLQ.js} +29 -22
- package/dist/chunk-L5BMGLLQ.js.map +1 -0
- package/dist/{chunk-SWQPIKPY.js → chunk-LVPVVLTI.js} +70 -49
- package/dist/chunk-LVPVVLTI.js.map +1 -0
- package/dist/{chunk-2TXLSKGU.js → chunk-MZT6HVGD.js} +3 -3
- package/dist/{chunk-DZRBTNQR.js → chunk-PZDR5ZZ2.js} +5 -5
- package/dist/{chunk-KH3RKPPO.js → chunk-UU6XCZG3.js} +4 -4
- package/dist/{chunk-5ASRBH5I.js → chunk-YR53PPVM.js} +4 -4
- package/dist/{chunk-MLDK7SCW.js → chunk-ZJIIICRA.js} +29 -7
- package/dist/chunk-ZJIIICRA.js.map +1 -0
- package/dist/client.cjs +116 -68
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +13 -13
- package/dist/index.cjs +116 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -13
- package/dist/tools/warp_grep/agent/parser.cjs +69 -48
- package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/parser.d.ts +2 -0
- package/dist/tools/warp_grep/agent/parser.js +1 -1
- package/dist/tools/warp_grep/agent/runner.cjs +88 -62
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.js +7 -7
- package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/types.d.ts +1 -1
- package/dist/tools/warp_grep/anthropic.cjs +116 -68
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.js +10 -10
- package/dist/tools/warp_grep/index.cjs +116 -68
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.js +12 -12
- package/dist/tools/warp_grep/openai.cjs +116 -68
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.js +10 -10
- package/dist/tools/warp_grep/providers/local.cjs +28 -6
- package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/local.js +1 -1
- package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/types.d.ts +2 -0
- package/dist/tools/warp_grep/tools/grep.cjs +3 -0
- package/dist/tools/warp_grep/tools/grep.cjs.map +1 -1
- package/dist/tools/warp_grep/tools/grep.js +3 -0
- package/dist/tools/warp_grep/tools/grep.js.map +1 -1
- package/dist/tools/warp_grep/tools/read.cjs +4 -0
- package/dist/tools/warp_grep/tools/read.cjs.map +1 -1
- package/dist/tools/warp_grep/tools/read.js +1 -1
- package/dist/tools/warp_grep/vercel.cjs +116 -68
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.js +10 -10
- package/package.json +1 -1
- package/dist/chunk-MLDK7SCW.js.map +0 -1
- package/dist/chunk-NRWVMX4O.js.map +0 -1
- package/dist/chunk-SWQPIKPY.js.map +0 -1
- package/dist/chunk-Z2FBMSNE.js.map +0 -1
- /package/dist/{chunk-4MELBN55.js.map → chunk-FYQUSDOE.js.map} +0 -0
- /package/dist/{chunk-2TXLSKGU.js.map → chunk-MZT6HVGD.js.map} +0 -0
- /package/dist/{chunk-DZRBTNQR.js.map → chunk-PZDR5ZZ2.js.map} +0 -0
- /package/dist/{chunk-KH3RKPPO.js.map → chunk-UU6XCZG3.js.map} +0 -0
- /package/dist/{chunk-5ASRBH5I.js.map → chunk-YR53PPVM.js.map} +0 -0
|
@@ -258,12 +258,6 @@ function getSystemPrompt() {
|
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
// tools/warp_grep/agent/parser.ts
|
|
261
|
-
var LLMResponseParseError = class extends Error {
|
|
262
|
-
constructor(message) {
|
|
263
|
-
super(message);
|
|
264
|
-
this.name = "LLMResponseParseError";
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
261
|
var VALID_COMMANDS = ["analyse", "grep", "read", "finish"];
|
|
268
262
|
function preprocessText(text) {
|
|
269
263
|
let processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
|
|
@@ -314,24 +308,23 @@ var LLMResponseParser = class {
|
|
|
314
308
|
const lines = preprocessText(text);
|
|
315
309
|
const commands = [];
|
|
316
310
|
let finishAccumulator = null;
|
|
317
|
-
lines.forEach((line
|
|
311
|
+
lines.forEach((line) => {
|
|
318
312
|
if (!line || line.startsWith("#")) return;
|
|
319
|
-
const
|
|
320
|
-
const parts = this.splitLine(line, ctx);
|
|
313
|
+
const parts = this.splitLine(line);
|
|
321
314
|
if (parts.length === 0) return;
|
|
322
315
|
const cmd = parts[0];
|
|
323
316
|
switch (cmd) {
|
|
324
317
|
case "analyse":
|
|
325
|
-
this.handleAnalyse(parts,
|
|
318
|
+
this.handleAnalyse(parts, line, commands);
|
|
326
319
|
break;
|
|
327
320
|
case "grep":
|
|
328
|
-
this.handleGrep(parts,
|
|
321
|
+
this.handleGrep(parts, line, commands);
|
|
329
322
|
break;
|
|
330
323
|
case "read":
|
|
331
|
-
this.handleRead(parts,
|
|
324
|
+
this.handleRead(parts, line, commands);
|
|
332
325
|
break;
|
|
333
326
|
case "finish":
|
|
334
|
-
finishAccumulator = this.handleFinish(parts,
|
|
327
|
+
finishAccumulator = this.handleFinish(parts, line, commands, finishAccumulator);
|
|
335
328
|
break;
|
|
336
329
|
default:
|
|
337
330
|
break;
|
|
@@ -348,53 +341,68 @@ var LLMResponseParser = class {
|
|
|
348
341
|
}
|
|
349
342
|
return commands;
|
|
350
343
|
}
|
|
351
|
-
splitLine(line
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
current = "";
|
|
365
|
-
}
|
|
366
|
-
} else {
|
|
367
|
-
current += ch;
|
|
344
|
+
splitLine(line) {
|
|
345
|
+
const parts = [];
|
|
346
|
+
let current = "";
|
|
347
|
+
let inSingle = false;
|
|
348
|
+
for (let i = 0; i < line.length; i++) {
|
|
349
|
+
const ch = line[i];
|
|
350
|
+
if (ch === "'" && line[i - 1] !== "\\") {
|
|
351
|
+
inSingle = !inSingle;
|
|
352
|
+
current += ch;
|
|
353
|
+
} else if (!inSingle && /\s/.test(ch)) {
|
|
354
|
+
if (current) {
|
|
355
|
+
parts.push(current);
|
|
356
|
+
current = "";
|
|
368
357
|
}
|
|
358
|
+
} else {
|
|
359
|
+
current += ch;
|
|
369
360
|
}
|
|
370
|
-
if (current) parts.push(current);
|
|
371
|
-
return parts;
|
|
372
|
-
} catch {
|
|
373
|
-
throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);
|
|
374
361
|
}
|
|
362
|
+
if (current) parts.push(current);
|
|
363
|
+
return parts;
|
|
364
|
+
}
|
|
365
|
+
/** Helper to create a _skip tool call with an error message */
|
|
366
|
+
skip(message) {
|
|
367
|
+
return { name: "_skip", arguments: { message } };
|
|
375
368
|
}
|
|
376
|
-
handleAnalyse(parts,
|
|
369
|
+
handleAnalyse(parts, rawLine, commands) {
|
|
377
370
|
if (parts.length < 2) {
|
|
378
|
-
|
|
371
|
+
commands.push(this.skip(
|
|
372
|
+
`[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: analyse <path> [pattern]. Example: analyse src/`
|
|
373
|
+
));
|
|
374
|
+
return;
|
|
379
375
|
}
|
|
380
376
|
const path4 = parts[1];
|
|
381
377
|
const pattern = parts[2]?.replace(/^"|"$/g, "") ?? null;
|
|
382
378
|
commands.push({ name: "analyse", arguments: { path: path4, pattern } });
|
|
383
379
|
}
|
|
384
380
|
// no glob tool in MCP
|
|
385
|
-
handleGrep(parts,
|
|
381
|
+
handleGrep(parts, rawLine, commands) {
|
|
386
382
|
if (parts.length < 3) {
|
|
387
|
-
|
|
383
|
+
commands.push(this.skip(
|
|
384
|
+
`[SKIPPED] Your command "${rawLine}" is missing arguments. Correct format: grep '<pattern>' <path>. Example: grep 'TODO' src/`
|
|
385
|
+
));
|
|
386
|
+
return;
|
|
388
387
|
}
|
|
389
|
-
|
|
390
|
-
if (
|
|
391
|
-
|
|
388
|
+
let pat = parts[1];
|
|
389
|
+
if (pat.startsWith("'") && pat.endsWith("'")) {
|
|
390
|
+
pat = pat.slice(1, -1);
|
|
392
391
|
}
|
|
393
|
-
|
|
392
|
+
if (!pat) {
|
|
393
|
+
commands.push(this.skip(
|
|
394
|
+
`[SKIPPED] Your command "${rawLine}" has an empty pattern. Provide a non-empty search pattern. Example: grep 'function' src/`
|
|
395
|
+
));
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
commands.push({ name: "grep", arguments: { pattern: pat, path: parts[2] } });
|
|
394
399
|
}
|
|
395
|
-
handleRead(parts,
|
|
400
|
+
handleRead(parts, rawLine, commands) {
|
|
396
401
|
if (parts.length < 2) {
|
|
397
|
-
|
|
402
|
+
commands.push(this.skip(
|
|
403
|
+
`[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: read <path> or read <path>:<start>-<end>. Example: read src/index.ts:1-50`
|
|
404
|
+
));
|
|
405
|
+
return;
|
|
398
406
|
}
|
|
399
407
|
const spec = parts[1];
|
|
400
408
|
const rangeIdx = spec.indexOf(":");
|
|
@@ -402,31 +410,38 @@ var LLMResponseParser = class {
|
|
|
402
410
|
commands.push({ name: "read", arguments: { path: spec } });
|
|
403
411
|
return;
|
|
404
412
|
}
|
|
405
|
-
const
|
|
413
|
+
const filePath = spec.slice(0, rangeIdx);
|
|
406
414
|
const range = spec.slice(rangeIdx + 1);
|
|
407
415
|
const [s, e] = range.split("-").map((v) => parseInt(v, 10));
|
|
408
416
|
if (!Number.isFinite(s) || !Number.isFinite(e)) {
|
|
409
|
-
|
|
417
|
+
commands.push({ name: "read", arguments: { path: filePath } });
|
|
418
|
+
return;
|
|
410
419
|
}
|
|
411
|
-
commands.push({ name: "read", arguments: { path:
|
|
420
|
+
commands.push({ name: "read", arguments: { path: filePath, start: s, end: e } });
|
|
412
421
|
}
|
|
413
|
-
handleFinish(parts,
|
|
422
|
+
handleFinish(parts, rawLine, commands, acc) {
|
|
414
423
|
const map = acc ?? /* @__PURE__ */ new Map();
|
|
415
424
|
const args = parts.slice(1);
|
|
416
425
|
for (const token of args) {
|
|
417
|
-
const [
|
|
418
|
-
if (!
|
|
419
|
-
|
|
426
|
+
const [filePath, rangesText] = token.split(":", 2);
|
|
427
|
+
if (!filePath || !rangesText) {
|
|
428
|
+
commands.push(this.skip(
|
|
429
|
+
`[SKIPPED] Invalid finish token "${token}". Correct format: finish <path>:<start>-<end>. Example: finish src/index.ts:1-50`
|
|
430
|
+
));
|
|
431
|
+
continue;
|
|
420
432
|
}
|
|
421
433
|
const rangeSpecs = rangesText.split(",").filter(Boolean);
|
|
422
434
|
for (const spec of rangeSpecs) {
|
|
423
435
|
const [s, e] = spec.split("-").map((v) => parseInt(v, 10));
|
|
424
436
|
if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {
|
|
425
|
-
|
|
437
|
+
commands.push(this.skip(
|
|
438
|
+
`[SKIPPED] Invalid range "${spec}" in "${token}". Ranges must be <start>-<end> where start <= end. Example: 1-50`
|
|
439
|
+
));
|
|
440
|
+
continue;
|
|
426
441
|
}
|
|
427
|
-
const arr = map.get(
|
|
442
|
+
const arr = map.get(filePath) ?? [];
|
|
428
443
|
arr.push([s, e]);
|
|
429
|
-
map.set(
|
|
444
|
+
map.set(filePath, arr);
|
|
430
445
|
}
|
|
431
446
|
}
|
|
432
447
|
return map;
|
|
@@ -436,6 +451,10 @@ var LLMResponseParser = class {
|
|
|
436
451
|
// tools/warp_grep/tools/read.ts
|
|
437
452
|
async function toolRead(provider, args) {
|
|
438
453
|
const res = await provider.read({ path: args.path, start: args.start, end: args.end });
|
|
454
|
+
if (res.error) {
|
|
455
|
+
return res.error;
|
|
456
|
+
}
|
|
457
|
+
if (!res.lines.length) return "(empty file)";
|
|
439
458
|
return res.lines.join("\n");
|
|
440
459
|
}
|
|
441
460
|
|
|
@@ -821,14 +840,7 @@ async function runWarpGrep(config) {
|
|
|
821
840
|
});
|
|
822
841
|
if (!assistantContent) break;
|
|
823
842
|
messages.push({ role: "assistant", content: assistantContent });
|
|
824
|
-
|
|
825
|
-
try {
|
|
826
|
-
toolCalls = parser.parse(assistantContent);
|
|
827
|
-
} catch (e) {
|
|
828
|
-
errors.push({ message: e instanceof Error ? e.message : String(e) });
|
|
829
|
-
terminationReason = "terminated";
|
|
830
|
-
break;
|
|
831
|
-
}
|
|
843
|
+
const toolCalls = parser.parse(assistantContent);
|
|
832
844
|
if (toolCalls.length === 0) {
|
|
833
845
|
errors.push({ message: "No tool calls produced by the model." });
|
|
834
846
|
terminationReason = "terminated";
|
|
@@ -838,7 +850,12 @@ async function runWarpGrep(config) {
|
|
|
838
850
|
const grepCalls = toolCalls.filter((c) => c.name === "grep");
|
|
839
851
|
const analyseCalls = toolCalls.filter((c) => c.name === "analyse");
|
|
840
852
|
const readCalls = toolCalls.filter((c) => c.name === "read");
|
|
853
|
+
const skipCalls = toolCalls.filter((c) => c.name === "_skip");
|
|
841
854
|
const formatted = [];
|
|
855
|
+
for (const c of skipCalls) {
|
|
856
|
+
const msg = c.arguments?.message || "Command skipped due to parsing error";
|
|
857
|
+
formatted.push(msg);
|
|
858
|
+
}
|
|
842
859
|
const otherPromises = [];
|
|
843
860
|
for (const c of analyseCalls) {
|
|
844
861
|
const args = c.arguments ?? {};
|
|
@@ -864,6 +881,15 @@ async function runWarpGrep(config) {
|
|
|
864
881
|
const args = c.arguments ?? {};
|
|
865
882
|
try {
|
|
866
883
|
const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });
|
|
884
|
+
if (grepRes.error) {
|
|
885
|
+
errors.push({ message: grepRes.error });
|
|
886
|
+
terminationReason = "terminated";
|
|
887
|
+
return {
|
|
888
|
+
terminationReason: "terminated",
|
|
889
|
+
messages,
|
|
890
|
+
errors
|
|
891
|
+
};
|
|
892
|
+
}
|
|
867
893
|
const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join("\n") : "";
|
|
868
894
|
const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);
|
|
869
895
|
let formattedPayload = formatTurnGrepOutput(newMatches);
|
|
@@ -1075,10 +1101,22 @@ var LocalRipgrepProvider = class {
|
|
|
1075
1101
|
];
|
|
1076
1102
|
const res = await runRipgrep(args, { cwd: this.repoRoot });
|
|
1077
1103
|
if (res.exitCode === -1) {
|
|
1078
|
-
|
|
1104
|
+
return {
|
|
1105
|
+
lines: [],
|
|
1106
|
+
error: `[RIPGREP NOT AVAILABLE] ripgrep (rg) is required but failed to execute. Please install it:
|
|
1107
|
+
\u2022 macOS: brew install ripgrep
|
|
1108
|
+
\u2022 Ubuntu/Debian: apt install ripgrep
|
|
1109
|
+
\u2022 Windows: choco install ripgrep
|
|
1110
|
+
\u2022 Or visit: https://github.com/BurntSushi/ripgrep#installation
|
|
1111
|
+
Exit code: ${res.exitCode}${res.stderr ? `
|
|
1112
|
+
Details: ${res.stderr}` : ""}`
|
|
1113
|
+
};
|
|
1079
1114
|
}
|
|
1080
1115
|
if (res.exitCode !== 0 && res.exitCode !== 1) {
|
|
1081
|
-
|
|
1116
|
+
return {
|
|
1117
|
+
lines: [],
|
|
1118
|
+
error: `[RIPGREP ERROR] grep failed with exit code ${res.exitCode}${res.stderr ? `: ${res.stderr}` : ""}`
|
|
1119
|
+
};
|
|
1082
1120
|
}
|
|
1083
1121
|
const lines = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
|
|
1084
1122
|
return { lines };
|
|
@@ -1096,7 +1134,8 @@ var LocalRipgrepProvider = class {
|
|
|
1096
1134
|
];
|
|
1097
1135
|
const res = await runRipgrep(args, { cwd: this.repoRoot });
|
|
1098
1136
|
if (res.exitCode === -1) {
|
|
1099
|
-
|
|
1137
|
+
console.warn(`[warp_grep] ripgrep not available for glob: ${res.stderr || "execution failed"}`);
|
|
1138
|
+
return { files: [] };
|
|
1100
1139
|
}
|
|
1101
1140
|
const files = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
|
|
1102
1141
|
return { files };
|
|
@@ -1105,13 +1144,22 @@ var LocalRipgrepProvider = class {
|
|
|
1105
1144
|
const abs = resolveUnderRepo(this.repoRoot, params.path);
|
|
1106
1145
|
const stat = await import_promises3.default.stat(abs).catch(() => null);
|
|
1107
1146
|
if (!stat || !stat.isFile()) {
|
|
1108
|
-
|
|
1147
|
+
return {
|
|
1148
|
+
lines: [],
|
|
1149
|
+
error: `[FILE NOT FOUND] You tried to read "${params.path}" but there is no file at this path. Double-check the path exists and is spelled correctly.`
|
|
1150
|
+
};
|
|
1109
1151
|
}
|
|
1110
1152
|
if (isSymlink(abs)) {
|
|
1111
|
-
|
|
1153
|
+
return {
|
|
1154
|
+
lines: [],
|
|
1155
|
+
error: `[SYMLINK] You tried to read "${params.path}" but this is a symlink. Try reading the actual file it points to instead.`
|
|
1156
|
+
};
|
|
1112
1157
|
}
|
|
1113
1158
|
if (!isTextualFile(abs)) {
|
|
1114
|
-
|
|
1159
|
+
return {
|
|
1160
|
+
lines: [],
|
|
1161
|
+
error: `[UNREADABLE FILE] You tried to read "${params.path}" but this file is either too large or not a text file, so it cannot be read. Try a different file.`
|
|
1162
|
+
};
|
|
1115
1163
|
}
|
|
1116
1164
|
const lines = await readAllLines(abs);
|
|
1117
1165
|
const total = lines.length;
|