Skip to content

Commit

Permalink
♻️ improve semantics of prompt packages
Browse files Browse the repository at this point in the history
  • Loading branch information
ianhomer committed Oct 1, 2024
1 parent 79255db commit fa55e91
Show file tree
Hide file tree
Showing 10 changed files with 39 additions and 31 deletions.
2 changes: 1 addition & 1 deletion DEVELOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Run tests

pytest

Run tests with watch
Run tests with pytest watcher

ptw

Expand Down
12 changes: 6 additions & 6 deletions ask/ask.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from prompt_toolkit.patch_stdout import patch_stdout

from .config import default_parse_args, load_config
from .handler import InputHandler
from .input import AbstractInputter, InputInterrupt, PromptInputter
from .prompt import get_prompt
from .pre_processor import PromptPreProcessor
from .prompt_generator import generate_prompt
from .prompter import AbstractPrompter, InputInterrupt, UserPrompter
from .renderer import AbstractRenderer, RichRenderer
from .services.anthropic import AnthropicService
from .services.bot_service import BotService
Expand All @@ -18,7 +18,7 @@


def run(
inputter: AbstractInputter = PromptInputter(),
inputter: AbstractPrompter = UserPrompter(),
Service: Optional[type[BotService]] = None,
Renderer: type[AbstractRenderer] = RichRenderer,
parse_args=default_parse_args,
Expand All @@ -41,11 +41,11 @@ def signal_handler(sig: int, frame: Optional[object]) -> None:
config = load_config(parse_args, config_file_name)

renderer = Renderer(pretty_markdown=config.markdown)
input_handler = InputHandler(renderer=renderer)
input_handler = PromptPreProcessor(renderer=renderer)

file_input = False

prompt, file_input = get_prompt(config.inputs, config.template)
prompt, file_input = generate_prompt(config.inputs, config.template)

if config.dry:
renderer.print_line("Prompt : ")
Expand Down
16 changes: 8 additions & 8 deletions ask/handler.py → ask/pre_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .save import save


class InputHandlerResponse:
class PromptPreProcessorResponse:
def __init__(self, ignore=False, process=True, quit=False) -> None:
self._ignore = ignore
self._process = process
Expand All @@ -27,24 +27,24 @@ def __str__(self) -> str:
return f"ignore:{self._ignore}, process:{self._process}, quit:{self._quit}"


class InputHandler:
class PromptPreProcessor:
def __init__(self, renderer: AbstractRenderer) -> None:
self.renderer = renderer

def handle(
self, input: str, previous_response_text: Optional[str]
) -> InputHandlerResponse:
) -> PromptPreProcessorResponse:
input_lower = input.lower()
if input_lower == "save":
save(previous_response_text)
return InputHandlerResponse(process=False)
return PromptPreProcessorResponse(process=False)

if previous_response_text and (
("copy code" in input_lower and len(input) < 17)
or ("copy" in input_lower and len(input) < 7)
):
copy_code(self.renderer, previous_response_text)
return InputHandlerResponse(process=False)
return PromptPreProcessorResponse(process=False)

# The handling for <quit> is currently only used within end to end
# tests and may be removed.
Expand All @@ -53,9 +53,9 @@ def handle(
or input_lower.endswith("<quit>")
or input_lower.startswith("<quit>")
):
return InputHandlerResponse(quit=True)
return PromptPreProcessorResponse(quit=True)

if input_lower.endswith("ignore"):
return InputHandlerResponse(process=False, ignore=True)
return PromptPreProcessorResponse(process=False, ignore=True)

return InputHandlerResponse()
return PromptPreProcessorResponse()
2 changes: 1 addition & 1 deletion ask/prompt.py → ask/prompt_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
ASK_PROMPT_DIRECTORY_NAME = "ASK_PROMPT_DIRECTORY"


def get_prompt(inputs: List[str], template: Optional[str]) -> Tuple[str, bool]:
def generate_prompt(inputs: List[str], template: Optional[str]) -> Tuple[str, bool]:
parts = []
file_input = False
for word in inputs:
Expand Down
4 changes: 2 additions & 2 deletions ask/input.py → ask/prompter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class InputInterrupt(KeyboardInterrupt):
prompt_fragments: AnyFormattedText = [("class:marker", "(-_-) ")]


class AbstractInputter:
class AbstractPrompter:
@abstractmethod
def get_input(self) -> str:
pass
Expand All @@ -37,7 +37,7 @@ def is_running(self) -> bool:
return True


class PromptInputter(AbstractInputter):
class UserPrompter(AbstractPrompter):
def __init__(self) -> None:
self.prompt_session: PromptSession = PromptSession(
prompt_fragments, style=style, vi_mode=True
Expand Down
4 changes: 2 additions & 2 deletions ask/tests/e2e_utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import argparse
from collections import deque

from ..input import AbstractInputter, InputInterrupt
from ..prompter import AbstractPrompter, InputInterrupt
from ..renderer import AbstractRenderer


class MockInputter(AbstractInputter):
class MockInputter(AbstractPrompter):
def __init__(self, inputs=["mock input 1"]) -> None:
self.queue = deque(inputs)

Expand Down
18 changes: 9 additions & 9 deletions ask/tests/test_prompt.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import os

from ..prompt import get_prompt
from ..prompt_generator import generate_prompt

TESTS_DIRECTORY = os.path.dirname(__file__)


def test_get_prompt_with_words():
def test_generate_prompt_with_words():
inputs = ["hello", "world"]
assert get_prompt(inputs, None) == ("hello world", False)
assert generate_prompt(inputs, None) == ("hello world", False)


def test_get_prompt_with_text_file():
def test_generate_prompt_with_text_file():
inputs = [f"{TESTS_DIRECTORY}/test.md"]
assert get_prompt(inputs, None) == (
assert generate_prompt(inputs, None) == (
"# Test\n\nThis is a test file\n",
True,
)


def test_get_prompt_with_pdf_file():
def test_generate_prompt_with_pdf_file():
inputs = [f"{TESTS_DIRECTORY}/test.pdf"]
assert get_prompt(inputs, None) == (
assert generate_prompt(inputs, None) == (
"test\n Test\nThis is a test file",
True,
)


def test_get_prompt_with_template():
def test_generate_prompt_with_template():
inputs = ["fish", "cat"]
assert get_prompt(inputs, f"{TESTS_DIRECTORY}/prompt.txt") == (
assert generate_prompt(inputs, f"{TESTS_DIRECTORY}/prompt.txt") == (
"one fish two cat\n",
False,
)
4 changes: 2 additions & 2 deletions ask/tests/transcribe_prompt_inputter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

from prompt_toolkit import PromptSession

from ..input import AbstractInputter, InputInterrupt
from ..prompter import AbstractPrompter, InputInterrupt
from ..transcribe import is_running


class TranscribePromptInputter(AbstractInputter):
class TranscribePromptInputter(AbstractPrompter):
def __init__(
self,
transcribe_filename,
Expand Down
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[tool.pytest-watcher]
now = false
delay = 0.2
runner = "pytest"
runner_args = []
patterns = ["*.py"]
ignore_patterns = [".null-ls*"]
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ flake8
isort
pre-commit
pytest
pytest-watcher

0 comments on commit fa55e91

Please sign in to comment.