offrouter-core 0.2.1 → 0.2.2

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 (139) hide show
  1. package/dist/audit.d.ts +137 -0
  2. package/dist/audit.d.ts.map +1 -0
  3. package/dist/audit.js +320 -0
  4. package/dist/audit.js.map +1 -0
  5. package/dist/auth/credential-chain.d.ts +84 -0
  6. package/dist/auth/credential-chain.d.ts.map +1 -0
  7. package/dist/auth/credential-chain.js +150 -0
  8. package/dist/auth/credential-chain.js.map +1 -0
  9. package/dist/auth/index.d.ts +10 -0
  10. package/dist/auth/index.d.ts.map +1 -0
  11. package/dist/auth/index.js +7 -0
  12. package/dist/auth/index.js.map +1 -0
  13. package/dist/auth/keychain.d.ts +60 -0
  14. package/dist/auth/keychain.d.ts.map +1 -0
  15. package/dist/auth/keychain.js +104 -0
  16. package/dist/auth/keychain.js.map +1 -0
  17. package/dist/auth/oauth-pkce.d.ts +138 -0
  18. package/dist/auth/oauth-pkce.d.ts.map +1 -0
  19. package/dist/auth/oauth-pkce.js +375 -0
  20. package/dist/auth/oauth-pkce.js.map +1 -0
  21. package/dist/auth/oauth-server.d.ts +36 -0
  22. package/dist/auth/oauth-server.d.ts.map +1 -0
  23. package/dist/auth/oauth-server.js +210 -0
  24. package/dist/auth/oauth-server.js.map +1 -0
  25. package/dist/config.d.ts +76 -0
  26. package/dist/config.d.ts.map +1 -0
  27. package/dist/config.js +355 -0
  28. package/dist/config.js.map +1 -0
  29. package/dist/delegation.d.ts +123 -0
  30. package/dist/delegation.d.ts.map +1 -0
  31. package/dist/delegation.js +455 -0
  32. package/dist/delegation.js.map +1 -0
  33. package/dist/index.d.ts +41 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +26 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/policy.d.ts +45 -0
  38. package/dist/policy.d.ts.map +1 -0
  39. package/dist/policy.js +318 -0
  40. package/dist/policy.js.map +1 -0
  41. package/{src/protocol.ts → dist/protocol.d.ts} +2 -2
  42. package/dist/protocol.d.ts.map +1 -0
  43. package/dist/protocol.js +6 -0
  44. package/dist/protocol.js.map +1 -0
  45. package/dist/providers/adapter.d.ts +137 -0
  46. package/dist/providers/adapter.d.ts.map +1 -0
  47. package/dist/providers/adapter.js +163 -0
  48. package/dist/providers/adapter.js.map +1 -0
  49. package/dist/providers/catalog-data.d.ts +128 -0
  50. package/dist/providers/catalog-data.d.ts.map +1 -0
  51. package/dist/providers/catalog-data.js +397 -0
  52. package/dist/providers/catalog-data.js.map +1 -0
  53. package/dist/providers/catalog.d.ts +63 -0
  54. package/dist/providers/catalog.d.ts.map +1 -0
  55. package/dist/providers/catalog.js +394 -0
  56. package/dist/providers/catalog.js.map +1 -0
  57. package/dist/providers/fake.d.ts +46 -0
  58. package/dist/providers/fake.d.ts.map +1 -0
  59. package/dist/providers/fake.js +234 -0
  60. package/dist/providers/fake.js.map +1 -0
  61. package/dist/providers/openai-compatible.d.ts +65 -0
  62. package/dist/providers/openai-compatible.d.ts.map +1 -0
  63. package/dist/providers/openai-compatible.js +434 -0
  64. package/dist/providers/openai-compatible.js.map +1 -0
  65. package/dist/proxy/responses-mapper.d.ts +366 -0
  66. package/dist/proxy/responses-mapper.d.ts.map +1 -0
  67. package/dist/proxy/responses-mapper.js +517 -0
  68. package/dist/proxy/responses-mapper.js.map +1 -0
  69. package/dist/proxy/responses-server.d.ts +29 -0
  70. package/dist/proxy/responses-server.d.ts.map +1 -0
  71. package/dist/proxy/responses-server.js +360 -0
  72. package/dist/proxy/responses-server.js.map +1 -0
  73. package/dist/router.d.ts +18 -0
  74. package/dist/router.d.ts.map +1 -0
  75. package/dist/router.js +296 -0
  76. package/dist/router.js.map +1 -0
  77. package/dist/schemas.d.ts +560 -0
  78. package/dist/schemas.d.ts.map +1 -0
  79. package/{src/schemas.ts → dist/schemas.js} +83 -103
  80. package/dist/schemas.js.map +1 -0
  81. package/dist/secrets.d.ts +112 -0
  82. package/dist/secrets.d.ts.map +1 -0
  83. package/dist/secrets.js +326 -0
  84. package/dist/secrets.js.map +1 -0
  85. package/dist/types.d.ts +117 -0
  86. package/dist/types.d.ts.map +1 -0
  87. package/dist/types.js +6 -0
  88. package/dist/types.js.map +1 -0
  89. package/dist/usage-file.d.ts +59 -0
  90. package/dist/usage-file.d.ts.map +1 -0
  91. package/dist/usage-file.js +316 -0
  92. package/dist/usage-file.js.map +1 -0
  93. package/dist/usage.d.ts +235 -0
  94. package/dist/usage.d.ts.map +1 -0
  95. package/dist/usage.js +517 -0
  96. package/dist/usage.js.map +1 -0
  97. package/package.json +7 -2
  98. package/src/audit.test.ts +0 -302
  99. package/src/audit.ts +0 -553
  100. package/src/auth/credential-chain.test.ts +0 -326
  101. package/src/auth/credential-chain.ts +0 -235
  102. package/src/auth/index.ts +0 -45
  103. package/src/auth/keychain.test.ts +0 -265
  104. package/src/auth/keychain.ts +0 -168
  105. package/src/auth/oauth-pkce.test.ts +0 -329
  106. package/src/auth/oauth-pkce.ts +0 -571
  107. package/src/auth/oauth-server.test.ts +0 -83
  108. package/src/auth/oauth-server.ts +0 -296
  109. package/src/config.test.ts +0 -479
  110. package/src/config.ts +0 -505
  111. package/src/delegation.test.ts +0 -368
  112. package/src/delegation.ts +0 -605
  113. package/src/index.ts +0 -280
  114. package/src/policy.test.ts +0 -634
  115. package/src/policy.ts +0 -420
  116. package/src/providers/adapter.test.ts +0 -293
  117. package/src/providers/adapter.ts +0 -328
  118. package/src/providers/catalog-data.test.ts +0 -258
  119. package/src/providers/catalog-data.ts +0 -498
  120. package/src/providers/catalog.test.ts +0 -84
  121. package/src/providers/catalog.ts +0 -483
  122. package/src/providers/fake.ts +0 -312
  123. package/src/providers/openai-compatible.test.ts +0 -366
  124. package/src/providers/openai-compatible.ts +0 -554
  125. package/src/proxy/responses-mapper.test.ts +0 -290
  126. package/src/proxy/responses-mapper.ts +0 -736
  127. package/src/proxy/responses-server.test.ts +0 -322
  128. package/src/proxy/responses-server.ts +0 -469
  129. package/src/router.test.ts +0 -699
  130. package/src/router.ts +0 -352
  131. package/src/schemas.test.ts +0 -291
  132. package/src/secrets.test.ts +0 -271
  133. package/src/secrets.ts +0 -461
  134. package/src/types.ts +0 -173
  135. package/src/usage-file.test.ts +0 -243
  136. package/src/usage-file.ts +0 -435
  137. package/src/usage.test.ts +0 -335
  138. package/src/usage.ts +0 -859
  139. package/tsconfig.json +0 -9
