Skip to main content

star-chamber

Multi-LLM council protocol SDK. Fan out code reviews and design questions to multiple LLM providers, then classify findings by consensus.

Installation

pip install star-chamber

Or with uv:

uv add star-chamber

Configuration

Create ~/.config/star-chamber/providers.json:

{
  "providers": [
    {"provider": "openai", "model": "gpt-4o", "api_key": "${OPENAI_API_KEY}"},
    {"provider": "anthropic", "model": "claude-sonnet-4-20250514", "api_key": "${ANTHROPIC_API_KEY}"}
  ],
  "timeout_seconds": 90,
  "consensus_threshold": 2
}

API keys can be literal values or ${ENV_VAR} references that are resolved at runtime.

Provider display names

When several council members share one provider — for example, multiple models behind an OpenAI-compatible gateway such as OpenRouter — give each entry a unique display_name. It becomes that member's identity in council output (consensus classification, flagged_by, quality ratings, individual issues) and is matched by --provider filters. Without it, same-provider members collapse into a single vote and unanimous consensus becomes unreachable:

{
  "providers": [
    {"provider": "openrouter", "display_name": "gpt-5.2", "model": "openai/gpt-5.2", "api_key": "${OPENROUTER_API_KEY}"},
    {"provider": "openrouter", "display_name": "gemini-3.1-pro", "model": "google/gemini-3.1-pro-preview", "api_key": "${OPENROUTER_API_KEY}"},
    {"provider": "openrouter", "display_name": "grok-4.3", "model": "x-ai/grok-4.3", "api_key": "${OPENROUTER_API_KEY}"}
  ],
  "consensus_threshold": 2
}

In the JSON output, each provider response carries both the underlying provider (the routing target) and this display_name, and the display name is the key used throughout the aggregated result — providers_used, quality_ratings, individual_issues, flagged_by, and failed_providers. A member with no display_name falls back to the provider name.

Otari gateway

Instead of managing API keys per provider, you can route all non-local providers through Otari, Mozilla AI's OpenAI-compatible LLM gateway, by adding a top-level otari object:

{
  "providers": [
    {"provider": "openai", "model": "openai:gpt-4o"},
    {"provider": "anthropic", "model": "anthropic:claude-sonnet-4-20250514"}
  ],
  "otari": {
    "api_base": "https://your-gateway.example/v1",
    "api_key": "${OTARI_API_KEY}"
  },
  "timeout_seconds": 90,
  "consensus_threshold": 2
}

In Otari mode, Otari — not the SDK — picks the upstream provider, so the per-provider provider field becomes a label. Otari expects the model field to use a provider:model prefix such as "openai:gpt-4o"; consult Otari's documentation for its model-naming convention.

api_base and api_key may be omitted from the config; when omitted, the SDK's OtariProvider auto-detects credentials from its own env vars (OTARI_AI_TOKEN for platform mode, GATEWAY_API_KEY for self-hosted). Both fields also support ${ENV_VAR} references.

Providers marked "local": true always bypass Otari and continue to use their own api_base.

Override the config path with the STAR_CHAMBER_CONFIG environment variable.

CLI

Code review

star-chamber review src/auth.py src/db.py

Design question

star-chamber ask "Should we use Redis or Memcached for session storage?"

Options

--provider, -p    Provider to include (repeatable)
--config          Path to providers.json
--timeout         Per-provider timeout in seconds
--context-file    File containing project context to include in the prompt
--council-context File containing prior council round feedback (debate mode)
--format          Output format: text or json
--output          Write JSON result to file

List providers

star-chamber list-providers

Protocol schemas

The SDK ships the council protocol specification as package data.

# List available schemas.
star-chamber schema list

# Print a specific schema.
star-chamber schema code-review-result

Python API

from star_chamber import run_council_sync, CouncilConfig, ProviderConfig

config = CouncilConfig(
    providers=(
        ProviderConfig(provider="openai", model="gpt-4o"),
        ProviderConfig(provider="anthropic", model="claude-sonnet-4-20250514"),
    ),
    timeout_seconds=90,
    consensus_threshold=2,
)

# Code review.
result = run_council_sync(
    files={"auth.py": open("auth.py").read()},
    config=config,
    mode="code-review",
)

print(result.summary)
for issue in result.consensus_issues:
    print(f"  [{issue.severity}] {issue.location}: {issue.description}")

# Design question.
result = run_council_sync(
    prompt="Should we use a monorepo or polyrepo?",
    config=config,
    mode="design-question",
)

print(result.consensus_recommendation)

Async

import asyncio
from star_chamber import run_council

result = asyncio.run(run_council(
    files={"auth.py": open("auth.py").read()},
    mode="code-review",
))

Schema access

from star_chamber import get_schema, list_schemas

# List available schema names.
names = list_schemas()

# Get a specific schema as a JSON string.
schema_json = get_schema("code-review-result")

Consensus classification

Issues from multiple providers are grouped by file, line proximity (within 5 lines), and category, then classified as:

  • Consensus -- all providers agree.
  • Majority -- two or more providers agree, but not all.
  • Individual -- flagged by a single provider.

Results are sorted by severity within each bucket.

License

Apache-2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

star_chamber-0.4.0.tar.gz (96.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

star_chamber-0.4.0-py3-none-any.whl (51.5 kB view details)

Uploaded Python 3

File details

Details for the file star_chamber-0.4.0.tar.gz.

File metadata

  • Download URL: star_chamber-0.4.0.tar.gz
  • Upload date:
  • Size: 96.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for star_chamber-0.4.0.tar.gz
Algorithm Hash digest
SHA256 77b020bf270870e3193e17cfd22afc83e95c603af749f55ba7a43f9a4ba093f2
MD5 489f23e01cf1e082699c9c10920b9d1f
BLAKE2b-256 7da7d05f579dceda44c7f6599c49cbb6bac73aabdc52166077a9fdc0c480e681

See more details on using hashes here.

Provenance

The following attestation bundles were made for star_chamber-0.4.0.tar.gz:

Publisher: release.yaml on peteski22/star-chamber

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file star_chamber-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: star_chamber-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 51.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for star_chamber-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3fc657cb017cf186373a012f04b5841426d4e183155a336732a2d6f50aa39fed
MD5 e63f4aa133618c1dd4a27b2259f7874f
BLAKE2b-256 b40d56cf28ab1243eec073c30b0cbd8f5d4b88903841ef2e3adad1977653a6ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for star_chamber-0.4.0-py3-none-any.whl:

Publisher: release.yaml on peteski22/star-chamber

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page