Skip to content

feat(chat): honor JSON and table response shapes end to end#573

Merged
HomenShum merged 1 commit into
mainfrom
feat/shape-json-table
Jul 17, 2026
Merged

feat(chat): honor JSON and table response shapes end to end#573
HomenShum merged 1 commit into
mainfrom
feat/shape-json-table

Conversation

@HomenShum

Copy link
Copy Markdown
Owner

Summary

Closes the final response-shape boundary deliberately left model-side in #572's PR body: explicit "as JSON" / "in a markdown table" requests are now detected, instructed, deterministically enforced from raw model output, and rendered in a monospace block in both the live surface and the reproducible replay page.

  • Detector anchored on request verbs — "why did the JSON parser fail" stays a memo
  • Policy reads raw output (new optional param): balanced-brace JSON extraction (string-aware, fenced, 20k bound) / longest markdown-table run; fails closed honestly when the model didn't comply
  • Unsupported-run honesty surfaces as a risks row (can't corrupt JSON with an inline limitation)
  • Shared isStructuredAnswer keeps both renderers agreeing; .rd-answer-structured mono block scrolls horizontally instead of stretching the column

Verification

  • npx tsc --noEmit — 0 errors
  • Shape + both guard suites — 30 passed (4 new scenarios incl. negatives and fail-closed paths)
  • Tier B one-flow-regression (incl. the 390px geometry test) runs on this PR

🤖 Generated with Claude Code

The last shape boundary left model-side falls. "as JSON" / "in a
markdown table" are detected (anchored on request verbs so incidental
mentions stay memos), instructed via the exhaustive switch, and
deterministically enforced from the RAW model output — parseMemo is
heading-driven and lossy, so the policy gains an optional rawText param.
JSON: first balanced block via string-aware brace scan, fence-stripped,
20k-char bound, parse-validated, re-serialized deterministically.
Table: longest consecutive |...| line run, header+separator minimum.
Both fail closed with an honest retry message on non-compliance, and
unsupported-run honesty surfaces as a risks row since a limitation
cannot ride inside JSON without corrupting it.

Both renderers show structured bodies in a bounded monospace block with
its own horizontal scroll, via a shared isStructuredAnswer helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@HomenShum
HomenShum enabled auto-merge (squash) July 17, 2026 20:17
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nodebench-ai Ready Ready Preview, Comment Jul 17, 2026 8:19pm

Request Review

@github-actions

Copy link
Copy Markdown

✅ Dogfood Visual QA Gate: PASSED

Check Status
Screenshots 7 captured (pass)
Walkthrough 9 chapters (pass)
Key Frames 9 extracted (pass)
Scribe Steps 8 how-to steps (pass)
Build success
Artifacts

Download the dogfood-evidence-2b7d3a8 artifact from the Actions tab for full screenshots, frames, and walkthrough video.


Generated by Dogfood QA Gate

@HomenShum
HomenShum merged commit e7e423f into main Jul 17, 2026
17 checks passed
@HomenShum
HomenShum deleted the feat/shape-json-table branch July 17, 2026 20:23
@github-actions

Copy link
Copy Markdown

Demo: walkthrough of the surfaces this PR changed is available as a workflow artifact (pr-demo-573) at https://github.com/HomenShum/NodeBenchAI/actions/runs/29611031116

HomenShum added a commit that referenced this pull request Jul 17, 2026
…, icons, row layout (#574)

* fix(redesign): design nitpick pass 1 — honest dark captures, state copy, chip icons

Four findings from the pixel review of the 4-variant dogfood captures:

- The capture spec's setTheme wrote only the legacy cockpit keys; the
  redesign shell reads nodebench:redesign:theme, so every "dark" variant
  screenshot silently captured a light render — QA evidence claimed
  coverage it did not have. The spec now writes the shell's key.
- The context-miss banner titled itself "Notebook context selected"
  while its body admitted the saved context was unavailable; the title
  now agrees with the state for the artifact and default branches.
- The composer status row repeated the context title the chip below it
  already carries, which pushed the load-bearing "12 attached sources"
  count into ellipsis at 390px. The row now leads with the count.
- Starter chips used platform emoji; they now use the inline stroke-SVG
  house style via a shared STARTER_ICONS set so the default and live
  chip sets cannot drift apart.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(redesign): let the run-scope summary size to content

flex: 1 + max-width: 36ch reserved a title-sized column in the composer
status row; with the title moved to the context chip, the short source
count left dead space and "Review · no shared writes" floated mid-row on
desktop. Content-sized now, with shrink + ellipsis kept for pressure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: seal design-nitpick lane entry, backfill #573 merge marker

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: hshum <hshum@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

2 participants