@ouro.bot/cli 0.1.0-alpha.60 → 0.1.0-alpha.600
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/README.md +127 -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/changelog.json +3857 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +254 -0
- package/dist/arc/packets.js +193 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +65 -0
- package/dist/heart/active-work.js +837 -26
- package/dist/heart/agent-entry.js +69 -3
- 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/adapter.js +2 -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 +16 -0
- package/dist/heart/attachments/store.js +103 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +479 -0
- package/dist/heart/awaiting/await-alert.js +146 -0
- package/dist/heart/awaiting/await-expiry.js +108 -0
- package/dist/heart/awaiting/await-loader.js +91 -0
- package/dist/heart/awaiting/await-parser.js +141 -0
- package/dist/heart/awaiting/await-runtime-state.js +97 -0
- package/dist/heart/awaiting/await-scheduler.js +377 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +142 -0
- package/dist/heart/config-registry.js +322 -0
- package/dist/heart/config.js +114 -119
- package/dist/heart/core.js +909 -246
- package/dist/heart/cross-chat-delivery.js +3 -18
- package/dist/heart/daemon/agent-config-check.js +419 -0
- package/dist/heart/daemon/agent-discovery.js +102 -3
- package/dist/heart/daemon/agent-service.js +522 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +776 -0
- package/dist/heart/daemon/cli-exec.js +7571 -0
- package/dist/heart/daemon/cli-help.js +498 -0
- package/dist/heart/daemon/cli-parse.js +1599 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +763 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/daemon-cli.js +29 -1703
- package/dist/heart/daemon/daemon-entry.js +485 -2
- package/dist/heart/daemon/daemon-health.js +176 -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 +842 -69
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +873 -0
- package/dist/heart/daemon/health-monitor.js +122 -1
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +115 -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 +89 -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 +78 -9
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +14 -12
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/process-manager.js +375 -33
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/pulse.js +475 -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 +10 -2
- package/dist/heart/daemon/runtime-metadata.js +2 -30
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +462 -38
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +158 -11
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +330 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +162 -17
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +1 -1
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +140 -0
- package/dist/heart/habits/habit-runtime-state.js +100 -0
- package/dist/heart/habits/habit-scheduler.js +372 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
- 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 +35 -12
- package/dist/heart/identity.js +166 -55
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +353 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +31 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +195 -0
- package/dist/heart/mailbox/readers/agent-machine.js +382 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
- package/dist/heart/mailbox/readers/mail.js +367 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
- package/dist/heart/mailbox/readers/sessions.js +232 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +656 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +19 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +267 -0
- package/dist/heart/provider-credentials.js +425 -0
- package/dist/heart/provider-failover.js +301 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-readiness-cache.js +40 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +139 -52
- package/dist/heart/providers/azure.js +23 -11
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +145 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +367 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +13 -4
- package/dist/heart/session-activity.js +43 -22
- package/dist/heart/session-events.js +1149 -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-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +182 -0
- package/dist/heart/session-transcript.js +243 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +44 -27
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +449 -0
- package/dist/heart/target-resolution.js +9 -5
- 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-description.js +143 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +421 -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 +426 -0
- package/dist/heart/versioning/ouro-version-manager.js +295 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
- package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/mailbox-ui/index.html +15 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +700 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/core.js +788 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +457 -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 +233 -0
- package/dist/mailroom/search-cache.js +268 -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 +7 -1
- package/dist/mind/context.js +165 -101
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +62 -75
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +39 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +39 -3
- package/dist/mind/friends/types.js +2 -2
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/note-search.js +268 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +4 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1050 -135
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -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 +129 -5
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +224 -4
- 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 +152 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +997 -0
- package/dist/repertoire/bundle-templates.js +72 -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 +330 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +158 -9
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +170 -7
- 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/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 +396 -0
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +362 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +15 -24
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +31 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +16 -4
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +16 -78
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-awaiting.js +360 -0
- package/dist/repertoire/tools-base.js +53 -1082
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +142 -0
- package/dist/repertoire/tools-bundle.js +984 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +381 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1916 -0
- package/dist/repertoire/tools-notes.js +421 -0
- package/dist/repertoire/tools-obligations.js +142 -0
- package/dist/repertoire/tools-runtime.js +61 -0
- package/dist/repertoire/tools-session.js +809 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +345 -0
- package/dist/repertoire/tools-teams.js +9 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +604 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools-voice.js +144 -0
- package/dist/repertoire/tools.js +115 -103
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +594 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +116 -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} +219 -18
- package/dist/senses/bluebubbles/entry.js +77 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
- package/dist/senses/bluebubbles/index.js +2548 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/replay.js +137 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- package/dist/senses/bluebubbles-meta-guard.js +40 -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 +240 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli-layout.js +100 -0
- package/dist/senses/cli.js +516 -204
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +185 -21
- package/dist/senses/inner-dialog.js +372 -27
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +654 -181
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +392 -0
- package/dist/senses/surface-tool.js +70 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +387 -98
- package/dist/senses/trust-gate.js +100 -5
- 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 +5077 -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/package.json +41 -7
- package/skills/agent-commerce.md +106 -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 -351
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -166
- package/dist/heart/safe-workspace.js +0 -228
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/associative-recall.js +0 -209
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/bluebubbles.js +0 -1177
- package/dist/senses/debug-activity.js +0 -148
- package/subagents/README.md +0 -86
- package/subagents/work-doer.md +0 -237
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -390
- /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/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
|
@@ -41,6 +41,9 @@ exports.readTaskFile = readTaskFile;
|
|
|
41
41
|
exports.buildTaskTriggeredMessage = buildTaskTriggeredMessage;
|
|
42
42
|
exports.deriveResumeCheckpoint = deriveResumeCheckpoint;
|
|
43
43
|
exports.innerDialogSessionPath = innerDialogSessionPath;
|
|
44
|
+
exports.enrichDelegatedFromWithBridge = enrichDelegatedFromWithBridge;
|
|
45
|
+
exports.routeDelegatedCompletion = routeDelegatedCompletion;
|
|
46
|
+
exports.buildParseErrorNudge = buildParseErrorNudge;
|
|
44
47
|
exports.runInnerDialogTurn = runInnerDialogTurn;
|
|
45
48
|
const fs = __importStar(require("fs"));
|
|
46
49
|
const path = __importStar(require("path"));
|
|
@@ -49,8 +52,13 @@ const core_1 = require("../heart/core");
|
|
|
49
52
|
const identity_1 = require("../heart/identity");
|
|
50
53
|
const context_1 = require("../mind/context");
|
|
51
54
|
const prompt_1 = require("../mind/prompt");
|
|
55
|
+
const mcp_manager_1 = require("../repertoire/mcp-manager");
|
|
56
|
+
const tools_1 = require("../repertoire/tools");
|
|
52
57
|
const bundle_manifest_1 = require("../mind/bundle-manifest");
|
|
53
58
|
const pending_1 = require("../mind/pending");
|
|
59
|
+
const obligations_1 = require("../arc/obligations");
|
|
60
|
+
const attention_queue_1 = require("./attention-queue");
|
|
61
|
+
const packets_1 = require("../arc/packets");
|
|
54
62
|
const channel_1 = require("../mind/friends/channel");
|
|
55
63
|
const trust_gate_1 = require("./trust-gate");
|
|
56
64
|
const tokens_1 = require("../mind/friends/tokens");
|
|
@@ -60,6 +68,15 @@ const runtime_1 = require("../nerves/runtime");
|
|
|
60
68
|
const manager_1 = require("../heart/bridges/manager");
|
|
61
69
|
const session_activity_1 = require("../heart/session-activity");
|
|
62
70
|
const bluebubbles_1 = require("./bluebubbles");
|
|
71
|
+
const habit_turn_message_1 = require("./habit-turn-message");
|
|
72
|
+
const await_turn_message_1 = require("./await-turn-message");
|
|
73
|
+
const await_parser_1 = require("../heart/awaiting/await-parser");
|
|
74
|
+
const await_runtime_state_1 = require("../heart/awaiting/await-runtime-state");
|
|
75
|
+
const journal_index_1 = require("../mind/journal-index");
|
|
76
|
+
const habit_parser_1 = require("../heart/habits/habit-parser");
|
|
77
|
+
const habit_runtime_state_1 = require("../heart/habits/habit-runtime-state");
|
|
78
|
+
const cadence_1 = require("../heart/daemon/cadence");
|
|
79
|
+
const daemon_health_1 = require("../heart/daemon/daemon-health");
|
|
63
80
|
const DEFAULT_INNER_DIALOG_INSTINCTS = [
|
|
64
81
|
{
|
|
65
82
|
id: "heartbeat_checkin",
|
|
@@ -98,23 +115,31 @@ function buildNonCanonicalCleanupNudge(nonCanonicalPaths) {
|
|
|
98
115
|
}
|
|
99
116
|
return [
|
|
100
117
|
"## canonical cleanup nudge",
|
|
101
|
-
"I found non-canonical files in my bundle. I should distill anything valuable into
|
|
118
|
+
"I found non-canonical files in my bundle. I should distill anything valuable into my diary and remove these files.",
|
|
102
119
|
...listed,
|
|
103
120
|
].join("\n");
|
|
104
121
|
}
|
|
122
|
+
function displayCheckpoint(checkpoint) {
|
|
123
|
+
const trimmed = checkpoint?.trim();
|
|
124
|
+
if (!trimmed || trimmed === "no prior checkpoint recorded") {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
return trimmed;
|
|
128
|
+
}
|
|
105
129
|
function buildInstinctUserMessage(instincts, _reason, state) {
|
|
106
130
|
const active = instincts.find((instinct) => instinct.enabled !== false) ?? DEFAULT_INNER_DIALOG_INSTINCTS[0];
|
|
107
|
-
const checkpoint = state.checkpoint
|
|
131
|
+
const checkpoint = displayCheckpoint(state.checkpoint);
|
|
108
132
|
const lines = [active.prompt];
|
|
109
133
|
if (checkpoint) {
|
|
110
|
-
lines.push(`\nlast
|
|
134
|
+
lines.push(`\nlast checkpoint: ${checkpoint}`);
|
|
111
135
|
}
|
|
112
136
|
return lines.join("\n");
|
|
113
137
|
}
|
|
114
138
|
function readTaskFile(agentRoot, taskId) {
|
|
115
|
-
// Task files live in collection subdirectories (one-shots, ongoing
|
|
139
|
+
// Task files live in collection subdirectories (one-shots, ongoing).
|
|
116
140
|
// Try each collection, then fall back to root tasks/ for legacy layout.
|
|
117
|
-
|
|
141
|
+
// Habits are no longer in tasks/ — they live at bundle root habits/.
|
|
142
|
+
const collections = ["one-shots", "ongoing", ""];
|
|
118
143
|
for (const collection of collections) {
|
|
119
144
|
try {
|
|
120
145
|
return fs.readFileSync(path.join(agentRoot, "tasks", collection, `${taskId}.md`), "utf8").trim();
|
|
@@ -133,8 +158,9 @@ function buildTaskTriggeredMessage(taskId, taskContent, checkpoint) {
|
|
|
133
158
|
else {
|
|
134
159
|
lines.push("", `## task: ${taskId}`, "(task file not found)");
|
|
135
160
|
}
|
|
136
|
-
|
|
137
|
-
|
|
161
|
+
const renderedCheckpoint = displayCheckpoint(checkpoint);
|
|
162
|
+
if (renderedCheckpoint) {
|
|
163
|
+
lines.push("", `last checkpoint: ${renderedCheckpoint}`);
|
|
138
164
|
}
|
|
139
165
|
return lines.join("\n");
|
|
140
166
|
}
|
|
@@ -164,19 +190,17 @@ function deriveResumeCheckpoint(messages) {
|
|
|
164
190
|
const assistantText = contentToText(lastAssistant.content);
|
|
165
191
|
if (!assistantText)
|
|
166
192
|
return "no prior checkpoint recorded";
|
|
167
|
-
const
|
|
193
|
+
const cleanedLines = assistantText
|
|
168
194
|
.split("\n")
|
|
169
|
-
.map((line) => line.trim())
|
|
195
|
+
.map((line) => line.replace(/<\/?think>/gi, "").trim())
|
|
196
|
+
.filter((line) => line.length > 0);
|
|
197
|
+
const explicitCheckpoint = cleanedLines
|
|
170
198
|
.find((line) => /^checkpoint\s*:/i.test(line));
|
|
171
199
|
if (explicitCheckpoint) {
|
|
172
200
|
const parsed = explicitCheckpoint.replace(/^checkpoint\s*:\s*/i, "").trim();
|
|
173
201
|
return parsed || "no prior checkpoint recorded";
|
|
174
202
|
}
|
|
175
|
-
const firstLine =
|
|
176
|
-
.split("\n")
|
|
177
|
-
.map((line) => line.trim())
|
|
178
|
-
.find((line) => line.length > 0);
|
|
179
|
-
/* v8 ignore next -- unreachable: contentToText().trim() guarantees a non-empty line @preserve */
|
|
203
|
+
const firstLine = cleanedLines[0];
|
|
180
204
|
if (!firstLine)
|
|
181
205
|
return "no prior checkpoint recorded";
|
|
182
206
|
if (firstLine.length <= 220)
|
|
@@ -247,6 +271,7 @@ function writeInnerDialogRuntimeState(sessionFilePath, state) {
|
|
|
247
271
|
});
|
|
248
272
|
}
|
|
249
273
|
}
|
|
274
|
+
/* v8 ignore start -- routing helpers: called from routing functions which are integration paths @preserve */
|
|
250
275
|
function writePendingEnvelope(pendingDir, message) {
|
|
251
276
|
fs.mkdirSync(pendingDir, { recursive: true });
|
|
252
277
|
const fileName = `${message.timestamp}-${Math.random().toString(36).slice(2, 10)}.json`;
|
|
@@ -258,6 +283,8 @@ function sessionMatchesActivity(activity, session) {
|
|
|
258
283
|
&& activity.channel === session.channel
|
|
259
284
|
&& activity.key === session.key;
|
|
260
285
|
}
|
|
286
|
+
/* v8 ignore stop */
|
|
287
|
+
/* v8 ignore start -- routing: delivery now inline via surface tool; routing functions preserved for reuse @preserve */
|
|
261
288
|
function resolveBridgePreferredSession(delegatedFrom, sessionActivity) {
|
|
262
289
|
if (!delegatedFrom.bridgeId)
|
|
263
290
|
return null;
|
|
@@ -277,15 +304,82 @@ async function tryDeliverDelegatedCompletion(target, outboundEnvelope) {
|
|
|
277
304
|
friendId: target.friendId,
|
|
278
305
|
sessionKey: target.key,
|
|
279
306
|
text: outboundEnvelope.content,
|
|
307
|
+
intent: "explicit_cross_chat",
|
|
280
308
|
});
|
|
281
309
|
return result.delivered;
|
|
282
310
|
}
|
|
311
|
+
function enrichDelegatedFromWithBridge(delegatedFrom) {
|
|
312
|
+
if (delegatedFrom.bridgeId) {
|
|
313
|
+
return delegatedFrom;
|
|
314
|
+
}
|
|
315
|
+
const bridgeManager = (0, manager_1.createBridgeManager)();
|
|
316
|
+
const originBridges = bridgeManager.findBridgesForSession({
|
|
317
|
+
friendId: delegatedFrom.friendId,
|
|
318
|
+
channel: delegatedFrom.channel,
|
|
319
|
+
key: delegatedFrom.key,
|
|
320
|
+
});
|
|
321
|
+
const activeBridge = originBridges.find((b) => b.lifecycle === "active");
|
|
322
|
+
if (activeBridge) {
|
|
323
|
+
return { ...delegatedFrom, bridgeId: activeBridge.id };
|
|
324
|
+
}
|
|
325
|
+
return delegatedFrom;
|
|
326
|
+
}
|
|
327
|
+
function advanceObligationQuietly(agentName, obligationId, update) {
|
|
328
|
+
if (!obligationId)
|
|
329
|
+
return;
|
|
330
|
+
try {
|
|
331
|
+
(0, obligations_1.advanceReturnObligation)(agentName, obligationId, update);
|
|
332
|
+
/* v8 ignore start -- best-effort: obligation fs errors must never block return routing @preserve */
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
// swallowed
|
|
336
|
+
}
|
|
337
|
+
/* v8 ignore stop */
|
|
338
|
+
}
|
|
283
339
|
async function routeDelegatedCompletion(agentRoot, agentName, completion, drainedPending, timestamp) {
|
|
284
340
|
const delegated = (drainedPending ?? []).find((message) => message.delegatedFrom);
|
|
285
341
|
if (!delegated?.delegatedFrom || !completion?.answer?.trim()) {
|
|
286
342
|
return;
|
|
287
343
|
}
|
|
288
|
-
const delegatedFrom = delegated.delegatedFrom;
|
|
344
|
+
const delegatedFrom = enrichDelegatedFromWithBridge(delegated.delegatedFrom);
|
|
345
|
+
const obligationId = delegated.obligationId;
|
|
346
|
+
// Advance any inner return obligations from queued -> running (they were drained this turn).
|
|
347
|
+
// drainedPending is guaranteed non-null here (we found delegated above).
|
|
348
|
+
for (const msg of drainedPending) {
|
|
349
|
+
if (msg.obligationId) {
|
|
350
|
+
advanceObligationQuietly(agentName, msg.obligationId, {
|
|
351
|
+
status: "running",
|
|
352
|
+
startedAt: timestamp,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (delegated.obligationStatus === "pending") {
|
|
357
|
+
// Fulfill the persistent obligation in the store
|
|
358
|
+
try {
|
|
359
|
+
const pending = (0, obligations_1.findPendingObligationForOrigin)(agentRoot, {
|
|
360
|
+
friendId: delegatedFrom.friendId,
|
|
361
|
+
channel: delegatedFrom.channel,
|
|
362
|
+
key: delegatedFrom.key,
|
|
363
|
+
});
|
|
364
|
+
/* v8 ignore next 2 -- obligation fulfillment tested via obligations.test.ts; integration requires real disk state @preserve */
|
|
365
|
+
if (pending) {
|
|
366
|
+
(0, obligations_1.fulfillObligation)(agentRoot, pending.id);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
/* v8 ignore next -- defensive: obligation store read failure should not break delivery @preserve */
|
|
371
|
+
}
|
|
372
|
+
(0, runtime_1.emitNervesEvent)({
|
|
373
|
+
event: "senses.obligation_fulfilled",
|
|
374
|
+
component: "senses",
|
|
375
|
+
message: "obligation fulfilled via delegated completion",
|
|
376
|
+
meta: {
|
|
377
|
+
friendId: delegatedFrom.friendId,
|
|
378
|
+
channel: delegatedFrom.channel,
|
|
379
|
+
key: delegatedFrom.key,
|
|
380
|
+
},
|
|
381
|
+
});
|
|
382
|
+
}
|
|
289
383
|
const outboundEnvelope = {
|
|
290
384
|
from: agentName,
|
|
291
385
|
friendId: delegatedFrom.friendId,
|
|
@@ -294,36 +388,62 @@ async function routeDelegatedCompletion(agentRoot, agentName, completion, draine
|
|
|
294
388
|
content: completion.answer.trim(),
|
|
295
389
|
timestamp,
|
|
296
390
|
delegatedFrom,
|
|
391
|
+
...(obligationId ? { obligationId } : {}),
|
|
297
392
|
};
|
|
298
393
|
const sessionActivity = (0, session_activity_1.listSessionActivity)({
|
|
299
394
|
sessionsDir: path.join(agentRoot, "state", "sessions"),
|
|
300
395
|
friendsDir: path.join(agentRoot, "friends"),
|
|
301
396
|
agentName,
|
|
302
397
|
});
|
|
398
|
+
// Priority 1: Bridge-preferred session (if delegation was within a bridge).
|
|
303
399
|
const bridgeTarget = resolveBridgePreferredSession(delegatedFrom, sessionActivity);
|
|
304
400
|
if (bridgeTarget) {
|
|
305
401
|
if (await tryDeliverDelegatedCompletion(bridgeTarget, outboundEnvelope)) {
|
|
402
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "bridge-session" });
|
|
306
403
|
return;
|
|
307
404
|
}
|
|
308
405
|
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, bridgeTarget.friendId, bridgeTarget.channel, bridgeTarget.key), outboundEnvelope);
|
|
406
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "bridge-session" });
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
// Priority 1.5: Direct return to originating session (ponder without bridge).
|
|
410
|
+
// When delegatedFrom has specific channel+key, route directly there instead of searching for freshest.
|
|
411
|
+
if (delegatedFrom.channel && delegatedFrom.key && delegatedFrom.channel !== "inner") {
|
|
412
|
+
const directTarget = sessionActivity.find((a) => a.friendId === delegatedFrom.friendId && a.channel === delegatedFrom.channel && a.key === delegatedFrom.key);
|
|
413
|
+
if (directTarget) {
|
|
414
|
+
if (await tryDeliverDelegatedCompletion(directTarget, outboundEnvelope)) {
|
|
415
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "direct-originator" });
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// Even if session isn't in activity list (might have ended), queue to its pending dir
|
|
420
|
+
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, delegatedFrom.friendId, delegatedFrom.channel, delegatedFrom.key), outboundEnvelope);
|
|
421
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "direct-originator" });
|
|
309
422
|
return;
|
|
310
423
|
}
|
|
311
|
-
|
|
424
|
+
// Priority 2: Freshest active friend session.
|
|
425
|
+
// For BB, prefer DM sessions (;-;) over group chats (;+;) — proactive outreach should never land in groups.
|
|
426
|
+
const allFriendSessions = (0, session_activity_1.listSessionActivity)({
|
|
312
427
|
sessionsDir: path.join(agentRoot, "state", "sessions"),
|
|
313
428
|
friendsDir: path.join(agentRoot, "friends"),
|
|
314
429
|
agentName,
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if (freshest
|
|
430
|
+
}).filter((s) => s.friendId === delegatedFrom.friendId && s.channel !== "inner");
|
|
431
|
+
const bbDm = allFriendSessions.find((s) => s.channel === "bluebubbles" && s.key.includes(";-;"));
|
|
432
|
+
const freshest = bbDm ?? allFriendSessions.find((s) => s.channel !== "bluebubbles" || s.key.includes(";-;")) ?? allFriendSessions[0];
|
|
433
|
+
if (freshest) {
|
|
319
434
|
if (await tryDeliverDelegatedCompletion(freshest, outboundEnvelope)) {
|
|
435
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "freshest-session" });
|
|
320
436
|
return;
|
|
321
437
|
}
|
|
322
438
|
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, freshest.friendId, freshest.channel, freshest.key), outboundEnvelope);
|
|
439
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "freshest-session" });
|
|
323
440
|
return;
|
|
324
441
|
}
|
|
442
|
+
// Priority 3: Deferred return queue.
|
|
325
443
|
writePendingEnvelope((0, pending_1.getDeferredReturnDir)(agentName, delegatedFrom.friendId), outboundEnvelope);
|
|
444
|
+
advanceObligationQuietly(agentName, obligationId, { status: "deferred", returnedAt: timestamp, returnTarget: "deferred" });
|
|
326
445
|
}
|
|
446
|
+
/* v8 ignore stop */
|
|
327
447
|
// Self-referencing friend record for inner dialog (agent talking to itself).
|
|
328
448
|
// No real friend to resolve -- this satisfies the pipeline's friend resolver contract.
|
|
329
449
|
function createSelfFriend(agentName) {
|
|
@@ -350,12 +470,59 @@ function createNoOpFriendStore() {
|
|
|
350
470
|
findByExternalId: async () => null,
|
|
351
471
|
};
|
|
352
472
|
}
|
|
473
|
+
function buildParseErrorNudge(parseErrors) {
|
|
474
|
+
if (parseErrors.length === 0)
|
|
475
|
+
return "";
|
|
476
|
+
const lines = parseErrors.map((e) => `I noticed my habit file \`${e.file}\` has invalid frontmatter — I should fix it. (${e.error})`);
|
|
477
|
+
return lines.join("\n");
|
|
478
|
+
}
|
|
479
|
+
function buildAlsoDueLine(agentRoot, currentHabitName, now) {
|
|
480
|
+
const habitsDir = path.join(agentRoot, "habits");
|
|
481
|
+
let files;
|
|
482
|
+
try {
|
|
483
|
+
files = fs.readdirSync(habitsDir);
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
return "";
|
|
487
|
+
}
|
|
488
|
+
const nowMs = now().getTime();
|
|
489
|
+
const alsoDue = [];
|
|
490
|
+
for (const file of files) {
|
|
491
|
+
if (!file.endsWith(".md"))
|
|
492
|
+
continue;
|
|
493
|
+
const stem = file.replace(/\.md$/, "");
|
|
494
|
+
if (stem === currentHabitName)
|
|
495
|
+
continue;
|
|
496
|
+
try {
|
|
497
|
+
const content = fs.readFileSync(path.join(habitsDir, file), "utf-8");
|
|
498
|
+
const habit = (0, habit_runtime_state_1.applyHabitRuntimeState)(agentRoot, (0, habit_parser_1.parseHabitFile)(content, path.join(habitsDir, file)));
|
|
499
|
+
if (habit.status !== "active" || !habit.cadence)
|
|
500
|
+
continue;
|
|
501
|
+
const cadenceMs = (0, cadence_1.parseCadenceToMs)(habit.cadence);
|
|
502
|
+
if (cadenceMs === null)
|
|
503
|
+
continue;
|
|
504
|
+
if (habit.lastRun === null) {
|
|
505
|
+
alsoDue.push(stem);
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
const lastRunMs = new Date(habit.lastRun).getTime();
|
|
509
|
+
if (nowMs - lastRunMs >= cadenceMs) {
|
|
510
|
+
alsoDue.push(stem);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
catch {
|
|
514
|
+
// skip unreadable habits
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (alsoDue.length === 0)
|
|
518
|
+
return "";
|
|
519
|
+
return `also due: ${alsoDue.join(", ")}`;
|
|
520
|
+
}
|
|
353
521
|
async function runInnerDialogTurn(options) {
|
|
354
522
|
const now = options?.now ?? (() => new Date());
|
|
355
|
-
const reason = options?.reason ?? "
|
|
523
|
+
const reason = options?.reason ?? "instinct";
|
|
356
524
|
const sessionFilePath = innerDialogSessionPath();
|
|
357
525
|
const agentName = (0, identity_1.getAgentName)();
|
|
358
|
-
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
359
526
|
writeInnerDialogRuntimeState(sessionFilePath, {
|
|
360
527
|
status: "running",
|
|
361
528
|
reason,
|
|
@@ -372,6 +539,8 @@ async function runInnerDialogTurn(options) {
|
|
|
372
539
|
};
|
|
373
540
|
// ── Adapter concern: build user message ──────────────────────────
|
|
374
541
|
let userContent;
|
|
542
|
+
let habitTools;
|
|
543
|
+
let habitParsedSuccessfully = false;
|
|
375
544
|
if (existingMessages.length === 0) {
|
|
376
545
|
// Fresh session: bootstrap message with non-canonical cleanup nudge
|
|
377
546
|
const aspirations = readAspirations((0, identity_1.getAgentRoot)());
|
|
@@ -391,6 +560,113 @@ async function runInnerDialogTurn(options) {
|
|
|
391
560
|
const taskContent = readTaskFile((0, identity_1.getAgentRoot)(), options.taskId);
|
|
392
561
|
userContent = buildTaskTriggeredMessage(options.taskId, taskContent, state.checkpoint);
|
|
393
562
|
}
|
|
563
|
+
else if (reason === "habit" && options?.habitName) {
|
|
564
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
565
|
+
const habitName = options.habitName;
|
|
566
|
+
const habitFilePath = path.join(agentRoot, "habits", `${habitName}.md`);
|
|
567
|
+
// Read and parse the habit file
|
|
568
|
+
let habitBody;
|
|
569
|
+
let habitTitle = habitName;
|
|
570
|
+
let habitLastRun = null;
|
|
571
|
+
try {
|
|
572
|
+
const habitContent = fs.readFileSync(habitFilePath, "utf-8");
|
|
573
|
+
const parsed = (0, habit_runtime_state_1.applyHabitRuntimeState)(agentRoot, (0, habit_parser_1.parseHabitFile)(habitContent, habitFilePath));
|
|
574
|
+
habitBody = parsed.body || undefined;
|
|
575
|
+
habitTitle = parsed.title || habitName;
|
|
576
|
+
habitLastRun = parsed.lastRun;
|
|
577
|
+
habitTools = parsed.tools;
|
|
578
|
+
}
|
|
579
|
+
catch {
|
|
580
|
+
// Habit file missing or unreadable
|
|
581
|
+
}
|
|
582
|
+
// If the habit file couldn't be read at all (no body, no title parsed), error message
|
|
583
|
+
if (habitBody === undefined && habitTitle === habitName) {
|
|
584
|
+
userContent = `habit "${habitName}" could not be read (file not found or unreadable). check habits/${habitName}.md exists.`;
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
habitParsedSuccessfully = true;
|
|
588
|
+
// Unified path: gather context for ALL habits (heartbeat included)
|
|
589
|
+
const obligations = (0, obligations_1.listActiveReturnObligations)(agentName);
|
|
590
|
+
const nowMs = now().getTime();
|
|
591
|
+
const staleObligations = obligations.map((o) => ({
|
|
592
|
+
friendName: o.origin.friendId,
|
|
593
|
+
content: o.delegatedContent,
|
|
594
|
+
stalenessMs: nowMs - o.createdAt,
|
|
595
|
+
}));
|
|
596
|
+
const alsoDue = buildAlsoDueLine(agentRoot, habitName, now);
|
|
597
|
+
// Degraded state (best-effort: never crash)
|
|
598
|
+
let degradedComponents = [];
|
|
599
|
+
try {
|
|
600
|
+
const health = (0, daemon_health_1.readHealth)((0, daemon_health_1.getDefaultHealthPath)());
|
|
601
|
+
if (health && health.degraded.length > 0) {
|
|
602
|
+
degradedComponents = health.degraded.map((d) => ({ component: d.component, reason: d.reason }));
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
catch {
|
|
606
|
+
// Best-effort: missing file or parse error -> empty array, no crash
|
|
607
|
+
}
|
|
608
|
+
userContent = (0, habit_turn_message_1.buildHabitTurnMessage)({
|
|
609
|
+
habitName,
|
|
610
|
+
habitTitle,
|
|
611
|
+
habitBody,
|
|
612
|
+
lastRun: habitLastRun,
|
|
613
|
+
checkpoint: displayCheckpoint(state.checkpoint),
|
|
614
|
+
alsoDue: alsoDue || undefined,
|
|
615
|
+
staleObligations,
|
|
616
|
+
parseErrors: options?.parseErrors ?? [],
|
|
617
|
+
degradedComponents,
|
|
618
|
+
now,
|
|
619
|
+
});
|
|
620
|
+
// Piggyback journal embedding indexing (best-effort, fire-and-forget)
|
|
621
|
+
const journalDir = path.join(agentRoot, "journal");
|
|
622
|
+
/* v8 ignore start -- journal indexing piggyback: embedding provider may not be available; tested via journal-index unit tests @preserve */
|
|
623
|
+
void (0, journal_index_1.indexJournalFiles)(journalDir, path.join(journalDir, ".index.json"), {
|
|
624
|
+
embed: async () => [],
|
|
625
|
+
}).catch(() => {
|
|
626
|
+
// swallowed: indexing failure must never block habit turn
|
|
627
|
+
});
|
|
628
|
+
/* v8 ignore stop */
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
else if (reason === "await" && options?.awaitName) {
|
|
632
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
633
|
+
const awaitName = options.awaitName;
|
|
634
|
+
const awaitFilePath = path.join(agentRoot, "awaiting", `${awaitName}.md`);
|
|
635
|
+
let awaitBody;
|
|
636
|
+
let condition = null;
|
|
637
|
+
let lastCheckedAt = null;
|
|
638
|
+
let lastObservation = null;
|
|
639
|
+
let checkedCount = 0;
|
|
640
|
+
let awaitFound = false;
|
|
641
|
+
try {
|
|
642
|
+
const awaitContent = fs.readFileSync(awaitFilePath, "utf-8");
|
|
643
|
+
const parsed = (0, await_runtime_state_1.applyAwaitRuntimeState)(agentRoot, (0, await_parser_1.parseAwaitFile)(awaitContent, awaitFilePath));
|
|
644
|
+
awaitFound = true;
|
|
645
|
+
awaitBody = parsed.body || undefined;
|
|
646
|
+
condition = parsed.condition;
|
|
647
|
+
lastCheckedAt = parsed.last_checked ?? null;
|
|
648
|
+
lastObservation = parsed.last_observation ?? null;
|
|
649
|
+
checkedCount = parsed.checked_count ?? 0;
|
|
650
|
+
}
|
|
651
|
+
catch {
|
|
652
|
+
// file missing — fall through to error message
|
|
653
|
+
}
|
|
654
|
+
if (!awaitFound || !condition) {
|
|
655
|
+
userContent = `await "${awaitName}" could not be read (file not found or no condition). check awaiting/${awaitName}.md.`;
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
userContent = (0, await_turn_message_1.buildAwaitTurnMessage)({
|
|
659
|
+
awaitName,
|
|
660
|
+
condition,
|
|
661
|
+
body: awaitBody,
|
|
662
|
+
lastCheckedAt,
|
|
663
|
+
lastObservation,
|
|
664
|
+
checkedCount,
|
|
665
|
+
checkpoint: displayCheckpoint(state.checkpoint),
|
|
666
|
+
now,
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
}
|
|
394
670
|
else {
|
|
395
671
|
userContent = buildInstinctUserMessage(instincts, reason, state);
|
|
396
672
|
}
|
|
@@ -401,15 +677,43 @@ async function runInnerDialogTurn(options) {
|
|
|
401
677
|
const pendingDir = (0, pending_1.getInnerDialogPendingDir)(agentName);
|
|
402
678
|
const selfFriend = createSelfFriend(agentName);
|
|
403
679
|
const selfContext = { friend: selfFriend, channel: innerCapabilities };
|
|
680
|
+
const mcpManager = await (0, mcp_manager_1.getSharedMcpManager)() ?? undefined;
|
|
681
|
+
// ── Habit tool enforcement ───────────────────────────────────────
|
|
682
|
+
let habitToolsResolved;
|
|
683
|
+
if (habitTools !== undefined) {
|
|
684
|
+
const fullTools = (0, tools_1.getToolsForChannel)(innerCapabilities);
|
|
685
|
+
habitToolsResolved = fullTools.filter((t) => habitTools.includes(t.function.name));
|
|
686
|
+
(0, runtime_1.emitNervesEvent)({
|
|
687
|
+
event: "habit.tools_restricted",
|
|
688
|
+
component: "senses",
|
|
689
|
+
message: "habit running with restricted tools",
|
|
690
|
+
meta: {
|
|
691
|
+
habitName: options?.habitName,
|
|
692
|
+
declared: habitTools,
|
|
693
|
+
resolved: habitToolsResolved.map((t) => t.function.name),
|
|
694
|
+
},
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
else if (reason === "habit" && options?.habitName && habitParsedSuccessfully) {
|
|
698
|
+
(0, runtime_1.emitNervesEvent)({
|
|
699
|
+
event: "habit.tools_unrestricted",
|
|
700
|
+
component: "senses",
|
|
701
|
+
message: "habit running with full tool repertoire",
|
|
702
|
+
meta: { habitName: options.habitName },
|
|
703
|
+
});
|
|
704
|
+
}
|
|
404
705
|
const sessionLoader = {
|
|
405
706
|
loadOrCreate: async () => {
|
|
406
707
|
if (existingMessages.length > 0) {
|
|
407
|
-
return {
|
|
708
|
+
return {
|
|
709
|
+
messages: existingMessages,
|
|
710
|
+
sessionPath: sessionFilePath,
|
|
711
|
+
};
|
|
408
712
|
}
|
|
409
713
|
// Fresh session: build system prompt
|
|
410
714
|
const systemPrompt = await (0, prompt_1.buildSystem)("inner", { toolChoiceRequired: true });
|
|
411
715
|
return {
|
|
412
|
-
messages: [{ role: "system", content: systemPrompt }],
|
|
716
|
+
messages: [{ role: "system", content: (0, prompt_1.flattenSystemPrompt)(systemPrompt) }],
|
|
413
717
|
sessionPath: sessionFilePath,
|
|
414
718
|
};
|
|
415
719
|
},
|
|
@@ -417,6 +721,8 @@ async function runInnerDialogTurn(options) {
|
|
|
417
721
|
// ── Call shared pipeline ──────────────────────────────────────────
|
|
418
722
|
const callbacks = createInnerDialogCallbacks();
|
|
419
723
|
const traceId = (0, nerves_1.createTraceId)();
|
|
724
|
+
// Attention queue: built when pending messages are drained, shared with tool context
|
|
725
|
+
let attentionQueue = [];
|
|
420
726
|
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
421
727
|
channel: "inner",
|
|
422
728
|
sessionKey: "dialog",
|
|
@@ -431,16 +737,55 @@ async function runInnerDialogTurn(options) {
|
|
|
431
737
|
enforceTrustGate: trust_gate_1.enforceTrustGate,
|
|
432
738
|
drainPending: pending_1.drainPending,
|
|
433
739
|
runAgent: core_1.runAgent,
|
|
434
|
-
postTurn:
|
|
740
|
+
postTurn: (turnMessages, sessionPathArg, usage, hooks, state) => {
|
|
741
|
+
const prepared = (0, context_1.postTurnTrim)(turnMessages, usage, hooks);
|
|
742
|
+
(0, context_1.deferPostTurnPersist)(sessionPathArg, prepared, usage, state);
|
|
743
|
+
},
|
|
435
744
|
accumulateFriendTokens: tokens_1.accumulateFriendTokens,
|
|
436
745
|
signal: options?.signal,
|
|
746
|
+
/* v8 ignore start -- attention queue: callback invoked by pipeline during pending drain; tested via attention-queue unit tests @preserve */
|
|
747
|
+
onPendingDrained: (drained) => {
|
|
748
|
+
const outstandingObligations = (0, obligations_1.listActiveReturnObligations)(agentName);
|
|
749
|
+
attentionQueue = (0, attention_queue_1.buildAttentionQueue)({
|
|
750
|
+
drainedPending: drained,
|
|
751
|
+
outstandingObligations,
|
|
752
|
+
friendNameResolver: (friendId) => {
|
|
753
|
+
try {
|
|
754
|
+
const raw = fs.readFileSync(path.join((0, identity_1.getAgentRoot)(agentName), "friends", friendId + ".json"), "utf-8");
|
|
755
|
+
const parsed = JSON.parse(raw);
|
|
756
|
+
return typeof parsed.name === "string" ? parsed.name : null;
|
|
757
|
+
}
|
|
758
|
+
catch {
|
|
759
|
+
return null;
|
|
760
|
+
}
|
|
761
|
+
},
|
|
762
|
+
packetResolver: (packetId) => {
|
|
763
|
+
try {
|
|
764
|
+
return (0, packets_1.readPonderPacket)((0, identity_1.getAgentRoot)(agentName), packetId);
|
|
765
|
+
}
|
|
766
|
+
catch {
|
|
767
|
+
return null;
|
|
768
|
+
}
|
|
769
|
+
},
|
|
770
|
+
});
|
|
771
|
+
const summary = (0, attention_queue_1.buildAttentionQueueSummary)(attentionQueue);
|
|
772
|
+
return summary ? [summary] : [];
|
|
773
|
+
},
|
|
774
|
+
/* v8 ignore stop */
|
|
437
775
|
runAgentOptions: {
|
|
438
776
|
traceId,
|
|
439
777
|
toolChoiceRequired: true,
|
|
440
|
-
|
|
778
|
+
mcpManager,
|
|
779
|
+
...(habitToolsResolved !== undefined && { tools: habitToolsResolved }),
|
|
780
|
+
toolContext: {
|
|
781
|
+
signin: async () => undefined,
|
|
782
|
+
delegatedOrigins: attentionQueue,
|
|
783
|
+
},
|
|
441
784
|
},
|
|
442
785
|
});
|
|
443
|
-
|
|
786
|
+
// Post-turn routeDelegatedCompletion removed: delivery is now inline via surface tool.
|
|
787
|
+
// settle in inner dialog produces no CompletionMetadata, so routeDelegatedCompletion
|
|
788
|
+
// would be a no-op. The routing infrastructure is reused by the surface handler.
|
|
444
789
|
const resultMessages = result.messages ?? [];
|
|
445
790
|
const assistantPreview = extractAssistantPreview(resultMessages);
|
|
446
791
|
const toolCalls = extractToolCallNames(resultMessages);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const agentArgIndex = process.argv.indexOf("--agent");
|
|
37
|
+
const agentName = agentArgIndex >= 0 ? process.argv[agentArgIndex + 1] : undefined;
|
|
38
|
+
if (!agentName) {
|
|
39
|
+
// eslint-disable-next-line no-console -- pre-boot guard: --agent check before imports
|
|
40
|
+
console.error("Missing required --agent <name> argument.\nUsage: node dist/senses/mail-entry.js --agent ouroboros");
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
const runtime_logging_1 = require("../heart/daemon/runtime-logging");
|
|
44
|
+
const runtime_1 = require("../nerves/runtime");
|
|
45
|
+
(0, runtime_logging_1.configureDaemonRuntimeLogger)("mail");
|
|
46
|
+
(0, runtime_1.emitNervesEvent)({
|
|
47
|
+
component: "senses",
|
|
48
|
+
event: "senses.entry_boot",
|
|
49
|
+
message: "booting Mail entrypoint",
|
|
50
|
+
meta: { entry: "mail", agentName },
|
|
51
|
+
});
|
|
52
|
+
Promise.resolve().then(() => __importStar(require("./mail"))).then(async ({ startMailSenseApp }) => {
|
|
53
|
+
await startMailSenseApp({ agentName });
|
|
54
|
+
})
|
|
55
|
+
.catch((error) => {
|
|
56
|
+
(0, runtime_1.emitNervesEvent)({
|
|
57
|
+
level: "error",
|
|
58
|
+
component: "senses",
|
|
59
|
+
event: "senses.entry_error",
|
|
60
|
+
message: "Mail entrypoint failed",
|
|
61
|
+
meta: { entry: "mail", agentName, error: error instanceof Error ? error.message : String(error) },
|
|
62
|
+
});
|
|
63
|
+
// eslint-disable-next-line no-console -- fatal startup guard for sense process
|
|
64
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|