2sagaco48 1.0.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.
- package/diagnostics.mjs +141 -0
- package/dist/compute.worker-j5ahIpF-.js +1 -0
- package/dist/graph.worker-DG6iGCB9.js +1 -0
- package/dist/index.html +2314 -0
- package/flatten-guide.md +248 -0
- package/index.html +12 -0
- package/package.json +38 -0
- package/src/App.orig.tsx +204 -0
- package/src/App.orig1.tsx +27 -0
- package/src/App.orig2.tsx +25 -0
- package/src/App.tsx +3 -0
- package/src/BaseApp.tsx +18 -0
- package/src/INTEGRATION_LEDGER.md +22 -0
- package/src/PERSIST_CANARY.orig.txt +1 -0
- package/src/PERSIST_CANARY.txt +1 -0
- package/src/REGRESSION_LEDGER.md +651 -0
- package/src/TEMPLATE_PIPELINE_AUDIT.md +208 -0
- package/src/WILLIAMS_PERSONA_GUIDE.md +62 -0
- package/src/chat/VeritasChat.tsx +69 -0
- package/src/chat/synthesis.ts +31 -0
- package/src/chat/tier.ts +45 -0
- package/src/components/AdaptersPage.orig.tsx +99 -0
- package/src/components/AdaptersPage.tsx +3 -0
- package/src/components/AdversarialPanel.tsx +136 -0
- package/src/components/AnchorBaselinePanel.tsx +75 -0
- package/src/components/AnswerPanel.tsx +60 -0
- package/src/components/ArtifactPanel.tsx +43 -0
- package/src/components/ChatApp.orig.tsx +1582 -0
- package/src/components/ChatApp.orig1.tsx +722 -0
- package/src/components/ChatApp.tsx +95 -0
- package/src/components/ChatAugmentPanels.tsx +73 -0
- package/src/components/CitationLedgerPanel.tsx +313 -0
- package/src/components/ComputeSandboxPanel.tsx +130 -0
- package/src/components/ConfigPanel.tsx +110 -0
- package/src/components/ControlPlanePage.tsx +195 -0
- package/src/components/CreativeTreeLifePage.tsx +234 -0
- package/src/components/CreativeTreeOfLifePanel.tsx +149 -0
- package/src/components/DebugTracePanel.tsx +137 -0
- package/src/components/DeepReasoningTrace.tsx +48 -0
- package/src/components/EntitySheetPanel.tsx +51 -0
- package/src/components/FailureModesPanel.tsx +104 -0
- package/src/components/GBSDashboard.tsx +239 -0
- package/src/components/GraphView.tsx +116 -0
- package/src/components/HUD.tsx +125 -0
- package/src/components/HypothesisPanel.tsx +67 -0
- package/src/components/InnovationGenomeEngine.tsx +792 -0
- package/src/components/InnovationPersonaGuide.tsx +348 -0
- package/src/components/InnovationPersonaPanel.tsx +289 -0
- package/src/components/LiveResourceHUD.tsx +109 -0
- package/src/components/LongWriterPanel.tsx +112 -0
- package/src/components/MainPipelineV10Bridge.tsx +72 -0
- package/src/components/MarkdownLite.tsx +63 -0
- package/src/components/MemoryInspector.tsx +38 -0
- package/src/components/MemoryMonitor.tsx +52 -0
- package/src/components/MemoryStressPanel.tsx +176 -0
- package/src/components/ModulesPage.tsx +171 -0
- package/src/components/PipelineDebugConsole.orig.tsx +1856 -0
- package/src/components/PipelineDebugConsole.tsx +3 -0
- package/src/components/PreFlightHUD.tsx +67 -0
- package/src/components/PrismaFetchTracePanel.tsx +87 -0
- package/src/components/ReportOSPanel.tsx +165 -0
- package/src/components/ResourceEstimatorPage.tsx +327 -0
- package/src/components/RichText.tsx +181 -0
- package/src/components/SagaOsPanel.tsx +605 -0
- package/src/components/SagaOsReference.tsx +421 -0
- package/src/components/SagaOsV2Panel.tsx +594 -0
- package/src/components/SagaStyleTab.tsx +382 -0
- package/src/components/SageBlueprintPanel.tsx +416 -0
- package/src/components/SharedChatInput.tsx +77 -0
- package/src/components/StatFinancePanel.tsx +190 -0
- package/src/components/StylePersonaPanel.tsx +128 -0
- package/src/components/TemplatesPage.tsx +300 -0
- package/src/components/TestPanel.tsx +63 -0
- package/src/components/TraceLog.tsx +89 -0
- package/src/components/V15CalibrationAugment.tsx +1134 -0
- package/src/components/V15CalibrationDialog.tsx +1871 -0
- package/src/components/V15Overlay.orig.tsx +120 -0
- package/src/components/V15Overlay.tsx +4 -0
- package/src/components/V15OverlayWrapper.tsx +362 -0
- package/src/components/V15Toggle.tsx +34 -0
- package/src/console/DiagnosticRecoveryPanel.tsx +358 -0
- package/src/console/EngineeringConsole.tsx +103 -0
- package/src/console/FictionSystemPanels.tsx +882 -0
- package/src/console/InspectorPanels.tsx +254 -0
- package/src/console/ManuscriptGraderPanel.tsx +182 -0
- package/src/console/RecursiveReviserPanel.tsx +245 -0
- package/src/console/SeedControlPanel.tsx +135 -0
- package/src/console/StoryControllerPanel.tsx +443 -0
- package/src/console/engineBridge.ts +258 -0
- package/src/console/gemini.ts +106 -0
- package/src/console/grading.ts +250 -0
- package/src/console/util.ts +45 -0
- package/src/fiction/continuity.ts +372 -0
- package/src/fiction/crash-protection.ts +111 -0
- package/src/fiction/diagnostics.ts +208 -0
- package/src/fiction/diff.ts +74 -0
- package/src/fiction/entity-state-machine.ts +214 -0
- package/src/fiction/nive-engine.ts +404 -0
- package/src/fiction/pipeline-selftest.ts +132 -0
- package/src/fiction/seed-control.ts +193 -0
- package/src/fiction/story-engine.ts +326 -0
- package/src/fiction/types.ts +68 -0
- package/src/flatten-guide.md +379 -0
- package/src/index.css +14 -0
- package/src/index.orig.css +13 -0
- package/src/lib/academic-sources.base.ts +188 -0
- package/src/lib/academic-sources.orig.ts +28 -0
- package/src/lib/academic-sources.ts +10 -0
- package/src/lib/advanced-math.ts +119 -0
- package/src/lib/adversarial-engine.base.ts +409 -0
- package/src/lib/adversarial-engine.ts +82 -0
- package/src/lib/ai-revision.ts +623 -0
- package/src/lib/app-state.tsx +426 -0
- package/src/lib/artifact-registry.ts +97 -0
- package/src/lib/artifacts.ts +180 -0
- package/src/lib/atlas-dr.ts +167 -0
- package/src/lib/browser-mtls.ts +127 -0
- package/src/lib/browser-queue.ts +221 -0
- package/src/lib/browser-search-scraper.base.ts +382 -0
- package/src/lib/browser-search-scraper.orig.ts +90 -0
- package/src/lib/browser-search-scraper.ts +10 -0
- package/src/lib/calc-interceptor.ts +82 -0
- package/src/lib/citation-lane-tap.ts +78 -0
- package/src/lib/citation-ledger-store.ts +369 -0
- package/src/lib/citation-ledger.ts +203 -0
- package/src/lib/compute-sandbox.ts +215 -0
- package/src/lib/compute.worker.ts +153 -0
- package/src/lib/connectors/gemini.ts +120 -0
- package/src/lib/connectors/jina.ts +233 -0
- package/src/lib/connectors/marketdata.ts +51 -0
- package/src/lib/connectors/prismafetch.base.ts +175 -0
- package/src/lib/connectors/prismafetch.ts +1 -0
- package/src/lib/connectors/serpapi.ts +65 -0
- package/src/lib/connectors/wikidata.ts +44 -0
- package/src/lib/constraints.ts +331 -0
- package/src/lib/continuation-detector.base.ts +153 -0
- package/src/lib/continuation-detector.ts +48 -0
- package/src/lib/contradraft.ts +168 -0
- package/src/lib/cors-proxy.ts +120 -0
- package/src/lib/coverage.ts +81 -0
- package/src/lib/debug/architecture-prescription.ts +556 -0
- package/src/lib/debug/covea-repair.ts +543 -0
- package/src/lib/debug/helios-ground.ts +319 -0
- package/src/lib/debug/intent-decomposer.ts +281 -0
- package/src/lib/debug/intent-lattice.ts +349 -0
- package/src/lib/debug/pipeline-diagnosis.ts +1149 -0
- package/src/lib/debug/pipeline-trace-bus.ts +424 -0
- package/src/lib/debug/prompt-forge.ts +678 -0
- package/src/lib/debug/repair-sites.ts +513 -0
- package/src/lib/debug/research-phase.ts +266 -0
- package/src/lib/debug/retrieval-context.ts +76 -0
- package/src/lib/debug/retrieval-hardener.ts +142 -0
- package/src/lib/debug/scraper-debug-runner.ts +576 -0
- package/src/lib/debug/scraper-forensics.ts +418 -0
- package/src/lib/debug/scraper-lane-roadmap.ts +136 -0
- package/src/lib/debug/self-test.ts +415 -0
- package/src/lib/debug/step-attribution.ts +211 -0
- package/src/lib/debug/template-rubric.ts +301 -0
- package/src/lib/debug/unified-innovation.ts +126 -0
- package/src/lib/debug/veritas-hybrid-scraper.ts +335 -0
- package/src/lib/defense-registry.ts +104 -0
- package/src/lib/defenses.ts +162 -0
- package/src/lib/deterministic-citation-ledger.ts +174 -0
- package/src/lib/elo-registry.base.ts +117 -0
- package/src/lib/elo-registry.ts +1 -0
- package/src/lib/entity-resolver.ts +291 -0
- package/src/lib/failure-modes.ts +267 -0
- package/src/lib/feature-registry.ts +69 -0
- package/src/lib/flaw-registry.ts +143 -0
- package/src/lib/flaws/_template.ts +52 -0
- package/src/lib/flaws/builtins.ts +63 -0
- package/src/lib/flaws/finance.ts +169 -0
- package/src/lib/flaws/fixers.ts +10 -0
- package/src/lib/flaws/index.ts +32 -0
- package/src/lib/flaws/legal.ts +157 -0
- package/src/lib/flaws/medical.ts +188 -0
- package/src/lib/flaws/original-defenses-pack.ts +81 -0
- package/src/lib/flaws/sample-declarative-pack.json +38 -0
- package/src/lib/flaws/selftest.ts +201 -0
- package/src/lib/flaws/software-extended.ts +125 -0
- package/src/lib/flaws/software-rn-webgl.ts +182 -0
- package/src/lib/flaws/statistics-advanced.ts +46 -0
- package/src/lib/flaws/statistics.ts +61 -0
- package/src/lib/gbse/config.ts +20 -0
- package/src/lib/gbse/engine.ts +226 -0
- package/src/lib/gbse/graph.ts +118 -0
- package/src/lib/gbse/graph.worker.ts +21 -0
- package/src/lib/gbse/tests.ts +117 -0
- package/src/lib/gbse/tiers.ts +65 -0
- package/src/lib/gbse/types.ts +94 -0
- package/src/lib/innovation-genome-engine-v2.orig.ts +1001 -0
- package/src/lib/innovation-genome-engine-v2.ts +3 -0
- package/src/lib/innovation-genome-engine.orig.ts +330 -0
- package/src/lib/innovation-genome-engine.ts +3 -0
- package/src/lib/innovation-genome-v10.orig.ts +314 -0
- package/src/lib/innovation-genome-v10.ts +2 -0
- package/src/lib/innovation-genome-v3.orig.ts +2015 -0
- package/src/lib/innovation-genome-v3.ts +2 -0
- package/src/lib/innovation-genome-v4.orig.ts +1959 -0
- package/src/lib/innovation-genome-v4.ts +2 -0
- package/src/lib/innovation-genome-v5.orig.ts +1210 -0
- package/src/lib/innovation-genome-v5.ts +2 -0
- package/src/lib/innovation-genome-v7.orig.ts +2549 -0
- package/src/lib/innovation-genome-v7.ts +2 -0
- package/src/lib/innovation-genome-v8.orig.ts +1485 -0
- package/src/lib/innovation-genome-v8.ts +2 -0
- package/src/lib/innovation-genome-v9.orig.ts +643 -0
- package/src/lib/innovation-genome-v9.ts +2 -0
- package/src/lib/jina.base.ts +293 -0
- package/src/lib/jina.ts +1 -0
- package/src/lib/live-telemetry.ts +61 -0
- package/src/lib/longwriter.ts +84 -0
- package/src/lib/manuscript-grade-v2.ts +298 -0
- package/src/lib/memory-governor.ts +173 -0
- package/src/lib/memory-stress-tests.ts +248 -0
- package/src/lib/model-intelligence.ts +48 -0
- package/src/lib/model-rotator.ts +75 -0
- package/src/lib/models.orig.ts +513 -0
- package/src/lib/models.ts +151 -0
- package/src/lib/n-deep.base.ts +592 -0
- package/src/lib/n-deep.ts +51 -0
- package/src/lib/nih-simulator.ts +56 -0
- package/src/lib/nih-vulnerability-fixes.ts +460 -0
- package/src/lib/omega-templates.base.ts +294 -0
- package/src/lib/omega-templates.ts +225 -0
- package/src/lib/omni-nexus.ts +64 -0
- package/src/lib/oracle-adapters.ts +67 -0
- package/src/lib/oracle-registry.ts +163 -0
- package/src/lib/orchestrator.ts +357 -0
- package/src/lib/output-boundary.ts +235 -0
- package/src/lib/overrides/vite-native-chaos-harness.ts +154 -0
- package/src/lib/overrides/vite-native-contract-plane.ts +245 -0
- package/src/lib/overrides/vite-native-doctor-plane.ts +208 -0
- package/src/lib/overrides/vite-native-knowledge-store.ts +267 -0
- package/src/lib/overrides/vite-native-policy-plane.ts +190 -0
- package/src/lib/overrides/vite-native-replay-plane.ts +197 -0
- package/src/lib/overrides/vite-native-runtime-plane.ts +106 -0
- package/src/lib/overrides/vite-native-scraper.ts +848 -0
- package/src/lib/overrides/vite-native-selftest-functional.ts +217 -0
- package/src/lib/overrides/vite-native-selftest.ts +183 -0
- package/src/lib/overrides/vite-native-snapshot-plane.ts +123 -0
- package/src/lib/philosophy-toolkit.ts +75 -0
- package/src/lib/pipeline.orig.ts +659 -0
- package/src/lib/pipeline.ts +42 -0
- package/src/lib/precache.ts +128 -0
- package/src/lib/py-sandbox.ts +205 -0
- package/src/lib/quality-score.ts +96 -0
- package/src/lib/quant-engine.ts +231 -0
- package/src/lib/quant-lib.ts +80 -0
- package/src/lib/reportos.ts +175 -0
- package/src/lib/research-os.ts +306 -0
- package/src/lib/resource-estimator.ts +114 -0
- package/src/lib/rpm-governor.ts +93 -0
- package/src/lib/runtime-estimator.ts +135 -0
- package/src/lib/sage/empty-space-v6.ts +560 -0
- package/src/lib/sage/empty-space-v7.ts +222 -0
- package/src/lib/sage/empty-space.ts +733 -0
- package/src/lib/sage/engine.ts +786 -0
- package/src/lib/sage/index.ts +17 -0
- package/src/lib/sage/judge.ts +246 -0
- package/src/lib/sage/prng.ts +53 -0
- package/src/lib/sage/reality-grounding.ts +380 -0
- package/src/lib/sage/repetition.ts +151 -0
- package/src/lib/sage/saga-os-v2-engines.ts +1870 -0
- package/src/lib/sage/saga-os-v2.ts +274 -0
- package/src/lib/sage/saga-os-v3-core.ts +1491 -0
- package/src/lib/sage/saga-os-v3-release.ts +739 -0
- package/src/lib/sage/saga-os-v4-aureate.ts +1161 -0
- package/src/lib/sage/saga-os-v4.ts +212 -0
- package/src/lib/sage/saga-os-v5.ts +205 -0
- package/src/lib/sage/saga-os-v6.ts +346 -0
- package/src/lib/sage/saga-os-v7.ts +314 -0
- package/src/lib/sage/saga-os-v8.ts +505 -0
- package/src/lib/sage/saga-os.ts +329 -0
- package/src/lib/sage/taxonomy.ts +403 -0
- package/src/lib/sage/unified-roll.ts +524 -0
- package/src/lib/sage/worked-sketches.ts +44 -0
- package/src/lib/sage.ts +166 -0
- package/src/lib/scraper-debug-bus.ts +53 -0
- package/src/lib/scraper-enhanced.orig.ts +153 -0
- package/src/lib/scraper-enhanced.ts +10 -0
- package/src/lib/scraper-hardener.base.orig.ts +155 -0
- package/src/lib/scraper-hardener.base.ts +317 -0
- package/src/lib/scraper-hardener.ts +1 -0
- package/src/lib/scraper-palisade/palisade-adjudicator.orig.ts +419 -0
- package/src/lib/scraper-palisade/palisade-adjudicator.ts +13 -0
- package/src/lib/scraper-vnext/arbiter-omega.orig.ts +688 -0
- package/src/lib/scraper-vnext/arbiter-omega.ts +13 -0
- package/src/lib/scraper-vnext/canonical-portfolio-augments.ts +479 -0
- package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.orig.ts +1529 -0
- package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.ts +13 -0
- package/src/lib/scraper-vnext/conclave-omega.ts +1830 -0
- package/src/lib/scraper-vnext/content-extractor-v2.ts +226 -0
- package/src/lib/scraper-vnext/diagnostics-suite.ts +36 -0
- package/src/lib/scraper-vnext/epistemic-packer.ts +97 -0
- package/src/lib/scraper-vnext/fusion-v2.ts +65 -0
- package/src/lib/scraper-vnext/hydra-reader.orig.ts +1216 -0
- package/src/lib/scraper-vnext/hydra-reader.ts +13 -0
- package/src/lib/scraper-vnext/native-scraper-browser-vnext.orig.ts +91 -0
- package/src/lib/scraper-vnext/native-scraper-browser-vnext.ts +13 -0
- package/src/lib/scraper-vnext/nexus-consensus.orig.ts +905 -0
- package/src/lib/scraper-vnext/nexus-consensus.ts +13 -0
- package/src/lib/scraper-vnext/portfolio-consensus-adjudicator.ts +804 -0
- package/src/lib/scraper-vnext/portfolio-consensus-memory.ts +377 -0
- package/src/lib/scraper-vnext/portfolio-terminal-governor.ts +548 -0
- package/src/lib/scraper-vnext/query-strategist.orig.ts +224 -0
- package/src/lib/scraper-vnext/query-strategist.ts +423 -0
- package/src/lib/scraper-vnext/retrieval-accelerator.ts +708 -0
- package/src/lib/scraper-vnext/retrieval-audit-augments.ts +477 -0
- package/src/lib/scraper-vnext/retrieval-control-plane.ts +904 -0
- package/src/lib/scraper-vnext/retrieval-policy-augments.ts +358 -0
- package/src/lib/scraper-vnext/safe-fetch-v2.ts +157 -0
- package/src/lib/scraper-vnext/sentinel-omega.ts +56 -0
- package/src/lib/scraper-vnext/sentinel-orchestrator.ts +69 -0
- package/src/lib/scraper-vnext/sibyl-oracle.orig.ts +413 -0
- package/src/lib/scraper-vnext/sibyl-oracle.ts +13 -0
- package/src/lib/scraper-vnext/smart-read-v2.ts +55 -0
- package/src/lib/scraper-vnext/spa-rescue-bridge.ts +608 -0
- package/src/lib/scraper-vnext/strata-engine.orig.ts +2666 -0
- package/src/lib/scraper-vnext/strata-engine.ts +13 -0
- package/src/lib/scraper-vnext/structured-source-adapter.orig.ts +369 -0
- package/src/lib/scraper-vnext/structured-source-adapter.ts +34 -0
- package/src/lib/scraper-vnext/terminal-complete.ts +224 -0
- package/src/lib/scraper-vnext/terminal-final.ts +277 -0
- package/src/lib/scraper-vnext/terminal-saturation.ts +345 -0
- package/src/lib/scraper-vnext/terminal-wire.ts +425 -0
- package/src/lib/scraper-vnext/vanguard-titanium.orig.ts +467 -0
- package/src/lib/scraper-vnext/vanguard-titanium.ts +17 -0
- package/src/lib/search-cache.ts +138 -0
- package/src/lib/sloop-runner.base.ts +223 -0
- package/src/lib/sloop-runner.ts +104 -0
- package/src/lib/sloop.ts +114 -0
- package/src/lib/small-model-adapters.ts +82 -0
- package/src/lib/sscp.ts +86 -0
- package/src/lib/system-map.ts +54 -0
- package/src/lib/uni-node.ts +86 -0
- package/src/lib/universal-rigor-guard.ts +433 -0
- package/src/lib/v15-gate-testbed.ts +274 -0
- package/src/lib/v15-gemini.base.ts +89 -0
- package/src/lib/v15-gemini.ts +1 -0
- package/src/lib/v15-grounding.orig.ts +241 -0
- package/src/lib/v15-grounding.ts +79 -0
- package/src/lib/v15-pipeline.base.ts +769 -0
- package/src/lib/v15-pipeline.orig.ts +1154 -0
- package/src/lib/v15-pipeline.ts +674 -0
- package/src/lib/v15-questions.ts +64 -0
- package/src/lib/v15-rate-limiter.orig.ts +91 -0
- package/src/lib/v15-rate-limiter.ts +48 -0
- package/src/lib/v15-state.base.ts +87 -0
- package/src/lib/v15-state.ts +28 -0
- package/src/lib/visual-table-generator.tsx +207 -0
- package/src/lib/wasm-runtime.ts +133 -0
- package/src/lib/williams-persona-guide.ts +265 -0
- package/src/lib/williams-style.base.ts +464 -0
- package/src/lib/williams-style.ts +59 -0
- package/src/lib/worker-pool.ts +96 -0
- package/src/lib/writing-tiers.ts +125 -0
- package/src/main.orig.tsx +10 -0
- package/src/main.tsx +10 -0
- package/src/utils/cn.orig.ts +6 -0
- package/src/utils/cn.ts +6 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +31 -0
- package/unify.mjs +537 -0
- package/vite.config.ts +18 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* intent-lattice.ts — Intent Facet Lattice (IFL) query synthesis.
|
|
3
|
+
*
|
|
4
|
+
* PROBLEM (from the supplied scraper-forensics export):
|
|
5
|
+
* The dispatched queries were literally the raw, truncated user prompt —
|
|
6
|
+
* e.g. `"a product that doesn't exist but solves a large un"` — the SAME
|
|
7
|
+
* generic string reused across BLUF, Situation, and Diagnostic sections.
|
|
8
|
+
* Result: a cannabis + heart-rate + strategy prompt retrieved "Moldovan
|
|
9
|
+
* youth", "printed-circuit-board failures", and "CHAGEE tea market share".
|
|
10
|
+
* Two root causes, both durable to fix in the workspace without materialize:
|
|
11
|
+
* (a) TRUNCATION — `buildTemplateSearchQueries` slices the topic and the
|
|
12
|
+
* log shows an even shorter live query; and
|
|
13
|
+
* (b) NO INTENT DECOMPOSITION — one flat query cannot serve seven
|
|
14
|
+
* structurally different sections.
|
|
15
|
+
*
|
|
16
|
+
* WHY NOT the obvious things (negative space — why each fails the contract):
|
|
17
|
+
* 1. Raw prompt as query → returns topical noise (the observed failure).
|
|
18
|
+
* 2. Truncated prompt → drops the operative nouns; strictly worse.
|
|
19
|
+
* 3. Single LLM decomposition call → the log shows 429/503; a model-only
|
|
20
|
+
* path has no floor and produced `gap analysis unavailable`.
|
|
21
|
+
* 4. Self-Ask / sequential sub-questions → serial, latency-heavy, and each
|
|
22
|
+
* sub-question is still a sentence, not a search string.
|
|
23
|
+
* 5. HyDE hypothetical-doc expansion → fabricates content the retriever
|
|
24
|
+
* then "confirms"; a citation-fabrication vector we must avoid.
|
|
25
|
+
* 6. Keyword bag (all non-stopword tokens joined) → the package's existing
|
|
26
|
+
* `keywordize`; loses section specificity, still one query for all.
|
|
27
|
+
* 7. Query per template section using the section TITLE as the query →
|
|
28
|
+
* returns definitions of "BLUF"/"T-Bar", not the topic. (Detectably
|
|
29
|
+
* wrong: facetCoherence≈0 against the domain facet.)
|
|
30
|
+
*
|
|
31
|
+
* THE METHOD — Intent Facet Lattice (original to this codebase; not Self-Ask,
|
|
32
|
+
* not HyDE, not Plan×RAG, not sub-question decomposition):
|
|
33
|
+
* 1. Deterministically extract FACETS along five orthogonal axes:
|
|
34
|
+
* domain · object · constraint · metric · temporal · entity
|
|
35
|
+
* Each facet is a short high-signal phrase, NOT a sentence, NEVER
|
|
36
|
+
* truncated below a whole token boundary.
|
|
37
|
+
* 2. Each template section declares a FACET AFFINITY VECTOR — which axes
|
|
38
|
+
* matter for that section (e.g. Diagnostic → domain×metric×temporal;
|
|
39
|
+
* Options → domain×object×constraint).
|
|
40
|
+
* 3. For each section, take the CROSS-PRODUCT of its affine facets and emit
|
|
41
|
+
* the top-k coherent combinations as queries. A query therefore reads
|
|
42
|
+
* like `cannabis vaporizer market size 2024` — several operative facets
|
|
43
|
+
* joined — instead of a truncated prompt slice.
|
|
44
|
+
* 4. Every query carries its facet provenance, enabling downstream
|
|
45
|
+
* `facetCoherence(result, query)`: a retrieved doc that shares none of
|
|
46
|
+
* the query's facet tokens is drift (the "CHAGEE tea" case) and is
|
|
47
|
+
* down-weighted.
|
|
48
|
+
*
|
|
49
|
+
* Determinism: same prompt ⇒ same lattice, always. No network, no model. An
|
|
50
|
+
* optional LLM enrichment layer may ADD facets but can never remove the
|
|
51
|
+
* deterministic floor — if it 429/503s, the lattice still stands.
|
|
52
|
+
*/
|
|
53
|
+
export type FacetAxis = "domain" | "object" | "constraint" | "metric" | "temporal" | "entity";
|
|
54
|
+
|
|
55
|
+
export interface Facet {
|
|
56
|
+
axis: FacetAxis;
|
|
57
|
+
phrase: string;
|
|
58
|
+
/** Deterministic salience 0..1 (token rarity × axis weight). */
|
|
59
|
+
weight: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface LatticeQuery {
|
|
63
|
+
q: string;
|
|
64
|
+
section: string;
|
|
65
|
+
facets: Facet[];
|
|
66
|
+
axes: FacetAxis[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface IntentLattice {
|
|
70
|
+
original: string;
|
|
71
|
+
facets: Facet[];
|
|
72
|
+
byAxis: Record<FacetAxis, Facet[]>;
|
|
73
|
+
queries: LatticeQuery[];
|
|
74
|
+
llmEnriched: boolean;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ─── Lexicons (deterministic facet extraction) ─────────────────────────────
|
|
78
|
+
const DOMAIN_LEX: Record<string, string[]> = {
|
|
79
|
+
cannabis: ["cannabis", "marijuana", "cbd", "thc", "hemp", "weed", "dispensary", "vaporizer", "vape", "edible", "cannabinoid", "terpene"],
|
|
80
|
+
medical: ["medical", "health", "clinical", "patient", "therapy", "disease", "nerve", "heart rate", "blood pressure", "dose", "dosage", "tachycardia"],
|
|
81
|
+
technology: ["technology", "sensor", "device", "hardware", "software", "iot", "wearable", "biofeedback", "micro-needle", "transdermal", "ppg", "photoplethysmography"],
|
|
82
|
+
finance: ["market", "revenue", "npv", "irr", "tam", "sam", "som", "valuation", "margin", "cagr", "investment", "pricing"],
|
|
83
|
+
legal: ["regulation", "compliance", "fda", "schedule i", "legal", "statute", "approval", "510(k)"],
|
|
84
|
+
manufacturing: ["manufacturing", "production", "assembly", "supply chain", "tooling", "extraction", "co2 extraction"],
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const CONSTRAINT_PATTERNS: Array<{ re: RegExp; phrase: string }> = [
|
|
88
|
+
{ re: /\b(existing|current|available)\s+(technolog|tech|infrastructure)/i, phrase: "existing technology feasibility" },
|
|
89
|
+
{ re: /\b(unmet|underserved)\s+(demand|need|market)/i, phrase: "unmet demand market gap" },
|
|
90
|
+
{ re: /\b(doesn'?t exist|not exist|novel|new|first-of-its-kind)\b/i, phrase: "novel product whitespace" },
|
|
91
|
+
{ re: /\b(large|big|major|significant|multi-?billion)\b/i, phrase: "large addressable market" },
|
|
92
|
+
{ re: /\b(safe|safety|risk|adverse|side effect)\b/i, phrase: "safety risk profile" },
|
|
93
|
+
{ re: /\b(scal(e|able)|mass production)\b/i, phrase: "scalability" },
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
const METRIC_PATTERNS: Array<{ re: RegExp; phrase: string }> = [
|
|
97
|
+
{ re: /\b(market size|tam|sam|som|addressable market)\b/i, phrase: "market size TAM SAM SOM" },
|
|
98
|
+
{ re: /\b(growth|cagr|projection|forecast)\b/i, phrase: "growth rate forecast" },
|
|
99
|
+
{ re: /\b(npv|irr|roi|payback|valuation)\b/i, phrase: "NPV IRR valuation" },
|
|
100
|
+
{ re: /\b(share|competitive|competitor)\b/i, phrase: "competitive market share" },
|
|
101
|
+
{ re: /\b(heart rate|blood pressure|hr|bp|physiolog)\b/i, phrase: "physiological measurement" },
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
const TEMPORAL_PATTERNS: Array<{ re: RegExp; phrase: string }> = [
|
|
105
|
+
{ re: /\b(20\d\d)\b/, phrase: "$1" },
|
|
106
|
+
{ re: /\b(latest|recent|current|today|now|emerging)\b/i, phrase: "2024 2025 latest" },
|
|
107
|
+
{ re: /\b(trend|projection|forecast|future)\b/i, phrase: "trends forecast" },
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
const STOP = new Set([
|
|
111
|
+
"the", "a", "an", "of", "to", "in", "on", "for", "and", "or", "is", "are", "be", "can",
|
|
112
|
+
"that", "this", "with", "using", "made", "solve", "solves", "find", "me", "large", "but",
|
|
113
|
+
"please", "help", "product", "doesn't", "exist", "demand", "unmet", "space", "existing",
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
const NOISE_LEX = ["moldovan", "youth", "printed circuit board", "chagee", "tea", "ellipsis", "civil engineering", "automotive seals", "nanopore", "genome assembly"];
|
|
117
|
+
|
|
118
|
+
function tokenize(s: string): string[] {
|
|
119
|
+
return s.toLowerCase().replace(/[^\p{L}\p{N}\s-]/gu, " ").split(/\s+/).filter(t => t.length > 2 && !STOP.has(t));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Deterministically extract the full facet set — NO truncation of the input. */
|
|
123
|
+
export function extractFacets(question: string): Facet[] {
|
|
124
|
+
const facets: Facet[] = [];
|
|
125
|
+
const seen = new Set<string>();
|
|
126
|
+
const push = (axis: FacetAxis, phrase: string, weight: number) => {
|
|
127
|
+
const key = `${axis}:${phrase.toLowerCase()}`;
|
|
128
|
+
if (!phrase.trim() || seen.has(key)) return;
|
|
129
|
+
seen.add(key);
|
|
130
|
+
facets.push({ axis, phrase: phrase.trim(), weight: Math.max(0, Math.min(1, weight)) });
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// domain
|
|
134
|
+
for (const [domain, lex] of Object.entries(DOMAIN_LEX)) {
|
|
135
|
+
const hits = lex.filter(k => question.toLowerCase().includes(k));
|
|
136
|
+
if (hits.length) {
|
|
137
|
+
push("domain", domain, 0.9);
|
|
138
|
+
for (const h of hits.slice(0, 3)) push("object", h, 0.75); // concrete objects mentioned
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// entity (proper nouns / acronyms) — full token, never sliced
|
|
143
|
+
for (const e of question.match(/\b([A-Z][a-zA-Z0-9-]+(?:\s+[A-Z][a-zA-Z0-9-]+){0,2}|[A-Z]{2,})\b/g) ?? []) {
|
|
144
|
+
if (e.length >= 2 && !/^(Find|Please|Help)$/i.test(e)) push("entity", e, 0.6);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
for (const { re, phrase } of CONSTRAINT_PATTERNS) if (re.test(question)) push("constraint", phrase, 0.7);
|
|
148
|
+
for (const { re, phrase } of METRIC_PATTERNS) if (re.test(question)) push("metric", phrase, 0.8);
|
|
149
|
+
for (const { re, phrase } of TEMPORAL_PATTERNS) {
|
|
150
|
+
const m = re.exec(question);
|
|
151
|
+
if (m) push("temporal", phrase.replace("$1", m[1] ?? ""), 0.55);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Residual high-signal nouns as objects (token rarity weight), never truncated.
|
|
155
|
+
const toks = tokenize(question);
|
|
156
|
+
const freq = new Map<string, number>();
|
|
157
|
+
for (const t of toks) freq.set(t, (freq.get(t) ?? 0) + 1);
|
|
158
|
+
const rare = [...freq.entries()].sort((a, b) => a[1] - b[1]).map(([t]) => t);
|
|
159
|
+
for (const t of rare.slice(0, 6)) push("object", t, 0.5);
|
|
160
|
+
|
|
161
|
+
return facets;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ─── Section facet-affinity vectors ────────────────────────────────────────
|
|
165
|
+
// Which axes each OMEGA-STRATEGY section actually needs to search for.
|
|
166
|
+
const SECTION_AFFINITY: Record<string, FacetAxis[]> = {
|
|
167
|
+
"BLUF": ["domain", "object", "metric"],
|
|
168
|
+
"Situation (SCQA)": ["domain", "object", "constraint"],
|
|
169
|
+
"Diagnostic (T-Bar)": ["domain", "metric", "temporal"],
|
|
170
|
+
"Options Tournament": ["domain", "object", "constraint"],
|
|
171
|
+
"Recommendation & Value Bridge": ["domain", "metric", "object"],
|
|
172
|
+
"Implementation (Wave Architecture)": ["domain", "object", "constraint"],
|
|
173
|
+
"Risk Register & Assumption Ledger": ["domain", "constraint", "metric"],
|
|
174
|
+
"Appendix (T-Body)": ["domain", "metric", "temporal"],
|
|
175
|
+
// Generic fallback for non-OMEGA-STRATEGY templates / HDIG / adv-repair.
|
|
176
|
+
"general": ["domain", "object", "metric"],
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/** Search-role facets guarantee each query contains more than the domain. */
|
|
180
|
+
const SECTION_ROLE_FACETS: Record<string, Facet[]> = {
|
|
181
|
+
"BLUF": [{ axis: "metric", phrase: "market opportunity product innovation", weight: 0.8 }],
|
|
182
|
+
"Situation (SCQA)": [{ axis: "constraint", phrase: "current unmet need user pain", weight: 0.8 }],
|
|
183
|
+
"Diagnostic (T-Bar)": [
|
|
184
|
+
{ axis: "metric", phrase: "market size TAM SAM SOM", weight: 0.9 },
|
|
185
|
+
{ axis: "temporal", phrase: "2024 2025", weight: 0.6 },
|
|
186
|
+
],
|
|
187
|
+
"Options Tournament": [{ axis: "constraint", phrase: "alternatives comparison tradeoffs", weight: 0.8 }],
|
|
188
|
+
"Recommendation & Value Bridge": [{ axis: "metric", phrase: "business model revenue NPV IRR", weight: 0.8 }],
|
|
189
|
+
"Implementation (Wave Architecture)": [{ axis: "constraint", phrase: "implementation milestones regulatory pathway", weight: 0.8 }],
|
|
190
|
+
"Risk Register & Assumption Ledger": [{ axis: "constraint", phrase: "safety regulatory technical risks", weight: 0.8 }],
|
|
191
|
+
"Appendix (T-Body)": [{ axis: "metric", phrase: "research evidence methodology data", weight: 0.8 }],
|
|
192
|
+
"general": [{ axis: "constraint", phrase: "research evidence application", weight: 0.65 }],
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
function facetsByAxis(facets: Facet[]): Record<FacetAxis, Facet[]> {
|
|
196
|
+
const out = { domain: [], object: [], constraint: [], metric: [], temporal: [], entity: [] } as Record<FacetAxis, Facet[]>;
|
|
197
|
+
for (const f of facets) out[f.axis].push(f);
|
|
198
|
+
for (const axis of Object.keys(out) as FacetAxis[]) out[axis].sort((a, b) => b.weight - a.weight);
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Cross-product synthesis: for a section, take its affine axes and join one
|
|
204
|
+
* high-salience facet from each into a compact, high-signal query. Emits up to
|
|
205
|
+
* `perSection` distinct queries by rotating the object/metric facets.
|
|
206
|
+
*/
|
|
207
|
+
function buildFromFacets(question: string, facets: Facet[], sections: string[], perSection: number): IntentLattice {
|
|
208
|
+
const byAxis = facetsByAxis(facets);
|
|
209
|
+
const domain = byAxis.domain[0]?.phrase ?? byAxis.object[0]?.phrase ?? "";
|
|
210
|
+
const queries: LatticeQuery[] = [];
|
|
211
|
+
|
|
212
|
+
for (const section of sections) {
|
|
213
|
+
const axes = SECTION_AFFINITY[section] ?? SECTION_AFFINITY.general;
|
|
214
|
+
// Rotate the most-variable axis (object, else metric) to make each query distinct.
|
|
215
|
+
const rotAxis: FacetAxis = byAxis.object.length >= byAxis.metric.length ? "object" : "metric";
|
|
216
|
+
const rawRotPool = byAxis[rotAxis].length ? byAxis[rotAxis] : byAxis.object.length ? byAxis.object : byAxis.domain;
|
|
217
|
+
// Do not rotate an object identical to the domain — that produced the
|
|
218
|
+
// one-token query `cannabis` in prior runs.
|
|
219
|
+
const rotPool = rawRotPool.filter((f) => f.phrase.toLowerCase() !== domain.toLowerCase());
|
|
220
|
+
const roles = SECTION_ROLE_FACETS[section] ?? SECTION_ROLE_FACETS.general;
|
|
221
|
+
|
|
222
|
+
for (let i = 0; i < Math.max(1, perSection); i++) {
|
|
223
|
+
const parts: Facet[] = [];
|
|
224
|
+
for (const axis of axes) {
|
|
225
|
+
const pool = axis === rotAxis ? rotPool : byAxis[axis];
|
|
226
|
+
const pick = pool.length ? pool[(axis === rotAxis ? i : 0) % pool.length] : undefined;
|
|
227
|
+
if (pick && !parts.some(p => p.phrase === pick.phrase)) parts.push(pick);
|
|
228
|
+
}
|
|
229
|
+
// Always anchor on the domain so a section can never drift off-topic.
|
|
230
|
+
if (domain && !parts.some(p => p.phrase === domain)) parts.unshift({ axis: "domain", phrase: domain, weight: 0.9 });
|
|
231
|
+
// Fill absent axes from the section role. This prevents domain-only
|
|
232
|
+
// queries while preserving all extracted prompt facets.
|
|
233
|
+
for (const role of roles) {
|
|
234
|
+
if (!parts.some((p) => p.axis === role.axis)) parts.push(role);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const q = parts.map(p => p.phrase).join(" ").replace(/\s+/g, " ").trim();
|
|
238
|
+
if (q && q.length >= 6 && !queries.some(x => x.section === section && x.q === q)) {
|
|
239
|
+
queries.push({ q, section, facets: parts, axes });
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return { original: question, facets, byAxis, queries, llmEnriched: false };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function buildLatticeQueries(question: string, sections: string[], perSection = 2): IntentLattice {
|
|
248
|
+
return buildFromFacets(question, extractFacets(question), sections, perSection);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Facet coherence of a retrieved result against a query: fraction of the
|
|
253
|
+
* query's facet tokens that appear in the result's title+snippet. Used to
|
|
254
|
+
* down-rank cross-facet drift (the "CHAGEE tea" result for a cannabis query).
|
|
255
|
+
* Pure, exported for self-test.
|
|
256
|
+
*/
|
|
257
|
+
export function facetCoherence(query: LatticeQuery, resultText: string): number {
|
|
258
|
+
const hay = resultText.toLowerCase();
|
|
259
|
+
const toks = Array.from(new Set(query.facets.flatMap(f => tokenize(f.phrase))));
|
|
260
|
+
if (toks.length === 0) return 1;
|
|
261
|
+
const hits = toks.filter(t => hay.includes(t)).length;
|
|
262
|
+
return Math.round((hits / toks.length) * 100) / 100;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** Detect the obviously-off-topic noise results the logs were full of. Pure. */
|
|
266
|
+
export function isLikelyDriftResult(resultText: string, query: LatticeQuery): boolean {
|
|
267
|
+
const hay = resultText.toLowerCase();
|
|
268
|
+
if (NOISE_LEX.some(n => hay.includes(n))) return facetCoherence(query, resultText) < 0.34;
|
|
269
|
+
return facetCoherence(query, resultText) < 0.2;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Render the lattice as an untruncated, model-readable directive block. This
|
|
274
|
+
* is what gets appended to the question envelope so the package's
|
|
275
|
+
* relative-path grounding receives decomposed, per-section intents instead of
|
|
276
|
+
* a single raw prompt. NOTHING here is truncated.
|
|
277
|
+
*/
|
|
278
|
+
export function renderLatticeDirective(lattice: IntentLattice): string {
|
|
279
|
+
const lines: string[] = [
|
|
280
|
+
"## RETRIEVAL INTENT LATTICE (deterministic facet decomposition — search these, not the raw prompt)",
|
|
281
|
+
`Facets: ${lattice.facets.map(f => `${f.axis}:${f.phrase}`).join(" · ")}`,
|
|
282
|
+
"Per-section high-signal queries (each is a keyword query, already decomposed and NOT truncated):",
|
|
283
|
+
];
|
|
284
|
+
const bySection = new Map<string, string[]>();
|
|
285
|
+
for (const q of lattice.queries) {
|
|
286
|
+
const arr = bySection.get(q.section) ?? [];
|
|
287
|
+
arr.push(q.q);
|
|
288
|
+
bySection.set(q.section, arr);
|
|
289
|
+
}
|
|
290
|
+
for (const [section, qs] of bySection) {
|
|
291
|
+
lines.push(`- ${section}: ${qs.map(q => `"${q}"`).join(" | ")}`);
|
|
292
|
+
}
|
|
293
|
+
lines.push("When grounding a section, dispatch that section's queries verbatim; do not fall back to the raw user prompt as a search string.");
|
|
294
|
+
return lines.join("\n");
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Optional LLM enrichment — ADDS facets only, never removes the deterministic
|
|
299
|
+
* floor. Fails safe: on any error/429/503 the input lattice is returned
|
|
300
|
+
* unchanged. Caller supplies the generate function to avoid a hard dependency.
|
|
301
|
+
*/
|
|
302
|
+
export async function enrichLatticeWithLlm(
|
|
303
|
+
lattice: IntentLattice,
|
|
304
|
+
generate: (prompt: string) => Promise<{ ok: boolean; text: string; error?: string }>,
|
|
305
|
+
): Promise<{ lattice: IntentLattice; ok: boolean; error?: string }> {
|
|
306
|
+
const prompt = [
|
|
307
|
+
"Extract additional high-signal SEARCH FACETS for web retrieval from the user prompt below.",
|
|
308
|
+
"Return ONLY a JSON array of {axis, phrase} where axis ∈ [domain,object,constraint,metric,temporal,entity].",
|
|
309
|
+
"Each phrase must be a short keyword phrase (2-6 words), NOT a sentence, NOT the raw prompt.",
|
|
310
|
+
"Do NOT invent facts, products, numbers, or URLs — only reformulate what is present.",
|
|
311
|
+
"",
|
|
312
|
+
`USER PROMPT (full, untruncated):\n${lattice.original}`,
|
|
313
|
+
"",
|
|
314
|
+
`Facets already found deterministically (do not repeat): ${lattice.facets.map(f => `${f.axis}:${f.phrase}`).join(", ")}`,
|
|
315
|
+
].join("\n");
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
const res = await generate(prompt);
|
|
319
|
+
if (!res.ok) return { lattice, ok: false, error: res.error };
|
|
320
|
+
const m = res.text.replace(/```json/gi, "").replace(/```/g, "").match(/\[[\s\S]*\]/);
|
|
321
|
+
const arr = JSON.parse(m ? m[0] : res.text) as Array<{ axis?: string; phrase?: string }>;
|
|
322
|
+
if (!Array.isArray(arr)) return { lattice, ok: false, error: "non-array" };
|
|
323
|
+
|
|
324
|
+
const validAxes = new Set<FacetAxis>(["domain", "object", "constraint", "metric", "temporal", "entity"]);
|
|
325
|
+
const added: Facet[] = [];
|
|
326
|
+
for (const a of arr.slice(0, 12)) {
|
|
327
|
+
const axis = String(a.axis ?? "").toLowerCase() as FacetAxis;
|
|
328
|
+
const phrase = String(a.phrase ?? "").trim();
|
|
329
|
+
if (validAxes.has(axis) && phrase && phrase.length >= 2 && phrase.length <= 60) {
|
|
330
|
+
added.push({ axis, phrase, weight: 0.65 });
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (added.length === 0) return { lattice, ok: true };
|
|
334
|
+
|
|
335
|
+
const merged = [...lattice.facets];
|
|
336
|
+
const seen = new Set(lattice.facets.map(f => `${f.axis}:${f.phrase.toLowerCase()}`));
|
|
337
|
+
for (const f of added) {
|
|
338
|
+
const k = `${f.axis}:${f.phrase.toLowerCase()}`;
|
|
339
|
+
if (!seen.has(k)) { seen.add(k); merged.push(f); }
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Rebuild queries with the enriched facet set, keeping the same sections.
|
|
343
|
+
const sections = Array.from(new Set(lattice.queries.map(q => q.section)));
|
|
344
|
+
const rebuilt = buildFromFacets(lattice.original, merged, sections.length ? sections : ["general"], 2);
|
|
345
|
+
return { lattice: { ...rebuilt, llmEnriched: true }, ok: true };
|
|
346
|
+
} catch (e) {
|
|
347
|
+
return { lattice, ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
348
|
+
}
|
|
349
|
+
}
|