offrouter-core 0.2.0 → 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 +9 -4
  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
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Static provider/model catalog for offline subscription-first routing tests.
3
+ * No credential scraping; entries describe discovery shapes only.
4
+ */
5
+ import { selectBuiltinProviders, } from "./catalog-data.js";
6
+ /**
7
+ * Built-in catalog: for several families, ship subscription + local + api-key
8
+ * candidates so routing prefers subscription without live credentials.
9
+ */
10
+ export const STATIC_CATALOG = [
11
+ // frontier-coder across all three tiers
12
+ {
13
+ providerId: "claude-subscription",
14
+ modelId: "claude-sonnet-4",
15
+ displayName: "Claude Sonnet (subscription)",
16
+ family: "frontier-coder",
17
+ authTier: "subscription",
18
+ authScope: "first-party",
19
+ subscriptionStatus: "active",
20
+ health: "healthy",
21
+ supportsTools: true,
22
+ supportsStreaming: true,
23
+ supportsJson: true,
24
+ supportsImages: true,
25
+ contextWindowTokens: 200_000,
26
+ maxOutputTokens: 32_000,
27
+ estimatedCostUsd: 0,
28
+ notes: "Official harness subscription capacity",
29
+ },
30
+ {
31
+ providerId: "ollama",
32
+ modelId: "qwen2.5-coder:32b",
33
+ displayName: "Qwen2.5 Coder 32B (local)",
34
+ family: "frontier-coder",
35
+ authTier: "local",
36
+ authScope: "first-party",
37
+ health: "healthy",
38
+ supportsTools: true,
39
+ supportsStreaming: true,
40
+ supportsJson: true,
41
+ supportsImages: false,
42
+ contextWindowTokens: 32_768,
43
+ maxOutputTokens: 8_192,
44
+ estimatedCostUsd: 0,
45
+ },
46
+ {
47
+ providerId: "openrouter",
48
+ modelId: "anthropic/claude-sonnet-4",
49
+ displayName: "Claude Sonnet via OpenRouter",
50
+ family: "frontier-coder",
51
+ authTier: "api-key",
52
+ authScope: "third-party",
53
+ health: "healthy",
54
+ supportsTools: true,
55
+ supportsStreaming: true,
56
+ supportsJson: true,
57
+ supportsImages: true,
58
+ contextWindowTokens: 200_000,
59
+ maxOutputTokens: 32_000,
60
+ estimatedCostUsd: 0.03,
61
+ },
62
+ {
63
+ providerId: "xai",
64
+ modelId: "grok-code-fast-1",
65
+ displayName: "Grok Code Fast (api-key)",
66
+ family: "frontier-coder",
67
+ authTier: "api-key",
68
+ authScope: "first-party",
69
+ health: "healthy",
70
+ supportsTools: true,
71
+ supportsStreaming: true,
72
+ supportsJson: true,
73
+ supportsImages: false,
74
+ contextWindowTokens: 131_072,
75
+ maxOutputTokens: 16_384,
76
+ estimatedCostUsd: 0.02,
77
+ },
78
+ // fast-coder across tiers
79
+ {
80
+ providerId: "codex-subscription",
81
+ modelId: "gpt-5-codex",
82
+ displayName: "GPT Codex (subscription)",
83
+ family: "fast-coder",
84
+ authTier: "subscription",
85
+ authScope: "first-party",
86
+ subscriptionStatus: "active",
87
+ health: "healthy",
88
+ supportsTools: true,
89
+ supportsStreaming: true,
90
+ supportsJson: true,
91
+ supportsImages: false,
92
+ contextWindowTokens: 128_000,
93
+ maxOutputTokens: 16_384,
94
+ estimatedCostUsd: 0,
95
+ },
96
+ {
97
+ providerId: "lmstudio",
98
+ modelId: "local-fast-coder",
99
+ displayName: "Local Fast Coder",
100
+ family: "fast-coder",
101
+ authTier: "local",
102
+ authScope: "first-party",
103
+ health: "healthy",
104
+ supportsTools: true,
105
+ supportsStreaming: true,
106
+ supportsJson: true,
107
+ supportsImages: false,
108
+ contextWindowTokens: 16_384,
109
+ maxOutputTokens: 4_096,
110
+ estimatedCostUsd: 0,
111
+ },
112
+ {
113
+ providerId: "openrouter",
114
+ modelId: "openai/gpt-4.1-mini",
115
+ displayName: "GPT-4.1 Mini (OpenRouter)",
116
+ family: "fast-coder",
117
+ authTier: "api-key",
118
+ authScope: "third-party",
119
+ health: "healthy",
120
+ supportsTools: true,
121
+ supportsStreaming: true,
122
+ supportsJson: true,
123
+ supportsImages: false,
124
+ contextWindowTokens: 128_000,
125
+ maxOutputTokens: 16_384,
126
+ estimatedCostUsd: 0.005,
127
+ },
128
+ // local-coder family (local preferred; still include subscription / api-key siblings)
129
+ {
130
+ providerId: "ollama",
131
+ modelId: "deepseek-coder-v2:lite",
132
+ displayName: "DeepSeek Coder Lite (local)",
133
+ family: "local-coder",
134
+ authTier: "local",
135
+ authScope: "first-party",
136
+ health: "healthy",
137
+ supportsTools: true,
138
+ supportsStreaming: true,
139
+ supportsJson: true,
140
+ supportsImages: false,
141
+ contextWindowTokens: 16_384,
142
+ maxOutputTokens: 4_096,
143
+ estimatedCostUsd: 0,
144
+ },
145
+ {
146
+ providerId: "gemini-subscription",
147
+ modelId: "gemini-2.5-flash",
148
+ displayName: "Gemini Flash (subscription)",
149
+ family: "local-coder",
150
+ authTier: "subscription",
151
+ authScope: "first-party",
152
+ subscriptionStatus: "active",
153
+ health: "healthy",
154
+ supportsTools: true,
155
+ supportsStreaming: true,
156
+ supportsJson: true,
157
+ supportsImages: false,
158
+ contextWindowTokens: 1_000_000,
159
+ maxOutputTokens: 8_192,
160
+ estimatedCostUsd: 0,
161
+ },
162
+ {
163
+ providerId: "openrouter",
164
+ modelId: "deepseek/deepseek-coder",
165
+ displayName: "DeepSeek Coder (OpenRouter)",
166
+ family: "local-coder",
167
+ authTier: "api-key",
168
+ authScope: "third-party",
169
+ health: "healthy",
170
+ supportsTools: true,
171
+ supportsStreaming: true,
172
+ supportsJson: true,
173
+ supportsImages: false,
174
+ contextWindowTokens: 64_000,
175
+ maxOutputTokens: 8_192,
176
+ estimatedCostUsd: 0.002,
177
+ },
178
+ // vision-helper
179
+ {
180
+ providerId: "claude-subscription",
181
+ modelId: "claude-sonnet-4-vision",
182
+ displayName: "Claude Vision (subscription)",
183
+ family: "vision-helper",
184
+ authTier: "subscription",
185
+ authScope: "first-party",
186
+ subscriptionStatus: "active",
187
+ health: "healthy",
188
+ supportsTools: true,
189
+ supportsStreaming: true,
190
+ supportsJson: true,
191
+ supportsImages: true,
192
+ contextWindowTokens: 200_000,
193
+ maxOutputTokens: 16_384,
194
+ estimatedCostUsd: 0,
195
+ },
196
+ {
197
+ providerId: "openrouter",
198
+ modelId: "openai/gpt-4o",
199
+ displayName: "GPT-4o Vision (api-key)",
200
+ family: "vision-helper",
201
+ authTier: "api-key",
202
+ authScope: "third-party",
203
+ health: "healthy",
204
+ supportsTools: true,
205
+ supportsStreaming: true,
206
+ supportsJson: true,
207
+ supportsImages: true,
208
+ contextWindowTokens: 128_000,
209
+ maxOutputTokens: 16_384,
210
+ estimatedCostUsd: 0.04,
211
+ },
212
+ {
213
+ providerId: "ollama",
214
+ modelId: "llava:latest",
215
+ displayName: "LLaVA (local vision)",
216
+ family: "vision-helper",
217
+ authTier: "local",
218
+ authScope: "first-party",
219
+ health: "healthy",
220
+ supportsTools: false,
221
+ supportsStreaming: true,
222
+ supportsJson: false,
223
+ supportsImages: true,
224
+ contextWindowTokens: 4_096,
225
+ maxOutputTokens: 2_048,
226
+ estimatedCostUsd: 0,
227
+ },
228
+ // Degraded / unconfigured samples for status tests
229
+ {
230
+ providerId: "claude-subscription",
231
+ modelId: "claude-opus-4",
232
+ displayName: "Claude Opus (subscription exhausted)",
233
+ family: "frontier-coder",
234
+ authTier: "subscription",
235
+ authScope: "first-party",
236
+ subscriptionStatus: "exhausted",
237
+ health: "degraded",
238
+ supportsTools: true,
239
+ supportsStreaming: true,
240
+ supportsJson: true,
241
+ supportsImages: true,
242
+ contextWindowTokens: 200_000,
243
+ maxOutputTokens: 32_000,
244
+ estimatedCostUsd: 0,
245
+ },
246
+ {
247
+ providerId: "codex-subscription",
248
+ modelId: "o3",
249
+ displayName: "o3 (subscription unconfigured)",
250
+ family: "fast-coder",
251
+ authTier: "subscription",
252
+ authScope: "first-party",
253
+ subscriptionStatus: "unconfigured",
254
+ health: "dead",
255
+ supportsTools: true,
256
+ supportsStreaming: true,
257
+ supportsJson: true,
258
+ supportsImages: false,
259
+ contextWindowTokens: 200_000,
260
+ maxOutputTokens: 32_000,
261
+ estimatedCostUsd: 0,
262
+ },
263
+ ];
264
+ export function loadStaticCatalog(options = {}) {
265
+ const includeUnhealthy = options.includeUnhealthy ?? true;
266
+ return STATIC_CATALOG.filter((entry) => {
267
+ if (options.providerIds &&
268
+ !options.providerIds.includes(entry.providerId)) {
269
+ return false;
270
+ }
271
+ if (options.families && !options.families.includes(entry.family)) {
272
+ return false;
273
+ }
274
+ if (options.authTiers && !options.authTiers.includes(entry.authTier)) {
275
+ return false;
276
+ }
277
+ if (!includeUnhealthy && entry.health !== "healthy") {
278
+ return false;
279
+ }
280
+ return true;
281
+ }).map((e) => ({ ...e }));
282
+ }
283
+ export function catalogToCandidates(entries = STATIC_CATALOG) {
284
+ return entries.map((e) => ({
285
+ providerId: e.providerId,
286
+ modelId: e.modelId,
287
+ displayName: e.displayName,
288
+ authTier: e.authTier,
289
+ authScope: e.authScope,
290
+ subscriptionStatus: e.subscriptionStatus,
291
+ health: e.health,
292
+ supportsTools: e.supportsTools,
293
+ supportsStreaming: e.supportsStreaming,
294
+ supportsJson: e.supportsJson,
295
+ supportsImages: e.supportsImages,
296
+ contextWindowTokens: e.contextWindowTokens,
297
+ maxOutputTokens: e.maxOutputTokens,
298
+ estimatedCostUsd: e.estimatedCostUsd,
299
+ }));
300
+ }
301
+ /** Families that must expose all three auth tiers for offline preference tests. */
302
+ export const MULTI_TIER_FAMILIES = [
303
+ "frontier-coder",
304
+ "fast-coder",
305
+ "local-coder",
306
+ "vision-helper",
307
+ ];
308
+ export function familyAuthTiers(family) {
309
+ const tiers = new Set();
310
+ for (const e of STATIC_CATALOG) {
311
+ if (e.family === family)
312
+ tiers.add(e.authTier);
313
+ }
314
+ return tiers;
315
+ }
316
+ /** Flatten built-in provider metadata into catalog rows (copies). */
317
+ function builtinProvidersToEntries(providers) {
318
+ const entries = [];
319
+ for (const provider of providers) {
320
+ for (const model of provider.knownModels) {
321
+ entries.push({
322
+ providerId: provider.providerId,
323
+ modelId: model.modelId,
324
+ displayName: model.displayName ??
325
+ `${provider.displayName} ${model.modelId}`,
326
+ family: model.family,
327
+ authTier: provider.defaultAuthTier,
328
+ authScope: provider.defaultAuthScope,
329
+ health: "healthy",
330
+ supportsTools: model.supportsTools ?? true,
331
+ supportsStreaming: model.supportsStreaming ?? true,
332
+ supportsJson: model.supportsJson ?? true,
333
+ supportsImages: model.supportsImages ?? false,
334
+ contextWindowTokens: model.contextWindowTokens,
335
+ maxOutputTokens: model.maxOutputTokens,
336
+ notes: provider.subscriptionSurfaceNote,
337
+ });
338
+ }
339
+ }
340
+ return entries;
341
+ }
342
+ /**
343
+ * Structured dedup key for catalog rows. Serializes the discriminating fields
344
+ * as a JSON tuple so there is no ad hoc delimiter parsing or collision risk.
345
+ */
346
+ function catalogEntryDedupKey(entry) {
347
+ return JSON.stringify([
348
+ entry.providerId,
349
+ entry.modelId,
350
+ entry.authTier,
351
+ entry.family,
352
+ ]);
353
+ }
354
+ /**
355
+ * Load the merged built-in catalog: static rows plus built-in provider
356
+ * metadata, with provider enable/disable and base URL overrides applied.
357
+ * Existing static loading behavior (loadStaticCatalog) is unchanged.
358
+ */
359
+ export function loadBuiltinCatalog(options = {}) {
360
+ const includeUnhealthy = options.includeUnhealthy ?? true;
361
+ const config = options.providers ?? {};
362
+ const providerEnabled = (providerId) => config[providerId]?.enabled ?? true;
363
+ const builtinEntries = builtinProvidersToEntries(selectBuiltinProviders(config));
364
+ // Merge static catalog with built-in entries, applying the provider
365
+ // enable/disable filter to both sources and deduping identical rows.
366
+ const merged = [];
367
+ const seen = new Set();
368
+ const sources = [
369
+ ...STATIC_CATALOG.map((entry) => ({ ...entry })),
370
+ ...builtinEntries,
371
+ ];
372
+ for (const entry of sources) {
373
+ if (!providerEnabled(entry.providerId))
374
+ continue;
375
+ const key = catalogEntryDedupKey(entry);
376
+ if (seen.has(key))
377
+ continue;
378
+ seen.add(key);
379
+ merged.push(entry);
380
+ }
381
+ return merged.filter((entry) => {
382
+ if (options.families && !options.families.includes(entry.family)) {
383
+ return false;
384
+ }
385
+ if (options.authTiers && !options.authTiers.includes(entry.authTier)) {
386
+ return false;
387
+ }
388
+ if (!includeUnhealthy && entry.health !== "healthy") {
389
+ return false;
390
+ }
391
+ return true;
392
+ });
393
+ }
394
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/providers/catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Deterministic fake provider adapter for offline tests and MCP demos.
3
+ * Supports one-shot, streaming, configured errors, and cancellation.
4
+ */
5
+ import type { AuthTier, RouteRequest } from "../types.js";
6
+ import { ProviderError, type AuthStatus, type CostEstimate, type LimitSnapshot, type ModelCapability, type ProviderAdapter, type ProviderEvent, type ProviderInvokeRequest } from "./adapter.js";
7
+ export interface FakeModelConfig extends ModelCapability {
8
+ authTier?: AuthTier;
9
+ }
10
+ export interface FakeProviderOptions {
11
+ id?: string;
12
+ authTier?: AuthTier;
13
+ /** Presence-only flag; never stores a secret value. */
14
+ hasApiKey?: boolean;
15
+ limitsDiscoverable?: boolean;
16
+ opaqueLimits?: boolean;
17
+ remaining?: number;
18
+ limit?: number;
19
+ models?: FakeModelConfig[];
20
+ /** Fixed one-shot body when stream is false/omitted. */
21
+ responseText?: string;
22
+ /** Chunks for streaming invokes (token-ish pieces). */
23
+ streamChunks?: string[];
24
+ /** Delay between stream chunks in ms (default 0). */
25
+ streamDelayMs?: number;
26
+ /** If set, invoke throws/errors with this ProviderError. */
27
+ error?: ProviderError;
28
+ /** When true, delay long enough for cancel to win (default false). */
29
+ hangUntilCancel?: boolean;
30
+ estimatedCostUsd?: number;
31
+ }
32
+ export declare class FakeProviderAdapter implements ProviderAdapter {
33
+ readonly id: string;
34
+ private readonly options;
35
+ private readonly active;
36
+ private cancelled;
37
+ constructor(options?: FakeProviderOptions);
38
+ listModels(): Promise<ModelCapability[]>;
39
+ checkAuth(): Promise<AuthStatus>;
40
+ queryLimits(authTier: AuthTier): Promise<LimitSnapshot>;
41
+ estimate(request: RouteRequest, model: string, authTier: AuthTier): Promise<CostEstimate>;
42
+ invoke(request: ProviderInvokeRequest): AsyncIterable<ProviderEvent>;
43
+ cancel(callId: string): Promise<void>;
44
+ }
45
+ export declare function createFakeProvider(options?: FakeProviderOptions): FakeProviderAdapter;
46
+ //# sourceMappingURL=fake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake.d.ts","sourceRoot":"","sources":["../../src/providers/fake.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC3B,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,sEAAsE;IACtE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAgDD,qBAAa,mBAAoB,YAAW,eAAe;IACzD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAcF;IAEtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAC7D,OAAO,CAAC,SAAS,CAAqB;gBAE1B,OAAO,GAAE,mBAAwB;IAgBvC,UAAU,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAIxC,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IAiBhC,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IAyBvD,QAAQ,CACZ,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,CAAC;IAYjB,MAAM,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa,CAAC,aAAa,CAAC;IAgHrE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI5C;AAED,wBAAgB,kBAAkB,CAChC,OAAO,CAAC,EAAE,mBAAmB,GAC5B,mBAAmB,CAErB"}