isa-model 0.3.5__py3-none-any.whl → 0.3.7__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.
Files changed (88) hide show
  1. isa_model/__init__.py +30 -1
  2. isa_model/client.py +937 -0
  3. isa_model/core/config/__init__.py +16 -0
  4. isa_model/core/config/config_manager.py +514 -0
  5. isa_model/core/config.py +426 -0
  6. isa_model/core/models/model_billing_tracker.py +476 -0
  7. isa_model/core/models/model_manager.py +399 -0
  8. isa_model/core/{storage/supabase_storage.py → models/model_repo.py} +72 -73
  9. isa_model/core/pricing_manager.py +426 -0
  10. isa_model/core/services/__init__.py +19 -0
  11. isa_model/core/services/intelligent_model_selector.py +547 -0
  12. isa_model/core/types.py +291 -0
  13. isa_model/deployment/__init__.py +2 -0
  14. isa_model/deployment/cloud/modal/isa_vision_doc_service.py +157 -3
  15. isa_model/deployment/cloud/modal/isa_vision_table_service.py +532 -0
  16. isa_model/deployment/cloud/modal/isa_vision_ui_service.py +104 -3
  17. isa_model/deployment/cloud/modal/register_models.py +321 -0
  18. isa_model/deployment/runtime/deployed_service.py +338 -0
  19. isa_model/deployment/services/__init__.py +9 -0
  20. isa_model/deployment/services/auto_deploy_vision_service.py +538 -0
  21. isa_model/deployment/services/model_service.py +332 -0
  22. isa_model/deployment/services/service_monitor.py +356 -0
  23. isa_model/deployment/services/service_registry.py +527 -0
  24. isa_model/deployment/services/simple_auto_deploy_vision_service.py +275 -0
  25. isa_model/eval/__init__.py +80 -44
  26. isa_model/eval/config/__init__.py +10 -0
  27. isa_model/eval/config/evaluation_config.py +108 -0
  28. isa_model/eval/evaluators/__init__.py +18 -0
  29. isa_model/eval/evaluators/base_evaluator.py +503 -0
  30. isa_model/eval/evaluators/llm_evaluator.py +472 -0
  31. isa_model/eval/factory.py +417 -709
  32. isa_model/eval/infrastructure/__init__.py +24 -0
  33. isa_model/eval/infrastructure/experiment_tracker.py +466 -0
  34. isa_model/eval/metrics.py +191 -21
  35. isa_model/inference/ai_factory.py +257 -601
  36. isa_model/inference/services/audio/base_stt_service.py +65 -1
  37. isa_model/inference/services/audio/base_tts_service.py +75 -1
  38. isa_model/inference/services/audio/openai_stt_service.py +189 -151
  39. isa_model/inference/services/audio/openai_tts_service.py +12 -10
  40. isa_model/inference/services/audio/replicate_tts_service.py +61 -56
  41. isa_model/inference/services/base_service.py +55 -17
  42. isa_model/inference/services/embedding/base_embed_service.py +65 -1
  43. isa_model/inference/services/embedding/ollama_embed_service.py +103 -43
  44. isa_model/inference/services/embedding/openai_embed_service.py +8 -10
  45. isa_model/inference/services/helpers/stacked_config.py +148 -0
  46. isa_model/inference/services/img/__init__.py +18 -0
  47. isa_model/inference/services/{vision → img}/base_image_gen_service.py +80 -1
  48. isa_model/inference/services/{stacked → img}/flux_professional_service.py +25 -1
  49. isa_model/inference/services/{stacked → img/helpers}/base_stacked_service.py +40 -35
  50. isa_model/inference/services/{vision → img}/replicate_image_gen_service.py +44 -31
  51. isa_model/inference/services/llm/__init__.py +3 -3
  52. isa_model/inference/services/llm/base_llm_service.py +492 -40
  53. isa_model/inference/services/llm/helpers/llm_prompts.py +258 -0
  54. isa_model/inference/services/llm/helpers/llm_utils.py +280 -0
  55. isa_model/inference/services/llm/ollama_llm_service.py +51 -17
  56. isa_model/inference/services/llm/openai_llm_service.py +70 -19
  57. isa_model/inference/services/llm/yyds_llm_service.py +24 -23
  58. isa_model/inference/services/vision/__init__.py +38 -4
  59. isa_model/inference/services/vision/base_vision_service.py +218 -117
  60. isa_model/inference/services/vision/{isA_vision_service.py → disabled/isA_vision_service.py} +98 -0
  61. isa_model/inference/services/{stacked → vision}/doc_analysis_service.py +1 -1
  62. isa_model/inference/services/vision/helpers/base_stacked_service.py +274 -0
  63. isa_model/inference/services/vision/helpers/image_utils.py +272 -3
  64. isa_model/inference/services/vision/helpers/vision_prompts.py +297 -0
  65. isa_model/inference/services/vision/openai_vision_service.py +104 -307
  66. isa_model/inference/services/vision/replicate_vision_service.py +140 -325
  67. isa_model/inference/services/{stacked → vision}/ui_analysis_service.py +2 -498
  68. isa_model/scripts/register_models.py +370 -0
  69. isa_model/scripts/register_models_with_embeddings.py +510 -0
  70. isa_model/serving/api/fastapi_server.py +6 -1
  71. isa_model/serving/api/routes/unified.py +274 -0
  72. {isa_model-0.3.5.dist-info → isa_model-0.3.7.dist-info}/METADATA +4 -1
  73. {isa_model-0.3.5.dist-info → isa_model-0.3.7.dist-info}/RECORD +78 -53
  74. isa_model/config/__init__.py +0 -9
  75. isa_model/config/config_manager.py +0 -213
  76. isa_model/core/model_manager.py +0 -213
  77. isa_model/core/model_registry.py +0 -375
  78. isa_model/core/vision_models_init.py +0 -116
  79. isa_model/inference/billing_tracker.py +0 -406
  80. isa_model/inference/services/llm/triton_llm_service.py +0 -481
  81. isa_model/inference/services/stacked/__init__.py +0 -26
  82. isa_model/inference/services/stacked/config.py +0 -426
  83. isa_model/inference/services/vision/ollama_vision_service.py +0 -194
  84. /isa_model/core/{model_storage.py → models/model_storage.py} +0 -0
  85. /isa_model/inference/services/{vision → embedding}/helpers/text_splitter.py +0 -0
  86. /isa_model/inference/services/llm/{llm_adapter.py → helpers/llm_adapter.py} +0 -0
  87. {isa_model-0.3.5.dist-info → isa_model-0.3.7.dist-info}/WHEEL +0 -0
  88. {isa_model-0.3.5.dist-info → isa_model-0.3.7.dist-info}/top_level.txt +0 -0
