vector-inspector 0.3.2__py3-none-any.whl → 0.3.3__py3-none-any.whl
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.
- vector_inspector/core/connection_manager.py +55 -49
- vector_inspector/core/connections/base_connection.py +41 -41
- vector_inspector/core/connections/chroma_connection.py +110 -86
- vector_inspector/core/connections/pinecone_connection.py +168 -182
- vector_inspector/core/connections/qdrant_connection.py +109 -126
- vector_inspector/core/connections/qdrant_helpers/__init__.py +4 -0
- vector_inspector/core/connections/qdrant_helpers/qdrant_embedding_resolver.py +35 -0
- vector_inspector/core/connections/qdrant_helpers/qdrant_filter_builder.py +51 -0
- vector_inspector/core/connections/template_connection.py +55 -65
- vector_inspector/core/embedding_utils.py +32 -32
- vector_inspector/core/logging.py +27 -0
- vector_inspector/core/model_registry.py +4 -3
- vector_inspector/main.py +6 -2
- vector_inspector/services/backup_helpers.py +63 -0
- vector_inspector/services/backup_restore_service.py +73 -152
- vector_inspector/services/credential_service.py +33 -40
- vector_inspector/services/import_export_service.py +70 -67
- vector_inspector/services/profile_service.py +92 -94
- vector_inspector/services/settings_service.py +68 -48
- vector_inspector/services/visualization_service.py +40 -39
- vector_inspector/ui/components/splash_window.py +57 -0
- vector_inspector/ui/dialogs/cross_db_migration.py +6 -5
- vector_inspector/ui/main_window.py +200 -146
- vector_inspector/ui/views/info_panel.py +208 -127
- vector_inspector/ui/views/metadata_view.py +8 -7
- vector_inspector/ui/views/search_view.py +97 -75
- vector_inspector/ui/views/visualization_view.py +140 -97
- vector_inspector/utils/version.py +5 -0
- {vector_inspector-0.3.2.dist-info → vector_inspector-0.3.3.dist-info}/METADATA +3 -1
- {vector_inspector-0.3.2.dist-info → vector_inspector-0.3.3.dist-info}/RECORD +32 -25
- {vector_inspector-0.3.2.dist-info → vector_inspector-0.3.3.dist-info}/WHEEL +0 -0
- {vector_inspector-0.3.2.dist-info → vector_inspector-0.3.3.dist-info}/entry_points.txt +0 -0
|
@@ -6,10 +6,12 @@ from enum import Enum
|
|
|
6
6
|
from PySide6.QtCore import QObject, Signal
|
|
7
7
|
|
|
8
8
|
from .connections.base_connection import VectorDBConnection
|
|
9
|
+
from vector_inspector.core.logging import log_error
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class ConnectionState(Enum):
|
|
12
13
|
"""Possible connection states."""
|
|
14
|
+
|
|
13
15
|
DISCONNECTED = "disconnected"
|
|
14
16
|
CONNECTING = "connecting"
|
|
15
17
|
CONNECTED = "connected"
|
|
@@ -18,18 +20,18 @@ class ConnectionState(Enum):
|
|
|
18
20
|
|
|
19
21
|
class ConnectionInstance:
|
|
20
22
|
"""Represents a single active connection with its state and context."""
|
|
21
|
-
|
|
23
|
+
|
|
22
24
|
def __init__(
|
|
23
25
|
self,
|
|
24
26
|
connection_id: str,
|
|
25
27
|
name: str,
|
|
26
28
|
provider: str,
|
|
27
29
|
connection: VectorDBConnection,
|
|
28
|
-
config: Dict[str, Any]
|
|
30
|
+
config: Dict[str, Any],
|
|
29
31
|
):
|
|
30
32
|
"""
|
|
31
33
|
Initialize a connection instance.
|
|
32
|
-
|
|
34
|
+
|
|
33
35
|
Args:
|
|
34
36
|
connection_id: Unique connection identifier
|
|
35
37
|
name: User-friendly connection name
|
|
@@ -46,11 +48,11 @@ class ConnectionInstance:
|
|
|
46
48
|
self.active_collection: Optional[str] = None
|
|
47
49
|
self.collections: List[str] = []
|
|
48
50
|
self.error_message: Optional[str] = None
|
|
49
|
-
|
|
51
|
+
|
|
50
52
|
def get_display_name(self) -> str:
|
|
51
53
|
"""Get a display-friendly connection name."""
|
|
52
54
|
return f"{self.name} ({self.provider})"
|
|
53
|
-
|
|
55
|
+
|
|
54
56
|
def get_breadcrumb(self) -> str:
|
|
55
57
|
"""Get breadcrumb showing connection > collection."""
|
|
56
58
|
if self.active_collection:
|
|
@@ -60,7 +62,7 @@ class ConnectionInstance:
|
|
|
60
62
|
|
|
61
63
|
class ConnectionManager(QObject):
|
|
62
64
|
"""Manages multiple vector database connections and saved profiles.
|
|
63
|
-
|
|
65
|
+
|
|
64
66
|
Signals:
|
|
65
67
|
connection_opened: Emitted when a new connection is opened (connection_id)
|
|
66
68
|
connection_closed: Emitted when a connection is closed (connection_id)
|
|
@@ -69,7 +71,7 @@ class ConnectionManager(QObject):
|
|
|
69
71
|
active_collection_changed: Emitted when active collection changes (connection_id, collection_name or None)
|
|
70
72
|
collections_updated: Emitted when collections list is updated (connection_id, collections)
|
|
71
73
|
"""
|
|
72
|
-
|
|
74
|
+
|
|
73
75
|
# Signals
|
|
74
76
|
connection_opened = Signal(str) # connection_id
|
|
75
77
|
connection_closed = Signal(str) # connection_id
|
|
@@ -77,116 +79,119 @@ class ConnectionManager(QObject):
|
|
|
77
79
|
active_connection_changed = Signal(object) # connection_id or None
|
|
78
80
|
active_collection_changed = Signal(str, object) # connection_id, collection_name or None
|
|
79
81
|
collections_updated = Signal(str, list) # connection_id, collections
|
|
80
|
-
|
|
82
|
+
|
|
81
83
|
MAX_CONNECTIONS = 10 # Limit to prevent resource exhaustion
|
|
82
|
-
|
|
84
|
+
|
|
83
85
|
def __init__(self):
|
|
84
86
|
"""Initialize the connection manager."""
|
|
85
87
|
super().__init__()
|
|
86
88
|
self._connections: Dict[str, ConnectionInstance] = {}
|
|
87
89
|
self._active_connection_id: Optional[str] = None
|
|
88
|
-
|
|
90
|
+
|
|
89
91
|
def create_connection(
|
|
90
92
|
self,
|
|
91
93
|
name: str,
|
|
92
94
|
provider: str,
|
|
93
95
|
connection: VectorDBConnection,
|
|
94
|
-
config: Dict[str, Any]
|
|
96
|
+
config: Dict[str, Any],
|
|
97
|
+
connection_id: str = None,
|
|
95
98
|
) -> str:
|
|
96
99
|
"""
|
|
97
100
|
Create a new connection instance (not yet connected).
|
|
98
|
-
|
|
101
|
+
|
|
99
102
|
Args:
|
|
100
103
|
name: User-friendly connection name
|
|
101
104
|
provider: Provider type
|
|
102
105
|
connection: The connection object
|
|
103
106
|
config: Connection configuration
|
|
104
|
-
|
|
107
|
+
connection_id: Optional. Use this ID instead of generating a new one (for profiles).
|
|
108
|
+
|
|
105
109
|
Returns:
|
|
106
110
|
The connection ID
|
|
107
|
-
|
|
111
|
+
|
|
108
112
|
Raises:
|
|
109
113
|
RuntimeError: If maximum connections limit reached
|
|
110
114
|
"""
|
|
111
115
|
if len(self._connections) >= self.MAX_CONNECTIONS:
|
|
112
116
|
raise RuntimeError(f"Maximum number of connections ({self.MAX_CONNECTIONS}) reached")
|
|
113
|
-
|
|
114
|
-
connection_id
|
|
117
|
+
|
|
118
|
+
if connection_id is None:
|
|
119
|
+
connection_id = str(uuid.uuid4())
|
|
115
120
|
instance = ConnectionInstance(connection_id, name, provider, connection, config)
|
|
116
121
|
self._connections[connection_id] = instance
|
|
117
|
-
|
|
122
|
+
|
|
118
123
|
# Set as active if it's the first connection
|
|
119
124
|
if len(self._connections) == 1:
|
|
120
125
|
self._active_connection_id = connection_id
|
|
121
126
|
self.active_connection_changed.emit(connection_id)
|
|
122
|
-
|
|
127
|
+
|
|
123
128
|
# Don't emit connection_opened yet - wait until actually connected
|
|
124
129
|
return connection_id
|
|
125
|
-
|
|
130
|
+
|
|
126
131
|
def mark_connection_opened(self, connection_id: str):
|
|
127
132
|
"""
|
|
128
133
|
Mark a connection as opened (after successful connection).
|
|
129
|
-
|
|
134
|
+
|
|
130
135
|
Args:
|
|
131
136
|
connection_id: ID of connection that opened
|
|
132
137
|
"""
|
|
133
138
|
if connection_id in self._connections:
|
|
134
139
|
self.connection_opened.emit(connection_id)
|
|
135
|
-
|
|
140
|
+
|
|
136
141
|
def get_connection(self, connection_id: str) -> Optional[ConnectionInstance]:
|
|
137
142
|
"""Get a connection instance by ID."""
|
|
138
143
|
return self._connections.get(connection_id)
|
|
139
|
-
|
|
144
|
+
|
|
140
145
|
def get_active_connection(self) -> Optional[ConnectionInstance]:
|
|
141
146
|
"""Get the currently active connection instance."""
|
|
142
147
|
if self._active_connection_id:
|
|
143
148
|
return self._connections.get(self._active_connection_id)
|
|
144
149
|
return None
|
|
145
|
-
|
|
150
|
+
|
|
146
151
|
def get_active_connection_id(self) -> Optional[str]:
|
|
147
152
|
"""Get the currently active connection ID."""
|
|
148
153
|
return self._active_connection_id
|
|
149
|
-
|
|
154
|
+
|
|
150
155
|
def set_active_connection(self, connection_id: str) -> bool:
|
|
151
156
|
"""
|
|
152
157
|
Set the active connection.
|
|
153
|
-
|
|
158
|
+
|
|
154
159
|
Args:
|
|
155
160
|
connection_id: ID of connection to make active
|
|
156
|
-
|
|
161
|
+
|
|
157
162
|
Returns:
|
|
158
163
|
True if successful, False if connection not found
|
|
159
164
|
"""
|
|
160
165
|
if connection_id not in self._connections:
|
|
161
166
|
return False
|
|
162
|
-
|
|
167
|
+
|
|
163
168
|
self._active_connection_id = connection_id
|
|
164
169
|
self.active_connection_changed.emit(connection_id)
|
|
165
170
|
return True
|
|
166
|
-
|
|
171
|
+
|
|
167
172
|
def close_connection(self, connection_id: str) -> bool:
|
|
168
173
|
"""
|
|
169
174
|
Close and remove a connection.
|
|
170
|
-
|
|
175
|
+
|
|
171
176
|
Args:
|
|
172
177
|
connection_id: ID of connection to close
|
|
173
|
-
|
|
178
|
+
|
|
174
179
|
Returns:
|
|
175
180
|
True if successful, False if connection not found
|
|
176
181
|
"""
|
|
177
182
|
instance = self._connections.get(connection_id)
|
|
178
183
|
if not instance:
|
|
179
184
|
return False
|
|
180
|
-
|
|
185
|
+
|
|
181
186
|
# Disconnect the connection
|
|
182
187
|
try:
|
|
183
188
|
instance.connection.disconnect()
|
|
184
189
|
except Exception as e:
|
|
185
|
-
|
|
186
|
-
|
|
190
|
+
log_error("Error disconnecting: %s", e)
|
|
191
|
+
|
|
187
192
|
# Remove from connections dict
|
|
188
193
|
del self._connections[connection_id]
|
|
189
|
-
|
|
194
|
+
|
|
190
195
|
# If this was the active connection, set a new one or None
|
|
191
196
|
if self._active_connection_id == connection_id:
|
|
192
197
|
if self._connections:
|
|
@@ -196,14 +201,16 @@ class ConnectionManager(QObject):
|
|
|
196
201
|
else:
|
|
197
202
|
self._active_connection_id = None
|
|
198
203
|
self.active_connection_changed.emit(None)
|
|
199
|
-
|
|
204
|
+
|
|
200
205
|
self.connection_closed.emit(connection_id)
|
|
201
206
|
return True
|
|
202
|
-
|
|
203
|
-
def update_connection_state(
|
|
207
|
+
|
|
208
|
+
def update_connection_state(
|
|
209
|
+
self, connection_id: str, state: ConnectionState, error: Optional[str] = None
|
|
210
|
+
):
|
|
204
211
|
"""
|
|
205
212
|
Update the state of a connection.
|
|
206
|
-
|
|
213
|
+
|
|
207
214
|
Args:
|
|
208
215
|
connection_id: ID of connection
|
|
209
216
|
state: New connection state
|
|
@@ -217,11 +224,11 @@ class ConnectionManager(QObject):
|
|
|
217
224
|
else:
|
|
218
225
|
instance.error_message = None
|
|
219
226
|
self.connection_state_changed.emit(connection_id, state)
|
|
220
|
-
|
|
227
|
+
|
|
221
228
|
def update_collections(self, connection_id: str, collections: List[str]):
|
|
222
229
|
"""
|
|
223
230
|
Update the collections list for a connection.
|
|
224
|
-
|
|
231
|
+
|
|
225
232
|
Args:
|
|
226
233
|
connection_id: ID of connection
|
|
227
234
|
collections: List of collection names
|
|
@@ -230,11 +237,11 @@ class ConnectionManager(QObject):
|
|
|
230
237
|
if instance:
|
|
231
238
|
instance.collections = collections
|
|
232
239
|
self.collections_updated.emit(connection_id, collections)
|
|
233
|
-
|
|
240
|
+
|
|
234
241
|
def set_active_collection(self, connection_id: str, collection_name: Optional[str]):
|
|
235
242
|
"""
|
|
236
243
|
Set the active collection for a connection.
|
|
237
|
-
|
|
244
|
+
|
|
238
245
|
Args:
|
|
239
246
|
connection_id: ID of connection
|
|
240
247
|
collection_name: Name of collection to make active, or None
|
|
@@ -243,29 +250,29 @@ class ConnectionManager(QObject):
|
|
|
243
250
|
if instance:
|
|
244
251
|
instance.active_collection = collection_name
|
|
245
252
|
self.active_collection_changed.emit(connection_id, collection_name)
|
|
246
|
-
|
|
253
|
+
|
|
247
254
|
def get_all_connections(self) -> List[ConnectionInstance]:
|
|
248
255
|
"""Get list of all connection instances."""
|
|
249
256
|
return list(self._connections.values())
|
|
250
|
-
|
|
257
|
+
|
|
251
258
|
def get_connection_count(self) -> int:
|
|
252
259
|
"""Get the number of active connections."""
|
|
253
260
|
return len(self._connections)
|
|
254
|
-
|
|
261
|
+
|
|
255
262
|
def close_all_connections(self):
|
|
256
263
|
"""Close all connections. Typically called on application exit."""
|
|
257
264
|
connection_ids = list(self._connections.keys())
|
|
258
265
|
for conn_id in connection_ids:
|
|
259
266
|
self.close_connection(conn_id)
|
|
260
|
-
|
|
267
|
+
|
|
261
268
|
def rename_connection(self, connection_id: str, new_name: str) -> bool:
|
|
262
269
|
"""
|
|
263
270
|
Rename a connection.
|
|
264
|
-
|
|
271
|
+
|
|
265
272
|
Args:
|
|
266
273
|
connection_id: ID of connection
|
|
267
274
|
new_name: New name for the connection
|
|
268
|
-
|
|
275
|
+
|
|
269
276
|
Returns:
|
|
270
277
|
True if successful, False if connection not found
|
|
271
278
|
"""
|
|
@@ -274,4 +281,3 @@ class ConnectionManager(QObject):
|
|
|
274
281
|
instance.name = new_name
|
|
275
282
|
return True
|
|
276
283
|
return False
|
|
277
|
-
|
|
@@ -2,59 +2,60 @@
|
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
from typing import Optional, List, Dict, Any
|
|
5
|
+
from vector_inspector.core.logging import log_error
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class VectorDBConnection(ABC):
|
|
8
9
|
"""Abstract base class for vector database connections.
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
This class defines the interface that all vector database providers
|
|
11
12
|
must implement to be compatible with Vector Inspector.
|
|
12
13
|
"""
|
|
13
|
-
|
|
14
|
+
|
|
14
15
|
@abstractmethod
|
|
15
16
|
def connect(self) -> bool:
|
|
16
17
|
"""
|
|
17
18
|
Establish connection to the vector database.
|
|
18
|
-
|
|
19
|
+
|
|
19
20
|
Returns:
|
|
20
21
|
True if connection successful, False otherwise
|
|
21
22
|
"""
|
|
22
23
|
pass
|
|
23
|
-
|
|
24
|
+
|
|
24
25
|
@abstractmethod
|
|
25
26
|
def disconnect(self):
|
|
26
27
|
"""Close connection to the vector database."""
|
|
27
28
|
pass
|
|
28
|
-
|
|
29
|
+
|
|
29
30
|
@property
|
|
30
31
|
@abstractmethod
|
|
31
32
|
def is_connected(self) -> bool:
|
|
32
33
|
"""
|
|
33
34
|
Check if connected to the vector database.
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
Returns:
|
|
36
37
|
True if connected, False otherwise
|
|
37
38
|
"""
|
|
38
39
|
pass
|
|
39
|
-
|
|
40
|
+
|
|
40
41
|
@abstractmethod
|
|
41
42
|
def list_collections(self) -> List[str]:
|
|
42
43
|
"""
|
|
43
44
|
Get list of all collections/indexes.
|
|
44
|
-
|
|
45
|
+
|
|
45
46
|
Returns:
|
|
46
47
|
List of collection/index names
|
|
47
48
|
"""
|
|
48
49
|
pass
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
@abstractmethod
|
|
51
52
|
def get_collection_info(self, name: str) -> Optional[Dict[str, Any]]:
|
|
52
53
|
"""
|
|
53
54
|
Get collection metadata and statistics.
|
|
54
|
-
|
|
55
|
+
|
|
55
56
|
Args:
|
|
56
57
|
name: Collection/index name
|
|
57
|
-
|
|
58
|
+
|
|
58
59
|
Returns:
|
|
59
60
|
Dictionary with collection info including:
|
|
60
61
|
- name: Collection name
|
|
@@ -94,7 +95,7 @@ class VectorDBConnection(ABC):
|
|
|
94
95
|
def count_collection(self, name: str) -> int:
|
|
95
96
|
"""Return the number of items in the collection."""
|
|
96
97
|
pass
|
|
97
|
-
|
|
98
|
+
|
|
98
99
|
@abstractmethod
|
|
99
100
|
def query_collection(
|
|
100
101
|
self,
|
|
@@ -107,7 +108,7 @@ class VectorDBConnection(ABC):
|
|
|
107
108
|
) -> Optional[Dict[str, Any]]:
|
|
108
109
|
"""
|
|
109
110
|
Query a collection for similar vectors.
|
|
110
|
-
|
|
111
|
+
|
|
111
112
|
Args:
|
|
112
113
|
collection_name: Name of collection to query
|
|
113
114
|
query_texts: Text queries to embed and search
|
|
@@ -115,7 +116,7 @@ class VectorDBConnection(ABC):
|
|
|
115
116
|
n_results: Number of results to return
|
|
116
117
|
where: Metadata filter
|
|
117
118
|
where_document: Document content filter
|
|
118
|
-
|
|
119
|
+
|
|
119
120
|
Returns:
|
|
120
121
|
Query results dictionary with keys:
|
|
121
122
|
- ids: List of result IDs
|
|
@@ -125,7 +126,7 @@ class VectorDBConnection(ABC):
|
|
|
125
126
|
- embeddings: List of embedding vectors (optional)
|
|
126
127
|
"""
|
|
127
128
|
pass
|
|
128
|
-
|
|
129
|
+
|
|
129
130
|
@abstractmethod
|
|
130
131
|
def get_all_items(
|
|
131
132
|
self,
|
|
@@ -136,13 +137,13 @@ class VectorDBConnection(ABC):
|
|
|
136
137
|
) -> Optional[Dict[str, Any]]:
|
|
137
138
|
"""
|
|
138
139
|
Get all items from a collection.
|
|
139
|
-
|
|
140
|
+
|
|
140
141
|
Args:
|
|
141
142
|
collection_name: Name of collection
|
|
142
143
|
limit: Maximum number of items to return
|
|
143
144
|
offset: Number of items to skip
|
|
144
145
|
where: Metadata filter
|
|
145
|
-
|
|
146
|
+
|
|
146
147
|
Returns:
|
|
147
148
|
Dictionary with collection items:
|
|
148
149
|
- ids: List of item IDs
|
|
@@ -151,7 +152,7 @@ class VectorDBConnection(ABC):
|
|
|
151
152
|
- embeddings: List of embedding vectors
|
|
152
153
|
"""
|
|
153
154
|
pass
|
|
154
|
-
|
|
155
|
+
|
|
155
156
|
@abstractmethod
|
|
156
157
|
def update_items(
|
|
157
158
|
self,
|
|
@@ -163,19 +164,19 @@ class VectorDBConnection(ABC):
|
|
|
163
164
|
) -> bool:
|
|
164
165
|
"""
|
|
165
166
|
Update items in a collection.
|
|
166
|
-
|
|
167
|
+
|
|
167
168
|
Args:
|
|
168
169
|
collection_name: Name of collection
|
|
169
170
|
ids: IDs of items to update
|
|
170
171
|
documents: New document texts
|
|
171
172
|
metadatas: New metadata
|
|
172
173
|
embeddings: New embeddings
|
|
173
|
-
|
|
174
|
+
|
|
174
175
|
Returns:
|
|
175
176
|
True if successful, False otherwise
|
|
176
177
|
"""
|
|
177
178
|
pass
|
|
178
|
-
|
|
179
|
+
|
|
179
180
|
@abstractmethod
|
|
180
181
|
def delete_items(
|
|
181
182
|
self,
|
|
@@ -185,36 +186,32 @@ class VectorDBConnection(ABC):
|
|
|
185
186
|
) -> bool:
|
|
186
187
|
"""
|
|
187
188
|
Delete items from a collection.
|
|
188
|
-
|
|
189
|
+
|
|
189
190
|
Args:
|
|
190
191
|
collection_name: Name of collection
|
|
191
192
|
ids: IDs of items to delete
|
|
192
193
|
where: Metadata filter for items to delete
|
|
193
|
-
|
|
194
|
+
|
|
194
195
|
Returns:
|
|
195
196
|
True if successful, False otherwise
|
|
196
197
|
"""
|
|
197
198
|
pass
|
|
198
|
-
|
|
199
199
|
|
|
200
200
|
# Optional: Methods that may be provider-specific but useful to define
|
|
201
|
-
|
|
201
|
+
|
|
202
202
|
def get_connection_info(self) -> Dict[str, Any]:
|
|
203
203
|
"""
|
|
204
204
|
Get information about the current connection.
|
|
205
|
-
|
|
205
|
+
|
|
206
206
|
Returns:
|
|
207
207
|
Dictionary with connection details (provider-specific)
|
|
208
208
|
"""
|
|
209
|
-
return {
|
|
210
|
-
|
|
211
|
-
"connected": self.is_connected
|
|
212
|
-
}
|
|
213
|
-
|
|
209
|
+
return {"provider": self.__class__.__name__, "connected": self.is_connected}
|
|
210
|
+
|
|
214
211
|
def get_supported_filter_operators(self) -> List[Dict[str, Any]]:
|
|
215
212
|
"""
|
|
216
213
|
Get list of filter operators supported by this provider.
|
|
217
|
-
|
|
214
|
+
|
|
218
215
|
Returns:
|
|
219
216
|
List of operator dictionaries with 'name' and 'server_side' keys
|
|
220
217
|
"""
|
|
@@ -230,20 +227,22 @@ class VectorDBConnection(ABC):
|
|
|
230
227
|
{"name": "not in", "server_side": True},
|
|
231
228
|
{"name": "contains", "server_side": False},
|
|
232
229
|
]
|
|
233
|
-
|
|
234
|
-
def get_embedding_model(
|
|
230
|
+
|
|
231
|
+
def get_embedding_model(
|
|
232
|
+
self, collection_name: str, connection_id: Optional[str] = None
|
|
233
|
+
) -> Optional[str]:
|
|
235
234
|
"""
|
|
236
235
|
Get the embedding model used for a collection.
|
|
237
|
-
|
|
236
|
+
|
|
238
237
|
Retrieves the model name from:
|
|
239
238
|
1. Collection-level metadata (if supported)
|
|
240
239
|
2. Vector metadata (_embedding_model field)
|
|
241
240
|
3. User settings (for collections we can't modify)
|
|
242
|
-
|
|
241
|
+
|
|
243
242
|
Args:
|
|
244
243
|
collection_name: Name of collection
|
|
245
244
|
connection_id: Optional connection ID for settings lookup
|
|
246
|
-
|
|
245
|
+
|
|
247
246
|
Returns:
|
|
248
247
|
Model name string (e.g., "sentence-transformers/all-MiniLM-L6-v2") or None
|
|
249
248
|
"""
|
|
@@ -252,23 +251,24 @@ class VectorDBConnection(ABC):
|
|
|
252
251
|
info = self.get_collection_info(collection_name)
|
|
253
252
|
if info and info.get("embedding_model"):
|
|
254
253
|
return info["embedding_model"]
|
|
255
|
-
|
|
254
|
+
|
|
256
255
|
# Fall back to checking a sample vector's metadata
|
|
257
256
|
data = self.get_all_items(collection_name, limit=1, offset=0)
|
|
258
257
|
if data and data.get("metadatas") and len(data["metadatas"]) > 0:
|
|
259
258
|
metadata = data["metadatas"][0]
|
|
260
259
|
if "_embedding_model" in metadata:
|
|
261
260
|
return metadata["_embedding_model"]
|
|
262
|
-
|
|
261
|
+
|
|
263
262
|
# Finally, check user settings (for collections we can't modify)
|
|
264
263
|
if connection_id:
|
|
265
264
|
from ...services.settings_service import SettingsService
|
|
265
|
+
|
|
266
266
|
settings = SettingsService()
|
|
267
267
|
model_info = settings.get_embedding_model(connection_id, collection_name)
|
|
268
268
|
if model_info:
|
|
269
269
|
return model_info["model"]
|
|
270
|
-
|
|
270
|
+
|
|
271
271
|
return None
|
|
272
272
|
except Exception as e:
|
|
273
|
-
|
|
273
|
+
log_error("Failed to get embedding model: %s", e)
|
|
274
274
|
return None
|