squish-memory 1.0.2 → 1.1.5
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/.env.example +130 -0
- package/CHANGELOG.md +55 -0
- package/README.md +150 -287
- package/config/hooks/claude-code-hooks.json +39 -0
- package/config/hooks/cursor-hooks.json +30 -0
- package/config/hooks/opencode-hooks.json +30 -0
- package/config/hooks/windsurf-hooks.json +30 -0
- package/config/mcp-mode-semantics.json +23 -21
- package/config/plugin-manifest.json +101 -152
- package/{plugin.json → config/plugin.json} +2 -2
- package/config/settings.json +52 -51
- package/{commands → core/commands}/init.md +39 -39
- package/dist/config.d.ts +28 -4
- package/dist/config.js +97 -29
- package/dist/core/adapters/config/claude-code.d.ts +45 -0
- package/dist/core/adapters/config/claude-code.js +113 -0
- package/dist/core/adapters/config/cursor.d.ts +26 -0
- package/dist/core/adapters/config/cursor.js +74 -0
- package/dist/core/adapters/config/opencode.d.ts +23 -0
- package/dist/core/adapters/config/opencode.js +73 -0
- package/dist/core/adapters/config/windsurf.d.ts +26 -0
- package/dist/core/adapters/config/windsurf.js +74 -0
- package/dist/core/adapters/index.d.ts +45 -0
- package/dist/core/adapters/index.js +84 -0
- package/dist/core/adapters/scripts/install-adapter.d.ts +19 -0
- package/dist/core/adapters/scripts/install-adapter.js +149 -0
- package/dist/core/adapters/timeline.d.ts +23 -0
- package/dist/core/adapters/timeline.js +88 -0
- package/dist/core/adapters/types.d.ts +157 -0
- package/dist/core/adapters/types.js +50 -0
- package/dist/{algorithms → core/algorithms}/analytics/token-estimator.d.ts +1 -1
- package/dist/{algorithms → core/algorithms}/analytics/token-estimator.js +3 -3
- package/dist/{algorithms → core/algorithms}/detection/semantic-ranker.d.ts +1 -1
- package/dist/{algorithms → core/algorithms}/detection/semantic-ranker.js +1 -1
- package/dist/{algorithms → core/algorithms}/detection/two-stage-detector.d.ts +1 -1
- package/dist/{algorithms → core/algorithms}/detection/two-stage-detector.js +7 -10
- package/dist/{algorithms → core/algorithms}/handlers/approve-merge.js +4 -4
- package/dist/{algorithms → core/algorithms}/handlers/detect-duplicates.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/get-stats.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/list-proposals.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/preview-merge.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/reject-merge.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/reverse-merge.js +3 -3
- package/dist/core/algorithms/index.d.ts +21 -0
- package/dist/core/algorithms/index.js +26 -0
- package/dist/core/algorithms/operations/cache-maintenance.d.ts +12 -0
- package/dist/core/algorithms/operations/cache-maintenance.js +157 -0
- package/dist/{algorithms → core/algorithms}/safety/safety-checks.d.ts +1 -1
- package/dist/{algorithms → core/algorithms}/strategies/merge-strategies.d.ts +19 -1
- package/dist/{algorithms → core/algorithms}/strategies/merge-strategies.js +74 -123
- package/dist/core/algorithms/types.d.ts +133 -0
- package/dist/core/algorithms/types.js +5 -0
- package/dist/core/associations.d.ts +1 -2
- package/dist/core/associations.js +1 -2
- package/dist/core/autosave.d.ts +19 -0
- package/dist/core/autosave.js +16 -0
- package/dist/{commands → core/commands}/managed-sync.js +5 -5
- package/dist/core/commands/mcp-server.js +739 -0
- package/dist/core/context/agent-context.d.ts +106 -0
- package/dist/core/context/agent-context.js +274 -0
- package/dist/core/{context-paging.d.ts → context/context-paging.d.ts} +2 -12
- package/dist/core/{context-paging.js → context/context-paging.js} +19 -39
- package/dist/core/context/context-window.d.ts +40 -0
- package/dist/core/context/context-window.js +177 -0
- package/dist/core/context/context.js +22 -0
- package/dist/core/embeddings.d.ts +1 -1
- package/dist/core/embeddings.js +54 -2
- package/dist/core/error-handling.d.ts +63 -0
- package/dist/core/error-handling.js +173 -0
- package/dist/core/external-folder/index.d.ts +102 -0
- package/dist/core/external-folder/index.js +294 -0
- package/dist/core/hooks/agent-hooks.d.ts +74 -0
- package/dist/core/hooks/agent-hooks.js +244 -0
- package/dist/core/hooks/auto-tagger.d.ts +19 -0
- package/dist/core/hooks/auto-tagger.js +155 -0
- package/dist/core/hooks/capture-filter.d.ts +41 -0
- package/dist/core/hooks/capture-filter.js +128 -0
- package/dist/core/index.d.ts +6 -6
- package/dist/core/index.js +6 -6
- package/dist/core/{agent-memory.js → ingestion/agent-memory.js} +5 -7
- package/dist/core/{core-memory.js → ingestion/core-memory.js} +4 -4
- package/dist/core/ingestion/learnings.d.ts +57 -0
- package/dist/core/ingestion/learnings.js +202 -0
- package/dist/core/lib/db-client.d.ts +114 -0
- package/dist/core/lib/db-client.js +130 -0
- package/dist/core/lib/schemas.d.ts +129 -0
- package/dist/core/lib/schemas.js +87 -0
- package/dist/core/{utils.d.ts → lib/utils.d.ts} +1 -0
- package/dist/core/{utils.js → lib/utils.js} +31 -15
- package/dist/core/lib/validation.d.ts +38 -0
- package/dist/core/lib/validation.js +151 -0
- package/dist/core/lifecycle.d.ts +7 -0
- package/dist/core/lifecycle.js +140 -20
- package/dist/core/local-embeddings.d.ts +6 -1
- package/dist/core/local-embeddings.js +6 -15
- package/dist/core/logger.js +7 -1
- package/dist/core/mcp/tools.js +35 -3
- package/dist/core/memory/categorizer.js +1 -0
- package/dist/core/memory/conflict-detector.js +1 -1
- package/dist/core/memory/consolidation.d.ts +1 -10
- package/dist/core/memory/consolidation.js +2 -11
- package/dist/core/memory/context-collector.js +1 -1
- package/dist/core/memory/edit-workflow.js +1 -1
- package/dist/core/memory/entity-resolver.js +7 -7
- package/dist/core/memory/fact-extractor.js +12 -12
- package/dist/core/memory/feedback-tracker.js +1 -1
- package/dist/core/memory/hooks.d.ts +88 -0
- package/dist/core/memory/hooks.js +174 -0
- package/dist/core/memory/hybrid-retrieval.js +2 -2
- package/dist/core/memory/hybrid-search.d.ts +1 -6
- package/dist/core/memory/hybrid-search.js +70 -84
- package/dist/core/memory/importance.d.ts +8 -13
- package/dist/core/memory/importance.js +47 -74
- package/dist/core/memory/loader.d.ts +31 -0
- package/dist/core/memory/loader.js +141 -0
- package/dist/core/memory/markdown/markdown-storage.d.ts +72 -0
- package/dist/core/memory/markdown/markdown-storage.js +243 -0
- package/dist/core/memory/memories.d.ts +12 -4
- package/dist/core/memory/memories.js +192 -180
- package/dist/core/memory/memory-lifecycle.d.ts +8 -0
- package/dist/core/memory/memory-lifecycle.js +55 -0
- package/dist/core/memory/migrate.d.ts +21 -0
- package/dist/core/memory/migrate.js +134 -0
- package/dist/core/memory/normalization.d.ts +22 -0
- package/dist/core/memory/normalization.js +26 -0
- package/dist/core/memory/progressive-disclosure.js +1 -1
- package/dist/core/memory/query-rewriter.js +9 -9
- package/dist/core/memory/serialization.d.ts +4 -0
- package/dist/core/memory/serialization.js +49 -0
- package/dist/core/memory/stats.d.ts +5 -0
- package/dist/core/memory/stats.js +63 -12
- package/dist/core/memory/temporal-facts.js +21 -0
- package/dist/core/memory/write-gate.js +1 -1
- package/dist/core/obsidian-vault.d.ts +30 -0
- package/dist/core/obsidian-vault.js +94 -0
- package/dist/core/places/index.d.ts +14 -0
- package/dist/core/places/index.js +14 -0
- package/dist/core/places/memory-places.d.ts +68 -0
- package/dist/core/places/memory-places.js +261 -0
- package/dist/core/places/places.d.ts +88 -0
- package/dist/core/places/places.js +314 -0
- package/dist/core/places/rules.d.ts +74 -0
- package/dist/core/places/rules.js +240 -0
- package/dist/core/places/walking.d.ts +56 -0
- package/dist/core/places/walking.js +121 -0
- package/dist/core/projects.d.ts +5 -0
- package/dist/core/projects.js +39 -18
- package/dist/core/responses.d.ts +96 -0
- package/dist/core/responses.js +122 -0
- package/dist/core/scheduler/cron-scheduler.js +29 -7
- package/dist/core/scheduler/index.d.ts +1 -1
- package/dist/core/scheduler/index.js +1 -1
- package/dist/core/scheduler/job-runner.js +1 -1
- package/dist/core/search/conversations.js +40 -42
- package/dist/core/search/entities.js +6 -9
- package/dist/core/search/graph-boost.d.ts +7 -0
- package/dist/core/search/graph-boost.js +23 -0
- package/dist/core/search/qmd-search.js +4 -4
- package/dist/core/security/encrypt.d.ts +6 -0
- package/dist/core/security/encrypt.js +47 -0
- package/dist/core/{governance.d.ts → security/governance.d.ts} +6 -1
- package/dist/core/security/governance.js +79 -0
- package/dist/core/session/auto-load.js +6 -6
- package/dist/core/session/index.d.ts +1 -1
- package/dist/core/session/index.js +1 -1
- package/dist/core/session/self-iteration-job.d.ts +20 -0
- package/dist/core/session/self-iteration-job.js +282 -0
- package/dist/core/session/session-hooks.d.ts +18 -0
- package/dist/core/session/session-hooks.js +58 -0
- package/dist/core/session-hooks/self-iteration-job.js +35 -35
- package/dist/core/{cache.js → storage/cache.js} +2 -2
- package/dist/core/sync/qmd-sync.d.ts +1 -13
- package/dist/core/sync/qmd-sync.js +1 -13
- package/dist/core/toon.d.ts +43 -0
- package/dist/core/toon.js +160 -0
- package/dist/core/utils/memory-operations.js +1 -1
- package/dist/core/utils/vector-operations.d.ts +71 -0
- package/dist/core/utils/vector-operations.js +129 -0
- package/dist/db/adapter.d.ts +3 -3
- package/dist/db/adapter.js +99 -88
- package/dist/db/bootstrap.js +820 -522
- package/dist/{drizzle → db/drizzle}/schema-sqlite.d.ts +74 -25
- package/dist/{drizzle → db/drizzle}/schema-sqlite.js +91 -24
- package/dist/{drizzle → db/drizzle}/schema.d.ts +79 -32
- package/dist/{drizzle → db/drizzle}/schema.js +106 -35
- package/dist/db/drizzle.config.d.ts +3 -0
- package/dist/db/drizzle.config.js +12 -0
- package/dist/db/index.d.ts +1 -5
- package/dist/db/index.js +51 -8
- package/dist/db/neon.d.ts +8 -0
- package/dist/db/neon.js +20 -0
- package/dist/db/schema/index.d.ts +40 -0
- package/dist/db/schema/index.js +105 -0
- package/dist/db/schema/tables/context-sessions.d.ts +9 -0
- package/dist/db/schema/tables/context-sessions.js +37 -0
- package/dist/db/schema/tables/conversations.d.ts +9 -0
- package/dist/db/schema/tables/conversations.js +47 -0
- package/dist/db/schema/tables/core-memory.d.ts +9 -0
- package/dist/db/schema/tables/core-memory.js +41 -0
- package/dist/db/schema/tables/entities.d.ts +9 -0
- package/dist/db/schema/tables/entities.js +39 -0
- package/dist/db/schema/tables/entity-relations.d.ts +9 -0
- package/dist/db/schema/tables/entity-relations.js +31 -0
- package/dist/db/schema/tables/learnings.d.ts +9 -0
- package/dist/db/schema/tables/learnings.js +66 -0
- package/dist/db/schema/tables/memories.d.ts +9 -0
- package/dist/db/schema/tables/memories.js +161 -0
- package/dist/db/schema/tables/memory-associations.d.ts +9 -0
- package/dist/db/schema/tables/memory-associations.js +39 -0
- package/dist/db/schema/tables/memory-hash-cache.d.ts +9 -0
- package/dist/db/schema/tables/memory-hash-cache.js +29 -0
- package/dist/db/schema/tables/memory-merge-history.d.ts +9 -0
- package/dist/db/schema/tables/memory-merge-history.js +33 -0
- package/dist/db/schema/tables/memory-merge-proposals.d.ts +9 -0
- package/dist/db/schema/tables/memory-merge-proposals.js +39 -0
- package/dist/db/schema/tables/messages.d.ts +9 -0
- package/dist/db/schema/tables/messages.js +41 -0
- package/dist/db/schema/tables/namespaces.d.ts +9 -0
- package/dist/db/schema/tables/namespaces.js +37 -0
- package/dist/db/schema/tables/projects.d.ts +9 -0
- package/dist/db/schema/tables/projects.js +31 -0
- package/dist/db/schema/tables/users.d.ts +9 -0
- package/dist/db/schema/tables/users.js +27 -0
- package/dist/db/schema.d.ts +1 -1
- package/dist/db/schema.js +2 -2
- package/dist/db/supabase.d.ts +9 -0
- package/dist/db/supabase.js +24 -0
- package/dist/index.d.ts +2 -14
- package/dist/index.js +1320 -640
- package/dist/vendor/sql.js/sql-wasm.wasm +0 -0
- package/dist/webui/server.d.ts +5 -0
- package/dist/{api/web/web.js → webui/server.js} +511 -508
- package/generated/mcp/manifest.json +1 -1
- package/{.mcp.json → mcp.json.example} +1 -1
- package/package.json +159 -181
- package/scripts/README.md +60 -0
- package/scripts/copy-runtime-assets.mjs +26 -0
- package/scripts/generate-mcp.mjs +264 -264
- package/scripts/github-release.sh +4 -4
- package/scripts/install-claude-code.sh +85 -0
- package/scripts/install-cursor.sh +56 -0
- package/scripts/install-hooks.sh +73 -0
- package/scripts/install-interactive.mjs +357 -677
- package/scripts/install-opencode.sh +75 -0
- package/scripts/install-windsurf.sh +67 -0
- package/skills/squish-memory/SKILL.md +104 -114
- package/skills/squish-memory/{install.mjs → scripts/install.mjs} +2 -2
- package/skills/squish-memory/{install.sh → scripts/install.sh} +2 -2
- package/skills/squish-memory/write_skill.js +2 -0
- package/.claude-plugin/marketplace.json +0 -20
- package/.claude-plugin/plugin.json +0 -32
- package/.env.mcp.example +0 -60
- package/QUICK-START.md +0 -71
- package/bin/squish-add.mjs +0 -32
- package/bin/squish-rm.mjs +0 -21
- package/commands/observe.md +0 -5
- package/dist/api/web/index.d.ts +0 -3
- package/dist/api/web/index.js +0 -4
- package/dist/api/web/web-server.d.ts +0 -3
- package/dist/api/web/web-server.js +0 -6
- package/dist/api/web/web.d.ts +0 -4
- package/dist/commands/mcp-server.js +0 -393
- package/dist/core/context.js +0 -24
- package/dist/core/governance.js +0 -64
- package/dist/core/observations.d.ts +0 -26
- package/dist/core/observations.js +0 -110
- package/dist/core/requirements.d.ts +0 -20
- package/dist/core/requirements.js +0 -35
- package/hooks/hooks.json +0 -52
- package/hooks/post-tool-use.js +0 -26
- package/hooks/session-end.js +0 -28
- package/hooks/session-start.js +0 -33
- package/hooks/user-prompt-submit.js +0 -26
- package/hooks/utils.js +0 -153
- package/npx-installer.js +0 -208
- package/packages/plugin-claude-code/README.md +0 -73
- package/packages/plugin-claude-code/dist/plugin-wrapper.d.ts +0 -35
- package/packages/plugin-claude-code/dist/plugin-wrapper.js +0 -191
- package/packages/plugin-claude-code/package.json +0 -31
- package/packages/plugin-openclaw/README.md +0 -70
- package/packages/plugin-openclaw/dist/index.d.ts +0 -49
- package/packages/plugin-openclaw/dist/index.js +0 -262
- package/packages/plugin-openclaw/openclaw.plugin.json +0 -94
- package/packages/plugin-openclaw/package.json +0 -31
- package/packages/plugin-opencode/install.mjs +0 -217
- package/packages/plugin-opencode/package.json +0 -21
- package/scripts/db/check-db.mjs +0 -88
- package/scripts/db/fix-all-columns.mjs +0 -52
- package/scripts/db/fix-schema-all.mjs +0 -55
- package/scripts/db/fix-schema-full.mjs +0 -46
- package/scripts/db/fix-schema.mjs +0 -38
- package/scripts/db/init-db.mjs +0 -13
- package/scripts/db/recreate-db.mjs +0 -14
- package/scripts/install-mcp.mjs +0 -116
- package/scripts/install-web.sh +0 -120
- package/scripts/install.mjs +0 -340
- package/scripts/openclaw-bootstrap.mjs +0 -127
- package/scripts/package-release.sh +0 -71
- package/scripts/test/test-all-systems.mjs +0 -139
- package/scripts/test/test-memory-system.mjs +0 -139
- package/scripts/test/test-v0.5.0.mjs +0 -210
- package/skills/memory-guide/SKILL.md +0 -332
- package/skills/squish-cli/SKILL.md +0 -240
- package/skills/squish-mcp/SKILL.md +0 -355
- package/skills/squish-memory/claude-desktop.json +0 -12
- package/skills/squish-memory/openclaw.json +0 -13
- package/skills/squish-memory/opencode.json +0 -14
- package/skills/squish-memory/skill.json +0 -32
- /package/{commands → core/commands}/context-paging.md +0 -0
- /package/{commands → core/commands}/context-status.md +0 -0
- /package/{commands → core/commands}/context.md +0 -0
- /package/{commands → core/commands}/core-memory.md +0 -0
- /package/{commands → core/commands}/health.md +0 -0
- /package/{commands → core/commands}/merge.md +0 -0
- /package/{commands → core/commands}/recall.md +0 -0
- /package/{commands → core/commands}/remember.md +0 -0
- /package/{commands → core/commands}/search.md +0 -0
- /package/dist/{algorithms → core/algorithms}/detection/hash-filters.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/detection/hash-filters.js +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/approve-merge.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/detect-duplicates.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/get-stats.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/list-proposals.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/preview-merge.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/reject-merge.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/reverse-merge.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/safety/safety-checks.js +0 -0
- /package/dist/{algorithms → core/algorithms}/utils/response-builder.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/utils/response-builder.js +0 -0
- /package/dist/{commands → core/commands}/managed-sync.d.ts +0 -0
- /package/dist/{commands → core/commands}/mcp-server.d.ts +0 -0
- /package/dist/core/{context.d.ts → context/context.d.ts} +0 -0
- /package/dist/core/{agent-memory.d.ts → ingestion/agent-memory.d.ts} +0 -0
- /package/dist/core/{core-memory.d.ts → ingestion/core-memory.d.ts} +0 -0
- /package/dist/core/{privacy.d.ts → security/privacy.d.ts} +0 -0
- /package/dist/core/{privacy.js → security/privacy.js} +0 -0
- /package/dist/core/{secret-detector.d.ts → security/secret-detector.d.ts} +0 -0
- /package/dist/core/{secret-detector.js → security/secret-detector.js} +0 -0
- /package/dist/core/{cache.d.ts → storage/cache.d.ts} +0 -0
- /package/dist/core/{database.d.ts → storage/database.d.ts} +0 -0
- /package/dist/core/{database.js → storage/database.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type MemoryType = 'observation' | 'fact' | 'decision' | 'context' | 'preference';
|
|
1
|
+
export type MemoryType = 'observation' | 'fact' | 'decision' | 'context' | 'preference' | 'note';
|
|
2
2
|
export interface RememberInput {
|
|
3
3
|
content: string;
|
|
4
4
|
type?: MemoryType;
|
|
@@ -6,6 +6,12 @@ export interface RememberInput {
|
|
|
6
6
|
project?: string;
|
|
7
7
|
metadata?: Record<string, unknown>;
|
|
8
8
|
source?: string;
|
|
9
|
+
reasoning?: string;
|
|
10
|
+
memoryContext?: string;
|
|
11
|
+
examples?: string;
|
|
12
|
+
exceptions?: string;
|
|
13
|
+
tier?: 'hot' | 'cold';
|
|
14
|
+
namespaceId?: string;
|
|
9
15
|
}
|
|
10
16
|
export interface SearchInput {
|
|
11
17
|
query: string;
|
|
@@ -28,12 +34,14 @@ export interface MemoryRecord {
|
|
|
28
34
|
recordedAt?: string | null;
|
|
29
35
|
similarity?: number;
|
|
30
36
|
importance?: number;
|
|
37
|
+
confidenceLevel?: 'certain' | 'speculative' | 'outdated' | null;
|
|
31
38
|
}
|
|
32
39
|
export interface SearchResult extends MemoryRecord {
|
|
33
40
|
similarity: number;
|
|
34
41
|
}
|
|
35
42
|
export declare function rememberMemory(input: RememberInput): Promise<MemoryRecord>;
|
|
36
|
-
export declare function
|
|
37
|
-
export declare function
|
|
38
|
-
export declare function
|
|
43
|
+
export declare function getMemory(id: string, incrementAccess?: boolean): Promise<MemoryRecord | null>;
|
|
44
|
+
export declare function setConfidence(id: string, level: 'certain' | 'speculative' | 'outdated'): Promise<boolean>;
|
|
45
|
+
export declare function getRecent(projectPath: string, limit: number): Promise<MemoryRecord[]>;
|
|
46
|
+
export declare function search(input: SearchInput): Promise<SearchResult[]>;
|
|
39
47
|
//# sourceMappingURL=memories.d.ts.map
|
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
2
|
import { eq } from 'drizzle-orm';
|
|
3
|
-
import { getDb } from '../../db/index.js';
|
|
4
|
-
import { getSchema } from '../../db/schema.js';
|
|
5
3
|
import { config } from '../../config.js';
|
|
6
|
-
import {
|
|
4
|
+
import { logger } from '../../core/logger.js';
|
|
5
|
+
import { getOrCreateProject, requireProject } from '../../core/projects.js';
|
|
7
6
|
import { getEmbedding } from '../../core/embeddings.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
7
|
+
import { normalizeTags, serializeTags, deserializeTags, serializeMetadata, deserializeMetadata } from '../../core/memory/serialization.js';
|
|
8
|
+
import { normalizeTimestamp, clampLimit, prepareEmbedding } from '../lib/utils.js';
|
|
9
|
+
import { requireUuid } from '../lib/validation.js';
|
|
10
|
+
import { cosineSimilarity } from '../utils/vector-operations.js';
|
|
11
11
|
import { hybridSearch as hybridSearchImpl } from './hybrid-search.js';
|
|
12
12
|
import { calculateImportance } from './importance.js';
|
|
13
13
|
import { detectMemorySignals } from './trigger-detector.js';
|
|
14
14
|
import { resolveContradictions, applySupersession } from './contradiction-resolver.js';
|
|
15
|
+
import { encrypt, decrypt } from '../security/encrypt.js';
|
|
16
|
+
import { estimateTokens } from '../context/context-window.js';
|
|
17
|
+
import { getDbClient } from '../lib/db-client.js';
|
|
15
18
|
export async function rememberMemory(input) {
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
db = createDatabaseClient(await getDb());
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
throw new Error(`Database unavailable: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
22
|
-
}
|
|
23
|
-
const schema = await getSchema();
|
|
19
|
+
const { db, schema } = await getDbClient();
|
|
24
20
|
const tags = normalizeTags(input.tags);
|
|
25
|
-
const project = await
|
|
21
|
+
const project = await getOrCreateProject(input.project);
|
|
26
22
|
const embedding = await getEmbedding(input.content);
|
|
27
23
|
const id = randomUUID();
|
|
28
24
|
const signals = detectMemorySignals(input.content);
|
|
@@ -45,17 +41,15 @@ export async function rememberMemory(input) {
|
|
|
45
41
|
isImmutable: false,
|
|
46
42
|
});
|
|
47
43
|
const embeddingValues = prepareEmbedding(embedding);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
tagsValue = tags.length ? tags : null;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
tagsValue = toSqliteTags(tags);
|
|
54
|
-
}
|
|
55
|
-
let metadataValue;
|
|
56
|
-
// Build enriched metadata with memory signals
|
|
44
|
+
const tokensEstimate = estimateTokens(input.content);
|
|
45
|
+
let tagsValue = serializeTags(tags);
|
|
57
46
|
const enrichedMetadata = {
|
|
58
47
|
...(input.metadata ?? {}),
|
|
48
|
+
// Rich context fields (Agent 4 feedback)
|
|
49
|
+
reasoning: input.reasoning,
|
|
50
|
+
memoryContext: input.memoryContext,
|
|
51
|
+
examples: input.examples,
|
|
52
|
+
exceptions: input.exceptions,
|
|
59
53
|
memorySignals: {
|
|
60
54
|
explicitTriggers: signals.explicitTriggers,
|
|
61
55
|
implicit: signals.implicit,
|
|
@@ -63,21 +57,81 @@ export async function rememberMemory(input) {
|
|
|
63
57
|
requiresConflictCheck: signals.implicit.correction,
|
|
64
58
|
},
|
|
65
59
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
else {
|
|
70
|
-
metadataValue = toSqliteJson(enrichedMetadata);
|
|
71
|
-
}
|
|
72
|
-
await db.insert(schema.memories).values({
|
|
60
|
+
let metadataValue = serializeMetadata(enrichedMetadata);
|
|
61
|
+
// Prepare fields for insertion, handling optional encryption
|
|
62
|
+
let insertValues = {
|
|
73
63
|
...baseValues,
|
|
74
64
|
tags: tagsValue,
|
|
75
65
|
metadata: metadataValue,
|
|
76
66
|
...embeddingValues,
|
|
77
67
|
importanceScore: importance.score,
|
|
78
68
|
lastImportanceRecalc: new Date(),
|
|
69
|
+
tokensEstimate,
|
|
79
70
|
createdAt: new Date(),
|
|
80
|
-
|
|
71
|
+
status: 'active',
|
|
72
|
+
tier: input.tier || 'hot', // Default to hot tier
|
|
73
|
+
};
|
|
74
|
+
// Add namespace if specified
|
|
75
|
+
if (input.namespaceId) {
|
|
76
|
+
insertValues.namespaceId = input.namespaceId;
|
|
77
|
+
}
|
|
78
|
+
// For cold tier, store original content in metadata
|
|
79
|
+
if (input.tier === 'cold') {
|
|
80
|
+
enrichedMetadata.originalContent = input.content;
|
|
81
|
+
}
|
|
82
|
+
if (config.clientEncryptionEnabled) {
|
|
83
|
+
const { ciphertext, nonce } = encrypt(input.content);
|
|
84
|
+
insertValues.encrypted_content = ciphertext;
|
|
85
|
+
insertValues.encryption_nonce = nonce;
|
|
86
|
+
insertValues.is_encrypted = true;
|
|
87
|
+
// Store empty placeholder for plain content
|
|
88
|
+
insertValues.content = '';
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
insertValues.content = input.content;
|
|
92
|
+
insertValues.is_encrypted = false;
|
|
93
|
+
}
|
|
94
|
+
await db.insert(schema.memories).values(insertValues);
|
|
95
|
+
// Append to Obsidian vault if enabled and hot tier (NEW)
|
|
96
|
+
if (config.obsidianEnabled && config.obsidianVaultPath && insertValues.tier === 'hot') {
|
|
97
|
+
try {
|
|
98
|
+
const { appendToObsidianVault } = await import('../obsidian-vault.js');
|
|
99
|
+
await appendToObsidianVault({
|
|
100
|
+
content: input.content,
|
|
101
|
+
id,
|
|
102
|
+
type,
|
|
103
|
+
tags,
|
|
104
|
+
reasoning: input.reasoning,
|
|
105
|
+
memoryContext: input.memoryContext,
|
|
106
|
+
examples: input.examples,
|
|
107
|
+
exceptions: input.exceptions,
|
|
108
|
+
source: input.source,
|
|
109
|
+
}, config.obsidianVaultPath);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
logger.warn(`[Obsidian] Failed to append to vault: ${error}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Write to external folder memory if enabled and hot tier
|
|
116
|
+
if (config.externalMemoryEnabled && config.externalMemoryPath && insertValues.tier === 'hot') {
|
|
117
|
+
try {
|
|
118
|
+
const { getExternalMemory } = await import('../external-folder/index.js');
|
|
119
|
+
const externalMemory = getExternalMemory();
|
|
120
|
+
const memoryRecord = {
|
|
121
|
+
id,
|
|
122
|
+
projectId: project?.id ?? null,
|
|
123
|
+
type,
|
|
124
|
+
content: input.content,
|
|
125
|
+
tags,
|
|
126
|
+
createdAt: insertValues.createdAt?.toISOString(),
|
|
127
|
+
confidenceLevel: null,
|
|
128
|
+
};
|
|
129
|
+
await externalMemory.writeMemory(externalMemory.toMarkdownFormat(memoryRecord));
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
logger.warn(`[ExternalMemory] Failed to write: ${error}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
81
135
|
// Resolve contradictions and supersede old memories (async, non-blocking)
|
|
82
136
|
resolveContradictions(input.content, type, project?.id)
|
|
83
137
|
.then(async (result) => {
|
|
@@ -92,12 +146,7 @@ export async function rememberMemory(input) {
|
|
|
92
146
|
reason: result.reason,
|
|
93
147
|
},
|
|
94
148
|
};
|
|
95
|
-
|
|
96
|
-
metadataValue = updatedMetadata;
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
metadataValue = toSqliteJson(updatedMetadata);
|
|
100
|
-
}
|
|
149
|
+
metadataValue = serializeMetadata(updatedMetadata);
|
|
101
150
|
}
|
|
102
151
|
})
|
|
103
152
|
.catch((error) => {
|
|
@@ -117,10 +166,11 @@ export async function rememberMemory(input) {
|
|
|
117
166
|
};
|
|
118
167
|
return memoryRecord;
|
|
119
168
|
}
|
|
120
|
-
export async function
|
|
169
|
+
export async function getMemory(id, incrementAccess = true) {
|
|
121
170
|
try {
|
|
122
|
-
|
|
123
|
-
|
|
171
|
+
// Validate UUID
|
|
172
|
+
requireUuid(id);
|
|
173
|
+
const { db, schema } = await getDbClient();
|
|
124
174
|
const rows = await db.select().from(schema.memories).where(eq(schema.memories.id, id)).limit(1);
|
|
125
175
|
const row = rows[0];
|
|
126
176
|
if (!row)
|
|
@@ -134,25 +184,48 @@ export async function getMemoryById(id, incrementAccess = true) {
|
|
|
134
184
|
})
|
|
135
185
|
.where(eq(schema.memories.id, id));
|
|
136
186
|
}
|
|
137
|
-
|
|
187
|
+
let content = row.content;
|
|
188
|
+
if (row.is_encrypted) {
|
|
189
|
+
try {
|
|
190
|
+
content = decrypt(row.encrypted_content, row.encryption_nonce);
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
console.warn('Failed to decrypt memory', e);
|
|
194
|
+
content = row.content; // fall back to stored content
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const decryptedRow = { ...row, content };
|
|
198
|
+
return normalizeMemory(decryptedRow);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
export async function setConfidence(id, level) {
|
|
205
|
+
try {
|
|
206
|
+
// Validate UUID
|
|
207
|
+
requireUuid(id);
|
|
208
|
+
const { db, schema } = await getDbClient();
|
|
209
|
+
await db.update(schema.memories)
|
|
210
|
+
.set({ confidenceLevel: level, updatedAt: new Date() })
|
|
211
|
+
.where(eq(schema.memories.id, id));
|
|
212
|
+
return true;
|
|
138
213
|
}
|
|
139
214
|
catch (error) {
|
|
140
215
|
throw error;
|
|
141
216
|
}
|
|
142
217
|
}
|
|
143
|
-
export async function
|
|
218
|
+
export async function getRecent(projectPath, limit) {
|
|
144
219
|
try {
|
|
145
|
-
const db =
|
|
220
|
+
const { db } = await getDbClient();
|
|
146
221
|
const sqlite = db.$client;
|
|
147
|
-
const project = await
|
|
148
|
-
if (!project)
|
|
149
|
-
return [];
|
|
222
|
+
const project = await requireProject(projectPath);
|
|
150
223
|
// Use raw SQL to avoid drizzle column name issues
|
|
151
|
-
const rows = sqlite.prepare(`
|
|
152
|
-
SELECT * FROM memories
|
|
153
|
-
WHERE project_id = ?
|
|
154
|
-
ORDER BY created_at DESC
|
|
155
|
-
LIMIT ?
|
|
224
|
+
const rows = sqlite.prepare(`
|
|
225
|
+
SELECT * FROM memories
|
|
226
|
+
WHERE project_id = ?
|
|
227
|
+
ORDER BY created_at DESC
|
|
228
|
+
LIMIT ?
|
|
156
229
|
`).all(project.id, limit);
|
|
157
230
|
return rows.map((row) => normalizeMemory(row));
|
|
158
231
|
}
|
|
@@ -160,32 +233,19 @@ export async function getRecentMemories(projectPath, limit) {
|
|
|
160
233
|
throw error;
|
|
161
234
|
}
|
|
162
235
|
}
|
|
163
|
-
export async function
|
|
236
|
+
export async function search(input) {
|
|
164
237
|
const limit = clampLimit(input.limit, 10, 1, 100);
|
|
165
238
|
const tags = normalizeTags(input.tags);
|
|
239
|
+
// Get results from database (hybrid search: BM25 + vectors with RRF)
|
|
240
|
+
let dbResults;
|
|
166
241
|
if (config.isTeamMode) {
|
|
167
|
-
|
|
242
|
+
dbResults = await searchMemoriesPostgres(input, tags, limit);
|
|
168
243
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Calculate cosine similarity between two vectors
|
|
174
|
-
*/
|
|
175
|
-
function cosineSimilarity(a, b) {
|
|
176
|
-
if (a.length !== b.length)
|
|
177
|
-
return 0;
|
|
178
|
-
let dotProduct = 0;
|
|
179
|
-
let normA = 0;
|
|
180
|
-
let normB = 0;
|
|
181
|
-
for (let i = 0; i < a.length; i++) {
|
|
182
|
-
dotProduct += a[i] * b[i];
|
|
183
|
-
normA += a[i] * a[i];
|
|
184
|
-
normB += b[i] * b[i];
|
|
244
|
+
else {
|
|
245
|
+
// Use hybrid search for SQLite (BM25 + vectors with RRF)
|
|
246
|
+
dbResults = await hybridSearchImpl(input, { limit });
|
|
185
247
|
}
|
|
186
|
-
|
|
187
|
-
return 0;
|
|
188
|
-
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
248
|
+
return dbResults.slice(0, limit);
|
|
189
249
|
}
|
|
190
250
|
/**
|
|
191
251
|
* Parse embedding from SQLite storage
|
|
@@ -233,7 +293,7 @@ function parseEmbedding(embeddingData) {
|
|
|
233
293
|
return null;
|
|
234
294
|
}
|
|
235
295
|
async function searchMemoriesSqlite(input, tags, limit) {
|
|
236
|
-
const db =
|
|
296
|
+
const { db } = await getDbClient();
|
|
237
297
|
const sqlite = db.$client;
|
|
238
298
|
// Get embedding for the query (for semantic search)
|
|
239
299
|
const queryEmbedding = await getEmbedding(input.query);
|
|
@@ -250,32 +310,30 @@ async function searchMemoriesSqlite(input, tags, limit) {
|
|
|
250
310
|
}
|
|
251
311
|
let projectId = null;
|
|
252
312
|
if (input.project) {
|
|
253
|
-
const project = await
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
params.push(project.id);
|
|
258
|
-
}
|
|
313
|
+
const project = await requireProject(input.project);
|
|
314
|
+
projectId = project.id;
|
|
315
|
+
conditions.push('m.project_id = ?');
|
|
316
|
+
params.push(project.id);
|
|
259
317
|
}
|
|
260
318
|
const whereClause = conditions.length > 0 ? 'WHERE ' + conditions.join(' AND ') : '';
|
|
261
319
|
// Fetch memories with embeddings for semantic search
|
|
262
320
|
const fetchLimit = Math.max(limit * 3, 50); // Fetch more for re-ranking
|
|
263
|
-
const statement = sqlite.prepare(`
|
|
264
|
-
SELECT
|
|
265
|
-
m.id as id,
|
|
266
|
-
m.project_id as projectId,
|
|
267
|
-
m.type as type,
|
|
268
|
-
m.content as content,
|
|
269
|
-
m.summary as summary,
|
|
270
|
-
m.tags as tags,
|
|
271
|
-
m.metadata as metadata,
|
|
272
|
-
m.embedding as embedding,
|
|
273
|
-
m.embedding_json as embeddingJson,
|
|
274
|
-
m.created_at as createdAt
|
|
275
|
-
FROM memories m
|
|
276
|
-
${whereClause}
|
|
277
|
-
ORDER BY m.created_at DESC
|
|
278
|
-
LIMIT ?
|
|
321
|
+
const statement = sqlite.prepare(`
|
|
322
|
+
SELECT
|
|
323
|
+
m.id as id,
|
|
324
|
+
m.project_id as projectId,
|
|
325
|
+
m.type as type,
|
|
326
|
+
m.content as content,
|
|
327
|
+
m.summary as summary,
|
|
328
|
+
m.tags as tags,
|
|
329
|
+
m.metadata as metadata,
|
|
330
|
+
m.embedding as embedding,
|
|
331
|
+
m.embedding_json as embeddingJson,
|
|
332
|
+
m.created_at as createdAt
|
|
333
|
+
FROM memories m
|
|
334
|
+
${whereClause}
|
|
335
|
+
ORDER BY m.created_at DESC
|
|
336
|
+
LIMIT ?
|
|
279
337
|
`);
|
|
280
338
|
const rows = statement.all(...params, fetchLimit);
|
|
281
339
|
if (rows.length === 0)
|
|
@@ -306,7 +364,7 @@ async function searchMemoriesSqlite(input, tags, limit) {
|
|
|
306
364
|
}));
|
|
307
365
|
}
|
|
308
366
|
async function searchMemoriesPostgres(input, tags, limit) {
|
|
309
|
-
const db =
|
|
367
|
+
const { db } = await getDbClient();
|
|
310
368
|
const values = [];
|
|
311
369
|
const whereParts = [];
|
|
312
370
|
values.push(`%${input.query}%`);
|
|
@@ -320,51 +378,49 @@ async function searchMemoriesPostgres(input, tags, limit) {
|
|
|
320
378
|
whereParts.push(`tags && $${values.length}::text[]`);
|
|
321
379
|
}
|
|
322
380
|
if (input.project) {
|
|
323
|
-
const project = await
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
whereParts.push(`project_id = $${values.length}`);
|
|
327
|
-
}
|
|
381
|
+
const project = await requireProject(input.project);
|
|
382
|
+
values.push(project.id);
|
|
383
|
+
whereParts.push(`project_id = $${values.length}`);
|
|
328
384
|
}
|
|
329
385
|
const whereClause = whereParts.length ? `WHERE ${whereParts.join(' AND ')}` : '';
|
|
330
386
|
const embedding = await getEmbedding(input.query);
|
|
331
387
|
if (embedding) {
|
|
332
|
-
const rows = await db.$client.query(`SELECT
|
|
333
|
-
id,
|
|
334
|
-
project_id as "projectId",
|
|
335
|
-
type,
|
|
336
|
-
content,
|
|
337
|
-
summary,
|
|
338
|
-
tags,
|
|
339
|
-
metadata,
|
|
340
|
-
created_at as "createdAt",
|
|
341
|
-
valid_from as "validFrom",
|
|
342
|
-
valid_to as "validTo",
|
|
343
|
-
recorded_at as "recordedAt"
|
|
344
|
-
FROM memories
|
|
345
|
-
${whereClause}
|
|
346
|
-
ORDER BY created_at DESC
|
|
388
|
+
const rows = await db.$client.query(`SELECT
|
|
389
|
+
id,
|
|
390
|
+
project_id as "projectId",
|
|
391
|
+
type,
|
|
392
|
+
content,
|
|
393
|
+
summary,
|
|
394
|
+
tags,
|
|
395
|
+
metadata,
|
|
396
|
+
created_at as "createdAt",
|
|
397
|
+
valid_from as "validFrom",
|
|
398
|
+
valid_to as "validTo",
|
|
399
|
+
recorded_at as "recordedAt"
|
|
400
|
+
FROM memories
|
|
401
|
+
${whereClause}
|
|
402
|
+
ORDER BY created_at DESC
|
|
347
403
|
LIMIT $${values.length + 1}`, [...values, limit]);
|
|
348
404
|
return rows.rows.map((row) => ({
|
|
349
405
|
...normalizeMemory(row),
|
|
350
406
|
similarity: row.similarity ?? 0,
|
|
351
407
|
}));
|
|
352
408
|
}
|
|
353
|
-
const rows = await db.$client.query(`SELECT
|
|
354
|
-
id,
|
|
355
|
-
project_id as "projectId",
|
|
356
|
-
type,
|
|
357
|
-
content,
|
|
358
|
-
summary,
|
|
359
|
-
tags,
|
|
360
|
-
metadata,
|
|
361
|
-
created_at as "createdAt",
|
|
362
|
-
valid_from as "validFrom",
|
|
363
|
-
valid_to as "validTo",
|
|
364
|
-
recorded_at as "recordedAt"
|
|
365
|
-
FROM memories
|
|
366
|
-
${whereClause}
|
|
367
|
-
ORDER BY created_at DESC
|
|
409
|
+
const rows = await db.$client.query(`SELECT
|
|
410
|
+
id,
|
|
411
|
+
project_id as "projectId",
|
|
412
|
+
type,
|
|
413
|
+
content,
|
|
414
|
+
summary,
|
|
415
|
+
tags,
|
|
416
|
+
metadata,
|
|
417
|
+
created_at as "createdAt",
|
|
418
|
+
valid_from as "validFrom",
|
|
419
|
+
valid_to as "validTo",
|
|
420
|
+
recorded_at as "recordedAt"
|
|
421
|
+
FROM memories
|
|
422
|
+
${whereClause}
|
|
423
|
+
ORDER BY created_at DESC
|
|
368
424
|
LIMIT $${values.length + 1}`, [...values, limit]);
|
|
369
425
|
return rows.rows.map((row) => ({
|
|
370
426
|
...normalizeMemory(row),
|
|
@@ -372,54 +428,9 @@ async function searchMemoriesPostgres(input, tags, limit) {
|
|
|
372
428
|
}));
|
|
373
429
|
}
|
|
374
430
|
function normalizeMemory(row) {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
tags = fromSqliteTags(row.tags ?? null);
|
|
381
|
-
}
|
|
382
|
-
let metadata;
|
|
383
|
-
if (config.isTeamMode) {
|
|
384
|
-
metadata = row.metadata;
|
|
385
|
-
}
|
|
386
|
-
else {
|
|
387
|
-
metadata = fromSqliteJson(row.metadata ?? null);
|
|
388
|
-
}
|
|
389
|
-
const createdAt = row.createdAt ?? row.created_at;
|
|
390
|
-
let createdAtStr = null;
|
|
391
|
-
if (createdAt !== undefined && createdAt !== null) {
|
|
392
|
-
try {
|
|
393
|
-
if (createdAt instanceof Date && !isNaN(createdAt.getTime())) {
|
|
394
|
-
createdAtStr = createdAt.toISOString();
|
|
395
|
-
}
|
|
396
|
-
else if (typeof createdAt === 'number') {
|
|
397
|
-
// Handle different timestamp formats
|
|
398
|
-
// Microseconds: > 100000000000000 (e.g., 170000000000000)
|
|
399
|
-
// Milliseconds: > 1000000000000 (e.g., 1700000000000)
|
|
400
|
-
// Seconds: <= 1000000000000 (e.g., 1700000000)
|
|
401
|
-
if (createdAt > 100000000000000) {
|
|
402
|
-
createdAtStr = new Date(createdAt / 1000).toISOString();
|
|
403
|
-
}
|
|
404
|
-
else if (createdAt > 1000000000000) {
|
|
405
|
-
createdAtStr = new Date(createdAt).toISOString();
|
|
406
|
-
}
|
|
407
|
-
else if (createdAt >= 0) {
|
|
408
|
-
// Unix timestamp in seconds - convert to milliseconds
|
|
409
|
-
createdAtStr = new Date(createdAt * 1000).toISOString();
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
else if (typeof createdAt === 'string' && createdAt.trim()) {
|
|
413
|
-
const parsed = new Date(createdAt);
|
|
414
|
-
if (!isNaN(parsed.getTime())) {
|
|
415
|
-
createdAtStr = parsed.toISOString();
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
catch {
|
|
420
|
-
// Keep null on parse error
|
|
421
|
-
}
|
|
422
|
-
}
|
|
431
|
+
const tags = deserializeTags(row.tags ?? null);
|
|
432
|
+
const metadata = deserializeMetadata(row.metadata ?? null);
|
|
433
|
+
const createdAtStr = normalizeTimestamp(row.createdAt ?? row.created_at);
|
|
423
434
|
return {
|
|
424
435
|
id: row.id,
|
|
425
436
|
projectId: row.projectId ?? row.project_id ?? null,
|
|
@@ -432,6 +443,7 @@ function normalizeMemory(row) {
|
|
|
432
443
|
validFrom: row.validFrom ?? row.valid_from ?? null,
|
|
433
444
|
validTo: row.validTo ?? row.valid_to ?? null,
|
|
434
445
|
recordedAt: row.recordedAt ?? row.recorded_at ?? null,
|
|
446
|
+
confidenceLevel: row.confidenceLevel ?? row.confidence_level ?? null,
|
|
435
447
|
};
|
|
436
448
|
}
|
|
437
449
|
//# sourceMappingURL=memories.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Promote a memory to a higher tier (hot -> warm -> cold) */
|
|
2
|
+
export declare function promoteTier(memoryId: string): Promise<void>;
|
|
3
|
+
/** Demote a memory tier or expire it based on decay */
|
|
4
|
+
export declare function demoteTier(memoryId: string): Promise<void>;
|
|
5
|
+
export declare function expireMemory(memoryId: string): Promise<void>;
|
|
6
|
+
export declare function markMerged(memoryId: string, targetId: string): Promise<void>;
|
|
7
|
+
export declare function markSuperseded(memoryId: string): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=memory-lifecycle.d.ts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getDb } from '../../db/index.js';
|
|
2
|
+
import { memories } from '../../db/drizzle/schema.js';
|
|
3
|
+
import { eq } from 'drizzle-orm';
|
|
4
|
+
import { logger } from '../logger.js';
|
|
5
|
+
/** Promote a memory to a higher tier (hot -> warm -> cold) */
|
|
6
|
+
export async function promoteTier(memoryId) {
|
|
7
|
+
const db = await getDb();
|
|
8
|
+
// @ts-ignore - drizzle overloads
|
|
9
|
+
const row = await db.select().from(memories).where(eq(memories.id, memoryId)).limit(1);
|
|
10
|
+
const mem = row[0];
|
|
11
|
+
if (!mem)
|
|
12
|
+
return;
|
|
13
|
+
let newTier = mem.tier;
|
|
14
|
+
if (mem.tier === 'warm')
|
|
15
|
+
newTier = 'hot';
|
|
16
|
+
else if (mem.tier === 'cold')
|
|
17
|
+
newTier = 'warm';
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
await db.update(memories).set({ tier: newTier }).where(eq(memories.id, memoryId));
|
|
20
|
+
}
|
|
21
|
+
/** Demote a memory tier or expire it based on decay */
|
|
22
|
+
export async function demoteTier(memoryId) {
|
|
23
|
+
const db = await getDb();
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
const row = await db.select().from(memories).where(eq(memories.id, memoryId)).limit(1);
|
|
26
|
+
const mem = row[0];
|
|
27
|
+
if (!mem)
|
|
28
|
+
return;
|
|
29
|
+
let updates = {};
|
|
30
|
+
if (mem.tier === 'hot')
|
|
31
|
+
updates.tier = 'warm';
|
|
32
|
+
else if (mem.tier === 'warm')
|
|
33
|
+
updates.tier = 'cold';
|
|
34
|
+
else
|
|
35
|
+
updates.status = 'expired';
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
await db.update(memories).set(updates).where(eq(memories.id, memoryId));
|
|
38
|
+
}
|
|
39
|
+
export async function expireMemory(memoryId) {
|
|
40
|
+
const db = await getDb();
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
await db.update(memories).set({ status: 'expired' }).where(eq(memories.id, memoryId));
|
|
43
|
+
}
|
|
44
|
+
export async function markMerged(memoryId, targetId) {
|
|
45
|
+
const db = await getDb();
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
await db.update(memories).set({ is_merged: true, merged_into_id: targetId }).where(eq(memories.id, memoryId));
|
|
48
|
+
}
|
|
49
|
+
export async function markSuperseded(memoryId) {
|
|
50
|
+
const db = await getDb();
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
await db.update(memories).set({ is_merged: true }).where(eq(memories.id, memoryId));
|
|
53
|
+
}
|
|
54
|
+
logger.info('Memory lifecycle helpers loaded');
|
|
55
|
+
//# sourceMappingURL=memory-lifecycle.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Migration Module
|
|
3
|
+
* Migrate memories between .squish directories/databases
|
|
4
|
+
*/
|
|
5
|
+
export interface MigrateOptions {
|
|
6
|
+
dryRun?: boolean;
|
|
7
|
+
deleteSource?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface MigrateResult {
|
|
10
|
+
memoriesCopied: number;
|
|
11
|
+
observationsCopied: number;
|
|
12
|
+
associationsCopied: number;
|
|
13
|
+
projectsMapped: number;
|
|
14
|
+
sourceDeleted?: boolean;
|
|
15
|
+
message: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Migrate memories from one .squish directory to another
|
|
19
|
+
*/
|
|
20
|
+
export declare function migrateMemories(sourceDir: string, targetDir: string, options?: MigrateOptions): Promise<MigrateResult>;
|
|
21
|
+
//# sourceMappingURL=migrate.d.ts.map
|