@assistant-ui/react 0.12.15 → 0.12.17
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.d.ts +1 -4
- package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.js +2 -527
- package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +96 -96
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts +1 -16
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.js +1 -14
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.d.ts +1 -13
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.js +2 -82
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts +1 -23
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js +1 -410
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.d.ts +1 -16
- package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.js +1 -48
- package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +1 -33
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +1 -307
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.d.ts +1 -3
- package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.js +1 -17
- package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts +2 -26
- package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.js +1 -13
- package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.d.ts +1 -3
- package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.js +1 -51
- package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts +1 -96
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.js +1 -110
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts +1 -112
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js +1 -439
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts +1 -12
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js +1 -102
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.d.ts +1 -3
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.js +1 -46
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.js +7 -20
- package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarEdit.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarEdit.js +3 -8
- package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +4 -7
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +5 -7
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarReload.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarReload.js +3 -10
- package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.js +5 -4
- package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
- package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerCancel.js +3 -8
- package/dist/primitives/composer/ComposerCancel.js.map +1 -1
- package/dist/primitives/composer/ComposerSend.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerSend.js +3 -8
- package/dist/primitives/composer/ComposerSend.js.map +1 -1
- package/dist/utils/createActionButton.js +1 -1
- package/dist/utils/createActionButton.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -1
- package/src/internal.ts +1 -1
- package/src/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.ts +2 -784
- package/src/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.tsx +5 -43
- package/src/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.ts +2 -100
- package/src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts +4 -580
- package/src/legacy-runtime/runtime-cores/external-store/createMessageConverter.ts +1 -76
- package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.ts +4 -483
- package/src/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.ts +1 -27
- package/src/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.ts +2 -35
- package/src/legacy-runtime/runtime-cores/local/useLocalRuntime.ts +1 -67
- package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.tsx +1 -178
- package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.tsx +1 -529
- package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.tsx +1 -152
- package/src/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.ts +1 -80
- package/src/primitives/actionBar/ActionBarCopy.tsx +7 -26
- package/src/primitives/actionBar/ActionBarEdit.ts +3 -10
- package/src/primitives/actionBar/ActionBarFeedbackNegative.tsx +4 -9
- package/src/primitives/actionBar/ActionBarFeedbackPositive.tsx +5 -9
- package/src/primitives/actionBar/ActionBarReload.ts +3 -16
- package/src/primitives/composer/ComposerAddAttachment.ts +5 -4
- package/src/primitives/composer/ComposerCancel.ts +3 -10
- package/src/primitives/composer/ComposerSend.ts +3 -13
- package/src/tests/BaseComposerRuntimeCore.test.ts +2 -3
- package/src/utils/createActionButton.tsx +1 -1
|
@@ -1,785 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import type {
|
|
3
|
-
GenericThreadHistoryAdapter,
|
|
4
|
-
ThreadHistoryAdapter,
|
|
5
|
-
ExportedMessageRepositoryItem,
|
|
6
|
-
MessageFormatAdapter,
|
|
7
|
-
MessageFormatItem,
|
|
8
|
-
MessageFormatRepository,
|
|
9
|
-
} from "@assistant-ui/core";
|
|
10
|
-
import {
|
|
11
|
-
AssistantCloud,
|
|
12
|
-
CloudMessagePersistence,
|
|
13
|
-
createFormattedPersistence,
|
|
14
|
-
} from "assistant-cloud";
|
|
15
|
-
import { auiV0Decode, auiV0Encode } from "./auiV0";
|
|
16
|
-
import { AssistantClient, useAui } from "@assistant-ui/store";
|
|
17
|
-
import { ThreadListItemMethods } from "../../types/scopes";
|
|
1
|
+
"use client";
|
|
18
2
|
|
|
19
|
-
|
|
20
|
-
ThreadListItemMethods,
|
|
21
|
-
CloudMessagePersistence
|
|
22
|
-
>();
|
|
23
|
-
|
|
24
|
-
class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
|
|
25
|
-
constructor(
|
|
26
|
-
private cloudRef: RefObject<AssistantCloud>,
|
|
27
|
-
private aui: AssistantClient,
|
|
28
|
-
) {}
|
|
29
|
-
|
|
30
|
-
private get _persistence(): CloudMessagePersistence {
|
|
31
|
-
const key = this.aui.threadListItem();
|
|
32
|
-
if (!globalPersistence.has(key)) {
|
|
33
|
-
globalPersistence.set(
|
|
34
|
-
key,
|
|
35
|
-
new CloudMessagePersistence(this.cloudRef.current),
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
return globalPersistence.get(key)!;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
withFormat<TMessage, TStorageFormat extends Record<string, unknown>>(
|
|
42
|
-
formatAdapter: MessageFormatAdapter<TMessage, TStorageFormat>,
|
|
43
|
-
): GenericThreadHistoryAdapter<TMessage> {
|
|
44
|
-
const adapter = this;
|
|
45
|
-
const formatted = createFormattedPersistence(
|
|
46
|
-
this._persistence,
|
|
47
|
-
formatAdapter,
|
|
48
|
-
);
|
|
49
|
-
return {
|
|
50
|
-
// Note: callers must also call reportTelemetry() for run tracking
|
|
51
|
-
async append(item: MessageFormatItem<TMessage>) {
|
|
52
|
-
const { remoteId } = await adapter.aui.threadListItem().initialize();
|
|
53
|
-
await formatted.append(remoteId, item);
|
|
54
|
-
},
|
|
55
|
-
async update(item: MessageFormatItem<TMessage>, localMessageId: string) {
|
|
56
|
-
const remoteId = adapter.aui.threadListItem().getState().remoteId;
|
|
57
|
-
if (!remoteId) return;
|
|
58
|
-
await formatted.update?.(remoteId, item, localMessageId);
|
|
59
|
-
},
|
|
60
|
-
reportTelemetry(
|
|
61
|
-
items: MessageFormatItem<TMessage>[],
|
|
62
|
-
options?: {
|
|
63
|
-
durationMs?: number;
|
|
64
|
-
stepTimestamps?: StepTimestamp[];
|
|
65
|
-
},
|
|
66
|
-
) {
|
|
67
|
-
const encodedRunMessages = items.map((item) =>
|
|
68
|
-
formatAdapter.encode(item),
|
|
69
|
-
);
|
|
70
|
-
adapter._reportRunTelemetry(
|
|
71
|
-
formatAdapter.format,
|
|
72
|
-
encodedRunMessages,
|
|
73
|
-
options,
|
|
74
|
-
);
|
|
75
|
-
},
|
|
76
|
-
async load(): Promise<MessageFormatRepository<TMessage>> {
|
|
77
|
-
const remoteId = adapter.aui.threadListItem().getState().remoteId;
|
|
78
|
-
if (!remoteId) return { messages: [] };
|
|
79
|
-
return formatted.load(remoteId);
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async append({ parentId, message }: ExportedMessageRepositoryItem) {
|
|
85
|
-
const { remoteId } = await this.aui.threadListItem().initialize();
|
|
86
|
-
const encoded = auiV0Encode(message);
|
|
87
|
-
await this._persistence.append(
|
|
88
|
-
remoteId,
|
|
89
|
-
message.id,
|
|
90
|
-
parentId,
|
|
91
|
-
"aui/v0",
|
|
92
|
-
encoded,
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
if (this.cloudRef.current.telemetry.enabled) {
|
|
96
|
-
this._maybeReportRun(remoteId, "aui/v0", encoded);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async load() {
|
|
101
|
-
const remoteId = this.aui.threadListItem().getState().remoteId;
|
|
102
|
-
if (!remoteId) return { messages: [] };
|
|
103
|
-
const messages = await this._persistence.load(remoteId, "aui/v0");
|
|
104
|
-
return {
|
|
105
|
-
messages: messages
|
|
106
|
-
.filter(
|
|
107
|
-
(m): m is typeof m & { format: "aui/v0" } => m.format === "aui/v0",
|
|
108
|
-
)
|
|
109
|
-
.map(auiV0Decode)
|
|
110
|
-
.reverse(),
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private _reportRunTelemetry<T>(
|
|
115
|
-
format: string,
|
|
116
|
-
runMessages: T[],
|
|
117
|
-
options?: {
|
|
118
|
-
durationMs?: number;
|
|
119
|
-
stepTimestamps?: StepTimestamp[];
|
|
120
|
-
},
|
|
121
|
-
) {
|
|
122
|
-
if (!this.cloudRef.current.telemetry.enabled) return;
|
|
123
|
-
|
|
124
|
-
const remoteId = this.aui.threadListItem().getState().remoteId;
|
|
125
|
-
if (!remoteId) return;
|
|
126
|
-
|
|
127
|
-
const extracted = extractRunTelemetry(format, runMessages);
|
|
128
|
-
if (!extracted) return;
|
|
129
|
-
|
|
130
|
-
this._sendReport(
|
|
131
|
-
remoteId,
|
|
132
|
-
extracted,
|
|
133
|
-
options?.durationMs,
|
|
134
|
-
options?.stepTimestamps,
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
private _maybeReportRun<T>(remoteId: string, format: string, content: T) {
|
|
139
|
-
const extracted = extractTelemetry(format, content);
|
|
140
|
-
if (!extracted) return;
|
|
141
|
-
|
|
142
|
-
this._sendReport(remoteId, extracted);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
private _sendReport(
|
|
146
|
-
remoteId: string,
|
|
147
|
-
data: TelemetryData,
|
|
148
|
-
durationMs?: number,
|
|
149
|
-
stepTimestamps?: StepTimestamp[],
|
|
150
|
-
) {
|
|
151
|
-
const mergedSteps = mergeStepTimestamps(data.steps, stepTimestamps);
|
|
152
|
-
// Keep in sync with assistant-cloud createRunSchema
|
|
153
|
-
// (apps/aui-cloud-api/src/endpoints/runs/create.ts).
|
|
154
|
-
const initial: Parameters<typeof this.cloudRef.current.runs.report>[0] = {
|
|
155
|
-
thread_id: remoteId,
|
|
156
|
-
status: data.status,
|
|
157
|
-
...(data.totalSteps != null
|
|
158
|
-
? { total_steps: data.totalSteps }
|
|
159
|
-
: undefined),
|
|
160
|
-
...(data.toolCalls ? { tool_calls: data.toolCalls } : undefined),
|
|
161
|
-
...(mergedSteps ? { steps: mergedSteps } : undefined),
|
|
162
|
-
...(data.inputTokens != null
|
|
163
|
-
? { input_tokens: data.inputTokens }
|
|
164
|
-
: undefined),
|
|
165
|
-
...(data.outputTokens != null
|
|
166
|
-
? { output_tokens: data.outputTokens }
|
|
167
|
-
: undefined),
|
|
168
|
-
...(data.reasoningTokens != null
|
|
169
|
-
? { reasoning_tokens: data.reasoningTokens }
|
|
170
|
-
: undefined),
|
|
171
|
-
...(data.cachedInputTokens != null
|
|
172
|
-
? { cached_input_tokens: data.cachedInputTokens }
|
|
173
|
-
: undefined),
|
|
174
|
-
...(durationMs != null ? { duration_ms: durationMs } : undefined),
|
|
175
|
-
...(data.outputText != null
|
|
176
|
-
? { output_text: data.outputText }
|
|
177
|
-
: undefined),
|
|
178
|
-
...(data.metadata ? { metadata: data.metadata } : undefined),
|
|
179
|
-
...(data.modelId ? { model_id: data.modelId } : undefined),
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
const { beforeReport } = this.cloudRef.current.telemetry;
|
|
183
|
-
const report = beforeReport ? beforeReport(initial) : initial;
|
|
184
|
-
if (!report) return;
|
|
185
|
-
|
|
186
|
-
this.cloudRef.current.runs.report(report).catch(() => {});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const MAX_SPAN_CONTENT = 50_000;
|
|
191
|
-
|
|
192
|
-
function truncateStr(value: string): string {
|
|
193
|
-
if (value.length <= MAX_SPAN_CONTENT) return value;
|
|
194
|
-
return value.slice(0, MAX_SPAN_CONTENT);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function safeStringify(value: unknown): string | undefined {
|
|
198
|
-
if (value == null) return undefined;
|
|
199
|
-
try {
|
|
200
|
-
return truncateStr(JSON.stringify(value));
|
|
201
|
-
} catch {
|
|
202
|
-
return undefined;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
type TelemetryToolCall = {
|
|
207
|
-
tool_name: string;
|
|
208
|
-
tool_call_id: string;
|
|
209
|
-
tool_args?: string;
|
|
210
|
-
tool_result?: string;
|
|
211
|
-
tool_source?: "mcp" | "frontend" | "backend";
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
const BASE64_PATTERN = /^[A-Za-z0-9+/]{100,}={0,2}$/;
|
|
215
|
-
|
|
216
|
-
function summarizeMcpResult(value: unknown): string | undefined {
|
|
217
|
-
if (value == null) return undefined;
|
|
218
|
-
try {
|
|
219
|
-
const parsed = typeof value === "string" ? JSON.parse(value) : value;
|
|
220
|
-
if (Array.isArray(parsed)) {
|
|
221
|
-
const summarized = parsed.map((item) => {
|
|
222
|
-
if (item && typeof item === "object" && item.type) {
|
|
223
|
-
if (
|
|
224
|
-
(item.type === "image" || item.type === "audio") &&
|
|
225
|
-
typeof item.data === "string" &&
|
|
226
|
-
BASE64_PATTERN.test(item.data.slice(0, 200))
|
|
227
|
-
) {
|
|
228
|
-
const sizeKB = ((item.data.length * 3) / 4 / 1024).toFixed(1);
|
|
229
|
-
return { ...item, data: `[${item.type}: ${sizeKB}KB]` };
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return item;
|
|
233
|
-
});
|
|
234
|
-
return truncateStr(JSON.stringify(summarized));
|
|
235
|
-
}
|
|
236
|
-
} catch {
|
|
237
|
-
// not JSON array, fall through
|
|
238
|
-
}
|
|
239
|
-
return safeStringify(value);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function buildToolCall(
|
|
243
|
-
toolName: string,
|
|
244
|
-
toolCallId: string,
|
|
245
|
-
args: unknown,
|
|
246
|
-
result: unknown,
|
|
247
|
-
argsText?: string,
|
|
248
|
-
toolSource?: "mcp" | "frontend" | "backend",
|
|
249
|
-
): TelemetryToolCall {
|
|
250
|
-
const call: TelemetryToolCall = {
|
|
251
|
-
tool_name: toolName,
|
|
252
|
-
tool_call_id: toolCallId,
|
|
253
|
-
};
|
|
254
|
-
const toolArgs = argsText ?? safeStringify(args);
|
|
255
|
-
if (toolArgs !== undefined) call.tool_args = toolArgs;
|
|
256
|
-
const toolResult =
|
|
257
|
-
toolSource === "mcp" ? summarizeMcpResult(result) : safeStringify(result);
|
|
258
|
-
if (toolResult !== undefined) call.tool_result = toolResult;
|
|
259
|
-
if (toolSource) call.tool_source = toolSource;
|
|
260
|
-
return call;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
type TelemetryStepData = {
|
|
264
|
-
input_tokens?: number;
|
|
265
|
-
output_tokens?: number;
|
|
266
|
-
reasoning_tokens?: number;
|
|
267
|
-
cached_input_tokens?: number;
|
|
268
|
-
tool_calls?: TelemetryToolCall[];
|
|
269
|
-
start_ms?: number;
|
|
270
|
-
end_ms?: number;
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
type StepTimestamp = { start_ms: number; end_ms: number };
|
|
274
|
-
|
|
275
|
-
function mergeStepTimestamps(
|
|
276
|
-
steps: TelemetryStepData[] | undefined,
|
|
277
|
-
timestamps: StepTimestamp[] | undefined,
|
|
278
|
-
): TelemetryStepData[] | undefined {
|
|
279
|
-
if (!timestamps) return steps;
|
|
280
|
-
if (!steps) return timestamps.map((t) => ({ ...t }));
|
|
281
|
-
|
|
282
|
-
const len = Math.min(steps.length, timestamps.length);
|
|
283
|
-
return steps.map((s, i) => ({
|
|
284
|
-
...s,
|
|
285
|
-
...(i < len ? timestamps[i] : undefined),
|
|
286
|
-
}));
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
type TelemetryData = {
|
|
290
|
-
status: "completed" | "incomplete" | "error";
|
|
291
|
-
toolCalls?: TelemetryToolCall[];
|
|
292
|
-
totalSteps?: number;
|
|
293
|
-
inputTokens?: number;
|
|
294
|
-
outputTokens?: number;
|
|
295
|
-
reasoningTokens?: number;
|
|
296
|
-
cachedInputTokens?: number;
|
|
297
|
-
outputText?: string;
|
|
298
|
-
metadata?: Record<string, unknown>;
|
|
299
|
-
steps?: TelemetryStepData[];
|
|
300
|
-
modelId?: string;
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
function extractTelemetry<T>(format: string, content: T): TelemetryData | null {
|
|
304
|
-
switch (format) {
|
|
305
|
-
case "aui/v0":
|
|
306
|
-
return extractAuiV0(content);
|
|
307
|
-
case "ai-sdk/v6":
|
|
308
|
-
return extractAiSdkV6(content);
|
|
309
|
-
default:
|
|
310
|
-
return null;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
function extractRunTelemetry<T>(
|
|
315
|
-
format: string,
|
|
316
|
-
runMessages: T[],
|
|
317
|
-
): TelemetryData | null {
|
|
318
|
-
if (format === "ai-sdk/v6") {
|
|
319
|
-
return aggregateAiSdkV6RunSteps(runMessages);
|
|
320
|
-
}
|
|
321
|
-
for (let i = runMessages.length - 1; i >= 0; i--) {
|
|
322
|
-
const result = extractTelemetry(format, runMessages[i]!);
|
|
323
|
-
if (result) return result;
|
|
324
|
-
}
|
|
325
|
-
return null;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const AUI_STATUS_MAP: Record<string, TelemetryData["status"]> = {
|
|
329
|
-
error: "error",
|
|
330
|
-
incomplete: "incomplete",
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
function extractAuiV0<T>(content: T): TelemetryData | null {
|
|
334
|
-
const msg = content as {
|
|
335
|
-
role?: string;
|
|
336
|
-
status?: { type: string };
|
|
337
|
-
content?: readonly {
|
|
338
|
-
type: string;
|
|
339
|
-
text?: string;
|
|
340
|
-
toolName?: string;
|
|
341
|
-
toolCallId?: string;
|
|
342
|
-
args?: unknown;
|
|
343
|
-
argsText?: string;
|
|
344
|
-
result?: unknown;
|
|
345
|
-
}[];
|
|
346
|
-
metadata?: {
|
|
347
|
-
modelId?: string;
|
|
348
|
-
steps?: readonly {
|
|
349
|
-
usage?: {
|
|
350
|
-
inputTokens?: number;
|
|
351
|
-
outputTokens?: number;
|
|
352
|
-
reasoningTokens?: number;
|
|
353
|
-
cachedInputTokens?: number;
|
|
354
|
-
};
|
|
355
|
-
}[];
|
|
356
|
-
custom?: Record<string, unknown> & { modelId?: string };
|
|
357
|
-
};
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
if (msg.role !== "assistant") return null;
|
|
361
|
-
|
|
362
|
-
const toolCalls = msg.content
|
|
363
|
-
?.filter((p) => p.type === "tool-call" && p.toolName && p.toolCallId)
|
|
364
|
-
.map((p) =>
|
|
365
|
-
buildToolCall(p.toolName!, p.toolCallId!, p.args, p.result, p.argsText),
|
|
366
|
-
);
|
|
367
|
-
|
|
368
|
-
const textParts = msg.content?.filter((p) => p.type === "text" && p.text);
|
|
369
|
-
const outputText =
|
|
370
|
-
textParts && textParts.length > 0
|
|
371
|
-
? truncateStr(textParts.map((p) => p.text).join(""))
|
|
372
|
-
: undefined;
|
|
373
|
-
|
|
374
|
-
const steps = msg.metadata?.steps;
|
|
375
|
-
let inputTokens: number | undefined;
|
|
376
|
-
let outputTokens: number | undefined;
|
|
377
|
-
let reasoningTokens: number | undefined;
|
|
378
|
-
let cachedInputTokens: number | undefined;
|
|
379
|
-
if (steps && steps.length > 0) {
|
|
380
|
-
let totalInput = 0;
|
|
381
|
-
let totalOutput = 0;
|
|
382
|
-
let totalReasoning = 0;
|
|
383
|
-
let totalCachedInput = 0;
|
|
384
|
-
let hasInput = false;
|
|
385
|
-
let hasOutput = false;
|
|
386
|
-
let hasReasoning = false;
|
|
387
|
-
let hasCachedInput = false;
|
|
388
|
-
for (const step of steps) {
|
|
389
|
-
if (step.usage?.inputTokens != null) {
|
|
390
|
-
totalInput += step.usage.inputTokens;
|
|
391
|
-
hasInput = true;
|
|
392
|
-
}
|
|
393
|
-
if (step.usage?.outputTokens != null) {
|
|
394
|
-
totalOutput += step.usage.outputTokens;
|
|
395
|
-
hasOutput = true;
|
|
396
|
-
}
|
|
397
|
-
if (step.usage?.reasoningTokens != null) {
|
|
398
|
-
totalReasoning += step.usage.reasoningTokens;
|
|
399
|
-
hasReasoning = true;
|
|
400
|
-
}
|
|
401
|
-
if (step.usage?.cachedInputTokens != null) {
|
|
402
|
-
totalCachedInput += step.usage.cachedInputTokens;
|
|
403
|
-
hasCachedInput = true;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
inputTokens = hasInput ? totalInput : undefined;
|
|
407
|
-
outputTokens = hasOutput ? totalOutput : undefined;
|
|
408
|
-
reasoningTokens = hasReasoning ? totalReasoning : undefined;
|
|
409
|
-
cachedInputTokens = hasCachedInput ? totalCachedInput : undefined;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
const statusType = msg.status?.type;
|
|
413
|
-
const status: TelemetryData["status"] =
|
|
414
|
-
(statusType && AUI_STATUS_MAP[statusType]) || "completed";
|
|
415
|
-
|
|
416
|
-
const metadata = msg.metadata?.custom as Record<string, unknown> | undefined;
|
|
417
|
-
const modelId =
|
|
418
|
-
msg.metadata?.modelId ??
|
|
419
|
-
(typeof msg.metadata?.custom?.modelId === "string"
|
|
420
|
-
? msg.metadata.custom.modelId
|
|
421
|
-
: undefined);
|
|
422
|
-
|
|
423
|
-
const telemetrySteps: TelemetryStepData[] | undefined =
|
|
424
|
-
steps && steps.length > 1
|
|
425
|
-
? steps.map((s) => ({
|
|
426
|
-
...(s.usage?.inputTokens != null
|
|
427
|
-
? { input_tokens: s.usage.inputTokens }
|
|
428
|
-
: undefined),
|
|
429
|
-
...(s.usage?.outputTokens != null
|
|
430
|
-
? { output_tokens: s.usage.outputTokens }
|
|
431
|
-
: undefined),
|
|
432
|
-
...(s.usage?.reasoningTokens != null
|
|
433
|
-
? { reasoning_tokens: s.usage.reasoningTokens }
|
|
434
|
-
: undefined),
|
|
435
|
-
...(s.usage?.cachedInputTokens != null
|
|
436
|
-
? { cached_input_tokens: s.usage.cachedInputTokens }
|
|
437
|
-
: undefined),
|
|
438
|
-
}))
|
|
439
|
-
: undefined;
|
|
440
|
-
|
|
441
|
-
return {
|
|
442
|
-
status,
|
|
443
|
-
...(toolCalls && toolCalls.length > 0 ? { toolCalls } : undefined),
|
|
444
|
-
...(steps?.length ? { totalSteps: steps.length } : undefined),
|
|
445
|
-
...(inputTokens != null ? { inputTokens } : undefined),
|
|
446
|
-
...(outputTokens != null ? { outputTokens } : undefined),
|
|
447
|
-
...(reasoningTokens != null ? { reasoningTokens } : undefined),
|
|
448
|
-
...(cachedInputTokens != null ? { cachedInputTokens } : undefined),
|
|
449
|
-
...(outputText != null ? { outputText } : undefined),
|
|
450
|
-
...(metadata ? { metadata } : undefined),
|
|
451
|
-
...(telemetrySteps ? { steps: telemetrySteps } : undefined),
|
|
452
|
-
...(modelId ? { modelId } : undefined),
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
type AiSdkV6Part = {
|
|
457
|
-
type: string;
|
|
458
|
-
text?: string;
|
|
459
|
-
toolName?: string;
|
|
460
|
-
toolCallId?: string;
|
|
461
|
-
args?: unknown;
|
|
462
|
-
result?: unknown;
|
|
463
|
-
input?: unknown;
|
|
464
|
-
output?: unknown;
|
|
465
|
-
};
|
|
466
|
-
|
|
467
|
-
type AiSdkV6Message = {
|
|
468
|
-
role?: string;
|
|
469
|
-
parts?: readonly AiSdkV6Part[];
|
|
470
|
-
metadata?: Record<string, unknown>;
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
function isToolCallPart(p: AiSdkV6Part): boolean {
|
|
474
|
-
if (!p.toolCallId) return false;
|
|
475
|
-
if (p.type === "tool-call" || p.type === "dynamic-tool") return !!p.toolName;
|
|
476
|
-
return p.type.startsWith("tool-") || p.type.startsWith("dynamic-tool-");
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
function isDynamicToolPart(p: AiSdkV6Part): boolean {
|
|
480
|
-
return p.type === "dynamic-tool" || p.type.startsWith("dynamic-tool-");
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
function partToToolCall(p: AiSdkV6Part): TelemetryToolCall {
|
|
484
|
-
const toolSource: "mcp" | undefined = isDynamicToolPart(p)
|
|
485
|
-
? "mcp"
|
|
486
|
-
: undefined;
|
|
487
|
-
return buildToolCall(
|
|
488
|
-
p.toolName ?? p.type.slice(5),
|
|
489
|
-
p.toolCallId!,
|
|
490
|
-
p.args ?? p.input,
|
|
491
|
-
p.result ?? p.output,
|
|
492
|
-
undefined,
|
|
493
|
-
toolSource,
|
|
494
|
-
);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
function collectAiSdkV6Parts(parts: readonly AiSdkV6Part[]): {
|
|
498
|
-
textParts: string[];
|
|
499
|
-
toolCalls: TelemetryToolCall[];
|
|
500
|
-
stepsData: { tool_calls: TelemetryToolCall[] }[];
|
|
501
|
-
} {
|
|
502
|
-
const textParts: string[] = [];
|
|
503
|
-
const toolCalls: TelemetryToolCall[] = [];
|
|
504
|
-
const stepsData: { tool_calls: TelemetryToolCall[] }[] = [];
|
|
505
|
-
let currentStepToolCalls: TelemetryToolCall[] | null = null;
|
|
506
|
-
|
|
507
|
-
for (const p of parts) {
|
|
508
|
-
if (p.type === "step-start") {
|
|
509
|
-
if (currentStepToolCalls !== null) {
|
|
510
|
-
stepsData.push({ tool_calls: currentStepToolCalls });
|
|
511
|
-
}
|
|
512
|
-
currentStepToolCalls = [];
|
|
513
|
-
} else if (p.type === "text" && p.text) {
|
|
514
|
-
textParts.push(p.text);
|
|
515
|
-
} else if (isToolCallPart(p)) {
|
|
516
|
-
const tc = partToToolCall(p);
|
|
517
|
-
toolCalls.push(tc);
|
|
518
|
-
if (currentStepToolCalls !== null) {
|
|
519
|
-
currentStepToolCalls.push(tc);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
if (currentStepToolCalls !== null) {
|
|
525
|
-
stepsData.push({ tool_calls: currentStepToolCalls });
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
return { textParts, toolCalls, stepsData };
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
function extractModelId(
|
|
532
|
-
metadata?: Record<string, unknown>,
|
|
533
|
-
): string | undefined {
|
|
534
|
-
if (!metadata) return undefined;
|
|
535
|
-
if (typeof metadata.modelId === "string") return metadata.modelId;
|
|
536
|
-
const custom = metadata.custom as Record<string, unknown> | undefined;
|
|
537
|
-
if (typeof custom?.modelId === "string") return custom.modelId;
|
|
538
|
-
return undefined;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
function buildAiSdkV6Result(
|
|
542
|
-
textParts: string[],
|
|
543
|
-
toolCalls: TelemetryToolCall[],
|
|
544
|
-
totalSteps: number,
|
|
545
|
-
metadata?: Record<string, unknown>,
|
|
546
|
-
stepsData?: { tool_calls: TelemetryToolCall[] }[],
|
|
547
|
-
usage?: {
|
|
548
|
-
inputTokens?: number;
|
|
549
|
-
outputTokens?: number;
|
|
550
|
-
reasoningTokens?: number;
|
|
551
|
-
cachedInputTokens?: number;
|
|
552
|
-
},
|
|
553
|
-
): TelemetryData {
|
|
554
|
-
const hasText = textParts.length > 0;
|
|
555
|
-
const outputText = hasText ? truncateStr(textParts.join("")) : undefined;
|
|
556
|
-
const modelId = extractModelId(metadata);
|
|
557
|
-
|
|
558
|
-
const steps: TelemetryStepData[] | undefined =
|
|
559
|
-
stepsData && stepsData.length > 1
|
|
560
|
-
? stepsData.map((s) => ({
|
|
561
|
-
...(s.tool_calls.length > 0
|
|
562
|
-
? { tool_calls: s.tool_calls }
|
|
563
|
-
: undefined),
|
|
564
|
-
}))
|
|
565
|
-
: undefined;
|
|
566
|
-
|
|
567
|
-
return {
|
|
568
|
-
status: hasText ? "completed" : "incomplete",
|
|
569
|
-
...(toolCalls.length > 0 ? { toolCalls } : undefined),
|
|
570
|
-
...(totalSteps > 0 ? { totalSteps } : undefined),
|
|
571
|
-
...(usage?.inputTokens != null
|
|
572
|
-
? { inputTokens: usage.inputTokens }
|
|
573
|
-
: undefined),
|
|
574
|
-
...(usage?.outputTokens != null
|
|
575
|
-
? { outputTokens: usage.outputTokens }
|
|
576
|
-
: undefined),
|
|
577
|
-
...(usage?.reasoningTokens != null
|
|
578
|
-
? { reasoningTokens: usage.reasoningTokens }
|
|
579
|
-
: undefined),
|
|
580
|
-
...(usage?.cachedInputTokens != null
|
|
581
|
-
? { cachedInputTokens: usage.cachedInputTokens }
|
|
582
|
-
: undefined),
|
|
583
|
-
...(outputText != null ? { outputText } : undefined),
|
|
584
|
-
...(metadata ? { metadata } : undefined),
|
|
585
|
-
...(steps ? { steps } : undefined),
|
|
586
|
-
...(modelId ? { modelId } : undefined),
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
type UsageFields = {
|
|
591
|
-
inputTokens?: number;
|
|
592
|
-
outputTokens?: number;
|
|
593
|
-
promptTokens?: number;
|
|
594
|
-
completionTokens?: number;
|
|
595
|
-
reasoningTokens?: number;
|
|
596
|
-
cachedInputTokens?: number;
|
|
597
|
-
};
|
|
598
|
-
|
|
599
|
-
function normalizeUsage(u: UsageFields):
|
|
600
|
-
| {
|
|
601
|
-
inputTokens?: number;
|
|
602
|
-
outputTokens?: number;
|
|
603
|
-
reasoningTokens?: number;
|
|
604
|
-
cachedInputTokens?: number;
|
|
605
|
-
}
|
|
606
|
-
| undefined {
|
|
607
|
-
const input = u.inputTokens ?? u.promptTokens;
|
|
608
|
-
const output = u.outputTokens ?? u.completionTokens;
|
|
609
|
-
if (
|
|
610
|
-
input == null &&
|
|
611
|
-
output == null &&
|
|
612
|
-
u.reasoningTokens == null &&
|
|
613
|
-
u.cachedInputTokens == null
|
|
614
|
-
) {
|
|
615
|
-
return undefined;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
return {
|
|
619
|
-
...(input != null ? { inputTokens: input } : undefined),
|
|
620
|
-
...(output != null ? { outputTokens: output } : undefined),
|
|
621
|
-
...(u.reasoningTokens != null
|
|
622
|
-
? { reasoningTokens: u.reasoningTokens }
|
|
623
|
-
: undefined),
|
|
624
|
-
...(u.cachedInputTokens != null
|
|
625
|
-
? { cachedInputTokens: u.cachedInputTokens }
|
|
626
|
-
: undefined),
|
|
627
|
-
};
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
function extractAiSdkV6Usage(metadata?: Record<string, unknown>):
|
|
631
|
-
| {
|
|
632
|
-
inputTokens?: number;
|
|
633
|
-
outputTokens?: number;
|
|
634
|
-
reasoningTokens?: number;
|
|
635
|
-
cachedInputTokens?: number;
|
|
636
|
-
}
|
|
637
|
-
| undefined {
|
|
638
|
-
// Try top-level metadata.usage
|
|
639
|
-
const usage = metadata?.usage as UsageFields | undefined;
|
|
640
|
-
if (usage) {
|
|
641
|
-
const normalized = normalizeUsage(usage);
|
|
642
|
-
if (normalized) return normalized;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
// Try aggregating from metadata.steps[].usage
|
|
646
|
-
const steps = metadata?.steps as
|
|
647
|
-
| readonly { usage?: UsageFields }[]
|
|
648
|
-
| undefined;
|
|
649
|
-
if (steps && steps.length > 0) {
|
|
650
|
-
let inputTokens = 0;
|
|
651
|
-
let outputTokens = 0;
|
|
652
|
-
let reasoningTokens = 0;
|
|
653
|
-
let cachedInputTokens = 0;
|
|
654
|
-
let hasInput = false;
|
|
655
|
-
let hasOutput = false;
|
|
656
|
-
let hasReasoning = false;
|
|
657
|
-
let hasCachedInput = false;
|
|
658
|
-
let hasAny = false;
|
|
659
|
-
for (const s of steps) {
|
|
660
|
-
if (!s.usage) continue;
|
|
661
|
-
const n = normalizeUsage(s.usage);
|
|
662
|
-
if (n) {
|
|
663
|
-
if (n.inputTokens != null) {
|
|
664
|
-
inputTokens += n.inputTokens;
|
|
665
|
-
hasInput = true;
|
|
666
|
-
}
|
|
667
|
-
if (n.outputTokens != null) {
|
|
668
|
-
outputTokens += n.outputTokens;
|
|
669
|
-
hasOutput = true;
|
|
670
|
-
}
|
|
671
|
-
if (n.reasoningTokens != null) {
|
|
672
|
-
reasoningTokens += n.reasoningTokens;
|
|
673
|
-
hasReasoning = true;
|
|
674
|
-
}
|
|
675
|
-
if (n.cachedInputTokens != null) {
|
|
676
|
-
cachedInputTokens += n.cachedInputTokens;
|
|
677
|
-
hasCachedInput = true;
|
|
678
|
-
}
|
|
679
|
-
hasAny = true;
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
if (hasAny) {
|
|
683
|
-
return {
|
|
684
|
-
...(hasInput ? { inputTokens } : undefined),
|
|
685
|
-
...(hasOutput ? { outputTokens } : undefined),
|
|
686
|
-
...(hasReasoning ? { reasoningTokens } : undefined),
|
|
687
|
-
...(hasCachedInput ? { cachedInputTokens } : undefined),
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
return undefined;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
function extractAiSdkV6<T>(content: T): TelemetryData | null {
|
|
696
|
-
const msg = content as AiSdkV6Message;
|
|
697
|
-
if (msg.role !== "assistant") return null;
|
|
698
|
-
|
|
699
|
-
const { textParts, toolCalls, stepsData } = collectAiSdkV6Parts(
|
|
700
|
-
msg.parts ?? [],
|
|
701
|
-
);
|
|
702
|
-
return buildAiSdkV6Result(
|
|
703
|
-
textParts,
|
|
704
|
-
toolCalls,
|
|
705
|
-
stepsData.length,
|
|
706
|
-
msg.metadata,
|
|
707
|
-
stepsData,
|
|
708
|
-
extractAiSdkV6Usage(msg.metadata),
|
|
709
|
-
);
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
function aggregateAiSdkV6RunSteps<T>(stepMessages: T[]): TelemetryData | null {
|
|
713
|
-
const allTextParts: string[] = [];
|
|
714
|
-
const allToolCalls: TelemetryToolCall[] = [];
|
|
715
|
-
const allStepsData: { tool_calls: TelemetryToolCall[] }[] = [];
|
|
716
|
-
let hasAssistant = false;
|
|
717
|
-
let metadata: Record<string, unknown> | undefined;
|
|
718
|
-
let inputTokens = 0;
|
|
719
|
-
let outputTokens = 0;
|
|
720
|
-
let reasoningTokens = 0;
|
|
721
|
-
let cachedInputTokens = 0;
|
|
722
|
-
let hasInput = false;
|
|
723
|
-
let hasOutput = false;
|
|
724
|
-
let hasReasoning = false;
|
|
725
|
-
let hasCachedInput = false;
|
|
726
|
-
|
|
727
|
-
for (const content of stepMessages) {
|
|
728
|
-
const msg = content as AiSdkV6Message;
|
|
729
|
-
if (msg.role !== "assistant") continue;
|
|
730
|
-
hasAssistant = true;
|
|
731
|
-
|
|
732
|
-
const { textParts, toolCalls, stepsData } = collectAiSdkV6Parts(
|
|
733
|
-
msg.parts ?? [],
|
|
734
|
-
);
|
|
735
|
-
allTextParts.push(...textParts);
|
|
736
|
-
allToolCalls.push(...toolCalls);
|
|
737
|
-
allStepsData.push(...stepsData);
|
|
738
|
-
if (msg.metadata) metadata = msg.metadata;
|
|
739
|
-
|
|
740
|
-
const usage = extractAiSdkV6Usage(msg.metadata);
|
|
741
|
-
if (usage) {
|
|
742
|
-
if (usage.inputTokens != null) {
|
|
743
|
-
inputTokens += usage.inputTokens;
|
|
744
|
-
hasInput = true;
|
|
745
|
-
}
|
|
746
|
-
if (usage.outputTokens != null) {
|
|
747
|
-
outputTokens += usage.outputTokens;
|
|
748
|
-
hasOutput = true;
|
|
749
|
-
}
|
|
750
|
-
if (usage.reasoningTokens != null) {
|
|
751
|
-
reasoningTokens += usage.reasoningTokens;
|
|
752
|
-
hasReasoning = true;
|
|
753
|
-
}
|
|
754
|
-
if (usage.cachedInputTokens != null) {
|
|
755
|
-
cachedInputTokens += usage.cachedInputTokens;
|
|
756
|
-
hasCachedInput = true;
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
if (!hasAssistant) return null;
|
|
762
|
-
return buildAiSdkV6Result(
|
|
763
|
-
allTextParts,
|
|
764
|
-
allToolCalls,
|
|
765
|
-
allStepsData.length,
|
|
766
|
-
metadata,
|
|
767
|
-
allStepsData,
|
|
768
|
-
{
|
|
769
|
-
...(hasInput ? { inputTokens } : undefined),
|
|
770
|
-
...(hasOutput ? { outputTokens } : undefined),
|
|
771
|
-
...(hasReasoning ? { reasoningTokens } : undefined),
|
|
772
|
-
...(hasCachedInput ? { cachedInputTokens } : undefined),
|
|
773
|
-
},
|
|
774
|
-
);
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
export function useAssistantCloudThreadHistoryAdapter(
|
|
778
|
-
cloudRef: RefObject<AssistantCloud>,
|
|
779
|
-
): ThreadHistoryAdapter {
|
|
780
|
-
const aui = useAui();
|
|
781
|
-
const [adapter] = useState(
|
|
782
|
-
() => new AssistantCloudThreadHistoryAdapter(cloudRef, aui),
|
|
783
|
-
);
|
|
784
|
-
return adapter;
|
|
785
|
-
}
|
|
3
|
+
export { useAssistantCloudThreadHistoryAdapter } from "@assistant-ui/core/react";
|