Skip to content

fix(a2ui): move history storage from server to client#2675

Merged
gaoachao merged 1 commit into
lynx-family:mainfrom
Sherry-hue:fix/remove-server-history
May 20, 2026
Merged

fix(a2ui): move history storage from server to client#2675
gaoachao merged 1 commit into
lynx-family:mainfrom
Sherry-hue:fix/remove-server-history

Conversation

@Sherry-hue
Copy link
Copy Markdown
Collaborator

@Sherry-hue Sherry-hue commented May 20, 2026

Summary by CodeRabbit

  • New Features

    • Client-provided conversation context is now accepted for chat and action requests, enabling bounded histories and model-backed data to flow with each request.
  • Bug Fixes

    • Improved handling of malformed JSON escapes in model output and safer recovery when generation fails.
  • Documentation

    • Deployment guidance updated to clarify serverless/multi-replica suitability and client-driven conversation responsibilities.
  • Chores

    • Removed server-side per-thread conversation memory; conversation size and content are validated with configurable limits.

Review Change Stack

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (or not required).

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 20, 2026

⚠️ No Changeset found

Latest commit: 772593c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

📝 Walkthrough

Walkthrough

This PR moves conversation memory from server-side threadId-backed storage to a client-supplied ConversationContext, adds validation and size limits, updates service and route signatures to accept conversation context, and updates the playground client to build, send, and apply conversation/data-model payloads.

Changes

Conversation state migration from server-side threads to client context

Layer / File(s) Summary
Service layer: conversation context contract and API updates
packages/genui/server/service/a2ui-agent.ts
Introduces ConversationContext interface (history + dataModel), removes ChatOptions.threadId, and updates streamAsAsyncIterable, generateRaw, generateValidated to accept optional conversation parameter. Removes internal ConversationMemory structure, thread-lifecycle methods (getConversation, peekConversation, resetConversation, recordStreamedConversation), and thread-based conversation merging helpers. Adds buildConversationMessages helper to construct prompts from history and data model.
Shared request body validation: conversation shape and limits
packages/genui/server/app/a2ui/_shared.ts
Introduces ConversationContext type import, adds MAX_CONVERSATION_CHARS constant, updates A2UIChatBody to accept conversation field instead of threadId, removes threadId from pickChatOptions, and implements validateConversation function that validates message roles/counts, character limits, and data model structure with 400/413 error responses.
Route handlers: validation and conversation forwarding
packages/genui/server/app/a2ui/chat/route.ts, packages/genui/server/app/a2ui/stream/route.ts, packages/genui/server/app/a2ui/action/route.ts, packages/genui/server/app/a2ui/action/stream/route.ts
All four route handlers updated to validate body.conversation via validateConversation, return CORS-wrapped errors on validation failure, and pass validated conversation to service methods. Removes thread-based conversation lookups, recordStreamedConversation calls, threadId requirements, and reset behavior. Updated A2UIActionBody and A2UIActionStreamBody contracts.
Client: conversation context building and data model updates
packages/genui/a2ui-playground/src/pages/AIChatPage.tsx
Adds conversation-context building utilities: ConversationContext interface, MAX_CONVERSATION_TURNS/MAX_CONVERSATION_CHARS bounds, buildConversationContext() function, data-model cloning/patching helpers, and dataModelRef state. Refactors send/action flows to snapshot conversation context, pass it in request bodies, apply returned updateDataModel mutations, and restore context on failure. Removes threadId tracking and SSE start event handling.
Documentation and parsing/prompt updates
packages/genui/server/AGENTS.md, packages/genui/server/agent/a2ui-agent.ts, packages/genui/server/agent/a2ui-prompt.ts, packages/genui/server/agent/a2ui-validator.ts
Updates AGENTS.md deployment guidance to reflect serverless/multi-replica safety via client-supplied conversation context; removes TTL/LRU conversation-memory documentation. Removes threadId from run options. Rewrites PROTOCOL_OVERVIEW system prompt to reference client-held conversation instead of threadId. Adds JSON escape sanitization in a2ui-validator.ts to retry parsing of malformed JSON with minimal unescape logic.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • lynx-family/lynx-stack#2667: Refactors action-streaming flows; related to removing threadId-based action streaming and switching to conversation payloads.
  • lynx-family/lynx-stack#2472: Earlier AIChatPage scaffold that this PR extends with ConversationContext and data-model handling.

Suggested reviewers

  • PupilTong
  • HuJean

Poem

🐰 I cloned the model, trimmed the past,
I sent the context—compact and fast,
No threads to hold what clients keep,
Conversations flow, and rabbits leap! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately summarizes the main architectural change: moving conversation history storage from server-side (threadId-based in-memory state) to client-side (ConversationContext sent per request), which is the primary objective across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 `@packages/genui/server/agent/a2ui-validator.ts`:
- Around line 180-182: The current code applies unescapeInvalidJsonEscapes
before the initial JSON.parse which can corrupt valid strings (e.g., "\\\\x");
change the flow so you first build the candidate body from
stripCodeFenceWrapper(text) and unescapeInvalidBackticks(...) and attempt
JSON.parse on that original candidate, and only if the parse fails apply
unescapeInvalidJsonEscapes to the candidate (or to the failing parse input) and
retry parsing; update usages of the body variable and any error handling to
reflect the two-step parse attempt and keep functions
unescapeInvalidJsonEscapes, stripCodeFenceWrapper, and unescapeInvalidBackticks
as referenced symbols.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4820960f-38fe-45f2-8601-425154452c7c

📥 Commits

Reviewing files that changed from the base of the PR and between bf08205 and cab3aaa.

📒 Files selected for processing (12)
  • packages/genui/a2ui-playground/src/pages/AIChatPage.tsx
  • packages/genui/server/AGENTS.md
  • packages/genui/server/agent/a2ui-agent.ts
  • packages/genui/server/agent/a2ui-prompt.ts
  • packages/genui/server/agent/a2ui-validator.ts
  • packages/genui/server/app/a2ui/_shared.ts
  • packages/genui/server/app/a2ui/action/route.ts
  • packages/genui/server/app/a2ui/action/stream/route.ts
  • packages/genui/server/app/a2ui/chat/route.ts
  • packages/genui/server/app/a2ui/reset/route.ts
  • packages/genui/server/app/a2ui/stream/route.ts
  • packages/genui/server/service/a2ui-agent.ts
💤 Files with no reviewable changes (2)
  • packages/genui/server/app/a2ui/reset/route.ts
  • packages/genui/server/agent/a2ui-agent.ts

Comment thread packages/genui/server/agent/a2ui-validator.ts Outdated
@Sherry-hue Sherry-hue force-pushed the fix/remove-server-history branch from cab3aaa to 772593c Compare May 20, 2026 04:05
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 `@packages/genui/server/app/a2ui/action/route.ts`:
- Around line 55-60: The early-return validation for missing action.name in the
route handler currently returns a 200 response; update the conditional that
checks if (!body.action || !body.action.name) to return the same bad-request
status used by the conversation validation branch (i.e., set HTTP status 400)
when calling jsonWithCors so the response indicates a client validation error;
adjust the jsonWithCors call in that block (the one returning { ok: false,
error: 'action.name is required' }) to include the 400 status.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 94866cfc-4f37-4fdd-b737-4cbb9c84006f

📥 Commits

Reviewing files that changed from the base of the PR and between cab3aaa and 772593c.

📒 Files selected for processing (12)
  • packages/genui/a2ui-playground/src/pages/AIChatPage.tsx
  • packages/genui/server/AGENTS.md
  • packages/genui/server/agent/a2ui-agent.ts
  • packages/genui/server/agent/a2ui-prompt.ts
  • packages/genui/server/agent/a2ui-validator.ts
  • packages/genui/server/app/a2ui/_shared.ts
  • packages/genui/server/app/a2ui/action/route.ts
  • packages/genui/server/app/a2ui/action/stream/route.ts
  • packages/genui/server/app/a2ui/chat/route.ts
  • packages/genui/server/app/a2ui/reset/route.ts
  • packages/genui/server/app/a2ui/stream/route.ts
  • packages/genui/server/service/a2ui-agent.ts
