Improve MCP status display and message metadata
This commit is contained in:
@@ -6,32 +6,39 @@ interface InstanceInfoProps {
|
|||||||
compact?: boolean
|
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 []
|
if (!status || typeof status !== "object") return []
|
||||||
|
|
||||||
try {
|
const result: ParsedMcpStatus[] = []
|
||||||
const obj = status as Record<string, string>
|
|
||||||
return Object.entries(obj).map(([name, statusValue]) => {
|
|
||||||
let mappedStatus: "running" | "stopped" | "error"
|
|
||||||
|
|
||||||
if (statusValue === "connected") {
|
for (const [name, value] of Object.entries(status as Record<string, unknown>)) {
|
||||||
mappedStatus = "running"
|
if (!value || typeof value !== "object") continue
|
||||||
} else if (statusValue === "disabled") {
|
const rawStatus = (value as { status?: string }).status
|
||||||
mappedStatus = "stopped"
|
if (!rawStatus) continue
|
||||||
} else if (statusValue === "failed") {
|
|
||||||
mappedStatus = "error"
|
|
||||||
} else {
|
|
||||||
mappedStatus = "stopped"
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
let mappedStatus: ParsedMcpStatus["status"]
|
||||||
name,
|
if (rawStatus === "connected") {
|
||||||
status: mappedStatus,
|
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) => {
|
const InstanceInfo: Component<InstanceInfoProps> = (props) => {
|
||||||
@@ -173,19 +180,37 @@ const InstanceInfo: Component<InstanceInfoProps> = (props) => {
|
|||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
<For each={mcpServers()}>
|
<For each={mcpServers()}>
|
||||||
{(server) => (
|
{(server) => (
|
||||||
<div class="flex items-center justify-between px-2 py-1.5 rounded border bg-surface-secondary border-base">
|
<div class="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 justify-between gap-2">
|
||||||
<div class="flex items-center gap-1.5 flex-shrink-0">
|
<span class="text-xs text-primary font-medium truncate">{server.name}</span>
|
||||||
<Show when={server.status === "running"}>
|
<div class="flex items-center gap-1.5 flex-shrink-0 text-xs text-secondary">
|
||||||
<div class="status-dot ready animate-pulse" />
|
<div
|
||||||
</Show>
|
class={`status-dot ${
|
||||||
<Show when={server.status === "error"}>
|
server.status === "running"
|
||||||
<div class="status-dot error" />
|
? "ready animate-pulse"
|
||||||
</Show>
|
: server.status === "error"
|
||||||
<Show when={server.status === "stopped"}>
|
? "error"
|
||||||
<div class="status-dot stopped" />
|
: "stopped"
|
||||||
</Show>
|
}`}
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
{
|
||||||
|
server.status === "running"
|
||||||
|
? "Connected"
|
||||||
|
: server.status === "error"
|
||||||
|
? "Error"
|
||||||
|
: "Disabled"
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Show when={server.error}>
|
||||||
|
{(error) => (
|
||||||
|
<div class="text-[11px] mt-1 break-words" style={{ color: "var(--status-error)" }}>
|
||||||
|
{error()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
|
|||||||
@@ -63,13 +63,51 @@ export default function MessageItem(props: MessageItemProps) {
|
|||||||
isUser()
|
isUser()
|
||||||
? "message-item-base bg-[var(--message-user-bg)] border-l-4 border-[var(--message-user-border)]"
|
? "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)]"
|
: "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 (
|
return (
|
||||||
|
|
||||||
<div class={containerClass()}>
|
<div class={containerClass()}>
|
||||||
<div class="flex justify-between items-center gap-2.5 pb-0.5">
|
<div class="flex justify-between items-center gap-2.5 pb-0.5">
|
||||||
<span class="font-semibold text-xs text-[var(--text-muted)]">
|
<div class="flex flex-col">
|
||||||
{isUser() ? "You" : "Assistant"}
|
<Show when={isUser()}>
|
||||||
</span>
|
<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">
|
<div class="flex items-center gap-2">
|
||||||
<span class="text-[11px] text-[var(--text-muted)]">{timestamp()}</span>
|
<span class="text-[11px] text-[var(--text-muted)]">{timestamp()}</span>
|
||||||
<Show when={isUser() && props.onRevert}>
|
<Show when={isUser() && props.onRevert}>
|
||||||
@@ -94,8 +132,9 @@ export default function MessageItem(props: MessageItemProps) {
|
|||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-1 whitespace-pre-wrap break-words leading-[1.1]">
|
<div class="pt-1 whitespace-pre-wrap break-words leading-[1.1]">
|
||||||
|
|
||||||
<Show when={props.isQueued && isUser()}>
|
<Show when={props.isQueued && isUser()}>
|
||||||
<div class="message-queued-badge">QUEUED</div>
|
<div class="message-queued-badge">QUEUED</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|||||||
Reference in New Issue
Block a user