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

from typing import Any

from goodmem._base import AsyncCRUDNamespace, CRUDNamespace
from goodmem._base import _op_meta, _expand_label_filters
from goodmem._base import _op_meta, _prepare_create_payload
from goodmem._generated.models.create_llm_response import CreateLLMResponse
from goodmem._generated.models.list_llms_response import ListLLMsResponse
from goodmem._generated.models.llm_creation_request import LLMCreationRequest
from goodmem._generated.models.llm_response import LLMResponse
from goodmem._generated.models.llm_update_request import LLMUpdateRequest
from goodmem.errors import raise_for_status


class LlmsAPIBase(CRUDNamespace):
    """Llms API — auto-generated structural base.

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

    _base_path = "/v1/llms"
    _create_model = LLMCreationRequest
    _update_model = LLMUpdateRequest
    _response_model = LLMResponse
    _create_response_model = CreateLLMResponse
    _list_response_model = ListLLMsResponse
    _list_items_field = "llms"
    _rest_metadata: dict = {'create': {'http_method': 'POST', 'path': '/v1/llms', 'response': 'CreateLLMResponse', 'body_model': 'LLMCreationRequest', 'body_expr': 'LLMCreationRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'get': {'http_method': 'GET', 'path': '/v1/llms/{id}', 'response': 'LLMResponse', 'query_params': ['id']}, 'list': {'http_method': 'GET', 'path': '/v1/llms', 'response': 'ListLLMsResponse', 'query_params': ['owner_id', 'provider_type', 'label.*'], 'supports_label_wildcard': True}, 'update': {'http_method': 'PUT', 'path': '/v1/llms/{id}', 'response': 'LLMResponse', 'query_params': ['id'], 'body_model': 'LLMUpdateRequest', 'body_expr': 'LLMUpdateRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'delete': {'http_method': 'DELETE', 'path': '/v1/llms/{id}', 'response': 'None', 'query_params': ['id']}}

    def create(self, **kwargs: Any) -> Any:
        """Create a new LLM

        Creates a new LLM configuration for text generation services. LLMs represent connections to different language model API services (like OpenAI, vLLM, etc.) and include all the necessary configuration to use them for text generation. DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if another LLM exists with identical {owner_id, provider_type, endpoint_url, api_path, model_identifier, credentials_fingerprint} after URL canonicalization. Uniqueness is enforced per-owner. Credentials are hashed (SHA-256) for uniqueness while remaining encrypted. The api_path field defaults to '/chat/completions' if omitted. Requires CREATE_LLM_OWN permission (or CREATE_LLM_ANY for admin users).

        Args:
            display_name (string): User-facing name of the LLM
            description (string, optional): Description of the LLM
            provider_type (LLMProviderType): Type of LLM provider
            endpoint_url (string): API endpoint base URL (OpenAI-compatible base, typically ends with /v1)
            api_path (string, optional): API path for chat/completions request (defaults to /chat/completions if not provided)
            model_identifier (string): Model identifier
            supported_modalities (array, optional): Supported content modalities (defaults to TEXT if not provided)
            credentials (EndpointAuthentication, optional): Structured credential payload describing how to authenticate with the provider. Omit for deployments that do not require credentials.
            labels (object, optional): User-defined labels for categorization
            version (string, optional): Version information
            monitoring_endpoint (string, optional): Monitoring endpoint URL
            capabilities (LLMCapabilities, optional): LLM capabilities defining supported features and modes. Optional - server infers capabilities from model identifier if not provided.
            default_sampling_params (LLMSamplingParams, optional): Default sampling parameters for generation requests
            max_context_length (integer, optional): Maximum context window size in tokens
            client_config (object, optional): Provider-specific client configuration as flexible JSON structure
            owner_id (string, optional): Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_LLM_ANY permission if specified.
            llm_id (string, 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:
            CreateLLMResponse
        """
        op = _op_meta(self, 'create')
        json_payload, data_payload, files_payload = _prepare_create_payload(
            create_model=self._create_model, op=op, kwargs=dict(kwargs),
        )
        resp = self._http.post(
            self._base_path,
            json=json_payload,
            data=data_payload,
            files=files_payload,
            headers=self._headers,
        )
        return self._handle_response(resp, self._create_response_model or self._response_model)

    def list(self, *, labels: dict[str, str] | None = None, **kwargs: Any) -> Any:
        """List LLMs

        Retrieves a list of LLM configurations accessible to the caller, with optional filtering. PERMISSION-BASED FILTERING: With LIST_LLM_OWN permission, you can only see your own LLMs (owner_id filter is ignored if set to another user). With LIST_LLM_ANY permission, you can see all LLMs or filter by any owner_id. This is a read-only operation with no side effects.

        Args:
            owner_id (string, optional): Filter LLMs by owner ID. With LIST_LLM_ANY permission, omitting this shows all accessible LLMs; providing it filters by that owner. With LIST_LLM_OWN permission, only your own LLMs are shown regardless of this parameter.
            provider_type (LLMProviderType, optional): Filter LLMs by provider type (e.g., OPENAI, VLLM, OLLAMA, etc.)
            label.* (string, optional): Filter by label value. Multiple label filters can be specified (e.g., ?label.environment=production&label.team=ai)

        Returns:
            ListLLMsResponse
        """
        op = _op_meta(self, 'list')
        params = _expand_label_filters(op=op, labels=labels, params=dict(kwargs))
        resp = self._http.get(
            self._base_path,
            params=params or None,
            headers=self._headers,
        )
        return self._handle_list_response(resp)

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

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

        Args:
            id (string): The unique identifier of the LLM to retrieve

        Returns:
            LLMResponse
        """
        resp = self._http.get(f"{self._base_path}/{id}", headers=self._headers)
        return self._handle_response(resp, self._response_model)

    def update(self, *, id: str, request: LLMUpdateRequest | dict) -> Any:
        """Update an LLM

        Updates an existing LLM 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. Requires UPDATE_LLM_OWN permission for LLMs you own (or UPDATE_LLM_ANY for admin users).

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

        Returns:
            LLMResponse
        """
        if isinstance(request, dict):
            request = LLMUpdateRequest.model_validate(request)
        resp = self._http.put(
            f"{self._base_path}/{id}",
            json=request.model_dump(by_alias=True, exclude_unset=True),
            headers=self._headers,
        )
        return self._handle_response(resp, self._response_model)

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

        Permanently deletes an LLM configuration. This operation cannot be undone and removes the LLM record and securely deletes stored credentials. IMPORTANT: This does NOT invalidate or delete any previously generated content using this LLM - existing generations remain accessible. Requires DELETE_LLM_OWN permission for LLMs you own (or DELETE_LLM_ANY for admin users).

        Args:
            id (string): The unique identifier of the LLM to delete
        """
        resp = self._http.delete(f"{self._base_path}/{id}", headers=self._headers)
        raise_for_status(resp)


class AsyncLlmsAPIBase(AsyncCRUDNamespace):
    """Async Llms API — auto-generated structural base.

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

    _base_path = "/v1/llms"
    _create_model = LLMCreationRequest
    _update_model = LLMUpdateRequest
    _response_model = LLMResponse
    _create_response_model = CreateLLMResponse
    _list_response_model = ListLLMsResponse
    _list_items_field = "llms"
    _rest_metadata: dict = {'create': {'http_method': 'POST', 'path': '/v1/llms', 'response': 'CreateLLMResponse', 'body_model': 'LLMCreationRequest', 'body_expr': 'LLMCreationRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'get': {'http_method': 'GET', 'path': '/v1/llms/{id}', 'response': 'LLMResponse', 'query_params': ['id']}, 'list': {'http_method': 'GET', 'path': '/v1/llms', 'response': 'ListLLMsResponse', 'query_params': ['owner_id', 'provider_type', 'label.*'], 'supports_label_wildcard': True}, 'update': {'http_method': 'PUT', 'path': '/v1/llms/{id}', 'response': 'LLMResponse', 'query_params': ['id'], 'body_model': 'LLMUpdateRequest', 'body_expr': 'LLMUpdateRequest(**kwargs)', 'body_kind': 'json', 'body_kinds': ['application/json']}, 'delete': {'http_method': 'DELETE', 'path': '/v1/llms/{id}', 'response': 'None', 'query_params': ['id']}}

    async def create(self, **kwargs: Any) -> Any:
        """Create a new LLM

        Creates a new LLM configuration for text generation services. LLMs represent connections to different language model API services (like OpenAI, vLLM, etc.) and include all the necessary configuration to use them for text generation. DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if another LLM exists with identical {owner_id, provider_type, endpoint_url, api_path, model_identifier, credentials_fingerprint} after URL canonicalization. Uniqueness is enforced per-owner. Credentials are hashed (SHA-256) for uniqueness while remaining encrypted. The api_path field defaults to '/chat/completions' if omitted. Requires CREATE_LLM_OWN permission (or CREATE_LLM_ANY for admin users).

        Args:
            display_name (string): User-facing name of the LLM
            description (string, optional): Description of the LLM
            provider_type (LLMProviderType): Type of LLM provider
            endpoint_url (string): API endpoint base URL (OpenAI-compatible base, typically ends with /v1)
            api_path (string, optional): API path for chat/completions request (defaults to /chat/completions if not provided)
            model_identifier (string): Model identifier
            supported_modalities (array, optional): Supported content modalities (defaults to TEXT if not provided)
            credentials (EndpointAuthentication, optional): Structured credential payload describing how to authenticate with the provider. Omit for deployments that do not require credentials.
            labels (object, optional): User-defined labels for categorization
            version (string, optional): Version information
            monitoring_endpoint (string, optional): Monitoring endpoint URL
            capabilities (LLMCapabilities, optional): LLM capabilities defining supported features and modes. Optional - server infers capabilities from model identifier if not provided.
            default_sampling_params (LLMSamplingParams, optional): Default sampling parameters for generation requests
            max_context_length (integer, optional): Maximum context window size in tokens
            client_config (object, optional): Provider-specific client configuration as flexible JSON structure
            owner_id (string, optional): Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_LLM_ANY permission if specified.
            llm_id (string, 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:
            CreateLLMResponse
        """
        op = _op_meta(self, 'create')
        json_payload, data_payload, files_payload = _prepare_create_payload(
            create_model=self._create_model, op=op, kwargs=dict(kwargs),
        )
        resp = await self._http.post(
            self._base_path,
            json=json_payload,
            data=data_payload,
            files=files_payload,
            headers=self._headers,
        )
        return self._handle_response(resp, self._create_response_model or self._response_model)

    async def list(self, *, labels: dict[str, str] | None = None, **kwargs: Any) -> Any:
        """List LLMs

        Retrieves a list of LLM configurations accessible to the caller, with optional filtering. PERMISSION-BASED FILTERING: With LIST_LLM_OWN permission, you can only see your own LLMs (owner_id filter is ignored if set to another user). With LIST_LLM_ANY permission, you can see all LLMs or filter by any owner_id. This is a read-only operation with no side effects.

        Args:
            owner_id (string, optional): Filter LLMs by owner ID. With LIST_LLM_ANY permission, omitting this shows all accessible LLMs; providing it filters by that owner. With LIST_LLM_OWN permission, only your own LLMs are shown regardless of this parameter.
            provider_type (LLMProviderType, optional): Filter LLMs by provider type (e.g., OPENAI, VLLM, OLLAMA, etc.)
            label.* (string, optional): Filter by label value. Multiple label filters can be specified (e.g., ?label.environment=production&label.team=ai)

        Returns:
            ListLLMsResponse
        """
        op = _op_meta(self, 'list')
        params = _expand_label_filters(op=op, labels=labels, params=dict(kwargs))
        resp = await self._http.get(
            self._base_path,
            params=params or None,
            headers=self._headers,
        )
        return self._handle_list_response(resp)

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

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

        Args:
            id (string): The unique identifier of the LLM to retrieve

        Returns:
            LLMResponse
        """
        resp = await self._http.get(f"{self._base_path}/{id}", headers=self._headers)
        return self._handle_response(resp, self._response_model)

    async def update(self, *, id: str, request: LLMUpdateRequest | dict) -> Any:
        """Update an LLM

        Updates an existing LLM 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. Requires UPDATE_LLM_OWN permission for LLMs you own (or UPDATE_LLM_ANY for admin users).

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

        Returns:
            LLMResponse
        """
        if isinstance(request, dict):
            request = LLMUpdateRequest.model_validate(request)
        resp = await self._http.put(
            f"{self._base_path}/{id}",
            json=request.model_dump(by_alias=True, exclude_unset=True),
            headers=self._headers,
        )
        return self._handle_response(resp, self._response_model)

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

        Permanently deletes an LLM configuration. This operation cannot be undone and removes the LLM record and securely deletes stored credentials. IMPORTANT: This does NOT invalidate or delete any previously generated content using this LLM - existing generations remain accessible. Requires DELETE_LLM_OWN permission for LLMs you own (or DELETE_LLM_ANY for admin users).

        Args:
            id (string): The unique identifier of the LLM to delete
        """
        resp = await self._http.delete(f"{self._base_path}/{id}", headers=self._headers)
        raise_for_status(resp)

