@morphllm/morphsdk 0.2.125 → 0.2.127

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 (219) hide show
  1. package/dist/{chunk-DGYWACHC.js → chunk-3ZA7Y66U.js} +2 -2
  2. package/dist/{chunk-5L3TPS6A.js → chunk-6DRIR7AI.js} +5 -4
  3. package/dist/chunk-6DRIR7AI.js.map +1 -0
  4. package/dist/{chunk-G5YJDK5S.js → chunk-ADHGSV2D.js} +2 -2
  5. package/dist/{chunk-5PNMAWLC.js → chunk-DKODF3YG.js} +2 -2
  6. package/dist/{chunk-5PNMAWLC.js.map → chunk-DKODF3YG.js.map} +1 -1
  7. package/dist/{chunk-BQO3WODX.js → chunk-DS7YL4V3.js} +8 -13
  8. package/dist/chunk-DS7YL4V3.js.map +1 -0
  9. package/dist/{chunk-FEQJCZJQ.js → chunk-EGOCFCAH.js} +2 -2
  10. package/dist/{chunk-TFK4UOUE.js → chunk-EL6CCK7C.js} +6 -6
  11. package/dist/{chunk-IB4MEIQG.js → chunk-GDCVK6SP.js} +2 -2
  12. package/dist/{chunk-UGSV5LPO.js → chunk-GVF4Q75N.js} +2 -2
  13. package/dist/{chunk-TS3E6IRI.js → chunk-GWKCMFD6.js} +2 -2
  14. package/dist/{chunk-WZAZFW77.js → chunk-HZK5TEUK.js} +1 -1
  15. package/dist/{chunk-EF7ZYLA2.js → chunk-HZOTLGJH.js} +19 -12
  16. package/dist/chunk-HZOTLGJH.js.map +1 -0
  17. package/dist/{chunk-3MLWXJTJ.js → chunk-K2FXHDX2.js} +15 -10
  18. package/dist/chunk-K2FXHDX2.js.map +1 -0
  19. package/dist/{chunk-FAZO2LNY.js → chunk-K6YSD3DR.js} +2 -2
  20. package/dist/{chunk-ACHEU2V3.js → chunk-LX34ZO3N.js} +2 -2
  21. package/dist/{chunk-OFQRY3RM.js → chunk-LXBIP5FI.js} +18 -23
  22. package/dist/chunk-LXBIP5FI.js.map +1 -0
  23. package/dist/{chunk-F6HNFC2H.js → chunk-MJHAVXFK.js} +2 -2
  24. package/dist/{chunk-PUGSTXLO.js → chunk-NF2QWJDY.js} +6 -7
  25. package/dist/chunk-NF2QWJDY.js.map +1 -0
  26. package/dist/{chunk-6TH3VNCF.js → chunk-NQQS5BZZ.js} +3 -3
  27. package/dist/{chunk-V3HLOZK2.js → chunk-QLBRTLEI.js} +1 -1
  28. package/dist/{chunk-V3HLOZK2.js.map → chunk-QLBRTLEI.js.map} +1 -1
  29. package/dist/{chunk-57PXQ6IS.js → chunk-QOE522DB.js} +15 -15
  30. package/dist/chunk-QRXG5CAZ.js +27 -0
  31. package/dist/chunk-QRXG5CAZ.js.map +1 -0
  32. package/dist/{chunk-7RTJCQWB.js → chunk-QUULFOWB.js} +10 -5
  33. package/dist/chunk-QUULFOWB.js.map +1 -0
  34. package/dist/{chunk-33CP5QCC.js → chunk-R5IFI552.js} +3 -3
  35. package/dist/{chunk-33CP5QCC.js.map → chunk-R5IFI552.js.map} +1 -1
  36. package/dist/{chunk-IRNUW2DB.js → chunk-REJNS3OW.js} +8 -13
  37. package/dist/chunk-REJNS3OW.js.map +1 -0
  38. package/dist/{chunk-2S7ZQFIB.js → chunk-U73OIAJC.js} +2 -2
  39. package/dist/{chunk-OQGX4RZP.js → chunk-UAQ7UWZB.js} +2 -2
  40. package/dist/chunk-VCKJ22DX.js +131 -0
  41. package/dist/chunk-VCKJ22DX.js.map +1 -0
  42. package/dist/{chunk-2MK64KK4.js → chunk-YTUQEDWH.js} +2 -2
  43. package/dist/{chunk-H6KT7IXW.js → chunk-ZVAXTR2V.js} +2 -2
  44. package/dist/{chunk-BGL35LL6.js → chunk-ZYD2SEQK.js} +2 -2
  45. package/dist/{client-JHPwle1Z.d.ts → client-CNYzlN_6.d.ts} +6 -7
  46. package/dist/client.cjs +166 -579
  47. package/dist/client.cjs.map +1 -1
  48. package/dist/client.d.ts +1 -2
  49. package/dist/client.js +27 -28
  50. package/dist/edge.cjs +2 -2
  51. package/dist/edge.cjs.map +1 -1
  52. package/dist/edge.js +4 -4
  53. package/dist/{finish-pPJfB0uO.d.ts → finish-DBKuo8yj.d.ts} +2 -0
  54. package/dist/index.cjs +166 -579
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/index.d.ts +1 -2
  57. package/dist/index.js +29 -30
  58. package/dist/modelrouter/core.cjs +2 -2
  59. package/dist/modelrouter/core.cjs.map +1 -1
  60. package/dist/modelrouter/core.js +3 -3
  61. package/dist/modelrouter/index.cjs +2 -2
  62. package/dist/modelrouter/index.cjs.map +1 -1
  63. package/dist/modelrouter/index.js +3 -3
  64. package/dist/tools/browser/anthropic.cjs +2 -2
  65. package/dist/tools/browser/anthropic.cjs.map +1 -1
  66. package/dist/tools/browser/anthropic.js +5 -5
  67. package/dist/tools/browser/core.cjs +2 -2
  68. package/dist/tools/browser/core.cjs.map +1 -1
  69. package/dist/tools/browser/core.js +4 -4
  70. package/dist/tools/browser/index.cjs +2 -2
  71. package/dist/tools/browser/index.cjs.map +1 -1
  72. package/dist/tools/browser/index.js +7 -7
  73. package/dist/tools/browser/openai.cjs +2 -2
  74. package/dist/tools/browser/openai.cjs.map +1 -1
  75. package/dist/tools/browser/openai.js +5 -5
  76. package/dist/tools/browser/profiles/core.cjs +2 -2
  77. package/dist/tools/browser/profiles/core.cjs.map +1 -1
  78. package/dist/tools/browser/profiles/core.js +3 -3
  79. package/dist/tools/browser/profiles/index.cjs +2 -2
  80. package/dist/tools/browser/profiles/index.cjs.map +1 -1
  81. package/dist/tools/browser/profiles/index.js +3 -3
  82. package/dist/tools/browser/vercel.cjs +2 -2
  83. package/dist/tools/browser/vercel.cjs.map +1 -1
  84. package/dist/tools/browser/vercel.js +5 -5
  85. package/dist/tools/codebase_search/anthropic.cjs +2 -2
  86. package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
  87. package/dist/tools/codebase_search/anthropic.js +4 -4
  88. package/dist/tools/codebase_search/core.cjs +2 -2
  89. package/dist/tools/codebase_search/core.cjs.map +1 -1
  90. package/dist/tools/codebase_search/core.js +3 -3
  91. package/dist/tools/codebase_search/index.cjs +2 -2
  92. package/dist/tools/codebase_search/index.cjs.map +1 -1
  93. package/dist/tools/codebase_search/index.js +6 -6
  94. package/dist/tools/codebase_search/openai.cjs +2 -2
  95. package/dist/tools/codebase_search/openai.cjs.map +1 -1
  96. package/dist/tools/codebase_search/openai.js +4 -4
  97. package/dist/tools/codebase_search/vercel.cjs +2 -2
  98. package/dist/tools/codebase_search/vercel.cjs.map +1 -1
  99. package/dist/tools/codebase_search/vercel.js +4 -4
  100. package/dist/tools/fastapply/anthropic.cjs +2 -2
  101. package/dist/tools/fastapply/anthropic.cjs.map +1 -1
  102. package/dist/tools/fastapply/anthropic.js +4 -4
  103. package/dist/tools/fastapply/apply.cjs +2 -2
  104. package/dist/tools/fastapply/apply.cjs.map +1 -1
  105. package/dist/tools/fastapply/apply.js +2 -2
  106. package/dist/tools/fastapply/core.cjs +2 -2
  107. package/dist/tools/fastapply/core.cjs.map +1 -1
  108. package/dist/tools/fastapply/core.js +3 -3
  109. package/dist/tools/fastapply/index.cjs +2 -2
  110. package/dist/tools/fastapply/index.cjs.map +1 -1
  111. package/dist/tools/fastapply/index.js +6 -6
  112. package/dist/tools/fastapply/openai.cjs +2 -2
  113. package/dist/tools/fastapply/openai.cjs.map +1 -1
  114. package/dist/tools/fastapply/openai.js +4 -4
  115. package/dist/tools/fastapply/vercel.cjs +2 -2
  116. package/dist/tools/fastapply/vercel.cjs.map +1 -1
  117. package/dist/tools/fastapply/vercel.js +4 -4
  118. package/dist/tools/index.cjs +2 -2
  119. package/dist/tools/index.cjs.map +1 -1
  120. package/dist/tools/index.js +6 -6
  121. package/dist/tools/utils/resilience.cjs +2 -2
  122. package/dist/tools/utils/resilience.cjs.map +1 -1
  123. package/dist/tools/utils/resilience.js +2 -2
  124. package/dist/tools/warp_grep/agent/config.cjs +1 -1
  125. package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
  126. package/dist/tools/warp_grep/agent/config.d.ts +1 -1
  127. package/dist/tools/warp_grep/agent/config.js +1 -1
  128. package/dist/tools/warp_grep/agent/formatter.cjs +3 -74
  129. package/dist/tools/warp_grep/agent/formatter.cjs.map +1 -1
  130. package/dist/tools/warp_grep/agent/formatter.d.ts +1 -5
  131. package/dist/tools/warp_grep/agent/formatter.js +1 -1
  132. package/dist/tools/warp_grep/agent/parser.cjs +91 -242
  133. package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
  134. package/dist/tools/warp_grep/agent/parser.d.ts +0 -8
  135. package/dist/tools/warp_grep/agent/parser.js +1 -1
  136. package/dist/tools/warp_grep/agent/runner.cjs +122 -543
  137. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  138. package/dist/tools/warp_grep/agent/runner.js +6 -7
  139. package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
  140. package/dist/tools/warp_grep/agent/types.d.ts +2 -0
  141. package/dist/tools/warp_grep/anthropic.cjs +152 -570
  142. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  143. package/dist/tools/warp_grep/anthropic.d.ts +2 -4
  144. package/dist/tools/warp_grep/anthropic.js +11 -15
  145. package/dist/tools/warp_grep/client.cjs +143 -558
  146. package/dist/tools/warp_grep/client.cjs.map +1 -1
  147. package/dist/tools/warp_grep/client.js +9 -10
  148. package/dist/tools/warp_grep/gemini.cjs +152 -570
  149. package/dist/tools/warp_grep/gemini.cjs.map +1 -1
  150. package/dist/tools/warp_grep/gemini.d.ts +2 -4
  151. package/dist/tools/warp_grep/gemini.js +18 -23
  152. package/dist/tools/warp_grep/gemini.js.map +1 -1
  153. package/dist/tools/warp_grep/harness.cjs +124 -540
  154. package/dist/tools/warp_grep/harness.cjs.map +1 -1
  155. package/dist/tools/warp_grep/harness.d.ts +4 -5
  156. package/dist/tools/warp_grep/harness.js +5 -11
  157. package/dist/tools/warp_grep/harness.js.map +1 -1
  158. package/dist/tools/warp_grep/index.cjs +147 -565
  159. package/dist/tools/warp_grep/index.cjs.map +1 -1
  160. package/dist/tools/warp_grep/index.d.ts +7 -4
  161. package/dist/tools/warp_grep/index.js +14 -20
  162. package/dist/tools/warp_grep/openai.cjs +152 -570
  163. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  164. package/dist/tools/warp_grep/openai.d.ts +2 -4
  165. package/dist/tools/warp_grep/openai.js +11 -15
  166. package/dist/tools/warp_grep/providers/local.cjs +17 -10
  167. package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
  168. package/dist/tools/warp_grep/providers/local.d.ts +6 -1
  169. package/dist/tools/warp_grep/providers/local.js +2 -2
  170. package/dist/tools/warp_grep/providers/remote.cjs +4 -5
  171. package/dist/tools/warp_grep/providers/remote.cjs.map +1 -1
  172. package/dist/tools/warp_grep/providers/remote.js +2 -2
  173. package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
  174. package/dist/tools/warp_grep/providers/types.d.ts +2 -0
  175. package/dist/tools/warp_grep/vercel.cjs +151 -563
  176. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  177. package/dist/tools/warp_grep/vercel.d.ts +2 -2
  178. package/dist/tools/warp_grep/vercel.js +11 -15
  179. package/dist/version.cjs +2 -2
  180. package/dist/version.cjs.map +1 -1
  181. package/dist/version.js +1 -1
  182. package/package.json +2 -2
  183. package/dist/chunk-3MLWXJTJ.js.map +0 -1
  184. package/dist/chunk-5L3TPS6A.js.map +0 -1
  185. package/dist/chunk-7RTJCQWB.js.map +0 -1
  186. package/dist/chunk-APP75CBN.js +0 -98
  187. package/dist/chunk-APP75CBN.js.map +0 -1
  188. package/dist/chunk-BQO3WODX.js.map +0 -1
  189. package/dist/chunk-EF7ZYLA2.js.map +0 -1
  190. package/dist/chunk-FMLHRJDF.js +0 -207
  191. package/dist/chunk-FMLHRJDF.js.map +0 -1
  192. package/dist/chunk-GHGJAQSJ.js +0 -282
  193. package/dist/chunk-GHGJAQSJ.js.map +0 -1
  194. package/dist/chunk-IRNUW2DB.js.map +0 -1
  195. package/dist/chunk-OFQRY3RM.js.map +0 -1
  196. package/dist/chunk-PUGSTXLO.js.map +0 -1
  197. package/dist/tools/warp_grep/agent/prompt.cjs +0 -232
  198. package/dist/tools/warp_grep/agent/prompt.cjs.map +0 -1
  199. package/dist/tools/warp_grep/agent/prompt.d.ts +0 -4
  200. package/dist/tools/warp_grep/agent/prompt.js +0 -10
  201. package/dist/tools/warp_grep/agent/prompt.js.map +0 -1
  202. /package/dist/{chunk-DGYWACHC.js.map → chunk-3ZA7Y66U.js.map} +0 -0
  203. /package/dist/{chunk-G5YJDK5S.js.map → chunk-ADHGSV2D.js.map} +0 -0
  204. /package/dist/{chunk-FEQJCZJQ.js.map → chunk-EGOCFCAH.js.map} +0 -0
  205. /package/dist/{chunk-TFK4UOUE.js.map → chunk-EL6CCK7C.js.map} +0 -0
  206. /package/dist/{chunk-IB4MEIQG.js.map → chunk-GDCVK6SP.js.map} +0 -0
  207. /package/dist/{chunk-UGSV5LPO.js.map → chunk-GVF4Q75N.js.map} +0 -0
  208. /package/dist/{chunk-TS3E6IRI.js.map → chunk-GWKCMFD6.js.map} +0 -0
  209. /package/dist/{chunk-WZAZFW77.js.map → chunk-HZK5TEUK.js.map} +0 -0
  210. /package/dist/{chunk-FAZO2LNY.js.map → chunk-K6YSD3DR.js.map} +0 -0
  211. /package/dist/{chunk-ACHEU2V3.js.map → chunk-LX34ZO3N.js.map} +0 -0
  212. /package/dist/{chunk-F6HNFC2H.js.map → chunk-MJHAVXFK.js.map} +0 -0
  213. /package/dist/{chunk-6TH3VNCF.js.map → chunk-NQQS5BZZ.js.map} +0 -0
  214. /package/dist/{chunk-57PXQ6IS.js.map → chunk-QOE522DB.js.map} +0 -0
  215. /package/dist/{chunk-2S7ZQFIB.js.map → chunk-U73OIAJC.js.map} +0 -0
  216. /package/dist/{chunk-OQGX4RZP.js.map → chunk-UAQ7UWZB.js.map} +0 -0
  217. /package/dist/{chunk-2MK64KK4.js.map → chunk-YTUQEDWH.js.map} +0 -0
  218. /package/dist/{chunk-H6KT7IXW.js.map → chunk-ZVAXTR2V.js.map} +0 -0
  219. /package/dist/{chunk-BGL35LL6.js.map → chunk-ZYD2SEQK.js.map} +0 -0
@@ -130,7 +130,7 @@ var init_config = __esm({
130
130
  ".*"
131
131
  ];
132
132
  DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || "").split(",").map((s) => s.trim()).filter(Boolean).concat(BUILTIN_EXCLUDES);
133
- DEFAULT_MODEL = "morph-warp-grep-v1";
133
+ DEFAULT_MODEL = "morph-warp-grep-v2";
134
134
  }
135
135
  });
136
136
 
@@ -285,7 +285,8 @@ var local_exports = {};
285
285
  __export(local_exports, {
286
286
  LocalRipgrepProvider: () => LocalRipgrepProvider
287
287
  });
288
- function shouldSkip2(name) {
288
+ function shouldSkip2(name, allowNames) {
289
+ if (allowNames?.has(name)) return false;
289
290
  if (SKIP_NAMES2.has(name)) return true;
290
291
  if (name.startsWith(".")) return true;
291
292
  for (const ext of SKIP_EXTENSIONS2) {
@@ -380,10 +381,14 @@ var init_local = __esm({
380
381
  ".js.map"
381
382
  ]);
382
383
  LocalRipgrepProvider = class {
383
- constructor(repoRoot, excludes = DEFAULT_EXCLUDES) {
384
+ constructor(repoRoot, excludes = DEFAULT_EXCLUDES, options) {
384
385
  this.repoRoot = repoRoot;
385
386
  this.excludes = excludes;
387
+ if (options?.allowNames?.length) {
388
+ this.allowNames = new Set(options.allowNames);
389
+ }
386
390
  }
391
+ allowNames;
387
392
  async grep(params) {
388
393
  let abs;
389
394
  try {
@@ -397,6 +402,7 @@ var init_local = __esm({
397
402
  const stat = await import_promises2.default.stat(abs).catch(() => null);
398
403
  if (!stat) return { lines: [] };
399
404
  const targetArg = abs === import_path4.default.resolve(this.repoRoot) ? "." : toRepoRelative(this.repoRoot, abs);
405
+ const contextLines = params.context_lines !== void 0 ? String(params.context_lines) : "1";
400
406
  const args = [
401
407
  "--no-config",
402
408
  "--no-heading",
@@ -406,9 +412,10 @@ var init_local = __esm({
406
412
  "--trim",
407
413
  "--max-columns=400",
408
414
  "-C",
409
- "1",
415
+ contextLines,
416
+ ...params.case_sensitive === false ? ["--ignore-case"] : [],
410
417
  ...params.glob ? ["--glob", params.glob] : [],
411
- ...this.excludes.flatMap((e) => ["-g", `!${e}`]),
418
+ ...this.excludes.filter((e) => !this.allowNames?.has(e)).flatMap((e) => ["-g", `!${e}`]),
412
419
  params.pattern,
413
420
  targetArg || "."
414
421
  ];
@@ -433,10 +440,9 @@ Details: ${res.stderr}` : ""}`
433
440
  }
434
441
  const lines = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
435
442
  if (lines.length > AGENT_CONFIG.MAX_OUTPUT_LINES) {
436
- return {
437
- lines: [],
438
- error: "query not specific enough, tool tried to return too much context and failed"
439
- };
443
+ const truncated = lines.slice(0, AGENT_CONFIG.MAX_OUTPUT_LINES);
444
+ truncated.push(`... (output truncated at ${AGENT_CONFIG.MAX_OUTPUT_LINES} of ${lines.length} lines)`);
445
+ return { lines: truncated };
440
446
  }
441
447
  return { lines };
442
448
  }
@@ -510,7 +516,7 @@ Details: ${res.stderr}` : ""}`
510
516
  }
511
517
  if (out.length > AGENT_CONFIG.MAX_READ_LINES) {
512
518
  const truncated = out.slice(0, AGENT_CONFIG.MAX_READ_LINES);
513
- truncated.push(`... [truncated: showing ${AGENT_CONFIG.MAX_READ_LINES} of ${out.length} lines]`);
519
+ truncated.push(`... (output truncated at ${AGENT_CONFIG.MAX_READ_LINES} of ${out.length} lines)`);
514
520
  return { lines: truncated };
515
521
  }
516
522
  return { lines: out };
@@ -530,6 +536,7 @@ Details: ${res.stderr}` : ""}`
530
536
  const maxDepth = params.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;
531
537
  const regex = params.pattern ? new RegExp(params.pattern) : null;
532
538
  const repoRoot = this.repoRoot;
539
+ const allowNames = this.allowNames;
533
540
  const results = [];
534
541
  let timedOut = false;
535
542
  const startTime = Date.now();
@@ -547,7 +554,7 @@ Details: ${res.stderr}` : ""}`
547
554
  }
548
555
  for (const entry of entries) {
549
556
  if (timedOut || results.length >= maxResults) break;
550
- if (shouldSkip2(entry.name)) continue;
557
+ if (shouldSkip2(entry.name, allowNames)) continue;
551
558
  if (regex && !regex.test(entry.name)) continue;
552
559
  const full = import_path4.default.join(dir, entry.name);
553
560
  const isDir = entry.isDirectory();
@@ -579,7 +586,6 @@ __export(gemini_exports, {
579
586
  default: () => gemini_default,
580
587
  execute: () => execute,
581
588
  formatResult: () => formatResult,
582
- getSystemPrompt: () => getSystemPrompt,
583
589
  warpGrepFunctionDeclaration: () => warpGrepFunctionDeclaration
584
590
  });
585
591
  module.exports = __toCommonJS(gemini_exports);
@@ -587,483 +593,130 @@ module.exports = __toCommonJS(gemini_exports);
587
593
  // tools/warp_grep/agent/runner.ts
588
594
  init_config();
589
595
 
590
- // tools/warp_grep/agent/prompt.ts
591
- var SYSTEM_PROMPT = `You are a code search agent. Your task is to find all relevant code for a given search_string.
592
-
593
- ### workflow
594
- You have exactly 4 turns. The 4th turn MUST be a \`finish\` call. Each turn allows up to 8 parallel tool calls.
595
-
596
- - Turn 1: Map the territory OR dive deep (based on search_string specificity)
597
- - Turn 2-3: Refine based on findings
598
- - Turn 4: MUST call \`finish\` with all relevant code locations
599
- - You MAY call \`finish\` early if confident\u2014but never before at least 1 search turn.
600
- - The user strongly prefers if you can call the finish tool early, but you must be correct
601
-
602
- Remember, if the task feels easy to you, it is strongly desirable to call 'finish' early using fewer turns, but quality over speed
603
-
604
- ### tools
605
- Tool calls use nested XML elements:
606
- \`\`\`xml
607
- <tool_name>
608
- <parameter>value</parameter>
609
- </tool_name>
610
- \`\`\`
611
-
612
- ### \`list_directory\`
613
- Directory tree view. Shows structure of a path, optionally filtered by regex pattern.
614
-
615
- Elements:
616
- - \`<path>\` (required): Directory path to list (use \`.\` for repo root)
617
- - \`<pattern>\` (optional): Regex to filter results
618
-
619
- Examples:
620
- \`\`\`
621
- <list_directory>
622
- <path>src/services</path>
623
- </list_directory>
624
-
625
- <list_directory>
626
- <path>lib/utils</path>
627
- <pattern>.*\\.(ts|js)$</pattern>
628
- </list_directory>
629
- \`\`\`
630
-
631
- ### \`read\`
632
- Read file contents. Supports multiple line ranges.
633
- - Returns numbered lines for easy reference
634
- - ALWAYS include import statements (usually lines 1-20). Better to over-include than miss context.
635
-
636
- Elements:
637
- - \`<path>\` (required): File path to read
638
- - \`<lines>\` (optional): Line ranges like "1-50,75-80,100-120" (omit to read entire file)
639
-
640
- Examples:
641
- \`\`\`
642
- <read>
643
- <path>src/main.py</path>
644
- </read>
645
-
646
- <read>
647
- <path>src/auth.py</path>
648
- <lines>1-20,45-80,150-200</lines>
649
- </read>
650
- \`\`\`
651
-
652
- ### \`grep\`
653
- Search for pattern matches across files. Returns matches with 1 line of context above and below.
654
- - Match lines use \`:\` separator \u2192 \`filepath:linenum:content\`
655
- - Context lines use \`-\` separator \u2192 \`filepath-linenum-content\`
656
-
657
- Elements:
658
- - \`<pattern>\` (required): Search pattern (regex). Use \`(a|b)\` for OR patterns.
659
- - \`<sub_dir>\` (optional): Subdirectory to search in (defaults to \`.\`)
660
- - \`<glob>\` (optional): File pattern filter like \`*.py\` or \`*.{ts,tsx}\`
661
-
662
- Examples:
663
- \`\`\`
664
- <grep>
665
- <pattern>(authenticate|authorize|login)</pattern>
666
- <sub_dir>src/auth/</sub_dir>
667
- </grep>
668
-
669
- <grep>
670
- <pattern>class.*(Service|Controller)</pattern>
671
- <glob>*.{ts,js}</glob>
672
- </grep>
673
-
674
- <grep>
675
- <pattern>(DB_HOST|DATABASE_URL|connection)</pattern>
676
- <glob>*.{py,yaml,env}</glob>
677
- <sub_dir>lib/</sub_dir>
678
- </grep>
679
- \`\`\`
680
-
681
- ### \`finish\`
682
- Submit final answer with all relevant code locations. Uses nested \`<file>\` elements.
683
-
684
- File elements:
685
- - \`<path>\` (required): File path
686
- - \`<lines>\` (optional): Line ranges like "1-50,75-80" (\`*\` for entire file)
687
-
688
- ALWAYS include import statements (usually lines 1-20). Better to over-include than miss context.
689
-
690
- Examples:
691
- \`\`\`
692
- <finish>
693
- <file>
694
- <path>src/auth.py</path>
695
- <lines>1-15,25-50,75-80</lines>
696
- </file>
697
- <file>
698
- <path>src/models/user.py</path>
699
- <lines>*</lines>
700
- </file>
701
- </finish>
702
- \`\`\`
703
- </tools>
704
-
705
- <strategy>
706
- **Before your first tool call, classify the search_string:**
707
-
708
- | Search_string Type | Round 1 Strategy | Early Finish? |
709
- |------------|------------------|---------------|
710
- | **Specific** (function name, error string, unique identifier) | 8 parallel greps on likely paths | Often by round 2 |
711
- | **Conceptual** (how does X work, where is Y handled) | list_directory + 2-3 broad greps | Rarely early |
712
- | **Exploratory** (find all tests, list API endpoints) | list_directory at multiple depths | Usually needs 3 rounds |
713
-
714
- **Parallel call patterns:**
715
- - **Shotgun grep**: Same pattern, 8 different directories\u2014fast coverage
716
- - **Variant grep**: 8 pattern variations (synonyms, naming conventions)\u2014catches inconsistent codebases
717
- - **Funnel**: 1 list_directory + 7 greps\u2014orient and search simultaneously
718
- - **Deep read**: 8 reads on files you already identified\u2014gather full context fast
719
-
720
- **Tool call expectations:**
721
- - Low quality tool calls are ones that give back sparse information. This either means they are not well thought out and are not educated guesses OR, they are too broad and give back too many results.
722
- - High quality tool calls strike a balance between complexity in the tool call to exclude results we know we don't want, and how wide the search space is so that we don't miss anything. It is ok to start off with wider search spaces, but is imperative that you use your intuition from there on out and seek high quality tool calls only.
723
- - You are not starting blind, you have some information about root level repo structure going in, so use that to prevent making trivial repo wide queries.
724
- - The grep tool shows you which file path and line numbers the pattern was found in, use this information smartly when trying to read the file.
725
- </strategy>
726
-
727
- <output_format>
728
- EVERY response MUST follow this exact format:
729
-
730
- 1. First, wrap your reasoning in \`<think>...</think>\` tags containing:
731
- - Search_string classification (specific/conceptual/exploratory)
732
- - Confidence estimate (can I finish in 1-2 rounds?)
733
- - This round's parallel strategy
734
- - What signals would let me finish early?
735
-
736
- 2. Then, output up to 8 tool calls using nested XML elements.
737
-
738
- Example:
739
- \`\`\`
740
- <think>
741
- This is a specific search_string about authentication. I'll grep for auth-related patterns.
742
- High confidence I can finish in 2 rounds if I find the auth module. I have already been shown the repo's structure at root
743
- Strategy: Shotgun grep across likely directories.
744
- </think>
745
- <grep>
746
- <pattern>(authenticate|login|session)</pattern>
747
- <sub_dir>src/auth/</sub_dir>
748
- </grep>
749
- <grep>
750
- <pattern>(middleware|interceptor)</pattern>
751
- <glob>*.{ts,js}</glob>
752
- </grep>
753
- <list_directory>
754
- <path>src/auth</path>
755
- </list_directory>
756
- \`\`\`
757
-
758
- Finishing example:
759
- \`\`\`
760
- <think>
761
- I think I have a rough idea, but this is my last turn so I must call the finish tool regardless.
762
- </think>
763
- <finish>
764
- <file>
765
- <path>src/auth/login.py</path>
766
- <lines>1-50</lines>
767
- </file>
768
- <file>
769
- <path>src/middleware/session.py</path>
770
- <lines>10-80</lines>
771
- </file>
772
- </finish>
773
- \`\`\`
774
-
775
- No commentary outside \`<think>\`. No explanations after tool calls.
776
- </output_format>
777
-
778
- use as all 8 tool calls to be optimal
779
-
780
- <finishing_requirements>
781
- When calling \`finish\`:
782
- - Include the import section (typically lines 1-20) of each file
783
- - Include all function/class definitions that are relevant
784
- - Include any type definitions, interfaces, or constants used
785
- - Better to over-include than leave the user missing context
786
- - If unsure about boundaries, include more rather than less
787
- </finishing_requirements>`;
788
- function getSystemPrompt() {
789
- return SYSTEM_PROMPT;
790
- }
791
-
792
596
  // tools/warp_grep/agent/parser.ts
793
- var VALID_COMMANDS = ["list_directory", "grep", "read", "finish"];
597
+ var VALID_COMMANDS = ["list_directory", "ripgrep", "read", "finish"];
794
598
  function isValidCommand(name) {
795
599
  return VALID_COMMANDS.includes(name);
796
600
  }
797
- function getXmlElementText(xml, tagName) {
798
- const regex = new RegExp(`<${tagName}>([\\s\\S]*?)</${tagName}>`, "i");
799
- const match = xml.match(regex);
800
- return match ? match[1].trim() : null;
801
- }
802
- function parseNestedXmlTools(text) {
601
+ function parseQwen3ToolCalls(text) {
803
602
  const tools = [];
804
- const toolRegex = /<([a-z_][a-z0-9_]*)>([\s\S]*?)<\/\1>/gi;
603
+ const toolCallRegex = /<tool_call>\s*<function=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/function>\s*<\/tool_call>/gi;
805
604
  let match;
806
- while ((match = toolRegex.exec(text)) !== null) {
807
- const rawToolName = match[1].toLowerCase();
808
- const content = match[2];
809
- if (!isValidCommand(rawToolName)) continue;
810
- const toolName = rawToolName;
811
- if (toolName === "list_directory") {
812
- const path5 = getXmlElementText(content, "path");
813
- const pattern = getXmlElementText(content, "pattern");
814
- if (path5) {
815
- tools.push({ name: "list_directory", arguments: { path: path5, pattern } });
605
+ while ((match = toolCallRegex.exec(text)) !== null) {
606
+ const funcName = match[1].toLowerCase();
607
+ const body = match[2];
608
+ if (!isValidCommand(funcName)) continue;
609
+ const params = {};
610
+ const paramRegex = /<parameter=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/parameter>/gi;
611
+ let paramMatch;
612
+ while ((paramMatch = paramRegex.exec(body)) !== null) {
613
+ params[paramMatch[1].toLowerCase()] = paramMatch[2].trim();
614
+ }
615
+ if (funcName === "ripgrep") {
616
+ const pattern = params.pattern;
617
+ if (!pattern) continue;
618
+ const args = {
619
+ pattern,
620
+ path: params.path || ".",
621
+ ...params.glob && { glob: params.glob },
622
+ ...params.context_lines && { context_lines: parseInt(params.context_lines, 10) },
623
+ ...params.case_sensitive && { case_sensitive: params.case_sensitive === "true" }
624
+ };
625
+ tools.push({ name: "grep", arguments: args });
626
+ } else if (funcName === "list_directory") {
627
+ const command = params.command;
628
+ const directPath = params.path;
629
+ let dirPath = directPath || ".";
630
+ if (!directPath && command) {
631
+ const tokens = command.trim().split(/\s+/);
632
+ const pathTokens = tokens.slice(1).filter((t) => !t.startsWith("-") && !t.startsWith("|") && !t.startsWith("\\("));
633
+ if (pathTokens.length > 0) {
634
+ dirPath = pathTokens[0];
635
+ }
816
636
  }
817
- } else if (toolName === "grep") {
818
- const pattern = getXmlElementText(content, "pattern");
819
- const subDir = getXmlElementText(content, "sub_dir");
820
- const glob = getXmlElementText(content, "glob");
821
- if (pattern) {
822
- tools.push({
823
- name: "grep",
824
- arguments: {
825
- pattern,
826
- path: subDir || ".",
827
- ...glob && { glob }
637
+ tools.push({ name: "list_directory", arguments: { path: dirPath, pattern: params.pattern || null } });
638
+ } else if (funcName === "read") {
639
+ const filePath = params.path;
640
+ if (!filePath) continue;
641
+ const args = { path: filePath };
642
+ const linesStr = params.lines;
643
+ if (linesStr) {
644
+ const ranges = [];
645
+ for (const rangeStr of linesStr.split(",")) {
646
+ const trimmed = rangeStr.trim();
647
+ if (!trimmed) continue;
648
+ const [s, e] = trimmed.split("-").map((v) => parseInt(v.trim(), 10));
649
+ if (Number.isFinite(s) && Number.isFinite(e)) {
650
+ ranges.push([s, e]);
651
+ } else if (Number.isFinite(s)) {
652
+ ranges.push([s, s]);
828
653
  }
829
- });
654
+ }
655
+ if (ranges.length === 1) {
656
+ args.start = ranges[0][0];
657
+ args.end = ranges[0][1];
658
+ } else if (ranges.length > 1) {
659
+ args.lines = ranges;
660
+ }
661
+ }
662
+ tools.push({ name: "read", arguments: args });
663
+ } else if (funcName === "finish") {
664
+ if (params.result && !params.files) {
665
+ tools.push({ name: "finish", arguments: { files: [], textResult: params.result } });
666
+ continue;
830
667
  }
831
- } else if (toolName === "read") {
832
- const path5 = getXmlElementText(content, "path");
833
- const linesStr = getXmlElementText(content, "lines");
834
- if (path5) {
835
- const args = { path: path5 };
836
- if (linesStr) {
668
+ const filesStr = params.files;
669
+ if (!filesStr) {
670
+ tools.push({ name: "finish", arguments: { files: [], textResult: "No relevant code found." } });
671
+ continue;
672
+ }
673
+ const files = [];
674
+ for (const line of filesStr.split("\n")) {
675
+ const trimmed = line.trim();
676
+ if (!trimmed) continue;
677
+ const colonIdx = trimmed.indexOf(":");
678
+ if (colonIdx === -1) {
679
+ files.push({ path: trimmed, lines: "*" });
680
+ } else {
681
+ const filePath = trimmed.slice(0, colonIdx);
682
+ const rangesPart = trimmed.slice(colonIdx + 1);
837
683
  const ranges = [];
838
- for (const rangeStr of linesStr.split(",")) {
839
- const trimmed = rangeStr.trim();
840
- if (!trimmed) continue;
841
- const [s, e] = trimmed.split("-").map((v) => parseInt(v.trim(), 10));
684
+ for (const rangeStr of rangesPart.split(",")) {
685
+ const rt = rangeStr.trim();
686
+ if (!rt || rt === "*") {
687
+ files.push({ path: filePath, lines: "*" });
688
+ break;
689
+ }
690
+ const [s, e] = rt.split("-").map((v) => parseInt(v.trim(), 10));
842
691
  if (Number.isFinite(s) && Number.isFinite(e)) {
843
692
  ranges.push([s, e]);
844
693
  } else if (Number.isFinite(s)) {
845
694
  ranges.push([s, s]);
846
695
  }
847
696
  }
848
- if (ranges.length === 1) {
849
- args.start = ranges[0][0];
850
- args.end = ranges[0][1];
851
- } else if (ranges.length > 1) {
852
- args.lines = ranges;
853
- }
854
- }
855
- tools.push({ name: "read", arguments: args });
856
- }
857
- } else if (toolName === "finish") {
858
- const fileRegex = /<file>([\s\S]*?)<\/file>/gi;
859
- const files = [];
860
- let fileMatch;
861
- while ((fileMatch = fileRegex.exec(content)) !== null) {
862
- const fileContent = fileMatch[1];
863
- const filePath = getXmlElementText(fileContent, "path");
864
- const linesStr = getXmlElementText(fileContent, "lines");
865
- if (filePath) {
866
- if (!linesStr || linesStr.trim() === "*") {
697
+ if (ranges.length > 0) {
698
+ files.push({ path: filePath, lines: ranges });
699
+ } else if (!files.some((f) => f.path === filePath)) {
867
700
  files.push({ path: filePath, lines: "*" });
868
- } else {
869
- const ranges = [];
870
- for (const rangeStr of linesStr.split(",")) {
871
- const [s, e] = rangeStr.split("-").map((v) => parseInt(v.trim(), 10));
872
- if (Number.isFinite(s) && Number.isFinite(e)) {
873
- ranges.push([s, e]);
874
- }
875
- }
876
- if (ranges.length > 0) {
877
- files.push({ path: filePath, lines: ranges });
878
- } else {
879
- files.push({ path: filePath, lines: "*" });
880
- }
881
701
  }
882
702
  }
883
703
  }
884
704
  if (files.length > 0) {
885
705
  tools.push({ name: "finish", arguments: { files } });
886
706
  } else {
887
- const raw = content.replace(/<[^>]*>/g, "").trim();
888
- const textResult = !raw || raw === "*" ? "No relevant code found." : raw;
889
- tools.push({ name: "finish", arguments: { files: [], textResult } });
707
+ tools.push({ name: "finish", arguments: { files: [], textResult: filesStr } });
890
708
  }
891
709
  }
892
710
  }
893
- if (tools.length === 0) {
894
- const fnFinishMatch = text.match(/<function=finish>([\s\S]*?)<\/function>/i);
895
- if (fnFinishMatch) {
896
- const inner = fnFinishMatch[1];
897
- const paramMatch = inner.match(/<parameter=result>([\s\S]*?)<\/parameter>/i);
898
- const raw = (paramMatch ? paramMatch[1] : inner).trim();
899
- const textResult = !raw || raw === "*" ? "No relevant code found." : raw;
900
- tools.push({ name: "finish", arguments: { files: [], textResult } });
901
- }
902
- }
903
711
  return tools;
904
712
  }
905
- function preprocessText(text) {
906
- const processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "").replace(/<\/?tool_call>/gi, "");
907
- const nestedTools = parseNestedXmlTools(processed);
908
- const toolCallLines = [];
909
- const allLines = processed.split(/\r?\n/).map((l) => l.trim());
910
- for (const line of allLines) {
911
- if (!line) continue;
912
- if (line.startsWith("<")) continue;
913
- const firstWord = line.split(/\s/)[0];
914
- if (VALID_COMMANDS.includes(firstWord)) {
915
- if (!toolCallLines.includes(line)) {
916
- toolCallLines.push(line);
917
- }
918
- }
919
- }
920
- return { lines: toolCallLines, nestedTools };
921
- }
922
713
  var LLMResponseParser = class {
923
- finishSpecSplitRe = /,(?=[^,\s]+:)/;
924
714
  parse(text) {
925
715
  if (typeof text !== "string") {
926
716
  throw new TypeError("Command text must be a string.");
927
717
  }
928
- const { lines, nestedTools } = preprocessText(text);
929
- const commands = [...nestedTools];
930
- let finishAccumulator = null;
931
- lines.forEach((line) => {
932
- if (!line || line.startsWith("#")) return;
933
- const parts = this.splitLine(line);
934
- if (parts.length === 0) return;
935
- const cmd = parts[0];
936
- switch (cmd) {
937
- case "list_directory":
938
- this.handleListDirectory(parts, line, commands);
939
- break;
940
- case "grep":
941
- this.handleGrep(parts, line, commands);
942
- break;
943
- case "read":
944
- this.handleRead(parts, line, commands);
945
- break;
946
- case "finish":
947
- finishAccumulator = this.handleFinish(parts, line, commands, finishAccumulator);
948
- break;
949
- default:
950
- break;
951
- }
952
- });
953
- if (finishAccumulator) {
954
- const map = finishAccumulator;
955
- const entries = [...map.entries()];
956
- const filesPayload = entries.map(([path5, ranges]) => ({
957
- path: path5,
958
- lines: [...ranges].sort((a, b) => a[0] - b[0])
959
- }));
960
- commands.push({ name: "finish", arguments: { files: filesPayload } });
961
- }
962
- return commands;
963
- }
964
- splitLine(line) {
965
- const parts = [];
966
- let current = "";
967
- let inSingle = false;
968
- for (let i = 0; i < line.length; i++) {
969
- const ch = line[i];
970
- if (ch === "'" && line[i - 1] !== "\\") {
971
- inSingle = !inSingle;
972
- current += ch;
973
- } else if (!inSingle && /\s/.test(ch)) {
974
- if (current) {
975
- parts.push(current);
976
- current = "";
977
- }
978
- } else {
979
- current += ch;
980
- }
981
- }
982
- if (current) parts.push(current);
983
- return parts;
984
- }
985
- /** Helper to create a _skip tool call with an error message */
986
- skip(message) {
987
- return { name: "_skip", arguments: { message } };
988
- }
989
- handleListDirectory(parts, rawLine, commands) {
990
- if (parts.length < 2) {
991
- commands.push(this.skip(
992
- `[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: list_directory <path> [pattern]. Example: list_directory src/`
993
- ));
994
- return;
995
- }
996
- const path5 = parts[1];
997
- const pattern = parts[2]?.replace(/^"|"$/g, "") ?? null;
998
- commands.push({ name: "list_directory", arguments: { path: path5, pattern } });
999
- }
1000
- handleGrep(parts, rawLine, commands) {
1001
- if (parts.length < 3) {
1002
- commands.push(this.skip(
1003
- `[SKIPPED] Your command "${rawLine}" is missing arguments. Correct format: grep '<pattern>' <path>. Example: grep 'TODO' src/`
1004
- ));
1005
- return;
1006
- }
1007
- let pat = parts[1];
1008
- if (pat.startsWith("'") && pat.endsWith("'")) {
1009
- pat = pat.slice(1, -1);
1010
- }
1011
- if (!pat) {
1012
- commands.push(this.skip(
1013
- `[SKIPPED] Your command "${rawLine}" has an empty pattern. Provide a non-empty search pattern. Example: grep 'function' src/`
1014
- ));
1015
- return;
1016
- }
1017
- commands.push({ name: "grep", arguments: { pattern: pat, path: parts[2] } });
1018
- }
1019
- handleRead(parts, rawLine, commands) {
1020
- if (parts.length < 2) {
1021
- commands.push(this.skip(
1022
- `[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: read <path> or read <path>:<start>-<end>. Example: read src/index.ts:1-50`
1023
- ));
1024
- return;
1025
- }
1026
- const spec = parts[1];
1027
- const rangeIdx = spec.indexOf(":");
1028
- if (rangeIdx === -1) {
1029
- commands.push({ name: "read", arguments: { path: spec } });
1030
- return;
1031
- }
1032
- const filePath = spec.slice(0, rangeIdx);
1033
- const range = spec.slice(rangeIdx + 1);
1034
- const [s, e] = range.split("-").map((v) => parseInt(v, 10));
1035
- if (!Number.isFinite(s) || !Number.isFinite(e)) {
1036
- commands.push({ name: "read", arguments: { path: filePath } });
1037
- return;
1038
- }
1039
- commands.push({ name: "read", arguments: { path: filePath, start: s, end: e } });
1040
- }
1041
- handleFinish(parts, rawLine, commands, acc) {
1042
- const map = acc ?? /* @__PURE__ */ new Map();
1043
- const args = parts.slice(1);
1044
- for (const token of args) {
1045
- const [filePath, rangesText] = token.split(":", 2);
1046
- if (!filePath || !rangesText) {
1047
- commands.push(this.skip(
1048
- `[SKIPPED] Invalid finish token "${token}". Correct format: finish <path>:<start>-<end>. Example: finish src/index.ts:1-50`
1049
- ));
1050
- continue;
1051
- }
1052
- const rangeSpecs = rangesText.split(",").filter(Boolean);
1053
- for (const spec of rangeSpecs) {
1054
- const [s, e] = spec.split("-").map((v) => parseInt(v, 10));
1055
- if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {
1056
- commands.push(this.skip(
1057
- `[SKIPPED] Invalid range "${spec}" in "${token}". Ranges must be <start>-<end> where start <= end. Example: 1-50`
1058
- ));
1059
- continue;
1060
- }
1061
- const arr = map.get(filePath) ?? [];
1062
- arr.push([s, e]);
1063
- map.set(filePath, arr);
1064
- }
1065
- }
1066
- return map;
718
+ const withoutThink = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
719
+ return parseQwen3ToolCalls(withoutThink);
1067
720
  }
1068
721
  };
1069
722
 
@@ -1133,14 +786,12 @@ async function toolListDirectory(provider, args) {
1133
786
  }
1134
787
  const { entries: list } = await getListRecursive(initialDepth);
1135
788
  if (!list.length) return "empty";
1136
- if (list.length >= maxResults) {
1137
- return "query not specific enough, tool called tried to return too much context and failed";
1138
- }
1139
- return list.map((e) => {
789
+ const tree = list.map((e) => {
1140
790
  const indent = " ".repeat(e.depth);
1141
791
  const name = e.type === "dir" ? `${e.name}/` : e.name;
1142
792
  return `${indent}${name}`;
1143
793
  }).join("\n");
794
+ return tree;
1144
795
  }
1145
796
 
1146
797
  // tools/warp_grep/agent/tools/finish.ts
@@ -1203,90 +854,19 @@ function mergeRanges(ranges) {
1203
854
 
1204
855
  // tools/warp_grep/agent/formatter.ts
1205
856
  var ToolOutputFormatter = class {
1206
- format(toolName, args, output, options = {}) {
857
+ format(toolName, _args, output, options = {}) {
1207
858
  const name = (toolName ?? "").trim();
1208
859
  if (!name) {
1209
860
  return "";
1210
861
  }
1211
862
  const payload = output?.toString?.()?.trim?.() ?? "";
1212
863
  const isError = Boolean(options.isError);
1213
- const safeArgs = args ?? {};
1214
864
  if (!payload && !isError) {
1215
865
  return "";
1216
866
  }
1217
- switch (name) {
1218
- case "read":
1219
- return this.formatRead(safeArgs, payload, isError);
1220
- case "list_directory":
1221
- return this.formatListDirectory(safeArgs, payload, isError);
1222
- case "grep":
1223
- return this.formatGrep(safeArgs, payload, isError);
1224
- default:
1225
- return payload ? `<tool_output>
1226
- ${payload}
1227
- </tool_output>` : "";
1228
- }
1229
- }
1230
- formatRead(args, payload, isError) {
1231
- if (isError) {
1232
- return payload;
1233
- }
1234
- const path5 = this.asString(args.path) || "...";
1235
- const start = args.start;
1236
- const end = args.end;
1237
- const linesArray = args.lines;
1238
- const attributes = [`path="${path5}"`];
1239
- if (linesArray && linesArray.length > 0) {
1240
- const rangeStr = linesArray.map(([s, e]) => `${s}-${e}`).join(",");
1241
- attributes.push(`lines="${rangeStr}"`);
1242
- } else if (start !== void 0 && end !== void 0) {
1243
- attributes.push(`lines="${start}-${end}"`);
1244
- }
1245
- return `<read ${attributes.join(" ")}>
867
+ return `<tool_response>
1246
868
  ${payload}
1247
- </read>`;
1248
- }
1249
- formatListDirectory(args, payload, isError) {
1250
- const path5 = this.asString(args.path) || ".";
1251
- const pattern = this.asString(args.pattern);
1252
- const attributes = [`path="${path5}"`];
1253
- if (pattern) {
1254
- attributes.push(`pattern="${pattern}"`);
1255
- }
1256
- if (isError) {
1257
- attributes.push('status="error"');
1258
- }
1259
- return `<list_directory ${attributes.join(" ")}>
1260
- ${payload}
1261
- </list_directory>`;
1262
- }
1263
- formatGrep(args, payload, isError) {
1264
- const pattern = this.asString(args.pattern);
1265
- const subDir = this.asString(args.path);
1266
- const glob = this.asString(args.glob);
1267
- const attributes = [];
1268
- if (pattern !== void 0) {
1269
- attributes.push(`pattern="${pattern}"`);
1270
- }
1271
- if (subDir !== void 0) {
1272
- attributes.push(`sub_dir="${subDir}"`);
1273
- }
1274
- if (glob !== void 0) {
1275
- attributes.push(`glob="${glob}"`);
1276
- }
1277
- if (isError) {
1278
- attributes.push('status="error"');
1279
- }
1280
- const attrText = attributes.length ? ` ${attributes.join(" ")}` : "";
1281
- return `<grep${attrText}>
1282
- ${payload}
1283
- </grep>`;
1284
- }
1285
- asString(value) {
1286
- if (value === null || value === void 0) {
1287
- return void 0;
1288
- }
1289
- return String(value);
869
+ </tool_response>`;
1290
870
  }
1291
871
  };
1292
872
  var sharedFormatter = new ToolOutputFormatter();
@@ -1315,12 +895,15 @@ function calculateContextBudget(messages) {
1315
895
  const maxK = Math.round(maxChars / 1e3);
1316
896
  return `<context_budget>${percent}% (${usedK}K/${maxK}K chars)</context_budget>`;
1317
897
  }
1318
- async function buildInitialState(repoRoot, query, provider) {
898
+ async function buildInitialState(repoRoot, query, provider, options) {
899
+ const budget = calculateContextBudget([]);
900
+ const turnTag = `Turn 0/${AGENT_CONFIG.MAX_TURNS}`;
901
+ const treeDepth = options?.query_type === "node_modules" ? 1 : 2;
1319
902
  try {
1320
903
  const entries = await provider.listDirectory({
1321
904
  path: ".",
1322
905
  maxResults: AGENT_CONFIG.MAX_OUTPUT_LINES,
1323
- maxDepth: 2
906
+ maxDepth: treeDepth
1324
907
  });
1325
908
  const treeLines = entries.map((e) => {
1326
909
  const indent = " ".repeat(e.depth);
@@ -1336,7 +919,9 @@ ${treeOutput}
1336
919
 
1337
920
  <search_string>
1338
921
  ${query}
1339
- </search_string>`;
922
+ </search_string>
923
+ ${budget}
924
+ ${turnTag}`;
1340
925
  } catch {
1341
926
  const repoName = import_path.default.basename(repoRoot);
1342
927
  return `<repo_structure>
@@ -1345,7 +930,9 @@ ${repoName}/
1345
930
 
1346
931
  <search_string>
1347
932
  ${query}
1348
- </search_string>`;
933
+ </search_string>
934
+ ${budget}
935
+ ${turnTag}`;
1349
936
  }
1350
937
  }
1351
938
  function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS) {
@@ -1381,7 +968,7 @@ var import_openai = __toESM(require("openai"), 1);
1381
968
  // package.json
1382
969
  var package_default = {
1383
970
  name: "@morphllm/morphsdk",
1384
- version: "0.2.125",
971
+ version: "0.2.127",
1385
972
  description: "TypeScript SDK and CLI for Morph Fast Apply integration",
1386
973
  type: "module",
1387
974
  main: "./dist/index.cjs",
@@ -1523,7 +1110,7 @@ var package_default = {
1523
1110
  "!dist/**/*.test.*"
1524
1111
  ],
1525
1112
  scripts: {
1526
- build: "tsup version.ts index.ts edge.ts client.ts tools/index.ts tools/fastapply/index.ts tools/fastapply/core.ts tools/fastapply/apply.ts tools/fastapply/types.ts tools/fastapply/prompts.ts tools/fastapply/anthropic.ts tools/fastapply/openai.ts tools/fastapply/vercel.ts tools/codebase_search/index.ts tools/codebase_search/core.ts tools/codebase_search/types.ts tools/codebase_search/prompts.ts tools/codebase_search/anthropic.ts tools/codebase_search/openai.ts tools/codebase_search/vercel.ts tools/warp_grep/index.ts tools/warp_grep/client.ts tools/warp_grep/openai.ts tools/warp_grep/anthropic.ts tools/warp_grep/vercel.ts tools/warp_grep/gemini.ts tools/warp_grep/harness.ts tools/warp_grep/agent/config.ts tools/warp_grep/agent/prompt.ts tools/warp_grep/agent/parser.ts tools/warp_grep/agent/runner.ts tools/warp_grep/agent/types.ts tools/warp_grep/agent/formatter.ts tools/warp_grep/providers/types.ts tools/warp_grep/providers/local.ts tools/warp_grep/providers/remote.ts tools/warp_grep/providers/code_storage_http.ts tools/warp_grep/tools/grep.ts tools/warp_grep/tools/analyse.ts tools/warp_grep/tools/read.ts tools/warp_grep/tools/finish.ts tools/warp_grep/utils/paths.ts tools/warp_grep/utils/github.ts tools/warp_grep/utils/ripgrep.ts tools/warp_grep/utils/format.ts tools/warp_grep/utils/files.ts git/index.ts git/client.ts git/config.ts git/types.ts tools/browser/index.ts tools/browser/core.ts tools/browser/types.ts tools/browser/prompts.ts tools/browser/anthropic.ts tools/browser/openai.ts tools/browser/vercel.ts tools/browser/live.ts tools/browser/errors.ts tools/browser/profiles/index.ts tools/browser/profiles/core.ts tools/browser/profiles/types.ts modelrouter/index.ts modelrouter/core.ts modelrouter/types.ts tools/compact/index.ts tools/compact/core.ts tools/compact/types.ts tools/utils/resilience.ts --format esm,cjs --sourcemap --clean --dts --dts-resolve",
1113
+ build: "tsup version.ts index.ts edge.ts client.ts tools/index.ts tools/fastapply/index.ts tools/fastapply/core.ts tools/fastapply/apply.ts tools/fastapply/types.ts tools/fastapply/prompts.ts tools/fastapply/anthropic.ts tools/fastapply/openai.ts tools/fastapply/vercel.ts tools/codebase_search/index.ts tools/codebase_search/core.ts tools/codebase_search/types.ts tools/codebase_search/prompts.ts tools/codebase_search/anthropic.ts tools/codebase_search/openai.ts tools/codebase_search/vercel.ts tools/warp_grep/index.ts tools/warp_grep/client.ts tools/warp_grep/openai.ts tools/warp_grep/anthropic.ts tools/warp_grep/vercel.ts tools/warp_grep/gemini.ts tools/warp_grep/harness.ts tools/warp_grep/agent/config.ts tools/warp_grep/agent/parser.ts tools/warp_grep/agent/runner.ts tools/warp_grep/agent/types.ts tools/warp_grep/agent/formatter.ts tools/warp_grep/providers/types.ts tools/warp_grep/providers/local.ts tools/warp_grep/providers/remote.ts tools/warp_grep/providers/code_storage_http.ts tools/warp_grep/tools/grep.ts tools/warp_grep/tools/analyse.ts tools/warp_grep/tools/read.ts tools/warp_grep/tools/finish.ts tools/warp_grep/utils/paths.ts tools/warp_grep/utils/github.ts tools/warp_grep/utils/ripgrep.ts tools/warp_grep/utils/format.ts tools/warp_grep/utils/files.ts git/index.ts git/client.ts git/config.ts git/types.ts tools/browser/index.ts tools/browser/core.ts tools/browser/types.ts tools/browser/prompts.ts tools/browser/anthropic.ts tools/browser/openai.ts tools/browser/vercel.ts tools/browser/live.ts tools/browser/errors.ts tools/browser/profiles/index.ts tools/browser/profiles/core.ts tools/browser/profiles/types.ts modelrouter/index.ts modelrouter/core.ts modelrouter/types.ts tools/compact/index.ts tools/compact/core.ts tools/compact/types.ts tools/utils/resilience.ts --format esm,cjs --sourcemap --clean --dts --dts-resolve",
1527
1114
  prepare: "npm run build",
1528
1115
  typecheck: "tsc --noEmit",
1529
1116
  lint: "eslint .",
@@ -1660,14 +1247,13 @@ async function runWarpGrep(config) {
1660
1247
  const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
1661
1248
  const timings = { turns: [], timeout_ms: timeoutMs };
1662
1249
  const repoRoot = import_path2.default.resolve(config.repoRoot || process.cwd());
1250
+ const model = config.model || DEFAULT_MODEL;
1663
1251
  const messages = [];
1664
- messages.push({ role: "system", content: getSystemPrompt() });
1252
+ const maxTurns = AGENT_CONFIG.MAX_TURNS;
1665
1253
  const initialStateStart = Date.now();
1666
- const initialState = await buildInitialState(repoRoot, config.query, config.provider);
1254
+ const initialState = await buildInitialState(repoRoot, config.query, config.provider, { query_type: config.query_type });
1667
1255
  timings.initial_state_ms = Date.now() - initialStateStart;
1668
1256
  messages.push({ role: "user", content: initialState });
1669
- const maxTurns = AGENT_CONFIG.MAX_TURNS;
1670
- const model = config.model || DEFAULT_MODEL;
1671
1257
  const provider = config.provider;
1672
1258
  const errors = [];
1673
1259
  let finishMeta;
@@ -1717,7 +1303,7 @@ async function runWarpGrep(config) {
1717
1303
  const args = c.arguments ?? {};
1718
1304
  allPromises.push(
1719
1305
  toolGrep(provider, args).then(
1720
- ({ output }) => formatAgentToolOutput("grep", args, output, { isError: false }),
1306
+ ({ output }) => formatAgentToolOutput("grep", args, output),
1721
1307
  (err) => formatAgentToolOutput("grep", args, String(err), { isError: true })
1722
1308
  )
1723
1309
  );
@@ -1726,7 +1312,7 @@ async function runWarpGrep(config) {
1726
1312
  const args = c.arguments ?? {};
1727
1313
  allPromises.push(
1728
1314
  toolListDirectory(provider, args).then(
1729
- (p) => formatAgentToolOutput("list_directory", args, p, { isError: false }),
1315
+ (p) => formatAgentToolOutput("list_directory", args, p),
1730
1316
  (err) => formatAgentToolOutput("list_directory", args, String(err), { isError: true })
1731
1317
  )
1732
1318
  );
@@ -1735,7 +1321,7 @@ async function runWarpGrep(config) {
1735
1321
  const args = c.arguments ?? {};
1736
1322
  allPromises.push(
1737
1323
  toolRead(provider, args).then(
1738
- (p) => formatAgentToolOutput("read", args, p, { isError: false }),
1324
+ (p) => formatAgentToolOutput("read", args, p),
1739
1325
  (err) => formatAgentToolOutput("read", args, String(err), { isError: true })
1740
1326
  )
1741
1327
  );
@@ -1819,14 +1405,13 @@ async function* runWarpGrepStreaming(config) {
1819
1405
  const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
1820
1406
  const timings = { turns: [], timeout_ms: timeoutMs };
1821
1407
  const repoRoot = import_path2.default.resolve(config.repoRoot || process.cwd());
1408
+ const model = config.model || DEFAULT_MODEL;
1822
1409
  const messages = [];
1823
- messages.push({ role: "system", content: getSystemPrompt() });
1410
+ const maxTurns = AGENT_CONFIG.MAX_TURNS;
1824
1411
  const initialStateStart = Date.now();
1825
- const initialState = await buildInitialState(repoRoot, config.query, config.provider);
1412
+ const initialState = await buildInitialState(repoRoot, config.query, config.provider, { query_type: config.query_type });
1826
1413
  timings.initial_state_ms = Date.now() - initialStateStart;
1827
1414
  messages.push({ role: "user", content: initialState });
1828
- const maxTurns = AGENT_CONFIG.MAX_TURNS;
1829
- const model = config.model || DEFAULT_MODEL;
1830
1415
  const provider = config.provider;
1831
1416
  const errors = [];
1832
1417
  let finishMeta;
@@ -1883,7 +1468,7 @@ async function* runWarpGrepStreaming(config) {
1883
1468
  const args = c.arguments ?? {};
1884
1469
  allPromises.push(
1885
1470
  toolGrep(provider, args).then(
1886
- ({ output }) => formatAgentToolOutput("grep", args, output, { isError: false }),
1471
+ ({ output }) => formatAgentToolOutput("grep", args, output),
1887
1472
  (err) => formatAgentToolOutput("grep", args, String(err), { isError: true })
1888
1473
  )
1889
1474
  );
@@ -1892,7 +1477,7 @@ async function* runWarpGrepStreaming(config) {
1892
1477
  const args = c.arguments ?? {};
1893
1478
  allPromises.push(
1894
1479
  toolListDirectory(provider, args).then(
1895
- (p) => formatAgentToolOutput("list_directory", args, p, { isError: false }),
1480
+ (p) => formatAgentToolOutput("list_directory", args, p),
1896
1481
  (err) => formatAgentToolOutput("list_directory", args, String(err), { isError: true })
1897
1482
  )
1898
1483
  );
@@ -1901,7 +1486,7 @@ async function* runWarpGrepStreaming(config) {
1901
1486
  const args = c.arguments ?? {};
1902
1487
  allPromises.push(
1903
1488
  toolRead(provider, args).then(
1904
- (p) => formatAgentToolOutput("read", args, p, { isError: false }),
1489
+ (p) => formatAgentToolOutput("read", args, p),
1905
1490
  (err) => formatAgentToolOutput("read", args, String(err), { isError: true })
1906
1491
  )
1907
1492
  );
@@ -2079,10 +1664,9 @@ var RemoteCommandsProvider = class {
2079
1664
  const stdout = await this.commands.grep(params.pattern, params.path, params.glob);
2080
1665
  const lines = (stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
2081
1666
  if (lines.length > AGENT_CONFIG.MAX_OUTPUT_LINES) {
2082
- return {
2083
- lines: [],
2084
- error: "Query not specific enough - too many results returned. Try a more specific pattern."
2085
- };
1667
+ const truncated = lines.slice(0, AGENT_CONFIG.MAX_OUTPUT_LINES);
1668
+ truncated.push(`... (output truncated at ${AGENT_CONFIG.MAX_OUTPUT_LINES} of ${lines.length} lines)`);
1669
+ return { lines: truncated };
2086
1670
  }
2087
1671
  return { lines };
2088
1672
  } catch (error) {
@@ -2112,7 +1696,7 @@ var RemoteCommandsProvider = class {
2112
1696
  const lines = contentLines.map((content, idx) => `${start + idx}|${content}`);
2113
1697
  if (lines.length > AGENT_CONFIG.MAX_READ_LINES) {
2114
1698
  const truncated = lines.slice(0, AGENT_CONFIG.MAX_READ_LINES);
2115
- truncated.push(`... [truncated: showing ${AGENT_CONFIG.MAX_READ_LINES} of ${lines.length} lines]`);
1699
+ truncated.push(`... (output truncated at ${AGENT_CONFIG.MAX_READ_LINES} of ${lines.length} lines)`);
2116
1700
  return { lines: truncated };
2117
1701
  }
2118
1702
  return { lines };
@@ -2469,7 +2053,7 @@ function formatResult(result) {
2469
2053
  var WARP_GREP_TOOL_NAME = "warpgrep_codebase_search";
2470
2054
  var WARP_GREP_DESCRIPTION = 'IMPORTANT: If you need to explore the codebase to gather context, and the task does not involve a single file or function which is provided by name, you should ALWAYS use the warpgrep codebase search tool first instead of running search commands. When the task requires exploration beyond a single known file, invoke warpgrep first with a natural-language query describing the target functionality, bug, or architectural concern. Warp Grep is a fast and accurate tool that can search for all relevant context in a codebase. Keep queries action-oriented (e.g., "Find where billing invoices are generated and emailed"), and after reviewing the summarized results, you may verify important findings with other search tools or direct file reads to ensure completeness. Warp Grep can be used for query types like: find function responsible for <small feature>; find code that does <description>; find code path for <big feature>; Where does <minimal error message> come from?; or any query of that type. When a task requires exploration beyond a single known file, ALWAYS default to warpgrep codebase search before other search mechanisms.';
2471
2055
  var GITHUB_WARP_GREP_SEARCH_TOOL_NAME = "warpgrep_github_search";
2472
- var GITHUB_WARP_GREP_SEARCH_DESCRIPTION = 'IMPORTANT: If you need to explore the codebase of a public GitHub repository (not your local workspace), use warpgrep_github_search instead of warpgrep_codebase_search. ONLY use this tool when the task requires understanding code in an external repo, and invoke warpgrep_github_search with a GitHub URL or owner/repo shorthand (e.g., vercel/next.js) and a natural-language query describing the target functionality, bug, or architectural concern. DO NOT use this tool when the task requires understanding code in your local workspace. Use warpgrep_codebase_search instead.Useful when you suspect a library or framework is being used in a way that is not documented, or if you suspect an update or a bug in the library or framework.WarpGrep searches GitHub repos the same way it searches local codebases: fast and accurate. Keep queries action-oriented (e.g., "Find where how the new use workflow directive works"), and after reviewing the results, you may verify important findings with other tools or direct file reads. WarpGrep can be used for query types like: find function responsible for <small feature>; find code that does <description>; find code path for <big feature>; Where does <minimal error message> come from?; or any query of that type. When a task involves exploring code in an external public repo, ALWAYS use warpgrep_github_search.';
2056
+ var GITHUB_WARP_GREP_SEARCH_DESCRIPTION = 'IMPORTANT: If you need to explore the codebase of a public GitHub repository (not your local workspace), use warpgrep_github_search instead of warpgrep_codebase_search. ONLY use this tool when the task requires understanding code in an external repo, and invoke warpgrep_github_search with a natural-language query describing the target functionality, bug, or architectural concern. DO NOT use this tool when the task requires understanding code in your local workspace. Use warpgrep_codebase_search instead.Useful when you suspect a library or framework is being used in a way that is not documented, or if you suspect an update or a bug in the library or framework.WarpGrep searches GitHub repos the same way it searches local codebases: fast and accurate. Keep queries action-oriented (e.g., "Find where how the new use workflow directive works"), and after reviewing the results, you may verify important findings with other tools or direct file reads. WarpGrep can be used for query types like: find function responsible for <small feature>; find code that does <description>; find code path for <big feature>; Where does <minimal error message> come from?; or any query of that type. When a task involves exploring code in an external public repo, ALWAYS use warpgrep_github_search. You must provide either a github_url or owner_repo parameter (at least one is required).';
2473
2057
  var GITHUB_SEARCH_TOOL_NAME = GITHUB_WARP_GREP_SEARCH_TOOL_NAME;
2474
2058
  var GITHUB_SEARCH_DESCRIPTION = GITHUB_WARP_GREP_SEARCH_DESCRIPTION;
2475
2059
  var GITHUB_READ_FILE_TOOL_NAME = "readfile_github_search";
@@ -2506,9 +2090,6 @@ function createWarpGrepTool(config) {
2506
2090
  },
2507
2091
  formatResult: (result) => {
2508
2092
  return formatResult(result);
2509
- },
2510
- getSystemPrompt: () => {
2511
- return getSystemPrompt();
2512
2093
  }
2513
2094
  });
2514
2095
  }
@@ -2517,10 +2098,11 @@ var GITHUB_SEARCH_PARAMETERS = {
2517
2098
  type: "OBJECT",
2518
2099
  properties: {
2519
2100
  query: { type: "STRING", description: "Natural language search query" },
2520
- github: { type: "STRING", description: 'GitHub URL or "owner/repo" shorthand' },
2101
+ github_url: { type: "STRING", description: 'GitHub repository URL to search (e.g. "https://github.com/vercel/next.js"). You must provide either github_url or owner_repo.' },
2102
+ owner_repo: { type: "STRING", description: 'Repository owner/repo shorthand (e.g. "vercel/next.js"). You must provide either github_url or owner_repo.' },
2521
2103
  branch: { type: "STRING", description: "Branch to search (defaults to repo default branch)" }
2522
2104
  },
2523
- required: ["query", "github"]
2105
+ required: ["query"]
2524
2106
  };
2525
2107
  function createGitHubSearchTool(config) {
2526
2108
  const client = new WarpGrepClient(config);
@@ -2531,13 +2113,14 @@ function createGitHubSearchTool(config) {
2531
2113
  };
2532
2114
  return Object.assign(declaration, {
2533
2115
  execute: async (input) => {
2534
- return client.searchGitHub(input);
2116
+ const github = input.github_url || input.owner_repo;
2117
+ if (!github) {
2118
+ throw new Error("Please provide github search url or owner/repo id");
2119
+ }
2120
+ return client.searchGitHub({ query: input.query, github, branch: input.branch });
2535
2121
  },
2536
2122
  formatResult: (result) => {
2537
2123
  return formatResult(result);
2538
- },
2539
- getSystemPrompt: () => {
2540
- return getSystemPrompt();
2541
2124
  }
2542
2125
  });
2543
2126
  }
@@ -2576,7 +2159,6 @@ var gemini_default = warpGrepFunctionDeclaration;
2576
2159
  createWarpGrepTool,
2577
2160
  execute,
2578
2161
  formatResult,
2579
- getSystemPrompt,
2580
2162
  warpGrepFunctionDeclaration
2581
2163
  });
2582
2164
  //# sourceMappingURL=gemini.cjs.map