package/dist/router.js ADDED
@@ -0,0 +1,296 @@
1
+ /**
2
+ * Deterministic model scoring and route explain for OffRouter V1.
3
+ */
4
+ import { evaluatePolicy } from "./policy.js";
5
+ import { ROUTE_PROTOCOL_VERSION } from "./protocol.js";
6
+ function candidateId(c) {
7
+ return `${c.providerId}:${c.modelId}`;
8
+ }
9
+ /**
10
+ * Rank score: higher is better.
11
+ * Order of preference:
12
+ * 1. Healthy active subscription (status !== "near-limit")
13
+ * 2. Healthy near-limit subscription
14
+ * 3. Local
15
+ * 4. Degraded subscription (active + degraded)
16
+ * 5. API-key
17
+ * Within same tier: lower estimatedCostUsd, then providerId, then modelId.
18
+ */
19
+ function rankKey(c) {
20
+ let tierRank;
21
+ if (c.authTier === "subscription") {
22
+ if (c.health === "healthy") {
23
+ tierRank = c.subscriptionStatus === "near-limit" ? 350 : 400;
24
+ }
25
+ else if (c.health === "degraded") {
26
+ tierRank = 200;
27
+ }
28
+ else {
29
+ tierRank = 0;
30
+ }
31
+ }
32
+ else if (c.authTier === "local") {
33
+ tierRank = 300;
34
+ }
35
+ else {
36
+ // api-key
37
+ tierRank = 100;
38
+ }
39
+ // Invert cost so higher is better; missing cost treated as mid-ish.
40
+ const cost = c.estimatedCostUsd ?? 0.05;
41
+ const costScore = -cost;
42
+ return [tierRank, costScore, c.providerId, c.modelId];
43
+ }
44
+ function sortCandidates(candidates) {
45
+ return [...candidates].sort((a, b) => {
46
+ const ka = rankKey(a);
47
+ const kb = rankKey(b);
48
+ // tierRank desc
49
+ if (ka[0] !== kb[0])
50
+ return kb[0] - ka[0];
51
+ // costScore desc (higher costScore => cheaper)
52
+ if (ka[1] !== kb[1])
53
+ return kb[1] - ka[1];
54
+ if (a.providerId !== b.providerId) {
55
+ return a.providerId < b.providerId ? -1 : 1;
56
+ }
57
+ if (a.modelId !== b.modelId) {
58
+ return a.modelId < b.modelId ? -1 : 1;
59
+ }
60
+ return 0;
61
+ });
62
+ }
63
+ function selectionReason(winner) {
64
+ if (winner.authTier === "subscription") {
65
+ if (winner.health === "degraded") {
66
+ return {
67
+ reason: "subscription_degraded",
68
+ fallbackReason: "subscription_degraded",
69
+ explanation: `Selected degraded subscription candidate ${candidateId(winner)} as the best available subscription-backed route.`,
70
+ };
71
+ }
72
+ return {
73
+ reason: "subscription_primary",
74
+ fallbackReason: "primary",
75
+ explanation: `Selected healthy subscription-backed candidate ${candidateId(winner)} over lower-priority routes.`,
76
+ };
77
+ }
78
+ if (winner.authTier === "local") {
79
+ return {
80
+ reason: "local_preferred",
81
+ fallbackReason: "local_preferred",
82
+ explanation: `Selected local runtime candidate ${candidateId(winner)}.`,
83
+ };
84
+ }
85
+ return {
86
+ reason: "api_key_fallback",
87
+ fallbackReason: "api_key_fallback",
88
+ explanation: `Selected API-key candidate ${candidateId(winner)} because no healthy subscription candidate could satisfy the task.`,
89
+ };
90
+ }
91
+ function buildFallbackChain(sorted, winner) {
92
+ const { fallbackReason } = selectionReason(winner);
93
+ const chain = [
94
+ {
95
+ provider: winner.providerId,
96
+ model: winner.modelId,
97
+ authTier: winner.authTier,
98
+ reason: fallbackReason,
99
+ },
100
+ ];
101
+ // Include a short ordered list of alternative ranked candidates for explain.
102
+ for (const c of sorted) {
103
+ if (c.providerId === winner.providerId && c.modelId === winner.modelId) {
104
+ continue;
105
+ }
106
+ let reason = "primary";
107
+ if (c.authTier === "api-key") {
108
+ reason = "api_key_fallback";
109
+ }
110
+ else if (c.authTier === "local") {
111
+ reason = "local_preferred";
112
+ }
113
+ else if (c.health === "degraded") {
114
+ reason = "subscription_degraded";
115
+ }
116
+ else if (c.subscriptionStatus === "exhausted") {
117
+ reason = "subscription_exhausted";
118
+ }
119
+ else if (c.subscriptionStatus === "unconfigured") {
120
+ reason = "subscription_unconfigured";
121
+ }
122
+ chain.push({
123
+ provider: c.providerId,
124
+ model: c.modelId,
125
+ authTier: c.authTier,
126
+ reason,
127
+ });
128
+ if (chain.length >= 5)
129
+ break;
130
+ }
131
+ return chain;
132
+ }
133
+ function confidenceFor(winner, nAllowed) {
134
+ if (winner.authTier === "subscription" && winner.health === "healthy") {
135
+ return nAllowed === 1 ? 0.95 : 0.9;
136
+ }
137
+ if (winner.authTier === "local")
138
+ return 0.8;
139
+ if (winner.authTier === "subscription")
140
+ return 0.7;
141
+ return 0.6;
142
+ }
143
+ /**
144
+ * Route a request against candidates under policy.
145
+ * Pure and deterministic: same inputs -> same decision (except optional decisionId).
146
+ */
147
+ export function routeRequest(request, candidates, config, options = {}) {
148
+ const decisionId = options.decisionId ??
149
+ `dec_${request.requestId}_${candidates.length}_${request.harness.profile}`;
150
+ // Empty catalog -> needs configuration (even before profile denials, so
151
+ // tests/docs can distinguish "no providers set up"). But work profiles still
152
+ // block on policy; empty list with blocked profile binary is fine either way.
153
+ // Spec: "no candidate returns actionable needsConfiguration"
154
+ // Spec: "denied work profile returns blocked decision" (needsConfiguration false).
155
+ if (candidates.length === 0) {
156
+ // Still surface hard policy denials. Work/untrusted contexts should not
157
+ // be framed as "needs configuration".
158
+ const policy = evaluatePolicy(request, candidates, config);
159
+ const hardBlock = policy.denials.some((d) => d.code === "work_profile_denied" ||
160
+ d.code === "privacy_label_denied" ||
161
+ d.code === "project_untrusted");
162
+ if (hardBlock) {
163
+ return {
164
+ protocolVersion: ROUTE_PROTOCOL_VERSION,
165
+ decisionId,
166
+ requestId: request.requestId,
167
+ route: null,
168
+ reason: "policy_blocked",
169
+ explanation: policy.denials.map((d) => d.message).join(" "),
170
+ fallbackChain: [],
171
+ policyDenials: policy.denials,
172
+ confidence: 1,
173
+ auditSummary: `Blocked profile=${request.harness.profile} digests=${request.task.promptDigest}`,
174
+ blocked: true,
175
+ needsConfiguration: false,
176
+ };
177
+ }
178
+ return {
179
+ protocolVersion: ROUTE_PROTOCOL_VERSION,
180
+ decisionId,
181
+ requestId: request.requestId,
182
+ route: null,
183
+ reason: "no_candidate_needs_configuration",
184
+ explanation: "No provider candidates are available. Configure a subscription, local runtime, or API-key provider before routing.",
185
+ fallbackChain: [],
186
+ policyDenials: policy.denials,
187
+ confidence: 1,
188
+ auditSummary: `Needs configuration profile=${request.harness.profile} digest=${request.task.promptDigest}`,
189
+ blocked: true,
190
+ needsConfiguration: true,
191
+ };
192
+ }
193
+ const policy = evaluatePolicy(request, candidates, config);
194
+ if (policy.allowed.length === 0) {
195
+ const profileHardBlock = policy.denials.some((d) => d.code === "work_profile_denied" ||
196
+ d.code === "profile_not_allowlisted" ||
197
+ d.code === "project_untrusted");
198
+ // If candidates existed but all filtered: may be needsConfiguration when
199
+ // nothing is policy-profile blocked and no usable routes after hard filters.
200
+ const onlyCapabilityOrCostOrApiKey = policy.denials.every((d) => d.code === "capability_missing" ||
201
+ d.code === "cost_cap_exceeded" ||
202
+ d.code === "local_only_required" ||
203
+ d.code === "api_key_blocked_by_subscription_first_policy" ||
204
+ d.code === "provider_denied" ||
205
+ d.code === "subscription_scope_denied");
206
+ return {
207
+ protocolVersion: ROUTE_PROTOCOL_VERSION,
208
+ decisionId,
209
+ requestId: request.requestId,
210
+ route: null,
211
+ reason: profileHardBlock
212
+ ? "policy_blocked"
213
+ : onlyCapabilityOrCostOrApiKey
214
+ ? "no_allowed_candidate"
215
+ : "policy_blocked",
216
+ explanation: policy.denials.map((d) => d.message).join(" ") ||
217
+ "No allowed candidate remaining after policy evaluation.",
218
+ fallbackChain: [],
219
+ policyDenials: policy.denials,
220
+ confidence: 1,
221
+ auditSummary: `Blocked profile=${request.harness.profile} denials=${policy.denials.length} digest=${request.task.promptDigest}`,
222
+ blocked: true,
223
+ needsConfiguration: !profileHardBlock && policy.denials.length === 0,
224
+ };
225
+ }
226
+ const sorted = sortCandidates(policy.allowed);
227
+ const winner = sorted[0];
228
+ const { reason, explanation, fallbackReason } = selectionReason(winner);
229
+ // If winner is api-key but there were subscription denials for exhausted etc
230
+ // keep explanation accurate.
231
+ let finalExplanation = explanation;
232
+ if (winner.authTier === "api-key") {
233
+ const subExhausted = candidates.some((c) => c.authTier === "subscription" &&
234
+ (c.subscriptionStatus === "exhausted" ||
235
+ c.subscriptionStatus === "rate-limited"));
236
+ if (subExhausted) {
237
+ finalExplanation = `Selected API-key candidate ${candidateId(winner)} after subscription capacity was exhausted or rate-limited.`;
238
+ }
239
+ }
240
+ // Prefer primary reason label for true cheapest api-key when no subscription involved
241
+ let finalReason = reason;
242
+ let finalFallback = fallbackReason;
243
+ if (winner.authTier === "api-key" &&
244
+ !candidates.some((c) => c.authTier === "subscription")) {
245
+ finalReason = "primary";
246
+ finalFallback = "primary";
247
+ finalExplanation = `Selected cheap allowed candidate ${candidateId(winner)} for low-risk task.`;
248
+ }
249
+ const fallbackChain = buildFallbackChain(sorted, winner);
250
+ // Fix primary entry reason if we rewrote fallback reason
251
+ if (fallbackChain[0]) {
252
+ fallbackChain[0] = { ...fallbackChain[0], reason: finalFallback };
253
+ }
254
+ // Compute near-limit warning
255
+ let nearLimitWarning;
256
+ if (winner.authTier === "subscription" &&
257
+ winner.subscriptionStatus === "near-limit") {
258
+ const hasHealthyAlt = sorted.some((c) => c !== winner &&
259
+ c.authTier === "subscription" &&
260
+ c.health === "healthy" &&
261
+ c.subscriptionStatus !== "near-limit");
262
+ if (!hasHealthyAlt) {
263
+ const acct = winner.accountId ?? winner.providerId;
264
+ const pct = winner.subscriptionQuotaPercentRemaining;
265
+ const pctText = pct !== undefined ? ` (${Math.round(pct)}% remaining)` : "";
266
+ nearLimitWarning = `Your ${winner.providerId} subscription (${acct}) is near its limit${pctText}. Consider switching or adding another account.`;
267
+ }
268
+ }
269
+ if (nearLimitWarning) {
270
+ finalExplanation = `${finalExplanation} ${nearLimitWarning}`;
271
+ }
272
+ return {
273
+ protocolVersion: ROUTE_PROTOCOL_VERSION,
274
+ decisionId,
275
+ requestId: request.requestId,
276
+ route: {
277
+ provider: winner.providerId,
278
+ model: winner.modelId,
279
+ authTier: winner.authTier,
280
+ authScope: winner.authScope,
281
+ accountId: winner.accountId ?? winner.providerId,
282
+ },
283
+ reason: finalReason,
284
+ explanation: finalExplanation,
285
+ fallbackChain,
286
+ policyDenials: policy.denials,
287
+ confidence: confidenceFor(winner, policy.allowed.length),
288
+ auditSummary: `route=${winner.providerId}/${winner.modelId} tier=${winner.authTier} profile=${request.harness.profile} digest=${request.task.promptDigest}`,
289
+ blocked: false,
290
+ needsConfiguration: false,
291
+ nearLimitWarning,
292
+ };
293
+ }
294
+ /** @internal exported for focused testing */
295
+ export { sortCandidates };
296
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}