docforge-sdk 0.26.0__tar.gz → 0.28.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/PKG-INFO +1 -1
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/__init__.py +28 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/_version.py +1 -1
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/__init__.py +30 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/collections.py +41 -41
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/estimate.py +14 -5
- docforge_sdk-0.28.0/docforge_sdk/models/field_spec.py +51 -0
- docforge_sdk-0.28.0/docforge_sdk/models/index_rebuild.py +22 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/jobs.py +17 -3
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/pipelines.py +41 -0
- docforge_sdk-0.28.0/docforge_sdk/models/schema_ops.py +132 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/search.py +10 -4
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/collections.py +62 -6
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/pipelines.py +66 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/openapi_snapshot.json +877 -75
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/parity_map.py +26 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/route_map.py +2 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_collections.py +22 -1
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/.gitignore +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/.python-version +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/LICENSE +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/README.md +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/_exceptions.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/_requestspec.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/_transport_async.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/_transport_base.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/_transport_sync.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/client.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/_shared.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/audit.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/auth.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/blobs.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/capabilities.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/corpus.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/documents.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/explorer.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/health.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/ir.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/preview.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/reingest.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/snippets.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/storage.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/trace.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/models/transfers.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/py.typed +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/__init__.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/_base.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/audit.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/auth.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/blobs.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/capabilities.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/corpus.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/documents.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/explorer.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/health.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/jobs.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/search.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/snippets.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/docforge_sdk/resources/transfers.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/pyproject.toml +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/__init__.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/check_schema_drift.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/live/__init__.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/live/test_openapi_parity_live.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/__init__.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_audit.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_auth.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_blobs.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_corpus.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_documents.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_explorer.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_health.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_jobs.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_models_offline_parity.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_pipelines.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_resource_parity.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_route_coverage.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_search.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_snippets.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_transfers.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/tests/unit/test_transport.py +0 -0
- {docforge_sdk-0.26.0 → docforge_sdk-0.28.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: docforge-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.28.0
|
|
4
4
|
Summary: Typed async + sync Python client for the DocForge REST API (standalone, zero server deps).
|
|
5
5
|
Project-URL: Homepage, https://github.com/Florian-BARRE/docforge
|
|
6
6
|
Project-URL: Repository, https://github.com/Florian-BARRE/docforge
|
|
@@ -48,6 +48,7 @@ from .models.collections import (
|
|
|
48
48
|
FieldSpec,
|
|
49
49
|
ReingestJobHandle,
|
|
50
50
|
UpdateCollectionRequest,
|
|
51
|
+
UpdateCollectionResponse,
|
|
51
52
|
)
|
|
52
53
|
|
|
53
54
|
# ------------------- Documents models ------------------- #
|
|
@@ -89,6 +90,9 @@ from .models.explorer import (
|
|
|
89
90
|
# ------------------- Health models ------------------- #
|
|
90
91
|
from .models.health import HealthStatus
|
|
91
92
|
|
|
93
|
+
# ------------------- Index rebuild models ------------------- #
|
|
94
|
+
from .models.index_rebuild import RebuildIndexAccepted
|
|
95
|
+
|
|
92
96
|
# ------------------- IR models ------------------- #
|
|
93
97
|
from .models.ir import (
|
|
94
98
|
DocumentIRModel,
|
|
@@ -136,6 +140,19 @@ from .models.preview import (
|
|
|
136
140
|
PreviewTraceNode,
|
|
137
141
|
)
|
|
138
142
|
|
|
143
|
+
# ------------------- Collection schema ops ------------------- #
|
|
144
|
+
from .models.schema_ops import (
|
|
145
|
+
AddFieldOp,
|
|
146
|
+
FieldOp,
|
|
147
|
+
FieldPatch,
|
|
148
|
+
RemoveFieldOp,
|
|
149
|
+
RenameFieldOp,
|
|
150
|
+
SchemaDiff,
|
|
151
|
+
SchemaDiffModifiedField,
|
|
152
|
+
SchemaDiffRename,
|
|
153
|
+
UpdateFieldOp,
|
|
154
|
+
)
|
|
155
|
+
|
|
139
156
|
# ------------------- Search models ------------------- #
|
|
140
157
|
from .models.search import (
|
|
141
158
|
BlockLocation,
|
|
@@ -194,6 +211,16 @@ __all__ = [
|
|
|
194
211
|
"CollectionModel",
|
|
195
212
|
"CreateCollectionRequest",
|
|
196
213
|
"UpdateCollectionRequest",
|
|
214
|
+
"UpdateCollectionResponse",
|
|
215
|
+
"FieldPatch",
|
|
216
|
+
"AddFieldOp",
|
|
217
|
+
"UpdateFieldOp",
|
|
218
|
+
"RemoveFieldOp",
|
|
219
|
+
"RenameFieldOp",
|
|
220
|
+
"FieldOp",
|
|
221
|
+
"SchemaDiff",
|
|
222
|
+
"SchemaDiffModifiedField",
|
|
223
|
+
"SchemaDiffRename",
|
|
197
224
|
"BulkReingestRequest",
|
|
198
225
|
"ReingestJobHandle",
|
|
199
226
|
"BulkReingestAccepted",
|
|
@@ -284,6 +311,7 @@ __all__ = [
|
|
|
284
311
|
"TransferStatus",
|
|
285
312
|
# Trace payloads
|
|
286
313
|
"TracePurgeResult",
|
|
314
|
+
"RebuildIndexAccepted",
|
|
287
315
|
# Exceptions
|
|
288
316
|
"DocForgeError",
|
|
289
317
|
"APIConnectionError",
|
|
@@ -37,6 +37,7 @@ from .collections import (
|
|
|
37
37
|
ReingestJobHandle,
|
|
38
38
|
SearchTargetGuide,
|
|
39
39
|
UpdateCollectionRequest,
|
|
40
|
+
UpdateCollectionResponse,
|
|
40
41
|
)
|
|
41
42
|
|
|
42
43
|
# ------------------- Corpus filter + grid models ------------------- #
|
|
@@ -112,6 +113,9 @@ from .health import (
|
|
|
112
113
|
SearchIndex,
|
|
113
114
|
)
|
|
114
115
|
|
|
116
|
+
# ------------------- Index rebuild models ------------------- #
|
|
117
|
+
from .index_rebuild import RebuildIndexAccepted
|
|
118
|
+
|
|
115
119
|
# ------------------- IR models ------------------- #
|
|
116
120
|
from .ir import (
|
|
117
121
|
DocumentIRModel,
|
|
@@ -145,6 +149,7 @@ from .jobs import (
|
|
|
145
149
|
|
|
146
150
|
# ------------------- Pipelines models ------------------- #
|
|
147
151
|
from .pipelines import (
|
|
152
|
+
CollectionStageApplyResponse,
|
|
148
153
|
EditResponse,
|
|
149
154
|
InspectResponse,
|
|
150
155
|
PipelineDesignResponse,
|
|
@@ -166,6 +171,19 @@ from .preview import (
|
|
|
166
171
|
PreviewTraceNode,
|
|
167
172
|
)
|
|
168
173
|
|
|
174
|
+
# ------------------- Collection schema ops ------------------- #
|
|
175
|
+
from .schema_ops import (
|
|
176
|
+
AddFieldOp,
|
|
177
|
+
FieldOp,
|
|
178
|
+
FieldPatch,
|
|
179
|
+
RemoveFieldOp,
|
|
180
|
+
RenameFieldOp,
|
|
181
|
+
SchemaDiff,
|
|
182
|
+
SchemaDiffModifiedField,
|
|
183
|
+
SchemaDiffRename,
|
|
184
|
+
UpdateFieldOp,
|
|
185
|
+
)
|
|
186
|
+
|
|
169
187
|
# ------------------- Search models ------------------- #
|
|
170
188
|
from .search import (
|
|
171
189
|
BlockLocation,
|
|
@@ -239,6 +257,16 @@ __all__ = [
|
|
|
239
257
|
"CollectionListItem",
|
|
240
258
|
"CreateCollectionRequest",
|
|
241
259
|
"UpdateCollectionRequest",
|
|
260
|
+
"UpdateCollectionResponse",
|
|
261
|
+
"FieldPatch",
|
|
262
|
+
"AddFieldOp",
|
|
263
|
+
"UpdateFieldOp",
|
|
264
|
+
"RemoveFieldOp",
|
|
265
|
+
"RenameFieldOp",
|
|
266
|
+
"FieldOp",
|
|
267
|
+
"SchemaDiff",
|
|
268
|
+
"SchemaDiffModifiedField",
|
|
269
|
+
"SchemaDiffRename",
|
|
242
270
|
"BulkReingestRequest",
|
|
243
271
|
"ReingestJobHandle",
|
|
244
272
|
"BulkReingestAccepted",
|
|
@@ -331,6 +359,7 @@ __all__ = [
|
|
|
331
359
|
"EditResponse",
|
|
332
360
|
"StageViewResponse",
|
|
333
361
|
"StageApplyResponse",
|
|
362
|
+
"CollectionStageApplyResponse",
|
|
334
363
|
# Preview
|
|
335
364
|
"PreviewIrSummary",
|
|
336
365
|
"PreviewChunk",
|
|
@@ -370,4 +399,5 @@ __all__ = [
|
|
|
370
399
|
"TransferStatus",
|
|
371
400
|
# Trace payloads
|
|
372
401
|
"TracePurgeResult",
|
|
402
|
+
"RebuildIndexAccepted",
|
|
373
403
|
]
|
|
@@ -13,47 +13,10 @@ from pydantic import BaseModel, Field
|
|
|
13
13
|
# ====== Local Project Imports ======
|
|
14
14
|
from ._shared import FieldOrigin, FieldScope, FieldType
|
|
15
15
|
from .estimate import EstimateOverrides
|
|
16
|
+
from .field_spec import FieldSpec
|
|
16
17
|
from .health import CollectionHealthSummary
|
|
17
18
|
from .reingest import ReingestJobHandle
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class FieldSpec(BaseModel):
|
|
21
|
-
"""
|
|
22
|
-
One metadata field of the collection's contract (declared OR generated).
|
|
23
|
-
|
|
24
|
-
Attributes:
|
|
25
|
-
field_name (str): Unique field name within the collection.
|
|
26
|
-
field_type (FieldType): Value type — drives validation and storage.
|
|
27
|
-
required (bool): Upload refused without it (user fields).
|
|
28
|
-
filterable (bool): Present in the Qdrant payload (lean vector).
|
|
29
|
-
lexical (bool): Gets a sparse BM25 named vector.
|
|
30
|
-
semantic (bool): Gets a dense named vector.
|
|
31
|
-
enum_values (list[str] | None): Allowed values when ``field_type`` is enum.
|
|
32
|
-
origin (FieldOrigin): user (declared at upload) or generated (metagen).
|
|
33
|
-
scope (FieldScope): document or chunk level value.
|
|
34
|
-
description (str | None): What the field means (max 1000 chars).
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
field_name: str = Field(description="Unique field name within the collection.")
|
|
38
|
-
field_type: FieldType = Field(description="Value type — drives validation and storage.")
|
|
39
|
-
required: bool = Field(default=False, description="Upload refused without it (user fields).")
|
|
40
|
-
filterable: bool = Field(default=False, description="Present in the Qdrant payload (lean).")
|
|
41
|
-
lexical: bool = Field(default=False, description="Gets a sparse BM25 named vector.")
|
|
42
|
-
semantic: bool = Field(default=False, description="Gets a dense named vector.")
|
|
43
|
-
enum_values: list[str] | None = Field(
|
|
44
|
-
default=None, description="Allowed values when field_type is enum."
|
|
45
|
-
)
|
|
46
|
-
origin: FieldOrigin = Field(
|
|
47
|
-
default=FieldOrigin.USER, description="user (declared at upload) or generated (metagen)."
|
|
48
|
-
)
|
|
49
|
-
scope: FieldScope = Field(
|
|
50
|
-
default=FieldScope.DOCUMENT, description="document or chunk level value."
|
|
51
|
-
)
|
|
52
|
-
description: str | None = Field(
|
|
53
|
-
default=None,
|
|
54
|
-
max_length=1000,
|
|
55
|
-
description="What the field means, in plain words — surfaced to search clients (max 1000).",
|
|
56
|
-
)
|
|
19
|
+
from .schema_ops import FieldOp, SchemaDiff
|
|
57
20
|
|
|
58
21
|
|
|
59
22
|
class CollectionModel(BaseModel):
|
|
@@ -68,6 +31,8 @@ class CollectionModel(BaseModel):
|
|
|
68
31
|
job_timeout_seconds (float | None): Per-collection whole-ingest-job wall-clock job timeout,
|
|
69
32
|
seconds. None = inherit the worker's global WORKER_JOB_TIMEOUT_SECONDS default.
|
|
70
33
|
needs_reindex (bool): True when a config change requires reindexing.
|
|
34
|
+
missing_vectors (list[str] | None): Named vectors the schema's semantic/lexical fields need
|
|
35
|
+
but the vector store does not declare (an index rebuild is required); None on list rows.
|
|
71
36
|
created_at (datetime | None): Creation timestamp.
|
|
72
37
|
title_field (str | None): Document-scope field used as the display title (None = parsed).
|
|
73
38
|
pipeline (dict[str, Any]): The ingestion pipeline blob (the graph).
|
|
@@ -103,6 +68,14 @@ class CollectionModel(BaseModel):
|
|
|
103
68
|
),
|
|
104
69
|
)
|
|
105
70
|
needs_reindex: bool = Field(description="True when a config change requires reindexing.")
|
|
71
|
+
missing_vectors: list[str] | None = Field(
|
|
72
|
+
default=None,
|
|
73
|
+
description="Named Qdrant vectors (meta_<slug>_dense / meta_<slug>_bm25) the schema's "
|
|
74
|
+
"semantic/lexical fields need but the vector store does not declare — those fields are not "
|
|
75
|
+
"searchable until the collection's index is rebuilt (a reingest cannot add them). Computed "
|
|
76
|
+
"on the single-collection read and the PATCH response ([] = aligned or never ingested); "
|
|
77
|
+
"null on the fleet list, which never reads the vector store.",
|
|
78
|
+
)
|
|
106
79
|
created_at: datetime | None = Field(default=None, description="Creation timestamp.")
|
|
107
80
|
title_field: str | None = Field(
|
|
108
81
|
default=None,
|
|
@@ -213,7 +186,10 @@ class UpdateCollectionRequest(BaseModel):
|
|
|
213
186
|
job_timeout_seconds (float | None): New per-collection whole-ingest-job wall-clock
|
|
214
187
|
job timeout, seconds. Omitted = leave the current value unchanged.
|
|
215
188
|
title_field (str | None): Display-title field. Omitted = unchanged; explicit null = clear.
|
|
216
|
-
fields (list[FieldSpec] | None):
|
|
189
|
+
fields (list[FieldSpec] | None): LEGACY full TARGET schema (omitted fields are removed).
|
|
190
|
+
field_ops (list[FieldOp] | None): Explicit add/update/remove/rename ops (exclusive with
|
|
191
|
+
``fields``).
|
|
192
|
+
dry_run (bool): Preview only — the response's ``schema_diff`` is computed, nothing written.
|
|
217
193
|
pipeline (dict[str, Any] | None): New pipeline blob (validated before storage).
|
|
218
194
|
search (dict[str, Any] | None): New search graph blob ({} = stock default).
|
|
219
195
|
estimate_overrides (EstimateOverrides | None): Partial cost-estimate overrides. Omitted =
|
|
@@ -256,7 +232,17 @@ class UpdateCollectionRequest(BaseModel):
|
|
|
256
232
|
)
|
|
257
233
|
fields: list[FieldSpec] | None = Field(
|
|
258
234
|
default=None,
|
|
259
|
-
description="
|
|
235
|
+
description="LEGACY full TARGET schema (omitted fields are REMOVED with their values). "
|
|
236
|
+
"Prefer field_ops. Mutually exclusive with field_ops.",
|
|
237
|
+
)
|
|
238
|
+
field_ops: list[FieldOp] | None = Field(
|
|
239
|
+
default=None,
|
|
240
|
+
description="Explicit schema operations applied in order (add / update / remove / rename). "
|
|
241
|
+
"Mutually exclusive with fields.",
|
|
242
|
+
)
|
|
243
|
+
dry_run: bool = Field(
|
|
244
|
+
default=False,
|
|
245
|
+
description="Validate and compute schema_diff only — nothing is written.",
|
|
260
246
|
)
|
|
261
247
|
pipeline: dict[str, Any] | None = Field(
|
|
262
248
|
default=None, description="New pipeline blob (validated before being stored)."
|
|
@@ -273,6 +259,19 @@ class UpdateCollectionRequest(BaseModel):
|
|
|
273
259
|
note: str | None = Field(default=None, description="Version note shown in the history.")
|
|
274
260
|
|
|
275
261
|
|
|
262
|
+
class UpdateCollectionResponse(CollectionModel):
|
|
263
|
+
"""
|
|
264
|
+
The PATCH result: the collection (unchanged under dry_run) plus its schema diff.
|
|
265
|
+
|
|
266
|
+
Attributes:
|
|
267
|
+
schema_diff (SchemaDiff): The schema change applied (or previewed); empty when untouched.
|
|
268
|
+
dry_run (bool): True when nothing was written.
|
|
269
|
+
"""
|
|
270
|
+
|
|
271
|
+
schema_diff: SchemaDiff = Field(description="The metadata-schema change applied or previewed.")
|
|
272
|
+
dry_run: bool = Field(description="True when nothing was written (preview only).")
|
|
273
|
+
|
|
274
|
+
|
|
276
275
|
class BulkReingestRequest(BaseModel):
|
|
277
276
|
"""
|
|
278
277
|
The re-run request over a collection's corpus (a full-pipeline re-ingest).
|
|
@@ -431,6 +430,7 @@ __all__ = [
|
|
|
431
430
|
"CollectionListItem",
|
|
432
431
|
"CreateCollectionRequest",
|
|
433
432
|
"UpdateCollectionRequest",
|
|
433
|
+
"UpdateCollectionResponse",
|
|
434
434
|
"BulkReingestRequest",
|
|
435
435
|
"ReingestJobHandle",
|
|
436
436
|
"BulkReingestAccepted",
|
|
@@ -323,8 +323,9 @@ class CostEstimate(BaseModel):
|
|
|
323
323
|
"""
|
|
324
324
|
The full pre-hoc breakdown — an ESTIMATE, with its assumptions and caveats surfaced.
|
|
325
325
|
|
|
326
|
-
``total_cost_usd``
|
|
327
|
-
|
|
326
|
+
``total_cost_usd`` is None as soon as any enabled cost-incurring stage priced to null
|
|
327
|
+
(``cost_complete`` False); ``total_cost_lower_bound_usd`` then carries the priced sum, and a
|
|
328
|
+
caveat names each unpriced model + stage + the override path.
|
|
328
329
|
|
|
329
330
|
Attributes:
|
|
330
331
|
document_count (int): Documents the estimate covers.
|
|
@@ -332,8 +333,10 @@ class CostEstimate(BaseModel):
|
|
|
332
333
|
volume (VolumeEstimate): Projected material volume.
|
|
333
334
|
total_prompt_tokens (int): Summed projected prompt/input tokens.
|
|
334
335
|
total_completion_tokens (int): Summed projected completion tokens.
|
|
335
|
-
total_cost_usd (float | None):
|
|
336
|
-
|
|
336
|
+
total_cost_usd (float | None): Total projected USD — None when any enabled cost-incurring
|
|
337
|
+
stage has no known rate.
|
|
338
|
+
total_cost_lower_bound_usd (float): Sum of the priced stages only (== the total when
|
|
339
|
+
complete, else a lower bound).
|
|
337
340
|
cost_complete (bool): True when every enabled cost-incurring stage had a known rate.
|
|
338
341
|
assumptions (EstimateAssumptions): The assumptions this estimate rests on.
|
|
339
342
|
caveats (list[str]): Human-readable accuracy caveats for this estimate.
|
|
@@ -348,7 +351,13 @@ class CostEstimate(BaseModel):
|
|
|
348
351
|
total_prompt_tokens: int = Field(description="Summed projected prompt/input tokens.")
|
|
349
352
|
total_completion_tokens: int = Field(description="Summed projected completion tokens.")
|
|
350
353
|
total_cost_usd: float | None = Field(
|
|
351
|
-
description="
|
|
354
|
+
description="Total projected USD — None when any enabled cost-incurring stage has no known "
|
|
355
|
+
"rate (see total_cost_lower_bound_usd and the caveats)."
|
|
356
|
+
)
|
|
357
|
+
total_cost_lower_bound_usd: float = Field(
|
|
358
|
+
default=0.0,
|
|
359
|
+
description="Sum of the PRICED stages only — equals total_cost_usd when the cost is "
|
|
360
|
+
"complete, else a lower bound of the true cost.",
|
|
352
361
|
)
|
|
353
362
|
cost_complete: bool = Field(
|
|
354
363
|
description="True when every enabled cost-incurring stage had a known rate."
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# ====== Code Summary ======
|
|
2
|
+
# FieldSpec — one metadata field of a collection's contract, mirrored from the backend
|
|
3
|
+
# ``FieldSpecModel``. Its own module so both the collections and the schema-ops models build on it.
|
|
4
|
+
|
|
5
|
+
# ====== Third-Party Library Imports ======
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
# ====== Local Project Imports ======
|
|
9
|
+
from ._shared import FieldOrigin, FieldScope, FieldType
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class FieldSpec(BaseModel):
|
|
13
|
+
"""
|
|
14
|
+
One metadata field of the collection's contract (declared OR generated).
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
field_name (str): Unique field name within the collection.
|
|
18
|
+
field_type (FieldType): Value type — drives validation and storage.
|
|
19
|
+
required (bool): Upload refused without it (user fields).
|
|
20
|
+
filterable (bool): Present in the Qdrant payload (lean vector).
|
|
21
|
+
lexical (bool): Gets a sparse BM25 named vector.
|
|
22
|
+
semantic (bool): Gets a dense named vector.
|
|
23
|
+
enum_values (list[str] | None): Allowed values when ``field_type`` is enum.
|
|
24
|
+
origin (FieldOrigin): user (declared at upload) or generated (metagen).
|
|
25
|
+
scope (FieldScope): document or chunk level value.
|
|
26
|
+
description (str | None): What the field means (max 1000 chars).
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
field_name: str = Field(description="Unique field name within the collection.")
|
|
30
|
+
field_type: FieldType = Field(description="Value type — drives validation and storage.")
|
|
31
|
+
required: bool = Field(default=False, description="Upload refused without it (user fields).")
|
|
32
|
+
filterable: bool = Field(default=False, description="Present in the Qdrant payload (lean).")
|
|
33
|
+
lexical: bool = Field(default=False, description="Gets a sparse BM25 named vector.")
|
|
34
|
+
semantic: bool = Field(default=False, description="Gets a dense named vector.")
|
|
35
|
+
enum_values: list[str] | None = Field(
|
|
36
|
+
default=None, description="Allowed values when field_type is enum."
|
|
37
|
+
)
|
|
38
|
+
origin: FieldOrigin = Field(
|
|
39
|
+
default=FieldOrigin.USER, description="user (declared at upload) or generated (metagen)."
|
|
40
|
+
)
|
|
41
|
+
scope: FieldScope = Field(
|
|
42
|
+
default=FieldScope.DOCUMENT, description="document or chunk level value."
|
|
43
|
+
)
|
|
44
|
+
description: str | None = Field(
|
|
45
|
+
default=None,
|
|
46
|
+
max_length=1000,
|
|
47
|
+
description="What the field means, in plain words — surfaced to search clients (max 1000).",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
__all__ = ["FieldSpec"]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# ====== Code Summary ======
|
|
2
|
+
# Response model for the collection index rebuild, mirrored field-for-field from the DocForge backend
|
|
3
|
+
# (POST /collections/{collection_id}/rebuild-index → 202).
|
|
4
|
+
|
|
5
|
+
# ====== Third-Party Library Imports ======
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RebuildIndexAccepted(BaseModel):
|
|
10
|
+
"""
|
|
11
|
+
A queued index rebuild — poll the job.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
collection_id (str): The collection being rebuilt.
|
|
15
|
+
job_id (str): The tracked ``rebuild_index`` job (GET /jobs/{job_id}).
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
collection_id: str = Field(description="The collection whose index is being rebuilt.")
|
|
19
|
+
job_id: str = Field(description="The tracked rebuild_index job — poll GET /jobs/{job_id}.")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = ["RebuildIndexAccepted"]
|
|
@@ -17,12 +17,15 @@ class JobStatus(BaseModel):
|
|
|
17
17
|
|
|
18
18
|
Attributes:
|
|
19
19
|
job_id (str): The job row's UUID.
|
|
20
|
-
document_id (str): The document being ingested.
|
|
20
|
+
document_id (str | None): The document being ingested (None for a rebuild_index job).
|
|
21
21
|
document_filename (str | None): The document's filename, joined at read (None if the
|
|
22
22
|
document is gone).
|
|
23
23
|
document_title (str | None): The document's metagen-generated title, joined at read — a
|
|
24
24
|
nicer display label than the filename when present (None if none was generated or the
|
|
25
25
|
document is gone; the UI falls back to document_filename).
|
|
26
|
+
display_title (str | None): The document's display title — the collection's
|
|
27
|
+
``title_field`` value when configured and set, else the parsed title (None when
|
|
28
|
+
neither exists, the document is gone, or on the SSE stream).
|
|
26
29
|
collection_id (str): Its collection.
|
|
27
30
|
collection_name (str | None): The collection's name, joined at read (None if the
|
|
28
31
|
collection is gone).
|
|
@@ -47,7 +50,9 @@ class JobStatus(BaseModel):
|
|
|
47
50
|
"""
|
|
48
51
|
|
|
49
52
|
job_id: str = Field(description="The job row's UUID.")
|
|
50
|
-
document_id: str = Field(
|
|
53
|
+
document_id: str | None = Field(
|
|
54
|
+
description="The document being ingested; null for a collection-level job (rebuild_index)."
|
|
55
|
+
)
|
|
51
56
|
document_filename: str | None = Field(
|
|
52
57
|
default=None,
|
|
53
58
|
description="The document's filename, joined at read (None if the document is gone).",
|
|
@@ -58,6 +63,14 @@ class JobStatus(BaseModel):
|
|
|
58
63
|
"than the filename when present (None if none was generated or the document is gone; the UI "
|
|
59
64
|
"falls back to document_filename).",
|
|
60
65
|
)
|
|
66
|
+
display_title: str | None = Field(
|
|
67
|
+
default=None,
|
|
68
|
+
description="The document's DISPLAY title, resolved at read exactly like the document "
|
|
69
|
+
"list/grid/detail `display_title`: the value of the collection's `title_field` when one is "
|
|
70
|
+
"configured and set on this document, else the parsed title. None when neither exists, the "
|
|
71
|
+
"document is gone, or on the SSE stream (which re-reads only the job row). Prefer it over "
|
|
72
|
+
"document_title for labelling; fall back to document_filename.",
|
|
73
|
+
)
|
|
61
74
|
collection_id: str = Field(description="Its collection.")
|
|
62
75
|
collection_name: str | None = Field(
|
|
63
76
|
default=None,
|
|
@@ -66,7 +79,8 @@ class JobStatus(BaseModel):
|
|
|
66
79
|
status: str = Field(description="queued / running / done / failed / cancelled.")
|
|
67
80
|
kind: str = Field(
|
|
68
81
|
description="The kind of work this job tracks: 'ingest' (a full document pipeline run) or "
|
|
69
|
-
"'metadata_sync' (a lightweight per-document metadata re-embed after an in-place value edit)
|
|
82
|
+
"'metadata_sync' (a lightweight per-document metadata re-embed after an in-place value edit) or "
|
|
83
|
+
"'rebuild_index' (a collection-level vector-store rebuild — document_id is null). "
|
|
70
84
|
"Lets a client render a side-job distinctly from a full ingestion."
|
|
71
85
|
)
|
|
72
86
|
cancel_requested: bool = Field(
|
|
@@ -195,7 +195,48 @@ class StageApplyResponse(BaseModel):
|
|
|
195
195
|
)
|
|
196
196
|
|
|
197
197
|
|
|
198
|
+
class CollectionStageApplyResponse(BaseModel):
|
|
199
|
+
"""
|
|
200
|
+
The outcome of a collection-scoped stage action (applied to the STORED pipeline, persisted if valid).
|
|
201
|
+
|
|
202
|
+
Attributes:
|
|
203
|
+
collection_id (str): The edited collection.
|
|
204
|
+
persisted (bool): True when the new pipeline was stored (a config version written).
|
|
205
|
+
needs_reindex (bool): The collection's derived reindex flag after the write.
|
|
206
|
+
stages (list[dict[str, Any]]): The redacted stage view of the result (opaque engine JSON).
|
|
207
|
+
valid (bool): True when the result built and has zero validation issues.
|
|
208
|
+
issues (list[dict[str, Any]]): Validation problems of the result.
|
|
209
|
+
notices (list[str]): Compiler notices plus the reason nothing was stored, if so.
|
|
210
|
+
build_error (str | None): Builder failure when the result cannot build (not persisted).
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
collection_id: str = Field(description="The edited collection.")
|
|
214
|
+
persisted: bool = Field(
|
|
215
|
+
description="True when the new pipeline was stored (a config version was written); false "
|
|
216
|
+
"when the result is invalid or the action changed nothing."
|
|
217
|
+
)
|
|
218
|
+
needs_reindex: bool = Field(
|
|
219
|
+
default=False,
|
|
220
|
+
description="The collection's derived reindex flag after the write (embed-space change).",
|
|
221
|
+
)
|
|
222
|
+
stages: list[dict[str, Any]] = Field(
|
|
223
|
+
description="The redacted stage view of the resulting pipeline, in run order."
|
|
224
|
+
)
|
|
225
|
+
valid: bool = Field(description="True when the result built and has zero validation issues.")
|
|
226
|
+
issues: list[dict[str, Any]] = Field(
|
|
227
|
+
default_factory=list, description="Validation problems of the result (empty when healthy)."
|
|
228
|
+
)
|
|
229
|
+
notices: list[str] = Field(
|
|
230
|
+
default_factory=list,
|
|
231
|
+
description="Compiler notices (cascades, ignored no-ops) and the reason nothing was stored.",
|
|
232
|
+
)
|
|
233
|
+
build_error: str | None = Field(
|
|
234
|
+
default=None, description="Builder failure when the result cannot build (not persisted)."
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
|
|
198
238
|
__all__ = [
|
|
239
|
+
"CollectionStageApplyResponse",
|
|
199
240
|
"PipelineSurface",
|
|
200
241
|
"PipelineIndexResponse",
|
|
201
242
|
"PipelineDesignResponse",
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# ====== Code Summary ======
|
|
2
|
+
# Collection metadata-schema operations, mirrored from the DocForge backend: the ``field_ops``
|
|
3
|
+
# discriminated union of a collection PATCH (add / update / remove / rename) and the ``SchemaDiff``
|
|
4
|
+
# every PATCH response carries (applied, or previewed under ``dry_run``).
|
|
5
|
+
|
|
6
|
+
# ====== Standard Library Imports ======
|
|
7
|
+
from typing import Annotated, Literal
|
|
8
|
+
|
|
9
|
+
# ====== Third-Party Library Imports ======
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
# ====== Local Project Imports ======
|
|
13
|
+
from ._shared import FieldOrigin, FieldScope, FieldType
|
|
14
|
+
from .field_spec import FieldSpec
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class FieldPatch(BaseModel):
|
|
18
|
+
"""
|
|
19
|
+
The attributes an ``update`` op changes — only the keys set are sent (null clears).
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
field_type / required / filterable / lexical / semantic / enum_values / origin / scope /
|
|
23
|
+
description: The new value of each attribute to change.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
field_type: FieldType | None = Field(default=None, description="New value type.")
|
|
27
|
+
required: bool | None = Field(default=None, description="New upload-required flag.")
|
|
28
|
+
filterable: bool | None = Field(default=None, description="New filterable flag.")
|
|
29
|
+
lexical: bool | None = Field(default=None, description="New lexical (BM25 vector) flag.")
|
|
30
|
+
semantic: bool | None = Field(default=None, description="New semantic (dense vector) flag.")
|
|
31
|
+
enum_values: list[str] | None = Field(
|
|
32
|
+
default=None, description="New allowed values (enum fields)."
|
|
33
|
+
)
|
|
34
|
+
origin: FieldOrigin | None = Field(default=None, description="New origin (user/generated).")
|
|
35
|
+
scope: FieldScope | None = Field(default=None, description="New scope (document/chunk).")
|
|
36
|
+
description: str | None = Field(
|
|
37
|
+
default=None, max_length=1000, description="New description (explicit null clears it)."
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AddFieldOp(BaseModel):
|
|
42
|
+
"""Add a new field (its name must not already exist)."""
|
|
43
|
+
|
|
44
|
+
op: Literal["add"] = Field(description="Operation tag.")
|
|
45
|
+
field: FieldSpec = Field(description="The full definition of the new field.")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class UpdateFieldOp(BaseModel):
|
|
49
|
+
"""Change some attributes of an existing field in place (its stored values are kept)."""
|
|
50
|
+
|
|
51
|
+
op: Literal["update"] = Field(description="Operation tag.")
|
|
52
|
+
field_name: str = Field(description="The existing field to update.")
|
|
53
|
+
changes: FieldPatch = Field(description="The attributes to change (only the keys set apply).")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class RemoveFieldOp(BaseModel):
|
|
57
|
+
"""Remove a field — DESTRUCTIVE: its stored document/chunk values are deleted with it."""
|
|
58
|
+
|
|
59
|
+
op: Literal["remove"] = Field(description="Operation tag.")
|
|
60
|
+
field_name: str = Field(description="The existing field to remove.")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class RenameFieldOp(BaseModel):
|
|
64
|
+
"""Rename a field in place — its stored values and a ``title_field`` pointing at it follow."""
|
|
65
|
+
|
|
66
|
+
op: Literal["rename"] = Field(description="Operation tag.")
|
|
67
|
+
field_name: str = Field(description="The existing field to rename.")
|
|
68
|
+
new_name: str = Field(min_length=1, description="Its new name (must not already exist).")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
FieldOp = Annotated[
|
|
72
|
+
AddFieldOp | UpdateFieldOp | RemoveFieldOp | RenameFieldOp,
|
|
73
|
+
Field(discriminator="op"),
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class SchemaDiffModifiedField(BaseModel):
|
|
78
|
+
"""One field updated in place, with the attributes that changed."""
|
|
79
|
+
|
|
80
|
+
field_name: str = Field(description="The field's (post-PATCH) name.")
|
|
81
|
+
changed_attrs: list[str] = Field(description="The attributes whose value changed.")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class SchemaDiffRename(BaseModel):
|
|
85
|
+
"""One field renamed in place (its values are kept)."""
|
|
86
|
+
|
|
87
|
+
from_name: str = Field(description="The field's previous name.")
|
|
88
|
+
to_name: str = Field(description="The field's new name.")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class SchemaDiff(BaseModel):
|
|
92
|
+
"""
|
|
93
|
+
The metadata-schema change of a collection PATCH (applied, or previewed under dry_run).
|
|
94
|
+
|
|
95
|
+
Attributes:
|
|
96
|
+
added (list[str]): Fields created.
|
|
97
|
+
modified (list[SchemaDiffModifiedField]): Fields updated in place (values kept).
|
|
98
|
+
removed (list[str]): Fields deleted with their stored values.
|
|
99
|
+
renamed (list[SchemaDiffRename]): Fields renamed in place (values kept).
|
|
100
|
+
values_lost (dict[str, int]): Removed field → stored document + chunk values deleted.
|
|
101
|
+
reindex_required_fields (list[str]): Fields needing a reindex before being searchable.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
added: list[str] = Field(default_factory=list, description="Fields created.")
|
|
105
|
+
modified: list[SchemaDiffModifiedField] = Field(
|
|
106
|
+
default_factory=list, description="Fields updated in place (values kept)."
|
|
107
|
+
)
|
|
108
|
+
removed: list[str] = Field(
|
|
109
|
+
default_factory=list, description="Fields deleted with their stored values."
|
|
110
|
+
)
|
|
111
|
+
renamed: list[SchemaDiffRename] = Field(
|
|
112
|
+
default_factory=list, description="Fields renamed in place (values kept)."
|
|
113
|
+
)
|
|
114
|
+
values_lost: dict[str, int] = Field(
|
|
115
|
+
default_factory=dict, description="Removed field → stored values deleted with it."
|
|
116
|
+
)
|
|
117
|
+
reindex_required_fields: list[str] = Field(
|
|
118
|
+
default_factory=list, description="Fields whose change needs a reindex to be searchable."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
__all__ = [
|
|
123
|
+
"FieldPatch",
|
|
124
|
+
"AddFieldOp",
|
|
125
|
+
"UpdateFieldOp",
|
|
126
|
+
"RemoveFieldOp",
|
|
127
|
+
"RenameFieldOp",
|
|
128
|
+
"FieldOp",
|
|
129
|
+
"SchemaDiff",
|
|
130
|
+
"SchemaDiffModifiedField",
|
|
131
|
+
"SchemaDiffRename",
|
|
132
|
+
]
|
|
@@ -240,16 +240,20 @@ class SearchCost(BaseModel):
|
|
|
240
240
|
|
|
241
241
|
class SearchHint(BaseModel):
|
|
242
242
|
"""
|
|
243
|
-
An actionable explanation
|
|
243
|
+
An actionable explanation attached to a (200) search response — a filter value no document
|
|
244
|
+
stores, the likely culprit of a filtered zero-hit search, a ``min_score`` that dropped every hit,
|
|
245
|
+
or a lexical metadata target the query gave no searchable term to.
|
|
244
246
|
|
|
245
247
|
Attributes:
|
|
246
|
-
field (str):
|
|
248
|
+
field (str): What the hint is about: a filtered or targeted metadata field, or ``min_score``.
|
|
247
249
|
value (Any): The filter value as sent.
|
|
248
250
|
message (str): Human/agent-readable explanation.
|
|
249
251
|
suggestions (list[str]): Closest stored values to retry with, best first (may be empty).
|
|
250
252
|
"""
|
|
251
253
|
|
|
252
|
-
field: str = Field(
|
|
254
|
+
field: str = Field(
|
|
255
|
+
description="What the hint is about: a filtered or targeted metadata field, or 'min_score'."
|
|
256
|
+
)
|
|
253
257
|
value: Any = Field(description="The filter value as sent (one list item, or the whole value).")
|
|
254
258
|
message: str = Field(description="Human/agent-readable explanation of the problem.")
|
|
255
259
|
suggestions: list[str] = Field(
|
|
@@ -278,7 +282,9 @@ class SearchResponse(BaseModel):
|
|
|
278
282
|
description="What every hit's ``score`` represents, so the UI labels it honestly: "
|
|
279
283
|
"'rrf_fusion' (Reciprocal Rank Fusion of the dense+sparse branches — the default; "
|
|
280
284
|
"rank-based, not a similarity), 'dbsf_fusion' (Distribution-Based Score Fusion), or "
|
|
281
|
-
"'cross_encoder_rerank' (a cross-encoder relevance score, when reranking is enabled)
|
|
285
|
+
"'cross_encoder_rerank' (a cross-encoder relevance score, when reranking is enabled), "
|
|
286
|
+
"'raw_dense' (ONE dense vector queried, no fusion — a cosine similarity) or 'raw_sparse' "
|
|
287
|
+
"(ONE sparse vector — its raw sparse dot / BM25 score, unbounded).",
|
|
282
288
|
)
|
|
283
289
|
cost: SearchCost | None = Field(
|
|
284
290
|
default=None,
|