@tangle-network/agent-app 0.44.48 → 0.44.50

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.
@@ -3,9 +3,9 @@ import {
3
3
  ChatMessages,
4
4
  ModelPicker,
5
5
  ProviderLogo
6
- } from "../chunk-T3TYG3VW.js";
6
+ } from "../chunk-D3GK2IPA.js";
7
7
  import "../chunk-FBVLEGEG.js";
8
- import "../chunk-3E4MW5LR.js";
8
+ import "../chunk-YOSSGDIG.js";
9
9
  import "../chunk-YTMKRL3L.js";
10
10
  import "../chunk-GEYACSFW.js";
11
11
  import "../chunk-6MUJROBT.js";
@@ -5,7 +5,7 @@ import { ChatTurnIdentity, ChatTurnProducer } from '@tangle-network/agent-runtim
5
5
  import { C as ChatMessagePart, a as ChatAttachmentPart, e as ChatMentionPart } from '../parts-F8W3-iry.js';
6
6
  import { InteractionAnswerRoute, InteractionAnswerRouteOptions } from '../interactions/index.js';
7
7
  import { PersistedChatMessageForTurn } from '../stream/index.js';
8
- import { T as TurnEventStore } from '../turn-buffer-BcPfhr1_.js';
8
+ import { T as TurnEventStore } from '../turn-buffer-CFKQlnxf.js';
9
9
  import { M as ModelFailoverAttempt } from '../failover-D-3UXXTb.js';
10
10
  export { D as DEFAULT_STALE_TURN_LOCK_GRACE_MS, a as DEFAULT_TERMINAL_TURN_LOCK_GRACE_MS, R as ReconcileStaleTurnLockOptions, b as ReconcileStaleTurnLockResult, S as StaleTurnLockSandboxProbeResult, c as StaleTurnLockSessionProbeResult, r as reconcileStaleTurnLock } from '../stale-turn-lock-DucQzvXu.js';
11
11
  import { J as JsonRecord } from '../stream-normalizer-CnPnMaTp.js';
@@ -68,6 +68,11 @@ interface DraftStoredMessage {
68
68
  role: 'user' | 'assistant' | 'system' | 'tool';
69
69
  content: string;
70
70
  parts?: ChatMessagePart[] | null;
71
+ model?: string | null;
72
+ requestedModel?: string | null;
73
+ servedModel?: string | null;
74
+ servedProvider?: string | null;
75
+ servedSource?: string | null;
71
76
  }
72
77
  /** Values written to the assistant row — the intersection of the append and
73
78
  * patch shapes, so one snapshot serves both. */
@@ -75,6 +80,10 @@ interface AssistantRowValues {
75
80
  content: string;
76
81
  parts?: ChatMessagePart[];
77
82
  model?: string | null;
83
+ requestedModel?: string | null;
84
+ servedModel?: string | null;
85
+ servedProvider?: string | null;
86
+ servedSource?: string | null;
78
87
  inputTokens?: number | null;
79
88
  outputTokens?: number | null;
80
89
  reasoningTokens?: number | null;
@@ -281,6 +290,10 @@ interface ChatTurnMessageStore {
281
290
  content: string;
282
291
  parts?: ChatMessagePart[];
283
292
  model?: string | null;
293
+ requestedModel?: string | null;
294
+ servedModel?: string | null;
295
+ servedProvider?: string | null;
296
+ servedSource?: string | null;
284
297
  inputTokens?: number | null;
285
298
  outputTokens?: number | null;
286
299
  reasoningTokens?: number | null;
@@ -295,6 +308,10 @@ interface ChatTurnMessageStore {
295
308
  content?: string;
296
309
  parts?: ChatMessagePart[];
297
310
  model?: string | null;
311
+ requestedModel?: string | null;
312
+ servedModel?: string | null;
313
+ servedProvider?: string | null;
314
+ servedSource?: string | null;
298
315
  inputTokens?: number | null;
299
316
  outputTokens?: number | null;
300
317
  reasoningTokens?: number | null;
@@ -325,6 +342,9 @@ interface ChatTurnRouteProducer extends ChatTurnProducer {
325
342
  /** Model-failover attribution, when the producer supports it. Reported onto
326
343
  * the usage/billing receipt so a downgrade is never silent. */
327
344
  modelFailover?(): ChatTurnModelFailover;
345
+ /** Requested-versus-served attribution reported by the sandbox sidecar.
346
+ * `echoReceived` distinguishes a missing echo from a partial echo. */
347
+ modelAttribution?(): ChatTurnModelAttribution;
328
348
  }
329
349
  /** Which model served, and what it took to get there. */
330
350
  interface ChatTurnModelFailover {
@@ -335,6 +355,19 @@ interface ChatTurnModelFailover {
335
355
  /** True when the preferred model did not serve. */
336
356
  usedFallback: boolean;
337
357
  }
358
+ /** Requested and effective model attribution for one sandbox turn. */
359
+ interface ChatTurnModelAttribution {
360
+ /** The model explicitly requested by the caller, before shell failover. */
361
+ requestedModel?: string;
362
+ /** The model the downstream sandbox reports actually served the turn. */
363
+ servedModel?: string;
364
+ /** The provider that served the turn, when echoed by the sandbox. */
365
+ servedProvider?: string;
366
+ /** How the sandbox selected the served model. */
367
+ servedSource?: 'request' | 'environment' | 'profile';
368
+ /** True when a structurally valid effective-backend echo was observed. */
369
+ echoReceived: boolean;
370
+ }
338
371
  /** Resolve authorization status and context for a chat turn including tenant and user identification */
339
372
  type ChatTurnAuthorization<TContext> = {
340
373
  ok: true;
@@ -475,6 +508,12 @@ interface ChatTurnLifecycleComplete<TContext> extends ChatTurnLifecycleBase<TCon
475
508
  * `usage` is that model's, so telemetry that splits cost or quality by model
476
509
  * must key on this and not on the requested one. */
477
510
  model?: string;
511
+ /** Requested-versus-served attribution. A difference is detectable from
512
+ * this receipt and from the persisted assistant row independently. */
513
+ requestedModel?: string;
514
+ servedModel?: string;
515
+ servedProvider?: string;
516
+ servedSource?: 'request' | 'environment' | 'profile';
478
517
  /** Attribution for a downgrade: which models were tried and why each failed.
479
518
  * `undefined` when the producer reports no failover support. */
480
519
  modelFailover?: ChatTurnModelFailover;
@@ -520,6 +559,12 @@ interface ChatTurnCompleteInput<TContext> {
520
559
  * the requested one, so a product that bills or scores per model MUST read
521
560
  * it here rather than assuming the model it asked for. */
522
561
  model?: string;
562
+ /** Requested-versus-served attribution. A difference is detectable from
563
+ * this receipt and from the persisted assistant row independently. */
564
+ requestedModel?: string;
565
+ servedModel?: string;
566
+ servedProvider?: string;
567
+ servedSource?: 'request' | 'environment' | 'profile';
523
568
  /** Present when the producer supports failover: the full attempt trail, and
524
569
  * `usedFallback` — the flag that makes a silent downgrade impossible. */
525
570
  modelFailover?: ChatTurnModelFailover;
@@ -1162,6 +1207,14 @@ interface DetachedTurnResult {
1162
1207
  * A caller that bills or scores per model must read this, not the model it
1163
1208
  * requested. */
1164
1209
  model?: string;
1210
+ /** The caller's explicit model request, before shell failover. */
1211
+ requestedModel?: string;
1212
+ /** The effective model echoed by the downstream sandbox. */
1213
+ servedModel?: string;
1214
+ /** The effective provider echoed by the downstream sandbox. */
1215
+ servedProvider?: string;
1216
+ /** How the downstream sandbox selected the effective model. */
1217
+ servedSource?: 'request' | 'environment' | 'profile';
1165
1218
  /** True when the preferred model did not serve. Makes an autonomous
1166
1219
  * downgrade — which no human watched happen — attributable after the fact. */
1167
1220
  usedModelFallback?: boolean;
@@ -1702,4 +1755,4 @@ interface PromoteAgentFilePartOptions {
1702
1755
  /** Promote a part of an agent file with optional byte limits and MIME type detection */
1703
1756
  declare function promoteAgentFilePart(options: PromoteAgentFilePartOptions): Promise<PromoteFilePartResult>;
1704
1757
 
1705
- export { type AssistantDraftSnapshot, type AssistantDraftStore, type AssistantDraftWriter, type AssistantDraftWriterOptions, type AssistantRowValues, type AttachmentPathArgs, type AttachmentPathCheck, type AttachmentReadResult, type AttachmentUploadAuthorization, type AttachmentWriteResult, type BuildDispatchPartsInput, ChatAttachmentKind, type ChatRouteDurableProjection, type ChatRouteDurableProjectionLogger, type ChatRouteEvent, type ChatTurnAuthorization, type ChatTurnAuthorizeArgs, type ChatTurnCompleteInput, ChatTurnFilePartInput, type ChatTurnGateResult, type ChatTurnHeartbeat, type ChatTurnInputPatch, type ChatTurnLifecycle, type ChatTurnLifecycleComplete, type ChatTurnLifecycleError, type ChatTurnLifecycleStart, type ChatTurnLock, type ChatTurnLockResult, type ChatTurnMessageStore, type ChatTurnModelFailover, ChatTurnPartInput, type ChatTurnProduceArgs, ChatTurnRequestPayload, type ChatTurnRouteProducer, type ChatTurnRoutes, type ChatTurnUsage, type CreateAttachmentUploadRouteOptions, type CreateChatTurnRoutesOptions, type CreateUploadRouteOptions, type DetachedTurnFinal, type DetachedTurnOptions, type DetachedTurnParts, type DetachedTurnResult, type DispatchPartsOutcome, type DraftPersistenceTuning, type DraftStoredMessage, type EmptyTurnRetryInfo, type FilePartPromotionOutcome, MAX_EMPTY_TURN_RETRIES, type ModelFailoverStreamHandle, type ModelFailoverStreamOptions, type ModelFallbackInfo, type OpenModelStream, PROMOTE_MAX_FILE_BYTES, type PromoteAgentFilePartOptions, type PromoteFilePartResult, PromptInputPart, type RawAgentFilePart, type ReadAttachmentFn, type ReadSandboxMentionFn, type ResolveChatAttachmentsOptions, type ResolveChatAttachmentsResult, type SandboxChatProducerOptions, type SandboxUploadSink, UPLOAD_INLINE_MAX_BYTES, UPLOAD_MAX_FILE_BYTES, type UploadAuthorization, type UploadedChatFile, type WriteAttachmentFn, assistantRowIdForTurn, buildDispatchParts, bytesToBase64, classifyTerminalFailure, createAssistantDraftWriter, createAttachmentUploadRoute, createChatTurnRoutes, createSandboxChatProducer, createUploadRoute, defaultValidateAttachmentPath, isCommittingSandboxEvent, isDraftContentEvent, normalizeChatPromptForSandbox, promoteAgentFilePart, resolveChatAttachments, resolveEmptyTurnRetries, rowIdOf, runDetachedTurn, sanitizeUploadFilename, sniffMimeFromName, storeSupportsDraftPersistence, streamWithModelFailover, summarizeFailoverReason, withDurableChatProjection };
1758
+ export { type AssistantDraftSnapshot, type AssistantDraftStore, type AssistantDraftWriter, type AssistantDraftWriterOptions, type AssistantRowValues, type AttachmentPathArgs, type AttachmentPathCheck, type AttachmentReadResult, type AttachmentUploadAuthorization, type AttachmentWriteResult, type BuildDispatchPartsInput, ChatAttachmentKind, type ChatRouteDurableProjection, type ChatRouteDurableProjectionLogger, type ChatRouteEvent, type ChatTurnAuthorization, type ChatTurnAuthorizeArgs, type ChatTurnCompleteInput, ChatTurnFilePartInput, type ChatTurnGateResult, type ChatTurnHeartbeat, type ChatTurnInputPatch, type ChatTurnLifecycle, type ChatTurnLifecycleComplete, type ChatTurnLifecycleError, type ChatTurnLifecycleStart, type ChatTurnLock, type ChatTurnLockResult, type ChatTurnMessageStore, type ChatTurnModelAttribution, type ChatTurnModelFailover, ChatTurnPartInput, type ChatTurnProduceArgs, ChatTurnRequestPayload, type ChatTurnRouteProducer, type ChatTurnRoutes, type ChatTurnUsage, type CreateAttachmentUploadRouteOptions, type CreateChatTurnRoutesOptions, type CreateUploadRouteOptions, type DetachedTurnFinal, type DetachedTurnOptions, type DetachedTurnParts, type DetachedTurnResult, type DispatchPartsOutcome, type DraftPersistenceTuning, type DraftStoredMessage, type EmptyTurnRetryInfo, type FilePartPromotionOutcome, MAX_EMPTY_TURN_RETRIES, type ModelFailoverStreamHandle, type ModelFailoverStreamOptions, type ModelFallbackInfo, type OpenModelStream, PROMOTE_MAX_FILE_BYTES, type PromoteAgentFilePartOptions, type PromoteFilePartResult, PromptInputPart, type RawAgentFilePart, type ReadAttachmentFn, type ReadSandboxMentionFn, type ResolveChatAttachmentsOptions, type ResolveChatAttachmentsResult, type SandboxChatProducerOptions, type SandboxUploadSink, UPLOAD_INLINE_MAX_BYTES, UPLOAD_MAX_FILE_BYTES, type UploadAuthorization, type UploadedChatFile, type WriteAttachmentFn, assistantRowIdForTurn, buildDispatchParts, bytesToBase64, classifyTerminalFailure, createAssistantDraftWriter, createAttachmentUploadRoute, createChatTurnRoutes, createSandboxChatProducer, createUploadRoute, defaultValidateAttachmentPath, isCommittingSandboxEvent, isDraftContentEvent, normalizeChatPromptForSandbox, promoteAgentFilePart, resolveChatAttachments, resolveEmptyTurnRetries, rowIdOf, runDetachedTurn, sanitizeUploadFilename, sniffMimeFromName, storeSupportsDraftPersistence, streamWithModelFailover, summarizeFailoverReason, withDurableChatProjection };
@@ -15,18 +15,20 @@ import {
15
15
  sniffBinary
16
16
  } from "../chunk-WBHPN5DY.js";
17
17
  import {
18
- coalesceDeltas,
19
- createBufferedTurnTap,
20
18
  normalizeClientTurnId,
21
- replayTurnEvents,
22
- resolveChatTurn,
23
- stampReplaySeq
24
- } from "../chunk-2EJFIQUV.js";
19
+ resolveChatTurn
20
+ } from "../chunk-JEZJ6HTF.js";
25
21
  import {
26
22
  DEFAULT_STALE_TURN_LOCK_GRACE_MS,
27
23
  DEFAULT_TERMINAL_TURN_LOCK_GRACE_MS,
28
24
  reconcileStaleTurnLock
29
25
  } from "../chunk-CCVWR33L.js";
26
+ import {
27
+ coalesceDeltas,
28
+ createBufferedTurnTap,
29
+ replayTurnEvents,
30
+ stampReplaySeq
31
+ } from "../chunk-6VWA26BV.js";
30
32
  import {
31
33
  createInteractionAnswerRoute
32
34
  } from "../chunk-6KMAM7BL.js";
@@ -502,6 +504,7 @@ function createChatTurnRoutes(options) {
502
504
  });
503
505
  } else {
504
506
  const failoverInfo = producer?.modelFailover?.();
507
+ const attribution = producer?.modelAttribution?.();
505
508
  await lifecycle.onTurnComplete?.({
506
509
  identity,
507
510
  executionId,
@@ -513,6 +516,10 @@ function createChatTurnRoutes(options) {
513
516
  assistantMessageId: assistantRowId(),
514
517
  ...gatedTurn ? { gated: true } : {},
515
518
  ...producer?.model ? { model: producer.model } : {},
519
+ ...attribution?.requestedModel ? { requestedModel: attribution.requestedModel } : {},
520
+ ...attribution?.servedModel ? { servedModel: attribution.servedModel } : {},
521
+ ...attribution?.servedProvider ? { servedProvider: attribution.servedProvider } : {},
522
+ ...attribution?.servedSource ? { servedSource: attribution.servedSource } : {},
516
523
  ...failoverInfo ? { modelFailover: failoverInfo } : {}
517
524
  });
518
525
  }
@@ -657,10 +664,15 @@ function createChatTurnRoutes(options) {
657
664
  return;
658
665
  }
659
666
  const usage = producer?.usage?.() ?? {};
667
+ const attribution = producer?.modelAttribution?.();
660
668
  const values = {
661
669
  content: finalText,
662
670
  ...parts && parts.length > 0 ? { parts } : {},
663
671
  ...producer?.model ? { model: producer.model } : {},
672
+ ...attribution?.requestedModel ? { requestedModel: attribution.requestedModel } : {},
673
+ ...attribution?.servedModel ? { servedModel: attribution.servedModel } : {},
674
+ ...attribution?.servedProvider ? { servedProvider: attribution.servedProvider } : {},
675
+ ...attribution?.servedSource ? { servedSource: attribution.servedSource } : {},
664
676
  ...usage.inputTokens !== void 0 ? { inputTokens: usage.inputTokens } : {},
665
677
  ...usage.outputTokens !== void 0 ? { outputTokens: usage.outputTokens } : {},
666
678
  ...usage.reasoningTokens !== void 0 ? { reasoningTokens: usage.reasoningTokens } : {},
@@ -689,6 +701,7 @@ function createChatTurnRoutes(options) {
689
701
  // complete with empty text.
690
702
  onTurnComplete: ({ identity: turnIdentity, finalText }) => {
691
703
  const failoverInfo = producer?.modelFailover?.();
704
+ const attribution = producer?.modelAttribution?.();
692
705
  return options.onTurnComplete({
693
706
  identity: turnIdentity,
694
707
  finalText,
@@ -697,6 +710,10 @@ function createChatTurnRoutes(options) {
697
710
  assistantMessageId: assistantRowId(),
698
711
  ...runFailed ? { failureReason: failureReasonOf(lastFailureData) } : {},
699
712
  ...producer?.model ? { model: producer.model } : {},
713
+ ...attribution?.requestedModel ? { requestedModel: attribution.requestedModel } : {},
714
+ ...attribution?.servedModel ? { servedModel: attribution.servedModel } : {},
715
+ ...attribution?.servedProvider ? { servedProvider: attribution.servedProvider } : {},
716
+ ...attribution?.servedSource ? { servedSource: attribution.servedSource } : {},
700
717
  ...failoverInfo ? { modelFailover: failoverInfo } : {}
701
718
  });
702
719
  }
@@ -1027,6 +1044,20 @@ function textDelta(tracker, key, part, rawDelta) {
1027
1044
  tracker.seen.set(key, snapshot);
1028
1045
  return snapshot;
1029
1046
  }
1047
+ function parseEffectiveBackend(data) {
1048
+ const backend = asRecord(data.effectiveBackend);
1049
+ if (!backend) return void 0;
1050
+ const provider = asString(backend.provider);
1051
+ const model = asString(backend.model);
1052
+ const rawSource = asString(backend.source);
1053
+ const source = rawSource === "request" || rawSource === "environment" || rawSource === "profile" ? rawSource : void 0;
1054
+ if (!provider && !model && !source) return void 0;
1055
+ return {
1056
+ ...model ? { servedModel: model } : {},
1057
+ ...provider ? { servedProvider: provider } : {},
1058
+ ...source ? { servedSource: source } : {}
1059
+ };
1060
+ }
1030
1061
  function usageFromStepFinish(part, usage) {
1031
1062
  const tokens = asRecord(part.tokens);
1032
1063
  if (tokens) {
@@ -1161,6 +1192,22 @@ function createSandboxChatProducer(options) {
1161
1192
  source = options.events;
1162
1193
  }
1163
1194
  const servingModel = () => failover?.servingModel() ?? options.model;
1195
+ let effectiveBackend;
1196
+ let substitutionNoticeQueued = false;
1197
+ const servedModel = () => effectiveBackend?.servedModel ?? servingModel();
1198
+ const captureEffectiveBackend = (data) => {
1199
+ if (!data) return;
1200
+ const parsed = parseEffectiveBackend(data);
1201
+ if (!parsed) return;
1202
+ effectiveBackend = parsed;
1203
+ const sentModel = servingModel();
1204
+ if (substitutionNoticeQueued || !options.model || !sentModel || !parsed.servedModel || parsed.servedModel === sentModel) return;
1205
+ substitutionNoticeQueued = true;
1206
+ pendingModelNotices.push({
1207
+ id: "model-substitution-1",
1208
+ text: `Requested ${sentModel} \u2014 the sandbox answered with ${parsed.servedModel} instead.`
1209
+ });
1210
+ };
1164
1211
  let fullText = "";
1165
1212
  const partOrder = [];
1166
1213
  const partMap = /* @__PURE__ */ new Map();
@@ -1218,8 +1265,9 @@ function createSandboxChatProducer(options) {
1218
1265
  async function* stream() {
1219
1266
  try {
1220
1267
  for await (const raw of source) {
1221
- yield* drainModelNotices();
1222
1268
  const record = asRecord(raw);
1269
+ captureEffectiveBackend(asRecord(record?.data));
1270
+ yield* drainModelNotices();
1223
1271
  if (!record || typeof record.type !== "string") continue;
1224
1272
  const normalized = normalizeToolEvent({ type: record.type, data: asRecord(record.data) });
1225
1273
  const event = normalized.type === "message.part.updated" ? normalized : { type: record.type, data: asRecord(record.data) };
@@ -1485,12 +1533,17 @@ ${diagnostic.userMessage}` : diagnostic.userMessage;
1485
1533
  // model into the row and make a downgrade unattributable — the exact
1486
1534
  // failure mode this work exists to prevent.
1487
1535
  get model() {
1488
- return servingModel();
1536
+ return servedModel();
1489
1537
  },
1490
1538
  modelFailover: () => ({
1491
1539
  model: servingModel(),
1492
1540
  attempts: failover?.attempts() ?? [],
1493
1541
  usedFallback: failover?.usedFallback() ?? false
1542
+ }),
1543
+ modelAttribution: () => ({
1544
+ ...options.model ? { requestedModel: options.model } : {},
1545
+ ...effectiveBackend ?? {},
1546
+ echoReceived: effectiveBackend !== void 0
1494
1547
  })
1495
1548
  };
1496
1549
  }
@@ -1542,10 +1595,23 @@ async function runDetachedTurn(opts) {
1542
1595
  });
1543
1596
  }
1544
1597
  const settleRow = async (base) => {
1598
+ const persisted = !producer && opts.persist ? (await opts.persist.store.listMessages(opts.persist.threadId)).find(
1599
+ (message) => message.id === (opts.persist?.messageId ?? assistantRowIdForTurn(turnId))
1600
+ ) : void 0;
1545
1601
  const info = producer?.modelFailover?.();
1602
+ const attribution = producer?.modelAttribution?.();
1603
+ const model = producer?.model ?? persisted?.model ?? opts.model;
1604
+ const requestedModel = attribution?.requestedModel ?? persisted?.requestedModel ?? opts.model;
1605
+ const servedModel = attribution?.servedModel ?? persisted?.servedModel;
1606
+ const servedProvider = attribution?.servedProvider ?? persisted?.servedProvider;
1607
+ const servedSource = attribution?.servedSource ?? (persisted?.servedSource === "request" || persisted?.servedSource === "environment" || persisted?.servedSource === "profile" ? persisted.servedSource : void 0);
1546
1608
  const result = {
1547
1609
  ...base,
1548
- ...servingModel() ? { model: servingModel() } : {},
1610
+ ...model ? { model } : {},
1611
+ ...requestedModel ? { requestedModel } : {},
1612
+ ...servedModel ? { servedModel } : {},
1613
+ ...servedProvider ? { servedProvider } : {},
1614
+ ...servedSource ? { servedSource } : {},
1549
1615
  ...info ? { usedModelFallback: info.usedFallback, modelAttempts: info.attempts } : {}
1550
1616
  };
1551
1617
  if (!draft) return result;
@@ -1565,6 +1631,10 @@ async function runDetachedTurn(opts) {
1565
1631
  content,
1566
1632
  ...parts2.length > 0 ? { parts: parts2 } : {},
1567
1633
  ...result.model ? { model: result.model } : {},
1634
+ ...result.requestedModel ? { requestedModel: result.requestedModel } : {},
1635
+ ...result.servedModel ? { servedModel: result.servedModel } : {},
1636
+ ...result.servedProvider ? { servedProvider: result.servedProvider } : {},
1637
+ ...result.servedSource ? { servedSource: result.servedSource } : {},
1568
1638
  ...result.usage.inputTokens !== void 0 ? { inputTokens: result.usage.inputTokens } : {},
1569
1639
  ...result.usage.outputTokens !== void 0 ? { outputTokens: result.usage.outputTokens } : {},
1570
1640
  ...result.usage.reasoningTokens !== void 0 ? { reasoningTokens: result.usage.reasoningTokens } : {},