@oeronteros-1/opencode-orchestra 1.0.27 → 1.0.29

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.
Files changed (48) hide show
  1. package/README.md +79 -1
  2. package/dashboard-dist/assets/index-DXFxvVhJ.css +1 -0
  3. package/dashboard-dist/assets/index-DlLCX2BY.js +132 -0
  4. package/dashboard-dist/index.html +2 -2
  5. package/dist/agents/integrator.js +1 -1
  6. package/dist/agents/integrator.js.map +1 -1
  7. package/dist/agents/lead.js +2 -13
  8. package/dist/agents/lead.js.map +1 -1
  9. package/dist/config/load.d.ts +5 -0
  10. package/dist/config/load.js +20 -5
  11. package/dist/config/load.js.map +1 -1
  12. package/dist/config/schema.d.ts +3 -0
  13. package/dist/config/schema.js +6 -0
  14. package/dist/config/schema.js.map +1 -1
  15. package/dist/dashboard/server.js +27 -8
  16. package/dist/dashboard/server.js.map +1 -1
  17. package/dist/diagnostics/doctor.js +194 -0
  18. package/dist/diagnostics/doctor.js.map +1 -1
  19. package/dist/diagnostics/update.js +8 -7
  20. package/dist/diagnostics/update.js.map +1 -1
  21. package/dist/index.js +33 -4
  22. package/dist/index.js.map +1 -1
  23. package/dist/orchestration/ownership.d.ts +19 -0
  24. package/dist/orchestration/ownership.js +26 -0
  25. package/dist/orchestration/ownership.js.map +1 -1
  26. package/dist/routing/classifier.js +20 -2
  27. package/dist/routing/classifier.js.map +1 -1
  28. package/dist/routing/fallback.d.ts +19 -10
  29. package/dist/routing/fallback.js +89 -18
  30. package/dist/routing/fallback.js.map +1 -1
  31. package/dist/routing/model-resolver.d.ts +47 -0
  32. package/dist/routing/model-resolver.js +110 -2
  33. package/dist/routing/model-resolver.js.map +1 -1
  34. package/dist/spawn.d.ts +14 -1
  35. package/dist/spawn.js +58 -4
  36. package/dist/spawn.js.map +1 -1
  37. package/dist/telemetry/ledger.d.ts +49 -0
  38. package/dist/telemetry/ledger.js +157 -0
  39. package/dist/telemetry/ledger.js.map +1 -1
  40. package/dist/telemetry/live.d.ts +12 -1
  41. package/dist/telemetry/live.js +50 -9
  42. package/dist/telemetry/live.js.map +1 -1
  43. package/dist/tools.js +71 -3
  44. package/dist/tools.js.map +1 -1
  45. package/package.json +4 -4
  46. package/schema/opencode-orchestra.schema.json +8 -0
  47. package/dashboard-dist/assets/index-BcxwxSxG.js +0 -124
  48. package/dashboard-dist/assets/index-igZBUoKO.css +0 -2
