revise_workplan
Updates existing GitHub workplans by fetching the current version and applying AI-driven revisions based on your instructions, then automatically updating the issue with the improved plan.
Instructions
Updates an existing workplan based on revision instructions.
This tool will:
Fetch the existing workplan from the specified GitHub issue
Launch a background AI process to revise the workplan based on your instructions
Update the issue with the revised workplan once complete
The AI will use the same codebase analysis mode and model as the original workplan.
Returns the issue URL and number immediately.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| issue_number | Yes | ||
| revision_instructions | Yes | ||
| codebase_reasoning | No | full | |
| debug | No | ||
| disable_search_grounding | No |
Implementation Reference
- yellhorn_mcp/server.py:415-427 (registration)Registration of the 'revise_workplan' tool using @mcp.tool decorator.@mcp.tool( name="revise_workplan", description="""Updates an existing workplan based on revision instructions. This tool will: 1. Fetch the existing workplan from the specified GitHub issue 2. Launch a background AI process to revise the workplan based on your instructions 3. Update the issue with the revised workplan once complete The AI will use the same codebase analysis mode and model as the original workplan. Returns the issue URL and number immediately.""", )
- yellhorn_mcp/server.py:428-541 (handler)Main handler function for the revise_workplan tool. Fetches original workplan, adds status comment, launches background process_revision_async task, and returns issue info immediately.async def revise_workplan( ctx: Context, issue_number: str, revision_instructions: str, codebase_reasoning: str = "full", debug: bool = False, disable_search_grounding: bool = False, ) -> str: """Revises an existing workplan based on revision instructions. Args: ctx: Server context. issue_number: The GitHub issue number containing the workplan to revise. revision_instructions: Instructions describing how to revise the workplan. codebase_reasoning: Reasoning mode for codebase analysis (same options as create_workplan). debug: If True, adds a comment to the issue with the full prompt used for generation. disable_search_grounding: If True, disables Google Search Grounding for this request. Returns: JSON string containing the issue URL and number. Raises: YellhornMCPError: If revision fails. """ try: repo_path: Path = ctx.request_context.lifespan_context["repo_path"] # Fetch original workplan original_workplan = await get_issue_body(repo_path, issue_number) if not original_workplan: raise YellhornMCPError(f"Could not retrieve workplan for issue #{issue_number}") # Handle search grounding override if specified original_search_grounding = ctx.request_context.lifespan_context.get( "use_search_grounding", True ) if disable_search_grounding: ctx.request_context.lifespan_context["use_search_grounding"] = False await ctx.log( level="info", message="Search grounding temporarily disabled for this request", ) # Extract URLs from the revision instructions submitted_urls = extract_urls(revision_instructions) # Add submission comment submission_metadata = SubmissionMetadata( status="Revising workplan...", model_name=ctx.request_context.lifespan_context["model"], search_grounding_enabled=ctx.request_context.lifespan_context.get( "use_search_grounding", False ), yellhorn_version=__version__, submitted_urls=submitted_urls if submitted_urls else None, codebase_reasoning_mode=codebase_reasoning, timestamp=datetime.now(timezone.utc), ) submission_comment = format_submission_comment(submission_metadata) await add_issue_comment(repo_path, issue_number, submission_comment) llm_manager = ctx.request_context.lifespan_context.get("llm_manager") model = ctx.request_context.lifespan_context["model"] reasoning_effort = ctx.request_context.lifespan_context.get("reasoning_effort") # Launch background task to process the revision await ctx.log( level="info", message=f"Launching background task to revise workplan with AI model {model}", ) start_time = datetime.now(timezone.utc) asyncio.create_task( process_revision_async( repo_path, llm_manager, model, issue_number, original_workplan, revision_instructions, codebase_reasoning, debug=debug, disable_search_grounding=disable_search_grounding, reasoning_effort=reasoning_effort, _meta={ "original_search_grounding": original_search_grounding, "start_time": start_time, "submitted_urls": submitted_urls, }, ctx=ctx, github_command_func=ctx.request_context.lifespan_context.get("github_command_func"), git_command_func=ctx.request_context.lifespan_context.get("git_command_func"), ) ) # Restore original search grounding setting if modified if disable_search_grounding: ctx.request_context.lifespan_context["use_search_grounding"] = original_search_grounding # Get issue URL get_issue_url_cmd = await run_github_command( repo_path, ["issue", "view", issue_number, "--json", "url"], github_command_func=ctx.request_context.lifespan_context.get("github_command_func"), ) issue_data = json.loads(get_issue_url_cmd) issue_url = issue_data["url"] # Return the issue URL and number as JSON return json.dumps({"issue_url": issue_url, "issue_number": issue_number}) except Exception as e: raise YellhornMCPError(f"Failed to revise workplan: {str(e)}")
- Core helper function that performs the actual revision: gathers codebase context, builds specialized LLM prompt including original workplan and instructions, calls LLM via llm_manager, and updates GitHub issue.async def process_revision_async( repo_path: Path, llm_manager: LLMManager, model: str, issue_number: str, original_workplan: str, revision_instructions: str, codebase_reasoning: str, debug: bool = False, disable_search_grounding: bool = False, _meta: dict[str, object] | None = None, ctx: Context | None = None, github_command_func: Callable | None = None, git_command_func: Callable | None = None, reasoning_effort: ReasoningEffort | None = None, ) -> None: """Revise an existing workplan asynchronously and update the GitHub issue. Args: repo_path: Path to the repository. llm_manager: LLM Manager instance. model: Model name to use. issue_number: GitHub issue number to update. original_workplan: The current workplan content. revision_instructions: Instructions for how to revise the workplan. codebase_reasoning: Reasoning mode to use for codebase analysis. debug: If True, add a comment with the full prompt used for generation. disable_search_grounding: If True, disables search grounding for this request. _meta: Optional metadata from the caller. ctx: Optional context for logging. github_command_func: Optional GitHub command function (for mocking). git_command_func: Optional Git command function (for mocking). reasoning_effort: Optional reasoning effort to apply for supported models. """ try: # Create a simple logging function that uses ctx if available def context_log(msg: str): if ctx: asyncio.create_task(ctx.log(level="info", message=msg)) # Get codebase info based on reasoning mode # Calculate token limit for codebase context (70% of model's context window) token_counter = TokenCounter() model_limit = token_counter.get_model_limit(model) # Reserve tokens for prompt template, task details, and response # Estimate: prompt template ~1000, task details ~500, safety margin for response ~4000 codebase_token_limit = int((model_limit - 5500) * 0.7) codebase_info, _ = await get_codebase_context( repo_path, codebase_reasoning, context_log, token_limit=codebase_token_limit, model=model, git_command_func=git_command_func, ) # Extract title from original workplan (assumes first line is # Title) title_line = original_workplan.split("\n")[0] if original_workplan else "" title = ( title_line.replace("# ", "").strip() if title_line.startswith("# ") else "Workplan Revision" ) # Construct revision prompt prompt = f"""You are an expert software developer tasked with revising an existing workplan based on revision instructions. # Original Workplan {original_workplan} # Revision Instructions {revision_instructions} # Codebase Context {codebase_info} # Instructions Revise the "Original Workplan" based on the "Revision Instructions" and the provided "Codebase Context". Your output should be the complete, revised workplan in the same format as the original. The revised workplan should: 1. Incorporate all changes requested in the revision instructions 2. Maintain the same overall structure and formatting as the original 3. Update any implementation details that are affected by the changes 4. Ensure all sections remain comprehensive and implementable Respond directly with the complete revised workplan in Markdown format. IMPORTANT: Respond *only* with the Markdown content for the GitHub issue body. Do *not* wrap your entire response in a single Markdown code block (```). Start directly with the '## Summary' heading. """ # llm_manager is now passed as a parameter # Generate and update issue using the helper await _generate_and_update_issue( repo_path, llm_manager, model, prompt, issue_number, title, "", disable_search_grounding, debug, codebase_reasoning, _meta, ctx, github_command_func=github_command_func, git_command_func=git_command_func, reasoning_effort=reasoning_effort, ) except Exception as e: error_msg = f"Error processing revision: {str(e)}" if ctx: await ctx.log(level="error", message=error_msg) # Try to add error comment to issue try: error_comment = f"❌ **Error revising workplan**\n\n{str(e)}" await add_issue_comment( repo_path, issue_number, error_comment, github_command_func=github_command_func ) except Exception: # If we can't even add a comment, just log if ctx: await ctx.log( level="error", message=f"Failed to add error comment to issue: {str(e)}" )