talos-code 0.0.1 → 0.2.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/CHANGELOG.md +87 -0
- package/LICENSE +661 -0
- package/README.md +116 -3
- package/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/archive/zip.js +73 -0
- package/dist/args.js +100 -0
- package/dist/automations/history-store.js +34 -0
- package/dist/automations/policy-store.js +43 -0
- package/dist/automations/runner.js +107 -0
- package/dist/automations/schedule.js +85 -0
- package/dist/automations/windows-task.js +53 -0
- package/dist/commands/advanced-cli.js +233 -0
- package/dist/commands/checkpoint-cli.js +45 -0
- package/dist/commands/config-cli.js +107 -0
- package/dist/commands/context.js +17 -0
- package/dist/commands/extensions-cli.js +207 -0
- package/dist/commands/project-cli.js +74 -0
- package/dist/commands/project-commands.js +143 -0
- package/dist/commands/provider-cli.js +244 -0
- package/dist/commands/services-cli.js +248 -0
- package/dist/commands/session-cli.js +171 -0
- package/dist/commands/system-cli.js +405 -0
- package/dist/config/commands.js +60 -0
- package/dist/config/load.js +382 -0
- package/dist/config/migrations.js +48 -0
- package/dist/config/types.js +11 -0
- package/dist/diagnostics/development-log.js +154 -0
- package/dist/diagnostics/doctor.js +104 -0
- package/dist/diagnostics/redact.js +80 -0
- package/dist/diagnostics/zip.js +52 -0
- package/dist/errors.js +156 -0
- package/dist/events/bridge.js +130 -0
- package/dist/extensions/installer.js +178 -0
- package/dist/extensions/package-schema.js +24 -0
- package/dist/headless/result.js +84 -0
- package/dist/headless/run.js +230 -0
- package/dist/i18n/en/approval.js +46 -0
- package/dist/i18n/en/common.js +9 -0
- package/dist/i18n/en/credentials.js +92 -0
- package/dist/i18n/en/errors.js +267 -0
- package/dist/i18n/en/firstrun.js +101 -0
- package/dist/i18n/en/providers.js +37 -0
- package/dist/i18n/en/screen.js +774 -0
- package/dist/i18n/en/tools.js +127 -0
- package/dist/i18n/en.js +14 -0
- package/dist/i18n/error-view.js +307 -0
- package/dist/i18n/index.js +19 -0
- package/dist/i18n/kernel-map.js +139 -0
- package/dist/io.js +45 -0
- package/dist/main.js +331 -0
- package/dist/paths.js +41 -0
- package/dist/protocol/v2/codec.js +9 -0
- package/dist/protocol/v2/events.js +555 -0
- package/dist/protocol/v2/index.js +4 -0
- package/dist/protocol/v2/replay.js +28 -0
- package/dist/protocol/v2/types.js +1 -0
- package/dist/provider/control-plane.js +135 -0
- package/dist/provider/environment-keys.js +275 -0
- package/dist/provider/health.js +110 -0
- package/dist/provider/missing-key.js +48 -0
- package/dist/provider/model-catalog.js +168 -0
- package/dist/provider/openrouter-login.js +172 -0
- package/dist/provider/provider-text.js +13 -0
- package/dist/provider/store.js +95 -0
- package/dist/provider/system-keyring.js +214 -0
- package/dist/runtime/active-run.js +63 -0
- package/dist/runtime/agent-tree.js +74 -0
- package/dist/runtime/attachments.js +84 -0
- package/dist/runtime/brokered-executor.js +395 -0
- package/dist/runtime/context-archive.js +69 -0
- package/dist/runtime/context-status.js +76 -0
- package/dist/runtime/create-runtime.js +111 -0
- package/dist/runtime/model-profile.js +361 -0
- package/dist/runtime/output-store.js +137 -0
- package/dist/runtime/provider-attempts.js +185 -0
- package/dist/runtime/replay-buffer.js +153 -0
- package/dist/runtime/repo.js +95 -0
- package/dist/runtime/session-facade.js +135 -0
- package/dist/runtime/session-summary.js +125 -0
- package/dist/runtime/supervisor.js +265 -0
- package/dist/runtime/talos-composition.js +1011 -0
- package/dist/runtime/types.js +5 -0
- package/dist/runtime/usage-snapshot.js +82 -0
- package/dist/security/auto-classifier.js +38 -0
- package/dist/security/credential-free-environment.js +54 -0
- package/dist/security/evaluate.js +243 -0
- package/dist/security/execution-backends.js +236 -0
- package/dist/security/execution-broker.js +102 -0
- package/dist/security/forge-scan.js +74 -0
- package/dist/security/from-approval.js +39 -0
- package/dist/security/mxc-execution-backend.js +281 -0
- package/dist/security/permission-engine.js +138 -0
- package/dist/security/permission-explanation.js +54 -0
- package/dist/security/persist.js +179 -0
- package/dist/security/plugin-guard.js +230 -0
- package/dist/security/process-tree-evidence-store.js +74 -0
- package/dist/security/process-tree-probe.js +554 -0
- package/dist/security/project-resource-inventory.js +186 -0
- package/dist/security/project-trust-gate.js +38 -0
- package/dist/security/project-trust.js +367 -0
- package/dist/security/rule-parser.js +201 -0
- package/dist/security/shell-segmentation.js +68 -0
- package/dist/security/trust-authority.js +324 -0
- package/dist/security/types.js +1 -0
- package/dist/security/workspace-identity.js +102 -0
- package/dist/services/automation-facade.js +59 -0
- package/dist/services/forge-facade.js +77 -0
- package/dist/services/hook-facade.js +240 -0
- package/dist/services/index.js +16 -0
- package/dist/services/library-facade.js +174 -0
- package/dist/services/mcp-facade.js +348 -0
- package/dist/services/memory-facade.js +126 -0
- package/dist/services/notes-facade.js +157 -0
- package/dist/services/plugin-facade.js +308 -0
- package/dist/services/research-facade.js +110 -0
- package/dist/services/task-board-facade.js +236 -0
- package/dist/services/workflow-catalog.js +246 -0
- package/dist/sessions/export-format.js +98 -0
- package/dist/sessions/metadata-store.js +160 -0
- package/dist/sessions/share.js +122 -0
- package/dist/sessions/transfer.js +16 -0
- package/dist/subcommands.js +62 -0
- package/dist/tui/agent-roster.js +36 -0
- package/dist/tui/agent-view.js +51 -0
- package/dist/tui/app.js +4098 -0
- package/dist/tui/approval.js +36 -0
- package/dist/tui/boot/boot-sequence.js +76 -0
- package/dist/tui/boot/cinematic.js +243 -0
- package/dist/tui/boot/desktop-logo.js +82 -0
- package/dist/tui/boot.js +3 -0
- package/dist/tui/busy-input.js +58 -0
- package/dist/tui/catalog-service.js +560 -0
- package/dist/tui/components/assistant-stream.js +1 -0
- package/dist/tui/components/command-menu.js +68 -0
- package/dist/tui/components/composer.js +219 -0
- package/dist/tui/components/diff.js +35 -0
- package/dist/tui/components/footer.js +48 -0
- package/dist/tui/components/header.js +6 -0
- package/dist/tui/components/markdown.js +305 -0
- package/dist/tui/components/status-indicator.js +38 -0
- package/dist/tui/components/terminal-shell.js +214 -0
- package/dist/tui/components/thinking-row.js +19 -0
- package/dist/tui/components/tool-row.js +97 -0
- package/dist/tui/components/transcript-virtualizer.js +165 -0
- package/dist/tui/components/transcript.js +43 -0
- package/dist/tui/descendant-approvals.js +104 -0
- package/dist/tui/diff-model.js +77 -0
- package/dist/tui/editor-history.js +21 -0
- package/dist/tui/editor.js +210 -0
- package/dist/tui/event-adapter.js +436 -0
- package/dist/tui/exit-output.js +58 -0
- package/dist/tui/external-editor.js +53 -0
- package/dist/tui/file-completion.js +89 -0
- package/dist/tui/focus-manager.js +5 -0
- package/dist/tui/highlight.js +30 -0
- package/dist/tui/input-router.js +18 -0
- package/dist/tui/interrupt.js +99 -0
- package/dist/tui/keybindings.js +194 -0
- package/dist/tui/keymap-resolver.js +91 -0
- package/dist/tui/launch-state.js +148 -0
- package/dist/tui/line-diff.js +57 -0
- package/dist/tui/live-activity.js +56 -0
- package/dist/tui/metrics.js +123 -0
- package/dist/tui/onboarding.js +36 -0
- package/dist/tui/overlays/agent-tree.js +43 -0
- package/dist/tui/overlays/approval-dialog.js +642 -0
- package/dist/tui/overlays/automation-center.js +51 -0
- package/dist/tui/overlays/checkpoint-picker.js +47 -0
- package/dist/tui/overlays/context-inspector.js +36 -0
- package/dist/tui/overlays/effort-line.js +110 -0
- package/dist/tui/overlays/forge-center.js +46 -0
- package/dist/tui/overlays/help-dialog.js +16 -0
- package/dist/tui/overlays/history-picker.js +37 -0
- package/dist/tui/overlays/hook-center.js +70 -0
- package/dist/tui/overlays/library-center.js +55 -0
- package/dist/tui/overlays/mcp-center.js +60 -0
- package/dist/tui/overlays/memory-center.js +63 -0
- package/dist/tui/overlays/model-picker.js +77 -0
- package/dist/tui/overlays/notes-center.js +53 -0
- package/dist/tui/overlays/overlay-host.js +8 -0
- package/dist/tui/overlays/plugin-center.js +76 -0
- package/dist/tui/overlays/provider-picker.js +171 -0
- package/dist/tui/overlays/queue-editor.js +32 -0
- package/dist/tui/overlays/research-center.js +59 -0
- package/dist/tui/overlays/scroll-window.js +234 -0
- package/dist/tui/overlays/session-picker.js +115 -0
- package/dist/tui/overlays/tasks-center.js +83 -0
- package/dist/tui/overlays/theme-picker.js +21 -0
- package/dist/tui/overlays/transcript-search.js +58 -0
- package/dist/tui/overlays/trust-center.js +29 -0
- package/dist/tui/overlays/workflow-center.js +46 -0
- package/dist/tui/project-file-index.js +214 -0
- package/dist/tui/project-references.js +85 -0
- package/dist/tui/project-trust-prompt.js +289 -0
- package/dist/tui/prompt-history-store.js +116 -0
- package/dist/tui/queue-store.js +110 -0
- package/dist/tui/regions/budget.js +59 -0
- package/dist/tui/regions/views.js +96 -0
- package/dist/tui/render-coordinator.js +148 -0
- package/dist/tui/render-scheduler.js +4 -0
- package/dist/tui/run.js +69 -0
- package/dist/tui/selection-list.js +29 -0
- package/dist/tui/session-controller.js +791 -0
- package/dist/tui/session-export.js +54 -0
- package/dist/tui/setup-wizard.js +46 -0
- package/dist/tui/shell-input.js +35 -0
- package/dist/tui/shell-layout.js +48 -0
- package/dist/tui/shell-model.js +98 -0
- package/dist/tui/slash-commands.js +82 -0
- package/dist/tui/state.js +151 -0
- package/dist/tui/status-bar.js +125 -0
- package/dist/tui/status-view.js +40 -0
- package/dist/tui/terminal-capabilities.js +9 -0
- package/dist/tui/terminal-session.js +11 -0
- package/dist/tui/text-width.js +66 -0
- package/dist/tui/theme-catalog.js +27 -0
- package/dist/tui/theme-store.js +23 -0
- package/dist/tui/theme.js +23 -0
- package/dist/tui/tool-display.js +135 -0
- package/dist/tui/tool-facts.js +1 -0
- package/dist/tui/tools/bash-renderer.js +32 -0
- package/dist/tui/tools/change.js +61 -0
- package/dist/tui/tools/edit-renderer.js +17 -0
- package/dist/tui/tools/generic-renderer.js +13 -0
- package/dist/tui/tools/list-renderer.js +14 -0
- package/dist/tui/tools/read-renderer.js +13 -0
- package/dist/tui/tools/registry.js +20 -0
- package/dist/tui/tools/row-format.js +187 -0
- package/dist/tui/tools/search-renderer.js +38 -0
- package/dist/tui/tools/shared.js +97 -0
- package/dist/tui/tools/write-renderer.js +15 -0
- package/dist/tui/transcript-model.js +441 -0
- package/dist/tui/ui-preferences.js +79 -0
- package/dist/tui/usage-view.js +77 -0
- package/dist/tui/vim-mode.js +99 -0
- package/dist/update/check.js +15 -0
- package/dist/update/npm.js +51 -0
- package/dist/update/run.js +129 -0
- package/dist/version.js +2 -0
- package/dist/workspace/checkpoint-store.js +210 -0
- package/dist/workspace/checkpoint.js +413 -0
- package/dist/workspace/restore.js +232 -0
- package/package.json +64 -5
- package/vendor/context-engine/package.json +11 -0
- package/vendor/context-engine/src/compaction-planner.mjs +57 -0
- package/vendor/context-engine/src/contracts.mjs +48 -0
- package/vendor/context-engine/src/engine.mjs +445 -0
- package/vendor/context-engine/src/node/context-export.mjs +164 -0
- package/vendor/context-engine/src/node/legacy-import.mjs +92 -0
- package/vendor/context-engine/src/node/migrations/001-context.sql +126 -0
- package/vendor/context-engine/src/node/sqlite-store.mjs +85 -0
- package/vendor/context-engine/src/node/sqlite-worker.mjs +559 -0
- package/vendor/context-engine/src/profiles.mjs +10 -0
- package/vendor/context-engine/src/retrieval.mjs +104 -0
- package/vendor/context-engine/src/summary.mjs +97 -0
- package/vendor/context-engine/src/usage.mjs +34 -0
- package/vendor/harness-ui/package.json +38 -0
- package/vendor/harness-ui/src/acp-agent.mjs +350 -0
- package/vendor/harness-ui/src/agent-service.mjs +2188 -0
- package/vendor/harness-ui/src/agui-events.mjs +452 -0
- package/vendor/harness-ui/src/ambiente-solo-server.mjs +121 -0
- package/vendor/harness-ui/src/artifact-store.mjs +39 -0
- package/vendor/harness-ui/src/assistenza.mjs +123 -0
- package/vendor/harness-ui/src/automation-scheduler.mjs +69 -0
- package/vendor/harness-ui/src/automation-store.mjs +145 -0
- package/vendor/harness-ui/src/browser-annota.mjs +639 -0
- package/vendor/harness-ui/src/browser-frame.mjs +211 -0
- package/vendor/harness-ui/src/browser-proxy-universale.mjs +519 -0
- package/vendor/harness-ui/src/browser-proxy.mjs +87 -0
- package/vendor/harness-ui/src/browser-sessione-viva.mjs +329 -0
- package/vendor/harness-ui/src/browser-stream.mjs +445 -0
- package/vendor/harness-ui/src/browser-vivo.mjs +694 -0
- package/vendor/harness-ui/src/chat-image-attachments.mjs +72 -0
- package/vendor/harness-ui/src/config.mjs +697 -0
- package/vendor/harness-ui/src/contesto-del-progetto.mjs +385 -0
- package/vendor/harness-ui/src/context-asset-adapter.mjs +72 -0
- package/vendor/harness-ui/src/context-desktop-service.mjs +253 -0
- package/vendor/harness-ui/src/context-embedding-runtime.mjs +252 -0
- package/vendor/harness-ui/src/context-inference-scheduler.mjs +81 -0
- package/vendor/harness-ui/src/context-native-compaction.mjs +75 -0
- package/vendor/harness-ui/src/context-provider-adapter.mjs +141 -0
- package/vendor/harness-ui/src/context-runtime.mjs +118 -0
- package/vendor/harness-ui/src/context-token-counters.mjs +184 -0
- package/vendor/harness-ui/src/context-tool-catalog.mjs +86 -0
- package/vendor/harness-ui/src/context-tool-output.mjs +72 -0
- package/vendor/harness-ui/src/costo-elenco.mjs +252 -0
- package/vendor/harness-ui/src/custom-task.mjs +171 -0
- package/vendor/harness-ui/src/doctor.mjs +142 -0
- package/vendor/harness-ui/src/document-filename.mjs +97 -0
- package/vendor/harness-ui/src/document-generator.mjs +493 -0
- package/vendor/harness-ui/src/document-report.mjs +331 -0
- package/vendor/harness-ui/src/duckduckgo-search.mjs +155 -0
- package/vendor/harness-ui/src/elenco-profondo.mjs +337 -0
- package/vendor/harness-ui/src/favicon-proxy.mjs +113 -0
- package/vendor/harness-ui/src/forge-contract.mjs +221 -0
- package/vendor/harness-ui/src/frequent-dirs.mjs +134 -0
- package/vendor/harness-ui/src/generated-image-store.mjs +147 -0
- package/vendor/harness-ui/src/generation-idle.mjs +332 -0
- package/vendor/harness-ui/src/gguf-header.mjs +207 -0
- package/vendor/harness-ui/src/git-service.mjs +626 -0
- package/vendor/harness-ui/src/gitignore-elenco.mjs +604 -0
- package/vendor/harness-ui/src/harness-receipt-keypair.mjs +207 -0
- package/vendor/harness-ui/src/hf-direct-transfer.mjs +170 -0
- package/vendor/harness-ui/src/hf-hub-client.mjs +106 -0
- package/vendor/harness-ui/src/hf-image-proxy.mjs +105 -0
- package/vendor/harness-ui/src/hf-model-transfer.mjs +245 -0
- package/vendor/harness-ui/src/hook-registry.mjs +186 -0
- package/vendor/harness-ui/src/http-app.mjs +6259 -0
- package/vendor/harness-ui/src/http-lifecycle.mjs +132 -0
- package/vendor/harness-ui/src/id-archivio.mjs +27 -0
- package/vendor/harness-ui/src/image-generator.mjs +143 -0
- package/vendor/harness-ui/src/istruzioni-di-progetto.mjs +234 -0
- package/vendor/harness-ui/src/kernel/dist/kernelPerIlBanco.js +518 -0
- package/vendor/harness-ui/src/kernel/talosHarness.mjs +10437 -0
- package/vendor/harness-ui/src/library-policy-store.mjs +175 -0
- package/vendor/harness-ui/src/library-store.mjs +652 -0
- package/vendor/harness-ui/src/llama-server-supervisor.mjs +629 -0
- package/vendor/harness-ui/src/local-model-store.mjs +339 -0
- package/vendor/harness-ui/src/local-runtime-contract.mjs +66 -0
- package/vendor/harness-ui/src/local-runtime-events.mjs +44 -0
- package/vendor/harness-ui/src/local-runtime-llama-server.mjs +244 -0
- package/vendor/harness-ui/src/local-runtime-probe.mjs +401 -0
- package/vendor/harness-ui/src/machine-capacity.mjs +66 -0
- package/vendor/harness-ui/src/mappa-cartelle.mjs +491 -0
- package/vendor/harness-ui/src/mcp-client.mjs +98 -0
- package/vendor/harness-ui/src/mcp-registry.mjs +157 -0
- package/vendor/harness-ui/src/mcp-session.mjs +177 -0
- package/vendor/harness-ui/src/memory-store.mjs +227 -0
- package/vendor/harness-ui/src/model-catalog-models-dev.mjs +276 -0
- package/vendor/harness-ui/src/model-catalog.mjs +129 -0
- package/vendor/harness-ui/src/model-destination.mjs +189 -0
- package/vendor/harness-ui/src/modifica-ancorata.mjs +177 -0
- package/vendor/harness-ui/src/native-provider-adapter.mjs +205 -0
- package/vendor/harness-ui/src/notes-store.mjs +250 -0
- package/vendor/harness-ui/src/openai-compatible-runtime.mjs +428 -0
- package/vendor/harness-ui/src/openrouter-oauth.mjs +339 -0
- package/vendor/harness-ui/src/path-policy.mjs +442 -0
- package/vendor/harness-ui/src/plugin-registry.mjs +780 -0
- package/vendor/harness-ui/src/plugin-session.mjs +180 -0
- package/vendor/harness-ui/src/process-policy.mjs +345 -0
- package/vendor/harness-ui/src/prompt-enhancer-provider.mjs +94 -0
- package/vendor/harness-ui/src/provider-auth-cloud.mjs +95 -0
- package/vendor/harness-ui/src/provider-credential-store.mjs +541 -0
- package/vendor/harness-ui/src/provider-probe.mjs +582 -0
- package/vendor/harness-ui/src/provider-registry.mjs +1633 -0
- package/vendor/harness-ui/src/pty-terminal.mjs +312 -0
- package/vendor/harness-ui/src/public-problem.mjs +109 -0
- package/vendor/harness-ui/src/research/card.mjs +235 -0
- package/vendor/harness-ui/src/research/citations.mjs +142 -0
- package/vendor/harness-ui/src/research/collector.mjs +275 -0
- package/vendor/harness-ui/src/research/deposito-a-pezzi.mjs +139 -0
- package/vendor/harness-ui/src/research/dossier.mjs +114 -0
- package/vendor/harness-ui/src/research/esportazioni.mjs +560 -0
- package/vendor/harness-ui/src/research/fetch-cache.mjs +465 -0
- package/vendor/harness-ui/src/research/fidelity.mjs +122 -0
- package/vendor/harness-ui/src/research/independence.mjs +159 -0
- package/vendor/harness-ui/src/research/ledger.mjs +166 -0
- package/vendor/harness-ui/src/research/markdown-server.mjs +565 -0
- package/vendor/harness-ui/src/research/narration.mjs +181 -0
- package/vendor/harness-ui/src/research/open-cards.mjs +131 -0
- package/vendor/harness-ui/src/research/opposing.mjs +305 -0
- package/vendor/harness-ui/src/research/outline.mjs +111 -0
- package/vendor/harness-ui/src/research/page-budget.mjs +209 -0
- package/vendor/harness-ui/src/research/pdf.mjs +291 -0
- package/vendor/harness-ui/src/research/plan.mjs +301 -0
- package/vendor/harness-ui/src/research/raccolta-viva.mjs +452 -0
- package/vendor/harness-ui/src/research/recheck-document.mjs +69 -0
- package/vendor/harness-ui/src/research/recheck-history.mjs +192 -0
- package/vendor/harness-ui/src/research/recheck.mjs +194 -0
- package/vendor/harness-ui/src/research/report.mjs +203 -0
- package/vendor/harness-ui/src/research/run.mjs +527 -0
- package/vendor/harness-ui/src/research/synthesis.mjs +318 -0
- package/vendor/harness-ui/src/research/verification.mjs +572 -0
- package/vendor/harness-ui/src/research-orchestrator.mjs +2679 -0
- package/vendor/harness-ui/src/research-store.mjs +1133 -0
- package/vendor/harness-ui/src/runtime-build-manifest.mjs +26 -0
- package/vendor/harness-ui/src/runtime-contract.mjs +59 -0
- package/vendor/harness-ui/src/runtime-owner-adapter.mjs +1348 -0
- package/vendor/harness-ui/src/runtime-owner-contract.mjs +32 -0
- package/vendor/harness-ui/src/scheda-di-lavoro.mjs +249 -0
- package/vendor/harness-ui/src/search-source-store.mjs +172 -0
- package/vendor/harness-ui/src/session-registry.mjs +6095 -0
- package/vendor/harness-ui/src/session-store.mjs +220 -0
- package/vendor/harness-ui/src/sessione-pronta.mjs +73 -0
- package/vendor/harness-ui/src/setup-stato.mjs +31 -0
- package/vendor/harness-ui/src/sezioni-istruzioni.mjs +204 -0
- package/vendor/harness-ui/src/skill-registry.mjs +120 -0
- package/vendor/harness-ui/src/sse-replay-coalescente.mjs +0 -0
- package/vendor/harness-ui/src/static-files.mjs +96 -0
- package/vendor/harness-ui/src/stream-partition.mjs +123 -0
- package/vendor/harness-ui/src/subagent-orchestrator.mjs +453 -0
- package/vendor/harness-ui/src/task-catalog.mjs +65 -0
- package/vendor/harness-ui/src/tasks-store.mjs +220 -0
- package/vendor/harness-ui/src/terminal-registry.mjs +312 -0
- package/vendor/harness-ui/src/terminal-ws.mjs +170 -0
- package/vendor/harness-ui/src/tool-forge-store.mjs +299 -0
- package/vendor/harness-ui/src/tool-schema-normalize.mjs +100 -0
- package/vendor/harness-ui/src/usage-cache.mjs +315 -0
- package/vendor/harness-ui/src/workspace-browser.mjs +213 -0
- package/vendor/harness-ui/src/workspace-context.mjs +124 -0
- package/vendor/harness-ui/src/workspace-disk.mjs +62 -0
- package/vendor/harness-ui/src/workspace-files.mjs +589 -0
- package/vendor/harness-ui/src/workspace-info.mjs +189 -0
- package/vendor/harness-ui/src/workspace-launch-store.mjs +150 -0
- package/vendor/harness-ui/src/workspace-tree.mjs +67 -0
- package/vendor/harness-ui/src/workspace-watcher.mjs +161 -0
- package/vendor/manifest.json +170 -0
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* PORTO FEDELE di AVM/mobile/src/lib/research/researchVerification.ts (544 righe, 11/09/2026).
|
|
3
|
+
*
|
|
4
|
+
* I tre livelli, e il rifiuto che li regge.
|
|
5
|
+
*
|
|
6
|
+
* R-4. Quello che il campo misura davvero, sugli agenti di ricerca approfondita
|
|
7
|
+
* in particolare (arXiv 2605.06635): il link risolve più del 94% delle volte, la
|
|
8
|
+
* fonte è in tema più dell'80% delle volte, e la fonte SOSTIENE davvero
|
|
9
|
+
* l'affermazione fra il 39% e il 77% delle volte. Quindi il link morto — la cosa
|
|
10
|
+
* che ogni prodotto controlla — non è il problema. Il problema è il link vivo che
|
|
11
|
+
* non dice quello che il rapporto dichiara dica. Peggio: quell'accuratezza cala
|
|
12
|
+
* di circa il 42% quando un agente passa da 2 recuperi a 150, cioè la modalità
|
|
13
|
+
* più profonda è quella le cui citazioni sono meno affidabili, che è esattamente
|
|
14
|
+
* il contrario di quello che un lettore dà per scontato.
|
|
15
|
+
*
|
|
16
|
+
* Da qui la forma:
|
|
17
|
+
*
|
|
18
|
+
* L1 Come la fonte è stata ottenuta. Registrato dalla lettura, non richiesto di
|
|
19
|
+
* nuovo: un secondo scaricamento pochi istanti dopo il primo conferma solo
|
|
20
|
+
* quello che abbiamo appena visto, e uno stato HTTP mente comunque (i soft
|
|
21
|
+
* 404 rispondono 200 con una pagina d'errore). La domanda onesta più tardi
|
|
22
|
+
* — «dice ancora questo?» — è quella di R12, ed è rispondibile solo perché
|
|
23
|
+
* abbiamo tenuto il testo.
|
|
24
|
+
* L2 Il passaggio è davvero nel testo che abbiamo tenuto, e DOVE. Meccanico,
|
|
25
|
+
* gratis, nessun modello, nessuna opinione. Prende da solo la categoria
|
|
26
|
+
* peggiore: la citazione che non è mai stata sulla pagina. Gli offset sono
|
|
27
|
+
* ciò che permette al rapporto di mostrare al lettore il pezzo esatto.
|
|
28
|
+
* L3 Quel passaggio sostiene quell'affermazione. Questo costa un modello, ed è
|
|
29
|
+
* giudicato una affermazione contro un passaggio — mai il rapporto intero,
|
|
30
|
+
* perché un valutatore di implicazione pronto all'uso che arriva a AUROC
|
|
31
|
+
* 0,90 su affermazioni corte crolla a 0,53 (il caso) sulle risposte lunghe
|
|
32
|
+
* (arXiv 2606.23915). La granularità non è un dettaglio; è la differenza
|
|
33
|
+
* fra un controllo e una decorazione.
|
|
34
|
+
*
|
|
35
|
+
* E il rifiuto: il modello che ha scritto l'affermazione non la giudica mai. Un
|
|
36
|
+
* modello che valuta la propria uscita ha fino al 50% di probabilità in più di
|
|
37
|
+
* marcare come soddisfatto un criterio che in realtà ha fallito (arXiv
|
|
38
|
+
* 2604.06996). Una promozione auto-rilasciata vale meno di nessuna promozione,
|
|
39
|
+
* perché ne ha l'aspetto.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import {
|
|
43
|
+
talosResearchOpposingCandidate,
|
|
44
|
+
talosResearchParseOpposingVerdict,
|
|
45
|
+
} from './opposing.mjs';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @typedef {import('./collector.mjs').TalosResearchSource} TalosResearchSource
|
|
49
|
+
* @typedef {import('./synthesis.mjs').TalosResearchClaim} TalosResearchClaim
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* ⛔⛔ CONTESA-01 — «contesa» non è «parziale», e confonderle mente.
|
|
54
|
+
*
|
|
55
|
+
* - **parziale**: la fonte dice una parte di quello che si afferma. Una
|
|
56
|
+
* fonte, un verdetto a metà.
|
|
57
|
+
* - **contesa**: una fonte dice di sì e un'altra dice di no. Due fonti, due
|
|
58
|
+
* verdetti opposti, e nessuna metà da nessuna parte.
|
|
59
|
+
*
|
|
60
|
+
* Registrarle come la stessa cosa lusinga il rapporto proprio dove è più
|
|
61
|
+
* fragile: una contesa segnata «parziale» si legge come «quasi sostenuta»,
|
|
62
|
+
* mentre vuol dire che il mondo non è d'accordo.
|
|
63
|
+
*
|
|
64
|
+
* ⛔ Ricerca del 2026-08-20: i conflitti sono di tre tipi distinti — nelle
|
|
65
|
+
* prove, fra le fonti sulle prove, dentro la stessa fonte — e la pratica
|
|
66
|
+
* concorde è mostrare **entrambe** le versioni col perché differiscono
|
|
67
|
+
* (metodo, portata, data, disciplina). Non si media, e non si sceglie in
|
|
68
|
+
* silenzio la più comoda.
|
|
69
|
+
*
|
|
70
|
+
* @typedef {'yes' | 'partial' | 'no' | 'unchecked' | 'contested'} TalosResearchSupport
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Una fonte che dice il CONTRARIO, col suo passaggio: la scheda le affianca.
|
|
75
|
+
*
|
|
76
|
+
* @typedef {object} TalosResearchOpposing
|
|
77
|
+
* @property {string} url
|
|
78
|
+
* @property {string} title
|
|
79
|
+
* @property {string} passage Il passaggio come sta nella fonte, non come il modello lo ha riscritto.
|
|
80
|
+
* @property {TalosResearchSpan | null} span
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Dove sta il passaggio nel testo tenuto, così il lettore lo può vedere.
|
|
85
|
+
*
|
|
86
|
+
* @typedef {object} TalosResearchSpan
|
|
87
|
+
* @property {number} from
|
|
88
|
+
* @property {number} to
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Quanto basta a distinguere due giudici, e a riconoscere l'autore fra loro.
|
|
93
|
+
*
|
|
94
|
+
* @typedef {object} TalosResearchJudgeIdentity
|
|
95
|
+
* @property {string} id
|
|
96
|
+
* @property {string} provider
|
|
97
|
+
* @property {string} model
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @typedef {object} TalosResearchChecks
|
|
102
|
+
* @property {'page' | 'snippet' | 'missing'} resolved L1: letta dalla pagina, presa da un estratto di ricerca, o citata nel vuoto.
|
|
103
|
+
* @property {boolean} quotePresent L2
|
|
104
|
+
* @property {TalosResearchSpan | null} quoteSpan
|
|
105
|
+
* @property {TalosResearchSupport} claimSupported L3
|
|
106
|
+
* @property {string} supportReason
|
|
107
|
+
* @property {string | null} judge Chi ha reso il verdetto, e quando. Null quando nessuno l'ha fatto — e il perché sta nel motivo.
|
|
108
|
+
* @property {string | null} judgedAt
|
|
109
|
+
* @property {readonly TalosResearchOpposing[]} [opposing]
|
|
110
|
+
* ⛔ CONTESA-01 — le fonti che dicono il contrario, col loro passaggio.
|
|
111
|
+
* Opzionale perché una verifica vecchia non le ha: assente vuol dire «non
|
|
112
|
+
* guardato», non «non ce ne sono». Le due cose si leggono uguali solo se non
|
|
113
|
+
* ti importa di sbagliare.
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @typedef {object} TalosResearchVerifiedClaim
|
|
118
|
+
* @property {TalosResearchClaim} claim
|
|
119
|
+
* @property {string} passage Il passaggio com'è nella fonte, non come il modello l'ha ribattuto.
|
|
120
|
+
* @property {TalosResearchChecks} checks
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @typedef {object} TalosResearchVerifyDeps
|
|
125
|
+
* @property {TalosResearchJudgeIdentity | null} judge Il giudice indipendente, o null quando non ce n'è. Scelto da `talosResearchPickJudge`.
|
|
126
|
+
* @property {(claim: string, passage: string) => Promise<string>} ask
|
|
127
|
+
* Chiede al giudice di UNA affermazione e UN passaggio. La firma È
|
|
128
|
+
* l'isolamento: non c'è modo di passargli la domanda, il riassunto o le altre
|
|
129
|
+
* affermazioni, perché tutto ciò che aggiungi spinge la risposta verso «sì,
|
|
130
|
+
* quadra».
|
|
131
|
+
* @property {(claim: string, passage: string) => Promise<string>} [askOpposing]
|
|
132
|
+
* ⛔ CONTESA-02 — chiede allo stesso giudice se un passaggio di un'ALTRA fonte
|
|
133
|
+
* contraddice l'affermazione. Opzionale, e assente vuol dire «non guardato»:
|
|
134
|
+
* senza, il verdetto resta quello di prima e `opposing` non c'è. È la stessa
|
|
135
|
+
* distinzione che il campo `opposing` porta nella scheda — «non guardato» non
|
|
136
|
+
* è «non ce ne sono», e le due cose si leggono uguali solo se non importa
|
|
137
|
+
* sbagliare.
|
|
138
|
+
* @property {() => string} at
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
/* -------------------------------------------------------------------------- */
|
|
142
|
+
/* L2 */
|
|
143
|
+
/* -------------------------------------------------------------------------- */
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Normalizza un testo ricordandosi da dove viene ogni carattere.
|
|
147
|
+
*
|
|
148
|
+
* Una pagina e un modello non sono d'accordo su spazi e virgolette e sono
|
|
149
|
+
* d'accordo sul significato, quindi il confronto deve essere lasco. Ma il
|
|
150
|
+
* RAPPORTO deve poter puntare al testo originale, e un confronto lasco che
|
|
151
|
+
* perde la posizione è inutile. Tenere la mappa è ciò che fa funzionare «tocca
|
|
152
|
+
* la citazione, vedi le parole esatte».
|
|
153
|
+
*
|
|
154
|
+
* @param {string} text
|
|
155
|
+
* @returns {{flat: string, at: {s:number, e:number}[]}}
|
|
156
|
+
*/
|
|
157
|
+
function mapped(text) {
|
|
158
|
+
/** @type {string[]} */
|
|
159
|
+
const out = [];
|
|
160
|
+
/** @type {{s:number, e:number}[]} */
|
|
161
|
+
const at = [];
|
|
162
|
+
|
|
163
|
+
for (let index = 0; index < text.length;) {
|
|
164
|
+
const char = text[index];
|
|
165
|
+
if (/\s/.test(char)) {
|
|
166
|
+
let end = index;
|
|
167
|
+
while (end < text.length && /\s/.test(text[end])) end += 1;
|
|
168
|
+
out.push(' ');
|
|
169
|
+
at.push({ s: index, e: end });
|
|
170
|
+
index = end;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const plain = char === '‘' || char === '’' ? "'"
|
|
175
|
+
: char === '“' || char === '”' ? '"'
|
|
176
|
+
: char.toLowerCase();
|
|
177
|
+
// Un carattere della fonte può diventare più caratteri in minuscolo; tutti
|
|
178
|
+
// puntano indietro allo stesso carattere, così gli offset restano onesti.
|
|
179
|
+
for (const produced of plain) {
|
|
180
|
+
out.push(produced);
|
|
181
|
+
at.push({ s: index, e: index + 1 });
|
|
182
|
+
}
|
|
183
|
+
index += 1;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return { flat: out.join(''), at };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Trova il passaggio nel testo tenuto e dice dov'è, oppure null.
|
|
191
|
+
*
|
|
192
|
+
* Null è una risposta vera: il modello ha citato qualcosa che non c'è. Qui
|
|
193
|
+
* dentro niente cerca la frase simile più vicina — un verificatore che
|
|
194
|
+
* gentilmente trova un'approssimazione è un verificatore che fabbrica
|
|
195
|
+
* attribuzioni, che è esattamente il guasto per cui questo file esiste.
|
|
196
|
+
*
|
|
197
|
+
* @param {string} text
|
|
198
|
+
* @param {string} quote
|
|
199
|
+
* @returns {TalosResearchSpan | null}
|
|
200
|
+
*/
|
|
201
|
+
export function talosResearchLocate(text, quote) {
|
|
202
|
+
const haystack = mapped(text);
|
|
203
|
+
const needle = mapped(quote).flat.trim();
|
|
204
|
+
if (needle.length === 0) return null;
|
|
205
|
+
|
|
206
|
+
const found = haystack.flat.indexOf(needle);
|
|
207
|
+
if (found < 0) return null;
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
from: haystack.at[found].s,
|
|
211
|
+
to: haystack.at[found + needle.length - 1].e,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* -------------------------------------------------------------------------- */
|
|
216
|
+
/* L3 */
|
|
217
|
+
/* -------------------------------------------------------------------------- */
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Il giudice, scelto per eliminazione: chiunque tranne l'autore.
|
|
221
|
+
*
|
|
222
|
+
* I candidati arrivano nell'ordine che il chiamante preferisce — il motore sul
|
|
223
|
+
* dispositivo per primo, perché non costa niente, non ha bisogno di rete e non
|
|
224
|
+
* appartiene alla famiglia di nessun modello in cloud. Se ogni candidato è
|
|
225
|
+
* l'autore, questa torna null e le affermazioni escono marcate `unchecked` col
|
|
226
|
+
* motivo scritto. È tutto il punto: un'affermazione non giudicata è onesta, una
|
|
227
|
+
* auto-giudicata no.
|
|
228
|
+
*
|
|
229
|
+
* Generico perché il chiamante tenga quello che aveva attaccato al candidato —
|
|
230
|
+
* l'oggetto modello, le credenziali — invece di scegliere un giudice e poi
|
|
231
|
+
* doverlo ricercare per nome, che è il modo in cui si finisce per chiamare
|
|
232
|
+
* quello sbagliato.
|
|
233
|
+
*
|
|
234
|
+
* @template {TalosResearchJudgeIdentity} T
|
|
235
|
+
* @param {TalosResearchJudgeIdentity} author
|
|
236
|
+
* @param {readonly T[]} candidates
|
|
237
|
+
* @returns {T | null}
|
|
238
|
+
*/
|
|
239
|
+
export function talosResearchPickJudge(author, candidates) {
|
|
240
|
+
return candidates.find((candidate) => !(
|
|
241
|
+
candidate.provider === author.provider && candidate.model === author.model
|
|
242
|
+
)) ?? null;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Quali case interpellare, e in che ordine.
|
|
247
|
+
*
|
|
248
|
+
* Sul dispositivo per primo: gratis, senza rete, e imparentato con nessun
|
|
249
|
+
* modello in cloud. Poi qualunque fornitore che non sia quello dell'autore,
|
|
250
|
+
* perché la preferenza per sé è misurata estendersi alla famiglia di un modello
|
|
251
|
+
* e non solo a sé stesso. Il fornitore dell'autore viene per ultimo, e ci si
|
|
252
|
+
* arriva solo con un modello diverso — un'indipendenza reale ma più debole, ed
|
|
253
|
+
* è per questo che il nome del giudice finisce nel rapporto, perché il lettore
|
|
254
|
+
* lo possa pesare.
|
|
255
|
+
*
|
|
256
|
+
* @template {string} P
|
|
257
|
+
* @param {P} authorProvider
|
|
258
|
+
* @param {readonly P[]} providers
|
|
259
|
+
* @param {P} onDevice
|
|
260
|
+
* @returns {readonly P[]}
|
|
261
|
+
*/
|
|
262
|
+
export function talosResearchJudgeOrder(authorProvider, providers, onDevice) {
|
|
263
|
+
return [
|
|
264
|
+
...providers.filter((provider) => provider === onDevice),
|
|
265
|
+
...providers.filter((provider) => provider !== onDevice && provider !== authorProvider),
|
|
266
|
+
...providers.filter((provider) => provider !== onDevice && provider === authorProvider),
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Quello che si chiede al giudice, e nient'altro.
|
|
272
|
+
*
|
|
273
|
+
* L'istruzione a usare solo il passaggio è la riga portante: senza, il modello
|
|
274
|
+
* risponde da quello che già sa, e un'affermazione che si dà il caso sia vera
|
|
275
|
+
* raccoglie una promozione da un passaggio che non l'ha mai detta — che è
|
|
276
|
+
* precisamente il guasto che un controllo delle citazioni dovrebbe prendere.
|
|
277
|
+
*
|
|
278
|
+
* @param {string} claim
|
|
279
|
+
* @param {string} passage
|
|
280
|
+
* @returns {string}
|
|
281
|
+
*/
|
|
282
|
+
export function talosResearchJudgePrompt(claim, passage) {
|
|
283
|
+
return [
|
|
284
|
+
'Passaggio, copiato dalla fonte:',
|
|
285
|
+
'"""',
|
|
286
|
+
passage,
|
|
287
|
+
'"""',
|
|
288
|
+
'',
|
|
289
|
+
'Affermazione da verificare:',
|
|
290
|
+
claim,
|
|
291
|
+
'',
|
|
292
|
+
'Il passaggio, DA SOLO, sostiene l’affermazione?',
|
|
293
|
+
'Non usare altro: né quello che sai, né quello che ti sembra probabile.',
|
|
294
|
+
'',
|
|
295
|
+
// ⛔⛔ IL MENU CON LE BARRE lo faceva RICOPIARE.
|
|
296
|
+
//
|
|
297
|
+
// MISURATO sul Pad il 2026-08-20 con gemma-3-4b come giudice: la
|
|
298
|
+
// risposta arrivava come «Sì | PARZIALE | Il passaggio indica che…»,
|
|
299
|
+
// cioè due voci del menu invece di una. Il parser prendeva la prima
|
|
300
|
+
// e quei rapporti risultavano al 100%: erano verdetti che il giudice
|
|
301
|
+
// non aveva dato.
|
|
302
|
+
//
|
|
303
|
+
// ⇒ Le tre parole si elencano una per riga, senza barre, e si mostra
|
|
304
|
+
// com’è fatta una risposta buona. Non c’è più niente da ricopiare.
|
|
305
|
+
'Rispondi con UNA riga sola. Comincia con UNA di queste tre parole:',
|
|
306
|
+
'SI',
|
|
307
|
+
'PARZIALE',
|
|
308
|
+
'NO',
|
|
309
|
+
'Poi un trattino e il motivo, massimo quindici parole.',
|
|
310
|
+
'',
|
|
311
|
+
'Esempio di risposta: SI — il passaggio lo dice testualmente.',
|
|
312
|
+
'',
|
|
313
|
+
'PARZIALE significa: il passaggio riguarda l’argomento ma non sostiene',
|
|
314
|
+
'tutta l’affermazione (per esempio ne sostiene il fatto ma non la misura).',
|
|
315
|
+
].join('\n');
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* `\b` qui non serve a niente: i verdetti italiani finiscono con lettere
|
|
320
|
+
* accentate, che JavaScript non conta come caratteri di parola, quindi «Sì»
|
|
321
|
+
* fallirebbe un test di confine di parola.
|
|
322
|
+
*
|
|
323
|
+
* ⛔ Le barre in testa si saltano: un modello che risponde «| PARZIALE |
|
|
324
|
+
* motivo» ha dato il verdetto, con addosso la punteggiatura del menu.
|
|
325
|
+
*/
|
|
326
|
+
const VERDICT = /^[\s|]*(s[iì]|parziale|no)(?![\p{L}\p{N}])/iu;
|
|
327
|
+
|
|
328
|
+
/** Un pezzo che è SOLO una parola di verdetto, senza niente attorno. */
|
|
329
|
+
const SOLO_VERDETTO = /^\s*(s[iì]|parziale|no)\s*$/iu;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Legge il verdetto, o ammette che non ce n'era uno.
|
|
333
|
+
*
|
|
334
|
+
* Una risposta che non si analizza è `unchecked`, mai una promozione.
|
|
335
|
+
* L'alternativa — trattare una risposta confusa come un assenso — metterebbe un
|
|
336
|
+
* segno di verifica sulle affermazioni che il giudice ha trovato più difficili,
|
|
337
|
+
* che è il posto peggiore possibile dove metterlo.
|
|
338
|
+
*
|
|
339
|
+
* @param {string} answer
|
|
340
|
+
* @returns {{support: TalosResearchSupport, reason: string}}
|
|
341
|
+
*/
|
|
342
|
+
export function talosResearchParseVerdict(answer) {
|
|
343
|
+
for (const line of answer.split('\n')) {
|
|
344
|
+
const match = VERDICT.exec(line);
|
|
345
|
+
if (!match) continue;
|
|
346
|
+
|
|
347
|
+
/*
|
|
348
|
+
* ⛔⛔ IL MENU RICOPIATO non è una scelta.
|
|
349
|
+
*
|
|
350
|
+
* MISURATO sul Pad il 2026-08-20: il giudice ha risposto «Sì |
|
|
351
|
+
* PARZIALE | Il passaggio indica che…», cioè ha ricopiato due voci
|
|
352
|
+
* del formato invece di sceglierne una. Il parser prendeva la prima
|
|
353
|
+
* e attaccava il resto — barre comprese — come «motivo»: a schermo
|
|
354
|
+
* si leggeva «contesa» sopra e «| PARZIALE |» sotto, due parole
|
|
355
|
+
* diverse per lo stesso stato, e il verdetto era il più generoso
|
|
356
|
+
* dei due.
|
|
357
|
+
*
|
|
358
|
+
* ⇒ Due voci del menu in una riga = nessun verdetto. Sceglierne una
|
|
359
|
+
* al posto suo sarebbe inventare la parte che non ha detto.
|
|
360
|
+
*/
|
|
361
|
+
const pezzi = line.split('|').map((pezzo) => pezzo.trim());
|
|
362
|
+
if (pezzi.filter((pezzo) => SOLO_VERDETTO.test(pezzo)).length >= 2) {
|
|
363
|
+
return { support: 'unchecked', reason: '' };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const word = match[1].toLowerCase();
|
|
367
|
+
return {
|
|
368
|
+
support: word === 'parziale' ? 'partial' : word === 'no' ? 'no' : 'yes',
|
|
369
|
+
// La barra sta fra i separatori: «SI | motivo» è la stessa cosa
|
|
370
|
+
// di «SI — motivo», e la barra non è parte del motivo.
|
|
371
|
+
reason: line.slice(match[0].length).replace(/^[\s|—–\-:,.]+/, '').trim(),
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
return { support: 'unchecked', reason: '' };
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* -------------------------------------------------------------------------- */
|
|
378
|
+
/* I tre livelli insieme */
|
|
379
|
+
/* -------------------------------------------------------------------------- */
|
|
380
|
+
|
|
381
|
+
const NO_SOURCE = 'la fonte citata non esiste fra quelle raccolte';
|
|
382
|
+
const NO_QUOTE = 'il passaggio non è nel testo della fonte';
|
|
383
|
+
const NO_JUDGE = 'nessun giudice indipendente disponibile: l’autore non può verificare sé stesso';
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Cerca chi dice il contrario, e chiede al giudice se lo dice davvero.
|
|
387
|
+
*
|
|
388
|
+
* ⛔ UNA sola candidata per affermazione: è una chiamata al giudice in più,
|
|
389
|
+
* e sul motore del telefono le chiamate sono in fila. Cercarne tre
|
|
390
|
+
* raddoppierebbe il tempo di un rapporto per trovare, quasi sempre, la
|
|
391
|
+
* stessa cosa.
|
|
392
|
+
*
|
|
393
|
+
* ⛔ E un guasto qui NON porta via l'affermazione: torna vuoto, il verdetto
|
|
394
|
+
* resta quello del primo giro. Una contesa che non si è potuta cercare non
|
|
395
|
+
* è una contesa che non c'è, ma è comunque meglio di un rapporto perso.
|
|
396
|
+
*
|
|
397
|
+
* @param {TalosResearchVerifyDeps} deps
|
|
398
|
+
* @param {TalosResearchClaim} claim
|
|
399
|
+
* @param {readonly TalosResearchSource[]} sources
|
|
400
|
+
* @param {TalosResearchSupport} support
|
|
401
|
+
* @param {string} passage Quello che il giudice ha appena approvato: chi lo ripete non lo nega.
|
|
402
|
+
* @returns {Promise<readonly TalosResearchOpposing[]>}
|
|
403
|
+
*/
|
|
404
|
+
async function contrarie(deps, claim, sources, support, passage) {
|
|
405
|
+
// La contesa è disaccordo: senza un accordo prima non c'è niente con cui
|
|
406
|
+
// essere in disaccordo, e chiedere costerebbe per nulla.
|
|
407
|
+
if (!deps.askOpposing) return [];
|
|
408
|
+
if (support !== 'yes' && support !== 'partial') return [];
|
|
409
|
+
|
|
410
|
+
const candidata = talosResearchOpposingCandidate(claim.text, claim.sourceIndex - 1, sources, passage);
|
|
411
|
+
if (!candidata) return [];
|
|
412
|
+
|
|
413
|
+
try {
|
|
414
|
+
const risposta = await deps.askOpposing(claim.text, candidata.passage);
|
|
415
|
+
if (!talosResearchParseOpposingVerdict(risposta)) return [];
|
|
416
|
+
return [{
|
|
417
|
+
url: candidata.url,
|
|
418
|
+
title: candidata.title,
|
|
419
|
+
passage: candidata.passage,
|
|
420
|
+
span: candidata.span,
|
|
421
|
+
}];
|
|
422
|
+
} catch {
|
|
423
|
+
return [];
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Fa girare i tre livelli su ogni affermazione.
|
|
429
|
+
*
|
|
430
|
+
* IN SEQUENZA, e non per caso: il motore sul dispositivo risponde a una
|
|
431
|
+
* richiesta per volta e rifiuta la seconda, quindi una verifica che si
|
|
432
|
+
* aprisse a ventaglio farebbe fallire ogni affermazione tranne la prima —
|
|
433
|
+
* proprio sul giudice che non costa niente ed è quindi quello predefinito.
|
|
434
|
+
*
|
|
435
|
+
* L3 si salta quando L2 è fallito. Chiedere a un modello se un passaggio
|
|
436
|
+
* inventato sostiene un'affermazione è chiedergli di qualcosa che non è una
|
|
437
|
+
* prova; la citazione è già rotta, e pagare per farla discutere produrrebbe
|
|
438
|
+
* solo un secondo parere su una fabbricazione.
|
|
439
|
+
*
|
|
440
|
+
* @param {TalosResearchVerifyDeps} deps
|
|
441
|
+
* @param {readonly TalosResearchClaim[]} claims
|
|
442
|
+
* @param {readonly TalosResearchSource[]} sources
|
|
443
|
+
* @returns {Promise<readonly TalosResearchVerifiedClaim[]>}
|
|
444
|
+
*/
|
|
445
|
+
export async function talosResearchVerify(deps, claims, sources) {
|
|
446
|
+
/** @type {TalosResearchVerifiedClaim[]} */
|
|
447
|
+
const verified = [];
|
|
448
|
+
|
|
449
|
+
for (const claim of claims) {
|
|
450
|
+
const source = sources[claim.sourceIndex - 1];
|
|
451
|
+
const span = source ? talosResearchLocate(source.text, claim.quote) : null;
|
|
452
|
+
const passage = source && span ? source.text.slice(span.from, span.to) : '';
|
|
453
|
+
|
|
454
|
+
const base = {
|
|
455
|
+
resolved: source ? source.obtained : 'missing',
|
|
456
|
+
quotePresent: span !== null,
|
|
457
|
+
quoteSpan: span,
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
if (!source || !span) {
|
|
461
|
+
verified.push({
|
|
462
|
+
claim,
|
|
463
|
+
passage,
|
|
464
|
+
checks: {
|
|
465
|
+
...base,
|
|
466
|
+
claimSupported: 'unchecked',
|
|
467
|
+
supportReason: source ? NO_QUOTE : NO_SOURCE,
|
|
468
|
+
judge: null,
|
|
469
|
+
judgedAt: null,
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (!deps.judge) {
|
|
476
|
+
verified.push({
|
|
477
|
+
claim,
|
|
478
|
+
passage,
|
|
479
|
+
checks: { ...base, claimSupported: 'unchecked', supportReason: NO_JUDGE, judge: null, judgedAt: null },
|
|
480
|
+
});
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
try {
|
|
485
|
+
// Il passaggio mandato è quello ritagliato dalla fonte, quindi un modello
|
|
486
|
+
// non può far passare una citazione ritoccata davanti al controllo che la
|
|
487
|
+
// legge.
|
|
488
|
+
const verdict = talosResearchParseVerdict(await deps.ask(claim.text, passage));
|
|
489
|
+
const judged = verdict.support !== 'unchecked';
|
|
490
|
+
const opposing = judged ? await contrarie(deps, claim, sources, verdict.support, passage) : [];
|
|
491
|
+
verified.push({
|
|
492
|
+
claim,
|
|
493
|
+
passage,
|
|
494
|
+
checks: {
|
|
495
|
+
...base,
|
|
496
|
+
// ⛔ La contesa NON sostituisce il verdetto a mano: la regola
|
|
497
|
+
// («era un sì o un in parte, e qualcuno dice di no») sta in
|
|
498
|
+
// un posto solo, con i suoi test.
|
|
499
|
+
claimSupported: talosResearchContestedVerdict(verdict.support, opposing),
|
|
500
|
+
supportReason: judged ? verdict.reason : 'il giudice non ha dato un verdetto leggibile',
|
|
501
|
+
judge: judged ? deps.judge.id : null,
|
|
502
|
+
judgedAt: judged ? deps.at() : null,
|
|
503
|
+
...(opposing.length ? { opposing } : {}),
|
|
504
|
+
},
|
|
505
|
+
});
|
|
506
|
+
} catch (failure) {
|
|
507
|
+
// Un giudice che cade non deve portarsi via il rapporto: le altre
|
|
508
|
+
// affermazioni restano controllabili, e questa dice perché non lo è.
|
|
509
|
+
verified.push({
|
|
510
|
+
claim,
|
|
511
|
+
passage,
|
|
512
|
+
checks: {
|
|
513
|
+
...base,
|
|
514
|
+
claimSupported: 'unchecked',
|
|
515
|
+
supportReason: failure instanceof Error ? failure.message : 'il giudice non ha risposto',
|
|
516
|
+
judge: null,
|
|
517
|
+
judgedAt: null,
|
|
518
|
+
},
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
return verified;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* ⛔ CONTESA-01 — il verdetto FINALE, dopo aver guardato anche le contrarie.
|
|
528
|
+
*
|
|
529
|
+
* Contesa vuol dire **disaccordo**, e il disaccordo esiste solo se il
|
|
530
|
+
* giudice aveva detto di sì (o in parte) e qualcuno dice di no. Se il
|
|
531
|
+
* giudice ha già detto «no», una fonte contraria non è un conflitto: è la
|
|
532
|
+
* stessa cosa detta due volte, e chiamarla contesa toglierebbe forza a un
|
|
533
|
+
* «no» che invece è solido.
|
|
534
|
+
*
|
|
535
|
+
* ⛔ E una NON verificata non diventa contesa: se nessuno ha giudicato non
|
|
536
|
+
* c'è niente con cui l'altra fonte possa essere in disaccordo.
|
|
537
|
+
*
|
|
538
|
+
* @param {TalosResearchSupport} support
|
|
539
|
+
* @param {readonly TalosResearchOpposing[] | undefined} opposing
|
|
540
|
+
* @returns {TalosResearchSupport}
|
|
541
|
+
*/
|
|
542
|
+
export function talosResearchContestedVerdict(support, opposing) {
|
|
543
|
+
if (!opposing?.length) return support;
|
|
544
|
+
return support === 'yes' || support === 'partial' ? 'contested' : support;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* La riga in cima al rapporto: quanto di questo ha davvero retto.
|
|
549
|
+
*
|
|
550
|
+
* @param {readonly TalosResearchVerifiedClaim[]} claims
|
|
551
|
+
* @returns {{total:number, supported:number, partial:number, unsupported:number, unchecked:number, contested:number}}
|
|
552
|
+
*/
|
|
553
|
+
export function talosResearchVerifiedStanding(claims) {
|
|
554
|
+
/** @param {TalosResearchSupport} support */
|
|
555
|
+
const count = (support) =>
|
|
556
|
+
claims.filter((entry) => entry.checks.claimSupported === support).length;
|
|
557
|
+
|
|
558
|
+
return {
|
|
559
|
+
total: claims.length,
|
|
560
|
+
supported: count('yes'),
|
|
561
|
+
partial: count('partial'),
|
|
562
|
+
unsupported: count('no'),
|
|
563
|
+
// Tenuto a parte da `unsupported` di proposito: «non abbiamo potuto
|
|
564
|
+
// controllarlo» e «abbiamo controllato, e la fonte non lo dice» sono due
|
|
565
|
+
// ammissioni diverse, e fonderle lusingherebbe la seconda.
|
|
566
|
+
unchecked: count('unchecked'),
|
|
567
|
+
// ⛔ E la contesa sta fuori da tutte e tre: non è una sostenuta con
|
|
568
|
+
// una riserva, non è una parziale, e non è un'ammissione di non
|
|
569
|
+
// sapere. È il mondo che non concorda, ed è un esito suo.
|
|
570
|
+
contested: count('contested'),
|
|
571
|
+
};
|
|
572
|
+
}
|