Agent Runtime

The runtime lives at web/lib/agent-runtime/ and handles everything from model selection to tool execution.


File Structure

web/lib/agent-runtime/
  index.ts              — Public barrel exports
  providers.ts          — Model-agnostic provider resolution
  prompt-builder.ts     — System prompt construction
  chat-loop.ts          — Streaming + non-streaming chat loops
  tools/
    index.ts            — Tool registry (buildToolset)
    types.ts            — Shared ToolContext interface
    web-search.ts       — Brave Search API
    web-scrape.ts       — Firecrawl URL extraction
    send-email.ts       — Resend email sending
    read-inbox.ts       — Agent inbox reading
    read-emails.ts      — Gmail API via OAuth
    calendar.ts         — Google Calendar read + create
    notion.ts           — Notion read + write
    knowledge.ts        — Pinecone RAG search + store
    manage-todos.ts     — Supabase todo CRUD

Chat Loop

The chat loop uses the Vercel AI SDK's streamText() and generateText() functions which handle the tool-use loop automatically.

Streaming (1:1 chat)

Used by /api/agents/[id]/chat for real-time agent conversations:

const result = streamText({
  model,
  system: systemPrompt,
  messages,
  tools,
  stopWhen: stepCountIs(10),  // max 10 tool-use rounds
});

return result.toTextStreamResponse();

The SDK calls the LLM, if it returns tool calls, executes them via the execute functions defined on each tool, feeds results back, and repeats up to the step limit.

Non-streaming (background tasks)

Used for group chat responses, head agent coordination, Telegram replies:

const result = await generateText({
  model,
  system: systemPrompt,
  messages,
  tools,
  stopWhen: stepCountIs(5),
});

return result.text;

Prompt Builder

buildSystemPrompt() replaces the old container-oriented buildSoulMd(). It constructs the system prompt from:

  • Agent identity — Name, type, tone, verbosity, tagline
  • Objective & instructions — Custom agent configuration
  • Trust tier rules — Observer, Helper, Partner, or Trusted
  • Available tools — Dynamically listed based on what's registered
  • User context — Name, occupation, goals, interests from personalization
  • Knowledge context — RAG results from Pinecone
  • Training data — Custom knowledge, instructions, and examples
  • Group chat context — Team roster and skip guidance (for home chat)

Usage Tracking

Every LLM call logs token usage to the usage_logs table via trackUsage():

  • Input tokens
  • Output tokens
  • Model name and provider
  • Cost in cents (calculated from pricing tables)
  • Operation type (chat, checkin, embedding, etc.)

This enables per-agent, per-user cost visibility.


Key API Routes

| Route | Method | Transport | Purpose | |-------|--------|-----------|---------| | /api/agents/[id]/chat | POST | Streaming | 1:1 agent chat | | /api/home/chat | POST | Non-streaming | Group chat responses | | /api/agents/[id]/greet | POST | Non-streaming | Thread greeting | | /api/home/head-agent | POST | Non-streaming | Head agent coordination | | /api/integrations/telegram/webhook/[agentId] | POST | Non-streaming | Telegram bot messages |