"""
Generated CLI for Maniac SDK.

DO NOT EDIT - This file is generated by scripts/generate.py --cli
"""

import json
import sys

import click

from maniac import Maniac
from maniac._cli_format import format_output


def _get_client(ctx):
    """Get or create the Maniac client from click context."""
    if "client" not in ctx.obj:
        ctx.obj["client"] = Maniac(
            api_key=ctx.obj.get("api_key"),
            base_url=ctx.obj.get("base_url"),
        )
    return ctx.obj["client"]


@click.group()
@click.option("--api-key", envvar="MANIAC_API_KEY", default=None, help="Maniac API key.")
@click.option("--base-url", envvar="MANIAC_BASE_URL", default=None, help="API base URL.")
@click.pass_context
def cli(ctx, api_key, base_url):
    """Maniac CLI - manage containers, models, evaluators, and more."""
    ctx.ensure_object(dict)
    ctx.obj["api_key"] = api_key
    ctx.obj["base_url"] = base_url


@cli.group("chat")
def chat():
    """Manage chat."""
    pass


@chat.group("completions")
def chat_completions():
    """Manage completions."""
    pass


@chat_completions.command("list")
@click.option("--limit", type=int, default=20)
@click.option("--offset", type=int, default=0)
@click.option("--model", type=str, default=None)
@click.option("--container", type=str, default=None)
@click.option("--order", type=str, default='desc')
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def chat_completions_list(ctx, limit, offset, model, container, order, output_json, columns):
    """List chat completions"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.chat.completions.list(limit=limit, offset=offset, model=model, container=container, order=order)
    format_output(ctx, result)


@chat_completions.command("create")
@click.option("--messages", type=str, required=True, help="JSON string.")
@click.option("--container", type=str, default=None, help="Optional container label (maniac:<label>) to route within a ...")
@click.option("--frequency-penalty", type=str, default=None, help="JSON string.")
@click.option("--logit-bias", type=str, default=None, help="JSON string.")
@click.option("--logprobs", type=str, default=None, help="JSON string.")
@click.option("--max-completion-tokens", type=str, default=None, help="JSON string.")
@click.option("--max-tokens", type=str, default=None, help="JSON string.")
@click.option("--metadata", type=str, default=None, help="Arbitrary key/value metadata to attach to the request.")
@click.option("--model", type=str, default=None, help="Model slug to use. Supports global slugs or project slugs (m...")
@click.option("--models", type=str, default=None, help="JSON string.")
@click.option("--presence-penalty", type=str, default=None, help="JSON string.")
@click.option("--reasoning", type=str, default=None, help="JSON string.")
@click.option("--response-format", type=str, default=None, help="JSON string.")
@click.option("--seed", type=str, default=None, help="JSON string.")
@click.option("--stop", type=str, default=None, help="JSON string.")
@click.option("--store", is_flag=True, default=True, help="Whether to store the completion in the database.")
@click.option("--stream", is_flag=True, default=False)
@click.option("--stream-options", type=str, default=None, help="JSON string.")
@click.option("--tags", type=str, default=None, help="Optional tags for tracking.")
@click.option("--temperature", type=str, default=None, help="JSON string.")
@click.option("--tool-choice", type=str, default=None, help="JSON string.")
@click.option("--tools", type=str, default=None, help="JSON string.")
@click.option("--top-logprobs", type=str, default=None, help="JSON string.")
@click.option("--top-p", type=str, default=None, help="JSON string.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def chat_completions_create(ctx, messages, container, frequency_penalty, logit_bias, logprobs, max_completion_tokens, max_tokens, metadata, model, models, presence_penalty, reasoning, response_format, seed, stop, store, stream, stream_options, tags, temperature, tool_choice, tools, top_logprobs, top_p, output_json, columns):
    """Create a chat completion"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if messages is not None:
        try:
            messages = json.loads(messages)
        except (json.JSONDecodeError, TypeError):
            pass
    if frequency_penalty is not None:
        try:
            frequency_penalty = json.loads(frequency_penalty)
        except (json.JSONDecodeError, TypeError):
            pass
    if logit_bias is not None:
        try:
            logit_bias = json.loads(logit_bias)
        except (json.JSONDecodeError, TypeError):
            pass
    if logprobs is not None:
        try:
            logprobs = json.loads(logprobs)
        except (json.JSONDecodeError, TypeError):
            pass
    if max_completion_tokens is not None:
        try:
            max_completion_tokens = json.loads(max_completion_tokens)
        except (json.JSONDecodeError, TypeError):
            pass
    if max_tokens is not None:
        try:
            max_tokens = json.loads(max_tokens)
        except (json.JSONDecodeError, TypeError):
            pass
    if metadata is not None:
        try:
            metadata = json.loads(metadata)
        except (json.JSONDecodeError, TypeError):
            pass
    if models is not None:
        try:
            models = json.loads(models)
        except (json.JSONDecodeError, TypeError):
            pass
    if presence_penalty is not None:
        try:
            presence_penalty = json.loads(presence_penalty)
        except (json.JSONDecodeError, TypeError):
            pass
    if reasoning is not None:
        try:
            reasoning = json.loads(reasoning)
        except (json.JSONDecodeError, TypeError):
            pass
    if response_format is not None:
        try:
            response_format = json.loads(response_format)
        except (json.JSONDecodeError, TypeError):
            pass
    if seed is not None:
        try:
            seed = json.loads(seed)
        except (json.JSONDecodeError, TypeError):
            pass
    if stop is not None:
        try:
            stop = json.loads(stop)
        except (json.JSONDecodeError, TypeError):
            pass
    if stream_options is not None:
        try:
            stream_options = json.loads(stream_options)
        except (json.JSONDecodeError, TypeError):
            pass
    if tags is not None:
        try:
            tags = json.loads(tags)
        except (json.JSONDecodeError, TypeError):
            pass
    if temperature is not None:
        try:
            temperature = json.loads(temperature)
        except (json.JSONDecodeError, TypeError):
            pass
    if tool_choice is not None:
        try:
            tool_choice = json.loads(tool_choice)
        except (json.JSONDecodeError, TypeError):
            pass
    if tools is not None:
        try:
            tools = json.loads(tools)
        except (json.JSONDecodeError, TypeError):
            pass
    if top_logprobs is not None:
        try:
            top_logprobs = json.loads(top_logprobs)
        except (json.JSONDecodeError, TypeError):
            pass
    if top_p is not None:
        try:
            top_p = json.loads(top_p)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    if stream:
        for chunk in client.chat.completions.create(messages=messages, container=container, frequency_penalty=frequency_penalty, logit_bias=logit_bias, logprobs=logprobs, max_completion_tokens=max_completion_tokens, max_tokens=max_tokens, metadata=metadata, model=model, models=models, presence_penalty=presence_penalty, reasoning=reasoning, response_format=response_format, seed=seed, stop=stop, store=store, stream=stream, stream_options=stream_options, tags=tags, temperature=temperature, tool_choice=tool_choice, tools=tools, top_logprobs=top_logprobs, top_p=top_p):
            click.echo(chunk, nl=False)
            sys.stdout.flush()
        click.echo()
    else:
        result = client.chat.completions.create(messages=messages, container=container, frequency_penalty=frequency_penalty, logit_bias=logit_bias, logprobs=logprobs, max_completion_tokens=max_completion_tokens, max_tokens=max_tokens, metadata=metadata, model=model, models=models, presence_penalty=presence_penalty, reasoning=reasoning, response_format=response_format, seed=seed, stop=stop, store=store, stream=stream, stream_options=stream_options, tags=tags, temperature=temperature, tool_choice=tool_choice, tools=tools, top_logprobs=top_logprobs, top_p=top_p)
        format_output(ctx, result)


