From 06ecf8ede9b4eea0f676f4f18eaecbec6a3c4d3f Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Fri, 23 May 2025 18:07:04 -0700 Subject: [PATCH] feat (asyncify): async batch block creation for agent creation (#2397) --- letta/services/agent_manager.py | 2 +- letta/services/block_manager.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/letta/services/agent_manager.py b/letta/services/agent_manager.py index f4934c11..4ea48bcb 100644 --- a/letta/services/agent_manager.py +++ b/letta/services/agent_manager.py @@ -387,7 +387,7 @@ class AgentManager: block_ids = list(agent_create.block_ids or []) if agent_create.memory_blocks: pydantic_blocks = [PydanticBlock(**b.model_dump(to_orm=True)) for b in agent_create.memory_blocks] - created_blocks = self.block_manager.batch_create_blocks( + created_blocks = await self.block_manager.batch_create_blocks_async( pydantic_blocks, actor=actor, ) diff --git a/letta/services/block_manager.py b/letta/services/block_manager.py index 3a642ba1..571170fb 100644 --- a/letta/services/block_manager.py +++ b/letta/services/block_manager.py @@ -77,6 +77,30 @@ class BlockManager: # Convert back to Pydantic return [m.to_pydantic() for m in created_models] + @trace_method + @enforce_types + async def batch_create_blocks_async(self, blocks: List[PydanticBlock], actor: PydanticUser) -> List[PydanticBlock]: + """ + Batch-create multiple Blocks in one transaction for better performance. + Args: + blocks: List of PydanticBlock schemas to create + actor: The user performing the operation + Returns: + List of created PydanticBlock instances (with IDs, timestamps, etc.) + """ + if not blocks: + return [] + + async with db_registry.async_session() as session: + block_models = [ + BlockModel(**block.model_dump(to_orm=True, exclude_none=True), organization_id=actor.organization_id) for block in blocks + ] + + created_models = await BlockModel.batch_create_async(items=block_models, db_session=session, actor=actor) + + # Convert back to Pydantic + return [m.to_pydantic() for m in created_models] + @trace_method @enforce_types def update_block(self, block_id: str, block_update: BlockUpdate, actor: PydanticUser) -> PydanticBlock: