@ouro.bot/cli 0.1.0-alpha.49 → 0.1.0-alpha.490
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 +133 -19
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -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 +3118 -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 +237 -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 +989 -0
- package/dist/heart/agent-entry.js +58 -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 +426 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bridges/manager.js +37 -0
- package/dist/heart/bridges/state-machine.js +20 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +304 -0
- package/dist/heart/config.js +119 -129
- package/dist/heart/core.js +758 -227
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +490 -0
- package/dist/heart/daemon/agent-discovery.js +79 -3
- package/dist/heart/daemon/agent-service.js +360 -0
- package/dist/heart/daemon/agentic-repair.js +216 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +640 -0
- package/dist/heart/daemon/cli-exec.js +7229 -0
- package/dist/heart/daemon/cli-help.js +493 -0
- package/dist/heart/daemon/cli-parse.js +1533 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +561 -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 -1616
- package/dist/heart/daemon/daemon-entry.js +345 -3
- package/dist/heart/daemon/daemon-health.js +141 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +190 -12
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +677 -58
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +486 -0
- package/dist/heart/daemon/health-monitor.js +92 -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 +25 -5
- package/dist/heart/daemon/log-tailer.js +82 -12
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/message-router.js +2 -2
- package/dist/heart/daemon/os-cron-deps.js +134 -0
- 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 +214 -0
- 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 +67 -16
- package/dist/heart/daemon/runtime-metadata.js +73 -0
- package/dist/heart/daemon/runtime-mode.js +67 -0
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +178 -37
- 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 +109 -4
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +264 -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 +62 -0
- 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 +52 -117
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
- 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 +201 -66
- 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/mcp/mcp-server.js +653 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +59 -0
- package/dist/heart/outlook/outlook-http-hooks.js +66 -0
- package/dist/heart/outlook/outlook-http-response.js +7 -0
- package/dist/heart/outlook/outlook-http-routes.js +244 -0
- package/dist/heart/outlook/outlook-http-static.js +103 -0
- package/dist/heart/outlook/outlook-http-transport.js +116 -0
- package/dist/heart/outlook/outlook-http.js +99 -0
- package/dist/heart/outlook/outlook-read.js +31 -0
- package/dist/heart/outlook/outlook-types.js +27 -0
- package/dist/heart/outlook/outlook-view.js +195 -0
- package/dist/heart/outlook/readers/agent-machine.js +382 -0
- package/dist/heart/outlook/readers/continuity-readers.js +336 -0
- package/dist/heart/outlook/readers/mail.js +362 -0
- package/dist/heart/outlook/readers/runtime-readers.js +644 -0
- package/dist/heart/outlook/readers/sessions.js +232 -0
- package/dist/heart/outlook/readers/shared.js +111 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +255 -0
- package/dist/heart/provider-credentials.js +424 -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-state.js +216 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +193 -55
- package/dist/heart/providers/azure.js +104 -13
- package/dist/heart/providers/error-classification.js +63 -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 +29 -7
- package/dist/heart/providers/openai-codex.js +63 -39
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +260 -0
- package/dist/heart/sense-truth.js +11 -4
- package/dist/heart/session-activity.js +190 -0
- package/dist/heart/session-events.js +981 -0
- package/dist/heart/session-transcript.js +167 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +48 -28
- package/dist/heart/sync.js +332 -0
- package/dist/heart/target-resolution.js +127 -0
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/tool-activity-callbacks.js +36 -0
- package/dist/heart/tool-description.js +135 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +372 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +425 -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 +5 -1
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +600 -0
- package/dist/mailroom/core.js +658 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +426 -0
- package/dist/mailroom/mbox-import.js +382 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +219 -0
- package/dist/mailroom/search-cache.js +182 -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/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +7 -1
- package/dist/mind/context.js +164 -93
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +74 -93
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +30 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +39 -3
- package/dist/mind/friends/trust-explanation.js +74 -0
- 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 +56 -8
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +973 -168
- 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 +93 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- 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/runtime.js +5 -1
- package/dist/outlook-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/outlook-ui/assets/index-Cm51CY9W.js +61 -0
- package/dist/outlook-ui/index.html +15 -0
- 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 +774 -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 +111 -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 +255 -0
- package/dist/repertoire/mcp-manager.js +305 -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-base.js +46 -842
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +141 -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 +105 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1281 -0
- package/dist/repertoire/tools-notes.js +376 -0
- package/dist/repertoire/tools-session.js +749 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +243 -0
- package/dist/repertoire/tools-teams.js +9 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +280 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools.js +144 -115
- 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 +561 -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/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 +73 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
- package/dist/senses/bluebubbles/index.js +1835 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
- 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 +111 -0
- package/dist/senses/bluebubbles/replay.js +129 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +2 -2
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- 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 +605 -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 +83 -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 +187 -0
- package/dist/senses/cli.js +515 -211
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +110 -20
- package/dist/senses/inner-dialog.js +408 -21
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +588 -81
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +205 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +412 -163
- package/dist/senses/trust-gate.js +100 -5
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +146 -0
- package/package.json +37 -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 +101 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -166
- 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 -1032
- package/dist/senses/debug-activity.js +0 -127
- 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,14 +52,28 @@ 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");
|
|
57
65
|
const pipeline_1 = require("./pipeline");
|
|
58
66
|
const nerves_1 = require("../nerves");
|
|
59
67
|
const runtime_1 = require("../nerves/runtime");
|
|
68
|
+
const manager_1 = require("../heart/bridges/manager");
|
|
69
|
+
const session_activity_1 = require("../heart/session-activity");
|
|
70
|
+
const bluebubbles_1 = require("./bluebubbles");
|
|
71
|
+
const habit_turn_message_1 = require("./habit-turn-message");
|
|
72
|
+
const journal_index_1 = require("../mind/journal-index");
|
|
73
|
+
const habit_parser_1 = require("../heart/habits/habit-parser");
|
|
74
|
+
const habit_runtime_state_1 = require("../heart/habits/habit-runtime-state");
|
|
75
|
+
const cadence_1 = require("../heart/daemon/cadence");
|
|
76
|
+
const daemon_health_1 = require("../heart/daemon/daemon-health");
|
|
60
77
|
const DEFAULT_INNER_DIALOG_INSTINCTS = [
|
|
61
78
|
{
|
|
62
79
|
id: "heartbeat_checkin",
|
|
@@ -95,23 +112,31 @@ function buildNonCanonicalCleanupNudge(nonCanonicalPaths) {
|
|
|
95
112
|
}
|
|
96
113
|
return [
|
|
97
114
|
"## canonical cleanup nudge",
|
|
98
|
-
"I found non-canonical files in my bundle. I should distill anything valuable into
|
|
115
|
+
"I found non-canonical files in my bundle. I should distill anything valuable into my diary and remove these files.",
|
|
99
116
|
...listed,
|
|
100
117
|
].join("\n");
|
|
101
118
|
}
|
|
119
|
+
function displayCheckpoint(checkpoint) {
|
|
120
|
+
const trimmed = checkpoint?.trim();
|
|
121
|
+
if (!trimmed || trimmed === "no prior checkpoint recorded") {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
return trimmed;
|
|
125
|
+
}
|
|
102
126
|
function buildInstinctUserMessage(instincts, _reason, state) {
|
|
103
127
|
const active = instincts.find((instinct) => instinct.enabled !== false) ?? DEFAULT_INNER_DIALOG_INSTINCTS[0];
|
|
104
|
-
const checkpoint = state.checkpoint
|
|
128
|
+
const checkpoint = displayCheckpoint(state.checkpoint);
|
|
105
129
|
const lines = [active.prompt];
|
|
106
130
|
if (checkpoint) {
|
|
107
|
-
lines.push(`\nlast
|
|
131
|
+
lines.push(`\nlast checkpoint: ${checkpoint}`);
|
|
108
132
|
}
|
|
109
133
|
return lines.join("\n");
|
|
110
134
|
}
|
|
111
135
|
function readTaskFile(agentRoot, taskId) {
|
|
112
|
-
// Task files live in collection subdirectories (one-shots, ongoing
|
|
136
|
+
// Task files live in collection subdirectories (one-shots, ongoing).
|
|
113
137
|
// Try each collection, then fall back to root tasks/ for legacy layout.
|
|
114
|
-
|
|
138
|
+
// Habits are no longer in tasks/ — they live at bundle root habits/.
|
|
139
|
+
const collections = ["one-shots", "ongoing", ""];
|
|
115
140
|
for (const collection of collections) {
|
|
116
141
|
try {
|
|
117
142
|
return fs.readFileSync(path.join(agentRoot, "tasks", collection, `${taskId}.md`), "utf8").trim();
|
|
@@ -130,8 +155,9 @@ function buildTaskTriggeredMessage(taskId, taskContent, checkpoint) {
|
|
|
130
155
|
else {
|
|
131
156
|
lines.push("", `## task: ${taskId}`, "(task file not found)");
|
|
132
157
|
}
|
|
133
|
-
|
|
134
|
-
|
|
158
|
+
const renderedCheckpoint = displayCheckpoint(checkpoint);
|
|
159
|
+
if (renderedCheckpoint) {
|
|
160
|
+
lines.push("", `last checkpoint: ${renderedCheckpoint}`);
|
|
135
161
|
}
|
|
136
162
|
return lines.join("\n");
|
|
137
163
|
}
|
|
@@ -161,19 +187,17 @@ function deriveResumeCheckpoint(messages) {
|
|
|
161
187
|
const assistantText = contentToText(lastAssistant.content);
|
|
162
188
|
if (!assistantText)
|
|
163
189
|
return "no prior checkpoint recorded";
|
|
164
|
-
const
|
|
190
|
+
const cleanedLines = assistantText
|
|
165
191
|
.split("\n")
|
|
166
|
-
.map((line) => line.trim())
|
|
192
|
+
.map((line) => line.replace(/<\/?think>/gi, "").trim())
|
|
193
|
+
.filter((line) => line.length > 0);
|
|
194
|
+
const explicitCheckpoint = cleanedLines
|
|
167
195
|
.find((line) => /^checkpoint\s*:/i.test(line));
|
|
168
196
|
if (explicitCheckpoint) {
|
|
169
197
|
const parsed = explicitCheckpoint.replace(/^checkpoint\s*:\s*/i, "").trim();
|
|
170
198
|
return parsed || "no prior checkpoint recorded";
|
|
171
199
|
}
|
|
172
|
-
const firstLine =
|
|
173
|
-
.split("\n")
|
|
174
|
-
.map((line) => line.trim())
|
|
175
|
-
.find((line) => line.length > 0);
|
|
176
|
-
/* v8 ignore next -- unreachable: contentToText().trim() guarantees a non-empty line @preserve */
|
|
200
|
+
const firstLine = cleanedLines[0];
|
|
177
201
|
if (!firstLine)
|
|
178
202
|
return "no prior checkpoint recorded";
|
|
179
203
|
if (firstLine.length <= 220)
|
|
@@ -244,6 +268,179 @@ function writeInnerDialogRuntimeState(sessionFilePath, state) {
|
|
|
244
268
|
});
|
|
245
269
|
}
|
|
246
270
|
}
|
|
271
|
+
/* v8 ignore start -- routing helpers: called from routing functions which are integration paths @preserve */
|
|
272
|
+
function writePendingEnvelope(pendingDir, message) {
|
|
273
|
+
fs.mkdirSync(pendingDir, { recursive: true });
|
|
274
|
+
const fileName = `${message.timestamp}-${Math.random().toString(36).slice(2, 10)}.json`;
|
|
275
|
+
const filePath = path.join(pendingDir, fileName);
|
|
276
|
+
fs.writeFileSync(filePath, JSON.stringify(message, null, 2), "utf8");
|
|
277
|
+
}
|
|
278
|
+
function sessionMatchesActivity(activity, session) {
|
|
279
|
+
return activity.friendId === session.friendId
|
|
280
|
+
&& activity.channel === session.channel
|
|
281
|
+
&& activity.key === session.key;
|
|
282
|
+
}
|
|
283
|
+
/* v8 ignore stop */
|
|
284
|
+
/* v8 ignore start -- routing: delivery now inline via surface tool; routing functions preserved for reuse @preserve */
|
|
285
|
+
function resolveBridgePreferredSession(delegatedFrom, sessionActivity) {
|
|
286
|
+
if (!delegatedFrom.bridgeId)
|
|
287
|
+
return null;
|
|
288
|
+
const bridge = (0, manager_1.createBridgeManager)().getBridge(delegatedFrom.bridgeId);
|
|
289
|
+
if (!bridge || bridge.lifecycle === "completed" || bridge.lifecycle === "cancelled") {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
return sessionActivity.find((activity) => activity.friendId === delegatedFrom.friendId
|
|
293
|
+
&& activity.channel !== "inner"
|
|
294
|
+
&& bridge.attachedSessions.some((session) => sessionMatchesActivity(activity, session))) ?? null;
|
|
295
|
+
}
|
|
296
|
+
async function tryDeliverDelegatedCompletion(target, outboundEnvelope) {
|
|
297
|
+
if (target.channel !== "bluebubbles") {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
const result = await (0, bluebubbles_1.sendProactiveBlueBubblesMessageToSession)({
|
|
301
|
+
friendId: target.friendId,
|
|
302
|
+
sessionKey: target.key,
|
|
303
|
+
text: outboundEnvelope.content,
|
|
304
|
+
intent: "explicit_cross_chat",
|
|
305
|
+
});
|
|
306
|
+
return result.delivered;
|
|
307
|
+
}
|
|
308
|
+
function enrichDelegatedFromWithBridge(delegatedFrom) {
|
|
309
|
+
if (delegatedFrom.bridgeId) {
|
|
310
|
+
return delegatedFrom;
|
|
311
|
+
}
|
|
312
|
+
const bridgeManager = (0, manager_1.createBridgeManager)();
|
|
313
|
+
const originBridges = bridgeManager.findBridgesForSession({
|
|
314
|
+
friendId: delegatedFrom.friendId,
|
|
315
|
+
channel: delegatedFrom.channel,
|
|
316
|
+
key: delegatedFrom.key,
|
|
317
|
+
});
|
|
318
|
+
const activeBridge = originBridges.find((b) => b.lifecycle === "active");
|
|
319
|
+
if (activeBridge) {
|
|
320
|
+
return { ...delegatedFrom, bridgeId: activeBridge.id };
|
|
321
|
+
}
|
|
322
|
+
return delegatedFrom;
|
|
323
|
+
}
|
|
324
|
+
function advanceObligationQuietly(agentName, obligationId, update) {
|
|
325
|
+
if (!obligationId)
|
|
326
|
+
return;
|
|
327
|
+
try {
|
|
328
|
+
(0, obligations_1.advanceReturnObligation)(agentName, obligationId, update);
|
|
329
|
+
/* v8 ignore start -- best-effort: obligation fs errors must never block return routing @preserve */
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
// swallowed
|
|
333
|
+
}
|
|
334
|
+
/* v8 ignore stop */
|
|
335
|
+
}
|
|
336
|
+
async function routeDelegatedCompletion(agentRoot, agentName, completion, drainedPending, timestamp) {
|
|
337
|
+
const delegated = (drainedPending ?? []).find((message) => message.delegatedFrom);
|
|
338
|
+
if (!delegated?.delegatedFrom || !completion?.answer?.trim()) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const delegatedFrom = enrichDelegatedFromWithBridge(delegated.delegatedFrom);
|
|
342
|
+
const obligationId = delegated.obligationId;
|
|
343
|
+
// Advance any inner return obligations from queued -> running (they were drained this turn).
|
|
344
|
+
// drainedPending is guaranteed non-null here (we found delegated above).
|
|
345
|
+
for (const msg of drainedPending) {
|
|
346
|
+
if (msg.obligationId) {
|
|
347
|
+
advanceObligationQuietly(agentName, msg.obligationId, {
|
|
348
|
+
status: "running",
|
|
349
|
+
startedAt: timestamp,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (delegated.obligationStatus === "pending") {
|
|
354
|
+
// Fulfill the persistent obligation in the store
|
|
355
|
+
try {
|
|
356
|
+
const pending = (0, obligations_1.findPendingObligationForOrigin)(agentRoot, {
|
|
357
|
+
friendId: delegatedFrom.friendId,
|
|
358
|
+
channel: delegatedFrom.channel,
|
|
359
|
+
key: delegatedFrom.key,
|
|
360
|
+
});
|
|
361
|
+
/* v8 ignore next 2 -- obligation fulfillment tested via obligations.test.ts; integration requires real disk state @preserve */
|
|
362
|
+
if (pending) {
|
|
363
|
+
(0, obligations_1.fulfillObligation)(agentRoot, pending.id);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
catch {
|
|
367
|
+
/* v8 ignore next -- defensive: obligation store read failure should not break delivery @preserve */
|
|
368
|
+
}
|
|
369
|
+
(0, runtime_1.emitNervesEvent)({
|
|
370
|
+
event: "senses.obligation_fulfilled",
|
|
371
|
+
component: "senses",
|
|
372
|
+
message: "obligation fulfilled via delegated completion",
|
|
373
|
+
meta: {
|
|
374
|
+
friendId: delegatedFrom.friendId,
|
|
375
|
+
channel: delegatedFrom.channel,
|
|
376
|
+
key: delegatedFrom.key,
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
const outboundEnvelope = {
|
|
381
|
+
from: agentName,
|
|
382
|
+
friendId: delegatedFrom.friendId,
|
|
383
|
+
channel: delegatedFrom.channel,
|
|
384
|
+
key: delegatedFrom.key,
|
|
385
|
+
content: completion.answer.trim(),
|
|
386
|
+
timestamp,
|
|
387
|
+
delegatedFrom,
|
|
388
|
+
...(obligationId ? { obligationId } : {}),
|
|
389
|
+
};
|
|
390
|
+
const sessionActivity = (0, session_activity_1.listSessionActivity)({
|
|
391
|
+
sessionsDir: path.join(agentRoot, "state", "sessions"),
|
|
392
|
+
friendsDir: path.join(agentRoot, "friends"),
|
|
393
|
+
agentName,
|
|
394
|
+
});
|
|
395
|
+
// Priority 1: Bridge-preferred session (if delegation was within a bridge).
|
|
396
|
+
const bridgeTarget = resolveBridgePreferredSession(delegatedFrom, sessionActivity);
|
|
397
|
+
if (bridgeTarget) {
|
|
398
|
+
if (await tryDeliverDelegatedCompletion(bridgeTarget, outboundEnvelope)) {
|
|
399
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "bridge-session" });
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, bridgeTarget.friendId, bridgeTarget.channel, bridgeTarget.key), outboundEnvelope);
|
|
403
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "bridge-session" });
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
// Priority 1.5: Direct return to originating session (ponder without bridge).
|
|
407
|
+
// When delegatedFrom has specific channel+key, route directly there instead of searching for freshest.
|
|
408
|
+
if (delegatedFrom.channel && delegatedFrom.key && delegatedFrom.channel !== "inner") {
|
|
409
|
+
const directTarget = sessionActivity.find((a) => a.friendId === delegatedFrom.friendId && a.channel === delegatedFrom.channel && a.key === delegatedFrom.key);
|
|
410
|
+
if (directTarget) {
|
|
411
|
+
if (await tryDeliverDelegatedCompletion(directTarget, outboundEnvelope)) {
|
|
412
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "direct-originator" });
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
// Even if session isn't in activity list (might have ended), queue to its pending dir
|
|
417
|
+
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, delegatedFrom.friendId, delegatedFrom.channel, delegatedFrom.key), outboundEnvelope);
|
|
418
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "direct-originator" });
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
// Priority 2: Freshest active friend session.
|
|
422
|
+
// For BB, prefer DM sessions (;-;) over group chats (;+;) — proactive outreach should never land in groups.
|
|
423
|
+
const allFriendSessions = (0, session_activity_1.listSessionActivity)({
|
|
424
|
+
sessionsDir: path.join(agentRoot, "state", "sessions"),
|
|
425
|
+
friendsDir: path.join(agentRoot, "friends"),
|
|
426
|
+
agentName,
|
|
427
|
+
}).filter((s) => s.friendId === delegatedFrom.friendId && s.channel !== "inner");
|
|
428
|
+
const bbDm = allFriendSessions.find((s) => s.channel === "bluebubbles" && s.key.includes(";-;"));
|
|
429
|
+
const freshest = bbDm ?? allFriendSessions.find((s) => s.channel !== "bluebubbles" || s.key.includes(";-;")) ?? allFriendSessions[0];
|
|
430
|
+
if (freshest) {
|
|
431
|
+
if (await tryDeliverDelegatedCompletion(freshest, outboundEnvelope)) {
|
|
432
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "freshest-session" });
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
writePendingEnvelope((0, pending_1.getPendingDir)(agentName, freshest.friendId, freshest.channel, freshest.key), outboundEnvelope);
|
|
436
|
+
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "freshest-session" });
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
// Priority 3: Deferred return queue.
|
|
440
|
+
writePendingEnvelope((0, pending_1.getDeferredReturnDir)(agentName, delegatedFrom.friendId), outboundEnvelope);
|
|
441
|
+
advanceObligationQuietly(agentName, obligationId, { status: "deferred", returnedAt: timestamp, returnTarget: "deferred" });
|
|
442
|
+
}
|
|
443
|
+
/* v8 ignore stop */
|
|
247
444
|
// Self-referencing friend record for inner dialog (agent talking to itself).
|
|
248
445
|
// No real friend to resolve -- this satisfies the pipeline's friend resolver contract.
|
|
249
446
|
function createSelfFriend(agentName) {
|
|
@@ -270,10 +467,59 @@ function createNoOpFriendStore() {
|
|
|
270
467
|
findByExternalId: async () => null,
|
|
271
468
|
};
|
|
272
469
|
}
|
|
470
|
+
function buildParseErrorNudge(parseErrors) {
|
|
471
|
+
if (parseErrors.length === 0)
|
|
472
|
+
return "";
|
|
473
|
+
const lines = parseErrors.map((e) => `I noticed my habit file \`${e.file}\` has invalid frontmatter — I should fix it. (${e.error})`);
|
|
474
|
+
return lines.join("\n");
|
|
475
|
+
}
|
|
476
|
+
function buildAlsoDueLine(agentRoot, currentHabitName, now) {
|
|
477
|
+
const habitsDir = path.join(agentRoot, "habits");
|
|
478
|
+
let files;
|
|
479
|
+
try {
|
|
480
|
+
files = fs.readdirSync(habitsDir);
|
|
481
|
+
}
|
|
482
|
+
catch {
|
|
483
|
+
return "";
|
|
484
|
+
}
|
|
485
|
+
const nowMs = now().getTime();
|
|
486
|
+
const alsoDue = [];
|
|
487
|
+
for (const file of files) {
|
|
488
|
+
if (!file.endsWith(".md"))
|
|
489
|
+
continue;
|
|
490
|
+
const stem = file.replace(/\.md$/, "");
|
|
491
|
+
if (stem === currentHabitName)
|
|
492
|
+
continue;
|
|
493
|
+
try {
|
|
494
|
+
const content = fs.readFileSync(path.join(habitsDir, file), "utf-8");
|
|
495
|
+
const habit = (0, habit_runtime_state_1.applyHabitRuntimeState)(agentRoot, (0, habit_parser_1.parseHabitFile)(content, path.join(habitsDir, file)));
|
|
496
|
+
if (habit.status !== "active" || !habit.cadence)
|
|
497
|
+
continue;
|
|
498
|
+
const cadenceMs = (0, cadence_1.parseCadenceToMs)(habit.cadence);
|
|
499
|
+
if (cadenceMs === null)
|
|
500
|
+
continue;
|
|
501
|
+
if (habit.lastRun === null) {
|
|
502
|
+
alsoDue.push(stem);
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
const lastRunMs = new Date(habit.lastRun).getTime();
|
|
506
|
+
if (nowMs - lastRunMs >= cadenceMs) {
|
|
507
|
+
alsoDue.push(stem);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
catch {
|
|
511
|
+
// skip unreadable habits
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (alsoDue.length === 0)
|
|
515
|
+
return "";
|
|
516
|
+
return `also due: ${alsoDue.join(", ")}`;
|
|
517
|
+
}
|
|
273
518
|
async function runInnerDialogTurn(options) {
|
|
274
519
|
const now = options?.now ?? (() => new Date());
|
|
275
|
-
const reason = options?.reason ?? "
|
|
520
|
+
const reason = options?.reason ?? "instinct";
|
|
276
521
|
const sessionFilePath = innerDialogSessionPath();
|
|
522
|
+
const agentName = (0, identity_1.getAgentName)();
|
|
277
523
|
writeInnerDialogRuntimeState(sessionFilePath, {
|
|
278
524
|
status: "running",
|
|
279
525
|
reason,
|
|
@@ -290,6 +536,8 @@ async function runInnerDialogTurn(options) {
|
|
|
290
536
|
};
|
|
291
537
|
// ── Adapter concern: build user message ──────────────────────────
|
|
292
538
|
let userContent;
|
|
539
|
+
let habitTools;
|
|
540
|
+
let habitParsedSuccessfully = false;
|
|
293
541
|
if (existingMessages.length === 0) {
|
|
294
542
|
// Fresh session: bootstrap message with non-canonical cleanup nudge
|
|
295
543
|
const aspirations = readAspirations((0, identity_1.getAgentRoot)());
|
|
@@ -309,6 +557,74 @@ async function runInnerDialogTurn(options) {
|
|
|
309
557
|
const taskContent = readTaskFile((0, identity_1.getAgentRoot)(), options.taskId);
|
|
310
558
|
userContent = buildTaskTriggeredMessage(options.taskId, taskContent, state.checkpoint);
|
|
311
559
|
}
|
|
560
|
+
else if (reason === "habit" && options?.habitName) {
|
|
561
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
562
|
+
const habitName = options.habitName;
|
|
563
|
+
const habitFilePath = path.join(agentRoot, "habits", `${habitName}.md`);
|
|
564
|
+
// Read and parse the habit file
|
|
565
|
+
let habitBody;
|
|
566
|
+
let habitTitle = habitName;
|
|
567
|
+
let habitLastRun = null;
|
|
568
|
+
try {
|
|
569
|
+
const habitContent = fs.readFileSync(habitFilePath, "utf-8");
|
|
570
|
+
const parsed = (0, habit_runtime_state_1.applyHabitRuntimeState)(agentRoot, (0, habit_parser_1.parseHabitFile)(habitContent, habitFilePath));
|
|
571
|
+
habitBody = parsed.body || undefined;
|
|
572
|
+
habitTitle = parsed.title || habitName;
|
|
573
|
+
habitLastRun = parsed.lastRun;
|
|
574
|
+
habitTools = parsed.tools;
|
|
575
|
+
}
|
|
576
|
+
catch {
|
|
577
|
+
// Habit file missing or unreadable
|
|
578
|
+
}
|
|
579
|
+
// If the habit file couldn't be read at all (no body, no title parsed), error message
|
|
580
|
+
if (habitBody === undefined && habitTitle === habitName) {
|
|
581
|
+
userContent = `habit "${habitName}" could not be read (file not found or unreadable). check habits/${habitName}.md exists.`;
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
habitParsedSuccessfully = true;
|
|
585
|
+
// Unified path: gather context for ALL habits (heartbeat included)
|
|
586
|
+
const obligations = (0, obligations_1.listActiveReturnObligations)(agentName);
|
|
587
|
+
const nowMs = now().getTime();
|
|
588
|
+
const staleObligations = obligations.map((o) => ({
|
|
589
|
+
friendName: o.origin.friendId,
|
|
590
|
+
content: o.delegatedContent,
|
|
591
|
+
stalenessMs: nowMs - o.createdAt,
|
|
592
|
+
}));
|
|
593
|
+
const alsoDue = buildAlsoDueLine(agentRoot, habitName, now);
|
|
594
|
+
// Degraded state (best-effort: never crash)
|
|
595
|
+
let degradedComponents = [];
|
|
596
|
+
try {
|
|
597
|
+
const health = (0, daemon_health_1.readHealth)((0, daemon_health_1.getDefaultHealthPath)());
|
|
598
|
+
if (health && health.degraded.length > 0) {
|
|
599
|
+
degradedComponents = health.degraded.map((d) => ({ component: d.component, reason: d.reason }));
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
catch {
|
|
603
|
+
// Best-effort: missing file or parse error -> empty array, no crash
|
|
604
|
+
}
|
|
605
|
+
userContent = (0, habit_turn_message_1.buildHabitTurnMessage)({
|
|
606
|
+
habitName,
|
|
607
|
+
habitTitle,
|
|
608
|
+
habitBody,
|
|
609
|
+
lastRun: habitLastRun,
|
|
610
|
+
checkpoint: displayCheckpoint(state.checkpoint),
|
|
611
|
+
alsoDue: alsoDue || undefined,
|
|
612
|
+
staleObligations,
|
|
613
|
+
parseErrors: options?.parseErrors ?? [],
|
|
614
|
+
degradedComponents,
|
|
615
|
+
now,
|
|
616
|
+
});
|
|
617
|
+
// Piggyback journal embedding indexing (best-effort, fire-and-forget)
|
|
618
|
+
const journalDir = path.join(agentRoot, "journal");
|
|
619
|
+
/* v8 ignore start -- journal indexing piggyback: embedding provider may not be available; tested via journal-index unit tests @preserve */
|
|
620
|
+
void (0, journal_index_1.indexJournalFiles)(journalDir, path.join(journalDir, ".index.json"), {
|
|
621
|
+
embed: async () => [],
|
|
622
|
+
}).catch(() => {
|
|
623
|
+
// swallowed: indexing failure must never block habit turn
|
|
624
|
+
});
|
|
625
|
+
/* v8 ignore stop */
|
|
626
|
+
}
|
|
627
|
+
}
|
|
312
628
|
else {
|
|
313
629
|
userContent = buildInstinctUserMessage(instincts, reason, state);
|
|
314
630
|
}
|
|
@@ -316,18 +632,46 @@ async function runInnerDialogTurn(options) {
|
|
|
316
632
|
const userMessage = { role: "user", content: userContent };
|
|
317
633
|
// ── Session loader: wraps existing session logic ──────────────────
|
|
318
634
|
const innerCapabilities = (0, channel_1.getChannelCapabilities)("inner");
|
|
319
|
-
const pendingDir = (0, pending_1.getInnerDialogPendingDir)(
|
|
320
|
-
const selfFriend = createSelfFriend(
|
|
635
|
+
const pendingDir = (0, pending_1.getInnerDialogPendingDir)(agentName);
|
|
636
|
+
const selfFriend = createSelfFriend(agentName);
|
|
321
637
|
const selfContext = { friend: selfFriend, channel: innerCapabilities };
|
|
638
|
+
const mcpManager = await (0, mcp_manager_1.getSharedMcpManager)() ?? undefined;
|
|
639
|
+
// ── Habit tool enforcement ───────────────────────────────────────
|
|
640
|
+
let habitToolsResolved;
|
|
641
|
+
if (habitTools !== undefined) {
|
|
642
|
+
const fullTools = (0, tools_1.getToolsForChannel)(innerCapabilities);
|
|
643
|
+
habitToolsResolved = fullTools.filter((t) => habitTools.includes(t.function.name));
|
|
644
|
+
(0, runtime_1.emitNervesEvent)({
|
|
645
|
+
event: "habit.tools_restricted",
|
|
646
|
+
component: "senses",
|
|
647
|
+
message: "habit running with restricted tools",
|
|
648
|
+
meta: {
|
|
649
|
+
habitName: options?.habitName,
|
|
650
|
+
declared: habitTools,
|
|
651
|
+
resolved: habitToolsResolved.map((t) => t.function.name),
|
|
652
|
+
},
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
else if (reason === "habit" && options?.habitName && habitParsedSuccessfully) {
|
|
656
|
+
(0, runtime_1.emitNervesEvent)({
|
|
657
|
+
event: "habit.tools_unrestricted",
|
|
658
|
+
component: "senses",
|
|
659
|
+
message: "habit running with full tool repertoire",
|
|
660
|
+
meta: { habitName: options.habitName },
|
|
661
|
+
});
|
|
662
|
+
}
|
|
322
663
|
const sessionLoader = {
|
|
323
664
|
loadOrCreate: async () => {
|
|
324
665
|
if (existingMessages.length > 0) {
|
|
325
|
-
return {
|
|
666
|
+
return {
|
|
667
|
+
messages: existingMessages,
|
|
668
|
+
sessionPath: sessionFilePath,
|
|
669
|
+
};
|
|
326
670
|
}
|
|
327
671
|
// Fresh session: build system prompt
|
|
328
672
|
const systemPrompt = await (0, prompt_1.buildSystem)("inner", { toolChoiceRequired: true });
|
|
329
673
|
return {
|
|
330
|
-
messages: [{ role: "system", content: systemPrompt }],
|
|
674
|
+
messages: [{ role: "system", content: (0, prompt_1.flattenSystemPrompt)(systemPrompt) }],
|
|
331
675
|
sessionPath: sessionFilePath,
|
|
332
676
|
};
|
|
333
677
|
},
|
|
@@ -335,6 +679,8 @@ async function runInnerDialogTurn(options) {
|
|
|
335
679
|
// ── Call shared pipeline ──────────────────────────────────────────
|
|
336
680
|
const callbacks = createInnerDialogCallbacks();
|
|
337
681
|
const traceId = (0, nerves_1.createTraceId)();
|
|
682
|
+
// Attention queue: built when pending messages are drained, shared with tool context
|
|
683
|
+
let attentionQueue = [];
|
|
338
684
|
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
339
685
|
channel: "inner",
|
|
340
686
|
sessionKey: "dialog",
|
|
@@ -349,15 +695,55 @@ async function runInnerDialogTurn(options) {
|
|
|
349
695
|
enforceTrustGate: trust_gate_1.enforceTrustGate,
|
|
350
696
|
drainPending: pending_1.drainPending,
|
|
351
697
|
runAgent: core_1.runAgent,
|
|
352
|
-
postTurn:
|
|
698
|
+
postTurn: (turnMessages, sessionPathArg, usage, hooks, state) => {
|
|
699
|
+
const prepared = (0, context_1.postTurnTrim)(turnMessages, usage, hooks);
|
|
700
|
+
(0, context_1.deferPostTurnPersist)(sessionPathArg, prepared, usage, state);
|
|
701
|
+
},
|
|
353
702
|
accumulateFriendTokens: tokens_1.accumulateFriendTokens,
|
|
354
703
|
signal: options?.signal,
|
|
704
|
+
/* v8 ignore start -- attention queue: callback invoked by pipeline during pending drain; tested via attention-queue unit tests @preserve */
|
|
705
|
+
onPendingDrained: (drained) => {
|
|
706
|
+
const outstandingObligations = (0, obligations_1.listActiveReturnObligations)(agentName);
|
|
707
|
+
attentionQueue = (0, attention_queue_1.buildAttentionQueue)({
|
|
708
|
+
drainedPending: drained,
|
|
709
|
+
outstandingObligations,
|
|
710
|
+
friendNameResolver: (friendId) => {
|
|
711
|
+
try {
|
|
712
|
+
const raw = fs.readFileSync(path.join((0, identity_1.getAgentRoot)(agentName), "friends", friendId + ".json"), "utf-8");
|
|
713
|
+
const parsed = JSON.parse(raw);
|
|
714
|
+
return typeof parsed.name === "string" ? parsed.name : null;
|
|
715
|
+
}
|
|
716
|
+
catch {
|
|
717
|
+
return null;
|
|
718
|
+
}
|
|
719
|
+
},
|
|
720
|
+
packetResolver: (packetId) => {
|
|
721
|
+
try {
|
|
722
|
+
return (0, packets_1.readPonderPacket)((0, identity_1.getAgentRoot)(agentName), packetId);
|
|
723
|
+
}
|
|
724
|
+
catch {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
});
|
|
729
|
+
const summary = (0, attention_queue_1.buildAttentionQueueSummary)(attentionQueue);
|
|
730
|
+
return summary ? [summary] : [];
|
|
731
|
+
},
|
|
732
|
+
/* v8 ignore stop */
|
|
355
733
|
runAgentOptions: {
|
|
356
734
|
traceId,
|
|
357
735
|
toolChoiceRequired: true,
|
|
358
|
-
|
|
736
|
+
mcpManager,
|
|
737
|
+
...(habitToolsResolved !== undefined && { tools: habitToolsResolved }),
|
|
738
|
+
toolContext: {
|
|
739
|
+
signin: async () => undefined,
|
|
740
|
+
delegatedOrigins: attentionQueue,
|
|
741
|
+
},
|
|
359
742
|
},
|
|
360
743
|
});
|
|
744
|
+
// Post-turn routeDelegatedCompletion removed: delivery is now inline via surface tool.
|
|
745
|
+
// settle in inner dialog produces no CompletionMetadata, so routeDelegatedCompletion
|
|
746
|
+
// would be a no-op. The routing infrastructure is reused by the surface handler.
|
|
361
747
|
const resultMessages = result.messages ?? [];
|
|
362
748
|
const assistantPreview = extractAssistantPreview(resultMessages);
|
|
363
749
|
const toolCalls = extractToolCallNames(resultMessages);
|
|
@@ -382,6 +768,7 @@ async function runInnerDialogTurn(options) {
|
|
|
382
768
|
messages: resultMessages,
|
|
383
769
|
usage: result.usage,
|
|
384
770
|
sessionPath: result.sessionPath ?? sessionFilePath,
|
|
771
|
+
completion: result.completion,
|
|
385
772
|
};
|
|
386
773
|
}
|
|
387
774
|
finally {
|
|
@@ -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
|
+
});
|