Spaces:
Running
Running
File size: 3,475 Bytes
837e3ac | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 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;
}
|