Skip to content
kemalcalakPublic

About

Autonomous competitive intelligence: one URL in, an evidence-linked report and a war-gamed prediction of your rival's next move out. AMD Developer Hackathon ACT II.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

🎯 WarRoom

Autonomous competitive intelligence — from a single URL to an evidence-linked report and a war-gamed prediction of your rival's next move.

Klue tells you what your competitor did. WarRoom tells you what they'll do next.

Built for the AMD Developer Hackathon — ACT II, Unicorn track.


What it is

Give WarRoom one company URL. It autonomously:

  1. Infers the market the company plays in (country, category, and its distinct product verticals) from the company's own site.
  2. Discovers ~10 real competitors — national and global — with vertical-aware, local-language search, each graded with an evidence-linked profile card.
  3. Scrapes their public surfaces (pricing, changelog, blog, careers), chunks and embeds them, and runs analyst agents to extract evidence-linked findings — every claim carries a source URL and confidence, or is honestly marked inference.
  4. Synthesizes a report: executive summary, a transparent multi-factor threat ranking, competitor dossiers, a pricing comparison matrix, SWOT, feature gaps, and opportunities.
  5. War-games a move: pick a competitor and a scenario, and two AI agents — a Strategist (you) and a Competitor persona grounded in that rival's own scraped data — debate over three rounds, judged by an Arbiter verdict.

Everything is grounded in the competitor's real, public data — no hallucinated intelligence.

Highlights

  • 🧭 Vertical-aware discovery — a multi-product company isn't collapsed into one generic search. Market inference emits the company's distinct verticals in the home market's language, and discovery fans out one region-scoped search per vertical — so a Turkish savings + pension + insurance app finds gold-app, BES, insurtech, and digital-contract rivals, not generic budgeting tools.
  • 🔗 Evidence discipline (product-critical) — every synthesized claim is {text, source_urls[], evidence_chunk_ids[], confidence, type}. A claim can only be evidence if it cites a chunk the model was actually shown for that competitor; source URLs are re-derived from real chunk rows, never trusted from the LLM. Anything unverifiable degrades to inference — the run never fails, it just gets more honest.
  • ⚖️ Transparent threat score — a 0–100 rating that shows why: four weighted factors (category overlap · audience overlap · market proximity · momentum) rendered as a segmented bar with a per-factor rationale, in both the UI and the PDF.
  • 🎮 Grounded war-game — a 3-round Strategist↔Competitor debate + Arbiter verdict, where the rival persona can only cite chunks retrieved from its own pages.
  • ⚡ Hybrid inference — high-volume work (embeddings, extraction) routes to a local tier; heavy reasoning (reconcile, synthesis, debate) routes to a remote tier. Every call is metered into a cost panel — the AMD-usage evidence.
  • 📄 Branded PDF export, EN/TR i18n, dark/light theming, and a seeded offline demo mode that replays without network.

How it works

flowchart LR
    URL([company URL]) --> D[discover]
    D -->|market inference + vertical search| GATE{{awaiting_confirmation<br/>HITL gate}}
    GATE -->|PATCH confirm| C[collect]
    C --> A[analyze]
    A --> E[enrich]
    E --> S[synthesize]
    S --> R[[evidence-linked report]]
    R --> W[war-game debate]

    subgraph tiers[hybrid LLM routing]
      L[local tier<br/>embeddings · extraction]
      RM[remote tier<br/>reconcile · synthesis · debate]
    end
    C -. embed .-> L
    A -. extract .-> L
    A -. reconcile .-> RM
    S -. synthesis .-> RM
    W -. debate .-> RM
Loading

The pipeline is two Agno workflows split across a human-in-the-loop confirmation gate: phase 1 is discover (own-company market inference + search-grounded discovery), then the user confirms/rejects/adds competitors, then phase 2 runs collect → analyze → enrich → synthesize. Progress streams live over Server-Sent Events (Redis pub/sub); the war-game streams the same way.


Architecture

A modular monolith with a strict, unidirectional module DAG and router → service → repository layering (routers hold no business logic).

