Agents

An agent is a model, a set of instructions and the tools it may call, written as one file: deep-agents/<name>/index.ts. You do not write a server. The box (the container running your workspace, on your laptop under stackbone dev or deployed in your cloud) builds it once at boot and serves it over the standard OpenAI, Anthropic and AG-UI chat APIs, so any client that speaks one of them can talk to it. Studio lists every agent the box serves, chats with it, decides the tool calls you asked it to hold, and keeps every turn as a run you can open.

The Catalog: every agent and workflow the box serves, read live, with what ran last.

Use an agent for open-ended work: answering a question, or walking someone through a task. You do not script what it does next; the model decides from your instructions and the tools you gave it. For a fixed pipeline that must run the same way every time, use a workflow instead.

What you can do with one

Stage What you do
Build One file: a model id, a system prompt, and plain LangChain tools that reach your data through the ambient stackbone client. stackbone add agent <name> scaffolds it and stackbone dev hot-swaps it on every save. See Write one.
Test Playground in Studio chats with the agent over the same wire your product will use, and unfolds every tool call. Or curl the box with the OpenAI or Anthropic shape. See Chat with it.
Debug Every chat turn is a run: open it under Runs to read the tool calls with input, output and timing. Sessions groups the turns of one conversation. See Follow every turn.
Improve Save a turn as a test case and score the agent from Evals or from CI. Change the instructions under Prompts without a rebuild. See Evaluation and stackbone.prompts.
Operate Hold a tool for a person with interruptOn, attach Guardrails to the agent or the workspace, and point the box at your Model provider. See Hold a tool for a person and Guardrails.

Open an entry in the Catalog and Studio prints what the box knows about it: the model, the tools by name, the instructions, the recent runs and conversations, and the guardrails wired to it. Copy curl gives you the call your own client will make.

One agent's entry: model, tools, instructions and what ran last.

Write one

The whole agent is one defineDeepAgent call. The folder name is its identity: it is the name in the Catalog and the model value a chat client sends.

deep-agents/support/index.ts
import { tool } from '@langchain/core/tools';
import { z } from 'zod';
import { defineDeepAgent } from '@stackbone/sdk/deep';
import { stackbone } from '@stackbone/sdk';
import { eq } from '@stackbone/sdk/db';
import { orders } from './schema';

const lookupOrder = tool(
  async ({ orderId }: { orderId: string }) => {
    const [order] = await stackbone.database.select().from(orders).where(eq(orders.id, orderId));
    return order ? JSON.stringify(order) : 'not_found';
  },
  {
    name: 'lookup_order',
    description: 'Look up an order by its id.',
    schema: z.object({ orderId: z.string() }),
  },
);

export default defineDeepAgent({
  name: 'support',
  model: 'openai/gpt-4o-mini',
  tools: [lookupOrder],
});

The instruction is not in the file. It is a prompt in the catalogue, owned by this agent and keyed by its name, that you write and publish in Studio:

You are the support agent for Acme.
Use lookup_order when the customer gives an order id.

The model id resolves through the provider configured on the box, so you never wire a key. A tool is a name, a description and a Zod schema; inside its handler you reach the platform through the ambient stackbone client (.database, .storage, .rag, .config, .connection). The same object takes subagents, interruptOn and editableState when you need them.

Chat with it

Every agent answers on three wires, and the request's model field picks the agent: POST /openai/v1/chat/completions, POST /anthropic/v1/messages and POST /agui/v1/agents/:name. Any client built for OpenAI or Anthropic works with a base URL and a key; an AG-UI frontend gets streaming events, tool approvals and shared state on top.

curl http://127.0.0.1:4242/openai/v1/chat/completions \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer local-dev' \
  -d '{"model":"support","messages":[{"role":"user","content":"Where is order A-1001?"}]}'

The Playground in Studio is one such client. Pick the agent, type, and the reply streams back. Every tool call is a foldable block with the arguments the model chose and what the tool returned.

A turn in the Playground: the tool the model called, what it was called with, and what came back.

Sessions, streaming and auth are on the API page; the full contract is the agent runtime protocol.

Hold a tool for a person

Some tools act on the outside world: a refund, or a message sent in someone's name. List them under interruptOn and the runtime stops before running one. The turn parks with the tool name and the arguments the model chose; a person approves, rejects or edits them, and the run resumes.

A held tool in the Playground: approve it, reject it, or edit the arguments before it runs.

The same pause is an entry in the HITL Inbox, next to the approvals your workflows ask for and the messages a guardrail held. See Human-in-the-loop for the model and tool approvals for what a client of your own sees. Guardrails are the other gate, and they need no code.

Follow every turn

Every chat turn is a run under Runs, with its duration, its token count and its status. Open one and the trace lists the tool calls in order; click one and the inspector prints its input and output.

One turn: the tool the model called and what it returned.

From the same screen, Save as test case turns the turn into an eval case, Copy run details copies the trace as JSON, and View run logs shows what your tools printed. Sessions groups turns into conversations. From a terminal, stackbone runs list and stackbone logs tail --run <id> read the same data.

Team it with a workflow

When a process has a fixed outline and a judgment-heavy middle, a workflow owns the steps and hands one turn to the agent from inside a 'use step' with callDeepAgent('support', message). The reply becomes a durable checkpoint of the run. See Workflow agents and the examples a workflow that delegates a turn to an agent and an agent that starts a workflow.

Note

Check the agents sdk and agents cli documentation for more details.

Read more

BUILT WITH ❤️ FROM CANADA AND SPAIN