@dylanrussell/agent-router 1.0.7 → 1.1.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/tui.js CHANGED
@@ -14615,14 +14615,26 @@ function date4(params) {
14615
14615
  config(en_default());
14616
14616
 
14617
14617
  // src/core/schema.ts
14618
+ var FallbackSchema = external_exports.object({
14619
+ model: external_exports.string().regex(/^[^/\s]+\/\S+$/, "Expected provider/model"),
14620
+ variant: external_exports.string().min(1).optional()
14621
+ }).strict();
14622
+ var RoutingEntrySchema = external_exports.object({
14623
+ model: external_exports.string().min(1),
14624
+ variant: external_exports.string().min(1).nullable().optional(),
14625
+ fallbacks: external_exports.array(FallbackSchema).max(8).optional()
14626
+ }).strict();
14618
14627
  var StateFileSchema = external_exports.object({
14619
14628
  version: external_exports.literal(1),
14620
14629
  active: external_exports.string().min(1),
14621
14630
  previousActive: external_exports.string().min(1).nullable(),
14622
- lastSwitchedAt: external_exports.string().min(1)
14631
+ lastSwitchedAt: external_exports.string().min(1),
14632
+ fallbackAgents: external_exports.record(external_exports.string(), RoutingEntrySchema).optional()
14623
14633
  }).strict();
14624
14634
  var AgentEntrySchema = external_exports.object({
14625
- model: external_exports.string().min(1)
14635
+ model: external_exports.string().min(1),
14636
+ variant: external_exports.string().min(1).nullable().optional(),
14637
+ fallbacks: external_exports.array(FallbackSchema).max(8).optional()
14626
14638
  }).passthrough();
14627
14639
  var StackFileSchema = external_exports.object({
14628
14640
  agents: external_exports.record(external_exports.string(), AgentEntrySchema)
@@ -15303,6 +15315,9 @@ function collectModelRefs(stack) {
15303
15315
  const refs = [];
15304
15316
  for (const [k, v] of Object.entries(stack.agents)) {
15305
15317
  refs.push({ path: `agents.${k}.model`, modelId: v.model });
15318
+ for (const [index, candidate] of (v.fallbacks ?? []).entries()) {
15319
+ refs.push({ path: `agents.${k}.fallbacks.${index}.model`, modelId: candidate.model });
15320
+ }
15306
15321
  }
15307
15322
  return refs;
15308
15323
  }
@@ -15382,7 +15397,7 @@ async function applyStack(paths, name, options = {}) {
15382
15397
  }
15383
15398
  const prevState = await readState(paths.statePath);
15384
15399
  const prevActive = prevState?.active ?? null;
15385
- const displaced = { agents: entriesToStackAgents(await readAgentEntries(paths.agentsDir)) };
15400
+ const displaced = { agents: await captureAgents(paths) };
15386
15401
  const historyId = await appendHistory(
15387
15402
  paths.historyDir,
15388
15403
  prevActive ?? "(none)",
@@ -15400,7 +15415,20 @@ async function applyStack(paths, name, options = {}) {
15400
15415
  version: 1,
15401
15416
  active: name,
15402
15417
  previousActive: prevActive,
15403
- lastSwitchedAt: (/* @__PURE__ */ new Date()).toISOString()
15418
+ lastSwitchedAt: (/* @__PURE__ */ new Date()).toISOString(),
15419
+ fallbackAgents: Object.fromEntries(
15420
+ Object.entries(target.agents).filter(([, entry]) => entry.fallbacks?.length).map(([agent, entry]) => {
15421
+ const variant = "variant" in entry ? entry.variant : displaced.agents[agent]?.variant;
15422
+ return [
15423
+ agent,
15424
+ {
15425
+ model: entry.model,
15426
+ variant: typeof variant === "string" ? variant : void 0,
15427
+ fallbacks: entry.fallbacks
15428
+ }
15429
+ ];
15430
+ })
15431
+ )
15404
15432
  });
15405
15433
  await trimHistory(paths.historyDir).catch(() => {
15406
15434
  });
@@ -15416,7 +15444,7 @@ function entryOptions(entry) {
15416
15444
  const rec = entry;
15417
15445
  const out = {};
15418
15446
  for (const [k, v] of Object.entries(rec)) {
15419
- if (k === "model" || RESERVED_AGENT_KEYS.has(k)) continue;
15447
+ if (k === "model" || k === "fallbacks" || RESERVED_AGENT_KEYS.has(k)) continue;
15420
15448
  out[k] = v;
15421
15449
  }
15422
15450
  return out;
@@ -15428,11 +15456,24 @@ function entriesToStackAgents(entries) {
15428
15456
  if (!entry) continue;
15429
15457
  const { model, options } = entry;
15430
15458
  const stackEntry = { model };
15431
- for (const [k, v] of Object.entries(options)) stackEntry[k] = v;
15459
+ for (const [k, v] of Object.entries(options)) {
15460
+ if (k !== "fallbacks") stackEntry[k] = v;
15461
+ }
15432
15462
  out[name] = stackEntry;
15433
15463
  }
15434
15464
  return out;
15435
15465
  }
15466
+ async function captureAgents(paths) {
15467
+ const agents = entriesToStackAgents(await readAgentEntries(paths.agentsDir));
15468
+ const state = await readState(paths.statePath);
15469
+ for (const [name, entry] of Object.entries(agents)) {
15470
+ const routing = state?.fallbackAgents?.[name];
15471
+ if (routing && routing.model === entry.model && (routing.variant ?? void 0) === (entry.variant ?? void 0)) {
15472
+ entry.fallbacks = routing.fallbacks;
15473
+ }
15474
+ }
15475
+ return agents;
15476
+ }
15436
15477
  async function back(paths, n = 1, options = {}) {
15437
15478
  if (n < 1) throw new UserError("`back -n` must be at least 1.");
15438
15479
  const state = await readState(paths.statePath);