diff --git a/frontend-modern/src/components/Dashboard/Dashboard.tsx b/frontend-modern/src/components/Dashboard/Dashboard.tsx index e675836..91f2654 100644 --- a/frontend-modern/src/components/Dashboard/Dashboard.tsx +++ b/frontend-modern/src/components/Dashboard/Dashboard.tsx @@ -914,14 +914,22 @@ export function Dashboard(props: DashboardProps) { aiChatStore.removeContextItem(guestId); // If no items left in context and sidebar is open, keep it open for now } else { - aiChatStore.addContextItem(guestType, guestId, guest.name, { + // Build context with OCI-specific info when applicable + const contextData: Record = { guestName: guest.name, name: guest.name, type: guest.type === 'qemu' ? 'Virtual Machine' : (guest.type === 'oci' ? 'OCI Container' : 'LXC Container'), vmid: guest.vmid, node: guest.node, status: guest.status, - }); + }; + + // Add OCI image info if available + if (guest.type === 'oci' && 'osTemplate' in guest && guest.osTemplate) { + contextData.ociImage = guest.osTemplate; + } + + aiChatStore.addContextItem(guestType, guestId, guest.name, contextData); // Auto-open the sidebar when first item is selected if (!aiChatStore.isOpen) { aiChatStore.open(); diff --git a/frontend-modern/src/components/Dashboard/GuestRow.tsx b/frontend-modern/src/components/Dashboard/GuestRow.tsx index 3fc5a9b..e29a503 100644 --- a/frontend-modern/src/components/Dashboard/GuestRow.tsx +++ b/frontend-modern/src/components/Dashboard/GuestRow.tsx @@ -571,6 +571,18 @@ export function GuestRow(props: GuestRowProps) { const agentVersion = createMemo(() => props.guest.agentVersion?.trim() ?? ''); const hasOsInfo = createMemo(() => osName().length > 0 || osVersion().length > 0); + // OCI image info - extract clean image name from osTemplate (similar to Docker container image display) + const ociImage = createMemo(() => { + if (props.guest.type !== 'oci') return null; + const template = (props.guest as Container).osTemplate; + if (!template) return null; + // Strip common prefixes to get clean image reference + let image = template; + if (image.startsWith('oci:')) image = image.slice(4); + if (image.startsWith('docker:')) image = image.slice(7); + return image; + }); + // Update custom URL when prop changes createEffect(() => { const prevUrl = customUrl(); @@ -890,16 +902,16 @@ export function GuestRow(props: GuestRowProps) {
@@ -1111,7 +1123,23 @@ export function GuestRow(props: GuestRowProps) {
- -}> + -} + > + {/* For OCI containers without guest agent, show image name in OS column */} + + {ociImage()} + + + } + > 0 { - sb.WriteString("## LXC Containers\n") + sb.WriteString("## LXC/OCI Containers\n") for _, r := range ctx.Containers { sb.WriteString(FormatResourceContext(r)) } @@ -312,6 +312,8 @@ func formatResourceType(t string) string { return "VM" case "container": return "Container" + case "oci_container": + return "OCI Container" case "storage": return "Storage" case "docker_host": diff --git a/internal/ai/context/types.go b/internal/ai/context/types.go index 459d20a..d980108 100644 --- a/internal/ai/context/types.go +++ b/internal/ai/context/types.go @@ -113,7 +113,7 @@ type ResourceTrends struct { // ResourceContext contains all context for a single resource type ResourceContext struct { ResourceID string - ResourceType string // "node", "vm", "container", "storage", "docker_host" + ResourceType string // "node", "vm", "container", "oci_container", "storage", "docker_host" ResourceName string Node string // Parent node (for guests) @@ -137,6 +137,9 @@ type ResourceContext struct { PastIssues []string // Summary of past findings LastRemediation string // What was done last time RecentChanges []Change // Recent configuration changes + + // Additional metadata (e.g., OCI image for OCI containers) + Metadata map[string]interface{} } // InfrastructureContext contains summarized context for the entire infrastructure