@morphllm/morphsdk 0.2.114 → 0.2.115

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.
Files changed (48) hide show
  1. package/dist/{chunk-ALTKGCG5.js → chunk-CM75JPVD.js} +2 -2
  2. package/dist/{chunk-FL4ZBHK2.js → chunk-GQUNK324.js} +2 -2
  3. package/dist/{chunk-23R562QJ.js → chunk-NTDAIKZI.js} +9 -4
  4. package/dist/chunk-NTDAIKZI.js.map +1 -0
  5. package/dist/{chunk-YY7NZLAI.js → chunk-RBTL6EJG.js} +11 -3
  6. package/dist/chunk-RBTL6EJG.js.map +1 -0
  7. package/dist/{chunk-HI35Y6EZ.js → chunk-SYZ75S3S.js} +18 -5
  8. package/dist/chunk-SYZ75S3S.js.map +1 -0
  9. package/dist/{chunk-3U7AWFBN.js → chunk-TZBDXZFC.js} +5 -5
  10. package/dist/{client-Bm_umdno.d.ts → client-D7iO2TbA.d.ts} +7 -0
  11. package/dist/client.cjs +30 -6
  12. package/dist/client.cjs.map +1 -1
  13. package/dist/client.d.ts +1 -1
  14. package/dist/client.js +6 -6
  15. package/dist/index.cjs +30 -6
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.js +6 -6
  19. package/dist/tools/warp_grep/agent/runner.cjs +10 -2
  20. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  21. package/dist/tools/warp_grep/agent/runner.js +1 -1
  22. package/dist/tools/warp_grep/anthropic.cjs +8 -2
  23. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  24. package/dist/tools/warp_grep/anthropic.js +3 -3
  25. package/dist/tools/warp_grep/client.cjs +18 -4
  26. package/dist/tools/warp_grep/client.cjs.map +1 -1
  27. package/dist/tools/warp_grep/client.d.ts +7 -1
  28. package/dist/tools/warp_grep/client.js +4 -2
  29. package/dist/tools/warp_grep/gemini.cjs +8 -2
  30. package/dist/tools/warp_grep/gemini.cjs.map +1 -1
  31. package/dist/tools/warp_grep/gemini.js +2 -2
  32. package/dist/tools/warp_grep/index.cjs +16 -4
  33. package/dist/tools/warp_grep/index.cjs.map +1 -1
  34. package/dist/tools/warp_grep/index.js +2 -2
  35. package/dist/tools/warp_grep/openai.cjs +8 -2
  36. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  37. package/dist/tools/warp_grep/openai.js +3 -3
  38. package/dist/tools/warp_grep/vercel.cjs +216 -4
  39. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  40. package/dist/tools/warp_grep/vercel.d.ts +7 -0
  41. package/dist/tools/warp_grep/vercel.js +3 -3
  42. package/package.json +6 -1
  43. package/dist/chunk-23R562QJ.js.map +0 -1
  44. package/dist/chunk-HI35Y6EZ.js.map +0 -1
  45. package/dist/chunk-YY7NZLAI.js.map +0 -1
  46. /package/dist/{chunk-ALTKGCG5.js.map → chunk-CM75JPVD.js.map} +0 -0
  47. /package/dist/{chunk-FL4ZBHK2.js.map → chunk-GQUNK324.js.map} +0 -0
  48. /package/dist/{chunk-3U7AWFBN.js.map → chunk-TZBDXZFC.js.map} +0 -0
@@ -3,12 +3,12 @@ import {
3
3
  execute,
4
4
  openai_default,
5
5
  warpGrepTool
6
- } from "../../chunk-FL4ZBHK2.js";
6
+ } from "../../chunk-GQUNK324.js";
7
7
  import "../../chunk-KW7OEGZK.js";
8
8
  import {
9
9
  formatResult
10
- } from "../../chunk-23R562QJ.js";
11
- import "../../chunk-YY7NZLAI.js";
10
+ } from "../../chunk-NTDAIKZI.js";
11
+ import "../../chunk-RBTL6EJG.js";
12
12
  import "../../chunk-PUGSTXLO.js";
13
13
  import "../../chunk-3MLWXJTJ.js";
14
14
  import "../../chunk-SNGGSPYJ.js";
