diff --git a/letta/services/job_manager.py b/letta/services/job_manager.py index aaa17f74..60afcfd1 100644 --- a/letta/services/job_manager.py +++ b/letta/services/job_manager.py @@ -1,4 +1,3 @@ -from datetime import datetime from functools import partial, reduce from operator import add from typing import List, Literal, Optional, Union @@ -28,7 +27,6 @@ from letta.schemas.step import Step as PydanticStep from letta.schemas.usage import LettaUsageStatistics from letta.schemas.user import User as PydanticUser from letta.server.db import db_registry -from letta.settings import DatabaseChoice, settings from letta.utils import enforce_types logger = get_logger(__name__) @@ -337,11 +335,7 @@ class JobManager: conditions = [] if before_obj: # records before this cursor (older) - before_timestamp = before_obj.created_at - # SQLite does not support as granular timestamping, so we need to round the timestamp - if settings.database_engine is DatabaseChoice.SQLITE and isinstance(before_timestamp, datetime): - before_timestamp = before_timestamp.strftime("%Y-%m-%d %H:%M:%S") conditions.append( or_( @@ -353,9 +347,6 @@ class JobManager: if after_obj: # records after this cursor (newer) after_timestamp = after_obj.created_at - # SQLite does not support as granular timestamping, so we need to round the timestamp - if settings.database_engine is DatabaseChoice.SQLITE and isinstance(after_timestamp, datetime): - after_timestamp = after_timestamp.strftime("%Y-%m-%d %H:%M:%S") conditions.append( or_(JobModel.created_at > after_timestamp, and_(JobModel.created_at == after_timestamp, JobModel.id > after_obj.id)) diff --git a/tests/configs/embedding_model_configs/letta-hosted.json b/tests/configs/embedding_model_configs/letta-hosted.json index d0e53cae..502d52ab 100644 --- a/tests/configs/embedding_model_configs/letta-hosted.json +++ b/tests/configs/embedding_model_configs/letta-hosted.json @@ -1,7 +1,7 @@ { "embedding_endpoint": "https://embeddings.letta.com", - "embedding_model": "BAAI/bge-large-en-v1.5", + "embedding_model": "letta-free", "embedding_dim": 1536, "embedding_chunk_size": 300, - "embedding_endpoint_type": "hugging-face" + "embedding_endpoint_type": "openai" } diff --git a/tests/test_agent_serialization.py b/tests/test_agent_serialization.py index 7ea29ea5..c5272bcb 100644 --- a/tests/test_agent_serialization.py +++ b/tests/test_agent_serialization.py @@ -625,6 +625,7 @@ def test_agent_download_upload_flow(server, server_url, serialize_test_agent, de response = requests.get( f"{server_url}/v1/agents/{agent_id}/export", headers={"user_id": default_user.id}, + params={"use_legacy_format": True}, ) assert response.status_code == 200, f"Download failed: {response.text}" diff --git a/tests/test_agent_serialization_v2.py b/tests/test_agent_serialization_v2.py index f0cc7304..7f6b1054 100644 --- a/tests/test_agent_serialization_v2.py +++ b/tests/test_agent_serialization_v2.py @@ -205,7 +205,7 @@ def test_agent(server: SyncServer, default_user, default_organization, test_bloc yield agent_state -@pytest.fixture +@pytest.fixture(scope="function") async def test_source(server: SyncServer, default_user): """Fixture to create and return a test source.""" source_data = Source( @@ -217,7 +217,7 @@ async def test_source(server: SyncServer, default_user): yield source -@pytest.fixture +@pytest.fixture(scope="function") async def test_file(server: SyncServer, default_user, test_source): """Fixture to create and return a test file attached to test_source.""" from letta.schemas.file import FileMetadata @@ -233,7 +233,7 @@ async def test_file(server: SyncServer, default_user, test_source): yield file_metadata -@pytest.fixture +@pytest.fixture(scope="function") async def agent_with_files(server: SyncServer, default_user, test_block, weather_tool, test_source, test_file): """Fixture to create and return an agent with attached files.""" memory_blocks = [ @@ -274,7 +274,7 @@ async def agent_with_files(server: SyncServer, default_user, test_block, weather return (agent_state.id, test_source.id, test_file.id) -@pytest.fixture +@pytest.fixture(scope="function") async def test_mcp_server(server: SyncServer, default_user): """Fixture to create and return a test MCP server.""" from letta.schemas.mcp import MCPServer, MCPServerType @@ -290,7 +290,7 @@ async def test_mcp_server(server: SyncServer, default_user): yield mcp_server -@pytest.fixture +@pytest.fixture(scope="function") async def mcp_tool(server: SyncServer, default_user, test_mcp_server): """Fixture to create and return an MCP tool.""" from letta.schemas.tool import MCPTool, ToolCreate @@ -308,7 +308,7 @@ async def mcp_tool(server: SyncServer, default_user, test_mcp_server): yield mcp_tool -@pytest.fixture +@pytest.fixture(scope="function") async def agent_with_mcp_tools(server: SyncServer, default_user, test_block, mcp_tool, test_mcp_server): """Fixture to create and return an agent with MCP tools.""" memory_blocks = [ @@ -732,7 +732,7 @@ def validate_id_format(schema: AgentFileSchema) -> bool: class TestFileExport: """Test file export functionality with comprehensive validation""" - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_basic_file_export(self, default_user, agent_serialization_manager, agent_with_files): """Test basic file export functionality""" agent_id, source_id, file_id = agent_with_files @@ -755,7 +755,7 @@ class TestFileExport: assert file_agent.file_id == exported.files[0].id assert file_agent.source_id == exported.sources[0].id - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_multiple_files_per_source(self, server, default_user, agent_serialization_manager): """Test export with multiple files from the same source""" source = await create_test_source(server, "multi-file-source", default_user) @@ -782,7 +782,7 @@ class TestFileExport: assert file_agent.file_id in file_ids assert file_agent.source_id == source_id - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_multiple_sources_export(self, server, default_user, agent_serialization_manager): """Test export with files from multiple sources""" source1 = await create_test_source(server, "source-1", default_user) @@ -804,7 +804,7 @@ class TestFileExport: for file_schema in exported.files: assert file_schema.source_id in source_ids - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_cross_agent_file_deduplication(self, server, default_user, agent_serialization_manager): """Test that files shared across agents are deduplicated in export""" source = await create_test_source(server, "shared-source", default_user) @@ -828,7 +828,7 @@ class TestFileExport: assert file_agent.file_id == file_id assert file_agent.source_id == source_id - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_file_agent_relationship_preservation(self, server, default_user, agent_serialization_manager): """Test that file-agent relationship details are preserved""" source = await create_test_source(server, "test-source", default_user) @@ -845,7 +845,7 @@ class TestFileExport: assert file_agent.is_open is True assert hasattr(file_agent, "last_accessed_at") - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_id_remapping_consistency(self, server, default_user, agent_serialization_manager): """Test that ID remapping is consistent across all references""" source = await create_test_source(server, "consistency-source", default_user) @@ -864,7 +864,7 @@ class TestFileExport: assert file_agent.file_id == file_schema.id assert file_agent.source_id == source_schema.id - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_empty_file_relationships(self, server, default_user, agent_serialization_manager): """Test export of agent with no file relationships""" agent_create = CreateAgent( @@ -883,7 +883,7 @@ class TestFileExport: agent_schema = exported.agents[0] assert len(agent_schema.files_agents) == 0 - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_file_content_inclusion_in_export(self, default_user, agent_serialization_manager, agent_with_files): """Test that file content is included in export""" agent_id, source_id, file_id = agent_with_files @@ -992,7 +992,7 @@ class TestAgentFileExport: with pytest.raises(AgentFileExportError): # Should raise AgentFileExportError for non-existent agent await agent_serialization_manager.export(["non-existent-id"], default_user) - @pytest.mark.asyncio(loop_scope="session") + @pytest.mark.asyncio async def test_revision_id_automatic_setting(self, agent_serialization_manager, test_agent, default_user): """Test that revision_id is automatically set to the latest alembic revision.""" agent_file = await agent_serialization_manager.export([test_agent.id], default_user)