feat(workflows): display full run ids consistently and reshape run cards - #2140
Merged
Conversation
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
flora131
added a commit
that referenced
this pull request
Aug 2, 2026
…olution PR #2140 made every display surface render the full run UUID but left input resolution accepting typed prefixes, so the contract was asymmetric: the UI only ever printed a 36-character id while the resolver still answered to six characters of it. Run targets now require the full 8-4-4-4-12 hex UUID. Prefix scanning is gone from the live resolver, the durable DBOS catalog, the resume-target lookup, and inspectRun. A target that is not a well-formed UUID is reported as malformed rather than missing: Run id must be a full 36-character UUID; got "339e05a4" (8 chars). That is deliberately distinct from `Run not found:` so a truncated paste is diagnosable as truncated instead of looking like a stale run. Because run ids are unique and now matched exactly, run-level ambiguity is unreachable by construction. The `ambiguous` result variant is replaced by `malformed` at every call site rather than deleted, which keeps each existing error branch and its coverage intact. Stage targeting is exact but deliberately NOT held to 36 characters. Stage identifiers are not uniformly bare UUIDs: virtualNodeId builds a nested stage id as the `runId:nodeId` composite (73 chars), and a ctx.tool node carries `tool:<argsHash>`. A blanket length rule would have made every nested stage and every tool node untargetable, so the stage axis keeps exact id and exact name matching and only loses prefix and partial-name matching. The session-picker filter keeps prefix search on purpose: it narrows a list the user then selects from, so it never targets a run by a truncated id. Fixtures across 50 test files carried short ids like "run-1" that are no longer valid input. They now derive stable UUIDs from readable seeds via testRunId(seed) rather than hardcoding opaque literals, so each fixture's intent still reads at the call site. Tests that encoded the old contract were inverted rather than deleted: typed prefixes must now be rejected, and full ids must still resolve. Also fixes a pre-existing failure on this branch, unrelated to the id contract: the dispatch card's connect hint styles its prefix and id as separate ANSI spans, so a contiguous regex could not match the styled string. That assertion now runs against the plain render. Verification: - npm run check clean - test:unit 615 files, 5739 passed - test:integration 36 files, 485 passed (baseline had 2 failing) - test:ci-contracts 5 files, 38 passed
|
Too many files changed for review. ( Bypass the limit by tagging |
Render full UUIDs across workflow surfaces and use the shared two-row identity renderer for run cards and prompt attribution banners. Preserve prefix resolution while wrapping narrow cards without shortening identifiers. PR body notes - The prompt card's border title is now exactly `AWAITING INPUT`; the run identity moved off the border line into a two-row attribution banner in the card body, rendered by the new shared `renderRunIdentityRows`. - PR #2135's queue counter belongs on banner row two beside the workflow name, in the optional `meta` slot that is already wired through `PromptCardIdentity.meta` but left unset here. - The question and options UI below the banner is byte-identical to before.
The standard prompt surface degrades attribution in three rungs — two identity rows, then the run id alone, then no banner — but the primitive input/editor path built a single banner and fell straight through to unattributed. At the one height where the middle rung applies, attribution vanished entirely even though the run id alone would have fit. That path now walks the same ladder. `renderPromptRunIdBanner` is exported so both surfaces share one definition of the middle rung rather than each deriving it, and the loop keeps the existing guards: a banner is only kept when the question still renders and loses no rows against the unattributed layout. Measured for input and editor kinds at width 100: rows <= 9 shows no banner, row 10 shows a one-row banner carrying the run id, rows >= 11 show both identity rows. The suite previously asserted that row 10 omitted attribution, which encoded the missing rung.
…olution PR #2140 made every display surface render the full run UUID but left input resolution accepting typed prefixes, so the contract was asymmetric: the UI only ever printed a 36-character id while the resolver still answered to six characters of it. Run targets now require the full 8-4-4-4-12 hex UUID. Prefix scanning is gone from the live resolver, the durable DBOS catalog, the resume-target lookup, and inspectRun. A target that is not a well-formed UUID is reported as malformed rather than missing: Run id must be a full 36-character UUID; got "339e05a4" (8 chars). That is deliberately distinct from `Run not found:` so a truncated paste is diagnosable as truncated instead of looking like a stale run. Because run ids are unique and now matched exactly, run-level ambiguity is unreachable by construction. The `ambiguous` result variant is replaced by `malformed` at every call site rather than deleted, which keeps each existing error branch and its coverage intact. Stage targeting is exact but deliberately NOT held to 36 characters. Stage identifiers are not uniformly bare UUIDs: virtualNodeId builds a nested stage id as the `runId:nodeId` composite (73 chars), and a ctx.tool node carries `tool:<argsHash>`. A blanket length rule would have made every nested stage and every tool node untargetable, so the stage axis keeps exact id and exact name matching and only loses prefix and partial-name matching. The session-picker filter keeps prefix search on purpose: it narrows a list the user then selects from, so it never targets a run by a truncated id. Fixtures across 50 test files carried short ids like "run-1" that are no longer valid input. They now derive stable UUIDs from readable seeds via testRunId(seed) rather than hardcoding opaque literals, so each fixture's intent still reads at the call site. Tests that encoded the old contract were inverted rather than deleted: typed prefixes must now be rejected, and full ids must still resolve. Also fixes a pre-existing failure on this branch, unrelated to the id contract: the dispatch card's connect hint styles its prefix and id as separate ANSI spans, so a contiguous regex could not match the styled string. That assertion now runs against the plain render. Verification: - npm run check clean - test:unit 615 files, 5739 passed - test:integration 36 files, 485 passed (baseline had 2 failing) - test:ci-contracts 5 files, 38 passed
flora131
force-pushed
the
fix/full-run-id-display
branch
from
August 2, 2026 20:29
06a9501 to
1d0caf9
Compare
flora131
pushed a commit
that referenced
this pull request
Aug 3, 2026
Add an invalidation-only store channel and one memoized payload-free graph projection per store version, so a small status or question update no longer walks complete workflow inputs, authored stage result bodies, child output values, and tool bodies before the overlay renders. Rebased onto current main. Two conflicts resolved against #2140, which reshaped run cards after this commit was written: - node-card.ts: kept main's meta line, which no longer carries the short run id because #2140 moved the full id onto its own wrapped row, and applied this commit's payload-free `outputCount ?? Object.keys(outputs).length`. - session-overlays.ts: main had begun caching a snapshot from the subscribe callback for the resume-candidate lookup. The invalidation channel carries no snapshot, so that cache would have gone stale and newly-started runs would never have appeared in the picker. The picker now reads one memoized projection per render via readGraphStoreSnapshot(). Co-authored-by: Ashkan Vedadi Gargary <70602836+ashkanvg@users.noreply.github.com>
flora131
pushed a commit
that referenced
this pull request
Aug 3, 2026
Add an invalidation-only store channel and one memoized payload-free graph projection per store version, so a small status or question update no longer walks complete workflow inputs, authored stage result bodies, child output values, and tool bodies before the overlay renders. Rebased onto current main. Two conflicts resolved against #2140, which reshaped run cards after this commit was written: - node-card.ts: kept main's meta line, which no longer carries the short run id because #2140 moved the full id onto its own wrapped row, and applied this commit's payload-free `outputCount ?? Object.keys(outputs).length`. - session-overlays.ts: main had begun caching a snapshot from the subscribe callback for the resume-candidate lookup. The invalidation channel carries no snapshot, so that cache would have gone stale and newly-started runs would never have appeared in the picker. The picker now reads one memoized projection per render via readGraphStoreSnapshot(). Co-authored-by: Ashkan Vedadi Gargary <70602836+ashkanvg@users.noreply.github.com>
flora131
pushed a commit
that referenced
this pull request
Aug 3, 2026
Add an invalidation-only store channel and one memoized payload-free graph projection per store version, so a small status or question update no longer walks complete workflow inputs, authored stage result bodies, child output values, and tool bodies before the overlay renders. Rebased onto current main. Two conflicts resolved against #2140, which reshaped run cards after this commit was written: - node-card.ts: kept main's meta line, which no longer carries the short run id because #2140 moved the full id onto its own wrapped row, and applied this commit's payload-free `outputCount ?? Object.keys(outputs).length`. - session-overlays.ts: main had begun caching a snapshot from the subscribe callback for the resume-candidate lookup. The invalidation channel carries no snapshot, so that cache would have gone stale and newly-started runs would never have appeared in the picker. The picker now reads one memoized projection per render via readGraphStoreSnapshot(). Co-authored-by: Ashkan Vedadi Gargary <70602836+ashkanvg@users.noreply.github.com>
sina85
added a commit
to sina85/atomic
that referenced
this pull request
Aug 3, 2026
Bring the node-card model/thinking/fast + durable thinkingLevel persistence up to date with upstream's tabs reformat, the ModelRuntime refactor (bastani-inc#2064), and the reshaped graph node cards (bastani-inc#2140). Re-applied thinkingLevel across the durable serialize/restore path, integrated the model row into the reshaped card, and preserved the replay model-identity fix. NODE_H stays 6 for the model row; updated the bastani-inc#2100 graph-perf composed-row expectation to match the taller card.
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.
Problem
Run identifiers were rendered at three different lengths by four separate constants plus a pile of hardcoded slices, so the same run read differently depending on where you looked:
Reading
a1b2c3in the BACKGROUND widget anda1b2c3d4in a tool message meant mentally aligning prefixes to confirm they were the same run.What ships
Full 36-character UUID in every user-facing surface. All short-id constants and hardcoded truncations are removed rather than unified at some shorter length.
Run cards become two lines, since a full UUID plus a workflow name does not fit beside a glyph at the 80-column collapse breakpoint:
The prompt card is an attribution banner only. Its border title is just
AWAITING INPUT, and the body carries the same two identity rows as the widget through a shared renderer. The prompt question and its options continue to render through the existing prompt UI, unchanged — the banner never duplicates them.Input now matches display: full UUIDs only. The original revision changed rendering alone and left prefix resolution in place, which made the contract asymmetric — the UI only ever printed a 36-character id while the resolver still answered to six characters of it. Run targets now require the full 8-4-4-4-12 hex UUID everywhere
runIdis accepted. Prefix scanning is gone from the live resolver, the durable DBOS catalog, the resume-target lookup, andinspectRun.A malformed target is reported separately from a missing one, so a truncated paste is diagnosable as truncated rather than looking like a stale run:
Because run ids are unique and now matched exactly, run-level ambiguity is unreachable by construction. The
ambiguousresult variant was replaced bymalformedat every call site rather than deleted, so each existing error branch and its coverage stayed intact.Stage targeting is exact, but deliberately not 36-bound. Stage identifiers are not uniformly bare UUIDs:
virtualNodeIdbuilds a nested stage id as therunId:nodeIdcomposite (73 characters), and actx.toolnode carriestool:<argsHash>. Applying the length rule to the stage axis would have made every nested stage and every tool node untargetable, so that axis keeps exact id and exact name matching and loses only prefixes and partial names —buildno longer selectsbuild-check. Nested-stage and tool-node targeting are unchanged and now have explicit coverage.The
/workflow connectpicker keeps prefix search in its filter box on purpose: it narrows a list the user then selects from, so it never targets a run by a truncated id.Height behaviour
Doubling card height matters because the four-run display cap was removed in #2134, so every qualifying run now renders. Two review findings came directly from that pressure and are fixed:
The primitive input/editor prompt path now walks that same ladder; it previously built a single banner and fell straight through to unattributed, so at the one height where the middle rung applies, attribution vanished even though the run id alone would have fit. Measured for both prompt kinds at width 100: rows ≤ 9 no banner, row 10 a one-row banner with the run id, rows ≥ 11 both identity rows.
Verification
npm run check— cleannpm run test:unit— 615 files, 5739 passed, 1 skippednpm run test:integration— 36 files, 485 passednpm run test:ci-contracts— 5 files, 38 passedOn the fixture churn. Roughly 600 test sites used short ids such as
"run-1"and"r1", which are no longer valid input, so 50 files change. They derive stable UUIDs from readable seeds throughtestRunId(seed)rather than hardcoding opaque literals, so each fixture's intent still reads at the call site. Tests that encoded the old contract were inverted rather than deleted: a typed prefix must now be rejected, and the full id must still resolve. No test-only bypass was added to the resolver.One unrelated fix is included.
mock-extension-api-rendering/mock-extension-apiwere already failing on this branch before this revision, on the dispatch-card test. The connect hint styles its dim prefix and accent id as separate ANSI spans, so a contiguous regex could not match the styled string; the rendered output was correct for a user the whole time. That assertion now runs against the plain render. Integration therefore goes from 2 failing to fully green.Note for reviewers
PR #2135 adds a queue counter for concurrent prompts. Under this layout it belongs on the second identity row beside the workflow name (
build-check · 1/2), in the same meta position the widget uses for mode, progress and elapsed time. That branch should rebase onto this one.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Greptile Summary
This change displays full workflow-run UUIDs and adjusts workflow cards, prompt attribution, and the connect picker layout for the wider identifiers. The five-run connect-picker viewport is documented to support mouse-wheel scrolling, but wheel input does not move selection, preventing mouse users from reaching runs outside the visible rows.
Confidence Score: 4/5
What T-Rex did
Comments Outside Diff (2)
packages/workflows/src/tui/session-picker.ts, line 402 (link)The five-row picker is documented to scroll with the mouse wheel, but this handler only recognizes arrow and
j/knavigation. With six runs, a terminal SGR wheel-down event (\x1b[<65;10;10M) falls through to thisnoopreturn and leaves the selection unchanged, so the off-viewport run cannot be reached with the documented mouse interaction. Parse wheel-up/down events and apply the same bounded selection updates as the keyboard navigation paths.Artifacts
Executable session-picker mouse-wheel reproduction source
Arrow-down baseline executed against the six-row session picker
SGR mouse-wheel-down executed against the six-row session picker
Existing session-picker unit test run
Prompt To Fix With AI
General comment
\x1b[<65;10;10MreacheshandleSessionPickerInputbut returns{ kind: "noop" }and leavesselectedIndexat 0, preventing wheel navigation to the additional run.handleSessionPickerInputinpackages/workflows/src/tui/session-picker.ts:344-403recognizes only arrow and j/k navigation at lines 385-394; it neither parses SGR mouse input nor maps vertical wheel events to selection movement. The remaining fallback at line 402 returnsnoop.Key.up/Key.down; add direct tests for both wheel directions with more than five rows.Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "fix(workflows): complete the banner ladd..." | Re-trigger Greptile