Spaces:
Running
Running
| import type { | |
| ChatProvider, | |
| ParsedCommand, | |
| ResolvedChatContext, | |
| WorkPackage, | |
| } from "./work-package-types"; | |
| const SLASH_COMMAND = /^\/(ask|plan|change|execute)\b\s*/i; | |
| export function resolveChatRequestContext(args: { | |
| parsed: ParsedCommand; | |
| detailOpen: boolean; | |
| selectedWorkPackage?: Pick<WorkPackage, "id" | "title" | "shortName">; | |
| }) { | |
| const { parsed, detailOpen, selectedWorkPackage } = args; | |
| const hasExplicitCommand = | |
| Boolean(parsed.mode) || Boolean(parsed.referencedPackageName); | |
| if (hasExplicitCommand) { | |
| return { | |
| parsedCommand: parsed, | |
| shouldAutomateBoard: false, | |
| source: "explicit-command" as const, | |
| }; | |
| } | |
| const slashMatch = parsed.instruction.match(SLASH_COMMAND); | |
| if (slashMatch && selectedWorkPackage) { | |
| return { | |
| parsedCommand: { | |
| referencedPackageName: selectedWorkPackage.title, | |
| mode: slashMatch[1].toLowerCase() as "ask" | "plan" | "change" | "execute", | |
| instruction: parsed.instruction.replace(SLASH_COMMAND, "").trim(), | |
| }, | |
| shouldAutomateBoard: false, | |
| source: "slash-command" as const, | |
| }; | |
| } | |
| if (detailOpen && selectedWorkPackage && parsed.instruction.trim()) { | |
| return { | |
| parsedCommand: { | |
| referencedPackageName: selectedWorkPackage.title, | |
| mode: "ask" as const, | |
| instruction: parsed.instruction, | |
| }, | |
| shouldAutomateBoard: false, | |
| source: "selected-package-context" as const, | |
| }; | |
| } | |
| return { | |
| parsedCommand: parsed, | |
| shouldAutomateBoard: true, | |
| source: "board-automation" as const, | |
| }; | |
| } | |
| export function buildResolvedContext(args: { | |
| parsedCommand?: ParsedCommand; | |
| shouldAutomateBoard?: boolean; | |
| selectedWorkPackage?: Pick<WorkPackage, "id" | "title" | "shortName"> | null; | |
| provider: ChatProvider; | |
| }): ResolvedChatContext { | |
| const { parsedCommand, shouldAutomateBoard, selectedWorkPackage, provider } = args; | |
| if (shouldAutomateBoard || !parsedCommand?.mode) { | |
| return { | |
| scope: "global", | |
| workPackageId: null, | |
| workPackageTitle: null, | |
| mode: "board_automation", | |
| provider, | |
| boardMutationPolicy: "replace_all", | |
| }; | |
| } | |
| return { | |
| scope: "package", | |
| workPackageId: selectedWorkPackage?.id ?? null, | |
| workPackageTitle: | |
| selectedWorkPackage?.title ?? parsedCommand.referencedPackageName ?? null, | |
| mode: parsedCommand.mode, | |
| provider, | |
| boardMutationPolicy: | |
| parsedCommand.mode === "ask" ? "none" : "selected_package_only", | |
| }; | |
| } | |
| export function buildThinkingSummary(args: { | |
| context: ResolvedChatContext; | |
| model?: string; | |
| note?: string; | |
| }) { | |
| const { context, model, note } = args; | |
| const lines: string[] = []; | |
| if (context.scope === "package" && context.workPackageTitle) { | |
| lines.push(`Resolved scope to ${context.workPackageTitle}.`); | |
| } else { | |
| lines.push("Resolved scope to board-wide planning."); | |
| } | |
| if (context.mode === "board_automation") { | |
| lines.push("Mode: board_automation. Board hydration is allowed."); | |
| } else if (context.boardMutationPolicy === "none") { | |
| lines.push(`Mode: ${context.mode}. Board changes are disabled for this request.`); | |
| } else { | |
| lines.push( | |
| `Mode: ${context.mode}. Board changes are limited to the selected work package.`, | |
| ); | |
| } | |
| lines.push( | |
| context.provider === "live" | |
| ? `Using live model ${model ?? "configured model"}.` | |
| : "Using mock mode.", | |
| ); | |
| if (note) { | |
| lines.push(note); | |
| } | |
| return lines; | |
| } | |