-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.js
More file actions
82 lines (71 loc) · 2.32 KB
/
Copy pathconfig.js
File metadata and controls
82 lines (71 loc) · 2.32 KB
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
export const OPENCODE_BASE = "https://opencode.ai";
export const MESSAGES_FORMAT_MODELS = new Set([
"big-pickle",
]);
export const STATIC_FALLBACK_MODELS = [
{ id: "big-pickle", name: "Big Pickle", free: true },
{ id: "deepseek-v4-flash-free", name: "DeepSeek V4 Flash Free", free: true },
{ id: "mimo-v2.5-free", name: "MiMo-V2.5 Free", free: true },
{ id: "nemotron-3-ultra-free", name: "Nemotron 3 Ultra Free", free: true },
{ id: "grok-code", name: "Grok Code Fast 1", free: true },
{ id: "glm-5-free", name: "GLM 5 Free", free: true },
{ id: "kimi-k2.5-free", name: "Kimi K2.5 Free", free: true },
{ id: "minimax-m2.5-free", name: "MiniMax M2.5 Free", free: true },
];
let cachedModels = null;
let cacheTime = 0;
const CACHE_TTL = 3600 * 1000;
export function buildOpenCodeHeaders() {
return {
"Content-Type": "application/json",
"Authorization": "Bearer public",
"x-opencode-client": "desktop",
"Accept": "text/event-stream",
};
}
export function resolveEndpoint(modelId) {
if (MESSAGES_FORMAT_MODELS.has(modelId)) {
return `${OPENCODE_BASE}/zen/v1/messages`;
}
return `${OPENCODE_BASE}/zen/v1/chat/completions`;
}
export async function getFreeModels() {
const now = Date.now();
if (cachedModels && now - cacheTime < CACHE_TTL) {
return cachedModels;
}
try {
const resp = await fetch(`${OPENCODE_BASE}/zen/v1/models`, {
headers: buildOpenCodeHeaders(),
});
if (!resp.ok) {
throw new Error(`Failed to fetch models: ${resp.status}`);
}
const payload = await resp.json();
if (Array.isArray(payload.data)) {
const parsedModels = payload.data
.map((m) => m.id)
.filter((id) => id.includes("-free") || id === "big-pickle" || id === "grok-code" || id === "gpt-5-nano")
.map((id) => ({
id,
name: id
.split("-")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" "),
free: true,
}));
if (parsedModels.length > 0) {
cachedModels = parsedModels;
cacheTime = now;
return cachedModels;
}
}
} catch (err) {
console.error("Error fetching dynamic models, using static fallback:", err.message);
}
if (!cachedModels) {
cachedModels = STATIC_FALLBACK_MODELS;
cacheTime = now;
}
return cachedModels;
}