@memstack/core 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +213 -49
- package/dist/index.cjs +268 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -1
- package/dist/index.d.ts +42 -1
- package/dist/index.js +268 -8
- package/dist/index.js.map +1 -1
- package/package.json +21 -18
package/dist/index.d.cts
CHANGED
|
@@ -148,7 +148,10 @@ interface LLMProvider {
|
|
|
148
148
|
}
|
|
149
149
|
interface EmbeddingProvider {
|
|
150
150
|
embed(texts: string[]): Promise<number[][]>;
|
|
151
|
+
/** Vector dimension length (e.g., 1536 for text-embedding-3-small). */
|
|
151
152
|
dimensions: number;
|
|
153
|
+
/** Maximum number of texts per embed() call. Default: 2048. */
|
|
154
|
+
maxBatchSize?: number;
|
|
152
155
|
}
|
|
153
156
|
interface StorageProvider {
|
|
154
157
|
initialize(): Promise<void>;
|
|
@@ -817,6 +820,42 @@ declare class MongoDBStorageAdapter implements StorageProvider {
|
|
|
817
820
|
private toDoc;
|
|
818
821
|
}
|
|
819
822
|
|
|
823
|
+
type BetterSqlite3Db = {
|
|
824
|
+
exec(sql: string): void;
|
|
825
|
+
prepare(sql: string): {
|
|
826
|
+
run(...params: unknown[]): {
|
|
827
|
+
changes: number;
|
|
828
|
+
lastInsertRowid: number | bigint;
|
|
829
|
+
};
|
|
830
|
+
get(...params: unknown[]): unknown | undefined;
|
|
831
|
+
all(...params: unknown[]): unknown[];
|
|
832
|
+
};
|
|
833
|
+
close(): void;
|
|
834
|
+
};
|
|
835
|
+
interface SQLiteStorageConfig {
|
|
836
|
+
db: BetterSqlite3Db;
|
|
837
|
+
tableName?: string;
|
|
838
|
+
vectorDimensions?: number;
|
|
839
|
+
}
|
|
840
|
+
declare class SQLiteStorageAdapter implements StorageProvider {
|
|
841
|
+
private db;
|
|
842
|
+
private table;
|
|
843
|
+
private vectorDimensions;
|
|
844
|
+
constructor(config: SQLiteStorageConfig);
|
|
845
|
+
initialize(): Promise<void>;
|
|
846
|
+
generateId(): string;
|
|
847
|
+
store(input: MemoryStoreInput): Promise<Memory>;
|
|
848
|
+
storeBatch(inputs: MemoryStoreInput[]): Promise<Memory[]>;
|
|
849
|
+
get(id: string): Promise<Memory | null>;
|
|
850
|
+
delete(id: string): Promise<void>;
|
|
851
|
+
deleteMany(ids: string[]): Promise<number>;
|
|
852
|
+
touch(id: string): Promise<void>;
|
|
853
|
+
retrieve(query: MemoryRetrieveQuery, embedding?: number[]): Promise<Memory[]>;
|
|
854
|
+
count(filter?: MemoryCountFilter): Promise<number>;
|
|
855
|
+
close(): Promise<void>;
|
|
856
|
+
private _rowToMemory;
|
|
857
|
+
}
|
|
858
|
+
|
|
820
859
|
interface OpenAILLMConfig {
|
|
821
860
|
apiKey: string;
|
|
822
861
|
baseURL?: string;
|
|
@@ -900,6 +939,7 @@ declare class OpenAIEmbeddingAdapter implements EmbeddingProvider {
|
|
|
900
939
|
private baseURL;
|
|
901
940
|
private model;
|
|
902
941
|
readonly dimensions: number;
|
|
942
|
+
readonly maxBatchSize = 2048;
|
|
903
943
|
constructor(config: OpenAIEmbeddingConfig);
|
|
904
944
|
embed(texts: string[]): Promise<number[][]>;
|
|
905
945
|
}
|
|
@@ -917,6 +957,7 @@ declare class CohereEmbeddingAdapter implements EmbeddingProvider {
|
|
|
917
957
|
private baseURL;
|
|
918
958
|
private model;
|
|
919
959
|
readonly dimensions: number;
|
|
960
|
+
readonly maxBatchSize = 96;
|
|
920
961
|
constructor(config: CohereEmbeddingConfig);
|
|
921
962
|
embed(texts: string[]): Promise<number[][]>;
|
|
922
963
|
}
|
|
@@ -1002,4 +1043,4 @@ declare class GroqLLMAdapter implements LLMProvider {
|
|
|
1002
1043
|
}>;
|
|
1003
1044
|
}
|
|
1004
1045
|
|
|
1005
|
-
export { AnthropicLLMAdapter, type AnthropicLLMConfig, CohereEmbeddingAdapter, type CohereEmbeddingConfig, type CompiledContext, type ContextOptions, DiskStorageAdapter, type DiskStorageConfig, type EmbeddingProvider, GroqLLMAdapter, type GroqLLMConfig, type HealthStatus, HybridStorageAdapter, type HybridStorageConfig, InMemoryStorageAdapter, type LLMProvider, LanceDBStorageAdapter, type LanceDBStorageConfig, MarkdownStorageAdapter, type MarkdownStorageConfig, MemStack, type MemStackConfig, MemStackError, type MemStackErrorCode, type MemStackSnapshot, type Memory, type MemoryCountFilter, type MemoryRetrieveQuery, type MemoryStats, type MemoryStoreInput, type MemoryType, MongoDBStorageAdapter, type MongoDBStorageConfig, Neo4jStorageAdapter, type Neo4jStorageConfig, OllamaLLMAdapter, type OllamaLLMConfig, OpenAIEmbeddingAdapter, type OpenAIEmbeddingConfig, OpenAILLMAdapter, type OpenAILLMConfig, PostgresStorageAdapter, type PostgresStorageConfig, type ProcessInput, type ProcessResult, type PruneStrategy, QdrantStorageAdapter, type QdrantStorageConfig, RedisStorageAdapter, type RedisStorageConfig, type StorageProvider, type SummarizeOptions, WeaviateStorageAdapter, type WeaviateStorageConfig, configError, notFound, storageError, validationError };
|
|
1046
|
+
export { AnthropicLLMAdapter, type AnthropicLLMConfig, CohereEmbeddingAdapter, type CohereEmbeddingConfig, type CompiledContext, type ContextOptions, DiskStorageAdapter, type DiskStorageConfig, type EmbeddingProvider, GroqLLMAdapter, type GroqLLMConfig, type HealthStatus, HybridStorageAdapter, type HybridStorageConfig, InMemoryStorageAdapter, type LLMProvider, LanceDBStorageAdapter, type LanceDBStorageConfig, MarkdownStorageAdapter, type MarkdownStorageConfig, MemStack, type MemStackConfig, MemStackError, type MemStackErrorCode, type MemStackSnapshot, type Memory, type MemoryCountFilter, type MemoryRetrieveQuery, type MemoryStats, type MemoryStoreInput, type MemoryType, MongoDBStorageAdapter, type MongoDBStorageConfig, Neo4jStorageAdapter, type Neo4jStorageConfig, OllamaLLMAdapter, type OllamaLLMConfig, OpenAIEmbeddingAdapter, type OpenAIEmbeddingConfig, OpenAILLMAdapter, type OpenAILLMConfig, PostgresStorageAdapter, type PostgresStorageConfig, type ProcessInput, type ProcessResult, type PruneStrategy, QdrantStorageAdapter, type QdrantStorageConfig, RedisStorageAdapter, type RedisStorageConfig, SQLiteStorageAdapter, type SQLiteStorageConfig, type StorageProvider, type SummarizeOptions, WeaviateStorageAdapter, type WeaviateStorageConfig, configError, notFound, storageError, validationError };
|
package/dist/index.d.ts
CHANGED
|
@@ -148,7 +148,10 @@ interface LLMProvider {
|
|
|
148
148
|
}
|
|
149
149
|
interface EmbeddingProvider {
|
|
150
150
|
embed(texts: string[]): Promise<number[][]>;
|
|
151
|
+
/** Vector dimension length (e.g., 1536 for text-embedding-3-small). */
|
|
151
152
|
dimensions: number;
|
|
153
|
+
/** Maximum number of texts per embed() call. Default: 2048. */
|
|
154
|
+
maxBatchSize?: number;
|
|
152
155
|
}
|
|
153
156
|
interface StorageProvider {
|
|
154
157
|
initialize(): Promise<void>;
|
|
@@ -817,6 +820,42 @@ declare class MongoDBStorageAdapter implements StorageProvider {
|
|
|
817
820
|
private toDoc;
|
|
818
821
|
}
|
|
819
822
|
|
|
823
|
+
type BetterSqlite3Db = {
|
|
824
|
+
exec(sql: string): void;
|
|
825
|
+
prepare(sql: string): {
|
|
826
|
+
run(...params: unknown[]): {
|
|
827
|
+
changes: number;
|
|
828
|
+
lastInsertRowid: number | bigint;
|
|
829
|
+
};
|
|
830
|
+
get(...params: unknown[]): unknown | undefined;
|
|
831
|
+
all(...params: unknown[]): unknown[];
|
|
832
|
+
};
|
|
833
|
+
close(): void;
|
|
834
|
+
};
|
|
835
|
+
interface SQLiteStorageConfig {
|
|
836
|
+
db: BetterSqlite3Db;
|
|
837
|
+
tableName?: string;
|
|
838
|
+
vectorDimensions?: number;
|
|
839
|
+
}
|
|
840
|
+
declare class SQLiteStorageAdapter implements StorageProvider {
|
|
841
|
+
private db;
|
|
842
|
+
private table;
|
|
843
|
+
private vectorDimensions;
|
|
844
|
+
constructor(config: SQLiteStorageConfig);
|
|
845
|
+
initialize(): Promise<void>;
|
|
846
|
+
generateId(): string;
|
|
847
|
+
store(input: MemoryStoreInput): Promise<Memory>;
|
|
848
|
+
storeBatch(inputs: MemoryStoreInput[]): Promise<Memory[]>;
|
|
849
|
+
get(id: string): Promise<Memory | null>;
|
|
850
|
+
delete(id: string): Promise<void>;
|
|
851
|
+
deleteMany(ids: string[]): Promise<number>;
|
|
852
|
+
touch(id: string): Promise<void>;
|
|
853
|
+
retrieve(query: MemoryRetrieveQuery, embedding?: number[]): Promise<Memory[]>;
|
|
854
|
+
count(filter?: MemoryCountFilter): Promise<number>;
|
|
855
|
+
close(): Promise<void>;
|
|
856
|
+
private _rowToMemory;
|
|
857
|
+
}
|
|
858
|
+
|
|
820
859
|
interface OpenAILLMConfig {
|
|
821
860
|
apiKey: string;
|
|
822
861
|
baseURL?: string;
|
|
@@ -900,6 +939,7 @@ declare class OpenAIEmbeddingAdapter implements EmbeddingProvider {
|
|
|
900
939
|
private baseURL;
|
|
901
940
|
private model;
|
|
902
941
|
readonly dimensions: number;
|
|
942
|
+
readonly maxBatchSize = 2048;
|
|
903
943
|
constructor(config: OpenAIEmbeddingConfig);
|
|
904
944
|
embed(texts: string[]): Promise<number[][]>;
|
|
905
945
|
}
|
|
@@ -917,6 +957,7 @@ declare class CohereEmbeddingAdapter implements EmbeddingProvider {
|
|
|
917
957
|
private baseURL;
|
|
918
958
|
private model;
|
|
919
959
|
readonly dimensions: number;
|
|
960
|
+
readonly maxBatchSize = 96;
|
|
920
961
|
constructor(config: CohereEmbeddingConfig);
|
|
921
962
|
embed(texts: string[]): Promise<number[][]>;
|
|
922
963
|
}
|
|
@@ -1002,4 +1043,4 @@ declare class GroqLLMAdapter implements LLMProvider {
|
|
|
1002
1043
|
}>;
|
|
1003
1044
|
}
|
|
1004
1045
|
|
|
1005
|
-
export { AnthropicLLMAdapter, type AnthropicLLMConfig, CohereEmbeddingAdapter, type CohereEmbeddingConfig, type CompiledContext, type ContextOptions, DiskStorageAdapter, type DiskStorageConfig, type EmbeddingProvider, GroqLLMAdapter, type GroqLLMConfig, type HealthStatus, HybridStorageAdapter, type HybridStorageConfig, InMemoryStorageAdapter, type LLMProvider, LanceDBStorageAdapter, type LanceDBStorageConfig, MarkdownStorageAdapter, type MarkdownStorageConfig, MemStack, type MemStackConfig, MemStackError, type MemStackErrorCode, type MemStackSnapshot, type Memory, type MemoryCountFilter, type MemoryRetrieveQuery, type MemoryStats, type MemoryStoreInput, type MemoryType, MongoDBStorageAdapter, type MongoDBStorageConfig, Neo4jStorageAdapter, type Neo4jStorageConfig, OllamaLLMAdapter, type OllamaLLMConfig, OpenAIEmbeddingAdapter, type OpenAIEmbeddingConfig, OpenAILLMAdapter, type OpenAILLMConfig, PostgresStorageAdapter, type PostgresStorageConfig, type ProcessInput, type ProcessResult, type PruneStrategy, QdrantStorageAdapter, type QdrantStorageConfig, RedisStorageAdapter, type RedisStorageConfig, type StorageProvider, type SummarizeOptions, WeaviateStorageAdapter, type WeaviateStorageConfig, configError, notFound, storageError, validationError };
|
|
1046
|
+
export { AnthropicLLMAdapter, type AnthropicLLMConfig, CohereEmbeddingAdapter, type CohereEmbeddingConfig, type CompiledContext, type ContextOptions, DiskStorageAdapter, type DiskStorageConfig, type EmbeddingProvider, GroqLLMAdapter, type GroqLLMConfig, type HealthStatus, HybridStorageAdapter, type HybridStorageConfig, InMemoryStorageAdapter, type LLMProvider, LanceDBStorageAdapter, type LanceDBStorageConfig, MarkdownStorageAdapter, type MarkdownStorageConfig, MemStack, type MemStackConfig, MemStackError, type MemStackErrorCode, type MemStackSnapshot, type Memory, type MemoryCountFilter, type MemoryRetrieveQuery, type MemoryStats, type MemoryStoreInput, type MemoryType, MongoDBStorageAdapter, type MongoDBStorageConfig, Neo4jStorageAdapter, type Neo4jStorageConfig, OllamaLLMAdapter, type OllamaLLMConfig, OpenAIEmbeddingAdapter, type OpenAIEmbeddingConfig, OpenAILLMAdapter, type OpenAILLMConfig, PostgresStorageAdapter, type PostgresStorageConfig, type ProcessInput, type ProcessResult, type PruneStrategy, QdrantStorageAdapter, type QdrantStorageConfig, RedisStorageAdapter, type RedisStorageConfig, SQLiteStorageAdapter, type SQLiteStorageConfig, type StorageProvider, type SummarizeOptions, WeaviateStorageAdapter, type WeaviateStorageConfig, configError, notFound, storageError, validationError };
|
package/dist/index.js
CHANGED
|
@@ -358,7 +358,6 @@ var ContextCompiler = class {
|
|
|
358
358
|
};
|
|
359
359
|
|
|
360
360
|
// src/memory/MemoryStore.ts
|
|
361
|
-
var EMBEDDING_BATCH_SIZE = 2048;
|
|
362
361
|
var MemoryStore = class {
|
|
363
362
|
storage;
|
|
364
363
|
embedding;
|
|
@@ -447,8 +446,9 @@ var MemoryStore = class {
|
|
|
447
446
|
let stored;
|
|
448
447
|
if (this.embedding && this.embedOnStore) {
|
|
449
448
|
const enrichedResults = [];
|
|
450
|
-
|
|
451
|
-
|
|
449
|
+
const batchSize = this.embedding.maxBatchSize ?? 2048;
|
|
450
|
+
for (let i = 0; i < normalInputs.length; i += batchSize) {
|
|
451
|
+
const batch = normalInputs.slice(i, i + batchSize);
|
|
452
452
|
const texts = batch.map((inp) => inp.content);
|
|
453
453
|
const embeddings = await this.embedding.embed(texts);
|
|
454
454
|
const enriched = batch.map((input, j) => ({ ...input, embedding: embeddings[j] }));
|
|
@@ -3436,6 +3436,264 @@ var MongoDBStorageAdapter = class {
|
|
|
3436
3436
|
}
|
|
3437
3437
|
};
|
|
3438
3438
|
|
|
3439
|
+
// src/adapters/storage/sqlite.ts
|
|
3440
|
+
function cosineSimilarity(a, b) {
|
|
3441
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
3442
|
+
const dims = Math.min(a.length, b.length);
|
|
3443
|
+
let dot = 0;
|
|
3444
|
+
let magA = 0;
|
|
3445
|
+
let magB = 0;
|
|
3446
|
+
for (let i = 0; i < dims; i++) {
|
|
3447
|
+
dot += a[i] * b[i];
|
|
3448
|
+
magA += a[i] * a[i];
|
|
3449
|
+
magB += b[i] * b[i];
|
|
3450
|
+
}
|
|
3451
|
+
const mag = Math.sqrt(magA) * Math.sqrt(magB);
|
|
3452
|
+
return mag === 0 ? 0 : dot / mag;
|
|
3453
|
+
}
|
|
3454
|
+
var SQLiteStorageAdapter = class {
|
|
3455
|
+
db;
|
|
3456
|
+
table;
|
|
3457
|
+
vectorDimensions;
|
|
3458
|
+
constructor(config) {
|
|
3459
|
+
if (!config.db) {
|
|
3460
|
+
throw configError("SQLiteStorageAdapter requires a better-sqlite3 database instance");
|
|
3461
|
+
}
|
|
3462
|
+
this.db = config.db;
|
|
3463
|
+
this.table = config.tableName ?? "memstack_memories";
|
|
3464
|
+
if (!/^[a-zA-Z0-9_]+$/.test(this.table)) {
|
|
3465
|
+
throw configError(`Invalid table name: "${this.table}". Use only alphanumeric characters and underscores.`);
|
|
3466
|
+
}
|
|
3467
|
+
this.vectorDimensions = config.vectorDimensions ?? 1536;
|
|
3468
|
+
}
|
|
3469
|
+
async initialize() {
|
|
3470
|
+
this.db.exec(`
|
|
3471
|
+
CREATE TABLE IF NOT EXISTS ${this.table} (
|
|
3472
|
+
id TEXT PRIMARY KEY,
|
|
3473
|
+
actor_id TEXT NOT NULL,
|
|
3474
|
+
memory_type TEXT NOT NULL DEFAULT 'interaction',
|
|
3475
|
+
content TEXT NOT NULL,
|
|
3476
|
+
importance REAL NOT NULL DEFAULT 0.5,
|
|
3477
|
+
emotional_valence REAL NOT NULL DEFAULT 0,
|
|
3478
|
+
tags TEXT NOT NULL DEFAULT '[]',
|
|
3479
|
+
embedding TEXT,
|
|
3480
|
+
source_id TEXT,
|
|
3481
|
+
metadata TEXT NOT NULL DEFAULT '{}',
|
|
3482
|
+
expires_at TEXT,
|
|
3483
|
+
created_at TEXT NOT NULL,
|
|
3484
|
+
touched_at TEXT NOT NULL
|
|
3485
|
+
)
|
|
3486
|
+
`);
|
|
3487
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.table}_actor ON ${this.table}(actor_id)`);
|
|
3488
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.table}_created ON ${this.table}(created_at DESC)`);
|
|
3489
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.table}_importance ON ${this.table}(importance DESC)`);
|
|
3490
|
+
}
|
|
3491
|
+
generateId() {
|
|
3492
|
+
return `mem_${Date.now().toString(36)}_${crypto.randomUUID().slice(0, 8)}`;
|
|
3493
|
+
}
|
|
3494
|
+
async store(input) {
|
|
3495
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3496
|
+
const id = input.id ?? this.generateId();
|
|
3497
|
+
this.db.prepare(
|
|
3498
|
+
`INSERT INTO ${this.table} (id, actor_id, memory_type, content, importance, emotional_valence, tags, embedding, source_id, metadata, expires_at, created_at, touched_at)
|
|
3499
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
3500
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
3501
|
+
content = excluded.content,
|
|
3502
|
+
importance = excluded.importance,
|
|
3503
|
+
emotional_valence = excluded.emotional_valence,
|
|
3504
|
+
tags = excluded.tags,
|
|
3505
|
+
embedding = excluded.embedding,
|
|
3506
|
+
source_id = excluded.source_id,
|
|
3507
|
+
metadata = excluded.metadata,
|
|
3508
|
+
expires_at = excluded.expires_at,
|
|
3509
|
+
touched_at = excluded.touched_at`
|
|
3510
|
+
).run(
|
|
3511
|
+
id,
|
|
3512
|
+
input.actorId,
|
|
3513
|
+
input.memoryType ?? "interaction",
|
|
3514
|
+
input.content,
|
|
3515
|
+
input.importance ?? 0.5,
|
|
3516
|
+
input.emotionalValence ?? 0,
|
|
3517
|
+
JSON.stringify(input.tags ?? []),
|
|
3518
|
+
input.embedding ? JSON.stringify(input.embedding) : null,
|
|
3519
|
+
input.sourceId ?? null,
|
|
3520
|
+
JSON.stringify(input.metadata ?? {}),
|
|
3521
|
+
input.expiresAt?.toISOString() ?? null,
|
|
3522
|
+
now,
|
|
3523
|
+
now
|
|
3524
|
+
);
|
|
3525
|
+
return {
|
|
3526
|
+
id,
|
|
3527
|
+
actorId: input.actorId,
|
|
3528
|
+
memoryType: input.memoryType ?? "interaction",
|
|
3529
|
+
content: input.content,
|
|
3530
|
+
importance: input.importance ?? 0.5,
|
|
3531
|
+
emotionalValence: input.emotionalValence ?? 0,
|
|
3532
|
+
tags: input.tags ?? [],
|
|
3533
|
+
embedding: input.embedding,
|
|
3534
|
+
sourceId: input.sourceId,
|
|
3535
|
+
metadata: input.metadata ?? {},
|
|
3536
|
+
expiresAt: input.expiresAt,
|
|
3537
|
+
createdAt: new Date(now)
|
|
3538
|
+
};
|
|
3539
|
+
}
|
|
3540
|
+
async storeBatch(inputs) {
|
|
3541
|
+
const results = [];
|
|
3542
|
+
for (const input of inputs) {
|
|
3543
|
+
results.push(await this.store(input));
|
|
3544
|
+
}
|
|
3545
|
+
return results;
|
|
3546
|
+
}
|
|
3547
|
+
async get(id) {
|
|
3548
|
+
const row = this.db.prepare(
|
|
3549
|
+
`SELECT * FROM ${this.table} WHERE id = ? AND (expires_at IS NULL OR expires_at > ?)`
|
|
3550
|
+
).get(id, (/* @__PURE__ */ new Date()).toISOString());
|
|
3551
|
+
if (!row) return null;
|
|
3552
|
+
return this._rowToMemory(row);
|
|
3553
|
+
}
|
|
3554
|
+
async delete(id) {
|
|
3555
|
+
const row = this.db.prepare(`SELECT id FROM ${this.table} WHERE id = ?`).get(id);
|
|
3556
|
+
if (!row) throw notFound("Memory", id);
|
|
3557
|
+
this.db.prepare(`DELETE FROM ${this.table} WHERE id = ?`).run(id);
|
|
3558
|
+
}
|
|
3559
|
+
async deleteMany(ids) {
|
|
3560
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
3561
|
+
const result = this.db.prepare(
|
|
3562
|
+
`DELETE FROM ${this.table} WHERE id IN (${placeholders})`
|
|
3563
|
+
).run(...ids);
|
|
3564
|
+
return result.changes;
|
|
3565
|
+
}
|
|
3566
|
+
async touch(id) {
|
|
3567
|
+
const row = this.db.prepare(`SELECT id FROM ${this.table} WHERE id = ?`).get(id);
|
|
3568
|
+
if (!row) throw notFound("Memory", id);
|
|
3569
|
+
this.db.prepare(`UPDATE ${this.table} SET touched_at = ? WHERE id = ?`).run((/* @__PURE__ */ new Date()).toISOString(), id);
|
|
3570
|
+
}
|
|
3571
|
+
async retrieve(query, embedding) {
|
|
3572
|
+
const conditions = ["(expires_at IS NULL OR expires_at > ?)"];
|
|
3573
|
+
const params = [(/* @__PURE__ */ new Date()).toISOString()];
|
|
3574
|
+
if (query.actorId) {
|
|
3575
|
+
conditions.push("actor_id = ?");
|
|
3576
|
+
params.push(query.actorId);
|
|
3577
|
+
}
|
|
3578
|
+
if (query.memoryTypes && query.memoryTypes.length > 0) {
|
|
3579
|
+
const placeholders = query.memoryTypes.map(() => "?").join(", ");
|
|
3580
|
+
conditions.push(`memory_type IN (${placeholders})`);
|
|
3581
|
+
params.push(...query.memoryTypes);
|
|
3582
|
+
}
|
|
3583
|
+
if (query.createdAfter) {
|
|
3584
|
+
conditions.push("created_at >= ?");
|
|
3585
|
+
params.push(query.createdAfter.toISOString());
|
|
3586
|
+
}
|
|
3587
|
+
if (query.createdBefore) {
|
|
3588
|
+
conditions.push("created_at <= ?");
|
|
3589
|
+
params.push(query.createdBefore.toISOString());
|
|
3590
|
+
}
|
|
3591
|
+
const where = `WHERE ${conditions.join(" AND ")}`;
|
|
3592
|
+
const hasSemantic = (query.strategy === "semantic" || query.strategy === "hybrid") && embedding && embedding.length > 0;
|
|
3593
|
+
let orderBy;
|
|
3594
|
+
switch (query.strategy) {
|
|
3595
|
+
case "recent":
|
|
3596
|
+
orderBy = "touched_at DESC";
|
|
3597
|
+
break;
|
|
3598
|
+
case "important":
|
|
3599
|
+
orderBy = "importance DESC";
|
|
3600
|
+
break;
|
|
3601
|
+
case "hybrid":
|
|
3602
|
+
case "semantic":
|
|
3603
|
+
default:
|
|
3604
|
+
if (hasSemantic) {
|
|
3605
|
+
orderBy = "touched_at DESC";
|
|
3606
|
+
} else {
|
|
3607
|
+
orderBy = "importance DESC, touched_at DESC";
|
|
3608
|
+
}
|
|
3609
|
+
break;
|
|
3610
|
+
}
|
|
3611
|
+
const limit = query.limit ?? 10;
|
|
3612
|
+
const sql = `SELECT * FROM ${this.table} ${where} ORDER BY ${orderBy}`;
|
|
3613
|
+
const rows = this.db.prepare(sql).all(...params);
|
|
3614
|
+
let results = rows;
|
|
3615
|
+
if (query.query) {
|
|
3616
|
+
const q = query.query.toLowerCase();
|
|
3617
|
+
results = results.filter((r) => r.content.toLowerCase().includes(q));
|
|
3618
|
+
}
|
|
3619
|
+
if (query.tags && query.tags.length > 0) {
|
|
3620
|
+
results = results.filter((r) => {
|
|
3621
|
+
const tags = JSON.parse(r.tags);
|
|
3622
|
+
return tags.some((t) => query.tags.includes(t));
|
|
3623
|
+
});
|
|
3624
|
+
}
|
|
3625
|
+
if (hasSemantic && embedding) {
|
|
3626
|
+
const scored = results.filter((r) => r.embedding !== null).map((r) => {
|
|
3627
|
+
const emb = JSON.parse(r.embedding);
|
|
3628
|
+
const score = cosineSimilarity(embedding, emb);
|
|
3629
|
+
return { row: r, score };
|
|
3630
|
+
}).sort((a, b) => b.score - a.score);
|
|
3631
|
+
if (query.strategy === "hybrid") {
|
|
3632
|
+
scored.sort((a, b) => b.score + b.row.importance - (a.score + a.row.importance));
|
|
3633
|
+
}
|
|
3634
|
+
const topK = scored.slice(0, limit);
|
|
3635
|
+
for (const { row } of topK) {
|
|
3636
|
+
this.db.prepare(`UPDATE ${this.table} SET touched_at = ? WHERE id = ?`).run((/* @__PURE__ */ new Date()).toISOString(), row.id);
|
|
3637
|
+
}
|
|
3638
|
+
return topK.map(({ row }) => this._rowToMemory(row));
|
|
3639
|
+
}
|
|
3640
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3641
|
+
const limited = results.slice(0, limit);
|
|
3642
|
+
for (const row of limited) {
|
|
3643
|
+
this.db.prepare(`UPDATE ${this.table} SET touched_at = ? WHERE id = ?`).run(now, row.id);
|
|
3644
|
+
}
|
|
3645
|
+
return limited.map((r) => this._rowToMemory(r));
|
|
3646
|
+
}
|
|
3647
|
+
async count(filter) {
|
|
3648
|
+
const conditions = ["(expires_at IS NULL OR expires_at > ?)"];
|
|
3649
|
+
const params = [(/* @__PURE__ */ new Date()).toISOString()];
|
|
3650
|
+
if (filter?.actorId) {
|
|
3651
|
+
conditions.push("actor_id = ?");
|
|
3652
|
+
params.push(filter.actorId);
|
|
3653
|
+
}
|
|
3654
|
+
if (filter?.memoryType) {
|
|
3655
|
+
conditions.push("memory_type = ?");
|
|
3656
|
+
params.push(filter.memoryType);
|
|
3657
|
+
}
|
|
3658
|
+
if (filter?.minImportance !== void 0) {
|
|
3659
|
+
conditions.push("importance >= ?");
|
|
3660
|
+
params.push(filter.minImportance);
|
|
3661
|
+
}
|
|
3662
|
+
if (filter?.createdAfter) {
|
|
3663
|
+
conditions.push("created_at >= ?");
|
|
3664
|
+
params.push(filter.createdAfter.toISOString());
|
|
3665
|
+
}
|
|
3666
|
+
if (filter?.createdBefore) {
|
|
3667
|
+
conditions.push("created_at <= ?");
|
|
3668
|
+
params.push(filter.createdBefore.toISOString());
|
|
3669
|
+
}
|
|
3670
|
+
const where = conditions.join(" AND ");
|
|
3671
|
+
const row = this.db.prepare(
|
|
3672
|
+
`SELECT COUNT(*) as count FROM ${this.table} WHERE ${where}`
|
|
3673
|
+
).get(...params);
|
|
3674
|
+
return row?.count ?? 0;
|
|
3675
|
+
}
|
|
3676
|
+
async close() {
|
|
3677
|
+
this.db.close();
|
|
3678
|
+
}
|
|
3679
|
+
_rowToMemory(row) {
|
|
3680
|
+
return {
|
|
3681
|
+
id: row.id,
|
|
3682
|
+
actorId: row.actor_id,
|
|
3683
|
+
memoryType: row.memory_type,
|
|
3684
|
+
content: row.content,
|
|
3685
|
+
importance: row.importance,
|
|
3686
|
+
emotionalValence: row.emotional_valence,
|
|
3687
|
+
tags: JSON.parse(row.tags),
|
|
3688
|
+
embedding: row.embedding ? JSON.parse(row.embedding) : void 0,
|
|
3689
|
+
sourceId: row.source_id ?? void 0,
|
|
3690
|
+
metadata: JSON.parse(row.metadata),
|
|
3691
|
+
expiresAt: row.expires_at ? new Date(row.expires_at) : void 0,
|
|
3692
|
+
createdAt: new Date(row.created_at)
|
|
3693
|
+
};
|
|
3694
|
+
}
|
|
3695
|
+
};
|
|
3696
|
+
|
|
3439
3697
|
// src/adapters/llm/openai.ts
|
|
3440
3698
|
var OpenAILLMAdapter = class {
|
|
3441
3699
|
apiKey;
|
|
@@ -3622,6 +3880,7 @@ var OpenAIEmbeddingAdapter = class {
|
|
|
3622
3880
|
baseURL;
|
|
3623
3881
|
model;
|
|
3624
3882
|
dimensions;
|
|
3883
|
+
maxBatchSize = 2048;
|
|
3625
3884
|
constructor(config) {
|
|
3626
3885
|
this.apiKey = config.apiKey;
|
|
3627
3886
|
this.baseURL = config.baseURL ?? "https://api.openai.com/v1";
|
|
@@ -3630,8 +3889,8 @@ var OpenAIEmbeddingAdapter = class {
|
|
|
3630
3889
|
}
|
|
3631
3890
|
async embed(texts) {
|
|
3632
3891
|
if (texts.length === 0) return [];
|
|
3633
|
-
if (texts.length >
|
|
3634
|
-
throw new MemStackError("VALIDATION_ERROR", `Max
|
|
3892
|
+
if (texts.length > this.maxBatchSize) {
|
|
3893
|
+
throw new MemStackError("VALIDATION_ERROR", `Max ${this.maxBatchSize} texts per batch, got ${texts.length}`);
|
|
3635
3894
|
}
|
|
3636
3895
|
try {
|
|
3637
3896
|
const response = await fetch(`${this.baseURL}/embeddings`, {
|
|
@@ -3678,6 +3937,7 @@ var CohereEmbeddingAdapter = class {
|
|
|
3678
3937
|
baseURL;
|
|
3679
3938
|
model;
|
|
3680
3939
|
dimensions;
|
|
3940
|
+
maxBatchSize = 96;
|
|
3681
3941
|
constructor(config) {
|
|
3682
3942
|
this.apiKey = config.apiKey;
|
|
3683
3943
|
this.baseURL = config.baseURL ?? "https://api.cohere.ai/v1";
|
|
@@ -3686,8 +3946,8 @@ var CohereEmbeddingAdapter = class {
|
|
|
3686
3946
|
}
|
|
3687
3947
|
async embed(texts) {
|
|
3688
3948
|
if (texts.length === 0) return [];
|
|
3689
|
-
if (texts.length >
|
|
3690
|
-
throw new MemStackError("VALIDATION_ERROR", `Cohere max
|
|
3949
|
+
if (texts.length > this.maxBatchSize) {
|
|
3950
|
+
throw new MemStackError("VALIDATION_ERROR", `Cohere max ${this.maxBatchSize} texts per batch, got ${texts.length}`);
|
|
3691
3951
|
}
|
|
3692
3952
|
try {
|
|
3693
3953
|
const response = await fetch(`${this.baseURL}/embed`, {
|
|
@@ -3912,6 +4172,6 @@ var GroqLLMAdapter = class {
|
|
|
3912
4172
|
}
|
|
3913
4173
|
};
|
|
3914
4174
|
|
|
3915
|
-
export { AnthropicLLMAdapter, CohereEmbeddingAdapter, DiskStorageAdapter, GroqLLMAdapter, HybridStorageAdapter, InMemoryStorageAdapter, LanceDBStorageAdapter, MarkdownStorageAdapter, MemStack, MemStackError, MongoDBStorageAdapter, Neo4jStorageAdapter, OllamaLLMAdapter, OpenAIEmbeddingAdapter, OpenAILLMAdapter, PostgresStorageAdapter, QdrantStorageAdapter, RedisStorageAdapter, WeaviateStorageAdapter, configError, notFound, storageError, validationError };
|
|
4175
|
+
export { AnthropicLLMAdapter, CohereEmbeddingAdapter, DiskStorageAdapter, GroqLLMAdapter, HybridStorageAdapter, InMemoryStorageAdapter, LanceDBStorageAdapter, MarkdownStorageAdapter, MemStack, MemStackError, MongoDBStorageAdapter, Neo4jStorageAdapter, OllamaLLMAdapter, OpenAIEmbeddingAdapter, OpenAILLMAdapter, PostgresStorageAdapter, QdrantStorageAdapter, RedisStorageAdapter, SQLiteStorageAdapter, WeaviateStorageAdapter, configError, notFound, storageError, validationError };
|
|
3916
4176
|
//# sourceMappingURL=index.js.map
|
|
3917
4177
|
//# sourceMappingURL=index.js.map
|