# Agentic Team Documentation ## Table of Contents - [Overview](#overview) - [Why It Exists](#why-it-exists) - [Separation from Orchestrator](#separation-from-orchestrator) - [Core Concepts](#core-concepts) - [Role Model](#role-model) - [Execution Lifecycle](#execution-lifecycle) - [Communication Protocol](#communication-protocol) - [Communication Examples](#communication-examples) - [Configuration Model](#configuration-model) - [UI: Agentic Team Studio](#ui-agentic-team-studio) - [CLI: Agentic Team REPL](#cli-agentic-team-repl) - [Local Model Integration and Limits](#local-model-integration-and-limits) - [Validation and Failure Handling](#validation-and-failure-handling) - [Observability](#observability) - [Security and Safety](#security-and-safety) - [Extension Guide](#extension-guide) - [Operational Commands](#operational-commands) - [Package Structure](#package-structure) - [MCP Integration (Optional)](#mcp-integration-optional) - [Context System](#context-system) - [Obsidian Vault Export](#obsidian-vault-export) ## Overview `AGENTIC_TEAM` is a standalone runtime for true role-based multi-agent collaboration. It is not a workflow preset inside the orchestrator. The runtime simulates an autonomous software team where roles communicate by passing scoped messages and subtasks. The default team includes: - `project_manager` (team lead and final gatekeeper) - `software_architect` - `software_developer` - `qa_engineer` - `devops_engineer` Each role is mapped to any enabled model adapter from `orchestrator/config/agents.yaml` and is intentionally model-agnostic. ```mermaid flowchart LR U[User Task] --> PM[Project Manager] PM --> A[Software Architect] PM --> D[Software Developer] PM --> Q[QA Engineer] PM --> O[DevOps Engineer] A --> D D --> Q Q --> PM O --> PM D --> O PM --> R[Final Response to User] ```

Agentic Team Architecture

