Skip to content

fix: improve string escaping in toTsLiteral function for better compatibility#298

Merged
frontegg-david merged 6 commits intorelease/1.0.xfrom
fix-streamable-elicit
Mar 19, 2026
Merged

fix: improve string escaping in toTsLiteral function for better compatibility#298
frontegg-david merged 6 commits intorelease/1.0.xfrom
fix-streamable-elicit

Conversation

@frontegg-david
Copy link
Contributor

@frontegg-david frontegg-david commented Mar 18, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Fixed string escaping in generated type schemas so backslashes are preserved correctly.
  • Refactor

    • Consolidated initialization persistence to improve consistency and reliability of session initialization handling.
  • Tests

    • Updated session utility tests to better validate session update and missing-session behaviors.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 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: fdc2a1bb-6eec-448f-b530-b92cd31d3415

📥 Commits

Reviewing files that changed from the base of the PR and between 0e34831 and 52bd65d.

📒 Files selected for processing (1)
  • libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts

📝 Walkthrough

Walkthrough

Centralizes MCP initialization payload persistence via a new helper, updates unit test expectations in session utilities, and tightens string escaping in the schema type generator to preserve backslashes in TypeScript literals.

Changes

Cohort / File(s) Summary
Session Test Updates
libs/sdk/src/auth/session/__tests__/session-id.utils.spec.ts
Adjusted two assertions: added a type check that updated is a string and changed the non-existent session expectation from false to null.
MCP Handler Refactoring
libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts
Added persistInitPayload helper; replaced direct calls to updateSessionPayload/transport.setInitSessionPayload with the helper in both init branches; uses SdkAuthInfo.transport to persist at transport level.
Schema Type Generation
scripts/generate-schema-types.mjs
Enhanced toTsLiteral to double backslashes before escaping single quotes so string values preserve backslashes in generated TS literals.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant InitHandler as InitializeRequestHandler
    participant PersistHelper as persistInitPayload
    participant SessionStore as SessionPayloadStore
    participant Transport as TransportAdapter

    Client->>InitHandler: send initialize request (clientInfo / sessionIdPayload)
    InitHandler->>PersistHelper: call persistInitPayload(data)
    PersistHelper->>SessionStore: updateSessionPayload(data)
    PersistHelper->>Transport: setInitSessionPayload(data)
    PersistHelper-->>InitHandler: ack
    InitHandler-->>Client: respond (sessionId not propagated)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hop, hop, I patched the stream,
Payloads settle, tidy as a dream.
Backslashes doubled, tests now true,
Init saved twice — for me and you. 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title focuses on the toTsLiteral string escaping fix, which is a secondary change. The primary changes are in session handling and MCP initialization logic, making the title partially related but not representative of the main changeset. Consider a more comprehensive title like 'refactor: improve session initialization and string escaping' to better represent all significant changes in the PR.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 66.67% which is sufficient. The required threshold is 65.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-streamable-elicit
📝 Coding Plan
  • Generate coding plan for human review comments

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

@frontegg-david frontegg-david changed the title Fix streamable elicit fix: improve string escaping in toTsLiteral function for better compatibility Mar 18, 2026
Copy link
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.

🧹 Nitpick comments (5)
libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts (3)

106-142: Minor duplication in transport persistence logic.

Both branches (with and without clientInfo) follow the same pattern:

  1. Build initPayload
  2. Call updateSessionPayload
  3. Persist on transport via setInitSessionPayload

Consider extracting the common persistence logic into a helper to reduce duplication.

💡 Potential refactor
// Helper function for persistence
function persistInitPayload(
  sessionId: string, 
  initPayload: Record<string, unknown>, 
  transport?: { setInitSessionPayload: (p: Record<string, unknown>) => void }
): void {
  updateSessionPayload(sessionId, initPayload);
  transport?.setInitSessionPayload(initPayload);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts` around
lines 106 - 142, Extract the duplicated persistence steps into a small helper
(e.g., persistInitPayload) that takes sessionId, initPayload, and an optional
transport and calls updateSessionPayload(sessionId, initPayload) and
transport?.setInitSessionPayload(initPayload); then replace the duplicated
blocks in initialize-request.handler.ts (both branches that currently build
initPayload and call updateSessionPayload / transport?.setInitSessionPayload)
with a single call to that helper to remove duplication while keeping existing
behavior.

115-115: Consider using the new session ID returned by updateSessionPayload.

updateSessionPayload now returns the new encrypted session ID containing the updated payload, but this return value is ignored. While both old and new session IDs are cached, consider whether the new session ID should be propagated to ensure clients use the updated session ID in subsequent requests.

If ignoring the return value is intentional (relying on dual caching), a comment explaining this would improve clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts` at line
115, The call to updateSessionPayload(sessionId, initPayload) currently ignores
its returned new encrypted session ID; either capture that return value and
propagate it (e.g., replace cached sessionId and ensure it is included in
subsequent responses to clients) so clients use the updated session ID, or if
the dual-caching approach is intentional, add an explicit comment next to the
call explaining why the returned new session ID is safely ignored; reference
updateSessionPayload, sessionId, and initPayload when making the change.

121-122: Type cast to access transport suggests a type definition gap.

The cast (ctx.authInfo as SdkAuthInfo)?.transport is used twice to access the transport property. If ctx.authInfo should include the transport property, consider updating the type definition for authInfo in the context type to include it, avoiding runtime type assertions.

Also applies to: 140-141

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts` around
lines 121 - 122, Update the context type so ctx.authInfo is typed to include the
transport property (i.e., extend the Context/AuthInfo interface to reference
SdkAuthInfo or a transport-bearing type) instead of using ad-hoc casts; then
remove the inline casts `(ctx.authInfo as SdkAuthInfo)?.transport` in the places
where you call transport?.setInitSessionPayload(initPayload) and the later usage
(lines showing setInitSessionPayload and the second occurrence), ensuring calls
reference ctx.authInfo.transport directly and that the transport type exposes
setInitSessionPayload.
libs/sdk/src/auth/session/__tests__/session-id.utils.spec.ts (2)

240-241: Consider asserting the returned session ID type.

The assertion expect(updated).not.toBeNull() verifies the update succeeded, but doesn't verify the return value is actually a string (the new session ID). Consider adding expect(typeof updated).toBe('string') to fully validate the new return type contract.

💡 Suggested enhancement
-      expect(updated).not.toBeNull();
+      expect(updated).not.toBeNull();
+      expect(typeof updated).toBe('string');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/sdk/src/auth/session/__tests__/session-id.utils.spec.ts` around lines
240 - 241, The test currently only asserts that `updated` is not null; add an
assertion that the returned session ID is a string by checking `typeof updated
=== 'string'` (i.e., add `expect(typeof updated).toBe('string')`) immediately
after the existing `expect(updated).not.toBeNull()` in the test that sets
`updated` to validate the return type contract for the session ID.

281-289: Test name is now inconsistent with actual behavior.

The test is named "should return false for non-existent session" but the function now returns null, not false. Consider updating the test name for clarity.

📝 Suggested name fix
-    it('should return false for non-existent session', () => {
+    it('should return null for non-existent session', () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/sdk/src/auth/session/__tests__/session-id.utils.spec.ts` around lines
281 - 289, The test title is inconsistent with the asserted behavior: update the
test description for the spec that calls updateSessionPayload (the one using
mockSafeDecrypt) from "should return false for non-existent session" to
something like "should return null for non-existent session" so it matches the
actual return value (the assertion expect(result).toBeNull()); ensure the string
passed to the it(...) call is updated accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@libs/sdk/src/auth/session/__tests__/session-id.utils.spec.ts`:
- Around line 240-241: The test currently only asserts that `updated` is not
null; add an assertion that the returned session ID is a string by checking
`typeof updated === 'string'` (i.e., add `expect(typeof
updated).toBe('string')`) immediately after the existing
`expect(updated).not.toBeNull()` in the test that sets `updated` to validate the
return type contract for the session ID.
- Around line 281-289: The test title is inconsistent with the asserted
behavior: update the test description for the spec that calls
updateSessionPayload (the one using mockSafeDecrypt) from "should return false
for non-existent session" to something like "should return null for non-existent
session" so it matches the actual return value (the assertion
expect(result).toBeNull()); ensure the string passed to the it(...) call is
updated accordingly.

In `@libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts`:
- Around line 106-142: Extract the duplicated persistence steps into a small
helper (e.g., persistInitPayload) that takes sessionId, initPayload, and an
optional transport and calls updateSessionPayload(sessionId, initPayload) and
transport?.setInitSessionPayload(initPayload); then replace the duplicated
blocks in initialize-request.handler.ts (both branches that currently build
initPayload and call updateSessionPayload / transport?.setInitSessionPayload)
with a single call to that helper to remove duplication while keeping existing
behavior.
- Line 115: The call to updateSessionPayload(sessionId, initPayload) currently
ignores its returned new encrypted session ID; either capture that return value
and propagate it (e.g., replace cached sessionId and ensure it is included in
subsequent responses to clients) so clients use the updated session ID, or if
the dual-caching approach is intentional, add an explicit comment next to the
call explaining why the returned new session ID is safely ignored; reference
updateSessionPayload, sessionId, and initPayload when making the change.
- Around line 121-122: Update the context type so ctx.authInfo is typed to
include the transport property (i.e., extend the Context/AuthInfo interface to
reference SdkAuthInfo or a transport-bearing type) instead of using ad-hoc
casts; then remove the inline casts `(ctx.authInfo as SdkAuthInfo)?.transport`
in the places where you call transport?.setInitSessionPayload(initPayload) and
the later usage (lines showing setInitSessionPayload and the second occurrence),
ensuring calls reference ctx.authInfo.transport directly and that the transport
type exposes setInitSessionPayload.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b9103250-e17f-4b27-89a3-c8c0becbfe5b

📥 Commits

Reviewing files that changed from the base of the PR and between ecbccf0 and 93cef31.

📒 Files selected for processing (7)
  • apps/e2e/demo-e2e-elicitation/e2e/elicitation.e2e.spec.ts
  • libs/sdk/package.json
  • libs/sdk/src/auth/session/__tests__/session-id.utils.spec.ts
  • libs/sdk/src/auth/session/utils/session-id.utils.ts
  • libs/sdk/src/transport/adapters/transport.local.adapter.ts
  • libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts
  • scripts/generate-schema-types.mjs

@github-actions
Copy link
Contributor

github-actions bot commented Mar 18, 2026

Performance Test Results

Status: ✅ All tests passed

Summary

Project Tests Passed Warnings Failed Leaks
✅ demo-e2e-agents 4 4 0 0 0
✅ demo-e2e-cache 11 11 0 0 0
✅ demo-e2e-codecall 4 4 0 0 0
✅ demo-e2e-config 4 4 0 0 0
✅ demo-e2e-direct 3 3 0 0 0
✅ demo-e2e-elicitation 1 1 0 0 0
✅ demo-e2e-errors 4 4 0 0 0
✅ demo-e2e-hooks 3 3 0 0 0
✅ demo-e2e-multiapp 4 4 0 0 0
✅ demo-e2e-notifications 3 3 0 0 0
✅ demo-e2e-openapi 2 2 0 0 0
✅ demo-e2e-providers 4 4 0 0 0
✅ demo-e2e-public 4 4 0 0 0
✅ demo-e2e-redis 14 14 0 0 0
✅ demo-e2e-remember 4 4 0 0 0
✅ demo-e2e-remote 5 5 0 0 0
✅ demo-e2e-serverless 2 2 0 0 0
✅ demo-e2e-skills 15 15 0 0 0
✅ demo-e2e-standalone 2 2 0 0 0
✅ demo-e2e-transport-recreation 3 3 0 0 0
✅ demo-e2e-ui 4 4 0 0 0

Total: 100 tests across 21 projects

📊 View full report in workflow run


Generated at: 2026-03-19T01:08:42.234Z
Commit: 609b7e69

Copy link
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.

🧹 Nitpick comments (1)
libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts (1)

19-28: Consider stronger typing for initPayload parameter.

The initPayload parameter is typed as Partial<Record<string, unknown>>, which is very loose. Since updateSessionPayload expects Partial<SessionIdPayload>, using a more specific type would provide better compile-time safety and prevent invalid properties from being passed.

♻️ Suggested type improvement
+import type { SessionIdPayload } from '../../auth/session/utils/session-id.utils';
+
 function persistInitPayload(
   sessionId: string,
-  initPayload: Partial<Record<string, unknown>>,
+  initPayload: Partial<SessionIdPayload>,
   ctx: { authInfo?: unknown },
 ): void {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts` around
lines 19 - 28, The initPayload param of persistInitPayload is too loose
(Partial<Record<string, unknown>>) and should be tightened to match the shape
expected by updateSessionPayload; change the type to Partial<SessionIdPayload>
(or a union/partial of the concrete payload interface used by
updateSessionPayload) so TypeScript enforces valid keys, and update any call
sites accordingly; ensure imports/types for SessionIdPayload are available in
the file and keep ctx handling (SdkAuthInfo?.transport.setInitSessionPayload)
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts`:
- Around line 19-28: The initPayload param of persistInitPayload is too loose
(Partial<Record<string, unknown>>) and should be tightened to match the shape
expected by updateSessionPayload; change the type to Partial<SessionIdPayload>
(or a union/partial of the concrete payload interface used by
updateSessionPayload) so TypeScript enforces valid keys, and update any call
sites accordingly; ensure imports/types for SessionIdPayload are available in
the file and keep ctx handling (SdkAuthInfo?.transport.setInitSessionPayload)
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3ff3372b-978b-48f2-a8fd-5443b8105632

📥 Commits

Reviewing files that changed from the base of the PR and between 93cef31 and 0e34831.

📒 Files selected for processing (2)
  • libs/sdk/src/auth/session/__tests__/session-id.utils.spec.ts
  • libs/sdk/src/transport/mcp-handlers/initialize-request.handler.ts

@frontegg-david frontegg-david merged commit 7e3d3fd into release/1.0.x Mar 19, 2026
63 checks passed
@frontegg-david frontegg-david deleted the fix-streamable-elicit branch March 19, 2026 01:39
github-actions bot pushed a commit that referenced this pull request Mar 19, 2026
… better compatibility

Cherry-picked from #298 (merged to release/1.0.x)
Original commit: 7e3d3fd

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>
@github-actions
Copy link
Contributor

Cherry-pick Created

A cherry-pick PR to main has been automatically created.

Please review and merge if this change should also be in main.

If the cherry-pick is not needed, close the PR.

frontegg-david added a commit that referenced this pull request Mar 19, 2026
… better compatibility (#299)

Cherry-picked from #298 (merged to release/1.0.x)
Original commit: 7e3d3fd

Co-authored-by: agentfront[bot] <agentfront[bot]@users.noreply.github.com>
Co-authored-by: frontegg-david <69419539+frontegg-david@users.noreply.github.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.

1 participant