codai-sdk 0.29.0 → 0.54.1

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.js CHANGED
@@ -257,6 +257,14 @@ function sleep(ms) {
257
257
  return new Promise((r) => setTimeout(r, ms));
258
258
  }
259
259
 
260
+ //#endregion
261
+ //#region src/resources/_shared.ts
262
+ function stripUndefined(obj) {
263
+ const out = {};
264
+ for (const [k, v] of Object.entries(obj)) if (v !== void 0) out[k] = v;
265
+ return out;
266
+ }
267
+
260
268
  //#endregion
261
269
  //#region src/resources/account.ts
262
270
  var Account = class {
@@ -555,6 +563,65 @@ var Audio = class {
555
563
  }
556
564
  };
557
565
 
566
+ //#endregion
567
+ //#region src/resources/billing.ts
568
+ var Billing = class {
569
+ http;
570
+ constructor(http) {
571
+ this.http = http;
572
+ }
573
+ /** `GET /v1/billing` — plan, wallet, auto top-up, cards and pay links (read-only). */
574
+ get(opts = {}) {
575
+ return this.http.json("/v1/billing", {
576
+ ext: opts.ext,
577
+ signal: opts.signal
578
+ });
579
+ }
580
+ /** `GET /v1/billing/invoices` — fiscal invoices and credit notes, newest first. */
581
+ async invoices(query = {}, opts = {}) {
582
+ return [...(await this.http.json("/v1/billing/invoices", {
583
+ query: { limit: query.limit },
584
+ ext: opts.ext,
585
+ signal: opts.signal
586
+ })).invoices];
587
+ }
588
+ /**
589
+ * Poll `get()` every `intervalMs` and call `onLow` once each time the wallet
590
+ * balance crosses below `thresholdEur`. Read-only: never creates a checkout.
591
+ * Returns a function that stops the watcher.
592
+ */
593
+ watchBalance(opts) {
594
+ const intervalMs = Math.max(1e3, opts.intervalMs ?? 6e4);
595
+ const ctrl = new AbortController();
596
+ const stop = () => ctrl.abort();
597
+ if (opts.signal) {
598
+ if (opts.signal.aborted) stop();
599
+ else opts.signal.addEventListener("abort", stop, { once: true });
600
+ }
601
+ let low = false;
602
+ let timer;
603
+ const tick = async () => {
604
+ if (ctrl.signal.aborted) return;
605
+ try {
606
+ const billing = await this.get({ signal: ctrl.signal });
607
+ const balance = billing.wallet.balance_eur;
608
+ if (balance < opts.thresholdEur) {
609
+ if (!low) {
610
+ low = true;
611
+ await opts.onLow(balance, billing);
612
+ }
613
+ } else low = false;
614
+ } catch (err) {
615
+ if (!ctrl.signal.aborted) opts.onError?.(err);
616
+ }
617
+ if (!ctrl.signal.aborted) timer = setTimeout(() => void tick(), intervalMs);
618
+ };
619
+ ctrl.signal.addEventListener("abort", () => clearTimeout(timer), { once: true });
620
+ tick();
621
+ return stop;
622
+ }
623
+ };
624
+
558
625
  //#endregion
559
626
  //#region src/resources/cards.ts
560
627
  var Cards = class {
@@ -608,6 +675,29 @@ var Cards = class {
608
675
  return this.get("/v1/cards/fx", params, opts);
609
676
  }
610
677
  /**
678
+ * `GET /v1/cards/route` — travel time from Google Routes: `route` { mode, durationS, staticDurationS, distanceM,
679
+ * polyline } and a `map` block. `origin`/`destination` as "lat,lng" or `from`/`to` as addresses; `mode` drive
680
+ * (traffic-aware, default), walk, bicycle, transit, two_wheeler. Billed per call; both null when no route exists.
681
+ */
682
+ route(params, opts = {}) {
683
+ return this.get("/v1/cards/route", params, opts);
684
+ }
685
+ /**
686
+ * `GET /v1/cards/track` — parcel history as a `timeline` block plus `result` (carrier, configured, found,
687
+ * delivered, events, trackingUrl). `carrier` (sameday | fan | cargus | dpd) is guessed from the AWB when omitted;
688
+ * carriers without gateway credentials answer `configured: false` with only the tracking link. Free.
689
+ */
690
+ track(params, opts = {}) {
691
+ return this.get("/v1/cards/track", params, opts);
692
+ }
693
+ /**
694
+ * `GET /v1/cards/efactura` — your fiscal documents issued through Brivio with their ANAF e-Factura status
695
+ * (`documents[]` + a `table` block, null when there are none). Free.
696
+ */
697
+ efactura(params = {}, opts = {}) {
698
+ return this.get("/v1/cards/efactura", params, opts);
699
+ }
700
+ /**
611
701
  * `POST /v1/cards/unfurl` — `links` block (variant `preview`) for a public https page; SSRF-guarded, cached 24 h.
612
702
  * Private targets throw 400 `unfurl_blocked`, non-https pages 422 `unfurl_not_https`.
613
703
  */
@@ -620,6 +710,44 @@ var Cards = class {
620
710
  signal: opts.signal
621
711
  });
622
712
  }
713
+ /**
714
+ * `POST /v1/cards/product` — `products` block with one item from a public https product page's schema.org
715
+ * `Product` JSON-LD (or OpenGraph product tags): name, image, price + currency (lowest offer), old price, rating
716
+ * (0–5), reviews, seller, availability badge in `lang` (en default). Only what the page states; never sponsored.
717
+ * SSRF-guarded like `unfurl`, cached 6 h. No product data throws 422 `product_not_found`.
718
+ */
719
+ product(url, lang, opts = {}) {
720
+ const body = lang ? {
721
+ url,
722
+ lang
723
+ } : { url };
724
+ return this.http.json("/v1/cards/product", {
725
+ method: "POST",
726
+ body,
727
+ ext: opts.ext,
728
+ signal: opts.signal
729
+ });
730
+ }
731
+ /**
732
+ * `POST /v1/cards/render` — renders a `chart` or `qr` block to `format` (`png` default, or `svg`) at
733
+ * `width` x `height` CSS px (64–1200, defaults 480 x 300; QR is square) times `scale` (1–3, PNG only).
734
+ * Other block types (Mermaid `diagram`, `math`, …) throw 422 `render_unsupported`. Free; 2000 renders per day.
735
+ */
736
+ async render(body, opts = {}) {
737
+ const res = await this.http.request("/v1/cards/render", {
738
+ method: "POST",
739
+ body,
740
+ ext: opts.ext,
741
+ signal: opts.signal
742
+ });
743
+ const size = /^(\d+)x(\d+)$/.exec(res.headers.get("x-codai-render-size") ?? "");
744
+ return {
745
+ bytes: new Uint8Array(await res.arrayBuffer()),
746
+ contentType: res.headers.get("content-type") ?? "image/png",
747
+ width: size ? Number(size[1]) : null,
748
+ height: size ? Number(size[2]) : null
749
+ };
750
+ }
623
751
  };
624
752
 
625
753
  //#endregion
@@ -847,6 +975,8 @@ var Embeddings = class {
847
975
  //#endregion
848
976
  //#region src/resources/environments.ts
849
977
  const envPath = (id, suffix = "") => `/v1/environments/${encodeURIComponent(id)}${suffix}`;
978
+ /** Absolute environment path → `/files/<each segment URL-encoded>`. */
979
+ const filePath$1 = (path) => path.replace(/^\/+/, "").split("/").map((s) => encodeURIComponent(s)).join("/");
850
980
  var EnvironmentMembers = class {
851
981
  http;
852
982
  constructor(http) {
@@ -936,6 +1066,68 @@ var EnvironmentTasks = class {
936
1066
  });
937
1067
  }
938
1068
  };
