UAT: Groq, Together AI, and Cohere providers lack dedicated AIProviderInterface adapter classes #6017

Open
opened 2026-04-09 13:42:03 +00:00 by HAL9000 · 1 comment
Owner

Bug Report

Summary

The provider system has an architectural inconsistency: OpenAI, Anthropic, Google, and OpenRouter each have dedicated AIProviderInterface adapter classes (OpenAIChatProvider, AnthropicChatProvider, GoogleChatProvider, OpenRouterChatProvider) in src/cleveragents/providers/llm/. However, Groq, Together AI, and Cohere do not have dedicated adapter classes — they fall through to a generic LangChainChatProvider wrapper via _create_provider_llm().

What Was Tested

  • Inspected src/cleveragents/providers/llm/ directory structure
  • Analyzed ProviderRegistry.create_ai_provider() method (lines ~400–500 in registry.py)
  • Compared provider handling paths for all supported providers

Expected Behavior

All first-class providers should have consistent implementation. Either:

  1. All providers have dedicated adapter classes (consistent with OpenAI/Anthropic/Google/OpenRouter pattern), OR
  2. All providers use the generic LangChainChatProvider wrapper (consistent pattern)

The spec describes a Provider Registry as a central catalog — all registered providers should have equivalent implementation depth.

Actual Behavior

Providers WITH dedicated adapter classes:

  • OpenAIChatProvidersrc/cleveragents/providers/llm/openai_provider.py
  • AnthropicChatProvidersrc/cleveragents/providers/llm/anthropic_provider.py
  • GoogleChatProvidersrc/cleveragents/providers/llm/google_provider.py
  • OpenRouterChatProvidersrc/cleveragents/providers/llm/openrouter_provider.py

Providers WITHOUT dedicated adapter classes (generic fallback only):

  • Groq — uses generic LangChainChatProvider via _create_provider_llm()
  • Together AI — uses generic LangChainChatProvider via _create_provider_llm()
  • Cohere — uses generic LangChainChatProvider via _create_provider_llm()

In registry.py create_ai_provider(), the Groq/Together/Cohere path falls through to:

# Capture the narrowed ProviderType in a local variable...
resolved_provider_type: ProviderType = provider_type

def llm_factory(mid: str) -> BaseLanguageModel:
    factory_kwargs: dict[str, Any] = {"max_retries": max_retries}
    return self._create_provider_llm(resolved_provider_type, mid, **factory_kwargs)

return LangChainChatProvider(
    name=provider_type.value,
    model_id=model_id or self.DEFAULT_MODELS.get(provider_type, "unknown"),
    llm_factory=llm_factory,
    max_retries=max_retries,
    supports_streaming=capabilities.supports_streaming,
)

This means:

  1. No API key validation at create_ai_provider() time for Groq/Together/Cohere (unlike OpenAI/Anthropic/Google which raise ValueError immediately if key missing)
  2. No provider-specific initialization logic (e.g., Cohere uses cohere_api_key parameter name, not api_key)
  3. Inconsistent error messages when provider is misconfigured

Specific Issue: Cohere API Key Parameter Name Mismatch

The ChatCohere constructor uses cohere_api_key as the parameter name (per the type stub in typings/langchain_cohere/__init__.pyi), but the generic LangChainChatProvider path does not pass the API key at all — it relies on the environment variable being set. This is inconsistent with how OpenAI/Anthropic/Google providers explicitly pass the API key to the LangChain constructor.

Code Locations

  • src/cleveragents/providers/llm/ — missing groq_provider.py, together_provider.py, cohere_provider.py
  • src/cleveragents/providers/registry.pycreate_ai_provider() method, lines ~400–500
  • src/cleveragents/providers/llm/__init__.py — exports only 4 providers, missing 3

Fix

Create dedicated adapter classes:

  • src/cleveragents/providers/llm/groq_provider.pyGroqChatProvider(LangChainChatProvider)
  • src/cleveragents/providers/llm/together_provider.pyTogetherChatProvider(LangChainChatProvider)
  • src/cleveragents/providers/llm/cohere_provider.pyCohereChatProvider(LangChainChatProvider)

Each should follow the same pattern as OpenAIChatProvider:

  1. Accept api_key parameter
  2. Validate API key is non-empty
  3. Pass API key explicitly to the LangChain constructor
  4. Export from __init__.py
  5. Add explicit handling in create_ai_provider() in registry.py

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: uat-tester

