assistant-cloud 0.2.2 → 0.2.3

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 (87) hide show
  1. package/README.md +2 -2
  2. package/dist/AssistantCloud.d.ts +15 -17
  3. package/dist/AssistantCloud.d.ts.map +1 -1
  4. package/dist/AssistantCloud.js +7 -2
  5. package/dist/AssistantCloud.js.map +1 -1
  6. package/dist/AssistantCloudAPI.d.ts +69 -66
  7. package/dist/AssistantCloudAPI.d.ts.map +1 -1
  8. package/dist/AssistantCloudAPI.js.map +1 -1
  9. package/dist/AssistantCloudAuthStrategy.d.ts +23 -25
  10. package/dist/AssistantCloudAuthStrategy.d.ts.map +1 -1
  11. package/dist/AssistantCloudAuthTokens.d.ts +6 -7
  12. package/dist/AssistantCloudAuthTokens.d.ts.map +1 -1
  13. package/dist/AssistantCloudEvents.d.ts +32 -25
  14. package/dist/AssistantCloudEvents.d.ts.map +1 -1
  15. package/dist/AssistantCloudEvents.js +65 -16
  16. package/dist/AssistantCloudEvents.js.map +1 -1
  17. package/dist/AssistantCloudFiles.d.ts +25 -26
  18. package/dist/AssistantCloudFiles.d.ts.map +1 -1
  19. package/dist/AssistantCloudProjectThreadMessages.d.ts +10 -11
  20. package/dist/AssistantCloudProjectThreadMessages.d.ts.map +1 -1
  21. package/dist/AssistantCloudProjectThreads.d.ts +11 -12
  22. package/dist/AssistantCloudProjectThreads.d.ts.map +1 -1
  23. package/dist/AssistantCloudProjects.d.ts +3 -5
  24. package/dist/AssistantCloudProjects.d.ts.map +1 -1
  25. package/dist/AssistantCloudRuns.d.ts +65 -53
  26. package/dist/AssistantCloudRuns.d.ts.map +1 -1
  27. package/dist/AssistantCloudRuns.js +9 -4
  28. package/dist/AssistantCloudRuns.js.map +1 -1
  29. package/dist/AssistantCloudScores.d.ts +17 -19
  30. package/dist/AssistantCloudScores.d.ts.map +1 -1
  31. package/dist/AssistantCloudThreadMessages.d.ts +33 -31
  32. package/dist/AssistantCloudThreadMessages.d.ts.map +1 -1
  33. package/dist/AssistantCloudThreadMessages.js +9 -2
  34. package/dist/AssistantCloudThreadMessages.js.map +1 -1
  35. package/dist/AssistantCloudThreads.d.ts +37 -38
  36. package/dist/AssistantCloudThreads.d.ts.map +1 -1
  37. package/dist/CloudEngagementReporter.d.ts +53 -54
  38. package/dist/CloudEngagementReporter.d.ts.map +1 -1
  39. package/dist/CloudEngagementReporter.js +4 -1
  40. package/dist/CloudEngagementReporter.js.map +1 -1
  41. package/dist/CloudMessagePersistence.d.ts +55 -56
  42. package/dist/CloudMessagePersistence.d.ts.map +1 -1
  43. package/dist/CloudMessagePersistence.js +3 -0
  44. package/dist/CloudMessagePersistence.js.map +1 -1
  45. package/dist/CloudRunReporter.d.ts +6 -8
  46. package/dist/CloudRunReporter.d.ts.map +1 -1
  47. package/dist/FormattedCloudPersistence.d.ts +34 -36
  48. package/dist/FormattedCloudPersistence.d.ts.map +1 -1
  49. package/dist/ai-sdk/index.d.ts +10 -12
  50. package/dist/ai-sdk/index.d.ts.map +1 -1
  51. package/dist/cloudResponse.d.ts +2 -4
  52. package/dist/cloudResponse.d.ts.map +1 -1
  53. package/dist/generateThreadTitle.d.ts +8 -10
  54. package/dist/generateThreadTitle.d.ts.map +1 -1
  55. package/dist/index.d.ts +18 -17
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/instrumentMcpSampling.d.ts +30 -32
  58. package/dist/instrumentMcpSampling.d.ts.map +1 -1
  59. package/dist/runTelemetry.d.ts +86 -78
  60. package/dist/runTelemetry.d.ts.map +1 -1
  61. package/dist/runTelemetry.js +57 -15
  62. package/dist/runTelemetry.js.map +1 -1
  63. package/dist/telemetry/index.d.ts +13 -15
  64. package/dist/telemetry/index.d.ts.map +1 -1
  65. package/dist/version.d.ts +0 -2
  66. package/dist/version.d.ts.map +1 -1
  67. package/dist/version.js +1 -1
  68. package/package.json +3 -3
  69. package/src/AssistantCloud.ts +17 -2
  70. package/src/AssistantCloudAPI.ts +4 -0
  71. package/src/AssistantCloudEvents.test.ts +116 -0
  72. package/src/AssistantCloudEvents.ts +81 -20
  73. package/src/AssistantCloudRuns.ts +35 -5
  74. package/src/AssistantCloudThreadMessages.ts +21 -1
  75. package/src/BackendTranscriptCopy.test.ts +79 -0
  76. package/src/CloudEngagementReporter.ts +9 -3
  77. package/src/CloudMessagePersistence.ts +4 -0
  78. package/src/ai-sdk/index.test.ts +2 -2
  79. package/src/runTelemetry.test.ts +226 -2
  80. package/src/runTelemetry.ts +121 -17
  81. package/src/tests/AssistantCloud.test.ts +22 -0
  82. package/src/tests/AssistantCloudRuns.test.ts +28 -0
  83. package/src/tests/CloudEngagementReporter.test.ts +45 -0
  84. package/src/tests/CloudRunReporter.test.ts +14 -2
  85. package/dist/tests/setup.d.ts +0 -1
  86. package/dist/tests/setup.js +0 -7
  87. package/dist/tests/setup.js.map +0 -1
@@ -1,51 +1,53 @@
1
- import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
- import { ReadonlyJSONObject } from "assistant-stream/utils";
3
- //#region src/AssistantCloudThreadMessages.d.ts
1
+ import type { ReadonlyJSONObject } from "assistant-stream/utils";
2
+ import type { AssistantCloudAPI } from "./AssistantCloudAPI.js";
4
3
  export type CloudMessage = {
5
- id: string;
6
- parent_id: string | null;
7
- height: number;
8
- created_at: Date;
9
- updated_at: Date;
10
- format: "aui/v0" | string;
11
- content: ReadonlyJSONObject;
4
+ id: string;
5
+ parent_id: string | null;
6
+ height: number;
7
+ created_at: Date;
8
+ updated_at: Date;
9
+ format: "aui/v0" | string;
10
+ content: ReadonlyJSONObject;
11
+ external_id?: string | null | undefined;
12
12
  };
13
13
  type AssistantCloudThreadMessageListQuery = {
14
- format?: string;
15
- limit?: number;
16
- after?: string;
14
+ format?: string;
15
+ limit?: number;
16
+ after?: string;
17
17
  };
18
18
  type AssistantCloudThreadMessageListResponse = {
19
- messages: CloudMessage[];
19
+ messages: CloudMessage[];
20
20
  };
21
21
  type AssistantCloudThreadMessageCreateBody = {
22
- parent_id: string | null;
23
- format: "aui/v0" | string;
24
- content: ReadonlyJSONObject;
22
+ parent_id: string | null;
23
+ format: "aui/v0" | string;
24
+ content: ReadonlyJSONObject;
25
+ external_id?: string | undefined;
26
+ parent_external_id?: string | undefined;
25
27
  };
26
28
  type AssistantCloudMessageCreateResponse = {
27
- message_id: string;
29
+ message_id: string;
28
30
  };
29
31
  type AssistantCloudThreadMessageUpdateBody = {
30
- content: ReadonlyJSONObject;
32
+ content: ReadonlyJSONObject;
31
33
  };
32
34
  export type AssistantCloudThreadMessageFeedbackBody = {
33
- type: "positive" | "negative";
34
- comment?: string;
35
+ type: "positive" | "negative";
36
+ comment?: string;
35
37
  };
36
38
  export type AssistantCloudThreadMessageFeedbackResponse = {
37
- feedback_id: string;
38
- type: "positive" | "negative";
39
- comment?: string | null;
39
+ feedback_id: string;
40
+ type: "positive" | "negative";
41
+ comment?: string | null;
40
42
  };
