mirror of
https://github.com/Pythagora-io/gpt-pilot.git
synced 2026-01-09 21:27:53 -05:00
Merge pull request #988 from Pythagora-io/console-input
console ui: add multiline, readline, paste, initial/default text support
This commit is contained in:
@@ -11,7 +11,7 @@ from core.llm.base import APIError, BaseLLMClient
|
||||
from core.log import get_logger
|
||||
from core.state.state_manager import StateManager
|
||||
from core.telemetry import telemetry
|
||||
from core.ui.base import UIBase, UIClosedError, pythagora_source
|
||||
from core.ui.base import UIBase, UIClosedError, UserInput, pythagora_source
|
||||
|
||||
log = get_logger(__name__)
|
||||
|
||||
@@ -112,7 +112,15 @@ async def start_new_project(sm: StateManager, ui: UIBase) -> bool:
|
||||
:param ui: User interface.
|
||||
:return: True if the project was created successfully, False otherwise.
|
||||
"""
|
||||
user_input = await ui.ask_question("What is the project name?", allow_empty=False, source=pythagora_source)
|
||||
try:
|
||||
user_input = await ui.ask_question(
|
||||
"What is the project name?",
|
||||
allow_empty=False,
|
||||
source=pythagora_source,
|
||||
)
|
||||
except (KeyboardInterrupt, UIClosedError):
|
||||
user_input = UserInput(cancelled=True)
|
||||
|
||||
if user_input.cancelled:
|
||||
return False
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from typing import Optional
|
||||
|
||||
from prompt_toolkit.shortcuts import PromptSession
|
||||
|
||||
from core.log import get_logger
|
||||
from core.ui.base import ProjectStage, UIBase, UIClosedError, UISource, UserInput
|
||||
|
||||
@@ -57,9 +59,12 @@ class PlainConsoleUI(UIBase):
|
||||
default_str = " (default)" if k == default else ""
|
||||
print(f" [{k}]: {v}{default_str}")
|
||||
|
||||
session = PromptSession("> ")
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = input("> ").strip()
|
||||
choice = await session.prompt_async(default=initial_text or "")
|
||||
choice = choice.strip()
|
||||
except KeyboardInterrupt:
|
||||
raise UIClosedError()
|
||||
if not choice and default:
|
||||
|
||||
@@ -37,6 +37,7 @@ psutil = "^5.9.8"
|
||||
httpx = "^0.27.0"
|
||||
alembic = "^1.13.1"
|
||||
python-dotenv = "^1.0.1"
|
||||
prompt-toolkit = "^3.0.45"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest = "^8.1.1"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -35,8 +35,9 @@ async def test_stream(capsys):
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("builtins.input", return_value="awesome")
|
||||
async def test_ask_question_simple(mock_input):
|
||||
@patch("core.ui.console.PromptSession")
|
||||
async def test_ask_question_simple(mock_PromptSession):
|
||||
prompt_async = mock_PromptSession.return_value.prompt_async = AsyncMock(return_value="awesome")
|
||||
ui = PlainConsoleUI()
|
||||
|
||||
await ui.start()
|
||||
@@ -48,12 +49,13 @@ async def test_ask_question_simple(mock_input):
|
||||
|
||||
await ui.stop()
|
||||
|
||||
mock_input.assert_called_once()
|
||||
prompt_async.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("builtins.input", return_value="yes")
|
||||
async def test_ask_question_with_buttons(mock_input):
|
||||
@patch("core.ui.console.PromptSession")
|
||||
async def test_ask_question_with_buttons(mock_PromptSession):
|
||||
prompt_async = mock_PromptSession.return_value.prompt_async = AsyncMock(return_value="yes")
|
||||
ui = PlainConsoleUI()
|
||||
|
||||
await ui.start()
|
||||
@@ -68,12 +70,13 @@ async def test_ask_question_with_buttons(mock_input):
|
||||
|
||||
await ui.stop()
|
||||
|
||||
mock_input.assert_called_once()
|
||||
prompt_async.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("builtins.input", side_effect=KeyboardInterrupt())
|
||||
async def test_ask_question_interrupted(mock_input):
|
||||
@patch("core.ui.console.PromptSession")
|
||||
async def test_ask_question_interrupted(mock_PromptSession):
|
||||
prompt_async = mock_PromptSession.return_value.prompt_async = AsyncMock(side_effect=KeyboardInterrupt)
|
||||
ui = PlainConsoleUI()
|
||||
|
||||
await ui.start()
|
||||
@@ -82,4 +85,4 @@ async def test_ask_question_interrupted(mock_input):
|
||||
|
||||
await ui.stop()
|
||||
|
||||
mock_input.assert_called_once()
|
||||
prompt_async.assert_awaited_once()
|
||||
|
||||
Reference in New Issue
Block a user