@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.
Files changed (84) hide show
  1. package/dist/{chunk-ALTKGCG5.js → chunk-CM75JPVD.js} +2 -2
  2. package/dist/{chunk-Z6TF5G4R.js → chunk-FXBT4UDY.js} +16 -32
  3. package/dist/chunk-FXBT4UDY.js.map +1 -0
  4. package/dist/{chunk-FL4ZBHK2.js → chunk-GQUNK324.js} +2 -2
  5. package/dist/{chunk-TGUQHW3I.js → chunk-HMAX2FEE.js} +2 -2
  6. package/dist/{chunk-R3BSIJCL.js → chunk-M5DR2WOZ.js} +1 -1
  7. package/dist/{chunk-23R562QJ.js → chunk-NTDAIKZI.js} +9 -4
  8. package/dist/chunk-NTDAIKZI.js.map +1 -0
  9. package/dist/{chunk-YY7NZLAI.js → chunk-RBTL6EJG.js} +11 -3
  10. package/dist/chunk-RBTL6EJG.js.map +1 -0
  11. package/dist/{chunk-HI35Y6EZ.js → chunk-SYZ75S3S.js} +18 -5
  12. package/dist/chunk-SYZ75S3S.js.map +1 -0
  13. package/dist/{chunk-2SOSDQFG.js → chunk-TZBDXZFC.js} +9 -9
  14. package/dist/{chunk-A3PK4H7A.js → chunk-UNHHRMU7.js} +2 -2
  15. package/dist/{chunk-JD4H6U3Z.js → chunk-Y5BB7JFH.js} +2 -2
  16. package/dist/{client-Bm_umdno.d.ts → client-D7iO2TbA.d.ts} +7 -0
  17. package/dist/client.cjs +123 -125
  18. package/dist/client.cjs.map +1 -1
  19. package/dist/client.d.ts +1 -1
  20. package/dist/client.js +11 -11
  21. package/dist/edge.cjs +99 -102
  22. package/dist/edge.cjs.map +1 -1
  23. package/dist/edge.js +1 -1
  24. package/dist/index.cjs +123 -125
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +11 -11
  28. package/dist/tools/fastapply/anthropic.cjs +16 -108
  29. package/dist/tools/fastapply/anthropic.cjs.map +1 -1
  30. package/dist/tools/fastapply/anthropic.js +3 -4
  31. package/dist/tools/fastapply/apply.cjs +25 -102
  32. package/dist/tools/fastapply/apply.cjs.map +1 -1
  33. package/dist/tools/fastapply/apply.d.ts +3 -2
  34. package/dist/tools/fastapply/apply.js +1 -2
  35. package/dist/tools/fastapply/core.cjs +16 -108
  36. package/dist/tools/fastapply/core.cjs.map +1 -1
  37. package/dist/tools/fastapply/core.js +2 -3
  38. package/dist/tools/fastapply/index.cjs +16 -108
  39. package/dist/tools/fastapply/index.cjs.map +1 -1
  40. package/dist/tools/fastapply/index.js +5 -6
  41. package/dist/tools/fastapply/openai.cjs +16 -108
  42. package/dist/tools/fastapply/openai.cjs.map +1 -1
  43. package/dist/tools/fastapply/openai.js +3 -4
  44. package/dist/tools/fastapply/vercel.cjs +16 -108
  45. package/dist/tools/fastapply/vercel.cjs.map +1 -1
  46. package/dist/tools/fastapply/vercel.js +3 -4
  47. package/dist/tools/index.cjs +16 -108
  48. package/dist/tools/index.cjs.map +1 -1
  49. package/dist/tools/index.js +5 -6
  50. package/dist/tools/warp_grep/agent/runner.cjs +10 -2
  51. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  52. package/dist/tools/warp_grep/agent/runner.js +1 -1
  53. package/dist/tools/warp_grep/anthropic.cjs +8 -2
  54. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  55. package/dist/tools/warp_grep/anthropic.js +3 -3
  56. package/dist/tools/warp_grep/client.cjs +18 -4
  57. package/dist/tools/warp_grep/client.cjs.map +1 -1
  58. package/dist/tools/warp_grep/client.d.ts +7 -1
  59. package/dist/tools/warp_grep/client.js +4 -2
  60. package/dist/tools/warp_grep/gemini.cjs +8 -2
  61. package/dist/tools/warp_grep/gemini.cjs.map +1 -1
  62. package/dist/tools/warp_grep/gemini.js +2 -2
  63. package/dist/tools/warp_grep/index.cjs +16 -4
  64. package/dist/tools/warp_grep/index.cjs.map +1 -1
  65. package/dist/tools/warp_grep/index.js +2 -2
  66. package/dist/tools/warp_grep/openai.cjs +8 -2
  67. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  68. package/dist/tools/warp_grep/openai.js +3 -3
  69. package/dist/tools/warp_grep/vercel.cjs +216 -4
  70. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  71. package/dist/tools/warp_grep/vercel.d.ts +7 -0
  72. package/dist/tools/warp_grep/vercel.js +3 -3
  73. package/package.json +6 -1
  74. package/dist/chunk-23R562QJ.js.map +0 -1
  75. package/dist/chunk-HI35Y6EZ.js.map +0 -1
  76. package/dist/chunk-YY7NZLAI.js.map +0 -1
  77. package/dist/chunk-Z6TF5G4R.js.map +0 -1
  78. /package/dist/{chunk-ALTKGCG5.js.map → chunk-CM75JPVD.js.map} +0 -0
  79. /package/dist/{chunk-FL4ZBHK2.js.map → chunk-GQUNK324.js.map} +0 -0
  80. /package/dist/{chunk-TGUQHW3I.js.map → chunk-HMAX2FEE.js.map} +0 -0
  81. /package/dist/{chunk-R3BSIJCL.js.map → chunk-M5DR2WOZ.js.map} +0 -0
  82. /package/dist/{chunk-2SOSDQFG.js.map → chunk-TZBDXZFC.js.map} +0 -0
  83. /package/dist/{chunk-A3PK4H7A.js.map → chunk-UNHHRMU7.js.map} +0 -0
  84. /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 fetchPromise = fetchWithRetry(
170
- `${apiUrl}/v1/chat/completions`,
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
- `Morph API request timed out after ${timeout}ms`
188
- );
189
- if (!response.ok) {
190
- const error = await response.text();
191
- if (debug) console.error(`[FastApply] API error: ${response.status} - ${error}`);
192
- throw new Error(`Morph API error (${response.status}): ${error}`);
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] \u2705 Success in ${elapsed}ms, merged: ${data.choices[0].message.content.length} chars`);
105
+ console.log(`[FastApply] Success in ${elapsed}ms, merged: ${content.length} chars`);
198
106
  }
199
- return { content: data.choices[0].message.content, completionId: data.id };
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
- init_resilience();
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 import_openai = __toESM(require("openai"), 1);
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 import_openai.default({
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 import_openai.default.APIError && error.status === 404) {
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
- errors.push({ message: e instanceof Error ? e.message : String(e) });
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
- errors.push({ message: e instanceof Error ? e.message : String(e) });
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
- return { success: false, error: "Search did not complete" };
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
- return { success: false, error: "Search did not complete" };
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 result = await executeToolCall(params, config);
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
  });