Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/ultra/display.ts

Raw
// Human views of structured data. Never use these to serialize agent payloads.

import type { TokenUsage } from "./runner.ts";

function compactTokens(tokens: number): string {
	if (tokens < 1000) return String(tokens);
	const units = ["", "k", "M", "G"];
	let unit = Math.min(Math.floor(Math.log10(tokens) / 3), units.length - 1);
	let value = Number((tokens / 1000 ** unit).toPrecision(3));
	if (value >= 1000 && unit < units.length - 1) {
		value /= 1000;
		unit++;
	}
	return `${value}${units[unit]}`;
}

export function formatUsage(usage: TokenUsage): {
	summary: string;
	detail: string;
} {
	const cost =
		usage.cost > 0 && usage.cost < 0.0001
			? "<$0.0001"
			: `$${usage.cost.toFixed(4)}`;
	return {
		summary: `${cost} · ${compactTokens(usage.output)} output`,
		detail: `${compactTokens(usage.input)} uncached input · ${compactTokens(usage.cacheRead)} cache read · ${compactTokens(usage.cacheWrite)} cache write`,
	};
}

function label(key: string): string {
	const words = key
		.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
		.replace(/[_-]+/g, " ");
	return words.charAt(0).toUpperCase() + words.slice(1);
}

function structuredValue(value: unknown): unknown {
	if (typeof value !== "string") return value;
	const json = value.trim().replace(/^```json\s*\n([\s\S]*?)\n```$/i, "$1");
	if (!json.startsWith("{") && !json.startsWith("[")) return value;
	try {
		return JSON.parse(json);
	} catch {
		return value;
	}
}

function scalar(value: unknown): string {
	if (value === null) return "None";
	if (value === undefined) return "Not provided";
	return String(value);
}

function count(value: object): string {
	const size = Array.isArray(value) ? value.length : Object.keys(value).length;
	const noun = Array.isArray(value) ? "item" : "field";
	return `${size} ${noun}${size === 1 ? "" : "s"}`;
}

/** One bounded line for progress, never a nested payload. */
export function summarizeValue(value: unknown): string {
	value = structuredValue(value);
	let summary: string;
	if (value === undefined) return "";
	if (Array.isArray(value)) summary = count(value);
	else if (value !== null && typeof value === "object") {
		const entries = Object.entries(value);
		const title = ["summary", "title", "task", "name", "file", "path", "id"]
			.map((key) => entries.find(([name]) => name === key)?.[1])
			.find((entry) => typeof entry === "string" && entry.trim());
		summary =
			typeof title === "string"
				? title
				: entries
						.slice(0, 3)
						.map(
							([key, entry]) =>
								`${label(key)}: ${entry !== null && typeof entry === "object" ? count(entry) : scalar(entry)}`,
						)
						.join(" · ") || count(value);
		if (!title && entries.length > 3)
			summary += ` · +${entries.length - 3} fields`;
	} else summary = scalar(value);
	summary = summary.replace(/\s+/g, " ").trim();
	return summary.length > 120 ? `${summary.slice(0, 119)}…` : summary;
}

/** Complete field/list view of JSON values, with explicit empty collections. */
export function formatValueMarkdown(value: unknown): string {
	value = structuredValue(value);
	const indent = (text: string) =>
		text
			.split("\n")
			.map((line) => `  ${line}`)
			.join("\n");
	if (Array.isArray(value)) {
		if (value.length === 0) return "- No items";
		return value
			.map(structuredValue)
			.map((entry, index) =>
				entry !== null && typeof entry === "object"
					? `- **Item ${index + 1}**\n${indent(formatValueMarkdown(entry))}`
					: formatValueMarkdown(entry),
			)
			.join("\n");
	}
	if (value !== null && typeof value === "object") {
		const entries = Object.entries(value);
		if (entries.length === 0) return "- No fields";
		return entries
			.map(([key, raw]) => {
				const entry = structuredValue(raw);
				const heading = `- **${label(key).replace(/[\\`*_[\]<>]/g, "\\$&")}:**`;
				return entry !== null && typeof entry === "object"
					? `${heading}\n${indent(formatValueMarkdown(entry))}`
					: `${heading} ${scalar(entry).replace(/\n/g, "  \n  ")}`;
			})
			.join("\n");
	}
	return `- ${scalar(value).replace(/\n/g, "  \n  ")}`;
}

/** Tool text may carry a complete JSON document; prose and incomplete data stay verbatim. */
export function formatStructuredText(
	text: string,
	render: (value: unknown) => string = formatValueMarkdown,
): string {
	const json = text.trim().replace(/^```json\s*\n([\s\S]*?)\n```$/i, "$1");
	try {
		return render(JSON.parse(json));
	} catch {
		return text;
	}
}