1069
+ /** `/v1/environments/{id}/files` — read/write/list over the relay (developer role or higher). */
1070
+ var EnvironmentFiles = class {
1071
+ http;
1072
+ constructor(http) {
1073
+ this.http = http;
1074
+ }
1075
+ /** `GET /v1/environments/{id}/files?path=` — directory entries; no path → your workspace. */
1076
+ list(envId, path, opts = {}) {
1077
+ return this.http.json(envPath(envId, "/files"), {
1078
+ query: { path },
1079
+ ext: opts.ext,
1080
+ signal: opts.signal
1081
+ });
1082
+ }
1083
+ /** `GET /v1/environments/{id}/files/{path}` — UTF-8 text (64 KB default, `maxBytes` ≤ 512 KB). */
1084
+ get(envId, path, options = {}) {
1085
+ return this.http.json(envPath(envId, `/files/${filePath$1(path)}`), {
1086
+ query: { max_bytes: options.maxBytes },
1087
+ ext: options.ext,
1088
+ signal: options.signal
1089
+ });
1090
+ }
1091
+ /** `PUT /v1/environments/{id}/files/{path}` — replace with UTF-8 text (≤ 2 MB). */
1092
+ put(envId, path, content, opts = {}) {
1093
+ return this.http.json(envPath(envId, `/files/${filePath$1(path)}`), {
1094
+ method: "PUT",
1095
+ rawBody: content,
1096
+ headers: { "Content-Type": "text/plain; charset=utf-8" },
1097
+ ext: opts.ext,
1098
+ signal: opts.signal
1099
+ });
1100
+ }
1101
+ };
1102
+ /** `/v1/environments/{id}/jobs` — background jobs on the environment daemon. */
1103
+ var EnvironmentJobs = class {
1104
+ http;
1105
+ constructor(http) {
1106
+ this.http = http;
1107
+ }
1108
+ /** `POST /v1/environments/{id}/jobs` — returns at once with `job_id`. */
1109
+ start(envId, body, opts = {}) {
1110
+ return this.http.json(envPath(envId, "/jobs"), {
1111
+ method: "POST",
1112
+ body,
1113
+ ext: opts.ext,
1114
+ signal: opts.signal,
1115
+ noRetry: true
1116
+ });
1117
+ }
1118
+ /** `GET /v1/environments/{id}/jobs/{jobId}` — status + output (`since` = previous `next_offset`). */
1119
+ get(envId, jobId, query = {}, opts = {}) {
1120
+ return this.http.json(envPath(envId, `/jobs/${encodeURIComponent(String(jobId))}`), {
1121
+ query: {
1122
+ since: query.since,
1123
+ tail: query.tail,
1124
+ session: query.session
1125
+ },
1126
+ ext: opts.ext,
1127
+ signal: opts.signal
1128
+ });
1129
+ }
1130
+ };
939
1131
  var EnvironmentPorts = class {
940
1132
  http;
941
1133
  constructor(http) {
@@ -1003,12 +1195,29 @@ var Environments = class {
1003
1195
  ports;
1004
1196
  secrets;
1005
1197
  tasks;
1198
+ files;
1199
+ jobs;
1006
1200
  constructor(http) {
1007
1201
  this.http = http;
1008
1202
  this.members = new EnvironmentMembers(http);
1009
1203
  this.ports = new EnvironmentPorts(http);
1010
1204
  this.secrets = new EnvironmentSecrets(http);
1011
1205
  this.tasks = new EnvironmentTasks(http);
1206
+ this.files = new EnvironmentFiles(http);
1207
+ this.jobs = new EnvironmentJobs(http);
1208
+ }
1209
+ /**
1210
+ * `POST /v1/environments/{id}/exec` — run one relay op and wait (developer+). `op` defaults to
1211
+ * `shell` with `command`; 409 `environment_offline`, 504 `host_timeout`.
1212
+ */
1213
+ exec(envId, body, opts = {}) {
1214
+ return this.http.json(envPath(envId, "/exec"), {
1215
+ method: "POST",
1216
+ body,
1217
+ ext: opts.ext,
1218
+ signal: opts.signal,
1219
+ noRetry: true
1220
+ });
1012
1221
  }
1013
1222
  /** `GET /v1/environments/{id}/ssh-ca` — CA public keys to trust (`@cert-authority` lines). */
1014
1223
  sshCa(envId, opts = {}) {
@@ -1359,7 +1568,7 @@ function decodeBase64(b64) {
1359
1568
  for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
1360
1569
  return out;
1361
1570
  }
1362
- function abortableSleep$2(ms, signal) {
1571
+ function abortableSleep$4(ms, signal) {
1363
1572
  return new Promise((resolve, reject) => {
1364
1573
  if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
1365
1574
  const t = setTimeout(() => {
@@ -1474,7 +1683,7 @@ var Videos = class {
1474
1683
  }
1475
1684
  if (st.status === "failed" || st.status === "filtered") throw new Error(`codai video job ${st.status}: ${st.error ?? "no details"}`);
1476
1685
  if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai video job ${job.id} did not finish within ${timeoutMs} ms`);
1477
- await abortableSleep$2(pollIntervalMs, signal);
1686
+ await abortableSleep$4(pollIntervalMs, signal);
1478
1687
  }
1479
1688
  }
1480
1689
  };
@@ -1495,14 +1704,56 @@ var Renders = class {
1495
1704
  /**
1496
1705
  * Poll a render (`GET /v1/studio/renders/{id}`). Billed exactly once (final $0.01 / s, min $0.05; draft half) on the
1497
1706
  * first poll that sees the finished render; failed renders cost nothing.
1707
+ * `expandAssets` signs the timeline's scene and narration assets (`?expand=assets`).
1498
1708
  */
1499
1709
  async retrieve(id, opts = {}) {
1500
1710
  return await (await this.http.request(`/v1/studio/renders/${encodeURIComponent(id)}`, {
1501
1711
  method: "GET",
1712
+ query: { expand: opts.expandAssets ? "assets" : void 0 },
1713
+ ext: opts.ext,
1714
+ signal: opts.signal
1715
+ })).json();
1716
+ }
1717
+ /**
1718
+ * List renders newest first (`GET /v1/studio/renders`) — no polling, no signed URLs. `rootRenderId` restricts the
1719
+ * list to one timeline's version chain; pass `next_before` as `before` for the next page.
1720
+ */
1721
+ async list(params = {}, opts = {}) {
1722
+ return await (await this.http.request("/v1/studio/renders", {
1723
+ method: "GET",
1724
+ query: {
1725
+ before: params.before,
1726
+ limit: params.limit,
1727
+ root_render_id: params.rootRenderId
1728
+ },
1502
1729
  ext: opts.ext,
1503
1730
  signal: opts.signal
1504
1731
  })).json();
1505
1732
  }
1733
+ /**
1734
+ * Render a scene timeline (`POST /v1/studio/timelines`, HTTP 202): image/video scenes, optional narration (billed
1735
+ * now, `narration_cost_micro_usd`) and music. Poll with `retrieve(id)`; the render is billed once when it succeeds.
1736
+ */
1737
+ async createTimeline(body, opts = {}) {
1738
+ return await (await this.http.request("/v1/studio/timelines", {
1739
+ body,
1740
+ ext: opts.ext,
1741
+ signal: opts.signal,
1742
+ noRetry: true
1743
+ })).json();
1744
+ }
1745
+ /**
1746
+ * Regenerate one scene (`POST /v1/studio/renders/{id}/scenes/{sceneId}/regenerate`, HTTP 202): a NEW render with
1747
+ * `parent_render_id` = `renderId`; the source must be a succeeded timeline render (409 `not_a_timeline`).
1748
+ */
1749
+ async regenerateScene(renderId, sceneId, body, opts = {}) {
1750
+ return await (await this.http.request(`/v1/studio/renders/${encodeURIComponent(renderId)}/scenes/${encodeURIComponent(sceneId)}/regenerate`, {
1751
+ body,
1752
+ ext: opts.ext,
1753
+ signal: opts.signal,
1754
+ noRetry: true
1755
+ })).json();
1756
+ }
1506
1757
  /** Queue a render and poll until it succeeds. Throws on `failed` or timeout. */
1507
1758
  async render(body, opts = {}) {
1508
1759
  const { pollIntervalMs = 5e3, timeoutMs = 9e5, signal, ext } = opts;
@@ -1531,14 +1782,14 @@ var Renders = class {
1531
1782
  }
1532
1783
  if (st.status === "failed") throw new Error(`codai render failed: ${st.error ?? "no details"}`);
1533
1784
  if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai render ${job.id} did not finish within ${timeoutMs} ms`);
1534
- await abortableSleep$2(pollIntervalMs, signal);
1785
+ await abortableSleep$4(pollIntervalMs, signal);
1535
1786
  }
1536
1787
  }
1537
1788
  };
1538
1789
 
1539
1790
  //#endregion
1540
1791
  //#region src/resources/documents.ts
1541
- function abortableSleep$1(ms, signal) {
1792
+ function abortableSleep$3(ms, signal) {
1542
1793
  return new Promise((resolve, reject) => {
1543
1794
  if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
1544
1795
  const t = setTimeout(() => {
@@ -1631,7 +1882,7 @@ var Documents = class {
1631
1882
  if (st.status === "succeeded") return st;
1632
1883
  if (st.status === "failed") throw new Error(`codai document preview failed: ${st.error ?? "no details"}`);
1633
1884
  if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai document preview ${job.id} did not finish within ${timeoutMs} ms`);
1634
- await abortableSleep$1(pollIntervalMs, signal);
1885
+ await abortableSleep$3(pollIntervalMs, signal);
1635
1886
  }
1636
1887
  }
1637
1888
  /** Queue a deck video and poll `renders.retrieve` until it succeeds. Throws on `failed` or timeout. */
@@ -1663,128 +1914,1203 @@ var Documents = class {
1663
1914
  }
1664
1915
  if (st.status === "failed") throw new Error(`codai deck video failed: ${st.error ?? "no details"}`);
1665
1916
  if (Date.now() + pollIntervalMs > deadline) throw new Error(`codai deck video ${accepted.id} did not finish within ${timeoutMs} ms`);
1666
- await abortableSleep$1(pollIntervalMs, signal);
1917
+ await abortableSleep$3(pollIntervalMs, signal);
1667
1918
  }
1668
1919
  }
1669
1920
  };
1670
1921
 
1671
1922
  //#endregion
1672
- //#region src/resources/messages.ts
1673
- /** `POST /v1/messages` — Anthropic Messages wire (JSON + named-event SSE). */
1674
- var Messages = class {
1923
+ //#region src/resources/exports.ts
1924
+ const path$4 = (id) => `/v1/studio/exports/${encodeURIComponent(id)}`;
1925
+ function abortableSleep$2(ms, signal) {
1926
+ return new Promise((resolve, reject) => {
1927
+ if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
1928
+ const t = setTimeout(() => {
1929
+ signal?.removeEventListener("abort", onAbort);
1930
+ resolve();
1931
+ }, ms);
1932
+ const onAbort = () => {
1933
+ clearTimeout(t);
1934
+ reject(signal?.reason ?? /* @__PURE__ */ new Error("Aborted"));
1935
+ };
1936
+ signal?.addEventListener("abort", onAbort, { once: true });
1937
+ });
1938
+ }
1939
+ var Exports = class {
1675
1940
  http;
1676
1941
  constructor(http) {
1677
1942
  this.http = http;
1678
1943
  }
1679
- async create(body, opts = {}) {
1680
- const res = await this.http.request("/v1/messages", {
1681
- body: {
1682
- ...body,
1683
- model: body.model ?? "codai",
1684
- stream: false
1685
- },
1944
+ /** The export: `queued` / `running`, then `succeeded` (signed `url`, valid 1 h) or `failed` (`error`). Free. */
1945
+ retrieve(id, opts = {}) {
1946
+ return this.http.json(path$4(id), {
1686
1947
  ext: opts.ext,
1687
1948
  signal: opts.signal
1688
1949
  });
1689
- const raw = await res.json();
1690
- return {
1691
- text: (raw.content ?? []).map((b) => b.type === "text" && typeof b.text === "string" ? b.text : "").join(""),
1692
- raw,
1693
- requestId: res.headers.get("x-codai-trace-id") ?? res.headers.get("x-request-id"),
1694
- routedTo: res.headers.get("x-codai-routed-to"),
1695
- headers: res.headers
1696
- };
1697
1950
  }
1698
- stream(body, opts = {}) {
1699
- const requestPromise = this.http.request("/v1/messages", {
1700
- body: {
1701
- ...body,
1702
- model: body.model ?? "codai",
1703
- stream: true
1704
- },
1705
- ext: opts.ext,
1706
- signal: opts.signal,
1707
- timeoutMs: 0,
1708
- noRetry: true
1709
- });
1710
- let resolveFinal;
1711
- let rejectFinal;
1712
- const final = new Promise((resolve, reject) => {
1713
- resolveFinal = resolve;
1714
- rejectFinal = reject;
1715
- });
1716
- final.catch(() => {});
1717
- let text = "";
1718
- let stopReason = null;
1719
- let inputTokens = null;
1720
- let outputTokens = null;
1721
- let res = null;
1722
- async function* events() {
1723
- try {
1724
- res = await requestPromise;
1725
- for await (const frame of readSse(res, opts.signal)) {
1726
- const ev = frameJson(frame);
1727
- if (!ev) continue;
1728
- if (typeof ev.type !== "string") ev.type = frame.event;
1729
- if (ev.type === "message_start") {
1730
- const usage = ev.message?.usage;
1731
- if (usage?.input_tokens !== void 0) inputTokens = usage.input_tokens;
1732
- } else if (ev.type === "content_block_delta") {
1733
- const delta = ev.delta;
1734
- if (delta?.type === "text_delta" && typeof delta.text === "string") text += delta.text;
1735
- } else if (ev.type === "message_delta") {
1736
- const delta = ev.delta;
1737
- if (delta?.stop_reason) stopReason = delta.stop_reason;
1738
- const usage = ev.usage;
1739
- if (usage?.output_tokens !== void 0) outputTokens = usage.output_tokens;
1740
- }
1741
- yield ev;
1742
- if (ev.type === "message_stop") break;
1743
- }
1744
- resolveFinal({
1745
- text,
1746
- stopReason,
1747
- usage: inputTokens !== null || outputTokens !== null ? {
1748
- inputTokens: inputTokens ?? 0,
1749
- outputTokens: outputTokens ?? 0
1750
- } : null,
1751
- requestId: res.headers.get("x-codai-trace-id") ?? res.headers.get("x-request-id") ?? null,
1752
- routedTo: res.headers.get("x-codai-routed-to"),
1753
- headers: res.headers
1754
- });
1755
- } catch (err) {
1756
- rejectFinal(err);
1757
- throw err;
1758
- }
1759
- }
1760
- async function* textOnly() {
1761
- for await (const ev of events()) {
1762
- if (ev.type !== "content_block_delta") continue;
1763
- const delta = ev.delta;
1764
- if (delta?.type === "text_delta" && delta.text) yield delta.text;
1765
- }
1951
+ /**
1952
+ * Poll `retrieve` every `intervalMs` (default 3 s) until the export is `succeeded` or `failed` and resolve with it
1953
+ * (a `failed` export resolves too — check `status` / `error`). Throws when it is not done within `timeoutMs`
1954
+ * (default 15 min) or when `signal` aborts.
1955
+ */
1956
+ async wait(id, opts = {}) {
1957
+ const { intervalMs = 3e3, timeoutMs = 9e5, signal, ext } = opts;
1958
+ const deadline = Date.now() + timeoutMs;
1959
+ for (;;) {
1960
+ const st = await this.retrieve(id, {
1961
+ ext,
1962
+ signal
1963
+ });
1964
+ if (st.status === "succeeded" || st.status === "failed") return st;
1965
+ if (Date.now() + intervalMs > deadline) throw new Error(`codai export ${id} did not finish within ${timeoutMs} ms`);
1966
+ await abortableSleep$2(intervalMs, signal);
1766
1967
  }
1767
- return {
1768
- [Symbol.asyncIterator]: () => events(),
1769
- text: () => ({ [Symbol.asyncIterator]: () => textOnly() }),
1770
- final
1771
- };
1772
1968
  }
1773
1969
  };
1774
1970
 
1775
1971
  //#endregion
1776
- //#region src/resources/models.ts
1777
- var Models = class {
1972
+ //#region src/resources/creatives.ts
1973
+ const path$3 = (id, tail = "") => `/v1/studio/creatives/${encodeURIComponent(id)}${tail}`;
1974
+ const lottieQuery = (q) => ({
1975
+ format: q.format,
1976
+ formats: q.formats,
1977
+ seq: q.seq,
1978
+ container: q.container
1979
+ });
1980
+ var Creatives = class {
1778
1981
  http;
1779
1982
  constructor(http) {
1780
1983
  this.http = http;
1781
1984
  }
1782
- /** Every model the calling key may address (OpenAI list shape, `data[]`). */
1783
- async list(opts = {}) {
1784
- return [...(await this.http.json("/v1/models", {
1985
+ /** List your creatives, most recently updated first (`next_before` pages). */
1986
+ list(query = {}, opts = {}) {
1987
+ return this.http.json("/v1/studio/creatives", {
1988
+ query: {
1989
+ kind: query.kind,
1990
+ before: query.before,
1991
+ limit: query.limit
1992
+ },
1785
1993
  ext: opts.ext,
1786
1994
  signal: opts.signal
1787
- })).data ?? []];
1995
+ });
1996
+ }
1997
+ /**
1998
+ * Create a creative (`kind` + optional `title` / `doc`); without `doc` you get an empty document for the kind.
1999
+ * `brand_kit_id` applies one of your brand kits (`brandKits`) to version 1: `brand = { kitId, tokens }` + its logo.
2000
+ * `template` (+ `vars`, values by var key) starts from one of your templates (`templates`) instead of `doc`.
2001
+ */
2002
+ create(body, opts = {}) {
2003
+ return this.http.json("/v1/studio/creatives", {
2004
+ method: "POST",
2005
+ body,
2006
+ ext: opts.ext,
2007
+ signal: opts.signal,
2008
+ noRetry: true
2009
+ });
2010
+ }
2011
+ /** The document at the head (or `seq`) with signed `assets` (1 h URLs). */
2012
+ retrieve(id, query = {}, opts = {}) {
2013
+ return this.http.json(path$3(id), {
2014
+ query: { seq: query.seq },
2015
+ ext: opts.ext,
2016
+ signal: opts.signal
2017
+ });
2018
+ }
2019
+ /** Compact text outline (+ formats and vars) — the cheapest structure for a prompt. */
2020
+ outline(id, opts = {}) {
2021
+ return this.http.json(path$3(id, "/outline"), {
2022
+ ext: opts.ext,
2023
+ signal: opts.signal
2024
+ });
2025
+ }
2026
+ /** Node ids matching `query` (a string = text/name/id substring, or `{ text, type, sceneId, assetId, locked }`). */
2027
+ find(id, query, opts = {}) {
2028
+ return this.http.json(path$3(id, "/find"), {
2029
+ method: "POST",
2030
+ body: { query },
2031
+ ext: opts.ext,
2032
+ signal: opts.signal
2033
+ });
2034
+ }
2035
+ /** Full JSON of `ids` (scene ids return whole scenes) or of one `sceneId`. */
2036
+ subtree(id, body, opts = {}) {
2037
+ return this.http.json(path$3(id, "/subtree"), {
2038
+ method: "POST",
2039
+ body,
2040
+ ext: opts.ext,
2041
+ signal: opts.signal
2042
+ });
2043
+ }
2044
+ /**
2045
+ * Apply an op batch (all or nothing) authored against `baseSeq`. A stale base is rebased when the touched
2046
+ * targets did not change meanwhile; otherwise the call throws `CodaiError` 409 `stale` (reload and retry). Rejected
2047
+ * ops throw 400 with `code` (`invalid`, `not_found`, `locked`, `duplicate_id`).
2048
+ */
2049
+ edit(id, body, opts = {}) {
2050
+ return this.http.json(path$3(id, "/ops"), {
2051
+ method: "POST",
2052
+ body: {
2053
+ base_seq: body.baseSeq,
2054
+ ops: body.ops,
2055
+ ...body.intent !== void 0 ? { intent: body.intent } : {},
2056
+ ...body.author !== void 0 ? { author: body.author } : {},
2057
+ ...body.force !== void 0 ? { force: body.force } : {}
2058
+ },
2059
+ ext: opts.ext,
2060
+ signal: opts.signal,
2061
+ noRetry: true
2062
+ });
2063
+ }
2064
+ /** Version history, newest first (`beforeSeq` pages). */
2065
+ versions(id, query = {}, opts = {}) {
2066
+ return this.http.json(path$3(id, "/versions"), {
2067
+ query: {
2068
+ before_seq: query.beforeSeq,
2069
+ limit: query.limit
2070
+ },
2071
+ ext: opts.ext,
2072
+ signal: opts.signal
2073
+ });
2074
+ }
2075
+ /** New head whose document is version `seq`'s (undo / redo). */
2076
+ revert(id, seq, opts = {}) {
2077
+ return this.http.json(path$3(id, "/revert"), {
2078
+ method: "POST",
2079
+ body: { seq },
2080
+ ext: opts.ext,
2081
+ signal: opts.signal,
2082
+ noRetry: true
2083
+ });
2084
+ }
2085
+ /** New creative from version `seq` (default the head). */
2086
+ fork(id, body = {}, opts = {}) {
2087
+ return this.http.json(path$3(id, "/fork"), {
2088
+ method: "POST",
2089
+ body,
2090
+ ext: opts.ext,
2091
+ signal: opts.signal,
2092
+ noRetry: true
2093
+ });
2094
+ }
2095
+ /** Soft-delete the creative. */
2096
+ delete(id, opts = {}) {
2097
+ return this.http.json(path$3(id), {
2098
+ method: "DELETE",
2099
+ ext: opts.ext,
2100
+ signal: opts.signal
2101
+ });
2102
+ }
2103
+ /**
2104
+ * Contrast, safe area, empty text, missing assets, brand colours, platform safe zones and text floors, alt text,
2105
+ * missing captions, reading speed, flashing, missing / stale translations. Issues carry `format` / `fixable` /
2106
+ * `locale`; `fixable` counts them (`lintFix`). `locale` lints the translated document (adds
2107
+ * `text_overflow_locale`); 404 `Locale not found.` for an unknown locale.
2108
+ */
2109
+ lint(id, body = {}, opts = {}) {
2110
+ return this.http.json(path$3(id, "/lint"), {
2111
+ method: "POST",
2112
+ ...body.locale !== void 0 ? { body: { locale: body.locale } } : {},
2113
+ ext: opts.ext,
2114
+ signal: opts.signal
2115
+ });
2116
+ }
2117
+ /** Preview HTML (signed asset URLs) for `format` / one `scene` / a translation (`locale`). */
2118
+ compiled(id, query = {}, opts = {}) {
2119
+ return this.http.json(path$3(id, "/compiled"), {
2120
+ query: {
2121
+ format: query.format,
2122
+ scene: query.scene,
2123
+ locale: query.locale
2124
+ },
2125
+ ext: opts.ext,
2126
+ signal: opts.signal
2127
+ });
2128
+ }
2129
+ /**
2130
+ * Queue an MP4 render of the head (`codai-render`, HTTP 202, `cached: false`); poll `renders.retrieve(render_id)`.
2131
+ * When the same render already exists for this version / format / quality / fps you get it back at once
2132
+ * (HTTP 200, `cached: true`, `status: 'succeeded'`, no new charge). Unchanged scenes are reused either way.
2133
+ * `locale` renders a translation (404 `Locale not found.` when the creative has no such locale).
2134
+ * `ai_label` (`none` | `corner` | `end_card`, EU AI Act art. 50(4)) burns a visible AI label into the video; omitted =
2135
+ * `corner` when the creative uses TTS narration or AI images, else `none` (`none` with narration: 400 `ai_label_required`).
2136
+ */
2137
+ render(id, body = {}, opts = {}) {
2138
+ return this.http.json(path$3(id, "/render"), {
2139
+ method: "POST",
2140
+ body,
2141
+ ext: opts.ext,
2142
+ signal: opts.signal,
2143
+ noRetry: true
2144
+ });
2145
+ }
2146
+ /**
2147
+ * PNG still frames at up to 6 times (`t_ms`). `exact: false` (default) screenshots the compiled HTML; `exact: true`
2148
+ * cuts them from a draft render of the covering scenes. Waits up to ~90 s: frames (`status: 'succeeded'`) or a
2149
+ * running job (`status: 'running'`) to poll with `frameJob(id, frame_job_id)`. Cached frames are free; 60 frame
2150
+ * jobs per UTC day are free, then billed (`billed_micro_usd`).
2151
+ */
2152
+ frame(id, body, opts = {}) {
2153
+ return this.http.json(path$3(id, "/frame"), {
2154
+ method: "POST",
2155
+ body,
2156
+ ext: opts.ext,
2157
+ signal: opts.signal,
2158
+ noRetry: true
2159
+ });
2160
+ }
2161
+ /**
2162
+ * Turn a comment pinned on a frame (`t_ms`, optional `node_id` / `scene_id`) into an edit: one bounded `codai`
2163
+ * model turn proposes ops, applied like `edit` against `base_seq` (rebased when possible, 409 `stale` else).
2164
+ * 422 `no_edit` when the model made no edit (its answer in `error.text`); `apply: false` only proposes the ops.
2165
+ * Token-metered like any `codai` text call.
2166
+ */
2167
+ comment(id, body, opts = {}) {
2168
+ return this.http.json(path$3(id, "/comments"), {
2169
+ method: "POST",
2170
+ body,
2171
+ ext: opts.ext,
2172
+ signal: opts.signal,
2173
+ noRetry: true
2174
+ });
2175
+ }
2176
+ /**
2177
+ * Generate A/B variants: one bounded `codai` model turn proposes `count` (default 3) variants changing only
2178
+ * `focus` (default hook / title / cta); each becomes a fork of the creative at `base_seq` with the ops applied, plus
2179
+ * a queued draft render (`render: false` to skip; poll `renders.retrieve(render_id)`). The original is unchanged
2180
+ * until `pickVariant`. 422 `no_edit` when no valid variant came back, 504 `timeout` after 90 s. Token-metered.
2181
+ */
2182
+ variants(id, body, opts = {}) {
2183
+ return this.http.json(path$3(id, "/variants"), {
2184
+ method: "POST",
2185
+ body,
2186
+ ext: opts.ext,
2187
+ signal: opts.signal,
2188
+ noRetry: true
2189
+ });
2190
+ }
2191
+ /** The latest variant group of a creative (`group_id: null` when none) with statuses and stored render state. */
2192
+ listVariants(id, opts = {}) {
2193
+ return this.http.json(path$3(id, "/variants"), {
2194
+ ext: opts.ext,
2195
+ signal: opts.signal
2196
+ });
2197
+ }
2198
+ /**
2199
+ * Pick the winner: its ops are applied to the original against `base_seq` (rebased when possible, 409 `stale`
2200
+ * else); the winner is marked `winner`, the rest of its group `rejected`.
2201
+ */
2202
+ pickVariant(id, variantId, body, opts = {}) {
2203
+ return this.http.json(path$3(id, `/variants/${encodeURIComponent(variantId)}/pick`), {
2204
+ method: "POST",
2205
+ body,
2206
+ ext: opts.ext,
2207
+ signal: opts.signal,
2208
+ noRetry: true
2209
+ });
2210
+ }
2211
+ /**
2212
+ * Save the creative (at `seq`, default the head) as a private template: each `vars` entry turns a text node's text
2213
+ * (`prop: 'text'`) or an image node's asset (`prop: 'image'`) into a variable whose default is the current value.
2214
+ * 400 `node_not_found` / `invalid_pick` / `duplicate_key`. Free.
2215
+ */
2216
+ saveTemplate(id, body, opts = {}) {
2217
+ return this.http.json(path$3(id, "/template"), {
2218
+ method: "POST",
2219
+ body,
2220
+ ext: opts.ext,
2221
+ signal: opts.signal,
2222
+ noRetry: true
2223
+ });
2224
+ }
2225
+ /**
2226
+ * Queue an FCPXML export of a video creative (`seq`, default the head; `format`, default the first 1920×1080 /
2227
+ * 1080×1920 / 1080×1080 format): a zip with `project.fcpxml` + per-scene MP4 segments + audio, for Final Cut Pro,
2228
+ * DaVinci Resolve or Premiere. Resolves to the queued export; poll it with `exports.wait(e.id)`. Only newly
2229
+ * rendered seconds are billed (final render price). 400 `unsupported_kind` / `unsupported_format` / `too_long`.
2230
+ */
2231
+ exportFcpxml(id, query = {}, opts = {}) {
2232
+ return this.http.json(path$3(id, "/export.fcpxml"), {
2233
+ query: {
2234
+ format: query.format,
2235
+ seq: query.seq
2236
+ },
2237
+ ext: opts.ext,
2238
+ signal: opts.signal,
2239
+ noRetry: true
2240
+ });
2241
+ }
2242
+ /**
2243
+ * Export a video creative as a Lottie animation (`seq`, default the head; `format`, default the document's default
2244
+ * format, or `formats: 'all'`; `container: 'json'` (default, Bodymovin JSON with embedded images) or `'dotlottie'`).
2245
+ * Free and synchronous: resolves to an export that is already `succeeded` with a signed `url` (valid 1 h) and the
2246
+ * fidelity report in `warnings` (video, chart, HTML block, table, cell grid and audio nodes are not exported).
2247
+ * 400 `unsupported_kind` / `invalid_request`, 413 `too_large` (over 20 MB).
2248
+ */
2249
+ exportLottie(id, query = {}, opts = {}) {
2250
+ return this.http.json(path$3(id, "/export.lottie"), {
2251
+ query: lottieQuery(query),
2252
+ ext: opts.ext,
2253
+ signal: opts.signal,
2254
+ noRetry: true
2255
+ });
2256
+ }
2257
+ /**
2258
+ * The Lottie file itself (`download=1`, nothing stored): `application/json` for one Bodymovin JSON, `application/zip`
2259
+ * for a dotLottie archive or a zip of JSON files (`formats: 'all'`). Same options and errors as `exportLottie`. Free.
2260
+ */
2261
+ async downloadLottie(id, query = {}, opts = {}) {
2262
+ const res = await this.http.request(path$3(id, "/export.lottie"), {
2263
+ query: {
2264
+ ...lottieQuery(query),
2265
+ download: "1"
2266
+ },
2267
+ ext: opts.ext,
2268
+ signal: opts.signal
2269
+ });
2270
+ const m = /filename="([^"]+)"/i.exec(res.headers.get("content-disposition") ?? "");
2271
+ return {
2272
+ bytes: new Uint8Array(await res.arrayBuffer()),
2273
+ filename: m ? m[1] : null,
2274
+ contentType: res.headers.get("content-type")
2275
+ };
2276
+ }
2277
+ /**
2278
+ * Turn one of your Studio documents (deck, doc, sheet) into an editable creative — slides become scenes with a
2279
+ * `layout` and speaker `notes`, doc pages a `flow` group, sheets a `cell_grid`; nodes carry semantic `role`s.
2280
+ * Idempotent: a document that already has a creative resolves to it (`existing: true`). Free. 404 unknown document,
2281
+ * 409 `document_spec_missing`, 400 `invalid_spec`, 413 `too_large`.
2282
+ */
2283
+ fromDocument(documentId, opts = {}) {
2284
+ return this.http.json(`/v1/studio/documents/${encodeURIComponent(documentId)}/creative`, {
2285
+ method: "POST",
2286
+ ext: opts.ext,
2287
+ signal: opts.signal,
2288
+ noRetry: true
2289
+ });
2290
+ }
2291
+ /**
2292
+ * Build a deck / doc / sheet creative (at `seq`, default the head) into a PPTX / DOCX / XLSX — a new version of its
2293
+ * Studio document (`document`, exactly the `POST /v1/studio/documents` body). Converter notes come back in
2294
+ * `warnings`. The file is free; `preview: true` also queues a billed preview (poll it with
2295
+ * `documents.waitForPreview`). 400 `not_supported_for_kind` (video / image) or `invalid_spec`.
2296
+ */
2297
+ build(id, body = {}, opts = {}) {
2298
+ return this.http.json(path$3(id, "/build"), {
2299
+ method: "POST",
2300
+ body: stripUndefined(body),
2301
+ ext: opts.ext,
2302
+ signal: opts.signal,
2303
+ noRetry: true
2304
+ });
2305
+ }
2306
+ /**
2307
+ * Re-apply a brand kit (`brand_kit_id`) or a flat token map (`tokens`) to the creative as one new version: literal
2308
+ * colours equal to the old brand become token refs, `snap: true` maps every other colour to the nearest kit colour,
2309
+ * `fonts` (default true) sets heading / body font refs by role, locked nodes are skipped unless `force`. The kit
2310
+ * logo is registered too. `base_seq` defaults to the head (rebased like `edit`, 409 `stale` else). Free.
2311
+ */
2312
+ restyle(id, body, opts = {}) {
2313
+ return this.http.json(path$3(id, "/restyle"), {
2314
+ method: "POST",
2315
+ body: stripUndefined(body),
2316
+ ext: opts.ext,
2317
+ signal: opts.signal,
2318
+ noRetry: true
2319
+ });
2320
+ }
2321
+ /**
2322
+ * Auto-captions: transcribe a voice clip (`clip_id`, default the first voice clip) word by word and add or update a
2323
+ * captions node (`preset`, default `bold-pill`) as one new version. Words are cached on the asset (free next time
2324
+ * unless `retranscribe`); `script` (default the narration of a codai speech asset) corrects the spelling. A fresh
2325
+ * transcription is billed at the speech-to-text rate (`cost_micro_usd`). Video creatives only (400
2326
+ * `unsupported_kind`); 403 `residency_unavailable`, 503 `transcription_unavailable`.
2327
+ */
2328
+ captions(id, body = {}, opts = {}) {
2329
+ return this.http.json(path$3(id, "/captions"), {
2330
+ method: "POST",
2331
+ body: stripUndefined(body),
2332
+ ext: opts.ext,
2333
+ signal: opts.signal,
2334
+ noRetry: true
2335
+ });
2336
+ }
2337
+ /** The captions as SubRip text on the document timeline (`node_id`, `seq` optional); 404 without captions. Free. */
2338
+ async captionsSrt(id, query = {}, opts = {}) {
2339
+ return (await this.http.request(path$3(id, "/captions.srt"), {
2340
+ query: {
2341
+ node_id: query.node_id,
2342
+ seq: query.seq,
2343
+ locale: query.locale
2344
+ },
2345
+ ext: opts.ext,
2346
+ signal: opts.signal
2347
+ })).text();
2348
+ }
2349
+ /** The captions as WebVTT text on the document timeline (`node_id`, `seq` optional); 404 without captions. Free. */
2350
+ async captionsVtt(id, query = {}, opts = {}) {
2351
+ return (await this.http.request(path$3(id, "/captions.vtt"), {
2352
+ query: {
2353
+ node_id: query.node_id,
2354
+ seq: query.seq,
2355
+ locale: query.locale
2356
+ },
2357
+ ext: opts.ext,
2358
+ signal: opts.signal
2359
+ })).text();
2360
+ }
2361
+ /**
2362
+ * Adapt to platforms (`tiktok`, `reels`, `shorts`, `feed-square`, `feed-portrait`, `youtube`): one format per
2363
+ * platform in one new version, text kept inside each platform's safe zone and above its legible size.
2364
+ * `focal: 'vision'` (token-metered) finds the focal point of full-bleed images; it fails open. Free otherwise.
2365
+ */
2366
+ adapt(id, body, opts = {}) {
2367
+ return this.http.json(path$3(id, "/adapt"), {
2368
+ method: "POST",
2369
+ body: stripUndefined(body),
2370
+ ext: opts.ext,
2371
+ signal: opts.signal,
2372
+ noRetry: true
2373
+ });
2374
+ }
2375
+ /**
2376
+ * Fix lint issues as one new version: deterministic fixes (free) for `off_brand_color`, `text_too_small`,
2377
+ * `outside_platform_safe_zone` and `flashing` (`codes` limits them); `agent: true` (token-metered) gives the rest
2378
+ * to one `codai` turn. Nothing to fix: the current `seq`, empty `fixed`, no new version.
2379
+ */
2380
+ lintFix(id, body = {}, opts = {}) {
2381
+ return this.http.json(path$3(id, "/lint/fix"), {
2382
+ method: "POST",
2383
+ body: stripUndefined(body),
2384
+ ext: opts.ext,
2385
+ signal: opts.signal,
2386
+ noRetry: true
2387
+ });
2388
+ }
2389
+ /**
2390
+ * The tweak panel model: one control per variable (stored `meta.controls` entry or derived from the type). Change
2391
+ * values with a `setVar` op and controls with a `setControl` op (`edit`). Free.
2392
+ */
2393
+ controls(id, opts = {}) {
2394
+ return this.http.json(path$3(id, "/controls"), {
2395
+ ext: opts.ext,
2396
+ signal: opts.signal
2397
+ });
2398
+ }
2399
+ /**
2400
+ * Localisation state: source locale, glossary, unit count and per locale translated / missing / stale / voice.
2401
+ * With `locale` (+ `units`, default 1) also the units of that locale (paged with `offset` / `limit` ≤ 500). Free.
2402
+ */
2403
+ locales(id, query = {}, opts = {}) {
2404
+ return this.http.json(path$3(id, "/locales"), {
2405
+ query: {
2406
+ locale: query.locale,
2407
+ units: query.units,
2408
+ offset: query.offset,
2409
+ limit: query.limit
2410
+ },
2411
+ ext: opts.ext,
2412
+ signal: opts.signal
2413
+ });
2414
+ }
2415
+ /**
2416
+ * Translate every text into up to 10 BCP-47 `locales` as per-locale overrides (one new version, author `agent`).
2417
+ * Token-metered `codai` turns; `glossary` terms and the brand kit name stay verbatim, `tone` picks the address,
2418
+ * `only_missing` (default true) skips fresh translations, `voice: true` (video, billed) narrates voice clips again.
2419
+ * 400 `nothing_to_translate`; 503 `localize_unavailable` when every locale failed.
2420
+ */
2421
+ localize(id, body, opts = {}) {
2422
+ return this.http.json(path$3(id, "/localize"), {
2423
+ method: "POST",
2424
+ body: stripUndefined(body),
2425
+ ext: opts.ext,
2426
+ signal: opts.signal,
2427
+ noRetry: true
2428
+ });
2429
+ }
2430
+ /**
2431
+ * Save `locale` as a new standalone creative (translations applied, overrides dropped, `fork_of` recorded; default
2432
+ * title `<title> (<locale>)`). 404 `Locale not found.`. Free (HTTP 201).
2433
+ */
2434
+ forkLocale(id, locale, body = {}, opts = {}) {
2435
+ return this.http.json(path$3(id, `/locales/${encodeURIComponent(locale)}/fork`), {
2436
+ method: "POST",
2437
+ body: stripUndefined(body),
2438
+ ext: opts.ext,
2439
+ signal: opts.signal,
2440
+ noRetry: true
2441
+ });
2442
+ }
2443
+ /**
2444
+ * Create a public link: `view` (read-only preview of version `seq` or the head; `allow_remix` default false) or
2445
+ * `review` (comments by name, no account; `can_approve` lets the holder approve). The `token` and `url` are shown
2446
+ * only in this answer (HTTP 201). 400 `unknown_seq`; 409 `too_many_shares` (20 active links). Free.
2447
+ */
2448
+ createShare(id, body, opts = {}) {
2449
+ return this.http.json(path$3(id, "/shares"), {
2450
+ method: "POST",
2451
+ body: stripUndefined(body),
2452
+ ext: opts.ext,
2453
+ signal: opts.signal,
2454
+ noRetry: true
2455
+ });
2456
+ }
2457
+ /** The active links (not revoked, not expired), newest first; `url` is always null. Free. */
2458
+ listShares(id, opts = {}) {
2459
+ return this.http.json(path$3(id, "/shares"), {
2460
+ ext: opts.ext,
2461
+ signal: opts.signal
2462
+ });
2463
+ }
2464
+ /** Revoke a link: it answers 404 from now on. 404 when unknown or already revoked. Free. */
2465
+ async revokeShare(id, shareId, opts = {}) {
2466
+ await this.http.request(path$3(id, `/shares/${encodeURIComponent(shareId)}`), {
2467
+ method: "DELETE",
2468
+ ext: opts.ext,
2469
+ signal: opts.signal
2470
+ });
2471
+ }
2472
+ /**
2473
+ * The review state: `status` (`draft` → `in_review` → `approved` | `changes_requested`), requested / approved
2474
+ * version (`approved_is_head` false once the creative changed), decider and thread counts. Free.
2475
+ */
2476
+ review(id, opts = {}) {
2477
+ return this.http.json(path$3(id, "/review"), {
2478
+ ext: opts.ext,
2479
+ signal: opts.signal
2480
+ });
2481
+ }
2482
+ /** Send the head to review (`in_review`, earlier decision cleared) so approver links can decide. Free. */
2483
+ requestReview(id, opts = {}) {
2484
+ return this.http.json(path$3(id, "/review"), {
2485
+ method: "POST",
2486
+ body: { action: "request" },
2487
+ ext: opts.ext,
2488
+ signal: opts.signal
2489
+ });
2490
+ }
2491
+ /** Back to `draft` (decision cleared, comments kept). Free. */
2492
+ resetReview(id, opts = {}) {
2493
+ return this.http.json(path$3(id, "/review"), {
2494
+ method: "POST",
2495
+ body: { action: "reset" },
2496
+ ext: opts.ext,
2497
+ signal: opts.signal
2498
+ });
2499
+ }
2500
+ /** Comment threads, newest first (≤ 200), replies oldest first; `status` `open` | `resolved` | `all`. Free. */
2501
+ reviewThreads(id, query = {}, opts = {}) {
2502
+ return this.http.json(path$3(id, "/review/threads"), {
2503
+ query: { status: query.status },
2504
+ ext: opts.ext,
2505
+ signal: opts.signal
2506
+ });
2507
+ }
2508
+ /**
2509
+ * Start a thread as the owner, optionally anchored to `node_id` / `scene_id` / `t_ms` (checked against the head:
2510
+ * 400 `unknown_node` / `unknown_scene`; HTTP 201). 409 `too_many_comments`. Free.
2511
+ */
2512
+ createReviewThread(id, body, opts = {}) {
2513
+ return this.http.json(path$3(id, "/review/threads"), {
2514
+ method: "POST",
2515
+ body: stripUndefined(body),
2516
+ ext: opts.ext,
2517
+ signal: opts.signal,
2518
+ noRetry: true
2519
+ });
2520
+ }
2521
+ /** Reply in a thread as the owner (HTTP 201) — returns the whole thread. Free. */
2522
+ replyReviewThread(id, threadId, body, opts = {}) {
2523
+ return this.http.json(path$3(id, `/review/threads/${encodeURIComponent(threadId)}/replies`), {
2524
+ method: "POST",
2525
+ body: { body: body.body },
2526
+ ext: opts.ext,
2527
+ signal: opts.signal,
2528
+ noRetry: true
2529
+ });
2530
+ }
2531
+ /** Resolve a thread. Free. */
2532
+ resolveReviewThread(id, threadId, opts = {}) {
2533
+ return this.http.json(path$3(id, `/review/threads/${encodeURIComponent(threadId)}/resolve`), {
2534
+ method: "POST",
2535
+ ext: opts.ext,
2536
+ signal: opts.signal
2537
+ });
2538
+ }
2539
+ /** Reopen a resolved thread. Free. */
2540
+ reopenReviewThread(id, threadId, opts = {}) {
2541
+ return this.http.json(path$3(id, `/review/threads/${encodeURIComponent(threadId)}/reopen`), {
2542
+ method: "POST",
2543
+ ext: opts.ext,
2544
+ signal: opts.signal
2545
+ });
2546
+ }
2547
+ /** Delete any comment (owner moderation; deleting a root hides the thread). 404 when unknown. Free. */
2548
+ async deleteReviewComment(id, commentId, opts = {}) {
2549
+ await this.http.request(path$3(id, `/review/comments/${encodeURIComponent(commentId)}`), {
2550
+ method: "DELETE",
2551
+ ext: opts.ext,
2552
+ signal: opts.signal
2553
+ });
2554
+ }
2555
+ /** Poll a frame job: frames when done (`status: 'succeeded'`), `status: 'running'` meanwhile; 404 unknown job. */
2556
+ frameJob(id, jobId, opts = {}) {
2557
+ return this.http.json(path$3(id, `/frames/${encodeURIComponent(jobId)}`), {
2558
+ ext: opts.ext,
2559
+ signal: opts.signal
2560
+ });
2561
+ }
2562
+ };
2563
+
2564
+ //#endregion
2565
+ //#region src/resources/brand-kits.ts
2566
+ const path$2 = (id, tail = "") => `/v1/studio/brand-kits/${encodeURIComponent(id)}${tail}`;
2567
+ var BrandKits = class {
2568
+ http;
2569
+ constructor(http) {
2570
+ this.http = http;
2571
+ }
2572
+ /**
2573
+ * Create a kit you define: flat `tokens` (the 5 colours `#rrggbb`, optional fonts) or a DTCG document in `dtcg`
2574
+ * (import) — exactly one. 400 `invalid_tokens` (with `details.issues`) for an invalid DTCG document, 404 when
2575
+ * `logo_asset_id` is not one of your ready image assets. Free.
2576
+ */
2577
+ create(body, opts = {}) {
2578
+ return this.http.json("/v1/studio/brand-kits", {
2579
+ method: "POST",
2580
+ body,
2581
+ ext: opts.ext,
2582
+ signal: opts.signal,
2583
+ noRetry: true
2584
+ });
2585
+ }
2586
+ /**
2587
+ * Edit a kit: `tokens` is merged onto the current kit, `dtcg` replaces the whole document (not both),
2588
+ * `logo_asset_id: null` removes the logo. Creatives keep their tokens until `creatives.restyle`. Free.
2589
+ */
2590
+ update(id, body, opts = {}) {
2591
+ return this.http.json(path$2(id), {
2592
+ method: "PATCH",
2593
+ body,
2594
+ ext: opts.ext,
2595
+ signal: opts.signal,
2596
+ noRetry: true
2597
+ });
2598
+ }
2599
+ /** The kit as a DTCG 2025.10 JSON document (`$extensions['ro.codai']` = kit id, name, logo asset id). Free. */
2600
+ exportDtcg(id, opts = {}) {
2601
+ return this.http.json(path$2(id, "/dtcg"), {
2602
+ ext: opts.ext,
2603
+ signal: opts.signal
2604
+ });
2605
+ }
2606
+ /**
2607
+ * Extract a brand kit from a public `https` page (`{ url }`) or from one of your logo images
2608
+ * (`{ logo_asset_id }`, PNG / JPEG / WebP up to 5 MB; it becomes the kit logo): palette (primary, secondary, accent,
2609
+ * background, text) and heading / body fonts. One bounded `codai` model call (token-metered); 400 `url_blocked` for
2610
+ * private hosts, 400 `unsupported_media` for a bad logo, 422 `fetch_failed` / `extract_failed`, 504 `timeout`.
2611
+ */
2612
+ extract(body, opts = {}) {
2613
+ return this.http.json("/v1/studio/brand-kits/extract", {
2614
+ method: "POST",
2615
+ body,
2616
+ ext: opts.ext,
2617
+ signal: opts.signal,
2618
+ noRetry: true
2619
+ });
2620
+ }
2621
+ /** Your brand kits, newest first (`limit` 1–100, default 50). Free. */
2622
+ list(query = {}, opts = {}) {
2623
+ return this.http.json("/v1/studio/brand-kits", {
2624
+ query: { limit: query.limit },
2625
+ ext: opts.ext,
2626
+ signal: opts.signal
2627
+ });
2628
+ }
2629
+ /** One kit with a signed logo URL (1 h), its `dtcg` and the WCAG `contrast` pairs. Free. */
2630
+ retrieve(id, opts = {}) {
2631
+ return this.http.json(path$2(id), {
2632
+ ext: opts.ext,
2633
+ signal: opts.signal
2634
+ });
2635
+ }
2636
+ /** Delete a kit (creatives keep their tokens; the logo asset stays). Free. */
2637
+ delete(id, opts = {}) {
2638
+ return this.http.json(path$2(id), {
2639
+ method: "DELETE",
2640
+ ext: opts.ext,
2641
+ signal: opts.signal
2642
+ });
2643
+ }
2644
+ };
2645
+
2646
+ //#endregion
2647
+ //#region src/resources/templates.ts
2648
+ const path$1 = (id) => `/v1/studio/templates/${encodeURIComponent(id)}`;
2649
+ var Templates = class {
2650
+ http;
2651
+ constructor(http) {
2652
+ this.http = http;
2653
+ }
2654
+ /** Your templates, newest first (`kind` filter, `limit` 1–100, default 50); without `doc`. Free. */
2655
+ list(query = {}, opts = {}) {
2656
+ return this.http.json("/v1/studio/templates", {
2657
+ query: {
2658
+ kind: query.kind,
2659
+ limit: query.limit
2660
+ },
2661
+ ext: opts.ext,
2662
+ signal: opts.signal
2663
+ });
2664
+ }
2665
+ /** One template with its variables and `doc`. Free. */
2666
+ retrieve(id, opts = {}) {
2667
+ return this.http.json(path$1(id), {
2668
+ ext: opts.ext,
2669
+ signal: opts.signal
2670
+ });
2671
+ }
2672
+ /** Delete a template (creatives made from it are not affected). Free. */
2673
+ delete(id, opts = {}) {
2674
+ return this.http.json(path$1(id), {
2675
+ method: "DELETE",
2676
+ ext: opts.ext,
2677
+ signal: opts.signal
2678
+ });
2679
+ }
2680
+ };
2681
+
2682
+ //#endregion
2683
+ //#region src/resources/batches.ts
2684
+ const BATCH_DONE = [
2685
+ "completed",
2686
+ "failed",
2687
+ "cancelled"
2688
+ ];
2689
+ const path = (id, tail = "") => `/v1/studio/batches/${encodeURIComponent(id)}${tail}`;
2690
+ function abortableSleep$1(ms, signal) {
2691
+ return new Promise((resolve, reject) => {
2692
+ if (signal?.aborted) return reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted"));
2693
+ const t = setTimeout(() => {
2694
+ signal?.removeEventListener("abort", onAbort);
2695
+ resolve();
2696
+ }, ms);
2697
+ const onAbort = () => {
2698
+ clearTimeout(t);
2699
+ reject(signal?.reason ?? /* @__PURE__ */ new Error("Aborted"));
2700
+ };
2701
+ signal?.addEventListener("abort", onAbort, { once: true });
2702
+ });
2703
+ }
2704
+ var Batches = class {
2705
+ http;
2706
+ constructor(http) {
2707
+ this.http = http;
2708
+ }
2709
+ /**
2710
+ * Create a batch: rows are validated (invalid rows are stored as `failed`) and run in the background; poll `get`
2711
+ * or `wait`. 400 `invalid_rows` when every row is invalid. Free (translations and renders are billed as usual).
2712
+ */
2713
+ async create(body, opts = {}) {
2714
+ return this.http.json("/v1/studio/batches", {
2715
+ method: "POST",
2716
+ body: stripUndefined({
2717
+ ...body,
2718
+ dry_run: false
2719
+ }),
2720
+ ext: opts.ext,
2721
+ signal: opts.signal,
2722
+ noRetry: true
2723
+ });
2724
+ }
2725
+ /** Validate only (`dry_run: true`): the mapping, row errors, a 3-row preview and an estimate; nothing stored. Free. */
2726
+ dryRun(body, opts = {}) {
2727
+ return this.http.json("/v1/studio/batches", {
2728
+ method: "POST",
2729
+ body: stripUndefined({
2730
+ ...body,
2731
+ dry_run: true
2732
+ }),
2733
+ ext: opts.ext,
2734
+ signal: opts.signal
2735
+ });
2736
+ }
2737
+ /** Your batches, newest first (`limit` 1–50, `before` = the previous `next_before`). Free. */
2738
+ list(query = {}, opts = {}) {
2739
+ return this.http.json("/v1/studio/batches", {
2740
+ query: {
2741
+ limit: query.limit,
2742
+ before: query.before
2743
+ },
2744
+ ext: opts.ext,
2745
+ signal: opts.signal
2746
+ });
2747
+ }
2748
+ /** The batch (`rows: 1` adds rows; `status`, `offset`, `limit` ≤ 100). Each poll advances it a little. Free. */
2749
+ get(id, query = {}, opts = {}) {
2750
+ return this.http.json(path(id), {
2751
+ query: {
2752
+ rows: query.rows,
2753
+ status: query.status,
2754
+ offset: query.offset,
2755
+ limit: query.limit
2756
+ },
2757
+ ext: opts.ext,
2758
+ signal: opts.signal
2759
+ });
2760
+ }
2761
+ /** Stop the batch; rows not started become `skipped`. 409 `not_cancellable` when already finished. Free. */
2762
+ cancel(id, opts = {}) {
2763
+ return this.http.json(path(id, "/cancel"), {
2764
+ method: "POST",
2765
+ ext: opts.ext,
2766
+ signal: opts.signal,
2767
+ noRetry: true
2768
+ });
2769
+ }
2770
+ /** Queue the failed rows again (≤ 3 attempts each). 409 `nothing_to_retry`. Free. */
2771
+ retry(id, opts = {}) {
2772
+ return this.http.json(path(id, "/retry"), {
2773
+ method: "POST",
2774
+ ext: opts.ext,
2775
+ signal: opts.signal,
2776
+ noRetry: true
2777
+ });
2778
+ }
2779
+ /** The original CSV plus `creative_id`, `status`, `error`, `render_url` per row (formula-safe). Free. */
2780
+ async exportCsv(id, opts = {}) {
2781
+ return (await this.http.request(path(id, "/export.csv"), {
2782
+ ext: opts.ext,
2783
+ signal: opts.signal
2784
+ })).text();
2785
+ }
2786
+ /**
2787
+ * Start building a ZIP of the finished renders (202, `zip.status: 'building'`; unchanged when already building or
2788
+ * ready). Poll `get` until `zip.status` is `ready` (signed `zip.url`). 409 `no_renders`. Free.
2789
+ */
2790
+ zip(id, opts = {}) {
2791
+ return this.http.json(path(id, "/zip"), {
2792
+ method: "POST",
2793
+ ext: opts.ext,
2794
+ signal: opts.signal,
2795
+ noRetry: true
2796
+ });
2797
+ }
2798
+ /**
2799
+ * Poll `get` every `intervalMs` (default 3 s) until the batch is `completed`, `failed` or `cancelled` and resolve
2800
+ * with it. Throws when it is not done within `timeoutMs` (default 10 min) or when `signal` aborts.
2801
+ */
2802
+ async wait(id, opts = {}) {
2803
+ const { intervalMs = 3e3, timeoutMs = 6e5, signal, ext } = opts;
2804
+ const deadline = Date.now() + timeoutMs;
2805
+ for (;;) {
2806
+ const { batch } = await this.get(id, {}, {
2807
+ ext,
2808
+ signal
2809
+ });
2810
+ if (BATCH_DONE.includes(batch.status)) return batch;
2811
+ if (Date.now() + intervalMs > deadline) throw new Error(`codai batch ${id} did not finish within ${timeoutMs} ms`);
2812
+ await abortableSleep$1(intervalMs, signal);
2813
+ }
2814
+ }
2815
+ };
2816
+
2817
+ //#endregion
2818
+ //#region src/resources/shares.ts
2819
+ const SHARE_TOKEN_RE = /^[A-Za-z0-9_-]{43}$/;
2820
+ /**
2821
+ * The share token in `input`: a raw token, or any `https://…/s/<token>` / `…/r/<token>` URL (query and fragment
2822
+ * ignored). Trims; `null` for anything else (same rule as the gateway and the apps).
2823
+ */
2824
+ function shareTokenFrom(input) {
2825
+ const s = input.trim();
2826
+ if (SHARE_TOKEN_RE.test(s)) return s;
2827
+ let url;
2828
+ try {
2829
+ url = new URL(s);
2830
+ } catch {
2831
+ return null;
2832
+ }
2833
+ if (url.protocol !== "https:" && url.protocol !== "http:") return null;
2834
+ const parts = url.pathname.split("/").filter(Boolean);
2835
+ if (parts.length < 2) return null;
2836
+ const kind = parts[parts.length - 2];
2837
+ const token = parts[parts.length - 1];
2838
+ return (kind === "s" || kind === "r") && SHARE_TOKEN_RE.test(token) ? token : null;
2839
+ }
2840
+ function tokenOf(tokenOrUrl) {
2841
+ const token = shareTokenFrom(tokenOrUrl);
2842
+ if (!token) throw new TypeError("codai: not a share link or token (expected …/s/<token> or …/r/<token>)");
2843
+ return token;
2844
+ }
2845
+ const review = (tokenOrUrl, tail) => `/v1/public/studio/reviews/${encodeURIComponent(tokenOf(tokenOrUrl))}${tail}`;
2846
+ const thread = (tokenOrUrl, threadId, tail) => review(tokenOrUrl, `/threads/${encodeURIComponent(threadId)}${tail}`);
2847
+ var Shares = class {
2848
+ http;
2849
+ constructor(http) {
2850
+ this.http = http;
2851
+ }
2852
+ /**
2853
+ * The shared creative: title, kind, version, formats, locales and the compiled preview HTML of `format` /
2854
+ * `locale` (null for images); review links add the review state and every thread. 404 for unknown, revoked or
2855
+ * expired links. No key needed.
2856
+ */
2857
+ get(tokenOrUrl, query = {}, opts = {}) {
2858
+ return this.http.json(`/v1/public/studio/shares/${encodeURIComponent(tokenOf(tokenOrUrl))}`, {
2859
+ query: {
2860
+ format: query.format,
2861
+ locale: query.locale
2862
+ },
2863
+ ext: opts.ext,
2864
+ signal: opts.signal
2865
+ });
2866
+ }
2867
+ /**
2868
+ * Copy the version a `view` link shows into a new creative of yours (the owner's ready assets are copied, the
2869
+ * foreign brand kit dropped; HTTP 201). 404 for review links or links without remix; 413 `remix_too_large`. Free.
2870
+ */
2871
+ remix(tokenOrUrl, body = {}, opts = {}) {
2872
+ return this.http.json(`/v1/studio/shares/${encodeURIComponent(tokenOf(tokenOrUrl))}/remix`, {
2873
+ method: "POST",
2874
+ body: stripUndefined(body),
2875
+ ext: opts.ext,
2876
+ signal: opts.signal,
2877
+ noRetry: true
2878
+ });
2879
+ }
2880
+ /** Start a thread through a review link (`name`, `body`, optional anchor; HTTP 201). 400 `invalid_name`. */
2881
+ comment(tokenOrUrl, body, opts = {}) {
2882
+ return this.http.json(review(tokenOrUrl, "/threads"), {
2883
+ method: "POST",
2884
+ body: stripUndefined(body),
2885
+ ext: opts.ext,
2886
+ signal: opts.signal,
2887
+ noRetry: true
2888
+ });
2889
+ }
2890
+ /** Reply in a thread through a review link (`name`, `body`; HTTP 201) — returns the whole thread. */
2891
+ reply(tokenOrUrl, threadId, body, opts = {}) {
2892
+ return this.http.json(thread(tokenOrUrl, threadId, "/replies"), {
2893
+ method: "POST",
2894
+ body: stripUndefined(body),
2895
+ ext: opts.ext,
2896
+ signal: opts.signal,
2897
+ noRetry: true
2898
+ });
2899
+ }
2900
+ /** Resolve a thread through a review link (`resolved_by` = `name`). */
2901
+ resolve(tokenOrUrl, threadId, body, opts = {}) {
2902
+ return this.http.json(thread(tokenOrUrl, threadId, "/resolve"), {
2903
+ method: "POST",
2904
+ body: { name: body.name },
2905
+ ext: opts.ext,
2906
+ signal: opts.signal
2907
+ });
2908
+ }
2909
+ /** Reopen a resolved thread through a review link. */
2910
+ reopen(tokenOrUrl, threadId, body, opts = {}) {
2911
+ return this.http.json(thread(tokenOrUrl, threadId, "/reopen"), {
2912
+ method: "POST",
2913
+ body: { name: body.name },
2914
+ ext: opts.ext,
2915
+ signal: opts.signal
2916
+ });
2917
+ }
2918
+ /**
2919
+ * Approve or request changes (approver review links only). 403 `not_an_approver`, 409 `review_not_open`, 409
2920
+ * `stale` (with `head_seq`) when `seq` is not the head. Returns the new review state.
2921
+ */
2922
+ decide(tokenOrUrl, body, opts = {}) {
2923
+ return this.http.json(review(tokenOrUrl, "/decision"), {
2924
+ method: "POST",
2925
+ body: stripUndefined(body),
2926
+ ext: opts.ext,
2927
+ signal: opts.signal,
2928
+ noRetry: true
2929
+ });
2930
+ }
2931
+ };
2932
+
2933
+ //#endregion
2934
+ //#region src/resources/voice-revocations.ts
2935
+ var VoiceRevocations = class {
2936
+ http;
2937
+ constructor(http) {
2938
+ this.http = http;
2939
+ }
2940
+ /** Store a takedown ticket for manual review (HTTP 202). Rate-limited per IP; never retried. */
2941
+ create(body, opts = {}) {
2942
+ return this.http.json("/v1/studio/voice-revocations", {
2943
+ method: "POST",
2944
+ body: stripUndefined(body),
2945
+ ext: opts.ext,
2946
+ signal: opts.signal,
2947
+ noRetry: true
2948
+ });
2949
+ }
2950
+ };
2951
+
2952
+ //#endregion
2953
+ //#region src/resources/abuse-reports.ts
2954
+ var AbuseReports = class {
2955
+ http;
2956
+ constructor(http) {
2957
+ this.http = http;
2958
+ }
2959
+ /** Store an abuse report for manual review (HTTP 202). Rate-limited per IP; never retried. */
2960
+ create(body, opts = {}) {
2961
+ return this.http.json("/v1/studio/abuse-reports", {
2962
+ method: "POST",
2963
+ body: stripUndefined(body),
2964
+ ext: opts.ext,
2965
+ signal: opts.signal,
2966
+ noRetry: true
2967
+ });
2968
+ }
2969
+ };
2970
+
2971
+ //#endregion
2972
+ //#region src/resources/provenance.ts
2973
+ /** Largest file the checker accepts (25 MB). */
2974
+ const PROVENANCE_MAX_BYTES = 26214400;
2975
+ var Provenance = class {
2976
+ http;
2977
+ constructor(http) {
2978
+ this.http = http;
2979
+ }
2980
+ /**
2981
+ * Upload `file` (PNG, JPEG, WebP, WAV, MP3 or MP4, ≤ 25 MB) and return what was found. A `Blob`/`File` sends its own
2982
+ * `type`; raw bytes need `contentType` (default `application/octet-stream`). Never retried.
2983
+ */
2984
+ check(file, opts = {}) {
2985
+ const type = opts.contentType || (file instanceof Blob && file.type ? file.type : "application/octet-stream");
2986
+ return this.http.json("/v1/public/provenance/check", {
2987
+ method: "POST",
2988
+ rawBody: file,
2989
+ headers: { "Content-Type": type },
2990
+ ext: opts.ext,
2991
+ signal: opts.signal,
2992
+ noRetry: true
2993
+ });
2994
+ }
2995
+ };
2996
+
2997
+ //#endregion
2998
+ //#region src/resources/messages.ts
2999
+ /** `POST /v1/messages` — Anthropic Messages wire (JSON + named-event SSE). */
3000
+ var Messages = class {
3001
+ http;
3002
+ constructor(http) {
3003
+ this.http = http;
3004
+ }
3005
+ async create(body, opts = {}) {
3006
+ const res = await this.http.request("/v1/messages", {
3007
+ body: {
3008
+ ...body,
3009
+ model: body.model ?? "codai",
3010
+ stream: false
3011
+ },
3012
+ ext: opts.ext,
3013
+ signal: opts.signal
3014
+ });
3015
+ const raw = await res.json();
3016
+ return {
3017
+ text: (raw.content ?? []).map((b) => b.type === "text" && typeof b.text === "string" ? b.text : "").join(""),
3018
+ raw,
3019
+ requestId: res.headers.get("x-codai-trace-id") ?? res.headers.get("x-request-id"),
3020
+ routedTo: res.headers.get("x-codai-routed-to"),
3021
+ headers: res.headers
3022
+ };
3023
+ }
3024
+ stream(body, opts = {}) {
3025
+ const requestPromise = this.http.request("/v1/messages", {
3026
+ body: {
3027
+ ...body,
3028
+ model: body.model ?? "codai",
3029
+ stream: true
3030
+ },
3031
+ ext: opts.ext,
3032
+ signal: opts.signal,
3033
+ timeoutMs: 0,
3034
+ noRetry: true
3035
+ });
3036
+ let resolveFinal;
3037
+ let rejectFinal;
3038
+ const final = new Promise((resolve, reject) => {
3039
+ resolveFinal = resolve;
3040
+ rejectFinal = reject;
3041
+ });
3042
+ final.catch(() => {});
3043
+ let text = "";
3044
+ let stopReason = null;
3045
+ let inputTokens = null;
3046
+ let outputTokens = null;
3047
+ let res = null;
3048
+ async function* events() {
3049
+ try {
3050
+ res = await requestPromise;
3051
+ for await (const frame of readSse(res, opts.signal)) {
3052
+ const ev = frameJson(frame);
3053
+ if (!ev) continue;
3054
+ if (typeof ev.type !== "string") ev.type = frame.event;
3055
+ if (ev.type === "message_start") {
3056
+ const usage = ev.message?.usage;
3057
+ if (usage?.input_tokens !== void 0) inputTokens = usage.input_tokens;
3058
+ } else if (ev.type === "content_block_delta") {
3059
+ const delta = ev.delta;
3060
+ if (delta?.type === "text_delta" && typeof delta.text === "string") text += delta.text;
3061
+ } else if (ev.type === "message_delta") {
3062
+ const delta = ev.delta;
3063
+ if (delta?.stop_reason) stopReason = delta.stop_reason;
3064
+ const usage = ev.usage;
3065
+ if (usage?.output_tokens !== void 0) outputTokens = usage.output_tokens;
3066
+ }
3067
+ yield ev;
3068
+ if (ev.type === "message_stop") break;
3069
+ }
3070
+ resolveFinal({
3071
+ text,
3072
+ stopReason,
3073
+ usage: inputTokens !== null || outputTokens !== null ? {
3074
+ inputTokens: inputTokens ?? 0,
3075
+ outputTokens: outputTokens ?? 0
3076
+ } : null,
3077
+ requestId: res.headers.get("x-codai-trace-id") ?? res.headers.get("x-request-id") ?? null,
3078
+ routedTo: res.headers.get("x-codai-routed-to"),
3079
+ headers: res.headers
3080
+ });
3081
+ } catch (err) {
3082
+ rejectFinal(err);
3083
+ throw err;
3084
+ }
3085
+ }
3086
+ async function* textOnly() {
3087
+ for await (const ev of events()) {
3088
+ if (ev.type !== "content_block_delta") continue;
3089
+ const delta = ev.delta;
3090
+ if (delta?.type === "text_delta" && delta.text) yield delta.text;
3091
+ }
3092
+ }
3093
+ return {
3094
+ [Symbol.asyncIterator]: () => events(),
3095
+ text: () => ({ [Symbol.asyncIterator]: () => textOnly() }),
3096
+ final
3097
+ };
3098
+ }
3099
+ };
3100
+
3101
+ //#endregion
3102
+ //#region src/resources/models.ts
3103
+ var Models = class {
3104
+ http;
3105
+ constructor(http) {
3106
+ this.http = http;
3107
+ }
3108
+ /** Every model the calling key may address (OpenAI list shape, `data[]`). */
3109
+ async list(opts = {}) {
3110
+ return [...(await this.http.json("/v1/models", {
3111
+ ext: opts.ext,
3112
+ signal: opts.signal
3113
+ })).data ?? []];
1788
3114
  }
1789
3115
  };
1790
3116
 
@@ -2075,6 +3401,42 @@ var Realtime = class {
2075
3401
  }
2076
3402
  };
2077
3403
 
3404
+ //#endregion
3405
+ //#region src/resources/referrals.ts
3406
+ var Referrals = class {
3407
+ http;
3408
+ constructor(http) {
3409
+ this.http = http;
3410
+ }
3411
+ /** `GET /v1/referrals` — stats, redeem deadline and invitees (masked, no PII). */
3412
+ get(opts = {}) {
3413
+ return this.http.json("/v1/referrals", {
3414
+ ext: opts.ext,
3415
+ signal: opts.signal
3416
+ });
3417
+ }
3418
+ /**
3419
+ * Redeem a referrer's code (their username) — `PATCH /v1/account
3420
+ * { referral_code }`. Allowed within 7 days of signup; the outcome is in
3421
+ * `referral_result` of the response.
3422
+ */
3423
+ redeem(code, opts = {}) {
3424
+ return this.patch({ referral_code: code }, opts);
3425
+ }
3426
+ /** Opt in/out of the referral programme — `PATCH /v1/account { referral_consent }`. */
3427
+ setConsent(consent, opts = {}) {
3428
+ return this.patch({ referral_consent: consent }, opts);
3429
+ }
3430
+ patch(body, opts) {
3431
+ return this.http.json("/v1/account", {
3432
+ method: "PATCH",
3433
+ body,
3434
+ ext: opts.ext,
3435
+ signal: opts.signal
3436
+ });
3437
+ }
3438
+ };
3439
+
2078
3440
  //#endregion
2079
3441
  //#region src/resources/resolve.ts
2080
3442
  /**
@@ -2313,6 +3675,38 @@ var Resolve = class {
2313
3675
  return this.call(`/v1/resolve/jobs/${encodeURIComponent(id)}`, { signal: opts.signal });
2314
3676
  }
2315
3677
  /**
3678
+ * `GET /v1/resolve/jobs` — one page of your jobs, newest first. Pass the
3679
+ * page's `next_cursor` back as `cursor` for the next page (`null` = last).
3680
+ * `status` filters by one or more statuses.
3681
+ */
3682
+ list(query = {}, opts = {}) {
3683
+ const status = Array.isArray(query.status) ? query.status.join(",") : query.status;
3684
+ return this.call("/v1/resolve/jobs", {
3685
+ query: {
3686
+ status: status || void 0,
3687
+ limit: query.limit,
3688
+ cursor: query.cursor
3689
+ },
3690
+ signal: opts.signal
3691
+ });
3692
+ }
3693
+ /**
3694
+ * Every job matching `query`, newest first, following `next_cursor` page by
3695
+ * page (`limit` = page size). Stop early with `break`.
3696
+ */
3697
+ async *iterate(query = {}, opts = {}) {
3698
+ let cursor;
3699
+ for (;;) {
3700
+ const page = await this.list({
3701
+ ...query,
3702
+ cursor
3703
+ }, opts);
3704
+ for (const job of page.jobs) yield job;
3705
+ if (!page.next_cursor) return;
3706
+ cursor = page.next_cursor;
3707
+ }
3708
+ }
3709
+ /**
2316
3710
  * `POST /v1/resolve/jobs/{id}/accept` — accept a paid quote and start the job.
2317
3711
  * The result's `paid_with` says how it was paid (`intro` €1 hold, `credit`
2318
3712
  * t7 fix credit, or `wallet`). Throws `ResolveInsufficientFundsError` (402,
@@ -3058,7 +4452,7 @@ var Notifications = class {
3058
4452
  //#endregion
3059
4453
  //#region src/resources/prompts.ts
3060
4454
  /** `/v1/prompts/*` — pending prompts: ready-to-paste prompts left for a future chat (handoffs, follow-ups). */
3061
- const one$2 = (id, suffix = "") => `/v1/prompts/${encodeURIComponent(id)}${suffix}`;
4455
+ const one$3 = (id, suffix = "") => `/v1/prompts/${encodeURIComponent(id)}${suffix}`;
3062
4456
  var Prompts = class {
3063
4457
  http;
3064
4458
  constructor(http) {
@@ -3086,14 +4480,14 @@ var Prompts = class {
3086
4480
  }
3087
4481
  /** `GET /v1/prompts/{id}`. */
3088
4482
  get(id, opts = {}) {
3089
- return this.http.json(one$2(id), {
4483
+ return this.http.json(one$3(id), {
3090
4484
  ext: opts.ext,
3091
4485
  signal: opts.signal
3092
4486
  });
3093
4487
  }
3094
4488
  /** `PATCH /v1/prompts/{id}` — edit, snooze (`not_before`), close (`status: 'done' | 'dismissed'`). */
3095
4489
  update(id, body, opts = {}) {
3096
- return this.http.json(one$2(id), {
4490
+ return this.http.json(one$3(id), {
3097
4491
  method: "PATCH",
3098
4492
  body,
3099
4493
  ext: opts.ext,
@@ -3102,7 +4496,7 @@ var Prompts = class {
3102
4496
  }
3103
4497
  /** `DELETE /v1/prompts/{id}` — `{ deleted: 0 }` when the id is missing or not yours. */
3104
4498
  delete(id, opts = {}) {
3105
- return this.http.json(one$2(id), {
4499
+ return this.http.json(one$3(id), {
3106
4500
  method: "DELETE",
3107
4501
  ext: opts.ext,
3108
4502
  signal: opts.signal
@@ -3110,7 +4504,7 @@ var Prompts = class {
3110
4504
  }
3111
4505
  /** `POST /v1/prompts/{id}/launch` — new shared session + `send` control on a device; the prompt becomes `launched`. */
3112
4506
  launch(id, deviceId, opts = {}) {
3113
- return this.http.json(one$2(id, "/launch"), {
4507
+ return this.http.json(one$3(id, "/launch"), {
3114
4508
  method: "POST",
3115
4509
  body: deviceId ? { device_id: deviceId } : {},
3116
4510
  ext: opts.ext,
@@ -3120,7 +4514,7 @@ var Prompts = class {
3120
4514
  }
3121
4515
  /** `POST /v1/prompts/{id}/match` — the prompt was sent in a chat → `sent` (or `answered`); never downgrades. */
3122
4516
  match(id, body, opts = {}) {
3123
- return this.http.json(one$2(id, "/match"), {
4517
+ return this.http.json(one$3(id, "/match"), {
3124
4518
  method: "POST",
3125
4519
  body,
3126
4520
  ext: opts.ext,
@@ -3132,7 +4526,7 @@ var Prompts = class {
3132
4526
  * events) and an optional diff; verdict `done` → `verified`. 502 when the model call fails.
3133
4527
  */
3134
4528
  verify(id, body = {}, opts = {}) {
3135
- return this.http.json(one$2(id, "/verify"), {
4529
+ return this.http.json(one$3(id, "/verify"), {
3136
4530
  method: "POST",
3137
4531
  body,
3138
4532
  ext: opts.ext,
@@ -3167,7 +4561,7 @@ var Prompts = class {
3167
4561
  //#endregion
3168
4562
  //#region src/resources/schedules.ts
3169
4563
  /** `/v1/schedules/*`, `/v1/schedule-runs/*`, `/v1/scheduler/*` — the codai Scheduler (ADR 0006). */
3170
- const one$1 = (id, suffix = "") => `/v1/schedules/${encodeURIComponent(id)}${suffix}`;
4564
+ const one$2 = (id, suffix = "") => `/v1/schedules/${encodeURIComponent(id)}${suffix}`;
3171
4565
  const run = (id, suffix) => `/v1/schedule-runs/${encodeURIComponent(id)}${suffix}`;
3172
4566
  /** Host-side executor protocol: claim → heartbeat → result. Needs a device header (`device` client option). */
3173
4567
  var ScheduleExecutor = class {
@@ -3209,7 +4603,7 @@ var ScheduleExecutor = class {
3209
4603
  }
3210
4604
  /** `POST /v1/schedules/{id}/approve-command` — this host approves the exact shell command hash it showed the user. */
3211
4605
  approveCommand(scheduleId, commandHash, opts = {}) {
3212
- return this.http.json(one$1(scheduleId, "/approve-command"), {
4606
+ return this.http.json(one$2(scheduleId, "/approve-command"), {
3213
4607
  method: "POST",
3214
4608
  body: { command_hash: commandHash },
3215
4609
  ext: opts.ext,
@@ -3318,14 +4712,14 @@ var Schedules = class {
3318
4712
  }
3319
4713
  /** `GET /v1/schedules/{id}`. */
3320
4714
  get(id, opts = {}) {
3321
- return this.http.json(one$1(id), {
4715
+ return this.http.json(one$2(id), {
3322
4716
  ext: opts.ext,
3323
4717
  signal: opts.signal
3324
4718
  });
3325
4719
  }
3326
4720
  /** `PATCH /v1/schedules/{id}` — partial; a changed shell command clears host approvals. */
3327
4721
  update(id, body, opts = {}) {
3328
- return this.http.json(one$1(id), {
4722
+ return this.http.json(one$2(id), {
3329
4723
  method: "PATCH",
3330
4724
  body,
3331
4725
  ext: opts.ext,
@@ -3334,7 +4728,7 @@ var Schedules = class {
3334
4728
  }
3335
4729
  /** `DELETE /v1/schedules/{id}`. */
3336
4730
  async delete(id, opts = {}) {
3337
- await this.http.request(one$1(id), {
4731
+ await this.http.request(one$2(id), {
3338
4732
  method: "DELETE",
3339
4733
  ext: opts.ext,
3340
4734
  signal: opts.signal
@@ -3342,7 +4736,7 @@ var Schedules = class {
3342
4736
  }
3343
4737
  /** `POST /v1/schedules/{id}/run` — run now (policy still applies). */
3344
4738
  runNow(id, opts = {}) {
3345
- return this.http.json(one$1(id, "/run"), {
4739
+ return this.http.json(one$2(id, "/run"), {
3346
4740
  method: "POST",
3347
4741
  body: {},
3348
4742
  ext: opts.ext,
@@ -3353,7 +4747,7 @@ var Schedules = class {
3353
4747
  }
3354
4748
  /** `GET /v1/schedules/{id}/runs`. */
3355
4749
  async runs(id, opts = {}) {
3356
- return [...(await this.http.json(one$1(id, "/runs"), {
4750
+ return [...(await this.http.json(one$2(id, "/runs"), {
3357
4751
  ext: opts.ext,
3358
4752
  signal: opts.signal
3359
4753
  })).runs];
@@ -3393,6 +4787,17 @@ var Schedules = class {
3393
4787
  signal: opts.signal
3394
4788
  });
3395
4789
  }
4790
+ /** `GET /v1/schedules/audit` — append-only scheduler history, newest first (optionally one schedule). */
4791
+ async audit(params = {}, opts = {}) {
4792
+ return [...(await this.http.json("/v1/schedules/audit", {
4793
+ query: {
4794
+ schedule_id: params.schedule_id,
4795
+ limit: params.limit
4796
+ },
4797
+ ext: opts.ext,
4798
+ signal: opts.signal
4799
+ })).audit];
4800
+ }
3396
4801
  /** `GET /v1/schedules/templates`. */
3397
4802
  templates(opts = {}) {
3398
4803
  return this.http.json("/v1/schedules/templates", {
@@ -3425,6 +4830,348 @@ var Schedules = class {
3425
4830
  }
3426
4831
  };
3427
4832
 
4833
+ //#endregion
4834
+ //#region src/resources/lists.ts
4835
+ /** `/v1/lists/*`, `/v1/share` — lists and the share-sheet entry point. */
4836
+ const one$1 = (id, suffix = "") => `/v1/lists/${encodeURIComponent(id)}${suffix}`;
4837
+ const item = (id, suffix = "") => `/v1/lists/items/${encodeURIComponent(id)}${suffix}`;
4838
+ var Lists = class {
4839
+ http;
4840
+ constructor(http) {
4841
+ this.http = http;
4842
+ }
4843
+ /** `GET /v1/lists` — share-sheet order; presets are created on the first call. */
4844
+ async list(params = {}, opts = {}) {
4845
+ return [...(await this.http.json("/v1/lists", {
4846
+ query: { archived: params.archived ? "1" : void 0 },
4847
+ ext: opts.ext,
4848
+ signal: opts.signal
4849
+ })).lists];
4850
+ }
4851
+ /** `POST /v1/lists` — a custom list. */
4852
+ async create(body, opts = {}) {
4853
+ return (await this.http.json("/v1/lists", {
4854
+ method: "POST",
4855
+ body,
4856
+ ext: opts.ext,
4857
+ signal: opts.signal,
4858
+ acceptStatus: [201]
4859
+ })).list;
4860
+ }
4861
+ /** `PATCH /v1/lists/order` — the order of your lists (and of the share-sheet targets). */
4862
+ reorder(ids, opts = {}) {
4863
+ return this.http.json("/v1/lists/order", {
4864
+ method: "PATCH",
4865
+ body: { ids },
4866
+ ext: opts.ext,
4867
+ signal: opts.signal
4868
+ });
4869
+ }
4870
+ /** `GET /v1/lists/stream` — live `list` events (keepalives skipped). */
4871
+ async *stream(opts = {}) {
4872
+ for await (const frame of this.http.sse("/v1/lists/stream", {
4873
+ ext: opts.ext,
4874
+ signal: opts.signal
4875
+ })) {
4876
+ if (frame.event !== "list") continue;
4877
+ const data = frameJson(frame);
4878
+ if (data) yield data;
4879
+ }
4880
+ }
4881
+ /** `PATCH /v1/lists/{id}` — name, icon, color, share-sheet visibility, price watch, archived. */
4882
+ async update(id, patch, opts = {}) {
4883
+ return (await this.http.json(one$1(id), {
4884
+ method: "PATCH",
4885
+ body: patch,
4886
+ ext: opts.ext,
4887
+ signal: opts.signal
4888
+ })).list;
4889
+ }
4890
+ /** `DELETE /v1/lists/{id}` — custom lists only (presets → 409 `preset_list`). */
4891
+ async delete(id, opts = {}) {
4892
+ await this.http.request(one$1(id), {
4893
+ method: "DELETE",
4894
+ ext: opts.ext,
4895
+ signal: opts.signal
4896
+ });
4897
+ }
4898
+ /** `GET /v1/lists/{id}/items` — pinned first, then newest; done items only with `done: true`. */
4899
+ async items(id, params = {}, opts = {}) {
4900
+ return [...(await this.http.json(one$1(id, "/items"), {
4901
+ query: {
4902
+ done: params.done ? "1" : void 0,
4903
+ limit: params.limit
4904
+ },
4905
+ ext: opts.ext,
4906
+ signal: opts.signal
4907
+ })).items];
4908
+ }
4909
+ /** `POST /v1/lists/{id}/items` — 201 created, or 200 with the existing item (`created: false`). */
4910
+ add(id, body, opts = {}) {
4911
+ return this.http.json(one$1(id, "/items"), {
4912
+ method: "POST",
4913
+ body,
4914
+ ext: opts.ext,
4915
+ signal: opts.signal,
4916
+ acceptStatus: [200, 201]
4917
+ });
4918
+ }
4919
+ /** `PATCH /v1/lists/items/{itemId}` — title, body, done, pinned, reminder; `list_id` moves it. */
4920
+ async updateItem(itemId, patch, opts = {}) {
4921
+ return (await this.http.json(item(itemId), {
4922
+ method: "PATCH",
4923
+ body: patch,
4924
+ ext: opts.ext,
4925
+ signal: opts.signal
4926
+ })).item;
4927
+ }
4928
+ /** `DELETE /v1/lists/items/{itemId}` — also deletes its uploaded media. */
4929
+ async deleteItem(itemId, opts = {}) {
4930
+ await this.http.request(item(itemId), {
4931
+ method: "DELETE",
4932
+ ext: opts.ext,
4933
+ signal: opts.signal
4934
+ });
4935
+ }
4936
+ /** `GET /v1/lists/items/{itemId}/image` — the uploaded image or the unfurled preview image. */
4937
+ async image(itemId, opts = {}) {
4938
+ const res = await this.http.request(item(itemId, "/image"), {
4939
+ ext: opts.ext,
4940
+ signal: opts.signal
4941
+ });
4942
+ return {
4943
+ bytes: new Uint8Array(await res.arrayBuffer()),
4944
+ contentType: res.headers.get("content-type") ?? "application/octet-stream"
4945
+ };
4946
+ }
4947
+ /** `GET /v1/lists/{id}/export.md` — the whole list as GitHub-flavoured Markdown. */
4948
+ async exportMarkdown(id, opts = {}) {
4949
+ return (await this.http.request(one$1(id, "/export.md"), {
4950
+ ext: opts.ext,
4951
+ signal: opts.signal
4952
+ })).text();
4953
+ }
4954
+ /** `POST /v1/share` — share-sheet entry point (`list_id`, `preset`, or auto → Inbox + suggestion). */
4955
+ share(body, opts = {}) {
4956
+ return this.http.json("/v1/share", {
4957
+ method: "POST",
4958
+ body,
4959
+ ext: opts.ext,
4960
+ signal: opts.signal,
4961
+ acceptStatus: [200, 201]
4962
+ });
4963
+ }
4964
+ };
4965
+
4966
+ //#endregion
4967
+ //#region src/resources/memory.ts
4968
+ var Memory = class {
4969
+ http;
4970
+ constructor(http) {
4971
+ this.http = http;
4972
+ }
4973
+ /** `GET /v1/memory` — newest first; `limit` 1–100 (20), optional `tier`. Not metered. */
4974
+ list(query = {}, opts = {}) {
4975
+ return this.http.json("/v1/memory", {
4976
+ query: {
4977
+ tier: query.tier,
4978
+ limit: query.limit,
4979
+ offset: query.offset
4980
+ },
4981
+ ext: opts.ext,
4982
+ signal: opts.signal
4983
+ });
4984
+ }
4985
+ /** `GET /v1/memory/search` — semantic recall, most relevant first; `limit` 1–10 (5). One embedding. */
4986
+ search(query, opts = {}) {
4987
+ return this.http.json("/v1/memory/search", {
4988
+ query: {
4989
+ q: query.q,
4990
+ limit: query.limit
4991
+ },
4992
+ ext: opts.ext,
4993
+ signal: opts.signal
4994
+ });
4995
+ }
4996
+ /** `POST /v1/memory` — store one semantic memory (`content` ≤ 4000 chars, `importance` 0–1, default 0.6). */
4997
+ create(input, opts = {}) {
4998
+ return this.http.json("/v1/memory", {
4999
+ method: "POST",
5000
+ body: input,
5001
+ ext: opts.ext,
5002
+ signal: opts.signal
5003
+ });
5004
+ }
5005
+ /** `DELETE /v1/memory/{id}` — 404 when the id is unknown or not yours. */
5006
+ delete(id, opts = {}) {
5007
+ return this.http.json(`/v1/memory/${encodeURIComponent(id)}`, {
5008
+ method: "DELETE",
5009
+ ext: opts.ext,
5010
+ signal: opts.signal
5011
+ });
5012
+ }
5013
+ };
5014
+
5015
+ //#endregion
5016
+ //#region src/resources/sandboxes.ts
5017
+ /**
5018
+ * `/v1/sandboxes` — agent sandboxes (beta): isolated gVisor containers with a persistent
5019
+ * `/workspace`, no network by default, artifacts from `/workspace/out` as scanned, signed links.
5020
+ */
5021
+ const base = (id) => `/v1/sandboxes/${encodeURIComponent(id)}`;
5022
+ /** Encode each segment of a workspace path, keeping the slashes. */
5023
+ const filePath = (p) => p.replace(/^\/+/, "").split("/").map((s) => encodeURIComponent(s)).join("/");
5024
+ const idem = (key) => key ? { "Idempotency-Key": key } : void 0;
5025
+ var SandboxFiles = class {
5026
+ http;
5027
+ constructor(http) {
5028
+ this.http = http;
5029
+ }
5030
+ /** `PUT /v1/sandboxes/{id}/files/{path}` — write raw bytes (≤ 100 MB) to `/workspace/<path>`. */
5031
+ put(id, path, content, opts = {}) {
5032
+ const body = typeof content === "string" ? new TextEncoder().encode(content) : content;
5033
+ return this.http.json(`${base(id)}/files/${filePath(path)}`, {
5034
+ method: "PUT",
5035
+ rawBody: body,
5036
+ headers: { "Content-Type": "application/octet-stream" },
5037
+ ext: opts.ext,
5038
+ signal: opts.signal
5039
+ });
5040
+ }
5041
+ /** `GET /v1/sandboxes/{id}/files/{path}` — raw bytes of `/workspace/<path>` (`sha256` from `x-sha256`). */
5042
+ async get(id, path, opts = {}) {
5043
+ const res = await this.http.request(`${base(id)}/files/${filePath(path)}`, {
5044
+ ext: opts.ext,
5045
+ signal: opts.signal
5046
+ });
5047
+ return {
5048
+ bytes: new Uint8Array(await res.arrayBuffer()),
5049
+ sha256: res.headers.get("x-sha256"),
5050
+ contentType: res.headers.get("content-type")
5051
+ };
5052
+ }
5053
+ /** `GET /v1/sandboxes/{id}/files?path=` — entries under a directory (default the workspace root). */
5054
+ list(id, path, opts = {}) {
5055
+ return this.http.json(`${base(id)}/files`, {
5056
+ query: { path },
5057
+ ext: opts.ext,
5058
+ signal: opts.signal
5059
+ });
5060
+ }
5061
+ };
5062
+ var Sandboxes = class {
5063
+ http;
5064
+ files;
5065
+ constructor(http) {
5066
+ this.http = http;
5067
+ this.files = new SandboxFiles(http);
5068
+ }
5069
+ /** `POST /v1/sandboxes` — start a sandbox (`ttl_seconds` 60–86400, default 3600; `egress` none by default). */
5070
+ create(input = {}, opts = {}) {
5071
+ return this.http.json("/v1/sandboxes", {
5072
+ method: "POST",
5073
+ body: input,
5074
+ ext: opts.ext,
5075
+ signal: opts.signal
5076
+ });
5077
+ }
5078
+ /** `GET /v1/sandboxes` — your sandboxes, newest first, optionally one `status`. */
5079
+ list(query = {}, opts = {}) {
5080
+ return this.http.json("/v1/sandboxes", {
5081
+ query: { status: query.status },
5082
+ ext: opts.ext,
5083
+ signal: opts.signal
5084
+ });
5085
+ }
5086
+ /** `GET /v1/sandboxes/{id}` */
5087
+ retrieve(id, opts = {}) {
5088
+ return this.http.json(base(id), {
5089
+ ext: opts.ext,
5090
+ signal: opts.signal
5091
+ });
5092
+ }
5093
+ /**
5094
+ * `POST /v1/sandboxes/{id}/exec` — run one command and wait for it (≤ 900 s). Use
5095
+ * {@link execStream} to receive stdout / stderr as they are produced.
5096
+ */
5097
+ exec(id, input, opts = {}) {
5098
+ return this.http.json(`${base(id)}/exec`, {
5099
+ method: "POST",
5100
+ body: input,
5101
+ headers: idem(opts.idempotencyKey),
5102
+ timeoutMs: execTimeoutMs(input.timeout_seconds),
5103
+ noRetry: !opts.idempotencyKey,
5104
+ ext: opts.ext,
5105
+ signal: opts.signal
5106
+ });
5107
+ }
5108
+ /**
5109
+ * `POST /v1/sandboxes/{id}/exec` with `Accept: text/event-stream` — yields `start`, `stdout`,
5110
+ * `stderr`, `truncated` and finally `exit` (or `error`) events.
5111
+ */
5112
+ async *execStream(id, input, opts = {}) {
5113
+ const frames = this.http.sse(`${base(id)}/exec`, {
5114
+ method: "POST",
5115
+ body: input,
5116
+ headers: {
5117
+ Accept: "text/event-stream",
5118
+ ...idem(opts.idempotencyKey)
5119
+ },
5120
+ ext: opts.ext,
5121
+ signal: opts.signal
5122
+ });
5123
+ for await (const frame of frames) {
5124
+ const data = frameJson(frame);
5125
+ if (!data || typeof data !== "object" || !("type" in data)) continue;
5126
+ yield data;
5127
+ if (data.type === "exit" || data.type === "error") return;
5128
+ }
5129
+ }
5130
+ /** `GET /v1/sandboxes/{id}/artifacts` — collect `/workspace/out` (scanned, signed 1 h links). */
5131
+ artifacts(id, opts = {}) {
5132
+ return this.http.json(`${base(id)}/artifacts`, {
5133
+ ext: opts.ext,
5134
+ signal: opts.signal
5135
+ });
5136
+ }
5137
+ /** `POST /v1/sandboxes/{id}/snapshot` — store a compressed copy of the workspace. */
5138
+ snapshot(id, input = {}, opts = {}) {
5139
+ return this.http.json(`${base(id)}/snapshot`, {
5140
+ method: "POST",
5141
+ body: input,
5142
+ ext: opts.ext,
5143
+ signal: opts.signal
5144
+ });
5145
+ }
5146
+ /** `DELETE /v1/sandboxes/{id}` — destroy the sandbox and its workspace (204). */
5147
+ async delete(id, opts = {}) {
5148
+ await this.http.request(base(id), {
5149
+ method: "DELETE",
5150
+ ext: opts.ext,
5151
+ signal: opts.signal
5152
+ });
5153
+ }
5154
+ /**
5155
+ * `POST /v1/sandboxes/run` — one shot: create, write `inputs` under `/workspace/in`, run,
5156
+ * collect artifacts, destroy. Pass `idempotencyKey` to make retries safe.
5157
+ */
5158
+ run(input, opts = {}) {
5159
+ return this.http.json("/v1/sandboxes/run", {
5160
+ method: "POST",
5161
+ body: input,
5162
+ headers: idem(opts.idempotencyKey),
5163
+ timeoutMs: execTimeoutMs(input.timeout_seconds),
5164
+ noRetry: !opts.idempotencyKey,
5165
+ ext: opts.ext,
5166
+ signal: opts.signal
5167
+ });
5168
+ }
5169
+ };
5170
+ /** Client timeout for a blocking exec: the server limit plus a margin for restore and upload. */
5171
+ function execTimeoutMs(timeoutSeconds) {
5172
+ return ((timeoutSeconds ?? 120) + 60) * 1e3;
5173
+ }
5174
+
3428
5175
  //#endregion
3429
5176
  //#region src/resources/transcripts.ts
3430
5177
  /**
@@ -4008,6 +5755,9 @@ const OPERATION_METHODS = {
4008
5755
  getVideo: "videos.retrieve",
4009
5756
  createRender: "renders.create",
4010
5757
  getRender: "renders.retrieve",
5758
+ listRenders: "renders.list",
5759
+ createTimeline: "renders.createTimeline",
5760
+ regenerateRenderScene: "renders.regenerateScene",
4011
5761
  listAssets: "assets.list",
4012
5762
  getAsset: "assets.retrieve",
4013
5763
  getAssetContent: "assets.contentUrl",
@@ -4019,12 +5769,91 @@ const OPERATION_METHODS = {
4019
5769
  cardsGeocode: "cards.geocode",
4020
5770
  cardsStaticMap: "cards.staticMap",
4021
5771
  cardsFx: "cards.fx",
5772
+ cardsRoute: "cards.route",
5773
+ cardsTrack: "cards.track",
5774
+ cardsEfactura: "cards.efactura",
4022
5775
  cardsUnfurl: "cards.unfurl",
5776
+ cardsProduct: "cards.product",
5777
+ cardsRender: "cards.render",
4023
5778
  createDocument: "documents.create",
4024
5779
  retrieveDocument: "documents.retrieve",
4025
5780
  createDocumentPreview: "documents.preview",
4026
5781
  retrievePreview: "documents.retrievePreview",
4027
5782
  createDocumentVideo: "documents.video",
5783
+ listCreatives: "creatives.list",
5784
+ createCreative: "creatives.create",
5785
+ getCreative: "creatives.retrieve",
5786
+ deleteCreative: "creatives.delete",
5787
+ getCreativeOutline: "creatives.outline",
5788
+ findCreativeNodes: "creatives.find",
5789
+ getCreativeSubtree: "creatives.subtree",
5790
+ applyCreativeOps: "creatives.edit",
5791
+ listCreativeVersions: "creatives.versions",
5792
+ revertCreative: "creatives.revert",
5793
+ forkCreative: "creatives.fork",
5794
+ lintCreative: "creatives.lint",
5795
+ getCreativeCompiled: "creatives.compiled",
5796
+ renderCreative: "creatives.render",
5797
+ createCreativeFrame: "creatives.frame",
5798
+ getCreativeFrameJob: "creatives.frameJob",
5799
+ commentCreative: "creatives.comment",
5800
+ createCreativeVariants: "creatives.variants",
5801
+ listCreativeVariants: "creatives.listVariants",
5802
+ pickCreativeVariant: "creatives.pickVariant",
5803
+ extractBrandKit: "brandKits.extract",
5804
+ listBrandKits: "brandKits.list",
5805
+ getBrandKit: "brandKits.retrieve",
5806
+ deleteBrandKit: "brandKits.delete",
5807
+ createBrandKit: "brandKits.create",
5808
+ updateBrandKit: "brandKits.update",
5809
+ exportBrandKitDtcg: "brandKits.exportDtcg",
5810
+ restyleCreative: "creatives.restyle",
5811
+ captionCreative: "creatives.captions",
5812
+ getCreativeCaptionsSrt: "creatives.captionsSrt",
5813
+ getCreativeCaptionsVtt: "creatives.captionsVtt",
5814
+ adaptCreative: "creatives.adapt",
5815
+ fixCreativeLint: "creatives.lintFix",
5816
+ getCreativeControls: "creatives.controls",
5817
+ getCreativeLocales: "creatives.locales",
5818
+ localizeCreative: "creatives.localize",
5819
+ forkCreativeLocale: "creatives.forkLocale",
5820
+ createCreativeShare: "creatives.createShare",
5821
+ listCreativeShares: "creatives.listShares",
5822
+ revokeCreativeShare: "creatives.revokeShare",
5823
+ getCreativeReview: "creatives.review",
5824
+ updateCreativeReview: "creatives.requestReview",
5825
+ listCreativeReviewThreads: "creatives.reviewThreads",
5826
+ createCreativeReviewThread: "creatives.createReviewThread",
5827
+ replyCreativeReviewThread: "creatives.replyReviewThread",
5828
+ resolveCreativeReviewThread: "creatives.resolveReviewThread",
5829
+ reopenCreativeReviewThread: "creatives.reopenReviewThread",
5830
+ deleteCreativeReviewComment: "creatives.deleteReviewComment",
5831
+ remixStudioShare: "shares.remix",
5832
+ getPublicStudioShare: "shares.get",
5833
+ createPublicReviewThread: "shares.comment",
5834
+ replyPublicReviewThread: "shares.reply",
5835
+ resolvePublicReviewThread: "shares.resolve",
5836
+ reopenPublicReviewThread: "shares.reopen",
5837
+ decidePublicReview: "shares.decide",
5838
+ createVoiceRevocation: "voiceRevocations.create",
5839
+ createStudioAbuseReport: "abuseReports.create",
5840
+ checkProvenance: "provenance.check",
5841
+ createStudioBatch: "batches.create",
5842
+ listStudioBatches: "batches.list",
5843
+ getStudioBatch: "batches.get",
5844
+ cancelStudioBatch: "batches.cancel",
5845
+ retryStudioBatch: "batches.retry",
5846
+ exportStudioBatchCsv: "batches.exportCsv",
5847
+ zipStudioBatch: "batches.zip",
5848
+ saveCreativeTemplate: "creatives.saveTemplate",
5849
+ listCreativeTemplates: "templates.list",
5850
+ getCreativeTemplate: "templates.retrieve",
5851
+ deleteCreativeTemplate: "templates.delete",
5852
+ exportCreativeFcpxml: "creatives.exportFcpxml",
5853
+ exportCreativeLottie: "creatives.exportLottie",
5854
+ getStudioExport: "exports.retrieve",
5855
+ createCreativeFromDocument: "creatives.fromDocument",
5856
+ buildCreative: "creatives.build",
4028
5857
  createSystemOne: "systemOne.create",
4029
5858
  createTranscription: "audio.transcribe",
4030
5859
  createSpeech: "audio.speech",
@@ -4126,13 +5955,42 @@ const OPERATION_METHODS = {
4126
5955
  resumeSchedules: "schedules.resume",
4127
5956
  listScheduleTemplates: "schedules.templates",
4128
5957
  renderScheduleTemplate: "schedules.renderTemplate",
5958
+ listScheduleAudit: "schedules.audit",
4129
5959
  listHeartbeats: "heartbeats.list",
4130
5960
  createHeartbeat: "heartbeats.create",
4131
5961
  updateHeartbeat: "heartbeats.update",
4132
5962
  deleteHeartbeat: "heartbeats.delete",
5963
+ listLists: "lists.list",
5964
+ createList: "lists.create",
5965
+ reorderLists: "lists.reorder",
5966
+ streamLists: "lists.stream",
5967
+ updateList: "lists.update",
5968
+ deleteList: "lists.delete",
5969
+ listListItems: "lists.items",
5970
+ addListItem: "lists.add",
5971
+ updateListItem: "lists.updateItem",
5972
+ deleteListItem: "lists.deleteItem",
5973
+ getListItemImage: "lists.image",
5974
+ exportListMarkdown: "lists.exportMarkdown",
5975
+ shareToList: "lists.share",
4133
5976
  getUsage: "usage.get",
4134
5977
  listKeys: "keys.list",
4135
5978
  setKeyTags: "keys.setTags",
5979
+ listMemories: "memory.list",
5980
+ searchMemories: "memory.search",
5981
+ createMemory: "memory.create",
5982
+ deleteMemory: "memory.delete",
5983
+ createSandbox: "sandboxes.create",
5984
+ listSandboxes: "sandboxes.list",
5985
+ getSandbox: "sandboxes.retrieve",
5986
+ execSandbox: "sandboxes.exec",
5987
+ putSandboxFile: "sandboxes.files.put",
5988
+ getSandboxFile: "sandboxes.files.get",
5989
+ listSandboxFiles: "sandboxes.files.list",
5990
+ listSandboxArtifacts: "sandboxes.artifacts",
5991
+ snapshotSandbox: "sandboxes.snapshot",
5992
+ deleteSandbox: "sandboxes.delete",
5993
+ runSandbox: "sandboxes.run",
4136
5994
  createSession: "sessions.create",
4137
5995
  listSessions: "sessions.list",
4138
5996
  getSession: "sessions.get",
@@ -4191,6 +6049,12 @@ const OPERATION_METHODS = {
4191
6049
  listEnvironmentTasks: "environments.tasks.list",
4192
6050
  createEnvironmentTask: "environments.tasks.create",
4193
6051
  getEnvironmentTask: "environments.tasks.get",
6052
+ execEnvironment: "environments.exec",
6053
+ listEnvironmentFiles: "environments.files.list",
6054
+ getEnvironmentFile: "environments.files.get",
6055
+ putEnvironmentFile: "environments.files.put",
6056
+ startEnvironmentJob: "environments.jobs.start",
6057
+ getEnvironmentJob: "environments.jobs.get",
4194
6058
  getAgentOutputKey: "verify.agentOutputKey",
4195
6059
  verifyAgentOutput: "verify.agentOutput",
4196
6060
  listEnvironmentPorts: "environments.ports.list",
@@ -4201,6 +6065,9 @@ const OPERATION_METHODS = {
4201
6065
  removeEnvironmentSecret: "environments.secrets.remove",
4202
6066
  getAccount: "account.get",
4203
6067
  patchAccount: "account.update",
6068
+ getBilling: "billing.get",
6069
+ listBillingInvoices: "billing.invoices",
6070
+ getReferrals: "referrals.get",
4204
6071
  getSettings: "settings.get",
4205
6072
  patchSettings: "settings.update",
4206
6073
  getReceipt: "receipt.get",
@@ -4215,7 +6082,8 @@ const STREAMING_OPERATIONS = /* @__PURE__ */ new Set([
4215
6082
  "createSpeechStream",
4216
6083
  "streamPrompts",
4217
6084
  "streamTranscripts",
4218
- "streamSchedules"
6085
+ "streamSchedules",
6086
+ "streamLists"
4219
6087
  ]);
4220
6088
  /**
4221
6089
  * Same parity contract for the separate Resolve service
@@ -4226,6 +6094,7 @@ const RESOLVE_OPERATION_METHODS = {
4226
6094
  resolveHealth: "resolve.health",
4227
6095
  createResolveJob: "resolve.submit",
4228
6096
  getResolveJob: "resolve.get",
6097
+ listResolveJobs: "resolve.list",
4229
6098
  acceptResolveJob: "resolve.accept",
4230
6099
  getResolveAttestation: "resolve.attestation",
4231
6100
  getResolveKeys: "resolve.keys",
@@ -4415,6 +6284,28 @@ var CodaiApps = class {
4415
6284
  * client.sfx.search / .import (codai Studio CC0 sound-effects library, codai-sfx)
4416
6285
  * client.documents.create / .retrieve / .preview / .retrievePreview / .video / .createPreviewAndWait / .videoAndWait
4417
6286
  * (codai Studio decks / docs / sheets → PPTX / DOCX / XLSX, codai-docs; previews codai-docs-preview)
6287
+ * client.creatives.create / .retrieve / .outline / .find / .subtree / .edit / .versions / .revert / .fork / .lint
6288
+ * / .compiled / .render / .frame / .frameJob / .comment / .variants / .listVariants / .pickVariant
6289
+ * / .saveTemplate / .exportFcpxml / .exportLottie / .downloadLottie / .fromDocument / .build / .restyle / .captions / .captionsSrt / .captionsVtt
6290
+ * / .adapt / .lintFix / .controls / .locales / .localize / .forkLocale / .createShare / .listShares
6291
+ * / .revokeShare / .review / .requestReview / .resetReview / .reviewThreads / .createReviewThread
6292
+ * / .replyReviewThread / .resolveReviewThread / .reopenReviewThread / .deleteReviewComment / .delete
6293
+ * (codai Studio editable creative documents, ops + version history + A/B variants; free but render, comment,
6294
+ * variants and frames beyond the daily quota)
6295
+ * client.brandKits.create / .update / .exportDtcg / .extract / .list / .retrieve / .delete (codai Studio brand
6296
+ * kits as DTCG tokens, from a web page or a logo; extract is
6297
+ * token-metered, the rest free; apply with creatives.create({ kind, brand_kit_id }))
6298
+ * client.templates.list / .retrieve / .delete (codai Studio templates saved with creatives.saveTemplate; free;
6299
+ * use with creatives.create({ kind, template, vars }))
6300
+ * client.exports.retrieve / .wait (codai Studio FCPXML exports queued with creatives.exportFcpxml; only newly
6301
+ * rendered seconds are billed; Lottie exports from creatives.exportLottie are free and ready at once)
6302
+ * client.batches.create / .dryRun / .list / .get / .cancel / .retry / .exportCsv / .zip / .wait (codai Studio
6303
+ * batches: one creative per CSV / sheet row; free, row translations and renders billed as usual)
6304
+ * client.shares.get / .remix / .comment / .reply / .resolve / .reopen / .decide (codai Studio share links from the
6305
+ * outside: read a shared creative, remix a view link, comment and decide through a review link; free)
6306
+ * client.voiceRevocations.create (public takedown ticket for a voice cloned in codai Studio; no key needed)
6307
+ * client.abuseReports.create (public DSA notice about a codai Studio share / review link; no key needed)
6308
+ * client.provenance.check (public: which codai AI-provenance marks a file carries; no key needed)
4418
6309
  * client.systemOne.create / .batch (typed decisions, codai-s1)
4419
6310
  * client.realtime.connect (WebSocket live STT / voice; not an OpenAPI operation)
4420
6311
  * client.agents.run + client.agents.runs.* client.tools.search / .fetch
@@ -4422,11 +6313,15 @@ var CodaiApps = class {
4422
6313
  * client.tasks.* client.sessions.* (events, controls, lease, shares, stream)
4423
6314
  * client.devices.* / client.hosts.* client.orgs.* / client.account / client.receipt
4424
6315
  * client.settings.get / .update (account-level settings shared by every device)
6316
+ * client.billing.get / .invoices / .watchBalance (READ-ONLY billing overview; never starts a payment)
6317
+ * client.referrals.get / .redeem / .setConsent (referral stats + invitees; mutations via PATCH /v1/account)
4425
6318
  * client.usage.get / client.keys.list / .setTags (own usage breakdown + API keys)
4426
6319
  * client.projects.* client.environments.* (members, ports, secrets)
6320
+ * client.sandboxes.create / .list / .retrieve / .exec / .execStream / .files.put / .files.get / .files.list
6321
+ * / .artifacts / .snapshot / .delete / .run (agent sandboxes, beta: isolated gVisor workspaces, no network by default)
4427
6322
  * client.verify.agentOutputKey / .agentOutput (EXPERIMENTAL HIDE-signed agent outputs)
4428
6323
  * client.feedback / client.phoneModels
4429
- * client.resolve.* (verified bug fixes on https://resolve.codai.ro — resolve.yaml)
6324
+ * client.resolve.* (verified bug fixes on https://resolve.codai.ro — resolve.yaml; .list / .iterate page your jobs)
4430
6325
  *
4431
6326
  * Top-level `chat()`, `chatStream()`, `embeddings()`, `models()`, `feedback()`,
4432
6327
  * `mintToken()` from 0.2.x are kept as thin aliases.
@@ -4455,6 +6350,24 @@ var Codai = class {
4455
6350
  sfx;
4456
6351
  /** codai Studio documents (`documents.create({ type: 'deck', spec })` → PPTX / DOCX / XLSX, codai-docs, free; previews + deck → MP4). */
4457
6352
  documents;
6353
+ /** codai Studio creatives (`creatives.create({ kind: 'video' })`, `.edit(id, { baseSeq, ops })`, `.render(id)`; editable documents with versions, free except renders). */
6354
+ creatives;
6355
+ /** codai Studio brand kits (`brandKits.extract({ url })` → palette + fonts + logo; apply with `creatives.create({ kind, brand_kit_id })`). */
6356
+ brandKits;
6357
+ /** codai Studio templates (`creatives.saveTemplate(id, { vars })` saves one; `templates.list()`; create with `creatives.create({ kind, template, vars })`). */
6358
+ templates;
6359
+ /** codai Studio FCPXML exports (`creatives.exportFcpxml(id)` queues one; `exports.wait(id)` polls until the zip is ready). */
6360
+ exports;
6361
+ /** codai Studio batches (`batches.create({ source: { template_id }, csv })` → one creative per row; `batches.wait(id)`). */
6362
+ batches;
6363
+ /** codai Studio share links from the outside (`shares.get(url)`, `shares.remix(url)`, `shares.comment(url, …)`). */
6364
+ shares;
6365
+ /** Public takedown tickets for voices cloned in codai Studio (`voiceRevocations.create({ email, … })`; no key needed). */
6366
+ voiceRevocations;
6367
+ /** Public abuse reports about codai Studio share / review links (`abuseReports.create({ share_token, … })`; no key needed). */
6368
+ abuseReports;
6369
+ /** Public AI-provenance checker (`provenance.check(file)` → C2PA / RIFF INFO / ID3 / MP4 / XMP marks; no key needed). */
6370
+ provenance;
4458
6371
  /** Typed decisions from codai-s1 (`systemOne.create({ state, questions })`). */
4459
6372
  systemOne;
4460
6373
  tokens;
@@ -4475,6 +6388,8 @@ var Codai = class {
4475
6388
  prompts;
4476
6389
  /** codai Scheduler — cron / natural-language schedules run on any of your hosts or in the cloud (`schedules.create`, `.executor.claim`). */
4477
6390
  schedules;
6391
+ /** Lists and the share sheet — save links, text and media to Inbox / Wishlist / Notes or your own lists (`lists.share`). */
6392
+ lists;
4478
6393
  /** Heartbeat monitors — dead-man switches for crons codai does not run (`heartbeats.create({ name, period_s })` → `ping_url`). */
4479
6394
  heartbeats;
4480
6395
  /** Transcripts — voice recordings → diarized transcripts + insights (feature-flagged per account). */
@@ -4483,17 +6398,25 @@ var Codai = class {
4483
6398
  usage;
4484
6399
  /** Your API keys (device attribution, tags). */
4485
6400
  keys;
6401
+ /** Your persistent memory — the same store as the MCP memory tools (`memory.list/search/create/delete`). */
6402
+ memory;
4486
6403
  sessions;
4487
6404
  devices;
4488
6405
  hosts;
4489
6406
  orgs;
4490
6407
  projects;
4491
6408
  environments;
6409
+ /** Agent sandboxes (beta) — isolated gVisor workspaces: `sandboxes.create/exec/execStream/files/artifacts/run`. */
6410
+ sandboxes;
4492
6411
  /** EXPERIMENTAL (HIDE, unaudited): verify signed agent outputs. Provenance only. */
4493
6412
  verify;
4494
6413
  account;
4495
6414
  /** Account-level settings shared by every device (`settings.get()`, `settings.update(partial, { version })`). */
4496
6415
  settings;
6416
+ /** READ-ONLY billing: plan, wallet, invoices, `watchBalance` (pay via the returned links, never via the SDK). */
6417
+ billing;
6418
+ /** Referral stats and invitees; `redeem(code)` / `setConsent(bool)` go through `PATCH /v1/account`. */
6419
+ referrals;
4497
6420
  receipt;
4498
6421
  feedback;
4499
6422
  phoneModels;
@@ -4527,6 +6450,15 @@ var Codai = class {
4527
6450
  this.assets = new Assets(http);
4528
6451
  this.sfx = new Sfx(http);
4529
6452
  this.documents = new Documents(http);
6453
+ this.creatives = new Creatives(http);
6454
+ this.brandKits = new BrandKits(http);
6455
+ this.templates = new Templates(http);
6456
+ this.exports = new Exports(http);
6457
+ this.batches = new Batches(http);
6458
+ this.shares = new Shares(http);
6459
+ this.voiceRevocations = new VoiceRevocations(http);
6460
+ this.abuseReports = new AbuseReports(http);
6461
+ this.provenance = new Provenance(http);
4530
6462
  this.systemOne = new SystemOne(http);
4531
6463
  this.tokens = new Tokens(http);
4532
6464
  this.realtime = new Realtime({
@@ -4542,19 +6474,24 @@ var Codai = class {
4542
6474
  this.notifications = new Notifications(http);
4543
6475
  this.prompts = new Prompts(http);
4544
6476
  this.schedules = new Schedules(http);
6477
+ this.lists = new Lists(http);
4545
6478
  this.heartbeats = new Heartbeats(http);
4546
6479
  this.transcripts = new Transcripts(http);
4547
6480
  this.usage = new Usage(http);
4548
6481
  this.keys = new Keys(http);
6482
+ this.memory = new Memory(http);
4549
6483
  this.sessions = new Sessions(http);
4550
6484
  this.devices = new Devices(http);
4551
6485
  this.hosts = new Hosts(http);
4552
6486
  this.orgs = new Orgs(http);
4553
6487
  this.projects = new Projects(http);
4554
6488
  this.environments = new Environments(http);
6489
+ this.sandboxes = new Sandboxes(http);
4555
6490
  this.verify = new Verify(http);
4556
6491
  this.account = new Account(http);
4557
6492
  this.settings = new Settings(http);
6493
+ this.billing = new Billing(http);
6494
+ this.referrals = new Referrals(http);
4558
6495
  this.receipt = new Receipts(http);
4559
6496
  this.phoneModels = new PhoneModels(http);
4560
6497
  this.resolve = new Resolve(new HttpClient({
@@ -4647,5 +6584,5 @@ function allKeys(obj) {
4647
6584
  }
4648
6585
 
4649
6586
  //#endregion
4650
- export { Account, AgentRuns, Agents, Assets, Audio, Cards, Chat, ChatCompletions, Codai, Codai as default, CodaiApps, CodaiError, Devices, Documents, Embeddings, EnvironmentMembers, EnvironmentPorts, EnvironmentSecrets, EnvironmentTasks, Environments, Feedback, Health, Heartbeats, Hosts, HttpClient, Images, Keys, Messages, Models, Music, Notifications, OPERATION_METHODS, OrgMembers, Orgs, PhoneModels, Projects, Prompts, RESOLVE_ATTESTATION_PAYLOAD_TYPE, RESOLVE_OPERATION_METHODS, RESOLVE_TERMINAL_STATUSES, Realtime, RealtimeSession, Receipts, Renders, Resolve, ResolveError, ResolveInsufficientFundsError, Responses, STREAMING_OPERATIONS, ScheduleExecutor, SchedulerHosts, Schedules, SessionControls, SessionEvents, SessionLease, SessionShares, Sessions, Settings, Sfx, SystemOne, TUS_CHUNK_BYTES, Tasks, Tokens, Tools, Transcripts, Triggers, Usage, Verify, Videos, extensionHeaders, frameJson, isAssetDto, mergeToolCall, readSse, realtimeUrl, resolveAttestationStatement, settingsConflictCurrent, uploadIdFromLocation, verifyAttestationWithKeys, verifyResolveWebhook };
6587
+ 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, PROVENANCE_MAX_BYTES, PhoneModels, Projects, Prompts, Provenance, RESOLVE_ATTESTATION_PAYLOAD_TYPE, RESOLVE_OPERATION_METHODS, RESOLVE_TERMINAL_STATUSES, Realtime, RealtimeSession, Receipts, Referrals, Renders, 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, Verify, Videos, VoiceRevocations, extensionHeaders, frameJson, isAssetDto, mergeToolCall, readSse, realtimeUrl, resolveAttestationStatement, settingsConflictCurrent, shareTokenFrom, uploadIdFromLocation, verifyAttestationWithKeys, verifyResolveWebhook };
4651
6588
  //# sourceMappingURL=index.js.map