illusion-code 0.1.0__py3-none-any.whl
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.
- illusion/__init__.py +24 -0
- illusion/__main__.py +15 -0
- illusion/_frontend/dist/index.mjs +39208 -0
- illusion/_frontend/package.json +27 -0
- illusion/_frontend/src/App.tsx +624 -0
- illusion/_frontend/src/components/CommandPicker.tsx +98 -0
- illusion/_frontend/src/components/Composer.tsx +55 -0
- illusion/_frontend/src/components/ComposerController.tsx +128 -0
- illusion/_frontend/src/components/ConversationView.tsx +750 -0
- illusion/_frontend/src/components/Footer.tsx +25 -0
- illusion/_frontend/src/components/MarkdownContent.tsx +537 -0
- illusion/_frontend/src/components/MarkdownTable.tsx +245 -0
- illusion/_frontend/src/components/ModalHost.tsx +425 -0
- illusion/_frontend/src/components/MultilineTextInput.tsx +250 -0
- illusion/_frontend/src/components/PromptInput.tsx +64 -0
- illusion/_frontend/src/components/SelectModal.tsx +78 -0
- illusion/_frontend/src/components/SidePanel.tsx +175 -0
- illusion/_frontend/src/components/Spinner.tsx +77 -0
- illusion/_frontend/src/components/StatusBar.tsx +142 -0
- illusion/_frontend/src/components/SwarmPanel.tsx +141 -0
- illusion/_frontend/src/components/TodoPanel.tsx +126 -0
- illusion/_frontend/src/components/ToolCallDisplay.tsx +202 -0
- illusion/_frontend/src/components/TranscriptPane.tsx +79 -0
- illusion/_frontend/src/components/WelcomeBanner.tsx +37 -0
- illusion/_frontend/src/hooks/useBackendSession.ts +468 -0
- illusion/_frontend/src/hooks/useTerminalSize.ts +9 -0
- illusion/_frontend/src/i18n.ts +78 -0
- illusion/_frontend/src/index.tsx +42 -0
- illusion/_frontend/src/theme/ThemeContext.tsx +19 -0
- illusion/_frontend/src/theme/builtinThemes.ts +89 -0
- illusion/_frontend/src/types.ts +110 -0
- illusion/_frontend/src/utils/markdown.ts +33 -0
- illusion/_frontend/src/utils/thinking.ts +191 -0
- illusion/_frontend/tsconfig.json +13 -0
- illusion/_web_dist/assets/index-BseIw-ik.css +10 -0
- illusion/_web_dist/assets/index-C_0ZWMuW.js +82 -0
- illusion/_web_dist/index.html +16 -0
- illusion/api/__init__.py +36 -0
- illusion/api/client.py +568 -0
- illusion/api/codex_client.py +563 -0
- illusion/api/compat.py +138 -0
- illusion/api/effort.py +128 -0
- illusion/api/errors.py +57 -0
- illusion/api/openai_client.py +819 -0
- illusion/api/provider.py +148 -0
- illusion/api/registry.py +479 -0
- illusion/api/usage.py +45 -0
- illusion/auth/__init__.py +50 -0
- illusion/auth/copilot.py +419 -0
- illusion/auth/external.py +612 -0
- illusion/auth/flows.py +58 -0
- illusion/auth/manager.py +214 -0
- illusion/auth/storage.py +372 -0
- illusion/bridge/__init__.py +38 -0
- illusion/bridge/manager.py +190 -0
- illusion/bridge/session_runner.py +84 -0
- illusion/bridge/types.py +113 -0
- illusion/bridge/work_secret.py +131 -0
- illusion/cli.py +1228 -0
- illusion/commands/__init__.py +32 -0
- illusion/commands/registry.py +1934 -0
- illusion/config/__init__.py +39 -0
- illusion/config/i18n.py +522 -0
- illusion/config/paths.py +259 -0
- illusion/config/settings.py +564 -0
- illusion/coordinator/__init__.py +41 -0
- illusion/coordinator/agent_definitions.py +1093 -0
- illusion/coordinator/coordinator_mode.py +127 -0
- illusion/engine/__init__.py +95 -0
- illusion/engine/cost_tracker.py +55 -0
- illusion/engine/messages.py +369 -0
- illusion/engine/query.py +632 -0
- illusion/engine/query_engine.py +343 -0
- illusion/engine/stream_events.py +169 -0
- illusion/hooks/__init__.py +67 -0
- illusion/hooks/events.py +43 -0
- illusion/hooks/executor.py +397 -0
- illusion/hooks/hot_reload.py +74 -0
- illusion/hooks/loader.py +133 -0
- illusion/hooks/schemas.py +121 -0
- illusion/hooks/types.py +86 -0
- illusion/mcp/__init__.py +104 -0
- illusion/mcp/client.py +377 -0
- illusion/mcp/config.py +140 -0
- illusion/mcp/types.py +175 -0
- illusion/memory/__init__.py +36 -0
- illusion/memory/manager.py +94 -0
- illusion/memory/memdir.py +58 -0
- illusion/memory/paths.py +57 -0
- illusion/memory/scan.py +120 -0
- illusion/memory/search.py +83 -0
- illusion/memory/types.py +43 -0
- illusion/output_styles/__init__.py +15 -0
- illusion/output_styles/loader.py +64 -0
- illusion/permissions/__init__.py +39 -0
- illusion/permissions/checker.py +174 -0
- illusion/permissions/modes.py +38 -0
- illusion/platforms.py +148 -0
- illusion/plugins/__init__.py +71 -0
- illusion/plugins/bundled/__init__.py +0 -0
- illusion/plugins/installer.py +59 -0
- illusion/plugins/loader.py +301 -0
- illusion/plugins/schemas.py +51 -0
- illusion/plugins/types.py +56 -0
- illusion/prompts/__init__.py +29 -0
- illusion/prompts/claudemd.py +74 -0
- illusion/prompts/context.py +187 -0
- illusion/prompts/environment.py +189 -0
- illusion/prompts/system_prompt.py +155 -0
- illusion/py.typed +0 -0
- illusion/sandbox/__init__.py +29 -0
- illusion/sandbox/adapter.py +174 -0
- illusion/services/__init__.py +59 -0
- illusion/services/compact/__init__.py +1015 -0
- illusion/services/cron.py +338 -0
- illusion/services/cron_scheduler.py +715 -0
- illusion/services/file_history.py +258 -0
- illusion/services/lsp/__init__.py +455 -0
- illusion/services/session_storage.py +237 -0
- illusion/services/token_estimation.py +72 -0
- illusion/skills/__init__.py +60 -0
- illusion/skills/bundled/__init__.py +110 -0
- illusion/skills/bundled/content/batch.md +86 -0
- illusion/skills/bundled/content/coding-guidelines.md +70 -0
- illusion/skills/bundled/content/debug.md +38 -0
- illusion/skills/bundled/content/loop.md +82 -0
- illusion/skills/bundled/content/remember.md +105 -0
- illusion/skills/bundled/content/simplify.md +53 -0
- illusion/skills/bundled/content/skillify.md +113 -0
- illusion/skills/bundled/content/stuck.md +54 -0
- illusion/skills/bundled/content/update-config.md +329 -0
- illusion/skills/bundled/content/verify.md +74 -0
- illusion/skills/loader.py +219 -0
- illusion/skills/registry.py +40 -0
- illusion/skills/types.py +24 -0
- illusion/state/__init__.py +18 -0
- illusion/state/app_state.py +67 -0
- illusion/state/store.py +93 -0
- illusion/swarm/__init__.py +71 -0
- illusion/swarm/agent_executor.py +857 -0
- illusion/swarm/in_process.py +259 -0
- illusion/swarm/subprocess_backend.py +136 -0
- illusion/swarm/team_helpers.py +123 -0
- illusion/swarm/types.py +159 -0
- illusion/swarm/worktree.py +347 -0
- illusion/tasks/__init__.py +33 -0
- illusion/tasks/local_agent_task.py +42 -0
- illusion/tasks/local_shell_task.py +27 -0
- illusion/tasks/manager.py +377 -0
- illusion/tasks/stop_task.py +21 -0
- illusion/tasks/types.py +88 -0
- illusion/tools/__init__.py +126 -0
- illusion/tools/agent_tool.py +388 -0
- illusion/tools/ask_user_question_tool.py +186 -0
- illusion/tools/base.py +149 -0
- illusion/tools/bash_tool.py +413 -0
- illusion/tools/config_tool.py +90 -0
- illusion/tools/cron_tool.py +473 -0
- illusion/tools/enter_plan_mode_tool.py +147 -0
- illusion/tools/enter_worktree_tool.py +188 -0
- illusion/tools/exit_plan_mode_tool.py +69 -0
- illusion/tools/exit_worktree_tool.py +225 -0
- illusion/tools/file_edit_tool.py +283 -0
- illusion/tools/file_read_tool.py +294 -0
- illusion/tools/file_write_tool.py +184 -0
- illusion/tools/glob_tool.py +165 -0
- illusion/tools/grep_tool.py +190 -0
- illusion/tools/list_mcp_resources_tool.py +80 -0
- illusion/tools/lsp_tool.py +333 -0
- illusion/tools/mcp_auth_tool.py +100 -0
- illusion/tools/mcp_tool.py +75 -0
- illusion/tools/notebook_edit_tool.py +242 -0
- illusion/tools/powershell_tool.py +334 -0
- illusion/tools/read_mcp_resource_tool.py +63 -0
- illusion/tools/repl_tool.py +100 -0
- illusion/tools/send_message_tool.py +112 -0
- illusion/tools/shell_common.py +187 -0
- illusion/tools/skill_tool.py +86 -0
- illusion/tools/sleep_tool.py +62 -0
- illusion/tools/structured_output_tool.py +58 -0
- illusion/tools/task_create_tool.py +98 -0
- illusion/tools/task_get_tool.py +94 -0
- illusion/tools/task_list_tool.py +94 -0
- illusion/tools/task_output_tool.py +55 -0
- illusion/tools/task_stop_tool.py +52 -0
- illusion/tools/task_update_tool.py +224 -0
- illusion/tools/team_create_tool.py +236 -0
- illusion/tools/team_delete_tool.py +104 -0
- illusion/tools/todo_write_tool.py +198 -0
- illusion/tools/tool_search_tool.py +156 -0
- illusion/tools/web_fetch_tool.py +264 -0
- illusion/tools/web_search_tool.py +186 -0
- illusion/ui/__init__.py +23 -0
- illusion/ui/app.py +258 -0
- illusion/ui/backend_host.py +1180 -0
- illusion/ui/input.py +86 -0
- illusion/ui/output.py +363 -0
- illusion/ui/permission_dialog.py +47 -0
- illusion/ui/permission_store.py +99 -0
- illusion/ui/protocol.py +384 -0
- illusion/ui/react_launcher.py +280 -0
- illusion/ui/runtime.py +787 -0
- illusion/ui/textual_app.py +603 -0
- illusion/ui/web/__init__.py +10 -0
- illusion/ui/web/server.py +87 -0
- illusion/ui/web/ws_host.py +1197 -0
- illusion/utils/__init__.py +0 -0
- illusion/utils/ripgrep.py +299 -0
- illusion/utils/shell.py +248 -0
- illusion_code-0.1.0.dist-info/METADATA +1159 -0
- illusion_code-0.1.0.dist-info/RECORD +214 -0
- illusion_code-0.1.0.dist-info/WHEEL +4 -0
- illusion_code-0.1.0.dist-info/entry_points.txt +2 -0
- illusion_code-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"""
|
|
2
|
+
团队创建工具
|
|
3
|
+
============
|
|
4
|
+
|
|
5
|
+
本模块提供 team_create 工具,用于创建多代理协作团队。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import time
|
|
13
|
+
from uuid import uuid4
|
|
14
|
+
|
|
15
|
+
from pydantic import BaseModel, Field
|
|
16
|
+
|
|
17
|
+
from illusion.state import AppStateStore
|
|
18
|
+
from illusion.swarm.team_helpers import (
|
|
19
|
+
TEAM_LEAD_NAME,
|
|
20
|
+
ensure_tasks_dir,
|
|
21
|
+
get_team_file_path,
|
|
22
|
+
read_team_file,
|
|
23
|
+
register_team_for_session_cleanup,
|
|
24
|
+
reset_task_list,
|
|
25
|
+
sanitize_name,
|
|
26
|
+
write_team_file,
|
|
27
|
+
)
|
|
28
|
+
from illusion.tools.base import BaseTool, ToolExecutionContext, ToolResult
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TeamCreateToolInput(BaseModel):
|
|
32
|
+
"""team_create 输入参数。"""
|
|
33
|
+
|
|
34
|
+
team_name: str = Field(description="Name for the new team to create.")
|
|
35
|
+
description: str | None = Field(default=None, description="Team description/purpose.")
|
|
36
|
+
agent_type: str | None = Field(
|
|
37
|
+
default=None,
|
|
38
|
+
description=(
|
|
39
|
+
'Type/role of the team lead (e.g., "researcher", "test-runner"). '
|
|
40
|
+
"Used for team file and inter-agent coordination."
|
|
41
|
+
),
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _generate_unique_team_name(provided_name: str) -> str:
|
|
46
|
+
"""生成唯一团队名(若已存在则回退到随机 slug)。"""
|
|
47
|
+
if read_team_file(provided_name) is None:
|
|
48
|
+
return provided_name
|
|
49
|
+
return f"team-{uuid4().hex[:8]}"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TeamCreateTool(BaseTool):
|
|
53
|
+
"""创建新的多代理团队。"""
|
|
54
|
+
|
|
55
|
+
name = "team_create"
|
|
56
|
+
description = """# TeamCreate
|
|
57
|
+
|
|
58
|
+
## When to Use
|
|
59
|
+
|
|
60
|
+
Use this tool proactively whenever:
|
|
61
|
+
- The user explicitly asks to use a team, swarm, or group of agents
|
|
62
|
+
- The user mentions wanting agents to work together, coordinate, or collaborate
|
|
63
|
+
- A task is complex enough that it would benefit from parallel work by multiple agents (e.g., building a full-stack feature with frontend and backend work, refactoring a codebase while keeping tests passing, implementing a multi-step project with research, planning, and coding phases)
|
|
64
|
+
|
|
65
|
+
When in doubt about whether a task warrants a team, prefer spawning a team.
|
|
66
|
+
|
|
67
|
+
## Choosing Agent Types for Teammates
|
|
68
|
+
|
|
69
|
+
When spawning teammates via the Agent tool, choose the `subagent_type` based on what tools the agent needs for its task. Each agent type has a different set of available tools — match the agent to the work:
|
|
70
|
+
|
|
71
|
+
- **Read-only agents** (e.g., Explore, Plan) cannot edit or write files. Only assign them research, search, or planning tasks. Never assign them implementation work.
|
|
72
|
+
- **Full-capability agents** (e.g., general-purpose) have access to all tools including file editing, writing, and bash. Use these for tasks that require making changes.
|
|
73
|
+
- **Custom agents** defined in `.illusion/agents/` may have their own tool restrictions. Check their descriptions to understand what they can and cannot do.
|
|
74
|
+
|
|
75
|
+
Always review the agent type descriptions and their available tools listed in the Agent tool prompt before selecting a `subagent_type` for a teammate.
|
|
76
|
+
|
|
77
|
+
Create a new team to coordinate multiple agents working on a project. Teams have a 1:1 correspondence with task lists (Team = TaskList).
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"team_name": "my-project",
|
|
82
|
+
"description": "Working on feature X"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This creates:
|
|
87
|
+
- A team file at `~/.illusion/teams/{team-name}/config.json`
|
|
88
|
+
- A corresponding task list directory at `~/.illusion/data/tasks/{team-name}/`
|
|
89
|
+
|
|
90
|
+
**Note**: If a team with the same name already exists, a random suffix is appended to ensure uniqueness (e.g., `my-project` may become `team-a1b2c3d4`). The actual name used is returned in the tool output.
|
|
91
|
+
|
|
92
|
+
## Team Workflow
|
|
93
|
+
|
|
94
|
+
1. **Create a team** with TeamCreate - this creates both the team and its task list
|
|
95
|
+
2. **Create tasks** using the Task tools (TaskCreate, TaskList, etc.) - they automatically use the team's task list
|
|
96
|
+
3. **Spawn teammates** using the Agent tool with `team_name` and `name` parameters to create teammates that join the team
|
|
97
|
+
4. **Assign tasks** using TaskUpdate with `owner` to give tasks to idle teammates
|
|
98
|
+
5. **Teammates work on assigned tasks** and mark them completed via TaskUpdate
|
|
99
|
+
6. **Teammates go idle between turns** - after each turn, teammates automatically go idle and send a notification. IMPORTANT: Be patient with idle teammates! Don't comment on their idleness until it actually impacts your work.
|
|
100
|
+
7. **Shutdown your team** - when the task is completed, gracefully shut down your teammates via `SendMessage` with a shutdown request, then call TeamDelete.
|
|
101
|
+
|
|
102
|
+
## Task Ownership
|
|
103
|
+
|
|
104
|
+
Tasks are assigned using TaskUpdate with the `owner` parameter. Any agent can set or change task ownership via TaskUpdate.
|
|
105
|
+
|
|
106
|
+
## Automatic Message Delivery
|
|
107
|
+
|
|
108
|
+
**IMPORTANT**: Messages from teammates are automatically delivered to you. You do NOT need to manually check your inbox.
|
|
109
|
+
|
|
110
|
+
When you spawn teammates:
|
|
111
|
+
- They will send you messages when they complete tasks or need help
|
|
112
|
+
- These messages appear automatically as new conversation turns (like user messages)
|
|
113
|
+
- If you're busy (mid-turn), messages are queued and delivered when your turn ends
|
|
114
|
+
- The UI shows a brief notification with the sender's name when messages are waiting
|
|
115
|
+
|
|
116
|
+
Messages will be delivered automatically.
|
|
117
|
+
|
|
118
|
+
When reporting on teammate messages, you do NOT need to quote the original message—it's already rendered to the user.
|
|
119
|
+
|
|
120
|
+
## Teammate Idle State
|
|
121
|
+
|
|
122
|
+
Teammates go idle after every turn—this is completely normal and expected. A teammate going idle immediately after sending you a message does NOT mean they are done or unavailable. Idle simply means they are waiting for input.
|
|
123
|
+
|
|
124
|
+
- **Idle teammates can receive messages.** Sending a message to an idle teammate wakes them up and they will process it normally.
|
|
125
|
+
- **Idle notifications are automatic.** The system sends an idle notification whenever a teammate's turn ends. You do not need to react to idle notifications unless you want to assign new work or send a follow-up message.
|
|
126
|
+
- **Do not treat idle as an error.** A teammate sending a message and then going idle is the normal flow—they sent their message and are now waiting for a response.
|
|
127
|
+
- **Peer DM visibility.** When a teammate sends a DM to another teammate, a brief summary is included in their idle notification. This gives you visibility into peer collaboration without the full message content. You do not need to respond to these summaries — they are informational.
|
|
128
|
+
|
|
129
|
+
## Discovering Team Members
|
|
130
|
+
|
|
131
|
+
Teammates can read the team config file to discover other team members:
|
|
132
|
+
- **Team config location**: `~/.illusion/teams/{team-name}/config.json`
|
|
133
|
+
|
|
134
|
+
The config file contains a `members` array with each teammate's:
|
|
135
|
+
- `name`: Human-readable name (**always use this** for messaging and task assignment)
|
|
136
|
+
- `agentId`: Unique identifier (for reference only - do not use for communication)
|
|
137
|
+
- `agentType`: Role/type of the agent
|
|
138
|
+
|
|
139
|
+
**IMPORTANT**: Always refer to teammates by their NAME (e.g., "team-lead", "researcher", "tester"). Names are used for:
|
|
140
|
+
- `to` when sending messages
|
|
141
|
+
- Identifying task owners
|
|
142
|
+
|
|
143
|
+
Example of reading team config:
|
|
144
|
+
```
|
|
145
|
+
Use the Read tool to read ~/.illusion/teams/{team-name}/config.json
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Task List Coordination
|
|
149
|
+
|
|
150
|
+
Teams share a task list that all teammates can access at `~/.illusion/data/tasks/{team-name}/`.
|
|
151
|
+
|
|
152
|
+
Teammates should:
|
|
153
|
+
1. Check TaskList periodically, **especially after completing each task**, to find available work or see newly unblocked tasks
|
|
154
|
+
2. Claim unassigned, unblocked tasks with TaskUpdate (set `owner` to your name). **Prefer tasks in ID order** (lowest ID first) when multiple tasks are available, as earlier tasks often set up context for later ones
|
|
155
|
+
3. Create new tasks with `TaskCreate` when identifying additional work
|
|
156
|
+
4. Mark tasks as completed with `TaskUpdate` when done, then check TaskList for next work
|
|
157
|
+
5. Coordinate with other teammates by reading the task list status
|
|
158
|
+
6. If all available tasks are blocked, notify the team lead or help resolve blocking tasks
|
|
159
|
+
|
|
160
|
+
**IMPORTANT notes for communication with your team**:
|
|
161
|
+
- Do not use terminal tools to view your team's activity; always send a message to your teammates (and remember, refer to them by name).
|
|
162
|
+
- Your team cannot hear you if you do not use the SendMessage tool. Always send a message to your teammates if you are responding to them.
|
|
163
|
+
- Do NOT send structured JSON status messages like `{"type":"idle",...}` or `{"type":"task_completed",...}`. Just communicate in plain text when you need to message teammates.
|
|
164
|
+
- Use TaskUpdate to mark tasks completed.
|
|
165
|
+
- If you are an agent in the team, the system will automatically send idle notifications to the team lead when you stop.
|
|
166
|
+
"""
|
|
167
|
+
input_model = TeamCreateToolInput
|
|
168
|
+
|
|
169
|
+
async def execute(self, arguments: TeamCreateToolInput, context: ToolExecutionContext) -> ToolResult:
|
|
170
|
+
team_name = arguments.team_name.strip()
|
|
171
|
+
if not team_name:
|
|
172
|
+
return ToolResult(output="team_name is required for team_create", is_error=True)
|
|
173
|
+
|
|
174
|
+
app_state_store = context.metadata.get("app_state_store")
|
|
175
|
+
if isinstance(app_state_store, AppStateStore):
|
|
176
|
+
existing_team = app_state_store.get().team_context
|
|
177
|
+
if isinstance(existing_team, dict) and existing_team.get("teamName"):
|
|
178
|
+
active_team = str(existing_team["teamName"])
|
|
179
|
+
return ToolResult(
|
|
180
|
+
output=(
|
|
181
|
+
f'Already leading team "{active_team}". '
|
|
182
|
+
"A leader can only manage one team at a time. "
|
|
183
|
+
"Use team_delete to end the current team before creating a new one."
|
|
184
|
+
),
|
|
185
|
+
is_error=True,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
final_team_name = _generate_unique_team_name(team_name)
|
|
189
|
+
lead_agent_id = f"{TEAM_LEAD_NAME}@{sanitize_name(final_team_name)}"
|
|
190
|
+
lead_agent_type = arguments.agent_type or TEAM_LEAD_NAME
|
|
191
|
+
team_file_path = str(get_team_file_path(final_team_name))
|
|
192
|
+
session_id = str(context.metadata.get("session_id") or "")
|
|
193
|
+
|
|
194
|
+
team_file = {
|
|
195
|
+
"name": final_team_name,
|
|
196
|
+
"description": arguments.description,
|
|
197
|
+
"createdAt": int(time.time() * 1000),
|
|
198
|
+
"leadAgentId": lead_agent_id,
|
|
199
|
+
"leadSessionId": session_id,
|
|
200
|
+
"members": [
|
|
201
|
+
{
|
|
202
|
+
"agentId": lead_agent_id,
|
|
203
|
+
"name": TEAM_LEAD_NAME,
|
|
204
|
+
"agentType": lead_agent_type,
|
|
205
|
+
"joinedAt": int(time.time() * 1000),
|
|
206
|
+
"tmuxPaneId": "",
|
|
207
|
+
"cwd": str(context.cwd),
|
|
208
|
+
"subscriptions": [],
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
write_team_file(final_team_name, team_file)
|
|
214
|
+
register_team_for_session_cleanup(final_team_name)
|
|
215
|
+
|
|
216
|
+
task_list_id = sanitize_name(final_team_name)
|
|
217
|
+
reset_task_list(task_list_id)
|
|
218
|
+
ensure_tasks_dir(task_list_id)
|
|
219
|
+
os.environ["ILLUSION_TASK_LIST_ID"] = task_list_id
|
|
220
|
+
|
|
221
|
+
if isinstance(app_state_store, AppStateStore):
|
|
222
|
+
app_state_store.set(
|
|
223
|
+
team_context={
|
|
224
|
+
"teamName": final_team_name,
|
|
225
|
+
"teamFilePath": team_file_path,
|
|
226
|
+
"leadAgentId": lead_agent_id,
|
|
227
|
+
}
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
output = {
|
|
231
|
+
"team_name": final_team_name,
|
|
232
|
+
"team_file_path": team_file_path,
|
|
233
|
+
"lead_agent_id": lead_agent_id,
|
|
234
|
+
}
|
|
235
|
+
return ToolResult(output=json.dumps(output, ensure_ascii=False))
|
|
236
|
+
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
团队删除工具
|
|
3
|
+
============
|
|
4
|
+
|
|
5
|
+
本模块提供 team_delete 工具,用于清理团队相关资源。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel
|
|
14
|
+
|
|
15
|
+
from illusion.state import AppStateStore
|
|
16
|
+
from illusion.swarm.team_helpers import (
|
|
17
|
+
TEAM_LEAD_NAME,
|
|
18
|
+
cleanup_team_directories,
|
|
19
|
+
read_team_file,
|
|
20
|
+
unregister_team_for_session_cleanup,
|
|
21
|
+
)
|
|
22
|
+
from illusion.tools.base import BaseTool, ToolExecutionContext, ToolResult
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TeamDeleteToolInput(BaseModel):
|
|
26
|
+
"""team_delete 输入参数(无参数)。"""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TeamDeleteTool(BaseTool):
|
|
30
|
+
"""删除当前团队并清理关联目录。"""
|
|
31
|
+
|
|
32
|
+
name = "team_delete"
|
|
33
|
+
description = """# TeamDelete
|
|
34
|
+
|
|
35
|
+
Remove team and task directories when the swarm work is complete.
|
|
36
|
+
|
|
37
|
+
This operation:
|
|
38
|
+
- Removes the team directory (`~/.illusion/teams/{team-name}/`)
|
|
39
|
+
- Removes the task directory (`~/.illusion/data/tasks/{team-name}/`)
|
|
40
|
+
- Clears team context from the current session
|
|
41
|
+
|
|
42
|
+
**IMPORTANT**: TeamDelete will fail if the team still has active members. Gracefully terminate teammates via `SendMessage` first, then call TeamDelete after all teammates have shut down.
|
|
43
|
+
|
|
44
|
+
Use this when all teammates have finished their work and you want to clean up the team resources. The team name is automatically determined from the current session's team context.
|
|
45
|
+
"""
|
|
46
|
+
input_model = TeamDeleteToolInput
|
|
47
|
+
|
|
48
|
+
async def execute(self, arguments: TeamDeleteToolInput, context: ToolExecutionContext) -> ToolResult:
|
|
49
|
+
del arguments
|
|
50
|
+
app_state_store = context.metadata.get("app_state_store")
|
|
51
|
+
|
|
52
|
+
team_name: str | None = None
|
|
53
|
+
if isinstance(app_state_store, AppStateStore):
|
|
54
|
+
team_context = app_state_store.get().team_context
|
|
55
|
+
if isinstance(team_context, dict):
|
|
56
|
+
raw = team_context.get("teamName")
|
|
57
|
+
if isinstance(raw, str) and raw.strip():
|
|
58
|
+
team_name = raw
|
|
59
|
+
|
|
60
|
+
if team_name:
|
|
61
|
+
team_file = read_team_file(team_name)
|
|
62
|
+
if team_file:
|
|
63
|
+
members = team_file.get("members", [])
|
|
64
|
+
if isinstance(members, list):
|
|
65
|
+
non_lead_members = [
|
|
66
|
+
member
|
|
67
|
+
for member in members
|
|
68
|
+
if isinstance(member, dict) and member.get("name") != TEAM_LEAD_NAME
|
|
69
|
+
]
|
|
70
|
+
active_members = [
|
|
71
|
+
member
|
|
72
|
+
for member in non_lead_members
|
|
73
|
+
if member.get("isActive", member.get("is_active", True)) is not False
|
|
74
|
+
]
|
|
75
|
+
if active_members:
|
|
76
|
+
member_names = ", ".join(str(member.get("name", "")) for member in active_members)
|
|
77
|
+
output = {
|
|
78
|
+
"success": False,
|
|
79
|
+
"message": (
|
|
80
|
+
f"Cannot cleanup team with {len(active_members)} active member(s): "
|
|
81
|
+
f"{member_names}. Use SendMessage to gracefully terminate teammates first."
|
|
82
|
+
),
|
|
83
|
+
"team_name": team_name,
|
|
84
|
+
}
|
|
85
|
+
return ToolResult(output=json.dumps(output, ensure_ascii=False))
|
|
86
|
+
|
|
87
|
+
cleanup_team_directories(team_name)
|
|
88
|
+
unregister_team_for_session_cleanup(team_name)
|
|
89
|
+
os.environ.pop("ILLUSION_TASK_LIST_ID", None)
|
|
90
|
+
|
|
91
|
+
if isinstance(app_state_store, AppStateStore):
|
|
92
|
+
app_state_store.set(team_context=None)
|
|
93
|
+
|
|
94
|
+
output = {
|
|
95
|
+
"success": True,
|
|
96
|
+
"message": (
|
|
97
|
+
f'Cleaned up directories and worktrees for team "{team_name}"'
|
|
98
|
+
if team_name
|
|
99
|
+
else "No team name found, nothing to clean up"
|
|
100
|
+
),
|
|
101
|
+
"team_name": team_name,
|
|
102
|
+
}
|
|
103
|
+
return ToolResult(output=json.dumps(output, ensure_ascii=False))
|
|
104
|
+
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO写入工具模块
|
|
3
|
+
================
|
|
4
|
+
|
|
5
|
+
本模块提供编码会话结构化任务列表的管理功能。
|
|
6
|
+
|
|
7
|
+
主要功能:
|
|
8
|
+
- 创建和管理结构化任务列表
|
|
9
|
+
- 跟踪当前编码会话的进度
|
|
10
|
+
- 展示任务的整体进度给用户
|
|
11
|
+
|
|
12
|
+
类说明:
|
|
13
|
+
- TodoWriteToolInput: TODO写入工具输入参数
|
|
14
|
+
- TodoWriteTool: TODO写入工具类
|
|
15
|
+
|
|
16
|
+
使用示例:
|
|
17
|
+
>>> # 通过全量替换更新任务列表
|
|
18
|
+
>>> # 工具将任务状态存入执行结果的元数据中
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from pydantic import BaseModel, Field
|
|
24
|
+
|
|
25
|
+
from illusion.tools.base import BaseTool, ToolExecutionContext, ToolResult
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class TodoItem(BaseModel):
|
|
29
|
+
"""TODO项数据模型
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
content: 任务描述(祈使形式)
|
|
33
|
+
status: 任务状态(pending/in_progress/completed)
|
|
34
|
+
activeForm: 执行时显示的进行时形式
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
content: str = Field(min_length=1)
|
|
38
|
+
status: str = Field(pattern=r"^(pending|in_progress|completed)$")
|
|
39
|
+
activeForm: str = Field(min_length=1)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class TodoWriteToolInput(BaseModel):
|
|
43
|
+
"""TODO写入工具的参数模型
|
|
44
|
+
|
|
45
|
+
Attributes:
|
|
46
|
+
todos: TODO项列表,每项包含content/status/activeForm
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
todos: list[TodoItem] = Field(description="List of todo items to update")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TodoWriteTool(BaseTool):
|
|
53
|
+
"""创建和管理当前编码会话的结构化任务列表。
|
|
54
|
+
|
|
55
|
+
通过全量替换的方式更新任务列表,要删除某个任务只需在下一次调用中不再包含它。
|
|
56
|
+
这有助于您跟踪进度、组织复杂任务,并展示给用户您的周到性。
|
|
57
|
+
它还帮助用户了解任务进度和整体请求进度。
|
|
58
|
+
|
|
59
|
+
何时使用此工具:
|
|
60
|
+
在以下场景中主动使用此工具:
|
|
61
|
+
|
|
62
|
+
1. 复杂的多步骤任务 - 当任务需要3个或更多不同步骤或操作时
|
|
63
|
+
2. 非平凡和复杂的任务 - 需要仔细规划或多个操作的任务
|
|
64
|
+
3. 用户明确请求TODO列表 - 当用户直接要求您使用TODO列表时
|
|
65
|
+
4. 用户提供多个任务 - 当用户提供要做的事情列表时(用数字或逗号分隔)
|
|
66
|
+
5. 收到新指令后 - 立即将用户需求捕获为TODO
|
|
67
|
+
6. 开始任务时 - 在开始工作之前将其标记为in_progress。理想情况下,您应该一次只有一个TODO为in_progress
|
|
68
|
+
7. 完成任务后 - 立即将其标记为completed,并在实施过程中添加发现的新后续任务
|
|
69
|
+
|
|
70
|
+
何时不使用此工具:
|
|
71
|
+
|
|
72
|
+
仅对简单任务跳过使用此工具:
|
|
73
|
+
- 只有单一、直接的任务
|
|
74
|
+
- 任务 trivial,跟踪它没有组织好处
|
|
75
|
+
- 任务可以在3个简单步骤内完成
|
|
76
|
+
- 任务纯粹是对话式或信息性的
|
|
77
|
+
|
|
78
|
+
注意:如果只有一个简单的任务要处理,您不应该使用此工具。
|
|
79
|
+
在这种情况下,您最好直接完成任务。
|
|
80
|
+
|
|
81
|
+
任务状态和管理:
|
|
82
|
+
|
|
83
|
+
1. **任务状态**:使用这些状态跟踪进度:
|
|
84
|
+
- pending: 任务尚未开始
|
|
85
|
+
- in_progress: 当前正在处理(一次限制为一个任务)
|
|
86
|
+
- completed: 任务成功完成
|
|
87
|
+
|
|
88
|
+
**重要**:任务描述必须有两种形式:
|
|
89
|
+
- content: 描述需要做什么的祈使形式(例如,"运行测试"、"构建项目")
|
|
90
|
+
- activeForm: 执行期间显示的现在进行时形式(例如,"正在运行测试"、"正在构建项目")
|
|
91
|
+
|
|
92
|
+
2. **任务管理**:
|
|
93
|
+
- 工作时实时更新任务状态
|
|
94
|
+
- 完成后立即标记任务(不要批量完成)
|
|
95
|
+
- 任何时候必须恰好有一个任务为in_progress(不少于,也不多于)
|
|
96
|
+
- 在开始新任务之前完成当前任务
|
|
97
|
+
- 从列表中完全删除不再相关的任务
|
|
98
|
+
|
|
99
|
+
3. **任务完成要求**:
|
|
100
|
+
- 仅在完全完成时才将任务标记为completed
|
|
101
|
+
- 如果遇到错误、阻塞或无法完成,请保持任务为in_progress
|
|
102
|
+
- 被阻塞时,创建描述需要解决的新任务
|
|
103
|
+
- 永远不要将任务标记为completed如果:
|
|
104
|
+
- 测试失败
|
|
105
|
+
- 实现不完整
|
|
106
|
+
- 遇到未解决的错误
|
|
107
|
+
- 找不到必要的文件或依赖
|
|
108
|
+
|
|
109
|
+
4. **任务分解**:
|
|
110
|
+
- 创建具体、可操作的项目
|
|
111
|
+
- 将复杂任务分解为更小、可管理的步骤
|
|
112
|
+
- 使用清晰、描述性的任务名称
|
|
113
|
+
- 始终提供两种形式:
|
|
114
|
+
- content: "修复认证bug"
|
|
115
|
+
- activeForm: "正在修复认证bug"
|
|
116
|
+
|
|
117
|
+
如有疑问,请使用此工具。主动的任务管理展示 attentive 并确保您成功完成所有要求。
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
name = "todo_write"
|
|
121
|
+
description = """Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
|
|
122
|
+
It also helps the user understand the progress of the task and overall progress of their requests.
|
|
123
|
+
|
|
124
|
+
## When to Use This Tool
|
|
125
|
+
Use this tool proactively in these scenarios:
|
|
126
|
+
|
|
127
|
+
1. Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
|
|
128
|
+
2. Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
|
|
129
|
+
3. User explicitly requests todo list - When the user directly asks you to use the todo list
|
|
130
|
+
4. User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
|
|
131
|
+
5. After receiving new instructions - Immediately capture user requirements as todos
|
|
132
|
+
6. When you start working on a task - Mark it as in_progress BEFORE beginning work. Ideally you should only have one todo as in_progress at a time
|
|
133
|
+
7. After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
|
|
134
|
+
|
|
135
|
+
## When NOT to Use This Tool
|
|
136
|
+
|
|
137
|
+
Skip using this tool when:
|
|
138
|
+
1. There is only a single, straightforward task
|
|
139
|
+
2. The task is trivial and tracking it provides no organizational benefit
|
|
140
|
+
3. The task can be completed in less than 3 trivial steps
|
|
141
|
+
4. The task is purely conversational or informational
|
|
142
|
+
|
|
143
|
+
NOTE that you should not use this tool if there is only one trivial task to do. In this case you are better off just doing the task directly.
|
|
144
|
+
|
|
145
|
+
## Task States and Management
|
|
146
|
+
|
|
147
|
+
1. **Task States**: Use these states to track progress:
|
|
148
|
+
- pending: Task not yet started
|
|
149
|
+
- in_progress: Currently working on (limit to ONE task at a time)
|
|
150
|
+
- completed: Task finished successfully
|
|
151
|
+
|
|
152
|
+
**IMPORTANT**: Task descriptions must have two forms:
|
|
153
|
+
- content: The imperative form describing what needs to be done (e.g., "Run tests", "Build the project")
|
|
154
|
+
- activeForm: The present continuous form shown during execution (e.g., "Running tests", "Building the project")
|
|
155
|
+
|
|
156
|
+
2. **Task Management**:
|
|
157
|
+
- Update task status in real-time as you work
|
|
158
|
+
- Mark tasks complete IMMEDIATELY after finishing (don't batch completions)
|
|
159
|
+
- Exactly ONE task must be in_progress at any time (not less, not more)
|
|
160
|
+
- Complete current tasks before starting new ones
|
|
161
|
+
- Remove tasks that are no longer relevant from the list entirely
|
|
162
|
+
|
|
163
|
+
3. **Task Completion Requirements**:
|
|
164
|
+
- ONLY mark a task as completed when you have FULLY accomplished it
|
|
165
|
+
- If you encounter errors, blockers, or cannot finish, keep the task as in_progress
|
|
166
|
+
- When blocked, create a new task describing what needs to be resolved
|
|
167
|
+
- Never mark a task as completed if:
|
|
168
|
+
- Tests are failing
|
|
169
|
+
- Implementation is partial
|
|
170
|
+
- You encountered unresolved errors
|
|
171
|
+
- You couldn't find necessary files or dependencies
|
|
172
|
+
|
|
173
|
+
4. **Task Breakdown**:
|
|
174
|
+
- Create specific, actionable items
|
|
175
|
+
- Break complex tasks into smaller, manageable steps
|
|
176
|
+
- Use clear, descriptive task names
|
|
177
|
+
- Always provide both forms:
|
|
178
|
+
- content: "Fix authentication bug"
|
|
179
|
+
- activeForm: "Fixing authentication bug"
|
|
180
|
+
|
|
181
|
+
When in doubt, use this tool. Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully."""
|
|
182
|
+
input_model = TodoWriteToolInput
|
|
183
|
+
|
|
184
|
+
async def execute(self, arguments: TodoWriteToolInput, context: ToolExecutionContext) -> ToolResult:
|
|
185
|
+
"""执行TODO写入操作
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
arguments: 工具输入参数
|
|
189
|
+
context: 工具执行上下文
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
ToolResult: 执行结果
|
|
193
|
+
"""
|
|
194
|
+
todos_data = [item.model_dump() for item in arguments.todos]
|
|
195
|
+
all_done = all(item.status == "completed" for item in arguments.todos)
|
|
196
|
+
if all_done and len(arguments.todos) >= 1:
|
|
197
|
+
todos_data = []
|
|
198
|
+
return ToolResult(output="Todos updated", metadata={"todos": todos_data})
|