assistant-cloud 0.2.0 → 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 (109) hide show
  1. package/README.md +48 -6
  2. package/dist/AssistantCloud.d.ts +3 -3
  3. package/dist/AssistantCloud.d.ts.map +1 -1
  4. package/dist/AssistantCloud.js +2 -0
  5. package/dist/AssistantCloud.js.map +1 -1
  6. package/dist/AssistantCloudAPI.d.ts +14 -6
  7. package/dist/AssistantCloudAPI.d.ts.map +1 -1
  8. package/dist/AssistantCloudAPI.js +17 -1
  9. package/dist/AssistantCloudAPI.js.map +1 -1
  10. package/dist/AssistantCloudAuthStrategy.d.ts +6 -7
  11. package/dist/AssistantCloudAuthStrategy.d.ts.map +1 -1
  12. package/dist/AssistantCloudAuthStrategy.js +4 -2
  13. package/dist/AssistantCloudAuthStrategy.js.map +1 -1
  14. package/dist/AssistantCloudAuthTokens.d.ts +1 -2
  15. package/dist/AssistantCloudAuthTokens.d.ts.map +1 -1
  16. package/dist/AssistantCloudEvents.d.ts +3 -4
  17. package/dist/AssistantCloudEvents.d.ts.map +1 -1
  18. package/dist/AssistantCloudEvents.js +5 -1
  19. package/dist/AssistantCloudEvents.js.map +1 -1
  20. package/dist/AssistantCloudFiles.d.ts +2 -3
  21. package/dist/AssistantCloudFiles.d.ts.map +1 -1
  22. package/dist/AssistantCloudProjectThreadMessages.d.ts +1 -2
  23. package/dist/AssistantCloudProjectThreadMessages.d.ts.map +1 -1
  24. package/dist/AssistantCloudProjectThreads.d.ts +1 -2
  25. package/dist/AssistantCloudProjectThreads.d.ts.map +1 -1
  26. package/dist/AssistantCloudProjects.d.ts +1 -2
  27. package/dist/AssistantCloudProjects.d.ts.map +1 -1
  28. package/dist/AssistantCloudRuns.d.ts +3 -3
  29. package/dist/AssistantCloudRuns.d.ts.map +1 -1
  30. package/dist/AssistantCloudRuns.js +2 -1
  31. package/dist/AssistantCloudRuns.js.map +1 -1
  32. package/dist/AssistantCloudScores.d.ts +3 -4
  33. package/dist/AssistantCloudScores.d.ts.map +1 -1
  34. package/dist/AssistantCloudThreadMessages.d.ts +7 -6
  35. package/dist/AssistantCloudThreadMessages.d.ts.map +1 -1
  36. package/dist/AssistantCloudThreadMessages.js +7 -2
  37. package/dist/AssistantCloudThreadMessages.js.map +1 -1
  38. package/dist/AssistantCloudThreads.d.ts +3 -4
  39. package/dist/AssistantCloudThreads.d.ts.map +1 -1
  40. package/dist/CloudEngagementReporter.d.ts +73 -0
  41. package/dist/CloudEngagementReporter.d.ts.map +1 -0
  42. package/dist/CloudEngagementReporter.js +132 -0
  43. package/dist/CloudEngagementReporter.js.map +1 -0
  44. package/dist/CloudMessagePersistence.d.ts +9 -11
  45. package/dist/CloudMessagePersistence.d.ts.map +1 -1
  46. package/dist/CloudMessagePersistence.js +18 -11
  47. package/dist/CloudMessagePersistence.js.map +1 -1
  48. package/dist/CloudRunReporter.d.ts +19 -0
  49. package/dist/CloudRunReporter.d.ts.map +1 -0
  50. package/dist/CloudRunReporter.js +47 -0
  51. package/dist/CloudRunReporter.js.map +1 -0
  52. package/dist/FormattedCloudPersistence.d.ts +5 -11
  53. package/dist/FormattedCloudPersistence.d.ts.map +1 -1
  54. package/dist/FormattedCloudPersistence.js +3 -8
  55. package/dist/FormattedCloudPersistence.js.map +1 -1
  56. package/dist/ai-sdk/index.d.ts +32 -0
  57. package/dist/ai-sdk/index.d.ts.map +1 -0
  58. package/dist/ai-sdk/index.js +147 -0
  59. package/dist/ai-sdk/index.js.map +1 -0
  60. package/dist/cloudResponse.d.ts +12 -13
  61. package/dist/cloudResponse.d.ts.map +1 -1
  62. package/dist/generateThreadTitle.d.ts +1 -2
  63. package/dist/generateThreadTitle.d.ts.map +1 -1
  64. package/dist/generateThreadTitle.js +1 -0
  65. package/dist/generateThreadTitle.js.map +1 -1
  66. package/dist/index.d.ts +5 -3
  67. package/dist/index.js +4 -2
  68. package/dist/instrumentMcpSampling.d.ts +6 -7
  69. package/dist/instrumentMcpSampling.d.ts.map +1 -1
  70. package/dist/instrumentMcpSampling.js +12 -2
  71. package/dist/instrumentMcpSampling.js.map +1 -1
  72. package/dist/runTelemetry.d.ts +30 -15
  73. package/dist/runTelemetry.d.ts.map +1 -1
  74. package/dist/runTelemetry.js.map +1 -1
  75. package/dist/telemetry/index.d.ts +8 -9
  76. package/dist/telemetry/index.d.ts.map +1 -1
  77. package/dist/version.d.ts +4 -0
  78. package/dist/version.d.ts.map +1 -0
  79. package/dist/version.js +6 -0
  80. package/dist/version.js.map +1 -0
  81. package/package.json +24 -10
  82. package/src/AssistantCloud.ts +3 -0
  83. package/src/AssistantCloudAPI.ts +31 -1
  84. package/src/AssistantCloudAuthStrategy.ts +4 -2
  85. package/src/AssistantCloudEvents.test.ts +68 -2
  86. package/src/AssistantCloudEvents.ts +6 -0
  87. package/src/AssistantCloudRuns.ts +1 -0
  88. package/src/AssistantCloudThreadMessages.test.ts +53 -2
  89. package/src/AssistantCloudThreadMessages.ts +13 -1
  90. package/src/CloudEngagementReporter.ts +231 -0
  91. package/src/CloudMessagePersistence.ts +24 -13
  92. package/src/CloudRunReporter.ts +50 -0
  93. package/src/FormattedCloudPersistence.ts +3 -8
  94. package/src/ai-sdk/index.test.ts +258 -0
  95. package/src/ai-sdk/index.ts +222 -0
  96. package/src/generateThreadTitle.test.ts +32 -0
  97. package/src/generateThreadTitle.ts +1 -0
  98. package/src/index.ts +11 -1
  99. package/src/instrumentMcpSampling.test.ts +102 -0
  100. package/src/instrumentMcpSampling.ts +16 -2
  101. package/src/runTelemetry.ts +17 -0
  102. package/src/tests/AssistantCloud.test.ts +33 -1
  103. package/src/tests/AssistantCloudAPI.test.ts +51 -0
  104. package/src/tests/AssistantCloudAuthStrategy.test.ts +22 -0
  105. package/src/tests/AssistantCloudProjects.test.ts +1 -5
  106. package/src/tests/CloudEngagementReporter.test.ts +184 -0
  107. package/src/tests/CloudMessagePersistence.test.ts +235 -0
  108. package/src/tests/CloudRunReporter.test.ts +135 -0
  109. package/src/version.ts +4 -0
