segmind 0.2.2 → 0.2.3

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.d.cts CHANGED
@@ -147,6 +147,12 @@ interface UploadOptions {
147
147
  filename?: string;
148
148
  /** The file's type, when neither the name nor the bytes tell. */
149
149
  mimeType?: string;
150
+ /**
151
+ * Keep the file in your Segmind asset library and return a URL that does not
152
+ * expire, as the Python SDK's upload does. By default the file is a temporary
153
+ * model input, kept for at least two days.
154
+ */
155
+ persist?: boolean;
150
156
  signal?: AbortSignal;
151
157
  }
152
158
  interface UploadedFile {
@@ -154,11 +160,13 @@ interface UploadedFile {
154
160
  url: string;
155
161
  filename: string;
156
162
  size: number;
163
+ /** True when the file is in your asset library and the URL does not expire. */
164
+ persistent: boolean;
157
165
  }
158
166
  /**
159
167
  * Uploads files to pass as model inputs. Each file goes straight to storage on
160
168
  * a presigned URL, so large videos never travel as base64 JSON. The URLs are
161
- * public and temporary: the files are kept for at least two days.
169
+ * public. They are temporary unless you pass `persist: true`.
162
170
  */
163
171
  declare class Files {
164
172
  private readonly client;
@@ -168,6 +176,12 @@ declare class Files {
168
176
  /** Uploads several files, in order. */
169
177
  upload(files: FileInput[], options?: Omit<UploadOptions, 'filename'>): Promise<UploadedFile[]>;
170
178
  private uploadOne;
179
+ /** A temporary model input on the inference API's input bucket. */
180
+ private stage;
181
+ /** A file in the caller's asset library: presign, PUT, then confirm to register it. */
182
+ private persist;
183
+ /** A PUT to the same key is idempotent, so it retries. `bare` keeps the API key off the storage host. */
184
+ private put;
171
185
  }
172
186
 
173
187
  /** One page of a paginated list. */
@@ -418,6 +432,8 @@ interface ClientOptions {
418
432
  spotURL?: string;
419
433
  /** The account API. Default https://cloud.segmind.com/api. */
420
434
  consoleURL?: string;
435
+ /** The asset library API, for persistent uploads. Default https://platform-api.segmind.com. */
436
+ assetsURL?: string;
421
437
  /** Milliseconds per HTTP request. Default 600 000. */
422
438
  timeout?: number;
423
439
  /** Retries for requests that cannot bill twice. Default 2. */
@@ -445,6 +461,7 @@ declare class Segmind {
445
461
  readonly baseURL: string;
446
462
  readonly spotURL: string;
447
463
  readonly consoleURL: string;
464
+ readonly assetsURL: string;
448
465
  readonly models: Models;
449
466
  readonly accounts: Accounts;
450
467
  /** Upload files to pass as model inputs. */
@@ -581,7 +598,7 @@ declare class InferenceTimeout extends SegmindError {
581
598
  constructor(requestId: string, elapsedMs: number);
582
599
  }
583
600
 
584
- declare const VERSION = "0.2.2";
601
+ declare const VERSION = "0.2.3";
585
602
 
586
603
  /** `new Segmind().run(...)` with the key from `SEGMIND_API_KEY`. */
587
604
  declare const run: (slug: string, params?: Params, options?: RunOptions) => Promise<RunResult>;
package/dist/index.d.ts CHANGED
@@ -147,6 +147,12 @@ interface UploadOptions {
147
147
  filename?: string;
148
148
  /** The file's type, when neither the name nor the bytes tell. */
149
149
  mimeType?: string;
150
+ /**
151
+ * Keep the file in your Segmind asset library and return a URL that does not
152
+ * expire, as the Python SDK's upload does. By default the file is a temporary
153
+ * model input, kept for at least two days.
154
+ */
155
+ persist?: boolean;
150
156
  signal?: AbortSignal;
151
157
  }
152
158
  interface UploadedFile {
@@ -154,11 +160,13 @@ interface UploadedFile {
154
160
  url: string;
155
161
  filename: string;
156
162
  size: number;
163
+ /** True when the file is in your asset library and the URL does not expire. */
164
+ persistent: boolean;
157
165
  }
158
166
  /**
159
167
  * Uploads files to pass as model inputs. Each file goes straight to storage on
160
168
  * a presigned URL, so large videos never travel as base64 JSON. The URLs are
161
- * public and temporary: the files are kept for at least two days.
169
+ * public. They are temporary unless you pass `persist: true`.
162
170
  */
163
171
  declare class Files {
164
172
  private readonly client;
@@ -168,6 +176,12 @@ declare class Files {
168
176
  /** Uploads several files, in order. */
169
177
  upload(files: FileInput[], options?: Omit<UploadOptions, 'filename'>): Promise<UploadedFile[]>;
170
178
  private uploadOne;
179
+ /** A temporary model input on the inference API's input bucket. */
180
+ private stage;
181
+ /** A file in the caller's asset library: presign, PUT, then confirm to register it. */
182
+ private persist;
183
+ /** A PUT to the same key is idempotent, so it retries. `bare` keeps the API key off the storage host. */
184
+ private put;
171
185
  }
172
186
 
173
187
  /** One page of a paginated list. */
@@ -418,6 +432,8 @@ interface ClientOptions {
418
432
  spotURL?: string;
419
433
  /** The account API. Default https://cloud.segmind.com/api. */
420
434
  consoleURL?: string;
435
+ /** The asset library API, for persistent uploads. Default https://platform-api.segmind.com. */
436
+ assetsURL?: string;
421
437
  /** Milliseconds per HTTP request. Default 600 000. */
422
438
  timeout?: number;
423
439
  /** Retries for requests that cannot bill twice. Default 2. */
@@ -445,6 +461,7 @@ declare class Segmind {
445
461
  readonly baseURL: string;
446
462
  readonly spotURL: string;
447
463
  readonly consoleURL: string;
464
+ readonly assetsURL: string;
448
465
  readonly models: Models;
449
466
  readonly accounts: Accounts;
450
467
  /** Upload files to pass as model inputs. */
@@ -581,7 +598,7 @@ declare class InferenceTimeout extends SegmindError {
581
598
  constructor(requestId: string, elapsedMs: number);
582
599
  }
583
600
 
584
- declare const VERSION = "0.2.2";
601
+ declare const VERSION = "0.2.3";
585
602
 
586
603
  /** `new Segmind().run(...)` with the key from `SEGMIND_API_KEY`. */
587
604
  declare const run: (slug: string, params?: Params, options?: RunOptions) => Promise<RunResult>;
package/dist/index.js CHANGED
@@ -423,12 +423,16 @@ var Files = class {
423
423
  }
424
424
  async uploadOne(input, options) {
425
425
  const file = await readFileInput(input, { ...options, caller: "files.upload" });
426
- const { http } = this.client;
427
- const ticket = await http.json({
426
+ const url = options.persist ? await this.persist(file, options.signal) : await this.stage(file, options.signal);
427
+ return { url, filename: file.filename, size: file.bytes.byteLength, persistent: options.persist === true };
428
+ }
429
+ /** A temporary model input on the inference API's input bucket. */
430
+ async stage(file, signal) {
431
+ const ticket = await this.client.http.json({
428
432
  method: "POST",
429
433
  url: `${this.client.spotURL}/inference-request/input-presign`,
430
434
  body: { filename: file.filename, size: file.bytes.byteLength },
431
- signal: options.signal,
435
+ signal,
432
436
  retry: true
433
437
  });
434
438
  if (!ticket.upload_url || !ticket.url) {
@@ -437,16 +441,41 @@ var Files = class {
437
441
  const headers = { ...ticket.required_headers };
438
442
  delete headers["Content-Length"];
439
443
  delete headers["content-length"];
440
- await http.request({
441
- method: "PUT",
442
- url: ticket.upload_url,
443
- rawBody: file.bytes,
444
- headers,
445
- bare: true,
446
- signal: options.signal,
444
+ await this.put(ticket.upload_url, file, headers, signal);
445
+ return ticket.url;
446
+ }
447
+ /** A file in the caller's asset library: presign, PUT, then confirm to register it. */
448
+ async persist(file, signal) {
449
+ const contentType = file.mimeType;
450
+ if (!contentType) {
451
+ throw new SegmindError(`files.upload: cannot tell the type of ${file.filename}; pass { mimeType } to persist it`);
452
+ }
453
+ const { http, assetsURL } = this.client;
454
+ const ticket = await http.json({
455
+ method: "POST",
456
+ url: `${assetsURL}/upload-asset/presign`,
457
+ body: { filename: file.filename, contentType, size: file.bytes.byteLength },
458
+ signal,
447
459
  retry: true
448
460
  });
449
- return { url: ticket.url, filename: file.filename, size: file.bytes.byteLength };
461
+ if (!ticket.presignedUrl || !ticket.s3Key || !ticket.publicUrl) {
462
+ throw new SegmindError("files.upload: the asset presign response had no presignedUrl, s3Key or publicUrl", {
463
+ body: ticket
464
+ });
465
+ }
466
+ await this.put(ticket.presignedUrl, file, { "Content-Type": contentType }, signal);
467
+ const confirmed = await http.json({
468
+ method: "POST",
469
+ url: `${assetsURL}/upload-asset/confirm`,
470
+ body: { s3Key: ticket.s3Key, publicUrl: ticket.publicUrl, contentType, filename: file.filename },
471
+ signal,
472
+ retry: true
473
+ });
474
+ return confirmed.asset?.url ?? ticket.publicUrl;
475
+ }
476
+ /** A PUT to the same key is idempotent, so it retries. `bare` keeps the API key off the storage host. */
477
+ async put(url, file, headers, signal) {
478
+ await this.client.http.request({ method: "PUT", url, rawBody: file.bytes, headers, bare: true, signal, retry: true });
450
479
  }
451
480
  };
452
481
 
@@ -684,7 +713,7 @@ function failureDetail(body) {
684
713
  }
685
714
 
686
715
  // src/version.ts
687
- var VERSION = "0.2.2";
716
+ var VERSION = "0.2.3";
688
717
 
689
718
  // src/webhooks.ts
690
719
  var Webhooks = class {
@@ -733,10 +762,12 @@ function requireTypes(eventTypes) {
733
762
  var DEFAULT_BASE_URL = "https://api.segmind.com";
734
763
  var DEFAULT_SPOT_URL = "https://api.spotprod.segmind.com";
735
764
  var DEFAULT_CONSOLE_URL = "https://cloud.segmind.com/api";
765
+ var DEFAULT_ASSETS_URL = "https://platform-api.segmind.com";
736
766
  var Segmind = class {
737
767
  baseURL;
738
768
  spotURL;
739
769
  consoleURL;
770
+ assetsURL;
740
771
  models;
741
772
  accounts;
742
773
  /** Upload files to pass as model inputs. */
@@ -765,6 +796,7 @@ var Segmind = class {
765
796
  this.baseURL = trimBase(options.baseURL ?? readEnv("SEGMIND_BASE_URL") ?? DEFAULT_BASE_URL);
766
797
  this.spotURL = trimSlash(options.spotURL ?? DEFAULT_SPOT_URL);
767
798
  this.consoleURL = trimSlash(options.consoleURL ?? DEFAULT_CONSOLE_URL);
799
+ this.assetsURL = trimSlash(options.assetsURL ?? DEFAULT_ASSETS_URL);
768
800
  const headers = { "X-Initiator": "SDK-JS", ...options.defaultHeaders };
769
801
  const node = nodeVersion();
770
802
  if (runtime === "node" && node) headers["User-Agent"] = `segmind-js/${VERSION} node/${node}`;