Skip to content
This repository has been archived by the owner on Jan 7, 2025. It is now read-only.

Conversation get_messages gets code_message #533

Merged
merged 4 commits into from
Feb 27, 2024

Conversation

jakethekoenig
Copy link
Member

@jakethekoenig jakethekoenig commented Feb 23, 2024

Frequently in the codebase people will go to conversation for the messages and then independently get the code_message. It's simpler if the conversation handles that.

get_messages is also changed to accept a system prompt argument instead of having a include_system_prompt parameter to simplify agent's calling of it. If callers genuinely want no system prompt they can pass [].

Move responsibility to raise if context too big from code_context to conversation.

Pull Request Checklist

  • Documentation has been updated, or this change doesn't require that

Frequently in the codebase people will go to conversation for the
messages and then independently get the code_message. It's simpler if
the conversation handles that.

The sampler and reviser both do this but with a different system prompt.
I think we should also change get_conversation to have an optional
system prompt parameter that overrides the default parser system prompt
when passed.

We should also provide a get_token_count method as many callers are
getting the messages just for this one piece of information.
@@ -92,7 +92,7 @@ async def _determine_commands(self) -> List[str]:
ChatCompletionSystemMessageParam(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job making the get_messages call asynchronous. This ensures consistency with the rest of the codebase.

@@ -68,7 +66,7 @@ def __init__(
self.ignore_files: Set[Path] = set()
self.auto_features: List[CodeFeature] = []

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making refresh_context_display asynchronous is a good move for consistency and potentially allows for more complex operations within the method in the future.

@@ -45,20 +45,7 @@ async def display_token_count(self):
config = session_context.config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition of include_code_message parameter in get_messages method is a smart way to reduce redundancy. It's a good practice to encapsulate this logic within the conversation class.

) -> list[ChatCompletionMessageParam]:
"""Returns the messages in the conversation. The system message may change throughout
the conversation and messages may contain additional metadata not supported by the API,
so it is important to access the messages through this method.
"""
session_context = SESSION_CONTEXT.get()
config = session_context.config
ctx = SESSION_CONTEXT.get()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The async keyword addition here is crucial for the method's functionality with the new async calls inside it. Well done on updating the method signature accordingly.

@@ -54,7 +54,7 @@ async def revise_edit(file_edit: FileEdit):
user_message = list(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating to the async get_messages call here ensures that the revisor's behavior remains consistent with the rest of the system's async nature.

@@ -118,7 +118,8 @@ async def create_sample(self) -> Sample:
message_history: list[dict[str, str]] = []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good to see the async get_messages being used here. This change ensures that the sampler's operations are in line with the async architecture of the application.

@@ -151,7 +151,7 @@ async def _main(self):
stream.send("Type 'q' or use Ctrl-C to quit at any time.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change to call refresh_context_display asynchronously is necessary and correct. It's important for maintaining the non-blocking nature of the application.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chose the wrong line to comment on here?

@@ -60,7 +60,7 @@ async def collect_input_with_commands() -> StreamMessage:
arguments = shlex.split(" ".join(response.data.split(" ")[1:]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The update to call refresh_context_display asynchronously here is a good catch. It ensures that the command handling process doesn't block other operations.

@@ -246,7 +246,8 @@ async def test_clear_command(temp_testbed, mock_collect_user_input, mock_call_ll
await session.stream.recv(channel="client_exit")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating the test to await get_messages is necessary due to the changes in the Conversation class. Good job on keeping the tests up to date.

@@ -1,44 +1,50 @@
import pytest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition of async and await in the tests is essential for testing the new asynchronous get_messages method. It's great to see the tests being adapted to match the code changes.

Copy link
Contributor

mentatbot bot commented Feb 23, 2024

MENTAT CODE REVIEW IN BETA. Please Reply with feedback

This pull request introduces several key improvements, notably making various methods asynchronous to align with the overall async architecture of the application. The changes are well thought out and implemented, ensuring consistency and efficiency in message handling and command execution. It's particularly commendable how the changes have been propagated throughout the codebase, including updating tests to reflect the new asynchronous behavior. Overall, this PR represents a solid step forward in maintaining and improving the codebase's quality and functionality.


# Calculate user included features token size
include_features = [
feature
for file_features in self.include_files.values()
for feature in file_features
]
include_files_message = get_code_message_from_features(include_features)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved all this to the if because it's only relevant if auto_context is on. Benchmarking shows its basically unimportant for performance but I think its easier to see how things are used and the flow of logic this way.

Copy link
Member

@granawkins granawkins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like removing all the token checks from the context-building process (moving to llm_api_handler instead), and the conversation.count_tokens method. Made one small suggestion, otherwise LGTM. 🚀

Comment on lines +275 to +276
messages_snapshot = await self.get_messages(include_code_message=True)
tokens_used = prompt_tokens(messages_snapshot, config.model)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
messages_snapshot = await self.get_messages(include_code_message=True)
tokens_used = prompt_tokens(messages_snapshot, config.model)
tokens_used = await self.count_tokens(include_code_message=True)

Can this new method be reused here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be used but we still need to compute messages_snapshot to send to the llm anyway. So I think it is better as is.

@jakethekoenig jakethekoenig merged commit 7b04721 into main Feb 27, 2024
16 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants