Skip to content

Commit

Permalink
fix: better error if attempting to run on Windows, refactor readline …
Browse files Browse the repository at this point in the history
…stuff (#221)

* fix: better error if attempting to run on Windows, refactored readline stuff into tabcomplete file

* refactor: renamed tabcomplete file to readline

* fix: removed remaining imports of readline outside of readline.py

* test: fixed tests
  • Loading branch information
ErikBjare authored Oct 23, 2024
1 parent 7f1ba2b commit bd8b746
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 39 deletions.
4 changes: 2 additions & 2 deletions gptme/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging
import os
import re
import readline
import sys
import termios
import urllib.parse
Expand All @@ -18,6 +17,7 @@
from .logmanager import Log, LogManager, prepare_messages
from .message import Message
from .models import get_model
from .readline import add_history
from .tools import ToolUse, execute_msg, has_tool
from .tools.base import ConfirmFunc
from .tools.browser import read_url
Expand Down Expand Up @@ -228,7 +228,7 @@ def prompt_user(value=None) -> str: # pragma: no cover
print("\nInterrupted. Press Ctrl-D to exit.")
clear_interruptible()
if response:
readline.add_history(response)
add_history(response) # readline history
return response


Expand Down
37 changes: 2 additions & 35 deletions gptme/init.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import atexit
import logging
import readline
from typing import cast

from dotenv import load_dotenv

from .config import config_path, load_config, set_config_value
from .dirs import get_readline_history_file
from .llm import init_llm
from .models import (
PROVIDERS,
Provider,
get_recommended_model,
set_default_model,
)
from .tabcomplete import register_tabcomplete
from .readline import load_readline_history, register_tabcomplete
from .tools import init_tools
from .util import console

Expand Down Expand Up @@ -74,7 +71,7 @@ def init(model: str | None, interactive: bool, tool_allowlist: list[str] | None)
set_default_model(model)

if interactive:
_load_readline_history()
load_readline_history()

# for some reason it bugs out shell tests in CI
register_tabcomplete()
Expand All @@ -89,36 +86,6 @@ def init_logging(verbose):
logging.getLogger("httpx").setLevel(logging.WARNING)


# default history if none found
# NOTE: there are also good examples in the integration tests
history_examples = [
"What is love?",
"Have you heard about an open-source app called ActivityWatch?",
"Explain 'Attention is All You Need' in the style of Andrej Karpathy.",
"Explain how public-key cryptography works as if I'm five.",
"Write a Python script that prints the first 100 prime numbers.",
"Find all TODOs in the current git project",
]


def _load_readline_history() -> None: # pragma: no cover
logger.debug("Loading history")
# enabled by default in CPython, make it explicit
readline.set_auto_history(True)
# had some bugs where it grew to gigs, which should be fixed, but still good precaution
readline.set_history_length(100)
history_file = get_readline_history_file()
try:
readline.read_history_file(history_file)
except FileNotFoundError:
for line in history_examples:
readline.add_history(line)
except Exception:
logger.exception("Failed to load history file")

atexit.register(readline.write_history_file, history_file)


def _prompt_api_key() -> tuple[str, str, str]: # pragma: no cover
api_key = input("Your OpenAI, Anthropic, or OpenRouter API key: ").strip()
if api_key.startswith("sk-ant-"):
Expand Down
46 changes: 45 additions & 1 deletion gptme/tabcomplete.py → gptme/readline.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,57 @@
import atexit
import logging
import readline
from functools import lru_cache
from pathlib import Path

from .commands import COMMANDS
from .dirs import get_readline_history_file

# noreorder
try:
import readline # fmt: skip
except ImportError: # pragma: no cover
raise Exception(
"Unsupported platform: readline not available.\nIf you are on Windows, use WSL or Docker to run gptme."
) from None


logger = logging.getLogger(__name__)


# default history if none found
# NOTE: there are also good examples in the integration tests
history_examples = [
"What is love?",
"Have you heard about an open-source app called ActivityWatch?",
"Explain 'Attention is All You Need' in the style of Andrej Karpathy.",
"Explain how public-key cryptography works as if I'm five.",
"Write a Python script that prints the first 100 prime numbers.",
"Find all TODOs in the current git project",
]


def add_history(line: str) -> None: # pragma: no cover
readline.add_history(line)


def load_readline_history() -> None: # pragma: no cover
logger.debug("Loading history")
# enabled by default in CPython, make it explicit
readline.set_auto_history(True)
# had some bugs where it grew to gigs, which should be fixed, but still good precaution
readline.set_history_length(100)
history_file = get_readline_history_file()
try:
readline.read_history_file(history_file)
except FileNotFoundError:
for line in history_examples:
readline.add_history(line)
except Exception:
logger.exception("Failed to load history file")

atexit.register(readline.write_history_file, history_file)


def register_tabcomplete() -> None: # pragma: no cover
"""Register tab completion for readline."""

Expand Down
2 changes: 1 addition & 1 deletion tests/test_tabcomplete.py → tests/test_readline.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import sys

from gptme.tabcomplete import _matches
from gptme.readline import _matches


def test_matches():
Expand Down

0 comments on commit bd8b746

Please sign in to comment.