@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 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)
@@ -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 };
@@ -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
+ }