How the Mermaid Canvas Handles Verbose Tool Logs in TencentDB Agent Memory
The Mermaid Canvas filters verbose tool logs through a multi-stage pipeline that strips debug-level diagnostics, heartbeat pings, and retry-wait entries before they reach the visualization layer, ensuring only essential tool-call flowchart nodes are rendered.
The TencentDB Agent Memory project implements a robust off-load pipeline to manage agent execution state and visualize tool interactions. When the system generates verbose tool logs—including debug diagnostics, heartbeat signals, and retry-wait entries—the Mermaid Canvas relies on a sophisticated filtering architecture to prevent diagnostic noise from cluttering the visual flowchart representation.
The Four-Stage Off-Load Filtering Pipeline
The system processes verbose logs through four distinct stages before any content reaches the front-end canvas. Each stage progressively reduces noise to deliver a clean, actionable visualization.
1. Off-Load Ingestion and Entry Classification
The filtering begins in the L2 Mermaid pipeline at MemoryCore/src/offload/pipelines/l2-mermaid.ts. The checkL2Trigger function iterates through all off-load entries and immediately classifies potential noise sources.
The system identifies heartbeat entries through the isHeartbeatEntry helper:
function isHeartbeatEntry(entry: OffloadEntry): boolean {
// Heartbeat files are pure diagnostics and are ignored.
const tc = entry.tool_call ?? "";
return tc.includes("HEARTBEAT.md");
}
During the checkL2Trigger execution, the pipeline applies immediate exclusion rules:
// In checkL2Trigger → entry filtering
if (isHeartbeatEntry(entry)) continue; // ← drop heartbeat
if (entry.node_id === "wait") { // ← drop retry-wait
const tsIso = entry.timestamp;
if (tsIso && (nowMs - new Date(tsIso).getTime()) / 1000 < waitRetrySeconds) continue;
}
This early filtration ensures that heartbeat diagnostics and premature retry-wait entries never proceed to downstream processing stages.
2. Log-Level Configuration Filtering
Before JSON extraction begins, the MemoryProxy configuration determines whether debug-level logs should persist. The MemoryProxy/src/config.ts file defines the default logging behavior:
// MemoryProxy/src/config.ts
export const DEFAULT_CONFIG = {
log: {
verbose: false, // ← set to true only for deep debugging
// …
},
};
When verbose: false (the production default), the system strips any log line flagged as DEBUG level before the Mermaid extraction stage. This configuration acts as a gatekeeper, ensuring that verbose diagnostic chatter is discarded at the configuration layer rather than propagated through the pipeline.
3. Mermaid Extraction and Node Deduplication
Surviving entries proceed to the extraction stage in MemoryCore/src/offload/parsers/json-utils.ts. The extractMermaidFromFence function parses fenced Mermaid code blocks, while backfillNodeIds in the L2 pipeline fills in node identifiers.
This stage performs two critical operations:
- Grouping by target diagram: Entries are organized by their
targetMmdproperty to ensure contextually relevant grouping. - Node contribution analysis: The pipeline discards any entry that does not contribute a new node or edge to the flowchart structure.
Only essential tool-call identifiers (tool_call_id) required to build the flowchart graph are retained. Redundant or non-structural log entries are eliminated during this deduplication process.
4. Canvas Rendering with Distilled Payload
The front-end receives a sanitized JSON payload containing only the distilled node-mapping and final Mermaid source string. The rendering occurs in MemoryPanel/web/src/pages/KnowledgeGraph.tsx:
// MemoryPanel/web/src/pages/KnowledgeGraph.tsx
import mermaid from "mermaid";
export const KnowledgeGraph = ({ mermaidSrc }: { mermaidSrc: string }) => {
useEffect(() => {
mermaid.initialize({ startOnLoad: false });
mermaid.render("graphDiv", mermaidSrc, (svg) => {
const container = document.getElementById("graphContainer");
if (container) container.innerHTML = svg;
});
}, [mermaidSrc]);
return <div id="graphContainer" />;
};
The component receives a clean data structure such as:
{
"mmd_content": "flowchart TD\n A[Start] --> B{Decision}\n B -->|Yes| C[Proceed]\n B -->|No| D[Stop]",
"node_mapping": { "tool1": "A", "tool2": "B" }
}
The mermaid library renders exactly this diagram—verbose logs never appear in the DOM because they were filtered out during earlier pipeline stages.
Implementation Examples
Disabling Verbose Logging Globally
To ensure verbose logs never enter the pipeline, confirm the proxy configuration maintains the default restrictive setting:
// MemoryProxy/src/config.ts
export const DEFAULT_CONFIG = {
log: {
verbose: false, // Production default strips DEBUG logs
level: "INFO",
},
};
Conditional Entry Skipping Logic
The L2 pipeline implements time-based filtering for retry-wait entries to prevent transient wait states from cluttering the visualization:
if (entry.node_id === "wait") {
const tsIso = entry.timestamp;
const elapsedSeconds = tsIso
? (nowMs - new Date(tsIso).getTime()) / 1000
: 0;
if (elapsedSeconds < waitRetrySeconds) {
continue; // Skip early retry-wait entries
}
}
Front-End Sanitization
Even if verbose logs bypass back-end filters, the KnowledgeGraph component only renders explicitly provided Mermaid syntax, ignoring any unexpected properties in the JSON payload.
Summary
- Early filtration: The
checkL2Triggerfunction inl2-mermaid.tsidentifies and drops heartbeat and premature retry-wait entries before processing. - Configuration gating: The
verboseflag inMemoryProxy/src/config.tsdefaults tofalse, causing DEBUG-level logs to be stripped before extraction. - Structural extraction: The
extractMermaidFromFenceandbackfillNodeIdsfunctions retain only node-contributing entries, discarding non-structural logs. - Clean rendering: The
KnowledgeGraphcomponent in the Memory Panel receives only distilled Mermaid source strings, ensuring the canvas displays pure flowchart logic without diagnostic noise.
Frequently Asked Questions
What happens to verbose logs when the verbose flag is set to false?
When verbose: false in MemoryProxy/src/config.ts, any log entry marked with DEBUG level is stripped from the payload before it reaches the Mermaid extraction stage. These logs are permanently discarded and do not persist in the off-load pipeline or reach the front-end canvas.
How does the system identify heartbeat entries for filtering?
The system uses the isHeartbeatEntry function in MemoryCore/src/offload/pipelines/l2-mermaid.ts to check if the tool_call property contains "HEARTBEAT.md". Entries matching this pattern are classified as pure diagnostics and are skipped via the continue statement in the main processing loop.
Can verbose tool logs be enabled for debugging purposes?
Yes, setting verbose: true in the DEFAULT_CONFIG object within MemoryProxy/src/config.ts allows DEBUG-level logs to proceed through the pipeline. However, even with verbose logging enabled, heartbeat entries and premature retry-wait states are still filtered by the checkL2Trigger logic unless explicitly modified.
Which component actually renders the final Mermaid diagram?
The KnowledgeGraph component located at MemoryPanel/web/src/pages/KnowledgeGraph.tsx handles the rendering. It initializes the mermaid library with startOnLoad: false and manually renders the sanitized mermaidSrc string into an SVG, injecting it into a container div identified as graphContainer.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →