@warmdrift/kgauto-compiler 2.0.0-alpha.31 → 2.0.0-alpha.32

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.
@@ -148,6 +148,99 @@ interface TraceDetail extends TraceSummary {
148
148
  health: TraceHealth;
149
149
  }
150
150
 
151
+ /**
152
+ * proxy(req) — Glass-Box replay query handler.
153
+ *
154
+ * GET /api/glassbox/proxy?traceId=<id> → single compile_outcomes row for trace
155
+ * GET /api/glassbox/proxy?limit=<N> → N most-recent compile_outcomes rows
156
+ * GET /api/glassbox/proxy → defaults to limit=20
157
+ *
158
+ * Brain reads go through PostgREST on Supabase. We always filter by
159
+ * `app_id=eq.<appId>` even though the scoped JWT's RLS policy already
160
+ * enforces tenant isolation — the explicit filter trims the network payload
161
+ * and makes the query intent obvious to anyone reading logs.
162
+ *
163
+ * Scrub: the optional `scrub` hook runs on each row before responding so
164
+ * sensitive payloads (rendered prompts, tool calls) can be redacted at the
165
+ * proxy boundary. Default is identity (no-op).
166
+ */
167
+
168
+ /**
169
+ * Typed boundary transformer: compile_outcomes row (snake_case, Postgres
170
+ * native) → TraceSummary (camelCase, TypeScript native + extension wire
171
+ * contract). Single canonical mapping site — every DB-shape ↔ wire-shape
172
+ * crossing routes through here so renderer-expected fields can't silently
173
+ * go missing. See `feedback_typed_boundary_transformers.md` for the rule.
174
+ */
175
+ declare function rowToSummary(row: Record<string, unknown>): TraceSummary;
176
+ /**
177
+ * Typed boundary transformer (L-118): compile_outcomes row → TraceDetail.
178
+ * Single canonical mapping site for the detail-view wire contract. Pre-018
179
+ * brain rows return NULL for the new columns; this transformer applies
180
+ * type-safe defaults (0 for token columns, undefined for optional strings)
181
+ * so the renderer never crashes on missing fields.
182
+ *
183
+ * alpha.28 extends the field set per the renderer design contract — every
184
+ * extended field has a default. The `counterfactuals` + `projectedDailyCost`
185
+ * fields are populated by the proxy AFTER this transformer runs (they need
186
+ * profile lookup / brain query / async I/O).
187
+ */
188
+ declare function rowToDetail(row: Record<string, unknown>): TraceDetail;
189
+
190
+ /**
191
+ * computeCounterfactuals — for a served trace, compute up to 2 cheaper
192
+ * alternatives that ALSO meet the archetype quality floor.
193
+ *
194
+ * Pure function. Called at detail-view time by the proxy's `rowToDetail`
195
+ * path. The cost-equivalent answer to "what could this have run on without
196
+ * tanking quality?" lets the Glass-Box render `💰 Cheaper alternatives` so a
197
+ * founder sees the actual cost of the routing choice rather than just the
198
+ * served cost.
199
+ *
200
+ * Mechanism (per design contract Phase 0 spec):
201
+ * 1. Walk the archetype's full default fallback chain.
202
+ * 2. For each model in the chain (excluding the served model):
203
+ * - Skip if archetypePerf[archetype] < ARCHETYPE_FLOOR_DEFAULT (6).
204
+ * Matches the cliff-advisor work — never recommend a swap that
205
+ * violates the quality floor. (Composition with Builder C is
206
+ * intentional.)
207
+ * - Skip if profile missing.
208
+ * - Compute estimated cost at the OBSERVED token counts:
209
+ * non_cached_in = tokensIn - cacheReadInputTokens
210
+ * cost = (non_cached_in / 1e6) * profile.costInputPer1m
211
+ * + (cacheable_in / 1e6) * profile.costInputPer1m
212
+ * * profile.lowering.cache.discount
213
+ * + (tokensOut / 1e6) * profile.costOutputPer1m
214
+ * - Only include if estimatedCostUsd ≤ 0.9 × servedCostUsd
215
+ * (≥10% cheaper — below that's noise of token-count estimation).
216
+ * 3. Sort cheapest first.
217
+ * 4. Cap to top 2.
218
+ *
219
+ * Edge cases:
220
+ * - tokensIn === 0 → return [] (can't meaningfully estimate).
221
+ * - servedCostUsd === 0 → return [] (no baseline to beat).
222
+ * - Zero matching alternatives → return [] (renderer hides the card).
223
+ * - Served model isn't in the chain (e.g. forceModel'd off-chain) → use
224
+ * the chain for the archetype anyway.
225
+ */
226
+
227
+ /** Only surface swaps that save at least 10% vs. served. */
228
+ declare const COUNTERFACTUAL_MIN_SAVINGS_RATIO = 0.1;
229
+ /** Cap on alternatives surfaced per trace. */
230
+ declare const COUNTERFACTUAL_MAX_RESULTS = 2;
231
+ interface ComputeCounterfactualsArgs {
232
+ servedModel: string;
233
+ servedCostUsd: number;
234
+ archetype: string;
235
+ tokensIn: number;
236
+ tokensOut: number;
237
+ /** Defaults to 0 when caller doesn't know. */
238
+ cacheReadInputTokens?: number;
239
+ /** Reserved for future per-mode chain selection. */
240
+ toolOrchestration?: 'parallel' | 'sequential' | 'either';
241
+ }
242
+ declare function computeCounterfactuals(args: ComputeCounterfactualsArgs): TraceCounterfactual[];
243
+
151
244
  /**
152
245
  * Public entry point for `@warmdrift/kgauto-compiler/glassbox-routes`.
153
246
  *
@@ -239,4 +332,4 @@ interface GlassboxRoutes {
239
332
  }
240
333
  declare function createGlassboxRoutes(config: GlassboxRoutesConfig): GlassboxRoutes;
241
334
 
242
- export { type GlassboxRoutes, type GlassboxRoutesConfig, type TraceDetail, type TraceSummary, createGlassboxRoutes };
335
+ export { type AdvisoryRecord, COUNTERFACTUAL_MAX_RESULTS, COUNTERFACTUAL_MIN_SAVINGS_RATIO, type ComputeCounterfactualsArgs, type GlassboxRoutes, type GlassboxRoutesConfig, type TraceCounterfactual, type TraceDetail, type TraceHealth, type TraceSectionRewrite, type TraceSummary, computeCounterfactuals, createGlassboxRoutes, rowToDetail, rowToSummary };
@@ -148,6 +148,99 @@ interface TraceDetail extends TraceSummary {
148
148
  health: TraceHealth;
149
149
  }
150
150
 
151
+ /**
152
+ * proxy(req) — Glass-Box replay query handler.
153
+ *
154
+ * GET /api/glassbox/proxy?traceId=<id> → single compile_outcomes row for trace
155
+ * GET /api/glassbox/proxy?limit=<N> → N most-recent compile_outcomes rows
156
+ * GET /api/glassbox/proxy → defaults to limit=20
157
+ *
158
+ * Brain reads go through PostgREST on Supabase. We always filter by
159
+ * `app_id=eq.<appId>` even though the scoped JWT's RLS policy already
160
+ * enforces tenant isolation — the explicit filter trims the network payload
161
+ * and makes the query intent obvious to anyone reading logs.
162
+ *
163
+ * Scrub: the optional `scrub` hook runs on each row before responding so
164
+ * sensitive payloads (rendered prompts, tool calls) can be redacted at the
165
+ * proxy boundary. Default is identity (no-op).
166
+ */
167
+
168
+ /**
169
+ * Typed boundary transformer: compile_outcomes row (snake_case, Postgres
170
+ * native) → TraceSummary (camelCase, TypeScript native + extension wire
171
+ * contract). Single canonical mapping site — every DB-shape ↔ wire-shape
172
+ * crossing routes through here so renderer-expected fields can't silently
173
+ * go missing. See `feedback_typed_boundary_transformers.md` for the rule.
174
+ */
175
+ declare function rowToSummary(row: Record<string, unknown>): TraceSummary;
176
+ /**
177
+ * Typed boundary transformer (L-118): compile_outcomes row → TraceDetail.
178
+ * Single canonical mapping site for the detail-view wire contract. Pre-018
179
+ * brain rows return NULL for the new columns; this transformer applies
180
+ * type-safe defaults (0 for token columns, undefined for optional strings)
181
+ * so the renderer never crashes on missing fields.
182
+ *
183
+ * alpha.28 extends the field set per the renderer design contract — every
184
+ * extended field has a default. The `counterfactuals` + `projectedDailyCost`
185
+ * fields are populated by the proxy AFTER this transformer runs (they need
186
+ * profile lookup / brain query / async I/O).
187
+ */
188
+ declare function rowToDetail(row: Record<string, unknown>): TraceDetail;
189
+
190
+ /**
191
+ * computeCounterfactuals — for a served trace, compute up to 2 cheaper
192
+ * alternatives that ALSO meet the archetype quality floor.
193
+ *
194
+ * Pure function. Called at detail-view time by the proxy's `rowToDetail`
195
+ * path. The cost-equivalent answer to "what could this have run on without
196
+ * tanking quality?" lets the Glass-Box render `💰 Cheaper alternatives` so a
197
+ * founder sees the actual cost of the routing choice rather than just the
198
+ * served cost.
199
+ *
200
+ * Mechanism (per design contract Phase 0 spec):
201
+ * 1. Walk the archetype's full default fallback chain.
202
+ * 2. For each model in the chain (excluding the served model):
203
+ * - Skip if archetypePerf[archetype] < ARCHETYPE_FLOOR_DEFAULT (6).
204
+ * Matches the cliff-advisor work — never recommend a swap that
205
+ * violates the quality floor. (Composition with Builder C is
206
+ * intentional.)
207
+ * - Skip if profile missing.
208
+ * - Compute estimated cost at the OBSERVED token counts:
209
+ * non_cached_in = tokensIn - cacheReadInputTokens
210
+ * cost = (non_cached_in / 1e6) * profile.costInputPer1m
211
+ * + (cacheable_in / 1e6) * profile.costInputPer1m
212
+ * * profile.lowering.cache.discount
213
+ * + (tokensOut / 1e6) * profile.costOutputPer1m
214
+ * - Only include if estimatedCostUsd ≤ 0.9 × servedCostUsd
215
+ * (≥10% cheaper — below that's noise of token-count estimation).
216
+ * 3. Sort cheapest first.
217
+ * 4. Cap to top 2.
218
+ *
219
+ * Edge cases:
220
+ * - tokensIn === 0 → return [] (can't meaningfully estimate).
221
+ * - servedCostUsd === 0 → return [] (no baseline to beat).
222
+ * - Zero matching alternatives → return [] (renderer hides the card).
223
+ * - Served model isn't in the chain (e.g. forceModel'd off-chain) → use
224
+ * the chain for the archetype anyway.
225
+ */
226
+
227
+ /** Only surface swaps that save at least 10% vs. served. */
228
+ declare const COUNTERFACTUAL_MIN_SAVINGS_RATIO = 0.1;
229
+ /** Cap on alternatives surfaced per trace. */
230
+ declare const COUNTERFACTUAL_MAX_RESULTS = 2;
231
+ interface ComputeCounterfactualsArgs {
232
+ servedModel: string;
233
+ servedCostUsd: number;
234
+ archetype: string;
235
+ tokensIn: number;
236
+ tokensOut: number;
237
+ /** Defaults to 0 when caller doesn't know. */
238
+ cacheReadInputTokens?: number;
239
+ /** Reserved for future per-mode chain selection. */
240
+ toolOrchestration?: 'parallel' | 'sequential' | 'either';
241
+ }
242
+ declare function computeCounterfactuals(args: ComputeCounterfactualsArgs): TraceCounterfactual[];
243
+
151
244
  /**
152
245
  * Public entry point for `@warmdrift/kgauto-compiler/glassbox-routes`.
153
246
  *
@@ -239,4 +332,4 @@ interface GlassboxRoutes {
239
332
  }
240
333
  declare function createGlassboxRoutes(config: GlassboxRoutesConfig): GlassboxRoutes;
241
334
 
242
- export { type GlassboxRoutes, type GlassboxRoutesConfig, type TraceDetail, type TraceSummary, createGlassboxRoutes };
335
+ export { type AdvisoryRecord, COUNTERFACTUAL_MAX_RESULTS, COUNTERFACTUAL_MIN_SAVINGS_RATIO, type ComputeCounterfactualsArgs, type GlassboxRoutes, type GlassboxRoutesConfig, type TraceCounterfactual, type TraceDetail, type TraceHealth, type TraceSectionRewrite, type TraceSummary, computeCounterfactuals, createGlassboxRoutes, rowToDetail, rowToSummary };
@@ -20,7 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/glassbox-routes/index.ts
21
21
  var glassbox_routes_exports = {};
22
22
  __export(glassbox_routes_exports, {
23
- createGlassboxRoutes: () => createGlassboxRoutes
23
+ COUNTERFACTUAL_MAX_RESULTS: () => COUNTERFACTUAL_MAX_RESULTS,
24
+ COUNTERFACTUAL_MIN_SAVINGS_RATIO: () => COUNTERFACTUAL_MIN_SAVINGS_RATIO,
25
+ computeCounterfactuals: () => computeCounterfactuals,
26
+ createGlassboxRoutes: () => createGlassboxRoutes,
27
+ rowToDetail: () => rowToDetail,
28
+ rowToSummary: () => rowToSummary
24
29
  });
25
30
  module.exports = __toCommonJS(glassbox_routes_exports);
26
31
 
@@ -2454,5 +2459,10 @@ function createGlassboxRoutes(config) {
2454
2459
  }
2455
2460
  // Annotate the CommonJS export names for ESM import in node:
2456
2461
  0 && (module.exports = {
2457
- createGlassboxRoutes
2462
+ COUNTERFACTUAL_MAX_RESULTS,
2463
+ COUNTERFACTUAL_MIN_SAVINGS_RATIO,
2464
+ computeCounterfactuals,
2465
+ createGlassboxRoutes,
2466
+ rowToDetail,
2467
+ rowToSummary
2458
2468
  });
@@ -654,5 +654,10 @@ function createGlassboxRoutes(config) {
654
654
  return { proxy, stream };
655
655
  }
656
656
  export {
657
- createGlassboxRoutes
657
+ COUNTERFACTUAL_MAX_RESULTS,
658
+ COUNTERFACTUAL_MIN_SAVINGS_RATIO,
659
+ computeCounterfactuals,
660
+ createGlassboxRoutes,
661
+ rowToDetail,
662
+ rowToSummary
658
663
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmdrift/kgauto-compiler",
3
- "version": "2.0.0-alpha.31",
3
+ "version": "2.0.0-alpha.32",
4
4
  "description": "Prompt compiler + central learning brain for multi-model AI apps. Swap models without rewriting prompts.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",