@morphllm/morphsdk 0.2.113 → 0.2.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ALTKGCG5.js → chunk-CM75JPVD.js} +2 -2
- package/dist/{chunk-Z6TF5G4R.js → chunk-FXBT4UDY.js} +16 -32
- package/dist/chunk-FXBT4UDY.js.map +1 -0
- package/dist/{chunk-FL4ZBHK2.js → chunk-GQUNK324.js} +2 -2
- package/dist/{chunk-TGUQHW3I.js → chunk-HMAX2FEE.js} +2 -2
- package/dist/{chunk-R3BSIJCL.js → chunk-M5DR2WOZ.js} +1 -1
- package/dist/{chunk-23R562QJ.js → chunk-NTDAIKZI.js} +9 -4
- package/dist/chunk-NTDAIKZI.js.map +1 -0
- package/dist/{chunk-YY7NZLAI.js → chunk-RBTL6EJG.js} +11 -3
- package/dist/chunk-RBTL6EJG.js.map +1 -0
- package/dist/{chunk-HI35Y6EZ.js → chunk-SYZ75S3S.js} +18 -5
- package/dist/chunk-SYZ75S3S.js.map +1 -0
- package/dist/{chunk-2SOSDQFG.js → chunk-TZBDXZFC.js} +9 -9
- package/dist/{chunk-A3PK4H7A.js → chunk-UNHHRMU7.js} +2 -2
- package/dist/{chunk-JD4H6U3Z.js → chunk-Y5BB7JFH.js} +2 -2
- package/dist/{client-Bm_umdno.d.ts → client-D7iO2TbA.d.ts} +7 -0
- package/dist/client.cjs +123 -125
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +11 -11
- package/dist/edge.cjs +99 -102
- package/dist/edge.cjs.map +1 -1
- package/dist/edge.js +1 -1
- package/dist/index.cjs +123 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -11
- package/dist/tools/fastapply/anthropic.cjs +16 -108
- package/dist/tools/fastapply/anthropic.cjs.map +1 -1
- package/dist/tools/fastapply/anthropic.js +3 -4
- package/dist/tools/fastapply/apply.cjs +25 -102
- package/dist/tools/fastapply/apply.cjs.map +1 -1
- package/dist/tools/fastapply/apply.d.ts +3 -2
- package/dist/tools/fastapply/apply.js +1 -2
- package/dist/tools/fastapply/core.cjs +16 -108
- package/dist/tools/fastapply/core.cjs.map +1 -1
- package/dist/tools/fastapply/core.js +2 -3
- package/dist/tools/fastapply/index.cjs +16 -108
- package/dist/tools/fastapply/index.cjs.map +1 -1
- package/dist/tools/fastapply/index.js +5 -6
- package/dist/tools/fastapply/openai.cjs +16 -108
- package/dist/tools/fastapply/openai.cjs.map +1 -1
- package/dist/tools/fastapply/openai.js +3 -4
- package/dist/tools/fastapply/vercel.cjs +16 -108
- package/dist/tools/fastapply/vercel.cjs.map +1 -1
- package/dist/tools/fastapply/vercel.js +3 -4
- package/dist/tools/index.cjs +16 -108
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.js +5 -6
- package/dist/tools/warp_grep/agent/runner.cjs +10 -2
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.js +1 -1
- package/dist/tools/warp_grep/anthropic.cjs +8 -2
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.js +3 -3
- package/dist/tools/warp_grep/client.cjs +18 -4
- package/dist/tools/warp_grep/client.cjs.map +1 -1
- package/dist/tools/warp_grep/client.d.ts +7 -1
- package/dist/tools/warp_grep/client.js +4 -2
- package/dist/tools/warp_grep/gemini.cjs +8 -2
- package/dist/tools/warp_grep/gemini.cjs.map +1 -1
- package/dist/tools/warp_grep/gemini.js +2 -2
- package/dist/tools/warp_grep/index.cjs +16 -4
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.js +2 -2
- package/dist/tools/warp_grep/openai.cjs +8 -2
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.js +3 -3
- package/dist/tools/warp_grep/vercel.cjs +216 -4
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.d.ts +7 -0
- package/dist/tools/warp_grep/vercel.js +3 -3
- package/package.json +6 -1
- package/dist/chunk-23R562QJ.js.map +0 -1
- package/dist/chunk-HI35Y6EZ.js.map +0 -1
- package/dist/chunk-YY7NZLAI.js.map +0 -1
- package/dist/chunk-Z6TF5G4R.js.map +0 -1
- /package/dist/{chunk-ALTKGCG5.js.map → chunk-CM75JPVD.js.map} +0 -0
- /package/dist/{chunk-FL4ZBHK2.js.map → chunk-GQUNK324.js.map} +0 -0
- /package/dist/{chunk-TGUQHW3I.js.map → chunk-HMAX2FEE.js.map} +0 -0
- /package/dist/{chunk-R3BSIJCL.js.map → chunk-M5DR2WOZ.js.map} +0 -0
- /package/dist/{chunk-2SOSDQFG.js.map → chunk-TZBDXZFC.js.map} +0 -0
- /package/dist/{chunk-A3PK4H7A.js.map → chunk-UNHHRMU7.js.map} +0 -0
- /package/dist/{chunk-JD4H6U3Z.js.map → chunk-Y5BB7JFH.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -30,86 +30,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
|
-
// tools/utils/resilience.ts
|
|
34
|
-
async function fetchWithRetry(url, options, retryConfig = {}) {
|
|
35
|
-
const {
|
|
36
|
-
maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,
|
|
37
|
-
initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,
|
|
38
|
-
maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,
|
|
39
|
-
backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,
|
|
40
|
-
retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,
|
|
41
|
-
onRetry
|
|
42
|
-
} = retryConfig;
|
|
43
|
-
let lastError = null;
|
|
44
|
-
let delay = initialDelay;
|
|
45
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
46
|
-
try {
|
|
47
|
-
const response = await fetch(url, options);
|
|
48
|
-
if (response.status === 429 || response.status === 503) {
|
|
49
|
-
if (attempt < maxRetries) {
|
|
50
|
-
const retryAfter = response.headers.get("Retry-After");
|
|
51
|
-
const waitTime = retryAfter ? parseInt(retryAfter) * 1e3 : Math.min(delay, maxDelay);
|
|
52
|
-
const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);
|
|
53
|
-
if (onRetry) {
|
|
54
|
-
onRetry(attempt + 1, error);
|
|
55
|
-
}
|
|
56
|
-
await sleep(waitTime);
|
|
57
|
-
delay *= backoffMultiplier;
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return response;
|
|
62
|
-
} catch (error) {
|
|
63
|
-
lastError = error;
|
|
64
|
-
const isRetryable = retryableErrors.some(
|
|
65
|
-
(errType) => lastError?.message?.includes(errType)
|
|
66
|
-
);
|
|
67
|
-
if (!isRetryable || attempt === maxRetries) {
|
|
68
|
-
throw lastError;
|
|
69
|
-
}
|
|
70
|
-
const waitTime = Math.min(delay, maxDelay);
|
|
71
|
-
if (onRetry) {
|
|
72
|
-
onRetry(attempt + 1, lastError);
|
|
73
|
-
}
|
|
74
|
-
await sleep(waitTime);
|
|
75
|
-
delay *= backoffMultiplier;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
throw lastError || new Error("Max retries exceeded");
|
|
79
|
-
}
|
|
80
|
-
async function withTimeout(promise, timeoutMs, errorMessage) {
|
|
81
|
-
let timeoutId;
|
|
82
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
83
|
-
timeoutId = setTimeout(() => {
|
|
84
|
-
reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));
|
|
85
|
-
}, timeoutMs);
|
|
86
|
-
});
|
|
87
|
-
try {
|
|
88
|
-
const result = await Promise.race([promise, timeoutPromise]);
|
|
89
|
-
clearTimeout(timeoutId);
|
|
90
|
-
return result;
|
|
91
|
-
} catch (error) {
|
|
92
|
-
clearTimeout(timeoutId);
|
|
93
|
-
throw error;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
function sleep(ms) {
|
|
97
|
-
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
98
|
-
}
|
|
99
|
-
var DEFAULT_RETRY_CONFIG;
|
|
100
|
-
var init_resilience = __esm({
|
|
101
|
-
"tools/utils/resilience.ts"() {
|
|
102
|
-
"use strict";
|
|
103
|
-
DEFAULT_RETRY_CONFIG = {
|
|
104
|
-
maxRetries: 3,
|
|
105
|
-
initialDelay: 1e3,
|
|
106
|
-
maxDelay: 3e4,
|
|
107
|
-
backoffMultiplier: 2,
|
|
108
|
-
retryableErrors: ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"]
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
|
|
113
33
|
// tools/fastapply/apply.ts
|
|
114
34
|
var apply_exports = {};
|
|
115
35
|
__export(apply_exports, {
|
|
@@ -166,37 +86,25 @@ async function callMorphAPI(originalCode, codeEdit, instructions, filepath, conf
|
|
|
166
86
|
console.log(`[FastApply] Original: ${originalCode.length} chars, Edit: ${codeEdit.length} chars`);
|
|
167
87
|
}
|
|
168
88
|
const startTime = Date.now();
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
method: "POST",
|
|
173
|
-
headers: {
|
|
174
|
-
"Content-Type": "application/json",
|
|
175
|
-
"Authorization": `Bearer ${apiKey}`
|
|
176
|
-
},
|
|
177
|
-
body: JSON.stringify({
|
|
178
|
-
model: "morph-v3-fast",
|
|
179
|
-
messages: [{ role: "user", content: message }]
|
|
180
|
-
})
|
|
181
|
-
},
|
|
182
|
-
config.retryConfig
|
|
183
|
-
);
|
|
184
|
-
const response = await withTimeout(
|
|
185
|
-
fetchPromise,
|
|
89
|
+
const client = new import_openai.default({
|
|
90
|
+
apiKey,
|
|
91
|
+
baseURL: `${apiUrl}/v1`,
|
|
186
92
|
timeout,
|
|
187
|
-
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
93
|
+
maxRetries: config.retryConfig?.maxRetries ?? 3
|
|
94
|
+
});
|
|
95
|
+
const completion = await client.chat.completions.create({
|
|
96
|
+
model: "morph-v3-fast",
|
|
97
|
+
messages: [{ role: "user", content: message }]
|
|
98
|
+
});
|
|
99
|
+
const content = completion.choices[0]?.message?.content;
|
|
100
|
+
if (!content) {
|
|
101
|
+
throw new Error("Morph API returned empty response");
|
|
193
102
|
}
|
|
194
|
-
const data = await response.json();
|
|
195
103
|
const elapsed = Date.now() - startTime;
|
|
196
104
|
if (debug) {
|
|
197
|
-
console.log(`[FastApply]
|
|
105
|
+
console.log(`[FastApply] Success in ${elapsed}ms, merged: ${content.length} chars`);
|
|
198
106
|
}
|
|
199
|
-
return { content
|
|
107
|
+
return { content, completionId: completion.id };
|
|
200
108
|
}
|
|
201
109
|
async function applyEdit(input, config = {}) {
|
|
202
110
|
const debug = config.debug || false;
|
|
@@ -231,12 +139,12 @@ async function applyEdit(input, config = {}) {
|
|
|
231
139
|
};
|
|
232
140
|
}
|
|
233
141
|
}
|
|
234
|
-
var import_diff, DEFAULT_API_URL, DEFAULT_TIMEOUT;
|
|
142
|
+
var import_diff, import_openai, DEFAULT_API_URL, DEFAULT_TIMEOUT;
|
|
235
143
|
var init_apply = __esm({
|
|
236
144
|
"tools/fastapply/apply.ts"() {
|
|
237
145
|
"use strict";
|
|
238
146
|
import_diff = require("diff");
|
|
239
|
-
|
|
147
|
+
import_openai = __toESM(require("openai"), 1);
|
|
240
148
|
DEFAULT_API_URL = "https://api.morphllm.com";
|
|
241
149
|
DEFAULT_TIMEOUT = 3e4;
|
|
242
150
|
}
|
|
@@ -913,8 +821,81 @@ async function executeEditFile(input, config = {}) {
|
|
|
913
821
|
}
|
|
914
822
|
}
|
|
915
823
|
|
|
824
|
+
// tools/utils/resilience.ts
|
|
825
|
+
var DEFAULT_RETRY_CONFIG = {
|
|
826
|
+
maxRetries: 3,
|
|
827
|
+
initialDelay: 1e3,
|
|
828
|
+
maxDelay: 3e4,
|
|
829
|
+
backoffMultiplier: 2,
|
|
830
|
+
retryableErrors: ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"]
|
|
831
|
+
};
|
|
832
|
+
async function fetchWithRetry(url, options, retryConfig = {}) {
|
|
833
|
+
const {
|
|
834
|
+
maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,
|
|
835
|
+
initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,
|
|
836
|
+
maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,
|
|
837
|
+
backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,
|
|
838
|
+
retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,
|
|
839
|
+
onRetry
|
|
840
|
+
} = retryConfig;
|
|
841
|
+
let lastError = null;
|
|
842
|
+
let delay = initialDelay;
|
|
843
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
844
|
+
try {
|
|
845
|
+
const response = await fetch(url, options);
|
|
846
|
+
if (response.status === 429 || response.status === 503) {
|
|
847
|
+
if (attempt < maxRetries) {
|
|
848
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
849
|
+
const waitTime = retryAfter ? parseInt(retryAfter) * 1e3 : Math.min(delay, maxDelay);
|
|
850
|
+
const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);
|
|
851
|
+
if (onRetry) {
|
|
852
|
+
onRetry(attempt + 1, error);
|
|
853
|
+
}
|
|
854
|
+
await sleep(waitTime);
|
|
855
|
+
delay *= backoffMultiplier;
|
|
856
|
+
continue;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return response;
|
|
860
|
+
} catch (error) {
|
|
861
|
+
lastError = error;
|
|
862
|
+
const isRetryable = retryableErrors.some(
|
|
863
|
+
(errType) => lastError?.message?.includes(errType)
|
|
864
|
+
);
|
|
865
|
+
if (!isRetryable || attempt === maxRetries) {
|
|
866
|
+
throw lastError;
|
|
867
|
+
}
|
|
868
|
+
const waitTime = Math.min(delay, maxDelay);
|
|
869
|
+
if (onRetry) {
|
|
870
|
+
onRetry(attempt + 1, lastError);
|
|
871
|
+
}
|
|
872
|
+
await sleep(waitTime);
|
|
873
|
+
delay *= backoffMultiplier;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
throw lastError || new Error("Max retries exceeded");
|
|
877
|
+
}
|
|
878
|
+
async function withTimeout(promise, timeoutMs, errorMessage) {
|
|
879
|
+
let timeoutId;
|
|
880
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
881
|
+
timeoutId = setTimeout(() => {
|
|
882
|
+
reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));
|
|
883
|
+
}, timeoutMs);
|
|
884
|
+
});
|
|
885
|
+
try {
|
|
886
|
+
const result = await Promise.race([promise, timeoutPromise]);
|
|
887
|
+
clearTimeout(timeoutId);
|
|
888
|
+
return result;
|
|
889
|
+
} catch (error) {
|
|
890
|
+
clearTimeout(timeoutId);
|
|
891
|
+
throw error;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
function sleep(ms) {
|
|
895
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
896
|
+
}
|
|
897
|
+
|
|
916
898
|
// tools/codebase_search/core.ts
|
|
917
|
-
init_resilience();
|
|
918
899
|
var CodebaseSearchClient = class {
|
|
919
900
|
config;
|
|
920
901
|
constructor(config = {}) {
|
|
@@ -1009,9 +990,6 @@ async function executeCodebaseSearch(input, config) {
|
|
|
1009
990
|
}
|
|
1010
991
|
}
|
|
1011
992
|
|
|
1012
|
-
// tools/browser/core.ts
|
|
1013
|
-
init_resilience();
|
|
1014
|
-
|
|
1015
993
|
// tools/browser/live.ts
|
|
1016
994
|
var LIVE_PRESETS = {
|
|
1017
995
|
/** Read-only monitoring (no interaction) */
|
|
@@ -1112,9 +1090,6 @@ function resolvePreset(optionsOrPreset) {
|
|
|
1112
1090
|
return optionsOrPreset;
|
|
1113
1091
|
}
|
|
1114
1092
|
|
|
1115
|
-
// tools/browser/profiles/core.ts
|
|
1116
|
-
init_resilience();
|
|
1117
|
-
|
|
1118
1093
|
// tools/browser/errors.ts
|
|
1119
1094
|
var MorphError = class extends Error {
|
|
1120
1095
|
/** Error code for programmatic handling */
|
|
@@ -3044,7 +3019,7 @@ function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS
|
|
|
3044
3019
|
}
|
|
3045
3020
|
|
|
3046
3021
|
// tools/warp_grep/agent/runner.ts
|
|
3047
|
-
var
|
|
3022
|
+
var import_openai2 = __toESM(require("openai"), 1);
|
|
3048
3023
|
var import_path3 = __toESM(require("path"), 1);
|
|
3049
3024
|
var parser = new LLMResponseParser();
|
|
3050
3025
|
var DEFAULT_API_URL3 = "https://api.morphllm.com";
|
|
@@ -3052,7 +3027,7 @@ async function callModel(messages, model, options = {}) {
|
|
|
3052
3027
|
const baseUrl = options.morphApiUrl || DEFAULT_API_URL3;
|
|
3053
3028
|
const apiKey = options.morphApiKey || process.env.MORPH_API_KEY || "";
|
|
3054
3029
|
const timeoutMs = options.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
|
|
3055
|
-
const client = new
|
|
3030
|
+
const client = new import_openai2.default({
|
|
3056
3031
|
apiKey,
|
|
3057
3032
|
baseURL: `${baseUrl}/v1`,
|
|
3058
3033
|
maxRetries: options.retryConfig?.maxRetries,
|
|
@@ -3067,7 +3042,7 @@ async function callModel(messages, model, options = {}) {
|
|
|
3067
3042
|
messages
|
|
3068
3043
|
});
|
|
3069
3044
|
} catch (error) {
|
|
3070
|
-
if (error instanceof
|
|
3045
|
+
if (error instanceof import_openai2.default.APIError && error.status === 404) {
|
|
3071
3046
|
throw new Error(
|
|
3072
3047
|
"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"
|
|
3073
3048
|
);
|
|
@@ -3107,17 +3082,21 @@ async function runWarpGrep(config) {
|
|
|
3107
3082
|
retryConfig: config.retryConfig,
|
|
3108
3083
|
timeout: timeoutMs
|
|
3109
3084
|
}).catch((e) => {
|
|
3110
|
-
|
|
3085
|
+
const errMsg = e instanceof Error ? e.message : String(e);
|
|
3086
|
+
console.error(`[warp_grep] Morph API call failed on turn ${turn}:`, errMsg);
|
|
3087
|
+
errors.push({ message: errMsg });
|
|
3111
3088
|
return "";
|
|
3112
3089
|
});
|
|
3113
3090
|
turnMetrics.morph_api_ms = Date.now() - modelCallStart;
|
|
3114
3091
|
if (!assistantContent) {
|
|
3092
|
+
console.error(`[warp_grep] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);
|
|
3115
3093
|
timings.turns.push(turnMetrics);
|
|
3116
3094
|
break;
|
|
3117
3095
|
}
|
|
3118
3096
|
messages.push({ role: "assistant", content: assistantContent });
|
|
3119
3097
|
const toolCalls = parser.parse(assistantContent);
|
|
3120
3098
|
if (toolCalls.length === 0) {
|
|
3099
|
+
console.error(`[warp_grep] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));
|
|
3121
3100
|
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" });
|
|
3122
3101
|
terminationReason = "terminated";
|
|
3123
3102
|
timings.turns.push(turnMetrics);
|
|
@@ -3250,17 +3229,21 @@ async function* runWarpGrepStreaming(config) {
|
|
|
3250
3229
|
retryConfig: config.retryConfig,
|
|
3251
3230
|
timeout: timeoutMs
|
|
3252
3231
|
}).catch((e) => {
|
|
3253
|
-
|
|
3232
|
+
const errMsg = e instanceof Error ? e.message : String(e);
|
|
3233
|
+
console.error(`[warp_grep:stream] Morph API call failed on turn ${turn}:`, errMsg);
|
|
3234
|
+
errors.push({ message: errMsg });
|
|
3254
3235
|
return "";
|
|
3255
3236
|
});
|
|
3256
3237
|
turnMetrics.morph_api_ms = Date.now() - modelCallStart;
|
|
3257
3238
|
if (!assistantContent) {
|
|
3239
|
+
console.error(`[warp_grep:stream] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);
|
|
3258
3240
|
timings.turns.push(turnMetrics);
|
|
3259
3241
|
break;
|
|
3260
3242
|
}
|
|
3261
3243
|
messages.push({ role: "assistant", content: assistantContent });
|
|
3262
3244
|
const toolCalls = parser.parse(assistantContent);
|
|
3263
3245
|
if (toolCalls.length === 0) {
|
|
3246
|
+
console.error(`[warp_grep:stream] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));
|
|
3264
3247
|
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" });
|
|
3265
3248
|
terminationReason = "terminated";
|
|
3266
3249
|
timings.turns.push(turnMetrics);
|
|
@@ -3607,7 +3590,9 @@ async function executeToolCall(input, config) {
|
|
|
3607
3590
|
});
|
|
3608
3591
|
const finish = result.finish;
|
|
3609
3592
|
if (result.terminationReason !== "completed" || !finish?.metadata) {
|
|
3610
|
-
|
|
3593
|
+
const errorDetails = result.errors?.map((e) => e.message).join("; ") || "unknown reason";
|
|
3594
|
+
console.error(`[warp_grep] executeToolCall failed. Reason: ${result.terminationReason}. Errors: ${errorDetails}. Turns: ${result.timings?.turns?.length ?? 0}`);
|
|
3595
|
+
return { success: false, error: `Search did not complete: ${errorDetails}` };
|
|
3611
3596
|
}
|
|
3612
3597
|
const contexts = (finish.resolved ?? []).map((r) => ({
|
|
3613
3598
|
file: r.path,
|
|
@@ -3619,7 +3604,9 @@ async function executeToolCall(input, config) {
|
|
|
3619
3604
|
function processAgentResult(result) {
|
|
3620
3605
|
const finish = result.finish;
|
|
3621
3606
|
if (result.terminationReason !== "completed" || !finish?.metadata) {
|
|
3622
|
-
|
|
3607
|
+
const errorDetails = result.errors?.map((e) => e.message).join("; ") || "unknown reason";
|
|
3608
|
+
console.error(`[warp_grep] processAgentResult failed. Reason: ${result.terminationReason}. Errors: ${errorDetails}. Turns: ${result.timings?.turns?.length ?? 0}`);
|
|
3609
|
+
return { success: false, error: `Search did not complete: ${errorDetails}` };
|
|
3623
3610
|
}
|
|
3624
3611
|
const contexts = (finish.resolved ?? []).map((r) => ({
|
|
3625
3612
|
file: r.path,
|
|
@@ -4574,7 +4561,6 @@ var import_isomorphic_git2 = __toESM(require("isomorphic-git"), 1);
|
|
|
4574
4561
|
var import_node2 = __toESM(require("isomorphic-git/http/node"), 1);
|
|
4575
4562
|
|
|
4576
4563
|
// modelrouter/core.ts
|
|
4577
|
-
init_resilience();
|
|
4578
4564
|
var DEFAULT_CONFIG3 = {
|
|
4579
4565
|
apiUrl: "https://api.morphllm.com",
|
|
4580
4566
|
timeout: 5e3,
|
|
@@ -5253,14 +5239,26 @@ function createWarpGrepTool3(config) {
|
|
|
5253
5239
|
description: config.description ?? WARP_GREP_DESCRIPTION,
|
|
5254
5240
|
inputSchema: schema,
|
|
5255
5241
|
execute: async (params) => {
|
|
5256
|
-
const
|
|
5242
|
+
const steps = [];
|
|
5243
|
+
const generator = executeToolCallStreaming(params, config);
|
|
5244
|
+
let result;
|
|
5245
|
+
for (; ; ) {
|
|
5246
|
+
const { value, done } = await generator.next();
|
|
5247
|
+
if (done) {
|
|
5248
|
+
result = value;
|
|
5249
|
+
break;
|
|
5250
|
+
}
|
|
5251
|
+
steps.push(value);
|
|
5252
|
+
}
|
|
5257
5253
|
if (!result.success) {
|
|
5258
5254
|
throw new Error(`Failed to search codebase: ${result.error}`);
|
|
5259
5255
|
}
|
|
5256
|
+
const allToolCalls = steps.flatMap((s) => s.toolCalls);
|
|
5260
5257
|
return {
|
|
5261
5258
|
success: true,
|
|
5262
5259
|
contexts: result.contexts,
|
|
5263
|
-
summary: result.summary
|
|
5260
|
+
summary: result.summary,
|
|
5261
|
+
progress: allToolCalls.length > 0 ? { turn: steps.length, toolCalls: allToolCalls } : void 0
|
|
5264
5262
|
};
|
|
5265
5263
|
}
|
|
5266
5264
|
});
|