@oharness/server 0.5.1 → 0.7.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.
@@ -0,0 +1,249 @@
1
+ /**
2
+ * The order models are shown in, within each provider.
3
+ *
4
+ * A plain string sort got every part of this wrong: "claude-opus-4-5" came
5
+ * before "claude-opus-5" because "4" < "5" as characters, so the oldest version
6
+ * of a family led it; ":batch" and ":free" routings and dated snapshots were
7
+ * interleaved with the models they are variants of; and under OpenRouter four
8
+ * hundred ids ran together with no sense of whose they were.
9
+ *
10
+ * So an id is read as parts — an aggregator's vendor namespace, a family, a
11
+ * version, a suffix, a dated snapshot, a routing variant — and ordered by:
12
+ *
13
+ * 1. vendor: the provider's own models first, then the frontier labs in a
14
+ * fixed order, then the rest alphabetically. An aggregator's namespace
15
+ * names the vendor; where there is none (OHarness's own plan serves
16
+ * "gpt-6-astra" beside "glm-5.3") it is read off the family name, since
17
+ * version numbers from different vendors mean nothing side by side. A
18
+ * vendor's `~` aliases ("latest") lead it.
19
+ * 2. family: the main lines in a fixed order (Opus before Haiku, Gemini
20
+ * before Gemma), the rest by their newest version
21
+ * 3. the plain routing before ":free", ":batch" and the like — after the
22
+ * whole family, so a batch twin does not double the list's length
23
+ * 4. version, newest first, compared as numbers
24
+ * 5. the base model before its named variants, the heavier ones ("-max",
25
+ * "-pro") before the lighter ("-flash", "-lite", "-mini")
26
+ * 6. the rolling name before dated snapshots, newest snapshot first
27
+ *
28
+ * Newest-first is the rule because it is the one that holds across vendors
29
+ * without knowing them: the model someone is looking for is almost always the
30
+ * current one, and it is now at the top of its family rather than the bottom.
31
+ * Providers keep the order they arrive in, which is the catalog's.
32
+ */
33
+ /** Aggregator vendor namespaces that lead, in this order; the rest follow alphabetically. */
34
+ const LEADING_VENDORS = [
35
+ "anthropic",
36
+ "openai",
37
+ "google",
38
+ "x-ai",
39
+ "deepseek",
40
+ "qwen",
41
+ "moonshotai",
42
+ "z-ai",
43
+ "bytedance-seed",
44
+ "meta-llama",
45
+ "mistralai",
46
+ ];
47
+ /** Which vendor a provider's own models come from, for putting them first. */
48
+ const PROVIDER_VENDOR = {
49
+ anthropic: "anthropic",
50
+ openai: "openai",
51
+ "openai-codex": "openai",
52
+ google: "google",
53
+ xai: "x-ai",
54
+ deepseek: "deepseek",
55
+ qwen: "qwen",
56
+ "qwen-coding-plan": "qwen",
57
+ moonshot: "moonshotai",
58
+ "kimi-coding": "moonshotai",
59
+ zai: "z-ai",
60
+ "zai-coding": "z-ai",
61
+ byteplus: "bytedance-seed",
62
+ mistral: "mistralai",
63
+ llama: "meta-llama",
64
+ };
65
+ /** A family name's vendor, for ids that carry no namespace. First match wins. */
66
+ const FAMILY_VENDOR = [
67
+ [/^claude/, "anthropic"],
68
+ [/^(gpt|o\d|codex|chatgpt)/, "openai"],
69
+ [/^(gemini|gemma)/, "google"],
70
+ [/^grok/, "x-ai"],
71
+ [/^deepseek/, "deepseek"],
72
+ [/^(qwen|qwq)/, "qwen"],
73
+ [/^(kimi|moonshot)/, "moonshotai"],
74
+ [/^glm/, "z-ai"],
75
+ [/^(seed|doubao|dola)/, "bytedance-seed"],
76
+ [/^llama/, "meta-llama"],
77
+ [/^(mistral|magistral|devstral|codestral|ministral)/, "mistralai"],
78
+ ];
79
+ /** Main lines in the order they are reached for; other families follow by newest version. */
80
+ const FAMILY_ORDER = [
81
+ "claude-fable",
82
+ "claude-opus",
83
+ "claude-sonnet",
84
+ "claude-haiku",
85
+ "gpt",
86
+ "gemini",
87
+ "gemma",
88
+ "grok",
89
+ "deepseek",
90
+ "qwen",
91
+ "kimi",
92
+ "glm",
93
+ ];
94
+ const DATE = /[-_@](\d{4}-?\d{2}-?\d{2}|\d{4})$/;
95
+ export function modelParts(id, provider) {
96
+ let name = id.startsWith(provider + "/") ? id.slice(provider.length + 1) : id;
97
+ let routing = "";
98
+ const colon = name.lastIndexOf(":");
99
+ if (colon > 0) {
100
+ routing = name.slice(colon + 1);
101
+ name = name.slice(0, colon);
102
+ }
103
+ let vendor = "";
104
+ let alias = false;
105
+ const slash = name.lastIndexOf("/");
106
+ if (slash > 0) {
107
+ vendor = name.slice(0, slash);
108
+ name = name.slice(slash + 1);
109
+ if (vendor.startsWith("~")) {
110
+ alias = true;
111
+ vendor = vendor.slice(1);
112
+ }
113
+ }
114
+ // A trailing date is a pinned snapshot of the rolling name before it
115
+ // ("claude-haiku-4-5-20251001", "gpt-4o-2024-08-06"), not part of the
116
+ // version — read as one it would outrank every real release.
117
+ let snapshot = "";
118
+ const dated = name.match(DATE);
119
+ if (dated && dated[1].replace(/-/g, "").length >= 8) {
120
+ snapshot = dated[1].replace(/-/g, "");
121
+ name = name.slice(0, dated.index);
122
+ }
123
+ // Version parts are dotted or dashed numbers. One that runs into a letter is
124
+ // a size ("qwen3-235b", "llama-3.1-70b"), and one with a leading zero or four
125
+ // digits is a date ("kimi-k2-0905-preview"), not the next part of a version.
126
+ const versioned = name.match(/^(.*?)(\d+(?:[.-](?:0|[1-9]\d{0,2})(?![a-z\d]))*)(.*)$/i);
127
+ const family = versioned ? versioned[1].replace(/[-_.]+$/, "") : name;
128
+ if (!vendor)
129
+ vendor = FAMILY_VENDOR.find(([pattern]) => pattern.test(family.toLowerCase()))?.[1] ?? "";
130
+ if (!versioned) {
131
+ return { vendor, alias, family, version: [], suffix: "", snapshot, routing };
132
+ }
133
+ return {
134
+ vendor,
135
+ alias,
136
+ family,
137
+ version: versioned[2].split(/[.-]/).map(Number),
138
+ suffix: versioned[3].replace(/^[-_.]+/, ""),
139
+ snapshot,
140
+ routing,
141
+ };
142
+ }
143
+ /** The fixed rank of a family, or undefined for one ordered by its newest version. */
144
+ function familyRank(family) {
145
+ const lower = family.toLowerCase();
146
+ // Longest match, so "claude-opus" is not taken for a bare "claude".
147
+ let best;
148
+ let length = -1;
149
+ FAMILY_ORDER.forEach((name, i) => {
150
+ if ((lower === name || lower.startsWith(name + "-") || lower.startsWith(name)) && name.length > length) {
151
+ best = i;
152
+ length = name.length;
153
+ }
154
+ });
155
+ return best;
156
+ }
157
+ const HEAVY = new Set(["max", "pro", "plus", "ultra", "thinking", "opus"]);
158
+ const LIGHT = new Set(["flash", "turbo", "lite", "mini", "nano", "air", "fast", "highspeed", "haiku"]);
159
+ /** Base first, then heavier variants, then the rest, then the lighter ones. */
160
+ function suffixRank(suffix) {
161
+ if (!suffix)
162
+ return 0;
163
+ const head = suffix.toLowerCase().split(/[-_.]/)[0];
164
+ if (HEAVY.has(head))
165
+ return 1;
166
+ if (LIGHT.has(head))
167
+ return 3;
168
+ return 2;
169
+ }
170
+ function compareVersionsDesc(a, b) {
171
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
172
+ const d = (b[i] ?? -1) - (a[i] ?? -1);
173
+ if (d !== 0)
174
+ return d;
175
+ }
176
+ return 0;
177
+ }
178
+ /** Newest first; a dated model before an undated one; two undated are a tie. */
179
+ function byRelease(a, b) {
180
+ if (a === undefined)
181
+ return b === undefined ? 0 : 1;
182
+ if (b === undefined)
183
+ return -1;
184
+ return b - a;
185
+ }
186
+ function vendorRank(vendor, provider) {
187
+ if (!vendor)
188
+ return LEADING_VENDORS.length + 2;
189
+ if (PROVIDER_VENDOR[provider] === vendor)
190
+ return -1;
191
+ const at = LEADING_VENDORS.indexOf(vendor);
192
+ return at < 0 ? LEADING_VENDORS.length : at;
193
+ }
194
+ /**
195
+ * Sort models for display: providers in arrival order, and within each the
196
+ * newest release first.
197
+ *
198
+ * A release date is the order people mean by "newest", and the id only
199
+ * approximates it — "kimi-k2-0905" and "qwen3-235b" are the cases the rules
200
+ * above exist to survive. So the date leads wherever there is one: a `latest`
201
+ * alias first (it is whichever is newest), then dated models newest first,
202
+ * then the undated in the order the id rules give. Two models with the same
203
+ * date — a model and its `:batch` twin, a family released together — fall
204
+ * back to those rules too, which keeps a variant beside its model.
205
+ *
206
+ * Read from the wire name where there is one: a curated alias ("opus" for
207
+ * claude-opus-5) says nothing about where it belongs, the model it names does.
208
+ */
209
+ export function sortModelsForDisplay(models) {
210
+ const providerOrder = new Map();
211
+ for (const model of models) {
212
+ if (!providerOrder.has(model.provider))
213
+ providerOrder.set(model.provider, providerOrder.size);
214
+ }
215
+ const parts = new Map(models.map((model) => [model, modelParts(model.model ?? model.id, model.provider)]));
216
+ // Each family's newest version, so a family is placed by its best member.
217
+ const newest = new Map();
218
+ for (const [model, p] of parts) {
219
+ const key = `${model.provider}|${p.vendor}|${p.family}`;
220
+ const held = newest.get(key);
221
+ if (!held || compareVersionsDesc(p.version, held) < 0)
222
+ newest.set(key, p.version);
223
+ }
224
+ return [...models].sort((a, b) => {
225
+ const pa = parts.get(a);
226
+ const pb = parts.get(b);
227
+ const fa = familyRank(pa.family) ?? FAMILY_ORDER.length;
228
+ const fb = familyRank(pb.family) ?? FAMILY_ORDER.length;
229
+ return (providerOrder.get(a.provider) - providerOrder.get(b.provider) ||
230
+ Number(pb.alias) - Number(pa.alias) ||
231
+ byRelease(a.releasedAt, b.releasedAt) ||
232
+ vendorRank(pa.vendor, a.provider) - vendorRank(pb.vendor, b.provider) ||
233
+ pa.vendor.localeCompare(pb.vendor) ||
234
+ Number(pb.alias) - Number(pa.alias) ||
235
+ fa - fb ||
236
+ compareVersionsDesc(newest.get(`${a.provider}|${pa.vendor}|${pa.family}`), newest.get(`${b.provider}|${pb.vendor}|${pb.family}`)) ||
237
+ pa.family.localeCompare(pb.family) ||
238
+ Number(pa.routing !== "") - Number(pb.routing !== "") ||
239
+ compareVersionsDesc(pa.version, pb.version) ||
240
+ suffixRank(pa.suffix) - suffixRank(pb.suffix) ||
241
+ pa.suffix.localeCompare(pb.suffix) ||
242
+ Number(pa.snapshot !== "") - Number(pb.snapshot !== "") ||
243
+ pb.snapshot.localeCompare(pa.snapshot) ||
244
+ Number(pa.routing !== "") - Number(pb.routing !== "") ||
245
+ pa.routing.localeCompare(pb.routing) ||
246
+ a.id.localeCompare(b.id));
247
+ });
248
+ }
249
+ //# sourceMappingURL=model-order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-order.js","sourceRoot":"","sources":["../src/model-order.ts"],"names":[],"mappings":"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"}