From e2e0c6b93adaeb112bfc142b5bc0f8ecfa579b74 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Mon, 18 Dec 2023 09:17:32 +0800 Subject: [PATCH 1/6] add ide service and group ui --- libs/ide_services/__init__.py | 4 +-- libs/ide_services/services.py | 13 +++++++++ libs/ui_utils/__init__.py | 11 +++++--- libs/ui_utils/group.py | 28 +++++++++++++++++++ libs/ui_utils/iobase.py | 1 + libs/ui_utils/multi_selections.py | 41 +++++++++++++++------------- libs/ui_utils/single_select.py | 39 ++++++++++++++------------- libs/ui_utils/text_edit.py | 45 ++++++++++++++++++------------- 8 files changed, 121 insertions(+), 61 deletions(-) create mode 100644 libs/ui_utils/group.py diff --git a/libs/ide_services/__init__.py b/libs/ide_services/__init__.py index 73ddb1b..d1bbe1f 100644 --- a/libs/ide_services/__init__.py +++ b/libs/ide_services/__init__.py @@ -1,3 +1,3 @@ -from .services import get_lsp_brige_port +from .services import get_lsp_brige_port, install_python_env, update_slash_commands, open_folder -__all__ = ["get_lsp_brige_port"] +__all__ = ["get_lsp_brige_port", "install_python_env", "update_slash_commands", "open_folder"] diff --git a/libs/ide_services/services.py b/libs/ide_services/services.py index d836fd7..5ad2fac 100644 --- a/libs/ide_services/services.py +++ b/libs/ide_services/services.py @@ -1,5 +1,6 @@ import requests import os +import json from functools import wraps BASE_SERVER_URL = os.environ.get("DEVCHAT_IDE_SERVICE_URL", "http://localhost:3000") @@ -31,3 +32,15 @@ def wrapper(*args, **kwargs): @rpc_call def get_lsp_brige_port(): pass + +@rpc_call +def install_python_env(command_name: str, requirements_file: str) -> str: + pass + +@rpc_call +def update_slash_commands(): + pass + +@rpc_call +def open_folder(folder: str): + pass diff --git a/libs/ui_utils/__init__.py b/libs/ui_utils/__init__.py index f32af2c..1a41de1 100644 --- a/libs/ui_utils/__init__.py +++ b/libs/ui_utils/__init__.py @@ -1,7 +1,8 @@ from .iobase import parse_response_from_ui, pipe_interaction, pipe_interaction_mock -from .multi_selections import ui_checkbox_select, CheckboxOption -from .single_select import ui_radio_select, RadioOption -from .text_edit import ui_text_edit +from .multi_selections import ui_checkbox_select, CheckboxOption, make_checkbox_control +from .single_select import ui_radio_select, RadioOption, make_radio_control +from .text_edit import ui_text_edit, make_editor_control +from .group import ui_group __all__ = [ @@ -13,4 +14,8 @@ "ui_text_edit", "CheckboxOption", "RadioOption", + "make_checkbox_control", + "make_radio_control", + "make_editor_control", + "ui_group" ] diff --git a/libs/ui_utils/group.py b/libs/ui_utils/group.py new file mode 100644 index 0000000..0e7b321 --- /dev/null +++ b/libs/ui_utils/group.py @@ -0,0 +1,28 @@ +from typing import List, Tuple + +from .iobase import pipe_interaction +from .multi_selections import checkbox_answer +from .single_select import radio_answer +from .text_edit import editor_answer + + +def ui_group(ui_message: List[Tuple]) -> Tuple: + """ + ui_message: List[Tuple] + [ + ("editor", "editor ui message", "editor_id"), + ("checkbox", "checkbox ui message", ["id1", "id2"]), + ("radio", "radio ui message", ["id1", "id2"]), + ] + """ + ui_message = "\n".join([m[1] for m in ui_message]) + with open('tmp.txt', 'w+', encoding="utf8") as file: + file.write(ui_message) + response = pipe_interaction(ui_message) + return tuple([ + editor_answer(response, m[2]) if m[0] == "editor" else + checkbox_answer(response, m[2]) if m[0] == "checkbox" else + radio_answer(response, m[2]) if m[0] == "radio" else + None + for m in ui_message + ]) diff --git a/libs/ui_utils/iobase.py b/libs/ui_utils/iobase.py index 4721421..c060eef 100644 --- a/libs/ui_utils/iobase.py +++ b/libs/ui_utils/iobase.py @@ -52,6 +52,7 @@ def pipe_interaction(output: str): while True: try: line = input() + print("--> input:", line) if line.strip().startswith("```yaml"): lines = [] elif line.strip() == "```": diff --git a/libs/ui_utils/multi_selections.py b/libs/ui_utils/multi_selections.py index 0015b75..be7ca9a 100644 --- a/libs/ui_utils/multi_selections.py +++ b/libs/ui_utils/multi_selections.py @@ -12,16 +12,7 @@ def __init__(self, id, text, group: str = None, checked: bool = False): self._checked = checked -def ui_checkbox_select(title: str, options: List[CheckboxOption]) -> List[str]: - """ - send text to UI as: - ```chatmark - Which files would you like to commit? I've suggested a few. - > [x](file1) devchat/engine/prompter.py - > [x](file2) devchat/prompt.py - > [](file3) tests/test_cli_prompt.py - ``` - """ +def make_checkbox_control(title: str, options: List[CheckboxOption]) -> (str, str, List[str]): _NT = "\n" groups = list({option._group: 1 for option in options if option._group}.keys()) @@ -35,18 +26,30 @@ def _check_option_group_message(group): return f"{group}:{_NT}{s}" ui_message = f""" -```chatmark type=form {title} {_NT.join([_check_option_group_message(group) for group in groups])} -``` """ + return ('checkbox', ui_message, [option._id for option in options]) + + +def checkbox_answer(response: dict, ids: List[str]) -> List[str]: + return [key for key, value in response.items() if value == "checked" and key in ids] + + +def ui_checkbox_select(title: str, options: List[CheckboxOption]) -> List[str]: + """ + send text to UI as: + ```chatmark + Which files would you like to commit? I've suggested a few. + > [x](file1) devchat/engine/prompter.py + > [x](file2) devchat/prompt.py + > [](file3) tests/test_cli_prompt.py + ``` + """ + _1, ui_message, ids = make_checkbox_control(title, options) + ui_message = f"""```chatmark type=form\n{ui_message}\n```\n""" + # print(ui_message) # return [option._id for option in options] response = pipe_interaction(ui_message) - - selected_options = [ - key - for key, value in response.items() - if value == "checked" and key in [option._id for option in options] - ] - return selected_options + return checkbox_answer(response, ids) diff --git a/libs/ui_utils/single_select.py b/libs/ui_utils/single_select.py index b27c91f..fcf2b3d 100644 --- a/libs/ui_utils/single_select.py +++ b/libs/ui_utils/single_select.py @@ -10,32 +10,33 @@ def __init__(self, id, text): self._text = text -def ui_radio_select(title: str, options: List[RadioOption]) -> str | None: - """ - ```chatmark type=form - How would you like to make the change? - > - (insert) Insert the new code. - > - (new) Put the code in a new file. - > - (replace) Replace the current code. - ``` - """ - +def make_radio_control(title: str, options: List[RadioOption]) -> (str, str, List[str]): def _option_line(option): return f"> - ({option._id}) {option._text}" options_lines = "\n".join([_option_line(option) for option in options]) ui_message = f""" -```chatmark type=form {title} {options_lines} -``` """ + return ('radio', ui_message, [option._id for option in options]) - response = pipe_interaction(ui_message) - selected_options = [ - key - for key, value in response.items() - if value == "checked" and key in [option._id for option in options] - ] - return selected_options[0] if len(selected_options) > 0 else None +def radio_answer(response: dict, ids: List[str]) -> str | None: + selected_options = [key for key, value in response.items() if value == "checked" and key in ids] + return selected_options[0] if selected_options else None + + +def ui_radio_select(title: str, options: List[RadioOption]) -> str | None: + """ + ```chatmark type=form + How would you like to make the change? + > - (insert) Insert the new code. + > - (new) Put the code in a new file. + > - (replace) Replace the current code. + ``` + """ + _1, ui_message, ids = make_radio_control(title, options) + ui_message = f"""```chatmark type=form\n{ui_message}\n```\n""" + response = pipe_interaction(ui_message) + return radio_answer(response, ids) diff --git a/libs/ui_utils/text_edit.py b/libs/ui_utils/text_edit.py index 491fe24..c70b756 100644 --- a/libs/ui_utils/text_edit.py +++ b/libs/ui_utils/text_edit.py @@ -1,6 +1,29 @@ from .iobase import pipe_interaction +def make_editor_control(editor_id: str, title: str, text: str) -> (str, str, str): + text_lines = text.strip().split("\n") + if len(text_lines) > 0 and text_lines[0].strip().startswith("```"): + text_lines = text_lines[1:] + if len(text_lines) > 0 and text_lines[-1].strip() == "```": + text_lines = text_lines[:-1] + text = "\n".join(text_lines) + text = text.replace("\n", "\n> ") + ui_message = f""" +{title} + +> | ({editor_id}) +> {text} +""" + return ('editor', ui_message, editor_id) + + +def editor_answer(response: dict, editor_id: str) -> str | None: + if editor_id in response: + return response[editor_id] + return None + + def ui_text_edit(title: str, text: str) -> str | None: """ ```chatmark type=form @@ -16,22 +39,8 @@ def ui_text_edit(title: str, text: str) -> str | None: > Refs: #123 ``` """ - text_lines = text.strip().split("\n") - if len(text_lines) > 0 and text_lines[0].strip().startswith("```"): - text_lines = text_lines[1:] - if len(text_lines) > 0 and text_lines[-1].strip() == "```": - text_lines = text_lines[:-1] - text = "\n".join(text_lines) - text = text.replace("\n", "\n> ") - ui_message = f""" -```chatmark type=form -{title} - -> | (editor0) -> {text} -``` -""" + _1, ui_message, editor_id = make_editor_control("editor0", title, text) + ui_message = f"""```chatmark type=form\n{ui_message}\n```\n""" response = pipe_interaction(ui_message) - if "editor0" in response: - return response["editor0"] - return None + return editor_answer(response, editor_id) + From 63ca9b4140219b598c3de1ec16865c97d03028f0 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Mon, 18 Dec 2023 09:17:32 +0800 Subject: [PATCH 2/6] Remove unnecessary print statement in pipe_interaction function --- libs/ui_utils/iobase.py | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/ui_utils/iobase.py b/libs/ui_utils/iobase.py index c060eef..4721421 100644 --- a/libs/ui_utils/iobase.py +++ b/libs/ui_utils/iobase.py @@ -52,7 +52,6 @@ def pipe_interaction(output: str): while True: try: line = input() - print("--> input:", line) if line.strip().startswith("```yaml"): lines = [] elif line.strip() == "```": From 2b74ea0822eed0f1582c24fdcf8557dfddd95510 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Mon, 18 Dec 2023 09:17:32 +0800 Subject: [PATCH 3/6] reformat --- libs/ide_services/services.py | 4 +++- libs/ui_utils/__init__.py | 2 +- libs/ui_utils/group.py | 21 ++++++++++++--------- libs/ui_utils/multi_selections.py | 2 +- libs/ui_utils/single_select.py | 2 +- libs/ui_utils/text_edit.py | 3 +-- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/libs/ide_services/services.py b/libs/ide_services/services.py index 5ad2fac..c6a029a 100644 --- a/libs/ide_services/services.py +++ b/libs/ide_services/services.py @@ -1,6 +1,5 @@ import requests import os -import json from functools import wraps BASE_SERVER_URL = os.environ.get("DEVCHAT_IDE_SERVICE_URL", "http://localhost:3000") @@ -33,14 +32,17 @@ def wrapper(*args, **kwargs): def get_lsp_brige_port(): pass + @rpc_call def install_python_env(command_name: str, requirements_file: str) -> str: pass + @rpc_call def update_slash_commands(): pass + @rpc_call def open_folder(folder: str): pass diff --git a/libs/ui_utils/__init__.py b/libs/ui_utils/__init__.py index 1a41de1..d5a27b3 100644 --- a/libs/ui_utils/__init__.py +++ b/libs/ui_utils/__init__.py @@ -17,5 +17,5 @@ "make_checkbox_control", "make_radio_control", "make_editor_control", - "ui_group" + "ui_group", ] diff --git a/libs/ui_utils/group.py b/libs/ui_utils/group.py index 0e7b321..7c2b96c 100644 --- a/libs/ui_utils/group.py +++ b/libs/ui_utils/group.py @@ -16,13 +16,16 @@ def ui_group(ui_message: List[Tuple]) -> Tuple: ] """ ui_message = "\n".join([m[1] for m in ui_message]) - with open('tmp.txt', 'w+', encoding="utf8") as file: - file.write(ui_message) response = pipe_interaction(ui_message) - return tuple([ - editor_answer(response, m[2]) if m[0] == "editor" else - checkbox_answer(response, m[2]) if m[0] == "checkbox" else - radio_answer(response, m[2]) if m[0] == "radio" else - None - for m in ui_message - ]) + return tuple( + [ + editor_answer(response, m[2]) + if m[0] == "editor" + else checkbox_answer(response, m[2]) + if m[0] == "checkbox" + else radio_answer(response, m[2]) + if m[0] == "radio" + else None + for m in ui_message + ] + ) diff --git a/libs/ui_utils/multi_selections.py b/libs/ui_utils/multi_selections.py index be7ca9a..f406279 100644 --- a/libs/ui_utils/multi_selections.py +++ b/libs/ui_utils/multi_selections.py @@ -29,7 +29,7 @@ def _check_option_group_message(group): {title} {_NT.join([_check_option_group_message(group) for group in groups])} """ - return ('checkbox', ui_message, [option._id for option in options]) + return ("checkbox", ui_message, [option._id for option in options]) def checkbox_answer(response: dict, ids: List[str]) -> List[str]: diff --git a/libs/ui_utils/single_select.py b/libs/ui_utils/single_select.py index fcf2b3d..5dd4bc5 100644 --- a/libs/ui_utils/single_select.py +++ b/libs/ui_utils/single_select.py @@ -19,7 +19,7 @@ def _option_line(option): {title} {options_lines} """ - return ('radio', ui_message, [option._id for option in options]) + return ("radio", ui_message, [option._id for option in options]) def radio_answer(response: dict, ids: List[str]) -> str | None: diff --git a/libs/ui_utils/text_edit.py b/libs/ui_utils/text_edit.py index c70b756..a93b2b1 100644 --- a/libs/ui_utils/text_edit.py +++ b/libs/ui_utils/text_edit.py @@ -15,7 +15,7 @@ def make_editor_control(editor_id: str, title: str, text: str) -> (str, str, str > | ({editor_id}) > {text} """ - return ('editor', ui_message, editor_id) + return ("editor", ui_message, editor_id) def editor_answer(response: dict, editor_id: str) -> str | None: @@ -43,4 +43,3 @@ def ui_text_edit(title: str, text: str) -> str | None: ui_message = f"""```chatmark type=form\n{ui_message}\n```\n""" response = pipe_interaction(ui_message) return editor_answer(response, editor_id) - From 2cf1b0305b76dcfad98afb3a6ee644f61517b0e2 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Mon, 18 Dec 2023 09:24:09 +0800 Subject: [PATCH 4/6] Refactor UI group function --- libs/ui_utils/group.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/libs/ui_utils/group.py b/libs/ui_utils/group.py index 7c2b96c..751d6c1 100644 --- a/libs/ui_utils/group.py +++ b/libs/ui_utils/group.py @@ -14,18 +14,21 @@ def ui_group(ui_message: List[Tuple]) -> Tuple: ("checkbox", "checkbox ui message", ["id1", "id2"]), ("radio", "radio ui message", ["id1", "id2"]), ] + + items in ui_message are created by functions like:make_checkbox_control """ ui_message = "\n".join([m[1] for m in ui_message]) response = pipe_interaction(ui_message) - return tuple( - [ - editor_answer(response, m[2]) - if m[0] == "editor" - else checkbox_answer(response, m[2]) - if m[0] == "checkbox" - else radio_answer(response, m[2]) - if m[0] == "radio" - else None - for m in ui_message - ] - ) + + results = [] + for m in ui_message: + if m[0] == "editor": + result = editor_answer(response, m[2]) + elif m[0] == "checkbox": + result = checkbox_answer(response, m[2]) + elif m[0] == "radio": + result = radio_answer(response, m[2]) + else: + result = None + results.append(result) + return tuple(results) From 1e8cb3f6f65cb1e0d81cc565cb6be1e8e7812932 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Mon, 18 Dec 2023 19:45:26 +0800 Subject: [PATCH 5/6] Update ui_group function in group.py --- libs/ui_utils/group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ui_utils/group.py b/libs/ui_utils/group.py index 751d6c1..927619c 100644 --- a/libs/ui_utils/group.py +++ b/libs/ui_utils/group.py @@ -14,7 +14,7 @@ def ui_group(ui_message: List[Tuple]) -> Tuple: ("checkbox", "checkbox ui message", ["id1", "id2"]), ("radio", "radio ui message", ["id1", "id2"]), ] - + items in ui_message are created by functions like:make_checkbox_control """ ui_message = "\n".join([m[1] for m in ui_message]) From d2aaa486302ed4821604499fb33d8f95b75516f2 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Mon, 18 Dec 2023 21:03:21 +0800 Subject: [PATCH 6/6] Refactor ui_group function to format ui_message as a chatmark form --- libs/ui_utils/group.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/ui_utils/group.py b/libs/ui_utils/group.py index 927619c..6183fb8 100644 --- a/libs/ui_utils/group.py +++ b/libs/ui_utils/group.py @@ -17,8 +17,10 @@ def ui_group(ui_message: List[Tuple]) -> Tuple: items in ui_message are created by functions like:make_checkbox_control """ - ui_message = "\n".join([m[1] for m in ui_message]) - response = pipe_interaction(ui_message) + ui_message_str = "\n".join([m[1] for m in ui_message]) + + ui_message_str = f"""```chatmark type=form\n{ui_message_str}\n```\n""" + response = pipe_interaction(ui_message_str) results = [] for m in ui_message: