assistant-cloud 0.1.33 → 0.1.35

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 (32) hide show
  1. package/dist/AssistantCloud.d.ts +0 -1
  2. package/dist/AssistantCloud.d.ts.map +1 -1
  3. package/dist/AssistantCloudAPI.d.ts +5 -2
  4. package/dist/AssistantCloudAPI.d.ts.map +1 -1
  5. package/dist/AssistantCloudAPI.js +13 -7
  6. package/dist/AssistantCloudAPI.js.map +1 -1
  7. package/dist/AssistantCloudAuthStrategy.d.ts.map +1 -1
  8. package/dist/AssistantCloudAuthStrategy.js +36 -5
  9. package/dist/AssistantCloudAuthStrategy.js.map +1 -1
  10. package/dist/AssistantCloudAuthTokens.d.ts +0 -1
  11. package/dist/AssistantCloudAuthTokens.d.ts.map +1 -1
  12. package/dist/AssistantCloudFiles.d.ts +0 -1
  13. package/dist/AssistantCloudFiles.d.ts.map +1 -1
  14. package/dist/AssistantCloudRuns.d.ts +0 -1
  15. package/dist/AssistantCloudRuns.d.ts.map +1 -1
  16. package/dist/AssistantCloudThreadMessages.d.ts +0 -1
  17. package/dist/AssistantCloudThreadMessages.d.ts.map +1 -1
  18. package/dist/AssistantCloudThreads.d.ts +0 -1
  19. package/dist/AssistantCloudThreads.d.ts.map +1 -1
  20. package/dist/CloudMessagePersistence.d.ts +0 -1
  21. package/dist/CloudMessagePersistence.d.ts.map +1 -1
  22. package/dist/FormattedCloudPersistence.d.ts +0 -1
  23. package/dist/FormattedCloudPersistence.d.ts.map +1 -1
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +2 -1
  26. package/dist/instrumentMcpSampling.d.ts.map +1 -1
  27. package/package.json +5 -5
  28. package/src/AssistantCloudAPI.ts +20 -7
  29. package/src/AssistantCloudAuthStrategy.ts +47 -18
  30. package/src/index.ts +1 -0
  31. package/src/tests/AssistantCloudAPI.test.ts +76 -7
  32. package/src/tests/AssistantCloudAuthStrategy.test.ts +163 -0
@@ -3,7 +3,6 @@ import { AssistantCloudConfig, AssistantCloudTelemetryConfig } from "./Assistant
3
3
  import { AssistantCloudAuthTokens } from "./AssistantCloudAuthTokens.js";
4
4
  import { AssistantCloudThreads } from "./AssistantCloudThreads.js";
5
5
  import { AssistantCloudFiles } from "./AssistantCloudFiles.js";
6
-
7
6
  //#region src/AssistantCloud.d.ts
8
7
  declare class AssistantCloud {
9
8
  readonly threads: AssistantCloudThreads;
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloud.d.ts","names":[],"sources":["../src/AssistantCloud.ts"],"mappings":";;;;;;;cAUa,cAAA;EAAA,SACK,OAAA,EAAO,qBAAA;EAAA,SACP,IAAA;;;WACA,IAAA,EAAI,kBAAA;EAAA,SACJ,KAAA,EAAK,mBAAA;EAAA,SACL,SAAA,EAAW,6BAAA;cAEf,MAAA,EAAQ,oBAAA;AAAA"}
1
+ {"version":3,"file":"AssistantCloud.d.ts","names":[],"sources":["../src/AssistantCloud.ts"],"mappings":";;;;;;cAUa;WACK,SAAO;WACP;;;WACA,MAAI;WACJ,OAAK;WACL,WAAW;cAEf,QAAQ"}
@@ -1,6 +1,5 @@
1
1
  import { AssistantCloudAuthStrategy } from "./AssistantCloudAuthStrategy.js";
2
2
  import { AssistantCloudRunReport } from "./AssistantCloudRuns.js";
3
-
4
3
  //#region src/AssistantCloudAPI.d.ts
5
4
  type AssistantCloudTelemetryConfig = {
6
5
  enabled?: boolean;
@@ -36,6 +35,10 @@ type AssistantCloudConfig = ({
36
35
  */
37
36
  telemetry?: boolean | AssistantCloudTelemetryConfig;
38
37
  };
38
+ declare class CloudAPIError extends Error {
39
+ readonly status: number;
40
+ constructor(message: string, status: number);
41
+ }
39
42
  type MakeRequestOptions = {
40
43
  method?: "POST" | "PUT" | "DELETE" | undefined;
41
44
  headers?: Record<string, string> | undefined;
@@ -51,5 +54,5 @@ declare class AssistantCloudAPI {
51
54
  makeRequest(endpoint: string, options?: MakeRequestOptions): Promise<any>;
52
55
  }
53
56
  //#endregion
54
- export { AssistantCloudAPI, AssistantCloudConfig, AssistantCloudTelemetryConfig };
57
+ export { AssistantCloudAPI, AssistantCloudConfig, AssistantCloudTelemetryConfig, CloudAPIError };
55
58
  //# sourceMappingURL=AssistantCloudAPI.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAPI.d.ts","names":[],"sources":["../src/AssistantCloudAPI.ts"],"mappings":";;;;KAQY,6BAAA;EACV,OAAA;EADU;;;;;EAOV,YAAA,IACE,MAAA,EAAQ,uBAAA,KACL,uBAAuB;AAAA;AAAA,KAGlB,oBAAA;EAEN,OAAA;EACA,SAAA,QAAiB,OAAA;AAAA;EAGjB,OAAA;EACA,MAAA;EACA,MAAA;EACA,WAAA;AAAA;EAGA,OAAA;EACA,SAAA;AAAA;EANA;;;;;;;;AAoB+C;AACnD;;EADA,SAAA,aAAsB,6BAA6B;AAAA;AAAA,KAUhD,kBAAA;EACH,MAAA;EACA,OAAA,GAAU,MAAA;EACV,KAAA,GAAQ,MAAM;EACd,IAAA;AAAA;AAAA,cAGW,iBAAA;EACJ,KAAA,EAAO,0BAAA;EACP,QAAA;cAEK,MAAA,EAAQ,oBAAA;EAuBP,cAAA,IAAc,OAAA;EAId,cAAA,CACX,QAAA,UACA,OAAA,GAAS,kBAAA,GAAuB,OAAA,CAAA,QAAA;EAkDrB,WAAA,CAAY,QAAA,UAAkB,OAAA,GAAS,kBAAA,GAAuB,OAAA;AAAA"}
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;WAGf;cADhB,iBACgB;;KAOf;EACH;EACA,UAAU;EACV,QAAQ;EACR;;cAGW;EACJ,OAAO;EACP;cAEK,QAAQ;EAuBP,kBAAc;EAId,eACX,kBACA,UAAS,qBAAuB,QAAA;EAmDrB,YAAY,kBAAkB,UAAS,qBAAuB"}
@@ -1,9 +1,11 @@
1
1
  import { AssistantCloudAPIKeyAuthStrategy, AssistantCloudAnonymousAuthStrategy, AssistantCloudJWTAuthStrategy } from "./AssistantCloudAuthStrategy.js";
2
2
  //#region src/AssistantCloudAPI.ts
3
3
  var CloudAPIError = class extends Error {
4
- constructor(message) {
4
+ status;
5
+ constructor(message, status) {
5
6
  super(message);
6
- this.name = "APIError";
7
+ this.status = status;
8
+ this.name = "CloudAPIError";
7
9
  }
8
10
  };
9
11
  var AssistantCloudAPI = class {
@@ -22,7 +24,7 @@ var AssistantCloudAPI = class {
22
24
  } else throw new Error("Invalid configuration: Must provide authToken, apiKey, or anonymous configuration");
23
25
  }
24
26
  async initializeAuth() {
25
- return !!this._auth.getAuthHeaders();
27
+ return !!await this._auth.getAuthHeaders();
26
28
  }
27
29
  async makeRawRequest(endpoint, options = {}) {
28
30
  const authHeaders = await this._auth.getAuthHeaders();
@@ -49,19 +51,23 @@ var AssistantCloudAPI = class {
49
51
  if (!response.ok) {
50
52
  const text = await response.text();
51
53
  try {
52
- throw new CloudAPIError(JSON.parse(text).message);
54
+ throw new CloudAPIError(JSON.parse(text).message, response.status);
53
55
  } catch (error) {
54
56
  if (error instanceof CloudAPIError) throw error;
55
- throw new Error(`Request failed with status ${response.status}, ${text}`);
57
+ throw new CloudAPIError(`Request failed with status ${response.status}, ${text}`, response.status);
56
58
  }
57
59
  }
58
60
  return response;
59
61
  }
60
62
  async makeRequest(endpoint, options = {}) {
61
- return (await this.makeRawRequest(endpoint, options)).json();
63
+ const response = await this.makeRawRequest(endpoint, options);
64
+ if (response.status === 204 || response.headers.get("content-length") === "0") return void 0;
65
+ const text = await response.text();
66
+ if (text.trim() === "") return void 0;
67
+ return JSON.parse(text);
62
68
  }
63
69
  };
64
70
  //#endregion
65
- export { AssistantCloudAPI };
71
+ export { AssistantCloudAPI, CloudAPIError };
66
72
 
67
73
  //# sourceMappingURL=AssistantCloudAPI.js.map
@@ -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\nclass CloudAPIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"APIError\";\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\nexport class AssistantCloudAPI {\n public _auth: AssistantCloudAuthStrategy;\n public _baseUrl;\n\n constructor(config: AssistantCloudConfig) {\n if (\"authToken\" in config) {\n this._baseUrl = config.baseUrl;\n this._auth = new AssistantCloudJWTAuthStrategy(config.authToken);\n } else if (\"apiKey\" in config) {\n this._baseUrl = (\n config.baseUrl ?? \"https://backend.assistant-api.com\"\n ).replace(/\\/$/, \"\");\n this._auth = new AssistantCloudAPIKeyAuthStrategy(\n config.apiKey,\n config.userId,\n config.workspaceId,\n );\n } else if (\"anonymous\" in config) {\n this._baseUrl = config.baseUrl;\n this._auth = new AssistantCloudAnonymousAuthStrategy(config.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 !!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);\n } catch (error) {\n if (error instanceof CloudAPIError) throw error;\n throw new Error(\n `Request failed with status ${response.status}, ${text}`,\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 return response.json();\n }\n}\n"],"mappings":";;AAkDA,IAAM,gBAAN,cAA4B,MAAM;CAChC,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AASA,IAAa,oBAAb,MAA+B;CAC7B;CACA;CAEA,YAAY,QAA8B;EACxC,IAAI,eAAe,QAAQ;GACzB,KAAK,WAAW,OAAO;GACvB,KAAK,QAAQ,IAAI,8BAA8B,OAAO,SAAS;EACjE,OAAO,IAAI,YAAY,QAAQ;GAC7B,KAAK,YACH,OAAO,WAAW,oCAAA,CAClB,QAAQ,OAAO,EAAE;GACnB,KAAK,QAAQ,IAAI,iCACf,OAAO,QACP,OAAO,QACP,OAAO,WACT;EACF,OAAO,IAAI,eAAe,QAAQ;GAChC,KAAK,WAAW,OAAO;GACvB,KAAK,QAAQ,IAAI,oCAAoC,OAAO,OAAO;EACrE,OACE,MAAM,IAAI,MACR,mFACF;CAEJ;CAEA,MAAa,iBAAiB;EAC5B,OAAO,CAAC,CAAC,KAAK,MAAM,eAAe;CACrC;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,IACG,CAAC,CAAC,OAAO;GACtC,SAAS,OAAO;IACd,IAAI,iBAAiB,eAAe,MAAM;IAC1C,MAAM,IAAI,MACR,8BAA8B,SAAS,OAAO,IAAI,MACpD;GACF;EACF;EAEA,OAAO;CACT;CAEA,MAAa,YAAY,UAAkB,UAA8B,CAAC,GAAG;EAE3E,QAAO,MADgB,KAAK,eAAe,UAAU,OAAO,EAAA,CAC5C,KAAK;CACvB;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 constructor(\n message: string,\n public readonly status: number,\n ) {\n super(message);\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\nexport class AssistantCloudAPI {\n public _auth: AssistantCloudAuthStrategy;\n public _baseUrl;\n\n constructor(config: AssistantCloudConfig) {\n if (\"authToken\" in config) {\n this._baseUrl = config.baseUrl;\n this._auth = new AssistantCloudJWTAuthStrategy(config.authToken);\n } else if (\"apiKey\" in config) {\n this._baseUrl = (\n config.baseUrl ?? \"https://backend.assistant-api.com\"\n ).replace(/\\/$/, \"\");\n this._auth = new AssistantCloudAPIKeyAuthStrategy(\n config.apiKey,\n config.userId,\n config.workspaceId,\n );\n } else if (\"anonymous\" in config) {\n this._baseUrl = config.baseUrl;\n this._auth = new AssistantCloudAnonymousAuthStrategy(config.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;CAGrB;CAFlB,YACE,SACA,QACA;EACA,MAAM,OAAO;EAFG,KAAA,SAAA;EAGhB,KAAK,OAAO;CACd;AACF;AASA,IAAa,oBAAb,MAA+B;CAC7B;CACA;CAEA,YAAY,QAA8B;EACxC,IAAI,eAAe,QAAQ;GACzB,KAAK,WAAW,OAAO;GACvB,KAAK,QAAQ,IAAI,8BAA8B,OAAO,SAAS;EACjE,OAAO,IAAI,YAAY,QAAQ;GAC7B,KAAK,YACH,OAAO,WAAW,oCAAA,CAClB,QAAQ,OAAO,EAAE;GACnB,KAAK,QAAQ,IAAI,iCACf,OAAO,QACP,OAAO,QACP,OAAO,WACT;EACF,OAAO,IAAI,eAAe,QAAQ;GAChC,KAAK,WAAW,OAAO;GACvB,KAAK,QAAQ,IAAI,oCAAoC,OAAO,OAAO;EACrE,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 +1 @@
1
- {"version":3,"file":"AssistantCloudAuthStrategy.d.ts","names":[],"sources":["../src/AssistantCloudAuthStrategy.ts"],"mappings":";KAAY,0BAAA;EAAA,SACD,QAAA;EACT,cAAA,IAAkB,OAAA,CAAQ,MAAA;EAC1B,eAAA,CAAgB,OAAA,EAAS,OAAA;AAAA;AAAA,cAiCd,6BAAA,YAAyC,0BAAA;EAAA;WACpC,QAAA;EAAA,QAER,WAAA;EAAA,QACA,WAAA;cAGI,iBAAA,QAAyB,OAAA;EAIxB,cAAA,IAAkB,OAAA,CAAQ,MAAA;EAsBhC,eAAA,CAAgB,OAAA,EAAS,OAAA;AAAA;AAAA,cAcrB,gCAAA,YAA4C,0BAAA;EAAA;WACvC,QAAA;cAMJ,MAAA,UAAgB,MAAA,UAAgB,WAAA;EAM/B,cAAA,IAAkB,OAAA,CAAQ,MAAA;EAQhC,eAAA;AAAA;AAAA,cAOI,mCAAA,YAA+C,0BAAA;EAAA,SAC1C,QAAA;EAAA,QAER,OAAA;EAAA,QACA,WAAA;cAEI,OAAA;EA8DC,cAAA,IAAkB,OAAA,CAAQ,MAAA;EAIhC,eAAA,CAAgB,OAAA,EAAS,OAAA;AAAA"}
1
+ {"version":3,"file":"AssistantCloudAuthStrategy.d.ts","names":[],"sources":["../src/AssistantCloudAuthStrategy.ts"],"mappings":";KAAY;WACD;EACT,kBAAkB,QAAQ;EAC1B,gBAAgB,SAAS;;cAiCd,yCAAyC;;WACpC;UAER;UACA;cAGI,yBAAyB;EAIxB,kBAAkB,QAAQ;EAsBhC,gBAAgB,SAAS;;cAcrB,4CAA4C;;WACvC;cAMJ,gBAAgB,gBAAgB;EAM/B,kBAAkB,QAAQ;EAQhC;;cAkDI,+CAA+C;WAC1C;UAER;UACA;cAEI;EAgDC,kBAAkB,QAAQ;EAIhC,gBAAgB,SAAS"}
@@ -59,6 +59,38 @@ var AssistantCloudAPIKeyAuthStrategy = class {
59
59
  readAuthHeaders() {}
60
60
  };
61
61
  const AUI_REFRESH_TOKEN_NAME = "aui:refresh_token";
62
+ const getLocalStorage = () => {
63
+ if (!("localStorage" in globalThis)) return null;
64
+ try {
65
+ return globalThis.localStorage;
66
+ } catch {
67
+ return null;
68
+ }
69
+ };
70
+ const readRefreshToken = () => {
71
+ const storage = getLocalStorage();
72
+ if (!storage) return void 0;
73
+ try {
74
+ const value = storage.getItem(AUI_REFRESH_TOKEN_NAME);
75
+ return value ? JSON.parse(value) : void 0;
76
+ } catch {
77
+ return;
78
+ }
79
+ };
80
+ const writeRefreshToken = (refreshToken) => {
81
+ const storage = getLocalStorage();
82
+ if (!storage) return;
83
+ try {
84
+ storage.setItem(AUI_REFRESH_TOKEN_NAME, JSON.stringify(refreshToken));
85
+ } catch {}
86
+ };
87
+ const removeRefreshToken = () => {
88
+ const storage = getLocalStorage();
89
+ if (!storage) return;
90
+ try {
91
+ storage.removeItem(AUI_REFRESH_TOKEN_NAME);
92
+ } catch {}
93
+ };
62
94
  var AssistantCloudAnonymousAuthStrategy = class {
63
95
  strategy = "anon";
64
96
  baseUrl;
@@ -67,8 +99,7 @@ var AssistantCloudAnonymousAuthStrategy = class {
67
99
  this.baseUrl = baseUrl;
68
100
  this.jwtStrategy = new AssistantCloudJWTAuthStrategy(async () => {
69
101
  const currentTime = Date.now();
70
- const storedRefreshTokenJson = localStorage.getItem(AUI_REFRESH_TOKEN_NAME);
71
- const storedRefreshToken = storedRefreshTokenJson ? JSON.parse(storedRefreshTokenJson) : void 0;
102
+ const storedRefreshToken = readRefreshToken();
72
103
  if (storedRefreshToken) if (new Date(storedRefreshToken.expires_at).getTime() - currentTime > 30 * 1e3) {
73
104
  const response = await fetch(`${this.baseUrl}/v1/auth/tokens/refresh`, {
74
105
  method: "POST",
@@ -77,15 +108,15 @@ var AssistantCloudAnonymousAuthStrategy = class {
77
108
  });
78
109
  if (response.ok) {
79
110
  const { access_token, refresh_token } = await response.json();
80
- if (refresh_token) localStorage.setItem(AUI_REFRESH_TOKEN_NAME, JSON.stringify(refresh_token));
111
+ if (refresh_token) writeRefreshToken(refresh_token);
81
112
  return access_token;
82
113
  }
83
- } else localStorage.removeItem(AUI_REFRESH_TOKEN_NAME);
114
+ } else removeRefreshToken();
84
115
  const response = await fetch(`${this.baseUrl}/v1/auth/tokens/anonymous`, { method: "POST" });
85
116
  if (!response.ok) return null;
86
117
  const { access_token, refresh_token } = await response.json();
87
118
  if (!access_token || !refresh_token) return null;
88
- localStorage.setItem(AUI_REFRESH_TOKEN_NAME, JSON.stringify(refresh_token));
119
+ writeRefreshToken(refresh_token);
89
120
  return access_token;
90
121
  });
91
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAuthStrategy.js","names":["#authTokenCallback","#apiKey","#userId","#workspaceId"],"sources":["../src/AssistantCloudAuthStrategy.ts"],"sourcesContent":["export 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\nexport class AssistantCloudJWTAuthStrategy implements AssistantCloudAuthStrategy {\n public readonly strategy = \"jwt\";\n\n private cachedToken: string | null = null;\n private tokenExpiry: number | 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 // Fetch a new token via the callback\n const newToken = await this.#authTokenCallback();\n if (!newToken) return false;\n\n this.cachedToken = newToken;\n this.tokenExpiry = getJwtExpiry(newToken);\n\n return { Authorization: `Bearer ${newToken}` };\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\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 storedRefreshTokenJson = localStorage.getItem(\n AUI_REFRESH_TOKEN_NAME,\n );\n const storedRefreshToken = storedRefreshTokenJson\n ? (JSON.parse(storedRefreshTokenJson) as {\n token: string;\n expires_at: string;\n })\n : undefined;\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 = await response.json();\n const { access_token, refresh_token } = data;\n if (refresh_token) {\n localStorage.setItem(\n AUI_REFRESH_TOKEN_NAME,\n JSON.stringify(refresh_token),\n );\n }\n return access_token;\n }\n } else {\n localStorage.removeItem(AUI_REFRESH_TOKEN_NAME);\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 = await response.json();\n const { access_token, refresh_token } = data;\n\n if (!access_token || !refresh_token) return null;\n\n localStorage.setItem(\n AUI_REFRESH_TOKEN_NAME,\n JSON.stringify(refresh_token),\n );\n return access_token;\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":["export 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\nexport class AssistantCloudJWTAuthStrategy implements AssistantCloudAuthStrategy {\n public readonly strategy = \"jwt\";\n\n private cachedToken: string | null = null;\n private tokenExpiry: number | 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 // Fetch a new token via the callback\n const newToken = await this.#authTokenCallback();\n if (!newToken) return false;\n\n this.cachedToken = newToken;\n this.tokenExpiry = getJwtExpiry(newToken);\n\n return { Authorization: `Bearer ${newToken}` };\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 = ():\n | { token: string; expires_at: string }\n | 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: {\n token: string;\n expires_at: string;\n}): 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 = await response.json();\n const { access_token, refresh_token } = data;\n if (refresh_token) {\n writeRefreshToken(refresh_token);\n }\n return access_token;\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 = await response.json();\n const { access_token, refresh_token } = data;\n\n if (!access_token || !refresh_token) return null;\n\n writeRefreshToken(refresh_token);\n return access_token;\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,5 +1,4 @@
1
1
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
-
3
2
  //#region src/AssistantCloudAuthTokens.d.ts
4
3
  type AssistantCloudAuthTokensCreateResponse = {
5
4
  token: string;
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudAuthTokens.d.ts","names":[],"sources":["../src/AssistantCloudAuthTokens.ts"],"mappings":";;;KAEK,sCAAA;EACH,KAAK;AAAA;AAAA,cAGM,wBAAA;EAAA,QACS,KAAA;cAAA,KAAA,EAAO,iBAAA;EAEd,MAAA,IAAU,OAAA,CAAQ,sCAAA;AAAA"}
1
+ {"version":3,"file":"AssistantCloudAuthTokens.d.ts","names":[],"sources":["../src/AssistantCloudAuthTokens.ts"],"mappings":";;KAEK;EACH;;cAGW;UACS;cAAA,OAAO;EAEd,UAAU,QAAQ"}
@@ -1,5 +1,4 @@
1
1
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
-
3
2
  //#region src/AssistantCloudFiles.d.ts
4
3
  type PdfToImagesRequestBody = {
5
4
  file_blob?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudFiles.d.ts","names":[],"sources":["../src/AssistantCloudFiles.ts"],"mappings":";;;KAEK,sBAAA;EACH,SAAA;EACA,QAAQ;AAAA;AAAA,KAGL,mBAAA;EACH,OAAA;EACA,IAAA;EACA,OAAA;AAAA;AAAA,KAGG,qCAAA;EACH,QAAQ;AAAA;AAAA,KAGL,kCAAA;EACH,OAAA;EACA,SAAA;EACA,SAAA;EACA,SAAA;AAAA;AAAA,cAGW,mBAAA;EAAA,QACS,KAAA;cAAA,KAAA,EAAO,iBAAA;EAEd,WAAA,CACX,IAAA,EAAM,sBAAA,GACL,OAAA,CAAQ,mBAAA;EAOE,0BAAA,CACX,IAAA,EAAM,qCAAA,GACL,OAAA,CAAQ,kCAAA;AAAA"}
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;UACS;cAAA,OAAO;EAEd,YACX,MAAM,yBACL,QAAQ;EAOE,2BACX,MAAM,wCACL,QAAQ"}
@@ -1,7 +1,6 @@
1
1
  import { SamplingCallData } from "./instrumentMcpSampling.js";
2
2
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
3
3
  import { AssistantStream } from "assistant-stream";
4
-
5
4
  //#region src/AssistantCloudRuns.d.ts
6
5
  type AssistantCloudRunsStreamBody = {
7
6
  thread_id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudRuns.d.ts","names":[],"sources":["../src/AssistantCloudRuns.ts"],"mappings":";;;;;KAIK,4BAAA;EACH,SAAA;EACA,YAAA;EACA,QAAA;AAAA;AAAA,KAGG,cAAA;EACH,SAAA;EACA,YAAA;EACA,SAAA;EACA,WAAA;EACA,WAAA;EACA,QAAA;EACA,MAAA;EACA,cAAA,GAAiB,gBAAgB;AAAA;AAAA,KAMvB,uBAAA;EACV,SAAA;EACA,MAAA;EACA,WAAA;EACA,UAAA,GAAa,cAAA;EACb,KAAA;IACE,YAAA;IACA,aAAA;IACA,gBAAA;IACA,mBAAA;IACA,UAAA,GAAa,cAAA;IACb,QAAA;IACA,MAAA;EAAA;EAEF,YAAA;EACA,aAAA;EACA,gBAAA;EACA,mBAAA;EACA,QAAA;EACA,aAAA;EACA,WAAA;EACA,WAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,cAGA,kBAAA;EAAA,QACS,KAAA;cAAA,KAAA,EAAO,iBAAA;EAEpB,8BAAA,CAA+B,WAAA;;;;;;;;;;;EAmBzB,MAAA,CACX,IAAA,EAAM,4BAAA,GACL,OAAA,CAAQ,eAAA;EAWE,MAAA,CACX,IAAA,EAAM,uBAAA,GACL,OAAA;IAAU,MAAA;EAAA;AAAA"}
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;UACS;cAAA,OAAO;EAEpB,+BAA+B;;;;;;;;;;;EAmBzB,OACX,MAAM,+BACL,QAAQ;EAWE,OACX,MAAM,0BACL;IAAU"}
@@ -1,6 +1,5 @@
1
1
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
2
  import { ReadonlyJSONObject } from "assistant-stream/utils";
3
-
4
3
  //#region src/AssistantCloudThreadMessages.d.ts
5
4
  type CloudMessage = {
6
5
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreadMessages.d.ts","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"mappings":";;;;KAGY,YAAA;EACV,EAAA;EACA,SAAA;EACA,MAAA;EACA,UAAA,EAAY,IAAA;EACZ,UAAA,EAAY,IAAA;EACZ,MAAA;EACA,OAAA,EAAS,kBAAA;AAAA;AAAA,KAGN,oCAAA;EACH,MAAM;AAAA;AAAA,KAGH,uCAAA;EACH,QAAA,EAAU,YAAY;AAAA;AAAA,KAGnB,qCAAA;EACH,SAAA;EACA,MAAA;EACA,OAAA,EAAS,kBAAkB;AAAA;AAAA,KAGxB,mCAAA;EACH,UAAU;AAAA;AAAA,KAGP,qCAAA;EACH,OAAA,EAAS,kBAAkB;AAAA;AAAA,cAGhB,4BAAA;EAAA,QACS,KAAA;cAAA,KAAA,EAAO,iBAAA;EAEd,IAAA,CACX,QAAA,UACA,KAAA,GAAQ,oCAAA,GACP,OAAA,CAAQ,uCAAA;EAOE,MAAA,CACX,QAAA,UACA,IAAA,EAAM,qCAAA,GACL,OAAA,CAAQ,mCAAA;EAOE,MAAA,CACX,QAAA,UACA,SAAA,UACA,IAAA,EAAM,qCAAA,GACL,OAAA;AAAA"}
1
+ {"version":3,"file":"AssistantCloudThreadMessages.d.ts","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"mappings":";;;KAGY;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;UACS;cAAA,OAAO;EAEd,KACX,kBACA,QAAQ,uCACP,QAAQ;EAOE,OACX,kBACA,MAAM,wCACL,QAAQ;EAOE,OACX,kBACA,mBACA,MAAM,wCACL"}
@@ -1,6 +1,5 @@
1
1
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
2
  import { AssistantCloudThreadMessages } from "./AssistantCloudThreadMessages.js";
3
-
4
3
  //#region src/AssistantCloudThreads.d.ts
5
4
  type AssistantCloudThreadsListQuery = {
6
5
  is_archived?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreads.d.ts","names":[],"sources":["../src/AssistantCloudThreads.ts"],"mappings":";;;;KAGK,8BAAA;EACH,WAAA;EACA,KAAA;EACA,KAAA;AAAA;AAAA,KAGG,WAAA;EACH,KAAA;EACA,eAAA,EAAiB,IAAA;EACjB,QAAA;EACA,WAAA;EACA,EAAA;EACA,UAAA;EACA,UAAA,EAAY,IAAA;EACZ,UAAA,EAAY,IAAA;EACZ,YAAA;EACA,WAAA;AAAA;AAAA,KAGG,iCAAA;EACH,OAAA,EAAS,WAAW;AAAA;AAAA,KAGjB,+BAAA;EACH,KAAA;EACA,eAAA,EAAiB,IAAI;EACrB,QAAA;EACA,WAAA;AAAA;AAAA,KAGG,mCAAA;EACH,SAAS;AAAA;AAAA,KAGN,+BAAA;EACH,KAAA;EACA,eAAA,GAAkB,IAAI;EACtB,QAAA;EACA,WAAA;AAAA;AAAA,cAGW,qBAAA;EAAA,QAGS,KAAA;EAAA,SAFJ,QAAA,EAAU,4BAAA;cAEN,KAAA,EAAO,iBAAA;EAId,IAAA,CACX,KAAA,GAAQ,8BAAA,GACP,OAAA,CAAQ,iCAAA;EAIE,GAAA,CAAI,QAAA,WAAmB,OAAA,CAAQ,WAAA;EAI/B,MAAA,CACX,IAAA,EAAM,+BAAA,GACL,OAAA,CAAQ,mCAAA;EAIE,MAAA,CACX,QAAA,UACA,IAAA,EAAM,+BAAA,GACL,OAAA;EAOU,MAAA,CAAO,QAAA,WAAmB,OAAA;AAAA"}
1
+ {"version":3,"file":"AssistantCloudThreads.d.ts","names":[],"sources":["../src/AssistantCloudThreads.ts"],"mappings":";;;KAGK;EACH;EACA;EACA;;KAGG;EACH;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;UAGS;WAFJ,UAAU;cAEN,OAAO;EAId,KACX,QAAQ,iCACP,QAAQ;EAIE,IAAI,mBAAmB,QAAQ;EAI/B,OACX,MAAM,kCACL,QAAQ;EAIE,OACX,kBACA,MAAM,kCACL;EAOU,OAAO,mBAAmB"}
@@ -1,7 +1,6 @@
1
1
  import { CloudMessage } from "./AssistantCloudThreadMessages.js";
2
2
  import { AssistantCloud } from "./AssistantCloud.js";
3
3
  import { ReadonlyJSONObject } from "assistant-stream/utils";
4
-
5
4
  //#region src/CloudMessagePersistence.d.ts
6
5
  /**
7
6
  * Shared persistence logic for cloud message storage.
@@ -1 +1 @@
1
- {"version":3,"file":"CloudMessagePersistence.d.ts","names":[],"sources":["../src/CloudMessagePersistence.ts"],"mappings":";;;;;;;;AAcA;;;;;;;;cAAa,uBAAA;EAAA,QAGS,KAAA;EAAA,QAFZ,SAAA;cAEY,KAAA,EAAO,cAAA;EAuFiB;;;;;;;;;EA5EtC,MAAA,CACJ,QAAA,UACA,SAAA,UACA,QAAA,iBACA,MAAA,UACA,OAAA,EAAS,kBAAA,GACR,OAAA;EAFD;;;EAkCI,MAAA,CACJ,QAAA,UACA,SAAA,UACA,OAAA,UACA,OAAA,EAAS,kBAAA,GACR,OAAA;EALG;;;EAcN,WAAA,CAAY,SAAA;EAVD;;;;EAkBL,WAAA,CAAY,SAAA,WAAoB,OAAA;EAAhC;;;;;;;;;;EAgBA,IAAA,CAAK,QAAA,UAAkB,MAAA,YAAe,OAAA,CAhBC,YAAA;;;;EA+B7C,KAAA;AAAA"}
1
+ {"version":3,"file":"CloudMessagePersistence.d.ts","names":[],"sources":["../src/CloudMessagePersistence.ts"],"mappings":";;;;;;;;;;;;;;;cAca;UAGS;UAFZ;cAEY,OAAO;;;;;;;;;;EAWrB,OACJ,kBACA,mBACA,yBACA,gBACA,SAAS,qBACR;;;;EAgCG,OACJ,kBACA,mBACA,iBACA,SAAS,qBACR;;;;EASH,YAAY;;;;;EAQN,YAAY,oBAAoB;;;;;;;;;;;EAgBhC,KAAK,kBAAkB,kBAAe,QAhBN;;;;EA+BtC"}
@@ -1,5 +1,4 @@
1
1
  import { ReadonlyJSONObject } from "assistant-stream/utils";
2
-
3
2
  //#region src/FormattedCloudPersistence.d.ts
4
3
  /**
5
4
  * Format adapter shape — structurally identical to the MessageFormatAdapter
@@ -1 +1 @@
1
- {"version":3,"file":"FormattedCloudPersistence.d.ts","names":[],"sources":["../src/FormattedCloudPersistence.ts"],"mappings":";;;;;AAOA;;;KAAY,oBAAA;EACV,MAAA;EACA,MAAA,CAAO,IAAA;IAAQ,QAAA;IAAyB,OAAA,EAAS,QAAA;EAAA,IAAa,cAAA;EAC9D,MAAA,CAAO,MAAA;IACL,EAAA;IACA,SAAA;IACA,MAAA;IACA,OAAA,EAAS,cAAA;EAAA;IACL,QAAA;IAAyB,OAAA,EAAS,QAAA;EAAA;EACxC,KAAA,CAAM,OAAA,EAAS,QAAA;AAAA;;;;;;;;;;;cAaJ,0BAAA,6BACX,WAAA;EACE,MAAA,GACE,QAAA,UACA,SAAA,UACA,QAAA,iBACA,MAAA,UACA,OAAA,EAAS,kBAAA,KACN,OAAA;EACL,IAAA,GAAO,QAAA,UAAkB,MAAA,cAAoB,OAAA;EAC7C,WAAA,GAAc,SAAA;EACd,MAAA,IACE,QAAA,UACA,SAAA,UACA,MAAA,UACA,OAAA,EAAS,kBAAA,KACN,OAAA;AAAA,GAEP,OAAA,EAAS,oBAAA,CAAqB,QAAA,EAAU,cAAA;6BAGtB,IAAA;IACR,QAAA;IAAyB,OAAA,EAAS,QAAA;EAAA,MACzC,OAAA;8BAamB,IAAA;IACR,QAAA;IAAyB,OAAA,EAAS,QAAA;EAAA,GAAU,SAAA,aAEnD,OAAA;8BAUsB,OAAA"}
1
+ {"version":3,"file":"FormattedCloudPersistence.d.ts","names":[],"sources":["../src/FormattedCloudPersistence.ts"],"mappings":";;;;;;;KAOY,qBAAqB,UAAU;EACzC;EACA,OAAO;IAAQ;IAAyB,SAAS;MAAa;EAC9D,OAAO;IACL;IACA;IACA;IACA,SAAS;;IACL;IAAyB,SAAS;;EACxC,MAAM,SAAS;;;;;;;;;;;;cAaJ,6BAA8B,UAAU,gBACnD;EACE,SACE,kBACA,mBACA,yBACA,gBACA,SAAS,uBACN;EACL,OAAO,kBAAkB,oBAAoB;EAC7C,cAAc;EACd,UACE,kBACA,mBACA,gBACA,SAAS,uBACN;GAEP,SAAS,qBAAqB,UAAU;6BAGtB;IACR;IAAyB,SAAS;QACzC;8BAamB;IACR;IAAyB,SAAS;KAAU,sBAEnD;8BAUsB"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { McpSamplingHandler, SamplingCallData, createSamplingCollector, wrapSamplingHandler } from "./instrumentMcpSampling.js";
2
2
  import { AssistantCloudRunReport } from "./AssistantCloudRuns.js";
3
- import { AssistantCloudTelemetryConfig } from "./AssistantCloudAPI.js";
3
+ import { AssistantCloudTelemetryConfig, CloudAPIError } from "./AssistantCloudAPI.js";
4
4
  import { CloudMessage } from "./AssistantCloudThreadMessages.js";
5
5
  import { AssistantCloud } from "./AssistantCloud.js";
6
6
  import { CloudMessagePersistence } from "./CloudMessagePersistence.js";
7
7
  import { MessageFormatAdapter, createFormattedPersistence } from "./FormattedCloudPersistence.js";
8
- export { AssistantCloud, type AssistantCloudRunReport, type AssistantCloudTelemetryConfig, type CloudMessage, CloudMessagePersistence, type McpSamplingHandler, type MessageFormatAdapter, type SamplingCallData, createFormattedPersistence, createSamplingCollector, wrapSamplingHandler };
8
+ export { AssistantCloud, type AssistantCloudRunReport, type AssistantCloudTelemetryConfig, CloudAPIError, type CloudMessage, CloudMessagePersistence, type McpSamplingHandler, type MessageFormatAdapter, type SamplingCallData, createFormattedPersistence, createSamplingCollector, wrapSamplingHandler };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
+ import { CloudAPIError } from "./AssistantCloudAPI.js";
1
2
  import { AssistantCloud } from "./AssistantCloud.js";
2
3
  import { CloudMessagePersistence } from "./CloudMessagePersistence.js";
3
4
  import { createFormattedPersistence } from "./FormattedCloudPersistence.js";
4
5
  import { createSamplingCollector, wrapSamplingHandler } from "./instrumentMcpSampling.js";
5
- export { AssistantCloud, CloudMessagePersistence, createFormattedPersistence, createSamplingCollector, wrapSamplingHandler };
6
+ export { AssistantCloud, CloudAPIError, CloudMessagePersistence, createFormattedPersistence, createSamplingCollector, wrapSamplingHandler };
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentMcpSampling.d.ts","names":[],"sources":["../src/instrumentMcpSampling.ts"],"mappings":";;AAQA;;;;;;KAAY,gBAAA;EACV,QAAA;EACA,YAAA;EACA,aAAA;EACA,gBAAA;EACA,mBAAA;EACA,WAAA;AAAA;AAAA,KAGU,kBAAA,IACV,OAAA,EAAS,kBAAA,KACN,OAAA,CAAQ,mBAAA;AAAA,KAED,kBAAA;EACV,MAAA;EACA,MAAA;IACE,QAAA;IACA,gBAAA;MAAqB,KAAA;QAAU,IAAA;MAAA;IAAA;IAC/B,SAAA;IAAA,CACC,GAAA;EAAA;AAAA;AAAA,KAIO,mBAAA;EACV,KAAA;EACA,OAAA;EACA,KAAA;IACE,WAAA;IACA,YAAA;IACA,YAAA;IACA,gBAAA;IACA,eAAA;IACA,iBAAA;EAAA;EAAA,CAED,GAAA;AAAA;;;;;;;;;;;;;;;AAAW;AAqBd;;;iBAAgB,mBAAA,CACd,OAAA,EAAS,kBAAA,EACT,cAAA,GAAiB,IAAA,EAAM,gBAAA,YACtB,kBAAA;;;;;;;;;;;;AAAkB;iBA6CL,uBAAA;kBAGI,gBAAA;kBAAA,gBAAA"}
1
+ {"version":3,"file":"instrumentMcpSampling.d.ts","names":[],"sources":["../src/instrumentMcpSampling.ts"],"mappings":";;;;;;;;KAQY;EACV;EACA;EACA;EACA;EACA;EACA;;KAGU,sBACV,SAAS,uBACN,QAAQ;KAED;EACV;EACA;IACE;IACA;MAAqB;QAAU;;;IAC/B;KACC;;;KAIO;EACV;EACA;EACA;IACE;IACA;IACA;IACA;IACA;IACA;;GAED;;;;;;;;;;;;;;;;;;;;iBAqBa,oBACd,SAAS,oBACT,iBAAiB,MAAM,4BACtB;;;;;;;;;;;;;iBA6Ca;kBAGI;kBAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assistant-cloud",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "description": "Cloud integration for assistant-ui",
5
5
  "keywords": [
6
6
  "assistant",
@@ -27,12 +27,12 @@
27
27
  ],
28
28
  "sideEffects": false,
29
29
  "dependencies": {
30
- "assistant-stream": "^0.3.23"
30
+ "assistant-stream": "^0.3.26"
31
31
  },
32
32
  "devDependencies": {
33
- "@types/node": "^25.9.3",
34
- "vitest": "^4.1.8",
35
- "@assistant-ui/x-buildutils": "0.0.14"
33
+ "@types/node": "^26.1.1",
34
+ "vitest": "^4.1.10",
35
+ "@assistant-ui/x-buildutils": "0.0.18"
36
36
  },
37
37
  "publishConfig": {
38
38
  "access": "public",
@@ -48,10 +48,13 @@ export type AssistantCloudConfig = (
48
48
  telemetry?: boolean | AssistantCloudTelemetryConfig;
49
49
  };
50
50
 
51
- class CloudAPIError extends Error {
52
- constructor(message: string) {
51
+ export class CloudAPIError extends Error {
52
+ constructor(
53
+ message: string,
54
+ public readonly status: number,
55
+ ) {
53
56
  super(message);
54
- this.name = "APIError";
57
+ this.name = "CloudAPIError";
55
58
  }
56
59
  }
57
60
 
@@ -90,7 +93,7 @@ export class AssistantCloudAPI {
90
93
  }
91
94
 
92
95
  public async initializeAuth() {
93
- return !!this._auth.getAuthHeaders();
96
+ return !!(await this._auth.getAuthHeaders());
94
97
  }
95
98
 
96
99
  public async makeRawRequest(
@@ -133,11 +136,12 @@ export class AssistantCloudAPI {
133
136
  const text = await response.text();
134
137
  try {
135
138
  const body = JSON.parse(text);
136
- throw new CloudAPIError(body.message);
139
+ throw new CloudAPIError(body.message, response.status);
137
140
  } catch (error) {
138
141
  if (error instanceof CloudAPIError) throw error;
139
- throw new Error(
142
+ throw new CloudAPIError(
140
143
  `Request failed with status ${response.status}, ${text}`,
144
+ response.status,
141
145
  );
142
146
  }
143
147
  }
@@ -147,6 +151,15 @@ export class AssistantCloudAPI {
147
151
 
148
152
  public async makeRequest(endpoint: string, options: MakeRequestOptions = {}) {
149
153
  const response = await this.makeRawRequest(endpoint, options);
150
- return response.json();
154
+ if (
155
+ response.status === 204 ||
156
+ response.headers.get("content-length") === "0"
157
+ )
158
+ return undefined;
159
+
160
+ const text = await response.text();
161
+ if (text.trim() === "") return undefined;
162
+
163
+ return JSON.parse(text);
151
164
  }
152
165
  }
@@ -109,6 +109,49 @@ export class AssistantCloudAPIKeyAuthStrategy implements AssistantCloudAuthStrat
109
109
 
110
110
  const AUI_REFRESH_TOKEN_NAME = "aui:refresh_token";
111
111
 
112
+ const getLocalStorage = (): Storage | null => {
113
+ if (!("localStorage" in globalThis)) return null;
114
+ try {
115
+ return (globalThis as { localStorage: Storage }).localStorage;
116
+ } catch {
117
+ return null;
118
+ }
119
+ };
120
+
121
+ const readRefreshToken = ():
122
+ | { token: string; expires_at: string }
123
+ | undefined => {
124
+ const storage = getLocalStorage();
125
+ if (!storage) return undefined;
126
+ try {
127
+ const value = storage.getItem(AUI_REFRESH_TOKEN_NAME);
128
+ return value
129
+ ? (JSON.parse(value) as { token: string; expires_at: string })
130
+ : undefined;
131
+ } catch {
132
+ return undefined;
133
+ }
134
+ };
135
+
136
+ const writeRefreshToken = (refreshToken: {
137
+ token: string;
138
+ expires_at: string;
139
+ }): void => {
140
+ const storage = getLocalStorage();
141
+ if (!storage) return;
142
+ try {
143
+ storage.setItem(AUI_REFRESH_TOKEN_NAME, JSON.stringify(refreshToken));
144
+ } catch {}
145
+ };
146
+
147
+ const removeRefreshToken = (): void => {
148
+ const storage = getLocalStorage();
149
+ if (!storage) return;
150
+ try {
151
+ storage.removeItem(AUI_REFRESH_TOKEN_NAME);
152
+ } catch {}
153
+ };
154
+
112
155
  export class AssistantCloudAnonymousAuthStrategy implements AssistantCloudAuthStrategy {
113
156
  public readonly strategy = "anon";
114
157
 
@@ -119,15 +162,7 @@ export class AssistantCloudAnonymousAuthStrategy implements AssistantCloudAuthSt
119
162
  this.baseUrl = baseUrl;
120
163
  this.jwtStrategy = new AssistantCloudJWTAuthStrategy(async () => {
121
164
  const currentTime = Date.now();
122
- const storedRefreshTokenJson = localStorage.getItem(
123
- AUI_REFRESH_TOKEN_NAME,
124
- );
125
- const storedRefreshToken = storedRefreshTokenJson
126
- ? (JSON.parse(storedRefreshTokenJson) as {
127
- token: string;
128
- expires_at: string;
129
- })
130
- : undefined;
165
+ const storedRefreshToken = readRefreshToken();
131
166
 
132
167
  if (storedRefreshToken) {
133
168
  const refreshExpiry = new Date(storedRefreshToken.expires_at).getTime();
@@ -145,15 +180,12 @@ export class AssistantCloudAnonymousAuthStrategy implements AssistantCloudAuthSt
145
180
  const data = await response.json();
146
181
  const { access_token, refresh_token } = data;
147
182
  if (refresh_token) {
148
- localStorage.setItem(
149
- AUI_REFRESH_TOKEN_NAME,
150
- JSON.stringify(refresh_token),
151
- );
183
+ writeRefreshToken(refresh_token);
152
184
  }
153
185
  return access_token;
154
186
  }
155
187
  } else {
156
- localStorage.removeItem(AUI_REFRESH_TOKEN_NAME);
188
+ removeRefreshToken();
157
189
  }
158
190
  }
159
191
 
@@ -169,10 +201,7 @@ export class AssistantCloudAnonymousAuthStrategy implements AssistantCloudAuthSt
169
201
 
170
202
  if (!access_token || !refresh_token) return null;
171
203
 
172
- localStorage.setItem(
173
- AUI_REFRESH_TOKEN_NAME,
174
- JSON.stringify(refresh_token),
175
- );
204
+ writeRefreshToken(refresh_token);
176
205
  return access_token;
177
206
  });
178
207
  }
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export type { CloudMessage } from "./AssistantCloudThreadMessages";
2
2
  export type { AssistantCloudTelemetryConfig } from "./AssistantCloudAPI";
3
+ export { CloudAPIError } from "./AssistantCloudAPI";
3
4
  export type { AssistantCloudRunReport } from "./AssistantCloudRuns";
4
5
  export { AssistantCloud } from "./AssistantCloud";
5
6
  export { CloudMessagePersistence } from "./CloudMessagePersistence";
@@ -1,5 +1,5 @@
1
1
  import { beforeEach, describe, expect, it, vi } from "vitest";
2
- import { AssistantCloudAPI } from "../AssistantCloudAPI";
2
+ import { AssistantCloudAPI, CloudAPIError } from "../AssistantCloudAPI";
3
3
 
4
4
  describe("AssistantCloudAPI", () => {
5
5
  beforeEach(() => {
@@ -105,6 +105,15 @@ describe("AssistantCloudAPI", () => {
105
105
  expect(fetchMock).not.toHaveBeenCalled();
106
106
  });
107
107
 
108
+ it("returns false from initializeAuth when auth token callback returns null", async () => {
109
+ const api = new AssistantCloudAPI({
110
+ baseUrl: "https://test.example.com",
111
+ authToken: async () => null,
112
+ });
113
+
114
+ await expect(api.initializeAuth()).resolves.toBe(false);
115
+ });
116
+
108
117
  it("throws APIError with parsed message for JSON error responses", async () => {
109
118
  const fetchMock = vi.fn().mockResolvedValue({
110
119
  ok: false,
@@ -125,9 +134,10 @@ describe("AssistantCloudAPI", () => {
125
134
  });
126
135
 
127
136
  const error = await api.makeRawRequest("/threads").catch((e) => e);
128
- expect(error).toBeInstanceOf(Error);
129
- expect(error.name).toBe("APIError");
137
+ expect(error).toBeInstanceOf(CloudAPIError);
138
+ expect(error.name).toBe("CloudAPIError");
130
139
  expect(error.message).toBe("invalid request payload");
140
+ expect(error.status).toBe(400);
131
141
  });
132
142
 
133
143
  it("throws generic error with status for non-JSON error responses", async () => {
@@ -145,9 +155,10 @@ describe("AssistantCloudAPI", () => {
145
155
  workspaceId: "w-1",
146
156
  });
147
157
 
148
- await expect(api.makeRawRequest("/threads")).rejects.toThrow(
149
- "Request failed with status 502, Bad Gateway",
150
- );
158
+ const error = await api.makeRawRequest("/threads").catch((e) => e);
159
+ expect(error).toBeInstanceOf(CloudAPIError);
160
+ expect(error.message).toBe("Request failed with status 502, Bad Gateway");
161
+ expect(error.status).toBe(502);
151
162
  });
152
163
 
153
164
  it("makeRequest returns parsed JSON from a successful response", async () => {
@@ -155,7 +166,7 @@ describe("AssistantCloudAPI", () => {
155
166
  const fetchMock = vi.fn().mockResolvedValue({
156
167
  ok: true,
157
168
  headers: new Headers(),
158
- json: vi.fn().mockResolvedValue(responseData),
169
+ text: vi.fn().mockResolvedValue(JSON.stringify(responseData)),
159
170
  });
160
171
  vi.stubGlobal("fetch", fetchMock);
161
172
 
@@ -168,4 +179,62 @@ describe("AssistantCloudAPI", () => {
168
179
  const result = await api.makeRequest("/threads");
169
180
  expect(result).toEqual(responseData);
170
181
  });
182
+
183
+ it("makeRequest returns undefined from a successful empty response", async () => {
184
+ const fetchMock = vi.fn().mockResolvedValue({
185
+ ok: true,
186
+ status: 204,
187
+ headers: new Headers(),
188
+ text: vi.fn().mockResolvedValue(""),
189
+ });
190
+ vi.stubGlobal("fetch", fetchMock);
191
+
192
+ const api = new AssistantCloudAPI({
193
+ apiKey: "test-key",
194
+ userId: "u-1",
195
+ workspaceId: "w-1",
196
+ });
197
+
198
+ await expect(
199
+ api.makeRequest("/threads/t-1", { method: "DELETE" }),
200
+ ).resolves.toBeUndefined();
201
+ });
202
+
203
+ it("makeRequest returns undefined when content-length is zero", async () => {
204
+ const text = vi.fn().mockResolvedValue("");
205
+ const fetchMock = vi.fn().mockResolvedValue({
206
+ ok: true,
207
+ status: 200,
208
+ headers: new Headers({ "content-length": "0" }),
209
+ text,
210
+ });
211
+ vi.stubGlobal("fetch", fetchMock);
212
+
213
+ const api = new AssistantCloudAPI({
214
+ apiKey: "test-key",
215
+ userId: "u-1",
216
+ workspaceId: "w-1",
217
+ });
218
+
219
+ await expect(api.makeRequest("/threads/t-1")).resolves.toBeUndefined();
220
+ expect(text).not.toHaveBeenCalled();
221
+ });
222
+
223
+ it("makeRequest returns undefined from a whitespace-only success body", async () => {
224
+ const fetchMock = vi.fn().mockResolvedValue({
225
+ ok: true,
226
+ status: 200,
227
+ headers: new Headers(),
228
+ text: vi.fn().mockResolvedValue(" "),
229
+ });
230
+ vi.stubGlobal("fetch", fetchMock);
231
+
232
+ const api = new AssistantCloudAPI({
233
+ apiKey: "test-key",
234
+ userId: "u-1",
235
+ workspaceId: "w-1",
236
+ });
237
+
238
+ await expect(api.makeRequest("/threads/t-1")).resolves.toBeUndefined();
239
+ });
171
240
  });
@@ -0,0 +1,163 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { AssistantCloudAnonymousAuthStrategy } from "../AssistantCloudAuthStrategy";
3
+
4
+ const baseUrl = "https://test.example.com";
5
+ const accessToken = `${Buffer.from(JSON.stringify({ alg: "none" })).toString("base64url")}.${Buffer.from(JSON.stringify({ exp: 4102444800 })).toString("base64url")}.sig`;
6
+ const refreshToken = { token: "r1", expires_at: "2099-01-01" };
7
+
8
+ let originalLocalStorageDescriptor: PropertyDescriptor | undefined;
9
+
10
+ const installLocalStorage = (storage: Storage): void => {
11
+ Object.defineProperty(globalThis, "localStorage", {
12
+ configurable: true,
13
+ value: storage,
14
+ });
15
+ };
16
+
17
+ const mockAnonymousTokenFetch = () => {
18
+ const fetchMock = vi.fn().mockResolvedValue({
19
+ ok: true,
20
+ json: vi.fn().mockResolvedValue({
21
+ access_token: accessToken,
22
+ refresh_token: refreshToken,
23
+ }),
24
+ });
25
+ vi.stubGlobal("fetch", fetchMock);
26
+ return fetchMock;
27
+ };
28
+
29
+ describe("AssistantCloudAnonymousAuthStrategy", () => {
30
+ beforeEach(() => {
31
+ originalLocalStorageDescriptor = Object.getOwnPropertyDescriptor(
32
+ globalThis,
33
+ "localStorage",
34
+ );
35
+ });
36
+
37
+ afterEach(() => {
38
+ vi.unstubAllGlobals();
39
+ if (originalLocalStorageDescriptor) {
40
+ Object.defineProperty(
41
+ globalThis,
42
+ "localStorage",
43
+ originalLocalStorageDescriptor,
44
+ );
45
+ } else {
46
+ delete (globalThis as { localStorage?: Storage }).localStorage;
47
+ }
48
+ });
49
+
50
+ it("persists the refresh token and returns the anonymous access token", async () => {
51
+ const values = new Map<string, string>();
52
+ installLocalStorage({
53
+ getItem: (key) => values.get(key) ?? null,
54
+ setItem: (key, value) => {
55
+ values.set(key, value);
56
+ },
57
+ removeItem: (key) => {
58
+ values.delete(key);
59
+ },
60
+ } as Storage);
61
+ const fetchMock = mockAnonymousTokenFetch();
62
+
63
+ const strategy = new AssistantCloudAnonymousAuthStrategy(baseUrl);
64
+
65
+ await expect(strategy.getAuthHeaders()).resolves.toEqual({
66
+ Authorization: `Bearer ${accessToken}`,
67
+ });
68
+ expect(values.get("aui:refresh_token")).toBe(JSON.stringify(refreshToken));
69
+ expect(fetchMock).toHaveBeenCalledWith(
70
+ `${baseUrl}/v1/auth/tokens/anonymous`,
71
+ { method: "POST" },
72
+ );
73
+ });
74
+
75
+ it("returns an anonymous access token without localStorage", async () => {
76
+ delete (globalThis as { localStorage?: Storage }).localStorage;
77
+ mockAnonymousTokenFetch();
78
+
79
+ const strategy = new AssistantCloudAnonymousAuthStrategy(baseUrl);
80
+
81
+ await expect(strategy.getAuthHeaders()).resolves.toEqual({
82
+ Authorization: `Bearer ${accessToken}`,
83
+ });
84
+ });
85
+
86
+ it("returns an anonymous access token when localStorage access is blocked", async () => {
87
+ Object.defineProperty(globalThis, "localStorage", {
88
+ configurable: true,
89
+ get() {
90
+ throw new DOMException("blocked", "SecurityError");
91
+ },
92
+ });
93
+ mockAnonymousTokenFetch();
94
+
95
+ const strategy = new AssistantCloudAnonymousAuthStrategy(baseUrl);
96
+
97
+ await expect(strategy.getAuthHeaders()).resolves.toEqual({
98
+ Authorization: `Bearer ${accessToken}`,
99
+ });
100
+ });
101
+
102
+ it("returns an anonymous access token when storage methods throw", async () => {
103
+ const getItem = vi
104
+ .fn<(key: string) => string | null>()
105
+ .mockReturnValueOnce(JSON.stringify(refreshToken))
106
+ .mockImplementation(() => {
107
+ throw new DOMException("blocked", "SecurityError");
108
+ });
109
+ const setItem = vi.fn(() => {
110
+ throw new DOMException("blocked", "SecurityError");
111
+ });
112
+ const removeItem = vi.fn(() => {
113
+ throw new DOMException("blocked", "SecurityError");
114
+ });
115
+ installLocalStorage({ getItem, setItem, removeItem } as Storage);
116
+ mockAnonymousTokenFetch();
117
+
118
+ const originalDate = globalThis.Date;
119
+ const fixedDate = (originalDate as unknown as () => Date)();
120
+ const fixedTime = originalDate.now();
121
+ globalThis.Date = Object.assign(
122
+ function Date() {
123
+ return fixedDate;
124
+ },
125
+ { now: () => fixedTime },
126
+ ) as unknown as DateConstructor;
127
+
128
+ try {
129
+ await expect(
130
+ new AssistantCloudAnonymousAuthStrategy(baseUrl).getAuthHeaders(),
131
+ ).resolves.toEqual({ Authorization: `Bearer ${accessToken}` });
132
+ await expect(
133
+ new AssistantCloudAnonymousAuthStrategy(baseUrl).getAuthHeaders(),
134
+ ).resolves.toEqual({ Authorization: `Bearer ${accessToken}` });
135
+ } finally {
136
+ globalThis.Date = originalDate;
137
+ }
138
+ expect(getItem).toHaveBeenCalledTimes(2);
139
+ expect(setItem).toHaveBeenCalledTimes(2);
140
+ expect(removeItem).toHaveBeenCalledTimes(1);
141
+ });
142
+
143
+ it("treats corrupted refresh token JSON as absent", async () => {
144
+ const values = new Map([["aui:refresh_token", "not-json{"]]);
145
+ installLocalStorage({
146
+ getItem: (key) => values.get(key) ?? null,
147
+ setItem: (key, value) => {
148
+ values.set(key, value);
149
+ },
150
+ removeItem: (key) => {
151
+ values.delete(key);
152
+ },
153
+ } as Storage);
154
+ mockAnonymousTokenFetch();
155
+
156
+ const strategy = new AssistantCloudAnonymousAuthStrategy(baseUrl);
157
+
158
+ await expect(strategy.getAuthHeaders()).resolves.toEqual({
159
+ Authorization: `Bearer ${accessToken}`,
160
+ });
161
+ expect(values.get("aui:refresh_token")).toBe(JSON.stringify(refreshToken));
162
+ });
163
+ });