@morphllm/morphsdk 0.2.125 → 0.2.126
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-BQO3WODX.js → chunk-37ZZ24IX.js} +3 -12
- package/dist/chunk-37ZZ24IX.js.map +1 -0
- package/dist/{chunk-OQGX4RZP.js → chunk-3NLCSADX.js} +2 -2
- package/dist/{chunk-UGSV5LPO.js → chunk-5CIUBER5.js} +2 -2
- package/dist/{chunk-2S7ZQFIB.js → chunk-6722FXFI.js} +2 -2
- package/dist/{chunk-FAZO2LNY.js → chunk-6Y2LHEJJ.js} +2 -2
- package/dist/{chunk-IRNUW2DB.js → chunk-76PPJZWV.js} +3 -12
- package/dist/chunk-76PPJZWV.js.map +1 -0
- package/dist/{chunk-5L3TPS6A.js → chunk-AXYGFPEJ.js} +1 -1
- package/dist/{chunk-5L3TPS6A.js.map → chunk-AXYGFPEJ.js.map} +1 -1
- package/dist/{chunk-TFK4UOUE.js → chunk-C26M3TWM.js} +6 -6
- package/dist/{chunk-TS3E6IRI.js → chunk-CPZKCBED.js} +2 -2
- package/dist/{chunk-33CP5QCC.js → chunk-CYVV5X5K.js} +3 -3
- package/dist/{chunk-33CP5QCC.js.map → chunk-CYVV5X5K.js.map} +1 -1
- package/dist/{chunk-5PNMAWLC.js → chunk-DKODF3YG.js} +2 -2
- package/dist/{chunk-5PNMAWLC.js.map → chunk-DKODF3YG.js.map} +1 -1
- package/dist/{chunk-IB4MEIQG.js → chunk-EB656RG6.js} +2 -2
- package/dist/{chunk-6TH3VNCF.js → chunk-FAH4YGRN.js} +3 -3
- package/dist/{chunk-DGYWACHC.js → chunk-GISRJI5P.js} +2 -2
- package/dist/{chunk-EF7ZYLA2.js → chunk-HZOTLGJH.js} +19 -12
- package/dist/chunk-HZOTLGJH.js.map +1 -0
- package/dist/{chunk-FEQJCZJQ.js → chunk-IYZX6EYC.js} +2 -2
- package/dist/{chunk-3MLWXJTJ.js → chunk-K2FXHDX2.js} +15 -10
- package/dist/chunk-K2FXHDX2.js.map +1 -0
- package/dist/{chunk-F6HNFC2H.js → chunk-K6GLBQBV.js} +2 -2
- package/dist/{chunk-57PXQ6IS.js → chunk-KJVFYRXY.js} +15 -15
- package/dist/{chunk-2MK64KK4.js → chunk-KUABSLVR.js} +2 -2
- package/dist/{chunk-PUGSTXLO.js → chunk-NF2QWJDY.js} +6 -7
- package/dist/chunk-NF2QWJDY.js.map +1 -0
- package/dist/{chunk-7RTJCQWB.js → chunk-QK5RNORE.js} +3 -3
- package/dist/chunk-QK5RNORE.js.map +1 -0
- package/dist/{chunk-V3HLOZK2.js → chunk-QLBRTLEI.js} +1 -1
- package/dist/{chunk-V3HLOZK2.js.map → chunk-QLBRTLEI.js.map} +1 -1
- package/dist/chunk-QRXG5CAZ.js +27 -0
- package/dist/chunk-QRXG5CAZ.js.map +1 -0
- package/dist/{chunk-ACHEU2V3.js → chunk-R74NP2D4.js} +2 -2
- package/dist/{chunk-H6KT7IXW.js → chunk-TREVNTLA.js} +2 -2
- package/dist/{chunk-G5YJDK5S.js → chunk-ULZOJQ2W.js} +2 -2
- package/dist/chunk-VCKJ22DX.js +131 -0
- package/dist/chunk-VCKJ22DX.js.map +1 -0
- package/dist/{chunk-WZAZFW77.js → chunk-VYJUGQUR.js} +1 -1
- package/dist/{chunk-OFQRY3RM.js → chunk-W7WUZMKZ.js} +18 -23
- package/dist/chunk-W7WUZMKZ.js.map +1 -0
- package/dist/{chunk-BGL35LL6.js → chunk-YHZRHPJI.js} +2 -2
- package/dist/{client-JHPwle1Z.d.ts → client-s3_iDem0.d.ts} +0 -4
- package/dist/client.cjs +145 -572
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +1 -2
- package/dist/client.js +27 -28
- package/dist/edge.cjs +2 -2
- package/dist/edge.cjs.map +1 -1
- package/dist/edge.js +4 -4
- package/dist/{finish-pPJfB0uO.d.ts → finish-DBKuo8yj.d.ts} +2 -0
- package/dist/index.cjs +145 -572
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +29 -30
- package/dist/modelrouter/core.cjs +2 -2
- package/dist/modelrouter/core.cjs.map +1 -1
- package/dist/modelrouter/core.js +3 -3
- package/dist/modelrouter/index.cjs +2 -2
- package/dist/modelrouter/index.cjs.map +1 -1
- package/dist/modelrouter/index.js +3 -3
- package/dist/tools/browser/anthropic.cjs +2 -2
- package/dist/tools/browser/anthropic.cjs.map +1 -1
- package/dist/tools/browser/anthropic.js +5 -5
- package/dist/tools/browser/core.cjs +2 -2
- package/dist/tools/browser/core.cjs.map +1 -1
- package/dist/tools/browser/core.js +4 -4
- package/dist/tools/browser/index.cjs +2 -2
- package/dist/tools/browser/index.cjs.map +1 -1
- package/dist/tools/browser/index.js +7 -7
- package/dist/tools/browser/openai.cjs +2 -2
- package/dist/tools/browser/openai.cjs.map +1 -1
- package/dist/tools/browser/openai.js +5 -5
- package/dist/tools/browser/profiles/core.cjs +2 -2
- package/dist/tools/browser/profiles/core.cjs.map +1 -1
- package/dist/tools/browser/profiles/core.js +3 -3
- package/dist/tools/browser/profiles/index.cjs +2 -2
- package/dist/tools/browser/profiles/index.cjs.map +1 -1
- package/dist/tools/browser/profiles/index.js +3 -3
- package/dist/tools/browser/vercel.cjs +2 -2
- package/dist/tools/browser/vercel.cjs.map +1 -1
- package/dist/tools/browser/vercel.js +5 -5
- package/dist/tools/codebase_search/anthropic.cjs +2 -2
- package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
- package/dist/tools/codebase_search/anthropic.js +4 -4
- package/dist/tools/codebase_search/core.cjs +2 -2
- package/dist/tools/codebase_search/core.cjs.map +1 -1
- package/dist/tools/codebase_search/core.js +3 -3
- package/dist/tools/codebase_search/index.cjs +2 -2
- package/dist/tools/codebase_search/index.cjs.map +1 -1
- package/dist/tools/codebase_search/index.js +6 -6
- package/dist/tools/codebase_search/openai.cjs +2 -2
- package/dist/tools/codebase_search/openai.cjs.map +1 -1
- package/dist/tools/codebase_search/openai.js +4 -4
- package/dist/tools/codebase_search/vercel.cjs +2 -2
- package/dist/tools/codebase_search/vercel.cjs.map +1 -1
- package/dist/tools/codebase_search/vercel.js +4 -4
- package/dist/tools/fastapply/anthropic.cjs +2 -2
- package/dist/tools/fastapply/anthropic.cjs.map +1 -1
- package/dist/tools/fastapply/anthropic.js +4 -4
- package/dist/tools/fastapply/apply.cjs +2 -2
- package/dist/tools/fastapply/apply.cjs.map +1 -1
- package/dist/tools/fastapply/apply.js +2 -2
- package/dist/tools/fastapply/core.cjs +2 -2
- package/dist/tools/fastapply/core.cjs.map +1 -1
- package/dist/tools/fastapply/core.js +3 -3
- package/dist/tools/fastapply/index.cjs +2 -2
- package/dist/tools/fastapply/index.cjs.map +1 -1
- package/dist/tools/fastapply/index.js +6 -6
- package/dist/tools/fastapply/openai.cjs +2 -2
- package/dist/tools/fastapply/openai.cjs.map +1 -1
- package/dist/tools/fastapply/openai.js +4 -4
- package/dist/tools/fastapply/vercel.cjs +2 -2
- package/dist/tools/fastapply/vercel.cjs.map +1 -1
- package/dist/tools/fastapply/vercel.js +4 -4
- package/dist/tools/index.cjs +2 -2
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.js +6 -6
- package/dist/tools/utils/resilience.cjs +2 -2
- package/dist/tools/utils/resilience.cjs.map +1 -1
- package/dist/tools/utils/resilience.js +2 -2
- package/dist/tools/warp_grep/agent/config.cjs +1 -1
- package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/config.d.ts +1 -1
- package/dist/tools/warp_grep/agent/config.js +1 -1
- package/dist/tools/warp_grep/agent/formatter.cjs +3 -74
- package/dist/tools/warp_grep/agent/formatter.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/formatter.d.ts +1 -5
- package/dist/tools/warp_grep/agent/formatter.js +1 -1
- package/dist/tools/warp_grep/agent/parser.cjs +91 -242
- package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/parser.d.ts +0 -8
- package/dist/tools/warp_grep/agent/parser.js +1 -1
- package/dist/tools/warp_grep/agent/runner.cjs +122 -543
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.js +6 -7
- package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/types.d.ts +2 -0
- package/dist/tools/warp_grep/anthropic.cjs +143 -566
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.d.ts +0 -3
- package/dist/tools/warp_grep/anthropic.js +11 -15
- package/dist/tools/warp_grep/client.cjs +143 -558
- package/dist/tools/warp_grep/client.cjs.map +1 -1
- package/dist/tools/warp_grep/client.js +9 -10
- package/dist/tools/warp_grep/gemini.cjs +143 -566
- package/dist/tools/warp_grep/gemini.cjs.map +1 -1
- package/dist/tools/warp_grep/gemini.d.ts +0 -3
- package/dist/tools/warp_grep/gemini.js +10 -20
- package/dist/tools/warp_grep/gemini.js.map +1 -1
- package/dist/tools/warp_grep/harness.cjs +124 -540
- package/dist/tools/warp_grep/harness.cjs.map +1 -1
- package/dist/tools/warp_grep/harness.d.ts +4 -5
- package/dist/tools/warp_grep/harness.js +5 -11
- package/dist/tools/warp_grep/harness.js.map +1 -1
- package/dist/tools/warp_grep/index.cjs +143 -562
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.d.ts +1 -2
- package/dist/tools/warp_grep/index.js +14 -20
- package/dist/tools/warp_grep/openai.cjs +143 -566
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.d.ts +0 -3
- package/dist/tools/warp_grep/openai.js +11 -15
- package/dist/tools/warp_grep/providers/local.cjs +17 -10
- package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/local.d.ts +6 -1
- package/dist/tools/warp_grep/providers/local.js +2 -2
- package/dist/tools/warp_grep/providers/remote.cjs +4 -5
- package/dist/tools/warp_grep/providers/remote.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/remote.js +2 -2
- package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/types.d.ts +2 -0
- package/dist/tools/warp_grep/vercel.cjs +143 -560
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.d.ts +0 -1
- package/dist/tools/warp_grep/vercel.js +11 -15
- package/dist/version.cjs +2 -2
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-3MLWXJTJ.js.map +0 -1
- package/dist/chunk-7RTJCQWB.js.map +0 -1
- package/dist/chunk-APP75CBN.js +0 -98
- package/dist/chunk-APP75CBN.js.map +0 -1
- package/dist/chunk-BQO3WODX.js.map +0 -1
- package/dist/chunk-EF7ZYLA2.js.map +0 -1
- package/dist/chunk-FMLHRJDF.js +0 -207
- package/dist/chunk-FMLHRJDF.js.map +0 -1
- package/dist/chunk-GHGJAQSJ.js +0 -282
- package/dist/chunk-GHGJAQSJ.js.map +0 -1
- package/dist/chunk-IRNUW2DB.js.map +0 -1
- package/dist/chunk-OFQRY3RM.js.map +0 -1
- package/dist/chunk-PUGSTXLO.js.map +0 -1
- package/dist/tools/warp_grep/agent/prompt.cjs +0 -232
- package/dist/tools/warp_grep/agent/prompt.cjs.map +0 -1
- package/dist/tools/warp_grep/agent/prompt.d.ts +0 -4
- package/dist/tools/warp_grep/agent/prompt.js +0 -10
- package/dist/tools/warp_grep/agent/prompt.js.map +0 -1
- /package/dist/{chunk-OQGX4RZP.js.map → chunk-3NLCSADX.js.map} +0 -0
- /package/dist/{chunk-UGSV5LPO.js.map → chunk-5CIUBER5.js.map} +0 -0
- /package/dist/{chunk-2S7ZQFIB.js.map → chunk-6722FXFI.js.map} +0 -0
- /package/dist/{chunk-FAZO2LNY.js.map → chunk-6Y2LHEJJ.js.map} +0 -0
- /package/dist/{chunk-TFK4UOUE.js.map → chunk-C26M3TWM.js.map} +0 -0
- /package/dist/{chunk-TS3E6IRI.js.map → chunk-CPZKCBED.js.map} +0 -0
- /package/dist/{chunk-IB4MEIQG.js.map → chunk-EB656RG6.js.map} +0 -0
- /package/dist/{chunk-6TH3VNCF.js.map → chunk-FAH4YGRN.js.map} +0 -0
- /package/dist/{chunk-DGYWACHC.js.map → chunk-GISRJI5P.js.map} +0 -0
- /package/dist/{chunk-FEQJCZJQ.js.map → chunk-IYZX6EYC.js.map} +0 -0
- /package/dist/{chunk-F6HNFC2H.js.map → chunk-K6GLBQBV.js.map} +0 -0
- /package/dist/{chunk-57PXQ6IS.js.map → chunk-KJVFYRXY.js.map} +0 -0
- /package/dist/{chunk-2MK64KK4.js.map → chunk-KUABSLVR.js.map} +0 -0
- /package/dist/{chunk-ACHEU2V3.js.map → chunk-R74NP2D4.js.map} +0 -0
- /package/dist/{chunk-H6KT7IXW.js.map → chunk-TREVNTLA.js.map} +0 -0
- /package/dist/{chunk-G5YJDK5S.js.map → chunk-ULZOJQ2W.js.map} +0 -0
- /package/dist/{chunk-WZAZFW77.js.map → chunk-VYJUGQUR.js.map} +0 -0
- /package/dist/{chunk-BGL35LL6.js.map → chunk-YHZRHPJI.js.map} +0 -0
|
@@ -131,485 +131,132 @@ var BUILTIN_EXCLUDES = [
|
|
|
131
131
|
".*"
|
|
132
132
|
];
|
|
133
133
|
var DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || "").split(",").map((s) => s.trim()).filter(Boolean).concat(BUILTIN_EXCLUDES);
|
|
134
|
-
var DEFAULT_MODEL = "morph-warp-grep-
|
|
135
|
-
|
|
136
|
-
// tools/warp_grep/agent/prompt.ts
|
|
137
|
-
var SYSTEM_PROMPT = `You are a code search agent. Your task is to find all relevant code for a given search_string.
|
|
138
|
-
|
|
139
|
-
### workflow
|
|
140
|
-
You have exactly 4 turns. The 4th turn MUST be a \`finish\` call. Each turn allows up to 8 parallel tool calls.
|
|
141
|
-
|
|
142
|
-
- Turn 1: Map the territory OR dive deep (based on search_string specificity)
|
|
143
|
-
- Turn 2-3: Refine based on findings
|
|
144
|
-
- Turn 4: MUST call \`finish\` with all relevant code locations
|
|
145
|
-
- You MAY call \`finish\` early if confident\u2014but never before at least 1 search turn.
|
|
146
|
-
- The user strongly prefers if you can call the finish tool early, but you must be correct
|
|
147
|
-
|
|
148
|
-
Remember, if the task feels easy to you, it is strongly desirable to call 'finish' early using fewer turns, but quality over speed
|
|
149
|
-
|
|
150
|
-
### tools
|
|
151
|
-
Tool calls use nested XML elements:
|
|
152
|
-
\`\`\`xml
|
|
153
|
-
<tool_name>
|
|
154
|
-
<parameter>value</parameter>
|
|
155
|
-
</tool_name>
|
|
156
|
-
\`\`\`
|
|
157
|
-
|
|
158
|
-
### \`list_directory\`
|
|
159
|
-
Directory tree view. Shows structure of a path, optionally filtered by regex pattern.
|
|
160
|
-
|
|
161
|
-
Elements:
|
|
162
|
-
- \`<path>\` (required): Directory path to list (use \`.\` for repo root)
|
|
163
|
-
- \`<pattern>\` (optional): Regex to filter results
|
|
164
|
-
|
|
165
|
-
Examples:
|
|
166
|
-
\`\`\`
|
|
167
|
-
<list_directory>
|
|
168
|
-
<path>src/services</path>
|
|
169
|
-
</list_directory>
|
|
170
|
-
|
|
171
|
-
<list_directory>
|
|
172
|
-
<path>lib/utils</path>
|
|
173
|
-
<pattern>.*\\.(ts|js)$</pattern>
|
|
174
|
-
</list_directory>
|
|
175
|
-
\`\`\`
|
|
176
|
-
|
|
177
|
-
### \`read\`
|
|
178
|
-
Read file contents. Supports multiple line ranges.
|
|
179
|
-
- Returns numbered lines for easy reference
|
|
180
|
-
- ALWAYS include import statements (usually lines 1-20). Better to over-include than miss context.
|
|
181
|
-
|
|
182
|
-
Elements:
|
|
183
|
-
- \`<path>\` (required): File path to read
|
|
184
|
-
- \`<lines>\` (optional): Line ranges like "1-50,75-80,100-120" (omit to read entire file)
|
|
185
|
-
|
|
186
|
-
Examples:
|
|
187
|
-
\`\`\`
|
|
188
|
-
<read>
|
|
189
|
-
<path>src/main.py</path>
|
|
190
|
-
</read>
|
|
191
|
-
|
|
192
|
-
<read>
|
|
193
|
-
<path>src/auth.py</path>
|
|
194
|
-
<lines>1-20,45-80,150-200</lines>
|
|
195
|
-
</read>
|
|
196
|
-
\`\`\`
|
|
197
|
-
|
|
198
|
-
### \`grep\`
|
|
199
|
-
Search for pattern matches across files. Returns matches with 1 line of context above and below.
|
|
200
|
-
- Match lines use \`:\` separator \u2192 \`filepath:linenum:content\`
|
|
201
|
-
- Context lines use \`-\` separator \u2192 \`filepath-linenum-content\`
|
|
202
|
-
|
|
203
|
-
Elements:
|
|
204
|
-
- \`<pattern>\` (required): Search pattern (regex). Use \`(a|b)\` for OR patterns.
|
|
205
|
-
- \`<sub_dir>\` (optional): Subdirectory to search in (defaults to \`.\`)
|
|
206
|
-
- \`<glob>\` (optional): File pattern filter like \`*.py\` or \`*.{ts,tsx}\`
|
|
207
|
-
|
|
208
|
-
Examples:
|
|
209
|
-
\`\`\`
|
|
210
|
-
<grep>
|
|
211
|
-
<pattern>(authenticate|authorize|login)</pattern>
|
|
212
|
-
<sub_dir>src/auth/</sub_dir>
|
|
213
|
-
</grep>
|
|
214
|
-
|
|
215
|
-
<grep>
|
|
216
|
-
<pattern>class.*(Service|Controller)</pattern>
|
|
217
|
-
<glob>*.{ts,js}</glob>
|
|
218
|
-
</grep>
|
|
219
|
-
|
|
220
|
-
<grep>
|
|
221
|
-
<pattern>(DB_HOST|DATABASE_URL|connection)</pattern>
|
|
222
|
-
<glob>*.{py,yaml,env}</glob>
|
|
223
|
-
<sub_dir>lib/</sub_dir>
|
|
224
|
-
</grep>
|
|
225
|
-
\`\`\`
|
|
226
|
-
|
|
227
|
-
### \`finish\`
|
|
228
|
-
Submit final answer with all relevant code locations. Uses nested \`<file>\` elements.
|
|
229
|
-
|
|
230
|
-
File elements:
|
|
231
|
-
- \`<path>\` (required): File path
|
|
232
|
-
- \`<lines>\` (optional): Line ranges like "1-50,75-80" (\`*\` for entire file)
|
|
233
|
-
|
|
234
|
-
ALWAYS include import statements (usually lines 1-20). Better to over-include than miss context.
|
|
235
|
-
|
|
236
|
-
Examples:
|
|
237
|
-
\`\`\`
|
|
238
|
-
<finish>
|
|
239
|
-
<file>
|
|
240
|
-
<path>src/auth.py</path>
|
|
241
|
-
<lines>1-15,25-50,75-80</lines>
|
|
242
|
-
</file>
|
|
243
|
-
<file>
|
|
244
|
-
<path>src/models/user.py</path>
|
|
245
|
-
<lines>*</lines>
|
|
246
|
-
</file>
|
|
247
|
-
</finish>
|
|
248
|
-
\`\`\`
|
|
249
|
-
</tools>
|
|
250
|
-
|
|
251
|
-
<strategy>
|
|
252
|
-
**Before your first tool call, classify the search_string:**
|
|
253
|
-
|
|
254
|
-
| Search_string Type | Round 1 Strategy | Early Finish? |
|
|
255
|
-
|------------|------------------|---------------|
|
|
256
|
-
| **Specific** (function name, error string, unique identifier) | 8 parallel greps on likely paths | Often by round 2 |
|
|
257
|
-
| **Conceptual** (how does X work, where is Y handled) | list_directory + 2-3 broad greps | Rarely early |
|
|
258
|
-
| **Exploratory** (find all tests, list API endpoints) | list_directory at multiple depths | Usually needs 3 rounds |
|
|
259
|
-
|
|
260
|
-
**Parallel call patterns:**
|
|
261
|
-
- **Shotgun grep**: Same pattern, 8 different directories\u2014fast coverage
|
|
262
|
-
- **Variant grep**: 8 pattern variations (synonyms, naming conventions)\u2014catches inconsistent codebases
|
|
263
|
-
- **Funnel**: 1 list_directory + 7 greps\u2014orient and search simultaneously
|
|
264
|
-
- **Deep read**: 8 reads on files you already identified\u2014gather full context fast
|
|
265
|
-
|
|
266
|
-
**Tool call expectations:**
|
|
267
|
-
- 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.
|
|
268
|
-
- 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.
|
|
269
|
-
- 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.
|
|
270
|
-
- 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.
|
|
271
|
-
</strategy>
|
|
272
|
-
|
|
273
|
-
<output_format>
|
|
274
|
-
EVERY response MUST follow this exact format:
|
|
275
|
-
|
|
276
|
-
1. First, wrap your reasoning in \`<think>...</think>\` tags containing:
|
|
277
|
-
- Search_string classification (specific/conceptual/exploratory)
|
|
278
|
-
- Confidence estimate (can I finish in 1-2 rounds?)
|
|
279
|
-
- This round's parallel strategy
|
|
280
|
-
- What signals would let me finish early?
|
|
281
|
-
|
|
282
|
-
2. Then, output up to 8 tool calls using nested XML elements.
|
|
283
|
-
|
|
284
|
-
Example:
|
|
285
|
-
\`\`\`
|
|
286
|
-
<think>
|
|
287
|
-
This is a specific search_string about authentication. I'll grep for auth-related patterns.
|
|
288
|
-
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
|
|
289
|
-
Strategy: Shotgun grep across likely directories.
|
|
290
|
-
</think>
|
|
291
|
-
<grep>
|
|
292
|
-
<pattern>(authenticate|login|session)</pattern>
|
|
293
|
-
<sub_dir>src/auth/</sub_dir>
|
|
294
|
-
</grep>
|
|
295
|
-
<grep>
|
|
296
|
-
<pattern>(middleware|interceptor)</pattern>
|
|
297
|
-
<glob>*.{ts,js}</glob>
|
|
298
|
-
</grep>
|
|
299
|
-
<list_directory>
|
|
300
|
-
<path>src/auth</path>
|
|
301
|
-
</list_directory>
|
|
302
|
-
\`\`\`
|
|
303
|
-
|
|
304
|
-
Finishing example:
|
|
305
|
-
\`\`\`
|
|
306
|
-
<think>
|
|
307
|
-
I think I have a rough idea, but this is my last turn so I must call the finish tool regardless.
|
|
308
|
-
</think>
|
|
309
|
-
<finish>
|
|
310
|
-
<file>
|
|
311
|
-
<path>src/auth/login.py</path>
|
|
312
|
-
<lines>1-50</lines>
|
|
313
|
-
</file>
|
|
314
|
-
<file>
|
|
315
|
-
<path>src/middleware/session.py</path>
|
|
316
|
-
<lines>10-80</lines>
|
|
317
|
-
</file>
|
|
318
|
-
</finish>
|
|
319
|
-
\`\`\`
|
|
320
|
-
|
|
321
|
-
No commentary outside \`<think>\`. No explanations after tool calls.
|
|
322
|
-
</output_format>
|
|
323
|
-
|
|
324
|
-
use as all 8 tool calls to be optimal
|
|
325
|
-
|
|
326
|
-
<finishing_requirements>
|
|
327
|
-
When calling \`finish\`:
|
|
328
|
-
- Include the import section (typically lines 1-20) of each file
|
|
329
|
-
- Include all function/class definitions that are relevant
|
|
330
|
-
- Include any type definitions, interfaces, or constants used
|
|
331
|
-
- Better to over-include than leave the user missing context
|
|
332
|
-
- If unsure about boundaries, include more rather than less
|
|
333
|
-
</finishing_requirements>`;
|
|
334
|
-
function getSystemPrompt() {
|
|
335
|
-
return SYSTEM_PROMPT;
|
|
336
|
-
}
|
|
134
|
+
var DEFAULT_MODEL = "morph-warp-grep-v2";
|
|
337
135
|
|
|
338
136
|
// tools/warp_grep/agent/parser.ts
|
|
339
|
-
var VALID_COMMANDS = ["list_directory", "
|
|
137
|
+
var VALID_COMMANDS = ["list_directory", "ripgrep", "read", "finish"];
|
|
340
138
|
function isValidCommand(name) {
|
|
341
139
|
return VALID_COMMANDS.includes(name);
|
|
342
140
|
}
|
|
343
|
-
function
|
|
344
|
-
const regex = new RegExp(`<${tagName}>([\\s\\S]*?)</${tagName}>`, "i");
|
|
345
|
-
const match = xml.match(regex);
|
|
346
|
-
return match ? match[1].trim() : null;
|
|
347
|
-
}
|
|
348
|
-
function parseNestedXmlTools(text) {
|
|
141
|
+
function parseQwen3ToolCalls(text) {
|
|
349
142
|
const tools = [];
|
|
350
|
-
const
|
|
143
|
+
const toolCallRegex = /<tool_call>\s*<function=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/function>\s*<\/tool_call>/gi;
|
|
351
144
|
let match;
|
|
352
|
-
while ((match =
|
|
353
|
-
const
|
|
354
|
-
const
|
|
355
|
-
if (!isValidCommand(
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
145
|
+
while ((match = toolCallRegex.exec(text)) !== null) {
|
|
146
|
+
const funcName = match[1].toLowerCase();
|
|
147
|
+
const body = match[2];
|
|
148
|
+
if (!isValidCommand(funcName)) continue;
|
|
149
|
+
const params = {};
|
|
150
|
+
const paramRegex = /<parameter=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/parameter>/gi;
|
|
151
|
+
let paramMatch;
|
|
152
|
+
while ((paramMatch = paramRegex.exec(body)) !== null) {
|
|
153
|
+
params[paramMatch[1].toLowerCase()] = paramMatch[2].trim();
|
|
154
|
+
}
|
|
155
|
+
if (funcName === "ripgrep") {
|
|
156
|
+
const pattern = params.pattern;
|
|
157
|
+
if (!pattern) continue;
|
|
158
|
+
const args = {
|
|
159
|
+
pattern,
|
|
160
|
+
path: params.path || ".",
|
|
161
|
+
...params.glob && { glob: params.glob },
|
|
162
|
+
...params.context_lines && { context_lines: parseInt(params.context_lines, 10) },
|
|
163
|
+
...params.case_sensitive && { case_sensitive: params.case_sensitive === "true" }
|
|
164
|
+
};
|
|
165
|
+
tools.push({ name: "grep", arguments: args });
|
|
166
|
+
} else if (funcName === "list_directory") {
|
|
167
|
+
const command = params.command;
|
|
168
|
+
const directPath = params.path;
|
|
169
|
+
let dirPath = directPath || ".";
|
|
170
|
+
if (!directPath && command) {
|
|
171
|
+
const tokens = command.trim().split(/\s+/);
|
|
172
|
+
const pathTokens = tokens.slice(1).filter((t) => !t.startsWith("-") && !t.startsWith("|") && !t.startsWith("\\("));
|
|
173
|
+
if (pathTokens.length > 0) {
|
|
174
|
+
dirPath = pathTokens[0];
|
|
175
|
+
}
|
|
362
176
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
177
|
+
tools.push({ name: "list_directory", arguments: { path: dirPath, pattern: params.pattern || null } });
|
|
178
|
+
} else if (funcName === "read") {
|
|
179
|
+
const filePath = params.path;
|
|
180
|
+
if (!filePath) continue;
|
|
181
|
+
const args = { path: filePath };
|
|
182
|
+
const linesStr = params.lines;
|
|
183
|
+
if (linesStr) {
|
|
184
|
+
const ranges = [];
|
|
185
|
+
for (const rangeStr of linesStr.split(",")) {
|
|
186
|
+
const trimmed = rangeStr.trim();
|
|
187
|
+
if (!trimmed) continue;
|
|
188
|
+
const [s, e] = trimmed.split("-").map((v) => parseInt(v.trim(), 10));
|
|
189
|
+
if (Number.isFinite(s) && Number.isFinite(e)) {
|
|
190
|
+
ranges.push([s, e]);
|
|
191
|
+
} else if (Number.isFinite(s)) {
|
|
192
|
+
ranges.push([s, s]);
|
|
374
193
|
}
|
|
375
|
-
}
|
|
194
|
+
}
|
|
195
|
+
if (ranges.length === 1) {
|
|
196
|
+
args.start = ranges[0][0];
|
|
197
|
+
args.end = ranges[0][1];
|
|
198
|
+
} else if (ranges.length > 1) {
|
|
199
|
+
args.lines = ranges;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
tools.push({ name: "read", arguments: args });
|
|
203
|
+
} else if (funcName === "finish") {
|
|
204
|
+
if (params.result && !params.files) {
|
|
205
|
+
tools.push({ name: "finish", arguments: { files: [], textResult: params.result } });
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const filesStr = params.files;
|
|
209
|
+
if (!filesStr) {
|
|
210
|
+
tools.push({ name: "finish", arguments: { files: [], textResult: "No relevant code found." } });
|
|
211
|
+
continue;
|
|
376
212
|
}
|
|
377
|
-
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
const
|
|
382
|
-
if (
|
|
213
|
+
const files = [];
|
|
214
|
+
for (const line of filesStr.split("\n")) {
|
|
215
|
+
const trimmed = line.trim();
|
|
216
|
+
if (!trimmed) continue;
|
|
217
|
+
const colonIdx = trimmed.indexOf(":");
|
|
218
|
+
if (colonIdx === -1) {
|
|
219
|
+
files.push({ path: trimmed, lines: "*" });
|
|
220
|
+
} else {
|
|
221
|
+
const filePath = trimmed.slice(0, colonIdx);
|
|
222
|
+
const rangesPart = trimmed.slice(colonIdx + 1);
|
|
383
223
|
const ranges = [];
|
|
384
|
-
for (const rangeStr of
|
|
385
|
-
const
|
|
386
|
-
if (!
|
|
387
|
-
|
|
224
|
+
for (const rangeStr of rangesPart.split(",")) {
|
|
225
|
+
const rt = rangeStr.trim();
|
|
226
|
+
if (!rt || rt === "*") {
|
|
227
|
+
files.push({ path: filePath, lines: "*" });
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
const [s, e] = rt.split("-").map((v) => parseInt(v.trim(), 10));
|
|
388
231
|
if (Number.isFinite(s) && Number.isFinite(e)) {
|
|
389
232
|
ranges.push([s, e]);
|
|
390
233
|
} else if (Number.isFinite(s)) {
|
|
391
234
|
ranges.push([s, s]);
|
|
392
235
|
}
|
|
393
236
|
}
|
|
394
|
-
if (ranges.length
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
} else if (ranges.length > 1) {
|
|
398
|
-
args.lines = ranges;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
tools.push({ name: "read", arguments: args });
|
|
402
|
-
}
|
|
403
|
-
} else if (toolName === "finish") {
|
|
404
|
-
const fileRegex = /<file>([\s\S]*?)<\/file>/gi;
|
|
405
|
-
const files = [];
|
|
406
|
-
let fileMatch;
|
|
407
|
-
while ((fileMatch = fileRegex.exec(content)) !== null) {
|
|
408
|
-
const fileContent = fileMatch[1];
|
|
409
|
-
const filePath = getXmlElementText(fileContent, "path");
|
|
410
|
-
const linesStr = getXmlElementText(fileContent, "lines");
|
|
411
|
-
if (filePath) {
|
|
412
|
-
if (!linesStr || linesStr.trim() === "*") {
|
|
237
|
+
if (ranges.length > 0) {
|
|
238
|
+
files.push({ path: filePath, lines: ranges });
|
|
239
|
+
} else if (!files.some((f) => f.path === filePath)) {
|
|
413
240
|
files.push({ path: filePath, lines: "*" });
|
|
414
|
-
} else {
|
|
415
|
-
const ranges = [];
|
|
416
|
-
for (const rangeStr of linesStr.split(",")) {
|
|
417
|
-
const [s, e] = rangeStr.split("-").map((v) => parseInt(v.trim(), 10));
|
|
418
|
-
if (Number.isFinite(s) && Number.isFinite(e)) {
|
|
419
|
-
ranges.push([s, e]);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
if (ranges.length > 0) {
|
|
423
|
-
files.push({ path: filePath, lines: ranges });
|
|
424
|
-
} else {
|
|
425
|
-
files.push({ path: filePath, lines: "*" });
|
|
426
|
-
}
|
|
427
241
|
}
|
|
428
242
|
}
|
|
429
243
|
}
|
|
430
244
|
if (files.length > 0) {
|
|
431
245
|
tools.push({ name: "finish", arguments: { files } });
|
|
432
246
|
} else {
|
|
433
|
-
|
|
434
|
-
const textResult = !raw || raw === "*" ? "No relevant code found." : raw;
|
|
435
|
-
tools.push({ name: "finish", arguments: { files: [], textResult } });
|
|
247
|
+
tools.push({ name: "finish", arguments: { files: [], textResult: filesStr } });
|
|
436
248
|
}
|
|
437
249
|
}
|
|
438
250
|
}
|
|
439
|
-
if (tools.length === 0) {
|
|
440
|
-
const fnFinishMatch = text.match(/<function=finish>([\s\S]*?)<\/function>/i);
|
|
441
|
-
if (fnFinishMatch) {
|
|
442
|
-
const inner = fnFinishMatch[1];
|
|
443
|
-
const paramMatch = inner.match(/<parameter=result>([\s\S]*?)<\/parameter>/i);
|
|
444
|
-
const raw = (paramMatch ? paramMatch[1] : inner).trim();
|
|
445
|
-
const textResult = !raw || raw === "*" ? "No relevant code found." : raw;
|
|
446
|
-
tools.push({ name: "finish", arguments: { files: [], textResult } });
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
251
|
return tools;
|
|
450
252
|
}
|
|
451
|
-
function preprocessText(text) {
|
|
452
|
-
const processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "").replace(/<\/?tool_call>/gi, "");
|
|
453
|
-
const nestedTools = parseNestedXmlTools(processed);
|
|
454
|
-
const toolCallLines = [];
|
|
455
|
-
const allLines = processed.split(/\r?\n/).map((l) => l.trim());
|
|
456
|
-
for (const line of allLines) {
|
|
457
|
-
if (!line) continue;
|
|
458
|
-
if (line.startsWith("<")) continue;
|
|
459
|
-
const firstWord = line.split(/\s/)[0];
|
|
460
|
-
if (VALID_COMMANDS.includes(firstWord)) {
|
|
461
|
-
if (!toolCallLines.includes(line)) {
|
|
462
|
-
toolCallLines.push(line);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
return { lines: toolCallLines, nestedTools };
|
|
467
|
-
}
|
|
468
253
|
var LLMResponseParser = class {
|
|
469
|
-
finishSpecSplitRe = /,(?=[^,\s]+:)/;
|
|
470
254
|
parse(text) {
|
|
471
255
|
if (typeof text !== "string") {
|
|
472
256
|
throw new TypeError("Command text must be a string.");
|
|
473
257
|
}
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
let finishAccumulator = null;
|
|
477
|
-
lines.forEach((line) => {
|
|
478
|
-
if (!line || line.startsWith("#")) return;
|
|
479
|
-
const parts = this.splitLine(line);
|
|
480
|
-
if (parts.length === 0) return;
|
|
481
|
-
const cmd = parts[0];
|
|
482
|
-
switch (cmd) {
|
|
483
|
-
case "list_directory":
|
|
484
|
-
this.handleListDirectory(parts, line, commands);
|
|
485
|
-
break;
|
|
486
|
-
case "grep":
|
|
487
|
-
this.handleGrep(parts, line, commands);
|
|
488
|
-
break;
|
|
489
|
-
case "read":
|
|
490
|
-
this.handleRead(parts, line, commands);
|
|
491
|
-
break;
|
|
492
|
-
case "finish":
|
|
493
|
-
finishAccumulator = this.handleFinish(parts, line, commands, finishAccumulator);
|
|
494
|
-
break;
|
|
495
|
-
default:
|
|
496
|
-
break;
|
|
497
|
-
}
|
|
498
|
-
});
|
|
499
|
-
if (finishAccumulator) {
|
|
500
|
-
const map = finishAccumulator;
|
|
501
|
-
const entries = [...map.entries()];
|
|
502
|
-
const filesPayload = entries.map(([path3, ranges]) => ({
|
|
503
|
-
path: path3,
|
|
504
|
-
lines: [...ranges].sort((a, b) => a[0] - b[0])
|
|
505
|
-
}));
|
|
506
|
-
commands.push({ name: "finish", arguments: { files: filesPayload } });
|
|
507
|
-
}
|
|
508
|
-
return commands;
|
|
509
|
-
}
|
|
510
|
-
splitLine(line) {
|
|
511
|
-
const parts = [];
|
|
512
|
-
let current = "";
|
|
513
|
-
let inSingle = false;
|
|
514
|
-
for (let i = 0; i < line.length; i++) {
|
|
515
|
-
const ch = line[i];
|
|
516
|
-
if (ch === "'" && line[i - 1] !== "\\") {
|
|
517
|
-
inSingle = !inSingle;
|
|
518
|
-
current += ch;
|
|
519
|
-
} else if (!inSingle && /\s/.test(ch)) {
|
|
520
|
-
if (current) {
|
|
521
|
-
parts.push(current);
|
|
522
|
-
current = "";
|
|
523
|
-
}
|
|
524
|
-
} else {
|
|
525
|
-
current += ch;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
if (current) parts.push(current);
|
|
529
|
-
return parts;
|
|
530
|
-
}
|
|
531
|
-
/** Helper to create a _skip tool call with an error message */
|
|
532
|
-
skip(message) {
|
|
533
|
-
return { name: "_skip", arguments: { message } };
|
|
534
|
-
}
|
|
535
|
-
handleListDirectory(parts, rawLine, commands) {
|
|
536
|
-
if (parts.length < 2) {
|
|
537
|
-
commands.push(this.skip(
|
|
538
|
-
`[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: list_directory <path> [pattern]. Example: list_directory src/`
|
|
539
|
-
));
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
const path3 = parts[1];
|
|
543
|
-
const pattern = parts[2]?.replace(/^"|"$/g, "") ?? null;
|
|
544
|
-
commands.push({ name: "list_directory", arguments: { path: path3, pattern } });
|
|
545
|
-
}
|
|
546
|
-
handleGrep(parts, rawLine, commands) {
|
|
547
|
-
if (parts.length < 3) {
|
|
548
|
-
commands.push(this.skip(
|
|
549
|
-
`[SKIPPED] Your command "${rawLine}" is missing arguments. Correct format: grep '<pattern>' <path>. Example: grep 'TODO' src/`
|
|
550
|
-
));
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
let pat = parts[1];
|
|
554
|
-
if (pat.startsWith("'") && pat.endsWith("'")) {
|
|
555
|
-
pat = pat.slice(1, -1);
|
|
556
|
-
}
|
|
557
|
-
if (!pat) {
|
|
558
|
-
commands.push(this.skip(
|
|
559
|
-
`[SKIPPED] Your command "${rawLine}" has an empty pattern. Provide a non-empty search pattern. Example: grep 'function' src/`
|
|
560
|
-
));
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
commands.push({ name: "grep", arguments: { pattern: pat, path: parts[2] } });
|
|
564
|
-
}
|
|
565
|
-
handleRead(parts, rawLine, commands) {
|
|
566
|
-
if (parts.length < 2) {
|
|
567
|
-
commands.push(this.skip(
|
|
568
|
-
`[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: read <path> or read <path>:<start>-<end>. Example: read src/index.ts:1-50`
|
|
569
|
-
));
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
const spec = parts[1];
|
|
573
|
-
const rangeIdx = spec.indexOf(":");
|
|
574
|
-
if (rangeIdx === -1) {
|
|
575
|
-
commands.push({ name: "read", arguments: { path: spec } });
|
|
576
|
-
return;
|
|
577
|
-
}
|
|
578
|
-
const filePath = spec.slice(0, rangeIdx);
|
|
579
|
-
const range = spec.slice(rangeIdx + 1);
|
|
580
|
-
const [s, e] = range.split("-").map((v) => parseInt(v, 10));
|
|
581
|
-
if (!Number.isFinite(s) || !Number.isFinite(e)) {
|
|
582
|
-
commands.push({ name: "read", arguments: { path: filePath } });
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
commands.push({ name: "read", arguments: { path: filePath, start: s, end: e } });
|
|
586
|
-
}
|
|
587
|
-
handleFinish(parts, rawLine, commands, acc) {
|
|
588
|
-
const map = acc ?? /* @__PURE__ */ new Map();
|
|
589
|
-
const args = parts.slice(1);
|
|
590
|
-
for (const token of args) {
|
|
591
|
-
const [filePath, rangesText] = token.split(":", 2);
|
|
592
|
-
if (!filePath || !rangesText) {
|
|
593
|
-
commands.push(this.skip(
|
|
594
|
-
`[SKIPPED] Invalid finish token "${token}". Correct format: finish <path>:<start>-<end>. Example: finish src/index.ts:1-50`
|
|
595
|
-
));
|
|
596
|
-
continue;
|
|
597
|
-
}
|
|
598
|
-
const rangeSpecs = rangesText.split(",").filter(Boolean);
|
|
599
|
-
for (const spec of rangeSpecs) {
|
|
600
|
-
const [s, e] = spec.split("-").map((v) => parseInt(v, 10));
|
|
601
|
-
if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {
|
|
602
|
-
commands.push(this.skip(
|
|
603
|
-
`[SKIPPED] Invalid range "${spec}" in "${token}". Ranges must be <start>-<end> where start <= end. Example: 1-50`
|
|
604
|
-
));
|
|
605
|
-
continue;
|
|
606
|
-
}
|
|
607
|
-
const arr = map.get(filePath) ?? [];
|
|
608
|
-
arr.push([s, e]);
|
|
609
|
-
map.set(filePath, arr);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
return map;
|
|
258
|
+
const withoutThink = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
|
|
259
|
+
return parseQwen3ToolCalls(withoutThink);
|
|
613
260
|
}
|
|
614
261
|
};
|
|
615
262
|
|
|
@@ -678,14 +325,12 @@ async function toolListDirectory(provider, args) {
|
|
|
678
325
|
}
|
|
679
326
|
const { entries: list } = await getListRecursive(initialDepth);
|
|
680
327
|
if (!list.length) return "empty";
|
|
681
|
-
|
|
682
|
-
return "query not specific enough, tool called tried to return too much context and failed";
|
|
683
|
-
}
|
|
684
|
-
return list.map((e) => {
|
|
328
|
+
const tree = list.map((e) => {
|
|
685
329
|
const indent = " ".repeat(e.depth);
|
|
686
330
|
const name = e.type === "dir" ? `${e.name}/` : e.name;
|
|
687
331
|
return `${indent}${name}`;
|
|
688
332
|
}).join("\n");
|
|
333
|
+
return tree;
|
|
689
334
|
}
|
|
690
335
|
|
|
691
336
|
// tools/warp_grep/agent/tools/finish.ts
|
|
@@ -748,90 +393,19 @@ function mergeRanges(ranges) {
|
|
|
748
393
|
|
|
749
394
|
// tools/warp_grep/agent/formatter.ts
|
|
750
395
|
var ToolOutputFormatter = class {
|
|
751
|
-
format(toolName,
|
|
396
|
+
format(toolName, _args, output, options = {}) {
|
|
752
397
|
const name = (toolName ?? "").trim();
|
|
753
398
|
if (!name) {
|
|
754
399
|
return "";
|
|
755
400
|
}
|
|
756
401
|
const payload = output?.toString?.()?.trim?.() ?? "";
|
|
757
402
|
const isError = Boolean(options.isError);
|
|
758
|
-
const safeArgs = args ?? {};
|
|
759
403
|
if (!payload && !isError) {
|
|
760
404
|
return "";
|
|
761
405
|
}
|
|
762
|
-
|
|
763
|
-
case "read":
|
|
764
|
-
return this.formatRead(safeArgs, payload, isError);
|
|
765
|
-
case "list_directory":
|
|
766
|
-
return this.formatListDirectory(safeArgs, payload, isError);
|
|
767
|
-
case "grep":
|
|
768
|
-
return this.formatGrep(safeArgs, payload, isError);
|
|
769
|
-
default:
|
|
770
|
-
return payload ? `<tool_output>
|
|
771
|
-
${payload}
|
|
772
|
-
</tool_output>` : "";
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
formatRead(args, payload, isError) {
|
|
776
|
-
if (isError) {
|
|
777
|
-
return payload;
|
|
778
|
-
}
|
|
779
|
-
const path3 = this.asString(args.path) || "...";
|
|
780
|
-
const start = args.start;
|
|
781
|
-
const end = args.end;
|
|
782
|
-
const linesArray = args.lines;
|
|
783
|
-
const attributes = [`path="${path3}"`];
|
|
784
|
-
if (linesArray && linesArray.length > 0) {
|
|
785
|
-
const rangeStr = linesArray.map(([s, e]) => `${s}-${e}`).join(",");
|
|
786
|
-
attributes.push(`lines="${rangeStr}"`);
|
|
787
|
-
} else if (start !== void 0 && end !== void 0) {
|
|
788
|
-
attributes.push(`lines="${start}-${end}"`);
|
|
789
|
-
}
|
|
790
|
-
return `<read ${attributes.join(" ")}>
|
|
791
|
-
${payload}
|
|
792
|
-
</read>`;
|
|
793
|
-
}
|
|
794
|
-
formatListDirectory(args, payload, isError) {
|
|
795
|
-
const path3 = this.asString(args.path) || ".";
|
|
796
|
-
const pattern = this.asString(args.pattern);
|
|
797
|
-
const attributes = [`path="${path3}"`];
|
|
798
|
-
if (pattern) {
|
|
799
|
-
attributes.push(`pattern="${pattern}"`);
|
|
800
|
-
}
|
|
801
|
-
if (isError) {
|
|
802
|
-
attributes.push('status="error"');
|
|
803
|
-
}
|
|
804
|
-
return `<list_directory ${attributes.join(" ")}>
|
|
805
|
-
${payload}
|
|
806
|
-
</list_directory>`;
|
|
807
|
-
}
|
|
808
|
-
formatGrep(args, payload, isError) {
|
|
809
|
-
const pattern = this.asString(args.pattern);
|
|
810
|
-
const subDir = this.asString(args.path);
|
|
811
|
-
const glob = this.asString(args.glob);
|
|
812
|
-
const attributes = [];
|
|
813
|
-
if (pattern !== void 0) {
|
|
814
|
-
attributes.push(`pattern="${pattern}"`);
|
|
815
|
-
}
|
|
816
|
-
if (subDir !== void 0) {
|
|
817
|
-
attributes.push(`sub_dir="${subDir}"`);
|
|
818
|
-
}
|
|
819
|
-
if (glob !== void 0) {
|
|
820
|
-
attributes.push(`glob="${glob}"`);
|
|
821
|
-
}
|
|
822
|
-
if (isError) {
|
|
823
|
-
attributes.push('status="error"');
|
|
824
|
-
}
|
|
825
|
-
const attrText = attributes.length ? ` ${attributes.join(" ")}` : "";
|
|
826
|
-
return `<grep${attrText}>
|
|
406
|
+
return `<tool_response>
|
|
827
407
|
${payload}
|
|
828
|
-
</
|
|
829
|
-
}
|
|
830
|
-
asString(value) {
|
|
831
|
-
if (value === null || value === void 0) {
|
|
832
|
-
return void 0;
|
|
833
|
-
}
|
|
834
|
-
return String(value);
|
|
408
|
+
</tool_response>`;
|
|
835
409
|
}
|
|
836
410
|
};
|
|
837
411
|
var sharedFormatter = new ToolOutputFormatter();
|
|
@@ -859,12 +433,15 @@ function calculateContextBudget(messages) {
|
|
|
859
433
|
const maxK = Math.round(maxChars / 1e3);
|
|
860
434
|
return `<context_budget>${percent}% (${usedK}K/${maxK}K chars)</context_budget>`;
|
|
861
435
|
}
|
|
862
|
-
async function buildInitialState(repoRoot, query, provider) {
|
|
436
|
+
async function buildInitialState(repoRoot, query, provider, options) {
|
|
437
|
+
const budget = calculateContextBudget([]);
|
|
438
|
+
const turnTag = `Turn 0/${AGENT_CONFIG.MAX_TURNS}`;
|
|
439
|
+
const treeDepth = options?.query_type === "node_modules" ? 1 : 2;
|
|
863
440
|
try {
|
|
864
441
|
const entries = await provider.listDirectory({
|
|
865
442
|
path: ".",
|
|
866
443
|
maxResults: AGENT_CONFIG.MAX_OUTPUT_LINES,
|
|
867
|
-
maxDepth:
|
|
444
|
+
maxDepth: treeDepth
|
|
868
445
|
});
|
|
869
446
|
const treeLines = entries.map((e) => {
|
|
870
447
|
const indent = " ".repeat(e.depth);
|
|
@@ -880,7 +457,9 @@ ${treeOutput}
|
|
|
880
457
|
|
|
881
458
|
<search_string>
|
|
882
459
|
${query}
|
|
883
|
-
</search_string
|
|
460
|
+
</search_string>
|
|
461
|
+
${budget}
|
|
462
|
+
${turnTag}`;
|
|
884
463
|
} catch {
|
|
885
464
|
const repoName = import_path.default.basename(repoRoot);
|
|
886
465
|
return `<repo_structure>
|
|
@@ -889,7 +468,9 @@ ${repoName}/
|
|
|
889
468
|
|
|
890
469
|
<search_string>
|
|
891
470
|
${query}
|
|
892
|
-
</search_string
|
|
471
|
+
</search_string>
|
|
472
|
+
${budget}
|
|
473
|
+
${turnTag}`;
|
|
893
474
|
}
|
|
894
475
|
}
|
|
895
476
|
function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS) {
|
|
@@ -925,7 +506,7 @@ var import_openai = __toESM(require("openai"), 1);
|
|
|
925
506
|
// package.json
|
|
926
507
|
var package_default = {
|
|
927
508
|
name: "@morphllm/morphsdk",
|
|
928
|
-
version: "0.2.
|
|
509
|
+
version: "0.2.126",
|
|
929
510
|
description: "TypeScript SDK and CLI for Morph Fast Apply integration",
|
|
930
511
|
type: "module",
|
|
931
512
|
main: "./dist/index.cjs",
|
|
@@ -1067,7 +648,7 @@ var package_default = {
|
|
|
1067
648
|
"!dist/**/*.test.*"
|
|
1068
649
|
],
|
|
1069
650
|
scripts: {
|
|
1070
|
-
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/
|
|
651
|
+
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",
|
|
1071
652
|
prepare: "npm run build",
|
|
1072
653
|
typecheck: "tsc --noEmit",
|
|
1073
654
|
lint: "eslint .",
|
|
@@ -1204,14 +785,13 @@ async function runWarpGrep(config) {
|
|
|
1204
785
|
const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
|
|
1205
786
|
const timings = { turns: [], timeout_ms: timeoutMs };
|
|
1206
787
|
const repoRoot = import_path2.default.resolve(config.repoRoot || process.cwd());
|
|
788
|
+
const model = config.model || DEFAULT_MODEL;
|
|
1207
789
|
const messages = [];
|
|
1208
|
-
|
|
790
|
+
const maxTurns = AGENT_CONFIG.MAX_TURNS;
|
|
1209
791
|
const initialStateStart = Date.now();
|
|
1210
|
-
const initialState = await buildInitialState(repoRoot, config.query, config.provider);
|
|
792
|
+
const initialState = await buildInitialState(repoRoot, config.query, config.provider, { query_type: config.query_type });
|
|
1211
793
|
timings.initial_state_ms = Date.now() - initialStateStart;
|
|
1212
794
|
messages.push({ role: "user", content: initialState });
|
|
1213
|
-
const maxTurns = AGENT_CONFIG.MAX_TURNS;
|
|
1214
|
-
const model = config.model || DEFAULT_MODEL;
|
|
1215
795
|
const provider = config.provider;
|
|
1216
796
|
const errors = [];
|
|
1217
797
|
let finishMeta;
|
|
@@ -1261,7 +841,7 @@ async function runWarpGrep(config) {
|
|
|
1261
841
|
const args = c.arguments ?? {};
|
|
1262
842
|
allPromises.push(
|
|
1263
843
|
toolGrep(provider, args).then(
|
|
1264
|
-
({ output }) => formatAgentToolOutput("grep", args, output
|
|
844
|
+
({ output }) => formatAgentToolOutput("grep", args, output),
|
|
1265
845
|
(err) => formatAgentToolOutput("grep", args, String(err), { isError: true })
|
|
1266
846
|
)
|
|
1267
847
|
);
|
|
@@ -1270,7 +850,7 @@ async function runWarpGrep(config) {
|
|
|
1270
850
|
const args = c.arguments ?? {};
|
|
1271
851
|
allPromises.push(
|
|
1272
852
|
toolListDirectory(provider, args).then(
|
|
1273
|
-
(p) => formatAgentToolOutput("list_directory", args, p
|
|
853
|
+
(p) => formatAgentToolOutput("list_directory", args, p),
|
|
1274
854
|
(err) => formatAgentToolOutput("list_directory", args, String(err), { isError: true })
|
|
1275
855
|
)
|
|
1276
856
|
);
|
|
@@ -1279,7 +859,7 @@ async function runWarpGrep(config) {
|
|
|
1279
859
|
const args = c.arguments ?? {};
|
|
1280
860
|
allPromises.push(
|
|
1281
861
|
toolRead(provider, args).then(
|
|
1282
|
-
(p) => formatAgentToolOutput("read", args, p
|
|
862
|
+
(p) => formatAgentToolOutput("read", args, p),
|
|
1283
863
|
(err) => formatAgentToolOutput("read", args, String(err), { isError: true })
|
|
1284
864
|
)
|
|
1285
865
|
);
|
|
@@ -1363,14 +943,13 @@ async function* runWarpGrepStreaming(config) {
|
|
|
1363
943
|
const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
|
|
1364
944
|
const timings = { turns: [], timeout_ms: timeoutMs };
|
|
1365
945
|
const repoRoot = import_path2.default.resolve(config.repoRoot || process.cwd());
|
|
946
|
+
const model = config.model || DEFAULT_MODEL;
|
|
1366
947
|
const messages = [];
|
|
1367
|
-
|
|
948
|
+
const maxTurns = AGENT_CONFIG.MAX_TURNS;
|
|
1368
949
|
const initialStateStart = Date.now();
|
|
1369
|
-
const initialState = await buildInitialState(repoRoot, config.query, config.provider);
|
|
950
|
+
const initialState = await buildInitialState(repoRoot, config.query, config.provider, { query_type: config.query_type });
|
|
1370
951
|
timings.initial_state_ms = Date.now() - initialStateStart;
|
|
1371
952
|
messages.push({ role: "user", content: initialState });
|
|
1372
|
-
const maxTurns = AGENT_CONFIG.MAX_TURNS;
|
|
1373
|
-
const model = config.model || DEFAULT_MODEL;
|
|
1374
953
|
const provider = config.provider;
|
|
1375
954
|
const errors = [];
|
|
1376
955
|
let finishMeta;
|
|
@@ -1427,7 +1006,7 @@ async function* runWarpGrepStreaming(config) {
|
|
|
1427
1006
|
const args = c.arguments ?? {};
|
|
1428
1007
|
allPromises.push(
|
|
1429
1008
|
toolGrep(provider, args).then(
|
|
1430
|
-
({ output }) => formatAgentToolOutput("grep", args, output
|
|
1009
|
+
({ output }) => formatAgentToolOutput("grep", args, output),
|
|
1431
1010
|
(err) => formatAgentToolOutput("grep", args, String(err), { isError: true })
|
|
1432
1011
|
)
|
|
1433
1012
|
);
|
|
@@ -1436,7 +1015,7 @@ async function* runWarpGrepStreaming(config) {
|
|
|
1436
1015
|
const args = c.arguments ?? {};
|
|
1437
1016
|
allPromises.push(
|
|
1438
1017
|
toolListDirectory(provider, args).then(
|
|
1439
|
-
(p) => formatAgentToolOutput("list_directory", args, p
|
|
1018
|
+
(p) => formatAgentToolOutput("list_directory", args, p),
|
|
1440
1019
|
(err) => formatAgentToolOutput("list_directory", args, String(err), { isError: true })
|
|
1441
1020
|
)
|
|
1442
1021
|
);
|
|
@@ -1445,7 +1024,7 @@ async function* runWarpGrepStreaming(config) {
|
|
|
1445
1024
|
const args = c.arguments ?? {};
|
|
1446
1025
|
allPromises.push(
|
|
1447
1026
|
toolRead(provider, args).then(
|
|
1448
|
-
(p) => formatAgentToolOutput("read", args, p
|
|
1027
|
+
(p) => formatAgentToolOutput("read", args, p),
|
|
1449
1028
|
(err) => formatAgentToolOutput("read", args, String(err), { isError: true })
|
|
1450
1029
|
)
|
|
1451
1030
|
);
|