Build Stateful Agents with AI SDK v6 Sandboxes
AI Engineergo watch the original →
the gist
Vercel workshop teaches building a tool-loop agent with persistent file system, bash execution, web search, and self-generating Python scripts for long-running, accumulative tasks.
Agent Runtime: Tool Loops and Instructions
Nico Albanese demonstrates constructing a reusable agent runtime using AI SDK v6's toolLoop primitive, which encapsulates LLM logic into a lightweight, shareable module separate from API handlers. Start with a base agent defined in agent.ts: import toolLoopAgent, specify a model like 'gpt-4o-mini' via global AI Gateway provider, and pass instructions to shape behavior—e.g., "respond like a cowboy" instantly alters responses without redeploying prompts inline. This separation prevents 2,000-line bloat in route handlers; instead, createAgentUIStreamResponse(agent, messages) handles streaming in /api/chat/route.ts. On the frontend, useChat from @ai-sdk/react manages message state, rendering typed parts for seamless integration. Principle: Treat agent definition as source of truth for end-to-end type safety—inferAgentUIMessage<typeof agent> propagates tool schemas to UI, enabling autocomplete for tool inputs/outputs without manual typing.
Key teaching moment: Instructions aren't obsolete; they anchor behavior alongside tools and persistence. Common mistake: Embedding prompts/tools in call sites leads to duplication; solution: Monorepo-reusable agents work across Next.js, Bun, or plain JS.
Context Augmentation: Provider-Executed Tools
Augment agents with minimal code using provider-executed tools like OpenAI's web search—no custom execute function needed. Install @ai-sdk/openai, append { webSearch: {} } to agent tools; OpenAI handles execution server-side, injecting results into message state. Customize via options like { location: 'London' } for localized queries. UI enhancement: Switch on part.type === 'tool-start' or 'tool-end' in message rendering, accessing typed input.query and output.content—e.g., display "Searching: query..." during pending states.
Principle: Three tool types—custom (user-defined execute), provider-defined (pre-trained schemas like Anthropic's bash), provider-executed (infrastructure-bound like search)—prioritize speed for demos. Avoid: Untyped unknown inputs; leverage SDK's type flow from agent to useChat<AgentUIMessage>(). Example: Querying "when is AI Engineer Summit London" fetches real-time data, showing tool calls transparently.
Persistence Revolution: Sandboxes as Agent Computers
Core insight: File systems transform agents from hallucinating short-burst responders to persistent workers. Internal Vercel agent DZero gained a sandbox with plan.md scratchpad and research dir; instructions to "create plan file with objective at top, check off steps" made it follow long tasks, reference priors, and produce artifacts. Replay: Agents read/write files across loops, avoiding context window dilution where early objectives get buried.
Implementation: Vercel's persistent named sandboxes provide per-session file systems. Initialize via Vercel CLI (vercel sandbox create), link with OIDC tokens from .env. Define BashExecute tool: Custom tool with Zod schema for command: z.string(), execute via sandbox.run(command) returning stdout/stderr. Integrate into agent tools array. Add memories.md: Agent reads on start ("Review memories.md for prior work"), appends summaries post-task ("Update memories with new insights"). Behavior shift: Agent stays on-track, builds incrementally.
Warning: Without persistence, multi-step tasks derail; sandboxes enforce stateful loops. Prerequisites: Vercel project linked, AI Gateway for models.
Accumulative Intelligence: Script Generation and Sub-Agents
Elevate to self-improving agents: Instructions mandate generating Python scripts for repeatable tasks ("If task recurs, write Python script in /scripts, store for reuse"). Agent uses bash to echo 'script.py' > /scripts/script.py, executes python /scripts/script.py. Sub-agents emerge: Delegate via tools calling child toolLoopAgents. Full flow: Web search → bash research → plan.md updates → script gen → memories append.
Quality criteria: Plans explicit (objective → steps → checkpoints); scripts idempotent; memories concise. Practice: Clone repo (github.com/nicoalbanese/ai-london-demo), vercel link, pnpm install, iterate instructions/tools. Example before/after: Stateless agent hallucinates; sandboxed version completes audits across sessions.
"The key insight from Vercel's internal agent work: giving an agent a file system didn't just add storage, it changed how the agent behaved. It started following through on long tasks, staying on track, and building on its own prior work."
Deployment and Iteration
Setup mirrors production: vercel dev for local, CLI handles auth/env. Global provider simplifies models; override per-call if needed. End-to-end: Typed UI reflects agent evolution—no manual sync.
"We saw in our own applications how much they were ballooning by having all of the LLM logic in the call site... the beauty of the AI SDK is it is lightweight JavaScript and so you can define this once in code."
Key Takeaways
- Define agents with
toolLoop({ model, tools, instructions })as reusable source of truth for types/UI. - Use provider-executed tools for quick wins like web search; custom for bash via Zod schemas.
- Persistent sandboxes (Vercel) + plan.md/memories.md enable long-task adherence without manual memory mgmt.
- Instruct agents to generate/run Python scripts for repeatability, fostering sub-agents.
- Type safety flows:
inferAgentUIMessage→ route handler →useChatfor zero-friction dev. - Avoid inline prompts/tools; separate concerns for monorepo reuse.
- Test behavior shifts: File access makes agents "follow through" per internal DZero evidence.
- Start cheap: gpt-4o-mini + AI Gateway; scale to production checklists.