Skip to content

AI-powered research assistant for Polymarket prediction markets

Notifications You must be signed in to change notification settings

OxFrancesco/PolyChrome

Repository files navigation

PolyChrome

AI-powered research assistant for Polymarket prediction markets.

PolyChrome searches multiple sources (Exa, Perplexity, xAI Grok), cross-checks claims, and estimates fair probabilities to help you make informed decisions.

Features

  • 🔍 Multi-source research: Queries Exa, Perplexity Sonar Pro, and xAI Grok for comprehensive coverage
  • 📊 Fair probability estimates: Compares market odds against research-based estimates
  • 📑 Citation tracking: Every claim links to its source
  • Multiple modes: Fast, Balanced, or Deep analysis
  • 🔒 Secure: API keys stay on your Cloudflare Worker, never in the extension

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                     Chrome Extension (MV3)                       │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────────┐  │
│  │Content Script│───▶│ Background SW │───▶│  Sidebar UI      │  │
│  │(DOM Parser)  │    │ (API Calls)   │    │  (Results)       │  │
│  └──────────────┘    └───────┬───────┘    └──────────────────┘  │
└──────────────────────────────┼──────────────────────────────────┘
                               │ POST /v1/analyze
                               ▼
┌─────────────────────────────────────────────────────────────────┐
│                    Cloudflare Worker                             │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────────┐  │
│  │  AI Agent    │───▶│    Tools     │───▶│  Cache + Rate    │  │
│  │ (OpenRouter) │    │ Exa/PPL/Grok │    │    Limiting      │  │
│  └──────────────┘    └──────────────┘    └──────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Project Structure

polychrome/
├── shared/               # Shared Zod schemas + TS types
│   ├── schema.ts         # API contract schemas
│   ├── types.ts          # Inferred TypeScript types
│   └── index.ts          # Re-exports
├── worker/               # Cloudflare Worker (API)
│   ├── src/
│   │   ├── index.ts      # Entry point + routing
│   │   ├── agent.ts      # AI agent with generateText
│   │   ├── env.ts        # Environment bindings
│   │   ├── tools/        # Search tool implementations
│   │   │   ├── exa.ts
│   │   │   ├── perplexity.ts
│   │   │   └── grok.ts
│   │   └── util/         # Caching + rate limiting
│   │       ├── cache.ts
│   │       └── rate-limit.ts
│   ├── test/             # Agent tests + trace runners (Bun)
│   │   ├── agent.unit.test.ts
│   │   ├── agent.run.test.ts
│   │   ├── http-test-agent.ts
│   │   ├── run-agent-trace.ts
│   │   └── traces/        # Local trace outputs (gitignored)
│   ├── wrangler.toml     # Worker configuration
│   └── package.json
├── extension/            # Chrome Extension (MV3)
│   ├── src/
│   │   ├── background.ts # Service worker
│   │   ├── content.ts    # Page injection
│   │   ├── options.ts    # Settings page
│   │   ├── options.html
│   │   ├── polymarket/
│   │   │   └── parse.ts  # DOM parser
│   │   └── ui/
│   │       ├── sidebar.ts
│   │       └── sidebar.css
│   ├── manifest.json
│   ├── build.ts          # Bun build script
│   └── package.json
├── package.json          # Workspace root
├── plan.md               # Implementation checklist
└── README.md

Setup

Prerequisites

Installation

# Clone and install dependencies
git clone https://github.com/your-repo/polychrome.git
cd polychrome
bun install

Deploy the Worker

  1. Configure secrets:
bunx wrangler secret put OPENROUTER_API_KEY --config worker/wrangler.toml
bunx wrangler secret put EXA_API_KEY --config worker/wrangler.toml
bunx wrangler secret put PERPLEXITY_API_KEY --config worker/wrangler.toml
bunx wrangler secret put XAI_API_KEY --config worker/wrangler.toml
  1. Deploy:
