Skip to content

feat: add server endpoint#2648

Merged
Sherry-hue merged 1 commit into
lynx-family:mainfrom
Sherry-hue:feat/server-endpoint
May 18, 2026
Merged

feat: add server endpoint#2648
Sherry-hue merged 1 commit into
lynx-family:mainfrom
Sherry-hue:feat/server-endpoint

Conversation

@Sherry-hue
Copy link
Copy Markdown
Collaborator

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

Summary by CodeRabbit

  • New Features

    • Configurable online chat streaming endpoint resolution and default streaming URL behavior.
    • Configurable limits for request body size, message length, and message count with sensible defaults.
  • Improvements

    • Unified, size-limited JSON parsing with clearer error responses across chat, stream, and action routes.
    • Stronger message validation with explicit errors for invalid or oversized messages.
    • Tighter CORS handling when Origin is absent.
    • Updated TypeScript compiler settings.

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 15, 2026

⚠️ No Changeset found

Latest commit: bc9a270

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 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cf73a529-621e-43fc-9fc7-9937d71dd7fe

📥 Commits

Reviewing files that changed from the base of the PR and between 186440d and bc9a270.

📒 Files selected for processing (10)
  • packages/genui/a2ui-playground/src/pages/AIChatPage.tsx
  • packages/genui/server/app/a2ui/_shared.ts
  • packages/genui/server/app/a2ui/action/route.ts
  • packages/genui/server/app/a2ui/chat/route.ts
  • packages/genui/server/app/a2ui/cors.ts
  • packages/genui/server/app/a2ui/rate-limit.ts
  • packages/genui/server/app/a2ui/stream/route.ts
  • packages/genui/server/instrumentation.ts
  • packages/genui/server/service/a2ui-agent.ts
  • packages/genui/server/tsconfig.json
✅ Files skipped from review due to trivial changes (2)
  • packages/genui/server/service/a2ui-agent.ts
  • packages/genui/server/app/a2ui/rate-limit.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/genui/server/instrumentation.ts
  • packages/genui/server/app/a2ui/action/route.ts
  • packages/genui/server/tsconfig.json
  • packages/genui/server/app/a2ui/cors.ts
  • packages/genui/server/app/a2ui/stream/route.ts
  • packages/genui/server/app/a2ui/_shared.ts

📝 Walkthrough

Walkthrough

Adds size-limited JSON parsing and message validation to a2ui shared utilities, applies them across chat/action/stream routes with structured CORS error responses, tightens CORS behavior, updates frontend endpoint origin handling, and includes small TypeScript/config and env-access refactors.

Changes

A2UI validation and endpoint configuration

Layer / File(s) Summary
Shared validation and parsing framework
packages/genui/server/app/a2ui/_shared.ts
Adds parsePositiveInt-backed MAX_* constants, validateMessages() enforcing array structure/count/shape/length, and readJsonBodyWithLimit() for size-limited JSON parsing returning { ok, status, error } typed results.
Route handler integration of validation and parsing
packages/genui/server/app/a2ui/action/route.ts, packages/genui/server/app/a2ui/chat/route.ts, packages/genui/server/app/a2ui/stream/route.ts
Replaces manual req.json() and local type guards with readJsonBodyWithLimit + validateMessages, returning CORS-wrapped JSON errors from parser/validator status codes and enforcing message/body limits before service calls.
CORS security hardening
packages/genui/server/app/a2ui/cors.ts
resolveAllowedOrigin now returns null (no Access-Control-Allow-Origin) when the request lacks an Origin header instead of returning '*'.
Frontend online endpoint configuration
packages/genui/a2ui-playground/src/pages/AIChatPage.tsx
Adds ONLINE_A2UI_SERVER_ORIGIN / ONLINE_A2UI_CHAT_URL and treats endpoints matching that origin as trusted in resolveTrustedA2UIEndpoint, and switches local/dev agent path to use /a2ui/stream.
TypeScript compiler configuration update
packages/genui/server/tsconfig.json
Targets ES2022, adds forceConsistentCasingInFileNames and useDefineForClassFields, removes empty references, and normalizes JSON formatting.
Env-access and minor refactors
packages/genui/server/app/a2ui/rate-limit.ts, packages/genui/server/instrumentation.ts, packages/genui/server/service/a2ui-agent.ts
Switches several process.env['X'] lookups to dot-notation process.env.X; no behavioral changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • PupilTong
  • HuJean

Poem

