feat: send conversation owner id header on CAS websocket handshake [JAR-9965]#1712
feat: send conversation owner id header on CAS websocket handshake [JAR-9965]#1712scottcmg wants to merge 4 commits into
Conversation
f72d183 to
95583d1
Compare
get_chat_bridge / get_voice_bridge forward context.synthetic_user_id as the X-UiPath-Internal-SyntheticUserId handshake header so CAS can validate Unified Runtime Robot connections for RunAsMe=false conversations. No-op when the context field is unset. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
95583d1 to
1941383
Compare
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR extends the conversational chat and voice CLI bridges to forward the conversation owner ID (context.synthetic_user_id) to CAS via a new X-UiPath-Internal-SyntheticUserId header during the WebSocket handshake, enabling CAS to validate Robot connections for RunAsMe=false conversations.
Changes:
- Add
X-UiPath-Internal-SyntheticUserIdto CAS handshake headers in both chat and voice bridges whencontext.synthetic_user_idis present. - Add unit tests covering presence/absence of the new header for both bridges.
- Bump the
uipathpackage version to2.10.82(and updateuv.lockaccordingly).
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/uipath/src/uipath/_cli/_chat/_bridge.py | Adds optional X-UiPath-Internal-SyntheticUserId header for CAS socket.io handshake (chat). |
| packages/uipath/src/uipath/_cli/_chat/_voice_bridge.py | Adds optional X-UiPath-Internal-SyntheticUserId header for CAS socket.io handshake (voice). |
| packages/uipath/tests/cli/chat/test_bridge.py | Adds tests asserting the synthetic user id header is included/omitted appropriately for chat bridge. |
| packages/uipath/tests/cli/chat/test_voice_bridge.py | Adds tests asserting the synthetic user id header is included/omitted appropriately for voice bridge. |
| packages/uipath/pyproject.toml | Bumps package version to 2.10.82. |
| packages/uipath/uv.lock | Updates lockfile entry for the local uipath package version. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "X-UiPath-ConversationId": context.conversation_id, | ||
| } |
There was a problem hiding this comment.
Good catch — fixed in 948cfa3. Dropped the f"{...}" wrapper so the or os.environ.get(...) fallback works (matches the voice bridge), and added a regression test for the env fallback when tenant_id/org_id are None.
f"{context.tenant_id}" yields the truthy string "None" when tenant_id
is None, so the `or os.environ.get(...)` env fallback was dead code and
the handshake sent a literal "None" id. Use the bare value like the voice
bridge already does, and add a regression test for the env fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
🚨 Heads up:
|
maxduu
left a comment
There was a problem hiding this comment.
Just a thread here regarding naming: https://github.com/UiPath/AgentInterfaces/pull/1022/changes#r3407200835



TL;DR
The conversational chat/voice bridge forwards the conversation owner id (
context.synthetic_user_id) as theX-UiPath-Internal-SyntheticUserIdheader on the CAS WebSocket handshake, so CAS can validate Robot connections for RunAsMe=false conversations.Solution
_cli/_chat/_bridge.py(get_chat_bridge) and_cli/_chat/_voice_bridge.py(get_voice_bridge): add the header whencontext.synthetic_user_idis set. Usesgetattr(context, "synthetic_user_id", None), so it's a no-op when absent (backward compatible).tests/cli/chat/test_bridge.py+test_voice_bridge.py(header present when set, omitted when absent).Depends on
uipath-runtimeexposingcontext.synthetic_user_id(mapped fromfpsProperties.conversationalService.syntheticUserId). Consumed by AgentInterfaces CAS, which validates the presented id againstconversation.user_idon the handshake.Notes
wait_timeoutpast its 1s default — CAS's socket-auth middleware does network I/O (JWKS / OIDC discovery) and can exceed 1s, so the client gave up before CAS granted (One or more namespaces failed to connect). Kept wait_timeout at default 1s for this PR. Worth considering extending if timeouts show in alpha on merge.