|
|
import json |
|
|
import os |
|
|
import sys |
|
|
|
|
|
import requests |
|
|
|
|
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
|
|
|
|
|
import asyncio |
|
|
|
|
|
from dotenv import load_dotenv |
|
|
from langchain_openai import ChatOpenAI |
|
|
from pydantic import BaseModel |
|
|
|
|
|
from browser_use import ActionResult, Agent, Controller |
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
|
|
|
class Person(BaseModel): |
|
|
name: str |
|
|
email: str | None = None |
|
|
|
|
|
|
|
|
class PersonList(BaseModel): |
|
|
people: list[Person] |
|
|
|
|
|
|
|
|
controller = Controller(exclude_actions=['search_google'], output_model=PersonList) |
|
|
BEARER_TOKEN = os.getenv('BEARER_TOKEN') |
|
|
|
|
|
if not BEARER_TOKEN: |
|
|
|
|
|
|
|
|
raise ValueError('BEARER_TOKEN is not set - go to https://www.heytessa.ai/ and create an api key') |
|
|
|
|
|
|
|
|
@controller.registry.action('Search the web for a specific query') |
|
|
async def search_web(query: str): |
|
|
keys_to_use = ['url', 'title', 'content', 'author', 'score'] |
|
|
headers = {'Authorization': f'Bearer {BEARER_TOKEN}'} |
|
|
response = requests.post('https://asktessa.ai/api/search', headers=headers, json={'query': query}) |
|
|
|
|
|
final_results = [ |
|
|
{key: source[key] for key in keys_to_use if key in source} |
|
|
for source in response.json()['sources'] |
|
|
if source['score'] >= 0.8 |
|
|
] |
|
|
|
|
|
result_text = json.dumps(final_results, indent=4) |
|
|
print(result_text) |
|
|
return ActionResult(extracted_content=result_text, include_in_memory=True) |
|
|
|
|
|
|
|
|
names = [ |
|
|
'Ruedi Aebersold', |
|
|
'Bernd Bodenmiller', |
|
|
'Eugene Demler', |
|
|
'Erich Fischer', |
|
|
'Pietro Gambardella', |
|
|
'Matthias Huss', |
|
|
'Reto Knutti', |
|
|
'Maksym Kovalenko', |
|
|
'Antonio Lanzavecchia', |
|
|
'Maria Lukatskaya', |
|
|
'Jochen Markard', |
|
|
'Javier Pérez-Ramírez', |
|
|
'Federica Sallusto', |
|
|
'Gisbert Schneider', |
|
|
'Sonia I. Seneviratne', |
|
|
'Michael Siegrist', |
|
|
'Johan Six', |
|
|
'Tanja Stadler', |
|
|
'Shinichi Sunagawa', |
|
|
'Michael Bruce Zimmermann', |
|
|
] |
|
|
|
|
|
|
|
|
async def main(): |
|
|
task = 'use search_web with "find email address of the following ETH professor:" for each of the following persons in a list of actions. Finally return the list with name and email if provided' |
|
|
task += '\n' + '\n'.join(names) |
|
|
model = ChatOpenAI(model='gpt-4o') |
|
|
agent = Agent(task=task, llm=model, controller=controller, max_actions_per_step=20) |
|
|
|
|
|
history = await agent.run() |
|
|
|
|
|
result = history.final_result() |
|
|
if result: |
|
|
parsed: PersonList = PersonList.model_validate_json(result) |
|
|
|
|
|
for person in parsed.people: |
|
|
print(f'{person.name} - {person.email}') |
|
|
else: |
|
|
print('No result') |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
asyncio.run(main()) |
|
|
|