Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: started working on always-fresh context message #281

Merged
merged 10 commits into from
Dec 8, 2024

Conversation

ErikBjare
Copy link
Owner

@ErikBjare ErikBjare commented Nov 25, 2024

I've had this idea for a while to gather all the dynamic context, like files and RAG results, and always output the most up-to-date versions of them right before a user message (not including previous/stale such messages).

This should save considerably on tokens (but may break caching), improve the reliability of patches, and unifies files handling.

TODO

TODO (to merge, not to finish)

We could also set the current date and time in such a message, instead of the system prompt (#137).


Important

Introduces fresh context message handling to ensure latest file versions and git status are included in messages, with changes in chat.py, context.py, and logmanager.py.

  • Behavior:
    • Introduces fresh context message handling in chat.py by tracking paths as files instead of codeblocks.
    • Updates prepare_messages() in logmanager.py to strip old context and ensure latest file versions are included.
  • Functions:
    • Adds gather_fresh_context() in context.py to collect fresh file contents and git status.
    • Modifies _include_paths() in chat.py to support fresh context mode.
  • Tests:
    • Adds tests in test_context.py for file_to_display_path(), append_file_content(), gather_fresh_context(), and get_mentioned_files().
  • Misc:
    • Adds Counter import in context.py for file mention tracking.
    • Adds TODOs for handling git context and sorting files by recency in context.py.

This description was created by Ellipsis for bbbbae8. It will automatically update as commits are pushed.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

❌ Changes requested. Reviewed everything up to 592a950 in 1 minute and 56 seconds

More details
  • Looked at 56 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 drafted comments based on config settings.
1. gptme/logmanager.py:321
  • Draft comment:
    The TODO comment about including git status -vv context is not yet implemented. Ensure this functionality is completed or tracked in an issue before merging.
  • Reason this comment was not posted:
    Comment did not seem useful.
2. gptme/logmanager.py:325
  • Draft comment:
    The TODO comment about getting mentioned files and ensuring their latest versions are in context is not yet implemented. Ensure this functionality is completed or tracked in an issue before merging.
  • Reason this comment was not posted:
    Marked as duplicate.
3. gptme/logmanager.py:331
  • Draft comment:
    The TODO comment about stripping old patches and saves is not yet implemented. Ensure this functionality is completed or tracked in an issue before merging.
  • Reason this comment was not posted:
    Marked as duplicate.

Workflow ID: wflow_CikcFQ4meMOMBZdj


Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

@codecov-commenter
Copy link

codecov-commenter commented Nov 25, 2024

Codecov Report

Attention: Patch coverage is 67.40331% with 59 lines in your changes missing coverage. Please review.

Project coverage is 73.45%. Comparing base (75b298b) to head (bbbbae8).

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
gptme/context.py 62.66% 56 Missing ⚠️
gptme/chat.py 91.30% 2 Missing ⚠️
gptme/logmanager.py 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #281      +/-   ##
==========================================
- Coverage   74.06%   73.45%   -0.61%     
==========================================
  Files          67       68       +1     
  Lines        4770     4932     +162     
==========================================
+ Hits         3533     3623      +90     
- Misses       1237     1309      +72     
Flag Coverage Δ
anthropic/claude-3-haiku-20240307 71.57% <67.40%> (-0.63%) ⬇️
openai/gpt-4o-mini 70.55% <66.85%> (-0.33%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ErikBjare
Copy link
Owner Author

The more I think about this the more of an improvement I realize that it would be.

I should prioritize this.

@ErikBjare
Copy link
Owner Author

I just realized I did something very similar in https://github.com/ErikBjare/gptme/blob/master/scripts/treeofthoughts.py

@ErikBjare ErikBjare mentioned this pull request Dec 7, 2024
1 task
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me! Incremental review on d953629 in 54 seconds

More details
  • Looked at 220 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 4 drafted comments based on config settings.
1. gptme/logmanager.py:320
  • Draft comment:
    Handle the case where a file is mentioned but does not exist to avoid potential KeyError. Consider using files.get(f, 0) instead of files[f].
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
2. gptme/logmanager.py:364
  • Draft comment:
    Handle OSError for long file paths in include_file_content to prevent potential crashes.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
3. gptme/logmanager.py:382
  • Draft comment:
    Consider logging or handling unexpected values for GPTME_FRESH_CONTEXT to avoid confusion or unexpected behavior.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The prepare_messages function in logmanager.py uses a feature flag to determine the context mode. However, it does not log or handle the case where the environment variable is set to an unexpected value. This could lead to confusion or unexpected behavior.
4. gptme/chat.py:311
  • Draft comment:
    Handle OSError for long file paths in _include_paths to prevent potential crashes.
  • Reason this comment was not posted:
    Marked as duplicate.

Workflow ID: wflow_vt1sLrQNkkTLw3cC


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

@ErikBjare
Copy link
Owner Author

Needs #262 fixed before merging

@ErikBjare
Copy link
Owner Author

It kinda works now (will push soon), but it gets confused and says stuff like "I notice that I was previously incorrect in claiming to see the contents of files that weren't actually shown to me."

What if we should just stuff the context up front? Before user messages?

@ErikBjare
Copy link
Owner Author

ErikBjare commented Dec 8, 2024

Here's a detailed specification for the fresh context message feature:

Fresh Context Message Specification

Overview

The fresh context message feature improves how file contents and git status are provided to the LLM by maintaining a single source of truth for the current state of relevant files and working directory.

Design Goals

  1. Single Source of Truth

    • Provide one clear location for current file contents
    • Avoid confusion about stale/outdated content
    • Make it clear which version of files the assistant should reference
  2. Temporal Consistency

    • Context messages represent state at a specific point in time
    • Context is inserted before user messages to maintain conversation flow
    • Working directory changes are reflected in proper chronological order
  3. Path Handling

    • Workspace-relative paths when possible
    • Home directory paths shown with ~
    • Absolute paths when needed for clarity
    • Consistent path resolution relative to workspace

Implementation

Context Message Format

# Fresh Context
Working directory: /path/to/workspace

This context message is inserted right before your last message.
It contains the current state of relevant files and git status at the time of processing.
The file contents shown in this context message are the source of truth.
Any file contents shown elsewhere in the conversation history may be outdated.

```file1.txt
<contents of file1.txt>
```

```file2.py
<contents of file2.py>
```

```git status -vv
<git status output>
```

File Selection and Ordering

  1. Files are collected from msg.files across the conversation
  2. Files are sorted by:
    • Number of mentions (most mentioned first)
    • Last modified time (most recently modified first)
  3. Limited to top 10 most relevant files

Path Resolution

  1. If path is relative and workspace is provided:
    • Make absolute relative to workspace
    • Display relative to current working directory if possible
  2. If path is in home directory:
    • Display with ~ prefix
  3. If path is absolute:
    • Keep as absolute path

Git Integration

  1. If in a git repository:
    • Include git status -vv output
    • Shows staged/unstaged changes
    • Shows untracked files
  2. If not in a git repository:
    • Skip git status section

Message Placement

  1. Context message is inserted before the last user message
  2. Each context message represents a snapshot at that point in time
  3. Previous context messages remain unchanged to maintain conversation history
  4. New context messages are added when:
    • Files are modified
    • Working directory changes
    • Git status changes

Configuration

  • Environment variable: GPTME_FRESH_CONTEXT
    • Values: "1", "true", "yes" to enable
    • Default: disabled (legacy mode)

Legacy Mode

When fresh context is disabled:

  • File contents are included inline where mentioned
  • No automatic updates of file contents
  • May lead to stale/outdated content in conversation

Future Improvements

  1. File monitoring:
    • Watch for file changes
    • Automatically insert new context when files change
  2. Smarter file selection:
    • Consider file relevance to current conversation
    • Use RAG to determine file importance
  3. Diff highlighting:
    • Show what changed between context updates
    • Highlight modified sections

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

❌ Changes requested. Incremental review on a563e79 in 36 seconds

More details
  • Looked at 485 lines of code in 3 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 drafted comments based on config settings.
1. gptme/context.py:135
  • Draft comment:
    Consider centralizing the check for GPTME_FRESH_CONTEXT to avoid redundancy and potential inconsistencies across the codebase.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The gather_fresh_context function in gptme/context.py uses os.getenv to check for the GPTME_FRESH_CONTEXT environment variable. This is done multiple times across different files. It might be beneficial to centralize this check to avoid redundancy and potential inconsistencies.
2. gptme/chat.py:279
  • Draft comment:
    Consider centralizing the check for GPTME_FRESH_CONTEXT to avoid redundancy and potential inconsistencies across the codebase.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The _include_paths function in gptme/chat.py uses os.getenv to check for the GPTME_FRESH_CONTEXT environment variable. This is done multiple times across different files. It might be beneficial to centralize this check to avoid redundancy and potential inconsistencies.
3. gptme/logmanager.py:311
  • Draft comment:
    The gather_fresh_context function appears to be a duplicate of the one in gptme/context.py. Consider removing it to avoid redundancy.
  • Reason this comment was not posted:
    Comment was on unchanged code.

Workflow ID: wflow_1BnjrTeJZOlJChMg


Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me! Incremental review on 8ae33f2 in 9 seconds

More details
  • Looked at 22 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. gptme/init.py:38
  • Draft comment:
    Consider providing more context on why setting TOKENIZERS_PARALLELISM to false is necessary and its potential impact on performance or functionality.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The comment about setting the environment variable for TOKENIZERS_PARALLELISM is not clear enough about its impact on performance and potential side effects.

Workflow ID: wflow_Mc8iy30CTWNeUd0A


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

- Add tests for context handling functionality
- Fix trailing whitespace and ruff issues
- Improve file path handling in context gathering
- Enhance context message formatting
@ErikBjare ErikBjare force-pushed the dev/fresh-context-message branch from 8ae33f2 to 7cde498 Compare December 8, 2024 13:15
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

❌ Changes requested. Incremental review on 7cde498 in 40 seconds

More details
  • Looked at 541 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 drafted comments based on config settings.
1. tests/test_context.py:22
  • Draft comment:
    Avoid using os.chdir() in tests as it can lead to side effects. Instead, use tmp_path directly for path operations.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The use of os.chdir() in tests can lead to side effects, especially if tests are run in parallel. It's better to use tmp_path directly without changing the working directory.
2. gptme/context.py:188
  • Draft comment:
    Remove commented-out code for git_status and gh_pr_status if not needed to keep the code clean.
  • Reason this comment was not posted:
    Confidence changes required: 30%
    The gather_fresh_context function has commented-out code for git and PR status. If these are not needed, they should be removed to keep the code clean.
3. gptme/context.py:269
  • Draft comment:
    Ensure consistency in environment variable names. FRESH_CONTEXT here should match GPTME_FRESH_CONTEXT used elsewhere.
  • Reason this comment was not posted:
    Comment did not seem useful.

Workflow ID: wflow_WWokdvjv8kJ7Nkrv


Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

gptme/context.py Outdated
files_fresh = [
f
for f in files
if not check_modified or f.stat().st_mtime <= datetime.timestamp(msg.timestamp)
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider handling FileNotFoundError when accessing f.stat().st_mtime to avoid runtime errors if the file is deleted between checks.

"""Run pre-commit checks on modified files and return output if there are issues."""
cmd = "pre-commit run --files $(git ls-files -m)"
try:
subprocess.run(cmd, shell=True, capture_output=True, text=True, check=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

Using shell=True with subprocess.run can be a security risk. Ensure the command is safe or refactor to avoid shell=True.

Add fresh context mode that provides accurate file state information:
- Add FRESH_CONTEXT environment flag to enable new mode
- Implement context gathering from git and files
- Track file paths and include contents before each user message
- Improve file path handling and workspace relative paths
- Add pre-commit check integration
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me! Incremental review on 5ca4f1c in 18 seconds

More details
  • Looked at 113 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 4 drafted comments based on config settings.
1. gptme/chat.py:13
  • Draft comment:
    Consider centralizing the use_fresh_context flag initialization to avoid multiple environment variable checks. This will ensure consistency and improve performance slightly.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The environment variable for fresh context mode is checked multiple times in different files. This can lead to inconsistencies if the environment variable changes during runtime. It's better to centralize this check.
2. gptme/context.py:16
  • Draft comment:
    Consider centralizing the use_fresh_context flag initialization to avoid multiple environment variable checks. This will ensure consistency and improve performance slightly.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The environment variable for fresh context mode is checked multiple times in different files. This can lead to inconsistencies if the environment variable changes during runtime. It's better to centralize this check.
3. gptme/chat.py:299
  • Draft comment:
    Consider adding support for directories in _include_paths as mentioned in the TODO comment. This could enhance functionality.
  • Reason this comment was not posted:
    Confidence changes required: 30%
    The _include_paths function in chat.py has a TODO comment about supporting directories. This is a potential area for improvement, but not a critical issue.
4. gptme/chat.py:308
  • Draft comment:
    Consider addressing the TODO about handling codeblocks within codeblocks in _include_paths. This could improve robustness.
  • Reason this comment was not posted:
    Confidence changes required: 30%
    The _include_paths function in chat.py has a TODO comment about handling codeblocks within codeblocks. This is a potential area for improvement, but not a critical issue.

Workflow ID: wflow_B4kRMRhDxZPLkUYa


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me! Incremental review on 944cb51 in 14 seconds

More details
  • Looked at 32 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. gptme/chat.py:282
  • Draft comment:
    Consider refactoring _include_paths to avoid duplicated logic for handling paths and URLs. Additionally, ensure that _parse_prompt checks if a file is a text file before attempting to read its contents to avoid errors with binary files.
  • Reason this comment was not posted:
    Comment did not seem useful.

Workflow ID: wflow_ThdBCSgRoOW3We4u


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

- Add file_to_display_path to handle relative/absolute paths consistently
- Enhance context gathering with fresh context mode support
- Improve handling of binary files in file parsing
- Better workspace path handling and validation
- Add pre-commit check integration
- Refactor file content inclusion logic
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me! Incremental review on fc54429 in 15 seconds

More details
  • Looked at 103 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 2 drafted comments based on config settings.
1. gptme/context.py:276
  • Draft comment:
    Ensure that the placeholder text for modified files is clearly marked and distinguishable from actual file content to avoid confusion.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The append_file_content function in context.py has a potential issue with handling file paths. If a file is modified after the message timestamp, it appends a placeholder text instead of the actual content. This could lead to confusion if the placeholder is not clearly marked or if the user expects the actual content.
2. gptme/context.py:286
  • Draft comment:
    Ensure that last_user_idx is correctly handled when there are no user messages to avoid incorrect message insertion.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The enrich_messages_with_context function in context.py has a potential issue with the insertion of the fresh context message. If last_user_idx is None, it defaults to -1, which might not be the intended behavior if there are no user messages. This could lead to incorrect message insertion.

Workflow ID: wflow_H5kPp8dU64B6rpHk


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me! Incremental review on 5fd6b62 in 26 seconds

More details
  • Looked at 35 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 2 drafted comments based on config settings.
1. gptme/context.py:70
  • Draft comment:
    Consider explicitly checking if a file is a text file before attempting to read it, to avoid relying on catching UnicodeDecodeError. This can improve clarity and performance.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The current implementation of append_file_content has a potential issue with handling non-text files. The function attempts to read the file content and if it fails due to a UnicodeDecodeError, it skips the file. However, it should also handle the case where the file is not a text file by design, and not just due to an error.
2. gptme/context.py:79
  • Draft comment:
    The list comprehension should filter out files that are not in files_text instead of files_fresh. This ensures that only files with content are removed from the list.
        files=[f for f in files if f not in files_text],
  • Reason this comment was not posted:
    Comment looked like it was already resolved.

Workflow ID: wflow_90CQP49NTl6T9miM


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me! Incremental review on e88ca95 in 33 seconds

More details
  • Looked at 244 lines of code in 7 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. gptme/chat.py:340
  • Draft comment:
    Remove unnecessary print statement to clean up the code.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The print statement on line 340 is unnecessary and should be removed to clean up the code.

Workflow ID: wflow_ExI4kn9P0QNqyrap


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me! Incremental review on bbbbae8 in 13 seconds

More details
  • Looked at 39 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 2 drafted comments based on config settings.
1. gptme/chat.py:337
  • Draft comment:
    Remove commented-out code to keep the codebase clean and maintainable.

  • Reason this comment was not posted:
    Confidence changes required: 50%
    The commented-out print statement should be removed to keep the code clean.
2. gptme/context.py:191
  • Draft comment:
    The git parameter should have a default value of True for clarity and consistency.
    msgs: list[Message], workspace: Path | None, git: bool = True
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The function signature should have a consistent style, and the default argument should be a boolean value.

Workflow ID: wflow_vDhARiGX8pCd4vq2


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

@ErikBjare ErikBjare merged commit 01d8052 into master Dec 8, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants