@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/client.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
|
}
|
|
@@ -894,8 +802,81 @@ async function executeEditFile(input, config = {}) {
|
|
|
894
802
|
}
|
|
895
803
|
}
|
|
896
804
|
|
|
805
|
+
// tools/utils/resilience.ts
|
|
806
|
+
var DEFAULT_RETRY_CONFIG = {
|
|
807
|
+
maxRetries: 3,
|
|
808
|
+
initialDelay: 1e3,
|
|
809
|
+
maxDelay: 3e4,
|
|
810
|
+
backoffMultiplier: 2,
|
|
811
|
+
retryableErrors: ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"]
|
|
812
|
+
};
|
|
813
|
+
async function fetchWithRetry(url, options, retryConfig = {}) {
|
|
814
|
+
const {
|
|
815
|
+
maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,
|
|
816
|
+
initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,
|
|
817
|
+
maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,
|
|
818
|
+
backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,
|
|
819
|
+
retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,
|
|
820
|
+
onRetry
|
|
821
|
+
} = retryConfig;
|
|
822
|
+
let lastError = null;
|
|
823
|
+
let delay = initialDelay;
|
|
824
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
825
|
+
try {
|
|
826
|
+
const response = await fetch(url, options);
|
|
827
|
+
if (response.status === 429 || response.status === 503) {
|
|
828
|
+
if (attempt < maxRetries) {
|
|
829
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
830
|
+
const waitTime = retryAfter ? parseInt(retryAfter) * 1e3 : Math.min(delay, maxDelay);
|
|
831
|
+
const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);
|
|
832
|
+
if (onRetry) {
|
|
833
|
+
onRetry(attempt + 1, error);
|
|
834
|
+
}
|
|
835
|
+
await sleep(waitTime);
|
|
836
|
+
delay *= backoffMultiplier;
|
|
837
|
+
continue;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return response;
|
|
841
|
+
} catch (error) {
|
|
842
|
+
lastError = error;
|
|
843
|
+
const isRetryable = retryableErrors.some(
|
|
844
|
+
(errType) => lastError?.message?.includes(errType)
|
|
845
|
+
);
|
|
846
|
+
if (!isRetryable || attempt === maxRetries) {
|
|
847
|
+
throw lastError;
|
|
848
|
+
}
|
|
849
|
+
const waitTime = Math.min(delay, maxDelay);
|
|
850
|
+
if (onRetry) {
|
|
851
|
+
onRetry(attempt + 1, lastError);
|
|
852
|
+
}
|
|
853
|
+
await sleep(waitTime);
|
|
854
|
+
delay *= backoffMultiplier;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
throw lastError || new Error("Max retries exceeded");
|
|
858
|
+
}
|
|
859
|
+
async function withTimeout(promise, timeoutMs, errorMessage) {
|
|
860
|
+
let timeoutId;
|
|
861
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
862
|
+
timeoutId = setTimeout(() => {
|
|
863
|
+
reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));
|
|
864
|
+
}, timeoutMs);
|
|
865
|
+
});
|
|
866
|
+
try {
|
|
867
|
+
const result = await Promise.race([promise, timeoutPromise]);
|
|
868
|
+
clearTimeout(timeoutId);
|
|
869
|
+
return result;
|
|
870
|
+
} catch (error) {
|
|
871
|
+
clearTimeout(timeoutId);
|
|
872
|
+
throw error;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
function sleep(ms) {
|
|
876
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
877
|
+
}
|
|
878
|
+
|
|
897
879
|
// tools/codebase_search/core.ts
|
|
898
|
-
init_resilience();
|
|
899
880
|
var CodebaseSearchClient = class {
|
|
900
881
|
config;
|
|
901
882
|
constructor(config = {}) {
|
|
@@ -990,9 +971,6 @@ async function executeCodebaseSearch(input, config) {
|
|
|
990
971
|
}
|
|
991
972
|
}
|
|
992
973
|
|
|
993
|
-
// tools/browser/core.ts
|
|
994
|
-
init_resilience();
|
|
995
|
-
|
|
996
974
|
// tools/browser/live.ts
|
|
997
975
|
var LIVE_PRESETS = {
|
|
998
976
|
/** Read-only monitoring (no interaction) */
|
|
@@ -1093,9 +1071,6 @@ function resolvePreset(optionsOrPreset) {
|
|
|
1093
1071
|
return optionsOrPreset;
|
|
1094
1072
|
}
|
|
1095
1073
|
|
|
1096
|
-
// tools/browser/profiles/core.ts
|
|
1097
|
-
init_resilience();
|
|
1098
|
-
|
|
1099
1074
|
// tools/browser/errors.ts
|
|
1100
1075
|
var MorphError = class extends Error {
|
|
1101
1076
|
/** Error code for programmatic handling */
|
|
@@ -3025,7 +3000,7 @@ function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS
|
|
|
3025
3000
|
}
|
|
3026
3001
|
|
|
3027
3002
|
// tools/warp_grep/agent/runner.ts
|
|
3028
|
-
var
|
|
3003
|
+
var import_openai2 = __toESM(require("openai"), 1);
|
|
3029
3004
|
var import_path3 = __toESM(require("path"), 1);
|
|
3030
3005
|
var parser = new LLMResponseParser();
|
|
3031
3006
|
var DEFAULT_API_URL3 = "https://api.morphllm.com";
|
|
@@ -3033,7 +3008,7 @@ async function callModel(messages, model, options = {}) {
|
|
|
3033
3008
|
const baseUrl = options.morphApiUrl || DEFAULT_API_URL3;
|
|
3034
3009
|
const apiKey = options.morphApiKey || process.env.MORPH_API_KEY || "";
|
|
3035
3010
|
const timeoutMs = options.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
|
|
3036
|
-
const client = new
|
|
3011
|
+
const client = new import_openai2.default({
|
|
3037
3012
|
apiKey,
|
|
3038
3013
|
baseURL: `${baseUrl}/v1`,
|
|
3039
3014
|
maxRetries: options.retryConfig?.maxRetries,
|
|
@@ -3048,7 +3023,7 @@ async function callModel(messages, model, options = {}) {
|
|
|
3048
3023
|
messages
|
|
3049
3024
|
});
|
|
3050
3025
|
} catch (error) {
|
|
3051
|
-
if (error instanceof
|
|
3026
|
+
if (error instanceof import_openai2.default.APIError && error.status === 404) {
|
|
3052
3027
|
throw new Error(
|
|
3053
3028
|
"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"
|
|
3054
3029
|
);
|
|
@@ -3088,17 +3063,21 @@ async function runWarpGrep(config) {
|
|
|
3088
3063
|
retryConfig: config.retryConfig,
|
|
3089
3064
|
timeout: timeoutMs
|
|
3090
3065
|
}).catch((e) => {
|
|
3091
|
-
|
|
3066
|
+
const errMsg = e instanceof Error ? e.message : String(e);
|
|
3067
|
+
console.error(`[warp_grep] Morph API call failed on turn ${turn}:`, errMsg);
|
|
3068
|
+
errors.push({ message: errMsg });
|
|
3092
3069
|
return "";
|
|
3093
3070
|
});
|
|
3094
3071
|
turnMetrics.morph_api_ms = Date.now() - modelCallStart;
|
|
3095
3072
|
if (!assistantContent) {
|
|
3073
|
+
console.error(`[warp_grep] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);
|
|
3096
3074
|
timings.turns.push(turnMetrics);
|
|
3097
3075
|
break;
|
|
3098
3076
|
}
|
|
3099
3077
|
messages.push({ role: "assistant", content: assistantContent });
|
|
3100
3078
|
const toolCalls = parser.parse(assistantContent);
|
|
3101
3079
|
if (toolCalls.length === 0) {
|
|
3080
|
+
console.error(`[warp_grep] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));
|
|
3102
3081
|
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" });
|
|
3103
3082
|
terminationReason = "terminated";
|
|
3104
3083
|
timings.turns.push(turnMetrics);
|
|
@@ -3231,17 +3210,21 @@ async function* runWarpGrepStreaming(config) {
|
|
|
3231
3210
|
retryConfig: config.retryConfig,
|
|
3232
3211
|
timeout: timeoutMs
|
|
3233
3212
|
}).catch((e) => {
|
|
3234
|
-
|
|
3213
|
+
const errMsg = e instanceof Error ? e.message : String(e);
|
|
3214
|
+
console.error(`[warp_grep:stream] Morph API call failed on turn ${turn}:`, errMsg);
|
|
3215
|
+
errors.push({ message: errMsg });
|
|
3235
3216
|
return "";
|
|
3236
3217
|
});
|
|
3237
3218
|
turnMetrics.morph_api_ms = Date.now() - modelCallStart;
|
|
3238
3219
|
if (!assistantContent) {
|
|
3220
|
+
console.error(`[warp_grep:stream] Empty response from Morph API on turn ${turn}. Errors so far:`, errors);
|
|
3239
3221
|
timings.turns.push(turnMetrics);
|
|
3240
3222
|
break;
|
|
3241
3223
|
}
|
|
3242
3224
|
messages.push({ role: "assistant", content: assistantContent });
|
|
3243
3225
|
const toolCalls = parser.parse(assistantContent);
|
|
3244
3226
|
if (toolCalls.length === 0) {
|
|
3227
|
+
console.error(`[warp_grep:stream] No tool calls parsed on turn ${turn}. Assistant content (first 500 chars):`, assistantContent.slice(0, 500));
|
|
3245
3228
|
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" });
|
|
3246
3229
|
terminationReason = "terminated";
|
|
3247
3230
|
timings.turns.push(turnMetrics);
|
|
@@ -3588,7 +3571,9 @@ async function executeToolCall(input, config) {
|
|
|
3588
3571
|
});
|
|
3589
3572
|
const finish = result.finish;
|
|
3590
3573
|
if (result.terminationReason !== "completed" || !finish?.metadata) {
|
|
3591
|
-
|
|
3574
|
+
const errorDetails = result.errors?.map((e) => e.message).join("; ") || "unknown reason";
|
|
3575
|
+
console.error(`[warp_grep] executeToolCall failed. Reason: ${result.terminationReason}. Errors: ${errorDetails}. Turns: ${result.timings?.turns?.length ?? 0}`);
|
|
3576
|
+
return { success: false, error: `Search did not complete: ${errorDetails}` };
|
|
3592
3577
|
}
|
|
3593
3578
|
const contexts = (finish.resolved ?? []).map((r) => ({
|
|
3594
3579
|
file: r.path,
|
|
@@ -3600,7 +3585,9 @@ async function executeToolCall(input, config) {
|
|
|
3600
3585
|
function processAgentResult(result) {
|
|
3601
3586
|
const finish = result.finish;
|
|
3602
3587
|
if (result.terminationReason !== "completed" || !finish?.metadata) {
|
|
3603
|
-
|
|
3588
|
+
const errorDetails = result.errors?.map((e) => e.message).join("; ") || "unknown reason";
|
|
3589
|
+
console.error(`[warp_grep] processAgentResult failed. Reason: ${result.terminationReason}. Errors: ${errorDetails}. Turns: ${result.timings?.turns?.length ?? 0}`);
|
|
3590
|
+
return { success: false, error: `Search did not complete: ${errorDetails}` };
|
|
3604
3591
|
}
|
|
3605
3592
|
const contexts = (finish.resolved ?? []).map((r) => ({
|
|
3606
3593
|
file: r.path,
|
|
@@ -4555,7 +4542,6 @@ var import_isomorphic_git2 = __toESM(require("isomorphic-git"), 1);
|
|
|
4555
4542
|
var import_node2 = __toESM(require("isomorphic-git/http/node"), 1);
|
|
4556
4543
|
|
|
4557
4544
|
// modelrouter/core.ts
|
|
4558
|
-
init_resilience();
|
|
4559
4545
|
var DEFAULT_CONFIG3 = {
|
|
4560
4546
|
apiUrl: "https://api.morphllm.com",
|
|
4561
4547
|
timeout: 5e3,
|
|
@@ -5234,14 +5220,26 @@ function createWarpGrepTool3(config) {
|
|
|
5234
5220
|
description: config.description ?? WARP_GREP_DESCRIPTION,
|
|
5235
5221
|
inputSchema: schema,
|
|
5236
5222
|
execute: async (params) => {
|
|
5237
|
-
const
|
|
5223
|
+
const steps = [];
|
|
5224
|
+
const generator = executeToolCallStreaming(params, config);
|
|
5225
|
+
let result;
|
|
5226
|
+
for (; ; ) {
|
|
5227
|
+
const { value, done } = await generator.next();
|
|
5228
|
+
if (done) {
|
|
5229
|
+
result = value;
|
|
5230
|
+
break;
|
|
5231
|
+
}
|
|
5232
|
+
steps.push(value);
|
|
5233
|
+
}
|
|
5238
5234
|
if (!result.success) {
|
|
5239
5235
|
throw new Error(`Failed to search codebase: ${result.error}`);
|
|
5240
5236
|
}
|
|
5237
|
+
const allToolCalls = steps.flatMap((s) => s.toolCalls);
|
|
5241
5238
|
return {
|
|
5242
5239
|
success: true,
|
|
5243
5240
|
contexts: result.contexts,
|
|
5244
|
-
summary: result.summary
|
|
5241
|
+
summary: result.summary,
|
|
5242
|
+
progress: allToolCalls.length > 0 ? { turn: steps.length, toolCalls: allToolCalls } : void 0
|
|
5245
5243
|
};
|
|
5246
5244
|
}
|
|
5247
5245
|
});
|