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

Enhanced Configuration and Development Workflow with Poetry, Markdown Prompts, and YAML Config #432

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0376cda
Replace dev-requirements.txt and requirements.txt with poetry.lock
greg-assa Dec 18, 2023
61ab014
Migrate packaging from setuptools to poetry
greg-assa Dec 19, 2023
5bdafdd
Switch to Poetry for dependency management
greg-assa Dec 19, 2023
869d622
Merge branch 'main' of https://github.com/use-the-fork/mentat into ma…
greg-assa Dec 19, 2023
ed640f8
Update installation instructions in README
greg-assa Dec 19, 2023
ed014b1
Add poetry installation step in Github workflows
greg-assa Dec 19, 2023
7a77a24
Update license check command in GitHub workflow
greg-assa Dec 19, 2023
c83c8fa
Use poetry to run pytest in benchmark script
greg-assa Dec 21, 2023
ad09fb4
Add markdown prompts and update file references
use-the-fork Dec 25, 2023
e6f2596
Compressed Coding Project prompts to markdown
use-the-fork Dec 26, 2023
c2a935e
Refactor prompt configuration and improve output formatting
use-the-fork Dec 27, 2023
8611ffa
Merge branch 'main' of https://github.com/use-the-fork/mentat into fe…
use-the-fork Dec 27, 2023
eb9725d
Refactor code to use global config object
use-the-fork Dec 27, 2023
f8da6ba
Refactor config import and usage across multiple files
greg-assa Dec 27, 2023
55e29ec
Replace custom debug function with rich inspect
greg-assa Dec 27, 2023
d22d33d
wip
greg-assa Dec 27, 2023
5468797
Update terminal client and dependencies
use-the-fork Dec 28, 2023
a529d13
Replace rich module with termcolor for message formatting
use-the-fork Dec 28, 2023
38a4da2
Updated configuration file path in Mentat
greg-assa Dec 28, 2023
7dae315
Update code to fetch configuration from user session
greg-assa Dec 28, 2023
be1b313
Refactor config handling
use-the-fork Dec 29, 2023
46a4070
Update code style for better readability and maintainability
use-the-fork Dec 29, 2023
352b64e
Adjustments for Ruff
use-the-fork Dec 29, 2023
a288ba7
Update the message in session stream and refactor config
use-the-fork Dec 29, 2023
19d3bf4
Update command in lint and test workflow
use-the-fork Dec 29, 2023
efdb45b
Added ability to disable and enable plugins / Commands based on YAML.
use-the-fork Dec 30, 2023
d903a85
Merge pull request #1 from use-the-fork/development
use-the-fork Dec 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ jobs:

- name: Install dependencies
run: |
python -m pip install .
pip install -r dev-requirements.txt
pipx install poetry
poetry install

- name: Run and upload benchmarks
run: ./scripts/run_and_upload_benchmarks.sh
run: poetry run ./scripts/run_and_upload_benchmarks.sh
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_SECRET_ACCESS_KEY }}
Expand Down
24 changes: 12 additions & 12 deletions .github/workflows/lint_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ jobs:
- uses: chartboost/ruff-action@v1
- name: Install dependencies
run: |
python -m pip install .
pip install -r dev-requirements.txt
pipx install poetry
poetry install
- name: black check
run: black --check --preview .
run: poetry run black --check --preview .
- name: isort check
run: isort --profile black --check .
run: poetry run isort --profile black --check .

build:
runs-on: ${{ matrix.os }}
Expand Down Expand Up @@ -46,21 +46,21 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install .
python -m pip install -r dev-requirements.txt
pipx install poetry
poetry install
- name: Check types with pyright
run: |
pyright
poetry run pyright
- name: Test with pytest
run: |
pytest
poetry run pytest
- name: Can run Mentat
# Unfortunately Github Actions Runners have trouble with prompt toolkit, so we can't do this on Windows.
if: runner.os != 'Windows'
# Ensure that python doesn't import local mentat folder and that 'mentat' command calls mentat instead of switching folders.
working-directory: ./testbed
run: |
mentat
poetry run mentat .

