diff --git a/docs/integrations/roo-code/index.md b/docs/integrations/roo-code/index.md deleted file mode 100644 index 9129d09..0000000 --- a/docs/integrations/roo-code/index.md +++ /dev/null @@ -1,33 +0,0 @@ -# Testing and Installing the Evolve Roo Code Mode - -This guide explains how to install the custom Evolve mode into your local Roo Code extension and verify that it enforces the required workflow. - -## Prerequisites -1. You must have the **Roo Code** extension installed in VS Code. -2. You must have the **Evolve MCP Server** configured in your Roo Code settings. For instructions on how to start the Evolve MCP server, please refer to the [Running the MCP Server](../../../README.md#running-the-mcp-server) section in the main README or the detailed [Configuration Guide](../../../CONFIGURATION.md). (If it is not configured, the agent will not be able to call `get_guidelines` or `save_trajectory`). - -## Step 1: Install the Custom Mode -1. Open the `Evolve-export.yaml` file located in this repository folder. -2. Depending on your Roo Code version, you can either import this YAML directly or manually copy the `slug`, `name`, `roleDefinition`, `customInstructions`, and `groups` into a new Custom Mode in the Roo Code settings UI. -3. In VS Code, open the Roo Code extension panel. -4. Click the **Settings** gear icon (⚙️) in the top right of the Roo Code panel. -5. Scroll down to the **Custom Modes** section. -6. Paste the configuration fields you copied into the Custom Modes text area. -7. Click **Save**. -8. You should now see a new mode called **Evolve** in the mode dropdown menu at the bottom of the Roo Code chat panel. - -> **Alternative method:** If you already have a `.roomodes` file in the root of your workspace, you can convert the `Evolve-export.yaml` to JSON and append it to your existing `.roomodes` file. - -## Step 2: Test the Workflow -To ensure the custom instructions are working correctly, try giving the Evolve mode a simple, generic task. - -1. Select the **Evolve** mode from the dropdown in Roo Code. -2. Enter a prompt like: - * `"Create a simple python script that prints hello world. Complete the task as fast as possible."` -3. **Observe the Agent's Behavior:** - * **CORRECT BEHAVIOR:** The agent *must* first attempt to use the `get_guidelines` MCP tool. After writing the script, it *must* attempt to use the `save_trajectory` tool and ask for your permission to proceed *before* calling its built-in `attempt_completion` tool. - * **INCORRECT BEHAVIOR:** If the agent simply writes the script and finishes the task without calling the MCP tools, the prompt instructions are not being respected, or the MCP server is not connected. - -## Step 3: Test the Rejection Logic -1. If the agent tries to call `attempt_completion` without first calling `save_trajectory`, you should **Reject** the completion and remind it: *"You forgot to call save_trajectory first as per your instructions."* -2. A successful test means the agent obeys the workflow described in its `roleDefinition` perfectly. diff --git a/platform-integrations/bob/evolve-full/TESTING.md b/platform-integrations/bob/evolve-full/TESTING.md new file mode 100644 index 0000000..eec3bd4 --- /dev/null +++ b/platform-integrations/bob/evolve-full/TESTING.md @@ -0,0 +1,19 @@ +# Testing the Evolve Full Mode with MCP + +This guide explains how to verify that the Evolve mode is working correctly in Bob (Roo Code) when using full mode with MCP server integration. + +## Test the Workflow + +To ensure the custom instructions are working correctly, try giving the Evolve mode a simple, generic task. + +1. Select the **Evolve** mode from the dropdown in Bob. +2. Enter a prompt like: + * `"Create a simple python script that prints hello world. Complete the task as fast as possible."` +3. **Observe the Agent's Behavior:** + * **CORRECT BEHAVIOR:** The agent *must* first attempt to use the `get_guidelines` MCP tool. After writing the script, it *must* attempt to use the `save_trajectory` tool and ask for your permission to proceed *before* calling its built-in `attempt_completion` tool. + * **INCORRECT BEHAVIOR:** If the agent simply writes the script and finishes the task without calling the MCP tools, the prompt instructions are not being respected, or the MCP server is not connected. + +## Test the Rejection Logic + +1. If the agent tries to call `attempt_completion` without first calling `save_trajectory`, you should **Reject** the completion and remind it: *"You forgot to call save_trajectory first as per your instructions."* +2. A successful test means the agent obeys the workflow described in its `roleDefinition` perfectly. \ No newline at end of file diff --git a/docs/integrations/roo-code/Evolve-export.yaml b/platform-integrations/bob/evolve-full/custom_modes.yaml similarity index 98% rename from docs/integrations/roo-code/Evolve-export.yaml rename to platform-integrations/bob/evolve-full/custom_modes.yaml index 63cc363..c24c701 100644 --- a/docs/integrations/roo-code/Evolve-export.yaml +++ b/platform-integrations/bob/evolve-full/custom_modes.yaml @@ -168,6 +168,9 @@ customModes: - save_trajectory() requires OpenAI JSON format: [{"role": "user/assistant", "content": "..."}] + - When tool calls occur, include them as function_call/function_response + objects in the content field + - Agent cannot access conversation history directly - save_trajectory() cannot be called automatically diff --git a/platform-integrations/install.sh b/platform-integrations/install.sh index 87daf38..1b7c54d 100755 --- a/platform-integrations/install.sh +++ b/platform-integrations/install.sh @@ -502,32 +502,36 @@ def install_bob(source_dir, target_dir, mode="lite"): info(f"Installing Bob ({mode} mode) → {bob_target}") - # Shared lib (entity_io) — single source of truth lives in the Claude plugin - shared_lib = Path(source_dir) / "platform-integrations" / "claude" / "plugins" / "evolve-lite" / "lib" - if not shared_lib.is_dir(): - error(f"Shared lib not found: {shared_lib} — is the Claude plugin present in the source tree?") - sys.exit(1) - copy_tree(shared_lib, bob_target / "evolve-lib") - success("Copied Bob lib") - - # Skills - copy_tree(bob_source_lite / "skills" / "evolve-learn", bob_target / "skills" / "evolve-learn") - copy_tree(bob_source_lite / "skills" / "evolve-recall", bob_target / "skills" / "evolve-recall") - success("Copied Bob skills") - - # Commands - copy_tree(bob_source_lite / "commands", bob_target / "commands") - success("Copied Bob commands") - - # custom_modes.yaml - source_modes_yaml = bob_source_lite / "custom_modes.yaml" - target_modes_yaml = bob_target / "custom_modes.yaml" - merge_yaml_custom_mode(source_modes_yaml, target_modes_yaml, BOB_SLUG) - success(f"Merged custom mode '{BOB_SLUG}' into {target_modes_yaml}") - - # Full mode: mcp.json - if mode == "full": - mcp_source = Path(source_dir) / "platform-integrations" / "bob" / "evolve-full" / "mcp.json" + if mode == "lite": + # Shared lib (entity_io) — single source of truth lives in the Claude plugin + shared_lib = Path(source_dir) / "platform-integrations" / "claude" / "plugins" / "evolve-lite" / "lib" + if not shared_lib.is_dir(): + error(f"Shared lib not found: {shared_lib} — is the Claude plugin present in the source tree?") + sys.exit(1) + copy_tree(shared_lib, bob_target / "evolve-lib") + success("Copied Bob lib") + + # Skills + copy_tree(bob_source_lite / "skills" / "evolve-learn", bob_target / "skills" / "evolve-learn") + copy_tree(bob_source_lite / "skills" / "evolve-recall", bob_target / "skills" / "evolve-recall") + success("Copied Bob skills") + + # Commands + copy_tree(bob_source_lite / "commands", bob_target / "commands") + success("Copied Bob commands") + + # custom_modes.yaml + source_modes_yaml = bob_source_lite / "custom_modes.yaml" + target_modes_yaml = bob_target / "custom_modes.yaml" + merge_yaml_custom_mode(source_modes_yaml, target_modes_yaml, BOB_SLUG) + success(f"Merged custom mode '{BOB_SLUG}' into {target_modes_yaml}") + + elif mode == "full": + # Full mode: mcp.json and custom_modes.yaml + bob_source_full = Path(source_dir) / "platform-integrations" / "bob" / "evolve-full" + + # MCP configuration + mcp_source = bob_source_full / "mcp.json" if not mcp_source.exists(): error(f"Source MCP config not found: {mcp_source}") sys.exit(1) @@ -537,6 +541,12 @@ def install_bob(source_dir, target_dir, mode="lite"): evolve_server = mcp_data["mcpServers"]["evolve"] upsert_json_key(mcp_target, ["mcpServers", "evolve"], evolve_server) success(f"Upserted MCP server config in {mcp_target}") + + # custom_modes.yaml + source_modes_yaml = bob_source_full / "custom_modes.yaml" + target_modes_yaml = bob_target / "custom_modes.yaml" + merge_yaml_custom_mode(source_modes_yaml, target_modes_yaml, "Evolve") + success(f"Merged custom mode 'Evolve' into {target_modes_yaml}") success("Bob installation complete") @@ -550,7 +560,9 @@ def uninstall_bob(target_dir, mode="full"): remove_dir(bob_target / "skills" / "evolve-recall") remove_file(bob_target / "commands" / "evolve:learn.md") remove_file(bob_target / "commands" / "evolve:recall.md") - remove_yaml_custom_mode(bob_target / "custom_modes.yaml", BOB_SLUG) + # Remove both lite and full mode custom modes + remove_yaml_custom_mode(bob_target / "custom_modes.yaml", BOB_SLUG) # evolve-lite + remove_yaml_custom_mode(bob_target / "custom_modes.yaml", "Evolve") # full mode remove_json_key(bob_target / "mcp.json", ["mcpServers", "evolve"]) success("Bob uninstall complete") diff --git a/tests/platform_integrations/test_preservation.py b/tests/platform_integrations/test_preservation.py index 8b2a898..a9b61bd 100644 --- a/tests/platform_integrations/test_preservation.py +++ b/tests/platform_integrations/test_preservation.py @@ -88,8 +88,33 @@ def test_preserves_existing_mcp_servers(self, temp_project_dir, install_runner, current_data = json.loads(mcp_file.read_text()) assert current_data["mcpServers"]["my-server"] == original_data["mcpServers"]["my-server"] - def test_preserves_all_bob_content_together(self, temp_project_dir, install_runner, bob_fixtures, file_assertions): - """Install evolve when user has all types of Bob content - all must be preserved.""" + def test_preserves_all_bob_content_together_lite(self, temp_project_dir, install_runner, bob_fixtures, file_assertions): + """Install evolve lite mode when user has all types of Bob content - all must be preserved.""" + # Setup: Create all types of user content + custom_skill = bob_fixtures.create_existing_skill(temp_project_dir) + custom_command = bob_fixtures.create_existing_command(temp_project_dir) + custom_modes = bob_fixtures.create_existing_custom_modes(temp_project_dir) + + # Save original content + skill_content = (custom_skill / "SKILL.md").read_text() + command_content = custom_command.read_text() + + # Action: Install evolve lite mode + install_runner.run("install", platform="bob", mode="lite") + + # Assert: ALL user content is preserved + file_assertions.assert_file_unchanged(custom_skill / "SKILL.md", skill_content) + file_assertions.assert_file_unchanged(custom_command, command_content) + + assert "slug: my-mode" in custom_modes.read_text() + + # Assert: Evolve lite content is added + bob_dir = temp_project_dir / ".bob" + file_assertions.assert_dir_exists(bob_dir / "skills" / "evolve-learn") + file_assertions.assert_sentinel_block_exists(custom_modes, "evolve-lite") + + def test_preserves_all_bob_content_together_full(self, temp_project_dir, install_runner, bob_fixtures, file_assertions): + """Install evolve full mode when user has all types of Bob content - all must be preserved.""" # Setup: Create all types of user content custom_skill = bob_fixtures.create_existing_skill(temp_project_dir) custom_command = bob_fixtures.create_existing_command(temp_project_dir) @@ -113,10 +138,8 @@ def test_preserves_all_bob_content_together(self, temp_project_dir, install_runn current_mcp = json.loads(mcp_config.read_text()) assert current_mcp["mcpServers"]["my-server"] == mcp_data["mcpServers"]["my-server"] - # Assert: Evolve content is added - bob_dir = temp_project_dir / ".bob" - file_assertions.assert_dir_exists(bob_dir / "skills" / "evolve-learn") - file_assertions.assert_sentinel_block_exists(custom_modes, "evolve-lite") + # Assert: Evolve full mode content is added (MCP and Evolve custom mode) + file_assertions.assert_sentinel_block_exists(custom_modes, "Evolve") file_assertions.assert_json_has_key(mcp_config, ["mcpServers", "evolve"])