stabilize instance info metadata loading
This commit is contained in:
25
src/App.tsx
25
src/App.tsx
@@ -1032,10 +1032,10 @@ const App: Component = () => {
|
|||||||
onNew={handleNewInstanceRequest}
|
onNew={handleNewInstanceRequest}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Show when={activeInstance()}>
|
<Show when={activeInstance()} keyed>
|
||||||
{(instance) => (
|
{(instance) => (
|
||||||
<>
|
<>
|
||||||
<Show when={activeSessions().size > 0} fallback={<InstanceWelcomeView instance={instance()} />}>
|
<Show when={activeSessions().size > 0} fallback={<InstanceWelcomeView instance={instance} />}>
|
||||||
<div class="flex flex-1 min-h-0">
|
<div class="flex flex-1 min-h-0">
|
||||||
{/* Session Sidebar */}
|
{/* Session Sidebar */}
|
||||||
<div
|
<div
|
||||||
@@ -1043,12 +1043,12 @@ const App: Component = () => {
|
|||||||
style={{ width: `${sessionSidebarWidth()}px` }}
|
style={{ width: `${sessionSidebarWidth()}px` }}
|
||||||
>
|
>
|
||||||
<SessionList
|
<SessionList
|
||||||
instanceId={instance().id}
|
instanceId={instance.id}
|
||||||
sessions={activeSessions()}
|
sessions={activeSessions()}
|
||||||
activeSessionId={activeSessionIdForInstance()}
|
activeSessionId={activeSessionIdForInstance()}
|
||||||
onSelect={(id) => setActiveSession(instance().id, id)}
|
onSelect={(id) => setActiveSession(instance.id, id)}
|
||||||
onClose={(id) => handleCloseSession(instance().id, id)}
|
onClose={(id) => handleCloseSession(instance.id, id)}
|
||||||
onNew={() => handleNewSession(instance().id)}
|
onNew={() => handleNewSession(instance.id)}
|
||||||
showHeader
|
showHeader
|
||||||
showFooter={false}
|
showFooter={false}
|
||||||
headerContent={
|
headerContent={
|
||||||
@@ -1075,16 +1075,17 @@ const App: Component = () => {
|
|||||||
<Show when={activeSessionForInstance()}>
|
<Show when={activeSessionForInstance()}>
|
||||||
{(activeSession) => (
|
{(activeSession) => (
|
||||||
<>
|
<>
|
||||||
<ContextUsagePanel instanceId={instance().id} sessionId={activeSession().id} />
|
<ContextUsagePanel instanceId={instance.id} sessionId={activeSession().id} />
|
||||||
<div class="session-sidebar-controls px-3 py-3 border-r border-base flex flex-col gap-3">
|
<div class="session-sidebar-controls px-3 py-3 border-r border-base flex flex-col gap-3">
|
||||||
<AgentSelector
|
<AgentSelector
|
||||||
instanceId={instance().id}
|
instanceId={instance.id}
|
||||||
sessionId={activeSession().id}
|
sessionId={activeSession().id}
|
||||||
currentAgent={activeSession().agent}
|
currentAgent={activeSession().agent}
|
||||||
onAgentChange={handleSidebarAgentChange}
|
onAgentChange={handleSidebarAgentChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ModelSelector
|
<ModelSelector
|
||||||
instanceId={instance().id}
|
instanceId={instance.id}
|
||||||
sessionId={activeSession().id}
|
sessionId={activeSession().id}
|
||||||
currentModel={activeSession().model}
|
currentModel={activeSession().model}
|
||||||
onModelChange={handleSidebarModelChange}
|
onModelChange={handleSidebarModelChange}
|
||||||
@@ -1115,15 +1116,15 @@ const App: Component = () => {
|
|||||||
<SessionView
|
<SessionView
|
||||||
sessionId={sessionId}
|
sessionId={sessionId}
|
||||||
activeSessions={activeSessions()}
|
activeSessions={activeSessions()}
|
||||||
instanceId={activeInstance()!.id}
|
instanceId={instance.id}
|
||||||
instanceFolder={activeInstance()!.folder}
|
instanceFolder={instance.folder}
|
||||||
escapeInDebounce={escapeInDebounce()}
|
escapeInDebounce={escapeInDebounce()}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Show>
|
</Show>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<InfoView instanceId={instance().id} />
|
<InfoView instanceId={instance.id} />
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Component, Show, For, onMount, createSignal } from "solid-js"
|
import { Component, Show, For, createSignal, createEffect, onCleanup } from "solid-js"
|
||||||
import type { Instance, RawMcpStatus } from "../types/instance"
|
import type { Instance, RawMcpStatus } from "../types/instance"
|
||||||
|
import { updateInstance } from "../stores/instances"
|
||||||
|
|
||||||
interface InstanceInfoProps {
|
interface InstanceInfoProps {
|
||||||
instance: Instance
|
instance: Instance
|
||||||
@@ -41,6 +42,8 @@ function parseMcpStatus(status: RawMcpStatus): ParsedMcpStatus[] {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pendingMetadataRequests = new Set<string>()
|
||||||
|
|
||||||
const InstanceInfo: Component<InstanceInfoProps> = (props) => {
|
const InstanceInfo: Component<InstanceInfoProps> = (props) => {
|
||||||
const [isLoadingMetadata, setIsLoadingMetadata] = createSignal(true)
|
const [isLoadingMetadata, setIsLoadingMetadata] = createSignal(true)
|
||||||
|
|
||||||
@@ -50,35 +53,73 @@ const InstanceInfo: Component<InstanceInfoProps> = (props) => {
|
|||||||
return status ? parseMcpStatus(status) : []
|
return status ? parseMcpStatus(status) : []
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
createEffect(() => {
|
||||||
if (!props.instance.client) {
|
const instance = props.instance
|
||||||
|
const instanceId = instance.id
|
||||||
|
const client = instance.client
|
||||||
|
const hasMetadata = Boolean(instance.metadata)
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
setIsLoadingMetadata(false)
|
setIsLoadingMetadata(false)
|
||||||
|
pendingMetadataRequests.delete(instanceId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsLoadingMetadata(true)
|
if (hasMetadata) {
|
||||||
try {
|
|
||||||
const [projectResult, mcpResult] = await Promise.allSettled([
|
|
||||||
props.instance.client.project.current(),
|
|
||||||
props.instance.client.mcp.status(),
|
|
||||||
])
|
|
||||||
|
|
||||||
const project = projectResult.status === "fulfilled" ? projectResult.value.data : undefined
|
|
||||||
const mcpStatus = mcpResult.status === "fulfilled" ? mcpResult.value.data as RawMcpStatus : undefined
|
|
||||||
|
|
||||||
const { updateInstance } = await import("../stores/instances")
|
|
||||||
updateInstance(props.instance.id, {
|
|
||||||
metadata: {
|
|
||||||
project,
|
|
||||||
mcpStatus,
|
|
||||||
version: "0.15.8",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to load instance metadata:", error)
|
|
||||||
} finally {
|
|
||||||
setIsLoadingMetadata(false)
|
setIsLoadingMetadata(false)
|
||||||
|
pendingMetadataRequests.delete(instanceId)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pendingMetadataRequests.has(instanceId)) {
|
||||||
|
setIsLoadingMetadata(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let cancelled = false
|
||||||
|
pendingMetadataRequests.add(instanceId)
|
||||||
|
setIsLoadingMetadata(true)
|
||||||
|
|
||||||
|
void (async () => {
|
||||||
|
try {
|
||||||
|
const [projectResult, mcpResult] = await Promise.allSettled([
|
||||||
|
client.project.current(),
|
||||||
|
client.mcp.status(),
|
||||||
|
])
|
||||||
|
|
||||||
|
if (cancelled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const project = projectResult.status === "fulfilled" ? projectResult.value.data : undefined
|
||||||
|
const mcpStatus = mcpResult.status === "fulfilled" ? (mcpResult.value.data as RawMcpStatus) : undefined
|
||||||
|
|
||||||
|
const nextMetadata = {
|
||||||
|
...(instance.metadata ?? {}),
|
||||||
|
...(project ? { project } : {}),
|
||||||
|
...(mcpStatus ? { mcpStatus } : {}),
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextMetadata.version) {
|
||||||
|
nextMetadata.version = "0.15.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInstance(instanceId, { metadata: nextMetadata })
|
||||||
|
} catch (error) {
|
||||||
|
if (!cancelled) {
|
||||||
|
console.error("Failed to load instance metadata:", error)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
pendingMetadataRequests.delete(instanceId)
|
||||||
|
if (!cancelled) {
|
||||||
|
setIsLoadingMetadata(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
onCleanup(() => {
|
||||||
|
cancelled = true
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user