Virtual Engineering Team as a Service — AI-powered multi-agent CLI for software development
Project description
Rigovo — Virtual Engineering Team as a Service
8 AI agents. One CLI. Production-grade code with deterministic quality gates.
Stop babysitting AI. Rigovo assembles a full engineering team — planner, coder, reviewer, security, QA, devops, SRE, tech lead — that ships code governed by Rigour quality gates.
Get Started in 60 Seconds
pip install rigovo
$ cd your-project
$ rigovo init
Rigovo — Project Initialization
Detected: python/fastapi
Source: src/
Tests: tests/
Package: pip
Created: rigovo.yml
Created: rigour.yml
Created: .env (add your API key)
Created: .rigovo/
Next steps:
1. Add your API key to .env
2. Run: rigovo doctor
3. Run: rigovo run "your first task"
$ rigovo doctor
Rigovo — Doctor
✓ Python 3.10.12
✓ Platform: Linux aarch64
✓ rigovo.yml found
✓ rigovo.yml valid (version 1)
✓ Project: python/fastapi
✓ .env found
✓ .rigovo/ directory exists
✓ Local database exists (116.0 KB)
✓ ANTHROPIC_API_KEY configured
✓ typer installed (CLI framework)
✓ rich installed (Terminal UI)
✓ pydantic installed (Configuration)
✓ anthropic installed (Anthropic SDK)
✓ langgraph installed (LangGraph orchestration)
✓ Rigour CLI available (npx @rigour-labs/cli)
✓ git found: /usr/bin/git
✓ Disk space: 2.3 GB free
0 issue(s) found, 18 passed
$ rigovo run "Add user authentication with JWT and refresh tokens"
RIGOVO │ Add user authentication with JWT and refresh tokens
Team: engineering
🔍 Scanned: 42 files (python, fastapi)
🧠 Classified: feature (high)
JWT auth with refresh tokens requires multiple new modules
🔧 Pipeline: 📋 planner → 💻 coder → 🔍 reviewer → 🔒 security → 🧪 qa
📋 planner → Claude Sonnet 4.6
💻 coder → Claude Opus 4.6
🔍 reviewer → Claude Sonnet 4.6
🔒 security → Claude Haiku 4.5
🧪 qa → Claude Haiku 4.5
─────────────────── 📋 planner ───────────────────
✓ 📋 planner 4,211 tok │ $0.0213 │ 3.2s
─────────────────── 💻 coder ────────────────────
✓ 💻 coder 12,847 tok │ $0.1024 │ 18.4s
└─ 4 file(s): src/auth/router.py, src/auth/service.py, ...
✓ Gates passed for coder
⚡ Parallel execution: 🔍 reviewer 🔒 security 🧪 qa
✓ Parallel execution complete
╭──────────────────── Task Complete ────────────────────╮
│ Status COMPLETED │
│ Duration 47.2s │
│ Agents 📋 planner → 💻 coder → 🔍 reviewer │
│ → 🔒 security → 🧪 qa │
│ Tokens 24,891 │
│ Cost $0.3241 │
╰───────────────────────────────────────────────────────╯
That's it. One command. Full engineering team.
Desktop Control Plane (Tauri)
Rigovo now includes a UI-first desktop shell under apps/desktop so users can operate the virtual team from a control plane instead of CLI commands.
cd apps/desktop
pnpm install
pnpm tauri dev
One-command local E2E launcher (API + desktop):
./scripts/e2e_desktop.sh
Fast path (skip dependency install if already installed):
RIGOVO_E2E_INSTALL=never ./scripts/e2e_desktop.sh
Prerequisite for desktop shell: Rust toolchain (cargo) installed via rustup.
The desktop app is designed for enterprise operation:
- Task ingestion inbox (plugins/channels)
- Approval center (
auto|notify|approve) - Cross-team workforce matrix (Team A/B/C role assignment)
- Live event stream + execution spotlight
Identity setup is backend-managed. End users running the desktop app are not expected to set WORKOS_* or RIGOVO_* identity env vars locally. Admins configure identity once from the Governance panel (or server env for cloud/self-hosted deploys). Secrets like WORKOS_API_KEY are persisted in project .env (gitignored), not in .rigovo/control_plane_state.json.
Meet Your Team
$ rigovo agents
Rigovo — Agents
Software Engineering Agents
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━━┓
┃ Role ID ┃ Name ┃ Model ┃ Code ┃ Rules ┃ Tools ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━━┩
│ planner │ Technical Planner │ Claude Sonnet 4.6 │ — │ — │ 5 │
│ coder │ Software Engineer │ Claude Opus 4.6 │ ✓ │ 7 │ 8 │
│ reviewer │ Code Reviewer │ Claude Sonnet 4.6 │ — │ 3 │ 4 │
│ security │ Security Expert │ Claude Haiku 4.5 │ — │ — │ 4 │
│ qa │ QA Engineer │ Claude Haiku 4.5 │ ✓ │ — │ 6 │
│ devops │ DevOps Engineer │ Claude Haiku 4.5 │ ✓ │ — │ 5 │
│ sre │ Site Reliability Engineer │ Claude Haiku 4.5 │ ✓ │ — │ 5 │
│ lead │ Tech Lead │ Claude Opus 4.6 │ — │ — │ 4 │
└──────────┴───────────────────────────┴────────────────────┴──────┴───────┴───────┘
Each agent has a dedicated system prompt, specialized tools, and custom rules for your stack. Inspect any agent:
$ rigovo agents coder
Rigovo — Agents
Software Engineer (coder)
Implements code changes following the plan. Writes production-quality code.
Model: Claude Opus 4.6
Produces code: Yes
Pipeline order: 1
Tools: read_file, write_file, list_directory, search_codebase,
run_command, read_dependencies, spawn_subtask, consult_agent
Custom rules (7):
• Use type hints on all function signatures
• Follow PEP 8 conventions
• Use dataclasses or Pydantic models for structured data
• Use pathlib.Path instead of os.path
• Use Pydantic models for all request/response schemas
• Add OpenAPI descriptions to all endpoints
• Use dependency injection for services
Rules are auto-generated based on your stack. Python/FastAPI gets different rules than TypeScript/Next.js.
Architecture Overview
Rigovo follows hexagonal architecture (ports & adapters) with strict dependency inversion. The domain layer has zero infrastructure imports — it defines interfaces that the infrastructure layer implements.
graph TB
subgraph CLI["CLI Layer"]
TYPER[Typer CLI<br/>15 commands]
TUI[Rich Terminal UI<br/>Streaming output]
end
subgraph APP["Application Layer"]
CMD[RunTaskCommand<br/>Task lifecycle orchestrator]
GRAPH[LangGraph StateGraph<br/>Compiled orchestration graph]
MASTER[Master Agent<br/>Classifier · Router · Enricher · Evaluator]
CTX[Context Engineering<br/>Scanner · Memory · Enrichment]
end
subgraph DOMAIN["Domain Layer — Zero I/O"]
ENT[Entities<br/>Task · Agent · Team · Quality · Memory]
IFACE[Interfaces<br/>LLMProvider · QualityGate · DomainPlugin]
SVC[Services<br/>CostCalculator · TeamAssembler · MemoryRanker]
end
subgraph INFRA["Infrastructure Layer"]
LLM[LLM Providers<br/>Anthropic · OpenAI · Groq · Ollama]
QG[Quality Gates<br/>Rigour CLI wrapper]
FS[Filesystem<br/>ToolExecutor · ProjectScanner]
DB[Persistence<br/>SQLite repos × 4]
end
subgraph PLUGINS["Domain Plugins"]
ENG[Engineering Domain<br/>8 roles · 8 tools · AST gates]
FUTURE[Future Domains<br/>LLM Training · Data Science · ...]
end
CLI --> APP
APP --> DOMAIN
APP --> INFRA
INFRA -.->|implements| IFACE
PLUGINS -.->|implements| IFACE
Project Structure
rigovo/
├── cli/ # Typer commands (15 total) + Rich terminal UI
│ ├── main.py # CLI entry point — rigovo run, init, doctor, ...
│ ├── commands_*.py # Command implementations grouped by concern
│ └── terminal/ # Rich console: streaming, approval prompts, summary
├── application/ # Use-case orchestration — the "brain"
│ ├── commands/ # RunTaskCommand — full task lifecycle orchestrator
│ ├── graph/ # LangGraph pipeline: builder, state, edges, 10 nodes
│ ├── master/ # Master Agent: classifier, router, enricher, evaluator
│ └── context/ # Context engineering: scanner, memory retriever, builder
├── domain/ # Pure domain logic — zero infrastructure dependencies
│ ├── entities/ # Task, Agent, Team, Workspace, Quality, Memory, Cost, Audit
│ ├── interfaces/ # LLMProvider, QualityGate, DomainPlugin, EventEmitter
│ └── services/ # CostCalculator, TeamAssembler, MemoryRanker
├── infrastructure/ # Concrete implementations (adapters)
│ ├── llm/ # Anthropic, OpenAI providers + model catalog + registry
│ ├── quality/ # Rigour CLI quality gate wrapper
│ ├── persistence/ # SQLite: tasks, costs, audit, memory (4 repos)
│ ├── filesystem/ # Tool executor: read/write files, run commands
│ ├── embeddings/ # Embedding models for memory similarity search
│ └── terminal/ # Rich console output with streaming
├── domains/ # Pluggable domain definitions
│ └── engineering/ # 8 agent roles, 8 tools, engineering-specific gates
├── config.py # Layered config: built-in → YAML → .env → env vars → CLI
└── container.py # Dependency injection (Composition Root)
Pipeline Architecture
Every task flows through a compiled LangGraph StateGraph — a directed acyclic graph with conditional edges, parallel fan-out, and SQLite checkpointing for crash recovery.
flowchart TD
START((START)) --> SCAN
subgraph PERCEIVE["Phase 1: Perception"]
SCAN["scan_project"]
end
SCAN --> CLASSIFY
subgraph THINK["Phase 2: Classification & Assembly"]
CLASSIFY["classify"]
CLASSIFY --> ROUTE_TEAM["route_team"]
ROUTE_TEAM --> ASSEMBLE["assemble"]
end
ASSEMBLE --> PLAN_APPROVAL
subgraph APPROVE_PLAN["Phase 3: Plan Approval"]
PLAN_APPROVAL{"plan_approval"}
end
PLAN_APPROVAL -->|rejected| FINALIZE
PLAN_APPROVAL -->|approved| EXECUTE
subgraph EXECUTE_LOOP["Phase 4: Agent Execution Loop"]
EXECUTE["execute_agent"]
EXECUTE -.-> CONSULT["consult_agent"]
CONSULT -.-> EXECUTE
EXECUTE --> QUALITY["quality_check"]
QUALITY --> GATE_ROUTE{Gates passed?}
GATE_ROUTE -->|fail + retries left| EXECUTE
GATE_ROUTE -->|fail + max retries| FINALIZE
GATE_ROUTE -->|pass| ROUTE_NEXT["route_next"]
ROUTE_NEXT --> PIPELINE_CHECK{Pipeline complete?}
PIPELINE_CHECK -->|more agents| EXECUTE
PIPELINE_CHECK -->|parallelizable agents| PARALLEL
PIPELINE_CHECK -->|done| COMMIT
end
subgraph PARALLEL_PHASE["Phase 5: Parallel Fan-Out"]
PARALLEL["parallel_fan_out"]
PARALLEL --> DEBATE_CHECK{"Reviewer requested changes?"}
DEBATE_CHECK -->|debate needed| DEBATE["debate_check"]
DEBATE --> EXECUTE
DEBATE_CHECK -->|debate done| COMMIT
end
subgraph COMMIT_PHASE["Phase 6: Commit Approval"]
COMMIT{"commit_approval"}
end
COMMIT -->|rejected| FINALIZE
COMMIT -->|approved| ENRICH
subgraph LEARN["Phase 7: Learning Loop"]
ENRICH["enrich"]
ENRICH --> MEMORY["store_memory"]
end
MEMORY --> FINALIZE
subgraph DONE["Phase 8: Finalization"]
FINALIZE["finalize"]
end
FINALIZE --> END_NODE((END))
Pipeline Nodes (11 total)
| # | Node | Purpose | Input | Output |
|---|---|---|---|---|
| 1 | scan_project |
Read codebase structure, detect tech stack | project_root |
ProjectSnapshot |
| 2 | classify |
Master Agent classifies task type & complexity | description + snapshot | ClassificationData |
| 3 | route_team |
Select target team (auto route or requested team) | classification + team set | team_config seed |
| 4 | assemble |
Build agent pipeline based on classification | classification + team agents | TeamConfig with pipeline_order |
| 5 | plan_approval |
User approves proposed pipeline | team config | approval_status |
| 6 | execute_agent |
Run agent with full context engineering | agent config + context | AgentOutput |
| 7 | quality_check |
Run Rigour AST gates on changed files | files_changed | GateResult |
| 8 | route_next |
Advance to next agent, reset retry state | pipeline index | next agent config |
| 9 | parallel_fan_out |
Execute independent agents simultaneously | remaining roles | merged AgentOutputs |
| 10 | commit_approval |
User approves final results before commit | all outputs | approval_status |
| 11 | enrich + store_memory + finalize |
Extract learnings, persist, aggregate | full state | final result |
State Machine
All state flows through a single TaskState TypedDict — checkpointed after every node for crash recovery.
classDiagram
class TaskState {
+str task_id
+str workspace_id
+str description
+str project_root
+ClassificationData classification
+TeamConfig team_config
+int current_agent_index
+str current_agent_role
+dict agent_outputs
+list agent_messages
+dict gate_results
+list fix_packets
+int retry_count
+int max_retries
+str approval_status
+dict cost_accumulator
+float budget_max_cost_per_task
+int budget_max_tokens_per_task
+Any project_snapshot
+int debate_round
+int max_debate_rounds
+str reviewer_feedback
+list memories_to_store
+str status
+list events
}
class ClassificationData {
+str task_type
+str complexity
+str reasoning
}
class TeamConfig {
+str team_id
+str team_name
+dict agents
+list pipeline_order
}
class AgentOutput {
+str summary
+list files_changed
+int tokens
+float cost
+int duration_ms
}
class AgentMessage {
+str id
+str type
+str from_role
+str to_role
+str status
+str linked_to
+str content
}
TaskState --> ClassificationData
TaskState --> TeamConfig
TaskState --> AgentOutput
TaskState --> AgentMessage
Agent Execution — Context Engineering
Each agent executes within a 5-phase context engineering loop inspired by the Perceive → Remember → Reason → Act → Verify pattern.
flowchart LR
subgraph CONTEXT["Context Assembly (per agent)"]
direction TB
P[📂 Project Snapshot<br/>File tree, tech stack,<br/>key file contents]
M[🧠 Retrieved Memories<br/>Ranked by similarity,<br/>recency, utility]
E[📚 Enrichment Context<br/>Known pitfalls,<br/>domain knowledge]
PI[📋 Pipeline Context<br/>Previous agent outputs]
Q[🛡️ Quality Contract<br/>Role-specific expectations]
end
subgraph LOOP["Agentic Tool Loop"]
direction TB
LLM[LLM Invocation<br/>System prompt +<br/>assembled context]
LLM -->|tool_calls| TOOLS[Tool Executor<br/>read_file, write_file,<br/>search, run_command,<br/>spawn_subtask, consult_agent]
TOOLS -->|results| LLM
LLM -->|end_turn| DONE[Agent Output<br/>summary, files_changed,<br/>tokens, cost]
end
CONTEXT --> LOOP
Inter-Agent Consultation (Advisory Channel)
Agents can request targeted advice from other roles during execution via consult_agent. This is advisory-only and never replaces the target role's pipeline step.
flowchart LR
A["Requesting agent"] -->|"consult request"| P{"Policy gate"}
P -->|blocked| ERR["Policy violation"]
P -->|allowed| READY{"Target output available?"}
READY -->|yes| IMM["Immediate advisory response"]
READY -->|no| Q[Queue Pending Consult Request]
Q --> TGT["Target role executes later"]
TGT --> AUTO["Auto-fulfill advisory response"]
IMM --> THREAD[agent_messages thread]
AUTO --> THREAD
Consultation Policy via rigovo.yml
orchestration:
consultation:
enabled: true
max_question_chars: 1200
max_response_chars: 1200
allowed_targets:
planner: [lead, security, devops]
coder: [reviewer, security, qa]
reviewer: [planner, coder, security, qa, devops, sre, lead]
qa: [coder, reviewer]
consultation.allowed_targetsoverrides the default matrix.- Consultation responses are tagged advisory-only and do not count as task completion for the consulted role.
Context Budget
Context is assembled with hard character limits to prevent blowup:
| Layer | Max Chars | Content |
|---|---|---|
| Project Snapshot | 15,000 | File tree, tech stack, entry points, key file contents |
| Retrieved Memories | 5,000 | Top 8 memories ranked by relevance to role |
| Enrichment Context | 5,000 | Known pitfalls, domain knowledge, conventions |
| Pipeline Context | 8,000 | Previous agent outputs (planner's plan, coder's files) |
| Quality Contract | 2,000 | Role-specific expectations ("Pass gates on first try") |
| Total Budget | 40,000 | Hard cap across all layers |
Memory Retrieval & Ranking
Memories are ranked per-agent using a weighted scoring formula:
score = (0.6 × similarity) + (0.2 × recency) + (0.2 × utility)
Each role gets role-specific memory preferences — the coder prefers ERROR_FIX and PATTERN memories, while the planner prefers CONVENTION and DOMAIN_KNOWLEDGE. Maximum 8 memories per agent to keep context focused.
Task Classification & Routing
The Master Agent classifies every task at temperature 0.0 (deterministic) before any agent executes.
flowchart LR
DESC[Task Description] --> CLASSIFIER[Master Agent<br/>TaskClassifier<br/>T=0.0]
CLASSIFIER --> TYPE[Task Type]
CLASSIFIER --> CX[Complexity]
TYPE --> ASSEMBLER[TeamAssembler]
CX --> ASSEMBLER
ASSEMBLER --> PIPELINE[Pipeline Order +<br/>Gate Schedule]
Task Types → Agent Pipelines
| Type | Example | Pipeline | Gates After |
|---|---|---|---|
FEATURE |
"Add JWT auth" | planner → coder → reviewer → qa | coder |
BUG |
"Fix login crash" | coder → reviewer | coder |
REFACTOR |
"Split auth module" | planner → coder → reviewer | coder |
SECURITY |
"Fix SQL injection" | security → coder → reviewer → qa | coder |
TEST |
"Add unit tests" | qa | qa |
INFRA |
"Add Docker support" | devops → sre → reviewer | devops, sre |
PERFORMANCE |
"Optimize N+1 query" | coder → reviewer | coder |
Complexity Adjustments
| Complexity | Modifications |
|---|---|
LOW |
Minimal pipeline, lower budget |
MEDIUM |
Standard pipeline |
HIGH |
Prepend lead for architectural oversight |
CRITICAL |
Prepend lead + append security if not present |
Quality Gates — Powered by Rigour
Every line of agent-generated code passes through Rigour — deterministic AST checks, not LLM opinions. Catches issues the instant they're written, not after CI fails.
flowchart LR
CODE[Agent writes code] --> RIGOUR[Rigour CLI<br/>rigour check --json<br/>+ auto --deep by policy]
RIGOUR --> PASS{Passed?}
PASS -->|yes| NEXT[Next agent]
PASS -->|no| FP[Fix Packet<br/>Machine-readable<br/>diagnostics]
FP --> RETRY[Agent retries<br/>with fix packet context]
RETRY --> RIGOUR
Automatic Deep Analysis Policy (Default)
Rigovo does not rely on manual user flags for deep analysis. By default:
orchestration.deep_mode: final- Deep analysis runs automatically on the final gated role in the pipeline.
- Earlier gated roles use fast deterministic checks for speed.
Available modes:
never— disable deep analysisfinal— deep on final gated role (default)ci— deep only when runningrigovo run --ci ...always— deep on every gated rolecritical_only— deep only forcriticalcomplexity tasks
Use orchestration.deep_pro: true to run deep in pro tier.
Deep/pro output is parsed into the same violation model as standard gates, so agents receive fix packets and auto-correct without user intervention.
What Rigour Catches
| Category | Gates | Examples |
|---|---|---|
| Security | Hardcoded secrets, SQL injection, command injection, XSS, path traversal | sk-ant-... in source, f"SELECT * FROM {user_input}" |
| AI Drift | Hallucinated imports, duplication drift, context window artifacts, phantom APIs | from utils.magic import solve (doesn't exist) |
| Structure | Cyclomatic complexity, file size, function length, nesting depth | 500-line god function, 8 levels of nesting |
| Safety | Floating promises, unhandled errors, deprecated APIs, bare excepts | async fetch() with no await |
Fix Packet Protocol
When gates fail, Rigour generates structured Fix Packets — machine-readable diagnostics that agents consume directly. No human interpretation needed.
[FIX PACKET]
Attempt 1 of 5:
- [ERROR] no_hardcoded_secrets: Found API key in src/config.py:42
Suggestion: Move to environment variable, use os.getenv("API_KEY")
- [WARNING] max_function_length: Function process_data() is 127 lines
Suggestion: Extract helper functions for each processing step
Agents retry automatically with the fix packet injected into their context, up to max_retries (default: 5).
Agent Debate Protocol
When the reviewer requests changes, the system enters a structured debate loop between the coder and reviewer — like a real code review.
sequenceDiagram
participant C as Coder
participant G as Quality Gates
participant R as Reviewer
participant Q as QA
participant S as Security
C->>G: Write code
G->>G: AST check (PASS)
par Parallel Review
G->>R: Review code
G->>Q: Write tests
G->>S: Security audit
end
R-->>C: CHANGES_REQUESTED<br/>"Extract auth middleware,<br/>add input validation"
Note over C,R: Debate Round 1
C->>G: Revise code with feedback
G->>G: AST check (PASS)
G->>R: Re-review
R-->>C: APPROVED
Note over C,R: Max 2 debate rounds
The debate protocol detects markers in reviewer output (CHANGES_REQUESTED, BLOCKED, needs revision), injects the reviewer's feedback as a fix packet, and routes the coder back for another pass. Maximum 2 debate rounds by default.
Parallel Execution
Independent agents execute simultaneously — cutting review-phase time from sum(individual) to max(individual).
flowchart TD
CODER[💻 Coder<br/>Sequential — must run first] --> GATES[🛡️ Gates PASS]
GATES --> FAN{All remaining<br/>agents parallelizable?}
FAN -->|yes| PAR
subgraph PAR["⚡ Parallel Fan-Out"]
direction LR
REV[🔍 Reviewer]
QA[🧪 QA]
SEC[🔒 Security]
end
FAN -->|no| SEQ[Sequential execution]
PAR --> MERGE[Fan-In & Merge]
SEQ --> MERGE
MERGE --> DEBATE{Debate needed?}
Parallelizable Roles
These roles have no inter-dependency — they all read the coder's output independently:
reviewer— Code review and feedbackqa— Test generation and validationsecurity— Security auditdocs— Documentation generation
Non-parallelizable roles (planner, coder, lead) must run sequentially because later agents depend on their output.
Parallel Tool Execution
Within a single agent's tool loop, multiple tool calls from one LLM response execute simultaneously via asyncio.gather(). When the coder asks to read 5 files at once, all 5 reads happen in parallel.
Sub-Agent Spawning
Agents can decompose complex tasks by spawning independent sub-agents — each with full tool access.
flowchart TD
CODER[💻 Coder Agent] -->|spawn_subtask| SUB1[Sub-Agent 1<br/>Implement auth module]
CODER -->|spawn_subtask| SUB2[Sub-Agent 2<br/>Add API endpoint]
CODER -->|spawn_subtask| SUB3[Sub-Agent 3<br/>Write migration]
SUB1 -->|result| CODER
SUB2 -->|result| CODER
SUB3 -->|result| CODER
The spawn_subtask tool allows agents to create parallel sub-agents during their agentic loop. Each sub-agent receives full tool access (read_file, write_file, search_codebase, run_command) and returns its output to the parent agent.
Model Selection System
Rigovo uses intelligent per-role model defaults — the right model for each job.
flowchart TD
ROLE[Agent Role] --> RESOLVE[resolve_model_for_role]
RESOLVE --> USER{User override<br/>in rigovo.yml?}
USER -->|yes| USE_USER[Use user's model]
USER -->|no| DEFAULT[Role default<br/>from ROLE_DEFAULT_MODELS]
DEFAULT --> PROVIDER{Provider<br/>available?}
PROVIDER -->|yes| USE_DEFAULT[Use default model]
PROVIDER -->|no| CATALOG[Model Catalog<br/>Find best alternative<br/>for available providers]
CATALOG --> USE_ALT[Use alternative model]
Default Model Assignments
| Role | Default Model | Tier | Why |
|---|---|---|---|
lead |
Claude Opus 4.6 | Premium | Architectural decisions need strongest reasoning |
planner |
Claude Sonnet 4.6 | Standard | Planning: fast + smart enough |
coder |
Claude Opus 4.6 | Premium | Coding: best agent model for complex implementations |
reviewer |
Claude Sonnet 4.6 | Standard | Code review needs analysis, Sonnet suffices |
security |
Claude Haiku 4.5 | Budget | Checklist-based security audit |
qa |
Claude Haiku 4.5 | Budget | Test generation is formulaic |
devops |
Claude Haiku 4.5 | Budget | Template-based configurations |
sre |
Claude Haiku 4.5 | Budget | Template-based configurations |
docs |
Claude Haiku 4.5 | Budget | Text generation |
Multi-Provider Support
Rigovo is provider-agnostic. If you only have an OpenAI key, the catalog resolves the best GPT model for each tier. Supported providers:
| Provider | Models | SDK |
|---|---|---|
| Anthropic | Claude Opus 4.6, Sonnet 4.6, Haiku 4.5 | anthropic |
| OpenAI | GPT-5, GPT-5 Mini, GPT-4o, o1, o3-mini | openai |
| Gemini 2.5 Pro, Gemini 2.5 Flash | openai compatible |
|
| DeepSeek | V3.2, R1 | openai compatible |
| Mistral | Large 3, Medium 3, Codestral | openai compatible |
| Groq | Llama 3.3 70B | openai compatible |
| Ollama | Any local model | openai compatible |
| Custom | Any OpenAI-compatible endpoint | openai compatible |
Preset System
Three presets auto-assign models across all roles:
| Preset | Description | Estimated Cost/Task |
|---|---|---|
budget |
Cheapest — still good for most tasks | ~$0.02 |
recommended |
Best quality/cost ratio | ~$0.15 |
premium |
Maximum quality — for critical tasks | ~$0.50 |
LLM Provider Architecture
All LLM interactions go through a unified LLMProvider interface — the application layer never touches a concrete SDK.
classDiagram
class LLMProvider {
<<interface>>
+model_name: str
+invoke(messages, tools, temperature, max_tokens) LLMResponse
+stream(messages, tools, temperature, max_tokens) AsyncIterator
}
class LLMResponse {
+str content
+LLMUsage usage
+str model
+str stop_reason
+list tool_calls
+Any raw
}
class LLMUsage {
+int input_tokens
+int output_tokens
+total_tokens: int
}
class AnthropicProvider {
-api_key: str
-model: str
+invoke() LLMResponse
+stream() AsyncIterator
-_invoke_with_retry()
}
class OpenAIProvider {
-api_key: str
-model: str
-base_url: str
+invoke() LLMResponse
+stream() AsyncIterator
-_invoke_with_retry()
}
LLMProvider <|.. AnthropicProvider
LLMProvider <|.. OpenAIProvider
LLMProvider --> LLMResponse
LLMResponse --> LLMUsage
Token Optimization
- Prompt Caching (Anthropic): System prompts use
cache_control: {type: "ephemeral"}— saving 90% of input tokens after the first call in an agentic loop (cached tokens cost 10% of fresh tokens). - Prompt Caching (OpenAI): Automatic prefix-based caching for repeated message prefixes (1024+ tokens). Optimized by keeping system messages at the start for prefix matching.
- Tool Result Truncation: Tool results are capped at 30,000 characters to prevent context window blowup from large file reads.
- Retry with Exponential Backoff: Both providers retry transient errors (429, 529, 500, 502, 503) with exponential backoff (1s, 2s, 4s, 8s, 16s) — up to 5 attempts.
Cost Tracking & Budget Guards
Every LLM call is tracked. Budget guards prevent runaway costs by halting execution when limits are exceeded.
flowchart LR
CALL[LLM Call] --> TRACK[CostCalculator<br/>input_tokens × price/1M<br/>+ output_tokens × price/1M]
TRACK --> ACC[cost_accumulator<br/>Per-agent running total]
ACC --> GUARD{Budget exceeded?}
GUARD -->|cost ≥ max_cost| HALT[🛑 BudgetExceededError<br/>Task halts immediately]
GUARD -->|tokens ≥ max_tokens| HALT
GUARD -->|within budget| CONTINUE[Continue execution]
Default limits: $2.00 per task, 200,000 tokens per task. Configurable in rigovo.yml.
Approval System
Two human-in-the-loop checkpoints ensure you stay in control:
flowchart LR
subgraph CP1["Checkpoint 1: Plan Approval"]
PLAN[Pipeline assembled:<br/>task type, complexity,<br/>agent pipeline, budget]
end
subgraph CP2["Checkpoint 2: Commit Approval"]
COMMIT[All agents complete:<br/>files changed, costs,<br/>gate results, agent outputs]
end
PLAN -->|approved| EXECUTE[Execute Agents]
PLAN -->|rejected| FAIL1[Finalize: rejected]
EXECUTE --> COMMIT
COMMIT -->|approved| LEARN[Enrich + Memory]
COMMIT -->|rejected| FAIL2[Finalize: rejected]
- Plan Approval — Review the proposed pipeline before any agent executes
- Commit Approval — Review all results before finalizing
Both checkpoints can be auto-approved for CI/CD workflows or interactive for human-in-the-loop development.
Memory & Learning Loop
Rigovo learns from every task — quality gate failures become training data, not just errors.
flowchart TD
TASK[Task Execution] --> GATE_FAIL[Gate Violations]
TASK --> RETRIES[Retry Loops]
TASK --> SUCCESS[Success Patterns]
GATE_FAIL --> ENRICHER[ContextEnricher<br/>Extract pitfalls,<br/>domain knowledge]
RETRIES --> ENRICHER
SUCCESS --> ENRICHER
ENRICHER --> INJECT[Inject into future<br/>agent contexts]
TASK --> MEMORY[Memory Extraction<br/>Master Agent extracts<br/>reusable lessons]
MEMORY --> STORE[SQLite Memory Store]
STORE --> RETRIEVE[MemoryRetriever<br/>Ranked by similarity,<br/>recency, utility]
RETRIEVE --> INJECT
Memory Types
| Type | Example | Used By |
|---|---|---|
PATTERN |
"Use factory pattern for service creation" | Coder, Planner |
ERROR_FIX |
"SQLAlchemy async sessions need expire_on_commit=False" |
Coder |
CONVENTION |
"All endpoints use Pydantic v2 model_validator" | Coder, Reviewer |
DOMAIN_KNOWLEDGE |
"Auth module uses JWT with 15-min access tokens" | All agents |
TASK_OUTCOME |
"Adding endpoints requires updating OpenAPI docs" | Planner |
Persistence Layer
Four SQLite repositories handle all persistence — zero external database dependencies.
erDiagram
TASKS {
uuid id PK
uuid workspace_id FK
string description
string status
int total_tokens
float total_cost_usd
int duration_ms
datetime created_at
}
COSTS {
uuid id PK
uuid task_id FK
string agent_role
int input_tokens
int output_tokens
float cost_usd
string model
}
AUDIT {
uuid id PK
uuid workspace_id FK
uuid task_id FK
string action
string agent_role
string summary
json metadata
datetime created_at
}
MEMORIES {
uuid id PK
uuid workspace_id FK
string memory_type
string content
float utility_score
datetime created_at
}
TASKS ||--o{ COSTS : "has"
TASKS ||--o{ AUDIT : "logged in"
Additionally, LangGraph uses a separate SQLite database (.rigovo/checkpoints.db) for state checkpointing — enabling crash recovery mid-task.
Domain Plugin System
Rigovo is domain-extensible through a plugin interface. The engineering domain ships built-in; future domains (LLM training, data science) plug in the same way.
classDiagram
class DomainPlugin {
<<interface>>
+get_agent_roles() list~AgentRoleDefinition~
+get_task_types() list~TaskTypeDefinition~
+get_quality_gates() list~QualityGate~
+get_tools(role_id) list~ToolDefinition~
+build_system_prompt(role_id, context) str
}
class EngineeringDomain {
+get_agent_roles() 8 roles
+get_tools(role_id) 7 tools
+build_system_prompt() stack-aware prompts
}
DomainPlugin <|.. EngineeringDomain
class AgentRoleDefinition {
+str role_id
+str name
+str description
+int pipeline_order
+bool produces_code
+str preferred_tier
+str default_system_prompt
+list default_tools
}
EngineeringDomain --> AgentRoleDefinition
Engineering Domain — 8 Roles
| Role | Name | Produces Code | Pipeline Order | Tools |
|---|---|---|---|---|
planner |
Technical Planner | — | 0 | read_file, list_directory, search_codebase, read_dependencies |
coder |
Software Engineer | ✓ | 1 | read_file, write_file, list_directory, search_codebase, run_command, read_dependencies, spawn_subtask |
reviewer |
Code Reviewer | — | 2 | read_file, list_directory, search_codebase |
security |
Security Expert | — | 3 | read_file, list_directory, search_codebase |
qa |
QA Engineer | ✓ | 4 | read_file, write_file, list_directory, search_codebase, run_command |
devops |
DevOps Engineer | ✓ | 5 | read_file, write_file, list_directory, run_command |
sre |
Site Reliability Engineer | ✓ | 6 | read_file, write_file, list_directory, run_command |
lead |
Tech Lead | — | 7 | read_file, list_directory, search_codebase |
Tool Definitions
| Tool | Description |
|---|---|
read_file |
Read file contents with optional line range |
write_file |
Create or modify files (creates parent directories) |
list_directory |
Recursive directory listing |
search_codebase |
Regex search across project files |
run_command |
Execute shell commands (tests, builds, linting) with timeout |
read_dependencies |
Parse package.json, pyproject.toml, requirements.txt, etc. |
spawn_subtask |
Spawn independent sub-agent with full tool access |
All 15 Commands
Setup
| Command | What it does |
|---|---|
rigovo init |
Auto-detect your stack, generate rigovo.yml + rigour.yml + .env |
rigovo doctor |
Validate everything — config, API keys, dependencies, Rigour gates |
rigovo version |
Show CLI version |
rigovo upgrade |
Check PyPI for updates |
Run
| Command | What it does |
|---|---|
rigovo run "Add JWT auth" |
Full pipeline — plan → code → review → gates → done |
rigovo run "Fix bug" --ci |
CI mode — JSON output, non-interactive |
rigovo run "Deploy" --team ops |
Target a specific team |
rigovo replay <task_id> |
Re-run a failed task with same parameters |
Inspect
| Command | What it does |
|---|---|
rigovo teams |
List teams with agents, models, and rules |
rigovo agents |
Agent summary table |
rigovo agents coder |
Deep inspect a specific agent |
rigovo config |
View full rigovo.yml |
rigovo config orchestration.budget |
View a specific config section |
rigovo status |
Project health — tasks, costs, Rigour score |
Track
| Command | What it does |
|---|---|
rigovo history |
Task history with outcomes, costs, durations |
rigovo history <task_id> |
Detailed view of a specific run |
rigovo costs |
Cost breakdown — per task, per agent, totals |
rigovo export |
Export as JSON (default) or --format csv |
rigovo login |
Authenticate with Rigovo Cloud |
rigovo dashboard |
Open cloud dashboard in browser |
Configuration
Rigovo uses layered configuration — higher layers override lower:
Built-in defaults → rigovo.yml → rigour.yml → .env → env vars → CLI flags
Quick Config Examples
rigovo init writes a complete rigovo.yml with all schema fields and defaults. The examples below show common overrides.
Override agent model:
# rigovo.yml
teams:
engineering:
agents:
coder:
model: "gpt-5" # Use GPT-5 for coding
temperature: 0.1
security:
model: "claude-opus-4-6" # Use Opus for security
Set budget limits:
orchestration:
budget:
max_cost_per_task: 2.00 # USD per task
max_tokens_per_task: 200000
monthly_budget: 100.00 # USD per month
alert_at_percent: 0.80 # Alert at 80%
Select database backend (company mode):
database:
backend: postgres # sqlite|postgres
local_path: .rigovo/local.db # used when backend=sqlite
Set RIGOVO_DB_URL in .env when using postgres.
Deep analysis policy (automatic by default):
orchestration:
deep_mode: final # never|final|ci|always|critical_only
deep_pro: false # true = use pro deep tier
Inter-agent consultation policy:
orchestration:
consultation:
enabled: true
max_question_chars: 1200
max_response_chars: 1200
allowed_targets:
reviewer: [planner, coder, security, qa, devops, sre, lead]
Enable ecosystem plugins (connectors/skills/MCP):
plugins:
enabled: true
paths: [".rigovo/plugins"]
enabled_plugins: [] # optional allow-list
allow_unsigned: false # keep false in company mode
Enterprise SSO + personas:
identity:
sso_enabled: true
auth_mode: hybrid # email_only|hybrid|sso_required
provider: workos # local|workos (desktop control-plane identity adapter)
workos_organization_id: org_123
issuer_url: https://sso.company.com
client_id: rigovo-desktop
allowed_domains: [company.com]
personas:
admin: [workspace.manage, teams.manage, plugins.manage, tasks.abort, tasks.approve, audit.read]
operator: [tasks.run, tasks.approve, tasks.resume, audit.read]
viewer: [tasks.read, audit.read]
Add custom rules per agent:
teams:
engineering:
agents:
coder:
rules:
- "Use Pydantic v2 model_validator"
- "All endpoints must have OpenAPI docs"
- "Use dependency injection for services"
Human-in-the-loop approvals:
approval:
after_planning: true # Review the plan before coding
before_commit: true # Approve before git commits
auto_approve:
- type: "test" # Auto-approve test tasks
max_files: 3
- type: "docs" # Auto-approve docs tasks
Custom OpenAI-compatible provider:
providers:
my_local:
base_url: "http://localhost:11434/v1"
api_key_env: "OLLAMA_API_KEY"
input_price: 0.0
output_price: 0.0
Environment Variables
# .env (auto-generated by rigovo init — gitignored)
ANTHROPIC_API_KEY=sk-ant-... # Required for Claude models
# OPENAI_API_KEY=sk-... # Alternative: GPT models
# GOOGLE_API_KEY=... # Alternative: Gemini models
# DEEPSEEK_API_KEY=... # Alternative: DeepSeek models
# GROQ_API_KEY=... # Alternative: Groq models
# MISTRAL_API_KEY=... # Alternative: Mistral models
# RIGOVO_API_KEY=... # Optional: cloud sync
Rigour CLI Auto-Install
The Rigour quality gate CLI auto-installs on first use — no manual setup required.
flowchart LR
START[Quality gate needed] --> CHECK1{rigour in PATH?}
CHECK1 -->|yes| USE[Use system binary]
CHECK1 -->|no| CHECK2{~/.rigovo/bin/rigour<br/>cached?}
CHECK2 -->|yes| USE2[Use cached binary]
CHECK2 -->|no| INSTALL[Background install<br/>npm install -g @rigour-labs/cli]
INSTALL --> USE3[Use installed binary]
INSTALL -->|failed| NPX[Fallback: npx -y @rigour-labs/cli]
NPX -->|failed| BUILTIN[Fallback: built-in AST checks]
The install runs in background alongside the planner agent — by the time quality gates need the CLI, it's already ready. Eliminates the 30-60s first-run latency entirely.
CI/CD
GitHub Actions with PyPI Trusted Publishing (OIDC). CI runs tests + lint + Rigour gates. Versioning via python-semantic-release with Conventional Commits.
Development
git clone https://github.com/rigovo/rigovo-virtual-team.git && cd rigovo-virtual-team
pip install -e ".[dev]"
pytest # 353 tests
npx @rigour-labs/cli check # Rigour gates
Requires Python 3.10+, Node.js 18+ (for Rigour CLI), and an API key for at least one LLM provider.
License
MIT — Rigovo
Built by Ashutosh Singh — author of Rigour.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rigovo-1.0.0.tar.gz.
File metadata
- Download URL: rigovo-1.0.0.tar.gz
- Upload date:
- Size: 218.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9173bcd402d2741cd1c68b30a576a171fd79db7305d1f70607c4a92c3eaf311f
|
|
| MD5 |
ded599c2296f8f04af56c9316abc3e64
|
|
| BLAKE2b-256 |
fcae3305182760520cafb9076cc3f2e274b517b855c5c1c2ad48e7c273d8bb5b
|
Provenance
The following attestation bundles were made for rigovo-1.0.0.tar.gz:
Publisher:
publish.yml on rigovo/rigovo-virtual-team
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rigovo-1.0.0.tar.gz -
Subject digest:
9173bcd402d2741cd1c68b30a576a171fd79db7305d1f70607c4a92c3eaf311f - Sigstore transparency entry: 1003666067
- Sigstore integration time:
-
Permalink:
rigovo/rigovo-virtual-team@a76680c5f8921632fd3930961569bbc547ec5ef2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/rigovo
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a76680c5f8921632fd3930961569bbc547ec5ef2 -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file rigovo-1.0.0-py3-none-any.whl.
File metadata
- Download URL: rigovo-1.0.0-py3-none-any.whl
- Upload date:
- Size: 257.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2306263acd30390740fa297b3a8d420a53fba9882cc8c9f365ede8a30960dfc0
|
|
| MD5 |
9591699183abacb6bf730682046e1454
|
|
| BLAKE2b-256 |
5ae843137116ab93b60798e7bb45ff6c05c5ef439e616c95a5b9596ac1bd49d7
|
Provenance
The following attestation bundles were made for rigovo-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on rigovo/rigovo-virtual-team
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rigovo-1.0.0-py3-none-any.whl -
Subject digest:
2306263acd30390740fa297b3a8d420a53fba9882cc8c9f365ede8a30960dfc0 - Sigstore transparency entry: 1003666070
- Sigstore integration time:
-
Permalink:
rigovo/rigovo-virtual-team@a76680c5f8921632fd3930961569bbc547ec5ef2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/rigovo
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a76680c5f8921632fd3930961569bbc547ec5ef2 -
Trigger Event:
workflow_run
-
Statement type: