Run graph: read a node's text in a popup, and make the graph routes generic over strut runs - #5384
Merged
Merged
Conversation
…eneric over strut runs Clicking a node in the run graph showed its name, type, namespace and id, but never its text — the trace is hydrated with one bulk query that pulls only identity, so a Concept's docs never left the swarm. Now the panel asks for the node's body when it is first picked (cached per node), previews the first few lines, and a Read button opens it whole in a dialog: the text as escaped markdown, the other properties as attributes. The body is read through the same 7799 Cypher passthrough the trace uses, with the projection written here so the two vector properties stay on the swarm. No jarvis read, nothing to deploy upstream. The routes are no longer OpenHealth's: a run of any kind that walked the graph gets the same viewer. The trace and the node read live at /api/workspaces/[slug]/strut/runs/[runId]/graph and .../graph/nodes/[refId], membership-gated, the row found by id and workspace with no kind filter. The two OpenHealth graph routes are removed and both viewers point at the new path. The text rules (docs first, then the deprecated documentation, then description, body, ...) are one pure helper, which the run report's node peek now shares.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Clicking a node in the run graph (OpenHealth benchmark → Graph) showed its name, type, namespace and id, and nothing you could read. The trace is hydrated with one bulk Cypher query that pulls identity only, so a Concept's
docsnever left the swarm.Two asks from review of the design: read the body without going through jarvis, and stop making the graph viewer OpenHealth's — every benchmark will run off struts doing graph walks over Concepts.
What
The popup. The panel asks for a node's body when it is first picked (cached per node), previews the first few lines of its first text property, and a Read button opens it whole in a dialog: the text as markdown, the remaining properties as attributes. The markdown renders through the run report's escaped renderer, never an HTML sink, since graph content is agent- and ingest-written. A failure shows the graph's reason with Ask again; a node the graph no longer holds asks for nothing.
The read.
readRunGraphNodeinlib/strut-run-graph/hydrate.tsgoes through the same 7799/api/hive/querypassthrough the trace uses. The projection is written here:so the vectors stay on the swarm, and the existing runner gives the timeout and the "did not answer" wording for free. A ref id that is not id-shaped never reaches a query (the route refuses it with a 400 before any lookup). Nothing to deploy in stakgraph or repo2graph.
Generic routes. The trace and the node read live at
GET /api/workspaces/[slug]/strut/runs/[runId]/graphGET /api/workspaces/[slug]/strut/runs/[runId]/graph/nodes/[refId]membership-gated (as the Graph Explorer's read-only queries of the same graph), the row found by id + workspace with no kind filter — a benchmark run, a climb, a job turn, a strut chat. The two OpenHealth graph routes are removed; both OpenHealth viewers point at the new path. A future benchmark viewer mounts
StrutRunGraphwith its run id and gets the trace and the reader with no new server code.One text rule.
lib/strut-run-graph/node-text.tsdecides what of a node is prose (docs, then the deprecateddocumentation, then description, definition, body, content, text, summary) and what is an attribute. The run report'sNodePeeknow imports that list instead of carrying its own copy.Tests
hydrate.test.ts: the node read (whole, without vectors; gone vs. unread; an unshaped id never sent) andisRunGraphRefId.node-text.test.ts: the text rules.strut-runs-graph-route.test.ts: both routes — member gate (401/403/404 and public viewer), workspace scoping, 400 on a non-id, 404 gone vs. 502 unread, 502 when strut/swarm cannot be read.StrutRunGraph.test.tsx(jsdom): pick a node → body fetched once → preview → Read opens the dialog with a rendered heading and emphasis, identity keys kept out of attributes; retry after a failure; no fetch for an unresolved node.Not run against a live swarm — the dialog has only been exercised in jsdom.