Skip to content

Repository files navigation

Rooster — Autonomous Multi-Agent Desktop OS

English | 中文

CI

Version: 0.5.0 | Python >= 3.12 | License: MIT


1. Project Overview

Rooster is a multi-role Agent framework that autonomously handles complex tasks including desktop automation, web browsing, file processing, and data queries.

Core Features

  • CCP Capability-Constrained Planning: Six-step planning protocol — blocker detection, owner labeling (AGENT/USER), confidence rating, deliverable declaration, feasibility analysis, DAG construction. Planner explicitly declares capability boundaries and risk notes before execution.
  • Tool Dependency Injection (RoosterContext): Unified RoosterContext dataclass injects session, task, memory, LLM client, blackboard, and config into every tool call. Zero-breakage migration — old tools continue working unchanged.
  • Schema Validation Self-Healing (ToolCallValidator): Pydantic-based tool call validator with two auto-healing paths (JSON syntax fix + schema structure repair). Invalid parameters are automatically corrected by a lightweight router model before execution, with a hard budget of 2 retries.
  • Progressive History Compression: Per-10-step semantic distillation during ReAct execution. Preserves the latest 5 raw steps while compressing older context, eliminating the "hard truncation degradation" that plagued long-running tasks.
  • Thin routing pipeline: Router hard rules → SkillIndex hint → Strategist.decide() → MissionRunner / Schedule
  • Unified execution modes: DIRECT_REPLY / SINGLE_STEP / DAG_PLAN / SCHEDULE
  • Typed Signal Exceptions: Native Python EscalateSignal / AbortSignal replace magic string parsing for control flow, enabling precise exception catching and stack traces.
  • Structured Observability: Prometheus histograms for tool latency, subtask duration, Provider failover rate, and LLM error tracking. Automatic mission_id correlation across all log entries.
  • Visual grounding: YOLO-driven desktop UI element detection and manipulation
  • Multi-LLM failover: Zhipu / MiMo / Jiutian / OpenAI / Anthropic / Kimi / Qwen / Cloud / Local — 10+ provider auto-switching
  • Gateway security: API Key auth + HMAC signing + IP rate limiting + security headers + request size limits
  • Dashboard UI: Real-time monitoring — 13 panels, bilingual (ZH/EN), mobile-responsive

2. Technical Highlights

1. L1 Hard-Routing + Strategist Semantic Sovereignty: Every Request Takes the Optimal Path

V15 Routing Architecture: Three-layer triage — zero-LLM gate + capability index + semantic judgment:

  • L1 Hard-Rule Gate (< 5ms, pure code): Security keywords → BLOCK / Schedule keywords → SCHEDULE / Download keywords → Reframer pre-processing
  • L2 SkillIndex (~20ms, TF-IDF): Local capability index matching, outputs SkillHint for Strategist reference
  • Strategist.decide() (fast LLM): Semantic depth judgment → DIRECT_REPLY (streaming) / SINGLE_STEP (single task) / DAG_PLAN (multi-step DAG) / CLARIFY (ambiguity intercept)

Low-latency hard gate: Built-in download/schedule/security trigger dictionaries handle deterministic branching in code. Router no longer spends an LLM call on semantic triage.

Thin-router handoff: The hard gate only decides BLOCK / SCHEDULE / reframe-preprocess. Everything else continues into SkillIndex + Strategist.decide() instead of a separate Router-owned planner model.

Single semantic decision point: Semantic depth is judged exactly once by Strategist.decide(). That keeps routing thin while still preserving DIRECT_REPLY, SINGLE_STEP, DAG_PLAN, and CLARIFY.

2. Full-Spectrum Security Sandbox & Privacy Isolation: Defense-in-Depth from Ingestion to Execution

Built on a "defense-in-depth" philosophy covering the network edge, runtime environment, and LLM call layer. The guiding principle is "prefer false negatives over blocking the user" — every interception supports graceful degradation.

Data Privacy Physical Isolation Funnel

Layer Mechanism Latency
L0 Physical cutoff LOCAL_DIRS path matching → matched files/requests are force-routed to a local model (e.g. Ollama), cutting off cloud egress at the source 0ms
L1 Entity cleansing Deep-customized Microsoft Presidio — millisecond bilingual PII scan, detecting phone numbers (0.8), ID cards (0.85), bank cards (0.6), and other sensitive assets 5–20ms
Vision-level privacy circuit breaker Screenshots never leave the machine — local PaddleOCR extracts on-screen text → Presidio redaction → only a safe text description is sent to cloud; original screenshots remain local permanently per-frame

AdvancedGuard LLM Defense Engine

  • Jailbreak immunity: Three-tier regex matching matrix, blocking DAN-mode, "ignore previous instructions", unrestricted roleplay, and similar prompt injection attempts in real time.
  • Output injection interception: When the Agent uses the browser or reads external files, tool return content is scanned in real time to prevent maliciously hidden web instructions from hijacking the Agent.
  • Skill supply-chain poison detection: Third-party skill packages (SKILL.md) are statically analyzed on mount — blocks eval/base64 obfuscation, hidden malicious network requests, and system commands embedded in skill descriptions.

Runtime Sandbox & State Control

  • PathGuard directory sandbox: Strict os.path.realpath prefix validation — blocks symlink bypass and ../ directory traversal attacks.
  • StateGuard atomic lock (RSA-Synchronizer): Cross-process atomic transaction lock designed for multi-agent concurrency — eliminates race conditions and dirty-write injection.
  • Tool abuse rate limiting: Automatically interrupts infinite loop calls triggered by LLM hallucination, preventing unexpected exhaustion of compute and API quota.

Boundary Gateway & Compliance Audit

  • Full-stack traffic control: API Key auth + Webhook HMAC-SHA256 anti-tampering signature + IP sliding-window rate limiting (100 req/min).
  • Log secrets mask: API keys, tokens, and other credentials are irreversibly masked before log writes, preventing credential leakage.
  • Dynamic config immunity (Input Guard): Key allowlist validation + oversized-value circuit breaker on hot-reload endpoints, guarding against buffer-overflow style attacks.

3. UIA Matrix Scan + YOLO Visual Grounding: What You See Is What Rooster Controls

A dual-engine "system API + computer vision" architecture — no API access required from the target application. If it's on screen, Rooster can interact with it.

  • UIA (UI Automation) engine: Retrieves standardized information on all on-screen controls (type, name, position, state) via system accessibility APIs — broad coverage, deterministic, fast, precise, and stable.
  • YOLO vision engine: Ships with a 39 MB ultra-lightweight detection model bundled in the repository — zero extra download. Effectively fills UIA blind spots: custom controls, game icons, non-standard UI elements.
  • Complementary operation: desktop_grounding_scan handles full-scene element sensing; desktop_act handles precise click/input simulation. UIA ensures efficiency; YOLO ensures coverage.

4. Guardian — Self-Healing, Self-Scheduling, Self-Repairing Watchdog

An external watchdog fully independent of the main process — even a complete main process crash leaves Guardian unaffected. Designed for true unattended operation.

Three parallel monitoring threads

Thread Mechanism Trigger
Heartbeat Poll /api/health every 30s 3 consecutive failures → force-kill and restart
Resource circuit breaker Sample CPU/memory every 15s CPU > 95% or RAM > 2 GB sustained 120s → force-kill to prevent freeze
Time wheel Poll schedules.json every 60s Dispatch scheduled tasks on time via POST

Fully automatic fault recovery

  • Missing package auto-install: Catches ModuleNotFoundError, matches against a 23-entry safe library allowlist, and runs pip install. The allowlist prevents malicious package injection.
  • Port conflict resolution: Matches port-in-use errors, extracts the port number via cross-platform regex, and immediately terminates the blocking process.
  • Service wakeup: Automatically restarts aria2c and similar daemons when their RPC becomes unresponsive.

Enterprise-grade resilience: circuit breaker (2 identical consecutive errors → stop retry), restart storm guard (5 restarts in 300s → alert + stop), exponential backoff with jitter, single-instance PID mutex, Feishu/DingTalk/Slack webhook alerts.

5. Dual-Memory Self-Evolution + Auditor Quality Gate: Gets Smarter Over Time, Results Stay Reliable

Zero-latency self-evolution engine

After each conversation turn, a background scan fires instantly without blocking the current user interaction. A local model (never cloud) analyzes the last 5 turns (200 chars/turn), detects three core signal types, and writes them to the memory store:

Signal Example triggers Write target
CORRECTION "That's wrong", "You misunderstood" SOUL.md → core behavior principles
PREFERENCE "From now on", "I prefer" USER.md → user preference profile
MILESTONE "It's live", "Successfully done" USER.md → current key projects

Core identity fields (Identity / Hard Limits / Memory Protocol) are code-level protected — the evolution engine cannot modify them.

Independent Auditor quality gate

After Executor completes, an independent Auditor renders the final verdict with five outcomes:

Verdict Meaning User experience
AFFIRM Approved Receives a passing result
REMAND Quality below standard Silently re-executed, seamless to user
REPLAN Path dead end Strategist replans the task structure
CLOSURE Cannot be completed Graceful shutdown, no half-finished results
ESCALATE High-risk / permission block Proactively escalates to human intervention

Strong robustness: _robust_json_parse() auto-repairs malformed LLM output — Markdown code-block wrapping, trailing commas, Chinese quotation marks (\u201c/\u201d), etc. Auditor timeouts degrade safely to PASS_WITH_WARNING — the audit system never blocks the user flow.

6. Memory Anti-Garbage System v2 — Three-Layer Defense Keeps Long-Term Memory Clean

┌─────────────────────────────────────────────────────────────────────┐
│                  Rooster Memory Anti-Garbage v2                 │
│                                                                 │
│  User msg → Router → MissionRunner → Executor(ReAct)           │
│                        │                                        │
│                        ▼                                        │
│  ┌────────────────────────────────────────────────────┐           │
│  │  Layer 1: Source Interception (mission_runner.py)│           │
│  │                                                  │           │
│  │  On subtask completion:                          │           │
│  │    ✖ Success notification  ───── DROPPED        │           │
│  │    ✖ Output file           ───── Deferred       │           │
│  │                                                  │           │
│  │  On mission close (batch commit):                │           │
│  │    ✖ Mission complete      ───── DROPPED        │           │
│  │    ✖ Output file (dup)     ───── DROPPED        │           │
│  │    ✖ Tool call traces      ───── DROPPED        │           │
│  │    ✔ Output file path      ───── Written 1x     │           │
│  │    ✔ Execution summary     ───── Kept + filtered│           │
│  │       (len > 50 AND no template phrases)         │           │
│  │                                                  │           │
│  │  Before: 5-8 facts/task, each triggers rebuild   │           │
│  │  After:  0-2 facts/task, all trigger 1 rebuild   │           │
│  └───────────────┬──────────────────────────────────┘           │
│                 │                                               │
│                 │ batch_update_facts(_batch)                    │
│                 │ Collect all → single add_fact → single rebuild│
│                 ▼                                               │
│  ┌─────────────────────────────────────────────┐              │
│  │              LTM Storage                      │              │
│  │         project_memory.json                   │              │
│  │         Current: ~9 valid facts               │              │
│  │    (cleaned from ~50, garbage → zero)         │              │
│  └───────────────────┬────────────────────────────┘              │
│                 │                                               │
│       ┌─────────┴─────────┐                                    │
│       │                   │                                     │
│       ▼                   ▼                                     │
│  ┌──────────────┐  ┌───────────────────────┐                        │
│  │  Read Path  │  │  Distill Path     │                        │
│  │             │  │                   │                        │
│  │ Each ReAct  │  │ Three triggers:   │                        │
│  │ step calls  │  │                   │                        │
│  │ once        │  │ · Timer: every    │                        │
│  │             │  │   10 min, auto    │                        │
│  │ Semantic    │  │   scan quiet      │                        │
│  │ recall      │  │   sessions        │                        │
│  │ query=      │  │                   │                        │
│  │ current     │  │ · Passive: token  │                        │
│  │ task        │  │   > 60% capacity  │                        │
│  │             │  │   memory_compactor│                        │
│  │ Outputs:    │  │                   │                        │
│  │ ┌────────┐  │  │ · Manual:         │                        │
│  │ │Key     │  │  │   /distill or API │                        │
│  │ │entities│  │  │                   │                        │
│  │ │≤10     │  │  │ ─────────────────│                        │
│  │ │500 ch  │  │                   │                        │
│  │ └────────┘  │  │ Layer 2:          │                        │
│  │ ┌────────┐  │  │ Distill Negative  │                        │
│  │ │Key     │  │  │ Rules (manager.py)│                        │
│  │ │facts   │  │  │                   │                        │
│  │ │semantic│  │  │ LLM explicitly    │                        │
│  │ │recall  │  │  │ told NOT to       │                        │
│  │ │top 15  │  │  │ extract:          │                        │
│  │ │2000 ch │  │  │ · Template OK msg │                        │
│  │ └────────┘  │  │ · Tool traces     │                        │
│  │             │  │ · Truncated output│                        │
│  │ Relevance-  │  │ · No-context text │                        │
│  │ based, not  │  └────────────┬─────────────┘                       │
│  │ fixed top 15│            │                                  │
│  └───────────────┘             ▼                                  │
│  ┌─────────────────────────────────────────────────┐             │
│  │  Layer 3: Decay & Eviction                    │             │
│  │  periodic_housekeeping runs every 6 hours     │             │
│  │                                              │             │
│  │  Facts > 30 → dedup                          │             │
│  │  Facts > 50 → quality audit + low-score drop │             │
│  │  Facts > 60 → hard cap eviction (lowest wgt) │             │
│  │  7-day half-life → unrecalled facts decay     │             │
│  │                                              │             │
│  │  Residual low-value facts auto-evict over time│             │
│  └─────────────────────────────────────────────────┘             │
│                                                              │
│  ┌─────────────────────────────────────────────────┐             │
│  │  Bonus: Conversation Summary Layer             │             │
│  │  _prune_history → async                       │             │
│  │                                              │             │
│  │  On token overflow: compress middle turns     │             │
│  │  into 300-char summary via local LLM          │             │
│  │  Keep head + tail + summary → zero info loss  │             │
│  └─────────────────────────────────────────────────┘             │
│                                                              │
└────────────────────────────────────────────────────────────────┘

How it works — three layers in series, each independent, combined pushing garbage facts to near-zero:

Layer 1: Source Interception — the most critical layer, solving "where garbage comes from." Before the refactor, MissionRunner unconditionally wrote 5 types of status notifications at two moments (subtask completion + mission close), with the same output file written twice causing duplicates. After the refactor: nothing is written on subtask completion; everything is batched to batch_update_facts at mission close. Only the output file path (written once) and a template-filtered execution summary are kept. Result: from 5-8 facts/task to 0-2, with index rebuilt only once.

Layer 2: Distill Filtering — even if Layer 1 misses some templated content in conversation history, distillation won't extract it. All three distill entry points (10-min timer, passive token threshold, manual /distill) are constrained by the same negative rules. This was the smallest change (one string edit) but has the widest coverage.

Layer 3: Decay & Eviction — long-term safety net. Unrecalled facts decay via a 7-day half-life. Thresholds at 30/50/60 facts trigger dedup, quality audit, and hard eviction respectively. Residual garbage naturally disappears over time.

Bonus: Conversation Summary — when the ReAct loop hits the token limit, _prune_history compresses middle turns into a 300-char summary via local LLM instead of discarding them outright. Combined with LTM semantic recall (per-step relevance-based retrieval instead of fixed top-15), the LLM always sees complete context.

7. CCP Capability-Constrained Planning — Planner Declares Boundaries Before Execution

v0.5.0 introduces the CCP (Capability-Constrained Planning) protocol, a six-step planning discipline that forces the Strategist to explicitly declare what it can and cannot do before any execution begins.

Step 1: Blocker Detection       — Identify missing credentials, resources, or authorizations
Step 2: Owner Labeling          — Mark each subtask as AGENT (AI-executable) or USER (requires human action)
Step 3: Confidence Rating       — Rate HIGH / MEDIUM / LOW per subtask
Step 4: Deliverable Declaration — List concrete artifacts the plan will produce
Step 5: Feasibility Note        — State the boundary between "promised" and "guaranteed"
Step 6: DAG Construction        — Build dependency graph with cycle detection

USER step routing: Subtasks marked owner: USER (e.g., "purchase a server", "provide API key") pause execution and prompt the human via the existing confirmation mechanism. They don't consume concurrency slots, and upstream cancellation automatically cascades to dependent downstream steps — no dead-wait loops.

Pydantic self-healing: The entire planning pipeline is wrapped in ValidationError / JSONDecodeError interception. Malformed LLM JSON output is auto-repaired (Markdown wrapping, trailing commas, Chinese quotes) and retried through the model before falling back to a safe default.

8. Tool Dependency Injection + Schema Self-Healing — Zero-Breakage Plumbing Upgrade

RoosterContext injection (src/toolset/context.py): A RoosterContext dataclass carries session_id, task_id, workspace_dir, memory_manager, llm_client, blackboard, config, and security_policy into every tool's execute() call. Tools opt-in by implementing execute(self, args, ctx) alongside the legacy run(**kwargs) — the dispatcher auto-detects which signature to use. Existing tools require zero changes.

ToolCallValidator (src/toolset/validation.py): Before any tool executes, its arguments pass through a Pydantic-based validator. Two self-healing paths kick in on failure:

  • JSON syntax healing: Fixes malformed JSON (missing quotes, trailing commas, single quotes) via lightweight LLM correction
  • Schema structure healing: When model_validate raises ValidationError, the error message is packaged into a prompt for the router model (temperature=0.1) to fix the parameters

Each path allows up to 2 retries. After budget exhaustion, the call degrades to a SchemaValidationFailed error for the ReAct loop to handle autonomously. The system never infinite-loops.

9. Engineering Hardening — Security, Observability, and Resource Governance

Security defaults upgraded: ADVANCED_SECURITY defaults to true, CONFIRMATION_BEHAVIOR defaults to block. Dangerous operations require explicit user confirmation instead of silent pass-through. PI scan exemptions cleared — python_exec, terminal, and other high-impact tools are no longer exempt from Prompt Injection scanning.

Typed signal exceptions (src/utils/exceptions.py): EscalateSignal and AbortSignal replace the fragile raise Exception("__ESCALATE__: ...") + .replace() magic-string pattern. Exception catching is now type-safe with precise stack traces.

Structured metrics (gateway/metrics.py): New Prometheus instruments — observe_tool_execution() (tool latency histogram + status counter), observe_subtask_execution() (subtask duration), observe_failover() (Provider failover rate), observe_llm_error() (LLM error tracking). Breaks the previous blind spot of token-count-only monitoring.

Mission correlation ID (src/utils/logging_context.py): ContextVar-based mission_id injection. Once MissionRunner calls set_mission_id(), all logs produced by that mission carry the [mission=xxx] tag — across Router, Strategist, Executor, and Auditor.

Resource governance: Unified cleanup() shutdown hook in launcher.py ensures Router, DistillationScheduler, and ModelFactory release their HTTPX connection pools on process exit. Bare except: clauses eliminated in favor of targeted except (json.JSONDecodeError, ValueError).


3. Directory Structure

rooster/
├── .env                        # Non-sensitive config (model routing, behavior policies)
├── .env.local.example          # Secrets template
├── pyproject.toml              # Project config & dependencies
├── guardian.py                 # Process guardian (lifecycle, port cleanup, auto-restart)
├── start.bat                    # Windows launch script (macOS: double-click Rooster.app)
├── CONTRIBUTING.md             # Contribution guidelines
├── SECURITY.md                 # Security policy
│
├── resources/
│   └── models/                 # Vision model weights (committed to git, no extra download)
│       └── grounding/
│           └── icon_detect/
│               └── model.pt    #   YOLO UI element detection model (39 MB)
│
├── skills/                     # External skills (12 built-in)
│   ├── coding-agent/           #   Coding agent
│   ├── data-analysis/          #   Data analysis
│   ├── dev-tools/              #   Dev tools
│   ├── git-ops/                #   Git operations
│   ├── github/                 #   GitHub operations
│   ├── pdf-tools/              #   PDF tools
│   ├── resource-downloader/    #   Resource downloader
│   ├── self-improving/         #   Self-improvement
│   ├── summarize/              #   Summarization
│   ├── visual-control/         #   Visual control
│   ├── weather-query/          #   Weather query
│   └── web-search/             #   Web search
│
├── src/
│   ├── main.py                 # Entry: preflight + launch
│   ├── launcher.py             # Launcher: gateway + CLI + channels + memory warmup
│   │
│   ├── agents/                 # Core Agent roles
│   │   ├── protocol.py         #   Data protocol (MissionPlan / SubTask / Report / AuditVerdict)
│   │   ├── router.py           #   Entry router: L1 Gate → SkillIndex → Strategist.decide() → MissionRunner
│   │   ├── reframer.py         #   Intent normalizer (vague → structured instructions)
│   │   ├── short_circuit.py    #   Short-circuit router (fast-path for common tasks)
│   │   ├── strategist.py       #   Strategist (DAG subtask decomposition + replan)
│   │   ├── executor.py         #   Executor (ReAct loop + tool dispatch)
│   │   ├── auditor.py          #   Auditor (AFFIRM / REMAND / REPLAN / ESCALATE)
│   │   ├── orchestrator.py     #   Tool orchestrator (visual strategy + self-healing)
│   │   ├── mission_tactician.py#   Tactician (DAG topo sort + parallel grouping)
│   │   ├── mission_blackboard.py#  Shared blackboard for concurrent subtasks
│   │   ├── reflection_engine.py#   Reflection engine (error pattern analysis)
│   │   ├── llm_client.py       #  LLM client (multi-provider rotation + cooldown + backoff)
│   │   ├── prompt_builder.py   #   5-layer System Prompt builder
│   │   ├── tool_dispatch.py    #   Tool call extraction & execution
│   │   └── runners/
│   │       └── mission_runner.py#    Multi-step orchestration (V15: DIRECT_REPLY / SINGLE_STEP / DAG_PLAN)
│   │
│   ├── toolset/                # Tool registry (55 tools, 32 exposed to LLM)
│   │   ├── base.py             #   BaseTool base class (platform / kit / fc_hidden)
│   │   ├── registry.py         #   Global tool registry (auto-discovery + schema validation)
│   │   ├── context.py          #   RoosterContext — unified DI container for tool execution
│   │   ├── validation.py       #   ToolCallValidator — schema self-healing (JSON + structure repair)
│   │   └── definitions/        #   Tool implementations (22 modules)
│   │       ├── browser_automation.py #   Browser automation (nav / read / click / act)
│   │       ├── visual_control.py   #   Desktop visual control (grounding_scan / read_screen / act)
│   │       ├── file_system.py      #   File system (file_system_op — read/write/list/search/mkdir)
│   │       ├── office.py           #   Office (excel_op / docx_write / pdf_op)
│   │       ├── interpreter.py      #   Python execution (E2B sandbox / local)
│   │       ├── web_search.py        #   Search (Linkup / Exa / GLM / 7-lane / Playwright 5-tier dynamic fallback)
│   │       ├── subagent.py         #   SubAgent orchestration
│   │       ├── task_manager.py     #   Task management
│   │       ├── task_scheduler.py   #   Scheduled tasks (Windows schtasks / macOS launchd)
│   │       ├── email.py            #   Email sending
│   │       ├── ocr.py              #   OCR text extraction
│   │       ├── memory.py           #   Long-term memory write
│   │       └── ...                 #   22 definition files total
│   │
│   ├── gateway/                # HTTP / WebSocket gateway
│   │   ├── server.py           #   FastAPI application factory
│   │   ├── auth.py             #   API Key auth + HMAC + rate limiting
│   │   ├── security.py         #   Security headers + request size limits
│   │   ├── run_manager.py      #   Run task management (with global cancel)
│   │   ├── connection_manager.py#  Node connection pool
│   │   ├── dashboard_ws.py     #   Dashboard WebSocket push
│   │   ├── event_handler.py    #   Agent events → WebSocket broadcast
│   │   ├── local_node.py       #   Local controlled desktop node
│   │   ├── metrics.py          #   Prometheus metrics
│   │   ├── stream.py           #   Streaming protocol
│   │   └── routes/
│   │       ├── websockets.py   #     WebSocket endpoints
│   │       ├── config.py       #     /api/config read/write
│   │       ├── memory.py       #     /api/memory CRUD
│   │       ├── models.py       #     /api/models (Ollama / HuggingFace)
│   │       ├── skills.py       #     /api/skills marketplace
│   │       └── system.py       #     /api system endpoints
│   │
│   ├── channels/               # Input channels
│   │   ├── cli.py              #   Console interaction (bilingual /lang switch)
│   │   ├── feishu.py           #   Feishu/Lark bot (lazy-loaded)
│   │   ├── webhook.py          #   HTTP Webhook channel
│   │   └── registry.py         #   Channel registry
│   │
│   ├── models/                 # LLM provider adapters
│   │   ├── factory.py          #   ModelFactory (provider → client factory)
│   │   ├── openai_adapter.py   #   OpenAI-compatible adapter
│   │   ├── anthropic_adapter.py#   Anthropic Claude adapter
│   │   └── vision_strategy.py  #   Vision strategy
│   │
│   ├── memory/                 # Memory system
│   │   ├── manager.py          #   LTM core (embedding + retrieval + decay)
│   │   ├── backends.py         #   JSON / Markdown storage backend
│   │   ├── soul_loader.py      #   SOUL.md / USER.md loading + 5-layer prompt build
│   │   ├── embeddings.py       #   Embedding vector generation
│   │   ├── semantic_search.py  #   Semantic search
│   │   ├── dedup.py            #   Memory deduplication
│   │   ├── indexer.py          #   Full-text indexer
│   │   ├── compactor.py        #   Memory compaction
│   │   └── watcher.py          #   File system watcher (hot reload)
│   │
│   ├── evolution/              # Self-evolution engine
│   │   ├── engine.py           #   Signal detection → LLM extraction → auto-write SOUL/USER
│   │   ├── soul_writer.py      #   SOUL.md append-only writer
│   │   └── user_writer.py      #   USER.md writer
│   │
│   ├── sessions/               # Session management
│   │   └── store.py            #   Global session store (atomic write)
│   │
│   ├── prompts/                # Prompt templates (Markdown)
│   │   ├── base.md             #   Base behavior protocol
│   │   ├── strategist.md       #   Strategist prompt
│   │   ├── executor.md         #   Executor prompt
│   │   ├── auditor.md          #   Auditor prompt
│   │   ├── replan.md           #   Replan prompt
│   │   ├── strategist_triage.md #   V15 depth judgment prompt
│   │   └── intent_reframer.md  #   Intent reframer prompt
│   │
│   └── utils/                  # Utilities
│       ├── config/             #   Config system
│       │   ├── _base.py        #     Env var reading helpers (with typo detection)
│       │   ├── _settings.py    #     Composite Settings
│       │   ├── loader.py       #     Config loader (deprecated — .env is the sole config source)
│       │   ├── providers.py    #     LLM provider config
│       │   ├── runtime.py      #     Runtime config
│       │   ├── hardware.py     #     Hardware/vision config
│       │   ├── channels.py     #     Channel config
│       │   └── memory.py       #     Memory config
│       ├── security/           #   Security modules
│       │   ├── path_guard.py   #     Path guard (symlink bypass prevention)
│       │   ├── state_guard.py  #     State guard
│       │   ├── advanced_guard.py#    Jailbreak detection (PI scan — no tool exemptions)
│       │   ├── input_guard.py  #     Input validation
│       │   ├── secrets_mask.py #     Log secret masking
│       │   └── tool_rate_limiter.py # Per-tool rate limiting
│       ├── exceptions.py       #   Typed signal exceptions (EscalateSignal / AbortSignal)
│       ├── logging_context.py  #   Mission correlation ID (ContextVar-based log injection)
│       ├── vision/             #   Vision engine (YOLO)
│       ├── browser/            #   Browser tools (Playwright)
│       └── audit/              #   Audit tools
│
├── tests/                      # Test suite (31 test files)
└── .rooster/                   # Runtime data (gitignored)
    ├── SOUL.md                 #   Agent soul file
    ├── USER.md                 #   User profile file
    ├── project_memory.json     #   Long-term memory
    ├── schedules.json          #   Scheduled tasks
    ├── sessions/               #   Session data
    └── logs/                   #   Logs

4. Core Architecture

Request Processing Flow

User Message (CLI / Feishu / WebSocket / Dashboard)
    │
    ▼
L1 Hard-Rule Gate (< 5ms, pure code)
    ├─ BLOCK ────────► Safety intercept
    ├─ SCHEDULE ─────► Scheduled task registration → schedules.json
    ├─ Download KW ──► Reframer pre-processing
    └─ Other ────────► Continue to planner path
                            │
                            ▼
                     L2 SkillIndex (~20ms, TF-IDF)
                           │
                           ▼
                    Strategist.decide() (fast LLM)
                           │
                           ├─ DIRECT_REPLY ──► Streaming response
                           ├─ SINGLE_STEP ───► MissionRunner single task
                           ├─ DAG_PLAN ──────► MissionRunner multi-step DAG
                           └─ CLARIFY ────────► Send clarification question
                                                     │
                                                     ▼
                                             MissionRunner
                                                   │
                                                   ▼
                                             Strategist (Planning Phase)
                                             ├─ DAG decomposition: task → ordered subtasks
                                             ├─ Dependency analysis: parallel grouping
                                             └─ Domain routing: local vs cloud per subtask
                                                   │
                                             ┌─────┴─────┐
                                             ▼           ▼
                                        Executor      Executor
                                        (ReAct loop   (parallel
                                         + 29 tools)   subtasks)
                                             │           │
                                             └─────┬─────┘
                                                   ▼
                                            ┌──────────────┐
                                            │   Privacy    │
                                            │   Router     │
                                            │ ┌──────────┐ │
                                            │ │L0: Folder│ │  LOCAL_DIRS → local model
                                            │ │L1: PII   │ │  Presidio scan → local model
                                            │ │L3: Policy│ │  Memory/Compaction → local
                                            │ └──────────┘ │  Screenshots → OCR + strip
                                            └──────────────┘
                                                   │
                                                   ▼
                                               Auditor
                                              (quality review)
                                                   │
                                             ┌─────┴─────┐
                                             ▼           ▼
                                           AFFIRM    REMAND / REPLAN / ESCALATE
                                          (continue)  (redo / replan / escalate)

5-Layer System Prompt Architecture

Layer 1: SOUL.md         — Agent soul / personality (highest priority)
Layer 2: USER.md         — User profile / preferences
Layer 3: Skills digest   — Installed skills summary
Layer 4: LTM context     — Long-term memory semantic recall
Layer 5: Base prompt     — Role prompt (strategist.md / executor.md / etc.)

LLM Provider System

Multi-provider automatic failover, degrading by priority:

Provider Env Variable Notes
Zhipu CodingPlan ZHIPU_KEY Enhanced coding GLM, current primary
Zhipu GLM Standard ZHIPU_GLM_KEY Standard API fallback
Xiaomi MiMo MIMO_KEY Lightweight, default for reframer
Jiutian MoMA JIUTIAN_KEY Dual-model (large/small) auto-routing
OpenAI OPENAI_KEY GPT-4o etc.
Anthropic Claude ANTHROPIC_KEY Native Messages API
Kimi (Moonshot) KIMI_KEY Moonshot AI
Qwen (Tongyi Qianwen) QWEN_KEY DashScope compatible
Cloud CLOUD_KEY Generic OpenAI-compatible
Local LOCAL_KEY llama.cpp / Ollama local inference

Tool System

55 tools registered, 32 exposed to LLM for Function Calling (23 are internal/legacy). All tool calls pass through ToolCallValidator for schema auto-healing before execution. Tools can opt into RoosterContext dependency injection by implementing execute(self, args, ctx) alongside the legacy run(**kwargs). Grouped by Kit:

Kit Core Tools Capabilities
Browser browser_nav, browser_act, web_fetch, batch_web_fetch Web browsing & scraping
Search web_search Multi-engine search (Linkup / Exa / GLM / 7-lane / Playwright 5-tier dynamic fallback)
Vision desktop_grounding_scan, desktop_act, desktop_read_screen Desktop UI control
FileSystem file_system_op File read/write/list/search/mkdir/download
Office excel_op, office_docx_write, pdf_op Excel / Word / PDF
Interpreter python_interpreter Python execution (E2B sandbox / local)
Memory memory_add_fact Long-term memory write
Task task_manager, task_scheduler Task management + scheduled tasks
SubAgent subagent_spawn, subagent_result SubAgent orchestration
Comms email_send, feishu_push_file Email / Feishu push
Multimedia multimedia_download, movie_downloader Resource downloads
OCR ocr_extract Image text extraction (PaddleOCR)
Plan plan_mode Planning mode (pause → user review → continue)
System tool_info, skill_read, wait_until Meta-tools

Security System

Layer Mechanism Details
Gateway auth API Key (X-API-Key / Authorization: Bearer) Skipped when GATEWAY_API_KEY is empty (local dev)
Webhook signing HMAC-SHA256 Enabled when WEBHOOK_HMAC_SECRET is set
Rate limiting IP sliding window (100 req/min) Localhost automatically exempt
Security headers CSP / X-Frame-Options / X-Content-Type-Options Global middleware
Request size 1 MB limit Prevents oversized request bodies
Input validation Config key whitelist + value length limits /api/config/save endpoint
File sandbox PathGuard (realpath + prefix) Prevents symlink bypass
Jailbreak detection AdvancedGuard Detects prompt injection / skill poisoning
Log masking secrets_mask Auto-masks secrets in logs
Tool rate limiting tool_rate_limiter Per-tool quota rate limiting

5. Quick Start

Option A: Local Installation (Recommended)

# 1. Clone and install (Dashboard is pre-built, no Node.js needed)
git clone https://github.com/zzycxz/rooster.git
cd rooster
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

# 2. Configure API keys (at least one LLM key required)
cp .env.local.example .env.local
# Edit .env.local — fill in at least one API Key

# 3. Launch (guardian mode with auto-restart)
python guardian.py

Dashboard opens automatically at http://localhost:8765/dashboard.

First-time user notes:

  • Ready to use after git clone — model weights and Dashboard frontend are included in the repo
  • If the browser doesn't open automatically, navigate to http://localhost:8765/dashboard
  • Dashboard supports bilingual ZH/EN (Language button at sidebar bottom)
  • Only one LLM API key is needed to run (Zhipu recommended — has free tier)
  • Ollama users: install Ollama and pull a model first

Launching on macOS

Method How
Double-click Double-click Rooster.app (macOS launcher, venv auto-activated)
Terminal python3 guardian.py

macOS Sequoia (15.x) Gatekeeper: If you see "无法执行,因为你没有正确的访问权限" when double-clicking for the first time, go to System Settings → Privacy & Security → Security and click "Open Anyway". This is a one-time approval — subsequent launches work normally. Alternatively, use python3 guardian.py from Terminal to bypass Gatekeeper entirely.

macOS Notes

Core features (LLM, browser, file ops, Dashboard) work identically on macOS. Known differences:

Feature macOS Status Notes
Visual desktop control Partial Screenshots + pyautogui work; UIA window scanning unavailable
window_visible wait Needs permission Grant Accessibility access to Terminal/Python in System Settings
Playwright Needs install playwright install chromium
YOLO grounding Manual install pip install -e ".[vision]"

Option B: Dashboard First-Run Setup

On first launch, the Dashboard automatically detects whether .env.local is configured. If not:

  1. Open http://localhost:8765/dashboard
  2. Click the "Setup" tab on the left
  3. Select an LLM provider → Enter API Key → Click "Save Config"
  4. The system auto-restarts with the new config
  5. Use "Test Connection" to verify provider connectivity

The Setup panel also includes:

  • Ollama Guardian: Detect local Ollama status, pull models, assign roles
  • HuggingFace Model Browser: Search/download GGUF models, import to Ollama or launch llama.cpp
  • Role Matrix: Assign providers to Router / Strategist / Executor / Auditor / Solo individually

6. Dashboard

Dashboard is a single-page web app (Alpine.js + Tailwind) with 13 panels:

Panel Features
Execution Agent chat + real-time Pipeline visualization (Router→Strategist→Executor→Auditor status) + session management + image paste
Downloader Full-featured visual download manager (AriaNg integration + aria2c status)
Steps Detailed timeline of every Agent action (tool args / return values), with filter and search
Logs Real-time log stream (level filter + search + export + stack trace expand)
Errors Error collection (stack traces + fix suggestions)
Tools Tool call history (args + results + duration) + per-tool success/fail/latency stats
Skills Installed skill management (load/unload/test/fix-deps) + ClawHub online marketplace
Memory Memory facts browser (search / delete / decay) + SOUL.md / USER.md editor
Metrics Active sessions/subtasks/requests + LLM/Tool/HTTP latency percentiles + Guardian watchdog status
Config .env config view (grouped by category, secrets masked)
Setup 10 provider cards + Ollama manager + HF model browser + role matrix + failover config + danger zone
Health Service connectivity check + CPU / Memory / Disk / Network / Top processes
Scheduler Cron task list + editor + execution history + dashboard

7. Integration Guide

6.1 WebSocket API (Recommended)

Gateway listens on ws://127.0.0.1:8765/ws/gateway by default.

Send a task:

{
  "method": "chat.send",
  "params": {
    "sessionKey": "my_session_001",
    "message": "Search for Python asyncio usage"
  },
  "id": "req_001"
}

Cancel execution:

{
  "method": "chat.cancel",
  "params": { "sessionKey": "my_session_001" },
  "id": "cancel_001"
}

6.2 HTTP API

System endpoints:

Endpoint Method Description
/api/health GET Health check (LLM + .env.local)
/api/version GET Version number
/api/cancel POST Global cancel all running tasks
/api/metrics/summary GET JSON metrics summary
/metrics GET Prometheus metrics
/api/system/stats GET System resources (CPU / memory / disk / network)
/api/guardian/status GET Guardian watchdog status
/api/sessions GET Session list
/api/toolset GET Registered tools (grouped by Kit)
/api/security/status GET Security configuration status

Config endpoints (/api/config):

Endpoint Method Description
/api/config/save POST Save config to .env.local (auto-restart)
/api/config/reload POST Hot-reload .env files (no restart)
/api/config/models GET Configured provider list
/api/config/masked GET Masked full config
/api/config/test GET Test provider connectivity

Memory endpoints (/api/memory):

Endpoint Method Description
/api/memory/stats GET Memory statistics
/api/memory/facts GET Memory facts list
/api/memory/facts/{id} DELETE Delete a memory
/api/memory/decay POST Trigger memory decay
/api/memory/soul GET / PUT SOUL.md read/write
/api/memory/user GET / PUT USER.md read/write

Skills endpoints (/api/skills):

Endpoint Method Description
/api/skills GET Installed skills list
/api/skills/market GET ClawHub skill marketplace
/api/skills/install POST Install a skill
/api/skills/uninstall POST Uninstall a skill
/api/skills/reload POST Hot-reload skill cache
/api/skills/toggle POST Enable / disable a skill
/api/skills/test POST Test a skill

Model endpoints (/api/models):

Endpoint Method Description
/api/models/ollama/scan GET Scan local Ollama models
/api/models/ollama/pull POST Pull Ollama model
/api/models/ollama/apply POST Assign model to role
/api/models/ollama/delete POST Delete Ollama model
/api/models/hf/search GET Search HuggingFace GGUF models
/api/models/hf/download POST Download HF model
/api/models/hf/import/ollama POST Import to Ollama
/api/models/hf/import/llamacpp POST Launch llama.cpp server

6.3 CLI

python guardian.py
# Enters interactive CLI

# Available commands:
/new      - Start a new session
/list     - List sessions
/switch   - Switch session
/model    - Switch model
/proxy    - Proxy control (status / on / off)
/lang     - Switch language (zh/en)
/exit     - Exit

6.4 Node WebSocket

WS /ws/gateway   — Main gateway WebSocket (Dashboard push)
WS /ws/dashboard — Dashboard real-time updates
WS /v1/node/ws   — Controlled desktop node (with auth_required handshake)

8. Key Configuration

.env.local.example only templates secrets. Runtime behavior, routing, and model selection live in .env.

Required: At Least One LLM Key

# Recommended (Zhipu — has free tier)
ZHIPU_KEY=your_key

# Or other providers (any one is sufficient)
OPENAI_KEY=your_key
ANTHROPIC_KEY=your_key
MIMO_KEY=your_key
JIUTIAN_KEY=your_key
KIMI_KEY=your_key
QWEN_KEY=your_key
CLOUD_KEY=your_key

Gateway Security

GATEWAY_API_KEY=your-secret-key    # Leave empty to skip auth (local dev)
WEBHOOK_HMAC_SECRET=your-hmac      # Webhook signing key

Role Model Assignment

STRATEGIST_MODEL_MODE=zhipu        # Strategist (default: zhipu)
EXECUTOR_MODEL_MODE=jiutian        # Executor (default: jiutian)
AUDITOR_MODEL_MODE=jiutian         # Auditor (default: jiutian)

V15 Thin Routing / Model Tiers

FAST_MODEL_PROVIDER=mimo            # Lightweight provider for decide() / validator repair
FAST_MODEL_NAME=mimo-v2.5           # Fast-path model (must match FAST_MODEL_PROVIDER; see providers.py comment)

MODEL_TIER_FAST=                   # Optional override for fast tier
MODEL_TIER_STANDARD=               # Optional override for standard executor tier
MODEL_TIER_REASONING=              # Optional override for reasoning executor tier

SKILL_INDEX_THRESHOLD=0.3          # TF-IDF hint threshold
# Runtime priority: OLLAMA domain > model tier > executor defaults

Failover

LLM_FAILOVER_ENABLED=true
LLM_FAILOVER_ORDER=jiutian,zhipu,mimo,local
LLM_FAILOVER_RETRY_MAX=2

Network / Proxy

GATEWAY_PORT=8765
OLLAMA_URL=http://localhost:11434         # Ollama management API
HF_ENDPOINT=https://huggingface.co        # HuggingFace mirror (China: hf-mirror.com)
# HTTP_PROXY=http://127.0.0.1:7897        # Configure in .env.local

9. Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest -q

# Lint
ruff check .

Adding a New Skill

Create a directory and SKILL.md under skills/:

---
name: my-skill
description: "Skill description"
metadata:
  rooster:
    emoji: "🔧"
    platform: ["any"]
    category: "automation"
    requires:
      python_packages: ["pandas"]
      bins: ["git"]
---

Adding a New Tool

Create a Python file under src/toolset/definitions/, inheriting BaseTool:

from toolset.base import BaseTool
from toolset.context import RoosterContext
from pydantic import BaseModel

class MyToolArgs(BaseModel):
    query: str

class MyTool(BaseTool):
    name = "my_tool"
    description = "A custom tool"
    kit = "custom"
    args_schema = MyToolArgs

    # New: use execute() for RoosterContext injection (preferred)
    async def execute(self, args: MyToolArgs, ctx: RoosterContext):
        return {"result": "done", "session": ctx.session_id}

    # Legacy: run(**kwargs) still works for backward compatibility
    async def run(self, **kwargs):
        return {"result": "done"}

See CONTRIBUTING.md for detailed guidelines.


10. Debugging Reference

Issue Check First
Startup failure Console output — preflight checks indicate missing API keys
Task not executing src/agents/router.pyhandle_inbound()
Subtask timeout src/agents/strategist.py → timeout parameter
Tool call failure src/agents/tool_dispatch.py_execute_tool_with_healing()
LLM call failure src/agents/llm_client.py → Provider switching logic
Vision grounding inaccurate src/utils/vision/grounding.py (requires pip install -e ".[vision]")
Dashboard disconnected Check GATEWAY_API_KEY config and browser console
Feishu channel not starting Normal — auto-skipped when lark-oapi is not installed

Common Issues

Symptom Cause Solution
"No LLM API keys" error .env.local not configured cp .env.local.example .env.local and fill in a key
Web scraping returns empty Anti-scraping block Check HTTP_PROXY or playwright install chromium
Vision tool error Missing YOLO dependencies pip install -e ".[vision]"
Dashboard shows disconnected Auth mismatch Ensure browser has auth header injected, or clear GATEWAY_API_KEY
Tool registration failed BaseTool subclass missing name/description/run Refer to toolset/base.py contract
Ollama connection failed Ollama not running or wrong port Check OLLAMA_URL config, default http://localhost:11434

License

MIT

About

Autonomous multi-agent desktop OS

Resources

Contributing

Security policy

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages