@lunaroute/cli 0.3.0 → 0.3.1
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/dist/index.js +38 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Command, InvalidArgumentError, Option } from "commander";
|
|
5
5
|
|
|
6
6
|
// package.json
|
|
7
|
-
var version = "0.3.
|
|
7
|
+
var version = "0.3.1";
|
|
8
8
|
|
|
9
9
|
// src/login.ts
|
|
10
10
|
import { createServer } from "http";
|
|
@@ -372,10 +372,10 @@ function isChatModel(m) {
|
|
|
372
372
|
}
|
|
373
373
|
return true;
|
|
374
374
|
}
|
|
375
|
-
async function fetchModels(routingUrl, key) {
|
|
375
|
+
async function fetchModels(routingUrl, key, opts) {
|
|
376
376
|
const url = `${routingUrl}/v1/models`;
|
|
377
377
|
const headers = key ? { Authorization: `Bearer ${key}` } : {};
|
|
378
|
-
const res = await fetch(url, { method: "GET", headers });
|
|
378
|
+
const res = await fetch(url, { method: "GET", headers, signal: opts?.signal });
|
|
379
379
|
if (!res.ok) {
|
|
380
380
|
if (res.status === 401) {
|
|
381
381
|
throw new KeyRejectedError(
|
|
@@ -916,24 +916,28 @@ function validatedRoutingUrl(routingUrl) {
|
|
|
916
916
|
function buildPlan4(ctx) {
|
|
917
917
|
const base = validatedRoutingUrl(ctx.routingUrl);
|
|
918
918
|
const model = ctx.models[0]?.id ?? "<model>";
|
|
919
|
-
const
|
|
920
|
-
|
|
921
|
-
|
|
919
|
+
const contextWindow = ctx.models[0]?.context_window_tokens;
|
|
920
|
+
const lines = [`model = "${model}"`, 'model_provider = "lunaroute"'];
|
|
921
|
+
if (Number.isInteger(contextWindow) && (contextWindow ?? 0) > 0) {
|
|
922
|
+
lines.push(`model_context_window = ${contextWindow}`);
|
|
923
|
+
}
|
|
924
|
+
const content = lines.concat([
|
|
922
925
|
"",
|
|
923
926
|
"[model_providers.lunaroute]",
|
|
924
927
|
'name = "LunaRoute"',
|
|
925
928
|
`base_url = "${base}/v1"`,
|
|
926
929
|
'env_key = "LUNAROUTE_API_KEY"',
|
|
927
930
|
'wire_api = "responses"'
|
|
928
|
-
].join("\n") + "\n";
|
|
931
|
+
]).join("\n") + "\n";
|
|
929
932
|
return {
|
|
930
933
|
fileWrites: [{ kind: "text", path: codexProfilePath(), content }],
|
|
931
934
|
exports: [{ name: ctx.keyEnvVar, value: "__KEY__" }],
|
|
932
935
|
notes: [
|
|
933
936
|
"\nCodex: add the export above to your shell profile, then start Codex with `codex --profile lunaroute`.",
|
|
934
|
-
`Change model to any of: ${ctx.models.map((m) => m.id).join(", ")}, or pass \`--model <id>\` for one session.`,
|
|
937
|
+
`Change model to any of: ${ctx.models.map((m) => m.id).join(", ")}, or pass \`--model <id>\` for one session. If you change model, update or remove model_context_window to match.`,
|
|
935
938
|
"The key rides the Authorization: Bearer header via env_key; LunaRoute authenticates the lr_ key at the edge and never forwards it upstream.",
|
|
936
|
-
"One file: the model and the named provider live in the profile file \u2014 your ~/.codex/config.toml is untouched."
|
|
939
|
+
"One file: the model and the named provider live in the profile file \u2014 your ~/.codex/config.toml is untouched.",
|
|
940
|
+
"Codex logs a `Model metadata ... fallback metadata` warning for LunaRoute models (its /v1/models catalog shape differs); it is expected and harmless \u2014 model_context_window pins the real window above."
|
|
937
941
|
]
|
|
938
942
|
};
|
|
939
943
|
}
|
|
@@ -2106,16 +2110,20 @@ function buildRunSpec(ctx) {
|
|
|
2106
2110
|
// src/run/adapters/codex.ts
|
|
2107
2111
|
function buildRunSpec2(ctx) {
|
|
2108
2112
|
const provider = `{name="LunaRoute",base_url="${ctx.routingUrl}/v1",env_key="LUNAROUTE_API_KEY",wire_api="responses"}`;
|
|
2113
|
+
const args = [
|
|
2114
|
+
"-c",
|
|
2115
|
+
'model_provider="lunaroute"',
|
|
2116
|
+
"-c",
|
|
2117
|
+
`model_providers.lunaroute=${provider}`,
|
|
2118
|
+
"-c",
|
|
2119
|
+
`model="${ctx.model}"`
|
|
2120
|
+
];
|
|
2121
|
+
if (Number.isInteger(ctx.contextWindow) && (ctx.contextWindow ?? 0) > 0) {
|
|
2122
|
+
args.push("-c", `model_context_window=${ctx.contextWindow}`);
|
|
2123
|
+
}
|
|
2109
2124
|
return {
|
|
2110
2125
|
command: "codex",
|
|
2111
|
-
args
|
|
2112
|
-
"-c",
|
|
2113
|
-
'model_provider="lunaroute"',
|
|
2114
|
-
"-c",
|
|
2115
|
-
`model_providers.lunaroute=${provider}`,
|
|
2116
|
-
"-c",
|
|
2117
|
-
`model="${ctx.model}"`
|
|
2118
|
-
],
|
|
2126
|
+
args,
|
|
2119
2127
|
env: {
|
|
2120
2128
|
LUNAROUTE_API_KEY: ctx.apiKey
|
|
2121
2129
|
}
|
|
@@ -2128,6 +2136,7 @@ var ADAPTERS2 = {
|
|
|
2128
2136
|
"claude-code": buildRunSpec,
|
|
2129
2137
|
codex: buildRunSpec2
|
|
2130
2138
|
};
|
|
2139
|
+
var MODEL_LOOKUP_TIMEOUT_MS = 3e3;
|
|
2131
2140
|
var INSTALL_HINT = {
|
|
2132
2141
|
claude: "Install Claude Code: https://docs.anthropic.com/claude-code/install",
|
|
2133
2142
|
"claude-code": "Install Claude Code: https://docs.anthropic.com/claude-code/install",
|
|
@@ -2149,8 +2158,8 @@ async function runRun(harness, opts, deps = realDeps) {
|
|
|
2149
2158
|
return 1;
|
|
2150
2159
|
}
|
|
2151
2160
|
let model = opts.model;
|
|
2161
|
+
let models = [];
|
|
2152
2162
|
if (!model) {
|
|
2153
|
-
let models;
|
|
2154
2163
|
try {
|
|
2155
2164
|
models = await deps.fetchModels(creds.routing_url, creds.routing_key);
|
|
2156
2165
|
} catch (err) {
|
|
@@ -2163,11 +2172,21 @@ async function runRun(harness, opts, deps = realDeps) {
|
|
|
2163
2172
|
return 1;
|
|
2164
2173
|
}
|
|
2165
2174
|
console.error(`# using model ${model} (pass --model to change)`);
|
|
2175
|
+
} else if (harness === "codex") {
|
|
2176
|
+
try {
|
|
2177
|
+
models = await deps.fetchModels(creds.routing_url, creds.routing_key, {
|
|
2178
|
+
signal: AbortSignal.timeout(MODEL_LOOKUP_TIMEOUT_MS)
|
|
2179
|
+
});
|
|
2180
|
+
} catch {
|
|
2181
|
+
models = [];
|
|
2182
|
+
}
|
|
2166
2183
|
}
|
|
2184
|
+
const contextWindow = models.find((m) => m.id === model)?.context_window_tokens;
|
|
2167
2185
|
const spec = adapter({
|
|
2168
2186
|
routingUrl: creds.routing_url,
|
|
2169
2187
|
apiKey: creds.routing_key,
|
|
2170
|
-
model
|
|
2188
|
+
model,
|
|
2189
|
+
contextWindow
|
|
2171
2190
|
});
|
|
2172
2191
|
const args = spec.args.concat(opts.passthrough ?? []);
|
|
2173
2192
|
const env = { ...process.env, ...spec.env };
|