(log: BlockLog, streamedContent: string)
| 21 | * Processes a block log and adds tokenization data if needed |
| 22 | */ |
| 23 | export function processStreamingBlockLog(log: BlockLog, streamedContent: string): boolean { |
| 24 | // Check if this block should be tokenized |
| 25 | if (!isTokenizableBlockType(log.blockType)) { |
| 26 | return false |
| 27 | } |
| 28 | |
| 29 | // Check if we already have meaningful token/cost data |
| 30 | if (hasRealTokenData(log.output?.tokens) && hasRealCostData(log.output?.cost)) { |
| 31 | return false |
| 32 | } |
| 33 | |
| 34 | // Skip recalculation if cost was explicitly set by the billing layer (e.g. BYOK zero cost) |
| 35 | if (log.output?.cost?.pricing) { |
| 36 | return false |
| 37 | } |
| 38 | |
| 39 | // Check if we have content to tokenize |
| 40 | if (!streamedContent?.trim()) { |
| 41 | return false |
| 42 | } |
| 43 | |
| 44 | try { |
| 45 | // Determine model to use |
| 46 | const model = getModelForBlock(log) |
| 47 | |
| 48 | // Prepare input text from log |
| 49 | const inputText = extractTextContent(log.input) |
| 50 | |
| 51 | // Calculate streaming cost |
| 52 | const systemPrompt = |
| 53 | typeof log.input?.systemPrompt === 'string' ? log.input.systemPrompt : undefined |
| 54 | const context = typeof log.input?.context === 'string' ? log.input.context : undefined |
| 55 | const messages = Array.isArray(log.input?.messages) |
| 56 | ? (log.input.messages as Array<{ role: string; content: string }>) |
| 57 | : undefined |
| 58 | const result = calculateStreamingCost( |
| 59 | model, |
| 60 | inputText, |
| 61 | streamedContent, |
| 62 | systemPrompt, |
| 63 | context, |
| 64 | messages |
| 65 | ) |
| 66 | |
| 67 | // Update the log output with tokenization data |
| 68 | if (!log.output) { |
| 69 | log.output = {} |
| 70 | } |
| 71 | |
| 72 | log.output.tokens = result.tokens |
| 73 | log.output.cost = result.cost |
| 74 | log.output.model = result.model |
| 75 | |
| 76 | logTokenizationDetails(`Streaming tokenization completed for ${log.blockType}`, { |
| 77 | blockId: log.blockId, |
| 78 | blockType: log.blockType, |
| 79 | model: result.model, |
| 80 | provider: result.provider, |
no test coverage detected