@warmdrift/kgauto-compiler 2.0.0-alpha.53 → 2.0.0-alpha.54

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.
@@ -0,0 +1,87 @@
1
+ /**
2
+ * `@warmdrift/kgauto-compiler/brain-proxy` — consumer brain-forward factory.
3
+ *
4
+ * ## Why this exists (the 4-consumer silent-drop class, 2026-07-06 s62)
5
+ *
6
+ * The library's `record()` / `recordOutcome()` / `recordShadowProbe()` /
7
+ * advisory paths all POST to a consumer-hosted proxy that forwards the row to
8
+ * the shared Supabase brain (the consumer holds the service-role key; kgauto's
9
+ * library never sees it). Every consumer hand-rolled that proxy layer — and a
10
+ * 4-consumer audit found every one silently broken in a *different* shape:
11
+ *
12
+ * - tt-intelligence: middleware blocked 2 of 3 routes — server-to-server
13
+ * POSTs 307-redirected to /login (missing public-path allowlist entry).
14
+ * - inspire-central: the `/outcomes` proxy carried a column whitelist frozen
15
+ * at alpha.7 that stripped `fell_over_from` / `fallback_reason`
16
+ * (migration 018 columns) — Glass-Box fallback telemetry silently NULL.
17
+ * - playbacksam: the `/probe_outcomes` whitelist would strip alpha.53's
18
+ * `error_class` — every future migration column drops on the floor.
19
+ * - global-expansion: mounted 1 of 4 routes — advisory POSTs 404 silently.
20
+ *
21
+ * Same L-142 / L-117 silent-drop family, four independent shapes, all in the
22
+ * layer consumers hand-roll. This factory kills the *class*: kgauto owns the
23
+ * forward handler, the consumer mounts ONE catch-all route. No column
24
+ * whitelist — the body is forwarded verbatim (`{ ...body }`), so any future
25
+ * migration column passes through untouched. One middleware/public-path entry
26
+ * (`/api/kgauto/v2/`) covers all four segments, which structurally prevents
27
+ * the tt-intel middleware-drift failure.
28
+ *
29
+ * ## Mounting recipes
30
+ *
31
+ * ### (a) Next.js app-router catch-all — ONE file, ONE middleware entry
32
+ *
33
+ * // app/api/kgauto/v2/[segment]/route.ts
34
+ * import { createBrainForwardRoutes } from '@warmdrift/kgauto-compiler/brain-proxy';
35
+ * const routes = createBrainForwardRoutes({
36
+ * ingestSecret: process.env.KGAUTO_INGEST_SECRET!,
37
+ * brainUrl: process.env.KGAUTO_BRAIN_URL!, // https://xxxx.supabase.co
38
+ * serviceKey: process.env.KGAUTO_BRAIN_SERVICE_KEY!,
39
+ * });
40
+ * export const POST = (req: Request, { params }: { params: { segment: string } }) =>
41
+ * routes.handle(req, params.segment);
42
+ *
43
+ * // middleware.ts — ONE public-path entry covers ALL four segments.
44
+ * // This is the structural fix for the tt-intel drift: you cannot mount
45
+ * // 3-of-4 routes and forget the 4th, because the catch-all is one file
46
+ * // and the allowlist is one prefix.
47
+ * const PUBLIC_PATHS = [ ... '/api/kgauto/v2/' ];
48
+ *
49
+ * ### (b) Plain Vercel edge function, per segment
50
+ *
51
+ * // api/kgauto/probe_outcomes.ts
52
+ * export const config = { runtime: 'edge' };
53
+ * const routes = createBrainForwardRoutes({ ... });
54
+ * export default (req: Request) => routes.handle(req, 'probe_outcomes');
55
+ *
56
+ * The library appends the segment path to the consumer's `endpoint`, so the
57
+ * consumer's `KGAUTO_V2_BRAIN_URL` (the value passed to `configureBrain`)
58
+ * must be the base that resolves to `.../api/kgauto/v2` — i.e. the last path
59
+ * segment of each library POST (`outcomes`, `probe_outcomes`, …) is what
60
+ * `handle()` receives as `segment`.
61
+ */
62
+ interface BrainForwardConfig {
63
+ /** Bearer token consumers' callers must present (usually KGAUTO_INGEST_SECRET). */
64
+ ingestSecret: string;
65
+ /** Brain Supabase project URL (e.g. https://xxxx.supabase.co). */
66
+ brainUrl: string;
67
+ /** Brain service-role key (server-side only). */
68
+ serviceKey: string;
69
+ /** Optional fetch impl for tests. */
70
+ fetchImpl?: typeof fetch;
71
+ }
72
+ interface BrainForwardRoutes {
73
+ /**
74
+ * Web-standard handler. `segment` is the last path segment of the library's
75
+ * POST URL (e.g. 'outcomes', 'probe_outcomes'). In a Next.js catch-all this
76
+ * is `params.segment`. Never throws — every error path returns a `Response`.
77
+ */
78
+ handle(req: Request, segment: string): Promise<Response>;
79
+ /**
80
+ * The path segments this factory serves. Consumers can use it for route
81
+ * generation, allowlist construction, or tests.
82
+ */
83
+ segments: readonly string[];
84
+ }
85
+ declare function createBrainForwardRoutes(config: BrainForwardConfig): BrainForwardRoutes;
86
+
87
+ export { type BrainForwardConfig, type BrainForwardRoutes, createBrainForwardRoutes };
@@ -0,0 +1,87 @@
1
+ /**
2
+ * `@warmdrift/kgauto-compiler/brain-proxy` — consumer brain-forward factory.
3
+ *
4
+ * ## Why this exists (the 4-consumer silent-drop class, 2026-07-06 s62)
5
+ *
6
+ * The library's `record()` / `recordOutcome()` / `recordShadowProbe()` /
7
+ * advisory paths all POST to a consumer-hosted proxy that forwards the row to
8
+ * the shared Supabase brain (the consumer holds the service-role key; kgauto's
9
+ * library never sees it). Every consumer hand-rolled that proxy layer — and a
10
+ * 4-consumer audit found every one silently broken in a *different* shape:
11
+ *
12
+ * - tt-intelligence: middleware blocked 2 of 3 routes — server-to-server
13
+ * POSTs 307-redirected to /login (missing public-path allowlist entry).
14
+ * - inspire-central: the `/outcomes` proxy carried a column whitelist frozen
15
+ * at alpha.7 that stripped `fell_over_from` / `fallback_reason`
16
+ * (migration 018 columns) — Glass-Box fallback telemetry silently NULL.
17
+ * - playbacksam: the `/probe_outcomes` whitelist would strip alpha.53's
18
+ * `error_class` — every future migration column drops on the floor.
19
+ * - global-expansion: mounted 1 of 4 routes — advisory POSTs 404 silently.
20
+ *
21
+ * Same L-142 / L-117 silent-drop family, four independent shapes, all in the
22
+ * layer consumers hand-roll. This factory kills the *class*: kgauto owns the
23
+ * forward handler, the consumer mounts ONE catch-all route. No column
24
+ * whitelist — the body is forwarded verbatim (`{ ...body }`), so any future
25
+ * migration column passes through untouched. One middleware/public-path entry
26
+ * (`/api/kgauto/v2/`) covers all four segments, which structurally prevents
27
+ * the tt-intel middleware-drift failure.
28
+ *
29
+ * ## Mounting recipes
30
+ *
31
+ * ### (a) Next.js app-router catch-all — ONE file, ONE middleware entry
32
+ *
33
+ * // app/api/kgauto/v2/[segment]/route.ts
34
+ * import { createBrainForwardRoutes } from '@warmdrift/kgauto-compiler/brain-proxy';
35
+ * const routes = createBrainForwardRoutes({
36
+ * ingestSecret: process.env.KGAUTO_INGEST_SECRET!,
37
+ * brainUrl: process.env.KGAUTO_BRAIN_URL!, // https://xxxx.supabase.co
38
+ * serviceKey: process.env.KGAUTO_BRAIN_SERVICE_KEY!,
39
+ * });
40
+ * export const POST = (req: Request, { params }: { params: { segment: string } }) =>
41
+ * routes.handle(req, params.segment);
42
+ *
43
+ * // middleware.ts — ONE public-path entry covers ALL four segments.
44
+ * // This is the structural fix for the tt-intel drift: you cannot mount
45
+ * // 3-of-4 routes and forget the 4th, because the catch-all is one file
46
+ * // and the allowlist is one prefix.
47
+ * const PUBLIC_PATHS = [ ... '/api/kgauto/v2/' ];
48
+ *
49
+ * ### (b) Plain Vercel edge function, per segment
50
+ *
51
+ * // api/kgauto/probe_outcomes.ts
52
+ * export const config = { runtime: 'edge' };
53
+ * const routes = createBrainForwardRoutes({ ... });
54
+ * export default (req: Request) => routes.handle(req, 'probe_outcomes');
55
+ *
56
+ * The library appends the segment path to the consumer's `endpoint`, so the
57
+ * consumer's `KGAUTO_V2_BRAIN_URL` (the value passed to `configureBrain`)
58
+ * must be the base that resolves to `.../api/kgauto/v2` — i.e. the last path
59
+ * segment of each library POST (`outcomes`, `probe_outcomes`, …) is what
60
+ * `handle()` receives as `segment`.
61
+ */
62
+ interface BrainForwardConfig {
63
+ /** Bearer token consumers' callers must present (usually KGAUTO_INGEST_SECRET). */
64
+ ingestSecret: string;
65
+ /** Brain Supabase project URL (e.g. https://xxxx.supabase.co). */
66
+ brainUrl: string;
67
+ /** Brain service-role key (server-side only). */
68
+ serviceKey: string;
69
+ /** Optional fetch impl for tests. */
70
+ fetchImpl?: typeof fetch;
71
+ }
72
+ interface BrainForwardRoutes {
73
+ /**
74
+ * Web-standard handler. `segment` is the last path segment of the library's
75
+ * POST URL (e.g. 'outcomes', 'probe_outcomes'). In a Next.js catch-all this
76
+ * is `params.segment`. Never throws — every error path returns a `Response`.
77
+ */
78
+ handle(req: Request, segment: string): Promise<Response>;
79
+ /**
80
+ * The path segments this factory serves. Consumers can use it for route
81
+ * generation, allowlist construction, or tests.
82
+ */
83
+ segments: readonly string[];
84
+ }
85
+ declare function createBrainForwardRoutes(config: BrainForwardConfig): BrainForwardRoutes;
86
+
87
+ export { type BrainForwardConfig, type BrainForwardRoutes, createBrainForwardRoutes };
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/brain-proxy.ts
21
+ var brain_proxy_exports = {};
22
+ __export(brain_proxy_exports, {
23
+ createBrainForwardRoutes: () => createBrainForwardRoutes
24
+ });
25
+ module.exports = __toCommonJS(brain_proxy_exports);
26
+ var SEGMENT_TO_TABLE = {
27
+ outcomes: "compile_outcomes",
28
+ compile_outcome_advisories: "compile_outcome_advisories",
29
+ compile_outcome_quality: "compile_outcome_quality",
30
+ probe_outcomes: "probe_outcomes"
31
+ };
32
+ var KNOWN_SEGMENTS = Object.keys(SEGMENT_TO_TABLE);
33
+ var JSON_HEADERS = { "Content-Type": "application/json" };
34
+ function jsonResponse(status, body) {
35
+ return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS });
36
+ }
37
+ function bearerOf(req) {
38
+ const header = req.headers.get("Authorization") ?? "";
39
+ const match = /^Bearer\s+(.+)$/i.exec(header);
40
+ return match?.[1]?.trim() ?? "";
41
+ }
42
+ function requireString(name, value) {
43
+ if (typeof value !== "string" || value.length === 0) {
44
+ throw new Error(`createBrainForwardRoutes: ${name} is required`);
45
+ }
46
+ return value;
47
+ }
48
+ function createBrainForwardRoutes(config) {
49
+ const ingestSecret = requireString("ingestSecret", config.ingestSecret);
50
+ const brainUrl = requireString("brainUrl", config.brainUrl).replace(/\/+$/, "");
51
+ const serviceKey = requireString("serviceKey", config.serviceKey);
52
+ const fetchFn = config.fetchImpl ?? fetch;
53
+ async function handle(req, segment) {
54
+ try {
55
+ if (req.method !== "POST") {
56
+ return jsonResponse(405, {
57
+ error: "method-not-allowed",
58
+ method: req.method,
59
+ allowed: ["POST"]
60
+ });
61
+ }
62
+ const table = SEGMENT_TO_TABLE[segment];
63
+ if (!table) {
64
+ return jsonResponse(404, {
65
+ error: "unknown-brain-forward-segment",
66
+ segment,
67
+ known: KNOWN_SEGMENTS
68
+ });
69
+ }
70
+ if (bearerOf(req) !== ingestSecret) {
71
+ return jsonResponse(401, { error: "unauthorized" });
72
+ }
73
+ let body;
74
+ try {
75
+ body = await req.json();
76
+ } catch {
77
+ return jsonResponse(400, { error: "invalid-json" });
78
+ }
79
+ const row = Array.isArray(body) ? body : { ...body };
80
+ let brainRes;
81
+ try {
82
+ brainRes = await fetchFn(`${brainUrl}/rest/v1/${table}`, {
83
+ method: "POST",
84
+ headers: {
85
+ apikey: serviceKey,
86
+ Authorization: `Bearer ${serviceKey}`,
87
+ "Content-Type": "application/json",
88
+ Prefer: "return=minimal"
89
+ },
90
+ body: JSON.stringify(row)
91
+ });
92
+ } catch (err) {
93
+ return jsonResponse(502, {
94
+ error: "brain-unreachable",
95
+ table,
96
+ detail: err instanceof Error ? err.message : String(err)
97
+ });
98
+ }
99
+ if (brainRes.ok) {
100
+ return jsonResponse(201, { ok: true });
101
+ }
102
+ const text = await brainRes.text().catch(() => "<no body>");
103
+ return jsonResponse(brainRes.status, {
104
+ error: "brain-write-failed",
105
+ table,
106
+ status: brainRes.status,
107
+ detail: text
108
+ });
109
+ } catch (err) {
110
+ return jsonResponse(500, {
111
+ error: "brain-forward-internal-error",
112
+ detail: err instanceof Error ? err.message : String(err)
113
+ });
114
+ }
115
+ }
116
+ return { handle, segments: KNOWN_SEGMENTS };
117
+ }
118
+ // Annotate the CommonJS export names for ESM import in node:
119
+ 0 && (module.exports = {
120
+ createBrainForwardRoutes
121
+ });
@@ -0,0 +1,6 @@
1
+ import {
2
+ createBrainForwardRoutes
3
+ } from "./chunk-NGPB3D53.mjs";
4
+ export {
5
+ createBrainForwardRoutes
6
+ };
@@ -0,0 +1,97 @@
1
+ // src/brain-proxy.ts
2
+ var SEGMENT_TO_TABLE = {
3
+ outcomes: "compile_outcomes",
4
+ compile_outcome_advisories: "compile_outcome_advisories",
5
+ compile_outcome_quality: "compile_outcome_quality",
6
+ probe_outcomes: "probe_outcomes"
7
+ };
8
+ var KNOWN_SEGMENTS = Object.keys(SEGMENT_TO_TABLE);
9
+ var JSON_HEADERS = { "Content-Type": "application/json" };
10
+ function jsonResponse(status, body) {
11
+ return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS });
12
+ }
13
+ function bearerOf(req) {
14
+ const header = req.headers.get("Authorization") ?? "";
15
+ const match = /^Bearer\s+(.+)$/i.exec(header);
16
+ return match?.[1]?.trim() ?? "";
17
+ }
18
+ function requireString(name, value) {
19
+ if (typeof value !== "string" || value.length === 0) {
20
+ throw new Error(`createBrainForwardRoutes: ${name} is required`);
21
+ }
22
+ return value;
23
+ }
24
+ function createBrainForwardRoutes(config) {
25
+ const ingestSecret = requireString("ingestSecret", config.ingestSecret);
26
+ const brainUrl = requireString("brainUrl", config.brainUrl).replace(/\/+$/, "");
27
+ const serviceKey = requireString("serviceKey", config.serviceKey);
28
+ const fetchFn = config.fetchImpl ?? fetch;
29
+ async function handle(req, segment) {
30
+ try {
31
+ if (req.method !== "POST") {
32
+ return jsonResponse(405, {
33
+ error: "method-not-allowed",
34
+ method: req.method,
35
+ allowed: ["POST"]
36
+ });
37
+ }
38
+ const table = SEGMENT_TO_TABLE[segment];
39
+ if (!table) {
40
+ return jsonResponse(404, {
41
+ error: "unknown-brain-forward-segment",
42
+ segment,
43
+ known: KNOWN_SEGMENTS
44
+ });
45
+ }
46
+ if (bearerOf(req) !== ingestSecret) {
47
+ return jsonResponse(401, { error: "unauthorized" });
48
+ }
49
+ let body;
50
+ try {
51
+ body = await req.json();
52
+ } catch {
53
+ return jsonResponse(400, { error: "invalid-json" });
54
+ }
55
+ const row = Array.isArray(body) ? body : { ...body };
56
+ let brainRes;
57
+ try {
58
+ brainRes = await fetchFn(`${brainUrl}/rest/v1/${table}`, {
59
+ method: "POST",
60
+ headers: {
61
+ apikey: serviceKey,
62
+ Authorization: `Bearer ${serviceKey}`,
63
+ "Content-Type": "application/json",
64
+ Prefer: "return=minimal"
65
+ },
66
+ body: JSON.stringify(row)
67
+ });
68
+ } catch (err) {
69
+ return jsonResponse(502, {
70
+ error: "brain-unreachable",
71
+ table,
72
+ detail: err instanceof Error ? err.message : String(err)
73
+ });
74
+ }
75
+ if (brainRes.ok) {
76
+ return jsonResponse(201, { ok: true });
77
+ }
78
+ const text = await brainRes.text().catch(() => "<no body>");
79
+ return jsonResponse(brainRes.status, {
80
+ error: "brain-write-failed",
81
+ table,
82
+ status: brainRes.status,
83
+ detail: text
84
+ });
85
+ } catch (err) {
86
+ return jsonResponse(500, {
87
+ error: "brain-forward-internal-error",
88
+ detail: err instanceof Error ? err.message : String(err)
89
+ });
90
+ }
91
+ }
92
+ return { handle, segments: KNOWN_SEGMENTS };
93
+ }
94
+
95
+ export {
96
+ createBrainForwardRoutes
97
+ };
package/dist/index.d.mts CHANGED
@@ -2,6 +2,7 @@ import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as Provide
2
2
  export { m as CallAttempt, n as CallError, o as ChainModelEntry, p as ChainWithGrounding, q as Constraints, F as FallbackReason, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, r as MutationApplied, s as NormalizedTokens, t as OutcomeKind, u as PerAxisMetricsByModel, v as PromptSection, w as SectionKind, x as ShadowProbeConfig, T as ToolCall, y as ToolDefinition } from './ir-CAlLBu5d.mjs';
