The agent loop
Everything else today runs on one loop, so you build it first and test it against a model you control. An agent is that loop. It asks the model, runs the tools the model calls and hands back the results. Then it asks again, until the model answers in text or calls the tool that ends the task. Day 7's tool loop runs inside one chat turn, while this loop runs a whole task on its own, with explicit limits. A task with a fixed sequence of steps is a chain, like the Day 7 research chain. Keep agents for tasks where the next step depends on what the last one found.
Study first
- Read the AI SDK's reference for
generateTextand see what happens when you declaretoolswithoutexecute. The call then returns the model'stoolCallsinstead of running them, along with the response's messages to append. Because nothing has run the tools, your loop runs them and builds thetoolmessage with the results itself. - Read the ReAct paper, whose name is short for reason and act. In this pattern the model alternates reasoning and actions, so it writes a thought, makes a tool call, reads the observation and repeats.
Build
- Write
runAgent({ model, system, task, tools, done, limits, on })insrc/lib/agent.ts, wheredonenames the tool that ends the task andonholds the event callbacks. The loop makes up tolimits.stepsmodel calls, 15 by default. In each step it appends the response messages and runs every tool call through the tools you passed in. Then it appends onetoolmessage with the results, with failures marked as errors. It returns when the model answers in text or when thedonetool runs, and it reports why the run ended instopped, asanswered,steps,dollarsortime. - Emit 2 events, so that whoever calls the loop can show the run as it happens.
thought(text)carries the model's words between tool calls, andtool(call)carries each call with its input, its result and whether it failed. - Write tests with a scripted model, which is a mock model that answers from a script, built with the AI SDK's testing helpers. Cover a round trip through a tool and then the
donetool. Cover a failing tool too, which comes back to the model as an error while the loop goes on.
Done when
- The tests show that the
toolmessage the model receives holds the result of the tool call before it. - A failing tool reaches the model as an error, and the loop keeps going.
Technical notes
- A tool that throws becomes a tool result with an
error-textoutput, which the model can read and recover from. - An invalid call is an error result too, never an exception. A call is invalid when it names a tool the loop was not given, or when the schema rejects its input.
- A model that answers in text without calling the
donetool also ends the run, and the investigation agent maps both endings to the same result shape.
