import type { AgentLogEntry } from "@kb/core";
import { ProviderIcon } from "./ProviderIcon";
interface ModelInfo {
provider?: string;
modelId?: string;
}
interface AgentLogViewerProps {
entries: AgentLogEntry[];
loading: boolean;
executorModel?: ModelInfo | null;
validatorModel?: ModelInfo | null;
}
/**
* Renders agent log entries in a scrollable, monospace container.
* Displays entries in reverse chronological order (newest first).
*/
export function AgentLogViewer({ entries, loading, executorModel, validatorModel }: AgentLogViewerProps) {
if (loading && entries.length === 0) {
return (
{/* Model info header */}
Executor:
{hasExecutorOverride ? (
{executorModel.provider}/{executorModel.modelId}
) : (
Using default
)}
Validator:
{hasValidatorOverride ? (
{validatorModel.provider}/{validatorModel.modelId}
) : (
Using default
)}
{reversedEntries.map((entry, i) => {
// Look at previous entry in reversed array (= next chronologically) for deduplication
const prev = reversedEntries[i - 1];
const isBlockLevel = entry.type === "tool" || entry.type === "tool_result" || entry.type === "tool_error";
const showBadge = entry.agent
? isBlockLevel || i === 0 || (prev && (prev.agent !== entry.agent || prev.type !== entry.type))
: false;
const agentBadge = showBadge ? (
[{entry.agent}]
) : null;
if (entry.type === "tool") {
return (
{agentBadge}⚡ {entry.text}
{entry.detail && (
— {entry.detail}
)}
);
}
if (entry.type === "thinking") {
return (
{agentBadge}{entry.text}
);
}
if (entry.type === "tool_result") {
return (
{agentBadge}✓ {entry.text}
{entry.detail && (
— {entry.detail}
)}
);
}
if (entry.type === "tool_error") {
return (
{agentBadge}✗ {entry.text}
{entry.detail && (
— {entry.detail}
)}
);
}
// Default: text entries
return (
{agentBadge}{entry.text}
);
})}
);
}