@@ -1419,17 +1419,21 @@ async function runWarpGrep(config) {
1419
1419
  retryConfig: config.retryConfig,
1420
1420
  timeout: timeoutMs
1421
1421
  }).catch((e) => {
1422
- errors.push({ message: e instanceof Error ? e.message : String(e) });
1422
+ const errMsg = e instanceof Error ? e.message : String(e);
1423
+ console.error(`[warp_grep] Morph API call failed on turn ${turn}:`, errMsg);
1424
+ errors.push({ message: errMsg });
1423
1425
  return "";
1424
1426
  });
1425
1427
  turnMetrics.morph_api_ms = Date.now() - modelCallStart;
1426
1428
  if (!assistantContent) {
1429
+ console.error(`[warp_grep] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);
1427
1430
  timings.turns.push(turnMetrics);
1428
1431
  break;
1429
1432
  }
1430
1433
  messages.push({ role: "assistant", content: assistantContent });
1431
1434
  const toolCalls = parser.parse(assistantContent);
1432
1435
  if (toolCalls.length === 0) {
1436
+ console.error(`[warp_grep] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));
1433
1437
  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" });
1434
1438
  terminationReason = "terminated";
1435
1439
  timings.turns.push(turnMetrics);
@@ -1535,6 +1539,160 @@ async function runWarpGrep(config) {
1535
1539
  timings
1536
1540
  };
1537
1541
  }
1542
+ async function* runWarpGrepStreaming(config) {
1543
+ const totalStart = Date.now();
1544
+ const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
1545
+ const timings = { turns: [], timeout_ms: timeoutMs };
1546
+ const repoRoot = import_path2.default.resolve(config.repoRoot || process.cwd());
1547
+ const messages = [];
1548
+ messages.push({ role: "system", content: getSystemPrompt() });
1549
+ const initialStateStart = Date.now();
1550
+ const initialState = await buildInitialState(repoRoot, config.query, config.provider);
1551
+ timings.initial_state_ms = Date.now() - initialStateStart;
1552
+ messages.push({ role: "user", content: initialState });
1553
+ const maxTurns = AGENT_CONFIG.MAX_TURNS;
1554
+ const model = config.model || DEFAULT_MODEL;
1555
+ const provider = config.provider;
1556
+ const errors = [];
1557
+ let finishMeta;
1558
+ let terminationReason = "terminated";
1559
+ for (let turn = 1; turn <= maxTurns; turn += 1) {
1560
+ const turnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };
1561
+ enforceContextLimit(messages);
1562
+ const modelCallStart = Date.now();
1563
+ const assistantContent = await callModel(messages, model, {
1564
+ morphApiKey: config.morphApiKey,
1565
+ morphApiUrl: config.morphApiUrl,
1566
+ retryConfig: config.retryConfig,
1567
+ timeout: timeoutMs
1568
+ }).catch((e) => {
1569
+ const errMsg = e instanceof Error ? e.message : String(e);
1570
+ console.error(`[warp_grep:stream] Morph API call failed on turn ${turn}:`, errMsg);
1571
+ errors.push({ message: errMsg });
1572
+ return "";
1573
+ });
1574
+ turnMetrics.morph_api_ms = Date.now() - modelCallStart;
1575
+ if (!assistantContent) {
1576
+ console.error(`[warp_grep:stream] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);
1577
+ timings.turns.push(turnMetrics);
1578
+ break;
1579
+ }
1580
+ messages.push({ role: "assistant", content: assistantContent });
1581
+ const toolCalls = parser.parse(assistantContent);
1582
+ if (toolCalls.length === 0) {
1583
+ console.error(`[warp_grep:stream] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));
1584
+ 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" });
1585
+ terminationReason = "terminated";
1586
+ timings.turns.push(turnMetrics);
1587
+ break;
1588
+ }
1589
+ yield {
1590
+ turn,
1591
+ toolCalls: toolCalls.map((c) => ({
1592
+ name: c.name,
1593
+ arguments: c.arguments ?? {}
1594
+ }))
1595
+ };
1596
+ const finishCalls = toolCalls.filter((c) => c.name === "finish");
1597
+ const grepCalls = toolCalls.filter((c) => c.name === "grep");
1598
+ const listDirCalls = toolCalls.filter((c) => c.name === "list_directory");
1599
+ const readCalls = toolCalls.filter((c) => c.name === "read");
1600
+ const skipCalls = toolCalls.filter((c) => c.name === "_skip");
1601
+ const formatted = [];
1602
+ for (const c of skipCalls) {
1603
+ const msg = c.arguments?.message || "Command skipped due to parsing error";
1604
+ formatted.push(msg);
1605
+ }
1606
+ const allPromises = [];
1607
+ for (const c of grepCalls) {
1608
+ const args = c.arguments ?? {};
1609
+ allPromises.push(
1610
+ toolGrep(provider, args).then(
1611
+ ({ output }) => formatAgentToolOutput("grep", args, output, { isError: false }),
1612
+ (err) => formatAgentToolOutput("grep", args, String(err), { isError: true })
1613
+ )
1614
+ );
1615
+ }
1616
+ for (const c of listDirCalls) {
1617
+ const args = c.arguments ?? {};
1618
+ allPromises.push(
1619
+ toolListDirectory(provider, args).then(
1620
+ (p) => formatAgentToolOutput("list_directory", args, p, { isError: false }),
1621
+ (err) => formatAgentToolOutput("list_directory", args, String(err), { isError: true })
1622
+ )
1623
+ );
1624
+ }
1625
+ for (const c of readCalls) {
1626
+ const args = c.arguments ?? {};
1627
+ allPromises.push(
1628
+ toolRead(provider, args).then(
1629
+ (p) => formatAgentToolOutput("read", args, p, { isError: false }),
1630
+ (err) => formatAgentToolOutput("read", args, String(err), { isError: true })
1631
+ )
1632
+ );
1633
+ }
1634
+ const toolExecStart = Date.now();
1635
+ const allResults = await Promise.all(allPromises);
1636
+ turnMetrics.local_tools_ms = Date.now() - toolExecStart;
1637
+ for (const result of allResults) {
1638
+ formatted.push(result);
1639
+ }
1640
+ if (formatted.length > 0) {
1641
+ const turnMessage = formatTurnMessage(turn, maxTurns);
1642
+ const contextBudget = calculateContextBudget(messages);
1643
+ messages.push({ role: "user", content: formatted.join("\n") + turnMessage + "\n" + contextBudget });
1644
+ }
1645
+ timings.turns.push(turnMetrics);
1646
+ if (finishCalls.length) {
1647
+ const fc = finishCalls[0];
1648
+ const files = fc.arguments?.files ?? [];
1649
+ finishMeta = { files };
1650
+ terminationReason = "completed";
1651
+ break;
1652
+ }
1653
+ }
1654
+ if (terminationReason !== "completed" || !finishMeta) {
1655
+ timings.total_ms = Date.now() - totalStart;
1656
+ return { terminationReason, messages, errors, timings };
1657
+ }
1658
+ const parts = ["Relevant context found:"];
1659
+ for (const f of finishMeta.files) {
1660
+ const ranges = f.lines === "*" ? "*" : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(", ") : "*";
1661
+ parts.push(`- ${f.path}: ${ranges}`);
1662
+ }
1663
+ const payload = parts.join("\n");
1664
+ const finishResolutionStart = Date.now();
1665
+ const fileReadErrors = [];
1666
+ const resolved = await readFinishFiles(
1667
+ repoRoot,
1668
+ finishMeta.files,
1669
+ async (p, s, e) => {
1670
+ try {
1671
+ const rr = await provider.read({ path: p, start: s, end: e });
1672
+ return rr.lines.map((l) => {
1673
+ const idx = l.indexOf("|");
1674
+ return idx >= 0 ? l.slice(idx + 1) : l;
1675
+ });
1676
+ } catch (err) {
1677
+ const errorMsg = err instanceof Error ? err.message : String(err);
1678
+ fileReadErrors.push({ path: p, error: errorMsg });
1679
+ console.error(`[warp_grep] Failed to read file: ${p} - ${errorMsg}`);
1680
+ return [`[couldn't find: ${p}]`];
1681
+ }
1682
+ }
1683
+ );
1684
+ timings.finish_resolution_ms = Date.now() - finishResolutionStart;
1685
+ if (fileReadErrors.length > 0) {
1686
+ errors.push(...fileReadErrors.map((e) => ({ message: `File read error: ${e.path} - ${e.error}` })));
1687
+ }
1688
+ timings.total_ms = Date.now() - totalStart;
1689
+ return {
1690
+ terminationReason: "completed",
1691
+ messages,
1692
+ finish: { payload, metadata: finishMeta, resolved },
1693
+ timings
1694
+ };
1695
+ }
1538
1696
 
1539
1697
  // tools/warp_grep/providers/remote.ts
1540
1698
  init_config();
@@ -1739,7 +1897,9 @@ async function executeToolCall(input, config) {
1739
1897
  });
1740
1898
  const finish = result.finish;
1741
1899
  if (result.terminationReason !== "completed" || !finish?.metadata) {
1742
- return { success: false, error: "Search did not complete" };
1900
+ const errorDetails = result.errors?.map((e) => e.message).join("; ") || "unknown reason";
1901
+ console.error(`[warp_grep] executeToolCall failed. Reason: ${result.terminationReason}. Errors: ${errorDetails}. Turns: ${result.timings?.turns?.length ?? 0}`);
1902
+ return { success: false, error: `Search did not complete: ${errorDetails}` };
1743
1903
  }
1744
1904
  const contexts = (finish.resolved ?? []).map((r) => ({
1745
1905
  file: r.path,
@@ -1748,6 +1908,46 @@ async function executeToolCall(input, config) {
1748
1908
  }));
1749
1909
  return { success: true, contexts, summary: finish.payload };
1750
1910
  }
1911
+ function processAgentResult(result) {
1912
+ const finish = result.finish;
1913
+ if (result.terminationReason !== "completed" || !finish?.metadata) {
1914
+ const errorDetails = result.errors?.map((e) => e.message).join("; ") || "unknown reason";
1915
+ console.error(`[warp_grep] processAgentResult failed. Reason: ${result.terminationReason}. Errors: ${errorDetails}. Turns: ${result.timings?.turns?.length ?? 0}`);
1916
+ return { success: false, error: `Search did not complete: ${errorDetails}` };
1917
+ }
1918
+ const contexts = (finish.resolved ?? []).map((r) => ({
1919
+ file: r.path,
1920
+ content: r.content,
1921
+ lines: r.ranges
1922
+ }));
1923
+ return { success: true, contexts, summary: finish.payload };
1924
+ }
1925
+ async function* executeToolCallStreaming(input, config) {
1926
+ const parsed = typeof input === "string" ? JSON.parse(input) : input;
1927
+ const provider = config.remoteCommands ? new RemoteCommandsProvider(config.repoRoot, config.remoteCommands) : config.provider ?? await getLocalProvider(config.repoRoot, config.excludes);
1928
+ const generator = runWarpGrepStreaming({
1929
+ query: parsed.query,
1930
+ repoRoot: config.repoRoot,
1931
+ provider,
1932
+ excludes: config.excludes,
1933
+ includes: config.includes,
1934
+ debug: config.debug ?? false,
1935
+ morphApiKey: config.morphApiKey,
1936
+ morphApiUrl: config.morphApiUrl,
1937
+ retryConfig: config.retryConfig,
1938
+ timeout: config.timeout
1939
+ });
1940
+ let agentResult;
1941
+ for (; ; ) {
1942
+ const { value, done } = await generator.next();
1943
+ if (done) {
1944
+ agentResult = value;
1945
+ break;
1946
+ }
1947
+ yield value;
1948
+ }
1949
+ return processAgentResult(agentResult);
1950
+ }
1751
1951
  function formatResult(result) {
1752
1952
  if (!result.success) {
1753
1953
  return `Search failed: ${result.error}`;
@@ -1799,14 +1999,26 @@ function createWarpGrepTool(config) {
1799
1999
  description: config.description ?? WARP_GREP_DESCRIPTION,
1800
2000
  inputSchema: schema,
1801
2001
  execute: async (params) => {
1802
- const result = await executeToolCall(params, config);
2002
+ const steps = [];
2003
+ const generator = executeToolCallStreaming(params, config);
2004
+ let result;
2005
+ for (; ; ) {
2006
+ const { value, done } = await generator.next();
2007
+ if (done) {
2008
+ result = value;
2009
+ break;
2010
+ }
2011
+ steps.push(value);
2012
+ }
1803
2013
  if (!result.success) {
1804
2014
  throw new Error(`Failed to search codebase: ${result.error}`);
1805
2015
  }
2016
+ const allToolCalls = steps.flatMap((s) => s.toolCalls);
1806
2017
  return {
1807
2018
  success: true,
1808
2019
  contexts: result.contexts,
1809
- summary: result.summary
2020
+ summary: result.summary,
2021
+ progress: allToolCalls.length > 0 ? { turn: steps.length, toolCalls: allToolCalls } : void 0
1810
2022
  };
1811
2023
  }
1812
2024
  });