From d28140561f5f34b3fe78607eb2929414b4dbb769 Mon Sep 17 00:00:00 2001 From: Caren Thomas Date: Thu, 19 Dec 2024 12:12:32 -0800 Subject: [PATCH] rename to reasoning --- examples/helper.py | 2 ++ letta/client/streaming.py | 6 +++--- letta/schemas/letta_message.py | 28 +++++++++++++++++++++------- letta/schemas/letta_response.py | 2 ++ letta/schemas/message.py | 6 +++--- letta/server/rest_api/interface.py | 20 ++++++++++---------- tests/helpers/endpoints_helper.py | 4 ++-- tests/test_client_legacy.py | 6 +++--- tests/test_server.py | 6 +++--- 9 files changed, 49 insertions(+), 31 deletions(-) diff --git a/examples/helper.py b/examples/helper.py index f19e8ffb13..18b60cc446 100644 --- a/examples/helper.py +++ b/examples/helper.py @@ -95,6 +95,8 @@ def nb_print(messages): def get_formatted_content(msg): if msg.message_type == "internal_monologue": return f'
{html.escape(msg.internal_monologue)}
' + elif msg.message_type == "reasoning_message": + return f'
{html.escape(msg.reasoning)}
' elif msg.message_type == "function_call": args = format_json(msg.function_call.arguments) return f'
{html.escape(msg.function_call.name)}({args})
' diff --git a/letta/client/streaming.py b/letta/client/streaming.py index 9f57352b73..4a258cdc7a 100644 --- a/letta/client/streaming.py +++ b/letta/client/streaming.py @@ -10,7 +10,7 @@ from letta.schemas.letta_message import ( ToolCallMessage, ToolReturnMessage, - InternalMonologue, + ReasoningMessage, ) from letta.schemas.letta_response import LettaStreamingResponse from letta.schemas.usage import LettaUsageStatistics @@ -53,8 +53,8 @@ def _sse_post(url: str, data: dict, headers: dict) -> Generator[LettaStreamingRe yield MessageStreamStatus(sse.data) else: chunk_data = json.loads(sse.data) - if "internal_monologue" in chunk_data: - yield InternalMonologue(**chunk_data) + if "reasoning" in chunk_data: + yield ReasoningMessage(**chunk_data) elif "tool_call" in chunk_data: yield ToolCallMessage(**chunk_data) elif "tool_return" in chunk_data: diff --git a/letta/schemas/letta_message.py b/letta/schemas/letta_message.py index 424a003844..45fcf36180 100644 --- a/letta/schemas/letta_message.py +++ b/letta/schemas/letta_message.py @@ -60,18 +60,18 @@ class UserMessage(LettaMessage): message: str -class InternalMonologue(LettaMessage): +class ReasoningMessage(LettaMessage): """ - Representation of an agent's internal monologue. + Representation of an agent's internal reasoning. Attributes: - internal_monologue (str): The internal monologue of the agent + reasoning (str): The internal reasoning of the agent id (str): The ID of the message date (datetime): The date the message was created in ISO format """ - message_type: Literal["internal_monologue"] = "internal_monologue" - internal_monologue: str + message_type: Literal["reasoning_message"] = "reasoning_message" + reasoning: str class ToolCall(BaseModel): @@ -196,10 +196,24 @@ class LegacyFunctionReturn(LettaMessage): stderr: Optional[List[str]] = None -LegacyLettaMessage = Union[InternalMonologue, AssistantMessage, LegacyFunctionCallMessage, LegacyFunctionReturn] +class LegacyInternalMonologue(LettaMessage): + """ + Representation of an agent's internal monologue. + + Attributes: + internal_monologue (str): The internal monologue of the agent + id (str): The ID of the message + date (datetime): The date the message was created in ISO format + """ + + message_type: Literal["internal_monologue"] = "internal_monologue" + internal_monologue: str + + +LegacyLettaMessage = Union[LegacyInternalMonologue, AssistantMessage, LegacyFunctionCallMessage, LegacyFunctionReturn] LettaMessageUnion = Annotated[ - Union[SystemMessage, UserMessage, InternalMonologue, ToolCallMessage, ToolReturnMessage, AssistantMessage], + Union[SystemMessage, UserMessage, ReasoningMessage, ToolCallMessage, ToolReturnMessage, AssistantMessage], Field(discriminator="message_type"), ] diff --git a/letta/schemas/letta_response.py b/letta/schemas/letta_response.py index 990a55cb15..c6a1e8be58 100644 --- a/letta/schemas/letta_response.py +++ b/letta/schemas/letta_response.py @@ -40,6 +40,8 @@ def _repr_html_(self): def get_formatted_content(msg): if msg.message_type == "internal_monologue": return f'
{html.escape(msg.internal_monologue)}
' + if msg.message_type == "reasoning_message": + return f'
{html.escape(msg.reasoning)}
' elif msg.message_type == "function_call": args = format_json(msg.function_call.arguments) return f'
{html.escape(msg.function_call.name)}({args})
' diff --git a/letta/schemas/message.py b/letta/schemas/message.py index b548ec256a..74bb813567 100644 --- a/letta/schemas/message.py +++ b/letta/schemas/message.py @@ -19,7 +19,7 @@ ToolCall as LettaToolCall, ToolCallMessage, ToolReturnMessage, - InternalMonologue, + ReasoningMessage, LettaMessage, SystemMessage, UserMessage, @@ -145,10 +145,10 @@ def to_letta_message( if self.text is not None: # This is type InnerThoughts messages.append( - InternalMonologue( + ReasoningMessage( id=self.id, date=self.created_at, - internal_monologue=self.text, + reasoning=self.text, ) ) if self.tool_calls is not None: diff --git a/letta/server/rest_api/interface.py b/letta/server/rest_api/interface.py index 85248ec3bb..b3d344798b 100644 --- a/letta/server/rest_api/interface.py +++ b/letta/server/rest_api/interface.py @@ -16,7 +16,7 @@ ToolCallDelta, ToolCallMessage, ToolReturnMessage, - InternalMonologue, + ReasoningMessage, LegacyFunctionCallMessage, LegacyLettaMessage, LettaMessage, @@ -411,7 +411,7 @@ def clear(): def _process_chunk_to_letta_style( self, chunk: ChatCompletionChunkResponse, message_id: str, message_date: datetime - ) -> Optional[Union[InternalMonologue, ToolCallMessage, AssistantMessage]]: + ) -> Optional[Union[ReasoningMessage, ToolCallMessage, AssistantMessage]]: """ Example data from non-streaming response looks like: @@ -426,10 +426,10 @@ def _process_chunk_to_letta_style( # inner thoughts if message_delta.content is not None: - processed_chunk = InternalMonologue( + processed_chunk = ReasoningMessage( id=message_id, date=message_date, - internal_monologue=message_delta.content, + reasoning=message_delta.content, ) # tool calls @@ -518,10 +518,10 @@ def _process_chunk_to_letta_style( # If we have inner thoughts, we should output them as a chunk if updates_inner_thoughts: - processed_chunk = InternalMonologue( + processed_chunk = ReasoningMessage( id=message_id, date=message_date, - internal_monologue=updates_inner_thoughts, + reasoning=updates_inner_thoughts, ) # Additionally inner thoughts may stream back with a chunk of main JSON # In that case, since we can only return a chunk at a time, we should buffer it @@ -680,13 +680,13 @@ def _process_chunk_to_letta_style( # Once we get a complete key, check if the key matches # If it does match, start processing the value (stringified-JSON string - # And with each new chunk, output it as a chunk of type InternalMonologue + # And with each new chunk, output it as a chunk of type ReasoningMessage # If the key doesn't match, then flush the buffer as a single ToolCallMessage chunk # If we're reading a value - # If we're reading the inner thoughts value, we output chunks of type InternalMonologue + # If we're reading the inner thoughts value, we output chunks of type ReasoningMessage # Otherwise, do simple chunks of ToolCallMessage @@ -823,10 +823,10 @@ def internal_monologue(self, msg: str, msg_obj: Optional[Message] = None): # "id": str(msg_obj.id) if msg_obj is not None else None, # } assert msg_obj is not None, "Internal monologue requires msg_obj references for metadata" - processed_chunk = InternalMonologue( + processed_chunk = ReasoningMessage( id=msg_obj.id, date=msg_obj.created_at, - internal_monologue=msg, + reasoning=msg, ) self._push_to_buffer(processed_chunk) diff --git a/tests/helpers/endpoints_helper.py b/tests/helpers/endpoints_helper.py index a526f2315b..c267a4bd1f 100644 --- a/tests/helpers/endpoints_helper.py +++ b/tests/helpers/endpoints_helper.py @@ -26,7 +26,7 @@ from letta.schemas.embedding_config import EmbeddingConfig from letta.schemas.letta_message import ( ToolCallMessage, - InternalMonologue, + ReasoningMessage, LettaMessage, ) from letta.schemas.letta_response import LettaResponse @@ -419,7 +419,7 @@ def assert_invoked_function_call(messages: List[LettaMessage], function_name: st def assert_inner_monologue_is_present_and_valid(messages: List[LettaMessage]) -> None: for message in messages: - if isinstance(message, InternalMonologue): + if isinstance(message, ReasoningMessage): # Found it, do nothing return diff --git a/tests/test_client_legacy.py b/tests/test_client_legacy.py index 30b78c911f..37c227c526 100644 --- a/tests/test_client_legacy.py +++ b/tests/test_client_legacy.py @@ -20,7 +20,7 @@ AssistantMessage, ToolCallMessage, ToolReturnMessage, - InternalMonologue, + ReasoningMessage, LettaMessage, SystemMessage, UserMessage, @@ -171,7 +171,7 @@ def test_agent_interactions(mock_e2b_api_key_none, client: Union[LocalClient, RE assert type(letta_message) in [ SystemMessage, UserMessage, - InternalMonologue, + ReasoningMessage, ToolCallMessage, ToolReturnMessage, AssistantMessage, @@ -255,7 +255,7 @@ def test_streaming_send_message(mock_e2b_api_key_none, client: RESTClient, agent assert response, "Sending message failed" for chunk in response: assert isinstance(chunk, LettaStreamingResponse) - if isinstance(chunk, InternalMonologue) and chunk.internal_monologue and chunk.internal_monologue != "": + if isinstance(chunk, ReasoningMessage) and chunk.reasoning and chunk.reasoning != "": inner_thoughts_exist = True inner_thoughts_count += 1 if isinstance(chunk, ToolCallMessage) and chunk.tool_call and chunk.tool_call.name == "send_message": diff --git a/tests/test_server.py b/tests/test_server.py index fc39d527a5..2209c8bcff 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -12,7 +12,7 @@ from letta.schemas.letta_message import ( ToolCallMessage, ToolReturnMessage, - InternalMonologue, + ReasoningMessage, LettaMessage, SystemMessage, UserMessage, @@ -691,14 +691,14 @@ def _test_get_messages_letta_format( letta_message = letta_messages[letta_message_index] if message.text: - assert isinstance(letta_message, InternalMonologue) + assert isinstance(letta_message, ReasoningMessage) letta_message_index += 1 else: assert message.tool_calls is not None else: # Non-reverse handling if message.text: - assert isinstance(letta_message, InternalMonologue) + assert isinstance(letta_message, ReasoningMessage) letta_message_index += 1 if letta_message_index >= len(letta_messages): break