Manual
Open a tool span with trace.tool(name, ...). Entering the block records a tool.call; record_output sets the result; leaving the block records the terminal tool.result (marked as an error if an exception propagates).
with trace.tool("issue_refund", arguments={"order": "4421", "amount": 49.0}) as call: result = issue_refund(order="4421", amount=49.0) call.record_output(result)Linking to the LLM call
When a tool call comes from a model's tool-calling output, pass the LLM's tool_call_id so the call and result link back to the assistant message that requested them.
import jsonfor tool_call in response.choices[0].message.tool_calls: args = json.loads(tool_call.function.arguments) with trace.tool(tool_call.function.name, tool_call_id=tool_call.id, arguments=args) as call: result = run_tool(tool_call.function.name, args) call.record_output(result)The @tool decorator
Decorate a function with @rollout.tool and every call records a tool.call / tool.result pair, capturing the bound arguments and the return value. It works on sync and async functions and requires an active trace (for example, inside a decorated agent).
import mv37.rollout as rollout@rollout.tool("get_weather")def get_weather(city: str) -> dict: return {"city": city, "temp": 21}The name is optional and defaults to the function name. Pass record_input=False or record_output=False to skip capturing arguments or the return value.
Wrapping a registry
If you keep your tools in a registry, wrap_tools instruments them all at once so each call is recorded without a manual with block. It accepts a {name: callable} mapping or an iterable of callables, and supports sync and async functions. Return values and exceptions are preserved exactly.
import mv37.rollout as rollouttools = rollout.wrap_tools({ "search": search, "refund_order": refund_order,})result = tools["search"]("latest invoice") # recorded automaticallyNote
Wrapped tools need an active trace. When you call them outside one — for example from a script — pass implicit_trace=True to wrap_tools(...) and each call opens a one-off trace named after the tool.