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.
- package/README.md +48 -6
- package/dist/AssistantCloud.d.ts +3 -3
- package/dist/AssistantCloud.d.ts.map +1 -1
- package/dist/AssistantCloud.js +2 -0
- package/dist/AssistantCloud.js.map +1 -1
- package/dist/AssistantCloudAPI.d.ts +14 -6
- package/dist/AssistantCloudAPI.d.ts.map +1 -1
- package/dist/AssistantCloudAPI.js +17 -1
- package/dist/AssistantCloudAPI.js.map +1 -1
- package/dist/AssistantCloudAuthStrategy.d.ts +6 -7
- package/dist/AssistantCloudAuthStrategy.d.ts.map +1 -1
- package/dist/AssistantCloudAuthStrategy.js +4 -2
- package/dist/AssistantCloudAuthStrategy.js.map +1 -1
- package/dist/AssistantCloudAuthTokens.d.ts +1 -2
- package/dist/AssistantCloudAuthTokens.d.ts.map +1 -1
- package/dist/AssistantCloudEvents.d.ts +3 -4
- package/dist/AssistantCloudEvents.d.ts.map +1 -1
- package/dist/AssistantCloudEvents.js +5 -1
- package/dist/AssistantCloudEvents.js.map +1 -1
- package/dist/AssistantCloudFiles.d.ts +2 -3
- package/dist/AssistantCloudFiles.d.ts.map +1 -1
- package/dist/AssistantCloudProjectThreadMessages.d.ts +1 -2
- package/dist/AssistantCloudProjectThreadMessages.d.ts.map +1 -1
- package/dist/AssistantCloudProjectThreads.d.ts +1 -2
- package/dist/AssistantCloudProjectThreads.d.ts.map +1 -1
- package/dist/AssistantCloudProjects.d.ts +1 -2
- package/dist/AssistantCloudProjects.d.ts.map +1 -1
- package/dist/AssistantCloudRuns.d.ts +3 -3
- package/dist/AssistantCloudRuns.d.ts.map +1 -1
- package/dist/AssistantCloudRuns.js +2 -1
- package/dist/AssistantCloudRuns.js.map +1 -1
- package/dist/AssistantCloudScores.d.ts +3 -4
- package/dist/AssistantCloudScores.d.ts.map +1 -1
- package/dist/AssistantCloudThreadMessages.d.ts +7 -6
- package/dist/AssistantCloudThreadMessages.d.ts.map +1 -1
- package/dist/AssistantCloudThreadMessages.js +7 -2
- package/dist/AssistantCloudThreadMessages.js.map +1 -1
- package/dist/AssistantCloudThreads.d.ts +3 -4
- package/dist/AssistantCloudThreads.d.ts.map +1 -1
- package/dist/CloudEngagementReporter.d.ts +73 -0
- package/dist/CloudEngagementReporter.d.ts.map +1 -0
- package/dist/CloudEngagementReporter.js +132 -0
- package/dist/CloudEngagementReporter.js.map +1 -0
- package/dist/CloudMessagePersistence.d.ts +9 -11
- package/dist/CloudMessagePersistence.d.ts.map +1 -1
- package/dist/CloudMessagePersistence.js +18 -11
- package/dist/CloudMessagePersistence.js.map +1 -1
- package/dist/CloudRunReporter.d.ts +19 -0
- package/dist/CloudRunReporter.d.ts.map +1 -0
- package/dist/CloudRunReporter.js +47 -0
- package/dist/CloudRunReporter.js.map +1 -0
- package/dist/FormattedCloudPersistence.d.ts +5 -11
- package/dist/FormattedCloudPersistence.d.ts.map +1 -1
- package/dist/FormattedCloudPersistence.js +3 -8
- package/dist/FormattedCloudPersistence.js.map +1 -1
- package/dist/ai-sdk/index.d.ts +32 -0
- package/dist/ai-sdk/index.d.ts.map +1 -0
- package/dist/ai-sdk/index.js +147 -0
- package/dist/ai-sdk/index.js.map +1 -0
- package/dist/cloudResponse.d.ts +12 -13
- package/dist/cloudResponse.d.ts.map +1 -1
- package/dist/generateThreadTitle.d.ts +1 -2
- package/dist/generateThreadTitle.d.ts.map +1 -1
- package/dist/generateThreadTitle.js +1 -0
- package/dist/generateThreadTitle.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -2
- package/dist/instrumentMcpSampling.d.ts +6 -7
- package/dist/instrumentMcpSampling.d.ts.map +1 -1
- package/dist/instrumentMcpSampling.js +12 -2
- package/dist/instrumentMcpSampling.js.map +1 -1
- package/dist/runTelemetry.d.ts +30 -15
- package/dist/runTelemetry.d.ts.map +1 -1
- package/dist/runTelemetry.js.map +1 -1
- package/dist/telemetry/index.d.ts +8 -9
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/version.d.ts +4 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +24 -10
- package/src/AssistantCloud.ts +3 -0
- package/src/AssistantCloudAPI.ts +31 -1
- package/src/AssistantCloudAuthStrategy.ts +4 -2
- package/src/AssistantCloudEvents.test.ts +68 -2
- package/src/AssistantCloudEvents.ts +6 -0
- package/src/AssistantCloudRuns.ts +1 -0
- package/src/AssistantCloudThreadMessages.test.ts +53 -2
- package/src/AssistantCloudThreadMessages.ts +13 -1
- package/src/CloudEngagementReporter.ts +231 -0
- package/src/CloudMessagePersistence.ts +24 -13
- package/src/CloudRunReporter.ts +50 -0
- package/src/FormattedCloudPersistence.ts +3 -8
- package/src/ai-sdk/index.test.ts +258 -0
- package/src/ai-sdk/index.ts +222 -0
- package/src/generateThreadTitle.test.ts +32 -0
- package/src/generateThreadTitle.ts +1 -0
- package/src/index.ts +11 -1
- package/src/instrumentMcpSampling.test.ts +102 -0
- package/src/instrumentMcpSampling.ts +16 -2
- package/src/runTelemetry.ts +17 -0
- package/src/tests/AssistantCloud.test.ts +33 -1
- package/src/tests/AssistantCloudAPI.test.ts +51 -0
- package/src/tests/AssistantCloudAuthStrategy.test.ts +22 -0
- package/src/tests/AssistantCloudProjects.test.ts +1 -5
- package/src/tests/CloudEngagementReporter.test.ts +184 -0
- package/src/tests/CloudMessagePersistence.test.ts +235 -0
- package/src/tests/CloudRunReporter.test.ts +135 -0
- 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;;
|
|
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":";;;
|
|
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;;
|
|
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"}
|
|
@@ -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;
|
|
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":";;
|
|
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":";;;
|
|
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 {
|
|
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;;
|
|
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
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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":"
|
|
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
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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)
|
|
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
|
|
133
|
+
this.idMapping = /* @__PURE__ */ new Map();
|
|
127
134
|
}
|
|
128
135
|
};
|
|
129
136
|
//#endregion
|