@albinocrabs/o-switcher 0.1.0 → 0.2.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.
@@ -1,3 +1,14 @@
1
+ import { z } from 'zod';
2
+ import pino from 'pino';
3
+ import crypto from 'crypto';
4
+ import { EventEmitter } from 'eventemitter3';
5
+ import { CircuitState, ConsecutiveBreaker, CountBreaker, BrokenCircuitError, IsolatedCircuitError, circuitBreaker, handleAll } from 'cockatiel';
6
+ import PQueue from 'p-queue';
7
+ import { tool } from '@opencode-ai/plugin/tool';
8
+ import { readFile, mkdir, writeFile, rename, watch } from 'fs/promises';
9
+ import { homedir } from 'os';
10
+ import { join, dirname } from 'path';
11
+
1
12
  // src/config/defaults.ts
2
13
  var DEFAULT_RETRY_BUDGET = 3;
3
14
  var DEFAULT_FAILOVER_BUDGET = 2;
@@ -21,9 +32,6 @@ var DEFAULT_CB_HALF_OPEN_MAX_PROBES = 1;
21
32
  var DEFAULT_CB_SUCCESS_THRESHOLD = 2;
22
33
  var DEFAULT_RETRY = 3;
23
34
  var DEFAULT_TIMEOUT_MS = 3e4;
24
-
25
- // src/config/schema.ts
26
- import { z } from "zod";
27
35
  var BackoffConfigSchema = z.object({
28
36
  base_ms: z.number().positive().default(DEFAULT_BACKOFF_BASE_MS),
29
37
  multiplier: z.number().positive().default(DEFAULT_BACKOFF_MULTIPLIER),
@@ -133,13 +141,11 @@ var validateConfig = (raw) => {
133
141
  }
134
142
  return Object.freeze(data);
135
143
  }
136
- const diagnostics = result.error.issues.map(
137
- (issue) => ({
138
- path: issue.path.join("."),
139
- message: issue.message,
140
- received: "expected" in issue ? issue.expected : void 0
141
- })
142
- );
144
+ const diagnostics = result.error.issues.map((issue) => ({
145
+ path: issue.path.join("."),
146
+ message: issue.message,
147
+ received: "expected" in issue ? issue.expected : void 0
148
+ }));
143
149
  throw new ConfigValidationError(diagnostics);
144
150
  };
145
151
 
@@ -240,10 +246,7 @@ var TargetRegistry = class {
240
246
  if (!target) {
241
247
  return;
242
248
  }
243
- const newHealthScore = updateHealthScore(
244
- target.health_score,
245
- observation
246
- );
249
+ const newHealthScore = updateHealthScore(target.health_score, observation);
247
250
  this.targets.set(id, { ...target, health_score: newHealthScore });
248
251
  }
249
252
  /** Sets the cooldown_until timestamp for a target. */
@@ -302,10 +305,6 @@ var TARGET_STATES = [
302
305
  "Draining",
303
306
  "Disabled"
304
307
  ];
305
-
306
- // src/audit/logger.ts
307
- import pino from "pino";
308
- import crypto from "crypto";
309
308
  var REDACT_PATHS = [
310
309
  "api_key",
311
310
  "token",
@@ -337,57 +336,54 @@ var createAuditLogger = (options) => {
337
336
  };
338
337
  var createRequestLogger = (baseLogger, requestId) => baseLogger.child({ request_id: requestId });
339
338
  var generateCorrelationId = () => crypto.randomUUID();
340
-
341
- // src/errors/taxonomy.ts
342
- import { z as z2 } from "zod";
343
- var RateLimitedSchema = z2.object({
344
- class: z2.literal("RateLimited"),
345
- retryable: z2.literal(true),
346
- retry_after_ms: z2.number().optional(),
347
- provider_reason: z2.string().optional()
339
+ var RateLimitedSchema = z.object({
340
+ class: z.literal("RateLimited"),
341
+ retryable: z.literal(true),
342
+ retry_after_ms: z.number().optional(),
343
+ provider_reason: z.string().optional()
348
344
  });
349
- var QuotaExhaustedSchema = z2.object({
350
- class: z2.literal("QuotaExhausted"),
351
- retryable: z2.literal(false),
352
- provider_reason: z2.string().optional()
345
+ var QuotaExhaustedSchema = z.object({
346
+ class: z.literal("QuotaExhausted"),
347
+ retryable: z.literal(false),
348
+ provider_reason: z.string().optional()
353
349
  });
354
- var AuthFailureSchema = z2.object({
355
- class: z2.literal("AuthFailure"),
356
- retryable: z2.literal(false),
357
- recovery_attempted: z2.boolean().default(false)
350
+ var AuthFailureSchema = z.object({
351
+ class: z.literal("AuthFailure"),
352
+ retryable: z.literal(false),
353
+ recovery_attempted: z.boolean().default(false)
358
354
  });
359
- var PermissionFailureSchema = z2.object({
360
- class: z2.literal("PermissionFailure"),
361
- retryable: z2.literal(false)
355
+ var PermissionFailureSchema = z.object({
356
+ class: z.literal("PermissionFailure"),
357
+ retryable: z.literal(false)
362
358
  });
363
- var PolicyFailureSchema = z2.object({
364
- class: z2.literal("PolicyFailure"),
365
- retryable: z2.literal(false)
359
+ var PolicyFailureSchema = z.object({
360
+ class: z.literal("PolicyFailure"),
361
+ retryable: z.literal(false)
366
362
  });
367
- var RegionRestrictionSchema = z2.object({
368
- class: z2.literal("RegionRestriction"),
369
- retryable: z2.literal(false)
363
+ var RegionRestrictionSchema = z.object({
364
+ class: z.literal("RegionRestriction"),
365
+ retryable: z.literal(false)
370
366
  });
371
- var ModelUnavailableSchema = z2.object({
372
- class: z2.literal("ModelUnavailable"),
373
- retryable: z2.literal(false),
374
- failover_eligible: z2.literal(true)
367
+ var ModelUnavailableSchema = z.object({
368
+ class: z.literal("ModelUnavailable"),
369
+ retryable: z.literal(false),
370
+ failover_eligible: z.literal(true)
375
371
  });
376
- var TransientServerFailureSchema = z2.object({
377
- class: z2.literal("TransientServerFailure"),
378
- retryable: z2.literal(true),
379
- http_status: z2.number().optional()
372
+ var TransientServerFailureSchema = z.object({
373
+ class: z.literal("TransientServerFailure"),
374
+ retryable: z.literal(true),
375
+ http_status: z.number().optional()
380
376
  });
381
- var TransportFailureSchema = z2.object({
382
- class: z2.literal("TransportFailure"),
383
- retryable: z2.literal(true)
377
+ var TransportFailureSchema = z.object({
378
+ class: z.literal("TransportFailure"),
379
+ retryable: z.literal(true)
384
380
  });
385
- var InterruptedExecutionSchema = z2.object({
386
- class: z2.literal("InterruptedExecution"),
387
- retryable: z2.literal(true),
388
- partial_output_bytes: z2.number().optional()
381
+ var InterruptedExecutionSchema = z.object({
382
+ class: z.literal("InterruptedExecution"),
383
+ retryable: z.literal(true),
384
+ partial_output_bytes: z.number().optional()
389
385
  });
390
- var ErrorClassSchema = z2.discriminatedUnion("class", [
386
+ var ErrorClassSchema = z.discriminatedUnion("class", [
391
387
  RateLimitedSchema,
392
388
  QuotaExhaustedSchema,
393
389
  AuthFailureSchema,
@@ -433,10 +429,7 @@ var DEFAULT_BACKOFF_PARAMS = {
433
429
  jitter: "full"
434
430
  };
435
431
  var computeBackoffMs = (attempt, params, retryAfterMs) => {
436
- const rawDelay = Math.min(
437
- params.base_ms * Math.pow(params.multiplier, attempt),
438
- params.max_ms
439
- );
432
+ const rawDelay = Math.min(params.base_ms * Math.pow(params.multiplier, attempt), params.max_ms);
440
433
  const jitteredDelay = params.jitter === "full" ? Math.random() * rawDelay : params.jitter === "equal" ? rawDelay / 2 + Math.random() * (rawDelay / 2) : rawDelay;
441
434
  return Math.max(jitteredDelay, retryAfterMs ?? 0);
442
435
  };
@@ -480,22 +473,8 @@ var EXCLUSION_REASONS = [
480
473
  "capability_mismatch",
481
474
  "draining"
482
475
  ];
483
- var ADMISSION_RESULTS = [
484
- "admitted",
485
- "queued",
486
- "degraded",
487
- "rejected"
488
- ];
489
-
490
- // src/routing/events.ts
491
- import { EventEmitter } from "eventemitter3";
476
+ var ADMISSION_RESULTS = ["admitted", "queued", "degraded", "rejected"];
492
477
  var createRoutingEventBus = () => new EventEmitter();
493
-
494
- // src/routing/dual-breaker.ts
495
- import {
496
- ConsecutiveBreaker,
497
- CountBreaker
498
- } from "cockatiel";
499
478
  var DualBreaker = class {
500
479
  consecutive;
501
480
  count;
@@ -537,21 +516,11 @@ var DualBreaker = class {
537
516
  return consecutiveTripped || countTripped;
538
517
  }
539
518
  };
540
-
541
- // src/routing/circuit-breaker.ts
542
- import {
543
- CircuitState as CircuitState2,
544
- handleAll,
545
- circuitBreaker,
546
- BrokenCircuitError,
547
- IsolatedCircuitError
548
- } from "cockatiel";
549
- import "eventemitter3";
550
519
  var COCKATIEL_TO_TARGET = /* @__PURE__ */ new Map([
551
- [CircuitState2.Closed, "Active"],
552
- [CircuitState2.Open, "CircuitOpen"],
553
- [CircuitState2.HalfOpen, "CircuitHalfOpen"],
554
- [CircuitState2.Isolated, "Disabled"]
520
+ [CircuitState.Closed, "Active"],
521
+ [CircuitState.Open, "CircuitOpen"],
522
+ [CircuitState.HalfOpen, "CircuitHalfOpen"],
523
+ [CircuitState.Isolated, "Disabled"]
555
524
  ]);
556
525
  var toTargetState = (state) => COCKATIEL_TO_TARGET.get(state) ?? "Disabled";
557
526
  var createCircuitBreaker = (targetId, config, eventBus) => {
@@ -567,11 +536,11 @@ var createCircuitBreaker = (targetId, config, eventBus) => {
567
536
  return { policy, breaker };
568
537
  };
569
538
  let current = createPolicy();
570
- let previousState = CircuitState2.Closed;
539
+ let previousState = CircuitState.Closed;
571
540
  let openedAtMs = 0;
572
541
  const subscribeEvents = (policy) => {
573
542
  policy.onStateChange((newState) => {
574
- if (newState === CircuitState2.Open) {
543
+ if (newState === CircuitState.Open) {
575
544
  openedAtMs = Date.now();
576
545
  }
577
546
  const from = toTargetState(previousState);
@@ -590,8 +559,8 @@ var createCircuitBreaker = (targetId, config, eventBus) => {
590
559
  subscribeEvents(current.policy);
591
560
  const effectiveState = () => {
592
561
  const raw = current.policy.state;
593
- if (raw === CircuitState2.Open && openedAtMs > 0 && Date.now() - openedAtMs >= config.half_open_after_ms) {
594
- return CircuitState2.HalfOpen;
562
+ if (raw === CircuitState.Open && openedAtMs > 0 && Date.now() - openedAtMs >= config.half_open_after_ms) {
563
+ return CircuitState.HalfOpen;
595
564
  }
596
565
  return raw;
597
566
  };
@@ -618,11 +587,11 @@ var createCircuitBreaker = (targetId, config, eventBus) => {
618
587
  }
619
588
  },
620
589
  allowRequest() {
621
- return effectiveState() !== CircuitState2.Open;
590
+ return effectiveState() !== CircuitState.Open;
622
591
  },
623
592
  reset() {
624
593
  current = createPolicy();
625
- previousState = CircuitState2.Closed;
594
+ previousState = CircuitState.Closed;
626
595
  openedAtMs = 0;
627
596
  subscribeEvents(current.policy);
628
597
  }
@@ -824,9 +793,6 @@ var createCooldownManager = (registry, eventBus) => ({
824
793
  return target.cooldown_until !== null && target.cooldown_until > nowMs;
825
794
  }
826
795
  });
827
-
828
- // src/routing/admission.ts
829
- import PQueue from "p-queue";
830
796
  var checkHardRejects = (ctx) => {
831
797
  if (!ctx.hasEligibleTargets) {
832
798
  return { result: "rejected", reason: "no eligible targets available" };
@@ -997,7 +963,11 @@ var createFailoverOrchestrator = (deps) => ({
997
963
  let totalFailovers = 0;
998
964
  let lastErrorClass;
999
965
  log?.info(
1000
- { event: "failover_start", retry_budget: deps.retryBudget, failover_budget: deps.failoverBudget },
966
+ {
967
+ event: "failover_start",
968
+ retry_budget: deps.retryBudget,
969
+ failover_budget: deps.failoverBudget
970
+ },
1001
971
  "Failover loop started"
1002
972
  );
1003
973
  for (let failoverNo = 0; failoverNo <= deps.failoverBudget; failoverNo++) {
@@ -1028,10 +998,7 @@ var createFailoverOrchestrator = (deps) => ({
1028
998
  };
1029
999
  }
1030
1000
  const targetId = selection.selected.target_id;
1031
- const retryPolicy = createRetryPolicy(
1032
- deps.retryBudget,
1033
- deps.backoffParams
1034
- );
1001
+ const retryPolicy = createRetryPolicy(deps.retryBudget, deps.backoffParams);
1035
1002
  for (let retry = 0; retry <= deps.retryBudget; retry++) {
1036
1003
  const attemptNo = retry + 1;
1037
1004
  const acquired = deps.concurrency.acquire(targetId);
@@ -1057,7 +1024,13 @@ var createFailoverOrchestrator = (deps) => ({
1057
1024
  deps.registry.recordObservation(targetId, 1);
1058
1025
  deps.registry.updateLatency(targetId, attemptResult.latency_ms);
1059
1026
  log?.info(
1060
- { event: "attempt_success", target_id: targetId, attempt_no: attemptNo, failover_no: failoverNo, latency_ms: attemptResult.latency_ms },
1027
+ {
1028
+ event: "attempt_success",
1029
+ target_id: targetId,
1030
+ attempt_no: attemptNo,
1031
+ failover_no: failoverNo,
1032
+ latency_ms: attemptResult.latency_ms
1033
+ },
1061
1034
  "Attempt succeeded"
1062
1035
  );
1063
1036
  attempts.push({
@@ -1095,15 +1068,16 @@ var createFailoverOrchestrator = (deps) => ({
1095
1068
  deps.backoffParams,
1096
1069
  deps.backoffParams.max_ms
1097
1070
  );
1098
- deps.cooldownManager.setCooldown(
1099
- targetId,
1100
- cooldownMs,
1101
- errorClass.class
1102
- );
1071
+ deps.cooldownManager.setCooldown(targetId, cooldownMs, errorClass.class);
1103
1072
  }
1104
1073
  if (errorClass.class === "ModelUnavailable") {
1105
1074
  log?.info(
1106
- { event: "early_failover", target_id: targetId, error_class: errorClass.class, failover_no: failoverNo },
1075
+ {
1076
+ event: "early_failover",
1077
+ target_id: targetId,
1078
+ error_class: errorClass.class,
1079
+ failover_no: failoverNo
1080
+ },
1107
1081
  "Early failover \u2014 ModelUnavailable"
1108
1082
  );
1109
1083
  attempts.push({
@@ -1181,17 +1155,25 @@ var createFailoverOrchestrator = (deps) => ({
1181
1155
  totalRetries++;
1182
1156
  if (decision.action === "retry") {
1183
1157
  log?.info(
1184
- { event: "retry", target_id: targetId, attempt_no: attemptNo, error_class: errorClass.class, delay_ms: decision.delay_ms },
1158
+ {
1159
+ event: "retry",
1160
+ target_id: targetId,
1161
+ attempt_no: attemptNo,
1162
+ error_class: errorClass.class,
1163
+ delay_ms: decision.delay_ms
1164
+ },
1185
1165
  "Retrying after delay"
1186
1166
  );
1187
- await new Promise(
1188
- (resolve) => setTimeout(resolve, decision.delay_ms)
1189
- );
1167
+ await new Promise((resolve) => setTimeout(resolve, decision.delay_ms));
1190
1168
  }
1191
1169
  }
1192
1170
  }
1193
1171
  log?.warn(
1194
- { event: "failover_budget_exhausted", total_retries: totalRetries, total_failovers: totalFailovers },
1172
+ {
1173
+ event: "failover_budget_exhausted",
1174
+ total_retries: totalRetries,
1175
+ total_failovers: totalFailovers
1176
+ },
1195
1177
  "Failover budget exhausted"
1196
1178
  );
1197
1179
  return {
@@ -1231,7 +1213,8 @@ var hasConfigChanged = (oldTarget, newTarget) => {
1231
1213
  if (oldTarget.enabled !== newTarget.enabled) return true;
1232
1214
  if (oldTarget.operator_priority !== newTarget.operator_priority) return true;
1233
1215
  if (JSON.stringify(oldTarget.policy_tags) !== JSON.stringify(newTarget.policy_tags)) return true;
1234
- if (JSON.stringify(oldTarget.capabilities) !== JSON.stringify(newTarget.capabilities)) return true;
1216
+ if (JSON.stringify(oldTarget.capabilities) !== JSON.stringify(newTarget.capabilities))
1217
+ return true;
1235
1218
  if (oldTarget.retry_budget !== newTarget.retry_budget) return true;
1236
1219
  if (oldTarget.failover_budget !== newTarget.failover_budget) return true;
1237
1220
  if (oldTarget.concurrency_limit !== newTarget.concurrency_limit) return true;
@@ -1372,9 +1355,6 @@ var reloadConfig = (deps, rawConfig) => {
1372
1355
  throw err;
1373
1356
  }
1374
1357
  };
1375
-
1376
- // src/operator/plugin-tools.ts
1377
- import { tool } from "@opencode-ai/plugin/tool";
1378
1358
  var { schema: z3 } = tool;
1379
1359
  var createOperatorTools = (deps) => ({
1380
1360
  listTargets: tool({
@@ -1390,10 +1370,7 @@ var createOperatorTools = (deps) => ({
1390
1370
  description: "Pause a target, preventing new requests from being routed to it.",
1391
1371
  args: { target_id: z3.string().min(1) },
1392
1372
  async execute(args) {
1393
- deps.logger.info(
1394
- { op: "pauseTarget", target_id: args.target_id },
1395
- "operator: pauseTarget"
1396
- );
1373
+ deps.logger.info({ op: "pauseTarget", target_id: args.target_id }, "operator: pauseTarget");
1397
1374
  const result = pauseTarget(deps, args.target_id);
1398
1375
  return JSON.stringify(result, null, 2);
1399
1376
  }
@@ -1402,10 +1379,7 @@ var createOperatorTools = (deps) => ({
1402
1379
  description: "Resume a previously paused or disabled target, allowing new requests.",
1403
1380
  args: { target_id: z3.string().min(1) },
1404
1381
  async execute(args) {
1405
- deps.logger.info(
1406
- { op: "resumeTarget", target_id: args.target_id },
1407
- "operator: resumeTarget"
1408
- );
1382
+ deps.logger.info({ op: "resumeTarget", target_id: args.target_id }, "operator: resumeTarget");
1409
1383
  const result = resumeTarget(deps, args.target_id);
1410
1384
  return JSON.stringify(result, null, 2);
1411
1385
  }
@@ -1414,10 +1388,7 @@ var createOperatorTools = (deps) => ({
1414
1388
  description: "Drain a target, allowing in-flight requests to complete but preventing new ones.",
1415
1389
  args: { target_id: z3.string().min(1) },
1416
1390
  async execute(args) {
1417
- deps.logger.info(
1418
- { op: "drainTarget", target_id: args.target_id },
1419
- "operator: drainTarget"
1420
- );
1391
+ deps.logger.info({ op: "drainTarget", target_id: args.target_id }, "operator: drainTarget");
1421
1392
  const result = drainTarget(deps, args.target_id);
1422
1393
  return JSON.stringify(result, null, 2);
1423
1394
  }
@@ -1456,11 +1427,6 @@ var createOperatorTools = (deps) => ({
1456
1427
  }
1457
1428
  })
1458
1429
  });
1459
-
1460
- // src/profiles/store.ts
1461
- import { readFile, writeFile, rename, mkdir } from "fs/promises";
1462
- import { homedir } from "os";
1463
- import { join, dirname } from "path";
1464
1430
  var PROFILES_DIR = join(homedir(), ".local", "share", "o-switcher");
1465
1431
  var PROFILES_PATH = join(PROFILES_DIR, "profiles.json");
1466
1432
  var loadProfiles = async (path = PROFILES_PATH) => {
@@ -1527,22 +1493,11 @@ var nextProfileId = (store, provider) => {
1527
1493
  const maxN = Object.keys(store).filter((key) => key.startsWith(prefix)).map((key) => Number(key.slice(prefix.length))).filter((n) => !Number.isNaN(n)).reduce((max, n) => Math.max(max, n), 0);
1528
1494
  return `${provider}-${maxN + 1}`;
1529
1495
  };
1530
-
1531
- // src/profiles/watcher.ts
1532
- import { readFile as readFile2, watch } from "fs/promises";
1533
- import { homedir as homedir2 } from "os";
1534
- import { join as join2, dirname as dirname2 } from "path";
1535
- var AUTH_JSON_PATH = join2(
1536
- homedir2(),
1537
- ".local",
1538
- "share",
1539
- "opencode",
1540
- "auth.json"
1541
- );
1496
+ var AUTH_JSON_PATH = join(homedir(), ".local", "share", "opencode", "auth.json");
1542
1497
  var DEBOUNCE_MS = 100;
1543
1498
  var readAuthJson = async (path) => {
1544
1499
  try {
1545
- const content = await readFile2(path, "utf-8");
1500
+ const content = await readFile(path, "utf-8");
1546
1501
  return JSON.parse(content);
1547
1502
  } catch {
1548
1503
  return {};
@@ -1575,7 +1530,6 @@ var createAuthWatcher = (options) => {
1575
1530
  let lastKnownAuth = {};
1576
1531
  let abortController = null;
1577
1532
  let debounceTimer = null;
1578
- let watchPromise = null;
1579
1533
  const processChange = async () => {
1580
1534
  const newAuth = await readAuthJson(authPath);
1581
1535
  let store = await loadProfiles(profPath);
@@ -1584,7 +1538,10 @@ var createAuthWatcher = (options) => {
1584
1538
  if (!entry) continue;
1585
1539
  const previousEntry = lastKnownAuth[provider];
1586
1540
  if (previousEntry !== void 0 && !entriesEqual(previousEntry, entry)) {
1587
- log?.info({ provider, action: "credential_changed" }, "Credential change detected \u2014 saving previous credential");
1541
+ log?.info(
1542
+ { provider, action: "credential_changed" },
1543
+ "Credential change detected \u2014 saving previous credential"
1544
+ );
1588
1545
  const prevCredential = toCredential(previousEntry);
1589
1546
  const newStore = addProfile(store, provider, prevCredential);
1590
1547
  if (newStore !== store) {
@@ -1630,12 +1587,15 @@ var createAuthWatcher = (options) => {
1630
1587
  store = addProfile(store, provider, credential);
1631
1588
  }
1632
1589
  await saveProfiles(store, profPath);
1633
- log?.info({ profiles_initialized: Object.keys(store).length }, "Initialized profiles from auth.json");
1590
+ log?.info(
1591
+ { profiles_initialized: Object.keys(store).length },
1592
+ "Initialized profiles from auth.json"
1593
+ );
1634
1594
  }
1635
1595
  lastKnownAuth = currentAuth;
1636
1596
  abortController = new AbortController();
1637
- const parentDir = dirname2(authPath);
1638
- watchPromise = (async () => {
1597
+ const parentDir = dirname(authPath);
1598
+ (async () => {
1639
1599
  try {
1640
1600
  const watcher = watch(parentDir, {
1641
1601
  signal: abortController.signal
@@ -1646,9 +1606,7 @@ var createAuthWatcher = (options) => {
1646
1606
  }
1647
1607
  }
1648
1608
  } catch (err) {
1649
- const name = err.name;
1650
- if (name !== "AbortError") {
1651
- }
1609
+ err.name;
1652
1610
  }
1653
1611
  })();
1654
1612
  };
@@ -1661,17 +1619,13 @@ var createAuthWatcher = (options) => {
1661
1619
  abortController.abort();
1662
1620
  abortController = null;
1663
1621
  }
1664
- watchPromise = null;
1665
1622
  log?.info("Auth watcher stopped");
1666
1623
  };
1667
1624
  return { start, stop };
1668
1625
  };
1669
-
1670
- // src/profiles/tools.ts
1671
- import { tool as tool2 } from "@opencode-ai/plugin/tool";
1672
- var { schema: z4 } = tool2;
1626
+ var { schema: z4 } = tool;
1673
1627
  var createProfileTools = (options) => ({
1674
- profilesList: tool2({
1628
+ profilesList: tool({
1675
1629
  description: "List all saved auth profiles with provider, type, and creation date.",
1676
1630
  args: {},
1677
1631
  async execute() {
@@ -1686,7 +1640,7 @@ var createProfileTools = (options) => ({
1686
1640
  return JSON.stringify(result, null, 2);
1687
1641
  }
1688
1642
  }),
1689
- profilesRemove: tool2({
1643
+ profilesRemove: tool({
1690
1644
  description: "Remove a saved auth profile by ID.",
1691
1645
  args: { id: z4.string().min(1) },
1692
1646
  async execute(args) {
@@ -1705,73 +1659,4 @@ var createProfileTools = (options) => ({
1705
1659
  })
1706
1660
  });
1707
1661
 
1708
- export {
1709
- DEFAULT_RETRY_BUDGET,
1710
- DEFAULT_FAILOVER_BUDGET,
1711
- DEFAULT_BACKOFF_BASE_MS,
1712
- DEFAULT_BACKOFF_MULTIPLIER,
1713
- DEFAULT_BACKOFF_MAX_MS,
1714
- DEFAULT_BACKOFF_JITTER,
1715
- DEFAULT_RETRY,
1716
- DEFAULT_TIMEOUT_MS,
1717
- BackoffConfigSchema,
1718
- TargetConfigSchema,
1719
- SwitcherConfigSchema,
1720
- ConfigValidationError,
1721
- validateConfig,
1722
- discoverTargets,
1723
- discoverTargetsFromProfiles,
1724
- INITIAL_HEALTH_SCORE,
1725
- DEFAULT_ALPHA,
1726
- updateHealthScore,
1727
- updateLatencyEma,
1728
- TargetRegistry,
1729
- createRegistry,
1730
- TARGET_STATES,
1731
- REDACT_PATHS,
1732
- createAuditLogger,
1733
- createRequestLogger,
1734
- generateCorrelationId,
1735
- ErrorClassSchema,
1736
- isRetryable,
1737
- getTargetStateTransition,
1738
- DEFAULT_BACKOFF_PARAMS,
1739
- computeBackoffMs,
1740
- createRetryPolicy,
1741
- EXCLUSION_REASONS,
1742
- ADMISSION_RESULTS,
1743
- createRoutingEventBus,
1744
- DualBreaker,
1745
- createCircuitBreaker,
1746
- createConcurrencyTracker,
1747
- normalizeLatency,
1748
- computeScore,
1749
- getExclusionReason,
1750
- selectTarget,
1751
- computeCooldownMs,
1752
- createCooldownManager,
1753
- checkHardRejects,
1754
- createAdmissionController,
1755
- createLogSubscriber,
1756
- createFailoverOrchestrator,
1757
- computeConfigDiff,
1758
- applyConfigDiff,
1759
- createRequestTraceBuffer,
1760
- listTargets,
1761
- pauseTarget,
1762
- resumeTarget,
1763
- drainTarget,
1764
- disableTarget,
1765
- inspectRequest,
1766
- reloadConfig,
1767
- createOperatorTools,
1768
- loadProfiles,
1769
- saveProfiles,
1770
- addProfile,
1771
- removeProfile,
1772
- listProfiles,
1773
- nextProfileId,
1774
- createAuthWatcher,
1775
- createProfileTools
1776
- };
1777
- //# sourceMappingURL=chunk-BTDKGS7P.js.map
1662
+ export { ADMISSION_RESULTS, BackoffConfigSchema, ConfigValidationError, DEFAULT_ALPHA, DEFAULT_BACKOFF_BASE_MS, DEFAULT_BACKOFF_JITTER, DEFAULT_BACKOFF_MAX_MS, DEFAULT_BACKOFF_MULTIPLIER, DEFAULT_BACKOFF_PARAMS, DEFAULT_FAILOVER_BUDGET, DEFAULT_RETRY, DEFAULT_RETRY_BUDGET, DEFAULT_TIMEOUT_MS, DualBreaker, EXCLUSION_REASONS, ErrorClassSchema, INITIAL_HEALTH_SCORE, REDACT_PATHS, SwitcherConfigSchema, TARGET_STATES, TargetConfigSchema, TargetRegistry, addProfile, applyConfigDiff, checkHardRejects, computeBackoffMs, computeConfigDiff, computeCooldownMs, computeScore, createAdmissionController, createAuditLogger, createAuthWatcher, createCircuitBreaker, createConcurrencyTracker, createCooldownManager, createFailoverOrchestrator, createLogSubscriber, createOperatorTools, createProfileTools, createRegistry, createRequestLogger, createRequestTraceBuffer, createRetryPolicy, createRoutingEventBus, disableTarget, discoverTargets, discoverTargetsFromProfiles, drainTarget, generateCorrelationId, getExclusionReason, getTargetStateTransition, inspectRequest, isRetryable, listProfiles, listTargets, loadProfiles, nextProfileId, normalizeLatency, pauseTarget, reloadConfig, removeProfile, resumeTarget, saveProfiles, selectTarget, updateHealthScore, updateLatencyEma, validateConfig };