@kuralle-agents/postgres-store 0.5.0 → 0.6.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/README.md CHANGED
@@ -18,6 +18,7 @@ Three backend implementations — sessions, long-term memory, and pgvector simil
18
18
 
19
19
  - **`PostgresSessionStore`** — `SessionStore` implementation for durable session persistence.
20
20
  - **`PostgresMemoryService`** — `MemoryService` implementation for cross-session long-term memory.
21
+ - **`PostgresPersistentMemoryStore`** — `PersistentMemoryStore` for durable USER/MEMORY markdown blocks.
21
22
  - **`PgVectorStore`** — `VectorStoreCore` implementation using pgvector for similarity search.
22
23
 
23
24
  ## Session store
@@ -58,6 +59,22 @@ const runtime = createRuntime({
58
59
  });
59
60
  ```
60
61
 
62
+ ## Working memory blocks
63
+
64
+ ```ts
65
+ import { PostgresPersistentMemoryStore } from '@kuralle-agents/postgres-store';
66
+
67
+ const workingMemoryStore = new PostgresPersistentMemoryStore({ client: pool });
68
+
69
+ const runtime = createRuntime({
70
+ agents: [agent],
71
+ defaultAgentId: 'support',
72
+ defaultWorkingMemoryStore: workingMemoryStore,
73
+ });
74
+ ```
75
+
76
+ On Cloudflare Workers, connect the pool through [Hyperdrive](https://developers.cloudflare.com/hyperdrive/) rather than a direct TCP connection.
77
+
61
78
  ## Vector store (pgvector)
62
79
 
63
80
  Requires the `pgvector` extension in your Postgres instance.
@@ -0,0 +1,22 @@
1
+ import type { MemoryBlockScope, PersistentMemoryBlock, PersistentMemoryStore } from '@kuralle-agents/core';
2
+ import type { QueryResult } from 'pg';
3
+ type PostgresClient = {
4
+ query: (text: string, params?: unknown[]) => Promise<QueryResult>;
5
+ };
6
+ export type PostgresPersistentMemoryStoreOptions = {
7
+ client: PostgresClient;
8
+ tableName?: string;
9
+ autoMigrate?: boolean;
10
+ };
11
+ export declare class PostgresPersistentMemoryStore implements PersistentMemoryStore {
12
+ private client;
13
+ private table;
14
+ private ready;
15
+ constructor(options: PostgresPersistentMemoryStoreOptions);
16
+ private init;
17
+ loadBlock(scope: MemoryBlockScope, owner: string, key: string): Promise<PersistentMemoryBlock | null>;
18
+ saveBlock(block: PersistentMemoryBlock, owner: string): Promise<void>;
19
+ deleteBlock(scope: MemoryBlockScope, owner: string, key: string): Promise<void>;
20
+ listBlocks(scope: MemoryBlockScope, owner: string): Promise<string[]>;
21
+ }
22
+ export {};
@@ -0,0 +1,70 @@
1
+ const defaultTable = 'working_memory_blocks';
2
+ const normalizeTableName = (tableName) => {
3
+ const table = tableName ?? defaultTable;
4
+ if (!/^[a-zA-Z0-9_.]+$/.test(table)) {
5
+ throw new Error(`Invalid table name: ${table}`);
6
+ }
7
+ return table;
8
+ };
9
+ export class PostgresPersistentMemoryStore {
10
+ client;
11
+ table;
12
+ ready;
13
+ constructor(options) {
14
+ this.client = options.client;
15
+ this.table = normalizeTableName(options.tableName);
16
+ const autoMigrate = options.autoMigrate ?? true;
17
+ this.ready = autoMigrate ? this.init() : Promise.resolve();
18
+ }
19
+ async init() {
20
+ await this.client.query(`CREATE TABLE IF NOT EXISTS ${this.table} (
21
+ scope TEXT NOT NULL,
22
+ owner TEXT NOT NULL,
23
+ key TEXT NOT NULL,
24
+ content TEXT NOT NULL,
25
+ char_limit INTEGER NOT NULL,
26
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
27
+ PRIMARY KEY (scope, owner, key)
28
+ )`);
29
+ await this.client.query(`CREATE INDEX IF NOT EXISTS idx_${this.table}_scope_owner
30
+ ON ${this.table} (scope, owner)`);
31
+ }
32
+ async loadBlock(scope, owner, key) {
33
+ await this.ready;
34
+ const result = await this.client.query(`SELECT content, char_limit, updated_at
35
+ FROM ${this.table}
36
+ WHERE scope = $1 AND owner = $2 AND key = $3`, [scope, owner, key]);
37
+ if (result.rows.length === 0) {
38
+ return null;
39
+ }
40
+ const row = result.rows[0];
41
+ return {
42
+ key,
43
+ scope,
44
+ content: row.content,
45
+ charLimit: row.char_limit,
46
+ updatedAt: new Date(row.updated_at).toISOString(),
47
+ };
48
+ }
49
+ async saveBlock(block, owner) {
50
+ await this.ready;
51
+ const updatedAt = block.updatedAt ?? new Date().toISOString();
52
+ await this.client.query(`INSERT INTO ${this.table} (scope, owner, key, content, char_limit, updated_at)
53
+ VALUES ($1, $2, $3, $4, $5, $6)
54
+ ON CONFLICT (scope, owner, key) DO UPDATE SET
55
+ content = EXCLUDED.content,
56
+ char_limit = EXCLUDED.char_limit,
57
+ updated_at = EXCLUDED.updated_at`, [block.scope, owner, block.key, block.content, block.charLimit, updatedAt]);
58
+ }
59
+ async deleteBlock(scope, owner, key) {
60
+ await this.ready;
61
+ await this.client.query(`DELETE FROM ${this.table} WHERE scope = $1 AND owner = $2 AND key = $3`, [scope, owner, key]);
62
+ }
63
+ async listBlocks(scope, owner) {
64
+ await this.ready;
65
+ const result = await this.client.query(`SELECT key FROM ${this.table}
66
+ WHERE scope = $1 AND owner = $2
67
+ ORDER BY key`, [scope, owner]);
68
+ return result.rows.map((row) => row.key);
69
+ }
70
+ }
package/dist/index.d.ts CHANGED
@@ -2,5 +2,7 @@ export { PostgresSessionStore } from './PostgresSessionStore.js';
2
2
  export type { PostgresStoreOptions } from './PostgresSessionStore.js';
3
3
  export { PostgresMemoryService } from './PostgresMemoryService.js';
4
4
  export type { PostgresMemoryStoreOptions } from './PostgresMemoryService.js';
5
+ export { PostgresPersistentMemoryStore } from './PostgresPersistentMemoryStore.js';
6
+ export type { PostgresPersistentMemoryStoreOptions } from './PostgresPersistentMemoryStore.js';
5
7
  export { PgVectorStore } from './PgVectorStore.js';
6
8
  export type { PgVectorStoreOptions } from './PgVectorStore.js';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { PostgresSessionStore } from './PostgresSessionStore.js';
2
2
  export { PostgresMemoryService } from './PostgresMemoryService.js';
3
+ export { PostgresPersistentMemoryStore } from './PostgresPersistentMemoryStore.js';
3
4
  export { PgVectorStore } from './PgVectorStore.js';
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "git+https://github.com/kuralle/kuralle-agents.git",
7
7
  "directory": "packages/kuralle-postgres-store"
8
8
  },
9
- "version": "0.5.0",
9
+ "version": "0.6.1",
10
10
  "description": "PostgreSQL-backed SessionStore for Kuralle",
11
11
  "type": "module",
12
12
  "main": "dist/index.js",
@@ -18,19 +18,19 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@kuralle-agents/core": "0.5.0"
21
+ "@kuralle-agents/core": "0.6.1"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "pg": "^8.0.0",
25
- "@kuralle-agents/core": "0.5.0",
26
- "@kuralle-agents/rag": "0.5.0"
25
+ "@kuralle-agents/core": "0.6.1",
26
+ "@kuralle-agents/rag": "0.6.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^20.11.0",
30
30
  "@types/pg": "^8.11.0",
31
31
  "pg": "^8.11.0",
32
32
  "typescript": "^5.3.0",
33
- "@kuralle-agents/rag": "0.5.0"
33
+ "@kuralle-agents/rag": "0.6.1"
34
34
  },
35
35
  "publishConfig": {
36
36
  "access": "public"