feat(loops+otel): topology edge lineage for loop visualization (#80) — 0.35.0#81
Merged
Conversation
…n-repo adoption skill (#77)
…ization (#80) Closes the visualization gap from #80: the kernel computed the topology edges (which iteration each round branches from / dispatches) and discarded them before they reached a trace, so a viewer could only INFER edges for the two built-in drivers and could not render createDynamicDriver topologies faithfully. Now emitted (additive, backward-compatible): - loop.plan: + parentIndex (branch source; root for round 0) + childIndices (the iterations this round dispatched) — the move's edges, emitted not guessed. - loop.iteration.{started,dispatch,ended}: + groupId (plan round) + parentIndex (the iteration this one descends from). - loop.iteration.ended: + outputPreview (bounded ~280-char string for a drawer). - Kernel branchPoint(): round k>0 branches from the best-valid (else latest) iteration so far — so refine renders as a chain, fanout→refine chains off the fanout winner. Inferred, not driver-declared (a planner-declared override is a clean future extension). OTel span tree (buildLoopOtelSpans): - loop.round (move) span: + tangle.loop.move.{round,parent_index,child_indices}. - loop.iteration span: + tangle.loop.iteration.{group_id,parent_index,duration_ms,output_preview}. - loop (root): + tangle.loop.duration_ms. Convention (decided on #80): gen_ai.* semantic conventions win for fields OTel standardizes (gen_ai.agent.name, gen_ai.usage.input/output_tokens, gen_ai.operation.name) — NOT duplicated into bespoke tangle keys; tangle.loop.* covers only what OTel does not (move/topology, verdict, placement, cost, lineage, output_preview, rollups). Tests: buildLoopOtelSpans lineage (move child_indices/parent_index + iteration group_id/parent_index/duration_ms/output_preview + root duration_ms); kernel emits childIndices/parentIndex on loop.plan + groupId/outputPreview on iteration ended. Full suite 404 green, tsc + biome clean.
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.
Resolves #80. Also carries the 0.34.0 version bump (supersedes #79 — close that), so
maincatches up 0.33.0 → 0.35.0 in one merge.What #80 asked + what landed
The kernel computed topology edges (which iteration each round branches from / dispatches) then dropped them before they reached a trace — so the Tangle Intelligence loop-graph viewer could only infer edges for the two built-in drivers and couldn't render
createDynamicDrivertopologies faithfully. Now emitted (additive, backward-compatible):loop.plan: +parentIndex(branch source; root for round 0) +childIndices(dispatched iterations).loop.iteration.{started,dispatch,ended}: +groupId(plan round) +parentIndex.loop.iteration.ended: +outputPreview(bounded ~280-char drawer string).branchPoint(): round k>0 branches from best-valid (else latest) iteration → refine renders as a chain, fanout→refine chains off the fanout winner. Inferred; planner-declared override is a clean future extension.loop.round+tangle.loop.move.{round,parent_index,child_indices};loop.iteration+tangle.loop.iteration.{group_id,parent_index,duration_ms,output_preview}; root +tangle.loop.duration_ms.Convention decision (documented on #80)
gen_ai. semconv wins for fields OTel standardizes* (
gen_ai.agent.name,gen_ai.usage.input/output_tokens,gen_ai.operation.name) — NOT duplicated into bespoketangle.*.tangle.loop.*covers only what OTel doesn't (move/topology, verdict, placement, cost, lineage, preview, rollups). The consumer'sspansToLoopEventsaligns to read gen_ai.* for agent/tokens (small, one-time).Published as
0.35.0. Full suite 404 green, tsc + biome clean.