pi-windsurf-beta 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/auth.ts +139 -0
- package/catalog.ts +139 -0
- package/chat.ts +501 -0
- package/index.ts +155 -0
- package/metadata.ts +47 -0
- package/models.ts +353 -0
- package/oauth.ts +290 -0
- package/package.json +40 -0
- package/proxy.ts +350 -0
- package/wire.ts +132 -0
package/metadata.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `exa.codeium_common_pb.Metadata` proto builder.
|
|
3
|
+
*/
|
|
4
|
+
import { encodeMessage, encodeString, encodeTimestampBody, encodeVarintField } from "./wire";
|
|
5
|
+
|
|
6
|
+
const WINDSURF_VERSION_STRING = "2.0.0";
|
|
7
|
+
|
|
8
|
+
export interface MetadataInput {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
userJwt?: string;
|
|
11
|
+
sessionId: string;
|
|
12
|
+
requestId: bigint;
|
|
13
|
+
triggerId: string;
|
|
14
|
+
windsurfVersion?: string;
|
|
15
|
+
osName?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function osString(): string {
|
|
19
|
+
switch (process.platform) {
|
|
20
|
+
case "darwin": return "darwin";
|
|
21
|
+
case "linux": return "linux";
|
|
22
|
+
case "win32": return "windows";
|
|
23
|
+
default: return String(process.platform);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function buildMetadata(input: MetadataInput): Buffer {
|
|
28
|
+
const version = input.windsurfVersion ?? WINDSURF_VERSION_STRING;
|
|
29
|
+
const os = input.osName ?? osString();
|
|
30
|
+
const parts: Buffer[] = [
|
|
31
|
+
encodeString(1, "windsurf"),
|
|
32
|
+
encodeString(2, version),
|
|
33
|
+
encodeString(3, input.apiKey),
|
|
34
|
+
encodeString(4, "en"),
|
|
35
|
+
encodeString(5, os),
|
|
36
|
+
encodeString(7, version),
|
|
37
|
+
encodeVarintField(9, input.requestId),
|
|
38
|
+
encodeString(10, input.sessionId),
|
|
39
|
+
encodeString(12, "windsurf"),
|
|
40
|
+
encodeMessage(16, encodeTimestampBody()),
|
|
41
|
+
encodeString(25, input.triggerId),
|
|
42
|
+
encodeString(26, "Unset"),
|
|
43
|
+
encodeString(28, "windsurf"),
|
|
44
|
+
];
|
|
45
|
+
if (input.userJwt) parts.push(encodeString(21, input.userJwt));
|
|
46
|
+
return Buffer.concat(parts);
|
|
47
|
+
}
|
package/models.ts
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windsurf model catalog — variant resolution + model_uid mapping.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const ModelEnum = {
|
|
6
|
+
MODEL_UNSPECIFIED: 0,
|
|
7
|
+
CLAUDE_3_OPUS_20240229: 63,
|
|
8
|
+
CLAUDE_3_SONNET_20240229: 64,
|
|
9
|
+
CLAUDE_3_HAIKU_20240307: 172,
|
|
10
|
+
CLAUDE_3_5_SONNET_20241022: 166,
|
|
11
|
+
CLAUDE_3_5_HAIKU_20241022: 171,
|
|
12
|
+
CLAUDE_3_7_SONNET_20250219: 226,
|
|
13
|
+
CLAUDE_3_7_SONNET_20250219_THINKING: 227,
|
|
14
|
+
CLAUDE_4_OPUS: 290,
|
|
15
|
+
CLAUDE_4_OPUS_THINKING: 291,
|
|
16
|
+
CLAUDE_4_SONNET: 281,
|
|
17
|
+
CLAUDE_4_SONNET_THINKING: 282,
|
|
18
|
+
CLAUDE_4_1_OPUS: 328,
|
|
19
|
+
CLAUDE_4_1_OPUS_THINKING: 329,
|
|
20
|
+
CLAUDE_4_5_SONNET: 353,
|
|
21
|
+
CLAUDE_4_5_SONNET_THINKING: 354,
|
|
22
|
+
CLAUDE_4_5_OPUS: 391,
|
|
23
|
+
CLAUDE_4_5_OPUS_THINKING: 392,
|
|
24
|
+
CLAUDE_CODE: 344,
|
|
25
|
+
GPT_4: 30,
|
|
26
|
+
GPT_4O_2024_08_06: 109,
|
|
27
|
+
GPT_4O_MINI_2024_07_18: 113,
|
|
28
|
+
GPT_4_1_2025_04_14: 259,
|
|
29
|
+
GPT_4_1_MINI_2025_04_14: 260,
|
|
30
|
+
GPT_4_1_NANO_2025_04_14: 261,
|
|
31
|
+
GPT_5: 340,
|
|
32
|
+
GPT_5_NANO: 337,
|
|
33
|
+
GPT_5_LOW: 339,
|
|
34
|
+
GPT_5_HIGH: 341,
|
|
35
|
+
GPT_5_CODEX: 346,
|
|
36
|
+
GPT_5_1_CODEX_MINI_LOW: 385,
|
|
37
|
+
GPT_5_1_CODEX_MINI_MEDIUM: 386,
|
|
38
|
+
GPT_5_1_CODEX_MINI_HIGH: 387,
|
|
39
|
+
GPT_5_1_CODEX_LOW: 388,
|
|
40
|
+
GPT_5_1_CODEX_MEDIUM: 389,
|
|
41
|
+
GPT_5_1_CODEX_HIGH: 390,
|
|
42
|
+
GPT_5_1_CODEX_MAX_LOW: 395,
|
|
43
|
+
GPT_5_1_CODEX_MAX_MEDIUM: 396,
|
|
44
|
+
GPT_5_1_CODEX_MAX_HIGH: 397,
|
|
45
|
+
GPT_5_2_NONE: 399, GPT_5_2_LOW: 400, GPT_5_2_MEDIUM: 401, GPT_5_2_HIGH: 402, GPT_5_2_XHIGH: 403,
|
|
46
|
+
GPT_5_2_NONE_PRIORITY: 404, GPT_5_2_LOW_PRIORITY: 405, GPT_5_2_MEDIUM_PRIORITY: 406, GPT_5_2_HIGH_PRIORITY: 407, GPT_5_2_XHIGH_PRIORITY: 408,
|
|
47
|
+
O3: 218, O3_MINI: 207, O3_LOW: 262, O3_HIGH: 263, O3_PRO: 294, O3_PRO_LOW: 295, O3_PRO_HIGH: 296,
|
|
48
|
+
O4_MINI: 264, O4_MINI_LOW: 265, O4_MINI_HIGH: 266,
|
|
49
|
+
GEMINI_2_0_FLASH: 184, GEMINI_2_5_PRO: 246, GEMINI_2_5_FLASH: 312,
|
|
50
|
+
GEMINI_2_5_FLASH_THINKING: 313, GEMINI_2_5_FLASH_LITE: 343,
|
|
51
|
+
GEMINI_3_0_PRO_MINIMAL: 411, GEMINI_3_0_PRO_LOW: 378, GEMINI_3_0_PRO_MEDIUM: 412, GEMINI_3_0_PRO_HIGH: 379,
|
|
52
|
+
GEMINI_3_0_FLASH_MINIMAL: 413, GEMINI_3_0_FLASH_LOW: 414, GEMINI_3_0_FLASH_MEDIUM: 415, GEMINI_3_0_FLASH_HIGH: 416,
|
|
53
|
+
DEEPSEEK_V3: 205, DEEPSEEK_V3_2: 409, DEEPSEEK_R1: 206, DEEPSEEK_R1_FAST: 216, DEEPSEEK_R1_SLOW: 215,
|
|
54
|
+
LLAMA_3_1_8B_INSTRUCT: 106, LLAMA_3_1_70B_INSTRUCT: 107, LLAMA_3_1_405B_INSTRUCT: 105,
|
|
55
|
+
LLAMA_3_3_70B_INSTRUCT: 208, LLAMA_3_3_70B_INSTRUCT_R1: 209,
|
|
56
|
+
QWEN_2_5_7B_INSTRUCT: 178, QWEN_2_5_32B_INSTRUCT: 179, QWEN_2_5_72B_INSTRUCT: 180,
|
|
57
|
+
QWEN_2_5_32B_INSTRUCT_R1: 224, QWEN_3_235B_INSTRUCT: 324,
|
|
58
|
+
QWEN_3_CODER_480B_INSTRUCT: 325, QWEN_3_CODER_480B_INSTRUCT_FAST: 327,
|
|
59
|
+
GROK_2: 212, GROK_3: 217, GROK_3_MINI_REASONING: 234, GROK_CODE_FAST: 345,
|
|
60
|
+
MISTRAL_7B: 77, KIMI_K2: 323, KIMI_K2_THINKING: 394,
|
|
61
|
+
GLM_4_5: 342, GLM_4_5_FAST: 352, GLM_4_6: 356, GLM_4_6_FAST: 357, GLM_4_7: 417, GLM_4_7_FAST: 418,
|
|
62
|
+
MINIMAX_M2: 368, MINIMAX_M2_1: 419,
|
|
63
|
+
SWE_1_5: 359, SWE_1_5_THINKING: 369, SWE_1_5_SLOW: 377,
|
|
64
|
+
SWE_1_6: 420, SWE_1_6_FAST: 421,
|
|
65
|
+
GPT_OSS_120B: 326,
|
|
66
|
+
GPT_5_2_CODEX_LOW: 422, GPT_5_2_CODEX_MEDIUM: 423, GPT_5_2_CODEX_HIGH: 424, GPT_5_2_CODEX_XHIGH: 425,
|
|
67
|
+
GPT_5_2_CODEX_LOW_PRIORITY: 426, GPT_5_2_CODEX_MEDIUM_PRIORITY: 427, GPT_5_2_CODEX_HIGH_PRIORITY: 428, GPT_5_2_CODEX_XHIGH_PRIORITY: 429,
|
|
68
|
+
PRIVATE_1: 219, PRIVATE_2: 220, PRIVATE_3: 221, PRIVATE_4: 222, PRIVATE_5: 223,
|
|
69
|
+
PRIVATE_6: 314, PRIVATE_7: 315, PRIVATE_8: 316, PRIVATE_9: 317, PRIVATE_10: 318,
|
|
70
|
+
PRIVATE_11: 347, PRIVATE_12: 348, PRIVATE_13: 349, PRIVATE_14: 350, PRIVATE_15: 351,
|
|
71
|
+
PRIVATE_16: 363, PRIVATE_17: 364, PRIVATE_18: 365, PRIVATE_19: 366, PRIVATE_20: 367,
|
|
72
|
+
PRIVATE_21: 372, PRIVATE_22: 373, PRIVATE_23: 374, PRIVATE_24: 375, PRIVATE_25: 376,
|
|
73
|
+
PRIVATE_26: 380, PRIVATE_27: 381, PRIVATE_28: 382, PRIVATE_29: 383, PRIVATE_30: 384,
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
export type ModelEnumValue = (typeof ModelEnum)[keyof typeof ModelEnum];
|
|
77
|
+
|
|
78
|
+
// ----------------------------------------------------------------------------
|
|
79
|
+
// Enum → cloud uid mapping
|
|
80
|
+
// ----------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
const ENUM_PREFIX_OVERRIDES: Array<{ enumPrefix: string; uidPrefix: string }> = [
|
|
83
|
+
{ enumPrefix: "GPT_4_1_2025_04_14", uidPrefix: "MODEL_CHAT_GPT_4_1_2025_04_14" },
|
|
84
|
+
{ enumPrefix: "GPT_4O_2024_08_06", uidPrefix: "MODEL_CHAT_GPT_4O_2024_08_06" },
|
|
85
|
+
{ enumPrefix: "GPT_5_CODEX", uidPrefix: "MODEL_CHAT_GPT_5_CODEX" },
|
|
86
|
+
{ enumPrefix: "O3_HIGH", uidPrefix: "MODEL_CHAT_O3_HIGH" },
|
|
87
|
+
{ enumPrefix: "O3", uidPrefix: "MODEL_CHAT_O3" },
|
|
88
|
+
{ enumPrefix: "GEMINI_3_0_FLASH", uidPrefix: "MODEL_GOOGLE_GEMINI_3_0_FLASH" },
|
|
89
|
+
{ enumPrefix: "GEMINI_2_5_PRO", uidPrefix: "MODEL_GOOGLE_GEMINI_2_5_PRO" },
|
|
90
|
+
{ enumPrefix: "GROK_3_MINI_REASONING", uidPrefix: "MODEL_XAI_GROK_3_MINI_REASONING" },
|
|
91
|
+
{ enumPrefix: "GROK_3", uidPrefix: "MODEL_XAI_GROK_3" },
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
function enumKeyToCloudUid(key: string): string {
|
|
95
|
+
const sorted = [...ENUM_PREFIX_OVERRIDES].sort((a, b) => b.enumPrefix.length - a.enumPrefix.length);
|
|
96
|
+
for (const { enumPrefix, uidPrefix } of sorted) {
|
|
97
|
+
if (key === enumPrefix) return uidPrefix;
|
|
98
|
+
if (key.startsWith(enumPrefix + "_")) return uidPrefix + key.slice(enumPrefix.length);
|
|
99
|
+
}
|
|
100
|
+
return `MODEL_${key}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const ENUM_VALUE_TO_NAME: Map<number, string> = (() => {
|
|
104
|
+
const map = new Map<number, string>();
|
|
105
|
+
for (const [key, value] of Object.entries(ModelEnum)) {
|
|
106
|
+
if (typeof value === "number") map.set(value, enumKeyToCloudUid(key));
|
|
107
|
+
}
|
|
108
|
+
return map;
|
|
109
|
+
})();
|
|
110
|
+
|
|
111
|
+
// ----------------------------------------------------------------------------
|
|
112
|
+
// Variant catalog
|
|
113
|
+
// ----------------------------------------------------------------------------
|
|
114
|
+
|
|
115
|
+
type VariantMeta = { description?: string; modelUid?: string; enumValue?: ModelEnumValue; };
|
|
116
|
+
type VariantName = string;
|
|
117
|
+
|
|
118
|
+
interface ModelCatalogEntry {
|
|
119
|
+
id: string;
|
|
120
|
+
defaultEnum?: ModelEnumValue;
|
|
121
|
+
defaultUid?: string;
|
|
122
|
+
variants?: Record<VariantName, VariantMeta>;
|
|
123
|
+
aliases?: string[];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const VARIANT_CATALOG: Record<string, ModelCatalogEntry> = {
|
|
127
|
+
"claude-opus-4.8": { id: "claude-opus-4.8", defaultUid: "claude-opus-4-8-medium",
|
|
128
|
+
variants: {
|
|
129
|
+
"low": { modelUid: "claude-opus-4-8-low" }, "medium": { modelUid: "claude-opus-4-8-medium" },
|
|
130
|
+
"high": { modelUid: "claude-opus-4-8-high" }, "xhigh": { modelUid: "claude-opus-4-8-xhigh" },
|
|
131
|
+
"max": { modelUid: "claude-opus-4-8-max" },
|
|
132
|
+
"low-fast": { modelUid: "claude-opus-4-8-low-fast" }, "medium-fast": { modelUid: "claude-opus-4-8-medium-fast" },
|
|
133
|
+
"high-fast": { modelUid: "claude-opus-4-8-high-fast" }, "xhigh-fast": { modelUid: "claude-opus-4-8-xhigh-fast" },
|
|
134
|
+
"max-fast": { modelUid: "claude-opus-4-8-max-fast" },
|
|
135
|
+
}, aliases: ["claude-opus-4-8"],
|
|
136
|
+
},
|
|
137
|
+
"claude-opus-4.7": { id: "claude-opus-4.7", defaultUid: "claude-opus-4-7-medium",
|
|
138
|
+
variants: {
|
|
139
|
+
"low": { modelUid: "claude-opus-4-7-low" }, "medium": { modelUid: "claude-opus-4-7-medium" },
|
|
140
|
+
"high": { modelUid: "claude-opus-4-7-high" }, "xhigh": { modelUid: "claude-opus-4-7-xhigh" },
|
|
141
|
+
"max": { modelUid: "claude-opus-4-7-max" },
|
|
142
|
+
"low-fast": { modelUid: "claude-opus-4-7-low-fast" }, "medium-fast": { modelUid: "claude-opus-4-7-medium-fast" },
|
|
143
|
+
"high-fast": { modelUid: "claude-opus-4-7-high-fast" }, "xhigh-fast": { modelUid: "claude-opus-4-7-xhigh-fast" },
|
|
144
|
+
"max-fast": { modelUid: "claude-opus-4-7-max-fast" },
|
|
145
|
+
}, aliases: ["claude-opus-4-7"],
|
|
146
|
+
},
|
|
147
|
+
"claude-opus-4.6": { id: "claude-opus-4.6", defaultUid: "claude-opus-4-6-thinking",
|
|
148
|
+
variants: {
|
|
149
|
+
"thinking": { modelUid: "claude-opus-4-6-thinking" }, "base": { modelUid: "claude-opus-4-6" },
|
|
150
|
+
"1m": { modelUid: "claude-opus-4-6-1m" }, "thinking-1m": { modelUid: "claude-opus-4-6-thinking-1m" },
|
|
151
|
+
"fast": { modelUid: "claude-opus-4-6-fast" }, "thinking-fast": { modelUid: "claude-opus-4-6-thinking-fast" },
|
|
152
|
+
}, aliases: ["claude-opus-4-6"],
|
|
153
|
+
},
|
|
154
|
+
"gemini-3.5-flash": { id: "gemini-3.5-flash", defaultUid: "gemini-3-5-flash-medium",
|
|
155
|
+
variants: {
|
|
156
|
+
"minimal": { modelUid: "gemini-3-5-flash-minimal" }, "low": { modelUid: "gemini-3-5-flash-low" },
|
|
157
|
+
"medium": { modelUid: "gemini-3-5-flash-medium" }, "high": { modelUid: "gemini-3-5-flash-high" },
|
|
158
|
+
}, aliases: ["gemini-3-5-flash"],
|
|
159
|
+
},
|
|
160
|
+
"gpt-5.5": { id: "gpt-5.5", defaultUid: "gpt-5-5-low",
|
|
161
|
+
variants: {
|
|
162
|
+
"none": { modelUid: "gpt-5-5-none" }, "low": { modelUid: "gpt-5-5-low" },
|
|
163
|
+
"medium": { modelUid: "gpt-5-5-medium" }, "high": { modelUid: "gpt-5-5-high" }, "xhigh": { modelUid: "gpt-5-5-xhigh" },
|
|
164
|
+
"none-priority": { modelUid: "gpt-5-5-none-priority" }, "low-priority": { modelUid: "gpt-5-5-low-priority" },
|
|
165
|
+
"medium-priority": { modelUid: "gpt-5-5-medium-priority" }, "high-priority": { modelUid: "gpt-5-5-high-priority" },
|
|
166
|
+
"xhigh-priority": { modelUid: "gpt-5-5-xhigh-priority" },
|
|
167
|
+
}, aliases: ["gpt-5-5"],
|
|
168
|
+
},
|
|
169
|
+
"gpt-5.4": { id: "gpt-5.4", defaultUid: "gpt-5-4-none",
|
|
170
|
+
variants: {
|
|
171
|
+
"none": { modelUid: "gpt-5-4-none" }, "low": { modelUid: "gpt-5-4-low" },
|
|
172
|
+
"medium": { modelUid: "gpt-5-4-medium" }, "high": { modelUid: "gpt-5-4-high" }, "xhigh": { modelUid: "gpt-5-4-xhigh" },
|
|
173
|
+
"none-priority": { modelUid: "gpt-5-4-none-priority" }, "low-priority": { modelUid: "gpt-5-4-low-priority" },
|
|
174
|
+
"medium-priority": { modelUid: "gpt-5-4-medium-priority" }, "high-priority": { modelUid: "gpt-5-4-high-priority" },
|
|
175
|
+
"xhigh-priority": { modelUid: "gpt-5-4-xhigh-priority" },
|
|
176
|
+
}, aliases: ["gpt-5-4"],
|
|
177
|
+
},
|
|
178
|
+
"gpt-5.3-codex": { id: "gpt-5.3-codex", defaultUid: "gpt-5-3-codex-medium",
|
|
179
|
+
variants: {
|
|
180
|
+
"low": { modelUid: "gpt-5-3-codex-low" }, "medium": { modelUid: "gpt-5-3-codex-medium" },
|
|
181
|
+
"high": { modelUid: "gpt-5-3-codex-high" }, "xhigh": { modelUid: "gpt-5-3-codex-xhigh" },
|
|
182
|
+
"low-priority": { modelUid: "gpt-5-3-codex-low-priority" }, "medium-priority": { modelUid: "gpt-5-3-codex-medium-priority" },
|
|
183
|
+
"high-priority": { modelUid: "gpt-5-3-codex-high-priority" }, "xhigh-priority": { modelUid: "gpt-5-3-codex-xhigh-priority" },
|
|
184
|
+
}, aliases: ["gpt-5-3-codex"],
|
|
185
|
+
},
|
|
186
|
+
"gpt-5.2": { id: "gpt-5.2", defaultUid: "MODEL_GPT_5_2_LOW",
|
|
187
|
+
variants: {
|
|
188
|
+
"low": { modelUid: "MODEL_GPT_5_2_LOW" }, "medium": { modelUid: "MODEL_GPT_5_2_MEDIUM" },
|
|
189
|
+
"high": { modelUid: "MODEL_GPT_5_2_HIGH" }, "xhigh": { modelUid: "MODEL_GPT_5_2_XHIGH" },
|
|
190
|
+
"none": { modelUid: "MODEL_GPT_5_2_NONE" },
|
|
191
|
+
"low-priority": { modelUid: "MODEL_GPT_5_2_LOW_PRIORITY" }, "medium-priority": { modelUid: "MODEL_GPT_5_2_MEDIUM_PRIORITY" },
|
|
192
|
+
"high-priority": { modelUid: "MODEL_GPT_5_2_HIGH_PRIORITY" }, "xhigh-priority": { modelUid: "MODEL_GPT_5_2_XHIGH_PRIORITY" },
|
|
193
|
+
"none-priority": { modelUid: "MODEL_GPT_5_2_NONE_PRIORITY" },
|
|
194
|
+
}, aliases: ["gpt-5-2"],
|
|
195
|
+
},
|
|
196
|
+
"gpt-5.2-codex": { id: "gpt-5.2-codex", defaultUid: "MODEL_GPT_5_2_CODEX_LOW",
|
|
197
|
+
variants: {
|
|
198
|
+
"low": { modelUid: "MODEL_GPT_5_2_CODEX_LOW" }, "medium": { modelUid: "MODEL_GPT_5_2_CODEX_MEDIUM" },
|
|
199
|
+
"high": { modelUid: "MODEL_GPT_5_2_CODEX_HIGH" }, "xhigh": { modelUid: "MODEL_GPT_5_2_CODEX_XHIGH" },
|
|
200
|
+
"low-priority": { modelUid: "MODEL_GPT_5_2_CODEX_LOW_PRIORITY" }, "medium-priority": { modelUid: "MODEL_GPT_5_2_CODEX_MEDIUM_PRIORITY" },
|
|
201
|
+
"high-priority": { modelUid: "MODEL_GPT_5_2_CODEX_HIGH_PRIORITY" }, "xhigh-priority": { modelUid: "MODEL_GPT_5_2_CODEX_XHIGH_PRIORITY" },
|
|
202
|
+
}, aliases: ["gpt-5-2-codex"],
|
|
203
|
+
},
|
|
204
|
+
"kimi-k2.6": { id: "kimi-k2.6", defaultUid: "kimi-k2-6", aliases: ["kimi-k2-6"] },
|
|
205
|
+
"kimi-k2.7": { id: "kimi-k2.7", defaultUid: "kimi-k2-7", aliases: ["kimi-k2-7"] },
|
|
206
|
+
"glm-5.2": { id: "glm-5.2", defaultUid: "glm-5-2", aliases: ["glm-5-2"] },
|
|
207
|
+
"swe-1.6": { id: "swe-1.6", defaultUid: "swe-1-6",
|
|
208
|
+
variants: {
|
|
209
|
+
"base": { modelUid: "swe-1-6" }, "fast": { modelUid: "swe-1-6-fast" },
|
|
210
|
+
}, aliases: ["swe-1-6"],
|
|
211
|
+
},
|
|
212
|
+
"deepseek-v4": { id: "deepseek-v4", defaultUid: "deepseek-v4" },
|
|
213
|
+
"gemini-3.1-pro": { id: "gemini-3.1-pro", defaultUid: "gemini-3-1-pro-low",
|
|
214
|
+
variants: { "low": { modelUid: "gemini-3-1-pro-low" }, "high": { modelUid: "gemini-3-1-pro-high" } }, aliases: ["gemini-3-1-pro"],
|
|
215
|
+
},
|
|
216
|
+
"gpt-5.4-mini": { id: "gpt-5.4-mini", defaultUid: "gpt-5-4-mini-low",
|
|
217
|
+
variants: {
|
|
218
|
+
"low": { modelUid: "gpt-5-4-mini-low" }, "medium": { modelUid: "gpt-5-4-mini-medium" },
|
|
219
|
+
"high": { modelUid: "gpt-5-4-mini-high" }, "xhigh": { modelUid: "gpt-5-4-mini-xhigh" },
|
|
220
|
+
}, aliases: ["gpt-5-4-mini"],
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const ALIAS_TO_ID: Record<string, string> = Object.values(VARIANT_CATALOG).reduce((acc, entry) => {
|
|
225
|
+
acc[entry.id] = entry.id;
|
|
226
|
+
for (const alias of entry.aliases || []) acc[alias] = entry.id;
|
|
227
|
+
return acc;
|
|
228
|
+
}, {} as Record<string, string>);
|
|
229
|
+
|
|
230
|
+
// ----------------------------------------------------------------------------
|
|
231
|
+
// Model resolution
|
|
232
|
+
// ----------------------------------------------------------------------------
|
|
233
|
+
|
|
234
|
+
export interface ResolvedModel {
|
|
235
|
+
modelId: string;
|
|
236
|
+
modelUid: string;
|
|
237
|
+
variant?: string;
|
|
238
|
+
enumValue?: ModelEnumValue;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function splitModelAndVariant(raw: string): { base: string; variant?: string } {
|
|
242
|
+
const normalized = raw.toLowerCase().trim();
|
|
243
|
+
const colonIdx = normalized.indexOf(":");
|
|
244
|
+
if (colonIdx !== -1) {
|
|
245
|
+
return { base: normalized.slice(0, colonIdx), variant: normalized.slice(colonIdx + 1).trim() || undefined };
|
|
246
|
+
}
|
|
247
|
+
const parts = normalized.split("-");
|
|
248
|
+
for (let cut = 1; cut < parts.length; cut++) {
|
|
249
|
+
const base = parts.slice(0, parts.length - cut).join("-");
|
|
250
|
+
const maybeVariant = parts.slice(parts.length - cut).join("-");
|
|
251
|
+
const entry = VARIANT_CATALOG[ALIAS_TO_ID[base] || base];
|
|
252
|
+
if (entry?.variants?.[maybeVariant]) return { base, variant: maybeVariant };
|
|
253
|
+
}
|
|
254
|
+
return { base: normalized };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function resolveModel(modelName: string): ResolvedModel {
|
|
258
|
+
const { base, variant } = splitModelAndVariant(modelName);
|
|
259
|
+
const baseId = ALIAS_TO_ID[base] || base;
|
|
260
|
+
const entry = VARIANT_CATALOG[baseId];
|
|
261
|
+
|
|
262
|
+
if (entry) {
|
|
263
|
+
const effectiveVariant = (variant || "").trim().toLowerCase();
|
|
264
|
+
if (effectiveVariant && entry.variants?.[effectiveVariant]) {
|
|
265
|
+
const v = entry.variants[effectiveVariant]!;
|
|
266
|
+
return {
|
|
267
|
+
modelId: entry.id,
|
|
268
|
+
modelUid: v.modelUid ?? (v.enumValue !== undefined ? ENUM_VALUE_TO_NAME.get(v.enumValue as number) ?? "" : uidForEntry(entry)),
|
|
269
|
+
enumValue: v.enumValue,
|
|
270
|
+
variant: effectiveVariant,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
return { modelId: entry.id, modelUid: uidForEntry(entry), enumValue: entry.defaultEnum };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Legacy enum fallback
|
|
277
|
+
const enumKey = base.toUpperCase().replace(/\./g, "_").replace(/-/g, "_");
|
|
278
|
+
const enumValue = (ModelEnum as Record<string, number>)[enumKey];
|
|
279
|
+
if (enumValue !== undefined) {
|
|
280
|
+
const uid = ENUM_VALUE_TO_NAME.get(enumValue);
|
|
281
|
+
if (uid) return { modelId: base, modelUid: uid, enumValue: enumValue as ModelEnumValue };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
throw new Error(`Unknown Windsurf model: "${modelName}".`);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Resolve model but accept raw model_uid passthrough for catalog-discovered models
|
|
288
|
+
export function resolveModelOrPassthrough(modelName: string): ResolvedModel {
|
|
289
|
+
try {
|
|
290
|
+
return resolveModel(modelName);
|
|
291
|
+
} catch {
|
|
292
|
+
// Unknown model — pass through the raw name as the UID
|
|
293
|
+
return { modelId: modelName, modelUid: modelName };
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function uidForEntry(entry: ModelCatalogEntry): string {
|
|
298
|
+
if (entry.defaultUid) return entry.defaultUid;
|
|
299
|
+
if (entry.defaultEnum !== undefined) {
|
|
300
|
+
const uid = ENUM_VALUE_TO_NAME.get(entry.defaultEnum as number);
|
|
301
|
+
if (uid) return uid;
|
|
302
|
+
}
|
|
303
|
+
throw new Error(`Catalog entry "${entry.id}" has no defaultUid or defaultEnum`);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export function getDefaultModel(): string { return "claude-opus-4.8:medium"; }
|
|
307
|
+
|
|
308
|
+
export function getCanonicalModels(): string[] {
|
|
309
|
+
return Object.keys(VARIANT_CATALOG);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Build reverse lookup: model_uid → user-facing model ID
|
|
313
|
+
const UID_TO_MODEL_ID: Map<string, string> = (() => {
|
|
314
|
+
const map = new Map<string, string>();
|
|
315
|
+
for (const [id, entry] of Object.entries(VARIANT_CATALOG)) {
|
|
316
|
+
// Default UID
|
|
317
|
+
try {
|
|
318
|
+
const defaultUid = entry.defaultUid ?? (entry.defaultEnum !== undefined ? ENUM_VALUE_TO_NAME.get(entry.defaultEnum as number) : undefined);
|
|
319
|
+
if (defaultUid) map.set(defaultUid, id);
|
|
320
|
+
} catch {}
|
|
321
|
+
// Variant UIDs
|
|
322
|
+
if (entry.variants) {
|
|
323
|
+
for (const [variantKey, variantMeta] of Object.entries(entry.variants)) {
|
|
324
|
+
const vUid = variantMeta.modelUid ?? (variantMeta.enumValue !== undefined ? ENUM_VALUE_TO_NAME.get(variantMeta.enumValue as number) : undefined);
|
|
325
|
+
if (vUid) map.set(vUid, `${id}:${variantKey}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Also map legacy enum names
|
|
330
|
+
for (const [key, value] of Object.entries(ModelEnum)) {
|
|
331
|
+
if (typeof value === "number") {
|
|
332
|
+
const uid = ENUM_VALUE_TO_NAME.get(value);
|
|
333
|
+
if (uid && !map.has(uid)) {
|
|
334
|
+
const id = key.toLowerCase().replace(/_/g, "-");
|
|
335
|
+
map.set(uid, id);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return map;
|
|
340
|
+
})();
|
|
341
|
+
|
|
342
|
+
export function lookupModelId(uid: string): string | null {
|
|
343
|
+
// Direct lookup
|
|
344
|
+
const direct = UID_TO_MODEL_ID.get(uid);
|
|
345
|
+
if (direct) return direct;
|
|
346
|
+
// Strip _BYOK suffix (Bring Your Own Key variants)
|
|
347
|
+
const withoutByok = uid.replace(/_BYOK$/, "");
|
|
348
|
+
if (withoutByok !== uid) {
|
|
349
|
+
const byokMatch = UID_TO_MODEL_ID.get(withoutByok);
|
|
350
|
+
if (byokMatch) return byokMatch;
|
|
351
|
+
}
|
|
352
|
+
return null;
|
|
353
|
+
}
|