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_API_KEY for the hosted otari.ai platform (Authorization: Bearer, matching otari.ai's docs), or GATEWAY_API_KEY for a self-hosted gateway (Otari-Key header). OTARI_AI_TOKEN is also accepted as a platform-token alias. 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.1.tar.gz (96.2 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.1-py3-none-any.whl (51.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for star_chamber-0.4.1.tar.gz
Algorithm Hash digest
SHA256 7e93a7f7afe190fb43e2dbac32911e28fa8f5d2e1db65880b22a2c6086e4b303
MD5 885d8ca3ee4971aa9996aa14a65f7805
BLAKE2b-256 9ac44397ea191427da8316c6b8989150c06f21da5ae490dd1a378c38b4c3c4b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for star_chamber-0.4.1.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.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for star_chamber-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 efcd266a53eb8792a986799723566bef3948a579f9175d6b4c0fe6594d75a5f7
MD5 9fef61ec85e81fdf2e056f2d24177454
BLAKE2b-256 955ff662858e789e888e01526d6e3fea6afd3edeaf96c1d7a7d8610b0e6b117a

See more details on using hashes here.

Provenance

The following attestation bundles were made for star_chamber-0.4.1-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