@nodaro/sdk 2.4.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +192 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +479 -1
- package/dist/index.d.ts +479 -1
- package/dist/index.js +190 -48
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -146,6 +146,20 @@ var JobAbortedError = class extends NodaroError {
|
|
|
146
146
|
}
|
|
147
147
|
jobId;
|
|
148
148
|
};
|
|
149
|
+
var StudioPreviewUnavailable = class extends NodaroError {
|
|
150
|
+
constructor(message = "This deployment does not preview operation batches; nothing was sent") {
|
|
151
|
+
super(message, "studio_preview_unavailable", 0);
|
|
152
|
+
this.name = "StudioPreviewUnavailable";
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
var StudioPreviewAppliedError = class extends NodaroError {
|
|
156
|
+
constructor(applied, message = applied ? "Asked for a preview and this deployment APPLIED the batch; the change is written \u2014 see `applied`" : "Asked for a preview and this deployment answered with neither one nor a body to read; the batch may have been applied \u2014 re-read the production before deciding anything") {
|
|
157
|
+
super(message, "studio_preview_applied", 0);
|
|
158
|
+
this.applied = applied;
|
|
159
|
+
this.name = "StudioPreviewAppliedError";
|
|
160
|
+
}
|
|
161
|
+
applied;
|
|
162
|
+
};
|
|
149
163
|
var JobHeldError = class extends NodaroError {
|
|
150
164
|
constructor(message, jobId) {
|
|
151
165
|
super(message, "job_held", 0);
|
|
@@ -2037,6 +2051,47 @@ var LlmResource = class {
|
|
|
2037
2051
|
}
|
|
2038
2052
|
};
|
|
2039
2053
|
|
|
2054
|
+
// src/sse.ts
|
|
2055
|
+
async function* readSseStream(res, opts = {}) {
|
|
2056
|
+
if (!res.ok) {
|
|
2057
|
+
let errBody = {};
|
|
2058
|
+
try {
|
|
2059
|
+
errBody = await res.json();
|
|
2060
|
+
} catch {
|
|
2061
|
+
}
|
|
2062
|
+
throwFromResponse(res.status, errBody);
|
|
2063
|
+
}
|
|
2064
|
+
if (!res.body) {
|
|
2065
|
+
throw new NodaroError(`${opts.label ?? "event stream"} has no response body`, "empty_stream", res.status);
|
|
2066
|
+
}
|
|
2067
|
+
const reader = res.body.getReader();
|
|
2068
|
+
const decoder = new TextDecoder();
|
|
2069
|
+
let buffer = "";
|
|
2070
|
+
try {
|
|
2071
|
+
for (; ; ) {
|
|
2072
|
+
const { done, value } = await reader.read();
|
|
2073
|
+
if (done) break;
|
|
2074
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2075
|
+
let sep;
|
|
2076
|
+
while ((sep = buffer.indexOf("\n\n")) >= 0) {
|
|
2077
|
+
const frame = buffer.slice(0, sep);
|
|
2078
|
+
buffer = buffer.slice(sep + 2);
|
|
2079
|
+
for (const line of frame.split("\n")) {
|
|
2080
|
+
if (!line.startsWith("data:")) continue;
|
|
2081
|
+
try {
|
|
2082
|
+
yield JSON.parse(line.slice(5).trim());
|
|
2083
|
+
} catch {
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
} finally {
|
|
2089
|
+
reader.releaseLock();
|
|
2090
|
+
await res.body.cancel().catch(() => {
|
|
2091
|
+
});
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2040
2095
|
// src/resources/media.ts
|
|
2041
2096
|
var MediaResource = class {
|
|
2042
2097
|
constructor(client) {
|
|
@@ -2073,43 +2128,7 @@ var MediaResource = class {
|
|
|
2073
2128
|
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
|
2074
2129
|
signal: opts.signal
|
|
2075
2130
|
});
|
|
2076
|
-
|
|
2077
|
-
let errBody = {};
|
|
2078
|
-
try {
|
|
2079
|
-
errBody = await res.json();
|
|
2080
|
-
} catch {
|
|
2081
|
-
}
|
|
2082
|
-
throwFromResponse(res.status, errBody);
|
|
2083
|
-
}
|
|
2084
|
-
if (!res.body) {
|
|
2085
|
-
throw new NodaroError("progress stream has no response body", "empty_stream", res.status);
|
|
2086
|
-
}
|
|
2087
|
-
const reader = res.body.getReader();
|
|
2088
|
-
const decoder = new TextDecoder();
|
|
2089
|
-
let buffer = "";
|
|
2090
|
-
try {
|
|
2091
|
-
for (; ; ) {
|
|
2092
|
-
const { done, value } = await reader.read();
|
|
2093
|
-
if (done) break;
|
|
2094
|
-
buffer += decoder.decode(value, { stream: true });
|
|
2095
|
-
let sep;
|
|
2096
|
-
while ((sep = buffer.indexOf("\n\n")) >= 0) {
|
|
2097
|
-
const frame = buffer.slice(0, sep);
|
|
2098
|
-
buffer = buffer.slice(sep + 2);
|
|
2099
|
-
for (const line of frame.split("\n")) {
|
|
2100
|
-
if (!line.startsWith("data:")) continue;
|
|
2101
|
-
try {
|
|
2102
|
-
yield JSON.parse(line.slice(5).trim());
|
|
2103
|
-
} catch {
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
} finally {
|
|
2109
|
-
reader.releaseLock();
|
|
2110
|
-
await res.body.cancel().catch(() => {
|
|
2111
|
-
});
|
|
2112
|
-
}
|
|
2131
|
+
yield* readSseStream(res, { label: "progress stream" });
|
|
2113
2132
|
}
|
|
2114
2133
|
/**
|
|
2115
2134
|
* Copy an external media URL into your Nodaro storage (`POST /v1/save-to-storage`)
|
|
@@ -2138,6 +2157,22 @@ var MediaResource = class {
|
|
|
2138
2157
|
imageCollage(input) {
|
|
2139
2158
|
return this.client.request("POST", "/v1/image-collage", { body: input });
|
|
2140
2159
|
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Place 1–12 layers — pictures, real text, QR codes, shapes — on a base image,
|
|
2162
|
+
* pixel-exactly (`POST /v1/image-overlay`) — local, deterministic, no AI.
|
|
2163
|
+
* Every layer position/size is a PERCENT of the base image: `anchor` (nine
|
|
2164
|
+
* positions, default `"center"`), `x`/`y` (offset from the anchor in % of
|
|
2165
|
+
* the base width/height; negative on a right/bottom anchor moves inward),
|
|
2166
|
+
* `width` (% of the base width, default 25 — height follows the layer's
|
|
2167
|
+
* aspect unless `height` is set). Plus `opacity` (0..1), `rotation`
|
|
2168
|
+
* (degrees), `blend` (`"over"` | `"multiply"` | `"screen"`), `fit`,
|
|
2169
|
+
* `shadow` and `roundedCorners`. The output keeps the base's pixel size
|
|
2170
|
+
* unless `canvas` is set. Flat credit cost. Poll `jobs.get(jobId)` for the
|
|
2171
|
+
* finished image.
|
|
2172
|
+
*/
|
|
2173
|
+
imageOverlay(input) {
|
|
2174
|
+
return this.client.request("POST", "/v1/image-overlay", { body: input });
|
|
2175
|
+
}
|
|
2141
2176
|
/**
|
|
2142
2177
|
* Trim a video to a range (`POST /v1/trim-video`). Give the range in whichever
|
|
2143
2178
|
* unit fits: `startTime`/`endTime` seconds, `trim*Frames`, `trim*Seconds`, or
|
|
@@ -2631,19 +2666,27 @@ var StudioProductionsResource = class {
|
|
|
2631
2666
|
);
|
|
2632
2667
|
return res.data;
|
|
2633
2668
|
}
|
|
2634
|
-
/**
|
|
2635
|
-
* Apply a batch of operations. Atomic: one bad operation refuses the whole
|
|
2636
|
-
* batch with a `StudioOpError` naming its index, and nothing is written. On
|
|
2637
|
-
* success adopt `production` wholesale and carry `version` forward as the
|
|
2638
|
-
* next `baseVersion`.
|
|
2639
|
-
*/
|
|
2640
2669
|
async ops(productionId, input) {
|
|
2641
|
-
|
|
2670
|
+
if (input.dryRun !== true) {
|
|
2671
|
+
const res2 = await this.client.request(
|
|
2672
|
+
"POST",
|
|
2673
|
+
this.path(productionId, "/ops"),
|
|
2674
|
+
{ body: input }
|
|
2675
|
+
);
|
|
2676
|
+
return res2.data;
|
|
2677
|
+
}
|
|
2678
|
+
const ping = await this.client.request(
|
|
2642
2679
|
"POST",
|
|
2643
2680
|
this.path(productionId, "/ops"),
|
|
2644
|
-
{ body:
|
|
2681
|
+
{ body: { ops: [], dryRun: true } }
|
|
2645
2682
|
);
|
|
2646
|
-
|
|
2683
|
+
if (ping?.data?.dryRun !== true) throw new StudioPreviewUnavailable();
|
|
2684
|
+
const res = await this.client.request("POST", this.path(productionId, "/ops"), { body: input });
|
|
2685
|
+
const data = res?.data;
|
|
2686
|
+
if (data?.dryRun !== true) {
|
|
2687
|
+
throw new StudioPreviewAppliedError(data);
|
|
2688
|
+
}
|
|
2689
|
+
return data;
|
|
2647
2690
|
}
|
|
2648
2691
|
/**
|
|
2649
2692
|
* Land every generation that has finished since you last looked, and report
|
|
@@ -2851,6 +2894,103 @@ var StudioResource = class {
|
|
|
2851
2894
|
}
|
|
2852
2895
|
};
|
|
2853
2896
|
|
|
2897
|
+
// src/resources/copilot.ts
|
|
2898
|
+
var COPILOT_FRAME_TYPES = /* @__PURE__ */ new Set([
|
|
2899
|
+
"metadata",
|
|
2900
|
+
"token",
|
|
2901
|
+
"tool_call",
|
|
2902
|
+
"workflow_updated",
|
|
2903
|
+
"workflow_created",
|
|
2904
|
+
"run_proposed",
|
|
2905
|
+
"memory_saved",
|
|
2906
|
+
"usage",
|
|
2907
|
+
"done",
|
|
2908
|
+
"error"
|
|
2909
|
+
]);
|
|
2910
|
+
function isCopilotFrame(value) {
|
|
2911
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2912
|
+
const type = value.type;
|
|
2913
|
+
return typeof type === "string" && COPILOT_FRAME_TYPES.has(type);
|
|
2914
|
+
}
|
|
2915
|
+
var CopilotResource = class {
|
|
2916
|
+
constructor(client) {
|
|
2917
|
+
this.client = client;
|
|
2918
|
+
}
|
|
2919
|
+
client;
|
|
2920
|
+
/**
|
|
2921
|
+
* Open a conversation (`POST /v1/copilot/threads`) — on `workflowId`, or on
|
|
2922
|
+
* a workflow the server creates from `prompt`. Re-opening a workflow that
|
|
2923
|
+
* already has an active thread answers THAT thread rather than a second one.
|
|
2924
|
+
*/
|
|
2925
|
+
create(input) {
|
|
2926
|
+
return this.client.request("POST", "/v1/copilot/threads", { body: input });
|
|
2927
|
+
}
|
|
2928
|
+
/**
|
|
2929
|
+
* The active thread for a workflow (`GET /v1/copilot/threads?workflowId=…`),
|
|
2930
|
+
* or `null` when the user has none open on it.
|
|
2931
|
+
*/
|
|
2932
|
+
list(params) {
|
|
2933
|
+
return this.client.request("GET", "/v1/copilot/threads", { query: { workflowId: params.workflowId } });
|
|
2934
|
+
}
|
|
2935
|
+
/**
|
|
2936
|
+
* One thread with its messages (`GET /v1/copilot/threads/:id`). `after` reads
|
|
2937
|
+
* only what followed that sequence number (the panel's catch-up); `limit`
|
|
2938
|
+
* caps the page at the server's own ceiling.
|
|
2939
|
+
*/
|
|
2940
|
+
get(id, opts = {}) {
|
|
2941
|
+
return this.client.request("GET", `/v1/copilot/threads/${encodeURIComponent(id)}`, {
|
|
2942
|
+
query: { ...opts.after !== void 0 ? { after: opts.after } : {}, ...opts.limit !== void 0 ? { limit: opts.limit } : {} }
|
|
2943
|
+
});
|
|
2944
|
+
}
|
|
2945
|
+
/**
|
|
2946
|
+
* Close a conversation (`DELETE /v1/copilot/threads/:id`). Archival, not
|
|
2947
|
+
* deletion — the messages stay readable. Refused while a turn is running.
|
|
2948
|
+
*/
|
|
2949
|
+
archive(id) {
|
|
2950
|
+
return this.client.request("DELETE", `/v1/copilot/threads/${encodeURIComponent(id)}`);
|
|
2951
|
+
}
|
|
2952
|
+
/**
|
|
2953
|
+
* Stop the running turn (`POST /v1/copilot/threads/:id/cancel`). Answers the
|
|
2954
|
+
* turn it asked to stop; the turn's own stream ends with a `done` frame.
|
|
2955
|
+
*/
|
|
2956
|
+
cancel(id) {
|
|
2957
|
+
return this.client.request("POST", `/v1/copilot/threads/${encodeURIComponent(id)}/cancel`);
|
|
2958
|
+
}
|
|
2959
|
+
/**
|
|
2960
|
+
* Send one message and iterate the turn's frames
|
|
2961
|
+
* (`POST /v1/copilot/threads/:id/messages`, server-sent events).
|
|
2962
|
+
*
|
|
2963
|
+
* Deliberately NOT routed through `client.request`: that path arms an abort
|
|
2964
|
+
* timer around the whole exchange, and a turn legitimately runs for minutes —
|
|
2965
|
+
* inheriting `timeoutMs` would cut the assistant off mid-answer. The caller
|
|
2966
|
+
* owns the lifetime instead: pass `signal` to end the stream, or stop
|
|
2967
|
+
* iterating (the reader cancels the body, which ends the request).
|
|
2968
|
+
*
|
|
2969
|
+
* A frame kind this package does not model is skipped rather than thrown, so
|
|
2970
|
+
* a newer server cannot break an older caller.
|
|
2971
|
+
*/
|
|
2972
|
+
async *stream(threadId, opts) {
|
|
2973
|
+
const url = `${this.client.baseUrl}/v1/copilot/threads/${encodeURIComponent(threadId)}/messages`;
|
|
2974
|
+
const token = await this.client.auth.getToken();
|
|
2975
|
+
const res = await this.client.fetch(url, {
|
|
2976
|
+
method: "POST",
|
|
2977
|
+
headers: {
|
|
2978
|
+
"Content-Type": "application/json",
|
|
2979
|
+
...token ? { Authorization: `Bearer ${token}` } : {}
|
|
2980
|
+
},
|
|
2981
|
+
body: JSON.stringify({
|
|
2982
|
+
message: opts.message,
|
|
2983
|
+
...opts.baseVersion !== void 0 ? { baseVersion: opts.baseVersion } : {},
|
|
2984
|
+
...opts.tier ? { tier: opts.tier } : {}
|
|
2985
|
+
}),
|
|
2986
|
+
signal: opts.signal
|
|
2987
|
+
});
|
|
2988
|
+
for await (const value of readSseStream(res, { label: "copilot stream" })) {
|
|
2989
|
+
if (isCopilotFrame(value)) yield value;
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
};
|
|
2993
|
+
|
|
2854
2994
|
// src/resources/community.ts
|
|
2855
2995
|
var CommunityResource = class {
|
|
2856
2996
|
constructor(client) {
|
|
@@ -3232,7 +3372,7 @@ var WorkspacesResource = class {
|
|
|
3232
3372
|
return this.client.requestText("GET", `/v1/workspaces/${encodeURIComponent(id)}/usage`, { query: { ...opts, format: "csv" } });
|
|
3233
3373
|
}
|
|
3234
3374
|
};
|
|
3235
|
-
var SDK_VERSION = "2.
|
|
3375
|
+
var SDK_VERSION = "2.6.0" ;
|
|
3236
3376
|
var CLIENT_HEADER = "X-Nodaro-Client";
|
|
3237
3377
|
var isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
3238
3378
|
var NodaroClient = class _NodaroClient {
|
|
@@ -3284,6 +3424,7 @@ var NodaroClient = class _NodaroClient {
|
|
|
3284
3424
|
shots;
|
|
3285
3425
|
recast;
|
|
3286
3426
|
studio;
|
|
3427
|
+
copilot;
|
|
3287
3428
|
community;
|
|
3288
3429
|
templates;
|
|
3289
3430
|
tutorials;
|
|
@@ -3330,6 +3471,7 @@ var NodaroClient = class _NodaroClient {
|
|
|
3330
3471
|
this.shots = new ShotsResource(this);
|
|
3331
3472
|
this.recast = new RecastResource(this);
|
|
3332
3473
|
this.studio = new StudioResource(this);
|
|
3474
|
+
this.copilot = new CopilotResource(this);
|
|
3333
3475
|
this.community = new CommunityResource(this);
|
|
3334
3476
|
this.templates = new TemplatesResource(this);
|
|
3335
3477
|
this.tutorials = new TutorialsResource(this);
|
|
@@ -3582,6 +3724,7 @@ exports.CallbackAuth = CallbackAuth;
|
|
|
3582
3724
|
exports.CatalogsResource = CatalogsResource;
|
|
3583
3725
|
exports.CharactersResource = CharactersResource;
|
|
3584
3726
|
exports.CommunityResource = CommunityResource;
|
|
3727
|
+
exports.CopilotResource = CopilotResource;
|
|
3585
3728
|
exports.CreaturesResource = CreaturesResource;
|
|
3586
3729
|
exports.CreditsResource = CreditsResource;
|
|
3587
3730
|
exports.DeveloperAppsResource = DeveloperAppsResource;
|
|
@@ -3619,6 +3762,8 @@ exports.ShotsResource = ShotsResource;
|
|
|
3619
3762
|
exports.StaticTokenAuth = StaticTokenAuth;
|
|
3620
3763
|
exports.StorageExceededError = StorageExceededError;
|
|
3621
3764
|
exports.StudioOpError = StudioOpError;
|
|
3765
|
+
exports.StudioPreviewAppliedError = StudioPreviewAppliedError;
|
|
3766
|
+
exports.StudioPreviewUnavailable = StudioPreviewUnavailable;
|
|
3622
3767
|
exports.StudioProductionsResource = StudioProductionsResource;
|
|
3623
3768
|
exports.StudioResource = StudioResource;
|
|
3624
3769
|
exports.TemplatesResource = TemplatesResource;
|