Refactor tracer - integrate built-in tracing mechanism#2
Refactor tracer - integrate built-in tracing mechanism#2ArtyomVancyan merged 23 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the trace inspector by replacing the custom callback-based tracing system with langchain_core's built-in AsyncBaseTracer. The main architectural change consolidates separate nodeOutputLog and nodeStepLog into a unified nodeEntries structure, simplifying data flow from backend to frontend.
Changes:
- Replaced
SubStepCallbackHandlerwithBroadcastingTracerthat extends AsyncBaseTracer, using run.run_type for node classification instead of the customclassify_nodefunction - Unified node execution tracking into a single
NodeEntrytype with hierarchical relationships viaparent_run_id - Removed the complex
useInspectTreehook andcomputeDepthMaplogic, simplifying the inspector UI to directly render the flat list of entries
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| langgraphics/topology.py | Removed classify_node function and node_kind field from extracted topology |
| langgraphics/streamer.py | Replaced AsyncCallbackHandler with AsyncBaseTracer, using run.run_type for classification |
| tests/lib/test_classify.py | Removed tests for the deleted classify_node function |
| langgraphics-web/src/types.ts | Simplified types: removed old NodeKind union, added new NodeMessage/NodeEntry types |
| langgraphics-web/src/hooks/useWebSocket.ts | Consolidated nodeStepLog and nodeOutputLog into single nodeEntries array |
| langgraphics-web/src/hooks/useInspectTree.tsx | Deleted entire hook with depth computation logic |
| tests/web/depthMap.test.ts | Removed tests for deleted computeDepthMap function |
| langgraphics-web/src/components/InspectPanel.tsx | Simplified to directly render nodeEntries tree without depth computation |
| langgraphics-web/src/main.tsx | Updated to pass nodeEntries instead of separate logs |
| langgraphics-web/src/layout.ts | Set nodeKind to null in layout (moved to runtime via tracer) |
| langgraphics-web/src/index.css | Updated inspector styles with new step status indicators and icons |
| langgraphics-web/tsconfig.app.json | Changed target from ES2022 to ESNext |
| langgraphics-web/public/icons/chat_model.svg | Added new icon for chat_model node type |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…us stream support
|
@claude, please review the changes |
|
Claude finished @ArtyomVancyan's task in 4m 23s —— View job Code Review
Overall this is a strong refactoring. Replacing the custom callback handler with A few real issues and some notes on the Copilot review comments below. Issues1. Auto-selection in
useEffect(() => {
if (nodeEntries.length > 0 && !selectedKey) {
setSelectedKey(nodeEntries[0].run_id);
}
}, [nodeEntries, selectedKey]);
Fix: select the first root node instead: setSelectedKey(nodeEntries.find(e => !e.parent_run_id)?.run_id ?? nodeEntries[0].run_id);2. Tree depth is hard-coded to 2 levels
children: nodeEntries.filter(({parent_run_id}) => parent_run_id === entry.run_id).map(child => ({
isLeaf: true,
...The tree only renders root nodes → their direct children. If there is a chain-inside-a-chain scenario (e.g., a LangGraph node calls a chain which calls an LLM), the intermediate chain and the LLM step would each arrive with different Whether this matters today depends on the graph structure being targeted, but it's worth documenting as a known limitation or implementing a recursive tree build. 3.
async def _on_chain_end(self, run: Run) -> None:
self.node_kinds[run.name] = run.run_type # set here
...
"node_kind": self.node_kinds.get(run.name), # immediately read back
The 4.
export type NodeKind = "llm" | "chain" | "tool" | "retriever" | "embedding" | "prompt" | "parser";
Adding Minor Notes
On the Copilot Review CommentsSeveral Copilot comments appear to reference an intermediate commit state rather than the final branch HEAD:
These can be dismissed. |
|
@claude, I like your suggestions, please make comments using GitHub suggestion blocks. |
|
Claude finished @ArtyomVancyan's task in 2m 50s —— View job Implemented Review Suggestions
Committed as
|
…de_kinds - InspectPanel: extract buildTree() as a recursive function so entries nested more than one level deep are reflected in the tree instead of being silently dropped - InspectPanel: auto-select the first root entry (no parent_run_id) rather than nodeEntries[0], which is typically a child step that completes before its parent node - streamer: remove the self.node_kinds dict and all assignments to it; replace self.node_kinds.get(run.name) in _on_chain_end with run.run_type directly, matching what _emit_end already does Co-authored-by: Artyom Vancyan <ArtyomVancyan@users.noreply.github.com>
This pull request refactors the trace inspector and related data flow to simplify the codebase and streamline the management and display of node execution data. The main change is the consolidation of node output and step logs into a unified
nodeEntriesstructure, which simplifies both state management and UI rendering. The UI for the inspector tree and detail pane has also been updated for clarity and maintainability.Important changes:
useInspectTreehook and all related logic, since the new data structure makes this unnecessaryNodeDetailandDetailSectioncomponents in favor of a more direct and readable implementationNodeKindunion and updating node kind handling