## Bug Report ### Summary The provider system has an architectural inconsistency: OpenAI, Anthropic, Google, and OpenRouter each have dedicated `AIProviderInterface` adapter classes (`OpenAIChatProvider`, `AnthropicChatProvider`, `GoogleChatProvider`, `OpenRouterChatProvider`) in `src/cleveragents/providers/llm/`. However, Groq, Together AI, and Cohere **do not have dedicated adapter classes** — they fall through to a generic `LangChainChatProvider` wrapper via `_create_provider_llm()`. ### What Was Tested - Inspected `src/cleveragents/providers/llm/` directory structure - Analyzed `ProviderRegistry.create_ai_provider()` method (lines ~400–500 in `registry.py`) - Compared provider handling paths for all supported providers ### Expected Behavior All first-class providers should have consistent implementation. Either: 1. All providers have dedicated adapter classes (consistent with OpenAI/Anthropic/Google/OpenRouter pattern), OR 2. All providers use the generic `LangChainChatProvider` wrapper (consistent pattern) The spec describes a `Provider Registry` as a central catalog — all registered providers should have equivalent implementation depth. ### Actual Behavior **Providers WITH dedicated adapter classes:** - `OpenAIChatProvider` — `src/cleveragents/providers/llm/openai_provider.py` - `AnthropicChatProvider` — `src/cleveragents/providers/llm/anthropic_provider.py` - `GoogleChatProvider` — `src/cleveragents/providers/llm/google_provider.py` - `OpenRouterChatProvider` — `src/cleveragents/providers/llm/openrouter_provider.py` **Providers WITHOUT dedicated adapter classes (generic fallback only):** - Groq — uses generic `LangChainChatProvider` via `_create_provider_llm()` - Together AI — uses generic `LangChainChatProvider` via `_create_provider_llm()` - Cohere — uses generic `LangChainChatProvider` via `_create_provider_llm()` In `registry.py` `create_ai_provider()`, the Groq/Together/Cohere path falls through to: ```python # Capture the narrowed ProviderType in a local variable... resolved_provider_type: ProviderType = provider_type def llm_factory(mid: str) -> BaseLanguageModel: factory_kwargs: dict[str, Any] = {"max_retries": max_retries} return self._create_provider_llm(resolved_provider_type, mid, **factory_kwargs) return LangChainChatProvider( name=provider_type.value, model_id=model_id or self.DEFAULT_MODELS.get(provider_type, "unknown"), llm_factory=llm_factory, max_retries=max_retries, supports_streaming=capabilities.supports_streaming, ) ``` This means: 1. No API key validation at `create_ai_provider()` time for Groq/Together/Cohere (unlike OpenAI/Anthropic/Google which raise `ValueError` immediately if key missing) 2. No provider-specific initialization logic (e.g., Cohere uses `cohere_api_key` parameter name, not `api_key`) 3. Inconsistent error messages when provider is misconfigured ### Specific Issue: Cohere API Key Parameter Name Mismatch The `ChatCohere` constructor uses `cohere_api_key` as the parameter name (per the type stub in `typings/langchain_cohere/__init__.pyi`), but the generic `LangChainChatProvider` path does not pass the API key at all — it relies on the environment variable being set. This is inconsistent with how OpenAI/Anthropic/Google providers explicitly pass the API key to the LangChain constructor. ### Code Locations - `src/cleveragents/providers/llm/` — missing `groq_provider.py`, `together_provider.py`, `cohere_provider.py` - `src/cleveragents/providers/registry.py` — `create_ai_provider()` method, lines ~400–500 - `src/cleveragents/providers/llm/__init__.py` — exports only 4 providers, missing 3 ### Fix Create dedicated adapter classes: - `src/cleveragents/providers/llm/groq_provider.py` — `GroqChatProvider(LangChainChatProvider)` - `src/cleveragents/providers/llm/together_provider.py` — `TogetherChatProvider(LangChainChatProvider)` - `src/cleveragents/providers/llm/cohere_provider.py` — `CohereChatProvider(LangChainChatProvider)` Each should follow the same pattern as `OpenAIChatProvider`: 1. Accept `api_key` parameter 2. Validate API key is non-empty 3. Pass API key explicitly to the LangChain constructor 4. Export from `__init__.py` 5. Add explicit handling in `create_ai_provider()` in `registry.py` --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
Author
Owner

🏷️ Label compliance fix applied by backlog groomer (cycle 64)

Added missing label: State/Verified

This issue already had Type/Bug and Priority/Backlog but was missing the required State/ label. Applied State/Verified to bring the issue into full label compliance.


Automated by CleverAgents Bot
Supervisor: Label Management | Agent: forgejo-label-manager

🏷️ **Label compliance fix applied by backlog groomer (cycle 64)** Added missing label: `State/Verified` This issue already had `Type/Bug` and `Priority/Backlog` but was missing the required `State/` label. Applied `State/Verified` to bring the issue into full label compliance. --- **Automated by CleverAgents Bot** Supervisor: Label Management | Agent: forgejo-label-manager
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#6017
No description provided.