🐰 I counted bytes and snugged each line,
I guard the chat where streaming lights shine.
Origins checked and CORS doors tight,
Messages trimmed to fit just right.
Hop—deploy the patch, I hare with delight!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'feat: add server endpoint' is vague and does not clearly reflect the actual changes in the PR, which involve multiple substantial refactorings including validation utilities, CORS adjustments, environment variable parsing improvements, and endpoint modifications across several files. Replace the title with a more specific summary of the primary changes, such as 'feat: add request validation and size-limit utilities for A2UI endpoints' or 'refactor: consolidate request parsing and validation across A2UI routes'.
Docstring Coverage ⚠️ Warning Docstring coverage is 5.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 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.

✏️ 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.

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: 3

🧹 Nitpick comments (1)
packages/genui/a2ui-playground/src/pages/AIChatPage.tsx (1)

71-71: ⚡ Quick win

Consider sourcing the online origin from build-time configuration.

Hardcoding https://genui-server.vercel.app couples the playground to a specific Vercel deployment, making it awkward to point at staging/preview backends or to rebrand the production host. Since this project uses Vite, consider reading it from import.meta.env.VITE_A2UI_SERVER_ORIGIN with the current value as a fallback, similar to how LOCAL_A2UI_SERVER_PORT is already extracted as a constant.

♻️ Suggested refactor
-const ONLINE_A2UI_SERVER_ORIGIN = 'https://genui-server.vercel.app';
+const ONLINE_A2UI_SERVER_ORIGIN = import.meta.env.VITE_A2UI_SERVER_ORIGIN
+  ?? 'https://genui-server.vercel.app';
🤖 Prompt for 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.

