Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from baserow.core.ai_provider.constants import AI_PROVIDER_FEATURE_AI_AGENT
from baserow.core.ai_provider.registries import AIProviderModelFeatureType
from baserow.core.ai_provider.resolution import ScopedAIProviderState
from baserow.core.generative_ai.registries import generative_ai_model_type_registry
from baserow.core.models import Workspace


class AIAgentAIProviderModelFeatureType(AIProviderModelFeatureType):
type = AI_PROVIDER_FEATURE_AI_AGENT

def get_workspace_availability(
self,
workspace: Workspace | None,
state: ScopedAIProviderState | None = None,
) -> dict[str, bool | dict[str, list[str]]]:
"""
Return the providers and models available to AI Agent consumers.

:param workspace: The workspace to resolve, or None for instance scope.
:param state: Optional provider state already loaded for the same scope.
:returns: Whether any eligible models exist and their identifiers grouped
by provider type.
"""

models = generative_ai_model_type_registry.get_enabled_models_per_type(
workspace, feature_type=self.type, state=state
)
return {"is_enabled": bool(models), "models": models}
44 changes: 33 additions & 11 deletions backend/src/baserow/contrib/integrations/ai/integration_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ class SerializedDict(IntegrationDict):
required=False,
default=dict,
help_text="Per-provider AI settings overrides. If a provider key is not "
"present, workspace settings are inherited. If present, these values "
"override workspace settings. Structure: "
"present, workspace settings are inherited. A complete connection uses "
"its own credentials and explicit model list; omitting models inherits "
"available models, while an empty list disables them. An incomplete "
"connection can only restrict inherited model availability. Structure: "
'{"openai": {"api_key": "...", "models": [...], "organization": ""}, ...}',
),
}
Expand All @@ -53,12 +55,14 @@ def prepare_values(
) -> Dict[str, Any]:
"""Validate explicit per-integration provider settings before saving.

Database-only providers are valid here because these overrides are passed
directly to the runtime instead of being stored in legacy workspace settings.
Database-only providers are valid here because complete overrides are passed
atomically to the runtime instead of being stored in legacy workspace settings.

:param values: The integration values supplied by the caller.
:param user: The user creating or updating the integration.
:return: The normalized values prepared by the base integration type.
:returns: The normalized values prepared by the base integration type.
:raises RequestBodyValidationException: If provider settings fail their
registered serializer's validation.
"""

if "ai_settings" not in values:
Expand All @@ -76,6 +80,24 @@ def prepare_values(

return super().prepare_values(values, user)

def get_integration_provider_settings(
self, integration: AIIntegration, provider_type: str
) -> dict[str, Any] | None:
"""
Return the integration-level settings override for a provider.

:param integration: The AI integration to read the override from.
:param provider_type: The generative AI provider type key.
:returns: The stored override, including an explicit empty dictionary, or
None when no dictionary is stored for this provider. This does not
validate whether the override defines a complete connection.
"""

provider_settings = integration.ai_settings.get(provider_type)
if isinstance(provider_settings, dict):
return provider_settings
return None

def get_provider_settings(
self, integration: AIIntegration, provider_type: str
) -> Dict[str, Any]:
Expand All @@ -87,15 +109,15 @@ def get_provider_settings(

:param integration: The AI integration whose provider settings are requested.
:param provider_type: The generative AI provider type.
:return: Explicit or legacy provider settings, or an empty dictionary when
:returns: Explicit or legacy provider settings, or an empty dictionary when
database-backed workspace inheritance should be used.
"""

# Check if provider has overrides in integration settings
if provider_type in integration.ai_settings:
provider_settings = integration.ai_settings[provider_type]
if isinstance(provider_settings, dict):
return provider_settings
provider_settings = self.get_integration_provider_settings(
integration, provider_type
)
if provider_settings is not None:
return provider_settings

if feature_flag_is_enabled(FF_AI_PROVIDERS):
return {}
Expand Down
Loading
Loading