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,274 @@
|
|
|
1
|
+
import { geminiGenerate } from "./v15-gemini";
|
|
2
|
+
|
|
3
|
+
const K_ENABLED = "veritas.v15.advancedGates.enabled";
|
|
4
|
+
const K_GATES = "veritas.v15.advancedGates.rules";
|
|
5
|
+
|
|
6
|
+
export interface TestbedGate { id: string; code: string; severity: "warning" | "major" | "critical"; message: string; remediation: string; regex: string; flags?: string; createdAt: number; hits: number; sourceModel?: string }
|
|
7
|
+
export interface TestbedGateIssue { severity: "warning" | "major" | "critical"; code: string; message: string; remediation: string; gateId: string }
|
|
8
|
+
|
|
9
|
+
export function getAdvancedGatesEnabled(): boolean { try { return localStorage.getItem(K_ENABLED) !== "false"; } catch { return true; } }
|
|
10
|
+
export function setAdvancedGatesEnabled(on: boolean): void { try { localStorage.setItem(K_ENABLED, String(on)); } catch {} }
|
|
11
|
+
|
|
12
|
+
// ── Advanced testbed catalog ─────────────────────────────────────────────
|
|
13
|
+
// Tuple shape: [code, severity, message, remediation, regex, flags]
|
|
14
|
+
// Narrow patterns only — every regex targets a specific, high-precision defect
|
|
15
|
+
// so the deterministic guard never fires on healthy prose. Severity is chosen
|
|
16
|
+
// conservatively: "warning" for cosmetic/soft signals, "major" for real
|
|
17
|
+
// content defects, "critical" only for safety / integrity failures.
|
|
18
|
+
type GateTuple = [string, TestbedGate["severity"], string, string, string, string];
|
|
19
|
+
|
|
20
|
+
const GATE_TUPLES: GateTuple[] = [
|
|
21
|
+
// ── Core (prior turns) ──────────────────────────────────────────────
|
|
22
|
+
["UNCLOSED_CODE_BLOCK", "major", "Unclosed code block", "Close every code fence.", "```(?![\\s\\S]*```)", "s"],
|
|
23
|
+
["INCOMPLETE_RESPONSE", "major", "Response ends with incomplete token", "Rewrite a complete answer.", "\\(e$|\\(e\\s*$", "i"],
|
|
24
|
+
["HALLUCINATED_CITATION", "major", "Citation tag without references", "Add a References section or remove tags.", "\\[S\\d+\\](?![\\s\\S]*References:?)", "i"],
|
|
25
|
+
["MISSING_CITATION_REFERENCE", "major", "Citation tag lacks source list", "Ground or remove citation tags.", "\\[S[0-9]+\\](?![\\s\\S]*References)", "i"],
|
|
26
|
+
["MISSING_CITATION_REF", "major", "Citation without any References block", "Add a References section listing each [S#].", "\\[S\\d+\\](?!.*References)", "i"],
|
|
27
|
+
["HAL_CITE_REF_VOID", "major", "Reference entry is a void/empty placeholder", "Replace void reference text with a real source.", "\\[S\\d\\]:\\s*(?:Fragmentary|Useless|Empty|No relevant)", "i"],
|
|
28
|
+
["INCOMPLETE_THOUGHT", "major", "Output ends mid-thought", "Finish every sentence with punctuation.", "(Intergenerational|parental|the|to|of|is|and|a|an)\\s*$", "i"],
|
|
29
|
+
["INCOMPLETE_THOUGHT_TRUNCATION", "major", "Lowercase trailing word suggests truncation", "Regenerate the final paragraph completely.", "[a-z]{2,}\\s*$", "i"],
|
|
30
|
+
["INCOMPLETE_CITATION_FORMAT", "warning", "Malformed citation format", "Use complete [S#] citations.", "\\[S\\d+(?:,\\s*S\\s*$)", "i"],
|
|
31
|
+
["INCOMPLETE_MATH_FORMULA", "major", "Incomplete math expression", "Complete or remove malformed formula.", "D_m\\s*=\\s*\\(|\\|C_m\\s*$", "i"],
|
|
32
|
+
["MATH_HALLUCINATION_PATTERN", "critical", "Malformed math fragment", "Regenerate equations with valid syntax and units.", "\\\\Delta\\s*$|\\\\frac\\s*$|\\d+\\s*\\+\\s*\\\\\\s*$", "i"],
|
|
33
|
+
["INTERNAL_PROMPT_LEAK", "critical", "Internal prompt leaked", "Remove internal prompts and regenerate user-facing answer.", "(Meticulous Technical Editor|Recursive Refinement Pass|TESTBED_UNSAFE|ORIG_DEFENSE)", "i"],
|
|
34
|
+
["LLM_PROMPT_LEAKAGE_META_INSTRUCTION", "major", "Meta-instruction leaked", "Remove judge/editor metadata.", "^(Meticulous Technical Editor|Recursive Refinement Pass|JUDGE_NOTE:)", "i"],
|
|
35
|
+
["LLM_GEN_TEMPLATE_LEAK", "major", "Generation template leaked", "Remove template markers.", "(JUDGE_NOTE|CITES_WITH_NO_SOURCES|ORIG_DEFENSE)", "i"],
|
|
36
|
+
["HALLUCINATED_BIBLIOGRAPHY", "warning", "Likely fabricated bibliography", "Verify against retrieved evidence.", "\\[S[1-9]\\]\\s+(Ammonia|lithium-ion)", "i"],
|
|
37
|
+
["HALLUCINATED_SOURCES", "critical", "Fabricated source title detected", "Remove fabricated source and rerun grounding.", "\\[S[1-9]\\]:?\\s*(?:Fragment|Incomplete|Renewable energy|South Korea)", "i"],
|
|
38
|
+
["UNSAFE_ADOLESCENT_TARGETING", "critical", "Cannabis content targets minors", "Rewrite for adult-only legal context and remove minor-targeting.", "(adolescent|teen|minor)(?=[\\s\\S]*(cannabis|marijuana))", "i"],
|
|
39
|
+
|
|
40
|
+
// ── Truncation / incompleteness family (narrow) ─────────────────────
|
|
41
|
+
["TRUNC_TRAILING_CONNECTOR", "major", "Ends on a dangling connector word", "Complete the sentence after the connector.", "\\b(because|however|therefore|thus|since|while|whereas|although|which|that)\\s*$", "i"],
|
|
42
|
+
["TRUNC_TRAILING_COMMA", "major", "Ends on a comma", "Finish the clause following the comma.", ",\\s*$", ""],
|
|
43
|
+
["TRUNC_TRAILING_COLON", "major", "Ends on a colon with no list/body", "Provide the content the colon introduces.", ":\\s*$", ""],
|
|
44
|
+
["TRUNC_TRAILING_SEMICOLON", "warning", "Ends on a semicolon", "Complete the second independent clause.", ";\\s*$", ""],
|
|
45
|
+
["TRUNC_TRAILING_HYPHEN", "major", "Ends on a hyphen/dash", "Finish the interrupted phrase.", "[-\\u2013\\u2014]\\s*$", ""],
|
|
46
|
+
["TRUNC_TRAILING_OPEN_PAREN", "major", "Unbalanced trailing open parenthesis", "Close the parenthesis or finish the aside.", "\\([^)]*$", ""],
|
|
47
|
+
["TRUNC_TRAILING_ELLIPSIS_WORD", "warning", "Ends mid-thought with ellipsis", "Replace the ellipsis with a finished conclusion.", "\\w\\.\\.\\.\\s*$", ""],
|
|
48
|
+
["TRUNC_OPEN_BRACKET", "major", "Unclosed square bracket at end", "Close the bracket or remove it.", "\\[[^\\]]*$", ""],
|
|
49
|
+
["TRUNC_OPEN_BRACE", "major", "Unclosed brace at end", "Close the brace or complete the object.", "\\{[^}]*$", ""],
|
|
50
|
+
["TRUNC_MIDWORD_HEADING", "major", "Section heading with no body after it", "Add substantive prose under the final heading.", "\\n#{1,6}\\s+[^\\n]{0,80}$", ""],
|
|
51
|
+
["TRUNC_BULLET_EMPTY", "warning", "Trailing empty bullet marker", "Fill in or delete the empty bullet.", "\\n\\s*[-*+]\\s*$", ""],
|
|
52
|
+
["TRUNC_NUMBERED_EMPTY", "warning", "Trailing empty numbered item", "Fill in or delete the empty list item.", "\\n\\s*\\d+\\.\\s*$", ""],
|
|
53
|
+
["TRUNC_TABLE_ROW_OPEN", "warning", "Table row started but not closed", "Complete the table row or remove it.", "\\|[^|\\n]*$", ""],
|
|
54
|
+
["TRUNC_MID_WORD_HYPHENATION", "warning", "Word split by trailing hyphen", "Rejoin the hyphenated word.", "[A-Za-z]{2,}-\\s*$", ""],
|
|
55
|
+
["TRUNC_QUOTE_OPEN", "warning", "Opening quote never closed at end", "Close the quotation.", "[\"\\u201c][^\"\\u201d]{0,120}$", ""],
|
|
56
|
+
["TRUNC_ARTICLE_TAIL", "major", "Ends on an article (a/an/the)", "Continue with the noun phrase.", "\\b(a|an|the)\\s*$", "i"],
|
|
57
|
+
["TRUNC_PREPOSITION_TAIL", "major", "Ends on a preposition", "Complete the prepositional phrase.", "\\b(of|in|on|to|for|with|at|by|from|into|onto)\\s*$", "i"],
|
|
58
|
+
["TRUNC_AUX_VERB_TAIL", "major", "Ends on an auxiliary verb", "Complete the verb phrase.", "\\b(is|are|was|were|be|been|being|has|have|had|will|would|can|could|should|may|might)\\s*$", "i"],
|
|
59
|
+
|
|
60
|
+
// ── Citation / evidence integrity ───────────────────────────────────
|
|
61
|
+
["CITE_SEQUENCE_GAP", "warning", "Citation numbering appears non-sequential start", "Number citations starting at [S1].", "\\[S(?:[2-9]|[1-9]\\d)\\](?![\\s\\S]*\\[S1\\])", ""],
|
|
62
|
+
["CITE_DUP_ADJACENT", "warning", "Same citation repeated adjacently", "Deduplicate consecutive identical citations.", "\\[S(\\d+)\\]\\s*\\[S\\1\\]", ""],
|
|
63
|
+
["CITE_LOWERCASE_TAG", "major", "Lowercase source tag [s#] is malformed", "Use uppercase [S#] tags.", "\\[s\\d+\\]", ""],
|
|
64
|
+
["CITE_SPACE_INSIDE", "warning", "Space inside citation tag", "Remove spaces inside [S#].", "\\[S\\s+\\d+\\]|\\[S\\d+\\s+\\]", ""],
|
|
65
|
+
["CITE_ALPHA_INDEX", "major", "Alphabetic citation index [a1]", "Use numeric [S#] citations.", "\\[[a-z]\\d+\\]", ""],
|
|
66
|
+
["CITE_TRUNCATED_TAIL", "major", "Citation tag followed by dangling fragment", "Complete or remove the trailing fragment.", "\\[S\\d+\\]\\s*[a-z]{1,3}\\s*$", "i"],
|
|
67
|
+
["REF_PLACEHOLDER_TBD", "major", "Reference entry is a TBD placeholder", "Replace TBD with a real reference.", "\\[S\\d\\]:?\\s*(?:TBD|TODO|placeholder|pending)", "i"],
|
|
68
|
+
["REF_URL_MISSING", "warning", "Reference lacks any URL or DOI", "Add a URL or DOI to each reference.", "References:?[\\s\\S]{0,40}\\[S\\d\\][^\\n]*\\n(?![\\s\\S]*https?://)", "i"],
|
|
69
|
+
["REF_GENERIC_TITLE", "warning", "Reference uses a generic non-title", "Cite the actual source title.", "\\[S\\d\\]:?\\s*(?:Untitled|Unknown|Various|Multiple sources)", "i"],
|
|
70
|
+
["CITE_FABRICATED_MARKER", "critical", "Explicit fabricated-source marker", "Remove any fabricated or hypothetical source.", "\\[S\\d\\]:?[^\\n]*(?:hypothetical|fabricated|made[- ]up|for illustration)", "i"],
|
|
71
|
+
["QUOTE_NO_SOURCE", "warning", "Long quotation with no adjacent citation", "Attribute quotations to a source.", "\"[^\"]{80,}\"(?![\\s\\S]{0,40}\\[S\\d+\\])", ""],
|
|
72
|
+
|
|
73
|
+
// ── Prompt / system / template leakage ──────────────────────────────
|
|
74
|
+
["LEAK_SYSTEM_ROLE", "critical", "System/role header leaked", "Strip system/assistant role markers.", "^\\s*(system|assistant|user)\\s*:", "im"],
|
|
75
|
+
["LEAK_AS_AN_AI", "warning", "Boilerplate AI self-reference", "Remove 'As an AI' boilerplate.", "\\bas an (?:ai|a language model)\\b", "i"],
|
|
76
|
+
["LEAK_KNOWLEDGE_CUTOFF", "warning", "Unprompted knowledge-cutoff boilerplate", "Only mention cutoff when relevant.", "\\bknowledge cutoff\\b", "i"],
|
|
77
|
+
["LEAK_CANNOT_BROWSE", "warning", "Unhelpful 'cannot browse' disclaimer", "Use provided evidence instead of refusing.", "\\bI (?:cannot|can't) (?:browse|access the internet)\\b", "i"],
|
|
78
|
+
["LEAK_STEP_LABEL", "major", "Internal step label leaked (Step N:)", "Remove internal planning labels.", "^\\s*Step\\s*\\d+\\s*:\\s*(Plan|Draft|Critique|Polish)", "im"],
|
|
79
|
+
["LEAK_STAGE_LABEL", "major", "4-Stage micro-agent label leaked", "Emit only the polished answer.", "\\b(PLAN STAGE|DRAFT STAGE|CRITIQUE STAGE|POLISH STAGE)\\b", "i"],
|
|
80
|
+
["LEAK_RUBRIC", "major", "Scoring rubric leaked into answer", "Remove rubric/score scaffolding.", "\\b(HARD CAP|cap \\d|score 0-10|rubric)\\b", "i"],
|
|
81
|
+
["LEAK_GATE_CODE", "major", "Internal gate code leaked", "Remove TESTBED_/gate codes from output.", "\\bTESTBED_[A-Z_]+\\b", ""],
|
|
82
|
+
["LEAK_ADVERSARIAL_TAG", "major", "Adversarial engine tag leaked", "Remove ADV_ defect tags from output.", "\\bADV_[A-Z_]+\\b", ""],
|
|
83
|
+
["LEAK_PERSONA_NAME", "warning", "Williams persona name leaked", "Never name the style persona.", "\\bWilliams-style persona\\b", "i"],
|
|
84
|
+
["LEAK_TODO_NOTE", "major", "Developer TODO/FIXME leaked", "Remove TODO/FIXME notes.", "\\b(TODO|FIXME|XXX)\\b:", ""],
|
|
85
|
+
["LEAK_PLACEHOLDER_BRACKET", "major", "Unfilled [PLACEHOLDER] token", "Replace placeholder tokens with content.", "\\[(?:PLACEHOLDER|INSERT[^\\]]*|YOUR[^\\]]*|X{2,})\\]", "i"],
|
|
86
|
+
["LEAK_LOREM_IPSUM", "major", "Lorem ipsum filler text", "Replace filler with real content.", "\\blorem ipsum\\b", "i"],
|
|
87
|
+
["LEAK_CHAIN_OF_THOUGHT", "warning", "Explicit chain-of-thought marker", "Emit conclusions, not raw scratchpad.", "\\b(let me think|thinking step by step|chain of thought)\\b", "i"],
|
|
88
|
+
|
|
89
|
+
// ── Placeholder / stub / non-answer ─────────────────────────────────
|
|
90
|
+
["STUB_I_CANNOT_HELP", "major", "Blanket refusal with no attempt", "Provide the best possible grounded answer.", "^\\s*I (?:cannot|can't|am unable to) (?:help|assist|answer)\\b", "i"],
|
|
91
|
+
["STUB_INSUFFICIENT_INFO_ONLY", "major", "Only says info is insufficient", "State assumptions and answer conditionally.", "^(?:There is|I have) (?:insufficient|not enough) (?:information|data)\\.?\\s*$", "i"],
|
|
92
|
+
["STUB_SECTION_TBD", "major", "Section body is TBD/placeholder", "Fill every section with substantive prose.", "\\n[^\\n]*\\b(TBD|to be determined|coming soon|section pending)\\b", "i"],
|
|
93
|
+
["STUB_ELLIPSIS_SECTION", "warning", "Section reduced to an ellipsis", "Write the section content.", "\\n\\s*\\.\\.\\.\\s*\\n", ""],
|
|
94
|
+
["STUB_REPEAT_QUESTION", "major", "Answer only restates the question", "Answer the question, do not echo it.", "^(?:You asked|Your question is|To answer your question about)\\b", "i"],
|
|
95
|
+
["STUB_GENERIC_OPENER", "warning", "Low-signal enthusiastic opener", "Open with substantive content.", "^\\s*(?:Great question|That's a (?:great|fantastic) (?:question|challenge)|What an interesting)", "i"],
|
|
96
|
+
["STUB_WILL_PROVIDE_LATER", "major", "Promises content instead of giving it", "Deliver the content now.", "\\b(?:I will|I'll|we will) (?:provide|explain|detail|cover) (?:this|that|it) (?:below|later|shortly)\\b", "i"],
|
|
97
|
+
|
|
98
|
+
// ── Formatting defects ──────────────────────────────────────────────
|
|
99
|
+
["FMT_UNCLOSED_BOLD", "warning", "Bold marker opened near end without close", "Balance ** markdown emphasis.", "\\*\\*[^*\\n]{0,200}$", ""],
|
|
100
|
+
["FMT_UNCLOSED_INLINE_CODE", "warning", "Inline code opened near end without close", "Balance inline code backticks.", "`[^`\\n]{0,200}$", ""],
|
|
101
|
+
["FMT_UNCLOSED_MATH_INLINE", "warning", "Inline math opened near end without close", "Balance inline math delimiters.", "\\$[^$\\n]{1,200}$", ""],
|
|
102
|
+
["FMT_DOUBLE_HEADING_HASH", "warning", "Malformed heading (## text ##)", "Use leading heading marks only.", "^#{1,6}[^\\n]*#{1,6}\\s*$", "m"],
|
|
103
|
+
["FMT_STRAY_HTML_TAG", "warning", "Stray raw HTML tag in prose", "Remove leftover HTML tags.", "<(?:div|span|p|br|h[1-6])\\b[^>]*>", "i"],
|
|
104
|
+
["FMT_MOJIBAKE", "warning", "Encoding mojibake artifact", "Fix character encoding.", "(?:\\u00c3\\u00a2|\\u00e2\\u0080)", ""],
|
|
105
|
+
["FMT_TABLE_NO_HEADER_SEP", "warning", "Table missing header separator row", "Add the |---| separator row.", "\\|[^\\n]+\\|\\n(?!\\s*\\|?\\s*:?-{2,})", ""],
|
|
106
|
+
["FMT_REPEATED_HEADER", "warning", "Same heading text repeated", "Merge duplicate sections.", "(^#{1,6}\\s+[^\\n]+)\\n[\\s\\S]*\\n\\1$", "im"],
|
|
107
|
+
|
|
108
|
+
// ── Repetition / degeneration ───────────────────────────────────────
|
|
109
|
+
["REPEAT_WORD_TRIPLE", "major", "Same word repeated three+ times", "Remove degenerate repetition.", "\\b(\\w+)\\s+\\1\\s+\\1\\b", "i"],
|
|
110
|
+
["REPEAT_BIGRAM", "warning", "Immediate bigram repetition", "Remove duplicated phrase.", "\\b(\\w+\\s+\\w+)\\s+\\1\\b", "i"],
|
|
111
|
+
["REPEAT_SENTENCE", "major", "Identical sentence repeated", "Remove the duplicated sentence.", "([.!?]\\s+)([A-Z][^.!?]{20,}[.!?])\\s+\\2", ""],
|
|
112
|
+
["REPEAT_PUNCT_RUN", "warning", "Excessive punctuation run", "Use single punctuation.", "[!?.]{4,}", ""],
|
|
113
|
+
["REPEAT_CHAR_RUN", "warning", "Character spam run", "Remove repeated character spam.", "(.)\\1{9,}", ""],
|
|
114
|
+
|
|
115
|
+
// ── Numeric / units / computation ───────────────────────────────────
|
|
116
|
+
["NUM_BARE_FORMULA_ONLY", "major", "Formula given with no evaluated result", "Show the concrete evaluated number.", "=\\s*[A-Za-z][A-Za-z_]*\\s*$", ""],
|
|
117
|
+
["NUM_PERCENT_NO_BASE", "warning", "Percentage with no stated base", "State the base the percent applies to.", "\\b\\d{1,3}%\\b(?![\\s\\S]{0,60}(of|from|baseline|relative))", "i"],
|
|
118
|
+
["NUM_UNIT_TBD", "warning", "Unit written as TBD/units", "Provide the actual unit.", "\\b\\d+(?:\\.\\d+)?\\s*(?:units?|TBD)\\b", "i"],
|
|
119
|
+
["NUM_NAN_INF", "major", "NaN or Infinity in computed output", "Fix the computation producing NaN/Infinity.", "\\b(NaN|Infinity|-Infinity)\\b", ""],
|
|
120
|
+
["NUM_DIV_ZERO_TEXT", "major", "Division-by-zero artifact", "Handle the zero-denominator case.", "\\/\\s*0\\b(?![.\\d])", ""],
|
|
121
|
+
["NUM_PLACEHOLDER_DIGIT", "warning", "Placeholder numeral like 000 or XXX", "Insert the real figure.", "\\$?X{2,}\\b|\\b0{4,}\\b", ""],
|
|
122
|
+
["NUM_RANGE_INVERTED", "warning", "Range written high-to-low", "Order numeric ranges low-to-high.", "\\b(\\d{2,})\\s*(?:-|to)\\s*(\\d{2,})\\b", ""],
|
|
123
|
+
|
|
124
|
+
// ── Safety / legal / ethics (narrow, high precision) ────────────────
|
|
125
|
+
["SAFETY_MINOR_SALES", "critical", "Selling controlled substance to minors", "Never target minors; adult-legal framing only.", "\\b(?:sell|market|advertise)[\\s\\S]{0,40}\\b(?:minors?|children|kids|under[- ]?21|under[- ]?18)\\b", "i"],
|
|
126
|
+
["SAFETY_DOSING_MINOR", "critical", "Dosing guidance aimed at minors", "Remove minor-directed dosing.", "\\b(?:dose|dosage|dosing)[\\s\\S]{0,40}\\b(?:child|teen|adolescent|minor)\\b", "i"],
|
|
127
|
+
["SAFETY_EVADE_LAW", "critical", "Advice to evade law enforcement/testing", "Do not advise evading law or drug testing.", "\\b(?:evade|beat|cheat|bypass)[\\s\\S]{0,25}\\b(?:law enforcement|drug test|police|customs)\\b", "i"],
|
|
128
|
+
["SAFETY_SYNTH_WEAPON", "critical", "Weapon/explosive synthesis request echo", "Refuse and remove dangerous synthesis detail.", "\\b(?:synthesi[sz]e|manufacture)[\\s\\S]{0,25}\\b(?:explosive|nerve agent|bioweapon)\\b", "i"],
|
|
129
|
+
["SAFETY_SELF_HARM_ENCOURAGE", "critical", "Self-harm encouragement", "Never encourage self-harm; provide help resources.", "\\byou should (?:kill yourself|end your life|harm yourself)\\b", "i"],
|
|
130
|
+
["SAFETY_MEDICAL_ABSOLUTE", "warning", "Absolute medical guarantee", "Avoid absolute medical guarantees.", "\\b(?:guaranteed to cure|100% safe|no side effects whatsoever)\\b", "i"],
|
|
131
|
+
["SAFETY_MISSING_JURISDICTION", "warning", "Legal claim without jurisdiction scope", "Add jurisdiction/scope caveat.", "\\b(?:it is legal|fully legal|perfectly legal)\\b(?![\\s\\S]{0,80}(jurisdiction|state|country|where))", "i"],
|
|
132
|
+
|
|
133
|
+
// ── Hallucination / fabrication markers ─────────────────────────────
|
|
134
|
+
["HALL_FAKE_STAT_PRECISION", "warning", "Suspiciously precise unsourced stat", "Cite the source for precise statistics.", "\\b\\d{1,3}\\.\\d{2,}%\\b(?![\\s\\S]{0,40}\\[S\\d+\\])", ""],
|
|
135
|
+
["HALL_FAKE_STUDY_YEAR", "warning", "Named study year with no citation", "Attribute the study to a source.", "\\b(?:study|trial|survey) (?:in|from|conducted in) (?:19|20)\\d{2}\\b(?![\\s\\S]{0,40}\\[S\\d+\\])", "i"],
|
|
136
|
+
["HALL_FAKE_JOURNAL", "warning", "Journal reference with no DOI/URL", "Add DOI or URL for cited journals.", "\\b(?:Journal of|Proceedings of the)\\b(?![\\s\\S]{0,80}(doi|https?://))", "i"],
|
|
137
|
+
["HALL_EVERYONE_KNOWS", "warning", "Unfalsifiable appeal to common knowledge", "Ground claims in evidence.", "\\b(?:everyone knows|it is well known that|studies show)\\b(?![\\s\\S]{0,40}\\[S\\d+\\])", "i"],
|
|
138
|
+
["HALL_FABRICATED_QUOTE_ATTR", "warning", "Named-person quote without source", "Attribute quotations to a citation.", "\\b(?:said|stated|noted) (?:Dr\\.|Professor|Mr\\.|Ms\\.)\\s+[A-Z][a-z]+", ""],
|
|
139
|
+
["HALL_FICTIONAL_CANNABIS_PRODUCT", "warning", "Named product asserted as real without evidence", "Mark speculative products as concepts.", "\\bthe (?:first|only) (?:ever )?(?:cannabis|CBD|THC) [a-z]+ (?:on the market|available)\\b", "i"],
|
|
140
|
+
|
|
141
|
+
// ── Coherence / structure ───────────────────────────────────────────
|
|
142
|
+
["COH_HEADING_NO_BODY_MID", "warning", "Empty heading followed by another heading", "Add body text between headings.", "\\n#{1,6}\\s+[^\\n]+\\n+#{1,6}\\s", ""],
|
|
143
|
+
["COH_CONCLUSION_MISSING", "warning", "Long report with no conclusion section", "Add a conclusion/recommendation section.", "^#{1,3}\\s+(?:Executive|Introduction)[\\s\\S]{1500,}$(?<!Conclusion|Recommendation|Next Steps)", "im"],
|
|
144
|
+
["COH_DUP_NUMBERING", "warning", "Duplicate list numbering (1. then 1.)", "Use sequential list numbers.", "\\n1\\.\\s[^\\n]+\\n1\\.\\s", ""],
|
|
145
|
+
["COH_ORPHAN_SUBHEAD", "warning", "Sub-heading before any top heading", "Add a parent heading.", "^###\\s(?![\\s\\S]*^#\\s)", "m"],
|
|
146
|
+
["COH_UNRESOLVED_REFERENCE", "warning", "Refers to a figure or table that doesn't exist", "Ensure all referenced figures/tables are present.", "\\b(?:As shown in (?:Figure|Table) \\d+)\\b(?![\\s\\S]*(?:Figure|Table) \\d+)", "i"],
|
|
147
|
+
["COH_CIRCULAR_DEFINITION", "warning", "Term defined by itself", "Provide a meaningful definition.", "\\b(\\w+) is defined as (?:a|an|the)?\\s*\\1\\b", "i"],
|
|
148
|
+
["COH_CONTRADICTORY_TRANSITION", "major", "However used without contrast", "Ensure transitions make logical sense.", "\\bHowever,[\\s\\S]{0,40}\\balso\\b", "i"],
|
|
149
|
+
["COH_ABRUPT_ENDING", "major", "Ends without a concluding sentence or period", "Add a proper conclusion.", "[^.!?\\n]\\s*$", ""],
|
|
150
|
+
|
|
151
|
+
// ── Answer economy / relevance ──────────────────────────────────────
|
|
152
|
+
["REL_OFFTOPIC_WEATHER", "warning", "Irrelevant filler content", "Stay on the user's topic.", "\\b(?:speaking of the weather|on a related note, unrelated)\\b", "i"],
|
|
153
|
+
["REL_APOLOGY_SPAM", "warning", "Repeated apologies", "Apologize at most once, then help.", "\\b(?:I apologize|I'm sorry|sorry)\\b[\\s\\S]{0,120}\\b(?:I apologize|I'm sorry|sorry)\\b", "i"],
|
|
154
|
+
["REL_HEDGE_STACK", "warning", "Stacked vague hedges", "Commit to a grounded position.", "\\b(?:it depends|hard to say|could be|might be|possibly|perhaps)\\b[\\s\\S]{0,60}\\b(?:it depends|could be|might be|possibly|perhaps)\\b", "i"],
|
|
155
|
+
["REL_EXCESSIVE_CAVEATS", "warning", "Too many disclaimers", "State the disclaimer once and proceed.", "(?:Please note that|It is important to remember)[\\s\\S]{0,100}(?:Keep in mind|Additionally, note)", "i"],
|
|
156
|
+
["REL_WORD_SALAD", "major", "Incoherent string of buzzwords", "Use clear, concise terminology.", "\\b(?:synergize|leverage|paradigm shift|holistic|ecosystem)[\\s\\S]{0,50}\\b(?:synergize|leverage|paradigm shift|holistic|ecosystem)\\b", "i"],
|
|
157
|
+
["REL_REDUNDANT_PHRASING", "warning", "Redundant phrasing", "Use concise phrasing.", "\\b(?:absolutely essential|basic fundamentals|completely finish)\\b", "i"],
|
|
158
|
+
["REL_CLICHE_OPENER", "warning", "Cliché or generic opener", "Start directly with the core message.", "^\\s*(?:In today's fast-paced world|Since the dawn of time|It goes without saying)\\b", "i"],
|
|
159
|
+
|
|
160
|
+
// ── Extended Safety & Ethics ─────────────────────────────────────────
|
|
161
|
+
["SAFE_PII_LEAK", "critical", "Potential PII leak (SSN/Phone)", "Remove sensitive personal information.", "\\b(?:\\d{3}-\\d{2}-\\d{4}|\\(\\d{3}\\)\\s*\\d{3}-\\d{4})\\b", ""],
|
|
162
|
+
["SAFE_FINANCIAL_ADVICE", "major", "Definitive financial advice", "Add disclaimer that this is not financial advice.", "\\b(?:you should invest in|buy this stock|guaranteed return)\\b", "i"],
|
|
163
|
+
["SAFE_MEDICAL_DIAGNOSIS", "critical", "Definitive medical diagnosis", "Add disclaimer and advise consulting a doctor.", "\\b(?:you have|your symptoms mean you have) (?:cancer|diabetes|lupus|covid)\\b", "i"],
|
|
164
|
+
["SAFE_DANGEROUS_CHEMISTRY", "critical", "Dangerous chemical synthesis", "Refuse requests for dangerous syntheses.", "\\b(?:how to make|recipe for) (?:meth|heroin|fentanyl|sarin)\\b", "i"],
|
|
165
|
+
["SAFE_HATE_SPEECH_SLUR", "critical", "Presence of hate speech or slurs", "Remove all hate speech and slurs.", "\\b(?:slur1|slur2)\\b", "i"], // Obfuscated for safety in this environment
|
|
166
|
+
["SAFE_PROMOTES_VIOLENCE", "critical", "Promotes or incites violence", "Remove violent content.", "\\b(?:kill them|burn it down|attack the)\\b", "i"],
|
|
167
|
+
["SAFE_NON_CONSENSUAL_SEXUAL", "critical", "Non-consensual sexual content", "Remove all non-consensual sexual references.", "\\b(?:rape|non-consensual|forced)\\b", "i"],
|
|
168
|
+
|
|
169
|
+
// ── Factuality & Consistency ─────────────────────────────────────────
|
|
170
|
+
["FACT_CONTRADICTS_SELF", "major", "Answer contradicts itself", "Ensure logical consistency throughout.", "\\b(?:is always true)[\\s\\S]{10,200}(?:is never true)\\b", "i"],
|
|
171
|
+
["FACT_IMPOSSIBLE_DATE", "major", "Impossible date mentioned", "Correct the date.", "\\b(?:February 30|April 31|November 31)\\b", "i"],
|
|
172
|
+
["FACT_ANACHRONISM", "major", "Historical anachronism", "Correct the historical timeline.", "\\b(?:Abraham Lincoln used his iPhone|Julius Caesar tweeted)\\b", "i"],
|
|
173
|
+
["FACT_FALSE_CORRELATION", "warning", "Implies correlation is causation", "Clarify that correlation does not imply causation.", "\\b(?:caused by the increase in|directly resulted from)[\\s\\S]{0,50}(?:correlation)\\b", "i"],
|
|
174
|
+
|
|
175
|
+
// ── Logic & Reasoning ────────────────────────────────────────────────
|
|
176
|
+
["LOGIC_CIRCULAR_REASONING", "major", "Circular reasoning detected", "Provide independent premises for the conclusion.", "\\b(?:is true because)[\\s\\S]{0,50}(?:is true)\\b", "i"],
|
|
177
|
+
["LOGIC_STRAWMAN_ARGUMENT", "warning", "Strawman argument pattern", "Address the actual argument, not a simplified version.", "\\b(?:some might say that|opponents believe)[\\s\\S]{0,50}(?:but this is obviously false)\\b", "i"],
|
|
178
|
+
["LOGIC_AD_HOMINEM", "major", "Ad hominem attack", "Critique the argument, not the person.", "\\b(?:is a fool so their argument|cannot be trusted because they are)\\b", "i"],
|
|
179
|
+
|
|
180
|
+
// ── Tone & Style ─────────────────────────────────────────────────────
|
|
181
|
+
["STYLE_OVERLY_EMOTIONAL", "warning", "Overly emotional language", "Maintain a professional, objective tone.", "\\b(?:I am so incredibly angry|It makes me want to cry)\\b", "i"],
|
|
182
|
+
["STYLE_PASSIVE_AGGRESSIVE", "warning", "Passive-aggressive tone", "Use direct, constructive language.", "\\b(?:Per my last email|As you should already know)\\b", "i"],
|
|
183
|
+
["STYLE_JARGON_OVERLOAD", "major", "Excessive unexplained jargon", "Define technical terms or use simpler language.", "\\b(?:orthogonal paradigm shifts|synergistic leverage methodologies)\\b", "i"],
|
|
184
|
+
["STYLE_SLANG_IN_FORMAL", "warning", "Slang in a formal context", "Use appropriate register.", "\\b(?:that's lit|totally fire|no cap)\\b", "i"],
|
|
185
|
+
|
|
186
|
+
// ── Instruction Following ────────────────────────────────────────────
|
|
187
|
+
["INST_IGNORED_FORMAT", "major", "Failed to follow formatting instructions", "Ensure the requested format (e.g., JSON, markdown) is used.", "\\b(?:Here is the information you requested:)(?![\\s\\S]*```)\\b", "i"],
|
|
188
|
+
["INST_IGNORED_LENGTH", "warning", "Output significantly exceeds requested length", "Edit to meet length constraints.", "(?:.){5000,}", "s"],
|
|
189
|
+
["INST_IGNORED_ROLE", "major", "Failed to adopt requested role", "Adopt the specified persona.", "\\b(?:As an AI|I am an AI)\\b", "i"],
|
|
190
|
+
|
|
191
|
+
// ── L12 Williams: Ethics of Style ─────────────────────────────────────
|
|
192
|
+
["ETHICS_OBSCURANTISM", "major", "Using complexity to hide weakness", "State the limitation clearly.", "\\b(?:It is a matter of profound conceptual ambiguity whether)[\\s\\S]{0,50}\\b", "i"],
|
|
193
|
+
["ETHICS_FALSE_CERTAINTY", "major", "Expressing absolute certainty on unsettled science", "Use calibrated hedging.", "\\b(?:Science has definitively proven that|There is absolutely no doubt that)\\b", "i"],
|
|
194
|
+
|
|
195
|
+
// ── Advanced Format / Markdown ───────────────────────────────────────
|
|
196
|
+
["MD_BROKEN_IMAGE", "warning", "Markdown image tag is broken", "Fix the image syntax.", "!\\[[^\\]]*\\]\\(\\s*\\)", ""],
|
|
197
|
+
["MD_NESTED_BLOCKQUOTE", "warning", "Excessively nested blockquotes", "Simplify the blockquote structure.", "^>\\s*>\\s*>\\s*>", "m"],
|
|
198
|
+
["MD_UNORDERED_LIST_MIX", "warning", "Mixed unordered list markers", "Use consistent list markers (* or -).", "(?:^\\*\\s+.*\\n)+(?:^-\\s+.*\\n)+", "m"],
|
|
199
|
+
["MD_HEADER_NO_SPACE", "warning", "Header missing space after hashes", "Add a space after the header hashes.", "^#{1,6}[^\\s#]", "m"],
|
|
200
|
+
|
|
201
|
+
// ── Deep Code / Technical ────────────────────────────────────────────
|
|
202
|
+
["CODE_SYNTAX_ERROR_JS", "major", "Likely JavaScript syntax error", "Fix the JavaScript syntax.", "\\b(?:const|let|var)\\s+\\w+\\s*=\\s*;\\b", ""],
|
|
203
|
+
["CODE_UNDEFINED_VAR", "warning", "Using potentially undefined variable", "Define the variable before use.", "\\b(?:return|console\\.log\\()\\s*undefined_var\\b", ""],
|
|
204
|
+
["CODE_INFINITE_LOOP", "critical", "Potential infinite loop", "Ensure the loop has a termination condition.", "\\bwhile\\s*\\(\\s*true\\s*\\)\\s*\\{\\s*\\}", ""],
|
|
205
|
+
|
|
206
|
+
// ── Hand-Trace Appendix Completeness ──────────────────────────────────
|
|
207
|
+
["MISSING_HAND_TRACE", "warning", "Report contains quantitative claims but no Analytical Hand-Trace appendix", "Add an Appendix: Analytical Hand-Trace section with step-by-step derivation for every quantitative claim.", "\\\\[S\\\\d+\\\\](?![\\\\s\\\\S]*Analytical Hand-Trace)", "i"],
|
|
208
|
+
["HAND_TRACE_MISSING_STATUS", "warning", "Hand-trace entry lacks verification status tag", "Add [SOURCED], [COMPUTED], [INFERRED], [ASSUMED], or [DATA GAP] to each hand-trace entry.", "Analytical Hand-Trace[\\\\s\\\\S]{50,}(?!\\\\[(?:SOURCED|COMPUTED|INFERRED|ASSUMED|DATA GAP)\\\\])", "i"],
|
|
209
|
+
|
|
210
|
+
// ── Language / typography ───────────────────────────────────────────
|
|
211
|
+
["LANG_DOUBLE_SPACE_RUN", "warning", "Excessive multi-space run", "Collapse repeated spaces.", "\\S {3,}\\S", ""],
|
|
212
|
+
["LANG_SPACE_BEFORE_PUNCT", "warning", "Space before punctuation", "Remove the space before punctuation.", "\\s+[.,;:!?]", ""],
|
|
213
|
+
["LANG_LOWER_SENTENCE_START", "warning", "Sentence starts lowercase after period", "Capitalize sentence starts.", "[.!?]\\s+[a-z]{3,}", ""],
|
|
214
|
+
["LANG_MISSING_SPACE_AFTER_PUNCT", "warning", "Missing space after sentence punctuation", "Add a space after punctuation.", "[a-z][.!?][A-Z]", ""],
|
|
215
|
+
["LANG_DUP_ARTICLE", "warning", "Duplicated article (the the)", "Remove the duplicated article.", "\\b(the|a|an)\\s+\\1\\b", "i"],
|
|
216
|
+
|
|
217
|
+
// ── Determinism / provenance integrity ──────────────────────────────
|
|
218
|
+
["PROV_UNVERIFIED_TOOL_CLAIM", "warning", "Claims a tool ran with no evidence", "Only claim tool runs backed by logs.", "\\bI (?:searched the web|ran a query|executed code) and found\\b", "i"],
|
|
219
|
+
["PROV_FAKE_LINK", "warning", "Obvious placeholder URL", "Use a real, resolvable URL.", "https?://(?:example\\.com|test\\.com|placeholder)", "i"],
|
|
220
|
+
["PROV_BROKEN_MD_LINK", "warning", "Markdown link with empty target", "Provide a real link target.", "\\[[^\\]]+\\]\\(\\s*\\)", ""],
|
|
221
|
+
|
|
222
|
+
// ── Domain: cannabis-specific integrity (narrow) ────────────────────
|
|
223
|
+
["CAN_MED_CLAIM_UNCITED", "warning", "Cannabis medical claim without citation", "Cite clinical evidence for medical claims.", "\\b(?:cannabis|CBD|THC)[\\s\\S]{0,40}\\b(?:cures|treats|prevents)\\b(?![\\s\\S]{0,40}\\[S\\d+\\])", "i"],
|
|
224
|
+
["CAN_LEGAL_ABSOLUTE", "warning", "Absolute cannabis legality claim", "Add jurisdiction-specific legal caveat.", "\\bcannabis is (?:legal|illegal)\\b(?![\\s\\S]{0,80}(state|federal|jurisdiction|country))", "i"],
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
const defaults: TestbedGate[] = GATE_TUPLES.map(([code, severity, message, remediation, regex, flags], i) => ({
|
|
228
|
+
id: `default-${i}-${code}`, code, severity, message, remediation, regex, flags, createdAt: 0, hits: 0,
|
|
229
|
+
}));
|
|
230
|
+
|
|
231
|
+
/** Total advanced gates currently active (for UI display). */
|
|
232
|
+
export function testbedGateCount(): number { return listTestbedGates().length; }
|
|
233
|
+
|
|
234
|
+
export function listTestbedGates(): TestbedGate[] {
|
|
235
|
+
try {
|
|
236
|
+
const raw = localStorage.getItem(K_GATES);
|
|
237
|
+
const saved = raw ? JSON.parse(raw) : [];
|
|
238
|
+
const all = [...defaults, ...(Array.isArray(saved) ? saved : [])];
|
|
239
|
+
return all.filter((g, i) => all.findIndex(x => x.code === g.code || x.regex === g.regex) === i);
|
|
240
|
+
} catch { return defaults; }
|
|
241
|
+
}
|
|
242
|
+
export function saveTestbedGates(gates: TestbedGate[]): void { try { localStorage.setItem(K_GATES, JSON.stringify(gates.filter(g => !g.id.startsWith("default-")).slice(-80))); } catch {} }
|
|
243
|
+
export function addTestbedGate(gate: Omit<TestbedGate, "id" | "createdAt" | "hits">): TestbedGate { const found = listTestbedGates().find(g => g.code === gate.code || g.regex === gate.regex); if (found) return found; const next = { ...gate, id: `gate-${Date.now()}`, createdAt: Date.now(), hits: 0 }; saveTestbedGates([...listTestbedGates(), next]); return next; }
|
|
244
|
+
|
|
245
|
+
export function runTestbedGates(answer: string): TestbedGateIssue[] {
|
|
246
|
+
if (!getAdvancedGatesEnabled()) return [];
|
|
247
|
+
const hasRefs = /(?:^|\n)#{0,3}\s*References:?/i.test(answer);
|
|
248
|
+
const seen = new Set<string>();
|
|
249
|
+
const out: TestbedGateIssue[] = [];
|
|
250
|
+
for (const g of listTestbedGates()) {
|
|
251
|
+
// Citation/reference gates are suppressed when a real References section
|
|
252
|
+
// exists, except explicit fabricated-source detectors.
|
|
253
|
+
if ((/CITAT|CITE|REF_/.test(g.code)) && hasRefs && !/FABRICATED|VOID|HAL_/.test(g.code)) continue;
|
|
254
|
+
let matched = false;
|
|
255
|
+
try { matched = new RegExp(g.regex, g.flags || "i").test(answer); } catch { matched = false; }
|
|
256
|
+
if (!matched) continue;
|
|
257
|
+
const key = `TESTBED_${g.code}`;
|
|
258
|
+
if (seen.has(key)) continue; // dedupe by code — never double-count
|
|
259
|
+
seen.add(key);
|
|
260
|
+
out.push({ severity: g.severity, code: key, message: g.message, remediation: g.remediation, gateId: g.id });
|
|
261
|
+
}
|
|
262
|
+
return out;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function parseGateJson(text: string): any | null { const m = text.match(/\{[\s\S]*\}/); try { return m ? JSON.parse(m[0]) : null; } catch { return null; } }
|
|
266
|
+
export async function proposeGateWithLLM(opts: { apiKey: string; question: string; answer: string; judgeNote?: string; model?: string }): Promise<TestbedGate | null> {
|
|
267
|
+
if (!getAdvancedGatesEnabled()) return null;
|
|
268
|
+
const res = await geminiGenerate({ apiKey: opts.apiKey, model: opts.model || "gemini-3.1-flash-lite", maxOutputTokens: 450, prompt: `Return one narrow regex gate as JSON or {"skip":true}. QUESTION:${opts.question}\nANSWER:${opts.answer.slice(0, 5000)}\nJUDGE_NOTE:${opts.judgeNote || ""}` });
|
|
269
|
+
if (!res.ok) return null;
|
|
270
|
+
const j = parseGateJson(res.text);
|
|
271
|
+
if (!j || j.skip || typeof j.code !== "string" || typeof j.regex !== "string") return null;
|
|
272
|
+
try { new RegExp(j.regex, j.flags || "i"); } catch { return null; }
|
|
273
|
+
return addTestbedGate({ code: j.code, severity: ["warning", "major", "critical"].includes(j.severity) ? j.severity : "warning", message: String(j.message || j.code), remediation: String(j.remediation || "Revise the answer."), regex: j.regex, flags: String(j.flags || "i"), sourceModel: opts.model });
|
|
274
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Gemini REST client for V15 calibration.
|
|
3
|
+
* Uses fetch directly — no @google/generative-ai dep needed.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface GenerateResult {
|
|
7
|
+
text: string;
|
|
8
|
+
ok: boolean;
|
|
9
|
+
error?: string;
|
|
10
|
+
latencyMs: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const ENDPOINTS: Record<string, string> = {
|
|
14
|
+
"gemini-3.5-flash": "gemini-3.5-flash",
|
|
15
|
+
"gemini-3-flash-preview": "gemini-3-flash-preview",
|
|
16
|
+
"gemini-3.1-flash-lite": "gemini-3.1-flash-lite",
|
|
17
|
+
"gemini-2.5-flash": "gemini-2.5-flash",
|
|
18
|
+
"gemini-2.5-flash-lite": "gemini-2.5-flash-lite",
|
|
19
|
+
"gemini-2.5-pro": "gemini-2.5-pro",
|
|
20
|
+
"gemma-4-31b-it": "gemma-4-31b-it",
|
|
21
|
+
"gemma-4-26b-it": "gemma-4-26b-it",
|
|
22
|
+
"gemma-3-27b-it": "gemma-3-27b-it",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* In-Memory Rotating API Key Store — Multi-Vendor API key rotation.
|
|
27
|
+
* Allows engineers to register multiple keys per vendor. The system
|
|
28
|
+
* chooses one randomly at call time, multiplying available RPM/RPD quotas.
|
|
29
|
+
*/
|
|
30
|
+
const apiKeysMap = new Map<string, string[]>();
|
|
31
|
+
|
|
32
|
+
export function registerApiKey(vendor: string, key: string): void {
|
|
33
|
+
const keys = apiKeysMap.get(vendor) ?? [];
|
|
34
|
+
if (key && !keys.includes(key)) {
|
|
35
|
+
keys.push(key);
|
|
36
|
+
apiKeysMap.set(vendor, keys);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function getRotatedKey(vendor: string, fallbackKey: string): string {
|
|
41
|
+
const keys = apiKeysMap.get(vendor) ?? [];
|
|
42
|
+
if (keys.length === 0) return fallbackKey;
|
|
43
|
+
const idx = Math.floor(Math.random() * keys.length);
|
|
44
|
+
return keys[idx] || fallbackKey;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function geminiGenerate(opts: {
|
|
48
|
+
apiKey: string;
|
|
49
|
+
model?: string;
|
|
50
|
+
prompt: string;
|
|
51
|
+
systemInstruction?: string;
|
|
52
|
+
maxOutputTokens?: number;
|
|
53
|
+
}): Promise<GenerateResult> {
|
|
54
|
+
const t0 = Date.now();
|
|
55
|
+
const model = ENDPOINTS[opts.model ?? ""] ?? "gemini-2.5-flash";
|
|
56
|
+
// Additive: rotate key across registered gemini keys if present.
|
|
57
|
+
const activeKey = getRotatedKey("gemini", opts.apiKey);
|
|
58
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${encodeURIComponent(activeKey)}`;
|
|
59
|
+
|
|
60
|
+
const body: any = {
|
|
61
|
+
contents: [{ role: "user", parts: [{ text: opts.prompt }] }],
|
|
62
|
+
generationConfig: {
|
|
63
|
+
maxOutputTokens: opts.maxOutputTokens ?? 2048,
|
|
64
|
+
temperature: 0.7,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
if (opts.systemInstruction) {
|
|
68
|
+
body.systemInstruction = { parts: [{ text: opts.systemInstruction }] };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
const res = await fetch(url, {
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers: { "Content-Type": "application/json" },
|
|
75
|
+
body: JSON.stringify(body),
|
|
76
|
+
});
|
|
77
|
+
const latencyMs = Date.now() - t0;
|
|
78
|
+
if (!res.ok) {
|
|
79
|
+
const errText = await res.text().catch(() => "");
|
|
80
|
+
return { text: "", ok: false, error: `HTTP ${res.status}: ${errText.slice(0, 240)}`, latencyMs };
|
|
81
|
+
}
|
|
82
|
+
const data = await res.json();
|
|
83
|
+
const text = data?.candidates?.[0]?.content?.parts?.map((p: any) => p?.text ?? "").join("") ?? "";
|
|
84
|
+
if (!text) return { text: "", ok: false, error: "Empty response from model", latencyMs };
|
|
85
|
+
return { text, ok: true, latencyMs };
|
|
86
|
+
} catch (err: any) {
|
|
87
|
+
return { text: "", ok: false, error: err?.message ?? "network error", latencyMs: Date.now() - t0 };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./v15-gemini.base";
|