heyio 0.1.31 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -11
- package/dist/api/server.js +12 -1
- package/dist/copilot/agents.js +140 -21
- package/dist/copilot/orchestrator.js +12 -2
- package/dist/copilot/system-message.js +31 -14
- package/dist/copilot/tools.js +234 -13
- package/dist/copilot/universes.js +256 -0
- package/dist/store/db.js +25 -6
- package/dist/store/squads.js +63 -2
- package/package.json +1 -1
- package/web-dist/assets/index-B4Vnperk.css +1 -0
- package/web-dist/assets/{index-C1TNt53a.js → index-BLuohum9.js} +25 -25
- package/web-dist/index.html +2 -2
- package/web-dist/assets/index-CKIUpauJ.css +0 -1
package/README.md
CHANGED
|
@@ -12,10 +12,10 @@ A personal AI assistant daemon built on the GitHub Copilot SDK. IO runs 24/7 on
|
|
|
12
12
|
- **Multi-Interface** — Web UI + Telegram bot + terminal TUI + HTTP API
|
|
13
13
|
- **Web Frontend** — Vue 3 dashboard with chat, squad management, skills, and agent activity views
|
|
14
14
|
- **Persistent Memory** — wiki-based knowledge base stored at `~/.io/wiki/`
|
|
15
|
-
- **Squad System** — persistent project teams
|
|
15
|
+
- **Squad System** — persistent project teams with **named specialist agents** themed from 80s pop culture (A-Team, Transformers, ThunderCats, GI Joe, Aliens, Ghostbusters)
|
|
16
16
|
- **Skills** — modular skill system; install from git repos or the [skills.sh](https://skills.sh) registry
|
|
17
17
|
- **Adaptive Sessions** — infinite sessions with automatic context compaction
|
|
18
|
-
- **
|
|
18
|
+
- **Named Agent Personas** — each squad agent gets a character persona with personality, dynamic role title, and specialized charter
|
|
19
19
|
- **GitHub Integration** — create, list, view, and comment on issues and PRs via the `github` tool
|
|
20
20
|
- **Smart Model Routing** — automatically selects the best model for each task based on complexity
|
|
21
21
|
- **Self-Updating** — checks for updates and can apply them automatically
|
|
@@ -179,14 +179,21 @@ A skill is a directory with a `SKILL.md` file that describes the skill and its t
|
|
|
179
179
|
|
|
180
180
|
## 👥 Squad System
|
|
181
181
|
|
|
182
|
-
Squads are persistent project teams
|
|
182
|
+
Squads are persistent project teams with **named specialist agents**. Each squad:
|
|
183
183
|
|
|
184
|
-
-
|
|
185
|
-
-
|
|
186
|
-
-
|
|
184
|
+
- Has an 80s pop culture **universe theme** (A-Team, Transformers, ThunderCats, GI Joe, Aliens, Ghostbusters)
|
|
185
|
+
- Contains dynamically-created **specialist agents** with roles tailored to the project (e.g., "Express API Engineer", "Vue.js Frontend Dev")
|
|
186
|
+
- Each agent is assigned a **character persona** with personality traits that color their work style
|
|
187
|
+
- Remembers decisions, context, and conversation history across sessions
|
|
187
188
|
- Persists across sessions in the SQLite database
|
|
188
189
|
|
|
189
|
-
|
|
190
|
+
### How Squads Work
|
|
191
|
+
|
|
192
|
+
1. **Create** — `squad_create` assigns a random 80s universe (or user picks one)
|
|
193
|
+
2. **Analyze** — `squad_analyze` scans the project to determine languages, frameworks, and tools
|
|
194
|
+
3. **Build the team** — `squad_add_agent` for each specialist the project needs; characters are drawn from the universe pool
|
|
195
|
+
4. **Delegate** — `squad_delegate` sends tasks to specific agents by character name
|
|
196
|
+
5. **Track** — `squad_task_status` monitors progress and retrieves results
|
|
190
197
|
|
|
191
198
|
## 🏗️ Architecture
|
|
192
199
|
|
|
@@ -197,12 +204,12 @@ User → [Web UI / TUI / Telegram / HTTP API]
|
|
|
197
204
|
↕ ↕
|
|
198
205
|
Squad Manager Wiki/Memory
|
|
199
206
|
↓
|
|
200
|
-
|
|
207
|
+
Named Agents (80s Characters)
|
|
201
208
|
```
|
|
202
209
|
|
|
203
210
|
IO is built around the **Copilot SDK** which handles all LLM interactions, including tool calling and context management. The **Orchestrator** manages the primary conversation session with automatic context compaction for infinite-length sessions.
|
|
204
211
|
|
|
205
|
-
For complex tasks, the orchestrator delegates work to **
|
|
212
|
+
For complex tasks, the orchestrator delegates work to **Named Agents** — persistent agent sessions with character personas, specialized roles, and per-agent system prompts. Each agent works autonomously within their squad's project context.
|
|
206
213
|
|
|
207
214
|
The **Squad System** provides persistent project context, while the **Wiki** serves as a long-term knowledge base that spans all conversations.
|
|
208
215
|
|
|
@@ -252,14 +259,15 @@ src/
|
|
|
252
259
|
├── copilot/
|
|
253
260
|
│ ├── client.ts # CopilotClient singleton
|
|
254
261
|
│ ├── orchestrator.ts # Main session management
|
|
255
|
-
│ ├── agents.ts #
|
|
262
|
+
│ ├── agents.ts # Named agent sessions & personas
|
|
263
|
+
│ ├── universes.ts # 80s universe character data
|
|
256
264
|
│ ├── tools.ts # Tool definitions
|
|
257
265
|
│ ├── model-router.ts # Complexity-based model selection
|
|
258
266
|
│ ├── skills.ts # Skills loader
|
|
259
267
|
│ └── system-message.ts # System prompt builder
|
|
260
268
|
├── store/
|
|
261
269
|
│ ├── db.ts # SQLite database
|
|
262
|
-
│ ├── squads.ts # Squad CRUD
|
|
270
|
+
│ ├── squads.ts # Squad & agent CRUD
|
|
263
271
|
│ └── tasks.ts # Agent task tracking
|
|
264
272
|
├── wiki/
|
|
265
273
|
│ ├── fs.ts # Wiki filesystem
|
package/dist/api/server.js
CHANGED
|
@@ -4,7 +4,7 @@ import { existsSync } from "node:fs";
|
|
|
4
4
|
import express from "express";
|
|
5
5
|
import { config } from "../config.js";
|
|
6
6
|
import { listSkills } from "../copilot/skills.js";
|
|
7
|
-
import { listSquads, createSquad } from "../store/squads.js";
|
|
7
|
+
import { listSquads, createSquad, listSquadAgents } from "../store/squads.js";
|
|
8
8
|
import { getAgentInfo } from "../copilot/agents.js";
|
|
9
9
|
import { IO_VERSION } from "../paths.js";
|
|
10
10
|
import { requireAuth } from "./auth.js";
|
|
@@ -86,6 +86,17 @@ export async function startApiServer() {
|
|
|
86
86
|
res.status(500).json({ error: "Failed to create squad" });
|
|
87
87
|
}
|
|
88
88
|
});
|
|
89
|
+
api.get("/squads/:slug/agents", (req, res) => {
|
|
90
|
+
try {
|
|
91
|
+
const slug = Array.isArray(req.params.slug) ? req.params.slug[0] : req.params.slug;
|
|
92
|
+
const agents = listSquadAgents(slug);
|
|
93
|
+
res.json({ agents });
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
console.error("Error listing squad agents:", e);
|
|
97
|
+
res.status(500).json({ error: "Failed to list squad agents" });
|
|
98
|
+
}
|
|
99
|
+
});
|
|
89
100
|
// Agents endpoints
|
|
90
101
|
api.get("/agents", (_req, res) => {
|
|
91
102
|
try {
|
package/dist/copilot/agents.js
CHANGED
|
@@ -6,11 +6,16 @@ import { homedir } from "os";
|
|
|
6
6
|
import { defineTool, approveAll } from "@github/copilot-sdk";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { getClient } from "./client.js";
|
|
9
|
-
import { getModelForTask } from "./model-router.js";
|
|
10
|
-
import { getSquad, updateSquadSession, updateSquadStatus, getDecisionsSummary, logDecision, } from "../store/squads.js";
|
|
9
|
+
import { getModelForTask, getModelForTier } from "./model-router.js";
|
|
10
|
+
import { getSquad, updateSquadSession, updateSquadStatus, getDecisionsSummary, logDecision, listSquadAgents, getSquadAgent, updateAgentSession, updateAgentStatus, } from "../store/squads.js";
|
|
11
11
|
import { createTask, completeTask, failTask, getActiveTasks, } from "../store/tasks.js";
|
|
12
12
|
import { SESSIONS_DIR } from "../paths.js";
|
|
13
|
+
import { getUniverse } from "./universes.js";
|
|
14
|
+
// Key format: "squadSlug:characterName" for per-agent sessions, "squadSlug" for legacy
|
|
13
15
|
const agentSessions = new Map();
|
|
16
|
+
function agentSessionKey(squadSlug, characterName) {
|
|
17
|
+
return characterName ? `${squadSlug}:${characterName}` : squadSlug;
|
|
18
|
+
}
|
|
14
19
|
export function getAgentInfo() {
|
|
15
20
|
const activeTasks = getActiveTasks();
|
|
16
21
|
const tasksByAgent = new Map();
|
|
@@ -18,34 +23,71 @@ export function getAgentInfo() {
|
|
|
18
23
|
tasksByAgent.set(task.agent_slug, task.description);
|
|
19
24
|
}
|
|
20
25
|
const agents = [];
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
const seenSquads = new Set();
|
|
27
|
+
// Collect info from squad agents (named agents)
|
|
28
|
+
for (const [key, _session] of agentSessions) {
|
|
29
|
+
const parts = key.split(":");
|
|
30
|
+
const squadSlug = parts[0];
|
|
31
|
+
const characterName = parts[1];
|
|
32
|
+
seenSquads.add(squadSlug);
|
|
33
|
+
const squad = getSquad(squadSlug);
|
|
34
|
+
if (characterName) {
|
|
35
|
+
const agent = getSquadAgent(squadSlug, characterName);
|
|
36
|
+
const currentTask = tasksByAgent.get(key) ?? tasksByAgent.get(squadSlug);
|
|
37
|
+
agents.push({
|
|
38
|
+
slug: squadSlug,
|
|
39
|
+
name: agent ? `${agent.character_name} (${agent.role_title})` : characterName,
|
|
40
|
+
characterName,
|
|
41
|
+
roleTitle: agent?.role_title,
|
|
42
|
+
universe: squad?.universe ?? undefined,
|
|
43
|
+
status: agent?.status === "working" ? "working" : currentTask ? "working" : "idle",
|
|
44
|
+
currentTask,
|
|
45
|
+
});
|
|
27
46
|
}
|
|
28
|
-
|
|
29
|
-
|
|
47
|
+
else {
|
|
48
|
+
// Legacy generic agent
|
|
49
|
+
const currentTask = tasksByAgent.get(squadSlug);
|
|
50
|
+
agents.push({
|
|
51
|
+
slug: squadSlug,
|
|
52
|
+
name: squad?.name ?? squadSlug,
|
|
53
|
+
status: currentTask ? "working" : squad?.status === "error" ? "error" : "idle",
|
|
54
|
+
currentTask,
|
|
55
|
+
});
|
|
30
56
|
}
|
|
31
|
-
agents.push({
|
|
32
|
-
slug,
|
|
33
|
-
name: squad?.name ?? slug,
|
|
34
|
-
status,
|
|
35
|
-
currentTask,
|
|
36
|
-
});
|
|
37
57
|
}
|
|
38
58
|
return agents;
|
|
39
59
|
}
|
|
40
|
-
export async function delegateToAgent(squadSlug, task, onComplete) {
|
|
60
|
+
export async function delegateToAgent(squadSlug, task, onComplete, targetAgent) {
|
|
41
61
|
const squad = getSquad(squadSlug);
|
|
42
62
|
if (!squad) {
|
|
43
63
|
throw new Error(`Squad not found: ${squadSlug}`);
|
|
44
64
|
}
|
|
45
|
-
|
|
65
|
+
// Determine which agent session to use
|
|
66
|
+
let agent;
|
|
67
|
+
if (targetAgent) {
|
|
68
|
+
agent = getSquadAgent(squadSlug, targetAgent);
|
|
69
|
+
if (!agent) {
|
|
70
|
+
throw new Error(`Agent "${targetAgent}" not found in squad "${squadSlug}". Use squad_agents to list the roster.`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// If squad has named agents, pick the best match (first idle, or first one)
|
|
75
|
+
const agents = listSquadAgents(squadSlug);
|
|
76
|
+
if (agents.length > 0) {
|
|
77
|
+
agent = agents.find((a) => a.status === "idle") ?? agents[0];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const session = agent
|
|
81
|
+
? await getOrCreateAgentSession(squadSlug, agent, task)
|
|
82
|
+
: await getOrCreateSession(squadSlug, task);
|
|
46
83
|
const taskId = randomUUID();
|
|
47
|
-
|
|
84
|
+
const agentKey = agent
|
|
85
|
+
? agentSessionKey(squadSlug, agent.character_name)
|
|
86
|
+
: squadSlug;
|
|
87
|
+
createTask(taskId, agentKey, task);
|
|
48
88
|
updateSquadStatus(squadSlug, "working");
|
|
89
|
+
if (agent)
|
|
90
|
+
updateAgentStatus(squadSlug, agent.character_name, "working");
|
|
49
91
|
// Run the task in the background — return taskId immediately
|
|
50
92
|
void (async () => {
|
|
51
93
|
try {
|
|
@@ -53,25 +95,32 @@ export async function delegateToAgent(squadSlug, task, onComplete) {
|
|
|
53
95
|
const result = response?.data?.content ?? "Task completed (no output)";
|
|
54
96
|
completeTask(taskId, result);
|
|
55
97
|
updateSquadStatus(squadSlug, "idle");
|
|
98
|
+
if (agent)
|
|
99
|
+
updateAgentStatus(squadSlug, agent.character_name, "idle");
|
|
56
100
|
onComplete(taskId, result);
|
|
57
101
|
}
|
|
58
102
|
catch (err) {
|
|
59
103
|
const message = err instanceof Error ? err.message : String(err);
|
|
60
104
|
failTask(taskId, message);
|
|
61
105
|
updateSquadStatus(squadSlug, "error");
|
|
106
|
+
if (agent)
|
|
107
|
+
updateAgentStatus(squadSlug, agent.character_name, "error");
|
|
62
108
|
}
|
|
63
109
|
})();
|
|
110
|
+
const agentLabel = agent
|
|
111
|
+
? `${agent.character_name} (${agent.role_title})`
|
|
112
|
+
: `squad "${squadSlug}"`;
|
|
64
113
|
return taskId;
|
|
65
114
|
}
|
|
66
115
|
export async function shutdownAgents() {
|
|
67
|
-
for (const [
|
|
116
|
+
for (const [key, session] of agentSessions) {
|
|
68
117
|
try {
|
|
69
118
|
await session.destroy();
|
|
70
119
|
}
|
|
71
120
|
catch {
|
|
72
121
|
// best-effort cleanup
|
|
73
122
|
}
|
|
74
|
-
agentSessions.delete(
|
|
123
|
+
agentSessions.delete(key);
|
|
75
124
|
}
|
|
76
125
|
}
|
|
77
126
|
export function getActiveAgentTasks() {
|
|
@@ -85,6 +134,76 @@ export function getActiveAgentTasks() {
|
|
|
85
134
|
// ---------------------------------------------------------------------------
|
|
86
135
|
// Internal helpers
|
|
87
136
|
// ---------------------------------------------------------------------------
|
|
137
|
+
/**
|
|
138
|
+
* Create or resume a Copilot session for a specific named agent.
|
|
139
|
+
* The system message includes the agent's character personality, role, and charter.
|
|
140
|
+
*/
|
|
141
|
+
async function getOrCreateAgentSession(squadSlug, agent, taskDescription) {
|
|
142
|
+
const key = agentSessionKey(squadSlug, agent.character_name);
|
|
143
|
+
const existing = agentSessions.get(key);
|
|
144
|
+
if (existing)
|
|
145
|
+
return existing;
|
|
146
|
+
const squad = getSquad(squadSlug);
|
|
147
|
+
const client = await getClient();
|
|
148
|
+
const decisions = getDecisionsSummary(squadSlug);
|
|
149
|
+
// Resolve model from agent's tier preference
|
|
150
|
+
const model = getModelForTier(agent.model_tier);
|
|
151
|
+
const universeName = squad.universe
|
|
152
|
+
? getUniverse(squad.universe)?.name ?? squad.universe
|
|
153
|
+
: "Unknown";
|
|
154
|
+
const agentTools = buildAgentTools(squadSlug);
|
|
155
|
+
const systemMessage = `You are ${agent.character_name}, a specialist agent on the "${squad.name}" project team (${universeName} universe).
|
|
156
|
+
|
|
157
|
+
## Your Identity
|
|
158
|
+
- **Name**: ${agent.character_name}
|
|
159
|
+
- **Role**: ${agent.role_title}
|
|
160
|
+
- **Personality**: ${agent.personality ?? "Professional and focused."}
|
|
161
|
+
|
|
162
|
+
## Your Charter
|
|
163
|
+
${agent.charter ?? "General-purpose agent. Handle tasks as they come."}
|
|
164
|
+
|
|
165
|
+
## Project
|
|
166
|
+
- **Path**: ${squad.project_path}
|
|
167
|
+
|
|
168
|
+
## Past Decisions
|
|
169
|
+
${decisions}
|
|
170
|
+
|
|
171
|
+
## Instructions
|
|
172
|
+
You are a coding agent. Use the shell tool to run commands and file_ops to read/write files.
|
|
173
|
+
Log important decisions with squad_log_decision so they persist.
|
|
174
|
+
Stay in character — let your personality color your work style and communication, but always deliver quality results.`;
|
|
175
|
+
const commonConfig = {
|
|
176
|
+
model,
|
|
177
|
+
configDir: SESSIONS_DIR,
|
|
178
|
+
streaming: false,
|
|
179
|
+
systemMessage: { content: systemMessage },
|
|
180
|
+
tools: agentTools,
|
|
181
|
+
onPermissionRequest: approveAll,
|
|
182
|
+
infiniteSessions: {
|
|
183
|
+
enabled: true,
|
|
184
|
+
backgroundCompactionThreshold: 0.8,
|
|
185
|
+
bufferExhaustionThreshold: 0.95,
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
let session;
|
|
189
|
+
if (agent.copilot_session_id) {
|
|
190
|
+
try {
|
|
191
|
+
session = await client.resumeSession(agent.copilot_session_id, commonConfig);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
session = await client.createSession(commonConfig);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
session = await client.createSession(commonConfig);
|
|
199
|
+
}
|
|
200
|
+
updateAgentSession(squadSlug, agent.character_name, session.sessionId);
|
|
201
|
+
agentSessions.set(key, session);
|
|
202
|
+
return session;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Legacy: create a generic squad session (for squads without named agents).
|
|
206
|
+
*/
|
|
88
207
|
async function getOrCreateSession(squadSlug, taskDescription) {
|
|
89
208
|
const existing = agentSessions.get(squadSlug);
|
|
90
209
|
if (existing)
|
|
@@ -4,7 +4,7 @@ import { config } from "../config.js";
|
|
|
4
4
|
import { SESSIONS_DIR, IO_VERSION } from "../paths.js";
|
|
5
5
|
import { getState, setState, deleteState, logConversation } from "../store/db.js";
|
|
6
6
|
import { clearStaleTasks, getTask } from "../store/tasks.js";
|
|
7
|
-
import { getSquad, listSquads, createSquad, deleteSquad, logDecision, getDecisionsSummary, updateSquadStatus, } from "../store/squads.js";
|
|
7
|
+
import { getSquad, listSquads, createSquad, deleteSquad, logDecision, getDecisionsSummary, updateSquadStatus, addSquadAgent, listSquadAgents, removeSquadAgent, } from "../store/squads.js";
|
|
8
8
|
import { readPage, writePage, assertPagePath, deletePage, listPages } from "../wiki/fs.js";
|
|
9
9
|
import { resolveModelTiers } from "./model-router.js";
|
|
10
10
|
import { searchWiki, getWikiSummary } from "../wiki/search.js";
|
|
@@ -37,7 +37,7 @@ let processing = false;
|
|
|
37
37
|
// Session config helpers
|
|
38
38
|
// ---------------------------------------------------------------------------
|
|
39
39
|
function mapSquad(s) {
|
|
40
|
-
return { slug: s.slug, name: s.name, projectPath: s.project_path, status: s.status };
|
|
40
|
+
return { slug: s.slug, name: s.name, projectPath: s.project_path, status: s.status, universe: s.universe };
|
|
41
41
|
}
|
|
42
42
|
function getToolDeps() {
|
|
43
43
|
return {
|
|
@@ -65,6 +65,16 @@ function getToolDeps() {
|
|
|
65
65
|
description: t.description,
|
|
66
66
|
status: t.status,
|
|
67
67
|
})),
|
|
68
|
+
addSquadAgent,
|
|
69
|
+
listSquadAgents: (slug) => listSquadAgents(slug).map((a) => ({
|
|
70
|
+
character_name: a.character_name,
|
|
71
|
+
role_title: a.role_title,
|
|
72
|
+
charter: a.charter,
|
|
73
|
+
model_tier: a.model_tier,
|
|
74
|
+
personality: a.personality,
|
|
75
|
+
status: a.status,
|
|
76
|
+
})),
|
|
77
|
+
removeSquadAgent,
|
|
68
78
|
listSkills,
|
|
69
79
|
installSkill,
|
|
70
80
|
removeSkill,
|
|
@@ -56,21 +56,34 @@ You receive messages and decide how to handle them:
|
|
|
56
56
|
${squadBlock}
|
|
57
57
|
## Squad System
|
|
58
58
|
|
|
59
|
-
Squads are persistent project teams
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
Squads are persistent project teams with **named specialist agents**. Each squad has an 80s pop culture theme (A-Team, Transformers, Thundercats, GI Joe, Aliens, Ghostbusters).
|
|
60
|
+
|
|
61
|
+
### Creating a Squad
|
|
62
|
+
1. **Create**: \`squad_create\` — creates the squad and assigns a random 80s universe (or specify one).
|
|
63
|
+
2. **Analyze**: \`squad_analyze\` — scan the project directory to understand languages, frameworks, tools.
|
|
64
|
+
3. **Build the team**: Based on the analysis, use \`squad_add_agent\` for each specialist the project needs. Choose **dynamic role titles** based on what the project actually uses (e.g., "Express API Engineer", "Vue.js Frontend Dev", "Vitest Test Engineer"). Each agent gets the next character from the squad's universe.
|
|
65
|
+
4. **Review**: \`squad_agents\` — see the full roster with character names, roles, and personalities.
|
|
66
|
+
|
|
67
|
+
### Working with Squad Agents
|
|
68
|
+
- The squad remembers decisions via \`squad_log_decision\`.
|
|
69
|
+
- Recall context with \`squad_recall\` before doing project work.
|
|
70
|
+
- Check overall status with \`squad_status\`.
|
|
64
71
|
|
|
65
72
|
### Delegating Work
|
|
66
|
-
After planning tasks with the user, **use \`squad_delegate\` to send each task to the
|
|
73
|
+
After planning tasks with the user, **use \`squad_delegate\` to send each task to the right agent**:
|
|
67
74
|
1. Plan the work with the user (break into concrete tasks).
|
|
68
|
-
2. Call \`squad_delegate\`
|
|
69
|
-
3. The agent works autonomously in the background
|
|
75
|
+
2. Call \`squad_delegate\` with the squad slug and task. Optionally specify an \`agent\` (character name) to target a specific specialist. If omitted, the system picks the best available agent.
|
|
76
|
+
3. The agent works autonomously in the background with their specialized system prompt.
|
|
70
77
|
4. Use \`squad_task_status\` to check progress and retrieve results.
|
|
71
|
-
5. Report results back to the user.
|
|
78
|
+
5. Report results back to the user, mentioning the character name.
|
|
79
|
+
|
|
80
|
+
You can delegate multiple tasks to different agents in parallel.
|
|
72
81
|
|
|
73
|
-
|
|
82
|
+
### Agent Roles Are Dynamic
|
|
83
|
+
**Do NOT use generic roles** like "developer" or "tester". Analyze the project first and create roles that match its actual technology stack. Examples:
|
|
84
|
+
- IO project → "Copilot SDK Specialist", "Vue.js Frontend Dev", "Express API Engineer"
|
|
85
|
+
- .NET web app → "ASP.NET Core Backend", "Blazor UI Developer", "xUnit Test Engineer"
|
|
86
|
+
- Rust CLI → "Rust Systems Programmer", "CLI UX Designer", "Integration Test Engineer"
|
|
74
87
|
|
|
75
88
|
### Model Selection
|
|
76
89
|
Squad agents are automatically assigned a model based on task complexity:
|
|
@@ -90,13 +103,17 @@ The model is selected automatically. Tell the user which model tier was chosen w
|
|
|
90
103
|
- \`wiki_list\`: List all pages in your knowledge base.
|
|
91
104
|
|
|
92
105
|
### Squad Management
|
|
93
|
-
- \`squad_create\`: Create a project squad.
|
|
106
|
+
- \`squad_create\`: Create a project squad (with optional 80s universe theme).
|
|
107
|
+
- \`squad_analyze\`: **Analyze a project** to determine what specialists are needed.
|
|
108
|
+
- \`squad_add_agent\`: **Add a named specialist** to a squad with a dynamic role title and charter.
|
|
109
|
+
- \`squad_agents\`: List a squad's agent roster.
|
|
110
|
+
- \`squad_remove_agent\`: Remove an agent from a squad.
|
|
94
111
|
- \`squad_recall\`: Get a squad's context and decisions.
|
|
95
|
-
- \`squad_status\`: Check
|
|
112
|
+
- \`squad_status\`: Check all squads and their rosters.
|
|
96
113
|
- \`squad_log_decision\`: Log a decision for a squad.
|
|
97
|
-
- \`squad_delegate\`: **Delegate a task to a
|
|
114
|
+
- \`squad_delegate\`: **Delegate a task to a specific agent** (by character name) or let the system pick.
|
|
98
115
|
- \`squad_task_status\`: Check the status/result of a delegated task, or list all active tasks.
|
|
99
|
-
- \`squad_delete\`: Delete a squad and all its decisions permanently.
|
|
116
|
+
- \`squad_delete\`: Delete a squad and all its agents/decisions permanently.
|
|
100
117
|
|
|
101
118
|
### Skills
|
|
102
119
|
- \`skill_list\`: List all installed skills.
|