@assistant-ui/core 0.3.18 → 0.3.19
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/dist/adapters/speech.d.ts.map +1 -1
- package/dist/adapters/speech.js +13 -3
- package/dist/adapters/speech.js.map +1 -1
- package/dist/adapters/thread-history.d.ts +4 -0
- package/dist/adapters/thread-history.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +26 -11
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/interactable-composer-metadata.js +11 -9
- package/dist/model-context/interactable-composer-metadata.js.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
- package/dist/react/adapters/LocalStorageThreadListAdapter.js +45 -7
- package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
- package/dist/react/client/DataRenderers.d.ts.map +1 -1
- package/dist/react/client/DataRenderers.js +20 -15
- package/dist/react/client/DataRenderers.js.map +1 -1
- package/dist/react/client/Interactables.d.ts.map +1 -1
- package/dist/react/client/Interactables.js +11 -5
- package/dist/react/client/Interactables.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
- package/dist/react/client/RemoteThreadList.js +3 -2
- package/dist/react/client/RemoteThreadList.js.map +1 -1
- package/dist/react/client/interactable-model-context.d.ts.map +1 -1
- package/dist/react/client/interactable-model-context.js +3 -2
- package/dist/react/client/interactable-model-context.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +2 -2
- package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
- package/dist/react/interactables-legacy/useAssistantInteractable.js +3 -0
- package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -1
- package/dist/react/model-context/useInteractable.d.ts.map +1 -1
- package/dist/react/model-context/useInteractable.js +4 -1
- package/dist/react/model-context/useInteractable.js.map +1 -1
- package/dist/react/model-context/useInteractableVersions.js +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.d.ts +11 -2
- package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js +3 -2
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/part/PartMessages.d.ts +1 -0
- package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
- package/dist/react/primitives/part/PartMessages.js +1 -0
- package/dist/react/primitives/part/PartMessages.js.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
- package/dist/react/primitives/thread/ThreadMessages.js +6 -5
- package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +2 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +2 -24
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +135 -374
- package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -0
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +22 -2
- package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.d.ts +40 -15
- package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/auiV0.js +62 -15
- package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +2 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +4 -0
- package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -1
- package/dist/react/runtimes/cloud/sdkIdentity.d.ts +6 -0
- package/dist/react/runtimes/cloud/sdkIdentity.d.ts.map +1 -0
- package/dist/react/runtimes/cloud/sdkIdentity.js +9 -0
- package/dist/react/runtimes/cloud/sdkIdentity.js.map +1 -0
- package/dist/react/runtimes/external-message-converter.d.ts +12 -2
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +26 -61
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.js +1 -1
- package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
- package/dist/react/utils/groupParts.d.ts +6 -1
- package/dist/react/utils/groupParts.d.ts.map +1 -1
- package/dist/react/utils/groupParts.js +6 -0
- package/dist/react/utils/groupParts.js.map +1 -1
- package/dist/react/utils/useJSONEqual.d.ts +3 -1
- package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
- package/dist/react/utils/useJSONEqual.js +6 -1
- package/dist/react/utils/useJSONEqual.js.map +1 -1
- package/dist/react/utils/useJSONSchemaDependency.d.ts +7 -0
- package/dist/react/utils/useJSONSchemaDependency.d.ts.map +1 -0
- package/dist/react/utils/useJSONSchemaDependency.js +20 -0
- package/dist/react/utils/useJSONSchemaDependency.js.map +1 -0
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/api/thread-runtime.js +2 -5
- package/dist/runtime/api/thread-runtime.js.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -0
- package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-composer-runtime-core.js +46 -10
- package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -0
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js +155 -64
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.d.ts +5 -0
- package/dist/runtime/queue/message-queue.d.ts.map +1 -1
- package/dist/runtime/queue/message-queue.js +61 -6
- package/dist/runtime/queue/message-queue.js.map +1 -1
- package/dist/runtime/utils/auto-status.d.ts +6 -2
- package/dist/runtime/utils/auto-status.d.ts.map +1 -1
- package/dist/runtime/utils/auto-status.js +12 -4
- package/dist/runtime/utils/auto-status.js.map +1 -1
- package/dist/runtime/utils/external-message-conversion.d.ts +16 -4
- package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
- package/dist/runtime/utils/external-message-conversion.js +48 -12
- package/dist/runtime/utils/external-message-conversion.js.map +1 -1
- package/dist/runtime/utils/message-repository.js +3 -3
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtime/utils/thread-message-like.d.ts +2 -1
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js +4 -2
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +8 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/internal.d.ts +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +4 -1
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
- package/dist/store/clients/external-thread.d.ts.map +1 -1
- package/dist/store/clients/external-thread.js +241 -200
- package/dist/store/clients/external-thread.js.map +1 -1
- package/dist/store/clients/thread-tasks.d.ts +13 -0
- package/dist/store/clients/thread-tasks.d.ts.map +1 -0
- package/dist/store/clients/thread-tasks.js +69 -0
- package/dist/store/clients/thread-tasks.js.map +1 -0
- package/dist/store/index.d.ts +3 -2
- package/dist/store/index.js +3 -3
- package/dist/store/primitive-predicates.d.ts.map +1 -1
- package/dist/store/primitive-predicates.js +4 -4
- package/dist/store/primitive-predicates.js.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
- package/dist/store/runtime-clients/thread-runtime-client.js +176 -128
- package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
- package/dist/store/scope-registration.d.ts +2 -0
- package/dist/store/scope-registration.d.ts.map +1 -1
- package/dist/store/scopes/task.d.ts +36 -0
- package/dist/store/scopes/task.d.ts.map +1 -0
- package/dist/store/scopes/task.js +0 -0
- package/dist/store/scopes/thread.d.ts +20 -0
- package/dist/store/scopes/thread.d.ts.map +1 -1
- package/dist/subscribable/subscribable.d.ts +2 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js +23 -15
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/message.d.ts +8 -1
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/abortable-iterable.d.ts.map +1 -1
- package/dist/utils/abortable-iterable.js +30 -14
- package/dist/utils/abortable-iterable.js.map +1 -1
- package/dist/utils/getGroupStatus.d.ts +18 -2
- package/dist/utils/getGroupStatus.d.ts.map +1 -1
- package/dist/utils/getGroupStatus.js +32 -7
- package/dist/utils/getGroupStatus.js.map +1 -1
- package/dist/utils/wire-media.d.ts.map +1 -1
- package/dist/utils/wire-media.js +2 -2
- package/dist/utils/wire-media.js.map +1 -1
- package/package.json +6 -6
- package/src/adapters/speech.test.ts +236 -0
- package/src/adapters/speech.ts +17 -10
- package/src/adapters/thread-history.ts +3 -0
- package/src/index.ts +1 -0
- package/src/model-context/frame/host.test.ts +113 -1
- package/src/model-context/frame/host.ts +39 -12
- package/src/model-context/interactable-composer-metadata.test.ts +30 -0
- package/src/model-context/interactable-composer-metadata.ts +10 -10
- package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +244 -0
- package/src/react/adapters/LocalStorageThreadListAdapter.tsx +104 -7
- package/src/react/client/DataRenderers.test.tsx +45 -0
- package/src/react/client/DataRenderers.ts +13 -9
- package/src/react/client/Interactables.test.ts +44 -1
- package/src/react/client/Interactables.ts +7 -1
- package/src/react/client/RemoteThreadList.test.ts +41 -1
- package/src/react/client/RemoteThreadList.ts +15 -2
- package/src/react/client/interactable-model-context.test.ts +44 -0
- package/src/react/client/interactable-model-context.ts +3 -2
- package/src/react/index.ts +5 -1
- package/src/react/interactables-legacy/useAssistantInteractable.test.tsx +132 -0
- package/src/react/interactables-legacy/useAssistantInteractable.ts +10 -1
- package/src/react/model-context/useInteractable.test.tsx +177 -0
- package/src/react/model-context/useInteractable.ts +3 -0
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +0 -1
- package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +0 -1
- package/src/react/primitives/message/MessageGroupedParts.test.tsx +96 -0
- package/src/react/primitives/message/MessageGroupedParts.tsx +15 -4
- package/src/react/primitives/part/PartMessages.test.tsx +104 -1
- package/src/react/primitives/part/PartMessages.tsx +1 -0
- package/src/react/primitives/thread/ThreadMessages.test.tsx +142 -0
- package/src/react/primitives/thread/ThreadMessages.tsx +8 -5
- package/src/react/providers/ReadonlyThreadProvider.test.tsx +56 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +7 -1
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +20 -14
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +221 -1
- package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +166 -512
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +77 -0
- package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +27 -1
- package/src/react/runtimes/cloud/auiV0.ts +160 -25
- package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +21 -0
- package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +7 -1
- package/src/react/runtimes/cloud/sdkIdentity.ts +9 -0
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +18 -4
- package/src/react/runtimes/external-message-converter.test.ts +136 -1
- package/src/react/runtimes/external-message-converter.ts +39 -93
- package/src/react/runtimes/useRemoteThreadListRuntime.ts +1 -1
- package/src/react/utils/groupParts.ts +12 -1
- package/src/react/utils/useJSONEqual.ts +9 -0
- package/src/react/utils/useJSONSchemaDependency.ts +22 -0
- package/src/runtime/api/thread-runtime.test.ts +58 -0
- package/src/runtime/api/thread-runtime.ts +2 -4
- package/src/runtime/base/base-composer-runtime-core.ts +69 -16
- package/src/runtime/base/base-thread-runtime-core.test.ts +1008 -1
- package/src/runtime/base/base-thread-runtime-core.ts +222 -83
- package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
- package/src/runtime/queue/message-queue.ts +68 -6
- package/src/runtime/utils/auto-status.test.ts +112 -1
- package/src/runtime/utils/auto-status.ts +31 -5
- package/src/runtime/utils/external-message-conversion.test.ts +134 -0
- package/src/runtime/utils/external-message-conversion.ts +122 -31
- package/src/runtime/utils/message-repository.test.ts +49 -0
- package/src/runtime/utils/message-repository.ts +3 -3
- package/src/runtime/utils/thread-message-like.test.ts +52 -0
- package/src/runtime/utils/thread-message-like.ts +4 -0
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +31 -1
- package/src/runtimes/local/local-thread-runtime-core.test.ts +21 -0
- package/src/runtimes/local/local-thread-runtime-core.ts +11 -1
- package/src/runtimes/tool-invocations/EDGE_CASES.md +2 -6
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +133 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +10 -6
- package/src/store/clients/external-thread.ts +19 -1
- package/src/store/clients/thread-tasks.test.ts +274 -0
- package/src/store/clients/thread-tasks.ts +138 -0
- package/src/store/index.ts +8 -0
- package/src/store/primitive-predicates.test.ts +48 -5
- package/src/store/primitive-predicates.ts +7 -2
- package/src/store/runtime-clients/thread-runtime-client.ts +31 -1
- package/src/store/scope-registration.ts +2 -0
- package/src/store/scopes/task.ts +34 -0
- package/src/store/scopes/thread.ts +16 -0
- package/src/store/thread-tasks.test.tsx +209 -0
- package/src/subscribable/subscribable.test.ts +156 -1
- package/src/subscribable/subscribable.ts +25 -15
- package/src/tests/MessageRepository.test.ts +1 -5
- package/src/tests/auiV0Encode.test.ts +300 -0
- package/src/tests/base-composer-runtime-core-send.test.ts +51 -0
- package/src/tests/base-composer-runtime-core.test.ts +314 -2
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +151 -0
- package/src/tests/external-thread-attachments.test.tsx +69 -0
- package/src/tests/external-thread-parity.test.tsx +34 -0
- package/src/tests/groupParts.test.ts +71 -0
- package/src/tests/message-queue.test.ts +253 -0
- package/src/tests/remote-thread-list-reactive-threadId.test.ts +51 -0
- package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +43 -0
- package/src/types/index.ts +1 -0
- package/src/types/message.ts +8 -0
- package/src/utils/abortable-iterable.test.ts +115 -0
- package/src/utils/abortable-iterable.ts +34 -23
- package/src/utils/getGroupStatus.test.ts +70 -4
- package/src/utils/getGroupStatus.ts +35 -12
- package/src/utils/wire-media.test.ts +10 -0
- package/src/utils/wire-media.ts +6 -2
|
@@ -7,24 +7,29 @@ import type {
|
|
|
7
7
|
MessageFormatRepository,
|
|
8
8
|
} from "../../../adapters/thread-history";
|
|
9
9
|
import type { ExportedMessageRepositoryItem } from "../../../runtime/utils/message-repository";
|
|
10
|
+
import type { ThreadMessage } from "../../../types";
|
|
10
11
|
import {
|
|
11
12
|
type AssistantCloud,
|
|
12
13
|
type AssistantCloudEvent,
|
|
13
|
-
|
|
14
|
+
CloudEngagementReporter,
|
|
14
15
|
CloudMessagePersistence,
|
|
16
|
+
CloudRunReporter,
|
|
15
17
|
createFormattedPersistence,
|
|
16
|
-
createRunReport,
|
|
17
18
|
createRunTelemetryToolCall,
|
|
18
19
|
deriveRunOutcome,
|
|
19
20
|
describeRunError,
|
|
20
21
|
extractRunTelemetryModelId,
|
|
21
22
|
normalizeRunTelemetryUsage,
|
|
23
|
+
type RunMessageTelemetry,
|
|
22
24
|
type RunReportOutcome,
|
|
23
25
|
type RunReportStepInit,
|
|
24
|
-
type RunTelemetryUsage,
|
|
25
26
|
type RunTelemetryUsageInit,
|
|
26
27
|
truncateRunTelemetryText,
|
|
27
28
|
} from "assistant-cloud";
|
|
29
|
+
import {
|
|
30
|
+
extractAISDKRunTelemetry,
|
|
31
|
+
type AISDKMessageLike,
|
|
32
|
+
} from "assistant-cloud/ai-sdk";
|
|
28
33
|
import { auiV0Decode, auiV0Encode } from "./auiV0";
|
|
29
34
|
import { type AssistantClient, getClientId, useAui } from "@assistant-ui/store";
|
|
30
35
|
import type { ThreadListItemMethods } from "../../../store/scopes/thread-list-item";
|
|
@@ -43,6 +48,8 @@ const globalPersistence = new WeakMap<
|
|
|
43
48
|
class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
44
49
|
private cloudRef: RefObject<AssistantCloud>;
|
|
45
50
|
private getAui: () => AssistantClient;
|
|
51
|
+
private runReporter: CloudRunReporter;
|
|
52
|
+
public readonly engagementReporter: CloudEngagementReporter;
|
|
46
53
|
|
|
47
54
|
constructor(
|
|
48
55
|
cloudRef: RefObject<AssistantCloud>,
|
|
@@ -50,6 +57,12 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
|
50
57
|
) {
|
|
51
58
|
this.cloudRef = cloudRef;
|
|
52
59
|
this.getAui = getAui;
|
|
60
|
+
this.runReporter = new CloudRunReporter(() => this.cloudRef.current);
|
|
61
|
+
this.engagementReporter = new CloudEngagementReporter(
|
|
62
|
+
() => this.cloudRef.current,
|
|
63
|
+
(threadId, messageId, options) =>
|
|
64
|
+
this.resolveEngagementEventIds(threadId, messageId, options),
|
|
65
|
+
);
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
private get aui(): AssistantClient {
|
|
@@ -215,6 +228,7 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
|
215
228
|
options?: {
|
|
216
229
|
durationMs?: number;
|
|
217
230
|
stepTimestamps?: StepTimestamp[];
|
|
231
|
+
message?: ThreadMessage;
|
|
218
232
|
},
|
|
219
233
|
) {
|
|
220
234
|
const encodedRunMessages = items.map((item) =>
|
|
@@ -225,7 +239,12 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
|
225
239
|
encodedRunMessages,
|
|
226
240
|
options,
|
|
227
241
|
resolvePinned(),
|
|
228
|
-
|
|
242
|
+
mergeRunMessageInfo(
|
|
243
|
+
extractLastRunMessageInfo(items, formatAdapter),
|
|
244
|
+
options?.message
|
|
245
|
+
? extractRunMessageInfo(options.message, "aui/v0")
|
|
246
|
+
: undefined,
|
|
247
|
+
),
|
|
229
248
|
);
|
|
230
249
|
},
|
|
231
250
|
async load(): Promise<MessageFormatRepository<TMessage>> {
|
|
@@ -312,13 +331,15 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
|
312
331
|
threadListItem?: CloudThreadListItem,
|
|
313
332
|
messageInfo?: RunMessageInfo,
|
|
314
333
|
) {
|
|
315
|
-
if (!this.cloudRef.current.telemetry.enabled) return;
|
|
316
|
-
|
|
317
334
|
const item = threadListItem ?? this.aui.threadListItem;
|
|
318
335
|
const remoteId = item.getState().remoteId;
|
|
319
336
|
if (!remoteId) return;
|
|
320
337
|
|
|
321
|
-
const extracted =
|
|
338
|
+
const extracted =
|
|
339
|
+
extractRunTelemetry(format, runMessages) ??
|
|
340
|
+
(messageInfo?.status !== undefined
|
|
341
|
+
? { status: "incomplete" as const }
|
|
342
|
+
: undefined);
|
|
322
343
|
if (!extracted) return;
|
|
323
344
|
|
|
324
345
|
this._sendReport(
|
|
@@ -345,7 +366,7 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
|
345
366
|
|
|
346
367
|
private _sendReport(
|
|
347
368
|
remoteId: string,
|
|
348
|
-
data:
|
|
369
|
+
data: RunMessageTelemetry,
|
|
349
370
|
durationMs?: number,
|
|
350
371
|
stepTimestamps?: StepTimestamp[],
|
|
351
372
|
messageInfo?: RunMessageInfo,
|
|
@@ -355,7 +376,7 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
|
355
376
|
const messageId = messageInfo?.localMessageId
|
|
356
377
|
? persistence.getResolvedRemoteId(messageInfo.localMessageId)
|
|
357
378
|
: undefined;
|
|
358
|
-
|
|
379
|
+
void this.runReporter.report({
|
|
359
380
|
threadId: remoteId,
|
|
360
381
|
status: messageInfo?.status ?? data.status,
|
|
361
382
|
outcome: messageInfo?.outcomeType,
|
|
@@ -365,90 +386,47 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
|
365
386
|
traceId: messageInfo?.traceId,
|
|
366
387
|
modelId: data.modelId,
|
|
367
388
|
provider: messageInfo?.provider,
|
|
368
|
-
usage:
|
|
369
|
-
|
|
370
|
-
outputTokens: data.outputTokens,
|
|
371
|
-
reasoningTokens: data.reasoningTokens,
|
|
372
|
-
cachedInputTokens: data.cachedInputTokens,
|
|
373
|
-
},
|
|
374
|
-
steps: toRunReportSteps(mergedSteps),
|
|
389
|
+
usage: data.usage,
|
|
390
|
+
steps: mergedSteps,
|
|
375
391
|
totalSteps: data.totalSteps,
|
|
376
392
|
toolCalls: data.toolCalls,
|
|
377
393
|
durationMs,
|
|
378
394
|
firstTokenMs: messageInfo?.firstTokenMs,
|
|
379
395
|
outputText: data.outputText,
|
|
380
396
|
metadata: data.metadata,
|
|
381
|
-
telemetry: this.cloudRef.current.telemetry,
|
|
382
397
|
});
|
|
383
|
-
|
|
384
|
-
const { beforeReport } = this.cloudRef.current.telemetry;
|
|
385
|
-
const report = beforeReport ? beforeReport(initial) : initial;
|
|
386
|
-
if (!report) return;
|
|
387
|
-
|
|
388
|
-
this.cloudRef.current.runs.report(report).catch(() => {});
|
|
389
398
|
}
|
|
390
399
|
}
|
|
391
400
|
|
|
392
|
-
type TelemetryStepData = {
|
|
393
|
-
input_tokens?: number;
|
|
394
|
-
output_tokens?: number;
|
|
395
|
-
reasoning_tokens?: number;
|
|
396
|
-
cached_input_tokens?: number;
|
|
397
|
-
tool_calls?: AssistantCloudRunReportToolCall[];
|
|
398
|
-
start_ms?: number;
|
|
399
|
-
end_ms?: number;
|
|
400
|
-
};
|
|
401
|
-
|
|
402
401
|
type StepTimestamp = { start_ms: number; end_ms: number };
|
|
403
402
|
|
|
404
|
-
function toRunReportSteps(
|
|
405
|
-
steps: TelemetryStepData[] | undefined,
|
|
406
|
-
): RunReportStepInit[] | undefined {
|
|
407
|
-
if (!steps) return undefined;
|
|
408
|
-
return steps.map((step) => ({
|
|
409
|
-
usage: {
|
|
410
|
-
inputTokens: step.input_tokens,
|
|
411
|
-
outputTokens: step.output_tokens,
|
|
412
|
-
reasoningTokens: step.reasoning_tokens,
|
|
413
|
-
cachedInputTokens: step.cached_input_tokens,
|
|
414
|
-
},
|
|
415
|
-
toolCalls: step.tool_calls,
|
|
416
|
-
startMs: step.start_ms,
|
|
417
|
-
endMs: step.end_ms,
|
|
418
|
-
}));
|
|
419
|
-
}
|
|
420
|
-
|
|
421
403
|
function mergeStepTimestamps(
|
|
422
|
-
steps:
|
|
404
|
+
steps: RunReportStepInit[] | undefined,
|
|
423
405
|
timestamps: StepTimestamp[] | undefined,
|
|
424
|
-
):
|
|
406
|
+
): RunReportStepInit[] | undefined {
|
|
425
407
|
if (!timestamps) return steps;
|
|
426
|
-
if (!steps)
|
|
408
|
+
if (!steps) {
|
|
409
|
+
return timestamps.map(({ start_ms, end_ms }) => ({
|
|
410
|
+
startMs: start_ms,
|
|
411
|
+
endMs: end_ms,
|
|
412
|
+
}));
|
|
413
|
+
}
|
|
427
414
|
|
|
428
415
|
const len = Math.min(steps.length, timestamps.length);
|
|
429
|
-
return steps.map((
|
|
430
|
-
...
|
|
431
|
-
...(
|
|
416
|
+
return steps.map((step, index) => ({
|
|
417
|
+
...step,
|
|
418
|
+
...(index < len
|
|
419
|
+
? {
|
|
420
|
+
startMs: timestamps[index]!.start_ms,
|
|
421
|
+
endMs: timestamps[index]!.end_ms,
|
|
422
|
+
}
|
|
423
|
+
: undefined),
|
|
432
424
|
}));
|
|
433
425
|
}
|
|
434
426
|
|
|
435
|
-
type TelemetryData = {
|
|
436
|
-
status: "completed" | "incomplete" | "error";
|
|
437
|
-
toolCalls?: AssistantCloudRunReportToolCall[];
|
|
438
|
-
totalSteps?: number;
|
|
439
|
-
inputTokens?: number;
|
|
440
|
-
outputTokens?: number;
|
|
441
|
-
reasoningTokens?: number;
|
|
442
|
-
cachedInputTokens?: number;
|
|
443
|
-
outputText?: string;
|
|
444
|
-
metadata?: Record<string, unknown>;
|
|
445
|
-
steps?: TelemetryStepData[];
|
|
446
|
-
modelId?: string;
|
|
447
|
-
};
|
|
448
|
-
|
|
449
427
|
type RunMessageInfo = {
|
|
450
428
|
localMessageId?: string;
|
|
451
|
-
status?: "error";
|
|
429
|
+
status?: "completed" | "incomplete" | "error";
|
|
452
430
|
outcomeType?: RunReportOutcome;
|
|
453
431
|
error?: string;
|
|
454
432
|
errorCode?: string;
|
|
@@ -476,6 +454,15 @@ function extractLastRunMessageInfo<
|
|
|
476
454
|
return undefined;
|
|
477
455
|
}
|
|
478
456
|
|
|
457
|
+
function mergeRunMessageInfo(
|
|
458
|
+
stored: RunMessageInfo | undefined,
|
|
459
|
+
observed: RunMessageInfo | undefined,
|
|
460
|
+
): RunMessageInfo | undefined {
|
|
461
|
+
if (!observed) return stored;
|
|
462
|
+
const { localMessageId: _observedId, ...outcome } = observed;
|
|
463
|
+
return { ...stored, ...outcome };
|
|
464
|
+
}
|
|
465
|
+
|
|
479
466
|
function extractRunMessageInfo(
|
|
480
467
|
message: unknown,
|
|
481
468
|
format: string,
|
|
@@ -487,27 +474,30 @@ function extractRunMessageInfo(
|
|
|
487
474
|
const metadata = isRecord(message.metadata) ? message.metadata : undefined;
|
|
488
475
|
const custom = isRecord(metadata?.custom) ? metadata.custom : undefined;
|
|
489
476
|
const timing = isRecord(metadata?.timing) ? metadata.timing : undefined;
|
|
490
|
-
const streamStartTime = timing?.streamStartTime;
|
|
491
477
|
const firstTokenTime = timing?.firstTokenTime;
|
|
492
478
|
const firstTokenMs =
|
|
493
|
-
typeof
|
|
494
|
-
|
|
495
|
-
typeof firstTokenTime === "number" &&
|
|
496
|
-
Number.isFinite(firstTokenTime)
|
|
497
|
-
? Math.round(firstTokenTime - streamStartTime)
|
|
479
|
+
typeof firstTokenTime === "number" && Number.isFinite(firstTokenTime)
|
|
480
|
+
? Math.round(firstTokenTime)
|
|
498
481
|
: undefined;
|
|
499
482
|
const finishReason =
|
|
500
483
|
status?.type === "incomplete"
|
|
501
|
-
? status.reason
|
|
484
|
+
? typeof status.reason === "string"
|
|
485
|
+
? status.reason
|
|
486
|
+
: undefined
|
|
502
487
|
: typeof metadata?.finishReason === "string"
|
|
503
488
|
? metadata.finishReason
|
|
504
489
|
: undefined;
|
|
505
490
|
const failed = status?.type === "incomplete" && status.reason === "error";
|
|
506
|
-
const outcome = deriveRunOutcome({
|
|
507
|
-
finishReason: typeof finishReason === "string" ? finishReason : undefined,
|
|
508
|
-
isError: failed,
|
|
509
|
-
});
|
|
491
|
+
const outcome = deriveRunOutcome({ finishReason, isError: failed });
|
|
510
492
|
const outcomeType = outcome.outcome;
|
|
493
|
+
const runStatus =
|
|
494
|
+
outcome.status === "error"
|
|
495
|
+
? "error"
|
|
496
|
+
: status?.type === "incomplete"
|
|
497
|
+
? "incomplete"
|
|
498
|
+
: finishReason !== undefined
|
|
499
|
+
? outcome.status
|
|
500
|
+
: undefined;
|
|
511
501
|
const failure = failed ? describeRunError(status.error) : {};
|
|
512
502
|
const messageId =
|
|
513
503
|
localMessageId ?? (typeof message.id === "string" ? message.id : undefined);
|
|
@@ -526,7 +516,7 @@ function extractRunMessageInfo(
|
|
|
526
516
|
|
|
527
517
|
return {
|
|
528
518
|
...(messageId ? { localMessageId: messageId } : undefined),
|
|
529
|
-
...(
|
|
519
|
+
...(runStatus !== undefined ? { status: runStatus } : undefined),
|
|
530
520
|
...(outcomeType ? { outcomeType } : undefined),
|
|
531
521
|
...failure,
|
|
532
522
|
...(firstTokenMs != null && firstTokenMs >= 0
|
|
@@ -541,12 +531,15 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
541
531
|
return value !== null && typeof value === "object";
|
|
542
532
|
}
|
|
543
533
|
|
|
544
|
-
function extractTelemetry<T>(
|
|
534
|
+
function extractTelemetry<T>(
|
|
535
|
+
format: string,
|
|
536
|
+
content: T,
|
|
537
|
+
): RunMessageTelemetry | null {
|
|
545
538
|
switch (format) {
|
|
546
539
|
case "aui/v0":
|
|
547
540
|
return extractAuiV0(content);
|
|
548
541
|
case "ai-sdk/v6":
|
|
549
|
-
return
|
|
542
|
+
return extractAISDKRunTelemetry([content as AISDKMessageLike]);
|
|
550
543
|
default:
|
|
551
544
|
return null;
|
|
552
545
|
}
|
|
@@ -555,9 +548,9 @@ function extractTelemetry<T>(format: string, content: T): TelemetryData | null {
|
|
|
555
548
|
function extractRunTelemetry<T>(
|
|
556
549
|
format: string,
|
|
557
550
|
runMessages: T[],
|
|
558
|
-
):
|
|
551
|
+
): RunMessageTelemetry | null {
|
|
559
552
|
if (format === "ai-sdk/v6") {
|
|
560
|
-
return
|
|
553
|
+
return extractAISDKRunTelemetry(runMessages as AISDKMessageLike[]);
|
|
561
554
|
}
|
|
562
555
|
for (let i = runMessages.length - 1; i >= 0; i--) {
|
|
563
556
|
const result = extractTelemetry(format, runMessages[i]!);
|
|
@@ -566,12 +559,7 @@ function extractRunTelemetry<T>(
|
|
|
566
559
|
return null;
|
|
567
560
|
}
|
|
568
561
|
|
|
569
|
-
|
|
570
|
-
error: "error",
|
|
571
|
-
incomplete: "incomplete",
|
|
572
|
-
};
|
|
573
|
-
|
|
574
|
-
export function extractAuiV0<T>(content: T): TelemetryData | null {
|
|
562
|
+
export function extractAuiV0<T>(content: T): RunMessageTelemetry | null {
|
|
575
563
|
const msg = content as {
|
|
576
564
|
role?: string;
|
|
577
565
|
status?: { type: string; reason?: string };
|
|
@@ -655,317 +643,42 @@ export function extractAuiV0<T>(content: T): TelemetryData | null {
|
|
|
655
643
|
cachedInputTokens = hasCachedInput ? totalCachedInput : undefined;
|
|
656
644
|
}
|
|
657
645
|
|
|
658
|
-
const
|
|
659
|
-
const status: TelemetryData["status"] =
|
|
660
|
-
statusType === "incomplete" && msg.status?.reason === "error"
|
|
661
|
-
? "error"
|
|
662
|
-
: (statusType && AUI_STATUS_MAP[statusType]) || "completed";
|
|
646
|
+
const status = msg.status?.type === "incomplete" ? "incomplete" : "completed";
|
|
663
647
|
|
|
664
648
|
const metadata = msg.metadata?.custom as Record<string, unknown> | undefined;
|
|
665
649
|
const modelId = extractRunTelemetryModelId(
|
|
666
650
|
msg.metadata as Record<string, unknown> | undefined,
|
|
667
651
|
);
|
|
668
652
|
|
|
669
|
-
const telemetrySteps:
|
|
670
|
-
steps && steps.length >
|
|
671
|
-
? steps.map((
|
|
672
|
-
const usage = s.usage
|
|
673
|
-
? normalizeRunTelemetryUsage(s.usage)
|
|
674
|
-
: undefined;
|
|
675
|
-
return {
|
|
676
|
-
...(usage?.inputTokens != null
|
|
677
|
-
? { input_tokens: usage.inputTokens }
|
|
678
|
-
: undefined),
|
|
679
|
-
...(usage?.outputTokens != null
|
|
680
|
-
? { output_tokens: usage.outputTokens }
|
|
681
|
-
: undefined),
|
|
682
|
-
...(usage?.reasoningTokens != null
|
|
683
|
-
? { reasoning_tokens: usage.reasoningTokens }
|
|
684
|
-
: undefined),
|
|
685
|
-
...(usage?.cachedInputTokens != null
|
|
686
|
-
? { cached_input_tokens: usage.cachedInputTokens }
|
|
687
|
-
: undefined),
|
|
688
|
-
};
|
|
689
|
-
})
|
|
653
|
+
const telemetrySteps: RunReportStepInit[] | undefined =
|
|
654
|
+
steps && steps.length > 0
|
|
655
|
+
? steps.map((step) => (step.usage ? { usage: step.usage } : {}))
|
|
690
656
|
: undefined;
|
|
691
657
|
|
|
692
658
|
return {
|
|
693
659
|
status,
|
|
694
660
|
...(toolCalls && toolCalls.length > 0 ? { toolCalls } : undefined),
|
|
695
661
|
...(steps?.length ? { totalSteps: steps.length } : undefined),
|
|
696
|
-
...(inputTokens != null
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
type: string;
|
|
709
|
-
text?: string;
|
|
710
|
-
toolName?: string;
|
|
711
|
-
toolCallId?: string;
|
|
712
|
-
args?: unknown;
|
|
713
|
-
result?: unknown;
|
|
714
|
-
input?: unknown;
|
|
715
|
-
output?: unknown;
|
|
716
|
-
};
|
|
717
|
-
|
|
718
|
-
type AiSdkV6Message = {
|
|
719
|
-
role?: string;
|
|
720
|
-
parts?: readonly AiSdkV6Part[];
|
|
721
|
-
metadata?: Record<string, unknown>;
|
|
722
|
-
};
|
|
723
|
-
|
|
724
|
-
function isToolCallPart(p: AiSdkV6Part): boolean {
|
|
725
|
-
if (!p.toolCallId) return false;
|
|
726
|
-
if (p.type === "tool-call" || p.type === "dynamic-tool") return !!p.toolName;
|
|
727
|
-
return p.type.startsWith("tool-") || p.type.startsWith("dynamic-tool-");
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
function isDynamicToolPart(p: AiSdkV6Part): boolean {
|
|
731
|
-
return p.type === "dynamic-tool" || p.type.startsWith("dynamic-tool-");
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
function partToToolCall(p: AiSdkV6Part): AssistantCloudRunReportToolCall {
|
|
735
|
-
const toolSource: "mcp" | "frontend" = isDynamicToolPart(p)
|
|
736
|
-
? "mcp"
|
|
737
|
-
: "frontend";
|
|
738
|
-
return createRunTelemetryToolCall({
|
|
739
|
-
toolName: p.toolName ?? p.type.slice(5),
|
|
740
|
-
toolCallId: p.toolCallId!,
|
|
741
|
-
args: p.args ?? p.input,
|
|
742
|
-
result: p.result ?? p.output,
|
|
743
|
-
toolSource,
|
|
744
|
-
});
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
function collectAiSdkV6Parts(parts: readonly AiSdkV6Part[]): {
|
|
748
|
-
textParts: string[];
|
|
749
|
-
toolCalls: AssistantCloudRunReportToolCall[];
|
|
750
|
-
stepsData: { tool_calls: AssistantCloudRunReportToolCall[] }[];
|
|
751
|
-
} {
|
|
752
|
-
const textParts: string[] = [];
|
|
753
|
-
const toolCalls: AssistantCloudRunReportToolCall[] = [];
|
|
754
|
-
const stepsData: { tool_calls: AssistantCloudRunReportToolCall[] }[] = [];
|
|
755
|
-
let currentStepToolCalls: AssistantCloudRunReportToolCall[] | null = null;
|
|
756
|
-
|
|
757
|
-
for (const p of parts) {
|
|
758
|
-
if (p.type === "step-start") {
|
|
759
|
-
if (currentStepToolCalls !== null) {
|
|
760
|
-
stepsData.push({ tool_calls: currentStepToolCalls });
|
|
761
|
-
}
|
|
762
|
-
currentStepToolCalls = [];
|
|
763
|
-
} else if (p.type === "text" && p.text) {
|
|
764
|
-
textParts.push(p.text);
|
|
765
|
-
} else if (isToolCallPart(p)) {
|
|
766
|
-
const tc = partToToolCall(p);
|
|
767
|
-
toolCalls.push(tc);
|
|
768
|
-
if (currentStepToolCalls !== null) {
|
|
769
|
-
currentStepToolCalls.push(tc);
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
if (currentStepToolCalls !== null) {
|
|
775
|
-
stepsData.push({ tool_calls: currentStepToolCalls });
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
return { textParts, toolCalls, stepsData };
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
function buildAiSdkV6Result(
|
|
782
|
-
textParts: string[],
|
|
783
|
-
toolCalls: AssistantCloudRunReportToolCall[],
|
|
784
|
-
totalSteps: number,
|
|
785
|
-
metadata?: Record<string, unknown>,
|
|
786
|
-
stepsData?: { tool_calls: AssistantCloudRunReportToolCall[] }[],
|
|
787
|
-
usage?: RunTelemetryUsage,
|
|
788
|
-
): TelemetryData {
|
|
789
|
-
const hasText = textParts.length > 0;
|
|
790
|
-
const outputText = hasText
|
|
791
|
-
? truncateRunTelemetryText(textParts.join(""))
|
|
792
|
-
: undefined;
|
|
793
|
-
const modelId = extractRunTelemetryModelId(metadata);
|
|
794
|
-
|
|
795
|
-
const steps: TelemetryStepData[] | undefined =
|
|
796
|
-
stepsData && stepsData.length > 1
|
|
797
|
-
? stepsData.map((s) => ({
|
|
798
|
-
...(s.tool_calls.length > 0
|
|
799
|
-
? { tool_calls: s.tool_calls }
|
|
800
|
-
: undefined),
|
|
801
|
-
}))
|
|
802
|
-
: undefined;
|
|
803
|
-
|
|
804
|
-
return {
|
|
805
|
-
status: hasText ? "completed" : "incomplete",
|
|
806
|
-
...(toolCalls.length > 0 ? { toolCalls } : undefined),
|
|
807
|
-
...(totalSteps > 0 ? { totalSteps } : undefined),
|
|
808
|
-
...(usage?.inputTokens != null
|
|
809
|
-
? { inputTokens: usage.inputTokens }
|
|
810
|
-
: undefined),
|
|
811
|
-
...(usage?.outputTokens != null
|
|
812
|
-
? { outputTokens: usage.outputTokens }
|
|
813
|
-
: undefined),
|
|
814
|
-
...(usage?.reasoningTokens != null
|
|
815
|
-
? { reasoningTokens: usage.reasoningTokens }
|
|
816
|
-
: undefined),
|
|
817
|
-
...(usage?.cachedInputTokens != null
|
|
818
|
-
? { cachedInputTokens: usage.cachedInputTokens }
|
|
662
|
+
...(inputTokens != null ||
|
|
663
|
+
outputTokens != null ||
|
|
664
|
+
reasoningTokens != null ||
|
|
665
|
+
cachedInputTokens != null
|
|
666
|
+
? {
|
|
667
|
+
usage: {
|
|
668
|
+
...(inputTokens != null ? { inputTokens } : undefined),
|
|
669
|
+
...(outputTokens != null ? { outputTokens } : undefined),
|
|
670
|
+
...(reasoningTokens != null ? { reasoningTokens } : undefined),
|
|
671
|
+
...(cachedInputTokens != null ? { cachedInputTokens } : undefined),
|
|
672
|
+
},
|
|
673
|
+
}
|
|
819
674
|
: undefined),
|
|
820
675
|
...(outputText != null ? { outputText } : undefined),
|
|
821
676
|
...(metadata ? { metadata } : undefined),
|
|
822
|
-
...(
|
|
677
|
+
...(telemetrySteps ? { steps: telemetrySteps } : undefined),
|
|
823
678
|
...(modelId ? { modelId } : undefined),
|
|
824
679
|
};
|
|
825
680
|
}
|
|
826
681
|
|
|
827
|
-
function extractAiSdkV6Usage(
|
|
828
|
-
metadata?: Record<string, unknown>,
|
|
829
|
-
): RunTelemetryUsage | undefined {
|
|
830
|
-
// Try top-level metadata.usage
|
|
831
|
-
const usage = metadata?.usage as RunTelemetryUsageInit | undefined;
|
|
832
|
-
if (usage) {
|
|
833
|
-
const normalized = normalizeRunTelemetryUsage(usage);
|
|
834
|
-
if (normalized) return normalized;
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
// Try aggregating from metadata.steps[].usage
|
|
838
|
-
const steps = metadata?.steps as
|
|
839
|
-
| readonly { usage?: RunTelemetryUsageInit }[]
|
|
840
|
-
| undefined;
|
|
841
|
-
if (steps && steps.length > 0) {
|
|
842
|
-
let inputTokens = 0;
|
|
843
|
-
let outputTokens = 0;
|
|
844
|
-
let reasoningTokens = 0;
|
|
845
|
-
let cachedInputTokens = 0;
|
|
846
|
-
let hasInput = false;
|
|
847
|
-
let hasOutput = false;
|
|
848
|
-
let hasReasoning = false;
|
|
849
|
-
let hasCachedInput = false;
|
|
850
|
-
let hasAny = false;
|
|
851
|
-
for (const s of steps) {
|
|
852
|
-
if (!s.usage) continue;
|
|
853
|
-
const n = normalizeRunTelemetryUsage(s.usage);
|
|
854
|
-
if (n) {
|
|
855
|
-
if (n.inputTokens != null) {
|
|
856
|
-
inputTokens += n.inputTokens;
|
|
857
|
-
hasInput = true;
|
|
858
|
-
}
|
|
859
|
-
if (n.outputTokens != null) {
|
|
860
|
-
outputTokens += n.outputTokens;
|
|
861
|
-
hasOutput = true;
|
|
862
|
-
}
|
|
863
|
-
if (n.reasoningTokens != null) {
|
|
864
|
-
reasoningTokens += n.reasoningTokens;
|
|
865
|
-
hasReasoning = true;
|
|
866
|
-
}
|
|
867
|
-
if (n.cachedInputTokens != null) {
|
|
868
|
-
cachedInputTokens += n.cachedInputTokens;
|
|
869
|
-
hasCachedInput = true;
|
|
870
|
-
}
|
|
871
|
-
hasAny = true;
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
if (hasAny) {
|
|
875
|
-
return {
|
|
876
|
-
...(hasInput ? { inputTokens } : undefined),
|
|
877
|
-
...(hasOutput ? { outputTokens } : undefined),
|
|
878
|
-
...(hasReasoning ? { reasoningTokens } : undefined),
|
|
879
|
-
...(hasCachedInput ? { cachedInputTokens } : undefined),
|
|
880
|
-
};
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
return undefined;
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
function extractAiSdkV6<T>(content: T): TelemetryData | null {
|
|
888
|
-
const msg = content as AiSdkV6Message;
|
|
889
|
-
if (msg.role !== "assistant") return null;
|
|
890
|
-
|
|
891
|
-
const { textParts, toolCalls, stepsData } = collectAiSdkV6Parts(
|
|
892
|
-
msg.parts ?? [],
|
|
893
|
-
);
|
|
894
|
-
return buildAiSdkV6Result(
|
|
895
|
-
textParts,
|
|
896
|
-
toolCalls,
|
|
897
|
-
stepsData.length,
|
|
898
|
-
msg.metadata,
|
|
899
|
-
stepsData,
|
|
900
|
-
extractAiSdkV6Usage(msg.metadata),
|
|
901
|
-
);
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
function aggregateAiSdkV6RunSteps<T>(stepMessages: T[]): TelemetryData | null {
|
|
905
|
-
const allTextParts: string[] = [];
|
|
906
|
-
const allToolCalls: AssistantCloudRunReportToolCall[] = [];
|
|
907
|
-
const allStepsData: { tool_calls: AssistantCloudRunReportToolCall[] }[] = [];
|
|
908
|
-
let hasAssistant = false;
|
|
909
|
-
let metadata: Record<string, unknown> | undefined;
|
|
910
|
-
let inputTokens = 0;
|
|
911
|
-
let outputTokens = 0;
|
|
912
|
-
let reasoningTokens = 0;
|
|
913
|
-
let cachedInputTokens = 0;
|
|
914
|
-
let hasInput = false;
|
|
915
|
-
let hasOutput = false;
|
|
916
|
-
let hasReasoning = false;
|
|
917
|
-
let hasCachedInput = false;
|
|
918
|
-
|
|
919
|
-
for (const content of stepMessages) {
|
|
920
|
-
const msg = content as AiSdkV6Message;
|
|
921
|
-
if (msg.role !== "assistant") continue;
|
|
922
|
-
hasAssistant = true;
|
|
923
|
-
|
|
924
|
-
const { textParts, toolCalls, stepsData } = collectAiSdkV6Parts(
|
|
925
|
-
msg.parts ?? [],
|
|
926
|
-
);
|
|
927
|
-
allTextParts.push(...textParts);
|
|
928
|
-
allToolCalls.push(...toolCalls);
|
|
929
|
-
allStepsData.push(...stepsData);
|
|
930
|
-
if (msg.metadata) metadata = msg.metadata;
|
|
931
|
-
|
|
932
|
-
const usage = extractAiSdkV6Usage(msg.metadata);
|
|
933
|
-
if (usage) {
|
|
934
|
-
if (usage.inputTokens != null) {
|
|
935
|
-
inputTokens += usage.inputTokens;
|
|
936
|
-
hasInput = true;
|
|
937
|
-
}
|
|
938
|
-
if (usage.outputTokens != null) {
|
|
939
|
-
outputTokens += usage.outputTokens;
|
|
940
|
-
hasOutput = true;
|
|
941
|
-
}
|
|
942
|
-
if (usage.reasoningTokens != null) {
|
|
943
|
-
reasoningTokens += usage.reasoningTokens;
|
|
944
|
-
hasReasoning = true;
|
|
945
|
-
}
|
|
946
|
-
if (usage.cachedInputTokens != null) {
|
|
947
|
-
cachedInputTokens += usage.cachedInputTokens;
|
|
948
|
-
hasCachedInput = true;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
if (!hasAssistant) return null;
|
|
954
|
-
return buildAiSdkV6Result(
|
|
955
|
-
allTextParts,
|
|
956
|
-
allToolCalls,
|
|
957
|
-
allStepsData.length,
|
|
958
|
-
metadata,
|
|
959
|
-
allStepsData,
|
|
960
|
-
{
|
|
961
|
-
...(hasInput ? { inputTokens } : undefined),
|
|
962
|
-
...(hasOutput ? { outputTokens } : undefined),
|
|
963
|
-
...(hasReasoning ? { reasoningTokens } : undefined),
|
|
964
|
-
...(hasCachedInput ? { cachedInputTokens } : undefined),
|
|
965
|
-
},
|
|
966
|
-
);
|
|
967
|
-
}
|
|
968
|
-
|
|
969
682
|
export function useAssistantCloudThreadHistoryAdapter(
|
|
970
683
|
cloudRef: RefObject<AssistantCloud>,
|
|
971
684
|
): ThreadHistoryAdapter & { readonly feedback: FeedbackAdapter } {
|
|
@@ -979,14 +692,13 @@ export function useAssistantCloudThreadHistoryAdapter(
|
|
|
979
692
|
() =>
|
|
980
693
|
new AssistantCloudThreadHistoryAdapter(cloudRef, () => auiRef.current),
|
|
981
694
|
);
|
|
982
|
-
useAssistantCloudEngagementEvents(
|
|
695
|
+
useAssistantCloudEngagementEvents(adapter, aui);
|
|
983
696
|
return adapter;
|
|
984
697
|
}
|
|
985
698
|
|
|
986
699
|
type RootEngagementTracker = {
|
|
987
700
|
count: number;
|
|
988
|
-
|
|
989
|
-
cloudRef: RefObject<AssistantCloud>;
|
|
701
|
+
engagementReporter: CloudEngagementReporter;
|
|
990
702
|
dispose: () => void;
|
|
991
703
|
};
|
|
992
704
|
|
|
@@ -1001,7 +713,6 @@ const rootEngagementTrackers = new WeakMap<
|
|
|
1001
713
|
* subscription and the last one to unmount removes it.
|
|
1002
714
|
*/
|
|
1003
715
|
const useRootEngagementEvents = (
|
|
1004
|
-
cloudRef: RefObject<AssistantCloud>,
|
|
1005
716
|
adapter: AssistantCloudThreadHistoryAdapter,
|
|
1006
717
|
aui: AssistantClient,
|
|
1007
718
|
) => {
|
|
@@ -1010,31 +721,20 @@ const useRootEngagementEvents = (
|
|
|
1010
721
|
if (!tracker) {
|
|
1011
722
|
const created: RootEngagementTracker = {
|
|
1012
723
|
count: 0,
|
|
1013
|
-
adapter,
|
|
1014
|
-
cloudRef,
|
|
724
|
+
engagementReporter: adapter.engagementReporter,
|
|
1015
725
|
dispose: () => {},
|
|
1016
726
|
};
|
|
1017
727
|
created.dispose = aui.on(
|
|
1018
728
|
{ scope: "*", event: "threads.selectionChanged" },
|
|
1019
729
|
(payload) => {
|
|
1020
|
-
|
|
1021
|
-
.resolveEngagementEventIds(payload.threadId)
|
|
1022
|
-
.then((ids) => {
|
|
1023
|
-
if (!ids.thread_id) return;
|
|
1024
|
-
created.cloudRef.current.events?.track({
|
|
1025
|
-
kind: "thread_switched",
|
|
1026
|
-
...ids,
|
|
1027
|
-
});
|
|
1028
|
-
})
|
|
1029
|
-
.catch(() => {});
|
|
730
|
+
created.engagementReporter.threadSwitched(payload.threadId);
|
|
1030
731
|
},
|
|
1031
732
|
);
|
|
1032
733
|
rootEngagementTrackers.set(aui, created);
|
|
1033
734
|
tracker = created;
|
|
1034
735
|
}
|
|
1035
736
|
const active = tracker;
|
|
1036
|
-
active.
|
|
1037
|
-
active.cloudRef = cloudRef;
|
|
737
|
+
active.engagementReporter = adapter.engagementReporter;
|
|
1038
738
|
active.count += 1;
|
|
1039
739
|
return () => {
|
|
1040
740
|
active.count -= 1;
|
|
@@ -1043,175 +743,129 @@ const useRootEngagementEvents = (
|
|
|
1043
743
|
rootEngagementTrackers.delete(aui);
|
|
1044
744
|
}
|
|
1045
745
|
};
|
|
1046
|
-
}, [adapter, aui
|
|
746
|
+
}, [adapter, aui]);
|
|
1047
747
|
};
|
|
1048
748
|
|
|
1049
749
|
const useAssistantCloudEngagementEvents = (
|
|
1050
|
-
cloudRef: RefObject<AssistantCloud>,
|
|
1051
750
|
adapter: AssistantCloudThreadHistoryAdapter,
|
|
1052
751
|
aui: AssistantClient,
|
|
1053
752
|
) => {
|
|
1054
|
-
useRootEngagementEvents(
|
|
1055
|
-
const runStartedAt = useRef(new Map<string, number>());
|
|
1056
|
-
const runEndedAt = useRef(new Map<string, number>());
|
|
1057
|
-
const shownSuggestions = useRef(new Set<string>());
|
|
753
|
+
useRootEngagementEvents(adapter, aui);
|
|
1058
754
|
|
|
1059
755
|
useEffect(() => {
|
|
1060
|
-
const
|
|
1061
|
-
event: AssistantCloudEvent,
|
|
1062
|
-
threadId: string,
|
|
1063
|
-
messageId?: string,
|
|
1064
|
-
options?: { awaitThread?: boolean },
|
|
1065
|
-
) => {
|
|
1066
|
-
void adapter
|
|
1067
|
-
.resolveEngagementEventIds(threadId, messageId, options)
|
|
1068
|
-
.then((ids) => {
|
|
1069
|
-
cloudRef.current.events?.track({ ...event, ...ids });
|
|
1070
|
-
})
|
|
1071
|
-
.catch(() => {});
|
|
1072
|
-
};
|
|
1073
|
-
const trackRunStopped = (threadId: string) => {
|
|
1074
|
-
const startedAt = runStartedAt.current.get(threadId);
|
|
1075
|
-
if (startedAt === undefined) return;
|
|
1076
|
-
runStartedAt.current.delete(threadId);
|
|
1077
|
-
track(
|
|
1078
|
-
{ kind: "run_stopped", value: Math.max(0, Date.now() - startedAt) },
|
|
1079
|
-
threadId,
|
|
1080
|
-
);
|
|
1081
|
-
};
|
|
756
|
+
const reporter = adapter.engagementReporter;
|
|
1082
757
|
|
|
1083
758
|
const unsubscribers = [
|
|
1084
759
|
aui.on({ scope: "thread", event: "composer.send" }, (payload) => {
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
}),
|
|
1097
|
-
...(!payload.messageId && previousRunEndedAt !== undefined
|
|
1098
|
-
? { value: Math.max(0, Date.now() - previousRunEndedAt) }
|
|
1099
|
-
: undefined),
|
|
1100
|
-
},
|
|
1101
|
-
payload.threadId,
|
|
1102
|
-
payload.messageId,
|
|
1103
|
-
{ awaitThread: !payload.messageId },
|
|
1104
|
-
);
|
|
760
|
+
if (payload.messageId) {
|
|
761
|
+
reporter.messageEdited(payload.threadId, {
|
|
762
|
+
messageId: payload.messageId,
|
|
763
|
+
chars: payload.chars,
|
|
764
|
+
});
|
|
765
|
+
} else {
|
|
766
|
+
reporter.messageSent(payload.threadId, {
|
|
767
|
+
chars: payload.chars,
|
|
768
|
+
attachments: payload.attachments,
|
|
769
|
+
});
|
|
770
|
+
}
|
|
1105
771
|
if (payload.suggestion) {
|
|
1106
|
-
|
|
772
|
+
reporter.suggestionClicked(payload.threadId);
|
|
1107
773
|
}
|
|
1108
774
|
}),
|
|
1109
775
|
aui.on(
|
|
1110
776
|
{ scope: "thread", event: "composer.attachmentAdd" },
|
|
1111
777
|
(payload) => {
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
? { props: { type: payload.contentType } }
|
|
1117
|
-
: undefined),
|
|
1118
|
-
},
|
|
1119
|
-
payload.threadId,
|
|
1120
|
-
payload.messageId,
|
|
1121
|
-
);
|
|
778
|
+
reporter.attachmentAdded(payload.threadId, {
|
|
779
|
+
messageId: payload.messageId,
|
|
780
|
+
contentType: payload.contentType,
|
|
781
|
+
});
|
|
1122
782
|
},
|
|
1123
783
|
),
|
|
1124
784
|
aui.on(
|
|
1125
785
|
{ scope: "thread", event: "composer.attachmentAddError" },
|
|
1126
786
|
(payload) => {
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
? { props: { type: payload.contentType } }
|
|
1132
|
-
: undefined),
|
|
1133
|
-
},
|
|
1134
|
-
payload.threadId,
|
|
1135
|
-
payload.messageId,
|
|
1136
|
-
);
|
|
787
|
+
reporter.attachmentFailed(payload.threadId, {
|
|
788
|
+
messageId: payload.messageId,
|
|
789
|
+
contentType: payload.contentType,
|
|
790
|
+
});
|
|
1137
791
|
},
|
|
1138
792
|
),
|
|
1139
793
|
aui.on({ scope: "thread", event: "composer.cancel" }, (payload) => {
|
|
1140
|
-
|
|
794
|
+
reporter.runStopped(payload.threadId);
|
|
1141
795
|
}),
|
|
1142
796
|
aui.on({ scope: "thread", event: "thread.runStart" }, (payload) => {
|
|
1143
|
-
|
|
797
|
+
reporter.runStarted(payload.threadId);
|
|
1144
798
|
}),
|
|
1145
799
|
aui.on({ scope: "thread", event: "thread.runEnd" }, (payload) => {
|
|
1146
|
-
|
|
1147
|
-
runEndedAt.current.set(payload.threadId, Date.now());
|
|
800
|
+
reporter.runEnded(payload.threadId);
|
|
1148
801
|
}),
|
|
1149
802
|
aui.on({ scope: "thread", event: "thread.cancelRun" }, (payload) => {
|
|
1150
|
-
|
|
803
|
+
reporter.runStopped(payload.threadId);
|
|
1151
804
|
}),
|
|
1152
805
|
aui.on({ scope: "thread", event: "thread.voiceStarted" }, (payload) => {
|
|
1153
|
-
|
|
806
|
+
reporter.voiceStarted(payload.threadId);
|
|
1154
807
|
}),
|
|
1155
808
|
aui.on({ scope: "thread", event: "message.reload" }, (payload) => {
|
|
1156
|
-
|
|
1157
|
-
{ kind: "message_regenerated" },
|
|
1158
|
-
payload.threadId,
|
|
1159
|
-
payload.messageId,
|
|
1160
|
-
);
|
|
809
|
+
reporter.messageRegenerated(payload.threadId, payload.messageId);
|
|
1161
810
|
}),
|
|
1162
811
|
aui.on(
|
|
1163
812
|
{ scope: "thread", event: "message.branchSwitched" },
|
|
1164
813
|
(payload) => {
|
|
1165
|
-
|
|
1166
|
-
{ kind: "branch_switched" },
|
|
1167
|
-
payload.threadId,
|
|
1168
|
-
payload.messageId,
|
|
1169
|
-
);
|
|
814
|
+
reporter.branchSwitched(payload.threadId, payload.messageId);
|
|
1170
815
|
},
|
|
1171
816
|
),
|
|
1172
817
|
aui.on({ scope: "thread", event: "message.copied" }, (payload) => {
|
|
1173
|
-
|
|
818
|
+
reporter.messageCopied(payload.threadId, payload.messageId);
|
|
1174
819
|
}),
|
|
820
|
+
aui.on(
|
|
821
|
+
{ scope: "thread", event: "thread.toolApprovalAnswered" },
|
|
822
|
+
(payload) => {
|
|
823
|
+
if (payload.approved) {
|
|
824
|
+
reporter.toolApproved(
|
|
825
|
+
payload.threadId,
|
|
826
|
+
payload.messageId,
|
|
827
|
+
payload.toolCallId,
|
|
828
|
+
payload.toolName,
|
|
829
|
+
);
|
|
830
|
+
} else {
|
|
831
|
+
reporter.toolRejected(
|
|
832
|
+
payload.threadId,
|
|
833
|
+
payload.messageId,
|
|
834
|
+
payload.toolCallId,
|
|
835
|
+
payload.toolName,
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
},
|
|
839
|
+
),
|
|
1175
840
|
aui.on({ scope: "thread", event: "message.speak" }, (payload) => {
|
|
1176
|
-
|
|
841
|
+
reporter.speechStarted(payload.threadId, payload.messageId);
|
|
1177
842
|
}),
|
|
1178
843
|
aui.on({ scope: "thread", event: "message.error" }, (payload) => {
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
payload.
|
|
1182
|
-
|
|
1183
|
-
);
|
|
844
|
+
reporter.errorShown(payload.threadId, {
|
|
845
|
+
messageId: payload.messageId,
|
|
846
|
+
reason: payload.reason,
|
|
847
|
+
});
|
|
1184
848
|
}),
|
|
1185
849
|
];
|
|
1186
850
|
|
|
1187
851
|
return () => {
|
|
1188
852
|
for (const unsubscribe of unsubscribers) unsubscribe();
|
|
1189
853
|
};
|
|
1190
|
-
}, [adapter, aui
|
|
854
|
+
}, [adapter, aui]);
|
|
1191
855
|
|
|
1192
856
|
useEffect(() => {
|
|
1193
857
|
const reportSuggestions = () => {
|
|
1194
858
|
const { mainThreadId } = aui.threads.getState();
|
|
1195
859
|
if (aui.threadListItem.getState().id !== mainThreadId) return;
|
|
1196
860
|
const { isEmpty, suggestions } = aui.thread.getState();
|
|
1197
|
-
if (
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
)
|
|
1202
|
-
return;
|
|
1203
|
-
}
|
|
1204
|
-
shownSuggestions.current.add(mainThreadId);
|
|
1205
|
-
void adapter.resolveEngagementEventIds(mainThreadId).then((ids) => {
|
|
1206
|
-
cloudRef.current.events?.track({
|
|
1207
|
-
kind: "suggestions_shown",
|
|
1208
|
-
value: suggestions.length,
|
|
1209
|
-
...ids,
|
|
1210
|
-
});
|
|
1211
|
-
});
|
|
861
|
+
if (!isEmpty || suggestions.length === 0) return;
|
|
862
|
+
adapter.engagementReporter.suggestionsShown(
|
|
863
|
+
mainThreadId,
|
|
864
|
+
suggestions.length,
|
|
865
|
+
);
|
|
1212
866
|
};
|
|
1213
867
|
|
|
1214
868
|
reportSuggestions();
|
|
1215
869
|
return aui.subscribe(reportSuggestions);
|
|
1216
|
-
}, [adapter, aui
|
|
870
|
+
}, [adapter, aui]);
|
|
1217
871
|
};
|