3
3
  import { ModelProfile, ArchetypeConvention } from './profiles.mjs';
4
4
  export { ALIASES, CacheStrategy, CliffRule, LATENCY_TIER_MS, LatencyTier, LoweringSpec, RecoveryRule, StructuredOutputCapability, SystemPromptMode, allProfiles, getProfile, latencyTierOf, profilesByProvider, tryGetProfile } from './profiles.mjs';
5
+ export { BrainForwardConfig, BrainForwardRoutes, createBrainForwardRoutes } from './brain-proxy.mjs';
5
6
  import { IntentArchetypeName } from './dialect.mjs';
6
7
  export { ALL_ARCHETYPES, ContextBucket, DIALECT_VERSION, HistoryDepth, INTENT_ARCHETYPES, OutputMode, ShapeSignature, ToolCountBucket, bucketContext, bucketHistory, bucketToolCount, hashShape, isArchetype, learningKey } from './dialect.mjs';
7
8
 
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as Provide
2
2
  export { m as CallAttempt, n as CallError, o as ChainModelEntry, p as ChainWithGrounding, q as Constraints, F as FallbackReason, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, r as MutationApplied, s as NormalizedTokens, t as OutcomeKind, u as PerAxisMetricsByModel, v as PromptSection, w as SectionKind, x as ShadowProbeConfig, T as ToolCall, y as ToolDefinition } from './ir-BiXAMyji.js';
3
3
  import { ModelProfile, ArchetypeConvention } from './profiles.js';
4
4
  export { ALIASES, CacheStrategy, CliffRule, LATENCY_TIER_MS, LatencyTier, LoweringSpec, RecoveryRule, StructuredOutputCapability, SystemPromptMode, allProfiles, getProfile, latencyTierOf, profilesByProvider, tryGetProfile } from './profiles.js';
5
+ export { BrainForwardConfig, BrainForwardRoutes, createBrainForwardRoutes } from './brain-proxy.js';
5
6
  import { IntentArchetypeName } from './dialect.js';
6
7
  export { ALL_ARCHETYPES, ContextBucket, DIALECT_VERSION, HistoryDepth, INTENT_ARCHETYPES, OutputMode, ShapeSignature, ToolCountBucket, bucketContext, bucketHistory, bucketToolCount, hashShape, isArchetype, learningKey } from './dialect.js';
7
8
 
package/dist/index.js CHANGED
@@ -51,6 +51,7 @@ __export(index_exports, {
51
51
  compileForAISDKv6: () => compileForAISDKv6,
52
52
  configureBrain: () => configureBrain,
53
53
  countTokens: () => countTokens,
54
+ createBrainForwardRoutes: () => createBrainForwardRoutes,
54
55
  deriveFamilyFromModelId: () => deriveFamilyFromModelId,
55
56
  deriveOwnership: () => deriveOwnership,
56
57
  execute: () => execute,
@@ -6761,6 +6762,100 @@ function extractKeptToolNames(result) {
6761
6762
  return names;
6762
6763
  }
6763
6764
 
6765
+ // src/brain-proxy.ts
6766
+ var SEGMENT_TO_TABLE = {
6767
+ outcomes: "compile_outcomes",
6768
+ compile_outcome_advisories: "compile_outcome_advisories",
6769
+ compile_outcome_quality: "compile_outcome_quality",
6770
+ probe_outcomes: "probe_outcomes"
6771
+ };
6772
+ var KNOWN_SEGMENTS = Object.keys(SEGMENT_TO_TABLE);
6773
+ var JSON_HEADERS = { "Content-Type": "application/json" };
6774
+ function jsonResponse(status, body) {
6775
+ return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS });
6776
+ }
6777
+ function bearerOf(req) {
6778
+ const header = req.headers.get("Authorization") ?? "";
6779
+ const match = /^Bearer\s+(.+)$/i.exec(header);
6780
+ return match?.[1]?.trim() ?? "";
6781
+ }
6782
+ function requireString(name, value) {
6783
+ if (typeof value !== "string" || value.length === 0) {
6784
+ throw new Error(`createBrainForwardRoutes: ${name} is required`);
6785
+ }
6786
+ return value;
6787
+ }
6788
+ function createBrainForwardRoutes(config) {
6789
+ const ingestSecret = requireString("ingestSecret", config.ingestSecret);
6790
+ const brainUrl = requireString("brainUrl", config.brainUrl).replace(/\/+$/, "");
6791
+ const serviceKey = requireString("serviceKey", config.serviceKey);
6792
+ const fetchFn = config.fetchImpl ?? fetch;
6793
+ async function handle(req, segment) {
6794
+ try {
6795
+ if (req.method !== "POST") {
6796
+ return jsonResponse(405, {
6797
+ error: "method-not-allowed",
6798
+ method: req.method,
6799
+ allowed: ["POST"]
6800
+ });
6801
+ }
6802
+ const table = SEGMENT_TO_TABLE[segment];
6803
+ if (!table) {
6804
+ return jsonResponse(404, {
6805
+ error: "unknown-brain-forward-segment",
6806
+ segment,
6807
+ known: KNOWN_SEGMENTS
6808
+ });
6809
+ }
6810
+ if (bearerOf(req) !== ingestSecret) {
6811
+ return jsonResponse(401, { error: "unauthorized" });
6812
+ }
6813
+ let body;
6814
+ try {
6815
+ body = await req.json();
6816
+ } catch {
6817
+ return jsonResponse(400, { error: "invalid-json" });
6818
+ }
6819
+ const row = Array.isArray(body) ? body : { ...body };
6820
+ let brainRes;
6821
+ try {
6822
+ brainRes = await fetchFn(`${brainUrl}/rest/v1/${table}`, {
6823
+ method: "POST",
6824
+ headers: {
6825
+ apikey: serviceKey,
6826
+ Authorization: `Bearer ${serviceKey}`,
6827
+ "Content-Type": "application/json",
6828
+ Prefer: "return=minimal"
6829
+ },
6830
+ body: JSON.stringify(row)
6831
+ });
6832
+ } catch (err) {
6833
+ return jsonResponse(502, {
6834
+ error: "brain-unreachable",
6835
+ table,
6836
+ detail: err instanceof Error ? err.message : String(err)
6837
+ });
6838
+ }
6839
+ if (brainRes.ok) {
6840
+ return jsonResponse(201, { ok: true });
6841
+ }
6842
+ const text = await brainRes.text().catch(() => "<no body>");
6843
+ return jsonResponse(brainRes.status, {
6844
+ error: "brain-write-failed",
6845
+ table,
6846
+ status: brainRes.status,
6847
+ detail: text
6848
+ });
6849
+ } catch (err) {
6850
+ return jsonResponse(500, {
6851
+ error: "brain-forward-internal-error",
6852
+ detail: err instanceof Error ? err.message : String(err)
6853
+ });
6854
+ }
6855
+ }
6856
+ return { handle, segments: KNOWN_SEGMENTS };
6857
+ }
6858
+
6764
6859
  // src/oracle.ts
6765
6860
  var DEFAULT_DIMENSIONS = ["correctness", "completeness", "conciseness", "format"];
6766
6861
  var judgeCallTimes = [];
@@ -7220,6 +7315,7 @@ function compile2(ir, opts) {
7220
7315
  compileForAISDKv6,
7221
7316
  configureBrain,
7222
7317
  countTokens,
7318
+ createBrainForwardRoutes,
7223
7319
  deriveFamilyFromModelId,
7224
7320
  deriveOwnership,
7225
7321
  execute,
package/dist/index.mjs CHANGED
@@ -1,3 +1,6 @@
1
+ import {
2
+ createBrainForwardRoutes
3
+ } from "./chunk-NGPB3D53.mjs";
1
4
  import {
2
5
  ALL_ARCHETYPES,
3
6
  DIALECT_VERSION,
@@ -4658,6 +4661,7 @@ export {
4658
4661
  compileForAISDKv6,
4659
4662
  configureBrain,
4660
4663
  countTokens,
4664
+ createBrainForwardRoutes,
4661
4665
  deriveFamilyFromModelId,
4662
4666
  deriveOwnership,
4663
4667
  execute,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmdrift/kgauto-compiler",
3
- "version": "2.0.0-alpha.53",
3
+ "version": "2.0.0-alpha.54",
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",
@@ -21,6 +21,11 @@
21
21
  "import": "./dist/profiles.mjs",
22
22
  "require": "./dist/profiles.js"
23
23
  },
24
+ "./brain-proxy": {
25
+ "types": "./dist/brain-proxy.d.ts",
26
+ "import": "./dist/brain-proxy.mjs",
27
+ "require": "./dist/brain-proxy.js"
28
+ },
24
29
  "./glassbox": {
25
30
  "types": "./dist/glassbox/index.d.ts",
26
31
  "import": "./dist/glassbox/index.mjs",
@@ -47,7 +52,7 @@
47
52
  "README.md"
48
53
  ],
49
54
  "scripts": {
50
- "build": "tsup src/index.ts src/dialect.ts src/profiles.ts src/glassbox/index.ts src/glassbox-routes/index.ts src/glassbox-routes/format.ts src/glassbox-routes/react/index.ts --format cjs,esm --dts --clean --external react --external react-dom",
55
+ "build": "tsup src/index.ts src/dialect.ts src/profiles.ts src/brain-proxy.ts src/glassbox/index.ts src/glassbox-routes/index.ts src/glassbox-routes/format.ts src/glassbox-routes/react/index.ts --format cjs,esm --dts --clean --external react --external react-dom",
51
56
  "test": "vitest run",
52
57
  "test:watch": "vitest",
53
58
  "typecheck": "tsc --noEmit",