From 4b49386f96f7ad93136f31fd0bc1a37c95159ff2 Mon Sep 17 00:00:00 2001 From: Alessandro <155005371+3clyp50@users.noreply.github.com> Date: Tue, 23 Jun 2026 17:51:43 +0200 Subject: [PATCH] Refactor a0-development into grounded references Split the monolithic a0-development skill into a lean entry point plus focused reference files for runtime, DOX, tools, extensions, API/WebUI, profiles, prompts, skills, projects, and plugin workflow. Update the skill DOX ownership for the new references directory and clarify the root framework-vs-agent Python runtimes plus port-discovery guidance. Verified with git diff --check, targeted skill/tool tests under PYTHONPATH, and live localhost:32769 skill loading/read_file checks before committing. --- AGENTS.md | 18 +- skills/a0-development/AGENTS.md | 16 +- skills/a0-development/SKILL.md | 850 +----------------- skills/a0-development/references/AGENTS.md | 38 + .../agents-prompts-skills-projects.md | 95 ++ skills/a0-development/references/api-webui.md | 93 ++ .../references/architecture-runtime.md | 79 ++ .../a0-development/references/dox-workflow.md | 66 ++ .../a0-development/references/extensions.md | 150 ++++ .../references/plugins-workflow.md | 91 ++ skills/a0-development/references/tools.md | 76 ++ 11 files changed, 752 insertions(+), 820 deletions(-) create mode 100644 skills/a0-development/references/AGENTS.md create mode 100644 skills/a0-development/references/agents-prompts-skills-projects.md create mode 100644 skills/a0-development/references/api-webui.md create mode 100644 skills/a0-development/references/architecture-runtime.md create mode 100644 skills/a0-development/references/dox-workflow.md create mode 100644 skills/a0-development/references/extensions.md create mode 100644 skills/a0-development/references/plugins-workflow.md create mode 100644 skills/a0-development/references/tools.md diff --git a/AGENTS.md b/AGENTS.md index 8340f16b9..549f6b559 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,8 +3,8 @@ [Generated using reconnaissance on 2026-02-22] ## Quick Reference -Tech Stack: Python 3.12+ | Flask | Alpine.js | LiteLLM | WebSocket (Socket.io) -Dev Server: python run_ui.py (runs on http://localhost:50001 by default) +Tech Stack: Framework Python 3.12+ | Agent execution Python 3.13 in Docker | Flask | Alpine.js | LiteLLM | WebSocket (Socket.io) +Dev Server: python run_ui.py (discover host/port from startup output or runtime configuration; do not assume a default port) Run Tests: pytest (standard) or pytest tests/test_name.py (file-scoped) Documentation: README.md | docs/ Frontend & Plugin DOX: [WebUI](webui/AGENTS.md) | [Components](webui/components/AGENTS.md) | [Frontend JS](webui/js/AGENTS.md) | [Plugins](plugins/AGENTS.md) @@ -43,22 +43,24 @@ Do not combine these commands; run them individually: pip install -r requirements.txt ``` - Start WebUI: python run_ui.py +- Discover the WebUI URL from startup output, launcher/Docker port mappings, or explicit `--host`/`--port`/`WEB_UI_PORT` configuration; do not hardcode a default port. --- ## Docker Environment -When running in Docker, Agent Zero uses two distinct Python runtimes to isolate the framework from the code being executed: +When running in Docker, Agent Zero uses two distinct Python runtimes to isolate the framework itself from code executed on behalf of the agent: ### 1. Framework Runtime (/opt/venv-a0) - Version: Python 3.12.4 -- Purpose: Runs the Agent Zero backend, API, and core logic. -- Packages: Contains all dependencies from requirements.txt. +- Purpose: Runs the Agent Zero framework itself: WebUI backend, API, core loop, scheduler, framework imports, and plugin hooks/tools that execute inside the framework process. +- Packages: Contains framework dependencies from requirements.txt. +- Verification: Use this runtime for framework/backend import checks, WebUI startup checks, and plugin hook behavior unless the code explicitly switches environments. -### 2. Execution Runtime (/opt/venv) +### 2. Agent Execution Runtime (/opt/venv) - Version: Python 3.13 -- Purpose: Default environment for the interactive terminal and the agent's code execution tool. -- Behavior: This is the environment active when you docker exec into the container. Packages installed by the agent via pip install during a task are stored here. +- Purpose: Default Python environment for the agent's terminal/code-execution tasks and user code run by the agent. +- Behavior: Packages installed by the agent during a task belong here so task dependencies do not pollute or prove the framework runtime. Do not use this runtime as evidence that framework imports, WebUI startup, or plugin hooks work. --- diff --git a/skills/a0-development/AGENTS.md b/skills/a0-development/AGENTS.md index b53fd4cc0..bfa89616a 100644 --- a/skills/a0-development/AGENTS.md +++ b/skills/a0-development/AGENTS.md @@ -3,27 +3,35 @@ ## Purpose - Own the broad Agent Zero development guide used by agents extending the framework. -- Keep architecture, tools, extensions, API, agents, prompts, projects, and skills guidance in sync with the repository. +- Keep architecture, tools, extensions, API, agents, prompts, projects, plugins, runtime, and skills guidance in sync with the repository. ## Ownership -- `SKILL.md` owns the development overview, path conventions, and implementation references. +- `SKILL.md` owns the concise development entry point, routing workflow, path conventions, and reference map. +- `references/` owns detailed source-grounded development references loaded on demand. ## Local Contracts - Keep paths and examples current with source files and DOX contracts. - Route plugin-specific tasks to the plugin router or specialist plugin skills. - Do not duplicate long contracts that belong in narrower AGENTS.md files when a reference is enough. +- Reference files must identify current source or DOX anchors and avoid hardcoded default WebUI ports. ## Work Guidance - Update this skill after durable framework workflow, extension, tool, API, prompt, or profile changes. - Keep examples operational and compatible with the current helper classes. +- Keep `SKILL.md` lean; move detailed schemas, examples, and topic-specific guidance to `references/`. ## Verification -- Manually read `SKILL.md` for stale architecture references and broken related-skill links. +- Manually read `SKILL.md` and changed reference files for stale architecture references, broken relative paths, and specialist-skill duplication. +- Load the skill after reference-map changes and confirm `skills_tool` exposes the expected reference file tree. ## Child DOX Index -No child DOX files. +Direct child DOX files: + +| Child | Scope | +| --- | --- | +| [references/AGENTS.md](references/AGENTS.md) | Source-grounded development references loaded by this skill. | diff --git a/skills/a0-development/SKILL.md b/skills/a0-development/SKILL.md index 7dbf21c0e..94d44a500 100644 --- a/skills/a0-development/SKILL.md +++ b/skills/a0-development/SKILL.md @@ -1,9 +1,9 @@ --- name: a0-development -description: Development guide for extending and building features for the Agent Zero AI framework. Covers architecture, tools, extensions, API endpoints, agent profiles, projects, prompts, and skills — with correct paths, imports, and patterns matching the current codebase. -version: 1.0.0 +description: Development guide for extending Agent Zero from current source and DOX. Use for framework architecture, tools, extensions, API/WebUI handlers, agent profiles, prompts, skills, projects, runtime boundaries, and contribution workflow. Load the focused reference files before giving implementation guidance. +version: 1.1.0 author: Agent Zero Team -tags: ["development", "framework", "agent-zero", "extending", "tools", "extensions", "skills", "api", "agents", "prompts"] +tags: ["development", "framework", "agent-zero", "extending", "tools", "extensions", "skills", "api", "agents", "prompts", "dox"] trigger_patterns: - "extend agent zero" - "agent zero development" @@ -21,826 +21,60 @@ trigger_patterns: - "extension hook points" - "prompt system" - "agent profile" + - "dox" --- -# Agent Zero Development Guide +# Agent Zero Development -This skill provides comprehensive, accurate guidance for extending and building features for Agent Zero. Use it when you need to: +Use this skill as the entry point for Agent Zero framework development. It is intentionally lean: load only the reference files that match the task, then verify against the current repository before changing code. -- Understand the **architecture** and project layout -- Create new **Tools** for agent capabilities -- Add **Extensions** to hook into the framework lifecycle -- Build **API Endpoints** for the Web UI -- Create **Agent Profiles** (subordinates) with custom prompts -- Understand and extend the **Prompt System** -- Create **Skills** (see the dedicated `build-skill` skill for the full wizard) -- Work with **Projects** and workspace configuration +## Reality Rules -> **Path convention:** Throughout this guide, `/a0/` refers to the framework root — this is `/a0/` inside Docker, or your local repository root in development. All paths are relative to this root. +1. Source and nearest DOX beat memory, examples, and this skill if they disagree. +2. Before editing, read the applicable `AGENTS.md` chain from the repo root to every file you expect to touch. +3. New capabilities should usually be plugins. For plugin-specific work, load `a0-plugin-router` and follow the routed specialist skill. +4. Do not assume ports. Discover WebUI host/port from startup output, launcher or Docker mapping, or explicit `--host`, `--port`, `WEB_UI_HOST`, and `WEB_UI_PORT` configuration. +5. In Docker, framework checks belong to `/opt/venv-a0` and agent/user code execution belongs to `/opt/venv`. Do not use one runtime as proof for the other. +6. Treat `/a0/` as the runtime framework root inside Docker. In local development it means the repository root. If a live container matters, prove that `/a0` matches the checkout before trusting source-only conclusions. +7. Do not document or change ignored `usr/` or `tmp/` runtime state unless the user explicitly asks. -> [!IMPORTANT] -> **Plugins are the primary way to extend Agent Zero.** Most new tools, extensions, and prompts should be packaged as plugins. For all plugin tasks (create, review, manage, debug, contribute), load the `a0-plugin-router` skill which routes to the appropriate specialist. This guide covers the underlying framework patterns that plugins build upon. +## Reference Map -Related skills: `a0-plugin-router` (plugin tasks) | `build-skill` (skill creation wizard) | `a0-create-plugin` | `a0-review-plugin` | `a0-manage-plugin` | `a0-contribute-plugin` | `a0-debug-plugin` - ---- - -## Architecture Overview - -### Project Layout - -``` -/a0/ # Framework root -├── agent.py # Core Agent + AgentContext + AgentConfig classes -├── initialize.py # Agent initialization logic -├── models.py # Model definitions -├── run_ui.py # Web UI entry point -│ -├── tools/ # Core tools (search, response, browser, etc.) -├── extensions/ -│ ├── python/ # Python lifecycle extensions -│ │ ├── / # e.g., agent_init/, system_prompt/, etc. -│ │ │ └── _NN_name.py # Numbered extension files -│ │ └── _functions/ # Implicit @extensible decorator extensions -│ └── webui/ # JavaScript WebUI extensions -│ └── / # e.g., json_api_call_before/ -│ └── name.js -├── api/ # Flask API endpoint handlers -├── helpers/ # Framework utilities and base classes -│ ├── tool.py # Tool + Response base classes -│ ├── extension.py # Extension base class + @extensible decorator -│ ├── api.py # ApiHandler base class -│ ├── files.py # File operations + prompt reading -│ ├── plugins.py # Plugin system manager -│ ├── print_style.py # Console output formatting -│ └── ... # Many more utility modules -│ -├── prompts/ # Core prompt fragments (system, tools, framework) -├── agents/ # Agent profiles (subordinate specializations) -│ ├── default/ # Base profile (inherited by others) -│ ├── agent0/ # Main user-facing agent -│ ├── developer/ # Developer subordinate -│ ├── hacker/ # Security subordinate -│ ├── researcher/ # Research subordinate -│ └── _example/ # Example profile with tool + extension samples -│ -├── plugins/ # Core plugins (tools, extensions, prompts) -│ ├── _code_execution/ # Terminal/Python/Node.js execution -│ ├── _memory/ # Persistent memory system -│ ├── _text_editor/ # File read/write/patch -│ ├── _model_config/ # LLM model selection -│ ├── _infection_check/ # Prompt injection safety -│ └── ... # More core plugins -│ -├── skills/ # Core skills (SKILL.md bundles) -├── knowledge/ # Knowledge base files -├── webui/ # Web UI frontend -├── docs/ # Documentation -│ -└── usr/ # User-space (survives updates) - ├── agents/ # User-created agent profiles - ├── plugins/ # User-installed plugins - ├── skills/ # User-created skills - ├── knowledge/ # User knowledge base files - ├── extensions/ # Standalone user extensions (created on demand; prefer plugins instead) - ├── projects/ # Project workspaces (created on demand when user adds projects via UI) - └── workdir/ # Default working directory -``` - -### Key Architecture Patterns - -1. **Plugin-first design** — Most capabilities (tools, extensions, prompts) are delivered via plugins in `/a0/plugins/` (core) or `/a0/usr/plugins/` (user). -2. **Extensions execute in numeric order** — Files named `_10_*.py`, `_20_*.py`, etc. run sequentially within each hook point. -3. **Tools inherit from `Tool`** — All tools implement the `execute()` method returning a `Response`. -4. **Shared `AgentContext`** — Enables state persistence across agents in a conversation. -5. **Async/await throughout** — All tool execution, extensions, and API handlers are async. -6. **Prompt fragments compose** — System prompts are assembled from named fragments with includes and variable substitution. -7. **Profile inheritance** — Agent profiles inherit from `default/` and override specific prompt fragments. -8. **User-space separation** — Everything under `/a0/usr/` survives framework updates. - -### Agent Loop - -The core execution cycle works as follows: - -1. **User message** arrives (via UI or API) -2. **System prompt assembly** — prompt fragments are composed with includes and variable substitution -3. **LLM call** — the assembled prompt + conversation history is sent to the model -4. **Response parsing** — the framework parses the LLM response looking for JSON tool calls -5. **Tool execution** — if tool calls are found, each tool's `execute()` method is called and the result is appended to history -6. **Loop continues** — steps 3-5 repeat until the agent produces a `response` tool call (which ends the loop) or a loop limit is reached - -Extensions fire at each stage (e.g., `monologue_start`, `before_main_llm_call`, `tool_execute_before`, etc.), allowing plugins to observe and modify behavior at every point. - ---- - -## Creating Tools - -Tools are how agents interact with the world. Each tool inherits from the `Tool` base class. - -### Import Path - -```python -from helpers.tool import Tool, Response -``` - -### Tool Base Class - -```python -# /a0/helpers/tool.py - -@dataclass -class Response: - message: str # Text response shown to agent - break_loop: bool # True = stop agent message loop - additional: dict[str, Any] | None = None # Extra metadata for history - -class Tool: - def __init__(self, agent: Agent, name: str, method: str | None, - args: dict[str,str], message: str, - loop_data: LoopData | None, **kwargs) -> None: - self.agent = agent - self.name = name - self.method = method # For tools with sub-methods (e.g., "skills_tool:load") - self.args = args - self.loop_data = loop_data - self.message = message - - async def execute(self, **kwargs) -> Response: - pass # Override this - - # Lifecycle hooks (called automatically): - async def before_execution(self, **kwargs): ... - async def after_execution(self, response: Response, **kwargs): ... -``` - -### Where Tools Live - -| Location | Purpose | -|---|---| -| `/a0/tools/` | Core framework tools (search, response, call_subordinate, etc.) | -| `/a0/plugins//tools/` | Plugin-provided tools (code_execution, memory, text_editor) | -| `/a0/agents//tools/` | Profile-specific tool overrides | -| `/a0/usr/plugins//tools/` | User plugin tools | - -### Example: Creating a Tool - -Based on the actual `_example` profile in `/a0/agents/_example/tools/example_tool.py`: - -```python -# my_tool.py -from helpers.tool import Tool, Response - -class MyTool(Tool): - async def execute(self, **kwargs): - # Get arguments — kwargs contains the tool_args from the agent's JSON - input_data = kwargs.get("input", "") - - # Do something - result = f"Processed: {input_data}" - - # Return response - return Response( - message=result, # Shown to the agent - break_loop=False, # Don't stop the agent loop - ) -``` - -> [!IMPORTANT] -> Every tool needs a corresponding **prompt fragment** so the agent knows how to use it. Create a file named `agent.system.tool..md` in the appropriate `prompts/` directory. See the [Prompt System](#prompt-system) section. - -### Tool Best Practices - -- Always handle errors gracefully — return error messages in `Response`, don't crash -- Access agent context via `self.agent.context` -- Use `self.method` to support sub-methods (e.g., `my_tool:action1`, `my_tool:action2`) -- Use `kwargs.get()` to read arguments with defaults -- For long operations, use `self.set_progress()` or `self.add_progress()` to show status -- Access `self.loop_data` for loop state (iteration count, timing, etc.) — this is the `LoopData` instance passed during tool dispatch - ---- - -## Creating Extensions - -Extensions hook into specific lifecycle points in the agent framework. - -### Import Path - -```python -from helpers.extension import Extension -``` - -### Extension Base Class - -```python -class Extension: - def __init__(self, agent: "Agent | None", **kwargs): - self.agent: "Agent | None" = agent - self.kwargs = kwargs - - def execute(self, **kwargs) -> None | Awaitable[None]: - pass # Override this — kwargs are hook-point-specific -``` - -> Extensions can be sync or async. If `execute()` returns an `Awaitable`, the framework will `await` it automatically. The `agent` parameter is nullable because some hook points (like `startup_migration` or `banners`) fire before an agent exists. - -### Extension File Location - -Extensions live in directories named by their hook point. The path structure is: - -``` -extensions/python//_NN_name.py -``` - -Where `_NN_` is a numeric prefix controlling execution order (e.g., `_10_`, `_20_`, `_50_`). - -| Source | Path | -|---|---| -| Core extensions | `/a0/extensions/python//` | -| Plugin extensions | `/a0/plugins//extensions/python//` | -| User extensions | `/a0/usr/extensions/python//` | -| Agent profile extensions | `/a0/agents//extensions//` | -| User plugin extensions | `/a0/usr/plugins//extensions/python//` | - -### Python Extension Hook Points - -Complete list of available hook points: - -| Hook Point | When It Fires | Common Use | -|---|---|---| -| `agent_init` | Agent is initialized | Load configs, set defaults | -| `system_prompt` | System prompt is being assembled | Inject prompt content | -| `monologue_start` | Agent monologue begins | Pre-processing, state setup | -| `message_loop_start` | Before message processing loop | Pre-loop setup | -| `message_loop_prompts_before` | Before prompt assembly in loop | Modify prompt inputs | -| `message_loop_prompts_after` | After prompt assembly in loop | Add context (memory recall lives here) | -| `before_main_llm_call` | Before the LLM API call | Modify prompts, add context | -| `util_model_call_before` | Before utility model calls | Modify utility prompts | -| `response_stream` | When response streaming begins | Initialize stream handlers | -| `response_stream_chunk` | Per response chunk received | Transform output, collect data | -| `response_stream_end` | Response streaming complete | Finalize, analyze full response | -| `reasoning_stream` | Reasoning/thinking stream begins | Monitor reasoning | -| `reasoning_stream_chunk` | Per reasoning chunk | Collect reasoning data | -| `reasoning_stream_end` | Reasoning stream complete | Analyze reasoning | -| `tool_execute_before` | Before a tool runs | Validation, logging, safety checks | -| `tool_execute_after` | After a tool runs | Post-process results | -| `hist_add_before` | Before adding to history | Modify history entries | -| `hist_add_tool_result` | After tool result added to history | Log tool results | -| `message_loop_end` | After message processing loop | Post-loop cleanup | -| `monologue_end` | Agent monologue complete | Memorization, cleanup | -| `process_chain_end` | Entire processing chain done | Final cleanup | -| `job_loop` | Background job loop tick | Periodic background tasks | -| `error_format` | Error is being formatted | Custom error messages | -| `startup_migration` | Framework startup | Data migrations | -| `banners` | Startup banners displayed | Add custom banners | -| `embedding_model_changed` | Embedding model changed | Reload vector stores (fired programmatically, not a directory-based hook) | -| `user_message_ui` | User message from UI | Pre-process user input | -| `webui_ws_connect` | WebSocket client connects | Session setup | -| `webui_ws_disconnect` | WebSocket client disconnects | Session cleanup | -| `webui_ws_event` | WebSocket event received | Handle custom WS events | - -### The `@extensible` Decorator (Implicit Extension Points) - -Any framework function decorated with `@extensible` automatically gets two extension points: - -``` -_functions///start -_functions///end -``` - -The path mapping converts Python module paths and qualified names using `/` separators: -- Module `agent.py` → `agent` -- Class method `Agent.handle_exception` → `Agent/handle_exception` -- Full path: `_functions/agent/Agent/handle_exception/start` - -For nested modules like `helpers.history`, a method `History.add` would map to `_functions/helpers/history/History/add/start`. - -For example, a function `Agent.handle_exception` in module `agent` creates: -- `_functions/agent/Agent/handle_exception/start` -- `_functions/agent/Agent/handle_exception/end` - -Extensions in these directories receive a `data` dict with: -- `data["args"]` — positional args (mutable) -- `data["kwargs"]` — keyword args (mutable) -- `data["result"]` — set this to short-circuit the function -- `data["exception"]` — set to a `BaseException` to force-raise - -This is used by plugins like `_error_retry` to wrap core agent methods. - -### WebUI Extensions (JavaScript) - -Client-side extensions live under `extensions/webui//`: - -| Hook Point | When It Fires | -|---|---| -| `json_api_call_before` | Before a JSON API request | -| `json_api_call_after` | After a JSON API response | -| `fetch_api_call_before` | Before a fetch API request | -| `fetch_api_call_after` | After a fetch API response | -| `get_message_handler` | Register custom message renderers | -| `set_messages_before_loop` | Before messages are rendered | -| `set_messages_after_loop` | After messages are rendered | -| `webui_ws_push` | WebSocket push to client | - -### Example: Creating an Extension - -Based on the actual `_example` profile in `/a0/agents/_example/extensions/agent_init/_10_example_extension.py`: - -```python -# extensions/python/agent_init/_15_my_extension.py -from helpers.extension import Extension - -class MyExtension(Extension): - async def execute(self, **kwargs): - # Access the agent - agent = self.agent - context = agent.context - - # Extension logic — kwargs content depends on the hook point - agent.agent_name = "CustomAgent" + str(agent.number) -``` - -### Extension Execution Order - -Extensions execute in numeric order based on filename prefix: - -``` -_10_first.py # Runs first -_20_second.py # Runs second -_50_third.py # Runs third -``` - -Use 10-number increments to leave room for future extensions. - ---- - -## Creating API Endpoints - -API endpoints serve the Web UI and external clients using Flask. - -### Import Path - -```python -from helpers.api import ApiHandler -from flask import Request, Response -``` - -### ApiHandler Base Class - -```python -class ApiHandler: - def __init__(self, app: Flask, thread_lock: ThreadLockType): - self.app = app - self.thread_lock = thread_lock - - # Override these class methods to configure behavior: - @classmethod - def requires_loopback(cls) -> bool: return False # Restrict to localhost - @classmethod - def requires_api_key(cls) -> bool: return False # Require API key - @classmethod - def requires_auth(cls) -> bool: return True # Require auth session - @classmethod - def get_methods(cls) -> list[str]: return ["POST"] # HTTP methods - @classmethod - def requires_csrf(cls) -> bool: return cls.requires_auth() # CSRF protection - - # Implement this: - async def process(self, input: dict, request: Request) -> dict | Response: - pass - - # Utility: get or create an agent context - def use_context(self, ctxid: str, create_if_not_exists: bool = True) -> AgentContext: - ... -``` - -### Where API Endpoints Live - -| Location | Purpose | -|---|---| -| `/a0/api/` | Core API endpoints | -| `/a0/plugins//api/` | Plugin API endpoints | -| `/a0/usr/plugins//api/` | User plugin API endpoints | - -Endpoints are auto-discovered by filename. The route is derived from the filename (e.g., `my_endpoint.py` -> `/api/my_endpoint`). - -### Example: API Endpoint - -```python -# api/my_endpoint.py -from helpers.api import ApiHandler -from flask import Request, Response -from agent import AgentContext - -class MyEndpoint(ApiHandler): - @classmethod - def get_methods(cls) -> list[str]: - return ["GET", "POST"] - - async def process(self, input: dict, request: Request) -> dict: - param = input.get("param", "default") - - # Get or create agent context - ctxid = input.get("context", "") - context = self.use_context(ctxid) - - return { - "result": f"processed {param}", - "context": context.id, - } -``` - ---- - -## Creating Agent Profiles - -Agent profiles define specialized subordinates with custom prompts and behaviors. - -> For a guided, step-by-step wizard (scope selection, `agent.yaml` schema, prompt overrides, tool/extension stubs, test checklist) use the dedicated `/a0/skills/a0-create-agent/SKILL.md` skill. - -### Profile Directory Structure - -``` -agents// -+-- agent.yaml # Required: profile metadata -+-- prompts/ # Optional: prompt overrides -| +-- agent.system.main.role.md # Role definition (most common override) -| +-- agent.system.main.communication.md # Communication style -| +-- agent.system.tool..md # Tool-specific prompts -+-- tools/ # Optional: profile-specific tools -| +-- my_tool.py -+-- extensions/ # Optional: profile-specific extensions - +-- / - +-- _NN_extension.py -``` - -### agent.yaml Format - -The actual format is simple YAML with only three fields: - -```yaml -title: Developer -description: Agent specialized in complex software development. -context: Use this agent for software development tasks, including writing code, - debugging, refactoring, and architectural design. -``` - -| Field | Purpose | -|---|---| -| `title` | Display name shown in UI and agent selection | -| `description` | Brief description of the agent's specialization | -| `context` | Instructions for when to delegate to this profile | - -> [!NOTE] -> There is **no** model configuration, temperature, or allowed_tools in the profile YAML. `agent.yaml` contains only `title`, `description`, and `context`. Profile-specific Main/Utility model settings are managed by the `_model_config` plugin in `usr/agents//plugins/_model_config/config.json`. Tool availability is controlled by plugin activation. - -### Where Profiles Live - -| Location | Purpose | -|---|---| -| `/a0/agents/` | Core profiles (default, agent0, developer, hacker, researcher) | -| `/a0/usr/agents/` | User-created profiles (survives updates) | - -### Prompt Override Mechanism - -Profiles inherit all prompts from the `default/` profile. To customize behavior, place prompt files with the **same name** in your profile's `prompts/` directory. The framework searches profile-specific prompts first, then falls back to the default. - -The most common override is `agent.system.main.role.md` which defines the agent's role and specialization. - -### Example: Creating a Profile - -```yaml -# /a0/usr/agents/data-analyst/agent.yaml -title: Data Analyst -description: Agent specialized in data analysis, visualization, and statistical modeling. -context: Use this agent for data analysis tasks, creating visualizations, statistical - analysis, and working with datasets in Python. -``` - -```markdown - - -## Your role -You are a specialized data analysis agent. -Your expertise includes: -- Python data analysis (pandas, numpy, scipy) -- Data visualization (matplotlib, seaborn, plotly) -- Statistical modeling and hypothesis testing -- SQL queries and database analysis -- Data cleaning and preprocessing - -## Process -1. Understand the data and the question -2. Choose appropriate tools and methods -3. Execute analysis with code_execution_tool -4. Visualize results when applicable -5. Provide clear interpretation of findings -``` - -### Reference: The `_example` Profile - -The framework includes a complete example profile at `/a0/agents/_example/` that demonstrates: -- Custom tool: `/a0/agents/_example/tools/example_tool.py` -- Custom extension: `/a0/agents/_example/extensions/agent_init/_10_example_extension.py` -- Tool prompt: `/a0/agents/_example/prompts/agent.system.tool.example_tool.md` -- Role prompt: `/a0/agents/_example/prompts/agent.system.main.role.md` - ---- - -## Prompt System - -Agent Zero assembles system prompts from **named fragments** using includes and variable substitution. - -### Prompt File Naming Convention - -Prompt files follow a dot-separated naming scheme: - -``` -agent.system.main.md # Main system prompt (entry point) -agent.system.main.role.md # Role definition -agent.system.main.communication.md # Communication style -agent.system.tool..md # Tool usage instructions -agent.system.tools.md # Tools overview -agent.system.projects.main.md # Project system -agent.system.secrets.md # Secret handling -agent.system.skills.md # Skills listing -agent.system.datetime.md # Current date/time -agent.context.extras.md # Context extras -fw.*.md # Framework messages (errors, hints, etc.) -``` - -### Where Prompts Live - -| Location | Priority | Purpose | -|---|---|---| -| `/a0/agents//prompts/` | Highest | Profile-specific overrides | -| `/a0/usr/agents//prompts/` | High | User profile overrides | -| `/a0/plugins//prompts/` | Normal | Plugin-provided prompts | -| `/a0/usr/plugins//prompts/` | Normal | User plugin prompts | -| `/a0/prompts/` | Base | Core framework prompts | - -The framework searches directories in priority order and uses the **first match** found. - -### Include Mechanism - -Prompts can include other fragments using double-brace `include` directives. - -The syntax uses opening double-brace, the keyword, and closing double-brace: - -| Directive | Purpose | -|---|---| -| `{{include "agent.system.main.role.md"}}` | Include a named prompt fragment | -| `{{include "agent.system.main.communication.md"}}` | Include another fragment | -| `{{include original}}` | Include the same file from the next lower-priority directory | - -The `include original` directive is particularly useful for **extending** rather than fully **replacing** a prompt — your override can include the base version and add to it. - -### Variable Substitution - -Prompts support `{{variable_name}}` placeholders that are replaced at render time with values passed from the framework or plugin configuration. - -### Conditional Blocks - -Prompts support conditional rendering based on variables. - -### Reading Prompts in Code - -```python -# From within an Agent method: -content = self.read_prompt("fw.some_message.md", variable1="value1") - -# From helpers: -from helpers.files import read_prompt_file -content = read_prompt_file("template.md", _directories=[...], var="value") -``` - ---- - -## Creating Skills - -Skills are reusable instruction bundles that the agent loads on demand via the `skills_tool`. Each skill lives in a directory containing a `SKILL.md` file with YAML frontmatter. - -| Location | Purpose | -|---|---| -| `/a0/skills/` | Core skills (shipped with framework) | -| `/a0/usr/skills/` | User-created skills (survives updates) | - -The agent interacts with skills through JSON tool calls: +Load references with: ```json -{"tool_name": "skills_tool:list", "tool_args": {}} -{"tool_name": "skills_tool:load", "tool_args": {"skill_name": "my-skill"}} +{"tool_name": "skills_tool:read_file", "tool_args": {"skill_name": "a0-development", "file_path": "references/.md"}} ``` -> For the complete skill creation wizard — including SKILL.md format, frontmatter fields, directory structure, best practices, and examples — load the `build-skill` skill. - ---- - -## Working with Projects - -Projects provide isolated workspaces with custom configuration. - -> Projects are typically created and managed via the Web UI. The `.a0proj/` directory and `project.json` are auto-generated when you create a project through the UI. - -### Project Structure - -``` -/a0/usr/projects// -+-- .a0proj/ -| +-- project.json # Project configuration -| +-- agents.json # Per-project agent overrides -| +-- variables.env # Non-sensitive variables -| +-- secrets.env # Encrypted secrets -| +-- memory/ # Project-specific memory -| +-- index.faiss -| +-- index.pkl -| +-- embedding.json -+-- / # Your project files (working directory) -``` - -### project.json Format - -```json -{ - "title": "My Project", - "description": "Project description", - "instructions": "Markdown instructions for the agent when this project is active", - "color": "#3a86ff", - "git_url": "", - "memory": "own", - "file_structure": { - "enabled": true, - "max_depth": 5, - "max_files": 20, - "max_folders": 20, - "max_lines": 250, - "gitignore": ".a0proj/\nvenv/\n**/__pycache__/\n**/node_modules/\n**/.git/\n" - } -} -``` - -| Field | Purpose | +| Need | Read | |---|---| -| `title` | Display name | -| `description` | Brief description | -| `instructions` | Markdown injected into agent system prompt when project is active | -| `color` | UI accent color (hex) | -| `git_url` | Optional Git repository URL | -| `memory` | `"own"` for project-specific memory, or shared | -| `file_structure` | Controls the working directory tree shown to the agent | +| Runtime split, root layout, discovery order, path and port boundaries | `references/architecture-runtime.md` | +| DOX edit workflow, when to update docs, file-level DOX checks | `references/dox-workflow.md` | +| Tool contracts, locations, prompts, and verification | `references/tools.md` | +| Python/WebUI extension discovery, hook points, ordering, implicit hooks | `references/extensions.md` | +| HTTP API, WebSocket handlers, WebUI extension surfaces | `references/api-webui.md` | +| Agent profiles, prompts, skills, projects | `references/agents-prompts-skills-projects.md` | +| Plugin-first workflow, where to put new work, handoffs to plugin skills | `references/plugins-workflow.md` | ---- +## Working Flow -## Plugin System Overview +1. Classify the request: tool, extension, API/WebUI, profile, prompt, skill, project, plugin, runtime, or docs. +2. Read the root `AGENTS.md`, then the nearest child `AGENTS.md` files for the target paths. +3. Read the focused reference file from this skill. +4. Inspect the current source files named by the reference before making a claim or patch. +5. Keep changes narrow and in the repo-owned surface. Prefer `usr/` for user-created runtime content, but do not document ignored user state unless requested. +6. Update DOX when a durable contract, path, behavior, workflow, responsibility, or verification rule changes. +7. Run targeted checks from the relevant DOX file. For skill-only changes, at minimum verify frontmatter parsing, reference paths, and markdown sanity. -Plugins are the **primary extension mechanism** in Agent Zero. A plugin can bundle tools, extensions, prompts, API endpoints, helpers, and UI components into a self-contained package. +## Handoffs -> For all plugin tasks — creating, reviewing, managing, contributing, or debugging plugins — load the `a0-plugin-router` skill, which routes to the appropriate specialist skill. +- Plugin creation: load `a0-create-plugin`. +- Plugin management or installation: load `a0-manage-plugin`. +- Plugin debugging: load `a0-debug-plugin`. +- Plugin review or publishing: load `a0-review-plugin` or `a0-contribute-plugin`. +- Agent profile creation: load `a0-create-agent`. +- Skill creation or skill format work: load `build-skill`. -### Core Plugins +## Closeout -The framework ships with these core plugins in `/a0/plugins/`: - -| Plugin | Purpose | -|---|---| -| `_code_execution` | Terminal, Python, Node.js code execution | -| `_memory` | Persistent vector memory system | -| `_text_editor` | File read/write/patch with line numbers | -| `_model_config` | LLM model selection and configuration | -| `_browser` | Direct browser automation and WebUI viewing | -| `_infection_check` | Prompt injection safety checks | -| `_error_retry` | Retry on critical exceptions | -| `_email_integration` | Email communication via IMAP/SMTP | -| `_telegram_integration` | Telegram bot integration | -| `_chat_branching` | Branch chats from any message | -| `_promptinclude` | Persistent behavioral rules (*.promptinclude.md) | -| `_plugin_installer` | Install plugins from ZIP/Git/Hub | -| `_plugin_scan` | Security scanning for plugins | -| `_plugin_validator` | Plugin manifest and code validation | - ---- - -## Common Patterns Reference - -### Accessing Agent Context - -```python -# Shared across all agents in a conversation -context = self.agent.context -data = context.data # dict-like shared state - -# Store data -data["my_key"] = my_value - -# Retrieve data -value = data.get("my_key", default) -``` - -### Using File Helpers - -```python -from helpers import files - -# File operations -content = files.read_file("path/to/file") -files.write_file("path/to/file", content) -exists = files.exists("path/to/file") - -# Read and render a prompt file -content = files.read_prompt_file("template.md", _directories=[...], var="value") -``` - -### Console Output - -```python -from helpers.print_style import PrintStyle - -PrintStyle.hint("Informational message") -PrintStyle.warning("Warning message") -PrintStyle.error("Error message") -PrintStyle(font_color="#85C1E9").print("Custom styled output") -``` - -### Error Handling - -```python -from helpers.tool import Response - -try: - result = await risky_operation() -except Exception as e: - PrintStyle.error(f"Operation failed: {e}") - return Response(message=f"Error: {e}", break_loop=False) -``` - ---- - -## Development Workflow - -When building features for Agent Zero: - -### 1. Choose Your Extension Point - -| Want to... | Use | -|---|---| -| Add a new agent capability | **Tool** (in a plugin) | -| Hook into agent lifecycle | **Extension** (in a plugin) | -| Add Web UI functionality | **API endpoint** + **WebUI extension** | -| Create a specialized agent | **Agent profile** | -| Bundle reusable instructions | **Skill** | -| Package everything together | **Plugin** (recommended) | - -### 2. Develop in User Space - -- New plugins -> `/a0/usr/plugins//` -- New profiles -> `/a0/usr/agents//` -- New skills -> `/a0/usr/skills//` -- New extensions -> `/a0/usr/extensions/python//` - -### 3. Test and Iterate - -- **Local dev**: Run `python run_ui.py` (default port 50001 at `http://localhost:50001`) -- **Docker**: Restart the container or use the UI restart button; check logs with `docker logs -f ` -- Test with minimal input first -- Verify in the Web UI - -### 4. Contributing - -For contribution guidelines, see `/a0/docs/contribution.md`. For plugin contributions to the community Plugin Index, load the `a0-contribute-plugin` skill. - ---- - -## Best Practices - -### DO -- Use the **plugin system** for new features (see `a0-create-plugin` skill) -- Follow existing code patterns and conventions -- Write clear docstrings and comments -- Handle errors gracefully in tools and extensions -- Create prompt fragments for every tool (`agent.system.tool..md`) -- Develop in `/a0/usr/` directories to survive updates -- Test with the `_example` profile as a reference -- Use `from helpers.*` imports (not `from python.helpers.*`) - -### DON'T -- Modify files in `/a0/plugins/` or `/a0/tools/` directly (use usr/ space) -- Hardcode paths or configuration values -- Skip creating prompt files for tools -- Ignore the plugin system (it's the intended extension mechanism) -- Mix sync and async code carelessly -- Access internal structures when helpers exist - ---- - -## Quick Reference: Key Files - -| File | Purpose | -|---|---| -| `/a0/agent.py` | Core `Agent`, `AgentContext`, `AgentConfig` classes | -| `/a0/helpers/tool.py` | `Tool` + `Response` base classes | -| `/a0/helpers/extension.py` | `Extension` base + `@extensible` decorator | -| `/a0/helpers/api.py` | `ApiHandler` base class | -| `/a0/helpers/files.py` | File ops + prompt reading | -| `/a0/helpers/plugins.py` | Plugin system manager | -| `/a0/helpers/print_style.py` | Console output formatting | -| `/a0/agents/_example/` | Reference example profile with tool + extension | -| `/a0/prompts/agent.system.main.md` | Main system prompt entry point | +Report the exact files changed, the grounding checks used, whether DOX was updated or intentionally left unchanged, and what verification ran. If a claim depends on a live Docker runtime, include the runtime proof, not only checkout evidence. diff --git a/skills/a0-development/references/AGENTS.md b/skills/a0-development/references/AGENTS.md new file mode 100644 index 000000000..0b913600c --- /dev/null +++ b/skills/a0-development/references/AGENTS.md @@ -0,0 +1,38 @@ +# A0 Development References DOX + +## Purpose + +- Own focused reference files loaded by the `a0-development` skill on demand. +- Keep detailed framework-development guidance grounded in current source files and nearest DOX contracts. + +## Ownership + +- `architecture-runtime.md` owns runtime, path, discovery-order, and port-boundary guidance. +- `dox-workflow.md` owns the edit and closeout workflow for DOX-governed changes. +- `tools.md` owns core and plugin tool development contracts. +- `extensions.md` owns backend and frontend extension contracts. +- `api-webui.md` owns HTTP API, WebSocket, and WebUI extension guidance. +- `agents-prompts-skills-projects.md` owns profiles, prompt fragments, skills, and project metadata guidance. +- `plugins-workflow.md` owns plugin-first placement and handoff guidance. + +## Local Contracts + +- Every reference file must list source anchors or DOX anchors that can be checked in the repository. +- Prefer pointing to narrower `AGENTS.md` files instead of copying long subtree contracts. +- Keep examples minimal and compatible with the current helper classes. +- Do not include hardcoded default WebUI ports or environment-specific credentials. + +## Work Guidance + +- Update the focused reference file when source or DOX changes make its guidance stale. +- If a reference starts duplicating a specialist skill, shorten it and hand off to that skill instead. +- Treat checked-in examples as examples, not authority, when they conflict with current discovery code. + +## Verification + +- Manually read changed references for broken relative paths, stale source anchors, and duplicated specialist-skill material. +- After changing reference names, load `a0-development` and confirm the file tree exposes the new paths through `skills_tool`. + +## Child DOX Index + +No child DOX files. diff --git a/skills/a0-development/references/agents-prompts-skills-projects.md b/skills/a0-development/references/agents-prompts-skills-projects.md new file mode 100644 index 000000000..27f5eac17 --- /dev/null +++ b/skills/a0-development/references/agents-prompts-skills-projects.md @@ -0,0 +1,95 @@ +# Agents, Prompts, Skills, And Projects + +## Source Anchors + +- Agent profiles: `/a0/helpers/subagents.py`, `/a0/agents/AGENTS.md` +- Prompt rendering: `/a0/agent.py`, `/a0/helpers/files.py`, `/a0/prompts/AGENTS.md` +- Skill runtime: `/a0/helpers/skills.py`, `/a0/tools/skills_tool.py`, `/a0/skills/AGENTS.md` +- Project metadata: `/a0/helpers/projects.py`, `/a0/api/projects.py`, `/a0/webui/components/projects/` + +## Agent Profiles + +Bundled profiles live under `agents//`. User-created profiles live under `usr/agents//`. Plugin-distributed profiles live under plugin `agents/` directories. + +The current profile loader accepts `agent.yaml` or `agent.json` and validates through `helpers.subagents.SubAgentListItem` / `SubAgent` fields: + +| Field | Meaning | +|---|---| +| `title` | Human-readable display name. Defaults to profile name if empty. | +| `description` | Brief specialization. | +| `context` | Delegation guidance for when to use the profile. | +| `enabled` | Optional availability flag in list contexts. | + +Bundled `agent.yaml` files currently use `title`, `description`, and `context`. Model settings are not read from `agent.yaml`; the `_model_config` plugin owns model configuration and scoped overrides. + +Profile folders may contain `prompts/`, `tools/`, `extensions/`, and `skills/`, but verify discovery code before relying on example layout. Source and DOX beat stale examples. + +## Prompt System + +Agents render prompt fragments through `Agent.read_prompt(...)`, which calls `helpers.files.read_prompt_file(...)`. + +Prompt capabilities: + +- Placeholder replacement with `{{variable_name}}`. +- Conditional blocks with `{{if ...}} ... {{endif}}`. +- Include directives such as `{{include "file.md"}}`. +- `{{include original}}` to include the same file from a lower-priority directory. + +Prompt locations include: + +| Location | Use | +|---|---| +| `prompts/` | Core framework prompts. | +| `agents//prompts/` | Bundled profile overrides. | +| `usr/agents//prompts/` | User profile overrides. | +| `plugins//prompts/` | Bundled plugin prompt additions or overrides. | +| `usr/plugins//prompts/` | User plugin prompts. | + +Prompt changes can change agent behavior. Keep edits narrow and run targeted prompt, budget, snapshot, tool, or behavior tests. + +## Skills + +Skills are directories containing `SKILL.md` frontmatter plus optional `references/`, `scripts/`, or `assets/`. + +Skill roots come from `helpers.skills.get_skill_roots(...)`, including bundled skills, user skills, project metadata, profile skills, and plugin skills. + +`skills_tool` actions: + +| Action | Purpose | +|---|---| +| `list` | List available skills without full content. | +| `search` | Search skill metadata and triggers. | +| `load` | Load `SKILL.md` body and show the skill file tree. | +| `read_file` | Read a file inside the skill directory, such as `references/foo.md`. | + +Keep always-loaded `SKILL.md` concise. Move long examples, schemas, policies, and variant-specific details into one-level-deep `references/` files and tell the agent when to read them. + +Use `build-skill` for skill creation and skill format work. + +## Projects + +Projects live under `usr/projects//` and store metadata in `.a0proj/`. + +Important project files and folders: + +| Path | Purpose | +|---|---| +| `.a0proj/project.json` | Project title, description, instructions, color, git URL, include-AGENTS option, and file-structure settings. | +| `.a0proj/instructions/` | Additional text instruction files. | +| `.a0proj/knowledge/` | Project knowledge files. | +| `.a0proj/variables.env` | Non-sensitive project variables. | +| `.a0proj/secrets.env` | Encrypted project secrets. | +| `.a0proj/agents/` | Per-project agent profile material. | +| `.a0proj/skills/` | Project-scoped skills. | +| `.a0proj/mcp_servers.json` | Project MCP server configuration. | + +`helpers.projects.BasicProjectData` currently normalizes `title`, `description`, `instructions`, `include_agents_md`, `color`, `git_url`, and `file_structure`. `EditProjectData` adds runtime/editing fields such as `variables`, `secrets`, `mcp_servers`, `subagents`, and git status. + +Project file-structure injection uses settings for `enabled`, `max_depth`, `max_files`, `max_folders`, `max_lines`, and `gitignore`. + +## Verification + +- Run profile-loading tests when changing agent profile schema or discovery. +- Inspect rendered prompts when changing prompt filenames, include behavior, placeholders, or prompt order. +- Run skill runtime/catalog tests after changing skill loading, search, active/hidden behavior, or skill format. +- For project changes, test create/load/edit paths and project prompt injection when relevant. diff --git a/skills/a0-development/references/api-webui.md b/skills/a0-development/references/api-webui.md new file mode 100644 index 000000000..7ee2e4cd6 --- /dev/null +++ b/skills/a0-development/references/api-webui.md @@ -0,0 +1,93 @@ +# API And WebUI + +## Source Anchors + +- HTTP handler base and route registration: `/a0/helpers/api.py` +- API DOX: `/a0/api/AGENTS.md` +- WebSocket handler base: `/a0/helpers/ws.py` +- WebUI shell DOX: `/a0/webui/AGENTS.md` +- Component and JS DOX: `/a0/webui/components/AGENTS.md`, `/a0/webui/js/AGENTS.md` +- Frontend extension loading: `/a0/webui/js/extensions.js` + +## HTTP API Contract + +HTTP API handlers derive from `helpers.api.ApiHandler`: + +```python +from flask import Request, Response +from helpers.api import ApiHandler + +class MyEndpoint(ApiHandler): + @classmethod + def get_methods(cls) -> list[str]: + return ["POST"] + + async def process(self, input: dict, request: Request) -> dict | Response: + return {"ok": True} +``` + +Defaults from `ApiHandler`: + +| Method | Default | +|---|---| +| `requires_loopback()` | `False` | +| `requires_api_key()` | `False` | +| `requires_auth()` | `True` | +| `get_methods()` | `["POST"]` | +| `requires_csrf()` | `requires_auth()` | + +Override these only when the endpoint contract requires it. Keep auth and CSRF protection intact for browser-facing state changes. + +## API Routes + +`helpers.api.register_api_route(...)` registers: + +```text +/api/ +``` + +Resolution: + +- Built-in endpoint `api/.py` becomes `/api/`. +- Plugin endpoint `plugins//api/.py` becomes `/api/plugins//`. + +Return a Flask `Response` for files, redirects, custom status codes, and plain text. Return a dictionary for JSON success payloads. + +Direct files under `api/*.py` require matching `api/*.py.dox.md`. + +## WebSocket Handlers + +WebSocket handlers live in `api/ws_*.py` or plugin API folders and derive from `helpers.ws.WsHandler`: + +```python +from helpers.ws import WsHandler + +class MyHandler(WsHandler): + async def process(self, event: str, data: dict, sid: str) -> dict | None: + return {"ok": True} +``` + +`WsHandler` mirrors `ApiHandler` security flags: auth defaults to `True`, CSRF defaults to auth, API-key and loopback default to `False`. Handlers should validate event data before using it and avoid returning secrets or unfiltered exception details. + +## WebUI Work + +Follow the nearest WebUI DOX before changing frontend files: + +- `webui/AGENTS.md` for the shell, CSS, assets, vendor, and extension loader. +- `webui/js/AGENTS.md` for stores, modals, API helpers, and JS infrastructure. +- `webui/components/AGENTS.md` and child docs for Alpine components. + +Patterns: + +- Store-dependent content should be gated by a `template x-if` guard before using `$store.`. +- Stores are registered with `createStore` from `/js/AlpineStore.js`. +- Modals use `openModal(path)` and `closeModal()` from `/js/modals.js`. +- Plugin settings UIs bind persisted plugin values to `config.*` and modal-only state/actions to `context.*`. +- Plugin UI should use the A0 notification system instead of inline success/error boxes. + +## Verification + +- Run endpoint-specific tests or nearest API/WebSocket tests for handler behavior. +- For auth, CSRF, upload/download, tunnel, or file endpoints, run security-focused regressions. +- For WebUI changes, use targeted component/store tests or a browser smoke check when practical. +- Check file-level DOX coverage when touching direct `api/*.py` modules. diff --git a/skills/a0-development/references/architecture-runtime.md b/skills/a0-development/references/architecture-runtime.md new file mode 100644 index 000000000..97e7b09cd --- /dev/null +++ b/skills/a0-development/references/architecture-runtime.md @@ -0,0 +1,79 @@ +# Architecture And Runtime + +## Source Anchors + +- Root contract: `/a0/AGENTS.md` +- WebUI entry point: `/a0/run_ui.py` +- Runtime arguments and WebUI port resolution: `/a0/helpers/runtime.py` +- Docker Python runtimes: `/a0/docker/base/fs/ins/install_python.sh` +- Docker framework activation: `/a0/docker/run/fs/ins/setup_venv.sh` +- Docker UI launch manager: `/a0/docker/run/fs/exe/self_update_manager.py` +- Search/discovery roots: `/a0/helpers/subagents.py`, `/a0/helpers/skills.py`, `/a0/helpers/projects.py` + +## Runtime Split + +Agent Zero has two Docker Python runtimes: + +| Runtime | Python | Purpose | +|---|---|---| +| `/opt/venv-a0` | 3.12.4 | Framework runtime. Runs the WebUI backend, API, scheduler, agent loop, framework imports, plugin hooks, and framework-side tools. | +| `/opt/venv` | 3.13 | Agent execution runtime. Use for Python code executed on behalf of the agent or user task dependencies. | + +Use `/opt/venv-a0` for framework import checks, WebUI startup checks, API/plugin hook behavior, and `py_compile` of framework code inside Docker. Use `/opt/venv` only when the feature explicitly targets agent/user code execution. + +Do not claim a package works in the framework because it imports in `/opt/venv`, and do not claim user-code execution works because it imports in `/opt/venv-a0`. + +## Ports And URLs + +Do not hardcode a WebUI default port in guidance. Discover the effective URL from: + +- WebUI startup output. +- Launcher or Docker published-port mapping. +- Explicit `--host` and `--port` arguments. +- `WEB_UI_HOST` and `WEB_UI_PORT` environment configuration. +- Live container inspection when the task targets a running runtime. + +`helpers.runtime.get_web_ui_port()` has a code fallback, and the Docker UI manager passes an internal container port. Those are implementation details, not a stable user-facing URL contract. + +## Root Paths + +- `/a0/` means the framework root inside the Docker runtime. +- In a local checkout, `/a0/` in documentation maps to the repository root. +- `usr/` contains user state, projects, settings, skills, plugins, chats, and workdirs. +- `tmp/` contains runtime caches and generated working files. +- Do not document ignored `usr/` or `tmp/` changes unless explicitly asked. + +When the user names a live Dockerized runtime, the live `/a0` tree is a separate artifact. Verify the file sync or runtime state directly before treating checkout code as live behavior. + +## Project Layout + +Key root areas: + +| Path | Purpose | +|---|---| +| `agent.py` | `Agent`, `AgentContext`, `AgentConfig`, prompt reading, tool loop. | +| `initialize.py` | Framework initialization and background loop startup. | +| `models.py` | Model provider and LiteLLM transport configuration. | +| `run_ui.py` | Flask/Socket.IO ASGI WebUI startup. | +| `api/` | HTTP API handlers and `ws_*.py` WebSocket handlers. | +| `helpers/` | Shared framework utilities and base contracts. | +| `tools/` | Core tool implementations. | +| `extensions/` | Built-in backend and WebUI extension points. | +| `plugins/` | Bundled system plugins. | +| `agents/` | Bundled agent profiles. | +| `prompts/` | Core prompt fragments. | +| `skills/` | Bundled skills. | +| `webui/` | Alpine.js frontend shell, components, CSS, assets, and vendor code. | + +## Discovery Order + +Agent-specific path resolution is handled by `helpers.subagents.get_paths(...)`. In broad terms, project and user/profile paths have higher priority than plugin and bundled defaults, then user root/plugin roots, then base defaults. Inspect `helpers/subagents.py` for exact order before changing discovery behavior. + +Skill discovery is handled by `helpers.skills.get_skill_roots(...)`. Skills may come from bundled `skills/`, user `usr/skills/`, project metadata, agent profile folders, and plugin roots. Loaded skills can expose additional files via `skills_tool action=read_file`. + +## Development Bias + +- Prefer plugins for new capabilities. +- Prefer `helpers/` only for reusable framework behavior. +- Prefer small, source-backed changes over broad rewrites. +- If an example conflicts with source discovery code or DOX, treat the example as stale until verified. diff --git a/skills/a0-development/references/dox-workflow.md b/skills/a0-development/references/dox-workflow.md new file mode 100644 index 000000000..8623fd468 --- /dev/null +++ b/skills/a0-development/references/dox-workflow.md @@ -0,0 +1,66 @@ +# DOX Workflow + +## Source Anchors + +- Root DOX contract: `/a0/AGENTS.md` +- Skill parent contract: `/a0/skills/AGENTS.md` +- Local skill contract: `/a0/skills/a0-development/AGENTS.md` +- Reference-file contract: `/a0/skills/a0-development/references/AGENTS.md` +- File-level DOX examples: `/a0/api/*.py.dox.md`, `/a0/tools/*.py.dox.md`, `/a0/helpers/*.py.dox.md` + +## Before Editing + +1. Read the root `AGENTS.md`. +2. Identify every path you expect to touch. +3. Walk from the root to each target path. +4. Read every `AGENTS.md` found on that route. +5. If a parent `AGENTS.md` lists a child whose scope contains the path, read that child and continue. +6. Use the nearest `AGENTS.md` as the local contract. Parent docs still apply. +7. If docs conflict, the closer doc controls local details, but no child weakens DOX. + +Do not rely on memory for DOX. Re-read the current files. + +## When To Update DOX + +Update the nearest owning `AGENTS.md` when a meaningful change affects: + +- Purpose, ownership, responsibilities, or scope. +- Durable structure, directories, file contracts, or child indexes. +- Runtime behavior, required inputs/outputs, side effects, or verification rules. +- User or agent workflow rules. +- Creation, deletion, rename, or movement of an `AGENTS.md` file. + +Update parent docs when parent-level structure or child indexes change. Remove stale or contradictory text rather than explaining old history. + +Small implementation edits that do not change contracts may leave DOX unchanged, but still perform the DOX closeout pass and say why docs stayed unchanged. + +Do not create or update DOX under ignored `usr/` or `tmp/` unless explicitly requested. + +## File-Level DOX + +Some directories require per-file `.dox.md` companions: + +| Directory | Requirement | +|---|---| +| `api/` | Every direct `*.py` endpoint or `ws_*.py` module must have matching `*.py.dox.md`. | +| `tools/` | Every direct `*.py` tool module must have matching `*.py.dox.md`. | +| `helpers/` | Many helper modules use file-level DOX; follow `helpers/AGENTS.md` before changing helper behavior. | + +When adding, deleting, renaming, or behaviorally changing one of those files, update the companion DOX in the same change. + +## Closeout + +1. Re-check changed paths against the DOX chain. +2. Update nearest owning docs and affected parents or children. +3. Refresh affected Child DOX Index tables. +4. Remove stale or contradictory text. +5. Run relevant verification from the nearest DOX. +6. Report docs intentionally left unchanged and why. + +## Practical Verification + +- `git diff --check` for whitespace. +- Targeted tests named by the relevant DOX file. +- Manual read-through for skill/reference link changes. +- Shell coverage checks for file-level DOX when touching `api/` or `tools/`. +- Runtime or live-container proof when the user asks about the running Dockerized system. diff --git a/skills/a0-development/references/extensions.md b/skills/a0-development/references/extensions.md new file mode 100644 index 000000000..c04112089 --- /dev/null +++ b/skills/a0-development/references/extensions.md @@ -0,0 +1,150 @@ +# Extensions + +## Source Anchors + +- Extension base and discovery: `/a0/helpers/extension.py` +- Backend extension DOX: `/a0/extensions/AGENTS.md`, `/a0/extensions/python/AGENTS.md` +- WebUI extension DOX: `/a0/extensions/webui/AGENTS.md` +- Plugin extension contract: `/a0/plugins/AGENTS.md` +- Example profile note: `/a0/agents/_example/AGENTS.md` + +## Python Extension Contract + +Backend extensions derive from `helpers.extension.Extension`: + +```python +from helpers.extension import Extension + +class MyExtension(Extension): + async def execute(self, **kwargs): + ... +``` + +`self.agent` may be `None` for startup or non-agent hooks. Match the arguments supplied by the hook point. Keep imports light because many extensions run in hot paths. + +## Python Discovery Layout + +`helpers.extension._get_extension_classes(...)` discovers backend extension classes through: + +```text +extensions/python// +``` + +using `helpers.subagents.get_paths(agent, "extensions/python", extension_point)`. + +Common locations: + +| Location | Use | +|---|---| +| `extensions/python//` | Built-in framework extension. | +| `plugins//extensions/python//` | Bundled plugin extension. | +| `usr/plugins//extensions/python//` | User plugin extension. | +| `usr/extensions/python//` | Standalone user extension. Prefer plugin packaging for durable features. | +| Project/profile roots resolved by `helpers.subagents.get_paths(...)` | Scope-specific extension overrides when discovery supports the path. Verify before copying examples. | + +The checked-in `_example` profile contains an older-looking `agents/_example/extensions/agent_init/...` sample. Current discovery code expects `extensions/python/`. Treat source code and DOX as authority before copying profile extension layout. + +## Ordering And Overrides + +- Files are sorted by filename. Numeric prefixes like `_10_`, `_20_`, `_50_` control order. +- Use gaps between prefixes so future extensions can fit between them. +- Discovery de-duplicates by module filename, preserving the first occurrence by search priority. +- Do not bypass secret masking, auth, persistence, or cleanup extensions for convenience. + +## Implicit `@extensible` Hooks + +Functions decorated with `@extensible` emit two implicit hook points: + +```text +_functions///start +_functions///end +``` + +The path preserves every module segment and nested qualname segment. Example: + +```text +helpers.something.Outer.Inner.__init__ +``` + +becomes: + +```text +_functions/helpers/something/Outer/Inner/__init__/start +_functions/helpers/something/Outer/Inner/__init__/end +``` + +Extensions receive a mutable `data` dict with `args`, `kwargs`, `result`, and `exception`. They may mutate inputs, short-circuit by setting `result`, or force/clear an exception. + +Do not use retired flattened `_functions` folder names. + +## Current Built-In Python Hook Directories + +Directory-backed built-in hook points currently include: + +```text +agent_init +banners +before_main_llm_call +error_format +hist_add_before +hist_add_tool_result +job_loop +message_loop_end +message_loop_prompts_after +message_loop_prompts_before +message_loop_start +monologue_end +monologue_start +process_chain_end +reasoning_stream +reasoning_stream_chunk +reasoning_stream_end +response_stream +response_stream_chunk +response_stream_end +startup_migration +system_prompt +tool_execute_after +tool_execute_before +user_message_ui +util_model_call_before +webui_ws_connect +webui_ws_disconnect +webui_ws_event +``` + +This list comes from the current `extensions/python/` tree. Re-check the tree before claiming the complete current set. + +## WebUI Extension Points + +Frontend extension files live under: + +```text +extensions/webui// +plugins//extensions/webui// +usr/plugins//extensions/webui// +``` + +Current built-in WebUI extension directories include: + +```text +fetch_api_call_after +fetch_api_call_before +get_message_handler +initFw_end +json_api_call_after +json_api_call_before +right-canvas-panels +right_canvas_register_surfaces +set_messages_after_loop +set_messages_before_loop +webui_ws_push +``` + +Plugin frontend HTML extensions should include a root Alpine scope and use `x-move-*` directives when targeting static breakpoints. JS extensions export a default function. + +## Verification + +- Run targeted lifecycle, prompt, stream, WebSocket, or WebUI extension tests for changed hook points. +- Smoke-test startup for `agent_init`, `startup_migration`, and `system_prompt` changes when practical. +- Check the exact directory path used by `helpers.extension` before adding profile or plugin extension files. diff --git a/skills/a0-development/references/plugins-workflow.md b/skills/a0-development/references/plugins-workflow.md new file mode 100644 index 000000000..39c94f393 --- /dev/null +++ b/skills/a0-development/references/plugins-workflow.md @@ -0,0 +1,91 @@ +# Plugins And Development Workflow + +## Source Anchors + +- Plugin contract: `/a0/plugins/AGENTS.md` +- Plugin helper code: `/a0/helpers/plugins.py` +- Plugin specialist skills: `/a0/skills/a0-plugin-router/SKILL.md`, `/a0/skills/a0-create-plugin/SKILL.md`, `/a0/skills/a0-debug-plugin/SKILL.md`, `/a0/skills/a0-review-plugin/SKILL.md` +- Root development contract: `/a0/AGENTS.md` + +## Plugin-First Rule + +Plugins are the primary way to extend Agent Zero. A plugin can bundle: + +- `plugin.yaml` +- `default_config.yaml` +- `hooks.py` +- `execute.py` +- `tools/` +- `api/` +- `helpers/` +- `prompts/` +- `skills/` +- `extensions/python/` +- `extensions/webui/` +- `webui/` +- plugin-local docs and assets + +Use root framework directories only when changing bundled framework behavior itself. For custom or experimental work, use `usr/plugins//` unless the task is explicitly to change a bundled plugin. + +## Imports And Runtime + +- Bundled plugins under `plugins/` may use `plugins....` imports. +- User plugins under `usr/plugins/` should use `usr.plugins....` imports. +- Avoid `sys.path` hacks and symlink-dependent imports. +- `hooks.py` runs inside the framework runtime (`/opt/venv-a0` in Docker). +- If a plugin must prepare the agent execution runtime or system packages, it must explicitly target that environment in a subprocess. + +## Manifest And Configuration + +Every plugin needs `plugin.yaml`. Runtime fields include: + +- `name` +- `title` +- `description` +- `version` +- `settings_sections` +- `per_project_config` +- `per_agent_config` +- `always_enabled` + +Defaults belong in `default_config.yaml`. Runtime user settings belong under `usr/`. + +Settings resolution order is project/profile, project, user/profile, user plugin config, then bundled `default_config.yaml`. + +## Activation And Cleanup + +- Global and scoped activation are independent. +- Activation files use `.toggle-1` for ON and `.toggle-0` for OFF. +- `always_enabled: true` forces ON and disables UI toggles. +- Plugin deletion or disablement should not leave unmanaged services, symlinks, or files outside plugin-owned paths unless explicitly documented with cleanup. + +## Routes And UI + +Plugin routes: + +| Route | Purpose | +|---|---| +| `GET /plugins//` | Static/plugin web assets. | +| `POST /api/plugins//` | Plugin API handler. | +| `POST /api/plugins` | Plugin management actions. | + +Plugin settings UIs should bind saved values to `config.*` and modal-only state/actions to `context.*` through `$store.pluginSettingsPrototype`. + +Plugin UI errors, warnings, success, and info should use the A0 notification system. + +## Workflow + +1. Decide whether the request is plugin-specific. If yes, load `a0-plugin-router`. +2. If creating a plugin, load `a0-create-plugin`. +3. If debugging a plugin, load `a0-debug-plugin`. +4. If reviewing or publishing a plugin, load `a0-review-plugin` or `a0-contribute-plugin`. +5. Read `plugins/AGENTS.md` and any plugin-local `AGENTS.md`. +6. Keep changes inside the plugin boundary unless shared framework behavior truly belongs in `helpers/` or root code. +7. Update plugin docs/DOX when user-visible behavior, configuration, routes, hooks, or cleanup changes. + +## Verification + +- Run plugin-specific tests after changing a bundled plugin. +- Run framework tests for touched tools, API handlers, extension points, settings, or WebUI surfaces. +- Smoke-test external-service, browser, desktop, or connector integrations when practical. +- For discovery banners/cards, verify rendering, dismiss behavior, ordering, and CTA behavior. diff --git a/skills/a0-development/references/tools.md b/skills/a0-development/references/tools.md new file mode 100644 index 000000000..632b53416 --- /dev/null +++ b/skills/a0-development/references/tools.md @@ -0,0 +1,76 @@ +# Tools + +## Source Anchors + +- Tool base class: `/a0/helpers/tool.py` +- Core tool contract: `/a0/tools/AGENTS.md` +- Tool dispatch path: `/a0/agent.py` +- Skills tool reference-file behavior: `/a0/tools/skills_tool.py` +- Example profile tool: `/a0/agents/_example/tools/example_tool.py` +- Prompt fragments: `/a0/prompts/AGENTS.md` + +## Contract + +All tools derive from `helpers.tool.Tool` and implement: + +```python +from helpers.tool import Tool, Response + +class MyTool(Tool): + async def execute(self, **kwargs) -> Response: + return Response(message="done", break_loop=False) +``` + +`Response` fields: + +| Field | Meaning | +|---|---| +| `message` | Text appended as the tool result and shown back to the agent. | +| `break_loop` | `True` stops the current message loop. | +| `additional` | Optional metadata added with the tool result. | + +`Tool` instances receive `agent`, `name`, `method`, `args`, `message`, and `loop_data`. Use `self.method` for method-style tools such as `skills_tool:load`. + +## Locations + +| Location | Use | +|---|---| +| `tools/` | Core framework tools. Use only for bundled framework behavior. | +| `plugins//tools/` | Bundled plugin tools. | +| `usr/plugins//tools/` | User plugin tools. This is the preferred place for custom plugin work. | +| `agents//tools/` | Profile-local tools. Verify current discovery before relying on profile examples. | + +Most new tools should be packaged in a plugin, not added directly to root `tools/`. + +## Prompt Contract + +Every tool needs an agent-facing prompt fragment so the model knows the tool name, JSON shape, arguments, and when to use it. + +Common locations: + +- Core tool prompt: `prompts/agent.system.tool..md` +- Plugin tool prompt: `plugins//prompts/agent.system.tool..md` +- User plugin prompt: `usr/plugins//prompts/agent.system.tool..md` +- Profile override prompt: `agents//prompts/agent.system.tool..md` + +When changing a tool name, argument shape, output behavior, safety rule, or `break_loop` behavior, update its prompt and tests together. + +## Progress And Interventions + +- Use `await self.set_progress(...)` when progress should be visible through the tool-output update extension. +- `self.add_progress(...)` only accumulates local progress text. +- For long-running or external-result workflows, follow `tools/AGENTS.md` and use `await self.agent.handle_intervention(...)` where pause/intervention flow matters. +- Sanitize and mask secrets before logging or returning outputs. + +## Core Tool DOX + +Direct files under `tools/*.py` require matching `tools/*.py.dox.md`. The companion file owns purpose, arguments, output, `break_loop`, side effects, prompt contract notes, dependencies, and verification. + +Plugin tool documentation belongs in that plugin's docs or DOX contract, not in root `tools/`. + +## Verification + +- Run targeted tests for changed tools. +- Run prompt/snapshot tests when tool instructions or output shape changes. +- For direct root tools, verify every `tools/*.py` has a matching `.py.dox.md`. +- If the tool is plugin-scoped, also run plugin-specific checks from the plugin's `AGENTS.md`.