@@ -1,375 +0,0 @@
1
- from typing import Dict, List, Optional, Any
2
- from enum import Enum
3
- import logging
4
- from pathlib import Path
5
- import json
6
- import sqlite3
7
- from datetime import datetime
8
- import threading
9
-
10
- logger = logging.getLogger(__name__)
11
-
12
- class ModelCapability(str, Enum):
13
- """Model capabilities"""
14
- TEXT_GENERATION = "text_generation"
15
- CHAT = "chat"
16
- EMBEDDING = "embedding"
17
- RERANKING = "reranking"
18
- REASONING = "reasoning"
19
- IMAGE_GENERATION = "image_generation"
20
- IMAGE_ANALYSIS = "image_analysis"
21
- AUDIO_TRANSCRIPTION = "audio_transcription"
22
- IMAGE_UNDERSTANDING = "image_understanding"
23
- UI_DETECTION = "ui_detection"
24
- OCR = "ocr"
25
- TABLE_DETECTION = "table_detection"
26
- TABLE_STRUCTURE_RECOGNITION = "table_structure_recognition"
27
-
28
- class ModelType(str, Enum):
29
- """Model types"""
30
- LLM = "llm"
31
- EMBEDDING = "embedding"
32
- RERANK = "rerank"
33
- IMAGE = "image"
34
- AUDIO = "audio"
35
- VIDEO = "video"
36
- VISION = "vision"
37
-
38
- class ModelRegistry:
39
- """Model registry with SQLite or Supabase backend"""
40
-
41
- def __init__(self, db_path: str = "./models/model_registry.db", use_supabase: bool = None):
42
- # Auto-detect Supabase if environment variables are set
43
- if use_supabase is None:
44
- import os
45
- use_supabase = bool(os.getenv("SUPABASE_URL") and os.getenv("SUPABASE_ANON_KEY"))
46
-
47
- self.use_supabase = use_supabase
48
-
49
- if self.use_supabase:
50
- try:
51
- from .storage.supabase_storage import SupabaseModelRegistry
52
- self.backend = SupabaseModelRegistry()
53
- logger.info("Using Supabase backend for model registry")
54
- except ImportError as e:
55
- logger.warning(f"Supabase not available, falling back to SQLite: {e}")
56
- self.use_supabase = False
57
-
58
- if not self.use_supabase:
59
- # Use SQLite backend
60
- self.db_path = Path(db_path)
61
- self.db_path.parent.mkdir(parents=True, exist_ok=True)
62
- self._lock = threading.Lock()
63
- self._initialize_database()
64
- self.backend = None
65
- logger.info("Using SQLite backend for model registry")
66
-
67
- def _initialize_database(self):
68
- """Initialize SQLite database with required tables"""
69
- with sqlite3.connect(self.db_path) as conn:
70
- conn.execute("""
71
- CREATE TABLE IF NOT EXISTS models (
72
- model_id TEXT PRIMARY KEY,
73
- model_type TEXT NOT NULL,
74
- metadata TEXT,
75
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
76
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
77
- )
78
- """)
79
-
80
- conn.execute("""
81
- CREATE TABLE IF NOT EXISTS model_capabilities (
82
- model_id TEXT,
83
- capability TEXT,
84
- PRIMARY KEY (model_id, capability),
85
- FOREIGN KEY (model_id) REFERENCES models(model_id) ON DELETE CASCADE
86
- )
87
- """)
88
-
89
- conn.execute("""
90
- CREATE INDEX IF NOT EXISTS idx_model_type ON models(model_type)
91
- """)
92
-
93
- conn.execute("""
94
- CREATE INDEX IF NOT EXISTS idx_capability ON model_capabilities(capability)
95
- """)
96
-
97
- conn.commit()
98
-
99
- def register_model(self,
100
- model_id: str,
101
- model_type: ModelType,
102
- capabilities: List[ModelCapability],
103
- metadata: Dict[str, Any]) -> bool:
104
- """Register a model with its capabilities and metadata"""
105
- if self.use_supabase:
106
- return self.backend.register_model(
107
- model_id=model_id,
108
- model_type=model_type.value,
109
- capabilities=[cap.value for cap in capabilities],
110
- metadata=metadata
111
- )
112
-
113
- # SQLite implementation
114
- try:
115
- with self._lock:
116
- with sqlite3.connect(self.db_path) as conn:
117
- # Insert or update model
118
- conn.execute("""
119
- INSERT OR REPLACE INTO models
120
- (model_id, model_type, metadata, updated_at)
121
- VALUES (?, ?, ?, CURRENT_TIMESTAMP)
122
- """, (model_id, model_type.value, json.dumps(metadata)))
123
-
124
- # Clear existing capabilities
125
- conn.execute("DELETE FROM model_capabilities WHERE model_id = ?", (model_id,))
126
-
127
- # Insert new capabilities
128
- for capability in capabilities:
129
- conn.execute("""
130
- INSERT INTO model_capabilities (model_id, capability)
131
- VALUES (?, ?)
132
- """, (model_id, capability.value))
133
-
134
- conn.commit()
135
-
136
- logger.info(f"Registered model {model_id}")
137
- return True
138
-
139
- except Exception as e:
140
- logger.error(f"Failed to register model {model_id}: {e}")
141
- return False
142
-
143
- def unregister_model(self, model_id: str) -> bool:
144
- """Unregister a model"""
145
- try:
146
- with self._lock:
147
- with sqlite3.connect(self.db_path) as conn:
148
- cursor = conn.execute("DELETE FROM models WHERE model_id = ?", (model_id,))
149
- conn.commit()
150
-
151
- if cursor.rowcount > 0:
152
- logger.info(f"Unregistered model {model_id}")
153
- return True
154
- return False
155
-
156
- except Exception as e:
157
- logger.error(f"Failed to unregister model {model_id}: {e}")
158
- return False
159
-
160
- def get_model_info(self, model_id: str) -> Optional[Dict[str, Any]]:
161
- """Get model information"""
162
- try:
163
- with sqlite3.connect(self.db_path) as conn:
164
- conn.row_factory = sqlite3.Row
165
-
166
- # Get model info
167
- model_row = conn.execute("""
168
- SELECT model_id, model_type, metadata, created_at, updated_at
169
- FROM models WHERE model_id = ?
170
- """, (model_id,)).fetchone()
171
-
172
- if not model_row:
173
- return None
174
-
175
- # Get capabilities
176
- capabilities = conn.execute("""
177
- SELECT capability FROM model_capabilities WHERE model_id = ?
178
- """, (model_id,)).fetchall()
179
-
180
- model_info = {
181
- "model_id": model_row["model_id"],
182
- "type": model_row["model_type"],
183
- "capabilities": [cap["capability"] for cap in capabilities],
184
- "metadata": json.loads(model_row["metadata"]) if model_row["metadata"] else {},
185
- "created_at": model_row["created_at"],
186
- "updated_at": model_row["updated_at"]
187
- }
188
-
189
- return model_info
190
-
191
- except Exception as e:
192
- logger.error(f"Failed to get model info for {model_id}: {e}")
193
- return None
194
-
195
- def get_models_by_type(self, model_type: ModelType) -> Dict[str, Dict[str, Any]]:
196
- """Get all models of a specific type"""
197
- try:
198
- with sqlite3.connect(self.db_path) as conn:
199
- conn.row_factory = sqlite3.Row
200
-
201
- models = conn.execute("""
202
- SELECT model_id, model_type, metadata, created_at, updated_at
203
- FROM models WHERE model_type = ?
204
- """, (model_type.value,)).fetchall()
205
-
206
- result = {}
207
- for model in models:
208
- model_id = model["model_id"]
209
-
210
- # Get capabilities for this model
211
- capabilities = conn.execute("""
212
- SELECT capability FROM model_capabilities WHERE model_id = ?
213
- """, (model_id,)).fetchall()
214
-
215
- result[model_id] = {
216
- "type": model["model_type"],
217
- "capabilities": [cap["capability"] for cap in capabilities],
218
- "metadata": json.loads(model["metadata"]) if model["metadata"] else {},
219
- "created_at": model["created_at"],
220
- "updated_at": model["updated_at"]
221
- }
222
-
223
- return result
224
-
225
- except Exception as e:
226
- logger.error(f"Failed to get models by type {model_type}: {e}")
227
- return {}
228
-
229
- def get_models_by_capability(self, capability: ModelCapability) -> Dict[str, Dict[str, Any]]:
230
- """Get all models with a specific capability"""
231
- try:
232
- with sqlite3.connect(self.db_path) as conn:
233
- conn.row_factory = sqlite3.Row
234
-
235
- models = conn.execute("""
236
- SELECT DISTINCT m.model_id, m.model_type, m.metadata, m.created_at, m.updated_at
237
- FROM models m
238
- JOIN model_capabilities mc ON m.model_id = mc.model_id
239
- WHERE mc.capability = ?
240
- """, (capability.value,)).fetchall()
241
-
242
- result = {}
243
- for model in models:
244
- model_id = model["model_id"]
245
-
246
- # Get all capabilities for this model
247
- capabilities = conn.execute("""
248
- SELECT capability FROM model_capabilities WHERE model_id = ?
249
- """, (model_id,)).fetchall()
250
-
251
- result[model_id] = {
252
- "type": model["model_type"],
253
- "capabilities": [cap["capability"] for cap in capabilities],
254
- "metadata": json.loads(model["metadata"]) if model["metadata"] else {},
255
- "created_at": model["created_at"],
256
- "updated_at": model["updated_at"]
257
- }
258
-
259
- return result
260
-
261
- except Exception as e:
262
- logger.error(f"Failed to get models by capability {capability}: {e}")
263
- return {}
264
-
265
- def has_capability(self, model_id: str, capability: ModelCapability) -> bool:
266
- """Check if a model has a specific capability"""
267
- try:
268
- with sqlite3.connect(self.db_path) as conn:
269
- result = conn.execute("""
270
- SELECT 1 FROM model_capabilities
271
- WHERE model_id = ? AND capability = ?
272
- """, (model_id, capability.value)).fetchone()
273
-
274
- return result is not None
275
-
276
- except Exception as e:
277
- logger.error(f"Failed to check capability for {model_id}: {e}")
278
- return False
279
-
280
- def list_models(self) -> Dict[str, Dict[str, Any]]:
281
- """List all registered models"""
282
- try:
283
- with sqlite3.connect(self.db_path) as conn:
284
- conn.row_factory = sqlite3.Row
285
-
286
- models = conn.execute("""
287
- SELECT model_id, model_type, metadata, created_at, updated_at
288
- FROM models ORDER BY created_at DESC
289
- """).fetchall()
290
-
291
- result = {}
292
- for model in models:
293
- model_id = model["model_id"]
294
-
295
- # Get capabilities for this model
296
- capabilities = conn.execute("""
297
- SELECT capability FROM model_capabilities WHERE model_id = ?
298
- """, (model_id,)).fetchall()
299
-
300
- result[model_id] = {
301
- "type": model["model_type"],
302
- "capabilities": [cap["capability"] for cap in capabilities],
303
- "metadata": json.loads(model["metadata"]) if model["metadata"] else {},
304
- "created_at": model["created_at"],
305
- "updated_at": model["updated_at"]
306
- }
307
-
308
- return result
309
-
310
- except Exception as e:
311
- logger.error(f"Failed to list models: {e}")
312
- return {}
313
-
314
- def get_stats(self) -> Dict[str, Any]:
315
- """Get registry statistics"""
316
- try:
317
- with sqlite3.connect(self.db_path) as conn:
318
- # Count total models
319
- total_models = conn.execute("SELECT COUNT(*) FROM models").fetchone()[0]
320
-
321
- # Count by type
322
- type_counts = dict(conn.execute("""
323
- SELECT model_type, COUNT(*) FROM models GROUP BY model_type
324
- """).fetchall())
325
-
326
- # Count by capability
327
- capability_counts = dict(conn.execute("""
328
- SELECT capability, COUNT(*) FROM model_capabilities GROUP BY capability
329
- """).fetchall())
330
-
331
- return {
332
- "total_models": total_models,
333
- "models_by_type": type_counts,
334
- "models_by_capability": capability_counts
335
- }
336
-
337
- except Exception as e:
338
- logger.error(f"Failed to get stats: {e}")
339
- return {}
340
-
341
- def search_models(self, query: str) -> Dict[str, Dict[str, Any]]:
342
- """Search models by name or metadata"""
343
- try:
344
- with sqlite3.connect(self.db_path) as conn:
345
- conn.row_factory = sqlite3.Row
346
-
347
- models = conn.execute("""
348
- SELECT model_id, model_type, metadata, created_at, updated_at
349
- FROM models
350
- WHERE model_id LIKE ? OR metadata LIKE ?
351
- ORDER BY created_at DESC
352
- """, (f"%{query}%", f"%{query}%")).fetchall()
353
-
354
- result = {}
355
- for model in models:
356
- model_id = model["model_id"]
357
-
358
- # Get capabilities for this model
359
- capabilities = conn.execute("""
360
- SELECT capability FROM model_capabilities WHERE model_id = ?
361
- """, (model_id,)).fetchall()
362
-
363
- result[model_id] = {
364
- "type": model["model_type"],
365
- "capabilities": [cap["capability"] for cap in capabilities],
366
- "metadata": json.loads(model["metadata"]) if model["metadata"] else {},
367
- "created_at": model["created_at"],
368
- "updated_at": model["updated_at"]
369
- }
370
-
371
- return result
372
-
373
- except Exception as e:
374
- logger.error(f"Failed to search models with query '{query}': {e}")
375
- return {}
@@ -1,116 +0,0 @@
1
- """
2
- Initialize Vision Models in Model Registry
3
-
4
- Simple function to register vision models for UI analysis in Supabase
5
- """
6
-
7
- from .model_registry import ModelRegistry, ModelType, ModelCapability
8
-
9
- def register_vision_models():
10
- """Register vision models for UI analysis pipeline"""
11
-
12
- registry = ModelRegistry() # Auto-detects Supabase from .env
13
-
14
- # Vision models for UI analysis
15
- models = [
16
- {
17
- "model_id": "omniparser-v2.0",
18
- "model_type": ModelType.VISION,
19
- "capabilities": [ModelCapability.UI_DETECTION, ModelCapability.IMAGE_ANALYSIS],
20
- "metadata": {
21
- "repo_id": "microsoft/OmniParser-v2.0",
22
- "provider": "microsoft",
23
- "version": "2.0",
24
- "description": "Advanced UI element detection",
25
- "gpu_memory_mb": 8192,
26
- "modal_service": "isa-vision"
27
- }
28
- },
29
- {
30
- "model_id": "table-transformer-detection",
31
- "model_type": ModelType.VISION,
32
- "capabilities": [ModelCapability.TABLE_DETECTION, ModelCapability.IMAGE_ANALYSIS],
33
- "metadata": {
34
- "repo_id": "microsoft/table-transformer-detection",
35
- "provider": "microsoft",
36
- "version": "1.1",
37
- "description": "Table detection in documents",
38
- "gpu_memory_mb": 4096,
39
- "modal_service": "isa-vision"
40
- }
41
- },
42
- {
43
- "model_id": "table-transformer-structure",
44
- "model_type": ModelType.VISION,
45
- "capabilities": [ModelCapability.TABLE_STRUCTURE_RECOGNITION, ModelCapability.IMAGE_ANALYSIS],
46
- "metadata": {
47
- "repo_id": "microsoft/table-transformer-structure-recognition-v1.1-all",
48
- "provider": "microsoft",
49
- "version": "1.1",
50
- "description": "Table structure recognition",
51
- "gpu_memory_mb": 4096,
52
- "modal_service": "isa-vision"
53
- }
54
- },
55
- {
56
- "model_id": "paddleocr-v3.0",
57
- "model_type": ModelType.VISION,
58
- "capabilities": [ModelCapability.OCR, ModelCapability.IMAGE_ANALYSIS],
59
- "metadata": {
60
- "repo_id": "PaddlePaddle/PaddleOCR",
61
- "provider": "paddlepaddle",
62
- "version": "3.0",
63
- "description": "Multilingual OCR",
64
- "gpu_memory_mb": 2048,
65
- "modal_service": "isa-vision"
66
- }
67
- }
68
- ]
69
-
70
- print("🔧 Registering vision models in Supabase...")
71
-
72
- success_count = 0
73
- for model in models:
74
- success = registry.register_model(
75
- model_id=model["model_id"],
76
- model_type=model["model_type"],
77
- capabilities=model["capabilities"],
78
- metadata=model["metadata"]
79
- )
80
-
81
- if success:
82
- print(f"✅ {model['model_id']}")
83
- success_count += 1
84
- else:
85
- print(f"❌ {model['model_id']}")
86
-
87
- print(f"\n📊 Registered {success_count}/{len(models)} models")
88
- return success_count == len(models)
89
-
90
- def get_model_for_capability(capability: ModelCapability) -> str:
91
- """Get best model for a capability"""
92
-
93
- registry = ModelRegistry()
94
- models = registry.get_models_by_capability(capability)
95
-
96
- # Priority mapping
97
- priorities = {
98
- ModelCapability.UI_DETECTION: ["omniparser-v2.0"],
99
- ModelCapability.OCR: ["paddleocr-v3.0"],
100
- ModelCapability.TABLE_DETECTION: ["table-transformer-detection"],
101
- ModelCapability.TABLE_STRUCTURE_RECOGNITION: ["table-transformer-structure"]
102
- }
103
-
104
- preferred = priorities.get(capability, [])
105
- for model_id in preferred:
106
- if model_id in models:
107
- return model_id
108
-
109
- return list(models.keys())[0] if models else None
110
-
111
- if __name__ == "__main__":
112
- success = register_vision_models()
113
- if success:
114
- print("🎉 All vision models registered successfully!")
115
- else:
116
- print("⚠️ Some models failed to register")