From d1a0dae9fb5ee02f2e08dca2fd1aba07746daf21 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Fri, 27 Jun 2025 16:31:23 -0700 Subject: [PATCH] fix: fixes to step feedback listing (#3080) --- letta/orm/sqlalchemy_base.py | 1 + letta/utils.py | 4 ++++ tests/test_managers.py | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/letta/orm/sqlalchemy_base.py b/letta/orm/sqlalchemy_base.py index af8a1077..368d5e30 100644 --- a/letta/orm/sqlalchemy_base.py +++ b/letta/orm/sqlalchemy_base.py @@ -243,6 +243,7 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base): join_conditions=join_conditions, identifier_keys=identifier_keys, identity_id=identity_id, + has_feedback=has_feedback, **kwargs, ) if query_options: diff --git a/letta/utils.py b/letta/utils.py index ef2306d6..6784a16e 100644 --- a/letta/utils.py +++ b/letta/utils.py @@ -531,6 +531,10 @@ def enforce_types(func): elif origin is list and isinstance(value, list): # Handle List[T] element_type = args[0] if args else None return all(isinstance(v, element_type) for v in value) if element_type else True + elif origin is not None and ( + str(origin).endswith("Literal") or getattr(origin, "_name", None) == "Literal" + ): # Handle Literal types + return value in args elif origin: # Handle other generics like Dict, Tuple, etc. return isinstance(value, origin) else: # Handle non-generic types diff --git a/tests/test_managers.py b/tests/test_managers.py index 862b6011..b809d169 100644 --- a/tests/test_managers.py +++ b/tests/test_managers.py @@ -87,6 +87,7 @@ from letta.server.db import db_registry from letta.server.server import SyncServer from letta.services.block_manager import BlockManager from letta.services.helpers.agent_manager_helper import calculate_base_tools +from letta.services.step_manager import FeedbackType from letta.settings import tool_settings from tests.helpers.utils import comprehensive_agent_checks, validate_context_window_overview from tests.utils import random_string @@ -6186,7 +6187,7 @@ async def test_job_usage_stats_add_multiple(server: SyncServer, sarah_agent, def step_manager = server.step_manager # Add feedback to first step - await step_manager.add_feedback_async(step_id=steps[0].id, feedback="positive", actor=default_user) + await step_manager.add_feedback_async(step_id=steps[0].id, feedback=FeedbackType.POSITIVE, actor=default_user) # Test has_feedback filtering steps_with_feedback = await step_manager.list_steps_async(agent_id=sarah_agent.id, has_feedback=True, actor=default_user)