From 7ea2239e1038b4a94b16492b9a3b9a592ac8bd16 Mon Sep 17 00:00:00 2001 From: yadonglu Date: Tue, 28 Jan 2025 21:33:58 -0800 Subject: [PATCH] add drop down for omni output in the chat; add args for app.py; --- .gitignore | 1 + demo/gradio/app.py | 59 ++++++++++++------ demo/gradio/computer_use_demo/loop.py | 2 +- .../omniparser_agent/vlm_agent.py | 12 +++- demo/remote_request.py | 41 +++++++++--- util/__pycache__/__init__.cpython-312.pyc | Bin 139 -> 0 bytes util/__pycache__/__init__.cpython-39.pyc | Bin 141 -> 0 bytes .../action_matching.cpython-39.pyc | Bin 8488 -> 0 bytes .../__pycache__/box_annotator.cpython-312.pyc | Bin 9804 -> 0 bytes util/__pycache__/box_annotator.cpython-39.pyc | Bin 6574 -> 0 bytes 10 files changed, 86 insertions(+), 29 deletions(-) delete mode 100644 util/__pycache__/__init__.cpython-312.pyc delete mode 100644 util/__pycache__/__init__.cpython-39.pyc delete mode 100644 util/__pycache__/action_matching.cpython-39.pyc delete mode 100644 util/__pycache__/box_annotator.cpython-312.pyc delete mode 100644 util/__pycache__/box_annotator.cpython-39.pyc diff --git a/.gitignore b/.gitignore index 2ad14a7..40c4d8c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ weights/icon_detect_v1_5_2/ .gradio __pycache__/ debug.ipynb +util/__pycache__/ diff --git a/demo/gradio/app.py b/demo/gradio/app.py index 842738f..d005c49 100644 --- a/demo/gradio/app.py +++ b/demo/gradio/app.py @@ -1,5 +1,6 @@ """ Entrypoint for Gradio, see https://gradio.app/ +python app.py --windows_host_url xxxx:8006/ --omniparser_host_url localhost:8000 """ import platform @@ -15,6 +16,7 @@ from pathlib import Path from typing import cast, Dict from PIL import Image import socket +import argparse import gradio as gr from anthropic import APIResponse @@ -39,6 +41,18 @@ Welcome to the OmniParser+X Demo! X = [GPT-4o/4o-mini, Claude, Phi, Llama]. Let Type a message and press submit to start OmniParser+X. Press the trash icon in the chat to clear the message history. ''' +def parse_arguments(): + parser = argparse.ArgumentParser(description="Gradio App") + parser.add_argument("--windows_host_url", type=str, default='GCRSANDBOX336.redmond.corp.microsoft.com:8006/') # http://gcrsandbox336.redmond.corp.microsoft.com/ + parser.add_argument("--omniparser_host_url", type=str, default="localhost:8000") + return parser.parse_args() +args = parse_arguments() +windows_host_url = args.windows_host_url +omniparser_host_url = args.omniparser_host_url +print(f"Windows host URL: {windows_host_url}") +print(f"OmniParser host URL: {omniparser_host_url}") + + class Sender(StrEnum): USER = "user" BOT = "assistant" @@ -68,8 +82,8 @@ def setup_state(state): state["only_n_most_recent_images"] = 2 if 'chatbot_messages' not in state: state['chatbot_messages'] = [] - if "omniparser_url" not in state: - state["omniparser_url"] = "localhost:8000" + # if "omniparser_url" not in state: + # state["omniparser_url"] = "localhost:8000" async def main(state): """Render loop for Gradio""" @@ -211,7 +225,7 @@ def process_input(user_input, state): api_response_callback=partial(_api_response_callback, response_state=state["responses"]), api_key=state["api_key"], only_n_most_recent_images=state["only_n_most_recent_images"], - omniparser_url=state["omniparser_url"] + omniparser_url=omniparser_host_url #state["omniparser_url"] ): if loop_msg is None: yield state['chatbot_messages'] @@ -275,13 +289,13 @@ with gr.Blocks(theme=gr.themes.Default()) as demo: placeholder="Paste your API key here", interactive=True, ) - with gr.Row(): - omniparser_url = gr.Textbox( - label="OmniParser Base URL", - value="localhost:8000", - placeholder="Enter OmniParser base URL (e.g. localhost:8000)", - interactive=True - ) + # with gr.Row(): + # omniparser_url = gr.Textbox( + # label="OmniParser Base URL", + # value="localhost:8000", + # placeholder="Enter OmniParser base URL (e.g. localhost:8000)", + # interactive=True + # ) # hide_images = gr.Checkbox(label="Hide screenshots", value=False) with gr.Row(): @@ -294,11 +308,20 @@ with gr.Blocks(theme=gr.themes.Default()) as demo: with gr.Column(scale=1): chatbot = gr.Chatbot(label="Chatbot History", autoscroll=True, height=580) with gr.Column(scale=3): - iframe = gr.HTML( - f'', - container=False, - elem_classes="no-padding" - ) + if not windows_host_url: + iframe = gr.HTML( + f'', + container=False, + elem_classes="no-padding" + ) + else: + # machine_fqdn = socket.getfqdn() + # print('machine_fqdn:', machine_fqdn) + iframe = gr.HTML( + f'', + container=False, + elem_classes="no-padding" + ) def update_model(model_selection, state): state["model"] = model_selection @@ -350,8 +373,8 @@ with gr.Blocks(theme=gr.themes.Default()) as demo: state["api_key"] = api_key_value state[f'{state["provider"]}_api_key'] = api_key_value - def update_omniparser_url(url_value, state): - state["omniparser_url"] = url_value + # def update_omniparser_url(url_value, state): + # state["omniparser_url"] = url_value def clear_chat(state): # Reset message-related state @@ -365,7 +388,7 @@ with gr.Blocks(theme=gr.themes.Default()) as demo: only_n_images.change(fn=update_only_n_images, inputs=[only_n_images, state], outputs=None) provider.change(fn=update_provider, inputs=[provider, state], outputs=api_key) api_key.change(fn=update_api_key, inputs=[api_key, state], outputs=None) - omniparser_url.change(fn=update_omniparser_url, inputs=[omniparser_url, state], outputs=None) + # omniparser_url.change(fn=update_omniparser_url, inputs=[omniparser_url, state], outputs=None) chatbot.clear(fn=clear_chat, inputs=[state], outputs=[chatbot]) submit_button.click(process_input, [chat_input, state], chatbot) diff --git a/demo/gradio/computer_use_demo/loop.py b/demo/gradio/computer_use_demo/loop.py index c4129e5..c400ec4 100644 --- a/demo/gradio/computer_use_demo/loop.py +++ b/demo/gradio/computer_use_demo/loop.py @@ -52,7 +52,7 @@ def sampling_loop_sync( Synchronous agentic sampling loop for the assistant/tool interaction of computer use. """ print('in sampling_loop_sync, model:', model) - omniparser = OmniParser(url=f"http://{omniparser_url}/send_text/" if omniparser_url and omniparser_url != "localhost:8000" else None) + omniparser = OmniParser(url=f"http://{omniparser_url}/send_text/" if omniparser_url else None) if model == "claude-3-5-sonnet-20241022": # Register Actor and Executor actor = AnthropicActor( diff --git a/demo/gradio/computer_use_demo/omniparser_agent/vlm_agent.py b/demo/gradio/computer_use_demo/omniparser_agent/vlm_agent.py index 92a7901..35f57c9 100644 --- a/demo/gradio/computer_use_demo/omniparser_agent/vlm_agent.py +++ b/demo/gradio/computer_use_demo/omniparser_agent/vlm_agent.py @@ -132,7 +132,15 @@ class VLMAgent: sender="bot") self.output_callback(f'Set of Marks Screenshot for {colorful_text_vlm}:\n', sender="bot") screen_info = str(parsed_screen['screen_info']) - self.output_callback(f'Screen Info for {colorful_text_vlm}:\n{screen_info}', sender="bot") + # self.output_callback(f'Screen Info for {colorful_text_vlm}:\n{screen_info}', sender="bot") + self.output_callback( + f'
' + f' Screen Info for {colorful_text_vlm}' + f'
{screen_info}
' + f'
', + sender="bot" + ) + screenshot_uuid = parsed_screen['screenshot_uuid'] screen_width, screen_height = parsed_screen['width'], parsed_screen['height'] @@ -155,7 +163,7 @@ class VLMAgent: planner_messages[-1]["content"].append(f"{OUTPUT_DIR}/screenshot_{screenshot_uuid}.png") planner_messages[-1]["content"].append(f"{OUTPUT_DIR}/screenshot_som_{screenshot_uuid}.png") - print(f"Sending messages to VLMPlanner : {planner_messages}") + # print(f"Sending messages to VLMPlanner : {planner_messages}") start = time.time() if "gpt" in self.model: vlm_response, token_usage = run_oai_interleaved( diff --git a/demo/remote_request.py b/demo/remote_request.py index 84dd3a9..7efafc3 100644 --- a/demo/remote_request.py +++ b/demo/remote_request.py @@ -1,4 +1,7 @@ # uvicorn remote_request:app --host 0.0.0.0 --port 8000 --reload +''' +python -m remote_request --som_model_path ../weights/icon_detect_v1_5/model_v1_5.pt --caption_model_name florence2 --caption_model_path ../weights/icon_detect_v1_5/model_v1_5.pt --device cuda --BOX_TRESHOLD 0.05 +''' import sys import os @@ -12,14 +15,31 @@ import base64 import io from fastapi import FastAPI from pydantic import BaseModel +import argparse -config = { - 'som_model_path': '../weights/icon_detect_v1_5/model_v1_5.pt', - 'device': 'cpu', - 'caption_model_name': 'florence2', - 'caption_model_path': '../weights/icon_caption_florence', - 'BOX_TRESHOLD': 0.05 -} +def parse_arguments(): + parser = argparse.ArgumentParser(description='Omniparser API') + parser.add_argument('--som_model_path', type=str, default='../weights/icon_detect_v1_5/model_v1_5.pt', help='Path to the som model') + parser.add_argument('--caption_model_name', type=str, default='florence2', help='Name of the caption model') + parser.add_argument('--caption_model_path', type=str, default='../weights/icon_caption_florence', help='Path to the caption model') + parser.add_argument('--device', type=str, default='cpu', help='Device to run the model') + parser.add_argument('--BOX_TRESHOLD', type=float, default=0.05, help='Threshold for box detection') + parser.add_argument('--host', type=str, default='0.0.0.0', help='Host for the API') + parser.add_argument('--port', type=int, default=8000, help='Port for the API') + args = parser.parse_args() + return args + +args = parse_arguments() +config = vars(args) + + +# config = { +# 'som_model_path': '../weights/icon_detect_v1_5/model_v1_5.pt', +# 'device': 'cpu', +# 'caption_model_name': 'florence2', +# 'caption_model_path': '../weights/icon_caption_florence', +# 'BOX_TRESHOLD': 0.05 +# } class Omniparser(object): @@ -74,4 +94,9 @@ async def send_text(item: Item): @app.get("/") async def root(): - return {"message": "Omniparser API ready"} \ No newline at end of file + return {"message": "Omniparser API ready"} + + +if __name__ == "__main__": + import uvicorn + uvicorn.run("remote_request:app", host=args.host, port=args.port, reload=True) \ No newline at end of file diff --git a/util/__pycache__/__init__.cpython-312.pyc b/util/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 9b6f52fbf85e2793f881cd3d4747d3b9130804d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 zcmX@j%ge<81lN+a(n0iN5P=Rpvj9b=GgLBYGWxA#C}INgK7-W!($de!&rQ{@Oiano zOV26Q_s`AC3`i_0PA$?eEy>K$kB`sH%PfhH*DI*}#bJ}1pHiBWYFESx)XE6N#URE< MW=2NFB4!{90N|@1ssI20 diff --git a/util/__pycache__/__init__.cpython-39.pyc b/util/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 9cb17e37edf94f1366173f0a6e7038e1d38e5dc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141 zcmYe~<>g`kg4Iudrh(|kAOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yUSe{fzwFRQ<}t zl>EH(oKpSb#JrTG{0e>l+`PNVBK^{m%pCpr_{_Y_lK6PNg34PQHo5sJr8%i~ KAhSLLF#`a32O(Vm diff --git a/util/__pycache__/action_matching.cpython-39.pyc b/util/__pycache__/action_matching.cpython-39.pyc deleted file mode 100644 index aac34478fcbeb2ca038358193b812f79105e0398..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8488 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 MFRI_LE?Ud~1147ly#N3J diff --git a/util/__pycache__/box_annotator.cpython-312.pyc b/util/__pycache__/box_annotator.cpython-312.pyc deleted file mode 100644 index 0b3df348534c65ee34374cb01718be25e1b64a6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9804 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 U^xj8a7rpDz)*+gnrU~u;0cdJ=oB#j- diff --git a/util/__pycache__/box_annotator.cpython-39.pyc b/util/__pycache__/box_annotator.cpython-39.pyc deleted file mode 100644 index c0919431598f60e80ad4221965b42389a35b8484..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6574 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