fix(chat,templates): keep reasoning in stream order and pin starter parser imports - #3438
Conversation
…arser imports Two problems a new project hits on its first `npm run dev`. Reasoning rendered below the tool calls that came after it. Providers reuse per-step reasoning part ids, so `reasoning-0` arrives again in step 2 with the same AG-UI messageId. `handleReasoningStart` overwrote the map entry, which assigned a fresh order and reset the text: step 2's reasoning jumped below the step 1 tool cards and step 1's reasoning was dropped entirely. A start now distinguishes the two cases. Still open means a replayed start, so the text and the original order stay. Already closed means a genuinely new span, so the closed one is retired with its own text and position instead of being overwritten. The chat starters also imported `react-markdown` and `remark-gfm` bare. The module pipeline resolves browser imports from the specifier, not package.json, so an exact pin there does nothing and the dev server warns about an unversioned import on every request. The renderers carry the version inline, and tsconfig aliases it back to node_modules so consumer tsc still resolves it.
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe change pins Markdown parser imports across five CLI templates and adds matching TypeScript aliases and tests. It also preserves streaming reasoning order when providers reuse reasoning IDs. ChangesTemplate Markdown dependency pinning
Streaming reasoning order
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant StreamProtocol
participant handler
participant parts-builder
participant Transcript
StreamProtocol->>handler: Emit reasoning start
handler->>handler: Preserve or close the existing reasoning span
handler->>parts-builder: Pass active and closed reasoning blocks
parts-builder->>Transcript: Build ordered reasoning parts
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cli/templates/index.test.ts`:
- Around line 972-997: Replace the substring and bare-import checks in the test
around chatTemplates with structural validation: parse the renderer import
specifiers and assert react-markdown and remark-gfm use exactly the installed
version, then read compilerOptions.paths and assert the relevant aliases exist
with non-empty targets. Ensure the test validates consumer TypeScript resolution
by compiling a minimal consumer or reusing the existing TypeScript verification.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 2a048ec7-dbc1-48d2-869f-453e4033db40
📒 Files selected for processing (15)
cli/templates/files/ai-agent/app/markdown-renderer.tsxcli/templates/files/ai-agent/tsconfig.jsoncli/templates/files/coding-agent/app/markdown-renderer.tsxcli/templates/files/coding-agent/tsconfig.jsoncli/templates/files/docs-agent/app/markdown-renderer.tsxcli/templates/files/docs-agent/tsconfig.jsoncli/templates/files/multi-agent-system/app/markdown-renderer.tsxcli/templates/files/multi-agent-system/tsconfig.jsoncli/templates/files/saas-starter/app/markdown-renderer.tsxcli/templates/files/saas-starter/tsconfig.jsoncli/templates/index.test.tscli/templates/manifest.jsonsrc/agent/react/use-chat/streaming/handler.test.tssrc/agent/react/use-chat/streaming/handler.tssrc/agent/react/use-chat/streaming/parts-builder.ts
…rally The substring checks could pass on an import that does not match what the starter installs: `9.0.3` is a prefix of `9.0.31`, and scanning the tsconfig text accepted an alias parked outside `compilerOptions.paths` or pointing at nothing. Compare the parsed import specifier against the exact installed version, and read the alias through `compilerOptions.paths` so its target has to name the installed package. The specifier regex is static now, which also drops the ReDoS lint on a pattern built from a variable.
Two problems a new project hits on its first
npm run devafternpm create veryfront@latest.Reasoning rendered below the tool calls that came after it
The stream order was
reasoning → tool → tool → reasoning → text. The UI renderedtool → tool → reasoning → text, and step 1's reasoning was gone entirely.Providers reuse per-step reasoning part ids, so
reasoning-0arrives again in step 2 carrying the same AG-UImessageId.handleReasoningStartoverwrote the map entry, which assigned a freshpartOrderCountervalue and resettextto"". Step 2's reasoning jumped below the step 1 tool cards; step 1's reasoning was dropped.A start now distinguishes the two cases:
closedReasoningBlocksso it keeps its own text and position instead of being overwritten.Test replays the exact wire trace from the reproduction:
Unversioned import warning in every chat starter
The starters already pin
react-markdownto9.0.3in package.json. The module pipeline resolves browser imports from the specifier, not package.json, so the pin does nothing and every request warns. Reading package.json to fill the version is gated behindVERYFRONT_DEPENDENCY_PINNING=1plus a rollout cohort, so it never fires for a new project.The five chat starters now carry the version inline, with a tsconfig wildcard alias so consumer
tscstill resolves it (react-markdown@9.0.3is not a module TypeScript can find on its own). Two tests assert the imported version matches the installed one and that the aliases exist, so they cannot drift.SSR is unaffected — the bare strategy strips the version and resolves from node_modules.
Verification
Fresh scaffold from these templates (
init ai-agent,npm install,npm run dev):Unversioned importwarnings.https://esm.sh/react-markdown@9.0.3?external=react,react-dom&target=es2022; both pinned CDN URLs return 200.tsc --noEmitclean.Suites:
cli278 passed / 0 failed, chat+react+agent 205 passed,deno task typecheckexit 0,deno fmt --checkanddeno lintclean.Summary by CodeRabbit
Bug Fixes
Tests