{"id":47682171,"url":"https://github.com/uipath/uipath-llm-client-python","last_synced_at":"2026-04-21T00:01:29.140Z","repository":{"id":346015893,"uuid":"1139001888","full_name":"UiPath/uipath-llm-client-python","owner":"UiPath","description":"UiPath HTTP LLM Client and UiPath Framework-specific clients (LangChain, LlamaIndex, etc.) for accessing Large Language Model (LLM) APIs from multiple model providers (OpenAI, Anthropic, Google) and cloud LLM platforms (Azure, Bedrock, VertexAI). Model access is handled via UiPath credentials, either through LLMGateway or AgentHub.","archived":false,"fork":false,"pushed_at":"2026-04-17T13:36:34.000Z","size":1055,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-17T13:36:47.129Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/UiPath.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-21T11:48:29.000Z","updated_at":"2026-04-17T13:24:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"89c3ac26-124d-487b-a8ae-539a9f473fb7","html_url":"https://github.com/UiPath/uipath-llm-client-python","commit_stats":null,"previous_names":["uipath/uipath-llm-client-python"],"tags_count":67,"template":false,"template_full_name":null,"purl":"pkg:github/UiPath/uipath-llm-client-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fuipath-llm-client-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fuipath-llm-client-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fuipath-llm-client-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fuipath-llm-client-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/UiPath","download_url":"https://codeload.github.com/UiPath/uipath-llm-client-python/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fuipath-llm-client-python/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32071013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T21:26:33.338Z","status":"ssl_error","status_checked_at":"2026-04-20T21:26:22.081Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-02T14:03:51.866Z","updated_at":"2026-04-21T00:01:29.133Z","avatar_url":"https://github.com/UiPath.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UiPath LLM Client\n\nA Python client for interacting with UiPath's LLM services. This package provides both a low-level HTTP client and a LangChain integration for accessing LLMs through UiPath's infrastructure.\n\n## Architecture Overview\n\nThis repository is organized as a monorepo with the following packages:\n\n- **`uipath_llm_client`** (root): Core HTTP client with authentication, retry logic, and request handling\n- **`uipath_langchain_client`** (packages/): LangChain-compatible chat models and embeddings\n\n### Supported Backends\n\nThe client supports two UiPath backends:\n\n| Backend | Description | Default |\n|---------|-------------|---------|\n| **AgentHub** | UiPath's AgentHub infrastructure with automatic CLI-based authentication | Yes |\n| **LLMGateway** | UiPath's LLM Gateway with S2S authentication | No |\n\n### Supported Providers\n\n| Provider | Chat Models | Embeddings | Vendor Type |\n|----------|-------------|------------|-------------|\n| OpenAI/Azure | GPT-4o, GPT-4, etc. | text-embedding-3-large/small | `openai` |\n| Google | Gemini 2.5, Gemini 2.0, etc. | text-embedding-004 | `vertexai` |\n| Anthropic | Claude Sonnet 4.5, etc. | - | `awsbedrock`, `vertexai` |\n| AWS Bedrock | Claude, Titan, etc. | Titan Embeddings, etc. | `awsbedrock` |\n| Fireworks AI | Various open-source models | Various | `openai` |\n| Azure AI | Various Azure AI models | Various | `azure` |\n\n## Installation\n\n### Using `pip`\n\n```bash\n# Base installation (core client only)\npip install uipath-llm-client\n\n# With optional provider extras for passthrough mode\npip install \"uipath-llm-client[openai]\"      # OpenAI/Azure OpenAI models\npip install \"uipath-llm-client[google]\"      # Google Gemini models\npip install \"uipath-llm-client[anthropic]\"   # Anthropic Claude models\npip install \"uipath-llm-client[all]\"         # All of the above\n```\n\nFor LangChain support, use the separate package: `pip install uipath-langchain-client`.\n\n### Using `uv`\n\n1. Add the custom index to your `pyproject.toml`:\n\n```toml\n[[tool.uv.index]]\nname = \"uipath\"\nurl = \"https://uipath.pkgs.visualstudio.com/_packaging/ml-packages/pypi/simple/\"\npublish-url = \"https://uipath.pkgs.visualstudio.com/_packaging/ml-packages/pypi/upload/\"\n```\n\n2. Install the packages:\n\n```bash\n# Core client\nuv add uipath-llm-client\n\n# LangChain integration with all providers\nuv add \"uipath-langchain-client[all]\"\n```\n\n## Configuration\n\n### Platform Backend (AgentHub / Orchestrator)\n\nThe Platform backend uses the UiPath CLI for authentication. Both `\"agenthub\"` (default) and `\"orchestrator\"` share the same settings — the `EndpointManager` selects the correct URL paths automatically.\n\n```bash\n# Authenticate via CLI (populates .uipath/.auth.json)\nuv run uipath auth login\n\n# Or set environment variables directly\nexport UIPATH_URL=\"https://cloud.uipath.com/org/tenant\"\nexport UIPATH_ORGANIZATION_ID=\"your-org-id\"\nexport UIPATH_TENANT_ID=\"your-tenant-id\"\nexport UIPATH_ACCESS_TOKEN=\"your-access-token\"\n\n# Optional: select backend (default: \"agenthub\")\nexport UIPATH_LLM_SERVICE=\"agenthub\"   # or \"orchestrator\"\n```\n\n### LLMGateway Backend\n\nTo use the LLMGateway backend, set the following environment variables:\n\n```bash\n# Select the backend\nexport UIPATH_LLM_SERVICE=\"llmgateway\"\n\n# Required configuration\nexport LLMGW_URL=\"https://your-llmgw-url.com\"\nexport LLMGW_SEMANTIC_ORG_ID=\"your-org-id\"\nexport LLMGW_SEMANTIC_TENANT_ID=\"your-tenant-id\"\nexport LLMGW_REQUESTING_PRODUCT=\"your-product-name\"\nexport LLMGW_REQUESTING_FEATURE=\"your-feature-name\"\n\n# Authentication (choose one)\nexport LLMGW_ACCESS_TOKEN=\"your-access-token\"\n# OR for S2S authentication:\nexport LLMGW_CLIENT_ID=\"your-client-id\"\nexport LLMGW_CLIENT_SECRET=\"your-client-secret\"\n\n# Optional tracking\nexport LLMGW_SEMANTIC_USER_ID=\"your-user-id\"\n```\n\n## Settings Reference\n\n### PlatformSettings\n\nConfiguration settings for UiPath Platform client requests. `PlatformSettings` is a unified settings class that serves both **AgentHub** and **Orchestrator** backends — the `EndpointManager` transparently selects the correct endpoints based on service availability.\n\nYou choose between them via the `UIPATH_LLM_SERVICE` environment variable (or the `backend` parameter in `get_default_client_settings()`):\n\n| Value | Description |\n|-------|-------------|\n| `\"agenthub\"` (default) | Routes requests through AgentHub endpoints |\n| `\"orchestrator\"` | Routes requests through Orchestrator endpoints |\n\nBoth values create a `PlatformSettings` instance — the difference is in how `EndpointManager` resolves the URL paths.\n\n```python\nfrom uipath.llm_client.settings import get_default_client_settings, PlatformSettings\n\n# Option 1: Factory (reads UIPATH_LLM_SERVICE, defaults to \"agenthub\")\nsettings = get_default_client_settings()\n\n# Option 2: Explicit backend\nsettings = get_default_client_settings(backend=\"agenthub\")\nsettings = get_default_client_settings(backend=\"orchestrator\")\n\n# Option 3: Direct instantiation\nsettings = PlatformSettings()\n```\n\n#### AgentHub\n\nAgentHub is the default backend. It routes LLM requests through UiPath's AgentHub service, which provides model discovery, routing, and tracing capabilities.\n\n```bash\n# Select the backend (default, can be omitted)\nexport UIPATH_LLM_SERVICE=\"agenthub\"\n\n# Core settings (populated automatically by `uipath auth login`)\nexport UIPATH_URL=\"https://cloud.uipath.com/org/tenant\"\nexport UIPATH_ORGANIZATION_ID=\"your-org-id\"\nexport UIPATH_TENANT_ID=\"your-tenant-id\"\nexport UIPATH_ACCESS_TOKEN=\"your-access-token\"\n\n# Optional: AgentHub configuration for discovery (default: \"agentsruntime\")\nexport UIPATH_AGENTHUB_CONFIG=\"agentsruntime\"\n\n# Optional: tracing\nexport UIPATH_PROCESS_KEY=\"your-process-key\"\nexport UIPATH_JOB_KEY=\"your-job-key\"\n```\n\n#### Orchestrator\n\nOrchestrator uses the same `PlatformSettings` and authentication as AgentHub, but routes requests through Orchestrator endpoints instead.\n\n```bash\n# Select the backend\nexport UIPATH_LLM_SERVICE=\"orchestrator\"\n\n# Core settings (same as AgentHub)\nexport UIPATH_URL=\"https://cloud.uipath.com/org/tenant\"\nexport UIPATH_ORGANIZATION_ID=\"your-org-id\"\nexport UIPATH_TENANT_ID=\"your-tenant-id\"\nexport UIPATH_ACCESS_TOKEN=\"your-access-token\"\n\n# Optional: tracing\nexport UIPATH_PROCESS_KEY=\"your-process-key\"\nexport UIPATH_JOB_KEY=\"your-job-key\"\n```\n\n#### PlatformSettings Attributes\n\n| Attribute | Environment Variable | Type | Default | Description |\n|-----------|---------------------|------|---------|-------------|\n| `access_token` | `UIPATH_ACCESS_TOKEN` | `SecretStr \\| None` | `None` | Access token for authentication (populated by `uipath auth login`) |\n| `base_url` | `UIPATH_URL` | `str \\| None` | `None` | Base URL of the UiPath Platform API |\n| `tenant_id` | `UIPATH_TENANT_ID` | `str \\| None` | `None` | Tenant ID for request routing |\n| `organization_id` | `UIPATH_ORGANIZATION_ID` | `str \\| None` | `None` | Organization ID for request routing |\n| `agenthub_config` | `UIPATH_AGENTHUB_CONFIG` | `str \\| None` | `\"agentsruntime\"` | AgentHub configuration for discovery |\n| `process_key` | `UIPATH_PROCESS_KEY` | `str \\| None` | `None` | Process key for tracing |\n| `job_key` | `UIPATH_JOB_KEY` | `str \\| None` | `None` | Job key for tracing |\n\n**Authentication behavior:**\n- All four core fields (`access_token`, `base_url`, `tenant_id`, `organization_id`) are required\n- Run `uipath auth login` to populate them automatically via the UiPath CLI\n- The access token is validated against the local `.uipath/.auth.json` file\n- Token refresh is handled automatically using the refresh token from the auth file\n\n### LLMGatewaySettings\n\nConfiguration settings for LLM Gateway client requests. These settings control routing, authentication, and tracking for requests to LLM Gateway.\n\n```python\nfrom uipath.llm_client.settings import LLMGatewaySettings\n\nsettings = LLMGatewaySettings(\n    base_url=\"https://your-llmgw-url.com\",\n    org_id=\"your-org-id\",\n    tenant_id=\"your-tenant-id\",\n    requesting_product=\"your-product\",\n    requesting_feature=\"your-feature\",\n    client_id=\"your-client-id\",           # For S2S auth\n    client_secret=\"your-client-secret\",   # For S2S auth\n)\n```\n\n| Attribute | Environment Variable | Type | Required | Description |\n|-----------|---------------------|------|----------|-------------|\n| `base_url` | `LLMGW_URL` | `str` | Yes | Base URL of the LLM Gateway |\n| `org_id` | `LLMGW_SEMANTIC_ORG_ID` | `str` | Yes | Organization ID for request routing |\n| `tenant_id` | `LLMGW_SEMANTIC_TENANT_ID` | `str` | Yes | Tenant ID for request routing |\n| `requesting_product` | `LLMGW_REQUESTING_PRODUCT` | `str` | Yes | Product name making the request (for tracking) |\n| `requesting_feature` | `LLMGW_REQUESTING_FEATURE` | `str` | Yes | Feature name making the request (for tracking) |\n| `access_token` | `LLMGW_ACCESS_TOKEN` | `SecretStr \\| None` | Conditional | Access token for authentication |\n| `client_id` | `LLMGW_CLIENT_ID` | `SecretStr \\| None` | Conditional | Client ID for S2S authentication |\n| `client_secret` | `LLMGW_CLIENT_SECRET` | `SecretStr \\| None` | Conditional | Client secret for S2S authentication |\n| `user_id` | `LLMGW_SEMANTIC_USER_ID` | `str \\| None` | No | User ID for tracking and billing |\n| `action_id` | `LLMGW_ACTION_ID` | `str \\| None` | No | Action ID for tracking |\n| `operation_code` | `LLMGW_OPERATION_CODE` | `str \\| None` | No | Operation code to identify BYO models |\n| `additional_headers` | `LLMGW_ADDITIONAL_HEADERS` | `Mapping[str, str]` | No | Additional custom headers to include in requests |\n\n**Authentication behavior:**\n- Either `access_token` OR both `client_id` and `client_secret` must be provided\n- S2S authentication uses `client_id`/`client_secret` to obtain tokens automatically\n\n## Usage Examples\n\n### Quick Start with Direct Client Classes\n\nThe simplest way to get started - settings are automatically loaded from environment variables:\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\n\n# No settings needed - uses defaults from environment (AgentHub backend)\nchat = UiPathAzureChatOpenAI(model=\"gpt-4o-2024-11-20\")\nresponse = chat.invoke(\"What is the capital of France?\")\nprint(response.content)\n```\n\n### Using Different Providers\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\nfrom uipath_langchain_client.clients.google.chat_models import UiPathChatGoogleGenerativeAI\nfrom uipath_langchain_client.clients.anthropic.chat_models import UiPathChatAnthropic\nfrom uipath_langchain_client.clients.openai.embeddings import UiPathAzureOpenAIEmbeddings\n\n# OpenAI/Azure models\nopenai_chat = UiPathAzureChatOpenAI(model=\"gpt-4o-2024-11-20\")\nresponse = openai_chat.invoke(\"Hello!\")\nprint(response.content)\n\n# Google Gemini models\ngemini_chat = UiPathChatGoogleGenerativeAI(model=\"gemini-2.5-flash\")\nresponse = gemini_chat.invoke(\"Hello!\")\nprint(response.content)\n\n# Anthropic Claude models (via AWS Bedrock)\nclaude_chat = UiPathChatAnthropic(model=\"anthropic.claude-sonnet-4-5-20250929-v1:0\", vendor_type=\"awsbedrock\")\nresponse = claude_chat.invoke(\"Hello!\")\nprint(response.content)\n\n# Embeddings\nembeddings = UiPathAzureOpenAIEmbeddings(model=\"text-embedding-3-large\")\nvectors = embeddings.embed_documents([\"Hello world\", \"How are you?\"])\nprint(f\"Generated {len(vectors)} embeddings of dimension {len(vectors[0])}\")\n```\n\n### Using Factory Functions (Auto-Detect Vendor)\n\nFactory functions automatically detect the model vendor but require settings to be passed:\n\n```python\nfrom uipath_langchain_client import get_chat_model, get_embedding_model\nfrom uipath.llm_client.settings import get_default_client_settings\n\nsettings = get_default_client_settings()\n\n# Create a chat model - vendor is auto-detected from model name\nchat_model = get_chat_model(model_name=\"gpt-4o-2024-11-20\", client_settings=settings)\nresponse = chat_model.invoke(\"What is the capital of France?\")\nprint(response.content)\n\n# Create an embeddings model\nembeddings_model = get_embedding_model(model_name=\"text-embedding-3-large\", client_settings=settings)\nvectors = embeddings_model.embed_documents([\"Hello world\", \"How are you?\"])\n```\n\n### Using the Normalized API (Provider-Agnostic)\n\nThe normalized API provides a consistent interface across all LLM providers:\n\n```python\nfrom uipath_langchain_client import get_chat_model\nfrom uipath.llm_client.settings import get_default_client_settings\n\nsettings = get_default_client_settings()\n\n# Use normalized API for provider-agnostic calls\nchat_model = get_chat_model(\n    model_name=\"gpt-4o-2024-11-20\",\n    client_settings=settings,\n    client_type=\"normalized\",\n)\n\n# Works the same way regardless of the underlying provider\nresponse = chat_model.invoke(\"Explain quantum computing in simple terms.\")\nprint(response.content)\n```\n\n### Streaming Responses\n\nAll chat models support streaming for real-time output:\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\n\nchat_model = UiPathAzureChatOpenAI(model=\"gpt-4o-2024-11-20\")\n\nfor chunk in chat_model.stream(\"Write a short poem about coding.\"):\n    print(chunk.content, end=\"\", flush=True)\nprint()\n```\n\n### Async Operations\n\nFor async/await support:\n\n```python\nimport asyncio\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\n\nasync def main():\n    chat_model = UiPathAzureChatOpenAI(model=\"gpt-4o-2024-11-20\")\n    \n    # Async invoke\n    response = await chat_model.ainvoke(\"What is 2 + 2?\")\n    print(response.content)\n    \n    # Async streaming\n    async for chunk in chat_model.astream(\"Tell me a joke.\"):\n        print(chunk.content, end=\"\", flush=True)\n    print()\n\nasyncio.run(main())\n```\n\n### Tool/Function Calling\n\nUse tools with LangChain's standard interface:\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\nfrom langchain_core.tools import tool\n\n@tool\ndef get_weather(city: str) -\u003e str:\n    \"\"\"Get the current weather for a city.\"\"\"\n    return f\"The weather in {city} is sunny and 72°F.\"\n\n@tool\ndef calculate(expression: str) -\u003e str:\n    \"\"\"Evaluate a mathematical expression.\"\"\"\n    return str(eval(expression))\n\nchat_model = UiPathAzureChatOpenAI(model=\"gpt-4o-2024-11-20\")\n\n# Bind tools to the model\nmodel_with_tools = chat_model.bind_tools([get_weather, calculate])\n\n# The model can now use tools\nresponse = model_with_tools.invoke(\"What's the weather in Paris?\")\nprint(response.tool_calls)\n```\n\n### Using with LangChain Agents\n\nIntegrate with LangChain's agent framework:\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\nfrom langchain_core.tools import tool\nfrom langgraph.prebuilt import create_react_agent\n\n@tool\ndef search(query: str) -\u003e str:\n    \"\"\"Search for information.\"\"\"\n    return f\"Search results for: {query}\"\n\nchat_model = UiPathAzureChatOpenAI(model=\"gpt-4o-2024-11-20\")\nagent = create_react_agent(chat_model, [search])\n\n# Run the agent\nresult = agent.invoke({\"messages\": [(\"user\", \"Search for Python tutorials\")]})\nprint(result[\"messages\"][-1].content)\n```\n\n### Native SDK Wrappers (Without LangChain)\n\nThe core `uipath_llm_client` package provides thin wrappers around native vendor SDKs. These are drop-in replacements that route requests through UiPath's infrastructure while preserving the original SDK's interface:\n\n```python\nfrom uipath.llm_client.clients.openai import UiPathOpenAI, UiPathAzureOpenAI\n\n# Drop-in replacement for openai.OpenAI — routes through UiPath\nclient = UiPathOpenAI(model_name=\"gpt-4o-2024-11-20\")\nresponse = client.chat.completions.create(\n    model=\"gpt-4o-2024-11-20\",\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}],\n)\nprint(response.choices[0].message.content)\n\n# Azure OpenAI variant\nazure_client = UiPathAzureOpenAI(model_name=\"gpt-4o-2024-11-20\")\n```\n\n```python\nfrom uipath.llm_client.clients.anthropic import UiPathAnthropic\n\n# Drop-in replacement for anthropic.Anthropic\nclient = UiPathAnthropic(model_name=\"anthropic.claude-sonnet-4-5-20250929-v1:0\")\nresponse = client.messages.create(\n    model=\"anthropic.claude-sonnet-4-5-20250929-v1:0\",\n    max_tokens=1024,\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}],\n)\nprint(response.content[0].text)\n```\n\n```python\nfrom uipath.llm_client.clients.google import UiPathGoogle\n\n# Drop-in replacement for google.genai.Client\nclient = UiPathGoogle(model_name=\"gemini-2.5-flash\")\nresponse = client.models.generate_content(\n    model=\"gemini-2.5-flash\",\n    contents=\"Hello!\",\n)\nprint(response.text)\n```\n\nAll native SDK wrappers are available in sync and async variants:\n\n| Class | SDK | Description |\n|-------|-----|-------------|\n| `UiPathOpenAI` / `UiPathAsyncOpenAI` | `openai.OpenAI` | OpenAI models (BYO) |\n| `UiPathAzureOpenAI` / `UiPathAsyncAzureOpenAI` | `openai.AzureOpenAI` | Azure OpenAI models |\n| `UiPathAnthropic` / `UiPathAsyncAnthropic` | `anthropic.Anthropic` | Anthropic models |\n| `UiPathAnthropicBedrock` / `UiPathAsyncAnthropicBedrock` | `anthropic.AnthropicBedrock` | Anthropic via AWS Bedrock |\n| `UiPathAnthropicVertex` / `UiPathAsyncAnthropicVertex` | `anthropic.AnthropicVertex` | Anthropic via Vertex AI |\n| `UiPathAnthropicFoundry` / `UiPathAsyncAnthropicFoundry` | `anthropic.AnthropicFoundry` | Anthropic via Azure Foundry |\n| `UiPathGoogle` | `google.genai.Client` | Google Gemini models |\n\n### Low-Level HTTP Client\n\nFor completely custom HTTP requests, use the low-level HTTPX client directly:\n\n```python\nfrom uipath.llm_client import UiPathHttpxClient\nfrom uipath.llm_client.settings import UiPathAPIConfig, get_default_client_settings\n\nsettings = get_default_client_settings()\n\n# Create a low-level HTTP client with UiPath auth and routing\nclient = UiPathHttpxClient(\n    base_url=settings.build_base_url(model_name=\"gpt-4o-2024-11-20\"),\n    auth=settings.build_auth_pipeline(),\n    headers=settings.build_auth_headers(model_name=\"gpt-4o-2024-11-20\"),\n    model_name=\"gpt-4o-2024-11-20\",\n    api_config=UiPathAPIConfig(\n        api_type=\"completions\",\n        client_type=\"passthrough\",\n        vendor_type=\"openai\",\n        api_flavor=\"chat-completions\",\n    ),\n    max_retries=2,\n)\n\n# Make a raw HTTP request\nresponse = client.post(\n    \"/chat/completions\",\n    json={\n        \"model\": \"gpt-4o-2024-11-20\",\n        \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}],\n        \"max_tokens\": 100,\n    },\n)\nresponse.raise_for_status()\nprint(response.json())\n```\n\n### Custom Configuration\n\nPass custom settings when you need more control:\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\nfrom uipath.llm_client.settings import PlatformSettings\nfrom uipath.llm_client.utils.retry import RetryConfig\n\n# Custom settings for Platform (AgentHub/Orchestrator)\nsettings = PlatformSettings()\n\n# With retry configuration\nretry_config: RetryConfig = {\n    \"initial_delay\": 2.0,\n    \"max_delay\": 60.0,\n    \"exp_base\": 2.0,\n    \"jitter\": 1.0,\n}\n\nchat_model = UiPathAzureChatOpenAI(\n    model=\"gpt-4o-2024-11-20\",\n    client_settings=settings,\n    max_retries=3,\n    retry_config=retry_config,\n)\n```\n\n### Switching Between Backends\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\nfrom uipath.llm_client.settings import get_default_client_settings\n\n# Explicitly specify the backend\nagenthub_settings = get_default_client_settings(backend=\"agenthub\")\nllmgw_settings = get_default_client_settings(backend=\"llmgateway\")\n\nchat = UiPathAzureChatOpenAI(model=\"gpt-4o-2024-11-20\", client_settings=llmgw_settings)\n\n# Or use environment variable (no code changes needed)\n# export UIPATH_LLM_SERVICE=\"llmgateway\"\n```\n\n### Using LLMGatewaySettings Directly\n\nYou can instantiate `LLMGatewaySettings` directly for full control over configuration:\n\n**With Direct Client Classes:**\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\nfrom uipath_langchain_client.clients.google.chat_models import UiPathChatGoogleGenerativeAI\nfrom uipath_langchain_client.clients.openai.embeddings import UiPathAzureOpenAIEmbeddings\nfrom uipath.llm_client.settings import LLMGatewaySettings\n\n# Create LLMGatewaySettings with explicit configuration\nsettings = LLMGatewaySettings(\n    base_url=\"https://your-llmgw-url.com\",\n    org_id=\"your-org-id\",\n    tenant_id=\"your-tenant-id\",\n    requesting_product=\"my-product\",\n    requesting_feature=\"my-feature\",\n    client_id=\"your-client-id\",\n    client_secret=\"your-client-secret\",\n    user_id=\"optional-user-id\",  # Optional: for tracking\n)\n\n# Use with OpenAI/Azure chat model\nopenai_chat = UiPathAzureChatOpenAI(\n    model=\"gpt-4o-2024-11-20\",\n    settings=settings,\n)\nresponse = openai_chat.invoke(\"Hello!\")\nprint(response.content)\n\n# Use with Google Gemini\ngemini_chat = UiPathChatGoogleGenerativeAI(\n    model=\"gemini-2.5-flash\",\n    settings=settings,\n)\nresponse = gemini_chat.invoke(\"Hello!\")\nprint(response.content)\n\n# Use with embeddings\nembeddings = UiPathAzureOpenAIEmbeddings(\n    model=\"text-embedding-3-large\",\n    settings=settings,\n)\nvectors = embeddings.embed_documents([\"Hello world\"])\n```\n\n**With Factory Methods:**\n\n```python\nfrom uipath_langchain_client import get_chat_model, get_embedding_model\nfrom uipath.llm_client.settings import LLMGatewaySettings\n\n# Create LLMGatewaySettings\nsettings = LLMGatewaySettings(\n    base_url=\"https://your-llmgw-url.com\",\n    org_id=\"your-org-id\",\n    tenant_id=\"your-tenant-id\",\n    requesting_product=\"my-product\",\n    requesting_feature=\"my-feature\",\n    client_id=\"your-client-id\",\n    client_secret=\"your-client-secret\",\n)\n\n# Factory auto-detects vendor from model name\nchat_model = get_chat_model(\n    model_name=\"gpt-4o-2024-11-20\",\n    client_settings=settings,\n)\nresponse = chat_model.invoke(\"What is the capital of France?\")\nprint(response.content)\n\n# Use normalized API for provider-agnostic interface\nnormalized_chat = get_chat_model(\n    model_name=\"gemini-2.5-flash\",\n    client_settings=settings,\n    client_type=\"normalized\",\n)\nresponse = normalized_chat.invoke(\"Explain quantum computing.\")\nprint(response.content)\n\n# Embeddings with factory\nembeddings = get_embedding_model(\n    model_name=\"text-embedding-3-large\",\n    client_settings=settings,\n)\nvectors = embeddings.embed_documents([\"Hello\", \"World\"])\n```\n\n### Bring Your Own (BYO) Model Connections\n\nIf you have enrolled your own model deployment into UiPath's LLMGateway, you can use it by providing your BYO connection ID. This allows you to route requests through LLMGateway to your custom-enrolled models.\n\n```python\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\n\n# Use your BYO connection ID from LLMGateway enrollment\nchat = UiPathAzureChatOpenAI(\n    model=\"your-custom-model-name\",\n    byo_connection_id=\"your-byo-connection-id\",  # UUID from LLMGateway enrollment\n)\n\nresponse = chat.invoke(\"Hello from my custom model!\")\nprint(response.content)\n```\n\nThis works with any client class:\n\n```python\nfrom uipath_langchain_client.clients.google.chat_models import UiPathChatGoogleGenerativeAI\nfrom uipath_langchain_client.clients.openai.embeddings import UiPathAzureOpenAIEmbeddings\n\n# BYO chat model\nbyo_chat = UiPathChatGoogleGenerativeAI(\n    model=\"my-custom-gemini\",\n    byo_connection_id=\"f1d29b49-0c7b-4c01-8bc4-fc1b7d918a87\",\n)\n\n# BYO embeddings model\nbyo_embeddings = UiPathAzureOpenAIEmbeddings(\n    model=\"my-custom-embeddings\",\n    byo_connection_id=\"a2e38c51-1d8a-5e02-9cd5-ge2c8e029b98\",\n)\n```\n\n## Error Handling\n\nThe client provides a hierarchy of typed exceptions for handling API errors. All exceptions extend `UiPathAPIError` (which extends `httpx.HTTPStatusError`):\n\n```python\nfrom uipath.llm_client import (\n    UiPathAPIError,\n    UiPathAuthenticationError,\n    UiPathRateLimitError,\n    UiPathNotFoundError,\n)\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\n\nchat = UiPathAzureChatOpenAI(model=\"gpt-4o-2024-11-20\")\n\ntry:\n    response = chat.invoke(\"Hello!\")\nexcept UiPathRateLimitError as e:\n    print(f\"Rate limited. Retry after: {e.retry_after} seconds\")\nexcept UiPathAuthenticationError:\n    print(\"Authentication failed — check your credentials\")\nexcept UiPathAPIError as e:\n    print(f\"API error {e.status_code}: {e.message}\")\n```\n\n### Exception Reference\n\n| Exception | HTTP Status | Description |\n|-----------|-------------|-------------|\n| `UiPathAPIError` | Any | Base exception for all UiPath API errors |\n| `UiPathBadRequestError` | 400 | Invalid request parameters |\n| `UiPathAuthenticationError` | 401 | Invalid or expired credentials |\n| `UiPathPermissionDeniedError` | 403 | Insufficient permissions |\n| `UiPathNotFoundError` | 404 | Model or resource not found |\n| `UiPathConflictError` | 409 | Request conflicts with current state |\n| `UiPathRequestTooLargeError` | 413 | Request payload too large |\n| `UiPathUnprocessableEntityError` | 422 | Request is well-formed but semantically invalid |\n| `UiPathRateLimitError` | 429 | Rate limit exceeded (has `retry_after` property) |\n| `UiPathInternalServerError` | 500 | Server-side error |\n| `UiPathServiceUnavailableError` | 503 | Service temporarily unavailable |\n| `UiPathGatewayTimeoutError` | 504 | Gateway timeout |\n| `UiPathTooManyRequestsError` | 529 | Anthropic overload (too many requests) |\n\n## UiPathAPIConfig Reference\n\nThe `UiPathAPIConfig` class controls how requests are routed through UiPath's infrastructure:\n\n```python\nfrom uipath.llm_client.settings import UiPathAPIConfig\n\nconfig = UiPathAPIConfig(\n    api_type=\"completions\",\n    client_type=\"passthrough\",\n    vendor_type=\"openai\",\n    api_flavor=\"chat-completions\",\n    api_version=\"2025-03-01-preview\",\n)\n```\n\n| Field | Type | Default | Description |\n|-------|------|---------|-------------|\n| `api_type` | `\"completions\"` \\| `\"embeddings\"` \\| `None` | `None` | Type of API call |\n| `client_type` | `\"passthrough\"` \\| `\"normalized\"` \\| `None` | `None` | `\"passthrough\"` uses vendor-native APIs; `\"normalized\"` uses UiPath's unified API |\n| `vendor_type` | `str \\| None` | `None` | LLM vendor identifier: `\"openai\"`, `\"vertexai\"`, `\"awsbedrock\"`, `\"anthropic\"`, `\"azure\"` |\n| `api_flavor` | `str \\| None` | `None` | Vendor-specific API flavor (e.g., `\"chat-completions\"`, `\"responses\"`, `\"generate-content\"`, `\"converse\"`, `\"invoke\"`, `\"anthropic-claude\"`) |\n| `api_version` | `str \\| None` | `None` | Vendor-specific API version (e.g., `\"2025-03-01-preview\"`, `\"v1beta1\"`) |\n| `freeze_base_url` | `bool` | `False` | Prevents httpx from modifying the base URL (required for some vendor SDKs) |\n\n## Advanced Configuration\n\n### SSL Configuration\n\nThe client supports custom SSL/TLS configuration through environment variables:\n\n| Environment Variable | Description |\n|---------------------|-------------|\n| `UIPATH_DISABLE_SSL_VERIFY` | Set to `\"1\"`, `\"true\"`, `\"yes\"`, or `\"on\"` to disable SSL verification (not recommended for production) |\n| `SSL_CERT_FILE` | Path to a custom SSL certificate file |\n| `REQUESTS_CA_BUNDLE` | Path to a custom CA bundle file |\n| `SSL_CERT_DIR` | Path to a directory containing SSL certificate files |\n\nBy default, the client uses [truststore](https://pypi.org/project/truststore/) (if available) or falls back to [certifi](https://pypi.org/project/certifi/) for SSL certificate verification.\n\n### Logging\n\nEnable request/response logging by passing a logger instance:\n\n```python\nimport logging\nfrom uipath_langchain_client.clients.openai.chat_models import UiPathAzureChatOpenAI\n\nlogging.basicConfig(level=logging.DEBUG)\nlogger = logging.getLogger(\"uipath_llm\")\n\nchat = UiPathAzureChatOpenAI(\n    model=\"gpt-4o-2024-11-20\",\n    logger=logger,  # Enables request/response logging with timing\n)\nresponse = chat.invoke(\"Hello!\")\n```\n\nThe logger will record:\n- Request start time and URL\n- Response duration (in milliseconds)\n- Error responses with status codes and body content\n\n### Default Headers\n\nAll requests automatically include the following default headers:\n\n| Header | Value | Description |\n|--------|-------|-------------|\n| `X-UiPath-LLMGateway-TimeoutSeconds` | `295` | Server-side timeout for LLM Gateway |\n| `X-UiPath-LLMGateway-AllowFull4xxResponse` | `true` | Returns full error response bodies for 4xx errors |\n\n### Authentication Auto-Refresh\n\nBoth AgentHub and LLMGateway authentication pipelines automatically handle token expiry:\n- When a request receives a **401 Unauthorized** response, the auth pipeline refreshes the token and retries the request\n- Token refresh is handled transparently — no user intervention required\n- Auth instances use the **singleton pattern** to reuse tokens across multiple client instances\n\n## Development\n\n```bash\n# Clone and install with dev dependencies\ngit clone https://github.com/UiPath/uipath-llm-client.git\ncd uipath-llm-client\nuv sync\n\n# Run tests\nuv run pytest\n\n# Format and lint\nuv run ruff format .\nuv run ruff check .\nuv run pyright\n```\n\n### Testing\n\nTests use [VCR.py](https://vcrpy.readthedocs.io/) to record and replay HTTP interactions. Cassettes (recorded responses) are stored in `tests/cassettes.db` (SQLite) via `pytest-recording`.\n\n**Important:** Tests must pass locally before submitting a PR. The CI pipeline does not make any real API requests—it only runs tests using the pre-recorded cassettes.\n\n**Prerequisites:**\n- Install [Git LFS](https://git-lfs.com/): `brew install git-lfs` (macOS) or `apt install git-lfs` (Ubuntu)\n- Initialize Git LFS: `git lfs install`\n- Pull cassettes: `git lfs pull`\n\n**Running tests locally:**\n\n```bash\n# Run all tests using cassettes (no API credentials required)\nuv run pytest\n\n# Run specific test files\nuv run pytest tests/langchain/\nuv run pytest tests/core/\n```\n\n**Updating cassettes:**\n\nWhen adding new tests or modifying existing ones that require new API interactions:\n\n1. Set up your environment with valid credentials (see [Configuration](#configuration))\n2. Run the tests—VCR will record new interactions automatically\n3. Commit the updated cassettes along with your code changes\n\n**Note:** The CI pipeline validates that all tests pass using the committed cassettes. If your tests require new API calls, you must record and commit the corresponding cassettes for the pipeline to pass.\n\n## Project Structure\n\n```\nuipath-llm-client/\n├── src/uipath/llm_client/              # Core package\n│   ├── httpx_client.py                 # UiPathHttpxClient / UiPathHttpxAsyncClient\n│   ├── clients/                        # Native SDK wrappers\n│   │   ├── openai/                     # UiPathOpenAI, UiPathAzureOpenAI, etc.\n│   │   ├── anthropic/                  # UiPathAnthropic, UiPathAnthropicBedrock, etc.\n│   │   ├── google/                     # UiPathGoogle\n│   │   ├── normalized/                 # UiPathNormalizedClient (provider-agnostic)\n│   │   └── litellm/                    # UiPathLiteLLM (via LiteLLM)\n│   ├── settings/                       # Backend-specific settings \u0026 auth\n│   │   ├── base.py                     # UiPathBaseSettings, UiPathAPIConfig\n│   │   ├── platform/                   # PlatformSettings, PlatformAuth\n│   │   └── llmgateway/                 # LLMGatewaySettings, LLMGatewayS2SAuth\n│   └── utils/                          # Exceptions, retry, logging, SSL\n│       ├── exceptions.py               # UiPathAPIError hierarchy (12 classes)\n│       ├── retry.py                    # RetryConfig, RetryableHTTPTransport\n│       ├── logging.py                  # LoggingConfig\n│       └── ssl_config.py              # SSL/TLS configuration\n├── packages/\n│   ├── uipath_langchain_client/        # LangChain integration\n│   │   └── src/uipath_langchain_client/\n│   │       ├── base_client.py          # UiPathBaseLLMClient mixin\n│   │       ├── factory.py              # get_chat_model(), get_embedding_model()\n│   │       └── clients/\n│   │           ├── normalized/         # UiPathChat, UiPathEmbeddings\n│   │           ├── openai/             # UiPathAzureChatOpenAI, UiPathChatOpenAI, etc.\n│   │           ├── google/             # UiPathChatGoogleGenerativeAI, etc.\n│   │           ├── anthropic/          # UiPathChatAnthropic\n│   │           ├── vertexai/           # UiPathChatAnthropicVertex\n│   │           ├── bedrock/            # UiPathChatBedrock, UiPathChatBedrockConverse\n│   │           ├── fireworks/          # UiPathChatFireworks, UiPathFireworksEmbeddings\n│   │           ├── litellm/           # UiPathChatLiteLLM, UiPathLiteLLMEmbeddings\n│   │           └── azure/              # UiPathAzureAIChatCompletionsModel\n└── tests/                              # Test suite with VCR cassettes (SQLite)\n```\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n## Contact\n\nFor any questions or issues, please contact the maintainers at [UiPath GitHub Repository](https://github.com/UiPath/uipath-llm-client).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuipath%2Fuipath-llm-client-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuipath%2Fuipath-llm-client-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuipath%2Fuipath-llm-client-python/lists"}