Improve MCP status display and message metadata

This commit is contained in:
Shantur Rathore
2025-11-07 23:27:28 +00:00
parent c2d5ecfb5d
commit f59c36f6f8
2 changed files with 101 additions and 37 deletions

View File

@@ -6,32 +6,39 @@ interface InstanceInfoProps {
compact?: boolean
}
function parseMcpStatus(status: unknown): Array<{ name: string; status: "running" | "stopped" | "error" }> {
type ParsedMcpStatus = {
name: string
status: "running" | "stopped" | "error"
error?: string
}
function parseMcpStatus(status: unknown): ParsedMcpStatus[] {
if (!status || typeof status !== "object") return []
try {
const obj = status as Record<string, string>
return Object.entries(obj).map(([name, statusValue]) => {
let mappedStatus: "running" | "stopped" | "error"
const result: ParsedMcpStatus[] = []
if (statusValue === "connected") {
mappedStatus = "running"
} else if (statusValue === "disabled") {
mappedStatus = "stopped"
} else if (statusValue === "failed") {
mappedStatus = "error"
} else {
mappedStatus = "stopped"
}
for (const [name, value] of Object.entries(status as Record<string, unknown>)) {
if (!value || typeof value !== "object") continue
const rawStatus = (value as { status?: string }).status
if (!rawStatus) continue
return {
name,
status: mappedStatus,
}
let mappedStatus: ParsedMcpStatus["status"]
if (rawStatus === "connected") {
mappedStatus = "running"
} else if (rawStatus === "failed") {
mappedStatus = "error"
} else {
mappedStatus = "stopped"
}
result.push({
name,
status: mappedStatus,
error: typeof (value as { error?: unknown }).error === "string" ? (value as { error?: string }).error : undefined,
})
} catch {
return []
}
return result
}
const InstanceInfo: Component<InstanceInfoProps> = (props) => {
@@ -173,19 +180,37 @@ const InstanceInfo: Component<InstanceInfoProps> = (props) => {
<div class="space-y-1.5">
<For each={mcpServers()}>
{(server) => (
<div class="flex items-center justify-between px-2 py-1.5 rounded border bg-surface-secondary border-base">
<span class="text-xs text-primary font-medium truncate">{server.name}</span>
<div class="flex items-center gap-1.5 flex-shrink-0">
<Show when={server.status === "running"}>
<div class="status-dot ready animate-pulse" />
</Show>
<Show when={server.status === "error"}>
<div class="status-dot error" />
</Show>
<Show when={server.status === "stopped"}>
<div class="status-dot stopped" />
</Show>
<div class="px-2 py-1.5 rounded border bg-surface-secondary border-base">
<div class="flex items-center justify-between gap-2">
<span class="text-xs text-primary font-medium truncate">{server.name}</span>
<div class="flex items-center gap-1.5 flex-shrink-0 text-xs text-secondary">
<div
class={`status-dot ${
server.status === "running"
? "ready animate-pulse"
: server.status === "error"
? "error"
: "stopped"
}`}
/>
<span>
{
server.status === "running"
? "Connected"
: server.status === "error"
? "Error"
: "Disabled"
}
</span>
</div>
</div>
<Show when={server.error}>
{(error) => (
<div class="text-[11px] mt-1 break-words" style={{ color: "var(--status-error)" }}>
{error()}
</div>
)}
</Show>
</div>
)}
</For>

View File

@@ -63,13 +63,51 @@ export default function MessageItem(props: MessageItemProps) {
isUser()
? "message-item-base bg-[var(--message-user-bg)] border-l-4 border-[var(--message-user-border)]"
: "message-item-base assistant-message bg-[var(--message-assistant-bg)] border-l-4 border-[var(--message-assistant-border)]"
const agentIdentifier = () => {
if (isUser()) return ""
return (
props.messageInfo?.agent ||
props.messageInfo?.mode ||
props.messageInfo?.agentID ||
props.messageInfo?.agentId ||
props.messageInfo?.metadata?.agentID ||
""
)
}
const modelIdentifier = () => {
if (isUser()) return ""
const modelID =
props.messageInfo?.modelID ||
props.messageInfo?.modelId ||
props.messageInfo?.model?.modelID ||
props.messageInfo?.model?.id ||
""
const providerID =
props.messageInfo?.providerID ||
props.messageInfo?.providerId ||
props.messageInfo?.model?.providerID ||
""
if (modelID && providerID) return `${providerID}/${modelID}`
return modelID
}
return (
<div class={containerClass()}>
<div class="flex justify-between items-center gap-2.5 pb-0.5">
<span class="font-semibold text-xs text-[var(--text-muted)]">
{isUser() ? "You" : "Assistant"}
</span>
<div class="flex flex-col">
<Show when={isUser()}>
<span class="font-semibold text-xs text-[var(--text-muted)]">You</span>
</Show>
<Show when={!isUser()}>
<div class="flex flex-wrap gap-x-3 gap-y-0.5 text-[11px] text-[var(--text-muted)]">
<Show when={agentIdentifier()}>{(value) => <span>Agent: {value()}</span>}</Show>
<Show when={modelIdentifier()}>{(value) => <span>Model: {value()}</span>}</Show>
</div>
</Show>
</div>
<div class="flex items-center gap-2">
<span class="text-[11px] text-[var(--text-muted)]">{timestamp()}</span>
<Show when={isUser() && props.onRevert}>
@@ -94,8 +132,9 @@ export default function MessageItem(props: MessageItemProps) {
</Show>
</div>
</div>
<div class="pt-1 whitespace-pre-wrap break-words leading-[1.1]">
<Show when={props.isQueued && isUser()}>
<div class="message-queued-badge">QUEUED</div>
</Show>