license-check:
runs-on: ubuntu-latest
Expand All @@ -73,8 +73,8 @@ jobs:
python-version: 3.11
- name: Install dependencies
run: |
python -m pip install .
pip install -r dev-requirements.txt
pipx install poetry
poetry install
- name: Run license checking script
run: |
python tests/license_check.py
poetry run python tests/license_check.py
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install setuptools wheel twine
pipx install poetry
poetry install
- name: Set Prod conf.ini
run: |
mv mentat/resources/conf/conf-prod.ini mentat/resources/conf/conf.ini
Expand All @@ -45,7 +45,7 @@ jobs:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
python setup.py sdist bdist_wheel
poetry build
twine upload dist/*
- name: Brew Release
# Since Homebrew automatically updates from PyPI, no need for us to run this
Expand All @@ -55,4 +55,4 @@ jobs:
with:
token: ${{ secrets.TOKEN_FOR_BREW }}
formula: mentat
tag: v${{ steps.version-number.outputs.group1 }}
tag: v${{ steps.version-number.outputs.group1 }}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ git clone https://github.com/AbanteAI/mentat.git
cd mentat

# install with pip in editable mode:
pip install -e .
poetry install
```

## Add your OpenAI API Key
Expand Down
11 changes: 0 additions & 11 deletions dev-requirements.txt

This file was deleted.

17 changes: 17 additions & 0 deletions mentat/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
from mentat.user_session import user_session

__all__ = [
"user_session",
]


def __dir__():
return __all__


# Make sure to bump this on Release x.y.z PR's!
__version__ = "1.0.7"


# the very first thing we need to do is load_config so we don't have an empty object while booting.
from mentat.config import load_config # noqa: E402

load_config()
10 changes: 5 additions & 5 deletions mentat/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
exit("Error: Python version 3.10 or higher is required.")


from mentat.terminal.client import run_cli

# This is only here so that mentat can be run with python -m mentat
# This file will NOT run when run from pip installation
run_cli()
# from mentat.terminal.client import run_cli
#
# # This is only here so that mentat can be run with python -m mentat
# # This file will NOT run when run from pip installation
# run_cli()
26 changes: 19 additions & 7 deletions mentat/agent_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,33 @@
ChatCompletionSystemMessageParam,
)

import mentat
from mentat.llm_api_handler import prompt_tokens
from mentat.prompts.prompts import read_prompt
from mentat.session_context import SESSION_CONTEXT
from mentat.session_input import ask_yes_no, collect_user_input
from mentat.transcripts import ModelMessage

agent_file_selection_prompt_path = Path("agent_file_selection_prompt.txt")
agent_command_prompt_path = Path("agent_command_selection_prompt.txt")


class AgentHandler:

config = mentat.user_session.get("config")
agent_file_selection_prompt_path = config.ai.prompts.get(
"agent_file_selection_prompt", Path("text/agent_file_selection_prompt.txt")
)
agent_command_prompt_path = config.ai.prompts.get(
"agent_command_selection_prompt",
Path("text/agent_command_selection_prompt.txt"),
)

def __init__(self):
self._agent_enabled = False

self.agent_file_message = ""
self.agent_file_selection_prompt = read_prompt(agent_file_selection_prompt_path)
self.agent_command_prompt = read_prompt(agent_command_prompt_path)
self.agent_file_selection_prompt = read_prompt(
self.agent_file_selection_prompt_path
)
self.agent_command_prompt = read_prompt(self.agent_command_prompt_path)

# Make this property readonly because we have to set things when we enable agent mode
@property
Expand Down Expand Up @@ -53,7 +63,8 @@ async def enable_agent_mode(self):
),
),
]
model = ctx.config.model
config = mentat.user_session.get("config")
model = config.ai.model
response = await ctx.llm_api_handler.call_llm_api(messages, model, False)
content = response.choices[0].message.content or ""

Expand Down Expand Up @@ -84,7 +95,8 @@ async def enable_agent_mode(self):
async def _determine_commands(self) -> List[str]:
ctx = SESSION_CONTEXT.get()

model = ctx.config.model
config = mentat.user_session.get("config")
model = config.ai.model
messages = [
ChatCompletionSystemMessageParam(
role="system", content=self.agent_command_prompt
Expand Down
43 changes: 24 additions & 19 deletions mentat/code_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pathlib import Path
from typing import Dict, Iterable, List, Optional, Set, Union

import mentat
from mentat.code_feature import (
CodeFeature,
get_code_message_from_features,
Expand Down Expand Up @@ -60,7 +61,7 @@ def display_context(self):
"""Display the baseline context: included files and auto-context settings"""
session_context = SESSION_CONTEXT.get()
stream = session_context.stream
config = session_context.config
config = mentat.user_session.get("config")

stream.send("Code Context:", color="blue")
prefix = " "
Expand All @@ -69,9 +70,11 @@ def display_context(self):
stream.send(f"{prefix}Diff:", end=" ")
stream.send(self.diff_context.get_display_context(), color="green")

if config.auto_context_tokens > 0:
if config.run.auto_context_tokens > 0:
stream.send(f"{prefix}Auto-Context: Enabled")
stream.send(f"{prefix}Auto-Context Tokens: {config.auto_context_tokens}")
stream.send(
f"{prefix}Auto-Context Tokens: {config.run.auto_context_tokens}"
)
else:
stream.send(f"{prefix}Auto-Context: Disabled")

Expand Down Expand Up @@ -120,9 +123,8 @@ async def get_code_message(
'prompt_tokens' argument is the total number of tokens used by the prompt before the code message,
used to ensure that the code message won't overflow the model's context size
"""
session_context = SESSION_CONTEXT.get()
config = session_context.config
model = config.model
config = mentat.user_session.get("config")
model = config.ai.model

# Setup code message metadata
code_message = list[str]()
Expand Down Expand Up @@ -151,14 +153,17 @@ async def get_code_message(
)

tokens_used = (
prompt_tokens + meta_tokens + include_files_tokens + config.token_buffer
prompt_tokens + meta_tokens + include_files_tokens + config.ai.token_buffer
)

if not is_context_sufficient(tokens_used):
raise ContextSizeInsufficient()
auto_tokens = min(get_max_tokens() - tokens_used, config.auto_context_tokens)
auto_tokens = min(
get_max_tokens() - tokens_used, config.run.auto_context_tokens
)

# Get auto included features
if config.auto_context_tokens > 0 and prompt:
if config.run.auto_context_tokens > 0 and prompt:
features = self.get_all_features()
feature_filter = DefaultFilter(
auto_tokens,
Expand Down Expand Up @@ -187,11 +192,10 @@ def get_all_features(
Retrieves every CodeFeature under the cwd. If files_only is True the features won't be split into intervals
"""
session_context = SESSION_CONTEXT.get()
config = mentat.user_session.get("config")

abs_exclude_patterns: Set[Path] = set()
for pattern in self.ignore_patterns.union(
session_context.config.file_exclude_glob_list
):
for pattern in self.ignore_patterns.union(config.run.file_exclude_glob_list):
if not Path(pattern).is_absolute():
abs_exclude_patterns.add(session_context.cwd / pattern)
else:
Expand Down Expand Up @@ -270,17 +274,17 @@ def include(
A set of paths that have been successfully included in the context
"""
session_context = SESSION_CONTEXT.get()
config = mentat.user_session.get("config")

path = Path(path)

abs_exclude_patterns: Set[Path] = set()
all_exclude_patterns: Set[Union[str, Path]] = set(
[
*exclude_patterns,
*self.ignore_patterns,
*session_context.config.file_exclude_glob_list,
]
)
all_exclude_patterns: Set[Union[str, Path]] = set([
*exclude_patterns,
*self.ignore_patterns,
*config.run.file_exclude_glob_list,
])

for pattern in all_exclude_patterns:
if not Path(pattern).is_absolute():
abs_exclude_patterns.add(session_context.cwd / pattern)
Expand All @@ -293,6 +297,7 @@ def include(
cwd=session_context.cwd,
exclude_patterns=abs_exclude_patterns,
)

except PathValidationError as e:
session_context.stream.send(str(e), color="light_red")
return set()
Expand Down
5 changes: 4 additions & 1 deletion mentat/code_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import attr

import mentat
from mentat.ctags import get_ctag_lines_and_names
from mentat.diff_context import annotate_file_message, parse_diff
from mentat.errors import MentatError
Expand Down Expand Up @@ -130,7 +131,9 @@ def get_code_message(self, standalone: bool = True) -> list[str]:
"""
session_context = SESSION_CONTEXT.get()
code_file_manager = session_context.code_file_manager
parser = session_context.config.parser

config = mentat.user_session.get("config")
parser = config.parser.parser
code_context = session_context.code_context

code_message: list[str] = []
Expand Down
Loading
Loading