The ReAct loop, and createAgent
The ReAct loop, from first principles: call the model; if it requested tools, execute them and append the results as tool messages; call the model again; repeat until it stops requesting tools and returns a final answer. Reason, act, observe, repeat. That loop is all "agent" means.
responseFormat: toolStrategy([ZodSchema]) is how you get typed structured output out of the agent loop, surfaced as result.structuredResponse. That is the modern replacement for the bare withStructuredOutput call from module 1, when you are inside an agent rather than calling a model directly.
Middleware wraps the loop with cross-cutting behavior, composed in a middleware: [...] array: summarizationMiddleware compresses long histories automatically, humanInTheLoopMiddleware pauses on chosen tools for human sign-off (module 5's territory), piiRedactionMiddleware strips PII. For this module you want the loop plus structured output; the destructive-action gate comes in module 5.
Try it yourself
Why the rename matters
createReactAgent being superseded by createAgent is more than a name change. What actually changed?
toolStrategy vs withStructuredOutput
Inside the loop, tool-calling is already doing one job. The structured response would be a second use of the same mechanism.
Why does createAgent need responseFormat: toolStrategy([...]) rather than just wrapping the model in withStructuredOutput?
Build the todoist triage agent
Build a real triage agent that reads the inbox and emits a plan, file actions only, guarded against destructive ops.
Tick every step to confirm you did it.
Plan validates against the apply contract
Confirm the emitted plan matches the existing consumer contract.
Plan JSON validates against {actions:[{id,do,project,labels,priority,due}]}, and a guard test proves the agent never emits close or graduate actions.