Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
·
8dd46ff
1
Parent(s):
7953467
lefg
Browse files- app.py +5 -264
- src/managers/app_manager.py +126 -0
app.py
CHANGED
@@ -74,6 +74,8 @@ from src.managers.ai_manager import AI_Manager
|
|
74 |
|
75 |
from src.managers.session_manager import SessionManager
|
76 |
|
|
|
|
|
77 |
from src.routes.analytics_routes import router as analytics_router
|
78 |
|
79 |
from src.routes.blog_routes import router as blog_router
|
@@ -409,269 +411,7 @@ X_SESSION_ID = APIKeyHeader(name="X-Session-ID", auto_error=False)
|
|
409 |
|
410 |
# Update AppState class to use SessionManager
|
411 |
|
412 |
-
class
|
413 |
-
|
414 |
-
def __init__(self):
|
415 |
-
|
416 |
-
self._session_manager = SessionManager(styling_instructions, {}) # Empty dict, agents loaded from DB
|
417 |
-
|
418 |
-
self.model_config = DEFAULT_MODEL_CONFIG.copy()
|
419 |
-
|
420 |
-
# Update the SessionManager with the current model_config
|
421 |
-
|
422 |
-
self._session_manager._app_model_config = self.model_config
|
423 |
-
|
424 |
-
self.ai_manager = AI_Manager()
|
425 |
-
|
426 |
-
self.chat_name_agent = chat_history_name_agent
|
427 |
-
|
428 |
-
# Initialize deep analysis module
|
429 |
-
|
430 |
-
self.deep_analyzer = None
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
def get_session_state(self, session_id: str):
|
435 |
-
|
436 |
-
"""Get or create session-specific state using the SessionManager"""
|
437 |
-
|
438 |
-
return self._session_manager.get_session_state(session_id)
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
def clear_session_state(self, session_id: str):
|
443 |
-
|
444 |
-
"""Clear session-specific state using the SessionManager"""
|
445 |
-
|
446 |
-
self._session_manager.clear_session_state(session_id)
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
def update_session_dataset(self, session_id: str, datasets, names, desc, pre_generated=False):
|
451 |
-
"""Update dataset for a specific session using the SessionManager"""
|
452 |
-
|
453 |
-
self._session_manager.update_session_dataset(session_id, datasets, names, desc, pre_generated=pre_generated)
|
454 |
-
|
455 |
-
|
456 |
-
def reset_session_to_default(self, session_id: str):
|
457 |
-
|
458 |
-
"""Reset a session to use the default dataset using the SessionManager"""
|
459 |
-
|
460 |
-
self._session_manager.reset_session_to_default(session_id)
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
def set_session_user(self, session_id: str, user_id: int, chat_id: int = None):
|
465 |
-
|
466 |
-
"""Associate a user with a session using the SessionManager"""
|
467 |
-
|
468 |
-
return self._session_manager.set_session_user(session_id, user_id, chat_id)
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
def get_ai_manager(self):
|
473 |
-
|
474 |
-
"""Get the AI Manager instance"""
|
475 |
-
|
476 |
-
return self.ai_manager
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
def get_provider_for_model(self, model_name):
|
481 |
-
|
482 |
-
return self.ai_manager.get_provider_for_model(model_name)
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
def calculate_cost(self, model_name, input_tokens, output_tokens):
|
487 |
-
|
488 |
-
return self.ai_manager.calculate_cost(model_name, input_tokens, output_tokens)
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
def save_usage_to_db(self, user_id, chat_id, model_name, provider, prompt_tokens, completion_tokens, total_tokens, query_size, response_size, cost, request_time_ms, is_streaming=False):
|
493 |
-
|
494 |
-
return self.ai_manager.save_usage_to_db(user_id, chat_id, model_name, provider, prompt_tokens, completion_tokens, total_tokens, query_size, response_size, round(cost, 7), request_time_ms, is_streaming)
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
def get_tokenizer(self):
|
499 |
-
|
500 |
-
return self.ai_manager.tokenizer
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
def get_chat_history_name_agent(self):
|
505 |
-
|
506 |
-
return dspy.Predict(self.chat_name_agent)
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
def get_deep_analyzer(self, session_id: str):
|
511 |
-
|
512 |
-
"""Get or create deep analysis module for a session"""
|
513 |
-
|
514 |
-
session_state = self.get_session_state(session_id)
|
515 |
-
|
516 |
-
user_id = session_state.get("user_id")
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
# Check if we need to recreate the deep analyzer (user changed or doesn't exist)
|
521 |
-
|
522 |
-
current_analyzer = session_state.get('deep_analyzer')
|
523 |
-
|
524 |
-
analyzer_user_id = session_state.get('deep_analyzer_user_id')
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
logger.log_message(f"Deep analyzer check - session: {session_id}, current_user: {user_id}, analyzer_user: {analyzer_user_id}, has_analyzer: {current_analyzer is not None}", level=logging.INFO)
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
if (not current_analyzer or
|
533 |
-
|
534 |
-
analyzer_user_id != user_id or
|
535 |
-
|
536 |
-
not hasattr(session_state, 'deep_analyzer')):
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
logger.log_message(f"Creating/recreating deep analyzer for session {session_id}, user_id: {user_id} (reason: analyzer_exists={current_analyzer is not None}, user_match={analyzer_user_id == user_id})", level=logging.INFO)
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
# Load user-enabled agents from database using preference system
|
545 |
-
|
546 |
-
from src.db.init_db import session_factory
|
547 |
-
|
548 |
-
from src.agents.agents import load_user_enabled_templates_for_planner_from_db
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
db_session = session_factory()
|
553 |
-
|
554 |
-
try:
|
555 |
-
|
556 |
-
# Load user-enabled agents for planner (respects preferences)
|
557 |
-
|
558 |
-
if user_id:
|
559 |
-
|
560 |
-
enabled_agents_dict = load_user_enabled_templates_for_planner_from_db(user_id, db_session)
|
561 |
-
|
562 |
-
logger.log_message(f"Deep analyzer loaded {len(enabled_agents_dict)} enabled agents for user {user_id}: {list(enabled_agents_dict.keys())}", level=logging.INFO)
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
if not enabled_agents_dict:
|
567 |
-
|
568 |
-
logger.log_message(f"WARNING: No enabled agents found for user {user_id}, falling back to defaults", level=logging.WARNING)
|
569 |
-
|
570 |
-
# Fallback to default agents if no enabled agents
|
571 |
-
|
572 |
-
from src.agents.agents import preprocessing_agent, statistical_analytics_agent, sk_learn_agent, data_viz_agent
|
573 |
-
|
574 |
-
enabled_agents_dict = {
|
575 |
-
|
576 |
-
"preprocessing_agent": preprocessing_agent,
|
577 |
-
|
578 |
-
"statistical_analytics_agent": statistical_analytics_agent,
|
579 |
-
|
580 |
-
"sk_learn_agent": sk_learn_agent,
|
581 |
-
|
582 |
-
"data_viz_agent": data_viz_agent
|
583 |
-
|
584 |
-
}
|
585 |
-
|
586 |
-
else:
|
587 |
-
|
588 |
-
# Fallback to default agents if no user_id
|
589 |
-
|
590 |
-
logger.log_message("No user_id in session, loading default agents for deep analysis", level=logging.WARNING)
|
591 |
-
|
592 |
-
from src.agents.agents import preprocessing_agent, statistical_analytics_agent, sk_learn_agent, data_viz_agent
|
593 |
-
|
594 |
-
enabled_agents_dict = {
|
595 |
-
|
596 |
-
"preprocessing_agent": preprocessing_agent,
|
597 |
-
|
598 |
-
"statistical_analytics_agent": statistical_analytics_agent,
|
599 |
-
|
600 |
-
"sk_learn_agent": sk_learn_agent,
|
601 |
-
|
602 |
-
"data_viz_agent": data_viz_agent
|
603 |
-
|
604 |
-
}
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
# Create agents dictionary for deep analysis using enabled agents
|
609 |
-
|
610 |
-
deep_agents = {}
|
611 |
-
|
612 |
-
deep_agents_desc = {}
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
for agent_name, signature in enabled_agents_dict.items():
|
617 |
-
|
618 |
-
deep_agents[agent_name] = dspy.asyncify(dspy.ChainOfThought(signature))
|
619 |
-
|
620 |
-
# Get agent description from database
|
621 |
-
|
622 |
-
deep_agents_desc[agent_name] = get_agent_description(agent_name)
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
logger.log_message(f"Deep analyzer initialized with {len(deep_agents)} agents: {list(deep_agents.keys())}", level=logging.INFO)
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
except Exception as e:
|
631 |
-
|
632 |
-
logger.log_message(f"Error loading agents for deep analysis: {str(e)}", level=logging.ERROR)
|
633 |
-
|
634 |
-
# Fallback to minimal set
|
635 |
-
|
636 |
-
from src.agents.agents import preprocessing_agent, statistical_analytics_agent, sk_learn_agent, data_viz_agent
|
637 |
-
|
638 |
-
deep_agents = {
|
639 |
-
|
640 |
-
"preprocessing_agent": dspy.asyncify(dspy.Predict(preprocessing_agent)),
|
641 |
-
|
642 |
-
"statistical_analytics_agent": dspy.asyncify(dspy.Predict(statistical_analytics_agent)),
|
643 |
-
|
644 |
-
"sk_learn_agent": dspy.asyncify(dspy.Predict(sk_learn_agent)),
|
645 |
-
|
646 |
-
"data_viz_agent": dspy.asyncify(dspy.Predict(data_viz_agent))
|
647 |
-
|
648 |
-
}
|
649 |
-
|
650 |
-
deep_agents_desc = {name: get_agent_description(name) for name in deep_agents.keys()}
|
651 |
-
|
652 |
-
logger.log_message(f"Using fallback agents: {list(deep_agents.keys())}", level=logging.WARNING)
|
653 |
-
|
654 |
-
finally:
|
655 |
-
|
656 |
-
db_session.close()
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
session_state['deep_analyzer'] = deep_analysis_module(
|
661 |
-
agents=deep_agents,
|
662 |
-
agents_desc=deep_agents_desc
|
663 |
-
)
|
664 |
-
# Set datasets separately or pass them when needed
|
665 |
-
session_state['deep_analyzer'].datasets = session_state.get("datasets")
|
666 |
-
session_state['deep_analyzer_user_id'] = user_id # Track which user this analyzer was created for
|
667 |
-
|
668 |
-
else:
|
669 |
-
|
670 |
-
logger.log_message(f"Using existing deep analyzer for session {session_id}, user_id: {user_id}", level=logging.INFO)
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
return session_state['deep_analyzer']
|
675 |
|
676 |
|
677 |
|
@@ -679,7 +419,8 @@ class AppState:
|
|
679 |
|
680 |
app = FastAPI(title="AI Analytics API", version="1.0")
|
681 |
|
682 |
-
|
|
|
683 |
|
684 |
|
685 |
|
|
|
74 |
|
75 |
from src.managers.session_manager import SessionManager
|
76 |
|
77 |
+
from src.managers.app_manager import AppState
|
78 |
+
|
79 |
from src.routes.analytics_routes import router as analytics_router
|
80 |
|
81 |
from src.routes.blog_routes import router as blog_router
|
|
|
411 |
|
412 |
# Update AppState class to use SessionManager
|
413 |
|
414 |
+
# The AppState class is now in src.managers.app_manager
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
|
416 |
|
417 |
|
|
|
419 |
|
420 |
app = FastAPI(title="AI Analytics API", version="1.0")
|
421 |
|
422 |
+
# Pass required parameters to AppState
|
423 |
+
app.state = AppState(styling_instructions, chat_history_name_agent, DEFAULT_MODEL_CONFIG)
|
424 |
|
425 |
|
426 |
|
src/managers/app_manager.py
ADDED
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
import dspy
|
3 |
+
from src.managers.session_manager import SessionManager
|
4 |
+
from src.managers.ai_manager import AI_Manager
|
5 |
+
from src.utils.logger import Logger
|
6 |
+
|
7 |
+
logger = Logger()
|
8 |
+
|
9 |
+
class AppState:
|
10 |
+
def __init__(self, styling_instructions, chat_history_name_agent, default_model_config):
|
11 |
+
self._session_manager = SessionManager(styling_instructions, {}) # Empty dict, agents loaded from DB
|
12 |
+
self.model_config = default_model_config.copy()
|
13 |
+
|
14 |
+
# Update the SessionManager with the current model_config
|
15 |
+
self._session_manager._app_model_config = self.model_config
|
16 |
+
|
17 |
+
self.ai_manager = AI_Manager()
|
18 |
+
self.chat_name_agent = chat_history_name_agent
|
19 |
+
|
20 |
+
# Initialize deep analysis module
|
21 |
+
self.deep_analyzer = None
|
22 |
+
|
23 |
+
def get_session_state(self, session_id: str):
|
24 |
+
"""Get or create session-specific state using the SessionManager"""
|
25 |
+
return self._session_manager.get_session_state(session_id)
|
26 |
+
|
27 |
+
def clear_session_state(self, session_id: str):
|
28 |
+
"""Clear session-specific state using the SessionManager"""
|
29 |
+
self._session_manager.clear_session_state(session_id)
|
30 |
+
|
31 |
+
def update_session_dataset(self, session_id: str, datasets, names, desc, pre_generated=False):
|
32 |
+
"""Update dataset for a specific session using the SessionManager"""
|
33 |
+
self._session_manager.update_session_dataset(session_id, datasets, names, desc, pre_generated=pre_generated)
|
34 |
+
|
35 |
+
def reset_session_to_default(self, session_id: str):
|
36 |
+
"""Reset a session to use the default dataset using the SessionManager"""
|
37 |
+
self._session_manager.reset_session_to_default(session_id)
|
38 |
+
|
39 |
+
def set_session_user(self, session_id: str, user_id: int, chat_id: int = None):
|
40 |
+
"""Associate a user with a session using the SessionManager"""
|
41 |
+
return self._session_manager.set_session_user(session_id, user_id, chat_id)
|
42 |
+
|
43 |
+
def get_ai_manager(self):
|
44 |
+
"""Get the AI Manager instance"""
|
45 |
+
return self.ai_manager
|
46 |
+
|
47 |
+
def get_provider_for_model(self, model_name):
|
48 |
+
return self.ai_manager.get_provider_for_model(model_name)
|
49 |
+
|
50 |
+
def calculate_cost(self, model_name, input_tokens, output_tokens):
|
51 |
+
return self.ai_manager.calculate_cost(model_name, input_tokens, output_tokens)
|
52 |
+
|
53 |
+
def save_usage_to_db(self, user_id, chat_id, model_name, provider, prompt_tokens, completion_tokens, total_tokens, query_size, response_size, cost, request_time_ms, is_streaming=False):
|
54 |
+
return self.ai_manager.save_usage_to_db(user_id, chat_id, model_name, provider, prompt_tokens, completion_tokens, total_tokens, query_size, response_size, round(cost, 7), request_time_ms, is_streaming)
|
55 |
+
|
56 |
+
def get_tokenizer(self):
|
57 |
+
return self.ai_manager.tokenizer
|
58 |
+
|
59 |
+
def get_chat_history_name_agent(self):
|
60 |
+
return dspy.Predict(self.chat_name_agent)
|
61 |
+
|
62 |
+
def get_deep_analyzer(self, session_id: str):
|
63 |
+
"""Get or create deep analysis module for a session"""
|
64 |
+
session_state = self.get_session_state(session_id)
|
65 |
+
user_id = session_state.get("user_id")
|
66 |
+
|
67 |
+
# Check if we need to recreate the deep analyzer (user changed or doesn't exist)
|
68 |
+
current_analyzer = session_state.get('deep_analyzer')
|
69 |
+
analyzer_user_id = session_state.get('deep_analyzer_user_id')
|
70 |
+
|
71 |
+
logger.log_message(f"Deep analyzer check - session: {session_id}, current_user: {user_id}, analyzer_user: {analyzer_user_id}, has_analyzer: {current_analyzer is not None}", level=logging.INFO)
|
72 |
+
|
73 |
+
if (not current_analyzer or
|
74 |
+
analyzer_user_id != user_id or
|
75 |
+
not hasattr(session_state, 'deep_analyzer')):
|
76 |
+
|
77 |
+
logger.log_message(f"Creating/recreating deep analyzer for session {session_id}, user_id: {user_id} (reason: analyzer_exists={current_analyzer is not None}, user_match={analyzer_user_id == user_id})", level=logging.INFO)
|
78 |
+
|
79 |
+
# Load user-enabled agents from database using preference system
|
80 |
+
from src.db.init_db import session_factory
|
81 |
+
from src.agents.agents import load_user_enabled_templates_for_planner_from_db
|
82 |
+
|
83 |
+
db_session = session_factory()
|
84 |
+
try:
|
85 |
+
# Load user-enabled agents for planner (respects preferences)
|
86 |
+
if user_id:
|
87 |
+
enabled_agents_dict = load_user_enabled_templates_for_planner_from_db(user_id, db_session)
|
88 |
+
else:
|
89 |
+
enabled_agents_dict = {}
|
90 |
+
|
91 |
+
if not enabled_agents_dict:
|
92 |
+
# Fallback to default agents if no user preferences
|
93 |
+
enabled_agents_dict = {
|
94 |
+
"preprocessing_agent": "preprocessing_agent",
|
95 |
+
"statistical_analytics_agent": "statistical_analytics_agent",
|
96 |
+
"sk_learn_agent": "sk_learn_agent",
|
97 |
+
"data_viz_agent": "data_viz_agent"
|
98 |
+
}
|
99 |
+
|
100 |
+
# Import deep analysis module
|
101 |
+
from src.agents.deep_agents import deep_analysis_module, get_agent_description
|
102 |
+
|
103 |
+
deep_agents = {}
|
104 |
+
deep_agents_desc = {}
|
105 |
+
|
106 |
+
for agent_name, signature in enabled_agents_dict.items():
|
107 |
+
deep_agents[agent_name] = signature
|
108 |
+
deep_agents_desc[agent_name] = get_agent_description(agent_name)
|
109 |
+
|
110 |
+
logger.log_message(f"Deep analyzer initialized with {len(deep_agents)} agents: {list(deep_agents.keys())}", level=logging.INFO)
|
111 |
+
|
112 |
+
finally:
|
113 |
+
db_session.close()
|
114 |
+
|
115 |
+
session_state['deep_analyzer'] = deep_analysis_module(
|
116 |
+
agents=deep_agents,
|
117 |
+
agents_desc=deep_agents_desc
|
118 |
+
)
|
119 |
+
# Set datasets separately or pass them when needed
|
120 |
+
session_state['deep_analyzer'].datasets = session_state.get("datasets")
|
121 |
+
session_state['deep_analyzer_user_id'] = user_id # Track which user this analyzer was created for
|
122 |
+
|
123 |
+
else:
|
124 |
+
logger.log_message(f"Using existing deep analyzer for session {session_id}, user_id: {user_id}", level=logging.INFO)
|
125 |
+
|
126 |
+
return session_state['deep_analyzer']
|