flowchart TD
    subgraph api[FastAPI · /api/v1]
      AN[analyses] --> COL[collection]
      COL --> INT[intelligence]
      INT --> WG[wargame]
      MET[metrics<br/>leaf]
    end

    subgraph core[app/core]
      LLM[llm.py<br/>tiered gateway + model_calls]
      DB[(Postgres + pgvector)]
      BUS[bus.py<br/>Redis SSE]
      TASKS[tasks.py<br/>background spawn]
      SEARCH[search.py<br/>DuckDuckGo → Tavily]
    end

    AN & COL & INT & WG --> LLM
    AN & COL & INT & WG & MET --> DB
    AN & WG --> BUS
    AN --> SEARCH
    LLM --> DB
Loading
Module Responsibility
analyses Pipeline orchestration + the HITL confirmation gate; owns the analysis lifecycle and SSE status.
collection Public-surface scraping → snapshots → chunks → embeddings (the RAG substrate). Internal service; no HTTP routes.
intelligence Analyst extraction + reconcile + the Synthesizer → the evidence-linked report.
wargame The two-agent debate: a competitor persona grounded in its own chunks vs. your Strategist, judged by an Arbiter.
metrics Aggregates model_calls into the cost-panel payload (leaf module).

Hard rules (see CLAUDE.md): all LLM access through core/llm.py; agent prompts live in backend/app/prompts/*.md (versioned, loaded at runtime); Alembic migration for every schema change; SSE over Redis (no WebSockets); no Celery/Kafka (a supervised spawn() registry is enough); no auth/multi-tenancy (single-user demo).


Hybrid inference & the AMD story

core/llm.py is a single OpenAI-compatible gateway with two chat tiers — local and remote — plus an embedding client. Model names and base URLs come entirely from config, never hardcoded. Every call logs a model_calls row (tier, model, task_type, tokens in/out, latency, cost estimate), which powers the cost panel — the evidence of how much work runs on the local/AMD tier.

The routing intent: send high-volume, cheap work to local (an AMD-hosted model) and heavy reasoning to remote. A real seeded run shows the split:

local  → chunk_embedding ×11 · pricing_extract ×5 · positioning_extract ×5
remote → pricing_reconcile ×3 · positioning_reconcile ×3 · synthesis ×1

Swapping the local tier onto AMD hardware is env-only — point LOCAL_LLM_BASE_URL / LOCAL_LLM_MODEL at a vLLM / Fireworks / AMD Instinct endpoint and set LLM_MAX_TOKENS_PARAM=max_tokens. No business-logic change.

Currently all tiers run on OpenAI (gpt-5-mini local, gpt-5.1 remote, text-embedding-3-small); the design keeps the provider swap to a handful of env vars.


Quickstart

Prerequisites: Docker + Docker Compose, and (for the frontend) Node.js + pnpm. An OpenAI-compatible API key.

# 1. Configure — copy the template and fill in your key(s)
cp .env.example .env        # set OPENAI_API_KEY (min); optionally TAVILY_API_KEY

# 2. Bring up the whole stack (Postgres + Redis + API + frontend)
docker compose up --build   # API on http://localhost:8000 (GET /healthz), UI on http://localhost:3000

The API container runs Alembic migrations against the pgvector Postgres on boot. The frontend reads NEXT_PUBLIC_API_URL (defaults to http://localhost:8000).

For frontend work with live reload, stop the Compose frontend service and run cd frontend && pnpm install && pnpm dev instead (same port 3000).

Seeded demo mode (offline)

Set SEEDED_DEMO=true and analyze https://notion.so. Discovery returns a deterministic Notion / Coda / Obsidian trio and collection replays committed HTML snapshots from backend/seeds/ — no discovery search, no scraping, no enrichment calls. (Embeddings, analyst extraction, and synthesis still run, so the report is real.) This is the reproducible happy-path used for demos and CI-style checks.


Configuration

Copy .env.example → .env. Key variables (full defaults in backend/app/core/config.py):

Variable Default Notes
OPENAI_API_KEY — Shared fallback key for every tier.
LOCAL_LLM_MODEL / LOCAL_LLM_BASE_URL gpt-5-mini / OpenAI High-volume tier (point at AMD/vLLM to tell the AMD story).
REMOTE_LLM_MODEL / REMOTE_LLM_BASE_URL gpt-5.1 / OpenAI Heavy-reasoning tier.
EMBEDDING_MODEL / EMBEDDING_DIM text-embedding-3-small / 1536 pgvector column + HNSW index size.
LLM_MAX_TOKENS_PARAM max_completion_tokens Use max_tokens for vLLM/Fireworks.
DATABASE_URL postgresql+asyncpg://warroom:warroom@localhost:5432/warroom Async driver.
REDIS_URL redis://localhost:6379/0 SSE pub/sub bus.
TAVILY_API_KEY — Optional search fallback when DuckDuckGo rate-limits.
SEEDED_DEMO false Offline replay of the demo trio.
MODEL_PRICES (built-in) USD per 1M tokens, per model — drives cost estimates.

Secrets live only in .env / backend/.env (both git-ignored); only .env.example is tracked.


Development

# Backend (from backend/) — Python 3.12, managed with uv
uv sync                               # install
uv run alembic upgrade head           # migrate
uv run uvicorn app.main:app --reload  # dev server
uv run pytest                         # service-layer tests
uv run ruff check . && uv run ruff format .

# Frontend (from frontend/) — Next.js 16 / React 19 / TS
pnpm install
pnpm dev                              # dev
pnpm build                            # gated: eslint . --max-warnings=0 && next build

The frontend build is gated on a strict, type-aware ESLint pass (strictTypeChecked + stylisticTypeChecked, zero warnings) before next build. Tests cover service-layer logic (extraction parsing, diff logic, evidence-schema enforcement, threat scoring, war-game persona resolution).

Project structure

backend/
  app/
    main.py            # FastAPI app; routers under /api/v1; startup sweep
    core/              # config · db · llm (tiered gateway) · bus · tasks · search · prompts
    agents/            # Agno workflows: pipeline.py (2 phases) · wargame.py (debate)
    modules/
      analyses/  collection/  intelligence/  wargame/  metrics/
    prompts/           # versioned *.md agent prompts
  seeds/               # Notion/Coda/Obsidian HTML snapshots for SEEDED_DEMO
  alembic/             # migrations (pgvector, domain tables, discovery + threat columns)
frontend/
  app/                 # App Router: / · analysis/[id] · report/[id] · report/[id]/wargame
  components/          # report · competitor · wargame · evidence · analysis · ui (shadcn)
  messages/{en,tr}/    # next-intl catalogs
PROJECT_SPEC.md        # source of truth for scope, agents, schema, plan

API surface (/api/v1)

Method & path Purpose
POST /analyses Start a run (kicks off discovery).
GET /analyses/{id} Status + per-step progress + competitors.
PATCH /analyses/{id}/competitors HITL gate — confirm/reject/add, then phase 2 runs.
GET /analyses/{id}/events SSE pipeline stream.
GET /analyses/{id}/report · GET /reports/{id} The synthesized report.
POST /reports/{id}/wargame Start a war-game debate.
GET /wargame/{id} · GET /wargame/{id}/stream Debate state / SSE stream.
GET /metrics/model-usage Cost-panel usage (never 404s).
GET /healthz Liveness.

Tech stack

Backend — FastAPI · async SQLAlchemy 2.0 · Alembic · PostgreSQL + pgvector (HNSW) · Redis (SSE) · Agno (agent workflows) · OpenAI-compatible LLMs · httpx + selectolax + trafilatura (scraping) · DuckDuckGo/Tavily (discovery search) · uv · ruff.

Frontend — Next.js 16 (App Router) · React 19 · TypeScript · Tailwind v4 · shadcn/ui + Radix · TanStack Query (server state) · Zustand (UI state) · Recharts · Motion · next-intl (EN/TR) · next-themes · @react-pdf/renderer · pnpm.


Documentation

PROJECT_SPEC.md is the source of truth for scope, architecture, the agent pipeline, the data model, and the build plan. CLAUDE.md records the hard architecture rules.


License

Apache License 2.0 — see LICENSE. The self-hosted fonts (frontend/public/fonts/) are under the SIL Open Font License 1.1, and the demo snapshots in backend/seeds/ are archived third-party web pages outside this license — see NOTICE.

About

Autonomous competitive intelligence: one URL in, an evidence-linked report and a war-gamed prediction of your rival's next move out. AMD Developer Hackathon ACT II.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages