@bman654/clodex 2.18.7 → 2.18.8
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/README.md +2 -2
- package/dist/cli.js +57 -38
- package/dist/cli.js.map +1 -1
- package/docs/opencode-go.md +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -244,7 +244,7 @@ Manage favorite models (max 20) and short aliases. Favorites feed the endpoint-m
|
|
|
244
244
|
| `--unalias <name>` | Remove a saved short name |
|
|
245
245
|
| `--context <model=stop>` | Choose how much of a model's context window to use: `standard`, `max`, `default` to clear, or a token count such as `500k`. Applies to this run unless `--save` is given |
|
|
246
246
|
| `--save` | With `--context`: store the stop as that model's default |
|
|
247
|
-
| `--json` | Print resolved metadata for saved favorites as JSON (ids, aliases, context stop and windows, output limit, pricing boundary, effort levels). Diagnostics go to stderr so stdout stays parseable |
|
|
247
|
+
| `--json` | Print resolved metadata for saved favorites as JSON (ids, aliases, context stop and windows, output limit, pricing boundary, effort levels). A model saved under several aliases lists them all in `aliases`, in saved order; `alias` is the first. Diagnostics go to stderr so stdout stays parseable |
|
|
248
248
|
| `--help`, `--version` | Help / version |
|
|
249
249
|
|
|
250
250
|
#### Context stops and the pricing boundary
|
|
@@ -324,7 +324,7 @@ and their seeded flags when discovery omits them. Models not using Responses-Lit
|
|
|
324
324
|
this version header and are not hidden by this check. This check does not establish your
|
|
325
325
|
account's model entitlement.
|
|
326
326
|
|
|
327
|
-
Providers supported: `openai` (API key, platform.openai.com), `openai-oauth` (ChatGPT/Codex plan), and `opencode-go` (OpenCode Go API key). OpenCode Go exposes its Anthropic Messages, Chat Completions, and Responses models; entries whose transport has
|
|
327
|
+
Providers supported: `openai` (API key, platform.openai.com), `openai-oauth` (ChatGPT/Codex plan), and `opencode-go` (OpenCode Go API key). OpenCode Go exposes its Anthropic Messages, Chat Completions, and Responses models; only entries whose transport has been verified, live or against OpenCode's per-model endpoint table, are included. See [OpenCode Go provider](docs/opencode-go.md).
|
|
328
328
|
|
|
329
329
|
A **custom OpenAI-compatible server** is any OpenAI-style API, given by its base URL (the part before `/chat/completions`), such as `https://openrouter.ai/api/v1`. `providers add` asks for a name, the base URL and an API key (leave it empty for a local server without auth), lists the server's models to check the connection, and saves the provider as `custom-<name>`. Its models then appear in `clodex models`; once saved as favorites they are addressed as `clodex:custom-<name>:<model>` and can be given a short alias with `clodex models --alias`. The base URL is checked before anything is saved and again when its models are refreshed: plain `http://` is accepted only after you confirm it, and only if every address the host resolves to is on this machine, your LAN or a private network such as Tailscale (loopback, private, unique-local IPv6 or carrier-grade-NAT `100.64.0.0/10` addresses); `https://` is accepted on any of those networks as well as the public internet; and a link-local (`169.254.0.0/16`, `fe80::/10`) or well-known cloud-metadata address is refused whether or not HTTP was approved. A server on another machine in your tailnet can be added by its `100.x` address, its MagicDNS name, or the HTTPS name `tailscale serve` gives it. A model's id and name are stored with surrounding whitespace trimmed, and a model whose trimmed id or name still contains a control character is skipped, whether the list is fetched by `providers add` or by `providers refresh-models`, and error text from the server is shown with control characters replaced by spaces. Only the OpenAI-compatible kind is offered in the menu.
|
|
330
330
|
|
package/dist/cli.js
CHANGED
|
@@ -346,7 +346,7 @@ import { join } from "path";
|
|
|
346
346
|
// package.json
|
|
347
347
|
var package_default = {
|
|
348
348
|
name: "@bman654/clodex",
|
|
349
|
-
version: "2.18.
|
|
349
|
+
version: "2.18.8",
|
|
350
350
|
publishConfig: {
|
|
351
351
|
access: "public"
|
|
352
352
|
},
|
|
@@ -3486,11 +3486,11 @@ function applyClodexPatches(source, config) {
|
|
|
3486
3486
|
};
|
|
3487
3487
|
for (const [id, value] of Object.entries(MODEL_CONFIG)) {
|
|
3488
3488
|
const spec = value && typeof value === "object" ? value : { alias: value };
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
const a =
|
|
3489
|
+
const aliasNames = spec.alias === void 0 ? [] : [String(spec.alias), ...(spec.moreAliases ?? []).map(String)];
|
|
3490
|
+
for (const name of aliasNames) {
|
|
3491
|
+
const a = name.trim().toLowerCase();
|
|
3492
3492
|
if (!/^[a-z0-9][a-z0-9._-]*(\[1m\])?$/.test(a)) {
|
|
3493
|
-
fail('clodex patch: alias "' +
|
|
3493
|
+
fail('clodex patch: alias "' + name + '" is not a safe lowercase alias');
|
|
3494
3494
|
}
|
|
3495
3495
|
if (isReservedModelAlias(a)) {
|
|
3496
3496
|
fail('clodex patch: reserved alias "' + a + '" cannot be reassigned');
|
|
@@ -3498,25 +3498,24 @@ function applyClodexPatches(source, config) {
|
|
|
3498
3498
|
ALIAS_TO_ID[a] = String(id);
|
|
3499
3499
|
IDENTITIES.push(a);
|
|
3500
3500
|
if (spec.display) DISPLAY_BY_IDENTITY[a] = String(spec.display);
|
|
3501
|
-
|
|
3501
|
+
registerCapabilityKeys(name);
|
|
3502
|
+
}
|
|
3503
|
+
if (aliasNames.length === 0) {
|
|
3502
3504
|
IDENTITIES.push(String(id));
|
|
3503
3505
|
if (spec.display) DISPLAY_BY_IDENTITY[String(id)] = String(spec.display);
|
|
3504
3506
|
}
|
|
3505
|
-
if (spec.alias !== void 0) {
|
|
3506
|
-
registerCapabilityKeys(String(spec.alias));
|
|
3507
|
-
}
|
|
3508
3507
|
registerCapabilityKeys(String(id));
|
|
3509
3508
|
if (spec.context !== void 0) {
|
|
3510
3509
|
const n = Number(spec.context);
|
|
3511
3510
|
if (!Number.isInteger(n) || n <= 0) {
|
|
3512
3511
|
fail('clodex patch: context for "' + id + '" must be a positive integer, got ' + spec.context);
|
|
3513
3512
|
}
|
|
3514
|
-
if (/\[1m\]/i.test(
|
|
3513
|
+
if (aliasNames.some((name) => /\[1m\]/i.test(name)) || /\[1m\]/i.test(id)) {
|
|
3515
3514
|
fail(
|
|
3516
3515
|
'clodex patch: "' + id + '" sets context but keeps the [1m] suffix \u2014 drop the suffix from both the id and the alias'
|
|
3517
3516
|
);
|
|
3518
3517
|
}
|
|
3519
|
-
|
|
3518
|
+
for (const name of aliasNames) CONTEXT_BY_KEY[name.trim().toLowerCase()] = n;
|
|
3520
3519
|
CONTEXT_BY_KEY[String(id).trim().toLowerCase()] = n;
|
|
3521
3520
|
}
|
|
3522
3521
|
if (spec.effort) {
|
|
@@ -3526,8 +3525,8 @@ function applyClodexPatches(source, config) {
|
|
|
3526
3525
|
`clodex patch: effort for "${id}" must include low, medium, and high with a native default`
|
|
3527
3526
|
);
|
|
3528
3527
|
}
|
|
3529
|
-
|
|
3530
|
-
for (const key of capabilityKeys(
|
|
3528
|
+
for (const name of aliasNames) {
|
|
3529
|
+
for (const key of capabilityKeys(name)) {
|
|
3531
3530
|
EFFORT_BY_KEY[key] = effort;
|
|
3532
3531
|
}
|
|
3533
3532
|
}
|
|
@@ -4186,11 +4185,12 @@ function configuredAliases(config) {
|
|
|
4186
4185
|
const aliases = /* @__PURE__ */ new Map();
|
|
4187
4186
|
for (const [id, entry] of Object.entries(config)) {
|
|
4188
4187
|
if (entry.alias === void 0) continue;
|
|
4189
|
-
const
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4188
|
+
for (const name of [entry.alias, ...entry.moreAliases ?? []]) {
|
|
4189
|
+
aliases.set(String(name).trim().toLowerCase(), {
|
|
4190
|
+
id,
|
|
4191
|
+
...entry.display === void 0 ? {} : { display: String(entry.display) }
|
|
4192
|
+
});
|
|
4193
|
+
}
|
|
4194
4194
|
}
|
|
4195
4195
|
return [...aliases].map(([alias, entry]) => ({ alias, ...entry }));
|
|
4196
4196
|
}
|
|
@@ -4902,17 +4902,27 @@ var opencode_go_models_default = [
|
|
|
4902
4902
|
output: 0.6,
|
|
4903
4903
|
cache_read: 3e-3
|
|
4904
4904
|
},
|
|
4905
|
-
modelFormat: "
|
|
4906
|
-
npm: "@ai-sdk/
|
|
4907
|
-
apiUrl: "https://opencode.ai/zen/go",
|
|
4905
|
+
modelFormat: "openai",
|
|
4906
|
+
npm: "@ai-sdk/openai-compatible",
|
|
4907
|
+
apiUrl: "https://opencode.ai/zen/go/v1",
|
|
4908
4908
|
reasoning: true,
|
|
4909
4909
|
modalities: [
|
|
4910
4910
|
"text",
|
|
4911
4911
|
"image"
|
|
4912
4912
|
],
|
|
4913
4913
|
compatibility: {
|
|
4914
|
-
|
|
4915
|
-
|
|
4914
|
+
reasoningEffortMap: {
|
|
4915
|
+
minimal: null,
|
|
4916
|
+
low: null,
|
|
4917
|
+
medium: null,
|
|
4918
|
+
high: "high",
|
|
4919
|
+
max: "max"
|
|
4920
|
+
},
|
|
4921
|
+
supportsStore: false,
|
|
4922
|
+
supportsDeveloperRole: false,
|
|
4923
|
+
maxTokensField: "max_tokens",
|
|
4924
|
+
requiresReasoningContentOnAssistantMessages: true,
|
|
4925
|
+
thinkingFormat: "deepseek"
|
|
4916
4926
|
},
|
|
4917
4927
|
upstreamModelId: "deepseek-v4.1-flash",
|
|
4918
4928
|
family: "deepseek"
|
|
@@ -14408,20 +14418,23 @@ function buildPatchModelConfig(favorites, aliases, modelMetaFor) {
|
|
|
14408
14418
|
alias: source,
|
|
14409
14419
|
reason: "target-not-favorite"
|
|
14410
14420
|
})));
|
|
14411
|
-
const
|
|
14412
|
-
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
]
|
|
14416
|
-
|
|
14421
|
+
const aliasesByFavorite = /* @__PURE__ */ new Map();
|
|
14422
|
+
for (const alias of normalizedAliases.aliases) {
|
|
14423
|
+
const key = `${alias.providerId}:${alias.modelId}`;
|
|
14424
|
+
if (!favoriteTargets.has(key)) continue;
|
|
14425
|
+
const names = aliasesByFavorite.get(key) ?? [];
|
|
14426
|
+
names.push(alias.name);
|
|
14427
|
+
aliasesByFavorite.set(key, names);
|
|
14428
|
+
}
|
|
14417
14429
|
for (const favorite of favorites) {
|
|
14418
14430
|
const id = stripOneMContextSuffix(httpProxyModelId(favorite.providerId, favorite.modelId));
|
|
14419
14431
|
if (config[id]) continue;
|
|
14420
14432
|
const meta = modelMetaFor(favorite.providerId, favorite.modelId);
|
|
14421
14433
|
const context = meta?.contextWindow;
|
|
14422
|
-
const alias =
|
|
14434
|
+
const [alias, ...moreAliases] = aliasesByFavorite.get(`${favorite.providerId}:${favorite.modelId}`) ?? [];
|
|
14423
14435
|
const entry = {};
|
|
14424
14436
|
if (alias) entry.alias = alias;
|
|
14437
|
+
if (moreAliases.length > 0) entry.moreAliases = moreAliases;
|
|
14425
14438
|
if (context === void 0 || context <= 0) unknownWindows.push(id);
|
|
14426
14439
|
else if (context !== 2e5) entry.context = context;
|
|
14427
14440
|
const display = meta?.displayName?.trim();
|
|
@@ -14461,7 +14474,9 @@ function computePatchConfigHash(config, transformsVersion = PATCH_TRANSFORMS_VER
|
|
|
14461
14474
|
entry.context ?? null,
|
|
14462
14475
|
entry.display ?? null,
|
|
14463
14476
|
entry.effort?.levels ?? null,
|
|
14464
|
-
entry.effort?.defaultLevel ?? null
|
|
14477
|
+
entry.effort?.defaultLevel ?? null,
|
|
14478
|
+
// Appended only when present, so a config with one alias per model keeps its hash.
|
|
14479
|
+
...entry.moreAliases ? [entry.moreAliases] : []
|
|
14465
14480
|
];
|
|
14466
14481
|
});
|
|
14467
14482
|
const payload = [transformsVersion, canonical];
|
|
@@ -14940,7 +14955,7 @@ async function applyPatch(binaryPath, version, desired, configHash, opts) {
|
|
|
14940
14955
|
};
|
|
14941
14956
|
writePatchManifest(manifest);
|
|
14942
14957
|
const modelCount = Object.keys(desired.config).length;
|
|
14943
|
-
const aliasCount = Object.values(desired.config).
|
|
14958
|
+
const aliasCount = Object.values(desired.config).reduce((n, entry) => n + (entry.alias ? 1 : 0) + (entry.moreAliases?.length ?? 0), 0);
|
|
14944
14959
|
const windowCount = Object.values(desired.config).filter((entry) => entry.context).length;
|
|
14945
14960
|
return {
|
|
14946
14961
|
ok: true,
|
|
@@ -15185,14 +15200,14 @@ function effortFor(meta) {
|
|
|
15185
15200
|
...meta.effort ? { providerLevels: meta.effort.levels } : {}
|
|
15186
15201
|
};
|
|
15187
15202
|
}
|
|
15188
|
-
function metadataFor(id, meta,
|
|
15203
|
+
function metadataFor(id, meta, aliases) {
|
|
15189
15204
|
const effective = positive(meta.contextWindow);
|
|
15190
15205
|
const effort = effortFor(meta);
|
|
15191
15206
|
return {
|
|
15192
15207
|
id,
|
|
15193
15208
|
...meta.providerId ? { providerId: meta.providerId } : {},
|
|
15194
15209
|
...meta.modelId ? { modelId: meta.modelId } : {},
|
|
15195
|
-
...
|
|
15210
|
+
...aliases.length > 0 ? { alias: aliases[0], aliases } : {},
|
|
15196
15211
|
...meta.displayName?.trim() ? { displayName: meta.displayName.trim() } : {},
|
|
15197
15212
|
context: {
|
|
15198
15213
|
stop: meta.contextStop ?? "standard",
|
|
@@ -15209,7 +15224,11 @@ function metadataFor(id, meta, alias) {
|
|
|
15209
15224
|
function buildModelMetadata() {
|
|
15210
15225
|
const desired = buildDesiredPatchConfig({ sessionStops: true });
|
|
15211
15226
|
return Object.entries(desired.config).map(
|
|
15212
|
-
([id, entry]) => metadataFor(
|
|
15227
|
+
([id, entry]) => metadataFor(
|
|
15228
|
+
id,
|
|
15229
|
+
desired.metaById[id] ?? {},
|
|
15230
|
+
entry.alias === void 0 ? [] : [entry.alias, ...entry.moreAliases ?? []]
|
|
15231
|
+
)
|
|
15213
15232
|
);
|
|
15214
15233
|
}
|
|
15215
15234
|
function formatModelMetadata(entries) {
|
|
@@ -22641,9 +22660,9 @@ ${pc13.bold("Behavior:")}
|
|
|
22641
22660
|
standard (the provider's tuned default), max (its ceiling), default (clear a
|
|
22642
22661
|
saved choice), or a token count such as 500k. Applies to this run only unless
|
|
22643
22662
|
--save is given. The model is a saved alias or clodex:<provider-id>:<model-id>.
|
|
22644
|
-
--json prints the resolved metadata for saved favorites as JSON: ids,
|
|
22645
|
-
|
|
22646
|
-
levels. Diagnostics go to stderr so stdout stays parseable.
|
|
22663
|
+
--json prints the resolved metadata for saved favorites as JSON: ids, every
|
|
22664
|
+
saved alias, context stop and windows, output limit, pricing boundary, and
|
|
22665
|
+
effort levels. Diagnostics go to stderr so stdout stays parseable.
|
|
22647
22666
|
|
|
22648
22667
|
${pc13.bold("How it works:")}
|
|
22649
22668
|
claude and server use the global favorites list.
|