fischer-agentkit/AGENTS.md

11 KiB

Fischer AgentKit — Project Context

Rules

  • Python >= 3.11, type hints required, pydantic>=2.0 for all data models
  • Ruff for lint + format: ruff check src/ && ruff format src/ (target py311, line-length 100)
  • Tests: pytest (asyncio_mode=auto), markers: integration, redis, postgres
  • Never use any type — use proper Pydantic models or Unknown
  • API key comparison must use hmac.compare_digest (constant-time)
  • Expert names validated with _EXPERT_NAME_RE = re.compile(r"^[a-zA-Z0-9_-]{1,64}$")
  • HandoffTransport queues bounded (maxsize=1024), close uses sentinel pattern
  • Frontend: Vue 3 + TypeScript + Ant Design Vue, Pinia stores, no require() calls
  • Async generator safety: Never use early return before the first yield in async def — use return; yield pattern instead (see .trae/rules/project_rules.md)

Tech Stack

  • Backend: Python 3.11+, FastAPI, Uvicorn, Pydantic v2, SQLAlchemy 2 (async)
  • Frontend: Vue 3, TypeScript, Vite 5, Ant Design Vue 4, Pinia, Vue Router 4
  • Desktop: Tauri 2.x (Rust shell + Python sidecar)
  • Infra: Redis (bus/cache/state), PostgreSQL + pgvector (episodic memory)
  • CLI: Typer + Rich
  • Exact versions: see pyproject.toml (Python), package.json (Node)

Commands

# Backend
pip install -e ".[dev]"                # Install with dev deps
agentkit gui --port 8002               # Web GUI (frontend + API)
agentkit serve --port 8001             # API-only server
agentkit chat                          # CLI interactive chat
agentkit init                          # Generate agentkit.yaml
agentkit version / doctor / usage      # Utility commands
agentkit task submit/status/list/cancel # Task management
agentkit skill list/load/info          # Skill management
agentkit pair --name X                 # Generate API key for external system
pytest                                 # Run all tests
pytest -m "not integration"            # Unit tests only
ruff check src/ && ruff format src/    # Lint + format

# Frontend
cd src/agentkit/server/frontend
npm install                            # Install deps
npm run dev                            # Vite dev server (proxy /api -> :8000)
npm run build:frontend                 # Production build -> ../static
npm run typecheck                      # TypeScript check

# Desktop
cd src/agentkit/server/frontend
npm run tauri dev                      # Tauri dev mode
npm run tauri build                    # Tauri production build

# Docker
docker-compose up -d                   # AgentKit + Redis + PostgreSQL

Architecture

Request Flow

