@warmdrift/kgauto-compiler 2.0.0-alpha.28 → 2.0.0-alpha.29
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/README.md +42 -0
- package/dist/glassbox/index.d.mts +3 -3
- package/dist/glassbox/index.d.ts +3 -3
- package/dist/glassbox-routes/index.d.mts +31 -2
- package/dist/glassbox-routes/index.d.ts +31 -2
- package/dist/glassbox-routes/index.js +39 -0
- package/dist/glassbox-routes/index.mjs +39 -0
- package/dist/index.d.mts +292 -13
- package/dist/index.d.ts +292 -13
- package/dist/index.js +385 -8
- package/dist/index.mjs +380 -8
- package/dist/{ir-5W0efxt9.d.ts → ir-BIAT9gJk.d.ts} +110 -1
- package/dist/{ir-MXCJA8L7.d.mts → ir-De2AQtlr.d.mts} +110 -1
- package/dist/profiles.d.mts +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/{types-sDZQzPM6.d.mts → types-BjrIFPGe.d.mts} +1 -1
- package/dist/{types-CiZ9HLIU.d.ts → types-D_JAhCv4.d.ts} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29,7 +29,10 @@ __export(index_exports, {
|
|
|
29
29
|
INTENT_ARCHETYPES: () => INTENT_ARCHETYPES,
|
|
30
30
|
MEASURED_GROUNDING_MIN_N: () => MEASURED_GROUNDING_MIN_N,
|
|
31
31
|
PROVIDER_ENV_KEYS: () => PROVIDER_ENV_KEYS,
|
|
32
|
+
RULE_SEQUENTIAL_TOOL_CLIFF: () => RULE_SEQUENTIAL_TOOL_CLIFF,
|
|
33
|
+
TRANSLATOR_FLOOR: () => TRANSLATOR_FLOOR,
|
|
32
34
|
allProfiles: () => allProfiles,
|
|
35
|
+
applySectionRewrites: () => applySectionRewrites,
|
|
33
36
|
bucketContext: () => bucketContext,
|
|
34
37
|
bucketHistory: () => bucketHistory,
|
|
35
38
|
bucketToolCount: () => bucketToolCount,
|
|
@@ -40,6 +43,7 @@ __export(index_exports, {
|
|
|
40
43
|
configureBrain: () => configureBrain,
|
|
41
44
|
countTokens: () => countTokens,
|
|
42
45
|
execute: () => execute,
|
|
46
|
+
getActionableAdvisories: () => getActionableAdvisories,
|
|
43
47
|
getAllStarterChains: () => getAllStarterChains,
|
|
44
48
|
getAllStarterChainsWithGrounding: () => getAllStarterChainsWithGrounding,
|
|
45
49
|
getArchetypePerfScore: () => getArchetypePerfScore,
|
|
@@ -65,6 +69,7 @@ __export(index_exports, {
|
|
|
65
69
|
loadChainsFromBrain: () => loadChainsFromBrain,
|
|
66
70
|
loadModelsFromBrain: () => loadModelsFromBrain,
|
|
67
71
|
loadPricingFromBrain: () => loadPricingFromBrain,
|
|
72
|
+
markAdvisoryResolved: () => markAdvisoryResolved,
|
|
68
73
|
profileToRow: () => profileToRow,
|
|
69
74
|
profilesByProvider: () => profilesByProvider,
|
|
70
75
|
record: () => record,
|
|
@@ -586,6 +591,7 @@ function lowerAnthropic(ir, profile, hints) {
|
|
|
586
591
|
const historyCacheableTokens = markIndex >= 0 ? sumHistoryTokens(history, markIndex) : 0;
|
|
587
592
|
const totalCacheableTokens = cacheableTokens + historyCacheableTokens;
|
|
588
593
|
const cacheSavings = totalCacheableTokens / 1e6 * profile.costInputPer1m * (1 - (profile.lowering.cache.discount ?? 0.1));
|
|
594
|
+
const toolChoice = hints.wireOverrides?.parallelToolCalls === false && tools && tools.length > 0 ? { type: "auto", disable_parallel_tool_use: true } : void 0;
|
|
589
595
|
return {
|
|
590
596
|
request: {
|
|
591
597
|
provider: "anthropic",
|
|
@@ -597,7 +603,8 @@ function lowerAnthropic(ir, profile, hints) {
|
|
|
597
603
|
// floor surprised every consumer once (PB-Cairn contract-gaps brief, Gap 3).
|
|
598
604
|
// Profile is the single source of truth; consumers wanting a tighter
|
|
599
605
|
// budget can pass providerOverrides.anthropic.max_tokens explicitly.
|
|
600
|
-
max_tokens: hints.forceTerseOutput ? 200 : profile.maxOutputTokens
|
|
606
|
+
max_tokens: hints.forceTerseOutput ? 200 : profile.maxOutputTokens,
|
|
607
|
+
tool_choice: toolChoice
|
|
601
608
|
},
|
|
602
609
|
diagnostics: {
|
|
603
610
|
cacheableTokens,
|
|
@@ -791,6 +798,7 @@ function lowerOpenAI(ir, profile, hints) {
|
|
|
791
798
|
const history = (ir.history ?? []).filter((m) => m.role !== "system");
|
|
792
799
|
const histMarkIndex = resolveHistoryMarkIndex(history.length, ir.historyCachePolicy);
|
|
793
800
|
const historyCacheableTokens = histMarkIndex >= 0 ? sumHistoryTokens(history, histMarkIndex) : 0;
|
|
801
|
+
const openaiParallelToolCalls = hints.wireOverrides?.parallelToolCalls === false && ir.tools && ir.tools.length > 0 ? false : void 0;
|
|
794
802
|
return {
|
|
795
803
|
request: {
|
|
796
804
|
provider: "openai",
|
|
@@ -798,7 +806,8 @@ function lowerOpenAI(ir, profile, hints) {
|
|
|
798
806
|
messages,
|
|
799
807
|
tools: ir.tools && ir.tools.length > 0 ? toOpenAITools(ir.tools) : void 0,
|
|
800
808
|
response_format: ir.constraints?.structuredOutput ? { type: "json_object" } : void 0,
|
|
801
|
-
reasoning_effort: hints.forceTerseOutput ? "low" : void 0
|
|
809
|
+
reasoning_effort: hints.forceTerseOutput ? "low" : void 0,
|
|
810
|
+
parallel_tool_calls: openaiParallelToolCalls
|
|
802
811
|
},
|
|
803
812
|
diagnostics: {
|
|
804
813
|
cacheableTokens: 0,
|
|
@@ -2406,9 +2415,19 @@ function runAdvisor(ir, result, profile, policy, phase2) {
|
|
|
2406
2415
|
out.push(...detectModelStaleEvidence(ir, profile));
|
|
2407
2416
|
out.push(...detectTierDown(ir, profile, phase2));
|
|
2408
2417
|
}
|
|
2409
|
-
|
|
2418
|
+
if (!translatorClearedToolCallCliff(phase2)) {
|
|
2419
|
+
out.push(...detectArchetypePerfFloorBreach(ir, profile));
|
|
2420
|
+
}
|
|
2410
2421
|
return out;
|
|
2411
2422
|
}
|
|
2423
|
+
function translatorClearedToolCallCliff(phase2) {
|
|
2424
|
+
const rewrites = phase2?.sectionRewritesApplied;
|
|
2425
|
+
if (!rewrites || rewrites.length === 0) return false;
|
|
2426
|
+
for (const rw of rewrites) {
|
|
2427
|
+
if (rw.kind === "tool_call_contract") return true;
|
|
2428
|
+
}
|
|
2429
|
+
return false;
|
|
2430
|
+
}
|
|
2412
2431
|
function detectCachingOff(ir, profile) {
|
|
2413
2432
|
if (profile.provider !== "anthropic") return [];
|
|
2414
2433
|
const totalChars = ir.sections.reduce((s, sec) => s + sec.text.length, 0);
|
|
@@ -2608,6 +2627,47 @@ function detectArchetypePerfFloorBreach(ir, profile) {
|
|
|
2608
2627
|
];
|
|
2609
2628
|
}
|
|
2610
2629
|
|
|
2630
|
+
// src/translator.ts
|
|
2631
|
+
var TRANSLATOR_FLOOR = ARCHETYPE_FLOOR_DEFAULT;
|
|
2632
|
+
var RULE_SEQUENTIAL_TOOL_CLIFF = "sequential-tool-cliff-below-floor";
|
|
2633
|
+
var SEQUENTIAL_TOOL_PREAMBLE = "IMPORTANT: Use one tool call per response. Wait for the tool result before deciding the next tool. Do NOT batch tool calls in parallel.";
|
|
2634
|
+
function applySectionRewrites(args) {
|
|
2635
|
+
const { ir, profile, archetype } = args;
|
|
2636
|
+
if (!Array.isArray(ir.sections) || ir.sections.length === 0) {
|
|
2637
|
+
return { rewrittenIR: ir, rewrites: [] };
|
|
2638
|
+
}
|
|
2639
|
+
if (!profile.archetypePerf) {
|
|
2640
|
+
return { rewrittenIR: ir, rewrites: [] };
|
|
2641
|
+
}
|
|
2642
|
+
const archetypeScore = profile.archetypePerf[archetype];
|
|
2643
|
+
const cliffFires = typeof archetypeScore === "number" && archetypeScore < TRANSLATOR_FLOOR;
|
|
2644
|
+
if (!cliffFires) {
|
|
2645
|
+
return { rewrittenIR: ir, rewrites: [] };
|
|
2646
|
+
}
|
|
2647
|
+
const rewrites = [];
|
|
2648
|
+
const newSections = ir.sections.map((section) => {
|
|
2649
|
+
if (section.kind !== "tool_call_contract") return section;
|
|
2650
|
+
const originalText = section.text;
|
|
2651
|
+
const transformedText = `${SEQUENTIAL_TOOL_PREAMBLE}
|
|
2652
|
+
|
|
2653
|
+
${originalText}`;
|
|
2654
|
+
rewrites.push({
|
|
2655
|
+
sectionId: section.id,
|
|
2656
|
+
kind: "tool_call_contract",
|
|
2657
|
+
rule: RULE_SEQUENTIAL_TOOL_CLIFF,
|
|
2658
|
+
originalText,
|
|
2659
|
+
transformedText,
|
|
2660
|
+
wireOverrides: { parallelToolCalls: false }
|
|
2661
|
+
});
|
|
2662
|
+
return { ...section, text: transformedText };
|
|
2663
|
+
});
|
|
2664
|
+
if (rewrites.length === 0) {
|
|
2665
|
+
return { rewrittenIR: ir, rewrites: [] };
|
|
2666
|
+
}
|
|
2667
|
+
const rewrittenIR = { ...ir, sections: newSections };
|
|
2668
|
+
return { rewrittenIR, rewrites };
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2611
2671
|
// src/compile.ts
|
|
2612
2672
|
var counter = 0;
|
|
2613
2673
|
function makeHandle() {
|
|
@@ -2651,9 +2711,33 @@ function compile(ir, opts = {}) {
|
|
|
2651
2711
|
const cliffs = passApplyCliffs(workingIR, profile, inputTokens);
|
|
2652
2712
|
workingIR = cliffs.value.ir;
|
|
2653
2713
|
accumulatedMutations.push(...cliffs.mutations);
|
|
2714
|
+
const translated = applySectionRewrites({
|
|
2715
|
+
ir: workingIR,
|
|
2716
|
+
profile,
|
|
2717
|
+
archetype: ir.intent.archetype
|
|
2718
|
+
});
|
|
2719
|
+
workingIR = translated.rewrittenIR;
|
|
2720
|
+
const sectionRewritesApplied = translated.rewrites;
|
|
2721
|
+
let wireOverrides;
|
|
2722
|
+
for (const rw of sectionRewritesApplied) {
|
|
2723
|
+
if (!rw.wireOverrides) continue;
|
|
2724
|
+
if (!wireOverrides) wireOverrides = {};
|
|
2725
|
+
if (rw.wireOverrides.parallelToolCalls !== void 0) {
|
|
2726
|
+
wireOverrides.parallelToolCalls = rw.wireOverrides.parallelToolCalls;
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
for (const rw of sectionRewritesApplied) {
|
|
2730
|
+
accumulatedMutations.push({
|
|
2731
|
+
id: `translator:${rw.rule}:${rw.sectionId}`,
|
|
2732
|
+
source: "translator",
|
|
2733
|
+
passName: "translator",
|
|
2734
|
+
description: `Rewrote section "${rw.sectionId}" (kind=${rw.kind}) via rule "${rw.rule}".`
|
|
2735
|
+
});
|
|
2736
|
+
}
|
|
2654
2737
|
const lowered = lower(workingIR, profile, {
|
|
2655
2738
|
forceThinkingZero: cliffs.value.loweringHints.forceThinkingZero,
|
|
2656
|
-
forceTerseOutput: cliffs.value.loweringHints.forceTerseOutput
|
|
2739
|
+
forceTerseOutput: cliffs.value.loweringHints.forceTerseOutput,
|
|
2740
|
+
wireOverrides
|
|
2657
2741
|
});
|
|
2658
2742
|
validateFinalFit(workingIR, profile, inputTokens);
|
|
2659
2743
|
const handle = makeHandle();
|
|
@@ -2701,7 +2785,13 @@ function compile(ir, opts = {}) {
|
|
|
2701
2785
|
opts.policy,
|
|
2702
2786
|
{
|
|
2703
2787
|
fallbackChain,
|
|
2704
|
-
profileResolver: phase2ProfileResolver
|
|
2788
|
+
profileResolver: phase2ProfileResolver,
|
|
2789
|
+
// alpha.29 — feed translator rewrites to the advisor so the
|
|
2790
|
+
// `archetype-perf-floor-breach` rule can suppress when the translator
|
|
2791
|
+
// already cleared the cliff for the same archetype. Without this,
|
|
2792
|
+
// both the rewrite AND the advisory fire — noisy, and the advisory
|
|
2793
|
+
// would mislead consumers into thinking the cliff is unaddressed.
|
|
2794
|
+
sectionRewritesApplied
|
|
2705
2795
|
}
|
|
2706
2796
|
);
|
|
2707
2797
|
return {
|
|
@@ -2714,7 +2804,9 @@ function compile(ir, opts = {}) {
|
|
|
2714
2804
|
mutationsApplied: accumulatedMutations,
|
|
2715
2805
|
fallbackChain,
|
|
2716
2806
|
advisories,
|
|
2717
|
-
diagnostics
|
|
2807
|
+
diagnostics,
|
|
2808
|
+
sectionRewritesApplied,
|
|
2809
|
+
wireOverrides
|
|
2718
2810
|
};
|
|
2719
2811
|
}
|
|
2720
2812
|
function validateIR(ir) {
|
|
@@ -2887,7 +2979,11 @@ function registerCompile(appId, archetype, ir, result) {
|
|
|
2887
2979
|
// alpha.28: shape fields for Glass-Box renderer.
|
|
2888
2980
|
toolsCount,
|
|
2889
2981
|
historyDepth,
|
|
2890
|
-
systemPromptChars
|
|
2982
|
+
systemPromptChars,
|
|
2983
|
+
// alpha.29: translator activity — persisted on the brain row so
|
|
2984
|
+
// cross-app aggregates can answer "Sonnet narration rule fired N times,
|
|
2985
|
+
// outcome quality lifted to M."
|
|
2986
|
+
sectionRewritesApplied: result.sectionRewritesApplied
|
|
2891
2987
|
});
|
|
2892
2988
|
}
|
|
2893
2989
|
function estimateSystemPromptChars(sections) {
|
|
@@ -3023,7 +3119,11 @@ function buildPayload(input, reg) {
|
|
|
3023
3119
|
history_depth: input.historyDepth ?? reg?.historyDepth,
|
|
3024
3120
|
system_prompt_chars: input.systemPromptChars ?? reg?.systemPromptChars,
|
|
3025
3121
|
fell_over_from: fellOverFrom,
|
|
3026
|
-
fallback_reason: fallbackReason
|
|
3122
|
+
fallback_reason: fallbackReason,
|
|
3123
|
+
// alpha.29 — translator activity (migration 019). Send NULL when no
|
|
3124
|
+
// rewrites fired so the brain's "did the translator do anything?"
|
|
3125
|
+
// queries can use `IS NOT NULL` cleanly.
|
|
3126
|
+
section_rewrites_applied: reg?.sectionRewritesApplied && reg.sectionRewritesApplied.length > 0 ? reg.sectionRewritesApplied : null
|
|
3027
3127
|
};
|
|
3028
3128
|
}
|
|
3029
3129
|
function computeCostUsd(modelId, tokensIn, tokensOut) {
|
|
@@ -4478,6 +4578,278 @@ function clamp(n) {
|
|
|
4478
4578
|
return Math.max(0, Math.min(1, n));
|
|
4479
4579
|
}
|
|
4480
4580
|
|
|
4581
|
+
// src/advisories-api.ts
|
|
4582
|
+
var SEVERITY_SET = /* @__PURE__ */ new Set(["info", "warn", "critical"]);
|
|
4583
|
+
var STATUS_SET = /* @__PURE__ */ new Set(["open", "snoozed", "resolved"]);
|
|
4584
|
+
var RESOLUTION_SOURCE_SET = /* @__PURE__ */ new Set([
|
|
4585
|
+
"auto",
|
|
4586
|
+
"consumer-marked",
|
|
4587
|
+
"declined"
|
|
4588
|
+
]);
|
|
4589
|
+
function asString(v) {
|
|
4590
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
4591
|
+
}
|
|
4592
|
+
function asSeverity(v) {
|
|
4593
|
+
if (typeof v === "string" && SEVERITY_SET.has(v)) {
|
|
4594
|
+
return v;
|
|
4595
|
+
}
|
|
4596
|
+
return "info";
|
|
4597
|
+
}
|
|
4598
|
+
function asStatus(v) {
|
|
4599
|
+
if (typeof v === "string" && STATUS_SET.has(v)) {
|
|
4600
|
+
return v;
|
|
4601
|
+
}
|
|
4602
|
+
return "open";
|
|
4603
|
+
}
|
|
4604
|
+
function asResolutionSource(v) {
|
|
4605
|
+
if (typeof v === "string" && RESOLUTION_SOURCE_SET.has(v)) {
|
|
4606
|
+
return v;
|
|
4607
|
+
}
|
|
4608
|
+
return void 0;
|
|
4609
|
+
}
|
|
4610
|
+
function rowToAdvisory(row) {
|
|
4611
|
+
const archetype = asString(row.applies_to_archetype);
|
|
4612
|
+
const model = asString(row.applies_to_model);
|
|
4613
|
+
const docsLink = asString(row.docs_url);
|
|
4614
|
+
const suggestion = asString(row.suggestion);
|
|
4615
|
+
let suggestedFix = null;
|
|
4616
|
+
if (docsLink || suggestion) {
|
|
4617
|
+
suggestedFix = { type: "manual" };
|
|
4618
|
+
if (docsLink) suggestedFix.docsLink = docsLink;
|
|
4619
|
+
if (suggestion) suggestedFix.before = suggestion;
|
|
4620
|
+
}
|
|
4621
|
+
const out = {
|
|
4622
|
+
id: typeof row.id === "string" ? row.id : "",
|
|
4623
|
+
rule: typeof row.rule === "string" ? row.rule : "",
|
|
4624
|
+
severity: asSeverity(row.severity),
|
|
4625
|
+
openedAt: typeof row.opened_at === "string" ? row.opened_at : "",
|
|
4626
|
+
lastObservedAt: typeof row.last_observed_at === "string" ? row.last_observed_at : "",
|
|
4627
|
+
observationCount: typeof row.observation_count === "number" ? row.observation_count : 0,
|
|
4628
|
+
appliesTo: {
|
|
4629
|
+
...archetype ? { archetype } : {},
|
|
4630
|
+
...model ? { model } : {}
|
|
4631
|
+
},
|
|
4632
|
+
message: typeof row.message === "string" ? row.message : "",
|
|
4633
|
+
suggestedFix,
|
|
4634
|
+
autoApplicable: false,
|
|
4635
|
+
// reserved — alpha.30+
|
|
4636
|
+
status: asStatus(row.status)
|
|
4637
|
+
};
|
|
4638
|
+
const resolvedAt = asString(row.resolved_at);
|
|
4639
|
+
if (resolvedAt) out.resolvedAt = resolvedAt;
|
|
4640
|
+
const resolutionSource = asResolutionSource(row.resolution_source);
|
|
4641
|
+
if (resolutionSource) out.resolutionSource = resolutionSource;
|
|
4642
|
+
const resolutionNote = asString(row.resolution_note);
|
|
4643
|
+
if (resolutionNote) out.resolutionNote = resolutionNote;
|
|
4644
|
+
return out;
|
|
4645
|
+
}
|
|
4646
|
+
function resolveFetch(injected) {
|
|
4647
|
+
return injected ?? ((...args) => globalThis.fetch(...args));
|
|
4648
|
+
}
|
|
4649
|
+
function normalizeEndpoint(endpoint) {
|
|
4650
|
+
return endpoint.replace(/\/+$/, "");
|
|
4651
|
+
}
|
|
4652
|
+
async function getActionableAdvisories(opts) {
|
|
4653
|
+
const {
|
|
4654
|
+
appId,
|
|
4655
|
+
severity,
|
|
4656
|
+
status,
|
|
4657
|
+
brainEndpoint,
|
|
4658
|
+
brainJwt,
|
|
4659
|
+
brainAnonKey,
|
|
4660
|
+
fetch: injectedFetch
|
|
4661
|
+
} = opts;
|
|
4662
|
+
if (!appId) {
|
|
4663
|
+
throw new Error("getActionableAdvisories: appId is required");
|
|
4664
|
+
}
|
|
4665
|
+
const doFetch = resolveFetch(injectedFetch);
|
|
4666
|
+
const base = normalizeEndpoint(brainEndpoint);
|
|
4667
|
+
const qs = new URLSearchParams();
|
|
4668
|
+
qs.set("app_id", `eq.${appId}`);
|
|
4669
|
+
if (severity) qs.set("severity", `eq.${severity}`);
|
|
4670
|
+
const effectiveStatus = status ?? "open";
|
|
4671
|
+
if (effectiveStatus !== "all") {
|
|
4672
|
+
qs.set("status", `eq.${effectiveStatus}`);
|
|
4673
|
+
}
|
|
4674
|
+
qs.set("order", "last_observed_at.desc");
|
|
4675
|
+
const url = `${base}/rest/v1/actionable_advisories_v?${qs.toString()}`;
|
|
4676
|
+
let res;
|
|
4677
|
+
try {
|
|
4678
|
+
res = await doFetch(url, {
|
|
4679
|
+
method: "GET",
|
|
4680
|
+
headers: {
|
|
4681
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
4682
|
+
apikey: brainAnonKey,
|
|
4683
|
+
Accept: "application/json"
|
|
4684
|
+
}
|
|
4685
|
+
});
|
|
4686
|
+
} catch (err) {
|
|
4687
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4688
|
+
throw new Error(`getActionableAdvisories: network error: ${msg}`);
|
|
4689
|
+
}
|
|
4690
|
+
if (res.status === 401 || res.status === 403) {
|
|
4691
|
+
throw new Error("getActionableAdvisories: brain auth misconfig");
|
|
4692
|
+
}
|
|
4693
|
+
if (res.status >= 500) {
|
|
4694
|
+
throw new Error(`getActionableAdvisories: brain unavailable (${res.status})`);
|
|
4695
|
+
}
|
|
4696
|
+
if (!res.ok) {
|
|
4697
|
+
throw new Error(`getActionableAdvisories: bad request (${res.status})`);
|
|
4698
|
+
}
|
|
4699
|
+
let rows;
|
|
4700
|
+
try {
|
|
4701
|
+
rows = await res.json();
|
|
4702
|
+
} catch {
|
|
4703
|
+
throw new Error("getActionableAdvisories: malformed brain response");
|
|
4704
|
+
}
|
|
4705
|
+
if (!Array.isArray(rows)) {
|
|
4706
|
+
throw new Error("getActionableAdvisories: expected array from brain");
|
|
4707
|
+
}
|
|
4708
|
+
const out = [];
|
|
4709
|
+
for (const raw of rows) {
|
|
4710
|
+
if (raw && typeof raw === "object") {
|
|
4711
|
+
out.push(rowToAdvisory(raw));
|
|
4712
|
+
}
|
|
4713
|
+
}
|
|
4714
|
+
return out;
|
|
4715
|
+
}
|
|
4716
|
+
async function markAdvisoryResolved(opts) {
|
|
4717
|
+
const {
|
|
4718
|
+
id,
|
|
4719
|
+
resolutionNote,
|
|
4720
|
+
brainEndpoint,
|
|
4721
|
+
brainJwt,
|
|
4722
|
+
brainAnonKey,
|
|
4723
|
+
fetch: injectedFetch
|
|
4724
|
+
} = opts;
|
|
4725
|
+
if (!id) {
|
|
4726
|
+
return { ok: false, reason: "id_required" };
|
|
4727
|
+
}
|
|
4728
|
+
const doFetch = resolveFetch(injectedFetch);
|
|
4729
|
+
const base = normalizeEndpoint(brainEndpoint);
|
|
4730
|
+
const lookupUrl = `${base}/rest/v1/actionable_advisories_v?id=eq.${encodeURIComponent(id)}&select=app_id,rule`;
|
|
4731
|
+
let lookupRes;
|
|
4732
|
+
try {
|
|
4733
|
+
lookupRes = await doFetch(lookupUrl, {
|
|
4734
|
+
method: "GET",
|
|
4735
|
+
headers: {
|
|
4736
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
4737
|
+
apikey: brainAnonKey,
|
|
4738
|
+
Accept: "application/json"
|
|
4739
|
+
}
|
|
4740
|
+
});
|
|
4741
|
+
} catch (err) {
|
|
4742
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4743
|
+
return { ok: false, reason: `network_error:${msg}` };
|
|
4744
|
+
}
|
|
4745
|
+
if (lookupRes.status === 401 || lookupRes.status === 403) {
|
|
4746
|
+
return { ok: false, reason: "brain_auth_misconfig" };
|
|
4747
|
+
}
|
|
4748
|
+
if (lookupRes.status >= 500) {
|
|
4749
|
+
return { ok: false, reason: "brain_unavailable" };
|
|
4750
|
+
}
|
|
4751
|
+
if (!lookupRes.ok) {
|
|
4752
|
+
return { ok: false, reason: `brain_lookup_failed:${lookupRes.status}` };
|
|
4753
|
+
}
|
|
4754
|
+
let lookupRows;
|
|
4755
|
+
try {
|
|
4756
|
+
lookupRows = await lookupRes.json();
|
|
4757
|
+
} catch {
|
|
4758
|
+
return { ok: false, reason: "brain_lookup_malformed" };
|
|
4759
|
+
}
|
|
4760
|
+
if (!Array.isArray(lookupRows) || lookupRows.length === 0) {
|
|
4761
|
+
return { ok: false, reason: "advisory_not_found" };
|
|
4762
|
+
}
|
|
4763
|
+
const tuple = lookupRows[0];
|
|
4764
|
+
const appId = typeof tuple.app_id === "string" ? tuple.app_id : "";
|
|
4765
|
+
const code = typeof tuple.rule === "string" ? tuple.rule : "";
|
|
4766
|
+
if (!appId || !code) {
|
|
4767
|
+
return { ok: false, reason: "advisory_tuple_invalid" };
|
|
4768
|
+
}
|
|
4769
|
+
const outcomesUrl = `${base}/rest/v1/compile_outcomes?app_id=eq.${encodeURIComponent(appId)}&select=id`;
|
|
4770
|
+
let outcomesRes;
|
|
4771
|
+
try {
|
|
4772
|
+
outcomesRes = await doFetch(outcomesUrl, {
|
|
4773
|
+
method: "GET",
|
|
4774
|
+
headers: {
|
|
4775
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
4776
|
+
apikey: brainAnonKey,
|
|
4777
|
+
Accept: "application/json"
|
|
4778
|
+
}
|
|
4779
|
+
});
|
|
4780
|
+
} catch (err) {
|
|
4781
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4782
|
+
return { ok: false, reason: `network_error:${msg}` };
|
|
4783
|
+
}
|
|
4784
|
+
if (outcomesRes.status === 401 || outcomesRes.status === 403) {
|
|
4785
|
+
return { ok: false, reason: "brain_auth_misconfig" };
|
|
4786
|
+
}
|
|
4787
|
+
if (outcomesRes.status >= 500) {
|
|
4788
|
+
return { ok: false, reason: "brain_unavailable" };
|
|
4789
|
+
}
|
|
4790
|
+
if (!outcomesRes.ok) {
|
|
4791
|
+
return { ok: false, reason: `brain_lookup_failed:${outcomesRes.status}` };
|
|
4792
|
+
}
|
|
4793
|
+
let outcomeRows;
|
|
4794
|
+
try {
|
|
4795
|
+
outcomeRows = await outcomesRes.json();
|
|
4796
|
+
} catch {
|
|
4797
|
+
return { ok: false, reason: "brain_lookup_malformed" };
|
|
4798
|
+
}
|
|
4799
|
+
if (!Array.isArray(outcomeRows)) {
|
|
4800
|
+
return { ok: false, reason: "brain_lookup_malformed" };
|
|
4801
|
+
}
|
|
4802
|
+
const outcomeIds = [];
|
|
4803
|
+
for (const row of outcomeRows) {
|
|
4804
|
+
if (row && typeof row === "object") {
|
|
4805
|
+
const idVal = row.id;
|
|
4806
|
+
if (typeof idVal === "number" && Number.isFinite(idVal)) {
|
|
4807
|
+
outcomeIds.push(idVal);
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
if (outcomeIds.length === 0) {
|
|
4812
|
+
return { ok: true };
|
|
4813
|
+
}
|
|
4814
|
+
const inList = outcomeIds.join(",");
|
|
4815
|
+
const patchUrl = `${base}/rest/v1/compile_outcome_advisories?outcome_id=in.(${inList})&code=eq.${encodeURIComponent(code)}&resolved_at=is.null`;
|
|
4816
|
+
const patchBody = {
|
|
4817
|
+
resolved_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4818
|
+
resolution_source: "consumer-marked"
|
|
4819
|
+
};
|
|
4820
|
+
if (resolutionNote !== void 0) {
|
|
4821
|
+
patchBody.resolution_note = resolutionNote;
|
|
4822
|
+
}
|
|
4823
|
+
let patchRes;
|
|
4824
|
+
try {
|
|
4825
|
+
patchRes = await doFetch(patchUrl, {
|
|
4826
|
+
method: "PATCH",
|
|
4827
|
+
headers: {
|
|
4828
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
4829
|
+
apikey: brainAnonKey,
|
|
4830
|
+
"Content-Type": "application/json",
|
|
4831
|
+
Accept: "application/json",
|
|
4832
|
+
// PostgREST default is no return; we don't need the row back.
|
|
4833
|
+
Prefer: "return=minimal"
|
|
4834
|
+
},
|
|
4835
|
+
body: JSON.stringify(patchBody)
|
|
4836
|
+
});
|
|
4837
|
+
} catch (err) {
|
|
4838
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4839
|
+
return { ok: false, reason: `network_error:${msg}` };
|
|
4840
|
+
}
|
|
4841
|
+
if (patchRes.status === 401 || patchRes.status === 403) {
|
|
4842
|
+
return { ok: false, reason: "brain_auth_misconfig" };
|
|
4843
|
+
}
|
|
4844
|
+
if (patchRes.status >= 500) {
|
|
4845
|
+
return { ok: false, reason: "brain_unavailable" };
|
|
4846
|
+
}
|
|
4847
|
+
if (!patchRes.ok) {
|
|
4848
|
+
return { ok: false, reason: `patch_failed:${patchRes.status}` };
|
|
4849
|
+
}
|
|
4850
|
+
return { ok: true };
|
|
4851
|
+
}
|
|
4852
|
+
|
|
4481
4853
|
// src/models-brain.ts
|
|
4482
4854
|
function isModelRow(x) {
|
|
4483
4855
|
if (!x || typeof x !== "object") return false;
|
|
@@ -4614,7 +4986,10 @@ function compile2(ir, opts) {
|
|
|
4614
4986
|
INTENT_ARCHETYPES,
|
|
4615
4987
|
MEASURED_GROUNDING_MIN_N,
|
|
4616
4988
|
PROVIDER_ENV_KEYS,
|
|
4989
|
+
RULE_SEQUENTIAL_TOOL_CLIFF,
|
|
4990
|
+
TRANSLATOR_FLOOR,
|
|
4617
4991
|
allProfiles,
|
|
4992
|
+
applySectionRewrites,
|
|
4618
4993
|
bucketContext,
|
|
4619
4994
|
bucketHistory,
|
|
4620
4995
|
bucketToolCount,
|
|
@@ -4625,6 +5000,7 @@ function compile2(ir, opts) {
|
|
|
4625
5000
|
configureBrain,
|
|
4626
5001
|
countTokens,
|
|
4627
5002
|
execute,
|
|
5003
|
+
getActionableAdvisories,
|
|
4628
5004
|
getAllStarterChains,
|
|
4629
5005
|
getAllStarterChainsWithGrounding,
|
|
4630
5006
|
getArchetypePerfScore,
|
|
@@ -4650,6 +5026,7 @@ function compile2(ir, opts) {
|
|
|
4650
5026
|
loadChainsFromBrain,
|
|
4651
5027
|
loadModelsFromBrain,
|
|
4652
5028
|
loadPricingFromBrain,
|
|
5029
|
+
markAdvisoryResolved,
|
|
4653
5030
|
profileToRow,
|
|
4654
5031
|
profilesByProvider,
|
|
4655
5032
|
record,
|