# DO NOT EDIT — generated by _client_gen/convenience_emitter.py from convenience.json.
# Regenerate with: cd clients/v2 && python -c "from _client_gen.convenience_emitter import generate_convenience; generate_convenience()"

"""Llms API namespace — generated from convenience.json."""

from __future__ import annotations

from typing import Any

from goodmem._api_base.llms import LlmsAPIBase, AsyncLlmsAPIBase


# --- Convenience imports ---
from goodmem._transforms import apply_convenience_transforms
from goodmem.models.create_llm_response import CreateLLMResponse
from goodmem.models.endpoint_authentication import EndpointAuthentication
from goodmem.models.llm_capabilities import LLMCapabilities
from goodmem.models.llm_provider_type import LLMProviderType
from goodmem.models.llm_response import LLMResponse
from goodmem.models.llm_sampling_params import LLMSamplingParams
from goodmem.models.modality import Modality


class LlmsAPI(LlmsAPIBase):
    def create(self, *, display_name: str, model_identifier: str, api_key: str | None = None, api_path: str | None = None, capabilities: LLMCapabilities | None = None, client_config: dict[str, Any] | None = None, credentials: EndpointAuthentication | None = None, default_sampling_params: LLMSamplingParams | None = None, description: str | None = None, endpoint_url: str | None = None, labels: dict[str, str] | None = None, llm_id: str | None = None, max_context_length: int | None = None, monitoring_endpoint: str | None = None, owner_id: str | None = None, provider_type: LLMProviderType | None = None, supported_modalities: list[Modality] | None = None, version: str | None = None) -> CreateLLMResponse:
        """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 (str): User-facing name of the LLM
            model_identifier (str): When a known model, auto-fills `provider_type`, `endpoint_url`, `max_context_length`, and `supported_modalities` for 34 registered models.
            api_key (str, optional): Converts a plain API key string to the full `EndpointAuthentication` structure (i.e. `{"kind": "CREDENTIAL_KIND_API_KEY", "api_key": {"inline_secret": "sk-..."}}`).
            api_path (str, optional, server default='/chat/completions'): API path for chat/completions request (defaults to `/chat/completions` if not provided).
            capabilities (LLMCapabilities, optional): LLM capabilities defining supported features and modes. Optional — server infers capabilities from model identifier if not provided.
            client_config (dict[str, Any], optional): Provider-specific client configuration as flexible JSON structure
            credentials (EndpointAuthentication, optional): Structured credential payload describing how to authenticate with the provider.
            default_sampling_params (LLMSamplingParams, optional): Default sampling parameters for generation requests
            description (str, optional): Description of the LLM
            endpoint_url (str, optional): Base URL for the LLM endpoint (OpenAI-compatible base, typically ends with `/v1`). Auto-inferred from `provider_type` for known providers; required when `model_identifier` is not in the registry.
            labels (dict[str, str], optional): User-defined labels for categorization
            llm_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.
            max_context_length (int, optional): Maximum context window size in tokens. Auto-inferred from `model_identifier` for known models; recommended when `model_identifier` is not in the registry.
            monitoring_endpoint (str, optional): Monitoring endpoint URL
            owner_id (str, optional): Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_LLM_ANY permission if specified.
            provider_type (LLMProviderType, optional): Provider backend — one of `"OPENAI"`, `"LITELLM_PROXY"`, `"OPEN_ROUTER"`, `"VLLM"`, `"OLLAMA"`, `"LLAMA_CPP"`, `"CUSTOM_OPENAI_COMPATIBLE"`. Use `"CUSTOM_OPENAI_COMPATIBLE"` for third-party OpenAI-compatible endpoints such as Anthropic, Google Gemini, or Mistral. Auto-inferred from `model_identifier` for known models; required when `model_identifier` is not in the registry.
            supported_modalities (list[Modality], optional, server default="['TEXT']"): Modalities supported by this LLM (e.g. `["TEXT"]`). Auto-inferred from `model_identifier` for known models; defaults to `["TEXT"]` on the server if omitted.
            version (str, optional): Version information

        Returns:
            CreateLLMResponse
        """
        _kw: dict[str, Any] = {"display_name": display_name, "model_identifier": model_identifier}
        if api_key is not None: _kw["api_key"] = api_key
        if api_path is not None: _kw["api_path"] = api_path
        if capabilities is not None: _kw["capabilities"] = capabilities
        if client_config is not None: _kw["client_config"] = client_config
        if credentials is not None: _kw["credentials"] = credentials
        if default_sampling_params is not None: _kw["default_sampling_params"] = default_sampling_params
        if description is not None: _kw["description"] = description
        if endpoint_url is not None: _kw["endpoint_url"] = endpoint_url
        if labels is not None: _kw["labels"] = labels
        if llm_id is not None: _kw["llm_id"] = llm_id
        if max_context_length is not None: _kw["max_context_length"] = max_context_length
        if monitoring_endpoint is not None: _kw["monitoring_endpoint"] = monitoring_endpoint
        if owner_id is not None: _kw["owner_id"] = owner_id
        if provider_type is not None: _kw["provider_type"] = provider_type
        if supported_modalities is not None: _kw["supported_modalities"] = supported_modalities
        if version is not None: _kw["version"] = version
        apply_convenience_transforms(("llms", "create"), _kw)
        return super().create(**_kw)

    def list(self, *, label: dict[str, str] | None = None, owner_id: str | None = None, provider_type: LLMProviderType | None = None) -> list[LLMResponse]:
        """List LLMs

        Retrieves a list of LLM configurations accessible to the caller, with optional filtering. LABEL FILTERS: Label filters accept either label.<key>=<value> or label[key]=value (for example, label.environment=production or label[environment]=production). 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:
            label (dict[str, str], optional): Filter by label key-value pairs. Label filters accept either label.<key>=<value> or label[key]=value (for example, label.environment=production or label[environment]=production).
            owner_id (str, 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. Allowed values match the LLMProviderType schema.

        Returns:
            list[LLMResponse]
        """
        _kw: dict[str, Any] = {}
        if label is not None: _kw["label"] = label
        if owner_id is not None: _kw["owner_id"] = owner_id
        if provider_type is not None: _kw["provider_type"] = provider_type
        return super().list(**_kw)



