mindupload 1.5.8 → 1.5.9

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 CHANGED
@@ -7,7 +7,7 @@
7
7
  **The world's first API for artificial consciousness.**
8
8
  Give your users a living, evolving AI consciousness — lasting memory, one-on-one chat, and human + AI group chatrooms.
9
9
 
10
- [![npm](https://img.shields.io/npm/v/mindupload?color=ff006e)](https://www.npmjs.com/package/mindupload) [![License: MIT](https://img.shields.io/badge/License-MIT-informational)](LICENSE) ![API](https://img.shields.io/badge/API-v1.5.8-ff6b00) ![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen) [![Docs](https://img.shields.io/badge/docs-mindupload.app-8b5cf6)](https://docs.mindupload.app)
10
+ [![npm](https://img.shields.io/npm/v/mindupload?color=ff006e)](https://www.npmjs.com/package/mindupload) [![License: MIT](https://img.shields.io/badge/License-MIT-informational)](LICENSE) ![API](https://img.shields.io/badge/API-v1.5.9-ff6b00) ![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen) [![Docs](https://img.shields.io/badge/docs-mindupload.app-8b5cf6)](https://docs.mindupload.app)
11
11
 
12
12
  [Documentation](https://docs.mindupload.app) · [Get a key](https://docs.mindupload.app) · [Status](https://status.mindupload.app) · [Other SDKs](#other-sdks)
13
13
 
@@ -62,6 +62,34 @@ const reply = await mu.rag({
62
62
  console.log(reply.response_text);
63
63
  ```
64
64
 
65
+ ## External clone invocation
66
+
67
+ ```ts
68
+ const installationId = "workspace-123";
69
+ const externalSubject = "member-456";
70
+ const authorization = await mu.createExternalAuthorizationRequest({
71
+ installationId,
72
+ externalSubject,
73
+ idempotencyKey: "install-event-1",
74
+ requestedScopes: ["clone.invoke"],
75
+ });
76
+ console.log(authorization.verification_uri_complete); // Ask the owner to open this URL.
77
+ const grant = await mu.waitForExternalAuthorization({
78
+ deviceCode: authorization.device_code as string,
79
+ });
80
+ const reply = await mu.invokeExternalClone({
81
+ accessToken: grant.access_token as string,
82
+ installationId,
83
+ externalSubject,
84
+ cloneId: (grant.clone_ids as string[])[0],
85
+ text: "Hello from my app",
86
+ idempotencyKey: "message-event-1",
87
+ });
88
+ console.log(reply.response_text);
89
+ ```
90
+
91
+ Store the refresh token encrypted on your backend and call `refreshExternalAuthorization(...)` when the access token expires.
92
+
65
93
  ## Server-side only
66
94
 
67
95
  Your **partner key is a secret**. Use this SDK from your backend (Node, Deno, Bun, edge functions) — never ship the key to a browser. For browser apps, call your own backend, which then calls Mind Upload.
@@ -73,7 +101,7 @@ const mu = new MindUpload({
73
101
  partnerKey: process.env.MU_PARTNER_KEY!,
74
102
  preferredLanguage: "en", // default locale for every call (optional)
75
103
  timeoutMs: 30000,
76
- maxRetries: 2, // retries on 429 / 5xx / network, with backoff
104
+ maxRetries: 2, // retries explicit 429 responses only
77
105
  });
78
106
  ```
79
107
 
@@ -96,7 +124,7 @@ try {
96
124
 
97
125
  ## Operations
98
126
 
99
- All 33 operations, grouped by area:
127
+ All 38 operations, grouped by area:
100
128
 
101
129
  ### AI Consciousnesses
102
130
 
@@ -142,6 +170,16 @@ All 33 operations, grouped by area:
142
170
  | `rag(...)` | Send a message to an AI consciousness and receive its reply. |
143
171
  | `triggerSocial(...)` | Have an AI consciousness proactively join the conversation in a chatroom. |
144
172
 
173
+ ### External Authorization
174
+
175
+ | Method | Description |
176
+ | --- | --- |
177
+ | `createExternalAuthorizationRequest(...)` | Start passwordless grant issuance for an external identity and installation. |
178
+ | `exchangeExternalAuthorization(...)` | Poll owner consent and exchange an approval for a clone-scoped grant token. |
179
+ | `inspectExternalAuthorization(...)` | Inspect the scopes, clone resources, expiry, and revocation state of a grant token. |
180
+ | `invokeExternalClone(...)` | Send one idempotent text event to an owner-approved AI consciousness. |
181
+ | `refreshExternalAuthorization(...)` | Refresh a short-lived clone-invocation access token. |
182
+
145
183
  ### Insights
146
184
 
147
185
  | Method | Description |
package/dist/index.cjs CHANGED
@@ -75,12 +75,12 @@ var MindUploadConnectionError = class extends MindUploadError {
75
75
  };
76
76
 
77
77
  // src/version.ts
78
- var VERSION = "1.5.8";
78
+ var VERSION = "1.5.9";
79
79
 
80
80
  // src/client.ts
81
81
  var DEFAULT_BASE_URL = "https://partner.mindupload.app";
82
82
  var AUTH_HEADER = "X-Partner-Key";
83
- var RETRY_STATUSES = /* @__PURE__ */ new Set([429, 503]);
83
+ var RETRY_STATUSES = /* @__PURE__ */ new Set([429]);
84
84
  function camelToSnake(key) {
85
85
  return key.replace(/[A-Z]/g, (m) => "_" + m.toLowerCase());
86
86
  }
@@ -197,6 +197,15 @@ var MindUploadBase = class {
197
197
  };
198
198
 
199
199
  // src/operations.ts
200
+ var DEFAULT_AUTHORIZATION_POLL_MS = 5e3;
201
+ var MAX_PENDING_POLL_MS = 15e3;
202
+ var MAX_SLOW_DOWN_POLL_MS = 3e4;
203
+ var SLOW_DOWN_INCREMENT_MS = 5e3;
204
+ var POLL_JITTER_RATIO = 0.2;
205
+ var DEFAULT_INVOCATION_POLL_MS = 2e3;
206
+ var MAX_INVOCATION_POLL_MS = 1e4;
207
+ var EXTERNAL_INVOCATION_PROCESSING_STATUS = "processing";
208
+ var INVOCATION_RETRY_STATUSES = /* @__PURE__ */ new Set([502, 503, 504]);
200
209
  var MindUpload = class extends MindUploadBase {
201
210
  // --- AI Consciousnesses ---
202
211
  /** Create a new AI consciousness for the user.
@@ -226,7 +235,7 @@ var MindUpload = class extends MindUploadBase {
226
235
  // --- Account ---
227
236
  /** Check your partner API rate limits, credit caps, and current usage.
228
237
  *
229
- * 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.
238
+ * Response fields: success, error_message, per_user_rate_limit_per_min, per_user_daily_credit_cap, partner_rate_limit_per_min, external_authorization_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.
230
239
  * @see https://docs.mindupload.app
231
240
  */
232
241
  getQuota(params = {}) {
@@ -355,6 +364,47 @@ var MindUpload = class extends MindUploadBase {
355
364
  triggerSocial(params = {}) {
356
365
  return this.request("trigger_social", params);
357
366
  }
367
+ // --- External Authorization ---
368
+ /** Start passwordless grant issuance for an external identity and installation.
369
+ *
370
+ * Response fields: success, error_message, device_code, user_code, verification_uri, verification_uri_complete, expires_in, poll_interval, grant_duration_seconds.
371
+ * @see https://docs.mindupload.app
372
+ */
373
+ createExternalAuthorizationRequest(params) {
374
+ return this.request("create_external_authorization_request", params);
375
+ }
376
+ /** Poll owner consent and exchange an approval for a clone-scoped grant token.
377
+ *
378
+ * Response fields: success, error_message, status, access_token, refresh_token, token_type, grant_id, scopes, clone_ids, access_token_expires_at, expires_at, poll_interval.
379
+ * @see https://docs.mindupload.app
380
+ */
381
+ exchangeExternalAuthorization(params) {
382
+ return this.request("exchange_external_authorization", params);
383
+ }
384
+ /** Inspect the scopes, clone resources, expiry, and revocation state of a grant token.
385
+ *
386
+ * Response fields: success, error_message, grant_id, status, scopes, clone_ids, created_at, access_token_expires_at, expires_at, revoked_at.
387
+ * @see https://docs.mindupload.app
388
+ */
389
+ inspectExternalAuthorization(params) {
390
+ return this.request("inspect_external_authorization", params);
391
+ }
392
+ /** Send one idempotent text event to an owner-approved AI consciousness.
393
+ *
394
+ * Response fields: success, error_message, invocation_id, status, response_text, clone_id, clone_nickname, generated_by_ai, idempotent_replay, retry_after_seconds.
395
+ * @see https://docs.mindupload.app
396
+ */
397
+ invokeExternalClone(params) {
398
+ return this.request("invoke_external_clone", params);
399
+ }
400
+ /** Refresh a short-lived clone-invocation access token.
401
+ *
402
+ * Response fields: success, error_message, status, access_token, refresh_token, token_type, grant_id, scopes, clone_ids, access_token_expires_at, expires_at.
403
+ * @see https://docs.mindupload.app
404
+ */
405
+ refreshExternalAuthorization(params) {
406
+ return this.request("refresh_external_authorization", params);
407
+ }
358
408
  // --- Insights ---
359
409
  /** Fetch the mind-graph visualization data of an AI consciousness.
360
410
  *
@@ -471,6 +521,82 @@ var MindUpload = class extends MindUploadBase {
471
521
  updateUser(params = {}) {
472
522
  return this.request("update_user", params);
473
523
  }
524
+ /** Poll owner consent at the server-advised cadence until exchange succeeds. */
525
+ async waitForExternalAuthorization(params) {
526
+ const deadline = Date.now() + (params.timeoutMs ?? 6e5);
527
+ let pollIntervalMs = DEFAULT_AUTHORIZATION_POLL_MS;
528
+ for (; ; ) {
529
+ const result = await this.exchangeExternalAuthorization({
530
+ deviceCode: params.deviceCode
531
+ });
532
+ const status = result.status;
533
+ if (status === "exchanged") return result;
534
+ if (status === "denied" || status === "expired" || status === "revoked") {
535
+ throw new MindUploadError(
536
+ `External authorization ended with status: ${status}`,
537
+ { operation: "exchange_external_authorization", response: result }
538
+ );
539
+ }
540
+ const serverIntervalMs = Number(
541
+ result.poll_interval ?? DEFAULT_AUTHORIZATION_POLL_MS / 1e3
542
+ ) * 1e3;
543
+ if (status === "slow_down") {
544
+ pollIntervalMs = Math.max(serverIntervalMs, Math.min(
545
+ pollIntervalMs + SLOW_DOWN_INCREMENT_MS,
546
+ MAX_SLOW_DOWN_POLL_MS
547
+ ));
548
+ } else {
549
+ pollIntervalMs = Math.max(serverIntervalMs, Math.min(
550
+ pollIntervalMs * 1.5,
551
+ MAX_PENDING_POLL_MS
552
+ ));
553
+ }
554
+ const waitMs = pollIntervalMs * (1 + Math.random() * POLL_JITTER_RATIO);
555
+ if (Date.now() + waitMs > deadline) {
556
+ throw new Error("Timed out waiting for external authorization.");
557
+ }
558
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
559
+ }
560
+ }
561
+ /** Invoke a clone and wait out slow generation via idempotent retries.
562
+ *
563
+ * A clone reply is generated inside the request, so under load a call can
564
+ * exceed the client or gateway timeout before the reply is ready. Because the
565
+ * invocation is idempotent on idempotencyKey, this re-sends the SAME event
566
+ * until it resolves: a still-generating call returns status "processing" (or
567
+ * times out), and the finished result is replayed once ready. Prefer this over
568
+ * a bare invokeExternalClone when generation may be slow.
569
+ */
570
+ async waitForExternalCloneInvocation(params) {
571
+ const { timeoutMs, ...invokeParams } = params;
572
+ const deadline = Date.now() + (timeoutMs ?? 12e4);
573
+ let pollIntervalMs = DEFAULT_INVOCATION_POLL_MS;
574
+ for (; ; ) {
575
+ let result;
576
+ try {
577
+ result = await this.invokeExternalClone(invokeParams);
578
+ } catch (error) {
579
+ if (error instanceof MindUploadConnectionError) {
580
+ result = void 0;
581
+ } else if (error instanceof ApiError && INVOCATION_RETRY_STATUSES.has(error.status)) {
582
+ result = void 0;
583
+ } else {
584
+ throw error;
585
+ }
586
+ }
587
+ if (result && result.status !== EXTERNAL_INVOCATION_PROCESSING_STATUS) {
588
+ return result;
589
+ }
590
+ if (result) {
591
+ pollIntervalMs = (Number(result.retry_after_seconds) || DEFAULT_INVOCATION_POLL_MS / 1e3) * 1e3;
592
+ }
593
+ const waitMs = Math.min(pollIntervalMs, MAX_INVOCATION_POLL_MS) * (1 + Math.random() * POLL_JITTER_RATIO);
594
+ if (Date.now() + waitMs > deadline) {
595
+ throw new Error("Timed out waiting for the external clone invocation.");
596
+ }
597
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
598
+ }
599
+ }
474
600
  };
475
601
  // Annotate the CommonJS export names for ESM import in node:
476
602
  0 && (module.exports = {
package/dist/index.d.cts CHANGED
@@ -13,7 +13,7 @@ interface ClientOptions {
13
13
  /** Default locale sent with every call (per-call `preferredLanguage` overrides). */
14
14
  preferredLanguage?: string;
15
15
  timeoutMs?: number;
16
- /** Retries on 429 / 5xx / network errors, with backoff. Default 2. */
16
+ /** Retries only explicit 429 rate-limit responses, with backoff. Default 2. */
17
17
  maxRetries?: number;
18
18
  userAgent?: string;
19
19
  }
@@ -32,6 +32,14 @@ declare class MindUploadBase {
32
32
  private errorFor;
33
33
  }
34
34
 
35
+ type ExternalAuthorizationStatus = "pending" | "slow_down" | "denied" | "expired" | "revoked" | "exchanged";
36
+ interface WaitForExternalAuthorizationParams {
37
+ deviceCode: string;
38
+ timeoutMs?: number;
39
+ }
40
+ interface WaitForExternalCloneInvocationParams extends InvokeExternalCloneParams {
41
+ timeoutMs?: number;
42
+ }
35
43
  interface CreateCloneParams {
36
44
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
37
45
  preferredLanguage?: string;
@@ -120,7 +128,7 @@ interface CheckChatroomUpdatesParams {
120
128
  /** The end-user's password on first sign-in. After login/register, send the returned session token (JWT) here instead — the field accepts either, and reusing the token keeps raw passwords out of your storage. */
121
129
  password?: string;
122
130
  /** Rooms to check. Each entry must include `chatroom_id`; include `known_updated_at` from the previous response, or null/omit it on the first poll. */
123
- chatrooms?: Record<string, unknown>[];
131
+ chatrooms?: Array<Record<string, unknown>>;
124
132
  }
125
133
  interface CreateChatroomParams {
126
134
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
@@ -262,6 +270,58 @@ interface TriggerSocialParams {
262
270
  /** Chatroom id as returned by chatroom operations. */
263
271
  chatroomId?: string;
264
272
  }
273
+ interface CreateExternalAuthorizationRequestParams {
274
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
275
+ preferredLanguage?: string;
276
+ /** A stable opaque event key that makes exact retries return the same outcome. */
277
+ idempotencyKey: string;
278
+ /** Your stable opaque identifier for this app installation. */
279
+ installationId: string;
280
+ /** Your stable opaque identifier for the person authorizing this installation. */
281
+ externalSubject: string;
282
+ /** Optional user-readable name for the installation shown during consent. */
283
+ installationLabel?: string;
284
+ /** Optional user-readable external identity shown during consent. */
285
+ externalIdentityLabel?: string;
286
+ /** Capabilities the owner is being asked to delegate. */
287
+ requestedScopes: Array<"clone:invoke">;
288
+ }
289
+ interface ExchangeExternalAuthorizationParams {
290
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
291
+ preferredLanguage?: string;
292
+ /** Short-lived high-entropy secret used only to poll and exchange this request. */
293
+ deviceCode: string;
294
+ }
295
+ interface InspectExternalAuthorizationParams {
296
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
297
+ preferredLanguage?: string;
298
+ /** Opaque grant token accepted only by grant inspection and external clone invocation; store it as a secret and never expose it to users. */
299
+ accessToken: string;
300
+ }
301
+ interface InvokeExternalCloneParams {
302
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
303
+ preferredLanguage?: string;
304
+ /** Opaque grant token accepted only by grant inspection and external clone invocation; store it as a secret and never expose it to users. */
305
+ accessToken: string;
306
+ /** Your stable opaque identifier for this app installation. */
307
+ installationId: string;
308
+ /** Your stable opaque identifier for the person authorizing this installation. */
309
+ externalSubject: string;
310
+ cloneId: string;
311
+ text: string;
312
+ /** A stable opaque event key that makes exact retries return the same outcome. */
313
+ idempotencyKey: string;
314
+ }
315
+ interface RefreshExternalAuthorizationParams {
316
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
317
+ preferredLanguage?: string;
318
+ /** Opaque grant-lifetime token used only with refresh_external_authorization; store it as a secret. */
319
+ refreshToken: string;
320
+ /** Your stable opaque identifier for this app installation. */
321
+ installationId: string;
322
+ /** Your stable opaque identifier for the person authorizing this installation. */
323
+ externalSubject: string;
324
+ }
265
325
  interface GetMindClusterParams {
266
326
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
267
327
  preferredLanguage?: string;
@@ -321,7 +381,7 @@ interface CompleteMultipartUploadParams {
321
381
  /** Multipart upload session id returned by `request_multipart_upload`. */
322
382
  uploadId?: string;
323
383
  /** The successfully uploaded parts, using the `part_number` and `etag` returned by each part upload. */
324
- parts?: Record<string, unknown>[];
384
+ parts?: Array<Record<string, unknown>>;
325
385
  }
326
386
  interface ListUploadPartsParams {
327
387
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
@@ -387,7 +447,7 @@ interface SignUploadPartsBatchParams {
387
447
  /** Multipart upload session id returned by `request_multipart_upload`. */
388
448
  uploadId?: string;
389
449
  /** One-based multipart part numbers to sign in a single batch. */
390
- partNumbers?: number[];
450
+ partNumbers?: Array<number>;
391
451
  }
392
452
  interface CreateTextParams {
393
453
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
@@ -470,7 +530,7 @@ declare class MindUpload extends MindUploadBase {
470
530
  updateClone(params?: UpdateCloneParams): Promise<Result>;
471
531
  /** Check your partner API rate limits, credit caps, and current usage.
472
532
  *
473
- * 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.
533
+ * Response fields: success, error_message, per_user_rate_limit_per_min, per_user_daily_credit_cap, partner_rate_limit_per_min, external_authorization_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.
474
534
  * @see https://docs.mindupload.app
475
535
  */
476
536
  getQuota(params?: GetQuotaParams): Promise<Result>;
@@ -564,6 +624,36 @@ declare class MindUpload extends MindUploadBase {
564
624
  * @see https://docs.mindupload.app
565
625
  */
566
626
  triggerSocial(params?: TriggerSocialParams): Promise<Result>;
627
+ /** Start passwordless grant issuance for an external identity and installation.
628
+ *
629
+ * Response fields: success, error_message, device_code, user_code, verification_uri, verification_uri_complete, expires_in, poll_interval, grant_duration_seconds.
630
+ * @see https://docs.mindupload.app
631
+ */
632
+ createExternalAuthorizationRequest(params: CreateExternalAuthorizationRequestParams): Promise<Result>;
633
+ /** Poll owner consent and exchange an approval for a clone-scoped grant token.
634
+ *
635
+ * Response fields: success, error_message, status, access_token, refresh_token, token_type, grant_id, scopes, clone_ids, access_token_expires_at, expires_at, poll_interval.
636
+ * @see https://docs.mindupload.app
637
+ */
638
+ exchangeExternalAuthorization(params: ExchangeExternalAuthorizationParams): Promise<Result>;
639
+ /** Inspect the scopes, clone resources, expiry, and revocation state of a grant token.
640
+ *
641
+ * Response fields: success, error_message, grant_id, status, scopes, clone_ids, created_at, access_token_expires_at, expires_at, revoked_at.
642
+ * @see https://docs.mindupload.app
643
+ */
644
+ inspectExternalAuthorization(params: InspectExternalAuthorizationParams): Promise<Result>;
645
+ /** Send one idempotent text event to an owner-approved AI consciousness.
646
+ *
647
+ * Response fields: success, error_message, invocation_id, status, response_text, clone_id, clone_nickname, generated_by_ai, idempotent_replay, retry_after_seconds.
648
+ * @see https://docs.mindupload.app
649
+ */
650
+ invokeExternalClone(params: InvokeExternalCloneParams): Promise<Result>;
651
+ /** Refresh a short-lived clone-invocation access token.
652
+ *
653
+ * Response fields: success, error_message, status, access_token, refresh_token, token_type, grant_id, scopes, clone_ids, access_token_expires_at, expires_at.
654
+ * @see https://docs.mindupload.app
655
+ */
656
+ refreshExternalAuthorization(params: RefreshExternalAuthorizationParams): Promise<Result>;
567
657
  /** Fetch the mind-graph visualization data of an AI consciousness.
568
658
  *
569
659
  * Response fields: success, error_message, root_node_id, node, children, texts, total_texts, texts_offset, has_more_texts, is_building.
@@ -648,6 +738,18 @@ declare class MindUpload extends MindUploadBase {
648
738
  * @see https://docs.mindupload.app
649
739
  */
650
740
  updateUser(params?: UpdateUserParams): Promise<Result>;
741
+ /** Poll owner consent at the server-advised cadence until exchange succeeds. */
742
+ waitForExternalAuthorization(params: WaitForExternalAuthorizationParams): Promise<Result>;
743
+ /** Invoke a clone and wait out slow generation via idempotent retries.
744
+ *
745
+ * A clone reply is generated inside the request, so under load a call can
746
+ * exceed the client or gateway timeout before the reply is ready. Because the
747
+ * invocation is idempotent on idempotencyKey, this re-sends the SAME event
748
+ * until it resolves: a still-generating call returns status "processing" (or
749
+ * times out), and the finished result is replayed once ready. Prefer this over
750
+ * a bare invokeExternalClone when generation may be slow.
751
+ */
752
+ waitForExternalCloneInvocation(params: WaitForExternalCloneInvocationParams): Promise<Result>;
651
753
  }
652
754
 
653
755
  interface ErrorOptions {
@@ -686,6 +788,6 @@ declare class MindUploadConnectionError extends MindUploadError {
686
788
  constructor(message: string, options?: ErrorOptions);
687
789
  }
688
790
 
689
- declare const VERSION = "1.5.8";
791
+ declare const VERSION = "1.5.9";
690
792
 
691
- export { type AbortMultipartUploadParams, ApiError, type ApiErrorOptions, AuthenticationError, type CancelUploadParams, type CheckChatroomUpdatesParams, type CheckUsernameParams, type ClientOptions, type CompleteMultipartUploadParams, type CreateChatroomMembershipParams, type CreateChatroomMessageParams, type CreateChatroomParams, type CreateCloneParams, type CreateTextParams, DEFAULT_BASE_URL, type ErrorOptions, type GetChatParams, type GetChatroomMembershipParams, type GetChatroomMessagesParams, type GetChatroomsParams, type GetClonesParams, type GetMindClusterParams, type GetQuotaParams, type GetSoulmateReportParams, type GetTextsParams, type GetUserParams, type ListUploadPartsParams, type LoginParams, type LogoutParams, MindUpload, MindUploadBase, MindUploadConnectionError, MindUploadError, type RagParams, RateLimitError, type RateLimitOptions, type RegisterParams, type RequestMultipartUploadParams, type RequestUploadUrlParams, type Result, type SignUploadPartParams, type SignUploadPartsBatchParams, type TranslateChatroomMessageParams, type TriggerSocialParams, type UpdateCloneParams, type UpdateUserParams, VERSION };
793
+ export { type AbortMultipartUploadParams, ApiError, type ApiErrorOptions, AuthenticationError, type CancelUploadParams, type CheckChatroomUpdatesParams, type CheckUsernameParams, type ClientOptions, type CompleteMultipartUploadParams, type CreateChatroomMembershipParams, type CreateChatroomMessageParams, type CreateChatroomParams, type CreateCloneParams, type CreateExternalAuthorizationRequestParams, type CreateTextParams, DEFAULT_BASE_URL, type ErrorOptions, type ExchangeExternalAuthorizationParams, type ExternalAuthorizationStatus, type GetChatParams, type GetChatroomMembershipParams, type GetChatroomMessagesParams, type GetChatroomsParams, type GetClonesParams, type GetMindClusterParams, type GetQuotaParams, type GetSoulmateReportParams, type GetTextsParams, type GetUserParams, type InspectExternalAuthorizationParams, type InvokeExternalCloneParams, type ListUploadPartsParams, type LoginParams, type LogoutParams, MindUpload, MindUploadBase, MindUploadConnectionError, MindUploadError, type RagParams, RateLimitError, type RateLimitOptions, type RefreshExternalAuthorizationParams, type RegisterParams, type RequestMultipartUploadParams, type RequestUploadUrlParams, type Result, type SignUploadPartParams, type SignUploadPartsBatchParams, type TranslateChatroomMessageParams, type TriggerSocialParams, type UpdateCloneParams, type UpdateUserParams, VERSION, type WaitForExternalAuthorizationParams, type WaitForExternalCloneInvocationParams };
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ interface ClientOptions {
13
13
  /** Default locale sent with every call (per-call `preferredLanguage` overrides). */
14
14
  preferredLanguage?: string;
15
15
  timeoutMs?: number;
16
- /** Retries on 429 / 5xx / network errors, with backoff. Default 2. */
16
+ /** Retries only explicit 429 rate-limit responses, with backoff. Default 2. */
17
17
  maxRetries?: number;
18
18
  userAgent?: string;
19
19
  }
@@ -32,6 +32,14 @@ declare class MindUploadBase {
32
32
  private errorFor;
33
33
  }
34
34
 
35
+ type ExternalAuthorizationStatus = "pending" | "slow_down" | "denied" | "expired" | "revoked" | "exchanged";
36
+ interface WaitForExternalAuthorizationParams {
37
+ deviceCode: string;
38
+ timeoutMs?: number;
39
+ }
40
+ interface WaitForExternalCloneInvocationParams extends InvokeExternalCloneParams {
41
+ timeoutMs?: number;
42
+ }
35
43
  interface CreateCloneParams {
36
44
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
37
45
  preferredLanguage?: string;
@@ -120,7 +128,7 @@ interface CheckChatroomUpdatesParams {
120
128
  /** The end-user's password on first sign-in. After login/register, send the returned session token (JWT) here instead — the field accepts either, and reusing the token keeps raw passwords out of your storage. */
121
129
  password?: string;
122
130
  /** Rooms to check. Each entry must include `chatroom_id`; include `known_updated_at` from the previous response, or null/omit it on the first poll. */
123
- chatrooms?: Record<string, unknown>[];
131
+ chatrooms?: Array<Record<string, unknown>>;
124
132
  }
125
133
  interface CreateChatroomParams {
126
134
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
@@ -262,6 +270,58 @@ interface TriggerSocialParams {
262
270
  /** Chatroom id as returned by chatroom operations. */
263
271
  chatroomId?: string;
264
272
  }
273
+ interface CreateExternalAuthorizationRequestParams {
274
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
275
+ preferredLanguage?: string;
276
+ /** A stable opaque event key that makes exact retries return the same outcome. */
277
+ idempotencyKey: string;
278
+ /** Your stable opaque identifier for this app installation. */
279
+ installationId: string;
280
+ /** Your stable opaque identifier for the person authorizing this installation. */
281
+ externalSubject: string;
282
+ /** Optional user-readable name for the installation shown during consent. */
283
+ installationLabel?: string;
284
+ /** Optional user-readable external identity shown during consent. */
285
+ externalIdentityLabel?: string;
286
+ /** Capabilities the owner is being asked to delegate. */
287
+ requestedScopes: Array<"clone:invoke">;
288
+ }
289
+ interface ExchangeExternalAuthorizationParams {
290
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
291
+ preferredLanguage?: string;
292
+ /** Short-lived high-entropy secret used only to poll and exchange this request. */
293
+ deviceCode: string;
294
+ }
295
+ interface InspectExternalAuthorizationParams {
296
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
297
+ preferredLanguage?: string;
298
+ /** Opaque grant token accepted only by grant inspection and external clone invocation; store it as a secret and never expose it to users. */
299
+ accessToken: string;
300
+ }
301
+ interface InvokeExternalCloneParams {
302
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
303
+ preferredLanguage?: string;
304
+ /** Opaque grant token accepted only by grant inspection and external clone invocation; store it as a secret and never expose it to users. */
305
+ accessToken: string;
306
+ /** Your stable opaque identifier for this app installation. */
307
+ installationId: string;
308
+ /** Your stable opaque identifier for the person authorizing this installation. */
309
+ externalSubject: string;
310
+ cloneId: string;
311
+ text: string;
312
+ /** A stable opaque event key that makes exact retries return the same outcome. */
313
+ idempotencyKey: string;
314
+ }
315
+ interface RefreshExternalAuthorizationParams {
316
+ /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
317
+ preferredLanguage?: string;
318
+ /** Opaque grant-lifetime token used only with refresh_external_authorization; store it as a secret. */
319
+ refreshToken: string;
320
+ /** Your stable opaque identifier for this app installation. */
321
+ installationId: string;
322
+ /** Your stable opaque identifier for the person authorizing this installation. */
323
+ externalSubject: string;
324
+ }
265
325
  interface GetMindClusterParams {
266
326
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
267
327
  preferredLanguage?: string;
@@ -321,7 +381,7 @@ interface CompleteMultipartUploadParams {
321
381
  /** Multipart upload session id returned by `request_multipart_upload`. */
322
382
  uploadId?: string;
323
383
  /** The successfully uploaded parts, using the `part_number` and `etag` returned by each part upload. */
324
- parts?: Record<string, unknown>[];
384
+ parts?: Array<Record<string, unknown>>;
325
385
  }
326
386
  interface ListUploadPartsParams {
327
387
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
@@ -387,7 +447,7 @@ interface SignUploadPartsBatchParams {
387
447
  /** Multipart upload session id returned by `request_multipart_upload`. */
388
448
  uploadId?: string;
389
449
  /** One-based multipart part numbers to sign in a single batch. */
390
- partNumbers?: number[];
450
+ partNumbers?: Array<number>;
391
451
  }
392
452
  interface CreateTextParams {
393
453
  /** BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages. */
@@ -470,7 +530,7 @@ declare class MindUpload extends MindUploadBase {
470
530
  updateClone(params?: UpdateCloneParams): Promise<Result>;
471
531
  /** Check your partner API rate limits, credit caps, and current usage.
472
532
  *
473
- * 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.
533
+ * Response fields: success, error_message, per_user_rate_limit_per_min, per_user_daily_credit_cap, partner_rate_limit_per_min, external_authorization_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.
474
534
  * @see https://docs.mindupload.app
475
535
  */
476
536
  getQuota(params?: GetQuotaParams): Promise<Result>;
@@ -564,6 +624,36 @@ declare class MindUpload extends MindUploadBase {
564
624
  * @see https://docs.mindupload.app
565
625
  */
566
626
  triggerSocial(params?: TriggerSocialParams): Promise<Result>;
627
+ /** Start passwordless grant issuance for an external identity and installation.
628
+ *
629
+ * Response fields: success, error_message, device_code, user_code, verification_uri, verification_uri_complete, expires_in, poll_interval, grant_duration_seconds.
630
+ * @see https://docs.mindupload.app
631
+ */
632
+ createExternalAuthorizationRequest(params: CreateExternalAuthorizationRequestParams): Promise<Result>;
633
+ /** Poll owner consent and exchange an approval for a clone-scoped grant token.
634
+ *
635
+ * Response fields: success, error_message, status, access_token, refresh_token, token_type, grant_id, scopes, clone_ids, access_token_expires_at, expires_at, poll_interval.
636
+ * @see https://docs.mindupload.app
637
+ */
638
+ exchangeExternalAuthorization(params: ExchangeExternalAuthorizationParams): Promise<Result>;
639
+ /** Inspect the scopes, clone resources, expiry, and revocation state of a grant token.
640
+ *
641
+ * Response fields: success, error_message, grant_id, status, scopes, clone_ids, created_at, access_token_expires_at, expires_at, revoked_at.
642
+ * @see https://docs.mindupload.app
643
+ */
644
+ inspectExternalAuthorization(params: InspectExternalAuthorizationParams): Promise<Result>;
645
+ /** Send one idempotent text event to an owner-approved AI consciousness.
646
+ *
647
+ * Response fields: success, error_message, invocation_id, status, response_text, clone_id, clone_nickname, generated_by_ai, idempotent_replay, retry_after_seconds.
648
+ * @see https://docs.mindupload.app
649
+ */
650
+ invokeExternalClone(params: InvokeExternalCloneParams): Promise<Result>;
651
+ /** Refresh a short-lived clone-invocation access token.
652
+ *
653
+ * Response fields: success, error_message, status, access_token, refresh_token, token_type, grant_id, scopes, clone_ids, access_token_expires_at, expires_at.
654
+ * @see https://docs.mindupload.app
655
+ */
656
+ refreshExternalAuthorization(params: RefreshExternalAuthorizationParams): Promise<Result>;
567
657
  /** Fetch the mind-graph visualization data of an AI consciousness.
568
658
  *
569
659
  * Response fields: success, error_message, root_node_id, node, children, texts, total_texts, texts_offset, has_more_texts, is_building.
@@ -648,6 +738,18 @@ declare class MindUpload extends MindUploadBase {
648
738
  * @see https://docs.mindupload.app
649
739
  */
650
740
  updateUser(params?: UpdateUserParams): Promise<Result>;
741
+ /** Poll owner consent at the server-advised cadence until exchange succeeds. */
742
+ waitForExternalAuthorization(params: WaitForExternalAuthorizationParams): Promise<Result>;
743
+ /** Invoke a clone and wait out slow generation via idempotent retries.
744
+ *
745
+ * A clone reply is generated inside the request, so under load a call can
746
+ * exceed the client or gateway timeout before the reply is ready. Because the
747
+ * invocation is idempotent on idempotencyKey, this re-sends the SAME event
748
+ * until it resolves: a still-generating call returns status "processing" (or
749
+ * times out), and the finished result is replayed once ready. Prefer this over
750
+ * a bare invokeExternalClone when generation may be slow.
751
+ */
752
+ waitForExternalCloneInvocation(params: WaitForExternalCloneInvocationParams): Promise<Result>;
651
753
  }
652
754
 
653
755
  interface ErrorOptions {
@@ -686,6 +788,6 @@ declare class MindUploadConnectionError extends MindUploadError {
686
788
  constructor(message: string, options?: ErrorOptions);
687
789
  }
688
790
 
689
- declare const VERSION = "1.5.8";
791
+ declare const VERSION = "1.5.9";
690
792
 
691
- export { type AbortMultipartUploadParams, ApiError, type ApiErrorOptions, AuthenticationError, type CancelUploadParams, type CheckChatroomUpdatesParams, type CheckUsernameParams, type ClientOptions, type CompleteMultipartUploadParams, type CreateChatroomMembershipParams, type CreateChatroomMessageParams, type CreateChatroomParams, type CreateCloneParams, type CreateTextParams, DEFAULT_BASE_URL, type ErrorOptions, type GetChatParams, type GetChatroomMembershipParams, type GetChatroomMessagesParams, type GetChatroomsParams, type GetClonesParams, type GetMindClusterParams, type GetQuotaParams, type GetSoulmateReportParams, type GetTextsParams, type GetUserParams, type ListUploadPartsParams, type LoginParams, type LogoutParams, MindUpload, MindUploadBase, MindUploadConnectionError, MindUploadError, type RagParams, RateLimitError, type RateLimitOptions, type RegisterParams, type RequestMultipartUploadParams, type RequestUploadUrlParams, type Result, type SignUploadPartParams, type SignUploadPartsBatchParams, type TranslateChatroomMessageParams, type TriggerSocialParams, type UpdateCloneParams, type UpdateUserParams, VERSION };
793
+ export { type AbortMultipartUploadParams, ApiError, type ApiErrorOptions, AuthenticationError, type CancelUploadParams, type CheckChatroomUpdatesParams, type CheckUsernameParams, type ClientOptions, type CompleteMultipartUploadParams, type CreateChatroomMembershipParams, type CreateChatroomMessageParams, type CreateChatroomParams, type CreateCloneParams, type CreateExternalAuthorizationRequestParams, type CreateTextParams, DEFAULT_BASE_URL, type ErrorOptions, type ExchangeExternalAuthorizationParams, type ExternalAuthorizationStatus, type GetChatParams, type GetChatroomMembershipParams, type GetChatroomMessagesParams, type GetChatroomsParams, type GetClonesParams, type GetMindClusterParams, type GetQuotaParams, type GetSoulmateReportParams, type GetTextsParams, type GetUserParams, type InspectExternalAuthorizationParams, type InvokeExternalCloneParams, type ListUploadPartsParams, type LoginParams, type LogoutParams, MindUpload, MindUploadBase, MindUploadConnectionError, MindUploadError, type RagParams, RateLimitError, type RateLimitOptions, type RefreshExternalAuthorizationParams, type RegisterParams, type RequestMultipartUploadParams, type RequestUploadUrlParams, type Result, type SignUploadPartParams, type SignUploadPartsBatchParams, type TranslateChatroomMessageParams, type TriggerSocialParams, type UpdateCloneParams, type UpdateUserParams, VERSION, type WaitForExternalAuthorizationParams, type WaitForExternalCloneInvocationParams };
package/dist/index.js CHANGED
@@ -41,12 +41,12 @@ var MindUploadConnectionError = class extends MindUploadError {
41
41
  };
42
42
 
43
43
  // src/version.ts
44
- var VERSION = "1.5.8";
44
+ var VERSION = "1.5.9";
45
45
 
46
46
  // src/client.ts
47
47
  var DEFAULT_BASE_URL = "https://partner.mindupload.app";
48
48
  var AUTH_HEADER = "X-Partner-Key";
49
- var RETRY_STATUSES = /* @__PURE__ */ new Set([429, 503]);
49
+ var RETRY_STATUSES = /* @__PURE__ */ new Set([429]);
50
50
  function camelToSnake(key) {
51
51
  return key.replace(/[A-Z]/g, (m) => "_" + m.toLowerCase());
52
52
  }
@@ -163,6 +163,15 @@ var MindUploadBase = class {
163
163
  };
164
164
 
165
165
  // src/operations.ts
166
+ var DEFAULT_AUTHORIZATION_POLL_MS = 5e3;
167
+ var MAX_PENDING_POLL_MS = 15e3;
168
+ var MAX_SLOW_DOWN_POLL_MS = 3e4;
169
+ var SLOW_DOWN_INCREMENT_MS = 5e3;
170
+ var POLL_JITTER_RATIO = 0.2;
171
+ var DEFAULT_INVOCATION_POLL_MS = 2e3;
172
+ var MAX_INVOCATION_POLL_MS = 1e4;
173
+ var EXTERNAL_INVOCATION_PROCESSING_STATUS = "processing";
174
+ var INVOCATION_RETRY_STATUSES = /* @__PURE__ */ new Set([502, 503, 504]);
166
175
  var MindUpload = class extends MindUploadBase {
167
176
  // --- AI Consciousnesses ---
168
177
  /** Create a new AI consciousness for the user.
@@ -192,7 +201,7 @@ var MindUpload = class extends MindUploadBase {
192
201
  // --- Account ---
193
202
  /** Check your partner API rate limits, credit caps, and current usage.
194
203
  *
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.
204
+ * Response fields: success, error_message, per_user_rate_limit_per_min, per_user_daily_credit_cap, partner_rate_limit_per_min, external_authorization_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
205
  * @see https://docs.mindupload.app
197
206
  */
198
207
  getQuota(params = {}) {
@@ -321,6 +330,47 @@ var MindUpload = class extends MindUploadBase {
321
330
  triggerSocial(params = {}) {
322
331
  return this.request("trigger_social", params);
323
332
  }
333
+ // --- External Authorization ---
334
+ /** Start passwordless grant issuance for an external identity and installation.
335
+ *
336
+ * Response fields: success, error_message, device_code, user_code, verification_uri, verification_uri_complete, expires_in, poll_interval, grant_duration_seconds.
337
+ * @see https://docs.mindupload.app
338
+ */
339
+ createExternalAuthorizationRequest(params) {
340
+ return this.request("create_external_authorization_request", params);
341
+ }
342
+ /** Poll owner consent and exchange an approval for a clone-scoped grant token.
343
+ *
344
+ * Response fields: success, error_message, status, access_token, refresh_token, token_type, grant_id, scopes, clone_ids, access_token_expires_at, expires_at, poll_interval.
345
+ * @see https://docs.mindupload.app
346
+ */
347
+ exchangeExternalAuthorization(params) {
348
+ return this.request("exchange_external_authorization", params);
349
+ }
350
+ /** Inspect the scopes, clone resources, expiry, and revocation state of a grant token.
351
+ *
352
+ * Response fields: success, error_message, grant_id, status, scopes, clone_ids, created_at, access_token_expires_at, expires_at, revoked_at.
353
+ * @see https://docs.mindupload.app
354
+ */
355
+ inspectExternalAuthorization(params) {
356
+ return this.request("inspect_external_authorization", params);
357
+ }
358
+ /** Send one idempotent text event to an owner-approved AI consciousness.
359
+ *
360
+ * Response fields: success, error_message, invocation_id, status, response_text, clone_id, clone_nickname, generated_by_ai, idempotent_replay, retry_after_seconds.
361
+ * @see https://docs.mindupload.app
362
+ */
363
+ invokeExternalClone(params) {
364
+ return this.request("invoke_external_clone", params);
365
+ }
366
+ /** Refresh a short-lived clone-invocation access token.
367
+ *
368
+ * Response fields: success, error_message, status, access_token, refresh_token, token_type, grant_id, scopes, clone_ids, access_token_expires_at, expires_at.
369
+ * @see https://docs.mindupload.app
370
+ */
371
+ refreshExternalAuthorization(params) {
372
+ return this.request("refresh_external_authorization", params);
373
+ }
324
374
  // --- Insights ---
325
375
  /** Fetch the mind-graph visualization data of an AI consciousness.
326
376
  *
@@ -437,6 +487,82 @@ var MindUpload = class extends MindUploadBase {
437
487
  updateUser(params = {}) {
438
488
  return this.request("update_user", params);
439
489
  }
490
+ /** Poll owner consent at the server-advised cadence until exchange succeeds. */
491
+ async waitForExternalAuthorization(params) {
492
+ const deadline = Date.now() + (params.timeoutMs ?? 6e5);
493
+ let pollIntervalMs = DEFAULT_AUTHORIZATION_POLL_MS;
494
+ for (; ; ) {
495
+ const result = await this.exchangeExternalAuthorization({
496
+ deviceCode: params.deviceCode
497
+ });
498
+ const status = result.status;
499
+ if (status === "exchanged") return result;
500
+ if (status === "denied" || status === "expired" || status === "revoked") {
501
+ throw new MindUploadError(
502
+ `External authorization ended with status: ${status}`,
503
+ { operation: "exchange_external_authorization", response: result }
504
+ );
505
+ }
506
+ const serverIntervalMs = Number(
507
+ result.poll_interval ?? DEFAULT_AUTHORIZATION_POLL_MS / 1e3
508
+ ) * 1e3;
509
+ if (status === "slow_down") {
510
+ pollIntervalMs = Math.max(serverIntervalMs, Math.min(
511
+ pollIntervalMs + SLOW_DOWN_INCREMENT_MS,
512
+ MAX_SLOW_DOWN_POLL_MS
513
+ ));
514
+ } else {
515
+ pollIntervalMs = Math.max(serverIntervalMs, Math.min(
516
+ pollIntervalMs * 1.5,
517
+ MAX_PENDING_POLL_MS
518
+ ));
519
+ }
520
+ const waitMs = pollIntervalMs * (1 + Math.random() * POLL_JITTER_RATIO);
521
+ if (Date.now() + waitMs > deadline) {
522
+ throw new Error("Timed out waiting for external authorization.");
523
+ }
524
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
525
+ }
526
+ }
527
+ /** Invoke a clone and wait out slow generation via idempotent retries.
528
+ *
529
+ * A clone reply is generated inside the request, so under load a call can
530
+ * exceed the client or gateway timeout before the reply is ready. Because the
531
+ * invocation is idempotent on idempotencyKey, this re-sends the SAME event
532
+ * until it resolves: a still-generating call returns status "processing" (or
533
+ * times out), and the finished result is replayed once ready. Prefer this over
534
+ * a bare invokeExternalClone when generation may be slow.
535
+ */
536
+ async waitForExternalCloneInvocation(params) {
537
+ const { timeoutMs, ...invokeParams } = params;
538
+ const deadline = Date.now() + (timeoutMs ?? 12e4);
539
+ let pollIntervalMs = DEFAULT_INVOCATION_POLL_MS;
540
+ for (; ; ) {
541
+ let result;
542
+ try {
543
+ result = await this.invokeExternalClone(invokeParams);
544
+ } catch (error) {
545
+ if (error instanceof MindUploadConnectionError) {
546
+ result = void 0;
547
+ } else if (error instanceof ApiError && INVOCATION_RETRY_STATUSES.has(error.status)) {
548
+ result = void 0;
549
+ } else {
550
+ throw error;
551
+ }
552
+ }
553
+ if (result && result.status !== EXTERNAL_INVOCATION_PROCESSING_STATUS) {
554
+ return result;
555
+ }
556
+ if (result) {
557
+ pollIntervalMs = (Number(result.retry_after_seconds) || DEFAULT_INVOCATION_POLL_MS / 1e3) * 1e3;
558
+ }
559
+ const waitMs = Math.min(pollIntervalMs, MAX_INVOCATION_POLL_MS) * (1 + Math.random() * POLL_JITTER_RATIO);
560
+ if (Date.now() + waitMs > deadline) {
561
+ throw new Error("Timed out waiting for the external clone invocation.");
562
+ }
563
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
564
+ }
565
+ }
440
566
  };
441
567
  export {
442
568
  ApiError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindupload",
3
- "version": "1.5.8",
3
+ "version": "1.5.9",
4
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
5
  "keywords": [
6
6
  "mindupload",