assistant-cloud 0.1.40 → 0.1.42

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.
Files changed (57) hide show
  1. package/README.md +3 -3
  2. package/dist/AssistantCloud.js +2 -2
  3. package/dist/AssistantCloud.js.map +1 -1
  4. package/dist/AssistantCloudAPI.d.ts.map +1 -1
  5. package/dist/AssistantCloudAPI.js +5 -5
  6. package/dist/AssistantCloudAPI.js.map +1 -1
  7. package/dist/AssistantCloudAuthStrategy.d.ts.map +1 -1
  8. package/dist/AssistantCloudAuthStrategy.js +35 -12
  9. package/dist/AssistantCloudAuthStrategy.js.map +1 -1
  10. package/dist/AssistantCloudAuthTokens.d.ts.map +1 -1
  11. package/dist/AssistantCloudAuthTokens.js +3 -1
  12. package/dist/AssistantCloudAuthTokens.js.map +1 -1
  13. package/dist/AssistantCloudFiles.d.ts.map +1 -1
  14. package/dist/AssistantCloudFiles.js +16 -4
  15. package/dist/AssistantCloudFiles.js.map +1 -1
  16. package/dist/AssistantCloudRuns.d.ts +3 -13
  17. package/dist/AssistantCloudRuns.d.ts.map +1 -1
  18. package/dist/AssistantCloudRuns.js +10 -2
  19. package/dist/AssistantCloudRuns.js.map +1 -1
  20. package/dist/AssistantCloudThreadMessages.d.ts.map +1 -1
  21. package/dist/AssistantCloudThreadMessages.js +3 -2
  22. package/dist/AssistantCloudThreadMessages.js.map +1 -1
  23. package/dist/AssistantCloudThreads.d.ts.map +1 -1
  24. package/dist/AssistantCloudThreads.js +3 -2
  25. package/dist/AssistantCloudThreads.js.map +1 -1
  26. package/dist/generateThreadTitle.d.ts +15 -0
  27. package/dist/generateThreadTitle.d.ts.map +1 -0
  28. package/dist/generateThreadTitle.js +25 -0
  29. package/dist/generateThreadTitle.js.map +1 -0
  30. package/dist/index.d.ts +3 -1
  31. package/dist/index.js +3 -1
  32. package/dist/runTelemetry.d.ts +54 -0
  33. package/dist/runTelemetry.d.ts.map +1 -0
  34. package/dist/runTelemetry.js +79 -0
  35. package/dist/runTelemetry.js.map +1 -0
  36. package/package.json +5 -5
  37. package/src/AssistantCloud.ts +1 -1
  38. package/src/AssistantCloudAPI.ts +9 -8
  39. package/src/AssistantCloudAuthStrategy.ts +49 -12
  40. package/src/AssistantCloudAuthTokens.test.ts +30 -0
  41. package/src/AssistantCloudAuthTokens.ts +7 -1
  42. package/src/AssistantCloudFiles.test.ts +71 -0
  43. package/src/AssistantCloudFiles.ts +56 -10
  44. package/src/AssistantCloudRuns.ts +37 -15
  45. package/src/AssistantCloudThreadMessages.test.ts +20 -0
  46. package/src/AssistantCloudThreadMessages.ts +10 -3
  47. package/src/AssistantCloudThreads.test.ts +17 -0
  48. package/src/AssistantCloudThreads.ts +6 -1
  49. package/src/generateThreadTitle.test.ts +71 -0
  50. package/src/generateThreadTitle.ts +38 -0
  51. package/src/index.ts +10 -0
  52. package/src/runTelemetry.test.ts +130 -0
  53. package/src/runTelemetry.ts +140 -0
  54. package/src/tests/AssistantCloud.test.ts +39 -0
  55. package/src/tests/AssistantCloudAPI.test.ts +25 -0
  56. package/src/tests/AssistantCloudAuthStrategy.test.ts +278 -5
  57. package/src/tests/AssistantCloudRuns.test.ts +115 -0
