docs: update for manager funcs

This commit is contained in:
Andy Li
2025-08-15 13:55:10 -07:00
committed by GitHub
parent 53230445fb
commit 49f7216a14
4 changed files with 199 additions and 6 deletions

View File

@@ -2007,6 +2007,26 @@ class AgentManager:
@enforce_types
@trace_method
async def refresh_file_blocks(self, agent_state: PydanticAgentState, actor: PydanticUser) -> PydanticAgentState:
"""
Refresh the file blocks in an agent's memory with current file content.
This method synchronizes the agent's in-memory file blocks with the actual
file content from attached sources. It respects the per-file view window
limit to prevent excessive memory usage.
Args:
agent_state: The current agent state containing memory configuration
actor: The user performing this action (for permission checking)
Returns:
Updated agent state with refreshed file blocks
Important:
- File blocks are truncated based on per_file_view_window_char_limit
- None values are filtered out (files that couldn't be loaded)
- This does NOT persist changes to the database, only updates the state object
- Call this before agent interactions if files may have changed externally
"""
file_blocks = await self.file_agent_manager.list_files_for_agent(
agent_id=agent_state.id,
per_file_view_window_char_limit=agent_state.per_file_view_window_char_limit,
@@ -2056,6 +2076,28 @@ class AgentManager:
@enforce_types
@trace_method
def append_system_message(self, agent_id: str, content: str, actor: PydanticUser):
"""
Append a system message to an agent's in-context message history.
This method is typically used during agent initialization to add system prompts,
instructions, or context that should be treated as system-level guidance.
Unlike user messages, system messages directly influence the agent's behavior
and understanding of its role.
Args:
agent_id: The ID of the agent to append the message to
content: The system message content (e.g., instructions, context, role definition)
actor: The user performing this action (for permission checking)
Side Effects:
- Creates a new Message object in the database
- Updates the agent's in_context_message_ids list
- The message becomes part of the agent's permanent context window
Note:
System messages consume tokens in the context window and cannot be
removed without rebuilding the agent's message history.
"""
# get the agent
agent = self.get_agent_by_id(agent_id=agent_id, actor=actor)
@@ -2069,6 +2111,15 @@ class AgentManager:
@enforce_types
@trace_method
async def append_system_message_async(self, agent_id: str, content: str, actor: PydanticUser):
"""
Async version of append_system_message.
Append a system message to an agent's in-context message history.
See append_system_message for detailed documentation.
This async version is preferred for high-throughput scenarios or when
called within other async operations to avoid blocking the event loop.
"""
# get the agent
agent = await self.get_agent_by_id_async(agent_id=agent_id, actor=actor)

View File

@@ -21,7 +21,26 @@ class ContextWindowCalculator:
@staticmethod
def extract_system_components(system_message: str) -> Tuple[str, str, str]:
"""Extract system prompt, core memory, and external memory summary from system message"""
"""
Extract structured components from a formatted system message.
Parses the system message to extract three distinct sections marked by XML-style tags:
- base_instructions: The core system prompt and agent instructions
- memory_blocks: The agent's core memory (persistent context)
- memory_metadata: Metadata about external memory systems
Args:
system_message: A formatted system message containing XML-style section markers
Returns:
A tuple of (system_prompt, core_memory, external_memory_summary)
Each component will be an empty string if its section is not found
Note:
This method assumes a specific format with sections delimited by:
<base_instructions>, <memory_blocks>, and <memory_metadata> tags.
The extraction is position-based and expects sections in this order.
"""
base_start = system_message.find("<base_instructions>")
memory_blocks_start = system_message.find("<memory_blocks>")
metadata_start = system_message.find("<memory_metadata>")
@@ -43,7 +62,26 @@ class ContextWindowCalculator:
@staticmethod
def extract_summary_memory(messages: List[Any]) -> Tuple[Optional[str], int]:
"""Extract summary memory if present and return starting index for real messages"""
"""
Extract summary memory from the message list if present.
Summary memory is a special message injected at position 1 (after system message)
that contains a condensed summary of previous conversation history. This is used
when the full conversation history doesn't fit in the context window.
Args:
messages: List of message objects to search for summary memory
Returns:
A tuple of (summary_text, start_index) where:
- summary_text: The extracted summary content, or None if not found
- start_index: Index where actual conversation messages begin (1 or 2)
Detection Logic:
Looks for a user message at index 1 containing the phrase
"The following is a summary of the previous" which indicates
it's a summarized conversation history rather than a real user message.
"""
if (
len(messages) > 1
and messages[1].role == MessageRole.user

View File

@@ -156,7 +156,25 @@ def _process_tags(agent: "AgentModel", tags: List[str], replace=True):
agent.tags.extend([tag for tag in new_tags if tag.tag not in existing_tags])
def derive_system_message(agent_type: AgentType, enable_sleeptime: Optional[bool] = None, system: Optional[str] = None):
def derive_system_message(agent_type: AgentType, enable_sleeptime: Optional[bool] = None, system: Optional[str] = None) -> str:
"""
Derive the appropriate system message based on agent type and configuration.
This function determines which system prompt template to use based on the
agent's type and whether sleeptime functionality is enabled. If a custom
system message is provided, it returns that instead.
Args:
agent_type: The type of agent (e.g., memgpt_agent, sleeptime_agent, react_agent)
enable_sleeptime: Whether sleeptime tools should be available (affects prompt choice)
system: Optional custom system message to use instead of defaults
Returns:
The system message string appropriate for the agent configuration
Raises:
ValueError: If an invalid or unsupported agent type is provided
"""
if system is None:
# TODO: don't hardcode
@@ -204,8 +222,33 @@ def compile_memory_metadata_block(
memory_edit_timestamp: datetime,
timezone: str,
previous_message_count: int = 0,
archival_memory_size: int = 0,
archival_memory_size: Optional[int] = 0,
) -> str:
"""
Generate a memory metadata block for the agent's system prompt.
This creates a structured metadata section that informs the agent about
the current state of its memory systems, including timing information
and memory counts. This helps the agent understand what information
is available through its tools.
Args:
memory_edit_timestamp: When memory blocks were last modified
timezone: The timezone to use for formatting timestamps (e.g., 'America/Los_Angeles')
previous_message_count: Number of messages in recall memory (conversation history)
archival_memory_size: Number of items in archival memory (long-term storage)
Returns:
A formatted string containing the memory metadata block with XML-style tags
Example Output:
<memory_metadata>
- The current time is: 2024-01-15 10:30 AM PST
- Memory blocks were last modified: 2024-01-15 09:00 AM PST
- 42 previous messages between you and the user are stored in recall memory (use tools to access them)
- 156 total memories you created are stored in archival memory (use tools to access them)
</memory_metadata>
"""
# Put the timestamp in the local timezone (mimicking get_local_time())
timestamp_str = format_datetime(memory_edit_timestamp, timezone)

View File

@@ -404,7 +404,37 @@ class ToolManager:
updated_tool_type: Optional[ToolType] = None,
bypass_name_check: bool = False,
) -> PydanticTool:
"""Update a tool by its ID with the given ToolUpdate object."""
"""
Update a tool with complex validation and schema derivation logic.
This method handles updates differently based on tool type:
- MCP tools: JSON schema is trusted, no Python source derivation
- Python/TypeScript tools: Schema derived from source code if provided
- Name conflicts are checked unless bypassed
Args:
tool_id: The UUID of the tool to update
tool_update: Partial update data (only changed fields)
actor: User performing the update (for permissions)
updated_tool_type: Optional new tool type (e.g., converting custom to builtin)
bypass_name_check: Skip name conflict validation (use with caution)
Returns:
Updated tool as Pydantic model
Raises:
LettaToolNameConflictError: If new name conflicts with existing tool
NoResultFound: If tool doesn't exist or user lacks access
Side Effects:
- Updates tool in database
- May change tool name if source code is modified
- Recomputes JSON schema from source for non-MCP tools
Important:
When source_code is provided for Python/TypeScript tools, the name
MUST match the function name in the code, overriding any name in json_schema
"""
# First, check if source code update would cause a name conflict
update_data = tool_update.model_dump(to_orm=True, exclude_none=True)
new_name = None
@@ -570,7 +600,38 @@ class ToolManager:
@enforce_types
@trace_method
def upsert_base_tools(self, actor: PydanticUser) -> List[PydanticTool]:
"""Add default tools in base.py and multi_agent.py"""
"""
Initialize or update all built-in Letta tools for a user.
This method scans predefined modules to discover and register all base tools
that ship with Letta. Tools are categorized by type (core, memory, multi-agent, etc.)
and tagged appropriately for filtering.
Args:
actor: The user to create/update tools for
Returns:
List of all base tools that were created or updated
Tool Categories Created:
- LETTA_CORE: Basic conversation tools (send_message)
- LETTA_MEMORY_CORE: Memory management (core_memory_append/replace)
- LETTA_MULTI_AGENT_CORE: Multi-agent communication tools
- LETTA_SLEEPTIME_CORE: Sleeptime agent tools
- LETTA_VOICE_SLEEPTIME_CORE: Voice agent specific tools
- LETTA_BUILTIN: Additional built-in utilities
- LETTA_FILES_CORE: File handling tools
Side Effects:
- Creates or updates tools in database
- Tools are marked with appropriate type and tags
- Existing custom tools with same names are NOT overwritten
Note:
This is typically called during user initialization or system upgrade
to ensure all base tools are available. Custom tools take precedence
over base tools with the same name.
"""
functions_to_schema = {}
for module_name in LETTA_TOOL_MODULE_NAMES: