update subagent-registry skill with explicit file operations
This commit is contained in:
@@ -1,25 +1,27 @@
|
|||||||
---
|
---
|
||||||
name: subagent-registry
|
name: subagent-registry
|
||||||
description: Manage named subagent instances with persistent provider pinning and memory. Use when spawning, resuming, listing, or deleting subagents.
|
description: Manage named subagent instances. MUST be used when spawning, resuming, listing, or deleting subagents. Read this skill FIRST before any subagent operation.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Subagent Registry
|
# Subagent Registry — CRITICAL
|
||||||
|
|
||||||
Manage named subagent instances. Each agent gets a human-readable name, persistent memory, and pinned provider for KV cache continuity.
|
You MUST manage `<project>/.pi/subagents.json` for ALL subagent operations. Read the file before any operation. Write the file after any change.
|
||||||
|
|
||||||
## Registry File
|
## File Location
|
||||||
|
|
||||||
`<project>/.pi/subagents.json`:
|
`<cwd>/.pi/subagents.json` (where cwd is the current project directory)
|
||||||
|
|
||||||
|
## File Format
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"session": "<session-name>",
|
"session": "<pi-session-name-or-project-dir>",
|
||||||
"agents": [
|
"agents": [
|
||||||
{
|
{
|
||||||
"name": "<human-readable-name>",
|
"name": "<human-readable-name>",
|
||||||
"id": "<agent-uuid>",
|
"id": "<agent-uuid-from-spawn-notification>",
|
||||||
"type": "<agent-type>",
|
"type": "<subagent_type>",
|
||||||
"provider": "<provider-config>",
|
"provider": "<exact-provider-config-from-agent-frontmatter>",
|
||||||
"status": "running|completed|error",
|
"status": "running|completed|error",
|
||||||
"created": "<ISO-timestamp>"
|
"created": "<ISO-timestamp>"
|
||||||
}
|
}
|
||||||
@@ -27,111 +29,72 @@ Manage named subagent instances. Each agent gets a human-readable name, persiste
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## MANDATORY Operations
|
||||||
|
|
||||||
|
### SPAWN — Always do this:
|
||||||
|
1. Ask user for a name if not provided: "What should I name this subagent?"
|
||||||
|
2. Spawn the agent: `Agent({ subagent_type, prompt, run_in_background: true })`
|
||||||
|
3. Wait for completion notification — extract the agent ID from the response
|
||||||
|
4. Read current `.pi/subagents.json`
|
||||||
|
5. Append new agent entry with name, id, type, provider, status="running", timestamp
|
||||||
|
6. Write updated `.pi/subagents.json`
|
||||||
|
7. Tell user: "Created subagent '<name>' (<id-short>) using <provider>"
|
||||||
|
|
||||||
|
### LIST — Always do this:
|
||||||
|
1. Read `.pi/subagents.json`
|
||||||
|
2. If file doesn't exist or agents array is empty: "No subagents found."
|
||||||
|
3. Display compact table:
|
||||||
|
```
|
||||||
|
Name Type Provider Status Created
|
||||||
|
---- ---- -------- ------ -------
|
||||||
|
searcher chat-search Google ↻ run 15:35
|
||||||
|
```
|
||||||
|
4. Show: name, type, provider, status, created time
|
||||||
|
|
||||||
|
### RESUME — Always do this:
|
||||||
|
1. Read `.pi/subagents.json`, find agent by name
|
||||||
|
2. If not found: "No subagent named '<name>'. Available: <list-of-names>"
|
||||||
|
3. If found: `Agent({ subagent_type, resume: "<agent-id>", prompt: "<new-task>", run_in_background: true })`
|
||||||
|
4. Update status to "running" in registry
|
||||||
|
5. Tell user: "Resumed '<name>' (<id-short>) — <provider> cache warm"
|
||||||
|
|
||||||
|
### DELETE — Always do this:
|
||||||
|
1. Read `.pi/subagents.json`, find agent by name
|
||||||
|
2. If running: steer to abort first
|
||||||
|
3. Remove entry from registry array
|
||||||
|
4. Write updated `.pi/subagents.json`
|
||||||
|
5. Tell user: "Deleted '<name>'"
|
||||||
|
|
||||||
|
### DELETE SESSION — Always do this:
|
||||||
|
1. Read `.pi/subagents.json`
|
||||||
|
2. Remove all agents where session matches
|
||||||
|
3. Write updated `.pi/subagents.json`
|
||||||
|
4. Tell user: "Deleted <N> subagents from session '<name>'"
|
||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
|
|
||||||
1. **Always ask for a name** when spawning a new subagent. Never auto-generate. Ask: "What should I name this subagent?"
|
- **NEVER spawn without asking for a name first**
|
||||||
2. **One agent per name.** If name exists, ask for a different name.
|
- **NEVER skip writing to the registry** after spawn/resume/delete
|
||||||
3. **Store the agent ID** in the registry immediately after spawn.
|
- **ALWAYS read the registry** before listing or resuming
|
||||||
4. **Use the same provider** when resuming — read from registry.
|
- **Provider config must be preserved exactly** from the agent's frontmatter (e.g., "only:DeepInfra")
|
||||||
5. **Each named agent gets its own memory** directory via `memory: project` in agent frontmatter.
|
- **No auto-cleanup** — agents persist until explicitly deleted
|
||||||
6. **No auto-cleanup.** Agents persist until explicitly deleted.
|
- **Each named agent gets `memory: project`** in its frontmatter for persistent memory
|
||||||
7. **Session-scoped.** Registry is per-project directory.
|
|
||||||
|
|
||||||
## Workflow: Spawn
|
## Example Workflow
|
||||||
|
|
||||||
1. User requests a subagent
|
|
||||||
2. **Ask for a name** if not provided: "What should I name this subagent?"
|
|
||||||
3. Call `Agent({ subagent_type, prompt, run_in_background: true, ... })`
|
|
||||||
4. Wait for completion notification with agent ID
|
|
||||||
5. Append to `.pi/subagents.json`:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "<user-given-name>",
|
|
||||||
"id": "<agent-uuid>",
|
|
||||||
"type": "<subagent_type>",
|
|
||||||
"provider": "<provider-config-from-agent-frontmatter>",
|
|
||||||
"status": "running",
|
|
||||||
"created": "<ISO-timestamp>"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
6. Inform user: "Created subagent '<name>' (<id-short>) using <provider>"
|
|
||||||
|
|
||||||
## Workflow: Resume
|
|
||||||
|
|
||||||
1. User says "resume <name>" or "tell <name> to..."
|
|
||||||
2. Read `.pi/subagents.json`, find agent by name
|
|
||||||
3. If not found: "No subagent named '<name>'. Use /subagent-list to see available agents."
|
|
||||||
4. If found: `Agent({ subagent_type, resume: "<agent-id>", prompt: "<new-task>", run_in_background: true })`
|
|
||||||
5. Update status in registry to "running"
|
|
||||||
6. Inform user: "Resumed '<name>' (<id-short>) — <provider> cache warm"
|
|
||||||
|
|
||||||
## Workflow: List
|
|
||||||
|
|
||||||
Display all agents in a compact table:
|
|
||||||
|
|
||||||
```
|
|
||||||
Name Type Provider Status Created
|
|
||||||
---- ---- -------- ------ -------
|
|
||||||
coder-login coder-pro DeepInfra ✓ done 20:00
|
|
||||||
coder-nav coder-pro DeepInfra ↻ run 20:05
|
|
||||||
obsidian-edit obsidian StreamLake ✓ done 19:30
|
|
||||||
```
|
|
||||||
|
|
||||||
Show: name, type, provider (from config), status, created time.
|
|
||||||
|
|
||||||
## Workflow: Delete
|
|
||||||
|
|
||||||
1. User says "delete <name>" or "kill <name>"
|
|
||||||
2. Read registry, find agent
|
|
||||||
3. If running: call `TaskStop` or steer to abort
|
|
||||||
4. Remove entry from registry
|
|
||||||
5. Inform user: "Deleted '<name>' (<id-short>)"
|
|
||||||
|
|
||||||
## Workflow: Delete Session
|
|
||||||
|
|
||||||
1. User says "delete session <name>" or "clear all subagents for <session>"
|
|
||||||
2. Find all agents where `session == <name>`
|
|
||||||
3. Abort any running agents
|
|
||||||
4. Remove all matching entries from registry
|
|
||||||
5. Inform user: "Deleted <N> subagents from session '<name>'"
|
|
||||||
|
|
||||||
## Provider Config Format
|
|
||||||
|
|
||||||
Store as string: `"only:<provider-slug>"`
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
- `"only:DeepInfra"`
|
|
||||||
- `"only:Baidu"`
|
|
||||||
- `"only:StreamLake"`
|
|
||||||
- `"only:Moonshot AI"`
|
|
||||||
|
|
||||||
When resuming, parse and reconstruct the provider field:
|
|
||||||
```
|
|
||||||
"only:DeepInfra" → { "only": ["DeepInfra"] }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Memory
|
|
||||||
|
|
||||||
Each named agent should have `memory: project` in its frontmatter. This gives it a persistent memory directory at `.pi/agent-memory/<agent-name>/` that survives across resume calls.
|
|
||||||
|
|
||||||
## Session Name
|
|
||||||
|
|
||||||
The `session` field in the registry should match the pi session name. If no session name is set, use the project directory name.
|
|
||||||
|
|
||||||
## Example Interaction
|
|
||||||
|
|
||||||
```
|
```
|
||||||
User: "Spawn a coder-pro to fix the login module"
|
User: "Spawn a coder-pro to fix the login module"
|
||||||
LLM: "What should I name this subagent?"
|
You: "What should I name this subagent?"
|
||||||
User: "auth-login"
|
User: "auth-login"
|
||||||
LLM: *spawns agent, gets ID 7efad0d8-5a78-415*
|
You: *spawn agent → get ID 7efad0d8-5a78-415*
|
||||||
LLM: "Created subagent 'auth-login' (7efad0d8) using DeepInfra"
|
You: *read .pi/subagents.json → append entry → write file*
|
||||||
|
You: "Created subagent 'auth-login' (7efad0d8) using DeepInfra"
|
||||||
|
|
||||||
User: "What subagents do we have?"
|
User: "List my subagents"
|
||||||
LLM: *reads registry, displays table*
|
You: *read .pi/subagents.json → display table*
|
||||||
auth-login coder-pro DeepInfra ✓ done 20:00
|
auth-login coder-pro DeepInfra ↻ running 20:00
|
||||||
|
|
||||||
User: "Resume auth-login and tell it to add password reset"
|
User: "Resume auth-login and add password reset"
|
||||||
LLM: *reads registry, finds ID, resumes with same provider*
|
You: *read .pi/subagents.json → find ID → resume*
|
||||||
LLM: "Resumed 'auth-login' (7efad0d8) — DeepInfra cache warm"
|
You: "Resumed 'auth-login' (7efad0d8) — DeepInfra cache warm"
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user