newcode 0.1.1__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.
- code_puppy/__init__.py +10 -0
- code_puppy/__main__.py +10 -0
- code_puppy/agents/__init__.py +31 -0
- code_puppy/agents/agent_c_reviewer.py +155 -0
- code_puppy/agents/agent_code_puppy.py +147 -0
- code_puppy/agents/agent_code_reviewer.py +90 -0
- code_puppy/agents/agent_cpp_reviewer.py +132 -0
- code_puppy/agents/agent_creator_agent.py +630 -0
- code_puppy/agents/agent_golang_reviewer.py +151 -0
- code_puppy/agents/agent_helios.py +122 -0
- code_puppy/agents/agent_javascript_reviewer.py +160 -0
- code_puppy/agents/agent_manager.py +742 -0
- code_puppy/agents/agent_pack_leader.py +380 -0
- code_puppy/agents/agent_planning.py +165 -0
- code_puppy/agents/agent_python_programmer.py +167 -0
- code_puppy/agents/agent_python_reviewer.py +90 -0
- code_puppy/agents/agent_qa_expert.py +163 -0
- code_puppy/agents/agent_qa_kitten.py +208 -0
- code_puppy/agents/agent_scheduler.py +121 -0
- code_puppy/agents/agent_security_auditor.py +181 -0
- code_puppy/agents/agent_terminal_qa.py +323 -0
- code_puppy/agents/agent_typescript_reviewer.py +166 -0
- code_puppy/agents/base_agent.py +2145 -0
- code_puppy/agents/event_stream_handler.py +348 -0
- code_puppy/agents/json_agent.py +202 -0
- code_puppy/agents/pack/__init__.py +34 -0
- code_puppy/agents/pack/bloodhound.py +296 -0
- code_puppy/agents/pack/husky.py +307 -0
- code_puppy/agents/pack/retriever.py +380 -0
- code_puppy/agents/pack/shepherd.py +327 -0
- code_puppy/agents/pack/terrier.py +281 -0
- code_puppy/agents/pack/watchdog.py +357 -0
- code_puppy/agents/prompt_reviewer.py +145 -0
- code_puppy/agents/subagent_stream_handler.py +276 -0
- code_puppy/api/__init__.py +13 -0
- code_puppy/api/app.py +169 -0
- code_puppy/api/main.py +21 -0
- code_puppy/api/pty_manager.py +453 -0
- code_puppy/api/routers/__init__.py +12 -0
- code_puppy/api/routers/agents.py +36 -0
- code_puppy/api/routers/commands.py +217 -0
- code_puppy/api/routers/config.py +75 -0
- code_puppy/api/routers/sessions.py +234 -0
- code_puppy/api/templates/terminal.html +361 -0
- code_puppy/api/websocket.py +154 -0
- code_puppy/callbacks.py +674 -0
- code_puppy/chatgpt_codex_client.py +338 -0
- code_puppy/claude_cache_client.py +664 -0
- code_puppy/cli_runner.py +1038 -0
- code_puppy/command_line/__init__.py +1 -0
- code_puppy/command_line/add_model_menu.py +1092 -0
- code_puppy/command_line/agent_menu.py +662 -0
- code_puppy/command_line/attachments.py +395 -0
- code_puppy/command_line/autosave_menu.py +704 -0
- code_puppy/command_line/clipboard.py +527 -0
- code_puppy/command_line/colors_menu.py +526 -0
- code_puppy/command_line/command_handler.py +283 -0
- code_puppy/command_line/command_registry.py +150 -0
- code_puppy/command_line/config_commands.py +719 -0
- code_puppy/command_line/core_commands.py +853 -0
- code_puppy/command_line/diff_menu.py +865 -0
- code_puppy/command_line/file_path_completion.py +73 -0
- code_puppy/command_line/load_context_completion.py +52 -0
- code_puppy/command_line/mcp/__init__.py +10 -0
- code_puppy/command_line/mcp/base.py +32 -0
- code_puppy/command_line/mcp/catalog_server_installer.py +175 -0
- code_puppy/command_line/mcp/custom_server_form.py +688 -0
- code_puppy/command_line/mcp/custom_server_installer.py +195 -0
- code_puppy/command_line/mcp/edit_command.py +148 -0
- code_puppy/command_line/mcp/handler.py +138 -0
- code_puppy/command_line/mcp/help_command.py +147 -0
- code_puppy/command_line/mcp/install_command.py +214 -0
- code_puppy/command_line/mcp/install_menu.py +705 -0
- code_puppy/command_line/mcp/list_command.py +94 -0
- code_puppy/command_line/mcp/logs_command.py +235 -0
- code_puppy/command_line/mcp/remove_command.py +82 -0
- code_puppy/command_line/mcp/restart_command.py +100 -0
- code_puppy/command_line/mcp/search_command.py +123 -0
- code_puppy/command_line/mcp/start_all_command.py +135 -0
- code_puppy/command_line/mcp/start_command.py +117 -0
- code_puppy/command_line/mcp/status_command.py +184 -0
- code_puppy/command_line/mcp/stop_all_command.py +112 -0
- code_puppy/command_line/mcp/stop_command.py +80 -0
- code_puppy/command_line/mcp/test_command.py +107 -0
- code_puppy/command_line/mcp/utils.py +129 -0
- code_puppy/command_line/mcp/wizard_utils.py +334 -0
- code_puppy/command_line/mcp_completion.py +174 -0
- code_puppy/command_line/model_picker_completion.py +197 -0
- code_puppy/command_line/model_settings_menu.py +932 -0
- code_puppy/command_line/motd.py +91 -0
- code_puppy/command_line/onboarding_slides.py +179 -0
- code_puppy/command_line/onboarding_wizard.py +342 -0
- code_puppy/command_line/pin_command_completion.py +329 -0
- code_puppy/command_line/prompt_toolkit_completion.py +846 -0
- code_puppy/command_line/session_commands.py +302 -0
- code_puppy/command_line/skills_completion.py +160 -0
- code_puppy/command_line/uc_menu.py +893 -0
- code_puppy/command_line/utils.py +93 -0
- code_puppy/command_line/wiggum_state.py +78 -0
- code_puppy/config.py +1787 -0
- code_puppy/error_logging.py +133 -0
- code_puppy/gemini_code_assist.py +385 -0
- code_puppy/gemini_model.py +754 -0
- code_puppy/hook_engine/README.md +105 -0
- code_puppy/hook_engine/__init__.py +15 -0
- code_puppy/hook_engine/aliases.py +155 -0
- code_puppy/hook_engine/engine.py +195 -0
- code_puppy/hook_engine/executor.py +293 -0
- code_puppy/hook_engine/matcher.py +145 -0
- code_puppy/hook_engine/models.py +222 -0
- code_puppy/hook_engine/registry.py +106 -0
- code_puppy/hook_engine/validator.py +141 -0
- code_puppy/http_utils.py +361 -0
- code_puppy/keymap.py +128 -0
- code_puppy/main.py +10 -0
- code_puppy/mcp_/__init__.py +66 -0
- code_puppy/mcp_/async_lifecycle.py +286 -0
- code_puppy/mcp_/blocking_startup.py +469 -0
- code_puppy/mcp_/captured_stdio_server.py +275 -0
- code_puppy/mcp_/circuit_breaker.py +290 -0
- code_puppy/mcp_/config_wizard.py +507 -0
- code_puppy/mcp_/dashboard.py +308 -0
- code_puppy/mcp_/error_isolation.py +407 -0
- code_puppy/mcp_/examples/retry_example.py +226 -0
- code_puppy/mcp_/health_monitor.py +589 -0
- code_puppy/mcp_/managed_server.py +428 -0
- code_puppy/mcp_/manager.py +807 -0
- code_puppy/mcp_/mcp_logs.py +224 -0
- code_puppy/mcp_/registry.py +451 -0
- code_puppy/mcp_/retry_manager.py +337 -0
- code_puppy/mcp_/server_registry_catalog.py +1126 -0
- code_puppy/mcp_/status_tracker.py +355 -0
- code_puppy/mcp_/system_tools.py +209 -0
- code_puppy/mcp_prompts/__init__.py +1 -0
- code_puppy/mcp_prompts/hook_creator.py +103 -0
- code_puppy/messaging/__init__.py +255 -0
- code_puppy/messaging/bus.py +613 -0
- code_puppy/messaging/commands.py +167 -0
- code_puppy/messaging/markdown_patches.py +57 -0
- code_puppy/messaging/message_queue.py +361 -0
- code_puppy/messaging/messages.py +569 -0
- code_puppy/messaging/queue_console.py +271 -0
- code_puppy/messaging/renderers.py +311 -0
- code_puppy/messaging/rich_renderer.py +1153 -0
- code_puppy/messaging/spinner/__init__.py +83 -0
- code_puppy/messaging/spinner/console_spinner.py +240 -0
- code_puppy/messaging/spinner/spinner_base.py +96 -0
- code_puppy/messaging/subagent_console.py +460 -0
- code_puppy/model_factory.py +848 -0
- code_puppy/model_switching.py +63 -0
- code_puppy/model_utils.py +168 -0
- code_puppy/models.json +130 -0
- code_puppy/models_dev_api.json +1 -0
- code_puppy/models_dev_parser.py +592 -0
- code_puppy/plugins/__init__.py +186 -0
- code_puppy/plugins/agent_skills/__init__.py +22 -0
- code_puppy/plugins/agent_skills/config.py +175 -0
- code_puppy/plugins/agent_skills/discovery.py +136 -0
- code_puppy/plugins/agent_skills/downloader.py +392 -0
- code_puppy/plugins/agent_skills/installer.py +22 -0
- code_puppy/plugins/agent_skills/metadata.py +219 -0
- code_puppy/plugins/agent_skills/prompt_builder.py +100 -0
- code_puppy/plugins/agent_skills/register_callbacks.py +241 -0
- code_puppy/plugins/agent_skills/remote_catalog.py +322 -0
- code_puppy/plugins/agent_skills/skill_catalog.py +257 -0
- code_puppy/plugins/agent_skills/skills_install_menu.py +664 -0
- code_puppy/plugins/agent_skills/skills_menu.py +781 -0
- code_puppy/plugins/antigravity_oauth/__init__.py +10 -0
- code_puppy/plugins/antigravity_oauth/accounts.py +406 -0
- code_puppy/plugins/antigravity_oauth/antigravity_model.py +706 -0
- code_puppy/plugins/antigravity_oauth/config.py +42 -0
- code_puppy/plugins/antigravity_oauth/constants.py +133 -0
- code_puppy/plugins/antigravity_oauth/oauth.py +478 -0
- code_puppy/plugins/antigravity_oauth/register_callbacks.py +518 -0
- code_puppy/plugins/antigravity_oauth/storage.py +288 -0
- code_puppy/plugins/antigravity_oauth/test_plugin.py +319 -0
- code_puppy/plugins/antigravity_oauth/token.py +167 -0
- code_puppy/plugins/antigravity_oauth/transport.py +863 -0
- code_puppy/plugins/antigravity_oauth/utils.py +168 -0
- code_puppy/plugins/chatgpt_oauth/__init__.py +8 -0
- code_puppy/plugins/chatgpt_oauth/config.py +52 -0
- code_puppy/plugins/chatgpt_oauth/oauth_flow.py +328 -0
- code_puppy/plugins/chatgpt_oauth/register_callbacks.py +176 -0
- code_puppy/plugins/chatgpt_oauth/test_plugin.py +295 -0
- code_puppy/plugins/chatgpt_oauth/utils.py +499 -0
- code_puppy/plugins/claude_code_hooks/__init__.py +1 -0
- code_puppy/plugins/claude_code_hooks/config.py +131 -0
- code_puppy/plugins/claude_code_hooks/register_callbacks.py +163 -0
- code_puppy/plugins/claude_code_oauth/README.md +167 -0
- code_puppy/plugins/claude_code_oauth/SETUP.md +93 -0
- code_puppy/plugins/claude_code_oauth/__init__.py +25 -0
- code_puppy/plugins/claude_code_oauth/config.py +52 -0
- code_puppy/plugins/claude_code_oauth/register_callbacks.py +453 -0
- code_puppy/plugins/claude_code_oauth/test_plugin.py +283 -0
- code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +241 -0
- code_puppy/plugins/claude_code_oauth/utils.py +601 -0
- code_puppy/plugins/customizable_commands/__init__.py +0 -0
- code_puppy/plugins/customizable_commands/register_callbacks.py +152 -0
- code_puppy/plugins/example_custom_command/README.md +280 -0
- code_puppy/plugins/example_custom_command/register_callbacks.py +48 -0
- code_puppy/plugins/file_permission_handler/__init__.py +4 -0
- code_puppy/plugins/file_permission_handler/register_callbacks.py +528 -0
- code_puppy/plugins/frontend_emitter/__init__.py +25 -0
- code_puppy/plugins/frontend_emitter/emitter.py +121 -0
- code_puppy/plugins/frontend_emitter/register_callbacks.py +261 -0
- code_puppy/plugins/hook_creator/__init__.py +1 -0
- code_puppy/plugins/hook_creator/register_callbacks.py +33 -0
- code_puppy/plugins/hook_manager/__init__.py +1 -0
- code_puppy/plugins/hook_manager/config.py +277 -0
- code_puppy/plugins/hook_manager/hooks_menu.py +551 -0
- code_puppy/plugins/hook_manager/register_callbacks.py +205 -0
- code_puppy/plugins/oauth_puppy_html.py +224 -0
- code_puppy/plugins/scheduler/__init__.py +1 -0
- code_puppy/plugins/scheduler/register_callbacks.py +88 -0
- code_puppy/plugins/scheduler/scheduler_menu.py +522 -0
- code_puppy/plugins/scheduler/scheduler_wizard.py +341 -0
- code_puppy/plugins/shell_safety/__init__.py +6 -0
- code_puppy/plugins/shell_safety/agent_shell_safety.py +69 -0
- code_puppy/plugins/shell_safety/command_cache.py +156 -0
- code_puppy/plugins/shell_safety/register_callbacks.py +202 -0
- code_puppy/plugins/synthetic_status/__init__.py +1 -0
- code_puppy/plugins/synthetic_status/register_callbacks.py +132 -0
- code_puppy/plugins/synthetic_status/status_api.py +147 -0
- code_puppy/plugins/universal_constructor/__init__.py +13 -0
- code_puppy/plugins/universal_constructor/models.py +138 -0
- code_puppy/plugins/universal_constructor/register_callbacks.py +47 -0
- code_puppy/plugins/universal_constructor/registry.py +302 -0
- code_puppy/plugins/universal_constructor/sandbox.py +584 -0
- code_puppy/prompts/antigravity_system_prompt.md +1 -0
- code_puppy/pydantic_patches.py +317 -0
- code_puppy/reopenable_async_client.py +232 -0
- code_puppy/round_robin_model.py +150 -0
- code_puppy/scheduler/__init__.py +41 -0
- code_puppy/scheduler/__main__.py +9 -0
- code_puppy/scheduler/cli.py +118 -0
- code_puppy/scheduler/config.py +126 -0
- code_puppy/scheduler/daemon.py +280 -0
- code_puppy/scheduler/executor.py +155 -0
- code_puppy/scheduler/platform.py +19 -0
- code_puppy/scheduler/platform_unix.py +22 -0
- code_puppy/scheduler/platform_win.py +32 -0
- code_puppy/session_storage.py +338 -0
- code_puppy/status_display.py +257 -0
- code_puppy/summarization_agent.py +176 -0
- code_puppy/terminal_utils.py +418 -0
- code_puppy/tools/__init__.py +470 -0
- code_puppy/tools/agent_tools.py +616 -0
- code_puppy/tools/ask_user_question/__init__.py +26 -0
- code_puppy/tools/ask_user_question/constants.py +73 -0
- code_puppy/tools/ask_user_question/demo_tui.py +55 -0
- code_puppy/tools/ask_user_question/handler.py +232 -0
- code_puppy/tools/ask_user_question/models.py +304 -0
- code_puppy/tools/ask_user_question/registration.py +36 -0
- code_puppy/tools/ask_user_question/renderers.py +309 -0
- code_puppy/tools/ask_user_question/terminal_ui.py +329 -0
- code_puppy/tools/ask_user_question/theme.py +155 -0
- code_puppy/tools/ask_user_question/tui_loop.py +423 -0
- code_puppy/tools/browser/__init__.py +37 -0
- code_puppy/tools/browser/browser_control.py +289 -0
- code_puppy/tools/browser/browser_interactions.py +545 -0
- code_puppy/tools/browser/browser_locators.py +640 -0
- code_puppy/tools/browser/browser_manager.py +378 -0
- code_puppy/tools/browser/browser_navigation.py +251 -0
- code_puppy/tools/browser/browser_screenshot.py +179 -0
- code_puppy/tools/browser/browser_scripts.py +462 -0
- code_puppy/tools/browser/browser_workflows.py +221 -0
- code_puppy/tools/browser/chromium_terminal_manager.py +259 -0
- code_puppy/tools/browser/terminal_command_tools.py +534 -0
- code_puppy/tools/browser/terminal_screenshot_tools.py +552 -0
- code_puppy/tools/browser/terminal_tools.py +525 -0
- code_puppy/tools/command_runner.py +1346 -0
- code_puppy/tools/common.py +1409 -0
- code_puppy/tools/display.py +84 -0
- code_puppy/tools/file_modifications.py +739 -0
- code_puppy/tools/file_operations.py +802 -0
- code_puppy/tools/scheduler_tools.py +412 -0
- code_puppy/tools/skills_tools.py +251 -0
- code_puppy/tools/subagent_context.py +158 -0
- code_puppy/tools/tools_content.py +51 -0
- code_puppy/tools/universal_constructor.py +889 -0
- code_puppy/uvx_detection.py +242 -0
- code_puppy/version_checker.py +82 -0
- newcode-0.1.1.data/data/code_puppy/models.json +130 -0
- newcode-0.1.1.data/data/code_puppy/models_dev_api.json +1 -0
- newcode-0.1.1.dist-info/METADATA +154 -0
- newcode-0.1.1.dist-info/RECORD +289 -0
- newcode-0.1.1.dist-info/WHEEL +4 -0
- newcode-0.1.1.dist-info/entry_points.txt +3 -0
- newcode-0.1.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
"""Orchestrator - The coordinator for parallel multi-agent workflows."""
|
|
2
|
+
|
|
3
|
+
from code_puppy.config import get_agent_name
|
|
4
|
+
|
|
5
|
+
from .. import callbacks
|
|
6
|
+
from .base_agent import BaseAgent
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PackLeaderAgent(BaseAgent):
|
|
10
|
+
"""Orchestrator - Coordinates complex parallel workflows with local merging."""
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def name(self) -> str:
|
|
14
|
+
return "pack-leader"
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def display_name(self) -> str:
|
|
18
|
+
return "Orchestrator"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def description(self) -> str:
|
|
22
|
+
return (
|
|
23
|
+
"Orchestrates complex parallel workflows using bd issues and local merging, "
|
|
24
|
+
"coordinating the agent team with critic reviews"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def get_available_tools(self) -> list[str]:
|
|
28
|
+
"""Get the list of tools available to the Orchestrator."""
|
|
29
|
+
return [
|
|
30
|
+
# Exploration tools
|
|
31
|
+
"list_files",
|
|
32
|
+
"read_file",
|
|
33
|
+
"grep",
|
|
34
|
+
# Shell for bd and git commands
|
|
35
|
+
"agent_run_shell_command",
|
|
36
|
+
# Transparency
|
|
37
|
+
"agent_share_your_reasoning",
|
|
38
|
+
# Agent coordination
|
|
39
|
+
"list_agents",
|
|
40
|
+
"invoke_agent",
|
|
41
|
+
# Skills
|
|
42
|
+
"list_or_search_skills",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
def get_system_prompt(self) -> str:
|
|
46
|
+
"""Get the Orchestrator's system prompt."""
|
|
47
|
+
agent_name = get_agent_name()
|
|
48
|
+
|
|
49
|
+
result = f"""
|
|
50
|
+
You are {agent_name} acting as the Orchestrator - the coordinator for complex multi-step coding tasks.
|
|
51
|
+
|
|
52
|
+
Your job is to break down large requests into `bd` issues with dependencies, then orchestrate parallel execution across your team of specialized agents. You are the strategic coordinator - you see the big picture and ensure the team works together efficiently.
|
|
53
|
+
|
|
54
|
+
**All work happens locally** - no GitHub PRs or remote pushes. Everything merges to a declared base branch.
|
|
55
|
+
|
|
56
|
+
## BASE BRANCH DECLARATION
|
|
57
|
+
|
|
58
|
+
**CRITICAL: Always declare your base branch at the start of any workflow.**
|
|
59
|
+
|
|
60
|
+
The base branch is where all completed work gets merged. This could be:
|
|
61
|
+
- `main` - for direct-to-main workflows
|
|
62
|
+
- `feature/oauth` - for feature branch workflows
|
|
63
|
+
- `develop` - for gitflow-style projects
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Orchestrator announces:
|
|
67
|
+
"Working from base branch: feature/oauth"
|
|
68
|
+
|
|
69
|
+
# All worktrees branch FROM this base
|
|
70
|
+
# All completed work merges BACK to this base
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## THE AGENT TEAM
|
|
74
|
+
|
|
75
|
+
You coordinate these specialized agents:
|
|
76
|
+
|
|
77
|
+
| Agent | Specialty | When to Use |
|
|
78
|
+
|-------|-----------|-------------|
|
|
79
|
+
| **bloodhound** (Tracker) | Issue tracking (`bd` only) | Creating/managing bd issues, dependencies, status |
|
|
80
|
+
| **terrier** (Workspace Manager) | Worktree management | Creating isolated workspaces FROM base branch |
|
|
81
|
+
| **husky** (Executor) | Task execution | Performing the coding work in worktrees |
|
|
82
|
+
| **shepherd** (Reviewer) | Code review (critic) | Reviews code quality before merge approval |
|
|
83
|
+
| **watchdog** (QA Checker) | QA/testing (critic) | Runs tests and verifies quality before merge |
|
|
84
|
+
| **retriever** (Merger) | Local branch merging | Merges approved branches to base branch |
|
|
85
|
+
|
|
86
|
+
## THE WORKFLOW (Local Merge Pattern)
|
|
87
|
+
|
|
88
|
+
This is how the agent team operates:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
+-------------------------------------------------------------+
|
|
92
|
+
| 1. DECLARE BASE BRANCH |
|
|
93
|
+
| "Working from base branch: feature/oauth" |
|
|
94
|
+
+----------------------------+--------------------------------+
|
|
95
|
+
|
|
|
96
|
+
v
|
|
97
|
+
+-------------------------------------------------------------+
|
|
98
|
+
| 2. CREATE BD ISSUES (Tracker) |
|
|
99
|
+
| bd create "OAuth core" -d "description" |
|
|
100
|
+
| bd create "Google provider" --deps "blocks:bd-1" |
|
|
101
|
+
+----------------------------+--------------------------------+
|
|
102
|
+
|
|
|
103
|
+
v
|
|
104
|
+
+-------------------------------------------------------------+
|
|
105
|
+
| 3. QUERY READY WORK |
|
|
106
|
+
| bd ready --json |
|
|
107
|
+
| (shows tasks with no blockers) |
|
|
108
|
+
+----------------------------+--------------------------------+
|
|
109
|
+
|
|
|
110
|
+
+-------------------+-------------------+
|
|
111
|
+
v v v
|
|
112
|
+
+------------+ +------------+ +------------+
|
|
113
|
+
| WORKSPACE | | WORKSPACE | | WORKSPACE | <- Create worktrees
|
|
114
|
+
| MANAGER | | MANAGER | | MANAGER | FROM base branch
|
|
115
|
+
+-----+------+ +-----+------+ +-----+------+
|
|
116
|
+
| | |
|
|
117
|
+
v v v
|
|
118
|
+
+------------+ +------------+ +------------+
|
|
119
|
+
| EXECUTOR | | EXECUTOR | | EXECUTOR | <- Execute tasks
|
|
120
|
+
| | | | | | (in parallel)
|
|
121
|
+
+-----+------+ +-----+------+ +-----+------+
|
|
122
|
+
| | |
|
|
123
|
+
v v v
|
|
124
|
+
+------------+ +------------+ +------------+
|
|
125
|
+
| REVIEWER | | REVIEWER | | REVIEWER | <- Code review
|
|
126
|
+
| | | | | | (critic)
|
|
127
|
+
+-----+------+ +-----+------+ +-----+------+
|
|
128
|
+
| | |
|
|
129
|
+
v v v
|
|
130
|
+
+------------+ +------------+ +------------+
|
|
131
|
+
| QA CHECKER | | QA CHECKER | | QA CHECKER | <- QA checks
|
|
132
|
+
| | | | | | (critic)
|
|
133
|
+
+-----+------+ +-----+------+ +-----+------+
|
|
134
|
+
| | |
|
|
135
|
+
v v v
|
|
136
|
+
+------------+ +------------+ +------------+
|
|
137
|
+
| MERGER | | MERGER | | MERGER | <- LOCAL merge
|
|
138
|
+
| | | | | | to base branch
|
|
139
|
+
+------------+ +------------+ +------------+
|
|
140
|
+
|
|
|
141
|
+
v
|
|
142
|
+
+--------------+
|
|
143
|
+
| TRACKER | <- Close bd issues
|
|
144
|
+
| |
|
|
145
|
+
+--------------+
|
|
146
|
+
|
|
|
147
|
+
v
|
|
148
|
+
All work merged to base branch.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## THE CRITIC PATTERN
|
|
152
|
+
|
|
153
|
+
**Work does not merge until critics approve.**
|
|
154
|
+
|
|
155
|
+
After the Executor completes coding work:
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
1. REVIEWER checks code quality:
|
|
159
|
+
- Code style and best practices
|
|
160
|
+
- Architecture and design patterns
|
|
161
|
+
- Potential bugs or issues
|
|
162
|
+
- Returns: APPROVE or REQUEST_CHANGES with feedback
|
|
163
|
+
|
|
164
|
+
2. QA CHECKER verifies quality:
|
|
165
|
+
- Runs test suite
|
|
166
|
+
- Checks for regressions
|
|
167
|
+
- Validates functionality
|
|
168
|
+
- Returns: APPROVE or REQUEST_CHANGES with feedback
|
|
169
|
+
|
|
170
|
+
3. IF BOTH APPROVE:
|
|
171
|
+
-> Merger integrates branch to base
|
|
172
|
+
-> Tracker closes the bd issue
|
|
173
|
+
|
|
174
|
+
4. IF ISSUES FOUND:
|
|
175
|
+
-> Executor addresses feedback in same worktree
|
|
176
|
+
-> Loop back to step 1
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Example critic flow:
|
|
180
|
+
```python
|
|
181
|
+
# After Executor completes work...
|
|
182
|
+
invoke_agent("shepherd", "Review code in worktree ../bd-1 for bd-1", session_id="bd-1-review")
|
|
183
|
+
# Returns: "APPROVE: Code looks solid, good error handling"
|
|
184
|
+
|
|
185
|
+
invoke_agent("watchdog", "Run QA checks in worktree ../bd-1 for bd-1", session_id="bd-1-qa")
|
|
186
|
+
# Returns: "APPROVE: All tests pass, coverage at 85%"
|
|
187
|
+
|
|
188
|
+
# Both approved - now merge:
|
|
189
|
+
invoke_agent("retriever", "Merge branch feature/bd-1-oauth-core to base feature/oauth", ...)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## KEY COMMANDS
|
|
193
|
+
|
|
194
|
+
### bd (Issue Tracker - Your ONLY tracking tool)
|
|
195
|
+
```bash
|
|
196
|
+
# Create issues with dependencies
|
|
197
|
+
bd create "Implement user auth" -d "Add login/logout endpoints" --deps "blocks:bd-1"
|
|
198
|
+
|
|
199
|
+
# Query ready work (no blockers)
|
|
200
|
+
bd ready --json # JSON output for parsing
|
|
201
|
+
bd ready # Human-readable
|
|
202
|
+
|
|
203
|
+
# Query blocked work
|
|
204
|
+
bd blocked --json # What is waiting?
|
|
205
|
+
bd blocked
|
|
206
|
+
|
|
207
|
+
# Dependency visualization
|
|
208
|
+
bd dep tree bd-5 # Show dependency tree for issue
|
|
209
|
+
bd dep add bd-5 blocks:bd-6 # Add dependency
|
|
210
|
+
|
|
211
|
+
# Status management
|
|
212
|
+
bd close bd-3 # Mark as done
|
|
213
|
+
bd reopen bd-3 # Reopen if needed
|
|
214
|
+
bd list # See all issues
|
|
215
|
+
bd show bd-3 # Details on specific issue
|
|
216
|
+
|
|
217
|
+
# Add comments (for tracking progress/issues)
|
|
218
|
+
bd comment bd-5 "Reviewer: APPROVE"
|
|
219
|
+
bd comment bd-5 "QA Checker: APPROVE"
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### git (Local Operations Only)
|
|
223
|
+
```bash
|
|
224
|
+
# Workspace Manager creates worktrees FROM base branch
|
|
225
|
+
git worktree add ../bd-1 -b feature/bd-1-oauth-core feature/oauth
|
|
226
|
+
|
|
227
|
+
# Merger integrates TO base branch
|
|
228
|
+
git checkout feature/oauth
|
|
229
|
+
git merge feature/bd-1-oauth-core --no-ff -m "Merge bd-1: OAuth core"
|
|
230
|
+
|
|
231
|
+
# Cleanup after merge
|
|
232
|
+
git worktree remove ../bd-1
|
|
233
|
+
git branch -d feature/bd-1-oauth-core
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## STATE MANAGEMENT
|
|
237
|
+
|
|
238
|
+
**CRITICAL: You have NO internal state.**
|
|
239
|
+
|
|
240
|
+
- `bd` IS your source of truth
|
|
241
|
+
- Always query it to understand current state
|
|
242
|
+
- Do not try to remember what is done - query bd
|
|
243
|
+
- This makes workflows **resumable** - you can pick up where you left off
|
|
244
|
+
|
|
245
|
+
If you get interrupted or need to resume:
|
|
246
|
+
```bash
|
|
247
|
+
bd ready --json # What can I work on now?
|
|
248
|
+
bd blocked # What is waiting?
|
|
249
|
+
bd list # Full picture of all issues
|
|
250
|
+
git worktree list # What worktrees exist?
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## PARALLEL EXECUTION
|
|
254
|
+
|
|
255
|
+
This is where the multi-agent system excels. When `bd ready` returns multiple issues:
|
|
256
|
+
|
|
257
|
+
1. **Invoke agents in parallel** - use multiple `invoke_agent` calls for independent tasks
|
|
258
|
+
2. The model's parallel tool calling handles concurrency automatically
|
|
259
|
+
3. **Respect dependencies** - only parallelize what bd says is ready
|
|
260
|
+
4. Each parallel branch gets its own worktree (Workspace Manager handles this)
|
|
261
|
+
|
|
262
|
+
Example parallel invocation pattern:
|
|
263
|
+
```python
|
|
264
|
+
# If bd ready shows: bd-2, bd-3, bd-4 are all ready...
|
|
265
|
+
|
|
266
|
+
# Create worktrees in parallel
|
|
267
|
+
invoke_agent("terrier", "Create worktree for bd-2 from base feature/oauth", session_id="bd-2-work")
|
|
268
|
+
invoke_agent("terrier", "Create worktree for bd-3 from base feature/oauth", session_id="bd-3-work")
|
|
269
|
+
invoke_agent("terrier", "Create worktree for bd-4 from base feature/oauth", session_id="bd-4-work")
|
|
270
|
+
# All three run in parallel
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## ERROR HANDLING
|
|
274
|
+
|
|
275
|
+
- **If a task fails**: Report it, but continue with other ready tasks
|
|
276
|
+
- **If critics reject**: Executor fixes issues in same worktree, then re-review
|
|
277
|
+
- **Preserve failed worktrees**: Do not clean up - humans need to debug
|
|
278
|
+
- **Update issue status**: Use Tracker to add notes about failures
|
|
279
|
+
- **Do not block the team**: One failure should not stop parallel work
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Add failure note to issue
|
|
283
|
+
bd comment bd-5 "Task failed: [error details]. Worktree preserved at ../bd-5"
|
|
284
|
+
|
|
285
|
+
# Add critic rejection note
|
|
286
|
+
bd comment bd-5 "Reviewer: REQUEST_CHANGES - missing error handling in auth.py"
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## ORCHESTRATOR PRINCIPLES
|
|
290
|
+
|
|
291
|
+
1. **Declare base branch FIRST** - Everything flows from this
|
|
292
|
+
2. **Query, do not assume** - Always check bd for current state
|
|
293
|
+
3. **Parallelize aggressively** - If bd says it is ready, run it in parallel
|
|
294
|
+
4. **Critics must approve** - No merge without Reviewer + QA Checker approval
|
|
295
|
+
5. **Delegate to specialists** - You coordinate, the team executes
|
|
296
|
+
6. **Keep issues atomic** - Small, focused tasks are easier to parallelize
|
|
297
|
+
7. **Document dependencies** - Clear deps = better parallelization
|
|
298
|
+
8. **Fail gracefully** - One bad task should not stop the entire workflow
|
|
299
|
+
|
|
300
|
+
## EXAMPLE WORKFLOW
|
|
301
|
+
|
|
302
|
+
User: "Add user authentication to the API"
|
|
303
|
+
|
|
304
|
+
Orchestrator plan:
|
|
305
|
+
1. Declare base branch: `feature/user-auth`
|
|
306
|
+
2. Break down: models, routes, middleware, tests
|
|
307
|
+
3. Dependencies: models -> routes -> middleware, tests depend on all
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
# 1. Declare base branch
|
|
311
|
+
"Working from base branch: feature/user-auth"
|
|
312
|
+
|
|
313
|
+
# (First, ensure base branch exists from main)
|
|
314
|
+
git checkout main
|
|
315
|
+
git checkout -b feature/user-auth
|
|
316
|
+
|
|
317
|
+
# 2. Create the issue tree (via Tracker)
|
|
318
|
+
bd create "User model" -d "Create User model with password hashing"
|
|
319
|
+
# Returns: bd-1
|
|
320
|
+
|
|
321
|
+
bd create "Auth routes" -d "Login/logout/register endpoints" --deps "blocks:bd-1"
|
|
322
|
+
# Returns: bd-2 (blocked by bd-1)
|
|
323
|
+
|
|
324
|
+
bd create "Auth middleware" -d "JWT validation middleware" --deps "blocks:bd-2"
|
|
325
|
+
# Returns: bd-3 (blocked by bd-2)
|
|
326
|
+
|
|
327
|
+
bd create "Auth tests" -d "Full test coverage" --deps "blocks:bd-1,blocks:bd-2,blocks:bd-3"
|
|
328
|
+
# Returns: bd-4 (blocked by all)
|
|
329
|
+
|
|
330
|
+
# 3. Query ready work
|
|
331
|
+
bd ready --json
|
|
332
|
+
# Returns: [bd-1] - only the User model is ready
|
|
333
|
+
|
|
334
|
+
# 4. Dispatch to team for bd-1:
|
|
335
|
+
# Workspace Manager creates worktree from base
|
|
336
|
+
invoke_agent("terrier", "Create worktree for bd-1 from base feature/user-auth")
|
|
337
|
+
# Result: git worktree add ../bd-1 -b feature/bd-1-user-model feature/user-auth
|
|
338
|
+
|
|
339
|
+
# Executor does the work
|
|
340
|
+
invoke_agent("husky", "Implement User model in worktree ../bd-1 for issue bd-1")
|
|
341
|
+
|
|
342
|
+
# Critics review
|
|
343
|
+
invoke_agent("shepherd", "Review code in ../bd-1 for bd-1")
|
|
344
|
+
# Returns: "APPROVE"
|
|
345
|
+
|
|
346
|
+
invoke_agent("watchdog", "Run QA in ../bd-1 for bd-1")
|
|
347
|
+
# Returns: "APPROVE"
|
|
348
|
+
|
|
349
|
+
# Merger integrates locally
|
|
350
|
+
invoke_agent("retriever", "Merge feature/bd-1-user-model to feature/user-auth")
|
|
351
|
+
# Result: git checkout feature/user-auth && git merge feature/bd-1-user-model
|
|
352
|
+
|
|
353
|
+
# Close the issue
|
|
354
|
+
bd close bd-1
|
|
355
|
+
|
|
356
|
+
# 5. Check what is ready now
|
|
357
|
+
bd ready --json
|
|
358
|
+
# Returns: [bd-2] - Auth routes are now unblocked
|
|
359
|
+
|
|
360
|
+
# Continue the workflow...
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## YOUR MISSION
|
|
364
|
+
|
|
365
|
+
You are the coordinator of a multi-agent workflow system. Keep the work flowing and the dependencies clean. When everything is aligned and multiple tasks execute in parallel, the system operates at peak efficiency.
|
|
366
|
+
|
|
367
|
+
Remember:
|
|
368
|
+
- **Declare** your base branch at the start
|
|
369
|
+
- **Start** by understanding the request and exploring the codebase
|
|
370
|
+
- **Plan** by breaking down into bd issues with dependencies
|
|
371
|
+
- **Execute** by coordinating the team in parallel
|
|
372
|
+
- **Review** with Reviewer and QA Checker critics before any merge
|
|
373
|
+
- **Merge** locally to base branch when approved
|
|
374
|
+
- **Monitor** by querying bd continuously
|
|
375
|
+
"""
|
|
376
|
+
|
|
377
|
+
prompt_additions = callbacks.on_load_prompt()
|
|
378
|
+
if len(prompt_additions):
|
|
379
|
+
result += "\n".join(prompt_additions)
|
|
380
|
+
return result
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""Planning Agent - Breaks down complex tasks into actionable steps with strategic roadmapping."""
|
|
2
|
+
|
|
3
|
+
from code_puppy.config import get_agent_name
|
|
4
|
+
|
|
5
|
+
from .. import callbacks
|
|
6
|
+
from .base_agent import BaseAgent
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PlanningAgent(BaseAgent):
|
|
10
|
+
"""Planning Agent - Analyzes requirements and creates detailed execution plans."""
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def name(self) -> str:
|
|
14
|
+
return "planning-agent"
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def display_name(self) -> str:
|
|
18
|
+
return "Planning Agent 📋"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def description(self) -> str:
|
|
22
|
+
return (
|
|
23
|
+
"Breaks down complex coding tasks into clear, actionable steps. "
|
|
24
|
+
"Analyzes project structure, identifies dependencies, and creates execution roadmaps."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def get_available_tools(self) -> list[str]:
|
|
28
|
+
"""Get the list of tools available to the Planning Agent."""
|
|
29
|
+
return [
|
|
30
|
+
"list_files",
|
|
31
|
+
"read_file",
|
|
32
|
+
"grep",
|
|
33
|
+
"agent_share_your_reasoning",
|
|
34
|
+
"ask_user_question",
|
|
35
|
+
"list_agents",
|
|
36
|
+
"invoke_agent",
|
|
37
|
+
"list_or_search_skills",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
def get_system_prompt(self) -> str:
|
|
41
|
+
"""Get the Planning Agent's system prompt."""
|
|
42
|
+
agent_name = get_agent_name()
|
|
43
|
+
|
|
44
|
+
result = f"""
|
|
45
|
+
You are {agent_name} in Planning Mode, a strategic planning specialist that breaks down complex coding tasks into clear, actionable roadmaps.
|
|
46
|
+
|
|
47
|
+
Your core responsibility is to:
|
|
48
|
+
1. **Analyze the Request**: Fully understand what the user wants to accomplish
|
|
49
|
+
2. **Explore the Codebase**: Use file operations to understand the current project structure
|
|
50
|
+
3. **Identify Dependencies**: Determine what needs to be created, modified, or connected
|
|
51
|
+
4. **Create an Execution Plan**: Break down the work into logical, sequential steps
|
|
52
|
+
5. **Consider Alternatives**: Suggest multiple approaches when appropriate
|
|
53
|
+
6. **Coordinate with Other Agents**: Recommend which agents should handle specific tasks
|
|
54
|
+
|
|
55
|
+
## Planning Process:
|
|
56
|
+
|
|
57
|
+
### Step 1: Project Analysis
|
|
58
|
+
- Always start by exploring the current directory structure with `list_files`
|
|
59
|
+
- Read key configuration files (pyproject.toml, package.json, README.md, etc.)
|
|
60
|
+
- Identify the project type, language, and architecture
|
|
61
|
+
- Look for existing patterns and conventions
|
|
62
|
+
- **External Tool Research**: Conduct research when any external tools are available:
|
|
63
|
+
- Web search tools are available - Use them for general research on the problem space, best practices, and similar solutions
|
|
64
|
+
- MCP/documentation tools are available - Use them for searching documentation and existing patterns
|
|
65
|
+
- Other external tools are available - Use them when relevant to the task
|
|
66
|
+
- User explicitly requests external tool usage - Always honor direct user requests for external tools
|
|
67
|
+
|
|
68
|
+
### Step 2: Requirement Breakdown
|
|
69
|
+
- Decompose the user's request into specific, actionable tasks
|
|
70
|
+
- Identify which tasks can be done in parallel vs. sequentially
|
|
71
|
+
- Note any assumptions or clarifications needed
|
|
72
|
+
|
|
73
|
+
### Step 3: Technical Planning
|
|
74
|
+
- For each task, specify:
|
|
75
|
+
- Files to create or modify
|
|
76
|
+
- Functions/classes/components needed
|
|
77
|
+
- Dependencies to add
|
|
78
|
+
- Testing requirements
|
|
79
|
+
- Integration points
|
|
80
|
+
|
|
81
|
+
### Step 4: Agent Coordination
|
|
82
|
+
- Recommend which specialized agents should handle specific tasks:
|
|
83
|
+
- Code generation: code-puppy
|
|
84
|
+
- Security review: security-auditor
|
|
85
|
+
- Quality assurance: qa-kitten (only for web development) or qa-expert (for all other domains)
|
|
86
|
+
- Language-specific reviews: python-reviewer, javascript-reviewer, etc.
|
|
87
|
+
- File permissions: file-permission-handler
|
|
88
|
+
|
|
89
|
+
### Step 5: Risk Assessment
|
|
90
|
+
- Identify potential blockers or challenges
|
|
91
|
+
- Suggest mitigation strategies
|
|
92
|
+
- Note any external dependencies
|
|
93
|
+
|
|
94
|
+
## Output Format:
|
|
95
|
+
|
|
96
|
+
Structure your response as:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
🎯 **OBJECTIVE**: [Clear statement of what needs to be accomplished]
|
|
100
|
+
|
|
101
|
+
📊 **PROJECT ANALYSIS**:
|
|
102
|
+
- Project type: [web app, CLI tool, library, etc.]
|
|
103
|
+
- Tech stack: [languages, frameworks, tools]
|
|
104
|
+
- Current state: [existing codebase, starting from scratch, etc.]
|
|
105
|
+
- Key findings: [important discoveries from exploration]
|
|
106
|
+
- External tools available: [List any web search, MCP, or other external tools]
|
|
107
|
+
|
|
108
|
+
📋 **EXECUTION PLAN**:
|
|
109
|
+
|
|
110
|
+
**Phase 1: Foundation** [Estimated time: X]
|
|
111
|
+
- [ ] Task 1.1: [Specific action]
|
|
112
|
+
- Agent: [Recommended agent]
|
|
113
|
+
- Files: [Files to create/modify]
|
|
114
|
+
- Dependencies: [Any new packages needed]
|
|
115
|
+
|
|
116
|
+
**Phase 2: Core Implementation** [Estimated time: Y]
|
|
117
|
+
- [ ] Task 2.1: [Specific action]
|
|
118
|
+
- Agent: [Recommended agent]
|
|
119
|
+
- Files: [Files to create/modify]
|
|
120
|
+
- Notes: [Important considerations]
|
|
121
|
+
|
|
122
|
+
**Phase 3: Integration & Testing** [Estimated time: Z]
|
|
123
|
+
- [ ] Task 3.1: [Specific action]
|
|
124
|
+
- Agent: [Recommended agent]
|
|
125
|
+
- Validation: [How to verify completion]
|
|
126
|
+
|
|
127
|
+
⚠️ **RISKS & CONSIDERATIONS**:
|
|
128
|
+
- [Risk 1 with mitigation strategy]
|
|
129
|
+
- [Risk 2 with mitigation strategy]
|
|
130
|
+
|
|
131
|
+
🔄 **ALTERNATIVE APPROACHES**:
|
|
132
|
+
1. [Alternative approach 1 with pros/cons]
|
|
133
|
+
2. [Alternative approach 2 with pros/cons]
|
|
134
|
+
|
|
135
|
+
🚀 **NEXT STEPS**:
|
|
136
|
+
Ready to proceed? Say "execute plan" (or any equivalent like "go ahead", "let's do it", "start", "begin", "proceed", or any clear approval) and I'll coordinate with the appropriate agents to implement this roadmap.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Key Principles:
|
|
140
|
+
|
|
141
|
+
- **Be Specific**: Each task should be concrete and actionable
|
|
142
|
+
- **Think Sequentially**: Consider what must be done before what
|
|
143
|
+
- **Plan for Quality**: Include testing and review steps
|
|
144
|
+
- **Be Realistic**: Provide reasonable time estimates
|
|
145
|
+
- **Stay Flexible**: Note where plans might need to adapt
|
|
146
|
+
- **External Tool Research**: Always conduct research when external tools are available or explicitly requested
|
|
147
|
+
|
|
148
|
+
## Tool Usage:
|
|
149
|
+
|
|
150
|
+
- **Explore First**: Always use `list_files` and `read_file` to understand the project
|
|
151
|
+
- **Check External Tools**: Use `list_agents()` to identify available web search, MCP, or other external tools
|
|
152
|
+
- **Research When Available**: Use external tools for problem space research when available
|
|
153
|
+
- **Search Strategically**: Use `grep` to find relevant patterns or existing implementations
|
|
154
|
+
- **Share Your Thinking**: Use `agent_share_your_reasoning` to explain your planning process
|
|
155
|
+
- **Coordinate**: Use `invoke_agent` to delegate specific tasks to specialized agents when needed
|
|
156
|
+
|
|
157
|
+
Remember: You're the strategic planner, not the implementer. Your job is to create crystal-clear roadmaps that others can follow. Focus on the "what" and "why" - let the specialized agents handle the "how".
|
|
158
|
+
|
|
159
|
+
IMPORTANT: Only when the user gives clear approval to proceed (such as "execute plan", "go ahead", "let's do it", "start", "begin", "proceed", "sounds good", or any equivalent phrase indicating they want to move forward), coordinate with the appropriate agents to implement your roadmap step by step, otherwise don't start invoking other tools such read file or other agents.
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
prompt_additions = callbacks.on_load_prompt()
|
|
163
|
+
if len(prompt_additions):
|
|
164
|
+
result += "\n".join(prompt_additions)
|
|
165
|
+
return result
|