Metadata-Version: 2.4
Name: whalecouncil
Version: 0.2.0
Summary: Independent second opinions for AI agent workflows.
Author-email: noetherly <noetherly@users.noreply.github.com>
License: MIT
Project-URL: Homepage, https://github.com/openwhale-labs/whalecouncil
Project-URL: Repository, https://github.com/openwhale-labs/whalecouncil
Project-URL: Bug Tracker, https://github.com/openwhale-labs/whalecouncil/issues
Project-URL: Changelog, https://github.com/openwhale-labs/whalecouncil/blob/main/CHANGELOG.md
Keywords: ai,agent,review,multi-model,llm,claude,openai,gemini
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Environment :: Console
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: anthropic>=0.25.0
Requires-Dist: openai>=1.30.0
Requires-Dist: click>=8.1.0
Requires-Dist: rich>=13.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: fastmcp>=2.0
Requires-Dist: fastapi>=0.136.0
Requires-Dist: uvicorn[standard]>=0.47.0
Requires-Dist: sse-starlette>=3.4.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: ruff; extra == "dev"

# WhaleCouncil

> Independent second opinions for AI agent workflows.

When you use a single AI model, you get a single perspective — one that can anchor on wrong assumptions, miss edge cases, or confidently hallucinate. WhaleCouncil sends your task to multiple models **in parallel**, collects independent responses, surfaces disagreements, and synthesizes a final report.

```
$ council review "Should I use Redis or Postgres for this session store?"

WhaleCouncil — reviewing with: claude, codex, gemini
────────────────────────────────────────────────────
claude   ✓  Redis for session data. Low latency reads, built-in TTL...
codex    ✓  Postgres if you already have it. Avoid infra complexity...
gemini   ✓  Depends on scale. Redis at >10k concurrent sessions...
────────────────────────────────────────────────────
⚡ Disagreement: Redis vs Postgres — codex flags infra cost, others favor Redis.
→ Key question to resolve: Do you already run Postgres in this stack?
```

---

## Why

Heavy AI users constantly switch between Claude, GPT, Gemini — manually copying context, pasting outputs back, comparing results by eye. This is slow, error-prone, and easy to skip under pressure.

WhaleCouncil automates the loop:

- **One task in** → multiple independent opinions out
- **No anchoring** — models don't see each other's responses in the first round
- **Structured diff** — disagreements are extracted, not buried in prose
- **Actionable output** — synthesis points to the next decision, not a summary of summaries

The core insight: one AI versus two AI is a qualitative difference, not a quantitative one.

---

## Install

```bash
pip install whalecouncil
```

Or from source:

```bash
git clone https://github.com/openwhale-labs/whalecouncil
cd whalecouncil
pip install -e ".[dev]"
```

Set your API keys in `.env` (copy from `.env.example`):

```bash
cp .env.example .env
# edit .env with your keys
```

---

## Usage

### Review a task

```bash
# inline
council review "Is this approach correct: use a global dict as a cache in a FastAPI app?"

# from file
council review --file mycode.py

# choose models
council review --models claude,codex "Review this SQL query for performance issues"

# output to markdown file
council review --output markdown --file plan.md > report.md
```

### Pipe input

```bash
cat diff.patch | council review --models claude,gemini
git diff HEAD~1 | council review "Any bugs introduced in this diff?"
```

### List available models

```bash
council models
```

### Configuration file

Persistent defaults can be set in `~/.council.toml` (copy from
[`council.toml.example`](council.toml.example)):

```toml
[defaults]
models = ['claude-cli']
output = 'terminal'

[models.claude]
model = 'claude-sonnet-4-6'
```

CLI flags always override the config file, which overrides the built-in
defaults. Per-provider `[models.*]` entries set the model each adapter uses.

---

## Supported Models

| Key          | Provider                                | Notes                                                           |
|--------------|-----------------------------------------|-----------------------------------------------------------------|
| `claude`     | Anthropic                               | Requires `ANTHROPIC_API_KEY`                                    |
| `claude-cli` | Local Claude subscription (Claude Code CLI) | No API key needed. Requires `claude` CLI installed and logged in. |
| `codex`      | OpenAI                                  | Requires `OPENAI_API_KEY`                                       |
| `codex-cli`  | Local Codex CLI (`codex exec`)          | No API key needed. Requires `codex` CLI installed and logged in. |
| `gemini`     | Google                                  | Requires `GEMINI_API_KEY`                                       |
| `gemini-cli` | Local Gemini CLI (`gemini -p`)          | No API key needed. Requires `gemini` CLI installed and logged in. |

---

## How It Works

```
Input task
    │
    ├──► Claude  (independent, no other model's output)
    ├──► Codex   (independent)
    └──► Gemini  (independent)
         │
         ▼
   Collect opinions
         │
         ▼
   Extract disagreements
         │
         ▼
   Synthesize + surface next question
         │
         ▼
   Markdown or terminal report
```

**Round 1 — Independent**: Each model receives only the task and a neutral system prompt. No model sees another's output.

**Round 2 — Synthesis** *(optional)*: A judge model receives all opinions and produces a structured diff: what they agree on, where they diverge, what the divergence reveals, and what question to resolve next.

---

## Roadmap

- [x] CLI skeleton
- [ ] Parallel model dispatch (asyncio)
- [ ] Model adapters: Claude, OpenAI, Gemini
- [ ] Disagreement extraction
- [ ] Synthesis / judge layer
- [ ] Markdown report output
- [ ] Pipe / stdin support
- [x] Config file (`~/.council.toml`)
- [ ] WhaleTrace — save and replay council runs
- [ ] WhaleBench — structured benchmark tasks for agent evaluation

---

## Design Philosophy

- **CLI-first** — works in any terminal, composable with pipes
- **Independent opinions** — first round is always blind; no anchoring
- **Disagreement over consensus** — the value is in the diff, not the summary
- **Minimal infra** — no server, no database, no account required
- **Extensible** — add any OpenAI-compatible model endpoint

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

---

## License

MIT © [noetherly](https://github.com/noetherly)
