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,110 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { GEMINI_MODELS, type GeminiModel } from "../lib/connectors/gemini";
|
|
3
|
+
import type { SearchProvider } from "../lib/orchestrator";
|
|
4
|
+
import { useAppState } from "../lib/app-state";
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
hypothesisModel: GeminiModel;
|
|
8
|
+
setHypothesisModel: (m: GeminiModel) => void;
|
|
9
|
+
scoringModel: GeminiModel;
|
|
10
|
+
setScoringModel: (m: GeminiModel) => void;
|
|
11
|
+
searchProvider: SearchProvider;
|
|
12
|
+
setSearchProvider: (p: SearchProvider) => void;
|
|
13
|
+
useJinaRerank: boolean;
|
|
14
|
+
setUseJinaRerank: (b: boolean) => void;
|
|
15
|
+
tier: number | "auto";
|
|
16
|
+
setTier: (t: number | "auto") => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function ConfigPanel(props: Props) {
|
|
20
|
+
const [open, setOpen] = useState(false);
|
|
21
|
+
const { keys, setKeys } = useAppState();
|
|
22
|
+
const [show, setShow] = useState<Record<string, boolean>>({});
|
|
23
|
+
|
|
24
|
+
function updateKey(k: "gemini" | "jina" | "serpapi" | "serpapiProxy" | "marketData", v: string) {
|
|
25
|
+
setKeys(prev => ({ ...prev, [k]: v }));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className="rounded-2xl border border-zinc-200 bg-white shadow-sm">
|
|
30
|
+
<button onClick={() => setOpen(!open)} className="flex w-full items-center justify-between px-4 py-3 text-left">
|
|
31
|
+
<span className="text-sm font-bold text-zinc-900">Dashboard configuration</span>
|
|
32
|
+
<span className="text-zinc-400">{open ? "−" : "+"}</span>
|
|
33
|
+
</button>
|
|
34
|
+
{open && (
|
|
35
|
+
<div className="space-y-4 border-t border-zinc-200 p-4">
|
|
36
|
+
<div className="grid gap-3 sm:grid-cols-2">
|
|
37
|
+
{([
|
|
38
|
+
{ k: "gemini", label: "Gemini / Gemma API key", ph: "AIza…" },
|
|
39
|
+
{ k: "jina", label: "Jina API key", ph: "jina_…" },
|
|
40
|
+
{ k: "serpapi", label: "SerpAPI key (optional)", ph: "(optional)" },
|
|
41
|
+
{ k: "serpapiProxy", label: "SerpAPI CORS proxy", ph: "https://proxy/?url=" },
|
|
42
|
+
{ k: "marketData", label: "Market data key (Alpha Vantage)", ph: "optional" },
|
|
43
|
+
] as { k: "gemini" | "jina" | "serpapi" | "serpapiProxy" | "marketData"; label: string; ph: string }[]).map(({ k, label, ph }) => (
|
|
44
|
+
<div key={k} className="space-y-1">
|
|
45
|
+
<label className="text-xs font-semibold text-zinc-600">{label}</label>
|
|
46
|
+
<div className="relative">
|
|
47
|
+
<input
|
|
48
|
+
type={show[k] ? "text" : "password"}
|
|
49
|
+
value={(keys[k] as string) ?? ""}
|
|
50
|
+
onChange={e => updateKey(k, e.target.value)}
|
|
51
|
+
placeholder={ph}
|
|
52
|
+
className="w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm font-mono text-zinc-900 outline-none focus:border-indigo-500"
|
|
53
|
+
/>
|
|
54
|
+
<button type="button" onClick={() => setShow(s => ({ ...s, [k]: !s[k] }))}
|
|
55
|
+
className="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-zinc-400 hover:text-zinc-700">{show[k] ? "hide" : "show"}</button>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
))}
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div className="grid gap-3 sm:grid-cols-2">
|
|
62
|
+
<div>
|
|
63
|
+
<label className="text-xs font-semibold text-zinc-600">Hypothesis generator</label>
|
|
64
|
+
<select value={props.hypothesisModel} onChange={e => props.setHypothesisModel(e.target.value as GeminiModel)}
|
|
65
|
+
className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm">
|
|
66
|
+
{GEMINI_MODELS.map(m => <option key={m.id} value={m.id}>{m.label}</option>)}
|
|
67
|
+
</select>
|
|
68
|
+
</div>
|
|
69
|
+
<div>
|
|
70
|
+
<label className="text-xs font-semibold text-zinc-600">Judge / synthesizer</label>
|
|
71
|
+
<select value={props.scoringModel} onChange={e => props.setScoringModel(e.target.value as GeminiModel)}
|
|
72
|
+
className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm">
|
|
73
|
+
{GEMINI_MODELS.map(m => <option key={m.id} value={m.id}>{m.label}</option>)}
|
|
74
|
+
</select>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div className="grid gap-3 sm:grid-cols-3">
|
|
79
|
+
<div>
|
|
80
|
+
<label className="text-xs font-semibold text-zinc-600">Search provider</label>
|
|
81
|
+
<select value={props.searchProvider} onChange={e => props.setSearchProvider(e.target.value as SearchProvider)}
|
|
82
|
+
className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm">
|
|
83
|
+
<option value="jina">Jina Search (s.jina.ai)</option>
|
|
84
|
+
<option value="serpapi">SerpAPI</option>
|
|
85
|
+
</select>
|
|
86
|
+
</div>
|
|
87
|
+
<div>
|
|
88
|
+
<label className="text-xs font-semibold text-zinc-600">Tier</label>
|
|
89
|
+
<select value={props.tier} onChange={e => props.setTier(e.target.value === "auto" ? "auto" : Number(e.target.value))}
|
|
90
|
+
className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm">
|
|
91
|
+
<option value="auto">Auto (adaptive)</option>
|
|
92
|
+
{[0,1,2,3,4,5].map(n => <option key={n} value={n}>T{n}</option>)}
|
|
93
|
+
</select>
|
|
94
|
+
</div>
|
|
95
|
+
<div className="flex flex-col pt-5">
|
|
96
|
+
<label className="inline-flex items-center gap-2 text-sm text-zinc-700 cursor-pointer">
|
|
97
|
+
<input type="checkbox" checked={props.useJinaRerank} onChange={e => props.setUseJinaRerank(e.target.checked)} className="h-4 w-4 rounded" />
|
|
98
|
+
Jina rerank
|
|
99
|
+
</label>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div className="rounded-xl border border-amber-100 bg-amber-50 p-3 text-xs text-amber-900">
|
|
104
|
+
Keys here are shared with the Chat tab (same localStorage). SerpAPI typically blocks browser CORS — use Jina or supply a proxy.
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
)}
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { useMemo, useState, type ReactNode } from "react";
|
|
2
|
+
import { AnchorBaselinePanel } from "./AnchorBaselinePanel";
|
|
3
|
+
import { useAppState } from "../lib/app-state";
|
|
4
|
+
import { extractConstraints, summarizeConstraints } from "../lib/constraints";
|
|
5
|
+
import { StylePersonaPanel } from "./StylePersonaPanel";
|
|
6
|
+
import { MemoryStressPanel } from "./MemoryStressPanel";
|
|
7
|
+
import { PrismaFetchTracePanel } from "./PrismaFetchTracePanel";
|
|
8
|
+
|
|
9
|
+
type Section = "depth" | "tools" | "verification" | "output" | "runtime" | "governance";
|
|
10
|
+
|
|
11
|
+
export function ControlPlanePage() {
|
|
12
|
+
const { input, lastRun, persona, reseedPersona, keys, model, settings, setSetting, debugEvents } = useAppState();
|
|
13
|
+
const constraints = input.trim() ? extractConstraints(input) : null;
|
|
14
|
+
|
|
15
|
+
const [config, setConfig] = useState({
|
|
16
|
+
research_tier: "AUTO",
|
|
17
|
+
reasoning_budget: "AUTO",
|
|
18
|
+
council_width: 5,
|
|
19
|
+
worker_depth: 9,
|
|
20
|
+
web_access: "on",
|
|
21
|
+
anchor_mode: "preferred",
|
|
22
|
+
verifier_alpha: 25,
|
|
23
|
+
entailment_threshold: 80,
|
|
24
|
+
require_verbatim: true,
|
|
25
|
+
falsification_gate: true,
|
|
26
|
+
output_format: "report",
|
|
27
|
+
citation_density: "every-claim",
|
|
28
|
+
driver_model: model,
|
|
29
|
+
token_ceiling: 300000,
|
|
30
|
+
time_ceiling: 1200,
|
|
31
|
+
audit_receipt: true,
|
|
32
|
+
cors_proxy: "",
|
|
33
|
+
});
|
|
34
|
+
const [active, setActive] = useState<Section>("depth");
|
|
35
|
+
const serialized = useMemo(() => JSON.stringify(config, null, 2), [config]);
|
|
36
|
+
const set = (key: keyof typeof config, value: string | number | boolean) =>
|
|
37
|
+
setConfig(p => ({ ...p, [key]: value }));
|
|
38
|
+
|
|
39
|
+
const keysConfigured = Object.entries(keys).filter(([, v]) => !!v).map(([k]) => k);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div className="bg-zinc-50 pb-10">
|
|
43
|
+
<div className="mx-auto max-w-6xl space-y-5 px-4 py-6">
|
|
44
|
+
{/* Header */}
|
|
45
|
+
<section className="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm">
|
|
46
|
+
<div className="text-xs font-bold uppercase tracking-[0.2em] text-indigo-600">ATLAS-DR Control Plane</div>
|
|
47
|
+
<h1 className="mt-1 text-2xl font-bold tracking-tight text-zinc-900">Power-user dials for tiered research</h1>
|
|
48
|
+
<p className="mt-2 max-w-3xl text-sm text-zinc-600">
|
|
49
|
+
These controls map to the chat and GBSE strategy. All values here are advisory — enable them then run a query.
|
|
50
|
+
</p>
|
|
51
|
+
</section>
|
|
52
|
+
|
|
53
|
+
{/* Live shared state mirror — proves cross-page state */}
|
|
54
|
+
<section className="rounded-2xl border border-emerald-200 bg-emerald-50 p-4 shadow-sm">
|
|
55
|
+
<div className="mb-2 text-[10px] font-bold uppercase tracking-[0.2em] text-emerald-700">Live shared state mirror (proves all pages share the same context)</div>
|
|
56
|
+
<div className="grid gap-2 text-xs sm:grid-cols-2 lg:grid-cols-4">
|
|
57
|
+
<div><span className="font-bold text-emerald-700">Current input:</span><div className="mt-0.5 font-mono text-zinc-800 truncate">{input || "(empty)"}</div></div>
|
|
58
|
+
<div><span className="font-bold text-emerald-700">Constraints:</span><div className="mt-0.5 font-mono text-zinc-800">{constraints ? summarizeConstraints(constraints) : "none"}</div></div>
|
|
59
|
+
<div><span className="font-bold text-emerald-700">Persona:</span><div className="mt-0.5 font-mono text-zinc-800">{persona.archetype.name} (seed {persona.seed})</div></div>
|
|
60
|
+
<div><span className="font-bold text-emerald-700">Keys configured:</span><div className="mt-0.5 font-mono text-zinc-800">{keysConfigured.join(", ") || "none"}</div></div>
|
|
61
|
+
{lastRun && (
|
|
62
|
+
<div className="sm:col-span-2 lg:col-span-4">
|
|
63
|
+
<span className="font-bold text-emerald-700">Last run:</span>
|
|
64
|
+
<div className="mt-0.5 font-mono text-zinc-800">
|
|
65
|
+
"{lastRun.query.slice(0, 80)}…" → {lastRun.totalClaims} claims · {lastRun.sources} sources · {(lastRun.elapsedMs / 1000).toFixed(1)}s
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
</section>
|
|
71
|
+
|
|
72
|
+
{/* App-level settings */}
|
|
73
|
+
<section className="rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm">
|
|
74
|
+
<h2 className="mb-3 text-sm font-bold text-zinc-900">App-level toggles</h2>
|
|
75
|
+
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
76
|
+
<Toggle label="4-Stage pipeline" sub="Logic Engine + Copywriter pass" checked={settings.deepResearch} onChange={v => setSetting("deepResearch", v)} accent />
|
|
77
|
+
<Toggle label="Show debug trace" sub="Debug events appear on all pages" checked={settings.showDebugTrace} onChange={v => setSetting("showDebugTrace", v)} />
|
|
78
|
+
<Toggle label="Auto-audit connectors" sub="Ping keys on page load" checked={settings.autoAuditConnectors} onChange={v => setSetting("autoAuditConnectors", v)} />
|
|
79
|
+
</div>
|
|
80
|
+
</section>
|
|
81
|
+
|
|
82
|
+
{/* Main config panels */}
|
|
83
|
+
<div className="grid gap-5 lg:grid-cols-[240px_1fr]">
|
|
84
|
+
<aside className="rounded-2xl border border-zinc-200 bg-white p-3 shadow-sm h-fit">
|
|
85
|
+
{(["depth", "tools", "verification", "output", "runtime", "governance"] as Section[]).map(s => (
|
|
86
|
+
<button key={s} onClick={() => setActive(s)}
|
|
87
|
+
className={`mb-1 block w-full rounded-xl px-3 py-2 text-left text-sm font-semibold capitalize transition-colors ${active === s ? "bg-zinc-900 text-white" : "text-zinc-700 hover:bg-zinc-100"}`}>
|
|
88
|
+
{s}
|
|
89
|
+
</button>
|
|
90
|
+
))}
|
|
91
|
+
</aside>
|
|
92
|
+
|
|
93
|
+
<section className="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm">
|
|
94
|
+
{active === "depth" && <Panel title="Depth">
|
|
95
|
+
<Select label="Research tier" value={config.research_tier} options={["AUTO","0","1","2","3","4","5"]} onChange={v => set("research_tier", v)} />
|
|
96
|
+
<Select label="Reasoning budget" value={config.reasoning_budget} options={["AUTO","low","medium","high","exhaustive"]} onChange={v => set("reasoning_budget", v)} />
|
|
97
|
+
<NumberInput label="Council width" value={config.council_width} min={1} max={32} onChange={v => set("council_width", v)} />
|
|
98
|
+
<NumberInput label="Worker depth" value={config.worker_depth} min={1} max={32} onChange={v => set("worker_depth", v)} />
|
|
99
|
+
</Panel>}
|
|
100
|
+
{active === "tools" && <Panel title="Tool scope">
|
|
101
|
+
<Select label="Web access" value={config.web_access} options={["on","trusted","off"]} onChange={v => set("web_access", v)} />
|
|
102
|
+
<Select label="Anchor mode" value={config.anchor_mode} options={["required","preferred","off"]} onChange={v => set("anchor_mode", v)} />
|
|
103
|
+
<label className="block text-xs font-semibold text-zinc-600 mt-2">
|
|
104
|
+
Custom CORS Proxy
|
|
105
|
+
<input
|
|
106
|
+
value={(config as any).cors_proxy ?? ""}
|
|
107
|
+
placeholder="https://cors-anywhere.herokuapp.com/"
|
|
108
|
+
onChange={e => set("cors_proxy", e.target.value)}
|
|
109
|
+
className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm"
|
|
110
|
+
/>
|
|
111
|
+
</label>
|
|
112
|
+
<Hint text="If direct browser fetch fails due to CORS, the app will rotate through public proxies. Use a custom one for higher reliability." />
|
|
113
|
+
</Panel>}
|
|
114
|
+
{active === "verification" && <Panel title="Verification">
|
|
115
|
+
<RangeInput label="Verifier alpha" value={config.verifier_alpha} min={10} max={40} suffix="%" onChange={v => set("verifier_alpha", v)} />
|
|
116
|
+
<RangeInput label="Entailment threshold" value={config.entailment_threshold} min={60} max={95} suffix="%" onChange={v => set("entailment_threshold", v)} />
|
|
117
|
+
<Toggle label="Require verbatim quote spans" checked={config.require_verbatim} onChange={v => set("require_verbatim", v)} />
|
|
118
|
+
<Toggle label="Falsification gate (construct ¬H)" checked={config.falsification_gate} onChange={v => set("falsification_gate", v)} />
|
|
119
|
+
</Panel>}
|
|
120
|
+
{active === "output" && <Panel title="Output">
|
|
121
|
+
<Select label="Format" value={config.output_format} options={["report","compact","json","slides","docs"]} onChange={v => set("output_format", v)} />
|
|
122
|
+
<Select label="Citation density" value={config.citation_density} options={["every-claim","load-bearing-only"]} onChange={v => set("citation_density", v)} />
|
|
123
|
+
</Panel>}
|
|
124
|
+
{active === "runtime" && <Panel title="Runtime">
|
|
125
|
+
<Select label="Driver model" value={config.driver_model} options={["frontier","gemma4-31b","qwen3.6","gemma4-e4b","apple-ondevice","bonsai-8b"]} onChange={v => set("driver_model", v)} />
|
|
126
|
+
<NumberInput label="Token ceiling" value={config.token_ceiling} min={2000} max={3000000} onChange={v => set("token_ceiling", v)} />
|
|
127
|
+
<NumberInput label="Time ceiling (seconds)" value={config.time_ceiling} min={15} max={5400} onChange={v => set("time_ceiling", v)} />
|
|
128
|
+
<div className="col-span-2 pt-2">
|
|
129
|
+
<MemoryStressPanel />
|
|
130
|
+
<div className="mt-3"><PrismaFetchTracePanel /></div>
|
|
131
|
+
</div>
|
|
132
|
+
</Panel>}
|
|
133
|
+
{active === "governance" && <Panel title="Governance">
|
|
134
|
+
<Toggle label="Audit receipt (SSCP/Merkle ledger)" checked={config.audit_receipt} onChange={v => set("audit_receipt", v)} />
|
|
135
|
+
<Hint text="Safety kernel, data-only context rule, injection defenses, and the 126 failure-mode guards remain active regardless of these settings." />
|
|
136
|
+
</Panel>}
|
|
137
|
+
|
|
138
|
+
<div className="mt-5 rounded-2xl border border-zinc-200 bg-zinc-950 p-4">
|
|
139
|
+
<div className="mb-2 text-xs font-bold uppercase tracking-[0.18em] text-emerald-300">atlas.config.json (portable)</div>
|
|
140
|
+
<pre className="max-h-64 overflow-auto text-xs leading-relaxed text-emerald-100">{serialized}</pre>
|
|
141
|
+
</div>
|
|
142
|
+
</section>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
{/* Williams style persona panel */}
|
|
146
|
+
<StylePersonaPanel persona={persona} onReseed={seed => reseedPersona(seed)} />
|
|
147
|
+
|
|
148
|
+
{/* Anchor baseline panel */}
|
|
149
|
+
<AnchorBaselinePanel />
|
|
150
|
+
|
|
151
|
+
{/* Debug events (cross-page) */}
|
|
152
|
+
{settings.showDebugTrace && (
|
|
153
|
+
<section className="rounded-2xl border border-zinc-200 bg-zinc-950 p-4 shadow-sm">
|
|
154
|
+
<div className="mb-2 text-xs font-bold uppercase tracking-wider text-emerald-400">Cross-page debug events (all pages)</div>
|
|
155
|
+
<div className="max-h-48 overflow-y-auto font-mono text-[11px] space-y-0.5">
|
|
156
|
+
{debugEvents.length === 0
|
|
157
|
+
? <div className="text-zinc-500 py-2">No events yet. Run a query in Chat or Dashboard.</div>
|
|
158
|
+
: debugEvents.slice(-60).map((e, i) => <div key={i} className="text-emerald-200">{e}</div>)
|
|
159
|
+
}
|
|
160
|
+
</div>
|
|
161
|
+
</section>
|
|
162
|
+
)}
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function Panel({ title, children }: { title: string; children: ReactNode }) {
|
|
169
|
+
return (
|
|
170
|
+
<div>
|
|
171
|
+
<h2 className="mb-4 text-lg font-bold text-zinc-900">{title}</h2>
|
|
172
|
+
<div className="grid gap-4 sm:grid-cols-2">{children}</div>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
function Select({ label, value, options, onChange }: { label: string; value: string; options: string[]; onChange: (v: string) => void }) {
|
|
177
|
+
return <label className="block text-xs font-semibold text-zinc-600">{label}<select value={value} onChange={e => onChange(e.target.value)} className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm">{options.map(o => <option key={o} value={o}>{o}</option>)}</select></label>;
|
|
178
|
+
}
|
|
179
|
+
function NumberInput({ label, value, min, max, onChange }: { label: string; value: number; min: number; max: number; onChange: (v: number) => void }) {
|
|
180
|
+
return <label className="block text-xs font-semibold text-zinc-600">{label}<input type="number" min={min} max={max} value={value} onChange={e => onChange(Number(e.target.value))} className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm" /></label>;
|
|
181
|
+
}
|
|
182
|
+
function RangeInput({ label, value, min, max, suffix, onChange }: { label: string; value: number; min: number; max: number; suffix: string; onChange: (v: number) => void }) {
|
|
183
|
+
return <label className="block text-xs font-semibold text-zinc-600">{label} {value}{suffix}<input type="range" min={min} max={max} value={value} onChange={e => onChange(Number(e.target.value))} className="mt-2 w-full" /></label>;
|
|
184
|
+
}
|
|
185
|
+
function Toggle({ label, sub, checked, onChange, accent }: { label: string; sub?: string; checked: boolean; onChange: (v: boolean) => void; accent?: boolean }) {
|
|
186
|
+
return (
|
|
187
|
+
<label className={`flex items-start justify-between rounded-xl border px-3 py-2.5 cursor-pointer ${accent && checked ? "border-indigo-300 bg-indigo-50" : "border-zinc-200"}`}>
|
|
188
|
+
<div><div className="text-sm font-semibold text-zinc-700">{label}</div>{sub && <div className="text-[10px] text-zinc-500 mt-0.5">{sub}</div>}</div>
|
|
189
|
+
<input type="checkbox" checked={checked} onChange={e => onChange(e.target.checked)} className="h-4 w-4 rounded mt-0.5 shrink-0" />
|
|
190
|
+
</label>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
function Hint({ text }: { text: string }) {
|
|
194
|
+
return <div className="rounded-xl border border-indigo-100 bg-indigo-50 p-3 text-xs leading-relaxed text-indigo-900">{text}</div>;
|
|
195
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/** V10 Creative Tree of Life — independent animated 3D discovery studio. */
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import {
|
|
4
|
+
CreativeStudio, V10CreativeStore, buildV10DiscoveryContext,
|
|
5
|
+
type CreativeBrief, type CreativeMode, type LifeStage, type NodeRecord, type IdeaCard,
|
|
6
|
+
} from "@/lib/innovation-genome-v10";
|
|
7
|
+
|
|
8
|
+
interface Props { initialDomain?: string; onClose?: () => void; onDirectiveChange?: (d: string) => void; }
|
|
9
|
+
const DOMAINS = ["mathematics","algorithms","software","medicine","legal","physics","chemistry","ml","general"];
|
|
10
|
+
const COLORS: Record<LifeStage, string> = { seed:"#a87945", sprout:"#8bd17c", branch:"#4fbd73", bloom:"#f29ac4", fruit:"#ffd166", compost:"#8d6e63" };
|
|
11
|
+
|
|
12
|
+
function TreeCanvas({ nodes, edges, active, select }: { nodes: NodeRecord[]; edges: Array<{ source_node_id: string; target_node_id: string; relation: string }>; active: string | null; select: (n: NodeRecord) => void }) {
|
|
13
|
+
const positions = useMemo(() => {
|
|
14
|
+
const layers = new Map<number, NodeRecord[]>();
|
|
15
|
+
nodes.forEach(n => layers.set(n.depth, [...(layers.get(n.depth) || []), n]));
|
|
16
|
+
const out = new Map<string, { x: number; y: number; z: number }>();
|
|
17
|
+
for (const [depth, layer] of layers) {
|
|
18
|
+
layer.forEach((n, i) => {
|
|
19
|
+
const spread = Math.max(130, Math.min(680, layer.length * 92));
|
|
20
|
+
const offset = layer.length === 1 ? 0 : i / (layer.length - 1) - 0.5;
|
|
21
|
+
out.set(n.nodeId, { x: 380 + offset * spread, y: 360 - depth * 56 - Math.abs(offset) * 25, z: Math.min(1, depth / 5) });
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}, [nodes]);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<svg viewBox="0 0 760 430" className="h-full w-full" role="img" aria-label="Animated 3D Creative Tree of Life">
|
|
29
|
+
<defs>
|
|
30
|
+
<radialGradient id="v10-ground"><stop offset="0" stopColor="#1b3a2e" /><stop offset="1" stopColor="#07100e" /></radialGradient>
|
|
31
|
+
<linearGradient id="v10-trunk" x1="0" y1="1" x2="0" y2="0"><stop stopColor="#a8784b" /><stop offset=".5" stopColor="#61412c" /><stop offset="1" stopColor="#2b201b" /></linearGradient>
|
|
32
|
+
<filter id="v10-glow"><feGaussianBlur stdDeviation="3" result="b" /><feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge></filter>
|
|
33
|
+
</defs>
|
|
34
|
+
<ellipse cx="380" cy="382" rx="230" ry="28" fill="url(#v10-ground)" />
|
|
35
|
+
<path d="M380 374 C365 320 395 270 380 215" fill="none" stroke="url(#v10-trunk)" strokeWidth="20" strokeLinecap="round" />
|
|
36
|
+
{edges.map((e, i) => {
|
|
37
|
+
const a = positions.get(e.source_node_id), b = positions.get(e.target_node_id);
|
|
38
|
+
if (!a || !b) return null;
|
|
39
|
+
const d = `M ${a.x} ${a.y} Q ${(a.x + b.x) / 2} ${Math.min(a.y, b.y) - 28} ${b.x} ${b.y}`;
|
|
40
|
+
return (
|
|
41
|
+
<g key={`${e.source_node_id}-${e.target_node_id}-${i}`}>
|
|
42
|
+
<path d={d} fill="none" stroke="#315b4b" strokeWidth="7" strokeLinecap="round" opacity=".75" />
|
|
43
|
+
<circle r="4" fill="#f4c86b" filter="url(#v10-glow)">
|
|
44
|
+
<animateMotion dur={`${3 + i % 3}s`} path={d} repeatCount="indefinite" />
|
|
45
|
+
</circle>
|
|
46
|
+
</g>
|
|
47
|
+
);
|
|
48
|
+
})}
|
|
49
|
+
{nodes.map(n => {
|
|
50
|
+
const p = positions.get(n.nodeId) || { x: 380, y: 350, z: 0 };
|
|
51
|
+
const selected = active === n.nodeId;
|
|
52
|
+
const r = n.lifeStage === "seed" ? 18 : n.lifeStage === "fruit" ? 15 : 10 + (1 - p.z) * 3;
|
|
53
|
+
return (
|
|
54
|
+
<g key={n.nodeId} transform={`translate(${p.x} ${p.y})`} onClick={() => select(n)} className="cursor-pointer">
|
|
55
|
+
<ellipse rx={r * 1.6} ry={r * 0.48} cy={r * 0.95} fill="#020504" opacity=".4" />
|
|
56
|
+
<circle r={r + (selected ? 5 : 0)} fill={selected ? "#fff3bc" : COLORS[n.lifeStage]} stroke={selected ? "#fff" : "#10241c"} strokeWidth={selected ? 3 : 2}>
|
|
57
|
+
<animate attributeName="r" values={`${r};${r + 2};${r}`} dur="3s" repeatCount="indefinite" />
|
|
58
|
+
</circle>
|
|
59
|
+
<text y={r + 18} textAnchor="middle" fill="#d7e6df" fontSize="9">{n.title.slice(0, 22)}</text>
|
|
60
|
+
<text y={r + 30} textAnchor="middle" fill="#77968a" fontSize="8">{n.lifeStage}</text>
|
|
61
|
+
</g>
|
|
62
|
+
);
|
|
63
|
+
})}
|
|
64
|
+
</svg>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function CreativeTreeLifePage({ initialDomain = "general", onClose, onDirectiveChange }: Props) {
|
|
69
|
+
const [studio] = useState(() => new CreativeStudio(new V10CreativeStore()));
|
|
70
|
+
const [workspaceId, setWorkspaceId] = useState<string | null>(null);
|
|
71
|
+
const [ver, setVer] = useState(0);
|
|
72
|
+
const [domain, setDomain] = useState(initialDomain);
|
|
73
|
+
const [active, setActive] = useState<NodeRecord | null>(null);
|
|
74
|
+
const [directive, setDirective] = useState("");
|
|
75
|
+
const [angles, setAngles] = useState<string[]>([]);
|
|
76
|
+
const [notice, setNotice] = useState("");
|
|
77
|
+
|
|
78
|
+
const nodes = useMemo(() => workspaceId ? studio.nodes(workspaceId) : [], [workspaceId, ver]);
|
|
79
|
+
const ranking = useMemo(() => workspaceId ? studio.rankIdeas(workspaceId) : [], [workspaceId, ver]);
|
|
80
|
+
const edges = useMemo(() => workspaceId ? studio.edgesFor(workspaceId) : [], [workspaceId, ver]);
|
|
81
|
+
const workspaces = useMemo(() => studio.listWorkspaces(), [ver]);
|
|
82
|
+
|
|
83
|
+
const publish = () => {
|
|
84
|
+
if (!workspaceId) return;
|
|
85
|
+
try {
|
|
86
|
+
const w = studio.workspace(workspaceId);
|
|
87
|
+
const c = buildV10DiscoveryContext((w.brief as CreativeBrief).challenge, (w.brief as CreativeBrief).mode, w.seed as number);
|
|
88
|
+
setDirective(c.directive); setAngles(c.searchAngles);
|
|
89
|
+
(window as any)._VERITAS_V10_DISCOVERY_CONTEXT = c;
|
|
90
|
+
window.dispatchEvent(new CustomEvent("veritas:v10-discovery-context", { detail: c }));
|
|
91
|
+
onDirectiveChange?.(c.directive);
|
|
92
|
+
} catch { /* workspace may not exist yet */ }
|
|
93
|
+
};
|
|
94
|
+
useEffect(publish, [workspaceId, ver]);
|
|
95
|
+
|
|
96
|
+
const mutate = (fn: () => unknown, msg: string) => { try { fn(); setVer(v => v + 1); setNotice(msg); } catch (e) { setNotice(e instanceof Error ? e.message : String(e)); } };
|
|
97
|
+
|
|
98
|
+
const create = () => {
|
|
99
|
+
const brief: CreativeBrief = {
|
|
100
|
+
challenge: `Discover feasible, high-impact directions in ${domain}`,
|
|
101
|
+
mode: "research" as CreativeMode,
|
|
102
|
+
audience: ["independent researcher", "product builder"],
|
|
103
|
+
desiredOutcomes: ["evidence-bound next step", "specific search angle"],
|
|
104
|
+
constraints: ["preserve uncertainty", "locally inspectable"],
|
|
105
|
+
resources: ["retrieved evidence", "scraper results", "human judgment"],
|
|
106
|
+
inspirationDomains: [domain, "scientific instrumentation", "ecology"],
|
|
107
|
+
avoid: ["generic repetition", "unsupported novelty claims"],
|
|
108
|
+
axes: { evidence_strategy: ["primary sources", "counter-evidence", "implementation evidence", "failure evidence"] },
|
|
109
|
+
};
|
|
110
|
+
const id = studio.createWorkspaceSimple("Live Discovery Tree", brief, Date.now());
|
|
111
|
+
setWorkspaceId(id);
|
|
112
|
+
studio.sprout(id, 6);
|
|
113
|
+
studio.burst(id, { count: 10, candidateMultiplier: 4, maximumSimilarity: 0.82, minimumOperatorFamilies: 6 });
|
|
114
|
+
setVer(v => v + 1);
|
|
115
|
+
setNotice("Tree seeded: 6 sprouts + 10 branches");
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<div className="fixed inset-0 z-[10003] overflow-y-auto bg-[#07100e] p-4 text-zinc-100 sm:p-8">
|
|
120
|
+
<div className="mx-auto min-h-full max-w-[1500px] rounded-[28px] border border-emerald-950 bg-[#0a1714] p-5 shadow-2xl sm:p-7" onClick={e => e.stopPropagation()}>
|
|
121
|
+
{/* Header */}
|
|
122
|
+
<header className="flex flex-wrap items-start justify-between gap-4 border-b border-emerald-950 pb-5">
|
|
123
|
+
<div>
|
|
124
|
+
<div className="text-[10px] uppercase tracking-[.3em] text-emerald-400">V10 · offline discovery plane</div>
|
|
125
|
+
<h2 className="mt-1 text-2xl font-black">Creative Tree of Life</h2>
|
|
126
|
+
<p className="mt-1 max-w-2xl text-xs text-emerald-100/60">Animated local graph. Generated branches remain unverified proposals; human judgment controls promotion.</p>
|
|
127
|
+
</div>
|
|
128
|
+
<div className="flex gap-2">
|
|
129
|
+
<button onClick={create} className="rounded-lg bg-emerald-500 px-3 py-2 text-xs font-bold text-emerald-950">New tree</button>
|
|
130
|
+
{onClose && <button onClick={onClose} className="rounded-lg border border-emerald-900 px-3 py-2 text-xs font-bold">Close</button>}
|
|
131
|
+
</div>
|
|
132
|
+
</header>
|
|
133
|
+
|
|
134
|
+
{/* Controls bar */}
|
|
135
|
+
<div className="mt-4 flex flex-wrap items-center gap-3 border-b border-emerald-950 pb-4 text-xs">
|
|
136
|
+
<label className="flex items-center gap-2 text-emerald-100/70">Domain
|
|
137
|
+
<select value={domain} onChange={e => setDomain(e.target.value)} className="rounded-md border border-emerald-800 bg-[#0e211c] px-2 py-1">
|
|
138
|
+
{DOMAINS.map(d => <option key={d}>{d}</option>)}
|
|
139
|
+
</select>
|
|
140
|
+
</label>
|
|
141
|
+
<label className="flex items-center gap-2 text-emerald-100/70">Workspace
|
|
142
|
+
<select value={workspaceId || ""} onChange={e => { setWorkspaceId(e.target.value); setVer(v => v + 1); }} className="max-w-[250px] rounded-md border border-emerald-800 bg-[#0e211c] px-2 py-1">
|
|
143
|
+
<option value="">choose tree</option>
|
|
144
|
+
{workspaces.map((w: any) => <option key={w.workspace_id} value={w.workspace_id}>{w.title}</option>)}
|
|
145
|
+
</select>
|
|
146
|
+
</label>
|
|
147
|
+
{notice && <span className="text-amber-300">{notice}</span>}
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
{!workspaceId ? (
|
|
151
|
+
<div className="grid min-h-[500px] place-items-center text-emerald-100/50">Create new tree to begin offline discovery.</div>
|
|
152
|
+
) : (
|
|
153
|
+
<>
|
|
154
|
+
{/* Main: 3D graph + growth controls */}
|
|
155
|
+
<div className="mt-5 grid gap-5 xl:grid-cols-[1.6fr_.9fr]">
|
|
156
|
+
<section className="rounded-2xl border border-emerald-950 bg-[#08120f] p-3">
|
|
157
|
+
<div className="mb-2 flex justify-between px-2 text-[10px] uppercase tracking-[.22em] text-emerald-400">
|
|
158
|
+
<span>3D living graph · animated flow</span><span>{nodes.length} nodes</span>
|
|
159
|
+
</div>
|
|
160
|
+
<div className="aspect-[16/9]">
|
|
161
|
+
<TreeCanvas nodes={nodes} edges={edges} active={active?.nodeId || null} select={setActive} />
|
|
162
|
+
</div>
|
|
163
|
+
</section>
|
|
164
|
+
|
|
165
|
+
<section className="space-y-4">
|
|
166
|
+
<div className="rounded-2xl border border-emerald-950 bg-[#0d211b] p-4">
|
|
167
|
+
<div className="text-[10px] uppercase tracking-[.22em] text-emerald-400">Growth controls</div>
|
|
168
|
+
<div className="mt-3 grid grid-cols-2 gap-2">
|
|
169
|
+
<button onClick={() => mutate(() => studio.sprout(workspaceId, 6), "6 sprouts added")} className="rounded-lg bg-sky-600 px-3 py-2 text-xs font-bold">Sprout</button>
|
|
170
|
+
<button onClick={() => mutate(() => studio.burst(workspaceId, { count: 8, candidateMultiplier: 4, maximumSimilarity: 0.82, minimumOperatorFamilies: 6 }), "8 branches grown")} className="rounded-lg bg-orange-600 px-3 py-2 text-xs font-bold">Burst</button>
|
|
171
|
+
<button disabled={!active} onClick={() => active && mutate(() => studio.expand(active.nodeId, "resolve bottleneck", 5), "Fractal expansion added")} className="rounded-lg bg-indigo-600 px-3 py-2 text-xs font-bold disabled:opacity-30">Expand</button>
|
|
172
|
+
<button disabled={!active} onClick={() => active && mutate(() => studio.fractalZoom(active.nodeId, 4), "Fractal zoom added")} className="rounded-lg bg-violet-600 px-3 py-2 text-xs font-bold disabled:opacity-30">Zoom</button>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
<div className="rounded-2xl border border-emerald-950 bg-[#0d211b] p-4">
|
|
177
|
+
<div className="text-[10px] uppercase tracking-[.22em] text-emerald-400">Logic + search modifier</div>
|
|
178
|
+
<pre className="mt-3 max-h-44 overflow-auto whitespace-pre-wrap text-[10px] leading-relaxed text-emerald-100/80">{directive || "Create tree to compile directive."}</pre>
|
|
179
|
+
<div className="mt-3 space-y-1">
|
|
180
|
+
{angles.slice(0, 4).map((q, i) => (
|
|
181
|
+
<div key={i} className="rounded-md border border-emerald-900 bg-[#08120f] px-2 py-1 text-[10px] text-amber-200">S{i + 1} · {q}</div>
|
|
182
|
+
))}
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</section>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
{/* Bottom: selected branch + ranking */}
|
|
189
|
+
<div className="mt-5 grid gap-5 xl:grid-cols-[.9fr_1.1fr]">
|
|
190
|
+
<section className="rounded-2xl border border-emerald-950 bg-[#0d211b] p-4">
|
|
191
|
+
<div className="text-[10px] uppercase tracking-[.22em] text-emerald-400">Selected branch</div>
|
|
192
|
+
{active ? (
|
|
193
|
+
<>
|
|
194
|
+
<h3 className="mt-2 text-lg font-bold">{active.title}</h3>
|
|
195
|
+
<div className="mt-1 text-[10px] text-emerald-100/50">
|
|
196
|
+
{active.lifeStage} · {active.status} · novelty {active.localNovelty.toFixed(2)} · cohesion {active.cohesion.toFixed(2)}
|
|
197
|
+
</div>
|
|
198
|
+
<p className="mt-3 text-xs leading-relaxed text-emerald-100/80">
|
|
199
|
+
{(active.body as IdeaCard).thesis || (active.body as Record<string, unknown>).text as string || "Open tree node."}
|
|
200
|
+
</p>
|
|
201
|
+
<div className="mt-4 flex flex-wrap gap-2">
|
|
202
|
+
<button onClick={() => mutate(() => studio.confirm(active.nodeId, "overall", "confirm", 5, "human V10 review"), "Confirmed")} className="rounded-md bg-emerald-600 px-2 py-1 text-[10px] font-bold">Confirm</button>
|
|
203
|
+
<button onClick={() => mutate(() => studio.confirm(active.nodeId, "overall", "reject", 5, "human V10 rejection"), "Rejected and preserved")} className="rounded-md bg-rose-700 px-2 py-1 text-[10px] font-bold">Reject</button>
|
|
204
|
+
<button onClick={() => mutate(() => studio.compost(active.nodeId, "human preserved failure reason"), "Moved to compost")} className="rounded-md bg-stone-600 px-2 py-1 text-[10px] font-bold">Compost</button>
|
|
205
|
+
</div>
|
|
206
|
+
</>
|
|
207
|
+
) : (
|
|
208
|
+
<p className="mt-3 text-xs text-emerald-100/50">Select glowing node in graph.</p>
|
|
209
|
+
)}
|
|
210
|
+
</section>
|
|
211
|
+
|
|
212
|
+
<section className="rounded-2xl border border-emerald-950 bg-[#0d211b] p-4">
|
|
213
|
+
<div className="text-[10px] uppercase tracking-[.22em] text-emerald-400">Advisory ranking + exports</div>
|
|
214
|
+
<div className="mt-3 max-h-52 space-y-1 overflow-auto">
|
|
215
|
+
{ranking.slice(0, 8).map(r => (
|
|
216
|
+
<button key={r.node.nodeId} onClick={() => setActive(r.node)} className="flex w-full items-center justify-between rounded-md border border-emerald-950 bg-[#08120f] px-2 py-1.5 text-left text-[10px] hover:border-emerald-500">
|
|
217
|
+
<span className="truncate">{r.node.title}</span>
|
|
218
|
+
<span className="ml-2 text-amber-300">{r.score.toFixed(2)}</span>
|
|
219
|
+
</button>
|
|
220
|
+
))}
|
|
221
|
+
</div>
|
|
222
|
+
<div className="mt-4 flex flex-wrap gap-2">
|
|
223
|
+
{(["json", "markdown", "mermaid", "terminal"] as const).map(format => (
|
|
224
|
+
<button key={format} onClick={() => workspaceId && navigator.clipboard.writeText(studio.exportWorkspace(workspaceId, format))} className="rounded-md border border-emerald-800 px-2 py-1 text-[10px]">Copy {format}</button>
|
|
225
|
+
))}
|
|
226
|
+
</div>
|
|
227
|
+
</section>
|
|
228
|
+
</div>
|
|
229
|
+
</>
|
|
230
|
+
)}
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
}
|