import { useEffect, useMemo } from "react"; import { Button, Timeline } from "@ace/ui"; import type { Listing } from "@ace/host/protocol"; import { Composer } from "./composer"; import { toEvents } from "./timeline"; import { useTranscript } from "./transcript"; import { Usage } from "./usage"; type Props = { channel: Listing; chat: number; user: string; draft?: string; onDraftLoaded: () => void; onSettings?: () => void; /** Called once the chat loads and whenever its agent may have changed files since. */ onWork?: () => void; }; /** One chat's timeline and composer over its transcript; the content of a Chat tab. */ export function Conversation( { channel, chat: id, user, draft, onDraftLoaded, onSettings, onWork }: Props, ) { const transcript = useTranscript(channel.id, id); const chat = transcript.info?.chats.find((value) => value.id === id); const events = useMemo(() => toEvents(transcript.items, channel.id, transcript.busy), [ transcript.items, channel.id, transcript.busy, ]); const results = useMemo( () => transcript.items.reduce( (sum, item) => item.kind === "reply" ? sum + item.tools.filter((tool) => tool.result).length : sum, 0, ), [transcript.items], ); useEffect(() => { if (transcript.live) onWork?.(); }, [transcript.live, transcript.busy, results, onWork]); return ( <>
{transcript.error || (channel.state === "dormant" ? "Starting channel…" : "Loading chat…")}
{transcript.error && }