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,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type B — ChatApp wrapper.
|
|
3
|
+
* ---------------------------------------------------------------------------
|
|
4
|
+
* Renders the packaged ChatApp unchanged and mounts the granular
|
|
5
|
+
* SageBlueprintPanel inside the fiction-engine controls.
|
|
6
|
+
*
|
|
7
|
+
* PROMPT INJECTION LIVES ELSEWHERE — see `src/lib/sage.ts`.
|
|
8
|
+
* A previous turn shipped a capture-phase `submit` listener here that appended
|
|
9
|
+
* the v2 directive to the textarea and gated on `getV15Enabled()`. It was
|
|
10
|
+
* removed because it did not work:
|
|
11
|
+
* 1. `getV15Enabled()` is the V15 calibration toggle, NOT Fiction mode
|
|
12
|
+
* (Fiction mode is localStorage "veritas.sage.pipeline.mode.v2").
|
|
13
|
+
* 2. The fiction runner never re-reads the textarea — it compiles from the
|
|
14
|
+
* frozen `blueprint` memo — so mutating the textarea changed nothing.
|
|
15
|
+
* The replacement overrides `compileCompactChapterPrompt` in the `@/lib/sage`
|
|
16
|
+
* shim, which is the function the packaged runner actually calls.
|
|
17
|
+
*/
|
|
18
|
+
import { useEffect, useMemo, useState } from "react";
|
|
19
|
+
import { createPortal } from "react-dom";
|
|
20
|
+
import { ChatApp as OriginalChatApp } from "./ChatApp.orig1.tsx";
|
|
21
|
+
import { SageBlueprintPanel } from "./SageBlueprintPanel";
|
|
22
|
+
|
|
23
|
+
export * from "./ChatApp.orig1.tsx";
|
|
24
|
+
|
|
25
|
+
const ANCHOR_ID = "veritas-sage-blueprint-detail-anchor";
|
|
26
|
+
|
|
27
|
+
function findFictionPanel(): HTMLElement | null {
|
|
28
|
+
const candidates = Array.from(document.querySelectorAll("div.rounded-xl"));
|
|
29
|
+
return (candidates.find((el) =>
|
|
30
|
+
el.classList.contains("border-rose-200") ||
|
|
31
|
+
(typeof el.className === "string" &&
|
|
32
|
+
el.className.includes("rose-50") &&
|
|
33
|
+
/Fiction Engine active/i.test(el.textContent || "")),
|
|
34
|
+
) as HTMLElement) ?? null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ensureAnchor(): HTMLElement | null {
|
|
38
|
+
const host = findFictionPanel();
|
|
39
|
+
if (!host) return null;
|
|
40
|
+
let anchor = document.getElementById(ANCHOR_ID);
|
|
41
|
+
if (anchor && host.contains(anchor)) return anchor;
|
|
42
|
+
if (!anchor) {
|
|
43
|
+
anchor = document.createElement("div");
|
|
44
|
+
anchor.id = ANCHOR_ID;
|
|
45
|
+
anchor.className = "mt-3";
|
|
46
|
+
}
|
|
47
|
+
host.appendChild(anchor);
|
|
48
|
+
return anchor;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function BlueprintPortal() {
|
|
52
|
+
const [anchor, setAnchor] = useState<HTMLElement | null>(null);
|
|
53
|
+
const [seed, setSeed] = useState<number | null>(null);
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const sync = () => {
|
|
57
|
+
setAnchor((prev) => {
|
|
58
|
+
const next = ensureAnchor();
|
|
59
|
+
return prev === next ? prev : next;
|
|
60
|
+
});
|
|
61
|
+
const panel = findFictionPanel();
|
|
62
|
+
if (panel) {
|
|
63
|
+
const seedBtn = Array.from(panel.querySelectorAll("button"))
|
|
64
|
+
.find((b) => /seed\s+\d+/i.test(b.textContent || ""));
|
|
65
|
+
const m = seedBtn?.textContent?.match(/seed\s+(\d+)/i);
|
|
66
|
+
if (m) {
|
|
67
|
+
const s = Number(m[1]);
|
|
68
|
+
setSeed((prev) => (prev === s ? prev : s));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
sync();
|
|
73
|
+
const observer = new MutationObserver(sync);
|
|
74
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
75
|
+
const interval = window.setInterval(sync, 800);
|
|
76
|
+
return () => {
|
|
77
|
+
observer.disconnect();
|
|
78
|
+
window.clearInterval(interval);
|
|
79
|
+
document.getElementById(ANCHOR_ID)?.remove();
|
|
80
|
+
};
|
|
81
|
+
}, []);
|
|
82
|
+
|
|
83
|
+
const view = useMemo(() => (seed == null ? null : { seed }), [seed]);
|
|
84
|
+
if (!anchor || !view) return null;
|
|
85
|
+
return createPortal(<SageBlueprintPanel seed={view.seed} />, anchor);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function ChatApp(props: { onSubmitFromShared?: number } = {}) {
|
|
89
|
+
return (
|
|
90
|
+
<>
|
|
91
|
+
<OriginalChatApp {...props} />
|
|
92
|
+
<BlueprintPortal />
|
|
93
|
+
</>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type B — Chat augment portal (workspace durable).
|
|
3
|
+
* Mirrors package ChatAugmentPanels and mounts the workspace SAGA-OS Studio
|
|
4
|
+
* (v3 pipeline + v2 lab + v1–v8 reference, all inside one panel) below Style Persona.
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import { createPortal } from "react-dom";
|
|
8
|
+
import { InnovationPersonaPanel } from '@/components/InnovationPersonaPanel.tsx';
|
|
9
|
+
import { CitationLedgerPanel } from '@/components/CitationLedgerPanel.tsx';
|
|
10
|
+
import { CreativeTreeOfLifePanel } from '@/components/CreativeTreeOfLifePanel.tsx';
|
|
11
|
+
import { SagaOsPanel } from "./SagaOsPanel";
|
|
12
|
+
|
|
13
|
+
const ANCHOR_ID = "veritas-augment-persona-anchor";
|
|
14
|
+
|
|
15
|
+
function findStylePersonaSection(): HTMLElement | null {
|
|
16
|
+
const sections = Array.from(document.querySelectorAll("section"));
|
|
17
|
+
for (const section of sections) {
|
|
18
|
+
if (section.textContent?.includes("Style Persona:")) return section as HTMLElement;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function ensureAnchor(): HTMLElement | null {
|
|
24
|
+
const host = findStylePersonaSection();
|
|
25
|
+
if (!host || !host.parentElement) return null;
|
|
26
|
+
|
|
27
|
+
let anchor = document.getElementById(ANCHOR_ID);
|
|
28
|
+
if (anchor && anchor.previousElementSibling === host) return anchor;
|
|
29
|
+
|
|
30
|
+
if (!anchor) {
|
|
31
|
+
anchor = document.createElement("div");
|
|
32
|
+
anchor.id = ANCHOR_ID;
|
|
33
|
+
anchor.className = "mt-3 space-y-3";
|
|
34
|
+
}
|
|
35
|
+
host.insertAdjacentElement("afterend", anchor);
|
|
36
|
+
return anchor;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function ChatAugmentPanels() {
|
|
40
|
+
const [anchor, setAnchor] = useState<HTMLElement | null>(null);
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (typeof document === "undefined") return;
|
|
44
|
+
|
|
45
|
+
const sync = () => {
|
|
46
|
+
const next = ensureAnchor();
|
|
47
|
+
setAnchor((prev) => (prev === next ? prev : next));
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
sync();
|
|
51
|
+
const observer = new MutationObserver(sync);
|
|
52
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
53
|
+
const interval = window.setInterval(sync, 1000);
|
|
54
|
+
|
|
55
|
+
return () => {
|
|
56
|
+
observer.disconnect();
|
|
57
|
+
window.clearInterval(interval);
|
|
58
|
+
document.getElementById(ANCHOR_ID)?.remove();
|
|
59
|
+
};
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
if (!anchor) return null;
|
|
63
|
+
|
|
64
|
+
return createPortal(
|
|
65
|
+
<>
|
|
66
|
+
<InnovationPersonaPanel />
|
|
67
|
+
<CreativeTreeOfLifePanel />
|
|
68
|
+
<SagaOsPanel />
|
|
69
|
+
<CitationLedgerPanel />
|
|
70
|
+
</>,
|
|
71
|
+
anchor,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CitationLedgerPanel — design-identical sibling of `StylePersonaPanel`.
|
|
3
|
+
* ============================================================================
|
|
4
|
+
* Same section chrome, same expand affordance, same control row, same
|
|
5
|
+
* quantitative card grid with filled bars and numeric readouts.
|
|
6
|
+
*
|
|
7
|
+
* Data source: `@/lib/citation-ledger-store`, populated exclusively by sources
|
|
8
|
+
* that the grounding fleet ACTUALLY fetched. If nothing has been retrieved the
|
|
9
|
+
* panel says so explicitly — it never invents rows to look populated.
|
|
10
|
+
*
|
|
11
|
+
* Columns required by the audit contract:
|
|
12
|
+
* - scraped site (hostname)
|
|
13
|
+
* - title
|
|
14
|
+
* - usage: the pipeline stage at which the source was FIRST integrated
|
|
15
|
+
* ============================================================================ */
|
|
16
|
+
import { useEffect, useMemo, useState } from "react";
|
|
17
|
+
import {
|
|
18
|
+
subscribeCitationLedger,
|
|
19
|
+
clearCitationLedger,
|
|
20
|
+
buildQuotationContract,
|
|
21
|
+
getCitationStyle,
|
|
22
|
+
formatReferenceEntry,
|
|
23
|
+
type CitationLedgerSnapshotLive,
|
|
24
|
+
type CitationStage,
|
|
25
|
+
} from "@/lib/citation-ledger-store";
|
|
26
|
+
|
|
27
|
+
const STAGE_STYLE: Record<CitationStage, string> = {
|
|
28
|
+
initial: "bg-zinc-100 text-zinc-700",
|
|
29
|
+
grounding: "bg-sky-100 text-sky-800",
|
|
30
|
+
hdig: "bg-indigo-100 text-indigo-800",
|
|
31
|
+
cove: "bg-emerald-100 text-emerald-800",
|
|
32
|
+
"n-deep": "bg-violet-100 text-violet-800",
|
|
33
|
+
adversarial: "bg-rose-100 text-rose-800",
|
|
34
|
+
synthesis: "bg-amber-100 text-amber-800",
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const EMPTY: CitationLedgerSnapshotLive = {
|
|
38
|
+
records: [],
|
|
39
|
+
siteCount: 0,
|
|
40
|
+
lastQuestion: "",
|
|
41
|
+
updatedAt: 0,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export function CitationLedgerPanel() {
|
|
45
|
+
const [expanded, setExpanded] = useState(false);
|
|
46
|
+
const [snapshot, setSnapshot] = useState<CitationLedgerSnapshotLive>(EMPTY);
|
|
47
|
+
|
|
48
|
+
useEffect(() => subscribeCitationLedger(setSnapshot), []);
|
|
49
|
+
|
|
50
|
+
const stageCounts = useMemo(() => {
|
|
51
|
+
const counts = new Map<CitationStage, number>();
|
|
52
|
+
for (const record of snapshot.records) {
|
|
53
|
+
counts.set(record.stage, (counts.get(record.stage) ?? 0) + 1);
|
|
54
|
+
}
|
|
55
|
+
return counts;
|
|
56
|
+
}, [snapshot.records]);
|
|
57
|
+
|
|
58
|
+
const siteCounts = useMemo(() => {
|
|
59
|
+
const counts = new Map<string, number>();
|
|
60
|
+
for (const record of snapshot.records) {
|
|
61
|
+
counts.set(record.site, (counts.get(record.site) ?? 0) + 1);
|
|
62
|
+
}
|
|
63
|
+
return Array.from(counts.entries()).sort((a, b) => b[1] - a[1]);
|
|
64
|
+
}, [snapshot.records]);
|
|
65
|
+
|
|
66
|
+
const withSnippet = snapshot.records.filter((r) => r.snippet.length > 0).length;
|
|
67
|
+
const total = snapshot.records.length;
|
|
68
|
+
const quotableRatio = total > 0 ? withSnippet / total : 0;
|
|
69
|
+
const maxSiteHits = siteCounts.length > 0 ? siteCounts[0][1] : 1;
|
|
70
|
+
|
|
71
|
+
const citationStyle = useMemo(() => getCitationStyle(), [snapshot.updatedAt]);
|
|
72
|
+
|
|
73
|
+
const contract = useMemo(
|
|
74
|
+
() => buildQuotationContract(snapshot.records),
|
|
75
|
+
[snapshot.records, citationStyle],
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const referencesFormatted = useMemo(
|
|
79
|
+
() => snapshot.records.map(r => formatReferenceEntry(r, citationStyle)),
|
|
80
|
+
[snapshot.records, citationStyle]
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<section className="rounded-2xl border border-zinc-200 bg-white shadow-sm">
|
|
85
|
+
<button
|
|
86
|
+
onClick={() => setExpanded(!expanded)}
|
|
87
|
+
className="flex w-full items-center justify-between px-5 py-3 text-left"
|
|
88
|
+
>
|
|
89
|
+
<div className="flex items-center gap-3">
|
|
90
|
+
<div className="grid h-8 w-8 place-items-center rounded-lg bg-gradient-to-br from-sky-100 to-emerald-100 text-lg">📚</div>
|
|
91
|
+
<div>
|
|
92
|
+
<div className="flex items-center gap-2">
|
|
93
|
+
<div className="text-sm font-bold text-zinc-900">
|
|
94
|
+
Citation Ledger: <span className="text-sky-700">{total} source{total === 1 ? "" : "s"}</span>
|
|
95
|
+
</div>
|
|
96
|
+
<span
|
|
97
|
+
className={`rounded px-1.5 py-0.5 text-[10px] font-bold ${
|
|
98
|
+
total === 0
|
|
99
|
+
? "bg-zinc-100 text-zinc-600"
|
|
100
|
+
: quotableRatio === 1
|
|
101
|
+
? "bg-emerald-100 text-emerald-800"
|
|
102
|
+
: "bg-amber-100 text-amber-800"
|
|
103
|
+
}`}
|
|
104
|
+
>
|
|
105
|
+
{total === 0 ? "Empty" : `${withSnippet}/${total} quotable`}
|
|
106
|
+
</span>
|
|
107
|
+
</div>
|
|
108
|
+
<div className="text-xs text-zinc-500">
|
|
109
|
+
Verified-retrieved provenance · site, title, and first-use stage per [S#]
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
<div className="flex items-center gap-2">
|
|
114
|
+
<span className="rounded bg-zinc-100 px-2 py-1 font-mono text-[10px] text-zinc-600">
|
|
115
|
+
{snapshot.siteCount} site{snapshot.siteCount === 1 ? "" : "s"}
|
|
116
|
+
</span>
|
|
117
|
+
<span className="text-zinc-400">{expanded ? "−" : "+"}</span>
|
|
118
|
+
</div>
|
|
119
|
+
</button>
|
|
120
|
+
|
|
121
|
+
{expanded && (
|
|
122
|
+
<div className="border-t border-zinc-100 px-5 py-4">
|
|
123
|
+
<div className="mb-4 flex flex-wrap items-center gap-2">
|
|
124
|
+
<button
|
|
125
|
+
onClick={() => navigator.clipboard.writeText(
|
|
126
|
+
snapshot.records
|
|
127
|
+
.map((r) => `[S${r.id}] ${r.title} — ${r.url} (site ${r.site}; first used at ${r.stage}; fingerprint ${r.fingerprint})`)
|
|
128
|
+
.join("\n"),
|
|
129
|
+
)}
|
|
130
|
+
disabled={total === 0}
|
|
131
|
+
className="rounded-lg bg-sky-600 px-3 py-1.5 text-xs font-bold text-white hover:bg-sky-700 disabled:opacity-40"
|
|
132
|
+
>
|
|
133
|
+
Copy References
|
|
134
|
+
</button>
|
|
135
|
+
<button
|
|
136
|
+
onClick={() => navigator.clipboard.writeText(contract)}
|
|
137
|
+
disabled={total === 0}
|
|
138
|
+
className="rounded-lg border border-zinc-200 bg-white px-3 py-1.5 text-xs font-bold text-zinc-700 hover:bg-zinc-50 disabled:opacity-40"
|
|
139
|
+
title="Copy the source-first quotation contract injected into every grounded prompt"
|
|
140
|
+
>
|
|
141
|
+
Copy Contract
|
|
142
|
+
</button>
|
|
143
|
+
<button
|
|
144
|
+
onClick={() => navigator.clipboard.writeText(JSON.stringify(snapshot.records, null, 2))}
|
|
145
|
+
disabled={total === 0}
|
|
146
|
+
className="rounded-lg border border-zinc-200 bg-white px-3 py-1.5 text-xs font-bold text-zinc-700 hover:bg-zinc-50 disabled:opacity-40"
|
|
147
|
+
>
|
|
148
|
+
Export JSON
|
|
149
|
+
</button>
|
|
150
|
+
<button
|
|
151
|
+
onClick={clearCitationLedger}
|
|
152
|
+
disabled={total === 0}
|
|
153
|
+
className="rounded-lg border border-rose-200 bg-rose-50 px-3 py-1.5 text-xs font-bold text-rose-700 hover:bg-rose-100 disabled:opacity-40"
|
|
154
|
+
>
|
|
155
|
+
Clear
|
|
156
|
+
</button>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<div className="mb-4">
|
|
160
|
+
<div className="text-[10px] font-bold uppercase tracking-[0.2em] text-zinc-400">Provenance metrics</div>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
|
164
|
+
<div className="rounded-xl border border-zinc-100 bg-zinc-50 p-3">
|
|
165
|
+
<div className="flex items-center justify-between">
|
|
166
|
+
<div className="text-xs font-bold text-zinc-900">Quotable coverage</div>
|
|
167
|
+
<div className="rounded bg-sky-50 px-1.5 py-0.5 font-mono text-[9px] text-sky-700">verbatim</div>
|
|
168
|
+
</div>
|
|
169
|
+
<div className="mt-2 flex items-center gap-2">
|
|
170
|
+
<span className="w-16 text-right text-[9px] leading-tight text-zinc-500">no text</span>
|
|
171
|
+
<div className="relative h-2 flex-1 overflow-hidden rounded-full bg-zinc-200">
|
|
172
|
+
<div className="absolute left-0 top-0 h-full rounded-full bg-gradient-to-r from-sky-500 to-emerald-500" style={{ width: `${quotableRatio * 100}%` }} />
|
|
173
|
+
<div className="absolute top-[-2px] h-3 w-1 rounded-full bg-zinc-900" style={{ left: `calc(${quotableRatio * 100}% - 2px)` }} />
|
|
174
|
+
</div>
|
|
175
|
+
<span className="w-16 text-[9px] leading-tight text-zinc-500">full text</span>
|
|
176
|
+
</div>
|
|
177
|
+
<div className="mt-1 text-right font-mono text-[10px] text-zinc-400">{quotableRatio.toFixed(2)}</div>
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<div className="rounded-xl border border-zinc-100 bg-zinc-50 p-3">
|
|
181
|
+
<div className="flex items-center justify-between">
|
|
182
|
+
<div className="text-xs font-bold text-zinc-900">Source diversity</div>
|
|
183
|
+
<div className="rounded bg-emerald-50 px-1.5 py-0.5 font-mono text-[9px] text-emerald-700">hosts</div>
|
|
184
|
+
</div>
|
|
185
|
+
<div className="mt-2 flex items-center gap-2">
|
|
186
|
+
<span className="w-16 text-right text-[9px] leading-tight text-zinc-500">single host</span>
|
|
187
|
+
<div className="relative h-2 flex-1 overflow-hidden rounded-full bg-zinc-200">
|
|
188
|
+
<div
|
|
189
|
+
className="absolute left-0 top-0 h-full rounded-full bg-gradient-to-r from-emerald-500 to-sky-500"
|
|
190
|
+
style={{ width: `${total > 0 ? (snapshot.siteCount / total) * 100 : 0}%` }}
|
|
191
|
+
/>
|
|
192
|
+
</div>
|
|
193
|
+
<span className="w-16 text-[9px] leading-tight text-zinc-500">all distinct</span>
|
|
194
|
+
</div>
|
|
195
|
+
<div className="mt-1 text-right font-mono text-[10px] text-zinc-400">
|
|
196
|
+
{total > 0 ? (snapshot.siteCount / total).toFixed(2) : "0.00"}
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<div className="rounded-xl border border-zinc-100 bg-zinc-50 p-3">
|
|
201
|
+
<div className="flex items-center justify-between">
|
|
202
|
+
<div className="text-xs font-bold text-zinc-900">Stage spread</div>
|
|
203
|
+
<div className="rounded bg-violet-50 px-1.5 py-0.5 font-mono text-[9px] text-violet-700">usage</div>
|
|
204
|
+
</div>
|
|
205
|
+
<div className="mt-2 space-y-1">
|
|
206
|
+
{stageCounts.size === 0 && <div className="text-[10px] text-zinc-400">No stages recorded yet.</div>}
|
|
207
|
+
{Array.from(stageCounts.entries()).map(([stage, count]) => (
|
|
208
|
+
<div key={stage} className="flex items-center justify-between text-[10px]">
|
|
209
|
+
<span className={`rounded px-1.5 py-0.5 font-bold ${STAGE_STYLE[stage]}`}>{stage}</span>
|
|
210
|
+
<span className="font-mono text-zinc-500">{count}</span>
|
|
211
|
+
</div>
|
|
212
|
+
))}
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
|
|
217
|
+
{siteCounts.length > 0 && (
|
|
218
|
+
<>
|
|
219
|
+
<div className="mb-2 mt-4 text-[10px] font-bold uppercase tracking-[0.2em] text-zinc-400">
|
|
220
|
+
Per-site retrieval count
|
|
221
|
+
</div>
|
|
222
|
+
<div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
|
223
|
+
{siteCounts.map(([site, count]) => (
|
|
224
|
+
<div key={site} className="rounded-xl border border-zinc-100 bg-zinc-50 p-3">
|
|
225
|
+
<div className="flex items-center justify-between">
|
|
226
|
+
<div className="truncate text-xs font-bold text-zinc-900" title={site}>{site}</div>
|
|
227
|
+
<div className="font-mono text-[10px] text-zinc-500">{count}</div>
|
|
228
|
+
</div>
|
|
229
|
+
<div className="mt-2 h-2 overflow-hidden rounded-full bg-zinc-200">
|
|
230
|
+
<div
|
|
231
|
+
className="h-full rounded-full bg-gradient-to-r from-sky-500 to-indigo-500"
|
|
232
|
+
style={{ width: `${(count / maxSiteHits) * 100}%` }}
|
|
233
|
+
/>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
))}
|
|
237
|
+
</div>
|
|
238
|
+
</>
|
|
239
|
+
)}
|
|
240
|
+
|
|
241
|
+
<div className="mb-2 mt-4 text-[10px] font-bold uppercase tracking-[0.2em] text-zinc-400">
|
|
242
|
+
Ledger entries
|
|
243
|
+
</div>
|
|
244
|
+
<div className="mb-2 text-[10px] leading-tight text-zinc-500">
|
|
245
|
+
<b>grounding</b> = fetched by a retrieval lane, not yet confirmed in the draft.
|
|
246
|
+
All other stages come from the pipeline's own ledger and mark the point at
|
|
247
|
+
which the source was <b>first integrated into the draft</b>.
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
{total === 0 ? (
|
|
251
|
+
<div className="rounded-xl border border-dashed border-zinc-200 bg-zinc-50 p-4 text-center text-xs text-zinc-500">
|
|
252
|
+
No sources retrieved yet. Run a grounded query — every fetched document is recorded here
|
|
253
|
+
automatically with its site, title, and the stage at which it first entered the draft.
|
|
254
|
+
</div>
|
|
255
|
+
) : (
|
|
256
|
+
<div className="overflow-x-auto rounded-xl border border-zinc-200">
|
|
257
|
+
<table className="w-full text-left text-[11px]">
|
|
258
|
+
<thead className="bg-zinc-50 font-bold text-zinc-600">
|
|
259
|
+
<tr>
|
|
260
|
+
<th className="px-3 py-2">Tag</th>
|
|
261
|
+
<th className="px-3 py-2">Site</th>
|
|
262
|
+
<th className="px-3 py-2">Title</th>
|
|
263
|
+
<th className="px-3 py-2">Usage (first draft stage)</th>
|
|
264
|
+
<th className="px-3 py-2">Lane</th>
|
|
265
|
+
<th className="px-3 py-2">Fingerprint</th>
|
|
266
|
+
</tr>
|
|
267
|
+
</thead>
|
|
268
|
+
<tbody className="divide-y divide-zinc-100">
|
|
269
|
+
{snapshot.records.map((record) => (
|
|
270
|
+
<tr key={record.id} className="align-top">
|
|
271
|
+
<td className="whitespace-nowrap px-3 py-2 font-mono font-bold text-zinc-800">[S{record.id}]</td>
|
|
272
|
+
<td className="px-3 py-2">
|
|
273
|
+
<a href={record.url} target="_blank" rel="noreferrer" className="text-blue-600 hover:underline">
|
|
274
|
+
{record.site}
|
|
275
|
+
</a>
|
|
276
|
+
</td>
|
|
277
|
+
<td className="max-w-[280px] px-3 py-2 text-zinc-800" title={record.title}>{record.title}</td>
|
|
278
|
+
<td className="px-3 py-2">
|
|
279
|
+
<span className={`rounded px-1.5 py-0.5 text-[10px] font-bold ${STAGE_STYLE[record.stage]}`}>
|
|
280
|
+
{record.stage}
|
|
281
|
+
</span>
|
|
282
|
+
</td>
|
|
283
|
+
<td className="px-3 py-2 font-mono text-[10px] text-zinc-500">{record.lane}</td>
|
|
284
|
+
<td className="px-3 py-2 font-mono text-[10px] text-zinc-400">{record.fingerprint}</td>
|
|
285
|
+
</tr>
|
|
286
|
+
))}
|
|
287
|
+
</tbody>
|
|
288
|
+
</table>
|
|
289
|
+
</div>
|
|
290
|
+
)}
|
|
291
|
+
|
|
292
|
+
<details className="mt-4">
|
|
293
|
+
<summary className="cursor-pointer text-xs font-bold text-zinc-600 hover:text-zinc-900">
|
|
294
|
+
View References formatted as {citationStyle.toUpperCase()} (from Cite dropdown)
|
|
295
|
+
</summary>
|
|
296
|
+
<pre className="mt-2 max-h-64 overflow-auto whitespace-pre-wrap rounded-xl border border-zinc-200 bg-white p-4 font-mono text-xs leading-relaxed text-zinc-800">
|
|
297
|
+
{referencesFormatted.length > 0 ? referencesFormatted.join("\n\n") : "(no sources yet — references appear here once ledger is populated)"}
|
|
298
|
+
</pre>
|
|
299
|
+
</details>
|
|
300
|
+
|
|
301
|
+
<details className="mt-2">
|
|
302
|
+
<summary className="cursor-pointer text-xs font-bold text-zinc-600 hover:text-zinc-900">
|
|
303
|
+
View source-first quotation contract (injected into every grounded prompt, {citationStyle.toUpperCase()} style)
|
|
304
|
+
</summary>
|
|
305
|
+
<pre className="mt-2 max-h-64 overflow-auto whitespace-pre-wrap rounded-xl border border-zinc-200 bg-white p-4 font-mono text-xs leading-relaxed text-zinc-800">
|
|
306
|
+
{contract || "(no sources yet — contract is injected once the ledger is populated)"}
|
|
307
|
+
</pre>
|
|
308
|
+
</details>
|
|
309
|
+
</div>
|
|
310
|
+
)}
|
|
311
|
+
</section>
|
|
312
|
+
);
|
|
313
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { useMemo, useState } from "react";
|
|
2
|
+
import { COMPUTE_REGISTRY, runComputeCall, type ComputeRecord } from "../lib/compute-sandbox";
|
|
3
|
+
|
|
4
|
+
// Interactive front-end for the SAME deterministic sandbox the reasoning
|
|
5
|
+
// pipeline calls. Whatever you run here is byte-for-byte what the AI invokes
|
|
6
|
+
// during Stage 2.5 — no separate code path, no simulation.
|
|
7
|
+
export function ComputeSandboxPanel() {
|
|
8
|
+
const groups = useMemo(() => {
|
|
9
|
+
const m = new Map<string, typeof COMPUTE_REGISTRY>();
|
|
10
|
+
for (const s of COMPUTE_REGISTRY) { const g = m.get(s.group) ?? []; g.push(s); m.set(s.group, g); }
|
|
11
|
+
return [...m.entries()];
|
|
12
|
+
}, []);
|
|
13
|
+
|
|
14
|
+
const [activeId, setActiveId] = useState(COMPUTE_REGISTRY[0].id);
|
|
15
|
+
const spec = COMPUTE_REGISTRY.find((s) => s.id === activeId)!;
|
|
16
|
+
const [args, setArgs] = useState<Record<string, string>>(() =>
|
|
17
|
+
Object.fromEntries(spec.params.map((p) => [p.name, String(p.default)]))
|
|
18
|
+
);
|
|
19
|
+
const [record, setRecord] = useState<ComputeRecord | null>(null);
|
|
20
|
+
|
|
21
|
+
function selectFn(id: string) {
|
|
22
|
+
setActiveId(id);
|
|
23
|
+
const s = COMPUTE_REGISTRY.find((x) => x.id === id)!;
|
|
24
|
+
setArgs(Object.fromEntries(s.params.map((p) => [p.name, String(p.default)])));
|
|
25
|
+
setRecord(null);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function run() {
|
|
29
|
+
const parsed: Record<string, number | number[]> = {};
|
|
30
|
+
for (const p of spec.params) {
|
|
31
|
+
const raw = args[p.name] ?? "";
|
|
32
|
+
parsed[p.name] = p.kind === "number[]"
|
|
33
|
+
? raw.split(/[,\s]+/).map(Number).filter((x) => isFinite(x))
|
|
34
|
+
: Number(raw);
|
|
35
|
+
}
|
|
36
|
+
setRecord(runComputeCall({ id: spec.id, args: parsed }));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div className="rounded-2xl border border-zinc-200 bg-white shadow-sm overflow-hidden">
|
|
41
|
+
<div className="flex flex-wrap items-center justify-between gap-2 border-b border-zinc-200 px-4 py-2.5">
|
|
42
|
+
<div className="flex items-center gap-2">
|
|
43
|
+
<span className="text-sm font-bold text-zinc-900">Deterministic Compute Sandbox</span>
|
|
44
|
+
<span className="rounded-full bg-emerald-50 px-2 py-0.5 text-[10px] font-bold text-emerald-700">{COMPUTE_REGISTRY.length} whitelisted functions</span>
|
|
45
|
+
</div>
|
|
46
|
+
<span className="text-[10px] text-zinc-400">same path the reasoning chain calls · no eval · pure functions</span>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div className="grid gap-4 p-4 lg:grid-cols-[260px_1fr]">
|
|
50
|
+
{/* Function list */}
|
|
51
|
+
<div className="max-h-80 space-y-3 overflow-y-auto pr-1">
|
|
52
|
+
{groups.map(([group, specs]) => (
|
|
53
|
+
<div key={group}>
|
|
54
|
+
<div className="mb-1 text-[10px] font-bold uppercase tracking-wider text-zinc-400">{group}</div>
|
|
55
|
+
<div className="space-y-0.5">
|
|
56
|
+
{specs.map((s) => (
|
|
57
|
+
<button key={s.id} onClick={() => selectFn(s.id)}
|
|
58
|
+
className={`block w-full rounded-lg px-2.5 py-1.5 text-left text-xs ${activeId === s.id ? "bg-zinc-900 text-white" : "text-zinc-700 hover:bg-zinc-100"}`}>
|
|
59
|
+
{s.label}
|
|
60
|
+
<span className={`ml-1 font-mono text-[10px] ${activeId === s.id ? "text-zinc-400" : "text-zinc-400"}`}>{s.id}</span>
|
|
61
|
+
</button>
|
|
62
|
+
))}
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
))}
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
{/* Inputs + run + output */}
|
|
69
|
+
<div className="space-y-3">
|
|
70
|
+
<div className="rounded-xl border border-zinc-100 bg-zinc-50 p-3">
|
|
71
|
+
<div className="text-xs font-bold text-zinc-900">{spec.label}</div>
|
|
72
|
+
<div className="font-mono text-[11px] text-zinc-500">{spec.id} — {spec.formula}</div>
|
|
73
|
+
</div>
|
|
74
|
+
<div className="grid grid-cols-2 gap-2">
|
|
75
|
+
{spec.params.map((p) => (
|
|
76
|
+
<label key={p.name} className="block text-[11px] font-semibold text-zinc-600">
|
|
77
|
+
{p.name} <span className="font-mono text-zinc-400">{p.kind}</span>
|
|
78
|
+
<input value={args[p.name] ?? ""} onChange={(e) => setArgs({ ...args, [p.name]: e.target.value })}
|
|
79
|
+
placeholder={p.kind === "number[]" ? "comma-separated" : "number"}
|
|
80
|
+
className="mt-0.5 w-full rounded-lg border border-zinc-300 px-2 py-1 text-xs font-mono" />
|
|
81
|
+
</label>
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
<button onClick={run} className="rounded-lg bg-indigo-600 px-4 py-1.5 text-xs font-bold text-white hover:bg-indigo-700">Run calculation</button>
|
|
85
|
+
|
|
86
|
+
{record && (
|
|
87
|
+
<div className={`rounded-xl border p-3 ${record.ok ? "border-emerald-200 bg-emerald-50" : "border-rose-200 bg-rose-50"}`}>
|
|
88
|
+
<div className="flex items-center justify-between">
|
|
89
|
+
<span className={`text-xs font-bold ${record.ok ? "text-emerald-800" : "text-rose-800"}`}>{record.ok ? "Verified output" : "Compute failed"}</span>
|
|
90
|
+
<span className="font-mono text-[10px] text-zinc-500">{record.ms.toFixed(2)} ms</span>
|
|
91
|
+
</div>
|
|
92
|
+
{record.result ? (
|
|
93
|
+
<div className="mt-2 space-y-1">
|
|
94
|
+
{Object.entries(record.result).map(([k, v]) => (
|
|
95
|
+
<div key={k} className="flex items-center justify-between font-mono text-xs">
|
|
96
|
+
<span className="text-zinc-600">{k}</span>
|
|
97
|
+
<span className={`font-bold ${isFinite(v) ? "text-zinc-900" : "text-rose-700"}`}>{isFinite(v) ? v.toLocaleString(undefined, { maximumFractionDigits: 4 }) : "NaN — check inputs"}</span>
|
|
98
|
+
</div>
|
|
99
|
+
))}
|
|
100
|
+
</div>
|
|
101
|
+
) : (
|
|
102
|
+
<div className="mt-1 text-xs text-rose-700">{record.error}</div>
|
|
103
|
+
)}
|
|
104
|
+
</div>
|
|
105
|
+
)}
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Compact read-only renderer for compute records attached to a chat answer. */
|
|
113
|
+
export function ComputeRecordsInline({ records }: { records: ComputeRecord[] }) {
|
|
114
|
+
if (!records.length) return null;
|
|
115
|
+
return (
|
|
116
|
+
<details className="mb-3">
|
|
117
|
+
<summary className="cursor-pointer text-xs font-semibold text-emerald-700 hover:text-emerald-900">
|
|
118
|
+
Deterministic calculations ({records.filter((r) => r.ok).length}/{records.length} verified)
|
|
119
|
+
</summary>
|
|
120
|
+
<div className="mt-2 space-y-1 rounded-lg border border-emerald-100 bg-emerald-50/60 p-3 font-mono text-[11px]">
|
|
121
|
+
{records.map((r, i) => (
|
|
122
|
+
<div key={i} className={r.ok ? "text-emerald-800" : "text-rose-700"}>
|
|
123
|
+
{r.label}: {r.result ? Object.entries(r.result).map(([k, v]) => `${k}=${isFinite(v) ? v.toLocaleString(undefined, { maximumFractionDigits: 3 }) : "NaN"}`).join(", ") : (r.error ?? "failed")}
|
|
124
|
+
<span className="ml-1 text-zinc-400">[{r.formula}]</span>
|
|
125
|
+
</div>
|
|
126
|
+
))}
|
|
127
|
+
</div>
|
|
128
|
+
</details>
|
|
129
|
+
);
|
|
130
|
+
}
|