@morphllm/morphsdk 0.2.84 → 0.2.85
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-D4EQYM6O.js → chunk-37SJ3IOY.js} +63 -42
- package/dist/chunk-37SJ3IOY.js.map +1 -0
- package/dist/{chunk-MJ7JODAY.js → chunk-5X7IJXKA.js} +2 -2
- package/dist/{chunk-262WRPS5.js → chunk-AJEE5RRB.js} +2 -2
- package/dist/{chunk-LF2X6YNP.js → chunk-HJOMBO2A.js} +153 -2
- package/dist/chunk-HJOMBO2A.js.map +1 -0
- package/dist/{chunk-LX2WNS3L.js → chunk-IXNX4HMC.js} +2 -2
- package/dist/{chunk-FY32COVL.js → chunk-L5C6E32T.js} +1 -1
- package/dist/{chunk-FY32COVL.js.map → chunk-L5C6E32T.js.map} +1 -1
- package/dist/{chunk-N3RNM4A4.js → chunk-SQF3OG24.js} +5 -5
- package/dist/{client-CsO9LifG.d.ts → client-Drz3OGq-.d.ts} +1 -1
- package/dist/client.cjs +204 -37
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +3 -2
- package/dist/client.js +6 -6
- package/dist/index.cjs +204 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -7
- package/dist/tools/warp_grep/agent/runner.cjs +154 -2
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.d.ts +9 -2
- package/dist/tools/warp_grep/agent/runner.js +5 -3
- package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/types.d.ts +12 -1
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.d.ts +3 -2
- package/dist/tools/warp_grep/anthropic.js +3 -3
- package/dist/tools/warp_grep/client.cjs +209 -39
- package/dist/tools/warp_grep/client.cjs.map +1 -1
- package/dist/tools/warp_grep/client.d.ts +39 -6
- package/dist/tools/warp_grep/client.js +2 -2
- package/dist/tools/warp_grep/gemini.cjs.map +1 -1
- package/dist/tools/warp_grep/gemini.d.ts +3 -2
- package/dist/tools/warp_grep/gemini.js +2 -2
- package/dist/tools/warp_grep/index.cjs +211 -39
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.d.ts +3 -3
- package/dist/tools/warp_grep/index.js +6 -4
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.d.ts +3 -2
- package/dist/tools/warp_grep/openai.js +3 -3
- package/dist/tools/warp_grep/providers/remote.d.ts +1 -1
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.d.ts +2 -1
- package/dist/tools/warp_grep/vercel.js +3 -3
- package/dist/{types-Cv4LpqVl.d.ts → types-BMowL9iZ.d.ts} +5 -0
- package/package.json +1 -1
- package/dist/chunk-D4EQYM6O.js.map +0 -1
- package/dist/chunk-LF2X6YNP.js.map +0 -1
- /package/dist/{chunk-MJ7JODAY.js.map → chunk-5X7IJXKA.js.map} +0 -0
- /package/dist/{chunk-262WRPS5.js.map → chunk-AJEE5RRB.js.map} +0 -0
- /package/dist/{chunk-LX2WNS3L.js.map → chunk-IXNX4HMC.js.map} +0 -0
- /package/dist/{chunk-N3RNM4A4.js.map → chunk-SQF3OG24.js.map} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
runWarpGrep
|
|
3
|
-
|
|
2
|
+
runWarpGrep,
|
|
3
|
+
runWarpGrepStreaming
|
|
4
|
+
} from "./chunk-HJOMBO2A.js";
|
|
4
5
|
import {
|
|
5
6
|
RemoteCommandsProvider
|
|
6
7
|
} from "./chunk-PUGSTXLO.js";
|
|
@@ -20,48 +21,31 @@ var WarpGrepClient = class {
|
|
|
20
21
|
retryConfig: config.retryConfig
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* }
|
|
41
|
-
* }
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
async execute(input) {
|
|
45
|
-
return executeToolCall(
|
|
46
|
-
{ query: input.query },
|
|
47
|
-
{
|
|
48
|
-
repoRoot: input.repoRoot,
|
|
49
|
-
remoteCommands: input.remoteCommands,
|
|
50
|
-
provider: input.provider,
|
|
51
|
-
excludes: input.excludes,
|
|
52
|
-
includes: input.includes,
|
|
53
|
-
debug: input.debug ?? this.config.debug,
|
|
54
|
-
morphApiKey: this.config.morphApiKey,
|
|
55
|
-
morphApiUrl: this.config.morphApiUrl,
|
|
56
|
-
retryConfig: this.config.retryConfig,
|
|
57
|
-
timeout: this.config.timeout
|
|
58
|
-
}
|
|
59
|
-
);
|
|
24
|
+
execute(input) {
|
|
25
|
+
const toolConfig = {
|
|
26
|
+
repoRoot: input.repoRoot,
|
|
27
|
+
remoteCommands: input.remoteCommands,
|
|
28
|
+
provider: input.provider,
|
|
29
|
+
excludes: input.excludes,
|
|
30
|
+
includes: input.includes,
|
|
31
|
+
debug: input.debug ?? this.config.debug,
|
|
32
|
+
morphApiKey: this.config.morphApiKey,
|
|
33
|
+
morphApiUrl: this.config.morphApiUrl,
|
|
34
|
+
retryConfig: this.config.retryConfig,
|
|
35
|
+
timeout: this.config.timeout
|
|
36
|
+
};
|
|
37
|
+
if (input.streamSteps) {
|
|
38
|
+
return executeToolCallStreaming({ query: input.query }, toolConfig);
|
|
39
|
+
}
|
|
40
|
+
return executeToolCall({ query: input.query }, toolConfig);
|
|
60
41
|
}
|
|
61
42
|
};
|
|
62
|
-
|
|
43
|
+
function executeWarpGrep(input, config) {
|
|
63
44
|
const client = new WarpGrepClient(config);
|
|
64
|
-
|
|
45
|
+
if (input.streamSteps) {
|
|
46
|
+
return client.execute({ ...input, streamSteps: true });
|
|
47
|
+
}
|
|
48
|
+
return client.execute({ ...input, streamSteps: false });
|
|
65
49
|
}
|
|
66
50
|
async function executeToolCall(input, config) {
|
|
67
51
|
const parsed = typeof input === "string" ? JSON.parse(input) : input;
|
|
@@ -88,6 +72,43 @@ async function executeToolCall(input, config) {
|
|
|
88
72
|
}));
|
|
89
73
|
return { success: true, contexts, summary: finish.payload };
|
|
90
74
|
}
|
|
75
|
+
function processAgentResult(result) {
|
|
76
|
+
const finish = result.finish;
|
|
77
|
+
if (result.terminationReason !== "completed" || !finish?.metadata) {
|
|
78
|
+
return { success: false, error: "Search did not complete" };
|
|
79
|
+
}
|
|
80
|
+
const contexts = (finish.resolved ?? []).map((r) => ({
|
|
81
|
+
file: r.path,
|
|
82
|
+
content: r.content
|
|
83
|
+
}));
|
|
84
|
+
return { success: true, contexts, summary: finish.payload };
|
|
85
|
+
}
|
|
86
|
+
async function* executeToolCallStreaming(input, config) {
|
|
87
|
+
const parsed = typeof input === "string" ? JSON.parse(input) : input;
|
|
88
|
+
const provider = config.remoteCommands ? new RemoteCommandsProvider(config.repoRoot, config.remoteCommands) : config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
|
|
89
|
+
const generator = runWarpGrepStreaming({
|
|
90
|
+
query: parsed.query,
|
|
91
|
+
repoRoot: config.repoRoot,
|
|
92
|
+
provider,
|
|
93
|
+
excludes: config.excludes,
|
|
94
|
+
includes: config.includes,
|
|
95
|
+
debug: config.debug ?? false,
|
|
96
|
+
morphApiKey: config.morphApiKey,
|
|
97
|
+
morphApiUrl: config.morphApiUrl,
|
|
98
|
+
retryConfig: config.retryConfig,
|
|
99
|
+
timeout: config.timeout
|
|
100
|
+
});
|
|
101
|
+
let agentResult;
|
|
102
|
+
for (; ; ) {
|
|
103
|
+
const { value, done } = await generator.next();
|
|
104
|
+
if (done) {
|
|
105
|
+
agentResult = value;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
yield value;
|
|
109
|
+
}
|
|
110
|
+
return processAgentResult(agentResult);
|
|
111
|
+
}
|
|
91
112
|
function formatResult(result) {
|
|
92
113
|
if (!result.success) {
|
|
93
114
|
return `Search failed: ${result.error}`;
|
|
@@ -117,4 +138,4 @@ export {
|
|
|
117
138
|
executeToolCall,
|
|
118
139
|
formatResult
|
|
119
140
|
};
|
|
120
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-37SJ3IOY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../tools/warp_grep/client.ts"],"sourcesContent":["/**\n * WarpGrep client for programmatic code search\n */\n\nimport { runWarpGrep, runWarpGrepStreaming } from './agent/runner.js';\nimport { LocalRipgrepProvider } from './providers/local.js';\nimport { RemoteCommandsProvider } from './providers/remote.js';\nimport type { AgentRunResult, WarpGrepStep } from './agent/types.js';\nimport type {\n WarpGrepClientConfig,\n WarpGrepInput,\n WarpGrepResult,\n WarpGrepContext,\n WarpGrepToolConfig,\n} from './types.js';\n\n/**\n * WarpGrep client for programmatic code search\n * \n * @example\n * ```typescript\n * import { WarpGrepClient } from '@morphllm/morphsdk';\n * \n * const client = new WarpGrepClient({ morphApiKey: process.env.MORPH_API_KEY });\n * \n * // Simple usage - defaults to LocalRipgrepProvider\n * const result = await client.execute({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n * \n * // With custom excludes\n * const result = await client.execute({\n * query: 'Find database models',\n * repoRoot: '.',\n * excludes: ['node_modules', '.git', 'dist']\n * });\n * ```\n */\nexport class WarpGrepClient {\n private config: WarpGrepClientConfig;\n\n constructor(config: WarpGrepClientConfig = {}) {\n this.config = {\n morphApiKey: config.morphApiKey,\n morphApiUrl: config.morphApiUrl,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n };\n }\n\n /**\n * Execute a code search query\n *\n * @param input - Search parameters including query, repoRoot, and optional provider\n * @returns Search results with relevant code contexts, or an AsyncGenerator if streamSteps is true\n *\n * @example\n * ```typescript\n * // Standard execution\n * const result = await client.execute({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n *\n * if (result.success) {\n * for (const ctx of result.contexts) {\n * console.log(`File: ${ctx.file}`);\n * console.log(ctx.content);\n * }\n * }\n *\n * // Streaming execution\n * const stream = client.execute({\n * query: 'Find auth middleware',\n * repoRoot: '.',\n * streamSteps: true\n * });\n *\n * for await (const step of stream) {\n * console.log(`Turn ${step.turn}:`, step.toolCalls);\n * }\n * ```\n */\n execute(input: WarpGrepInput & { streamSteps: true }): AsyncGenerator<WarpGrepStep, WarpGrepResult, undefined>;\n execute(input: WarpGrepInput & { streamSteps?: false | undefined }): Promise<WarpGrepResult>;\n execute(input: WarpGrepInput): Promise<WarpGrepResult> | AsyncGenerator<WarpGrepStep, WarpGrepResult, undefined> {\n const toolConfig: WarpGrepToolConfig = {\n repoRoot: input.repoRoot,\n remoteCommands: input.remoteCommands,\n provider: input.provider,\n excludes: input.excludes,\n includes: input.includes,\n debug: input.debug ?? this.config.debug,\n morphApiKey: this.config.morphApiKey,\n morphApiUrl: this.config.morphApiUrl,\n retryConfig: this.config.retryConfig,\n timeout: this.config.timeout,\n };\n\n if (input.streamSteps) {\n return executeToolCallStreaming({ query: input.query }, toolConfig);\n }\n return executeToolCall({ query: input.query }, toolConfig);\n }\n}\n\n/**\n * Execute a warp grep search directly\n *\n * @param input - Search parameters\n * @param config - Optional client configuration\n * @returns Search results, or an AsyncGenerator if streamSteps is true\n *\n * @example\n * ```typescript\n * import { executeWarpGrep } from '@morphllm/morphsdk/tools/warp-grep';\n *\n * const result = await executeWarpGrep({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n *\n * // Streaming\n * const stream = executeWarpGrep({\n * query: 'Find auth',\n * repoRoot: '.',\n * streamSteps: true\n * });\n * for await (const step of stream) {\n * console.log(step.turn, step.toolCalls);\n * }\n * ```\n */\nexport function executeWarpGrep(\n input: WarpGrepInput & { streamSteps: true },\n config?: WarpGrepClientConfig\n): AsyncGenerator<WarpGrepStep, WarpGrepResult, undefined>;\nexport function executeWarpGrep(\n input: WarpGrepInput & { streamSteps?: false | undefined },\n config?: WarpGrepClientConfig\n): Promise<WarpGrepResult>;\nexport function executeWarpGrep(\n input: WarpGrepInput,\n config?: WarpGrepClientConfig\n): Promise<WarpGrepResult> | AsyncGenerator<WarpGrepStep, WarpGrepResult, undefined> {\n const client = new WarpGrepClient(config);\n if (input.streamSteps) {\n return client.execute({ ...input, streamSteps: true });\n }\n return client.execute({ ...input, streamSteps: false });\n}\n\nexport async function executeToolCall(\n input: { query: string } | string,\n config: WarpGrepToolConfig\n): Promise<WarpGrepResult> {\n const parsed = typeof input === 'string' ? JSON.parse(input) : input;\n \n // Priority: remoteCommands > provider > LocalRipgrepProvider\n const provider = config.remoteCommands\n ? new RemoteCommandsProvider(config.repoRoot, config.remoteCommands)\n : config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);\n \n const result = await runWarpGrep({\n query: parsed.query,\n repoRoot: config.repoRoot,\n provider,\n excludes: config.excludes,\n includes: config.includes,\n debug: config.debug ?? false,\n morphApiKey: config.morphApiKey,\n morphApiUrl: config.morphApiUrl,\n retryConfig: config.retryConfig,\n timeout: config.timeout,\n });\n\n const finish = result.finish;\n if (result.terminationReason !== 'completed' || !finish?.metadata) {\n return { success: false, error: 'Search did not complete' };\n }\n\n const contexts: WarpGrepContext[] = (finish.resolved ?? []).map(r => ({\n file: r.path,\n content: r.content,\n }));\n\n return { success: true, contexts, summary: finish.payload };\n}\n\n/**\n * Helper to process AgentRunResult into WarpGrepResult\n */\nfunction processAgentResult(result: AgentRunResult): WarpGrepResult {\n const finish = result.finish;\n if (result.terminationReason !== 'completed' || !finish?.metadata) {\n return { success: false, error: 'Search did not complete' };\n }\n\n const contexts: WarpGrepContext[] = (finish.resolved ?? []).map(r => ({\n file: r.path,\n content: r.content,\n }));\n\n return { success: true, contexts, summary: finish.payload };\n}\n\n/**\n * Streaming version of executeToolCall that yields WarpGrepStep for each turn.\n */\nasync function* executeToolCallStreaming(\n input: { query: string } | string,\n config: WarpGrepToolConfig\n): AsyncGenerator<WarpGrepStep, WarpGrepResult, undefined> {\n const parsed = typeof input === 'string' ? JSON.parse(input) : input;\n\n // Priority: remoteCommands > provider > LocalRipgrepProvider\n const provider = config.remoteCommands\n ? new RemoteCommandsProvider(config.repoRoot, config.remoteCommands)\n : config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);\n\n const generator = runWarpGrepStreaming({\n query: parsed.query,\n repoRoot: config.repoRoot,\n provider,\n excludes: config.excludes,\n includes: config.includes,\n debug: config.debug ?? false,\n morphApiKey: config.morphApiKey,\n morphApiUrl: config.morphApiUrl,\n retryConfig: config.retryConfig,\n timeout: config.timeout,\n });\n\n // Forward all yielded steps\n let agentResult: AgentRunResult;\n for (;;) {\n const { value, done } = await generator.next();\n if (done) {\n agentResult = value;\n break;\n }\n yield value;\n }\n\n return processAgentResult(agentResult);\n}\n\n/**\n * Format warp grep results for display or tool responses\n * \n * @param result - The search result\n * @returns Formatted string representation\n */\nexport function formatResult(result: WarpGrepResult): string {\n if (!result.success) {\n return `Search failed: ${result.error}`;\n }\n\n if (!result.contexts || result.contexts.length === 0) {\n return 'No relevant code found. Try rephrasing your query.';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${result.contexts.length} relevant code sections:\\n`);\n\n result.contexts.forEach((ctx, i) => {\n lines.push(`${i + 1}. ${ctx.file}`);\n lines.push('```');\n lines.push(ctx.content);\n lines.push('```');\n lines.push('');\n });\n\n if (result.summary) {\n lines.push(`Summary: ${result.summary}`);\n }\n\n return lines.join('\\n');\n}\n\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-KW7OEGZK.js";
|
|
4
4
|
import {
|
|
5
5
|
executeToolCall
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-37SJ3IOY.js";
|
|
7
7
|
|
|
8
8
|
// tools/warp_grep/vercel.ts
|
|
9
9
|
import { tool } from "ai";
|
|
@@ -38,4 +38,4 @@ export {
|
|
|
38
38
|
createWarpGrepTool,
|
|
39
39
|
vercel_default
|
|
40
40
|
};
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
41
|
+
//# sourceMappingURL=chunk-5X7IJXKA.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
executeToolCall,
|
|
7
7
|
formatResult
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-37SJ3IOY.js";
|
|
9
9
|
import {
|
|
10
10
|
getSystemPrompt
|
|
11
11
|
} from "./chunk-FMLHRJDF.js";
|
|
@@ -50,4 +50,4 @@ export {
|
|
|
50
50
|
execute,
|
|
51
51
|
createWarpGrepTool
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
53
|
+
//# sourceMappingURL=chunk-AJEE5RRB.js.map
|
|
@@ -211,8 +211,159 @@ async function runWarpGrep(config) {
|
|
|
211
211
|
timings
|
|
212
212
|
};
|
|
213
213
|
}
|
|
214
|
+
async function* runWarpGrepStreaming(config) {
|
|
215
|
+
const totalStart = Date.now();
|
|
216
|
+
const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
|
|
217
|
+
const timings = { turns: [], timeout_ms: timeoutMs };
|
|
218
|
+
const repoRoot = path.resolve(config.repoRoot || process.cwd());
|
|
219
|
+
const messages = [];
|
|
220
|
+
messages.push({ role: "system", content: getSystemPrompt() });
|
|
221
|
+
const initialStateStart = Date.now();
|
|
222
|
+
const initialState = await buildInitialState(repoRoot, config.query, config.provider);
|
|
223
|
+
timings.initial_state_ms = Date.now() - initialStateStart;
|
|
224
|
+
messages.push({ role: "user", content: initialState });
|
|
225
|
+
const maxTurns = AGENT_CONFIG.MAX_TURNS;
|
|
226
|
+
const model = config.model || DEFAULT_MODEL;
|
|
227
|
+
const provider = config.provider;
|
|
228
|
+
const errors = [];
|
|
229
|
+
let finishMeta;
|
|
230
|
+
let terminationReason = "terminated";
|
|
231
|
+
for (let turn = 1; turn <= maxTurns; turn += 1) {
|
|
232
|
+
const turnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };
|
|
233
|
+
enforceContextLimit(messages);
|
|
234
|
+
const modelCallStart = Date.now();
|
|
235
|
+
const assistantContent = await callModel(messages, model, {
|
|
236
|
+
morphApiKey: config.morphApiKey,
|
|
237
|
+
morphApiUrl: config.morphApiUrl,
|
|
238
|
+
retryConfig: config.retryConfig,
|
|
239
|
+
timeout: timeoutMs
|
|
240
|
+
}).catch((e) => {
|
|
241
|
+
errors.push({ message: e instanceof Error ? e.message : String(e) });
|
|
242
|
+
return "";
|
|
243
|
+
});
|
|
244
|
+
turnMetrics.morph_api_ms = Date.now() - modelCallStart;
|
|
245
|
+
if (!assistantContent) {
|
|
246
|
+
timings.turns.push(turnMetrics);
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
messages.push({ role: "assistant", content: assistantContent });
|
|
250
|
+
const toolCalls = parser.parse(assistantContent);
|
|
251
|
+
if (toolCalls.length === 0) {
|
|
252
|
+
errors.push({ message: "No tool calls produced by the model. Your MCP is likely out of date! Update it by running: rm -rf ~/.npm/_npx && npm cache clean --force && npx -y @morphllm/morphmcp@latest" });
|
|
253
|
+
terminationReason = "terminated";
|
|
254
|
+
timings.turns.push(turnMetrics);
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
yield {
|
|
258
|
+
turn,
|
|
259
|
+
toolCalls: toolCalls.map((c) => ({
|
|
260
|
+
name: c.name,
|
|
261
|
+
arguments: c.arguments ?? {}
|
|
262
|
+
}))
|
|
263
|
+
};
|
|
264
|
+
const finishCalls = toolCalls.filter((c) => c.name === "finish");
|
|
265
|
+
const grepCalls = toolCalls.filter((c) => c.name === "grep");
|
|
266
|
+
const listDirCalls = toolCalls.filter((c) => c.name === "list_directory");
|
|
267
|
+
const readCalls = toolCalls.filter((c) => c.name === "read");
|
|
268
|
+
const skipCalls = toolCalls.filter((c) => c.name === "_skip");
|
|
269
|
+
const formatted = [];
|
|
270
|
+
for (const c of skipCalls) {
|
|
271
|
+
const msg = c.arguments?.message || "Command skipped due to parsing error";
|
|
272
|
+
formatted.push(msg);
|
|
273
|
+
}
|
|
274
|
+
const allPromises = [];
|
|
275
|
+
for (const c of grepCalls) {
|
|
276
|
+
const args = c.arguments ?? {};
|
|
277
|
+
allPromises.push(
|
|
278
|
+
toolGrep(provider, args).then(
|
|
279
|
+
({ output }) => formatAgentToolOutput("grep", args, output, { isError: false }),
|
|
280
|
+
(err) => formatAgentToolOutput("grep", args, String(err), { isError: true })
|
|
281
|
+
)
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
for (const c of listDirCalls) {
|
|
285
|
+
const args = c.arguments ?? {};
|
|
286
|
+
allPromises.push(
|
|
287
|
+
toolListDirectory(provider, args).then(
|
|
288
|
+
(p) => formatAgentToolOutput("list_directory", args, p, { isError: false }),
|
|
289
|
+
(err) => formatAgentToolOutput("list_directory", args, String(err), { isError: true })
|
|
290
|
+
)
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
for (const c of readCalls) {
|
|
294
|
+
const args = c.arguments ?? {};
|
|
295
|
+
allPromises.push(
|
|
296
|
+
toolRead(provider, args).then(
|
|
297
|
+
(p) => formatAgentToolOutput("read", args, p, { isError: false }),
|
|
298
|
+
(err) => formatAgentToolOutput("read", args, String(err), { isError: true })
|
|
299
|
+
)
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
const toolExecStart = Date.now();
|
|
303
|
+
const allResults = await Promise.all(allPromises);
|
|
304
|
+
turnMetrics.local_tools_ms = Date.now() - toolExecStart;
|
|
305
|
+
for (const result of allResults) {
|
|
306
|
+
formatted.push(result);
|
|
307
|
+
}
|
|
308
|
+
if (formatted.length > 0) {
|
|
309
|
+
const turnMessage = formatTurnMessage(turn, maxTurns);
|
|
310
|
+
const contextBudget = calculateContextBudget(messages);
|
|
311
|
+
messages.push({ role: "user", content: formatted.join("\n") + turnMessage + "\n" + contextBudget });
|
|
312
|
+
}
|
|
313
|
+
timings.turns.push(turnMetrics);
|
|
314
|
+
if (finishCalls.length) {
|
|
315
|
+
const fc = finishCalls[0];
|
|
316
|
+
const files = fc.arguments?.files ?? [];
|
|
317
|
+
finishMeta = { files };
|
|
318
|
+
terminationReason = "completed";
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (terminationReason !== "completed" || !finishMeta) {
|
|
323
|
+
timings.total_ms = Date.now() - totalStart;
|
|
324
|
+
return { terminationReason, messages, errors, timings };
|
|
325
|
+
}
|
|
326
|
+
const parts = ["Relevant context found:"];
|
|
327
|
+
for (const f of finishMeta.files) {
|
|
328
|
+
const ranges = f.lines === "*" ? "*" : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(", ") : "*";
|
|
329
|
+
parts.push(`- ${f.path}: ${ranges}`);
|
|
330
|
+
}
|
|
331
|
+
const payload = parts.join("\n");
|
|
332
|
+
const finishResolutionStart = Date.now();
|
|
333
|
+
const fileReadErrors = [];
|
|
334
|
+
const resolved = await readFinishFiles(
|
|
335
|
+
repoRoot,
|
|
336
|
+
finishMeta.files,
|
|
337
|
+
async (p, s, e) => {
|
|
338
|
+
try {
|
|
339
|
+
const rr = await provider.read({ path: p, start: s, end: e });
|
|
340
|
+
return rr.lines.map((l) => {
|
|
341
|
+
const idx = l.indexOf("|");
|
|
342
|
+
return idx >= 0 ? l.slice(idx + 1) : l;
|
|
343
|
+
});
|
|
344
|
+
} catch (err) {
|
|
345
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
346
|
+
fileReadErrors.push({ path: p, error: errorMsg });
|
|
347
|
+
console.error(`[warp_grep] Failed to read file: ${p} - ${errorMsg}`);
|
|
348
|
+
return [`[couldn't find: ${p}]`];
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
);
|
|
352
|
+
timings.finish_resolution_ms = Date.now() - finishResolutionStart;
|
|
353
|
+
if (fileReadErrors.length > 0) {
|
|
354
|
+
errors.push(...fileReadErrors.map((e) => ({ message: `File read error: ${e.path} - ${e.error}` })));
|
|
355
|
+
}
|
|
356
|
+
timings.total_ms = Date.now() - totalStart;
|
|
357
|
+
return {
|
|
358
|
+
terminationReason: "completed",
|
|
359
|
+
messages,
|
|
360
|
+
finish: { payload, metadata: finishMeta, resolved },
|
|
361
|
+
timings
|
|
362
|
+
};
|
|
363
|
+
}
|
|
214
364
|
|
|
215
365
|
export {
|
|
216
|
-
runWarpGrep
|
|
366
|
+
runWarpGrep,
|
|
367
|
+
runWarpGrepStreaming
|
|
217
368
|
};
|
|
218
|
-
//# sourceMappingURL=chunk-
|
|
369
|
+
//# sourceMappingURL=chunk-HJOMBO2A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../tools/warp_grep/agent/runner.ts"],"sourcesContent":["import { AGENT_CONFIG, DEFAULT_MODEL } from './config.js';\nimport { getSystemPrompt } from './prompt.js';\nimport type { AgentRunResult, ChatMessage, SessionConfig, AgentFinish, WarpGrepExecutionMetrics, WarpGrepTurnMetrics, WarpGrepStep } from './types.js';\nimport { LLMResponseParser } from './parser.js';\nimport type { WarpGrepProvider } from '../providers/types.js';\nimport { toolGrep } from './tools/grep.js';\nimport { toolRead } from './tools/read.js';\nimport { toolListDirectory } from './tools/list_directory.js';\nimport { readFinishFiles } from './tools/finish.js';\nimport { fetchWithRetry, withTimeout, type RetryConfig } from '../../utils/resilience.js';\nimport { formatAgentToolOutput } from './formatter.js';\nimport { formatTurnMessage, calculateContextBudget, buildInitialState, enforceContextLimit } from './helpers.js';\nimport path from 'path';\n\ntype EventName =\n | 'initial_state'\n | 'round_start'\n | 'round_end'\n | 'finish'\n | 'error';\n\nexport type EventCallback = (name: EventName, payload: Record<string, unknown>) => void;\n\nconst parser = new LLMResponseParser();\n\nconst DEFAULT_API_URL = 'https://api.morphllm.com';\n\ninterface CallModelOptions {\n morphApiKey?: string;\n morphApiUrl?: string;\n retryConfig?: RetryConfig;\n timeout?: number;\n}\n\nasync function callModel(\n messages: ChatMessage[],\n model: string,\n options: CallModelOptions = {}\n): Promise<string> {\n const baseUrl = options.morphApiUrl || DEFAULT_API_URL;\n const apiKey = options.morphApiKey || process.env.MORPH_API_KEY || '';\n \n const fetchPromise = fetchWithRetry(\n `${baseUrl}/v1/chat/completions`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n temperature: 0.0,\n max_tokens: 1024,\n messages,\n }),\n },\n options.retryConfig\n );\n const timeoutMs = options.timeout ?? AGENT_CONFIG.TIMEOUT_MS;\n const resp = await withTimeout(fetchPromise, timeoutMs, 'morph-warp-grep request timed out');\n if (!resp.ok) {\n if (resp.status === 404) {\n throw new Error(\n 'The endpoint you are trying to call is likely deprecated. Please update with: npm cache clean --force && npx -y @morphllm/morphmcp@latest or visit: https://morphllm.com/mcp'\n );\n }\n // keeping these cases are real throws, if this happens retry will likely not help, so best we just throw here, notice the error and fix\n const t = await resp.text();\n throw new Error(`morph-warp-grep error ${resp.status}: ${t}`);\n }\n const data = await resp.json();\n const content = data?.choices?.[0]?.message?.content;\n if (!content || typeof content !== 'string') {\n throw new Error('Invalid response from model');\n }\n return content;\n}\n\nexport async function runWarpGrep(config: SessionConfig & { provider: WarpGrepProvider }): Promise<AgentRunResult> {\n const totalStart = Date.now();\n const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;\n const timings: Partial<WarpGrepExecutionMetrics> = { turns: [], timeout_ms: timeoutMs };\n \n const repoRoot = path.resolve(config.repoRoot || process.cwd());\n const messages: ChatMessage[] = [];\n\n messages.push({ role: 'system' as const, content: getSystemPrompt() });\n \n const initialStateStart = Date.now();\n const initialState = await buildInitialState(repoRoot, config.query, config.provider);\n timings.initial_state_ms = Date.now() - initialStateStart;\n \n messages.push({ role: 'user', content: initialState });\n\n const maxTurns = AGENT_CONFIG.MAX_TURNS;\n const model = config.model || DEFAULT_MODEL;\n const provider = config.provider;\n const errors: Array<{ message: string }> = [];\n\n let finishMeta: AgentFinish | undefined;\n let terminationReason: AgentRunResult['terminationReason'] = 'terminated';\n\n for (let turn = 1; turn <= maxTurns; turn += 1) {\n const turnMetrics: WarpGrepTurnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };\n \n // Enforce hard context limit before calling model\n enforceContextLimit(messages);\n \n // call model\n const modelCallStart = Date.now();\n const assistantContent = await callModel(messages, model, {\n morphApiKey: config.morphApiKey,\n morphApiUrl: config.morphApiUrl,\n retryConfig: config.retryConfig,\n timeout: timeoutMs,\n }).catch((e: unknown) => {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n return '';\n });\n turnMetrics.morph_api_ms = Date.now() - modelCallStart;\n \n if (!assistantContent) {\n timings.turns!.push(turnMetrics);\n break;\n }\n messages.push({ role: 'assistant', content: assistantContent });\n\n // parse tool calls (no longer throws - returns _skip calls for malformed commands)\n const toolCalls = parser.parse(assistantContent);\n if (toolCalls.length === 0) {\n errors.push({ message: 'No tool calls produced by the model. Your MCP is likely out of date! Update it by running: rm -rf ~/.npm/_npx && npm cache clean --force && npx -y @morphllm/morphmcp@latest' });\n terminationReason = 'terminated';\n timings.turns!.push(turnMetrics);\n break;\n }\n\n const finishCalls = toolCalls.filter(c => c.name === 'finish');\n const grepCalls = toolCalls.filter(c => c.name === 'grep');\n const listDirCalls = toolCalls.filter(c => c.name === 'list_directory');\n const readCalls = toolCalls.filter(c => c.name === 'read');\n const skipCalls = toolCalls.filter(c => c.name === '_skip');\n\n const formatted: string[] = [];\n\n // Surface any skipped commands as feedback to the LLM\n for (const c of skipCalls) {\n const msg = (c.arguments as { message?: string })?.message || 'Command skipped due to parsing error';\n formatted.push(msg);\n }\n\n const allPromises: Array<Promise<string>> = [];\n \n for (const c of grepCalls) {\n const args = (c.arguments ?? {}) as { pattern: string; path: string; glob?: string };\n allPromises.push(\n toolGrep(provider, args).then(\n ({ output }) => formatAgentToolOutput('grep', args, output, { isError: false }),\n err => formatAgentToolOutput('grep', args, String(err), { isError: true })\n )\n );\n }\n \n for (const c of listDirCalls) {\n const args = (c.arguments ?? {}) as { path: string; pattern?: string | null };\n allPromises.push(\n toolListDirectory(provider, args).then(\n p => formatAgentToolOutput('list_directory', args, p, { isError: false }),\n err => formatAgentToolOutput('list_directory', args, String(err), { isError: true })\n )\n );\n }\n \n for (const c of readCalls) {\n const args = (c.arguments ?? {}) as { path: string; start?: number; end?: number; lines?: Array<[number, number]> };\n allPromises.push(\n toolRead(provider, args).then(\n p => formatAgentToolOutput('read', args, p, { isError: false }),\n err => formatAgentToolOutput('read', args, String(err), { isError: true })\n )\n );\n }\n \n const toolExecStart = Date.now();\n const allResults = await Promise.all(allPromises);\n turnMetrics.local_tools_ms = Date.now() - toolExecStart;\n \n for (const result of allResults) {\n formatted.push(result);\n }\n\n if (formatted.length > 0) {\n const turnMessage = formatTurnMessage(turn, maxTurns);\n const contextBudget = calculateContextBudget(messages);\n messages.push({ role: 'user', content: formatted.join('\\n') + turnMessage + '\\n' + contextBudget });\n }\n\n timings.turns!.push(turnMetrics);\n\n if (finishCalls.length) {\n const fc = finishCalls[0];\n const files = ((fc.arguments as any)?.files ?? []) as AgentFinish['files'];\n finishMeta = { files };\n terminationReason = 'completed';\n break;\n }\n }\n\n if (terminationReason !== 'completed' || !finishMeta) {\n timings.total_ms = Date.now() - totalStart;\n return { terminationReason, messages, errors, timings: timings as WarpGrepExecutionMetrics };\n }\n\n // Build finish payload\n const parts: string[] = ['Relevant context found:'];\n for (const f of finishMeta.files) {\n const ranges = f.lines === '*' ? '*' \n : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(', ') \n : '*';\n parts.push(`- ${f.path}: ${ranges}`);\n }\n const payload = parts.join('\\n');\n\n // Resolve file contents for returned ranges\n // Wrap reader in try-catch to handle non-existent or unreadable files gracefully\n // Track files that couldn't be read for error reporting\n const finishResolutionStart = Date.now();\n const fileReadErrors: Array<{ path: string; error: string }> = [];\n const resolved = await readFinishFiles(\n repoRoot,\n finishMeta.files,\n async (p: string, s?: number, e?: number) => {\n try {\n const rr = await provider.read({ path: p, start: s, end: e });\n // rr.lines are \"line|content\" → strip the \"line|\" prefix\n return rr.lines.map(l => {\n const idx = l.indexOf('|');\n return idx >= 0 ? l.slice(idx + 1) : l;\n });\n } catch (err) {\n // File doesn't exist or can't be read - log error but don't throw\n // This handles cases where the agent hallucinated a path or the file was deleted\n const errorMsg = err instanceof Error ? err.message : String(err);\n fileReadErrors.push({ path: p, error: errorMsg });\n console.error(`[warp_grep] Failed to read file: ${p} - ${errorMsg}`);\n return [`[couldn't find: ${p}]`];\n }\n }\n );\n\n timings.finish_resolution_ms = Date.now() - finishResolutionStart;\n\n // Add file read errors to the result so MCP can report them\n if (fileReadErrors.length > 0) {\n errors.push(...fileReadErrors.map(e => ({ message: `File read error: ${e.path} - ${e.error}` })));\n }\n\n timings.total_ms = Date.now() - totalStart;\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta, resolved },\n timings: timings as WarpGrepExecutionMetrics,\n };\n}\n\n/**\n * Streaming version of runWarpGrep that yields step information after each turn.\n * Yields WarpGrepStep with tool calls for each turn, then returns the final AgentRunResult.\n */\nexport async function* runWarpGrepStreaming(\n config: SessionConfig & { provider: WarpGrepProvider }\n): AsyncGenerator<WarpGrepStep, AgentRunResult, undefined> {\n const totalStart = Date.now();\n const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;\n const timings: Partial<WarpGrepExecutionMetrics> = { turns: [], timeout_ms: timeoutMs };\n\n const repoRoot = path.resolve(config.repoRoot || process.cwd());\n const messages: ChatMessage[] = [];\n\n messages.push({ role: 'system' as const, content: getSystemPrompt() });\n\n const initialStateStart = Date.now();\n const initialState = await buildInitialState(repoRoot, config.query, config.provider);\n timings.initial_state_ms = Date.now() - initialStateStart;\n\n messages.push({ role: 'user', content: initialState });\n\n const maxTurns = AGENT_CONFIG.MAX_TURNS;\n const model = config.model || DEFAULT_MODEL;\n const provider = config.provider;\n const errors: Array<{ message: string }> = [];\n\n let finishMeta: AgentFinish | undefined;\n let terminationReason: AgentRunResult['terminationReason'] = 'terminated';\n\n for (let turn = 1; turn <= maxTurns; turn += 1) {\n const turnMetrics: WarpGrepTurnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };\n\n // Enforce hard context limit before calling model\n enforceContextLimit(messages);\n\n // call model\n const modelCallStart = Date.now();\n const assistantContent = await callModel(messages, model, {\n morphApiKey: config.morphApiKey,\n morphApiUrl: config.morphApiUrl,\n retryConfig: config.retryConfig,\n timeout: timeoutMs,\n }).catch((e: unknown) => {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n return '';\n });\n turnMetrics.morph_api_ms = Date.now() - modelCallStart;\n\n if (!assistantContent) {\n timings.turns!.push(turnMetrics);\n break;\n }\n messages.push({ role: 'assistant', content: assistantContent });\n\n // parse tool calls (no longer throws - returns _skip calls for malformed commands)\n const toolCalls = parser.parse(assistantContent);\n if (toolCalls.length === 0) {\n errors.push({ message: 'No tool calls produced by the model. Your MCP is likely out of date! Update it by running: rm -rf ~/.npm/_npx && npm cache clean --force && npx -y @morphllm/morphmcp@latest' });\n terminationReason = 'terminated';\n timings.turns!.push(turnMetrics);\n break;\n }\n\n // Yield step with tool calls (before execution)\n yield {\n turn,\n toolCalls: toolCalls.map(c => ({\n name: c.name,\n arguments: c.arguments ?? {}\n }))\n };\n\n const finishCalls = toolCalls.filter(c => c.name === 'finish');\n const grepCalls = toolCalls.filter(c => c.name === 'grep');\n const listDirCalls = toolCalls.filter(c => c.name === 'list_directory');\n const readCalls = toolCalls.filter(c => c.name === 'read');\n const skipCalls = toolCalls.filter(c => c.name === '_skip');\n\n const formatted: string[] = [];\n\n // Surface any skipped commands as feedback to the LLM\n for (const c of skipCalls) {\n const msg = (c.arguments as { message?: string })?.message || 'Command skipped due to parsing error';\n formatted.push(msg);\n }\n\n const allPromises: Array<Promise<string>> = [];\n\n for (const c of grepCalls) {\n const args = (c.arguments ?? {}) as { pattern: string; path: string; glob?: string };\n allPromises.push(\n toolGrep(provider, args).then(\n ({ output }) => formatAgentToolOutput('grep', args, output, { isError: false }),\n err => formatAgentToolOutput('grep', args, String(err), { isError: true })\n )\n );\n }\n\n for (const c of listDirCalls) {\n const args = (c.arguments ?? {}) as { path: string; pattern?: string | null };\n allPromises.push(\n toolListDirectory(provider, args).then(\n p => formatAgentToolOutput('list_directory', args, p, { isError: false }),\n err => formatAgentToolOutput('list_directory', args, String(err), { isError: true })\n )\n );\n }\n\n for (const c of readCalls) {\n const args = (c.arguments ?? {}) as { path: string; start?: number; end?: number; lines?: Array<[number, number]> };\n allPromises.push(\n toolRead(provider, args).then(\n p => formatAgentToolOutput('read', args, p, { isError: false }),\n err => formatAgentToolOutput('read', args, String(err), { isError: true })\n )\n );\n }\n\n const toolExecStart = Date.now();\n const allResults = await Promise.all(allPromises);\n turnMetrics.local_tools_ms = Date.now() - toolExecStart;\n\n for (const result of allResults) {\n formatted.push(result);\n }\n\n if (formatted.length > 0) {\n const turnMessage = formatTurnMessage(turn, maxTurns);\n const contextBudget = calculateContextBudget(messages);\n messages.push({ role: 'user', content: formatted.join('\\n') + turnMessage + '\\n' + contextBudget });\n }\n\n timings.turns!.push(turnMetrics);\n\n if (finishCalls.length) {\n const fc = finishCalls[0];\n const files = ((fc.arguments as any)?.files ?? []) as AgentFinish['files'];\n finishMeta = { files };\n terminationReason = 'completed';\n break;\n }\n }\n\n if (terminationReason !== 'completed' || !finishMeta) {\n timings.total_ms = Date.now() - totalStart;\n return { terminationReason, messages, errors, timings: timings as WarpGrepExecutionMetrics };\n }\n\n // Build finish payload\n const parts: string[] = ['Relevant context found:'];\n for (const f of finishMeta.files) {\n const ranges = f.lines === '*' ? '*'\n : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(', ')\n : '*';\n parts.push(`- ${f.path}: ${ranges}`);\n }\n const payload = parts.join('\\n');\n\n // Resolve file contents for returned ranges\n const finishResolutionStart = Date.now();\n const fileReadErrors: Array<{ path: string; error: string }> = [];\n const resolved = await readFinishFiles(\n repoRoot,\n finishMeta.files,\n async (p: string, s?: number, e?: number) => {\n try {\n const rr = await provider.read({ path: p, start: s, end: e });\n return rr.lines.map(l => {\n const idx = l.indexOf('|');\n return idx >= 0 ? l.slice(idx + 1) : l;\n });\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n fileReadErrors.push({ path: p, error: errorMsg });\n console.error(`[warp_grep] Failed to read file: ${p} - ${errorMsg}`);\n return [`[couldn't find: ${p}]`];\n }\n }\n );\n\n timings.finish_resolution_ms = Date.now() - finishResolutionStart;\n\n if (fileReadErrors.length > 0) {\n errors.push(...fileReadErrors.map(e => ({ message: `File read error: ${e.path} - ${e.error}` })));\n }\n\n timings.total_ms = Date.now() - totalStart;\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta, resolved },\n timings: timings as WarpGrepExecutionMetrics,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
executeToolCall,
|
|
7
7
|
formatResult
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-37SJ3IOY.js";
|
|
9
9
|
import {
|
|
10
10
|
getSystemPrompt
|
|
11
11
|
} from "./chunk-FMLHRJDF.js";
|
|
@@ -58,4 +58,4 @@ export {
|
|
|
58
58
|
createWarpGrepTool,
|
|
59
59
|
openai_default
|
|
60
60
|
};
|
|
61
|
-
//# sourceMappingURL=chunk-
|
|
61
|
+
//# sourceMappingURL=chunk-IXNX4HMC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../tools/warp_grep/index.ts"],"sourcesContent":["/**\n * Morph Warp Grep SDK\n * \n * Fast and accurate code search tool for AI agents.\n * Uses ripgrep locally, or use `remoteCommands` for sandbox environments.\n * \n * @example Local usage\n * ```typescript\n * // With MorphClient (recommended)\n * import { MorphClient } from '@morphllm/morphsdk';\n * \n * const morph = new MorphClient({ morphApiKey: process.env.MORPH_API_KEY });\n * const result = await morph.warpGrep.execute({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n * ```\n * \n * @example\n * ```typescript\n * // Standalone client\n * import { WarpGrepClient } from '@morphllm/morphsdk/tools/warp-grep';\n * \n * const client = new WarpGrepClient({ morphApiKey: process.env.MORPH_API_KEY });\n * const result = await client.execute({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n * ```\n * \n * @example\n * ```typescript\n * // As a tool for AI agents\n * import { createWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/anthropic';\n * \n * const tool = createWarpGrepTool({ repoRoot: '.' });\n * // Pass to Claude, GPT, Gemini, etc.\n * ```\n * \n * @example Remote sandbox (E2B, Modal, Daytona, etc.)\n * ```typescript\n * import { createMorphWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/anthropic';\n * \n * const tool = createMorphWarpGrepTool({\n * repoRoot: '/home/repo',\n * remoteCommands: {\n * grep: async (pattern, path) => (await sandbox.run(`rg '${pattern}' '${path}'`)).stdout,\n * read: async (path, start, end) => (await sandbox.run(`sed -n '${start},${end}p' '${path}'`)).stdout,\n * listDir: async (path, maxDepth) => (await sandbox.run(`find '${path}' -maxdepth ${maxDepth}`)).stdout,\n * },\n * });\n * ```\n * \n * @example Provider-agnostic usage (bring your own tool abstraction)\n * ```typescript\n * import { \n * warpGrepInputSchema,\n * executeToolCall,\n * WARP_GREP_TOOL_NAME,\n * WARP_GREP_DESCRIPTION,\n * } from '@morphllm/morphsdk/tools/warp-grep';\n * \n * // Use with your own tool definition abstraction\n * const toolDef = createToolDef({\n * name: WARP_GREP_TOOL_NAME,\n * description: WARP_GREP_DESCRIPTION,\n * schema: warpGrepInputSchema,\n * });\n * \n * // Execute\n * const result = await executeToolCall(\n * { query: 'Find auth middleware' },\n * { repoRoot: '.', morphApiKey: process.env.MORPH_API_KEY }\n * );\n * ```\n */\n\nimport { z } from 'zod';\n\n/** Provider-agnostic Zod schema for warp grep input */\nexport const warpGrepInputSchema = z.object({\n query: z.string().describe('Free-form repository question'),\n});\n\nexport type WarpGrepInputSchema = z.infer<typeof warpGrepInputSchema>;\n\n// Core client and functions\nexport { WarpGrepClient, executeWarpGrep, executeToolCall, formatResult } from './client.js';\n\n// Types\nexport type {\n WarpGrepClientConfig,\n WarpGrepInput,\n WarpGrepResult,\n WarpGrepContext,\n WarpGrepToolConfig,\n WarpGrepProvider,\n GrepResult,\n ReadResult,\n ListDirectoryEntry,\n RemoteCommands,\n} from './types.js';\n\n// Prompts\nexport {\n WARP_GREP_DESCRIPTION,\n WARP_GREP_TOOL_NAME,\n WARP_GREP_SYSTEM_PROMPT,\n getSystemPrompt,\n} from './prompts.js';\n\n// Providers (re-exported for convenience)\nexport { LocalRipgrepProvider, RemoteCommandsProvider } from './providers/index.js';\n\n// Path utilities (for handling model path prediction issues)\nexport { fixPathRepetition } from './utils/paths.js';\n\n// Agent internals (advanced usage)\nexport { runWarpGrep } from './agent/index.js';\nexport type { AgentRunResult, SessionConfig, ChatMessage } from './agent/index.js';\n\n// Internal agent tools (for harness builders)\nexport { toolGrep, toolRead, toolListDirectory, readFinishFiles, normalizeFinishFiles } from './agent/tools/index.js';\n\n// Provider adapters are available via dedicated import paths:\n// - '@morphllm/morphsdk/tools/warp-grep/anthropic'\n// - '@morphllm/morphsdk/tools/warp-grep/openai'\n// - '@morphllm/morphsdk/tools/warp-grep/gemini'\n// - '@morphllm/morphsdk/tools/warp-grep/vercel'\n"],"mappings":";AA6EA,SAAS,SAAS;AAGX,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,OAAO,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAC5D,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../tools/warp_grep/index.ts"],"sourcesContent":["/**\n * Morph Warp Grep SDK\n * \n * Fast and accurate code search tool for AI agents.\n * Uses ripgrep locally, or use `remoteCommands` for sandbox environments.\n * \n * @example Local usage\n * ```typescript\n * // With MorphClient (recommended)\n * import { MorphClient } from '@morphllm/morphsdk';\n * \n * const morph = new MorphClient({ morphApiKey: process.env.MORPH_API_KEY });\n * const result = await morph.warpGrep.execute({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n * ```\n * \n * @example\n * ```typescript\n * // Standalone client\n * import { WarpGrepClient } from '@morphllm/morphsdk/tools/warp-grep';\n * \n * const client = new WarpGrepClient({ morphApiKey: process.env.MORPH_API_KEY });\n * const result = await client.execute({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n * ```\n * \n * @example\n * ```typescript\n * // As a tool for AI agents\n * import { createWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/anthropic';\n * \n * const tool = createWarpGrepTool({ repoRoot: '.' });\n * // Pass to Claude, GPT, Gemini, etc.\n * ```\n * \n * @example Remote sandbox (E2B, Modal, Daytona, etc.)\n * ```typescript\n * import { createMorphWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/anthropic';\n * \n * const tool = createMorphWarpGrepTool({\n * repoRoot: '/home/repo',\n * remoteCommands: {\n * grep: async (pattern, path) => (await sandbox.run(`rg '${pattern}' '${path}'`)).stdout,\n * read: async (path, start, end) => (await sandbox.run(`sed -n '${start},${end}p' '${path}'`)).stdout,\n * listDir: async (path, maxDepth) => (await sandbox.run(`find '${path}' -maxdepth ${maxDepth}`)).stdout,\n * },\n * });\n * ```\n * \n * @example Provider-agnostic usage (bring your own tool abstraction)\n * ```typescript\n * import { \n * warpGrepInputSchema,\n * executeToolCall,\n * WARP_GREP_TOOL_NAME,\n * WARP_GREP_DESCRIPTION,\n * } from '@morphllm/morphsdk/tools/warp-grep';\n * \n * // Use with your own tool definition abstraction\n * const toolDef = createToolDef({\n * name: WARP_GREP_TOOL_NAME,\n * description: WARP_GREP_DESCRIPTION,\n * schema: warpGrepInputSchema,\n * });\n * \n * // Execute\n * const result = await executeToolCall(\n * { query: 'Find auth middleware' },\n * { repoRoot: '.', morphApiKey: process.env.MORPH_API_KEY }\n * );\n * ```\n */\n\nimport { z } from 'zod';\n\n/** Provider-agnostic Zod schema for warp grep input */\nexport const warpGrepInputSchema = z.object({\n query: z.string().describe('Free-form repository question'),\n});\n\nexport type WarpGrepInputSchema = z.infer<typeof warpGrepInputSchema>;\n\n// Core client and functions\nexport { WarpGrepClient, executeWarpGrep, executeToolCall, formatResult } from './client.js';\n\n// Types\nexport type {\n WarpGrepClientConfig,\n WarpGrepInput,\n WarpGrepResult,\n WarpGrepContext,\n WarpGrepToolConfig,\n WarpGrepProvider,\n GrepResult,\n ReadResult,\n ListDirectoryEntry,\n RemoteCommands,\n WarpGrepStep,\n} from './types.js';\n\n// Prompts\nexport {\n WARP_GREP_DESCRIPTION,\n WARP_GREP_TOOL_NAME,\n WARP_GREP_SYSTEM_PROMPT,\n getSystemPrompt,\n} from './prompts.js';\n\n// Providers (re-exported for convenience)\nexport { LocalRipgrepProvider, RemoteCommandsProvider } from './providers/index.js';\n\n// Path utilities (for handling model path prediction issues)\nexport { fixPathRepetition } from './utils/paths.js';\n\n// Agent internals (advanced usage)\nexport { runWarpGrep, runWarpGrepStreaming } from './agent/index.js';\nexport type { AgentRunResult, SessionConfig, ChatMessage } from './agent/index.js';\n\n// Internal agent tools (for harness builders)\nexport { toolGrep, toolRead, toolListDirectory, readFinishFiles, normalizeFinishFiles } from './agent/tools/index.js';\n\n// Provider adapters are available via dedicated import paths:\n// - '@morphllm/morphsdk/tools/warp-grep/anthropic'\n// - '@morphllm/morphsdk/tools/warp-grep/openai'\n// - '@morphllm/morphsdk/tools/warp-grep/gemini'\n// - '@morphllm/morphsdk/tools/warp-grep/vercel'\n"],"mappings":";AA6EA,SAAS,SAAS;AAGX,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,OAAO,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAC5D,CAAC;","names":[]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createWarpGrepTool as createWarpGrepTool2
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AJEE5RRB.js";
|
|
4
4
|
import {
|
|
5
5
|
createWarpGrepTool
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IXNX4HMC.js";
|
|
7
7
|
import {
|
|
8
8
|
createWarpGrepTool as createWarpGrepTool3
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5X7IJXKA.js";
|
|
10
10
|
import {
|
|
11
11
|
WarpGrepClient
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-37SJ3IOY.js";
|
|
13
13
|
import {
|
|
14
14
|
createCodebaseSearchTool as createCodebaseSearchTool3
|
|
15
15
|
} from "./chunk-UBX7QYBD.js";
|
|
@@ -280,4 +280,4 @@ export {
|
|
|
280
280
|
VercelToolFactory,
|
|
281
281
|
MorphClient
|
|
282
282
|
};
|
|
283
|
-
//# sourceMappingURL=chunk-
|
|
283
|
+
//# sourceMappingURL=chunk-SQF3OG24.js.map
|
|
@@ -7,7 +7,7 @@ import { MorphGit } from './git/client.js';
|
|
|
7
7
|
import { OpenAIRouter, AnthropicRouter, GeminiRouter, RawRouter } from './modelrouter/core.js';
|
|
8
8
|
import { EditFileConfig, EditFileInput, EditFileResult, EditChanges } from './tools/fastapply/types.js';
|
|
9
9
|
import { CodebaseSearchConfig, CodebaseSearchInput, CodebaseSearchResult } from './tools/codebase_search/types.js';
|
|
10
|
-
import { d as WarpGrepToolConfig, b as WarpGrepResult, c as WarpGrepContext } from './types-
|
|
10
|
+
import { d as WarpGrepToolConfig, b as WarpGrepResult, c as WarpGrepContext } from './types-BMowL9iZ.js';
|
|
11
11
|
import * as openai_resources_index_mjs from 'openai/resources/index.mjs';
|
|
12
12
|
import * as _anthropic_ai_sdk_resources_messages_mjs from '@anthropic-ai/sdk/resources/messages.mjs';
|
|
13
13
|
import * as ai from 'ai';
|