@ouro.bot/cli 0.1.0-alpha.83 → 0.1.0-alpha.831
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/LICENSE +21 -0
- package/README.md +154 -23
- package/RepairGuide.ouro/agent.json +5 -0
- package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
- package/RepairGuide.ouro/psyche/SOUL.md +55 -0
- package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
- package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
- package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
- package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/assets/bluebubbles-host +264 -0
- package/assets/sanctuary-host-launcher.sh +16 -0
- package/changelog.json +5308 -16
- package/deploy/unraid/Dockerfile +54 -0
- package/deploy/unraid/README.txt +2983 -0
- package/deploy/unraid/audit-container-spec.sh +4 -0
- package/deploy/unraid/container-runtime.json +1 -0
- package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
- package/deploy/unraid/docker-man-template-xml.cjs +105 -0
- package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
- package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
- package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
- package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
- package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
- package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
- package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
- package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
- package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
- package/deploy/unraid/sanctuary-authority-installation.json +36 -0
- package/deploy/unraid/sanctuary-authority-service.sh +30 -0
- package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
- package/deploy/unraid/sanctuary-safe-rename.py +24 -0
- package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
- package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
- package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
- package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
- package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
- package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
- package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
- package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
- package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
- package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
- package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
- package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
- package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
- package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
- package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
- package/deploy/unraid/sanctuary.ouro/tool-profiles.json +135 -0
- package/deploy/unraid/sanctuary.xml +28 -0
- package/dist/a2a/card.js +57 -0
- package/dist/a2a/client.js +180 -0
- package/dist/a2a/config.js +50 -0
- package/dist/a2a/delegation-stores.js +56 -0
- package/dist/a2a/did-resolution.js +93 -0
- package/dist/a2a/identity.js +170 -0
- package/dist/a2a/inbound-share.js +107 -0
- package/dist/a2a/mission-result-wire.js +196 -0
- package/dist/a2a/onboarding.js +115 -0
- package/dist/a2a/pin-store.js +132 -0
- package/dist/a2a/seen-ledger.js +120 -0
- package/dist/a2a/server.js +604 -0
- package/dist/a2a/task-store.js +69 -0
- package/dist/a2a/transport.js +45 -0
- package/dist/a2a/types.js +3 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +360 -0
- package/dist/arc/episodes.js +118 -0
- package/dist/arc/evolution.js +490 -0
- package/dist/arc/flight-recorder.js +1034 -0
- package/dist/arc/intentions.js +134 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +386 -0
- package/dist/arc/packets.js +336 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +57 -0
- package/dist/commerce/store.js +755 -0
- package/dist/commerce/types.js +3 -0
- package/dist/heart/active-work.js +798 -40
- package/dist/heart/agent-entry.js +252 -3
- package/dist/heart/approval-files.js +113 -0
- package/dist/heart/approval-store.js +960 -0
- package/dist/heart/attachments/image-normalize.js +194 -0
- package/dist/heart/attachments/materialize.js +97 -0
- package/dist/heart/attachments/originals.js +88 -0
- package/dist/heart/attachments/render.js +29 -0
- package/dist/heart/attachments/sources/bluebubbles.js +156 -0
- package/dist/heart/attachments/sources/cli-local-file.js +78 -0
- package/dist/heart/attachments/sources/index.js +18 -0
- package/dist/heart/attachments/sources/telegram.js +71 -0
- package/dist/heart/attachments/store.js +132 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +495 -0
- package/dist/heart/autonomy-budget.js +478 -0
- package/dist/heart/awaiting/await-alert.js +148 -0
- package/dist/heart/awaiting/await-expiry.js +143 -0
- package/dist/heart/awaiting/await-loader.js +91 -0
- package/dist/heart/awaiting/await-parser.js +149 -0
- package/dist/heart/awaiting/await-runtime-state.js +111 -0
- package/dist/heart/awaiting/await-scheduler.js +382 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bridges/manager.js +137 -17
- package/dist/heart/bridges/store.js +14 -2
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +44 -18
- package/dist/heart/config-registry.js +331 -0
- package/dist/heart/config.js +174 -131
- package/dist/heart/context-loss-gauntlet.js +387 -0
- package/dist/heart/context-loss-sentinel.js +1157 -0
- package/dist/heart/core.js +2169 -581
- package/dist/heart/cross-chat-delivery.js +9 -22
- package/dist/heart/daemon/agent-config-check.js +451 -0
- package/dist/heart/daemon/agent-discovery.js +185 -3
- package/dist/heart/daemon/agent-service.js +542 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/await-private-wake.js +59 -0
- package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
- package/dist/heart/daemon/bluebubbles-host.js +273 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +180 -0
- package/dist/heart/daemon/cli-defaults.js +854 -0
- package/dist/heart/daemon/cli-desk.js +322 -0
- package/dist/heart/daemon/cli-exec.js +8822 -0
- package/dist/heart/daemon/cli-help.js +716 -0
- package/dist/heart/daemon/cli-parse.js +2771 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +777 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
- package/dist/heart/daemon/container-healthcheck.js +112 -0
- package/dist/heart/daemon/container-runtime.js +97 -0
- package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
- package/dist/heart/daemon/container-spec-auditor.js +229 -0
- package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
- package/dist/heart/daemon/daemon-cli.js +29 -2349
- package/dist/heart/daemon/daemon-entry.js +930 -11
- package/dist/heart/daemon/daemon-health.js +186 -0
- package/dist/heart/daemon/daemon-rollup.js +57 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +2084 -105
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +1755 -0
- package/dist/heart/daemon/freshness.js +345 -0
- package/dist/heart/daemon/habit-private-wake.js +61 -0
- package/dist/heart/daemon/health-monitor.js +142 -11
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
- package/dist/heart/daemon/http-health-probe.js +80 -0
- package/dist/heart/daemon/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +78 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +37 -8
- package/dist/heart/daemon/log-tailer.js +79 -10
- package/dist/heart/daemon/logs-prune.js +132 -0
- package/dist/heart/daemon/mcp-canary.js +524 -0
- package/dist/heart/daemon/message-router.js +65 -5
- package/dist/heart/daemon/migrate-to-desk.js +848 -0
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +22 -14
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/plugin-cli.js +432 -0
- package/dist/heart/daemon/process-manager.js +733 -61
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/prunable-bundle.js +144 -0
- package/dist/heart/daemon/pulse.js +511 -0
- package/dist/heart/daemon/readiness-repair.js +365 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +47 -14
- package/dist/heart/daemon/runtime-metadata.js +2 -30
- package/dist/heart/daemon/runtime-mode.js +13 -2
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
- package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
- package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
- package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
- package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
- package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
- package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
- package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
- package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +819 -0
- package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
- package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
- package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
- package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
- package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
- package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
- package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
- package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
- package/dist/heart/daemon/sanctuary-package-management.js +103 -0
- package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
- package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-service.js +630 -0
- package/dist/heart/daemon/sense-manager.js +699 -48
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +1 -1
- package/dist/heart/daemon/socket-client.js +180 -12
- package/dist/heart/daemon/stale-bundle-prune.js +113 -0
- package/dist/heart/daemon/startup-tui.js +339 -0
- package/dist/heart/daemon/supercronic-supervisor.js +282 -0
- package/dist/heart/daemon/task-scheduler.js +117 -39
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +138 -54
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +1 -4
- package/dist/heart/external-events/router.js +1430 -0
- package/dist/heart/frontend-approval-runtime.js +506 -0
- package/dist/heart/frontend-journal.js +215 -0
- package/dist/heart/frontend-session-service.js +237 -0
- package/dist/heart/frontend-socket-client.js +164 -0
- package/dist/heart/frontend-socket.js +400 -0
- package/dist/heart/habits/habit-cancel.js +810 -0
- package/dist/heart/habits/habit-lifecycle.js +1327 -0
- package/dist/heart/habits/habit-migration.js +194 -0
- package/dist/heart/habits/habit-parser.js +278 -0
- package/dist/heart/habits/habit-runtime-state.js +93 -0
- package/dist/heart/habits/habit-scheduler.js +653 -0
- package/dist/heart/habits/habit-session-summary.js +318 -0
- package/dist/heart/habits/habit-session.js +636 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
- package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
- package/dist/heart/identity.js +196 -59
- package/dist/heart/kept-notes.js +289 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +356 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +39 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +197 -0
- package/dist/heart/mailbox/readers/agent-machine.js +428 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
- package/dist/heart/mailbox/readers/mail.js +375 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
- package/dist/heart/mailbox/readers/sessions.js +231 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +696 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +11 -0
- package/dist/heart/orientation-frame.js +345 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/primitives.js +1 -1
- package/dist/heart/private-runtime/decision-renderer.js +158 -0
- package/dist/heart/private-runtime/index.js +18 -0
- package/dist/heart/private-runtime/ledger.js +221 -0
- package/dist/heart/private-runtime/policy.js +252 -0
- package/dist/heart/private-runtime/types.js +2 -0
- package/dist/heart/progress-story.js +1 -1
- package/dist/heart/provider-attempt.js +137 -0
- package/dist/heart/provider-binding-resolver.js +273 -0
- package/dist/heart/provider-credentials.js +449 -0
- package/dist/heart/provider-failover.js +311 -0
- package/dist/heart/provider-models.js +96 -0
- package/dist/heart/provider-ping.js +265 -0
- package/dist/heart/provider-readiness-cache.js +119 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +173 -60
- package/dist/heart/providers/azure.js +23 -11
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +34 -38
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex-token.js +349 -0
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/providers/openai-compatible.js +177 -0
- package/dist/heart/run-ledger.js +247 -0
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +607 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +22 -4
- package/dist/heart/session-activity.js +92 -24
- package/dist/heart/session-events.js +1504 -0
- package/dist/heart/session-playback-cli-main.js +5 -0
- package/dist/heart/session-playback-cli.js +36 -0
- package/dist/heart/session-playback.js +231 -0
- package/dist/heart/session-redaction-repair-cli-main.js +31 -0
- package/dist/heart/session-redaction-repair.js +552 -0
- package/dist/heart/session-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +183 -0
- package/dist/heart/session-transcript.js +133 -0
- package/dist/heart/start-of-turn-packet.js +372 -0
- package/dist/heart/steward-policy.js +618 -0
- package/dist/heart/streaming.js +604 -207
- package/dist/heart/structured-output.js +196 -0
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +449 -0
- package/dist/heart/target-resolution.js +11 -7
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/timeouts.js +101 -0
- package/dist/heart/tool-activity-callbacks.js +59 -0
- package/dist/heart/tool-approval.js +382 -0
- package/dist/heart/tool-description.js +155 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +482 -0
- package/dist/heart/turn-execution-lease.js +30 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +432 -0
- package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
- package/dist/heart/versioning/ouro-version-manager.js +409 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/versioning/update-hooks.js +154 -0
- package/dist/heart/versioning/version-intent.js +114 -0
- package/dist/heart/work-card.js +380 -0
- package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
- package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
- package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
- package/dist/mailbox-ui/index.html +16 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +889 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/cache-sync-cli.js +58 -0
- package/dist/mailroom/core.js +803 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +568 -0
- package/dist/mailroom/hosted-cache-sync.js +384 -0
- package/dist/mailroom/mbox-import.js +393 -0
- package/dist/mailroom/migration.js +164 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +292 -0
- package/dist/mailroom/search-cache.js +513 -0
- package/dist/mailroom/search-relevance.js +319 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/thread.js +109 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +24 -2
- package/dist/mind/context.js +309 -111
- package/dist/mind/desk-section.js +362 -0
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +68 -77
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/{associative-recall.js → note-search.js} +47 -58
- package/dist/mind/obligation-steering.js +199 -3
- package/dist/mind/pending.js +36 -10
- package/dist/mind/prompt-budget.js +479 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1050 -189
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/record-paths.js +312 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/session-transaction.js +564 -0
- package/dist/nerves/cli-logging.js +7 -1
- package/dist/nerves/coverage/audit-rules.js +15 -6
- package/dist/nerves/coverage/audit.js +28 -2
- package/dist/nerves/coverage/cli.js +1 -1
- package/dist/nerves/coverage/contract.js +5 -5
- package/dist/nerves/coverage/file-completeness.js +139 -5
- package/dist/nerves/coverage/run-artifacts.js +55 -35
- package/dist/nerves/coverage/source-scanner.js +4 -4
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +293 -9
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/redact.js +79 -0
- package/dist/nerves/review/cli-main.js +5 -0
- package/dist/nerves/review/cli.js +156 -0
- package/dist/nerves/review/core.js +159 -0
- package/dist/nerves/runtime.js +17 -1
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +16 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +1045 -0
- package/dist/repertoire/bundle-templates.js +71 -0
- package/dist/repertoire/bw-installer.js +180 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +331 -0
- package/dist/repertoire/coding/feedback.js +174 -32
- package/dist/repertoire/coding/index.js +15 -3
- package/dist/repertoire/coding/manager.js +159 -10
- package/dist/repertoire/coding/spawner.js +58 -11
- package/dist/repertoire/coding/tools.js +221 -15
- package/dist/repertoire/coding/workbench-client.js +272 -0
- package/dist/repertoire/coding/workbench-manager.js +346 -0
- package/dist/repertoire/commerce-errors.js +109 -0
- package/dist/repertoire/commerce-self-test.js +156 -0
- package/dist/repertoire/credential-access.js +178 -0
- package/dist/repertoire/desk/classifier.js +362 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +811 -18
- package/dist/repertoire/mcp-client.js +44 -3
- package/dist/repertoire/mcp-manager.js +427 -139
- package/dist/repertoire/mcp-tools.js +124 -0
- package/dist/repertoire/plugin-mcp.js +175 -0
- package/dist/repertoire/plugins.js +253 -0
- package/dist/repertoire/relationship-authorization.js +322 -0
- package/dist/repertoire/shell-sessions.js +134 -0
- package/dist/repertoire/skills.js +48 -4
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tool-arguments.js +170 -0
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-a2a.js +699 -0
- package/dist/repertoire/tools-attachments.js +322 -0
- package/dist/repertoire/tools-awaiting.js +575 -0
- package/dist/repertoire/tools-base.js +77 -1138
- package/dist/repertoire/tools-bluebubbles.js +2 -0
- package/dist/repertoire/tools-bridge.js +144 -0
- package/dist/repertoire/tools-bundle.js +993 -0
- package/dist/repertoire/tools-commerce.js +253 -0
- package/dist/repertoire/tools-config.js +186 -0
- package/dist/repertoire/tools-continuity.js +575 -0
- package/dist/repertoire/tools-credential.js +383 -0
- package/dist/repertoire/tools-evolution.js +527 -0
- package/dist/repertoire/tools-files.js +344 -0
- package/dist/repertoire/tools-flight.js +290 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +3 -8
- package/dist/repertoire/tools-habits.js +103 -0
- package/dist/repertoire/tools-mail.js +1828 -0
- package/dist/repertoire/tools-notes.js +485 -0
- package/dist/repertoire/tools-obligations.js +182 -0
- package/dist/repertoire/tools-orientation.js +31 -0
- package/dist/repertoire/tools-record.js +482 -0
- package/dist/repertoire/tools-rsvp.js +139 -0
- package/dist/repertoire/tools-runtime.js +150 -0
- package/dist/repertoire/tools-sanctuary-host.js +202 -0
- package/dist/repertoire/tools-session.js +1133 -0
- package/dist/repertoire/tools-shell.js +149 -0
- package/dist/repertoire/tools-steward-policy.js +119 -0
- package/dist/repertoire/tools-stripe.js +224 -0
- package/dist/repertoire/tools-surface.js +369 -0
- package/dist/repertoire/tools-teams.js +12 -39
- package/dist/repertoire/tools-telegram-contacts.js +37 -0
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +982 -0
- package/dist/repertoire/tools-unraid.js +531 -0
- package/dist/repertoire/tools-user-profile.js +146 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools-voice.js +145 -0
- package/dist/repertoire/tools.js +494 -148
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/unraid-client.js +155 -0
- package/dist/repertoire/unraid-restart.js +339 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +628 -0
- package/dist/rsvp/aisleplanner-client.js +354 -0
- package/dist/rsvp/cli.js +926 -0
- package/dist/rsvp/config.js +327 -0
- package/dist/rsvp/cutover.js +433 -0
- package/dist/rsvp/diagnostics.js +232 -0
- package/dist/rsvp/diff-renderer.js +176 -0
- package/dist/rsvp/habit-policy.js +110 -0
- package/dist/rsvp/habit-stage.js +123 -0
- package/dist/rsvp/incident-bundle.js +97 -0
- package/dist/rsvp/migration.js +204 -0
- package/dist/rsvp/native-habit-runner.js +630 -0
- package/dist/rsvp/outbound-state.js +628 -0
- package/dist/rsvp/query.js +118 -0
- package/dist/rsvp/replay.js +233 -0
- package/dist/rsvp/snapshot.js +232 -0
- package/dist/rsvp/spend-ledger.js +175 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/a2a-entry.js +115 -0
- package/dist/senses/acp-server.js +386 -0
- package/dist/senses/attention-queue.js +186 -0
- package/dist/senses/await-turn-message.js +58 -0
- package/dist/senses/bluebubbles/active-turns.js +216 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/bluebubbles/attachment-download.js +137 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
- package/dist/senses/bluebubbles/context-packet.js +207 -0
- package/dist/senses/bluebubbles/context-smoke.js +144 -0
- package/dist/senses/bluebubbles/entry.js +90 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
- package/dist/senses/bluebubbles/index.js +3841 -0
- package/dist/senses/bluebubbles/latest-turn.js +311 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
- package/dist/senses/bluebubbles/outbound-state.js +308 -0
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/reaction-policy.js +47 -0
- package/dist/senses/bluebubbles/replay.js +284 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
- package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- package/dist/senses/bluebubbles/webhook-registration.js +228 -0
- package/dist/senses/bluebubbles-meta-guard.js +39 -0
- package/dist/senses/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +287 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +607 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +85 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +241 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli.js +604 -320
- package/dist/senses/commands.js +66 -3
- package/dist/senses/context-packet-ledger.js +371 -0
- package/dist/senses/context-packets.js +154 -0
- package/dist/senses/habit-lifecycle-guard.js +24 -0
- package/dist/senses/habit-turn-message.js +160 -0
- package/dist/senses/ingress-evidence.js +2 -0
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +524 -0
- package/dist/senses/pipeline.js +1115 -204
- package/dist/senses/private-runtime-worker.js +859 -0
- package/dist/senses/private-runtime.js +1517 -0
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/root-host-approval-port.js +345 -0
- package/dist/senses/root-host-approval-runtime.js +393 -0
- package/dist/senses/sanctuary-authority-resident.js +102 -0
- package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
- package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
- package/dist/senses/sanctuary-grounding.js +118 -0
- package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
- package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
- package/dist/senses/sanctuary-health-runner.js +100 -0
- package/dist/senses/sanctuary-health.js +408 -0
- package/dist/senses/sanctuary-install-state-contract.js +126 -0
- package/dist/senses/sanctuary-interactive-control.js +410 -0
- package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
- package/dist/senses/sanctuary-media-optimization.js +514 -0
- package/dist/senses/sanctuary-runtime.js +340 -0
- package/dist/senses/sanctuary-sab.js +85 -0
- package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
- package/dist/senses/shared-turn.js +772 -0
- package/dist/senses/surface-tool.js +109 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +519 -218
- package/dist/senses/telegram-admission.js +718 -0
- package/dist/senses/telegram-approval-runtime.js +793 -0
- package/dist/senses/telegram-attachments.js +186 -0
- package/dist/senses/telegram-audit-ledger.js +220 -0
- package/dist/senses/telegram-authority-transport.js +231 -0
- package/dist/senses/telegram-client.js +1749 -0
- package/dist/senses/telegram-effect-adapter.js +896 -0
- package/dist/senses/telegram-entry.js +83 -0
- package/dist/senses/telegram.js +2324 -0
- package/dist/senses/trust-gate.js +104 -9
- package/dist/senses/voice/audio-playback.js +237 -0
- package/dist/senses/voice/audio-routing.js +119 -0
- package/dist/senses/voice/elevenlabs.js +202 -0
- package/dist/senses/voice/floor-control.js +431 -0
- package/dist/senses/voice/floor-controller.js +115 -0
- package/dist/senses/voice/golden-path.js +116 -0
- package/dist/senses/voice/index.js +29 -0
- package/dist/senses/voice/meeting.js +113 -0
- package/dist/senses/voice/outbound.js +190 -0
- package/dist/senses/voice/phone.js +33 -0
- package/dist/senses/voice/playback.js +139 -0
- package/dist/senses/voice/realtime-eval.js +496 -0
- package/dist/senses/voice/realtime-trace.js +531 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +191 -0
- package/dist/senses/voice/twilio-phone-runtime.js +807 -0
- package/dist/senses/voice/twilio-phone.js +5031 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +81 -0
- package/dist/senses/voice-realtime-eval-command.js +99 -0
- package/dist/senses/voice-realtime-eval-entry.js +21 -0
- package/dist/senses/voice-twilio-entry.js +87 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +265 -0
- package/dist/util/frontmatter.js +69 -0
- package/npm-shrinkwrap.json +8138 -0
- package/package.json +72 -13
- package/skills/agent-commerce.md +113 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +99 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -430
- package/dist/heart/daemon/ouro-path-installer.js +0 -260
- package/dist/heart/daemon/ouro-version-manager.js +0 -171
- package/dist/heart/daemon/update-hooks.js +0 -138
- package/dist/heart/obligations.js +0 -191
- package/dist/heart/safe-workspace.js +0 -228
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/friends/channel.js +0 -84
- package/dist/mind/friends/group-context.js +0 -144
- package/dist/mind/friends/resolver.js +0 -84
- package/dist/mind/friends/store-file.js +0 -190
- package/dist/mind/friends/store.js +0 -4
- package/dist/mind/friends/tokens.js +0 -26
- package/dist/mind/friends/trust-explanation.js +0 -74
- package/dist/mind/friends/types.js +0 -29
- package/dist/repertoire/tasks/board.js +0 -134
- package/dist/repertoire/tasks/index.js +0 -224
- package/dist/repertoire/tasks/lifecycle.js +0 -80
- package/dist/repertoire/tasks/middleware.js +0 -65
- package/dist/repertoire/tasks/parser.js +0 -173
- package/dist/repertoire/tasks/scanner.js +0 -132
- package/dist/repertoire/tasks/transitions.js +0 -144
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/bluebubbles.js +0 -1181
- package/dist/senses/debug-activity.js +0 -154
- package/dist/senses/inner-dialog-worker.js +0 -90
- package/dist/senses/inner-dialog.js +0 -525
- package/subagents/README.md +0 -7
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
- /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
- /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
- /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
- /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
- /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isSanctuaryCurrentStatusIntent = isSanctuaryCurrentStatusIntent;
|
|
4
|
+
exports.sanctuaryFullVisibilityEmptyResponse = sanctuaryFullVisibilityEmptyResponse;
|
|
5
|
+
exports.sanctuaryFullVisibilityRequiredToolCalls = sanctuaryFullVisibilityRequiredToolCalls;
|
|
6
|
+
exports.sanctuaryStaleDockerCareRequiredToolCalls = sanctuaryStaleDockerCareRequiredToolCalls;
|
|
7
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
|
+
const cares_1 = require("../arc/cares");
|
|
9
|
+
const runtime_1 = require("../nerves/runtime");
|
|
10
|
+
const REQUIRED_TOOL_NAMES = ["query_active_work", "query_cares", "unraid_get_system", "unraid_list_containers", "unraid_get_storage", "unraid_get_notifications", "sanctuary_get_download_queue"];
|
|
11
|
+
const WHOLE_STATUS_REQUESTS = new Set(["what are you working on", "what's going on with sanctuary"]);
|
|
12
|
+
function unsupportedCurrentClaim(answer, queueUnavailable, authorizedDockerClaims) {
|
|
13
|
+
if (queueUnavailable && answer.trim().length === 0)
|
|
14
|
+
return "Give Ari the current results that did complete and say plainly that the download queue is currently unavailable; do not return an empty answer.";
|
|
15
|
+
if (queueUnavailable) {
|
|
16
|
+
const unsupportedQueueClaim = answer.split(/[,;!?\n]|(?<!\d)\.(?!\d)/u).some((clause) => {
|
|
17
|
+
if (!/\b(?:download(?:s| queue)?|queue|SABnzbd)\b/iu.test(clause))
|
|
18
|
+
return false;
|
|
19
|
+
const explicitlyUnverified = /\b(?:(?:cannot|can't|could not|couldn't|unable to) (?:currently )?(?:be )?(?:verif(?:y|ied)|read|check(?:ed)?|confirm(?:ed)?)|(?:do not|don't) know(?: whether)?|unknown|unavailable|unverified|stale|historical|previous|prior|failed)\b|\bneeds? (?:a )?(?:fresh |authoritative )*(?:check|read|verification)\b/iu.test(clause);
|
|
20
|
+
return !explicitlyUnverified;
|
|
21
|
+
});
|
|
22
|
+
if (unsupportedQueueClaim)
|
|
23
|
+
return "The current download-queue read is unavailable. Preserve the other current results, but do not claim a queue state; say plainly that downloads could not be verified.";
|
|
24
|
+
}
|
|
25
|
+
const unsupported = answer.replace(/docker\.img/giu, "docker image").split(/[,;!?\n]|(?<!\d)\.(?!\d)/u).some((sentence) => {
|
|
26
|
+
if (!/docker image(?: disk)?/iu.test(sentence))
|
|
27
|
+
return false;
|
|
28
|
+
const normalizedSentence = sentence.normalize("NFKC").trim().toLocaleLowerCase("en-US");
|
|
29
|
+
if (authorizedDockerClaims.some((claim) => claim.normalize("NFKC").replace(/[.!?]+$/u, "").trim().toLocaleLowerCase("en-US") === normalizedSentence))
|
|
30
|
+
return false;
|
|
31
|
+
const uncertaintyOnly = /\b(?:cannot|can't|unable to) (?:currently )?(?:verify|measure)\b|\b(?:unknown|unverified)\b|\bneeds? (?:a )?(?:fresh |authoritative )*(?:check|measurement)\b/iu.test(sentence);
|
|
32
|
+
const stateClaim = /\b\d+(?:\.\d+)?\s*%|\bfull\b|\b(?:no|out of) space\b|\bwrites? (?:will |may )?fail\b|\b(?:healthy|unhealthy|running|stopped)\b/iu.test(sentence);
|
|
33
|
+
return stateClaim || !uncertaintyOnly;
|
|
34
|
+
});
|
|
35
|
+
if (unsupported)
|
|
36
|
+
return "No current Butler tool measures Docker image utilization. Do not report a Docker image percentage or full state as current; say that the stale care needs a fresh authoritative check.";
|
|
37
|
+
const unsupportedProviderClaim = answer.split(/[,;!?\n]|(?<!\d)\.(?!\d)/u).some((clause) => {
|
|
38
|
+
const explicitlyUnverified = /\b(?:cannot|can't|unable to) (?:currently )?(?:verify|confirm)|\b(?:unknown|unverified|stale|historical|previous|prior)\b|\bneeds? (?:a )?(?:fresh |authoritative )*(?:check|verification)\b/iu.test(clause);
|
|
39
|
+
if (explicitlyUnverified)
|
|
40
|
+
return false;
|
|
41
|
+
if (/\b(?:Astraweb|Usenet provider|download provider|(?:block|prepaid|download|provider) credit)\b/iu.test(clause))
|
|
42
|
+
return true;
|
|
43
|
+
return /\bSABnzbd\b/iu.test(clause) && /\b(?:auth(?:entication)?|authenticated|credentials?)\b/iu.test(clause);
|
|
44
|
+
});
|
|
45
|
+
return unsupportedProviderClaim ? "The current queue read does not prove provider credit or authentication status. Do not report Astraweb, block-credit, or authentication failure as current; say that the provider needs a fresh authoritative check." : undefined;
|
|
46
|
+
}
|
|
47
|
+
function exactQueueUnavailableResult(value) {
|
|
48
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
49
|
+
return false;
|
|
50
|
+
const result = value;
|
|
51
|
+
if (JSON.stringify(Object.keys(result).sort()) !== JSON.stringify(["error", "observedAt", "ok"]))
|
|
52
|
+
return false;
|
|
53
|
+
if (result.ok !== false || typeof result.observedAt !== "string" || !Number.isFinite(Date.parse(result.observedAt)) || new Date(result.observedAt).toISOString() !== result.observedAt)
|
|
54
|
+
return false;
|
|
55
|
+
const error = result.error;
|
|
56
|
+
return !!error && typeof error === "object" && !Array.isArray(error)
|
|
57
|
+
&& JSON.stringify(Object.keys(error).sort()) === JSON.stringify(["code"])
|
|
58
|
+
&& ["credential_unavailable", "request_unavailable", "malformed_response"].includes(String(error.code));
|
|
59
|
+
}
|
|
60
|
+
function successfulCurrentResult(name, result) {
|
|
61
|
+
if (Buffer.byteLength(result, "utf8") > 1_000_000)
|
|
62
|
+
return { valid: false, queueUnavailable: false };
|
|
63
|
+
if (name === "query_active_work")
|
|
64
|
+
return { valid: result.trimStart().startsWith("this is my current top-level live world-state."), queueUnavailable: false };
|
|
65
|
+
try {
|
|
66
|
+
const parsed = JSON.parse(result);
|
|
67
|
+
if (name === "query_cares")
|
|
68
|
+
return { valid: Array.isArray(parsed), queueUnavailable: false };
|
|
69
|
+
if (name === "unraid_get_notifications") {
|
|
70
|
+
const root = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
71
|
+
const error = root?.error && typeof root.error === "object" && !Array.isArray(root.error) ? root.error : null;
|
|
72
|
+
const unavailable = root?.ok === false
|
|
73
|
+
&& JSON.stringify(Object.keys(root).sort()) === JSON.stringify(["error", "ok"])
|
|
74
|
+
&& !!error && JSON.stringify(Object.keys(error).sort()) === JSON.stringify(["code", "degraded", "message"])
|
|
75
|
+
&& ["unauthorized", "forbidden", "timeout", "transport", "graphql", "invalid_response"].includes(String(error.code))
|
|
76
|
+
&& typeof error.message === "string" && Buffer.byteLength(error.message, "utf8") <= 512 && error.degraded === true;
|
|
77
|
+
if (unavailable)
|
|
78
|
+
return { valid: true, queueUnavailable: false };
|
|
79
|
+
const data = root?.data && typeof root.data === "object" && !Array.isArray(root.data) ? root.data : null;
|
|
80
|
+
return { valid: root?.ok === true && Array.isArray(data?.unacknowledged) && typeof data.truncated === "boolean", queueUnavailable: false };
|
|
81
|
+
}
|
|
82
|
+
if (name === "sanctuary_get_download_queue") {
|
|
83
|
+
if (exactQueueUnavailableResult(parsed))
|
|
84
|
+
return { valid: true, queueUnavailable: true };
|
|
85
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
86
|
+
return { valid: false, queueUnavailable: false };
|
|
87
|
+
const queue = parsed;
|
|
88
|
+
const exactKeys = ["observedAt", "paused", "queuedJobs", "stateDigest", "status"];
|
|
89
|
+
return { valid: JSON.stringify(Object.keys(queue).sort()) === JSON.stringify(exactKeys)
|
|
90
|
+
&& typeof queue.paused === "boolean"
|
|
91
|
+
&& typeof queue.status === "string" && Buffer.byteLength(queue.status, "utf8") <= 64
|
|
92
|
+
&& Number.isSafeInteger(queue.queuedJobs) && Number(queue.queuedJobs) >= 0 && Number(queue.queuedJobs) <= 1_000_000
|
|
93
|
+
&& typeof queue.observedAt === "string" && Number.isFinite(Date.parse(queue.observedAt)) && new Date(queue.observedAt).toISOString() === queue.observedAt
|
|
94
|
+
&& typeof queue.stateDigest === "string" && /^[a-f0-9]{64}$/u.test(queue.stateDigest), queueUnavailable: false };
|
|
95
|
+
}
|
|
96
|
+
return { valid: !!parsed && typeof parsed === "object" && !Array.isArray(parsed) && parsed.ok === true, queueUnavailable: false };
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return { valid: false, queueUnavailable: false };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function normalizedRequest(request) {
|
|
103
|
+
return request.normalize("NFKC").trim().toLocaleLowerCase("en-US").replace(/[‘’]/gu, "'").replace(/[^a-z0-9']+/gu, " ").trim();
|
|
104
|
+
}
|
|
105
|
+
function isSanctuaryCurrentStatusIntent(request) {
|
|
106
|
+
const normalized = normalizedRequest(request);
|
|
107
|
+
if (WHOLE_STATUS_REQUESTS.has(normalized))
|
|
108
|
+
return true;
|
|
109
|
+
if (["what's up", "everything good", "anything wrong"].includes(normalized))
|
|
110
|
+
return true;
|
|
111
|
+
if (!normalized || /\b(?:yesterday|tomorrow|document|movie request)\b/u.test(normalized))
|
|
112
|
+
return false;
|
|
113
|
+
if (/^do you care about\b/u.test(normalized) || /\b(?:plex|jellyfin|sonarr|radarr|docker labels?)\b/u.test(normalized))
|
|
114
|
+
return false;
|
|
115
|
+
const wholeScope = /\b(?:anything|everything|what(?:'s| is)|things?)\b/u.test(normalized);
|
|
116
|
+
const current = /\b(?:now|right now|currently|going on|status)\b/u.test(normalized);
|
|
117
|
+
const concern = /\b(?:care about|should (?:i|we) know about|working on|going on|status)\b/u.test(normalized);
|
|
118
|
+
return wholeScope && current && concern;
|
|
119
|
+
}
|
|
120
|
+
function sanctuaryFullVisibilityEmptyResponse(request) {
|
|
121
|
+
return isSanctuaryCurrentStatusIntent(request)
|
|
122
|
+
? "I couldn't finish a trustworthy Sanctuary status check because a current check was unavailable. I won't guess or reuse old alerts; please try again shortly."
|
|
123
|
+
: undefined;
|
|
124
|
+
}
|
|
125
|
+
function sanctuaryFullVisibilityRequiredToolCalls(request, _advertisedToolNames, authorizedDockerClaims = () => []) {
|
|
126
|
+
if (!isSanctuaryCurrentStatusIntent(request))
|
|
127
|
+
return undefined;
|
|
128
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.sanctuary_full_visibility_reads_required", message: "required current Sanctuary visibility reads", meta: { toolCount: REQUIRED_TOOL_NAMES.length } });
|
|
129
|
+
let queueUnavailable = false;
|
|
130
|
+
const completed = new Set();
|
|
131
|
+
return {
|
|
132
|
+
names: REQUIRED_TOOL_NAMES,
|
|
133
|
+
retryMessage: "Before answering, read current active work, cares, system health, service state, storage, notifications, and the download queue. Current tool facts outrank care history; a stale care is a recheck item, not a present-tense fact. Then give Ari one compact household summary; do not ask him to choose a status slice.",
|
|
134
|
+
requireSuccessfulResults: true,
|
|
135
|
+
validateRequiredToolResult: (name, result) => {
|
|
136
|
+
const validation = successfulCurrentResult(name, result);
|
|
137
|
+
if (name === "sanctuary_get_download_queue" && validation.valid)
|
|
138
|
+
queueUnavailable = validation.queueUnavailable;
|
|
139
|
+
if (validation.valid)
|
|
140
|
+
completed.add(name);
|
|
141
|
+
return validation.valid;
|
|
142
|
+
},
|
|
143
|
+
validateTerminalAnswer: (answer) => unsupportedCurrentClaim(answer, queueUnavailable, authorizedDockerClaims()),
|
|
144
|
+
emptyResponseFallback: () => REQUIRED_TOOL_NAMES.every((name) => completed.has(name)) ? sanctuaryFullVisibilityEmptyResponse(request) : undefined,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const SAFE_LABEL = "Docker image disk utilization";
|
|
148
|
+
const INCONCLUSIVE_RISK = "Docker image disk utilization verification is inconclusive.";
|
|
149
|
+
const ACTIVE_RISK = "A fresh Unraid notification reports high Docker image disk utilization.";
|
|
150
|
+
function qualifyingDockerCare(care, now) {
|
|
151
|
+
if ((0, cares_1.projectCareEvidence)(care, now) === care)
|
|
152
|
+
return undefined;
|
|
153
|
+
const binding = care.incidentBindings?.find(cares_1.isManagedDockerCareIncidentBinding);
|
|
154
|
+
return binding ? {
|
|
155
|
+
id: care.id, updatedAt: care.updatedAt, currentRisk: care.currentRisk, nextCheckAt: care.nextCheckAt, salience: care.salience, steward: care.steward, binding: { ...binding },
|
|
156
|
+
hasOtherUnresolvedBindings: care.incidentBindings.some((candidate) => candidate !== binding && !candidate.resolvedAt),
|
|
157
|
+
} : undefined;
|
|
158
|
+
}
|
|
159
|
+
function canonicalNotification(value) {
|
|
160
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
161
|
+
return undefined;
|
|
162
|
+
const notification = value;
|
|
163
|
+
return typeof notification.id === "string"
|
|
164
|
+
&& typeof notification.createdAt === "string"
|
|
165
|
+
&& Number.isFinite(Date.parse(notification.createdAt))
|
|
166
|
+
&& new Date(notification.createdAt).toISOString() === notification.createdAt
|
|
167
|
+
&& typeof notification.title === "string"
|
|
168
|
+
&& typeof notification.summary === "string"
|
|
169
|
+
&& typeof notification.severity === "string"
|
|
170
|
+
&& typeof notification.degraded === "boolean"
|
|
171
|
+
? notification
|
|
172
|
+
: undefined;
|
|
173
|
+
}
|
|
174
|
+
function notificationRevision(notification) {
|
|
175
|
+
return (0, node_crypto_1.createHash)("sha256").update(JSON.stringify({
|
|
176
|
+
id: notification.id,
|
|
177
|
+
createdAt: notification.createdAt,
|
|
178
|
+
severity: notification.severity,
|
|
179
|
+
title: notification.title,
|
|
180
|
+
summary: notification.summary,
|
|
181
|
+
degraded: notification.degraded,
|
|
182
|
+
})).digest("hex");
|
|
183
|
+
}
|
|
184
|
+
function dockerObservation(result, care) {
|
|
185
|
+
try {
|
|
186
|
+
const parsed = JSON.parse(result);
|
|
187
|
+
const data = parsed?.ok === true && parsed.data && typeof parsed.data === "object" && !Array.isArray(parsed.data) ? parsed.data : undefined;
|
|
188
|
+
if (!data || data.truncated !== false || !Array.isArray(data.unacknowledged))
|
|
189
|
+
return { outcome: "inconclusive" };
|
|
190
|
+
const boundary = Math.max(Date.parse(care.updatedAt), Date.parse(care.nextCheckAt));
|
|
191
|
+
const related = data.unacknowledged.map(canonicalNotification).filter((item) => !!item).filter((item) => {
|
|
192
|
+
const text = `${item.title} ${item.summary}`;
|
|
193
|
+
return item.degraded === false && Date.parse(String(item.createdAt)) > boundary && /docker/iu.test(text) && /image/iu.test(text) && /(?:disk|utilization)/iu.test(text);
|
|
194
|
+
});
|
|
195
|
+
if (related.length !== 1)
|
|
196
|
+
return { outcome: "inconclusive" };
|
|
197
|
+
const notification = related[0];
|
|
198
|
+
const text = `${notification.title} ${notification.summary}`;
|
|
199
|
+
const revision = notificationRevision(notification);
|
|
200
|
+
if (/\b(?:recover(?:ed|y)?|resolved|normal|healthy|cleared)\b/iu.test(text))
|
|
201
|
+
return { outcome: "fresh_recovered", revision };
|
|
202
|
+
if (/\b(?:critical|warning|error|full|high|9[0-9]%|100%)\b/iu.test(`${notification.severity} ${text}`)) {
|
|
203
|
+
return { outcome: "fresh_active", revision, risk: ACTIVE_RISK };
|
|
204
|
+
}
|
|
205
|
+
return { outcome: "inconclusive" };
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return { outcome: "inconclusive" };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function mutationFor(care, observation, now) {
|
|
212
|
+
const common = {
|
|
213
|
+
id: care.id,
|
|
214
|
+
source: care.binding.source,
|
|
215
|
+
incidentKey: care.binding.incidentKey,
|
|
216
|
+
expectedUpdatedAt: care.updatedAt,
|
|
217
|
+
label: SAFE_LABEL,
|
|
218
|
+
why: observation.outcome === "inconclusive" ? "Current Unraid notification evidence was inconclusive." : "Current Unraid notification evidence was checked.",
|
|
219
|
+
};
|
|
220
|
+
if (observation.outcome === "fresh_recovered") {
|
|
221
|
+
const unresolvedContextRemains = care.hasOtherUnresolvedBindings;
|
|
222
|
+
return {
|
|
223
|
+
...common,
|
|
224
|
+
action: "resolve_incident",
|
|
225
|
+
currentRisk: unresolvedContextRemains ? cares_1.CARE_INCIDENT_RECOVERY_REVIEW_RISK : "",
|
|
226
|
+
nextCheckAt: unresolvedContextRemains ? new Date(now + 15 * 60_000).toISOString() : "",
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
...common,
|
|
231
|
+
action: "upsert_incident",
|
|
232
|
+
kind: "system",
|
|
233
|
+
status: observation.outcome === "fresh_active" ? "active" : "watching",
|
|
234
|
+
salience: care.salience,
|
|
235
|
+
stewardship: care.steward,
|
|
236
|
+
classifiedRevision: observation.outcome === "fresh_active" ? observation.revision : care.binding.classifiedRevision,
|
|
237
|
+
currentRisk: observation.outcome === "fresh_active" ? observation.risk : INCONCLUSIVE_RISK,
|
|
238
|
+
nextCheckAt: new Date(now + 15 * 60_000).toISOString(),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function exactMutation(expected, actual) {
|
|
242
|
+
return Object.keys(expected).length === Object.keys(actual).length
|
|
243
|
+
&& Object.entries(expected).every(([key, value]) => actual[key] === value);
|
|
244
|
+
}
|
|
245
|
+
function sanctuaryStaleDockerCareRequiredToolCalls(activeCares, now, _advertisedToolNames) {
|
|
246
|
+
const cares = activeCares.map((care) => qualifyingDockerCare(care, now)).filter((care) => !!care);
|
|
247
|
+
if (cares.length === 0)
|
|
248
|
+
return undefined;
|
|
249
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.sanctuary_stale_docker_care_verification_required", message: "stale Docker Care requires current notification verification", meta: { careCount: cares.length } });
|
|
250
|
+
let verifierComplete = false;
|
|
251
|
+
let mutations = [];
|
|
252
|
+
const completed = new Set();
|
|
253
|
+
return {
|
|
254
|
+
names: ["unraid_get_notifications"],
|
|
255
|
+
get retryMessage() {
|
|
256
|
+
return mutations.length === 0
|
|
257
|
+
? "Recheck the stale Docker image disk Care from current notifications, then apply every exact evidence-bounded Care update before answering."
|
|
258
|
+
: `Apply these exact evidence-bounded care_manage arguments before answering: ${JSON.stringify(mutations)}.`;
|
|
259
|
+
},
|
|
260
|
+
requireSuccessfulResults: true,
|
|
261
|
+
validateRequiredToolResult: (name, result, args) => {
|
|
262
|
+
if (name === "unraid_get_notifications")
|
|
263
|
+
return Buffer.byteLength(result, "utf8") <= 1_000_000;
|
|
264
|
+
if (name !== "care_manage")
|
|
265
|
+
return false;
|
|
266
|
+
const expected = mutations.find((candidate) => exactMutation(candidate, args));
|
|
267
|
+
if (!expected)
|
|
268
|
+
return false;
|
|
269
|
+
try {
|
|
270
|
+
const care = JSON.parse(result);
|
|
271
|
+
const binding = care.incidentBindings?.find((candidate) => candidate.source === expected.source && candidate.incidentKey === expected.incidentKey);
|
|
272
|
+
const resolved = expected.action === "resolve_incident" ? !!binding?.resolvedAt : binding?.classifiedRevision === expected.classifiedRevision;
|
|
273
|
+
const updatedUnderCas = typeof care.updatedAt === "string" && Date.parse(care.updatedAt) > Date.parse(expected.expectedUpdatedAt);
|
|
274
|
+
const wholeCareResolutionValid = expected.action !== "resolve_incident" || expected.currentRisk !== "" || care.incidentBindings?.some((candidate) => !candidate.resolvedAt) || care.status === "resolved";
|
|
275
|
+
if (care.id !== expected.id || care.label !== SAFE_LABEL || care.why !== expected.why || care.currentRisk !== (expected.currentRisk || null) || care.nextCheckAt !== (expected.nextCheckAt || null) || (expected.status && care.status !== expected.status) || !resolved || !updatedUnderCas || !wholeCareResolutionValid)
|
|
276
|
+
return false;
|
|
277
|
+
completed.add(care.id);
|
|
278
|
+
return completed.size === mutations.length;
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
validateToolCallBeforeDispatch: (name, args) => {
|
|
285
|
+
if (name !== "care_manage")
|
|
286
|
+
return undefined;
|
|
287
|
+
if (!verifierComplete)
|
|
288
|
+
return "Read current Unraid notifications before mutating stale Docker Care.";
|
|
289
|
+
return mutations.some((candidate) => exactMutation(candidate, args)) ? undefined : `Only these exact evidence-bounded stale Docker Care mutations are authorized in this turn: ${JSON.stringify(mutations)}.`;
|
|
290
|
+
},
|
|
291
|
+
requiredToolCallsAfterResult: (name, _args, result) => {
|
|
292
|
+
if (name !== "unraid_get_notifications")
|
|
293
|
+
return [];
|
|
294
|
+
mutations = cares.map((care) => mutationFor(care, dockerObservation(result, care), now));
|
|
295
|
+
verifierComplete = true;
|
|
296
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.sanctuary_stale_docker_care_verification_completed", message: "current notification verification produced bounded Care outcomes", meta: { careCount: cares.length, mutationCount: mutations.length } });
|
|
297
|
+
return ["care_manage"];
|
|
298
|
+
},
|
|
299
|
+
expectedMutations: () => mutations.map((mutation) => ({ ...mutation })),
|
|
300
|
+
currentRiskClaims: () => mutations.filter((mutation) => mutation.currentRisk === ACTIVE_RISK).map((mutation) => mutation.currentRisk),
|
|
301
|
+
};
|
|
302
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanctuaryGroundingDigest = sanctuaryGroundingDigest;
|
|
4
|
+
exports.projectSanctuaryGrounding = projectSanctuaryGrounding;
|
|
5
|
+
exports.renderSanctuaryGroundedResponse = renderSanctuaryGroundedResponse;
|
|
6
|
+
exports.sanctuaryGroundedResponseAccurate = sanctuaryGroundedResponseAccurate;
|
|
7
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
|
+
const runtime_1 = require("../nerves/runtime");
|
|
9
|
+
function object(value, label) {
|
|
10
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
11
|
+
throw new Error(`${label} must be an object`);
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
function sanctuaryGroundingDigest(facts) {
|
|
15
|
+
return (0, node_crypto_1.createHash)("sha256").update(JSON.stringify(facts)).digest("hex");
|
|
16
|
+
}
|
|
17
|
+
function projectSanctuaryGrounding(toolName, result) {
|
|
18
|
+
if (toolName !== "unraid_get_system" && toolName !== "unraid_get_storage")
|
|
19
|
+
return null;
|
|
20
|
+
const envelope = object(result, "Sanctuary grounding result");
|
|
21
|
+
if (envelope.ok !== true)
|
|
22
|
+
throw new Error("Sanctuary grounding result must succeed");
|
|
23
|
+
const data = object(envelope.data, "Sanctuary grounding data");
|
|
24
|
+
if (toolName === "unraid_get_system") {
|
|
25
|
+
const exact = ["apiVersion", "arrayState", "degraded", "serverName", "sourceIdentityDigest", "unraidVersion", "uptimeSeconds"];
|
|
26
|
+
if (JSON.stringify(Object.keys(data).sort()) !== JSON.stringify(exact))
|
|
27
|
+
throw new Error("Sanctuary system grounding shape is invalid");
|
|
28
|
+
for (const key of ["serverName", "unraidVersion", "apiVersion", "arrayState"])
|
|
29
|
+
if (typeof data[key] !== "string" || !data[key])
|
|
30
|
+
throw new Error("Sanctuary system grounding value is invalid");
|
|
31
|
+
if (typeof data.degraded !== "boolean" || (data.uptimeSeconds !== null && (!Number.isSafeInteger(data.uptimeSeconds) || Number(data.uptimeSeconds) < 0)))
|
|
32
|
+
throw new Error("Sanctuary system grounding value is invalid");
|
|
33
|
+
const facts = { serverName: data.serverName, unraidVersion: data.unraidVersion, apiVersion: data.apiVersion, arrayState: data.arrayState, degraded: data.degraded };
|
|
34
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.sanctuary_grounding_projected", message: "Sanctuary grounding facts projected", meta: { toolName } });
|
|
35
|
+
return facts;
|
|
36
|
+
}
|
|
37
|
+
const exact = ["array", "shares", "sourceIdentityDigest", "truncated"];
|
|
38
|
+
if (JSON.stringify(Object.keys(data).sort()) !== JSON.stringify(exact) || !Array.isArray(data.shares) || typeof data.truncated !== "boolean")
|
|
39
|
+
throw new Error("Sanctuary storage grounding shape is invalid");
|
|
40
|
+
const array = object(data.array, "Sanctuary storage array grounding");
|
|
41
|
+
if (JSON.stringify(Object.keys(array).sort()) !== JSON.stringify(["degraded", "freeBytes", "state", "usedBytes", "usedPercent"]))
|
|
42
|
+
throw new Error("Sanctuary storage array grounding shape is invalid");
|
|
43
|
+
if (typeof array.state !== "string" || !array.state || typeof array.degraded !== "boolean"
|
|
44
|
+
|| ![array.usedBytes, array.freeBytes].every((value) => value === null || (Number.isSafeInteger(value) && Number(value) >= 0))
|
|
45
|
+
|| (array.usedPercent !== null && (typeof array.usedPercent !== "number" || !Number.isFinite(array.usedPercent))))
|
|
46
|
+
throw new Error("Sanctuary storage array grounding value is invalid");
|
|
47
|
+
const { sourceIdentityDigest: _sourceIdentityDigest, ...facts } = data;
|
|
48
|
+
(0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.sanctuary_grounding_projected", message: "Sanctuary grounding facts projected", meta: { toolName } });
|
|
49
|
+
return structuredClone(facts);
|
|
50
|
+
}
|
|
51
|
+
function normalized(value) {
|
|
52
|
+
return value.normalize("NFKC").toLocaleLowerCase("en-US");
|
|
53
|
+
}
|
|
54
|
+
function regexEscape(value) {
|
|
55
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
56
|
+
}
|
|
57
|
+
function systemResponseAccurate(facts, response) {
|
|
58
|
+
if (typeof facts.serverName !== "string" || typeof facts.unraidVersion !== "string" || typeof facts.arrayState !== "string" || typeof facts.degraded !== "boolean")
|
|
59
|
+
return false;
|
|
60
|
+
const pattern = new RegExp(`^${regexEscape(normalized(facts.serverName))} is running unraid ${regexEscape(normalized(facts.unraidVersion))}(?:; the array is| with the array) ${regexEscape(normalized(facts.arrayState))} and (not degraded|healthy|nominal|degraded|unhealthy)\\.?$`, "u");
|
|
61
|
+
const match = pattern.exec(response);
|
|
62
|
+
if (!match)
|
|
63
|
+
return false;
|
|
64
|
+
return facts.degraded ? match[1] === "degraded" || match[1] === "unhealthy" : match[1] === "not degraded" || match[1] === "healthy" || match[1] === "nominal";
|
|
65
|
+
}
|
|
66
|
+
function byteAmount(amount, unit) {
|
|
67
|
+
const divisors = { tb: 1_000_000_000_000, tib: 1_099_511_627_776, gb: 1_000_000_000, gib: 1_073_741_824, byte: 1, bytes: 1 };
|
|
68
|
+
return Number(amount) * divisors[unit];
|
|
69
|
+
}
|
|
70
|
+
function storageResponseAccurate(facts, response) {
|
|
71
|
+
const array = object(facts.array, "Sanctuary response storage facts");
|
|
72
|
+
if (typeof array.freeBytes !== "number" || typeof array.usedPercent !== "number" || typeof array.state !== "string" || typeof array.degraded !== "boolean")
|
|
73
|
+
return false;
|
|
74
|
+
const pattern = /^(?:there is|about) (\d+(?:\.\d+)?)\s*(tb|tib|gb|gib|bytes?) (?:is )?(?:available|free|left)(?:;|,| and) (?:(?:the array is )(\d+(?:\.\d+)?)\s*%\s*(?:used|full)|(?:usage is )(\d+(?:\.\d+)?)\s*%)\.(?: the array is ([\p{L}\p{N}_-]+) and (not degraded|healthy|nominal|degraded|unhealthy)\.)?$/u;
|
|
75
|
+
const match = pattern.exec(response);
|
|
76
|
+
if (!match)
|
|
77
|
+
return false;
|
|
78
|
+
const bytesAccurate = Math.abs(byteAmount(match[1], match[2]) - array.freeBytes) <= Math.max(1, array.freeBytes * 0.025);
|
|
79
|
+
const percentAccurate = Math.abs(Number(match[3] ?? match[4]) - array.usedPercent) <= 0.51;
|
|
80
|
+
if (!bytesAccurate || !percentAccurate)
|
|
81
|
+
return false;
|
|
82
|
+
if (match[5] === undefined && match[6] === undefined)
|
|
83
|
+
return true;
|
|
84
|
+
const healthAccurate = array.degraded ? match[6] === "degraded" || match[6] === "unhealthy" : match[6] === "not degraded" || match[6] === "healthy" || match[6] === "nominal";
|
|
85
|
+
return normalized(String(match[5])) === normalized(array.state) && healthAccurate;
|
|
86
|
+
}
|
|
87
|
+
function compactNumber(value) {
|
|
88
|
+
return value.toFixed(2).replace(/\.0+$/u, "").replace(/(\.\d*?)0+$/u, "$1");
|
|
89
|
+
}
|
|
90
|
+
function renderSanctuaryGroundedResponse(toolName, facts) {
|
|
91
|
+
let response;
|
|
92
|
+
if (toolName === "unraid_get_system") {
|
|
93
|
+
if (typeof facts.serverName !== "string" || typeof facts.unraidVersion !== "string" || typeof facts.arrayState !== "string" || typeof facts.degraded !== "boolean")
|
|
94
|
+
throw new Error("Sanctuary system response facts are invalid");
|
|
95
|
+
response = `${facts.serverName} is running Unraid ${facts.unraidVersion} with the array ${facts.arrayState} and ${facts.degraded ? "degraded" : "not degraded"}.`;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const array = object(facts.array, "Sanctuary storage response facts");
|
|
99
|
+
if (typeof array.freeBytes !== "number" || typeof array.usedPercent !== "number")
|
|
100
|
+
throw new Error("Sanctuary storage response facts are invalid");
|
|
101
|
+
const units = [[1_000_000_000_000, "TB"], [1_000_000_000, "GB"], [1, "bytes"]];
|
|
102
|
+
const freeBytes = Number(array.freeBytes);
|
|
103
|
+
const usedPercent = Number(array.usedPercent);
|
|
104
|
+
const [divisor, unit] = units.find(([candidate]) => freeBytes >= candidate) ?? units[units.length - 1];
|
|
105
|
+
response = `There is ${compactNumber(freeBytes / divisor)} ${unit} free and the array is ${compactNumber(usedPercent)}% used.`;
|
|
106
|
+
}
|
|
107
|
+
(0, runtime_1.emitNervesEvent)({
|
|
108
|
+
component: "senses",
|
|
109
|
+
event: "senses.sanctuary_grounded_response_rendered",
|
|
110
|
+
message: "Rendered a deterministic Sanctuary response from grounded facts",
|
|
111
|
+
meta: { toolName },
|
|
112
|
+
});
|
|
113
|
+
return response;
|
|
114
|
+
}
|
|
115
|
+
function sanctuaryGroundedResponseAccurate(toolName, facts, responseText) {
|
|
116
|
+
const response = normalized(responseText);
|
|
117
|
+
return toolName === "unraid_get_system" ? systemResponseAccurate(facts, response) : storageResponseAccurate(facts, response);
|
|
118
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const sanctuary_health_acceptance_probe_1 = require("./sanctuary-health-acceptance-probe");
|
|
5
|
+
const runtime_1 = require("../nerves/runtime");
|
|
6
|
+
(0, runtime_1.emitNervesEvent)({
|
|
7
|
+
component: "senses",
|
|
8
|
+
event: "senses.entry_boot",
|
|
9
|
+
message: "booting Sanctuary health acceptance probe entrypoint",
|
|
10
|
+
meta: { entry: "sanctuary-health-acceptance-probe" },
|
|
11
|
+
});
|
|
12
|
+
(0, sanctuary_health_acceptance_probe_1.startSanctuaryHealthAcceptanceProbeCli)(process.argv.slice(2), (0, sanctuary_health_acceptance_probe_1.createSanctuaryHealthAcceptanceProbeCliOutput)());
|