@kuralle-agents/cf-agent 0.4.1 → 0.6.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 +15 -0
- package/dist/KuralleAgent.d.ts +6 -0
- package/dist/KuralleAgent.js +12 -0
- package/dist/SqlPersistentMemoryStore.d.ts +12 -0
- package/dist/SqlPersistentMemoryStore.js +71 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/sqlExecutor.d.ts +7 -0
- package/dist/sqlExecutor.js +19 -0
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Peers: `agents` (Cloudflare Agents SDK), `zod`.
|
|
|
19
19
|
- **`KuralleAgent`** (alias `CfChatAgent`) — abstract base class; extend and implement `getAgents()` and `getDefaultAgentId()`.
|
|
20
20
|
- **`BridgeSessionStore`** — bridges Kuralle `SessionStore` interface to CF's SQLite storage.
|
|
21
21
|
- **`OrchestrationStore`** — Durable Object KV for orchestration state.
|
|
22
|
+
- **`SqlPersistentMemoryStore`** — DO SQLite-backed `PersistentMemoryStore` for USER/MEMORY blocks.
|
|
22
23
|
- **`createSSEResponse`** — helper for streaming SSE responses from Workers.
|
|
23
24
|
|
|
24
25
|
## Usage
|
|
@@ -64,6 +65,20 @@ tag = "v1"
|
|
|
64
65
|
new_sqlite_classes = ["SupportAgent"]
|
|
65
66
|
```
|
|
66
67
|
|
|
68
|
+
## Working memory blocks
|
|
69
|
+
|
|
70
|
+
`KuralleAgent` wires `SqlPersistentMemoryStore` into `defaultWorkingMemoryStore` automatically via DO SQLite. Override in `getRuntimeConfig()` or disable by overriding `getWorkingMemoryStore()` to return `undefined`.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { SqlPersistentMemoryStore } from '@kuralle-agents/cf-agent';
|
|
74
|
+
|
|
75
|
+
protected getRuntimeConfig() {
|
|
76
|
+
return {
|
|
77
|
+
defaultWorkingMemoryStore: new SqlPersistentMemoryStore(this.getSql()),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
67
82
|
## Flows and routing
|
|
68
83
|
|
|
69
84
|
Attach `flows` for structured SOPs or `routes` + `routing: { mode: 'structured' }` for triage — same `defineAgent` primitive as Node/Bun. No runtime differences.
|
package/dist/KuralleAgent.d.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { AIChatAgent } from '@cloudflare/ai-chat';
|
|
22
22
|
import { type HarnessConfig } from '@kuralle-agents/core';
|
|
23
|
+
import type { PersistentMemoryStore } from '@kuralle-agents/core';
|
|
23
24
|
import type { StreamTextOnFinishCallback, ToolSet } from 'ai';
|
|
24
25
|
import type { OnChatMessageOptions } from '@cloudflare/ai-chat';
|
|
25
26
|
import type { StreamAdapterConfig } from './types.js';
|
|
@@ -64,6 +65,11 @@ export declare abstract class KuralleAgent<Env = unknown, State = unknown> exten
|
|
|
64
65
|
* Optional: Configure which Kuralle events become data parts in the stream.
|
|
65
66
|
*/
|
|
66
67
|
protected getStreamConfig(): Partial<StreamAdapterConfig>;
|
|
68
|
+
/**
|
|
69
|
+
* Optional: durable working-memory blocks backed by DO SQLite.
|
|
70
|
+
* When returned, wired into `HarnessConfig.defaultWorkingMemoryStore`.
|
|
71
|
+
*/
|
|
72
|
+
protected getWorkingMemoryStore(): PersistentMemoryStore | undefined;
|
|
67
73
|
/**
|
|
68
74
|
* Get the SQL executor for the Durable Object.
|
|
69
75
|
* CF's AIChatAgent exposes this.sql as a tagged template function.
|
package/dist/KuralleAgent.js
CHANGED
|
@@ -22,6 +22,7 @@ import { AIChatAgent } from '@cloudflare/ai-chat';
|
|
|
22
22
|
import { createRuntime } from '@kuralle-agents/core';
|
|
23
23
|
import { BridgeSessionStore } from './BridgeSessionStore.js';
|
|
24
24
|
import { OrchestrationStore } from './OrchestrationStore.js';
|
|
25
|
+
import { SqlPersistentMemoryStore } from './SqlPersistentMemoryStore.js';
|
|
25
26
|
import { createSSEResponse } from './StreamAdapter.js';
|
|
26
27
|
import { DEFAULT_STREAM_CONFIG } from './types.js';
|
|
27
28
|
import { durableAgentSurface } from './durable-agent-surface.js';
|
|
@@ -62,6 +63,13 @@ export class KuralleAgent extends AIChatAgent {
|
|
|
62
63
|
getStreamConfig() {
|
|
63
64
|
return {};
|
|
64
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Optional: durable working-memory blocks backed by DO SQLite.
|
|
68
|
+
* When returned, wired into `HarnessConfig.defaultWorkingMemoryStore`.
|
|
69
|
+
*/
|
|
70
|
+
getWorkingMemoryStore() {
|
|
71
|
+
return new SqlPersistentMemoryStore(this.getSql());
|
|
72
|
+
}
|
|
65
73
|
/**
|
|
66
74
|
* Get the SQL executor for the Durable Object.
|
|
67
75
|
* CF's AIChatAgent exposes this.sql as a tagged template function.
|
|
@@ -113,11 +121,15 @@ export class KuralleAgent extends AIChatAgent {
|
|
|
113
121
|
});
|
|
114
122
|
// Build runtime (fresh per request to pick up latest config)
|
|
115
123
|
const extraConfig = this.getRuntimeConfig();
|
|
124
|
+
const workingMemoryStore = this.getWorkingMemoryStore();
|
|
116
125
|
this.runtime = createRuntime({
|
|
117
126
|
...extraConfig,
|
|
118
127
|
agents: this.getAgents(),
|
|
119
128
|
defaultAgentId,
|
|
120
129
|
sessionStore,
|
|
130
|
+
...(workingMemoryStore && !extraConfig.defaultWorkingMemoryStore
|
|
131
|
+
? { defaultWorkingMemoryStore: workingMemoryStore }
|
|
132
|
+
: {}),
|
|
121
133
|
});
|
|
122
134
|
const handle = this.runtime.run({
|
|
123
135
|
input: lastUserMessage,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { MemoryBlockScope, PersistentMemoryBlock, PersistentMemoryStore } from '@kuralle-agents/core';
|
|
2
|
+
import type { SqlExecutor } from './types.js';
|
|
3
|
+
export declare class SqlPersistentMemoryStore implements PersistentMemoryStore {
|
|
4
|
+
private sql;
|
|
5
|
+
private initialized;
|
|
6
|
+
constructor(sql: SqlExecutor);
|
|
7
|
+
private ensureTable;
|
|
8
|
+
loadBlock(scope: MemoryBlockScope, owner: string, key: string): Promise<PersistentMemoryBlock | null>;
|
|
9
|
+
saveBlock(block: PersistentMemoryBlock, owner: string): Promise<void>;
|
|
10
|
+
deleteBlock(scope: MemoryBlockScope, owner: string, key: string): Promise<void>;
|
|
11
|
+
listBlocks(scope: MemoryBlockScope, owner: string): Promise<string[]>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export class SqlPersistentMemoryStore {
|
|
2
|
+
sql;
|
|
3
|
+
initialized = false;
|
|
4
|
+
constructor(sql) {
|
|
5
|
+
this.sql = sql;
|
|
6
|
+
}
|
|
7
|
+
ensureTable() {
|
|
8
|
+
if (this.initialized) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
this.sql `
|
|
12
|
+
CREATE TABLE IF NOT EXISTS working_memory_blocks (
|
|
13
|
+
scope TEXT NOT NULL,
|
|
14
|
+
owner TEXT NOT NULL,
|
|
15
|
+
key TEXT NOT NULL,
|
|
16
|
+
content TEXT NOT NULL,
|
|
17
|
+
char_limit INTEGER NOT NULL,
|
|
18
|
+
updated_at TEXT NOT NULL,
|
|
19
|
+
PRIMARY KEY (scope, owner, key)
|
|
20
|
+
)
|
|
21
|
+
`;
|
|
22
|
+
this.initialized = true;
|
|
23
|
+
}
|
|
24
|
+
async loadBlock(scope, owner, key) {
|
|
25
|
+
this.ensureTable();
|
|
26
|
+
const rows = this.sql `
|
|
27
|
+
SELECT content, char_limit, updated_at
|
|
28
|
+
FROM working_memory_blocks
|
|
29
|
+
WHERE scope = ${scope} AND owner = ${owner} AND key = ${key}
|
|
30
|
+
`;
|
|
31
|
+
if (!rows || rows.length === 0) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const row = rows[0];
|
|
35
|
+
return {
|
|
36
|
+
key,
|
|
37
|
+
scope,
|
|
38
|
+
content: row.content,
|
|
39
|
+
charLimit: row.char_limit,
|
|
40
|
+
updatedAt: row.updated_at,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
async saveBlock(block, owner) {
|
|
44
|
+
this.ensureTable();
|
|
45
|
+
const updatedAt = block.updatedAt ?? new Date().toISOString();
|
|
46
|
+
this.sql `
|
|
47
|
+
INSERT INTO working_memory_blocks (scope, owner, key, content, char_limit, updated_at)
|
|
48
|
+
VALUES (${block.scope}, ${owner}, ${block.key}, ${block.content}, ${block.charLimit}, ${updatedAt})
|
|
49
|
+
ON CONFLICT(scope, owner, key) DO UPDATE SET
|
|
50
|
+
content = excluded.content,
|
|
51
|
+
char_limit = excluded.char_limit,
|
|
52
|
+
updated_at = excluded.updated_at
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
async deleteBlock(scope, owner, key) {
|
|
56
|
+
this.ensureTable();
|
|
57
|
+
this.sql `
|
|
58
|
+
DELETE FROM working_memory_blocks
|
|
59
|
+
WHERE scope = ${scope} AND owner = ${owner} AND key = ${key}
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
async listBlocks(scope, owner) {
|
|
63
|
+
this.ensureTable();
|
|
64
|
+
const rows = this.sql `
|
|
65
|
+
SELECT key FROM working_memory_blocks
|
|
66
|
+
WHERE scope = ${scope} AND owner = ${owner}
|
|
67
|
+
ORDER BY key
|
|
68
|
+
`;
|
|
69
|
+
return (rows ?? []).map((row) => row.key);
|
|
70
|
+
}
|
|
71
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
export { KuralleAgent, KuralleAgent as CfChatAgent } from './KuralleAgent.js';
|
|
27
27
|
export { BridgeSessionStore } from './BridgeSessionStore.js';
|
|
28
28
|
export { OrchestrationStore } from './OrchestrationStore.js';
|
|
29
|
+
export { SqlPersistentMemoryStore } from './SqlPersistentMemoryStore.js';
|
|
30
|
+
export { createSqlExecutor } from './sqlExecutor.js';
|
|
29
31
|
export { createSSEResponse } from './StreamAdapter.js';
|
|
30
32
|
export type { StreamAdapterConfig, OrchestrationState, SqlExecutor, } from './types.js';
|
|
31
33
|
export { DEFAULT_STREAM_CONFIG } from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -26,5 +26,7 @@
|
|
|
26
26
|
export { KuralleAgent, KuralleAgent as CfChatAgent } from './KuralleAgent.js';
|
|
27
27
|
export { BridgeSessionStore } from './BridgeSessionStore.js';
|
|
28
28
|
export { OrchestrationStore } from './OrchestrationStore.js';
|
|
29
|
+
export { SqlPersistentMemoryStore } from './SqlPersistentMemoryStore.js';
|
|
30
|
+
export { createSqlExecutor } from './sqlExecutor.js';
|
|
29
31
|
export { createSSEResponse } from './StreamAdapter.js';
|
|
30
32
|
export { DEFAULT_STREAM_CONFIG } from './types.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SqlExecutor } from './types.js';
|
|
2
|
+
type SqlStorageExec = {
|
|
3
|
+
exec: (query: string, ...params: unknown[]) => unknown;
|
|
4
|
+
};
|
|
5
|
+
/** Wrap DO `ctx.storage.sql.exec` as the tagged-template `SqlExecutor` shape. */
|
|
6
|
+
export declare function createSqlExecutor(storageSql: SqlStorageExec): SqlExecutor;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function rowsFromExecResult(result) {
|
|
2
|
+
if (result && typeof result === 'object') {
|
|
3
|
+
const cursor = result;
|
|
4
|
+
if (typeof cursor.toArray === 'function') {
|
|
5
|
+
return cursor.toArray();
|
|
6
|
+
}
|
|
7
|
+
if (Symbol.iterator in cursor) {
|
|
8
|
+
return [...result];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
/** Wrap DO `ctx.storage.sql.exec` as the tagged-template `SqlExecutor` shape. */
|
|
14
|
+
export function createSqlExecutor(storageSql) {
|
|
15
|
+
return ((strings, ...values) => {
|
|
16
|
+
const query = strings.reduce((acc, part, index) => acc + part + (index < values.length ? '?' : ''), '');
|
|
17
|
+
return rowsFromExecResult(storageSql.exec(query, ...values));
|
|
18
|
+
});
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kuralle-agents/cf-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Kuralle agent integration for Cloudflare Workers with AIChatAgent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,18 +22,20 @@
|
|
|
22
22
|
"@cloudflare/ai-chat": "^0.1.8",
|
|
23
23
|
"ai": "^6.0.90",
|
|
24
24
|
"zod-to-json-schema": "^3.24.0",
|
|
25
|
-
"@kuralle-agents/realtime-audio": "0.
|
|
26
|
-
"@kuralle-agents/core": "0.
|
|
25
|
+
"@kuralle-agents/realtime-audio": "0.6.0",
|
|
26
|
+
"@kuralle-agents/core": "0.6.0"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"agents": "^0.11.5",
|
|
30
30
|
"zod": "^3.0.0",
|
|
31
|
-
"@kuralle-agents/voice-protocol": "0.
|
|
31
|
+
"@kuralle-agents/voice-protocol": "0.6.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
+
"@cloudflare/vitest-pool-workers": "^0.12.7",
|
|
34
35
|
"agents": "^0.11.5",
|
|
35
36
|
"typescript": "^5.7.0",
|
|
36
|
-
"
|
|
37
|
+
"vitest": "^3.2.4",
|
|
38
|
+
"@kuralle-agents/voice-protocol": "0.6.0"
|
|
37
39
|
},
|
|
38
40
|
"engines": {
|
|
39
41
|
"node": ">=20"
|
|
@@ -57,7 +59,8 @@
|
|
|
57
59
|
"prebuild": "rm -rf dist",
|
|
58
60
|
"build": "tsc",
|
|
59
61
|
"dev": "tsc --watch",
|
|
60
|
-
"test": "bun test src/voice/__tests__ src/__tests__",
|
|
62
|
+
"test": "bun test src/voice/__tests__ src/__tests__ && vitest run --config vitest.config.ts",
|
|
63
|
+
"test:sql-memory-workers": "vitest run --config vitest.config.ts",
|
|
61
64
|
"typecheck": "tsc --noEmit",
|
|
62
65
|
"clean": "rm -rf dist"
|
|
63
66
|
}
|