bun run deploy:worker
# or: bunx wrangler deploy --config worker/wrangler.toml
  1. Note your Worker URL (e.g., https://polychrome-worker.your-subdomain.workers.dev)

Build the Extension

bun run build:extension
# or: cd extension && bun run build

Load in Chrome

  1. Open chrome://extensions
  2. Enable Developer mode (top right)
  3. Click Load unpacked
  4. Select the extension/dist folder

Configure the Extension

  1. Click the PolyChrome icon in Chrome toolbar
  2. Or right-click → Options
  3. Enter your Worker URL (from step 2 of deployment)
  4. Choose your default analysis mode

Development

Local Worker Development

# Start local dev server (port 8787)
bun run dev:worker
# or: bunx wrangler dev --config worker/wrangler.toml

Testing & Tracing (Worker)

The worker includes a comprehensive test suite with structured tracing for debugging and analysis.

Running Tests

# Run all offline agent tests (fast, deterministic, no network calls)
bun run test:worker
# or: cd worker && bun test

# Run tests and write trace JSON files for each test run
POLYCHROME_WRITE_TRACES=1 bun run test:worker

Test Coverage:

  • Unit tests (agent.unit.test.ts): Pure functions (JSON parsing, outcome preparation, fallback logic)
  • Integration tests (agent.run.test.ts): Full agent runs with mocked AI/tools, covering:
    • Success path (generateObject works)
    • Phase 1 failure (tool calls fail, continues with empty research)
    • Phase 2 failure (structured output fails, falls back to manual JSON extraction)
    • Complete fallback (manual parse fails, uses fallback analysis)
    • Schema validation (ensures all responses match AnalyzeResponseSchema)

Generating Traces

Traces capture every step of an agent run: prompts, tool calls/results, model outputs, errors, and timings.

# Generate a trace from a direct agent run (no HTTP)
bun run trace:worker
# or: cd worker && bun run trace

# Trace files are written to worker/test/traces/agent-trace-*.json

Trace Structure: Each trace is a JSON array of events with:

  • ts: ISO timestamp
  • tMs: Milliseconds since run start
  • type: Event type (e.g., run.start, phase1.step.finish, phase2.generateObject.error)
  • data: Event-specific payload (sanitized, truncated for large strings/objects)

Common Event Types:

  • run.start / run.complete: Run boundaries
  • phase1.start / phase1.complete / phase1.error: Research gathering
  • phase1.step.finish: Each tool-calling step (includes tool calls/results)
  • phase2.start / phase2.generateObject.success|error: Structured output generation
  • phase2.manualParse.success|error: Fallback JSON extraction attempts

HTTP Integration Test

Test against a running wrangler dev server:

# Terminal 1: Start the worker
cd worker
bunx wrangler dev --remote

# Terminal 2: Run HTTP test (optionally with trace)
cd worker
bun run test:agent
# or with trace: bun run test:agent --trace

The HTTP test validates the full request/response cycle and can optionally write trace JSON files.

Using Traces for Debugging

  1. Inspect trace files in worker/test/traces/ to see exactly what happened during a run
  2. Compare traces between runs to identify regressions or changes in behavior
  3. Debug failures: Trace events include error details, model outputs, and tool results
  4. Performance analysis: tMs timestamps show where time is spent

Note: Trace files are gitignored by default (worker/test/traces/*.json). Commit them only if needed for documentation or debugging specific issues.

Extension Development

cd extension
bun run build   # Build once
bun run watch   # Watch mode (if implemented)

After rebuilding, refresh the extension in chrome://extensions.

API Contract

POST /v1/analyze

Request:

{
  "url": "https://polymarket.com/event/...",
  "question": "Super Bowl Champion 2026",
  "outcomes": [
    { "name": "Kansas City Chiefs", "marketProb": 0.12 },
    { "name": "Buffalo Bills", "marketProb": 0.10 }
  ],
  "mode": "balanced"
}

Response:

{
  "market": {
    "asOf": "2025-12-29T12:55:00Z",
    "outcomes": [...]
  },
  "summaryBullets": [
    "Key finding 1",
    "Key finding 2"
  ],
  "evidence": [
    {
      "claim": "Chiefs have won 4 of last 5 Super Bowls",
      "confidence": 0.9,
      "sources": [{ "title": "ESPN", "url": "...", "provider": "exa" }]
    }
  ],
  "forecast": {
    "fairProbs": [
      { "name": "Kansas City Chiefs", "p": 0.11, "low": 0.08, "high": 0.14 }
    ],
    "methodNotes": "Based on historical performance and current season stats"
  },
  "deltas": [
    { "name": "Kansas City Chiefs", "market": 0.12, "fair": 0.11, "delta": -0.01 }
  ]
}

Configuration

Worker Environment Variables

Set in wrangler.toml under [vars]:

Variable Default Description
OPENROUTER_MODEL google/gemini-2.0-flash-001 LLM model slug
MODE_DEFAULT balanced Default analysis mode
MAX_STEPS 10 Max tool-calling iterations
CACHE_TTL_SECONDS 120 Cache duration
RATE_LIMIT_PER_MINUTE 30 Requests per IP per minute

Secrets (set via wrangler secret put)

  • OPENROUTER_API_KEY
  • EXA_API_KEY
  • PERPLEXITY_API_KEY
  • XAI_API_KEY

License

MIT

About

AI-powered research assistant for Polymarket prediction markets

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors