add a0-setup-cli Skill and restore lexical trigger matching

Add a builtin `a0-setup-cli` skill for guiding host-side A0 connector setup, and restore the lightweight trigger-word based skill matching flow, which many users asked for. - add builtin `skills/a0-setup-cli/` with installer-first host setup guidance, container guardrails, fallback install paths, and example responses - fix `helpers.skills_cli` so builtin skills under `/skills` are discoverable, searchable, and validatable - restore trigger-pattern scoring in runtime `search_skills()` - re-enable `skills_tool:search` in the current tool flow - add lightweight lexical relevant-skill recall for the current user message without reintroducing memory/vector-db skill recall - update skill prompts to steer the agent toward search/load when requests match skill trigger phrases

Alessandro committed Apr 11, 2026 at 18:03 UTC 954eca35635388207bc8d4ae39a1c73ec0d23a38
12 files changed +379 -36
docs/README.md
+4
@@ -7,6 +7,7 @@ Welcome to the Agent Zero documentation hub. Whether you're getting started or d
7
8 - **[Quickstart Guide](quickstart.md):** Get up and running in 5 minutes with Agent Zero.
9 - **[Installation Guide](setup/installation.md):** Install scripts, updates, and advanced Docker setup (includes [How to Update](setup/installation.md#how-to-update-agent-zero)).
10 +- **[A0 CLI Connector](guides/a0-cli-connector.md):** Install the terminal-native connector, connect it to Agent Zero, and copy a setup brief for another agent.
11 - **[Self Update](guides/self-update.md):** How the in-app updater works (technical reference).
12 - **[VPS Deployment](setup/vps-deployment.md):** Deploy Agent Zero on a remote server.
13 - **[Development Setup](setup/dev-setup.md):** Set up a local development environment.
@@ -14,6 +15,7 @@ Welcome to the Agent Zero documentation hub. Whether you're getting started or d
15 ## User Guides
16
17 - **[Usage Guide](guides/usage.md):** Comprehensive guide to Agent Zero's features and capabilities.
18 +- **[A0 CLI Connector](guides/a0-cli-connector.md):** Terminal-first companion workflow for Agent Zero.
19 - **[Projects Tutorial](guides/projects.md):** Learn to create isolated workspaces with dedicated context and memory.
20 - **[API Integration](guides/api-integration.md):** Add external APIs without writing code.
21 - **[MCP Setup](guides/mcp-setup.md):** Configure Model Context Protocol servers.
@@ -69,6 +71,7 @@ Welcome to the Agent Zero documentation hub. Whether you're getting started or d
71 - [Self Update (technical)](guides/self-update.md)
72 - [VPS Deployment](setup/vps-deployment.md)
73 - [Development Setup](setup/dev-setup.md)
74 + - [A0 CLI Connector](guides/a0-cli-connector.md)
75
76 - [User Guides](#user-guides)
77 - [Usage Guide](guides/usage.md)
@@ -91,6 +94,7 @@ Welcome to the Agent Zero documentation hub. Whether you're getting started or d
94 - [Voice Interface](guides/usage.md#voice-interface)
95 - [Memory Management](guides/usage.md#memory-management)
96 - [Backup & Restore](guides/usage.md#backup--restore)
97 + - [A0 CLI Connector](guides/a0-cli-connector.md)
98 - [Projects Tutorial](guides/projects.md)
99 - [API Integration](guides/api-integration.md)
100 - [MCP Setup](guides/mcp-setup.md)
docs/guides/a0-cli-connector.md new
+66
@@ -0,0 +1,66 @@
1 +# A0 CLI Connector
2 +
3 +Agent Zero lives in Docker for a reason. That keeps it safer. The problem is that people see Docker and assume the agent can never really touch the code on their computer.
4 +
5 +A0 CLI is the answer to that.
6 +
7 +Agent Zero stays in Docker. A0 CLI installs on the host machine. That is what lets Agent Zero finally work on the real files on your real computer.
8 +
9 +For now, use the install commands below.
10 +
11 +## Quick Install
12 +
13 +**macOS / Linux:**
14 +```bash
15 +curl -LsSf https://raw.githubusercontent.com/agent0ai/a0-connector/main/install.sh | sh
16 +```
17 +
18 +**Windows (PowerShell):**
19 +```powershell
20 +irm https://raw.githubusercontent.com/agent0ai/a0-connector/main/install.ps1 | iex
21 +```
22 +
23 +**Manual fallback when uv is already installed or if URLs give 404:**
24 +```bash
25 +uv tool install git+https://github.com/agent0ai/a0-connector
26 +```
27 +
28 +Run these on the host machine, not inside the Agent Zero container.
29 +
30 +The installer uses `uv`, and `uv` will select or download a compatible Python if needed.
31 +
32 +## Open it and start working
33 +
34 +1. Make sure Agent Zero is already running.
35 +2. Launch A0 CLI on the host machine:
36 +
37 +```bash
38 +a0
39 +```
40 +
41 +3. If Agent Zero is running on the same machine, A0 CLI will usually find it for you.
42 +4. If Agent Zero is somewhere else, enter the exact web address or set `AGENT_ZERO_HOST` as env variable before launching `a0`.
43 +5. Open or create a chat and confirm you can talk to Agent Zero from the host machine.
44 +
45 +> [!NOTE]
46 +> Current Agent Zero builds starting from v1.9 include the builtin connector support that A0 CLI expects. If you see a connector-specific `404`, update Agent Zero first.
47 +
48 +## Give this to another agent
49 +
50 +If another agent is helping with setup, do not paste a whole checklist. Paste one line:
51 +
52 +```text
53 +Set up the A0 CLI connector for Agent Zero on this machine using the a0-setup-cli Skill.
54 +```
55 +
56 +## Troubleshooting
57 +
58 +- **Nothing appears locally:** Enter the Agent Zero web address manually or export `AGENT_ZERO_HOST`.
59 +- **You tried to install from inside Docker:** A0 CLI belongs on the host machine. Agent Zero stays in Docker.
60 +- **Function keys do nothing:** Some terminals and IDEs capture function keys. Use `Ctrl+P`.
61 +- **Connector route returns `404`:** Update Agent Zero to a build with builtin connector support.
62 +
63 +## Related links
64 +
65 +- [Quick Start](../quickstart.md)
66 +- [Installation Guide](../setup/installation.md)
docs/quickstart.md
+28
@@ -23,6 +23,34 @@ Follow the CLI prompts for port and authentication, complete onboarding, then op
23 > [!NOTE]
24 > For manual Docker Desktop setup, volume mapping, and platform-specific detail, see the [Installation Guide](setup/installation.md#manual-installation-advanced).
25
26 +## Use Agent Zero on your real local files
27 +
28 +If you want Agent Zero to work on the actual files on your computer, this is the important part.
29 +
30 +Agent Zero stays in Docker for safety. The A0 CLI installs and runs on your host machine. That host-side CLI is what lets Agent Zero work on the real files on your real computer.
31 +
32 +**macOS / Linux:**
33 +```bash
34 +curl -LsSf https://raw.githubusercontent.com/agent0ai/a0-connector/main/install.sh | sh
35 +```
36 +
37 +**Windows (PowerShell):**
38 +```powershell
39 +irm https://raw.githubusercontent.com/agent0ai/a0-connector/main/install.ps1 | iex
40 +```
41 +
42 +Run those on the host machine, not inside the Agent Zero container.
43 +
44 +Then launch:
45 +
46 +```bash
47 +a0
48 +```
49 +
50 +Once `a0` connects, open or create a chat there. That is the path that lets Agent Zero stay in Docker while still working on real local files on your machine.
51 +
52 +For the full setup flow, manual fallback install paths, remote-host tips, and a copy-ready brief for another agent, see the [A0 CLI Connector guide](guides/a0-cli-connector.md).
53 +
54 ### Open the Web UI and configure your API key
55
56 Open your browser and navigate to `http://localhost:<PORT>`. The Web UI will show the onboarding banner. Click Start Onboarding to set your AI models and API key.
docs/setup/installation.md
+3
@@ -25,6 +25,9 @@ docker run -p 80:80 agent0ai/agent-zero
25
26 Once the install completes, open the URL shown in your terminal to access the Web UI. Follow the prompts in the CLI to set your port and authentication, complete onboarding, add your API key, then continue to [Step 3: Configure Agent Zero](#step-3-configure-agent-zero).
27
28 +> [!TIP]
29 +> Prefer a terminal-native workflow too? Install the optional [A0 CLI Connector](../guides/a0-cli-connector.md) from GitHub, then run `a0` to connect to this Agent Zero instance from your terminal.
30 +
31 ---
32
33 ## How to Update Agent Zero
extensions/python/message_loop_prompts_after/_63_recall_relevant_skills.py new
+39
@@ -0,0 +1,39 @@
1 +from agent import LoopData
2 +from helpers.extension import Extension
3 +from helpers import skills as skills_helper
4 +
5 +
6 +class RecallRelevantSkills(Extension):
7 + async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
8 + if not self.agent or loop_data.iteration != 0:
9 + return
10 +
11 + user_instruction = (
12 + loop_data.user_message.output_text() if loop_data.user_message else ""
13 + ).strip()
14 + if len(user_instruction) < 8:
15 + return
16 +
17 + matches = skills_helper.search_skills(
18 + user_instruction,
19 + limit=6,
20 + agent=self.agent,
21 + )
22 + if not matches:
23 + return
24 +
25 + lines: list[str] = []
26 + for skill in matches:
27 + name = skill.name.strip().replace("\n", " ")[:100]
28 + desc = (skill.description or "").replace("\n", " ").strip()
29 + if len(desc) > 220:
30 + desc = desc[:220].rstrip() + "…"
31 + lines.append(f"- {name}: {desc}")
32 +
33 + if not lines:
34 + return
35 +
36 + loop_data.extras_temporary["relevant_skills"] = self.agent.read_prompt(
37 + "agent.system.skills.relevant.md",
38 + skills="\n".join(lines),
39 + )
helpers/skills.py
+21 -2
@@ -450,7 +450,11 @@ def search_skills(
450 if not q:
451 return []
452
453 - terms = [t for t in re.split(r"\s+", q) if t]
453 + raw_terms = [t for t in re.split(r"\s+", q) if t]
454 + terms = [
455 + t for t in raw_terms
456 + if len(t) >= 3 or any(ch.isdigit() for ch in t)
457 + ] or raw_terms
458 candidates = list_skills(agent)
459
460 scored: List[Tuple[int, Skill]] = []
@@ -458,8 +462,22 @@ def search_skills(
462 name = s.name.lower()
463 desc = (s.description or "").lower()
464 tags = [t.lower() for t in s.tags]
465 + triggers = [t.lower() for t in s.triggers]
466
467 score = 0
468 + if q == name:
469 + score += 10
470 + if any(q == trigger for trigger in triggers):
471 + score += 9
472 + if q in name:
473 + score += 6
474 + if q in desc:
475 + score += 4
476 + if any(q in tag for tag in tags):
477 + score += 3
478 + if any(q in trigger for trigger in triggers):
479 + score += 8
480 +
481 for term in terms:
482 if term in name:
483 score += 3
@@ -467,6 +485,8 @@ def search_skills(
485 score += 2
486 if any(term in tag for tag in tags):
487 score += 1
488 + if any(term in trigger for trigger in triggers):
489 + score += 4
490
491 if score > 0:
492 scored.append((score, s))
@@ -524,4 +544,3 @@ def validate_skill_md(skill_md_path: Path) -> List[str]:
544 if not skill:
545 return ["Unable to parse SKILL.md frontmatter"]
546 return validate_skill(skill)
527 -
helpers/skills_cli.py
+10 -1
@@ -42,10 +42,19 @@ class Skill:
42 def get_skills_dirs() -> List[Path]:
43 """Get all skill directories"""
44 base = Path(files.get_abs_path("usr", "skills"))
45 - return [
45 + roots = [
46 + Path(files.get_abs_path("skills")),
47 + base,
48 base / "custom",
49 base / "default",
50 ]
51 + seen: set[Path] = set()
52 + ordered: List[Path] = []
53 + for root in roots:
54 + if root not in seen:
55 + seen.add(root)
56 + ordered.append(root)
57 + return ordered
58
59
60 def parse_skill_file(skill_path: Path) -> Optional[Skill]:
prompts/agent.system.skills.md
+2 -1
@@ -1,3 +1,4 @@
1 ## skills
2 -use `skills_tool:list` to discover skills when specialized instructions may help
2 +use `skills_tool:search` when the user's wording sounds like a task, trigger phrase, or keyword match for a skill
3 +use `skills_tool:list` when you need a broader catalog view
4 use `skills_tool:load` before following a skill
prompts/agent.system.skills.relevant.md new
+5
@@ -0,0 +1,5 @@
1 +# relevant skills
2 +- the following skills matched the user's current request by lexical search, including trigger phrases
3 +- use `skills_tool:load` to load one before following it
4 +
5 +{{skills}}
prompts/agent.system.tool.skills.md
+5 -4
@@ -1,6 +1,7 @@
1 ### skills_tool
2 use skills only when relevant
3 workflow:
4 +- `skills_tool:search`: find candidate skills by keywords or trigger phrases from the current task
5 - `skills_tool:list`: discover available skills
6 - `skills_tool:load`: load one skill by `skill_name`
7 after loading a skill, follow its instructions and use referenced files or scripts with other tools
@@ -8,11 +9,11 @@ reload a skill if its instructions are no longer in context
9 example:
10 ~~~json
11 {
11 - "thoughts": ["A skill may already encode the workflow I need."],
12 - "headline": "Loading relevant skill",
13 - "tool_name": "skills_tool:load",
12 + "thoughts": ["The user's request sounds like a skill trigger phrase, so I should search first."],
13 + "headline": "Searching for relevant skill",
14 + "tool_name": "skills_tool:search",
15 "tool_args": {
15 - "skill_name": "playwright"
16 + "query": "set up a0 cli connector"
17 }
18 }
19 ~~~
skills/a0-setup-cli/SKILL.md new
+168
@@ -0,0 +1,168 @@
1 +---
2 +name: a0-setup-cli
3 +description: Guide the user through installing and connecting the A0 CLI on the host machine so Dockerized Agent Zero can work on real local files. Use when asked to install A0, set up the CLI connector, connect Agent Zero to local files, or troubleshoot host-vs-container setup confusion.
4 +version: 1.0.0
5 +author: Agent Zero Team
6 +tags: ["agent-zero", "a0", "cli", "connector", "docker", "setup", "local-files"]
7 +trigger_patterns:
8 + - "install a0"
9 + - "install a0 cli"
10 + - "set up a0 cli"
11 + - "set up a0 cli connector"
12 + - "connect a0 to agent zero"
13 + - "connect agent zero to local files"
14 + - "let agent zero work on my local files"
15 + - "install the terminal connector"
16 + - "help me set up the a0 cli connector"
17 + - "install a0 connector"
18 +---
19 +
20 +# A0 CLI Host Setup
21 +
22 +Use this skill to guide the user through installing `a0` on their host machine and connecting it to Agent Zero.
23 +
24 +## Core Boundary
25 +
26 +- Agent Zero stays in Docker or its sandboxed runtime.
27 +- `a0` installs and runs on the user's host machine.
28 +- The whole point is to let Agent Zero work on the real files on the user's computer.
29 +
30 +## Response Flow
31 +
32 +### 1. Ask whether they already tried
33 +
34 +Start here:
35 +
36 +> Have you already tried installing `a0`? If so, what command did you run, where did you run it, and what happened?
37 +
38 +If they already tried, diagnose that attempt before repeating instructions.
39 +
40 +### 2. Stop container installs immediately
41 +
42 +If the user is inside the Agent Zero container, `/a0`, `docker exec`, or another sandbox shell, stop and say:
43 +
44 +> `a0` does not get installed inside the Agent Zero container. Exit to your normal host terminal first. Agent Zero stays in Docker; `a0` belongs on your machine.
45 +
46 +Do not keep giving install commands until they are back on the host.
47 +
48 +### 3. Identify the host OS only as needed
49 +
50 +If the platform is unclear, ask one short question:
51 +
52 +> Are you on macOS/Linux shell or Windows PowerShell on the host machine?
53 +
54 +Then use the matching installer.
55 +
56 +### 4. Use the installer-first flow
57 +
58 +Treat these public installer URLs as placeholders for now. Use them first, but be ready to switch to the manual `uv tool install` path if the raw GitHub URL is blocked, private, or unreachable.
59 +
60 +macOS / Linux:
61 +
62 +```bash
63 +curl -LsSf https://raw.githubusercontent.com/agent0ai/a0-connector/main/install.sh | sh
64 +```
65 +
66 +Windows PowerShell:
67 +
68 +```powershell
69 +irm https://raw.githubusercontent.com/agent0ai/a0-connector/main/install.ps1 | iex
70 +```
71 +
72 +The installer will install `uv` if needed, then run `uv tool install --upgrade <package-spec>` for the CLI.
73 +
74 +### 5. Use the manual `uv tool install` fallback when needed
75 +
76 +If the placeholder installer URL is unavailable, switch to a manual `uv tool install` flow instead of stopping.
77 +
78 +Public Git fallback:
79 +
80 +```bash
81 +uv tool install --upgrade git+https://github.com/agent0ai/a0-connector
82 +```
83 +
84 +Local checkout or internal mirror examples:
85 +
86 +```bash
87 +uv tool install --upgrade /path/to/a0-connector
88 +uv tool install --upgrade git+ssh://git.example.com/team/a0-connector.git
89 +```
90 +
91 +If they want to reuse the stock installer with a custom package source, explain that the installer honors `A0_PACKAGE_SPEC`.
92 +
93 +### 6. Tell them to run `a0`
94 +
95 +After install, the next step is always:
96 +
97 +```bash
98 +a0
99 +```
100 +
101 +If the command is not found yet, tell them to open a new terminal and run `a0` again.
102 +
103 +### 7. Explain how to connect
104 +
105 +Tell the user what to expect:
106 +
107 +- `a0` opens the host picker first.
108 +- If Agent Zero is running locally, `a0` may discover it automatically.
109 +- If not, the user can enter the Agent Zero web URL manually.
110 +- `AGENT_ZERO_HOST` can prefill the target host without bypassing the picker.
111 +
112 +Example:
113 +
114 +```bash
115 +export AGENT_ZERO_HOST=http://localhost:50001
116 +a0
117 +```
118 +
119 +### 8. Define success clearly
120 +
121 +Successful setup looks like this:
122 +
123 +- `a0` starts on the host machine.
124 +- It connects to the user's Agent Zero instance or reaches the login step.
125 +- The user can open a chat from the terminal.
126 +- Agent Zero can now act on real files on the host through the connector flow while Agent Zero itself still runs in Docker.
127 +
128 +## Troubleshooting
129 +
130 +- If the user says they installed inside Docker or shows `/a0` paths, redirect them to the host-machine install.
131 +- If `a0` gets a connector `404`, explain that the running Agent Zero build likely does not include the builtin `_a0_connector` support yet and should be updated.
132 +- If the browser UI works but `a0` does not, remind them the web UI can run without connector support but the CLI cannot.
133 +- If Docker discovery does not find the instance, have them enter the exact Agent Zero URL or set `AGENT_ZERO_HOST`.
134 +
135 +## Example Requests And Responses
136 +
137 +### Example 1
138 +
139 +User: "Help me set up the A0 CLI connector."
140 +
141 +Respond like this:
142 +
143 +1. Ask whether they already tried and whether they are on the host machine.
144 +2. If the OS is unknown, ask whether they are in macOS/Linux shell or Windows PowerShell.
145 +3. Give the matching installer command.
146 +4. Tell them to run `a0`.
147 +5. Explain what the host picker and successful connection should look like.
148 +
149 +### Example 2
150 +
151 +User: "I'm inside the Agent Zero container. How do I install A0?"
152 +
153 +Respond like this:
154 +
155 +- Stop the flow.
156 +- Explain that `a0` must be installed on the host, not in the container.
157 +- Tell them to exit Docker, open a normal terminal on the machine, then continue with the host installer.
158 +
159 +### Example 3
160 +
161 +User: "The raw GitHub installer URL is blocked on our network."
162 +
163 +Respond like this:
164 +
165 +- Say the public installer URL is only a placeholder path.
166 +- Switch to a manual `uv tool install --upgrade <package-spec>` flow.
167 +- Offer examples for a local checkout, internal Git host, or the public Git URL if that one works.
168 +- Then tell them to run `a0` and connect to Agent Zero.
tools/skills_tool.py
+28 -28
@@ -96,9 +96,9 @@ class SkillsTool(Tool):
96 try:
97 if method == "list":
98 return Response(message=self._list(), break_loop=False)
99 - # if method == "search":
100 - # query = str(kwargs.get("query") or "").strip()
101 - # return Response(message=self._search(query), break_loop=False)
99 + if method == "search":
100 + query = str(kwargs.get("query") or "").strip()
101 + return Response(message=self._search(query), break_loop=False)
102 if method == "load":
103 skill_name = self._normalize_skill_name(
104 str(kwargs.get("skill_name") or "")
@@ -112,7 +112,7 @@ class SkillsTool(Tool):
112 # )
113
114 return Response(
115 - message="Error: missing/invalid 'method'. Supported: list, load.",
115 + message="Error: missing/invalid 'method'. Supported: list, search, load.",
116 break_loop=False,
117 )
118 except (
@@ -144,30 +144,30 @@ class SkillsTool(Tool):
144 lines.append("Tip: use skills_tool method=search or method=load for details.")
145 return "\n".join(lines)
146
147 - # def _search(self, query: str) -> str:
148 - # if not query:
149 - # return "Error: 'query' is required for method=search."
150 -
151 - # results = skills_helper.search_skills(
152 - # query,
153 - # limit=25,
154 - # agent=self.agent,
155 - # )
156 - # if not results:
157 - # return f"No skills matched query: {query!r}"
158 -
159 - # lines: List[str] = []
160 - # lines.append(f"Skills matching {query!r} ({len(results)}):")
161 - # for s in results:
162 - # desc = (s.description or "").strip()
163 - # if len(desc) > 200:
164 - # desc = desc[:200].rstrip() + "…"
165 - # lines.append(f"- {s.name}: {desc}")
166 - # lines.append("")
167 - # lines.append(
168 - # "Tip: use skills_tool method=load skill_name=<name> to load full instructions."
169 - # )
170 - # return "\n".join(lines)
147 + def _search(self, query: str) -> str:
148 + if not query:
149 + return "Error: 'query' is required for method=search."
150 +
151 + results = skills_helper.search_skills(
152 + query,
153 + limit=25,
154 + agent=self.agent,
155 + )
156 + if not results:
157 + return f"No skills matched query: {query!r}"
158 +
159 + lines: List[str] = []
160 + lines.append(f"Skills matching {query!r} ({len(results)}):")
161 + for s in results:
162 + desc = (s.description or "").strip()
163 + if len(desc) > 200:
164 + desc = desc[:200].rstrip() + "…"
165 + lines.append(f"- {s.name}: {desc}")
166 + lines.append("")
167 + lines.append(
168 + "Tip: use skills_tool method=load skill_name=<name> to load full instructions."
169 + )
170 + return "\n".join(lines)
171
172 def _load(self, skill_name: str) -> str:
173 skill_name = self._normalize_skill_name(skill_name)