# DO NOT EDIT — generated by _gen/ from the OpenAPI spec.
# Regenerate with: ./client_gen.sh
from __future__ import annotations

from typing import Any

import httpx

from goodmem._base import _op_meta, _expand_label_filters
from goodmem._base import _op_meta, _prepare_create_payload
from goodmem.errors import raise_for_status
from goodmem.models.distribution_type import DistributionType
from goodmem.models.embedder_creation_request import EmbedderCreationRequest
from goodmem.models.embedder_response import EmbedderResponse
from goodmem.models.endpoint_authentication import EndpointAuthentication
from goodmem.models.list_embedders_response import ListEmbeddersResponse
from goodmem.models.provider_type import ProviderType
from goodmem.models.update_embedder_request import UpdateEmbedderRequest


class EmbeddersAPIBase:
    """Embedders API — auto-generated structural base.

    Auto-generated structural base. Do not edit.
    Override in goodmem/api/embedders.py to add domain-specific logic.
    """

    _create_model = EmbedderCreationRequest
    _rest_metadata: dict = {'create': {'http_method': 'POST', 'path': '/v1/embedders', 'input_shape': 'kwargs_body', 'summary': 'Create a new embedder', 'description': "Creates a new embedder configuration for vectorizing content. Embedders represent connections to different embedding API services (like OpenAI, vLLM, etc.) and include all the necessary configuration to use them with memory spaces. DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if another embedder exists with identical {ownerId, providerType, endpointUrl, apiPath, modelIdentifier, dimensionality, distributionType, credentialsFingerprint} after URL canonicalization. Uniqueness is enforced per-owner, allowing different users to have identical configurations. Credentials are hashed (SHA-256) for uniqueness while remaining encrypted. The apiPath field defaults to '/v2/embed' for Cohere, '/embed' for TEI, and '/embeddings' for other providers when omitted. Requires CREATE_EMBEDDER_OWN permission (or CREATE_EMBEDDER_ANY for admin users).", 'response': 'EmbedderResponse', 'params': [{'name': 'display_name', 'type': 'str', 'source': 'body', 'required': True, 'alias': 'displayName', 'description': 'User-facing name of the embedder'}, {'name': 'description', 'type': 'str', 'source': 'body', 'required': False, 'description': 'Description of the embedder'}, {'name': 'provider_type', 'type': 'ProviderType', 'source': 'body', 'required': True, 'alias': 'providerType', 'description': 'Type of embedding provider'}, {'name': 'endpoint_url', 'type': 'str', 'source': 'body', 'required': True, 'alias': 'endpointUrl', 'description': 'API endpoint URL'}, {'name': 'api_path', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'apiPath', 'description': 'API path for embeddings request (defaults: Cohere /v2/embed, TEI /embed, others /embeddings)'}, {'name': 'model_identifier', 'type': 'str', 'source': 'body', 'required': True, 'alias': 'modelIdentifier', 'description': 'Model identifier'}, {'name': 'dimensionality', 'type': 'int', 'source': 'body', 'required': True, 'description': 'Output vector dimensions'}, {'name': 'distribution_type', 'type': 'DistributionType', 'source': 'body', 'required': True, 'alias': 'distributionType', 'description': 'Type of embedding distribution (DENSE or SPARSE)'}, {'name': 'max_sequence_length', 'type': 'int', 'source': 'body', 'required': False, 'alias': 'maxSequenceLength', 'description': 'Maximum input sequence length'}, {'name': 'supported_modalities', 'type': 'list[Modality]', 'source': 'body', 'required': False, 'alias': 'supportedModalities', 'description': 'Supported content modalities (defaults to TEXT if not provided)', 'default': ['TEXT']}, {'name': 'credentials', 'type': 'EndpointAuthentication', 'source': 'body', 'required': False, 'description': 'Structured credential payload describing how to authenticate with the provider. Required for SaaS providers such as COHERE, JINA, and VOYAGE; optional for local or proxy providers.'}, {'name': 'labels', 'type': 'dict', 'source': 'body', 'required': False, 'description': 'User-defined labels for categorization'}, {'name': 'version', 'type': 'str', 'source': 'body', 'required': False, 'description': 'Version information'}, {'name': 'monitoring_endpoint', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'monitoringEndpoint', 'description': 'Monitoring endpoint URL'}, {'name': 'owner_id', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'ownerId', 'description': 'Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_EMBEDDER_ANY permission if specified.'}, {'name': 'embedder_id', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'embedderId', 'description': 'Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.'}], 'body_model': 'EmbedderCreationRequest', 'body_expr': 'EmbedderCreationRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'get': {'http_method': 'GET', 'path': '/v1/embedders/{id}', 'input_shape': 'path_query', 'summary': 'Get an embedder by ID', 'description': "Retrieves the details of a specific embedder configuration by its unique identifier. Requires READ_EMBEDDER_OWN permission for embedders you own (or READ_EMBEDDER_ANY for admin users to view any user's embedders). This is a read-only operation with no side effects.", 'response': 'EmbedderResponse', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the embedder to retrieve'}]}, 'list': {'http_method': 'GET', 'path': '/v1/embedders', 'input_shape': 'query_only', 'summary': 'List embedders', 'description': 'Retrieves a list of embedder configurations accessible to the caller, with optional filtering. LABEL FILTERS: Supply dynamic query parameters in the form label.<key>=<value> (for example, label.environment=production). PERMISSION-BASED FILTERING: With LIST_EMBEDDER_OWN permission, you can only see your own embedders (ownerId filter is ignored if set to another user). With LIST_EMBEDDER_ANY permission, you can see all embedders or filter by any ownerId. This is a read-only operation with no side effects.', 'response': 'ListEmbeddersResponse', 'query_params': ['owner_id', 'provider_type', 'label.*'], 'params': [{'name': 'owner_id', 'type': 'str', 'source': 'query', 'required': False, 'alias': 'ownerId', 'description': 'Filter embedders by owner ID. With LIST_EMBEDDER_ANY permission, omitting this shows all accessible embedders; providing it filters by that owner. With LIST_EMBEDDER_OWN permission, only your own embedders are shown regardless of this parameter.'}, {'name': 'provider_type', 'type': 'ProviderType', 'source': 'query', 'required': False, 'alias': 'providerType', 'description': 'Filter embedders by provider type. Allowed values match the ProviderType schema.'}, {'name': 'label.*', 'type': 'str', 'source': 'query', 'required': False, 'description': 'Filter by label value. Multiple label filters can be specified (e.g., ?label.environment=production&label.team=nlp)'}], 'supports_label_wildcard': True}, 'update': {'http_method': 'PUT', 'path': '/v1/embedders/{id}', 'input_shape': 'typed_request', 'summary': 'Update an embedder', 'description': 'Updates an existing embedder configuration including display information, endpoint configuration, model parameters, credentials, and labels. All fields are optional - only specified fields will be updated. IMPORTANT: providerType is IMMUTABLE after creation and cannot be changed. CRITICAL: Returns HTTP 412 Precondition Failed (FAILED_PRECONDITION) if attempting to update core fields (dimensionality, distributionType, modelIdentifier) while the embedder is actively referenced by spaces or ingestion jobs. Requires UPDATE_EMBEDDER_OWN permission for embedders you own (or UPDATE_EMBEDDER_ANY for admin users). DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if the update would create a duplicate embedder with the same provider, endpoint, model, dimensionality, distribution, and credentials for this owner. ', 'response': 'EmbedderResponse', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the embedder to update'}, {'name': 'display_name', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'displayName', 'description': 'User-facing name of the embedder'}, {'name': 'description', 'type': 'str', 'source': 'body', 'required': False, 'description': 'Description of the embedder'}, {'name': 'endpoint_url', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'endpointUrl', 'description': 'API endpoint URL'}, {'name': 'api_path', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'apiPath', 'description': 'API path for embeddings request'}, {'name': 'model_identifier', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'modelIdentifier', 'description': 'Model identifier'}, {'name': 'dimensionality', 'type': 'int', 'source': 'body', 'required': False, 'description': 'Output vector dimensions'}, {'name': 'max_sequence_length', 'type': 'int', 'source': 'body', 'required': False, 'alias': 'maxSequenceLength', 'description': 'Maximum input sequence length'}, {'name': 'supported_modalities', 'type': 'list[Modality]', 'source': 'body', 'required': False, 'alias': 'supportedModalities', 'description': 'Supported content modalities'}, {'name': 'credentials', 'type': 'EndpointAuthentication', 'source': 'body', 'required': False, 'description': 'Structured credential payload describing how to authenticate with the provider'}, {'name': 'replace_labels', 'type': 'dict', 'source': 'body', 'required': False, 'alias': 'replaceLabels', 'description': 'Replace all existing labels with these (mutually exclusive with mergeLabels)'}, {'name': 'merge_labels', 'type': 'dict', 'source': 'body', 'required': False, 'alias': 'mergeLabels', 'description': 'Merge these labels with existing ones (mutually exclusive with replaceLabels)'}, {'name': 'version', 'type': 'str', 'source': 'body', 'required': False, 'description': 'Version information'}, {'name': 'monitoring_endpoint', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'monitoringEndpoint', 'description': 'Monitoring endpoint URL'}], 'body_model': 'UpdateEmbedderRequest', 'body_expr': 'UpdateEmbedderRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'delete': {'http_method': 'DELETE', 'path': '/v1/embedders/{id}', 'input_shape': 'path_query', 'summary': 'Delete an embedder', 'description': 'Permanently deletes an embedder configuration. This operation cannot be undone and removes the embedder record and securely deletes stored credentials. IMPORTANT: This does NOT invalidate or delete embeddings previously created with this embedder - existing embeddings remain accessible. CONFLICT: Returns HTTP 409 Conflict if the embedder is still referenced by a space. Requires DELETE_EMBEDDER_OWN permission for embedders you own (or DELETE_EMBEDDER_ANY for admin users).', 'response': 'None', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the embedder to delete'}]}}

    def __init__(self, http: httpx.Client, headers: dict[str, str]) -> None:
        self._http = http
        self._headers = headers

    def create(self, *, display_name: str | None=None, description: str | None=None, provider_type: ProviderType | None=None, endpoint_url: str | None=None, api_path: str | None=None, model_identifier: str | None=None, dimensionality: int | None=None, distribution_type: DistributionType | None=None, max_sequence_length: int | None=None, supported_modalities: list | None=('TEXT',), credentials: EndpointAuthentication | None=None, labels: dict | None=None, version: str | None=None, monitoring_endpoint: str | None=None, owner_id: str | None=None, embedder_id: str | None=None) -> EmbedderResponse:
        """Create a new embedder

        Creates a new embedder configuration for vectorizing content. Embedders represent connections to different embedding API services (like OpenAI, vLLM, etc.) and include all the necessary configuration to use them with memory spaces. DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if another embedder exists with identical {owner_id, provider_type, endpoint_url, api_path, model_identifier, dimensionality, distribution_type, credentials_fingerprint} after URL canonicalization. Uniqueness is enforced per-owner, allowing different users to have identical configurations. Credentials are hashed (SHA-256) for uniqueness while remaining encrypted. The api_path field defaults to '/v2/embed' for Cohere, '/embed' for TEI, and '/embeddings' for other providers when omitted. Requires CREATE_EMBEDDER_OWN permission (or CREATE_EMBEDDER_ANY for admin users).

        Args:
            display_name (str): User-facing name of the embedder
            description (str, optional): Description of the embedder
            provider_type (ProviderType): Type of embedding provider
            endpoint_url (str): API endpoint URL
            api_path (str, optional): API path for embeddings request (defaults: Cohere /v2/embed, TEI /embed, others /embeddings)
            model_identifier (str): Model identifier
            dimensionality (int): Output vector dimensions
            distribution_type (DistributionType): Type of embedding distribution (DENSE or SPARSE)
            max_sequence_length (int, optional): Maximum input sequence length
            supported_modalities (list, optional, default=['TEXT']): Supported content modalities (defaults to TEXT if not provided)
            credentials (EndpointAuthentication, optional): Structured credential payload describing how to authenticate with the provider. Required for SaaS providers such as COHERE, JINA, and VOYAGE; optional for local or proxy providers.
            labels (dict, optional): User-defined labels for categorization
            version (str, optional): Version information
            monitoring_endpoint (str, optional): Monitoring endpoint URL
            owner_id (str, optional): Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_EMBEDDER_ANY permission if specified.
            embedder_id (str, optional): Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.

        Returns:
            EmbedderResponse
        """
        op = _op_meta(self, 'create')
        _params: dict = {}
        if display_name is not None:
            _params['display_name'] = display_name
        if description is not None:
            _params['description'] = description
        if provider_type is not None:
            _params['provider_type'] = provider_type
        if endpoint_url is not None:
            _params['endpoint_url'] = endpoint_url
        if api_path is not None:
            _params['api_path'] = api_path
        if model_identifier is not None:
            _params['model_identifier'] = model_identifier
        if dimensionality is not None:
            _params['dimensionality'] = dimensionality
        if distribution_type is not None:
            _params['distribution_type'] = distribution_type
        if max_sequence_length is not None:
            _params['max_sequence_length'] = max_sequence_length
        _params['supported_modalities'] = supported_modalities
        if credentials is not None:
            _params['credentials'] = credentials
        if labels is not None:
            _params['labels'] = labels
        if version is not None:
            _params['version'] = version
        if monitoring_endpoint is not None:
            _params['monitoring_endpoint'] = monitoring_endpoint
        if owner_id is not None:
            _params['owner_id'] = owner_id
        if embedder_id is not None:
            _params['embedder_id'] = embedder_id
        json_payload, data_payload, files_payload = _prepare_create_payload(
            create_model=EmbedderCreationRequest, op=op, kwargs=_params,
        )
        resp = self._http.post(
            "/v1/embedders",
            json=json_payload,
            data=data_payload,
            files=files_payload,
            headers=self._headers,
        )
        raise_for_status(resp)
        return EmbedderResponse.model_validate(resp.json())

    def list(self, *, labels: dict[str, str] | None = None, owner_id: str | None=None, provider_type: ProviderType | None=None) -> list[EmbedderResponse]:
        """List embedders

        Retrieves a list of embedder configurations accessible to the caller, with optional filtering. LABEL FILTERS: Supply dynamic query parameters in the form label.<key>=<value> (for example, label.environment=production). PERMISSION-BASED FILTERING: With LIST_EMBEDDER_OWN permission, you can only see your own embedders (owner_id filter is ignored if set to another user). With LIST_EMBEDDER_ANY permission, you can see all embedders or filter by any owner_id. This is a read-only operation with no side effects.

        Args:
            owner_id (str, optional): Filter embedders by owner ID. With LIST_EMBEDDER_ANY permission, omitting this shows all accessible embedders; providing it filters by that owner. With LIST_EMBEDDER_OWN permission, only your own embedders are shown regardless of this parameter.
            provider_type (ProviderType, optional): Filter embedders by provider type. Allowed values match the ProviderType schema.
            label.* (str, optional): Filter by label value. Multiple label filters can be specified (e.g., ?label.environment=production&label.team=nlp)

        Returns:
            list[EmbedderResponse]
        """
        op = _op_meta(self, 'list')
        _params: dict = {}
        if owner_id is not None:
            _params['owner_id'] = owner_id
        if provider_type is not None:
            _params['provider_type'] = provider_type
        params = _expand_label_filters(op=op, labels=labels, params=_params)
        resp = self._http.get(
            "/v1/embedders",
            params=params or None,
            headers=self._headers,
        )
        raise_for_status(resp)
        wrapper = ListEmbeddersResponse.model_validate(resp.json())
        return getattr(wrapper, 'embedders', [])

    def get(self, *, id: str) -> EmbedderResponse:
        """Get an embedder by ID

        Retrieves the details of a specific embedder configuration by its unique identifier. Requires READ_EMBEDDER_OWN permission for embedders you own (or READ_EMBEDDER_ANY for admin users to view any user's embedders). This is a read-only operation with no side effects.

        Args:
            id (str): The unique identifier of the embedder to retrieve

        Returns:
            EmbedderResponse
        """
        resp = self._http.get(
            f"/v1/embedders/{id}",
            headers=self._headers,
        )
        raise_for_status(resp)
        return EmbedderResponse.model_validate(resp.json())

    def update(self, *, id: str, request: UpdateEmbedderRequest | dict) -> EmbedderResponse:
        """Update an embedder

        Updates an existing embedder configuration including display information, endpoint configuration, model parameters, credentials, and labels. All fields are optional - only specified fields will be updated. IMPORTANT: provider_type is IMMUTABLE after creation and cannot be changed. CRITICAL: Returns HTTP 412 Precondition Failed (FAILED_PRECONDITION) if attempting to update core fields (dimensionality, distribution_type, model_identifier) while the embedder is actively referenced by spaces or ingestion jobs. Requires UPDATE_EMBEDDER_OWN permission for embedders you own (or UPDATE_EMBEDDER_ANY for admin users). DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if the update would create a duplicate embedder with the same provider, endpoint, model, dimensionality, distribution, and credentials for this owner.

        Args:
            id (str): The unique identifier of the embedder to update.
            request (UpdateEmbedderRequest | dict): The update payload. Accepts a UpdateEmbedderRequest instance or a plain dict with the same fields. Only specified fields will be modified.

        Returns:
            EmbedderResponse
        """
        if isinstance(request, dict):
            request = UpdateEmbedderRequest.model_validate(request)
        resp = self._http.put(
            f"/v1/embedders/{id}",
            json=request.model_dump(by_alias=True, exclude_unset=True),
            headers=self._headers,
        )
        raise_for_status(resp)
        return EmbedderResponse.model_validate(resp.json())

    def delete(self, *, id: str) -> None:
        """Delete an embedder

        Permanently deletes an embedder configuration. This operation cannot be undone and removes the embedder record and securely deletes stored credentials. IMPORTANT: This does NOT invalidate or delete embeddings previously created with this embedder - existing embeddings remain accessible. CONFLICT: Returns HTTP 409 Conflict if the embedder is still referenced by a space. Requires DELETE_EMBEDDER_OWN permission for embedders you own (or DELETE_EMBEDDER_ANY for admin users).

        Args:
            id (str): The unique identifier of the embedder to delete
        """
        resp = self._http.delete(
            f"/v1/embedders/{id}",
            headers=self._headers,
        )
        raise_for_status(resp)


class AsyncEmbeddersAPIBase:
    """Async Embedders API — auto-generated structural base.

    Auto-generated structural base. Do not edit.
    Override in goodmem/api/embedders.py to add domain-specific logic.
    """

    _create_model = EmbedderCreationRequest
    _rest_metadata: dict = {'create': {'http_method': 'POST', 'path': '/v1/embedders', 'input_shape': 'kwargs_body', 'summary': 'Create a new embedder', 'description': "Creates a new embedder configuration for vectorizing content. Embedders represent connections to different embedding API services (like OpenAI, vLLM, etc.) and include all the necessary configuration to use them with memory spaces. DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if another embedder exists with identical {ownerId, providerType, endpointUrl, apiPath, modelIdentifier, dimensionality, distributionType, credentialsFingerprint} after URL canonicalization. Uniqueness is enforced per-owner, allowing different users to have identical configurations. Credentials are hashed (SHA-256) for uniqueness while remaining encrypted. The apiPath field defaults to '/v2/embed' for Cohere, '/embed' for TEI, and '/embeddings' for other providers when omitted. Requires CREATE_EMBEDDER_OWN permission (or CREATE_EMBEDDER_ANY for admin users).", 'response': 'EmbedderResponse', 'params': [{'name': 'display_name', 'type': 'str', 'source': 'body', 'required': True, 'alias': 'displayName', 'description': 'User-facing name of the embedder'}, {'name': 'description', 'type': 'str', 'source': 'body', 'required': False, 'description': 'Description of the embedder'}, {'name': 'provider_type', 'type': 'ProviderType', 'source': 'body', 'required': True, 'alias': 'providerType', 'description': 'Type of embedding provider'}, {'name': 'endpoint_url', 'type': 'str', 'source': 'body', 'required': True, 'alias': 'endpointUrl', 'description': 'API endpoint URL'}, {'name': 'api_path', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'apiPath', 'description': 'API path for embeddings request (defaults: Cohere /v2/embed, TEI /embed, others /embeddings)'}, {'name': 'model_identifier', 'type': 'str', 'source': 'body', 'required': True, 'alias': 'modelIdentifier', 'description': 'Model identifier'}, {'name': 'dimensionality', 'type': 'int', 'source': 'body', 'required': True, 'description': 'Output vector dimensions'}, {'name': 'distribution_type', 'type': 'DistributionType', 'source': 'body', 'required': True, 'alias': 'distributionType', 'description': 'Type of embedding distribution (DENSE or SPARSE)'}, {'name': 'max_sequence_length', 'type': 'int', 'source': 'body', 'required': False, 'alias': 'maxSequenceLength', 'description': 'Maximum input sequence length'}, {'name': 'supported_modalities', 'type': 'list[Modality]', 'source': 'body', 'required': False, 'alias': 'supportedModalities', 'description': 'Supported content modalities (defaults to TEXT if not provided)', 'default': ['TEXT']}, {'name': 'credentials', 'type': 'EndpointAuthentication', 'source': 'body', 'required': False, 'description': 'Structured credential payload describing how to authenticate with the provider. Required for SaaS providers such as COHERE, JINA, and VOYAGE; optional for local or proxy providers.'}, {'name': 'labels', 'type': 'dict', 'source': 'body', 'required': False, 'description': 'User-defined labels for categorization'}, {'name': 'version', 'type': 'str', 'source': 'body', 'required': False, 'description': 'Version information'}, {'name': 'monitoring_endpoint', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'monitoringEndpoint', 'description': 'Monitoring endpoint URL'}, {'name': 'owner_id', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'ownerId', 'description': 'Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_EMBEDDER_ANY permission if specified.'}, {'name': 'embedder_id', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'embedderId', 'description': 'Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.'}], 'body_model': 'EmbedderCreationRequest', 'body_expr': 'EmbedderCreationRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'get': {'http_method': 'GET', 'path': '/v1/embedders/{id}', 'input_shape': 'path_query', 'summary': 'Get an embedder by ID', 'description': "Retrieves the details of a specific embedder configuration by its unique identifier. Requires READ_EMBEDDER_OWN permission for embedders you own (or READ_EMBEDDER_ANY for admin users to view any user's embedders). This is a read-only operation with no side effects.", 'response': 'EmbedderResponse', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the embedder to retrieve'}]}, 'list': {'http_method': 'GET', 'path': '/v1/embedders', 'input_shape': 'query_only', 'summary': 'List embedders', 'description': 'Retrieves a list of embedder configurations accessible to the caller, with optional filtering. LABEL FILTERS: Supply dynamic query parameters in the form label.<key>=<value> (for example, label.environment=production). PERMISSION-BASED FILTERING: With LIST_EMBEDDER_OWN permission, you can only see your own embedders (ownerId filter is ignored if set to another user). With LIST_EMBEDDER_ANY permission, you can see all embedders or filter by any ownerId. This is a read-only operation with no side effects.', 'response': 'ListEmbeddersResponse', 'query_params': ['owner_id', 'provider_type', 'label.*'], 'params': [{'name': 'owner_id', 'type': 'str', 'source': 'query', 'required': False, 'alias': 'ownerId', 'description': 'Filter embedders by owner ID. With LIST_EMBEDDER_ANY permission, omitting this shows all accessible embedders; providing it filters by that owner. With LIST_EMBEDDER_OWN permission, only your own embedders are shown regardless of this parameter.'}, {'name': 'provider_type', 'type': 'ProviderType', 'source': 'query', 'required': False, 'alias': 'providerType', 'description': 'Filter embedders by provider type. Allowed values match the ProviderType schema.'}, {'name': 'label.*', 'type': 'str', 'source': 'query', 'required': False, 'description': 'Filter by label value. Multiple label filters can be specified (e.g., ?label.environment=production&label.team=nlp)'}], 'supports_label_wildcard': True}, 'update': {'http_method': 'PUT', 'path': '/v1/embedders/{id}', 'input_shape': 'typed_request', 'summary': 'Update an embedder', 'description': 'Updates an existing embedder configuration including display information, endpoint configuration, model parameters, credentials, and labels. All fields are optional - only specified fields will be updated. IMPORTANT: providerType is IMMUTABLE after creation and cannot be changed. CRITICAL: Returns HTTP 412 Precondition Failed (FAILED_PRECONDITION) if attempting to update core fields (dimensionality, distributionType, modelIdentifier) while the embedder is actively referenced by spaces or ingestion jobs. Requires UPDATE_EMBEDDER_OWN permission for embedders you own (or UPDATE_EMBEDDER_ANY for admin users). DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if the update would create a duplicate embedder with the same provider, endpoint, model, dimensionality, distribution, and credentials for this owner. ', 'response': 'EmbedderResponse', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the embedder to update'}, {'name': 'display_name', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'displayName', 'description': 'User-facing name of the embedder'}, {'name': 'description', 'type': 'str', 'source': 'body', 'required': False, 'description': 'Description of the embedder'}, {'name': 'endpoint_url', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'endpointUrl', 'description': 'API endpoint URL'}, {'name': 'api_path', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'apiPath', 'description': 'API path for embeddings request'}, {'name': 'model_identifier', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'modelIdentifier', 'description': 'Model identifier'}, {'name': 'dimensionality', 'type': 'int', 'source': 'body', 'required': False, 'description': 'Output vector dimensions'}, {'name': 'max_sequence_length', 'type': 'int', 'source': 'body', 'required': False, 'alias': 'maxSequenceLength', 'description': 'Maximum input sequence length'}, {'name': 'supported_modalities', 'type': 'list[Modality]', 'source': 'body', 'required': False, 'alias': 'supportedModalities', 'description': 'Supported content modalities'}, {'name': 'credentials', 'type': 'EndpointAuthentication', 'source': 'body', 'required': False, 'description': 'Structured credential payload describing how to authenticate with the provider'}, {'name': 'replace_labels', 'type': 'dict', 'source': 'body', 'required': False, 'alias': 'replaceLabels', 'description': 'Replace all existing labels with these (mutually exclusive with mergeLabels)'}, {'name': 'merge_labels', 'type': 'dict', 'source': 'body', 'required': False, 'alias': 'mergeLabels', 'description': 'Merge these labels with existing ones (mutually exclusive with replaceLabels)'}, {'name': 'version', 'type': 'str', 'source': 'body', 'required': False, 'description': 'Version information'}, {'name': 'monitoring_endpoint', 'type': 'str', 'source': 'body', 'required': False, 'alias': 'monitoringEndpoint', 'description': 'Monitoring endpoint URL'}], 'body_model': 'UpdateEmbedderRequest', 'body_expr': 'UpdateEmbedderRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'delete': {'http_method': 'DELETE', 'path': '/v1/embedders/{id}', 'input_shape': 'path_query', 'summary': 'Delete an embedder', 'description': 'Permanently deletes an embedder configuration. This operation cannot be undone and removes the embedder record and securely deletes stored credentials. IMPORTANT: This does NOT invalidate or delete embeddings previously created with this embedder - existing embeddings remain accessible. CONFLICT: Returns HTTP 409 Conflict if the embedder is still referenced by a space. Requires DELETE_EMBEDDER_OWN permission for embedders you own (or DELETE_EMBEDDER_ANY for admin users).', 'response': 'None', 'query_params': ['id'], 'params': [{'name': 'id', 'type': 'str', 'source': 'path', 'required': True, 'description': 'The unique identifier of the embedder to delete'}]}}

    def __init__(self, http: httpx.AsyncClient, headers: dict[str, str]) -> None:
        self._http = http
        self._headers = headers

    async def create(self, *, display_name: str | None=None, description: str | None=None, provider_type: ProviderType | None=None, endpoint_url: str | None=None, api_path: str | None=None, model_identifier: str | None=None, dimensionality: int | None=None, distribution_type: DistributionType | None=None, max_sequence_length: int | None=None, supported_modalities: list | None=('TEXT',), credentials: EndpointAuthentication | None=None, labels: dict | None=None, version: str | None=None, monitoring_endpoint: str | None=None, owner_id: str | None=None, embedder_id: str | None=None) -> EmbedderResponse:
        """Create a new embedder

        Creates a new embedder configuration for vectorizing content. Embedders represent connections to different embedding API services (like OpenAI, vLLM, etc.) and include all the necessary configuration to use them with memory spaces. DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if another embedder exists with identical {owner_id, provider_type, endpoint_url, api_path, model_identifier, dimensionality, distribution_type, credentials_fingerprint} after URL canonicalization. Uniqueness is enforced per-owner, allowing different users to have identical configurations. Credentials are hashed (SHA-256) for uniqueness while remaining encrypted. The api_path field defaults to '/v2/embed' for Cohere, '/embed' for TEI, and '/embeddings' for other providers when omitted. Requires CREATE_EMBEDDER_OWN permission (or CREATE_EMBEDDER_ANY for admin users).

        Args:
            display_name (str): User-facing name of the embedder
            description (str, optional): Description of the embedder
            provider_type (ProviderType): Type of embedding provider
            endpoint_url (str): API endpoint URL
            api_path (str, optional): API path for embeddings request (defaults: Cohere /v2/embed, TEI /embed, others /embeddings)
            model_identifier (str): Model identifier
            dimensionality (int): Output vector dimensions
            distribution_type (DistributionType): Type of embedding distribution (DENSE or SPARSE)
            max_sequence_length (int, optional): Maximum input sequence length
            supported_modalities (list, optional, default=['TEXT']): Supported content modalities (defaults to TEXT if not provided)
            credentials (EndpointAuthentication, optional): Structured credential payload describing how to authenticate with the provider. Required for SaaS providers such as COHERE, JINA, and VOYAGE; optional for local or proxy providers.
            labels (dict, optional): User-defined labels for categorization
            version (str, optional): Version information
            monitoring_endpoint (str, optional): Monitoring endpoint URL
            owner_id (str, optional): Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_EMBEDDER_ANY permission if specified.
            embedder_id (str, optional): Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.

        Returns:
            EmbedderResponse
        """
        op = _op_meta(self, 'create')
        _params: dict = {}
        if display_name is not None:
            _params['display_name'] = display_name
        if description is not None:
            _params['description'] = description
        if provider_type is not None:
            _params['provider_type'] = provider_type
        if endpoint_url is not None:
            _params['endpoint_url'] = endpoint_url
        if api_path is not None:
            _params['api_path'] = api_path
        if model_identifier is not None:
            _params['model_identifier'] = model_identifier
        if dimensionality is not None:
            _params['dimensionality'] = dimensionality
        if distribution_type is not None:
            _params['distribution_type'] = distribution_type
        if max_sequence_length is not None:
            _params['max_sequence_length'] = max_sequence_length
        _params['supported_modalities'] = supported_modalities
        if credentials is not None:
            _params['credentials'] = credentials
        if labels is not None:
            _params['labels'] = labels
        if version is not None:
            _params['version'] = version
        if monitoring_endpoint is not None:
            _params['monitoring_endpoint'] = monitoring_endpoint
        if owner_id is not None:
            _params['owner_id'] = owner_id
        if embedder_id is not None:
            _params['embedder_id'] = embedder_id
        json_payload, data_payload, files_payload = _prepare_create_payload(
            create_model=EmbedderCreationRequest, op=op, kwargs=_params,
        )
        resp = await self._http.post(
            "/v1/embedders",
            json=json_payload,
            data=data_payload,
            files=files_payload,
            headers=self._headers,
        )
        raise_for_status(resp)
        return EmbedderResponse.model_validate(resp.json())

    async def list(self, *, labels: dict[str, str] | None = None, owner_id: str | None=None, provider_type: ProviderType | None=None) -> list[EmbedderResponse]:
        """List embedders

        Retrieves a list of embedder configurations accessible to the caller, with optional filtering. LABEL FILTERS: Supply dynamic query parameters in the form label.<key>=<value> (for example, label.environment=production). PERMISSION-BASED FILTERING: With LIST_EMBEDDER_OWN permission, you can only see your own embedders (owner_id filter is ignored if set to another user). With LIST_EMBEDDER_ANY permission, you can see all embedders or filter by any owner_id. This is a read-only operation with no side effects.

        Args:
            owner_id (str, optional): Filter embedders by owner ID. With LIST_EMBEDDER_ANY permission, omitting this shows all accessible embedders; providing it filters by that owner. With LIST_EMBEDDER_OWN permission, only your own embedders are shown regardless of this parameter.
            provider_type (ProviderType, optional): Filter embedders by provider type. Allowed values match the ProviderType schema.
            label.* (str, optional): Filter by label value. Multiple label filters can be specified (e.g., ?label.environment=production&label.team=nlp)

        Returns:
            list[EmbedderResponse]
        """
        op = _op_meta(self, 'list')
        _params: dict = {}
        if owner_id is not None:
            _params['owner_id'] = owner_id
        if provider_type is not None:
            _params['provider_type'] = provider_type
        params = _expand_label_filters(op=op, labels=labels, params=_params)
        resp = await self._http.get(
            "/v1/embedders",
            params=params or None,
            headers=self._headers,
        )
        raise_for_status(resp)
        wrapper = ListEmbeddersResponse.model_validate(resp.json())
        return getattr(wrapper, 'embedders', [])

    async def get(self, *, id: str) -> EmbedderResponse:
        """Get an embedder by ID

        Retrieves the details of a specific embedder configuration by its unique identifier. Requires READ_EMBEDDER_OWN permission for embedders you own (or READ_EMBEDDER_ANY for admin users to view any user's embedders). This is a read-only operation with no side effects.

        Args:
            id (str): The unique identifier of the embedder to retrieve

        Returns:
            EmbedderResponse
        """
        resp = await self._http.get(
            f"/v1/embedders/{id}",
            headers=self._headers,
        )
        raise_for_status(resp)
        return EmbedderResponse.model_validate(resp.json())

    async def update(self, *, id: str, request: UpdateEmbedderRequest | dict) -> EmbedderResponse:
        """Update an embedder

        Updates an existing embedder configuration including display information, endpoint configuration, model parameters, credentials, and labels. All fields are optional - only specified fields will be updated. IMPORTANT: provider_type is IMMUTABLE after creation and cannot be changed. CRITICAL: Returns HTTP 412 Precondition Failed (FAILED_PRECONDITION) if attempting to update core fields (dimensionality, distribution_type, model_identifier) while the embedder is actively referenced by spaces or ingestion jobs. Requires UPDATE_EMBEDDER_OWN permission for embedders you own (or UPDATE_EMBEDDER_ANY for admin users). DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if the update would create a duplicate embedder with the same provider, endpoint, model, dimensionality, distribution, and credentials for this owner.

        Args:
            id (str): The unique identifier of the embedder to update.
            request (UpdateEmbedderRequest | dict): The update payload. Accepts a UpdateEmbedderRequest instance or a plain dict with the same fields. Only specified fields will be modified.

        Returns:
            EmbedderResponse
        """
        if isinstance(request, dict):
            request = UpdateEmbedderRequest.model_validate(request)
        resp = await self._http.put(
            f"/v1/embedders/{id}",
            json=request.model_dump(by_alias=True, exclude_unset=True),
            headers=self._headers,
        )
        raise_for_status(resp)
        return EmbedderResponse.model_validate(resp.json())

    async def delete(self, *, id: str) -> None:
        """Delete an embedder

        Permanently deletes an embedder configuration. This operation cannot be undone and removes the embedder record and securely deletes stored credentials. IMPORTANT: This does NOT invalidate or delete embeddings previously created with this embedder - existing embeddings remain accessible. CONFLICT: Returns HTTP 409 Conflict if the embedder is still referenced by a space. Requires DELETE_EMBEDDER_OWN permission for embedders you own (or DELETE_EMBEDDER_ANY for admin users).

        Args:
            id (str): The unique identifier of the embedder to delete
        """
        resp = await self._http.delete(
            f"/v1/embedders/{id}",
            headers=self._headers,
        )
        raise_for_status(resp)

