llm-usage.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. export interface LlmUsage {
  2. inputTokens?: number
  3. outputTokens?: number
  4. totalTokens?: number
  5. cachedInputTokens?: number
  6. cacheWriteInputTokens?: number
  7. }
  8. const USAGE_FIELDS = [
  9. "inputTokens",
  10. "outputTokens",
  11. "totalTokens",
  12. "cachedInputTokens",
  13. "cacheWriteInputTokens",
  14. ] as const satisfies ReadonlyArray<keyof LlmUsage>
  15. function combineLlmUsage(
  16. left: LlmUsage | undefined,
  17. right: LlmUsage | undefined,
  18. combine: (leftValue: number, rightValue: number) => number,
  19. ): LlmUsage | undefined {
  20. if (!left) return right ? { ...right } : undefined
  21. if (!right) return { ...left }
  22. const result: LlmUsage = {}
  23. for (const field of USAGE_FIELDS) {
  24. const leftValue = left[field]
  25. const rightValue = right[field]
  26. if (leftValue === undefined && rightValue === undefined) continue
  27. if (leftValue === undefined) result[field] = rightValue
  28. else if (rightValue === undefined) result[field] = leftValue
  29. else result[field] = combine(leftValue, rightValue)
  30. }
  31. return result
  32. }
  33. export function mergeLlmUsageSnapshot(
  34. current: LlmUsage | undefined,
  35. next: LlmUsage | undefined,
  36. ): LlmUsage | undefined {
  37. return combineLlmUsage(current, next, Math.max)
  38. }
  39. export function addLlmUsage(
  40. current: LlmUsage | undefined,
  41. next: LlmUsage | undefined,
  42. ): LlmUsage | undefined {
  43. return combineLlmUsage(current, next, (left, right) => left + right)
  44. }