docs: update for manager funcs
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user