41
43
  export declare const decodeCloudMessage: (value: unknown, field: string) => CloudMessage;
42
44
  export declare class AssistantCloudThreadMessages {
43
- private cloud;
44
- constructor(cloud: AssistantCloudAPI);
45
- list(threadId: string, query?: AssistantCloudThreadMessageListQuery): Promise<AssistantCloudThreadMessageListResponse>;
46
- create(threadId: string, body: AssistantCloudThreadMessageCreateBody): Promise<AssistantCloudMessageCreateResponse>;
47
- update(threadId: string, messageId: string, body: AssistantCloudThreadMessageUpdateBody): Promise<void>;
48
- feedback(threadId: string, messageId: string, body: AssistantCloudThreadMessageFeedbackBody): Promise<AssistantCloudThreadMessageFeedbackResponse>;
45
+ private cloud;
46
+ constructor(cloud: AssistantCloudAPI);
47
+ list(threadId: string, query?: AssistantCloudThreadMessageListQuery): Promise<AssistantCloudThreadMessageListResponse>;
48
+ create(threadId: string, body: AssistantCloudThreadMessageCreateBody): Promise<AssistantCloudMessageCreateResponse>;
49
+ update(threadId: string, messageId: string, body: AssistantCloudThreadMessageUpdateBody): Promise<void>;
50
+ feedback(threadId: string, messageId: string, body: AssistantCloudThreadMessageFeedbackBody): Promise<AssistantCloudThreadMessageFeedbackResponse>;
49
51
  }
50
- //#endregion
52
+ export {};
51
53
  //# sourceMappingURL=AssistantCloudThreadMessages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreadMessages.d.ts","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"mappings":";;;YAaY;EACV;EACA;EACA;EACA,YAAY;EACZ,YAAY;EACZ;EACA,SAAS;;KAGN;EACH;EACA;EACA;;KAGG;EACH,UAAU;;KAGP;EACH;EACA;EACA,SAAS;;KAGN;EACH;;KAGG;EACH,SAAS;;YAKC;EACV;EACA;;YAGU;EACV;EACA;EACA;;qBAGW,qBACX,gBACA,kBACC;qBAaU;UACH;EAEI,YAAA,OAAO;EAIN,KACX,kBACA,QAAQ,uCACP,QAAQ;EAiBE,OACX,kBACA,MAAM,wCACL,QAAQ;EAcE,OACX,kBACA,mBACA,MAAM,wCACL;EAOU,SACX,kBACA,mBACA,MAAM,0CACL,QAAQ"}
1
+ {"version":3,"file":"AssistantCloudThreadMessages.d.ts","sourceRoot":"","sources":["../src/AssistantCloudThreadMessages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,+BAA4B;AAY7D,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACzC,CAAC;AAEF,KAAK,oCAAoC,GAAG;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,uCAAuC,GAAG;IAC7C,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B,CAAC;AAEF,KAAK,qCAAqC,GAAG;IAC3C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC,CAAC;AAEF,KAAK,mCAAmC,GAAG;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,qCAAqC,GAAG;IAC3C,OAAO,EAAE,kBAAkB,CAAC;CAC7B,CAAC;AAIF,MAAM,MAAM,uCAAuC,GAAG;IACpD,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,OAAO,EACd,OAAO,MAAM,KACZ,YAeF,CAAC;AAEF,qBAAa,4BAA4B;IACvC,OAAO,CAAC,KAAK,CAAoB;gBAErB,KAAK,EAAE,iBAAiB;IAIvB,IAAI,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,oCAAoC,GAC3C,OAAO,CAAC,uCAAuC,CAAC;IAiBtC,MAAM,CACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,qCAAqC,GAC1C,OAAO,CAAC,mCAAmC,CAAC;IA2BlC,MAAM,CACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,qCAAqC,GAC1C,OAAO,CAAC,IAAI,CAAC;IAOH,QAAQ,CACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,uCAAuC,GAC5C,OAAO,CAAC,2CAA2C,CAAC;CAwBxD"}
@@ -10,7 +10,8 @@ const decodeCloudMessage = (value, field) => {
10
10
  created_at: readCloudTimestamp(message.created_at, `${field}.created_at`),
11
11
  updated_at: readCloudTimestamp(message.updated_at, `${field}.updated_at`),
12
12
  format: readCloudString(message.format, `${field}.format`),
13
- content: readCloudJSONObject(message.content, `${field}.content`)
13
+ content: readCloudJSONObject(message.content, `${field}.content`),
14
+ external_id: readCloudNullableString(message.external_id ?? null, `${field}.external_id`)
14
15
  };
15
16
  };
16
17
  var AssistantCloudThreadMessages = class {
@@ -25,7 +26,13 @@ var AssistantCloudThreadMessages = class {
25
26
  async create(threadId, body) {
26
27
  const response = readCloudRecord(await this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}/messages`, {
27
28
  method: "POST",
28
- body
29
+ body: {
30
+ parent_id: body.parent_id,
31
+ format: body.format,
32
+ content: body.content,
33
+ ...body.external_id !== void 0 ? { external_id: body.external_id } : void 0,
34
+ ...body.parent_external_id !== void 0 ? { parent_external_id: body.parent_external_id } : void 0
35
+ }
29
36
  }), "thread message create response");
30
37
  return { message_id: readCloudString(response.message_id, "message_id") };
31
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreadMessages.js","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"sourcesContent":["import type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport {\n readCloudArray,\n readCloudEnum,\n readCloudInteger,\n readCloudJSONObject,\n readCloudNullableString,\n readCloudRecord,\n readCloudString,\n readCloudTimestamp,\n} from \"./cloudResponse\";\n\nexport type CloudMessage = {\n id: string;\n parent_id: string | null;\n height: number;\n created_at: Date;\n updated_at: Date;\n format: \"aui/v0\" | string;\n content: ReadonlyJSONObject;\n};\n\ntype AssistantCloudThreadMessageListQuery = {\n format?: string;\n limit?: number;\n after?: string;\n};\n\ntype AssistantCloudThreadMessageListResponse = {\n messages: CloudMessage[];\n};\n\ntype AssistantCloudThreadMessageCreateBody = {\n parent_id: string | null;\n format: \"aui/v0\" | string;\n content: ReadonlyJSONObject;\n};\n\ntype AssistantCloudMessageCreateResponse = {\n message_id: string;\n};\n\ntype AssistantCloudThreadMessageUpdateBody = {\n content: ReadonlyJSONObject;\n};\n\nconst MESSAGE_FEEDBACK_TYPES = [\"positive\", \"negative\"] as const;\n\nexport type AssistantCloudThreadMessageFeedbackBody = {\n type: \"positive\" | \"negative\";\n comment?: string;\n};\n\nexport type AssistantCloudThreadMessageFeedbackResponse = {\n feedback_id: string;\n type: \"positive\" | \"negative\";\n comment?: string | null;\n};\n\nexport const decodeCloudMessage = (\n value: unknown,\n field: string,\n): CloudMessage => {\n const message = readCloudRecord(value, field);\n return {\n id: readCloudString(message.id, `${field}.id`),\n parent_id: readCloudNullableString(message.parent_id, `${field}.parent_id`),\n height: readCloudInteger(message.height, `${field}.height`),\n created_at: readCloudTimestamp(message.created_at, `${field}.created_at`),\n updated_at: readCloudTimestamp(message.updated_at, `${field}.updated_at`),\n format: readCloudString(message.format, `${field}.format`),\n content: readCloudJSONObject(message.content, `${field}.content`),\n };\n};\n\nexport class AssistantCloudThreadMessages {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public async list(\n threadId: string,\n query?: AssistantCloudThreadMessageListQuery,\n ): Promise<AssistantCloudThreadMessageListResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages`,\n { query },\n ),\n \"thread message list response\",\n );\n const messages = readCloudArray(response.messages, \"messages\");\n\n return {\n messages: messages.map((message, index) =>\n decodeCloudMessage(message, `messages[${index}]`),\n ),\n };\n }\n\n public async create(\n threadId: string,\n body: AssistantCloudThreadMessageCreateBody,\n ): Promise<AssistantCloudMessageCreateResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages`,\n { method: \"POST\", body },\n ),\n \"thread message create response\",\n );\n\n return {\n message_id: readCloudString(response.message_id, \"message_id\"),\n };\n }\n\n public async update(\n threadId: string,\n messageId: string,\n body: AssistantCloudThreadMessageUpdateBody,\n ): Promise<void> {\n return this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}`,\n { method: \"PUT\", body },\n );\n }\n\n public async feedback(\n threadId: string,\n messageId: string,\n body: AssistantCloudThreadMessageFeedbackBody,\n ): Promise<AssistantCloudThreadMessageFeedbackResponse> {\n const comment = body.comment?.trim();\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/feedback`,\n {\n method: \"POST\",\n body: {\n type: body.type,\n ...(comment ? { comment } : undefined),\n },\n },\n ),\n \"thread message feedback response\",\n );\n\n return {\n feedback_id: readCloudString(response.feedback_id, \"feedback_id\"),\n type: readCloudEnum(response.type, \"type\", MESSAGE_FEEDBACK_TYPES),\n ...(\"comment\" in response\n ? { comment: readCloudNullableString(response.comment, \"comment\") }\n : undefined),\n };\n }\n}\n"],"mappings":";;AA+CA,MAAM,yBAAyB,CAAC,YAAY,UAAU;AAatD,MAAa,sBACX,OACA,UACiB;CACjB,MAAM,UAAU,gBAAgB,OAAO,KAAK;CAC5C,OAAO;EACL,IAAI,gBAAgB,QAAQ,IAAI,GAAG,MAAM,IAAI;EAC7C,WAAW,wBAAwB,QAAQ,WAAW,GAAG,MAAM,WAAW;EAC1E,QAAQ,iBAAiB,QAAQ,QAAQ,GAAG,MAAM,QAAQ;EAC1D,YAAY,mBAAmB,QAAQ,YAAY,GAAG,MAAM,YAAY;EACxE,YAAY,mBAAmB,QAAQ,YAAY,GAAG,MAAM,YAAY;EACxE,QAAQ,gBAAgB,QAAQ,QAAQ,GAAG,MAAM,QAAQ;EACzD,SAAS,oBAAoB,QAAQ,SAAS,GAAG,MAAM,SAAS;CAClE;AACF;AAEA,IAAa,+BAAb,MAA0C;CACxC;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,MAAa,KACX,UACA,OACkD;EAClD,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YACzC,EAAE,MAAM,CACV,GACA,8BACF;EAGA,OAAO,EACL,UAHe,eAAe,SAAS,UAAU,UAGhC,CAAC,CAAC,KAAK,SAAS,UAC/B,mBAAmB,SAAS,YAAY,MAAM,EAAE,CAClD,EACF;CACF;CAEA,MAAa,OACX,UACA,MAC8C;EAC9C,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YACzC;GAAE,QAAQ;GAAQ;EAAK,CACzB,GACA,gCACF;EAEA,OAAO,EACL,YAAY,gBAAgB,SAAS,YAAY,YAAY,EAC/D;CACF;CAEA,MAAa,OACX,UACA,WACA,MACe;EACf,OAAO,KAAK,MAAM,YAChB,YAAY,mBAAmB,QAAQ,EAAE,YAAY,mBAAmB,SAAS,KACjF;GAAE,QAAQ;GAAO;EAAK,CACxB;CACF;CAEA,MAAa,SACX,UACA,WACA,MACsD;EACtD,MAAM,UAAU,KAAK,SAAS,KAAK;EACnC,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YAAY,mBAAmB,SAAS,EAAE,YACnF;GACE,QAAQ;GACR,MAAM;IACJ,MAAM,KAAK;IACX,GAAI,UAAU,EAAE,QAAQ,IAAI,KAAA;GAC9B;EACF,CACF,GACA,kCACF;EAEA,OAAO;GACL,aAAa,gBAAgB,SAAS,aAAa,aAAa;GAChE,MAAM,cAAc,SAAS,MAAM,QAAQ,sBAAsB;GACjE,GAAI,aAAa,WACb,EAAE,SAAS,wBAAwB,SAAS,SAAS,SAAS,EAAE,IAChE,KAAA;EACN;CACF;AACF"}
1
+ {"version":3,"file":"AssistantCloudThreadMessages.js","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"sourcesContent":["import type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport {\n readCloudArray,\n readCloudEnum,\n readCloudInteger,\n readCloudJSONObject,\n readCloudNullableString,\n readCloudRecord,\n readCloudString,\n readCloudTimestamp,\n} from \"./cloudResponse\";\n\nexport type CloudMessage = {\n id: string;\n parent_id: string | null;\n height: number;\n created_at: Date;\n updated_at: Date;\n format: \"aui/v0\" | string;\n content: ReadonlyJSONObject;\n external_id?: string | null | undefined;\n};\n\ntype AssistantCloudThreadMessageListQuery = {\n format?: string;\n limit?: number;\n after?: string;\n};\n\ntype AssistantCloudThreadMessageListResponse = {\n messages: CloudMessage[];\n};\n\ntype AssistantCloudThreadMessageCreateBody = {\n parent_id: string | null;\n format: \"aui/v0\" | string;\n content: ReadonlyJSONObject;\n external_id?: string | undefined;\n parent_external_id?: string | undefined;\n};\n\ntype AssistantCloudMessageCreateResponse = {\n message_id: string;\n};\n\ntype AssistantCloudThreadMessageUpdateBody = {\n content: ReadonlyJSONObject;\n};\n\nconst MESSAGE_FEEDBACK_TYPES = [\"positive\", \"negative\"] as const;\n\nexport type AssistantCloudThreadMessageFeedbackBody = {\n type: \"positive\" | \"negative\";\n comment?: string;\n};\n\nexport type AssistantCloudThreadMessageFeedbackResponse = {\n feedback_id: string;\n type: \"positive\" | \"negative\";\n comment?: string | null;\n};\n\nexport const decodeCloudMessage = (\n value: unknown,\n field: string,\n): CloudMessage => {\n const message = readCloudRecord(value, field);\n return {\n id: readCloudString(message.id, `${field}.id`),\n parent_id: readCloudNullableString(message.parent_id, `${field}.parent_id`),\n height: readCloudInteger(message.height, `${field}.height`),\n created_at: readCloudTimestamp(message.created_at, `${field}.created_at`),\n updated_at: readCloudTimestamp(message.updated_at, `${field}.updated_at`),\n format: readCloudString(message.format, `${field}.format`),\n content: readCloudJSONObject(message.content, `${field}.content`),\n external_id: readCloudNullableString(\n message.external_id ?? null,\n `${field}.external_id`,\n ),\n };\n};\n\nexport class AssistantCloudThreadMessages {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public async list(\n threadId: string,\n query?: AssistantCloudThreadMessageListQuery,\n ): Promise<AssistantCloudThreadMessageListResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages`,\n { query },\n ),\n \"thread message list response\",\n );\n const messages = readCloudArray(response.messages, \"messages\");\n\n return {\n messages: messages.map((message, index) =>\n decodeCloudMessage(message, `messages[${index}]`),\n ),\n };\n }\n\n public async create(\n threadId: string,\n body: AssistantCloudThreadMessageCreateBody,\n ): Promise<AssistantCloudMessageCreateResponse> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages`,\n {\n method: \"POST\",\n body: {\n parent_id: body.parent_id,\n format: body.format,\n content: body.content,\n ...(body.external_id !== undefined\n ? { external_id: body.external_id }\n : undefined),\n ...(body.parent_external_id !== undefined\n ? { parent_external_id: body.parent_external_id }\n : undefined),\n },\n },\n ),\n \"thread message create response\",\n );\n\n return {\n message_id: readCloudString(response.message_id, \"message_id\"),\n };\n }\n\n public async update(\n threadId: string,\n messageId: string,\n body: AssistantCloudThreadMessageUpdateBody,\n ): Promise<void> {\n return this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}`,\n { method: \"PUT\", body },\n );\n }\n\n public async feedback(\n threadId: string,\n messageId: string,\n body: AssistantCloudThreadMessageFeedbackBody,\n ): Promise<AssistantCloudThreadMessageFeedbackResponse> {\n const comment = body.comment?.trim();\n const response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/feedback`,\n {\n method: \"POST\",\n body: {\n type: body.type,\n ...(comment ? { comment } : undefined),\n },\n },\n ),\n \"thread message feedback response\",\n );\n\n return {\n feedback_id: readCloudString(response.feedback_id, \"feedback_id\"),\n type: readCloudEnum(response.type, \"type\", MESSAGE_FEEDBACK_TYPES),\n ...(\"comment\" in response\n ? { comment: readCloudNullableString(response.comment, \"comment\") }\n : undefined),\n };\n }\n}\n"],"mappings":";;AAkDA,MAAM,yBAAyB,CAAC,YAAY,UAAU;AAatD,MAAa,sBACX,OACA,UACiB;CACjB,MAAM,UAAU,gBAAgB,OAAO,KAAK;CAC5C,OAAO;EACL,IAAI,gBAAgB,QAAQ,IAAI,GAAG,MAAM,IAAI;EAC7C,WAAW,wBAAwB,QAAQ,WAAW,GAAG,MAAM,WAAW;EAC1E,QAAQ,iBAAiB,QAAQ,QAAQ,GAAG,MAAM,QAAQ;EAC1D,YAAY,mBAAmB,QAAQ,YAAY,GAAG,MAAM,YAAY;EACxE,YAAY,mBAAmB,QAAQ,YAAY,GAAG,MAAM,YAAY;EACxE,QAAQ,gBAAgB,QAAQ,QAAQ,GAAG,MAAM,QAAQ;EACzD,SAAS,oBAAoB,QAAQ,SAAS,GAAG,MAAM,SAAS;EAChE,aAAa,wBACX,QAAQ,eAAe,MACvB,GAAG,MAAM,aACX;CACF;AACF;AAEA,IAAa,+BAAb,MAA0C;CACxC;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,MAAa,KACX,UACA,OACkD;EAClD,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YACzC,EAAE,MAAM,CACV,GACA,8BACF;EAGA,OAAO,EACL,UAHe,eAAe,SAAS,UAAU,UAGhC,CAAC,CAAC,KAAK,SAAS,UAC/B,mBAAmB,SAAS,YAAY,MAAM,EAAE,CAClD,EACF;CACF;CAEA,MAAa,OACX,UACA,MAC8C;EAC9C,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YACzC;GACE,QAAQ;GACR,MAAM;IACJ,WAAW,KAAK;IAChB,QAAQ,KAAK;IACb,SAAS,KAAK;IACd,GAAI,KAAK,gBAAgB,KAAA,IACrB,EAAE,aAAa,KAAK,YAAY,IAChC,KAAA;IACJ,GAAI,KAAK,uBAAuB,KAAA,IAC5B,EAAE,oBAAoB,KAAK,mBAAmB,IAC9C,KAAA;GACN;EACF,CACF,GACA,gCACF;EAEA,OAAO,EACL,YAAY,gBAAgB,SAAS,YAAY,YAAY,EAC/D;CACF;CAEA,MAAa,OACX,UACA,WACA,MACe;EACf,OAAO,KAAK,MAAM,YAChB,YAAY,mBAAmB,QAAQ,EAAE,YAAY,mBAAmB,SAAS,KACjF;GAAE,QAAQ;GAAO;EAAK,CACxB;CACF;CAEA,MAAa,SACX,UACA,WACA,MACsD;EACtD,MAAM,UAAU,KAAK,SAAS,KAAK;EACnC,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YAAY,mBAAmB,SAAS,EAAE,YACnF;GACE,QAAQ;GACR,MAAM;IACJ,MAAM,KAAK;IACX,GAAI,UAAU,EAAE,QAAQ,IAAI,KAAA;GAC9B;EACF,CACF,GACA,kCACF;EAEA,OAAO;GACL,aAAa,gBAAgB,SAAS,aAAa,aAAa;GAChE,MAAM,cAAc,SAAS,MAAM,QAAQ,sBAAsB;GACjE,GAAI,aAAa,WACb,EAAE,SAAS,wBAAwB,SAAS,SAAS,SAAS,EAAE,IAChE,KAAA;EACN;CACF;AACF"}
@@ -1,59 +1,58 @@
1
- import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
1
+ import type { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
2
  import { AssistantCloudThreadMessages } from "./AssistantCloudThreadMessages.js";
3
- //#region src/AssistantCloudThreads.d.ts
4
3
  type AssistantCloudThreadsListQuery = {
5
- is_archived?: boolean;
6
- limit?: number;
7
- after?: string;
4
+ is_archived?: boolean;
5
+ limit?: number;
6
+ after?: string;
8
7
  };
9
8
  export type CloudThread = {
10
- title: string;
11
- last_message_at: Date;
12
- metadata: unknown;
13
- external_id: string | null;
14
- id: string;
15
- project_id: string;
16
- created_at: Date;
17
- updated_at: Date;
18
- workspace_id: string;
19
- is_archived: boolean;
9
+ title: string;
10
+ last_message_at: Date;
11
+ metadata: unknown;
12
+ external_id: string | null;
13
+ id: string;
14
+ project_id: string;
15
+ created_at: Date;
16
+ updated_at: Date;
17
+ workspace_id: string;
18
+ is_archived: boolean;
20
19
  };
21
20
  type AssistantCloudThreadsListResponse = {
22
- threads: CloudThread[];
21
+ threads: CloudThread[];
23
22
  };
24
23
  type AssistantCloudThreadsCreateBody = {
25
- title?: string | undefined;
26
- last_message_at: Date;
27
- metadata?: unknown | undefined;
28
- external_id?: string | undefined;
24
+ title?: string | undefined;
25
+ last_message_at: Date;
26
+ metadata?: unknown | undefined;
27
+ external_id?: string | undefined;
29
28
  };
30
29
  type AssistantCloudThreadsCreateResponse = {
31
- thread_id: string;
30
+ thread_id: string;
32
31
  };
33
32
  type AssistantCloudThreadsClaimBody = {
34
- refresh_token: string;
33
+ refresh_token: string;
35
34
  };
36
35
  type AssistantCloudThreadsClaimResponse = {
37
- moved: number;
36
+ moved: number;
38
37
  };
39
38
  type AssistantCloudThreadsUpdateBody = {
40
- title?: string | undefined;
41
- last_message_at?: Date | undefined;
42
- metadata?: unknown | undefined;
43
- is_archived?: boolean | undefined;
39
+ title?: string | undefined;
40
+ last_message_at?: Date | undefined;
41
+ metadata?: unknown | undefined;
42
+ is_archived?: boolean | undefined;
44
43
  };
45
44
  export declare const decodeCloudThread: (value: unknown, field: string) => CloudThread;
46
45
  export declare class AssistantCloudThreads {
47
- readonly messages: AssistantCloudThreadMessages;
48
- private cloud;
49
- constructor(cloud: AssistantCloudAPI);
50
- list(query?: AssistantCloudThreadsListQuery): Promise<AssistantCloudThreadsListResponse>;
51
- get(threadId: string): Promise<CloudThread>;
52
- create(body: AssistantCloudThreadsCreateBody): Promise<AssistantCloudThreadsCreateResponse>;
53
- update(threadId: string, body: AssistantCloudThreadsUpdateBody): Promise<void>;
54
- /** Moves every thread of the anonymous identity behind `refresh_token` into the caller's workspace. */
55
- claim(body: AssistantCloudThreadsClaimBody): Promise<AssistantCloudThreadsClaimResponse>;
56
- delete(threadId: string): Promise<void>;
46
+ readonly messages: AssistantCloudThreadMessages;
47
+ private cloud;
48
+ constructor(cloud: AssistantCloudAPI);
49
+ list(query?: AssistantCloudThreadsListQuery): Promise<AssistantCloudThreadsListResponse>;
50
+ get(threadId: string): Promise<CloudThread>;
51
+ create(body: AssistantCloudThreadsCreateBody): Promise<AssistantCloudThreadsCreateResponse>;
52
+ update(threadId: string, body: AssistantCloudThreadsUpdateBody): Promise<void>;
53
+ /** Moves every thread of the anonymous identity behind `refresh_token` into the caller's workspace. */
54
+ claim(body: AssistantCloudThreadsClaimBody): Promise<AssistantCloudThreadsClaimResponse>;
55
+ delete(threadId: string): Promise<void>;
57
56
  }
58
- //#endregion
57
+ export {};
59
58
  //# sourceMappingURL=AssistantCloudThreads.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreads.d.ts","names":[],"sources":["../src/AssistantCloudThreads.ts"],"mappings":";;;KAYK;EACH;EACA;EACA;;YAGU;EACV;EACA,iBAAiB;EACjB;EACA;EACA;EACA;EACA,YAAY;EACZ,YAAY;EACZ;EACA;;KAGG;EACH,SAAS;;KAGN;EACH;EACA,iBAAiB;EACjB;EACA;;KAGG;EACH;;KAGG;EACH;;KAGG;EACH;;KAGG;EACH;EACA,kBAAkB;EAClB;EACA;;qBAGW,oBACX,gBACA,kBACC;qBAsBU;WACK,UAAU;UAElB;EAEI,YAAA,OAAO;EAKN,KACX,QAAQ,iCACP,QAAQ;EAkBE,IAAI,mBAAmB,QAAQ;EAS/B,OACX,MAAM,kCACL,QAAQ;EASE,OACX,kBACA,MAAM,kCACL;;EAQU,MACX,MAAM,iCACL,QAAQ;EASE,OAAO,mBAAmB"}
1
+ {"version":3,"file":"AssistantCloudThreads.d.ts","sourceRoot":"","sources":["../src/AssistantCloudThreads.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,+BAA4B;AAC7D,OAAO,EAAE,4BAA4B,EAAE,0CAAuC;AAW9E,KAAK,8BAA8B,GAAG;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,IAAI,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,KAAK,iCAAiC,GAAG;IACvC,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF,KAAK,+BAA+B,GAAG;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,eAAe,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,KAAK,mCAAmC,GAAG;IACzC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,8BAA8B,GAAG;IACpC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,kCAAkC,GAAG;IACxC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,+BAA+B,GAAG;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,eAAe,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,OAAO,EACd,OAAO,MAAM,KACZ,WAoBF,CAAC;AAEF,qBAAa,qBAAqB;IAChC,SAAgB,QAAQ,EAAE,4BAA4B,CAAC;IAEvD,OAAO,CAAC,KAAK,CAAoB;gBAErB,KAAK,EAAE,iBAAiB;IAKvB,IAAI,CACf,KAAK,CAAC,EAAE,8BAA8B,GACrC,OAAO,CAAC,iCAAiC,CAAC;IAkBhC,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAS3C,MAAM,CACjB,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,mCAAmC,CAAC;IASlC,MAAM,CACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,IAAI,CAAC;IAOhB,uGAAuG;IAC1F,KAAK,CAChB,IAAI,EAAE,8BAA8B,GACnC,OAAO,CAAC,kCAAkC,CAAC;IASjC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAKrD"}
@@ -1,16 +1,16 @@
1
- import { AssistantCloudEvent } from "./AssistantCloudEvents.js";
2
- import { AssistantCloud } from "./AssistantCloud.js";
3
- //#region src/CloudEngagementReporter.d.ts
1
+ import type { AssistantCloud } from "./AssistantCloud.js";
2
+ import type { AssistantCloudEvent } from "./AssistantCloudEvents.js";
4
3
  export type EngagementEventIds = Pick<AssistantCloudEvent, "thread_id" | "message_id" | "run_id">;
5
4
  /**
6
5
  * Turns the ids an integration knows (its own thread and message ids) into the
7
6
  * ids the cloud stores. A send is the one event that may create the remote
8
7
  * thread, so it asks for `awaitThread`; every other event reads the ids that
9
- * already exist.
8
+ * already exist. Returning nothing declines the event: the thread is not one
9
+ * the integration knows, so there is nothing to attribute it to.
10
10
  */
11
11
  export type EngagementIdResolver = (threadId: string, messageId: string | undefined, options: {
12
- awaitThread: boolean;
13
- }) => EngagementEventIds | Promise<EngagementEventIds>;
12
+ awaitThread: boolean;
13
+ }) => EngagementEventIds | undefined | Promise<EngagementEventIds | undefined>;
14
14
  /**
15
15
  * Derives engagement events from what a chat integration observes and keeps
16
16
  * the per thread state the events need: a run's start for the stop duration,
@@ -21,53 +21,52 @@ export type EngagementIdResolver = (threadId: string, messageId: string | undefi
21
21
  * buffer, so a disabled telemetry setting drops everything here as well.
22
22
  */
