bingocode 1.0.25 → 1.0.27
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
CHANGED
|
@@ -263,6 +263,103 @@ export class ProviderService {
|
|
|
263
263
|
await this.writeSettings(settings)
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Sync settings.json based on the current slot table.
|
|
268
|
+
*
|
|
269
|
+
* Examines all configured slots to determine whether the CLI should connect
|
|
270
|
+
* through the local proxy or directly. If ANY slot uses a non-anthropic format
|
|
271
|
+
* (openai_chat, openai_responses), the proxy is required and settings.json is
|
|
272
|
+
* written with:
|
|
273
|
+
* - ANTHROPIC_BASE_URL → http://127.0.0.1:{port}/proxy
|
|
274
|
+
* - ANTHROPIC_AUTH_TOKEN → "proxy-managed"
|
|
275
|
+
*
|
|
276
|
+
* Model env vars (ANTHROPIC_MODEL, ANTHROPIC_DEFAULT_*_MODEL) are populated
|
|
277
|
+
* from the slot table so the CLI requests the correct model names, which the
|
|
278
|
+
* proxy's identifySlot() then routes to the right provider.
|
|
279
|
+
*
|
|
280
|
+
* If ALL configured slots use native anthropic format, we write the main
|
|
281
|
+
* slot's provider info directly (no proxy needed).
|
|
282
|
+
*
|
|
283
|
+
* If no slots are configured at all, settings.json is left unchanged.
|
|
284
|
+
*/
|
|
285
|
+
private async syncSettingsForSlots(slots: SlotTable): Promise<void> {
|
|
286
|
+
const index = await this.readIndex()
|
|
287
|
+
|
|
288
|
+
// Collect resolved slot info
|
|
289
|
+
type ResolvedSlot = { slot: SlotName; provider: SavedProvider; modelId: string; label?: string | null }
|
|
290
|
+
const resolved: ResolvedSlot[] = []
|
|
291
|
+
for (const slotName of ['main', 'haiku', 'sonnet', 'opus'] as const) {
|
|
292
|
+
const entry = slots[slotName]
|
|
293
|
+
if (!entry) continue
|
|
294
|
+
const provider = index.providers.find((p) => p.id === entry.providerId)
|
|
295
|
+
if (!provider) continue
|
|
296
|
+
resolved.push({ slot: slotName, provider, modelId: entry.modelId, label: entry.label })
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// No slots configured at all — don't touch settings.json
|
|
300
|
+
if (resolved.length === 0) return
|
|
301
|
+
|
|
302
|
+
const needsProxy = resolved.some(
|
|
303
|
+
(r) => r.provider.apiFormat != null && r.provider.apiFormat !== 'anthropic',
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
const settings = await this.readSettings()
|
|
307
|
+
const existingEnv = (settings.env as Record<string, string>) || {}
|
|
308
|
+
|
|
309
|
+
// Build model env vars from slot table.
|
|
310
|
+
//
|
|
311
|
+
// The proxy's identifySlot() routes requests by looking for keywords
|
|
312
|
+
// (haiku/sonnet/opus) in the model name the CLI sends. If the actual
|
|
313
|
+
// model ID (e.g., "deepseek-chat") doesn't contain the keyword, the
|
|
314
|
+
// proxy would misroute to "main". To fix this, we ensure the env var
|
|
315
|
+
// value always contains the slot keyword so identifySlot() can match.
|
|
316
|
+
const modelEnv: Record<string, string> = {}
|
|
317
|
+
for (const r of resolved) {
|
|
318
|
+
const rawName = r.label || r.modelId
|
|
319
|
+
switch (r.slot) {
|
|
320
|
+
case 'main':
|
|
321
|
+
modelEnv.ANTHROPIC_MODEL = rawName
|
|
322
|
+
break
|
|
323
|
+
case 'haiku': {
|
|
324
|
+
// Ensure the value contains "haiku" for identifySlot() routing
|
|
325
|
+
const name = /haiku/i.test(rawName) ? rawName : `${rawName}-haiku`
|
|
326
|
+
modelEnv.ANTHROPIC_DEFAULT_HAIKU_MODEL = name
|
|
327
|
+
break
|
|
328
|
+
}
|
|
329
|
+
case 'sonnet': {
|
|
330
|
+
const name = /sonnet/i.test(rawName) ? rawName : `${rawName}-sonnet`
|
|
331
|
+
modelEnv.ANTHROPIC_DEFAULT_SONNET_MODEL = name
|
|
332
|
+
break
|
|
333
|
+
}
|
|
334
|
+
case 'opus': {
|
|
335
|
+
const name = /opus/i.test(rawName) ? rawName : `${rawName}-opus`
|
|
336
|
+
modelEnv.ANTHROPIC_DEFAULT_OPUS_MODEL = name
|
|
337
|
+
break
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (needsProxy) {
|
|
343
|
+
settings.env = {
|
|
344
|
+
...existingEnv,
|
|
345
|
+
ANTHROPIC_BASE_URL: `http://127.0.0.1:${ProviderService.serverPort}/proxy`,
|
|
346
|
+
ANTHROPIC_AUTH_TOKEN: 'proxy-managed',
|
|
347
|
+
...modelEnv,
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
// All slots are native anthropic — use main slot's provider directly
|
|
351
|
+
const mainSlot = resolved.find((r) => r.slot === 'main') || resolved[0]
|
|
352
|
+
settings.env = {
|
|
353
|
+
...existingEnv,
|
|
354
|
+
ANTHROPIC_BASE_URL: mainSlot.provider.baseUrl,
|
|
355
|
+
ANTHROPIC_AUTH_TOKEN: mainSlot.provider.apiKey,
|
|
356
|
+
...modelEnv,
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
await this.writeSettings(settings)
|
|
361
|
+
}
|
|
362
|
+
|
|
266
363
|
// --- Auth status ---
|
|
267
364
|
|
|
268
365
|
/**
|
|
@@ -356,6 +453,13 @@ export class ProviderService {
|
|
|
356
453
|
const slots = await this.readSlots()
|
|
357
454
|
slots[slot] = entry
|
|
358
455
|
await this.writeSlots(slots)
|
|
456
|
+
|
|
457
|
+
// Auto-sync settings.json so the CLI knows where to connect.
|
|
458
|
+
// When any slot uses a non-anthropic provider, the CLI must go through
|
|
459
|
+
// the local proxy; when all slots are anthropic (or empty), we can
|
|
460
|
+
// write direct provider info instead.
|
|
461
|
+
await this.syncSettingsForSlots(slots)
|
|
462
|
+
|
|
359
463
|
return slots
|
|
360
464
|
}
|
|
361
465
|
|