import { formatDurationHuman } from "../../../src/infra/format-time/format-duration.ts" ;
import { formatRelativeTimestamp } from "../../../src/infra/format-time/format-relative.ts" ;
import { stripAssistantInternalScaffolding } from "../../../src/shared/text/assistant-visible-text.js" ;
import { t } from "../i18n/index.ts" ;
export { formatRelativeTimestamp, formatDurationHuman };
export function formatUnknownText(
value: unknown,
opts: { fallback?: string; pretty?: boolean } = {},
): string {
const fallback = opts.fallback ?? "" ;
if (value == null ) {
return fallback;
}
if (typeof value === "string" ) {
return value;
}
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" ) {
return String(value);
}
if (typeof value === "symbol" ) {
return value.description ? `Symbol(${value.description})` : "Symbol()" ;
}
try {
const serialized = JSON.stringify(value, null , opts.pretty ? 2 : undefined);
if (serialized !== undefined) {
return serialized;
}
} catch {
// Fall back when value is not JSON-serializable.
}
if (value instanceof Error) {
return value.message || value.name;
}
return Object.prototype.toString.call(value);
}
export function formatMs(ms?: number | null ): string {
if (!ms && ms !== 0 ) {
return t("common.na" );
}
return new Date(ms).toLocaleString();
}
export function formatList(values?: Array<string | null | undefined>): string {
if (!values || values.length === 0 ) {
return "none" ;
}
return values.filter((v): v is string => Boolean (v && v.trim())).join(", " );
}
export function clampText(value: string, max = 120 ): string {
if (value.length <= max) {
return value;
}
return `${value.slice(0 , Math.max(0 , max - 1 ))}…`;
}
export function truncateText(
value: string,
max: number,
): {
text: string;
truncated: boolean ;
total: number;
} {
if (value.length <= max) {
return { text: value, truncated: false , total: value.length };
}
return {
text: value.slice(0 , Math.max(0 , max)),
truncated: true ,
total: value.length,
};
}
export function toNumber(value: string, fallback: number): number {
const n = Number(value);
return Number.isFinite(n) ? n : fallback;
}
export function stripThinkingTags(value: string): string {
return stripAssistantInternalScaffolding(value);
}
export function formatCost(cost: number | null | undefined, fallback = "$0.00" ): string {
if (cost == null || !Number.isFinite(cost)) {
return fallback;
}
if (cost === 0 ) {
return "$0.00" ;
}
if (cost < 0 .01 ) {
return `$${cost.toFixed(4 )}`;
}
if (cost < 1 ) {
return `$${cost.toFixed(3 )}`;
}
return `$${cost.toFixed(2 )}`;
}
export function formatTokens(tokens: number | null | undefined, fallback = "0" ): string {
if (tokens == null || !Number.isFinite(tokens)) {
return fallback;
}
if (tokens < 1000 ) {
return String(Math.round(tokens));
}
if (tokens < 1 _000 _000 ) {
const k = tokens / 1000 ;
return k < 10 ? `${k.toFixed(1 )}k` : `${Math.round(k)}k`;
}
const m = tokens / 1 _000 _000 ;
return m < 10 ? `${m.toFixed(1 )}M` : `${Math.round(m)}M`;
}
Messung V0.5 in Prozent C=95 H=98 G=96
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland