File size: 4,455 Bytes
0231daa
 
 
 
 
 
 
155ad69
0231daa
 
 
 
 
 
155ad69
 
 
 
0231daa
 
155ad69
0231daa
 
 
 
155ad69
 
 
 
0231daa
155ad69
 
 
 
 
 
 
 
0231daa
 
 
 
31bb4e3
0231daa
 
31bb4e3
0231daa
31bb4e3
0231daa
 
 
 
 
 
 
 
 
 
 
155ad69
0231daa
 
31bb4e3
0231daa
 
155ad69
0231daa
 
 
 
 
31bb4e3
0231daa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155ad69
0231daa
 
 
 
155ad69
0231daa
 
 
 
 
90528a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a23b910
90528a8
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
"""
Request schemas for API endpoints.

This module defines all Pydantic models for incoming API requests,
with validation and documentation.
"""

from typing import List, Optional, Literal
from pydantic import BaseModel, Field, field_validator, ConfigDict
from .common import EmbeddingOptions


class BaseEmbedRequest(BaseModel):
    """
    OpenAI-compatible embedding request.
    
    Matches the format of OpenAI's embeddings API:
    https://platform.openai.com/docs/api-reference/embeddings
    """

    model: str = Field(
        ...,
        description="Model identifier to use for embedding generation",
        examples=["qwen3-0.6b", "splade-pp-v2"],
    )

    encoding_format: Optional[Literal["float", "base64"]] = Field(
        default="float", 
        description="Encoding format"
    )
    dimensions: Optional[int] = Field(
        None, 
        description="Output dimensions")

    user: Optional[str] = Field(
        None,
        description="User identifier")

    options: Optional[EmbeddingOptions] = Field(
        None, description="Optional embedding generation parameters"
    )

    @field_validator("model")
    @classmethod
    def validate_model_id(cls, v: str) -> str:
        """Validate that model is not empty."""
        if not v or not v.strip():
            raise ValueError("model cannot be empty")
        return v.strip()

    model_config = ConfigDict(
        extra="allow"  # Allow extra fields for advanced users (passed as **kwargs)
    )


class EmbedRequest(BaseEmbedRequest):
    """
    Request model for single/batch text and sparse embedding.

    Used for /embeddings and /embed_sparse endpoint to process multiple texts at once.

    Attributes:
        input: List of input texts to embed
    """

    input: List[str] = Field(
        ...,
        description="List of input texts to generate embeddings for",
        min_length=1,
    )

    @field_validator("input")
    @classmethod
    def validate_texts(cls, v: List[str]) -> List[str]:
        """Validate that all texts are non-empty."""
        if not v:
            raise ValueError("texts list cannot be empty")

        if len(v) > 100:
            raise ValueError(f"Batch size ({len(v)}) exceeds maximum (100)")

        # Validate each text
        validated = []
        for idx, text in enumerate(v):
            if not isinstance(text, str):
                raise ValueError(f"texts[{idx}] must be a string")
            if not text.strip():
                raise ValueError(f"texts[{idx}] cannot be empty or whitespace only")
            if len(text) > 8192:
                raise ValueError(f"texts[{idx}] exceeds maximum length (8192)")
            validated.append(text)

        return validated

    class Config:
        json_schema_extra = {
            "example": {
                "input": [
                    "First document to embed",
                    "Second document to embed",
                    "Third document to embed",
                ],
                "model": "qwen3-0.6b",
                "options": {
                    "normalize_embeddings": True,
                },
            }
        }


class RerankRequest(BaseEmbedRequest):
    """
    Request model for document reranking.

    Attributes:
        query: The search query
        documents: List of documents to rerank
        top_k: Maximum number of documents to return

    """

    query: str = Field(..., description="Search query text")
    documents: List[str] = Field(
        ..., min_items=1, description="List of documents to rerank"
    )
    top_k: int = Field(..., description="Maximum number of results to return")

    class Config:
        json_schema_extra = {
            "example": {
                "model": "jina-reranker-v3",
                "query": "Python best programming languages for data science",
                "top_k": 4,
                "documents": [
                    "Python is a popular language for data science due to its extensive libraries.",
                    "R is widely used in statistical computing and data analysis.",
                    "Java is a versatile language used in various applications, including data science.",
                    "SQL is essential for managing and querying relational databases.",
                    "Julia is a high-performance language gaining popularity for numerical computing and data science.",
                ],
            }
        }