codai-sdk 0.66.0 → 0.68.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.d.ts +2127 -490
- package/dist/index.js +403 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1583,7 +1583,7 @@ function decodeBase64(b64) {
|
|
|
1583
1583
|
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
1584
1584
|
return out;
|
|
1585
1585
|
}
|
|
1586
|
-
function abortableSleep$
|
|
1586
|
+
function abortableSleep$7(ms, signal) {
|
|
1587
1587
|
return new Promise((resolve, reject) => {
|
|
1588
1588
|
if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
|
|
1589
1589
|
const t = setTimeout(() => {
|
|
@@ -1698,7 +1698,7 @@ var Videos = class {
|
|
|
1698
1698
|
}
|
|
1699
1699
|
if (st.status === "failed" || st.status === "filtered") throw new Error(`codai video job ${st.status}: ${st.error ?? "no details"}`);
|
|
1700
1700
|
if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai video job ${job.id} did not finish within ${timeoutMs} ms`);
|
|
1701
|
-
await abortableSleep$
|
|
1701
|
+
await abortableSleep$7(pollIntervalMs, signal);
|
|
1702
1702
|
}
|
|
1703
1703
|
}
|
|
1704
1704
|
};
|
|
@@ -1797,14 +1797,14 @@ var Renders = class {
|
|
|
1797
1797
|
}
|
|
1798
1798
|
if (st.status === "failed") throw new Error(`codai render failed: ${st.error ?? "no details"}`);
|
|
1799
1799
|
if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai render ${job.id} did not finish within ${timeoutMs} ms`);
|
|
1800
|
-
await abortableSleep$
|
|
1800
|
+
await abortableSleep$7(pollIntervalMs, signal);
|
|
1801
1801
|
}
|
|
1802
1802
|
}
|
|
1803
1803
|
};
|
|
1804
1804
|
|
|
1805
1805
|
//#endregion
|
|
1806
1806
|
//#region src/resources/documents.ts
|
|
1807
|
-
function abortableSleep$
|
|
1807
|
+
function abortableSleep$6(ms, signal) {
|
|
1808
1808
|
return new Promise((resolve, reject) => {
|
|
1809
1809
|
if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
|
|
1810
1810
|
const t = setTimeout(() => {
|
|
@@ -1897,7 +1897,7 @@ var Documents = class {
|
|
|
1897
1897
|
if (st.status === "succeeded") return st;
|
|
1898
1898
|
if (st.status === "failed") throw new Error(`codai document preview failed: ${st.error ?? "no details"}`);
|
|
1899
1899
|
if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai document preview ${job.id} did not finish within ${timeoutMs} ms`);
|
|
1900
|
-
await abortableSleep$
|
|
1900
|
+
await abortableSleep$6(pollIntervalMs, signal);
|
|
1901
1901
|
}
|
|
1902
1902
|
}
|
|
1903
1903
|
/** Queue a deck video and poll `renders.retrieve` until it succeeds. Throws on `failed` or timeout. */
|
|
@@ -1929,7 +1929,7 @@ var Documents = class {
|
|
|
1929
1929
|
}
|
|
1930
1930
|
if (st.status === "failed") throw new Error(`codai deck video failed: ${st.error ?? "no details"}`);
|
|
1931
1931
|
if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai deck video ${accepted.id} did not finish within ${timeoutMs} ms`);
|
|
1932
|
-
await abortableSleep$
|
|
1932
|
+
await abortableSleep$6(pollIntervalMs, signal);
|
|
1933
1933
|
}
|
|
1934
1934
|
}
|
|
1935
1935
|
};
|
|
@@ -1937,7 +1937,7 @@ var Documents = class {
|
|
|
1937
1937
|
//#endregion
|
|
1938
1938
|
//#region src/resources/exports.ts
|
|
1939
1939
|
const path$6 = (id) => `/v1/studio/exports/${encodeURIComponent(id)}`;
|
|
1940
|
-
function abortableSleep$
|
|
1940
|
+
function abortableSleep$5(ms, signal) {
|
|
1941
1941
|
return new Promise((resolve, reject) => {
|
|
1942
1942
|
if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
|
|
1943
1943
|
const t = setTimeout(() => {
|
|
@@ -1978,7 +1978,7 @@ var Exports = class {
|
|
|
1978
1978
|
});
|
|
1979
1979
|
if (st.status === "succeeded" || st.status === "failed") return st;
|
|
1980
1980
|
if (Date.now() + intervalMs > deadline) throw new Error(`codai export ${id} did not finish within ${timeoutMs} ms`);
|
|
1981
|
-
await abortableSleep$
|
|
1981
|
+
await abortableSleep$5(intervalMs, signal);
|
|
1982
1982
|
}
|
|
1983
1983
|
}
|
|
1984
1984
|
};
|
|
@@ -2159,6 +2159,24 @@ var Creatives = class {
|
|
|
2159
2159
|
});
|
|
2160
2160
|
}
|
|
2161
2161
|
/**
|
|
2162
|
+
* Mixdown + mastering + exports of an `audio` creative (MU-05; same `POST …/render` route, HTTP 202). `formats`
|
|
2163
|
+
* (default `['wav', 'mp3']`), `stems: true` adds one WAV per audible track (+50 %), `lrc` exports the timed lyrics
|
|
2164
|
+
* (default on when the document has them), `loudness` is `streaming` (−14) | `podcast` (−16) | `broadcast` (−23) or
|
|
2165
|
+
* LUFS (−40…−5). Poll `renders.retrieve(render_id)`: the finished render's `data[]` holds one signed asset per output
|
|
2166
|
+
* (`output: mix | stem | lrc`). $0.001 per output second, minimum $0.01; held up front, billed on the measured length.
|
|
2167
|
+
* 400 `empty_audio` / `too_long` (20 min) / `no_lyrics`; video creatives use `render`.
|
|
2168
|
+
*/
|
|
2169
|
+
renderAudio(id, body = {}, opts = {}) {
|
|
2170
|
+
return this.http.json(path$5(id, "/render"), {
|
|
2171
|
+
method: "POST",
|
|
2172
|
+
body,
|
|
2173
|
+
headers: opts.idempotencyKey ? { "Idempotency-Key": opts.idempotencyKey } : void 0,
|
|
2174
|
+
ext: opts.ext,
|
|
2175
|
+
signal: opts.signal,
|
|
2176
|
+
noRetry: !opts.idempotencyKey
|
|
2177
|
+
});
|
|
2178
|
+
}
|
|
2179
|
+
/**
|
|
2162
2180
|
* PNG still frames at up to 6 times (`t_ms`). `exact: false` (default) screenshots the compiled HTML; `exact: true`
|
|
2163
2181
|
* cuts them from a draft render of the covering scenes. Waits up to ~90 s: frames (`status: 'succeeded'`) or a
|
|
2164
2182
|
* running job (`status: 'running'`) to poll with `frameJob(id, frame_job_id)`. Cached frames are free; 60 frame
|
|
@@ -2705,7 +2723,7 @@ var Templates = class {
|
|
|
2705
2723
|
//#endregion
|
|
2706
2724
|
//#region src/resources/productions.ts
|
|
2707
2725
|
const path$2 = (id) => `/v1/studio/productions/${encodeURIComponent(id)}`;
|
|
2708
|
-
function abortableSleep$
|
|
2726
|
+
function abortableSleep$4(ms, signal) {
|
|
2709
2727
|
return new Promise((resolve, reject) => {
|
|
2710
2728
|
if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
|
|
2711
2729
|
const t = setTimeout(() => {
|
|
@@ -2754,7 +2772,7 @@ var Productions = class {
|
|
|
2754
2772
|
const p = await this.retrieve(id, opts);
|
|
2755
2773
|
if (isProductionFinished(p)) return p;
|
|
2756
2774
|
if (Date.now() + interval > deadline) throw new Error(`codai: production ${id} did not finish in time (phase ${p.phase})`);
|
|
2757
|
-
await abortableSleep$
|
|
2775
|
+
await abortableSleep$4(interval, opts.signal);
|
|
2758
2776
|
}
|
|
2759
2777
|
}
|
|
2760
2778
|
/** `create` + `wait`. */
|
|
@@ -2764,6 +2782,292 @@ var Productions = class {
|
|
|
2764
2782
|
}
|
|
2765
2783
|
};
|
|
2766
2784
|
|
|
2785
|
+
//#endregion
|
|
2786
|
+
//#region src/resources/media-ops.ts
|
|
2787
|
+
const BASE$1 = "/v1/studio/media-ops";
|
|
2788
|
+
const opPath = (op) => `${BASE$1}/${encodeURIComponent(op)}`;
|
|
2789
|
+
function abortableSleep$3(ms, signal) {
|
|
2790
|
+
return new Promise((resolve, reject) => {
|
|
2791
|
+
if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
|
|
2792
|
+
const t = setTimeout(() => {
|
|
2793
|
+
signal?.removeEventListener("abort", onAbort);
|
|
2794
|
+
resolve();
|
|
2795
|
+
}, ms);
|
|
2796
|
+
const onAbort = () => {
|
|
2797
|
+
clearTimeout(t);
|
|
2798
|
+
reject(signal?.reason ?? /* @__PURE__ */ new Error("Aborted"));
|
|
2799
|
+
};
|
|
2800
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
2801
|
+
});
|
|
2802
|
+
}
|
|
2803
|
+
const toBody = (input) => ({
|
|
2804
|
+
asset_ids: input.assetIds ?? [],
|
|
2805
|
+
params: input.params ?? {}
|
|
2806
|
+
});
|
|
2807
|
+
/** A run answer is a job (async op, HTTP 202) when `object` is `media_op.job`. */
|
|
2808
|
+
const isMediaOpJob = (r) => r.object === "media_op.job";
|
|
2809
|
+
const isMediaOpJobFinished = (j) => j.status === "ready" || j.status === "failed";
|
|
2810
|
+
var MediaOps = class {
|
|
2811
|
+
http;
|
|
2812
|
+
constructor(http) {
|
|
2813
|
+
this.http = http;
|
|
2814
|
+
}
|
|
2815
|
+
/** `GET /v1/studio/media-ops` — every op with engine, mode, inputs, `available` and a list quote (free). */
|
|
2816
|
+
list(opts = {}) {
|
|
2817
|
+
return this.http.json(BASE$1, {
|
|
2818
|
+
ext: opts.ext,
|
|
2819
|
+
signal: opts.signal
|
|
2820
|
+
});
|
|
2821
|
+
}
|
|
2822
|
+
/** `POST /v1/studio/media-ops/{op}/quote` — exact price of this request; nothing is held or billed. */
|
|
2823
|
+
quote(op, input = {}, opts = {}) {
|
|
2824
|
+
return this.http.json(`${opPath(op)}/quote`, {
|
|
2825
|
+
method: "POST",
|
|
2826
|
+
body: toBody(input),
|
|
2827
|
+
ext: opts.ext,
|
|
2828
|
+
signal: opts.signal
|
|
2829
|
+
});
|
|
2830
|
+
}
|
|
2831
|
+
/**
|
|
2832
|
+
* `POST /v1/studio/media-ops/{op}` — sync ops resolve to a `media_op.result` with the outputs, async ops to a
|
|
2833
|
+
* `media_op.job` (`status: pending`; poll with `job` / `wait`). Use `isMediaOpJob` to tell them apart.
|
|
2834
|
+
*/
|
|
2835
|
+
run(op, input = {}, opts = {}) {
|
|
2836
|
+
return this.http.json(opPath(op), {
|
|
2837
|
+
method: "POST",
|
|
2838
|
+
body: toBody(input),
|
|
2839
|
+
headers: opts.idempotencyKey ? { "Idempotency-Key": opts.idempotencyKey } : void 0,
|
|
2840
|
+
noRetry: !opts.idempotencyKey,
|
|
2841
|
+
ext: opts.ext,
|
|
2842
|
+
signal: opts.signal
|
|
2843
|
+
});
|
|
2844
|
+
}
|
|
2845
|
+
/** `GET /v1/studio/media-ops/jobs/{id}` — the job; reading a finished one stores its outputs and bills it once. */
|
|
2846
|
+
job(id, opts = {}) {
|
|
2847
|
+
return this.http.json(`${BASE$1}/jobs/${encodeURIComponent(id)}`, {
|
|
2848
|
+
ext: opts.ext,
|
|
2849
|
+
signal: opts.signal
|
|
2850
|
+
});
|
|
2851
|
+
}
|
|
2852
|
+
/**
|
|
2853
|
+
* Poll `job` every `intervalMs` (default 3 s) until it is `ready` or `failed` (a failed job resolves too — check
|
|
2854
|
+
* `status` / `error`). Throws after `timeoutMs` (default 20 min) or when `signal` aborts.
|
|
2855
|
+
*/
|
|
2856
|
+
async wait(id, opts = {}) {
|
|
2857
|
+
const interval = opts.intervalMs ?? 3e3;
|
|
2858
|
+
const deadline = Date.now() + (opts.timeoutMs ?? 12e5);
|
|
2859
|
+
for (;;) {
|
|
2860
|
+
const j = await this.job(id, opts);
|
|
2861
|
+
if (isMediaOpJobFinished(j)) return j;
|
|
2862
|
+
if (Date.now() + interval > deadline) throw new Error(`codai: media job ${id} did not finish in time (status ${j.status})`);
|
|
2863
|
+
await abortableSleep$3(interval, opts.signal);
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
/** `run`, then `wait` when the op is async. */
|
|
2867
|
+
async runAndWait(op, input = {}, opts = {}) {
|
|
2868
|
+
const r = await this.run(op, input, opts);
|
|
2869
|
+
return isMediaOpJob(r) && !isMediaOpJobFinished(r) ? this.wait(r.id, opts) : r;
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
|
|
2873
|
+
//#endregion
|
|
2874
|
+
//#region src/resources/lyrics.ts
|
|
2875
|
+
const BASE = "/v1/studio/lyrics";
|
|
2876
|
+
var LyricsResource = class {
|
|
2877
|
+
http;
|
|
2878
|
+
constructor(http) {
|
|
2879
|
+
this.http = http;
|
|
2880
|
+
}
|
|
2881
|
+
post(path, body, opts) {
|
|
2882
|
+
return this.http.json(path, {
|
|
2883
|
+
method: "POST",
|
|
2884
|
+
body,
|
|
2885
|
+
headers: opts.idempotencyKey ? { "Idempotency-Key": opts.idempotencyKey } : void 0,
|
|
2886
|
+
noRetry: !opts.idempotencyKey,
|
|
2887
|
+
ext: opts.ext,
|
|
2888
|
+
signal: opts.signal
|
|
2889
|
+
});
|
|
2890
|
+
}
|
|
2891
|
+
/**
|
|
2892
|
+
* `POST /v1/studio/lyrics` — `{ brief, language: 'ro' | 'en', genre?, mood?, structure?, syllables_per_line?,
|
|
2893
|
+
* rhyme_scheme?, lines_per_section?, title? }` → `studio.lyrics` with every line's syllables and rhyme letter, the
|
|
2894
|
+
* whole song as `text` (`[kind]` headers) and a `report`. `repaired: true` when the repair turn won.
|
|
2895
|
+
*/
|
|
2896
|
+
write(body, opts = {}) {
|
|
2897
|
+
return this.post(BASE, body, opts);
|
|
2898
|
+
}
|
|
2899
|
+
/**
|
|
2900
|
+
* `POST /v1/studio/lyrics/align` — `{ creative_id, clip_id, lyrics_text, language?, apply?, base_seq?,
|
|
2901
|
+
* retranscribe? }` → `studio.lyrics_alignment`: timed `lines`, `lrc`, `match_ratio`, `cached`, and `seq` /
|
|
2902
|
+
* `doc_hash` of the new version when applied.
|
|
2903
|
+
*/
|
|
2904
|
+
align(body, opts = {}) {
|
|
2905
|
+
return this.post(`${BASE}/align`, body, opts);
|
|
2906
|
+
}
|
|
2907
|
+
};
|
|
2908
|
+
|
|
2909
|
+
//#endregion
|
|
2910
|
+
//#region src/resources/jam.ts
|
|
2911
|
+
const JAM_SUBPROTOCOL = "codai-jam";
|
|
2912
|
+
/** WebSocket close codes of `/v1/studio/jam`. */
|
|
2913
|
+
const JAM_CLOSE_CODES = {
|
|
2914
|
+
invalidMessage: 4400,
|
|
2915
|
+
unauthorized: 4401,
|
|
2916
|
+
insufficientFunds: 4402,
|
|
2917
|
+
forbidden: 4403,
|
|
2918
|
+
maxDuration: 4408,
|
|
2919
|
+
busy: 4409,
|
|
2920
|
+
upstream: 4502,
|
|
2921
|
+
unavailable: 4503
|
|
2922
|
+
};
|
|
2923
|
+
const JAM_SCALES = [
|
|
2924
|
+
"SCALE_UNSPECIFIED",
|
|
2925
|
+
"C_MAJOR_A_MINOR",
|
|
2926
|
+
"D_FLAT_MAJOR_B_FLAT_MINOR",
|
|
2927
|
+
"D_MAJOR_B_MINOR",
|
|
2928
|
+
"E_FLAT_MAJOR_C_MINOR",
|
|
2929
|
+
"E_MAJOR_D_FLAT_MINOR",
|
|
2930
|
+
"F_MAJOR_D_MINOR",
|
|
2931
|
+
"G_FLAT_MAJOR_E_FLAT_MINOR",
|
|
2932
|
+
"G_MAJOR_E_MINOR",
|
|
2933
|
+
"A_FLAT_MAJOR_F_MINOR",
|
|
2934
|
+
"A_MAJOR_G_FLAT_MINOR",
|
|
2935
|
+
"B_FLAT_MAJOR_G_MINOR",
|
|
2936
|
+
"B_MAJOR_A_FLAT_MINOR"
|
|
2937
|
+
];
|
|
2938
|
+
const OPEN$1 = 1;
|
|
2939
|
+
function toArrayBuffer(data) {
|
|
2940
|
+
if (data instanceof ArrayBuffer) return data;
|
|
2941
|
+
if (ArrayBuffer.isView(data)) {
|
|
2942
|
+
const v = data;
|
|
2943
|
+
return v.buffer.slice(v.byteOffset, v.byteOffset + v.byteLength);
|
|
2944
|
+
}
|
|
2945
|
+
return null;
|
|
2946
|
+
}
|
|
2947
|
+
/** A live jam session: `on()` listeners for status / audio / errors and typed senders. */
|
|
2948
|
+
var JamSession = class {
|
|
2949
|
+
socket;
|
|
2950
|
+
listeners = /* @__PURE__ */ new Map();
|
|
2951
|
+
outbox = [];
|
|
2952
|
+
closed = false;
|
|
2953
|
+
/** Resolves when the socket is open (rejects if it closes first). */
|
|
2954
|
+
ready;
|
|
2955
|
+
constructor(socket) {
|
|
2956
|
+
this.socket = socket;
|
|
2957
|
+
let resolveReady;
|
|
2958
|
+
let rejectReady;
|
|
2959
|
+
this.ready = new Promise((res, rej) => {
|
|
2960
|
+
resolveReady = res;
|
|
2961
|
+
rejectReady = rej;
|
|
2962
|
+
});
|
|
2963
|
+
this.ready.catch(() => void 0);
|
|
2964
|
+
socket.onopen = () => {
|
|
2965
|
+
for (const f of this.outbox.splice(0)) socket.send(f);
|
|
2966
|
+
resolveReady();
|
|
2967
|
+
};
|
|
2968
|
+
socket.onmessage = (ev) => {
|
|
2969
|
+
if (typeof ev.data !== "string") {
|
|
2970
|
+
const buf = toArrayBuffer(ev.data);
|
|
2971
|
+
if (buf) this.emit({
|
|
2972
|
+
type: "audio",
|
|
2973
|
+
data: buf
|
|
2974
|
+
});
|
|
2975
|
+
return;
|
|
2976
|
+
}
|
|
2977
|
+
let parsed;
|
|
2978
|
+
try {
|
|
2979
|
+
parsed = JSON.parse(ev.data);
|
|
2980
|
+
} catch {
|
|
2981
|
+
return;
|
|
2982
|
+
}
|
|
2983
|
+
if (parsed && typeof parsed === "object" && typeof parsed.type === "string") this.emit(parsed);
|
|
2984
|
+
};
|
|
2985
|
+
socket.onerror = () => {};
|
|
2986
|
+
socket.onclose = (ev) => {
|
|
2987
|
+
rejectReady(/* @__PURE__ */ new Error(`jam socket closed before open (${String(ev.code)} ${ev.reason})`));
|
|
2988
|
+
this.closed = true;
|
|
2989
|
+
this.emit({
|
|
2990
|
+
type: "close",
|
|
2991
|
+
code: ev.code,
|
|
2992
|
+
reason: ev.reason
|
|
2993
|
+
});
|
|
2994
|
+
};
|
|
2995
|
+
}
|
|
2996
|
+
on(type, fn) {
|
|
2997
|
+
let set = this.listeners.get(type);
|
|
2998
|
+
if (!set) this.listeners.set(type, set = /* @__PURE__ */ new Set());
|
|
2999
|
+
set.add(fn);
|
|
3000
|
+
return () => set.delete(fn);
|
|
3001
|
+
}
|
|
3002
|
+
/** Send one client message (JSON). Queued until the socket opens. */
|
|
3003
|
+
send(msg) {
|
|
3004
|
+
if (this.closed) throw new Error("jam session is closed");
|
|
3005
|
+
const frame = JSON.stringify(msg);
|
|
3006
|
+
if (this.socket.readyState === OPEN$1) this.socket.send(frame);
|
|
3007
|
+
else this.outbox.push(frame);
|
|
3008
|
+
}
|
|
3009
|
+
prompts(prompts) {
|
|
3010
|
+
this.send({
|
|
3011
|
+
type: "prompts",
|
|
3012
|
+
prompts
|
|
3013
|
+
});
|
|
3014
|
+
}
|
|
3015
|
+
config(config) {
|
|
3016
|
+
this.send({
|
|
3017
|
+
type: "config",
|
|
3018
|
+
...config
|
|
3019
|
+
});
|
|
3020
|
+
}
|
|
3021
|
+
play() {
|
|
3022
|
+
this.send({ type: "play" });
|
|
3023
|
+
}
|
|
3024
|
+
pause() {
|
|
3025
|
+
this.send({ type: "pause" });
|
|
3026
|
+
}
|
|
3027
|
+
stop() {
|
|
3028
|
+
this.send({ type: "stop" });
|
|
3029
|
+
}
|
|
3030
|
+
reset() {
|
|
3031
|
+
this.send({ type: "reset" });
|
|
3032
|
+
}
|
|
3033
|
+
close(code = 1e3, reason = "client closed") {
|
|
3034
|
+
if (this.closed) return;
|
|
3035
|
+
this.socket.close(code, reason);
|
|
3036
|
+
}
|
|
3037
|
+
emit(ev) {
|
|
3038
|
+
for (const fn of this.listeners.get(ev.type) ?? []) fn(ev);
|
|
3039
|
+
for (const fn of this.listeners.get("*") ?? []) fn(ev);
|
|
3040
|
+
}
|
|
3041
|
+
};
|
|
3042
|
+
/** Build the `wss://…/v1/studio/jam` URL (exported for tests and custom transports). */
|
|
3043
|
+
function jamUrl(baseUrl, opts = {}) {
|
|
3044
|
+
const url = new URL(`${baseUrl.replace(/\/$/, "").replace(/^http/, "ws")}/v1/studio/jam`);
|
|
3045
|
+
if (opts.sessionId) url.searchParams.set("session_id", opts.sessionId);
|
|
3046
|
+
return url.toString();
|
|
3047
|
+
}
|
|
3048
|
+
var Jam = class {
|
|
3049
|
+
defaults;
|
|
3050
|
+
constructor(defaults) {
|
|
3051
|
+
this.defaults = defaults;
|
|
3052
|
+
}
|
|
3053
|
+
/** Open a live jam. Returns immediately; `await session.ready` to wait for the socket. */
|
|
3054
|
+
connect(opts = {}) {
|
|
3055
|
+
const Ctor = opts.WebSocket ?? globalThis.WebSocket;
|
|
3056
|
+
if (!Ctor) throw new Error("codai.jam: no WebSocket available — pass options.WebSocket");
|
|
3057
|
+
let token = opts.token;
|
|
3058
|
+
let apiKey = token ? void 0 : opts.apiKey ?? this.defaults.apiKey;
|
|
3059
|
+
if (apiKey?.startsWith("codai_eph_v1.")) {
|
|
3060
|
+
token = apiKey;
|
|
3061
|
+
apiKey = void 0;
|
|
3062
|
+
}
|
|
3063
|
+
if (!token && !apiKey) throw new Error("codai.jam: pass `token` (browser) or `apiKey`");
|
|
3064
|
+
const url = jamUrl(opts.baseUrl ?? this.defaults.baseUrl, opts);
|
|
3065
|
+
const socket = apiKey ? new Ctor(url, [JAM_SUBPROTOCOL], { headers: { Authorization: `Bearer ${apiKey}` } }) : new Ctor(url, [JAM_SUBPROTOCOL, `bearer.${token}`]);
|
|
3066
|
+
if ("binaryType" in socket) socket.binaryType = "arraybuffer";
|
|
3067
|
+
return new JamSession(socket);
|
|
3068
|
+
}
|
|
3069
|
+
};
|
|
3070
|
+
|
|
2767
3071
|
//#endregion
|
|
2768
3072
|
//#region src/resources/batches.ts
|
|
2769
3073
|
const BATCH_DONE = [
|
|
@@ -3036,6 +3340,10 @@ var VoiceRevocations = class {
|
|
|
3036
3340
|
|
|
3037
3341
|
//#endregion
|
|
3038
3342
|
//#region src/resources/vault.ts
|
|
3343
|
+
/** The UTF-8 message an unlock proof covers: `codai-vault/unlock/v1|<challenge>|<device_id or "passkey">`. */
|
|
3344
|
+
function vaultUnlockMessage(challenge, deviceIdOrPasskey) {
|
|
3345
|
+
return `codai-vault/unlock/v1|${challenge}|${deviceIdOrPasskey}`;
|
|
3346
|
+
}
|
|
3039
3347
|
const seg = (base, id, suffix = "") => `${base}/${encodeURIComponent(id)}${suffix}`;
|
|
3040
3348
|
/** `/v1/vault/devices/*` — hardware-backed device approval keys (public keys only; revocation is instant). */
|
|
3041
3349
|
var VaultDevices = class {
|
|
@@ -3124,6 +3432,53 @@ var Vault = class {
|
|
|
3124
3432
|
setDefaultTier(defaultTier, opts = {}) {
|
|
3125
3433
|
return this.send("PATCH", "/v1/vault/settings", opts, { default_tier: defaultTier });
|
|
3126
3434
|
}
|
|
3435
|
+
/**
|
|
3436
|
+
* `PATCH /v1/vault/settings` — `default_tier` and/or partial anomaly `guards` (merged over the current ones).
|
|
3437
|
+
* Answers the effective `{ default_tier, guards }`.
|
|
3438
|
+
*/
|
|
3439
|
+
updateSettings(body, opts = {}) {
|
|
3440
|
+
if (body.default_tier === void 0 && body.guards === void 0) return Promise.reject(/* @__PURE__ */ new TypeError("updateSettings needs default_tier and/or guards"));
|
|
3441
|
+
return this.send("PATCH", "/v1/vault/settings", opts, { ...body });
|
|
3442
|
+
}
|
|
3443
|
+
/**
|
|
3444
|
+
* `POST /v1/vault/lock` — panic: revoke every live grant, deny every pending approval, lock the vault (agent uses
|
|
3445
|
+
* then answer `vault_locked`). Device keys stay enrolled. Idempotent.
|
|
3446
|
+
*/
|
|
3447
|
+
lock(params = {}, opts = {}) {
|
|
3448
|
+
return this.send("POST", "/v1/vault/lock", opts, { via: params.via });
|
|
3449
|
+
}
|
|
3450
|
+
/** `POST /v1/vault/unlock/challenge` — single-use unlock challenge, valid 5 minutes. */
|
|
3451
|
+
unlockChallenge(opts = {}) {
|
|
3452
|
+
return this.send("POST", "/v1/vault/unlock/challenge", opts, {});
|
|
3453
|
+
}
|
|
3454
|
+
/**
|
|
3455
|
+
* `POST /v1/vault/unlock` — end a lock with a device-key proof over {@link vaultUnlockMessage} or a passkey whose
|
|
3456
|
+
* challenge is base64url(SHA-256(that message with `passkey`)). 403 `challenge_invalid`, `wear_t3_only`, …
|
|
3457
|
+
*/
|
|
3458
|
+
unlock(body, opts = {}) {
|
|
3459
|
+
return this.send("POST", "/v1/vault/unlock", opts, { ...body });
|
|
3460
|
+
}
|
|
3461
|
+
/** `GET /v1/vault/limits` — per-handle usage caps on your items. */
|
|
3462
|
+
async limits(opts = {}) {
|
|
3463
|
+
return [...(await this.get("/v1/vault/limits", opts)).limits];
|
|
3464
|
+
}
|
|
3465
|
+
/**
|
|
3466
|
+
* `PUT /v1/vault/items/{id}/limits` — all three keys required; `null` removes a cap, all `null` removes the limits
|
|
3467
|
+
* (answers `null`). Over a cap the broker calls answer 429 `vault_rate_limited` with `Retry-After`.
|
|
3468
|
+
*/
|
|
3469
|
+
async setLimits(id, limits, opts = {}) {
|
|
3470
|
+
return (await this.http.json(seg("/v1/vault/items", id, "/limits"), {
|
|
3471
|
+
method: "PUT",
|
|
3472
|
+
body: {
|
|
3473
|
+
per_minute: limits.per_minute,
|
|
3474
|
+
per_day: limits.per_day,
|
|
3475
|
+
units_per_day: limits.units_per_day
|
|
3476
|
+
},
|
|
3477
|
+
ext: opts.ext,
|
|
3478
|
+
signal: opts.signal,
|
|
3479
|
+
noRetry: true
|
|
3480
|
+
})).limits ?? null;
|
|
3481
|
+
}
|
|
3127
3482
|
/** `GET /v1/vault/vaults` — vaults you belong to, with your role and sealed vault key. */
|
|
3128
3483
|
vaults(opts = {}) {
|
|
3129
3484
|
return this.get("/v1/vault/vaults", opts);
|
|
@@ -3174,6 +3529,10 @@ var Vault = class {
|
|
|
3174
3529
|
revokeGrant(id, opts = {}) {
|
|
3175
3530
|
return this.send("DELETE", seg("/v1/vault/grants", id), opts);
|
|
3176
3531
|
}
|
|
3532
|
+
/** `POST /v1/vault/grants/revoke-task` — revoke every live grant of a task / session; answers `{ revoked }`. */
|
|
3533
|
+
revokeTaskGrants(task, opts = {}) {
|
|
3534
|
+
return this.send("POST", "/v1/vault/grants/revoke-task", opts, { task });
|
|
3535
|
+
}
|
|
3177
3536
|
/** `GET /v1/vault/events` — append-only audit log (never contains secret values). */
|
|
3178
3537
|
events(params = {}, opts = {}) {
|
|
3179
3538
|
return this.get("/v1/vault/events", opts, { limit: params.limit });
|
|
@@ -6354,7 +6713,13 @@ const OPERATION_METHODS = {
|
|
|
6354
6713
|
createVoiceRevocation: "voiceRevocations.create",
|
|
6355
6714
|
getVaultAccount: "vault.account",
|
|
6356
6715
|
putVaultAccount: "vault.putAccount",
|
|
6357
|
-
patchVaultSettings: "vault.
|
|
6716
|
+
patchVaultSettings: "vault.updateSettings",
|
|
6717
|
+
lockVault: "vault.lock",
|
|
6718
|
+
createVaultUnlockChallenge: "vault.unlockChallenge",
|
|
6719
|
+
unlockVault: "vault.unlock",
|
|
6720
|
+
listVaultLimits: "vault.limits",
|
|
6721
|
+
setVaultItemLimits: "vault.setLimits",
|
|
6722
|
+
revokeVaultTaskGrants: "vault.revokeTaskGrants",
|
|
6358
6723
|
listVaults: "vault.vaults",
|
|
6359
6724
|
createVault: "vault.createVault",
|
|
6360
6725
|
listVaultItems: "vault.items",
|
|
@@ -6392,6 +6757,12 @@ const OPERATION_METHODS = {
|
|
|
6392
6757
|
listCreativeTemplates: "templates.list",
|
|
6393
6758
|
createStudioProduction: "productions.create",
|
|
6394
6759
|
getStudioProduction: "productions.retrieve",
|
|
6760
|
+
listStudioMediaOps: "mediaOps.list",
|
|
6761
|
+
quoteStudioMediaOp: "mediaOps.quote",
|
|
6762
|
+
runStudioMediaOp: "mediaOps.run",
|
|
6763
|
+
getStudioMediaOpJob: "mediaOps.job",
|
|
6764
|
+
writeStudioLyrics: "lyrics.write",
|
|
6765
|
+
alignStudioLyrics: "lyrics.align",
|
|
6395
6766
|
getCreativeTemplate: "templates.retrieve",
|
|
6396
6767
|
deleteCreativeTemplate: "templates.delete",
|
|
6397
6768
|
exportCreativeFcpxml: "creatives.exportFcpxml",
|
|
@@ -6860,6 +7231,13 @@ var CodaiApps = class {
|
|
|
6860
7231
|
* built-in starters; free; use with creatives.create({ kind, template, vars }))
|
|
6861
7232
|
* client.productions.create / .retrieve / .wait / .run (codai Studio brief → promo video: storyboard, images,
|
|
6862
7233
|
* voice-over, editable creative, draft render, one review + repair; billed as the parts are produced)
|
|
7234
|
+
* client.mediaOps.list / .quote / .run / .job / .wait / .runAndWait (codai Studio media operations on your assets:
|
|
7235
|
+
* background removal, upscale, inpaint / outpaint / erase, stems, denoise, MIDI, mastering, analysis, ACE-Step
|
|
7236
|
+
* music and sound effects; quote held, measured cost billed; async ops return a job)
|
|
7237
|
+
* client.lyrics.write / .align (codai Studio lyrics writer with syllable + rhyme checks; karaoke alignment to a clip
|
|
7238
|
+
* of an audio creative with LRC; token-metered / transcription billed)
|
|
7239
|
+
* client.creatives.renderAudio (mixdown + mastering of an audio creative: WAV / MP3 / FLAC, stems, LRC)
|
|
7240
|
+
* client.jam.connect (WebSocket live jam on Lyria RealTime; not an OpenAPI operation)
|
|
6863
7241
|
* client.exports.retrieve / .wait (codai Studio FCPXML exports queued with creatives.exportFcpxml; only newly
|
|
6864
7242
|
* rendered seconds are billed; Lottie exports from creatives.exportLottie are free and ready at once)
|
|
6865
7243
|
* client.batches.create / .dryRun / .list / .get / .cancel / .retry / .exportCsv / .zip / .wait (codai Studio
|
|
@@ -6869,6 +7247,7 @@ var CodaiApps = class {
|
|
|
6869
7247
|
* client.voiceRevocations.create (public takedown ticket for a voice cloned in codai Studio; no key needed)
|
|
6870
7248
|
* client.vault.account / .items / .putItem / .rules / .approvals / .decide / .catalog / .use / .httpCall / .resolve
|
|
6871
7249
|
* client.vault.devices.challenge / .enroll / .list / .rename / .revoke (device approval keys, V-27)
|
|
7250
|
+
* client.vault.updateSettings / .lock / .unlockChallenge / .unlock / .limits / .setLimits / .revokeTaskGrants (guards, v4)
|
|
6872
7251
|
* (zero-knowledge credentials vault: ciphertext only; the broker calls never return secret values)
|
|
6873
7252
|
* client.abuseReports.create (public DSA notice about a codai Studio share / review link; no key needed)
|
|
6874
7253
|
* client.provenance.check (public: which codai AI-provenance marks a file carries; no key needed)
|
|
@@ -6927,6 +7306,12 @@ var Codai = class {
|
|
|
6927
7306
|
templates;
|
|
6928
7307
|
/** codai Studio productions (`productions.run({ brief, language: 'ro' })` → a finished promo video + editable creative). */
|
|
6929
7308
|
productions;
|
|
7309
|
+
/** codai Studio media operations (`mediaOps.run('audio.separate_stems', { assetIds })` → job; `mediaOps.wait(id)`). */
|
|
7310
|
+
mediaOps;
|
|
7311
|
+
/** codai Studio lyrics (`lyrics.write({ brief, language: 'ro' })`, `lyrics.align({ creative_id, clip_id, lyrics_text })`). */
|
|
7312
|
+
lyrics;
|
|
7313
|
+
/** codai Studio live jam over WebSocket (`jam.connect({ token })` → PCM16 48 kHz stereo; `prompts`, `config`, `play`). */
|
|
7314
|
+
jam;
|
|
6930
7315
|
/** codai Studio FCPXML exports (`creatives.exportFcpxml(id)` queues one; `exports.wait(id)` polls until the zip is ready). */
|
|
6931
7316
|
exports;
|
|
6932
7317
|
/** codai Studio batches (`batches.create({ source: { template_id }, csv })` → one creative per row; `batches.wait(id)`). */
|
|
@@ -7031,6 +7416,12 @@ var Codai = class {
|
|
|
7031
7416
|
this.brandKits = new BrandKits(http);
|
|
7032
7417
|
this.templates = new Templates(http);
|
|
7033
7418
|
this.productions = new Productions(http);
|
|
7419
|
+
this.mediaOps = new MediaOps(http);
|
|
7420
|
+
this.lyrics = new LyricsResource(http);
|
|
7421
|
+
this.jam = new Jam({
|
|
7422
|
+
baseUrl: http.baseUrl,
|
|
7423
|
+
apiKey: opts.apiKey
|
|
7424
|
+
});
|
|
7034
7425
|
this.exports = new Exports(http);
|
|
7035
7426
|
this.batches = new Batches(http);
|
|
7036
7427
|
this.shares = new Shares(http);
|
|
@@ -7165,5 +7556,5 @@ function allKeys(obj) {
|
|
|
7165
7556
|
}
|
|
7166
7557
|
|
|
7167
7558
|
//#endregion
|
|
7168
|
-
export { AbuseReports, Account, AgentRuns, Agents, Assets, Audio, Batches, Billing, BrandKits, Cards, Chat, ChatCompletions, Codai, Codai as default, CodaiApps, CodaiError, Creatives, Devices, Documents, Embeddings, EnvironmentFiles, EnvironmentJobs, EnvironmentMembers, EnvironmentPorts, EnvironmentSecrets, EnvironmentTasks, Environments, Exports, Feedback, Health, Heartbeats, Hosts, HttpClient, Images, Keys, Lists, Memory, Messages, Models, Music, Notifications, OPERATION_METHODS, OrgMembers, Orgs, OsGate, PROVENANCE_MAX_BYTES, PhoneModels, Productions, Projects, Prompts, Provenance, RESOLVE_ATTESTATION_PAYLOAD_TYPE, RESOLVE_OPERATION_METHODS, RESOLVE_TERMINAL_STATUSES, Realtime, RealtimeSession, Receipts, Referrals, Renders, Research, Resolve, ResolveError, ResolveInsufficientFundsError, Responses, STREAMING_OPERATIONS, SandboxFiles, Sandboxes, ScheduleExecutor, SchedulerHosts, Schedules, SessionControls, SessionEvents, SessionLease, SessionShares, Sessions, Settings, Sfx, Shares, SystemOne, TUS_CHUNK_BYTES, Tasks, Templates, Tokens, Tools, Transcripts, Triggers, Usage, Vault, VaultDevices, Verify, Videos, VoiceRevocations, extensionHeaders, frameJson, isAssetDto, isProductionFinished, isResearchFinished, mergeToolCall, readSse, realtimeUrl, resolveAttestationStatement, settingsConflictCurrent, shareTokenFrom, uploadIdFromLocation, verifyAttestationWithKeys, verifyResolveWebhook };
|
|
7559
|
+
export { AbuseReports, Account, AgentRuns, Agents, Assets, Audio, Batches, Billing, BrandKits, Cards, Chat, ChatCompletions, Codai, Codai as default, CodaiApps, CodaiError, Creatives, Devices, Documents, Embeddings, EnvironmentFiles, EnvironmentJobs, EnvironmentMembers, EnvironmentPorts, EnvironmentSecrets, EnvironmentTasks, Environments, Exports, Feedback, Health, Heartbeats, Hosts, HttpClient, Images, JAM_CLOSE_CODES, JAM_SCALES, JAM_SUBPROTOCOL, Jam, JamSession, Keys, Lists, LyricsResource, MediaOps, Memory, Messages, Models, Music, Notifications, OPERATION_METHODS, OrgMembers, Orgs, OsGate, PROVENANCE_MAX_BYTES, PhoneModels, Productions, Projects, Prompts, Provenance, RESOLVE_ATTESTATION_PAYLOAD_TYPE, RESOLVE_OPERATION_METHODS, RESOLVE_TERMINAL_STATUSES, Realtime, RealtimeSession, Receipts, Referrals, Renders, Research, Resolve, ResolveError, ResolveInsufficientFundsError, Responses, STREAMING_OPERATIONS, SandboxFiles, Sandboxes, ScheduleExecutor, SchedulerHosts, Schedules, SessionControls, SessionEvents, SessionLease, SessionShares, Sessions, Settings, Sfx, Shares, SystemOne, TUS_CHUNK_BYTES, Tasks, Templates, Tokens, Tools, Transcripts, Triggers, Usage, Vault, VaultDevices, Verify, Videos, VoiceRevocations, extensionHeaders, frameJson, isAssetDto, isMediaOpJob, isMediaOpJobFinished, isProductionFinished, isResearchFinished, jamUrl, mergeToolCall, readSse, realtimeUrl, resolveAttestationStatement, settingsConflictCurrent, shareTokenFrom, uploadIdFromLocation, vaultUnlockMessage, verifyAttestationWithKeys, verifyResolveWebhook };
|
|
7169
7560
|
//# sourceMappingURL=index.js.map
|