topchester-ai 0.52.0 → 0.54.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/dist/bin.mjs +1 -1
- package/dist/{cli-yf0DNAUH.mjs → cli-D1d-I3Fi.mjs} +254 -41
- package/dist/cli-D1d-I3Fi.mjs.map +1 -0
- package/dist/cli.mjs +1 -1
- package/package.json +1 -1
- package/dist/cli-yf0DNAUH.mjs.map +0 -1
package/dist/bin.mjs
CHANGED
|
@@ -127,13 +127,13 @@ function extractAccountIdFromClaims(claims) {
|
|
|
127
127
|
const flatClaim = getStringProperty(claims, "chatgpt_account_id");
|
|
128
128
|
if (flatClaim) return flatClaim;
|
|
129
129
|
const authClaims = claims["https://api.openai.com/auth"];
|
|
130
|
-
if (isPlainObject$
|
|
130
|
+
if (isPlainObject$3(authClaims)) {
|
|
131
131
|
const namespacedClaim = getStringProperty(authClaims, "chatgpt_account_id");
|
|
132
132
|
if (namespacedClaim) return namespacedClaim;
|
|
133
133
|
}
|
|
134
134
|
const organizations = claims.organizations;
|
|
135
135
|
if (Array.isArray(organizations)) {
|
|
136
|
-
const firstOrganization = organizations.find(isPlainObject$
|
|
136
|
+
const firstOrganization = organizations.find(isPlainObject$3);
|
|
137
137
|
const organizationId = firstOrganization ? getStringProperty(firstOrganization, "id") : void 0;
|
|
138
138
|
if (organizationId) return organizationId;
|
|
139
139
|
}
|
|
@@ -143,7 +143,7 @@ function parseJwtClaims(token) {
|
|
|
143
143
|
if (!parts || parts.length !== 3 || !parts[1]) return;
|
|
144
144
|
try {
|
|
145
145
|
const parsed = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
|
|
146
|
-
return isPlainObject$
|
|
146
|
+
return isPlainObject$3(parsed) ? parsed : void 0;
|
|
147
147
|
} catch {
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
@@ -190,7 +190,7 @@ async function readJsonObject(response, label) {
|
|
|
190
190
|
} catch (error) {
|
|
191
191
|
throw new CodexAuthError("invalid_response", `Invalid Codex ${label}: ${formatErrorMessage$4(error)}.`);
|
|
192
192
|
}
|
|
193
|
-
if (!isPlainObject$
|
|
193
|
+
if (!isPlainObject$3(parsed)) throw new CodexAuthError("invalid_response", `Invalid Codex ${label}: expected an object.`);
|
|
194
194
|
return parsed;
|
|
195
195
|
}
|
|
196
196
|
function isPendingDeviceAuthResponse(response) {
|
|
@@ -214,7 +214,7 @@ function optionalPositiveNumber(value) {
|
|
|
214
214
|
const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
|
|
215
215
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
216
216
|
}
|
|
217
|
-
function isPlainObject$
|
|
217
|
+
function isPlainObject$3(value) {
|
|
218
218
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
219
219
|
}
|
|
220
220
|
function formatErrorMessage$4(error) {
|
|
@@ -325,13 +325,13 @@ async function getAuthStoreStatus(options = {}) {
|
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
327
|
function parseAuthStore(path, value) {
|
|
328
|
-
if (!isPlainObject$
|
|
328
|
+
if (!isPlainObject$2(value)) throw new AuthStoreError(path, "<root>: expected an object");
|
|
329
329
|
if (value.version !== 1) throw new AuthStoreError(path, "version: expected 1");
|
|
330
|
-
if (!isPlainObject$
|
|
330
|
+
if (!isPlainObject$2(value.providers)) throw new AuthStoreError(path, "providers: expected an object");
|
|
331
331
|
const providers = {};
|
|
332
332
|
for (const [providerId, providerRecord] of Object.entries(value.providers)) {
|
|
333
333
|
if (!providerId) throw new AuthStoreError(path, "providers: provider id must not be empty");
|
|
334
|
-
if (!isPlainObject$
|
|
334
|
+
if (!isPlainObject$2(providerRecord)) throw new AuthStoreError(path, `providers.${providerId}: expected an object`);
|
|
335
335
|
providers[providerId] = parseProviderRecord(path, providerId, providerRecord);
|
|
336
336
|
}
|
|
337
337
|
return {
|
|
@@ -392,7 +392,7 @@ async function setModeIfSupported(path, mode) {
|
|
|
392
392
|
throw error;
|
|
393
393
|
});
|
|
394
394
|
}
|
|
395
|
-
function isPlainObject$
|
|
395
|
+
function isPlainObject$2(value) {
|
|
396
396
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
397
397
|
}
|
|
398
398
|
function isNodeError$4(error) {
|
|
@@ -5335,6 +5335,7 @@ function createCodexProviderFetch(options = {}) {
|
|
|
5335
5335
|
const providerId = options.providerId ?? "codex";
|
|
5336
5336
|
const upstreamFetch = options.fetch ?? fetch;
|
|
5337
5337
|
return (async (input, init) => {
|
|
5338
|
+
const request = await rewriteCodexRequest(input, init);
|
|
5338
5339
|
const auth = await resolveCodexAuth({
|
|
5339
5340
|
...options,
|
|
5340
5341
|
providerId,
|
|
@@ -5344,10 +5345,13 @@ function createCodexProviderFetch(options = {}) {
|
|
|
5344
5345
|
headers.delete("authorization");
|
|
5345
5346
|
headers.set("Authorization", `Bearer ${auth.accessToken}`);
|
|
5346
5347
|
if (auth.accountId) headers.set("ChatGPT-Account-Id", auth.accountId);
|
|
5347
|
-
|
|
5348
|
-
...init,
|
|
5348
|
+
const response = await upstreamFetch(request.input, {
|
|
5349
|
+
...request.init,
|
|
5349
5350
|
headers
|
|
5350
5351
|
});
|
|
5352
|
+
if (request.responseMode === "chat-json") return codexResponsesSseToChatJson(response);
|
|
5353
|
+
if (request.responseMode === "chat-sse") return codexResponsesSseToChatSse(response);
|
|
5354
|
+
return response;
|
|
5351
5355
|
});
|
|
5352
5356
|
}
|
|
5353
5357
|
function rewriteCodexRequestUrl(input) {
|
|
@@ -5360,6 +5364,193 @@ function rewriteCodexRequestUrl(input) {
|
|
|
5360
5364
|
}
|
|
5361
5365
|
return input;
|
|
5362
5366
|
}
|
|
5367
|
+
async function rewriteCodexRequest(input, init) {
|
|
5368
|
+
const rewrittenUrl = rewriteCodexRequestUrl(input);
|
|
5369
|
+
const body = await readJsonBody(init?.body);
|
|
5370
|
+
if (!isChatCompletionsBody(body)) return {
|
|
5371
|
+
input: rewrittenUrl,
|
|
5372
|
+
...init ? { init } : {}
|
|
5373
|
+
};
|
|
5374
|
+
const stream = body.stream === true;
|
|
5375
|
+
const codexBody = chatCompletionsBodyToCodexResponsesBody(body);
|
|
5376
|
+
const headers = new Headers(init?.headers);
|
|
5377
|
+
headers.set("Content-Type", "application/json");
|
|
5378
|
+
return {
|
|
5379
|
+
input: rewrittenUrl,
|
|
5380
|
+
init: {
|
|
5381
|
+
...init,
|
|
5382
|
+
headers,
|
|
5383
|
+
body: JSON.stringify(codexBody)
|
|
5384
|
+
},
|
|
5385
|
+
responseMode: stream ? "chat-sse" : "chat-json"
|
|
5386
|
+
};
|
|
5387
|
+
}
|
|
5388
|
+
function chatCompletionsBodyToCodexResponsesBody(body) {
|
|
5389
|
+
const instructions = body.messages.filter((message) => message.role === "system" || message.role === "developer").map((message) => messageContentToText(message.content)).filter((text) => text.trim().length > 0).join("\n\n");
|
|
5390
|
+
const input = body.messages.filter((message) => message.role !== "system" && message.role !== "developer").map(chatMessageToResponseInputItem).filter((item) => item !== void 0);
|
|
5391
|
+
return {
|
|
5392
|
+
model: body.model,
|
|
5393
|
+
instructions: instructions || "You are a helpful assistant.",
|
|
5394
|
+
input,
|
|
5395
|
+
store: false,
|
|
5396
|
+
stream: true,
|
|
5397
|
+
...typeof body.temperature === "number" ? { temperature: body.temperature } : {},
|
|
5398
|
+
...typeof body.top_p === "number" ? { top_p: body.top_p } : {},
|
|
5399
|
+
...typeof body.max_tokens === "number" ? { max_output_tokens: body.max_tokens } : {}
|
|
5400
|
+
};
|
|
5401
|
+
}
|
|
5402
|
+
function chatMessageToResponseInputItem(message) {
|
|
5403
|
+
const text = messageContentToText(message.content);
|
|
5404
|
+
if (!text.trim()) return;
|
|
5405
|
+
return {
|
|
5406
|
+
type: "message",
|
|
5407
|
+
role: message.role === "assistant" ? "assistant" : "user",
|
|
5408
|
+
content: [{
|
|
5409
|
+
type: message.role === "assistant" ? "output_text" : "input_text",
|
|
5410
|
+
text
|
|
5411
|
+
}]
|
|
5412
|
+
};
|
|
5413
|
+
}
|
|
5414
|
+
async function codexResponsesSseToChatJson(response) {
|
|
5415
|
+
if (!response.ok) return response;
|
|
5416
|
+
const parsed = parseCodexResponsesSse(await response.text());
|
|
5417
|
+
const headers = new Headers(response.headers);
|
|
5418
|
+
headers.set("Content-Type", "application/json");
|
|
5419
|
+
return new Response(JSON.stringify({
|
|
5420
|
+
id: parsed.id ?? "codex-response",
|
|
5421
|
+
object: "chat.completion",
|
|
5422
|
+
created: parsed.created ?? Math.floor(Date.now() / 1e3),
|
|
5423
|
+
model: parsed.model ?? "codex",
|
|
5424
|
+
choices: [{
|
|
5425
|
+
index: 0,
|
|
5426
|
+
finish_reason: "stop",
|
|
5427
|
+
message: {
|
|
5428
|
+
role: "assistant",
|
|
5429
|
+
content: parsed.text
|
|
5430
|
+
}
|
|
5431
|
+
}],
|
|
5432
|
+
...parsed.usage ? { usage: parsed.usage } : {}
|
|
5433
|
+
}), {
|
|
5434
|
+
status: response.status,
|
|
5435
|
+
statusText: response.statusText,
|
|
5436
|
+
headers
|
|
5437
|
+
});
|
|
5438
|
+
}
|
|
5439
|
+
async function codexResponsesSseToChatSse(response) {
|
|
5440
|
+
if (!response.ok) return response;
|
|
5441
|
+
const parsed = parseCodexResponsesSse(await response.text());
|
|
5442
|
+
const encoder = new TextEncoder();
|
|
5443
|
+
const id = parsed.id ?? "codex-response";
|
|
5444
|
+
const created = parsed.created ?? Math.floor(Date.now() / 1e3);
|
|
5445
|
+
const model = parsed.model ?? "codex";
|
|
5446
|
+
const chunks = [
|
|
5447
|
+
{
|
|
5448
|
+
id,
|
|
5449
|
+
object: "chat.completion.chunk",
|
|
5450
|
+
created,
|
|
5451
|
+
model,
|
|
5452
|
+
choices: [{
|
|
5453
|
+
index: 0,
|
|
5454
|
+
delta: { role: "assistant" },
|
|
5455
|
+
finish_reason: null
|
|
5456
|
+
}]
|
|
5457
|
+
},
|
|
5458
|
+
...(parsed.text.match(/[\s\S]{1,2048}/gu) ?? []).map((delta) => ({
|
|
5459
|
+
id,
|
|
5460
|
+
object: "chat.completion.chunk",
|
|
5461
|
+
created,
|
|
5462
|
+
model,
|
|
5463
|
+
choices: [{
|
|
5464
|
+
index: 0,
|
|
5465
|
+
delta: { content: delta },
|
|
5466
|
+
finish_reason: null
|
|
5467
|
+
}]
|
|
5468
|
+
})),
|
|
5469
|
+
{
|
|
5470
|
+
id,
|
|
5471
|
+
object: "chat.completion.chunk",
|
|
5472
|
+
created,
|
|
5473
|
+
model,
|
|
5474
|
+
choices: [{
|
|
5475
|
+
index: 0,
|
|
5476
|
+
delta: {},
|
|
5477
|
+
finish_reason: "stop"
|
|
5478
|
+
}],
|
|
5479
|
+
...parsed.usage ? { usage: parsed.usage } : {}
|
|
5480
|
+
}
|
|
5481
|
+
];
|
|
5482
|
+
const stream = new ReadableStream({ start(controller) {
|
|
5483
|
+
for (const chunk of chunks) controller.enqueue(encoder.encode(`data: ${JSON.stringify(chunk)}\n\n`));
|
|
5484
|
+
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
5485
|
+
controller.close();
|
|
5486
|
+
} });
|
|
5487
|
+
const headers = new Headers(response.headers);
|
|
5488
|
+
headers.set("Content-Type", "text/event-stream");
|
|
5489
|
+
return new Response(stream, {
|
|
5490
|
+
status: response.status,
|
|
5491
|
+
statusText: response.statusText,
|
|
5492
|
+
headers
|
|
5493
|
+
});
|
|
5494
|
+
}
|
|
5495
|
+
function parseCodexResponsesSse(source) {
|
|
5496
|
+
let text = "";
|
|
5497
|
+
let response;
|
|
5498
|
+
for (const event of source.split(/\n\n/u)) {
|
|
5499
|
+
const dataLines = event.split(/\r?\n/u).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart());
|
|
5500
|
+
if (dataLines.length === 0) continue;
|
|
5501
|
+
const data = dataLines.join("\n");
|
|
5502
|
+
if (data === "[DONE]") continue;
|
|
5503
|
+
const parsed = safeJsonParse(data);
|
|
5504
|
+
if (!isPlainObject$1(parsed)) continue;
|
|
5505
|
+
if (parsed.type === "response.output_text.delta" && typeof parsed.delta === "string") text += parsed.delta;
|
|
5506
|
+
if (parsed.type === "response.completed" && isPlainObject$1(parsed.response)) response = parsed.response;
|
|
5507
|
+
}
|
|
5508
|
+
return {
|
|
5509
|
+
...typeof response?.id === "string" ? { id: response.id } : {},
|
|
5510
|
+
...typeof response?.created_at === "number" ? { created: response.created_at } : {},
|
|
5511
|
+
...typeof response?.model === "string" ? { model: response.model } : {},
|
|
5512
|
+
text,
|
|
5513
|
+
...normalizeCodexUsage(response?.usage)
|
|
5514
|
+
};
|
|
5515
|
+
}
|
|
5516
|
+
function normalizeCodexUsage(usage) {
|
|
5517
|
+
if (!isPlainObject$1(usage)) return {};
|
|
5518
|
+
const promptTokens = typeof usage.input_tokens === "number" ? usage.input_tokens : void 0;
|
|
5519
|
+
const completionTokens = typeof usage.output_tokens === "number" ? usage.output_tokens : void 0;
|
|
5520
|
+
const totalTokens = typeof usage.total_tokens === "number" ? usage.total_tokens : void 0;
|
|
5521
|
+
return { usage: {
|
|
5522
|
+
...promptTokens === void 0 ? {} : { prompt_tokens: promptTokens },
|
|
5523
|
+
...completionTokens === void 0 ? {} : { completion_tokens: completionTokens },
|
|
5524
|
+
...totalTokens === void 0 ? {} : { total_tokens: totalTokens }
|
|
5525
|
+
} };
|
|
5526
|
+
}
|
|
5527
|
+
async function readJsonBody(body) {
|
|
5528
|
+
if (typeof body !== "string") return;
|
|
5529
|
+
return safeJsonParse(body);
|
|
5530
|
+
}
|
|
5531
|
+
function safeJsonParse(source) {
|
|
5532
|
+
try {
|
|
5533
|
+
return JSON.parse(source);
|
|
5534
|
+
} catch {
|
|
5535
|
+
return;
|
|
5536
|
+
}
|
|
5537
|
+
}
|
|
5538
|
+
function isChatCompletionsBody(value) {
|
|
5539
|
+
return isPlainObject$1(value) && typeof value.model === "string" && Array.isArray(value.messages) && value.messages.every((message) => isPlainObject$1(message) && typeof message.role === "string");
|
|
5540
|
+
}
|
|
5541
|
+
function messageContentToText(content) {
|
|
5542
|
+
if (typeof content === "string") return content;
|
|
5543
|
+
if (!Array.isArray(content)) return "";
|
|
5544
|
+
return content.map((part) => {
|
|
5545
|
+
if (!isPlainObject$1(part)) return "";
|
|
5546
|
+
if (typeof part.text === "string") return part.text;
|
|
5547
|
+
if (typeof part.content === "string") return part.content;
|
|
5548
|
+
return "";
|
|
5549
|
+
}).filter(Boolean).join("\n");
|
|
5550
|
+
}
|
|
5551
|
+
function isPlainObject$1(value) {
|
|
5552
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5553
|
+
}
|
|
5363
5554
|
async function resolveCodexAuth(options = {}) {
|
|
5364
5555
|
const providerId = options.providerId ?? "codex";
|
|
5365
5556
|
const record = (await readAuthStore({ path: options.authStorePath })).providers[providerId];
|
|
@@ -5972,8 +6163,7 @@ const rawModelsSchema = z.object({
|
|
|
5972
6163
|
"default": modelRefSchema.optional(),
|
|
5973
6164
|
"fast": modelRefSchema.optional(),
|
|
5974
6165
|
"kb.summarize": modelRefSchema.optional(),
|
|
5975
|
-
"choices": z.array(modelRefSchema).optional()
|
|
5976
|
-
"providers": providersSchema.optional()
|
|
6166
|
+
"choices": z.array(modelRefSchema).optional()
|
|
5977
6167
|
}).strict();
|
|
5978
6168
|
const ignorePathSchema = z.string().min(1).superRefine((value, context) => {
|
|
5979
6169
|
const pattern = value.startsWith("!") ? value.slice(1) : value;
|
|
@@ -6113,9 +6303,9 @@ const topchesterConfigSchema = z.object({
|
|
|
6113
6303
|
models: z.object({
|
|
6114
6304
|
defaultPurpose: modelPurposeSchema.optional(),
|
|
6115
6305
|
assignments: z.partialRecord(modelPurposeSchema, modelAssignmentSchema).optional(),
|
|
6116
|
-
choices: z.array(modelChoiceAssignmentSchema).optional()
|
|
6117
|
-
providers: providersSchema.optional()
|
|
6306
|
+
choices: z.array(modelChoiceAssignmentSchema).optional()
|
|
6118
6307
|
}).strict().optional(),
|
|
6308
|
+
providers: providersSchema.optional(),
|
|
6119
6309
|
ignore: z.object({ paths: z.array(ignorePathSchema).optional() }).optional(),
|
|
6120
6310
|
tools: z.object({ bash: bashPermissionPolicySchema.optional() }).strict().optional(),
|
|
6121
6311
|
mcp: mcpConfigSchema.optional(),
|
|
@@ -6124,6 +6314,7 @@ const topchesterConfigSchema = z.object({
|
|
|
6124
6314
|
});
|
|
6125
6315
|
const rawTopchesterConfigSchema = z.object({
|
|
6126
6316
|
models: rawModelsSchema.optional(),
|
|
6317
|
+
providers: providersSchema.optional(),
|
|
6127
6318
|
ignore: z.object({ paths: z.array(ignorePathSchema).optional() }).optional(),
|
|
6128
6319
|
tools: z.object({ bash: bashPermissionPolicySchema.optional() }).strict().optional(),
|
|
6129
6320
|
mcp: rawMcpConfigSchema.optional(),
|
|
@@ -6197,7 +6388,8 @@ const openRouterProviderDefaults = {
|
|
|
6197
6388
|
};
|
|
6198
6389
|
const codexProviderDefaults = {
|
|
6199
6390
|
type: "openai-compatible",
|
|
6200
|
-
baseURL: CODEX_BACKEND_BASE_URL
|
|
6391
|
+
baseURL: CODEX_BACKEND_BASE_URL,
|
|
6392
|
+
toolProtocol: "text-json"
|
|
6201
6393
|
};
|
|
6202
6394
|
const codexStarterModelChoices = [
|
|
6203
6395
|
"codex/gpt-5.5",
|
|
@@ -6209,7 +6401,7 @@ async function configureOpenRouterGlobalProvider() {
|
|
|
6209
6401
|
const configPath = getGlobalTopchesterConfigPath();
|
|
6210
6402
|
const config = readConfigObject(configPath);
|
|
6211
6403
|
const models = ensurePlainObjectProperty(config, "models");
|
|
6212
|
-
const providers = ensurePlainObjectProperty(
|
|
6404
|
+
const providers = ensurePlainObjectProperty(config, "providers");
|
|
6213
6405
|
providers.default ??= "openrouter";
|
|
6214
6406
|
providers.openrouter = {
|
|
6215
6407
|
...openRouterProviderDefaults,
|
|
@@ -6226,7 +6418,7 @@ async function configureCodexGlobalProvider() {
|
|
|
6226
6418
|
const configPath = getGlobalTopchesterConfigPath();
|
|
6227
6419
|
const config = readConfigObject(configPath);
|
|
6228
6420
|
const models = ensurePlainObjectProperty(config, "models");
|
|
6229
|
-
const providers = ensurePlainObjectProperty(
|
|
6421
|
+
const providers = ensurePlainObjectProperty(config, "providers");
|
|
6230
6422
|
const existingChoices = ensureStringArrayProperty(models, "choices");
|
|
6231
6423
|
const prioritizedChoices = new Set(codexStarterModelChoices);
|
|
6232
6424
|
providers.default ??= "codex";
|
|
@@ -6285,7 +6477,7 @@ function getConfiguredModelChoices(config) {
|
|
|
6285
6477
|
const seen = /* @__PURE__ */ new Set();
|
|
6286
6478
|
const fallbackChoices = [];
|
|
6287
6479
|
for (const assignment of assignments) {
|
|
6288
|
-
const provider = assignment.provider ?? config.
|
|
6480
|
+
const provider = assignment.provider ?? config.providers?.default;
|
|
6289
6481
|
if (typeof provider !== "string") continue;
|
|
6290
6482
|
const choice = {
|
|
6291
6483
|
...assignment,
|
|
@@ -6454,18 +6646,27 @@ function parseConfigFile(path, value) {
|
|
|
6454
6646
|
return parsed.data;
|
|
6455
6647
|
}
|
|
6456
6648
|
function normalizeConfigInput(value) {
|
|
6457
|
-
return normalizeHooksConfigInput(
|
|
6458
|
-
}
|
|
6459
|
-
function
|
|
6460
|
-
if (!isPlainObject(value)
|
|
6649
|
+
return normalizeHooksConfigInput(normalizeModelsAndProvidersConfigInput(value));
|
|
6650
|
+
}
|
|
6651
|
+
function normalizeModelsAndProvidersConfigInput(value) {
|
|
6652
|
+
if (!isPlainObject(value)) return value;
|
|
6653
|
+
const providers = isPlainObject(value.providers) ? { ...value.providers } : {};
|
|
6654
|
+
if (!isPlainObject(value.models)) {
|
|
6655
|
+
if (Object.keys(providers).length === 0) return value;
|
|
6656
|
+
applyKnownProviderDefaults(providers);
|
|
6657
|
+
return {
|
|
6658
|
+
...value,
|
|
6659
|
+
providers
|
|
6660
|
+
};
|
|
6661
|
+
}
|
|
6461
6662
|
const models = { ...value.models };
|
|
6462
|
-
const
|
|
6663
|
+
const knownProviders = getKnownModelProviders(providers);
|
|
6463
6664
|
const assignments = {};
|
|
6464
|
-
const defaultModelRef = normalizeModelRef(models.default, typeof providers.default === "string" ? providers.default : void 0);
|
|
6665
|
+
const defaultModelRef = normalizeModelRef(models.default, typeof providers.default === "string" ? providers.default : void 0, knownProviders);
|
|
6465
6666
|
const defaultProvider = typeof providers.default === "string" ? providers.default : defaultModelRef?.provider;
|
|
6466
|
-
const fastModelRef = normalizeModelRef(models.fast, defaultProvider);
|
|
6467
|
-
const kbSummarizeModelRef = normalizeModelRef(models["kb.summarize"], defaultProvider);
|
|
6468
|
-
const modelChoices = Array.isArray(models.choices) ? models.choices.map((choice) => modelRefToAssignment(normalizeModelRef(choice, void 0) ?? { model: "" })) : void 0;
|
|
6667
|
+
const fastModelRef = normalizeModelRef(models.fast, defaultProvider, knownProviders);
|
|
6668
|
+
const kbSummarizeModelRef = normalizeModelRef(models["kb.summarize"], defaultProvider, knownProviders);
|
|
6669
|
+
const modelChoices = Array.isArray(models.choices) ? models.choices.map((choice) => modelRefToAssignment(normalizeModelRef(choice, void 0, knownProviders) ?? { model: "" })) : void 0;
|
|
6469
6670
|
if (defaultModelRef) {
|
|
6470
6671
|
const assignment = modelRefToAssignment(defaultModelRef);
|
|
6471
6672
|
assignments["agent.primary"] = assignment;
|
|
@@ -6491,9 +6692,9 @@ function normalizeModelsConfigInput(value) {
|
|
|
6491
6692
|
models: {
|
|
6492
6693
|
...models,
|
|
6493
6694
|
assignments,
|
|
6494
|
-
...modelChoices ? { choices: modelChoices } : {}
|
|
6495
|
-
|
|
6496
|
-
}
|
|
6695
|
+
...modelChoices ? { choices: modelChoices } : {}
|
|
6696
|
+
},
|
|
6697
|
+
...Object.keys(providers).length > 0 ? { providers } : {}
|
|
6497
6698
|
};
|
|
6498
6699
|
}
|
|
6499
6700
|
function normalizeHooksConfigInput(value) {
|
|
@@ -6512,8 +6713,8 @@ function normalizeHooksConfigInput(value) {
|
|
|
6512
6713
|
hooks
|
|
6513
6714
|
};
|
|
6514
6715
|
}
|
|
6515
|
-
function normalizeModelRef(ref, defaultProvider) {
|
|
6516
|
-
if (typeof ref === "string") return parseModelRef(ref, defaultProvider);
|
|
6716
|
+
function normalizeModelRef(ref, defaultProvider, knownProviders = getKnownModelProviders()) {
|
|
6717
|
+
if (typeof ref === "string") return parseModelRef(ref, defaultProvider, knownProviders);
|
|
6517
6718
|
if (!isPlainObject(ref) || typeof ref.name !== "string") return;
|
|
6518
6719
|
return {
|
|
6519
6720
|
model: ref.name,
|
|
@@ -6528,7 +6729,12 @@ function modelRefToAssignment(ref) {
|
|
|
6528
6729
|
...ref.toolProtocol ? { toolProtocol: ref.toolProtocol } : {}
|
|
6529
6730
|
};
|
|
6530
6731
|
}
|
|
6531
|
-
function parseModelRef(ref, defaultProvider) {
|
|
6732
|
+
function parseModelRef(ref, defaultProvider, knownProviders) {
|
|
6733
|
+
const [explicitProvider, ...explicitModelParts] = ref.split("/");
|
|
6734
|
+
if (explicitProvider && explicitModelParts.length > 0 && knownProviders.has(explicitProvider)) return {
|
|
6735
|
+
provider: explicitProvider,
|
|
6736
|
+
model: explicitModelParts.join("/")
|
|
6737
|
+
};
|
|
6532
6738
|
if (defaultProvider) {
|
|
6533
6739
|
const providerPrefix = `${defaultProvider}/`;
|
|
6534
6740
|
return ref.startsWith(providerPrefix) ? {
|
|
@@ -6546,6 +6752,13 @@ function parseModelRef(ref, defaultProvider) {
|
|
|
6546
6752
|
};
|
|
6547
6753
|
return { model: ref };
|
|
6548
6754
|
}
|
|
6755
|
+
function getKnownModelProviders(providers = {}) {
|
|
6756
|
+
return new Set([
|
|
6757
|
+
"openrouter",
|
|
6758
|
+
"codex",
|
|
6759
|
+
...Object.keys(providers).filter((provider) => provider !== "default")
|
|
6760
|
+
]);
|
|
6761
|
+
}
|
|
6549
6762
|
function ensureKnownProvider(providers, provider) {
|
|
6550
6763
|
if (provider === "openrouter" && providers.openrouter === void 0) {
|
|
6551
6764
|
providers.openrouter = { ...openRouterProviderDefaults };
|
|
@@ -6681,7 +6894,7 @@ function createModelGatewayFromConfig(config) {
|
|
|
6681
6894
|
return new ModelGateway(normalizeModelGatewayConfig(config));
|
|
6682
6895
|
}
|
|
6683
6896
|
function normalizeModelGatewayConfig(config) {
|
|
6684
|
-
const { default: defaultProvider, ...namedProviders } = config.
|
|
6897
|
+
const { default: defaultProvider, ...namedProviders } = config.providers ?? {};
|
|
6685
6898
|
return {
|
|
6686
6899
|
defaultPurpose: config.models?.defaultPurpose ?? "agent.primary",
|
|
6687
6900
|
models: config.models?.assignments ?? {},
|
|
@@ -10070,7 +10283,7 @@ var PromptHistory = class {
|
|
|
10070
10283
|
const STARTUP_PROMPT_HINT = "Prompt hint: Enter sends, Shift+Enter adds a line, / opens commands, ↑↓ browse history.";
|
|
10071
10284
|
function getStartupThreadMessages(context) {
|
|
10072
10285
|
const assignments = context.config.models?.assignments ?? {};
|
|
10073
|
-
const providers = context.config.
|
|
10286
|
+
const providers = context.config.providers ?? {};
|
|
10074
10287
|
const banner = getRandomAsciiBanner();
|
|
10075
10288
|
const lines = banner ? [
|
|
10076
10289
|
"",
|
|
@@ -10107,7 +10320,7 @@ function getStartupThreadMessages(context) {
|
|
|
10107
10320
|
}
|
|
10108
10321
|
function getModelSetupHint(context) {
|
|
10109
10322
|
const assignments = context.config.models?.assignments ?? {};
|
|
10110
|
-
const providers = context.config.
|
|
10323
|
+
const providers = context.config.providers ?? {};
|
|
10111
10324
|
const hasAssignments = Object.keys(assignments).length > 0;
|
|
10112
10325
|
const hasProviders = Object.entries(providers).some(([providerId]) => providerId !== "default");
|
|
10113
10326
|
if (hasAssignments && hasProviders) return;
|
|
@@ -10177,7 +10390,7 @@ function getModelLabel(context) {
|
|
|
10177
10390
|
const purpose = context.config.models?.defaultPurpose ?? "agent.primary";
|
|
10178
10391
|
const model = context.config.models?.assignments?.[purpose] ?? context.config.models?.assignments?.fallback;
|
|
10179
10392
|
if (!model) return "not set";
|
|
10180
|
-
const provider = model.provider ?? context.config.
|
|
10393
|
+
const provider = model.provider ?? context.config.providers?.default;
|
|
10181
10394
|
return typeof provider === "string" ? `${model.name} [${provider}]` : model.name;
|
|
10182
10395
|
}
|
|
10183
10396
|
//#endregion
|
|
@@ -15199,7 +15412,7 @@ function formatModelHints(config) {
|
|
|
15199
15412
|
];
|
|
15200
15413
|
}
|
|
15201
15414
|
function formatProviderHints(config, authStoreStatus) {
|
|
15202
|
-
const providers = config.
|
|
15415
|
+
const providers = config.providers ?? {};
|
|
15203
15416
|
const namedProviders = Object.entries(providers).filter(([providerId]) => providerId !== "default");
|
|
15204
15417
|
if (namedProviders.length === 0) return [section("providers"), row("configured", status("none", "muted"))];
|
|
15205
15418
|
const lines = [section("providers")];
|
|
@@ -15446,7 +15659,7 @@ function createTopchesterProgram() {
|
|
|
15446
15659
|
}
|
|
15447
15660
|
function printStartupSummary(context) {
|
|
15448
15661
|
const assignments = context.config.models?.assignments ?? {};
|
|
15449
|
-
const providers = context.config.
|
|
15662
|
+
const providers = context.config.providers ?? {};
|
|
15450
15663
|
console.log(`workspace: ${context.workspaceRoot}`);
|
|
15451
15664
|
console.log(`default model purpose: ${context.config.models?.defaultPurpose ?? "agent.primary"}`);
|
|
15452
15665
|
if (context.devFlags.size > 0) console.log(`dev flags: ${[...context.devFlags].join(", ")}`);
|
|
@@ -15629,4 +15842,4 @@ function formatDryRunSyncStatus(status) {
|
|
|
15629
15842
|
//#endregion
|
|
15630
15843
|
export { runTopchesterCli as t };
|
|
15631
15844
|
|
|
15632
|
-
//# sourceMappingURL=cli-
|
|
15845
|
+
//# sourceMappingURL=cli-D1d-I3Fi.mjs.map
|