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

Function runAgentLoop

test/e2e-agentic.mjs:397–497  ·  view source on GitHub ↗
(userMessage, { label = '', verbose = false, extraTools, toolChoice } = {})

Source from the content-addressed store, hash-verified

395
396// ─── Agentic 循环驱动器 ─────────────────────────────────────────────────
397async function runAgentLoop(userMessage, { label = '', verbose = false, extraTools, toolChoice } = {}) {
398 const messages = [{ role: 'user', content: userMessage }];
399 // 更强的 system prompt:明确要求 tool-first,禁止不调工具就回答
400 const systemPrompt = [
401 'You are an AI coding assistant with full file system access.',
402 'CRITICAL RULES:',
403 '1. You MUST use tools to read files before discussing their content. Never guess file contents.',
404 '2. You MUST use Write or Edit tools to actually modify files. Never just show code in text.',
405 '3. You MUST use Bash to run commands. Never pretend to run them.',
406 '4. Always use LS or Glob first to discover files if you are not sure about paths.',
407 '5. Use attempt_completion when the task is fully done.',
408 '6. Working directory is /project. All files are accessible via the Read tool.',
409 ].join('\n');
410
411 let turnCount = 0;
412 const toolCallLog = [];
413 let finalResult = null;
414
415 while (turnCount < MAX_TURNS) {
416 turnCount++;
417
418 // 发送请求
419 const resp = await fetch(`${BASE_URL}/v1/messages`, {
420 method: 'POST',
421 headers: { 'Content-Type': 'application/json', 'x-api-key': 'dummy' },
422 body: JSON.stringify({
423 model: MODEL,
424 max_tokens: 8096,
425 system: systemPrompt,
426 tools: extraTools ? CLAUDE_CODE_TOOLS.filter(t => extraTools.includes(t.name)) : CLAUDE_CODE_TOOLS,
427 ...(toolChoice ? { tool_choice: toolChoice } : {}),
428 messages,
429 }),
430 });
431
432 if (!resp.ok) {
433 const text = await resp.text();
434 throw new Error(`HTTP ${resp.status}: ${text.substring(0, 200)}`);
435 }
436
437 const data = await resp.json();
438
439 if (verbose) {
440 const textBlock = data.content?.find(b => b.type === 'text');
441 if (textBlock?.text) {
442 console.log(info(` [Turn ${turnCount}] 模型文本: "${textBlock.text.substring(0, 100)}..."`));
443 }
444 }
445
446 // 收集本轮工具调用
447 const toolUseBlocks = data.content?.filter(b => b.type === 'tool_use') || [];
448
449 if (data.stop_reason === 'end_turn' || toolUseBlocks.length === 0) {
450 // 任务自然结束
451 const textBlock = data.content?.find(b => b.type === 'text');
452 finalResult = textBlock?.text || '(no text response)';
453 break;
454 }

Callers 1

e2e-agentic.mjsFile · 0.85

Calls 7

toolFunction · 0.85
executeToolFunction · 0.85
logMethod · 0.80
pushMethod · 0.80
infoFunction · 0.70
jsonMethod · 0.45
writeMethod · 0.45

Tested by

no test coverage detected