Conversation
Propose a provider-agnostic GenericLlmConfig component that uses a string-based provider.type discriminator and flexible ProviderConfig, replacing the need for per-provider LlmConfig subclasses.
|
Hi @spichen, thank you for the great work. This is a very good starting point, we have been discussing this design internally, and we agreed on a few points. Here's what we thought could be a possible solution: Instead of having a new GenericLlmConfig, we make the LlmConfig not abstract anymore. # Not abstract anymore
class LlmConfig(Component):
"""A generic, provider-agnostic LLM configuration."""
model_id: str
"""Primary model identifier"""
provider: Optional[str] = None
"""Model provider (e.g., meta, openai, anthropic, ...)"""
api_provider: Optional[str] = None
"""APIs provider (e.g., oci, openai, vertex_ai, aws_bedrock, ...)"""
api_type: Optional[str] = None
"""API protocol to use (e.g., chat_completions, responses, ...)"""Existing classes will fix the value of these attributes where needed, and they should be excluded from the serialization for brevity. class OciGenAiConfig(GenericLlmConfig):
# Don't know the (model) provider a priori
api_provider: str = "oci" # Freeze the value
...
class OpenAiConfig(GenericLlmConfig):
# We know both provider and api_provider, we fix them
provider: str = "openai" # Freeze the value
api_provider: str = "openai" # Freeze the value
...
class OpenAiCompatibleConfig(GenericLlmConfig):
# This limits only the api_type to chat_completions or responses
# We don't know what is the model, nor the api provider
...The name of the attributes are chosen to fit what is already present in some LlmConfig classes (you can give a look at the OCI ones for example). The main reason for this choice is that all the attributes are quite independent from each other, and collecting them in a Provider class would require to fix one of the attributes, but in an unclear manner, and the number of subclasses could explode. For example: meta model exposed by AWS bedrock behind responses APIs, cohere model exposed by OCI behind chat_completions, ... Let us know what you think about it. |
|
Hi @cesarebernardis , thanks for the thoughtful feedback and for discussing this internally. I agree with the direction here. Making Totally on board with deferring Auth as well. Better to land the provider/API fields as a focused change and layer authentication on top later. I'll rework the PR to follow this approach. Let me know if there's anything else you'd like adjusted. |
Strong support for this RFC — concrete use case: OpenRouter + reasoning tokensI want to share a concrete problem that this RFC would unblock. The problem todayWhen using OpenRouter (or similar routing proxies like LiteLLM) with Agent Spec + the LangGraph adapter, the only viable config types are The issue is that
This is a known and tracked problem on the LangChain side:
LangChain's solution is provider-specific packages. For example, But the current Agent Spec type hierarchy has no way to reach these provider-specific LangChain classes. The How this RFC solves itThe component_type: LlmConfig
model_id: "anthropic/claude-sonnet-4"
api_provider: openrouter
api_type: chat_completions
default_generation_parameters:
temperature: 0.7And on the adapter side: # In _llm_convert_to_langgraph, string-based dispatch for bare LlmConfig:
elif llm_config.api_provider == "openrouter":
from langchain_openrouter import ChatOpenRouter
return ChatOpenRouter(model=llm_config.model_id, ...)Without this RFC, the only alternative is adding a full Suggestions
Overall, this is a well-designed proposal. The three-axis separation ( |
|
Hi @spichen , sorry for the delay in our answer. We went through the latest version of the proposal internally, and the team approved. You can proceed with the implementation of this design. Thank you again for your contribution. |
…api_type fields Allow any LLM to be described via bare LlmConfig without requiring a dedicated subclass. Adds model_id, provider, api_provider, and api_type fields to the base class (min version v26_2_0). Updates all existing subclasses with frozen defaults and versioned field exclusions. Adds adapter dispatch for bare LlmConfig with api_provider="openai". Updates schema generation to handle concrete classes with subclasses.
… inherently v26_2_0 Remove _versioned_model_fields_to_exclude from LlmConfig and simplify _infer_min_agentspec_version_from_configuration to always return v26_2_0 for bare LlmConfig instances. Subclasses handle their own field exclusions following the standard project pattern.
Propose a provider-agnostic GenericLlmConfig component that uses a string-based provider.type discriminator and flexible ProviderConfig, replacing the need for per-provider LlmConfig subclasses.