openzoo 0.22.2 → 0.23.0
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/lib/cursorcfg.js +36 -2
- package/lib/models.js +35 -0
- package/package.json +1 -1
package/lib/cursorcfg.js
CHANGED
|
@@ -87,6 +87,40 @@ export async function quitEditor(which) {
|
|
|
87
87
|
* should offer. Returns what changed, or null when the store is unavailable
|
|
88
88
|
* (a fresh install with no globalStorage yet).
|
|
89
89
|
*/
|
|
90
|
+
/**
|
|
91
|
+
* PRETTY NAMES IN THE PICKER, WITHOUT LOSING VALIDATION.
|
|
92
|
+
*
|
|
93
|
+
* The editor validates `name` against its OWN catalog and refuses anything else
|
|
94
|
+
* ("Model name is not valid" / "Max Mode Required"), so `name` MUST stay a bland
|
|
95
|
+
* id it already knows. But the picker renders `inputboxShortModelName`, which it
|
|
96
|
+
* does not validate — so the row can read "Opus 5" while the id stays gpt-4o.
|
|
97
|
+
*
|
|
98
|
+
* The zoo model that actually answers is chosen by the proxy, so a slot is a
|
|
99
|
+
* (bland id -> real model -> label) triple. Override with OPENZOO_EDITOR_MAP:
|
|
100
|
+
* OPENZOO_EDITOR_MAP="gpt-4o=x-ai/grok-4.6:Grok 4.6,gpt-4.1=anthropic/claude-sonnet-5:Sonnet 5"
|
|
101
|
+
*/
|
|
102
|
+
const DEFAULT_SLOTS = {
|
|
103
|
+
'gpt-4o': { served: 'anthropic/claude-opus-5', label: 'Opus 5' },
|
|
104
|
+
'gpt-4.1': { served: 'anthropic/claude-sonnet-5', label: 'Sonnet 5' },
|
|
105
|
+
'gpt-4-turbo': { served: 'x-ai/grok-4.6', label: 'Grok 4.6' },
|
|
106
|
+
'gpt-4o-mini': { served: 'google/gemini-3.7-flash', label: 'Gemini 3.7 Flash' },
|
|
107
|
+
'gpt-4.1-mini': { served: 'deepseek/deepseek-v4-pro-0813', label: 'DeepSeek V4 Pro' },
|
|
108
|
+
'gpt-3.5-turbo': { served: 'qwen/qwen3.8-2.4t-a95b', label: 'Qwen3.8 2.4T' },
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export function slotFor(id) {
|
|
112
|
+
const env = process.env.OPENZOO_EDITOR_MAP;
|
|
113
|
+
if (env) {
|
|
114
|
+
for (const part of env.split(',')) {
|
|
115
|
+
const [lhs, rhs] = part.split('=');
|
|
116
|
+
if ((lhs || '').trim() !== id || !rhs) continue;
|
|
117
|
+
const [served, ...lbl] = rhs.split(':');
|
|
118
|
+
return { served: served.trim(), label: (lbl.join(':') || served).trim() };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return DEFAULT_SLOTS[id] || { served: id, label: id };
|
|
122
|
+
}
|
|
123
|
+
|
|
90
124
|
export function writeEditorProviderConfig(which, { baseUrl, models }) {
|
|
91
125
|
const db = storagePath(which);
|
|
92
126
|
if (!fs.existsSync(db)) return null;
|
|
@@ -132,11 +166,11 @@ export function writeEditorProviderConfig(which, { baseUrl, models }) {
|
|
|
132
166
|
supportsMaxMode: true,
|
|
133
167
|
supportsNonMaxMode: true,
|
|
134
168
|
serverModelName: m,
|
|
169
|
+
inputboxShortModelName: slotFor(m).label,
|
|
135
170
|
isRecommendedForBackgroundComposer: false,
|
|
136
171
|
supportsPlanMode: true,
|
|
137
172
|
supportsSandboxing: true,
|
|
138
173
|
isUserAdded: true,
|
|
139
|
-
inputboxShortModelName: m,
|
|
140
174
|
parameterDefinitions: [],
|
|
141
175
|
variants: [],
|
|
142
176
|
legacySlugs: [],
|
|
@@ -214,7 +248,7 @@ export function pinEditorProviderConfig(which, { baseUrl, models }) {
|
|
|
214
248
|
supportsThinking: true, supportsImages: true, supportsMaxMode: true,
|
|
215
249
|
supportsNonMaxMode: true, serverModelName: m,
|
|
216
250
|
isRecommendedForBackgroundComposer: false, supportsPlanMode: true,
|
|
217
|
-
supportsSandboxing: true, isUserAdded: true, inputboxShortModelName: m,
|
|
251
|
+
supportsSandboxing: true, isUserAdded: true, inputboxShortModelName: slotFor(m).label,
|
|
218
252
|
parameterDefinitions: [], variants: [], legacySlugs: [], idAliases: [],
|
|
219
253
|
namedModelSectionIndex: 1, cloudAgentEffortModes: [], modelPickerBadges: [],
|
|
220
254
|
}))));
|
package/lib/models.js
CHANGED
|
@@ -19,6 +19,31 @@ import { config } from './config.js';
|
|
|
19
19
|
* cached briefly, so new zoo models resolve without shipping this package.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* The editor-slot map: bland id the editor accepts -> the zoo model that should
|
|
24
|
+
* actually answer it. Mirrors DEFAULT_SLOTS in cursorcfg.js; OPENZOO_EDITOR_MAP
|
|
25
|
+
* overrides both ("gpt-4o=x-ai/grok-4.6:Grok 4.6,...").
|
|
26
|
+
*/
|
|
27
|
+
const DEFAULT_SLOT_MODELS = {
|
|
28
|
+
'gpt-4o': 'anthropic/claude-opus-5',
|
|
29
|
+
'gpt-4.1': 'anthropic/claude-sonnet-5',
|
|
30
|
+
'gpt-4-turbo': 'x-ai/grok-4.6',
|
|
31
|
+
'gpt-4o-mini': 'google/gemini-3.7-flash',
|
|
32
|
+
'gpt-4.1-mini': 'deepseek/deepseek-v4-pro-0813',
|
|
33
|
+
'gpt-3.5-turbo': 'qwen/qwen3.8-2.4t-a95b',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export function editorSlot(id) {
|
|
37
|
+
const env = process.env.OPENZOO_EDITOR_MAP;
|
|
38
|
+
if (env) {
|
|
39
|
+
for (const part of env.split(',')) {
|
|
40
|
+
const [lhs, rhs] = part.split('=');
|
|
41
|
+
if ((lhs || '').trim() === id && rhs) return rhs.split(':')[0].trim();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return DEFAULT_SLOT_MODELS[id] || null;
|
|
45
|
+
}
|
|
46
|
+
|
|
22
47
|
const CATALOG_TTL_MS = 5 * 60 * 1000;
|
|
23
48
|
let cache = { at: 0, ids: null };
|
|
24
49
|
|
|
@@ -114,9 +139,19 @@ export function resolveModel(requested, ids) {
|
|
|
114
139
|
if (exact) return exact;
|
|
115
140
|
requested = bare;
|
|
116
141
|
}
|
|
142
|
+
// An explicit OPENZOO_DEFAULT_MODEL is a deliberate act and outranks
|
|
143
|
+
// everything below it, including the editor slots.
|
|
117
144
|
const env = process.env.OPENZOO_DEFAULT_MODEL;
|
|
118
145
|
if (env && ids.includes(env)) return env;
|
|
119
146
|
|
|
147
|
+
// SLOT MAP. The editor only accepts a handful of bland ids it already knows,
|
|
148
|
+
// so the shim writes those as slots and shows a real label for each (slotFor
|
|
149
|
+
// in cursorcfg.js). That label would be a LIE if the id then fell through to
|
|
150
|
+
// the similarity scorer, so the same mapping is honoured here: gpt-4o really
|
|
151
|
+
// is served by claude-opus-5. One source of truth, OPENZOO_EDITOR_MAP.
|
|
152
|
+
const slot = editorSlot(requested);
|
|
153
|
+
if (slot && ids.includes(slot)) return slot;
|
|
154
|
+
|
|
120
155
|
const reqTier = tierOf(requested);
|
|
121
156
|
const reqCode = CODE_RE.test(requested);
|
|
122
157
|
const reqToks = new Set(tokensOf(requested));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzoo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Local x402-paying proxy + MCP server for openzoo.fun — point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana and Base rails live; Robinhood experimental.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|