Neural Mastery
← Practice
Parallel Tool Calls With IDsmedium

Parallel Tool Calls With IDs

medium Build an Agent 15–20 min

Standard library only · runs in your browser

Modern models ask for several tools in one turn (check Paris and Tokyo at once), and every result must carry the exact ID of the call it answers. Get the IDs wrong and the API rejects the request.

Task

Implement execute_tool_calls(calls, max_parallel=4). Each call is {"id": str (optional), "tool": str, "arguments": dict (optional)}.

Return one {"role": "tool", "tool_call_id": id, "content": str} per call, in the same order as the calls:

  • A missing or empty id becomes f"call_{i}", with i counting from 1 by position.
  • An id already used earlier in this batch (including generated ones) gets the content error: duplicate tool_call_id 'ID', and that call isn't run.
  • Calls past position max_parallel get error: too many parallel tool calls (limit N) and aren't run.
  • Otherwise the content is dispatch({"tool": ..., "arguments": ...}). A missing arguments key means {}.

One failing call never stops the others.

Function Signature

execute_tool_calls(calls: list[dict], max_parallel: int = 4) -> list[dict]

Examples

Example 1: Two calls in one turn
Input: calls = [{'id': 'toolu_01', 'tool': 'get_weather', 'arguments': {'city': 'Paris'}}, {'id': 'toolu_02', 'tool': 'get_weather', 'arguments': {'city': 'Tokyo'}}]
Output: [{'role': 'tool', 'tool_call_id': 'toolu_01', 'content': '18C, light rain'}, {'role': 'tool', 'tool_call_id': 'toolu_02', 'content': '24C, clear'}]
Example 2: Missing ids are generated by position
Input: calls = [{'tool': 'add', 'arguments': {'a': 1, 'b': 2}}, {'tool': 'lookup_doc', 'arguments': {'doc_id': 'shipping'}}]
Output: [{'role': 'tool', 'tool_call_id': 'call_1', 'content': '3'}, {'role': 'tool', 'tool_call_id': 'call_2', 'content': 'Standard shipping takes 3-5 business days.'}]
Example 3: One failure doesn't stop the batch
Input: calls = [{'id': 'a', 'tool': 'divide', 'arguments': {'a': 1, 'b': 0}}, {'id': 'b', 'tool': 'add', 'arguments': {'a': 2, 'b': 2}}]
Output: [{'role': 'tool', 'tool_call_id': 'a', 'content': 'error: divide raised ZeroDivisionError: division by zero'}, {'role': 'tool', 'tool_call_id': 'b', 'content': '4'}]
Example 4: Duplicate ids are rejected
Input: calls = [{'id': 'x', 'tool': 'add', 'arguments': {'a': 1, 'b': 1}}, {'id': 'x', 'tool': 'add', 'arguments': {'a': 2, 'b': 2}}]
Output: [{'role': 'tool', 'tool_call_id': 'x', 'content': '2'}, {'role': 'tool', 'tool_call_id': 'x', 'content': 'error: duplicate tool_call_id \'x\''}]

Constraints

  • Results stay in call order, so the model can match them to its requests.
  • Check for a duplicate id before checking the parallel limit.
  • `dispatch` from stage 3 is provided.
Python3Saved ✓
import json
import math
import re


def execute_tool_calls(calls, max_parallel=4):
"""Run a batch of tool calls; return one tool message per call, in order."""
# Your code here
pass


# =============================================================================
# PROVIDED BELOW -- the sandbox and your earlier stages. Read it, don't edit it.
# =============================================================================
# ---------------------------------------------------------------------------
# The sandbox world your agent lives in (provided -- you don't edit this).
# Four deterministic tools, each with a JSON-Schema-style argument spec,
# exactly the shape you'd hand a real model's tool-calling API.
# ---------------------------------------------------------------------------
WEATHER = {"paris": "18C, light rain", "tokyo": "24C, clear", "lima": "16C, overcast"}
DOCS = {
"refund-policy": "Refunds are accepted within 30 days with a receipt.",
"shipping": "Standard shipping takes 3-5 business days.",
}


def add(a, b):
return a + b


def divide(a, b):
return a / b


def get_weather(city):
key = city.strip().lower()
Case 1: Two calls in one turn
Input: calls = [{'id': 'toolu_01', 'tool': 'get_weather', 'arguments': {'city': 'Paris'}}, {'id': 'toolu_02', 'tool': 'get_weather', 'arguments': {'city': 'Tokyo'}}]
Expected: [{'role': 'tool', 'tool_call_id': 'toolu_01', 'content': '18C, light rain'}, {'role': 'tool', 'tool_call_id': 'toolu_02', 'content': '24C, clear'}]
Case 2: Missing ids are generated by position
Input: calls = [{'tool': 'add', 'arguments': {'a': 1, 'b': 2}}, {'tool': 'lookup_doc', 'arguments': {'doc_id': 'shipping'}}]
Expected: [{'role': 'tool', 'tool_call_id': 'call_1', 'content': '3'}, {'role': 'tool', 'tool_call_id': 'call_2', 'content': 'Standard shipping takes 3-5 business days.'}]
Case 3: One failure doesn't stop the batch
Input: calls = [{'id': 'a', 'tool': 'divide', 'arguments': {'a': 1, 'b': 0}}, {'id': 'b', 'tool': 'add', 'arguments': {'a': 2, 'b': 2}}]
Expected: [{'role': 'tool', 'tool_call_id': 'a', 'content': 'error: divide raised ZeroDivisionError: division by zero'}, {'role': 'tool', 'tool_call_id': 'b', 'content': '4'}]
Case 4: Duplicate ids are rejected
Input: calls = [{'id': 'x', 'tool': 'add', 'arguments': {'a': 1, 'b': 1}}, {'id': 'x', 'tool': 'add', 'arguments': {'a': 2, 'b': 2}}]
Expected: [{'role': 'tool', 'tool_call_id': 'x', 'content': '2'}, {'role': 'tool', 'tool_call_id': 'x', 'content': 'error: duplicate tool_call_id \'x\''}]