MCPcopy
hub / github.com/7836246/cursor2api / runMultiTurn

Function runMultiTurn

test/e2e-prompt-ab.mjs:179–235  ·  view source on GitHub ↗
(userMessage, { tools = TOOLS, systemPrompt = '', toolChoice, maxTurns = MAX_TURNS } = {})

Source from the content-addressed store, hash-verified

177
178// ─── 多轮 Agentic 循环(用于完整任务分析) ─────────────────────────────
179async function runMultiTurn(userMessage, { tools = TOOLS, systemPrompt = '', toolChoice, maxTurns = MAX_TURNS } = {}) {
180 const messages = [{ role: 'user', content: userMessage }];
181 const system = systemPrompt || 'You are an AI coding assistant. Working directory: /project.';
182
183 let totalToolCalls = 0;
184 let totalTextChars = 0;
185 let turns = 0;
186 let firstTurnHasToolCall = false;
187 const toolCallLog = [];
188
189 while (turns < maxTurns) {
190 turns++;
191 const resp = await fetch(`${BASE_URL}/v1/messages`, {
192 method: 'POST',
193 headers: { 'Content-Type': 'application/json', 'x-api-key': 'dummy' },
194 body: JSON.stringify({
195 model: MODEL,
196 max_tokens: 4096,
197 system,
198 tools,
199 ...(toolChoice ? { tool_choice: toolChoice } : {}),
200 messages,
201 }),
202 });
203
204 if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
205 const data = await resp.json();
206
207 const textBlocks = data.content?.filter(b => b.type === 'text') || [];
208 const toolUseBlocks = data.content?.filter(b => b.type === 'tool_use') || [];
209
210 totalTextChars += textBlocks.reduce((s, b) => s + (b.text?.length || 0), 0);
211 totalToolCalls += toolUseBlocks.length;
212
213 if (turns === 1 && toolUseBlocks.length > 0) firstTurnHasToolCall = true;
214
215 for (const tb of toolUseBlocks) {
216 toolCallLog.push({ turn: turns, tool: tb.name, input: tb.input });
217 }
218
219 if (data.stop_reason === 'end_turn' || toolUseBlocks.length === 0) break;
220
221 messages.push({ role: 'assistant', content: data.content });
222
223 const toolResults = toolUseBlocks.map(tb => ({
224 type: 'tool_result',
225 tool_use_id: tb.id,
226 content: mockExecute(tb.name, tb.input),
227 }));
228 messages.push({ role: 'user', content: toolResults });
229
230 // Check for completion signal
231 if (toolResults.some(r => r.content.startsWith('__DONE__'))) break;
232 }
233
234 return { totalToolCalls, totalTextChars, turns, firstTurnHasToolCall, toolCallLog };
235}
236

Callers 1

e2e-prompt-ab.mjsFile · 0.70

Calls 3

mockExecuteFunction · 0.85
pushMethod · 0.80
jsonMethod · 0.45

Tested by

no test coverage detected