Skip to content

feat: Agent Profiles — first-class agents with names, configs, skills, and model routing #3971

@OneStepAt4time

Description

@OneStepAt4time

Agent Profiles — Implementation Specification

Priority: P1 (prerequisite for Squads, Autopilots, Chat)
Reference: multica/server/internal/handler/agent.go, multica/server/pkg/db/queries/agent.sql


Overview

Agents are first-class objects in Multica — not anonymous CC sessions. Each agent has a name, avatar, tool selection, model, instructions, MCP config, skills, and visibility. This is the foundation for all multi-agent features.

Database Schema

CREATE TABLE agent (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    workspace_id UUID NOT NULL REFERENCES workspace(id),
    
    -- Identity
    name TEXT NOT NULL,
    description TEXT,
    avatar_url TEXT,
    
    -- Runtime configuration
    runtime_mode TEXT NOT NULL DEFAULT 'daemon'  -- 'daemon' (local) | 'cloud' (coming soon)
    runtime_config JSONB DEFAULT '{}',           -- tool-specific settings
    runtime_id UUID REFERENCES runtime(id),       -- bound runtime (optional)
    
    -- Execution settings
    model TEXT,              -- model override (null = tool default)
    thinking_level TEXT,     -- 'none' | 'low' | 'medium' | 'high'
    max_concurrent_tasks INTEGER NOT NULL DEFAULT 1,
    
    -- Prompt customization
    instructions TEXT,       -- custom system prompt additions
    custom_env JSONB DEFAULT '[]',  -- [{key, value}] environment variables
    custom_args JSONB DEFAULT '[]',  -- extra CLI arguments
    
    -- MCP configuration
    mcp_config JSONB DEFAULT '{}',   -- MCP server definitions
    
    -- Visibility
    visibility TEXT NOT NULL DEFAULT 'workspace'  -- 'workspace' | 'private'
    owner_id UUID REFERENCES member(id),  -- creator/owner
    
    -- Lifecycle
    archived_at TIMESTAMPTZ,
    archived_by UUID REFERENCES member(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_agent_workspace ON agent(workspace_id) WHERE archived_at IS NULL;

API Endpoints

GET    /api/agents                        — list agents (workspace-scoped, exclude archived)
GET    /api/agents/:id                    — get agent details
POST   /api/agents                        — create agent
PATCH  /api/agents/:id                    — update agent
DELETE /api/agents/:id                    — archive agent (soft delete)
POST   /api/agents/:id/restore            — restore archived agent

Create Agent Request

{
  name: string,           // required, e.g. "Frontend Lead"
  description?: string,
  avatar_url?: string,
  runtime_mode?: 'daemon' | 'cloud',
  runtime_config?: Record<string, any>,
  runtime_id?: string,    // bind to specific runtime
  model?: string,         // model override
  thinking_level?: 'none' | 'low' | 'medium' | 'high',
  max_concurrent_tasks?: number,
  instructions?: string,  // custom system prompt additions
  custom_env?: Array<{key: string, value: string}>,
  custom_args?: string[],
  mcp_config?: Record<string, any>,
  visibility?: 'workspace' | 'private'
}

Agent Visibility

Visibility Who can see Who can assign to issues
workspace All workspace members All workspace members
private Owners and admins only Owners and admins only

Integration with Task Queue

When an issue is assigned to an agent:

  1. System looks up agent config (model, instructions, MCP, etc.)
  2. Creates a task in agent_task_queue with agent_id
  3. Daemon claims task and applies agent's runtime config when spawning the CC session

Integration with Skills

  • Agent can have multiple skills attached (via agent_skill join table)
  • Skills are SKILL.md + supporting files (see separate Skills issue)
  • On task dispatch, daemon copies skill files into the tool's discovery path
  • Agent sees skills in system prompt context

Integration with Runtimes

  • Each runtime registers its available tools (CC, Codex, Gemini, etc.)
  • Agent binds to a specific runtime via runtime_id
  • Multiple agents can share a runtime
  • max_concurrent_tasks limits parallel execution per agent

WebSocket Events

"agent:created"    // new agent created
"agent:archived"   // agent archived
"agent:restored"   // agent restored from archive
"agent:status"     // agent status change (online/offline via runtime heartbeat)

Acceptance Criteria

  1. CRUD operations for agents work via API
  2. Agent listing excludes archived agents
  3. Archive/restore works (soft delete pattern)
  4. Private agents only visible to owners/admins
  5. Agent config (model, instructions, MCP, env) is applied when creating CC sessions
  6. Multiple agents can share a runtime
  7. max_concurrent_tasks is enforced when creating tasks
  8. npm run gate passes
  9. Tests cover: CRUD, visibility, archive/restore, task creation with agent config

E2E Test Requirements

  1. Create agent → verify appears in list
  2. Create private agent → verify non-admin can't see it
  3. Assign issue to agent → verify task created with agent config
  4. Archive agent → verify removed from list, existing tasks unaffected
  5. Update agent model → verify next task uses new model
  6. Create agent with MCP config → verify MCP config passed to CC session

Multica Source Reference

  • server/internal/handler/agent.go — full agent CRUD (1146 lines)
  • server/pkg/db/queries/agent.sql — DB queries
  • server/internal/agent/agent.go — agent interface/abstraction layer

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions