Frontmatter
| id | 8308 |
| title | Neural Link: Implement atomic get_vdom_and_vnode tool |
| state | Closed |
| labels | enhancementai |
| assignees | tobiu |
| createdAt | Jan 4, 2026, 12:47 PM |
| updatedAt | Jan 4, 2026, 1:02 PM |
| githubUrl | https://github.com/neomjs/neo/issues/8308 |
| author | tobiu |
| commentsCount | 2 |
| parentIssue | 8169 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Jan 4, 2026, 1:02 PM |
Neural Link: Implement atomic get_vdom_and_vnode tool
tobiu assigned to @tobiu on Jan 4, 2026, 12:47 PM
tobiu added parent issue #8169 on Jan 4, 2026, 12:47 PM

tobiu
Jan 4, 2026, 12:52 PM
Input from Gemini 3 pro:
✦ I have implemented the atomic
get_vdom_vnodetool across the full stack.Server Side:
- OpenAPI: Added
/component/vdom-vnode/getendpoint toopenapi.yaml.- Service: Added
getVdomAndVnodetoai/mcp/server/neural-link/services/ComponentService.mjs.- Tool Mapping: Mapped
get_vdom_vnodetoComponentService.getVdomAndVnodeinai/mcp/server/neural-link/services/toolService.mjs.Client Side:
- Service: Added
getVdomAndVnodetosrc/ai/client/ComponentService.mjs, which usesTreeBuilderto return both trees synchronously.- Client: The
get_vdom_vnodeprefix is implicitly handled by the existingget_vdommapping inClient.mjs(sinceget_vdom_vnodestarts withget_vdom), so strictly speaking, no change was required inClient.mjs's map, but I verified the routing logic covers it. Wait,get_vdomprefix matchesget_vdom_treebut alsoget_vdom_vnode.Verification: The prefix matching in
Client.mjsis:for (prefix in me.serviceMap) { if (method.startsWith(prefix)) { ... } }Since
get_vdomis a prefix,get_vdom_vnodewill match it and route tocomponentservice. This confirms correct routing without explicit addition, though explicit addition (or re-ordering) might be safer if we had conflicting prefixes. Given the current list, it is safe.The atomic tool is now ready for use.

tobiu
Jan 4, 2026, 1:02 PM
Input from Gemini 3 pro:
✦ I have refined the implementation:
- Renaming: Renamed
getVdomAndVnodetogetVdomVnodeinsrc/ai/client/ComponentService.mjsto match the RPC method name more closely and follow conventions.- Client Cleanup: Fixed duplicated keys in
src/ai/Client.mjsserviceMapthat were inadvertently introduced during previous edits, ensuring a clean registration ofget_vdom_vnode.- Formatting: Ensured the code changes adhere to project formatting standards (no extra newlines).
The feature is now fully implemented and polished.
tobiu closed this issue on Jan 4, 2026, 1:02 PM
We need a new tool to retrieve both the VDOM and VNode trees for a component in a single, atomic operation.
Context:
get_vdom_treereturns the next intended state (VDOM).get_vnode_treereturns the current live DOM state (VNode).get_component_treereturns the Neo.mjs component hierarchy (Class instances).Problem: In high-frequency scenarios (e.g., 60fps), fetching VDOM and VNode via separate network calls can lead to race conditions where the returned trees correspond to different render frames. This mismatch makes debugging rendering issues (reconciliation bugs) impossible.
Requirements:
get_vdom_vnode(orget_render_trees)rootId(string),depth(number, default -1).{ vdom: Object, vnode: Object }.Implementation:
src/ai/client/ComponentService.mjs->getVdomAndVnode({rootId, depth}).openapi.yaml,toolService.mjs, andserver/services/ComponentService.mjs.