@warmdrift/kgauto-compiler 2.0.0-alpha.38 → 2.0.0-alpha.39

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.
package/dist/index.d.mts CHANGED
@@ -768,6 +768,80 @@ declare function markAdvisoryResolved(opts: MarkAdvisoryResolvedOptions): Promis
768
768
  ok: false;
769
769
  reason: string;
770
770
  }>;
771
+ /**
772
+ * Resolution sources supported by the alpha.39 `markExclusionFindingHandled`
773
+ * API. Mirrors the subset of `exclusion_findings.resolution_source` CHECK
774
+ * constraint values that consumers can self-set:
775
+ *
776
+ * - `'consumer-marked'` — generic "we've handled this; stop reminding."
777
+ * Use this for "we evaluated and chose not to act" or "we'll act when
778
+ * ready but acknowledge the finding now."
779
+ * - `'declined'` — explicit "this exclusion is intentional; do not surface
780
+ * again." Stronger signal than consumer-marked; useful for compliance
781
+ * exclusions, brand-promise exclusions, etc.
782
+ * - `'probed-unblock'` — alpha.40+ probe-path verdict: consumer ran a live
783
+ * probe and decided to unblock the excluded model. Library accepts the
784
+ * value today so the probe path doesn't need a follow-up API release.
785
+ * - `'probed-stay-excluded'` — alpha.40+ probe-path verdict: consumer
786
+ * probed and confirmed the exclusion. Same forward-compat shape as
787
+ * `'probed-unblock'`.
788
+ *
789
+ * The `'auto'` resolution_source is NOT exposed here — that's reserved
790
+ * for the brain's own automatic resolution (e.g. when the detection
791
+ * conditions no longer hold). Consumer code sets only the four values
792
+ * above.
793
+ */
794
+ type ExclusionResolutionSource = 'consumer-marked' | 'declined' | 'probed-unblock' | 'probed-stay-excluded';
795
+ interface MarkExclusionFindingHandledOptions {
796
+ /** App id the finding belongs to. Required (RLS scopes writes by this). */
797
+ appId: string;
798
+ /** Archetype the finding applies to (e.g. 'hunt', 'classify'). */
799
+ archetype: string;
800
+ /** Canonical model id that the consumer had excluded. */
801
+ excludedModel: string;
802
+ /** Resolution semantics — see `ExclusionResolutionSource` for the four
803
+ * values consumers can set. */
804
+ resolution: ExclusionResolutionSource;
805
+ /** Optional free-form note explaining the decision. Surfaces in operator
806
+ * digests + dashboards alongside the resolution_source. */
807
+ resolutionNote?: string;
808
+ /** Brain Supabase URL base (e.g. `https://<project>.supabase.co`). The
809
+ * function appends `/rest/v1/exclusion_findings?...`. */
810
+ brainEndpoint: string;
811
+ /** Consumer-scoped JWT carrying the `app_id` claim. The brain's RLS
812
+ * policy enforces that the JWT's app_id matches the finding's app_id;
813
+ * cross-tenant writes fail at the database layer regardless of input. */
814
+ brainJwt: string;
815
+ /** Supabase anon key for the `apikey` header (PostgREST requires it). */
816
+ brainAnonKey: string;
817
+ /** Injected fetch for tests. Defaults to global fetch. */
818
+ fetch?: typeof fetch;
819
+ }
820
+ /**
821
+ * Mark a stale-exclusion finding as handled. Returns an `ok/reason` envelope
822
+ * matching `markAdvisoryResolved` — consumer Admin UIs typically render the
823
+ * failure inline rather than crash.
824
+ *
825
+ * Idempotent: if no row matches the (app_id, archetype, excludedModel)
826
+ * tuple (already resolved, never existed, cron not yet UPSERTed), PostgREST
827
+ * returns 200 with zero affected rows and we return `{ ok: true }`. The
828
+ * caller's "I marked it as handled" intent is satisfied regardless of
829
+ * whether the row was already in that state.
830
+ *
831
+ * Reasons surfaced on failure:
832
+ * - `app_id_required` / `archetype_required` / `excluded_model_required`
833
+ * - `resolution_invalid` — `resolution` not one of the four documented values
834
+ * - `brain_auth_misconfig` — 401/403 (JWT / anon key wrong)
835
+ * - `brain_unavailable` — 5xx
836
+ * - `network_error:<message>` — fetch threw
837
+ * - `patch_failed:<status>` — anything else non-2xx
838
+ */
839
+ declare function markExclusionFindingHandled(opts: MarkExclusionFindingHandledOptions): Promise<{
840
+ ok: true;
841
+ } | {
842
+ ok: false;
843
+ reason: string;
844
+ }>;
771
845
 
772
846
  /**
773
847
  * Archetype-cliff compatibility — alpha.28 (tt-intel-Cairn ratified).
@@ -1627,4 +1701,4 @@ declare function getStaleExclusionFindings(opts: GetExclusionFindingsOpts): Excl
1627
1701
  */
1628
1702
  declare function compile(ir: PromptIR, opts?: CompileOptions): CompileResult;
1629
1703
 
1630
- export { ABSOLUTE_FLOOR, type AISDKConvertedMessage, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, type AttachCacheControlResult, BestPracticeAdvisory, type BrainConfig, type BrainQueryConfig, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, DEFAULT_FINDINGS_ENDPOINT, type ExclusionFindingRow, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type FallbackPosture, type GetActionableAdvisoriesOptions, type GetDefaultFallbackChainOpts, type GetPerAxisMetricsOpts, Grounding, IntentArchetypeName, type LLMJudgeOptions, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, PROVIDER_ENV_KEYS, PerAxisMetrics, type PricingRow, type ProfileToRowOptions, PromptIR, Provider, ProviderOverrides, type ProviderReachability, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, SectionRewrite, type SupportedProvider, SystemModelMessage, TRANSLATOR_FLOOR, applySectionRewrites, attachCacheControlToStreamTextInput, buildLLMJudge, call, clearBrain, compile, configureBrain, countTokens, execute, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStaleExclusionFindings, getStarterChain, getStarterChainWithGrounding, isBrainQueryActiveFor, isExclusionFindingsBrainActive, isModelReachable, isProviderReachable, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, markAdvisoryResolved, profileToRow, record, recordOutcome, resetTokenizer, resolvePricingAt, resolveProviderKey, runAdvisor, setTokenizer };
1704
+ export { ABSOLUTE_FLOOR, type AISDKConvertedMessage, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, type AttachCacheControlResult, BestPracticeAdvisory, type BrainConfig, type BrainQueryConfig, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, DEFAULT_FINDINGS_ENDPOINT, type ExclusionFindingRow, type ExclusionResolutionSource, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type FallbackPosture, type GetActionableAdvisoriesOptions, type GetDefaultFallbackChainOpts, type GetPerAxisMetricsOpts, Grounding, IntentArchetypeName, type LLMJudgeOptions, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type MarkExclusionFindingHandledOptions, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, PROVIDER_ENV_KEYS, PerAxisMetrics, type PricingRow, type ProfileToRowOptions, PromptIR, Provider, ProviderOverrides, type ProviderReachability, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, SectionRewrite, type SupportedProvider, SystemModelMessage, TRANSLATOR_FLOOR, applySectionRewrites, attachCacheControlToStreamTextInput, buildLLMJudge, call, clearBrain, compile, configureBrain, countTokens, execute, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStaleExclusionFindings, getStarterChain, getStarterChainWithGrounding, isBrainQueryActiveFor, isExclusionFindingsBrainActive, isModelReachable, isProviderReachable, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, markAdvisoryResolved, markExclusionFindingHandled, profileToRow, record, recordOutcome, resetTokenizer, resolvePricingAt, resolveProviderKey, runAdvisor, setTokenizer };
package/dist/index.d.ts CHANGED
@@ -768,6 +768,80 @@ declare function markAdvisoryResolved(opts: MarkAdvisoryResolvedOptions): Promis
768
768
  ok: false;
769
769
  reason: string;
770
770
  }>;
771
+ /**
772
+ * Resolution sources supported by the alpha.39 `markExclusionFindingHandled`
773
+ * API. Mirrors the subset of `exclusion_findings.resolution_source` CHECK
774
+ * constraint values that consumers can self-set:
775
+ *
776
+ * - `'consumer-marked'` — generic "we've handled this; stop reminding."
777
+ * Use this for "we evaluated and chose not to act" or "we'll act when
778
+ * ready but acknowledge the finding now."
779
+ * - `'declined'` — explicit "this exclusion is intentional; do not surface
780
+ * again." Stronger signal than consumer-marked; useful for compliance
781
+ * exclusions, brand-promise exclusions, etc.
782
+ * - `'probed-unblock'` — alpha.40+ probe-path verdict: consumer ran a live
783
+ * probe and decided to unblock the excluded model. Library accepts the
784
+ * value today so the probe path doesn't need a follow-up API release.
785
+ * - `'probed-stay-excluded'` — alpha.40+ probe-path verdict: consumer
786
+ * probed and confirmed the exclusion. Same forward-compat shape as
787
+ * `'probed-unblock'`.
788
+ *
789
+ * The `'auto'` resolution_source is NOT exposed here — that's reserved
790
+ * for the brain's own automatic resolution (e.g. when the detection
791
+ * conditions no longer hold). Consumer code sets only the four values
792
+ * above.
793
+ */
794
+ type ExclusionResolutionSource = 'consumer-marked' | 'declined' | 'probed-unblock' | 'probed-stay-excluded';
795
+ interface MarkExclusionFindingHandledOptions {
796
+ /** App id the finding belongs to. Required (RLS scopes writes by this). */
797
+ appId: string;
798
+ /** Archetype the finding applies to (e.g. 'hunt', 'classify'). */
799
+ archetype: string;
800
+ /** Canonical model id that the consumer had excluded. */
801
+ excludedModel: string;
802
+ /** Resolution semantics — see `ExclusionResolutionSource` for the four
803
+ * values consumers can set. */
804
+ resolution: ExclusionResolutionSource;
805
+ /** Optional free-form note explaining the decision. Surfaces in operator
806
+ * digests + dashboards alongside the resolution_source. */
807
+ resolutionNote?: string;
808
+ /** Brain Supabase URL base (e.g. `https://<project>.supabase.co`). The
809
+ * function appends `/rest/v1/exclusion_findings?...`. */
810
+ brainEndpoint: string;
811
+ /** Consumer-scoped JWT carrying the `app_id` claim. The brain's RLS
812
+ * policy enforces that the JWT's app_id matches the finding's app_id;
813
+ * cross-tenant writes fail at the database layer regardless of input. */
814
+ brainJwt: string;
815
+ /** Supabase anon key for the `apikey` header (PostgREST requires it). */
816
+ brainAnonKey: string;
817
+ /** Injected fetch for tests. Defaults to global fetch. */
818
+ fetch?: typeof fetch;
819
+ }
820
+ /**
821
+ * Mark a stale-exclusion finding as handled. Returns an `ok/reason` envelope
822
+ * matching `markAdvisoryResolved` — consumer Admin UIs typically render the
823
+ * failure inline rather than crash.
824
+ *
825
+ * Idempotent: if no row matches the (app_id, archetype, excludedModel)
826
+ * tuple (already resolved, never existed, cron not yet UPSERTed), PostgREST
827
+ * returns 200 with zero affected rows and we return `{ ok: true }`. The
828
+ * caller's "I marked it as handled" intent is satisfied regardless of
829
+ * whether the row was already in that state.
830
+ *
831
+ * Reasons surfaced on failure:
832
+ * - `app_id_required` / `archetype_required` / `excluded_model_required`
833
+ * - `resolution_invalid` — `resolution` not one of the four documented values
834
+ * - `brain_auth_misconfig` — 401/403 (JWT / anon key wrong)
835
+ * - `brain_unavailable` — 5xx
836
+ * - `network_error:<message>` — fetch threw
837
+ * - `patch_failed:<status>` — anything else non-2xx
838
+ */
839
+ declare function markExclusionFindingHandled(opts: MarkExclusionFindingHandledOptions): Promise<{
840
+ ok: true;
841
+ } | {
842
+ ok: false;
843
+ reason: string;
844
+ }>;
771
845
 
772
846
  /**
773
847
  * Archetype-cliff compatibility — alpha.28 (tt-intel-Cairn ratified).
@@ -1627,4 +1701,4 @@ declare function getStaleExclusionFindings(opts: GetExclusionFindingsOpts): Excl
1627
1701
  */
1628
1702
  declare function compile(ir: PromptIR, opts?: CompileOptions): CompileResult;
1629
1703
 
1630
- export { ABSOLUTE_FLOOR, type AISDKConvertedMessage, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, type AttachCacheControlResult, BestPracticeAdvisory, type BrainConfig, type BrainQueryConfig, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, DEFAULT_FINDINGS_ENDPOINT, type ExclusionFindingRow, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type FallbackPosture, type GetActionableAdvisoriesOptions, type GetDefaultFallbackChainOpts, type GetPerAxisMetricsOpts, Grounding, IntentArchetypeName, type LLMJudgeOptions, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, PROVIDER_ENV_KEYS, PerAxisMetrics, type PricingRow, type ProfileToRowOptions, PromptIR, Provider, ProviderOverrides, type ProviderReachability, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, SectionRewrite, type SupportedProvider, SystemModelMessage, TRANSLATOR_FLOOR, applySectionRewrites, attachCacheControlToStreamTextInput, buildLLMJudge, call, clearBrain, compile, configureBrain, countTokens, execute, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStaleExclusionFindings, getStarterChain, getStarterChainWithGrounding, isBrainQueryActiveFor, isExclusionFindingsBrainActive, isModelReachable, isProviderReachable, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, markAdvisoryResolved, profileToRow, record, recordOutcome, resetTokenizer, resolvePricingAt, resolveProviderKey, runAdvisor, setTokenizer };
1704
+ export { ABSOLUTE_FLOOR, type AISDKConvertedMessage, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, type AttachCacheControlResult, BestPracticeAdvisory, type BrainConfig, type BrainQueryConfig, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, DEFAULT_FINDINGS_ENDPOINT, type ExclusionFindingRow, type ExclusionResolutionSource, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type FallbackPosture, type GetActionableAdvisoriesOptions, type GetDefaultFallbackChainOpts, type GetPerAxisMetricsOpts, Grounding, IntentArchetypeName, type LLMJudgeOptions, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type MarkExclusionFindingHandledOptions, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, PROVIDER_ENV_KEYS, PerAxisMetrics, type PricingRow, type ProfileToRowOptions, PromptIR, Provider, ProviderOverrides, type ProviderReachability, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, SectionRewrite, type SupportedProvider, SystemModelMessage, TRANSLATOR_FLOOR, applySectionRewrites, attachCacheControlToStreamTextInput, buildLLMJudge, call, clearBrain, compile, configureBrain, countTokens, execute, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStaleExclusionFindings, getStarterChain, getStarterChainWithGrounding, isBrainQueryActiveFor, isExclusionFindingsBrainActive, isModelReachable, isProviderReachable, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, markAdvisoryResolved, markExclusionFindingHandled, profileToRow, record, recordOutcome, resetTokenizer, resolvePricingAt, resolveProviderKey, runAdvisor, setTokenizer };
package/dist/index.js CHANGED
@@ -74,6 +74,7 @@ __export(index_exports, {
74
74
  loadModelsFromBrain: () => loadModelsFromBrain,
75
75
  loadPricingFromBrain: () => loadPricingFromBrain,
76
76
  markAdvisoryResolved: () => markAdvisoryResolved,
77
+ markExclusionFindingHandled: () => markExclusionFindingHandled,
77
78
  profileToRow: () => profileToRow,
78
79
  profilesByProvider: () => profilesByProvider,
79
80
  record: () => record,
@@ -5433,6 +5434,66 @@ async function markAdvisoryResolved(opts) {
5433
5434
  }
5434
5435
  return { ok: true };
5435
5436
  }
5437
+ async function markExclusionFindingHandled(opts) {
5438
+ const {
5439
+ appId,
5440
+ archetype,
5441
+ excludedModel,
5442
+ resolution,
5443
+ resolutionNote,
5444
+ brainEndpoint,
5445
+ brainJwt,
5446
+ brainAnonKey,
5447
+ fetch: injectedFetch
5448
+ } = opts;
5449
+ if (!appId) return { ok: false, reason: "app_id_required" };
5450
+ if (!archetype) return { ok: false, reason: "archetype_required" };
5451
+ if (!excludedModel) {
5452
+ return { ok: false, reason: "excluded_model_required" };
5453
+ }
5454
+ if (resolution !== "consumer-marked" && resolution !== "declined" && resolution !== "probed-unblock" && resolution !== "probed-stay-excluded") {
5455
+ return { ok: false, reason: "resolution_invalid" };
5456
+ }
5457
+ const doFetch = resolveFetch(injectedFetch);
5458
+ const base = normalizeEndpoint(brainEndpoint);
5459
+ const url = `${base}/rest/v1/exclusion_findings?app_id=eq.${encodeURIComponent(appId)}&intent_archetype=eq.${encodeURIComponent(archetype)}&excluded_model=eq.${encodeURIComponent(excludedModel)}&resolved_at=is.null`;
5460
+ const patchBody = {
5461
+ resolved_at: (/* @__PURE__ */ new Date()).toISOString(),
5462
+ resolution_source: resolution
5463
+ };
5464
+ if (resolutionNote !== void 0) {
5465
+ patchBody.resolution_note = resolutionNote;
5466
+ }
5467
+ let res;
5468
+ try {
5469
+ res = await doFetch(url, {
5470
+ method: "PATCH",
5471
+ headers: {
5472
+ Authorization: `Bearer ${brainJwt}`,
5473
+ apikey: brainAnonKey,
5474
+ "Content-Type": "application/json",
5475
+ Accept: "application/json",
5476
+ // PATCH may match zero rows when already resolved — return=minimal
5477
+ // keeps the response body empty so the success path is uniform.
5478
+ Prefer: "return=minimal"
5479
+ },
5480
+ body: JSON.stringify(patchBody)
5481
+ });
5482
+ } catch (err) {
5483
+ const msg = err instanceof Error ? err.message : String(err);
5484
+ return { ok: false, reason: `network_error:${msg}` };
5485
+ }
5486
+ if (res.status === 401 || res.status === 403) {
5487
+ return { ok: false, reason: "brain_auth_misconfig" };
5488
+ }
5489
+ if (res.status >= 500) {
5490
+ return { ok: false, reason: "brain_unavailable" };
5491
+ }
5492
+ if (!res.ok) {
5493
+ return { ok: false, reason: `patch_failed:${res.status}` };
5494
+ }
5495
+ return { ok: true };
5496
+ }
5436
5497
 
5437
5498
  // src/models-brain.ts
5438
5499
  function isModelRow(x) {
@@ -5615,6 +5676,7 @@ function compile2(ir, opts) {
5615
5676
  loadModelsFromBrain,
5616
5677
  loadPricingFromBrain,
5617
5678
  markAdvisoryResolved,
5679
+ markExclusionFindingHandled,
5618
5680
  profileToRow,
5619
5681
  profilesByProvider,
5620
5682
  record,
package/dist/index.mjs CHANGED
@@ -3150,6 +3150,66 @@ async function markAdvisoryResolved(opts) {
3150
3150
  }
3151
3151
  return { ok: true };
3152
3152
  }
3153
+ async function markExclusionFindingHandled(opts) {
3154
+ const {
3155
+ appId,
3156
+ archetype,
3157
+ excludedModel,
3158
+ resolution,
3159
+ resolutionNote,
3160
+ brainEndpoint,
3161
+ brainJwt,
3162
+ brainAnonKey,
3163
+ fetch: injectedFetch
3164
+ } = opts;
3165
+ if (!appId) return { ok: false, reason: "app_id_required" };
3166
+ if (!archetype) return { ok: false, reason: "archetype_required" };
3167
+ if (!excludedModel) {
3168
+ return { ok: false, reason: "excluded_model_required" };
3169
+ }
3170
+ if (resolution !== "consumer-marked" && resolution !== "declined" && resolution !== "probed-unblock" && resolution !== "probed-stay-excluded") {
3171
+ return { ok: false, reason: "resolution_invalid" };
3172
+ }
3173
+ const doFetch = resolveFetch(injectedFetch);
3174
+ const base = normalizeEndpoint(brainEndpoint);
3175
+ const url = `${base}/rest/v1/exclusion_findings?app_id=eq.${encodeURIComponent(appId)}&intent_archetype=eq.${encodeURIComponent(archetype)}&excluded_model=eq.${encodeURIComponent(excludedModel)}&resolved_at=is.null`;
3176
+ const patchBody = {
3177
+ resolved_at: (/* @__PURE__ */ new Date()).toISOString(),
3178
+ resolution_source: resolution
3179
+ };
3180
+ if (resolutionNote !== void 0) {
3181
+ patchBody.resolution_note = resolutionNote;
3182
+ }
3183
+ let res;
3184
+ try {
3185
+ res = await doFetch(url, {
3186
+ method: "PATCH",
3187
+ headers: {
3188
+ Authorization: `Bearer ${brainJwt}`,
3189
+ apikey: brainAnonKey,
3190
+ "Content-Type": "application/json",
3191
+ Accept: "application/json",
3192
+ // PATCH may match zero rows when already resolved — return=minimal
3193
+ // keeps the response body empty so the success path is uniform.
3194
+ Prefer: "return=minimal"
3195
+ },
3196
+ body: JSON.stringify(patchBody)
3197
+ });
3198
+ } catch (err) {
3199
+ const msg = err instanceof Error ? err.message : String(err);
3200
+ return { ok: false, reason: `network_error:${msg}` };
3201
+ }
3202
+ if (res.status === 401 || res.status === 403) {
3203
+ return { ok: false, reason: "brain_auth_misconfig" };
3204
+ }
3205
+ if (res.status >= 500) {
3206
+ return { ok: false, reason: "brain_unavailable" };
3207
+ }
3208
+ if (!res.ok) {
3209
+ return { ok: false, reason: `patch_failed:${res.status}` };
3210
+ }
3211
+ return { ok: true };
3212
+ }
3153
3213
 
3154
3214
  // src/models-brain.ts
3155
3215
  function isModelRow(x) {
@@ -3331,6 +3391,7 @@ export {
3331
3391
  loadModelsFromBrain,
3332
3392
  loadPricingFromBrain,
3333
3393
  markAdvisoryResolved,
3394
+ markExclusionFindingHandled,
3334
3395
  profileToRow,
3335
3396
  profilesByProvider,
3336
3397
  record,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmdrift/kgauto-compiler",
3
- "version": "2.0.0-alpha.38",
3
+ "version": "2.0.0-alpha.39",
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",