Skip to content

lucmir/advisors

Repository files navigation

Council of Advisors

A web app that lets you describe a decision and get parallel perspectives from multiple AI "advisor" personas — philosophers, entrepreneurs, scientists, and more — followed by a synthesis of their collective wisdom.

Features

  • 19 built-in advisor personas across 5 groups (Council, Philosophers, Entrepreneurs, Scientists, Pop Culture)
  • Parallel streaming responses — advisors think simultaneously, tokens stream in real-time
  • Synthesis — after all advisors respond, a synthesizer extracts agreements, disagreements, blind spots, and a verdict
  • Follow-up questions — continue the conversation with context from previous rounds
  • Persona management — create custom personas, fork built-ins, upload avatar photos, enable tools (web search)
  • Debate mode — pick 2 advisors, they argue for 3 rounds responding to each other, then synthesis
  • Meeting history — revisit past meetings with full responses and synthesis
  • Multi-tenant auth — powered by Civic Auth, each user gets their own persona library and meeting history

Architecture

Council Meeting Flow

flowchart TD
    A[User enters question + selects advisors] -->|POST /api/meetings| B[Create Meeting in DB]
    B --> C1[Advisor 1<br/>Claude API] & C2[Advisor 2<br/>Claude API] & C3[Advisor N<br/>Claude API]

    C1 & C2 & C3 -->|NDJSON stream<br/>token-by-token| D[Client renders in tabbed UI]

    C1 & C2 & C3 -->|All complete| E[Synthesizer<br/>Claude API]
    E -->|Stream| D

    D --> F{Follow-up?}
    F -->|Yes| G[Same advisors re-run<br/>with conversation history] --> C1 & C2 & C3
    F -->|No| H[New Meeting]

    style C1 fill:#f5f5f4,stroke:#78716c
    style C2 fill:#f5f5f4,stroke:#78716c
    style C3 fill:#f5f5f4,stroke:#78716c
    style E fill:#292524,color:#fff,stroke:#292524
Loading

Debate Mode Flow

flowchart TD
    A[User picks 2 advisors + topic] -->|POST /api/debates| R1

    subgraph R1[Round 1]
        direction LR
        A1[Advisor A speaks] --> B1[Advisor B responds]
    end

    R1 --> R2

    subgraph R2[Round 2 — order alternates]
        direction LR
        B2[Advisor B speaks] --> A2[Advisor A responds]
    end

    R2 --> R3

    subgraph R3[Round 3]
        direction LR
        A3[Advisor A speaks] --> B3[Advisor B responds]
    end

    R3 --> S[Synthesizer analyzes full debate]

    style R1 fill:#fafaf9,stroke:#d6d3d1
    style R2 fill:#fafaf9,stroke:#d6d3d1
    style R3 fill:#fafaf9,stroke:#d6d3d1
    style S fill:#292524,color:#fff,stroke:#292524
Loading

Data Model

erDiagram
    User ||--o{ UserPersona : has
    User ||--o{ Meeting : creates
    Persona ||--o{ UserPersona : linked
    User ||--o{ Persona : "creates (custom)"
    Meeting ||--o{ Response : contains
    Meeting ||--o{ Synthesis : contains
    Persona ||--o{ Response : "responds as"

    User {
        string id PK
        string sub UK
        string email
        string name
    }
    Persona {
        string id PK
        string name
        string instructions
        string groupName
        boolean isBuiltin
        string createdByUserId FK
    }
    Meeting {
        string id PK
        string question
        string userId FK
        string mode
    }
    Response {
        string id PK
        string meetingId FK
        string personaId FK
        string content
        int round
    }
    Synthesis {
        string id PK
        string meetingId FK
        string content
        string question
        int round
    }
Loading

Tech Stack

  • Next.js 16 (App Router)
  • Anthropic Claude API (claude-sonnet-4-6 default, configurable)
  • Prisma 7 with SQLite
  • Tailwind CSS v4 with typography plugin
  • Civic Auth for authentication

Getting Started

Prerequisites

Setup

# Install dependencies
npm install

# Generate Prisma client
npx prisma generate

# Run migrations
npx prisma migrate dev

# Seed built-in personas
npx prisma db seed

# Create .env.local with your keys
cp .env.example .env.local
# Edit .env.local with your actual keys

Environment Variables

Create a .env.local file:

ANTHROPIC_API_KEY=your-anthropic-api-key
CIVIC_CLIENT_ID=your-civic-client-id
ANTHROPIC_MODEL=claude-sonnet-4-6  # optional, defaults to claude-sonnet-4-6

Run

npm run dev

Open http://localhost:3000.

Project Structure

src/
  app/
    page.tsx                    # Meeting page
    login/page.tsx              # Login page (Civic Auth embedded)
    debate/                     # Debate mode (2 advisors, 3 rounds)
    history/                    # Meeting history
    personas/                   # Persona management (CRUD)
    api/
      auth/[...civicauth]/      # Civic Auth handler
      meetings/route.ts         # Meeting orchestration (NDJSON streaming)
      debates/route.ts          # Debate orchestration (sequential rounds)
    components/
      MeetingView.tsx           # Main meeting UI with follow-ups
      AdvisorTabs.tsx           # Tabbed synthesis + advisor responses
      AdvisorChip.tsx           # Advisor selection toggle
  lib/
    anthropic.ts                # Claude API streaming helpers
    auth.ts                     # User provisioning (auto-links built-in personas)
    config.ts                   # Model name + synthesizer prompt
    prisma.ts                   # Prisma client singleton
prisma/
  schema.prisma                 # Data model
  seed.ts                       # 19 built-in personas
public/
  avatars/                      # Portrait images for built-in personas

License

MIT

About

Get parallel perspectives from AI advisor personas

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages