Skip to main content

shilp_sdk/
models.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4// Generic response structure
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct GenericResponse {
7    pub success: bool,
8    pub message: String,
9}
10
11// Index type for a column
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(rename_all = "lowercase")]
14pub enum IndexType {
15    #[serde(rename = "hnsw")]
16    Hnsw,
17    #[serde(rename = "inverted")]
18    Inverted,
19    #[serde(rename = "metadata")]
20    Metadata,
21}
22
23// Storage backend types
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25#[repr(i32)]
26pub enum StorageBackendType {
27    DoesNotExist = -1,
28    File = 0,
29    S3 = 1,
30}
31
32impl<'de> Deserialize<'de> for StorageBackendType {
33    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
34    where
35        D: serde::Deserializer<'de>,
36    {
37        let value = i32::deserialize(deserializer)?;
38        match value {
39            -1 => Ok(StorageBackendType::DoesNotExist),
40            1 => Ok(StorageBackendType::File),
41            2 => Ok(StorageBackendType::S3),
42            _ => Err(serde::de::Error::custom(format!(
43                "Invalid storage backend type: {}",
44                value
45            ))),
46        }
47    }
48}
49
50impl Serialize for StorageBackendType {
51    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52    where
53        S: serde::Serializer,
54    {
55        serializer.serialize_i32(*self as i32)
56    }
57}
58
59impl StorageBackendType {
60    pub fn as_str(&self) -> &'static str {
61        match self {
62            StorageBackendType::File => "disk",
63            StorageBackendType::S3 => "s3",
64            StorageBackendType::DoesNotExist => "unknown",
65        }
66    }
67
68    pub fn is_valid(&self) -> bool {
69        matches!(self, StorageBackendType::File | StorageBackendType::S3)
70    }
71}
72
73// Attribute types
74#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75#[repr(i32)]
76pub enum AttrType {
77    Int64 = 0,
78    Float64 = 1,
79    String = 2,
80    Bool = 3,
81    Currency = 4,
82}
83
84impl AttrType {
85    pub fn as_str(&self) -> &'static str {
86        match self {
87            AttrType::Int64 => "int64",
88            AttrType::Float64 => "float64",
89            AttrType::String => "string",
90            AttrType::Bool => "bool",
91            AttrType::Currency => "currency",
92        }
93    }
94}
95
96impl<'de> Deserialize<'de> for AttrType {
97    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98    where
99        D: serde::Deserializer<'de>,
100    {
101        let value = i32::deserialize(deserializer)?;
102        match value {
103            0 => Ok(AttrType::Int64),
104            1 => Ok(AttrType::Float64),
105            2 => Ok(AttrType::String),
106            3 => Ok(AttrType::Bool),
107            4 => Ok(AttrType::Currency),
108            _ => Err(serde::de::Error::custom(format!(
109                "Invalid attribute type: {}",
110                value
111            ))),
112        }
113    }
114}
115
116// Attribute type for schema attributes
117#[derive(Debug, Clone, Copy, PartialEq, Eq)]
118#[repr(i32)]
119pub enum AttributeType {
120    Numerical = 1,
121    String = 2,
122}
123
124impl AttributeType {
125    pub fn as_str(&self) -> &'static str {
126        match self {
127            AttributeType::Numerical => "numerical",
128            AttributeType::String => "string",
129        }
130    }
131}
132
133impl<'de> Deserialize<'de> for AttributeType {
134    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
135    where
136        D: serde::Deserializer<'de>,
137    {
138        let value = i32::deserialize(deserializer)?;
139        match value {
140            1 => Ok(AttributeType::Numerical),
141            2 => Ok(AttributeType::String),
142            _ => Err(serde::de::Error::custom(format!(
143                "Invalid attribute type: {}",
144                value
145            ))),
146        }
147    }
148}
149
150impl Serialize for AttributeType {
151    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
152    where
153        S: serde::Serializer,
154    {
155        serializer.serialize_i32(*self as i32)
156    }
157}
158
159impl Serialize for AttrType {
160    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
161    where
162        S: serde::Serializer,
163    {
164        serializer.serialize_i32(*self as i32)
165    }
166}
167
168// Metadata column schema
169#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct MetadataColumnSchema {
171    pub name: String,
172    #[serde(rename = "type")]
173    pub attr_type: AttrType,
174}
175
176// Collection structure
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct Collection {
179    pub name: String,
180    pub is_loaded: bool,
181    pub fields: Option<Vec<String>>,
182    pub searchable_fields: Option<Vec<String>>,
183    #[serde(skip_serializing_if = "Option::is_none")]
184    pub field_config: Option<HashMap<String, IndexType>>,
185    #[serde(default)]
186    pub metadata: Option<Vec<MetadataColumnSchema>>,
187    pub has_metadata_enabled: bool,
188    pub no_reference_storage: bool,
189    pub storage_type: StorageBackendType,
190    pub reference_storage_type: StorageBackendType,
191    #[serde(skip_serializing_if = "Option::is_none")]
192    pub is_pq_enabled: Option<bool>,
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub is_nli_enabled: Option<bool>,
195    #[serde(skip_serializing_if = "Option::is_none")]
196    pub nli_domain: Option<String>,
197    #[serde(default)]
198    pub total_no_of_documents: i32,
199}
200
201#[derive(Debug, Clone, Serialize, Deserialize, Default)]
202pub struct EnableMetadataStoreRequest {
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub fields: Option<Vec<MetadataColumnSchema>>,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize)]
208pub struct EnableMetadataStoreResponse {
209    pub success: bool,
210    pub message: String,
211    #[serde(skip_serializing_if = "Option::is_none")]
212    pub records_indexed: Option<i32>,
213}
214
215// Metadata support info
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct MetadataSupportInfo {
218    pub support_metadata: bool,
219    pub name: String,
220    #[serde(rename = "type")]
221    pub storage_type: StorageBackendType,
222    pub is_default: bool,
223}
224
225// List collections response
226#[derive(Debug, Clone, Serialize, Deserialize)]
227pub struct ListCollectionsResponse {
228    pub success: bool,
229    pub message: String,
230    pub data: Vec<Collection>,
231    pub metadata_info: Vec<MetadataSupportInfo>,
232    #[serde(default)]
233    pub is_nli_supported: bool,
234}
235
236// Add collection request
237#[derive(Debug, Clone, Serialize, Deserialize)]
238pub struct AddCollectionRequest {
239    pub name: String,
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub no_reference_storage: Option<bool>,
242    #[serde(skip_serializing_if = "Option::is_none")]
243    pub has_metadata_storage: Option<bool>,
244    #[serde(skip_serializing_if = "Option::is_none")]
245    pub storage_type: Option<StorageBackendType>,
246    #[serde(skip_serializing_if = "Option::is_none")]
247    pub reference_storage_type: Option<StorageBackendType>,
248    #[serde(skip_serializing_if = "Option::is_none")]
249    pub enable_pq: Option<bool>,
250}
251
252// Get collection data response
253#[derive(Debug, Clone, Serialize, Deserialize)]
254pub struct GetCollectionDataResponse {
255    pub success: bool,
256    pub message: String,
257    pub data: Vec<CollectionDataRecord>,
258    pub total: i32,
259}
260
261// Collection data record
262#[derive(Debug, Clone, Serialize, Deserialize)]
263pub struct CollectionDataRecord {
264    pub id: String,
265    pub data: HashMap<String, serde_json::Value>,
266    #[serde(skip_serializing_if = "Option::is_none")]
267    pub vectors: Option<HashMap<String, Vec<f32>>>,
268}
269
270// Get collection schema response
271#[derive(Debug, Clone, Serialize, Deserialize)]
272pub struct GetCollectionSchemaResponse {
273    pub success: bool,
274    #[serde(skip_serializing_if = "Option::is_none")]
275    pub message: Option<String>,
276    #[serde(skip_serializing_if = "Option::is_none")]
277    pub data: Option<CollectionSchema>,
278}
279
280// Collection schema
281#[derive(Debug, Clone, Serialize, Deserialize)]
282pub struct CollectionSchema {
283    #[serde(skip_serializing_if = "Option::is_none")]
284    pub attributes: Option<Vec<Attribute>>,
285    #[serde(skip_serializing_if = "Option::is_none")]
286    pub value_schema: Option<Vec<CategorySchema>>,
287}
288
289// Attribute in a collection schema
290#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct Attribute {
292    #[serde(skip_serializing_if = "Option::is_none")]
293    pub name: Option<String>,
294    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
295    pub attr_type: Option<AttributeType>,
296    #[serde(skip_serializing_if = "Option::is_none")]
297    pub index_type: Option<IndexType>,
298    #[serde(skip_serializing_if = "Option::is_none")]
299    pub is_metadata: Option<bool>,
300}
301
302// Category schema for inverted-index fields
303#[derive(Debug, Clone, Serialize, Deserialize)]
304pub struct CategorySchema {
305    #[serde(skip_serializing_if = "Option::is_none")]
306    pub name: Option<String>,
307    #[serde(skip_serializing_if = "Option::is_none")]
308    pub index_type: Option<IndexType>,
309    #[serde(skip_serializing_if = "Option::is_none")]
310    pub values: Option<Vec<CategoryValue>>,
311    #[serde(skip_serializing_if = "Option::is_none")]
312    pub synonyms: Option<Vec<String>>,
313}
314
315// Category value
316#[derive(Debug, Clone, Serialize, Deserialize)]
317pub struct CategoryValue {
318    #[serde(skip_serializing_if = "Option::is_none")]
319    pub value: Option<String>,
320    #[serde(skip_serializing_if = "Option::is_none")]
321    pub count: Option<i32>,
322}
323
324// Vector create config
325#[derive(Debug, Clone, Serialize, Deserialize, Default)]
326pub struct VectorCreateConfig {
327    #[serde(skip_serializing_if = "Option::is_none")]
328    pub ef_construction: Option<i32>,
329}
330
331// Record data
332#[derive(Debug, Clone, Serialize, Deserialize)]
333pub struct RecordData {
334    pub id: String,
335    pub expiry: Option<i64>,
336    pub fields: HashMap<String, serde_json::Value>,
337    #[serde(skip_serializing_if = "Option::is_none")]
338    pub keyword_fields: Option<HashMap<String, bool>>,
339    #[serde(skip_serializing_if = "Option::is_none")]
340    pub metadata_fields: Option<HashMap<String, i32>>,
341}
342
343// Insert record request
344#[derive(Debug, Clone, Serialize, Deserialize)]
345pub struct InsertRecordRequest {
346    pub collection: String,
347    #[serde(skip_serializing_if = "Option::is_none")]
348    pub expiry: Option<i64>,
349    #[serde(skip_serializing_if = "Option::is_none")]
350    pub id: Option<String>,
351    pub record: HashMap<String, serde_json::Value>,
352    #[serde(skip_serializing_if = "Option::is_none")]
353    pub metadata_fields: Option<HashMap<String, AttrType>>,
354    #[serde(skip_serializing_if = "Option::is_none")]
355    pub embedding_provider: Option<String>,
356    #[serde(skip_serializing_if = "Option::is_none")]
357    pub fields: Option<Vec<String>>,
358    #[serde(skip_serializing_if = "Option::is_none")]
359    pub keyword_fields: Option<Vec<String>>,
360    #[serde(skip_serializing_if = "Option::is_none")]
361    pub vectors: Option<HashMap<String, Vec<f32>>>,
362    #[serde(skip_serializing_if = "Option::is_none")]
363    pub model: Option<String>,
364    #[serde(skip_serializing_if = "Option::is_none")]
365    pub vector_config: Option<HashMap<String, VectorCreateConfig>>,
366    #[serde(skip_serializing_if = "Option::is_none")]
367    pub array_fields: Option<Vec<String>>,
368}
369
370// Insert record response
371#[derive(Debug, Clone, Serialize, Deserialize)]
372pub struct InsertRecordResponse {
373    pub success: bool,
374    pub message: String,
375    #[serde(skip_serializing_if = "Option::is_none")]
376    pub record: Option<RecordData>,
377    #[serde(skip_serializing_if = "Option::is_none")]
378    pub remaining_records: Option<i32>,
379}
380
381// Ingest source type
382#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
383#[serde(rename_all = "lowercase")]
384pub enum IngestSourceType {
385    File,
386    #[serde(rename = "mongodb")]
387    MongoDB,
388    #[serde(rename = "anvitra")]
389    Anvitra,
390}
391
392impl IngestSourceType {
393    pub fn is_valid(&self) -> bool {
394        matches!(
395            self,
396            IngestSourceType::File | IngestSourceType::MongoDB | IngestSourceType::Anvitra
397        )
398    }
399}
400
401// Ingest request
402#[derive(Debug, Clone, Serialize, Deserialize)]
403pub struct IngestRequest {
404    #[serde(skip_serializing_if = "Option::is_none")]
405    pub file_path: Option<String>,
406    #[serde(skip_serializing_if = "Option::is_none")]
407    pub source_type: Option<IngestSourceType>,
408    #[serde(skip_serializing_if = "Option::is_none")]
409    pub database_name: Option<String>,
410    #[serde(skip_serializing_if = "Option::is_none")]
411    pub mongo_collection: Option<String>,
412    #[serde(skip_serializing_if = "Option::is_none")]
413    pub query: Option<HashMap<String, serde_json::Value>>,
414    #[serde(skip_serializing_if = "Option::is_none")]
415    pub mongo_fetch_batch_size: Option<i32>,
416    pub collection_name: String,
417    #[serde(skip_serializing_if = "Option::is_none")]
418    pub keyword_fields: Option<Vec<String>>,
419    #[serde(skip_serializing_if = "Option::is_none")]
420    pub metadata_fields: Option<HashMap<String, AttrType>>,
421    pub fields: Vec<String>,
422    #[serde(skip_serializing_if = "Option::is_none")]
423    pub array_fields: Option<Vec<String>>,
424    #[serde(skip_serializing_if = "Option::is_none")]
425    pub id_field: Option<String>,
426    #[serde(skip_serializing_if = "Option::is_none")]
427    pub expiry_field: Option<String>,
428    #[serde(skip_serializing_if = "Option::is_none")]
429    pub embedding_provider: Option<String>,
430    #[serde(skip_serializing_if = "Option::is_none")]
431    pub embedding_model: Option<String>,
432    #[serde(skip_serializing_if = "Option::is_none")]
433    pub ingestion_batch_size: Option<i32>,
434    #[serde(skip_serializing_if = "Option::is_none")]
435    pub vector_config: Option<HashMap<String, VectorCreateConfig>>,
436}
437
438// Ingest response
439#[derive(Debug, Clone, Serialize, Deserialize)]
440pub struct IngestResponse {
441    pub success: bool,
442    pub message: String,
443    #[serde(skip_serializing_if = "Option::is_none")]
444    pub details: Option<Vec<String>>,
445}
446
447// List ingestion sources response
448#[derive(Debug, Clone, Serialize, Deserialize)]
449pub struct ListIngestionSourcesResponse {
450    pub message: String,
451    pub success: bool,
452    #[serde(skip_serializing_if = "Option::is_none")]
453    pub data: Option<Vec<IngestSourceType>>,
454}
455
456// Vertical info for NLI
457#[derive(Debug, Clone, Serialize, Deserialize)]
458pub struct VerticalInfo {
459    #[serde(skip_serializing_if = "Option::is_none")]
460    pub name: Option<String>,
461    #[serde(skip_serializing_if = "Option::is_none")]
462    pub label: Option<String>,
463    #[serde(skip_serializing_if = "Option::is_none")]
464    pub models: Option<Vec<NLIModelInfo>>,
465    #[serde(skip_serializing_if = "Option::is_none")]
466    pub is_native: Option<bool>,
467    #[serde(skip_serializing_if = "Option::is_none")]
468    pub version: Option<String>,
469}
470
471// NLI model info
472#[derive(Debug, Clone, Serialize, Deserialize)]
473pub struct NLIModelInfo {
474    #[serde(skip_serializing_if = "Option::is_none")]
475    pub name: Option<String>,
476    #[serde(skip_serializing_if = "Option::is_none")]
477    pub version: Option<String>,
478}
479
480// List NLI verticals response
481#[derive(Debug, Clone, Serialize, Deserialize)]
482pub struct ListNLIVerticalsResponse {
483    pub success: bool,
484    #[serde(skip_serializing_if = "Option::is_none")]
485    pub data: Option<Vec<VerticalInfo>>,
486    #[serde(skip_serializing_if = "Option::is_none")]
487    pub message: Option<String>,
488}
489
490// File reader options
491#[derive(Debug, Clone, Serialize, Deserialize, Default)]
492pub struct FileReaderOptions {
493    #[serde(skip_serializing_if = "Option::is_none")]
494    pub source: Option<IngestSourceType>,
495    #[serde(skip_serializing_if = "Option::is_none")]
496    pub mongo_filter: Option<HashMap<String, serde_json::Value>>,
497    #[serde(skip_serializing_if = "Option::is_none")]
498    pub skip: Option<i32>,
499    #[serde(skip_serializing_if = "Option::is_none")]
500    pub limit: Option<i32>,
501}
502
503// Filter operations
504#[derive(Debug, Clone, Copy, PartialEq, Eq)]
505#[repr(i32)]
506pub enum FilterOp {
507    Unknown = -1,
508    Equals = 0,
509    NotEquals = 1,
510    GreaterThan = 2,
511    GreaterThanOrEqual = 3,
512    LessThan = 4,
513    LessThanOrEqual = 5,
514    In = 6,
515    NotIn = 7,
516}
517
518impl FilterOp {
519    pub fn as_str(&self) -> &'static str {
520        match self {
521            FilterOp::Unknown => "unknown",
522            FilterOp::Equals => "=",
523            FilterOp::NotEquals => "!=",
524            FilterOp::GreaterThan => ">",
525            FilterOp::GreaterThanOrEqual => ">=",
526            FilterOp::LessThan => "<",
527            FilterOp::LessThanOrEqual => "<=",
528            FilterOp::In => "IN",
529            FilterOp::NotIn => "NOT IN",
530        }
531    }
532}
533
534impl<'de> Deserialize<'de> for FilterOp {
535    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
536    where
537        D: serde::Deserializer<'de>,
538    {
539        let value = i32::deserialize(deserializer)?;
540        match value {
541            -1 => Ok(FilterOp::Unknown),
542            0 => Ok(FilterOp::Equals),
543            1 => Ok(FilterOp::NotEquals),
544            2 => Ok(FilterOp::GreaterThan),
545            3 => Ok(FilterOp::GreaterThanOrEqual),
546            4 => Ok(FilterOp::LessThan),
547            5 => Ok(FilterOp::LessThanOrEqual),
548            6 => Ok(FilterOp::In),
549            7 => Ok(FilterOp::NotIn),
550            _ => Err(serde::de::Error::custom(format!(
551                "Invalid attribute type: {}",
552                value
553            ))),
554        }
555    }
556}
557
558impl Serialize for FilterOp {
559    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
560    where
561        S: serde::Serializer,
562    {
563        serializer.serialize_i32(*self as i32)
564    }
565}
566
567// Filter expression
568#[derive(Debug, Clone, Serialize, Deserialize)]
569pub struct FilterExpression {
570    #[serde(skip_serializing_if = "Option::is_none")]
571    pub attribute: Option<String>,
572    #[serde(skip_serializing_if = "Option::is_none")]
573    pub op: Option<FilterOp>,
574    #[serde(skip_serializing_if = "Option::is_none")]
575    pub value: Option<serde_json::Value>,
576    #[serde(skip_serializing_if = "Option::is_none")]
577    pub values: Option<Vec<serde_json::Value>>,
578    #[serde(skip_serializing_if = "Option::is_none")]
579    pub filters: Option<Box<CompoundFilter>>,
580}
581
582// Compound filter
583#[derive(Debug, Clone, Serialize, Deserialize, Default)]
584pub struct CompoundFilter {
585    #[serde(skip_serializing_if = "Option::is_none")]
586    pub and: Option<Vec<FilterExpression>>,
587    #[serde(skip_serializing_if = "Option::is_none")]
588    pub or: Option<Vec<FilterExpression>>,
589}
590
591// Sort order
592#[derive(Debug, Clone, Copy, PartialEq, Eq)]
593#[repr(i32)]
594pub enum SortOrder {
595    Ascending = 0,
596    Descending = 1,
597}
598
599impl SortOrder {
600    pub fn as_str(&self) -> &'static str {
601        match self {
602            SortOrder::Ascending => "ASC",
603            SortOrder::Descending => "DESC",
604        }
605    }
606}
607
608impl<'de> Deserialize<'de> for SortOrder {
609    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
610    where
611        D: serde::Deserializer<'de>,
612    {
613        let value = i32::deserialize(deserializer)?;
614        match value {
615            0 => Ok(SortOrder::Ascending),
616            1 => Ok(SortOrder::Descending),
617            _ => Err(serde::de::Error::custom(format!(
618                "Invalid sort order: {}",
619                value
620            ))),
621        }
622    }
623}
624
625impl Serialize for SortOrder {
626    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
627    where
628        S: serde::Serializer,
629    {
630        serializer.serialize_i32(*self as i32)
631    }
632}
633
634// Sort expression
635#[derive(Debug, Clone, Serialize, Deserialize)]
636pub struct SortExpression {
637    pub attribute: String,
638    pub order: SortOrder,
639}
640
641// Compound sort
642#[derive(Debug, Clone, Serialize, Deserialize, Default)]
643pub struct CompoundSort {
644    #[serde(skip_serializing_if = "Option::is_none")]
645    pub sorts: Option<Vec<SortExpression>>,
646}
647
648// Vector search config
649#[derive(Debug, Clone, Serialize, Deserialize, Default)]
650pub struct VectorSearchConfig {
651    #[serde(skip_serializing_if = "Option::is_none")]
652    pub ef_search: Option<i32>,
653}
654
655// Search request
656#[derive(Debug, Clone, Serialize, Deserialize)]
657pub struct SearchRequest {
658    pub collection: String,
659    #[serde(skip_serializing_if = "Option::is_none")]
660    pub query: Option<String>,
661    #[serde(skip_serializing_if = "Option::is_none")]
662    pub fields: Option<Vec<String>>,
663    #[serde(skip_serializing_if = "Option::is_none")]
664    pub limit: Option<i32>,
665    #[serde(skip_serializing_if = "Option::is_none")]
666    pub weights: Option<HashMap<String, f64>>,
667    #[serde(skip_serializing_if = "Option::is_none")]
668    pub max_distance: Option<f64>,
669    #[serde(skip_serializing_if = "Option::is_none")]
670    pub filters: Option<CompoundFilter>,
671    #[serde(skip_serializing_if = "Option::is_none")]
672    pub sort: Option<CompoundSort>,
673    #[serde(skip_serializing_if = "Option::is_none")]
674    pub vector_query: Option<Vec<f32>>,
675    #[serde(skip_serializing_if = "Option::is_none")]
676    pub use_nli: Option<bool>,
677    #[serde(skip_serializing_if = "Option::is_none")]
678    pub field_config: Option<HashMap<String, VectorSearchConfig>>,
679    #[serde(skip_serializing_if = "Option::is_none")]
680    pub queries: Option<HashMap<String, String>>,
681    #[serde(skip_serializing_if = "Option::is_none")]
682    pub vector_queries: Option<HashMap<String, Vec<f32>>>,
683    #[serde(skip_serializing_if = "Option::is_none")]
684    pub fuzzy_algo: Option<FuzzyAlgo>,
685}
686
687#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
688pub enum FuzzyAlgo {
689    #[serde(rename = "levenshtein")]
690    Levenshtein,
691    #[serde(rename = "jaro_winkler")]
692    JaroWinkler,
693}
694
695// Search response
696#[derive(Debug, Clone, Serialize, Deserialize)]
697pub struct SearchResponse {
698    pub success: bool,
699    pub message: Option<String>,
700    pub data: Vec<HashMap<String, serde_json::Value>>,
701    #[serde(skip_serializing_if = "Option::is_none")]
702    pub interpretation: Option<Query>,
703    #[serde(skip_serializing_if = "Option::is_none")]
704    pub timing: Option<SearchTiming>,
705}
706
707#[derive(Debug, Clone, Serialize, Deserialize)]
708pub struct SearchTiming {
709    #[serde(skip_serializing_if = "Option::is_none")]
710    pub interpretation_ms: Option<i64>,
711    #[serde(skip_serializing_if = "Option::is_none")]
712    pub embedding_ms: Option<i64>,
713    #[serde(skip_serializing_if = "Option::is_none")]
714    pub metadata_filter_ms: Option<i64>,
715    #[serde(skip_serializing_if = "Option::is_none")]
716    pub search_ms: Option<i64>,
717    pub total_ms: i64,
718}
719
720// Query interpretation from NLI
721#[derive(Debug, Clone, Serialize, Deserialize)]
722pub struct Query {
723    pub vector_query: VectorQueryInterpretation,
724    pub filters: Vec<NliFilter>,
725    pub value_filters: Vec<NliValueFilter>,
726}
727
728// Vector query interpretation
729#[derive(Debug, Clone, Serialize, Deserialize)]
730pub struct VectorQueryInterpretation {
731    pub resolved_by: Vec<String>,
732    pub vector_query: String,
733    #[serde(skip_serializing_if = "Option::is_none")]
734    pub vector_queries: Option<HashMap<String, String>>,
735    #[serde(skip_serializing_if = "Option::is_none")]
736    pub vector_confidences: Option<HashMap<String, f32>>,
737}
738
739// Filter operator string for NLI
740#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
741pub enum FilterOperator {
742    #[serde(rename = "EQ")]
743    Equals,
744    #[serde(rename = "NEQ")]
745    NotEquals,
746    #[serde(rename = "GT")]
747    GreaterThan,
748    #[serde(rename = "LT")]
749    LessThan,
750    #[serde(rename = "GTE")]
751    GreaterEqual,
752    #[serde(rename = "LTE")]
753    LessEqual,
754    #[serde(rename = "IN")]
755    In,
756    #[serde(rename = "NOT IN")]
757    NotIn,
758}
759
760// Token in an NLI query
761#[derive(Debug, Clone, Serialize, Deserialize)]
762pub struct Token {
763    pub text: String,
764    pub tag: String,
765    pub label: String,
766}
767
768// Numerical value in an NLI filter
769#[derive(Debug, Clone, Serialize, Deserialize)]
770pub struct NumericalValue {
771    pub unit: String,
772    pub base_value: f64,
773    pub multiplier: f64,
774    pub total_value: f64,
775    pub original_text: String,
776}
777
778// NLI filter expression
779#[derive(Debug, Clone, Serialize, Deserialize)]
780pub struct NliFilter {
781    pub resolved_by: Vec<String>,
782    pub attribute: Vec<Token>,
783    pub operation: Token,
784    pub operator: FilterOperator,
785    pub value: Vec<Token>,
786    pub is_numerical: bool,
787    pub grounded: bool,
788    #[serde(skip_serializing_if = "Option::is_none")]
789    pub numerical_value: Option<NumericalValue>,
790}
791
792// NLI value filter
793#[derive(Debug, Clone, Serialize, Deserialize)]
794pub struct NliValueFilter {
795    pub resolved_by: Vec<String>,
796    pub attribute: Vec<Token>,
797    pub values: Vec<Vec<Token>>,
798    pub grounded: bool,
799    pub operator: FilterOperator,
800}
801
802// Storage item
803#[derive(Debug, Clone, Serialize, Deserialize)]
804pub struct StorageItem {
805    pub name: String,
806    #[serde(rename = "isDir")]
807    pub is_dir: bool,
808}
809
810// Storage data
811#[derive(Debug, Clone, Serialize, Deserialize)]
812pub struct StorageData {
813    pub items: Vec<StorageItem>,
814}
815
816// List storage response
817#[derive(Debug, Clone, Serialize, Deserialize)]
818pub struct ListStorageResponse {
819    pub success: bool,
820    pub message: String,
821    pub data: StorageData,
822}
823
824// Read document response
825#[derive(Debug, Clone, Serialize, Deserialize)]
826pub struct ReadDocumentResponse {
827    pub success: bool,
828    pub message: String,
829    pub data: Vec<HashMap<String, String>>,
830}
831
832// Health response
833#[derive(Debug, Clone, Serialize, Deserialize)]
834pub struct HealthResponse {
835    pub success: bool,
836    pub version: String,
837}
838
839// Debug get embeddings response
840#[derive(Debug, Clone, Serialize, Deserialize)]
841pub struct DebugGetEmbeddingsResponse {
842    pub success: bool,
843    pub message: String,
844    pub data: Vec<Vec<f32>>,
845}
846
847// Debug get embeddings request
848#[derive(Debug, Clone, Serialize, Deserialize)]
849pub struct DebugGetEmbeddingsRequest {
850    pub texts: Vec<String>,
851}
852
853// Debug distance data
854#[derive(Debug, Clone, Serialize, Deserialize)]
855pub struct DebugDistanceData {
856    pub distance: f64,
857    pub custom_matcher_distance: Option<f64>,
858    pub vector: Vec<f64>,
859}
860
861// Debug distance response
862#[derive(Debug, Clone, Serialize, Deserialize)]
863pub struct DebugDistanceResponse {
864    pub success: bool,
865    pub message: String,
866    pub data: DebugDistanceData,
867}
868
869// Debug neighbor
870#[derive(Debug, Clone, Serialize, Deserialize)]
871pub struct DebugNeighbor {
872    pub node_id: i32,
873    pub vector_id: String,
874    pub field: String,
875    pub distance: f64,
876    pub metadata: HashMap<String, serde_json::Value>,
877}
878
879// Debug node info
880#[derive(Debug, Clone, Serialize, Deserialize)]
881pub struct DebugNodeInfo {
882    pub node_id: i32,
883    pub vector_id: String,
884    pub field: String,
885    pub level: i32,
886    pub metadata: HashMap<String, serde_json::Value>,
887    pub neighbors: Vec<DebugNeighbor>,
888}
889
890// Debug node info response
891#[derive(Debug, Clone, Serialize, Deserialize)]
892pub struct DebugNodeInfoResponse {
893    pub success: bool,
894    pub message: String,
895    pub data: Option<DebugNodeInfo>,
896}
897
898// Debug level info
899#[derive(Debug, Clone, Serialize, Deserialize)]
900pub struct DebugLevelInfo {
901    pub level: i32,
902    pub node_count: i32,
903}
904
905// Debug levels response
906#[derive(Debug, Clone, Serialize, Deserialize)]
907pub struct DebugLevelsResponse {
908    pub success: bool,
909    pub message: String,
910    pub data: HashMap<String, Vec<DebugLevelInfo>>,
911}
912
913// Debug nodes at level response
914#[derive(Debug, Clone, Serialize, Deserialize)]
915pub struct DebugNodesAtLevelResponse {
916    pub success: bool,
917    pub message: String,
918    pub data: HashMap<String, Vec<i32>>,
919}
920
921// Debug vector node
922#[derive(Debug, Clone, Serialize, Deserialize)]
923pub struct DebugVectorNode {
924    pub id: i32,
925    pub field: String,
926    pub vector: Vec<f64>,
927}
928
929// Debug reference node
930#[derive(Debug, Clone, Serialize, Deserialize)]
931pub struct DebugReferenceNode {
932    pub id: String,
933    pub metadata: HashMap<String, serde_json::Value>,
934    pub nodes: Vec<DebugVectorNode>,
935}
936
937// Debug reference node response
938#[derive(Debug, Clone, Serialize, Deserialize)]
939pub struct DebugReferenceNodeResponse {
940    pub success: bool,
941    pub message: String,
942    pub data: Option<DebugReferenceNode>,
943}
944
945// Embedding model
946#[derive(Debug, Clone, Serialize, Deserialize)]
947pub struct EmbeddingModel {
948    pub name: String,
949    pub is_default: bool,
950}
951
952// Embedding provider
953#[derive(Debug, Clone, Serialize, Deserialize)]
954pub struct EmbeddingProvider {
955    pub name: String,
956    pub is_default: bool,
957    pub models: Vec<EmbeddingModel>,
958}
959
960// List embedding models response
961#[derive(Debug, Clone, Serialize, Deserialize)]
962pub struct ListEmbeddingModelsResponse {
963    pub success: bool,
964    pub message: String,
965    pub data: Vec<EmbeddingProvider>,
966    pub supports_distributed_embedding: bool,
967}
968
969// Oplog operation types
970#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
971#[serde(rename_all = "lowercase")]
972pub enum OpType {
973    Insert,
974    Update,
975    Delete,
976    #[serde(rename = "drop_collection")]
977    DropCollection,
978    #[serde(rename = "rename_collection")]
979    RenameCollection,
980}
981
982// Record
983#[derive(Debug, Clone, Serialize, Deserialize)]
984pub struct Record {
985    pub id: String,
986    pub fields: HashMap<String, serde_json::Value>,
987    #[serde(skip_serializing_if = "Option::is_none")]
988    pub keyword_fields: Option<HashMap<String, bool>>,
989    #[serde(skip_serializing_if = "Option::is_none")]
990    pub metadata_fields: Option<HashMap<String, AttrType>>,
991    #[serde(skip)]
992    pub vectors: Option<HashMap<String, Vec<f32>>>,
993    #[serde(skip)]
994    pub dist: Option<f32>,
995    #[serde(skip)]
996    pub nodes: Option<Vec<String>>,
997    #[serde(skip_serializing_if = "Option::is_none")]
998    pub expiry: Option<i64>,
999}
1000
1001// Oplog entry
1002#[derive(Debug, Clone, Serialize, Deserialize)]
1003pub struct OplogEntry {
1004    pub lsn: u64,
1005    pub timestamp: String,
1006    pub collection: String,
1007    pub doc_id: String,
1008    pub op_type: OpType,
1009    #[serde(skip_serializing_if = "Option::is_none")]
1010    pub vector: Option<Vec<f32>>,
1011    #[serde(skip_serializing_if = "Option::is_none")]
1012    pub metadata: Option<HashMap<String, serde_json::Value>>,
1013    #[serde(skip_serializing_if = "Option::is_none")]
1014    pub keywords: Option<Vec<String>>,
1015    #[serde(skip_serializing_if = "Option::is_none")]
1016    pub full_doc: Option<Record>,
1017    #[serde(skip_serializing_if = "Option::is_none")]
1018    pub vectors: Option<HashMap<String, Vec<f32>>>,
1019    #[serde(skip_serializing_if = "Option::is_none")]
1020    pub fields: Option<HashMap<String, serde_json::Value>>,
1021    #[serde(skip_serializing_if = "Option::is_none")]
1022    pub keyword_fields: Option<HashMap<String, bool>>,
1023    #[serde(skip_serializing_if = "Option::is_none")]
1024    pub metadata_fields: Option<HashMap<String, AttrType>>,
1025    #[serde(skip_serializing_if = "Option::is_none")]
1026    pub expiry: Option<i64>,
1027    #[serde(skip_serializing_if = "Option::is_none")]
1028    pub new_name: Option<String>,
1029}
1030
1031// Oplog status response
1032#[derive(Debug, Clone, Serialize, Deserialize)]
1033pub struct OplogStatusResponse {
1034    pub success: bool,
1035    pub message: String,
1036    pub last_lsn: u64,
1037    pub retention_lsn: u64,
1038    pub replica_count: i32,
1039}
1040
1041#[derive(Debug, Clone, Serialize, Deserialize)]
1042pub struct GetSettingsResponse {
1043    pub success: bool,
1044    pub message: String,
1045    #[serde(skip_serializing_if = "Option::is_none")]
1046    pub data: Option<Settings>,
1047}
1048
1049#[derive(Debug, Clone, Serialize, Deserialize)]
1050pub struct Settings {
1051    pub auth: SettingsAuth,
1052    #[serde(rename = "allowedOrigins", skip_serializing_if = "Option::is_none")]
1053    pub allowed_origins: Option<Vec<String>>,
1054    #[serde(skip_serializing_if = "Option::is_none")]
1055    pub integrations: Option<Vec<SettingsIntegration>>,
1056}
1057
1058#[derive(Debug, Clone, Serialize, Deserialize)]
1059pub struct SettingsAuth {
1060    pub enable: bool,
1061    pub tested: bool,
1062    #[serde(skip_serializing_if = "Option::is_none")]
1063    pub name: Option<String>,
1064    #[serde(skip_serializing_if = "Option::is_none")]
1065    pub arguments: Option<Vec<ProviderArgumentValue>>,
1066    #[serde(rename = "apiAuthConfig", skip_serializing_if = "Option::is_none")]
1067    pub api_auth_config: Option<APIAuthConfig>,
1068}
1069
1070#[derive(Debug, Clone, Serialize, Deserialize)]
1071pub struct APIAuthConfig {
1072    pub search: bool,
1073    pub collections: bool,
1074    pub data: bool,
1075    pub explore: bool,
1076    pub oplog: bool,
1077}
1078
1079#[derive(Debug, Clone, Serialize, Deserialize)]
1080pub struct ProviderArgumentValue {
1081    pub key: String,
1082    pub value: String,
1083    #[serde(skip_serializing_if = "Option::is_none")]
1084    pub is_secret: Option<bool>,
1085}
1086
1087#[derive(Debug, Clone, Serialize, Deserialize)]
1088pub struct SettingsIntegration {
1089    pub enable: bool,
1090    #[serde(skip_serializing_if = "Option::is_none")]
1091    pub name: Option<String>,
1092    #[serde(skip_serializing_if = "Option::is_none")]
1093    pub arguments: Option<Vec<ProviderArgumentValue>>,
1094}
1095
1096#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1097pub struct SettingsUpdateRequest {
1098    #[serde(skip_serializing_if = "Option::is_none")]
1099    pub auth: Option<SettingsAuth>,
1100    #[serde(skip_serializing_if = "Option::is_none")]
1101    pub tested: Option<bool>,
1102    #[serde(rename = "authConfig", skip_serializing_if = "Option::is_none")]
1103    pub auth_config: Option<SettingsAuth>,
1104    #[serde(rename = "allowedOrigins", skip_serializing_if = "Option::is_none")]
1105    pub allowed_origins: Option<Vec<String>>,
1106    #[serde(skip_serializing_if = "Option::is_none")]
1107    pub integration: Option<HashMap<String, SettingsIntegration>>,
1108}
1109
1110#[derive(Debug, Clone, Serialize, Deserialize)]
1111pub struct SettingsAvailableProvidersResponse {
1112    pub success: bool,
1113    pub message: String,
1114    #[serde(skip_serializing_if = "Option::is_none")]
1115    pub data: Option<SettingsAvailableProvidersData>,
1116}
1117
1118#[derive(Debug, Clone, Serialize, Deserialize)]
1119pub struct SettingsAvailableProvidersData {
1120    #[serde(skip_serializing_if = "Option::is_none")]
1121    pub auth: Option<Vec<SettingsProviderInfo>>,
1122    #[serde(skip_serializing_if = "Option::is_none")]
1123    pub integrations: Option<Vec<SettingsProviderInfo>>,
1124}
1125
1126#[derive(Debug, Clone, Serialize, Deserialize)]
1127pub struct SettingsProviderArguments {
1128    pub label: String,
1129    pub description: String,
1130    #[serde(skip_serializing_if = "Option::is_none")]
1131    pub is_secret: Option<bool>,
1132}
1133
1134#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1135pub enum SettingsProviderType {
1136    #[serde(rename = "auth")]
1137    Auth,
1138    #[serde(rename = "data-source")]
1139    DataSource,
1140}
1141
1142#[derive(Debug, Clone, Serialize, Deserialize)]
1143pub struct SettingsProviderInfo {
1144    pub name: String,
1145    #[serde(rename = "type")]
1146    pub provider_type: SettingsProviderType,
1147    #[serde(skip_serializing_if = "Option::is_none")]
1148    pub arguments: Option<Vec<SettingsProviderArguments>>,
1149}
1150
1151// Update replica LSN request
1152#[derive(Debug, Clone, Serialize, Deserialize)]
1153pub struct UpdateReplicaLSNRequest {
1154    pub collection: String,
1155    pub replica_id: String,
1156    pub lsn: u64,
1157}
1158
1159// Update replica LSN response
1160#[derive(Debug, Clone, Serialize, Deserialize)]
1161pub struct UpdateReplicaLSNResponse {
1162    pub success: bool,
1163    pub message: String,
1164}
1165
1166// Register replica request
1167#[derive(Debug, Clone, Serialize, Deserialize)]
1168pub struct RegisterReplicaRequest {
1169    pub replica_id: String,
1170}
1171
1172// Unregister replica request
1173#[derive(Debug, Clone, Serialize, Deserialize)]
1174pub struct UnRegisterReplicaRequest {
1175    pub replica_id: String,
1176}
1177
1178// Get oplog response
1179#[derive(Debug, Clone, Serialize, Deserialize)]
1180pub struct GetOplogResponse {
1181    pub success: bool,
1182    pub message: String,
1183    pub entries: Vec<OplogEntry>,
1184    pub last_lsn: u64,
1185    pub count: i32,
1186}
1187
1188// Replica
1189#[derive(Debug, Clone, Serialize, Deserialize)]
1190pub struct Replica {
1191    pub id: String,
1192    pub address: String,
1193    pub is_healthy: bool,
1194    pub is_syncing: bool,
1195}
1196
1197// Status
1198#[derive(Debug, Clone, Serialize, Deserialize)]
1199pub struct Status {
1200    pub write_replica: Replica,
1201    pub read_replicas: Vec<Replica>,
1202    pub available_count: i32,
1203    pub total_count: i32,
1204}
1205
1206// Proxy stats
1207#[derive(Debug, Clone, Serialize, Deserialize)]
1208pub struct ProxyStats {
1209    pub active_proxies: i32,
1210    pub targets: Vec<String>,
1211}
1212
1213// Discovery stats
1214#[derive(Debug, Clone, Serialize, Deserialize)]
1215pub struct DiscoveryStats {
1216    pub registry: Status,
1217    pub proxy: ProxyStats,
1218}
1219
1220// Sync status
1221#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1222#[serde(rename_all = "lowercase")]
1223pub enum SyncStatus {
1224    Ready,
1225    Syncing,
1226}
1227
1228// Update sync status request
1229#[derive(Debug, Clone, Serialize, Deserialize)]
1230pub struct UpdateSyncStatusRequest {
1231    pub account_id: String,
1232    pub address: String,
1233    pub status: SyncStatus,
1234}
1235
1236// Register to discovery request
1237#[derive(Debug, Clone, Serialize, Deserialize)]
1238pub struct RegisterToDiscoveryRequest {
1239    pub account_id: String,
1240    pub address: String,
1241    pub id: String,
1242    pub is_read: bool,
1243    pub is_write: bool,
1244}
1245
1246// Replica type
1247#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1248pub enum ReplicaType {
1249    Read,
1250    Write,
1251    SingleNode,
1252}
1253
1254impl ReplicaType {
1255    pub fn is_read(&self) -> bool {
1256        matches!(self, ReplicaType::Read)
1257    }
1258
1259    pub fn is_write(&self) -> bool {
1260        matches!(self, ReplicaType::Write)
1261    }
1262
1263    pub fn is_single_node(&self) -> bool {
1264        matches!(self, ReplicaType::SingleNode)
1265    }
1266}
1267
1268// List collections models response
1269#[derive(Debug, Clone, Serialize, Deserialize)]
1270pub struct ListCollectionsModelsResponse {
1271    pub success: bool,
1272    pub data: Vec<CollectionModel>,
1273    pub message: String,
1274}
1275
1276// Update models event for streaming updates
1277#[derive(Debug, Clone, Serialize, Deserialize)]
1278pub struct UpdateModelsEvent {
1279    /// Status of the update: "updating", "success", "error", "complete"
1280    pub status: String,
1281    /// Human-readable message
1282    pub message: String,
1283    /// Model field being updated
1284    pub field: String,
1285    /// Total models to update
1286    pub total: i32,
1287    /// Current model number
1288    pub current: i32,
1289    /// Error message if status is "error"
1290    #[serde(skip_serializing_if = "Option::is_none")]
1291    pub error: Option<String>,
1292}
1293
1294// Get collection model response
1295#[derive(Debug, Clone, Serialize, Deserialize)]
1296pub struct GetCollectionModelResponse {
1297    pub success: bool,
1298    #[serde(skip_serializing_if = "Option::is_none")]
1299    pub data: Option<Model>,
1300    pub message: String,
1301}
1302
1303// Collection model
1304#[derive(Debug, Clone, Serialize, Deserialize)]
1305pub struct CollectionModel {
1306    pub collection: String,
1307    pub models: Vec<Model>,
1308    pub upgrade_available: bool,
1309}
1310
1311// Model struct
1312#[derive(Debug, Clone, Serialize, Deserialize)]
1313pub struct Model {
1314    pub id: String,
1315    pub project_id: String,
1316    pub name: String,
1317    pub description: String,
1318    pub collection: String,
1319    pub version: String,
1320    pub model_type: ModelType,
1321    pub status: String,
1322    pub supported_version: String,
1323    pub labels: Vec<String>,
1324    pub embedding_dim: i32,
1325    pub mode: String,
1326    pub label_field: String,
1327    pub num_samples: i32,
1328    pub skipped: i32,
1329    pub label_grouping: HashMap<String, Vec<String>>,
1330    pub classifier_selection_strategy: HashMap<String, serde_json::Value>,
1331    pub file_path: String,
1332    pub file_size: i64,
1333    pub enabled: bool,
1334    pub created_at: serde_json::Value,
1335    pub updated_at: serde_json::Value,
1336    #[serde(skip_serializing_if = "Option::is_none")]
1337    pub deleted_at: Option<serde_json::Value>,
1338}
1339
1340// Model type enum
1341#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1342#[serde(rename_all = "lowercase")]
1343pub enum ModelType {
1344    Collection,
1345    Vertical,
1346}
1347
1348// Get model response
1349#[derive(Debug, Clone, Serialize, Deserialize)]
1350pub struct GetModelResponse {
1351    pub success: bool,
1352    #[serde(skip_serializing_if = "Option::is_none")]
1353    pub data: Option<Model>,
1354    pub message: String,
1355}