Skip to content

feat: per-vendor model_name defaults on new chat clients (parity with legacy)#809

Merged
cosminacho merged 1 commit intomainfrom
feat/default-model-name
Apr 27, 2026
Merged

feat: per-vendor model_name defaults on new chat clients (parity with legacy)#809
cosminacho merged 1 commit intomainfrom
feat/default-model-name

Conversation

@cosminacho
Copy link
Copy Markdown
Contributor

@cosminacho cosminacho commented Apr 24, 2026

Summary

The legacy chat classes had per-vendor model_name defaults so callers could instantiate UiPathChat() or UiPathChatBedrock() with no args. The new classes re-exported from uipath_langchain.chat (backed by uipath_langchain_client) don't — model= is a required pydantic field. This PR restores parity where a legacy default existed.

Per-vendor defaults (verified against the git history of the legacy classes)

Class Default Mechanism
UiPathChat, UiPathAzureChatOpenAI, UiPathChatOpenAI UIPATH_MODEL_NAMEgpt-4.1-mini-2025-04-14 field default_factory
UiPathChatGoogleGenerativeAI, UiPathChatVertex gemini-2.5-flash field default_factory
UiPathChatBedrock, UiPathChatAnthropicBedrock anthropic.claude-haiku-4-5-20251001-v1:0 field default_factory
UiPathChatBedrockConverse anthropic.claude-haiku-4-5-20251001-v1:0 thin subclass with a model_validator(mode="before")

Classes with NO default (model= stays required)

Class Reason
UiPathChatAnthropic No legacy equivalent
UiPathChatAnthropicVertex No legacy equivalent
UiPathChatFireworks No legacy equivalent

Only Azure-backed classes ever honored UIPATH_MODEL_NAME; Bedrock and Vertex legacy defaults were hardcoded. Verified in commit 634d9fe feat: add chat models.

Approach

Each existing vendor re-export file is where:

  1. The upstream uipath_langchain_client class is first imported
  2. The legacy model_name default is attached inline
src/uipath_langchain/chat/
    __init__.py       # lazy __getattr__ delegates to the vendor files
    openai.py         # sets default on UiPathChat, UiPathAzureChatOpenAI, UiPathChatOpenAI
    bedrock.py        # sets default on UiPathChatBedrock + UiPathChatAnthropicBedrock; wraps UiPathChatBedrockConverse with a before-validator subclass
    vertex.py         # sets default on UiPathChatGoogleGenerativeAI (+ UiPathChatVertex alias)
    models.py         # re-exports the OpenAI family from openai.py

For classes where it works, the default is attached via pydantic FieldInfo mutation directly on the upstream class: cls.model_fields["model_name"].default_factory = factory; cls.model_rebuild(force=True). Pydantic V2 gives each class its own FieldInfo instance at class creation, so the mutation is scoped to exactly that class and doesn't leak to siblings or parents in uipath_langchain_client.

UiPathChatBedrockConverse gets a thin subclass with a @model_validator(mode="before") because its upstream ChatBedrockConverse.set_disable_streaming reads model / model_id from the raw input dict before field defaults fire.

Properties preserved

  • model=... kwarg still wins over the default.
  • For non-wrapped classes, the re-exported class IS the upstream class (identity preserved).
  • For UiPathChatBedrockConverse, the re-export is a subclass — issubclass check still holds.
  • Tracing span names unchanged.
  • Lazy imports preserved: asking for UiPathChat doesn't load Bedrock/Vertex code.

Bookkeeping

  • pyproject.toml: 0.10.50.10.6
  • uv.lock refreshed

Test plan

  • tests/chat/test_default_model_name.py26 tests exercising the public uipath_langchain.chat API only. For each of the 8 defaulted classes: construct cls() with no model kwarg and assert .model_name. For the 3 non-defaulted classes: assert ValidationError is raised. Plus env-var behavior, identity/alias, and subclass-relationship assertions. All pass.
  • uv run pytest tests/chat/ — 192 passed
  • uv run mypy src/ — clean
  • just lint — clean

Generated with Claude Code

@cosminacho cosminacho changed the title feat: default model_name on new chat clients (parity with legacy) feat: per-vendor model_name defaults on new chat clients (parity with legacy) Apr 24, 2026
@cosminacho cosminacho force-pushed the feat/default-model-name branch 2 times, most recently from 98ecefa to 6637c30 Compare April 27, 2026 07:44
@cosminacho cosminacho force-pushed the feat/default-model-name branch 2 times, most recently from ea29e15 to 62251da Compare April 27, 2026 08:03
Ports the legacy model_name defaults from the pre-migration
UiPathRequestMixin / BedrockModels / GeminiModels over to the new
uipath_langchain_client-backed re-exports so callers can construct
UiPathChat(), UiPathChatBedrock(), UiPathChatVertex() etc. with no args.

Defaults per vendor:
- OpenAI / Azure (UiPathChat, UiPathAzureChatOpenAI, UiPathChatOpenAI):
  UIPATH_MODEL_NAME env var, fallback gpt-4.1-mini-2025-04-14.
- Bedrock (UiPathChatBedrock, UiPathChatAnthropicBedrock,
  UiPathChatBedrockConverse): anthropic.claude-haiku-4-5-20251001-v1:0.
- Vertex (UiPathChatGoogleGenerativeAI, UiPathChatVertex): gemini-2.5-flash.

Classes without a legacy equivalent (UiPathChatAnthropic,
UiPathChatAnthropicVertex, UiPathChatFireworks) keep model= required.

Implementation: defaults are attached inline in the per-vendor re-export
files (chat/openai.py, chat/bedrock.py, chat/vertex.py, chat/models.py).
For most classes this is a one-liner FieldInfo mutation
(cls.model_fields["model_name"].default_factory = factory;
cls.model_rebuild(force=True)) which pydantic V2 scopes per class.

UiPathChatBedrockConverse is the one class where the field-default path
does not suffice — its upstream ChatBedrockConverse.set_disable_streaming
before-validator reads model / model_id from the raw input dict before
field defaults fire — so it gets a thin subclass with our own
@model_validator(mode="before") that injects the default into values.

Version bump 0.10.5 -> 0.10.6.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cosminacho cosminacho force-pushed the feat/default-model-name branch from 62251da to 87a173a Compare April 27, 2026 08:06
@cosminacho cosminacho merged commit c9a4103 into main Apr 27, 2026
71 of 72 checks passed
@cosminacho cosminacho deleted the feat/default-model-name branch April 27, 2026 08:23
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.

2 participants