package/README.md CHANGED
@@ -9,16 +9,16 @@ Server- and client-side SDK for [Assistant Cloud](https://cloud.assistant-ui.com
9
9
  ## Installation
10
10
 
11
11
  ```bash
12
- npm install @assistant-ui/react @assistant-ui/react-ai-sdk assistant-cloud
12
+ npm install @assistant-ui/react @assistant-ui/ai-sdk assistant-cloud
13
13
  ```
14
14
 
15
15
  ## Usage
16
16
 
17
- Pass an `AssistantCloud` instance to your runtime hook (typically `useChatRuntime` from `@assistant-ui/react-ai-sdk`):
17
+ Pass an `AssistantCloud` instance to your runtime hook (typically `useChatRuntime` from `@assistant-ui/ai-sdk`):
18
18
 
19
19
  ```tsx
20
20
  import { AssistantCloud, AssistantRuntimeProvider } from "@assistant-ui/react";
21
- import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
21
+ import { useChatRuntime } from "@assistant-ui/ai-sdk";
22
22
 
23
23
  const cloud = new AssistantCloud({
24
24
  baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
@@ -21,8 +21,8 @@ var AssistantCloud = class {
21
21
  this.files = new AssistantCloudFiles(api);
22
22
  const t = config.telemetry;
23
23
  this.telemetry = t === false ? { enabled: false } : t === true || t === void 0 ? { enabled: true } : {
24
- enabled: t.enabled !== false,
25
- ...t
24
+ ...t,
25
+ enabled: t.enabled !== false
26
26
  };
27
27
  }
28
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloud.js","names":[],"sources":["../src/AssistantCloud.ts"],"sourcesContent":["import {\n AssistantCloudAPI,\n type AssistantCloudConfig,\n type AssistantCloudTelemetryConfig,\n} from \"./AssistantCloudAPI\";\nimport { AssistantCloudAuthTokens } from \"./AssistantCloudAuthTokens\";\nimport { AssistantCloudProjects } from \"./AssistantCloudProjects\";\nimport { AssistantCloudRuns } from \"./AssistantCloudRuns\";\nimport { AssistantCloudThreads } from \"./AssistantCloudThreads\";\nimport { AssistantCloudFiles } from \"./AssistantCloudFiles\";\n\nexport class AssistantCloud {\n public readonly threads;\n public readonly projects;\n public readonly auth;\n public readonly runs;\n public readonly files;\n public readonly telemetry: AssistantCloudTelemetryConfig;\n\n constructor(config: AssistantCloudConfig) {\n const api = new AssistantCloudAPI(config);\n this.threads = new AssistantCloudThreads(api);\n this.projects = new AssistantCloudProjects(api);\n this.auth = {\n tokens: new AssistantCloudAuthTokens(api),\n };\n this.runs = new AssistantCloudRuns(api);\n this.files = new AssistantCloudFiles(api);\n\n const t = config.telemetry;\n this.telemetry =\n t === false\n ? { enabled: false }\n : t === true || t === undefined\n ? { enabled: true }\n : { enabled: t.enabled !== false, ...t };\n }\n}\n"],"mappings":";;;;;;;AAWA,IAAa,iBAAb,MAA4B;CAC1B;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,QAA8B;EACxC,MAAM,MAAM,IAAI,kBAAkB,MAAM;EACxC,KAAK,UAAU,IAAI,sBAAsB,GAAG;EAC5C,KAAK,WAAW,IAAI,uBAAuB,GAAG;EAC9C,KAAK,OAAO,EACV,QAAQ,IAAI,yBAAyB,GAAG,EAC1C;EACA,KAAK,OAAO,IAAI,mBAAmB,GAAG;EACtC,KAAK,QAAQ,IAAI,oBAAoB,GAAG;EAExC,MAAM,IAAI,OAAO;EACjB,KAAK,YACH,MAAM,QACF,EAAE,SAAS,MAAM,IACjB,MAAM,QAAQ,MAAM,KAAA,IAClB,EAAE,SAAS,KAAK,IAChB;GAAE,SAAS,EAAE,YAAY;GAAO,GAAG;EAAE;CAC/C;AACF"}
1
+ {"version":3,"file":"AssistantCloud.js","names":[],"sources":["../src/AssistantCloud.ts"],"sourcesContent":["import {\n AssistantCloudAPI,\n type AssistantCloudConfig,\n type AssistantCloudTelemetryConfig,\n} from \"./AssistantCloudAPI\";\nimport { AssistantCloudAuthTokens } from \"./AssistantCloudAuthTokens\";\nimport { AssistantCloudProjects } from \"./AssistantCloudProjects\";\nimport { AssistantCloudRuns } from \"./AssistantCloudRuns\";\nimport { AssistantCloudThreads } from \"./AssistantCloudThreads\";\nimport { AssistantCloudFiles } from \"./AssistantCloudFiles\";\n\nexport class AssistantCloud {\n public readonly threads;\n public readonly projects;\n public readonly auth;\n public readonly runs;\n public readonly files;\n public readonly telemetry: AssistantCloudTelemetryConfig;\n\n constructor(config: AssistantCloudConfig) {\n const api = new AssistantCloudAPI(config);\n this.threads = new AssistantCloudThreads(api);\n this.projects = new AssistantCloudProjects(api);\n this.auth = {\n tokens: new AssistantCloudAuthTokens(api),\n };\n this.runs = new AssistantCloudRuns(api);\n this.files = new AssistantCloudFiles(api);\n\n const t = config.telemetry;\n this.telemetry =\n t === false\n ? { enabled: false }\n : t === true || t === undefined\n ? { enabled: true }\n : { ...t, enabled: t.enabled !== false };\n }\n}\n"],"mappings":";;;;;;;AAWA,IAAa,iBAAb,MAA4B;CAC1B;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,QAA8B;EACxC,MAAM,MAAM,IAAI,kBAAkB,MAAM;EACxC,KAAK,UAAU,IAAI,sBAAsB,GAAG;EAC5C,KAAK,WAAW,IAAI,uBAAuB,GAAG;EAC9C,KAAK,OAAO,EACV,QAAQ,IAAI,yBAAyB,GAAG,EAC1C;EACA,KAAK,OAAO,IAAI,mBAAmB,GAAG;EACtC,KAAK,QAAQ,IAAI,oBAAoB,GAAG;EAExC,MAAM,IAAI,OAAO;EACjB,KAAK,YACH,MAAM,QACF,EAAE,SAAS,MAAM,IACjB,MAAM,QAAQ,MAAM,KAAA,IAClB,EAAE,SAAS,KAAK,IAChB;GAAE,GAAG;GAAG,SAAS,EAAE,YAAY;EAAM;CAC/C;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAPI.d.ts","names":[],"sources":["../src/AssistantCloudAPI.ts"],"mappings":";;;KAQY;EACV;;;;;;EAMA,gBACE,QAAQ,4BACL;;KAGK;EAEN;EACA,iBAAiB;;EAGjB;EACA;EACA;EACA;;EAGA;EACA;;;;;;;;;;;;;EAcJ,sBAAsB;;cAGX,sBAAsB;WACjB;EAEJ,YAAA,iBAAiB;;KAO1B;EACH;EACA,UAAU;EACV,QAAQ;EACR;;cAQW;EACJ,OAAO;EACP;EAEK,YAAA,QAAQ;EAuBP,kBAAc;EAId,eACX,kBACA,UAAS,qBAAuB,QAAA;EAmDrB,YAAY,kBAAkB,UAAS,qBAAuB"}
1
+ {"version":3,"file":"AssistantCloudAPI.d.ts","names":[],"sources":["../src/AssistantCloudAPI.ts"],"mappings":";;;KAQY;EACV;;;;;;EAMA,gBACE,QAAQ,4BACL;;KAGK;EAEN;EACA,iBAAiB;;EAGjB;EACA;EACA;EACA;;EAGA;EACA;;;;;;;;;;;;;EAcJ,sBAAsB;;cAGX,sBAAsB;WACjB;EAEJ,YAAA,iBAAiB;;KAO1B;EACH;EACA,UAAU;EACV,QAAQ;EACR;;cAQW;EACJ,OAAO;EACP;EAEK,YAAA,QAAQ;EAuBP,kBAAc;EAId,eACX,kBACA,UAAS,qBAAuB,QAAA;EAoDrB,YAAY,kBAAkB,UAAS,qBAAuB"}
@@ -54,12 +54,12 @@ var AssistantCloudAPI = class {
54
54
  this._auth.readAuthHeaders(response.headers);
55
55
  if (!response.ok) {
56
56
  const text = await response.text();
57
+ let message;
57
58
  try {
58
- throw new CloudAPIError(JSON.parse(text).message, response.status);
59
- } catch (error) {
60
- if (error instanceof CloudAPIError) throw error;
61
- throw new CloudAPIError(`Request failed with status ${response.status}, ${text}`, response.status);
62
- }
59
+ const body = JSON.parse(text);
60
+ if (typeof body?.message === "string" && body.message.length > 0) message = body.message;
61
+ } catch {}
62
+ throw new CloudAPIError(message ?? `Request failed with status ${response.status}, ${text}`, response.status);
63
63
  }
64
64
  return response;
65
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAPI.js","names":[],"sources":["../src/AssistantCloudAPI.ts"],"sourcesContent":["import {\n type AssistantCloudAuthStrategy,\n AssistantCloudJWTAuthStrategy,\n AssistantCloudAPIKeyAuthStrategy,\n AssistantCloudAnonymousAuthStrategy,\n} from \"./AssistantCloudAuthStrategy\";\nimport type { AssistantCloudRunReport } from \"./AssistantCloudRuns\";\n\nexport type AssistantCloudTelemetryConfig = {\n enabled?: boolean;\n /**\n * Called before each telemetry report is sent.\n * Return a modified report to enrich it (e.g. add `model_id`),\n * or return `null` to skip the report.\n */\n beforeReport?: (\n report: AssistantCloudRunReport,\n ) => AssistantCloudRunReport | null;\n};\n\nexport type AssistantCloudConfig = (\n | {\n baseUrl: string;\n authToken: () => Promise<string | null>;\n }\n | {\n baseUrl?: string;\n apiKey: string;\n userId: string;\n workspaceId: string;\n }\n | {\n baseUrl: string;\n anonymous: true;\n }\n) & {\n /**\n * Client-side run telemetry reporting. Default: `true`.\n *\n * When enabled, the SDK automatically reports run metadata (status, step\n * count, tool calls, and token usage) to Assistant Cloud after each\n * assistant message is saved. No message content is sent.\n *\n * - `true` / `undefined` — enabled with defaults\n * - `false` — disabled\n * - `{ beforeReport }` — enabled with a hook to enrich or filter reports\n */\n telemetry?: boolean | AssistantCloudTelemetryConfig;\n};\n\nexport class CloudAPIError extends Error {\n public readonly status: number;\n\n constructor(message: string, status: number) {\n super(message);\n this.status = status;\n this.name = \"CloudAPIError\";\n }\n}\n\ntype MakeRequestOptions = {\n method?: \"POST\" | \"PUT\" | \"DELETE\" | undefined;\n headers?: Record<string, string> | undefined;\n query?: Record<string, string | number | boolean> | undefined;\n body?: object | undefined;\n};\n\nconst normalizeBaseUrl = (baseUrl: string) => {\n if (!baseUrl || !baseUrl.endsWith(\"/\")) return baseUrl;\n return baseUrl.slice(0, -1);\n};\n\nexport class AssistantCloudAPI {\n public _auth: AssistantCloudAuthStrategy;\n public _baseUrl;\n\n constructor(config: AssistantCloudConfig) {\n if (\"authToken\" in config) {\n this._baseUrl = normalizeBaseUrl(config.baseUrl);\n this._auth = new AssistantCloudJWTAuthStrategy(config.authToken);\n } else if (\"apiKey\" in config) {\n this._baseUrl = normalizeBaseUrl(\n config.baseUrl ?? \"https://backend.assistant-api.com\",\n );\n this._auth = new AssistantCloudAPIKeyAuthStrategy(\n config.apiKey,\n config.userId,\n config.workspaceId,\n );\n } else if (\"anonymous\" in config) {\n this._baseUrl = normalizeBaseUrl(config.baseUrl);\n this._auth = new AssistantCloudAnonymousAuthStrategy(this._baseUrl);\n } else {\n throw new Error(\n \"Invalid configuration: Must provide authToken, apiKey, or anonymous configuration\",\n );\n }\n }\n\n public async initializeAuth() {\n return !!(await this._auth.getAuthHeaders());\n }\n\n public async makeRawRequest(\n endpoint: string,\n options: MakeRequestOptions = {},\n ) {\n const authHeaders = await this._auth.getAuthHeaders();\n if (!authHeaders) throw new Error(\"Authorization failed\");\n\n const headers = {\n ...authHeaders,\n ...options.headers,\n \"Content-Type\": \"application/json\",\n };\n\n const queryParams = new URLSearchParams();\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value === false) continue;\n if (value === true) {\n queryParams.set(key, \"true\");\n } else {\n queryParams.set(key, value.toString());\n }\n }\n }\n\n const url = new URL(`${this._baseUrl}/v1${endpoint}`);\n url.search = queryParams.toString();\n\n const response = await fetch(url, {\n method: options.method ?? \"GET\",\n headers,\n body: options.body ? JSON.stringify(options.body) : null,\n });\n\n this._auth.readAuthHeaders(response.headers);\n\n if (!response.ok) {\n const text = await response.text();\n try {\n const body = JSON.parse(text);\n throw new CloudAPIError(body.message, response.status);\n } catch (error) {\n if (error instanceof CloudAPIError) throw error;\n throw new CloudAPIError(\n `Request failed with status ${response.status}, ${text}`,\n response.status,\n );\n }\n }\n\n return response;\n }\n\n public async makeRequest(endpoint: string, options: MakeRequestOptions = {}) {\n const response = await this.makeRawRequest(endpoint, options);\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n )\n return undefined;\n\n const text = await response.text();\n if (text.trim() === \"\") return undefined;\n\n return JSON.parse(text);\n }\n}\n"],"mappings":";;AAkDA,IAAa,gBAAb,cAAmC,MAAM;CACvC;CAEA,YAAY,SAAiB,QAAgB;EAC3C,MAAM,OAAO;EACb,KAAK,SAAS;EACd,KAAK,OAAO;CACd;AACF;AASA,MAAM,oBAAoB,YAAoB;CAC5C,IAAI,CAAC,WAAW,CAAC,QAAQ,SAAS,GAAG,GAAG,OAAO;CAC/C,OAAO,QAAQ,MAAM,GAAG,EAAE;AAC5B;AAEA,IAAa,oBAAb,MAA+B;CAC7B;CACA;CAEA,YAAY,QAA8B;EACxC,IAAI,eAAe,QAAQ;GACzB,KAAK,WAAW,iBAAiB,OAAO,OAAO;GAC/C,KAAK,QAAQ,IAAI,8BAA8B,OAAO,SAAS;EACjE,OAAO,IAAI,YAAY,QAAQ;GAC7B,KAAK,WAAW,iBACd,OAAO,WAAW,mCACpB;GACA,KAAK,QAAQ,IAAI,iCACf,OAAO,QACP,OAAO,QACP,OAAO,WACT;EACF,OAAO,IAAI,eAAe,QAAQ;GAChC,KAAK,WAAW,iBAAiB,OAAO,OAAO;GAC/C,KAAK,QAAQ,IAAI,oCAAoC,KAAK,QAAQ;EACpE,OACE,MAAM,IAAI,MACR,mFACF;CAEJ;CAEA,MAAa,iBAAiB;EAC5B,OAAO,CAAC,CAAE,MAAM,KAAK,MAAM,eAAe;CAC5C;CAEA,MAAa,eACX,UACA,UAA8B,CAAC,GAC/B;EACA,MAAM,cAAc,MAAM,KAAK,MAAM,eAAe;EACpD,IAAI,CAAC,aAAa,MAAM,IAAI,MAAM,sBAAsB;EAExD,MAAM,UAAU;GACd,GAAG;GACH,GAAG,QAAQ;GACX,gBAAgB;EAClB;EAEA,MAAM,cAAc,IAAI,gBAAgB;EACxC,IAAI,QAAQ,OACV,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,KAAK,GAAG;GACxD,IAAI,UAAU,OAAO;GACrB,IAAI,UAAU,MACZ,YAAY,IAAI,KAAK,MAAM;QAE3B,YAAY,IAAI,KAAK,MAAM,SAAS,CAAC;EAEzC;EAGF,MAAM,MAAM,IAAI,IAAI,GAAG,KAAK,SAAS,KAAK,UAAU;EACpD,IAAI,SAAS,YAAY,SAAS;EAElC,MAAM,WAAW,MAAM,MAAM,KAAK;GAChC,QAAQ,QAAQ,UAAU;GAC1B;GACA,MAAM,QAAQ,OAAO,KAAK,UAAU,QAAQ,IAAI,IAAI;EACtD,CAAC;EAED,KAAK,MAAM,gBAAgB,SAAS,OAAO;EAE3C,IAAI,CAAC,SAAS,IAAI;GAChB,MAAM,OAAO,MAAM,SAAS,KAAK;GACjC,IAAI;IAEF,MAAM,IAAI,cADG,KAAK,MAAM,IACA,CAAA,CAAK,SAAS,SAAS,MAAM;GACvD,SAAS,OAAO;IACd,IAAI,iBAAiB,eAAe,MAAM;IAC1C,MAAM,IAAI,cACR,8BAA8B,SAAS,OAAO,IAAI,QAClD,SAAS,MACX;GACF;EACF;EAEA,OAAO;CACT;CAEA,MAAa,YAAY,UAAkB,UAA8B,CAAC,GAAG;EAC3E,MAAM,WAAW,MAAM,KAAK,eAAe,UAAU,OAAO;EAC5D,IACE,SAAS,WAAW,OACpB,SAAS,QAAQ,IAAI,gBAAgB,MAAM,KAE3C,OAAO,KAAA;EAET,MAAM,OAAO,MAAM,SAAS,KAAK;EACjC,IAAI,KAAK,KAAK,MAAM,IAAI,OAAO,KAAA;EAE/B,OAAO,KAAK,MAAM,IAAI;CACxB;AACF"}
1
+ {"version":3,"file":"AssistantCloudAPI.js","names":[],"sources":["../src/AssistantCloudAPI.ts"],"sourcesContent":["import {\n type AssistantCloudAuthStrategy,\n AssistantCloudJWTAuthStrategy,\n AssistantCloudAPIKeyAuthStrategy,\n AssistantCloudAnonymousAuthStrategy,\n} from \"./AssistantCloudAuthStrategy\";\nimport type { AssistantCloudRunReport } from \"./AssistantCloudRuns\";\n\nexport type AssistantCloudTelemetryConfig = {\n enabled?: boolean;\n /**\n * Called before each telemetry report is sent.\n * Return a modified report to enrich it (e.g. add `model_id`),\n * or return `null` to skip the report.\n */\n beforeReport?: (\n report: AssistantCloudRunReport,\n ) => AssistantCloudRunReport | null;\n};\n\nexport type AssistantCloudConfig = (\n | {\n baseUrl: string;\n authToken: () => Promise<string | null>;\n }\n | {\n baseUrl?: string;\n apiKey: string;\n userId: string;\n workspaceId: string;\n }\n | {\n baseUrl: string;\n anonymous: true;\n }\n) & {\n /**\n * Client-side run telemetry reporting. Default: `true`.\n *\n * When enabled, the SDK automatically reports run metadata (status, step\n * count, tool calls, and token usage) to Assistant Cloud after each\n * assistant message is saved. No message content is sent.\n *\n * - `true` / `undefined` — enabled with defaults\n * - `false` — disabled\n * - `{ beforeReport }` — enabled with a hook to enrich or filter reports\n */\n telemetry?: boolean | AssistantCloudTelemetryConfig;\n};\n\nexport class CloudAPIError extends Error {\n public readonly status: number;\n\n constructor(message: string, status: number) {\n super(message);\n this.status = status;\n this.name = \"CloudAPIError\";\n }\n}\n\ntype MakeRequestOptions = {\n method?: \"POST\" | \"PUT\" | \"DELETE\" | undefined;\n headers?: Record<string, string> | undefined;\n query?: Record<string, string | number | boolean> | undefined;\n body?: object | undefined;\n};\n\nconst normalizeBaseUrl = (baseUrl: string) => {\n if (!baseUrl || !baseUrl.endsWith(\"/\")) return baseUrl;\n return baseUrl.slice(0, -1);\n};\n\nexport class AssistantCloudAPI {\n public _auth: AssistantCloudAuthStrategy;\n public _baseUrl;\n\n constructor(config: AssistantCloudConfig) {\n if (\"authToken\" in config) {\n this._baseUrl = normalizeBaseUrl(config.baseUrl);\n this._auth = new AssistantCloudJWTAuthStrategy(config.authToken);\n } else if (\"apiKey\" in config) {\n this._baseUrl = normalizeBaseUrl(\n config.baseUrl ?? \"https://backend.assistant-api.com\",\n );\n this._auth = new AssistantCloudAPIKeyAuthStrategy(\n config.apiKey,\n config.userId,\n config.workspaceId,\n );\n } else if (\"anonymous\" in config) {\n this._baseUrl = normalizeBaseUrl(config.baseUrl);\n this._auth = new AssistantCloudAnonymousAuthStrategy(this._baseUrl);\n } else {\n throw new Error(\n \"Invalid configuration: Must provide authToken, apiKey, or anonymous configuration\",\n );\n }\n }\n\n public async initializeAuth() {\n return !!(await this._auth.getAuthHeaders());\n }\n\n public async makeRawRequest(\n endpoint: string,\n options: MakeRequestOptions = {},\n ) {\n const authHeaders = await this._auth.getAuthHeaders();\n if (!authHeaders) throw new Error(\"Authorization failed\");\n\n const headers = {\n ...authHeaders,\n ...options.headers,\n \"Content-Type\": \"application/json\",\n };\n\n const queryParams = new URLSearchParams();\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value === false) continue;\n if (value === true) {\n queryParams.set(key, \"true\");\n } else {\n queryParams.set(key, value.toString());\n }\n }\n }\n\n const url = new URL(`${this._baseUrl}/v1${endpoint}`);\n url.search = queryParams.toString();\n\n const response = await fetch(url, {\n method: options.method ?? \"GET\",\n headers,\n body: options.body ? JSON.stringify(options.body) : null,\n });\n\n this._auth.readAuthHeaders(response.headers);\n\n if (!response.ok) {\n const text = await response.text();\n let message: string | undefined;\n try {\n const body = JSON.parse(text);\n if (typeof body?.message === \"string\" && body.message.length > 0) {\n message = body.message;\n }\n } catch {}\n throw new CloudAPIError(\n message ?? `Request failed with status ${response.status}, ${text}`,\n response.status,\n );\n }\n\n return response;\n }\n\n public async makeRequest(endpoint: string, options: MakeRequestOptions = {}) {\n const response = await this.makeRawRequest(endpoint, options);\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n )\n return undefined;\n\n const text = await response.text();\n if (text.trim() === \"\") return undefined;\n\n return JSON.parse(text);\n }\n}\n"],"mappings":";;AAkDA,IAAa,gBAAb,cAAmC,MAAM;CACvC;CAEA,YAAY,SAAiB,QAAgB;EAC3C,MAAM,OAAO;EACb,KAAK,SAAS;EACd,KAAK,OAAO;CACd;AACF;AASA,MAAM,oBAAoB,YAAoB;CAC5C,IAAI,CAAC,WAAW,CAAC,QAAQ,SAAS,GAAG,GAAG,OAAO;CAC/C,OAAO,QAAQ,MAAM,GAAG,EAAE;AAC5B;AAEA,IAAa,oBAAb,MAA+B;CAC7B;CACA;CAEA,YAAY,QAA8B;EACxC,IAAI,eAAe,QAAQ;GACzB,KAAK,WAAW,iBAAiB,OAAO,OAAO;GAC/C,KAAK,QAAQ,IAAI,8BAA8B,OAAO,SAAS;EACjE,OAAO,IAAI,YAAY,QAAQ;GAC7B,KAAK,WAAW,iBACd,OAAO,WAAW,mCACpB;GACA,KAAK,QAAQ,IAAI,iCACf,OAAO,QACP,OAAO,QACP,OAAO,WACT;EACF,OAAO,IAAI,eAAe,QAAQ;GAChC,KAAK,WAAW,iBAAiB,OAAO,OAAO;GAC/C,KAAK,QAAQ,IAAI,oCAAoC,KAAK,QAAQ;EACpE,OACE,MAAM,IAAI,MACR,mFACF;CAEJ;CAEA,MAAa,iBAAiB;EAC5B,OAAO,CAAC,CAAE,MAAM,KAAK,MAAM,eAAe;CAC5C;CAEA,MAAa,eACX,UACA,UAA8B,CAAC,GAC/B;EACA,MAAM,cAAc,MAAM,KAAK,MAAM,eAAe;EACpD,IAAI,CAAC,aAAa,MAAM,IAAI,MAAM,sBAAsB;EAExD,MAAM,UAAU;GACd,GAAG;GACH,GAAG,QAAQ;GACX,gBAAgB;EAClB;EAEA,MAAM,cAAc,IAAI,gBAAgB;EACxC,IAAI,QAAQ,OACV,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,KAAK,GAAG;GACxD,IAAI,UAAU,OAAO;GACrB,IAAI,UAAU,MACZ,YAAY,IAAI,KAAK,MAAM;QAE3B,YAAY,IAAI,KAAK,MAAM,SAAS,CAAC;EAEzC;EAGF,MAAM,MAAM,IAAI,IAAI,GAAG,KAAK,SAAS,KAAK,UAAU;EACpD,IAAI,SAAS,YAAY,SAAS;EAElC,MAAM,WAAW,MAAM,MAAM,KAAK;GAChC,QAAQ,QAAQ,UAAU;GAC1B;GACA,MAAM,QAAQ,OAAO,KAAK,UAAU,QAAQ,IAAI,IAAI;EACtD,CAAC;EAED,KAAK,MAAM,gBAAgB,SAAS,OAAO;EAE3C,IAAI,CAAC,SAAS,IAAI;GAChB,MAAM,OAAO,MAAM,SAAS,KAAK;GACjC,IAAI;GACJ,IAAI;IACF,MAAM,OAAO,KAAK,MAAM,IAAI;IAC5B,IAAI,OAAO,MAAM,YAAY,YAAY,KAAK,QAAQ,SAAS,GAC7D,UAAU,KAAK;GAEnB,QAAQ,CAAC;GACT,MAAM,IAAI,cACR,WAAW,8BAA8B,SAAS,OAAO,IAAI,QAC7D,SAAS,MACX;EACF;EAEA,OAAO;CACT;CAEA,MAAa,YAAY,UAAkB,UAA8B,CAAC,GAAG;EAC3E,MAAM,WAAW,MAAM,KAAK,eAAe,UAAU,OAAO;EAC5D,IACE,SAAS,WAAW,OACpB,SAAS,QAAQ,IAAI,gBAAgB,MAAM,KAE3C,OAAO,KAAA;EAET,MAAM,OAAO,MAAM,SAAS,KAAK;EACjC,IAAI,KAAK,KAAK,MAAM,IAAI,OAAO,KAAA;EAE/B,OAAO,KAAK,MAAM,IAAI;CACxB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAuthStrategy.d.ts","names":[],"sources":["../src/AssistantCloudAuthStrategy.ts"],"mappings":";KAMY;WACD;EACT,kBAAkB,QAAQ;EAC1B,gBAAgB,SAAS;;cAmFd,yCAAyC;;WACpC;UAER;UACA;UACA;EAGI,YAAA,yBAAyB;EAIxB,kBAAkB,QAAQ;UA0BzB;EAUP,gBAAgB,SAAS;;cAcrB,4CAA4C;;WACvC;EAMJ,YAAA,gBAAgB,gBAAgB;EAM/B,kBAAkB,QAAQ;EAQhC;;cA6CI,+CAA+C;WAC1C;UAER;UACA;EAEI,YAAA;EA4DC,kBAAkB,QAAQ;EAIhC,gBAAgB,SAAS"}
1
+ {"version":3,"file":"AssistantCloudAuthStrategy.d.ts","names":[],"sources":["../src/AssistantCloudAuthStrategy.ts"],"mappings":";KAMY;WACD;EACT,kBAAkB,QAAQ;EAC1B,gBAAgB,SAAS;;cAmFd,yCAAyC;;WACpC;UAER;UACA;UACA;EAGI,YAAA,yBAAyB;EAIxB,kBAAkB,QAAQ;UA0BzB;EAUP,gBAAgB,SAAS;;cAcrB,4CAA4C;;WACvC;EAMJ,YAAA,gBAAgB,gBAAgB;EAM/B,kBAAkB,QAAQ;EAQhC;;cA0EI,+CAA+C;WAC1C;UAER;UACA;EAEI,YAAA;EAoEC,kBAAkB,QAAQ;EAIhC,gBAAgB,SAAS"}
@@ -94,7 +94,13 @@ var AssistantCloudAPIKeyAuthStrategy = class {
94
94
  }
95
95
  readAuthHeaders() {}
96
96
  };
97
- const AUI_REFRESH_TOKEN_NAME = "aui:refresh_token";
97
+ const LEGACY_AUI_REFRESH_TOKEN_NAME = "aui:refresh_token";
98
+ const getRefreshTokenName = (baseUrl) => `${LEGACY_AUI_REFRESH_TOKEN_NAME}:${baseUrl}`;
99
+ const removeLegacyRefreshToken = (storage) => {
100
+ try {
101
+ storage.removeItem(LEGACY_AUI_REFRESH_TOKEN_NAME);
102
+ } catch {}
103
+ };
98
104
  const getLocalStorage = () => {
99
105
  if (!("localStorage" in globalThis)) return null;
100
106
  try {
@@ -103,28 +109,44 @@ const getLocalStorage = () => {
103
109
  return null;
104
110
  }
105
111
  };
106
- const readRefreshToken = () => {
112
+ const readRefreshToken = (baseUrl) => {
107
113
  const storage = getLocalStorage();
108
114
  if (!storage) return void 0;
109
115
  try {
110
- const value = storage.getItem(AUI_REFRESH_TOKEN_NAME);
111
- return value ? JSON.parse(value) : void 0;
116
+ const name = getRefreshTokenName(baseUrl);
117
+ const value = storage.getItem(name);
118
+ if (value) {
119
+ removeLegacyRefreshToken(storage);
120
+ return JSON.parse(value);
121
+ }
122
+ const legacyValue = storage.getItem(LEGACY_AUI_REFRESH_TOKEN_NAME);
123
+ if (!legacyValue) return void 0;
124
+ let refreshToken;
125
+ try {
126
+ refreshToken = JSON.parse(legacyValue);
127
+ } catch {
128
+ removeLegacyRefreshToken(storage);
129
+ return;
130
+ }
131
+ storage.setItem(name, legacyValue);
132
+ removeLegacyRefreshToken(storage);
133
+ return refreshToken;
112
134
  } catch {
113
135
  return;
114
136
  }
115
137
  };
116
- const writeRefreshToken = (refreshToken) => {
138
+ const writeRefreshToken = (baseUrl, refreshToken) => {
117
139
  const storage = getLocalStorage();
118
140
  if (!storage) return;
119
141
  try {
120
- storage.setItem(AUI_REFRESH_TOKEN_NAME, JSON.stringify(refreshToken));
142
+ storage.setItem(getRefreshTokenName(baseUrl), JSON.stringify(refreshToken));
121
143
  } catch {}
122
144
  };
123
- const removeRefreshToken = () => {
145
+ const removeRefreshToken = (baseUrl) => {
124
146
  const storage = getLocalStorage();
125
147
  if (!storage) return;
126
148
  try {
127
- storage.removeItem(AUI_REFRESH_TOKEN_NAME);
149
+ storage.removeItem(getRefreshTokenName(baseUrl));
128
150
  } catch {}
129
151
  };
130
152
  var AssistantCloudAnonymousAuthStrategy = class {
@@ -135,7 +157,7 @@ var AssistantCloudAnonymousAuthStrategy = class {
135
157
  this.baseUrl = baseUrl;
136
158
  this.jwtStrategy = new AssistantCloudJWTAuthStrategy(async () => {
137
159
  const currentTime = Date.now();
138
- const storedRefreshToken = readRefreshToken();
160
+ const storedRefreshToken = readRefreshToken(this.baseUrl);
139
161
  if (storedRefreshToken) {
140
162
  if (new Date(storedRefreshToken.expires_at).getTime() - currentTime > 3e4) {
141
163
  const response = await fetch(`${this.baseUrl}/v1/auth/tokens/refresh`, {
@@ -145,15 +167,16 @@ var AssistantCloudAnonymousAuthStrategy = class {
145
167
  });
146
168
  if (response.ok) {
147
169
  const { data, accessToken } = await readAuthTokenResponse(response, "refresh auth token response");
148
- if (data.refresh_token != null) writeRefreshToken(readRefreshTokenResponse(data.refresh_token, "refresh auth token response.refresh_token"));
170
+ if (data.refresh_token != null) writeRefreshToken(this.baseUrl, readRefreshTokenResponse(data.refresh_token, "refresh auth token response.refresh_token"));
149
171
  return accessToken;
150
172
  }
151
- } else removeRefreshToken();
173
+ if (response.status === 429 || response.status >= 500) throw new Error(`Assistant Cloud token refresh failed with status ${response.status}`);
174
+ } else removeRefreshToken(this.baseUrl);
152
175
  }
153
176
  const response = await fetch(`${this.baseUrl}/v1/auth/tokens/anonymous`, { method: "POST" });
154
177
  if (!response.ok) return null;
155
178
  const { data, accessToken } = await readAuthTokenResponse(response, "anonymous auth token response");
156
- writeRefreshToken(readRefreshTokenResponse(data.refresh_token, "anonymous auth token response.refresh_token"));
179
+ writeRefreshToken(this.baseUrl, readRefreshTokenResponse(data.refresh_token, "anonymous auth token response.refresh_token"));
157
180
  return accessToken;
158
181
  });
159
182
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAuthStrategy.js","names":["#authTokenCallback","#apiKey","#userId","#workspaceId"],"sources":["../src/AssistantCloudAuthStrategy.ts"],"sourcesContent":["import {\n CloudResponseError,\n readCloudRecord,\n readCloudString,\n} from \"./cloudResponse\";\n\nexport type AssistantCloudAuthStrategy = {\n readonly strategy: \"anon\" | \"jwt\" | \"api-key\";\n getAuthHeaders(): Promise<Record<string, string> | false>;\n readAuthHeaders(headers: Headers): void;\n};\n\nconst getJwtExpiry = (jwt: string): number => {\n try {\n const parts = jwt.split(\".\");\n const bodyPart = parts[1];\n if (!bodyPart) {\n throw new Error(\"Invalid JWT format\");\n }\n\n // Convert from Base64Url to Base64 and add padding if necessary\n let base64 = bodyPart.replace(/-/g, \"+\").replace(/_/g, \"/\");\n while (base64.length % 4 !== 0) {\n base64 += \"=\";\n }\n\n // Decode the Base64 string and parse the payload\n const payload = atob(base64);\n const payloadObj = JSON.parse(payload);\n const exp = payloadObj.exp;\n\n if (!exp || typeof exp !== \"number\") {\n throw new Error('JWT does not contain a valid \"exp\" field');\n }\n\n // Convert expiration time to milliseconds\n return exp * 1000;\n } catch (error) {\n throw new Error(`Unable to determine the token expiry: ${error}`);\n }\n};\n\ntype RefreshToken = {\n token: string;\n expires_at: string;\n};\n\nconst readNonEmptyCloudString = (value: unknown, field: string): string => {\n const result = readCloudString(value, field);\n if (result.length === 0) {\n throw new CloudResponseError(\n `Invalid Assistant Cloud response for \"${field}\": expected a non-empty string`,\n );\n }\n return result;\n};\n\nconst readRefreshTokenResponse = (\n value: unknown,\n field: string,\n): RefreshToken => {\n const refreshToken = readCloudRecord(value, field);\n return {\n token: readNonEmptyCloudString(refreshToken.token, `${field}.token`),\n expires_at: readNonEmptyCloudString(\n refreshToken.expires_at,\n `${field}.expires_at`,\n ),\n };\n};\n\nconst readAuthTokenResponse = async (\n response: Response,\n field: string,\n): Promise<{ data: Record<string, unknown>; accessToken: string }> => {\n let value: unknown;\n try {\n value = await response.json();\n } catch {\n throw new CloudResponseError(\n `Invalid Assistant Cloud response for \"${field}\": expected valid JSON`,\n );\n }\n\n const data = readCloudRecord(value, field);\n const accessToken = readNonEmptyCloudString(\n data.access_token,\n `${field}.access_token`,\n );\n return { data, accessToken };\n};\n\nexport class AssistantCloudJWTAuthStrategy implements AssistantCloudAuthStrategy {\n public readonly strategy = \"jwt\";\n\n private cachedToken: string | null = null;\n private tokenExpiry: number | null = null;\n private tokenRequest: Promise<Record<string, string> | false> | null = null;\n #authTokenCallback: () => Promise<string | null>;\n\n constructor(authTokenCallback: () => Promise<string | null>) {\n this.#authTokenCallback = authTokenCallback;\n }\n\n public async getAuthHeaders(): Promise<Record<string, string> | false> {\n const currentTime = Date.now();\n\n // Use cached token if it's valid for at least 30 more seconds\n if (\n this.cachedToken &&\n this.tokenExpiry &&\n this.tokenExpiry - currentTime > 30 * 1000\n ) {\n return { Authorization: `Bearer ${this.cachedToken}` };\n }\n\n if (!this.tokenRequest) {\n this.tokenRequest = this.fetchAuthHeaders();\n }\n\n const tokenRequest = this.tokenRequest;\n try {\n return await tokenRequest;\n } finally {\n if (this.tokenRequest === tokenRequest) {\n this.tokenRequest = null;\n }\n }\n }\n\n private async fetchAuthHeaders(): Promise<Record<string, string> | false> {\n const token = await this.#authTokenCallback();\n if (!token) return false;\n\n this.cachedToken = token;\n this.tokenExpiry = getJwtExpiry(token);\n\n return { Authorization: `Bearer ${token}` };\n }\n\n public readAuthHeaders(headers: Headers) {\n const authHeader = headers.get(\"Authorization\");\n if (!authHeader) return;\n\n const [scheme, token] = authHeader.split(\" \");\n if (scheme !== \"Bearer\" || !token) {\n throw new Error(\"Invalid auth header received\");\n }\n\n this.cachedToken = token;\n this.tokenExpiry = getJwtExpiry(token);\n }\n}\n\nexport class AssistantCloudAPIKeyAuthStrategy implements AssistantCloudAuthStrategy {\n public readonly strategy = \"api-key\";\n\n #apiKey: string;\n #userId: string;\n #workspaceId: string;\n\n constructor(apiKey: string, userId: string, workspaceId: string) {\n this.#apiKey = apiKey;\n this.#userId = userId;\n this.#workspaceId = workspaceId;\n }\n\n public async getAuthHeaders(): Promise<Record<string, string>> {\n return {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Aui-User-Id\": this.#userId,\n \"Aui-Workspace-Id\": this.#workspaceId,\n };\n }\n\n public readAuthHeaders() {\n // No operation needed for API key auth\n }\n}\n\nconst AUI_REFRESH_TOKEN_NAME = \"aui:refresh_token\";\n\nconst getLocalStorage = (): Storage | null => {\n if (!(\"localStorage\" in globalThis)) return null;\n try {\n return (globalThis as { localStorage: Storage }).localStorage;\n } catch {\n return null;\n }\n};\n\nconst readRefreshToken = (): RefreshToken | undefined => {\n const storage = getLocalStorage();\n if (!storage) return undefined;\n try {\n const value = storage.getItem(AUI_REFRESH_TOKEN_NAME);\n return value\n ? (JSON.parse(value) as { token: string; expires_at: string })\n : undefined;\n } catch {\n return undefined;\n }\n};\n\nconst writeRefreshToken = (refreshToken: RefreshToken): void => {\n const storage = getLocalStorage();\n if (!storage) return;\n try {\n storage.setItem(AUI_REFRESH_TOKEN_NAME, JSON.stringify(refreshToken));\n } catch {}\n};\n\nconst removeRefreshToken = (): void => {\n const storage = getLocalStorage();\n if (!storage) return;\n try {\n storage.removeItem(AUI_REFRESH_TOKEN_NAME);\n } catch {}\n};\n\nexport class AssistantCloudAnonymousAuthStrategy implements AssistantCloudAuthStrategy {\n public readonly strategy = \"anon\";\n\n private baseUrl: string;\n private jwtStrategy: AssistantCloudJWTAuthStrategy;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl;\n this.jwtStrategy = new AssistantCloudJWTAuthStrategy(async () => {\n const currentTime = Date.now();\n const storedRefreshToken = readRefreshToken();\n\n if (storedRefreshToken) {\n const refreshExpiry = new Date(storedRefreshToken.expires_at).getTime();\n if (refreshExpiry - currentTime > 30 * 1000) {\n const response = await fetch(\n `${this.baseUrl}/v1/auth/tokens/refresh`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: storedRefreshToken.token }),\n },\n );\n\n if (response.ok) {\n const { data, accessToken } = await readAuthTokenResponse(\n response,\n \"refresh auth token response\",\n );\n if (data.refresh_token != null) {\n writeRefreshToken(\n readRefreshTokenResponse(\n data.refresh_token,\n \"refresh auth token response.refresh_token\",\n ),\n );\n }\n return accessToken;\n }\n } else {\n removeRefreshToken();\n }\n }\n\n // No valid refresh token; request a new anonymous token\n const response = await fetch(`${this.baseUrl}/v1/auth/tokens/anonymous`, {\n method: \"POST\",\n });\n\n if (!response.ok) return null;\n\n const { data, accessToken } = await readAuthTokenResponse(\n response,\n \"anonymous auth token response\",\n );\n\n writeRefreshToken(\n readRefreshTokenResponse(\n data.refresh_token,\n \"anonymous auth token response.refresh_token\",\n ),\n );\n return accessToken;\n });\n }\n\n public async getAuthHeaders(): Promise<Record<string, string> | false> {\n return this.jwtStrategy.getAuthHeaders();\n }\n\n public readAuthHeaders(headers: Headers): void {\n this.jwtStrategy.readAuthHeaders(headers);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AssistantCloudAuthStrategy.js","names":["#authTokenCallback","#apiKey","#userId","#workspaceId"],"sources":["../src/AssistantCloudAuthStrategy.ts"],"sourcesContent":["import {\n CloudResponseError,\n readCloudRecord,\n readCloudString,\n} from \"./cloudResponse\";\n\nexport type AssistantCloudAuthStrategy = {\n readonly strategy: \"anon\" | \"jwt\" | \"api-key\";\n getAuthHeaders(): Promise<Record<string, string> | false>;\n readAuthHeaders(headers: Headers): void;\n};\n\nconst getJwtExpiry = (jwt: string): number => {\n try {\n const parts = jwt.split(\".\");\n const bodyPart = parts[1];\n if (!bodyPart) {\n throw new Error(\"Invalid JWT format\");\n }\n\n // Convert from Base64Url to Base64 and add padding if necessary\n let base64 = bodyPart.replace(/-/g, \"+\").replace(/_/g, \"/\");\n while (base64.length % 4 !== 0) {\n base64 += \"=\";\n }\n\n // Decode the Base64 string and parse the payload\n const payload = atob(base64);\n const payloadObj = JSON.parse(payload);\n const exp = payloadObj.exp;\n\n if (!exp || typeof exp !== \"number\") {\n throw new Error('JWT does not contain a valid \"exp\" field');\n }\n\n // Convert expiration time to milliseconds\n return exp * 1000;\n } catch (error) {\n throw new Error(`Unable to determine the token expiry: ${error}`);\n }\n};\n\ntype RefreshToken = {\n token: string;\n expires_at: string;\n};\n\nconst readNonEmptyCloudString = (value: unknown, field: string): string => {\n const result = readCloudString(value, field);\n if (result.length === 0) {\n throw new CloudResponseError(\n `Invalid Assistant Cloud response for \"${field}\": expected a non-empty string`,\n );\n }\n return result;\n};\n\nconst readRefreshTokenResponse = (\n value: unknown,\n field: string,\n): RefreshToken => {\n const refreshToken = readCloudRecord(value, field);\n return {\n token: readNonEmptyCloudString(refreshToken.token, `${field}.token`),\n expires_at: readNonEmptyCloudString(\n refreshToken.expires_at,\n `${field}.expires_at`,\n ),\n };\n};\n\nconst readAuthTokenResponse = async (\n response: Response,\n field: string,\n): Promise<{ data: Record<string, unknown>; accessToken: string }> => {\n let value: unknown;\n try {\n value = await response.json();\n } catch {\n throw new CloudResponseError(\n `Invalid Assistant Cloud response for \"${field}\": expected valid JSON`,\n );\n }\n\n const data = readCloudRecord(value, field);\n const accessToken = readNonEmptyCloudString(\n data.access_token,\n `${field}.access_token`,\n );\n return { data, accessToken };\n};\n\nexport class AssistantCloudJWTAuthStrategy implements AssistantCloudAuthStrategy {\n public readonly strategy = \"jwt\";\n\n private cachedToken: string | null = null;\n private tokenExpiry: number | null = null;\n private tokenRequest: Promise<Record<string, string> | false> | null = null;\n #authTokenCallback: () => Promise<string | null>;\n\n constructor(authTokenCallback: () => Promise<string | null>) {\n this.#authTokenCallback = authTokenCallback;\n }\n\n public async getAuthHeaders(): Promise<Record<string, string> | false> {\n const currentTime = Date.now();\n\n // Use cached token if it's valid for at least 30 more seconds\n if (\n this.cachedToken &&\n this.tokenExpiry &&\n this.tokenExpiry - currentTime > 30 * 1000\n ) {\n return { Authorization: `Bearer ${this.cachedToken}` };\n }\n\n if (!this.tokenRequest) {\n this.tokenRequest = this.fetchAuthHeaders();\n }\n\n const tokenRequest = this.tokenRequest;\n try {\n return await tokenRequest;\n } finally {\n if (this.tokenRequest === tokenRequest) {\n this.tokenRequest = null;\n }\n }\n }\n\n private async fetchAuthHeaders(): Promise<Record<string, string> | false> {\n const token = await this.#authTokenCallback();\n if (!token) return false;\n\n this.cachedToken = token;\n this.tokenExpiry = getJwtExpiry(token);\n\n return { Authorization: `Bearer ${token}` };\n }\n\n public readAuthHeaders(headers: Headers) {\n const authHeader = headers.get(\"Authorization\");\n if (!authHeader) return;\n\n const [scheme, token] = authHeader.split(\" \");\n if (scheme !== \"Bearer\" || !token) {\n throw new Error(\"Invalid auth header received\");\n }\n\n this.cachedToken = token;\n this.tokenExpiry = getJwtExpiry(token);\n }\n}\n\nexport class AssistantCloudAPIKeyAuthStrategy implements AssistantCloudAuthStrategy {\n public readonly strategy = \"api-key\";\n\n #apiKey: string;\n #userId: string;\n #workspaceId: string;\n\n constructor(apiKey: string, userId: string, workspaceId: string) {\n this.#apiKey = apiKey;\n this.#userId = userId;\n this.#workspaceId = workspaceId;\n }\n\n public async getAuthHeaders(): Promise<Record<string, string>> {\n return {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Aui-User-Id\": this.#userId,\n \"Aui-Workspace-Id\": this.#workspaceId,\n };\n }\n\n public readAuthHeaders() {\n // No operation needed for API key auth\n }\n}\n\nconst LEGACY_AUI_REFRESH_TOKEN_NAME = \"aui:refresh_token\";\n\nconst getRefreshTokenName = (baseUrl: string): string =>\n `${LEGACY_AUI_REFRESH_TOKEN_NAME}:${baseUrl}`;\n\nconst removeLegacyRefreshToken = (storage: Storage): void => {\n try {\n storage.removeItem(LEGACY_AUI_REFRESH_TOKEN_NAME);\n } catch {}\n};\n\nconst getLocalStorage = (): Storage | null => {\n if (!(\"localStorage\" in globalThis)) return null;\n try {\n return (globalThis as { localStorage: Storage }).localStorage;\n } catch {\n return null;\n }\n};\n\nconst readRefreshToken = (baseUrl: string): RefreshToken | undefined => {\n const storage = getLocalStorage();\n if (!storage) return undefined;\n try {\n const name = getRefreshTokenName(baseUrl);\n const value = storage.getItem(name);\n if (value) {\n removeLegacyRefreshToken(storage);\n return JSON.parse(value) as RefreshToken;\n }\n\n const legacyValue = storage.getItem(LEGACY_AUI_REFRESH_TOKEN_NAME);\n if (!legacyValue) return undefined;\n\n let refreshToken: RefreshToken;\n try {\n refreshToken = JSON.parse(legacyValue) as RefreshToken;\n } catch {\n removeLegacyRefreshToken(storage);\n return undefined;\n }\n\n storage.setItem(name, legacyValue);\n removeLegacyRefreshToken(storage);\n return refreshToken;\n } catch {\n return undefined;\n }\n};\n\nconst writeRefreshToken = (\n baseUrl: string,\n refreshToken: RefreshToken,\n): void => {\n const storage = getLocalStorage();\n if (!storage) return;\n try {\n storage.setItem(getRefreshTokenName(baseUrl), JSON.stringify(refreshToken));\n } catch {}\n};\n\nconst removeRefreshToken = (baseUrl: string): void => {\n const storage = getLocalStorage();\n if (!storage) return;\n try {\n storage.removeItem(getRefreshTokenName(baseUrl));\n } catch {}\n};\n\nexport class AssistantCloudAnonymousAuthStrategy implements AssistantCloudAuthStrategy {\n public readonly strategy = \"anon\";\n\n private baseUrl: string;\n private jwtStrategy: AssistantCloudJWTAuthStrategy;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl;\n this.jwtStrategy = new AssistantCloudJWTAuthStrategy(async () => {\n const currentTime = Date.now();\n const storedRefreshToken = readRefreshToken(this.baseUrl);\n\n if (storedRefreshToken) {\n const refreshExpiry = new Date(storedRefreshToken.expires_at).getTime();\n if (refreshExpiry - currentTime > 30 * 1000) {\n const response = await fetch(\n `${this.baseUrl}/v1/auth/tokens/refresh`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: storedRefreshToken.token }),\n },\n );\n\n if (response.ok) {\n const { data, accessToken } = await readAuthTokenResponse(\n response,\n \"refresh auth token response\",\n );\n if (data.refresh_token != null) {\n writeRefreshToken(\n this.baseUrl,\n readRefreshTokenResponse(\n data.refresh_token,\n \"refresh auth token response.refresh_token\",\n ),\n );\n }\n return accessToken;\n }\n\n if (response.status === 429 || response.status >= 500) {\n throw new Error(\n `Assistant Cloud token refresh failed with status ${response.status}`,\n );\n }\n } else {\n removeRefreshToken(this.baseUrl);\n }\n }\n\n // No valid refresh token; request a new anonymous token\n const response = await fetch(`${this.baseUrl}/v1/auth/tokens/anonymous`, {\n method: \"POST\",\n });\n\n if (!response.ok) return null;\n\n const { data, accessToken } = await readAuthTokenResponse(\n response,\n \"anonymous auth token response\",\n );\n\n writeRefreshToken(\n this.baseUrl,\n readRefreshTokenResponse(\n data.refresh_token,\n \"anonymous auth token response.refresh_token\",\n ),\n );\n return accessToken;\n });\n }\n\n public async getAuthHeaders(): Promise<Record<string, string> | false> {\n return this.jwtStrategy.getAuthHeaders();\n }\n\n public readAuthHeaders(headers: Headers): void {\n this.jwtStrategy.readAuthHeaders(headers);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAuthTokens.d.ts","names":[],"sources":["../src/AssistantCloudAuthTokens.ts"],"mappings":";;KAEK;EACH;;cAGW;UACH;EAEI,YAAA,OAAO;EAIN,UAAU,QAAQ"}
1
+ {"version":3,"file":"AssistantCloudAuthTokens.d.ts","names":[],"sources":["../src/AssistantCloudAuthTokens.ts"],"mappings":";;KAGK;EACH;;cAGW;UACH;EAEI,YAAA,OAAO;EAIN,UAAU,QAAQ"}
@@ -1,3 +1,4 @@
1
+ import { readCloudRecord, readCloudString } from "./cloudResponse.js";
1
2
  //#region src/AssistantCloudAuthTokens.ts
2
3
  var AssistantCloudAuthTokens = class {
3
4
  cloud;
@@ -5,7 +6,8 @@ var AssistantCloudAuthTokens = class {
5
6
  this.cloud = cloud;
6
7
  }
7
8
  async create() {
8
- return this.cloud.makeRequest("/auth/tokens", { method: "POST" });
9
+ const response = readCloudRecord(await this.cloud.makeRequest("/auth/tokens", { method: "POST" }), "auth token response");
10
+ return { token: readCloudString(response.token, "token") };
9
11
  }
10
12
  };
11
13
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAuthTokens.js","names":[],"sources":["../src/AssistantCloudAuthTokens.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\n\ntype AssistantCloudAuthTokensCreateResponse = {\n token: string;\n};\n\nexport class AssistantCloudAuthTokens {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public async create(): Promise<AssistantCloudAuthTokensCreateResponse> {\n return this.cloud.makeRequest(\"/auth/tokens\", { method: \"POST\" });\n }\n}\n"],"mappings":";AAMA,IAAa,2BAAb,MAAsC;CACpC;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,MAAa,SAA0D;EACrE,OAAO,KAAK,MAAM,YAAY,gBAAgB,EAAE,QAAQ,OAAO,CAAC;CAClE;AACF"}
1
+ {"version":3,"file":"AssistantCloudAuthTokens.js","names":[],"sources":["../src/AssistantCloudAuthTokens.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport { readCloudRecord, readCloudString } from \"./cloudResponse\";\n\ntype AssistantCloudAuthTokensCreateResponse = {\n token: string;\n};\n\nexport class AssistantCloudAuthTokens {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public async create(): Promise<AssistantCloudAuthTokensCreateResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\"/auth/tokens\", { method: \"POST\" }),\n \"auth token response\",\n );\n\n return { token: readCloudString(response.token, \"token\") };\n }\n}\n"],"mappings":";;AAOA,IAAa,2BAAb,MAAsC;CACpC;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,MAAa,SAA0D;EACrE,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,gBAAgB,EAAE,QAAQ,OAAO,CAAC,GAC/D,qBACF;EAEA,OAAO,EAAE,OAAO,gBAAgB,SAAS,OAAO,OAAO,EAAE;CAC3D;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudFiles.d.ts","names":[],"sources":["../src/AssistantCloudFiles.ts"],"mappings":";;KAEK;EACH;EACA;;KAGG;EACH;EACA;EACA;;KAGG;EACH;;KAGG;EACH;EACA;EACA;EACA;;cAGW;UACH;EAEI,YAAA,OAAO;EAIN,YACX,MAAM,yBACL,QAAQ;EAOE,2BACX,MAAM,wCACL,QAAQ"}
1
+ {"version":3,"file":"AssistantCloudFiles.d.ts","names":[],"sources":["../src/AssistantCloudFiles.ts"],"mappings":";;KAQK;EACH;EACA;;KAGG;EACH;EACA;EACA;;KAGG;EACH;;KAGG;EACH;EACA;EACA;EACA;;cAGW;UACH;EAEI,YAAA,OAAO;EAIN,YACX,MAAM,yBACL,QAAQ;EAyBE,2BACX,MAAM,wCACL,QAAQ"}
@@ -1,3 +1,4 @@
1
+ import { readCloudArray, readCloudBoolean, readCloudRecord, readCloudString } from "./cloudResponse.js";
1
2
  //#region src/AssistantCloudFiles.ts
2
3
  var AssistantCloudFiles = class {
3
4
  cloud;
@@ -5,16 +6,27 @@ var AssistantCloudFiles = class {
5
6
  this.cloud = cloud;
6
7
  }
7
8
  async pdfToImages(body) {
8
- return this.cloud.makeRequest("/files/pdf-to-images", {
9
+ const response = readCloudRecord(await this.cloud.makeRequest("/files/pdf-to-images", {
9
10
  method: "POST",
10
11
  body
11
- });
12
+ }), "PDF conversion response");
13
+ return {
14
+ success: readCloudBoolean(response.success, "PDF conversion response.success"),
15
+ urls: readCloudArray(response.urls, "PDF conversion response.urls").map((url, index) => readCloudString(url, `PDF conversion response.urls[${index}]`)),
16
+ message: readCloudString(response.message, "PDF conversion response.message")
17
+ };
12
18
  }
13
19
  async generatePresignedUploadUrl(body) {
14
- return this.cloud.makeRequest("/files/attachments/generate-presigned-upload-url", {
20
+ const response = readCloudRecord(await this.cloud.makeRequest("/files/attachments/generate-presigned-upload-url", {
15
21
  method: "POST",
16
22
  body
17
- });
23
+ }), "presigned upload response");
24
+ return {
25
+ success: readCloudBoolean(response.success, "presigned upload response.success"),
26
+ signedUrl: readCloudString(response.signedUrl, "presigned upload response.signedUrl"),
27
+ expiresAt: readCloudString(response.expiresAt, "presigned upload response.expiresAt"),
28
+ publicUrl: readCloudString(response.publicUrl, "presigned upload response.publicUrl")
29
+ };
18
30
  }
19
31
  };
20
32
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudFiles.js","names":[],"sources":["../src/AssistantCloudFiles.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\n\ntype PdfToImagesRequestBody = {\n file_blob?: string | undefined;\n file_url?: string | undefined;\n};\n\ntype PdfToImagesResponse = {\n success: boolean;\n urls: string[];\n message: string;\n};\n\ntype GeneratePresignedUploadUrlRequestBody = {\n filename: string;\n};\n\ntype GeneratePresignedUploadUrlResponse = {\n success: boolean;\n signedUrl: string;\n expiresAt: string;\n publicUrl: string;\n};\n\nexport class AssistantCloudFiles {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public async pdfToImages(\n body: PdfToImagesRequestBody,\n ): Promise<PdfToImagesResponse> {\n return this.cloud.makeRequest(\"/files/pdf-to-images\", {\n method: \"POST\",\n body,\n });\n }\n\n public async generatePresignedUploadUrl(\n body: GeneratePresignedUploadUrlRequestBody,\n ): Promise<GeneratePresignedUploadUrlResponse> {\n return this.cloud.makeRequest(\n \"/files/attachments/generate-presigned-upload-url\",\n {\n method: \"POST\",\n body,\n },\n );\n }\n}\n"],"mappings":";AAwBA,IAAa,sBAAb,MAAiC;CAC/B;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,MAAa,YACX,MAC8B;EAC9B,OAAO,KAAK,MAAM,YAAY,wBAAwB;GACpD,QAAQ;GACR;EACF,CAAC;CACH;CAEA,MAAa,2BACX,MAC6C;EAC7C,OAAO,KAAK,MAAM,YAChB,oDACA;GACE,QAAQ;GACR;EACF,CACF;CACF;AACF"}
1
+ {"version":3,"file":"AssistantCloudFiles.js","names":[],"sources":["../src/AssistantCloudFiles.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport {\n readCloudArray,\n readCloudBoolean,\n readCloudRecord,\n readCloudString,\n} from \"./cloudResponse\";\n\ntype PdfToImagesRequestBody = {\n file_blob?: string | undefined;\n file_url?: string | undefined;\n};\n\ntype PdfToImagesResponse = {\n success: boolean;\n urls: string[];\n message: string;\n};\n\ntype GeneratePresignedUploadUrlRequestBody = {\n filename: string;\n};\n\ntype GeneratePresignedUploadUrlResponse = {\n success: boolean;\n signedUrl: string;\n expiresAt: string;\n publicUrl: string;\n};\n\nexport class AssistantCloudFiles {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public async pdfToImages(\n body: PdfToImagesRequestBody,\n ): Promise<PdfToImagesResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\"/files/pdf-to-images\", {\n method: \"POST\",\n body,\n }),\n \"PDF conversion response\",\n );\n\n return {\n success: readCloudBoolean(\n response.success,\n \"PDF conversion response.success\",\n ),\n urls: readCloudArray(response.urls, \"PDF conversion response.urls\").map(\n (url, index) =>\n readCloudString(url, `PDF conversion response.urls[${index}]`),\n ),\n message: readCloudString(\n response.message,\n \"PDF conversion response.message\",\n ),\n };\n }\n\n public async generatePresignedUploadUrl(\n body: GeneratePresignedUploadUrlRequestBody,\n ): Promise<GeneratePresignedUploadUrlResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n \"/files/attachments/generate-presigned-upload-url\",\n {\n method: \"POST\",\n body,\n },\n ),\n \"presigned upload response\",\n );\n\n return {\n success: readCloudBoolean(\n response.success,\n \"presigned upload response.success\",\n ),\n signedUrl: readCloudString(\n response.signedUrl,\n \"presigned upload response.signedUrl\",\n ),\n expiresAt: readCloudString(\n response.expiresAt,\n \"presigned upload response.expiresAt\",\n ),\n publicUrl: readCloudString(\n response.publicUrl,\n \"presigned upload response.publicUrl\",\n ),\n };\n }\n}\n"],"mappings":";;AA8BA,IAAa,sBAAb,MAAiC;CAC/B;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,MAAa,YACX,MAC8B;EAC9B,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,wBAAwB;GACnD,QAAQ;GACR;EACF,CAAC,GACD,yBACF;EAEA,OAAO;GACL,SAAS,iBACP,SAAS,SACT,iCACF;GACA,MAAM,eAAe,SAAS,MAAM,8BAA8B,CAAC,CAAC,KACjE,KAAK,UACJ,gBAAgB,KAAK,gCAAgC,MAAM,EAAE,CACjE;GACA,SAAS,gBACP,SAAS,SACT,iCACF;EACF;CACF;CAEA,MAAa,2BACX,MAC6C;EAC7C,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,oDACA;GACE,QAAQ;GACR;EACF,CACF,GACA,2BACF;EAEA,OAAO;GACL,SAAS,iBACP,SAAS,SACT,mCACF;GACA,WAAW,gBACT,SAAS,WACT,qCACF;GACA,WAAW,gBACT,SAAS,WACT,qCACF;GACA,WAAW,gBACT,SAAS,WACT,qCACF;EACF;CACF;AACF"}
@@ -1,4 +1,4 @@
1
- import { SamplingCallData } from "./instrumentMcpSampling.js";
1
+ import { AssistantCloudRunReportToolCall } from "./runTelemetry.js";
2
2
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
3
3
  import { AssistantStream } from "assistant-stream";
4
4
  //#region src/AssistantCloudRuns.d.ts
@@ -7,27 +7,17 @@ type AssistantCloudRunsStreamBody = {
7
7
  assistant_id: "system/thread_title";
8
8
  messages: readonly unknown[];
9
9
  };
10
- type ReportToolCall = {
11
- tool_name: string;
12
- tool_call_id: string;
13
- tool_args?: string;
14
- tool_result?: string;
15
- tool_source?: "mcp" | "frontend" | "backend";
16
- start_ms?: number;
17
- end_ms?: number;
18
- sampling_calls?: SamplingCallData[];
19
- };
20
10
  type AssistantCloudRunReport = {
21
11
  thread_id: string;
22
12
  status: "completed" | "incomplete" | "error";
23
13
  total_steps?: number;
24
- tool_calls?: ReportToolCall[];
14
+ tool_calls?: AssistantCloudRunReportToolCall[];
25
15
  steps?: {
26
16
  input_tokens?: number;
27
17
  output_tokens?: number;
28
18
  reasoning_tokens?: number;
29
19
  cached_input_tokens?: number;
30
- tool_calls?: ReportToolCall[];
20
+ tool_calls?: AssistantCloudRunReportToolCall[];
31
21
  start_ms?: number;
32
22
  end_ms?: number;
33
23
  }[];
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudRuns.d.ts","names":[],"sources":["../src/AssistantCloudRuns.ts"],"mappings":";;;;KAIK;EACH;EACA;EACA;;KAGG;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;;KAMP;EACV;EACA;EACA;EACA,aAAa;EACb;IACE;IACA;IACA;IACA;IACA,aAAa;IACb;IACA;;EAEF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;;cAGA;UACH;EAEI,YAAA,OAAO;EAIZ,+BAA+B;;;;;;;;;;;EAmBzB,OACX,MAAM,+BACL,QAAQ;EAWE,OACX,MAAM,0BACL;IAAU"}
1
+ {"version":3,"file":"AssistantCloudRuns.d.ts","names":[],"sources":["../src/AssistantCloudRuns.ts"],"mappings":";;;;KASK;EACH;EACA;EACA;;KAMU;EACV;EACA;EACA;EACA,aAAa;EACb;IACE;IACA;IACA;IACA;IACA,aAAa;IACb;IACA;;EAEF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;;cAGA;UACH;EAEI,YAAA,OAAO;EAIZ,+BAA+B;;;;;;;;;;;EAmBzB,OACX,MAAM,+BACL,QAAQ;EAkCE,OACX,MAAM,0BACL;IAAU"}
@@ -1,3 +1,4 @@
1
+ import { CloudResponseError, readCloudRecord, readCloudString } from "./cloudResponse.js";
1
2
  import { AssistantStream, PlainTextDecoder } from "assistant-stream";
2
3
  //#region src/AssistantCloudRuns.ts
3
4
  var AssistantCloudRuns = class {
@@ -29,13 +30,20 @@ var AssistantCloudRuns = class {
29
30
  headers: { Accept: "text/plain" },
30
31
  body
31
32
  });
33
+ if (!response.body) throw new CloudResponseError("Invalid Assistant Cloud response for \"run stream\": expected a response body");
34
+ const receivedContentType = response.headers.get("content-type");
35
+ if (receivedContentType?.split(";", 1)[0]?.trim().toLowerCase() !== "text/plain") {
36
+ await response.body.cancel().catch(() => void 0);
37
+ throw new CloudResponseError(`Invalid Assistant Cloud response for "run stream": expected a "text/plain" content type, received ${receivedContentType ? `"${receivedContentType}"` : "no Content-Type header"}`);
38
+ }
32
39
  return AssistantStream.fromResponse(response, new PlainTextDecoder());
33
40
  }
34
41
  async report(body) {
35
- return this.cloud.makeRequest("/runs", {
42
+ const response = readCloudRecord(await this.cloud.makeRequest("/runs", {
36
43
  method: "POST",
37
44
  body
38
- });
45
+ }), "run report response");
46
+ return { run_id: readCloudString(response.run_id, "run_id") };
39
47
  }
40
48
  };
41
49
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudRuns.js","names":[],"sources":["../src/AssistantCloudRuns.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport type { SamplingCallData } from \"./instrumentMcpSampling\";\nimport { AssistantStream, PlainTextDecoder } from \"assistant-stream\";\n\ntype AssistantCloudRunsStreamBody = {\n thread_id: string;\n assistant_id: \"system/thread_title\";\n messages: readonly unknown[]; // TODO type\n};\n\ntype ReportToolCall = {\n tool_name: string;\n tool_call_id: string;\n tool_args?: string;\n tool_result?: string;\n tool_source?: \"mcp\" | \"frontend\" | \"backend\";\n start_ms?: number;\n end_ms?: number;\n sampling_calls?: SamplingCallData[];\n};\n\n// NOTE: Keep this payload shape aligned with the strict runtime validator in\n// assistant-cloud: apps/aui-cloud-api/src/endpoints/runs/create.ts\n// (createRunSchema). New telemetry fields must be added in both repos together.\nexport type AssistantCloudRunReport = {\n thread_id: string;\n status: \"completed\" | \"incomplete\" | \"error\";\n total_steps?: number;\n tool_calls?: ReportToolCall[];\n steps?: {\n input_tokens?: number;\n output_tokens?: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n tool_calls?: ReportToolCall[];\n start_ms?: number;\n end_ms?: number;\n }[];\n input_tokens?: number;\n output_tokens?: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n model_id?: string;\n provider_type?: string;\n duration_ms?: number;\n output_text?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport class AssistantCloudRuns {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public __internal_getAssistantOptions(assistantId: string) {\n return {\n api: `${this.cloud._baseUrl}/v1/runs/stream`,\n headers: async () => {\n const headers = await this.cloud._auth.getAuthHeaders();\n if (!headers) throw new Error(\"Authorization failed\");\n return {\n ...headers,\n Accept: \"text/plain\",\n };\n },\n body: {\n assistant_id: assistantId,\n response_format: \"vercel-ai-data-stream/v1\",\n thread_id: \"unstable_todo\",\n },\n };\n }\n\n public async stream(\n body: AssistantCloudRunsStreamBody,\n ): Promise<AssistantStream> {\n const response = await this.cloud.makeRawRequest(\"/runs/stream\", {\n method: \"POST\",\n headers: {\n Accept: \"text/plain\",\n },\n body,\n });\n return AssistantStream.fromResponse(response, new PlainTextDecoder());\n }\n\n public async report(\n body: AssistantCloudRunReport,\n ): Promise<{ run_id: string }> {\n return this.cloud.makeRequest(\"/runs\", { method: \"POST\", body });\n }\n}\n"],"mappings":";;AAiDA,IAAa,qBAAb,MAAgC;CAC9B;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,+BAAsC,aAAqB;EACzD,OAAO;GACL,KAAK,GAAG,KAAK,MAAM,SAAS;GAC5B,SAAS,YAAY;IACnB,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,eAAe;IACtD,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,sBAAsB;IACpD,OAAO;KACL,GAAG;KACH,QAAQ;IACV;GACF;GACA,MAAM;IACJ,cAAc;IACd,iBAAiB;IACjB,WAAW;GACb;EACF;CACF;CAEA,MAAa,OACX,MAC0B;EAC1B,MAAM,WAAW,MAAM,KAAK,MAAM,eAAe,gBAAgB;GAC/D,QAAQ;GACR,SAAS,EACP,QAAQ,aACV;GACA;EACF,CAAC;EACD,OAAO,gBAAgB,aAAa,UAAU,IAAI,iBAAiB,CAAC;CACtE;CAEA,MAAa,OACX,MAC6B;EAC7B,OAAO,KAAK,MAAM,YAAY,SAAS;GAAE,QAAQ;GAAQ;EAAK,CAAC;CACjE;AACF"}
1
+ {"version":3,"file":"AssistantCloudRuns.js","names":[],"sources":["../src/AssistantCloudRuns.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport type { AssistantCloudRunReportToolCall } from \"./runTelemetry\";\nimport { AssistantStream, PlainTextDecoder } from \"assistant-stream\";\nimport {\n CloudResponseError,\n readCloudRecord,\n readCloudString,\n} from \"./cloudResponse\";\n\ntype AssistantCloudRunsStreamBody = {\n thread_id: string;\n assistant_id: \"system/thread_title\";\n messages: readonly unknown[]; // TODO type\n};\n\n// NOTE: Keep this payload shape aligned with the strict runtime validator in\n// assistant-cloud: apps/aui-cloud-api/src/endpoints/runs/create.ts\n// (createRunSchema). New telemetry fields must be added in both repos together.\nexport type AssistantCloudRunReport = {\n thread_id: string;\n status: \"completed\" | \"incomplete\" | \"error\";\n total_steps?: number;\n tool_calls?: AssistantCloudRunReportToolCall[];\n steps?: {\n input_tokens?: number;\n output_tokens?: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n tool_calls?: AssistantCloudRunReportToolCall[];\n start_ms?: number;\n end_ms?: number;\n }[];\n input_tokens?: number;\n output_tokens?: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n model_id?: string;\n provider_type?: string;\n duration_ms?: number;\n output_text?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport class AssistantCloudRuns {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public __internal_getAssistantOptions(assistantId: string) {\n return {\n api: `${this.cloud._baseUrl}/v1/runs/stream`,\n headers: async () => {\n const headers = await this.cloud._auth.getAuthHeaders();\n if (!headers) throw new Error(\"Authorization failed\");\n return {\n ...headers,\n Accept: \"text/plain\",\n };\n },\n body: {\n assistant_id: assistantId,\n response_format: \"vercel-ai-data-stream/v1\",\n thread_id: \"unstable_todo\",\n },\n };\n }\n\n public async stream(\n body: AssistantCloudRunsStreamBody,\n ): Promise<AssistantStream> {\n const response = await this.cloud.makeRawRequest(\"/runs/stream\", {\n method: \"POST\",\n headers: {\n Accept: \"text/plain\",\n },\n body,\n });\n\n if (!response.body) {\n throw new CloudResponseError(\n 'Invalid Assistant Cloud response for \"run stream\": expected a response body',\n );\n }\n\n const receivedContentType = response.headers.get(\"content-type\");\n const contentType = receivedContentType\n ?.split(\";\", 1)[0]\n ?.trim()\n .toLowerCase();\n if (contentType !== \"text/plain\") {\n await response.body.cancel().catch(() => undefined);\n throw new CloudResponseError(\n `Invalid Assistant Cloud response for \"run stream\": expected a \"text/plain\" content type, received ${\n receivedContentType\n ? `\"${receivedContentType}\"`\n : \"no Content-Type header\"\n }`,\n );\n }\n\n return AssistantStream.fromResponse(response, new PlainTextDecoder());\n }\n\n public async report(\n body: AssistantCloudRunReport,\n ): Promise<{ run_id: string }> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\"/runs\", { method: \"POST\", body }),\n \"run report response\",\n );\n\n return { run_id: readCloudString(response.run_id, \"run_id\") };\n }\n}\n"],"mappings":";;;AA2CA,IAAa,qBAAb,MAAgC;CAC9B;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,+BAAsC,aAAqB;EACzD,OAAO;GACL,KAAK,GAAG,KAAK,MAAM,SAAS;GAC5B,SAAS,YAAY;IACnB,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,eAAe;IACtD,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,sBAAsB;IACpD,OAAO;KACL,GAAG;KACH,QAAQ;IACV;GACF;GACA,MAAM;IACJ,cAAc;IACd,iBAAiB;IACjB,WAAW;GACb;EACF;CACF;CAEA,MAAa,OACX,MAC0B;EAC1B,MAAM,WAAW,MAAM,KAAK,MAAM,eAAe,gBAAgB;GAC/D,QAAQ;GACR,SAAS,EACP,QAAQ,aACV;GACA;EACF,CAAC;EAED,IAAI,CAAC,SAAS,MACZ,MAAM,IAAI,mBACR,+EACF;EAGF,MAAM,sBAAsB,SAAS,QAAQ,IAAI,cAAc;EAK/D,IAJoB,qBAChB,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,EAChB,KAAK,CAAC,CACP,YAAY,MACK,cAAc;GAChC,MAAM,SAAS,KAAK,OAAO,CAAC,CAAC,YAAY,KAAA,CAAS;GAClD,MAAM,IAAI,mBACR,qGACE,sBACI,IAAI,oBAAoB,KACxB,0BAER;EACF;EAEA,OAAO,gBAAgB,aAAa,UAAU,IAAI,iBAAiB,CAAC;CACtE;CAEA,MAAa,OACX,MAC6B;EAC7B,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,SAAS;GAAE,QAAQ;GAAQ;EAAK,CAAC,GAC9D,qBACF;EAEA,OAAO,EAAE,QAAQ,gBAAgB,SAAS,QAAQ,QAAQ,EAAE;CAC9D;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreadMessages.d.ts","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"mappings":";;;KAYY;EACV;EACA;EACA;EACA,YAAY;EACZ,YAAY;EACZ;EACA,SAAS;;KAGN;EACH;;KAGG;EACH,UAAU;;KAGP;EACH;EACA;EACA,SAAS;;KAGN;EACH;;KAGG;EACH,SAAS;;cAGE,qBACX,gBACA,kBACC;cAaU;UACH;EAEI,YAAA,OAAO;EAIN,KACX,kBACA,QAAQ,uCACP,QAAQ;EAiBE,OACX,kBACA,MAAM,wCACL,QAAQ;EAOE,OACX,kBACA,mBACA,MAAM,wCACL"}
1
+ {"version":3,"file":"AssistantCloudThreadMessages.d.ts","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"mappings":";;;KAYY;EACV;EACA;EACA;EACA,YAAY;EACZ,YAAY;EACZ;EACA,SAAS;;KAGN;EACH;;KAGG;EACH,UAAU;;KAGP;EACH;EACA;EACA,SAAS;;KAGN;EACH;;KAGG;EACH,SAAS;;cAGE,qBACX,gBACA,kBACC;cAaU;UACH;EAEI,YAAA,OAAO;EAIN,KACX,kBACA,QAAQ,uCACP,QAAQ;EAiBE,OACX,kBACA,MAAM,wCACL,QAAQ;EAcE,OACX,kBACA,mBACA,MAAM,wCACL"}
@@ -22,10 +22,11 @@ var AssistantCloudThreadMessages = class {
22
22
  return { messages: readCloudArray(response.messages, "messages").map((message, index) => decodeCloudMessage(message, `messages[${index}]`)) };
23
23
  }
24
24
  async create(threadId, body) {
25
- return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}/messages`, {
25
+ const response = readCloudRecord(await this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}/messages`, {
26
26
  method: "POST",
27
27
  body
28
- });
28
+ }), "thread message create response");
29
+ return { message_id: readCloudString(response.message_id, "message_id") };
29
30
  }