In `@packages/genui/a2ui-playground/src/pages/AIChatPage.tsx` at line 71, Replace
the hardcoded ONLINE_A2UI_SERVER_ORIGIN value with a build-time environment
fallback: read import.meta.env.VITE_A2UI_SERVER_ORIGIN and fall back to
'https://genui-server.vercel.app' if undefined, mirroring how
LOCAL_A2UI_SERVER_PORT is obtained; update the constant
ONLINE_A2UI_SERVER_ORIGIN so runtime host selection can be driven by Vite env
vars while preserving the current default.
🤖 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/a2ui-playground/src/pages/AIChatPage.tsx`:
- Around line 71-72: The ONLINE_A2UI_CHAT_URL constant currently points to
/a2ui/stream while getA2UIChatEndpoint routes to /a2ui/chat, causing mismatched
handlers; choose the intended endpoint and make both match — e.g., if /a2ui/chat
is correct, update ONLINE_A2UI_CHAT_URL to
`${ONLINE_A2UI_SERVER_ORIGIN}/a2ui/chat`, or if /a2ui/stream is intended, change
getA2UIChatEndpoint to return the /a2ui/stream path and rename
functions/constants (ONLINE_A2UI_CHAT_URL, getA2UIChatEndpoint) to reflect
“stream” if you keep that route so names and branches are consistent.

In `@packages/genui/server/app/a2ui/_shared.ts`:
- Around line 153-159: The check currently compares raw.length (characters)
against MAX_BODY_BYTES, which fails for multibyte UTF-8 characters; replace the
character-length check with a UTF-8 byte-length check (e.g., compute the UTF-8
byte size of raw and compare that to MAX_BODY_BYTES) so the conditional guarding
the request body (the block returning { ok: false, status: 413, error: ... })
correctly enforces the byte limit; ensure you use the computed byte length (not
raw.length) in the error message and comparison.
- Around line 19-27: The parsePositiveInt function currently floors fractional
values which lets inputs like "0.5" become 0 instead of falling back; change
parsePositiveInt to reject non-integer numerical inputs by checking
Number.isFinite(n) and Number.isInteger(n) (or === Math.trunc(n)) and returning
fallback if not integer or if n <= 0, so only positive integers are accepted
before Math.floor/returning the value.

---

Nitpick comments:
In `@packages/genui/a2ui-playground/src/pages/AIChatPage.tsx`:
- Line 71: Replace the hardcoded ONLINE_A2UI_SERVER_ORIGIN value with a
build-time environment fallback: read import.meta.env.VITE_A2UI_SERVER_ORIGIN
and fall back to 'https://genui-server.vercel.app' if undefined, mirroring how
LOCAL_A2UI_SERVER_PORT is obtained; update the constant
ONLINE_A2UI_SERVER_ORIGIN so runtime host selection can be driven by Vite env
vars while preserving the current default.
🪄 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: 7f413734-d3cc-4d51-b4b5-bd8284180ce1

📥 Commits

Reviewing files that changed from the base of the PR and between 671c7d6 and 7633abd.

📒 Files selected for processing (7)
  • packages/genui/a2ui-playground/src/pages/AIChatPage.tsx
  • packages/genui/server/app/a2ui/_shared.ts
  • packages/genui/server/app/a2ui/action/route.ts
  • packages/genui/server/app/a2ui/chat/route.ts
  • packages/genui/server/app/a2ui/cors.ts
  • packages/genui/server/app/a2ui/stream/route.ts
  • packages/genui/server/tsconfig.json

Comment thread packages/genui/a2ui-playground/src/pages/AIChatPage.tsx
Comment thread packages/genui/server/app/a2ui/_shared.ts
Comment thread packages/genui/server/app/a2ui/_shared.ts Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 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!

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 15, 2026

Merging this PR will improve performance by 9.59%

⚠️ 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 improved benchmark
✅ 80 untouched benchmarks
⏩ 26 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
transform 1000 view elements 47.2 ms 43.1 ms +9.59%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing Sherry-hue:feat/server-endpoint (bc9a270) with main (676d1b3)

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 15, 2026

React Example with Element Template

#642 Bundle Size — 199.95KiB (0%).

bc9a270(current) vs 4e6b228 main#639(baseline)

Bundle metrics  Change 2 changes
                 Current
#642
     Baseline
#639
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 89(-2.2%) 91
No change  Duplicate Modules 27 27
Change  Duplicate Code 40.06%(+0.07%) 40.03%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#642
     Baseline
#639
No change  IMG 145.76KiB 145.76KiB
No change  Other 54.19KiB 54.19KiB

Bundle analysis reportBranch Sherry-hue:feat/server-endpointProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React MTF Example

#1506 Bundle Size — 208.1KiB (0%).

bc9a270(current) vs 4e6b228 main#1503(baseline)

Bundle metrics  no changes
                 Current
#1506
     Baseline
#1503
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 192 192
No change  Duplicate Modules 77 77
No change  Duplicate Code 44.4% 44.4%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1506
     Baseline
#1503
No change  IMG 111.23KiB 111.23KiB
No change  Other 96.86KiB 96.86KiB

Bundle analysis reportBranch Sherry-hue:feat/server-endpointProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React Example

#8373 Bundle Size — 237.15KiB (0%).

bc9a270(current) vs 4e6b228 main#8371(baseline)

Bundle metrics  no changes
                 Current
#8373
     Baseline
#8371
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 197 197
No change  Duplicate Modules 80 80
No change  Duplicate Code 44.89% 44.89%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#8373
     Baseline
#8371
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.39KiB 91.39KiB

Bundle analysis reportBranch Sherry-hue:feat/server-endpointProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

Web Explorer

#9947 Bundle Size — 901.35KiB (0%).

bc9a270(current) vs 4e6b228 main#9944(baseline)

Bundle metrics  no changes
                 Current
#9947
     Baseline
#9944
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
No change  Modules 229 229
No change  Duplicate Modules 11 11
No change  Duplicate Code 27.22% 27.22%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#9947
     Baseline
#9944
No change  JS 497.08KiB 497.08KiB
No change  Other 402.06KiB 402.06KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch Sherry-hue:feat/server-endpointProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 15, 2026

React External

#1488 Bundle Size — 695.33KiB (0%).

bc9a270(current) vs 4e6b228 main#1485(baseline)

Bundle metrics  no changes
                 Current
#1488
     Baseline
#1485
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
#1488
     Baseline
#1485
No change  Other 695.33KiB 695.33KiB

Bundle analysis reportBranch Sherry-hue:feat/server-endpointProject dashboard


Generated by RelativeCIDocumentationReport issue

PupilTong added a commit to PupilTong/lynx-stack that referenced this pull request May 15, 2026
`Vitest (Windows)` failed on
`packages/rspeedy/plugin-react/test/background-only.test.ts:153`:

  AssertionError: expected error.message === 'Rspack build failed.'
    Expected: "Rspack build failed."
    Received: "ENOENT: no such file or directory,
               open 'C:\\…\\test\\dist\\.rspeedy\\rspeedy.config.js'"

The test expects rsbuild to report `Rspack build failed.` when the
configured entry is missing, but on Windows the failure surfaces
earlier as an ENOENT trying to open a generated config file under the
test's dist tree. This PR doesn't touch
`packages/rspeedy/plugin-react`; Vitest (Ubuntu) passed; the same
Vitest (Windows) check passes on other open PRs against the same
upstream (lynx-family#2645, lynx-family#2646, lynx-family#2648). Windows-only rspeedy infrastructure
flake — same family as the `validate is not a function` race we hit
earlier. Empty commit to retry.
@Sherry-hue Sherry-hue force-pushed the feat/server-endpoint branch from 7633abd to 186440d Compare May 18, 2026 03:17
@Sherry-hue Sherry-hue force-pushed the feat/server-endpoint branch from 186440d to bc9a270 Compare May 18, 2026 03:35
@Sherry-hue Sherry-hue merged commit 51a32e1 into lynx-family:main May 18, 2026
83 of 85 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