Skip to content

fix: thread agenthub_config through chat_model_factory new path#834

Closed
cotovanu-cristian wants to merge 1 commit intomainfrom
fix/agenthub-config-factory-thread
Closed

fix: thread agenthub_config through chat_model_factory new path#834
cotovanu-cristian wants to merge 1 commit intomainfrom
fix/agenthub-config-factory-thread

Conversation

@cotovanu-cristian
Copy link
Copy Markdown
Collaborator

Summary

When agents run with command=\"debug\" (or any non-runtime context), the LLM gateway calls were shipping X-UiPath-AgentHub-Config: agentsruntime instead of the computed agentsplayground. Every debug session was billed against the runtime quota.

The bug

chat_model_factory.get_chat_model accepted an agenthub_config parameter whose docstring said it was "ignored by the new factory" — and it was. On the use_new_llm_clients=True path, the value was dropped before delegating to uipath_langchain_client.factory.get_chat_model, which built a fresh PlatformSettings whose agenthub_config defaults to \"agentsruntime\" upstream.

The local _AgentHubConfigDefaultMixin (added in #825/#830) clears that default for direct-construction users — from uipath_langchain.chat import UiPathChat etc. — but the factory path bypassed it entirely, so uipath-agents callers in agent_graph_builder/llm_utils.py:create_llm had their carefully computed value silently discarded.

Trace for uipath debug agent.json:

get_execution_type(ctx) → AgentExecutionType.PLAYGROUND
get_agenthub_config(PLAYGROUND) → \"agentsplayground\"  ✓
get_chat_model(model, agenthub_config=\"agentsplayground\")  → dropped on floor
get_chat_model_factory(client_settings=None)
  └─ PlatformSettings()  → agenthub_config=\"agentsruntime\"  ✗

The fix

In chat_model_factory.get_chat_model, when agenthub_config is provided on the new path:

  • Build client_settings via get_default_client_settings() if the caller didn't supply one.
  • Set client_settings.agenthub_config = agenthub_config before delegating.
  • Caller-supplied client_settings instances are mutated, not replaced, so other fields survive.
  • agenthub_config=None is a pass-through — preserves existing env-var / direct-construction paths governed by the mixin.

hasattr guard mirrors the pattern in _AgentHubConfigDefaultMixin._clear_agenthub_config_default, since the UiPathBaseSettings ABC doesn't expose agenthub_config (only the concrete PlatformBaseSettings does).

What changed

File Change
src/uipath_langchain/chat/chat_model_factory.py +12/-2 — fix + docstring update
tests/chat/test_chat_model_factory_agenthub.py +123 — 4 new tests
pyproject.toml 0.10.18 → 0.10.19
uv.lock regenerated

Tests added (4)

  1. Tracerget_chat_model(agenthub_config=\"agentsplayground\", use_new_llm_clients=True) results in client_settings.agenthub_config == \"agentsplayground\" reaching the upstream factory. Was failing before the fix; proves the bug.
  2. Pass-throughagenthub_config=None does not synthesize a client_settings; preserves env-var / mixin paths.
  3. Caller settings preserved — explicit client_settings is mutated, not replaced; non-agenthub_config fields survive.
  4. Legacy path regression guarduse_new_llm_clients=False still threads agenthub_config to the legacy factory.

Existing tests/chat/test_agenthub_config_default.py (39 tests for direct-construction mixin behavior) still passes — the fix is additive, the mixin is still load-bearing for direct constructors.

Full chat suite: 239 passed.

Out of scope / follow-ups

  • ClaudeSDKRuntime and GatewayProxy defaults in uipath-agents-python/src/uipath_agents/claude_sdk/{runtime.py:90,gateway_proxy.py:168} — same agenthub_config: str = \"agentsruntime\" anti-pattern. Currently masked by AgentsClaudeSDKRuntime overriding both. Worth fixing but lives in a different repo/package.
  • Upstream PlatformSettings.agenthub_config = \"agentsruntime\" default in uipath_langchain_client — would be a cleaner fix to set default=None upstream, but cross-package coordination. This PR neutralizes the symptom for the agents path without needing it.

Test plan

  • New tests pass: uv run pytest tests/chat/test_chat_model_factory_agenthub.py
  • Existing mixin tests still pass: uv run pytest tests/chat/test_agenthub_config_default.py
  • Full chat suite passes: uv run pytest tests/chat/ (239 passed)
  • mypy clean on changed source: uv run mypy src/uipath_langchain/chat/chat_model_factory.py
  • ruff clean on changed files
  • Manual verification: run uv run uipath debug agent.json '{}' against a real tenant; confirm LLM gateway requests carry X-UiPath-AgentHub-Config: agentsplayground

🤖 Generated with Claude Code

PlatformSettings.agenthub_config defaults to "agentsruntime" upstream.
The local _AgentHubConfigDefaultMixin clears this default for direct
chat-model construction (UiPathChat, UiPathChatOpenAI, etc.), but the
factory path used by uipath-agents bypassed the mitigation entirely:
get_chat_model accepted agenthub_config but its docstring said it was
"ignored by the new factory" — and indeed it was, dropped on the floor
before delegating to the upstream factory.

Result: agents running with command="debug" computed
agenthub_config="agentsplayground" via get_agenthub_config(...) and
passed it to get_chat_model, but every LLM gateway request shipped
X-UiPath-AgentHub-Config: agentsruntime — billing the runtime quota
instead of the developer debug quota.

Fix: when agenthub_config is provided on the new path, build a
client_settings (via get_default_client_settings) if absent and set
client_settings.agenthub_config before delegating. Caller-supplied
client_settings instances are mutated rather than replaced so other
fields survive. Pass-through preserved when agenthub_config is None
to leave existing env-var / direct-construction paths governed by
the mixin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cotovanu-cristian cotovanu-cristian marked this pull request as draft May 8, 2026 08:08
@cotovanu-cristian
Copy link
Copy Markdown
Collaborator Author

closing as it's included in #835

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