As AI agents become more advanced, they are doing more than just answering questions—they are taking actions, analyzing files, and executing multi-step plans on our local machines.
But this raises a massive problem: How do we debug their thought process? When an agent fails, or hallucinates, reading through a 5,000-line JSON transcript log is a nightmare.
To solve this, I built Cortex, an open-source, local-first memory visualizer that parses AI agent logs (specifically Gemini logs) and transforms them into interactive Knowledge Graphs and Timelines.
Here is a look under the hood at how I built it using Tauri, React, and Rust.
The Architecture: Why Local-First?
AI agent logs often contain extremely sensitive data. If an agent is indexing your local file system, reading your codebase, or executing terminal commands, you cannot safely upload those transcript logs to a cloud-based visualization tool.
It had to run entirely on the user's machine. I chose Tauri v2 for the architecture:
- Rust Backend: For lightning-fast local file system scanning and data processing.
- React + TypeScript Frontend: For rendering complex interactive graphs.
- Tauri IPC: To securely bridge the local logs to the UI without a traditional web server.
Step 1: Scanning the File System with Rust
The first technical challenge is automatically finding the logs. Gemini and other agents typically store their conversation history in hidden app data directories (like ~/.gemini/).
Instead of making the user manually upload JSON files, the Rust backend actively scans the hard drive on startup.
// A simplified example of the Tauri command
#[tauri::command]
fn get_gemini_conversations() -> Result<Vec<Conversation>, String> {
let mut conversations = Vec::new();
let log_dir = dirs::home_dir().unwrap().join(".gemini/logs");
// Read the directory and parse the raw transcripts
for entry in std::fs::read_dir(log_dir).unwrap() {
// ... parse JSONL or Markdown files
conversations.push(Conversation { id, transcript });
}
Ok(conversations)
}
This command is exposed to the frontend, which fetches the array of conversations the moment the app loads.
Step 2: Parsing Transcripts into a Knowledge Graph
Once the frontend receives a raw transcript string, we need to convert text into structured relational data.
Inside the React app, a custom parser reads the transcript and extracts:
- Nodes: Key decisions, tool executions, or insights.
- Edges: The relationships between a thought, a tool call, and the resulting outcome.
- Timeline Events: The chronological sequence of actions.
// Inside App.tsx
useEffect(() => {
if (selectedConvId) {
const conv = conversations.find(c => c.id === selectedConvId);
if (conv) {
// The magic happens here: parsing flat text into a Graph structure
const parsed = parseConversation(conv.transcript);
setNodes(parsed.nodes);
setEdges(parsed.edges);
setTimeline(parsed.timeline);
}
}
}, [selectedConvId]);
Step 3: Visualizing the Mind of the AI
With the data structured, we render two main views:
- The Memory Graph: A visual web of nodes (e.g., "User Request" -> "Search Web" -> "Summary"). This allows you to instantly see how the AI clustered information.
- The Timeline: A chronological step-by-step breakdown. If the agent got stuck in a loop, the timeline makes it blatantly obvious.
Because the app is built with Tauri, the React frontend renders these complex visualizations using the OS's native webview engine, ensuring it remains incredibly snappy even with thousands of nodes, while consuming a fraction of the RAM an Electron app would use.
The Future: Vector Databases
Right now, Cortex parses local logs directly. The next big step on the roadmap is integrating a local Vector Database to allow semantic searching across all past agent memories. Imagine asking your visualizer: "Show me the graph of the time the agent fixed my Webpack config."
Check it out!
If you are building AI agents, interested in Knowledge Graphs, or just want to see a cool Tauri app in action, you can check out the source code here:
I would love to hear your feedback, and contributions are always welcome!
Top comments (0)