@chat_completions.command("retrieve")
@click.argument("completion_id")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def chat_completions_retrieve(ctx, completion_id, output_json, columns):
    """Get a chat completion"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.chat.completions.retrieve(completion_id)
    format_output(ctx, result)


@chat_completions.command("register")
@click.option("--container", type=str, required=True, help="Container label to associate these examples with.")
@click.option("--items", type=str, required=True, help="List of chat input/output examples.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def chat_completions_register(ctx, container, items, output_json, columns):
    """Register chat completion examples"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if items is not None:
        try:
            items = json.loads(items)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    result = client.chat.completions.register(container=container, items=items)
    format_output(ctx, result)


@cli.group("containers")
def containers():
    """Manage containers."""
    pass


@containers.command("list")
@click.option("--limit", type=int, default=20)
@click.option("--offset", type=int, default=0)
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def containers_list(ctx, limit, offset, output_json, columns):
    """List containers"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.containers.list(limit=limit, offset=offset)
    format_output(ctx, result)


@containers.command("create")
@click.option("--initial-model", type=str, required=True, help="Initial model slug.")
@click.option("--label", type=str, required=True, help="Container label.")
@click.option("--api", type=str, default='chat.completions', help="API type.")
@click.option("--default-parameters", type=str, default=None, help="Default inference parameters.")
@click.option("--default-system-prompt", type=str, default=None, help="Default system prompt.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def containers_create(ctx, initial_model, label, api, default_parameters, default_system_prompt, output_json, columns):
    """Create a container"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if default_parameters is not None:
        try:
            default_parameters = json.loads(default_parameters)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    result = client.containers.create(initial_model=initial_model, label=label, api=api, default_parameters=default_parameters, default_system_prompt=default_system_prompt)
    format_output(ctx, result)


