mcli-framework 7.12.2__py3-none-any.whl → 7.12.4__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.
Potentially problematic release.
This version of mcli-framework might be problematic. Click here for more details.
- mcli/app/__init__.py +0 -2
- mcli/app/commands_cmd.py +30 -26
- mcli/app/completion_helpers.py +5 -5
- mcli/app/init_cmd.py +10 -10
- mcli/app/lock_cmd.py +29 -24
- mcli/app/main.py +2 -8
- mcli/app/model/model.py +5 -10
- mcli/app/store_cmd.py +8 -8
- mcli/app/video/__init__.py +0 -2
- mcli/app/video/video.py +1 -14
- mcli/chat/chat.py +90 -108
- mcli/chat/command_rag.py +0 -4
- mcli/chat/enhanced_chat.py +32 -41
- mcli/chat/system_controller.py +37 -37
- mcli/chat/system_integration.py +4 -5
- mcli/cli.py +2 -3
- mcli/lib/api/api.py +4 -9
- mcli/lib/api/daemon_client.py +19 -20
- mcli/lib/api/daemon_client_local.py +1 -3
- mcli/lib/api/daemon_decorator.py +6 -6
- mcli/lib/api/mcli_decorators.py +4 -8
- mcli/lib/auth/__init__.py +0 -1
- mcli/lib/auth/auth.py +4 -5
- mcli/lib/auth/mcli_manager.py +7 -12
- mcli/lib/auth/token_util.py +5 -5
- mcli/lib/config/__init__.py +29 -1
- mcli/lib/config/config.py +0 -1
- mcli/lib/custom_commands.py +1 -1
- mcli/lib/discovery/command_discovery.py +15 -15
- mcli/lib/erd/erd.py +7 -7
- mcli/lib/files/files.py +1 -1
- mcli/lib/fs/__init__.py +31 -1
- mcli/lib/fs/fs.py +12 -13
- mcli/lib/lib.py +0 -1
- mcli/lib/logger/logger.py +7 -10
- mcli/lib/performance/optimizer.py +25 -27
- mcli/lib/performance/rust_bridge.py +22 -27
- mcli/lib/performance/uvloop_config.py +0 -1
- mcli/lib/pickles/__init__.py +0 -1
- mcli/lib/pickles/pickles.py +0 -2
- mcli/lib/secrets/commands.py +0 -2
- mcli/lib/secrets/manager.py +0 -1
- mcli/lib/secrets/repl.py +2 -3
- mcli/lib/secrets/store.py +1 -2
- mcli/lib/services/data_pipeline.py +34 -34
- mcli/lib/services/lsh_client.py +38 -40
- mcli/lib/shell/shell.py +2 -2
- mcli/lib/toml/__init__.py +0 -1
- mcli/lib/ui/styling.py +0 -1
- mcli/lib/ui/visual_effects.py +33 -41
- mcli/lib/watcher/watcher.py +0 -1
- mcli/ml/__init__.py +1 -1
- mcli/ml/api/__init__.py +1 -1
- mcli/ml/api/app.py +8 -9
- mcli/ml/api/middleware.py +10 -10
- mcli/ml/api/routers/__init__.py +1 -1
- mcli/ml/api/routers/admin_router.py +3 -3
- mcli/ml/api/routers/auth_router.py +17 -18
- mcli/ml/api/routers/backtest_router.py +2 -2
- mcli/ml/api/routers/data_router.py +2 -2
- mcli/ml/api/routers/model_router.py +14 -15
- mcli/ml/api/routers/monitoring_router.py +2 -2
- mcli/ml/api/routers/portfolio_router.py +2 -2
- mcli/ml/api/routers/prediction_router.py +10 -9
- mcli/ml/api/routers/trade_router.py +2 -2
- mcli/ml/api/routers/websocket_router.py +6 -7
- mcli/ml/api/schemas.py +2 -2
- mcli/ml/auth/__init__.py +1 -1
- mcli/ml/auth/auth_manager.py +22 -23
- mcli/ml/auth/models.py +17 -17
- mcli/ml/auth/permissions.py +17 -17
- mcli/ml/backtesting/__init__.py +1 -1
- mcli/ml/backtesting/backtest_engine.py +31 -35
- mcli/ml/backtesting/performance_metrics.py +12 -14
- mcli/ml/backtesting/run.py +1 -2
- mcli/ml/cache.py +35 -36
- mcli/ml/cli/__init__.py +1 -1
- mcli/ml/cli/main.py +21 -24
- mcli/ml/config/__init__.py +1 -1
- mcli/ml/config/settings.py +28 -29
- mcli/ml/configs/__init__.py +1 -1
- mcli/ml/configs/dvc_config.py +14 -15
- mcli/ml/configs/mlflow_config.py +12 -13
- mcli/ml/configs/mlops_manager.py +19 -21
- mcli/ml/dashboard/__init__.py +4 -4
- mcli/ml/dashboard/app.py +20 -30
- mcli/ml/dashboard/app_supabase.py +16 -19
- mcli/ml/dashboard/app_training.py +11 -14
- mcli/ml/dashboard/cli.py +2 -2
- mcli/ml/dashboard/common.py +2 -3
- mcli/ml/dashboard/components/__init__.py +1 -1
- mcli/ml/dashboard/components/charts.py +13 -11
- mcli/ml/dashboard/components/metrics.py +7 -7
- mcli/ml/dashboard/components/tables.py +12 -9
- mcli/ml/dashboard/overview.py +2 -2
- mcli/ml/dashboard/pages/__init__.py +1 -1
- mcli/ml/dashboard/pages/cicd.py +15 -18
- mcli/ml/dashboard/pages/debug_dependencies.py +7 -7
- mcli/ml/dashboard/pages/monte_carlo_predictions.py +11 -18
- mcli/ml/dashboard/pages/predictions_enhanced.py +24 -32
- mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -24
- mcli/ml/dashboard/pages/test_portfolio.py +3 -6
- mcli/ml/dashboard/pages/trading.py +16 -18
- mcli/ml/dashboard/pages/workflows.py +20 -30
- mcli/ml/dashboard/utils.py +9 -9
- mcli/ml/dashboard/warning_suppression.py +3 -3
- mcli/ml/data_ingestion/__init__.py +1 -1
- mcli/ml/data_ingestion/api_connectors.py +41 -46
- mcli/ml/data_ingestion/data_pipeline.py +36 -46
- mcli/ml/data_ingestion/stream_processor.py +43 -46
- mcli/ml/database/__init__.py +1 -1
- mcli/ml/database/migrations/env.py +2 -2
- mcli/ml/database/models.py +22 -24
- mcli/ml/database/session.py +14 -14
- mcli/ml/experimentation/__init__.py +1 -1
- mcli/ml/experimentation/ab_testing.py +45 -46
- mcli/ml/features/__init__.py +1 -1
- mcli/ml/features/ensemble_features.py +22 -27
- mcli/ml/features/recommendation_engine.py +30 -30
- mcli/ml/features/stock_features.py +29 -32
- mcli/ml/features/test_feature_engineering.py +10 -11
- mcli/ml/logging.py +4 -4
- mcli/ml/mlops/__init__.py +1 -1
- mcli/ml/mlops/data_versioning.py +29 -30
- mcli/ml/mlops/experiment_tracker.py +24 -24
- mcli/ml/mlops/model_serving.py +31 -34
- mcli/ml/mlops/pipeline_orchestrator.py +27 -35
- mcli/ml/models/__init__.py +5 -6
- mcli/ml/models/base_models.py +23 -23
- mcli/ml/models/ensemble_models.py +31 -31
- mcli/ml/models/recommendation_models.py +18 -19
- mcli/ml/models/test_models.py +14 -16
- mcli/ml/monitoring/__init__.py +1 -1
- mcli/ml/monitoring/drift_detection.py +32 -36
- mcli/ml/monitoring/metrics.py +2 -2
- mcli/ml/optimization/__init__.py +1 -1
- mcli/ml/optimization/optimize.py +1 -2
- mcli/ml/optimization/portfolio_optimizer.py +30 -32
- mcli/ml/predictions/__init__.py +1 -1
- mcli/ml/preprocessing/__init__.py +1 -1
- mcli/ml/preprocessing/data_cleaners.py +22 -23
- mcli/ml/preprocessing/feature_extractors.py +23 -26
- mcli/ml/preprocessing/ml_pipeline.py +23 -23
- mcli/ml/preprocessing/test_preprocessing.py +7 -8
- mcli/ml/scripts/populate_sample_data.py +0 -4
- mcli/ml/serving/serve.py +1 -2
- mcli/ml/tasks.py +17 -17
- mcli/ml/tests/test_integration.py +29 -30
- mcli/ml/tests/test_training_dashboard.py +21 -21
- mcli/ml/trading/__init__.py +1 -1
- mcli/ml/trading/migrations.py +5 -5
- mcli/ml/trading/models.py +21 -23
- mcli/ml/trading/paper_trading.py +16 -13
- mcli/ml/trading/risk_management.py +17 -18
- mcli/ml/trading/trading_service.py +25 -28
- mcli/ml/training/__init__.py +1 -1
- mcli/ml/training/train.py +0 -1
- mcli/public/oi/oi.py +1 -2
- mcli/self/completion_cmd.py +6 -10
- mcli/self/logs_cmd.py +19 -24
- mcli/self/migrate_cmd.py +22 -20
- mcli/self/redis_cmd.py +10 -11
- mcli/self/self_cmd.py +10 -18
- mcli/self/store_cmd.py +10 -12
- mcli/self/visual_cmd.py +9 -14
- mcli/self/zsh_cmd.py +2 -4
- mcli/workflow/daemon/async_command_database.py +23 -24
- mcli/workflow/daemon/async_process_manager.py +27 -29
- mcli/workflow/daemon/client.py +27 -33
- mcli/workflow/daemon/daemon.py +32 -36
- mcli/workflow/daemon/enhanced_daemon.py +24 -33
- mcli/workflow/daemon/process_cli.py +11 -12
- mcli/workflow/daemon/process_manager.py +23 -26
- mcli/workflow/daemon/test_daemon.py +4 -5
- mcli/workflow/dashboard/dashboard_cmd.py +0 -1
- mcli/workflow/doc_convert.py +15 -17
- mcli/workflow/gcloud/__init__.py +0 -1
- mcli/workflow/gcloud/gcloud.py +11 -8
- mcli/workflow/git_commit/ai_service.py +14 -15
- mcli/workflow/lsh_integration.py +9 -11
- mcli/workflow/model_service/client.py +26 -31
- mcli/workflow/model_service/download_and_run_efficient_models.py +10 -14
- mcli/workflow/model_service/lightweight_embedder.py +25 -35
- mcli/workflow/model_service/lightweight_model_server.py +26 -32
- mcli/workflow/model_service/lightweight_test.py +7 -10
- mcli/workflow/model_service/model_service.py +80 -91
- mcli/workflow/model_service/ollama_efficient_runner.py +14 -18
- mcli/workflow/model_service/openai_adapter.py +23 -23
- mcli/workflow/model_service/pdf_processor.py +21 -26
- mcli/workflow/model_service/test_efficient_runner.py +12 -16
- mcli/workflow/model_service/test_example.py +11 -13
- mcli/workflow/model_service/test_integration.py +3 -5
- mcli/workflow/model_service/test_new_features.py +7 -8
- mcli/workflow/notebook/converter.py +1 -1
- mcli/workflow/notebook/notebook_cmd.py +5 -6
- mcli/workflow/notebook/schema.py +0 -1
- mcli/workflow/notebook/validator.py +7 -3
- mcli/workflow/openai/openai.py +1 -2
- mcli/workflow/registry/registry.py +4 -1
- mcli/workflow/repo/repo.py +6 -7
- mcli/workflow/scheduler/cron_parser.py +16 -19
- mcli/workflow/scheduler/job.py +10 -10
- mcli/workflow/scheduler/monitor.py +15 -15
- mcli/workflow/scheduler/persistence.py +17 -18
- mcli/workflow/scheduler/scheduler.py +37 -38
- mcli/workflow/secrets/__init__.py +1 -1
- mcli/workflow/sync/test_cmd.py +0 -1
- mcli/workflow/wakatime/__init__.py +5 -9
- mcli/workflow/wakatime/wakatime.py +1 -2
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/METADATA +1 -1
- mcli_framework-7.12.4.dist-info/RECORD +279 -0
- mcli_framework-7.12.2.dist-info/RECORD +0 -279
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/WHEEL +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/top_level.txt +0 -0
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import base64
|
|
3
1
|
import json
|
|
4
|
-
import logging
|
|
5
2
|
import os
|
|
6
|
-
import shutil
|
|
7
3
|
import signal
|
|
8
4
|
import sqlite3
|
|
9
5
|
import sys
|
|
10
|
-
import tempfile
|
|
11
6
|
import threading
|
|
12
7
|
import time
|
|
13
|
-
import urllib.parse
|
|
14
8
|
import uuid
|
|
15
|
-
from contextlib import asynccontextmanager
|
|
16
9
|
from dataclasses import asdict, dataclass
|
|
17
10
|
from datetime import datetime
|
|
18
11
|
from pathlib import Path
|
|
@@ -21,20 +14,17 @@ from urllib.parse import urlparse
|
|
|
21
14
|
|
|
22
15
|
# CLI Commands
|
|
23
16
|
import click
|
|
24
|
-
import numpy as np
|
|
25
17
|
import psutil
|
|
26
18
|
import requests
|
|
27
19
|
|
|
28
20
|
# Model loading and inference
|
|
29
21
|
import torch
|
|
30
|
-
import transformers
|
|
31
22
|
import uvicorn
|
|
32
23
|
|
|
33
24
|
# FastAPI for REST API
|
|
34
|
-
from fastapi import
|
|
25
|
+
from fastapi import FastAPI, HTTPException
|
|
35
26
|
from fastapi.middleware.cors import CORSMiddleware
|
|
36
|
-
from
|
|
37
|
-
from pydantic import BaseModel, Field
|
|
27
|
+
from pydantic import BaseModel
|
|
38
28
|
from transformers import AutoModel, AutoModelForCausalLM, AutoModelForSeq2SeqLM, AutoTokenizer
|
|
39
29
|
|
|
40
30
|
# Import existing utilities
|
|
@@ -66,7 +56,7 @@ DEFAULT_CONFIG = {
|
|
|
66
56
|
|
|
67
57
|
@dataclass
|
|
68
58
|
class ModelInfo:
|
|
69
|
-
"""Represents a loaded model"""
|
|
59
|
+
"""Represents a loaded model."""
|
|
70
60
|
|
|
71
61
|
id: str
|
|
72
62
|
name: str
|
|
@@ -91,7 +81,7 @@ class ModelInfo:
|
|
|
91
81
|
|
|
92
82
|
|
|
93
83
|
class ModelDatabase:
|
|
94
|
-
"""Manages model metadata storage"""
|
|
84
|
+
"""Manages model metadata storage."""
|
|
95
85
|
|
|
96
86
|
def __init__(self, db_path: Optional[str] = None):
|
|
97
87
|
if db_path is None:
|
|
@@ -103,7 +93,7 @@ class ModelDatabase:
|
|
|
103
93
|
self.init_database()
|
|
104
94
|
|
|
105
95
|
def init_database(self):
|
|
106
|
-
"""Initialize SQLite database"""
|
|
96
|
+
"""Initialize SQLite database."""
|
|
107
97
|
conn = sqlite3.connect(self.db_path)
|
|
108
98
|
cursor = conn.cursor()
|
|
109
99
|
|
|
@@ -150,7 +140,7 @@ class ModelDatabase:
|
|
|
150
140
|
conn.close()
|
|
151
141
|
|
|
152
142
|
def add_model(self, model_info: ModelInfo) -> str:
|
|
153
|
-
"""Add a new model to the database"""
|
|
143
|
+
"""Add a new model to the database."""
|
|
154
144
|
conn = sqlite3.connect(self.db_path)
|
|
155
145
|
cursor = conn.cursor()
|
|
156
146
|
|
|
@@ -192,7 +182,7 @@ class ModelDatabase:
|
|
|
192
182
|
conn.close()
|
|
193
183
|
|
|
194
184
|
def get_model(self, model_id: str) -> Optional[ModelInfo]:
|
|
195
|
-
"""Get a model by ID"""
|
|
185
|
+
"""Get a model by ID."""
|
|
196
186
|
conn = sqlite3.connect(self.db_path)
|
|
197
187
|
cursor = conn.cursor()
|
|
198
188
|
|
|
@@ -216,7 +206,7 @@ class ModelDatabase:
|
|
|
216
206
|
conn.close()
|
|
217
207
|
|
|
218
208
|
def get_all_models(self) -> List[ModelInfo]:
|
|
219
|
-
"""Get all models"""
|
|
209
|
+
"""Get all models."""
|
|
220
210
|
conn = sqlite3.connect(self.db_path)
|
|
221
211
|
cursor = conn.cursor()
|
|
222
212
|
|
|
@@ -236,7 +226,7 @@ class ModelDatabase:
|
|
|
236
226
|
conn.close()
|
|
237
227
|
|
|
238
228
|
def update_model(self, model_info: ModelInfo) -> bool:
|
|
239
|
-
"""Update model information"""
|
|
229
|
+
"""Update model information."""
|
|
240
230
|
conn = sqlite3.connect(self.db_path)
|
|
241
231
|
cursor = conn.cursor()
|
|
242
232
|
|
|
@@ -277,7 +267,7 @@ class ModelDatabase:
|
|
|
277
267
|
conn.close()
|
|
278
268
|
|
|
279
269
|
def delete_model(self, model_id: str) -> bool:
|
|
280
|
-
"""Delete a model"""
|
|
270
|
+
"""Delete a model."""
|
|
281
271
|
conn = sqlite3.connect(self.db_path)
|
|
282
272
|
cursor = conn.cursor()
|
|
283
273
|
|
|
@@ -302,7 +292,7 @@ class ModelDatabase:
|
|
|
302
292
|
execution_time_ms: int = int(),
|
|
303
293
|
error_message: str = str(),
|
|
304
294
|
):
|
|
305
|
-
"""Record inference request"""
|
|
295
|
+
"""Record inference request."""
|
|
306
296
|
conn = sqlite3.connect(self.db_path)
|
|
307
297
|
cursor = conn.cursor()
|
|
308
298
|
|
|
@@ -335,7 +325,7 @@ class ModelDatabase:
|
|
|
335
325
|
conn.close()
|
|
336
326
|
|
|
337
327
|
def _row_to_model_info(self, row) -> ModelInfo:
|
|
338
|
-
"""Convert database row to ModelInfo object"""
|
|
328
|
+
"""Convert database row to ModelInfo object."""
|
|
339
329
|
return ModelInfo(
|
|
340
330
|
id=row[0],
|
|
341
331
|
name=row[1],
|
|
@@ -355,7 +345,7 @@ class ModelDatabase:
|
|
|
355
345
|
|
|
356
346
|
|
|
357
347
|
class ModelManager:
|
|
358
|
-
"""Manages model loading, caching, and inference"""
|
|
348
|
+
"""Manages model loading, caching, and inference."""
|
|
359
349
|
|
|
360
350
|
def __init__(self, models_dir: str = "./models", max_cache_size: int = 2):
|
|
361
351
|
self.models_dir = Path(models_dir)
|
|
@@ -370,7 +360,7 @@ class ModelManager:
|
|
|
370
360
|
logger.info(f"Using device: {self.device}")
|
|
371
361
|
|
|
372
362
|
def load_model(self, model_info: ModelInfo) -> bool:
|
|
373
|
-
"""Load a model into memory"""
|
|
363
|
+
"""Load a model into memory."""
|
|
374
364
|
with self.model_lock:
|
|
375
365
|
try:
|
|
376
366
|
logger.info(f"Loading model: {model_info.name}")
|
|
@@ -418,7 +408,7 @@ class ModelManager:
|
|
|
418
408
|
return False
|
|
419
409
|
|
|
420
410
|
def unload_model(self, model_id: str) -> bool:
|
|
421
|
-
"""Unload a model from memory"""
|
|
411
|
+
"""Unload a model from memory."""
|
|
422
412
|
with self.model_lock:
|
|
423
413
|
if model_id in self.loaded_models:
|
|
424
414
|
del self.loaded_models[model_id]
|
|
@@ -435,7 +425,7 @@ class ModelManager:
|
|
|
435
425
|
return False
|
|
436
426
|
|
|
437
427
|
def _load_text_generation_model(self, model_info: ModelInfo):
|
|
438
|
-
"""Load a text generation model"""
|
|
428
|
+
"""Load a text generation model."""
|
|
439
429
|
tokenizer = AutoTokenizer.from_pretrained(
|
|
440
430
|
model_info.tokenizer_path or model_info.model_path, trust_remote_code=True
|
|
441
431
|
)
|
|
@@ -453,7 +443,7 @@ class ModelManager:
|
|
|
453
443
|
return model, tokenizer
|
|
454
444
|
|
|
455
445
|
def _load_text_classification_model(self, model_info: ModelInfo):
|
|
456
|
-
"""Load a text classification model"""
|
|
446
|
+
"""Load a text classification model."""
|
|
457
447
|
tokenizer = AutoTokenizer.from_pretrained(
|
|
458
448
|
model_info.tokenizer_path or model_info.model_path
|
|
459
449
|
)
|
|
@@ -470,7 +460,7 @@ class ModelManager:
|
|
|
470
460
|
return model, tokenizer
|
|
471
461
|
|
|
472
462
|
def _load_translation_model(self, model_info: ModelInfo):
|
|
473
|
-
"""Load a translation model"""
|
|
463
|
+
"""Load a translation model."""
|
|
474
464
|
tokenizer = AutoTokenizer.from_pretrained(
|
|
475
465
|
model_info.tokenizer_path or model_info.model_path
|
|
476
466
|
)
|
|
@@ -487,13 +477,13 @@ class ModelManager:
|
|
|
487
477
|
return model, tokenizer
|
|
488
478
|
|
|
489
479
|
def _load_image_generation_model(self, model_info: ModelInfo):
|
|
490
|
-
"""Load an image generation model (placeholder)"""
|
|
480
|
+
"""Load an image generation model (placeholder)."""
|
|
491
481
|
# This would be implemented based on specific image generation frameworks
|
|
492
482
|
# like Stable Diffusion, DALL-E, etc.
|
|
493
483
|
raise NotImplementedError("Image generation models not yet implemented")
|
|
494
484
|
|
|
495
485
|
def _evict_oldest_model(self):
|
|
496
|
-
"""Evict the oldest loaded model from cache"""
|
|
486
|
+
"""Evict the oldest loaded model from cache."""
|
|
497
487
|
if not self.loaded_models:
|
|
498
488
|
return
|
|
499
489
|
|
|
@@ -501,7 +491,7 @@ class ModelManager:
|
|
|
501
491
|
self.unload_model(oldest_id)
|
|
502
492
|
|
|
503
493
|
def _get_model_memory_usage(self, model) -> float:
|
|
504
|
-
"""Get model memory usage in MB"""
|
|
494
|
+
"""Get model memory usage in MB."""
|
|
505
495
|
try:
|
|
506
496
|
if self.device == "cuda":
|
|
507
497
|
return torch.cuda.memory_allocated() / 1024 / 1024
|
|
@@ -509,7 +499,7 @@ class ModelManager:
|
|
|
509
499
|
# Rough estimation for CPU
|
|
510
500
|
total_params = sum(p.numel() for p in model.parameters())
|
|
511
501
|
return total_params * 4 / 1024 / 1024 # 4 bytes per float32
|
|
512
|
-
except:
|
|
502
|
+
except Exception:
|
|
513
503
|
return 0.0
|
|
514
504
|
|
|
515
505
|
def generate_text(
|
|
@@ -521,7 +511,7 @@ class ModelManager:
|
|
|
521
511
|
top_p: float = float(),
|
|
522
512
|
top_k: int = int(),
|
|
523
513
|
) -> str:
|
|
524
|
-
"""Generate text using a loaded model"""
|
|
514
|
+
"""Generate text using a loaded model."""
|
|
525
515
|
if model_id not in self.loaded_models:
|
|
526
516
|
raise ValueError(f"Model {model_id} not loaded")
|
|
527
517
|
|
|
@@ -568,7 +558,7 @@ class ModelManager:
|
|
|
568
558
|
raise
|
|
569
559
|
|
|
570
560
|
def classify_text(self, model_id: str, text: str) -> Dict[str, float]:
|
|
571
|
-
"""Classify text using a loaded model"""
|
|
561
|
+
"""Classify text using a loaded model."""
|
|
572
562
|
if model_id not in self.loaded_models:
|
|
573
563
|
raise ValueError(f"Model {model_id} not loaded")
|
|
574
564
|
|
|
@@ -599,7 +589,7 @@ class ModelManager:
|
|
|
599
589
|
def translate_text(
|
|
600
590
|
self, model_id: str, text: str, source_lang: str = "en", target_lang: str = "fr"
|
|
601
591
|
) -> str:
|
|
602
|
-
"""Translate text using a loaded model"""
|
|
592
|
+
"""Translate text using a loaded model."""
|
|
603
593
|
if model_id not in self.loaded_models:
|
|
604
594
|
raise ValueError(f"Model {model_id} not loaded")
|
|
605
595
|
|
|
@@ -635,7 +625,7 @@ class ModelManager:
|
|
|
635
625
|
def download_model_from_url(
|
|
636
626
|
self, model_url: str, tokenizer_url: Optional[str] = None
|
|
637
627
|
) -> tuple[str, Optional[str]]:
|
|
638
|
-
"""Download model and tokenizer from URLs and return local paths"""
|
|
628
|
+
"""Download model and tokenizer from URLs and return local paths."""
|
|
639
629
|
try:
|
|
640
630
|
# Parse URLs
|
|
641
631
|
model_parsed = urlparse(model_url)
|
|
@@ -686,7 +676,7 @@ class ModelManager:
|
|
|
686
676
|
top_p: float = 0.9,
|
|
687
677
|
top_k: int = 50,
|
|
688
678
|
) -> str:
|
|
689
|
-
"""Add a model from URL by downloading it first"""
|
|
679
|
+
"""Add a model from URL by downloading it first."""
|
|
690
680
|
try:
|
|
691
681
|
# Download model and tokenizer
|
|
692
682
|
model_path, tokenizer_path = self.download_model_from_url(model_url, tokenizer_url)
|
|
@@ -721,7 +711,7 @@ class ModelManager:
|
|
|
721
711
|
raise
|
|
722
712
|
|
|
723
713
|
def get_models_summary(self) -> Dict[str, Any]:
|
|
724
|
-
"""Get a summary of all models with statistics"""
|
|
714
|
+
"""Get a summary of all models with statistics."""
|
|
725
715
|
models = self.db.get_all_models()
|
|
726
716
|
|
|
727
717
|
summary = {
|
|
@@ -802,7 +792,7 @@ class TranslationRequest(BaseModel):
|
|
|
802
792
|
|
|
803
793
|
|
|
804
794
|
class ModelService:
|
|
805
|
-
"""Main model service daemon"""
|
|
795
|
+
"""Main model service daemon."""
|
|
806
796
|
|
|
807
797
|
def __init__(self, config: Dict[str, Any] = dict[str(), object()]()):
|
|
808
798
|
self.config = {**DEFAULT_CONFIG, **(config or {})}
|
|
@@ -850,7 +840,7 @@ class ModelService:
|
|
|
850
840
|
self._setup_routes()
|
|
851
841
|
|
|
852
842
|
def _setup_routes(self):
|
|
853
|
-
"""Setup FastAPI routes"""
|
|
843
|
+
"""Setup FastAPI routes."""
|
|
854
844
|
|
|
855
845
|
@self.app.get("/")
|
|
856
846
|
async def root():
|
|
@@ -863,18 +853,18 @@ class ModelService:
|
|
|
863
853
|
|
|
864
854
|
@self.app.get("/models")
|
|
865
855
|
async def list_models():
|
|
866
|
-
"""List all available models"""
|
|
856
|
+
"""List all available models."""
|
|
867
857
|
models = self.model_manager.db.get_all_models()
|
|
868
858
|
return [asdict(model) for model in models]
|
|
869
859
|
|
|
870
860
|
@self.app.get("/models/summary")
|
|
871
861
|
async def get_models_summary():
|
|
872
|
-
"""Get a summary of all models with statistics"""
|
|
862
|
+
"""Get a summary of all models with statistics."""
|
|
873
863
|
return self.model_manager.get_models_summary()
|
|
874
864
|
|
|
875
865
|
@self.app.post("/models")
|
|
876
866
|
async def load_model(request: ModelLoadRequest):
|
|
877
|
-
"""Load a new model"""
|
|
867
|
+
"""Load a new model."""
|
|
878
868
|
try:
|
|
879
869
|
model_info = ModelInfo(
|
|
880
870
|
id=str(uuid.uuid4()),
|
|
@@ -907,7 +897,7 @@ class ModelService:
|
|
|
907
897
|
|
|
908
898
|
@self.app.post("/models/from-url")
|
|
909
899
|
async def load_model_from_url(request: ModelLoadFromUrlRequest):
|
|
910
|
-
"""Load a new model from URL"""
|
|
900
|
+
"""Load a new model from URL."""
|
|
911
901
|
try:
|
|
912
902
|
model_id = self.model_manager.add_model_from_url(
|
|
913
903
|
name=request.name,
|
|
@@ -928,7 +918,7 @@ class ModelService:
|
|
|
928
918
|
|
|
929
919
|
@self.app.delete("/models/{model_id}")
|
|
930
920
|
async def unload_model(model_id: str):
|
|
931
|
-
"""Unload a model"""
|
|
921
|
+
"""Unload a model."""
|
|
932
922
|
try:
|
|
933
923
|
success = self.model_manager.unload_model(model_id)
|
|
934
924
|
if success:
|
|
@@ -940,7 +930,7 @@ class ModelService:
|
|
|
940
930
|
|
|
941
931
|
@self.app.put("/models/{model_id}")
|
|
942
932
|
async def update_model(model_id: str, request: Dict[str, Any]):
|
|
943
|
-
"""Update model configuration"""
|
|
933
|
+
"""Update model configuration."""
|
|
944
934
|
try:
|
|
945
935
|
# Get current model info
|
|
946
936
|
model_info = self.model_manager.db.get_model(model_id)
|
|
@@ -966,7 +956,7 @@ class ModelService:
|
|
|
966
956
|
|
|
967
957
|
@self.app.delete("/models/{model_id}/remove")
|
|
968
958
|
async def remove_model(model_id: str):
|
|
969
|
-
"""Remove a model from the database"""
|
|
959
|
+
"""Remove a model from the database."""
|
|
970
960
|
try:
|
|
971
961
|
# First unload if loaded
|
|
972
962
|
self.model_manager.unload_model(model_id)
|
|
@@ -985,7 +975,7 @@ class ModelService:
|
|
|
985
975
|
|
|
986
976
|
@self.app.post("/models/{model_id}/generate")
|
|
987
977
|
async def generate_text(model_id: str, request: TextGenerationRequest):
|
|
988
|
-
"""Generate text using a model"""
|
|
978
|
+
"""Generate text using a model."""
|
|
989
979
|
try:
|
|
990
980
|
start_time = time.time()
|
|
991
981
|
|
|
@@ -1023,7 +1013,7 @@ class ModelService:
|
|
|
1023
1013
|
|
|
1024
1014
|
@self.app.post("/models/{model_id}/classify")
|
|
1025
1015
|
async def classify_text(model_id: str, request: TextClassificationRequest):
|
|
1026
|
-
"""Classify text using a model"""
|
|
1016
|
+
"""Classify text using a model."""
|
|
1027
1017
|
try:
|
|
1028
1018
|
start_time = time.time()
|
|
1029
1019
|
|
|
@@ -1056,7 +1046,7 @@ class ModelService:
|
|
|
1056
1046
|
|
|
1057
1047
|
@self.app.post("/models/{model_id}/translate")
|
|
1058
1048
|
async def translate_text(model_id: str, request: TranslationRequest):
|
|
1059
|
-
"""Translate text using a model"""
|
|
1049
|
+
"""Translate text using a model."""
|
|
1060
1050
|
try:
|
|
1061
1051
|
start_time = time.time()
|
|
1062
1052
|
|
|
@@ -1092,7 +1082,7 @@ class ModelService:
|
|
|
1092
1082
|
|
|
1093
1083
|
@self.app.get("/health")
|
|
1094
1084
|
async def health_check():
|
|
1095
|
-
"""Health check endpoint"""
|
|
1085
|
+
"""Health check endpoint."""
|
|
1096
1086
|
return {
|
|
1097
1087
|
"status": "healthy",
|
|
1098
1088
|
"models_loaded": len(self.model_manager.loaded_models),
|
|
@@ -1105,7 +1095,7 @@ class ModelService:
|
|
|
1105
1095
|
# Lightweight server endpoints
|
|
1106
1096
|
@self.app.get("/lightweight/models")
|
|
1107
1097
|
async def list_lightweight_models():
|
|
1108
|
-
"""List available lightweight models"""
|
|
1098
|
+
"""List available lightweight models."""
|
|
1109
1099
|
return {
|
|
1110
1100
|
"models": LIGHTWEIGHT_MODELS,
|
|
1111
1101
|
"downloaded": self.lightweight_server.downloader.get_downloaded_models(),
|
|
@@ -1114,7 +1104,7 @@ class ModelService:
|
|
|
1114
1104
|
|
|
1115
1105
|
@self.app.post("/lightweight/models/{model_key}/download")
|
|
1116
1106
|
async def download_lightweight_model(model_key: str):
|
|
1117
|
-
"""Download a lightweight model"""
|
|
1107
|
+
"""Download a lightweight model."""
|
|
1118
1108
|
if model_key not in LIGHTWEIGHT_MODELS:
|
|
1119
1109
|
raise HTTPException(status_code=404, detail="Model not found")
|
|
1120
1110
|
|
|
@@ -1129,7 +1119,7 @@ class ModelService:
|
|
|
1129
1119
|
|
|
1130
1120
|
@self.app.post("/lightweight/start")
|
|
1131
1121
|
async def start_lightweight_server():
|
|
1132
|
-
"""Start the lightweight server"""
|
|
1122
|
+
"""Start the lightweight server."""
|
|
1133
1123
|
try:
|
|
1134
1124
|
self.lightweight_server.start_server()
|
|
1135
1125
|
return {
|
|
@@ -1142,7 +1132,7 @@ class ModelService:
|
|
|
1142
1132
|
|
|
1143
1133
|
@self.app.get("/lightweight/status")
|
|
1144
1134
|
async def lightweight_status():
|
|
1145
|
-
"""Get lightweight server status"""
|
|
1135
|
+
"""Get lightweight server status."""
|
|
1146
1136
|
return {
|
|
1147
1137
|
"running": self.lightweight_server.running,
|
|
1148
1138
|
"port": self.lightweight_server.port,
|
|
@@ -1153,7 +1143,7 @@ class ModelService:
|
|
|
1153
1143
|
# PDF processing endpoints
|
|
1154
1144
|
@self.app.post("/pdf/extract-text")
|
|
1155
1145
|
async def extract_pdf_text(request: Dict[str, Any]):
|
|
1156
|
-
"""Extract text from PDF"""
|
|
1146
|
+
"""Extract text from PDF."""
|
|
1157
1147
|
try:
|
|
1158
1148
|
pdf_path = request.get("pdf_path")
|
|
1159
1149
|
if not pdf_path:
|
|
@@ -1166,7 +1156,7 @@ class ModelService:
|
|
|
1166
1156
|
|
|
1167
1157
|
@self.app.post("/pdf/process-with-ai")
|
|
1168
1158
|
async def process_pdf_with_ai(request: Dict[str, Any]):
|
|
1169
|
-
"""Process PDF with AI analysis"""
|
|
1159
|
+
"""Process PDF with AI analysis."""
|
|
1170
1160
|
try:
|
|
1171
1161
|
pdf_path = request.get("pdf_path")
|
|
1172
1162
|
model_key = request.get("model_key")
|
|
@@ -1185,13 +1175,13 @@ class ModelService:
|
|
|
1185
1175
|
|
|
1186
1176
|
@self.app.get("/pdf/status")
|
|
1187
1177
|
async def pdf_processor_status():
|
|
1188
|
-
"""Get PDF processor status"""
|
|
1178
|
+
"""Get PDF processor status."""
|
|
1189
1179
|
return self.pdf_processor.get_service_status()
|
|
1190
1180
|
|
|
1191
1181
|
# Embedding endpoints
|
|
1192
1182
|
@self.app.post("/embed/text")
|
|
1193
1183
|
async def embed_text(request: Dict[str, Any]):
|
|
1194
|
-
"""Embed text using lightweight embedder"""
|
|
1184
|
+
"""Embed text using lightweight embedder."""
|
|
1195
1185
|
try:
|
|
1196
1186
|
text = request.get("text")
|
|
1197
1187
|
method = request.get("method")
|
|
@@ -1210,7 +1200,7 @@ class ModelService:
|
|
|
1210
1200
|
|
|
1211
1201
|
@self.app.post("/embed/document")
|
|
1212
1202
|
async def embed_document(request: Dict[str, Any]):
|
|
1213
|
-
"""Embed document using lightweight embedder"""
|
|
1203
|
+
"""Embed document using lightweight embedder."""
|
|
1214
1204
|
try:
|
|
1215
1205
|
text = request.get("text")
|
|
1216
1206
|
chunk_size = request.get("chunk_size", 1000)
|
|
@@ -1225,7 +1215,7 @@ class ModelService:
|
|
|
1225
1215
|
|
|
1226
1216
|
@self.app.post("/embed/search")
|
|
1227
1217
|
async def search_embeddings(request: Dict[str, Any]):
|
|
1228
|
-
"""Search similar documents using embeddings"""
|
|
1218
|
+
"""Search similar documents using embeddings."""
|
|
1229
1219
|
try:
|
|
1230
1220
|
query = request.get("query")
|
|
1231
1221
|
embeddings = request.get("embeddings", [])
|
|
@@ -1241,11 +1231,11 @@ class ModelService:
|
|
|
1241
1231
|
|
|
1242
1232
|
@self.app.get("/embed/status")
|
|
1243
1233
|
async def embedder_status():
|
|
1244
|
-
"""Get embedder status"""
|
|
1234
|
+
"""Get embedder status."""
|
|
1245
1235
|
return self.embedder.get_status()
|
|
1246
1236
|
|
|
1247
1237
|
def start(self):
|
|
1248
|
-
"""Start the model service"""
|
|
1238
|
+
"""Start the model service."""
|
|
1249
1239
|
if self.running:
|
|
1250
1240
|
logger.info("Model service is already running")
|
|
1251
1241
|
return
|
|
@@ -1289,7 +1279,7 @@ class ModelService:
|
|
|
1289
1279
|
self.stop()
|
|
1290
1280
|
|
|
1291
1281
|
def stop(self):
|
|
1292
|
-
"""Stop the model service"""
|
|
1282
|
+
"""Stop the model service."""
|
|
1293
1283
|
if not self.running:
|
|
1294
1284
|
return
|
|
1295
1285
|
|
|
@@ -1306,13 +1296,13 @@ class ModelService:
|
|
|
1306
1296
|
logger.info("Model service stopped")
|
|
1307
1297
|
|
|
1308
1298
|
def _signal_handler(self, signum, frame):
|
|
1309
|
-
"""Handle shutdown signals"""
|
|
1299
|
+
"""Handle shutdown signals."""
|
|
1310
1300
|
logger.info(f"Received signal {signum}, shutting down...")
|
|
1311
1301
|
self.stop()
|
|
1312
1302
|
sys.exit(0)
|
|
1313
1303
|
|
|
1314
1304
|
def status(self) -> Dict[str, Any]:
|
|
1315
|
-
"""Get service status"""
|
|
1305
|
+
"""Get service status."""
|
|
1316
1306
|
is_running = False
|
|
1317
1307
|
pid = None
|
|
1318
1308
|
|
|
@@ -1334,13 +1324,12 @@ class ModelService:
|
|
|
1334
1324
|
|
|
1335
1325
|
|
|
1336
1326
|
# CLI Commands
|
|
1337
|
-
import click
|
|
1327
|
+
# import click # Already imported above
|
|
1338
1328
|
|
|
1339
1329
|
|
|
1340
1330
|
@click.group(name="model-service")
|
|
1341
1331
|
def model_service():
|
|
1342
|
-
"""Model service daemon for hosting language models"""
|
|
1343
|
-
pass
|
|
1332
|
+
"""Model service daemon for hosting language models."""
|
|
1344
1333
|
|
|
1345
1334
|
|
|
1346
1335
|
@model_service.command()
|
|
@@ -1349,7 +1338,7 @@ def model_service():
|
|
|
1349
1338
|
@click.option("--port", default=8000, help="Port to bind to")
|
|
1350
1339
|
@click.option("--models-dir", default="./models", help="Directory for model storage")
|
|
1351
1340
|
def start(config: Optional[str], host: str, port: int, models_dir: str):
|
|
1352
|
-
"""Start the model service daemon"""
|
|
1341
|
+
"""Start the model service daemon."""
|
|
1353
1342
|
# Load config if provided
|
|
1354
1343
|
service_config = DEFAULT_CONFIG.copy()
|
|
1355
1344
|
if config:
|
|
@@ -1371,7 +1360,7 @@ def start(config: Optional[str], host: str, port: int, models_dir: str):
|
|
|
1371
1360
|
|
|
1372
1361
|
@model_service.command()
|
|
1373
1362
|
def stop():
|
|
1374
|
-
"""Stop the model service daemon"""
|
|
1363
|
+
"""Stop the model service daemon."""
|
|
1375
1364
|
pid_file = Path.home() / ".local" / "mcli" / "model_service" / "model_service.pid"
|
|
1376
1365
|
|
|
1377
1366
|
if not pid_file.exists():
|
|
@@ -1399,7 +1388,7 @@ def stop():
|
|
|
1399
1388
|
|
|
1400
1389
|
@model_service.command()
|
|
1401
1390
|
def status():
|
|
1402
|
-
"""Show model service status"""
|
|
1391
|
+
"""Show model service status."""
|
|
1403
1392
|
service = ModelService()
|
|
1404
1393
|
status_info = service.status()
|
|
1405
1394
|
|
|
@@ -1416,7 +1405,7 @@ def status():
|
|
|
1416
1405
|
@model_service.command()
|
|
1417
1406
|
@click.option("--summary", is_flag=True, help="Show summary statistics")
|
|
1418
1407
|
def list_models(summary: bool = False):
|
|
1419
|
-
"""List all models in the service"""
|
|
1408
|
+
"""List all models in the service."""
|
|
1420
1409
|
service = ModelService()
|
|
1421
1410
|
|
|
1422
1411
|
try:
|
|
@@ -1481,7 +1470,7 @@ def list_models(summary: bool = False):
|
|
|
1481
1470
|
def add_model(
|
|
1482
1471
|
model_path: str, name: str, model_type: str, tokenizer_path: str = str(), device: str = "auto"
|
|
1483
1472
|
):
|
|
1484
|
-
"""Add a model to the service"""
|
|
1473
|
+
"""Add a model to the service."""
|
|
1485
1474
|
service = ModelService()
|
|
1486
1475
|
|
|
1487
1476
|
try:
|
|
@@ -1534,7 +1523,7 @@ def add_model_from_url(
|
|
|
1534
1523
|
top_p: float = 0.9,
|
|
1535
1524
|
top_k: int = 50,
|
|
1536
1525
|
):
|
|
1537
|
-
"""Add a model from URL to the service"""
|
|
1526
|
+
"""Add a model from URL to the service."""
|
|
1538
1527
|
service = ModelService()
|
|
1539
1528
|
|
|
1540
1529
|
try:
|
|
@@ -1577,7 +1566,7 @@ def update_model(
|
|
|
1577
1566
|
top_k: Optional[int] = None,
|
|
1578
1567
|
device: Optional[str] = None,
|
|
1579
1568
|
):
|
|
1580
|
-
"""Update model configuration"""
|
|
1569
|
+
"""Update model configuration."""
|
|
1581
1570
|
service = ModelService()
|
|
1582
1571
|
|
|
1583
1572
|
try:
|
|
@@ -1627,7 +1616,7 @@ def update_model(
|
|
|
1627
1616
|
@click.argument("model_id")
|
|
1628
1617
|
@click.option("--force", is_flag=True, help="Force removal without confirmation")
|
|
1629
1618
|
def remove_model(model_id: str, force: bool = False):
|
|
1630
|
-
"""Remove a model from the service"""
|
|
1619
|
+
"""Remove a model from the service."""
|
|
1631
1620
|
service = ModelService()
|
|
1632
1621
|
|
|
1633
1622
|
try:
|
|
@@ -1638,7 +1627,7 @@ def remove_model(model_id: str, force: bool = False):
|
|
|
1638
1627
|
return
|
|
1639
1628
|
|
|
1640
1629
|
if not force:
|
|
1641
|
-
click.echo(
|
|
1630
|
+
click.echo("Model to remove:")
|
|
1642
1631
|
click.echo(f" Name: {model_info.name}")
|
|
1643
1632
|
click.echo(f" Type: {model_info.model_type}")
|
|
1644
1633
|
click.echo(f" Path: {model_info.model_path}")
|
|
@@ -1672,7 +1661,7 @@ def remove_model(model_id: str, force: bool = False):
|
|
|
1672
1661
|
@click.option("--start-server", is_flag=True, help="Start the lightweight server")
|
|
1673
1662
|
@click.option("--port", default=8080, help="Port for lightweight server")
|
|
1674
1663
|
def lightweight(list: bool, download: str, auto: bool, start_server: bool, port: int):
|
|
1675
|
-
"""Manage lightweight models and server"""
|
|
1664
|
+
"""Manage lightweight models and server."""
|
|
1676
1665
|
service = ModelService()
|
|
1677
1666
|
|
|
1678
1667
|
if list:
|
|
@@ -1725,7 +1714,7 @@ def lightweight(list: bool, download: str, auto: bool, start_server: bool, port:
|
|
|
1725
1714
|
service.lightweight_server.port = port
|
|
1726
1715
|
service.lightweight_server.start_server()
|
|
1727
1716
|
|
|
1728
|
-
click.echo(
|
|
1717
|
+
click.echo("✅ Server started!")
|
|
1729
1718
|
click.echo(f"🌐 API: http://localhost:{port}")
|
|
1730
1719
|
click.echo(f"📊 Health: http://localhost:{port}/health")
|
|
1731
1720
|
click.echo(f"📋 Models: http://localhost:{port}/models")
|
|
@@ -1760,7 +1749,7 @@ def lightweight(list: bool, download: str, auto: bool, start_server: bool, port:
|
|
|
1760
1749
|
def lightweight_run(
|
|
1761
1750
|
model: Optional[str], auto: bool, port: int, list_models: bool, download_only: bool
|
|
1762
1751
|
):
|
|
1763
|
-
"""Run lightweight model server (standalone mode)"""
|
|
1752
|
+
"""Run lightweight model server (standalone mode)."""
|
|
1764
1753
|
service = ModelService()
|
|
1765
1754
|
|
|
1766
1755
|
click.echo("🚀 MCLI Lightweight Model Server")
|
|
@@ -1799,7 +1788,7 @@ def lightweight_run(
|
|
|
1799
1788
|
service.lightweight_server.port = port
|
|
1800
1789
|
service.lightweight_server.start_server()
|
|
1801
1790
|
|
|
1802
|
-
click.echo(
|
|
1791
|
+
click.echo("\n📝 Usage:")
|
|
1803
1792
|
click.echo(f" - API: http://localhost:{port}")
|
|
1804
1793
|
click.echo(f" - Health: http://localhost:{port}/health")
|
|
1805
1794
|
click.echo(f" - Models: http://localhost:{port}/models")
|
|
@@ -1818,7 +1807,7 @@ def lightweight_run(
|
|
|
1818
1807
|
@click.option("--model", help="Specific model to use for AI analysis")
|
|
1819
1808
|
@click.option("--extract-only", is_flag=True, help="Only extract text, no AI analysis")
|
|
1820
1809
|
def process_pdf(pdf_path: str, model: str, extract_only: bool):
|
|
1821
|
-
"""Process PDF with AI analysis"""
|
|
1810
|
+
"""Process PDF with AI analysis."""
|
|
1822
1811
|
service = ModelService()
|
|
1823
1812
|
|
|
1824
1813
|
try:
|
|
@@ -1839,7 +1828,7 @@ def process_pdf(pdf_path: str, model: str, extract_only: bool):
|
|
|
1839
1828
|
click.echo(f"📝 Preview: {result['text'][:200]}...")
|
|
1840
1829
|
else:
|
|
1841
1830
|
analysis = result["pdf_analysis"]["ai_analysis"]
|
|
1842
|
-
click.echo(
|
|
1831
|
+
click.echo("✅ PDF processed successfully!")
|
|
1843
1832
|
click.echo(f"📊 Document type: {analysis['document_type']}")
|
|
1844
1833
|
click.echo(f"📝 Summary: {analysis['summary'][:200]}...")
|
|
1845
1834
|
click.echo(f"🔑 Key topics: {', '.join(analysis['key_topics'])}")
|
|
@@ -1854,7 +1843,7 @@ def process_pdf(pdf_path: str, model: str, extract_only: bool):
|
|
|
1854
1843
|
@model_service.command()
|
|
1855
1844
|
@click.option("--port", default=8080, help="Port for PDF processing service")
|
|
1856
1845
|
def start_pdf_service(port: int):
|
|
1857
|
-
"""Start PDF processing service"""
|
|
1846
|
+
"""Start PDF processing service."""
|
|
1858
1847
|
service = ModelService()
|
|
1859
1848
|
|
|
1860
1849
|
try:
|
|
@@ -1862,7 +1851,7 @@ def start_pdf_service(port: int):
|
|
|
1862
1851
|
success = service.pdf_processor.start_pdf_processing_service(port)
|
|
1863
1852
|
|
|
1864
1853
|
if success:
|
|
1865
|
-
click.echo(
|
|
1854
|
+
click.echo("✅ PDF processing service started!")
|
|
1866
1855
|
click.echo(f"🌐 API: http://localhost:{port}")
|
|
1867
1856
|
click.echo(f"📊 Status: http://localhost:{port}/status")
|
|
1868
1857
|
|
|
@@ -1883,7 +1872,7 @@ def start_pdf_service(port: int):
|
|
|
1883
1872
|
@click.argument("text")
|
|
1884
1873
|
@click.option("--method", help="Embedding method (sentence_transformers, tfidf, simple_hash)")
|
|
1885
1874
|
def embed_text(text: str, method: str):
|
|
1886
|
-
"""Embed text using lightweight embedder"""
|
|
1875
|
+
"""Embed text using lightweight embedder."""
|
|
1887
1876
|
service = ModelService()
|
|
1888
1877
|
|
|
1889
1878
|
try:
|
|
@@ -1895,7 +1884,7 @@ def embed_text(text: str, method: str):
|
|
|
1895
1884
|
result = service.embedder.embed_text(text)
|
|
1896
1885
|
|
|
1897
1886
|
if result:
|
|
1898
|
-
click.echo(
|
|
1887
|
+
click.echo("✅ Text embedded successfully!")
|
|
1899
1888
|
click.echo(f"📊 Method: {result['method']}")
|
|
1900
1889
|
click.echo(f"📏 Dimensions: {result['dimensions']}")
|
|
1901
1890
|
click.echo(f"📝 Text length: {result['text_length']}")
|
|
@@ -1910,7 +1899,7 @@ def embed_text(text: str, method: str):
|
|
|
1910
1899
|
@click.argument("text")
|
|
1911
1900
|
@click.option("--chunk-size", default=1000, help="Chunk size for document embedding")
|
|
1912
1901
|
def embed_document(text: str, chunk_size: int):
|
|
1913
|
-
"""Embed document using lightweight embedder"""
|
|
1902
|
+
"""Embed document using lightweight embedder."""
|
|
1914
1903
|
service = ModelService()
|
|
1915
1904
|
|
|
1916
1905
|
try:
|
|
@@ -1919,7 +1908,7 @@ def embed_document(text: str, chunk_size: int):
|
|
|
1919
1908
|
|
|
1920
1909
|
if result.get("success"):
|
|
1921
1910
|
doc_embedding = result["document_embedding"]
|
|
1922
|
-
click.echo(
|
|
1911
|
+
click.echo("✅ Document embedded successfully!")
|
|
1923
1912
|
click.echo(f"📊 Method: {doc_embedding['method']}")
|
|
1924
1913
|
click.echo(f"📄 Total chunks: {doc_embedding['total_chunks']}")
|
|
1925
1914
|
click.echo(f"📏 Text length: {doc_embedding['total_text_length']}")
|
|
@@ -1932,7 +1921,7 @@ def embed_document(text: str, chunk_size: int):
|
|
|
1932
1921
|
|
|
1933
1922
|
@model_service.command()
|
|
1934
1923
|
def embedder_status():
|
|
1935
|
-
"""Show embedder status"""
|
|
1924
|
+
"""Show embedder status."""
|
|
1936
1925
|
service = ModelService()
|
|
1937
1926
|
|
|
1938
1927
|
try:
|