30
31
  async update(threadId, messageId, body) {
31
32
  return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}`, {
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreadMessages.js","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"sourcesContent":["import type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport {\n readCloudArray,\n readCloudInteger,\n readCloudJSONObject,\n readCloudNullableString,\n readCloudRecord,\n readCloudString,\n readCloudTimestamp,\n} from \"./cloudResponse\";\n\nexport type CloudMessage = {\n id: string;\n parent_id: string | null;\n height: number;\n created_at: Date;\n updated_at: Date;\n format: \"aui/v0\" | string;\n content: ReadonlyJSONObject;\n};\n\ntype AssistantCloudThreadMessageListQuery = {\n format?: string;\n};\n\ntype AssistantCloudThreadMessageListResponse = {\n messages: CloudMessage[];\n};\n\ntype AssistantCloudThreadMessageCreateBody = {\n parent_id: string | null;\n format: \"aui/v0\" | string;\n content: ReadonlyJSONObject;\n};\n\ntype AssistantCloudMessageCreateResponse = {\n message_id: string;\n};\n\ntype AssistantCloudThreadMessageUpdateBody = {\n content: ReadonlyJSONObject;\n};\n\nexport const decodeCloudMessage = (\n value: unknown,\n field: string,\n): CloudMessage => {\n const message = readCloudRecord(value, field);\n return {\n id: readCloudString(message.id, `${field}.id`),\n parent_id: readCloudNullableString(message.parent_id, `${field}.parent_id`),\n height: readCloudInteger(message.height, `${field}.height`),\n created_at: readCloudTimestamp(message.created_at, `${field}.created_at`),\n updated_at: readCloudTimestamp(message.updated_at, `${field}.updated_at`),\n format: readCloudString(message.format, `${field}.format`),\n content: readCloudJSONObject(message.content, `${field}.content`),\n };\n};\n\nexport class AssistantCloudThreadMessages {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public async list(\n threadId: string,\n query?: AssistantCloudThreadMessageListQuery,\n ): Promise<AssistantCloudThreadMessageListResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages`,\n { query },\n ),\n \"thread message list response\",\n );\n const messages = readCloudArray(response.messages, \"messages\");\n\n return {\n messages: messages.map((message, index) =>\n decodeCloudMessage(message, `messages[${index}]`),\n ),\n };\n }\n\n public async create(\n threadId: string,\n body: AssistantCloudThreadMessageCreateBody,\n ): Promise<AssistantCloudMessageCreateResponse> {\n return this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages`,\n { method: \"POST\", body },\n );\n }\n\n public async update(\n threadId: string,\n messageId: string,\n body: AssistantCloudThreadMessageUpdateBody,\n ): Promise<void> {\n return this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}`,\n { method: \"PUT\", body },\n );\n }\n}\n"],"mappings":";;AA4CA,MAAa,sBACX,OACA,UACiB;CACjB,MAAM,UAAU,gBAAgB,OAAO,KAAK;CAC5C,OAAO;EACL,IAAI,gBAAgB,QAAQ,IAAI,GAAG,MAAM,IAAI;EAC7C,WAAW,wBAAwB,QAAQ,WAAW,GAAG,MAAM,WAAW;EAC1E,QAAQ,iBAAiB,QAAQ,QAAQ,GAAG,MAAM,QAAQ;EAC1D,YAAY,mBAAmB,QAAQ,YAAY,GAAG,MAAM,YAAY;EACxE,YAAY,mBAAmB,QAAQ,YAAY,GAAG,MAAM,YAAY;EACxE,QAAQ,gBAAgB,QAAQ,QAAQ,GAAG,MAAM,QAAQ;EACzD,SAAS,oBAAoB,QAAQ,SAAS,GAAG,MAAM,SAAS;CAClE;AACF;AAEA,IAAa,+BAAb,MAA0C;CACxC;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,MAAa,KACX,UACA,OACkD;EAClD,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YACzC,EAAE,MAAM,CACV,GACA,8BACF;EAGA,OAAO,EACL,UAHe,eAAe,SAAS,UAAU,UAGhC,CAAC,CAAC,KAAK,SAAS,UAC/B,mBAAmB,SAAS,YAAY,MAAM,EAAE,CAClD,EACF;CACF;CAEA,MAAa,OACX,UACA,MAC8C;EAC9C,OAAO,KAAK,MAAM,YAChB,YAAY,mBAAmB,QAAQ,EAAE,YACzC;GAAE,QAAQ;GAAQ;EAAK,CACzB;CACF;CAEA,MAAa,OACX,UACA,WACA,MACe;EACf,OAAO,KAAK,MAAM,YAChB,YAAY,mBAAmB,QAAQ,EAAE,YAAY,mBAAmB,SAAS,KACjF;GAAE,QAAQ;GAAO;EAAK,CACxB;CACF;AACF"}
1
+ {"version":3,"file":"AssistantCloudThreadMessages.js","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"sourcesContent":["import type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport {\n readCloudArray,\n readCloudInteger,\n readCloudJSONObject,\n readCloudNullableString,\n readCloudRecord,\n readCloudString,\n readCloudTimestamp,\n} from \"./cloudResponse\";\n\nexport type CloudMessage = {\n id: string;\n parent_id: string | null;\n height: number;\n created_at: Date;\n updated_at: Date;\n format: \"aui/v0\" | string;\n content: ReadonlyJSONObject;\n};\n\ntype AssistantCloudThreadMessageListQuery = {\n format?: string;\n};\n\ntype AssistantCloudThreadMessageListResponse = {\n messages: CloudMessage[];\n};\n\ntype AssistantCloudThreadMessageCreateBody = {\n parent_id: string | null;\n format: \"aui/v0\" | string;\n content: ReadonlyJSONObject;\n};\n\ntype AssistantCloudMessageCreateResponse = {\n message_id: string;\n};\n\ntype AssistantCloudThreadMessageUpdateBody = {\n content: ReadonlyJSONObject;\n};\n\nexport const decodeCloudMessage = (\n value: unknown,\n field: string,\n): CloudMessage => {\n const message = readCloudRecord(value, field);\n return {\n id: readCloudString(message.id, `${field}.id`),\n parent_id: readCloudNullableString(message.parent_id, `${field}.parent_id`),\n height: readCloudInteger(message.height, `${field}.height`),\n created_at: readCloudTimestamp(message.created_at, `${field}.created_at`),\n updated_at: readCloudTimestamp(message.updated_at, `${field}.updated_at`),\n format: readCloudString(message.format, `${field}.format`),\n content: readCloudJSONObject(message.content, `${field}.content`),\n };\n};\n\nexport class AssistantCloudThreadMessages {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public async list(\n threadId: string,\n query?: AssistantCloudThreadMessageListQuery,\n ): Promise<AssistantCloudThreadMessageListResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages`,\n { query },\n ),\n \"thread message list response\",\n );\n const messages = readCloudArray(response.messages, \"messages\");\n\n return {\n messages: messages.map((message, index) =>\n decodeCloudMessage(message, `messages[${index}]`),\n ),\n };\n }\n\n public async create(\n threadId: string,\n body: AssistantCloudThreadMessageCreateBody,\n ): Promise<AssistantCloudMessageCreateResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages`,\n { method: \"POST\", body },\n ),\n \"thread message create response\",\n );\n\n return {\n message_id: readCloudString(response.message_id, \"message_id\"),\n };\n }\n\n public async update(\n threadId: string,\n messageId: string,\n body: AssistantCloudThreadMessageUpdateBody,\n ): Promise<void> {\n return this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}`,\n { method: \"PUT\", body },\n );\n }\n}\n"],"mappings":";;AA4CA,MAAa,sBACX,OACA,UACiB;CACjB,MAAM,UAAU,gBAAgB,OAAO,KAAK;CAC5C,OAAO;EACL,IAAI,gBAAgB,QAAQ,IAAI,GAAG,MAAM,IAAI;EAC7C,WAAW,wBAAwB,QAAQ,WAAW,GAAG,MAAM,WAAW;EAC1E,QAAQ,iBAAiB,QAAQ,QAAQ,GAAG,MAAM,QAAQ;EAC1D,YAAY,mBAAmB,QAAQ,YAAY,GAAG,MAAM,YAAY;EACxE,YAAY,mBAAmB,QAAQ,YAAY,GAAG,MAAM,YAAY;EACxE,QAAQ,gBAAgB,QAAQ,QAAQ,GAAG,MAAM,QAAQ;EACzD,SAAS,oBAAoB,QAAQ,SAAS,GAAG,MAAM,SAAS;CAClE;AACF;AAEA,IAAa,+BAAb,MAA0C;CACxC;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,MAAa,KACX,UACA,OACkD;EAClD,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YACzC,EAAE,MAAM,CACV,GACA,8BACF;EAGA,OAAO,EACL,UAHe,eAAe,SAAS,UAAU,UAGhC,CAAC,CAAC,KAAK,SAAS,UAC/B,mBAAmB,SAAS,YAAY,MAAM,EAAE,CAClD,EACF;CACF;CAEA,MAAa,OACX,UACA,MAC8C;EAC9C,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YACzC;GAAE,QAAQ;GAAQ;EAAK,CACzB,GACA,gCACF;EAEA,OAAO,EACL,YAAY,gBAAgB,SAAS,YAAY,YAAY,EAC/D;CACF;CAEA,MAAa,OACX,UACA,WACA,MACe;EACf,OAAO,KAAK,MAAM,YAChB,YAAY,mBAAmB,QAAQ,EAAE,YAAY,mBAAmB,SAAS,KACjF;GAAE,QAAQ;GAAO;EAAK,CACxB;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreads.d.ts","names":[],"sources":["../src/AssistantCloudThreads.ts"],"mappings":";;;KAWK;EACH;EACA;EACA;;KAGU;EACV;EACA,iBAAiB;EACjB;EACA;EACA;EACA;EACA,YAAY;EACZ,YAAY;EACZ;EACA;;KAGG;EACH,SAAS;;KAGN;EACH;EACA,iBAAiB;EACjB;EACA;;KAGG;EACH;;KAGG;EACH;EACA,kBAAkB;EAClB;EACA;;cAGW,oBACX,gBACA,kBACC;cAsBU;WACK,UAAU;UAElB;EAEI,YAAA,OAAO;EAKN,KACX,QAAQ,iCACP,QAAQ;EAkBE,IAAI,mBAAmB,QAAQ;EAS/B,OACX,MAAM,kCACL,QAAQ;EAIE,OACX,kBACA,MAAM,kCACL;EAOU,OAAO,mBAAmB"}
1
+ {"version":3,"file":"AssistantCloudThreads.d.ts","names":[],"sources":["../src/AssistantCloudThreads.ts"],"mappings":";;;KAWK;EACH;EACA;EACA;;KAGU;EACV;EACA,iBAAiB;EACjB;EACA;EACA;EACA;EACA,YAAY;EACZ,YAAY;EACZ;EACA;;KAGG;EACH,SAAS;;KAGN;EACH;EACA,iBAAiB;EACjB;EACA;;KAGG;EACH;;KAGG;EACH;EACA,kBAAkB;EAClB;EACA;;cAGW,oBACX,gBACA,kBACC;cAsBU;WACK,UAAU;UAElB;EAEI,YAAA,OAAO;EAKN,KACX,QAAQ,iCACP,QAAQ;EAkBE,IAAI,mBAAmB,QAAQ;EAS/B,OACX,MAAM,kCACL,QAAQ;EASE,OACX,kBACA,MAAM,kCACL;EAOU,OAAO,mBAAmB"}
@@ -36,10 +36,11 @@ var AssistantCloudThreads = class {
36
36
  return decodeCloudThread(response.thread, "thread");
37
37
  }
38
38
  async create(body) {
39
- return this.cloud.makeRequest("/threads", {
39
+ const response = readCloudRecord(await this.cloud.makeRequest("/threads", {
40
40
  method: "POST",
41
41
  body
42
- });
42
+ }), "thread create response");
43
+ return { thread_id: readCloudString(response.thread_id, "thread_id") };
43
44
  }
44
45
  async update(threadId, body) {
45
46
  return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreads.js","names":[],"sources":["../src/AssistantCloudThreads.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport { AssistantCloudThreadMessages } from \"./AssistantCloudThreadMessages\";\nimport {\n readCloudArray,\n readCloudBoolean,\n readCloudNullableString,\n readCloudRecord,\n readCloudString,\n readCloudTimestamp,\n} from \"./cloudResponse\";\n\ntype AssistantCloudThreadsListQuery = {\n is_archived?: boolean;\n limit?: number;\n after?: string;\n};\n\nexport type CloudThread = {\n title: string;\n last_message_at: Date;\n metadata: unknown;\n external_id: string | null;\n id: string;\n project_id: string;\n created_at: Date;\n updated_at: Date;\n workspace_id: string;\n is_archived: boolean;\n};\n\ntype AssistantCloudThreadsListResponse = {\n threads: CloudThread[];\n};\n\ntype AssistantCloudThreadsCreateBody = {\n title?: string | undefined;\n last_message_at: Date;\n metadata?: unknown | undefined;\n external_id?: string | undefined;\n};\n\ntype AssistantCloudThreadsCreateResponse = {\n thread_id: string;\n};\n\ntype AssistantCloudThreadsUpdateBody = {\n title?: string | undefined;\n last_message_at?: Date | undefined;\n metadata?: unknown | undefined;\n is_archived?: boolean | undefined;\n};\n\nexport const decodeCloudThread = (\n value: unknown,\n field: string,\n): CloudThread => {\n const thread = readCloudRecord(value, field);\n return {\n title: readCloudNullableString(thread.title, `${field}.title`) ?? \"\",\n last_message_at: readCloudTimestamp(\n thread.last_message_at,\n `${field}.last_message_at`,\n ),\n metadata: thread.metadata,\n external_id: readCloudNullableString(\n thread.external_id,\n `${field}.external_id`,\n ),\n id: readCloudString(thread.id, `${field}.id`),\n project_id: readCloudString(thread.project_id, `${field}.project_id`),\n created_at: readCloudTimestamp(thread.created_at, `${field}.created_at`),\n updated_at: readCloudTimestamp(thread.updated_at, `${field}.updated_at`),\n workspace_id: readCloudString(thread.workspace_id, `${field}.workspace_id`),\n is_archived: readCloudBoolean(thread.is_archived, `${field}.is_archived`),\n };\n};\n\nexport class AssistantCloudThreads {\n public readonly messages: AssistantCloudThreadMessages;\n\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n this.messages = new AssistantCloudThreadMessages(cloud);\n }\n\n public async list(\n query?: AssistantCloudThreadsListQuery,\n ): Promise<AssistantCloudThreadsListResponse> {\n const requestQuery =\n query?.is_archived === undefined\n ? query\n : { ...query, is_archived: String(query.is_archived) };\n const response = readCloudRecord(\n await this.cloud.makeRequest(\"/threads\", { query: requestQuery }),\n \"thread list response\",\n );\n const threads = readCloudArray(response.threads, \"threads\");\n\n return {\n threads: threads.map((thread, index) =>\n decodeCloudThread(thread, `threads[${index}]`),\n ),\n };\n }\n\n public async get(threadId: string): Promise<CloudThread> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`),\n \"thread response\",\n );\n\n return decodeCloudThread(response.thread, \"thread\");\n }\n\n public async create(\n body: AssistantCloudThreadsCreateBody,\n ): Promise<AssistantCloudThreadsCreateResponse> {\n return this.cloud.makeRequest(\"/threads\", { method: \"POST\", body });\n }\n\n public async update(\n threadId: string,\n body: AssistantCloudThreadsUpdateBody,\n ): Promise<void> {\n return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {\n method: \"PUT\",\n body,\n });\n }\n\n public async delete(threadId: string): Promise<void> {\n return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {\n method: \"DELETE\",\n });\n }\n}\n"],"mappings":";;;AAoDA,MAAa,qBACX,OACA,UACgB;CAChB,MAAM,SAAS,gBAAgB,OAAO,KAAK;CAC3C,OAAO;EACL,OAAO,wBAAwB,OAAO,OAAO,GAAG,MAAM,OAAO,KAAK;EAClE,iBAAiB,mBACf,OAAO,iBACP,GAAG,MAAM,iBACX;EACA,UAAU,OAAO;EACjB,aAAa,wBACX,OAAO,aACP,GAAG,MAAM,aACX;EACA,IAAI,gBAAgB,OAAO,IAAI,GAAG,MAAM,IAAI;EAC5C,YAAY,gBAAgB,OAAO,YAAY,GAAG,MAAM,YAAY;EACpE,YAAY,mBAAmB,OAAO,YAAY,GAAG,MAAM,YAAY;EACvE,YAAY,mBAAmB,OAAO,YAAY,GAAG,MAAM,YAAY;EACvE,cAAc,gBAAgB,OAAO,cAAc,GAAG,MAAM,cAAc;EAC1E,aAAa,iBAAiB,OAAO,aAAa,GAAG,MAAM,aAAa;CAC1E;AACF;AAEA,IAAa,wBAAb,MAAmC;CACjC;CAEA;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;EACb,KAAK,WAAW,IAAI,6BAA6B,KAAK;CACxD;CAEA,MAAa,KACX,OAC4C;EAC5C,MAAM,eACJ,OAAO,gBAAgB,KAAA,IACnB,QACA;GAAE,GAAG;GAAO,aAAa,OAAO,MAAM,WAAW;EAAE;EACzD,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,YAAY,EAAE,OAAO,aAAa,CAAC,GAChE,sBACF;EAGA,OAAO,EACL,SAHc,eAAe,SAAS,SAAS,SAGhC,CAAC,CAAC,KAAK,QAAQ,UAC5B,kBAAkB,QAAQ,WAAW,MAAM,EAAE,CAC/C,EACF;CACF;CAEA,MAAa,IAAI,UAAwC;EACvD,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,YAAY,mBAAmB,QAAQ,GAAG,GACvE,iBACF;EAEA,OAAO,kBAAkB,SAAS,QAAQ,QAAQ;CACpD;CAEA,MAAa,OACX,MAC8C;EAC9C,OAAO,KAAK,MAAM,YAAY,YAAY;GAAE,QAAQ;GAAQ;EAAK,CAAC;CACpE;CAEA,MAAa,OACX,UACA,MACe;EACf,OAAO,KAAK,MAAM,YAAY,YAAY,mBAAmB,QAAQ,KAAK;GACxE,QAAQ;GACR;EACF,CAAC;CACH;CAEA,MAAa,OAAO,UAAiC;EACnD,OAAO,KAAK,MAAM,YAAY,YAAY,mBAAmB,QAAQ,KAAK,EACxE,QAAQ,SACV,CAAC;CACH;AACF"}
