modelrig 0.0.1 → 0.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.
Files changed (220) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +115 -8
  3. package/dist/adapters/anthropic.d.ts +46 -0
  4. package/dist/adapters/anthropic.d.ts.map +1 -0
  5. package/dist/adapters/anthropic.js +202 -0
  6. package/dist/adapters/deepseek.d.ts +41 -0
  7. package/dist/adapters/deepseek.d.ts.map +1 -0
  8. package/dist/adapters/deepseek.js +163 -0
  9. package/dist/adapters/gemini.d.ts +44 -0
  10. package/dist/adapters/gemini.d.ts.map +1 -0
  11. package/dist/adapters/gemini.js +222 -0
  12. package/dist/adapters/grok.d.ts +44 -0
  13. package/dist/adapters/grok.d.ts.map +1 -0
  14. package/dist/adapters/grok.js +168 -0
  15. package/dist/adapters/openai-compat.d.ts +74 -0
  16. package/dist/adapters/openai-compat.d.ts.map +1 -0
  17. package/dist/adapters/openai-compat.js +187 -0
  18. package/dist/adapters/openai.d.ts +49 -0
  19. package/dist/adapters/openai.d.ts.map +1 -0
  20. package/dist/adapters/openai.js +222 -0
  21. package/dist/bakeoff/engine.d.ts +52 -0
  22. package/dist/bakeoff/engine.d.ts.map +1 -0
  23. package/dist/bakeoff/engine.js +163 -0
  24. package/dist/bakeoff/replay.d.ts +52 -0
  25. package/dist/bakeoff/replay.d.ts.map +1 -0
  26. package/dist/bakeoff/replay.js +94 -0
  27. package/dist/bakeoff/samples.d.ts +62 -0
  28. package/dist/bakeoff/samples.d.ts.map +1 -0
  29. package/dist/bakeoff/samples.js +128 -0
  30. package/dist/bakeoff/stats.d.ts +13 -0
  31. package/dist/bakeoff/stats.d.ts.map +1 -0
  32. package/dist/bakeoff/stats.js +48 -0
  33. package/dist/bakeoff/types.d.ts +37 -0
  34. package/dist/bakeoff/types.d.ts.map +1 -0
  35. package/dist/bakeoff/types.js +10 -0
  36. package/dist/cli.d.ts +27 -0
  37. package/dist/cli.d.ts.map +1 -0
  38. package/dist/cli.js +572 -0
  39. package/dist/config.d.ts +104 -0
  40. package/dist/config.d.ts.map +1 -0
  41. package/dist/config.js +148 -0
  42. package/dist/feedback/coverage.d.ts +32 -0
  43. package/dist/feedback/coverage.d.ts.map +1 -0
  44. package/dist/feedback/coverage.js +95 -0
  45. package/dist/feedback/feedback.d.ts +35 -0
  46. package/dist/feedback/feedback.d.ts.map +1 -0
  47. package/dist/feedback/feedback.js +39 -0
  48. package/dist/index.d.ts +155 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +448 -0
  51. package/dist/init/finder.d.ts +79 -0
  52. package/dist/init/finder.d.ts.map +1 -0
  53. package/dist/init/finder.js +297 -0
  54. package/dist/init/run.d.ts +99 -0
  55. package/dist/init/run.d.ts.map +1 -0
  56. package/dist/init/run.js +281 -0
  57. package/dist/init/signatures.d.ts +39 -0
  58. package/dist/init/signatures.d.ts.map +1 -0
  59. package/dist/init/signatures.js +116 -0
  60. package/dist/matrix/aggregate.d.ts +89 -0
  61. package/dist/matrix/aggregate.d.ts.map +1 -0
  62. package/dist/matrix/aggregate.js +186 -0
  63. package/dist/query/grammar.d.ts +35 -0
  64. package/dist/query/grammar.d.ts.map +1 -0
  65. package/dist/query/grammar.js +279 -0
  66. package/dist/query/run.d.ts +8 -0
  67. package/dist/query/run.d.ts.map +1 -0
  68. package/dist/query/run.js +21 -0
  69. package/dist/registry/build.d.ts +126 -0
  70. package/dist/registry/build.d.ts.map +1 -0
  71. package/dist/registry/build.js +192 -0
  72. package/dist/registry/call-notes.d.ts +11 -0
  73. package/dist/registry/call-notes.d.ts.map +1 -0
  74. package/dist/registry/call-notes.js +72 -0
  75. package/dist/registry/claims.d.ts +63 -0
  76. package/dist/registry/claims.d.ts.map +1 -0
  77. package/dist/registry/claims.js +107 -0
  78. package/dist/registry/facts.d.ts +32 -0
  79. package/dist/registry/facts.d.ts.map +1 -0
  80. package/dist/registry/facts.js +120 -0
  81. package/dist/registry/fingerprint.d.ts +20 -0
  82. package/dist/registry/fingerprint.d.ts.map +1 -0
  83. package/dist/registry/fingerprint.js +150 -0
  84. package/dist/registry/parity.d.ts +26 -0
  85. package/dist/registry/parity.d.ts.map +1 -0
  86. package/dist/registry/parity.js +41 -0
  87. package/dist/registry/pricing.d.ts +19 -0
  88. package/dist/registry/pricing.d.ts.map +1 -0
  89. package/dist/registry/pricing.js +69 -0
  90. package/dist/registry/rows.d.ts +16 -0
  91. package/dist/registry/rows.d.ts.map +1 -0
  92. package/dist/registry/rows.js +57 -0
  93. package/dist/registry/seed.d.ts +43 -0
  94. package/dist/registry/seed.d.ts.map +1 -0
  95. package/dist/registry/seed.js +97 -0
  96. package/dist/registry/select.d.ts +68 -0
  97. package/dist/registry/select.d.ts.map +1 -0
  98. package/dist/registry/select.js +141 -0
  99. package/dist/registry/staleness.d.ts +18 -0
  100. package/dist/registry/staleness.d.ts.map +1 -0
  101. package/dist/registry/staleness.js +39 -0
  102. package/dist/routes/draft.d.ts +83 -0
  103. package/dist/routes/draft.d.ts.map +1 -0
  104. package/dist/routes/draft.js +135 -0
  105. package/dist/routes/loader.d.ts +26 -0
  106. package/dist/routes/loader.d.ts.map +1 -0
  107. package/dist/routes/loader.js +436 -0
  108. package/dist/routes/manifest.d.ts +24 -0
  109. package/dist/routes/manifest.d.ts.map +1 -0
  110. package/dist/routes/manifest.js +118 -0
  111. package/dist/routes/serveability.d.ts +52 -0
  112. package/dist/routes/serveability.d.ts.map +1 -0
  113. package/dist/routes/serveability.js +73 -0
  114. package/dist/routes/template.d.ts +18 -0
  115. package/dist/routes/template.d.ts.map +1 -0
  116. package/dist/routes/template.js +94 -0
  117. package/dist/run/cost.d.ts +26 -0
  118. package/dist/run/cost.d.ts.map +1 -0
  119. package/dist/run/cost.js +41 -0
  120. package/dist/run/envelope.d.ts +21 -0
  121. package/dist/run/envelope.d.ts.map +1 -0
  122. package/dist/run/envelope.js +45 -0
  123. package/dist/run/grounding.d.ts +56 -0
  124. package/dist/run/grounding.d.ts.map +1 -0
  125. package/dist/run/grounding.js +89 -0
  126. package/dist/run/repair.d.ts +36 -0
  127. package/dist/run/repair.d.ts.map +1 -0
  128. package/dist/run/repair.js +61 -0
  129. package/dist/run/resolve.d.ts +26 -0
  130. package/dist/run/resolve.d.ts.map +1 -0
  131. package/dist/run/resolve.js +81 -0
  132. package/dist/run/retry.d.ts +19 -0
  133. package/dist/run/retry.d.ts.map +1 -0
  134. package/dist/run/retry.js +50 -0
  135. package/dist/run/run.d.ts +41 -0
  136. package/dist/run/run.d.ts.map +1 -0
  137. package/dist/run/run.js +0 -0
  138. package/dist/run/validate.d.ts +15 -0
  139. package/dist/run/validate.d.ts.map +1 -0
  140. package/dist/run/validate.js +56 -0
  141. package/dist/savings/emit.d.ts +25 -0
  142. package/dist/savings/emit.d.ts.map +1 -0
  143. package/dist/savings/emit.js +75 -0
  144. package/dist/savings/odometer.d.ts +32 -0
  145. package/dist/savings/odometer.d.ts.map +1 -0
  146. package/dist/savings/odometer.js +70 -0
  147. package/dist/savings/swap-execute.d.ts +44 -0
  148. package/dist/savings/swap-execute.d.ts.map +1 -0
  149. package/dist/savings/swap-execute.js +87 -0
  150. package/dist/savings/swaps-client.d.ts +41 -0
  151. package/dist/savings/swaps-client.d.ts.map +1 -0
  152. package/dist/savings/swaps-client.js +81 -0
  153. package/dist/telemetry/capture.d.ts +28 -0
  154. package/dist/telemetry/capture.d.ts.map +1 -0
  155. package/dist/telemetry/capture.js +74 -0
  156. package/dist/telemetry/exporter.d.ts +62 -0
  157. package/dist/telemetry/exporter.d.ts.map +1 -0
  158. package/dist/telemetry/exporter.js +233 -0
  159. package/dist/telemetry/ingest-protocol.d.ts +161 -0
  160. package/dist/telemetry/ingest-protocol.d.ts.map +1 -0
  161. package/dist/telemetry/ingest-protocol.js +163 -0
  162. package/dist/telemetry/sinks.d.ts +54 -0
  163. package/dist/telemetry/sinks.d.ts.map +1 -0
  164. package/dist/telemetry/sinks.js +89 -0
  165. package/dist/telemetry/store.d.ts +38 -0
  166. package/dist/telemetry/store.d.ts.map +1 -0
  167. package/dist/telemetry/store.js +332 -0
  168. package/dist/telemetry/supabase-exporter.d.ts +64 -0
  169. package/dist/telemetry/supabase-exporter.d.ts.map +1 -0
  170. package/dist/telemetry/supabase-exporter.js +211 -0
  171. package/dist/tenancy/api-key-format.d.ts +67 -0
  172. package/dist/tenancy/api-key-format.d.ts.map +1 -0
  173. package/dist/tenancy/api-key-format.js +91 -0
  174. package/dist/tenancy/constants.d.ts +23 -0
  175. package/dist/tenancy/constants.d.ts.map +1 -0
  176. package/dist/tenancy/constants.js +25 -0
  177. package/dist/tenancy/scrub.d.ts +47 -0
  178. package/dist/tenancy/scrub.d.ts.map +1 -0
  179. package/dist/tenancy/scrub.js +85 -0
  180. package/dist/types/failures-teaching.d.ts +56 -0
  181. package/dist/types/failures-teaching.d.ts.map +1 -0
  182. package/dist/types/failures-teaching.js +177 -0
  183. package/dist/types/failures.d.ts +27 -0
  184. package/dist/types/failures.d.ts.map +1 -0
  185. package/dist/types/failures.js +41 -0
  186. package/dist/types/provider.d.ts +79 -0
  187. package/dist/types/provider.d.ts.map +1 -0
  188. package/dist/types/provider.js +20 -0
  189. package/dist/types/route.d.ts +127 -0
  190. package/dist/types/route.d.ts.map +1 -0
  191. package/dist/types/route.js +6 -0
  192. package/dist/types/telemetry.d.ts +89 -0
  193. package/dist/types/telemetry.d.ts.map +1 -0
  194. package/dist/types/telemetry.js +6 -0
  195. package/dist/watch/budget.d.ts +19 -0
  196. package/dist/watch/budget.d.ts.map +1 -0
  197. package/dist/watch/budget.js +35 -0
  198. package/dist/watch/evaluate.d.ts +66 -0
  199. package/dist/watch/evaluate.d.ts.map +1 -0
  200. package/dist/watch/evaluate.js +94 -0
  201. package/dist/watch/proposals.d.ts +73 -0
  202. package/dist/watch/proposals.d.ts.map +1 -0
  203. package/dist/watch/proposals.js +169 -0
  204. package/dist/watch/run-record.d.ts +64 -0
  205. package/dist/watch/run-record.d.ts.map +1 -0
  206. package/dist/watch/run-record.js +86 -0
  207. package/dist/watch/run-reported.d.ts +20 -0
  208. package/dist/watch/run-reported.d.ts.map +1 -0
  209. package/dist/watch/run-reported.js +53 -0
  210. package/dist/watch/run.d.ts +40 -0
  211. package/dist/watch/run.d.ts.map +1 -0
  212. package/dist/watch/run.js +44 -0
  213. package/dist/watch/state-store.d.ts +48 -0
  214. package/dist/watch/state-store.d.ts.map +1 -0
  215. package/dist/watch/state-store.js +86 -0
  216. package/dist/watch/state.d.ts +21 -0
  217. package/dist/watch/state.d.ts.map +1 -0
  218. package/dist/watch/state.js +93 -0
  219. package/package.json +50 -14
  220. package/index.js +0 -3
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Generic openai-compatible adapter — Phase 4 addendum A1
3
+ * (provider-coverage-plan §1: "the DeepSeek adapter is its
4
+ * parameterization"). One adapter covers every OpenAI-dialect host; what
5
+ * varies is INJECTED: base URL, auth key, model-id shaping, and — the
6
+ * doctrine part — the per-model capability profile READ FROM THE REGISTRY.
7
+ * Speaking the dialect proves nothing: strict schema enforcement, caching,
8
+ * grounding are all probe-established facts, never dialect assumptions.
9
+ *
10
+ * Host quirks referenced from LiteLLM's per-provider transformation modules
11
+ * (vendor/litellm-upstream/litellm/llms/{deepinfra,fireworks_ai}/):
12
+ * DeepInfra base URL https://api.deepinfra.com/v1/openai (standard Bearer,
13
+ * OpenAI params incl. response_format); Fireworks base URL
14
+ * https://api.fireworks.ai/inference/v1 with model ids on the wire as
15
+ * accounts/fireworks/models/<short>.
16
+ * Portions derived from LiteLLM (https://github.com/BerriAI/litellm),
17
+ * Copyright (c) 2023 Berri AI, MIT License — retained per
18
+ * litellm-vendoring-strategy.md.
19
+ */
20
+ import type { CapabilityFlag, ProviderAdapter, ProviderId } from "../types/provider";
21
+ import type { ClassifiedFailure, ShapingInput } from "./gemini";
22
+ /** Fireworks serves models at accounts/fireworks/models/<short> — routes
23
+ * declare the short name; the wire gets the full path (LiteLLM
24
+ * fireworks_ai transformation, harvested). */
25
+ export declare function shapeFireworksModelId(model: string): string;
26
+ export interface OpenAICompatHost {
27
+ readonly baseUrl: string;
28
+ readonly shapeModelId?: (model: string) => string;
29
+ }
30
+ /** The researched Tier-2 hosts (provider-coverage-plan §2, architect pick
31
+ * 2026-08-02): DeepInfra (widest open catalog, lowest price) + Fireworks
32
+ * (SOC 2/HIPAA reliability counterweight). Same weights on both on purpose
33
+ * — host-level conformance/latency/price deltas become registry facts. */
34
+ export declare const OPENAI_COMPAT_HOSTS: Readonly<Record<"deepinfra" | "fireworks", OpenAICompatHost>>;
35
+ export declare function classifyCompatFailure(message: string, host: string): ClassifiedFailure;
36
+ interface ChatMessage {
37
+ readonly role: "system" | "user";
38
+ readonly content: string;
39
+ }
40
+ export interface OpenAICompatShapedParams {
41
+ readonly model: string;
42
+ readonly max_tokens: number;
43
+ readonly messages: readonly ChatMessage[];
44
+ readonly stream: true;
45
+ readonly stream_options: {
46
+ readonly include_usage: true;
47
+ };
48
+ readonly response_format?: {
49
+ readonly type: "json_object";
50
+ } | {
51
+ readonly type: "json_schema";
52
+ readonly json_schema: {
53
+ readonly name: string;
54
+ readonly strict: true;
55
+ readonly schema: object;
56
+ };
57
+ };
58
+ }
59
+ /** Pure request shaping. The PROFILE decides the wire shape: strict
60
+ * json_schema only when the registry granted structured_native for this
61
+ * model; else json_object (ajv still arbitrates above). */
62
+ export declare function buildOpenAICompatParams(model: string, req: ShapingInput, profileFlags: ReadonlySet<CapabilityFlag>): OpenAICompatShapedParams;
63
+ export interface OpenAICompatAdapterConfig {
64
+ readonly providerId: ProviderId;
65
+ readonly baseUrl: string;
66
+ readonly apiKey: string;
67
+ readonly shapeModelId?: (model: string) => string;
68
+ /** Registry-fed per-model capability flags — the ONLY capability source.
69
+ * The conservative dialect baseline is json_mode alone. */
70
+ readonly capabilityProfile: (model: string) => ReadonlySet<CapabilityFlag>;
71
+ }
72
+ export declare function createOpenAICompatAdapter(config: OpenAICompatAdapterConfig): ProviderAdapter;
73
+ export {};
74
+ //# sourceMappingURL=openai-compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-compat.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EACf,UAAU,EACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAIhE;;8CAE8C;AAC9C,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACnD;AAED;;;0EAG0E;AAC1E,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,GAAG,WAAW,EAAE,gBAAgB,CAAC,CAG7F,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAiBtF;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,QAAQ,CAAC,eAAe,CAAC,EACrB;QAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;KAAE,GAChC;QACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KACjG,CAAC;CACP;AAOD;;2DAE2D;AAC3D,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,YAAY,EACjB,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,GACxC,wBAAwB,CA4B1B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD;+DAC2D;IAC3D,QAAQ,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC,cAAc,CAAC,CAAC;CAC5E;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,eAAe,CAqH5F"}
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ /**
3
+ * Generic openai-compatible adapter — Phase 4 addendum A1
4
+ * (provider-coverage-plan §1: "the DeepSeek adapter is its
5
+ * parameterization"). One adapter covers every OpenAI-dialect host; what
6
+ * varies is INJECTED: base URL, auth key, model-id shaping, and — the
7
+ * doctrine part — the per-model capability profile READ FROM THE REGISTRY.
8
+ * Speaking the dialect proves nothing: strict schema enforcement, caching,
9
+ * grounding are all probe-established facts, never dialect assumptions.
10
+ *
11
+ * Host quirks referenced from LiteLLM's per-provider transformation modules
12
+ * (vendor/litellm-upstream/litellm/llms/{deepinfra,fireworks_ai}/):
13
+ * DeepInfra base URL https://api.deepinfra.com/v1/openai (standard Bearer,
14
+ * OpenAI params incl. response_format); Fireworks base URL
15
+ * https://api.fireworks.ai/inference/v1 with model ids on the wire as
16
+ * accounts/fireworks/models/<short>.
17
+ * Portions derived from LiteLLM (https://github.com/BerriAI/litellm),
18
+ * Copyright (c) 2023 Berri AI, MIT License — retained per
19
+ * litellm-vendoring-strategy.md.
20
+ */
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.OPENAI_COMPAT_HOSTS = void 0;
26
+ exports.shapeFireworksModelId = shapeFireworksModelId;
27
+ exports.classifyCompatFailure = classifyCompatFailure;
28
+ exports.buildOpenAICompatParams = buildOpenAICompatParams;
29
+ exports.createOpenAICompatAdapter = createOpenAICompatAdapter;
30
+ const openai_1 = __importDefault(require("openai"));
31
+ const DEFAULT_MAX_TOKENS = 32000;
32
+ /** Fireworks serves models at accounts/fireworks/models/<short> — routes
33
+ * declare the short name; the wire gets the full path (LiteLLM
34
+ * fireworks_ai transformation, harvested). */
35
+ function shapeFireworksModelId(model) {
36
+ return model.startsWith("accounts/") ? model : `accounts/fireworks/models/${model}`;
37
+ }
38
+ /** The researched Tier-2 hosts (provider-coverage-plan §2, architect pick
39
+ * 2026-08-02): DeepInfra (widest open catalog, lowest price) + Fireworks
40
+ * (SOC 2/HIPAA reliability counterweight). Same weights on both on purpose
41
+ * — host-level conformance/latency/price deltas become registry facts. */
42
+ exports.OPENAI_COMPAT_HOSTS = {
43
+ deepinfra: { baseUrl: "https://api.deepinfra.com/v1/openai" },
44
+ fireworks: { baseUrl: "https://api.fireworks.ai/inference/v1", shapeModelId: shapeFireworksModelId },
45
+ };
46
+ function classifyCompatFailure(message, host) {
47
+ const msg = message.toLowerCase();
48
+ if (/\b429\b|rate limit|\brate\b/.test(msg))
49
+ return { cls: "capacity_shed" };
50
+ if (/\b50[023]\b|service unavailable|overloaded/.test(msg))
51
+ return { cls: "capacity_shed" };
52
+ if (/timeout|etimedout|abort/.test(msg))
53
+ return { cls: "timeout" };
54
+ if (/econnreset|econnrefused|enotfound|fetch failed|network/.test(msg))
55
+ return { cls: "network" };
56
+ if (/\b401\b|\b403\b|api key|unauthorized/.test(msg)) {
57
+ // F2: non-retryable — a dead key never burns backoff retries.
58
+ return { cls: "config_auth", fixHint: `check the ${host} API key configured for this rig` };
59
+ }
60
+ if (/not found|does not exist/.test(msg)) {
61
+ return {
62
+ cls: "network",
63
+ fixHint: "the candidate model was not found — fix the model id in the route's candidate list",
64
+ };
65
+ }
66
+ return { cls: "network" };
67
+ }
68
+ /** json_object mode 400s on several compat backends when the literal word
69
+ * "JSON" appears nowhere in the prompt (the DeepSeek-family quirk; coached
70
+ * prompts normally guarantee it — this is belt-and-suspenders). */
71
+ const JSON_GUARD = "Respond with a single valid JSON object.";
72
+ /** Pure request shaping. The PROFILE decides the wire shape: strict
73
+ * json_schema only when the registry granted structured_native for this
74
+ * model; else json_object (ajv still arbitrates above). */
75
+ function buildOpenAICompatParams(model, req, profileFlags) {
76
+ const wantJson = req.outputSchema !== null;
77
+ const strict = wantJson && profileFlags.has("structured_native");
78
+ let systemPrompt = req.systemPrompt;
79
+ if (wantJson && !strict && !req.systemPrompt.includes("JSON") && !req.userPrompt.includes("JSON")) {
80
+ systemPrompt = systemPrompt === "" ? JSON_GUARD : `${systemPrompt}\n\n${JSON_GUARD}`;
81
+ }
82
+ const messages = [
83
+ ...(systemPrompt !== "" ? [{ role: "system", content: systemPrompt }] : []),
84
+ { role: "user", content: req.userPrompt },
85
+ ];
86
+ return {
87
+ model,
88
+ max_tokens: req.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
89
+ messages,
90
+ stream: true,
91
+ stream_options: { include_usage: true },
92
+ ...(wantJson
93
+ ? strict
94
+ ? {
95
+ response_format: {
96
+ type: "json_schema",
97
+ json_schema: { name: "output", strict: true, schema: req.outputSchema },
98
+ },
99
+ }
100
+ : { response_format: { type: "json_object" } }
101
+ : {}),
102
+ };
103
+ }
104
+ function createOpenAICompatAdapter(config) {
105
+ const shapeModel = config.shapeModelId ?? ((m) => m);
106
+ return {
107
+ id: config.providerId,
108
+ supports(feature, model) {
109
+ return config.capabilityProfile(model).has(feature);
110
+ },
111
+ async call(req) {
112
+ const model = req.candidate.model;
113
+ const fail = (cls, message, fixHint, usage) => ({
114
+ ok: false,
115
+ failure: {
116
+ class: cls,
117
+ message,
118
+ provider: config.providerId,
119
+ model,
120
+ ...(fixHint !== undefined ? { fixHint } : {}),
121
+ },
122
+ ...(usage !== undefined ? { usage } : {}),
123
+ });
124
+ try {
125
+ const client = new openai_1.default({
126
+ apiKey: config.apiKey,
127
+ baseURL: config.baseUrl,
128
+ timeout: req.timeoutMs,
129
+ });
130
+ const params = buildOpenAICompatParams(shapeModel(model), req, config.capabilityProfile(model));
131
+ const dispatchedAt = Date.now();
132
+ const stream = await client.chat.completions.create(params);
133
+ let text = "";
134
+ let promptTokens = 0;
135
+ let completionTokens = 0;
136
+ let cachedTokens = 0;
137
+ let finishReason = null;
138
+ // TTFB (Phase 4 WS3): first streamed chunk = first body byte.
139
+ let ttfbMs;
140
+ for await (const chunk of stream) {
141
+ if (ttfbMs === undefined)
142
+ ttfbMs = Date.now() - dispatchedAt;
143
+ const choice = chunk.choices[0];
144
+ if (choice?.delta?.content)
145
+ text += choice.delta.content;
146
+ if (choice?.finish_reason)
147
+ finishReason = choice.finish_reason;
148
+ if (chunk.usage) {
149
+ promptTokens = chunk.usage.prompt_tokens ?? 0;
150
+ completionTokens = chunk.usage.completion_tokens ?? 0;
151
+ cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;
152
+ }
153
+ }
154
+ // Hosts have no service tiers in this dialect — standard, always.
155
+ const usage = {
156
+ tokensIn: promptTokens,
157
+ tokensOut: completionTokens,
158
+ tokensCached: cachedTokens,
159
+ servedTier: "standard",
160
+ ...(ttfbMs !== undefined ? { ttfbMs } : {}),
161
+ };
162
+ if (text.trim().length === 0) {
163
+ return fail("content_invalid", `empty response from ${config.providerId} (finish_reason=${finishReason ?? "none"})`, undefined, usage);
164
+ }
165
+ if (finishReason === "length" && req.outputSchema !== null) {
166
+ return fail("content_invalid", `${config.providerId} JSON output truncated (finish_reason=length)`, "raise maxOutputTokens for this route", usage);
167
+ }
168
+ return { ok: true, text, usage };
169
+ }
170
+ catch (error) {
171
+ const message = error instanceof Error ? error.message : String(error);
172
+ const { cls, fixHint } = classifyCompatFailure(message, config.providerId);
173
+ return {
174
+ ok: false,
175
+ failure: {
176
+ class: cls,
177
+ message,
178
+ provider: config.providerId,
179
+ model,
180
+ cause: error,
181
+ ...(fixHint !== undefined ? { fixHint } : {}),
182
+ },
183
+ };
184
+ }
185
+ },
186
+ };
187
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * OpenAI ProviderAdapter — plan step 5.
3
+ * Transformation logic ported from apps/api/src/services/openai-provider.ts:
4
+ * response_format json_schema strict, service tiers (flex allowlist + served
5
+ * tier from the stream), prompt-cache key + retention passthrough, streaming
6
+ * with usage, structured-output refusal detection, suspicious-short guard.
7
+ * NOT ported: logging, pricing tables, env reads, the analyst-persona system
8
+ * prompt (route templates own prompt content).
9
+ *
10
+ * Portions may be derived from LiteLLM (https://github.com/BerriAI/litellm),
11
+ * Copyright (c) 2023 Berri AI, MIT License — retain this notice if LiteLLM's
12
+ * openai transformation logic is consulted during the port.
13
+ */
14
+ import type { CapabilityFlag, ProviderAdapter } from "../types/provider";
15
+ import type { ClassifiedFailure, ShapingInput } from "./gemini";
16
+ export interface OpenAIAdapterConfig {
17
+ readonly apiKey: string;
18
+ }
19
+ export declare function isModelFlexEligible(modelName: string): boolean;
20
+ export declare function openaiSupports(feature: CapabilityFlag, model: string): boolean;
21
+ export declare function classifyOpenAIFailure(message: string): ClassifiedFailure;
22
+ interface ChatMessage {
23
+ readonly role: "system" | "user";
24
+ readonly content: string;
25
+ }
26
+ export interface OpenAIShapedParams {
27
+ readonly model: string;
28
+ readonly max_completion_tokens: number;
29
+ readonly messages: readonly ChatMessage[];
30
+ readonly stream: true;
31
+ readonly stream_options: {
32
+ readonly include_usage: true;
33
+ };
34
+ readonly service_tier?: "flex" | "priority";
35
+ readonly prompt_cache_key?: string;
36
+ readonly prompt_cache_retention?: "24h";
37
+ readonly response_format?: {
38
+ readonly type: "json_schema";
39
+ readonly json_schema: {
40
+ readonly name: string;
41
+ readonly schema: object;
42
+ readonly strict: true;
43
+ };
44
+ };
45
+ }
46
+ export declare function buildOpenAIParams(model: string, req: ShapingInput): OpenAIShapedParams;
47
+ export declare function createOpenAIAdapter(config: OpenAIAdapterConfig): ProviderAdapter;
48
+ export {};
49
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAI9D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAc9E;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAiBxE;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,KAAK,CAAC;IACxC,QAAQ,CAAC,eAAe,CAAC,EAAE;QACzB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;SAAE,CAAC;KACjG,CAAC;CACH;AAID,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,kBAAkB,CAoCtF;AAcD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,eAAe,CAiJhF"}
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI ProviderAdapter — plan step 5.
4
+ * Transformation logic ported from apps/api/src/services/openai-provider.ts:
5
+ * response_format json_schema strict, service tiers (flex allowlist + served
6
+ * tier from the stream), prompt-cache key + retention passthrough, streaming
7
+ * with usage, structured-output refusal detection, suspicious-short guard.
8
+ * NOT ported: logging, pricing tables, env reads, the analyst-persona system
9
+ * prompt (route templates own prompt content).
10
+ *
11
+ * Portions may be derived from LiteLLM (https://github.com/BerriAI/litellm),
12
+ * Copyright (c) 2023 Berri AI, MIT License — retain this notice if LiteLLM's
13
+ * openai transformation logic is consulted during the port.
14
+ */
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.isModelFlexEligible = isModelFlexEligible;
20
+ exports.openaiSupports = openaiSupports;
21
+ exports.classifyOpenAIFailure = classifyOpenAIFailure;
22
+ exports.buildOpenAIParams = buildOpenAIParams;
23
+ exports.createOpenAIAdapter = createOpenAIAdapter;
24
+ const openai_1 = __importDefault(require("openai"));
25
+ /** OpenAI's documented flex-eligible allowlist as of 2026-05 (ported).
26
+ * Mini and nano variants are silently downgraded to default tier. */
27
+ const FLEX_ELIGIBLE_PREFIXES = ["gpt-5.4", "gpt-5.2", "gpt-5.1", "gpt-5", "gpt-4.1"];
28
+ function isModelFlexEligible(modelName) {
29
+ if (!modelName)
30
+ return false;
31
+ if (modelName.includes("-mini") || modelName.includes("-nano"))
32
+ return false;
33
+ return FLEX_ELIGIBLE_PREFIXES.some((prefix) => modelName.startsWith(prefix));
34
+ }
35
+ function openaiSupports(feature, model) {
36
+ switch (feature) {
37
+ case "structured_native":
38
+ case "json_mode":
39
+ case "prompt_cache_key":
40
+ case "prefix_cache_implicit":
41
+ return true;
42
+ case "tier_flex":
43
+ return isModelFlexEligible(model);
44
+ case "grounded_native":
45
+ case "context_cache_explicit":
46
+ case "trace_visible": // reasoning tokens are billed but never exposed
47
+ return false;
48
+ }
49
+ }
50
+ function classifyOpenAIFailure(message) {
51
+ const msg = message.toLowerCase();
52
+ if (/\b429\b|rate limit|\brate\b/.test(msg))
53
+ return { cls: "capacity_shed" };
54
+ if (/\b50[023]\b|service unavailable|overloaded/.test(msg))
55
+ return { cls: "capacity_shed" };
56
+ if (/timeout|etimedout|abort/.test(msg))
57
+ return { cls: "timeout" };
58
+ if (/econnreset|econnrefused|enotfound|fetch failed|network/.test(msg))
59
+ return { cls: "network" };
60
+ if (/\b401\b|api key/.test(msg)) {
61
+ // F2: non-retryable — a dead key never burns backoff retries.
62
+ return { cls: "config_auth", fixHint: "check the OpenAI API key configured for this rig" };
63
+ }
64
+ if (/does not exist|not found|\bmodel\b.*invalid/.test(msg)) {
65
+ return {
66
+ cls: "network",
67
+ fixHint: "the candidate model was not found — fix the model id in the route's candidate list",
68
+ };
69
+ }
70
+ return { cls: "network" };
71
+ }
72
+ const DEFAULT_MAX_COMPLETION_TOKENS = 32000;
73
+ function buildOpenAIParams(model, req) {
74
+ const messages = [
75
+ ...(req.systemPrompt !== "" ? [{ role: "system", content: req.systemPrompt }] : []),
76
+ { role: "user", content: req.userPrompt },
77
+ ];
78
+ return {
79
+ model,
80
+ max_completion_tokens: req.maxOutputTokens ?? DEFAULT_MAX_COMPLETION_TOKENS,
81
+ messages,
82
+ stream: true,
83
+ stream_options: { include_usage: true },
84
+ ...(req.requestedTier === "flex"
85
+ ? { service_tier: "flex" }
86
+ : req.requestedTier === "priority"
87
+ ? { service_tier: "priority" }
88
+ : {}),
89
+ ...(req.cache?.key !== undefined && req.cache.key !== ""
90
+ ? {
91
+ prompt_cache_key: req.cache.key,
92
+ // Extended retention only when the directive asks for a day or more.
93
+ ...((req.cache.ttlSeconds ?? 0) >= 86400 ? { prompt_cache_retention: "24h" } : {}),
94
+ }
95
+ : {}),
96
+ ...(req.outputSchema !== null
97
+ ? {
98
+ response_format: {
99
+ type: "json_schema",
100
+ json_schema: {
101
+ name: "modelrig_route_output",
102
+ schema: req.outputSchema,
103
+ strict: true,
104
+ },
105
+ },
106
+ }
107
+ : {}),
108
+ };
109
+ }
110
+ /** Ported suspicious-short heuristic: finish_reason 'stop' + <200 visible
111
+ * completion tokens on a 50K+ token prompt = flex degradation / stream drop. */
112
+ const SUSPICIOUSLY_SHORT_VISIBLE = 200;
113
+ const LONG_FORM_PROMPT_THRESHOLD = 50000;
114
+ function mapServedTier(raw, requested) {
115
+ if (raw === "flex")
116
+ return "flex";
117
+ if (raw === "priority")
118
+ return "priority";
119
+ if (raw === "default" || raw === "auto")
120
+ return "standard";
121
+ return requested === "flex" || requested === "priority" ? requested : "standard";
122
+ }
123
+ function createOpenAIAdapter(config) {
124
+ return {
125
+ id: "openai",
126
+ supports: openaiSupports,
127
+ async call(req) {
128
+ const model = req.candidate.model;
129
+ // F1: post-stream failures still billed tokens — attach usage.
130
+ const fail = (cls, message, fixHint, usage) => ({
131
+ ok: false,
132
+ failure: {
133
+ class: cls,
134
+ message,
135
+ provider: "openai",
136
+ model,
137
+ ...(fixHint !== undefined ? { fixHint } : {}),
138
+ },
139
+ ...(usage !== undefined ? { usage } : {}),
140
+ });
141
+ try {
142
+ const client = new openai_1.default({ apiKey: config.apiKey, timeout: req.timeoutMs });
143
+ const params = buildOpenAIParams(model, req);
144
+ const dispatchedAt = Date.now();
145
+ const stream = await client.chat.completions.create(params);
146
+ // TTFB (Phase 4 WS3): first streamed chunk = first body byte.
147
+ let ttfbMs;
148
+ let text = "";
149
+ let refusalText = "";
150
+ let promptTokens = 0;
151
+ let completionTokens = 0;
152
+ let cachedTokens = 0;
153
+ let reasoningTokens = 0;
154
+ let responseTier = null;
155
+ let finishReason = null;
156
+ for await (const chunk of stream) {
157
+ if (ttfbMs === undefined)
158
+ ttfbMs = Date.now() - dispatchedAt;
159
+ if (responseTier === null && chunk.service_tier !== undefined) {
160
+ responseTier = chunk.service_tier;
161
+ }
162
+ const choice = chunk.choices[0];
163
+ if (choice?.delta?.content)
164
+ text += choice.delta.content;
165
+ if (typeof choice?.delta?.refusal === "string" && choice.delta.refusal.length > 0) {
166
+ refusalText += choice.delta.refusal;
167
+ }
168
+ if (choice?.finish_reason)
169
+ finishReason = choice.finish_reason;
170
+ if (chunk.usage) {
171
+ promptTokens = chunk.usage.prompt_tokens ?? 0;
172
+ completionTokens = chunk.usage.completion_tokens ?? 0;
173
+ cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;
174
+ reasoningTokens = chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0;
175
+ }
176
+ }
177
+ const usage = {
178
+ tokensIn: promptTokens,
179
+ tokensOut: completionTokens,
180
+ tokensCached: cachedTokens,
181
+ servedTier: mapServedTier(responseTier, req.requestedTier),
182
+ ...(ttfbMs !== undefined ? { ttfbMs } : {}),
183
+ };
184
+ // Any streamed refusal is terminal for this call, even alongside
185
+ // partial content — OpenAI's structured-output semantics (ported).
186
+ if (refusalText.length > 0) {
187
+ return fail("refusal", `OpenAI refused structured output: ${refusalText.slice(0, 200)}`, undefined, usage);
188
+ }
189
+ const visibleCompletionTokens = Math.max(0, completionTokens - reasoningTokens);
190
+ if (finishReason === "stop" &&
191
+ completionTokens > 0 &&
192
+ visibleCompletionTokens < SUSPICIOUSLY_SHORT_VISIBLE &&
193
+ promptTokens >= LONG_FORM_PROMPT_THRESHOLD) {
194
+ return fail("content_invalid", `suspiciously short OpenAI response: ${visibleCompletionTokens} visible completion tokens ` +
195
+ `for ${promptTokens} prompt tokens (likely flex-tier degradation or stream drop)`, undefined, usage);
196
+ }
197
+ if (text.trim().length === 0) {
198
+ return fail("content_invalid", `empty response from OpenAI (finish_reason=${finishReason ?? "none"})`, undefined, usage);
199
+ }
200
+ if (finishReason === "length" && req.outputSchema !== null) {
201
+ return fail("content_invalid", "OpenAI structured output truncated (finish_reason=length)", "raise maxOutputTokens for this route", usage);
202
+ }
203
+ return { ok: true, text, usage };
204
+ }
205
+ catch (error) {
206
+ const message = error instanceof Error ? error.message : String(error);
207
+ const { cls, fixHint } = classifyOpenAIFailure(message);
208
+ return {
209
+ ok: false,
210
+ failure: {
211
+ class: cls,
212
+ message,
213
+ provider: "openai",
214
+ model,
215
+ cause: error,
216
+ ...(fixHint !== undefined ? { fixHint } : {}),
217
+ },
218
+ };
219
+ }
220
+ },
221
+ };
222
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Bake-off engine — Phase 3 spec WS5 (closed core). Replays the last N
3
+ * captures through each named variant, aggregates per-variant metrics
4
+ * (stats.ts), and assembles the BakeoffArtifact with the proposal verdict.
5
+ *
6
+ * Proposal gate (builder decision, flagged): the incumbent is the "default"
7
+ * variant when compared, else the FIRST listed variant. A challenger
8
+ * proposes when (a) its conformance CI lower bound ≥ the incumbent's CI
9
+ * lower bound, and (b) its effective $/1K-conformant is strictly lower.
10
+ * Value gates beyond mechanical conformance arrive with Phase 4 judges —
11
+ * the artifact records value_accuracy where the hook supplies it.
12
+ */
13
+ import type { CaptureStore } from "../telemetry/capture";
14
+ import type { RunDeps } from "../run/run";
15
+ import type { ArmSamples, KeepOutputsMode } from "./samples";
16
+ import type { BakeoffArtifact, VariantMetrics } from "./types";
17
+ /** Sink for retained review samples (addendum A3). The engine assembles the
18
+ * arms to persist (incumbent + winner, or all); the caller — createRig with
19
+ * the service-role config — does the truncation + PostgREST insert. Keeps
20
+ * payloads out of the engine and out of the (anon-readable) BakeoffArtifact. */
21
+ export type BakeoffSamplesSink = (input: {
22
+ readonly bakeoffId: string;
23
+ readonly route: string;
24
+ readonly arms: readonly ArmSamples[];
25
+ }) => Promise<void>;
26
+ export interface BakeoffRequest {
27
+ readonly route: string;
28
+ /** Variant names to compare; "default" = the route's base config. */
29
+ readonly variants: readonly string[];
30
+ readonly replayLastN: number;
31
+ /** Hard cap PER VARIANT replay pass (spec: replay is envelope-guarded). */
32
+ readonly envelopeUsdPerVariant: number;
33
+ /** Addendum A3: retain outputs for a value review. "winner" = incumbent +
34
+ * winning challenger; "all" = every arm. Undefined = keep nothing (the
35
+ * default pure-metrics path). Requires a samplesSink to persist. */
36
+ readonly keepOutputs?: KeepOutputsMode;
37
+ }
38
+ export declare function runBakeoff(deps: RunDeps, captures: CaptureStore, req: BakeoffRequest, samplesSink?: BakeoffSamplesSink): Promise<BakeoffArtifact>;
39
+ /** Winner among gate-passing challengers; null when nobody beats the
40
+ * incumbent. Exported for direct unit testing. */
41
+ export declare function computeProposal(requested: readonly string[], metrics: readonly VariantMetrics[]): BakeoffArtifact["proposal"];
42
+ export interface BakeoffMirrorConfig {
43
+ readonly supabaseUrl: string;
44
+ readonly serviceRoleKey: string;
45
+ readonly sourceId: string;
46
+ readonly fetchFn?: typeof fetch;
47
+ }
48
+ /** Upsert the artifact into the `bakeoffs` mirror table (console read path).
49
+ * Same PostgREST transport pattern as the telemetry exporter; captures have
50
+ * no cloud surface — ONLY aggregate metrics travel. */
51
+ export declare function mirrorBakeoff(artifact: BakeoffArtifact, config: BakeoffMirrorConfig): Promise<void>;
52
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/bakeoff/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAO1C,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/D;;;gFAGgF;AAChF,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,CAAC;CACtC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAgBpB,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC;;wEAEoE;IACpE,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC;CACxC;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,cAAc,EACnB,WAAW,CAAC,EAAE,kBAAkB,GAC/B,OAAO,CAAC,eAAe,CAAC,CA2E1B;AAED;kDACkD;AAClD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,eAAe,CAAC,UAAU,CAAC,CA4B7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACjC;AAED;;uDAEuD;AACvD,wBAAsB,aAAa,CACjC,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA6Bf"}