diff --git a/agents/generic_agent.py b/agents/generic_agent.py index 6bd3fb1..853b6f3 100644 --- a/agents/generic_agent.py +++ b/agents/generic_agent.py @@ -41,6 +41,8 @@ async def ainvoke(self, state: dict) -> dict: log_student(f"AGENT DISABLED: skipping") return {"response": "", "_skipped": True} + tracker = agent_config.create_tracker() + try: # Create model from config model = create_model_for_config( @@ -83,19 +85,19 @@ async def ainvoke(self, state: dict) -> dict: # Track metrics duration_ms = int((time.time() - start_time) * 1000) - agent_config.tracker.track_duration(duration_ms) - agent_config.tracker.track_success() + tracker.track_duration(duration_ms) + tracker.track_success() log_student(f"DURATION: {duration_ms}ms") if "_token_usage" in result and result["_token_usage"]["total"] > 0: - agent_config.tracker.track_tokens(TokenUsage(**result["_token_usage"])) + tracker.track_tokens(TokenUsage(**result["_token_usage"])) return result except Exception as e: log_student(f"AGENT ERROR: {e}") - agent_config.tracker.track_error() + tracker.track_error() return { "response": f"Error: {e}", "_error": str(e) diff --git a/agents/ld_agent_helpers.py b/agents/ld_agent_helpers.py index 2785ade..83fcda8 100644 --- a/agents/ld_agent_helpers.py +++ b/agents/ld_agent_helpers.py @@ -239,7 +239,7 @@ async def create_agent_with_fresh_config( prompt=config.instructions ) - return agent, config.tracker, False, recursion_limit + return agent, config.create_tracker(), False, recursion_limit except Exception as e: log_student(f"ERROR creating agent: {e}") @@ -284,8 +284,8 @@ async def ainvoke(self, request_data: dict) -> dict: # Use graph node tracker if available active_tracker = ( - graph_node_config.tracker - if graph_node_config and hasattr(graph_node_config, 'tracker') + graph_node_config.create_tracker() + if graph_node_config else tracker ) diff --git a/api/main.py b/api/main.py index 889f528..e88e8c9 100644 --- a/api/main.py +++ b/api/main.py @@ -94,7 +94,7 @@ async def submit_feedback(feedback: FeedbackRequest): # Track feedback using config_manager success = agent_service.config_manager.track_feedback( - support_config.tracker, + support_config.create_tracker(), thumbs_up=thumbs_up ) diff --git a/api/services/agent_service.py b/api/services/agent_service.py index c133e53..9e1a255 100644 --- a/api/services/agent_service.py +++ b/api/services/agent_service.py @@ -201,8 +201,10 @@ def _update_context(self, node_key: str, config, result: dict, ctx: dict): # Get variation key var_key = "default" - if hasattr(config, 'tracker') and hasattr(config.tracker, '_variation_key'): - var_key = config.tracker._variation_key + if config: + cfg_tracker = config.create_tracker() + if hasattr(cfg_tracker, '_variation_key'): + var_key = cfg_tracker._variation_key # Record agent config - fully generic, include all result fields agent_info = { @@ -226,7 +228,7 @@ def _track_duration(self, graph_tracker, graph_key: str, config, duration_ms: in if not hasattr(graph_tracker, '_ld_client'): return - tracker = config.tracker + tracker = config.create_tracker() track_data = { 'graphKey': graph_key, 'configKey': getattr(tracker, '_config_key', 'unknown'), diff --git a/config_manager.py b/config_manager.py index 1559bd0..1ef3089 100644 --- a/config_manager.py +++ b/config_manager.py @@ -7,7 +7,7 @@ from pathlib import Path import ldclient from ldclient import Context -from ldai.client import LDAIClient, AIAgentConfigDefault, ModelConfig, ProviderConfig +from ldai import LDAIClient, AIAgentConfigDefault, ModelConfig, ProviderConfig from ldai.tracker import FeedbackKind from dotenv import load_dotenv from utils.logger import log_student, log_debug @@ -207,8 +207,9 @@ async def get_config(self, user_id: str, config_key: str = None, user_context: d try: config_dict = result.to_dict() log_debug(f"CONFIG MANAGER: Model: {config_dict.get('model', {}).get('name', 'unknown')}") - if hasattr(result, 'tracker') and hasattr(result.tracker, '_variation_key'): - log_debug(f"CONFIG MANAGER: Variation: {result.tracker._variation_key}") + debug_tracker = result.create_tracker() + if hasattr(debug_tracker, '_variation_key'): + log_debug(f"CONFIG MANAGER: Variation: {debug_tracker._variation_key}") except Exception as debug_e: log_debug(f"CONFIG MANAGER: Could not debug result: {debug_e}") @@ -219,6 +220,18 @@ def flush(self): """Flush metrics and clear SDK cache""" self.ld_client.flush() + def clear_cache(self): + """Clear any cached configs (no-op for now, configs fetched live)""" + pass + + def get_agent_graph(self, user_id: str, graph_key: str, user_context: dict = None): + """Get LaunchDarkly Agent Graph definition.""" + log_debug(f"CONFIG MANAGER: Getting agent graph '{graph_key}' for user_id={user_id}") + ld_context = self.build_context(user_id, user_context) + graph = self.ai_client.agent_graph(graph_key, ld_context) + log_debug(f"CONFIG MANAGER: Got agent graph '{graph_key}'") + return graph + def track_feedback(self, tracker, thumbs_up: bool): """Track user feedback with LaunchDarkly""" if not tracker: diff --git a/pyproject.toml b/pyproject.toml index b0cccc0..85122d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,9 +12,8 @@ dependencies = [ "fastapi>=0.115.0", "uvicorn[standard]>=0.32.0", "pydantic>=2.10.0", - # LaunchDarkly (using currently available versions; update to >=10.0.0 / >=1.0.0 at GA) "launchdarkly-server-sdk>=9.0.0", - "launchdarkly-server-sdk-ai>=0.10.0", + "launchdarkly-server-sdk-ai>=0.20.0", # AWS Bedrock Integration "langchain-aws>=0.2.0", "boto3>=1.35.0", @@ -53,6 +52,3 @@ dev = [ [tool.setuptools] packages = ["api", "agents"] - -[tool.uv.sources] -launchdarkly-server-sdk-ai = { git = "https://github.com/launchdarkly/python-server-sdk-ai", subdirectory = "packages/sdk/server-ai", rev = "main" }