import { type } from "arktype"; import { formatMcpToolRef } from "../external.ts"; import type { Mode } from "../modes.ts"; import type { ToolContext } from "./server.ts"; import { execute, tool } from "./shared.ts"; export const SelectModeParams = type({ mode: type.string.describe( "the name of the mode to select (e.g., 'Build', 'Plan', 'Review', 'IncrementalReview', 'Fix', 'AddressReviews', 'Task', 'ResolveConflicts')" ), "issue_number?": type("number").describe( "optional issue number; when provided with Plan mode, used to look up an existing plan comment" ), }); function resolveMode(modes: Mode[], modeName: string): Mode | null { return modes.find((m) => m.name.toLowerCase() === modeName.toLowerCase()) ?? null; } function buildModeOverrides(t: (name: string) => string): Record { return { PlanEdit: `### Checklist (editing existing plan) An existing plan comment was found for this issue. Update that comment with the revised plan — do not create a new plan comment. 1. **task list**: create your task list for this run as your first action. 2. Use \`previousPlanBody\` from this response as the plan to revise; do not call \`get_issue\` or \`get_issue_comments\`. 3. Revise the plan based on the user's request. 4. Call \`${t("report_progress")}\` with the full revised plan text and \`{ target_plan_comment: true }\` so it updates the existing plan comment. 5. Then post a short note to the progress comment via \`${t("report_progress")}\` so it is not left as "Leaping...".`, }; } export function SelectModeTool(ctx: ToolContext) { return tool({ name: "select_mode", description: "Select the operating mode for this run. Call this first to get the workflow for your task. " + "Example: `select_mode({ mode: 'Review' })`.", parameters: SelectModeParams, execute: execute(async ({ mode, issue_number }) => { const t = (toolName: string) => formatMcpToolRef(ctx.agentId, toolName); const overrides = buildModeOverrides(t); // find mode in available list const foundMode = resolveMode(ctx.modes, mode); if (!foundMode) { const available = ctx.modes.map((m) => m.name).join(", "); throw new Error( `Unknown mode "${mode}". Available modes: ${available}` ); } ctx.toolState.selectedMode = foundMode.name; const overrideGuidance = overrides[foundMode.name]; const hardcoded = overrideGuidance ?? foundMode.prompt ?? ""; const userInstructions = ctx.modeInstructions[foundMode.name] ?? ""; const guidance = [hardcoded, userInstructions].filter(Boolean).join("\n\n"); const response: Record = { modeName: foundMode.name, description: foundMode.description, orchestratorGuidance: guidance, }; // For Plan mode with issue_number, look up existing plan comment if (foundMode.name === "Plan" && issue_number !== undefined) { try { const commentsR = await ctx.gitea.request( "GET /repos/{owner}/{repo}/issues/{index}/comments", { owner: ctx.repo.owner, repo: ctx.repo.name, index: issue_number, limit: 50 } ); const comments = commentsR.data as Array<{ id?: number; body?: string | null }>; // Look for a plan comment (one with our footer) const planComment = comments.find((c) => c.body?.includes("")); if (planComment) { if (planComment.id !== undefined) ctx.toolState.existingPlanCommentId = planComment.id; ctx.toolState.previousPlanBody = planComment.body ?? ""; response.existingPlanCommentFound = true; response.previousPlanBody = ctx.toolState.previousPlanBody; response.orchestratorGuidance = (overrides["PlanEdit"] ?? guidance) + "\n\n" + (userInstructions ? `\n\n${userInstructions}` : ""); } } catch { // Best-effort — if we can't find the plan comment, proceed normally } } return response; }), }); }