@mnexium/sdk 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/dist/index.js ADDED
@@ -0,0 +1,1110 @@
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
+ APIError: () => APIError,
24
+ AuthenticationError: () => AuthenticationError,
25
+ Chat: () => Chat,
26
+ ChatSession: () => Chat,
27
+ EventStream: () => EventStream,
28
+ Mnexium: () => Mnexium,
29
+ MnexiumError: () => MnexiumError,
30
+ RateLimitError: () => RateLimitError,
31
+ StreamResponse: () => StreamResponse,
32
+ Subject: () => Subject
33
+ });
34
+ module.exports = __toCommonJS(index_exports);
35
+
36
+ // src/errors.ts
37
+ var MnexiumError = class extends Error {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = "MnexiumError";
41
+ }
42
+ };
43
+ var AuthenticationError = class extends MnexiumError {
44
+ constructor(message = "Authentication failed") {
45
+ super(message);
46
+ this.name = "AuthenticationError";
47
+ }
48
+ };
49
+ var RateLimitError = class extends MnexiumError {
50
+ constructor(message = "Rate limit exceeded", options) {
51
+ super(message);
52
+ this.name = "RateLimitError";
53
+ this.retryAfter = options?.retryAfter;
54
+ this.current = options?.current;
55
+ this.limit = options?.limit;
56
+ }
57
+ };
58
+ var APIError = class extends MnexiumError {
59
+ constructor(message, status, code) {
60
+ super(message);
61
+ this.name = "APIError";
62
+ this.status = status;
63
+ this.code = code;
64
+ }
65
+ };
66
+ var NotFoundError = class extends APIError {
67
+ constructor(message = "Resource not found") {
68
+ super(message, 404, "not_found");
69
+ this.name = "NotFoundError";
70
+ }
71
+ };
72
+
73
+ // src/chat.ts
74
+ var Chat = class {
75
+ constructor(client, subjectId, options = {}) {
76
+ this.client = client;
77
+ this.subjectId = subjectId;
78
+ this.id = options.chatId || crypto.randomUUID();
79
+ this.options = options;
80
+ }
81
+ async process(input) {
82
+ const options = typeof input === "string" ? { content: input } : input;
83
+ return this.client.process({
84
+ content: options.content,
85
+ chatId: this.id,
86
+ subjectId: this.subjectId,
87
+ model: options.model ?? this.options.model,
88
+ log: options.log ?? this.options.log,
89
+ learn: options.learn ?? this.options.learn,
90
+ recall: options.recall ?? this.options.recall,
91
+ profile: options.profile ?? this.options.profile,
92
+ history: options.history ?? this.options.history,
93
+ summarize: options.summarize ?? this.options.summarize,
94
+ systemPrompt: options.systemPrompt ?? this.options.systemPrompt,
95
+ maxTokens: options.maxTokens ?? this.options.maxTokens,
96
+ temperature: options.temperature ?? this.options.temperature,
97
+ stream: options.stream,
98
+ metadata: options.metadata ?? this.options.metadata,
99
+ regenerateKey: options.regenerateKey
100
+ });
101
+ }
102
+ };
103
+
104
+ // src/events.ts
105
+ var EventStream = class {
106
+ constructor(client, subjectId, options) {
107
+ this.client = client;
108
+ this.subjectId = subjectId;
109
+ this.reader = null;
110
+ this.decoder = new TextDecoder();
111
+ this.connected = false;
112
+ this.abortController = new AbortController();
113
+ if (options?.signal) {
114
+ options.signal.addEventListener("abort", () => this.close());
115
+ }
116
+ }
117
+ async *[Symbol.asyncIterator]() {
118
+ const response = await this.client._requestRaw("GET", "/events/memories", {
119
+ query: { subject_id: this.subjectId }
120
+ });
121
+ if (!response.body) {
122
+ throw new Error("Response body is null \u2014 SSE not supported");
123
+ }
124
+ this.reader = response.body.getReader();
125
+ this.connected = true;
126
+ let buffer = "";
127
+ let currentEvent = "";
128
+ try {
129
+ while (true) {
130
+ const { value, done } = await this.reader.read();
131
+ if (done) break;
132
+ buffer += this.decoder.decode(value, { stream: true });
133
+ const lines = buffer.split("\n");
134
+ buffer = lines.pop() ?? "";
135
+ for (const line of lines) {
136
+ const trimmed = line.trim();
137
+ if (trimmed.startsWith("event:")) {
138
+ currentEvent = trimmed.slice(6).trim();
139
+ continue;
140
+ }
141
+ if (trimmed.startsWith("data:")) {
142
+ const data = trimmed.slice(5).trim();
143
+ if (!data) continue;
144
+ try {
145
+ const parsed = JSON.parse(data);
146
+ const eventType = currentEvent || "unknown";
147
+ currentEvent = "";
148
+ yield {
149
+ type: eventType,
150
+ data: parsed
151
+ };
152
+ } catch {
153
+ }
154
+ }
155
+ if (trimmed === "") {
156
+ currentEvent = "";
157
+ }
158
+ }
159
+ }
160
+ } finally {
161
+ this.connected = false;
162
+ if (this.reader) {
163
+ this.reader.releaseLock();
164
+ this.reader = null;
165
+ }
166
+ }
167
+ }
168
+ /** Close the event stream */
169
+ close() {
170
+ this.abortController.abort();
171
+ if (this.reader) {
172
+ this.reader.cancel().catch(() => {
173
+ });
174
+ this.reader = null;
175
+ }
176
+ this.connected = false;
177
+ }
178
+ /** Whether the stream is currently connected */
179
+ get isConnected() {
180
+ return this.connected;
181
+ }
182
+ };
183
+
184
+ // src/subject.ts
185
+ var SubjectMemoriesResource = class {
186
+ constructor(client, subjectId) {
187
+ this.client = client;
188
+ this.subjectId = subjectId;
189
+ }
190
+ async search(query, options) {
191
+ const response = await this.client._request("GET", "/memories/search", {
192
+ query: {
193
+ subject_id: this.subjectId,
194
+ q: query,
195
+ limit: options?.limit,
196
+ min_score: options?.minScore
197
+ }
198
+ });
199
+ return response.data || [];
200
+ }
201
+ async add(text, options) {
202
+ return this.client._request("POST", "/memories", {
203
+ body: {
204
+ subject_id: this.subjectId,
205
+ text,
206
+ source: options?.source,
207
+ visibility: options?.visibility,
208
+ metadata: options?.metadata
209
+ }
210
+ });
211
+ }
212
+ async list(options) {
213
+ const response = await this.client._request("GET", "/memories", {
214
+ query: {
215
+ subject_id: this.subjectId,
216
+ limit: options?.limit,
217
+ offset: options?.offset
218
+ }
219
+ });
220
+ return response.data || [];
221
+ }
222
+ async get(memoryId) {
223
+ return this.client._request("GET", `/memories/${memoryId}`);
224
+ }
225
+ async update(memoryId, updates) {
226
+ return this.client._request("PATCH", `/memories/${memoryId}`, {
227
+ body: updates
228
+ });
229
+ }
230
+ async delete(memoryId) {
231
+ await this.client._request("DELETE", `/memories/${memoryId}`);
232
+ }
233
+ async superseded(options) {
234
+ const response = await this.client._request("GET", "/memories/superseded", {
235
+ query: {
236
+ subject_id: this.subjectId,
237
+ limit: options?.limit,
238
+ offset: options?.offset
239
+ }
240
+ });
241
+ return response.data || [];
242
+ }
243
+ async restore(memoryId) {
244
+ return this.client._request("POST", `/memories/${memoryId}/restore`);
245
+ }
246
+ async recalls(options) {
247
+ const response = await this.client._request("GET", "/memories/recalls", {
248
+ query: {
249
+ chat_id: options.chatId,
250
+ memory_id: options.memoryId
251
+ }
252
+ });
253
+ return response.data || [];
254
+ }
255
+ subscribe(options) {
256
+ return new EventStream(this.client, this.subjectId, options);
257
+ }
258
+ };
259
+ var SubjectProfileResource = class {
260
+ constructor(client, subjectId) {
261
+ this.client = client;
262
+ this.subjectId = subjectId;
263
+ }
264
+ async get() {
265
+ return this.client._request("GET", "/profiles", {
266
+ query: { subject_id: this.subjectId }
267
+ });
268
+ }
269
+ async update(updates) {
270
+ return this.client._request("PATCH", "/profiles", {
271
+ body: {
272
+ subject_id: this.subjectId,
273
+ updates
274
+ }
275
+ });
276
+ }
277
+ async deleteField(fieldKey) {
278
+ await this.client._request("DELETE", "/profiles", {
279
+ body: {
280
+ subject_id: this.subjectId,
281
+ field_key: fieldKey
282
+ }
283
+ });
284
+ }
285
+ };
286
+ var SubjectStateResource = class {
287
+ constructor(client, subjectId) {
288
+ this.client = client;
289
+ this.subjectId = subjectId;
290
+ }
291
+ async get(key) {
292
+ try {
293
+ return await this.client._request("GET", `/state/${key}`, {
294
+ headers: { "x-subject-id": this.subjectId }
295
+ });
296
+ } catch (error) {
297
+ if (error?.status === 404) {
298
+ return null;
299
+ }
300
+ throw error;
301
+ }
302
+ }
303
+ async set(key, value, options) {
304
+ return this.client._request("PUT", `/state/${key}`, {
305
+ headers: { "x-subject-id": this.subjectId },
306
+ body: {
307
+ value,
308
+ ttl_seconds: options?.ttlSeconds
309
+ }
310
+ });
311
+ }
312
+ async delete(key) {
313
+ await this.client._request("DELETE", `/state/${key}`, {
314
+ headers: { "x-subject-id": this.subjectId }
315
+ });
316
+ }
317
+ };
318
+ var SubjectClaimsResource = class {
319
+ constructor(client, subjectId) {
320
+ this.client = client;
321
+ this.subjectId = subjectId;
322
+ }
323
+ async get(slot) {
324
+ try {
325
+ return await this.client._request("GET", `/claims/subject/${this.subjectId}/slot/${slot}`);
326
+ } catch (error) {
327
+ if (error?.status === 404) {
328
+ return null;
329
+ }
330
+ throw error;
331
+ }
332
+ }
333
+ async set(predicate, value, options) {
334
+ return this.client._request("POST", "/claims", {
335
+ body: {
336
+ subject_id: this.subjectId,
337
+ predicate,
338
+ object_value: value,
339
+ confidence: options?.confidence,
340
+ source_type: options?.source
341
+ }
342
+ });
343
+ }
344
+ async list() {
345
+ return this.client._request("GET", `/claims/subject/${this.subjectId}/slots`);
346
+ }
347
+ async truth() {
348
+ return this.client._request("GET", `/claims/subject/${this.subjectId}/truth`);
349
+ }
350
+ async history() {
351
+ const response = await this.client._request("GET", `/claims/subject/${this.subjectId}/history`);
352
+ return response.data || response.claims || [];
353
+ }
354
+ async retract(claimId) {
355
+ return this.client._request("POST", `/claims/${claimId}/retract`);
356
+ }
357
+ };
358
+ var SubjectChatsResource = class {
359
+ constructor(client, subjectId) {
360
+ this.client = client;
361
+ this.subjectId = subjectId;
362
+ }
363
+ async list(options) {
364
+ const response = await this.client._request("GET", "/chat/history/list", {
365
+ query: {
366
+ subject_id: this.subjectId,
367
+ limit: options?.limit,
368
+ offset: options?.offset
369
+ }
370
+ });
371
+ return response.chats;
372
+ }
373
+ async read(chatId) {
374
+ const response = await this.client._request("GET", "/chat/history/read", {
375
+ query: {
376
+ subject_id: this.subjectId,
377
+ chat_id: chatId
378
+ }
379
+ });
380
+ return response.data || [];
381
+ }
382
+ async delete(chatId) {
383
+ await this.client._request("DELETE", "/chat/history/delete", {
384
+ query: {
385
+ subject_id: this.subjectId,
386
+ chat_id: chatId
387
+ }
388
+ });
389
+ }
390
+ };
391
+ var Subject = class {
392
+ constructor(client, subjectId) {
393
+ this.client = client;
394
+ this.id = subjectId;
395
+ this.memories = new SubjectMemoriesResource(client, subjectId);
396
+ this.profile = new SubjectProfileResource(client, subjectId);
397
+ this.state = new SubjectStateResource(client, subjectId);
398
+ this.claims = new SubjectClaimsResource(client, subjectId);
399
+ this.chats = new SubjectChatsResource(client, subjectId);
400
+ }
401
+ /**
402
+ * Process a message with an ephemeral chat (no persistent chatId)
403
+ *
404
+ * @example
405
+ * const response = await alice.process("What's my favorite color?");
406
+ */
407
+ async process(input) {
408
+ const options = typeof input === "string" ? { content: input } : input;
409
+ return this.client.process({
410
+ ...options,
411
+ subjectId: this.id
412
+ });
413
+ }
414
+ /**
415
+ * Create a chat session for multi-turn conversation
416
+ *
417
+ * @example
418
+ * const chat = alice.createChat({ history: true });
419
+ * await chat.process("Hello!");
420
+ * await chat.process("What did I just say?");
421
+ */
422
+ createChat(options) {
423
+ return this.client.createChat(this, options);
424
+ }
425
+ };
426
+
427
+ // src/providers.ts
428
+ function detectProvider(model) {
429
+ const lowerModel = model.toLowerCase();
430
+ if (lowerModel.includes("claude")) {
431
+ return "anthropic";
432
+ }
433
+ if (lowerModel.includes("gemini") || lowerModel.includes("palm")) {
434
+ return "google";
435
+ }
436
+ if (lowerModel.includes("gpt") || lowerModel.includes("o1") || lowerModel.includes("o3") || lowerModel.includes("davinci")) {
437
+ return "openai";
438
+ }
439
+ return null;
440
+ }
441
+ function extractResponseContent(raw) {
442
+ if (raw.content && Array.isArray(raw.content)) {
443
+ let content = "";
444
+ for (const block of raw.content) {
445
+ if (block.type === "text") {
446
+ content += block.text || "";
447
+ }
448
+ }
449
+ return {
450
+ content,
451
+ usage: raw.usage ? {
452
+ prompt_tokens: raw.usage.input_tokens || 0,
453
+ completion_tokens: raw.usage.output_tokens || 0,
454
+ total_tokens: (raw.usage.input_tokens || 0) + (raw.usage.output_tokens || 0)
455
+ } : null
456
+ };
457
+ }
458
+ if (raw.candidates && Array.isArray(raw.candidates)) {
459
+ let content = "";
460
+ const parts = raw.candidates[0]?.content?.parts || [];
461
+ for (const part of parts) {
462
+ if (part.text) {
463
+ content += part.text;
464
+ }
465
+ }
466
+ return {
467
+ content,
468
+ usage: raw.usageMetadata ? {
469
+ prompt_tokens: raw.usageMetadata.promptTokenCount || 0,
470
+ completion_tokens: raw.usageMetadata.candidatesTokenCount || 0,
471
+ total_tokens: raw.usageMetadata.totalTokenCount || 0
472
+ } : null
473
+ };
474
+ }
475
+ return {
476
+ content: raw.choices?.[0]?.message?.content || "",
477
+ usage: raw.usage || null
478
+ };
479
+ }
480
+
481
+ // src/streaming.ts
482
+ var StreamResponse = class {
483
+ constructor(response, metadata) {
484
+ /** The full accumulated content after streaming completes */
485
+ this.totalContent = "";
486
+ this.consumed = false;
487
+ if (!response.body) {
488
+ throw new Error("Response body is null \u2014 streaming not supported");
489
+ }
490
+ this.reader = response.body.getReader();
491
+ this.decoder = new TextDecoder();
492
+ this.chatId = metadata.chatId;
493
+ this.subjectId = metadata.subjectId;
494
+ this.model = metadata.model;
495
+ this.provisionedKey = metadata.provisionedKey;
496
+ this.claimUrl = metadata.claimUrl;
497
+ }
498
+ async *[Symbol.asyncIterator]() {
499
+ if (this.consumed) {
500
+ throw new Error("StreamResponse has already been consumed");
501
+ }
502
+ this.consumed = true;
503
+ let buffer = "";
504
+ try {
505
+ while (true) {
506
+ const { value, done } = await this.reader.read();
507
+ if (done) break;
508
+ buffer += this.decoder.decode(value, { stream: true });
509
+ const lines = buffer.split("\n");
510
+ buffer = lines.pop() ?? "";
511
+ for (const line of lines) {
512
+ const trimmed = line.trim();
513
+ if (trimmed.startsWith("event:") || !trimmed.startsWith("data:")) continue;
514
+ const data = trimmed.slice(5).trim();
515
+ if (!data || data === "[DONE]") continue;
516
+ try {
517
+ const json = JSON.parse(data);
518
+ const chunk = this._extractChunk(json);
519
+ if (chunk) {
520
+ this.totalContent += chunk.content;
521
+ yield chunk;
522
+ }
523
+ this._extractUsage(json);
524
+ } catch {
525
+ }
526
+ }
527
+ }
528
+ } finally {
529
+ this.reader.releaseLock();
530
+ }
531
+ }
532
+ /**
533
+ * Convenience: collect the full response as a string.
534
+ * Consumes the stream if not already consumed.
535
+ */
536
+ async text() {
537
+ if (!this.consumed) {
538
+ for await (const _ of this) {
539
+ }
540
+ }
541
+ return this.totalContent;
542
+ }
543
+ _extractChunk(json) {
544
+ const delta = json?.choices?.[0]?.delta;
545
+ if (delta?.content) {
546
+ return { content: delta.content, raw: json };
547
+ }
548
+ if (json?.type === "content_block_delta" && json?.delta?.type === "text_delta") {
549
+ return { content: json.delta.text || "", raw: json };
550
+ }
551
+ const parts = json?.candidates?.[0]?.content?.parts;
552
+ if (Array.isArray(parts)) {
553
+ const text = parts.map((p) => p.text || "").join("");
554
+ if (text) {
555
+ return { content: text, raw: json };
556
+ }
557
+ }
558
+ return null;
559
+ }
560
+ _extractUsage(json) {
561
+ if (json?.usage) {
562
+ this.usage = {
563
+ promptTokens: json.usage.prompt_tokens || 0,
564
+ completionTokens: json.usage.completion_tokens || 0,
565
+ totalTokens: json.usage.total_tokens || 0
566
+ };
567
+ }
568
+ if (json?.type === "message_delta" && json?.usage) {
569
+ this.usage = {
570
+ promptTokens: json.usage.input_tokens || 0,
571
+ completionTokens: json.usage.output_tokens || 0,
572
+ totalTokens: (json.usage.input_tokens || 0) + (json.usage.output_tokens || 0)
573
+ };
574
+ }
575
+ if (json?.usageMetadata) {
576
+ this.usage = {
577
+ promptTokens: json.usageMetadata.promptTokenCount || 0,
578
+ completionTokens: json.usageMetadata.candidatesTokenCount || 0,
579
+ totalTokens: json.usageMetadata.totalTokenCount || 0
580
+ };
581
+ }
582
+ }
583
+ };
584
+
585
+ // src/resources/chat.ts
586
+ var ChatResource = class {
587
+ constructor(client) {
588
+ this.completions = new ChatCompletionsResource(client);
589
+ }
590
+ };
591
+ var ChatCompletionsResource = class {
592
+ constructor(client) {
593
+ this.client = client;
594
+ }
595
+ async create(options) {
596
+ const headers = {};
597
+ if (options.openaiKey) {
598
+ headers["x-openai-key"] = options.openaiKey;
599
+ } else if (options.anthropicKey) {
600
+ headers["x-anthropic-key"] = options.anthropicKey;
601
+ } else if (options.googleKey) {
602
+ headers["x-google-key"] = options.googleKey;
603
+ }
604
+ const body = {
605
+ model: options.model,
606
+ messages: options.messages,
607
+ stream: options.stream || false,
608
+ max_tokens: options.maxTokens,
609
+ temperature: options.temperature,
610
+ top_p: options.topP,
611
+ stop: options.stop,
612
+ mnx: {
613
+ subject_id: options.subjectId,
614
+ chat_id: options.chatId,
615
+ learn: options.learn,
616
+ recall: options.recall,
617
+ history: options.history,
618
+ log: options.log,
619
+ state: options.state,
620
+ system_prompt: options.systemPrompt,
621
+ metadata: options.metadata,
622
+ regenerate_key: options.regenerateKey
623
+ }
624
+ };
625
+ return this.client._request("POST", "/chat/completions", {
626
+ body,
627
+ headers
628
+ });
629
+ }
630
+ };
631
+
632
+ // src/resources/memories.ts
633
+ var MemoriesResource = class {
634
+ constructor(client) {
635
+ this.client = client;
636
+ }
637
+ async create(options) {
638
+ return this.client._request("POST", "/memories", {
639
+ body: {
640
+ subject_id: options.subjectId,
641
+ text: options.text,
642
+ source: options.source,
643
+ visibility: options.visibility,
644
+ metadata: options.metadata
645
+ }
646
+ });
647
+ }
648
+ async get(id) {
649
+ return this.client._request("GET", `/memories/${id}`);
650
+ }
651
+ async list(subjectId, options) {
652
+ const response = await this.client._request("GET", "/memories", {
653
+ query: {
654
+ subject_id: subjectId,
655
+ limit: options?.limit,
656
+ offset: options?.offset
657
+ }
658
+ });
659
+ return response.memories;
660
+ }
661
+ async search(options) {
662
+ const response = await this.client._request("POST", "/memories/search", {
663
+ body: {
664
+ subject_id: options.subjectId,
665
+ query: options.query,
666
+ limit: options.limit,
667
+ min_score: options.minScore,
668
+ include_deleted: options.includeDeleted,
669
+ include_superseded: options.includeSuperseded
670
+ }
671
+ });
672
+ return response.results;
673
+ }
674
+ async delete(id) {
675
+ await this.client._request("DELETE", `/memories/${id}`);
676
+ }
677
+ };
678
+
679
+ // src/resources/claims.ts
680
+ var ClaimsResource = class {
681
+ constructor(client) {
682
+ this.client = client;
683
+ }
684
+ async create(options) {
685
+ return this.client._request("POST", "/claims", {
686
+ body: {
687
+ subject_id: options.subjectId,
688
+ slot: options.slot,
689
+ value: options.value,
690
+ confidence: options.confidence,
691
+ source: options.source,
692
+ source_memory_id: options.sourceMemoryId
693
+ }
694
+ });
695
+ }
696
+ async get(id) {
697
+ return this.client._request("GET", `/claims/${id}`);
698
+ }
699
+ async getBySlot(subjectId, slot) {
700
+ try {
701
+ return await this.client._request("GET", `/claims/subject/${subjectId}/slot/${slot}`);
702
+ } catch (error) {
703
+ if (error instanceof NotFoundError) {
704
+ return null;
705
+ }
706
+ throw error;
707
+ }
708
+ }
709
+ async listSlots(subjectId) {
710
+ return this.client._request("GET", `/claims/subject/${subjectId}/slots`);
711
+ }
712
+ async retract(id) {
713
+ await this.client._request("POST", `/claims/${id}/retract`);
714
+ }
715
+ };
716
+
717
+ // src/resources/profiles.ts
718
+ var ProfilesResource = class {
719
+ constructor(client) {
720
+ this.client = client;
721
+ }
722
+ async get(subjectId) {
723
+ return this.client._request("GET", "/profiles", {
724
+ query: { subject_id: subjectId }
725
+ });
726
+ }
727
+ };
728
+
729
+ // src/resources/state.ts
730
+ var StateResource = class {
731
+ constructor(client) {
732
+ this.client = client;
733
+ }
734
+ async get(key, subjectId) {
735
+ try {
736
+ return await this.client._request("GET", `/state/${key}`, {
737
+ query: subjectId ? { subject_id: subjectId } : void 0
738
+ });
739
+ } catch (error) {
740
+ if (error instanceof NotFoundError) {
741
+ return null;
742
+ }
743
+ throw error;
744
+ }
745
+ }
746
+ async set(options) {
747
+ return this.client._request("POST", `/state/${options.key}`, {
748
+ body: {
749
+ value: options.value,
750
+ subject_id: options.subjectId,
751
+ ttl_seconds: options.ttlSeconds
752
+ }
753
+ });
754
+ }
755
+ async delete(key, subjectId) {
756
+ await this.client._request("DELETE", `/state/${key}`, {
757
+ query: subjectId ? { subject_id: subjectId } : void 0
758
+ });
759
+ }
760
+ };
761
+
762
+ // src/resources/prompts.ts
763
+ var PromptsResource = class {
764
+ constructor(client) {
765
+ this.client = client;
766
+ }
767
+ async create(options) {
768
+ const response = await this.client._request("POST", "/prompts", {
769
+ body: {
770
+ name: options.name,
771
+ prompt_text: options.promptText,
772
+ is_default: options.isDefault
773
+ }
774
+ });
775
+ return response.prompt;
776
+ }
777
+ async get(id) {
778
+ return this.client._request("GET", `/prompts/${id}`);
779
+ }
780
+ async list() {
781
+ const response = await this.client._request("GET", "/prompts");
782
+ return response.prompts;
783
+ }
784
+ async update(id, options) {
785
+ return this.client._request("PATCH", `/prompts/${id}`, {
786
+ body: {
787
+ name: options.name,
788
+ prompt_text: options.promptText,
789
+ is_default: options.isDefault
790
+ }
791
+ });
792
+ }
793
+ async delete(id) {
794
+ await this.client._request("DELETE", `/prompts/${id}`);
795
+ }
796
+ async resolve(options) {
797
+ return this.client._request("GET", "/prompts/resolve", {
798
+ query: {
799
+ subject_id: options?.subjectId,
800
+ chat_id: options?.chatId,
801
+ combined: options?.combined
802
+ }
803
+ });
804
+ }
805
+ };
806
+
807
+ // src/client.ts
808
+ var DEFAULT_BASE_URL = "https://mnexium.com/api/v1";
809
+ var DEFAULT_TIMEOUT = 3e4;
810
+ var DEFAULT_MAX_RETRIES = 2;
811
+ var Mnexium = class {
812
+ constructor(config = {}) {
813
+ this.apiKey = config.apiKey;
814
+ this.baseUrl = config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL;
815
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
816
+ this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
817
+ this.openaiConfig = config.openai;
818
+ this.anthropicConfig = config.anthropic;
819
+ this.googleConfig = config.google;
820
+ this.defaults = {
821
+ model: config.defaults?.model || "gpt-4o-mini",
822
+ log: config.defaults?.log ?? true,
823
+ learn: config.defaults?.learn ?? true,
824
+ recall: config.defaults?.recall ?? false,
825
+ history: config.defaults?.history ?? true,
826
+ summarize: config.defaults?.summarize ?? false,
827
+ systemPrompt: config.defaults?.systemPrompt ?? true,
828
+ ...config.defaults
829
+ };
830
+ this.chat = new ChatResource(this);
831
+ this.memories = new MemoriesResource(this);
832
+ this.claims = new ClaimsResource(this);
833
+ this.profiles = new ProfilesResource(this);
834
+ this.state = new StateResource(this);
835
+ this.prompts = new PromptsResource(this);
836
+ }
837
+ async process(input) {
838
+ const options = typeof input === "string" ? { content: input } : input;
839
+ const model = options.model || this.defaults.model || "gpt-4o-mini";
840
+ const subjectId = options.subjectId || this.defaults.subjectId;
841
+ const chatId = options.chatId || this.defaults.chatId;
842
+ const log = options.log ?? this.defaults.log ?? true;
843
+ const learn = options.learn ?? this.defaults.learn ?? true;
844
+ const recall = options.recall ?? this.defaults.recall ?? false;
845
+ const profile = options.profile ?? this.defaults.profile ?? false;
846
+ const history = options.history ?? this.defaults.history ?? true;
847
+ const summarize = options.summarize ?? this.defaults.summarize ?? false;
848
+ const systemPrompt = options.systemPrompt ?? this.defaults.systemPrompt ?? true;
849
+ const metadata = options.metadata || this.defaults.metadata;
850
+ const maxTokens = options.maxTokens || this.defaults.maxTokens;
851
+ const temperature = options.temperature ?? this.defaults.temperature;
852
+ const regenerateKey = options.regenerateKey ?? this.defaults.regenerateKey ?? false;
853
+ const headers = {};
854
+ const provider = detectProvider(model);
855
+ if (provider === "anthropic" && this.anthropicConfig?.apiKey) {
856
+ headers["x-anthropic-key"] = this.anthropicConfig.apiKey;
857
+ } else if (provider === "google" && this.googleConfig?.apiKey) {
858
+ headers["x-google-key"] = this.googleConfig.apiKey;
859
+ } else if (this.openaiConfig?.apiKey) {
860
+ headers["x-openai-key"] = this.openaiConfig.apiKey;
861
+ } else if (this.anthropicConfig?.apiKey) {
862
+ headers["x-anthropic-key"] = this.anthropicConfig.apiKey;
863
+ } else if (this.googleConfig?.apiKey) {
864
+ headers["x-google-key"] = this.googleConfig.apiKey;
865
+ }
866
+ const body = {
867
+ model,
868
+ messages: [{ role: "user", content: options.content }],
869
+ stream: options.stream || false,
870
+ max_tokens: maxTokens,
871
+ temperature,
872
+ mnx: {
873
+ subject_id: subjectId,
874
+ chat_id: chatId,
875
+ log,
876
+ learn,
877
+ recall,
878
+ profile,
879
+ history,
880
+ summarize,
881
+ system_prompt: systemPrompt,
882
+ metadata,
883
+ regenerate_key: regenerateKey
884
+ }
885
+ };
886
+ if (options.stream) {
887
+ const response = await this._requestRaw("POST", "/chat/completions", {
888
+ body,
889
+ headers
890
+ });
891
+ return new StreamResponse(response, {
892
+ chatId: response.headers.get("X-Mnx-Chat-Id") || chatId || "",
893
+ subjectId: response.headers.get("X-Mnx-Subject-Id") || subjectId || "",
894
+ model,
895
+ provisionedKey: response.headers.get("X-Mnx-Key-Provisioned") || void 0,
896
+ claimUrl: response.headers.get("X-Mnx-Claim-Url") || void 0
897
+ });
898
+ }
899
+ const raw = await this._request("POST", "/chat/completions", {
900
+ body,
901
+ headers
902
+ });
903
+ const { content: extractedContent, usage: extractedUsage } = extractResponseContent(raw);
904
+ return {
905
+ content: extractedContent,
906
+ chatId: raw.mnx.chat_id,
907
+ subjectId: raw.mnx.subject_id,
908
+ model: raw.model,
909
+ usage: extractedUsage ? {
910
+ promptTokens: extractedUsage.prompt_tokens,
911
+ completionTokens: extractedUsage.completion_tokens,
912
+ totalTokens: extractedUsage.total_tokens
913
+ } : void 0,
914
+ provisionedKey: raw.mnx.provisioned_key,
915
+ claimUrl: raw.mnx.claim_url,
916
+ raw
917
+ };
918
+ }
919
+ /**
920
+ * Get the provisioned trial key (if auto-provisioned)
921
+ * @deprecated Use getTrialInfo() instead
922
+ */
923
+ getProvisionedKey() {
924
+ return this.provisionedKey;
925
+ }
926
+ /**
927
+ * Get trial key info including the key and claim URL
928
+ *
929
+ * @example
930
+ * const trial = mnx.getTrialInfo();
931
+ * if (trial) {
932
+ * console.log('Key:', trial.key);
933
+ * console.log('Claim at:', trial.claimUrl);
934
+ * }
935
+ */
936
+ getTrialInfo() {
937
+ if (!this.provisionedKey) {
938
+ return null;
939
+ }
940
+ return {
941
+ key: this.provisionedKey,
942
+ claimUrl: "https://mnexium.com/claim"
943
+ };
944
+ }
945
+ /**
946
+ * Get a Subject handle for a given subject ID
947
+ *
948
+ * Creating a Subject does NOT make a network call - it's a lightweight scoped handle.
949
+ *
950
+ * @example
951
+ * const alice = mnx.subject("user_123");
952
+ * await alice.process("Hello!");
953
+ * await alice.memories.search("hobbies");
954
+ */
955
+ subject(subjectId) {
956
+ return new Subject(this, subjectId || crypto.randomUUID());
957
+ }
958
+ /**
959
+ * Create a chat for a subject
960
+ *
961
+ * @example
962
+ * const alice = mnx.subject("user_123");
963
+ * const chat = mnx.createChat(alice, { history: true });
964
+ * // or with string:
965
+ * const chat = mnx.createChat("user_123", { history: true });
966
+ */
967
+ createChat(subject, options) {
968
+ const subjectId = typeof subject === "string" ? subject : subject.id;
969
+ return new Chat(this, subjectId, options);
970
+ }
971
+ /**
972
+ * @deprecated Use createChat(subject, options) instead
973
+ */
974
+ createChatSession(options = {}) {
975
+ const subjectId = options.subjectId || crypto.randomUUID();
976
+ return new Chat(this, subjectId, options);
977
+ }
978
+ /**
979
+ * Internal: Set provisioned key from response
980
+ */
981
+ _setProvisionedKey(key) {
982
+ this.provisionedKey = key;
983
+ }
984
+ /**
985
+ * Internal: Make a raw API request (returns Response, used for streaming)
986
+ */
987
+ async _requestRaw(method, path, options = {}) {
988
+ const url = new URL(`${this.baseUrl}${path}`);
989
+ if (options.query) {
990
+ for (const [key, value] of Object.entries(options.query)) {
991
+ if (value !== void 0) {
992
+ url.searchParams.set(key, String(value));
993
+ }
994
+ }
995
+ }
996
+ const headers = {
997
+ "Content-Type": "application/json",
998
+ ...options.headers
999
+ };
1000
+ const effectiveKey = this.apiKey || this.provisionedKey;
1001
+ if (effectiveKey) {
1002
+ headers["x-mnexium-key"] = effectiveKey;
1003
+ }
1004
+ const controller = new AbortController();
1005
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1006
+ const response = await fetch(url.toString(), {
1007
+ method,
1008
+ headers,
1009
+ body: options.body ? JSON.stringify(options.body) : void 0,
1010
+ signal: controller.signal
1011
+ });
1012
+ clearTimeout(timeoutId);
1013
+ const provisionedKey = response.headers.get("x-mnx-key-provisioned");
1014
+ if (provisionedKey) {
1015
+ this._setProvisionedKey(provisionedKey);
1016
+ }
1017
+ if (!response.ok) {
1018
+ const errorBody = await response.json().catch(() => ({}));
1019
+ throw this._handleErrorResponse(response.status, errorBody);
1020
+ }
1021
+ return response;
1022
+ }
1023
+ /**
1024
+ * Internal: Make an API request
1025
+ */
1026
+ async _request(method, path, options = {}) {
1027
+ const url = new URL(`${this.baseUrl}${path}`);
1028
+ if (options.query) {
1029
+ for (const [key, value] of Object.entries(options.query)) {
1030
+ if (value !== void 0) {
1031
+ url.searchParams.set(key, String(value));
1032
+ }
1033
+ }
1034
+ }
1035
+ const headers = {
1036
+ "Content-Type": "application/json",
1037
+ ...options.headers
1038
+ };
1039
+ const effectiveKey = this.apiKey || this.provisionedKey;
1040
+ if (effectiveKey) {
1041
+ headers["x-mnexium-key"] = effectiveKey;
1042
+ }
1043
+ let lastError;
1044
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
1045
+ try {
1046
+ const controller = new AbortController();
1047
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1048
+ const response = await fetch(url.toString(), {
1049
+ method,
1050
+ headers,
1051
+ body: options.body ? JSON.stringify(options.body) : void 0,
1052
+ signal: controller.signal
1053
+ });
1054
+ clearTimeout(timeoutId);
1055
+ const provisionedKey = response.headers.get("x-mnx-key-provisioned");
1056
+ if (provisionedKey) {
1057
+ this._setProvisionedKey(provisionedKey);
1058
+ }
1059
+ if (!response.ok) {
1060
+ const errorBody = await response.json().catch(() => ({}));
1061
+ throw this._handleErrorResponse(response.status, errorBody);
1062
+ }
1063
+ return await response.json();
1064
+ } catch (error) {
1065
+ lastError = error;
1066
+ if (error instanceof APIError && error.status < 500 && !(error instanceof RateLimitError)) {
1067
+ throw error;
1068
+ }
1069
+ if (attempt === this.maxRetries) {
1070
+ throw error;
1071
+ }
1072
+ await this._sleep(Math.pow(2, attempt) * 1e3);
1073
+ }
1074
+ }
1075
+ throw lastError || new MnexiumError("Request failed");
1076
+ }
1077
+ _handleErrorResponse(status, body) {
1078
+ const message = body.message || body.error || "Unknown error";
1079
+ const code = body.error;
1080
+ switch (status) {
1081
+ case 401:
1082
+ return new AuthenticationError(message);
1083
+ case 404:
1084
+ return new NotFoundError(message);
1085
+ case 429:
1086
+ return new RateLimitError(message, {
1087
+ current: body.current,
1088
+ limit: body.limit
1089
+ });
1090
+ default:
1091
+ return new APIError(message, status, code);
1092
+ }
1093
+ }
1094
+ _sleep(ms) {
1095
+ return new Promise((resolve) => setTimeout(resolve, ms));
1096
+ }
1097
+ };
1098
+ // Annotate the CommonJS export names for ESM import in node:
1099
+ 0 && (module.exports = {
1100
+ APIError,
1101
+ AuthenticationError,
1102
+ Chat,
1103
+ ChatSession,
1104
+ EventStream,
1105
+ Mnexium,
1106
+ MnexiumError,
1107
+ RateLimitError,
1108
+ StreamResponse,
1109
+ Subject
1110
+ });