💤 Files with no reviewable changes (2)
  • packages/genui/server/app/a2ui/reset/route.ts
  • packages/genui/server/agent/a2ui-agent.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/genui/server/agent/a2ui-prompt.ts

Comment thread packages/genui/server/app/a2ui/action/route.ts
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 20, 2026

Merging this PR will degrade performance by 7.06%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 80 untouched benchmarks
⏩ 26 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
transform 1000 view elements 40 ms 43 ms -7.06%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing Sherry-hue:fix/remove-server-history (772593c) with main (bf08205)

Open in CodSpeed

Footnotes

  1. 26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

React Example

#8485 Bundle Size — 237.74KiB (0%).

772593c(current) vs bf08205 main#8482(baseline)

Bundle metrics  no changes
                 Current
#8485
     Baseline
#8482
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 200 200
No change  Duplicate Modules 81 81
No change  Duplicate Code 44.76% 44.76%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#8485
     Baseline
#8482
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.98KiB 91.98KiB

Bundle analysis reportBranch Sherry-hue:fix/remove-server-his...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

React External

#1600 Bundle Size — 697.9KiB (0%).

772593c(current) vs bf08205 main#1597(baseline)

Bundle metrics  no changes
                 Current
#1600
     Baseline
#1597
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1600
     Baseline
#1597
No change  Other 697.9KiB 697.9KiB

Bundle analysis reportBranch Sherry-hue:fix/remove-server-his...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

React MTF Example

#1618 Bundle Size — 208.69KiB (0%).

772593c(current) vs bf08205 main#1615(baseline)

Bundle metrics  no changes
                 Current
#1618
     Baseline
#1615
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 195 195
No change  Duplicate Modules 78 78
No change  Duplicate Code 44.26% 44.26%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1618
     Baseline
#1615
No change  IMG 111.23KiB 111.23KiB
No change  Other 97.46KiB 97.46KiB

Bundle analysis reportBranch Sherry-hue:fix/remove-server-his...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

React Example with Element Template

#754 Bundle Size — 204.53KiB (0%).

772593c(current) vs bf08205 main#751(baseline)

Bundle metrics  Change 2 changes
                 Current
#754
     Baseline
#751
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 100(+1.01%) 99
No change  Duplicate Modules 31 31
Change  Duplicate Code 39.57%(-0.03%) 39.58%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#754
     Baseline
#751
No change  IMG 145.76KiB 145.76KiB
No change  Other 58.78KiB 58.78KiB

Bundle analysis reportBranch Sherry-hue:fix/remove-server-his...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 20, 2026

Web Explorer

#10059 Bundle Size — 903.53KiB (0%).

772593c(current) vs bf08205 main#10056(baseline)

Bundle metrics  Change 2 changes
                 Current
#10059
     Baseline
#10056
No change  Initial JS 45.06KiB 45.06KiB
No change  Initial CSS 2.22KiB 2.22KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 9 9
No change  Assets 11 11
Change  Modules 232(+1.31%) 229
No change  Duplicate Modules 11 11
Change  Duplicate Code 27.12%(-0.04%) 27.13%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#10059
     Baseline
#10056
No change  JS 499.15KiB 499.15KiB
No change  Other 402.16KiB 402.16KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch Sherry-hue:fix/remove-server-his...Project dashboard


Generated by RelativeCIDocumentationReport issue

@Sherry-hue Sherry-hue changed the title fix(web): move history storage from server to client fix(a2ui): move history storage from server to client May 20, 2026
@gaoachao gaoachao self-requested a review May 20, 2026 05:52
@gaoachao gaoachao merged commit 3901c96 into lynx-family:main May 20, 2026
54 of 55 checks passed
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