1import type { ProviderOptionDescriptor, RuntimeMode } from "@t3tools/contracts";
2
3/**
4 * Desktop-oriented effort keywords that don't belong in the phone picker.
5 * Prompt-injected values (ultrathink and friends) are filtered from the
6 * descriptor metadata; ultracode is a real option but a workflow trigger, not
7 * a reasoning level. A value set elsewhere still displays, it just isn't
8 * offered.
9 */
10const HIDDEN_EFFORT_OPTION_IDS: ReadonlySet<string> = new Set(["ultracode"]);
11
12export const RUNTIME_MODE_CHOICES: ReadonlyArray<{
13 readonly mode: RuntimeMode;
14 readonly label: string;
15 readonly description: string;
16}> = [
17 {
18 mode: "approval-required",
19 label: "Supervised",
20 description: "Ask before commands and file changes.",
21 },
22 {
23 mode: "auto-accept-edits",
24 label: "Auto-accept edits",
25 description: "Auto-approve edits, ask before other actions.",
26 },
27 {
28 mode: "auto",
29 label: "Auto",
30 description: "Supported providers approve routine actions; others still ask.",
31 },
32 {
33 mode: "full-access",
34 label: "Full access",
35 description: "Allow commands and edits without prompts.",
36 },
37];
38
39export function runtimeModeChoicesForSupportedModes(
40 supportedRuntimeModes: ReadonlyArray<RuntimeMode> | undefined,
41) {
42 return supportedRuntimeModes && supportedRuntimeModes.length > 0
43 ? RUNTIME_MODE_CHOICES.filter((choice) => supportedRuntimeModes.includes(choice.mode))
44 : RUNTIME_MODE_CHOICES;
45}
46
47export function compatibleRuntimeModeForChoices(
48 runtimeMode: RuntimeMode,
49 choices: ReadonlyArray<{ readonly mode: RuntimeMode }>,
50): RuntimeMode {
51 return choices.some((choice) => choice.mode === runtimeMode)
52 ? runtimeMode
53 : (choices[0]?.mode ?? runtimeMode);
54}
55
56export function selectableChoices(
57 descriptor: Extract<ProviderOptionDescriptor, { type: "select" }>,
58) {
59 const injected = new Set(descriptor.promptInjectedValues ?? []);
60 return descriptor.options.filter(
61 (option) => !injected.has(option.id) && !HIDDEN_EFFORT_OPTION_IDS.has(option.id),
62 );
63}