mindupload 1.5.1

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,443 @@
1
+ // src/errors.ts
2
+ var MindUploadError = class extends Error {
3
+ operation;
4
+ response;
5
+ constructor(message, options = {}) {
6
+ super(message);
7
+ this.name = "MindUploadError";
8
+ this.operation = options.operation;
9
+ this.response = options.response;
10
+ Object.setPrototypeOf(this, new.target.prototype);
11
+ }
12
+ };
13
+ var ApiError = class extends MindUploadError {
14
+ status;
15
+ constructor(message, options) {
16
+ super(message, options);
17
+ this.name = "ApiError";
18
+ this.status = options.status;
19
+ }
20
+ };
21
+ var AuthenticationError = class extends ApiError {
22
+ constructor(message, options) {
23
+ super(message, options);
24
+ this.name = "AuthenticationError";
25
+ }
26
+ };
27
+ var RateLimitError = class extends ApiError {
28
+ /** Server-advised wait in seconds, when provided. */
29
+ retryAfter;
30
+ constructor(message, options) {
31
+ super(message, options);
32
+ this.name = "RateLimitError";
33
+ this.retryAfter = options.retryAfter;
34
+ }
35
+ };
36
+ var MindUploadConnectionError = class extends MindUploadError {
37
+ constructor(message, options = {}) {
38
+ super(message, options);
39
+ this.name = "MindUploadConnectionError";
40
+ }
41
+ };
42
+
43
+ // src/version.ts
44
+ var VERSION = "1.5.1";
45
+
46
+ // src/client.ts
47
+ var DEFAULT_BASE_URL = "https://partner.mindupload.app";
48
+ var AUTH_HEADER = "X-Partner-Key";
49
+ var RETRY_STATUSES = /* @__PURE__ */ new Set([429, 503]);
50
+ function camelToSnake(key) {
51
+ return key.replace(/[A-Z]/g, (m) => "_" + m.toLowerCase());
52
+ }
53
+ function toBody(params) {
54
+ const out = {};
55
+ for (const [key, value] of Object.entries(params)) {
56
+ if (value !== void 0 && value !== null) out[camelToSnake(key)] = value;
57
+ }
58
+ return out;
59
+ }
60
+ function sleep(ms) {
61
+ return new Promise((resolve) => setTimeout(resolve, ms));
62
+ }
63
+ function backoffMs(attempt, retryAfter) {
64
+ if (retryAfter) {
65
+ const seconds = Number(retryAfter);
66
+ if (Number.isFinite(seconds)) return Math.min(seconds * 1e3, 6e4);
67
+ }
68
+ return Math.min(500 * 2 ** (attempt - 1), 8e3);
69
+ }
70
+ var MindUploadBase = class {
71
+ partnerKey;
72
+ baseUrl;
73
+ preferredLanguage;
74
+ timeoutMs;
75
+ maxRetries;
76
+ userAgent;
77
+ fetchFn;
78
+ constructor(options) {
79
+ if (!options || !options.partnerKey) {
80
+ throw new Error(
81
+ "partnerKey is required. It is a server-side secret \u2014 never expose it to a browser or ship it in client code."
82
+ );
83
+ }
84
+ this.partnerKey = options.partnerKey;
85
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
86
+ this.preferredLanguage = options.preferredLanguage;
87
+ this.timeoutMs = options.timeoutMs ?? 3e4;
88
+ this.maxRetries = options.maxRetries ?? 2;
89
+ this.userAgent = options.userAgent ?? `mindupload-js/${VERSION}`;
90
+ const globalFetch = globalThis.fetch;
91
+ if (!globalFetch) {
92
+ throw new Error("global fetch is not available; use Node 18+, Deno, Bun, or an edge runtime.");
93
+ }
94
+ this.fetchFn = globalFetch.bind(globalThis);
95
+ }
96
+ async request(operation, params) {
97
+ const body = toBody(params);
98
+ if (body["preferred_language"] === void 0 && this.preferredLanguage !== void 0) {
99
+ body["preferred_language"] = this.preferredLanguage;
100
+ }
101
+ const url = `${this.baseUrl}/v1/${operation}`;
102
+ const payload = JSON.stringify(body);
103
+ const headers = {
104
+ "Content-Type": "application/json",
105
+ Accept: "application/json",
106
+ [AUTH_HEADER]: this.partnerKey,
107
+ "User-Agent": this.userAgent
108
+ };
109
+ let attempt = 0;
110
+ for (; ; ) {
111
+ let response;
112
+ try {
113
+ response = await this.fetchFn(url, { method: "POST", headers, body: payload, signal: this.timeoutSignal() });
114
+ } catch (err) {
115
+ throw new MindUploadConnectionError(
116
+ `Could not reach the Mind Upload API for '${operation}': ${err.message}`,
117
+ { operation }
118
+ );
119
+ }
120
+ let text;
121
+ try {
122
+ text = await response.text();
123
+ } catch (err) {
124
+ throw new MindUploadConnectionError(
125
+ `Failed to read the Mind Upload API response for '${operation}': ${err.message}`,
126
+ { operation }
127
+ );
128
+ }
129
+ let data;
130
+ try {
131
+ data = text ? JSON.parse(text) : { success: false };
132
+ } catch {
133
+ data = { success: false };
134
+ }
135
+ if (!response.ok) {
136
+ if (RETRY_STATUSES.has(response.status) && attempt < this.maxRetries) {
137
+ attempt += 1;
138
+ await sleep(backoffMs(attempt, response.headers.get("Retry-After")));
139
+ continue;
140
+ }
141
+ throw this.errorFor(response.status, data, operation, response.headers.get("Retry-After"));
142
+ }
143
+ if (!data.success) {
144
+ throw new MindUploadError(data.error_message || `${operation} failed`, { operation, response: data });
145
+ }
146
+ return data;
147
+ }
148
+ }
149
+ timeoutSignal() {
150
+ const abortSignal = globalThis.AbortSignal;
151
+ return abortSignal && typeof abortSignal.timeout === "function" ? abortSignal.timeout(this.timeoutMs) : void 0;
152
+ }
153
+ errorFor(status, data, operation, retryAfterHeader) {
154
+ const message = data && data.error_message || `HTTP ${status}`;
155
+ if (status === 401) return new AuthenticationError(message, { status, operation, response: data });
156
+ if (status === 429) {
157
+ const parsed = retryAfterHeader ? Number(retryAfterHeader) : void 0;
158
+ const retryAfter = parsed !== void 0 && Number.isFinite(parsed) ? parsed : void 0;
159
+ return new RateLimitError(message, { status, operation, response: data, retryAfter });
160
+ }
161
+ return new ApiError(message, { status, operation, response: data });
162
+ }
163
+ };
164
+
165
+ // src/operations.ts
166
+ var MindUpload = class extends MindUploadBase {
167
+ // --- AI Consciousnesses ---
168
+ /** Create a new AI consciousness for the user.
169
+ *
170
+ * Response fields: success, error_message.
171
+ * @see https://docs.mindupload.app
172
+ */
173
+ createClone(params = {}) {
174
+ return this.request("create_clone", params);
175
+ }
176
+ /** List the user's AI consciousnesses.
177
+ *
178
+ * Response fields: success, error_message, clones.
179
+ * @see https://docs.mindupload.app
180
+ */
181
+ getClones(params = {}) {
182
+ return this.request("get_clones", params);
183
+ }
184
+ /** Update an AI consciousness's profile.
185
+ *
186
+ * Response fields: success, error_message.
187
+ * @see https://docs.mindupload.app
188
+ */
189
+ updateClone(params = {}) {
190
+ return this.request("update_clone", params);
191
+ }
192
+ // --- Account ---
193
+ /** Check your partner API rate limits, credit caps, and current usage.
194
+ *
195
+ * Response fields: success, error_message, per_user_rate_limit_per_min, per_user_daily_credit_cap, partner_rate_limit_per_min, partner_daily_credit_cap, max_users, registered_users, partner_requests_last_minute, partner_credit_spends_last_day, user, user_requests_last_minute, user_credit_spends_last_day, credit_spending_tasks, operation_duration_ms.
196
+ * @see https://docs.mindupload.app
197
+ */
198
+ getQuota(params = {}) {
199
+ return this.request("get_quota", params);
200
+ }
201
+ // --- Authentication ---
202
+ /** Check whether a username is still available before registering.
203
+ *
204
+ * Response fields: success, error_message, exists, disabled, rate_limited, flood_window, wait_seconds, operation_duration_ms.
205
+ * @see https://docs.mindupload.app
206
+ */
207
+ checkUsername(params = {}) {
208
+ return this.request("check_username", params);
209
+ }
210
+ /** Sign a user in and receive a session token (JWT) for subsequent calls.
211
+ *
212
+ * Response fields: success, error_message, jwt, decrypted_user.
213
+ * @see https://docs.mindupload.app
214
+ */
215
+ login(params = {}) {
216
+ return this.request("login", params);
217
+ }
218
+ /** End the current user session.
219
+ *
220
+ * Response fields: success, error_message, revoked, operation_duration_ms.
221
+ * @see https://docs.mindupload.app
222
+ */
223
+ logout(params = {}) {
224
+ return this.request("logout", params);
225
+ }
226
+ /** Create a user account on your platform.
227
+ *
228
+ * Response fields: success, error_message, jwt, decrypted_user.
229
+ * @see https://docs.mindupload.app
230
+ */
231
+ register(params = {}) {
232
+ return this.request("register", params);
233
+ }
234
+ // --- Chatrooms ---
235
+ /** Cheaply poll whether the user's chatrooms have new activity.
236
+ *
237
+ * Response fields: success, error_message, server_time, poll_config, chatrooms.
238
+ * @see https://docs.mindupload.app
239
+ */
240
+ checkChatroomUpdates(params = {}) {
241
+ return this.request("check_chatroom_updates", params);
242
+ }
243
+ /** Create a chatroom.
244
+ *
245
+ * Response fields: success, error_message, chatroom_id.
246
+ * @see https://docs.mindupload.app
247
+ */
248
+ createChatroom(params = {}) {
249
+ return this.request("create_chatroom", params);
250
+ }
251
+ /** Invite a user or an AI consciousness into a chatroom.
252
+ *
253
+ * Response fields: success, error_message, membership_id.
254
+ * @see https://docs.mindupload.app
255
+ */
256
+ createChatroomMembership(params = {}) {
257
+ return this.request("create_chatroom_membership", params);
258
+ }
259
+ /** Send a message to a chatroom.
260
+ *
261
+ * Response fields: success, error_message, message_id.
262
+ * @see https://docs.mindupload.app
263
+ */
264
+ createChatroomMessage(params = {}) {
265
+ return this.request("create_chatroom_message", params);
266
+ }
267
+ /** List the members of a chatroom the user belongs to.
268
+ *
269
+ * Response fields: success, error_message, total_count, page, page_size, total_pages, has_next, has_prev, next_cursor_value, next_cursor_id, memberships.
270
+ * @see https://docs.mindupload.app
271
+ */
272
+ getChatroomMembership(params = {}) {
273
+ return this.request("get_chatroom_membership", params);
274
+ }
275
+ /** Fetch messages from a chatroom the user belongs to.
276
+ *
277
+ * Response fields: success, error_message, total_count, page, page_size, total_pages, has_next, has_prev, next_cursor_value, next_cursor_id, messages, media_thumbnails, since_overflow.
278
+ * @see https://docs.mindupload.app
279
+ */
280
+ getChatroomMessages(params = {}) {
281
+ return this.request("get_chatroom_messages", params);
282
+ }
283
+ /** List the chatrooms the user belongs to.
284
+ *
285
+ * Response fields: success, error_message, total_count, page, page_size, total_pages, has_next, has_prev, next_cursor_value, next_cursor_id, chatrooms.
286
+ * @see https://docs.mindupload.app
287
+ */
288
+ getChatrooms(params = {}) {
289
+ return this.request("get_chatrooms", params);
290
+ }
291
+ // --- Conversation ---
292
+ /** Fetch the one-on-one conversation history with an AI consciousness.
293
+ *
294
+ * Response fields: success, error_message, total_count, page, page_size, total_pages, has_next, has_prev, next_cursor_value, next_cursor_id, chats, media_thumbnails.
295
+ * @see https://docs.mindupload.app
296
+ */
297
+ getChat(params = {}) {
298
+ return this.request("get_chat", params);
299
+ }
300
+ /** Send a message to an AI consciousness and receive its reply.
301
+ *
302
+ * Response fields: success, error_message, response_text, clone_nickname, consolidation_summary, consolidation_count, consolidation_dispatched.
303
+ * @see https://docs.mindupload.app
304
+ */
305
+ rag(params = {}) {
306
+ return this.request("rag", params);
307
+ }
308
+ /** Have an AI consciousness proactively join the conversation in a chatroom.
309
+ *
310
+ * Response fields: success, error_message, response_text, chatroom_digests_count, chatroom_digests_summary, consolidation_summary, consolidation_count, consolidation_dispatched.
311
+ * @see https://docs.mindupload.app
312
+ */
313
+ triggerSocial(params = {}) {
314
+ return this.request("trigger_social", params);
315
+ }
316
+ // --- Insights ---
317
+ /** Fetch the mind-graph visualization data of an AI consciousness.
318
+ *
319
+ * Response fields: success, error_message, root_node_id, node, children, texts, total_texts, texts_offset, has_more_texts, is_building.
320
+ * @see https://docs.mindupload.app
321
+ */
322
+ getMindCluster(params = {}) {
323
+ return this.request("get_mind_cluster", params);
324
+ }
325
+ /** Generate or fetch the compatibility report between two chatroom members.
326
+ *
327
+ * Response fields: success, error_message, report, report_generated_at, is_generating, charged.
328
+ * @see https://docs.mindupload.app
329
+ */
330
+ getSoulmateReport(params = {}) {
331
+ return this.request("get_soulmate_report", params);
332
+ }
333
+ // --- Media ---
334
+ /** Cancel a multipart upload and discard its parts.
335
+ *
336
+ * Response fields: success, error_message.
337
+ * @see https://docs.mindupload.app
338
+ */
339
+ abortMultipartUpload(params = {}) {
340
+ return this.request("abort_multipart_upload", params);
341
+ }
342
+ /** Cancel a pending upload.
343
+ *
344
+ * Response fields: success, error_message.
345
+ * @see https://docs.mindupload.app
346
+ */
347
+ cancelUpload(params = {}) {
348
+ return this.request("cancel_upload", params);
349
+ }
350
+ /** Finish a multipart upload.
351
+ *
352
+ * Response fields: success, error_message, media_url.
353
+ * @see https://docs.mindupload.app
354
+ */
355
+ completeMultipartUpload(params = {}) {
356
+ return this.request("complete_multipart_upload", params);
357
+ }
358
+ /** List the parts already uploaded in a multipart upload.
359
+ *
360
+ * Response fields: success, error_message, parts.
361
+ * @see https://docs.mindupload.app
362
+ */
363
+ listUploadParts(params = {}) {
364
+ return this.request("list_upload_parts", params);
365
+ }
366
+ /** Start a large-file upload in multiple parts.
367
+ *
368
+ * Response fields: success, error_message, upload_id, r2_key, media_url, signed_media_url, thumbnail_r2_key, thumbnail_presigned_url, signed_thumbnail_url, message.
369
+ * @see https://docs.mindupload.app
370
+ */
371
+ requestMultipartUpload(params = {}) {
372
+ return this.request("request_multipart_upload", params);
373
+ }
374
+ /** Request an upload slot and a signed viewing link for a media attachment.
375
+ *
376
+ * Response fields: success, error_message, r2_key, presigned_url, media_url, signed_media_url, thumbnail_r2_key, thumbnail_presigned_url, signed_thumbnail_url, message.
377
+ * @see https://docs.mindupload.app
378
+ */
379
+ requestUploadUrl(params = {}) {
380
+ return this.request("request_upload_url", params);
381
+ }
382
+ /** Get the signed link for one part of a multipart upload.
383
+ *
384
+ * Response fields: success, error_message, presigned_url.
385
+ * @see https://docs.mindupload.app
386
+ */
387
+ signUploadPart(params = {}) {
388
+ return this.request("sign_upload_part", params);
389
+ }
390
+ /** Get signed links for several parts of a multipart upload at once.
391
+ *
392
+ * Response fields: success, error_message, presigned_urls.
393
+ * @see https://docs.mindupload.app
394
+ */
395
+ signUploadPartsBatch(params = {}) {
396
+ return this.request("sign_upload_parts_batch", params);
397
+ }
398
+ // --- Memories ---
399
+ /** Upload a memory or persona entry to an AI consciousness.
400
+ *
401
+ * Response fields: success, error_message, cluster_label, cluster_modified_count.
402
+ * @see https://docs.mindupload.app
403
+ */
404
+ createText(params = {}) {
405
+ return this.request("create_text", params);
406
+ }
407
+ /** List the memories and persona entries uploaded to an AI consciousness.
408
+ *
409
+ * Response fields: success, error_message, total_count, page, page_size, total_pages, has_next, has_prev, next_cursor_value, next_cursor_id, texts.
410
+ * @see https://docs.mindupload.app
411
+ */
412
+ getTexts(params = {}) {
413
+ return this.request("get_texts", params);
414
+ }
415
+ // --- Users ---
416
+ /** Fetch the signed-in user's profile.
417
+ *
418
+ * Response fields: success, error_message, jwt, decrypted_user.
419
+ * @see https://docs.mindupload.app
420
+ */
421
+ getUser(params = {}) {
422
+ return this.request("get_user", params);
423
+ }
424
+ /** Update the signed-in user's profile.
425
+ *
426
+ * Response fields: success, error_message.
427
+ * @see https://docs.mindupload.app
428
+ */
429
+ updateUser(params = {}) {
430
+ return this.request("update_user", params);
431
+ }
432
+ };
433
+ export {
434
+ ApiError,
435
+ AuthenticationError,
436
+ DEFAULT_BASE_URL,
437
+ MindUpload,
438
+ MindUploadBase,
439
+ MindUploadConnectionError,
440
+ MindUploadError,
441
+ RateLimitError,
442
+ VERSION
443
+ };
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "mindupload",
3
+ "version": "1.5.1",
4
+ "description": "Official server-side SDK for the Mind Upload partner API \u2014 the world's first API for artificial consciousness. Integrate living, evolving AI consciousnesses into your platform: lasting memory, one-on-one chat, and human + AI group chatrooms.",
5
+ "keywords": [
6
+ "mindupload",
7
+ "mind upload",
8
+ "AI consciousness",
9
+ "artificial consciousness",
10
+ "digital consciousness",
11
+ "AI clone",
12
+ "AI persona",
13
+ "AI companion",
14
+ "AI chatroom",
15
+ "digital immortality",
16
+ "consciousness API",
17
+ "AI SDK"
18
+ ],
19
+ "license": "MIT",
20
+ "author": "Mind Upload",
21
+ "homepage": "https://docs.mindupload.app",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/Voidborn-Industries/mindupload-sdk-js.git"
25
+ },
26
+ "bugs": {
27
+ "url": "https://docs.mindupload.app"
28
+ },
29
+ "type": "module",
30
+ "main": "./dist/index.cjs",
31
+ "module": "./dist/index.js",
32
+ "types": "./dist/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "import": {
36
+ "types": "./dist/index.d.ts",
37
+ "default": "./dist/index.js"
38
+ },
39
+ "require": {
40
+ "types": "./dist/index.d.cts",
41
+ "default": "./dist/index.cjs"
42
+ }
43
+ }
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "README.md",
48
+ "LICENSE"
49
+ ],
50
+ "engines": {
51
+ "node": ">=18"
52
+ },
53
+ "sideEffects": false,
54
+ "scripts": {
55
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean --target node18",
56
+ "test": "node --test",
57
+ "prepublishOnly": "npm run build"
58
+ },
59
+ "devDependencies": {
60
+ "tsup": "^8.0.0",
61
+ "typescript": "^5.4.0",
62
+ "@types/node": "^20.0.0"
63
+ }
64
+ }