assistant-cloud 0.2.1 → 0.2.2

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 (63) hide show
  1. package/README.md +23 -7
  2. package/dist/AssistantCloud.d.ts +1 -2
  3. package/dist/AssistantCloud.d.ts.map +1 -1
  4. package/dist/AssistantCloudAPI.d.ts +5 -6
  5. package/dist/AssistantCloudAPI.d.ts.map +1 -1
  6. package/dist/AssistantCloudAuthStrategy.d.ts +6 -7
  7. package/dist/AssistantCloudAuthStrategy.d.ts.map +1 -1
  8. package/dist/AssistantCloudAuthTokens.d.ts +1 -2
  9. package/dist/AssistantCloudAuthTokens.d.ts.map +1 -1
  10. package/dist/AssistantCloudEvents.d.ts +3 -4
  11. package/dist/AssistantCloudEvents.d.ts.map +1 -1
  12. package/dist/AssistantCloudEvents.js +1 -1
  13. package/dist/AssistantCloudEvents.js.map +1 -1
  14. package/dist/AssistantCloudFiles.d.ts +2 -3
  15. package/dist/AssistantCloudFiles.d.ts.map +1 -1
  16. package/dist/AssistantCloudProjectThreadMessages.d.ts +1 -2
  17. package/dist/AssistantCloudProjectThreadMessages.d.ts.map +1 -1
  18. package/dist/AssistantCloudProjectThreads.d.ts +1 -2
  19. package/dist/AssistantCloudProjectThreads.d.ts.map +1 -1
  20. package/dist/AssistantCloudProjects.d.ts +1 -2
  21. package/dist/AssistantCloudProjects.d.ts.map +1 -1
  22. package/dist/AssistantCloudRuns.d.ts +2 -3
  23. package/dist/AssistantCloudRuns.d.ts.map +1 -1
  24. package/dist/AssistantCloudScores.d.ts +3 -4
  25. package/dist/AssistantCloudScores.d.ts.map +1 -1
  26. package/dist/AssistantCloudThreadMessages.d.ts +7 -6
  27. package/dist/AssistantCloudThreadMessages.d.ts.map +1 -1
  28. package/dist/AssistantCloudThreadMessages.js +7 -2
  29. package/dist/AssistantCloudThreadMessages.js.map +1 -1
  30. package/dist/AssistantCloudThreads.d.ts +3 -4
  31. package/dist/AssistantCloudThreads.d.ts.map +1 -1
  32. package/dist/CloudEngagementReporter.d.ts +3 -4
  33. package/dist/CloudEngagementReporter.d.ts.map +1 -1
  34. package/dist/CloudMessagePersistence.d.ts +1 -2
  35. package/dist/CloudMessagePersistence.d.ts.map +1 -1
  36. package/dist/CloudRunReporter.d.ts +4 -5
  37. package/dist/CloudRunReporter.d.ts.map +1 -1
  38. package/dist/CloudRunReporter.js +13 -4
  39. package/dist/CloudRunReporter.js.map +1 -1
  40. package/dist/FormattedCloudPersistence.d.ts +2 -3
  41. package/dist/FormattedCloudPersistence.d.ts.map +1 -1
  42. package/dist/ai-sdk/index.d.ts +4 -5
  43. package/dist/ai-sdk/index.d.ts.map +1 -1
  44. package/dist/cloudResponse.d.ts +12 -13
  45. package/dist/cloudResponse.d.ts.map +1 -1
  46. package/dist/generateThreadTitle.d.ts +1 -2
  47. package/dist/generateThreadTitle.d.ts.map +1 -1
  48. package/dist/instrumentMcpSampling.d.ts +6 -7
  49. package/dist/instrumentMcpSampling.d.ts.map +1 -1
  50. package/dist/runTelemetry.d.ts +15 -16
  51. package/dist/runTelemetry.d.ts.map +1 -1
  52. package/dist/telemetry/index.d.ts +8 -9
  53. package/dist/telemetry/index.d.ts.map +1 -1
  54. package/dist/version.d.ts +1 -2
  55. package/dist/version.d.ts.map +1 -1
  56. package/dist/version.js +1 -1
  57. package/package.json +10 -9
  58. package/src/AssistantCloudEvents.test.ts +41 -0
  59. package/src/AssistantCloudEvents.ts +1 -0
  60. package/src/AssistantCloudThreadMessages.test.ts +53 -2
  61. package/src/AssistantCloudThreadMessages.ts +13 -1
  62. package/src/CloudRunReporter.ts +16 -4
  63. package/src/tests/CloudRunReporter.test.ts +35 -0
@@ -1 +1 @@
1
- {"version":3,"file":"CloudMessagePersistence.d.ts","names":[],"sources":["../src/CloudMessagePersistence.ts"],"mappings":";;;;;;;;;cAWa;UACH;UACA;EAEI,YAAA,OAAO;EACP,YAAA,gBAAgB;;;;;;;;;;EActB,OACJ,kBACA,mBACA,yBACA,gBACA,SAAS,qBACR;;;;EAsCG,OACJ,kBACA,mBACA,iBACA,SAAS,qBACR;;;;EAeH,YAAY;;;;;EAQN,YAAY,oBAAoB;EAMtC,oBAAoB;;;;;;;;;;;;;;;;EAoBd,KAAK,kBAAkB,kBAAe,QAAA;;;;;;;EAmD5C"}
1
+ {"version":3,"file":"CloudMessagePersistence.d.ts","names":[],"sources":["../src/CloudMessagePersistence.ts"],"mappings":";;;;;;;;;qBAWa;UACH;UACA;EAEI,YAAA,OAAO;EACP,YAAA,gBAAgB;;;;;;;;;;EActB,OACJ,kBACA,mBACA,yBACA,gBACA,SAAS,qBACR;;;;EAsCG,OACJ,kBACA,mBACA,iBACA,SAAS,qBACR;;;;EAeH,YAAY;;;;;EAQN,YAAY,oBAAoB;EAMtC,oBAAoB;;;;;;;;;;;;;;;;EAoBd,KAAK,kBAAkB,kBAAe,QAAA;;;;;;;EAmD5C"}
@@ -1,20 +1,19 @@
1
1
  import { RunReportInit } from "./runTelemetry.js";
2
2
  import { AssistantCloud } from "./AssistantCloud.js";
3
3
  //#region src/CloudRunReporter.d.ts
4
- type CloudRunReportInit = Omit<RunReportInit, "telemetry">;
4
+ export type CloudRunReportInit = Omit<RunReportInit, "telemetry">;
5
5
  /**
6
6
  * Sends run reports the way every client integration has to: nothing while
7
7
  * telemetry is off, the cloud's environment, release and tags on every report,
8
8
  * the `beforeReport` hook applied last, and a failed send that never surfaces.
9
- * A report given a key is sent once per key, so an integration that observes
10
- * the same finished run twice reports it once.
9
+ * A keyed report is deduplicated while in flight and after an attempt. A
10
+ * rate-limited attempt releases the key so a later observation can try again.
11
11
  */
12
- declare class CloudRunReporter {
12
+ export declare class CloudRunReporter {
13
13
  private readonly reported;
14
14
  private readonly getCloud;
15
15
  constructor(cloud: AssistantCloud | (() => AssistantCloud));
16
16
  report(init: CloudRunReportInit, key?: string): Promise<void>;
17
17
  }
18
18
  //#endregion
19
- export { CloudRunReportInit, CloudRunReporter };
20
19
  //# sourceMappingURL=CloudRunReporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CloudRunReporter.d.ts","names":[],"sources":["../src/CloudRunReporter.ts"],"mappings":";;;KAGY,qBAAqB,KAAK;;;;;;;;cASzB;mBACM;mBACA;EAEL,YAAA,OAAO,wBAAwB;EAI9B,OAAO,MAAM,oBAAoB,eAAe"}
1
+ {"version":3,"file":"CloudRunReporter.d.ts","names":[],"sources":["../src/CloudRunReporter.ts"],"mappings":";;;YAIY,qBAAqB,KAAK;;;;;;;;qBASzB;mBACM;mBACA;EAEL,YAAA,OAAO,wBAAwB;EAI9B,OAAO,MAAM,oBAAoB,eAAe"}
@@ -1,11 +1,12 @@
1
+ import { CloudAPIError } from "./AssistantCloudAPI.js";
1
2
  import { createRunReport } from "./runTelemetry.js";
2
3
  //#region src/CloudRunReporter.ts
3
4
  /**
4
5
  * Sends run reports the way every client integration has to: nothing while
5
6
  * telemetry is off, the cloud's environment, release and tags on every report,
6
7
  * the `beforeReport` hook applied last, and a failed send that never surfaces.
7
- * A report given a key is sent once per key, so an integration that observes
8
- * the same finished run twice reports it once.
8
+ * A keyed report is deduplicated while in flight and after an attempt. A
9
+ * rate-limited attempt releases the key so a later observation can try again.
9
10
  */
10
11
  var CloudRunReporter = class {
11
12
  reported = /* @__PURE__ */ new Set();
@@ -14,6 +15,7 @@ var CloudRunReporter = class {
14
15
  this.getCloud = typeof cloud === "function" ? cloud : () => cloud;
15
16
  }
16
17
  async report(init, key) {
18
+ let claimedKey;
17
19
  try {
18
20
  const cloud = this.getCloud();
19
21
  if (!cloud.telemetry.enabled) return;
@@ -25,13 +27,20 @@ var CloudRunReporter = class {
25
27
  const { beforeReport } = cloud.telemetry;
26
28
  const report = beforeReport ? beforeReport(initial) : initial;
27
29
  if (!report) return;
28
- if (key !== void 0) this.reported.add(key);
30
+ if (key !== void 0) {
31
+ this.reported.add(key);
32
+ claimedKey = key;
33
+ }
29
34
  await cloud.runs.report(report);
30
- } catch {
35
+ } catch (error) {
36
+ if (claimedKey !== void 0 && isRetryableReportError(error)) this.reported.delete(claimedKey);
31
37
  return;
32
38
  }
33
39
  }
34
40
  };
41
+ const isRetryableReportError = (error) => {
42
+ return error instanceof CloudAPIError && error.status === 429;
43
+ };
35
44
  //#endregion
36
45
  export { CloudRunReporter };
37
46
 
@@ -1 +1 @@
1
- {"version":3,"file":"CloudRunReporter.js","names":[],"sources":["../src/CloudRunReporter.ts"],"sourcesContent":["import type { AssistantCloud } from \"./AssistantCloud\";\nimport { createRunReport, type RunReportInit } from \"./runTelemetry\";\n\nexport type CloudRunReportInit = Omit<RunReportInit, \"telemetry\">;\n\n/**\n * Sends run reports the way every client integration has to: nothing while\n * telemetry is off, the cloud's environment, release and tags on every report,\n * the `beforeReport` hook applied last, and a failed send that never surfaces.\n * A report given a key is sent once per key, so an integration that observes\n * the same finished run twice reports it once.\n */\nexport class CloudRunReporter {\n private readonly reported = new Set<string>();\n private readonly getCloud: () => AssistantCloud;\n\n constructor(cloud: AssistantCloud | (() => AssistantCloud)) {\n this.getCloud = typeof cloud === \"function\" ? cloud : () => cloud;\n }\n\n public async report(init: CloudRunReportInit, key?: string): Promise<void> {\n try {\n const cloud = this.getCloud();\n if (!cloud.telemetry.enabled) return;\n if (key !== undefined && this.reported.has(key)) return;\n\n const initial = createRunReport({ ...init, telemetry: cloud.telemetry });\n const { beforeReport } = cloud.telemetry;\n const report = beforeReport ? beforeReport(initial) : initial;\n if (!report) return;\n\n if (key !== undefined) this.reported.add(key);\n await cloud.runs.report(report);\n } catch {\n return;\n }\n }\n}\n"],"mappings":";;;;;;;;;AAYA,IAAa,mBAAb,MAA8B;CAC5B,2BAA4B,IAAI,IAAY;CAC5C;CAEA,YAAY,OAAgD;EAC1D,KAAK,WAAW,OAAO,UAAU,aAAa,cAAc;CAC9D;CAEA,MAAa,OAAO,MAA0B,KAA6B;EACzE,IAAI;GACF,MAAM,QAAQ,KAAK,SAAS;GAC5B,IAAI,CAAC,MAAM,UAAU,SAAS;GAC9B,IAAI,QAAQ,KAAA,KAAa,KAAK,SAAS,IAAI,GAAG,GAAG;GAEjD,MAAM,UAAU,gBAAgB;IAAE,GAAG;IAAM,WAAW,MAAM;GAAU,CAAC;GACvE,MAAM,EAAE,iBAAiB,MAAM;GAC/B,MAAM,SAAS,eAAe,aAAa,OAAO,IAAI;GACtD,IAAI,CAAC,QAAQ;GAEb,IAAI,QAAQ,KAAA,GAAW,KAAK,SAAS,IAAI,GAAG;GAC5C,MAAM,MAAM,KAAK,OAAO,MAAM;EAChC,QAAQ;GACN;EACF;CACF;AACF"}
1
+ {"version":3,"file":"CloudRunReporter.js","names":[],"sources":["../src/CloudRunReporter.ts"],"sourcesContent":["import type { AssistantCloud } from \"./AssistantCloud\";\nimport { CloudAPIError } from \"./AssistantCloudAPI\";\nimport { createRunReport, type RunReportInit } from \"./runTelemetry\";\n\nexport type CloudRunReportInit = Omit<RunReportInit, \"telemetry\">;\n\n/**\n * Sends run reports the way every client integration has to: nothing while\n * telemetry is off, the cloud's environment, release and tags on every report,\n * the `beforeReport` hook applied last, and a failed send that never surfaces.\n * A keyed report is deduplicated while in flight and after an attempt. A\n * rate-limited attempt releases the key so a later observation can try again.\n */\nexport class CloudRunReporter {\n private readonly reported = new Set<string>();\n private readonly getCloud: () => AssistantCloud;\n\n constructor(cloud: AssistantCloud | (() => AssistantCloud)) {\n this.getCloud = typeof cloud === \"function\" ? cloud : () => cloud;\n }\n\n public async report(init: CloudRunReportInit, key?: string): Promise<void> {\n let claimedKey: string | undefined;\n try {\n const cloud = this.getCloud();\n if (!cloud.telemetry.enabled) return;\n if (key !== undefined && this.reported.has(key)) return;\n\n const initial = createRunReport({ ...init, telemetry: cloud.telemetry });\n const { beforeReport } = cloud.telemetry;\n const report = beforeReport ? beforeReport(initial) : initial;\n if (!report) return;\n\n if (key !== undefined) {\n this.reported.add(key);\n claimedKey = key;\n }\n await cloud.runs.report(report);\n } catch (error) {\n if (claimedKey !== undefined && isRetryableReportError(error)) {\n this.reported.delete(claimedKey);\n }\n return;\n }\n }\n}\n\nconst isRetryableReportError = (error: unknown): boolean => {\n return error instanceof CloudAPIError && error.status === 429;\n};\n"],"mappings":";;;;;;;;;;AAaA,IAAa,mBAAb,MAA8B;CAC5B,2BAA4B,IAAI,IAAY;CAC5C;CAEA,YAAY,OAAgD;EAC1D,KAAK,WAAW,OAAO,UAAU,aAAa,cAAc;CAC9D;CAEA,MAAa,OAAO,MAA0B,KAA6B;EACzE,IAAI;EACJ,IAAI;GACF,MAAM,QAAQ,KAAK,SAAS;GAC5B,IAAI,CAAC,MAAM,UAAU,SAAS;GAC9B,IAAI,QAAQ,KAAA,KAAa,KAAK,SAAS,IAAI,GAAG,GAAG;GAEjD,MAAM,UAAU,gBAAgB;IAAE,GAAG;IAAM,WAAW,MAAM;GAAU,CAAC;GACvE,MAAM,EAAE,iBAAiB,MAAM;GAC/B,MAAM,SAAS,eAAe,aAAa,OAAO,IAAI;GACtD,IAAI,CAAC,QAAQ;GAEb,IAAI,QAAQ,KAAA,GAAW;IACrB,KAAK,SAAS,IAAI,GAAG;IACrB,aAAa;GACf;GACA,MAAM,MAAM,KAAK,OAAO,MAAM;EAChC,SAAS,OAAO;GACd,IAAI,eAAe,KAAA,KAAa,uBAAuB,KAAK,GAC1D,KAAK,SAAS,OAAO,UAAU;GAEjC;EACF;CACF;AACF;AAEA,MAAM,0BAA0B,UAA4B;CAC1D,OAAO,iBAAiB,iBAAiB,MAAM,WAAW;AAC5D"}
@@ -5,7 +5,7 @@ import { ReadonlyJSONObject } from "assistant-stream/utils";
5
5
  * in @assistant-ui/react, but defined here to avoid cross-package type moves.
6
6
  * TypeScript's structural typing ensures these are interchangeable.
7
7
  */
8
- type MessageFormatAdapter<TMessage, TStorageFormat> = {
8
+ export type MessageFormatAdapter<TMessage, TStorageFormat> = {
9
9
  format: string;
10
10
  encode(item: {
11
11
  parentId: string | null;
@@ -27,7 +27,7 @@ type MessageFormatAdapter<TMessage, TStorageFormat> = {
27
27
  * decode. The persistence parameter is typed structurally, so a caller does
28
28
  * not need to import the class.
29
29
  */
30
- declare const createFormattedPersistence: <TMessage, TStorageFormat>(persistence: {
30
+ export declare const createFormattedPersistence: <TMessage, TStorageFormat>(persistence: {
31
31
  append: (threadId: string, messageId: string, parentId: string | null, format: string, content: ReadonlyJSONObject) => Promise<void>;
32
32
  load: (threadId: string, format?: string) => Promise<any[]>;
33
33
  isPersisted: (messageId: string) => boolean;
@@ -50,5 +50,4 @@ declare const createFormattedPersistence: <TMessage, TStorageFormat>(persistence
50
50
  isPersisted: (messageId: string) => boolean;
51
51
  };
52
52
  //#endregion
53
- export { MessageFormatAdapter, createFormattedPersistence };
54
53
  //# sourceMappingURL=FormattedCloudPersistence.d.ts.map
@@ -1 +1 @@
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;;;;;;;cAQJ,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;EAG5B,SAAA,kBAAM;IACR;IAAyB,SAAS;QACzC;EAaa,UAAA,kBAAM;IACR;IAAyB,SAAS;KAAU,sBAEnD;EAUgB,OAAA,qBAAM;;MA1Db;;;;EA0ES,cAAA"}
1
+ {"version":3,"file":"FormattedCloudPersistence.d.ts","names":[],"sources":["../src/FormattedCloudPersistence.ts"],"mappings":";;;;;;;YAOY,qBAAqB,UAAU;EACzC;EACA,OAAO;IAAQ;IAAyB,SAAS;MAAa;EAC9D,OAAO;IACL;IACA;IACA;IACA,SAAS;;IACL;IAAyB,SAAS;;EACxC,MAAM,SAAS;;;;;;;qBAQJ,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;EAG5B,SAAA,kBAAM;IACR;IAAyB,SAAS;QACzC;EAaa,UAAA,kBAAM;IACR;IAAyB,SAAS;KAAU,sBAEnD;EAUgB,OAAA,qBAAM;;MA1Db;;;;EA0ES,cAAA"}
@@ -2,15 +2,15 @@ import { RunMessageTelemetry } from "../runTelemetry.js";
2
2
  import { MessageFormatAdapter } from "../FormattedCloudPersistence.js";
3
3
  import { UIMessage } from "ai";
4
4
  //#region src/ai-sdk/index.d.ts
5
- type AISDKStorageFormat = Omit<UIMessage, "id">;
5
+ export type AISDKStorageFormat = Omit<UIMessage, "id">;
6
6
  /** The stored form of an AI SDK message: the message without its id. */
7
- declare const aiSDKV6FormatAdapter: MessageFormatAdapter<UIMessage, AISDKStorageFormat>;
7
+ export declare const aiSDKV6FormatAdapter: MessageFormatAdapter<UIMessage, AISDKStorageFormat>;
8
8
  /**
9
9
  * A message as an AI SDK integration holds it, or as the cloud stored it under
10
10
  * the ai-sdk/v6 format, which drops the id. Parts are typed by their `type`
11
11
  * alone, so this shape and the telemetry read from it need nothing from `ai`.
12
12
  */
13
- type AISDKMessageLike = {
13
+ export type AISDKMessageLike = {
14
14
  id?: string | undefined;
15
15
  role: string;
16
16
  parts: readonly {
@@ -27,7 +27,6 @@ type AISDKMessageLike = {
27
27
  * produced text or tool calls, as a live finish with reason `tool-calls` does;
28
28
  * an integration that observed the finish event overrides it.
29
29
  */
30
- declare function extractAISDKRunTelemetry(messages: readonly AISDKMessageLike[]): RunMessageTelemetry | null;
30
+ export declare function extractAISDKRunTelemetry(messages: readonly AISDKMessageLike[]): RunMessageTelemetry | null;
31
31
  //#endregion
32
- export { AISDKMessageLike, AISDKStorageFormat, aiSDKV6FormatAdapter, extractAISDKRunTelemetry };
33
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/ai-sdk/index.ts"],"mappings":";;;;KAeY,qBAAqB,KAAK;;cAGzB,sBAAsB,qBACjC,WACA;;;;;;KAgBU;EACV;EACA;EACA;IAAkB;KAAe;;EACjC;;;;;;;;;;iBAgHc,yBACd,mBAAmB,qBAClB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/ai-sdk/index.ts"],"mappings":";;;;YAeY,qBAAqB,KAAK;;qBAGzB,sBAAsB,qBACjC,WACA;;;;;;YAgBU;EACV;EACA;EACA;IAAkB;KAAe;;EACjC;;;;;;;;;;wBAgHc,yBACd,mBAAmB,qBAClB"}
@@ -1,19 +1,18 @@
1
1
  import { ReadonlyJSONObject } from "assistant-stream/utils";
2
2
  //#region src/cloudResponse.d.ts
3
- declare class CloudResponseError extends Error {
3
+ export declare class CloudResponseError extends Error {
4
4
  constructor(message: string);
5
5
  }
6
- declare const readCloudRecord: (value: unknown, field: string) => Record<string, unknown>;
7
- declare const readCloudArray: (value: unknown, field: string) => unknown[];
8
- declare const readCloudString: (value: unknown, field: string) => string;
9
- declare const readCloudNumber: (value: unknown, field: string) => number;
10
- declare const readCloudNullableNumber: (value: unknown, field: string) => number | null;
11
- declare const readCloudEnum: <const T extends readonly string[]>(value: unknown, field: string, allowed: T) => T[number];
12
- declare const readCloudNullableString: (value: unknown, field: string) => string | null;
13
- declare const readCloudBoolean: (value: unknown, field: string) => boolean;
14
- declare const readCloudInteger: (value: unknown, field: string) => number;
15
- declare const readCloudTimestamp: (value: unknown, field: string) => Date;
16
- declare const readCloudJSONObject: (value: unknown, field: string) => ReadonlyJSONObject;
6
+ export declare const readCloudRecord: (value: unknown, field: string) => Record<string, unknown>;
7
+ export declare const readCloudArray: (value: unknown, field: string) => unknown[];
8
+ export declare const readCloudString: (value: unknown, field: string) => string;
9
+ export declare const readCloudNumber: (value: unknown, field: string) => number;
10
+ export declare const readCloudNullableNumber: (value: unknown, field: string) => number | null;
11
+ export declare const readCloudEnum: <const T extends readonly string[]>(value: unknown, field: string, allowed: T) => T[number];
12
+ export declare const readCloudNullableString: (value: unknown, field: string) => string | null;
13
+ export declare const readCloudBoolean: (value: unknown, field: string) => boolean;
14
+ export declare const readCloudInteger: (value: unknown, field: string) => number;
15
+ export declare const readCloudTimestamp: (value: unknown, field: string) => Date;
16
+ export declare const readCloudJSONObject: (value: unknown, field: string) => ReadonlyJSONObject;
17
17
  //#endregion
18
- export { CloudResponseError, readCloudArray, readCloudBoolean, readCloudEnum, readCloudInteger, readCloudJSONObject, readCloudNullableNumber, readCloudNullableString, readCloudNumber, readCloudRecord, readCloudString, readCloudTimestamp };
19
18
  //# sourceMappingURL=cloudResponse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloudResponse.d.ts","names":[],"sources":["../src/cloudResponse.ts"],"mappings":";;cAEa,2BAA2B;EAC1B,YAAA;;cAWD,kBACX,gBACA,kBACC;cAOU,iBAAkB,gBAAgB;cAKlC,kBAAmB,gBAAgB;cAKnC,kBAAmB,gBAAgB;cAOnC,0BACX,gBACA;cAMW,sBAAuB,6BAClC,gBACA,eACA,SAAS,MACR;cAWU,0BACX,gBACA;cAMW,mBAAoB,gBAAgB;cAOpC,mBAAoB,gBAAgB;cAKpC,qBAAsB,gBAAgB,kBAAgB;cActD,sBACX,gBACA,kBACC"}
1
+ {"version":3,"file":"cloudResponse.d.ts","names":[],"sources":["../src/cloudResponse.ts"],"mappings":";;qBAEa,2BAA2B;EAC1B,YAAA;;qBAWD,kBACX,gBACA,kBACC;qBAOU,iBAAkB,gBAAgB;qBAKlC,kBAAmB,gBAAgB;qBAKnC,kBAAmB,gBAAgB;qBAOnC,0BACX,gBACA;qBAMW,sBAAuB,6BAClC,gBACA,eACA,SAAS,MACR;qBAWU,0BACX,gBACA;qBAMW,mBAAoB,gBAAgB;qBAOpC,mBAAoB,gBAAgB;qBAKpC,qBAAsB,gBAAgB,kBAAgB;qBActD,sBACX,gBACA,kBACC"}
@@ -1,6 +1,6 @@
1
1
  import { AssistantCloud } from "./AssistantCloud.js";
2
2
  //#region src/generateThreadTitle.d.ts
3
- declare function generateThreadTitle(cloud: AssistantCloud, options: {
3
+ export declare function generateThreadTitle(cloud: AssistantCloud, options: {
4
4
  threadId: string;
5
5
  messages: readonly {
6
6
  role: string;
@@ -11,5 +11,4 @@ declare function generateThreadTitle(cloud: AssistantCloud, options: {
11
11
  }[];
12
12
  }): Promise<string | null>;
13
13
  //#endregion
14
- export { generateThreadTitle };
15
14
  //# sourceMappingURL=generateThreadTitle.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"generateThreadTitle.d.ts","names":[],"sources":["../src/generateThreadTitle.ts"],"mappings":";;wBAEsB,oBACpB,OAAO,gBACP;EACE;EACA;IACE;IACA;MAAoB;MAAc;;;IAGrC"}
@@ -6,7 +6,7 @@
6
6
  * (sampling/createMessage requests) made during tool execution.
7
7
  * The captured data can be reported as child generation spans.
8
8
  */
9
- type SamplingCallData = {
9
+ export type SamplingCallData = {
10
10
  model_id?: string;
11
11
  input_tokens?: number;
12
12
  output_tokens?: number;
@@ -14,8 +14,8 @@ type SamplingCallData = {
14
14
  cached_input_tokens?: number;
15
15
  duration_ms?: number;
16
16
  };
17
- type McpSamplingHandler = (request: McpSamplingRequest) => Promise<McpSamplingResponse>;
18
- type McpSamplingRequest = {
17
+ export type McpSamplingHandler = (request: McpSamplingRequest) => Promise<McpSamplingResponse>;
18
+ export type McpSamplingRequest = {
19
19
  method: "sampling/createMessage";
20
20
  params: {
21
21
  messages: unknown[];
@@ -28,7 +28,7 @@ type McpSamplingRequest = {
28
28
  [key: string]: unknown;
29
29
  };
30
30
  };
31
- type McpSamplingResponse = {
31
+ export type McpSamplingResponse = {
32
32
  model?: string;
33
33
  content: unknown;
34
34
  usage?: {
@@ -59,7 +59,7 @@ type McpSamplingResponse = {
59
59
  * // After tool execution, `samplingCalls` contains metrics for all nested LLM calls
60
60
  * ```
61
61
  */
62
- declare function wrapSamplingHandler(handler: McpSamplingHandler, onSamplingCall: (data: SamplingCallData) => void): McpSamplingHandler;
62
+ export declare function wrapSamplingHandler(handler: McpSamplingHandler, onSamplingCall: (data: SamplingCallData) => void): McpSamplingHandler;
63
63
  /**
64
64
  * Creates a collector that accumulates sampling call data during tool execution.
65
65
  * Use with `wrapSamplingHandler` to capture all sampling calls for a tool invocation.
@@ -72,11 +72,10 @@ declare function wrapSamplingHandler(handler: McpSamplingHandler, onSamplingCall
72
72
  * const calls = collector.getCalls(); // SamplingCallData[]
73
73
  * ```
74
74
  */
75
- declare function createSamplingCollector(): {
75
+ export declare function createSamplingCollector(): {
76
76
  collect: (data: SamplingCallData) => number;
77
77
  getCalls: () => SamplingCallData[];
78
78
  reset: () => void;
79
79
  };
80
80
  //#endregion
81
- export { McpSamplingHandler, McpSamplingRequest, McpSamplingResponse, SamplingCallData, createSamplingCollector, wrapSamplingHandler };
82
81
  //# sourceMappingURL=instrumentMcpSampling.d.ts.map
@@ -1 +1 @@
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;;;;;;;;;;;;;;;;;;;;iBA8Ba,oBACd,SAAS,oBACT,iBAAiB,MAAM,4BACtB;;;;;;;;;;;;;iBAkDa;EAGI,UAAA,MAAA;kBAAA"}
1
+ {"version":3,"file":"instrumentMcpSampling.d.ts","names":[],"sources":["../src/instrumentMcpSampling.ts"],"mappings":";;;;;;;;YAQY;EACV;EACA;EACA;EACA;EACA;EACA;;YAGU,sBACV,SAAS,uBACN,QAAQ;YAED;EACV;EACA;IACE;IACA;MAAqB;QAAU;;;IAC/B;KACC;;;YAIO;EACV;EACA;EACA;IACE;IACA;IACA;IACA;IACA;IACA;;GAED;;;;;;;;;;;;;;;;;;;;wBA8Ba,oBACd,SAAS,oBACT,iBAAiB,MAAM,4BACtB;;;;;;;;;;;;;wBAkDa;EAGI,UAAA,MAAA;kBAAA"}
@@ -1,7 +1,7 @@
1
1
  import { SamplingCallData } from "./instrumentMcpSampling.js";
2
2
  import { AssistantCloudRunReport } from "./AssistantCloudRuns.js";
3
3
  //#region src/runTelemetry.d.ts
4
- type AssistantCloudRunReportToolCall = {
4
+ export type AssistantCloudRunReportToolCall = {
5
5
  tool_name: string;
6
6
  tool_call_id: string;
7
7
  tool_args?: string;
@@ -11,12 +11,12 @@ type AssistantCloudRunReportToolCall = {
11
11
  end_ms?: number;
12
12
  sampling_calls?: SamplingCallData[];
13
13
  };
14
- type RunReportOutcome = "aborted" | "disconnected" | "length" | "content_filter";
14
+ export type RunReportOutcome = "aborted" | "disconnected" | "length" | "content_filter";
15
15
  /**
16
16
  * Maps a finish event to the report status and outcome. `fallbackStatus`
17
17
  * applies when the event carries neither a finish reason nor a failure flag.
18
18
  */
19
- declare function deriveRunOutcome(input: {
19
+ export declare function deriveRunOutcome(input: {
20
20
  finishReason?: string | undefined;
21
21
  isAbort?: boolean | undefined;
22
22
  isDisconnect?: boolean | undefined;
@@ -29,7 +29,7 @@ declare function deriveRunOutcome(input: {
29
29
  * Reads the message and code the runs endpoint stores for a failed run. The
30
30
  * code is the error's `code` when it has one, else its class name.
31
31
  */
32
- declare function describeRunError(error: unknown): {
32
+ export declare function describeRunError(error: unknown): {
33
33
  error?: string;
34
34
  errorCode?: string;
35
35
  };
@@ -37,8 +37,8 @@ declare function describeRunError(error: unknown): {
37
37
  * Clamps a string to the size the runs endpoint accepts for a single span
38
38
  * field.
39
39
  */
40
- declare function truncateRunTelemetryText(value: string): string;
41
- type RunTelemetryToolCallInit = {
40
+ export declare function truncateRunTelemetryText(value: string): string;
41
+ export type RunTelemetryToolCallInit = {
42
42
  toolName: string;
43
43
  toolCallId: string;
44
44
  args?: unknown;
@@ -55,7 +55,7 @@ type RunTelemetryToolCallInit = {
55
55
  * source has its result summarized, because MCP content blocks carry inline
56
56
  * base64 image and audio payloads that would otherwise dominate the report.
57
57
  */
58
- declare function createRunTelemetryToolCall(init: RunTelemetryToolCallInit): AssistantCloudRunReportToolCall;
58
+ export declare function createRunTelemetryToolCall(init: RunTelemetryToolCallInit): AssistantCloudRunReportToolCall;
59
59
  /**
60
60
  * Resolves the model ID a run reports, in the order an app can supply it: an
61
61
  * explicit `modelId`, the `custom` bag, then the per-step `response.modelId`
@@ -63,14 +63,14 @@ declare function createRunTelemetryToolCall(init: RunTelemetryToolCallInit): Ass
63
63
  * The AI SDK puts no model ID on a UI message part, so message metadata is the
64
64
  * only channel one arrives on.
65
65
  */
66
- declare function extractRunTelemetryModelId(metadata: Record<string, unknown> | undefined): string | undefined;
67
- type RunTelemetryUsage = {
66
+ export declare function extractRunTelemetryModelId(metadata: Record<string, unknown> | undefined): string | undefined;
67
+ export type RunTelemetryUsage = {
68
68
  inputTokens?: number | undefined;
69
69
  outputTokens?: number | undefined;
70
70
  reasoningTokens?: number | undefined;
71
71
  cachedInputTokens?: number | undefined;
72
72
  };
73
- type RunTelemetryUsageInit = RunTelemetryUsage & {
73
+ export type RunTelemetryUsageInit = RunTelemetryUsage & {
74
74
  promptTokens?: number | undefined;
75
75
  completionTokens?: number | undefined;
76
76
  inputTokenDetails?: {
@@ -80,7 +80,7 @@ type RunTelemetryUsageInit = RunTelemetryUsage & {
80
80
  reasoningTokens?: number;
81
81
  };
82
82
  };
83
- type RunReportStepInit = {
83
+ export type RunReportStepInit = {
84
84
  usage?: RunTelemetryUsageInit | undefined;
85
85
  toolCalls?: AssistantCloudRunReportToolCall[] | undefined;
86
86
  startMs?: number | undefined;
@@ -92,7 +92,7 @@ type RunReportStepInit = {
92
92
  * format they were stored: the status the messages imply, the tool calls, the
93
93
  * steps, the text, the usage and the model.
94
94
  */
95
- type RunMessageTelemetry = {
95
+ export type RunMessageTelemetry = {
96
96
  assistantMessageId?: string;
97
97
  status: "completed" | "incomplete";
98
98
  toolCalls?: AssistantCloudRunReportToolCall[];
@@ -103,7 +103,7 @@ type RunMessageTelemetry = {
103
103
  modelId?: string;
104
104
  metadata?: Record<string, unknown>;
105
105
  };
106
- type RunReportInit = {
106
+ export type RunReportInit = {
107
107
  threadId: string;
108
108
  status: AssistantCloudRunReport["status"];
109
109
  outcome?: RunReportOutcome | undefined;
@@ -127,14 +127,13 @@ type RunReportInit = {
127
127
  tags?: readonly string[] | undefined;
128
128
  };
129
129
  };
130
- declare function createRunReport(init: RunReportInit): AssistantCloudRunReport;
130
+ export declare function createRunReport(init: RunReportInit): AssistantCloudRunReport;
131
131
  /**
132
132
  * Resolves the token counts a provider reports under any of the names the AI
133
133
  * SDK has used: the current top-level ones, the legacy prompt/completion pair,
134
134
  * and the v7 token detail objects. Returns undefined when no count is present,
135
135
  * so callers can tell an empty usage object from a zeroed one.
136
136
  */
137
- declare function normalizeRunTelemetryUsage(usage: RunTelemetryUsageInit): RunTelemetryUsage | undefined;
137
+ export declare function normalizeRunTelemetryUsage(usage: RunTelemetryUsageInit): RunTelemetryUsage | undefined;
138
138
  //#endregion
139
- export { AssistantCloudRunReportToolCall, RunMessageTelemetry, RunReportInit, RunReportOutcome, RunReportStepInit, RunTelemetryToolCallInit, RunTelemetryUsage, RunTelemetryUsageInit, createRunReport, createRunTelemetryToolCall, deriveRunOutcome, describeRunError, extractRunTelemetryModelId, normalizeRunTelemetryUsage, truncateRunTelemetryText };
140
139
  //# sourceMappingURL=runTelemetry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runTelemetry.d.ts","names":[],"sources":["../src/runTelemetry.ts"],"mappings":";;;KAOY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;;KAGP;;;;;iBAUI,iBACd;EACE;EACA;EACA;EACA;GAEF;EAEA;EACA,UAAU;;;;;;iBA+BI,iBAAiB;EAC/B;EACA;;;;;;iBA+Bc,yBAAyB;KAwC7B;EACV;EACA;EACA;;;;;EAKA;EACA;EACA;;;;;;;iBAQc,2BACd,MAAM,2BACL;;;;;;;;iBAuBa,2BACd,UAAU;KAmBA;EACV;EACA;EACA;EACA;;KAGU,wBAAwB;EAClC;EACA;EACA;IAAsB;;EACtB;IAAuB;;;KAGb;EACV,QAAQ;EACR,YAAY;EACZ;EACA;EACA;;;;;;;KAQU;EACV;EACA;EACA,YAAY;EACZ,QAAQ;EACR;EACA;EACA,QAAQ;EACR;EACA,WAAW;;KAGD;EACV;EACA,QAAQ;EACR,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR,QAAQ;EACR;EACA,YAAY;EACZ;EACA;EACA;EACA,WAAW;EACX;IACE;IACA;IACA;;;iBAuEY,gBAAgB,MAAM,gBAAgB;;;;;;;iBAiDtC,2BACd,OAAO,wBACN"}
1
+ {"version":3,"file":"runTelemetry.d.ts","names":[],"sources":["../src/runTelemetry.ts"],"mappings":";;;YAOY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;;YAGP;;;;;wBAUI,iBACd;EACE;EACA;EACA;EACA;GAEF;EAEA;EACA,UAAU;;;;;;wBA+BI,iBAAiB;EAC/B;EACA;;;;;;wBA+Bc,yBAAyB;YAwC7B;EACV;EACA;EACA;;;;;EAKA;EACA;EACA;;;;;;;wBAQc,2BACd,MAAM,2BACL;;;;;;;;wBAuBa,2BACd,UAAU;YAmBA;EACV;EACA;EACA;EACA;;YAGU,wBAAwB;EAClC;EACA;EACA;IAAsB;;EACtB;IAAuB;;;YAGb;EACV,QAAQ;EACR,YAAY;EACZ;EACA;EACA;;;;;;;YAQU;EACV;EACA;EACA,YAAY;EACZ,QAAQ;EACR;EACA;EACA,QAAQ;EACR;EACA,WAAW;;YAGD;EACV;EACA,QAAQ;EACR,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR,QAAQ;EACR;EACA,YAAY;EACZ;EACA;EACA;EACA,WAAW;EACX;IACE;IACA;IACA;;;wBAuEY,gBAAgB,MAAM,gBAAgB;;;;;;;wBAiDtC,2BACd,OAAO,wBACN"}
@@ -1,24 +1,24 @@
1
1
  import { ReadableSpan, SpanExporter, SpanProcessor } from "@opentelemetry/sdk-trace-base";
2
2
  //#region src/telemetry/index.d.ts
3
- type AssistantCloudTraceExportOptions = {
3
+ export type AssistantCloudTraceExportOptions = {
4
4
  apiKey: string;
5
5
  baseUrl?: string;
6
6
  headers?: Record<string, string>;
7
7
  };
8
- type AssistantCloudSpanProcessorOptions = {
8
+ export type AssistantCloudSpanProcessorOptions = {
9
9
  filter?: (span: ReadableSpan) => boolean;
10
10
  };
11
- declare function assistantCloudTraceExportOptions({ apiKey, baseUrl, headers }: AssistantCloudTraceExportOptions): {
11
+ export declare function assistantCloudTraceExportOptions({ apiKey, baseUrl, headers }: AssistantCloudTraceExportOptions): {
12
12
  url: string;
13
13
  headers: Record<string, string>;
14
14
  };
15
- declare function createAssistantCloudTraceExporter(options: AssistantCloudTraceExportOptions): SpanExporter;
16
- declare function isAssistantCloudSpan(span: ReadableSpan): boolean;
17
- declare function createAssistantCloudSpanProcessor(exporter: SpanExporter, options?: AssistantCloudSpanProcessorOptions): SpanProcessor;
18
- declare function assistantCloudTraceMetadata(): {
15
+ export declare function createAssistantCloudTraceExporter(options: AssistantCloudTraceExportOptions): SpanExporter;
16
+ export declare function isAssistantCloudSpan(span: ReadableSpan): boolean;
17
+ export declare function createAssistantCloudSpanProcessor(exporter: SpanExporter, options?: AssistantCloudSpanProcessorOptions): SpanProcessor;
18
+ export declare function assistantCloudTraceMetadata(): {
19
19
  traceId?: string;
20
20
  };
21
- declare function withAssistantCloudTraceMetadata<Part extends {
21
+ export declare function withAssistantCloudTraceMetadata<Part extends {
22
22
  type: string;
23
23
  } = {
24
24
  type: string;
@@ -28,5 +28,4 @@ declare function withAssistantCloudTraceMetadata<Part extends {
28
28
  part: Part;
29
29
  }) => Record<string, unknown> | undefined;
30
30
  //#endregion
31
- export { AssistantCloudSpanProcessorOptions, AssistantCloudTraceExportOptions, assistantCloudTraceExportOptions, assistantCloudTraceMetadata, createAssistantCloudSpanProcessor, createAssistantCloudTraceExporter, isAssistantCloudSpan, withAssistantCloudTraceMetadata };
32
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/telemetry/index.ts"],"mappings":";;KAYY;EACV;EACA;EACA,UAAU;;KAGA;EACV,UAAU,MAAM;;iBAGF,mCACd,QACA,SACA,WACC;EACD;EACA,SAAS;;iBAmBK,kCACd,SAAS,mCACR;iBAIa,qBAAqB,MAAM;iBAO3B,kCACd,UAAU,cACV,UAAS,qCACR;iBAca;EAAiC;;iBAOjC,gCACd;EAAe;;EAAmB;GAElC,mBAAmB;EACjB,MAAM;MACF,uCACJ;EAAW,MAAM;MAAW"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/telemetry/index.ts"],"mappings":";;YAYY;EACV;EACA;EACA,UAAU;;YAGA;EACV,UAAU,MAAM;;wBAGF,mCACd,QACA,SACA,WACC;EACD;EACA,SAAS;;wBAmBK,kCACd,SAAS,mCACR;wBAIa,qBAAqB,MAAM;wBAO3B,kCACd,UAAU,cACV,UAAS,qCACR;wBAca;EAAiC;;wBAOjC,gCACd;EAAe;;EAAmB;GAElC,mBAAmB;EACjB,MAAM;MACF,uCACJ;EAAW,MAAM;MAAW"}
package/dist/version.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  //#region src/version.d.ts
2
- declare const ASSISTANT_CLOUD_VERSION: string;
2
+ export declare const ASSISTANT_CLOUD_VERSION: string;
3
3
  //#endregion
4
- export { ASSISTANT_CLOUD_VERSION };
5
4
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","names":[],"sources":["../src/version.ts"],"mappings":";cAAa"}
1
+ {"version":3,"file":"version.d.ts","names":[],"sources":["../src/version.ts"],"mappings":";qBAAa"}
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.ts
2
- const ASSISTANT_CLOUD_VERSION = "0.2.1";
2
+ const ASSISTANT_CLOUD_VERSION = "0.2.2";
3
3
  //#endregion
4
4
  export { ASSISTANT_CLOUD_VERSION };
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assistant-cloud",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Cloud integration for assistant-ui",
5
5
  "keywords": [
6
6
  "assistant",
@@ -35,7 +35,7 @@
35
35
  ],
36
36
  "sideEffects": false,
37
37
  "dependencies": {
38
- "assistant-stream": "^0.3.43"
38
+ "assistant-stream": "^0.3.44"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@opentelemetry/api": "^1.9.0",
@@ -58,15 +58,15 @@
58
58
  }
59
59
  },
60
60
  "devDependencies": {
61
- "@assistant-ui/x-buildutils": "0.0.27",
62
- "@opentelemetry/api": "^1.9.0",
63
- "@opentelemetry/exporter-trace-otlp-http": "^0.205.0",
64
- "@opentelemetry/sdk-trace-base": "^2.1.0",
65
- "@types/node": "^26.4.1",
66
- "ai": "^7.0.93",
61
+ "@assistant-ui/x-buildutils": "0.0.28",
62
+ "@opentelemetry/api": "^1.9.1",
63
+ "@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
64
+ "@opentelemetry/sdk-trace-base": "^2.11.0",
65
+ "@types/node": "^26.5.1",
66
+ "ai": "^7.0.101",
67
67
  "ai-v6": "npm:ai@^6.0.277",
68
68
  "jsdom": "^30.0.1",
69
- "vitest": "^5.0.0"
69
+ "vitest": "^5.0.1"
70
70
  },
71
71
  "publishConfig": {
72
72
  "access": "public",
@@ -84,6 +84,7 @@
84
84
  "scripts": {
85
85
  "build": "aui-build",
86
86
  "test": "pnpm run test:v7 && pnpm run test:peer-v6 && pnpm run test:types:peer-v6",
87
+ "typecheck": "tsc --noEmit",
87
88
  "test:v7": "vitest run",
88
89
  "test:peer-v6": "vitest run --config vitest.peer-v6.config.ts",
89
90
  "test:types:peer-v6": "tsc --noEmit --project tsconfig.peer-v6.json",
@@ -146,4 +146,45 @@ describe("AssistantCloudEvents", () => {
146
146
  expect(options.body.events.length).toBeLessThanOrEqual(50);
147
147
  }
148
148
  });
149
+
150
+ it.each([Number.NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY])(
151
+ "drops props containing the non-finite number %s",
152
+ async (value) => {
153
+ const { events, makeRequest } = createEvents();
154
+
155
+ events.track({ kind: "message_sent", props: { value } });
156
+ events.dispose();
157
+
158
+ await vi.waitFor(() => expect(makeRequest).toHaveBeenCalledOnce());
159
+ expect(makeRequest).toHaveBeenCalledWith("/events", {
160
+ method: "POST",
161
+ body: { events: [{ kind: "message_sent" }] },
162
+ keepalive: true,
163
+ });
164
+ },
165
+ );
166
+
167
+ it("keeps finite numeric props", async () => {
168
+ const { events, makeRequest } = createEvents();
169
+
170
+ events.track({
171
+ kind: "message_sent",
172
+ props: { negative: -1.5, zero: 0, positive: 2.5 },
173
+ });
174
+ events.dispose();
175
+
176
+ await vi.waitFor(() => expect(makeRequest).toHaveBeenCalledOnce());
177
+ expect(makeRequest).toHaveBeenCalledWith("/events", {
178
+ method: "POST",
179
+ body: {
180
+ events: [
181
+ {
182
+ kind: "message_sent",
183
+ props: { negative: -1.5, zero: 0, positive: 2.5 },
184
+ },
185
+ ],
186
+ },
187
+ keepalive: true,
188
+ });
189
+ });
149
190
  });
@@ -176,6 +176,7 @@ const normalizeProps = (
176
176
  entries.some(
177
177
  ([, value]) =>
178
178
  (typeof value === "string" && value.length > 256) ||
179
+ (typeof value === "number" && !Number.isFinite(value)) ||
179
180
  (typeof value !== "string" &&
180
181
  typeof value !== "number" &&
181
182
  typeof value !== "boolean"),
@@ -43,14 +43,65 @@ describe("AssistantCloudThreadMessages responses", () => {
43
43
 
44
44
  await expect(
45
45
  messages.feedback("thread/1", "message/1", body),
46
- ).resolves.toEqual({
46
+ ).resolves.toStrictEqual({
47
47
  feedback_id: "feedback-1",
48
48
  type: "positive",
49
49
  });
50
50
  expect(makeRequest).toHaveBeenCalledWith(
51
51
  "/threads/thread%2F1/messages/message%2F1/feedback",
52
- { method: "POST", body },
52
+ { method: "POST", body: { type: "positive" } },
53
53
  );
54
+ expect(makeRequest.mock.calls[0]![1].body).toStrictEqual({
55
+ type: "positive",
56
+ });
57
+
58
+ const bodyWithComment = {
59
+ type: "negative" as const,
60
+ comment: "The response missed a detail",
61
+ };
62
+ makeRequest.mockResolvedValueOnce({
63
+ feedback_id: "feedback-2",
64
+ type: "negative",
65
+ comment: "The response missed a detail",
66
+ });
67
+
68
+ await expect(
69
+ messages.feedback("thread-1", "message-1", bodyWithComment),
70
+ ).resolves.toEqual({
71
+ feedback_id: "feedback-2",
72
+ type: "negative",
73
+ comment: "The response missed a detail",
74
+ });
75
+ expect(makeRequest).toHaveBeenLastCalledWith(
76
+ "/threads/thread-1/messages/message-1/feedback",
77
+ { method: "POST", body: bodyWithComment },
78
+ );
79
+
80
+ makeRequest.mockResolvedValueOnce({
81
+ feedback_id: "feedback-1",
82
+ type: "positive",
83
+ });
84
+ await messages.feedback("thread-1", "message-1", {
85
+ type: "positive",
86
+ comment: " ",
87
+ });
88
+ expect(makeRequest.mock.lastCall![1].body).toStrictEqual({
89
+ type: "positive",
90
+ });
91
+
92
+ makeRequest.mockResolvedValueOnce({
93
+ feedback_id: "feedback-3",
94
+ type: "positive",
95
+ comment: null,
96
+ });
97
+
98
+ await expect(
99
+ messages.feedback("thread-1", "message-1", body),
100
+ ).resolves.toStrictEqual({
101
+ feedback_id: "feedback-3",
102
+ type: "positive",
103
+ comment: null,
104
+ });
54
105
 
55
106
  makeRequest.mockResolvedValueOnce({ type: "positive" });
56
107