@hasna/mementos 0.14.84 → 0.14.86
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/bun.lock +63 -4
- package/dist/cli/index.js +769 -261
- package/dist/diagnostics/historical-project-registration-receipt.js +1675 -0
- package/dist/index.js +343 -85
- package/dist/mcp/index.js +419 -99
- package/dist/pg-sync-worker.js +7 -5
- package/dist/project-registration.js +309 -68
- package/dist/sdk/index.js +123 -30
- package/dist/server/index.js +677 -317
- package/dist/storage.js +63 -26
- package/hasna.contract.json +5 -4
- package/package.json +6 -4
- package/dist/cli/__fixtures__/clean-fallback-stub-server.d.ts +0 -2
- package/dist/cli/__fixtures__/clean-fallback-stub-server.d.ts.map +0 -1
- package/dist/cli/brains.d.ts +0 -3
- package/dist/cli/brains.d.ts.map +0 -1
- package/dist/cli/commands/agent.d.ts +0 -3
- package/dist/cli/commands/agent.d.ts.map +0 -1
- package/dist/cli/commands/consolidation.d.ts +0 -3
- package/dist/cli/commands/consolidation.d.ts.map +0 -1
- package/dist/cli/commands/entity.d.ts +0 -3
- package/dist/cli/commands/entity.d.ts.map +0 -1
- package/dist/cli/commands/graph.d.ts +0 -3
- package/dist/cli/commands/graph.d.ts.map +0 -1
- package/dist/cli/commands/info-context.d.ts +0 -3
- package/dist/cli/commands/info-context.d.ts.map +0 -1
- package/dist/cli/commands/info-history.d.ts +0 -3
- package/dist/cli/commands/info-history.d.ts.map +0 -1
- package/dist/cli/commands/info-report.d.ts +0 -3
- package/dist/cli/commands/info-report.d.ts.map +0 -1
- package/dist/cli/commands/info-stale.d.ts +0 -3
- package/dist/cli/commands/info-stale.d.ts.map +0 -1
- package/dist/cli/commands/info-stats.d.ts +0 -3
- package/dist/cli/commands/info-stats.d.ts.map +0 -1
- package/dist/cli/commands/info.d.ts +0 -12
- package/dist/cli/commands/info.d.ts.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -3
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/io-backup.d.ts +0 -3
- package/dist/cli/commands/io-backup.d.ts.map +0 -1
- package/dist/cli/commands/io-clean.d.ts +0 -3
- package/dist/cli/commands/io-clean.d.ts.map +0 -1
- package/dist/cli/commands/io-export.d.ts +0 -3
- package/dist/cli/commands/io-export.d.ts.map +0 -1
- package/dist/cli/commands/io-import.d.ts +0 -3
- package/dist/cli/commands/io-import.d.ts.map +0 -1
- package/dist/cli/commands/io-restore.d.ts +0 -3
- package/dist/cli/commands/io-restore.d.ts.map +0 -1
- package/dist/cli/commands/io.d.ts +0 -12
- package/dist/cli/commands/io.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-bulk.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-bulk.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-chain.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-chain.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-crud.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-crud.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-diff.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-diff.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-list.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-list.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-recall-exit.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-recall-exit.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-recall.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-recall.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-remove.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-remove.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-search.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-search.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-tail.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-tail.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-util.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-util.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-view.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-view.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-watch.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-watch.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-when-to-use.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-when-to-use.d.ts.map +0 -1
- package/dist/cli/commands/memory.d.ts +0 -3
- package/dist/cli/commands/memory.d.ts.map +0 -1
- package/dist/cli/commands/project-panel.d.ts +0 -3
- package/dist/cli/commands/project-panel.d.ts.map +0 -1
- package/dist/cli/commands/project.d.ts +0 -3
- package/dist/cli/commands/project.d.ts.map +0 -1
- package/dist/cli/commands/relation.d.ts +0 -3
- package/dist/cli/commands/relation.d.ts.map +0 -1
- package/dist/cli/commands/storage.d.ts +0 -3
- package/dist/cli/commands/storage.d.ts.map +0 -1
- package/dist/cli/commands/system-auto-memory.d.ts +0 -3
- package/dist/cli/commands/system-auto-memory.d.ts.map +0 -1
- package/dist/cli/commands/system-completions.d.ts +0 -13
- package/dist/cli/commands/system-completions.d.ts.map +0 -1
- package/dist/cli/commands/system-config.d.ts +0 -3
- package/dist/cli/commands/system-config.d.ts.map +0 -1
- package/dist/cli/commands/system-doctor.d.ts +0 -3
- package/dist/cli/commands/system-doctor.d.ts.map +0 -1
- package/dist/cli/commands/system-hooks.d.ts +0 -3
- package/dist/cli/commands/system-hooks.d.ts.map +0 -1
- package/dist/cli/commands/system-mcp.d.ts +0 -3
- package/dist/cli/commands/system-mcp.d.ts.map +0 -1
- package/dist/cli/commands/system-misc.d.ts +0 -3
- package/dist/cli/commands/system-misc.d.ts.map +0 -1
- package/dist/cli/commands/system-profile.d.ts +0 -3
- package/dist/cli/commands/system-profile.d.ts.map +0 -1
- package/dist/cli/commands/system-session.d.ts +0 -3
- package/dist/cli/commands/system-session.d.ts.map +0 -1
- package/dist/cli/commands/system-sessions.d.ts +0 -3
- package/dist/cli/commands/system-sessions.d.ts.map +0 -1
- package/dist/cli/commands/system-synthesis.d.ts +0 -3
- package/dist/cli/commands/system-synthesis.d.ts.map +0 -1
- package/dist/cli/commands/system-synthesized-profile.d.ts +0 -3
- package/dist/cli/commands/system-synthesized-profile.d.ts.map +0 -1
- package/dist/cli/commands/system-tools.d.ts +0 -3
- package/dist/cli/commands/system-tools.d.ts.map +0 -1
- package/dist/cli/commands/system-watch.d.ts +0 -3
- package/dist/cli/commands/system-watch.d.ts.map +0 -1
- package/dist/cli/commands/system.d.ts +0 -3
- package/dist/cli/commands/system.d.ts.map +0 -1
- package/dist/cli/exit-codes.d.ts +0 -13
- package/dist/cli/exit-codes.d.ts.map +0 -1
- package/dist/cli/global-options.d.ts +0 -27
- package/dist/cli/global-options.d.ts.map +0 -1
- package/dist/cli/helpers.d.ts +0 -119
- package/dist/cli/helpers.d.ts.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/register-all.d.ts +0 -17
- package/dist/cli/register-all.d.ts.map +0 -1
- package/dist/cli/startup-side-effects.d.ts +0 -9
- package/dist/cli/startup-side-effects.d.ts.map +0 -1
- package/dist/db/__fixtures__/fail-closed-stub-server.d.ts +0 -2
- package/dist/db/__fixtures__/fail-closed-stub-server.d.ts.map +0 -1
- package/dist/db/acl.d.ts +0 -34
- package/dist/db/acl.d.ts.map +0 -1
- package/dist/db/agents.d.ts +0 -21
- package/dist/db/agents.d.ts.map +0 -1
- package/dist/db/analytics.d.ts +0 -107
- package/dist/db/analytics.d.ts.map +0 -1
- package/dist/db/api-mode.d.ts +0 -127
- package/dist/db/api-mode.d.ts.map +0 -1
- package/dist/db/audit.d.ts +0 -53
- package/dist/db/audit.d.ts.map +0 -1
- package/dist/db/database.d.ts +0 -26
- package/dist/db/database.d.ts.map +0 -1
- package/dist/db/entities.d.ts +0 -62
- package/dist/db/entities.d.ts.map +0 -1
- package/dist/db/entity-memories.d.ts +0 -34
- package/dist/db/entity-memories.d.ts.map +0 -1
- package/dist/db/feedback.d.ts +0 -9
- package/dist/db/feedback.d.ts.map +0 -1
- package/dist/db/locks.d.ts +0 -63
- package/dist/db/locks.d.ts.map +0 -1
- package/dist/db/machines.d.ts +0 -23
- package/dist/db/machines.d.ts.map +0 -1
- package/dist/db/memories.d.ts +0 -137
- package/dist/db/memories.d.ts.map +0 -1
- package/dist/db/memory-links.d.ts +0 -21
- package/dist/db/memory-links.d.ts.map +0 -1
- package/dist/db/memory-project-link.d.ts +0 -13
- package/dist/db/memory-project-link.d.ts.map +0 -1
- package/dist/db/migrations.d.ts +0 -3
- package/dist/db/migrations.d.ts.map +0 -1
- package/dist/db/pg-migrate.d.ts +0 -27
- package/dist/db/pg-migrate.d.ts.map +0 -1
- package/dist/db/pg-migrations.d.ts +0 -2
- package/dist/db/pg-migrations.d.ts.map +0 -1
- package/dist/db/projects.d.ts +0 -27
- package/dist/db/projects.d.ts.map +0 -1
- package/dist/db/ratings.d.ts +0 -23
- package/dist/db/ratings.d.ts.map +0 -1
- package/dist/db/relations.d.ts +0 -49
- package/dist/db/relations.d.ts.map +0 -1
- package/dist/db/session-jobs.d.ts +0 -49
- package/dist/db/session-jobs.d.ts.map +0 -1
- package/dist/db/store-backend.d.ts +0 -42
- package/dist/db/store-backend.d.ts.map +0 -1
- package/dist/db/subscriptions.d.ts +0 -24
- package/dist/db/subscriptions.d.ts.map +0 -1
- package/dist/db/synthesis.d.ts +0 -101
- package/dist/db/synthesis.d.ts.map +0 -1
- package/dist/db/tasks.d.ts +0 -89
- package/dist/db/tasks.d.ts.map +0 -1
- package/dist/db/tool-events.d.ts +0 -27
- package/dist/db/tool-events.d.ts.map +0 -1
- package/dist/db/webhook_hooks.d.ts +0 -25
- package/dist/db/webhook_hooks.d.ts.map +0 -1
- package/dist/generated/storage-kit/backend.d.ts +0 -20
- package/dist/generated/storage-kit/backend.d.ts.map +0 -1
- package/dist/generated/storage-kit/health.d.ts +0 -20
- package/dist/generated/storage-kit/health.d.ts.map +0 -1
- package/dist/generated/storage-kit/index.d.ts +0 -8
- package/dist/generated/storage-kit/index.d.ts.map +0 -1
- package/dist/generated/storage-kit/migrations.d.ts +0 -48
- package/dist/generated/storage-kit/migrations.d.ts.map +0 -1
- package/dist/generated/storage-kit/own.d.ts +0 -11
- package/dist/generated/storage-kit/own.d.ts.map +0 -1
- package/dist/generated/storage-kit/pool.d.ts +0 -35
- package/dist/generated/storage-kit/pool.d.ts.map +0 -1
- package/dist/generated/storage-kit/query.d.ts +0 -36
- package/dist/generated/storage-kit/query.d.ts.map +0 -1
- package/dist/generated/storage-kit/tls.d.ts +0 -53
- package/dist/generated/storage-kit/tls.d.ts.map +0 -1
- package/dist/index.d.ts +0 -45
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/activation-matcher.d.ts +0 -17
- package/dist/lib/activation-matcher.d.ts.map +0 -1
- package/dist/lib/asmr/categorizer.d.ts +0 -31
- package/dist/lib/asmr/categorizer.d.ts.map +0 -1
- package/dist/lib/asmr/context-agent.d.ts +0 -4
- package/dist/lib/asmr/context-agent.d.ts.map +0 -1
- package/dist/lib/asmr/ensemble.d.ts +0 -23
- package/dist/lib/asmr/ensemble.d.ts.map +0 -1
- package/dist/lib/asmr/fact-agent.d.ts +0 -4
- package/dist/lib/asmr/fact-agent.d.ts.map +0 -1
- package/dist/lib/asmr/index.d.ts +0 -7
- package/dist/lib/asmr/index.d.ts.map +0 -1
- package/dist/lib/asmr/orchestrator.d.ts +0 -4
- package/dist/lib/asmr/orchestrator.d.ts.map +0 -1
- package/dist/lib/asmr/recall.d.ts +0 -3
- package/dist/lib/asmr/recall.d.ts.map +0 -1
- package/dist/lib/asmr/temporal-agent.d.ts +0 -4
- package/dist/lib/asmr/temporal-agent.d.ts.map +0 -1
- package/dist/lib/asmr/types.d.ts +0 -27
- package/dist/lib/asmr/types.d.ts.map +0 -1
- package/dist/lib/auto-inject-orchestrator.d.ts +0 -57
- package/dist/lib/auto-inject-orchestrator.d.ts.map +0 -1
- package/dist/lib/auto-memory-queue.d.ts +0 -48
- package/dist/lib/auto-memory-queue.d.ts.map +0 -1
- package/dist/lib/auto-memory.d.ts +0 -19
- package/dist/lib/auto-memory.d.ts.map +0 -1
- package/dist/lib/bench.d.ts +0 -20
- package/dist/lib/bench.d.ts.map +0 -1
- package/dist/lib/built-in-hooks.d.ts +0 -12
- package/dist/lib/built-in-hooks.d.ts.map +0 -1
- package/dist/lib/channel-pusher.d.ts +0 -39
- package/dist/lib/channel-pusher.d.ts.map +0 -1
- package/dist/lib/config.d.ts +0 -9
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/connectors/files.d.ts +0 -8
- package/dist/lib/connectors/files.d.ts.map +0 -1
- package/dist/lib/connectors/github.d.ts +0 -7
- package/dist/lib/connectors/github.d.ts.map +0 -1
- package/dist/lib/connectors/index.d.ts +0 -12
- package/dist/lib/connectors/index.d.ts.map +0 -1
- package/dist/lib/connectors/notion.d.ts +0 -7
- package/dist/lib/connectors/notion.d.ts.map +0 -1
- package/dist/lib/connectors/types.d.ts +0 -27
- package/dist/lib/connectors/types.d.ts.map +0 -1
- package/dist/lib/consolidation.d.ts +0 -52
- package/dist/lib/consolidation.d.ts.map +0 -1
- package/dist/lib/context-extractor.d.ts +0 -14
- package/dist/lib/context-extractor.d.ts.map +0 -1
- package/dist/lib/context.d.ts +0 -36
- package/dist/lib/context.d.ts.map +0 -1
- package/dist/lib/contradiction.d.ts +0 -50
- package/dist/lib/contradiction.d.ts.map +0 -1
- package/dist/lib/decay.d.ts +0 -35
- package/dist/lib/decay.d.ts.map +0 -1
- package/dist/lib/dedup.d.ts +0 -33
- package/dist/lib/dedup.d.ts.map +0 -1
- package/dist/lib/duration.d.ts +0 -28
- package/dist/lib/duration.d.ts.map +0 -1
- package/dist/lib/embeddings.d.ts +0 -20
- package/dist/lib/embeddings.d.ts.map +0 -1
- package/dist/lib/enum-validation.d.ts +0 -20
- package/dist/lib/enum-validation.d.ts.map +0 -1
- package/dist/lib/export-v1.d.ts +0 -30
- package/dist/lib/export-v1.d.ts.map +0 -1
- package/dist/lib/extractor.d.ts +0 -9
- package/dist/lib/extractor.d.ts.map +0 -1
- package/dist/lib/extractors/audio.d.ts +0 -8
- package/dist/lib/extractors/audio.d.ts.map +0 -1
- package/dist/lib/extractors/index.d.ts +0 -12
- package/dist/lib/extractors/index.d.ts.map +0 -1
- package/dist/lib/extractors/ocr.d.ts +0 -7
- package/dist/lib/extractors/ocr.d.ts.map +0 -1
- package/dist/lib/extractors/pdf.d.ts +0 -7
- package/dist/lib/extractors/pdf.d.ts.map +0 -1
- package/dist/lib/extractors/types.d.ts +0 -12
- package/dist/lib/extractors/types.d.ts.map +0 -1
- package/dist/lib/file-deps.d.ts +0 -27
- package/dist/lib/file-deps.d.ts.map +0 -1
- package/dist/lib/focus.d.ts +0 -58
- package/dist/lib/focus.d.ts.map +0 -1
- package/dist/lib/gatherer.d.ts +0 -16
- package/dist/lib/gatherer.d.ts.map +0 -1
- package/dist/lib/gdpr.d.ts +0 -39
- package/dist/lib/gdpr.d.ts.map +0 -1
- package/dist/lib/hooks.d.ts +0 -50
- package/dist/lib/hooks.d.ts.map +0 -1
- package/dist/lib/importers/index.d.ts +0 -38
- package/dist/lib/importers/index.d.ts.map +0 -1
- package/dist/lib/injector.d.ts +0 -89
- package/dist/lib/injector.d.ts.map +0 -1
- package/dist/lib/machine-visibility.d.ts +0 -6
- package/dist/lib/machine-visibility.d.ts.map +0 -1
- package/dist/lib/matryoshka.d.ts +0 -50
- package/dist/lib/matryoshka.d.ts.map +0 -1
- package/dist/lib/memory-lock.d.ts +0 -58
- package/dist/lib/memory-lock.d.ts.map +0 -1
- package/dist/lib/model-config.d.ts +0 -14
- package/dist/lib/model-config.d.ts.map +0 -1
- package/dist/lib/open-sessions-connector.d.ts +0 -60
- package/dist/lib/open-sessions-connector.d.ts.map +0 -1
- package/dist/lib/package-version.d.ts +0 -3
- package/dist/lib/package-version.d.ts.map +0 -1
- package/dist/lib/poisoning.d.ts +0 -19
- package/dist/lib/poisoning.d.ts.map +0 -1
- package/dist/lib/poll.d.ts +0 -17
- package/dist/lib/poll.d.ts.map +0 -1
- package/dist/lib/procedural-extractor.d.ts +0 -21
- package/dist/lib/procedural-extractor.d.ts.map +0 -1
- package/dist/lib/profile-sync.d.ts +0 -20
- package/dist/lib/profile-sync.d.ts.map +0 -1
- package/dist/lib/profile-synthesizer.d.ts +0 -20
- package/dist/lib/profile-synthesizer.d.ts.map +0 -1
- package/dist/lib/project-detect.d.ts +0 -18
- package/dist/lib/project-detect.d.ts.map +0 -1
- package/dist/lib/project-panel.d.ts +0 -7
- package/dist/lib/project-panel.d.ts.map +0 -1
- package/dist/lib/providers/anthropic.d.ts +0 -21
- package/dist/lib/providers/anthropic.d.ts.map +0 -1
- package/dist/lib/providers/base.d.ts +0 -96
- package/dist/lib/providers/base.d.ts.map +0 -1
- package/dist/lib/providers/cerebras.d.ts +0 -20
- package/dist/lib/providers/cerebras.d.ts.map +0 -1
- package/dist/lib/providers/grok.d.ts +0 -19
- package/dist/lib/providers/grok.d.ts.map +0 -1
- package/dist/lib/providers/index.d.ts +0 -7
- package/dist/lib/providers/index.d.ts.map +0 -1
- package/dist/lib/providers/openai-compat.d.ts +0 -18
- package/dist/lib/providers/openai-compat.d.ts.map +0 -1
- package/dist/lib/providers/openai.d.ts +0 -20
- package/dist/lib/providers/openai.d.ts.map +0 -1
- package/dist/lib/providers/registry.d.ts +0 -38
- package/dist/lib/providers/registry.d.ts.map +0 -1
- package/dist/lib/quality.d.ts +0 -16
- package/dist/lib/quality.d.ts.map +0 -1
- package/dist/lib/redact.d.ts +0 -10
- package/dist/lib/redact.d.ts.map +0 -1
- package/dist/lib/reflection.d.ts +0 -83
- package/dist/lib/reflection.d.ts.map +0 -1
- package/dist/lib/retention.d.ts +0 -17
- package/dist/lib/retention.d.ts.map +0 -1
- package/dist/lib/retired-storage-mode.d.ts +0 -11
- package/dist/lib/retired-storage-mode.d.ts.map +0 -1
- package/dist/lib/search.d.ts +0 -52
- package/dist/lib/search.d.ts.map +0 -1
- package/dist/lib/session-auto-resolve.d.ts +0 -28
- package/dist/lib/session-auto-resolve.d.ts.map +0 -1
- package/dist/lib/session-processor.d.ts +0 -38
- package/dist/lib/session-processor.d.ts.map +0 -1
- package/dist/lib/session-queue.d.ts +0 -28
- package/dist/lib/session-queue.d.ts.map +0 -1
- package/dist/lib/session-registry.d.ts +0 -47
- package/dist/lib/session-registry.d.ts.map +0 -1
- package/dist/lib/session-start-briefing.d.ts +0 -10
- package/dist/lib/session-start-briefing.d.ts.map +0 -1
- package/dist/lib/session-watcher.d.ts +0 -30
- package/dist/lib/session-watcher.d.ts.map +0 -1
- package/dist/lib/storage-sync.d.ts +0 -45
- package/dist/lib/storage-sync.d.ts.map +0 -1
- package/dist/lib/sync.d.ts +0 -10
- package/dist/lib/sync.d.ts.map +0 -1
- package/dist/lib/synthesis/corpus-builder.d.ts +0 -30
- package/dist/lib/synthesis/corpus-builder.d.ts.map +0 -1
- package/dist/lib/synthesis/executor.d.ts +0 -14
- package/dist/lib/synthesis/executor.d.ts.map +0 -1
- package/dist/lib/synthesis/index.d.ts +0 -37
- package/dist/lib/synthesis/index.d.ts.map +0 -1
- package/dist/lib/synthesis/llm-analyzer.d.ts +0 -18
- package/dist/lib/synthesis/llm-analyzer.d.ts.map +0 -1
- package/dist/lib/synthesis/metrics.d.ts +0 -13
- package/dist/lib/synthesis/metrics.d.ts.map +0 -1
- package/dist/lib/synthesis/scheduler.d.ts +0 -18
- package/dist/lib/synthesis/scheduler.d.ts.map +0 -1
- package/dist/lib/synthesis/validator.d.ts +0 -19
- package/dist/lib/synthesis/validator.d.ts.map +0 -1
- package/dist/lib/task-runner.d.ts +0 -37
- package/dist/lib/task-runner.d.ts.map +0 -1
- package/dist/lib/tool-lesson-extractor.d.ts +0 -24
- package/dist/lib/tool-lesson-extractor.d.ts.map +0 -1
- package/dist/lib/tool-memory-synthesizer.d.ts +0 -28
- package/dist/lib/tool-memory-synthesizer.d.ts.map +0 -1
- package/dist/lib/topic-clusterer.d.ts +0 -21
- package/dist/lib/topic-clusterer.d.ts.map +0 -1
- package/dist/lib/when-to-use-generator.d.ts +0 -22
- package/dist/lib/when-to-use-generator.d.ts.map +0 -1
- package/dist/mcp/http.d.ts +0 -17
- package/dist/mcp/http.d.ts.map +0 -1
- package/dist/mcp/index.d.ts +0 -6
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/memory-broadcast.d.ts +0 -12
- package/dist/mcp/memory-broadcast.d.ts.map +0 -1
- package/dist/mcp/tools/agent-tools.d.ts +0 -3
- package/dist/mcp/tools/agent-tools.d.ts.map +0 -1
- package/dist/mcp/tools/auto-memory-tools.d.ts +0 -5
- package/dist/mcp/tools/auto-memory-tools.d.ts.map +0 -1
- package/dist/mcp/tools/bulk-tools.d.ts +0 -3
- package/dist/mcp/tools/bulk-tools.d.ts.map +0 -1
- package/dist/mcp/tools/consolidation-tools.d.ts +0 -3
- package/dist/mcp/tools/consolidation-tools.d.ts.map +0 -1
- package/dist/mcp/tools/focus-tools.d.ts +0 -3
- package/dist/mcp/tools/focus-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-entity-tools.d.ts +0 -3
- package/dist/mcp/tools/graph-entity-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-query-tools.d.ts +0 -3
- package/dist/mcp/tools/graph-query-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-relation-tools.d.ts +0 -3
- package/dist/mcp/tools/graph-relation-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-tools.d.ts +0 -3
- package/dist/mcp/tools/graph-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-utils.d.ts +0 -5
- package/dist/mcp/tools/graph-utils.d.ts.map +0 -1
- package/dist/mcp/tools/hook-tools.d.ts +0 -3
- package/dist/mcp/tools/hook-tools.d.ts.map +0 -1
- package/dist/mcp/tools/lock-tools.d.ts +0 -3
- package/dist/mcp/tools/lock-tools.d.ts.map +0 -1
- package/dist/mcp/tools/memory-audit.d.ts +0 -3
- package/dist/mcp/tools/memory-audit.d.ts.map +0 -1
- package/dist/mcp/tools/memory-crud.d.ts +0 -3
- package/dist/mcp/tools/memory-crud.d.ts.map +0 -1
- package/dist/mcp/tools/memory-health.d.ts +0 -3
- package/dist/mcp/tools/memory-health.d.ts.map +0 -1
- package/dist/mcp/tools/memory-history.d.ts +0 -3
- package/dist/mcp/tools/memory-history.d.ts.map +0 -1
- package/dist/mcp/tools/memory-inject.d.ts +0 -3
- package/dist/mcp/tools/memory-inject.d.ts.map +0 -1
- package/dist/mcp/tools/memory-io.d.ts +0 -3
- package/dist/mcp/tools/memory-io.d.ts.map +0 -1
- package/dist/mcp/tools/memory-lifecycle.d.ts +0 -3
- package/dist/mcp/tools/memory-lifecycle.d.ts.map +0 -1
- package/dist/mcp/tools/memory-search.d.ts +0 -3
- package/dist/mcp/tools/memory-search.d.ts.map +0 -1
- package/dist/mcp/tools/memory-stats.d.ts +0 -3
- package/dist/mcp/tools/memory-stats.d.ts.map +0 -1
- package/dist/mcp/tools/memory-tools.d.ts +0 -17
- package/dist/mcp/tools/memory-tools.d.ts.map +0 -1
- package/dist/mcp/tools/memory-utils.d.ts +0 -27
- package/dist/mcp/tools/memory-utils.d.ts.map +0 -1
- package/dist/mcp/tools/memory-validation.d.ts +0 -3
- package/dist/mcp/tools/memory-validation.d.ts.map +0 -1
- package/dist/mcp/tools/project-tools.d.ts +0 -3
- package/dist/mcp/tools/project-tools.d.ts.map +0 -1
- package/dist/mcp/tools/session-tools.d.ts +0 -3
- package/dist/mcp/tools/session-tools.d.ts.map +0 -1
- package/dist/mcp/tools/storage-tools.d.ts +0 -3
- package/dist/mcp/tools/storage-tools.d.ts.map +0 -1
- package/dist/mcp/tools/synthesis-tools.d.ts +0 -3
- package/dist/mcp/tools/synthesis-tools.d.ts.map +0 -1
- package/dist/mcp/tools/system-tools-events.d.ts +0 -3
- package/dist/mcp/tools/system-tools-events.d.ts.map +0 -1
- package/dist/mcp/tools/system-tools-memory-admin.d.ts +0 -3
- package/dist/mcp/tools/system-tools-memory-admin.d.ts.map +0 -1
- package/dist/mcp/tools/system-tools-shared.d.ts +0 -23
- package/dist/mcp/tools/system-tools-shared.d.ts.map +0 -1
- package/dist/mcp/tools/system-tools.d.ts +0 -3
- package/dist/mcp/tools/system-tools.d.ts.map +0 -1
- package/dist/mcp/tools/tool-registry.d.ts +0 -30
- package/dist/mcp/tools/tool-registry.d.ts.map +0 -1
- package/dist/mcp/tools/utility-tools.d.ts +0 -3
- package/dist/mcp/tools/utility-tools.d.ts.map +0 -1
- package/dist/memory-project-link/index.d.ts +0 -2
- package/dist/memory-project-link/index.d.ts.map +0 -1
- package/dist/memory-project-link/schema.d.ts +0 -5
- package/dist/memory-project-link/schema.d.ts.map +0 -1
- package/dist/pg-sync-worker.d.ts +0 -2
- package/dist/pg-sync-worker.d.ts.map +0 -1
- package/dist/project-registration/authority.d.ts +0 -43
- package/dist/project-registration/authority.d.ts.map +0 -1
- package/dist/project-registration/http.d.ts +0 -32
- package/dist/project-registration/http.d.ts.map +0 -1
- package/dist/project-registration/identity.d.ts +0 -20
- package/dist/project-registration/identity.d.ts.map +0 -1
- package/dist/project-registration/index.d.ts +0 -11
- package/dist/project-registration/index.d.ts.map +0 -1
- package/dist/project-registration/project-references.d.ts +0 -71
- package/dist/project-registration/project-references.d.ts.map +0 -1
- package/dist/project-registration/project-resources.d.ts +0 -22
- package/dist/project-registration/project-resources.d.ts.map +0 -1
- package/dist/project-registration/schema.d.ts +0 -5
- package/dist/project-registration/schema.d.ts.map +0 -1
- package/dist/project-registration/types.d.ts +0 -293
- package/dist/project-registration/types.d.ts.map +0 -1
- package/dist/project-registration.d.ts +0 -2
- package/dist/project-registration.d.ts.map +0 -1
- package/dist/sdk/index.d.ts +0 -971
- package/dist/sdk/index.d.ts.map +0 -1
- package/dist/server/auth.d.ts +0 -11
- package/dist/server/auth.d.ts.map +0 -1
- package/dist/server/helpers.d.ts +0 -22
- package/dist/server/helpers.d.ts.map +0 -1
- package/dist/server/index.d.ts +0 -14
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/openapi.d.ts +0 -2
- package/dist/server/openapi.d.ts.map +0 -1
- package/dist/server/router.d.ts +0 -17
- package/dist/server/router.d.ts.map +0 -1
- package/dist/server/routes/agents.d.ts +0 -2
- package/dist/server/routes/agents.d.ts.map +0 -1
- package/dist/server/routes/entities.d.ts +0 -2
- package/dist/server/routes/entities.d.ts.map +0 -1
- package/dist/server/routes/memories-bulk.d.ts +0 -2
- package/dist/server/routes/memories-bulk.d.ts.map +0 -1
- package/dist/server/routes/memories-crud.d.ts +0 -2
- package/dist/server/routes/memories-crud.d.ts.map +0 -1
- package/dist/server/routes/memories-io.d.ts +0 -2
- package/dist/server/routes/memories-io.d.ts.map +0 -1
- package/dist/server/routes/memories-misc.d.ts +0 -2
- package/dist/server/routes/memories-misc.d.ts.map +0 -1
- package/dist/server/routes/memories-search.d.ts +0 -2
- package/dist/server/routes/memories-search.d.ts.map +0 -1
- package/dist/server/routes/memories-stats.d.ts +0 -2
- package/dist/server/routes/memories-stats.d.ts.map +0 -1
- package/dist/server/routes/memories.d.ts +0 -19
- package/dist/server/routes/memories.d.ts.map +0 -1
- package/dist/server/routes/memory-project-link.d.ts +0 -2
- package/dist/server/routes/memory-project-link.d.ts.map +0 -1
- package/dist/server/routes/project-registration.d.ts +0 -2
- package/dist/server/routes/project-registration.d.ts.map +0 -1
- package/dist/server/routes/projects.d.ts +0 -2
- package/dist/server/routes/projects.d.ts.map +0 -1
- package/dist/server/routes/system-auto-memory.d.ts +0 -2
- package/dist/server/routes/system-auto-memory.d.ts.map +0 -1
- package/dist/server/routes/system-chain.d.ts +0 -2
- package/dist/server/routes/system-chain.d.ts.map +0 -1
- package/dist/server/routes/system-consolidation.d.ts +0 -2
- package/dist/server/routes/system-consolidation.d.ts.map +0 -1
- package/dist/server/routes/system-hooks.d.ts +0 -2
- package/dist/server/routes/system-hooks.d.ts.map +0 -1
- package/dist/server/routes/system-sessions.d.ts +0 -2
- package/dist/server/routes/system-sessions.d.ts.map +0 -1
- package/dist/server/routes/system-subscriptions.d.ts +0 -2
- package/dist/server/routes/system-subscriptions.d.ts.map +0 -1
- package/dist/server/routes/system-synthesis.d.ts +0 -2
- package/dist/server/routes/system-synthesis.d.ts.map +0 -1
- package/dist/server/routes/system-tools.d.ts +0 -2
- package/dist/server/routes/system-tools.d.ts.map +0 -1
- package/dist/server/routes/system.d.ts +0 -2
- package/dist/server/routes/system.d.ts.map +0 -1
- package/dist/server/routes/tasks.d.ts +0 -2
- package/dist/server/routes/tasks.d.ts.map +0 -1
- package/dist/storage.d.ts +0 -266
- package/dist/storage.d.ts.map +0 -1
- package/dist/test-support/preload-local-store.d.ts +0 -2
- package/dist/test-support/preload-local-store.d.ts.map +0 -1
- package/dist/test-support/project-authority-identity.d.ts +0 -8
- package/dist/test-support/project-authority-identity.d.ts.map +0 -1
- package/dist/test-support/store-isolation.d.ts +0 -108
- package/dist/test-support/store-isolation.d.ts.map +0 -1
- package/dist/test-support/strip-ansi.d.ts +0 -3
- package/dist/test-support/strip-ansi.d.ts.map +0 -1
- package/dist/types/hooks.d.ts +0 -136
- package/dist/types/hooks.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -472
- package/dist/types/index.d.ts.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -243,6 +243,7 @@ function translateSql(sql) {
|
|
|
243
243
|
let translated = sql.replace(/\?/g, () => `$${++parameterIndex}`);
|
|
244
244
|
const ISO_FMT = `'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'`;
|
|
245
245
|
translated = translated.replace(/datetime\s*\(\s*'now'\s*\)/gi, `to_char(now() AT TIME ZONE 'UTC', ${ISO_FMT})`);
|
|
246
|
+
translated = translated.replace(/strftime\s*\(\s*'%Y-%m-%dT%H:%M:%fZ'\s*,\s*'now'\s*\)/gi, `to_char(now() AT TIME ZONE 'UTC', ${ISO_FMT})`);
|
|
246
247
|
translated = translated.replace(/datetime\s*\(\s*'now'\s*,\s*'(-?\d+)\s+(minutes?|hours?|days?|seconds?)'\s*\)/gi, (_match, amount, unit) => {
|
|
247
248
|
const parsed = parseInt(String(amount), 10);
|
|
248
249
|
const absolute = Math.abs(parsed);
|
|
@@ -524,8 +525,13 @@ var init_storage = __esm(() => {
|
|
|
524
525
|
data;
|
|
525
526
|
closed = false;
|
|
526
527
|
lastError = null;
|
|
528
|
+
generation = 0;
|
|
527
529
|
static DATA_BYTES = 128 * 1024 * 1024;
|
|
528
|
-
static
|
|
530
|
+
static queryTimeoutMs() {
|
|
531
|
+
const raw = process.env["MEMENTOS_PGSYNC_QUERY_TIMEOUT_MS"]?.trim();
|
|
532
|
+
const parsed = raw ? Number(raw) : Number.NaN;
|
|
533
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 60000;
|
|
534
|
+
}
|
|
529
535
|
static resolveWorkerPath() {
|
|
530
536
|
const ext = import.meta.url.endsWith(".ts") ? ".ts" : ".js";
|
|
531
537
|
const here = fileURLToPath(new URL(".", import.meta.url));
|
|
@@ -540,12 +546,12 @@ var init_storage = __esm(() => {
|
|
|
540
546
|
}
|
|
541
547
|
return candidates[0];
|
|
542
548
|
}
|
|
543
|
-
constructor(connectionString) {
|
|
544
|
-
const control = new SharedArrayBuffer(
|
|
549
|
+
constructor(connectionString, workerPath) {
|
|
550
|
+
const control = new SharedArrayBuffer(12);
|
|
545
551
|
const dataSab = new SharedArrayBuffer(PgSyncPool.DATA_BYTES);
|
|
546
552
|
this.status = new Int32Array(control);
|
|
547
553
|
this.data = new Uint8Array(dataSab);
|
|
548
|
-
this.worker = new Worker(PgSyncPool.resolveWorkerPath(), {
|
|
554
|
+
this.worker = new Worker(workerPath ?? PgSyncPool.resolveWorkerPath(), {
|
|
549
555
|
workerData: {
|
|
550
556
|
dsn: stripSslParams(connectionString),
|
|
551
557
|
ssl: sslConfigFor(connectionString),
|
|
@@ -563,21 +569,35 @@ var init_storage = __esm(() => {
|
|
|
563
569
|
throw new Error("PgSyncPool is closed");
|
|
564
570
|
if (this.lastError)
|
|
565
571
|
throw this.lastError;
|
|
572
|
+
const timeoutMs = PgSyncPool.queryTimeoutMs();
|
|
573
|
+
const gen = ++this.generation;
|
|
566
574
|
Atomics.store(this.status, 0, 0);
|
|
567
|
-
this.
|
|
568
|
-
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
575
|
+
Atomics.store(this.status, 2, 0);
|
|
576
|
+
this.worker.postMessage({ sql, params, gen });
|
|
577
|
+
const deadline = Date.now() + timeoutMs;
|
|
578
|
+
for (;; ) {
|
|
579
|
+
const remaining = deadline - Date.now();
|
|
580
|
+
const responding = Atomics.load(this.status, 0);
|
|
581
|
+
if (responding === gen) {
|
|
582
|
+
const code = Atomics.load(this.status, 2);
|
|
583
|
+
const len = Atomics.load(this.status, 1);
|
|
584
|
+
const payload = JSON.parse(new TextDecoder().decode(this.data.subarray(0, len)));
|
|
585
|
+
if (code === 2) {
|
|
586
|
+
throw new Error(payload.message ?? "PostgreSQL error");
|
|
587
|
+
}
|
|
588
|
+
return payload;
|
|
589
|
+
}
|
|
590
|
+
if (responding !== 0) {
|
|
591
|
+
Atomics.compareExchange(this.status, 0, responding, 0);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (remaining <= 0) {
|
|
595
|
+
if (this.lastError)
|
|
596
|
+
throw this.lastError;
|
|
597
|
+
throw new Error(`PostgreSQL query timed out after ${timeoutMs}ms`);
|
|
598
|
+
}
|
|
599
|
+
Atomics.wait(this.status, 0, 0, remaining);
|
|
579
600
|
}
|
|
580
|
-
return payload;
|
|
581
601
|
}
|
|
582
602
|
end() {
|
|
583
603
|
if (this.closed)
|
|
@@ -780,7 +800,16 @@ x-api-key: ${cfg.apiKey}
|
|
|
780
800
|
function apiJson(method, path, body, options) {
|
|
781
801
|
const raw = apiRequestRaw(method, path, body);
|
|
782
802
|
if (raw.status >= 200 && raw.status < 300) {
|
|
783
|
-
|
|
803
|
+
let data;
|
|
804
|
+
if (raw.body.trim()) {
|
|
805
|
+
try {
|
|
806
|
+
data = JSON.parse(raw.body);
|
|
807
|
+
} catch (e) {
|
|
808
|
+
throw new ApiRequestError(`mementos cloud ${method} ${path} returned status ${raw.status} with a body that is not valid JSON (${e instanceof Error ? e.message : String(e)}) \u2014 the response is truncated or the server is unhealthy`, raw.status, raw.body.slice(0, 500));
|
|
809
|
+
}
|
|
810
|
+
} else {
|
|
811
|
+
data = undefined;
|
|
812
|
+
}
|
|
784
813
|
return { status: raw.status, data };
|
|
785
814
|
}
|
|
786
815
|
if (raw.status === 404 && options?.allow404) {
|
|
@@ -2695,8 +2724,12 @@ __export(exports_memories, {
|
|
|
2695
2724
|
updateMemory: () => updateMemory,
|
|
2696
2725
|
touchMemory: () => touchMemory,
|
|
2697
2726
|
semanticSearch: () => semanticSearch,
|
|
2727
|
+
reservedAgentIdViolation: () => reservedAgentIdViolation,
|
|
2698
2728
|
parseMemoryRow: () => parseMemoryRow,
|
|
2729
|
+
listMemoryHistoryPage: () => listMemoryHistoryPage,
|
|
2699
2730
|
listMemoryHistory: () => listMemoryHistory,
|
|
2731
|
+
listMemoriesPage: () => listMemoriesPage,
|
|
2732
|
+
listMemoriesBounded: () => listMemoriesBounded,
|
|
2700
2733
|
listMemories: () => listMemories,
|
|
2701
2734
|
listLowTrustMemories: () => listLowTrustMemories,
|
|
2702
2735
|
indexMemoryEmbedding: () => indexMemoryEmbedding,
|
|
@@ -2710,6 +2743,8 @@ __export(exports_memories, {
|
|
|
2710
2743
|
getMemoriesByKey: () => getMemoriesByKey,
|
|
2711
2744
|
deleteMemory: () => deleteMemory,
|
|
2712
2745
|
createMemory: () => createMemory,
|
|
2746
|
+
countMemoryHistory: () => countMemoryHistory,
|
|
2747
|
+
countMemories: () => countMemories,
|
|
2713
2748
|
cleanExpiredMemories: () => cleanExpiredMemories,
|
|
2714
2749
|
bulkUpsertMemories: () => bulkUpsertMemories,
|
|
2715
2750
|
bulkDeleteMemories: () => bulkDeleteMemories
|
|
@@ -2761,7 +2796,20 @@ function parseMemoryRow(row) {
|
|
|
2761
2796
|
accessed_at: row["accessed_at"] || null
|
|
2762
2797
|
};
|
|
2763
2798
|
}
|
|
2799
|
+
function reservedAgentIdViolation(agentId) {
|
|
2800
|
+
if (!agentId)
|
|
2801
|
+
return null;
|
|
2802
|
+
const normalized = agentId.trim().toLowerCase();
|
|
2803
|
+
if (RESERVED_AGENT_IDS.has(normalized)) {
|
|
2804
|
+
return `Reserved placeholder agent id "${agentId}" cannot own a memory. ` + `Refusing to write: test harnesses must not write memories under placeholder agent ` + `identities. Register a real agent (mementos register-agent <name>) and pass its id.`;
|
|
2805
|
+
}
|
|
2806
|
+
return null;
|
|
2807
|
+
}
|
|
2764
2808
|
function createMemory(input, dedupeMode = "merge", db) {
|
|
2809
|
+
const reservedViolation = reservedAgentIdViolation(input.agent_id);
|
|
2810
|
+
if (reservedViolation) {
|
|
2811
|
+
throw new Error(reservedViolation);
|
|
2812
|
+
}
|
|
2765
2813
|
if (!db && isApiMode()) {
|
|
2766
2814
|
const { status, data } = apiJson("POST", "/memories", { ...input, dedupe: dedupeMode });
|
|
2767
2815
|
if (!data || !data.id) {
|
|
@@ -2811,7 +2859,8 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
2811
2859
|
importance = ?, metadata = ?, expires_at = ?,
|
|
2812
2860
|
when_to_use = ?,
|
|
2813
2861
|
pinned = COALESCE(pinned, 0),
|
|
2814
|
-
version = version + 1, updated_at =
|
|
2862
|
+
version = version + 1, updated_at = ?,
|
|
2863
|
+
updated_by_agent = ?
|
|
2815
2864
|
WHERE id = ?`, [
|
|
2816
2865
|
safeValue,
|
|
2817
2866
|
input.category || "knowledge",
|
|
@@ -2822,6 +2871,7 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
2822
2871
|
expiresAt,
|
|
2823
2872
|
input.when_to_use || null,
|
|
2824
2873
|
timestamp,
|
|
2874
|
+
input.agent_id || null,
|
|
2825
2875
|
existing.id
|
|
2826
2876
|
]);
|
|
2827
2877
|
d.run("DELETE FROM memory_tags WHERE memory_id = ?", [existing.id]);
|
|
@@ -2926,6 +2976,12 @@ function bulkUpsertMemories(memories, db) {
|
|
|
2926
2976
|
errors.push(`Rejected "${key}": ${formatEnumViolation(violation)}`);
|
|
2927
2977
|
continue;
|
|
2928
2978
|
}
|
|
2979
|
+
const agentViolation = reservedAgentIdViolation(typeof mem["agent_id"] === "string" ? mem["agent_id"] : undefined);
|
|
2980
|
+
if (agentViolation) {
|
|
2981
|
+
rejected++;
|
|
2982
|
+
errors.push(`Rejected "${key}": ${agentViolation}`);
|
|
2983
|
+
continue;
|
|
2984
|
+
}
|
|
2929
2985
|
const timestamp = now();
|
|
2930
2986
|
let tags = [];
|
|
2931
2987
|
const rawTags = mem["tags"];
|
|
@@ -3076,29 +3132,7 @@ function getMemoriesByKey(key, scope, agentId, projectId, db) {
|
|
|
3076
3132
|
const rows = d.query(sql).all(...params);
|
|
3077
3133
|
return rows.map(parseMemoryRow);
|
|
3078
3134
|
}
|
|
3079
|
-
function
|
|
3080
|
-
if (!db && isApiMode()) {
|
|
3081
|
-
const f = filter || {};
|
|
3082
|
-
const q = toQuery({
|
|
3083
|
-
key: f.key,
|
|
3084
|
-
scope: f.scope,
|
|
3085
|
-
category: f.category,
|
|
3086
|
-
status: f.status,
|
|
3087
|
-
tags: f.tags,
|
|
3088
|
-
min_importance: f.min_importance,
|
|
3089
|
-
pinned: f.pinned,
|
|
3090
|
-
agent_id: f.agent_id,
|
|
3091
|
-
project_id: f.project_id,
|
|
3092
|
-
session_id: f.session_id,
|
|
3093
|
-
namespace: f.namespace,
|
|
3094
|
-
as_of: f.as_of,
|
|
3095
|
-
limit: f.limit,
|
|
3096
|
-
offset: f.offset
|
|
3097
|
-
});
|
|
3098
|
-
const { data } = apiJson("GET", `/memories${q}`);
|
|
3099
|
-
return data?.memories ?? [];
|
|
3100
|
-
}
|
|
3101
|
-
const d = db || getDatabase();
|
|
3135
|
+
function buildMemoryListConditions(filter) {
|
|
3102
3136
|
const conditions = [];
|
|
3103
3137
|
const params = [];
|
|
3104
3138
|
if (filter) {
|
|
@@ -3210,21 +3244,114 @@ function listMemories(filter, db) {
|
|
|
3210
3244
|
} else {
|
|
3211
3245
|
conditions.push("status = 'active'");
|
|
3212
3246
|
}
|
|
3247
|
+
return { conditions, params };
|
|
3248
|
+
}
|
|
3249
|
+
function listMemoriesPage(filter, db) {
|
|
3250
|
+
const f = filter || {};
|
|
3251
|
+
if (!db && isApiMode()) {
|
|
3252
|
+
const q = toQuery({
|
|
3253
|
+
key: f.key,
|
|
3254
|
+
scope: f.scope,
|
|
3255
|
+
category: f.category,
|
|
3256
|
+
status: f.status,
|
|
3257
|
+
tags: f.tags,
|
|
3258
|
+
min_importance: f.min_importance,
|
|
3259
|
+
pinned: f.pinned,
|
|
3260
|
+
agent_id: f.agent_id,
|
|
3261
|
+
project_id: f.project_id,
|
|
3262
|
+
session_id: f.session_id,
|
|
3263
|
+
machine_id: f.machine_id,
|
|
3264
|
+
visible_to_machine_id: f.visible_to_machine_id,
|
|
3265
|
+
search: f.search,
|
|
3266
|
+
source: f.source,
|
|
3267
|
+
flag: f.flag,
|
|
3268
|
+
namespace: f.namespace,
|
|
3269
|
+
as_of: f.as_of,
|
|
3270
|
+
limit: f.limit,
|
|
3271
|
+
offset: f.offset
|
|
3272
|
+
});
|
|
3273
|
+
const { data } = apiJson("GET", `/memories${q}`);
|
|
3274
|
+
return {
|
|
3275
|
+
rows: data?.memories ?? [],
|
|
3276
|
+
has_more: data?.has_more,
|
|
3277
|
+
next_cursor: data?.next_cursor ?? null
|
|
3278
|
+
};
|
|
3279
|
+
}
|
|
3280
|
+
const d = db || getDatabase();
|
|
3281
|
+
const { conditions, params } = buildMemoryListConditions(f);
|
|
3213
3282
|
let sql = "SELECT * FROM memories";
|
|
3214
3283
|
if (conditions.length > 0) {
|
|
3215
3284
|
sql += ` WHERE ${conditions.join(" AND ")}`;
|
|
3216
3285
|
}
|
|
3217
3286
|
sql += " ORDER BY importance DESC, created_at DESC";
|
|
3218
|
-
if (
|
|
3287
|
+
if (f.limit) {
|
|
3219
3288
|
sql += " LIMIT ?";
|
|
3220
|
-
params.push(
|
|
3289
|
+
params.push(f.limit);
|
|
3221
3290
|
}
|
|
3222
|
-
if (
|
|
3291
|
+
if (f.offset) {
|
|
3223
3292
|
sql += " OFFSET ?";
|
|
3224
|
-
params.push(
|
|
3293
|
+
params.push(f.offset);
|
|
3225
3294
|
}
|
|
3226
3295
|
const rows = d.query(sql).all(...params);
|
|
3227
|
-
|
|
3296
|
+
const parsed = rows.map(parseMemoryRow);
|
|
3297
|
+
const hasMore = f.limit !== undefined && parsed.length === f.limit;
|
|
3298
|
+
return {
|
|
3299
|
+
rows: parsed,
|
|
3300
|
+
has_more: hasMore,
|
|
3301
|
+
next_cursor: hasMore ? (f.offset ?? 0) + parsed.length : null
|
|
3302
|
+
};
|
|
3303
|
+
}
|
|
3304
|
+
function listMemories(filter, db) {
|
|
3305
|
+
return listMemoriesPage(filter, db).rows;
|
|
3306
|
+
}
|
|
3307
|
+
function listMemoriesBounded(filter = {}, target, db) {
|
|
3308
|
+
const pageSize = 1000;
|
|
3309
|
+
const maxPages = 1000;
|
|
3310
|
+
const want = target === undefined ? undefined : target + 1;
|
|
3311
|
+
const rows = [];
|
|
3312
|
+
const seenCursors = new Set;
|
|
3313
|
+
let cursor = filter.offset ?? 0;
|
|
3314
|
+
let pages = 0;
|
|
3315
|
+
for (;; ) {
|
|
3316
|
+
if (want !== undefined && rows.length >= want)
|
|
3317
|
+
break;
|
|
3318
|
+
if (++pages > maxPages) {
|
|
3319
|
+
throw new Error(`memories list traversal exceeded ${maxPages} pages while collecting rows \u2014 aborting (cursor cycle?)`);
|
|
3320
|
+
}
|
|
3321
|
+
const limit = Math.min(want === undefined ? pageSize : want - rows.length, pageSize);
|
|
3322
|
+
const page = listMemoriesPage({ ...filter, limit, offset: cursor }, db);
|
|
3323
|
+
rows.push(...page.rows);
|
|
3324
|
+
if (page.has_more === false)
|
|
3325
|
+
break;
|
|
3326
|
+
if (page.has_more === undefined && page.rows.length < limit)
|
|
3327
|
+
break;
|
|
3328
|
+
if (page.has_more === true && (page.next_cursor === null || page.next_cursor === undefined)) {
|
|
3329
|
+
throw new Error("memories list page claimed more results without a next cursor \u2014 aborting");
|
|
3330
|
+
}
|
|
3331
|
+
const next = page.next_cursor ?? cursor + page.rows.length;
|
|
3332
|
+
if (seenCursors.has(next)) {
|
|
3333
|
+
throw new Error("memories list traversal repeated a cursor \u2014 aborting");
|
|
3334
|
+
}
|
|
3335
|
+
seenCursors.add(next);
|
|
3336
|
+
cursor = next;
|
|
3337
|
+
}
|
|
3338
|
+
const hasMore = target !== undefined && rows.length > target;
|
|
3339
|
+
const trimmed = hasMore ? rows.slice(0, target) : rows;
|
|
3340
|
+
return {
|
|
3341
|
+
rows: trimmed,
|
|
3342
|
+
has_more: hasMore,
|
|
3343
|
+
next_cursor: hasMore ? (filter.offset ?? 0) + trimmed.length : null
|
|
3344
|
+
};
|
|
3345
|
+
}
|
|
3346
|
+
function countMemories(filter, db) {
|
|
3347
|
+
const d = db || getDatabase();
|
|
3348
|
+
const { conditions, params } = buildMemoryListConditions(filter);
|
|
3349
|
+
let sql = "SELECT COUNT(*) AS c FROM memories";
|
|
3350
|
+
if (conditions.length > 0) {
|
|
3351
|
+
sql += ` WHERE ${conditions.join(" AND ")}`;
|
|
3352
|
+
}
|
|
3353
|
+
const row = d.query(sql).get(...params);
|
|
3354
|
+
return row?.c ?? 0;
|
|
3228
3355
|
}
|
|
3229
3356
|
function getMemoryBriefing(opts, db) {
|
|
3230
3357
|
const limit = opts.limit ?? 20;
|
|
@@ -3286,13 +3413,17 @@ function listLowTrustMemories(opts = {}, db) {
|
|
|
3286
3413
|
const rows = d.prepare(`SELECT * FROM memories WHERE ${conditions.join(" AND ")} ORDER BY trust_score ASC LIMIT ? OFFSET ?`).all(...params);
|
|
3287
3414
|
return rows.map(parseMemoryRow);
|
|
3288
3415
|
}
|
|
3289
|
-
function
|
|
3416
|
+
function listMemoryHistoryPage(opts = {}, db) {
|
|
3290
3417
|
const limit = opts.limit ?? 20;
|
|
3291
3418
|
const offset = opts.offset ?? 0;
|
|
3292
3419
|
if (!db && isApiMode()) {
|
|
3293
3420
|
const q = toQuery({ limit, offset });
|
|
3294
3421
|
const { data } = apiJson("GET", `/memories/history${q}`);
|
|
3295
|
-
return
|
|
3422
|
+
return {
|
|
3423
|
+
rows: data?.memories ?? [],
|
|
3424
|
+
has_more: data?.has_more,
|
|
3425
|
+
next_cursor: data?.next_cursor ?? null
|
|
3426
|
+
};
|
|
3296
3427
|
}
|
|
3297
3428
|
const d = db || getDatabase();
|
|
3298
3429
|
const params = [limit];
|
|
@@ -3302,7 +3433,21 @@ function listMemoryHistory(opts = {}, db) {
|
|
|
3302
3433
|
params.push(offset);
|
|
3303
3434
|
}
|
|
3304
3435
|
const rows = d.query(sql).all(...params);
|
|
3305
|
-
|
|
3436
|
+
const parsed = rows.map(parseMemoryRow);
|
|
3437
|
+
const hasMore = parsed.length === limit;
|
|
3438
|
+
return {
|
|
3439
|
+
rows: parsed,
|
|
3440
|
+
has_more: hasMore,
|
|
3441
|
+
next_cursor: hasMore ? offset + parsed.length : null
|
|
3442
|
+
};
|
|
3443
|
+
}
|
|
3444
|
+
function listMemoryHistory(opts = {}, db) {
|
|
3445
|
+
return listMemoryHistoryPage(opts, db).rows;
|
|
3446
|
+
}
|
|
3447
|
+
function countMemoryHistory(db) {
|
|
3448
|
+
const d = db || getDatabase();
|
|
3449
|
+
const row = d.query("SELECT COUNT(*) AS c FROM memories WHERE status = 'active' AND accessed_at IS NOT NULL").get();
|
|
3450
|
+
return row?.c ?? 0;
|
|
3306
3451
|
}
|
|
3307
3452
|
function getMemoryChain(sequenceGroup, projectId, db) {
|
|
3308
3453
|
if (!db && isApiMode()) {
|
|
@@ -3399,20 +3544,29 @@ function updateMemory(id, input, db) {
|
|
|
3399
3544
|
sets.push("when_to_use = ?");
|
|
3400
3545
|
params.push(input.when_to_use ?? null);
|
|
3401
3546
|
}
|
|
3547
|
+
if (input.updated_by_agent !== undefined) {
|
|
3548
|
+
sets.push("updated_by_agent = ?");
|
|
3549
|
+
params.push(input.updated_by_agent ?? null);
|
|
3550
|
+
}
|
|
3402
3551
|
if (input.tags !== undefined) {
|
|
3403
3552
|
sets.push("tags = ?");
|
|
3404
3553
|
params.push(JSON.stringify(input.tags));
|
|
3405
|
-
d.run("DELETE FROM memory_tags WHERE memory_id = ?", [memoryId]);
|
|
3406
|
-
const insertTag = d.prepare("INSERT OR IGNORE INTO memory_tags (memory_id, tag) VALUES (?, ?)");
|
|
3407
|
-
for (const tag of input.tags) {
|
|
3408
|
-
insertTag.run(memoryId, tag);
|
|
3409
|
-
}
|
|
3410
3554
|
}
|
|
3411
3555
|
params.push(memoryId);
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3556
|
+
d.transaction(() => {
|
|
3557
|
+
const res = d.run(`UPDATE memories SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
3558
|
+
if (res.changes === 0) {
|
|
3559
|
+
throw new Error(`Update affected no rows for memory ${memoryId}: the record was read but not written. ` + `This is a bug in @hasna/mementos, not a bad argument \u2014 please report it.`);
|
|
3560
|
+
}
|
|
3561
|
+
if (input.tags !== undefined) {
|
|
3562
|
+
d.run("DELETE FROM memory_tags WHERE memory_id = ?", [memoryId]);
|
|
3563
|
+
const insertTag = d.prepare("INSERT OR IGNORE INTO memory_tags (memory_id, tag) VALUES (?, ?)");
|
|
3564
|
+
for (const tag of input.tags) {
|
|
3565
|
+
insertTag.run(memoryId, tag);
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
return res;
|
|
3569
|
+
});
|
|
3416
3570
|
const updated = getMemory(memoryId, d);
|
|
3417
3571
|
if (input.value !== undefined) {
|
|
3418
3572
|
try {
|
|
@@ -3583,7 +3737,7 @@ async function semanticSearch(queryText, options = {}, db) {
|
|
|
3583
3737
|
scored.sort((a, b) => b.score - a.score);
|
|
3584
3738
|
return scored.slice(0, limit);
|
|
3585
3739
|
}
|
|
3586
|
-
var RECALL_PROMOTE_THRESHOLD = 3;
|
|
3740
|
+
var RESERVED_AGENT_IDS, RECALL_PROMOTE_THRESHOLD = 3;
|
|
3587
3741
|
var init_memories = __esm(() => {
|
|
3588
3742
|
init_types();
|
|
3589
3743
|
init_database();
|
|
@@ -3593,6 +3747,12 @@ var init_memories = __esm(() => {
|
|
|
3593
3747
|
init_poisoning();
|
|
3594
3748
|
init_entity_memories();
|
|
3595
3749
|
init_api_mode();
|
|
3750
|
+
RESERVED_AGENT_IDS = new Set([
|
|
3751
|
+
"agent-a",
|
|
3752
|
+
"agent-x",
|
|
3753
|
+
"agent-z",
|
|
3754
|
+
"nonexistent-agent"
|
|
3755
|
+
]);
|
|
3596
3756
|
});
|
|
3597
3757
|
|
|
3598
3758
|
// src/db/entities.ts
|
|
@@ -4175,7 +4335,7 @@ function buildFilterConditions(filter) {
|
|
|
4175
4335
|
const conditions = [];
|
|
4176
4336
|
const params = [];
|
|
4177
4337
|
conditions.push("m.status = 'active'");
|
|
4178
|
-
conditions.push("(m.expires_at IS NULL OR m.expires_at >=
|
|
4338
|
+
conditions.push("(m.expires_at IS NULL OR m.expires_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))");
|
|
4179
4339
|
if (!filter)
|
|
4180
4340
|
return { conditions, params };
|
|
4181
4341
|
if (filter.scope) {
|
|
@@ -6211,7 +6371,7 @@ async function detectContradiction(newKey, newValue, options = {}, db) {
|
|
|
6211
6371
|
conditions.push("project_id = ?");
|
|
6212
6372
|
params.push(project_id);
|
|
6213
6373
|
}
|
|
6214
|
-
conditions.push("(valid_until IS NULL OR valid_until >
|
|
6374
|
+
conditions.push("(valid_until IS NULL OR valid_until > strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))");
|
|
6215
6375
|
const sql = `SELECT * FROM memories WHERE ${conditions.join(" AND ")} ORDER BY importance DESC LIMIT 10`;
|
|
6216
6376
|
const rows = d.query(sql).all(...params);
|
|
6217
6377
|
if (rows.length === 0) {
|
|
@@ -19888,7 +20048,7 @@ class JSONSchemaGenerator {
|
|
|
19888
20048
|
if (val === undefined) {
|
|
19889
20049
|
if (this.unrepresentable === "throw") {
|
|
19890
20050
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
19891
|
-
}
|
|
20051
|
+
}
|
|
19892
20052
|
} else if (typeof val === "bigint") {
|
|
19893
20053
|
if (this.unrepresentable === "throw") {
|
|
19894
20054
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -41538,7 +41698,7 @@ var require_tracestate_impl = __commonJS((exports) => {
|
|
|
41538
41698
|
const value = listMember.slice(i + 1, part.length);
|
|
41539
41699
|
if ((0, tracestate_validators_1.validateKey)(key) && (0, tracestate_validators_1.validateValue)(value)) {
|
|
41540
41700
|
agg.set(key, value);
|
|
41541
|
-
}
|
|
41701
|
+
}
|
|
41542
41702
|
}
|
|
41543
41703
|
return agg;
|
|
41544
41704
|
}, new Map);
|
|
@@ -55845,6 +56005,18 @@ function getNextPendingJob(db) {
|
|
|
55845
56005
|
return null;
|
|
55846
56006
|
return parseJobRow(row);
|
|
55847
56007
|
}
|
|
56008
|
+
function claimSessionJob(id, db) {
|
|
56009
|
+
const d = db || getDatabase();
|
|
56010
|
+
const startedAt = now();
|
|
56011
|
+
const result = d.run("UPDATE session_memory_jobs SET status = 'processing', started_at = ? WHERE id = ? AND status = 'pending'", [startedAt, id]);
|
|
56012
|
+
return result.changes;
|
|
56013
|
+
}
|
|
56014
|
+
function recoverStaleProcessingJobs(maxAgeMs, db) {
|
|
56015
|
+
const d = db || getDatabase();
|
|
56016
|
+
const cutoff = new Date(Date.now() - maxAgeMs).toISOString();
|
|
56017
|
+
const result = d.run("UPDATE session_memory_jobs SET status = 'pending', started_at = NULL WHERE status = 'processing' AND started_at < ?", [cutoff]);
|
|
56018
|
+
return result.changes;
|
|
56019
|
+
}
|
|
55848
56020
|
|
|
55849
56021
|
// src/lib/session-processor.ts
|
|
55850
56022
|
init_memories();
|
|
@@ -56347,7 +56519,11 @@ async function processSessionJob(jobId, db) {
|
|
|
56347
56519
|
return result;
|
|
56348
56520
|
}
|
|
56349
56521
|
try {
|
|
56350
|
-
|
|
56522
|
+
const changes = claimSessionJob(jobId, db);
|
|
56523
|
+
if (changes === 0) {
|
|
56524
|
+
result.errors.push(`Job already claimed or not pending: ${jobId}`);
|
|
56525
|
+
return result;
|
|
56526
|
+
}
|
|
56351
56527
|
} catch (e) {
|
|
56352
56528
|
result.errors.push(`Failed to mark job as processing: ${String(e)}`);
|
|
56353
56529
|
return result;
|
|
@@ -56455,6 +56631,9 @@ function startSessionQueueWorker() {
|
|
|
56455
56631
|
return;
|
|
56456
56632
|
_workerStarted = true;
|
|
56457
56633
|
setInterval(() => {
|
|
56634
|
+
try {
|
|
56635
|
+
recoverStaleProcessingJobs(30 * 60 * 1000);
|
|
56636
|
+
} catch {}
|
|
56458
56637
|
_processNext();
|
|
56459
56638
|
}, 5000);
|
|
56460
56639
|
}
|
|
@@ -56726,7 +56905,7 @@ function getTaskStats(db, filter) {
|
|
|
56726
56905
|
const priorityRows = db.query(`SELECT priority, COUNT(*) as c FROM tasks ${where} GROUP BY priority`).all(...params);
|
|
56727
56906
|
for (const row of priorityRows)
|
|
56728
56907
|
byPriority[row.priority] = row.c;
|
|
56729
|
-
const overdue = db.query(`SELECT COUNT(*) as c FROM tasks ${where} AND status != 'completed' AND status != 'cancelled' AND due_at IS NOT NULL AND due_at <
|
|
56908
|
+
const overdue = db.query(`SELECT COUNT(*) as c FROM tasks ${where} AND status != 'completed' AND status != 'cancelled' AND due_at IS NOT NULL AND due_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`).get(...params).c;
|
|
56730
56909
|
return {
|
|
56731
56910
|
total,
|
|
56732
56911
|
by_status: {
|
|
@@ -56857,6 +57036,255 @@ async function _tick() {
|
|
|
56857
57036
|
|
|
56858
57037
|
// src/server/index.ts
|
|
56859
57038
|
init_storage();
|
|
57039
|
+
|
|
57040
|
+
// src/db/analytics.ts
|
|
57041
|
+
init_database();
|
|
57042
|
+
init_api_mode();
|
|
57043
|
+
function getMemoryStats(db) {
|
|
57044
|
+
if (!db && isApiMode()) {
|
|
57045
|
+
const { data } = apiJson("GET", "/memories/stats");
|
|
57046
|
+
return normalizeStats(data);
|
|
57047
|
+
}
|
|
57048
|
+
const d = db || getDatabase();
|
|
57049
|
+
const total = d.query("SELECT COUNT(*) as c FROM memories WHERE status = 'active'").get().c;
|
|
57050
|
+
const byScope = d.query("SELECT scope, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY scope").all();
|
|
57051
|
+
const byCategory = d.query("SELECT category, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY category").all();
|
|
57052
|
+
const byStatus = d.query("SELECT status, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY status").all();
|
|
57053
|
+
const pinnedCount = d.query("SELECT COUNT(*) as c FROM memories WHERE pinned = 1 AND status = 'active'").get().c;
|
|
57054
|
+
const expiredCount = d.query("SELECT COUNT(*) as c FROM memories WHERE status = 'expired'").get().c;
|
|
57055
|
+
const expiresAtCount = d.query("SELECT COUNT(*) as c FROM memories WHERE expires_at IS NOT NULL").get().c;
|
|
57056
|
+
const nowIso = new Date().toISOString();
|
|
57057
|
+
const expiredDueCount = d.query("SELECT COUNT(*) as c FROM memories WHERE status = 'expired' OR (expires_at IS NOT NULL AND expires_at < ?)").get(nowIso).c;
|
|
57058
|
+
const stats = {
|
|
57059
|
+
total,
|
|
57060
|
+
by_scope: { global: 0, shared: 0, private: 0, working: 0 },
|
|
57061
|
+
by_category: { preference: 0, fact: 0, knowledge: 0, history: 0, procedural: 0, resource: 0 },
|
|
57062
|
+
by_status: { active: 0, archived: 0, expired: 0 },
|
|
57063
|
+
by_agent: {},
|
|
57064
|
+
pinned_count: pinnedCount,
|
|
57065
|
+
expired_count: expiredCount,
|
|
57066
|
+
expires_at_count: expiresAtCount,
|
|
57067
|
+
expired_due_count: expiredDueCount
|
|
57068
|
+
};
|
|
57069
|
+
for (const row of byScope)
|
|
57070
|
+
if (row.scope in stats.by_scope)
|
|
57071
|
+
stats.by_scope[row.scope] = row.c;
|
|
57072
|
+
for (const row of byCategory)
|
|
57073
|
+
if (row.category in stats.by_category)
|
|
57074
|
+
stats.by_category[row.category] = row.c;
|
|
57075
|
+
for (const row of byStatus) {
|
|
57076
|
+
if (row.status in stats.by_status) {
|
|
57077
|
+
stats.by_status[row.status] = row.c;
|
|
57078
|
+
}
|
|
57079
|
+
}
|
|
57080
|
+
const byAgent = d.query("SELECT agent_id, COUNT(*) as c FROM memories WHERE status = 'active' AND agent_id IS NOT NULL GROUP BY agent_id").all();
|
|
57081
|
+
for (const row of byAgent)
|
|
57082
|
+
stats.by_agent[row.agent_id] = row.c;
|
|
57083
|
+
return stats;
|
|
57084
|
+
}
|
|
57085
|
+
function normalizeStats(data) {
|
|
57086
|
+
return {
|
|
57087
|
+
total: data?.total ?? 0,
|
|
57088
|
+
by_scope: { global: 0, shared: 0, private: 0, working: 0, ...data?.by_scope ?? {} },
|
|
57089
|
+
by_category: {
|
|
57090
|
+
preference: 0,
|
|
57091
|
+
fact: 0,
|
|
57092
|
+
knowledge: 0,
|
|
57093
|
+
history: 0,
|
|
57094
|
+
procedural: 0,
|
|
57095
|
+
resource: 0,
|
|
57096
|
+
...data?.by_category ?? {}
|
|
57097
|
+
},
|
|
57098
|
+
by_status: { active: 0, archived: 0, expired: 0, ...data?.by_status ?? {} },
|
|
57099
|
+
by_agent: data?.by_agent ?? {},
|
|
57100
|
+
pinned_count: data?.pinned_count ?? 0,
|
|
57101
|
+
expired_count: data?.expired_count ?? 0,
|
|
57102
|
+
expires_at_count: data?.expires_at_count ?? 0,
|
|
57103
|
+
expired_due_count: data?.expired_due_count ?? 0
|
|
57104
|
+
};
|
|
57105
|
+
}
|
|
57106
|
+
function getMemoryActivity(filter = {}, db) {
|
|
57107
|
+
const days = Math.min(filter.days || 30, 365);
|
|
57108
|
+
if (!db && isApiMode()) {
|
|
57109
|
+
const q = toQuery({ days, scope: filter.scope, agent_id: filter.agent_id, project_id: filter.project_id });
|
|
57110
|
+
const { data } = apiJson("GET", `/activity${q}`);
|
|
57111
|
+
return { activity: data?.activity ?? [], days: data?.days ?? days, total: data?.total ?? 0 };
|
|
57112
|
+
}
|
|
57113
|
+
const d = db || getDatabase();
|
|
57114
|
+
const conditions = ["status = 'active'"];
|
|
57115
|
+
const params = [];
|
|
57116
|
+
if (filter.scope) {
|
|
57117
|
+
conditions.push("scope = ?");
|
|
57118
|
+
params.push(filter.scope);
|
|
57119
|
+
}
|
|
57120
|
+
if (filter.agent_id) {
|
|
57121
|
+
conditions.push("agent_id = ?");
|
|
57122
|
+
params.push(filter.agent_id);
|
|
57123
|
+
}
|
|
57124
|
+
if (filter.project_id) {
|
|
57125
|
+
conditions.push("project_id = ?");
|
|
57126
|
+
params.push(filter.project_id);
|
|
57127
|
+
}
|
|
57128
|
+
const where = conditions.map((c) => `AND ${c}`).join(" ");
|
|
57129
|
+
const cutoffDate = new Date(Date.now() - days * 86400000).toISOString().slice(0, 10);
|
|
57130
|
+
params.push(cutoffDate);
|
|
57131
|
+
const rows = d.query(`
|
|
57132
|
+
SELECT
|
|
57133
|
+
date(created_at) AS date,
|
|
57134
|
+
COUNT(*) AS memories_created,
|
|
57135
|
+
SUM(CASE WHEN scope = 'global' THEN 1 ELSE 0 END) AS global_count,
|
|
57136
|
+
SUM(CASE WHEN scope = 'shared' THEN 1 ELSE 0 END) AS shared_count,
|
|
57137
|
+
SUM(CASE WHEN scope = 'private' THEN 1 ELSE 0 END) AS private_count,
|
|
57138
|
+
AVG(importance) AS avg_importance
|
|
57139
|
+
FROM memories
|
|
57140
|
+
WHERE date(created_at) >= ? ${where}
|
|
57141
|
+
GROUP BY date(created_at)
|
|
57142
|
+
ORDER BY date ASC
|
|
57143
|
+
`).all(...params);
|
|
57144
|
+
return { activity: rows, days, total: rows.reduce((s, r) => s + r.memories_created, 0) };
|
|
57145
|
+
}
|
|
57146
|
+
function getMemoryReport(filter = {}, db) {
|
|
57147
|
+
const days = Math.min(filter.days || 7, 365);
|
|
57148
|
+
if (!db && isApiMode()) {
|
|
57149
|
+
const q = toQuery({ days, project_id: filter.project_id, agent_id: filter.agent_id });
|
|
57150
|
+
const { data } = apiJson("GET", `/report${q}`);
|
|
57151
|
+
return {
|
|
57152
|
+
total: data?.total ?? 0,
|
|
57153
|
+
pinned: data?.pinned ?? 0,
|
|
57154
|
+
days: data?.days ?? days,
|
|
57155
|
+
recent: data?.recent ?? { total: 0, activity: [] },
|
|
57156
|
+
by_scope: data?.by_scope ?? {},
|
|
57157
|
+
by_category: data?.by_category ?? {},
|
|
57158
|
+
top_memories: data?.top_memories ?? [],
|
|
57159
|
+
top_agents: data?.top_agents ?? []
|
|
57160
|
+
};
|
|
57161
|
+
}
|
|
57162
|
+
const d = db || getDatabase();
|
|
57163
|
+
const cutoffDate = new Date(Date.now() - days * 86400000).toISOString().slice(0, 10);
|
|
57164
|
+
const scopedCond = [
|
|
57165
|
+
filter.project_id ? "AND project_id = ?" : "",
|
|
57166
|
+
filter.agent_id ? "AND agent_id = ?" : ""
|
|
57167
|
+
].filter(Boolean).join(" ");
|
|
57168
|
+
const scopedParams = [
|
|
57169
|
+
...filter.project_id ? [filter.project_id] : [],
|
|
57170
|
+
...filter.agent_id ? [filter.agent_id] : []
|
|
57171
|
+
];
|
|
57172
|
+
const recentParams = [cutoffDate, ...scopedParams];
|
|
57173
|
+
const total = d.query(`SELECT COUNT(*) as c FROM memories WHERE status = 'active' ${scopedCond}`).get(...scopedParams).c;
|
|
57174
|
+
const pinned = d.query(`SELECT COUNT(*) as c FROM memories WHERE status = 'active' AND pinned = 1 ${scopedCond}`).get(...scopedParams).c;
|
|
57175
|
+
const actRows = d.query(`
|
|
57176
|
+
SELECT date(created_at) AS date, COUNT(*) AS memories_created
|
|
57177
|
+
FROM memories WHERE status = 'active' AND date(created_at) >= ? ${scopedCond}
|
|
57178
|
+
GROUP BY date(created_at) ORDER BY date(created_at) ASC
|
|
57179
|
+
`).all(...recentParams);
|
|
57180
|
+
const recentTotal = actRows.reduce((s, r) => s + r.memories_created, 0);
|
|
57181
|
+
const byScopeRows = d.query(`SELECT scope, COUNT(*) as c FROM memories WHERE status = 'active' ${scopedCond} GROUP BY scope`).all(...scopedParams);
|
|
57182
|
+
const byCatRows = d.query(`SELECT category, COUNT(*) as c FROM memories WHERE status = 'active' ${scopedCond} GROUP BY category`).all(...scopedParams);
|
|
57183
|
+
const topMems = d.query(`SELECT id, key, value, importance, scope, category FROM memories WHERE status = 'active' ${scopedCond} ORDER BY importance DESC, access_count DESC LIMIT 5`).all(...scopedParams);
|
|
57184
|
+
const topAgents = d.query(`SELECT agent_id, COUNT(*) as c FROM memories WHERE status = 'active' AND agent_id IS NOT NULL ${scopedCond} GROUP BY agent_id ORDER BY c DESC LIMIT 5`).all(...scopedParams);
|
|
57185
|
+
return {
|
|
57186
|
+
total,
|
|
57187
|
+
pinned,
|
|
57188
|
+
days,
|
|
57189
|
+
recent: { total: recentTotal, activity: actRows },
|
|
57190
|
+
by_scope: Object.fromEntries(byScopeRows.map((r) => [r.scope, r.c])),
|
|
57191
|
+
by_category: Object.fromEntries(byCatRows.map((r) => [r.category, r.c])),
|
|
57192
|
+
top_memories: topMems,
|
|
57193
|
+
top_agents: topAgents
|
|
57194
|
+
};
|
|
57195
|
+
}
|
|
57196
|
+
function getStaleMemoriesPage(filter = {}, db) {
|
|
57197
|
+
const days = Math.min(filter.days || 30, 365);
|
|
57198
|
+
const limit = filter.limit ?? 20;
|
|
57199
|
+
const offset = filter.offset ?? 0;
|
|
57200
|
+
if (!db && isApiMode()) {
|
|
57201
|
+
const q = toQuery({ days, project_id: filter.project_id, agent_id: filter.agent_id, pinned: filter.pinned, limit, offset });
|
|
57202
|
+
const { data } = apiJson("GET", `/memories/stale${q}`);
|
|
57203
|
+
const rows2 = data?.memories ?? [];
|
|
57204
|
+
return {
|
|
57205
|
+
rows: rows2,
|
|
57206
|
+
total: data?.total ?? rows2.length,
|
|
57207
|
+
has_more: data?.has_more,
|
|
57208
|
+
next_cursor: data?.next_cursor ?? null
|
|
57209
|
+
};
|
|
57210
|
+
}
|
|
57211
|
+
const d = db || getDatabase();
|
|
57212
|
+
const cutoffDate = new Date(Date.now() - days * 86400000).toISOString();
|
|
57213
|
+
const conds = ["status = 'active'", "(accessed_at IS NULL OR accessed_at < ?)"];
|
|
57214
|
+
const params = [cutoffDate];
|
|
57215
|
+
if (filter.pinned !== undefined) {
|
|
57216
|
+
conds.push("pinned = ?");
|
|
57217
|
+
params.push(filter.pinned ? 1 : 0);
|
|
57218
|
+
} else {
|
|
57219
|
+
conds.push("pinned = 0");
|
|
57220
|
+
}
|
|
57221
|
+
if (filter.project_id) {
|
|
57222
|
+
conds.push("project_id = ?");
|
|
57223
|
+
params.push(filter.project_id);
|
|
57224
|
+
}
|
|
57225
|
+
if (filter.agent_id) {
|
|
57226
|
+
conds.push("agent_id = ?");
|
|
57227
|
+
params.push(filter.agent_id);
|
|
57228
|
+
}
|
|
57229
|
+
const where = conds.join(" AND ");
|
|
57230
|
+
const countRow = d.query(`SELECT COUNT(*) AS c FROM memories WHERE ${where}`).get(...params);
|
|
57231
|
+
let sql = `SELECT id, key, value, importance, scope, category, accessed_at, access_count, created_at FROM memories WHERE ${where} ORDER BY COALESCE(accessed_at, created_at) ASC LIMIT ?`;
|
|
57232
|
+
params.push(limit);
|
|
57233
|
+
if (offset) {
|
|
57234
|
+
sql += " OFFSET ?";
|
|
57235
|
+
params.push(offset);
|
|
57236
|
+
}
|
|
57237
|
+
const rows = d.query(sql).all(...params);
|
|
57238
|
+
const hasMore = rows.length === limit;
|
|
57239
|
+
return {
|
|
57240
|
+
rows,
|
|
57241
|
+
total: countRow?.c ?? 0,
|
|
57242
|
+
has_more: hasMore,
|
|
57243
|
+
next_cursor: hasMore ? offset + rows.length : null
|
|
57244
|
+
};
|
|
57245
|
+
}
|
|
57246
|
+
function getMemoryHealth(filter = {}, db) {
|
|
57247
|
+
const staleDays = filter.stale_days ?? 30;
|
|
57248
|
+
const forgottenDays = filter.forgotten_days ?? 60;
|
|
57249
|
+
const limit = filter.limit ?? 10;
|
|
57250
|
+
if (!db && isApiMode()) {
|
|
57251
|
+
const q = toQuery({
|
|
57252
|
+
stale_days: staleDays,
|
|
57253
|
+
forgotten_days: forgottenDays,
|
|
57254
|
+
project_id: filter.project_id,
|
|
57255
|
+
agent_id: filter.agent_id,
|
|
57256
|
+
limit
|
|
57257
|
+
});
|
|
57258
|
+
const { data } = apiJson("GET", `/memories/health${q}`);
|
|
57259
|
+
return { stale: data?.stale ?? [], forgotten: data?.forgotten ?? [], dupes: data?.dupes ?? [] };
|
|
57260
|
+
}
|
|
57261
|
+
const d = db || getDatabase();
|
|
57262
|
+
const extraWhere = [
|
|
57263
|
+
...filter.project_id ? ["project_id = ?"] : [],
|
|
57264
|
+
...filter.agent_id ? ["agent_id = ?"] : []
|
|
57265
|
+
].join(" AND ");
|
|
57266
|
+
const scopeParams = [
|
|
57267
|
+
...filter.project_id ? [filter.project_id] : [],
|
|
57268
|
+
...filter.agent_id ? [filter.agent_id] : []
|
|
57269
|
+
];
|
|
57270
|
+
const staleCutoff = new Date(Date.now() - staleDays * 86400000).toISOString();
|
|
57271
|
+
const forgottenCutoff = new Date(Date.now() - forgottenDays * 86400000).toISOString();
|
|
57272
|
+
const base = `status = 'active' AND pinned = 0${extraWhere ? " AND " + extraWhere : ""}`;
|
|
57273
|
+
const stale = d.prepare(`SELECT id, key, value, importance, scope, created_at FROM memories
|
|
57274
|
+
WHERE ${base} AND access_count = 0 AND created_at < ?
|
|
57275
|
+
ORDER BY created_at ASC LIMIT ?`).all(...scopeParams, staleCutoff, limit);
|
|
57276
|
+
const forgotten = d.prepare(`SELECT id, key, value, importance, scope, accessed_at FROM memories
|
|
57277
|
+
WHERE ${base} AND importance >= 7
|
|
57278
|
+
AND (accessed_at IS NULL OR accessed_at < ?)
|
|
57279
|
+
ORDER BY importance DESC, COALESCE(accessed_at, created_at) ASC LIMIT ?`).all(...scopeParams, forgottenCutoff, limit);
|
|
57280
|
+
const dupes = d.prepare(`SELECT key, COUNT(*) as cnt, MAX(updated_at) as latest, MIN(created_at) as oldest
|
|
57281
|
+
FROM memories WHERE ${base}
|
|
57282
|
+
GROUP BY key HAVING COUNT(*) > 1
|
|
57283
|
+
ORDER BY cnt DESC LIMIT ?`).all(...scopeParams, limit);
|
|
57284
|
+
return { stale, forgotten, dupes };
|
|
57285
|
+
}
|
|
57286
|
+
|
|
57287
|
+
// src/server/index.ts
|
|
56860
57288
|
init_router();
|
|
56861
57289
|
|
|
56862
57290
|
// src/server/helpers.ts
|
|
@@ -57102,6 +57530,7 @@ var FORMAT_UNITS = [
|
|
|
57102
57530
|
|
|
57103
57531
|
// src/server/routes/memories-crud.ts
|
|
57104
57532
|
init_router();
|
|
57533
|
+
init_database();
|
|
57105
57534
|
init_enum_validation();
|
|
57106
57535
|
init_types();
|
|
57107
57536
|
addRoute("GET", "/api/memories", (_req, url) => {
|
|
@@ -57127,21 +57556,49 @@ addRoute("GET", "/api/memories", (_req, url) => {
|
|
|
57127
57556
|
filter.project_id = q["project_id"];
|
|
57128
57557
|
if (q["session_id"])
|
|
57129
57558
|
filter.session_id = q["session_id"];
|
|
57559
|
+
if (q["machine_id"])
|
|
57560
|
+
filter.machine_id = q["machine_id"];
|
|
57561
|
+
if (q["visible_to_machine_id"])
|
|
57562
|
+
filter.visible_to_machine_id = q["visible_to_machine_id"];
|
|
57563
|
+
if (q["search"])
|
|
57564
|
+
filter.search = q["search"];
|
|
57565
|
+
if (q["source"])
|
|
57566
|
+
filter.source = q["source"].includes(",") ? q["source"].split(",") : q["source"];
|
|
57567
|
+
if (q["flag"])
|
|
57568
|
+
filter.flag = q["flag"];
|
|
57130
57569
|
if (q["namespace"])
|
|
57131
57570
|
filter.namespace = q["namespace"];
|
|
57132
57571
|
if (q["status"])
|
|
57133
57572
|
filter.status = q["status"];
|
|
57134
|
-
|
|
57135
|
-
|
|
57136
|
-
|
|
57137
|
-
|
|
57573
|
+
const parsedLimit = Number(q["limit"]);
|
|
57574
|
+
const limit = Number.isInteger(parsedLimit) && parsedLimit > 0 ? Math.min(parsedLimit, 1000) : 1000;
|
|
57575
|
+
const parsedOffset = Number(q["offset"]);
|
|
57576
|
+
filter.limit = limit;
|
|
57577
|
+
filter.offset = Number.isInteger(parsedOffset) && parsedOffset >= 0 ? parsedOffset : 0;
|
|
57138
57578
|
const memories = listMemories(filter);
|
|
57579
|
+
const total = countMemories(filter, getDatabase());
|
|
57580
|
+
const hasMore = memories.length === limit;
|
|
57581
|
+
const nextCursor = hasMore ? (filter.offset ?? 0) + memories.length : null;
|
|
57139
57582
|
if (q["fields"]) {
|
|
57140
57583
|
const fields = q["fields"].split(",").map((f) => f.trim());
|
|
57141
57584
|
const filtered = memories.map((m) => Object.fromEntries(fields.map((f) => [f, m[f]]).filter(([, v]) => v !== undefined)));
|
|
57142
|
-
return json({
|
|
57585
|
+
return json({
|
|
57586
|
+
memories: filtered,
|
|
57587
|
+
count: filtered.length,
|
|
57588
|
+
total,
|
|
57589
|
+
limit,
|
|
57590
|
+
has_more: hasMore,
|
|
57591
|
+
next_cursor: nextCursor
|
|
57592
|
+
});
|
|
57143
57593
|
}
|
|
57144
|
-
return json({
|
|
57594
|
+
return json({
|
|
57595
|
+
memories,
|
|
57596
|
+
count: memories.length,
|
|
57597
|
+
total,
|
|
57598
|
+
limit,
|
|
57599
|
+
has_more: hasMore,
|
|
57600
|
+
next_cursor: nextCursor
|
|
57601
|
+
});
|
|
57145
57602
|
});
|
|
57146
57603
|
addRoute("POST", "/api/memories", async (req) => {
|
|
57147
57604
|
const body = await readJson(req);
|
|
@@ -57239,227 +57696,6 @@ addRoute("DELETE", "/api/memories/:id", (_req, _url, params) => {
|
|
|
57239
57696
|
|
|
57240
57697
|
// src/server/routes/memories-stats.ts
|
|
57241
57698
|
init_database();
|
|
57242
|
-
|
|
57243
|
-
// src/db/analytics.ts
|
|
57244
|
-
init_database();
|
|
57245
|
-
init_api_mode();
|
|
57246
|
-
function getMemoryStats(db) {
|
|
57247
|
-
if (!db && isApiMode()) {
|
|
57248
|
-
const { data } = apiJson("GET", "/memories/stats");
|
|
57249
|
-
return normalizeStats(data);
|
|
57250
|
-
}
|
|
57251
|
-
const d = db || getDatabase();
|
|
57252
|
-
const total = d.query("SELECT COUNT(*) as c FROM memories WHERE status = 'active'").get().c;
|
|
57253
|
-
const byScope = d.query("SELECT scope, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY scope").all();
|
|
57254
|
-
const byCategory = d.query("SELECT category, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY category").all();
|
|
57255
|
-
const byStatus = d.query("SELECT status, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY status").all();
|
|
57256
|
-
const pinnedCount = d.query("SELECT COUNT(*) as c FROM memories WHERE pinned = 1 AND status = 'active'").get().c;
|
|
57257
|
-
const expiredCount = d.query("SELECT COUNT(*) as c FROM memories WHERE status = 'expired' OR (expires_at IS NOT NULL AND expires_at < datetime('now'))").get().c;
|
|
57258
|
-
const stats = {
|
|
57259
|
-
total,
|
|
57260
|
-
by_scope: { global: 0, shared: 0, private: 0, working: 0 },
|
|
57261
|
-
by_category: { preference: 0, fact: 0, knowledge: 0, history: 0, procedural: 0, resource: 0 },
|
|
57262
|
-
by_status: { active: 0, archived: 0, expired: 0 },
|
|
57263
|
-
by_agent: {},
|
|
57264
|
-
pinned_count: pinnedCount,
|
|
57265
|
-
expired_count: expiredCount
|
|
57266
|
-
};
|
|
57267
|
-
for (const row of byScope)
|
|
57268
|
-
if (row.scope in stats.by_scope)
|
|
57269
|
-
stats.by_scope[row.scope] = row.c;
|
|
57270
|
-
for (const row of byCategory)
|
|
57271
|
-
if (row.category in stats.by_category)
|
|
57272
|
-
stats.by_category[row.category] = row.c;
|
|
57273
|
-
for (const row of byStatus) {
|
|
57274
|
-
if (row.status in stats.by_status) {
|
|
57275
|
-
stats.by_status[row.status] = row.c;
|
|
57276
|
-
}
|
|
57277
|
-
}
|
|
57278
|
-
const byAgent = d.query("SELECT agent_id, COUNT(*) as c FROM memories WHERE status = 'active' AND agent_id IS NOT NULL GROUP BY agent_id").all();
|
|
57279
|
-
for (const row of byAgent)
|
|
57280
|
-
stats.by_agent[row.agent_id] = row.c;
|
|
57281
|
-
return stats;
|
|
57282
|
-
}
|
|
57283
|
-
function normalizeStats(data) {
|
|
57284
|
-
return {
|
|
57285
|
-
total: data?.total ?? 0,
|
|
57286
|
-
by_scope: { global: 0, shared: 0, private: 0, working: 0, ...data?.by_scope ?? {} },
|
|
57287
|
-
by_category: {
|
|
57288
|
-
preference: 0,
|
|
57289
|
-
fact: 0,
|
|
57290
|
-
knowledge: 0,
|
|
57291
|
-
history: 0,
|
|
57292
|
-
procedural: 0,
|
|
57293
|
-
resource: 0,
|
|
57294
|
-
...data?.by_category ?? {}
|
|
57295
|
-
},
|
|
57296
|
-
by_status: { active: 0, archived: 0, expired: 0, ...data?.by_status ?? {} },
|
|
57297
|
-
by_agent: data?.by_agent ?? {},
|
|
57298
|
-
pinned_count: data?.pinned_count ?? 0,
|
|
57299
|
-
expired_count: data?.expired_count ?? 0
|
|
57300
|
-
};
|
|
57301
|
-
}
|
|
57302
|
-
function getMemoryActivity(filter = {}, db) {
|
|
57303
|
-
const days = Math.min(filter.days || 30, 365);
|
|
57304
|
-
if (!db && isApiMode()) {
|
|
57305
|
-
const q = toQuery({ days, scope: filter.scope, agent_id: filter.agent_id, project_id: filter.project_id });
|
|
57306
|
-
const { data } = apiJson("GET", `/activity${q}`);
|
|
57307
|
-
return { activity: data?.activity ?? [], days: data?.days ?? days, total: data?.total ?? 0 };
|
|
57308
|
-
}
|
|
57309
|
-
const d = db || getDatabase();
|
|
57310
|
-
const conditions = ["status = 'active'"];
|
|
57311
|
-
const params = [];
|
|
57312
|
-
if (filter.scope) {
|
|
57313
|
-
conditions.push("scope = ?");
|
|
57314
|
-
params.push(filter.scope);
|
|
57315
|
-
}
|
|
57316
|
-
if (filter.agent_id) {
|
|
57317
|
-
conditions.push("agent_id = ?");
|
|
57318
|
-
params.push(filter.agent_id);
|
|
57319
|
-
}
|
|
57320
|
-
if (filter.project_id) {
|
|
57321
|
-
conditions.push("project_id = ?");
|
|
57322
|
-
params.push(filter.project_id);
|
|
57323
|
-
}
|
|
57324
|
-
const where = conditions.map((c) => `AND ${c}`).join(" ");
|
|
57325
|
-
const cutoffDate = new Date(Date.now() - days * 86400000).toISOString().slice(0, 10);
|
|
57326
|
-
params.push(cutoffDate);
|
|
57327
|
-
const rows = d.query(`
|
|
57328
|
-
SELECT
|
|
57329
|
-
date(created_at) AS date,
|
|
57330
|
-
COUNT(*) AS memories_created,
|
|
57331
|
-
SUM(CASE WHEN scope = 'global' THEN 1 ELSE 0 END) AS global_count,
|
|
57332
|
-
SUM(CASE WHEN scope = 'shared' THEN 1 ELSE 0 END) AS shared_count,
|
|
57333
|
-
SUM(CASE WHEN scope = 'private' THEN 1 ELSE 0 END) AS private_count,
|
|
57334
|
-
AVG(importance) AS avg_importance
|
|
57335
|
-
FROM memories
|
|
57336
|
-
WHERE date(created_at) >= ? ${where}
|
|
57337
|
-
GROUP BY date(created_at)
|
|
57338
|
-
ORDER BY date ASC
|
|
57339
|
-
`).all(...params);
|
|
57340
|
-
return { activity: rows, days, total: rows.reduce((s, r) => s + r.memories_created, 0) };
|
|
57341
|
-
}
|
|
57342
|
-
function getMemoryReport(filter = {}, db) {
|
|
57343
|
-
const days = Math.min(filter.days || 7, 365);
|
|
57344
|
-
if (!db && isApiMode()) {
|
|
57345
|
-
const q = toQuery({ days, project_id: filter.project_id, agent_id: filter.agent_id });
|
|
57346
|
-
const { data } = apiJson("GET", `/report${q}`);
|
|
57347
|
-
return {
|
|
57348
|
-
total: data?.total ?? 0,
|
|
57349
|
-
pinned: data?.pinned ?? 0,
|
|
57350
|
-
days: data?.days ?? days,
|
|
57351
|
-
recent: data?.recent ?? { total: 0, activity: [] },
|
|
57352
|
-
by_scope: data?.by_scope ?? {},
|
|
57353
|
-
by_category: data?.by_category ?? {},
|
|
57354
|
-
top_memories: data?.top_memories ?? [],
|
|
57355
|
-
top_agents: data?.top_agents ?? []
|
|
57356
|
-
};
|
|
57357
|
-
}
|
|
57358
|
-
const d = db || getDatabase();
|
|
57359
|
-
const cutoffDate = new Date(Date.now() - days * 86400000).toISOString().slice(0, 10);
|
|
57360
|
-
const scopedCond = [
|
|
57361
|
-
filter.project_id ? "AND project_id = ?" : "",
|
|
57362
|
-
filter.agent_id ? "AND agent_id = ?" : ""
|
|
57363
|
-
].filter(Boolean).join(" ");
|
|
57364
|
-
const scopedParams = [
|
|
57365
|
-
...filter.project_id ? [filter.project_id] : [],
|
|
57366
|
-
...filter.agent_id ? [filter.agent_id] : []
|
|
57367
|
-
];
|
|
57368
|
-
const recentParams = [cutoffDate, ...scopedParams];
|
|
57369
|
-
const total = d.query(`SELECT COUNT(*) as c FROM memories WHERE status = 'active' ${scopedCond}`).get(...scopedParams).c;
|
|
57370
|
-
const pinned = d.query(`SELECT COUNT(*) as c FROM memories WHERE status = 'active' AND pinned = 1 ${scopedCond}`).get(...scopedParams).c;
|
|
57371
|
-
const actRows = d.query(`
|
|
57372
|
-
SELECT date(created_at) AS date, COUNT(*) AS memories_created
|
|
57373
|
-
FROM memories WHERE status = 'active' AND date(created_at) >= ? ${scopedCond}
|
|
57374
|
-
GROUP BY date(created_at) ORDER BY date(created_at) ASC
|
|
57375
|
-
`).all(...recentParams);
|
|
57376
|
-
const recentTotal = actRows.reduce((s, r) => s + r.memories_created, 0);
|
|
57377
|
-
const byScopeRows = d.query(`SELECT scope, COUNT(*) as c FROM memories WHERE status = 'active' ${scopedCond} GROUP BY scope`).all(...scopedParams);
|
|
57378
|
-
const byCatRows = d.query(`SELECT category, COUNT(*) as c FROM memories WHERE status = 'active' ${scopedCond} GROUP BY category`).all(...scopedParams);
|
|
57379
|
-
const topMems = d.query(`SELECT id, key, value, importance, scope, category FROM memories WHERE status = 'active' ${scopedCond} ORDER BY importance DESC, access_count DESC LIMIT 5`).all(...scopedParams);
|
|
57380
|
-
const topAgents = d.query(`SELECT agent_id, COUNT(*) as c FROM memories WHERE status = 'active' AND agent_id IS NOT NULL ${scopedCond} GROUP BY agent_id ORDER BY c DESC LIMIT 5`).all(...scopedParams);
|
|
57381
|
-
return {
|
|
57382
|
-
total,
|
|
57383
|
-
pinned,
|
|
57384
|
-
days,
|
|
57385
|
-
recent: { total: recentTotal, activity: actRows },
|
|
57386
|
-
by_scope: Object.fromEntries(byScopeRows.map((r) => [r.scope, r.c])),
|
|
57387
|
-
by_category: Object.fromEntries(byCatRows.map((r) => [r.category, r.c])),
|
|
57388
|
-
top_memories: topMems,
|
|
57389
|
-
top_agents: topAgents
|
|
57390
|
-
};
|
|
57391
|
-
}
|
|
57392
|
-
function getStaleMemories(filter = {}, db) {
|
|
57393
|
-
const days = Math.min(filter.days || 30, 365);
|
|
57394
|
-
const limit = filter.limit ?? 20;
|
|
57395
|
-
const offset = filter.offset ?? 0;
|
|
57396
|
-
if (!db && isApiMode()) {
|
|
57397
|
-
const q = toQuery({ days, project_id: filter.project_id, agent_id: filter.agent_id, limit, offset });
|
|
57398
|
-
const { data } = apiJson("GET", `/memories/stale${q}`);
|
|
57399
|
-
return data?.memories ?? [];
|
|
57400
|
-
}
|
|
57401
|
-
const d = db || getDatabase();
|
|
57402
|
-
const cutoffDate = new Date(Date.now() - days * 86400000).toISOString();
|
|
57403
|
-
const conds = ["status = 'active'", "(accessed_at IS NULL OR accessed_at < ?)", "pinned = 0"];
|
|
57404
|
-
const params = [cutoffDate];
|
|
57405
|
-
if (filter.project_id) {
|
|
57406
|
-
conds.push("project_id = ?");
|
|
57407
|
-
params.push(filter.project_id);
|
|
57408
|
-
}
|
|
57409
|
-
if (filter.agent_id) {
|
|
57410
|
-
conds.push("agent_id = ?");
|
|
57411
|
-
params.push(filter.agent_id);
|
|
57412
|
-
}
|
|
57413
|
-
let sql = `SELECT id, key, value, importance, scope, category, accessed_at, access_count, created_at FROM memories WHERE ${conds.join(" AND ")} ORDER BY COALESCE(accessed_at, created_at) ASC LIMIT ?`;
|
|
57414
|
-
params.push(limit);
|
|
57415
|
-
if (offset) {
|
|
57416
|
-
sql += " OFFSET ?";
|
|
57417
|
-
params.push(offset);
|
|
57418
|
-
}
|
|
57419
|
-
return d.query(sql).all(...params);
|
|
57420
|
-
}
|
|
57421
|
-
function getMemoryHealth(filter = {}, db) {
|
|
57422
|
-
const staleDays = filter.stale_days ?? 30;
|
|
57423
|
-
const forgottenDays = filter.forgotten_days ?? 60;
|
|
57424
|
-
const limit = filter.limit ?? 10;
|
|
57425
|
-
if (!db && isApiMode()) {
|
|
57426
|
-
const q = toQuery({
|
|
57427
|
-
stale_days: staleDays,
|
|
57428
|
-
forgotten_days: forgottenDays,
|
|
57429
|
-
project_id: filter.project_id,
|
|
57430
|
-
agent_id: filter.agent_id,
|
|
57431
|
-
limit
|
|
57432
|
-
});
|
|
57433
|
-
const { data } = apiJson("GET", `/memories/health${q}`);
|
|
57434
|
-
return { stale: data?.stale ?? [], forgotten: data?.forgotten ?? [], dupes: data?.dupes ?? [] };
|
|
57435
|
-
}
|
|
57436
|
-
const d = db || getDatabase();
|
|
57437
|
-
const extraWhere = [
|
|
57438
|
-
...filter.project_id ? ["project_id = ?"] : [],
|
|
57439
|
-
...filter.agent_id ? ["agent_id = ?"] : []
|
|
57440
|
-
].join(" AND ");
|
|
57441
|
-
const scopeParams = [
|
|
57442
|
-
...filter.project_id ? [filter.project_id] : [],
|
|
57443
|
-
...filter.agent_id ? [filter.agent_id] : []
|
|
57444
|
-
];
|
|
57445
|
-
const staleCutoff = new Date(Date.now() - staleDays * 86400000).toISOString();
|
|
57446
|
-
const forgottenCutoff = new Date(Date.now() - forgottenDays * 86400000).toISOString();
|
|
57447
|
-
const base = `status = 'active' AND pinned = 0${extraWhere ? " AND " + extraWhere : ""}`;
|
|
57448
|
-
const stale = d.prepare(`SELECT id, key, value, importance, scope, created_at FROM memories
|
|
57449
|
-
WHERE ${base} AND access_count = 0 AND created_at < ?
|
|
57450
|
-
ORDER BY created_at ASC LIMIT ?`).all(...scopeParams, staleCutoff, limit);
|
|
57451
|
-
const forgotten = d.prepare(`SELECT id, key, value, importance, scope, accessed_at FROM memories
|
|
57452
|
-
WHERE ${base} AND importance >= 7
|
|
57453
|
-
AND (accessed_at IS NULL OR accessed_at < ?)
|
|
57454
|
-
ORDER BY importance DESC, COALESCE(accessed_at, created_at) ASC LIMIT ?`).all(...scopeParams, forgottenCutoff, limit);
|
|
57455
|
-
const dupes = d.prepare(`SELECT key, COUNT(*) as cnt, MAX(updated_at) as latest, MIN(created_at) as oldest
|
|
57456
|
-
FROM memories WHERE ${base}
|
|
57457
|
-
GROUP BY key HAVING COUNT(*) > 1
|
|
57458
|
-
ORDER BY cnt DESC LIMIT ?`).all(...scopeParams, limit);
|
|
57459
|
-
return { stale, forgotten, dupes };
|
|
57460
|
-
}
|
|
57461
|
-
|
|
57462
|
-
// src/server/routes/memories-stats.ts
|
|
57463
57699
|
init_memories();
|
|
57464
57700
|
init_router();
|
|
57465
57701
|
addRoute("GET", "/api/memories/stats", () => {
|
|
@@ -57499,23 +57735,45 @@ addRoute("GET", "/api/activity", (_req, url) => {
|
|
|
57499
57735
|
addRoute("GET", "/api/memories/stale", (_req, url) => {
|
|
57500
57736
|
const q = getSearchParams(url);
|
|
57501
57737
|
const days = q["days"] ? parseInt(q["days"], 10) : undefined;
|
|
57502
|
-
const
|
|
57503
|
-
const
|
|
57738
|
+
const parsedLimit = Number(q["limit"]);
|
|
57739
|
+
const limit = Number.isInteger(parsedLimit) && parsedLimit > 0 ? Math.min(parsedLimit, 1000) : 20;
|
|
57740
|
+
const parsedOffset = Number(q["offset"]);
|
|
57741
|
+
const offset = Number.isInteger(parsedOffset) && parsedOffset >= 0 ? parsedOffset : 0;
|
|
57742
|
+
const pinned = q["pinned"] === "1" || q["pinned"] === "true" ? true : q["pinned"] === "0" || q["pinned"] === "false" ? false : undefined;
|
|
57743
|
+
const page = getStaleMemoriesPage({
|
|
57504
57744
|
days,
|
|
57745
|
+
pinned,
|
|
57505
57746
|
project_id: q["project_id"],
|
|
57506
57747
|
agent_id: q["agent_id"],
|
|
57507
57748
|
limit,
|
|
57508
|
-
offset
|
|
57749
|
+
offset
|
|
57509
57750
|
}, getDatabase());
|
|
57510
|
-
return json({
|
|
57751
|
+
return json({
|
|
57752
|
+
memories: page.rows,
|
|
57753
|
+
count: page.rows.length,
|
|
57754
|
+
total: page.total,
|
|
57755
|
+
days: Math.min(days || 30, 365),
|
|
57756
|
+
limit,
|
|
57757
|
+
has_more: page.has_more,
|
|
57758
|
+
next_cursor: page.next_cursor
|
|
57759
|
+
});
|
|
57511
57760
|
});
|
|
57512
57761
|
addRoute("GET", "/api/memories/history", (_req, url) => {
|
|
57513
57762
|
const q = getSearchParams(url);
|
|
57514
|
-
const
|
|
57515
|
-
|
|
57516
|
-
|
|
57517
|
-
|
|
57518
|
-
|
|
57763
|
+
const parsedLimit = Number(q["limit"]);
|
|
57764
|
+
const limit = Number.isInteger(parsedLimit) && parsedLimit > 0 ? Math.min(parsedLimit, 200) : 20;
|
|
57765
|
+
const parsedOffset = Number(q["offset"]);
|
|
57766
|
+
const offset = Number.isInteger(parsedOffset) && parsedOffset >= 0 ? parsedOffset : 0;
|
|
57767
|
+
const page = listMemoryHistoryPage({ limit, offset }, getDatabase());
|
|
57768
|
+
const total = countMemoryHistory(getDatabase());
|
|
57769
|
+
return json({
|
|
57770
|
+
memories: page.rows,
|
|
57771
|
+
count: page.rows.length,
|
|
57772
|
+
total,
|
|
57773
|
+
limit,
|
|
57774
|
+
has_more: page.has_more,
|
|
57775
|
+
next_cursor: page.next_cursor
|
|
57776
|
+
});
|
|
57519
57777
|
});
|
|
57520
57778
|
addRoute("GET", "/api/memories/health", (_req, url) => {
|
|
57521
57779
|
const q = getSearchParams(url);
|
|
@@ -57556,7 +57814,7 @@ function hasFts5Table2(db) {
|
|
|
57556
57814
|
function buildScopeFilter(opts) {
|
|
57557
57815
|
const conditions = [
|
|
57558
57816
|
"m.status = 'active'",
|
|
57559
|
-
"(m.expires_at IS NULL OR m.expires_at >=
|
|
57817
|
+
"(m.expires_at IS NULL OR m.expires_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))",
|
|
57560
57818
|
"m.category IN ('preference', 'fact', 'knowledge')"
|
|
57561
57819
|
];
|
|
57562
57820
|
const params = [];
|
|
@@ -57824,7 +58082,7 @@ async function runTemporalAgent(db, query, opts) {
|
|
|
57824
58082
|
const maxResults = opts.max_results ?? 20;
|
|
57825
58083
|
const limit = maxResults * 3;
|
|
57826
58084
|
const conditions = [
|
|
57827
|
-
"(m.expires_at IS NULL OR m.expires_at >=
|
|
58085
|
+
"(m.expires_at IS NULL OR m.expires_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
|
57828
58086
|
];
|
|
57829
58087
|
const params = [];
|
|
57830
58088
|
if (opts.project_id) {
|
|
@@ -58594,6 +58852,90 @@ class MementosProjectRegistrationError extends Error {
|
|
|
58594
58852
|
}
|
|
58595
58853
|
}
|
|
58596
58854
|
|
|
58855
|
+
// src/project-registration/historical-receipt.ts
|
|
58856
|
+
var ROOT_TENANT_ID = "adfd95c7-ee8b-52cb-ae47-4ae65dae3313";
|
|
58857
|
+
var FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION = {
|
|
58858
|
+
authority: "mementos",
|
|
58859
|
+
authority_route: "mementos.project-registration.v1",
|
|
58860
|
+
package_version: "1.0.0-rc.3",
|
|
58861
|
+
authority_id: "mementos",
|
|
58862
|
+
tenant_id: "default",
|
|
58863
|
+
corpus_id: "default",
|
|
58864
|
+
operation_id: "op-cli-register-full",
|
|
58865
|
+
step_id: "mementos_project",
|
|
58866
|
+
resource_kind: "project",
|
|
58867
|
+
direction: "forward",
|
|
58868
|
+
target_selector: "wks_005285827590a93b70e5",
|
|
58869
|
+
target_id: "mm_project_f75606ef14e51fb577a15882ba0ab8ed333b2c29",
|
|
58870
|
+
idempotency_key: "prk_786cdc6babddeae1be8d5078d0f75322d1ea1010ac5d8a50",
|
|
58871
|
+
receipt_id: "mmpr_a647f9908a33bb64bf137f584202590f91b72a33",
|
|
58872
|
+
request_digest: "8eb0e3fee26fdb7edb8a444aeddaaedb79a84a5a36e742ae03616f62b19f5c22",
|
|
58873
|
+
precondition_digest: "0b6c22fcf75d835f9f27308b1a9d40e8902e48a97da370fd56df5acacfcd968e",
|
|
58874
|
+
result_revision: "2026-08-09T13:37:43.068Z",
|
|
58875
|
+
result_digest: "26fb0dd5c5e20909d3653ab0ddd8fa45e5142728e4e66d595e2419f7ed40b036",
|
|
58876
|
+
created_at: "2026-08-09T13:37:43.068Z",
|
|
58877
|
+
identity_digest: "1108dd972c90e4989036fb6ecec7dde10f54641a697bd53cfcd64017f589ace7",
|
|
58878
|
+
target_digest: "72789fcd60668eeb66ee068936d3afa96deadcb007228830c64b6de783b6dcef",
|
|
58879
|
+
operation_digest: "d7e37bfb2c0d28f8c4086c53224cd855d14694f32807b74c102b61a99963f3c0",
|
|
58880
|
+
idempotency_digest: "b56d8ec37efb818759cdd2ee3b58bc1401ac13384c8d64c1813bb5c198b1e376",
|
|
58881
|
+
receipt_digest: "52ce90c5de6817989f107d9d27e06156962a2b9c365e34e16a57aa37886501a2",
|
|
58882
|
+
response_digest: "2fa3ed508f5f192c18753b1205ced996340fdf02f735420d32db897fc239805c"
|
|
58883
|
+
};
|
|
58884
|
+
var FLEET_RESOURCES_HISTORICAL_RECEIPT = {
|
|
58885
|
+
receipt_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.receipt_id,
|
|
58886
|
+
authority: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority,
|
|
58887
|
+
route: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority_route,
|
|
58888
|
+
package_version: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.package_version,
|
|
58889
|
+
authority_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority_id,
|
|
58890
|
+
tenant_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.tenant_id,
|
|
58891
|
+
corpus_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.corpus_id,
|
|
58892
|
+
operation_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.operation_id,
|
|
58893
|
+
step_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.step_id,
|
|
58894
|
+
resource_kind: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.resource_kind,
|
|
58895
|
+
direction: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.direction,
|
|
58896
|
+
idempotency_key: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.idempotency_key,
|
|
58897
|
+
request_digest: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.request_digest,
|
|
58898
|
+
precondition_digest: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.precondition_digest,
|
|
58899
|
+
outcome: "accepted",
|
|
58900
|
+
reason: null,
|
|
58901
|
+
target_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.target_id,
|
|
58902
|
+
result_revision: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.result_revision,
|
|
58903
|
+
result_digest: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.result_digest,
|
|
58904
|
+
duplicate_of_receipt_id: null,
|
|
58905
|
+
accepted_receipt_id: null,
|
|
58906
|
+
created_by_operation: true,
|
|
58907
|
+
created_at: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.created_at
|
|
58908
|
+
};
|
|
58909
|
+
var FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY = {
|
|
58910
|
+
authority_id: "mementos",
|
|
58911
|
+
tenant_id: ROOT_TENANT_ID,
|
|
58912
|
+
corpus_id: "mementos:postgresql"
|
|
58913
|
+
};
|
|
58914
|
+
var FLEET_RESOURCES_HISTORICAL_LOOKUP_IDENTITY = {
|
|
58915
|
+
source: {
|
|
58916
|
+
authority: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority,
|
|
58917
|
+
authority_route: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority_route,
|
|
58918
|
+
package_version: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.package_version,
|
|
58919
|
+
authority_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority_id,
|
|
58920
|
+
tenant_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.tenant_id,
|
|
58921
|
+
corpus_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.corpus_id,
|
|
58922
|
+
operation_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.operation_id,
|
|
58923
|
+
step_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.step_id,
|
|
58924
|
+
resource_kind: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.resource_kind,
|
|
58925
|
+
direction: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.direction,
|
|
58926
|
+
target_selector: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.target_selector,
|
|
58927
|
+
target_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.target_id,
|
|
58928
|
+
idempotency_key: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.idempotency_key,
|
|
58929
|
+
receipt_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.receipt_id
|
|
58930
|
+
},
|
|
58931
|
+
destination: FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY,
|
|
58932
|
+
lookup_only: true,
|
|
58933
|
+
immutable_receipt: true
|
|
58934
|
+
};
|
|
58935
|
+
function supportsFleetResourcesHistoricalReceiptLookup(capability) {
|
|
58936
|
+
return capability.authority_id === FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY.authority_id && capability.tenant_id === FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY.tenant_id && capability.corpus_id === FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY.corpus_id;
|
|
58937
|
+
}
|
|
58938
|
+
|
|
58597
58939
|
// src/project-registration/identity.ts
|
|
58598
58940
|
var MEMENTOS_PROJECT_AUTHORITY_ENV = {
|
|
58599
58941
|
authorityId: "MEMENTOS_PROJECT_AUTHORITY_ID",
|
|
@@ -58635,12 +58977,13 @@ function resolveMementosProjectAuthorityIdentity(options = {}) {
|
|
|
58635
58977
|
}
|
|
58636
58978
|
function buildMementosProjectRegistrationCapability(options = {}) {
|
|
58637
58979
|
const identity = resolveMementosProjectAuthorityIdentity(options);
|
|
58638
|
-
|
|
58980
|
+
const capability = {
|
|
58639
58981
|
authority: "mementos",
|
|
58640
58982
|
route: MEMENTOS_PROJECT_REGISTRATION_ROUTE,
|
|
58641
58983
|
package_version: options.packageVersion ?? getMementosPackageVersion(),
|
|
58642
58984
|
...identity,
|
|
58643
58985
|
supported_resources: ["project"],
|
|
58986
|
+
supported_historical_lookup_identities: [],
|
|
58644
58987
|
conditional_create: true,
|
|
58645
58988
|
immutable_receipts: true,
|
|
58646
58989
|
exact_terminal_lookup: true,
|
|
@@ -58659,6 +59002,12 @@ function buildMementosProjectRegistrationCapability(options = {}) {
|
|
|
58659
59002
|
stable_keyset_pagination: true,
|
|
58660
59003
|
explicit_membership_only: true
|
|
58661
59004
|
};
|
|
59005
|
+
if (supportsFleetResourcesHistoricalReceiptLookup(capability)) {
|
|
59006
|
+
capability.supported_historical_lookup_identities = [
|
|
59007
|
+
FLEET_RESOURCES_HISTORICAL_LOOKUP_IDENTITY
|
|
59008
|
+
];
|
|
59009
|
+
}
|
|
59010
|
+
return capability;
|
|
58662
59011
|
}
|
|
58663
59012
|
|
|
58664
59013
|
// src/db/memory-project-link.ts
|
|
@@ -59567,7 +59916,7 @@ function acquireLock(agentId, resourceType, resourceId, lockType = "exclusive",
|
|
|
59567
59916
|
}
|
|
59568
59917
|
const d = db || getDatabase();
|
|
59569
59918
|
cleanExpiredLocks(d);
|
|
59570
|
-
const ownLock = d.query("SELECT * FROM resource_locks WHERE resource_type = ? AND resource_id = ? AND agent_id = ? AND lock_type = ? AND expires_at >
|
|
59919
|
+
const ownLock = d.query("SELECT * FROM resource_locks WHERE resource_type = ? AND resource_id = ? AND agent_id = ? AND lock_type = ? AND expires_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')").get(resourceType, resourceId, agentId, lockType);
|
|
59571
59920
|
if (ownLock) {
|
|
59572
59921
|
const newExpiry = new Date(Date.now() + ttlSeconds * 1000).toISOString();
|
|
59573
59922
|
d.run("UPDATE resource_locks SET expires_at = ? WHERE id = ?", [
|
|
@@ -59577,7 +59926,7 @@ function acquireLock(agentId, resourceType, resourceId, lockType = "exclusive",
|
|
|
59577
59926
|
return parseLockRow({ ...ownLock, expires_at: newExpiry });
|
|
59578
59927
|
}
|
|
59579
59928
|
if (lockType === "exclusive") {
|
|
59580
|
-
const existing = d.query("SELECT * FROM resource_locks WHERE resource_type = ? AND resource_id = ? AND lock_type = 'exclusive' AND agent_id != ? AND expires_at >
|
|
59929
|
+
const existing = d.query("SELECT * FROM resource_locks WHERE resource_type = ? AND resource_id = ? AND lock_type = 'exclusive' AND agent_id != ? AND expires_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')").get(resourceType, resourceId, agentId);
|
|
59581
59930
|
if (existing) {
|
|
59582
59931
|
return null;
|
|
59583
59932
|
}
|
|
@@ -59622,7 +59971,7 @@ function checkLock(resourceType, resourceId, lockType, db) {
|
|
|
59622
59971
|
}
|
|
59623
59972
|
const d = db || getDatabase();
|
|
59624
59973
|
cleanExpiredLocks(d);
|
|
59625
|
-
const query = lockType ? "SELECT * FROM resource_locks WHERE resource_type = ? AND resource_id = ? AND lock_type = ? AND expires_at >
|
|
59974
|
+
const query = lockType ? "SELECT * FROM resource_locks WHERE resource_type = ? AND resource_id = ? AND lock_type = ? AND expires_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')" : "SELECT * FROM resource_locks WHERE resource_type = ? AND resource_id = ? AND expires_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now')";
|
|
59626
59975
|
const rows = lockType ? d.query(query).all(resourceType, resourceId, lockType) : d.query(query).all(resourceType, resourceId);
|
|
59627
59976
|
return rows.map(parseLockRow);
|
|
59628
59977
|
}
|
|
@@ -59633,7 +59982,7 @@ function listAgentLocks(agentId, db) {
|
|
|
59633
59982
|
}
|
|
59634
59983
|
const d = db || getDatabase();
|
|
59635
59984
|
cleanExpiredLocks(d);
|
|
59636
|
-
const rows = d.query("SELECT * FROM resource_locks WHERE agent_id = ? AND expires_at >
|
|
59985
|
+
const rows = d.query("SELECT * FROM resource_locks WHERE agent_id = ? AND expires_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now') ORDER BY locked_at DESC").all(agentId);
|
|
59637
59986
|
return rows.map(parseLockRow);
|
|
59638
59987
|
}
|
|
59639
59988
|
function cleanExpiredLocks(db) {
|
|
@@ -59642,7 +59991,7 @@ function cleanExpiredLocks(db) {
|
|
|
59642
59991
|
return data?.cleaned ?? 0;
|
|
59643
59992
|
}
|
|
59644
59993
|
const d = db || getDatabase();
|
|
59645
|
-
const result = d.run("DELETE FROM resource_locks WHERE expires_at <=
|
|
59994
|
+
const result = d.run("DELETE FROM resource_locks WHERE expires_at <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')");
|
|
59646
59995
|
return result.changes;
|
|
59647
59996
|
}
|
|
59648
59997
|
|
|
@@ -60822,12 +61171,21 @@ function assertInverseRequest(request, capability) {
|
|
|
60822
61171
|
}
|
|
60823
61172
|
return accepted;
|
|
60824
61173
|
}
|
|
61174
|
+
function matchesCurrentLookupIdentity(request, capability) {
|
|
61175
|
+
return request.authority_route === capability.route && request.package_version === capability.package_version && request.authority_id === capability.authority_id && request.tenant_id === capability.tenant_id && request.corpus_id === capability.corpus_id;
|
|
61176
|
+
}
|
|
61177
|
+
function matchesFleetResourcesHistoricalLookup(request, capability) {
|
|
61178
|
+
if (!supportsFleetResourcesHistoricalReceiptLookup(capability))
|
|
61179
|
+
return false;
|
|
61180
|
+
const source = FLEET_RESOURCES_HISTORICAL_LOOKUP_IDENTITY.source;
|
|
61181
|
+
return request.authority === source.authority && request.authority_route === source.authority_route && request.package_version === source.package_version && request.authority_id === source.authority_id && request.tenant_id === source.tenant_id && request.corpus_id === source.corpus_id && request.operation_id === source.operation_id && request.step_id === source.step_id && request.resource_kind === source.resource_kind && request.direction === source.direction && request.target_selector === source.target_selector && request.target_id === source.target_id && request.idempotency_key === source.idempotency_key;
|
|
61182
|
+
}
|
|
60825
61183
|
function assertLookup(request, capability) {
|
|
60826
61184
|
assertBounds(request);
|
|
60827
61185
|
if (request.max_items !== 1) {
|
|
60828
61186
|
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_INVALID_BOUNDS", "terminal receipt lookup requires max_items exactly 1");
|
|
60829
61187
|
}
|
|
60830
|
-
if (request.authority !== "mementos" || request.resource_kind !== "project" || request
|
|
61188
|
+
if (request.authority !== "mementos" || request.resource_kind !== "project" || !matchesCurrentLookupIdentity(request, capability) && !matchesFleetResourcesHistoricalLookup(request, capability)) {
|
|
60831
61189
|
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_CAPABILITY_MISMATCH", "receipt lookup does not match this authority capability identity");
|
|
60832
61190
|
}
|
|
60833
61191
|
requireString(request.operation_id, "operation_id", { pattern: OPERATION_PATTERN });
|
|
@@ -60845,6 +61203,7 @@ function assertLookup(request, capability) {
|
|
|
60845
61203
|
pattern: PROJECT_ID_PATTERN
|
|
60846
61204
|
});
|
|
60847
61205
|
}
|
|
61206
|
+
return matchesCurrentLookupIdentity(request, capability) ? "current" : "fleet_resources_historical";
|
|
60848
61207
|
}
|
|
60849
61208
|
|
|
60850
61209
|
class PackageOwnedMementosProjectRegistrationAuthority {
|
|
@@ -61109,11 +61468,14 @@ class PackageOwnedMementosProjectRegistrationAuthority {
|
|
|
61109
61468
|
}
|
|
61110
61469
|
async lookupReceipt(request) {
|
|
61111
61470
|
const startedAt = Date.now();
|
|
61112
|
-
assertLookup(request, this.capabilityValue);
|
|
61471
|
+
const lookupIdentity = assertLookup(request, this.capabilityValue);
|
|
61113
61472
|
const receipt = getReceiptForLookup(this.db, request);
|
|
61114
61473
|
if (!receipt || request.target_id !== undefined && receipt.target_id !== request.target_id) {
|
|
61115
61474
|
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_RECEIPT_NOT_FOUND", "exact immutable terminal receipt was not found");
|
|
61116
61475
|
}
|
|
61476
|
+
if (lookupIdentity === "fleet_resources_historical" && (receipt.receipt_id !== FLEET_RESOURCES_HISTORICAL_LOOKUP_IDENTITY.source.receipt_id || canonicalMementosProjectRegistrationJson(publicReceipt(receipt)) !== canonicalMementosProjectRegistrationJson(FLEET_RESOURCES_HISTORICAL_RECEIPT))) {
|
|
61477
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_RECEIPT_NOT_FOUND", "exact immutable historical terminal receipt was not found");
|
|
61478
|
+
}
|
|
61117
61479
|
return withResponseControl(publicReceipt(receipt), request, startedAt);
|
|
61118
61480
|
}
|
|
61119
61481
|
async compensate(request) {
|
|
@@ -64720,13 +65082,11 @@ function startServer(port) {
|
|
|
64720
65082
|
const profile = getActiveProfile();
|
|
64721
65083
|
try {
|
|
64722
65084
|
const db = getDatabase();
|
|
64723
|
-
const
|
|
64724
|
-
const expired = db.query("SELECT COUNT(*) as c FROM memories WHERE status = 'expired' OR (expires_at IS NOT NULL AND expires_at < datetime('now'))").get().c;
|
|
64725
|
-
const pinned = db.query("SELECT COUNT(*) as c FROM memories WHERE status = 'active' AND pinned = 1").get().c;
|
|
65085
|
+
const stats = getMemoryStats(db);
|
|
64726
65086
|
const agents = db.query("SELECT COUNT(*) as c FROM agents").get().c;
|
|
64727
65087
|
const projects = db.query("SELECT COUNT(*) as c FROM projects").get().c;
|
|
64728
|
-
const status =
|
|
64729
|
-
return json({ status, version: pkgVersion(), backend, profile: profile ?? "default", db_path: getDbPath(), hostname: hostname3, memories: { total, expired, pinned }, agents, projects });
|
|
65088
|
+
const status = stats.expired_due_count > 50 ? "warn" : "ok";
|
|
65089
|
+
return json({ status, version: pkgVersion(), backend, profile: profile ?? "default", db_path: getDbPath(), hostname: hostname3, memories: { total: stats.total, expired: stats.expired_count, expired_due: stats.expired_due_count, pinned: stats.pinned_count }, agents, projects });
|
|
64730
65090
|
} catch (e) {
|
|
64731
65091
|
return json({ status: "error", version: pkgVersion(), backend, error: e instanceof Error ? e.message : String(e) }, 503);
|
|
64732
65092
|
}
|