class AsyncLlmsAPI(AsyncLlmsAPIBase):
    async def create(self, *, display_name: str, model_identifier: str, api_key: str | None = None, api_path: str | None = None, capabilities: LLMCapabilities | None = None, client_config: dict[str, Any] | None = None, credentials: EndpointAuthentication | None = None, default_sampling_params: LLMSamplingParams | None = None, description: str | None = None, endpoint_url: str | None = None, labels: dict[str, str] | None = None, llm_id: str | None = None, max_context_length: int | None = None, monitoring_endpoint: str | None = None, owner_id: str | None = None, provider_type: LLMProviderType | None = None, supported_modalities: list[Modality] | None = None, version: str | None = None) -> CreateLLMResponse:
        """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 (str): User-facing name of the LLM
            model_identifier (str): When a known model, auto-fills `provider_type`, `endpoint_url`, `max_context_length`, and `supported_modalities` for 34 registered models.
            api_key (str, optional): Converts a plain API key string to the full `EndpointAuthentication` structure (i.e. `{"kind": "CREDENTIAL_KIND_API_KEY", "api_key": {"inline_secret": "sk-..."}}`).
            api_path (str, optional, server default='/chat/completions'): API path for chat/completions request (defaults to `/chat/completions` if not provided).
            capabilities (LLMCapabilities, optional): LLM capabilities defining supported features and modes. Optional — server infers capabilities from model identifier if not provided.
            client_config (dict[str, Any], optional): Provider-specific client configuration as flexible JSON structure
            credentials (EndpointAuthentication, optional): Structured credential payload describing how to authenticate with the provider.
            default_sampling_params (LLMSamplingParams, optional): Default sampling parameters for generation requests
            description (str, optional): Description of the LLM
            endpoint_url (str, optional): Base URL for the LLM endpoint (OpenAI-compatible base, typically ends with `/v1`). Auto-inferred from `provider_type` for known providers; required when `model_identifier` is not in the registry.
            labels (dict[str, str], optional): User-defined labels for categorization
            llm_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.
            max_context_length (int, optional): Maximum context window size in tokens. Auto-inferred from `model_identifier` for known models; recommended when `model_identifier` is not in the registry.
            monitoring_endpoint (str, optional): Monitoring endpoint URL
            owner_id (str, optional): Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_LLM_ANY permission if specified.
            provider_type (LLMProviderType, optional): Provider backend — one of `"OPENAI"`, `"LITELLM_PROXY"`, `"OPEN_ROUTER"`, `"VLLM"`, `"OLLAMA"`, `"LLAMA_CPP"`, `"CUSTOM_OPENAI_COMPATIBLE"`. Use `"CUSTOM_OPENAI_COMPATIBLE"` for third-party OpenAI-compatible endpoints such as Anthropic, Google Gemini, or Mistral. Auto-inferred from `model_identifier` for known models; required when `model_identifier` is not in the registry.
            supported_modalities (list[Modality], optional, server default="['TEXT']"): Modalities supported by this LLM (e.g. `["TEXT"]`). Auto-inferred from `model_identifier` for known models; defaults to `["TEXT"]` on the server if omitted.
            version (str, optional): Version information

        Returns:
            CreateLLMResponse
        """
        _kw: dict[str, Any] = {"display_name": display_name, "model_identifier": model_identifier}
        if api_key is not None: _kw["api_key"] = api_key
        if api_path is not None: _kw["api_path"] = api_path
        if capabilities is not None: _kw["capabilities"] = capabilities
        if client_config is not None: _kw["client_config"] = client_config
        if credentials is not None: _kw["credentials"] = credentials
        if default_sampling_params is not None: _kw["default_sampling_params"] = default_sampling_params
        if description is not None: _kw["description"] = description
        if endpoint_url is not None: _kw["endpoint_url"] = endpoint_url
        if labels is not None: _kw["labels"] = labels
        if llm_id is not None: _kw["llm_id"] = llm_id
        if max_context_length is not None: _kw["max_context_length"] = max_context_length
        if monitoring_endpoint is not None: _kw["monitoring_endpoint"] = monitoring_endpoint
        if owner_id is not None: _kw["owner_id"] = owner_id
        if provider_type is not None: _kw["provider_type"] = provider_type
        if supported_modalities is not None: _kw["supported_modalities"] = supported_modalities
        if version is not None: _kw["version"] = version
        apply_convenience_transforms(("llms", "create"), _kw)
        return await super().create(**_kw)

    async def list(self, *, label: dict[str, str] | None = None, owner_id: str | None = None, provider_type: LLMProviderType | None = None) -> list[LLMResponse]:
        """List LLMs

        Retrieves a list of LLM configurations accessible to the caller, with optional filtering. LABEL FILTERS: Label filters accept either label.<key>=<value> or label[key]=value (for example, label.environment=production or label[environment]=production). 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:
            label (dict[str, str], optional): Filter by label key-value pairs. Label filters accept either label.<key>=<value> or label[key]=value (for example, label.environment=production or label[environment]=production).
            owner_id (str, 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. Allowed values match the LLMProviderType schema.

        Returns:
            list[LLMResponse]
        """
        _kw: dict[str, Any] = {}
        if label is not None: _kw["label"] = label
        if owner_id is not None: _kw["owner_id"] = owner_id
        if provider_type is not None: _kw["provider_type"] = provider_type
        return await super().list(**_kw)

