@smyslenny/agent-memory 4.0.0-alpha.1 → 4.1.0-alpha.1
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/dist/bin/agent-memory.js +1164 -882
- package/dist/bin/agent-memory.js.map +1 -1
- package/dist/index.d.ts +48 -6
- package/dist/index.js +124 -10
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +140 -23
- package/dist/mcp/server.js.map +1 -1
- package/docs/design/.next-id +1 -0
- package/docs/design/0016-v41-warm-boot-surface-emotion.md +228 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ interface Memory {
|
|
|
38
38
|
source: string | null;
|
|
39
39
|
agent_id: string;
|
|
40
40
|
hash: string | null;
|
|
41
|
+
emotion_tag: string | null;
|
|
41
42
|
}
|
|
42
43
|
interface CreateMemoryInput {
|
|
43
44
|
content: string;
|
|
@@ -47,6 +48,7 @@ interface CreateMemoryInput {
|
|
|
47
48
|
source?: string;
|
|
48
49
|
agent_id?: string;
|
|
49
50
|
embedding_provider_id?: string | null;
|
|
51
|
+
emotion_tag?: string;
|
|
50
52
|
}
|
|
51
53
|
interface UpdateMemoryInput {
|
|
52
54
|
content?: string;
|
|
@@ -57,6 +59,7 @@ interface UpdateMemoryInput {
|
|
|
57
59
|
stability?: number;
|
|
58
60
|
source?: string;
|
|
59
61
|
embedding_provider_id?: string | null;
|
|
62
|
+
emotion_tag?: string | null;
|
|
60
63
|
}
|
|
61
64
|
declare function contentHash(content: string): string;
|
|
62
65
|
declare function createMemory(db: Database.Database, input: CreateMemoryInput): Memory | null;
|
|
@@ -70,6 +73,7 @@ declare function listMemories(db: Database.Database, opts?: {
|
|
|
70
73
|
min_vitality?: number;
|
|
71
74
|
limit?: number;
|
|
72
75
|
offset?: number;
|
|
76
|
+
emotion_tag?: string;
|
|
73
77
|
}): Memory[];
|
|
74
78
|
declare function recordAccess(db: Database.Database, id: string, growthFactor?: number): void;
|
|
75
79
|
declare function countMemories(db: Database.Database, agent_id?: string): {
|
|
@@ -88,6 +92,7 @@ interface SyncInput {
|
|
|
88
92
|
agent_id?: string;
|
|
89
93
|
provider?: EmbeddingProvider | null;
|
|
90
94
|
conservative?: boolean;
|
|
95
|
+
emotion_tag?: string;
|
|
91
96
|
}
|
|
92
97
|
interface SyncResult {
|
|
93
98
|
action: "added" | "updated" | "merged" | "skipped";
|
|
@@ -115,6 +120,7 @@ interface RememberInput {
|
|
|
115
120
|
agent_id?: string;
|
|
116
121
|
provider?: EmbeddingProvider | null;
|
|
117
122
|
conservative?: boolean;
|
|
123
|
+
emotion_tag?: string;
|
|
118
124
|
}
|
|
119
125
|
declare function rememberMemory(db: Database.Database, input: RememberInput): Promise<SyncResult>;
|
|
120
126
|
|
|
@@ -258,6 +264,7 @@ interface RecallInput {
|
|
|
258
264
|
vectorLimit?: number;
|
|
259
265
|
provider?: EmbeddingProvider | null;
|
|
260
266
|
recordAccess?: boolean;
|
|
267
|
+
emotion_tag?: string;
|
|
261
268
|
}
|
|
262
269
|
declare function recallMemory(db: Database.Database, input: RecallInput): Promise<HybridRecallResponse>;
|
|
263
270
|
|
|
@@ -294,6 +301,7 @@ interface SurfaceInput {
|
|
|
294
301
|
agent_id?: string;
|
|
295
302
|
provider?: EmbeddingProvider | null;
|
|
296
303
|
min_vitality?: number;
|
|
304
|
+
emotion_tag?: string;
|
|
297
305
|
}
|
|
298
306
|
interface SurfaceResult {
|
|
299
307
|
memory: Memory;
|
|
@@ -713,13 +721,47 @@ interface BootResult {
|
|
|
713
721
|
identityMemories: Memory[];
|
|
714
722
|
bootPaths: string[];
|
|
715
723
|
}
|
|
724
|
+
interface WarmBootOptions {
|
|
725
|
+
agent_id?: string;
|
|
726
|
+
corePaths?: string[];
|
|
727
|
+
format?: "json" | "narrative";
|
|
728
|
+
agent_name?: string;
|
|
729
|
+
}
|
|
730
|
+
interface WarmBootResult extends BootResult {
|
|
731
|
+
narrative?: string;
|
|
732
|
+
layers?: {
|
|
733
|
+
identity: Memory[];
|
|
734
|
+
emotion: Memory[];
|
|
735
|
+
event: Memory[];
|
|
736
|
+
knowledge: Memory[];
|
|
737
|
+
};
|
|
738
|
+
}
|
|
716
739
|
/**
|
|
717
|
-
*
|
|
740
|
+
* Format a relative time string from an ISO date.
|
|
741
|
+
*/
|
|
742
|
+
declare function formatRelativeDate(isoDate: string): string;
|
|
743
|
+
/**
|
|
744
|
+
* Load layered memories for warm boot.
|
|
745
|
+
*/
|
|
746
|
+
declare function loadWarmBootLayers(db: Database.Database, agentId: string): {
|
|
747
|
+
identity: Memory[];
|
|
748
|
+
emotion: Memory[];
|
|
749
|
+
event: Memory[];
|
|
750
|
+
knowledge: Memory[];
|
|
751
|
+
};
|
|
752
|
+
/**
|
|
753
|
+
* Format layered memories as narrative Markdown.
|
|
754
|
+
*/
|
|
755
|
+
declare function formatNarrativeBoot(layers: {
|
|
756
|
+
identity: Memory[];
|
|
757
|
+
emotion: Memory[];
|
|
758
|
+
event: Memory[];
|
|
759
|
+
knowledge: Memory[];
|
|
760
|
+
}, agentName: string): string;
|
|
761
|
+
/**
|
|
762
|
+
* Load core identity memories at startup (legacy JSON format).
|
|
718
763
|
* Returns all P0 (identity) memories + any memories referenced by system://boot.
|
|
719
764
|
*/
|
|
720
|
-
declare function boot(db: Database.Database, opts?:
|
|
721
|
-
agent_id?: string;
|
|
722
|
-
corePaths?: string[];
|
|
723
|
-
}): BootResult;
|
|
765
|
+
declare function boot(db: Database.Database, opts?: WarmBootOptions): WarmBootResult;
|
|
724
766
|
|
|
725
|
-
export { type AgentMemoryHttpServer, type ReflectInput as AppReflectInput, type ReflectProgressEvent as AppReflectProgressEvent, type AutoIngestWatcher, type AutoIngestWatcherOptions, type BootResult, type CreateMemoryInput, type DedupScoreBreakdown, type EmbeddingProvider, type EmbeddingProviderConfig, type EmbeddingProviderKind, type EmbeddingProviderOptions, type EmbeddingStatus, type EvictionCandidate, type ExportResult, type FeedbackEventInput, type FeedbackEventRecord, type FeedbackSource, type FeedbackSummary, type GovernResult, type GuardAction, type GuardInput, type GuardResult, type HttpJobStatus, type HttpServerOptions, type HybridRecallResponse, type HybridRecallResult, type IngestExtractedItem, type IngestResult, type IngestRunOptions, type MaintenanceJob, type MaintenancePhase, type MaintenanceStatus, type Memory, type MemoryType, type MergeContext, type MergePlan, type Path, type PendingEmbeddingRecord, type Priority, type RecallInput, type ReflectCheckpoint, type ReflectOptions, type ReflectProgressEvent$1 as ReflectProgressEvent, type ReflectRunResult, type ReflectRunners, type ReflectStats, type ReflectStep, type ReindexEmbeddingsResult, type ReindexInput, type ReindexProgressEvent, type ReindexSearchResult, type RememberInput, type SearchResult, type StatusResult, type StoredEmbedding, type SurfaceInput, type SurfaceIntent, type SurfaceResponse, type SurfaceResult, type SyncInput, type SyncResult, type TidyResult, type UpdateMemoryInput, type VectorSearchResult, boot, buildFtsQuery, buildMergePlan, calculateVitality, classifyIngestType, completeMaintenanceJob, computeEvictionScore, contentHash, cosineSimilarity, countMemories, createEmbeddingProvider, createHttpServer, createInitialCheckpoint, createLocalHttpEmbeddingProvider, createMaintenanceJob, createMemory, createOpenAICompatibleEmbeddingProvider, createPath, decodeVector, deleteMemory, deletePath, encodeVector, exportMemories, extractIngestItems, failMaintenanceJob, findResumableMaintenanceJob, fuseHybridResults, fusionScore, getConfiguredEmbeddingProviderId, getDecayedMemories, getEmbedding, getEmbeddingProvider, getEmbeddingProviderConfigFromEnv, getEmbeddingProviderFromEnv, getFeedbackScore, getFeedbackSummary, getMaintenanceJob, getMemory, getMemoryStatus, getPath, getPathByUri, getPathsByDomain, getPathsByMemory, getPathsByPrefix, guard, healthcheckEmbeddingProvider, ingestText, listMemories, listPendingEmbeddings, markAllEmbeddingsPending, markEmbeddingFailed, markMemoryEmbeddingPending, parseUri, priorityPrior, rankEvictionCandidates, rebuildBm25Index, recallMemories, recallMemory, recordAccess, recordFeedbackEvent, reflectMemories, reindexEmbeddings, reindexMemories, reindexMemorySearch, rememberMemory, runAutoIngestWatcher, runDecay, runGovern, runReflectOrchestrator, runTidy, searchBM25, searchByVector, slugify, splitIngestBlocks, startHttpServer, surfaceMemories, syncBatch, syncOne, tokenize, updateMaintenanceCheckpoint, updateMemory, upsertReadyEmbedding };
|
|
767
|
+
export { type AgentMemoryHttpServer, type ReflectInput as AppReflectInput, type ReflectProgressEvent as AppReflectProgressEvent, type AutoIngestWatcher, type AutoIngestWatcherOptions, type BootResult, type CreateMemoryInput, type DedupScoreBreakdown, type EmbeddingProvider, type EmbeddingProviderConfig, type EmbeddingProviderKind, type EmbeddingProviderOptions, type EmbeddingStatus, type EvictionCandidate, type ExportResult, type FeedbackEventInput, type FeedbackEventRecord, type FeedbackSource, type FeedbackSummary, type GovernResult, type GuardAction, type GuardInput, type GuardResult, type HttpJobStatus, type HttpServerOptions, type HybridRecallResponse, type HybridRecallResult, type IngestExtractedItem, type IngestResult, type IngestRunOptions, type MaintenanceJob, type MaintenancePhase, type MaintenanceStatus, type Memory, type MemoryType, type MergeContext, type MergePlan, type Path, type PendingEmbeddingRecord, type Priority, type RecallInput, type ReflectCheckpoint, type ReflectOptions, type ReflectProgressEvent$1 as ReflectProgressEvent, type ReflectRunResult, type ReflectRunners, type ReflectStats, type ReflectStep, type ReindexEmbeddingsResult, type ReindexInput, type ReindexProgressEvent, type ReindexSearchResult, type RememberInput, type SearchResult, type StatusResult, type StoredEmbedding, type SurfaceInput, type SurfaceIntent, type SurfaceResponse, type SurfaceResult, type SyncInput, type SyncResult, type TidyResult, type UpdateMemoryInput, type VectorSearchResult, type WarmBootOptions, type WarmBootResult, boot, buildFtsQuery, buildMergePlan, calculateVitality, classifyIngestType, completeMaintenanceJob, computeEvictionScore, contentHash, cosineSimilarity, countMemories, createEmbeddingProvider, createHttpServer, createInitialCheckpoint, createLocalHttpEmbeddingProvider, createMaintenanceJob, createMemory, createOpenAICompatibleEmbeddingProvider, createPath, decodeVector, deleteMemory, deletePath, encodeVector, exportMemories, extractIngestItems, failMaintenanceJob, findResumableMaintenanceJob, formatNarrativeBoot, formatRelativeDate, fuseHybridResults, fusionScore, getConfiguredEmbeddingProviderId, getDecayedMemories, getEmbedding, getEmbeddingProvider, getEmbeddingProviderConfigFromEnv, getEmbeddingProviderFromEnv, getFeedbackScore, getFeedbackSummary, getMaintenanceJob, getMemory, getMemoryStatus, getPath, getPathByUri, getPathsByDomain, getPathsByMemory, getPathsByPrefix, guard, healthcheckEmbeddingProvider, ingestText, listMemories, listPendingEmbeddings, loadWarmBootLayers, markAllEmbeddingsPending, markEmbeddingFailed, markMemoryEmbeddingPending, parseUri, priorityPrior, rankEvictionCandidates, rebuildBm25Index, recallMemories, recallMemory, recordAccess, recordFeedbackEvent, reflectMemories, reindexEmbeddings, reindexMemories, reindexMemorySearch, rememberMemory, runAutoIngestWatcher, runDecay, runGovern, runReflectOrchestrator, runTidy, searchBM25, searchByVector, slugify, splitIngestBlocks, startHttpServer, surfaceMemories, syncBatch, syncOne, tokenize, updateMaintenanceCheckpoint, updateMemory, upsertReadyEmbedding };
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { createHash as createHash2 } from "crypto";
|
|
|
6
6
|
// src/core/db.ts
|
|
7
7
|
import Database from "better-sqlite3";
|
|
8
8
|
import { randomUUID } from "crypto";
|
|
9
|
-
var SCHEMA_VERSION =
|
|
9
|
+
var SCHEMA_VERSION = 6;
|
|
10
10
|
var SCHEMA_SQL = `
|
|
11
11
|
-- Memory entries
|
|
12
12
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -24,6 +24,7 @@ CREATE TABLE IF NOT EXISTS memories (
|
|
|
24
24
|
source TEXT,
|
|
25
25
|
agent_id TEXT NOT NULL DEFAULT 'default',
|
|
26
26
|
hash TEXT,
|
|
27
|
+
emotion_tag TEXT,
|
|
27
28
|
UNIQUE(hash, agent_id)
|
|
28
29
|
);
|
|
29
30
|
|
|
@@ -199,6 +200,11 @@ function migrateDatabase(db, from, to) {
|
|
|
199
200
|
v = 5;
|
|
200
201
|
continue;
|
|
201
202
|
}
|
|
203
|
+
if (v === 5) {
|
|
204
|
+
migrateV5ToV6(db);
|
|
205
|
+
v = 6;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
202
208
|
throw new Error(`Unsupported schema migration path: v${from} \u2192 v${to} (stuck at v${v})`);
|
|
203
209
|
}
|
|
204
210
|
}
|
|
@@ -284,6 +290,8 @@ function inferSchemaVersion(db) {
|
|
|
284
290
|
const hasV4Embeddings = hasEmbeddings && tableHasColumn(db, "embeddings", "provider_id") && tableHasColumn(db, "embeddings", "status") && tableHasColumn(db, "embeddings", "content_hash") && tableHasColumn(db, "embeddings", "id");
|
|
285
291
|
const hasMaintenanceJobs = tableExists(db, "maintenance_jobs");
|
|
286
292
|
const hasFeedbackEvents = tableExists(db, "feedback_events");
|
|
293
|
+
const hasEmotionTag = tableHasColumn(db, "memories", "emotion_tag");
|
|
294
|
+
if (hasAgentScopedPaths && hasAgentScopedLinks && hasV4Embeddings && hasMaintenanceJobs && hasFeedbackEvents && hasEmotionTag) return 6;
|
|
287
295
|
if (hasAgentScopedPaths && hasAgentScopedLinks && hasV4Embeddings && hasMaintenanceJobs && hasFeedbackEvents) return 5;
|
|
288
296
|
if (hasAgentScopedPaths && hasAgentScopedLinks && hasV4Embeddings) return 4;
|
|
289
297
|
if (hasAgentScopedPaths && hasAgentScopedLinks && hasEmbeddings) return 3;
|
|
@@ -310,6 +318,9 @@ function ensureIndexes(db) {
|
|
|
310
318
|
if (tableExists(db, "maintenance_jobs")) {
|
|
311
319
|
db.exec("CREATE INDEX IF NOT EXISTS idx_maintenance_jobs_phase_status ON maintenance_jobs(phase, status, started_at DESC);");
|
|
312
320
|
}
|
|
321
|
+
if (tableHasColumn(db, "memories", "emotion_tag")) {
|
|
322
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_memories_emotion_tag ON memories(emotion_tag) WHERE emotion_tag IS NOT NULL;");
|
|
323
|
+
}
|
|
313
324
|
if (tableExists(db, "feedback_events")) {
|
|
314
325
|
db.exec("CREATE INDEX IF NOT EXISTS idx_feedback_events_memory ON feedback_events(memory_id, created_at DESC);");
|
|
315
326
|
if (tableHasColumn(db, "feedback_events", "agent_id") && tableHasColumn(db, "feedback_events", "source")) {
|
|
@@ -443,6 +454,25 @@ function migrateV4ToV5(db) {
|
|
|
443
454
|
throw e;
|
|
444
455
|
}
|
|
445
456
|
}
|
|
457
|
+
function migrateV5ToV6(db) {
|
|
458
|
+
if (tableHasColumn(db, "memories", "emotion_tag")) {
|
|
459
|
+
db.prepare("INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('version', ?)").run(String(6));
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
try {
|
|
463
|
+
db.exec("BEGIN");
|
|
464
|
+
db.exec("ALTER TABLE memories ADD COLUMN emotion_tag TEXT;");
|
|
465
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_memories_emotion_tag ON memories(emotion_tag) WHERE emotion_tag IS NOT NULL;");
|
|
466
|
+
db.prepare("INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('version', ?)").run(String(6));
|
|
467
|
+
db.exec("COMMIT");
|
|
468
|
+
} catch (e) {
|
|
469
|
+
try {
|
|
470
|
+
db.exec("ROLLBACK");
|
|
471
|
+
} catch {
|
|
472
|
+
}
|
|
473
|
+
throw e;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
446
476
|
|
|
447
477
|
// src/search/tokenizer.ts
|
|
448
478
|
import { readFileSync } from "fs";
|
|
@@ -942,8 +972,8 @@ function createMemory(db, input) {
|
|
|
942
972
|
const timestamp = now();
|
|
943
973
|
db.prepare(
|
|
944
974
|
`INSERT INTO memories (id, content, type, priority, emotion_val, vitality, stability,
|
|
945
|
-
access_count, created_at, updated_at, source, agent_id, hash)
|
|
946
|
-
VALUES (?, ?, ?, ?, ?, 1.0, ?, 0, ?, ?, ?, ?, ?)`
|
|
975
|
+
access_count, created_at, updated_at, source, agent_id, hash, emotion_tag)
|
|
976
|
+
VALUES (?, ?, ?, ?, ?, 1.0, ?, 0, ?, ?, ?, ?, ?, ?)`
|
|
947
977
|
).run(
|
|
948
978
|
id,
|
|
949
979
|
input.content,
|
|
@@ -955,7 +985,8 @@ function createMemory(db, input) {
|
|
|
955
985
|
timestamp,
|
|
956
986
|
input.source ?? null,
|
|
957
987
|
agentId,
|
|
958
|
-
hash
|
|
988
|
+
hash,
|
|
989
|
+
input.emotion_tag ?? null
|
|
959
990
|
);
|
|
960
991
|
db.prepare("INSERT INTO memories_fts (id, content) VALUES (?, ?)").run(id, tokenizeForIndex(input.content));
|
|
961
992
|
markEmbeddingDirtyIfNeeded(db, id, hash, resolveEmbeddingProviderId(input.embedding_provider_id));
|
|
@@ -999,6 +1030,10 @@ function updateMemory(db, id, input) {
|
|
|
999
1030
|
fields.push("source = ?");
|
|
1000
1031
|
values.push(input.source);
|
|
1001
1032
|
}
|
|
1033
|
+
if (input.emotion_tag !== void 0) {
|
|
1034
|
+
fields.push("emotion_tag = ?");
|
|
1035
|
+
values.push(input.emotion_tag);
|
|
1036
|
+
}
|
|
1002
1037
|
fields.push("updated_at = ?");
|
|
1003
1038
|
values.push(now());
|
|
1004
1039
|
values.push(id);
|
|
@@ -1040,6 +1075,10 @@ function listMemories(db, opts) {
|
|
|
1040
1075
|
conditions.push("vitality >= ?");
|
|
1041
1076
|
params.push(opts.min_vitality);
|
|
1042
1077
|
}
|
|
1078
|
+
if (opts?.emotion_tag) {
|
|
1079
|
+
conditions.push("emotion_tag = ?");
|
|
1080
|
+
params.push(opts.emotion_tag);
|
|
1081
|
+
}
|
|
1043
1082
|
const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1044
1083
|
const limit = opts?.limit ?? 100;
|
|
1045
1084
|
const offset = opts?.offset ?? 0;
|
|
@@ -1703,7 +1742,8 @@ async function syncOne(db, input) {
|
|
|
1703
1742
|
agent_id: input.agent_id,
|
|
1704
1743
|
uri: input.uri,
|
|
1705
1744
|
provider: input.provider,
|
|
1706
|
-
conservative: input.conservative
|
|
1745
|
+
conservative: input.conservative,
|
|
1746
|
+
emotion_tag: input.emotion_tag
|
|
1707
1747
|
};
|
|
1708
1748
|
const guardResult = await guard(db, memInput);
|
|
1709
1749
|
switch (guardResult.action) {
|
|
@@ -1752,21 +1792,26 @@ async function rememberMemory(db, input) {
|
|
|
1752
1792
|
source: input.source,
|
|
1753
1793
|
agent_id: input.agent_id,
|
|
1754
1794
|
provider: input.provider,
|
|
1755
|
-
conservative: input.conservative
|
|
1795
|
+
conservative: input.conservative,
|
|
1796
|
+
emotion_tag: input.emotion_tag
|
|
1756
1797
|
});
|
|
1757
1798
|
}
|
|
1758
1799
|
|
|
1759
1800
|
// src/app/recall.ts
|
|
1760
1801
|
async function recallMemory(db, input) {
|
|
1761
|
-
|
|
1802
|
+
const result = await recallMemories(db, input.query, {
|
|
1762
1803
|
agent_id: input.agent_id,
|
|
1763
|
-
limit: input.limit,
|
|
1804
|
+
limit: input.emotion_tag ? (input.limit ?? 10) * 3 : input.limit,
|
|
1764
1805
|
min_vitality: input.min_vitality,
|
|
1765
1806
|
lexicalLimit: input.lexicalLimit,
|
|
1766
1807
|
vectorLimit: input.vectorLimit,
|
|
1767
1808
|
provider: input.provider,
|
|
1768
1809
|
recordAccess: input.recordAccess
|
|
1769
1810
|
});
|
|
1811
|
+
if (input.emotion_tag) {
|
|
1812
|
+
result.results = result.results.filter((r) => r.memory.emotion_tag === input.emotion_tag).slice(0, input.limit ?? 10);
|
|
1813
|
+
}
|
|
1814
|
+
return result;
|
|
1770
1815
|
}
|
|
1771
1816
|
|
|
1772
1817
|
// src/app/feedback.ts
|
|
@@ -2043,7 +2088,7 @@ async function surfaceMemories(db, input) {
|
|
|
2043
2088
|
signals.set(memory.id, { memory });
|
|
2044
2089
|
}
|
|
2045
2090
|
}
|
|
2046
|
-
const results = [...signals.values()].map((signal) => signal.memory).filter((memory) => memory.vitality >= minVitality).filter((memory) => input.types?.length ? input.types.includes(memory.type) : true).map((memory) => {
|
|
2091
|
+
const results = [...signals.values()].map((signal) => signal.memory).filter((memory) => memory.vitality >= minVitality).filter((memory) => input.types?.length ? input.types.includes(memory.type) : true).filter((memory) => input.emotion_tag ? memory.emotion_tag === input.emotion_tag : true).map((memory) => {
|
|
2047
2092
|
const signal = signals.get(memory.id) ?? { memory };
|
|
2048
2093
|
const memoryTokens = new Set(tokenize(memory.content));
|
|
2049
2094
|
const lexicalOverlap = overlapScore2(memoryTokens, queryTokens);
|
|
@@ -3307,8 +3352,68 @@ function runAutoIngestWatcher(options) {
|
|
|
3307
3352
|
}
|
|
3308
3353
|
|
|
3309
3354
|
// src/sleep/boot.ts
|
|
3355
|
+
function formatRelativeDate(isoDate) {
|
|
3356
|
+
const diffMs = Date.now() - new Date(isoDate).getTime();
|
|
3357
|
+
const diffDays = Math.floor(diffMs / 864e5);
|
|
3358
|
+
if (diffDays <= 0) return "\u4ECA\u5929";
|
|
3359
|
+
if (diffDays === 1) return "\u6628\u5929";
|
|
3360
|
+
if (diffDays <= 7) return `${diffDays}\u5929\u524D`;
|
|
3361
|
+
return isoDate.slice(0, 10);
|
|
3362
|
+
}
|
|
3363
|
+
function loadWarmBootLayers(db, agentId) {
|
|
3364
|
+
const identity = listMemories(db, { agent_id: agentId, type: "identity", limit: 50 });
|
|
3365
|
+
const emotion = listMemories(db, { agent_id: agentId, type: "emotion", limit: 5 });
|
|
3366
|
+
const event = listMemories(db, { agent_id: agentId, type: "event", limit: 7 });
|
|
3367
|
+
const knowledge = listMemories(db, {
|
|
3368
|
+
agent_id: agentId,
|
|
3369
|
+
type: "knowledge",
|
|
3370
|
+
min_vitality: 0.5,
|
|
3371
|
+
limit: 10
|
|
3372
|
+
});
|
|
3373
|
+
return { identity, emotion, event, knowledge };
|
|
3374
|
+
}
|
|
3375
|
+
function formatNarrativeBoot(layers, agentName) {
|
|
3376
|
+
const lines = [];
|
|
3377
|
+
lines.push(`# ${agentName}\u7684\u56DE\u5FC6`);
|
|
3378
|
+
lines.push("");
|
|
3379
|
+
if (layers.identity.length > 0) {
|
|
3380
|
+
lines.push("## \u6211\u662F\u8C01");
|
|
3381
|
+
for (const mem of layers.identity) {
|
|
3382
|
+
lines.push(`- ${mem.content.split("\n")[0].slice(0, 200)}`);
|
|
3383
|
+
}
|
|
3384
|
+
lines.push("");
|
|
3385
|
+
}
|
|
3386
|
+
if (layers.emotion.length > 0) {
|
|
3387
|
+
lines.push("## \u6700\u8FD1\u7684\u5FC3\u60C5");
|
|
3388
|
+
for (const mem of layers.emotion) {
|
|
3389
|
+
const tag = mem.emotion_tag;
|
|
3390
|
+
const time = formatRelativeDate(mem.updated_at);
|
|
3391
|
+
const tagStr = tag ? `${tag}, ${time}` : time;
|
|
3392
|
+
lines.push(`- ${mem.content.split("\n")[0].slice(0, 200)} (${tagStr})`);
|
|
3393
|
+
}
|
|
3394
|
+
lines.push("");
|
|
3395
|
+
}
|
|
3396
|
+
if (layers.event.length > 0) {
|
|
3397
|
+
lines.push("## \u6700\u8FD1\u53D1\u751F\u7684\u4E8B");
|
|
3398
|
+
for (const mem of layers.event) {
|
|
3399
|
+
const time = formatRelativeDate(mem.updated_at);
|
|
3400
|
+
lines.push(`- ${mem.content.split("\n")[0].slice(0, 200)} (${time})`);
|
|
3401
|
+
}
|
|
3402
|
+
lines.push("");
|
|
3403
|
+
}
|
|
3404
|
+
if (layers.knowledge.length > 0) {
|
|
3405
|
+
lines.push("## \u8FD8\u8BB0\u5F97\u7684\u77E5\u8BC6");
|
|
3406
|
+
for (const mem of layers.knowledge) {
|
|
3407
|
+
lines.push(`- ${mem.content.split("\n")[0].slice(0, 200)}`);
|
|
3408
|
+
}
|
|
3409
|
+
lines.push("");
|
|
3410
|
+
}
|
|
3411
|
+
return lines.join("\n");
|
|
3412
|
+
}
|
|
3310
3413
|
function boot(db, opts) {
|
|
3311
3414
|
const agentId = opts?.agent_id ?? "default";
|
|
3415
|
+
const format = opts?.format ?? "json";
|
|
3416
|
+
const agentName = opts?.agent_name ?? "Agent";
|
|
3312
3417
|
const corePaths = opts?.corePaths ?? [
|
|
3313
3418
|
"core://agent",
|
|
3314
3419
|
"core://user",
|
|
@@ -3352,10 +3457,16 @@ function boot(db, opts) {
|
|
|
3352
3457
|
}
|
|
3353
3458
|
}
|
|
3354
3459
|
}
|
|
3355
|
-
|
|
3460
|
+
const result = {
|
|
3356
3461
|
identityMemories: [...memories.values()],
|
|
3357
3462
|
bootPaths
|
|
3358
3463
|
};
|
|
3464
|
+
if (format === "narrative") {
|
|
3465
|
+
const layers = loadWarmBootLayers(db, agentId);
|
|
3466
|
+
result.layers = layers;
|
|
3467
|
+
result.narrative = formatNarrativeBoot(layers, agentName);
|
|
3468
|
+
}
|
|
3469
|
+
return result;
|
|
3359
3470
|
}
|
|
3360
3471
|
export {
|
|
3361
3472
|
boot,
|
|
@@ -3384,6 +3495,8 @@ export {
|
|
|
3384
3495
|
extractIngestItems,
|
|
3385
3496
|
failMaintenanceJob,
|
|
3386
3497
|
findResumableMaintenanceJob,
|
|
3498
|
+
formatNarrativeBoot,
|
|
3499
|
+
formatRelativeDate,
|
|
3387
3500
|
fuseHybridResults,
|
|
3388
3501
|
fusionScore,
|
|
3389
3502
|
getConfiguredEmbeddingProviderId,
|
|
@@ -3408,6 +3521,7 @@ export {
|
|
|
3408
3521
|
isCountRow,
|
|
3409
3522
|
listMemories,
|
|
3410
3523
|
listPendingEmbeddings,
|
|
3524
|
+
loadWarmBootLayers,
|
|
3411
3525
|
markAllEmbeddingsPending,
|
|
3412
3526
|
markEmbeddingFailed,
|
|
3413
3527
|
markMemoryEmbeddingPending,
|