Skip to content

Commit

Permalink
rename to reasoning
Browse files Browse the repository at this point in the history
  • Loading branch information
Caren Thomas committed Dec 19, 2024
1 parent a336092 commit d281405
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 31 deletions.
2 changes: 2 additions & 0 deletions examples/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ def nb_print(messages):
def get_formatted_content(msg):
if msg.message_type == "internal_monologue":
return f'<div class="content"><span class="internal-monologue">{html.escape(msg.internal_monologue)}</span></div>'
elif msg.message_type == "reasoning_message":
return f'<div class="content"><span class="internal-monologue">{html.escape(msg.reasoning)}</span></div>'
elif msg.message_type == "function_call":
args = format_json(msg.function_call.arguments)
return f'<div class="content"><span class="function-name">{html.escape(msg.function_call.name)}</span>({args})</div>'
Expand Down
6 changes: 3 additions & 3 deletions letta/client/streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
28 changes: 21 additions & 7 deletions letta/schemas/letta_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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"),
]
2 changes: 2 additions & 0 deletions letta/schemas/letta_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ def _repr_html_(self):
def get_formatted_content(msg):
if msg.message_type == "internal_monologue":
return f'<div class="content"><span class="internal-monologue">{html.escape(msg.internal_monologue)}</span></div>'
if msg.message_type == "reasoning_message":
return f'<div class="content"><span class="internal-monologue">{html.escape(msg.reasoning)}</span></div>'
elif msg.message_type == "function_call":
args = format_json(msg.function_call.arguments)
return f'<div class="content"><span class="function-name">{html.escape(msg.function_call.name)}</span>({args})</div>'
Expand Down
6 changes: 3 additions & 3 deletions letta/schemas/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
ToolCall as LettaToolCall,
ToolCallMessage,
ToolReturnMessage,
InternalMonologue,
ReasoningMessage,
LettaMessage,
SystemMessage,
UserMessage,
Expand Down Expand Up @@ -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:
Expand Down
20 changes: 10 additions & 10 deletions letta/server/rest_api/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
ToolCallDelta,
ToolCallMessage,
ToolReturnMessage,
InternalMonologue,
ReasoningMessage,
LegacyFunctionCallMessage,
LegacyLettaMessage,
LettaMessage,
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions tests/helpers/endpoints_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions tests/test_client_legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
AssistantMessage,
ToolCallMessage,
ToolReturnMessage,
InternalMonologue,
ReasoningMessage,
LettaMessage,
SystemMessage,
UserMessage,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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":
Expand Down
6 changes: 3 additions & 3 deletions tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from letta.schemas.letta_message import (
ToolCallMessage,
ToolReturnMessage,
InternalMonologue,
ReasoningMessage,
LettaMessage,
SystemMessage,
UserMessage,
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit d281405

Please sign in to comment.