Skip to content

Commit a04a35e

Browse files
committed
exposed flask server to invoke agent
1 parent add5336 commit a04a35e

File tree

12 files changed

+154
-47
lines changed

12 files changed

+154
-47
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ primaryClass={cs.AI},
8888
url={https://arxiv.org/abs/2408.07199},
8989
}
9090

91+
```
92+
```
93+
@inproceedings{yao2022webshop,
94+
bibtex_show = {true},
95+
title = {WebShop: Towards Scalable Real-World Web Interaction with Grounded Language Agents},
96+
author = {Yao, Shunyu and Chen, Howard and Yang, John and Narasimhan, Karthik},
97+
booktitle = {ArXiv},
98+
year = {preprint},
99+
html = {https://arxiv.org/abs/2207.01206},
100+
tag = {NLP}
101+
}
91102
```
92103
93104
```

agentq/__main__.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import asyncio
22

3+
from playwright.async_api import Page
4+
35
from agentq.core.agent.agentq import AgentQ
46
from agentq.core.agent.agentq_actor import AgentQActor
57
from agentq.core.agent.agentq_critic import AgentQCritic
@@ -8,17 +10,36 @@
810
from agentq.core.models.models import State
911
from agentq.core.orchestrator.orchestrator import Orchestrator
1012

13+
state_to_agent_map = {
14+
State.PLAN: PlannerAgent(),
15+
State.BROWSE: BrowserNavAgent(),
16+
State.AGENTQ_BASE: AgentQ(),
17+
State.AGENTQ_ACTOR: AgentQActor(),
18+
State.AGENTQ_CRITIC: AgentQCritic(),
19+
}
20+
21+
22+
async def run_agent(command):
23+
orchestrator = Orchestrator(state_to_agent_map=state_to_agent_map, eval_mode=True)
24+
await orchestrator.start()
25+
page: Page = await orchestrator.playwright_manager.get_current_page()
26+
await page.set_extra_http_headers({"User-Agent": "AgentQ-Bot"})
27+
await page.goto("https://686b-49-205-35-248.ngrok-free.app/abc", timeout=30000)
28+
result = await orchestrator.execute_command(command)
29+
return result
1130

12-
async def main():
13-
# Define state machine
14-
state_to_agent_map = {
15-
State.PLAN: PlannerAgent(),
16-
State.BROWSE: BrowserNavAgent(),
17-
State.AGENTQ_BASE: AgentQ(),
18-
State.AGENTQ_ACTOR: AgentQActor(),
19-
State.AGENTQ_CRITIC: AgentQCritic(),
20-
}
2131

32+
def run_agent_sync(command):
33+
if asyncio.get_event_loop().is_closed():
34+
loop = asyncio.new_event_loop()
35+
asyncio.set_event_loop(loop)
36+
else:
37+
loop = asyncio.get_event_loop()
38+
39+
return loop.run_until_complete(run_agent(command))
40+
41+
42+
async def main():
2243
orchestrator = Orchestrator(state_to_agent_map=state_to_agent_map)
2344
await orchestrator.start()
2445

agentq/core/agent/agentq.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def __modify_system_prompt(self, ltm):
2929
system_prompt: str = LLM_PROMPTS["AGENTQ_BASE_PROMPT"]
3030

3131
substitutions = {
32-
"basic_user_information": ltm if ltm is not None else "",
32+
"task_information": ltm if ltm is not None else "",
3333
}
3434

3535
# Use safe_substitute to avoid KeyError

agentq/core/orchestrator/orchestrator.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def __init__(
4949
self.eval_mode = eval_mode
5050
self.shutdown_event = asyncio.Event()
5151
self.session_id = str(uuid.uuid4())
52+
self.memory = None
5253

5354
async def start(self):
5455
print("Starting orchestrator")
@@ -95,9 +96,12 @@ async def execute_command(self, command: str):
9596
current_tasks_for_eval=None,
9697
sorted_tasks=None,
9798
)
99+
# Get the current event loop
100+
loop = asyncio.get_event_loop()
101+
98102
print(f"Executing command {self.memory.objective}")
99103
while self.memory.current_state != State.COMPLETED:
100-
await self._handle_state()
104+
await loop.create_task(self._handle_state())
101105
self._print_final_response()
102106

103107
if self.eval_mode:

agentq/core/prompts/prompts.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ class BrowserNavOutput(BaseModel):
185185
4. If the task requires multiple informations, all of them are equally important and should be gathered before terminating the task. You will strive to meet all the requirements of the task.
186186
5. If one plan fails, you MUST revise the plan and try a different approach. You will NOT terminate a task untill you are absolutely convinced that the task is impossible to accomplish.
187187
6. Think critically if the task has been actually been achieved before doing the final termination.
188+
7. Make sure to take into account task sepcific information.
188189
189190
## Web Navigation guidelines ##
190191
1. Based on the actions you output, web navigation will be done, which may include logging into websites and interacting with any web content
@@ -245,7 +246,7 @@ class BrowserNavOutput(BaseModel):
245246
246247
Notice above how there is confirmation after each step and how interaction (e.g. setting source and destination) with each element is a separate step. Follow same pattern.
247248
248-
Some basic information about the user: \n $basic_user_information
249+
Some task sepcific information that you MUST take into account: \n $task_information
249250
250251
## SOME VERY IMPORTANT POINTS TO ALWAYS REMEMBER ##
251252
1. NEVER ASK WHAT TO DO NEXT or HOW would you like to proceed to the user.

agentq/core/skills/open_url.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ async def openurl(
4040
try:
4141
await browser_manager.take_screenshots(f"{function_name}_start", page)
4242

43+
# set extra headers for bypassing ngrok
44+
await page.set_extra_http_headers({"User-Agent": "AgentQ-Sentient"})
45+
4346
# Use a longer timeout for navigation
4447
await page.goto(
4548
url, timeout=max(30000, timeout * 1000), wait_until="domcontentloaded"

agentq/core/web_driver/playwright.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,14 +270,11 @@ async def get_current_page(self) -> Page:
270270
page: Page = await browser.new_page() # type: ignore
271271
# await stealth_async(page) # Apply stealth to the new page
272272
return page
273-
except Exception as e:
274-
logger.warn(f"Browser context was closed. Creating a new one. {e}")
275273
except Exception as e:
276274
logger.warn(f"Browser context was closed. Creating a new one. {e}")
277275
PlaywrightManager._browser_context = None
278-
_browser: BrowserContext = await self.get_browser_context() # type: ignore
279-
page: Union[Page, None] = await self.get_current_page()
280-
return page
276+
await self.ensure_browser_context()
277+
return await self.get_current_page()
281278

282279
async def close_all_tabs(self, keep_first_tab: bool = True):
283280
"""
Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,7 @@
1-
Personal Info:
2-
First Name: Nischal
3-
Last Name: Jain
4-
Date of birth:
5-
Pronouns: He/Him
6-
7-
Email:
8-
Expeted Salary: 5000000
9-
Occupation: Data Engineer
10-
Address: Indiranagr, Bengaluru
11-
Phone Number:
12-
LinkedIn - https://linkedin.com/in/nischalj10
13-
14-
15-
Here are some of my preferences:
16-
Shopping Preferences: www.amazon.com
17-
Favorite news source: www.thehindu.com
18-
Favorite flight booking site to use with every flight related query: https://www.google.com/travel/flightsno
19-
Resume File to Upload Path = /Users/namanjain/Downloads/DummyResume.pdf
20-
My best project - checkout headless-ollama on google
21-
22-
23-
I am comfortable commuting to office.
24-
I have 4 years of experience in TypeScript, Node Js, Nextjs.
25-
I have work authorization for working in the USA.
26-
I have experience in cloud infrastructure, data warheouses.
1+
1. Your job is to find the relevant product asked by the user on a locally hosted ecommerce website https://686b-49-205-35-248.ngrok-free.app
2+
2. Your search query should be small and should only have important keywords. In general, you should try to checkout the first couple of results shown in the search results.
3+
3. Remember, a lot of custom filters like size, color, flavour, quantity etc are only available on the product page and the product title in search page may not exactly fit requirements but can loosely relate to the search query - so checkout first couple of search results that match most closely.
4+
Eg - you are asked to buy strawberry biscuits from birtannia - but when you search britannia strawberry biscuits, you get search reuslt with chocloate flavoured britannia buiscuits. You should still click on it as there could be an option on the product page to change falvour from chocolate to strawberry because the brand is same and the product is same "braitannia and buiscuits"
5+
4. If you do not find the relevant product in first couple of search results pages, you should go back to the search page and try to search with a different query.
6+
5. Make sure to pay attention to all the attributes like size/ color/ quantity etc. mentioned in the user's query and select appropriate attributes on the product details page before buying it.
7+
6. Ultimately - your task will only end when you click on the "Buy Now" button of the right product.

poetry.lock

Lines changed: 62 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ tabulate = "^0.9.0"
2727
nltk = "^3.9.1"
2828
langsmith = "^0.1.104"
2929
instructor = "^1.4.0"
30+
flask = "^3.0.3"
3031
numpy = "^2.1.0"
3132

3233

0 commit comments

Comments
 (0)