@@ -10,12 +10,11 @@ type AssistantCloudProjectThreadsListQuery = {
10
10
  type AssistantCloudProjectThreadsListResponse = {
11
11
  threads: CloudThread[];
12
12
  };
13
- declare class AssistantCloudProjectThreads {
13
+ export declare class AssistantCloudProjectThreads {
14
14
  readonly messages: AssistantCloudProjectThreadMessages;
15
15
  private cloud;
16
16
  constructor(cloud: AssistantCloudAPI);
17
17
  list(query?: AssistantCloudProjectThreadsListQuery): Promise<AssistantCloudProjectThreadsListResponse>;
18
18
  }
19
19
  //#endregion
20
- export { AssistantCloudProjectThreads };
21
20
  //# sourceMappingURL=AssistantCloudProjectThreads.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudProjectThreads.d.ts","names":[],"sources":["../src/AssistantCloudProjectThreads.ts"],"mappings":";;;;KAKK;EACH;EACA;EACA;;KAGG;EACH,SAAS;;cAGE;WACK,UAAU;UAElB;EAEI,YAAA,OAAO;EAKN,KACX,QAAQ,wCACP,QAAQ"}
1
+ {"version":3,"file":"AssistantCloudProjectThreads.d.ts","names":[],"sources":["../src/AssistantCloudProjectThreads.ts"],"mappings":";;;;KAKK;EACH;EACA;EACA;;KAGG;EACH,SAAS;;qBAGE;WACK,UAAU;UAElB;EAEI,YAAA,OAAO;EAKN,KACX,QAAQ,wCACP,QAAQ"}
@@ -1,10 +1,9 @@
1
1
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
2
  import { AssistantCloudProjectThreads } from "./AssistantCloudProjectThreads.js";
3
3
  //#region src/AssistantCloudProjects.d.ts
4
- declare class AssistantCloudProjects {
4
+ export declare class AssistantCloudProjects {
5
5
  readonly threads: AssistantCloudProjectThreads;
6
6
  constructor(cloud: AssistantCloudAPI);
7
7
  }
8
8
  //#endregion
9
- export { AssistantCloudProjects };
10
9
  //# sourceMappingURL=AssistantCloudProjects.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudProjects.d.ts","names":[],"sources":["../src/AssistantCloudProjects.ts"],"mappings":";;;cAGa;WACK,SAAS;EAEb,YAAA,OAAO"}
1
+ {"version":3,"file":"AssistantCloudProjects.d.ts","names":[],"sources":["../src/AssistantCloudProjects.ts"],"mappings":";;;qBAGa;WACK,SAAS;EAEb,YAAA,OAAO"}
@@ -7,7 +7,7 @@ type AssistantCloudRunsStreamBody = {
7
7
  assistant_id: "system/thread_title";
8
8
  messages: readonly unknown[];
9
9
  };
10
- type AssistantCloudRunReport = {
10
+ export type AssistantCloudRunReport = {
11
11
  thread_id: string;
12
12
  status: "completed" | "incomplete" | "error";
13
13
  outcome_type?: "aborted" | "disconnected" | "length" | "content_filter";
@@ -42,13 +42,14 @@ type AssistantCloudRunReport = {
42
42
  output_text?: string;
43
43
  metadata?: Record<string, unknown>;
44
44
  };
45
- declare class AssistantCloudRuns {
45
+ export declare class AssistantCloudRuns {
46
46
  private cloud;
47
47
  constructor(cloud: AssistantCloudAPI);
48
48
  __internal_getAssistantOptions(assistantId: string): {
49
49
  api: string;
50
50
  headers: () => Promise<{
51
51
  Accept: string;
52
+ "Aui-Sdk": string;
52
53
  }>;
53
54
  body: {
54
55
  assistant_id: string;
@@ -62,5 +63,4 @@ declare class AssistantCloudRuns {
62
63
  }>;
63
64
  }
64
65
  //#endregion
65
- export { AssistantCloudRunReport, AssistantCloudRuns };
66
66
  //# sourceMappingURL=AssistantCloudRuns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudRuns.d.ts","names":[],"sources":["../src/AssistantCloudRuns.ts"],"mappings":";;;;KASK;EACH;EACA;EACA;;KAMU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;IACE;IACA;IACA;IACA;IACA,aAAa;IACb;IACA;IACA;;EAEF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;;cAGA;UACH;EAEI,YAAA,OAAO;EAIZ,+BAA+B;;;;;;;;;;;EAmBzB,OACX,MAAM,+BACL,QAAQ;EAkCE,OACX,MAAM,0BACL;IAAU"}
1
+ {"version":3,"file":"AssistantCloudRuns.d.ts","names":[],"sources":["../src/AssistantCloudRuns.ts"],"mappings":";;;;KASK;EACH;EACA;EACA;;YAMU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;IACE;IACA;IACA;IACA;IACA,aAAa;IACb;IACA;IACA;;EAEF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;;qBAGA;UACH;EAEI,YAAA,OAAO;EAIZ,+BAA+B;;;;;;;;;;;;EAoBzB,OACX,MAAM,+BACL,QAAQ;EAkCE,OACX,MAAM,0BACL;IAAU"}
@@ -14,7 +14,8 @@ var AssistantCloudRuns = class {
14
14
  if (!headers) throw new Error("Authorization failed");
15
15
  return {
16
16
  ...headers,
17
- Accept: "text/plain"
17
+ Accept: "text/plain",
18
+ "Aui-Sdk": this.cloud.sdkHeader()
18
19
  };
19
20
  },
20
21
  body: {
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudRuns.js","names":[],"sources":["../src/AssistantCloudRuns.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport type { AssistantCloudRunReportToolCall } from \"./runTelemetry\";\nimport { AssistantStream, PlainTextDecoder } from \"assistant-stream\";\nimport {\n CloudResponseError,\n readCloudRecord,\n readCloudString,\n} from \"./cloudResponse\";\n\ntype AssistantCloudRunsStreamBody = {\n thread_id: string;\n assistant_id: \"system/thread_title\";\n messages: readonly unknown[]; // TODO type\n};\n\n// NOTE: Keep this payload shape aligned with the strict runtime validator in\n// assistant-cloud: apps/api/src/endpoints/runs/create.ts\n// (createRunSchema). New telemetry fields must be added in both repos together.\nexport type AssistantCloudRunReport = {\n thread_id: string;\n status: \"completed\" | \"incomplete\" | \"error\";\n outcome_type?: \"aborted\" | \"disconnected\" | \"length\" | \"content_filter\";\n message_id?: string;\n first_token_ms?: number;\n release?: string;\n environment?: string;\n tags?: string[];\n provider?: string;\n trace_id?: string;\n error_code?: string;\n error?: string;\n total_steps?: number;\n tool_calls?: AssistantCloudRunReportToolCall[];\n steps?: {\n input_tokens?: number;\n output_tokens?: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n tool_calls?: AssistantCloudRunReportToolCall[];\n start_ms?: number;\n end_ms?: number;\n finish_reason?: string;\n }[];\n input_tokens?: number;\n output_tokens?: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n model_id?: string;\n provider_type?: string;\n duration_ms?: number;\n output_text?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport class AssistantCloudRuns {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public __internal_getAssistantOptions(assistantId: string) {\n return {\n api: `${this.cloud._baseUrl}/v1/runs/stream`,\n headers: async () => {\n const headers = await this.cloud._auth.getAuthHeaders();\n if (!headers) throw new Error(\"Authorization failed\");\n return {\n ...headers,\n Accept: \"text/plain\",\n };\n },\n body: {\n assistant_id: assistantId,\n response_format: \"vercel-ai-data-stream/v1\",\n thread_id: \"unstable_todo\",\n },\n };\n }\n\n public async stream(\n body: AssistantCloudRunsStreamBody,\n ): Promise<AssistantStream> {\n const response = await this.cloud.makeRawRequest(\"/runs/stream\", {\n method: \"POST\",\n headers: {\n Accept: \"text/plain\",\n },\n body,\n });\n\n if (!response.body) {\n throw new CloudResponseError(\n 'Invalid Assistant Cloud response for \"run stream\": expected a response body',\n );\n }\n\n const receivedContentType = response.headers.get(\"content-type\");\n const contentType = receivedContentType\n ?.split(\";\", 1)[0]\n ?.trim()\n .toLowerCase();\n if (contentType !== \"text/plain\") {\n await response.body.cancel().catch(() => undefined);\n throw new CloudResponseError(\n `Invalid Assistant Cloud response for \"run stream\": expected a \"text/plain\" content type, received ${\n receivedContentType\n ? `\"${receivedContentType}\"`\n : \"no Content-Type header\"\n }`,\n );\n }\n\n return AssistantStream.fromResponse(response, new PlainTextDecoder());\n }\n\n public async report(\n body: AssistantCloudRunReport,\n ): Promise<{ run_id: string }> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\"/runs\", { method: \"POST\", body }),\n \"run report response\",\n );\n\n return { run_id: readCloudString(response.run_id, \"run_id\") };\n }\n}\n"],"mappings":";;;AAsDA,IAAa,qBAAb,MAAgC;CAC9B;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,+BAAsC,aAAqB;EACzD,OAAO;GACL,KAAK,GAAG,KAAK,MAAM,SAAS;GAC5B,SAAS,YAAY;IACnB,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,eAAe;IACtD,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,sBAAsB;IACpD,OAAO;KACL,GAAG;KACH,QAAQ;IACV;GACF;GACA,MAAM;IACJ,cAAc;IACd,iBAAiB;IACjB,WAAW;GACb;EACF;CACF;CAEA,MAAa,OACX,MAC0B;EAC1B,MAAM,WAAW,MAAM,KAAK,MAAM,eAAe,gBAAgB;GAC/D,QAAQ;GACR,SAAS,EACP,QAAQ,aACV;GACA;EACF,CAAC;EAED,IAAI,CAAC,SAAS,MACZ,MAAM,IAAI,mBACR,+EACF;EAGF,MAAM,sBAAsB,SAAS,QAAQ,IAAI,cAAc;EAK/D,IAJoB,qBAChB,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,EAChB,KAAK,CAAC,CACP,YAAY,MACK,cAAc;GAChC,MAAM,SAAS,KAAK,OAAO,CAAC,CAAC,YAAY,KAAA,CAAS;GAClD,MAAM,IAAI,mBACR,qGACE,sBACI,IAAI,oBAAoB,KACxB,0BAER;EACF;EAEA,OAAO,gBAAgB,aAAa,UAAU,IAAI,iBAAiB,CAAC;CACtE;CAEA,MAAa,OACX,MAC6B;EAC7B,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,SAAS;GAAE,QAAQ;GAAQ;EAAK,CAAC,GAC9D,qBACF;EAEA,OAAO,EAAE,QAAQ,gBAAgB,SAAS,QAAQ,QAAQ,EAAE;CAC9D;AACF"}
1
+ {"version":3,"file":"AssistantCloudRuns.js","names":[],"sources":["../src/AssistantCloudRuns.ts"],"sourcesContent":["import type { AssistantCloudAPI } from \"./AssistantCloudAPI\";\nimport type { AssistantCloudRunReportToolCall } from \"./runTelemetry\";\nimport { AssistantStream, PlainTextDecoder } from \"assistant-stream\";\nimport {\n CloudResponseError,\n readCloudRecord,\n readCloudString,\n} from \"./cloudResponse\";\n\ntype AssistantCloudRunsStreamBody = {\n thread_id: string;\n assistant_id: \"system/thread_title\";\n messages: readonly unknown[]; // TODO type\n};\n\n// NOTE: Keep this payload shape aligned with the strict runtime validator in\n// assistant-cloud: apps/api/src/endpoints/runs/create.ts\n// (createRunSchema). New telemetry fields must be added in both repos together.\nexport type AssistantCloudRunReport = {\n thread_id: string;\n status: \"completed\" | \"incomplete\" | \"error\";\n outcome_type?: \"aborted\" | \"disconnected\" | \"length\" | \"content_filter\";\n message_id?: string;\n first_token_ms?: number;\n release?: string;\n environment?: string;\n tags?: string[];\n provider?: string;\n trace_id?: string;\n error_code?: string;\n error?: string;\n total_steps?: number;\n tool_calls?: AssistantCloudRunReportToolCall[];\n steps?: {\n input_tokens?: number;\n output_tokens?: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n tool_calls?: AssistantCloudRunReportToolCall[];\n start_ms?: number;\n end_ms?: number;\n finish_reason?: string;\n }[];\n input_tokens?: number;\n output_tokens?: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n model_id?: string;\n provider_type?: string;\n duration_ms?: number;\n output_text?: string;\n metadata?: Record<string, unknown>;\n};\n\nexport class AssistantCloudRuns {\n private cloud: AssistantCloudAPI;\n\n constructor(cloud: AssistantCloudAPI) {\n this.cloud = cloud;\n }\n\n public __internal_getAssistantOptions(assistantId: string) {\n return {\n api: `${this.cloud._baseUrl}/v1/runs/stream`,\n headers: async () => {\n const headers = await this.cloud._auth.getAuthHeaders();\n if (!headers) throw new Error(\"Authorization failed\");\n return {\n ...headers,\n Accept: \"text/plain\",\n \"Aui-Sdk\": this.cloud.sdkHeader(),\n };\n },\n body: {\n assistant_id: assistantId,\n response_format: \"vercel-ai-data-stream/v1\",\n thread_id: \"unstable_todo\",\n },\n };\n }\n\n public async stream(\n body: AssistantCloudRunsStreamBody,\n ): Promise<AssistantStream> {\n const response = await this.cloud.makeRawRequest(\"/runs/stream\", {\n method: \"POST\",\n headers: {\n Accept: \"text/plain\",\n },\n body,\n });\n\n if (!response.body) {\n throw new CloudResponseError(\n 'Invalid Assistant Cloud response for \"run stream\": expected a response body',\n );\n }\n\n const receivedContentType = response.headers.get(\"content-type\");\n const contentType = receivedContentType\n ?.split(\";\", 1)[0]\n ?.trim()\n .toLowerCase();\n if (contentType !== \"text/plain\") {\n await response.body.cancel().catch(() => undefined);\n throw new CloudResponseError(\n `Invalid Assistant Cloud response for \"run stream\": expected a \"text/plain\" content type, received ${\n receivedContentType\n ? `\"${receivedContentType}\"`\n : \"no Content-Type header\"\n }`,\n );\n }\n\n return AssistantStream.fromResponse(response, new PlainTextDecoder());\n }\n\n public async report(\n body: AssistantCloudRunReport,\n ): Promise<{ run_id: string }> {\n const response = readCloudRecord(\n await this.cloud.makeRequest(\"/runs\", { method: \"POST\", body }),\n \"run report response\",\n );\n\n return { run_id: readCloudString(response.run_id, \"run_id\") };\n }\n}\n"],"mappings":";;;AAsDA,IAAa,qBAAb,MAAgC;CAC9B;CAEA,YAAY,OAA0B;EACpC,KAAK,QAAQ;CACf;CAEA,+BAAsC,aAAqB;EACzD,OAAO;GACL,KAAK,GAAG,KAAK,MAAM,SAAS;GAC5B,SAAS,YAAY;IACnB,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,eAAe;IACtD,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,sBAAsB;IACpD,OAAO;KACL,GAAG;KACH,QAAQ;KACR,WAAW,KAAK,MAAM,UAAU;IAClC;GACF;GACA,MAAM;IACJ,cAAc;IACd,iBAAiB;IACjB,WAAW;GACb;EACF;CACF;CAEA,MAAa,OACX,MAC0B;EAC1B,MAAM,WAAW,MAAM,KAAK,MAAM,eAAe,gBAAgB;GAC/D,QAAQ;GACR,SAAS,EACP,QAAQ,aACV;GACA;EACF,CAAC;EAED,IAAI,CAAC,SAAS,MACZ,MAAM,IAAI,mBACR,+EACF;EAGF,MAAM,sBAAsB,SAAS,QAAQ,IAAI,cAAc;EAK/D,IAJoB,qBAChB,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,EAChB,KAAK,CAAC,CACP,YAAY,MACK,cAAc;GAChC,MAAM,SAAS,KAAK,OAAO,CAAC,CAAC,YAAY,KAAA,CAAS;GAClD,MAAM,IAAI,mBACR,qGACE,sBACI,IAAI,oBAAoB,KACxB,0BAER;EACF;EAEA,OAAO,gBAAgB,aAAa,UAAU,IAAI,iBAAiB,CAAC;CACtE;CAEA,MAAa,OACX,MAC6B;EAC7B,MAAM,WAAW,gBACf,MAAM,KAAK,MAAM,YAAY,SAAS;GAAE,QAAQ;GAAQ;EAAK,CAAC,GAC9D,qBACF;EAEA,OAAO,EAAE,QAAQ,gBAAgB,SAAS,QAAQ,QAAQ,EAAE;CAC9D;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
2
  //#region src/AssistantCloudScores.d.ts
3
- type AssistantCloudScoreBody = {
3
+ export type AssistantCloudScoreBody = {
4
4
  name: string;
5
5
  data_type: "numeric" | "categorical" | "boolean";
6
6
  value?: number | boolean;
@@ -10,18 +10,17 @@ type AssistantCloudScoreBody = {
10
10
  message_id?: string;
11
11
  run_id?: string;
12
12
  };
13
- type AssistantCloudScoreResponse = {
13
+ export type AssistantCloudScoreResponse = {
14
14
  score_id: string;
15
15
  name: string;
16
16
  data_type: "numeric" | "categorical" | "boolean";
17
17
  value: number | null;
18
18
  string_value: string | null;
19
19
  };
20
- declare class AssistantCloudScores {
20
+ export declare class AssistantCloudScores {
21
21
  private cloud;
22
22
  constructor(cloud: AssistantCloudAPI);
23
23
  create(body: AssistantCloudScoreBody): Promise<AssistantCloudScoreResponse>;
24
24
  }
25
25
  //#endregion
26
- export { AssistantCloudScoreBody, AssistantCloudScoreResponse, AssistantCloudScores };
27
26
  //# sourceMappingURL=AssistantCloudScores.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudScores.d.ts","names":[],"sources":["../src/AssistantCloudScores.ts"],"mappings":";;KAWY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU;EACV;EACA;EACA;EACA;EACA;;cAGW;UACH;EAEI,YAAA,OAAO;EAIN,OACX,MAAM,0BACL,QAAQ"}
1
+ {"version":3,"file":"AssistantCloudScores.d.ts","names":[],"sources":["../src/AssistantCloudScores.ts"],"mappings":";;YAWY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;YAGU;EACV;EACA;EACA;EACA;EACA;;qBAGW;UACH;EAEI,YAAA,OAAO;EAIN,OACX,MAAM,0BACL,QAAQ"}
@@ -1,7 +1,7 @@
1
1
  import { AssistantCloudAPI } from "./AssistantCloudAPI.js";
2
2
  import { ReadonlyJSONObject } from "assistant-stream/utils";
3
3
  //#region src/AssistantCloudThreadMessages.d.ts
4
- type CloudMessage = {
4
+ export type CloudMessage = {
5
5
  id: string;
6
6
  parent_id: string | null;
7
7
  height: number;
@@ -29,15 +29,17 @@ type AssistantCloudMessageCreateResponse = {
29
29
  type AssistantCloudThreadMessageUpdateBody = {
30
30
  content: ReadonlyJSONObject;
31
31
  };
32
- type AssistantCloudThreadMessageFeedbackBody = {
32
+ export type AssistantCloudThreadMessageFeedbackBody = {
33
33
  type: "positive" | "negative";
34
+ comment?: string;
34
35
  };
35
- type AssistantCloudThreadMessageFeedbackResponse = {
36
+ export type AssistantCloudThreadMessageFeedbackResponse = {
36
37
  feedback_id: string;
37
38
  type: "positive" | "negative";
39
+ comment?: string | null;
38
40
  };
39
- declare const decodeCloudMessage: (value: unknown, field: string) => CloudMessage;
40
- declare class AssistantCloudThreadMessages {
41
+ export declare const decodeCloudMessage: (value: unknown, field: string) => CloudMessage;
42
+ export declare class AssistantCloudThreadMessages {
41
43
  private cloud;
42
44
  constructor(cloud: AssistantCloudAPI);
43
45
  list(threadId: string, query?: AssistantCloudThreadMessageListQuery): Promise<AssistantCloudThreadMessageListResponse>;
@@ -46,5 +48,4 @@ declare class AssistantCloudThreadMessages {
46
48
  feedback(threadId: string, messageId: string, body: AssistantCloudThreadMessageFeedbackBody): Promise<AssistantCloudThreadMessageFeedbackResponse>;
47
49
  }
48
50
  //#endregion
49
- export { AssistantCloudThreadMessageFeedbackBody, AssistantCloudThreadMessageFeedbackResponse, AssistantCloudThreadMessages, CloudMessage, decodeCloudMessage };
50
51
  //# sourceMappingURL=AssistantCloudThreadMessages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreadMessages.d.ts","names":[],"sources":["../src/AssistantCloudThreadMessages.ts"],"mappings":";;;KAaY;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;;KAKC;EACV;;KAGU;EACV;EACA;;cAGW,qBACX,gBACA,kBACC;cAaU;UACH;EAEI,YAAA,OAAO;EAIN,KACX,kBACA,QAAQ,uCACP,QAAQ;EAiBE,OACX,kBACA,MAAM,wCACL,QAAQ;EAcE,OACX,kBACA,mBACA,MAAM,wCACL;EAOU,SACX,kBACA,mBACA,MAAM,0CACL,QAAQ"}
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"}
@@ -36,13 +36,18 @@ var AssistantCloudThreadMessages = class {
36
36
  });
37
37
  }
38
38
  async feedback(threadId, messageId, body) {
39
+ const comment = body.comment?.trim();
39
40
  const response = readCloudRecord(await this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/feedback`, {
40
41
  method: "POST",
41
- body
42
+ body: {
43
+ type: body.type,
44
+ ...comment ? { comment } : void 0
45
+ }
42
46
  }), "thread message feedback response");
43
47
  return {
44
48
  feedback_id: readCloudString(response.feedback_id, "feedback_id"),
45
- type: readCloudEnum(response.type, "type", MESSAGE_FEEDBACK_TYPES)
49
+ type: readCloudEnum(response.type, "type", MESSAGE_FEEDBACK_TYPES),
50
+ ..."comment" in response ? { comment: readCloudNullableString(response.comment, "comment") } : void 0
46
51
  };
47
52
  }
48
53
  };
@@ -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};\n\nexport type AssistantCloudThreadMessageFeedbackResponse = {\n feedback_id: string;\n type: \"positive\" | \"negative\";\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 response = readCloudRecord(\n await this.cloud.makeRequest(\n `/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/feedback`,\n { method: \"POST\", body },\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 };\n }\n}\n"],"mappings":";;AA+CA,MAAM,yBAAyB,CAAC,YAAY,UAAU;AAWtD,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,WAAW,gBACf,MAAM,KAAK,MAAM,YACf,YAAY,mBAAmB,QAAQ,EAAE,YAAY,mBAAmB,SAAS,EAAE,YACnF;GAAE,QAAQ;GAAQ;EAAK,CACzB,GACA,kCACF;EAEA,OAAO;GACL,aAAa,gBAAgB,SAAS,aAAa,aAAa;GAChE,MAAM,cAAc,SAAS,MAAM,QAAQ,sBAAsB;EACnE;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};\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"}
@@ -6,7 +6,7 @@ type AssistantCloudThreadsListQuery = {
6
6
  limit?: number;
7
7
  after?: string;
8
8
  };
9
- type CloudThread = {
9
+ export type CloudThread = {
10
10
  title: string;
11
11
  last_message_at: Date;
12
12
  metadata: unknown;
@@ -42,8 +42,8 @@ type AssistantCloudThreadsUpdateBody = {
42
42
  metadata?: unknown | undefined;
43
43
  is_archived?: boolean | undefined;
44
44
  };
45
- declare const decodeCloudThread: (value: unknown, field: string) => CloudThread;
46
- declare class AssistantCloudThreads {
45
+ export declare const decodeCloudThread: (value: unknown, field: string) => CloudThread;
46
+ export declare class AssistantCloudThreads {
47
47
  readonly messages: AssistantCloudThreadMessages;
48
48
  private cloud;
49
49
  constructor(cloud: AssistantCloudAPI);
@@ -56,5 +56,4 @@ declare class AssistantCloudThreads {
56
56
  delete(threadId: string): Promise<void>;
57
57
  }
58
58
  //#endregion
59
- export { AssistantCloudThreads, CloudThread, decodeCloudThread };
60
59
  //# sourceMappingURL=AssistantCloudThreads.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantCloudThreads.d.ts","names":[],"sources":["../src/AssistantCloudThreads.ts"],"mappings":";;;KAYK;EACH;EACA;EACA;;KAGU;EACV;EACA,iBAAiB;EACjB;EACA;EACA;EACA;EACA,YAAY;EACZ,YAAY;EACZ;EACA;;KAGG;EACH,SAAS;;KAGN;EACH;EACA,iBAAiB;EACjB;EACA;;KAGG;EACH;;KAGG;EACH;;KAGG;EACH;;KAGG;EACH;EACA,kBAAkB;EAClB;EACA;;cAGW,oBACX,gBACA,kBACC;cAsBU;WACK,UAAU;UAElB;EAEI,YAAA,OAAO;EAKN,KACX,QAAQ,iCACP,QAAQ;EAkBE,IAAI,mBAAmB,QAAQ;EAS/B,OACX,MAAM,kCACL,QAAQ;EASE,OACX,kBACA,MAAM,kCACL;;EAQU,MACX,MAAM,iCACL,QAAQ;EASE,OAAO,mBAAmB"}
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"}
@@ -0,0 +1,73 @@
1
+ import { AssistantCloudEvent } from "./AssistantCloudEvents.js";
2
+ import { AssistantCloud } from "./AssistantCloud.js";
3
+ //#region src/CloudEngagementReporter.d.ts
4
+ export type EngagementEventIds = Pick<AssistantCloudEvent, "thread_id" | "message_id" | "run_id">;
5
+ /**
6
+ * Turns the ids an integration knows (its own thread and message ids) into the
7
+ * ids the cloud stores. A send is the one event that may create the remote
8
+ * thread, so it asks for `awaitThread`; every other event reads the ids that
9
+ * already exist.
10
+ */
11
+ export type EngagementIdResolver = (threadId: string, messageId: string | undefined, options: {
12
+ awaitThread: boolean;
13
+ }) => EngagementEventIds | Promise<EngagementEventIds>;
14
+ /**
15
+ * Derives engagement events from what a chat integration observes and keeps
16
+ * the per thread state the events need: a run's start for the stop duration,
17
+ * a run's end for the time to the next message, one error and one suggestion
18
+ * list per run or thread. A started run is kept until it ends or stops; the
19
+ * rest is kept for the 256 most recently touched threads, so a long session
20
+ * does not grow it without bound. Delivery goes through the cloud's event
21
+ * buffer, so a disabled telemetry setting drops everything here as well.
22
+ */
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;
71
+ }
72
+ //#endregion
73
+ //# sourceMappingURL=CloudEngagementReporter.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,132 @@
1
+ //#region src/CloudEngagementReporter.ts
2
+ const MAX_REMEMBERED_THREADS = 256;
3
+ function remember(map, threadId, value) {
4
+ map.delete(threadId);
5
+ map.set(threadId, value);
6
+ if (map.size > MAX_REMEMBERED_THREADS) map.delete(map.keys().next().value);
7
+ }
8
+ function mark(set, threadId) {
9
+ set.delete(threadId);
10
+ set.add(threadId);
11
+ if (set.size > MAX_REMEMBERED_THREADS) set.delete(set.values().next().value);
12
+ }
13
+ const passThroughIds = (threadId, messageId) => ({
14
+ thread_id: threadId,
15
+ ...messageId !== void 0 ? { message_id: messageId } : void 0
16
+ });
17
+ /**
18
+ * Derives engagement events from what a chat integration observes and keeps
19
+ * the per thread state the events need: a run's start for the stop duration,
20
+ * a run's end for the time to the next message, one error and one suggestion
21
+ * list per run or thread. A started run is kept until it ends or stops; the
22
+ * rest is kept for the 256 most recently touched threads, so a long session
23
+ * does not grow it without bound. Delivery goes through the cloud's event
24
+ * buffer, so a disabled telemetry setting drops everything here as well.
25
+ */
26
+ var CloudEngagementReporter = class {
27
+ runStartedAt = /* @__PURE__ */ new Map();
28
+ runEndedAt = /* @__PURE__ */ new Map();
29
+ shownErrors = /* @__PURE__ */ new Set();
30
+ shownSuggestions = /* @__PURE__ */ new Set();
31
+ getCloud;
32
+ resolveIds;
33
+ constructor(cloud, resolveIds = passThroughIds) {
34
+ this.getCloud = typeof cloud === "function" ? cloud : () => cloud;
35
+ this.resolveIds = resolveIds;
36
+ }
37
+ runStarted(threadId) {
38
+ this.runStartedAt.set(threadId, Date.now());
39
+ this.shownErrors.delete(threadId);
40
+ }
41
+ runEnded(threadId) {
42
+ this.runStartedAt.delete(threadId);
43
+ remember(this.runEndedAt, threadId, Date.now());
44
+ }
45
+ /** Reported once per started run, with the time the run had been going. */
46
+ runStopped(threadId) {
47
+ const startedAt = this.runStartedAt.get(threadId);
48
+ if (startedAt === void 0) return;
49
+ this.runStartedAt.delete(threadId);
50
+ this.track("run_stopped", threadId, void 0, { value: Math.max(0, Date.now() - startedAt) });
51
+ }
52
+ /** Carries the time since the previous run of the thread ended, when known. */
53
+ messageSent(threadId, init) {
54
+ const previousRunEndedAt = this.runEndedAt.get(threadId);
55
+ this.track("message_sent", threadId, init.messageId, {
56
+ props: {
57
+ chars: init.chars,
58
+ attachments: init.attachments
59
+ },
60
+ ...previousRunEndedAt !== void 0 ? { value: Math.max(0, Date.now() - previousRunEndedAt) } : void 0
61
+ }, { awaitThread: true });
62
+ }
63
+ messageEdited(threadId, init) {
64
+ this.track("message_edited", threadId, init.messageId, { props: { chars: init.chars } });
65
+ }
66
+ messageRegenerated(threadId, messageId) {
67
+ this.track("message_regenerated", threadId, messageId);
68
+ }
69
+ /** Reported once per run, so a retried render of the same error stays one event. */
70
+ errorShown(threadId, init) {
71
+ if (this.shownErrors.has(threadId)) return;
72
+ mark(this.shownErrors, threadId);
73
+ this.track("error_shown", threadId, init.messageId, { props: { reason: init.reason } });
74
+ }
75
+ /** Reported once per thread, with the number of suggestions on offer. */
76
+ suggestionsShown(threadId, count) {
77
+ if (this.shownSuggestions.has(threadId)) return;
78
+ mark(this.shownSuggestions, threadId);
79
+ this.track("suggestions_shown", threadId, void 0, { value: count });
80
+ }
81
+ suggestionClicked(threadId) {
82
+ this.track("suggestion_clicked", threadId);
83
+ }
84
+ attachmentAdded(threadId, init) {
85
+ this.track("attachment_added", threadId, init.messageId, { ...init.contentType ? { props: { type: init.contentType } } : void 0 });
86
+ }
87
+ attachmentFailed(threadId, init) {
88
+ this.track("attachment_failed", threadId, init.messageId, { ...init.contentType ? { props: { type: init.contentType } } : void 0 });
89
+ }
90
+ voiceStarted(threadId) {
91
+ this.track("voice_started", threadId);
92
+ }
93
+ speechStarted(threadId, messageId) {
94
+ this.track("speech_started", threadId, messageId);
95
+ }
96
+ branchSwitched(threadId, messageId) {
97
+ this.track("branch_switched", threadId, messageId);
98
+ }
99
+ messageCopied(threadId, messageId) {
100
+ this.track("message_copied", threadId, messageId);
101
+ }
102
+ toolApproved(threadId, messageId, toolCallId, toolName) {
103
+ this.track("tool_approved", threadId, messageId, { props: {
104
+ toolCallId,
105
+ toolName
106
+ } });
107
+ }
108
+ toolRejected(threadId, messageId, toolCallId, toolName) {
109
+ this.track("tool_rejected", threadId, messageId, { props: {
110
+ toolCallId,
111
+ toolName
112
+ } });
113
+ }
114
+ /** Reported only for a thread the cloud already knows. */
115
+ threadSwitched(threadId) {
116
+ this.track("thread_switched", threadId);
117
+ }
118
+ track(kind, threadId, messageId, init = {}, options = { awaitThread: false }) {
119
+ Promise.resolve().then(() => this.resolveIds(threadId, messageId, options)).then((ids) => {
120
+ if (kind === "thread_switched" && !ids.thread_id) return;
121
+ this.getCloud().events.track({
122
+ kind,
123
+ ...init,
124
+ ...ids
125
+ });
126
+ }).catch(() => {});
127
+ }
128
+ };
129
+ //#endregion
130
+ export { CloudEngagementReporter };
131
+
132
+ //# sourceMappingURL=CloudEngagementReporter.js.map
@@ -0,0 +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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"}
@@ -3,17 +3,11 @@ import { AssistantCloud } from "./AssistantCloud.js";
3
3
  import { ReadonlyJSONObject } from "assistant-stream/utils";
4
4
  //#region src/CloudMessagePersistence.d.ts
5
5
  /**
6
- * Shared persistence logic for cloud message storage.
7
- *
8
- * Handles ID mapping (local → remote) and parent_id chaining for both:
9
- * - AssistantCloudThreadHistoryAdapter (assistant-ui runtime)
10
- * - useCloudChat (standalone AI SDK hook)
11
- *
12
- * The promise-based ID resolution handles concurrent appends — if message B's
13
- * parent is message A, and A is still being created, we await A's promise
14
- * to get its remote ID before creating B.
6
+ * Appends, updates and loads cloud messages while mapping local ids to cloud
7
+ * ids and chaining parent_id. A parent that is still being created is awaited,
8
+ * so concurrent appends land under the right parent.
15
9
  */
16
- declare class CloudMessagePersistence {
10
+ export declare class CloudMessagePersistence {
17
11
  private idMapping;
18
12
  private getCloud;
19
13
  constructor(cloud: AssistantCloud);
@@ -51,6 +45,8 @@ declare class CloudMessagePersistence {
51
45
  * The ID mapping is populated so that `isPersisted()` returns true for
52
46
  * loaded messages, preventing re-persistence of already-stored messages.
53
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
+ *
54
50
  * @param threadId - Remote thread ID
55
51
  * @param format - Optional format filter
56
52
  * @returns Array of cloud messages
@@ -58,9 +54,11 @@ declare class CloudMessagePersistence {
58
54
  load(threadId: string, format?: string): Promise<CloudMessage[]>;
59
55
  /**
60
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.
61
60
  */
62
61
  reset(): void;
63
62
  }
64
63
  //#endregion
65
- export { CloudMessagePersistence };
66
64
  //# sourceMappingURL=CloudMessagePersistence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CloudMessagePersistence.d.ts","names":[],"sources":["../src/CloudMessagePersistence.ts"],"mappings":";;;;;;;;;;;;;;;cAiBa;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;;;;;;;;;;;;;;EAkBd,KAAK,kBAAkB,kBAAe,QAAA;;;;EAoC5C"}
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,15 +1,9 @@
1
1
  //#region src/CloudMessagePersistence.ts
2
2
  const CLOUD_MESSAGE_PAGE_SIZE = 200;
3
3
  /**
4
- * Shared persistence logic for cloud message storage.
5
- *
6
- * Handles ID mapping (local → remote) and parent_id chaining for both:
7
- * - AssistantCloudThreadHistoryAdapter (assistant-ui runtime)
8
- * - useCloudChat (standalone AI SDK hook)
9
- *
10
- * The promise-based ID resolution handles concurrent appends — if message B's
11
- * parent is message A, and A is still being created, we await A's promise
12
- * to get its remote ID before creating B.
4
+ * Appends, updates and loads cloud messages while mapping local ids to cloud
5
+ * ids and chaining parent_id. A parent that is still being created is awaited,
6
+ * so concurrent appends land under the right parent.
13
7
  */
14
8
  var CloudMessagePersistence = class {
15
9
  idMapping = /* @__PURE__ */ new Map();
@@ -92,11 +86,14 @@ var CloudMessagePersistence = class {
92
86
  * The ID mapping is populated so that `isPersisted()` returns true for
93
87
  * loaded messages, preventing re-persistence of already-stored messages.
94
88
  *
89
+ * 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.
90
+ *
95
91
  * @param threadId - Remote thread ID
96
92
  * @param format - Optional format filter
97
93
  * @returns Array of cloud messages
98
94
  */
99
95
  async load(threadId, format) {
96
+ const idMapping = this.idMapping;
100
97
  const cloud = this.getCloud();
101
98
  const messages = [];
102
99
  const seen = /* @__PURE__ */ new Set();
@@ -116,14 +113,24 @@ var CloudMessagePersistence = class {
116
113
  if (page.messages.length < CLOUD_MESSAGE_PAGE_SIZE) break;
117
114
  after = last.id;
118
115
  }
119
- for (const m of messages) this.idMapping.set(m.id, m.id);
116
+ if (this.idMapping === idMapping) for (const m of messages) {
117
+ const entry = idMapping.get(m.id);
118
+ if (entry === void 0) idMapping.set(m.id, m.id);
119
+ else if (entry instanceof Promise) entry.catch(() => {
120
+ const current = idMapping.get(m.id);
121
+ if (current === void 0 || current === entry) idMapping.set(m.id, m.id);
122
+ });
123
+ }
120
124
  return messages;
121
125
  }
122
126
  /**
123
127
  * Reset the ID mapping (call when switching threads).
128
+ *
129
+ * Pending `load()` and `append()` calls are not cancelled and still settle
130
+ * normally, but their results no longer populate the ID mapping.
124
131
  */
125
132
  reset() {
126
- this.idMapping.clear();
133
+ this.idMapping = /* @__PURE__ */ new Map();
127
134
  }
128
135
  };
129
136
  //#endregion