DLRSDLRS
Agents

Agents — 9 Specialized Workers

DLRS is not one chatbot. It's 9 narrow agents coordinated by an Orchestrator. Learn each agent's job, tools, permissions, and how to extend them — beginner-friendly with code.

Why Multi-Agent? (Beginner)

Analogy: Specialist Doctors

One general doctor (single LLM) tries to do everything and is mediocre. DLRS has 9 specialists: Inbox doctor for capture, Finance doctor for bank statements. The Orchestrator is the receptionist who routes you to the right specialist.
  • Single agent problem: one prompt with 50 tools → confusion, wrong tool, high token cost, permission bleed.
  • Multi-agent solution: Inbox Agent has 5 tools, Finance Agent has 4, each prompt narrow and accurate.
  • Beginner win: You can test Inbox Agent alone without loading Finance code.

The 9 Agents — What Each Does

AgentInput ExampleOutputTools
Inbox Agent“3 reels for GB by Friday, photos in Drive”client=GB, 3 tasks, deadline, asset searchclassify, extract_entities, link_project
Task AgentAll tasks for workspacePriority scores, at-risk, nextActionprioritize, detect_blocked, estimate
Project AgentProject health requestProgress 60%, 2 tasks overdue, summaryhealth, milestones, summarize

Tool Registry & Permissions

lib/agents/tools.ts
tools = [
  { name: "create_task", risk: "SAFE", input: z.object({ title, project_id, due_date }), handler },
  { name: "send_email", risk: "SENSITIVE", handler }, // needs confirm
  { name: "search_drive", risk: "SAFE" },
  ...
]

Catalog shown to LLM:
listTools() → [{ name, description, risk, inputSchema }]

Permission matrix:
SAFE: auto-exec (create_task, categorize_email, attach_file)
SENSITIVE: pause → modal "Send this email?" → user confirms → execute
Engine: lib/agents/orchestrator.ts → handleToolCall() checks risk

Keyword: Risk vs Permission

risk="SAFE"|"SENSITIVE" in tool definition. Sensitive tool calls are not executed until user clicks Confirm. Logged to activity_log with approved_by.

How to Add a New Tool (Steps)

1. Define in lib/agents/tools.ts

{
  name: "create_reminder",
  description: "Create reminder for task",
  risk: "SAFE",
  input: z.object({ task_id: z.string(), when: z.string() }),
  handler: async (args, { db, ctx }) => {
    // ctx.workspaceId enforced here
    const reminder = await db.reminder.create({ data: { workspace_id: ctx.workspaceId, task_id: args.task_id, when: new Date(args.when) }})
    return reminder
  }
}

2. Add to agent's allowed list

lib/agents/registry.ts
taskAgents = ["create_task", "update_task", "create_reminder"]

3. Add server wrapper (optional for UI)

lib/ai/agent/server-tools.ts
export const createReminder = createReminderDef.server<AgentRuntimeContext>(...)

4. Test via Assistant

Ask in /w/[workspace]/assistant: “Remind me about GB reel tomorrow 10am” → orchestrator → Inbox Agent → create_reminder tool.

Cost & Reliability Design

Why Not AI Everywhere?

AI is expensive and non-deterministic. DLRS uses heuristic first, LLM second. Dates, math, cron = TypeScript date-fns. Only understanding uses LLM. Saves tokens and avoids “2+2=5” errors.
  • Model: AGENT_MODEL=claude-3-5-sonnet for quality, haiku for cheap
  • Fallback: if no API key, heuristic regex still creates tasks (lower accuracy)
  • Limit: max 5 tool calls per turn, loop detection in orchestrator

Database & Audit

On this page