@seizn/spring 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/README.md +198 -0
- package/dist/index.d.mts +224 -0
- package/dist/index.d.ts +224 -0
- package/dist/index.js +255 -0
- package/dist/index.mjs +227 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# @seizn/spring
|
|
2
|
+
|
|
3
|
+
Semantic Memory SDK for AI Applications. Store, search, and retrieve memories with automatic embedding and vector similarity search.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @seizn/spring
|
|
9
|
+
# or
|
|
10
|
+
yarn add @seizn/spring
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @seizn/spring
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { SpringClient } from '@seizn/spring';
|
|
19
|
+
|
|
20
|
+
const spring = new SpringClient({
|
|
21
|
+
apiKey: process.env.SEIZN_API_KEY!,
|
|
22
|
+
namespace: 'my-app',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Store a memory
|
|
26
|
+
await spring.remember('User prefers dark mode');
|
|
27
|
+
|
|
28
|
+
// Search memories
|
|
29
|
+
const memories = await spring.recall('UI preferences');
|
|
30
|
+
console.log(memories);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- **Semantic Search**: Vector-based similarity search with automatic embedding
|
|
36
|
+
- **Hybrid Search**: Combine vector and keyword search for better results
|
|
37
|
+
- **Memory Types**: Organize memories by type (fact, preference, experience, etc.)
|
|
38
|
+
- **Namespaces**: Isolate memories by namespace for multi-tenant apps
|
|
39
|
+
- **Bulk Operations**: Add multiple memories in a single request
|
|
40
|
+
- **Export/Import**: Backup and restore memories
|
|
41
|
+
|
|
42
|
+
## API Reference
|
|
43
|
+
|
|
44
|
+
### Configuration
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const spring = new SpringClient({
|
|
48
|
+
apiKey: 'szn_...', // Required: Your Seizn API key
|
|
49
|
+
namespace: 'default', // Optional: Default namespace
|
|
50
|
+
baseUrl: 'https://seizn.com/api', // Optional: API base URL
|
|
51
|
+
timeout: 30000, // Optional: Request timeout (ms)
|
|
52
|
+
retries: 3, // Optional: Max retry attempts
|
|
53
|
+
onError: (error) => {}, // Optional: Error callback
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Core Methods
|
|
58
|
+
|
|
59
|
+
#### `add(request)` - Add a memory
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const memory = await spring.add({
|
|
63
|
+
content: 'User prefers dark mode',
|
|
64
|
+
memory_type: 'preference', // fact | preference | experience | relationship | instruction | conversation
|
|
65
|
+
tags: ['ui', 'settings'],
|
|
66
|
+
namespace: 'my-app',
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### `search(query)` - Search memories
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// Simple search
|
|
74
|
+
const results = await spring.search('UI preferences');
|
|
75
|
+
|
|
76
|
+
// Advanced search
|
|
77
|
+
const results = await spring.search({
|
|
78
|
+
query: 'UI preferences',
|
|
79
|
+
limit: 10,
|
|
80
|
+
threshold: 0.7,
|
|
81
|
+
mode: 'hybrid', // vector | hybrid | keyword
|
|
82
|
+
tags: ['ui'],
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### `get(id)` - Get a memory by ID
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const memory = await spring.get('mem_123');
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### `update(id, request)` - Update a memory
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
const memory = await spring.update('mem_123', {
|
|
96
|
+
content: 'User prefers light mode',
|
|
97
|
+
tags: ['ui', 'settings', 'updated'],
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### `delete(ids)` - Delete memories
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
await spring.delete('mem_123');
|
|
105
|
+
// or delete multiple
|
|
106
|
+
await spring.delete(['mem_123', 'mem_456']);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Shortcuts
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// remember = add with type 'fact'
|
|
113
|
+
await spring.remember('Important fact');
|
|
114
|
+
|
|
115
|
+
// recall = search and return results array
|
|
116
|
+
const memories = await spring.recall('query', 5);
|
|
117
|
+
|
|
118
|
+
// forget = delete
|
|
119
|
+
await spring.forget('mem_123');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Bulk Operations
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
const result = await spring.bulkAdd([
|
|
126
|
+
{ content: 'Memory 1', memory_type: 'fact' },
|
|
127
|
+
{ content: 'Memory 2', memory_type: 'preference' },
|
|
128
|
+
]);
|
|
129
|
+
console.log(`Added: ${result.added}, Failed: ${result.failed}`);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Export/Import
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// Export all memories
|
|
136
|
+
const backup = await spring.export();
|
|
137
|
+
|
|
138
|
+
// Export specific namespace
|
|
139
|
+
const backup = await spring.export({ namespace: 'my-app' });
|
|
140
|
+
|
|
141
|
+
// Import memories
|
|
142
|
+
const result = await spring.import(backup);
|
|
143
|
+
console.log(`Imported: ${result.imported}, Skipped: ${result.skipped}`);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Analytics
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
const stats = await spring.stats();
|
|
150
|
+
console.log(`Total memories: ${stats.totalMemories}`);
|
|
151
|
+
console.log(`Storage used: ${stats.storageUsedMb} MB`);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Error Handling
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { SpringClient, SpringError } from '@seizn/spring';
|
|
158
|
+
|
|
159
|
+
const spring = new SpringClient({
|
|
160
|
+
apiKey: 'szn_...',
|
|
161
|
+
onError: (error: SpringError) => {
|
|
162
|
+
console.error(`Error [${error.code}]: ${error.message}`);
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
await spring.search('query');
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if ((error as SpringError).code === 'RATE_LIMITED') {
|
|
170
|
+
// Handle rate limiting
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## TypeScript Support
|
|
176
|
+
|
|
177
|
+
Full TypeScript support with exported types:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import type {
|
|
181
|
+
Memory,
|
|
182
|
+
MemoryType,
|
|
183
|
+
MemoryScope,
|
|
184
|
+
SearchMode,
|
|
185
|
+
SpringClientConfig,
|
|
186
|
+
SpringError,
|
|
187
|
+
} from '@seizn/spring';
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT - see [LICENSE](LICENSE) for details.
|
|
193
|
+
|
|
194
|
+
## Links
|
|
195
|
+
|
|
196
|
+
- [Documentation](https://docs.seizn.com/spring)
|
|
197
|
+
- [API Reference](https://docs.seizn.com/api-reference)
|
|
198
|
+
- [GitHub](https://github.com/iruhana/seizn)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seizn Spring (Memory Layer) - Core Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the Spring Memory SDK.
|
|
5
|
+
* These types define the wire format for SDK consumers.
|
|
6
|
+
*/
|
|
7
|
+
type MemoryType = 'fact' | 'preference' | 'experience' | 'relationship' | 'instruction' | 'conversation';
|
|
8
|
+
type MemoryScope = 'user' | 'session' | 'global' | 'project';
|
|
9
|
+
interface Memory {
|
|
10
|
+
id: string;
|
|
11
|
+
content: string;
|
|
12
|
+
memoryType: MemoryType;
|
|
13
|
+
tags: string[];
|
|
14
|
+
namespace: string;
|
|
15
|
+
scope: MemoryScope;
|
|
16
|
+
sessionId?: string;
|
|
17
|
+
agentId?: string;
|
|
18
|
+
source: string;
|
|
19
|
+
confidence: number;
|
|
20
|
+
importance: number;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt?: string;
|
|
23
|
+
accessCount?: number;
|
|
24
|
+
lastAccessedAt?: string;
|
|
25
|
+
}
|
|
26
|
+
interface MemorySearchResult extends Memory {
|
|
27
|
+
similarity: number;
|
|
28
|
+
combinedScore?: number;
|
|
29
|
+
keywordScore?: number;
|
|
30
|
+
}
|
|
31
|
+
interface AddMemoryRequest {
|
|
32
|
+
content: string;
|
|
33
|
+
memory_type?: MemoryType;
|
|
34
|
+
tags?: string[];
|
|
35
|
+
namespace?: string;
|
|
36
|
+
scope?: MemoryScope;
|
|
37
|
+
session_id?: string;
|
|
38
|
+
agent_id?: string;
|
|
39
|
+
source?: string;
|
|
40
|
+
}
|
|
41
|
+
interface AddMemoryResponse {
|
|
42
|
+
success: boolean;
|
|
43
|
+
memory: Memory;
|
|
44
|
+
}
|
|
45
|
+
type SearchMode = 'vector' | 'hybrid' | 'keyword';
|
|
46
|
+
interface SearchMemoriesRequest {
|
|
47
|
+
query: string;
|
|
48
|
+
limit?: number;
|
|
49
|
+
threshold?: number;
|
|
50
|
+
namespace?: string;
|
|
51
|
+
mode?: SearchMode;
|
|
52
|
+
tags?: string[];
|
|
53
|
+
}
|
|
54
|
+
interface SearchMemoriesResponse {
|
|
55
|
+
success: boolean;
|
|
56
|
+
mode: SearchMode;
|
|
57
|
+
results: MemorySearchResult[];
|
|
58
|
+
count: number;
|
|
59
|
+
}
|
|
60
|
+
interface UpdateMemoryRequest {
|
|
61
|
+
content?: string;
|
|
62
|
+
memory_type?: MemoryType;
|
|
63
|
+
tags?: string[];
|
|
64
|
+
namespace?: string;
|
|
65
|
+
importance?: number;
|
|
66
|
+
}
|
|
67
|
+
interface UpdateMemoryResponse {
|
|
68
|
+
success: boolean;
|
|
69
|
+
memory: Memory;
|
|
70
|
+
}
|
|
71
|
+
interface DeleteMemoriesRequest {
|
|
72
|
+
ids: string[];
|
|
73
|
+
}
|
|
74
|
+
interface DeleteMemoriesResponse {
|
|
75
|
+
success: boolean;
|
|
76
|
+
deleted: number;
|
|
77
|
+
}
|
|
78
|
+
interface MemoryExport {
|
|
79
|
+
version: '1.0';
|
|
80
|
+
exportedAt: string;
|
|
81
|
+
userId: string;
|
|
82
|
+
namespace?: string;
|
|
83
|
+
memories: Memory[];
|
|
84
|
+
count: number;
|
|
85
|
+
}
|
|
86
|
+
interface MemoryImportResult {
|
|
87
|
+
success: boolean;
|
|
88
|
+
imported: number;
|
|
89
|
+
skipped: number;
|
|
90
|
+
errors: string[];
|
|
91
|
+
}
|
|
92
|
+
interface SpringClientConfig {
|
|
93
|
+
apiKey: string;
|
|
94
|
+
baseUrl?: string;
|
|
95
|
+
namespace?: string;
|
|
96
|
+
timeout?: number;
|
|
97
|
+
retries?: number;
|
|
98
|
+
onError?: (error: SpringError) => void;
|
|
99
|
+
}
|
|
100
|
+
interface SpringError {
|
|
101
|
+
code: string;
|
|
102
|
+
message: string;
|
|
103
|
+
status?: number;
|
|
104
|
+
details?: Record<string, unknown>;
|
|
105
|
+
}
|
|
106
|
+
interface BulkAddRequest {
|
|
107
|
+
memories: AddMemoryRequest[];
|
|
108
|
+
}
|
|
109
|
+
interface BulkAddResponse {
|
|
110
|
+
success: boolean;
|
|
111
|
+
added: number;
|
|
112
|
+
failed: number;
|
|
113
|
+
errors?: Array<{
|
|
114
|
+
index: number;
|
|
115
|
+
error: string;
|
|
116
|
+
}>;
|
|
117
|
+
}
|
|
118
|
+
interface MemoryStats {
|
|
119
|
+
totalMemories: number;
|
|
120
|
+
byType: Record<MemoryType, number>;
|
|
121
|
+
byNamespace: Record<string, number>;
|
|
122
|
+
recentAccessCount: number;
|
|
123
|
+
storageUsedMb: number;
|
|
124
|
+
}
|
|
125
|
+
interface MemoryUsage {
|
|
126
|
+
period: 'day' | 'week' | 'month';
|
|
127
|
+
searches: number;
|
|
128
|
+
additions: number;
|
|
129
|
+
deletions: number;
|
|
130
|
+
embeddingTokens: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Seizn Spring SDK Client
|
|
135
|
+
*
|
|
136
|
+
* TypeScript/JavaScript SDK for the Spring Memory API.
|
|
137
|
+
* Provides a simple interface for memory operations.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* import { SpringClient } from '@seizn/spring';
|
|
142
|
+
*
|
|
143
|
+
* const spring = new SpringClient({
|
|
144
|
+
* apiKey: 'szn_...',
|
|
145
|
+
* namespace: 'my-app',
|
|
146
|
+
* });
|
|
147
|
+
*
|
|
148
|
+
* // Add a memory
|
|
149
|
+
* await spring.add({
|
|
150
|
+
* content: 'User prefers dark mode',
|
|
151
|
+
* memory_type: 'preference',
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* // Search memories
|
|
155
|
+
* const results = await spring.search('UI preferences');
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
declare class SpringClient {
|
|
160
|
+
private readonly apiKey;
|
|
161
|
+
private readonly baseUrl;
|
|
162
|
+
private readonly namespace;
|
|
163
|
+
private readonly timeout;
|
|
164
|
+
private readonly retries;
|
|
165
|
+
private readonly onError?;
|
|
166
|
+
constructor(config: SpringClientConfig);
|
|
167
|
+
/**
|
|
168
|
+
* Add a new memory
|
|
169
|
+
*/
|
|
170
|
+
add(request: AddMemoryRequest): Promise<Memory>;
|
|
171
|
+
/**
|
|
172
|
+
* Search for memories
|
|
173
|
+
*/
|
|
174
|
+
search(queryOrRequest: string | SearchMemoriesRequest): Promise<SearchMemoriesResponse>;
|
|
175
|
+
/**
|
|
176
|
+
* Get a memory by ID
|
|
177
|
+
*/
|
|
178
|
+
get(id: string): Promise<Memory>;
|
|
179
|
+
/**
|
|
180
|
+
* Update a memory
|
|
181
|
+
*/
|
|
182
|
+
update(id: string, request: UpdateMemoryRequest): Promise<Memory>;
|
|
183
|
+
/**
|
|
184
|
+
* Delete memories by IDs
|
|
185
|
+
*/
|
|
186
|
+
delete(ids: string | string[]): Promise<number>;
|
|
187
|
+
/**
|
|
188
|
+
* Add multiple memories at once
|
|
189
|
+
*/
|
|
190
|
+
bulkAdd(memories: AddMemoryRequest[]): Promise<BulkAddResponse>;
|
|
191
|
+
/**
|
|
192
|
+
* Export memories
|
|
193
|
+
*/
|
|
194
|
+
export(options?: {
|
|
195
|
+
namespace?: string;
|
|
196
|
+
}): Promise<MemoryExport>;
|
|
197
|
+
/**
|
|
198
|
+
* Import memories from export
|
|
199
|
+
*/
|
|
200
|
+
import(data: MemoryExport): Promise<MemoryImportResult>;
|
|
201
|
+
/**
|
|
202
|
+
* Get memory statistics
|
|
203
|
+
*/
|
|
204
|
+
stats(): Promise<MemoryStats>;
|
|
205
|
+
/**
|
|
206
|
+
* Quick remember - shorthand for adding a fact
|
|
207
|
+
*/
|
|
208
|
+
remember(content: string, tags?: string[]): Promise<Memory>;
|
|
209
|
+
/**
|
|
210
|
+
* Quick recall - shorthand for searching
|
|
211
|
+
*/
|
|
212
|
+
recall(query: string, limit?: number): Promise<Memory[]>;
|
|
213
|
+
/**
|
|
214
|
+
* Forget - shorthand for deleting
|
|
215
|
+
*/
|
|
216
|
+
forget(ids: string | string[]): Promise<number>;
|
|
217
|
+
private request;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create a Spring client instance
|
|
221
|
+
*/
|
|
222
|
+
declare function createSpringClient(config: SpringClientConfig): SpringClient;
|
|
223
|
+
|
|
224
|
+
export { type AddMemoryRequest, type AddMemoryResponse, type BulkAddRequest, type BulkAddResponse, type DeleteMemoriesRequest, type DeleteMemoriesResponse, type Memory, type MemoryExport, type MemoryImportResult, type MemoryScope, type MemorySearchResult, type MemoryStats, type MemoryType, type MemoryUsage, type SearchMemoriesRequest, type SearchMemoriesResponse, type SearchMode, SpringClient, type SpringClientConfig, type SpringError, type UpdateMemoryRequest, type UpdateMemoryResponse, createSpringClient };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seizn Spring (Memory Layer) - Core Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the Spring Memory SDK.
|
|
5
|
+
* These types define the wire format for SDK consumers.
|
|
6
|
+
*/
|
|
7
|
+
type MemoryType = 'fact' | 'preference' | 'experience' | 'relationship' | 'instruction' | 'conversation';
|
|
8
|
+
type MemoryScope = 'user' | 'session' | 'global' | 'project';
|
|
9
|
+
interface Memory {
|
|
10
|
+
id: string;
|
|
11
|
+
content: string;
|
|
12
|
+
memoryType: MemoryType;
|
|
13
|
+
tags: string[];
|
|
14
|
+
namespace: string;
|
|
15
|
+
scope: MemoryScope;
|
|
16
|
+
sessionId?: string;
|
|
17
|
+
agentId?: string;
|
|
18
|
+
source: string;
|
|
19
|
+
confidence: number;
|
|
20
|
+
importance: number;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt?: string;
|
|
23
|
+
accessCount?: number;
|
|
24
|
+
lastAccessedAt?: string;
|
|
25
|
+
}
|
|
26
|
+
interface MemorySearchResult extends Memory {
|
|
27
|
+
similarity: number;
|
|
28
|
+
combinedScore?: number;
|
|
29
|
+
keywordScore?: number;
|
|
30
|
+
}
|
|
31
|
+
interface AddMemoryRequest {
|
|
32
|
+
content: string;
|
|
33
|
+
memory_type?: MemoryType;
|
|
34
|
+
tags?: string[];
|
|
35
|
+
namespace?: string;
|
|
36
|
+
scope?: MemoryScope;
|
|
37
|
+
session_id?: string;
|
|
38
|
+
agent_id?: string;
|
|
39
|
+
source?: string;
|
|
40
|
+
}
|
|
41
|
+
interface AddMemoryResponse {
|
|
42
|
+
success: boolean;
|
|
43
|
+
memory: Memory;
|
|
44
|
+
}
|
|
45
|
+
type SearchMode = 'vector' | 'hybrid' | 'keyword';
|
|
46
|
+
interface SearchMemoriesRequest {
|
|
47
|
+
query: string;
|
|
48
|
+
limit?: number;
|
|
49
|
+
threshold?: number;
|
|
50
|
+
namespace?: string;
|
|
51
|
+
mode?: SearchMode;
|
|
52
|
+
tags?: string[];
|
|
53
|
+
}
|
|
54
|
+
interface SearchMemoriesResponse {
|
|
55
|
+
success: boolean;
|
|
56
|
+
mode: SearchMode;
|
|
57
|
+
results: MemorySearchResult[];
|
|
58
|
+
count: number;
|
|
59
|
+
}
|
|
60
|
+
interface UpdateMemoryRequest {
|
|
61
|
+
content?: string;
|
|
62
|
+
memory_type?: MemoryType;
|
|
63
|
+
tags?: string[];
|
|
64
|
+
namespace?: string;
|
|
65
|
+
importance?: number;
|
|
66
|
+
}
|
|
67
|
+
interface UpdateMemoryResponse {
|
|
68
|
+
success: boolean;
|
|
69
|
+
memory: Memory;
|
|
70
|
+
}
|
|
71
|
+
interface DeleteMemoriesRequest {
|
|
72
|
+
ids: string[];
|
|
73
|
+
}
|
|
74
|
+
interface DeleteMemoriesResponse {
|
|
75
|
+
success: boolean;
|
|
76
|
+
deleted: number;
|
|
77
|
+
}
|
|
78
|
+
interface MemoryExport {
|
|
79
|
+
version: '1.0';
|
|
80
|
+
exportedAt: string;
|
|
81
|
+
userId: string;
|
|
82
|
+
namespace?: string;
|
|
83
|
+
memories: Memory[];
|
|
84
|
+
count: number;
|
|
85
|
+
}
|
|
86
|
+
interface MemoryImportResult {
|
|
87
|
+
success: boolean;
|
|
88
|
+
imported: number;
|
|
89
|
+
skipped: number;
|
|
90
|
+
errors: string[];
|
|
91
|
+
}
|
|
92
|
+
interface SpringClientConfig {
|
|
93
|
+
apiKey: string;
|
|
94
|
+
baseUrl?: string;
|
|
95
|
+
namespace?: string;
|
|
96
|
+
timeout?: number;
|
|
97
|
+
retries?: number;
|
|
98
|
+
onError?: (error: SpringError) => void;
|
|
99
|
+
}
|
|
100
|
+
interface SpringError {
|
|
101
|
+
code: string;
|
|
102
|
+
message: string;
|
|
103
|
+
status?: number;
|
|
104
|
+
details?: Record<string, unknown>;
|
|
105
|
+
}
|
|
106
|
+
interface BulkAddRequest {
|
|
107
|
+
memories: AddMemoryRequest[];
|
|
108
|
+
}
|
|
109
|
+
interface BulkAddResponse {
|
|
110
|
+
success: boolean;
|
|
111
|
+
added: number;
|
|
112
|
+
failed: number;
|
|
113
|
+
errors?: Array<{
|
|
114
|
+
index: number;
|
|
115
|
+
error: string;
|
|
116
|
+
}>;
|
|
117
|
+
}
|
|
118
|
+
interface MemoryStats {
|
|
119
|
+
totalMemories: number;
|
|
120
|
+
byType: Record<MemoryType, number>;
|
|
121
|
+
byNamespace: Record<string, number>;
|
|
122
|
+
recentAccessCount: number;
|
|
123
|
+
storageUsedMb: number;
|
|
124
|
+
}
|
|
125
|
+
interface MemoryUsage {
|
|
126
|
+
period: 'day' | 'week' | 'month';
|
|
127
|
+
searches: number;
|
|
128
|
+
additions: number;
|
|
129
|
+
deletions: number;
|
|
130
|
+
embeddingTokens: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Seizn Spring SDK Client
|
|
135
|
+
*
|
|
136
|
+
* TypeScript/JavaScript SDK for the Spring Memory API.
|
|
137
|
+
* Provides a simple interface for memory operations.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* import { SpringClient } from '@seizn/spring';
|
|
142
|
+
*
|
|
143
|
+
* const spring = new SpringClient({
|
|
144
|
+
* apiKey: 'szn_...',
|
|
145
|
+
* namespace: 'my-app',
|
|
146
|
+
* });
|
|
147
|
+
*
|
|
148
|
+
* // Add a memory
|
|
149
|
+
* await spring.add({
|
|
150
|
+
* content: 'User prefers dark mode',
|
|
151
|
+
* memory_type: 'preference',
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* // Search memories
|
|
155
|
+
* const results = await spring.search('UI preferences');
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
declare class SpringClient {
|
|
160
|
+
private readonly apiKey;
|
|
161
|
+
private readonly baseUrl;
|
|
162
|
+
private readonly namespace;
|
|
163
|
+
private readonly timeout;
|
|
164
|
+
private readonly retries;
|
|
165
|
+
private readonly onError?;
|
|
166
|
+
constructor(config: SpringClientConfig);
|
|
167
|
+
/**
|
|
168
|
+
* Add a new memory
|
|
169
|
+
*/
|
|
170
|
+
add(request: AddMemoryRequest): Promise<Memory>;
|
|
171
|
+
/**
|
|
172
|
+
* Search for memories
|
|
173
|
+
*/
|
|
174
|
+
search(queryOrRequest: string | SearchMemoriesRequest): Promise<SearchMemoriesResponse>;
|
|
175
|
+
/**
|
|
176
|
+
* Get a memory by ID
|
|
177
|
+
*/
|
|
178
|
+
get(id: string): Promise<Memory>;
|
|
179
|
+
/**
|
|
180
|
+
* Update a memory
|
|
181
|
+
*/
|
|
182
|
+
update(id: string, request: UpdateMemoryRequest): Promise<Memory>;
|
|
183
|
+
/**
|
|
184
|
+
* Delete memories by IDs
|
|
185
|
+
*/
|
|
186
|
+
delete(ids: string | string[]): Promise<number>;
|
|
187
|
+
/**
|
|
188
|
+
* Add multiple memories at once
|
|
189
|
+
*/
|
|
190
|
+
bulkAdd(memories: AddMemoryRequest[]): Promise<BulkAddResponse>;
|
|
191
|
+
/**
|
|
192
|
+
* Export memories
|
|
193
|
+
*/
|
|
194
|
+
export(options?: {
|
|
195
|
+
namespace?: string;
|
|
196
|
+
}): Promise<MemoryExport>;
|
|
197
|
+
/**
|
|
198
|
+
* Import memories from export
|
|
199
|
+
*/
|
|
200
|
+
import(data: MemoryExport): Promise<MemoryImportResult>;
|
|
201
|
+
/**
|
|
202
|
+
* Get memory statistics
|
|
203
|
+
*/
|
|
204
|
+
stats(): Promise<MemoryStats>;
|
|
205
|
+
/**
|
|
206
|
+
* Quick remember - shorthand for adding a fact
|
|
207
|
+
*/
|
|
208
|
+
remember(content: string, tags?: string[]): Promise<Memory>;
|
|
209
|
+
/**
|
|
210
|
+
* Quick recall - shorthand for searching
|
|
211
|
+
*/
|
|
212
|
+
recall(query: string, limit?: number): Promise<Memory[]>;
|
|
213
|
+
/**
|
|
214
|
+
* Forget - shorthand for deleting
|
|
215
|
+
*/
|
|
216
|
+
forget(ids: string | string[]): Promise<number>;
|
|
217
|
+
private request;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create a Spring client instance
|
|
221
|
+
*/
|
|
222
|
+
declare function createSpringClient(config: SpringClientConfig): SpringClient;
|
|
223
|
+
|
|
224
|
+
export { type AddMemoryRequest, type AddMemoryResponse, type BulkAddRequest, type BulkAddResponse, type DeleteMemoriesRequest, type DeleteMemoriesResponse, type Memory, type MemoryExport, type MemoryImportResult, type MemoryScope, type MemorySearchResult, type MemoryStats, type MemoryType, type MemoryUsage, type SearchMemoriesRequest, type SearchMemoriesResponse, type SearchMode, SpringClient, type SpringClientConfig, type SpringError, type UpdateMemoryRequest, type UpdateMemoryResponse, createSpringClient };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
SpringClient: () => SpringClient,
|
|
24
|
+
createSpringClient: () => createSpringClient
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/client.ts
|
|
29
|
+
var DEFAULT_BASE_URL = "https://seizn.com/api";
|
|
30
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
31
|
+
var DEFAULT_RETRIES = 3;
|
|
32
|
+
var SpringClient = class {
|
|
33
|
+
constructor(config) {
|
|
34
|
+
if (!config.apiKey) {
|
|
35
|
+
throw new Error("API key is required");
|
|
36
|
+
}
|
|
37
|
+
this.apiKey = config.apiKey;
|
|
38
|
+
this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
39
|
+
this.namespace = config.namespace ?? "default";
|
|
40
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
41
|
+
this.retries = config.retries ?? DEFAULT_RETRIES;
|
|
42
|
+
this.onError = config.onError;
|
|
43
|
+
}
|
|
44
|
+
// ============================================
|
|
45
|
+
// Core Operations
|
|
46
|
+
// ============================================
|
|
47
|
+
/**
|
|
48
|
+
* Add a new memory
|
|
49
|
+
*/
|
|
50
|
+
async add(request) {
|
|
51
|
+
const response = await this.request("/memories", {
|
|
52
|
+
method: "POST",
|
|
53
|
+
body: {
|
|
54
|
+
...request,
|
|
55
|
+
namespace: request.namespace ?? this.namespace
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return response.memory;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Search for memories
|
|
62
|
+
*/
|
|
63
|
+
async search(queryOrRequest) {
|
|
64
|
+
const params = typeof queryOrRequest === "string" ? { query: queryOrRequest } : queryOrRequest;
|
|
65
|
+
const searchParams = new URLSearchParams({
|
|
66
|
+
query: params.query,
|
|
67
|
+
limit: String(params.limit ?? 10),
|
|
68
|
+
threshold: String(params.threshold ?? 0.7),
|
|
69
|
+
namespace: params.namespace ?? this.namespace,
|
|
70
|
+
mode: params.mode ?? "vector"
|
|
71
|
+
});
|
|
72
|
+
if (params.tags?.length) {
|
|
73
|
+
searchParams.set("tags", params.tags.join(","));
|
|
74
|
+
}
|
|
75
|
+
return this.request(`/memories?${searchParams}`);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get a memory by ID
|
|
79
|
+
*/
|
|
80
|
+
async get(id) {
|
|
81
|
+
const response = await this.request(
|
|
82
|
+
`/memories/${id}`
|
|
83
|
+
);
|
|
84
|
+
return response.memory;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Update a memory
|
|
88
|
+
*/
|
|
89
|
+
async update(id, request) {
|
|
90
|
+
const response = await this.request(`/memories/${id}`, {
|
|
91
|
+
method: "PUT",
|
|
92
|
+
body: request
|
|
93
|
+
});
|
|
94
|
+
return response.memory;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Delete memories by IDs
|
|
98
|
+
*/
|
|
99
|
+
async delete(ids) {
|
|
100
|
+
const idsArray = Array.isArray(ids) ? ids : [ids];
|
|
101
|
+
const response = await this.request(
|
|
102
|
+
`/memories?ids=${idsArray.join(",")}`,
|
|
103
|
+
{ method: "DELETE" }
|
|
104
|
+
);
|
|
105
|
+
return response.deleted;
|
|
106
|
+
}
|
|
107
|
+
// ============================================
|
|
108
|
+
// Bulk Operations
|
|
109
|
+
// ============================================
|
|
110
|
+
/**
|
|
111
|
+
* Add multiple memories at once
|
|
112
|
+
*/
|
|
113
|
+
async bulkAdd(memories) {
|
|
114
|
+
const request = {
|
|
115
|
+
memories: memories.map((m) => ({
|
|
116
|
+
...m,
|
|
117
|
+
namespace: m.namespace ?? this.namespace
|
|
118
|
+
}))
|
|
119
|
+
};
|
|
120
|
+
return this.request("/memories/bulk", {
|
|
121
|
+
method: "POST",
|
|
122
|
+
body: request
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// ============================================
|
|
126
|
+
// Export/Import
|
|
127
|
+
// ============================================
|
|
128
|
+
/**
|
|
129
|
+
* Export memories
|
|
130
|
+
*/
|
|
131
|
+
async export(options) {
|
|
132
|
+
const params = new URLSearchParams();
|
|
133
|
+
if (options?.namespace) {
|
|
134
|
+
params.set("namespace", options.namespace);
|
|
135
|
+
}
|
|
136
|
+
const queryString = params.toString();
|
|
137
|
+
return this.request(
|
|
138
|
+
`/memories/export${queryString ? `?${queryString}` : ""}`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Import memories from export
|
|
143
|
+
*/
|
|
144
|
+
async import(data) {
|
|
145
|
+
return this.request("/memories/import", {
|
|
146
|
+
method: "POST",
|
|
147
|
+
body: data
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// ============================================
|
|
151
|
+
// Analytics
|
|
152
|
+
// ============================================
|
|
153
|
+
/**
|
|
154
|
+
* Get memory statistics
|
|
155
|
+
*/
|
|
156
|
+
async stats() {
|
|
157
|
+
return this.request("/memories/stats");
|
|
158
|
+
}
|
|
159
|
+
// ============================================
|
|
160
|
+
// Helpers
|
|
161
|
+
// ============================================
|
|
162
|
+
/**
|
|
163
|
+
* Quick remember - shorthand for adding a fact
|
|
164
|
+
*/
|
|
165
|
+
async remember(content, tags) {
|
|
166
|
+
return this.add({
|
|
167
|
+
content,
|
|
168
|
+
memory_type: "fact",
|
|
169
|
+
tags
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Quick recall - shorthand for searching
|
|
174
|
+
*/
|
|
175
|
+
async recall(query, limit = 5) {
|
|
176
|
+
const response = await this.search({ query, limit });
|
|
177
|
+
return response.results;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Forget - shorthand for deleting
|
|
181
|
+
*/
|
|
182
|
+
async forget(ids) {
|
|
183
|
+
return this.delete(ids);
|
|
184
|
+
}
|
|
185
|
+
// ============================================
|
|
186
|
+
// Internal
|
|
187
|
+
// ============================================
|
|
188
|
+
async request(path, options) {
|
|
189
|
+
const url = `${this.baseUrl}${path}`;
|
|
190
|
+
const method = options?.method ?? "GET";
|
|
191
|
+
let lastError = null;
|
|
192
|
+
for (let attempt = 0; attempt < this.retries; attempt++) {
|
|
193
|
+
try {
|
|
194
|
+
const controller = new AbortController();
|
|
195
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
196
|
+
const response = await fetch(url, {
|
|
197
|
+
method,
|
|
198
|
+
headers: {
|
|
199
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
200
|
+
"Content-Type": "application/json"
|
|
201
|
+
},
|
|
202
|
+
body: options?.body ? JSON.stringify(options.body) : void 0,
|
|
203
|
+
signal: controller.signal
|
|
204
|
+
});
|
|
205
|
+
clearTimeout(timeoutId);
|
|
206
|
+
if (!response.ok) {
|
|
207
|
+
const errorData = await response.json().catch(() => ({}));
|
|
208
|
+
const error = {
|
|
209
|
+
code: errorData.code ?? "REQUEST_FAILED",
|
|
210
|
+
message: errorData.error ?? errorData.message ?? `Request failed with status ${response.status}`,
|
|
211
|
+
status: response.status,
|
|
212
|
+
details: errorData
|
|
213
|
+
};
|
|
214
|
+
if (response.status >= 400 && response.status < 500) {
|
|
215
|
+
this.onError?.(error);
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
lastError = error;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
return response.json();
|
|
222
|
+
} catch (error) {
|
|
223
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
224
|
+
lastError = {
|
|
225
|
+
code: "TIMEOUT",
|
|
226
|
+
message: `Request timed out after ${this.timeout}ms`
|
|
227
|
+
};
|
|
228
|
+
} else if (error.code) {
|
|
229
|
+
throw error;
|
|
230
|
+
} else {
|
|
231
|
+
lastError = {
|
|
232
|
+
code: "NETWORK_ERROR",
|
|
233
|
+
message: error instanceof Error ? error.message : "Network error"
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
if (attempt < this.retries - 1) {
|
|
237
|
+
await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt) * 1e3));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (lastError) {
|
|
242
|
+
this.onError?.(lastError);
|
|
243
|
+
throw lastError;
|
|
244
|
+
}
|
|
245
|
+
throw { code: "UNKNOWN", message: "Unknown error" };
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
function createSpringClient(config) {
|
|
249
|
+
return new SpringClient(config);
|
|
250
|
+
}
|
|
251
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
252
|
+
0 && (module.exports = {
|
|
253
|
+
SpringClient,
|
|
254
|
+
createSpringClient
|
|
255
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
var DEFAULT_BASE_URL = "https://seizn.com/api";
|
|
3
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
4
|
+
var DEFAULT_RETRIES = 3;
|
|
5
|
+
var SpringClient = class {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
if (!config.apiKey) {
|
|
8
|
+
throw new Error("API key is required");
|
|
9
|
+
}
|
|
10
|
+
this.apiKey = config.apiKey;
|
|
11
|
+
this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
12
|
+
this.namespace = config.namespace ?? "default";
|
|
13
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
14
|
+
this.retries = config.retries ?? DEFAULT_RETRIES;
|
|
15
|
+
this.onError = config.onError;
|
|
16
|
+
}
|
|
17
|
+
// ============================================
|
|
18
|
+
// Core Operations
|
|
19
|
+
// ============================================
|
|
20
|
+
/**
|
|
21
|
+
* Add a new memory
|
|
22
|
+
*/
|
|
23
|
+
async add(request) {
|
|
24
|
+
const response = await this.request("/memories", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
body: {
|
|
27
|
+
...request,
|
|
28
|
+
namespace: request.namespace ?? this.namespace
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return response.memory;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Search for memories
|
|
35
|
+
*/
|
|
36
|
+
async search(queryOrRequest) {
|
|
37
|
+
const params = typeof queryOrRequest === "string" ? { query: queryOrRequest } : queryOrRequest;
|
|
38
|
+
const searchParams = new URLSearchParams({
|
|
39
|
+
query: params.query,
|
|
40
|
+
limit: String(params.limit ?? 10),
|
|
41
|
+
threshold: String(params.threshold ?? 0.7),
|
|
42
|
+
namespace: params.namespace ?? this.namespace,
|
|
43
|
+
mode: params.mode ?? "vector"
|
|
44
|
+
});
|
|
45
|
+
if (params.tags?.length) {
|
|
46
|
+
searchParams.set("tags", params.tags.join(","));
|
|
47
|
+
}
|
|
48
|
+
return this.request(`/memories?${searchParams}`);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get a memory by ID
|
|
52
|
+
*/
|
|
53
|
+
async get(id) {
|
|
54
|
+
const response = await this.request(
|
|
55
|
+
`/memories/${id}`
|
|
56
|
+
);
|
|
57
|
+
return response.memory;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Update a memory
|
|
61
|
+
*/
|
|
62
|
+
async update(id, request) {
|
|
63
|
+
const response = await this.request(`/memories/${id}`, {
|
|
64
|
+
method: "PUT",
|
|
65
|
+
body: request
|
|
66
|
+
});
|
|
67
|
+
return response.memory;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Delete memories by IDs
|
|
71
|
+
*/
|
|
72
|
+
async delete(ids) {
|
|
73
|
+
const idsArray = Array.isArray(ids) ? ids : [ids];
|
|
74
|
+
const response = await this.request(
|
|
75
|
+
`/memories?ids=${idsArray.join(",")}`,
|
|
76
|
+
{ method: "DELETE" }
|
|
77
|
+
);
|
|
78
|
+
return response.deleted;
|
|
79
|
+
}
|
|
80
|
+
// ============================================
|
|
81
|
+
// Bulk Operations
|
|
82
|
+
// ============================================
|
|
83
|
+
/**
|
|
84
|
+
* Add multiple memories at once
|
|
85
|
+
*/
|
|
86
|
+
async bulkAdd(memories) {
|
|
87
|
+
const request = {
|
|
88
|
+
memories: memories.map((m) => ({
|
|
89
|
+
...m,
|
|
90
|
+
namespace: m.namespace ?? this.namespace
|
|
91
|
+
}))
|
|
92
|
+
};
|
|
93
|
+
return this.request("/memories/bulk", {
|
|
94
|
+
method: "POST",
|
|
95
|
+
body: request
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// ============================================
|
|
99
|
+
// Export/Import
|
|
100
|
+
// ============================================
|
|
101
|
+
/**
|
|
102
|
+
* Export memories
|
|
103
|
+
*/
|
|
104
|
+
async export(options) {
|
|
105
|
+
const params = new URLSearchParams();
|
|
106
|
+
if (options?.namespace) {
|
|
107
|
+
params.set("namespace", options.namespace);
|
|
108
|
+
}
|
|
109
|
+
const queryString = params.toString();
|
|
110
|
+
return this.request(
|
|
111
|
+
`/memories/export${queryString ? `?${queryString}` : ""}`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Import memories from export
|
|
116
|
+
*/
|
|
117
|
+
async import(data) {
|
|
118
|
+
return this.request("/memories/import", {
|
|
119
|
+
method: "POST",
|
|
120
|
+
body: data
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// ============================================
|
|
124
|
+
// Analytics
|
|
125
|
+
// ============================================
|
|
126
|
+
/**
|
|
127
|
+
* Get memory statistics
|
|
128
|
+
*/
|
|
129
|
+
async stats() {
|
|
130
|
+
return this.request("/memories/stats");
|
|
131
|
+
}
|
|
132
|
+
// ============================================
|
|
133
|
+
// Helpers
|
|
134
|
+
// ============================================
|
|
135
|
+
/**
|
|
136
|
+
* Quick remember - shorthand for adding a fact
|
|
137
|
+
*/
|
|
138
|
+
async remember(content, tags) {
|
|
139
|
+
return this.add({
|
|
140
|
+
content,
|
|
141
|
+
memory_type: "fact",
|
|
142
|
+
tags
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Quick recall - shorthand for searching
|
|
147
|
+
*/
|
|
148
|
+
async recall(query, limit = 5) {
|
|
149
|
+
const response = await this.search({ query, limit });
|
|
150
|
+
return response.results;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Forget - shorthand for deleting
|
|
154
|
+
*/
|
|
155
|
+
async forget(ids) {
|
|
156
|
+
return this.delete(ids);
|
|
157
|
+
}
|
|
158
|
+
// ============================================
|
|
159
|
+
// Internal
|
|
160
|
+
// ============================================
|
|
161
|
+
async request(path, options) {
|
|
162
|
+
const url = `${this.baseUrl}${path}`;
|
|
163
|
+
const method = options?.method ?? "GET";
|
|
164
|
+
let lastError = null;
|
|
165
|
+
for (let attempt = 0; attempt < this.retries; attempt++) {
|
|
166
|
+
try {
|
|
167
|
+
const controller = new AbortController();
|
|
168
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
169
|
+
const response = await fetch(url, {
|
|
170
|
+
method,
|
|
171
|
+
headers: {
|
|
172
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
173
|
+
"Content-Type": "application/json"
|
|
174
|
+
},
|
|
175
|
+
body: options?.body ? JSON.stringify(options.body) : void 0,
|
|
176
|
+
signal: controller.signal
|
|
177
|
+
});
|
|
178
|
+
clearTimeout(timeoutId);
|
|
179
|
+
if (!response.ok) {
|
|
180
|
+
const errorData = await response.json().catch(() => ({}));
|
|
181
|
+
const error = {
|
|
182
|
+
code: errorData.code ?? "REQUEST_FAILED",
|
|
183
|
+
message: errorData.error ?? errorData.message ?? `Request failed with status ${response.status}`,
|
|
184
|
+
status: response.status,
|
|
185
|
+
details: errorData
|
|
186
|
+
};
|
|
187
|
+
if (response.status >= 400 && response.status < 500) {
|
|
188
|
+
this.onError?.(error);
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
lastError = error;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
return response.json();
|
|
195
|
+
} catch (error) {
|
|
196
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
197
|
+
lastError = {
|
|
198
|
+
code: "TIMEOUT",
|
|
199
|
+
message: `Request timed out after ${this.timeout}ms`
|
|
200
|
+
};
|
|
201
|
+
} else if (error.code) {
|
|
202
|
+
throw error;
|
|
203
|
+
} else {
|
|
204
|
+
lastError = {
|
|
205
|
+
code: "NETWORK_ERROR",
|
|
206
|
+
message: error instanceof Error ? error.message : "Network error"
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (attempt < this.retries - 1) {
|
|
210
|
+
await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt) * 1e3));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (lastError) {
|
|
215
|
+
this.onError?.(lastError);
|
|
216
|
+
throw lastError;
|
|
217
|
+
}
|
|
218
|
+
throw { code: "UNKNOWN", message: "Unknown error" };
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
function createSpringClient(config) {
|
|
222
|
+
return new SpringClient(config);
|
|
223
|
+
}
|
|
224
|
+
export {
|
|
225
|
+
SpringClient,
|
|
226
|
+
createSpringClient
|
|
227
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@seizn/spring",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Seizn Spring - Semantic Memory SDK for AI Applications",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
21
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
+
"lint": "eslint src/",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"seizn",
|
|
28
|
+
"spring",
|
|
29
|
+
"ai",
|
|
30
|
+
"memory",
|
|
31
|
+
"semantic-search",
|
|
32
|
+
"vector-database",
|
|
33
|
+
"llm",
|
|
34
|
+
"embeddings"
|
|
35
|
+
],
|
|
36
|
+
"author": "Seizn <support@seizn.com>",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/iruhana/seizn.git",
|
|
41
|
+
"directory": "packages/spring-sdk"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://docs.seizn.com/spring",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/iruhana/seizn/issues"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^20.0.0",
|
|
52
|
+
"tsup": "^8.0.0",
|
|
53
|
+
"typescript": "^5.0.0",
|
|
54
|
+
"vitest": "^1.0.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"typescript": ">=5.0.0"
|
|
58
|
+
},
|
|
59
|
+
"peerDependenciesMeta": {
|
|
60
|
+
"typescript": {
|
|
61
|
+
"optional": true
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|