"use client"; import React, { useState, useEffect, useCallback } from 'react'; import { api } from '@/lib/api-client'; import styles from './DatabasePanel.module.css'; interface DatabasePanelProps { threadId: string | null; refreshKey?: number; // increment to trigger refresh } export default function DatabasePanel({ threadId, refreshKey = 0 }: DatabasePanelProps) { const [dbState, setDbState] = useState | null>(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [expandedKeys, setExpandedKeys] = useState>(new Set()); const fetchState = useCallback(async () => { if (!threadId) return; setIsLoading(true); setError(null); try { const data = await (api.get as any)(`/threads/${threadId}/state`); const values = data?.values ?? data ?? {}; // Filter out message arrays — keep only structured DB entries const filtered: Record = {}; if (typeof values === 'object' && !Array.isArray(values)) { for (const [k, v] of Object.entries(values)) { if (k === 'messages' || Array.isArray(v)) continue; filtered[k] = v; } } setDbState(filtered); } catch (e: any) { setError(e?.message || 'Failed to load state'); } finally { setIsLoading(false); } }, [threadId]); useEffect(() => { fetchState(); }, [fetchState, refreshKey]); const toggleKey = (key: string) => { setExpandedKeys(prev => { const next = new Set(prev); next.has(key) ? next.delete(key) : next.add(key); return next; }); }; if (!threadId) { return (
🗄️

Virtual Database

Start a conversation to populate the database.

); } return (
🗄️

Virtual Database

{isLoading && !dbState &&

Loading…

} {error &&

{error}

} {dbState && Object.keys(dbState).length === 0 && (

DB Empty — the agent hasn't written any structured data yet.

)} {dbState && Object.keys(dbState).length > 0 && (
{Object.entries(dbState).map(([key, value]) => { const isObject = typeof value === 'object' && value !== null; const expanded = expandedKeys.has(key); return (
{isObject && expanded && (
{JSON.stringify(value, null, 2)}
)}
); })}
)}
); }