@savantoai/ai-sdk 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,10 +1,11 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
2
 
2
3
  //#region src/generated/core/bodySerializer.gen.ts
3
4
  const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
4
5
 
5
6
  //#endregion
6
7
  //#region src/generated/core/serverSentEvents.gen.ts
7
- const createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) => {
8
+ function createSseClient({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) {
8
9
  let lastEventId;
9
10
  const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
10
11
  const createStream = async function* () {
@@ -42,7 +43,7 @@ const createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransforme
42
43
  const { done, value } = await reader.read();
43
44
  if (done) break;
44
45
  buffer += value;
45
- buffer = buffer.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
46
+ buffer = buffer.replace(/\r\n?/g, "\n");
46
47
  const chunks = buffer.split("\n\n");
47
48
  buffer = chunks.pop() ?? "";
48
49
  for (const chunk of chunks) {
@@ -93,7 +94,7 @@ const createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransforme
93
94
  }
94
95
  };
95
96
  return { stream: createStream() };
96
- };
97
+ }
97
98
 
98
99
  //#endregion
99
100
  //#region src/generated/core/pathSerializer.gen.ts
@@ -123,12 +124,12 @@ const separatorObjectExplode = (style) => {
123
124
  };
124
125
  const serializeArrayParam = ({ allowReserved, explode, name, style, value }) => {
125
126
  if (!explode) {
126
- const joinedValues$1 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
127
+ const joinedValues = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
127
128
  switch (style) {
128
- case "label": return `.${joinedValues$1}`;
129
- case "matrix": return `;${name}=${joinedValues$1}`;
130
- case "simple": return joinedValues$1;
131
- default: return `${name}=${joinedValues$1}`;
129
+ case "label": return `.${joinedValues}`;
130
+ case "matrix": return `;${name}=${joinedValues}`;
131
+ case "simple": return joinedValues;
132
+ default: return `${name}=${joinedValues}`;
132
133
  }
133
134
  }
134
135
  const separator = separatorArrayExplode(style);
@@ -158,12 +159,12 @@ const serializeObjectParam = ({ allowReserved, explode, name, style, value, valu
158
159
  allowReserved ? v : encodeURIComponent(v)
159
160
  ];
160
161
  });
161
- const joinedValues$1 = values.join(",");
162
+ const joinedValues = values.join(",");
162
163
  switch (style) {
163
- case "form": return `${name}=${joinedValues$1}`;
164
- case "label": return `.${joinedValues$1}`;
165
- case "matrix": return `;${name}=${joinedValues$1}`;
166
- default: return joinedValues$1;
164
+ case "form": return `${name}=${joinedValues}`;
165
+ case "label": return `.${joinedValues}`;
166
+ case "matrix": return `;${name}=${joinedValues}`;
167
+ default: return joinedValues;
167
168
  }
168
169
  }
169
170
  const separator = separatorObjectExplode(style);
@@ -338,7 +339,6 @@ const setAuthParams = async ({ security, ...options }) => {
338
339
  case "cookie":
339
340
  options.headers.append("Cookie", `${name}=${token}`);
340
341
  break;
341
- case "header":
342
342
  default:
343
343
  options.headers.set(name, token);
344
344
  break;
@@ -441,8 +441,8 @@ const createConfig = (override = {}) => ({
441
441
  const createClient = (config = {}) => {
442
442
  let _config = mergeConfigs(createConfig(), config);
443
443
  const getConfig = () => ({ ..._config });
444
- const setConfig = (config$1) => {
445
- _config = mergeConfigs(_config, config$1);
444
+ const setConfig = (config) => {
445
+ _config = mergeConfigs(_config, config);
446
446
  return getConfig();
447
447
  };
448
448
  const interceptors = createInterceptors();
@@ -461,107 +461,102 @@ const createClient = (config = {}) => {
461
461
  if (opts.requestValidator) await opts.requestValidator(opts);
462
462
  if (opts.body !== void 0 && opts.bodySerializer) opts.serializedBody = opts.bodySerializer(opts.body);
463
463
  if (opts.body === void 0 || opts.serializedBody === "") opts.headers.delete("Content-Type");
464
+ const resolvedOpts = opts;
464
465
  return {
465
- opts,
466
- url: buildUrl(opts)
466
+ opts: resolvedOpts,
467
+ url: buildUrl(resolvedOpts)
467
468
  };
468
469
  };
469
470
  const request = async (options) => {
470
- const { opts, url } = await beforeRequest(options);
471
- const requestInit = {
472
- redirect: "follow",
473
- ...opts,
474
- body: getValidRequestBody(opts)
475
- };
476
- let request$1 = new Request(url, requestInit);
477
- for (const fn of interceptors.request.fns) if (fn) request$1 = await fn(request$1, opts);
478
- const _fetch = opts.fetch;
471
+ const throwOnError = options.throwOnError ?? _config.throwOnError;
472
+ const responseStyle = options.responseStyle ?? _config.responseStyle;
473
+ let request;
479
474
  let response;
480
475
  try {
481
- response = await _fetch(request$1);
482
- } catch (error$1) {
483
- let finalError$1 = error$1;
484
- for (const fn of interceptors.error.fns) if (fn) finalError$1 = await fn(error$1, void 0, request$1, opts);
485
- finalError$1 = finalError$1 || {};
486
- if (opts.throwOnError) throw finalError$1;
487
- return opts.responseStyle === "data" ? void 0 : {
488
- error: finalError$1,
489
- request: request$1,
490
- response: void 0
476
+ const { opts, url } = await beforeRequest(options);
477
+ const requestInit = {
478
+ redirect: "follow",
479
+ ...opts,
480
+ body: getValidRequestBody(opts)
491
481
  };
492
- }
493
- for (const fn of interceptors.response.fns) if (fn) response = await fn(response, request$1, opts);
494
- const result = {
495
- request: request$1,
496
- response
497
- };
498
- if (response.ok) {
499
- const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
500
- if (response.status === 204 || response.headers.get("Content-Length") === "0") {
501
- let emptyData;
482
+ request = new Request(url, requestInit);
483
+ for (const fn of interceptors.request.fns) if (fn) request = await fn(request, opts);
484
+ const _fetch = opts.fetch;
485
+ response = await _fetch(request);
486
+ for (const fn of interceptors.response.fns) if (fn) response = await fn(response, request, opts);
487
+ const result = {
488
+ request,
489
+ response
490
+ };
491
+ if (response.ok) {
492
+ const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
493
+ if (response.status === 204 || response.headers.get("Content-Length") === "0") {
494
+ let emptyData;
495
+ switch (parseAs) {
496
+ case "arrayBuffer":
497
+ case "blob":
498
+ case "text":
499
+ emptyData = await response[parseAs]();
500
+ break;
501
+ case "formData":
502
+ emptyData = new FormData();
503
+ break;
504
+ case "stream":
505
+ emptyData = response.body;
506
+ break;
507
+ default:
508
+ emptyData = {};
509
+ break;
510
+ }
511
+ return opts.responseStyle === "data" ? emptyData : {
512
+ data: emptyData,
513
+ ...result
514
+ };
515
+ }
516
+ let data;
502
517
  switch (parseAs) {
503
518
  case "arrayBuffer":
504
519
  case "blob":
505
- case "text":
506
- emptyData = await response[parseAs]();
507
- break;
508
520
  case "formData":
509
- emptyData = new FormData();
510
- break;
511
- case "stream":
512
- emptyData = response.body;
521
+ case "text":
522
+ data = await response[parseAs]();
513
523
  break;
514
- case "json":
515
- default:
516
- emptyData = {};
524
+ case "json": {
525
+ const text = await response.text();
526
+ data = text ? JSON.parse(text) : {};
517
527
  break;
528
+ }
529
+ case "stream": return opts.responseStyle === "data" ? response.body : {
530
+ data: response.body,
531
+ ...result
532
+ };
518
533
  }
519
- return opts.responseStyle === "data" ? emptyData : {
520
- data: emptyData,
521
- ...result
522
- };
523
- }
524
- let data;
525
- switch (parseAs) {
526
- case "arrayBuffer":
527
- case "blob":
528
- case "formData":
529
- case "text":
530
- data = await response[parseAs]();
531
- break;
532
- case "json": {
533
- const text = await response.text();
534
- data = text ? JSON.parse(text) : {};
535
- break;
534
+ if (parseAs === "json") {
535
+ if (opts.responseValidator) await opts.responseValidator(data);
536
+ if (opts.responseTransformer) data = await opts.responseTransformer(data);
536
537
  }
537
- case "stream": return opts.responseStyle === "data" ? response.body : {
538
- data: response.body,
538
+ return opts.responseStyle === "data" ? data : {
539
+ data,
539
540
  ...result
540
541
  };
541
542
  }
542
- if (parseAs === "json") {
543
- if (opts.responseValidator) await opts.responseValidator(data);
544
- if (opts.responseTransformer) data = await opts.responseTransformer(data);
545
- }
546
- return opts.responseStyle === "data" ? data : {
547
- data,
548
- ...result
543
+ const textError = await response.text();
544
+ let jsonError;
545
+ try {
546
+ jsonError = JSON.parse(textError);
547
+ } catch {}
548
+ throw jsonError ?? textError;
549
+ } catch (error) {
550
+ let finalError = error;
551
+ for (const fn of interceptors.error.fns) if (fn) finalError = await fn(finalError, response, request, options);
552
+ finalError = finalError || {};
553
+ if (throwOnError) throw finalError;
554
+ return responseStyle === "data" ? void 0 : {
555
+ error: finalError,
556
+ request,
557
+ response
549
558
  };
550
559
  }
551
- const textError = await response.text();
552
- let jsonError;
553
- try {
554
- jsonError = JSON.parse(textError);
555
- } catch {}
556
- const error = jsonError ?? textError;
557
- let finalError = error;
558
- for (const fn of interceptors.error.fns) if (fn) finalError = await fn(error, response, request$1, opts);
559
- finalError = finalError || {};
560
- if (opts.throwOnError) throw finalError;
561
- return opts.responseStyle === "data" ? void 0 : {
562
- error: finalError,
563
- ...result
564
- };
565
560
  };
566
561
  const makeMethodFn = (method) => (options) => request({
567
562
  ...options,
@@ -572,12 +567,11 @@ const createClient = (config = {}) => {
572
567
  return createSseClient({
573
568
  ...opts,
574
569
  body: opts.body,
575
- headers: opts.headers,
576
570
  method,
577
- onRequest: async (url$1, init) => {
578
- let request$1 = new Request(url$1, init);
579
- for (const fn of interceptors.request.fns) if (fn) request$1 = await fn(request$1, opts);
580
- return request$1;
571
+ onRequest: async (url, init) => {
572
+ let request = new Request(url, init);
573
+ for (const fn of interceptors.request.fns) if (fn) request = await fn(request, opts);
574
+ return request;
581
575
  },
582
576
  serializedBody: getValidRequestBody(opts),
583
577
  url
@@ -625,7 +619,7 @@ const client = createClient(createConfig({ baseUrl: "https://api.savanto.ai" }))
625
619
  /**
626
620
  * Send a chat message
627
621
  *
628
- * Send a message and receive AI response. Supports streaming via NDJSON.
622
+ * Send a visitor message through the full multi-agent pipeline: triage classifies intent, query agents retrieve grounded context from the product / post indexes (plus any custom domain agents), and response agents synthesise a grounded answer with product cards or cited content. The response is streamed as NDJSON when `stream: true` (each line is one of `{ type: "token", ... }`, `{ type: "product", ... }`, `{ type: "done" }`), or returned as a single JSON object when `stream: false`. Pass `threadId` to continue a conversation (memories and prior turns are loaded); omit it for a fresh one. Respects the workspace's active persona / system-prompt configuration.
629
623
  */
630
624
  const chat = (options) => (options?.client ?? client).post({
631
625
  security: [{
@@ -642,7 +636,7 @@ const chat = (options) => (options?.client ?? client).post({
642
636
  /**
643
637
  * Start a website crawl
644
638
  *
645
- * Initiate a crawl of a website URL. Pages are discovered and indexed into the knowledge base.
639
+ * Enqueue a crawl of the given root URL for the workspace in `X-Workspace-ID`. The crawler discovers pages via sitemap + link graph, classifies each page (product, product listing, or general content), and indexes products into `savanto-products` and content into `savanto-posts`. This call is asynchronous and returns immediately with a `crawlId`; poll `GET /crawl/{crawlId}/status` to track progress or subscribe to the email notification endpoint to be pinged when it completes. Starting a new crawl while one is already running for the same workspace will be rejected with 409 — cancel the running one first.
646
640
  */
647
641
  const startCrawl = (options) => (options?.client ?? client).post({
648
642
  security: [{
@@ -676,7 +670,7 @@ const scrapeSinglePage = (options) => (options?.client ?? client).post({
676
670
  /**
677
671
  * Get crawl configuration
678
672
  *
679
- * Retrieve the crawl configuration for a workspace.
673
+ * Return the persisted crawl configuration for the workspace (strategy, schedule, include / exclude URL patterns, max-pages budget, user-agent override). Use before a crawl to verify the active rules, or before an `update_crawl_config` call to preserve fields you are not changing.
680
674
  */
681
675
  const getCrawlConfig = (options) => (options?.client ?? client).get({
682
676
  security: [{
@@ -689,7 +683,7 @@ const getCrawlConfig = (options) => (options?.client ?? client).get({
689
683
  /**
690
684
  * Update crawl configuration
691
685
  *
692
- * Update the crawl configuration for a workspace including strategy, schedule, exclude patterns, etc.
686
+ * Replace the crawl configuration for the workspace. Common fields: `strategy` (`full` reindexes everything, `smart` skips pages whose content hash matches the previous crawl), `schedule` (cron-like), `includePatterns` / `excludePatterns` (glob URL filters), `maxPages` (safety cap). Omitted fields are set to their defaults — if you only want to tweak one setting, `GET /crawl/config` first and merge. Changes take effect on the next crawl run.
693
687
  */
694
688
  const updateCrawlConfig = (options) => (options?.client ?? client).put({
695
689
  security: [{
@@ -706,7 +700,7 @@ const updateCrawlConfig = (options) => (options?.client ?? client).put({
706
700
  /**
707
701
  * Get crawl history
708
702
  *
709
- * Retrieve recent crawl history for the tenant.
703
+ * Return a list of recent crawls for the tenant (or the workspace when `X-Workspace-ID` is set), newest first. Each entry has its final status (`completed`, `failed`, `cancelled`), page counts, duration, and any error summary — useful for diagnosing why a site's content is stale.
710
704
  */
711
705
  const getCrawlHistory = (options) => (options?.client ?? client).get({
712
706
  security: [{
@@ -719,7 +713,7 @@ const getCrawlHistory = (options) => (options?.client ?? client).get({
719
713
  /**
720
714
  * Get crawl status
721
715
  *
722
- * Check the progress and status of a running or completed crawl.
716
+ * Return live status for a specific crawl id: `status` (`running`, `completed`, `failed`, `cancelled`), pages discovered / indexed / skipped / failed, elapsed time, and the current URL being processed. Poll every 3–10 seconds while `running`; stop polling once status is terminal. Returns 404 if the crawl id does not belong to the caller's tenant.
723
717
  */
724
718
  const getCrawlStatus = (options) => (options.client ?? client).get({
725
719
  security: [{
@@ -743,6 +737,23 @@ const cancelCrawl = (options) => (options.client ?? client).post({
743
737
  ...options
744
738
  });
745
739
  /**
740
+ * Enroll for a crawl-complete email
741
+ *
742
+ * Requests an email notification when this crawl reaches a terminal state (completed or failed). Intended for the dashboard "continue onboarding, email me when done" CTA. Rejects crawls that have already finished. **Admin-only endpoint.** The `email` in the body is treated as opaque and persisted verbatim; the cloud API does NOT authenticate ownership of that address. Callers holding the admin bearer are trusted to have derived the recipient from an authoritative source (e.g. the signed-in user session on the Next.js proxy). Do NOT expose this route via license-key / public scopes.
743
+ */
744
+ const enrollCrawlNotification = (options) => (options.client ?? client).post({
745
+ security: [{
746
+ scheme: "bearer",
747
+ type: "http"
748
+ }],
749
+ url: "/crawl/{id}/notifications",
750
+ ...options,
751
+ headers: {
752
+ "Content-Type": "application/json",
753
+ ...options.headers
754
+ }
755
+ });
756
+ /**
746
757
  * Scrape or delete a single page
747
758
  *
748
759
  * Scrape a URL and index it into the knowledge base, or delete a previously scraped page.
@@ -775,7 +786,7 @@ const listProducts = (options) => (options?.client ?? client).get({
775
786
  /**
776
787
  * Upsert a product
777
788
  *
778
- * Create or update a product by external ID. Generates vector embeddings for semantic search.
789
+ * Create a new product or update the existing one whose `externalId` matches the body. Embeddings for the product's searchable text are generated and persisted as part of the call, so the product becomes searchable immediately after a successful response. Required fields: `externalId`, `name`. Optional: `description`, `price` (in cents), `priceMin` / `priceMax`, `stockStatus` (`in_stock` | `out_of_stock` | `limited`), `images` (array of URLs), `brand`, `category`, `attributes` (key/value). Workspaces with native Shopify / WooCommerce sync should normally rely on the plugin rather than calling this endpoint directly. Idempotent on `externalId`.
779
790
  */
780
791
  const upsertProduct = (options) => (options?.client ?? client).post({
781
792
  security: [{
@@ -826,7 +837,7 @@ const bulkUpsertProducts = (options) => (options?.client ?? client).post({
826
837
  /**
827
838
  * Search products
828
839
  *
829
- * Semantic search across products with optional filters and facets. Uses AI agent for query enhancement when beneficial.
840
+ * Hybrid (BM25 + k-NN vector) search across the workspace's product catalog. Pass a natural-language `query` — the backend expands and filters it with an agent when that improves recall. Optional `filters` support `priceMin` / `priceMax`, `stockStatus`, `brand`, `category`, and arbitrary `attributes` equality. Optional `facets` returns aggregate counts for the requested fields. Use for "find X" style requests; use the chat endpoint instead if you want a conversational answer that cites the products.
830
841
  */
831
842
  const searchProducts = (options) => (options?.client ?? client).post({
832
843
  security: [{
@@ -916,7 +927,7 @@ const patchProduct = (options) => (options.client ?? client).patch({
916
927
  /**
917
928
  * Upsert a post
918
929
  *
919
- * Create or update a post by external ID. Generates vector embeddings for semantic search.
930
+ * Create a new post / knowledge article or update the existing one whose `externalId` matches the body. Embeddings are generated synchronously so the post is immediately retrievable by chat and search. Required: `externalId`, `title`, `content` (markdown or plain text). Optional: `author`, `publishedAt` (ISO 8601), `url`, `tags`, `category`. Use this for help-center articles, FAQ entries, or arbitrary brand content that should be answerable via chat. For bulk backfills prefer `POST /posts/bulk`. Idempotent on `externalId`.
920
931
  */
921
932
  const upsertPost = (options) => (options?.client ?? client).post({
922
933
  security: [{
@@ -967,7 +978,7 @@ const bulkUpsertPosts = (options) => (options?.client ?? client).post({
967
978
  /**
968
979
  * Search posts
969
980
  *
970
- * Semantic search across posts with optional filters. Uses AI agent for query enhancement when beneficial.
981
+ * Hybrid semantic + lexical search across the workspace's indexed posts / knowledge articles. Pass a natural-language `query`; the response returns the top-matching posts with excerpts, scores, and URLs. Use when you need raw passages to feed another agent; use the chat endpoint when you want a cited, synthesised answer rather than a list of hits.
971
982
  */
972
983
  const searchPosts = (options) => (options?.client ?? client).post({
973
984
  security: [{
@@ -1697,6 +1708,19 @@ const getTenantStatus = (options) => (options?.client ?? client).get({
1697
1708
  ...options
1698
1709
  });
1699
1710
  /**
1711
+ * Identity probe (tenant, scopes, key type)
1712
+ *
1713
+ * Return the tenant ID, tier, API key ID, key type, and scope list for the current caller. Designed for agent / MCP bootstrapping so clients can decide which operations are available before issuing them. Does NOT return any secret material.
1714
+ */
1715
+ const getTenantWhoami = (options) => (options?.client ?? client).get({
1716
+ security: [{
1717
+ scheme: "bearer",
1718
+ type: "http"
1719
+ }],
1720
+ url: "/tenant/whoami",
1721
+ ...options
1722
+ });
1723
+ /**
1700
1724
  * Update tenant feature flags
1701
1725
  */
1702
1726
  const updateTenantFeatures = (options) => (options?.client ?? client).patch({
@@ -1713,6 +1737,8 @@ const updateTenantFeatures = (options) => (options?.client ?? client).patch({
1713
1737
  });
1714
1738
  /**
1715
1739
  * Get usage summary
1740
+ *
1741
+ * Return the authenticated tenant's current-period usage against plan limits: chat messages sent, products indexed, posts indexed, crawl pages processed, and the dates of the billing window. Use for quota-aware UX or to warn a user that the next operation would trip an overage.
1716
1742
  */
1717
1743
  const getTenantUsage = (options) => (options?.client ?? client).get({
1718
1744
  security: [{
@@ -1736,7 +1762,7 @@ const getTenantUsageHistory = (options) => (options?.client ?? client).get({
1736
1762
  /**
1737
1763
  * List workspaces
1738
1764
  *
1739
- * List all workspaces for the authenticated tenant.
1765
+ * Return every workspace owned by the authenticated tenant, with each workspace's id, name, platform (wordpress | shopify | custom | none), and domain. Use this before calling any workspace-scoped endpoint (crawl, products, posts, chat) to discover the correct `workspaceId` to pass via the `X-Workspace-ID` header. Always cheap and safe to call repeatedly.
1740
1766
  */
1741
1767
  const listTenantWorkspaces = (options) => (options?.client ?? client).get({
1742
1768
  security: [{
@@ -1749,7 +1775,7 @@ const listTenantWorkspaces = (options) => (options?.client ?? client).get({
1749
1775
  /**
1750
1776
  * Create a workspace
1751
1777
  *
1752
- * Create a new workspace under the authenticated tenant.
1778
+ * Create a new workspace (a distinct site / storefront) under the authenticated tenant. Returns the workspace id you will pass as `X-Workspace-ID` on every subsequent content, crawl, and chat request. Typical onboarding flow: create → (optionally set platform) → start crawl → ingest products/posts. Creation does NOT enqueue a crawl — call `POST /crawl` separately.
1753
1779
  */
1754
1780
  const createTenantWorkspace = (options) => (options?.client ?? client).post({
1755
1781
  security: [{
@@ -1765,6 +1791,8 @@ const createTenantWorkspace = (options) => (options?.client ?? client).post({
1765
1791
  });
1766
1792
  /**
1767
1793
  * Delete a workspace
1794
+ *
1795
+ * Permanently delete a workspace and every document indexed under it (products, posts, taxonomies, chat threads, crawl history). This is NOT recoverable — prefer `POST /workspaces` to create a new one rather than delete + recreate for routine cleanup. Returns 404 if the id does not belong to the caller's tenant.
1768
1796
  */
1769
1797
  const deleteWorkspace = (options) => (options.client ?? client).delete({
1770
1798
  security: [{
@@ -1776,6 +1804,8 @@ const deleteWorkspace = (options) => (options.client ?? client).delete({
1776
1804
  });
1777
1805
  /**
1778
1806
  * Update a workspace
1807
+ *
1808
+ * Patch name, platform, or metadata on an existing workspace. Accepts a partial body; omitted fields are left untouched. Changing `platform` from `none` to `wordpress` / `shopify` signals the ingestion pipeline to prefer native sync over crawl-derived content on subsequent operations.
1779
1809
  */
1780
1810
  const updateWorkspace = (options) => (options.client ?? client).put({
1781
1811
  security: [{
@@ -1873,7 +1903,7 @@ const getCredentialStatus = (options) => (options?.client ?? client).get({
1873
1903
  scheme: "bearer",
1874
1904
  type: "http"
1875
1905
  }],
1876
- url: "/tenant/credentials/status",
1906
+ url: "/tenant/live-agent/credentials/status",
1877
1907
  ...options
1878
1908
  });
1879
1909
  /**
@@ -1884,7 +1914,7 @@ const deleteCredentials = (options) => (options?.client ?? client).delete({
1884
1914
  scheme: "bearer",
1885
1915
  type: "http"
1886
1916
  }],
1887
- url: "/tenant/credentials",
1917
+ url: "/tenant/live-agent/credentials",
1888
1918
  ...options
1889
1919
  });
1890
1920
  /**
@@ -1895,7 +1925,7 @@ const storeCredentials = (options) => (options?.client ?? client).post({
1895
1925
  scheme: "bearer",
1896
1926
  type: "http"
1897
1927
  }],
1898
- url: "/tenant/credentials",
1928
+ url: "/tenant/live-agent/credentials",
1899
1929
  ...options,
1900
1930
  headers: {
1901
1931
  "Content-Type": "application/json",
@@ -1910,7 +1940,7 @@ const deleteLiveAgentSchedule = (options) => (options?.client ?? client).delete(
1910
1940
  scheme: "bearer",
1911
1941
  type: "http"
1912
1942
  }],
1913
- url: "/tenant/schedule",
1943
+ url: "/tenant/live-agent/schedule",
1914
1944
  ...options
1915
1945
  });
1916
1946
  /**
@@ -1921,7 +1951,7 @@ const getLiveAgentSchedule = (options) => (options?.client ?? client).get({
1921
1951
  scheme: "bearer",
1922
1952
  type: "http"
1923
1953
  }],
1924
- url: "/tenant/schedule",
1954
+ url: "/tenant/live-agent/schedule",
1925
1955
  ...options
1926
1956
  });
1927
1957
  /**
@@ -1932,7 +1962,7 @@ const updateLiveAgentSchedule = (options) => (options?.client ?? client).put({
1932
1962
  scheme: "bearer",
1933
1963
  type: "http"
1934
1964
  }],
1935
- url: "/tenant/schedule",
1965
+ url: "/tenant/live-agent/schedule",
1936
1966
  ...options,
1937
1967
  headers: {
1938
1968
  "Content-Type": "application/json",
@@ -2164,6 +2194,8 @@ const testDomainConnection = (options) => (options.client ?? client).post({
2164
2194
  });
2165
2195
  /**
2166
2196
  * Get workspace details
2197
+ *
2198
+ * Return the full configuration for a workspace: platform, domain, crawl config, widget settings, chat persona, live-agent handoff, custom domains, and document counts. Preferred read for agent bootstrap because it returns every knob in one call.
2167
2199
  */
2168
2200
  const getWorkspaceDetails = (options) => (options.client ?? client).get({
2169
2201
  security: [{
@@ -2460,6 +2492,40 @@ const adminResetCrawls = (options) => (options.client ?? client).post({
2460
2492
  url: "/admin/tenant/{tenantId}/crawls/reset",
2461
2493
  ...options
2462
2494
  });
2495
+ /**
2496
+ * Redact a customer across all stored PII
2497
+ *
2498
+ * Hard-deletes every thread document and memory document within the caller tenant that matches the supplied customer identifiers. Runs as async OpenSearch tasks; the response contains task IDs for reconciliation. Idempotent when `caller.externalId` is supplied.
2499
+ */
2500
+ const complianceCustomerRedact = (options) => (options?.client ?? client).post({
2501
+ security: [{
2502
+ scheme: "bearer",
2503
+ type: "http"
2504
+ }],
2505
+ url: "/compliance/customer-redact",
2506
+ ...options,
2507
+ headers: {
2508
+ "Content-Type": "application/json",
2509
+ ...options?.headers
2510
+ }
2511
+ });
2512
+ /**
2513
+ * Record a customer data-export request
2514
+ *
2515
+ * Queues a customer data-export request and notifies ops to fulfill it within Shopify's 30-day SLA. Idempotent when `caller.externalId` is supplied.
2516
+ */
2517
+ const complianceCustomerDataRequest = (options) => (options?.client ?? client).post({
2518
+ security: [{
2519
+ scheme: "bearer",
2520
+ type: "http"
2521
+ }],
2522
+ url: "/compliance/customer-data-request",
2523
+ ...options,
2524
+ headers: {
2525
+ "Content-Type": "application/json",
2526
+ ...options?.headers
2527
+ }
2528
+ });
2463
2529
 
2464
2530
  //#endregion
2465
2531
  //#region src/util.ts
@@ -2508,6 +2574,8 @@ exports.chat = chat;
2508
2574
  exports.clearDomainErrors = clearDomainErrors;
2509
2575
  exports.client = client;
2510
2576
  exports.commitSearch = commitSearch;
2577
+ exports.complianceCustomerDataRequest = complianceCustomerDataRequest;
2578
+ exports.complianceCustomerRedact = complianceCustomerRedact;
2511
2579
  exports.createApiKey = createApiKey;
2512
2580
  exports.createClient = createClient;
2513
2581
  exports.createConfig = createConfig;
@@ -2533,6 +2601,7 @@ exports.deleteWorkspace = deleteWorkspace;
2533
2601
  exports.deprovision = deprovision;
2534
2602
  exports.discoverTools = discoverTools;
2535
2603
  exports.endHandoff = endHandoff;
2604
+ exports.enrollCrawlNotification = enrollCrawlNotification;
2536
2605
  exports.exportThreads = exportThreads;
2537
2606
  exports.generateDomainConfig = generateDomainConfig;
2538
2607
  exports.getAnalyticsFeedback = getAnalyticsFeedback;
@@ -2560,6 +2629,7 @@ exports.getTaxonomy = getTaxonomy;
2560
2629
  exports.getTenantStatus = getTenantStatus;
2561
2630
  exports.getTenantUsage = getTenantUsage;
2562
2631
  exports.getTenantUsageHistory = getTenantUsageHistory;
2632
+ exports.getTenantWhoami = getTenantWhoami;
2563
2633
  exports.getThread = getThread;
2564
2634
  exports.getThreadAnalytics = getThreadAnalytics;
2565
2635
  exports.getThreadFeedback = getThreadFeedback;