@ouro.bot/cli 0.1.0-alpha.48 → 0.1.0-alpha.481
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 +132 -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 +3069 -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 +857 -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 +234 -0
- package/dist/heart/bridges/manager.js +358 -0
- package/dist/heart/bridges/state-machine.js +135 -0
- package/dist/heart/bridges/store.js +123 -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 +110 -128
- package/dist/heart/core.js +745 -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 +6933 -0
- package/dist/heart/daemon/cli-help.js +487 -0
- package/dist/heart/daemon/cli-parse.js +1527 -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 +149 -10
- 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/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 +99 -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 +359 -0
- package/dist/heart/outlook/readers/continuity-readers.js +332 -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 +266 -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 +103 -12
- 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 +62 -38
- 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 +855 -0
- package/dist/heart/session-transcript.js +167 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +36 -27
- 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 +361 -0
- package/dist/heart/turn-coordinator.js +24 -1
- 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 +573 -0
- package/dist/mailroom/core.js +658 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +400 -0
- package/dist/mailroom/mbox-import.js +341 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +197 -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 +132 -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 +38 -1
- 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 +66 -7
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +978 -169
- 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 +84 -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-CPfhbn13.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 +43 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +37 -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 +44 -740
- 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 +896 -0
- package/dist/repertoire/tools-notes.js +376 -0
- package/dist/repertoire/tools-session.js +746 -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-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools.js +144 -113
- 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} +7 -3
- package/dist/senses/{bluebubbles.js → bluebubbles/index.js} +705 -116
- 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/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 +516 -211
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +97 -17
- package/dist/senses/inner-dialog.js +404 -14
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +232 -0
- package/dist/senses/pipeline.js +533 -72
- 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 +413 -163
- package/dist/senses/trust-gate.js +5 -5
- 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/mind/associative-recall.js +0 -209
- package/dist/senses/bluebubbles-entry.js +0 -13
- 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
package/dist/mind/context.js
CHANGED
|
@@ -33,18 +33,26 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.validateSessionMessages = exports.repairSessionMessages = exports.migrateToolNames = void 0;
|
|
36
37
|
exports.trimMessages = trimMessages;
|
|
37
|
-
exports.validateSessionMessages = validateSessionMessages;
|
|
38
|
-
exports.repairSessionMessages = repairSessionMessages;
|
|
39
38
|
exports.saveSession = saveSession;
|
|
39
|
+
exports.appendSyntheticAssistantMessage = appendSyntheticAssistantMessage;
|
|
40
40
|
exports.loadSession = loadSession;
|
|
41
41
|
exports.postTurn = postTurn;
|
|
42
|
+
exports.postTurnTrim = postTurnTrim;
|
|
43
|
+
exports.postTurnPersist = postTurnPersist;
|
|
44
|
+
exports.deferPostTurnPersist = deferPostTurnPersist;
|
|
42
45
|
exports.deleteSession = deleteSession;
|
|
43
46
|
const config_1 = require("../heart/config");
|
|
47
|
+
const session_events_1 = require("../heart/session-events");
|
|
44
48
|
const runtime_1 = require("../nerves/runtime");
|
|
45
49
|
const fs = __importStar(require("fs"));
|
|
46
50
|
const path = __importStar(require("path"));
|
|
47
51
|
const token_estimate_1 = require("./token-estimate");
|
|
52
|
+
var session_events_2 = require("../heart/session-events");
|
|
53
|
+
Object.defineProperty(exports, "migrateToolNames", { enumerable: true, get: function () { return session_events_2.migrateToolNames; } });
|
|
54
|
+
Object.defineProperty(exports, "repairSessionMessages", { enumerable: true, get: function () { return session_events_2.repairSessionMessages; } });
|
|
55
|
+
Object.defineProperty(exports, "validateSessionMessages", { enumerable: true, get: function () { return session_events_2.validateSessionMessages; } });
|
|
48
56
|
function buildTrimmableBlocks(messages) {
|
|
49
57
|
const blocks = [];
|
|
50
58
|
let i = 0;
|
|
@@ -173,114 +181,94 @@ function trimMessages(messages, maxTokens, contextMargin, actualTokenCount) {
|
|
|
173
181
|
* user → assistant (with optional tool calls/results) → user → assistant...
|
|
174
182
|
* Never assistant → assistant without a user in between.
|
|
175
183
|
*/
|
|
176
|
-
function
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (msg.role === "system")
|
|
184
|
-
continue;
|
|
185
|
-
if (msg.role === "tool") {
|
|
186
|
-
sawToolResultSincePrevAssistant = true;
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
if (msg.role === "assistant" && prevNonToolRole === "assistant") {
|
|
190
|
-
// assistant → tool(s) → assistant is valid (tool call flow)
|
|
191
|
-
if (!(prevAssistantHadToolCalls && sawToolResultSincePrevAssistant)) {
|
|
192
|
-
violations.push(`back-to-back assistant at index ${i}`);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
prevAssistantHadToolCalls = msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0;
|
|
196
|
-
sawToolResultSincePrevAssistant = false;
|
|
197
|
-
prevNonToolRole = msg.role;
|
|
198
|
-
}
|
|
199
|
-
return violations;
|
|
184
|
+
function denormalizeContinuityState(state) {
|
|
185
|
+
if (!state.mustResolveBeforeHandoff && typeof state.lastFriendActivityAt !== "string")
|
|
186
|
+
return undefined;
|
|
187
|
+
return {
|
|
188
|
+
...(state.mustResolveBeforeHandoff ? { mustResolveBeforeHandoff: true } : {}),
|
|
189
|
+
...(typeof state.lastFriendActivityAt === "string" ? { lastFriendActivityAt: state.lastFriendActivityAt } : {}),
|
|
190
|
+
};
|
|
200
191
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
function repairSessionMessages(messages) {
|
|
205
|
-
const violations = validateSessionMessages(messages);
|
|
206
|
-
if (violations.length === 0)
|
|
207
|
-
return messages;
|
|
208
|
-
const result = [];
|
|
209
|
-
for (const msg of messages) {
|
|
210
|
-
if (msg.role === "assistant" && result.length > 0) {
|
|
211
|
-
const prev = result[result.length - 1];
|
|
212
|
-
if (prev.role === "assistant" && !("tool_calls" in prev)) {
|
|
213
|
-
const prevContent = typeof prev.content === "string" ? prev.content : "";
|
|
214
|
-
const curContent = typeof msg.content === "string" ? msg.content : "";
|
|
215
|
-
prev.content = `${prevContent}\n\n${curContent}`;
|
|
216
|
-
continue;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
result.push(msg);
|
|
220
|
-
}
|
|
221
|
-
(0, runtime_1.emitNervesEvent)({
|
|
222
|
-
level: "warn",
|
|
223
|
-
event: "mind.session_invariant_repair",
|
|
224
|
-
component: "mind",
|
|
225
|
-
message: "repaired session invariant violations",
|
|
226
|
-
meta: { violations },
|
|
227
|
-
});
|
|
228
|
-
return result;
|
|
192
|
+
function writeSessionEnvelope(filePath, envelope) {
|
|
193
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
194
|
+
fs.writeFileSync(filePath, JSON.stringify(envelope, null, 2));
|
|
229
195
|
}
|
|
230
196
|
function saveSession(filePath, messages, lastUsage, state) {
|
|
231
|
-
const
|
|
232
|
-
|
|
197
|
+
const existing = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
|
|
198
|
+
const previousMessages = existing ? (0, session_events_1.projectProviderMessages)(existing) : [];
|
|
199
|
+
const currentIngressTimes = messages.map(session_events_1.getIngressTime);
|
|
200
|
+
const sanitized = (0, session_events_1.sanitizeProviderMessages)(messages);
|
|
201
|
+
const { envelope } = (0, session_events_1.buildCanonicalSessionEnvelope)({
|
|
202
|
+
existing,
|
|
203
|
+
previousMessages,
|
|
204
|
+
currentMessages: sanitized,
|
|
205
|
+
trimmedMessages: sanitized,
|
|
206
|
+
currentIngressTimes,
|
|
207
|
+
recordedAt: new Date().toISOString(),
|
|
208
|
+
lastUsage: lastUsage ?? null,
|
|
209
|
+
state,
|
|
210
|
+
projectionBasis: {
|
|
211
|
+
maxTokens: null,
|
|
212
|
+
contextMargin: null,
|
|
213
|
+
inputTokens: lastUsage?.input_tokens ?? null,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
writeSessionEnvelope(filePath, envelope);
|
|
217
|
+
}
|
|
218
|
+
function appendSyntheticAssistantMessage(filePath, content) {
|
|
219
|
+
try {
|
|
220
|
+
if (!fs.existsSync(filePath))
|
|
221
|
+
return false;
|
|
222
|
+
const envelope = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
|
|
223
|
+
if (!envelope)
|
|
224
|
+
return false;
|
|
225
|
+
const updated = (0, session_events_1.appendSyntheticAssistantEvent)(envelope, content, new Date().toISOString());
|
|
226
|
+
writeSessionEnvelope(filePath, updated);
|
|
233
227
|
(0, runtime_1.emitNervesEvent)({
|
|
234
|
-
level: "warn",
|
|
235
|
-
event: "mind.session_invariant_violation",
|
|
236
228
|
component: "mind",
|
|
237
|
-
|
|
238
|
-
|
|
229
|
+
event: "mind.session_synthetic_message_appended",
|
|
230
|
+
message: "appended synthetic assistant message to session",
|
|
231
|
+
meta: { path: filePath, contentLength: content.length },
|
|
239
232
|
});
|
|
240
|
-
|
|
233
|
+
return true;
|
|
241
234
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (lastUsage)
|
|
245
|
-
envelope.lastUsage = lastUsage;
|
|
246
|
-
if (state?.mustResolveBeforeHandoff === true) {
|
|
247
|
-
envelope.state = { mustResolveBeforeHandoff: true };
|
|
235
|
+
catch {
|
|
236
|
+
return false;
|
|
248
237
|
}
|
|
249
|
-
fs.writeFileSync(filePath, JSON.stringify(envelope, null, 2));
|
|
250
238
|
}
|
|
251
239
|
function loadSession(filePath) {
|
|
252
240
|
try {
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
if (data.version !== 1)
|
|
241
|
+
const envelope = (0, session_events_1.loadSessionEnvelopeFile)(filePath);
|
|
242
|
+
if (!envelope)
|
|
256
243
|
return null;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
component: "mind",
|
|
264
|
-
message: "session invariant violated on load",
|
|
265
|
-
meta: { path: filePath, violations },
|
|
266
|
-
});
|
|
267
|
-
messages = repairSessionMessages(messages);
|
|
268
|
-
}
|
|
269
|
-
const state = data?.state && typeof data.state === "object" && data.state !== null
|
|
270
|
-
&& typeof data.state.mustResolveBeforeHandoff === "boolean"
|
|
271
|
-
&& data.state.mustResolveBeforeHandoff === true
|
|
272
|
-
? { mustResolveBeforeHandoff: true }
|
|
273
|
-
: undefined;
|
|
274
|
-
return { messages, lastUsage: data.lastUsage, state };
|
|
244
|
+
return {
|
|
245
|
+
messages: (0, session_events_1.annotateMessageTimestamps)(envelope, (0, session_events_1.projectProviderMessages)(envelope)),
|
|
246
|
+
events: envelope.events,
|
|
247
|
+
lastUsage: envelope.lastUsage ?? undefined,
|
|
248
|
+
state: denormalizeContinuityState(envelope.state),
|
|
249
|
+
};
|
|
275
250
|
}
|
|
276
251
|
catch {
|
|
277
252
|
return null;
|
|
278
253
|
}
|
|
279
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Synchronous post-turn: sanitize, trim (mutates messages in place), and persist to disk.
|
|
257
|
+
* For non-blocking persist, use postTurnTrim() + deferPostTurnPersist() instead.
|
|
258
|
+
*/
|
|
280
259
|
function postTurn(messages, sessPath, usage, hooks, state) {
|
|
260
|
+
const prepared = postTurnTrim(messages, usage, hooks);
|
|
261
|
+
postTurnPersist(sessPath, prepared, usage, state);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Synchronous phase: run hooks, sanitize, trim, and mutate the messages array in place.
|
|
265
|
+
* Returns the data needed by postTurnPersist / deferPostTurnPersist.
|
|
266
|
+
*/
|
|
267
|
+
function postTurnTrim(messages, usage, hooks) {
|
|
268
|
+
const preTrimMessages = [...messages];
|
|
281
269
|
if (hooks?.beforeTrim) {
|
|
282
270
|
try {
|
|
283
|
-
hooks.beforeTrim(
|
|
271
|
+
hooks.beforeTrim(preTrimMessages);
|
|
284
272
|
}
|
|
285
273
|
catch (error) {
|
|
286
274
|
(0, runtime_1.emitNervesEvent)({
|
|
@@ -295,9 +283,60 @@ function postTurn(messages, sessPath, usage, hooks, state) {
|
|
|
295
283
|
}
|
|
296
284
|
}
|
|
297
285
|
const { maxTokens, contextMargin } = (0, config_1.getContextConfig)();
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
286
|
+
const currentIngressTimes = messages.map(session_events_1.getIngressTime);
|
|
287
|
+
const currentMessages = (0, session_events_1.sanitizeProviderMessages)(messages);
|
|
288
|
+
const trimmedMessages = trimMessages(currentMessages, maxTokens, contextMargin, usage?.input_tokens);
|
|
289
|
+
messages.splice(0, messages.length, ...trimmedMessages);
|
|
290
|
+
return { currentMessages, trimmedMessages, currentIngressTimes, maxTokens, contextMargin };
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Synchronous persist: load existing envelope, build canonical envelope, write to disk.
|
|
294
|
+
*/
|
|
295
|
+
function postTurnPersist(sessPath, prepared, usage, state) {
|
|
296
|
+
const existing = (0, session_events_1.loadSessionEnvelopeFile)(sessPath);
|
|
297
|
+
const previousMessages = existing ? (0, session_events_1.projectProviderMessages)(existing) : [];
|
|
298
|
+
const { envelope, evictedEvents } = (0, session_events_1.buildCanonicalSessionEnvelope)({
|
|
299
|
+
existing,
|
|
300
|
+
previousMessages,
|
|
301
|
+
currentMessages: prepared.currentMessages,
|
|
302
|
+
trimmedMessages: prepared.trimmedMessages,
|
|
303
|
+
currentIngressTimes: prepared.currentIngressTimes,
|
|
304
|
+
recordedAt: new Date().toISOString(),
|
|
305
|
+
lastUsage: usage ?? null,
|
|
306
|
+
state,
|
|
307
|
+
projectionBasis: {
|
|
308
|
+
maxTokens: prepared.maxTokens,
|
|
309
|
+
contextMargin: prepared.contextMargin,
|
|
310
|
+
inputTokens: usage?.input_tokens ?? null,
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
(0, session_events_1.appendEvictedToArchive)(sessPath, evictedEvents);
|
|
314
|
+
writeSessionEnvelope(sessPath, envelope);
|
|
315
|
+
return envelope.events;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Deferred persist: same as postTurnPersist but runs on the next event loop tick.
|
|
319
|
+
* Returns a promise that resolves when the persist completes.
|
|
320
|
+
*/
|
|
321
|
+
function deferPostTurnPersist(sessPath, prepared, usage, state) {
|
|
322
|
+
return new Promise((resolve) => {
|
|
323
|
+
setImmediate(() => {
|
|
324
|
+
try {
|
|
325
|
+
const events = postTurnPersist(sessPath, prepared, usage, state);
|
|
326
|
+
resolve(events);
|
|
327
|
+
}
|
|
328
|
+
catch (err) {
|
|
329
|
+
(0, runtime_1.emitNervesEvent)({
|
|
330
|
+
level: "warn",
|
|
331
|
+
component: "mind",
|
|
332
|
+
event: "mind.deferred_persist_error",
|
|
333
|
+
message: "deferred session persist failed",
|
|
334
|
+
meta: { error: err instanceof Error ? err.message : String(err) },
|
|
335
|
+
});
|
|
336
|
+
resolve([]);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
});
|
|
301
340
|
}
|
|
302
341
|
function deleteSession(filePath) {
|
|
303
342
|
try {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectSuspiciousContent = detectSuspiciousContent;
|
|
4
|
+
const PATTERN_CATEGORIES = [
|
|
5
|
+
{
|
|
6
|
+
name: "instruction_framing",
|
|
7
|
+
patterns: [
|
|
8
|
+
/\byou are (?:a|an) (?:ai|assistant|language model|helpful assistant)\b/i,
|
|
9
|
+
/\byour (?:new )?instructions are\b/i,
|
|
10
|
+
/\bsystem\s*:/i,
|
|
11
|
+
/\bignore (?:all |my )?previous instructions\b/i,
|
|
12
|
+
/\bdo not reveal\b/i,
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "override_language",
|
|
17
|
+
patterns: [
|
|
18
|
+
/\bdisregard\b/i,
|
|
19
|
+
/\bforget everything\b/i,
|
|
20
|
+
/\bnew instructions:/i,
|
|
21
|
+
/\boverride (?:all |any |previous )?instructions\b/i,
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "role_injection",
|
|
26
|
+
patterns: [
|
|
27
|
+
/\bas (?:a|an) (?:ai|language model)\b/i,
|
|
28
|
+
/\byou must always\b/i,
|
|
29
|
+
/\byou are now\b/i,
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "boundary_markers",
|
|
34
|
+
patterns: [
|
|
35
|
+
/```system/i,
|
|
36
|
+
/<<SYS>>/i,
|
|
37
|
+
/\[INST\]/i,
|
|
38
|
+
/<\/?system>/i,
|
|
39
|
+
/\[system\]/i,
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
function detectSuspiciousContent(text) {
|
|
44
|
+
if (!text) {
|
|
45
|
+
return { suspicious: false, patterns: [] };
|
|
46
|
+
}
|
|
47
|
+
const matched = new Set();
|
|
48
|
+
for (const category of PATTERN_CATEGORIES) {
|
|
49
|
+
for (const pattern of category.patterns) {
|
|
50
|
+
if (pattern.test(text)) {
|
|
51
|
+
matched.add(category.name);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
suspicious: matched.size > 0,
|
|
58
|
+
patterns: [...matched],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -33,52 +33,25 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
37
|
-
exports.
|
|
38
|
-
exports.
|
|
39
|
-
exports.
|
|
40
|
-
exports.
|
|
36
|
+
exports.ensureDiaryStorePaths = ensureDiaryStorePaths;
|
|
37
|
+
exports.appendEntriesWithDedup = appendEntriesWithDedup;
|
|
38
|
+
exports.resolveDiaryRoot = resolveDiaryRoot;
|
|
39
|
+
exports.readDiaryEntries = readDiaryEntries;
|
|
40
|
+
exports.saveDiaryEntry = saveDiaryEntry;
|
|
41
41
|
exports.backfillEmbeddings = backfillEmbeddings;
|
|
42
|
-
exports.
|
|
42
|
+
exports.searchDiaryEntries = searchDiaryEntries;
|
|
43
43
|
const fs = __importStar(require("fs"));
|
|
44
44
|
const path = __importStar(require("path"));
|
|
45
45
|
const crypto_1 = require("crypto");
|
|
46
|
-
const config_1 = require("../heart/config");
|
|
47
46
|
const identity_1 = require("../heart/identity");
|
|
48
47
|
const runtime_1 = require("../nerves/runtime");
|
|
48
|
+
const note_search_1 = require("./note-search");
|
|
49
|
+
const diary_integrity_1 = require("./diary-integrity");
|
|
50
|
+
const embedding_provider_1 = require("./embedding-provider");
|
|
49
51
|
const DEDUP_THRESHOLD = 0.6;
|
|
52
|
+
const SEMANTIC_DEDUP_THRESHOLD = 0.95;
|
|
50
53
|
const ENTITY_TOKEN = /[a-z0-9]+/g;
|
|
51
|
-
|
|
52
|
-
class OpenAIEmbeddingProvider {
|
|
53
|
-
apiKey;
|
|
54
|
-
model;
|
|
55
|
-
constructor(apiKey, model = DEFAULT_EMBEDDING_MODEL) {
|
|
56
|
-
this.apiKey = apiKey;
|
|
57
|
-
this.model = model;
|
|
58
|
-
}
|
|
59
|
-
async embed(texts) {
|
|
60
|
-
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
61
|
-
method: "POST",
|
|
62
|
-
headers: {
|
|
63
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
64
|
-
"Content-Type": "application/json",
|
|
65
|
-
},
|
|
66
|
-
body: JSON.stringify({
|
|
67
|
-
model: this.model,
|
|
68
|
-
input: texts,
|
|
69
|
-
}),
|
|
70
|
-
});
|
|
71
|
-
if (!response.ok) {
|
|
72
|
-
throw new Error(`embedding request failed: ${response.status} ${response.statusText}`);
|
|
73
|
-
}
|
|
74
|
-
const payload = (await response.json());
|
|
75
|
-
if (!payload.data || payload.data.length !== texts.length) {
|
|
76
|
-
throw new Error("embedding response missing expected vectors");
|
|
77
|
-
}
|
|
78
|
-
return payload.data.map((entry) => entry.embedding);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
function ensureMemoryStorePaths(rootDir) {
|
|
54
|
+
function ensureDiaryStorePaths(rootDir) {
|
|
82
55
|
const factsPath = path.join(rootDir, "facts.jsonl");
|
|
83
56
|
const entitiesPath = path.join(rootDir, "entities.json");
|
|
84
57
|
const dailyDir = path.join(rootDir, "daily");
|
|
@@ -90,8 +63,8 @@ function ensureMemoryStorePaths(rootDir) {
|
|
|
90
63
|
fs.writeFileSync(entitiesPath, "{}\n", "utf8");
|
|
91
64
|
(0, runtime_1.emitNervesEvent)({
|
|
92
65
|
component: "mind",
|
|
93
|
-
event: "mind.
|
|
94
|
-
message: "
|
|
66
|
+
event: "mind.diary_paths_ready",
|
|
67
|
+
message: "diary store paths ready",
|
|
95
68
|
meta: { rootDir },
|
|
96
69
|
});
|
|
97
70
|
return { rootDir, factsPath, entitiesPath, dailyDir };
|
|
@@ -114,7 +87,7 @@ function overlapScore(left, right) {
|
|
|
114
87
|
}
|
|
115
88
|
return common / Math.min(leftWords.size, rightWords.size);
|
|
116
89
|
}
|
|
117
|
-
function
|
|
90
|
+
function readExistingEntries(factsPath) {
|
|
118
91
|
if (!fs.existsSync(factsPath))
|
|
119
92
|
return [];
|
|
120
93
|
const raw = fs.readFileSync(factsPath, "utf8").trim();
|
|
@@ -177,13 +150,24 @@ function appendDailyFact(dailyDir, fact) {
|
|
|
177
150
|
const dayPath = path.join(dailyDir, `${day}.jsonl`);
|
|
178
151
|
fs.appendFileSync(dayPath, `${JSON.stringify(fact)}\n`, "utf8");
|
|
179
152
|
}
|
|
180
|
-
function
|
|
181
|
-
const existing =
|
|
153
|
+
function appendEntriesWithDedup(stores, incoming, options) {
|
|
154
|
+
const existing = readExistingEntries(stores.factsPath);
|
|
182
155
|
const all = [...existing];
|
|
183
156
|
let added = 0;
|
|
184
157
|
let skipped = 0;
|
|
158
|
+
const semanticThreshold = options?.semanticThreshold;
|
|
185
159
|
for (const fact of incoming) {
|
|
186
|
-
const duplicate = all.some((prior) =>
|
|
160
|
+
const duplicate = all.some((prior) => {
|
|
161
|
+
if (overlapScore(prior.text, fact.text) > DEDUP_THRESHOLD)
|
|
162
|
+
return true;
|
|
163
|
+
if (semanticThreshold !== undefined &&
|
|
164
|
+
Array.isArray(fact.embedding) && fact.embedding.length > 0 &&
|
|
165
|
+
Array.isArray(prior.embedding) && prior.embedding.length > 0 &&
|
|
166
|
+
fact.embedding.length === prior.embedding.length) {
|
|
167
|
+
return (0, note_search_1.cosineSimilarity)(fact.embedding, prior.embedding) > semanticThreshold;
|
|
168
|
+
}
|
|
169
|
+
return false;
|
|
170
|
+
});
|
|
187
171
|
if (duplicate) {
|
|
188
172
|
skipped++;
|
|
189
173
|
continue;
|
|
@@ -196,44 +180,20 @@ function appendFactsWithDedup(stores, incoming) {
|
|
|
196
180
|
}
|
|
197
181
|
(0, runtime_1.emitNervesEvent)({
|
|
198
182
|
component: "mind",
|
|
199
|
-
event: "mind.
|
|
200
|
-
message: "
|
|
183
|
+
event: "mind.diary_write",
|
|
184
|
+
message: "diary write completed",
|
|
201
185
|
meta: { added, skipped },
|
|
202
186
|
});
|
|
203
187
|
return { added, skipped };
|
|
204
188
|
}
|
|
205
|
-
function cosineSimilarity(left, right) {
|
|
206
|
-
if (left.length === 0 || right.length === 0 || left.length !== right.length)
|
|
207
|
-
return 0;
|
|
208
|
-
let dot = 0;
|
|
209
|
-
let leftNorm = 0;
|
|
210
|
-
let rightNorm = 0;
|
|
211
|
-
for (let i = 0; i < left.length; i += 1) {
|
|
212
|
-
dot += left[i] * right[i];
|
|
213
|
-
leftNorm += left[i] * left[i];
|
|
214
|
-
rightNorm += right[i] * right[i];
|
|
215
|
-
}
|
|
216
|
-
if (leftNorm === 0 || rightNorm === 0)
|
|
217
|
-
return 0;
|
|
218
|
-
return dot / (Math.sqrt(leftNorm) * Math.sqrt(rightNorm));
|
|
219
|
-
}
|
|
220
|
-
exports.__memoryTestUtils = {
|
|
221
|
-
cosineSimilarity,
|
|
222
|
-
};
|
|
223
|
-
function createDefaultEmbeddingProvider() {
|
|
224
|
-
const apiKey = (0, config_1.getOpenAIEmbeddingsApiKey)().trim();
|
|
225
|
-
if (!apiKey)
|
|
226
|
-
return null;
|
|
227
|
-
return new OpenAIEmbeddingProvider(apiKey);
|
|
228
|
-
}
|
|
229
189
|
async function buildEmbedding(text, embeddingProvider) {
|
|
230
|
-
const provider = embeddingProvider ?? createDefaultEmbeddingProvider();
|
|
190
|
+
const provider = embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
|
|
231
191
|
if (!provider) {
|
|
232
192
|
(0, runtime_1.emitNervesEvent)({
|
|
233
193
|
level: "warn",
|
|
234
194
|
component: "mind",
|
|
235
|
-
event: "mind.
|
|
236
|
-
message: "embedding provider unavailable for
|
|
195
|
+
event: "mind.diary_embedding_unavailable",
|
|
196
|
+
message: "embedding provider unavailable for diary write",
|
|
237
197
|
meta: { reason: "missing_openai_embeddings_key" },
|
|
238
198
|
});
|
|
239
199
|
return [];
|
|
@@ -246,8 +206,8 @@ async function buildEmbedding(text, embeddingProvider) {
|
|
|
246
206
|
(0, runtime_1.emitNervesEvent)({
|
|
247
207
|
level: "warn",
|
|
248
208
|
component: "mind",
|
|
249
|
-
event: "mind.
|
|
250
|
-
message: "embedding provider unavailable for
|
|
209
|
+
event: "mind.diary_embedding_unavailable",
|
|
210
|
+
message: "embedding provider unavailable for diary write",
|
|
251
211
|
meta: {
|
|
252
212
|
reason: error instanceof Error ? error.message : String(error),
|
|
253
213
|
},
|
|
@@ -255,13 +215,19 @@ async function buildEmbedding(text, embeddingProvider) {
|
|
|
255
215
|
return [];
|
|
256
216
|
}
|
|
257
217
|
}
|
|
258
|
-
function
|
|
259
|
-
|
|
218
|
+
function resolveDiaryRoot(explicitRoot) {
|
|
219
|
+
if (explicitRoot)
|
|
220
|
+
return explicitRoot;
|
|
221
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
222
|
+
return path.join(agentRoot, "diary");
|
|
260
223
|
}
|
|
261
|
-
|
|
224
|
+
function readDiaryEntries(diaryRoot) {
|
|
225
|
+
return readExistingEntries(path.join(resolveDiaryRoot(diaryRoot), "facts.jsonl"));
|
|
226
|
+
}
|
|
227
|
+
async function saveDiaryEntry(options) {
|
|
262
228
|
const text = options.text.trim();
|
|
263
|
-
const
|
|
264
|
-
const stores =
|
|
229
|
+
const diaryRoot = resolveDiaryRoot(options.diaryRoot);
|
|
230
|
+
const stores = ensureDiaryStorePaths(diaryRoot);
|
|
265
231
|
const embedding = await buildEmbedding(text, options.embeddingProvider);
|
|
266
232
|
const fact = {
|
|
267
233
|
id: options.idFactory ? options.idFactory() : (0, crypto_1.randomUUID)(),
|
|
@@ -270,24 +236,39 @@ async function saveMemoryFact(options) {
|
|
|
270
236
|
about: options.about?.trim() || undefined,
|
|
271
237
|
createdAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
272
238
|
embedding,
|
|
239
|
+
...(options.provenance ? { provenance: options.provenance } : {}),
|
|
273
240
|
};
|
|
274
|
-
|
|
241
|
+
const integrity = (0, diary_integrity_1.detectSuspiciousContent)(text);
|
|
242
|
+
if (integrity.suspicious) {
|
|
243
|
+
(0, runtime_1.emitNervesEvent)({
|
|
244
|
+
level: "warn",
|
|
245
|
+
component: "mind",
|
|
246
|
+
event: "mind.diary_integrity_warning",
|
|
247
|
+
message: "suspicious content detected in diary entry",
|
|
248
|
+
meta: {
|
|
249
|
+
patterns: integrity.patterns,
|
|
250
|
+
textPreview: text.slice(0, 200),
|
|
251
|
+
entryId: fact.id,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return appendEntriesWithDedup(stores, [fact], { semanticThreshold: SEMANTIC_DEDUP_THRESHOLD });
|
|
275
256
|
}
|
|
276
257
|
async function backfillEmbeddings(options) {
|
|
277
|
-
const
|
|
278
|
-
const factsPath = path.join(
|
|
258
|
+
const diaryRoot = resolveDiaryRoot(options?.diaryRoot);
|
|
259
|
+
const factsPath = path.join(diaryRoot, "facts.jsonl");
|
|
279
260
|
if (!fs.existsSync(factsPath))
|
|
280
261
|
return { total: 0, backfilled: 0, failed: 0 };
|
|
281
|
-
const facts =
|
|
262
|
+
const facts = readExistingEntries(factsPath);
|
|
282
263
|
const needsEmbedding = facts.filter((f) => !Array.isArray(f.embedding) || f.embedding.length === 0);
|
|
283
264
|
if (needsEmbedding.length === 0)
|
|
284
265
|
return { total: facts.length, backfilled: 0, failed: 0 };
|
|
285
|
-
const provider = options?.embeddingProvider ?? createDefaultEmbeddingProvider();
|
|
266
|
+
const provider = options?.embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
|
|
286
267
|
if (!provider) {
|
|
287
268
|
(0, runtime_1.emitNervesEvent)({
|
|
288
269
|
level: "warn",
|
|
289
270
|
component: "mind",
|
|
290
|
-
event: "mind.
|
|
271
|
+
event: "mind.diary_backfill_skipped",
|
|
291
272
|
message: "embedding provider unavailable for backfill",
|
|
292
273
|
meta: { needsEmbedding: needsEmbedding.length },
|
|
293
274
|
});
|
|
@@ -313,7 +294,7 @@ async function backfillEmbeddings(options) {
|
|
|
313
294
|
(0, runtime_1.emitNervesEvent)({
|
|
314
295
|
level: "warn",
|
|
315
296
|
component: "mind",
|
|
316
|
-
event: "mind.
|
|
297
|
+
event: "mind.diary_backfill_batch_error",
|
|
317
298
|
message: "embedding backfill batch failed",
|
|
318
299
|
meta: {
|
|
319
300
|
batchStart: i,
|
|
@@ -328,7 +309,7 @@ async function backfillEmbeddings(options) {
|
|
|
328
309
|
fs.writeFileSync(factsPath, lines, "utf8");
|
|
329
310
|
(0, runtime_1.emitNervesEvent)({
|
|
330
311
|
component: "mind",
|
|
331
|
-
event: "mind.
|
|
312
|
+
event: "mind.diary_backfill_complete",
|
|
332
313
|
message: "embedding backfill completed",
|
|
333
314
|
meta: { total: facts.length, backfilled, failed },
|
|
334
315
|
});
|
|
@@ -348,7 +329,7 @@ function uniqueFacts(facts) {
|
|
|
348
329
|
}
|
|
349
330
|
return unique;
|
|
350
331
|
}
|
|
351
|
-
async function
|
|
332
|
+
async function searchDiaryEntries(query, facts, embeddingProvider) {
|
|
352
333
|
const trimmed = query.trim();
|
|
353
334
|
if (!trimmed)
|
|
354
335
|
return [];
|
|
@@ -358,7 +339,7 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
|
|
|
358
339
|
if (embeddedFacts.length === 0) {
|
|
359
340
|
return substringFallback();
|
|
360
341
|
}
|
|
361
|
-
const provider = embeddingProvider ?? createDefaultEmbeddingProvider();
|
|
342
|
+
const provider = embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
|
|
362
343
|
if (!provider) {
|
|
363
344
|
return substringFallback();
|
|
364
345
|
}
|
|
@@ -372,7 +353,7 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
|
|
|
372
353
|
.filter((fact) => fact.embedding.length === queryEmbedding.length)
|
|
373
354
|
.map((fact) => ({
|
|
374
355
|
fact,
|
|
375
|
-
score: cosineSimilarity(queryEmbedding, fact.embedding),
|
|
356
|
+
score: (0, note_search_1.cosineSimilarity)(queryEmbedding, fact.embedding),
|
|
376
357
|
}))
|
|
377
358
|
.filter((entry) => entry.score > 0)
|
|
378
359
|
.sort((left, right) => right.score - left.score)
|
|
@@ -384,8 +365,8 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
|
|
|
384
365
|
(0, runtime_1.emitNervesEvent)({
|
|
385
366
|
level: "warn",
|
|
386
367
|
component: "mind",
|
|
387
|
-
event: "mind.
|
|
388
|
-
message: "embedding provider unavailable for
|
|
368
|
+
event: "mind.diary_embedding_unavailable",
|
|
369
|
+
message: "embedding provider unavailable for diary search",
|
|
389
370
|
meta: {
|
|
390
371
|
reason: error instanceof Error ? error.message : String(error),
|
|
391
372
|
},
|