UAT: ensure_built_in_actors() stores title-cased provider name (e.g. "Openai") in actor provider field — breaks provider-name-based actor lookups #4767

Open
opened 2026-04-08 18:55:10 +00:00 by HAL9000 · 1 comment
Owner

Summary

ActorRegistry.ensure_built_in_actors() in src/cleveragents/actor/registry.py uses info.name as the provider_name for built-in actors. ProviderInfo.name is set in _discover_providers() as provider_type.value.title() — e.g., "openai""Openai", "anthropic""Anthropic". This title-cased name is then stored in the actor's provider field in the database. However, the default actor selection logic in ensure_built_in_actors() compares actor.provider.lower() == defaults.provider, which works around the issue — but any external code that queries actors by provider name using exact string matching will fail.

Expected Behavior

Built-in actors should store the lowercase canonical provider name (e.g., "openai", "anthropic") in the provider field, consistent with ProviderType.value values and the actor name namespace (e.g., "openai/gpt-4o").

Actual Behavior

# src/cleveragents/actor/registry.py — ensure_built_in_actors()

for info in configured:
    provider_name = info.name or info.provider_type.value
    # info.name = "Openai" (title-cased from _discover_providers)
    # info.provider_type.value = "openai" (lowercase)
    
    actor = self._actor_service.upsert_actor(
        name=self._actor_name(provider_name, model_id),
        # name = "openai/gpt-4o" ← lowercased by _actor_name()
        provider=provider_name,
        # provider = "Openai" ← NOT lowercased ← bug
        ...
        config_blob={
            "provider": provider_name,  # "Openai" ← bug
            ...
        },
    )

The _actor_name() method lowercases the provider name for the actor's name field, but the provider field in the actor record and config blob retains the title-cased value.

This creates an inconsistency:

  • actor.name = "openai/gpt-4o" (lowercase namespace)
  • actor.provider = "Openai" (title-cased)

Impact

  • Any code that filters actors by actor.provider == "openai" (lowercase) will fail to find built-in actors
  • The graph_descriptor stored in the actor config also uses the title-cased provider name, creating inconsistency with how providers are referenced elsewhere
  • Actor YAML files that specify provider: openai (lowercase) will not match the stored provider: Openai value when doing equality checks
  • The ensure_built_in_actors() workaround (actor.provider.lower() == defaults.provider) masks the bug but doesn't fix it for all consumers

Code Location

  • src/cleveragents/actor/registry.pyensure_built_in_actors() method (lines ~100–140)
  • src/cleveragents/providers/registry.py_discover_providers() method, name=provider_type.value.title() line

Fix Direction

Option A: Use provider_type.value (lowercase) instead of info.name for the actor's provider field:

for info in configured:
    provider_name = info.provider_type.value  # "openai" (lowercase) ← fix
    model_id = info.default_model
    ...
    actor = self._actor_service.upsert_actor(
        name=self._actor_name(provider_name, model_id),
        provider=provider_name,  # "openai" ✓
        ...
    )

Option B: Fix _discover_providers() to store lowercase names in ProviderInfo.name:

provider_info = ProviderInfo(
    ...
    name=provider_type.value,  # "openai" instead of "Openai"
    ...
)

Option A is safer as it doesn't change the ProviderInfo.name field which may be used for display purposes.


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

## Summary `ActorRegistry.ensure_built_in_actors()` in `src/cleveragents/actor/registry.py` uses `info.name` as the `provider_name` for built-in actors. `ProviderInfo.name` is set in `_discover_providers()` as `provider_type.value.title()` — e.g., `"openai"` → `"Openai"`, `"anthropic"` → `"Anthropic"`. This title-cased name is then stored in the actor's `provider` field in the database. However, the default actor selection logic in `ensure_built_in_actors()` compares `actor.provider.lower() == defaults.provider`, which works around the issue — but any external code that queries actors by provider name using exact string matching will fail. ## Expected Behavior Built-in actors should store the lowercase canonical provider name (e.g., `"openai"`, `"anthropic"`) in the `provider` field, consistent with `ProviderType.value` values and the actor name namespace (e.g., `"openai/gpt-4o"`). ## Actual Behavior ```python # src/cleveragents/actor/registry.py — ensure_built_in_actors() for info in configured: provider_name = info.name or info.provider_type.value # info.name = "Openai" (title-cased from _discover_providers) # info.provider_type.value = "openai" (lowercase) actor = self._actor_service.upsert_actor( name=self._actor_name(provider_name, model_id), # name = "openai/gpt-4o" ← lowercased by _actor_name() provider=provider_name, # provider = "Openai" ← NOT lowercased ← bug ... config_blob={ "provider": provider_name, # "Openai" ← bug ... }, ) ``` The `_actor_name()` method lowercases the provider name for the actor's `name` field, but the `provider` field in the actor record and config blob retains the title-cased value. This creates an inconsistency: - `actor.name = "openai/gpt-4o"` (lowercase namespace) - `actor.provider = "Openai"` (title-cased) ## Impact - Any code that filters actors by `actor.provider == "openai"` (lowercase) will fail to find built-in actors - The `graph_descriptor` stored in the actor config also uses the title-cased provider name, creating inconsistency with how providers are referenced elsewhere - Actor YAML files that specify `provider: openai` (lowercase) will not match the stored `provider: Openai` value when doing equality checks - The `ensure_built_in_actors()` workaround (`actor.provider.lower() == defaults.provider`) masks the bug but doesn't fix it for all consumers ## Code Location - `src/cleveragents/actor/registry.py` — `ensure_built_in_actors()` method (lines ~100–140) - `src/cleveragents/providers/registry.py` — `_discover_providers()` method, `name=provider_type.value.title()` line ## Fix Direction **Option A**: Use `provider_type.value` (lowercase) instead of `info.name` for the actor's `provider` field: ```python for info in configured: provider_name = info.provider_type.value # "openai" (lowercase) ← fix model_id = info.default_model ... actor = self._actor_service.upsert_actor( name=self._actor_name(provider_name, model_id), provider=provider_name, # "openai" ✓ ... ) ``` **Option B**: Fix `_discover_providers()` to store lowercase names in `ProviderInfo.name`: ```python provider_info = ProviderInfo( ... name=provider_type.value, # "openai" instead of "Openai" ... ) ``` Option A is safer as it doesn't change the `ProviderInfo.name` field which may be used for display purposes. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Medium — spec compliance bug identified by UAT testing
  • Story Points: 3 (M) — targeted fix to align implementation with spec
  • MoSCoW: Must Have — spec compliance is required for correct system behavior

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Medium — spec compliance bug identified by UAT testing - **Story Points**: 3 (M) — targeted fix to align implementation with spec - **MoSCoW**: Must Have — spec compliance is required for correct system behavior --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner
HAL9000 added this to the v3.5.0 milestone 2026-04-09 03:04:46 +00:00
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#4767
No description provided.