1
+ {"version":3,"file":"AssistantCloudThreads.js","names":[],"sources":["../src/AssistantCloudThreads.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport { AssistantCloudThreadMessages } from \"./AssistantCloudThreadMessages\";\nimport {\n readCloudArray,\n readCloudBoolean,\n readCloudNullableString,\n readCloudRecord,\n readCloudString,\n readCloudTimestamp,\n} from \"./cloudResponse\";\n\ntype AssistantCloudThreadsListQuery = {\n is_archived?: boolean;\n limit?: number;\n after?: string;\n};\n\nexport type CloudThread = {\n title: string;\n last_message_at: Date;\n metadata: unknown;\n external_id: string | null;\n id: string;\n project_id: string;\n created_at: Date;\n updated_at: Date;\n workspace_id: string;\n is_archived: boolean;\n};\n\ntype AssistantCloudThreadsListResponse = {\n threads: CloudThread[];\n};\n\ntype AssistantCloudThreadsCreateBody = {\n title?: string | undefined;\n last_message_at: Date;\n metadata?: unknown | undefined;\n external_id?: string | undefined;\n};\n\ntype AssistantCloudThreadsCreateResponse = {\n thread_id: string;\n};\n\ntype AssistantCloudThreadsUpdateBody = {\n title?: string | undefined;\n last_message_at?: Date | undefined;\n metadata?: unknown | undefined;\n is_archived?: boolean | undefined;\n};\n\nexport const decodeCloudThread = (\n value: unknown,\n field: string,\n): CloudThread => {\n const thread = readCloudRecord(value, field);\n return {\n title: readCloudNullableString(thread.title, `${field}.title`) ?? \"\",\n last_message_at: readCloudTimestamp(\n thread.last_message_at,\n `${field}.last_message_at`,\n ),\n metadata: thread.metadata,\n external_id: readCloudNullableString(\n thread.external_id,\n `${field}.external_id`,\n ),\n id: readCloudString(thread.id, `${field}.id`),\n project_id: readCloudString(thread.project_id, `${field}.project_id`),\n created_at: readCloudTimestamp(thread.created_at, `${field}.created_at`),\n updated_at: readCloudTimestamp(thread.updated_at, `${field}.updated_at`),\n workspace_id: readCloudString(thread.workspace_id, `${field}.workspace_id`),\n is_archived: readCloudBoolean(thread.is_archived, `${field}.is_archived`),\n };\n};\n\nexport class AssistantCloudThreads {\n public readonly messages: AssistantCloudThreadMessages;\n\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n this.messages = new AssistantCloudThreadMessages(cloud);\n }\n\n public async list(\n query?: AssistantCloudThreadsListQuery,\n ): Promise<AssistantCloudThreadsListResponse> {\n const requestQuery =\n query?.is_archived === undefined\n ? query\n : { ...query, is_archived: String(query.is_archived) };\n const response = readCloudRecord(\n await this.cloud.makeRequest(\"/threads\", { query: requestQuery }),\n \"thread list response\",\n );\n const threads = readCloudArray(response.threads, \"threads\");\n\n return {\n threads: threads.map((thread, index) =>\n decodeCloudThread(thread, `threads[${index}]`),\n ),\n };\n }\n\n public async get(threadId: string): Promise<CloudThread> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`),\n \"thread response\",\n );\n\n return decodeCloudThread(response.thread, \"thread\");\n }\n\n public async create(\n body: AssistantCloudThreadsCreateBody,\n ): Promise<AssistantCloudThreadsCreateResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\"/threads\", { method: \"POST\", body }),\n \"thread create response\",\n );\n\n return { thread_id: readCloudString(response.thread_id, \"thread_id\") };\n }\n\n public async update(\n threadId: string,\n body: AssistantCloudThreadsUpdateBody,\n ): Promise<void> {\n return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {\n method: \"PUT\",\n body,\n });\n }\n\n public async delete(threadId: string): Promise<void> {\n return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {\n method: \"DELETE\",\n });\n }\n}\n"],"mappings":";;;AAoDA,MAAa,qBACX,OACA,UACgB;CAChB,MAAM,SAAS,gBAAgB,OAAO,KAAK;CAC3C,OAAO;EACL,OAAO,wBAAwB,OAAO,OAAO,GAAG,MAAM,OAAO,KAAK;EAClE,iBAAiB,mBACf,OAAO,iBACP,GAAG,MAAM,iBACX;EACA,UAAU,OAAO;EACjB,aAAa,wBACX,OAAO,aACP,GAAG,MAAM,aACX;EACA,IAAI,gBAAgB,OAAO,IAAI,GAAG,MAAM,IAAI;EAC5C,YAAY,gBAAgB,OAAO,YAAY,GAAG,MAAM,YAAY;EACpE,YAAY,mBAAmB,OAAO,YAAY,GAAG,MAAM,YAAY;EACvE,YAAY,mBAAmB,OAAO,YAAY,GAAG,MAAM,YAAY;EACvE,cAAc,gBAAgB,OAAO,cAAc,GAAG,MAAM,cAAc;EAC1E,aAAa,iBAAiB,OAAO,aAAa,GAAG,MAAM,aAAa;CAC1E;AACF;AAEA,IAAa,wBAAb,MAAmC;CACjC;CAEA;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;EACb,KAAK,WAAW,IAAI,6BAA6B,KAAK;CACxD;CAEA,MAAa,KACX,OAC4C;EAC5C,MAAM,eACJ,OAAO,gBAAgB,KAAA,IACnB,QACA;GAAE,GAAG;GAAO,aAAa,OAAO,MAAM,WAAW;EAAE;EACzD,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,YAAY,EAAE,OAAO,aAAa,CAAC,GAChE,sBACF;EAGA,OAAO,EACL,SAHc,eAAe,SAAS,SAAS,SAGhC,CAAC,CAAC,KAAK,QAAQ,UAC5B,kBAAkB,QAAQ,WAAW,MAAM,EAAE,CAC/C,EACF;CACF;CAEA,MAAa,IAAI,UAAwC;EACvD,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,YAAY,mBAAmB,QAAQ,GAAG,GACvE,iBACF;EAEA,OAAO,kBAAkB,SAAS,QAAQ,QAAQ;CACpD;CAEA,MAAa,OACX,MAC8C;EAC9C,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,YAAY;GAAE,QAAQ;GAAQ;EAAK,CAAC,GACjE,wBACF;EAEA,OAAO,EAAE,WAAW,gBAAgB,SAAS,WAAW,WAAW,EAAE;CACvE;CAEA,MAAa,OACX,UACA,MACe;EACf,OAAO,KAAK,MAAM,YAAY,YAAY,mBAAmB,QAAQ,KAAK;GACxE,QAAQ;GACR;EACF,CAAC;CACH;CAEA,MAAa,OAAO,UAAiC;EACnD,OAAO,KAAK,MAAM,YAAY,YAAY,mBAAmB,QAAQ,KAAK,EACxE,QAAQ,SACV,CAAC;CACH;AACF"}
@@ -0,0 +1,15 @@
1
+ import { AssistantCloud } from "./AssistantCloud.js";
2
+ //#region src/generateThreadTitle.d.ts
3
+ declare function generateThreadTitle(cloud: AssistantCloud, options: {
4
+ threadId: string;
5
+ messages: readonly {
6
+ role: string;
7
+ content: readonly {
8
+ type: "text";
9
+ text: string;
10
+ }[];
11
+ }[];
12
+ }): Promise<string | null>;
13
+ //#endregion
14
+ export { generateThreadTitle };
15
+ //# sourceMappingURL=generateThreadTitle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateThreadTitle.d.ts","names":[],"sources":["../src/generateThreadTitle.ts"],"mappings":";;iBAEsB,oBACpB,OAAO,gBACP;EACE;EACA;IACE;IACA;MAAoB;MAAc;;;IAGrC"}
@@ -0,0 +1,25 @@
1
+ //#region src/generateThreadTitle.ts
2
+ async function generateThreadTitle(cloud, options) {
3
+ const stream = await cloud.runs.stream({
4
+ thread_id: options.threadId,
5
+ assistant_id: "system/thread_title",
6
+ messages: options.messages
7
+ });
8
+ let title = "";
9
+ const reader = stream.getReader();
10
+ try {
11
+ while (true) {
12
+ const { done, value: chunk } = await reader.read();
13
+ if (done) break;
14
+ if (chunk.type === "text-delta") title += chunk.textDelta;
15
+ }
16
+ } finally {
17
+ reader.releaseLock();
18
+ }
19
+ if (title) await cloud.threads.update(options.threadId, { title });
20
+ return title || null;
21
+ }
22
+ //#endregion
23
+ export { generateThreadTitle };
24
+
25
+ //# sourceMappingURL=generateThreadTitle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateThreadTitle.js","names":[],"sources":["../src/generateThreadTitle.ts"],"sourcesContent":["import type { AssistantCloud } from \"./AssistantCloud\";\n\nexport async function generateThreadTitle(\n cloud: AssistantCloud,\n options: {\n threadId: string;\n messages: readonly {\n role: string;\n content: readonly { type: \"text\"; text: string }[];\n }[];\n },\n): Promise<string | null> {\n const stream = await cloud.runs.stream({\n thread_id: options.threadId,\n assistant_id: \"system/thread_title\",\n messages: options.messages,\n });\n\n let title = \"\";\n const reader = stream.getReader();\n try {\n while (true) {\n const { done, value: chunk } = await reader.read();\n if (done) break;\n if (chunk.type === \"text-delta\") {\n title += chunk.textDelta;\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n if (title) {\n await cloud.threads.update(options.threadId, { title });\n }\n\n return title || null;\n}\n"],"mappings":";AAEA,eAAsB,oBACpB,OACA,SAOwB;CACxB,MAAM,SAAS,MAAM,MAAM,KAAK,OAAO;EACrC,WAAW,QAAQ;EACnB,cAAc;EACd,UAAU,QAAQ;CACpB,CAAC;CAED,IAAI,QAAQ;CACZ,MAAM,SAAS,OAAO,UAAU;CAChC,IAAI;EACF,OAAO,MAAM;GACX,MAAM,EAAE,MAAM,OAAO,UAAU,MAAM,OAAO,KAAK;GACjD,IAAI,MAAM;GACV,IAAI,MAAM,SAAS,cACjB,SAAS,MAAM;EAEnB;CACF,UAAU;EACR,OAAO,YAAY;CACrB;CAEA,IAAI,OACF,MAAM,MAAM,QAAQ,OAAO,QAAQ,UAAU,EAAE,MAAM,CAAC;CAGxD,OAAO,SAAS;AAClB"}