feat: routes for adding/linking new memory blocks to agents + unlinking blocks from agents (#2083)

This commit is contained in:
Charles Packer
2024-11-21 20:08:47 -08:00
committed by GitHub
parent 06744c9193
commit 507a60f71c
7 changed files with 364 additions and 8 deletions

View File

@@ -7,6 +7,7 @@ from fastapi.responses import JSONResponse, StreamingResponse
from letta.constants import DEFAULT_MESSAGE_TOOL, DEFAULT_MESSAGE_TOOL_KWARG
from letta.schemas.agent import AgentState, CreateAgent, UpdateAgentState
from letta.schemas.block import Block, BlockCreate, BlockLabelUpdate
from letta.schemas.enums import MessageStreamStatus
from letta.schemas.letta_message import (
LegacyLettaMessage,
@@ -217,7 +218,8 @@ def update_agent_memory(
):
"""
Update the core memory of a specific agent.
This endpoint accepts new memory contents (human and persona) and updates the core memory of the agent identified by the user ID and agent ID.
This endpoint accepts new memory contents to update the core memory of the agent.
This endpoint only supports modifying existing blocks; it does not support deleting/unlinking or creating/linking blocks.
"""
actor = server.get_user_or_default(user_id=user_id)
@@ -225,6 +227,66 @@ def update_agent_memory(
return memory
@router.patch("/{agent_id}/memory/label", response_model=Memory, operation_id="update_agent_memory_label")
def update_agent_memory_label(
agent_id: str,
update_label: BlockLabelUpdate = Body(...),
server: "SyncServer" = Depends(get_letta_server),
user_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
):
"""
Update the label of a block in an agent's memory.
"""
actor = server.get_user_or_default(user_id=user_id)
memory = server.update_agent_memory_label(
user_id=actor.id, agent_id=agent_id, current_block_label=update_label.current_label, new_block_label=update_label.new_label
)
return memory
@router.post("/{agent_id}/memory/block", response_model=Memory, operation_id="add_agent_memory_block")
def add_agent_memory_block(
agent_id: str,
create_block: BlockCreate = Body(...),
server: "SyncServer" = Depends(get_letta_server),
user_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
):
"""
Creates a memory block and links it to the agent.
"""
actor = server.get_user_or_default(user_id=user_id)
# Copied from POST /blocks
block_req = Block(**create_block.model_dump())
block = server.block_manager.create_or_update_block(actor=actor, block=block_req)
# Link the block to the agent
updated_memory = server.link_block_to_agent_memory(user_id=actor.id, agent_id=agent_id, block_id=block.id)
return updated_memory
@router.delete("/{agent_id}/memory/block/{block_label}", response_model=Memory, operation_id="remove_agent_memory_block")
def remove_agent_memory_block(
agent_id: str,
# TODO should this be block_id, or the label?
# I think label is OK since it's user-friendly + guaranteed to be unique within a Memory object
block_label: str,
server: "SyncServer" = Depends(get_letta_server),
user_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present
):
"""
Removes a memory block from an agent by unlnking it. If the block is not linked to any other agent, it is deleted.
"""
actor = server.get_user_or_default(user_id=user_id)
# Unlink the block from the agent
updated_memory = server.unlink_block_from_agent_memory(user_id=actor.id, agent_id=agent_id, block_label=block_label)
return updated_memory
@router.get("/{agent_id}/memory/recall", response_model=RecallMemorySummary, operation_id="get_agent_recall_memory_summary")
def get_agent_recall_memory_summary(
agent_id: str,