MCPcopy
hub / github.com/Doorman11991/smallcode / executeBatch

Function executeBatch

src/session/parallel_executor.js:73–141  ·  view source on GitHub ↗

* Execute a single batch of steps concurrently. * * Each step is a mini agent loop: * 1. Build isolated message context (system + step instruction) * 2. Call chatCompletion with that context * 3. Execute any tool calls returned * 4. Return { stepIndex, toolResults, finalContent } * *

(batch, planSteps, systemMessages, chatCompletionFn, executeToolFn, config, ctx)

Source from the content-addressed store, hash-verified

71 * @returns {Promise<Array<{stepIndex: number, content: string, toolResults: object[]}>>}
72 */
73async function executeBatch(batch, planSteps, systemMessages, chatCompletionFn, executeToolFn, config, ctx) {
74 const batchPromises = batch.map(async (stepIdx) => {
75 const stepText = planSteps[stepIdx] || `Step ${stepIdx + 1}`;
76 const messages = buildStepMessages(systemMessages, stepText);
77
78 const toolResults = [];
79 let finalContent = '';
80 let iterations = 0;
81 const MAX_ITERATIONS = 20; // per-step tool call limit
82
83 try {
84 let currentMessages = [...messages];
85
86 while (iterations < MAX_ITERATIONS) {
87 iterations++;
88 const response = await chatCompletionFn(config, currentMessages);
89 if (!response) break;
90
91 const choice = response?.choices?.[0]?.message;
92 if (!choice) break;
93
94 // Recover tool calls embedded in text content (qwen2.5-coder etc.).
95 // Issue #36 — the agent loop in bin/smallcode.js does the same.
96 try {
97 const { extractFromMessage } = require('../tools/tool_call_extractor');
98 const tools = (typeof ctx?.getAllTools === 'function' ? ctx.getAllTools(config) : null) || [];
99 extractFromMessage(choice, tools);
100 } catch {}
101
102 finalContent = choice.content || '';
103
104 const toolCalls = choice.tool_calls || [];
105 if (toolCalls.length === 0) break; // no more tool calls → step done
106
107 // Execute tool calls sequentially within this step
108 for (const tc of toolCalls) {
109 const name = tc?.function?.name;
110 const argsStr = tc?.function?.arguments || '{}';
111 let args = {};
112 try { args = JSON.parse(argsStr); } catch {}
113
114 const result = await executeToolFn(name, args, ctx);
115 const resultText = result?.result || result?.error || JSON.stringify(result);
116
117 toolResults.push({ toolName: name, args, result: resultText });
118
119 // Add tool call + result to this step's message history
120 currentMessages.push({
121 role: 'assistant',
122 content: choice.content || '',
123 tool_calls: toolCalls,
124 });
125 currentMessages.push({
126 role: 'tool',
127 tool_call_id: tc.id || String(Date.now()),
128 content: resultText,
129 });
130 }

Callers 1

runParallelPlanFunction · 0.85

Calls 3

buildStepMessagesFunction · 0.85
extractFromMessageFunction · 0.85
allMethod · 0.80

Tested by

no test coverage detected