Honest multi-model deliberation for local and OpenAI-compatible runtimes.
WEIPING_COUNCIL is the repository identity for Weiping Council. It asks several configured council members to reason through a question, then preserves the route, model evidence, dissent, timings, warnings, and degraded runtime state. The goal is not to make a chatbot look more confident. The goal is to make deliberation inspectable enough that you can tell when it worked, when it was partial, and why.
Compatibility note: this project was previously published as Vipin Council (vipin-council). The legacy vc.py CLI and vc console script remain supported while the public repository identity moves to WEIPING_COUNCIL.
Agents maintaining this repository should read AGENTS.md, this README, CLAUDE.md, and .codex/skills/weiping-council/SKILL.md before non-trivial work.
v2.3 is the honest-runtime release:
- provider credentials are environment-only, loaded from the process environment or
.env; - council member identity is separate from provider model identity, so six roles no longer collapse into one map key;
- each query gets session-scoped model traces, including concurrent requests;
/api/health, CLI status, and the React UI expose redacted readiness instead of raw provider endpoints;- missing provider config, provider errors, and unavailable agentmemory recall are explicit degraded states;
- default CORS is local-first through
VC_CORS_ORIGINS, not wildcard; - the project includes a Codex skill at
.codex/skills/weiping-council/SKILL.mdfor future reproduction, maintenance, monitoring, releases, and upgrade passes.
Single-model answers often hide the uncertainty that matters most. Weiping Council gives you several structured ways to ask for disagreement, review, synthesis, and verification:
| Protocol | Best For | Shape |
|---|---|---|
council |
open-ended questions, research, design review | first opinions, peer review, chairman synthesis |
debate |
trade-offs and contentious choices | pro, con, rebuttal, judge verdict |
redteam |
finding weaknesses | defenders, attacker critique, improved answer |
consensus |
alignment and policy choices | repeated rounds until enough members agree |
specialist |
domain routing | classify, specialist answer, verifier checks |
tournament |
choosing the strongest answer | bracketed comparisons and winner |
React UI / vc CLI / REST API
|
FastAPI backend
|
Orchestrator
- optional agentmemory context recall
- smart routing
- task decomposition
- protocol execution
- self-refine
- metrics, warnings, degraded state
|
ModelRouter
- OpenAI-compatible or Anthropic-format providers
- per-session model call traces
- redacted provider readiness
Core files:
backend/runtime.py-.env/environment loading, provider readiness, CORS origins, trace dataclasses.backend/providers/router.py- provider calls, retry/degraded handling, context-local trace collection.backend/council/orchestrator.py- run pipeline, timings, context recall, degraded semantics.backend/main.py- FastAPI API, health, models, session persistence.vc.py- terminal interface.frontend/src/components/ResultView.jsx- runtime evidence in the UI.
Prerequisites:
- Python 3.11+
- Node.js 18+
- an OpenAI-compatible provider key such as OpenRouter, or role-specific provider credentials
git clone https://github.com/appleweiping/WEIPING_COUNCIL.git
cd WEIPING_COUNCIL
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
copy .env.example .env
# edit .env and add provider keys
cd frontend
npm install
cd ..Run everything:
start.cmdManual run:
# terminal 1
.\.venv\Scripts\python.exe -m uvicorn backend.main:app --reload --port 8000
# terminal 2
cd frontend
npm run dev
# terminal 3
.\.venv\Scripts\python.exe vc.pyMinimal .env:
OPENROUTER_API_KEY=
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
OPENROUTER_MODEL=gpt-5.5
OPENROUTER_API_FORMAT=openai
DEEPSEEK_API_KEY=
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
DEEPSEEK_MODEL=deepseek-chat
DEEPSEEK_API_FORMAT=openai
AGENTMEMORY_URL=http://localhost:3111
VC_CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173Per-role overrides use this pattern:
VC_PROVIDER_ARCHITECT_MODEL=claude-opus-4-7
VC_PROVIDER_ARCHITECT_BASE_URL=http://127.0.0.1:8990/v1
VC_PROVIDER_ARCHITECT_API_KEY=
VC_PROVIDER_ARCHITECT_FORMAT=anthropicReplace ARCHITECT with COORDINATOR, IMPLEMENTER, REVIEWER, SPEEDSTER, or BULK_WORKER for other council roles.
Public health and session evidence intentionally do not expose raw provider URLs or API keys. They expose only source labels, configured/missing fields, provider model names, attempts, latency, and error classes.
WEIPING_COUNCIL, deepseek-cli, WEIPING_LAB, WEIPING_WIKI, AGENT_RESOURCE, and AGENTIC_SCIENCE should complement each other without becoming tightly coupled:
WEIPING_COUNCILis the deliberation runtime. It owns protocols, routing evidence, degraded-state semantics, saved session JSON, and the React/CLI interface for council-style reasoning.deepseek-cliis a terminal-first DeepSeek client. It can provide a convenient way to test DeepSeek credentials and workflows, but Weiping Council must remain provider-agnostic through OpenAI-compatible and per-role provider settings.WEIPING_LABis the broader lab/workbench layer. It can consume Weiping Council session artifacts, but lab-specific state should not be required to run this repository.WEIPING_WIKIis the public route map and durable operating context, not a runtime dependency.AGENT_RESOURCEprovides shared skills and workflow references; do not copy its caches, local clones, or private notes into this repo.AGENTIC_SCIENCEprovides optional audit methods such as UUPF for workflow upgrades. Generated UUPF reports are planning evidence only and must stay in ignored work areas unless deliberately released.
Historical compatibility: older local checkouts, session artifacts, or notes may still mention vipin-council, vipin-lab, or Vipin Council. Treat those names as legacy aliases unless a document explicitly describes historical release context.
The only shared memory dependency in this repo is optional agentmemory recall via AGENTMEMORY_URL.
After setup:
.\.venv\Scripts\python.exe vc.py statusHealthy output means:
- backend reachable;
- at least the configured providers are ready;
- agentmemory is reachable if
AGENTMEMORY_URLis set; statusisok.
Degraded output is still useful. It means the backend is alive but one subsystem is partial. Common examples:
- no provider key: queries return explicit unavailable text rather than fake model answers;
- agentmemory down: answers run without recalled context and mark the session degraded;
- provider schema or HTTP failure: the answer includes a provider failure marker and the trace stores the error class.
Submit a query:
curl -X POST http://localhost:8000/api/query \
-H "Content-Type: application/json" \
-d '{"query": "What architecture should I use for this feature?", "protocol": "council"}'Response shape:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"query": "What architecture should I use for this feature?",
"protocol": "council",
"created_at": "2026-06-01T12:00:00",
"stages": [],
"final_answer": "...",
"confidence": 0.82,
"dissent": [],
"audit_trail": [],
"metrics": {"routing_ms": 12.4, "protocol_ms": 2200.1, "total_ms": 2314.8},
"provider_health": [
{
"role": "architect",
"name": "Opus",
"model_id": "gpt-5.5",
"endpoint_configured": true,
"ready": true,
"has_api_key": true,
"missing": []
}
],
"model_call_traces": [
{
"role": "architect",
"model_name": "Opus",
"model_id": "gpt-5.5",
"attempts": 1,
"latency_ms": 850.0,
"error_kind": null
}
],
"degraded": false,
"warnings": []
}Other endpoints:
| Method | Endpoint | Purpose |
|---|---|---|
GET |
/api/health |
redacted backend, provider, and memory readiness |
GET |
/api/models |
council member IDs, roles, and provider model names |
GET |
/api/protocols |
available protocol list |
GET |
/api/sessions |
recent saved sessions |
GET |
/api/sessions/{id} |
saved session JSON |
Saved council handoffs live under data/sessions/<uuid>.json. The directory is runtime state and should stay out of maintenance commits unless the user explicitly asks to curate a public example.
Each saved session JSON should preserve:
id,query,protocol, andcreated_atstages,final_answer,confidence,dissent, andaudit_trailmetricswith timing fieldsprovider_healthwith redacted readiness onlymodel_call_traceswith role, model name/id, attempts, latency, and error classdegradedandwarnings
Lab and wiki workflows may point to these files as artifacts, but they should not require Council's .env, active backend, frontend build output, local caches, or private provider logs.
Use three levels, inspired by current open-source AI runtime practice:
-
Basic process check:
curl http://localhost:8000/api/health
The backend is reachable if this returns JSON.
status: degradedis not downtime. -
Configuration check:
curl http://localhost:8000/api/models
Confirm member IDs and provider models are what you expect.
-
End-to-end check:
curl -X POST http://localhost:8000/api/query \ -H "Content-Type: application/json" \ -d '{"query": "Respond with the word HEALTHY and explain one risk.", "protocol": "council"}'
Treat this as passing only when degraded is false and at least one trace has error_kind: null.
| Symptom | Meaning | Fix |
|---|---|---|
Backend not reachable in the UI |
Vite can load, but FastAPI is not responding | Start uvicorn backend.main:app --reload --port 8000 |
/api/health returns status: degraded |
Backend is alive, but a provider or memory dependency is incomplete | Inspect warnings, providers[].missing, and agentmemory.status |
Query returns [Name unavailable: missing provider configuration (...)] |
The selected role has no usable provider endpoint or key | Fill .env or the relevant VC_PROVIDER_<ROLE>_* variables |
Query returns provider call failed (ValueError) |
Provider responded, but not in the expected schema | Check *_API_FORMAT, provider compatibility, and provider logs |
| CLI status is degraded but UI works | This is a partial runtime, not downtime | Use the Runtime Evidence panel to see which dependency is partial |
| Tests try to use real keys | A test is not hermetic | Prefer RuntimeSettings.from_env(config, env={}) or a temporary .env in the test |
The repository includes .github/workflows/ci.yml with the same backend test, backend lint, frontend build, and secret/retired-path scan used locally.
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m ruff check .
.\.venv\Scripts\python.exe scripts\release_scan.py
cd frontend
npm run build
cd ..
rg -n "sk-[A-Za-z0-9]{10,}|agent[-]hub|memory\\INDEX|D:\\research\\Vipin's Knowledgebase\\memory" . --glob "!frontend/package-lock.json" --glob "!.venv/**" --glob "!*.egg-info/**"On Windows, powershell -ExecutionPolicy Bypass -File scripts\verify.ps1 runs the same local gate. The final scan should return no real source secrets, retired active-coordination dependencies, mirror registry lockfiles, or version drift.
This project does not vendor these systems, but v2.3 deliberately adopts several proven patterns from their actual code:
- Open WebUI separates basic
/healthfrom readiness checks that verify startup and dependencies. - LiteLLM keeps model group names, deployment IDs, routing indexes, cooldown, and health state separate.
- CrewAI loads agent/task configuration from project files and maps configuration into executable agents/tasks.
Useful source files:
See:
docs/releases/2026-06-04-weiping-council-uupf-upgrade.mddocs/releases/v2.3-honest-runtime-observability.md
MIT
