A multi-agent studio where shared context meets individual character.
ComMan combines common and man: a common world, distinct personalities, and independent judgment. Create character agents, shape their identities, and bring them into the same conversation—where each participant can build on, question, or challenge the previous response.
Runs locally without an API key using a deterministic demo provider. Live model responses and portrait generation are optional. The image above is a brand illustration; the current interface is in Simplified Chinese.
Quick start · How it works · Configuration · Verification · API
- Editable characters: configure identity, profession, appearance, personality, worldview, custom attributes, and four personality dimensions.
- Shared conversations: define a story background and ask the group a question; agents respond in order with access to earlier contributions.
- One-to-one chat: explore an individual character's perspective in a dedicated dialog.
- Inspectable configuration: view and copy the JSON behind each character, including its tool permissions.
- Selectable model: choose any model the provider exposes; the choice applies to both group runs and one-to-one chat, and is recorded with the run.
- Light and dark appearance: the theme is applied before first paint and remembered across reloads.
- Persistent run history: inspect group prompts, backgrounds, provider/model metadata, agent replies, errors, and completion status in SQLite-backed records.
- Progressive responses: receive each completed agent reply through an NDJSON event stream, with explicit failure and interruption handling.
- Optional portraits: start with bundled/default images, then generate portraits from the character configuration when an image provider is configured.
The bundled workspace starts with 林溪, a user researcher; 程野, a systems architect; and 沈知, a co-creation facilitator. Edit their personalities, add new members, or rename the group before starting a discussion.
- Set the background shared by every participant.
- Ask a question such as “How should we validate this product idea?”
- Each agent answers once, in the supplied order. Later agents receive earlier replies as context.
- Open 运行记录 to inspect the recorded discussion and its outcome.
flowchart LR
A[Character configuration] --> C[Per-agent prompt]
B[Shared background and question] --> C
C --> D[Sequential agent responses]
H[Earlier replies] --> D
D --> H
D --> E[NDJSON events]
E --> F[Live conversation]
E --> G[SQLite run history]
Each run finishes as completed, failed, or cancelled when execution ends, fails, or the stream is closed. The frontend also reports streams that end without a terminal event. Responses arrive as whole agent messages, rather than token-by-token output.
flowchart TB
UI[React and TypeScript studio :3000] -->|REST and NDJSON| API[FastAPI :8000]
API --> Config[Agent and workspace configuration]
API --> Runs[Multi-agent orchestrator]
API --> Chat[Direct chat]
Runs --> Provider[Model provider]
Chat --> Provider
Provider --> Demo[Offline rule engine]
Provider --> Live[OpenAI-compatible Chat Completions]
Config --> DB[(SQLite)]
Runs --> DB
API --> Tools[Permission-checked local tool API]
API --> Images[Optional portrait provider]
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, vinext, Vite |
| Backend | Python, FastAPI, Pydantic, HTTPX |
| Model integration | OpenAI-compatible Chat Completions |
| Persistence | SQLite for configuration and group-run events; local files for generated portraits |
| Frontend hosting entry | Cloudflare Worker; the Python API runs separately |
- Python 3.11 and a virtual environment of your choice
- Node.js 22.13+ and npm
- Optional: access to a compatible model endpoint for live responses
From your active Python environment:
git clone https://github.com/JaspinXu/ComMan.git
cd ComMan
python -m pip install -r backend/requirements.txt
npm ciRun the backend and frontend in two separate terminals, both from the repository root.
Backend:
python -m uvicorn backend.main:app --host 127.0.0.1 --port 8000Frontend:
npm run devOpen the studio. The API documentation and health endpoint are available on port 8000.
Without SOCLAAS_API_KEY, the interface displays Local Engine and uses the persona-rule-engine demo model. This exercises the workspace and persistence flow without making external model calls.
The helper starts both services, waits for backend readiness, and stops the backend when the frontend exits:
powershell -ExecutionPolicy Bypass -File .\scripts\run-demo.ps1It uses Python and Node.js from your current PATH. To select a Conda environment explicitly, append -CondaEnv your_environment_name.
For live responses or custom storage, copy .env.example to .env:
cp .env.example .envIn PowerShell, use Copy-Item .env.example .env. Edit the file locally and restart the backend after changing it. .env is excluded from Git.
| Variable | Purpose |
|---|---|
SOCLAAS_API_KEY |
Enables live model responses when set |
SOCLAAS_BASE_URL |
Compatible API base URL, including its API prefix such as /v1 |
SOCLAAS_MODEL |
Default chat model available from your provider |
SOCLAAS_TIMEOUT |
Provider request timeout in seconds; default 90 |
COMMAN_DB |
SQLite file path; new workspaces default to data/ComMan.db |
IMAGEGEN_BASE_URL |
Optional image endpoint base URL; falls back to the chat provider URL |
IMAGEGEN_API_KEY |
Optional image credential; falls back to the chat credential |
IMAGEGEN_MODEL |
Image-capable model; leave empty to keep portrait generation disabled |
AGENT_IMAGE_PATH |
Generated portrait directory; default data/agent_images |
The bundled endpoint targets SoC LaaS. Use your own compatible base URL, API key, and accessible model if you do not have access to that service. A configured live provider reports failures rather than silently replacing its responses with the demo engine.
Both the run API and the one-to-one chat API accept an optional model field. That selection is sent to the provider and, for group runs, stored with the run. Offline mode accepts only its own demo model and rejects any other value rather than ignoring it.
| Data or capability | Current behavior |
|---|---|
| Group name and character configuration | Persisted locally in SQLite |
| Group runs | Background, question, provider/model, status, and ordered events are persisted |
| Active chat windows | Session-only; direct-chat messages are not stored in SQLite |
| Conversation context | Frontend sends the latest 20 direct-chat messages or 60 group messages; the live group provider uses the latest 30 transcript entries |
| Local tools | current_time, calculator, and a memory declaration, exposed through an agent-permission-checked API |
| Automatic tool use | Tool permissions are described in prompts; the model does not execute tools during generation |
| Memory and MCP | Run records provide history; dedicated memory retrieval and MCP transports are extension points, not implemented integrations |
Local defaults remain ports 3000 and 8000. For deployment, set NEXT_PUBLIC_API_BASE before building the frontend and configure backend COMMAN_CORS_ORIGINS (set COMMAN_CORS_ORIGIN_REGEX= to disable the local-host regex). Hosting the frontend Worker alone does not deploy the Python backend.
Optional controls in .env.example include COMMAN_API_TOKEN for write requests, COMMAN_RATE_LIMIT_PER_MINUTE, COMMAN_RUN_TIMEOUT, and COMMAN_RUN_RETENTION_DAYS. These controls are disabled when unset. A matching NEXT_PUBLIC_API_TOKEN is embedded in the browser bundle: this is a personal-deployment gate, not multi-user authorization. Rate limits are process-local. Retention cleans completed old runs at startup and daily; active runs remain intact. Run-detail requests accept optional after_sequence and limit; omitting them preserves the complete event trace.
Unsaved character edits use an API-scoped local draft journal and serialized writes, with best-effort keepalive on page exit. Successful bootstrap replays drafts only for existing characters. Clearing browser storage removes drafts; this is not a server backup. The visible conversation retains 200 messages; persisted group events remain accessible in the archive.
Cloudflare deployments use the IMAGES binding for image transformations. Local development omits that binding because its simulator resets Worker startup on Windows. Without the binding, the image handler validates and serves the source without transformation. Core React, vinext, Vite, RSC, and Cloudflare packages are pinned together; upgrades must pass the build, SSR, unit, contract, and visual checks below.
npm run backend:test
npm run verify
npm run test:contract
npm run test:e2eBackend regression coverage includes agent persistence, deletion, model selection, run completion/failure/cancellation, tool permissions, portrait configuration, and database-name compatibility. Contract tests additionally freeze OpenAPI, NDJSON events, error responses, legacy database migration, and 15 complete persona prompts. Frontend verification runs ESLint architecture boundaries, TypeScript checks, API-stream and DOM/state tests, a production build, and server-rendered page checks. Playwright adds light/dark visual baselines and editing/chat/run/archive flows. Backend development checks also run python -m ruff check backend, python -m mypy, and lint-imports. Install Chromium with npx playwright install chromium before the first browser run. Run the build before a standalone TypeScript check because vinext generates route types. These checks use offline or mocked providers; they do not validate access to a live model service.
For reproducible contract tests, use an isolated Python environment with the pinned test dependencies (OpenAPI output depends on FastAPI and Pydantic versions):
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r backend/requirements-dev.txt
npm run backend:test
npm run verify
npm run test:contract
npm run test:e2eOn macOS/Linux, activate with source .venv/bin/activate. The snapshot test ignores only info.version; all other OpenAPI differences require review. After an intentional API change, export with python -m scripts.export_openapi and inspect the diff in shared/openapi.snapshot.json. Do not regenerate fixtures merely to make a refactor pass. Prompt fixtures and the stream golden file under backend/tests/contract/golden/ were captured before the persona refactor; their bytes (including whitespace) are part of its regression contract.
The deprecated backend.prompts and backend.imagegen.portrait_prompt imports remain supported and emit DeprecationWarning; new callers should use backend.infrastructure.prompts. The pinned Starlette version also emits an upstream TestClient/httpx deprecation warning; it does not indicate a failed test.
For a complete Windows environment check and dependency install:
powershell -ExecutionPolicy Bypass -File .\scripts\verify-local.ps1The verification helper also accepts -CondaEnv your_environment_name.
Interactive request and response schemas are available at /docs while the backend is running.
| Method | Endpoint | Purpose |
|---|---|---|
GET |
/api/health |
Provider, model, database, and tool status |
GET, PUT |
/api/settings |
Read or update the group name |
GET, POST |
/api/agents |
List or create characters |
PUT, DELETE |
/api/agents/{id} |
Update or delete a character |
POST |
/api/agents/{id}/chat |
One-to-one reply |
POST |
/api/agents/{id}/portrait |
Generate a character portrait |
GET |
/api/models |
List models visible to the provider |
POST |
/api/tools/{name}/execute |
Execute an authorized local tool |
POST |
/api/runs |
Start a group run and stream NDJSON events |
GET |
/api/runs |
List recent runs |
GET |
/api/runs/{id} |
Inspect a run and its ordered event trace |
app/studio/
contracts/ Runtime schemas and inferred types
config/ Deployment settings and shared limits
lib/api/ HTTP, NDJSON, and typed endpoint client
hooks/ Focused state, persistence, run/chat/archive logic
state/ Stable contexts and provider composition
features/ Studio composition
components/ Presentation, inspector tabs, common UI primitives
styles/ Scoped layout and feature CSS modules
backend/
domain/ Models and persona facts
ports/ Repository/provider/tool interfaces
application/ Agent, chat, run, portrait, and settings services
infrastructure/ SQLite, providers, tools, prompts, and image adapters
api/ Small routers, middleware, error handlers
core/ Settings, typed errors, structured logging
runtime.py Dependency assembly and resource lifecycle
main.py ASGI application
tests/ Regression, contract, and hardening tests
shared/ Seeds, limits, enums, tools, and OpenAPI snapshot
tests/ Unit/DOM, SSR, TypeScript contract, browser tests
docs/ Architecture decision and execution evidence
scripts/ Local launch, verification, and contract export
worker/ Hosted frontend and image-handler entry point
data/ Local database and portraits (Git-ignored)
The repository and interface use ComMan · 群像; the private npm package uses lowercase comman. The character configuration preview identifies its schema as ComMan/v1.
Older COMMAN_AGENTS_DB and PERSONA_LAB_DB environment variables remain supported, with COMMAN_DB taking precedence. Without an explicit database path, the backend reuses the first existing file in this order: data/ComMan.db, data/persona_lab.db, data/comman_agents.db. A fresh workspace uses data/ComMan.db.
