From b9c4f27b1e3e680f2ef1c5260d9da9fd55dc6ddb Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 21 Mar 2025 21:35:32 -0400 Subject: [PATCH 1/2] feat: implement sub-agent workflow modes (disabled, sync, async) (fixes #344) --- mycoder.config.js | 3 + packages/agent/src/tools/getTools.ts | 35 ++++-- packages/cli/src/commands/$default.ts | 1 + packages/cli/src/commands/tools.ts | 2 +- packages/cli/src/options.ts | 6 + packages/cli/src/settings/config.ts | 3 + packages/docs/docs/usage/configuration.md | 12 +- packages/docs/docs/usage/sub-agent-modes.md | 119 ++++++++++++++++++++ 8 files changed, 166 insertions(+), 15 deletions(-) create mode 100644 packages/docs/docs/usage/sub-agent-modes.md diff --git a/mycoder.config.js b/mycoder.config.js index 638b983..cbeff9e 100644 --- a/mycoder.config.js +++ b/mycoder.config.js @@ -20,6 +20,9 @@ export default { // executablePath: null, // e.g., '/path/to/chrome' }, + // Sub-agent workflow mode: 'disabled', 'sync', or 'async' (default) + subAgentMode: 'async', + // Model settings //provider: 'anthropic', //model: 'claude-3-7-sonnet-20250219', diff --git a/packages/agent/src/tools/getTools.ts b/packages/agent/src/tools/getTools.ts index f4406d8..27c0755 100644 --- a/packages/agent/src/tools/getTools.ts +++ b/packages/agent/src/tools/getTools.ts @@ -3,6 +3,7 @@ import { Tool } from '../core/types.js'; // Import tools import { agentDoneTool } from './agent/agentDone.js'; +import { agentExecuteTool } from './agent/agentExecute.js'; import { agentMessageTool } from './agent/agentMessage.js'; import { agentStartTool } from './agent/agentStart.js'; import { listAgentsTool } from './agent/listAgents.js'; @@ -21,38 +22,52 @@ import { textEditorTool } from './textEditor/textEditor.js'; // Import these separately to avoid circular dependencies +/** + * Sub-agent workflow modes + * - disabled: No sub-agent tools are available + * - sync: Parent agent waits for sub-agent completion before continuing + * - async: Sub-agents run in the background, parent can check status and provide guidance + */ +export type SubAgentMode = 'disabled' | 'sync' | 'async'; + interface GetToolsOptions { userPrompt?: boolean; mcpConfig?: McpConfig; + subAgentMode?: SubAgentMode; } export function getTools(options?: GetToolsOptions): Tool[] { const userPrompt = options?.userPrompt !== false; // Default to true if not specified const mcpConfig = options?.mcpConfig || { servers: [], defaultResources: [] }; + const subAgentMode = options?.subAgentMode || 'async'; // Default to async mode // Force cast to Tool type to avoid TypeScript issues const tools: Tool[] = [ textEditorTool as unknown as Tool, - - //agentExecuteTool as unknown as Tool, - agentStartTool as unknown as Tool, - agentMessageTool as unknown as Tool, - listAgentsTool as unknown as Tool, - agentDoneTool as unknown as Tool, - fetchTool as unknown as Tool, - shellStartTool as unknown as Tool, shellMessageTool as unknown as Tool, listShellsTool as unknown as Tool, - sessionStartTool as unknown as Tool, sessionMessageTool as unknown as Tool, listSessionsTool as unknown as Tool, - waitTool as unknown as Tool, ]; + // Add agent tools based on the configured mode + if (subAgentMode === 'sync') { + // For sync mode, include only agentExecute and agentDone + tools.push(agentExecuteTool as unknown as Tool); + tools.push(agentDoneTool as unknown as Tool); + } else if (subAgentMode === 'async') { + // For async mode, include all async agent tools + tools.push(agentStartTool as unknown as Tool); + tools.push(agentMessageTool as unknown as Tool); + tools.push(listAgentsTool as unknown as Tool); + tools.push(agentDoneTool as unknown as Tool); + } + // For 'disabled' mode, no agent tools are added + // Only include user interaction tools if enabled if (userPrompt) { tools.push(userPromptTool as unknown as Tool); diff --git a/packages/cli/src/commands/$default.ts b/packages/cli/src/commands/$default.ts index 2ebc0ea..3c8080c 100644 --- a/packages/cli/src/commands/$default.ts +++ b/packages/cli/src/commands/$default.ts @@ -158,6 +158,7 @@ export async function executePrompt( const tools = getTools({ userPrompt: config.userPrompt, mcpConfig: config.mcp, + subAgentMode: config.subAgentMode, }); // Error handling diff --git a/packages/cli/src/commands/tools.ts b/packages/cli/src/commands/tools.ts index 5656a0e..5f94997 100644 --- a/packages/cli/src/commands/tools.ts +++ b/packages/cli/src/commands/tools.ts @@ -41,7 +41,7 @@ export const command: CommandModule = { describe: 'List all available tools and their capabilities', handler: () => { try { - const tools = getTools(); + const tools = getTools({ subAgentMode: 'async' }); console.log('Available Tools:\n'); diff --git a/packages/cli/src/options.ts b/packages/cli/src/options.ts index d2d2f08..f59b70f 100644 --- a/packages/cli/src/options.ts +++ b/packages/cli/src/options.ts @@ -17,6 +17,7 @@ export type SharedOptions = { readonly githubMode?: boolean; readonly upgradeCheck?: boolean; readonly ollamaBaseUrl?: string; + readonly subAgentMode?: 'disabled' | 'sync' | 'async'; }; export const sharedOptions = { @@ -100,4 +101,9 @@ export const sharedOptions = { type: 'string', description: 'Base URL for Ollama API (default: http://localhost:11434)', } as const, + subAgentMode: { + type: 'string', + description: 'Sub-agent workflow mode (disabled, sync, or async)', + choices: ['disabled', 'sync', 'async'], + } as const, }; diff --git a/packages/cli/src/settings/config.ts b/packages/cli/src/settings/config.ts index dcb0458..543e7c3 100644 --- a/packages/cli/src/settings/config.ts +++ b/packages/cli/src/settings/config.ts @@ -20,6 +20,7 @@ export type Config = { upgradeCheck: boolean; tokenUsage: boolean; interactive: boolean; + subAgentMode?: 'disabled' | 'sync' | 'async'; baseUrl?: string; @@ -77,6 +78,7 @@ const defaultConfig: Config = { upgradeCheck: true, tokenUsage: false, interactive: false, + subAgentMode: 'async', // MCP configuration mcp: { @@ -103,6 +105,7 @@ export const getConfigFromArgv = (argv: ArgumentsCamelCase) => { upgradeCheck: argv.upgradeCheck, tokenUsage: argv.tokenUsage, interactive: argv.interactive, + subAgentMode: argv.subAgentMode, }; }; diff --git a/packages/docs/docs/usage/configuration.md b/packages/docs/docs/usage/configuration.md index 47f4782..a420d1a 100644 --- a/packages/docs/docs/usage/configuration.md +++ b/packages/docs/docs/usage/configuration.md @@ -118,10 +118,11 @@ export default { ### Behavior Customization -| Option | Description | Possible Values | Default | -| -------------- | ------------------------------ | --------------- | ------- | -| `customPrompt` | Custom instructions for the AI | Any string | `""` | -| `githubMode` | Enable GitHub integration | `true`, `false` | `false` | +| Option | Description | Possible Values | Default | +| -------------- | ------------------------------ | ------------------------------- | -------- | +| `customPrompt` | Custom instructions for the AI | Any string | `""` | +| `githubMode` | Enable GitHub integration | `true`, `false` | `false` | +| `subAgentMode` | Sub-agent workflow mode | `'disabled'`, `'sync'`, `'async'` | `'async'` | Example: @@ -209,5 +210,8 @@ export default { profile: true, tokenUsage: true, tokenCache: true, + + // Sub-agent workflow mode + subAgentMode: 'async', // Options: 'disabled', 'sync', 'async' }; ``` diff --git a/packages/docs/docs/usage/sub-agent-modes.md b/packages/docs/docs/usage/sub-agent-modes.md new file mode 100644 index 0000000..0051d53 --- /dev/null +++ b/packages/docs/docs/usage/sub-agent-modes.md @@ -0,0 +1,119 @@ +--- +sidebar_position: 9 +--- + +# Sub-Agent Workflow Modes + +MyCoder supports different modes for working with sub-agents, giving you flexibility in how tasks are distributed and executed. You can configure the sub-agent workflow mode based on your specific needs and resource constraints. + +## Available Modes + +MyCoder supports three distinct sub-agent workflow modes: + +### 1. Disabled Mode + +In this mode, sub-agent functionality is completely disabled: + +- No sub-agent tools are available to the main agent +- All tasks must be handled by the main agent directly +- Useful for simpler tasks or when resource constraints are a concern +- Reduces memory usage and API costs for straightforward tasks + +### 2. Synchronous Mode ("sync") + +In synchronous mode, the parent agent waits for sub-agents to complete before continuing: + +- Uses the `agentExecute` tool for synchronous execution +- Parent agent waits for sub-agent completion before continuing its own workflow +- Useful for tasks that require sequential execution +- Simpler to reason about as there's no parallel execution +- Good for tasks where later steps depend on the results of earlier steps + +### 3. Asynchronous Mode ("async") - Default + +In asynchronous mode, sub-agents run in parallel with the parent agent: + +- Uses `agentStart`, `agentMessage`, and `listAgents` tools +- Sub-agents run in the background while the parent agent continues its work +- Parent agent can check status and provide guidance to sub-agents +- Useful for complex tasks that can benefit from parallelization +- More efficient for tasks that can be executed concurrently +- Allows the parent agent to coordinate multiple sub-agents + +## Configuration + +You can set the sub-agent workflow mode in your `mycoder.config.js` file: + +```javascript +// mycoder.config.js +export default { + // Sub-agent workflow mode: 'disabled', 'sync', or 'async' + subAgentMode: 'async', // Default value + + // Other configuration options... +}; +``` + +You can also specify the mode via the command line: + +```bash +mycoder --subAgentMode disabled "Implement a simple React component" +``` + +## Choosing the Right Mode + +Consider these factors when choosing a sub-agent workflow mode: + +- **Task Complexity**: For complex tasks that can be broken down into independent parts, async mode is often best. For simpler tasks, disabled mode may be sufficient. + +- **Resource Constraints**: Disabled mode uses fewer resources. Async mode can use more memory and API tokens but may complete complex tasks faster. + +- **Task Dependencies**: If later steps depend heavily on the results of earlier steps, sync mode ensures proper sequencing. + +- **Coordination Needs**: If you need to coordinate multiple parallel workflows, async mode gives you more control. + +## Example: Using Different Modes + +### Disabled Mode + +Best for simple, focused tasks: + +```javascript +// mycoder.config.js +export default { + subAgentMode: 'disabled', + // Other settings... +}; +``` + +### Synchronous Mode + +Good for sequential, dependent tasks: + +```javascript +// mycoder.config.js +export default { + subAgentMode: 'sync', + // Other settings... +}; +``` + +### Asynchronous Mode + +Ideal for complex projects with independent components: + +```javascript +// mycoder.config.js +export default { + subAgentMode: 'async', // This is the default + // Other settings... +}; +``` + +## How It Works Internally + +- In **disabled mode**, no agent tools are added to the available tools list. +- In **sync mode**, only the `agentExecute` and `agentDone` tools are available, ensuring synchronous execution. +- In **async mode**, the full suite of agent tools (`agentStart`, `agentMessage`, `listAgents`, and `agentDone`) is available, enabling parallel execution. + +This implementation allows MyCoder to adapt to different task requirements while maintaining a consistent interface for users. \ No newline at end of file From a2954556a0466ac51f38091929186f92ebfe797c Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 21 Mar 2025 21:39:17 -0400 Subject: [PATCH 2/2] chore: change default subAgentMode to 'disabled' and mark sync/async modes as experimental --- mycoder.config.js | 4 ++-- packages/agent/src/tools/getTools.ts | 2 +- packages/cli/src/commands/tools.ts | 2 +- packages/cli/src/settings/config.ts | 2 +- packages/docs/docs/usage/configuration.md | 14 +++++++------- packages/docs/docs/usage/sub-agent-modes.md | 16 ++++++++-------- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/mycoder.config.js b/mycoder.config.js index cbeff9e..65b5023 100644 --- a/mycoder.config.js +++ b/mycoder.config.js @@ -20,8 +20,8 @@ export default { // executablePath: null, // e.g., '/path/to/chrome' }, - // Sub-agent workflow mode: 'disabled', 'sync', or 'async' (default) - subAgentMode: 'async', + // Sub-agent workflow mode: 'disabled' (default), 'sync' (experimental), or 'async' (experimental) + subAgentMode: 'disabled', // Model settings //provider: 'anthropic', diff --git a/packages/agent/src/tools/getTools.ts b/packages/agent/src/tools/getTools.ts index 27c0755..c74194d 100644 --- a/packages/agent/src/tools/getTools.ts +++ b/packages/agent/src/tools/getTools.ts @@ -39,7 +39,7 @@ interface GetToolsOptions { export function getTools(options?: GetToolsOptions): Tool[] { const userPrompt = options?.userPrompt !== false; // Default to true if not specified const mcpConfig = options?.mcpConfig || { servers: [], defaultResources: [] }; - const subAgentMode = options?.subAgentMode || 'async'; // Default to async mode + const subAgentMode = options?.subAgentMode || 'disabled'; // Default to disabled mode // Force cast to Tool type to avoid TypeScript issues const tools: Tool[] = [ diff --git a/packages/cli/src/commands/tools.ts b/packages/cli/src/commands/tools.ts index 5f94997..1fececc 100644 --- a/packages/cli/src/commands/tools.ts +++ b/packages/cli/src/commands/tools.ts @@ -41,7 +41,7 @@ export const command: CommandModule = { describe: 'List all available tools and their capabilities', handler: () => { try { - const tools = getTools({ subAgentMode: 'async' }); + const tools = getTools({ subAgentMode: 'disabled' }); console.log('Available Tools:\n'); diff --git a/packages/cli/src/settings/config.ts b/packages/cli/src/settings/config.ts index 543e7c3..be68c54 100644 --- a/packages/cli/src/settings/config.ts +++ b/packages/cli/src/settings/config.ts @@ -78,7 +78,7 @@ const defaultConfig: Config = { upgradeCheck: true, tokenUsage: false, interactive: false, - subAgentMode: 'async', + subAgentMode: 'disabled', // MCP configuration mcp: { diff --git a/packages/docs/docs/usage/configuration.md b/packages/docs/docs/usage/configuration.md index a420d1a..4f2ce09 100644 --- a/packages/docs/docs/usage/configuration.md +++ b/packages/docs/docs/usage/configuration.md @@ -118,11 +118,11 @@ export default { ### Behavior Customization -| Option | Description | Possible Values | Default | -| -------------- | ------------------------------ | ------------------------------- | -------- | -| `customPrompt` | Custom instructions for the AI | Any string | `""` | -| `githubMode` | Enable GitHub integration | `true`, `false` | `false` | -| `subAgentMode` | Sub-agent workflow mode | `'disabled'`, `'sync'`, `'async'` | `'async'` | +| Option | Description | Possible Values | Default | +| -------------- | ------------------------------ | --------------------------------- | --------- | +| `customPrompt` | Custom instructions for the AI | Any string | `""` | +| `githubMode` | Enable GitHub integration | `true`, `false` | `false` | +| `subAgentMode` | Sub-agent workflow mode | `'disabled'`, `'sync'` (experimental), `'async'` (experimental) | `'disabled'` | Example: @@ -210,8 +210,8 @@ export default { profile: true, tokenUsage: true, tokenCache: true, - + // Sub-agent workflow mode - subAgentMode: 'async', // Options: 'disabled', 'sync', 'async' + subAgentMode: 'disabled', // Options: 'disabled', 'sync' (experimental), 'async' (experimental) }; ``` diff --git a/packages/docs/docs/usage/sub-agent-modes.md b/packages/docs/docs/usage/sub-agent-modes.md index 0051d53..52a8219 100644 --- a/packages/docs/docs/usage/sub-agent-modes.md +++ b/packages/docs/docs/usage/sub-agent-modes.md @@ -10,7 +10,7 @@ MyCoder supports different modes for working with sub-agents, giving you flexibi MyCoder supports three distinct sub-agent workflow modes: -### 1. Disabled Mode +### 1. Disabled Mode (Default) In this mode, sub-agent functionality is completely disabled: @@ -19,7 +19,7 @@ In this mode, sub-agent functionality is completely disabled: - Useful for simpler tasks or when resource constraints are a concern - Reduces memory usage and API costs for straightforward tasks -### 2. Synchronous Mode ("sync") +### 2. Synchronous Mode ("sync") - Experimental In synchronous mode, the parent agent waits for sub-agents to complete before continuing: @@ -29,7 +29,7 @@ In synchronous mode, the parent agent waits for sub-agents to complete before co - Simpler to reason about as there's no parallel execution - Good for tasks where later steps depend on the results of earlier steps -### 3. Asynchronous Mode ("async") - Default +### 3. Asynchronous Mode ("async") - Experimental In asynchronous mode, sub-agents run in parallel with the parent agent: @@ -47,9 +47,9 @@ You can set the sub-agent workflow mode in your `mycoder.config.js` file: ```javascript // mycoder.config.js export default { - // Sub-agent workflow mode: 'disabled', 'sync', or 'async' - subAgentMode: 'async', // Default value - + // Sub-agent workflow mode: 'disabled', 'sync' (experimental), or 'async' (experimental) + subAgentMode: 'disabled', // Default value + // Other configuration options... }; ``` @@ -105,7 +105,7 @@ Ideal for complex projects with independent components: ```javascript // mycoder.config.js export default { - subAgentMode: 'async', // This is the default + subAgentMode: 'async', // Experimental // Other settings... }; ``` @@ -116,4 +116,4 @@ export default { - In **sync mode**, only the `agentExecute` and `agentDone` tools are available, ensuring synchronous execution. - In **async mode**, the full suite of agent tools (`agentStart`, `agentMessage`, `listAgents`, and `agentDone`) is available, enabling parallel execution. -This implementation allows MyCoder to adapt to different task requirements while maintaining a consistent interface for users. \ No newline at end of file +This implementation allows MyCoder to adapt to different task requirements while maintaining a consistent interface for users.