## Why It Exists The orchestrator is optimized for predefined workflow execution. `AGENTIC_TEAM` is optimized for open-ended inter-role delegation where: - routing is chosen by the AI role at runtime, - inter-role communication is first-class, - the team lead controls finalization, - all role-to-model bindings are configurable. ## Separation from Orchestrator The project keeps strict boundary lines between both systems. ```mermaid flowchart TB subgraph Orchestrator System OCLI[ai-orchestrator run/shell] OCore[orchestrator.core.Orchestrator] OWF[Workflow Engine] end subgraph Agentic Team System AUI[agentic_team/ui/app.py] ACore[agentic_team.engine.AgenticTeamEngine] AShell[ai-orchestrator agentic-shell] end OCLI --> OCore --> OWF AUI --> ACore AShell --> ACore ``` Separation guarantees: - No agentic-team logic embedded into orchestrator workflow execution. - No orchestrator workflow dependency for agentic team turns. - Independent UI backend (`agentic_team/ui/app.py`) and independent CLI REPL (`agentic-shell`). ## Core Concepts 1. `Role`: domain responsibility (PM, architect, developer, QA, DevOps). 2. `Agent`: concrete model adapter backing a role (`claude`, `codex`, `gemini`, `copilot`, local adapters). 3. `Turn`: one role receives a message, reasons, and emits one decision. 4. `Decision`: either: - `message` (handoff to another role) - `finalize` (lead role only; emits user response) 5. `Team Transcript`: ordered list of role-to-role turns. ```mermaid stateDiagram-v2 [*] --> ReceiveMessage ReceiveMessage --> BuildPrompt BuildPrompt --> ExecuteRoleAgent ExecuteRoleAgent --> ParseDecision ParseDecision --> RouteMessage: action=message ParseDecision --> Finalize: action=finalize and role=lead ParseDecision --> RouteMessage: invalid finalize/non-lead RouteMessage --> ReceiveMessage Finalize --> [*] ``` ## Role Model The team is configurable but defaults are generated if mappings are absent. ```mermaid graph TD PM[project_manager\nLead + Gatekeeper] SA[software_architect\nSystem design] SD[software_developer\nImplementation] QA[qa_engineer\nValidation + regressions] DO[devops_engineer\nRuntime/deployability] PM --> SA PM --> SD PM --> QA PM --> DO SA --> SD SD --> QA QA --> PM SD --> DO DO --> PM ``` Role responsibilities matrix: | Role | Main Responsibility | Typical Outgoing Messages | |------|----------------------|---------------------------| | `project_manager` | Initiation, prioritization, acceptance | Architecting, implementation, verification, finalization | | `software_architect` | Design constraints, interfaces, decomposition | Implementation guidance to developer/PM | | `software_developer` | Code generation and code changes | Validation request to QA, deployability request to DevOps | | `qa_engineer` | Test strategy, defects, regressions | Bug report back to developer/PM, release signal to PM | | `devops_engineer` | Runtime, environment, deployment concerns | Operability feedback to PM/developer | ## Execution Lifecycle A task starts at `lead_role` and loops until finalization or max turns. ```mermaid sequenceDiagram participant U as User participant PM as Project Manager participant R as Any Team Role participant E as AgenticTeamEngine U->>E: execute_task(task) E->>PM: turn 1 prompt PM-->>E: decision (message/finalize) loop until finalize or max_turns E->>R: routed prompt with transcript R-->>E: decision JSON E->>E: validate route/action end E-->>U: final_output (or max-turn fallback output) ``` Turn payload (normalized): ```yaml turn: 3 action: message from_role: software_developer to_role: qa_engineer from_agent: codex to_agent: gemini message: "Implementation complete. Validate edge cases and regressions." communication_type: inter_role success: true ``` ## Communication Protocol Each role receives: - original user task, - roster and role bindings, - recent transcript window, - incoming message from previous role. Each role returns strict JSON: ```json { "action": "message | finalize", "to_role": "", "message": "", "final_response": "" } ``` Route semantics: ```mermaid flowchart TD D[Role Decision] --> A{Action} A -->|message| B[Validate to_role] A -->|finalize| C{Current role == lead_role?} B -->|valid| E[Emit team_turn] B -->|invalid| F[Force route to lead_role] C -->|yes| G[Finalize for user] C -->|no| H[Convert to message -> lead_role] F --> E H --> E ``` ## Communication Examples The examples below mirror what the runtime emits through `team_turn`, `team_communication`, and logs. ### Example A: Normal Implementation Handoff ```mermaid sequenceDiagram participant PM as project_manager (claude) participant DEV as software_developer (codex) participant QA as qa_engineer (gemini) participant USER as user PM->>DEV: action=message, "Implement endpoint + tests" DEV->>QA: action=message, "Implementation complete, validate" QA->>PM: action=message, "Validation passed" PM->>USER: action=finalize, "Ready to ship" ``` Example per-turn payloads: ```json { "turn": 1, "action": "message", "from_role": "project_manager", "to_role": "software_developer", "from_agent": "claude", "to_agent": "codex", "message": "Implement endpoint + tests", "communication_type": "inter_role", "success": true } ``` ```json { "turn": 4, "action": "finalize", "from_role": "project_manager", "to_role": "user", "from_agent": "claude", "to_agent": "user", "message": "Validation complete and approved", "success": true } ``` ### Example B: Invalid Non-Lead Finalize Is Auto-Corrected If a non-lead role tries to finalize, runtime rewrites it to a lead-directed message. Input decision from developer: ```json { "action": "finalize", "final_response": "Done" } ``` Normalized routing outcome: ```json { "action": "message", "to_role": "project_manager", "message": "Done" } ``` ### Example C: UI Live Communication Event Socket event emitted to UI: ```json { "event": "team_communication", "timestamp": "2026-02-27T19:45:21.531Z", "turn": 2, "action": "message", "from_role": "software_developer", "to_role": "qa_engineer", "from_agent": "codex", "to_agent": "gemini", "message": "Please validate edge cases and regressions.", "success": true } ``` How graph edges aggregate in UI: ```text project_manager -> software_developer : 1x software_developer -> qa_engineer : 2x qa_engineer -> project_manager : 1x project_manager -> user : finalize ``` ### Example D: Repetition Escalation Safety When the same route+message pattern repeats over the configured threshold, the engine escalates to lead: ```json { "action": "message", "from_role": "software_developer", "to_role": "project_manager", "message": "Still implementing.\n\n[System] Repetition detected in team routing. Escalating to lead for decision." } ``` ## Configuration Model `AGENTIC_TEAM` lives under `agentic_team` in `orchestrator/config/agents.yaml`. ```yaml agentic_team: lead_role: "project_manager" max_turns: 12 roles: project_manager: title: "Project Manager (Team Lead)" agent: "claude" responsibilities: "Initiate work, route subtasks, and perform final approval." software_architect: title: "Software Architect" agent: "gemini" responsibilities: "Define architecture and technical design." software_developer: title: "Software Developer" agent: "codex" responsibilities: "Implement and update source code." qa_engineer: title: "QA Engineer" agent: "gemini" responsibilities: "Validate behavior and identify regressions." devops_engineer: title: "DevOps Engineer" agent: "claude" responsibilities: "Handle deployment, runtime, and operational concerns." ``` Config behavior: - Missing `agentic_team` section: defaults are generated. - Missing role mappings: defaults are merged. - Invalid mappings (role -> unavailable agent): execution is blocked until corrected. ```mermaid flowchart LR C[Load YAML] --> D[Merge Defaults] D --> V[Validate Roles + Lead] V --> A{Mapped agents available?} A -->|Yes| R[Execution allowed] A -->|No| B[Return validation error + missing mappings] ``` ## UI: Agentic Team Studio The standalone UI is served by `agentic_team/ui/app.py`. Key capabilities: - Live communication timeline - Live communication graph with directed edges - Guided config editor (form-based, no YAML editor) - Runtime logs for each routed handoff - Conversation memory with follow-up mode ```mermaid sequenceDiagram participant Browser participant API as Agentic UI Backend participant Engine as AgenticTeamEngine Browser->>API: POST /api/execute API->>Engine: execute_task(..., turn_callback) loop per turn Engine-->>API: step payload API-->>Browser: socket team_turn API-->>Browser: socket team_communication API-->>Browser: socket progress_log end Engine-->>API: final result API-->>Browser: socket task_completed ``` Live graph rendering model: ```mermaid classDiagram class TeamTurn { +int turn +string from_role +string to_role +string from_agent +string to_agent +string action +string message } class CommunicationEdge { +string from_role +string to_role +int count +bool latest +bool selected } TeamTurn --> CommunicationEdge : aggregates into ``` ## CLI: Agentic Team REPL Standalone CLI command: ```bash ./ai-orchestrator agentic-shell ``` This REPL is independent from orchestrator workflow shell. Supported commands: - `/help` - `/agents` - `/team` - `/maxturns ` - `/followup ` - `/history` - `/save [file]` - `/load ` - `/reset` - `/reload` - `/validate` - `/clear` - `/info` - `/exit` ```mermaid flowchart TD S[Start agentic-shell] --> I[Load team config + adapters] I --> P[Prompt user task] P --> E[Execute team turns] E --> D[Display communication table + final output] D --> Q{Another input?} Q -->|Yes| P Q -->|No| X[Exit] ``` ## Local Model Integration and Limits Agentic Team can map any role to local adapters (`ollama`, `llamacpp`, `localai`, `openai-compatible`) and those roles fully participate in turn routing, offline mode, and fallback. Implementation behavior: | Adapter type | Runtime transport | Direct file writes | |---|---|---| | CLI-backed agents | Local CLI execution path | Yes (tool-dependent) | | Local model adapters | HTTP completion endpoints | No (text output only) | Practical impact: - A role mapped to a local model can still act as architect/developer/QA in team conversation, but it returns guidance/drafts as text. - Local-model turns do not directly modify repository files by themselves. Best use: - offline role communication, - generating implementation drafts for another agent to apply, - review/critique and fallback continuity. > [!IMPORTANT] > While it is possible to make local LLMs directly edit files (e.g., via a `file-editor` tool), this approach is currently disabled to prevent unintended destructive changes. Local adapters are advisory — they provide text output that the Orchestrator can use to inform the next steps, but they do not have direct write access to the workspace. This design choice prioritizes safety and predictability while still leveraging local models for their strengths in drafting and feedback. The hard part is not feasibility, it’s safety and reliability: permissions, diff constraints, validation/tests before write, rollback, and preventing bad edits. ## Validation and Failure Handling Pre-run checks: - Task must be non-empty. - At least one available agent must exist. - Every configured role must map to an available agent. - Lead role must exist in role map. Runtime protections: - Non-lead `finalize` is rewritten to `message -> lead_role`. - Invalid `to_role` is rerouted to `lead_role`. - Role execution failures route a failure message back to lead. - If no finalize by `max_turns`, engine returns a bounded fallback result. ```mermaid flowchart TD START[Run request] --> C1{Any available agents?} C1 -->|No| E1[Reject run] C1 -->|Yes| C2{Role mappings valid?} C2 -->|No| E2[Reject run with missing mappings] C2 -->|Yes| LOOP[Turn loop] LOOP --> D{Decision valid?} D -->|No| FIX[Normalize decision] D -->|Yes| NEXT[Next turn or finalize] FIX --> NEXT NEXT --> END{Finalized by lead?} END -->|Yes| OUT[Return final output] END -->|No and max turns reached| FOUT[Return max-turn fallback output] ``` Fallback behavior leverages existing adapter fallback mappings where configured. ```mermaid sequenceDiagram participant Role as Current Role participant FB as Fallback Manager participant P as Primary Agent participant F as Fallback Agent Role->>FB: execute_with_fallback(primary) FB->>P: execute alt recoverable failure FB->>F: execute fallback F-->>FB: response else success P-->>FB: response end FB-->>Role: agent_used + response ``` ## Observability Agentic team telemetry is surfaced through: - `team_turn` socket events - `team_communication` socket events - `progress_log` socket events - `/api/status` session snapshots Session state stores: - current status, - turn history, - logs, - conversation history, - last task/output for follow-up. ```mermaid flowchart LR T[turn_callback] --> E1[team_turn] T --> E2[team_communication] T --> E3[progress_log] E1 --> UI[Timeline + status] E2 --> G[Live communication graph] E3 --> L[Runtime logs panel] ``` ## Code Quality | Metric | Value | |--------|-------| | **Pylint Score** | 10.00/10 (zero warnings) | | **Tests** | 386 passing (pytest) | | **Pre-commit Hooks** | 15 hooks passing (Black, isort, flake8, pylint, MyPy, etc.) | | **Formatting** | Black (120-char line length) | | **Logging** | Lazy `%s` formatting throughout; no stray `print()` in production code | | **I/O** | Explicit UTF-8 encoding on all file operations | ## Security and Safety - Config updates validate required top-level sections before write. - Invalid role mappings are blocked before execution. - Session data is isolated per client id. - UI renders communication text escaped in HTML. ## Extension Guide To add a new role: 1. Add role mapping in `orchestrator/config/agents.yaml` under `agentic_team.roles`. 2. Bind the role to any available agent. 3. Set role title and responsibilities. 4. Optionally set role-specific fallback via existing fallback mapping. To add a new model for existing roles: 1. Add agent in `agents` section with correct adapter type. 2. Ensure `enabled: true` and runtime availability. 3. Rebind role `agent` value in `agentic_team.roles`. ```mermaid flowchart TB A[Add or enable agent in agents] --> B[Reload config] B --> C[Team validation] C --> D{Valid mapping?} D -->|Yes| E[Run team] D -->|No| F[Fix role bindings in config form] ``` ## Operational Commands Start standalone Agentic Team UI backend: ```bash python agentic_team/ui/app.py ``` Start standalone Agentic Team UI helper script: ```bash ./start-agentic-ui.sh ``` Start standalone Agentic Team CLI: ```bash ./ai-orchestrator agentic-shell ./ai-orchestrator agentic-shell --max-turns 16 ./ai-orchestrator agentic-shell --offline ``` Validate base config and agents: ```bash ./ai-orchestrator validate ./ai-orchestrator agents ``` ## Package Structure The full `agentic_team/` package layout and its relationship to the shared MCP server: ```mermaid graph TD subgraph "agentic_team/" INIT[__init__.py] ENGINE[engine.py\nAgenticTeamEngine] DPARSER[decision_parser.py] CFGUTIL[config_utils.py] CONSTANTS[constants.py] FALLBACK[fallback.py] OFFLINE[offline.py] SHELL[shell.py\nAgentic REPL] MCPCLI[mcp_client.py] subgraph "adapters/" ABASE[base.py] ACLAUDE[claude_adapter.py] ACODEX[codex_adapter.py] AGEMINI[gemini_adapter.py] ACOPILOT[copilot_adapter.py] AOLLAMA[ollama_adapter.py] ALLAMA[llama_cpp_adapter.py] ACLI[cli_communicator.py] end subgraph "context/" CTX_MM[memory_manager.py] CTX_STORE[store/graph_store.py] CTX_MODELS[models/schemas.py] CTX_SEARCH[search/ BM25 + FTS5] CTX_OPS[ops/ analytics, export,\npruning, project_scanner] end subgraph "config/" AYAML[agents.yaml] end subgraph "ui/" UIAPP[app.py\nFlask + SocketIO :5002] end end ENGINE --> CTX_MM ENGINE --> ABASE ENGINE --> DPARSER ENGINE --> CFGUTIL ENGINE --> FALLBACK ENGINE --> OFFLINE SHELL --> ENGINE UIAPP --> ENGINE MCPCLI --> ENGINE ``` --- ## MCP Integration (Optional) > **Note:** The MCP server at `mcp_server/` is an optional integration layer. It is not required to use the agentic team. The team runs independently via its own CLI (`agentic-shell`) and UI (`agentic_team/ui/app.py`). The agentic team is accessible via MCP through the shared FastMCP server: ```mermaid sequenceDiagram participant Client as MCP Client participant Server as MCP Server participant Engine as AgenticTeamEngine participant PM as Project Manager participant Dev as Developer Client->>Server: call_tool("agentic_team_execute", {task, max_turns}) Server->>Engine: execute_task(task, max_turns) Engine->>PM: Build prompt -> execute PM->>Dev: {action: "message", to_role: "developer"} Dev->>PM: {action: "message", to_role: "project_manager"} PM->>Engine: {action: "finalize", final_response: "..."} Engine-->>Server: Result dict Server-->>Client: JSON response ``` ### Agentic Team MCP Tools | Tool | Read-Only | Description | |------|-----------|-------------| | `agentic_team_execute` | No | Run task with role-based team collaboration | | `agentic_team_list_agents` | Yes | List available agents | | `agentic_team_config` | Yes | Get team role configuration | | `agentic_team_validate` | Yes | Validate role-to-agent bindings | | `agentic_team_health` | Yes | Health check: team validity, agents, offline status | ### Python Client ```python from agentic_team.mcp_client import AgenticTeamMCPClient client = AgenticTeamMCPClient() # in-memory result = await client.execute_task("Design a microservice architecture") ``` ## Context System The Agentic Team maintains its own independent graph-based context database at `~/.agentic-team/context.db`. This is fully separate from the Orchestrator's context system — zero shared imports. ### Node Types | Type | Purpose | |------|---------| | `CONVERSATION` | Past chat sessions with message history | | `TASK` | Completed tasks with outcomes and duration | | `MISTAKE` | Errors with corrections and prevention strategies | | `PATTERN` | Reusable code patterns and best practices | | `DECISION` | Architectural decisions with rationale | | `CODE_SNIPPET` | Useful code fragments | | `PREFERENCE` | Learned user preferences | | `FILE` | Source file metadata from project scans | | `PROJECT` | Registered project roots with detected tech stack | ### Project-Scoped Operation When `PROJECT_PATH` is configured, the engine automatically registers the project at startup: ```mermaid sequenceDiagram participant User participant Engine as AgenticTeamEngine participant Scanner as ProjectScanner participant Graph as GraphStore User->>Engine: Set PROJECT_PATH Engine->>Scanner: scan(project_path) Scanner->>Graph: Add PROJECT node Scanner->>Graph: Add FILE nodes Scanner->>Graph: Add PATTERN nodes Scanner->>Graph: Add edges Note over Engine,Graph: All nodes tagged with project_id User->>Engine: execute_task(task) Engine->>Graph: Query project context Graph-->>Engine: Relevant patterns, decisions, files Engine->>Engine: Include context in prompts ``` ### Search The Agentic Team context uses FTS5 (SQLite built-in) and BM25 for search — no external embedding dependency required. This keeps the system lightweight and fully self-contained. ### Independence Guarantee The Agentic Team context system (`agentic_team/context/`) is a fully independent implementation: - Own `models/schemas.py` — mirrored but independent from orchestrator schemas - Own `store/graph_store.py` — independent SQLite graph store - Own `ops/project_scanner.py` — independent copy of the project scanner - **Zero imports from `orchestrator/`** — verified by CI ### Obsidian Vault Export Export the Agentic Team's communication and context graph as an [Obsidian](https://obsidian.md) vault. Each node becomes a markdown note with YAML frontmatter, typed folder organization, and `[[wikilinks]]` connecting related nodes. ```python from agentic_team.context.ops.export import ContextExporter from agentic_team.context.graph_store import GraphStore store = GraphStore("~/.agentic-team/context.db") exporter = ContextExporter(store) # Export full context graph result = exporter.export_obsidian("./team-vault") # → { notes_written: 89, edges_linked: 214, folders: [...] } # Export only tasks and decisions result = exporter.export_obsidian("./vault", node_types=["task", "decision"]) ``` Open the generated vault in Obsidian and press **Ctrl/Cmd + G** to explore team interactions, role handoffs, and decisions as a visual graph. ```mermaid graph LR subgraph "Agentic Team Context → Obsidian" DB[(context.db)] --> EXP[ContextExporter] EXP --> VAULT[Obsidian Vault] VAULT --> IDX[_Index.md
Map of Content] VAULT --> TASKS[Tasks/] VAULT --> DECS[Decisions/] VAULT --> PATS[Patterns/] VAULT --> MIST[Mistakes/] VAULT --> AGENTS[Agent Outputs/] VAULT --> OBS[.obsidian/
graph.json] end style VAULT fill:#7C3AED,color:#fff style OBS fill:#4FC3F7,color:#000 style IDX fill:#FFC107,color:#000 ``` **Vault features:** - **Typed folders** — Tasks/, Decisions/, Patterns/, Mistakes/, Conversations/, Agent Outputs/, etc. - **YAML frontmatter** — type, tags, importance score, timestamps, project_id, metadata - **`[[Wikilinks]]`** — Relationships grouped by edge type with → outgoing and ← incoming sections - **`_Index.md`** — Map of Content with stats table and links to every category - **`.obsidian/graph.json`** — Color groups per node type for the built-in graph view - **Dark theme** — `.obsidian/appearance.json` pre-configured with Obsidian dark mode > **Note:** This is a fully independent implementation from the orchestrator's Obsidian exporter — zero shared imports, consistent with the Agentic Team's independence guarantee.