vektori 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,162 @@
1
+ # Vektori TypeScript SDK
2
+
3
+ > AI Memory that Actually Works — Graph-based memory for LLM applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install vektori
9
+ # or
10
+ yarn add vektori
11
+ # or
12
+ pnpm add vektori
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { Vektori } from 'vektori';
19
+
20
+ // Initialize with your API key
21
+ const memory = new Vektori({ apiKey: 'vk_your_key_here' });
22
+
23
+ // Store conversation messages
24
+ await memory.ingest({
25
+ userId: 'user_123',
26
+ messages: [
27
+ { role: 'user', content: "I'm allergic to peanuts" },
28
+ { role: 'assistant', content: 'I\'ll remember that!' },
29
+ { role: 'user', content: 'I also love Italian food' }
30
+ ]
31
+ });
32
+
33
+ // Retrieve relevant context
34
+ const result = await memory.retrieve({
35
+ userId: 'user_123',
36
+ query: 'What are this user\'s dietary restrictions?'
37
+ });
38
+
39
+ console.log(result.context);
40
+ // Output: "User is allergic to peanuts. User loves Italian food."
41
+ ```
42
+
43
+ ## Self-Hosted
44
+
45
+ ```typescript
46
+ const memory = new Vektori({ url: 'http://localhost:8080' });
47
+ ```
48
+
49
+ ## API Reference
50
+
51
+ ### `new Vektori(options)`
52
+
53
+ Create a new client instance.
54
+
55
+ | Option | Type | Required | Description |
56
+ |--------|------|----------|-------------|
57
+ | `apiKey` | string | * | API key for Vektori Cloud |
58
+ | `url` | string | * | URL for self-hosted instance |
59
+ | `timeout` | number | No | Request timeout in ms (default: 30000) |
60
+
61
+ \* Either `apiKey` or `url` must be provided.
62
+
63
+ ### `memory.ingest(options)`
64
+
65
+ Store conversation messages.
66
+
67
+ ```typescript
68
+ const result = await memory.ingest({
69
+ userId: 'user_123',
70
+ messages: [
71
+ { role: 'user', content: 'Hello!' },
72
+ { role: 'assistant', content: 'Hi there!' }
73
+ ],
74
+ sessionId: 'optional-session-id' // auto-generated if not provided
75
+ });
76
+
77
+ console.log(result.processed.facts); // Number of facts extracted
78
+ ```
79
+
80
+ ### `memory.retrieve(options)`
81
+
82
+ Retrieve relevant context.
83
+
84
+ ```typescript
85
+ const result = await memory.retrieve({
86
+ userId: 'user_123',
87
+ query: 'What does the user like?',
88
+ topK: 10, // Max results (1-50)
89
+ includeRaw: false // Include raw facts/insights
90
+ });
91
+
92
+ console.log(result.context); // Synthesized context string
93
+ console.log(result.latencyMs); // Request latency
94
+ ```
95
+
96
+ ### `memory.health()`
97
+
98
+ Check API health.
99
+
100
+ ```typescript
101
+ const status = await memory.health();
102
+ console.log(status.version); // "1.0.0"
103
+ ```
104
+
105
+ ## Error Handling
106
+
107
+ ```typescript
108
+ import { Vektori, VektoriError, AuthenticationError, ValidationError } from 'vektori';
109
+
110
+ try {
111
+ const result = await memory.retrieve({ userId: 'u1', query: 'test' });
112
+ } catch (error) {
113
+ if (error instanceof AuthenticationError) {
114
+ console.error('Invalid API key');
115
+ } else if (error instanceof ValidationError) {
116
+ console.error('Bad request:', error.details);
117
+ } else if (error instanceof VektoriError) {
118
+ console.error('API error:', error.message);
119
+ }
120
+ }
121
+ ```
122
+
123
+ ## With OpenAI
124
+
125
+ ```typescript
126
+ import { Vektori } from 'vektori';
127
+ import OpenAI from 'openai';
128
+
129
+ const memory = new Vektori({ apiKey: 'vk_...' });
130
+ const openai = new OpenAI();
131
+
132
+ async function chatWithMemory(userId: string, userMessage: string) {
133
+ // Get relevant context
134
+ const context = await memory.retrieve({ userId, query: userMessage });
135
+
136
+ // Generate response with context
137
+ const response = await openai.chat.completions.create({
138
+ model: 'gpt-4',
139
+ messages: [
140
+ { role: 'system', content: `User context:\n${context.context}` },
141
+ { role: 'user', content: userMessage }
142
+ ]
143
+ });
144
+
145
+ const assistantMessage = response.choices[0].message.content!;
146
+
147
+ // Store for future context
148
+ await memory.ingest({
149
+ userId,
150
+ messages: [
151
+ { role: 'user', content: userMessage },
152
+ { role: 'assistant', content: assistantMessage }
153
+ ]
154
+ });
155
+
156
+ return assistantMessage;
157
+ }
158
+ ```
159
+
160
+ ## License
161
+
162
+ MIT
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Vektori TypeScript SDK Types
3
+ */
4
+ interface Message {
5
+ role: 'user' | 'assistant';
6
+ content: string;
7
+ timestamp?: string;
8
+ }
9
+ interface IngestOptions {
10
+ userId: string;
11
+ messages: Message[];
12
+ sessionId?: string;
13
+ }
14
+ interface RetrieveOptions {
15
+ userId: string;
16
+ query: string;
17
+ topK?: number;
18
+ includeRaw?: boolean;
19
+ }
20
+ interface ProcessedCounts {
21
+ messages: number;
22
+ sentences: number;
23
+ facts: number;
24
+ insights: number;
25
+ summary: boolean;
26
+ }
27
+ interface IngestResponse {
28
+ success: boolean;
29
+ sessionId: string;
30
+ processed: ProcessedCounts;
31
+ latencyMs: number;
32
+ errors?: string[];
33
+ }
34
+ interface RawItem {
35
+ id: string;
36
+ score: number;
37
+ text?: string;
38
+ }
39
+ interface RawResults {
40
+ facts: RawItem[];
41
+ insights: RawItem[];
42
+ sentences: RawItem[];
43
+ }
44
+ interface SourceMetadata {
45
+ sentences: number;
46
+ facts: number;
47
+ insights: number;
48
+ summaries: number;
49
+ }
50
+ interface RetrieveMetadata {
51
+ sources: SourceMetadata;
52
+ vectorLatencyMs?: number;
53
+ pprLatencyMs?: number;
54
+ synthesisUsed?: boolean;
55
+ }
56
+ interface RetrieveResponse {
57
+ context: string;
58
+ latencyMs: number;
59
+ metadata: RetrieveMetadata;
60
+ raw?: RawResults;
61
+ }
62
+ interface HealthResponse {
63
+ status: string;
64
+ version: string;
65
+ timestamp: string;
66
+ }
67
+ interface VektoriOptions {
68
+ apiKey?: string;
69
+ url?: string;
70
+ timeout?: number;
71
+ }
72
+
73
+ /**
74
+ * Vektori TypeScript SDK
75
+ *
76
+ * AI Memory that Actually Works — Graph-based memory for LLM applications.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * import { Vektori } from 'vektori';
81
+ *
82
+ * const memory = new Vektori({ apiKey: 'vk_...' });
83
+ *
84
+ * // Store memories
85
+ * await memory.ingest({
86
+ * userId: 'user_123',
87
+ * messages: [
88
+ * { role: 'user', content: 'I love pizza' },
89
+ * { role: 'assistant', content: 'Noted!' }
90
+ * ]
91
+ * });
92
+ *
93
+ * // Retrieve context
94
+ * const result = await memory.retrieve({
95
+ * userId: 'user_123',
96
+ * query: 'What food does this user like?'
97
+ * });
98
+ *
99
+ * console.log(result.context); // "User loves pizza"
100
+ * ```
101
+ */
102
+
103
+ declare class VektoriError extends Error {
104
+ constructor(message: string);
105
+ }
106
+ declare class AuthenticationError extends VektoriError {
107
+ constructor(message: string);
108
+ }
109
+ declare class ValidationError extends VektoriError {
110
+ details?: {
111
+ path: string;
112
+ message: string;
113
+ }[];
114
+ constructor(message: string, details?: {
115
+ path: string;
116
+ message: string;
117
+ }[]);
118
+ }
119
+ declare class Vektori {
120
+ private apiKey?;
121
+ private baseUrl;
122
+ private timeout;
123
+ /**
124
+ * Create a new Vektori client.
125
+ *
126
+ * @param options - Client configuration
127
+ * @param options.apiKey - API key for Vektori Cloud
128
+ * @param options.url - URL for self-hosted instance
129
+ * @param options.timeout - Request timeout in milliseconds (default: 30000)
130
+ *
131
+ * @example
132
+ * // Cloud
133
+ * const memory = new Vektori({ apiKey: 'vk_...' });
134
+ *
135
+ * // Self-hosted
136
+ * const memory = new Vektori({ url: 'http://localhost:8080' });
137
+ */
138
+ constructor(options: VektoriOptions);
139
+ /**
140
+ * Store conversation messages in memory.
141
+ *
142
+ * @param options - Ingest options
143
+ * @param options.userId - Unique identifier for the user
144
+ * @param options.messages - Array of messages to ingest
145
+ * @param options.sessionId - Optional session ID (auto-generated if not provided)
146
+ * @returns Ingest response with processing stats
147
+ *
148
+ * @example
149
+ * const result = await memory.ingest({
150
+ * userId: 'user_123',
151
+ * messages: [
152
+ * { role: 'user', content: "I'm allergic to peanuts" },
153
+ * { role: 'assistant', content: 'Noted!' }
154
+ * ]
155
+ * });
156
+ * console.log(`Extracted ${result.processed.facts} facts`);
157
+ */
158
+ ingest(options: IngestOptions): Promise<IngestResponse>;
159
+ /**
160
+ * Retrieve relevant context from memory.
161
+ *
162
+ * @param options - Retrieve options
163
+ * @param options.userId - User to retrieve memories for
164
+ * @param options.query - Search query
165
+ * @param options.topK - Max results (1-50, default: 10)
166
+ * @param options.includeRaw - Include raw facts/insights (default: false)
167
+ * @returns Retrieve response with synthesized context
168
+ *
169
+ * @example
170
+ * const result = await memory.retrieve({
171
+ * userId: 'user_123',
172
+ * query: 'What are the user allergies?'
173
+ * });
174
+ * console.log(result.context); // "User is allergic to peanuts"
175
+ */
176
+ retrieve(options: RetrieveOptions): Promise<RetrieveResponse>;
177
+ /**
178
+ * Check the health of the Vektori API.
179
+ *
180
+ * @returns Health status
181
+ */
182
+ health(): Promise<HealthResponse>;
183
+ /**
184
+ * Make an HTTP request to the API.
185
+ */
186
+ private request;
187
+ }
188
+
189
+ export { AuthenticationError, type HealthResponse, type IngestOptions, type IngestResponse, type Message, type ProcessedCounts, type RawItem, type RawResults, type RetrieveMetadata, type RetrieveOptions, type RetrieveResponse, type SourceMetadata, ValidationError, Vektori, VektoriError, type VektoriOptions };
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Vektori TypeScript SDK Types
3
+ */
4
+ interface Message {
5
+ role: 'user' | 'assistant';
6
+ content: string;
7
+ timestamp?: string;
8
+ }
9
+ interface IngestOptions {
10
+ userId: string;
11
+ messages: Message[];
12
+ sessionId?: string;
13
+ }
14
+ interface RetrieveOptions {
15
+ userId: string;
16
+ query: string;
17
+ topK?: number;
18
+ includeRaw?: boolean;
19
+ }
20
+ interface ProcessedCounts {
21
+ messages: number;
22
+ sentences: number;
23
+ facts: number;
24
+ insights: number;
25
+ summary: boolean;
26
+ }
27
+ interface IngestResponse {
28
+ success: boolean;
29
+ sessionId: string;
30
+ processed: ProcessedCounts;
31
+ latencyMs: number;
32
+ errors?: string[];
33
+ }
34
+ interface RawItem {
35
+ id: string;
36
+ score: number;
37
+ text?: string;
38
+ }
39
+ interface RawResults {
40
+ facts: RawItem[];
41
+ insights: RawItem[];
42
+ sentences: RawItem[];
43
+ }
44
+ interface SourceMetadata {
45
+ sentences: number;
46
+ facts: number;
47
+ insights: number;
48
+ summaries: number;
49
+ }
50
+ interface RetrieveMetadata {
51
+ sources: SourceMetadata;
52
+ vectorLatencyMs?: number;
53
+ pprLatencyMs?: number;
54
+ synthesisUsed?: boolean;
55
+ }
56
+ interface RetrieveResponse {
57
+ context: string;
58
+ latencyMs: number;
59
+ metadata: RetrieveMetadata;
60
+ raw?: RawResults;
61
+ }
62
+ interface HealthResponse {
63
+ status: string;
64
+ version: string;
65
+ timestamp: string;
66
+ }
67
+ interface VektoriOptions {
68
+ apiKey?: string;
69
+ url?: string;
70
+ timeout?: number;
71
+ }
72
+
73
+ /**
74
+ * Vektori TypeScript SDK
75
+ *
76
+ * AI Memory that Actually Works — Graph-based memory for LLM applications.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * import { Vektori } from 'vektori';
81
+ *
82
+ * const memory = new Vektori({ apiKey: 'vk_...' });
83
+ *
84
+ * // Store memories
85
+ * await memory.ingest({
86
+ * userId: 'user_123',
87
+ * messages: [
88
+ * { role: 'user', content: 'I love pizza' },
89
+ * { role: 'assistant', content: 'Noted!' }
90
+ * ]
91
+ * });
92
+ *
93
+ * // Retrieve context
94
+ * const result = await memory.retrieve({
95
+ * userId: 'user_123',
96
+ * query: 'What food does this user like?'
97
+ * });
98
+ *
99
+ * console.log(result.context); // "User loves pizza"
100
+ * ```
101
+ */
102
+
103
+ declare class VektoriError extends Error {
104
+ constructor(message: string);
105
+ }
106
+ declare class AuthenticationError extends VektoriError {
107
+ constructor(message: string);
108
+ }
109
+ declare class ValidationError extends VektoriError {
110
+ details?: {
111
+ path: string;
112
+ message: string;
113
+ }[];
114
+ constructor(message: string, details?: {
115
+ path: string;
116
+ message: string;
117
+ }[]);
118
+ }
119
+ declare class Vektori {
120
+ private apiKey?;
121
+ private baseUrl;
122
+ private timeout;
123
+ /**
124
+ * Create a new Vektori client.
125
+ *
126
+ * @param options - Client configuration
127
+ * @param options.apiKey - API key for Vektori Cloud
128
+ * @param options.url - URL for self-hosted instance
129
+ * @param options.timeout - Request timeout in milliseconds (default: 30000)
130
+ *
131
+ * @example
132
+ * // Cloud
133
+ * const memory = new Vektori({ apiKey: 'vk_...' });
134
+ *
135
+ * // Self-hosted
136
+ * const memory = new Vektori({ url: 'http://localhost:8080' });
137
+ */
138
+ constructor(options: VektoriOptions);
139
+ /**
140
+ * Store conversation messages in memory.
141
+ *
142
+ * @param options - Ingest options
143
+ * @param options.userId - Unique identifier for the user
144
+ * @param options.messages - Array of messages to ingest
145
+ * @param options.sessionId - Optional session ID (auto-generated if not provided)
146
+ * @returns Ingest response with processing stats
147
+ *
148
+ * @example
149
+ * const result = await memory.ingest({
150
+ * userId: 'user_123',
151
+ * messages: [
152
+ * { role: 'user', content: "I'm allergic to peanuts" },
153
+ * { role: 'assistant', content: 'Noted!' }
154
+ * ]
155
+ * });
156
+ * console.log(`Extracted ${result.processed.facts} facts`);
157
+ */
158
+ ingest(options: IngestOptions): Promise<IngestResponse>;
159
+ /**
160
+ * Retrieve relevant context from memory.
161
+ *
162
+ * @param options - Retrieve options
163
+ * @param options.userId - User to retrieve memories for
164
+ * @param options.query - Search query
165
+ * @param options.topK - Max results (1-50, default: 10)
166
+ * @param options.includeRaw - Include raw facts/insights (default: false)
167
+ * @returns Retrieve response with synthesized context
168
+ *
169
+ * @example
170
+ * const result = await memory.retrieve({
171
+ * userId: 'user_123',
172
+ * query: 'What are the user allergies?'
173
+ * });
174
+ * console.log(result.context); // "User is allergic to peanuts"
175
+ */
176
+ retrieve(options: RetrieveOptions): Promise<RetrieveResponse>;
177
+ /**
178
+ * Check the health of the Vektori API.
179
+ *
180
+ * @returns Health status
181
+ */
182
+ health(): Promise<HealthResponse>;
183
+ /**
184
+ * Make an HTTP request to the API.
185
+ */
186
+ private request;
187
+ }
188
+
189
+ export { AuthenticationError, type HealthResponse, type IngestOptions, type IngestResponse, type Message, type ProcessedCounts, type RawItem, type RawResults, type RetrieveMetadata, type RetrieveOptions, type RetrieveResponse, type SourceMetadata, ValidationError, Vektori, VektoriError, type VektoriOptions };
package/dist/index.js ADDED
@@ -0,0 +1,226 @@
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
+ AuthenticationError: () => AuthenticationError,
24
+ ValidationError: () => ValidationError,
25
+ Vektori: () => Vektori,
26
+ VektoriError: () => VektoriError
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/client.ts
31
+ var VektoriError = class extends Error {
32
+ constructor(message) {
33
+ super(message);
34
+ this.name = "VektoriError";
35
+ }
36
+ };
37
+ var AuthenticationError = class extends VektoriError {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = "AuthenticationError";
41
+ }
42
+ };
43
+ var ValidationError = class extends VektoriError {
44
+ constructor(message, details) {
45
+ super(message);
46
+ this.name = "ValidationError";
47
+ this.details = details;
48
+ }
49
+ };
50
+ var DEFAULT_CLOUD_URL = "https://api.vektori.cloud";
51
+ var DEFAULT_TIMEOUT = 3e4;
52
+ var Vektori = class {
53
+ /**
54
+ * Create a new Vektori client.
55
+ *
56
+ * @param options - Client configuration
57
+ * @param options.apiKey - API key for Vektori Cloud
58
+ * @param options.url - URL for self-hosted instance
59
+ * @param options.timeout - Request timeout in milliseconds (default: 30000)
60
+ *
61
+ * @example
62
+ * // Cloud
63
+ * const memory = new Vektori({ apiKey: 'vk_...' });
64
+ *
65
+ * // Self-hosted
66
+ * const memory = new Vektori({ url: 'http://localhost:8080' });
67
+ */
68
+ constructor(options) {
69
+ if (!options.apiKey && !options.url) {
70
+ throw new VektoriError(
71
+ "Must provide either 'apiKey' (for Cloud) or 'url' (for self-hosted)"
72
+ );
73
+ }
74
+ this.apiKey = options.apiKey;
75
+ this.baseUrl = (options.url || DEFAULT_CLOUD_URL).replace(/\/$/, "");
76
+ this.timeout = options.timeout || DEFAULT_TIMEOUT;
77
+ }
78
+ /**
79
+ * Store conversation messages in memory.
80
+ *
81
+ * @param options - Ingest options
82
+ * @param options.userId - Unique identifier for the user
83
+ * @param options.messages - Array of messages to ingest
84
+ * @param options.sessionId - Optional session ID (auto-generated if not provided)
85
+ * @returns Ingest response with processing stats
86
+ *
87
+ * @example
88
+ * const result = await memory.ingest({
89
+ * userId: 'user_123',
90
+ * messages: [
91
+ * { role: 'user', content: "I'm allergic to peanuts" },
92
+ * { role: 'assistant', content: 'Noted!' }
93
+ * ]
94
+ * });
95
+ * console.log(`Extracted ${result.processed.facts} facts`);
96
+ */
97
+ async ingest(options) {
98
+ const payload = {
99
+ user_id: options.userId,
100
+ messages: options.messages,
101
+ session_id: options.sessionId
102
+ };
103
+ const response = await this.request("POST", "/v1/ingest", payload);
104
+ return {
105
+ success: response.success,
106
+ sessionId: response.session_id,
107
+ processed: {
108
+ messages: response.processed.messages,
109
+ sentences: response.processed.sentences,
110
+ facts: response.processed.facts,
111
+ insights: response.processed.insights,
112
+ summary: response.processed.summary
113
+ },
114
+ latencyMs: response.latency_ms,
115
+ errors: response.errors
116
+ };
117
+ }
118
+ /**
119
+ * Retrieve relevant context from memory.
120
+ *
121
+ * @param options - Retrieve options
122
+ * @param options.userId - User to retrieve memories for
123
+ * @param options.query - Search query
124
+ * @param options.topK - Max results (1-50, default: 10)
125
+ * @param options.includeRaw - Include raw facts/insights (default: false)
126
+ * @returns Retrieve response with synthesized context
127
+ *
128
+ * @example
129
+ * const result = await memory.retrieve({
130
+ * userId: 'user_123',
131
+ * query: 'What are the user allergies?'
132
+ * });
133
+ * console.log(result.context); // "User is allergic to peanuts"
134
+ */
135
+ async retrieve(options) {
136
+ const payload = {
137
+ user_id: options.userId,
138
+ query: options.query,
139
+ top_k: options.topK ?? 10,
140
+ include_raw: options.includeRaw ?? false
141
+ };
142
+ const response = await this.request("POST", "/v1/retrieve", payload);
143
+ const result = {
144
+ context: response.context,
145
+ latencyMs: response.latency_ms,
146
+ metadata: {
147
+ sources: response.metadata.sources,
148
+ vectorLatencyMs: response.metadata.vector_latency_ms,
149
+ pprLatencyMs: response.metadata.ppr_latency_ms,
150
+ synthesisUsed: response.metadata.synthesis_used
151
+ }
152
+ };
153
+ if (response.raw) {
154
+ result.raw = {
155
+ facts: response.raw.facts || [],
156
+ insights: response.raw.insights || [],
157
+ sentences: response.raw.sentences || []
158
+ };
159
+ }
160
+ return result;
161
+ }
162
+ /**
163
+ * Check the health of the Vektori API.
164
+ *
165
+ * @returns Health status
166
+ */
167
+ async health() {
168
+ return this.request("GET", "/v1/health");
169
+ }
170
+ /**
171
+ * Make an HTTP request to the API.
172
+ */
173
+ async request(method, path, body) {
174
+ const url = `${this.baseUrl}${path}`;
175
+ const headers = {
176
+ "Content-Type": "application/json"
177
+ };
178
+ if (this.apiKey) {
179
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
180
+ }
181
+ const controller = new AbortController();
182
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
183
+ try {
184
+ const response = await fetch(url, {
185
+ method,
186
+ headers,
187
+ body: body ? JSON.stringify(body) : void 0,
188
+ signal: controller.signal
189
+ });
190
+ clearTimeout(timeoutId);
191
+ if (!response.ok) {
192
+ const errorBody = await response.json();
193
+ if (response.status === 401) {
194
+ throw new AuthenticationError(errorBody.error || "Invalid API key");
195
+ }
196
+ if (response.status === 400) {
197
+ throw new ValidationError(
198
+ errorBody.error || "Validation error",
199
+ errorBody.details
200
+ );
201
+ }
202
+ throw new VektoriError(errorBody.error || `HTTP ${response.status}`);
203
+ }
204
+ return response.json();
205
+ } catch (error) {
206
+ clearTimeout(timeoutId);
207
+ if (error instanceof VektoriError) {
208
+ throw error;
209
+ }
210
+ if (error instanceof Error) {
211
+ if (error.name === "AbortError") {
212
+ throw new VektoriError(`Request timeout after ${this.timeout}ms`);
213
+ }
214
+ throw new VektoriError(`Request failed: ${error.message}`);
215
+ }
216
+ throw new VektoriError("Unknown error occurred");
217
+ }
218
+ }
219
+ };
220
+ // Annotate the CommonJS export names for ESM import in node:
221
+ 0 && (module.exports = {
222
+ AuthenticationError,
223
+ ValidationError,
224
+ Vektori,
225
+ VektoriError
226
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,196 @@
1
+ // src/client.ts
2
+ var VektoriError = class extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "VektoriError";
6
+ }
7
+ };
8
+ var AuthenticationError = class extends VektoriError {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "AuthenticationError";
12
+ }
13
+ };
14
+ var ValidationError = class extends VektoriError {
15
+ constructor(message, details) {
16
+ super(message);
17
+ this.name = "ValidationError";
18
+ this.details = details;
19
+ }
20
+ };
21
+ var DEFAULT_CLOUD_URL = "https://api.vektori.cloud";
22
+ var DEFAULT_TIMEOUT = 3e4;
23
+ var Vektori = class {
24
+ /**
25
+ * Create a new Vektori client.
26
+ *
27
+ * @param options - Client configuration
28
+ * @param options.apiKey - API key for Vektori Cloud
29
+ * @param options.url - URL for self-hosted instance
30
+ * @param options.timeout - Request timeout in milliseconds (default: 30000)
31
+ *
32
+ * @example
33
+ * // Cloud
34
+ * const memory = new Vektori({ apiKey: 'vk_...' });
35
+ *
36
+ * // Self-hosted
37
+ * const memory = new Vektori({ url: 'http://localhost:8080' });
38
+ */
39
+ constructor(options) {
40
+ if (!options.apiKey && !options.url) {
41
+ throw new VektoriError(
42
+ "Must provide either 'apiKey' (for Cloud) or 'url' (for self-hosted)"
43
+ );
44
+ }
45
+ this.apiKey = options.apiKey;
46
+ this.baseUrl = (options.url || DEFAULT_CLOUD_URL).replace(/\/$/, "");
47
+ this.timeout = options.timeout || DEFAULT_TIMEOUT;
48
+ }
49
+ /**
50
+ * Store conversation messages in memory.
51
+ *
52
+ * @param options - Ingest options
53
+ * @param options.userId - Unique identifier for the user
54
+ * @param options.messages - Array of messages to ingest
55
+ * @param options.sessionId - Optional session ID (auto-generated if not provided)
56
+ * @returns Ingest response with processing stats
57
+ *
58
+ * @example
59
+ * const result = await memory.ingest({
60
+ * userId: 'user_123',
61
+ * messages: [
62
+ * { role: 'user', content: "I'm allergic to peanuts" },
63
+ * { role: 'assistant', content: 'Noted!' }
64
+ * ]
65
+ * });
66
+ * console.log(`Extracted ${result.processed.facts} facts`);
67
+ */
68
+ async ingest(options) {
69
+ const payload = {
70
+ user_id: options.userId,
71
+ messages: options.messages,
72
+ session_id: options.sessionId
73
+ };
74
+ const response = await this.request("POST", "/v1/ingest", payload);
75
+ return {
76
+ success: response.success,
77
+ sessionId: response.session_id,
78
+ processed: {
79
+ messages: response.processed.messages,
80
+ sentences: response.processed.sentences,
81
+ facts: response.processed.facts,
82
+ insights: response.processed.insights,
83
+ summary: response.processed.summary
84
+ },
85
+ latencyMs: response.latency_ms,
86
+ errors: response.errors
87
+ };
88
+ }
89
+ /**
90
+ * Retrieve relevant context from memory.
91
+ *
92
+ * @param options - Retrieve options
93
+ * @param options.userId - User to retrieve memories for
94
+ * @param options.query - Search query
95
+ * @param options.topK - Max results (1-50, default: 10)
96
+ * @param options.includeRaw - Include raw facts/insights (default: false)
97
+ * @returns Retrieve response with synthesized context
98
+ *
99
+ * @example
100
+ * const result = await memory.retrieve({
101
+ * userId: 'user_123',
102
+ * query: 'What are the user allergies?'
103
+ * });
104
+ * console.log(result.context); // "User is allergic to peanuts"
105
+ */
106
+ async retrieve(options) {
107
+ const payload = {
108
+ user_id: options.userId,
109
+ query: options.query,
110
+ top_k: options.topK ?? 10,
111
+ include_raw: options.includeRaw ?? false
112
+ };
113
+ const response = await this.request("POST", "/v1/retrieve", payload);
114
+ const result = {
115
+ context: response.context,
116
+ latencyMs: response.latency_ms,
117
+ metadata: {
118
+ sources: response.metadata.sources,
119
+ vectorLatencyMs: response.metadata.vector_latency_ms,
120
+ pprLatencyMs: response.metadata.ppr_latency_ms,
121
+ synthesisUsed: response.metadata.synthesis_used
122
+ }
123
+ };
124
+ if (response.raw) {
125
+ result.raw = {
126
+ facts: response.raw.facts || [],
127
+ insights: response.raw.insights || [],
128
+ sentences: response.raw.sentences || []
129
+ };
130
+ }
131
+ return result;
132
+ }
133
+ /**
134
+ * Check the health of the Vektori API.
135
+ *
136
+ * @returns Health status
137
+ */
138
+ async health() {
139
+ return this.request("GET", "/v1/health");
140
+ }
141
+ /**
142
+ * Make an HTTP request to the API.
143
+ */
144
+ async request(method, path, body) {
145
+ const url = `${this.baseUrl}${path}`;
146
+ const headers = {
147
+ "Content-Type": "application/json"
148
+ };
149
+ if (this.apiKey) {
150
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
151
+ }
152
+ const controller = new AbortController();
153
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
154
+ try {
155
+ const response = await fetch(url, {
156
+ method,
157
+ headers,
158
+ body: body ? JSON.stringify(body) : void 0,
159
+ signal: controller.signal
160
+ });
161
+ clearTimeout(timeoutId);
162
+ if (!response.ok) {
163
+ const errorBody = await response.json();
164
+ if (response.status === 401) {
165
+ throw new AuthenticationError(errorBody.error || "Invalid API key");
166
+ }
167
+ if (response.status === 400) {
168
+ throw new ValidationError(
169
+ errorBody.error || "Validation error",
170
+ errorBody.details
171
+ );
172
+ }
173
+ throw new VektoriError(errorBody.error || `HTTP ${response.status}`);
174
+ }
175
+ return response.json();
176
+ } catch (error) {
177
+ clearTimeout(timeoutId);
178
+ if (error instanceof VektoriError) {
179
+ throw error;
180
+ }
181
+ if (error instanceof Error) {
182
+ if (error.name === "AbortError") {
183
+ throw new VektoriError(`Request timeout after ${this.timeout}ms`);
184
+ }
185
+ throw new VektoriError(`Request failed: ${error.message}`);
186
+ }
187
+ throw new VektoriError("Unknown error occurred");
188
+ }
189
+ }
190
+ };
191
+ export {
192
+ AuthenticationError,
193
+ ValidationError,
194
+ Vektori,
195
+ VektoriError
196
+ };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "vektori",
3
+ "version": "0.1.0",
4
+ "description": "AI Memory that Actually Works — TypeScript SDK for Vektori",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format cjs,esm --dts",
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
+ "ai",
28
+ "memory",
29
+ "llm",
30
+ "rag",
31
+ "vector",
32
+ "graph",
33
+ "context",
34
+ "personalization"
35
+ ],
36
+ "author": "Vektori AI <hello@vektori.cloud>",
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/vektori-ai/vektori.git"
41
+ },
42
+ "homepage": "https://vektori.cloud",
43
+ "bugs": {
44
+ "url": "https://github.com/vektori-ai/vektori/issues"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^20.0.0",
48
+ "tsup": "^8.0.0",
49
+ "typescript": "^5.0.0",
50
+ "vitest": "^1.0.0"
51
+ },
52
+ "engines": {
53
+ "node": ">=18.0.0"
54
+ }
55
+ }