Skip to content

Commit bdc7d3a

Browse files
refactor: uniform headers into chat/http_client module
Move all shared HTTP concerns (headers, header capture, retryers) into a new chat/http_client subpackage. Introduce build_uipath_headers() as the single entry point for building UiPath LLM Gateway headers across OpenAI, Vertex, and Bedrock providers. Context headers (job_key, folder_key, trace_id) now read directly from env vars like process_key. Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 09b0286 commit bdc7d3a

File tree

14 files changed

+113
-125
lines changed

14 files changed

+113
-125
lines changed

src/uipath_langchain/_utils/_request_mixin.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import os
55
import time
66
from typing import Any, AsyncIterator, Dict, Iterator, Mapping
7-
from urllib.parse import quote
87

98
import httpx
109
import openai
@@ -34,7 +33,7 @@
3433
get_uipath_token_header,
3534
)
3635
from uipath_langchain._utils._sleep_policy import before_sleep_log
37-
from uipath_langchain.chat._headers import build_uipath_context_headers
36+
from uipath_langchain.chat.http_client import build_uipath_headers
3837
from uipath_langchain.runtime.errors import (
3938
LangGraphErrorCode,
4039
LangGraphRuntimeError,
@@ -80,7 +79,6 @@ class UiPathRequestMixin(BaseModel):
8079

8180
default_headers: Mapping[str, str] | None = {
8281
"X-UiPath-Streaming-Enabled": "false",
83-
"X-UiPath-ProcessKey": quote(os.getenv("UIPATH_PROCESS_KEY", ""), safe=""),
8482
}
8583
model_name: str | None = Field(
8684
default_factory=lambda: os.getenv(
@@ -756,23 +754,24 @@ def auth_headers(self) -> dict[str, str]:
756754
if not self._auth_headers:
757755
self._auth_headers = {
758756
**self.default_headers, # type: ignore
759-
"Authorization": f"Bearer {self.access_token}",
760-
"X-UiPath-LlmGateway-TimeoutSeconds": str(self.default_request_timeout),
761757
}
762-
if self.agenthub_config:
763-
self._auth_headers["X-UiPath-AgentHub-Config"] = self.agenthub_config
764-
if self.byo_connection_id:
765-
self._auth_headers["X-UiPath-LlmGateway-ByoIsConnectionId"] = (
766-
self.byo_connection_id
758+
self._auth_headers.update(
759+
build_uipath_headers(
760+
self.access_token,
761+
agenthub_config=self.agenthub_config,
762+
byo_connection_id=self.byo_connection_id,
767763
)
764+
)
765+
self._auth_headers["X-UiPath-LlmGateway-TimeoutSeconds"] = str(
766+
self.default_request_timeout
767+
)
768768
if self.is_normalized and self.model_name:
769769
self._auth_headers["X-UiPath-LlmGateway-NormalizedApi-ModelName"] = (
770770
self.model_name
771771
)
772772
if self.include_account_id:
773773
self._auth_headers["x-uipath-internal-accountid"] = self.org_id
774774
self._auth_headers["x-uipath-internal-tenantid"] = self.tenant_id
775-
self._auth_headers.update(build_uipath_context_headers())
776775
return self._auth_headers
777776

778777
def _get_llm_string(self, stop: list[str] | None = None, **kwargs: Any) -> str:

src/uipath_langchain/chat/_headers.py

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/uipath_langchain/chat/bedrock.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22
import os
33
from collections.abc import Iterator
44
from typing import Any, Optional
5-
from urllib.parse import quote
65

76
from langchain_core.callbacks import CallbackManagerForLLMRun
87
from langchain_core.messages import BaseMessage
98
from langchain_core.outputs import ChatGenerationChunk, ChatResult
109
from tenacity import AsyncRetrying, Retrying
1110
from uipath.platform.common import EndpointManager, resource_override
1211

13-
from ._headers import build_uipath_context_headers
14-
from .header_capture import HeaderCapture
15-
from .retryers.bedrock import AsyncBedrockRetryer, BedrockRetryer
12+
from .http_client import build_uipath_headers
13+
from .http_client.header_capture import HeaderCapture
14+
from .http_client.retryers.bedrock import AsyncBedrockRetryer, BedrockRetryer
1615
from .supported_models import BedrockModels
1716
from .types import APIFlavor, LLMProvider
1817

@@ -130,20 +129,13 @@ def _modify_request(self, request, **kwargs):
130129
streaming = "true" if request.url.endswith("-stream") else "false"
131130
request.url = self._build_base_url()
132131

133-
headers = {
134-
"Authorization": f"Bearer {self.token}",
135-
"X-UiPath-LlmGateway-ApiFlavor": self.api_flavor,
136-
"X-UiPath-Streaming-Enabled": streaming,
137-
}
138-
139-
if self.agenthub_config:
140-
headers["X-UiPath-AgentHub-Config"] = self.agenthub_config
141-
if self.byo_connection_id:
142-
headers["X-UiPath-LlmGateway-ByoIsConnectionId"] = self.byo_connection_id
143-
if process_key := os.getenv("UIPATH_PROCESS_KEY"):
144-
headers["X-UiPath-ProcessKey"] = quote(process_key, safe="")
145-
146-
headers.update(build_uipath_context_headers())
132+
headers = build_uipath_headers(
133+
self.token,
134+
agenthub_config=self.agenthub_config,
135+
byo_connection_id=self.byo_connection_id,
136+
)
137+
headers["X-UiPath-LlmGateway-ApiFlavor"] = self.api_flavor
138+
headers["X-UiPath-Streaming-Enabled"] = streaming
147139

148140
request.headers.update(headers)
149141

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .headers import build_uipath_headers
2+
3+
__all__ = ["build_uipath_headers"]
File renamed without changes.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Shared UiPath HTTP headers for LLM Gateway requests."""
2+
3+
import os
4+
from urllib.parse import quote
5+
6+
7+
def build_uipath_headers(
8+
token: str,
9+
*,
10+
agenthub_config: str | None = None,
11+
byo_connection_id: str | None = None,
12+
) -> dict[str, str]:
13+
"""Build common UiPath headers for LLM Gateway requests.
14+
15+
Reads process_key, job_key, folder_key, and trace_id directly from
16+
environment variables when set.
17+
"""
18+
headers: dict[str, str] = {
19+
"Authorization": f"Bearer {token}",
20+
}
21+
if agenthub_config:
22+
headers["X-UiPath-AgentHub-Config"] = agenthub_config
23+
if byo_connection_id:
24+
headers["X-UiPath-LlmGateway-ByoIsConnectionId"] = byo_connection_id
25+
if process_key := os.getenv("UIPATH_PROCESS_KEY"):
26+
headers["X-UiPath-ProcessKey"] = quote(process_key, safe="")
27+
if job_key := os.getenv("UIPATH_JOB_KEY"):
28+
headers["x-uipath-jobkey"] = job_key
29+
if folder_key := os.getenv("UIPATH_FOLDER_KEY"):
30+
headers["x-uipath-folderkey"] = folder_key
31+
if trace_id := os.getenv("UIPATH_TRACE_ID"):
32+
headers["x-uipath-traceid"] = trace_id
33+
return headers
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/uipath_langchain/chat/openai.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import logging
22
import os
33
from typing import Optional
4-
from urllib.parse import quote
54

65
import httpx
76
from langchain_openai import AzureChatOpenAI
@@ -12,7 +11,7 @@
1211
resource_override,
1312
)
1413

15-
from ._headers import build_uipath_context_headers
14+
from .http_client import build_uipath_headers
1615
from .supported_models import OpenAIModels
1716
from .types import APIFlavor, LLMProvider
1817

@@ -152,21 +151,12 @@ def __init__(
152151
self._api_flavor = api_flavor
153152

154153
def _build_headers(self, token: str) -> dict[str, str]:
155-
headers = {
156-
"X-UiPath-LlmGateway-ApiFlavor": "auto",
157-
"Authorization": f"Bearer {token}",
158-
}
159-
160-
if self._agenthub_config:
161-
headers["X-UiPath-AgentHub-Config"] = self._agenthub_config
162-
if self._byo_connection_id:
163-
headers["X-UiPath-LlmGateway-ByoIsConnectionId"] = self._byo_connection_id
164-
if process_key := os.getenv("UIPATH_PROCESS_KEY"):
165-
headers["X-UiPath-ProcessKey"] = quote(process_key, safe="")
166-
167-
headers.update(build_uipath_context_headers())
168-
169-
# Allow extra_headers to override defaults
154+
headers = build_uipath_headers(
155+
token,
156+
agenthub_config=self._agenthub_config,
157+
byo_connection_id=self._byo_connection_id,
158+
)
159+
headers["X-UiPath-LlmGateway-ApiFlavor"] = "auto"
170160
headers.update(self._extra_headers)
171161
return headers
172162

0 commit comments

Comments
 (0)