@ouro.bot/cli 0.1.0-alpha.66 → 0.1.0-alpha.661
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 +4216 -13
- package/dist/a2a/card.js +56 -0
- package/dist/a2a/client.js +143 -0
- package/dist/a2a/config.js +50 -0
- package/dist/a2a/onboarding.js +111 -0
- package/dist/a2a/server.js +498 -0
- package/dist/a2a/task-store.js +69 -0
- package/dist/a2a/types.js +3 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +144 -0
- package/dist/arc/episodes.js +118 -0
- package/dist/arc/evolution.js +487 -0
- package/dist/arc/flight-recorder.js +369 -0
- package/dist/arc/intentions.js +134 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +292 -0
- package/dist/arc/packets.js +288 -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 +860 -43
- 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/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 +100 -0
- package/dist/heart/awaiting/await-scheduler.js +377 -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 +135 -0
- package/dist/heart/config-registry.js +331 -0
- package/dist/heart/config.js +118 -119
- package/dist/heart/context-loss-gauntlet.js +354 -0
- package/dist/heart/core.js +1123 -247
- 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 +523 -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 +780 -0
- package/dist/heart/daemon/cli-desk.js +322 -0
- package/dist/heart/daemon/cli-exec.js +7767 -0
- package/dist/heart/daemon/cli-help.js +558 -0
- package/dist/heart/daemon/cli-parse.js +1688 -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 -1750
- 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 +937 -74
- 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 +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 +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- package/dist/heart/daemon/message-router.js +6 -2
- 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 +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/plugin-cli.js +432 -0
- package/dist/heart/daemon/process-manager.js +511 -40
- 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 +35 -14
- 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 +564 -38
- 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 +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 +117 -39
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +229 -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 -4
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +203 -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 +40 -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 +45 -18
- package/dist/heart/identity.js +174 -57
- 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 +353 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +67 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +250 -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 +32 -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 +418 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +324 -0
- package/dist/heart/mailbox/readers/mail.js +375 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +728 -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 +696 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +19 -0
- package/dist/heart/orientation-frame.js +217 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +272 -0
- package/dist/heart/provider-credentials.js +425 -0
- package/dist/heart/provider-failover.js +311 -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-token.js +349 -0
- 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 +17 -4
- package/dist/heart/session-activity.js +48 -24
- package/dist/heart/session-events.js +1133 -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 +133 -0
- package/dist/heart/start-of-turn-packet.js +351 -0
- package/dist/heart/streaming.js +44 -27
- 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 +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 +155 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +430 -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 +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/work-card.js +386 -0
- package/dist/mailbox-ui/assets/index-B-V9vRQ0.js +61 -0
- package/dist/mailbox-ui/assets/index-BOZbGbkL.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 +715 -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 +568 -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 +334 -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 +21 -2
- package/dist/mind/context.js +250 -101
- 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/friends/channel.js +48 -0
- package/dist/mind/friends/resolver.js +107 -4
- package/dist/mind/friends/store-file.js +61 -4
- package/dist/mind/friends/types.js +2 -2
- package/dist/mind/{associative-recall.js → note-search.js} +47 -58
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +6 -1
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1015 -140
- 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/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/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 +16 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +1041 -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 +197 -30
- package/dist/repertoire/coding/manager.js +166 -10
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +219 -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/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 +159 -25
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +434 -0
- package/dist/repertoire/mcp-tools.js +83 -0
- package/dist/repertoire/plugin-mcp.js +175 -0
- package/dist/repertoire/plugins.js +253 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +48 -4
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-a2a.js +283 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-awaiting.js +372 -0
- package/dist/repertoire/tools-base.js +63 -1082
- 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 +252 -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-mail.js +1975 -0
- package/dist/repertoire/tools-notes.js +418 -0
- package/dist/repertoire/tools-obligations.js +143 -0
- package/dist/repertoire/tools-orientation.js +31 -0
- package/dist/repertoire/tools-record.js +469 -0
- package/dist/repertoire/tools-runtime.js +150 -0
- package/dist/repertoire/tools-session.js +766 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +224 -0
- package/dist/repertoire/tools-surface.js +344 -0
- package/dist/repertoire/tools-teams.js +12 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +982 -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 +243 -79
- 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/a2a-entry.js +78 -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} +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 +2737 -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 +517 -204
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +122 -0
- package/dist/senses/inner-dialog-worker.js +303 -22
- package/dist/senses/inner-dialog.js +525 -41
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +857 -180
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +419 -0
- package/dist/senses/surface-tool.js +108 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +390 -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 +5079 -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/package.json +55 -12
- 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 -351
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/update-hooks.js +0 -138
- package/dist/heart/safe-workspace.js +0 -228
- package/dist/heart/session-recall.js +0 -116
- 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 -1177
- package/dist/senses/debug-activity.js +0 -148
- 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
|
@@ -41,6 +41,10 @@ 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;
|
|
47
|
+
exports.buildHeldReturnWakeMessage = buildHeldReturnWakeMessage;
|
|
44
48
|
exports.runInnerDialogTurn = runInnerDialogTurn;
|
|
45
49
|
const fs = __importStar(require("fs"));
|
|
46
50
|
const path = __importStar(require("path"));
|
|
@@ -49,8 +53,13 @@ const core_1 = require("../heart/core");
|
|
|
49
53
|
const identity_1 = require("../heart/identity");
|
|
50
54
|
const context_1 = require("../mind/context");
|
|
51
55
|
const prompt_1 = require("../mind/prompt");
|
|
56
|
+
const mcp_manager_1 = require("../repertoire/mcp-manager");
|
|
57
|
+
const tools_1 = require("../repertoire/tools");
|
|
52
58
|
const bundle_manifest_1 = require("../mind/bundle-manifest");
|
|
53
59
|
const pending_1 = require("../mind/pending");
|
|
60
|
+
const obligations_1 = require("../arc/obligations");
|
|
61
|
+
const attention_queue_1 = require("./attention-queue");
|
|
62
|
+
const packets_1 = require("../arc/packets");
|
|
54
63
|
const channel_1 = require("../mind/friends/channel");
|
|
55
64
|
const trust_gate_1 = require("./trust-gate");
|
|
56
65
|
const tokens_1 = require("../mind/friends/tokens");
|
|
@@ -60,6 +69,16 @@ const runtime_1 = require("../nerves/runtime");
|
|
|
60
69
|
const manager_1 = require("../heart/bridges/manager");
|
|
61
70
|
const session_activity_1 = require("../heart/session-activity");
|
|
62
71
|
const bluebubbles_1 = require("./bluebubbles");
|
|
72
|
+
const habit_turn_message_1 = require("./habit-turn-message");
|
|
73
|
+
const await_turn_message_1 = require("./await-turn-message");
|
|
74
|
+
const await_parser_1 = require("../heart/awaiting/await-parser");
|
|
75
|
+
const await_runtime_state_1 = require("../heart/awaiting/await-runtime-state");
|
|
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");
|
|
80
|
+
const flight_recorder_1 = require("../arc/flight-recorder");
|
|
81
|
+
const desk_section_1 = require("../mind/desk-section");
|
|
63
82
|
const DEFAULT_INNER_DIALOG_INSTINCTS = [
|
|
64
83
|
{
|
|
65
84
|
id: "heartbeat_checkin",
|
|
@@ -98,23 +117,31 @@ function buildNonCanonicalCleanupNudge(nonCanonicalPaths) {
|
|
|
98
117
|
}
|
|
99
118
|
return [
|
|
100
119
|
"## canonical cleanup nudge",
|
|
101
|
-
"I found non-canonical files in my bundle. I should distill anything valuable into
|
|
120
|
+
"I found non-canonical files in my bundle. I should distill anything valuable into my diary and remove these files.",
|
|
102
121
|
...listed,
|
|
103
122
|
].join("\n");
|
|
104
123
|
}
|
|
124
|
+
function displayCheckpoint(checkpoint) {
|
|
125
|
+
const trimmed = checkpoint?.trim();
|
|
126
|
+
if (!trimmed || trimmed === "no prior checkpoint recorded") {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
return trimmed;
|
|
130
|
+
}
|
|
105
131
|
function buildInstinctUserMessage(instincts, _reason, state) {
|
|
106
132
|
const active = instincts.find((instinct) => instinct.enabled !== false) ?? DEFAULT_INNER_DIALOG_INSTINCTS[0];
|
|
107
|
-
const checkpoint = state.checkpoint
|
|
133
|
+
const checkpoint = displayCheckpoint(state.checkpoint);
|
|
108
134
|
const lines = [active.prompt];
|
|
109
135
|
if (checkpoint) {
|
|
110
|
-
lines.push(`\nlast
|
|
136
|
+
lines.push(`\nlast checkpoint: ${checkpoint}`);
|
|
111
137
|
}
|
|
112
138
|
return lines.join("\n");
|
|
113
139
|
}
|
|
114
140
|
function readTaskFile(agentRoot, taskId) {
|
|
115
|
-
// Task files live in collection subdirectories (one-shots, ongoing
|
|
141
|
+
// Task files live in collection subdirectories (one-shots, ongoing).
|
|
116
142
|
// Try each collection, then fall back to root tasks/ for legacy layout.
|
|
117
|
-
|
|
143
|
+
// Habits are no longer in tasks/ — they live at bundle root habits/.
|
|
144
|
+
const collections = ["one-shots", "ongoing", ""];
|
|
118
145
|
for (const collection of collections) {
|
|
119
146
|
try {
|
|
120
147
|
return fs.readFileSync(path.join(agentRoot, "tasks", collection, `${taskId}.md`), "utf8").trim();
|
|
@@ -133,8 +160,9 @@ function buildTaskTriggeredMessage(taskId, taskContent, checkpoint) {
|
|
|
133
160
|
else {
|
|
134
161
|
lines.push("", `## task: ${taskId}`, "(task file not found)");
|
|
135
162
|
}
|
|
136
|
-
|
|
137
|
-
|
|
163
|
+
const renderedCheckpoint = displayCheckpoint(checkpoint);
|
|
164
|
+
if (renderedCheckpoint) {
|
|
165
|
+
lines.push("", `last checkpoint: ${renderedCheckpoint}`);
|
|
138
166
|
}
|
|
139
167
|
return lines.join("\n");
|
|
140
168
|
}
|
|
@@ -157,31 +185,129 @@ function contentToText(content) {
|
|
|
157
185
|
.join("\n");
|
|
158
186
|
return text.trim();
|
|
159
187
|
}
|
|
160
|
-
function
|
|
161
|
-
const
|
|
162
|
-
if (!lastAssistant)
|
|
163
|
-
return "no prior checkpoint recorded";
|
|
164
|
-
const assistantText = contentToText(lastAssistant.content);
|
|
188
|
+
function checkpointTextFromAssistantContent(content) {
|
|
189
|
+
const assistantText = contentToText(content);
|
|
165
190
|
if (!assistantText)
|
|
166
|
-
return
|
|
167
|
-
const
|
|
191
|
+
return null;
|
|
192
|
+
const cleanedLines = assistantText
|
|
168
193
|
.split("\n")
|
|
169
|
-
.map((line) => line.trim())
|
|
194
|
+
.map((line) => line.replace(/<\/?think>/gi, "").trim())
|
|
195
|
+
.filter((line) => line.length > 0);
|
|
196
|
+
const explicitCheckpoint = cleanedLines
|
|
170
197
|
.find((line) => /^checkpoint\s*:/i.test(line));
|
|
171
198
|
if (explicitCheckpoint) {
|
|
172
199
|
const parsed = explicitCheckpoint.replace(/^checkpoint\s*:\s*/i, "").trim();
|
|
173
|
-
return parsed ||
|
|
200
|
+
return parsed || null;
|
|
174
201
|
}
|
|
175
|
-
const firstLine =
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
202
|
+
const firstLine = cleanedLines[0];
|
|
203
|
+
return firstLine ?? null;
|
|
204
|
+
}
|
|
205
|
+
function truncateCheckpointText(text) {
|
|
206
|
+
if (text.length <= 220)
|
|
207
|
+
return text;
|
|
208
|
+
return `${text.slice(0, 217)}...`;
|
|
209
|
+
}
|
|
210
|
+
function parseToolArguments(argumentsValue) {
|
|
211
|
+
if (!argumentsValue)
|
|
212
|
+
return {};
|
|
213
|
+
try {
|
|
214
|
+
const parsed = JSON.parse(argumentsValue);
|
|
215
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
216
|
+
? parsed
|
|
217
|
+
: {};
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return {};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function toolArgumentText(args, keys) {
|
|
224
|
+
for (const key of keys) {
|
|
225
|
+
const value = args[key];
|
|
226
|
+
if (typeof value === "string" && value.trim()) {
|
|
227
|
+
return value.trim();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return "";
|
|
231
|
+
}
|
|
232
|
+
function summarizeToolAction(name, argumentsValue) {
|
|
233
|
+
if (!name)
|
|
234
|
+
return null;
|
|
235
|
+
const args = parseToolArguments(argumentsValue);
|
|
236
|
+
if (name === "surface") {
|
|
237
|
+
const message = toolArgumentText(args, ["message", "text", "content"]);
|
|
238
|
+
return message ? `surfaced: ${message}` : null;
|
|
239
|
+
}
|
|
240
|
+
if (name === "ponder") {
|
|
241
|
+
const thought = toolArgumentText(args, ["summary", "question", "topic", "prompt"]);
|
|
242
|
+
return thought ? `pondered: ${thought}` : null;
|
|
243
|
+
}
|
|
244
|
+
if (name === "diary_write") {
|
|
245
|
+
const note = toolArgumentText(args, ["text", "content", "note", "entry"]);
|
|
246
|
+
return note ? `diary: ${note}` : null;
|
|
247
|
+
}
|
|
248
|
+
if (name === "let_go") {
|
|
249
|
+
const reason = toolArgumentText(args, ["reason", "note", "status"]);
|
|
250
|
+
return reason ? `let go: ${reason}` : null;
|
|
251
|
+
}
|
|
252
|
+
if (name === "rest") {
|
|
253
|
+
const note = toolArgumentText(args, ["note", "status"]);
|
|
254
|
+
return note ? `rested: ${note}` : null;
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
function extractToolFunction(toolCall) {
|
|
259
|
+
if (!toolCall || typeof toolCall !== "object" || !("function" in toolCall))
|
|
260
|
+
return null;
|
|
261
|
+
const maybeFunction = toolCall.function;
|
|
262
|
+
if (!maybeFunction || typeof maybeFunction !== "object")
|
|
263
|
+
return null;
|
|
264
|
+
const name = "name" in maybeFunction && typeof maybeFunction.name === "string"
|
|
265
|
+
? maybeFunction.name
|
|
266
|
+
: undefined;
|
|
267
|
+
const argumentsValue = "arguments" in maybeFunction && typeof maybeFunction.arguments === "string"
|
|
268
|
+
? maybeFunction.arguments
|
|
269
|
+
: undefined;
|
|
270
|
+
return { name, arguments: argumentsValue };
|
|
271
|
+
}
|
|
272
|
+
function checkpointTextFromAssistantToolCalls(message) {
|
|
273
|
+
if (message.role !== "assistant" || !Array.isArray(message.tool_calls))
|
|
274
|
+
return null;
|
|
275
|
+
for (let i = message.tool_calls.length - 1; i >= 0; i--) {
|
|
276
|
+
const toolFunction = extractToolFunction(message.tool_calls[i]);
|
|
277
|
+
const summary = summarizeToolAction(toolFunction?.name, toolFunction?.arguments);
|
|
278
|
+
if (summary)
|
|
279
|
+
return summary;
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
function latestRestStatus(messages) {
|
|
284
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
285
|
+
const message = messages[i];
|
|
286
|
+
if (message.role !== "assistant" || !Array.isArray(message.tool_calls))
|
|
287
|
+
continue;
|
|
288
|
+
for (let j = message.tool_calls.length - 1; j >= 0; j--) {
|
|
289
|
+
const toolFunction = extractToolFunction(message.tool_calls[j]);
|
|
290
|
+
if (toolFunction?.name !== "rest")
|
|
291
|
+
continue;
|
|
292
|
+
const status = parseToolArguments(toolFunction.arguments).status;
|
|
293
|
+
return typeof status === "string" && status.trim() ? status.trim() : undefined;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return undefined;
|
|
297
|
+
}
|
|
298
|
+
function deriveResumeCheckpoint(messages) {
|
|
299
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
300
|
+
const message = messages[i];
|
|
301
|
+
if (message.role !== "assistant")
|
|
302
|
+
continue;
|
|
303
|
+
const textCheckpoint = checkpointTextFromAssistantContent(message.content);
|
|
304
|
+
if (textCheckpoint)
|
|
305
|
+
return truncateCheckpointText(textCheckpoint);
|
|
306
|
+
const toolCheckpoint = checkpointTextFromAssistantToolCalls(message);
|
|
307
|
+
if (toolCheckpoint)
|
|
308
|
+
return truncateCheckpointText(toolCheckpoint);
|
|
309
|
+
}
|
|
310
|
+
return "no prior checkpoint recorded";
|
|
185
311
|
}
|
|
186
312
|
function extractAssistantPreview(messages, maxLength = 120) {
|
|
187
313
|
const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
|
|
@@ -247,6 +373,7 @@ function writeInnerDialogRuntimeState(sessionFilePath, state) {
|
|
|
247
373
|
});
|
|
248
374
|
}
|
|
249
375
|
}
|
|
376
|
+
/* v8 ignore start -- routing helpers: called from routing functions which are integration paths @preserve */
|
|
250
377
|
function writePendingEnvelope(pendingDir, message) {
|
|
251
378
|
fs.mkdirSync(pendingDir, { recursive: true });
|
|
252
379
|
const fileName = `${message.timestamp}-${Math.random().toString(36).slice(2, 10)}.json`;
|
|
@@ -258,6 +385,8 @@ function sessionMatchesActivity(activity, session) {
|
|
|
258
385
|
&& activity.channel === session.channel
|
|
259
386
|
&& activity.key === session.key;
|
|
260
387
|
}
|
|
388
|
+
/* v8 ignore stop */
|
|
389
|
+
/* v8 ignore start -- routing: delivery now inline via surface tool; routing functions preserved for reuse @preserve */
|
|
261
390
|
function resolveBridgePreferredSession(delegatedFrom, sessionActivity) {
|
|
262
391
|
if (!delegatedFrom.bridgeId)
|
|
263
392
|
return null;
|
|
@@ -277,15 +406,82 @@ async function tryDeliverDelegatedCompletion(target, outboundEnvelope) {
|
|
|
277
406
|
friendId: target.friendId,
|
|
278
407
|
sessionKey: target.key,
|
|
279
408
|
text: outboundEnvelope.content,
|
|
409
|
+
intent: "explicit_cross_chat",
|
|
280
410
|
});
|
|
281
411
|
return result.delivered;
|
|
282
412
|
}
|
|
413
|
+
function enrichDelegatedFromWithBridge(delegatedFrom) {
|
|
414
|
+
if (delegatedFrom.bridgeId) {
|
|
415
|
+
return delegatedFrom;
|
|
416
|
+
}
|
|
417
|
+
const bridgeManager = (0, manager_1.createBridgeManager)();
|
|
418
|
+
const originBridges = bridgeManager.findBridgesForSession({
|
|
419
|
+
friendId: delegatedFrom.friendId,
|
|
420
|
+
channel: delegatedFrom.channel,
|
|
421
|
+
key: delegatedFrom.key,
|
|
422
|
+
});
|
|
423
|
+
const activeBridge = originBridges.find((b) => b.lifecycle === "active");
|
|
424
|
+
if (activeBridge) {
|
|
425
|
+
return { ...delegatedFrom, bridgeId: activeBridge.id };
|
|
426
|
+
}
|
|
427
|
+
return delegatedFrom;
|
|
428
|
+
}
|
|
429
|
+
function advanceObligationQuietly(agentName, obligationId, update) {
|
|
430
|
+
if (!obligationId)
|
|
431
|
+
return;
|
|
432
|
+
try {
|
|
433
|
+
(0, obligations_1.advanceReturnObligation)(agentName, obligationId, update);
|
|
434
|
+
/* v8 ignore start -- best-effort: obligation fs errors must never block return routing @preserve */
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
// swallowed
|
|
438
|
+
}
|
|
439
|
+
/* v8 ignore stop */
|
|
440
|
+
}
|
|
283
441
|
async function routeDelegatedCompletion(agentRoot, agentName, completion, drainedPending, timestamp) {
|
|
284
442
|
const delegated = (drainedPending ?? []).find((message) => message.delegatedFrom);
|
|
285
443
|
if (!delegated?.delegatedFrom || !completion?.answer?.trim()) {
|
|
286
444
|
return;
|
|
287
445
|
}
|
|
288
|
-
const delegatedFrom = delegated.delegatedFrom;
|
|
446
|
+
const delegatedFrom = enrichDelegatedFromWithBridge(delegated.delegatedFrom);
|
|
447
|
+
const obligationId = delegated.obligationId;
|
|
448
|
+
// Advance any inner return obligations from queued -> running (they were drained this turn).
|
|
449
|
+
// drainedPending is guaranteed non-null here (we found delegated above).
|
|
450
|
+
for (const msg of drainedPending) {
|
|
451
|
+
if (msg.obligationId) {
|
|
452
|
+
advanceObligationQuietly(agentName, msg.obligationId, {
|
|
453
|
+
status: "running",
|
|
454
|
+
startedAt: timestamp,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (delegated.obligationStatus === "pending") {
|
|
459
|
+
// Fulfill the persistent obligation in the store
|
|
460
|
+
try {
|
|
461
|
+
const pending = (0, obligations_1.findPendingObligationForOrigin)(agentRoot, {
|
|
462
|
+
friendId: delegatedFrom.friendId,
|
|
463
|
+
channel: delegatedFrom.channel,
|
|
464
|
+
key: delegatedFrom.key,
|
|
465
|
+
});
|
|
466
|
+
/* v8 ignore next 2 -- obligation fulfillment tested via obligations.test.ts; integration requires real disk state @preserve */
|
|
467
|
+
if (pending) {
|
|
468
|
+
(0, obligations_1.fulfillObligation)(agentRoot, pending.id);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
catch {
|
|
472
|
+
/* v8 ignore next -- defensive: obligation store read failure should not break delivery @preserve */
|
|
473
|
+
}
|
|
474
|
+
(0, runtime_1.emitNervesEvent)({
|
|
475
|
+
event: "senses.obligation_fulfilled",
|
|
476
|
+
component: "senses",
|
|
477
|
+
message: "obligation fulfilled via delegated completion",
|
|
478
|
+
meta: {
|
|
479
|
+
friendId: delegatedFrom.friendId,
|
|
480
|
+
channel: delegatedFrom.channel,
|
|
481
|
+
key: delegatedFrom.key,
|
|
482
|
+
},
|
|
483
|
+
});
|
|
484
|
+
}
|
|
289
485
|
const outboundEnvelope = {
|
|
290
486
|
from: agentName,
|
|
291
487
|
friendId: delegatedFrom.friendId,
|
|
@@ -294,36 +490,62 @@ async function routeDelegatedCompletion(agentRoot, agentName, completion, draine
|
|
|
294
490
|
content: completion.answer.trim(),
|
|
295
491
|
timestamp,
|
|
296
492
|
delegatedFrom,
|
|
493
|
+
...(obligationId ? { obligationId } : {}),
|
|
297
494
|
};
|
|
298
495
|
const sessionActivity = (0, session_activity_1.listSessionActivity)({
|
|
299
496
|
sessionsDir: path.join(agentRoot, "state", "sessions"),
|
|
300
497
|
friendsDir: path.join(agentRoot, "friends"),
|
|
301
498
|
agentName,
|
|
302
499
|
});
|
|
500
|
+
// Priority 1: Bridge-preferred session (if delegation was within a bridge).
|
|
303
501
|
const bridgeTarget = resolveBridgePreferredSession(delegatedFrom, sessionActivity);
|
|
304
502
|
if (bridgeTarget) {
|
|
305
503
|
if (await tryDeliverDelegatedCompletion(bridgeTarget, outboundEnvelope)) {
|
|
504
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "bridge-session" });
|
|
306
505
|
return;
|
|
307
506
|
}
|
|
308
507
|
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, bridgeTarget.friendId, bridgeTarget.channel, bridgeTarget.key), outboundEnvelope);
|
|
508
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "bridge-session" });
|
|
309
509
|
return;
|
|
310
510
|
}
|
|
311
|
-
|
|
511
|
+
// Priority 1.5: Direct return to originating session (ponder without bridge).
|
|
512
|
+
// When delegatedFrom has specific channel+key, route directly there instead of searching for freshest.
|
|
513
|
+
if (delegatedFrom.channel && delegatedFrom.key && delegatedFrom.channel !== "inner") {
|
|
514
|
+
const directTarget = sessionActivity.find((a) => a.friendId === delegatedFrom.friendId && a.channel === delegatedFrom.channel && a.key === delegatedFrom.key);
|
|
515
|
+
if (directTarget) {
|
|
516
|
+
if (await tryDeliverDelegatedCompletion(directTarget, outboundEnvelope)) {
|
|
517
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "direct-originator" });
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
// Even if session isn't in activity list (might have ended), queue to its pending dir
|
|
522
|
+
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, delegatedFrom.friendId, delegatedFrom.channel, delegatedFrom.key), outboundEnvelope);
|
|
523
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "direct-originator" });
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
// Priority 2: Freshest active friend session.
|
|
527
|
+
// For BB, prefer DM sessions (;-;) over group chats (;+;) — proactive outreach should never land in groups.
|
|
528
|
+
const allFriendSessions = (0, session_activity_1.listSessionActivity)({
|
|
312
529
|
sessionsDir: path.join(agentRoot, "state", "sessions"),
|
|
313
530
|
friendsDir: path.join(agentRoot, "friends"),
|
|
314
531
|
agentName,
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if (freshest
|
|
532
|
+
}).filter((s) => s.friendId === delegatedFrom.friendId && s.channel !== "inner");
|
|
533
|
+
const bbDm = allFriendSessions.find((s) => s.channel === "bluebubbles" && s.key.includes(";-;"));
|
|
534
|
+
const freshest = bbDm ?? allFriendSessions.find((s) => s.channel !== "bluebubbles" || s.key.includes(";-;")) ?? allFriendSessions[0];
|
|
535
|
+
if (freshest) {
|
|
319
536
|
if (await tryDeliverDelegatedCompletion(freshest, outboundEnvelope)) {
|
|
537
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "freshest-session" });
|
|
320
538
|
return;
|
|
321
539
|
}
|
|
322
540
|
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, freshest.friendId, freshest.channel, freshest.key), outboundEnvelope);
|
|
541
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "freshest-session" });
|
|
323
542
|
return;
|
|
324
543
|
}
|
|
544
|
+
// Priority 3: Deferred return queue.
|
|
325
545
|
writePendingEnvelope((0, pending_1.getDeferredReturnDir)(agentName, delegatedFrom.friendId), outboundEnvelope);
|
|
546
|
+
advanceObligationQuietly(agentName, obligationId, { status: "deferred", returnedAt: timestamp, returnTarget: "deferred" });
|
|
326
547
|
}
|
|
548
|
+
/* v8 ignore stop */
|
|
327
549
|
// Self-referencing friend record for inner dialog (agent talking to itself).
|
|
328
550
|
// No real friend to resolve -- this satisfies the pipeline's friend resolver contract.
|
|
329
551
|
function createSelfFriend(agentName) {
|
|
@@ -350,12 +572,81 @@ function createNoOpFriendStore() {
|
|
|
350
572
|
findByExternalId: async () => null,
|
|
351
573
|
};
|
|
352
574
|
}
|
|
575
|
+
function buildParseErrorNudge(parseErrors) {
|
|
576
|
+
if (parseErrors.length === 0)
|
|
577
|
+
return "";
|
|
578
|
+
const lines = parseErrors.map((e) => `I noticed my habit file \`${e.file}\` has invalid frontmatter — I should fix it. (${e.error})`);
|
|
579
|
+
return lines.join("\n");
|
|
580
|
+
}
|
|
581
|
+
function buildHeldReturnWakeMessage() {
|
|
582
|
+
return [
|
|
583
|
+
"held return work arrived; use the current held-work frame above as the authority for this turn.",
|
|
584
|
+
"Older checkpoints, rest summaries, transcript memories, completed returns, and repeated probes are historical context, not evidence about what is waiting now.",
|
|
585
|
+
"Return only the requested result; do not add commentary about prior attempts, old loops, or completed probes.",
|
|
586
|
+
"Return each listed item with surface(delegationId=...) before resting or settling.",
|
|
587
|
+
].join("\n");
|
|
588
|
+
}
|
|
589
|
+
function buildAlsoDueLine(agentRoot, currentHabitName, now) {
|
|
590
|
+
const habitsDir = path.join(agentRoot, "habits");
|
|
591
|
+
let files;
|
|
592
|
+
try {
|
|
593
|
+
files = fs.readdirSync(habitsDir);
|
|
594
|
+
}
|
|
595
|
+
catch {
|
|
596
|
+
return "";
|
|
597
|
+
}
|
|
598
|
+
const nowMs = now().getTime();
|
|
599
|
+
const alsoDue = [];
|
|
600
|
+
for (const file of files) {
|
|
601
|
+
if (!file.endsWith(".md"))
|
|
602
|
+
continue;
|
|
603
|
+
const stem = file.replace(/\.md$/, "");
|
|
604
|
+
if (stem === currentHabitName)
|
|
605
|
+
continue;
|
|
606
|
+
try {
|
|
607
|
+
const content = fs.readFileSync(path.join(habitsDir, file), "utf-8");
|
|
608
|
+
const habit = (0, habit_runtime_state_1.applyHabitRuntimeState)(agentRoot, (0, habit_parser_1.parseHabitFile)(content, path.join(habitsDir, file)));
|
|
609
|
+
if (habit.status !== "active" || !habit.cadence)
|
|
610
|
+
continue;
|
|
611
|
+
const cadenceMs = (0, cadence_1.parseCadenceToMs)(habit.cadence);
|
|
612
|
+
if (cadenceMs === null)
|
|
613
|
+
continue;
|
|
614
|
+
if (habit.lastRun === null) {
|
|
615
|
+
alsoDue.push(stem);
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
const lastRunMs = new Date(habit.lastRun).getTime();
|
|
619
|
+
if (nowMs - lastRunMs >= cadenceMs) {
|
|
620
|
+
alsoDue.push(stem);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
catch {
|
|
624
|
+
// skip unreadable habits
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (alsoDue.length === 0)
|
|
628
|
+
return "";
|
|
629
|
+
return `also due: ${alsoDue.join(", ")}`;
|
|
630
|
+
}
|
|
631
|
+
function buildHabitSurfacePolicy(origin, surface) {
|
|
632
|
+
const lines = ["## habit surface policy"];
|
|
633
|
+
lines.push("this habit runs privately, but it may message outward when it needs input, has a useful answer, is blocked, or should report status.");
|
|
634
|
+
if (surface.family)
|
|
635
|
+
lines.push("- family recipients are allowed by default.");
|
|
636
|
+
if (surface.originator && origin)
|
|
637
|
+
lines.push(`- the originator is allowed: ${origin.friendId} via ${origin.channel}/${origin.key}.`);
|
|
638
|
+
if (surface.originator && !origin)
|
|
639
|
+
lines.push("- originator messaging is enabled, but this habit has no origin metadata.");
|
|
640
|
+
if (surface.extra.length > 0)
|
|
641
|
+
lines.push(`- extra allowed recipients: ${surface.extra.join(", ")}.`);
|
|
642
|
+
lines.push("- use send_message for intentional contact; use surface only for a held return tied to an existing return obligation.");
|
|
643
|
+
return lines.join("\n");
|
|
644
|
+
}
|
|
353
645
|
async function runInnerDialogTurn(options) {
|
|
354
646
|
const now = options?.now ?? (() => new Date());
|
|
355
|
-
const reason = options?.reason ?? "
|
|
647
|
+
const reason = options?.reason ?? "instinct";
|
|
356
648
|
const sessionFilePath = innerDialogSessionPath();
|
|
357
649
|
const agentName = (0, identity_1.getAgentName)();
|
|
358
|
-
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
359
650
|
writeInnerDialogRuntimeState(sessionFilePath, {
|
|
360
651
|
status: "running",
|
|
361
652
|
reason,
|
|
@@ -370,8 +661,14 @@ async function runInnerDialogTurn(options) {
|
|
|
370
661
|
resting: false,
|
|
371
662
|
lastHeartbeatAt: now().toISOString(),
|
|
372
663
|
};
|
|
664
|
+
const pendingDir = (0, pending_1.getInnerDialogPendingDir)(agentName);
|
|
665
|
+
const shouldUseHeldReturnWake = !options?.taskId && reason !== "habit" && reason !== "await"
|
|
666
|
+
? (0, obligations_1.listActiveReturnObligations)(agentName).length > 0
|
|
667
|
+
: false;
|
|
373
668
|
// ── Adapter concern: build user message ──────────────────────────
|
|
374
669
|
let userContent;
|
|
670
|
+
let habitTools;
|
|
671
|
+
let habitParsedSuccessfully = false;
|
|
375
672
|
if (existingMessages.length === 0) {
|
|
376
673
|
// Fresh session: bootstrap message with non-canonical cleanup nudge
|
|
377
674
|
const aspirations = readAspirations((0, identity_1.getAgentRoot)());
|
|
@@ -391,32 +688,177 @@ async function runInnerDialogTurn(options) {
|
|
|
391
688
|
const taskContent = readTaskFile((0, identity_1.getAgentRoot)(), options.taskId);
|
|
392
689
|
userContent = buildTaskTriggeredMessage(options.taskId, taskContent, state.checkpoint);
|
|
393
690
|
}
|
|
691
|
+
else if (reason === "habit" && options?.habitName) {
|
|
692
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
693
|
+
const habitName = options.habitName;
|
|
694
|
+
const habitFilePath = path.join(agentRoot, "habits", `${habitName}.md`);
|
|
695
|
+
// Read and parse the habit file
|
|
696
|
+
let habitBody;
|
|
697
|
+
let habitTitle = habitName;
|
|
698
|
+
let habitLastRun = null;
|
|
699
|
+
let habitOrigin = null;
|
|
700
|
+
let habitSurface = { family: true, originator: true, extra: [] };
|
|
701
|
+
try {
|
|
702
|
+
const habitContent = fs.readFileSync(habitFilePath, "utf-8");
|
|
703
|
+
const parsed = (0, habit_runtime_state_1.applyHabitRuntimeState)(agentRoot, (0, habit_parser_1.parseHabitFile)(habitContent, habitFilePath));
|
|
704
|
+
habitBody = parsed.body || undefined;
|
|
705
|
+
habitTitle = parsed.title || habitName;
|
|
706
|
+
habitLastRun = parsed.lastRun;
|
|
707
|
+
habitTools = parsed.tools;
|
|
708
|
+
habitOrigin = parsed.origin;
|
|
709
|
+
habitSurface = parsed.surface;
|
|
710
|
+
}
|
|
711
|
+
catch {
|
|
712
|
+
// Habit file missing or unreadable
|
|
713
|
+
}
|
|
714
|
+
// If the habit file couldn't be read at all (no body, no title parsed), error message
|
|
715
|
+
if (habitBody === undefined && habitTitle === habitName) {
|
|
716
|
+
userContent = `habit "${habitName}" could not be read (file not found or unreadable). check habits/${habitName}.md exists.`;
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
habitParsedSuccessfully = true;
|
|
720
|
+
// Unified path: gather context for ALL habits (heartbeat included)
|
|
721
|
+
const obligations = (0, obligations_1.listActiveReturnObligations)(agentName);
|
|
722
|
+
const nowMs = now().getTime();
|
|
723
|
+
const staleObligations = obligations.map((o) => ({
|
|
724
|
+
friendName: o.origin.friendId,
|
|
725
|
+
content: o.delegatedContent,
|
|
726
|
+
stalenessMs: nowMs - o.createdAt,
|
|
727
|
+
}));
|
|
728
|
+
const alsoDue = buildAlsoDueLine(agentRoot, habitName, now);
|
|
729
|
+
const arcResume = (0, flight_recorder_1.formatFlightRecorderResume)((0, flight_recorder_1.readFlightRecorderResume)(agentRoot));
|
|
730
|
+
const deskOrientation = (0, desk_section_1.deskRecordOrientationSection)(agentRoot, now());
|
|
731
|
+
const surfacePolicy = buildHabitSurfacePolicy(habitOrigin, habitSurface);
|
|
732
|
+
// Degraded state (best-effort: never crash)
|
|
733
|
+
let degradedComponents = [];
|
|
734
|
+
try {
|
|
735
|
+
const health = (0, daemon_health_1.readHealth)((0, daemon_health_1.getDefaultHealthPath)());
|
|
736
|
+
if (health && health.degraded.length > 0) {
|
|
737
|
+
degradedComponents = health.degraded.map((d) => ({ component: d.component, reason: d.reason }));
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
catch {
|
|
741
|
+
// Best-effort: missing file or parse error -> empty array, no crash
|
|
742
|
+
}
|
|
743
|
+
userContent = (0, habit_turn_message_1.buildHabitTurnMessage)({
|
|
744
|
+
habitName,
|
|
745
|
+
habitTitle,
|
|
746
|
+
habitBody,
|
|
747
|
+
lastRun: habitLastRun,
|
|
748
|
+
checkpoint: displayCheckpoint(state.checkpoint),
|
|
749
|
+
alsoDue: alsoDue || undefined,
|
|
750
|
+
staleObligations,
|
|
751
|
+
parseErrors: options?.parseErrors ?? [],
|
|
752
|
+
degradedComponents,
|
|
753
|
+
arcResume,
|
|
754
|
+
deskOrientation,
|
|
755
|
+
surfacePolicy,
|
|
756
|
+
now,
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
else if (reason === "await" && options?.awaitName) {
|
|
761
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
762
|
+
const awaitName = options.awaitName;
|
|
763
|
+
const awaitFilePath = path.join(agentRoot, "awaiting", `${awaitName}.md`);
|
|
764
|
+
let awaitBody;
|
|
765
|
+
let condition = null;
|
|
766
|
+
let lastCheckedAt = null;
|
|
767
|
+
let lastObservation = null;
|
|
768
|
+
let checkedCount = 0;
|
|
769
|
+
let awaitFound = false;
|
|
770
|
+
try {
|
|
771
|
+
const awaitContent = fs.readFileSync(awaitFilePath, "utf-8");
|
|
772
|
+
const parsed = (0, await_runtime_state_1.applyAwaitRuntimeState)(agentRoot, (0, await_parser_1.parseAwaitFile)(awaitContent, awaitFilePath));
|
|
773
|
+
awaitFound = true;
|
|
774
|
+
awaitBody = parsed.body || undefined;
|
|
775
|
+
condition = parsed.condition;
|
|
776
|
+
lastCheckedAt = parsed.last_checked ?? null;
|
|
777
|
+
lastObservation = parsed.last_observation ?? null;
|
|
778
|
+
checkedCount = parsed.checked_count ?? 0;
|
|
779
|
+
}
|
|
780
|
+
catch {
|
|
781
|
+
// file missing — fall through to error message
|
|
782
|
+
}
|
|
783
|
+
if (!awaitFound || !condition) {
|
|
784
|
+
userContent = `await "${awaitName}" could not be read (file not found or no condition). check awaiting/${awaitName}.md.`;
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
userContent = (0, await_turn_message_1.buildAwaitTurnMessage)({
|
|
788
|
+
awaitName,
|
|
789
|
+
condition,
|
|
790
|
+
body: awaitBody,
|
|
791
|
+
lastCheckedAt,
|
|
792
|
+
lastObservation,
|
|
793
|
+
checkedCount,
|
|
794
|
+
checkpoint: displayCheckpoint(state.checkpoint),
|
|
795
|
+
now,
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
}
|
|
394
799
|
else {
|
|
395
800
|
userContent = buildInstinctUserMessage(instincts, reason, state);
|
|
396
801
|
}
|
|
397
802
|
}
|
|
803
|
+
if (shouldUseHeldReturnWake) {
|
|
804
|
+
userContent = buildHeldReturnWakeMessage();
|
|
805
|
+
}
|
|
398
806
|
const userMessage = { role: "user", content: userContent };
|
|
399
807
|
// ── Session loader: wraps existing session logic ──────────────────
|
|
400
808
|
const innerCapabilities = (0, channel_1.getChannelCapabilities)("inner");
|
|
401
|
-
const pendingDir = (0, pending_1.getInnerDialogPendingDir)(agentName);
|
|
402
809
|
const selfFriend = createSelfFriend(agentName);
|
|
403
810
|
const selfContext = { friend: selfFriend, channel: innerCapabilities };
|
|
811
|
+
const mcpManager = await (0, mcp_manager_1.getSharedMcpManager)() ?? undefined;
|
|
812
|
+
// ── Habit tool enforcement ───────────────────────────────────────
|
|
813
|
+
let habitToolsResolved;
|
|
814
|
+
if (habitTools !== undefined) {
|
|
815
|
+
const fullTools = (0, tools_1.getToolsForChannel)(innerCapabilities);
|
|
816
|
+
habitToolsResolved = fullTools.filter((t) => habitTools.includes(t.function.name));
|
|
817
|
+
(0, runtime_1.emitNervesEvent)({
|
|
818
|
+
event: "habit.tools_restricted",
|
|
819
|
+
component: "senses",
|
|
820
|
+
message: "habit running with restricted tools",
|
|
821
|
+
meta: {
|
|
822
|
+
habitName: options?.habitName,
|
|
823
|
+
declared: habitTools,
|
|
824
|
+
resolved: habitToolsResolved.map((t) => t.function.name),
|
|
825
|
+
},
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
else if (reason === "habit" && options?.habitName && habitParsedSuccessfully) {
|
|
829
|
+
(0, runtime_1.emitNervesEvent)({
|
|
830
|
+
event: "habit.tools_unrestricted",
|
|
831
|
+
component: "senses",
|
|
832
|
+
message: "habit running with full tool repertoire",
|
|
833
|
+
meta: { habitName: options.habitName },
|
|
834
|
+
});
|
|
835
|
+
}
|
|
404
836
|
const sessionLoader = {
|
|
405
837
|
loadOrCreate: async () => {
|
|
406
838
|
if (existingMessages.length > 0) {
|
|
407
|
-
return {
|
|
839
|
+
return {
|
|
840
|
+
messages: existingMessages,
|
|
841
|
+
sessionPath: sessionFilePath,
|
|
842
|
+
structuredOutputs: loaded?.structuredOutputs,
|
|
843
|
+
};
|
|
408
844
|
}
|
|
409
845
|
// Fresh session: build system prompt
|
|
410
|
-
const systemPrompt = await (0, prompt_1.buildSystem)("inner", {
|
|
846
|
+
const systemPrompt = await (0, prompt_1.buildSystem)("inner", {
|
|
847
|
+
toolChoiceRequired: true,
|
|
848
|
+
flightRecorderResume: (0, flight_recorder_1.readFlightRecorderResume)((0, identity_1.getAgentRoot)()),
|
|
849
|
+
});
|
|
411
850
|
return {
|
|
412
|
-
messages: [{ role: "system", content: systemPrompt }],
|
|
851
|
+
messages: [{ role: "system", content: (0, prompt_1.flattenSystemPrompt)(systemPrompt) }],
|
|
413
852
|
sessionPath: sessionFilePath,
|
|
853
|
+
structuredOutputs: [],
|
|
414
854
|
};
|
|
415
855
|
},
|
|
416
856
|
};
|
|
417
857
|
// ── Call shared pipeline ──────────────────────────────────────────
|
|
418
858
|
const callbacks = createInnerDialogCallbacks();
|
|
419
859
|
const traceId = (0, nerves_1.createTraceId)();
|
|
860
|
+
// Attention queue: built when pending messages are drained, shared with tool context
|
|
861
|
+
let attentionQueue = [];
|
|
420
862
|
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
421
863
|
channel: "inner",
|
|
422
864
|
sessionKey: "dialog",
|
|
@@ -431,16 +873,56 @@ async function runInnerDialogTurn(options) {
|
|
|
431
873
|
enforceTrustGate: trust_gate_1.enforceTrustGate,
|
|
432
874
|
drainPending: pending_1.drainPending,
|
|
433
875
|
runAgent: core_1.runAgent,
|
|
434
|
-
postTurn:
|
|
876
|
+
postTurn: (turnMessages, sessionPathArg, usage, hooks, state) => {
|
|
877
|
+
const prepared = (0, context_1.postTurnTrim)(turnMessages, usage, hooks);
|
|
878
|
+
(0, context_1.deferPostTurnPersist)(sessionPathArg, prepared, usage, state);
|
|
879
|
+
},
|
|
435
880
|
accumulateFriendTokens: tokens_1.accumulateFriendTokens,
|
|
436
881
|
signal: options?.signal,
|
|
882
|
+
/* v8 ignore start -- attention queue: callback invoked by pipeline during pending drain; tested via attention-queue unit tests @preserve */
|
|
883
|
+
onPendingDrained: (drained) => {
|
|
884
|
+
const outstandingObligations = (0, obligations_1.listActiveReturnObligations)(agentName);
|
|
885
|
+
const builtAttentionQueue = (0, attention_queue_1.buildAttentionQueue)({
|
|
886
|
+
drainedPending: drained,
|
|
887
|
+
outstandingObligations,
|
|
888
|
+
friendNameResolver: (friendId) => {
|
|
889
|
+
try {
|
|
890
|
+
const raw = fs.readFileSync(path.join((0, identity_1.getAgentRoot)(agentName), "friends", friendId + ".json"), "utf-8");
|
|
891
|
+
const parsed = JSON.parse(raw);
|
|
892
|
+
return typeof parsed.name === "string" ? parsed.name : null;
|
|
893
|
+
}
|
|
894
|
+
catch {
|
|
895
|
+
return null;
|
|
896
|
+
}
|
|
897
|
+
},
|
|
898
|
+
packetResolver: (packetId) => {
|
|
899
|
+
try {
|
|
900
|
+
return (0, packets_1.readPonderPacket)((0, identity_1.getAgentRoot)(agentName), packetId);
|
|
901
|
+
}
|
|
902
|
+
catch {
|
|
903
|
+
return null;
|
|
904
|
+
}
|
|
905
|
+
},
|
|
906
|
+
});
|
|
907
|
+
attentionQueue.splice(0, attentionQueue.length, ...builtAttentionQueue);
|
|
908
|
+
const attentionFrame = (0, attention_queue_1.buildAttentionQueueStatusFrame)(attentionQueue);
|
|
909
|
+
return attentionFrame ? [attentionFrame] : [];
|
|
910
|
+
},
|
|
911
|
+
/* v8 ignore stop */
|
|
437
912
|
runAgentOptions: {
|
|
438
913
|
traceId,
|
|
439
914
|
toolChoiceRequired: true,
|
|
440
|
-
|
|
915
|
+
mcpManager,
|
|
916
|
+
...(habitToolsResolved !== undefined && { tools: habitToolsResolved }),
|
|
917
|
+
toolContext: {
|
|
918
|
+
signin: async () => undefined,
|
|
919
|
+
delegatedOrigins: attentionQueue,
|
|
920
|
+
},
|
|
441
921
|
},
|
|
442
922
|
});
|
|
443
|
-
|
|
923
|
+
// Post-turn routeDelegatedCompletion removed: delivery is now inline via surface tool.
|
|
924
|
+
// settle in inner dialog produces no CompletionMetadata, so routeDelegatedCompletion
|
|
925
|
+
// would be a no-op. The routing infrastructure is reused by the surface handler.
|
|
444
926
|
const resultMessages = result.messages ?? [];
|
|
445
927
|
const assistantPreview = extractAssistantPreview(resultMessages);
|
|
446
928
|
const toolCalls = extractToolCallNames(resultMessages);
|
|
@@ -466,6 +948,8 @@ async function runInnerDialogTurn(options) {
|
|
|
466
948
|
usage: result.usage,
|
|
467
949
|
sessionPath: result.sessionPath ?? sessionFilePath,
|
|
468
950
|
completion: result.completion,
|
|
951
|
+
turnOutcome: result.turnOutcome,
|
|
952
|
+
restStatus: latestRestStatus(resultMessages),
|
|
469
953
|
};
|
|
470
954
|
}
|
|
471
955
|
finally {
|