23
23
  export declare class CloudEngagementReporter {
24
- private readonly runStartedAt;
25
- private readonly runEndedAt;
26
- private readonly shownErrors;
27
- private readonly shownSuggestions;
28
- private readonly getCloud;
29
- private readonly resolveIds;
30
- constructor(cloud: AssistantCloud | (() => AssistantCloud), resolveIds?: EngagementIdResolver);
31
- runStarted(threadId: string): void;
32
- runEnded(threadId: string): void;
33
- /** Reported once per started run, with the time the run had been going. */
34
- runStopped(threadId: string): void;
35
- /** Carries the time since the previous run of the thread ended, when known. */
36
- messageSent(threadId: string, init: {
37
- messageId?: string | undefined;
38
- chars: number;
39
- attachments: number;
40
- }): void;
41
- messageEdited(threadId: string, init: {
42
- messageId: string;
43
- chars: number;
44
- }): void;
45
- messageRegenerated(threadId: string, messageId?: string): void;
46
- /** Reported once per run, so a retried render of the same error stays one event. */
47
- errorShown(threadId: string, init: {
48
- messageId?: string | undefined;
49
- reason: string;
50
- }): void;
51
- /** Reported once per thread, with the number of suggestions on offer. */
52
- suggestionsShown(threadId: string, count: number): void;
53
- suggestionClicked(threadId: string): void;
54
- attachmentAdded(threadId: string, init: {
55
- messageId?: string | undefined;
56
- contentType?: string | undefined;
57
- }): void;
58
- attachmentFailed(threadId: string, init: {
59
- messageId?: string | undefined;
60
- contentType?: string | undefined;
61
- }): void;
62
- voiceStarted(threadId: string): void;
63
- speechStarted(threadId: string, messageId?: string): void;
64
- branchSwitched(threadId: string, messageId?: string): void;
65
- messageCopied(threadId: string, messageId?: string): void;
66
- toolApproved(threadId: string, messageId: string, toolCallId: string, toolName: string): void;
67
- toolRejected(threadId: string, messageId: string, toolCallId: string, toolName: string): void;
68
- /** Reported only for a thread the cloud already knows. */
69
- threadSwitched(threadId: string): void;
70
- private track;
24
+ private readonly runStartedAt;
25
+ private readonly runEndedAt;
26
+ private readonly shownErrors;
27
+ private readonly shownSuggestions;
28
+ private readonly getCloud;
29
+ private readonly resolveIds;
30
+ constructor(cloud: AssistantCloud | (() => AssistantCloud), resolveIds?: EngagementIdResolver);
31
+ runStarted(threadId: string): void;
32
+ runEnded(threadId: string): void;
33
+ /** Reported once per started run, with the time the run had been going. */
34
+ runStopped(threadId: string): void;
35
+ /** Carries the time since the previous run of the thread ended, when known. */
36
+ messageSent(threadId: string, init: {
37
+ messageId?: string | undefined;
38
+ chars: number;
39
+ attachments: number;
40
+ }): void;
41
+ messageEdited(threadId: string, init: {
42
+ messageId: string;
43
+ chars: number;
44
+ }): void;
45
+ messageRegenerated(threadId: string, messageId?: string): void;
46
+ /** Reported once per run, so a retried render of the same error stays one event. */
47
+ errorShown(threadId: string, init: {
48
+ messageId?: string | undefined;
49
+ reason: string;
50
+ }): void;
51
+ /** Reported once per thread, with the number of suggestions on offer. */
52
+ suggestionsShown(threadId: string, count: number): void;
53
+ suggestionClicked(threadId: string): void;
54
+ attachmentAdded(threadId: string, init: {
55
+ messageId?: string | undefined;
56
+ contentType?: string | undefined;
57
+ }): void;
58
+ attachmentFailed(threadId: string, init: {
59
+ messageId?: string | undefined;
60
+ contentType?: string | undefined;
61
+ }): void;
62
+ voiceStarted(threadId: string): void;
63
+ speechStarted(threadId: string, messageId?: string): void;
64
+ branchSwitched(threadId: string, messageId?: string): void;
65
+ messageCopied(threadId: string, messageId?: string): void;
66
+ toolApproved(threadId: string, messageId: string, toolCallId: string, toolName: string): void;
67
+ toolRejected(threadId: string, messageId: string, toolCallId: string, toolName: string): void;
68
+ /** Reported only for a thread the cloud already knows. */
69
+ threadSwitched(threadId: string): void;
70
+ private track;
71
71
  }
72
- //#endregion
73
72
  //# sourceMappingURL=CloudEngagementReporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CloudEngagementReporter.d.ts","names":[],"sources":["../src/CloudEngagementReporter.ts"],"mappings":";;;YAMY,qBAAqB,KAC/B;;;;;;;YAUU,wBACV,kBACA,+BACA;EAAW;MACR,qBAAqB,QAAQ;;;;;;;;;;qBAoCrB;mBACM;mBACA;mBACA;mBACA;mBAEA;mBACA;EAGf,YAAA,OAAO,wBAAwB,iBAC/B,aAAY;EAMP,WAAW;EAKX,SAAS;;EAMT,WAAW;;EAUX,YACL,kBACA;IACE;IACA;IACA;;EAkBG,cACL,kBACA;IAAQ;IAAmB;;EAOtB,mBAAmB,kBAAkB;;EAKrC,WACL,kBACA;IAAQ;IAAgC;;;EAUnC,iBAAiB,kBAAkB;EAMnC,kBAAkB;EAIlB,gBACL,kBACA;IAAQ;IAAgC;;EAOnC,iBACL,kBACA;IAAQ;IAAgC;;EAOnC,aAAa;EAIb,cAAc,kBAAkB;EAIhC,eAAe,kBAAkB;EAIjC,cAAc,kBAAkB;EAIhC,aACL,kBACA,mBACA,oBACA;EAOK,aACL,kBACA,mBACA,oBACA;;EAQK,eAAe;UAId"}
1
+ {"version":3,"file":"CloudEngagementReporter.d.ts","sourceRoot":"","sources":["../src/CloudEngagementReporter.ts"],"names":[],"mappings":"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"}
@@ -46,8 +46,10 @@ var CloudEngagementReporter = class {
46
46
  runStopped(threadId) {
47
47
  const startedAt = this.runStartedAt.get(threadId);
48
48
  if (startedAt === void 0) return;
49
+ const stoppedAt = Date.now();
49
50
  this.runStartedAt.delete(threadId);
50
- this.track("run_stopped", threadId, void 0, { value: Math.max(0, Date.now() - startedAt) });
51
+ remember(this.runEndedAt, threadId, stoppedAt);
52
+ this.track("run_stopped", threadId, void 0, { value: Math.max(0, stoppedAt - startedAt) });
51
53
  }
52
54
  /** Carries the time since the previous run of the thread ended, when known. */
53
55
  messageSent(threadId, init) {
@@ -117,6 +119,7 @@ var CloudEngagementReporter = class {
117
119
  }
118
120
  track(kind, threadId, messageId, init = {}, options = { awaitThread: false }) {
119
121
  Promise.resolve().then(() => this.resolveIds(threadId, messageId, options)).then((ids) => {
122
+ if (!ids) return;
120
123
  if (kind === "thread_switched" && !ids.thread_id) return;
121
124
  this.getCloud().events.track({
122
125
  kind,
@@ -1 +1 @@
1
- {"version":3,"file":"CloudEngagementReporter.js","names":[],"sources":["../src/CloudEngagementReporter.ts"],"sourcesContent":["import type { AssistantCloud } from \"./AssistantCloud\";\nimport type {\n AssistantCloudEvent,\n AssistantCloudEventKind,\n} from \"./AssistantCloudEvents\";\n\nexport type EngagementEventIds = Pick<\n AssistantCloudEvent,\n \"thread_id\" | \"message_id\" | \"run_id\"\n>;\n\n/**\n * Turns the ids an integration knows (its own thread and message ids) into the\n * ids the cloud stores. A send is the one event that may create the remote\n * thread, so it asks for `awaitThread`; every other event reads the ids that\n * already exist.\n */\nexport type EngagementIdResolver = (\n threadId: string,\n messageId: string | undefined,\n options: { awaitThread: boolean },\n) => EngagementEventIds | Promise<EngagementEventIds>;\n\ntype EngagementEventInit = Pick<AssistantCloudEvent, \"value\" | \"props\">;\n\nconst MAX_REMEMBERED_THREADS = 256;\n\nfunction remember<T>(map: Map<string, T>, threadId: string, value: T): void {\n map.delete(threadId);\n map.set(threadId, value);\n if (map.size > MAX_REMEMBERED_THREADS) {\n map.delete(map.keys().next().value!);\n }\n}\n\nfunction mark(set: Set<string>, threadId: string): void {\n set.delete(threadId);\n set.add(threadId);\n if (set.size > MAX_REMEMBERED_THREADS) {\n set.delete(set.values().next().value!);\n }\n}\n\nconst passThroughIds: EngagementIdResolver = (threadId, messageId) => ({\n thread_id: threadId,\n ...(messageId !== undefined ? { message_id: messageId } : undefined),\n});\n\n/**\n * Derives engagement events from what a chat integration observes and keeps\n * the per thread state the events need: a run's start for the stop duration,\n * a run's end for the time to the next message, one error and one suggestion\n * list per run or thread. A started run is kept until it ends or stops; the\n * rest is kept for the 256 most recently touched threads, so a long session\n * does not grow it without bound. Delivery goes through the cloud's event\n * buffer, so a disabled telemetry setting drops everything here as well.\n */\nexport class CloudEngagementReporter {\n private readonly runStartedAt = new Map<string, number>();\n private readonly runEndedAt = new Map<string, number>();\n private readonly shownErrors = new Set<string>();\n private readonly shownSuggestions = new Set<string>();\n\n private readonly getCloud: () => AssistantCloud;\n private readonly resolveIds: EngagementIdResolver;\n\n constructor(\n cloud: AssistantCloud | (() => AssistantCloud),\n resolveIds: EngagementIdResolver = passThroughIds,\n ) {\n this.getCloud = typeof cloud === \"function\" ? cloud : () => cloud;\n this.resolveIds = resolveIds;\n }\n\n public runStarted(threadId: string): void {\n this.runStartedAt.set(threadId, Date.now());\n this.shownErrors.delete(threadId);\n }\n\n public runEnded(threadId: string): void {\n this.runStartedAt.delete(threadId);\n remember(this.runEndedAt, threadId, Date.now());\n }\n\n /** Reported once per started run, with the time the run had been going. */\n public runStopped(threadId: string): void {\n const startedAt = this.runStartedAt.get(threadId);\n if (startedAt === undefined) return;\n this.runStartedAt.delete(threadId);\n this.track(\"run_stopped\", threadId, undefined, {\n value: Math.max(0, Date.now() - startedAt),\n });\n }\n\n /** Carries the time since the previous run of the thread ended, when known. */\n public messageSent(\n threadId: string,\n init: {\n messageId?: string | undefined;\n chars: number;\n attachments: number;\n },\n ): void {\n const previousRunEndedAt = this.runEndedAt.get(threadId);\n this.track(\n \"message_sent\",\n threadId,\n init.messageId,\n {\n props: { chars: init.chars, attachments: init.attachments },\n ...(previousRunEndedAt !== undefined\n ? { value: Math.max(0, Date.now() - previousRunEndedAt) }\n : undefined),\n },\n { awaitThread: true },\n );\n }\n\n public messageEdited(\n threadId: string,\n init: { messageId: string; chars: number },\n ): void {\n this.track(\"message_edited\", threadId, init.messageId, {\n props: { chars: init.chars },\n });\n }\n\n public messageRegenerated(threadId: string, messageId?: string): void {\n this.track(\"message_regenerated\", threadId, messageId);\n }\n\n /** Reported once per run, so a retried render of the same error stays one event. */\n public errorShown(\n threadId: string,\n init: { messageId?: string | undefined; reason: string },\n ): void {\n if (this.shownErrors.has(threadId)) return;\n mark(this.shownErrors, threadId);\n this.track(\"error_shown\", threadId, init.messageId, {\n props: { reason: init.reason },\n });\n }\n\n /** Reported once per thread, with the number of suggestions on offer. */\n public suggestionsShown(threadId: string, count: number): void {\n if (this.shownSuggestions.has(threadId)) return;\n mark(this.shownSuggestions, threadId);\n this.track(\"suggestions_shown\", threadId, undefined, { value: count });\n }\n\n public suggestionClicked(threadId: string): void {\n this.track(\"suggestion_clicked\", threadId);\n }\n\n public attachmentAdded(\n threadId: string,\n init: { messageId?: string | undefined; contentType?: string | undefined },\n ): void {\n this.track(\"attachment_added\", threadId, init.messageId, {\n ...(init.contentType ? { props: { type: init.contentType } } : undefined),\n });\n }\n\n public attachmentFailed(\n threadId: string,\n init: { messageId?: string | undefined; contentType?: string | undefined },\n ): void {\n this.track(\"attachment_failed\", threadId, init.messageId, {\n ...(init.contentType ? { props: { type: init.contentType } } : undefined),\n });\n }\n\n public voiceStarted(threadId: string): void {\n this.track(\"voice_started\", threadId);\n }\n\n public speechStarted(threadId: string, messageId?: string): void {\n this.track(\"speech_started\", threadId, messageId);\n }\n\n public branchSwitched(threadId: string, messageId?: string): void {\n this.track(\"branch_switched\", threadId, messageId);\n }\n\n public messageCopied(threadId: string, messageId?: string): void {\n this.track(\"message_copied\", threadId, messageId);\n }\n\n public toolApproved(\n threadId: string,\n messageId: string,\n toolCallId: string,\n toolName: string,\n ): void {\n this.track(\"tool_approved\", threadId, messageId, {\n props: { toolCallId, toolName },\n });\n }\n\n public toolRejected(\n threadId: string,\n messageId: string,\n toolCallId: string,\n toolName: string,\n ): void {\n this.track(\"tool_rejected\", threadId, messageId, {\n props: { toolCallId, toolName },\n });\n }\n\n /** Reported only for a thread the cloud already knows. */\n public threadSwitched(threadId: string): void {\n this.track(\"thread_switched\", threadId);\n }\n\n private track(\n kind: AssistantCloudEventKind,\n threadId: string,\n messageId?: string,\n init: EngagementEventInit = {},\n options: { awaitThread: boolean } = { awaitThread: false },\n ): void {\n void Promise.resolve()\n .then(() => this.resolveIds(threadId, messageId, options))\n .then((ids) => {\n if (kind === \"thread_switched\" && !ids.thread_id) return;\n this.getCloud().events.track({ kind, ...init, ...ids });\n })\n .catch(() => {});\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CloudEngagementReporter.js","names":[],"sources":["../src/CloudEngagementReporter.ts"],"sourcesContent":["import type { AssistantCloud } from \"./AssistantCloud\";\nimport type {\n AssistantCloudEvent,\n AssistantCloudEventKind,\n} from \"./AssistantCloudEvents\";\n\nexport type EngagementEventIds = Pick<\n AssistantCloudEvent,\n \"thread_id\" | \"message_id\" | \"run_id\"\n>;\n\n/**\n * Turns the ids an integration knows (its own thread and message ids) into the\n * ids the cloud stores. A send is the one event that may create the remote\n * thread, so it asks for `awaitThread`; every other event reads the ids that\n * already exist. Returning nothing declines the event: the thread is not one\n * the integration knows, so there is nothing to attribute it to.\n */\nexport type EngagementIdResolver = (\n threadId: string,\n messageId: string | undefined,\n options: { awaitThread: boolean },\n) => EngagementEventIds | undefined | Promise<EngagementEventIds | undefined>;\n\ntype EngagementEventInit = Pick<AssistantCloudEvent, \"value\" | \"props\">;\n\nconst MAX_REMEMBERED_THREADS = 256;\n\nfunction remember<T>(map: Map<string, T>, threadId: string, value: T): void {\n map.delete(threadId);\n map.set(threadId, value);\n if (map.size > MAX_REMEMBERED_THREADS) {\n map.delete(map.keys().next().value!);\n }\n}\n\nfunction mark(set: Set<string>, threadId: string): void {\n set.delete(threadId);\n set.add(threadId);\n if (set.size > MAX_REMEMBERED_THREADS) {\n set.delete(set.values().next().value!);\n }\n}\n\nconst passThroughIds: EngagementIdResolver = (threadId, messageId) => ({\n thread_id: threadId,\n ...(messageId !== undefined ? { message_id: messageId } : undefined),\n});\n\n/**\n * Derives engagement events from what a chat integration observes and keeps\n * the per thread state the events need: a run's start for the stop duration,\n * a run's end for the time to the next message, one error and one suggestion\n * list per run or thread. A started run is kept until it ends or stops; the\n * rest is kept for the 256 most recently touched threads, so a long session\n * does not grow it without bound. Delivery goes through the cloud's event\n * buffer, so a disabled telemetry setting drops everything here as well.\n */\nexport class CloudEngagementReporter {\n private readonly runStartedAt = new Map<string, number>();\n private readonly runEndedAt = new Map<string, number>();\n private readonly shownErrors = new Set<string>();\n private readonly shownSuggestions = new Set<string>();\n\n private readonly getCloud: () => AssistantCloud;\n private readonly resolveIds: EngagementIdResolver;\n\n constructor(\n cloud: AssistantCloud | (() => AssistantCloud),\n resolveIds: EngagementIdResolver = passThroughIds,\n ) {\n this.getCloud = typeof cloud === \"function\" ? cloud : () => cloud;\n this.resolveIds = resolveIds;\n }\n\n public runStarted(threadId: string): void {\n this.runStartedAt.set(threadId, Date.now());\n this.shownErrors.delete(threadId);\n }\n\n public runEnded(threadId: string): void {\n this.runStartedAt.delete(threadId);\n remember(this.runEndedAt, threadId, Date.now());\n }\n\n /** Reported once per started run, with the time the run had been going. */\n public runStopped(threadId: string): void {\n const startedAt = this.runStartedAt.get(threadId);\n if (startedAt === undefined) return;\n const stoppedAt = Date.now();\n this.runStartedAt.delete(threadId);\n // A stopped run is a run that ended, so the next send measures its idle\n // time from here rather than from the last run allowed to finish.\n remember(this.runEndedAt, threadId, stoppedAt);\n this.track(\"run_stopped\", threadId, undefined, {\n value: Math.max(0, stoppedAt - startedAt),\n });\n }\n\n /** Carries the time since the previous run of the thread ended, when known. */\n public messageSent(\n threadId: string,\n init: {\n messageId?: string | undefined;\n chars: number;\n attachments: number;\n },\n ): void {\n const previousRunEndedAt = this.runEndedAt.get(threadId);\n this.track(\n \"message_sent\",\n threadId,\n init.messageId,\n {\n props: { chars: init.chars, attachments: init.attachments },\n ...(previousRunEndedAt !== undefined\n ? { value: Math.max(0, Date.now() - previousRunEndedAt) }\n : undefined),\n },\n { awaitThread: true },\n );\n }\n\n public messageEdited(\n threadId: string,\n init: { messageId: string; chars: number },\n ): void {\n this.track(\"message_edited\", threadId, init.messageId, {\n props: { chars: init.chars },\n });\n }\n\n public messageRegenerated(threadId: string, messageId?: string): void {\n this.track(\"message_regenerated\", threadId, messageId);\n }\n\n /** Reported once per run, so a retried render of the same error stays one event. */\n public errorShown(\n threadId: string,\n init: { messageId?: string | undefined; reason: string },\n ): void {\n if (this.shownErrors.has(threadId)) return;\n mark(this.shownErrors, threadId);\n this.track(\"error_shown\", threadId, init.messageId, {\n props: { reason: init.reason },\n });\n }\n\n /** Reported once per thread, with the number of suggestions on offer. */\n public suggestionsShown(threadId: string, count: number): void {\n if (this.shownSuggestions.has(threadId)) return;\n mark(this.shownSuggestions, threadId);\n this.track(\"suggestions_shown\", threadId, undefined, { value: count });\n }\n\n public suggestionClicked(threadId: string): void {\n this.track(\"suggestion_clicked\", threadId);\n }\n\n public attachmentAdded(\n threadId: string,\n init: { messageId?: string | undefined; contentType?: string | undefined },\n ): void {\n this.track(\"attachment_added\", threadId, init.messageId, {\n ...(init.contentType ? { props: { type: init.contentType } } : undefined),\n });\n }\n\n public attachmentFailed(\n threadId: string,\n init: { messageId?: string | undefined; contentType?: string | undefined },\n ): void {\n this.track(\"attachment_failed\", threadId, init.messageId, {\n ...(init.contentType ? { props: { type: init.contentType } } : undefined),\n });\n }\n\n public voiceStarted(threadId: string): void {\n this.track(\"voice_started\", threadId);\n }\n\n public speechStarted(threadId: string, messageId?: string): void {\n this.track(\"speech_started\", threadId, messageId);\n }\n\n public branchSwitched(threadId: string, messageId?: string): void {\n this.track(\"branch_switched\", threadId, messageId);\n }\n\n public messageCopied(threadId: string, messageId?: string): void {\n this.track(\"message_copied\", threadId, messageId);\n }\n\n public toolApproved(\n threadId: string,\n messageId: string,\n toolCallId: string,\n toolName: string,\n ): void {\n this.track(\"tool_approved\", threadId, messageId, {\n props: { toolCallId, toolName },\n });\n }\n\n public toolRejected(\n threadId: string,\n messageId: string,\n toolCallId: string,\n toolName: string,\n ): void {\n this.track(\"tool_rejected\", threadId, messageId, {\n props: { toolCallId, toolName },\n });\n }\n\n /** Reported only for a thread the cloud already knows. */\n public threadSwitched(threadId: string): void {\n this.track(\"thread_switched\", threadId);\n }\n\n private track(\n kind: AssistantCloudEventKind,\n threadId: string,\n messageId?: string,\n init: EngagementEventInit = {},\n options: { awaitThread: boolean } = { awaitThread: false },\n ): void {\n void Promise.resolve()\n .then(() => this.resolveIds(threadId, messageId, options))\n .then((ids) => {\n if (!ids) return;\n if (kind === \"thread_switched\" && !ids.thread_id) return;\n this.getCloud().events.track({ kind, ...init, ...ids });\n })\n .catch(() => {});\n }\n}\n"],"mappings":"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"}
@@ -1,64 +1,63 @@
1
- import { CloudMessage } from "./AssistantCloudThreadMessages.js";
2
- import { AssistantCloud } from "./AssistantCloud.js";
3
- import { ReadonlyJSONObject } from "assistant-stream/utils";
4
- //#region src/CloudMessagePersistence.d.ts
1
+ import type { ReadonlyJSONObject } from "assistant-stream/utils";
2
+ import type { AssistantCloud } from "./AssistantCloud.js";
3
+ import type { CloudMessage } from "./AssistantCloudThreadMessages.js";
5
4
  /**
6
5
  * Appends, updates and loads cloud messages while mapping local ids to cloud
7
6
  * ids and chaining parent_id. A parent that is still being created is awaited,
8
7
  * so concurrent appends land under the right parent.
9
8
  */
10
9
  export declare class CloudMessagePersistence {
11
- private idMapping;
12
- private getCloud;
13
- constructor(cloud: AssistantCloud);
14
- constructor(getCloud: () => AssistantCloud);
15
- /**
16
- * Persist a message to the cloud.
17
- *
18
- * @param threadId - Remote thread ID
19
- * @param messageId - Local message ID (used for tracking)
20
- * @param parentId - Local parent message ID (or null for first message)
21
- * @param format - Message format (e.g., "aui/v0", "ai-sdk/v6")
22
- * @param content - Message content (format-specific)
23
- */
24
- append(threadId: string, messageId: string, parentId: string | null, format: string, content: ReadonlyJSONObject): Promise<void>;
25
- /**
26
- * Update an already-persisted message in the cloud.
27
- */
28
- update(threadId: string, messageId: string, _format: string, content: ReadonlyJSONObject): Promise<void>;
29
- /**
30
- * Check if a message has been persisted (or is currently being persisted).
31
- */
32
- isPersisted(messageId: string): boolean;
33
- /**
34
- * Get the remote ID for a local message ID (resolved).
35
- * Returns undefined if not persisted.
36
- */
37
- getRemoteId(messageId: string): Promise<string | undefined>;
38
- getResolvedRemoteId(messageId: string): string | undefined;
39
- /**
40
- * Load messages from the cloud and populate the ID mapping.
41
- *
42
- * The list endpoint caps a response at 200 rows, so pages are followed by
43
- * message ID cursor until a short page and concatenated in server order.
44
- *
45
- * The ID mapping is populated so that `isPersisted()` returns true for
46
- * loaded messages, preventing re-persistence of already-stored messages.
47
- *
48
- * A loaded ID that an append already maps keeps the remote ID from that append, and falls back to the loaded ID if the append fails.
49
- *
50
- * @param threadId - Remote thread ID
51
- * @param format - Optional format filter
52
- * @returns Array of cloud messages
53
- */
54
- load(threadId: string, format?: string): Promise<CloudMessage[]>;
55
- /**
56
- * Reset the ID mapping (call when switching threads).
57
- *
58
- * Pending `load()` and `append()` calls are not cancelled and still settle
59
- * normally, but their results no longer populate the ID mapping.
60
- */
61
- reset(): void;
10
+ private idMapping;
11
+ private getCloud;
12
+ constructor(cloud: AssistantCloud);
13
+ constructor(getCloud: () => AssistantCloud);
14
+ /**
15
+ * Persist a message to the cloud.
16
+ *
17
+ * @param threadId - Remote thread ID
18
+ * @param messageId - Local message ID (used for tracking)
19
+ * @param parentId - Local parent message ID (or null for first message)
20
+ * @param format - Message format (e.g., "aui/v0", "ai-sdk/v6")
21
+ * @param content - Message content (format-specific)
22
+ */
23
+ append(threadId: string, messageId: string, parentId: string | null, format: string, content: ReadonlyJSONObject): Promise<void>;
24
+ /**
25
+ * Update an already-persisted message in the cloud.
26
+ */
27
+ update(threadId: string, messageId: string, _format: string, content: ReadonlyJSONObject): Promise<void>;
28
+ /**
29
+ * Check if a message has been persisted (or is currently being persisted).
30
+ */
31
+ isPersisted(messageId: string): boolean;
32
+ /**
33
+ * Get the remote ID for a local message ID (resolved).
34
+ * Returns undefined if not persisted.
35
+ */
36
+ getRemoteId(messageId: string): Promise<string | undefined>;
37
+ getResolvedRemoteId(messageId: string): string | undefined;
38
+ record(localId: string, remoteId: string): void;
39
+ /**
40
+ * Load messages from the cloud and populate the ID mapping.
41
+ *
42
+ * The list endpoint caps a response at 200 rows, so pages are followed by
43
+ * message ID cursor until a short page and concatenated in server order.
44
+ *
45
+ * The ID mapping is populated so that `isPersisted()` returns true for
46
+ * loaded messages, preventing re-persistence of already-stored messages.
47
+ *
48
+ * A loaded ID that an append already maps keeps the remote ID from that append, and falls back to the loaded ID if the append fails.
49
+ *
50
+ * @param threadId - Remote thread ID
51
+ * @param format - Optional format filter
52
+ * @returns Array of cloud messages
53
+ */
54
+ load(threadId: string, format?: string): Promise<CloudMessage[]>;
55
+ /**
56
+ * Reset the ID mapping (call when switching threads).
57
+ *
58
+ * Pending `load()` and `append()` calls are not cancelled and still settle
59
+ * normally, but their results no longer populate the ID mapping.
60
+ */
61
+ reset(): void;
62
62
  }
63
- //#endregion
64
63
  //# sourceMappingURL=CloudMessagePersistence.d.ts.map
@@ -1 +1 @@
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
+ {"version":3,"file":"CloudMessagePersistence.d.ts","sourceRoot":"","sources":["../src/CloudMessagePersistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,4BAAyB;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,0CAAuC;AAInE;;;;GAIG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,KAAK,EAAE,cAAc;gBACrB,QAAQ,EAAE,MAAM,cAAc;IAK1C;;;;;;;;OAQG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC;IAmChB;;OAEG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC;IAYhB;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIvC;;;OAGG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAMjE,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK1D,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI/C;;;;;;;;;;;;;;OAcG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IA6C5C;;;;;OAKG;IACH,KAAK;CAGN"}
@@ -77,6 +77,9 @@ var CloudMessagePersistence = class {
77
77
  const entry = this.idMapping.get(messageId);
78
78
  return typeof entry === "string" ? entry : void 0;
79
79
  }
80
+ record(localId, remoteId) {
81
+ this.idMapping.set(localId, remoteId);
82
+ }
80
83
  /**
81
84
  * Load messages from the cloud and populate the ID mapping.
82
85
  *