pennyrouter 0.2.13 → 0.2.14
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/package.json +1 -1
- package/src/launch.js +1 -38
- package/src/launch.test.js +1 -14
package/package.json
CHANGED
package/src/launch.js
CHANGED
|
@@ -257,35 +257,6 @@ export function renderCodexLaunchProfile({ gatewayBaseUrl, subscriptionAuth }) {
|
|
|
257
257
|
].join("\n");
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
/**
|
|
261
|
-
* Per-command settings for `penny codex`.
|
|
262
|
-
*
|
|
263
|
-
* A named Codex profile causes a second configuration/MCP refresh during startup on
|
|
264
|
-
* some Codex builds. Keep the same provider contract, but pass it as CLI overrides
|
|
265
|
-
* so it is part of the initial configuration load instead of a later profile layer.
|
|
266
|
-
* These values deliberately contain no PennyRouter secret: the key remains in the
|
|
267
|
-
* process environment and is read by Codex through env_key/env_http_headers.
|
|
268
|
-
*/
|
|
269
|
-
export function codexLaunchOverrides({ gatewayBaseUrl, subscriptionAuth }) {
|
|
270
|
-
const baseUrl = `${String(gatewayBaseUrl).replace(/\/+$/, "")}/v1`;
|
|
271
|
-
const overrides = [
|
|
272
|
-
'model_provider="pennyrouter"',
|
|
273
|
-
'model_providers.pennyrouter.name="PennyRouter"',
|
|
274
|
-
`model_providers.pennyrouter.base_url=${JSON.stringify(baseUrl)}`,
|
|
275
|
-
'model_providers.pennyrouter.wire_api="responses"',
|
|
276
|
-
'model_providers.pennyrouter.supports_websockets=false',
|
|
277
|
-
];
|
|
278
|
-
if (subscriptionAuth) {
|
|
279
|
-
overrides.push(
|
|
280
|
-
'model_providers.pennyrouter.requires_openai_auth=true',
|
|
281
|
-
'model_providers.pennyrouter.env_http_headers={ "x-pennyrouter-key" = "PENNYROUTER_API_KEY" }',
|
|
282
|
-
);
|
|
283
|
-
} else {
|
|
284
|
-
overrides.push('model_providers.pennyrouter.env_key="PENNYROUTER_API_KEY"');
|
|
285
|
-
}
|
|
286
|
-
return overrides;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
260
|
async function writeClaudeLaunchSettings() {
|
|
290
261
|
const native = (await readJsonFile(join(homeDir(), ".claude", "settings.json"), null)) || {};
|
|
291
262
|
const overlay = { disableClaudeAiConnectors: true };
|
|
@@ -478,15 +449,7 @@ export function buildPennyInvocation(harness, args, config) {
|
|
|
478
449
|
};
|
|
479
450
|
}
|
|
480
451
|
if (harness === "codex") {
|
|
481
|
-
|
|
482
|
-
gatewayBaseUrl: config.gateway_base_url,
|
|
483
|
-
subscriptionAuth: Boolean(item.subscription_auth),
|
|
484
|
-
});
|
|
485
|
-
return {
|
|
486
|
-
command: "codex",
|
|
487
|
-
args: overrides.flatMap((override) => ["-c", override]).concat(args),
|
|
488
|
-
env,
|
|
489
|
-
};
|
|
452
|
+
return { command: "codex", args: ["--profile", "pennyrouter", ...args], env };
|
|
490
453
|
}
|
|
491
454
|
throw new Error(`Unknown Penny harness "${harness}". Try penny claude or penny codex.`);
|
|
492
455
|
}
|
package/src/launch.test.js
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
claudeLaunchSettingsPath,
|
|
9
9
|
claudeUserSkillPath,
|
|
10
10
|
codexLaunchProfilePath,
|
|
11
|
-
codexLaunchOverrides,
|
|
12
11
|
configurePennyHarness,
|
|
13
12
|
fileMode,
|
|
14
13
|
installPennyRuntime,
|
|
@@ -111,16 +110,7 @@ async function main() {
|
|
|
111
110
|
assert.equal(claude.env.CLAUDE_CODE_MAX_CONTEXT_TOKENS, undefined);
|
|
112
111
|
|
|
113
112
|
const codex = buildPennyInvocation("codex", ["resume", "--last"], config);
|
|
114
|
-
assert.deepEqual(codex.args, [
|
|
115
|
-
"-c", 'model_provider="pennyrouter"',
|
|
116
|
-
"-c", 'model_providers.pennyrouter.name="PennyRouter"',
|
|
117
|
-
"-c", 'model_providers.pennyrouter.base_url="https://gateway.example/v1"',
|
|
118
|
-
"-c", 'model_providers.pennyrouter.wire_api="responses"',
|
|
119
|
-
"-c", 'model_providers.pennyrouter.supports_websockets=false',
|
|
120
|
-
"-c", 'model_providers.pennyrouter.requires_openai_auth=true',
|
|
121
|
-
"-c", 'model_providers.pennyrouter.env_http_headers={ "x-pennyrouter-key" = "PENNYROUTER_API_KEY" }',
|
|
122
|
-
"resume", "--last",
|
|
123
|
-
]);
|
|
113
|
+
assert.deepEqual(codex.args, ["--profile", "pennyrouter", "resume", "--last"]);
|
|
124
114
|
assert.equal(codex.env.PENNYROUTER_API_KEY, "pr-super-secret");
|
|
125
115
|
assert.throws(() => buildPennyInvocation("claude", ["--settings=x"], config), /manages --settings/);
|
|
126
116
|
assert.throws(() => buildPennyInvocation("codex", ["-p", "other"], config), /manages --profile/);
|
|
@@ -165,9 +155,6 @@ async function main() {
|
|
|
165
155
|
});
|
|
166
156
|
assert.ok(paid.includes('env_key = "PENNYROUTER_API_KEY"'));
|
|
167
157
|
assert.ok(!paid.includes("requires_openai_auth"));
|
|
168
|
-
assert.deepEqual(codexLaunchOverrides({
|
|
169
|
-
gatewayBaseUrl: "https://gateway.example/", subscriptionAuth: false,
|
|
170
|
-
}).slice(-1), ['model_providers.pennyrouter.env_key="PENNYROUTER_API_KEY"']);
|
|
171
158
|
} finally {
|
|
172
159
|
for (const key of ENV_KEYS) {
|
|
173
160
|
if (previous[key] === undefined) delete process.env[key];
|