@@ -95,7 +95,6 @@ const SIGNALS = {
95
95
  "migration",
96
96
  "migrate",
97
97
  "upgrade",
98
- "port to",
99
98
  "rewrite",
100
99
  "миграц",
101
100
  "перенести",
@@ -127,6 +126,24 @@ const CRITICAL_SIGNALS = [
127
126
  "утечка",
128
127
  ];
129
128
  const INTERMITTENT_SIGNALS = ["intermittent", "occasionally", "sometimes", "randomly", "иногда", "периодически", "случайно"];
129
+ /**
130
+ * High-precision signals that state a task's primary domain or intent. When
131
+ * one of these matches, the profile receives PRIMARY_INTENT_BONUS so that an
132
+ * explicit domain mention is not overridden by incidental wording from a
133
+ * generic activity or environment profile. For example, "security review of
134
+ * the pull request" must route to security (not the generic review profile),
135
+ * and "migrate the docker deployment" must route to migration (not ops).
136
+ *
137
+ * Only signals proven by a failing test belong here: ambiguous words such as
138
+ * "injection", "upgrade", "port to", or "rewrite" would cause false positives
139
+ * (e.g. "Export to CSV" matches the "port to" substring, "dependency
140
+ * injection" is not a security task, and "rewrite the component" is UI work).
141
+ */
142
+ const PRIMARY_INTENT_SIGNALS = {
143
+ security: ["security", "vulnerability"],
144
+ migration: ["migrate", "migration"],
145
+ };
146
+ const PRIMARY_INTENT_BONUS = 3;
130
147
  export function classifyTask(task, enabledProfiles) {
131
148
  const normalized = task.toLowerCase();
132
149
  const ranked = Object.entries(SIGNALS)
@@ -136,7 +153,8 @@ export function classifyTask(task, enabledProfiles) {
136
153
  const intermittentDebugBonus = profile === "debug" && matched.length > 0 && INTERMITTENT_SIGNALS.some((signal) => normalized.includes(signal))
137
154
  ? 2
138
155
  : 0;
139
- return { profile, matched, score: matched.length + intermittentDebugBonus };
156
+ const primaryIntentBonus = PRIMARY_INTENT_SIGNALS[profile]?.some((signal) => matched.includes(signal)) ? PRIMARY_INTENT_BONUS : 0;
157
+ return { profile, matched, score: matched.length + intermittentDebugBonus + primaryIntentBonus };
140
158
  })
141
159
  .sort((a, b) => b.score - a.score);
142
160
  const winner = ranked[0];
@@ -1 +1 @@
1
- {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../src/routing/classifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../src/routing/classifier.ts"],"names":[],"mappings":"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"}
@@ -1,33 +1,42 @@
1
- import type { BudgetMode, ModelCandidateInput, ModelCost } from "../config/schema.js";
1
+ import type { BudgetMode, ModelCandidateInput, ModelCost, ModelTier } from "../config/schema.js";
2
2
  import { resolveModel } from "./model-resolver.js";
3
3
  export interface FallbackEntry {
4
4
  id: string;
5
5
  cost: ModelCost;
6
- /** Lower is cheaper; used to prefer cheaper fallbacks after a failure. */
6
+ /** Static cost-class rank: paid (2) > subscription (1) > free (0). */
7
7
  costRank: number;
8
+ /** True when the capability is declared or explicitly scored; false when unknown. */
9
+ compatible: boolean;
10
+ priority: number;
11
+ tier: ModelTier;
8
12
  }
9
13
  export interface FallbackChain {
10
14
  /** The winning model id (first choice). */
11
15
  primary: string;
12
- /** Ordered cheaper alternatives after the primary. */
16
+ /** Ordered alternatives after the primary (compatibility first). */
13
17
  alternatives: FallbackEntry[];
14
18
  /** All entries (primary + alternatives) in failover order. */
15
19
  all: FallbackEntry[];
16
20
  }
21
+ export type ErrorKind = "rate-limit" | "server" | "timeout" | "auth" | "invalid-request" | "other";
17
22
  interface RetryableError {
18
- /** HTTP status or "timeout". Rate-limit (429) and 5xx are retryable. */
19
- kind: "rate-limit" | "server" | "timeout" | "other";
23
+ /** Retryable failures trigger failover; auth and invalid-request are terminal. */
24
+ kind: ErrorKind;
20
25
  }
21
26
  /**
22
- * Classify an error into retryable categories. A retryable failure should
23
- * trigger failover to a cheaper model in the chain.
27
+ * Classify an error into policy categories. Only rate-limit, timeout, and
28
+ * server failures are retryable; auth and invalid-request stop the chain.
24
29
  */
25
30
  export declare function classifyError(error: unknown): RetryableError;
26
31
  export declare function isRetryable(kind: RetryableError["kind"]): boolean;
27
32
  /**
28
33
  * Build a failover chain for a capability pool. The primary is the current
29
- * winner; alternatives are the remaining candidates sorted by increasing cost
30
- * (cheaper first), so a retry steps down in price instead of up.
34
+ * winner; alternatives are the remaining candidates ranked deterministically:
35
+ * capability compatibility, then priority, tier, budget-aware cost class, and
36
+ * model id. Explicitly incompatible candidates are excluded before resolution
37
+ * so the primary is always compatible; unknown-capability candidates stay
38
+ * eligible but rank below compatible ones. Budget filters (paid exclusion)
39
+ * apply to alternatives as well as the primary.
31
40
  */
32
41
  export declare function buildFallbackChain(pool: ModelCandidateInput[], capability: Parameters<typeof resolveModel>[0]["capability"], budget: BudgetMode, allowPaid: boolean, options?: {
33
42
  preferredCosts?: ModelCost[];
@@ -37,7 +46,7 @@ export declare function buildFallbackChain(pool: ModelCandidateInput[], capabili
37
46
  }): FallbackChain | undefined;
38
47
  /**
39
48
  * Given a chain and the id of a model that just failed, return the next
40
- * cheaper alternative to try, or undefined when the chain is exhausted.
49
+ * alternative to try, or undefined when the chain is exhausted.
41
50
  */
42
51
  export declare function nextAfterFailure(chain: FallbackChain, failedId: string): string | undefined;
43
52
  export {};
@@ -1,11 +1,39 @@
1
- import { normalizeCandidate, resolveModel } from "./model-resolver.js";
1
+ import { isCapabilityCompatible, isCapabilityIncompatible, normalizeCandidate, resolveModel, } from "./model-resolver.js";
2
2
  const COST_RANK = { paid: 2, subscription: 1, free: 0 };
3
+ const TIER_RANK = { frontier: 2, lead: 1, worker: 0 };
4
+ /**
5
+ * Budget-aware cost-class preference applied as the tie-break after priority
6
+ * and tier. `ModelCost` is a closed union, so an unknown cost can never be
7
+ * coerced into a cheaper class.
8
+ */
9
+ const BUDGET_COST_PREFERENCE = {
10
+ eco: ["free", "subscription", "paid"],
11
+ balanced: ["subscription", "free", "paid"],
12
+ quality: ["subscription", "paid", "free"],
13
+ ebobo: ["paid", "subscription", "free"],
14
+ };
3
15
  function compareCodepoints(a, b) {
4
16
  return a < b ? -1 : a > b ? 1 : 0;
5
17
  }
18
+ function costPreferenceOrder(budget, preferredCosts) {
19
+ if (preferredCosts && preferredCosts.length > 0)
20
+ return preferredCosts;
21
+ return BUDGET_COST_PREFERENCE[budget];
22
+ }
23
+ function costPreferenceRank(cost, order) {
24
+ const index = order.indexOf(cost);
25
+ return index === -1 ? order.length : index;
26
+ }
27
+ function isBudgetEligible(candidate, allowPaid, paidCallsUsed, maxPaidCalls) {
28
+ if (candidate.cost !== "paid")
29
+ return true;
30
+ if (!allowPaid)
31
+ return false;
32
+ return maxPaidCalls === undefined || paidCallsUsed < maxPaidCalls;
33
+ }
6
34
  /**
7
- * Classify an error into retryable categories. A retryable failure should
8
- * trigger failover to a cheaper model in the chain.
35
+ * Classify an error into policy categories. Only rate-limit, timeout, and
36
+ * server failures are retryable; auth and invalid-request stop the chain.
9
37
  */
10
38
  export function classifyError(error) {
11
39
  const candidate = typeof error === "object" && error !== null ? error : undefined;
@@ -18,6 +46,12 @@ export function classifyError(error) {
18
46
  : String(error);
19
47
  const status = candidate?.status ?? candidate?.statusCode;
20
48
  const text = (status !== undefined ? String(status) + " " : "") + message.toLowerCase();
49
+ if (status === 401 || status === 403 || text.includes("unauthorized") || text.includes("forbidden") || text.includes("invalid api key") || text.includes("authentication")) {
50
+ return { kind: "auth" };
51
+ }
52
+ if (status === 400 || status === 404 || text.includes("not found") || text.includes("bad request") || text.includes("invalid request")) {
53
+ return { kind: "invalid-request" };
54
+ }
21
55
  if (status === 429 || text.includes("429") || text.includes("rate limit") || text.includes("rate-limit") || text.includes("too many requests")) {
22
56
  return { kind: "rate-limit" };
23
57
  }
@@ -34,15 +68,25 @@ export function isRetryable(kind) {
34
68
  }
35
69
  /**
36
70
  * Build a failover chain for a capability pool. The primary is the current
37
- * winner; alternatives are the remaining candidates sorted by increasing cost
38
- * (cheaper first), so a retry steps down in price instead of up.
71
+ * winner; alternatives are the remaining candidates ranked deterministically:
72
+ * capability compatibility, then priority, tier, budget-aware cost class, and
73
+ * model id. Explicitly incompatible candidates are excluded before resolution
74
+ * so the primary is always compatible; unknown-capability candidates stay
75
+ * eligible but rank below compatible ones. Budget filters (paid exclusion)
76
+ * apply to alternatives as well as the primary.
39
77
  */
40
78
  export function buildFallbackChain(pool, capability, budget, allowPaid, options = {}) {
41
79
  const normalized = pool.map(normalizeCandidate);
42
80
  if (normalized.length === 0)
43
81
  return undefined;
82
+ // The primary must always be capability-compatible: drop explicitly
83
+ // incompatible candidates before resolution so a high-priority incompatible
84
+ // model (e.g. an ebobo frontier) cannot take the primary slot.
85
+ const compatiblePool = normalized.filter((candidate) => !isCapabilityIncompatible(candidate, capability));
86
+ if (compatiblePool.length === 0)
87
+ return undefined;
44
88
  const winner = resolveModel({
45
- pool,
89
+ pool: compatiblePool,
46
90
  capability,
47
91
  budget,
48
92
  allowPaid,
@@ -51,31 +95,58 @@ export function buildFallbackChain(pool, capability, budget, allowPaid, options
51
95
  ...(options.paidCallsUsed !== undefined ? { paidCallsUsed: options.paidCallsUsed } : {}),
52
96
  ...(options.maxPaidCalls !== undefined ? { maxPaidCalls: options.maxPaidCalls } : {}),
53
97
  });
54
- const primary = winner?.id ?? normalized[0]?.id;
55
- if (!primary)
98
+ // If every compatible candidate was budget-excluded (e.g. an all-paid pool
99
+ // under an eco budget or a fully exhausted paid cap), `resolveModel` has no
100
+ // winner and there is no valid primary — never fail open to the first raw
101
+ // pool entry, which could surface a paid model as primary.
102
+ if (!winner)
56
103
  return undefined;
57
- const byId = new Map(normalized.map((candidate) => [candidate.id, candidate]));
58
- const primaryEntry = toEntry(byId.get(primary));
59
- const alternatives = normalized
104
+ const primary = winner.id;
105
+ const paidCallsUsed = options.paidCallsUsed ?? 0;
106
+ const costOrder = costPreferenceOrder(budget, options.preferredCosts);
107
+ const byId = new Map(compatiblePool.map((candidate) => [candidate.id, candidate]));
108
+ const primaryCandidate = byId.get(primary);
109
+ const primaryEntry = primaryCandidate ? toEntry(primaryCandidate, capability) : undefined;
110
+ const alternatives = compatiblePool
60
111
  .filter((candidate) => candidate.id !== primary)
61
- .sort((a, b) => COST_RANK[a.cost] - COST_RANK[b.cost] || compareCodepoints(a.id, b.id))
62
- .map((candidate) => toEntry(candidate));
112
+ .filter((candidate) => isBudgetEligible(candidate, allowPaid, paidCallsUsed, options.maxPaidCalls))
113
+ .sort((a, b) => {
114
+ const compat = compatibilityTier(b, capability) - compatibilityTier(a, capability);
115
+ if (compat !== 0)
116
+ return compat;
117
+ if (a.priority !== b.priority)
118
+ return b.priority - a.priority;
119
+ const tier = TIER_RANK[b.tier] - TIER_RANK[a.tier];
120
+ if (tier !== 0)
121
+ return tier;
122
+ const cost = costPreferenceRank(a.cost, costOrder) - costPreferenceRank(b.cost, costOrder);
123
+ if (cost !== 0)
124
+ return cost;
125
+ return compareCodepoints(a.id, b.id);
126
+ })
127
+ .map((candidate) => toEntry(candidate, capability));
63
128
  return {
64
129
  primary,
65
130
  alternatives,
66
131
  all: primaryEntry ? [primaryEntry, ...alternatives] : alternatives,
67
132
  };
68
133
  }
69
- function toEntry(candidate) {
134
+ function compatibilityTier(candidate, capability) {
135
+ return isCapabilityCompatible(candidate, capability) ? 1 : 0;
136
+ }
137
+ function toEntry(candidate, capability) {
70
138
  return {
71
- id: candidate?.id ?? "",
72
- cost: candidate?.cost ?? "free",
73
- costRank: COST_RANK[candidate?.cost ?? "free"],
139
+ id: candidate.id,
140
+ cost: candidate.cost,
141
+ costRank: COST_RANK[candidate.cost],
142
+ compatible: isCapabilityCompatible(candidate, capability),
143
+ priority: candidate.priority,
144
+ tier: candidate.tier,
74
145
  };
75
146
  }
76
147
  /**
77
148
  * Given a chain and the id of a model that just failed, return the next
78
- * cheaper alternative to try, or undefined when the chain is exhausted.
149
+ * alternative to try, or undefined when the chain is exhausted.
79
150
  */
80
151
  export function nextAfterFailure(chain, failedId) {
81
152
  const index = chain.all.findIndex((entry) => entry.id === failedId);
@@ -1 +1 @@
1
- {"version":3,"file":"fallback.js","sourceRoot":"","sources":["../../src/routing/fallback.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAuB,MAAM,qBAAqB,CAAA;AAsB3F,MAAM,SAAS,GAA8B,EAAE,IAAI,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;AAElF,SAAS,iBAAiB,CAAC,CAAS,EAAE,CAAS;IAC7C,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACnC,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,MAAM,SAAS,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAoE,CAAC,CAAC,CAAC,SAAS,CAAA;IAChJ,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ;QACvC,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,SAAS,EAAE,OAAO;YAClB,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC;YAC3B,CAAC,CAAC,KAAK,YAAY,KAAK;gBACtB,CAAC,CAAC,KAAK,CAAC,OAAO;gBACf,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrB,MAAM,MAAM,GAAG,SAAS,EAAE,MAAM,IAAI,SAAS,EAAE,UAAU,CAAA;IACzD,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAA;IAEvF,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC/I,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAA;IAC/B,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC5B,CAAC;IACD,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7J,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;IAC3B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAA4B;IACtD,OAAO,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,CAAA;AACzE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAA2B,EAC3B,UAA4D,EAC5D,MAAkB,EAClB,SAAkB,EAClB,UAKI,EAAE;IAEN,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IAC/C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAE7C,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,IAAI;QACJ,UAAU;QACV,MAAM;QACN,SAAS;QACT,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtF,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,MAAM,EAAE,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IAC/C,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAA;IAE9B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IAC9E,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,UAAU;SAC5B,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC;SAC/C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;SACtF,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;IAEzC,OAAO;QACL,OAAO;QACP,YAAY;QACZ,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY;KACnE,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,SAAqC;IACpD,OAAO;QACL,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE;QACvB,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,MAAM;QAC/B,QAAQ,EAAE,SAAS,CAAC,SAAS,EAAE,IAAI,IAAI,MAAM,CAAC;KAC/C,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAoB,EAAE,QAAgB;IACrE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAA;IACnE,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IAC/B,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,EAAE,CAAA;AACjC,CAAC"}
1
+ {"version":3,"file":"fallback.js","sourceRoot":"","sources":["../../src/routing/fallback.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,24 @@
1
1
  import type { BudgetMode, CapabilityName, ModelCandidateInput, ModelCost, ModelTier } from "../config/schema.js";
2
+ /**
3
+ * Stable machine-readable routing decision identifier. The resolver only emits
4
+ * the scoring codes; `exact_override` is reserved for an explicit orch-lead
5
+ * agent override and is produced by the tool layer, not the resolver.
6
+ */
7
+ export type RoutingReasonCode = "frontier" | "preferred_tier" | "preferred_cost" | "capability_match" | "price" | "priority" | "exact_override";
8
+ export interface RoutingReason {
9
+ code: RoutingReasonCode;
10
+ /** Bounded diagnostic copy; never contains secrets, prompts, or credentials. */
11
+ text: string;
12
+ matchedCapabilities: CapabilityName[];
13
+ score: number;
14
+ budget: BudgetMode;
15
+ }
16
+ /**
17
+ * Bound a routing reason's diagnostic text to a fixed length. The text only
18
+ * carries model id, cost class, tier, and score — never secrets, prompts, or
19
+ * credentials — so a plain truncation is safe.
20
+ */
21
+ export declare function boundReasonText(text: string, limit?: number): string;
2
22
  export interface ModelCandidate {
3
23
  id: string;
4
24
  cost: ModelCost;
@@ -23,6 +43,13 @@ export interface ResolveModelRequest {
23
43
  paidCallsUsed?: number;
24
44
  maxPaidCalls?: number;
25
45
  }
46
+ /**
47
+ * The shared resolution parameters for the orch-lead agent. Both the tool
48
+ * layer (routing metadata) and `createLeadAgent` (the actually assigned model)
49
+ * resolve the lead pool through this exact request so the reported lead always
50
+ * matches the assigned one.
51
+ */
52
+ export declare function leadResolveRequest(budget: BudgetMode): Omit<ResolveModelRequest, "pool" | "capability">;
26
53
  export interface ResolvedModel {
27
54
  id: string;
28
55
  score: number;
@@ -35,6 +62,26 @@ export interface ResolvedModel {
35
62
  * with a retryable error, step down this list instead of re-hitting it.
36
63
  */
37
64
  fallback: string[];
65
+ /** Structured, machine-readable routing decision for the winning model. */
66
+ routingReason?: RoutingReason;
38
67
  }
39
68
  export declare function normalizeCandidate(input: ModelCandidateInput): ModelCandidate;
69
+ /**
70
+ * Shared capability scoring helpers. `resolveModel` uses these for scoring and
71
+ * `buildFallbackChain` uses them to filter and rank fallback alternatives.
72
+ */
73
+ export declare function hasDeclaredCapability(candidate: ModelCandidate, capability: CapabilityName): boolean;
74
+ export declare function hasExplicitScore(candidate: ModelCandidate, capability: CapabilityName): boolean;
75
+ /**
76
+ * A candidate is compatible when it either declares the capability or carries
77
+ * an explicit positive score for it.
78
+ */
79
+ export declare function isCapabilityCompatible(candidate: ModelCandidate, capability: CapabilityName): boolean;
80
+ /**
81
+ * A candidate is explicitly incompatible when it declares *some* capabilities,
82
+ * does not declare the required one, and has no explicit score for it. Unknown
83
+ * candidates (empty capabilities) are NOT incompatible: they stay eligible but
84
+ * rank at lower confidence.
85
+ */
86
+ export declare function isCapabilityIncompatible(candidate: ModelCandidate, capability: CapabilityName): boolean;
40
87
  export declare function resolveModel(request: ResolveModelRequest): ResolvedModel | undefined;
@@ -1,4 +1,38 @@
1
1
  import { costAdjustment, getBudgetPolicy } from "./budget.js";
2
+ /** Maximum length of the `RoutingReason.text` diagnostic string. */
3
+ const REASON_TEXT_LIMIT = 200;
4
+ /**
5
+ * Bound a routing reason's diagnostic text to a fixed length. The text only
6
+ * carries model id, cost class, tier, and score — never secrets, prompts, or
7
+ * credentials — so a plain truncation is safe.
8
+ */
9
+ export function boundReasonText(text, limit = REASON_TEXT_LIMIT) {
10
+ if (text.length <= limit)
11
+ return text;
12
+ return text.slice(0, limit - 1) + "…";
13
+ }
14
+ /**
15
+ * The shared resolution parameters for the orch-lead agent. Both the tool
16
+ * layer (routing metadata) and `createLeadAgent` (the actually assigned model)
17
+ * resolve the lead pool through this exact request so the reported lead always
18
+ * matches the assigned one.
19
+ */
20
+ export function leadResolveRequest(budget) {
21
+ return {
22
+ budget,
23
+ allowPaid: budget === "quality" || budget === "ebobo",
24
+ preferredCosts: budget === "balanced"
25
+ ? ["subscription"]
26
+ : budget === "eco"
27
+ ? ["free"]
28
+ : [],
29
+ preferredTiers: budget === "balanced"
30
+ ? ["lead"]
31
+ : budget === "quality" || budget === "ebobo"
32
+ ? ["frontier", "lead"]
33
+ : [],
34
+ };
35
+ }
2
36
  export function normalizeCandidate(input) {
3
37
  if (typeof input === "string") {
4
38
  return {
@@ -22,6 +56,34 @@ export function normalizeCandidate(input) {
22
56
  ...(input.priceOutput !== undefined ? { priceOutput: input.priceOutput } : {}),
23
57
  };
24
58
  }
59
+ /**
60
+ * Shared capability scoring helpers. `resolveModel` uses these for scoring and
61
+ * `buildFallbackChain` uses them to filter and rank fallback alternatives.
62
+ */
63
+ export function hasDeclaredCapability(candidate, capability) {
64
+ return candidate.capabilities.includes(capability);
65
+ }
66
+ export function hasExplicitScore(candidate, capability) {
67
+ return (candidate.scores[capability] ?? 0) > 0;
68
+ }
69
+ /**
70
+ * A candidate is compatible when it either declares the capability or carries
71
+ * an explicit positive score for it.
72
+ */
73
+ export function isCapabilityCompatible(candidate, capability) {
74
+ return hasDeclaredCapability(candidate, capability) || hasExplicitScore(candidate, capability);
75
+ }
76
+ /**
77
+ * A candidate is explicitly incompatible when it declares *some* capabilities,
78
+ * does not declare the required one, and has no explicit score for it. Unknown
79
+ * candidates (empty capabilities) are NOT incompatible: they stay eligible but
80
+ * rank at lower confidence.
81
+ */
82
+ export function isCapabilityIncompatible(candidate, capability) {
83
+ return candidate.capabilities.length > 0
84
+ && !hasDeclaredCapability(candidate, capability)
85
+ && !hasExplicitScore(candidate, capability);
86
+ }
25
87
  const COST_ORDER = { paid: 2, subscription: 1, free: 0 };
26
88
  function compareCodepoints(a, b) {
27
89
  return a < b ? -1 : a > b ? 1 : 0;
@@ -42,7 +104,7 @@ export function resolveModel(request) {
42
104
  .filter((candidate) => candidate.cost !== "paid" || request.maxPaidCalls === undefined || (request.paidCallsUsed ?? 0) < request.maxPaidCalls)
43
105
  .map((candidate) => {
44
106
  const explicit = candidate.scores[request.capability] ?? 0;
45
- const declared = candidate.capabilities.includes(request.capability) ? 18 : 0;
107
+ const declared = hasDeclaredCapability(candidate, request.capability) ? 18 : 0;
46
108
  const contextBonus = candidate.context === "xlarge" ? 8 : candidate.context === "large" ? 4 : 0;
47
109
  const frontierBonus = request.budget === "ebobo"
48
110
  ? candidate.tier === "frontier"
@@ -67,7 +129,17 @@ export function resolveModel(request) {
67
129
  ...(preferredTierBonus ? ["preferred-tier=" + preferredTierBonus] : []),
68
130
  ...(priceAdj !== 0 ? ["price=" + priceAdj] : []),
69
131
  ];
70
- return { candidate, score, reason };
132
+ return {
133
+ candidate,
134
+ score,
135
+ reason,
136
+ explicit,
137
+ declared,
138
+ frontierBonus,
139
+ preferredCostBonus,
140
+ preferredTierBonus,
141
+ priceAdj,
142
+ };
71
143
  })
72
144
  .sort((a, b) => b.score - a.score || compareCodepoints(a.candidate.id, b.candidate.id));
73
145
  const winner = ranked[0];
@@ -77,6 +149,41 @@ export function resolveModel(request) {
77
149
  .slice(1)
78
150
  .sort((a, b) => COST_ORDER[a.candidate.cost] - COST_ORDER[b.candidate.cost] || a.score - b.score || compareCodepoints(a.candidate.id, b.candidate.id))
79
151
  .map((item) => item.candidate.id);
152
+ const matchedCapabilities = winner.explicit || winner.declared ? [request.capability] : [];
153
+ // Deterministic reason code by dominant scoring signal, strongest first.
154
+ let code;
155
+ let component;
156
+ if (winner.frontierBonus > 0) {
157
+ code = "frontier";
158
+ component = "frontier=" + winner.frontierBonus;
159
+ }
160
+ else if (winner.preferredTierBonus > 0) {
161
+ code = "preferred_tier";
162
+ component = "tier=" + winner.candidate.tier;
163
+ }
164
+ else if (winner.preferredCostBonus > 0) {
165
+ code = "preferred_cost";
166
+ component = "cost=" + winner.candidate.cost;
167
+ }
168
+ else if (winner.explicit || winner.declared) {
169
+ code = "capability_match";
170
+ component = "capability=" + (winner.explicit ? "explicit" : "declared");
171
+ }
172
+ else if (winner.priceAdj !== 0) {
173
+ code = "price";
174
+ component = "price=" + winner.priceAdj;
175
+ }
176
+ else {
177
+ code = "priority";
178
+ component = "priority=" + winner.candidate.priority;
179
+ }
180
+ const routingReason = {
181
+ code,
182
+ text: boundReasonText(`id=${winner.candidate.id} cost=${winner.candidate.cost} ${component} score=${winner.score}`),
183
+ matchedCapabilities,
184
+ score: winner.score,
185
+ budget: request.budget,
186
+ };
80
187
  return {
81
188
  id: winner.candidate.id,
82
189
  score: winner.score,
@@ -85,6 +192,7 @@ export function resolveModel(request) {
85
192
  ...(winner.candidate.priceOutput !== undefined ? { priceOutput: winner.candidate.priceOutput } : {}),
86
193
  reason: winner.reason,
87
194
  fallback,
195
+ routingReason,
88
196
  };
89
197
  }
90
198
  //# sourceMappingURL=model-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/routing/model-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/routing/model-resolver.ts"],"names":[],"mappings":"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"}
package/dist/spawn.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  export type SpawnSyncOptions = NonNullable<Parameters<typeof spawnSync>[2]>;
3
+ type SpawnSyncDependency = (command: string, args: string[], options: SpawnSyncOptions) => ReturnType<typeof spawnSync>;
4
+ export interface SpawnFallbackDependencies {
5
+ platform?: NodeJS.Platform;
6
+ spawnSync?: SpawnSyncDependency;
7
+ }
3
8
  /**
4
9
  * Quote a command line for cmd.exe: parts containing spaces or cmd
5
10
  * metacharacters are wrapped in double quotes so paths with spaces and
@@ -16,10 +21,18 @@ export declare function safeForCmdRetry(parts: string[]): boolean;
16
21
  * with EINVAL on CVE-2024-27980-patched Node). The retry is skipped for
17
22
  * inputs cmd.exe could reinterpret — see {@link safeForCmdRetry} — and
18
23
  * off-Windows the native result is always returned untouched.
24
+ *
25
+ * When a bare command name resolves to a `.cmd`/`.bat` shim ahead of any
26
+ * spawnable executable on Windows, the direct spawn is skipped entirely and
27
+ * the command runs through cmd.exe, mirroring cmd.exe's own resolution order.
28
+ * This keeps PATH-based shims authoritative even when a real `.exe` of the
29
+ * same name sits further down PATH (patched Node would otherwise bypass the
30
+ * shim and run the real tool).
19
31
  */
20
- export declare function spawnWithCmdFallback(command: string, args: string[], options?: SpawnSyncOptions): ReturnType<typeof spawnSync>;
32
+ export declare function spawnWithCmdFallback(command: string, args: string[], options?: SpawnSyncOptions, deps?: SpawnFallbackDependencies): ReturnType<typeof spawnSync>;
21
33
  /**
22
34
  * User home for tool discovery. Windows tests override HOME to shadow the
23
35
  * real per-user toolchain, so honor it before falling back to os.homedir().
24
36
  */
25
37
  export declare function homeDirectory(): string;
38
+ export {};