@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
package/dist/client.cjs
CHANGED
|
@@ -1103,12 +1103,6 @@ function getSystemPrompt() {
|
|
|
1103
1103
|
}
|
|
1104
1104
|
|
|
1105
1105
|
// tools/warp_grep/agent/parser.ts
|
|
1106
|
-
var LLMResponseParseError = class extends Error {
|
|
1107
|
-
constructor(message) {
|
|
1108
|
-
super(message);
|
|
1109
|
-
this.name = "LLMResponseParseError";
|
|
1110
|
-
}
|
|
1111
|
-
};
|
|
1112
1106
|
var VALID_COMMANDS = ["analyse", "grep", "read", "finish"];
|
|
1113
1107
|
function preprocessText(text) {
|
|
1114
1108
|
let processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
|
|
@@ -1159,24 +1153,23 @@ var LLMResponseParser = class {
|
|
|
1159
1153
|
const lines = preprocessText(text);
|
|
1160
1154
|
const commands = [];
|
|
1161
1155
|
let finishAccumulator = null;
|
|
1162
|
-
lines.forEach((line
|
|
1156
|
+
lines.forEach((line) => {
|
|
1163
1157
|
if (!line || line.startsWith("#")) return;
|
|
1164
|
-
const
|
|
1165
|
-
const parts = this.splitLine(line, ctx);
|
|
1158
|
+
const parts = this.splitLine(line);
|
|
1166
1159
|
if (parts.length === 0) return;
|
|
1167
1160
|
const cmd = parts[0];
|
|
1168
1161
|
switch (cmd) {
|
|
1169
1162
|
case "analyse":
|
|
1170
|
-
this.handleAnalyse(parts,
|
|
1163
|
+
this.handleAnalyse(parts, line, commands);
|
|
1171
1164
|
break;
|
|
1172
1165
|
case "grep":
|
|
1173
|
-
this.handleGrep(parts,
|
|
1166
|
+
this.handleGrep(parts, line, commands);
|
|
1174
1167
|
break;
|
|
1175
1168
|
case "read":
|
|
1176
|
-
this.handleRead(parts,
|
|
1169
|
+
this.handleRead(parts, line, commands);
|
|
1177
1170
|
break;
|
|
1178
1171
|
case "finish":
|
|
1179
|
-
finishAccumulator = this.handleFinish(parts,
|
|
1172
|
+
finishAccumulator = this.handleFinish(parts, line, commands, finishAccumulator);
|
|
1180
1173
|
break;
|
|
1181
1174
|
default:
|
|
1182
1175
|
break;
|
|
@@ -1193,53 +1186,68 @@ var LLMResponseParser = class {
|
|
|
1193
1186
|
}
|
|
1194
1187
|
return commands;
|
|
1195
1188
|
}
|
|
1196
|
-
splitLine(line
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
current = "";
|
|
1210
|
-
}
|
|
1211
|
-
} else {
|
|
1212
|
-
current += ch;
|
|
1189
|
+
splitLine(line) {
|
|
1190
|
+
const parts = [];
|
|
1191
|
+
let current = "";
|
|
1192
|
+
let inSingle = false;
|
|
1193
|
+
for (let i = 0; i < line.length; i++) {
|
|
1194
|
+
const ch = line[i];
|
|
1195
|
+
if (ch === "'" && line[i - 1] !== "\\") {
|
|
1196
|
+
inSingle = !inSingle;
|
|
1197
|
+
current += ch;
|
|
1198
|
+
} else if (!inSingle && /\s/.test(ch)) {
|
|
1199
|
+
if (current) {
|
|
1200
|
+
parts.push(current);
|
|
1201
|
+
current = "";
|
|
1213
1202
|
}
|
|
1203
|
+
} else {
|
|
1204
|
+
current += ch;
|
|
1214
1205
|
}
|
|
1215
|
-
if (current) parts.push(current);
|
|
1216
|
-
return parts;
|
|
1217
|
-
} catch {
|
|
1218
|
-
throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);
|
|
1219
1206
|
}
|
|
1207
|
+
if (current) parts.push(current);
|
|
1208
|
+
return parts;
|
|
1209
|
+
}
|
|
1210
|
+
/** Helper to create a _skip tool call with an error message */
|
|
1211
|
+
skip(message) {
|
|
1212
|
+
return { name: "_skip", arguments: { message } };
|
|
1220
1213
|
}
|
|
1221
|
-
handleAnalyse(parts,
|
|
1214
|
+
handleAnalyse(parts, rawLine, commands) {
|
|
1222
1215
|
if (parts.length < 2) {
|
|
1223
|
-
|
|
1216
|
+
commands.push(this.skip(
|
|
1217
|
+
`[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: analyse <path> [pattern]. Example: analyse src/`
|
|
1218
|
+
));
|
|
1219
|
+
return;
|
|
1224
1220
|
}
|
|
1225
1221
|
const path4 = parts[1];
|
|
1226
1222
|
const pattern = parts[2]?.replace(/^"|"$/g, "") ?? null;
|
|
1227
1223
|
commands.push({ name: "analyse", arguments: { path: path4, pattern } });
|
|
1228
1224
|
}
|
|
1229
1225
|
// no glob tool in MCP
|
|
1230
|
-
handleGrep(parts,
|
|
1226
|
+
handleGrep(parts, rawLine, commands) {
|
|
1231
1227
|
if (parts.length < 3) {
|
|
1232
|
-
|
|
1228
|
+
commands.push(this.skip(
|
|
1229
|
+
`[SKIPPED] Your command "${rawLine}" is missing arguments. Correct format: grep '<pattern>' <path>. Example: grep 'TODO' src/`
|
|
1230
|
+
));
|
|
1231
|
+
return;
|
|
1233
1232
|
}
|
|
1234
|
-
|
|
1235
|
-
if (
|
|
1236
|
-
|
|
1233
|
+
let pat = parts[1];
|
|
1234
|
+
if (pat.startsWith("'") && pat.endsWith("'")) {
|
|
1235
|
+
pat = pat.slice(1, -1);
|
|
1237
1236
|
}
|
|
1238
|
-
|
|
1237
|
+
if (!pat) {
|
|
1238
|
+
commands.push(this.skip(
|
|
1239
|
+
`[SKIPPED] Your command "${rawLine}" has an empty pattern. Provide a non-empty search pattern. Example: grep 'function' src/`
|
|
1240
|
+
));
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
commands.push({ name: "grep", arguments: { pattern: pat, path: parts[2] } });
|
|
1239
1244
|
}
|
|
1240
|
-
handleRead(parts,
|
|
1245
|
+
handleRead(parts, rawLine, commands) {
|
|
1241
1246
|
if (parts.length < 2) {
|
|
1242
|
-
|
|
1247
|
+
commands.push(this.skip(
|
|
1248
|
+
`[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: read <path> or read <path>:<start>-<end>. Example: read src/index.ts:1-50`
|
|
1249
|
+
));
|
|
1250
|
+
return;
|
|
1243
1251
|
}
|
|
1244
1252
|
const spec = parts[1];
|
|
1245
1253
|
const rangeIdx = spec.indexOf(":");
|
|
@@ -1247,31 +1255,38 @@ var LLMResponseParser = class {
|
|
|
1247
1255
|
commands.push({ name: "read", arguments: { path: spec } });
|
|
1248
1256
|
return;
|
|
1249
1257
|
}
|
|
1250
|
-
const
|
|
1258
|
+
const filePath = spec.slice(0, rangeIdx);
|
|
1251
1259
|
const range = spec.slice(rangeIdx + 1);
|
|
1252
1260
|
const [s, e] = range.split("-").map((v) => parseInt(v, 10));
|
|
1253
1261
|
if (!Number.isFinite(s) || !Number.isFinite(e)) {
|
|
1254
|
-
|
|
1262
|
+
commands.push({ name: "read", arguments: { path: filePath } });
|
|
1263
|
+
return;
|
|
1255
1264
|
}
|
|
1256
|
-
commands.push({ name: "read", arguments: { path:
|
|
1265
|
+
commands.push({ name: "read", arguments: { path: filePath, start: s, end: e } });
|
|
1257
1266
|
}
|
|
1258
|
-
handleFinish(parts,
|
|
1267
|
+
handleFinish(parts, rawLine, commands, acc) {
|
|
1259
1268
|
const map = acc ?? /* @__PURE__ */ new Map();
|
|
1260
1269
|
const args = parts.slice(1);
|
|
1261
1270
|
for (const token of args) {
|
|
1262
|
-
const [
|
|
1263
|
-
if (!
|
|
1264
|
-
|
|
1271
|
+
const [filePath, rangesText] = token.split(":", 2);
|
|
1272
|
+
if (!filePath || !rangesText) {
|
|
1273
|
+
commands.push(this.skip(
|
|
1274
|
+
`[SKIPPED] Invalid finish token "${token}". Correct format: finish <path>:<start>-<end>. Example: finish src/index.ts:1-50`
|
|
1275
|
+
));
|
|
1276
|
+
continue;
|
|
1265
1277
|
}
|
|
1266
1278
|
const rangeSpecs = rangesText.split(",").filter(Boolean);
|
|
1267
1279
|
for (const spec of rangeSpecs) {
|
|
1268
1280
|
const [s, e] = spec.split("-").map((v) => parseInt(v, 10));
|
|
1269
1281
|
if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {
|
|
1270
|
-
|
|
1282
|
+
commands.push(this.skip(
|
|
1283
|
+
`[SKIPPED] Invalid range "${spec}" in "${token}". Ranges must be <start>-<end> where start <= end. Example: 1-50`
|
|
1284
|
+
));
|
|
1285
|
+
continue;
|
|
1271
1286
|
}
|
|
1272
|
-
const arr = map.get(
|
|
1287
|
+
const arr = map.get(filePath) ?? [];
|
|
1273
1288
|
arr.push([s, e]);
|
|
1274
|
-
map.set(
|
|
1289
|
+
map.set(filePath, arr);
|
|
1275
1290
|
}
|
|
1276
1291
|
}
|
|
1277
1292
|
return map;
|
|
@@ -1281,6 +1296,10 @@ var LLMResponseParser = class {
|
|
|
1281
1296
|
// tools/warp_grep/tools/read.ts
|
|
1282
1297
|
async function toolRead(provider, args) {
|
|
1283
1298
|
const res = await provider.read({ path: args.path, start: args.start, end: args.end });
|
|
1299
|
+
if (res.error) {
|
|
1300
|
+
return res.error;
|
|
1301
|
+
}
|
|
1302
|
+
if (!res.lines.length) return "(empty file)";
|
|
1284
1303
|
return res.lines.join("\n");
|
|
1285
1304
|
}
|
|
1286
1305
|
|
|
@@ -1592,14 +1611,7 @@ async function runWarpGrep(config) {
|
|
|
1592
1611
|
});
|
|
1593
1612
|
if (!assistantContent) break;
|
|
1594
1613
|
messages.push({ role: "assistant", content: assistantContent });
|
|
1595
|
-
|
|
1596
|
-
try {
|
|
1597
|
-
toolCalls = parser.parse(assistantContent);
|
|
1598
|
-
} catch (e) {
|
|
1599
|
-
errors.push({ message: e instanceof Error ? e.message : String(e) });
|
|
1600
|
-
terminationReason = "terminated";
|
|
1601
|
-
break;
|
|
1602
|
-
}
|
|
1614
|
+
const toolCalls = parser.parse(assistantContent);
|
|
1603
1615
|
if (toolCalls.length === 0) {
|
|
1604
1616
|
errors.push({ message: "No tool calls produced by the model." });
|
|
1605
1617
|
terminationReason = "terminated";
|
|
@@ -1609,7 +1621,12 @@ async function runWarpGrep(config) {
|
|
|
1609
1621
|
const grepCalls = toolCalls.filter((c) => c.name === "grep");
|
|
1610
1622
|
const analyseCalls = toolCalls.filter((c) => c.name === "analyse");
|
|
1611
1623
|
const readCalls = toolCalls.filter((c) => c.name === "read");
|
|
1624
|
+
const skipCalls = toolCalls.filter((c) => c.name === "_skip");
|
|
1612
1625
|
const formatted = [];
|
|
1626
|
+
for (const c of skipCalls) {
|
|
1627
|
+
const msg = c.arguments?.message || "Command skipped due to parsing error";
|
|
1628
|
+
formatted.push(msg);
|
|
1629
|
+
}
|
|
1613
1630
|
const otherPromises = [];
|
|
1614
1631
|
for (const c of analyseCalls) {
|
|
1615
1632
|
const args = c.arguments ?? {};
|
|
@@ -1635,6 +1652,15 @@ async function runWarpGrep(config) {
|
|
|
1635
1652
|
const args = c.arguments ?? {};
|
|
1636
1653
|
try {
|
|
1637
1654
|
const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });
|
|
1655
|
+
if (grepRes.error) {
|
|
1656
|
+
errors.push({ message: grepRes.error });
|
|
1657
|
+
terminationReason = "terminated";
|
|
1658
|
+
return {
|
|
1659
|
+
terminationReason: "terminated",
|
|
1660
|
+
messages,
|
|
1661
|
+
errors
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1638
1664
|
const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join("\n") : "";
|
|
1639
1665
|
const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);
|
|
1640
1666
|
let formattedPayload = formatTurnGrepOutput(newMatches);
|
|
@@ -1846,10 +1872,22 @@ var LocalRipgrepProvider = class {
|
|
|
1846
1872
|
];
|
|
1847
1873
|
const res = await runRipgrep(args, { cwd: this.repoRoot });
|
|
1848
1874
|
if (res.exitCode === -1) {
|
|
1849
|
-
|
|
1875
|
+
return {
|
|
1876
|
+
lines: [],
|
|
1877
|
+
error: `[RIPGREP NOT AVAILABLE] ripgrep (rg) is required but failed to execute. Please install it:
|
|
1878
|
+
\u2022 macOS: brew install ripgrep
|
|
1879
|
+
\u2022 Ubuntu/Debian: apt install ripgrep
|
|
1880
|
+
\u2022 Windows: choco install ripgrep
|
|
1881
|
+
\u2022 Or visit: https://github.com/BurntSushi/ripgrep#installation
|
|
1882
|
+
Exit code: ${res.exitCode}${res.stderr ? `
|
|
1883
|
+
Details: ${res.stderr}` : ""}`
|
|
1884
|
+
};
|
|
1850
1885
|
}
|
|
1851
1886
|
if (res.exitCode !== 0 && res.exitCode !== 1) {
|
|
1852
|
-
|
|
1887
|
+
return {
|
|
1888
|
+
lines: [],
|
|
1889
|
+
error: `[RIPGREP ERROR] grep failed with exit code ${res.exitCode}${res.stderr ? `: ${res.stderr}` : ""}`
|
|
1890
|
+
};
|
|
1853
1891
|
}
|
|
1854
1892
|
const lines = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
|
|
1855
1893
|
return { lines };
|
|
@@ -1867,7 +1905,8 @@ var LocalRipgrepProvider = class {
|
|
|
1867
1905
|
];
|
|
1868
1906
|
const res = await runRipgrep(args, { cwd: this.repoRoot });
|
|
1869
1907
|
if (res.exitCode === -1) {
|
|
1870
|
-
|
|
1908
|
+
console.warn(`[warp_grep] ripgrep not available for glob: ${res.stderr || "execution failed"}`);
|
|
1909
|
+
return { files: [] };
|
|
1871
1910
|
}
|
|
1872
1911
|
const files = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
|
|
1873
1912
|
return { files };
|
|
@@ -1876,13 +1915,22 @@ var LocalRipgrepProvider = class {
|
|
|
1876
1915
|
const abs = resolveUnderRepo(this.repoRoot, params.path);
|
|
1877
1916
|
const stat = await import_promises4.default.stat(abs).catch(() => null);
|
|
1878
1917
|
if (!stat || !stat.isFile()) {
|
|
1879
|
-
|
|
1918
|
+
return {
|
|
1919
|
+
lines: [],
|
|
1920
|
+
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.`
|
|
1921
|
+
};
|
|
1880
1922
|
}
|
|
1881
1923
|
if (isSymlink(abs)) {
|
|
1882
|
-
|
|
1924
|
+
return {
|
|
1925
|
+
lines: [],
|
|
1926
|
+
error: `[SYMLINK] You tried to read "${params.path}" but this is a symlink. Try reading the actual file it points to instead.`
|
|
1927
|
+
};
|
|
1883
1928
|
}
|
|
1884
1929
|
if (!isTextualFile(abs)) {
|
|
1885
|
-
|
|
1930
|
+
return {
|
|
1931
|
+
lines: [],
|
|
1932
|
+
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.`
|
|
1933
|
+
};
|
|
1886
1934
|
}
|
|
1887
1935
|
const lines = await readAllLines(abs);
|
|
1888
1936
|
const total = lines.length;
|