segmind 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -1
- package/dist/index.cjs +400 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +260 -8
- package/dist/index.d.ts +260 -8
- package/dist/index.js +400 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,8 +34,8 @@ var APIConnectionError = class extends SegmindError {
|
|
|
34
34
|
var InferenceFailed = class extends SegmindError {
|
|
35
35
|
/** The status body that reported the failure. */
|
|
36
36
|
statusBody;
|
|
37
|
-
constructor(requestId, statusBody) {
|
|
38
|
-
|
|
37
|
+
constructor(requestId, statusBody, detail) {
|
|
38
|
+
detail ??= typeof statusBody.error === "string" ? statusBody.error : void 0;
|
|
39
39
|
super(detail ? `request ${requestId} failed: ${detail}` : `request ${requestId} failed`, {
|
|
40
40
|
detail,
|
|
41
41
|
requestId,
|
|
@@ -272,14 +272,15 @@ var HttpClient = class {
|
|
|
272
272
|
}, timeout);
|
|
273
273
|
const onAbort = () => controller.abort(signal.reason);
|
|
274
274
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
275
|
-
const headers = { ...this.config.headers, ...req.headers };
|
|
276
|
-
if (this.config.apiKey) headers["x-api-key"] = this.config.apiKey;
|
|
275
|
+
const headers = req.bare ? { ...req.headers } : { ...this.config.headers, ...req.headers };
|
|
276
|
+
if (this.config.apiKey && !req.bare) headers["x-api-key"] = this.config.apiKey;
|
|
277
277
|
if (req.body !== void 0) headers["content-type"] = "application/json";
|
|
278
|
+
const body = req.rawBody ?? (req.body === void 0 ? void 0 : JSON.stringify(req.body));
|
|
278
279
|
try {
|
|
279
|
-
return await this.config.fetch(req.url, {
|
|
280
|
+
return await this.config.fetch(withQuery(req.url, req.query), {
|
|
280
281
|
method: req.method,
|
|
281
282
|
headers,
|
|
282
|
-
body
|
|
283
|
+
body,
|
|
283
284
|
signal: controller.signal
|
|
284
285
|
});
|
|
285
286
|
} catch (err) {
|
|
@@ -304,6 +305,15 @@ async function readJson(response) {
|
|
|
304
305
|
});
|
|
305
306
|
}
|
|
306
307
|
}
|
|
308
|
+
function withQuery(url, query) {
|
|
309
|
+
if (!query) return url;
|
|
310
|
+
const params = new URLSearchParams();
|
|
311
|
+
for (const [key, value] of Object.entries(query)) {
|
|
312
|
+
if (value !== void 0) params.set(key, String(value));
|
|
313
|
+
}
|
|
314
|
+
const qs = params.toString();
|
|
315
|
+
return qs ? `${url}${url.includes("?") ? "&" : "?"}${qs}` : url;
|
|
316
|
+
}
|
|
307
317
|
function describe(err) {
|
|
308
318
|
if (err instanceof Error) {
|
|
309
319
|
const cause = err.cause;
|
|
@@ -312,6 +322,182 @@ function describe(err) {
|
|
|
312
322
|
return String(err);
|
|
313
323
|
}
|
|
314
324
|
|
|
325
|
+
// src/core/input.ts
|
|
326
|
+
var MIME_BY_EXTENSION = {
|
|
327
|
+
png: "image/png",
|
|
328
|
+
jpg: "image/jpeg",
|
|
329
|
+
jpeg: "image/jpeg",
|
|
330
|
+
gif: "image/gif",
|
|
331
|
+
webp: "image/webp",
|
|
332
|
+
bmp: "image/bmp",
|
|
333
|
+
svg: "image/svg+xml",
|
|
334
|
+
heic: "image/heic",
|
|
335
|
+
heif: "image/heif",
|
|
336
|
+
tif: "image/tiff",
|
|
337
|
+
tiff: "image/tiff",
|
|
338
|
+
avif: "image/avif",
|
|
339
|
+
mp4: "video/mp4",
|
|
340
|
+
mov: "video/quicktime",
|
|
341
|
+
webm: "video/webm",
|
|
342
|
+
mkv: "video/x-matroska",
|
|
343
|
+
avi: "video/x-msvideo",
|
|
344
|
+
mp3: "audio/mpeg",
|
|
345
|
+
wav: "audio/wav",
|
|
346
|
+
m4a: "audio/mp4",
|
|
347
|
+
ogg: "audio/ogg",
|
|
348
|
+
flac: "audio/flac",
|
|
349
|
+
aac: "audio/aac",
|
|
350
|
+
pdf: "application/pdf",
|
|
351
|
+
txt: "text/plain",
|
|
352
|
+
json: "application/json",
|
|
353
|
+
glb: "model/gltf-binary"
|
|
354
|
+
};
|
|
355
|
+
var EXTENSION_BY_MIME = Object.fromEntries(
|
|
356
|
+
Object.entries(MIME_BY_EXTENSION).map(([ext, mime]) => [mime, ext])
|
|
357
|
+
);
|
|
358
|
+
EXTENSION_BY_MIME["image/jpeg"] = "jpg";
|
|
359
|
+
function mimeFromName(name) {
|
|
360
|
+
const extension = name.includes(".") ? name.split(".").pop().toLowerCase() : "";
|
|
361
|
+
return MIME_BY_EXTENSION[extension];
|
|
362
|
+
}
|
|
363
|
+
async function readFileInput(input, options) {
|
|
364
|
+
let bytes;
|
|
365
|
+
let name = options.filename;
|
|
366
|
+
let mimeType = options.mimeType;
|
|
367
|
+
if (typeof input === "string") {
|
|
368
|
+
if (detectRuntime() !== "node") {
|
|
369
|
+
throw new SegmindError(`${options.caller}: file paths work in Node only; pass a Blob or bytes`);
|
|
370
|
+
}
|
|
371
|
+
const { readFile } = await import("node:fs/promises");
|
|
372
|
+
try {
|
|
373
|
+
bytes = new Uint8Array(await readFile(input));
|
|
374
|
+
} catch (err) {
|
|
375
|
+
throw new SegmindError(`${options.caller}: cannot read ${JSON.stringify(input)}: ${err.message}`, {
|
|
376
|
+
cause: err
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
name ??= input.split(/[\\/]/).pop();
|
|
380
|
+
} else if (typeof Blob !== "undefined" && input instanceof Blob) {
|
|
381
|
+
bytes = new Uint8Array(await input.arrayBuffer());
|
|
382
|
+
name ??= input.name || void 0;
|
|
383
|
+
mimeType ??= input.type || void 0;
|
|
384
|
+
} else {
|
|
385
|
+
bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
386
|
+
}
|
|
387
|
+
mimeType ??= name && mimeFromName(name) || sniff(bytes);
|
|
388
|
+
if (!name || !name.includes(".")) {
|
|
389
|
+
const extension = mimeType ? EXTENSION_BY_MIME[mimeType] : void 0;
|
|
390
|
+
if (!extension) {
|
|
391
|
+
throw new SegmindError(`${options.caller}: cannot tell the file type; pass { filename: 'name.ext' } or { mimeType }`);
|
|
392
|
+
}
|
|
393
|
+
name = `${name || "upload"}.${extension}`;
|
|
394
|
+
}
|
|
395
|
+
return { bytes, filename: name, mimeType };
|
|
396
|
+
}
|
|
397
|
+
function sniff(bytes) {
|
|
398
|
+
const at = (offset, signature) => signature.every((b, i) => bytes[offset + i] === b);
|
|
399
|
+
if (at(0, [137, 80, 78, 71])) return "image/png";
|
|
400
|
+
if (at(0, [255, 216, 255])) return "image/jpeg";
|
|
401
|
+
if (at(0, [71, 73, 70, 56])) return "image/gif";
|
|
402
|
+
if (at(0, [82, 73, 70, 70]) && at(8, [87, 69, 66, 80])) return "image/webp";
|
|
403
|
+
if (at(0, [82, 73, 70, 70]) && at(8, [87, 65, 86, 69])) return "audio/wav";
|
|
404
|
+
if (at(4, [102, 116, 121, 112])) return "video/mp4";
|
|
405
|
+
if (at(0, [73, 68, 51]) || at(0, [255, 251])) return "audio/mpeg";
|
|
406
|
+
if (at(0, [37, 80, 68, 70])) return "application/pdf";
|
|
407
|
+
return void 0;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// src/files.ts
|
|
411
|
+
var Files = class {
|
|
412
|
+
constructor(client2) {
|
|
413
|
+
this.client = client2;
|
|
414
|
+
}
|
|
415
|
+
client;
|
|
416
|
+
async upload(input, options = {}) {
|
|
417
|
+
if (Array.isArray(input)) {
|
|
418
|
+
const uploaded = [];
|
|
419
|
+
for (const file of input) uploaded.push(await this.uploadOne(file, { ...options, filename: void 0 }));
|
|
420
|
+
return uploaded;
|
|
421
|
+
}
|
|
422
|
+
return this.uploadOne(input, options);
|
|
423
|
+
}
|
|
424
|
+
async uploadOne(input, options) {
|
|
425
|
+
const file = await readFileInput(input, { ...options, caller: "files.upload" });
|
|
426
|
+
const { http } = this.client;
|
|
427
|
+
const ticket = await http.json({
|
|
428
|
+
method: "POST",
|
|
429
|
+
url: `${this.client.spotURL}/inference-request/input-presign`,
|
|
430
|
+
body: { filename: file.filename, size: file.bytes.byteLength },
|
|
431
|
+
signal: options.signal,
|
|
432
|
+
retry: true
|
|
433
|
+
});
|
|
434
|
+
if (!ticket.upload_url || !ticket.url) {
|
|
435
|
+
throw new SegmindError("files.upload: the presign response had no upload_url or url", { body: ticket });
|
|
436
|
+
}
|
|
437
|
+
const headers = { ...ticket.required_headers };
|
|
438
|
+
delete headers["Content-Length"];
|
|
439
|
+
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,
|
|
447
|
+
retry: true
|
|
448
|
+
});
|
|
449
|
+
return { url: ticket.url, filename: file.filename, size: file.bytes.byteLength };
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
// src/generations.ts
|
|
454
|
+
var Generations = class {
|
|
455
|
+
constructor(client2) {
|
|
456
|
+
this.client = client2;
|
|
457
|
+
}
|
|
458
|
+
client;
|
|
459
|
+
/** Generated outputs, newest first. */
|
|
460
|
+
async list(options = {}) {
|
|
461
|
+
return this.read("/inference-request/generations", options.signal, {
|
|
462
|
+
page: options.page ?? 1,
|
|
463
|
+
model_name: options.modelName,
|
|
464
|
+
start_date: options.startDate,
|
|
465
|
+
end_date: options.endDate,
|
|
466
|
+
user_id: options.userId
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
/** The newest generations for one model. */
|
|
470
|
+
async recent(modelName, options = {}) {
|
|
471
|
+
return this.read("/inference-request/recent-generations", options.signal, { model_name: modelName });
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Requests with their cost, inputs and outcome, failures included. A request
|
|
475
|
+
* with several outputs appears once per output, each carrying its full cost:
|
|
476
|
+
* de-duplicate on `request_id` before summing.
|
|
477
|
+
*/
|
|
478
|
+
async history(options = {}) {
|
|
479
|
+
return this.read("/inference-request/request-history", options.signal, {
|
|
480
|
+
page: options.page ?? 1,
|
|
481
|
+
per_page: options.perPage ?? 20,
|
|
482
|
+
from_date: options.fromDate,
|
|
483
|
+
to_date: options.toDate,
|
|
484
|
+
model_name: options.modelName,
|
|
485
|
+
status: options.status,
|
|
486
|
+
user_id: options.userId,
|
|
487
|
+
user_email: options.userEmail,
|
|
488
|
+
sort_by: options.sortBy,
|
|
489
|
+
sort_order: options.sortOrder
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
/** One of your own requests, of any age. A teammate's request id is not found. */
|
|
493
|
+
async get(requestId, options = {}) {
|
|
494
|
+
return this.read(`/inference-request/request-history/${encodeURIComponent(requestId)}`, options.signal);
|
|
495
|
+
}
|
|
496
|
+
read(path2, signal, query) {
|
|
497
|
+
return this.client.http.json({ method: "GET", url: `${this.client.spotURL}${path2}`, query, signal, retry: true });
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
315
501
|
// src/job.ts
|
|
316
502
|
var DEFAULT_WAIT_TIMEOUT_MS = 6e5;
|
|
317
503
|
var DEFAULT_WAIT_INTERVAL_MS = 1e3;
|
|
@@ -381,8 +567,167 @@ var Job = class {
|
|
|
381
567
|
}
|
|
382
568
|
};
|
|
383
569
|
|
|
570
|
+
// src/pixelflows.ts
|
|
571
|
+
var DONE = /* @__PURE__ */ new Set(["COMPLETED", "SUCCESS", "SUCCEEDED"]);
|
|
572
|
+
var FAILED = /* @__PURE__ */ new Set(["FAILED", "ERROR"]);
|
|
573
|
+
var DEFAULT_TIMEOUT_MS = 6e5;
|
|
574
|
+
var DEFAULT_INTERVAL_MS = 2e3;
|
|
575
|
+
var PixelFlows = class {
|
|
576
|
+
constructor(client2) {
|
|
577
|
+
this.client = client2;
|
|
578
|
+
}
|
|
579
|
+
client;
|
|
580
|
+
/** Runs a workflow and waits for its outputs. */
|
|
581
|
+
async run(slug, inputs = {}, options = {}) {
|
|
582
|
+
const job = await this.submit(slug, inputs, options);
|
|
583
|
+
return job.wait(options);
|
|
584
|
+
}
|
|
585
|
+
/** Starts a workflow and returns a job to wait on. Never retried: a run bills. */
|
|
586
|
+
async submit(slug, inputs = {}, options = {}) {
|
|
587
|
+
const clean = slug.trim().replace(/^\/+/, "");
|
|
588
|
+
if (!clean) throw new SegmindError("pixelflows: a workflow slug is required");
|
|
589
|
+
const route = options.engine === "v1" ? "/workflows/" : "/workflows/v2/";
|
|
590
|
+
const body = await this.client.http.json({
|
|
591
|
+
method: "POST",
|
|
592
|
+
url: `${this.client.baseURL}${route}${clean}`,
|
|
593
|
+
body: inputs,
|
|
594
|
+
signal: options.signal
|
|
595
|
+
});
|
|
596
|
+
const requestId = body.request_id;
|
|
597
|
+
if (typeof requestId !== "string" || !requestId) {
|
|
598
|
+
throw new SegmindError("pixelflows: the submit response had no request_id", { body });
|
|
599
|
+
}
|
|
600
|
+
return new PixelflowJob(this, requestId);
|
|
601
|
+
}
|
|
602
|
+
/** A run's current state, without waiting. */
|
|
603
|
+
async getStatus(requestId, options = {}) {
|
|
604
|
+
const raw = await this.client.http.json({
|
|
605
|
+
method: "GET",
|
|
606
|
+
url: `${this.client.baseURL}/workflows/request/${encodeURIComponent(requestId)}`,
|
|
607
|
+
signal: options.signal,
|
|
608
|
+
retry: true
|
|
609
|
+
});
|
|
610
|
+
return toStatus(raw);
|
|
611
|
+
}
|
|
612
|
+
/** Waits for a run started earlier, by its request id. */
|
|
613
|
+
async poll(requestId, options = {}) {
|
|
614
|
+
return new PixelflowJob(this, requestId).wait(options);
|
|
615
|
+
}
|
|
616
|
+
};
|
|
617
|
+
var PixelflowJob = class {
|
|
618
|
+
constructor(pixelflows2, requestId) {
|
|
619
|
+
this.pixelflows = pixelflows2;
|
|
620
|
+
this.requestId = requestId;
|
|
621
|
+
}
|
|
622
|
+
pixelflows;
|
|
623
|
+
requestId;
|
|
624
|
+
status(options = {}) {
|
|
625
|
+
return this.pixelflows.getStatus(this.requestId, options);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Polls until the run finishes. Throws `InferenceFailed` (its `detail` names
|
|
629
|
+
* the failing node) or `InferenceTimeout`; the run may still finish after a
|
|
630
|
+
* timeout, so `wait()` can be called again.
|
|
631
|
+
*/
|
|
632
|
+
async wait(options = {}) {
|
|
633
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
634
|
+
const interval = options.interval ?? DEFAULT_INTERVAL_MS;
|
|
635
|
+
const started = Date.now();
|
|
636
|
+
for (; ; ) {
|
|
637
|
+
const state = await this.status({ signal: options.signal });
|
|
638
|
+
if (DONE.has(state.status)) return state;
|
|
639
|
+
if (FAILED.has(state.status)) throw new InferenceFailed(this.requestId, state.raw, failureDetail(state.raw));
|
|
640
|
+
const elapsed = Date.now() - started;
|
|
641
|
+
if (elapsed + interval > timeout) throw new InferenceTimeout(this.requestId, elapsed);
|
|
642
|
+
await sleep(interval, options.signal);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
function toStatus(body) {
|
|
647
|
+
const raw = { ...body };
|
|
648
|
+
if (typeof raw.output === "string") {
|
|
649
|
+
try {
|
|
650
|
+
raw.output = JSON.parse(raw.output);
|
|
651
|
+
} catch {
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
const status = String(raw.status ?? "UNKNOWN").toUpperCase();
|
|
655
|
+
return { status, outputs: DONE.has(status) ? flattenOutputs(raw.output) : {}, raw };
|
|
656
|
+
}
|
|
657
|
+
function flattenOutputs(output) {
|
|
658
|
+
const outputs = {};
|
|
659
|
+
if (Array.isArray(output)) {
|
|
660
|
+
for (const item of output) {
|
|
661
|
+
if (item && typeof item === "object" && typeof item.keyname === "string") {
|
|
662
|
+
const { keyname, value } = item;
|
|
663
|
+
outputs[keyname] = unwrap(value);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
} else if (output && typeof output === "object") {
|
|
667
|
+
for (const [key, value] of Object.entries(output)) outputs[key] = unwrap(value);
|
|
668
|
+
}
|
|
669
|
+
return outputs;
|
|
670
|
+
}
|
|
671
|
+
function unwrap(value) {
|
|
672
|
+
if (value && typeof value === "object" && "data" in value) return value.data;
|
|
673
|
+
return value;
|
|
674
|
+
}
|
|
675
|
+
function failureDetail(body) {
|
|
676
|
+
const error = body.error_message ?? body.error;
|
|
677
|
+
if (typeof error === "string") return error;
|
|
678
|
+
if (error && typeof error === "object") {
|
|
679
|
+
const e = error;
|
|
680
|
+
const text = e.details ?? e.error_message ?? e.error;
|
|
681
|
+
if (typeof text === "string") return text;
|
|
682
|
+
}
|
|
683
|
+
return void 0;
|
|
684
|
+
}
|
|
685
|
+
|
|
384
686
|
// src/version.ts
|
|
385
|
-
var VERSION = "0.
|
|
687
|
+
var VERSION = "0.2.0";
|
|
688
|
+
|
|
689
|
+
// src/webhooks.ts
|
|
690
|
+
var Webhooks = class {
|
|
691
|
+
constructor(client2) {
|
|
692
|
+
this.client = client2;
|
|
693
|
+
}
|
|
694
|
+
client;
|
|
695
|
+
/** Every registration; `[]` when you have none. */
|
|
696
|
+
async get(options = {}) {
|
|
697
|
+
return this.call("GET", "/get", { signal: options.signal, retry: true });
|
|
698
|
+
}
|
|
699
|
+
/** Registers an endpoint for the given event types. */
|
|
700
|
+
async add(webhookUrl, eventTypes, options = {}) {
|
|
701
|
+
return this.call("POST", "/add", {
|
|
702
|
+
body: { webhook_url: webhookUrl, event: { types: requireTypes(eventTypes) } },
|
|
703
|
+
signal: options.signal
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
/** Changes a registration's URL and event types. */
|
|
707
|
+
async update(webhookId, webhookUrl, eventTypes, options = {}) {
|
|
708
|
+
return this.call("POST", "/update", {
|
|
709
|
+
body: { webhook_id: webhookId, webhook_url: webhookUrl, event: { types: requireTypes(eventTypes) } },
|
|
710
|
+
signal: options.signal
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
/** Deactivates a registration. */
|
|
714
|
+
async delete(webhookId, options = {}) {
|
|
715
|
+
return this.call("GET", "/inactive", { query: { webhook_id: webhookId }, signal: options.signal, retry: true });
|
|
716
|
+
}
|
|
717
|
+
/** Delivery history for one registration. */
|
|
718
|
+
async logs(webhookId, options = {}) {
|
|
719
|
+
return this.call("GET", "/dispatch-logs", { query: { webhook_id: webhookId }, signal: options.signal, retry: true });
|
|
720
|
+
}
|
|
721
|
+
call(method, path2, req) {
|
|
722
|
+
return this.client.http.json({ method, url: `${this.client.spotURL}/webhook${path2}`, ...req });
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
function requireTypes(eventTypes) {
|
|
726
|
+
if (!Array.isArray(eventTypes) || eventTypes.length === 0) {
|
|
727
|
+
throw new SegmindError('webhooks: pass at least one event type, e.g. ["PIXELFLOW_API_RUN"]');
|
|
728
|
+
}
|
|
729
|
+
return eventTypes;
|
|
730
|
+
}
|
|
386
731
|
|
|
387
732
|
// src/client.ts
|
|
388
733
|
var DEFAULT_BASE_URL = "https://api.segmind.com";
|
|
@@ -394,6 +739,14 @@ var Segmind = class {
|
|
|
394
739
|
consoleURL;
|
|
395
740
|
models;
|
|
396
741
|
accounts;
|
|
742
|
+
/** Upload files to pass as model inputs. */
|
|
743
|
+
files;
|
|
744
|
+
/** Your generations and request history. */
|
|
745
|
+
generations;
|
|
746
|
+
/** Your webhook registrations. */
|
|
747
|
+
webhooks;
|
|
748
|
+
/** Run published PixelFlow workflows. */
|
|
749
|
+
pixelflows;
|
|
397
750
|
/** @internal */
|
|
398
751
|
http;
|
|
399
752
|
constructor(options = {}) {
|
|
@@ -424,6 +777,10 @@ var Segmind = class {
|
|
|
424
777
|
});
|
|
425
778
|
this.models = new Models(this);
|
|
426
779
|
this.accounts = new Accounts(this);
|
|
780
|
+
this.files = new Files(this);
|
|
781
|
+
this.generations = new Generations(this);
|
|
782
|
+
this.webhooks = new Webhooks(this);
|
|
783
|
+
this.pixelflows = new PixelFlows(this);
|
|
427
784
|
}
|
|
428
785
|
/**
|
|
429
786
|
* Runs a model and returns its result: submits to the v2 queue, then polls
|
|
@@ -569,62 +926,12 @@ function trimBase(url) {
|
|
|
569
926
|
}
|
|
570
927
|
|
|
571
928
|
// src/image-url.ts
|
|
572
|
-
var MIME_BY_EXTENSION = {
|
|
573
|
-
png: "image/png",
|
|
574
|
-
jpg: "image/jpeg",
|
|
575
|
-
jpeg: "image/jpeg",
|
|
576
|
-
gif: "image/gif",
|
|
577
|
-
webp: "image/webp",
|
|
578
|
-
bmp: "image/bmp",
|
|
579
|
-
svg: "image/svg+xml",
|
|
580
|
-
heic: "image/heic",
|
|
581
|
-
heif: "image/heif",
|
|
582
|
-
tif: "image/tiff",
|
|
583
|
-
tiff: "image/tiff",
|
|
584
|
-
avif: "image/avif"
|
|
585
|
-
};
|
|
586
929
|
async function imageUrl(input, options = {}) {
|
|
587
|
-
|
|
588
|
-
}
|
|
589
|
-
async function toDataUri(input, mimeType) {
|
|
590
|
-
if (typeof input === "string") {
|
|
591
|
-
if (/^(https?:|data:)/i.test(input)) return input;
|
|
592
|
-
if (detectRuntime() !== "node") {
|
|
593
|
-
throw new SegmindError(`imageUrl: ${JSON.stringify(input)} is not an http(s) or data: URL (file paths work in Node only)`);
|
|
594
|
-
}
|
|
595
|
-
return fileToDataUri(input, mimeType);
|
|
930
|
+
if (typeof input === "string" && /^(https?:|data:)/i.test(input)) {
|
|
931
|
+
return { type: "image_url", image_url: { url: input } };
|
|
596
932
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
return dataUri(bytes2, mimeType ?? (input.type || sniff(bytes2)));
|
|
600
|
-
}
|
|
601
|
-
const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
602
|
-
return dataUri(bytes, mimeType ?? sniff(bytes));
|
|
603
|
-
}
|
|
604
|
-
async function fileToDataUri(path2, mimeType) {
|
|
605
|
-
const { readFile } = await import("node:fs/promises");
|
|
606
|
-
let bytes;
|
|
607
|
-
try {
|
|
608
|
-
bytes = new Uint8Array(await readFile(path2));
|
|
609
|
-
} catch (err) {
|
|
610
|
-
throw new SegmindError(`imageUrl: cannot read ${JSON.stringify(path2)}: ${err.message}`, { cause: err });
|
|
611
|
-
}
|
|
612
|
-
const extension = path2.split(".").pop()?.toLowerCase() ?? "";
|
|
613
|
-
return dataUri(bytes, mimeType ?? MIME_BY_EXTENSION[extension] ?? sniff(bytes));
|
|
614
|
-
}
|
|
615
|
-
function dataUri(bytes, mimeType) {
|
|
616
|
-
if (!mimeType) {
|
|
617
|
-
throw new SegmindError("imageUrl: cannot tell the image type; pass { mimeType }");
|
|
618
|
-
}
|
|
619
|
-
return `data:${mimeType};base64,${toBase64(bytes)}`;
|
|
620
|
-
}
|
|
621
|
-
function sniff(bytes) {
|
|
622
|
-
const at = (offset, signature) => signature.every((b, i) => bytes[offset + i] === b);
|
|
623
|
-
if (at(0, [137, 80, 78, 71])) return "image/png";
|
|
624
|
-
if (at(0, [255, 216, 255])) return "image/jpeg";
|
|
625
|
-
if (at(0, [71, 73, 70, 56])) return "image/gif";
|
|
626
|
-
if (at(0, [82, 73, 70, 70]) && at(8, [87, 69, 66, 80])) return "image/webp";
|
|
627
|
-
return void 0;
|
|
933
|
+
const file = await readFileInput(input, { mimeType: options.mimeType, caller: "imageUrl" });
|
|
934
|
+
return { type: "image_url", image_url: { url: `data:${file.mimeType};base64,${toBase64(file.bytes)}` } };
|
|
628
935
|
}
|
|
629
936
|
|
|
630
937
|
// src/index.ts
|
|
@@ -645,6 +952,28 @@ var models = {
|
|
|
645
952
|
var accounts = {
|
|
646
953
|
current: (options) => client().accounts.current(options)
|
|
647
954
|
};
|
|
955
|
+
var files = {
|
|
956
|
+
upload: ((input, options) => client().files.upload(input, options))
|
|
957
|
+
};
|
|
958
|
+
var generations = {
|
|
959
|
+
list: (options) => client().generations.list(options),
|
|
960
|
+
recent: (modelName, options) => client().generations.recent(modelName, options),
|
|
961
|
+
history: (options) => client().generations.history(options),
|
|
962
|
+
get: (requestId, options) => client().generations.get(requestId, options)
|
|
963
|
+
};
|
|
964
|
+
var webhooks = {
|
|
965
|
+
get: (options) => client().webhooks.get(options),
|
|
966
|
+
add: (webhookUrl, eventTypes, options) => client().webhooks.add(webhookUrl, eventTypes, options),
|
|
967
|
+
update: (webhookId, webhookUrl, eventTypes, options) => client().webhooks.update(webhookId, webhookUrl, eventTypes, options),
|
|
968
|
+
delete: (webhookId, options) => client().webhooks.delete(webhookId, options),
|
|
969
|
+
logs: (webhookId, options) => client().webhooks.logs(webhookId, options)
|
|
970
|
+
};
|
|
971
|
+
var pixelflows = {
|
|
972
|
+
run: (slug, inputs, options) => client().pixelflows.run(slug, inputs, options),
|
|
973
|
+
submit: (slug, inputs, options) => client().pixelflows.submit(slug, inputs, options),
|
|
974
|
+
getStatus: (requestId, options) => client().pixelflows.getStatus(requestId, options),
|
|
975
|
+
poll: (requestId, options) => client().pixelflows.poll(requestId, options)
|
|
976
|
+
};
|
|
648
977
|
export {
|
|
649
978
|
APIConnectionError,
|
|
650
979
|
Accounts,
|
|
@@ -654,21 +983,30 @@ export {
|
|
|
654
983
|
DEFAULT_SPOT_URL,
|
|
655
984
|
DEFAULT_WAIT_INTERVAL_MS,
|
|
656
985
|
DEFAULT_WAIT_TIMEOUT_MS,
|
|
986
|
+
Files,
|
|
987
|
+
Generations,
|
|
657
988
|
InferenceFailed,
|
|
658
989
|
InferenceTimeout,
|
|
659
990
|
Job,
|
|
660
991
|
Models,
|
|
992
|
+
PixelFlows,
|
|
993
|
+
PixelflowJob,
|
|
661
994
|
Segmind,
|
|
662
995
|
SegmindError,
|
|
663
996
|
VERSION,
|
|
997
|
+
Webhooks,
|
|
664
998
|
accounts,
|
|
665
999
|
chat,
|
|
666
1000
|
chatSync,
|
|
1001
|
+
files,
|
|
1002
|
+
generations,
|
|
667
1003
|
imageUrl,
|
|
668
1004
|
models,
|
|
1005
|
+
pixelflows,
|
|
669
1006
|
run,
|
|
670
1007
|
runSync,
|
|
671
1008
|
submit,
|
|
672
|
-
submitChat
|
|
1009
|
+
submitChat,
|
|
1010
|
+
webhooks
|
|
673
1011
|
};
|
|
674
1012
|
//# sourceMappingURL=index.js.map
|