Skip to content

🤖 feat(workflows): evaluate() step rendering in the workflow timeline and tool card - #4330

Open
ThomasK33 wants to merge 7 commits into
thomask33/eval-l3b-workflow-evaluatefrom
thomask33/eval-l4-settings-timeline
Open

ThomasK33 wants to merge 7 commits into
thomask33/eval-l3b-workflow-evaluatefrom
thomask33/eval-l4-settings-timeline

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Sep 22, 2026

Copy link
Copy Markdown
Member

Summary

Fourth layer of the workflow evaluate() primitive (stacked on #4329), reduced to timeline rendering: evaluate() steps in the right-sidebar workflow timeline and the workflow tool card (badge, model/usage metadata, coalesced rows). The Settings evaluation-model card that this PR originally also carried was removed after review round 5 (see Scope below).

Background

Plan layers: L2a #4321 → L2b #4322 → L3a #4324 → L3b #4329 (runner + CLI) → L4 (this PR) → L5 TypeSafe provider → L6 example + docs. #4324 deferred the "coalesce evaluation events in the tool card" finding to this layer.

Implementation

  • projectWorkflowRun: WorkflowStepView.evaluation = admission selection + attempt, plus responseModelId/usage from the committed EvaluationStepResult and cached from the replay event. WorkflowTimeline shows an evaluation / evaluation · cached badge and a metadata line (model, ↳ responseModelId only when it differs from the bare requested id — providers report gpt-5 while the admitted string is openai:gpt-5 —, attempt n when > 1, tokens); evaluate steps have no task, so no Open action.
  • WorkflowRunToolCall.getWorkflowDisplayRows coalesces evaluation events per stepId + inputHash (all attempts of one step) into one row: latest status, started title preserved when a terminal event lacks one, merged details.
  • Storybook: App/WorkflowsEvaluationSteps (cached / failed / running steps).

Scope

Review rounds 2–5 all found asynchronous-ownership defects in the Settings card (route/policy gating, then load race, reconnect load, superseded saves, stale verdict) — see the pause comment. The card, its config.checkEvaluationModel ORPC method, TasksSection wiring, story plumbing and IPC test were removed from this PR and preserved on thomask33/eval-l4c-card for a cohesive load/save lifecycle design (single owner of the displayed value, per-API-identity loads, one in-flight operation) in its own PR, which carries the card's review history and the TypeSafe card additions from L5. Until then evaluationDefaults.model is set via the existing config.updateEvaluationDefaults endpoint / xum workflow run --evaluation-model.

Validation

  • WorkflowTimeline.test.tsx (+1): the ↳ responseModelId line appears only when the response id differs from the requested bare id (same id → no line; dated snapshot id → shown).
  • projectWorkflowRun.test.ts (+1): evaluation facts from admission + result + cached event; running attempt exposes admission only; agent steps stay undefined.
  • WorkflowRunToolCall.test.tsx (+1): two attempts + a title-less terminal event collapse into one row labelled with the started title; other steps stay separate.
  • Storybook plays green for App.workflows.stories.tsx (bun x test-storybook … --verbose); make static-check green; Workflows/Tools suites 170/170.

Risks

  • UI-only; no persisted formats change. Timeline/tool-card changes touch only evaluation rows/steps; agent, patch and nested-workflow rendering is untouched.

Generated with xum • Model: coder:anthropic/claude-fable-5-1 • Thinking: xhigh • Cost: $511.72

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-22T20:08:43.632967Z 236d937 New commits
🔒 Security Review Completed 2026-09-22T20:08:57.704760Z 236d937 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ThomasK33
ThomasK33 added this pull request to stack #4326 September 22, 2026 07:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14498a973e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/RightSidebar/Workflows/projectWorkflowRun.ts
Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/RightSidebar/Workflows/WorkflowTimeline.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 70460ba55e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

case "evaluation":
return event.usage;

P2 Badge Preserve failed evaluation diagnostics in event details

When an evaluation event is failed, it normally has no usage, so returning only this field makes the coalesced row non-expandable. Its label retains reason and code but drops statusCode and defect, causing provider diagnostics such as HTTP 429/500 to disappear from the workflow tool card; include those failure fields in the projected detail instead.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
@ThomasK33
ThomasK33 force-pushed the thomask33/eval-l4-settings-timeline branch from 8ad87c3 to 3212f08 Compare September 22, 2026 09:26

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3212f08bbc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/RightSidebar/Workflows/WorkflowTimeline.tsx Outdated
Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
ThomasK33 added a commit that referenced this pull request Sep 22, 2026
…fault is read

Codex round 4 on #4330: a model selected before the initial `getConfig()`
resolved was persisted and then overwritten on screen by that read's older
value, leaving the card behind the on-disk default. The control row is now a
`<fieldset disabled>` until the read lands (disables every descendant
control, so ModelSelector needs no new prop). Test: deferred read → controls
disabled → read resolves → enabled with the persisted value.

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$441.23`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=441.23 -->
@ThomasK33
ThomasK33 force-pushed the thomask33/eval-l4-settings-timeline branch from 3212f08 to 0089f31 Compare September 22, 2026 10:20

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0089f31077

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
Comment thread src/browser/features/Settings/Sections/EvaluationModelCard.tsx Outdated
@ThomasK33

Copy link
Copy Markdown
Member Author

Paused for non-convergence (review round 5)

Successive Codex rounds keep finding asynchronous ownership defects in the new evaluation-model card (rounds 2–5), most recently a reconnect variant of the initial-load race fixed in round 4. Under the review-loop rules this PR is not ready, and another isolated guard is not the right next step. No merge and no new review cycle are being initiated.

Findings from rounds 4–5

Finding Status
Controls usable before the persisted default is read (krAO1) Fixed in 0089f31 (<fieldset disabled> until loaded)
Timeline compares bare responseModelId with prefixed modelString → spurious "↳ gpt-5" (krAO5) Deferred, fix + test prepared on a local follow-up branch
Failed re-check keeps the previous verdict (krAO7) Deferred, fix + test prepared on the same branch
Load guard does not reset across API-client changes (ksA1g) Unresolved — same display-vs-persisted invariant as round 4; blocking for the card
Stale error from a superseded save (ksA1n) Unresolved — advisory; persisted value is correct

Context: the card follows the existing GoalsSection one-shot load / optimistic save pattern, which shares these weaknesses; that is precedent, not correctness.

Proposed scope reduction (maintainer decision)

  1. Keep the evaluate() timeline/projection rendering (with the krAO5 fix) in this PR or a timeline-only successor.
  2. Hold the Settings evaluation-model card — plus the TypeSafe additions to it queued in the unpublished L5 layer — for one cohesive load/save lifecycle design (single owner of the displayed value, per-API-identity loads, one in-flight operation), reviewed as its own PR carrying this history forward.

Existing fixes and the open findings are preserved; L5/L6 stay unpublished until this is decided.


Generated with xum • Model: coder:anthropic/claude-fable-5-1 • Thinking: xhigh • Cost: $441.23

ThomasK33 added a commit that referenced this pull request Sep 22, 2026
…fault is read

Codex round 4 on #4330: a model selected before the initial `getConfig()`
resolved was persisted and then overwritten on screen by that read's older
value, leaving the card behind the on-disk default. The control row is now a
`<fieldset disabled>` until the read lands (disables every descendant
control, so ModelSelector needs no new prop). Test: deferred read → controls
disabled → read resolves → enabled with the persisted value.

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$441.23`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=441.23 -->
@ThomasK33
ThomasK33 force-pushed the thomask33/eval-l4-settings-timeline branch from 0089f31 to 88d8509 Compare September 22, 2026 14:42
@ThomasK33 ThomasK33 changed the title 🤖 feat(workflows): Settings evaluation-model card and evaluate() timeline rendering 🤖 feat(workflows): evaluate() step rendering in the workflow timeline and tool card Sep 22, 2026
@ThomasK33

Copy link
Copy Markdown
Member Author

Resumed under an explicitly bounded exception: one assessment of the reduced head 88d8509c3.

Scope reduced as proposed in the pause comment: this PR is now timeline/tool-card rendering only (plus the bare-response-model-id comparison fix). The Settings card, its config.checkEvaluationModel method, TasksSection wiring, story plumbing and IPC test are preserved on thomask33/eval-l4c-card for a cohesive lifecycle redesign in their own PR, carrying the round 2–5 findings as acceptance criteria. Rebased onto #4329's reduced head.

If this assessment finds another systemic issue, the PR stays paused; no further loop is intended.


Generated with xum • Model: coder:anthropic/claude-fable-5-1 • Thinking: xhigh • Cost: $511.72

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review


P2 Badge Key evaluation placement by input hash

When a workflow reuses an evaluation step ID with a different input hash, this event is folded into stepFirstEventSeq and stepTitle, which are keyed only by stepId, even though run.steps stores separate (stepId, inputHash) records. Both timeline rows consequently receive the first invocation's title and phase; index evaluation events by the full tuple and use that tuple when projecting each record.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/RightSidebar/Workflows/WorkflowTimeline.tsx Outdated
ThomasK33 added a commit that referenced this pull request Sep 22, 2026
Teach the workflow evaluate() resolver the reserved evaluation-only
`typesafe` key that main already ships for auto model routing (no new
PROVIDER_DEFINITIONS entry): shared resolveTypeSafeCredentials, a
createTypeSafeAi construction branch, and the CLI's run-scoped providers copy
keeps evaluation-only entries so a TypeSafe-only configuration reaches
evaluate(). Offering `typesafe:jev-latest` in the Settings evaluation card
moves with the card to its own PR (#4330 was reduced to timeline rendering).

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$511.72`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=511.72 -->
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 6744057451

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 6744057451

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

…line rendering

Adds the Settings → Tasks "Workflow Evaluation" card (`EvaluationModelCard`):
a `ModelSelector` restricted to evaluation-eligible models, a Clear action,
and a client-side route hint when the chosen model would not use its
provider's direct route. It persists through the dedicated
`config.updateEvaluationDefaults` endpoint.

The Workflows timeline projects `evaluate()` facts onto the step view
(selected model, response model id, attempt, usage, cached replay) and shows
an `evaluation` / `evaluation · cached` badge with a metadata line; the
workflow tool card coalesces a step's `evaluation` events into one row that
keeps the started title and shows the latest status. Storybook gains the
card (with a pinned phone variant) and an evaluation-steps run.

---

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$326.41`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=326.41 -->
…a for unfinished rows

Codex round 1 on the Settings card and timeline: the card filters the hidden
model list and explicit gateway prefixes like the backend resolver and
persists before publishing a selection; the timeline keys cached replay
state by (stepId, inputHash) and shows the admitted model/attempt for
failed and running evaluation rows.

---

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$378.37`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=378.37 -->
…red list gates

Codex round 2: instead of re-implementing resolver rules client-side, the
card asks the backend (new network-free config.checkEvaluationModel, a
public projection of the resolver's typed rejection) about the selected
model — covering Codex OAuth, custom-shadowed ids, gateway routes, missing
keys and policy — with a stale-response guard, and filters both offered
lists with the shared policy and custom-provider predicates.

---

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$417.19`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=417.19 -->
…, origin policy gate, no publish without API

Codex round 3: the backend check re-runs when route preferences or the
enforced policy change (not only on selection/providers changes); the
offered lists apply the policy to the canonical origin like the resolver
does, so a permitted gateway route cannot qualify a denied origin; and a
selection made while no API client exists is reported as unsaved instead
of being published.

---

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$431.97`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=431.97 -->
…fault is read

Codex round 4 on #4330: a model selected before the initial `getConfig()`
resolved was persisted and then overwritten on screen by that read's older
value, leaving the card behind the on-disk default. The control row is now a
`<fieldset disabled>` until the read lands (disables every descendant
control, so ModelSelector needs no new prop). Test: deferred read → controls
disabled → read resolves → enabled with the persisted value.

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$441.23`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=441.23 -->
…dering

Scope reduction after five review rounds of card-lifecycle findings: the
Settings evaluation-model card, its `config.checkEvaluationModel` ORPC
method, TasksSection wiring, story/mocks plumbing and IPC test leave this
PR (preserved on thomask33/eval-l4c-card for a cohesive load/save lifecycle
redesign). What remains is the evaluate() step rendering: projection,
WorkflowTimeline and WorkflowRunToolCall, plus the response-model comparison
fix — provider response ids are bare (`gpt-5`, or the requested bare id as
fallback) while the admitted model string is prefixed (`openai:gpt-5`), so
comparing them verbatim rendered a second "↳ gpt-5" line on every ordinary
completion.

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$511.72`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=511.72 -->
…data row

Codex on the reduced head: the step metadata row that now carries the
evaluation attempt and token count used Tailwind's generic `tabular-nums`;
the repository's `counter-nums` utility is the maintained contract for
incrementing numeric UI.

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$511.72`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=511.72 -->
@ThomasK33
ThomasK33 force-pushed the thomask33/eval-l4-settings-timeline branch from 6744057 to 236d937 Compare September 22, 2026 20:02
ThomasK33 added a commit that referenced this pull request Sep 22, 2026
Teach the workflow evaluate() resolver the reserved evaluation-only
`typesafe` key that main already ships for auto model routing (no new
PROVIDER_DEFINITIONS entry): shared resolveTypeSafeCredentials, a
createTypeSafeAi construction branch, and the CLI's run-scoped providers copy
keeps evaluation-only entries so a TypeSafe-only configuration reaches
evaluate(). Offering `typesafe:jev-latest` in the Settings evaluation card
moves with the card to its own PR (#4330 was reduced to timeline rendering).

_Generated with `xum` • Model: `coder:anthropic/claude-fable-5-1` • Thinking: `xhigh` • Cost: `$511.72`_

<!-- mux-attribution: model=coder:anthropic/claude-fable-5-1 thinking=xhigh costs=511.72 -->

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant