@nodaro/sdk 2.5.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 +176 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +420 -1
- package/dist/index.d.ts +420 -1
- package/dist/index.js +174 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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`)
|
|
@@ -2647,19 +2666,27 @@ var StudioProductionsResource = class {
|
|
|
2647
2666
|
);
|
|
2648
2667
|
return res.data;
|
|
2649
2668
|
}
|
|
2650
|
-
/**
|
|
2651
|
-
* Apply a batch of operations. Atomic: one bad operation refuses the whole
|
|
2652
|
-
* batch with a `StudioOpError` naming its index, and nothing is written. On
|
|
2653
|
-
* success adopt `production` wholesale and carry `version` forward as the
|
|
2654
|
-
* next `baseVersion`.
|
|
2655
|
-
*/
|
|
2656
2669
|
async ops(productionId, input) {
|
|
2657
|
-
|
|
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(
|
|
2658
2679
|
"POST",
|
|
2659
2680
|
this.path(productionId, "/ops"),
|
|
2660
|
-
{ body:
|
|
2681
|
+
{ body: { ops: [], dryRun: true } }
|
|
2661
2682
|
);
|
|
2662
|
-
|
|
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;
|
|
2663
2690
|
}
|
|
2664
2691
|
/**
|
|
2665
2692
|
* Land every generation that has finished since you last looked, and report
|
|
@@ -2867,6 +2894,103 @@ var StudioResource = class {
|
|
|
2867
2894
|
}
|
|
2868
2895
|
};
|
|
2869
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
|
+
|
|
2870
2994
|
// src/resources/community.ts
|
|
2871
2995
|
var CommunityResource = class {
|
|
2872
2996
|
constructor(client) {
|
|
@@ -3248,7 +3372,7 @@ var WorkspacesResource = class {
|
|
|
3248
3372
|
return this.client.requestText("GET", `/v1/workspaces/${encodeURIComponent(id)}/usage`, { query: { ...opts, format: "csv" } });
|
|
3249
3373
|
}
|
|
3250
3374
|
};
|
|
3251
|
-
var SDK_VERSION = "2.
|
|
3375
|
+
var SDK_VERSION = "2.6.0" ;
|
|
3252
3376
|
var CLIENT_HEADER = "X-Nodaro-Client";
|
|
3253
3377
|
var isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
3254
3378
|
var NodaroClient = class _NodaroClient {
|
|
@@ -3300,6 +3424,7 @@ var NodaroClient = class _NodaroClient {
|
|
|
3300
3424
|
shots;
|
|
3301
3425
|
recast;
|
|
3302
3426
|
studio;
|
|
3427
|
+
copilot;
|
|
3303
3428
|
community;
|
|
3304
3429
|
templates;
|
|
3305
3430
|
tutorials;
|
|
@@ -3346,6 +3471,7 @@ var NodaroClient = class _NodaroClient {
|
|
|
3346
3471
|
this.shots = new ShotsResource(this);
|
|
3347
3472
|
this.recast = new RecastResource(this);
|
|
3348
3473
|
this.studio = new StudioResource(this);
|
|
3474
|
+
this.copilot = new CopilotResource(this);
|
|
3349
3475
|
this.community = new CommunityResource(this);
|
|
3350
3476
|
this.templates = new TemplatesResource(this);
|
|
3351
3477
|
this.tutorials = new TutorialsResource(this);
|
|
@@ -3598,6 +3724,7 @@ exports.CallbackAuth = CallbackAuth;
|
|
|
3598
3724
|
exports.CatalogsResource = CatalogsResource;
|
|
3599
3725
|
exports.CharactersResource = CharactersResource;
|
|
3600
3726
|
exports.CommunityResource = CommunityResource;
|
|
3727
|
+
exports.CopilotResource = CopilotResource;
|
|
3601
3728
|
exports.CreaturesResource = CreaturesResource;
|
|
3602
3729
|
exports.CreditsResource = CreditsResource;
|
|
3603
3730
|
exports.DeveloperAppsResource = DeveloperAppsResource;
|
|
@@ -3635,6 +3762,8 @@ exports.ShotsResource = ShotsResource;
|
|
|
3635
3762
|
exports.StaticTokenAuth = StaticTokenAuth;
|
|
3636
3763
|
exports.StorageExceededError = StorageExceededError;
|
|
3637
3764
|
exports.StudioOpError = StudioOpError;
|
|
3765
|
+
exports.StudioPreviewAppliedError = StudioPreviewAppliedError;
|
|
3766
|
+
exports.StudioPreviewUnavailable = StudioPreviewUnavailable;
|
|
3638
3767
|
exports.StudioProductionsResource = StudioProductionsResource;
|
|
3639
3768
|
exports.StudioResource = StudioResource;
|
|
3640
3769
|
exports.TemplatesResource = TemplatesResource;
|