from __future__ import annotations

from typing import Any, Dict, List, Optional

from pydantic import BaseModel, ConfigDict, Field

from goodmem.models.context_item import ContextItem
from goodmem.models.space_key import SpaceKey
from goodmem.models.hnsw_options import HnswOptions
from goodmem.models.post_processor import PostProcessor


class RetrieveMemoryRequest(BaseModel):
    """Request body for semantic memory retrieval with optional embedder weight overrides."""

    model_config = ConfigDict(populate_by_name=True, protected_namespaces=(), extra='forbid')

    message: str = Field(description='Primary query/message for semantic search.')
    context: Optional[list[ContextItem]] = Field(default=None, description='Optional context items (text or binary) to provide additional context for the search.')
    space_keys: list[SpaceKey] = Field(description='List of spaces to search with optional per-embedder weight overrides.', alias="spaceKeys")
    requested_size: Optional[int] = Field(default=None, description='Maximum number of memories to retrieve.', alias="requestedSize")
    fetch_memory: Optional[bool] = Field(default=None, description='Whether to include full Memory objects in the response.', alias="fetchMemory")
    fetch_memory_content: Optional[bool] = Field(default=None, description='Whether to include memory content in the response. Requires fetchMemory=true.', alias="fetchMemoryContent")
    hnsw: Optional[HnswOptions] = Field(default=None, description='Optional request-level HNSW tuning overrides. Advanced usage; available on POST retrieve.')
    post_processor: Optional[PostProcessor] = Field(default=None, description='Optional post-processor configuration to transform retrieval results.', alias="postProcessor")

