Agent Recipes

Copy-paste snippets for creating, running and equipping agents

Short, self-contained recipes for working with agents. Every agent is model agnostic: set model to any OpenRouter-compatible identifier and the rest of the code is identical. Each snippet assumes const r = new Recursiv(), which reads RECURSIV_API_KEY from the environment.

Create an agent

Spin up a named agent backed by any LLM with a system prompt that defines its behavior.

1import { Recursiv } from '@recursiv/sdk';
2
3const r = new Recursiv();
4
5const { data: agent } = await r.agents.create({
6 name: 'Research Bot',
7 username: 'researcher',
8 model: 'anthropic/claude-sonnet-4.6',
9 system_prompt: 'You are a thorough research assistant. Always cite sources.',
10});
11
12console.log(agent.id, agent.username);

Chat and get a full reply

Send one message and read the whole response back. Pass conversation_id on the next call to keep context.

1const { data: reply } = await r.agents.chat(agent.id, {
2 message: 'Summarize the latest trends in vector databases.',
3});
4
5console.log(reply.content);
6console.log(reply.conversation_id); // reuse this to continue the thread

Stream a reply token by token

Render output as it generates instead of waiting for the full response. The stream yields typed chunks.

1for await (const chunk of r.agents.chatStream(agent.id, {
2 message: 'Explain how transformers work.',
3})) {
4 if (chunk.type === 'text_delta') process.stdout.write(chunk.delta ?? '');
5}

Give an agent tools

Flip an agent into tool-using mode. autonomous runs tools without asking; permission pauses for human approval before each call.

1const { data: agent } = await r.agents.create({
2 name: 'Ops Agent',
3 username: 'ops_agent',
4 model: 'anthropic/claude-sonnet-4.6',
5 tool_mode: 'autonomous', // or 'permission' to gate each tool call
6});

Connect hundreds of integrations

Recursiv ships hundreds of data integrations through one connection layer. Enable a connected integration (Gmail, Slack, Linear and more) for an agent and scope exactly which tools it may call.

1const orgId = 'org_123';
2
3// What is connected for this org
4const { data: connections } = await r.integrations.listConnections(orgId);
5const gmail = connections.find((c) => c.provider === 'gmail');
6
7// Enable it for the agent, allowing only specific tools
8await r.integrations.updateAgentIntegration(agent.id, {
9 user_integration_id: gmail!.id,
10 enabled: true,
11 allowed_tools: ['GMAIL_FETCH_EMAILS', 'GMAIL_SEND_EMAIL'],
12});

Persist memory across runs

Store facts and decisions so an agent remembers context between sessions. Memory is searchable and scoped per project.

1const PROJECT_ID = 'proj_123';
2
3// Write what the agent learned
4await r.memory.facts.add({
5 fact: 'Customer prefers async email over Slack for approvals.',
6 project_id: PROJECT_ID,
7 agent_id: agent.id,
8 tags: ['preferences'],
9});
10
11// Load relevant context before the next run
12const { data: { context } } = await r.memory.context({
13 message: 'Draft an approval request for the customer.',
14 project_id: PROJECT_ID,
15 agent_id: agent.id,
16});
17
18await r.agents.chat(agent.id, {
19 message: `Context from memory:\n${context}\n\nDraft the approval request.`,
20});

Run the same agent on a different model

Model choice is one field. Swap providers without touching any other logic.

1await r.agents.update(agent.id, { model: 'openai/gpt-4.1' });
2// next chat call runs on the new model, same prompt and tools
3await r.agents.update(agent.id, { model: 'google/gemini-2.5-pro' });

List and inspect conversations

Pull an agent’s conversation history to audit what it has been doing.

1const { data: conversations } = await r.agents.conversations(agent.id);
2
3for (const conv of conversations) {
4 console.log(conv.id, conv.last_message?.content ?? '(empty)');
5}

Hand work from one agent to another

Agents can message each other directly to delegate tasks and return results.

1await r.agents.sendMessage('target_agent_id', {
2 from_agent_id: agent.id,
3 type: 'delegation',
4 content: 'Analyze the deployment logs for proj_123 and report failures.',
5 project_id: 'proj_123',
6});
7
8// The receiving agent reads its inbox
9const { data: messages } = await r.agents.inbox('target_agent_id', {
10 unread_only: true,
11});