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 CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as runTopchesterCli } from "./cli-yf0DNAUH.mjs";
2
+ import { t as runTopchesterCli } from "./cli-D1d-I3Fi.mjs";
3
3
  //#region src/bin.ts
4
4
  await runTopchesterCli();
5
5
  //#endregion
@@ -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$2(authClaims)) {
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$2);
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$2(parsed) ? parsed : void 0;
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$2(parsed)) throw new CodexAuthError("invalid_response", `Invalid Codex ${label}: expected an object.`);
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$2(value) {
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$1(value)) throw new AuthStoreError(path, "<root>: expected an object");
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$1(value.providers)) throw new AuthStoreError(path, "providers: expected an object");
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$1(providerRecord)) throw new AuthStoreError(path, `providers.${providerId}: expected an object`);
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$1(value) {
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
- return upstreamFetch(rewriteCodexRequestUrl(input), {
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(models, "providers");
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(models, "providers");
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.models?.providers?.default;
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(normalizeModelsConfigInput(value));
6458
- }
6459
- function normalizeModelsConfigInput(value) {
6460
- if (!isPlainObject(value) || !isPlainObject(value.models)) return 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 providers = isPlainObject(models.providers) ? { ...models.providers } : {};
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
- providers
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.models?.providers ?? {};
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.models?.providers ?? {};
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.models?.providers ?? {};
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.models?.providers?.default;
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.models?.providers ?? {};
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.models?.providers ?? {};
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-yf0DNAUH.mjs.map
15845
+ //# sourceMappingURL=cli-D1d-I3Fi.mjs.map