/** * Shared utilities for subagent display components * * Used by both SubagentGroupDisplay (live) and SubagentGroupStatic (frozen). */ import { getModelShortName, resolveModel } from "../../agent/model"; import { OPENAI_CODEX_PROVIDER_NAME } from "../../providers/openai-codex-provider"; import { formatCompact } from "./format"; /** * Format tool count and token statistics for display * * @param toolCount - Number of tool calls * @param totalTokens - Total tokens used (0 or undefined means no data available) * @param isRunning - If true, shows "—" for tokens (since usage is only available at end) */ export function formatStats( toolCount: number, totalTokens: number, isRunning = false, ): string { const toolStr = `${toolCount} tool use${toolCount !== 1 ? "s" : ""}`; // Only show token count if we have actual data (not running and totalTokens > 0) const hasTokenData = !isRunning && totalTokens > 0; if (!hasTokenData) { return toolStr; } return `${toolStr} · ${formatCompact(totalTokens)} tokens`; } /** * Get tree-drawing characters for hierarchical display * * @param isLast - Whether this is the last item in the list * @returns Object with treeChar (branch connector) and continueChar (continuation line) */ export function getTreeChars(isLast: boolean): { treeChar: string; continueChar: string; } { return { treeChar: isLast ? "└─" : "├─", continueChar: isLast ? " " : "│ ", }; } export interface SubagentModelDisplay { label: string; isByokProvider: boolean; isOpenAICodexProvider: boolean; } /** * Format a subagent model identifier using the same logic as the input footer: * short label (if known) + provider-based BYOK marker eligibility. */ export function getSubagentModelDisplay( model: string | undefined, ): SubagentModelDisplay | null { if (!model) return null; // Normalize model IDs (e.g. "haiku") to handles before formatting. const normalized = resolveModel(model) ?? model; const slashIndex = normalized.indexOf("/"); const provider = slashIndex >= 0 ? normalized.slice(0, slashIndex) : normalized; const isOpenAICodexProvider = provider === OPENAI_CODEX_PROVIDER_NAME; const isByokProvider = provider.startsWith("lc-") || isOpenAICodexProvider; const label = getModelShortName(normalized) ?? normalized.split("/").pop() ?? normalized; return { label, isByokProvider, isOpenAICodexProvider, }; }