From 0cd477a3f9682ae3e1ac25c12cdda2a76aaf0ad9 Mon Sep 17 00:00:00 2001 From: Fangyin Cheng Date: Wed, 27 Mar 2024 09:46:17 +0800 Subject: [PATCH] feat: Run AWEL flow with interactive mode --- dbgpt/client/_cli.py | 123 +++++++++++++----- dbgpt/util/console/console.py | 4 + i18n/locales/fr/LC_MESSAGES/dbgpt_client.po | 27 ++-- i18n/locales/ja/LC_MESSAGES/dbgpt_client.po | 27 ++-- i18n/locales/ko/LC_MESSAGES/dbgpt_client.po | 27 ++-- i18n/locales/ru/LC_MESSAGES/dbgpt_client.po | 27 ++-- .../locales/zh_CN/LC_MESSAGES/dbgpt_client.mo | Bin 1285 -> 1393 bytes .../locales/zh_CN/LC_MESSAGES/dbgpt_client.po | 28 ++-- 8 files changed, 171 insertions(+), 92 deletions(-) diff --git a/dbgpt/client/_cli.py b/dbgpt/client/_cli.py index 4d9f222f6..78fc4e23d 100644 --- a/dbgpt/client/_cli.py +++ b/dbgpt/client/_cli.py @@ -3,6 +3,7 @@ import functools import json import time +import uuid from typing import Any, Dict import click @@ -107,6 +108,15 @@ def add_chat_options(func): required=False, help=_("The extra json data to run AWEL flow."), ) + @click.option( + "-i", + "--interactive", + type=bool, + default=False, + required=False, + is_flag=True, + help=_("Whether use interactive mode to run AWEL flow"), + ) @functools.wraps(func) def _wrapper(*args, **kwargs): return func(*args, **kwargs) @@ -117,7 +127,7 @@ def _wrapper(*args, **kwargs): @click.command(name="flow") @add_base_flow_options @add_chat_options -def run_flow(name: str, uid: str, data: str, **kwargs): +def run_flow(name: str, uid: str, data: str, interactive: bool, **kwargs): """Run a AWEL flow.""" client = Client() @@ -134,9 +144,9 @@ def run_flow(name: str, uid: str, data: str, **kwargs): json_data["chat_mode"] = "chat_flow" stream = "stream" in json_data and str(json_data["stream"]).lower() in ["true", "1"] if stream: - loop.run_until_complete(_chat_stream(client, json_data)) + loop.run_until_complete(_chat_stream(client, interactive, json_data)) else: - loop.run_until_complete(_chat(client, json_data)) + loop.run_until_complete(_chat(client, interactive, json_data)) def _parse_json_data(data: str, **kwargs): @@ -160,36 +170,77 @@ def _parse_json_data(data: str, **kwargs): return json_data -async def _chat_stream(client: Client, json_data: Dict[str, Any]): - start_time = time.time() - try: - cl.info("Chat stream started") - cl.info(f"JSON data: {json.dumps(json_data, ensure_ascii=False)}") - full_text = "" - async for out in client.chat_stream(**json_data): - if out.choices: - text = out.choices[0].delta.content - if text: - full_text += text - cl.print(text, end="") - end_time = time.time() - time_cost = round(end_time - start_time, 2) - - cl.success(f"\n:tada: Chat stream finished, timecost: {time_cost} s") - except Exception as e: - cl.error(f"Chat stream failed: {e}", exit_code=1) - - -async def _chat(client: Client, json_data: Dict[str, Any]): - start_time = time.time() - try: - cl.info("Chat started") - cl.info(f"JSON data: {json.dumps(json_data, ensure_ascii=False)}") - res = await client.chat(**json_data) - if res.choices: - text = res.choices[0].message.content - cl.markdown(text) - time_cost = round(time.time() - start_time, 2) - cl.success(f"\n:tada: Chat stream finished, timecost: {time_cost} s") - except Exception as e: - cl.error(f"Chat failed: {e}", exit_code=1) +async def _chat_stream(client: Client, interactive: bool, json_data: Dict[str, Any]): + user_input = json_data.get("messages", "") + if "conv_uid" not in json_data and interactive: + json_data["conv_uid"] = str(uuid.uuid4()) + first_message = True + while True: + try: + if interactive and not user_input: + cl.print("Type 'exit' or 'quit' to exit.") + while not user_input: + user_input = cl.ask("You") + if user_input.lower() in ["exit", "quit", "q"]: + break + start_time = time.time() + json_data["messages"] = user_input + if first_message: + cl.info("You: " + user_input) + cl.info("Chat stream started") + cl.debug(f"JSON data: {json.dumps(json_data, ensure_ascii=False)}") + full_text = "" + cl.print("Bot: ") + async for out in client.chat_stream(**json_data): + if out.choices: + text = out.choices[0].delta.content + if text: + full_text += text + cl.print(text, end="") + end_time = time.time() + time_cost = round(end_time - start_time, 2) + cl.success(f"\n:tada: Chat stream finished, timecost: {time_cost} s") + except Exception as e: + cl.error(f"Chat stream failed: {e}", exit_code=1) + finally: + first_message = False + if interactive: + user_input = "" + else: + break + + +async def _chat(client: Client, interactive: bool, json_data: Dict[str, Any]): + user_input = json_data.get("messages", "") + if "conv_uid" not in json_data and interactive: + json_data["conv_uid"] = str(uuid.uuid4()) + first_message = True + while True: + try: + if interactive and not user_input: + cl.print("Type 'exit' or 'quit' to exit.") + while not user_input: + user_input = cl.ask("You") + if user_input.lower() in ["exit", "quit", "q"]: + break + start_time = time.time() + json_data["messages"] = user_input + if first_message: + cl.info("You: " + user_input) + + cl.info("Chat started") + cl.debug(f"JSON data: {json.dumps(json_data, ensure_ascii=False)}") + res = await client.chat(**json_data) + if res.choices: + text = res.choices[0].message.content + cl.markdown(text) + time_cost = round(time.time() - start_time, 2) + cl.success(f"\n:tada: Chat stream finished, timecost: {time_cost} s") + except Exception as e: + cl.error(f"Chat failed: {e}", exit_code=1) + finally: + first_message = False + if interactive: + user_input = "" + else: + break diff --git a/dbgpt/util/console/console.py b/dbgpt/util/console/console.py index 4d7f96004..709a2e91a 100644 --- a/dbgpt/util/console/console.py +++ b/dbgpt/util/console/console.py @@ -6,6 +6,7 @@ from rich.console import Console from rich.markdown import Markdown +from rich.prompt import Prompt from rich.theme import Theme @@ -65,3 +66,6 @@ def print(self, *objects: Any, sep: str = " ", end: str = "\n", **kwargs): def markdown(self, msg: str, **kwargs): md = Markdown(msg) self.console.print(md, **kwargs) + + def ask(self, msg: str, **kwargs): + return Prompt.ask(msg, **kwargs) diff --git a/i18n/locales/fr/LC_MESSAGES/dbgpt_client.po b/i18n/locales/fr/LC_MESSAGES/dbgpt_client.po index d184d4045..0515cdab3 100644 --- a/i18n/locales/fr/LC_MESSAGES/dbgpt_client.po +++ b/i18n/locales/fr/LC_MESSAGES/dbgpt_client.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-27 03:37+0800\n" +"POT-Creation-Date: 2024-03-27 09:43+0800\n" "PO-Revision-Date: 2024-03-27 03:21+0800\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -18,54 +18,59 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ../dbgpt/client/_cli.py:29 +#: ../dbgpt/client/_cli.py:30 #, fuzzy msgid "The name of the AWEL flow" msgstr "Le nom du flux" -#: ../dbgpt/client/_cli.py:36 +#: ../dbgpt/client/_cli.py:37 #, fuzzy msgid "The uid of the AWEL flow" msgstr "L'UID du flux" -#: ../dbgpt/client/_cli.py:54 +#: ../dbgpt/client/_cli.py:55 #, fuzzy msgid "The messages to run AWEL flow" msgstr "Les messages du flux" -#: ../dbgpt/client/_cli.py:61 +#: ../dbgpt/client/_cli.py:62 #, fuzzy msgid "The model name of AWEL flow" msgstr "Le modèle du flux" -#: ../dbgpt/client/_cli.py:70 +#: ../dbgpt/client/_cli.py:71 msgid "Whether use stream mode to run AWEL flow" msgstr "" -#: ../dbgpt/client/_cli.py:78 +#: ../dbgpt/client/_cli.py:79 #, fuzzy msgid "The temperature to run AWEL flow" msgstr "La température du flux" -#: ../dbgpt/client/_cli.py:85 +#: ../dbgpt/client/_cli.py:86 #, fuzzy msgid "The max new tokens to run AWEL flow" msgstr "Le nombre maximal de nouveaux tokens du flux" -#: ../dbgpt/client/_cli.py:92 +#: ../dbgpt/client/_cli.py:93 #, fuzzy msgid "The conversation id of the AWEL flow" msgstr "L'identifiant de conversation du flux" -#: ../dbgpt/client/_cli.py:100 +#: ../dbgpt/client/_cli.py:101 msgid "The json data to run AWEL flow, if set, will overwrite other options" msgstr "" -#: ../dbgpt/client/_cli.py:108 +#: ../dbgpt/client/_cli.py:109 #, fuzzy msgid "The extra json data to run AWEL flow." msgstr "Les données JSON supplémentaires du flux" +#: ../dbgpt/client/_cli.py:118 +#, fuzzy +msgid "Whether use interactive mode to run AWEL flow" +msgstr "La température du flux" + #~ msgid "Whether to stream the flow, default is False" #~ msgstr "Indique si le flux doit être diffusé en continu, par défaut False" diff --git a/i18n/locales/ja/LC_MESSAGES/dbgpt_client.po b/i18n/locales/ja/LC_MESSAGES/dbgpt_client.po index db744a94a..a959b0415 100644 --- a/i18n/locales/ja/LC_MESSAGES/dbgpt_client.po +++ b/i18n/locales/ja/LC_MESSAGES/dbgpt_client.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-27 03:37+0800\n" +"POT-Creation-Date: 2024-03-27 09:43+0800\n" "PO-Revision-Date: 2024-03-27 03:21+0800\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -18,54 +18,59 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../dbgpt/client/_cli.py:29 +#: ../dbgpt/client/_cli.py:30 #, fuzzy msgid "The name of the AWEL flow" msgstr "フローの名前" -#: ../dbgpt/client/_cli.py:36 +#: ../dbgpt/client/_cli.py:37 #, fuzzy msgid "The uid of the AWEL flow" msgstr "フローのUID" -#: ../dbgpt/client/_cli.py:54 +#: ../dbgpt/client/_cli.py:55 #, fuzzy msgid "The messages to run AWEL flow" msgstr "フローのメッセージ" -#: ../dbgpt/client/_cli.py:61 +#: ../dbgpt/client/_cli.py:62 #, fuzzy msgid "The model name of AWEL flow" msgstr "フローのモデル" -#: ../dbgpt/client/_cli.py:70 +#: ../dbgpt/client/_cli.py:71 msgid "Whether use stream mode to run AWEL flow" msgstr "" -#: ../dbgpt/client/_cli.py:78 +#: ../dbgpt/client/_cli.py:79 #, fuzzy msgid "The temperature to run AWEL flow" msgstr "フローの温度" -#: ../dbgpt/client/_cli.py:85 +#: ../dbgpt/client/_cli.py:86 #, fuzzy msgid "The max new tokens to run AWEL flow" msgstr "フローの最大新トークン数" -#: ../dbgpt/client/_cli.py:92 +#: ../dbgpt/client/_cli.py:93 #, fuzzy msgid "The conversation id of the AWEL flow" msgstr "フローの会話ID" -#: ../dbgpt/client/_cli.py:100 +#: ../dbgpt/client/_cli.py:101 msgid "The json data to run AWEL flow, if set, will overwrite other options" msgstr "" -#: ../dbgpt/client/_cli.py:108 +#: ../dbgpt/client/_cli.py:109 #, fuzzy msgid "The extra json data to run AWEL flow." msgstr "フローの追加のJSONデータ" +#: ../dbgpt/client/_cli.py:118 +#, fuzzy +msgid "Whether use interactive mode to run AWEL flow" +msgstr "フローの温度" + #~ msgid "Whether to stream the flow, default is False" #~ msgstr "フローをストリーミングするかどうか、デフォルトはFalse" diff --git a/i18n/locales/ko/LC_MESSAGES/dbgpt_client.po b/i18n/locales/ko/LC_MESSAGES/dbgpt_client.po index 5896acb60..46df88396 100644 --- a/i18n/locales/ko/LC_MESSAGES/dbgpt_client.po +++ b/i18n/locales/ko/LC_MESSAGES/dbgpt_client.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-27 03:37+0800\n" +"POT-Creation-Date: 2024-03-27 09:43+0800\n" "PO-Revision-Date: 2024-03-27 03:21+0800\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -18,54 +18,59 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../dbgpt/client/_cli.py:29 +#: ../dbgpt/client/_cli.py:30 #, fuzzy msgid "The name of the AWEL flow" msgstr "플로우의 이름" -#: ../dbgpt/client/_cli.py:36 +#: ../dbgpt/client/_cli.py:37 #, fuzzy msgid "The uid of the AWEL flow" msgstr "플로우의 UID" -#: ../dbgpt/client/_cli.py:54 +#: ../dbgpt/client/_cli.py:55 #, fuzzy msgid "The messages to run AWEL flow" msgstr "플로우의 메시지" -#: ../dbgpt/client/_cli.py:61 +#: ../dbgpt/client/_cli.py:62 #, fuzzy msgid "The model name of AWEL flow" msgstr "플로우의 모델" -#: ../dbgpt/client/_cli.py:70 +#: ../dbgpt/client/_cli.py:71 msgid "Whether use stream mode to run AWEL flow" msgstr "" -#: ../dbgpt/client/_cli.py:78 +#: ../dbgpt/client/_cli.py:79 #, fuzzy msgid "The temperature to run AWEL flow" msgstr "플로우의 온도" -#: ../dbgpt/client/_cli.py:85 +#: ../dbgpt/client/_cli.py:86 #, fuzzy msgid "The max new tokens to run AWEL flow" msgstr "플로우의 최대 새 토큰" -#: ../dbgpt/client/_cli.py:92 +#: ../dbgpt/client/_cli.py:93 #, fuzzy msgid "The conversation id of the AWEL flow" msgstr "플로우의 대화 ID" -#: ../dbgpt/client/_cli.py:100 +#: ../dbgpt/client/_cli.py:101 msgid "The json data to run AWEL flow, if set, will overwrite other options" msgstr "" -#: ../dbgpt/client/_cli.py:108 +#: ../dbgpt/client/_cli.py:109 #, fuzzy msgid "The extra json data to run AWEL flow." msgstr "플로우의 추가 JSON 데이터" +#: ../dbgpt/client/_cli.py:118 +#, fuzzy +msgid "Whether use interactive mode to run AWEL flow" +msgstr "플로우의 온도" + #~ msgid "Whether to stream the flow, default is False" #~ msgstr "플로우를 스트리밍할지 여부, 기본값은 False" diff --git a/i18n/locales/ru/LC_MESSAGES/dbgpt_client.po b/i18n/locales/ru/LC_MESSAGES/dbgpt_client.po index 603b8b7c1..8ccaa75d2 100644 --- a/i18n/locales/ru/LC_MESSAGES/dbgpt_client.po +++ b/i18n/locales/ru/LC_MESSAGES/dbgpt_client.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-27 03:37+0800\n" +"POT-Creation-Date: 2024-03-27 09:43+0800\n" "PO-Revision-Date: 2024-03-27 03:21+0800\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -19,54 +19,59 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ../dbgpt/client/_cli.py:29 +#: ../dbgpt/client/_cli.py:30 #, fuzzy msgid "The name of the AWEL flow" msgstr "Имя потока" -#: ../dbgpt/client/_cli.py:36 +#: ../dbgpt/client/_cli.py:37 #, fuzzy msgid "The uid of the AWEL flow" msgstr "UID потока" -#: ../dbgpt/client/_cli.py:54 +#: ../dbgpt/client/_cli.py:55 #, fuzzy msgid "The messages to run AWEL flow" msgstr "Сообщения потока" -#: ../dbgpt/client/_cli.py:61 +#: ../dbgpt/client/_cli.py:62 #, fuzzy msgid "The model name of AWEL flow" msgstr "Модель потока" -#: ../dbgpt/client/_cli.py:70 +#: ../dbgpt/client/_cli.py:71 msgid "Whether use stream mode to run AWEL flow" msgstr "" -#: ../dbgpt/client/_cli.py:78 +#: ../dbgpt/client/_cli.py:79 #, fuzzy msgid "The temperature to run AWEL flow" msgstr "Температура потока" -#: ../dbgpt/client/_cli.py:85 +#: ../dbgpt/client/_cli.py:86 #, fuzzy msgid "The max new tokens to run AWEL flow" msgstr "Максимальное количество новых токенов потока" -#: ../dbgpt/client/_cli.py:92 +#: ../dbgpt/client/_cli.py:93 #, fuzzy msgid "The conversation id of the AWEL flow" msgstr "Идентификатор беседы потока" -#: ../dbgpt/client/_cli.py:100 +#: ../dbgpt/client/_cli.py:101 msgid "The json data to run AWEL flow, if set, will overwrite other options" msgstr "" -#: ../dbgpt/client/_cli.py:108 +#: ../dbgpt/client/_cli.py:109 #, fuzzy msgid "The extra json data to run AWEL flow." msgstr "Дополнительные JSON-данные потока" +#: ../dbgpt/client/_cli.py:118 +#, fuzzy +msgid "Whether use interactive mode to run AWEL flow" +msgstr "Температура потока" + #~ msgid "Whether to stream the flow, default is False" #~ msgstr "Потоковая передача, по умолчанию False" diff --git a/i18n/locales/zh_CN/LC_MESSAGES/dbgpt_client.mo b/i18n/locales/zh_CN/LC_MESSAGES/dbgpt_client.mo index 46705858d78f7af523964bc4b919a2ea62934ae0..d581af0f52988f5d21de5ab0f439a065d023e084 100644 GIT binary patch delta 284 zcmZqW`p8v(Pl#nI0}${4u?!H`0I?tt-vMF}P+(+WPyy14Kw1?@y8&qzAe{rGm4Wm| zAT0}|uL5alApIFgO9E+rCZJv*tqG(hfV3Bo)&_23fQgNQ(pM(@^opKw1>YXJUm|AOWO7`rKG2 zo-$+P+04io$0(keSCU$km|T)sma34OpOUIjlCMxynzz}5X&w{LlU+-m?3(m!#lok1 O`X>jlh)%xAq5}Z%jjy#C3yb|f4!w?5J!a26_jCH(Y72g=(7h4!; zkunaki!-$J)>sjVB+iKRXf3ozhH?a-2MNrSmb>}KcAX?%5jNP3zeL7 JtPj&{^9Skp7~%i` diff --git a/i18n/locales/zh_CN/LC_MESSAGES/dbgpt_client.po b/i18n/locales/zh_CN/LC_MESSAGES/dbgpt_client.po index 2a7dfb16e..d0ed3f10a 100644 --- a/i18n/locales/zh_CN/LC_MESSAGES/dbgpt_client.po +++ b/i18n/locales/zh_CN/LC_MESSAGES/dbgpt_client.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-27 03:37+0800\n" +"POT-Creation-Date: 2024-03-27 09:43+0800\n" "PO-Revision-Date: 2024-03-27 03:21+0800\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,42 +17,46 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../dbgpt/client/_cli.py:29 +#: ../dbgpt/client/_cli.py:30 msgid "The name of the AWEL flow" msgstr "AWEL 工作流的名称" -#: ../dbgpt/client/_cli.py:36 +#: ../dbgpt/client/_cli.py:37 msgid "The uid of the AWEL flow" msgstr "AWEL 工作流的 UID" -#: ../dbgpt/client/_cli.py:54 +#: ../dbgpt/client/_cli.py:55 msgid "The messages to run AWEL flow" msgstr "运行 AWEL 工作流的消息" -#: ../dbgpt/client/_cli.py:61 +#: ../dbgpt/client/_cli.py:62 msgid "The model name of AWEL flow" msgstr "AWEL 工作流的模型名称" -#: ../dbgpt/client/_cli.py:70 +#: ../dbgpt/client/_cli.py:71 msgid "Whether use stream mode to run AWEL flow" msgstr "是否使用流模式运行 AWEL 工作流" -#: ../dbgpt/client/_cli.py:78 +#: ../dbgpt/client/_cli.py:79 msgid "The temperature to run AWEL flow" msgstr "运行 AWEL 工作流的温度" -#: ../dbgpt/client/_cli.py:85 +#: ../dbgpt/client/_cli.py:86 msgid "The max new tokens to run AWEL flow" msgstr "运行 AWEL 工作流的最大新标记数" -#: ../dbgpt/client/_cli.py:92 +#: ../dbgpt/client/_cli.py:93 msgid "The conversation id of the AWEL flow" msgstr "AWEL 工作流的对话 ID" -#: ../dbgpt/client/_cli.py:100 +#: ../dbgpt/client/_cli.py:101 msgid "The json data to run AWEL flow, if set, will overwrite other options" msgstr "用于运行 AWEL 工作流的 JSON 数据,如果设置,将覆盖其他选项" -#: ../dbgpt/client/_cli.py:108 +#: ../dbgpt/client/_cli.py:109 msgid "The extra json data to run AWEL flow." -msgstr "用于运行 AWEL 工作流的额外 JSON 数据" \ No newline at end of file +msgstr "用于运行 AWEL 工作流的额外 JSON 数据" + +#: ../dbgpt/client/_cli.py:118 +msgid "Whether use interactive mode to run AWEL flow" +msgstr "是否使用交互模式运行 AWEL 工作流" \ No newline at end of file