@cogitator-ai/memory 0.1.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/LICENSE +21 -0
- package/README.md +89 -0
- package/dist/__tests__/context-builder.test.d.ts +2 -0
- package/dist/__tests__/context-builder.test.d.ts.map +1 -0
- package/dist/__tests__/context-builder.test.js +139 -0
- package/dist/__tests__/context-builder.test.js.map +1 -0
- package/dist/__tests__/memory-adapter.test.d.ts +2 -0
- package/dist/__tests__/memory-adapter.test.d.ts.map +1 -0
- package/dist/__tests__/memory-adapter.test.js +236 -0
- package/dist/__tests__/memory-adapter.test.js.map +1 -0
- package/dist/__tests__/token-counter.test.d.ts +2 -0
- package/dist/__tests__/token-counter.test.d.ts.map +1 -0
- package/dist/__tests__/token-counter.test.js +56 -0
- package/dist/__tests__/token-counter.test.js.map +1 -0
- package/dist/adapters/base.d.ts +22 -0
- package/dist/adapters/base.d.ts.map +1 -0
- package/dist/adapters/base.js +16 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +25 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/memory.d.ts +29 -0
- package/dist/adapters/memory.d.ts.map +1 -0
- package/dist/adapters/memory.js +130 -0
- package/dist/adapters/memory.js.map +1 -0
- package/dist/adapters/postgres.d.ts +43 -0
- package/dist/adapters/postgres.d.ts.map +1 -0
- package/dist/adapters/postgres.js +450 -0
- package/dist/adapters/postgres.js.map +1 -0
- package/dist/adapters/redis.d.ts +30 -0
- package/dist/adapters/redis.d.ts.map +1 -0
- package/dist/adapters/redis.js +186 -0
- package/dist/adapters/redis.js.map +1 -0
- package/dist/context-builder.d.ts +26 -0
- package/dist/context-builder.d.ts.map +1 -0
- package/dist/context-builder.js +154 -0
- package/dist/context-builder.js.map +1 -0
- package/dist/embedding/factory.d.ts +6 -0
- package/dist/embedding/factory.d.ts.map +1 -0
- package/dist/embedding/factory.js +18 -0
- package/dist/embedding/factory.js.map +1 -0
- package/dist/embedding/index.d.ts +7 -0
- package/dist/embedding/index.d.ts.map +1 -0
- package/dist/embedding/index.js +7 -0
- package/dist/embedding/index.js.map +1 -0
- package/dist/embedding/ollama.d.ts +19 -0
- package/dist/embedding/ollama.d.ts.map +1 -0
- package/dist/embedding/ollama.js +63 -0
- package/dist/embedding/ollama.js.map +1 -0
- package/dist/embedding/openai.d.ts +14 -0
- package/dist/embedding/openai.d.ts.map +1 -0
- package/dist/embedding/openai.js +56 -0
- package/dist/embedding/openai.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +169 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +52 -0
- package/dist/schema.js.map +1 -0
- package/dist/token-counter.d.ts +24 -0
- package/dist/token-counter.d.ts.map +1 -0
- package/dist/token-counter.js +40 -0
- package/dist/token-counter.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Cogitator Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @cogitator-ai/memory
|
|
2
|
+
|
|
3
|
+
Memory adapters for Cogitator AI agents. Supports in-memory, Redis (short-term), and PostgreSQL with pgvector (long-term semantic memory).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @cogitator-ai/memory
|
|
9
|
+
|
|
10
|
+
# Optional peer dependencies
|
|
11
|
+
pnpm add ioredis # For Redis adapter
|
|
12
|
+
pnpm add pg # For PostgreSQL adapter
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### In-Memory Adapter
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { InMemoryAdapter } from '@cogitator-ai/memory';
|
|
21
|
+
|
|
22
|
+
const memory = new InMemoryAdapter();
|
|
23
|
+
await memory.saveEntry(threadId, {
|
|
24
|
+
role: 'user',
|
|
25
|
+
content: 'Hello!',
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Redis Adapter
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { RedisAdapter } from '@cogitator-ai/memory';
|
|
33
|
+
|
|
34
|
+
const memory = new RedisAdapter({
|
|
35
|
+
url: 'redis://localhost:6379',
|
|
36
|
+
ttl: 3600, // 1 hour
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### PostgreSQL Adapter
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { PostgresAdapter } from '@cogitator-ai/memory';
|
|
44
|
+
|
|
45
|
+
const memory = new PostgresAdapter({
|
|
46
|
+
connectionString: 'postgresql://localhost:5432/cogitator',
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Context Builder
|
|
51
|
+
|
|
52
|
+
Build token-aware context from memory:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { ContextBuilder } from '@cogitator-ai/memory';
|
|
56
|
+
|
|
57
|
+
const builder = new ContextBuilder({
|
|
58
|
+
maxTokens: 4000,
|
|
59
|
+
strategy: 'recent',
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const context = await builder.build(memory, threadId, {
|
|
63
|
+
systemPrompt: 'You are a helpful assistant',
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Embedding Services
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { createEmbeddingService } from '@cogitator-ai/memory';
|
|
71
|
+
|
|
72
|
+
// OpenAI embeddings
|
|
73
|
+
const embeddings = createEmbeddingService('openai', {
|
|
74
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Ollama embeddings
|
|
78
|
+
const embeddings = createEmbeddingService('ollama', {
|
|
79
|
+
model: 'nomic-embed-text',
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Documentation
|
|
84
|
+
|
|
85
|
+
See the [Cogitator documentation](https://github.com/eL1fe/cogitator) for full API reference.
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-builder.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/context-builder.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { ContextBuilder } from '../context-builder';
|
|
3
|
+
import { InMemoryAdapter } from '../adapters/memory';
|
|
4
|
+
describe('ContextBuilder', () => {
|
|
5
|
+
let adapter;
|
|
6
|
+
let threadId;
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
adapter = new InMemoryAdapter({ provider: 'memory' });
|
|
9
|
+
await adapter.connect();
|
|
10
|
+
const thread = await adapter.createThread('agent1');
|
|
11
|
+
if (!thread.success)
|
|
12
|
+
throw new Error('Failed to create thread');
|
|
13
|
+
threadId = thread.data.id;
|
|
14
|
+
});
|
|
15
|
+
afterEach(async () => {
|
|
16
|
+
await adapter.disconnect();
|
|
17
|
+
});
|
|
18
|
+
describe('basic context building', () => {
|
|
19
|
+
it('builds empty context for empty thread', async () => {
|
|
20
|
+
const builder = new ContextBuilder({ maxTokens: 1000, strategy: 'recent' }, { memoryAdapter: adapter });
|
|
21
|
+
const result = await builder.build({ threadId, agentId: 'agent1' });
|
|
22
|
+
expect(result.messages).toHaveLength(0);
|
|
23
|
+
expect(result.tokenCount).toBe(0);
|
|
24
|
+
expect(result.truncated).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
it('includes system prompt when provided', async () => {
|
|
27
|
+
const builder = new ContextBuilder({ maxTokens: 1000, strategy: 'recent', includeSystemPrompt: true }, { memoryAdapter: adapter });
|
|
28
|
+
const result = await builder.build({
|
|
29
|
+
threadId,
|
|
30
|
+
agentId: 'agent1',
|
|
31
|
+
systemPrompt: 'You are helpful.',
|
|
32
|
+
});
|
|
33
|
+
expect(result.messages).toHaveLength(1);
|
|
34
|
+
expect(result.messages[0].role).toBe('system');
|
|
35
|
+
expect(result.messages[0].content).toBe('You are helpful.');
|
|
36
|
+
});
|
|
37
|
+
it('excludes system prompt when disabled', async () => {
|
|
38
|
+
const builder = new ContextBuilder({ maxTokens: 1000, strategy: 'recent', includeSystemPrompt: false }, { memoryAdapter: adapter });
|
|
39
|
+
const result = await builder.build({
|
|
40
|
+
threadId,
|
|
41
|
+
agentId: 'agent1',
|
|
42
|
+
systemPrompt: 'You are helpful.',
|
|
43
|
+
});
|
|
44
|
+
expect(result.messages).toHaveLength(0);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('recent strategy', () => {
|
|
48
|
+
it('includes all messages when they fit', async () => {
|
|
49
|
+
const messages = [
|
|
50
|
+
{ role: 'user', content: 'Hello' },
|
|
51
|
+
{ role: 'assistant', content: 'Hi there!' },
|
|
52
|
+
{ role: 'user', content: 'How are you?' },
|
|
53
|
+
];
|
|
54
|
+
for (const msg of messages) {
|
|
55
|
+
await adapter.addEntry({ threadId, message: msg, tokenCount: 10 });
|
|
56
|
+
}
|
|
57
|
+
const builder = new ContextBuilder({ maxTokens: 1000, strategy: 'recent' }, { memoryAdapter: adapter });
|
|
58
|
+
const result = await builder.build({ threadId, agentId: 'agent1' });
|
|
59
|
+
expect(result.messages).toHaveLength(3);
|
|
60
|
+
expect(result.truncated).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
it('truncates oldest messages when exceeding limit', async () => {
|
|
63
|
+
for (let i = 0; i < 5; i++) {
|
|
64
|
+
await adapter.addEntry({
|
|
65
|
+
threadId,
|
|
66
|
+
message: { role: 'user', content: `Message ${i}` },
|
|
67
|
+
tokenCount: 10,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const builder = new ContextBuilder({ maxTokens: 35, reserveTokens: 5, strategy: 'recent' }, { memoryAdapter: adapter });
|
|
71
|
+
const result = await builder.build({ threadId, agentId: 'agent1' });
|
|
72
|
+
expect(result.messages).toHaveLength(3);
|
|
73
|
+
expect(result.truncated).toBe(true);
|
|
74
|
+
expect(result.messages[0].content).toBe('Message 2');
|
|
75
|
+
expect(result.messages[2].content).toBe('Message 4');
|
|
76
|
+
});
|
|
77
|
+
it('respects reserve tokens', async () => {
|
|
78
|
+
await adapter.addEntry({
|
|
79
|
+
threadId,
|
|
80
|
+
message: { role: 'user', content: 'Hello' },
|
|
81
|
+
tokenCount: 50,
|
|
82
|
+
});
|
|
83
|
+
const builder = new ContextBuilder({ maxTokens: 100, reserveTokens: 60, strategy: 'recent' }, { memoryAdapter: adapter });
|
|
84
|
+
const result = await builder.build({ threadId, agentId: 'agent1' });
|
|
85
|
+
expect(result.messages).toHaveLength(0);
|
|
86
|
+
expect(result.truncated).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('metadata tracking', () => {
|
|
90
|
+
it('tracks original and included message counts', async () => {
|
|
91
|
+
for (let i = 0; i < 5; i++) {
|
|
92
|
+
await adapter.addEntry({
|
|
93
|
+
threadId,
|
|
94
|
+
message: { role: 'user', content: `Msg ${i}` },
|
|
95
|
+
tokenCount: 10,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const builder = new ContextBuilder({ maxTokens: 35, reserveTokens: 5, strategy: 'recent' }, { memoryAdapter: adapter });
|
|
99
|
+
const result = await builder.build({ threadId, agentId: 'agent1' });
|
|
100
|
+
expect(result.metadata.originalMessageCount).toBe(5);
|
|
101
|
+
expect(result.metadata.includedMessageCount).toBe(3);
|
|
102
|
+
});
|
|
103
|
+
it('tracks token count correctly', async () => {
|
|
104
|
+
await adapter.addEntry({
|
|
105
|
+
threadId,
|
|
106
|
+
message: { role: 'user', content: 'Hello' },
|
|
107
|
+
tokenCount: 15,
|
|
108
|
+
});
|
|
109
|
+
await adapter.addEntry({
|
|
110
|
+
threadId,
|
|
111
|
+
message: { role: 'assistant', content: 'Hi' },
|
|
112
|
+
tokenCount: 10,
|
|
113
|
+
});
|
|
114
|
+
const builder = new ContextBuilder({ maxTokens: 1000, strategy: 'recent' }, { memoryAdapter: adapter });
|
|
115
|
+
const result = await builder.build({ threadId, agentId: 'agent1' });
|
|
116
|
+
expect(result.tokenCount).toBe(25);
|
|
117
|
+
});
|
|
118
|
+
it('includes system prompt tokens in count', async () => {
|
|
119
|
+
const builder = new ContextBuilder({ maxTokens: 1000, strategy: 'recent', includeSystemPrompt: true }, { memoryAdapter: adapter });
|
|
120
|
+
const result = await builder.build({
|
|
121
|
+
threadId,
|
|
122
|
+
agentId: 'agent1',
|
|
123
|
+
systemPrompt: 'Be helpful.',
|
|
124
|
+
});
|
|
125
|
+
expect(result.tokenCount).toBeGreaterThan(0);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
describe('empty facts and semantic results', () => {
|
|
129
|
+
it('returns empty arrays when adapters not provided', async () => {
|
|
130
|
+
const builder = new ContextBuilder({ maxTokens: 1000, strategy: 'recent', includeFacts: true }, { memoryAdapter: adapter });
|
|
131
|
+
const result = await builder.build({ threadId, agentId: 'agent1' });
|
|
132
|
+
expect(result.facts).toHaveLength(0);
|
|
133
|
+
expect(result.semanticResults).toHaveLength(0);
|
|
134
|
+
expect(result.metadata.factsIncluded).toBe(0);
|
|
135
|
+
expect(result.metadata.semanticResultsIncluded).toBe(0);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
//# sourceMappingURL=context-builder.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-builder.test.js","sourceRoot":"","sources":["../../src/__tests__/context-builder.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAI,OAAwB,CAAC;IAC7B,IAAI,QAAgB,CAAC;IAErB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,OAAO,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtD,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAExB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAChE,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACvC,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE,EAClE,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;gBACjC,QAAQ;gBACR,OAAO,EAAE,QAAQ;gBACjB,YAAY,EAAE,kBAAkB;aACjC,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAE,KAAK,EAAE,EACnE,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;gBACjC,QAAQ;gBACR,OAAO,EAAE,QAAQ;gBACjB,YAAY,EAAE,kBAAkB;aACjC,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,QAAQ,GAAc;gBAC1B,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;gBAClC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE;gBAC3C,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE;aAC1C,CAAC;YAEF,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;YACrE,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACvC,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,MAAM,OAAO,CAAC,QAAQ,CAAC;oBACrB,QAAQ;oBACR,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE;oBAClD,UAAU,EAAE,EAAE;iBACf,CAAC,CAAC;YACL,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACvD,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACrD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACvC,MAAM,OAAO,CAAC,QAAQ,CAAC;gBACrB,QAAQ;gBACR,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;gBAC3C,UAAU,EAAE,EAAE;aACf,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACzD,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,MAAM,OAAO,CAAC,QAAQ,CAAC;oBACrB,QAAQ;oBACR,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE;oBAC9C,UAAU,EAAE,EAAE;iBACf,CAAC,CAAC;YACL,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACvD,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC5C,MAAM,OAAO,CAAC,QAAQ,CAAC;gBACrB,QAAQ;gBACR,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;gBAC3C,UAAU,EAAE,EAAE;aACf,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,QAAQ,CAAC;gBACrB,QAAQ;gBACR,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE;gBAC7C,UAAU,EAAE,EAAE;aACf,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACvC,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE,EAClE,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;gBACjC,QAAQ;gBACR,OAAO,EAAE,QAAQ;gBACjB,YAAY,EAAE,aAAa;aAC5B,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAChD,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,EAC3D,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEpE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-adapter.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/memory-adapter.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { InMemoryAdapter } from '../adapters/memory';
|
|
3
|
+
describe('InMemoryAdapter', () => {
|
|
4
|
+
let adapter;
|
|
5
|
+
beforeEach(async () => {
|
|
6
|
+
adapter = new InMemoryAdapter({ provider: 'memory' });
|
|
7
|
+
await adapter.connect();
|
|
8
|
+
});
|
|
9
|
+
afterEach(async () => {
|
|
10
|
+
await adapter.disconnect();
|
|
11
|
+
});
|
|
12
|
+
describe('connect/disconnect', () => {
|
|
13
|
+
it('connects successfully', async () => {
|
|
14
|
+
const result = await adapter.connect();
|
|
15
|
+
expect(result.success).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
it('disconnects and clears data', async () => {
|
|
18
|
+
await adapter.createThread('agent1');
|
|
19
|
+
expect(adapter.stats.threads).toBe(1);
|
|
20
|
+
await adapter.disconnect();
|
|
21
|
+
expect(adapter.stats.threads).toBe(0);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('thread operations', () => {
|
|
25
|
+
it('creates a thread', async () => {
|
|
26
|
+
const result = await adapter.createThread('agent1', { foo: 'bar' });
|
|
27
|
+
expect(result.success).toBe(true);
|
|
28
|
+
if (result.success) {
|
|
29
|
+
expect(result.data.id).toMatch(/^thread_/);
|
|
30
|
+
expect(result.data.agentId).toBe('agent1');
|
|
31
|
+
expect(result.data.metadata).toEqual({ foo: 'bar' });
|
|
32
|
+
expect(result.data.createdAt).toBeInstanceOf(Date);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
it('gets a thread', async () => {
|
|
36
|
+
const created = await adapter.createThread('agent1');
|
|
37
|
+
if (!created.success)
|
|
38
|
+
throw new Error('Failed to create');
|
|
39
|
+
const result = await adapter.getThread(created.data.id);
|
|
40
|
+
expect(result.success).toBe(true);
|
|
41
|
+
if (result.success) {
|
|
42
|
+
expect(result.data?.id).toBe(created.data.id);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
it('returns null for non-existent thread', async () => {
|
|
46
|
+
const result = await adapter.getThread('nonexistent');
|
|
47
|
+
expect(result.success).toBe(true);
|
|
48
|
+
if (result.success) {
|
|
49
|
+
expect(result.data).toBeNull();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
it('updates thread metadata', async () => {
|
|
53
|
+
const created = await adapter.createThread('agent1', { a: 1 });
|
|
54
|
+
if (!created.success)
|
|
55
|
+
throw new Error('Failed to create');
|
|
56
|
+
const result = await adapter.updateThread(created.data.id, { b: 2 });
|
|
57
|
+
expect(result.success).toBe(true);
|
|
58
|
+
if (result.success) {
|
|
59
|
+
expect(result.data.metadata).toEqual({ a: 1, b: 2 });
|
|
60
|
+
expect(result.data.updatedAt.getTime()).toBeGreaterThanOrEqual(created.data.createdAt.getTime());
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
it('returns error for updating non-existent thread', async () => {
|
|
64
|
+
const result = await adapter.updateThread('nonexistent', {});
|
|
65
|
+
expect(result.success).toBe(false);
|
|
66
|
+
if (!result.success) {
|
|
67
|
+
expect(result.error).toContain('not found');
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
it('deletes thread and its entries', async () => {
|
|
71
|
+
const created = await adapter.createThread('agent1');
|
|
72
|
+
if (!created.success)
|
|
73
|
+
throw new Error('Failed to create');
|
|
74
|
+
const message = { role: 'user', content: 'Hello' };
|
|
75
|
+
await adapter.addEntry({
|
|
76
|
+
threadId: created.data.id,
|
|
77
|
+
message,
|
|
78
|
+
tokenCount: 10,
|
|
79
|
+
});
|
|
80
|
+
await adapter.deleteThread(created.data.id);
|
|
81
|
+
const threadResult = await adapter.getThread(created.data.id);
|
|
82
|
+
expect(threadResult.success && threadResult.data).toBeNull();
|
|
83
|
+
expect(adapter.stats.entries).toBe(0);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
describe('entry operations', () => {
|
|
87
|
+
let threadId;
|
|
88
|
+
const message = { role: 'user', content: 'Hello' };
|
|
89
|
+
beforeEach(async () => {
|
|
90
|
+
const result = await adapter.createThread('agent1');
|
|
91
|
+
if (!result.success)
|
|
92
|
+
throw new Error('Failed to create thread');
|
|
93
|
+
threadId = result.data.id;
|
|
94
|
+
});
|
|
95
|
+
it('adds an entry', async () => {
|
|
96
|
+
const result = await adapter.addEntry({
|
|
97
|
+
threadId,
|
|
98
|
+
message,
|
|
99
|
+
tokenCount: 10,
|
|
100
|
+
});
|
|
101
|
+
expect(result.success).toBe(true);
|
|
102
|
+
if (result.success) {
|
|
103
|
+
expect(result.data.id).toMatch(/^entry_/);
|
|
104
|
+
expect(result.data.message).toEqual(message);
|
|
105
|
+
expect(result.data.tokenCount).toBe(10);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
it('gets entries for a thread', async () => {
|
|
109
|
+
await adapter.addEntry({ threadId, message: { role: 'user', content: 'One' }, tokenCount: 5 });
|
|
110
|
+
await adapter.addEntry({ threadId, message: { role: 'assistant', content: 'Two' }, tokenCount: 5 });
|
|
111
|
+
const result = await adapter.getEntries({ threadId });
|
|
112
|
+
expect(result.success).toBe(true);
|
|
113
|
+
if (result.success) {
|
|
114
|
+
expect(result.data).toHaveLength(2);
|
|
115
|
+
expect(result.data[0].message.content).toBe('One');
|
|
116
|
+
expect(result.data[1].message.content).toBe('Two');
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
it('applies limit to entries', async () => {
|
|
120
|
+
for (let i = 0; i < 5; i++) {
|
|
121
|
+
await adapter.addEntry({
|
|
122
|
+
threadId,
|
|
123
|
+
message: { role: 'user', content: `Message ${i}` },
|
|
124
|
+
tokenCount: 5,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const result = await adapter.getEntries({ threadId, limit: 2 });
|
|
128
|
+
expect(result.success).toBe(true);
|
|
129
|
+
if (result.success) {
|
|
130
|
+
expect(result.data).toHaveLength(2);
|
|
131
|
+
expect(result.data[0].message.content).toBe('Message 3');
|
|
132
|
+
expect(result.data[1].message.content).toBe('Message 4');
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
it('filters by before/after dates', async () => {
|
|
136
|
+
const before = new Date();
|
|
137
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
138
|
+
await adapter.addEntry({ threadId, message: { role: 'user', content: 'After' }, tokenCount: 5 });
|
|
139
|
+
const result = await adapter.getEntries({ threadId, before });
|
|
140
|
+
expect(result.success).toBe(true);
|
|
141
|
+
if (result.success) {
|
|
142
|
+
expect(result.data).toHaveLength(0);
|
|
143
|
+
}
|
|
144
|
+
const after = new Date(before.getTime() - 1);
|
|
145
|
+
const result2 = await adapter.getEntries({ threadId, after });
|
|
146
|
+
expect(result2.success).toBe(true);
|
|
147
|
+
if (result2.success) {
|
|
148
|
+
expect(result2.data).toHaveLength(1);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
it('excludes toolCalls when not requested', async () => {
|
|
152
|
+
await adapter.addEntry({
|
|
153
|
+
threadId,
|
|
154
|
+
message,
|
|
155
|
+
tokenCount: 10,
|
|
156
|
+
toolCalls: [{ id: 'tc1', name: 'tool', arguments: {} }],
|
|
157
|
+
});
|
|
158
|
+
const result = await adapter.getEntries({ threadId, includeToolCalls: false });
|
|
159
|
+
expect(result.success).toBe(true);
|
|
160
|
+
if (result.success) {
|
|
161
|
+
expect(result.data[0].toolCalls).toBeUndefined();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
it('includes toolCalls when requested', async () => {
|
|
165
|
+
await adapter.addEntry({
|
|
166
|
+
threadId,
|
|
167
|
+
message,
|
|
168
|
+
tokenCount: 10,
|
|
169
|
+
toolCalls: [{ id: 'tc1', name: 'tool', arguments: {} }],
|
|
170
|
+
});
|
|
171
|
+
const result = await adapter.getEntries({ threadId, includeToolCalls: true });
|
|
172
|
+
expect(result.success).toBe(true);
|
|
173
|
+
if (result.success) {
|
|
174
|
+
expect(result.data[0].toolCalls).toHaveLength(1);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
it('gets single entry by id', async () => {
|
|
178
|
+
const added = await adapter.addEntry({ threadId, message, tokenCount: 10 });
|
|
179
|
+
if (!added.success)
|
|
180
|
+
throw new Error('Failed to add');
|
|
181
|
+
const result = await adapter.getEntry(added.data.id);
|
|
182
|
+
expect(result.success).toBe(true);
|
|
183
|
+
if (result.success) {
|
|
184
|
+
expect(result.data?.message).toEqual(message);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
it('deletes an entry', async () => {
|
|
188
|
+
const added = await adapter.addEntry({ threadId, message, tokenCount: 10 });
|
|
189
|
+
if (!added.success)
|
|
190
|
+
throw new Error('Failed to add');
|
|
191
|
+
await adapter.deleteEntry(added.data.id);
|
|
192
|
+
const result = await adapter.getEntry(added.data.id);
|
|
193
|
+
expect(result.success && result.data).toBeNull();
|
|
194
|
+
});
|
|
195
|
+
it('clears all entries in a thread', async () => {
|
|
196
|
+
await adapter.addEntry({ threadId, message, tokenCount: 10 });
|
|
197
|
+
await adapter.addEntry({ threadId, message, tokenCount: 10 });
|
|
198
|
+
await adapter.clearThread(threadId);
|
|
199
|
+
const result = await adapter.getEntries({ threadId });
|
|
200
|
+
expect(result.success).toBe(true);
|
|
201
|
+
if (result.success) {
|
|
202
|
+
expect(result.data).toHaveLength(0);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
describe('max entries limit', () => {
|
|
207
|
+
it('evicts oldest entries when limit reached', async () => {
|
|
208
|
+
const limitedAdapter = new InMemoryAdapter({ provider: 'memory', maxEntries: 3 });
|
|
209
|
+
await limitedAdapter.connect();
|
|
210
|
+
const thread = await limitedAdapter.createThread('agent1');
|
|
211
|
+
if (!thread.success)
|
|
212
|
+
throw new Error('Failed');
|
|
213
|
+
const threadId = thread.data.id;
|
|
214
|
+
for (let i = 0; i < 5; i++) {
|
|
215
|
+
await limitedAdapter.addEntry({
|
|
216
|
+
threadId,
|
|
217
|
+
message: { role: 'user', content: `Msg ${i}` },
|
|
218
|
+
tokenCount: 5,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
expect(limitedAdapter.stats.entries).toBe(3);
|
|
222
|
+
const result = await limitedAdapter.getEntries({ threadId });
|
|
223
|
+
if (result.success) {
|
|
224
|
+
expect(result.data[0].message.content).toBe('Msg 2');
|
|
225
|
+
expect(result.data[2].message.content).toBe('Msg 4');
|
|
226
|
+
}
|
|
227
|
+
await limitedAdapter.disconnect();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
describe('provider property', () => {
|
|
231
|
+
it('returns memory as provider', () => {
|
|
232
|
+
expect(adapter.provider).toBe('memory');
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
//# sourceMappingURL=memory-adapter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-adapter.test.js","sourceRoot":"","sources":["../../src/__tests__/memory-adapter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-counter.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/token-counter.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { countTokens, countMessageTokens, countMessagesTokens, truncateToTokens, } from '../token-counter';
|
|
3
|
+
describe('countTokens', () => {
|
|
4
|
+
it('returns 0 for empty string', () => {
|
|
5
|
+
expect(countTokens('')).toBe(0);
|
|
6
|
+
});
|
|
7
|
+
it('estimates tokens based on character count', () => {
|
|
8
|
+
expect(countTokens('Hello')).toBe(2);
|
|
9
|
+
expect(countTokens('Hello World!')).toBe(3);
|
|
10
|
+
expect(countTokens('This is a longer sentence.')).toBe(7);
|
|
11
|
+
});
|
|
12
|
+
it('handles unicode characters', () => {
|
|
13
|
+
expect(countTokens('Привет')).toBe(2);
|
|
14
|
+
expect(countTokens('🚀🌟')).toBe(1);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
describe('countMessageTokens', () => {
|
|
18
|
+
it('counts tokens with message overhead', () => {
|
|
19
|
+
const message = { role: 'user', content: 'Hello' };
|
|
20
|
+
expect(countMessageTokens(message)).toBe(6);
|
|
21
|
+
});
|
|
22
|
+
it('handles empty content', () => {
|
|
23
|
+
const message = { role: 'system', content: '' };
|
|
24
|
+
expect(countMessageTokens(message)).toBe(4);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('countMessagesTokens', () => {
|
|
28
|
+
it('counts total tokens for multiple messages', () => {
|
|
29
|
+
const messages = [
|
|
30
|
+
{ role: 'system', content: 'You are helpful.' },
|
|
31
|
+
{ role: 'user', content: 'Hello' },
|
|
32
|
+
{ role: 'assistant', content: 'Hi there!' },
|
|
33
|
+
];
|
|
34
|
+
expect(countMessagesTokens(messages)).toBe(21);
|
|
35
|
+
});
|
|
36
|
+
it('returns 0 for empty array', () => {
|
|
37
|
+
expect(countMessagesTokens([])).toBe(0);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe('truncateToTokens', () => {
|
|
41
|
+
it('returns text unchanged if within limit', () => {
|
|
42
|
+
const text = 'Hello';
|
|
43
|
+
expect(truncateToTokens(text, 10)).toBe('Hello');
|
|
44
|
+
});
|
|
45
|
+
it('truncates text to fit token limit', () => {
|
|
46
|
+
const text = 'This is a very long sentence that needs to be truncated';
|
|
47
|
+
const result = truncateToTokens(text, 5);
|
|
48
|
+
expect(result).toBe('This is a very long ');
|
|
49
|
+
expect(result.length).toBe(20);
|
|
50
|
+
});
|
|
51
|
+
it('handles edge cases', () => {
|
|
52
|
+
expect(truncateToTokens('', 10)).toBe('');
|
|
53
|
+
expect(truncateToTokens('Hi', 0)).toBe('');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=token-counter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-counter.test.js","sourceRoot":"","sources":["../../src/__tests__/token-counter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base memory adapter - abstract class for all adapters
|
|
3
|
+
*/
|
|
4
|
+
import type { MemoryAdapter, MemoryProvider, MemoryResult, Thread, MemoryEntry, MemoryQueryOptions } from '@cogitator-ai/types';
|
|
5
|
+
export declare abstract class BaseMemoryAdapter implements MemoryAdapter {
|
|
6
|
+
abstract readonly provider: MemoryProvider;
|
|
7
|
+
abstract createThread(agentId: string, metadata?: Record<string, unknown>): Promise<MemoryResult<Thread>>;
|
|
8
|
+
abstract getThread(threadId: string): Promise<MemoryResult<Thread | null>>;
|
|
9
|
+
abstract updateThread(threadId: string, metadata: Record<string, unknown>): Promise<MemoryResult<Thread>>;
|
|
10
|
+
abstract deleteThread(threadId: string): Promise<MemoryResult<void>>;
|
|
11
|
+
abstract addEntry(entry: Omit<MemoryEntry, 'id' | 'createdAt'>): Promise<MemoryResult<MemoryEntry>>;
|
|
12
|
+
abstract getEntries(options: MemoryQueryOptions): Promise<MemoryResult<MemoryEntry[]>>;
|
|
13
|
+
abstract getEntry(entryId: string): Promise<MemoryResult<MemoryEntry | null>>;
|
|
14
|
+
abstract deleteEntry(entryId: string): Promise<MemoryResult<void>>;
|
|
15
|
+
abstract clearThread(threadId: string): Promise<MemoryResult<void>>;
|
|
16
|
+
abstract connect(): Promise<MemoryResult<void>>;
|
|
17
|
+
abstract disconnect(): Promise<MemoryResult<void>>;
|
|
18
|
+
protected generateId(prefix: string): string;
|
|
19
|
+
protected success<T>(data: T): MemoryResult<T>;
|
|
20
|
+
protected failure(error: string): MemoryResult<never>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,MAAM,EACN,WAAW,EACX,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;AAE7B,8BAAsB,iBAAkB,YAAW,aAAa;IAC9D,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAE3C,QAAQ,CAAC,YAAY,CACnB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAEhC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE1E,QAAQ,CAAC,YAAY,CACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAEhC,QAAQ,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAEpE,QAAQ,CAAC,QAAQ,CACf,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,CAAC,GAC3C,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IAErC,QAAQ,CAAC,UAAU,CACjB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;IAEvC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE7E,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAElE,QAAQ,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAEnE,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAE/C,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAElD,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI5C,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;IAI9C,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC;CAGtD"}
|