Skip to content

examples: fix setup and signaling inconsistencies - #970

Merged
yisding merged 4 commits into
mainfrom
agent/fix-example-consistency
Aug 9, 2026
Merged

examples: fix setup and signaling inconsistencies#970
yisding merged 4 commits into
mainfrom
agent/fix-example-consistency

Conversation

@yisding

@yisding yisding commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Problem

Runnable examples, their setup guidance, and WebRTC signaling behavior had drifted across dependency versions, transport capabilities, authentication defaults, and TURN exposure semantics. Some gaps were security-relevant: browser bootstrap tokens traveled in query strings, root redirects repeated them, and hidden-credential TURN entries produced invalid browser ICE configuration.

Changes

  • move bundled-browser token bootstrap to an encoded #token= fragment, scrub it immediately, and ignore/remove legacy query bootstraps
  • strip token parameters from root redirects while preserving safe route/query state
  • split browser-safe STUN/TURN serialization from the full server-peer ICE configuration; omit hidden/incomplete TURN from browser config while retaining anonymous/partial TURN server-side
  • make EC2 signaling tokens URL-safe, clarify TURN relay behavior, recognize both turn: and turns:, and repair failed pre-registration WebRTC startup rollback
  • preserve optional capabilities in the custom transport wrapper and align VAD, noise-reduction, Twilio proxy, sample-rate, offline-provider, and support-file guidance
  • pin legacy AgentExecutor examples to compatible LangChain versions and add an isolated CI job that loads both examples, adapts them to LangChainBridge, and runs a network-free RunnableLambda turn
  • synchronize tests, typecheck commands, contributor docs, and deployment/browser documentation with these contracts

Impact

Authenticated browser links no longer put bearer tokens in HTTP requests or redirect history. Browser ICE configuration is always constructible, server-only TURN remains usable, example setup commands match their dependencies, and transport/provider claims are backed by runtime constants or regression coverage.

Root cause

Examples, browser assets, CI dependency lanes, and shared WebRTC serializers evolved independently, allowing duplicated assumptions and stale guidance to accumulate.

Verification

  • all three independent subagent audit tracks ended with no new actionable findings
  • pre-commit: Ruff check/format, import linter, YAML, codespell, actionlint, and zizmor passed
  • mypy: 291 source files plus the legacy smoke script passed
  • focused WebRTC suite: 182 passed
  • docs guard: 179 passed, 1 skipped
  • operations guard: 327 passed, 2 skipped, 4 deselected
  • examples guard: 570 passed, 57 skipped, 9 deselected
  • teaching guard: 322 passed, 1 skipped
  • isolated legacy environment resolved langchain==0.3.30 and langchain-openai==0.3.35; example load, bridge adaptation, and runtime event streaming passed
  • credential-free parallel suite: 9,295 passed, 163 skipped; one unrelated load-sensitive 50 ms timer assertion passed immediately on focused retry
  • credential-free serial lane: 5 passed, 9,528 deselected
  • shell syntax, inline JavaScript syntax, git diff --check, and targeted environment/path-sensitive reruns passed

Summary by CodeRabbit

  • New Features

    • WebRTC browser clients now authenticate with bearer tokens supplied through URL fragments.
    • Added HTTPS public URL support for remote serve deployments.
    • Public ICE configuration filters incomplete TURN credentials while retaining valid STUN/TURN entries.
  • Bug Fixes

    • Token values are removed from browser history, and query-string tokens are ignored.
    • Redirects no longer propagate legacy signaling tokens.
    • Improved WebRTC startup cleanup after failed initialization.
  • Documentation

    • Updated deployment, browser, transport, provider, proxy, TURN, offline, and legacy LangChain guidance.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yisding, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 48638680-54d6-457c-8075-258a42048408

📥 Commits