User Input
  ├─ @board prefix -> BoardRouter (experts/board_router.py) -> BoardOrchestrator (multi-round discussion)
  ├─ @team prefix  -> ExpertTeamRouter (experts/router.py) -> TeamOrchestrator (pipeline collaboration)
  └─ otherwise     -> RequestPreprocessor (chat/request_preprocessor.py)
       Layer 0: @skill:xxx prefix -> explicit skill selection (SKILL_REACT or skill's configured mode)
       Layer 1: Trivial-input regex (~0ms, 0 tokens) -> DIRECT_CHAT
                (greetings, identity, factual Q&A, math, translation; guarded by _TOOL_CONTEXT_RE)
       Default: -> REACT (LLM decides tool usage autonomously in the agent loop)
  -> ExecutionMode: DIRECT_CHAT / REACT / SKILL_REACT / REWOO / REFLEXION / PLAN_EXEC / TEAM_COLLAB
     (chat handler currently supports DIRECT_CHAT, REACT, SKILL_REACT; others raise "not yet supported")

Note: The old 3-layer CostAwareRouter (with RegexRules / HeuristicClassifier / SemanticRouter / Vickrey Auction) has been replaced by RequestPreprocessor. The IntentRouter (router/intent.py) exists but is not wired into the chat flow. AuctionHouse with Vickrey auction lives in marketplace/auction.py (marketplace subsystem, not routing).

Agent Hierarchy

BaseAgent (core/base.py) — abstract, execute() is final
  +-- ConfigDrivenAgent (core/config_driven.py) — YAML-driven, 3 task modes
  +-- ReActEngine (core/react.py) — Think->Act->Observe
  +-- ReflexionAgent (core/reflexion.py) — reflection-driven
  +-- ReWOOAgent (core/rewoo.py) — plan-without-observation
  +-- StandaloneAgent (core/standalone.py) — standalone runner

Expert Team Mode (Pipeline)

ExpertConfig (extends AgentConfig) -> Expert (wraps ConfigDrivenAgent via AgentPool)
ExpertTeam: manages experts, shared workspace, team status (FORMING→PLANNING→EXECUTING→SYNTHESIZING→COMPLETED)
TeamOrchestrator: pipeline execution — Lead decomposes task into PlanPhase with depends_on, topological sort, parallel layers
PlanPhase: id, name, assigned_expert, task_description, depends_on, status (PENDING/RUNNING/COMPLETED/FAILED)
TeamPlan: phases with dependencies, topological_sort() returns execution layers (Kahn's algorithm)
ExpertTeamRouter: @team prefix routing, @team:dev_team template expansion, name validation, MAX_EXPERTS=10
HandoffTransport: InProcess (asyncio.Queue) + Redis Pub/Sub — used for event broadcasting only

Pipeline Flow:

  1. @team prefix triggers team mode (or @team:dev_team for template, @team:expert1,expert2 for explicit)
  2. ExpertTeam.create_team() sets status to PLANNING
  3. Lead Expert decomposes task into phases via LLM (fallback to single phase on failure)
  4. topological_sort() arranges phases into layers (same-layer parallel, inter-layer serial)
  5. Each phase creates an isolated ConfigDrivenAgent via AgentPool.create_agent (context isolation, KTD3)
  6. Phase outputs passed via SharedWorkspace ({plan_id}/phase/{phase_id}/output)
  7. Lead synthesizes results (BEST strategy)
  8. On all-phases-fail: fallback to single agent mode

Event Sequence: team_formedplan_updatephase_startedexpert_stepexpert_resultphase_completedteam_synthesisteam_dissolved

Team Templates: configs/experts/dev_team.yaml stores member list in bound_skills field (tech_lead, frontend_engineer, backend_engineer, qa_engineer, code_reviewer)

Lifecycle: FORMING -> PLANNING -> EXECUTING -> SYNTHESIZING -> COMPLETED -> DISSOLVED On failure: fallback to single-agent mode (lead or first active expert).

Module Map

Layer Modules Purpose
API server/, cli/ FastAPI routes + Typer CLI
Auth server/auth/ JWT + RBAC + terminal security (6-layer whitelist)
Service core/, chat/, skills/, experts/ Agent engine, routing, skills, expert teams
Data memory/, session/, bus/ Persistence, sessions, messaging
Utility llm/, tools/, evolution/, quality/, mcp/ LLM gateway, tools, self-evolution, quality, MCP
Client client/ ConfigSync, RemoteLLMProvider integration

Key Subsystems

  • LLM Gateway (llm/): 6 providers (OpenAI/Anthropic/Gemini/Doubao/Wenxin/Yuanbao), fallback, semantic cache, usage tracking, RemoteLLMProvider (client→server proxy with 401 refresh retry)
  • Memory (memory/): 4-layer (SOUL/USER/MEMORY/DAILY), WorkingMemory (Redis), EpisodicMemory (PG+pgvector), SemanticMemory (HTTP RAG)
  • Evolution (evolution/): Reflector, PromptOptimizer (genetic), PitfallDetector, ABTester
  • Tools (tools/): 21 built-in + MCP extension, composition (SequentialChain/ParallelFanOut/DynamicSelector)
  • Pipeline (orchestrator/): PipelineEngine, SagaOrchestrator, DynamicPipeline, HandoffManager
  • Bus (bus/): MemoryBus (in-process), RedisBus (distributed)
  • Auth (server/auth/): JWT (access 15min + refresh 7d, HS256), API Key (constant-time compare), 3-level RBAC (member/operator/admin + permission bits), 6-layer terminal security (blocklist→shell-ops→builtin→global→user→session→danger), bcrypt password hashing (rounds=12)

Server Routes (22 modules)

Prefix Module Purpose
/api/v1/agents agents.py Agent CRUD
/api/v1/tasks tasks.py Task submit/query/cancel
/api/v1/skills skills.py Skill register/list
/api/v1/chat chat.py Chat REST + WebSocket
/api/v1/ws ws.py WebSocket channel
/api/v1/llm llm.py LLM usage
/api/v1/llm/chat llm_gateway.py LLM gateway proxy (JWT auth, SSE streaming)
/api/v1/health health.py Health check
/api/v1/metrics metrics.py Metrics
/api/v1/evolution evolution.py + evolution_dashboard.py Self-evolution API
/api/v1/memory memory.py Memory management
/api/v1/portal portal.py Portal
/api/v1/kb kb_management.py Knowledge base
/api/v1/skill-mgmt skill_management.py Skill management
/api/v1/workflows workflows.py Workflows
/api/v1/terminal terminal.py Local terminal (client sidecar PTY)
/api/v1/terminal/server terminal_server.py Server terminal (server PTY + admin approval)
/api/v1/terminal terminal_whitelist.py Whitelist/blocklist/audit-log management
/api/v1/settings settings.py Settings
/api/v1/auth auth.py Login/refresh/logout/me
/api/v1/system system.py System resources (SYSTEM_CONFIG permission)
/api/v1/config config_sync.py Config version + sync (polling)

WebSocket Chat Protocol

Client -> Server: message, reply, confirmation_reply, cancel, ping Server -> Client: connected, token, thinking, step, final_answer, skill_match, confirmation_request, confirmation_result, ask_human, error, pong Expert Team events: team_formed, expert_step, expert_result, plan_update, phase_started, phase_completed, phase_failed, team_synthesis, team_dissolved

Frontend Pages

  • /agent/chat — Chat with Expert Team view
  • /agent/code — Code/workflow
  • /agent/monitor — Evolution dashboard
  • /computer-use — Desktop control
  • /login — Login page (JWT auth)
  • Terminal panel — Local + server terminal with whitelist manager

Configuration Priority

CLI args > agentkit.yaml > env vars (${VAR:-default}) > .env > hardcoded defaults

Config search: --config path > ./agentkit.yaml > ~/.agentkit/agentkit.yaml

Conventions

  • Skill configs: configs/skills/*.yaml (15 presets)
  • LLM configs: agentkit.yaml llm section (unified with server config)
  • Pipeline configs: configs/pipelines/*.yaml
  • Expert templates: configs/experts/*.yaml (5 programming experts + dev_team team template), registered via ExpertTemplateRegistry
  • Team templates: bound_skills field stores member list (e.g., dev_team.yaml lists tech_lead, frontend_engineer, backend_engineer, qa_engineer, code_reviewer)
  • All Pydantic models use model_config = ConfigDict(...) not class Config
  • Test files: tests/unit/ and tests/integration/
  • Frontend stores: Pinia, one per domain (chat, team, settings)
  • Frontend components: src/agentkit/server/frontend/src/components/

Boundaries

  • Never modify pyproject.toml version without explicit request
  • Never push to main directly — use feature branches
  • Integration tests require Docker (Redis + PostgreSQL)
  • Desktop builds require Rust toolchain + PyInstaller