@containers.command("retrieve")
@click.argument("label")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def containers_retrieve(ctx, label, output_json, columns):
    """Get a container"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.containers.retrieve(label)
    format_output(ctx, result)


@containers.command("delete")
@click.argument("label")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def containers_delete(ctx, label, output_json, columns):
    """Delete a container"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.containers.delete(label)
    format_output(ctx, result)


@cli.group("datasets")
def datasets():
    """Manage datasets."""
    pass


@datasets.command("list")
@click.option("--limit", type=int, default=100, help="Max number of datasets.")
@click.option("--offset", type=int, default=0, help="Number of datasets to skip.")
@click.option("--container", type=str, default=None, help="Container ID or label to filter datasets by.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def datasets_list(ctx, limit, offset, container, output_json, columns):
    """List datasets"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.datasets.list(limit=limit, offset=offset, container=container)
    format_output(ctx, result)


@datasets.command("create")
@click.option("--container", type=str, required=True, help="Container label for source data.")
@click.option("--name", type=str, required=True, help="Dataset name.")
@click.option("--size", type=int, required=True, help="Requested dataset size.")
@click.option("--data-source", type=str, default=None, help="Optional data source override.")
@click.option("--description", type=str, default=None, help="Dataset description.")
@click.option("--filters", type=str, default=None, help="Filter conditions.")
@click.option("--metadata", type=str, default=None, help="Arbitrary metadata.")
@click.option("--model-filters", type=str, default=None, help="Model filter slugs.")
@click.option("--tags", type=str, default=None, help="Optional dataset tags.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def datasets_create(ctx, container, name, size, data_source, description, filters, metadata, model_filters, tags, output_json, columns):
    """Create a dataset"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if filters is not None:
        try:
            filters = json.loads(filters)
        except (json.JSONDecodeError, TypeError):
            pass
    if metadata is not None:
        try:
            metadata = json.loads(metadata)
        except (json.JSONDecodeError, TypeError):
            pass
    if model_filters is not None:
        try:
            model_filters = json.loads(model_filters)
        except (json.JSONDecodeError, TypeError):
            pass
    if tags is not None:
        try:
            tags = json.loads(tags)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    result = client.datasets.create(container=container, name=name, size=size, data_source=data_source, description=description, filters=filters, metadata=metadata, model_filters=model_filters, tags=tags)
    format_output(ctx, result)


@datasets.command("retrieve")
@click.argument("dataset_id")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def datasets_retrieve(ctx, dataset_id, output_json, columns):
    """Get a dataset"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.datasets.retrieve(dataset_id)
    format_output(ctx, result)


@cli.group("evaluation")
def evaluation():
    """Manage evaluation."""
    pass


@evaluation.group("runs")
def evaluation_runs():
    """Manage runs."""
    pass


@evaluation_runs.command("list")
@click.option("--container", type=str, default=None, help="Container ID or label to filter by.")
@click.option("--status", type=str, default=None, help="Filter by run status (e.g. 'running', 'completed', 'error').")
@click.option("--limit", type=int, default=20)
@click.option("--offset", type=int, default=0)
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def evaluation_runs_list(ctx, container, status, limit, offset, output_json, columns):
    """List evaluation runs"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.evaluation.runs.list(container=container, status=status, limit=limit, offset=offset)
    format_output(ctx, result)


@evaluation_runs.command("create")
@click.option("--container", type=str, required=True, help="Container id or label.")
@click.option("--evaluators", type=str, required=True, help="Evaluator ids or labels.")
@click.option("--environment", type=str, default='main', help="Execution environment name (maps to Modal app suffix).")
@click.option("--ground-truth", type=str, default=None, help="Ground-truth-side data source. Omit to default to the contai...")
@click.option("--metadata", type=str, default=None, help="Optional metadata.")
@click.option("--sample", type=str, default=None, help="Sample-side data source. Omit to default to the container's ...")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def evaluation_runs_create(ctx, container, evaluators, environment, ground_truth, metadata, sample, output_json, columns):
    """Create an evaluation run"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if evaluators is not None:
        try:
            evaluators = json.loads(evaluators)
        except (json.JSONDecodeError, TypeError):
            pass
    if ground_truth is not None:
        try:
            ground_truth = json.loads(ground_truth)
        except (json.JSONDecodeError, TypeError):
            pass
    if metadata is not None:
        try:
            metadata = json.loads(metadata)
        except (json.JSONDecodeError, TypeError):
            pass
    if sample is not None:
        try:
            sample = json.loads(sample)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    result = client.evaluation.runs.create(container=container, evaluators=evaluators, environment=environment, ground_truth=ground_truth, metadata=metadata, sample=sample)
    format_output(ctx, result)


@evaluation_runs.command("retrieve")
@click.argument("run_id")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def evaluation_runs_retrieve(ctx, run_id, output_json, columns):
    """Get an evaluation run"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.evaluation.runs.retrieve(run_id)
    format_output(ctx, result)


@cli.group("evaluators")
def evaluators():
    """Manage evaluators."""
    pass


@evaluators.command("list")
@click.option("--container", type=str, default=None)
@click.option("--limit", type=int, default=20)
@click.option("--offset", type=int, default=0)
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def evaluators_list(ctx, container, limit, offset, output_json, columns):
    """List evaluators"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.evaluators.list(container=container, limit=limit, offset=offset)
    format_output(ctx, result)


@evaluators.command("create")
@click.option("--type", type=str, required=True, help="Evaluator type.")
@click.option("--api", type=str, default=None, help="API type.")
@click.option("--container", type=str, default=None, help="Container label.")
@click.option("--description", type=str, default=None, help="Evaluator description.")
@click.option("--metadata", type=str, default=None, help="Optional metadata.")
@click.option("--model", type=str, default=None, help="Judge model slug.")
@click.option("--name", type=str, default=None, help="Evaluator name.")
@click.option("--pass-threshold", type=float, default=None, help="Optional pass threshold.")
@click.option("--prompt", type=str, default=None, help="Judge prompt.")
@click.option("--requirements", type=str, default=None, help="Optional requirements list.")
@click.option("--source", type=str, default=None, help="Code evaluator source.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def evaluators_create(ctx, type, api, container, description, metadata, model, name, pass_threshold, prompt, requirements, source, output_json, columns):
    """Create an evaluator"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if metadata is not None:
        try:
            metadata = json.loads(metadata)
        except (json.JSONDecodeError, TypeError):
            pass
    if requirements is not None:
        try:
            requirements = json.loads(requirements)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    result = client.evaluators.create(type=type, api=api, container=container, description=description, metadata=metadata, model=model, name=name, pass_threshold=pass_threshold, prompt=prompt, requirements=requirements, source=source)
    format_output(ctx, result)


@evaluators.command("retrieve")
@click.argument("evaluator")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def evaluators_retrieve(ctx, evaluator, output_json, columns):
    """Get an evaluator"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.evaluators.retrieve(evaluator)
    format_output(ctx, result)


@evaluators.command("update")
@click.argument("evaluator")
@click.option("--api", type=str, default=None, help="API type.")
@click.option("--container", type=str, default=None, help="Container label.")
@click.option("--description", type=str, default=None, help="Evaluator description.")
@click.option("--metadata", type=str, default=None, help="Optional metadata.")
@click.option("--model", type=str, default=None, help="Judge model slug.")
@click.option("--name", type=str, default=None, help="Evaluator name.")
@click.option("--pass-threshold", type=float, default=None, help="Optional pass threshold.")
@click.option("--prompt", type=str, default=None, help="Judge prompt.")
@click.option("--requirements", type=str, default=None, help="Optional requirements list.")
@click.option("--source", type=str, default=None, help="Code evaluator source.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def evaluators_update(ctx, evaluator, api, container, description, metadata, model, name, pass_threshold, prompt, requirements, source, output_json, columns):
    """Update an evaluator"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if metadata is not None:
        try:
            metadata = json.loads(metadata)
        except (json.JSONDecodeError, TypeError):
            pass
    if requirements is not None:
        try:
            requirements = json.loads(requirements)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    result = client.evaluators.update(evaluator, api=api, container=container, description=description, metadata=metadata, model=model, name=name, pass_threshold=pass_threshold, prompt=prompt, requirements=requirements, source=source)
    format_output(ctx, result)


@evaluators.command("delete")
@click.argument("evaluator_id")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def evaluators_delete(ctx, evaluator_id, output_json, columns):
    """Delete an evaluator"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.evaluators.delete(evaluator_id)
    format_output(ctx, result)


@cli.group("models")
def models():
    """Manage models."""
    pass


@models.command("list")
@click.option("--limit", type=int, default=100, help="Max number of models.")
@click.option("--offset", type=int, default=0, help="Number of models to skip.")
@click.option("--container", type=str, default=None, help="Container ID or label to filter models by.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def models_list(ctx, limit, offset, container, output_json, columns):
    """List available models"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    client = _get_client(ctx)
    result = client.models.list(limit=limit, offset=offset, container=container)
    format_output(ctx, result)


@models.command("add")
@click.option("--container", type=str, required=True, help="Container id or label.")
@click.option("--model", type=str, required=True, help="Model slug to add.")
@click.option("--slug", type=str, required=True, help="User specified submodel slug.")
@click.option("--default-parameters", type=str, default=None, help="Default inference parameters.")
@click.option("--default-system-prompt", type=str, default=None, help="Default system prompt.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def models_add(ctx, container, model, slug, default_parameters, default_system_prompt, output_json, columns):
    """Add a model to a container"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if default_parameters is not None:
        try:
            default_parameters = json.loads(default_parameters)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    result = client.models.add(container=container, model=model, slug=slug, default_parameters=default_parameters, default_system_prompt=default_system_prompt)
    format_output(ctx, result)


@cli.group("optimization")
def optimization():
    """Manage optimization."""
    pass


@optimization.group("runs")
def optimization_runs():
    """Manage runs."""
    pass


@optimization_runs.command("create")
@click.option("--base-models", type=str, required=True, help="Base model ids or labels.")
@click.option("--container", type=str, required=True, help="Container id or label.")
@click.option("--evals", type=str, required=True, help="Evaluator ids or labels.")
@click.option("--methods", type=str, required=True, help="Optimization methods to run.")
@click.option("--data-source", type=str, default=None, help="Optional data source override.")
@click.option("--environment", type=str, default='main', help="Execution environment name.")
@click.option("--metadata", type=str, default=None, help="Optional metadata.")
@click.option("--json", "output_json", is_flag=True, default=False, help="Output raw JSON.")
@click.option("--columns", default=None, help="Comma-separated columns to add to table output.")
@click.pass_context
def optimization_runs_create(ctx, base_models, container, evals, methods, data_source, environment, metadata, output_json, columns):
    """Create an optimization run"""
    ctx.obj["json"] = output_json
    ctx.obj["columns"] = [c.strip() for c in columns.split(",")] if columns else None
    if base_models is not None:
        try:
            base_models = json.loads(base_models)
        except (json.JSONDecodeError, TypeError):
            pass
    if evals is not None:
        try:
            evals = json.loads(evals)
        except (json.JSONDecodeError, TypeError):
            pass
    if methods is not None:
        try:
            methods = json.loads(methods)
        except (json.JSONDecodeError, TypeError):
            pass
    if data_source is not None:
        try:
            data_source = json.loads(data_source)
        except (json.JSONDecodeError, TypeError):
            pass
    if metadata is not None:
        try:
            metadata = json.loads(metadata)
        except (json.JSONDecodeError, TypeError):
            pass
    client = _get_client(ctx)
    result = client.optimization.runs.create(base_models=base_models, container=container, evals=evals, methods=methods, data_source=data_source, environment=environment, metadata=metadata)
    format_output(ctx, result)