Reviewing files that changed from the base of the PR and between 305b9e4 and 607713f.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (20)
  • .github/workflows/ci.yml
  • .github/workflows/nightly-validation.yml
  • CONTRIBUTING.md
  • docs/architecture.md
  • docs/install.md
  • docs/using-easycat/05-agent-bridges/README.md
  • examples/README.md
  • examples/function_tools_langchain.py
  • examples/langchain_voice.py
  • examples/session_actions_langchain.py
  • justfile
  • pyproject.toml
  • scripts/bridge_extras_evidence.py
  • scripts/extras_smoke.py
  • scripts/smoke_langchain_versions.py
  • tests/examples/_examples_helpers.py
  • tests/examples/test_readme_matrix.py
  • tests/install/test_install_guidance.py
  • tests/test_dependency_policy.py
  • tests/test_extras_matrix.py
📝 Walkthrough

Walkthrough

The PR moves WebRTC bootstrap tokens to URL fragments, sends them as bearer headers, filters public ICE configuration, and sanitizes redirects. It also adds isolated legacy LangChain checks and updates example types, installation guidance, and provider documentation.

Changes

WebRTC authentication and browser flow

Layer / File(s) Summary
Fragment token forwarding
src/easycat/cli/serve.py, src/easycat/voice_app.py, examples/webrtc_static/*, examples/webrtc_server.py, examples/webrtc_observability_server.py, src/easycat/transports/static/webrtc_client.html
WebRTC URLs use #token= fragments. Browser clients remove token data from visible URLs and send bearer headers.
Redirect and browser-safe ICE handling
src/easycat/server/*, src/easycat/transports/_webrtc_config.py, src/easycat/transports/webrtc.py
Redirects discard legacy token query parameters. Browser /config responses omit incomplete TURN entries and expose credentials only when configured. Failed startup cleanup discards unregistered sites.
WebRTC integration coverage
tests/cli/test_serve.py, tests/server/test_webrtc_routes.py, tests/transports/test_webrtc_*.py, tests/examples/test_deploy_and_browser_docs.py
Tests cover fragment tokens, bearer requests, redirect sanitization, ICE filtering, token generation, documentation, and browser event forwarding.

Legacy LangChain examples

Layer / File(s) Summary
Legacy dependency setup
examples/README.md, examples/function_tools_langchain.py, examples/session_actions_langchain.py
Legacy examples use the quickstart setup and require langchain<1 and langchain-openai<1.
Legacy smoke validation
.github/workflows/ci.yml, scripts/smoke_legacy_langchain_examples.py, CONTRIBUTING.md, justfile, tests/test_dependency_policy.py
An isolated Python 3.12 CI job loads both examples and validates LangChainBridge events. Type-check and policy checks include the smoke script.

Example contracts and guidance

Layer / File(s) Summary
Example type contracts
examples/custom_transport.py, examples/noise_reduction_backends.py, examples/vad_backends.py, examples/voice_app_twilio.py, tests/examples/test_example_imports.py
Examples use concrete backend and transport types. CountingTransport delegates optional capabilities to LocalTransport.
Provider and deployment guidance
docs/teaching/13-swap-providers-and-transports/README.md, examples/README.md, examples/ec2_webrtc/deploy.sh, tests/examples/test_readme_matrix.py
Documentation updates installation commands, proxy settings, TURN behavior, client variants, audio characteristics, and offline provider guidance.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant WebRTCClient
  participant WebRTCRoutes
  participant WebRTCSignaling
  Browser->>WebRTCClient: Load URL with fragment token
  WebRTCClient->>WebRTCSignaling: Request /config with bearer header
  WebRTCSignaling-->>WebRTCClient: Return browser-safe ICE configuration
  WebRTCClient->>WebRTCSignaling: Submit /offer with bearer header
  WebRTCSignaling-->>Browser: Return WebRTC session response
Loading

Possibly related PRs

Suggested reviewers: charliecreates

Poem

A rabbit guards the token trail,
Fragments ride where headers sail.
TURN paths hide without full keys,
Legacy checks run with ease.
Typed examples hop in line,
WebRTC links stay safe and fine.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% 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.
Title check ✅ Passed The title clearly identifies the main themes: example setup fixes and WebRTC signaling consistency updates.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-example-consistency

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.

@yisding
yisding marked this pull request as ready for review August 9, 2026 05:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 `@examples/function_tools_langchain.py`:
- Line 35: Move the trailing period outside the rendered command/code span in
examples/function_tools_langchain.py lines 35-35 and
examples/session_actions_langchain.py lines 35-35, so both displayed commands
can be copied without including punctuation.

In `@examples/README.md`:
- Line 82: Resolve the incompatible legacy LangChain dependency instructions by
isolating these examples in a separate environment with LangChain 0.3.x and a
compatible langchain-core range, or update the extra and lockfile accordingly.
Apply the fix to the install cells in examples/README.md lines 82-82 and 86-86,
and the setup commands in examples/function_tools_langchain.py lines 9-10 and
examples/session_actions_langchain.py lines 13-14, keeping all four locations
consistent.

In `@examples/webrtc_static/webrtc_client.html`:
- Around line 112-122: Update authHeaders and its callers fetchIceConfig and
negotiate to only attach the bearer token when the request URL matches the
trusted signaling origin, preventing authToken from location.search being
forwarded to different origins. Preserve existing extra headers and
unauthenticated behavior.

In `@examples/webrtc_static/webrtc_observability.html`:
- Around line 44-50: Update examples/webrtc_static/webrtc_observability.html
lines 44-50 to stop forwarding signalingToken through the iframe query string
and hand it to the same-origin WebRTC client via an explicit
postMessage/bootstrap mechanism. Update docs/deployment/production-servers.md
lines 213-218 to restrict URL-token forwarding to local development or document
the non-URL bootstrap. Update tests/examples/test_deploy_and_browser_docs.py
lines 652-662 to assert the safer token handoff rather than query-string
propagation.

In `@tests/examples/test_deploy_and_browser_docs.py`:
- Around line 652-662: The regression test
test_webrtc_observability_client_forwards_signaling_token currently requires URL
query-string token forwarding through webrtcParams.set("token", signalingToken).
Replace that assertion with checks for the selected non-URL, same-origin token
handoff in the observability flow, while retaining the existing bearer-header
assertions and other relevant behavior coverage.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6a9e5b9e-49a0-4037-b9d6-21303ba03516

📥 Commits

Reviewing files that changed from the base of the PR and between 3a32b20 and afb1ce9.

📒 Files selected for processing (14)
  • docs/browser-playground.md
  • docs/deployment/production-servers.md
  • docs/teaching/13-swap-providers-and-transports/README.md
  • examples/README.md
  • examples/custom_transport.py
  • examples/function_tools_langchain.py
  • examples/noise_reduction_backends.py
  • examples/session_actions_langchain.py
  • examples/vad_backends.py
  • examples/voice_app_twilio.py
  • examples/webrtc_static/webrtc_client.html
  • examples/webrtc_static/webrtc_observability.html
  • tests/examples/test_deploy_and_browser_docs.py
  • tests/examples/test_readme_matrix.py

Comment thread examples/function_tools_langchain.py Outdated
Comment thread examples/README.md Outdated
Comment thread examples/webrtc_static/webrtc_client.html Outdated
Comment thread examples/webrtc_static/webrtc_observability.html Outdated
Comment thread tests/examples/test_deploy_and_browser_docs.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 @.github/workflows/ci.yml:
- Around line 191-198: Replace the incompatible `.[quickstart]` plus legacy
constraints in the legacy CI install step with a dedicated legacy extra or
environment specifying mutually compatible LangChain 0.3.x packages. Update the
README installation cells and `tests/test_dependency_policy.py` to reference and
validate this same legacy dependency contract, while keeping
`smoke_legacy_langchain_examples.py` running in that environment.

In `@tests/cli/test_serve.py`:
- Line 205: Update _playground_url() and its serve output path so token-bearing
URLs are not printed for non-loopback HTTP bindings. Require an explicitly
configured HTTPS public URL for remote token URLs, or restrict
token-authenticated direct HTTP to loopback, while preserving token output for
safe loopback and HTTPS cases.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b2604465-e847-4401-a118-5ed9503775d1

📥 Commits

Reviewing files that changed from the base of the PR and between afb1ce9 and f752764.

📒 Files selected for processing (34)
  • .github/workflows/ci.yml
  • CONTRIBUTING.md
  • docs/browser-playground.md
  • docs/deployment/production-servers.md
  • docs/teaching/13-swap-providers-and-transports/README.md
  • examples/README.md
  • examples/custom_transport.py
  • examples/ec2_webrtc/deploy.sh
  • examples/noise_reduction_backends.py
  • examples/vad_backends.py
  • examples/voice_app_twilio.py
  • examples/webrtc_observability_server.py
  • examples/webrtc_server.py
  • examples/webrtc_static/webrtc_client.html
  • examples/webrtc_static/webrtc_observability.html
  • justfile
  • scripts/smoke_legacy_langchain_examples.py
  • src/easycat/cli/serve.py
  • src/easycat/server/_webrtc_handlers.py
  • src/easycat/server/webrtc_routes.py
  • src/easycat/transports/_webrtc_config.py
  • src/easycat/transports/static/webrtc_client.html
  • src/easycat/transports/webrtc.py
  • src/easycat/voice_app.py
  • tests/cli/test_serve.py
  • tests/examples/test_deploy_and_browser_docs.py
  • tests/examples/test_example_imports.py
  • tests/examples/test_readme_matrix.py
  • tests/server/test_webrtc_routes.py
  • tests/teaching/test_provider_matrix_measurement.py
  • tests/test_dependency_policy.py
  • tests/transports/test_voice_app_modes.py
  • tests/transports/test_webrtc_auth_browser_playground.py
  • tests/transports/test_webrtc_lifecycle_server.py

Comment thread .github/workflows/ci.yml Outdated
Comment thread tests/cli/test_serve.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
examples/session_actions_langchain.py (1)

13-14: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Align the legacy LangChain guidance with the pinned langchain-core floor.

Both setup paths add langchain<1 / langchain-openai<1, but this repo pins langchain-core>=1.5.3 for langchain/all and the installed lock contains langchain_core==1.5.3. Legacy LangChain 0.3.x is not compatible with langchain-core>=1.5.3, so these setup instructions can fail or leave an unusable dependency graph. Add an explicit constraint for both langchain packages that matches langchain-core<1, or move this example into a separate dependency path.

🤖 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 `@examples/session_actions_langchain.py` around lines 13 - 14, Update the setup
guidance in session_actions_langchain.py so both installation paths constrain
langchain and langchain-openai to versions compatible with the repository’s
langchain-core requirement, using an explicit langchain-core<1 constraint
alongside the existing package bounds.
🤖 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.

Outside diff comments:
In `@examples/session_actions_langchain.py`:
- Around line 13-14: Update the setup guidance in session_actions_langchain.py
so both installation paths constrain langchain and langchain-openai to versions
compatible with the repository’s langchain-core requirement, using an explicit
langchain-core<1 constraint alongside the existing package bounds.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cfc9f391-7328-4828-b3e0-47e09d76cab6

📥 Commits

Reviewing files that changed from the base of the PR and between f752764 and 305b9e4.

📒 Files selected for processing (6)
  • docs/browser-playground.md
  • docs/teaching/15-operate-in-production/README.md
  • examples/function_tools_langchain.py
  • examples/session_actions_langchain.py
  • src/easycat/cli/serve.py
  • tests/cli/test_serve.py

@yisding

yisding commented Aug 9, 2026

Copy link
Copy Markdown
Owner Author

Addressed in 607713f by using the separate dependency path suggested here, expanded into first-class support for both LangChain lines:

  • langchain installs a coherent 1.x langchain / langchain-core / langchain-openai set.
  • langchain-v0 installs the coherent 0.3.x set and explicitly conflicts with the v1, LangGraph, and all selections.
  • The 0.3 AgentExecutor examples now use --extra langchain-v0; the LCEL example uses --extra langchain.
  • PR CI installs and smokes both lines independently, while the nightly extras matrix runs the same exact real-SDK bridge contract for both.

Validation: both isolated installs passed their example/runtime smoke, and the same 7 real-SDK bridge contract tests passed on LangChain 0.3 and 1.x. Dependency-policy, examples, docs, lint, formatting, typing, pre-commit, and lock checks also pass.

This finding was emitted in the review body as an outside-diff comment, so GitHub did not create an inline thread that can be marked resolved. This reply records it as addressed.

@yisding
yisding merged commit 3058a5b into main Aug 9, 2026
20 checks passed
@yisding
yisding deleted the agent/fix-example-consistency branch August 9, 2026 20:30
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