basant307/AI_Governance_Project
048
1/**2 * @license3 * Copyright 2026 Qwen Team4 * SPDX-License-Identifier: Apache-2.05 */6 7import type { GenerateContentResponse } from '@google/genai';8 9/**10 * Detects whether a streaming chunk contains user-visible model output.11 *12 * Used by the LoggingContentGenerator stream wrapper to identify the first13 * chunk that should trigger TTFT (time-to-first-token) measurement.14 *15 * A chunk is "user-visible" if any normalized Part in candidates[0].content.parts16 * is one of:17 * - text with a non-empty string18 * - functionCall (tool use — even tool-call-only responses count)19 * - inlineData (image, binary blob)20 * - executableCode (sandbox / code-execution responses)21 * - thought / reasoning content (provider-dependent; o1, qwen thinking, Anthropic <thinking>)22 *23 * Chunks containing only role metadata, only usageMetadata (final summary24 * chunk), or empty parts are NOT user-visible — TTFT should not fire on these.25 *26 * Centralised here (single predicate over the normalized GenerateContentResponse27 * shape) so the four provider generators (Anthropic / OpenAI / Gemini / Qwen)28 * don't each need their own first-token logic. Each provider already normalizes29 * its native chunk shape to GenerateContentResponse before LoggingContentGenerator30 * sees it (see loggingContentGenerator.ts generateContentStream).31 */32export function hasUserVisibleContent(chunk: GenerateContentResponse): boolean {33 const parts = chunk.candidates?.[0]?.content?.parts;34 if (!parts || parts.length === 0) return false;35 return parts.some(isUserVisiblePart);36}37 38function isUserVisiblePart(part: unknown): boolean {39 if (part === null || typeof part !== 'object') return false;40 const p = part as {41 text?: unknown;42 functionCall?: unknown;43 inlineData?: unknown;44 executableCode?: unknown;45 thought?: unknown;46 };47 if (typeof p.text === 'string' && p.text.length > 0) return true;48 if (p.functionCall !== undefined) return true;49 if (p.inlineData !== undefined) return true;50 if (p.executableCode !== undefined) return true;51 // `thought` is a boolean flag in this codebase — `true` means the part52 // carries reasoning content, false / absent means none (see loggingContentGenerator.ts53 // where `part.thought ? {...} : {}` is the canonical pattern). Match strict `=== true`54 // rather than checking presence — `thought: false` parts are explicitly NOT user-visible.55 if (p.thought === true) return true;56 return false;57}58 