diff --git a/letta/functions/function_sets/multi_agent.py b/letta/functions/function_sets/multi_agent.py index 2bfdff03..100bf737 100644 --- a/letta/functions/function_sets/multi_agent.py +++ b/letta/functions/function_sets/multi_agent.py @@ -134,7 +134,7 @@ def send_message_to_agent_async(self: "Agent", message: str, other_agent_id: str Returns: str: A confirmation message indicating the message was successfully sent. """ - if settings.environment == "PRODUCTION": + if settings.environment == "prod": raise RuntimeError("This tool is not allowed to be run on Letta Cloud.") message = ( diff --git a/letta/otel/resource.py b/letta/otel/resource.py index 3932ca18..bcc8cd7e 100644 --- a/letta/otel/resource.py +++ b/letta/otel/resource.py @@ -14,27 +14,27 @@ def _normalize_environment_tag(env: str) -> str: """ Normalize environment value for OTEL deployment.environment tag. Maps internal environment values to abbreviated lowercase tags for Datadog. - + Examples: - PRODUCTION -> prod DEV -> dev - CANARY -> canary - LOCAL-TEST -> local-test + DEVELOPMENT -> dev + STAGING -> dev + prod -> prod (already normalized) + canary -> canary + local-test -> local-test """ if not env: return "unknown" - + env_upper = env.upper() - + # Map known values to abbreviated forms - if env_upper == "PRODUCTION": - return "prod" - elif env_upper == "DEV" or env_upper == "DEVELOPMENT": + if env_upper == "DEV" or env_upper == "DEVELOPMENT": return "dev" elif env_upper == "STAGING": return "dev" # Staging maps to dev else: - # For other values (canary, local-test, etc.), use lowercase as-is + # For other values (prod, canary, local-test, etc.), use lowercase as-is return env.lower() @@ -50,7 +50,7 @@ def get_resource(service_name: str) -> Resource: if _env: resource_dict["deployment.environment"] = _normalize_environment_tag(_env) # Only add device.id in non-production environments (for debugging) - if _env != "PRODUCTION": + if _env != "prod": resource_dict["device.id"] = uuid.getnode() # MAC address as unique device identifier, _resources[(service_name, _env)] = Resource.create(resource_dict) return _resources[(service_name, _env)] diff --git a/letta/services/helpers/agent_manager_helper.py b/letta/services/helpers/agent_manager_helper.py index 845d93ce..63fb7590 100644 --- a/letta/services/helpers/agent_manager_helper.py +++ b/letta/services/helpers/agent_manager_helper.py @@ -1298,7 +1298,7 @@ def calculate_base_tools(is_v2: bool) -> Set[str]: def calculate_multi_agent_tools() -> Set[str]: """Calculate multi-agent tools, excluding local-only tools in production environment.""" - if settings.environment == "PRODUCTION": + if settings.environment == "prod": return set(MULTI_AGENT_TOOLS) - set(LOCAL_ONLY_MULTI_AGENT_TOOLS) else: return set(MULTI_AGENT_TOOLS) diff --git a/letta/services/tool_executor/multi_agent_tool_executor.py b/letta/services/tool_executor/multi_agent_tool_executor.py index 2e6a3815..901e2022 100644 --- a/letta/services/tool_executor/multi_agent_tool_executor.py +++ b/letta/services/tool_executor/multi_agent_tool_executor.py @@ -127,7 +127,7 @@ class LettaMultiAgentToolExecutor(ToolExecutor): } async def send_message_to_agent_async(self, agent_state: AgentState, actor: User, message: str, other_agent_id: str) -> str: - if settings.environment == "PRODUCTION": + if settings.environment == "prod": raise RuntimeError("This tool is not allowed to be run on Letta Cloud.") # 1) Build the prefixed system‐message diff --git a/letta/services/tool_manager.py b/letta/services/tool_manager.py index 246f493b..de3ff428 100644 --- a/letta/services/tool_manager.py +++ b/letta/services/tool_manager.py @@ -638,7 +638,7 @@ class ToolManager: # TODO: This requires a deeper rethink about how we keep all our internal tools up-to-date if not after and upsert_base_tools: existing_tool_names = {tool.name for tool in tools} - base_tool_names = LETTA_TOOL_SET - set(LOCAL_ONLY_MULTI_AGENT_TOOLS) if settings.environment == "PRODUCTION" else LETTA_TOOL_SET + base_tool_names = LETTA_TOOL_SET - set(LOCAL_ONLY_MULTI_AGENT_TOOLS) if settings.environment == "prod" else LETTA_TOOL_SET missing_base_tools = base_tool_names - existing_tool_names # If any base tools are missing, upsert all base tools diff --git a/letta/settings.py b/letta/settings.py index ce096c8b..fbafb26d 100644 --- a/letta/settings.py +++ b/letta/settings.py @@ -235,7 +235,7 @@ class Settings(BaseSettings): cors_origins: Optional[list] = cors_origins environment: Optional[str] = Field( default=None, - description="Application environment (PRODUCTION, DEV, CANARY, etc. - normalized to lowercase for OTEL tags)", + description="Application environment (prod, dev, canary, etc. - lowercase values used for OTEL tags)", ) # SSE Streaming keepalive settings diff --git a/tests/managers/conftest.py b/tests/managers/conftest.py index 15e3f564..6e56cdcd 100644 --- a/tests/managers/conftest.py +++ b/tests/managers/conftest.py @@ -773,7 +773,7 @@ def dummy_successful_response() -> BetaMessageBatchIndividualResponse: # ====================================================================================================================== -@pytest.fixture(params=[None, "PRODUCTION"]) +@pytest.fixture(params=[None, "prod"]) def set_letta_environment(request, monkeypatch): """Parametrized fixture to test with different environment settings.""" from letta.settings import settings diff --git a/tests/managers/test_agent_manager.py b/tests/managers/test_agent_manager.py index 2584459a..733d7e76 100644 --- a/tests/managers/test_agent_manager.py +++ b/tests/managers/test_agent_manager.py @@ -256,7 +256,7 @@ async def test_calculate_multi_agent_tools(set_letta_environment): """Test that calculate_multi_agent_tools excludes local-only tools in production.""" result = calculate_multi_agent_tools() - if settings.environment == "PRODUCTION": + if settings.environment == "prod": # Production environment should exclude local-only tools expected_tools = set(MULTI_AGENT_TOOLS) - set(LOCAL_ONLY_MULTI_AGENT_TOOLS) assert result == expected_tools, "Production should exclude local-only multi-agent tools" @@ -283,7 +283,7 @@ async def test_upsert_base_tools_excludes_local_only_in_production(server: SyncS tools = await server.tool_manager.upsert_base_tools_async(actor=default_user) tool_names = {tool.name for tool in tools} - if settings.environment == "PRODUCTION": + if settings.environment == "prod": # Production environment should exclude local-only multi-agent tools for local_only_tool in LOCAL_ONLY_MULTI_AGENT_TOOLS: assert local_only_tool not in tool_names, f"Local-only tool '{local_only_tool}' should not be upserted in production" @@ -306,7 +306,7 @@ async def test_upsert_multi_agent_tools_only(server: SyncServer, default_user, s tools = await server.tool_manager.upsert_base_tools_async(actor=default_user, allowed_types={ToolType.LETTA_MULTI_AGENT_CORE}) tool_names = {tool.name for tool in tools} - if settings.environment == "PRODUCTION": + if settings.environment == "prod": # Should only have non-local multi-agent tools expected_tools = set(MULTI_AGENT_TOOLS) - set(LOCAL_ONLY_MULTI_AGENT_TOOLS) assert tool_names == expected_tools, "Production multi-agent upsert should exclude local-only tools" diff --git a/tests/managers/test_tool_manager.py b/tests/managers/test_tool_manager.py index 81e0c428..9861029e 100644 --- a/tests/managers/test_tool_manager.py +++ b/tests/managers/test_tool_manager.py @@ -1278,7 +1278,7 @@ async def test_upsert_base_tools(server: SyncServer, default_user): tools = await server.tool_manager.upsert_base_tools_async(actor=default_user) # Calculate expected tools accounting for production filtering - if settings.environment == "PRODUCTION": + if settings.environment == "prod": expected_tool_names = sorted(LETTA_TOOL_SET - set(LOCAL_ONLY_MULTI_AGENT_TOOLS)) else: expected_tool_names = sorted(LETTA_TOOL_SET) @@ -1330,7 +1330,7 @@ async def test_upsert_filtered_base_tools(server: SyncServer, default_user, tool tool_names = sorted([t.name for t in tools]) # Adjust expected names for multi-agent tools in production - if tool_type == ToolType.LETTA_MULTI_AGENT_CORE and settings.environment == "PRODUCTION": + if tool_type == ToolType.LETTA_MULTI_AGENT_CORE and settings.environment == "prod": expected_sorted = sorted(set(expected_names) - set(LOCAL_ONLY_MULTI_AGENT_TOOLS)) else: expected_sorted = sorted(expected_names)