@anvia/studio 0.7.10 → 0.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/ui/assets/{evals-page-BJKMS1fR.js → evals-page-eIWZ_vsI.js} +2 -2
- package/dist/ui/assets/{evals-page-BJKMS1fR.js.map → evals-page-eIWZ_vsI.js.map} +1 -1
- package/dist/ui/assets/index-CC5mjRie.js +154 -0
- package/dist/ui/assets/index-CC5mjRie.js.map +1 -0
- package/dist/ui/assets/{knowledge-page-COXaxj3j.js → knowledge-page-C6WkzIFh.js} +2 -2
- package/dist/ui/assets/{knowledge-page-COXaxj3j.js.map → knowledge-page-C6WkzIFh.js.map} +1 -1
- package/dist/ui/assets/{mcps-page-D1e6dvNE.js → mcps-page-BJ4m_GoP.js} +2 -2
- package/dist/ui/assets/{mcps-page-D1e6dvNE.js.map → mcps-page-BJ4m_GoP.js.map} +1 -1
- package/dist/ui/assets/{memory-page-Dy11ocsi.js → memory-page-BuerJ-04.js} +2 -2
- package/dist/ui/assets/{memory-page-Dy11ocsi.js.map → memory-page-BuerJ-04.js.map} +1 -1
- package/dist/ui/assets/{pipelines-page-1epSSZ5H.js → pipelines-page-Dx0uB0Dm.js} +2 -2
- package/dist/ui/assets/{pipelines-page-1epSSZ5H.js.map → pipelines-page-Dx0uB0Dm.js.map} +1 -1
- package/dist/ui/assets/{sessions-page-BH7t2H-M.js → sessions-page-UdXui_Zk.js} +2 -2
- package/dist/ui/assets/{sessions-page-BH7t2H-M.js.map → sessions-page-UdXui_Zk.js.map} +1 -1
- package/dist/ui/assets/{status-page-Dlb6Q1aP.js → status-page-DC5pVW4o.js} +2 -2
- package/dist/ui/assets/{status-page-Dlb6Q1aP.js.map → status-page-DC5pVW4o.js.map} +1 -1
- package/dist/ui/assets/{tools-page-BCTZ2glH.js → tools-page-ByKfOqk3.js} +2 -2
- package/dist/ui/assets/{tools-page-BCTZ2glH.js.map → tools-page-ByKfOqk3.js.map} +1 -1
- package/dist/ui/assets/{trace-browser-CkzLOQ8P.js → trace-browser-Dk7nD7KO.js} +2 -2
- package/dist/ui/assets/{trace-browser-CkzLOQ8P.js.map → trace-browser-Dk7nD7KO.js.map} +1 -1
- package/dist/ui/assets/{transcript-item-2OjC7_oe.js → transcript-item-DbtXMj-E.js} +2 -2
- package/dist/ui/assets/{transcript-item-2OjC7_oe.js.map → transcript-item-DbtXMj-E.js.map} +1 -1
- package/dist/ui/index.html +1 -1
- package/package.json +4 -4
- package/dist/ui/assets/index-DMEhoZEd.js +0 -154
- package/dist/ui/assets/index-DMEhoZEd.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-page-Dy11ocsi.js","names":[],"sources":["../../../src/ui/app/modules/memory/memory-page.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport type {\n StudioConfig,\n StudioMemoryConversationMessages,\n StudioMemoryConversationSteps,\n StudioMemoryConversationSummary,\n StudioMemoryConversationsPage,\n StudioMemoryUsersPage,\n} from \"../../../../types\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { formatRelativeTime } from \"../shared/format\";\nimport { JsonSyntax } from \"../shared/renderers\";\n\nexport function MemoryPage(props: { agents: StudioConfig[\"agents\"]; enabled: boolean }) {\n const [users, setUsers] = useState<StudioMemoryUsersPage[\"users\"]>([]);\n const [conversations, setConversations] = useState<StudioMemoryConversationSummary[]>([]);\n const [selectedUserId, setSelectedUserId] = useState(\"\");\n const [selectedConversationId, setSelectedConversationId] = useState(\"\");\n const [messages, setMessages] = useState<StudioMemoryConversationMessages | undefined>();\n const [steps, setSteps] = useState<StudioMemoryConversationSteps | undefined>();\n const [loading, setLoading] = useState(false);\n const [detailLoading, setDetailLoading] = useState(false);\n const [error, setError] = useState(\"\");\n\n const loadMemory = useCallback(async () => {\n if (!props.enabled) {\n setUsers([]);\n setConversations([]);\n setMessages(undefined);\n setSteps(undefined);\n return;\n }\n setLoading(true);\n setError(\"\");\n try {\n const [usersResponse, conversationsResponse] = await Promise.all([\n fetch(\"/memory/users?limit=50\"),\n fetch(\"/memory/conversations?limit=100\"),\n ]);\n if (!usersResponse.ok) {\n throw new Error(`Memory users failed with HTTP ${usersResponse.status}`);\n }\n if (!conversationsResponse.ok) {\n throw new Error(`Memory conversations failed with HTTP ${conversationsResponse.status}`);\n }\n const usersBody = (await usersResponse.json()) as StudioMemoryUsersPage;\n const conversationsBody =\n (await conversationsResponse.json()) as StudioMemoryConversationsPage;\n setUsers(usersBody.users);\n setConversations(conversationsBody.conversations);\n setSelectedConversationId(\n (current) => current || conversationsBody.conversations[0]?.id || \"\",\n );\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError.message : String(loadError));\n } finally {\n setLoading(false);\n }\n }, [props.enabled]);\n\n useEffect(() => {\n void loadMemory();\n }, [loadMemory]);\n\n useEffect(() => {\n if (!props.enabled || selectedConversationId.length === 0) {\n setMessages(undefined);\n setSteps(undefined);\n return;\n }\n let cancelled = false;\n async function loadDetail() {\n setDetailLoading(true);\n try {\n const [messagesResponse, stepsResponse] = await Promise.all([\n fetch(`/memory/conversations/${encodeURIComponent(selectedConversationId)}/messages`),\n fetch(`/memory/conversations/${encodeURIComponent(selectedConversationId)}/steps`),\n ]);\n if (!messagesResponse.ok) {\n throw new Error(`Conversation messages failed with HTTP ${messagesResponse.status}`);\n }\n if (!stepsResponse.ok) {\n throw new Error(`Conversation steps failed with HTTP ${stepsResponse.status}`);\n }\n if (!cancelled) {\n setMessages((await messagesResponse.json()) as StudioMemoryConversationMessages);\n setSteps((await stepsResponse.json()) as StudioMemoryConversationSteps);\n }\n } catch (loadError) {\n if (!cancelled) {\n setError(loadError instanceof Error ? loadError.message : String(loadError));\n setMessages(undefined);\n setSteps(undefined);\n }\n } finally {\n if (!cancelled) {\n setDetailLoading(false);\n }\n }\n }\n void loadDetail();\n return () => {\n cancelled = true;\n };\n }, [props.enabled, selectedConversationId]);\n\n const visibleConversations =\n selectedUserId.length === 0\n ? conversations\n : conversations.filter((conversation) => conversation.userId === selectedUserId);\n const selectedConversation =\n conversations.find((conversation) => conversation.id === selectedConversationId) ??\n visibleConversations[0];\n\n return (\n <section\n className=\"grid min-h-0 grid-rows-[auto_minmax(0,1fr)] overflow-hidden bg-background/55\"\n aria-label=\"Memory\"\n >\n <header className=\"bg-background/70 pb-5 pl-0 pr-6 pt-0 backdrop-blur\">\n <div className=\"grid w-full grid-cols-[minmax(0,1fr)_auto] items-end gap-4 max-md:grid-cols-1\">\n <div className=\"grid min-w-0 gap-2\">\n <div className=\" text-xs font-semibold uppercase tracking-[0.24em] text-foreground\">\n Conversation store\n </div>\n <h1 className=\"m-0 text-2xl font-semibold leading-none tracking-tight text-foreground\">\n Memory\n </h1>\n <p className=\"m-0 max-w-[62ch] text-sm leading-6 text-muted-foreground\">\n Stored users, conversations, raw messages, and transcript steps from the Studio\n session store.\n </p>\n </div>\n <Button\n className=\"h-9 min-h-9 rounded-lg px-3 text-xs\"\n type=\"button\"\n variant=\"secondary\"\n disabled={loading}\n onClick={() => void loadMemory()}\n >\n Refresh\n </Button>\n </div>\n </header>\n\n <div className=\"min-h-0 overflow-auto pb-6 pl-0 pr-6\">\n {!props.enabled ? (\n <EmptyState title=\"Memory unavailable\" text=\"This Studio runtime has no session store.\" />\n ) : loading && conversations.length === 0 ? (\n <EmptyState title=\"Loading memory\" text=\"Reading users and conversations.\" />\n ) : error.length > 0 && conversations.length === 0 ? (\n <EmptyState title=\"Memory error\" text={error} />\n ) : (\n <div className=\"grid min-h-0 gap-4 xl:grid-cols-[280px_minmax(320px,0.8fr)_minmax(0,1.2fr)]\">\n <section className=\"grid content-start gap-2 rounded-xl border border-border/80 bg-card/45 p-3\">\n <PanelHeader title=\"Users\" value={users.length} />\n <Button\n className=\"h-auto min-h-9 justify-start rounded-lg px-3 py-2 text-left text-xs\"\n type=\"button\"\n variant={selectedUserId.length === 0 ? \"secondary\" : \"ghost\"}\n onClick={() => setSelectedUserId(\"\")}\n >\n All users\n </Button>\n {users.map((user) => (\n <Button\n className=\"grid h-auto min-h-14 justify-start rounded-lg px-3 py-2 text-left\"\n type=\"button\"\n variant={selectedUserId === user.userId ? \"secondary\" : \"ghost\"}\n onClick={() => setSelectedUserId(user.userId)}\n key={user.userId}\n >\n <span className=\"min-w-0 truncate text-xs font-semibold\">{user.userId}</span>\n <span className=\"min-w-0 truncate text-xs text-muted-foreground\">\n {user.conversationCount} conversations ·{\" \"}\n {formatRelativeTime(user.lastInteractionAt)}\n </span>\n </Button>\n ))}\n </section>\n\n <section className=\"grid content-start gap-2 rounded-xl border border-border/80 bg-card/45 p-3\">\n <PanelHeader title=\"Conversations\" value={visibleConversations.length} />\n {visibleConversations.length === 0 ? (\n <div className=\"rounded-lg border border-dashed border-border/80 bg-background/45 px-3 py-8 text-center text-sm text-muted-foreground\">\n No conversations.\n </div>\n ) : (\n visibleConversations.map((conversation) => (\n <ConversationButton\n key={conversation.id}\n conversation={conversation}\n agentName={agentLabel(props.agents, conversation.agentId)}\n active={conversation.id === selectedConversationId}\n onSelect={() => setSelectedConversationId(conversation.id)}\n />\n ))\n )}\n </section>\n\n <section className=\"grid min-h-0 content-start gap-4\">\n {selectedConversation === undefined ? (\n <EmptyState\n title=\"No conversation selected\"\n text=\"Choose a conversation to inspect.\"\n />\n ) : (\n <>\n <article className=\"grid gap-3 rounded-xl border border-border/80 bg-card/45 p-5\">\n <div className=\"flex min-w-0 flex-wrap items-start justify-between gap-3\">\n <div className=\"grid min-w-0 gap-1\">\n <h2 className=\"m-0 min-w-0 truncate text-lg font-semibold text-foreground\">\n {selectedConversation.title ?? \"Untitled conversation\"}\n </h2>\n <span className=\"min-w-0 break-all text-xs text-muted-foreground\">\n {selectedConversation.id}\n </span>\n </div>\n <Badge className=\"border-border/80 bg-muted/45 text-foreground\">\n {agentLabel(props.agents, selectedConversation.agentId)}\n </Badge>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-3\">\n <Fact label=\"user\" value={selectedConversation.userId} />\n <Fact label=\"messages\" value={selectedConversation.messageCount} />\n <Fact\n label=\"updated\"\n value={formatRelativeTime(selectedConversation.updatedAt)}\n />\n </div>\n </article>\n {detailLoading ? (\n <EmptyState\n title=\"Loading detail\"\n text=\"Reading message and transcript data.\"\n />\n ) : (\n <div className=\"grid gap-4\">\n <JsonPanel title=\"messages\" value={messages?.messages ?? []} />\n <JsonPanel title=\"steps\" value={steps?.steps ?? []} />\n </div>\n )}\n </>\n )}\n </section>\n </div>\n )}\n </div>\n </section>\n );\n}\n\nfunction ConversationButton(props: {\n conversation: StudioMemoryConversationSummary;\n agentName: string;\n active: boolean;\n onSelect: () => void;\n}) {\n return (\n <Button\n className=\"grid h-auto min-h-20 justify-start gap-2 rounded-lg px-3 py-3 text-left\"\n type=\"button\"\n variant={props.active ? \"secondary\" : \"ghost\"}\n onClick={props.onSelect}\n >\n <div className=\"grid min-w-0 gap-1\">\n <span className=\"min-w-0 truncate text-sm font-semibold text-foreground\">\n {props.conversation.title ?? \"Untitled conversation\"}\n </span>\n <span className=\"min-w-0 truncate text-xs text-muted-foreground\">\n {props.agentName} · {props.conversation.userId}\n </span>\n </div>\n <span className=\" text-xs text-muted-foreground\">\n {props.conversation.messageCount} messages ·{\" \"}\n {formatRelativeTime(props.conversation.updatedAt)}\n </span>\n </Button>\n );\n}\n\nfunction JsonPanel(props: { title: string; value: unknown }) {\n const count = Array.isArray(props.value) ? props.value.length : undefined;\n return (\n <section className=\"grid min-w-0 overflow-hidden rounded-xl border border-border/80 bg-card/45\">\n <div className=\"flex min-h-10 items-center justify-between gap-3 border-b border-border/80 bg-muted/20 px-4\">\n <PanelHeader title={props.title} {...(count === undefined ? {} : { value: count })} />\n </div>\n <div className=\"min-w-0 overflow-x-auto\">\n <pre className=\"m-0 max-h-96 min-w-max p-4 text-xs leading-5 text-foreground\">\n <code>\n <JsonSyntax text={JSON.stringify(props.value, null, 2)} />\n </code>\n </pre>\n </div>\n </section>\n );\n}\n\nfunction PanelHeader(props: { title: string; value?: number }) {\n return (\n <div className=\"flex min-w-0 items-center justify-between gap-3\">\n <h2 className=\"m-0 text-xs font-semibold uppercase tracking-[0.2em] text-muted-foreground\">\n {props.title}\n </h2>\n {props.value === undefined ? null : (\n <span className=\" text-xs font-semibold text-muted-foreground\">{props.value}</span>\n )}\n </div>\n );\n}\n\nfunction Fact(props: { label: string; value: string | number }) {\n return (\n <div className=\"grid min-w-0 gap-1 rounded-lg bg-background/45 px-3 py-2\">\n <span className=\" text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground\">\n {props.label}\n </span>\n <span className=\"min-w-0 truncate text-xs text-foreground\" title={String(props.value)}>\n {props.value}\n </span>\n </div>\n );\n}\n\nfunction EmptyState(props: { title: string; text: string }) {\n return (\n <div className=\"grid min-h-80 place-items-center rounded-xl border border-dashed border-border/80 bg-card/35 px-6 text-center\">\n <div className=\"grid max-w-md gap-2\">\n <h2 className=\"m-0 text-base font-semibold text-foreground\">{props.title}</h2>\n <p className=\"m-0 text-sm leading-6 text-muted-foreground\">{props.text}</p>\n </div>\n </div>\n );\n}\n\nfunction agentLabel(agents: StudioConfig[\"agents\"], agentId: string): string {\n return agents.find((agent) => agent.id === agentId)?.name ?? agentId;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"memory-page-BuerJ-04.js","names":[],"sources":["../../../src/ui/app/modules/memory/memory-page.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport type {\n StudioConfig,\n StudioMemoryConversationMessages,\n StudioMemoryConversationSteps,\n StudioMemoryConversationSummary,\n StudioMemoryConversationsPage,\n StudioMemoryUsersPage,\n} from \"../../../../types\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { formatRelativeTime } from \"../shared/format\";\nimport { JsonSyntax } from \"../shared/renderers\";\n\nexport function MemoryPage(props: { agents: StudioConfig[\"agents\"]; enabled: boolean }) {\n const [users, setUsers] = useState<StudioMemoryUsersPage[\"users\"]>([]);\n const [conversations, setConversations] = useState<StudioMemoryConversationSummary[]>([]);\n const [selectedUserId, setSelectedUserId] = useState(\"\");\n const [selectedConversationId, setSelectedConversationId] = useState(\"\");\n const [messages, setMessages] = useState<StudioMemoryConversationMessages | undefined>();\n const [steps, setSteps] = useState<StudioMemoryConversationSteps | undefined>();\n const [loading, setLoading] = useState(false);\n const [detailLoading, setDetailLoading] = useState(false);\n const [error, setError] = useState(\"\");\n\n const loadMemory = useCallback(async () => {\n if (!props.enabled) {\n setUsers([]);\n setConversations([]);\n setMessages(undefined);\n setSteps(undefined);\n return;\n }\n setLoading(true);\n setError(\"\");\n try {\n const [usersResponse, conversationsResponse] = await Promise.all([\n fetch(\"/memory/users?limit=50\"),\n fetch(\"/memory/conversations?limit=100\"),\n ]);\n if (!usersResponse.ok) {\n throw new Error(`Memory users failed with HTTP ${usersResponse.status}`);\n }\n if (!conversationsResponse.ok) {\n throw new Error(`Memory conversations failed with HTTP ${conversationsResponse.status}`);\n }\n const usersBody = (await usersResponse.json()) as StudioMemoryUsersPage;\n const conversationsBody =\n (await conversationsResponse.json()) as StudioMemoryConversationsPage;\n setUsers(usersBody.users);\n setConversations(conversationsBody.conversations);\n setSelectedConversationId(\n (current) => current || conversationsBody.conversations[0]?.id || \"\",\n );\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError.message : String(loadError));\n } finally {\n setLoading(false);\n }\n }, [props.enabled]);\n\n useEffect(() => {\n void loadMemory();\n }, [loadMemory]);\n\n useEffect(() => {\n if (!props.enabled || selectedConversationId.length === 0) {\n setMessages(undefined);\n setSteps(undefined);\n return;\n }\n let cancelled = false;\n async function loadDetail() {\n setDetailLoading(true);\n try {\n const [messagesResponse, stepsResponse] = await Promise.all([\n fetch(`/memory/conversations/${encodeURIComponent(selectedConversationId)}/messages`),\n fetch(`/memory/conversations/${encodeURIComponent(selectedConversationId)}/steps`),\n ]);\n if (!messagesResponse.ok) {\n throw new Error(`Conversation messages failed with HTTP ${messagesResponse.status}`);\n }\n if (!stepsResponse.ok) {\n throw new Error(`Conversation steps failed with HTTP ${stepsResponse.status}`);\n }\n if (!cancelled) {\n setMessages((await messagesResponse.json()) as StudioMemoryConversationMessages);\n setSteps((await stepsResponse.json()) as StudioMemoryConversationSteps);\n }\n } catch (loadError) {\n if (!cancelled) {\n setError(loadError instanceof Error ? loadError.message : String(loadError));\n setMessages(undefined);\n setSteps(undefined);\n }\n } finally {\n if (!cancelled) {\n setDetailLoading(false);\n }\n }\n }\n void loadDetail();\n return () => {\n cancelled = true;\n };\n }, [props.enabled, selectedConversationId]);\n\n const visibleConversations =\n selectedUserId.length === 0\n ? conversations\n : conversations.filter((conversation) => conversation.userId === selectedUserId);\n const selectedConversation =\n conversations.find((conversation) => conversation.id === selectedConversationId) ??\n visibleConversations[0];\n\n return (\n <section\n className=\"grid min-h-0 grid-rows-[auto_minmax(0,1fr)] overflow-hidden bg-background/55\"\n aria-label=\"Memory\"\n >\n <header className=\"bg-background/70 pb-5 pl-0 pr-6 pt-0 backdrop-blur\">\n <div className=\"grid w-full grid-cols-[minmax(0,1fr)_auto] items-end gap-4 max-md:grid-cols-1\">\n <div className=\"grid min-w-0 gap-2\">\n <div className=\" text-xs font-semibold uppercase tracking-[0.24em] text-foreground\">\n Conversation store\n </div>\n <h1 className=\"m-0 text-2xl font-semibold leading-none tracking-tight text-foreground\">\n Memory\n </h1>\n <p className=\"m-0 max-w-[62ch] text-sm leading-6 text-muted-foreground\">\n Stored users, conversations, raw messages, and transcript steps from the Studio\n session store.\n </p>\n </div>\n <Button\n className=\"h-9 min-h-9 rounded-lg px-3 text-xs\"\n type=\"button\"\n variant=\"secondary\"\n disabled={loading}\n onClick={() => void loadMemory()}\n >\n Refresh\n </Button>\n </div>\n </header>\n\n <div className=\"min-h-0 overflow-auto pb-6 pl-0 pr-6\">\n {!props.enabled ? (\n <EmptyState title=\"Memory unavailable\" text=\"This Studio runtime has no session store.\" />\n ) : loading && conversations.length === 0 ? (\n <EmptyState title=\"Loading memory\" text=\"Reading users and conversations.\" />\n ) : error.length > 0 && conversations.length === 0 ? (\n <EmptyState title=\"Memory error\" text={error} />\n ) : (\n <div className=\"grid min-h-0 gap-4 xl:grid-cols-[280px_minmax(320px,0.8fr)_minmax(0,1.2fr)]\">\n <section className=\"grid content-start gap-2 rounded-xl border border-border/80 bg-card/45 p-3\">\n <PanelHeader title=\"Users\" value={users.length} />\n <Button\n className=\"h-auto min-h-9 justify-start rounded-lg px-3 py-2 text-left text-xs\"\n type=\"button\"\n variant={selectedUserId.length === 0 ? \"secondary\" : \"ghost\"}\n onClick={() => setSelectedUserId(\"\")}\n >\n All users\n </Button>\n {users.map((user) => (\n <Button\n className=\"grid h-auto min-h-14 justify-start rounded-lg px-3 py-2 text-left\"\n type=\"button\"\n variant={selectedUserId === user.userId ? \"secondary\" : \"ghost\"}\n onClick={() => setSelectedUserId(user.userId)}\n key={user.userId}\n >\n <span className=\"min-w-0 truncate text-xs font-semibold\">{user.userId}</span>\n <span className=\"min-w-0 truncate text-xs text-muted-foreground\">\n {user.conversationCount} conversations ·{\" \"}\n {formatRelativeTime(user.lastInteractionAt)}\n </span>\n </Button>\n ))}\n </section>\n\n <section className=\"grid content-start gap-2 rounded-xl border border-border/80 bg-card/45 p-3\">\n <PanelHeader title=\"Conversations\" value={visibleConversations.length} />\n {visibleConversations.length === 0 ? (\n <div className=\"rounded-lg border border-dashed border-border/80 bg-background/45 px-3 py-8 text-center text-sm text-muted-foreground\">\n No conversations.\n </div>\n ) : (\n visibleConversations.map((conversation) => (\n <ConversationButton\n key={conversation.id}\n conversation={conversation}\n agentName={agentLabel(props.agents, conversation.agentId)}\n active={conversation.id === selectedConversationId}\n onSelect={() => setSelectedConversationId(conversation.id)}\n />\n ))\n )}\n </section>\n\n <section className=\"grid min-h-0 content-start gap-4\">\n {selectedConversation === undefined ? (\n <EmptyState\n title=\"No conversation selected\"\n text=\"Choose a conversation to inspect.\"\n />\n ) : (\n <>\n <article className=\"grid gap-3 rounded-xl border border-border/80 bg-card/45 p-5\">\n <div className=\"flex min-w-0 flex-wrap items-start justify-between gap-3\">\n <div className=\"grid min-w-0 gap-1\">\n <h2 className=\"m-0 min-w-0 truncate text-lg font-semibold text-foreground\">\n {selectedConversation.title ?? \"Untitled conversation\"}\n </h2>\n <span className=\"min-w-0 break-all text-xs text-muted-foreground\">\n {selectedConversation.id}\n </span>\n </div>\n <Badge className=\"border-border/80 bg-muted/45 text-foreground\">\n {agentLabel(props.agents, selectedConversation.agentId)}\n </Badge>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-3\">\n <Fact label=\"user\" value={selectedConversation.userId} />\n <Fact label=\"messages\" value={selectedConversation.messageCount} />\n <Fact\n label=\"updated\"\n value={formatRelativeTime(selectedConversation.updatedAt)}\n />\n </div>\n </article>\n {detailLoading ? (\n <EmptyState\n title=\"Loading detail\"\n text=\"Reading message and transcript data.\"\n />\n ) : (\n <div className=\"grid gap-4\">\n <JsonPanel title=\"messages\" value={messages?.messages ?? []} />\n <JsonPanel title=\"steps\" value={steps?.steps ?? []} />\n </div>\n )}\n </>\n )}\n </section>\n </div>\n )}\n </div>\n </section>\n );\n}\n\nfunction ConversationButton(props: {\n conversation: StudioMemoryConversationSummary;\n agentName: string;\n active: boolean;\n onSelect: () => void;\n}) {\n return (\n <Button\n className=\"grid h-auto min-h-20 justify-start gap-2 rounded-lg px-3 py-3 text-left\"\n type=\"button\"\n variant={props.active ? \"secondary\" : \"ghost\"}\n onClick={props.onSelect}\n >\n <div className=\"grid min-w-0 gap-1\">\n <span className=\"min-w-0 truncate text-sm font-semibold text-foreground\">\n {props.conversation.title ?? \"Untitled conversation\"}\n </span>\n <span className=\"min-w-0 truncate text-xs text-muted-foreground\">\n {props.agentName} · {props.conversation.userId}\n </span>\n </div>\n <span className=\" text-xs text-muted-foreground\">\n {props.conversation.messageCount} messages ·{\" \"}\n {formatRelativeTime(props.conversation.updatedAt)}\n </span>\n </Button>\n );\n}\n\nfunction JsonPanel(props: { title: string; value: unknown }) {\n const count = Array.isArray(props.value) ? props.value.length : undefined;\n return (\n <section className=\"grid min-w-0 overflow-hidden rounded-xl border border-border/80 bg-card/45\">\n <div className=\"flex min-h-10 items-center justify-between gap-3 border-b border-border/80 bg-muted/20 px-4\">\n <PanelHeader title={props.title} {...(count === undefined ? {} : { value: count })} />\n </div>\n <div className=\"min-w-0 overflow-x-auto\">\n <pre className=\"m-0 max-h-96 min-w-max p-4 text-xs leading-5 text-foreground\">\n <code>\n <JsonSyntax text={JSON.stringify(props.value, null, 2)} />\n </code>\n </pre>\n </div>\n </section>\n );\n}\n\nfunction PanelHeader(props: { title: string; value?: number }) {\n return (\n <div className=\"flex min-w-0 items-center justify-between gap-3\">\n <h2 className=\"m-0 text-xs font-semibold uppercase tracking-[0.2em] text-muted-foreground\">\n {props.title}\n </h2>\n {props.value === undefined ? null : (\n <span className=\" text-xs font-semibold text-muted-foreground\">{props.value}</span>\n )}\n </div>\n );\n}\n\nfunction Fact(props: { label: string; value: string | number }) {\n return (\n <div className=\"grid min-w-0 gap-1 rounded-lg bg-background/45 px-3 py-2\">\n <span className=\" text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground\">\n {props.label}\n </span>\n <span className=\"min-w-0 truncate text-xs text-foreground\" title={String(props.value)}>\n {props.value}\n </span>\n </div>\n );\n}\n\nfunction EmptyState(props: { title: string; text: string }) {\n return (\n <div className=\"grid min-h-80 place-items-center rounded-xl border border-dashed border-border/80 bg-card/35 px-6 text-center\">\n <div className=\"grid max-w-md gap-2\">\n <h2 className=\"m-0 text-base font-semibold text-foreground\">{props.title}</h2>\n <p className=\"m-0 text-sm leading-6 text-muted-foreground\">{props.text}</p>\n </div>\n </div>\n );\n}\n\nfunction agentLabel(agents: StudioConfig[\"agents\"], agentId: string): string {\n return agents.find((agent) => agent.id === agentId)?.name ?? agentId;\n}\n"],"mappings":"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"}
|