Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
3457a87
start a fetch models type feature
adubatl Feb 20, 2025
1b10fc5
put the smart quotes back in
adubatl Feb 20, 2025
ddf08a0
put the imports back in my linter is BROKEN lmao
adubatl Feb 20, 2025
692b85b
add test script for model fetch, and some custom handling for models
adubatl Feb 20, 2025
d1cb209
replace inquirer with a better lib (mostly just to understand the cli…
adubatl Feb 20, 2025
eb36ae1
Merge branch 'main' into adubatl/model_fetching_PoC
adubatl Feb 22, 2025
067935b
ensure tests all run on a windows machine
adubatl Feb 22, 2025
54c106e
add caveat to all models, remove limiting providers to the ones I pic…
adubatl Feb 22, 2025
574d8d7
smaller fix for undoing the awkward assign but dont use
adubatl Feb 22, 2025
fc84956
remove changes to run, though there is an unused import
adubatl Feb 22, 2025
7b953d0
pull some formatting changes
adubatl Feb 22, 2025
9ada5cb
add defaulting functionality to questionary implementation
adubatl Feb 23, 2025
c7cfb9b
Rename AgentQL tool
desi003 Feb 27, 2025
04e62b7
Merge pull request #339 from desi003/update-agentql-tool-name
bboynton97 Mar 4, 2025
aaf3200
Update text
desi003 Mar 4, 2025
558fa55
Add examples
desi003 Mar 4, 2025
2501e81
Merge branch 'main' into update-agentql-page
desi003 Mar 5, 2025
a019d26
Merge pull request #341 from desi003/update-agentql-page
bboynton97 Mar 5, 2025
146fc2c
merge main
adubatl Mar 7, 2025
e00f418
Merge branch 'main' into adubatl/model_fetching_PoC
adubatl Mar 7, 2025
9989edb
Add market monitoring example
desi003 Mar 7, 2025
4fef0f1
Update READMEs
desi003 Mar 7, 2025
ff8a175
Edit market monitoring example
desi003 Mar 7, 2025
308f87b
Merge pull request #342 from desi003/update-agentql-examples
bboynton97 Mar 7, 2025
f7abfe3
Merge branch 'main' into adubatl/model_fetching_PoC
bboynton97 Mar 7, 2025
309e3fa
Update description and arguments
desi003 Mar 10, 2025
bd59f14
Add new example
desi003 Mar 10, 2025
c56df43
Merge branch 'main' into update-agentql-page
desi003 Mar 18, 2025
12ec250
Set origin request in headers
desi003 Mar 18, 2025
846c799
Add stealth mode
desi003 Mar 21, 2025
88f6054
Rename stealth mode param
desi003 Mar 21, 2025
45f7d67
Add stealth mode argument
desi003 Mar 21, 2025
7f52774
Merge pull request #345 from desi003/add-stealth-agentql
tcdent Apr 1, 2025
6c919b0
Merge pull request #344 from desi003/set-request-origin-agentql
tcdent Apr 1, 2025
437db17
Merge pull request #343 from desi003/update-agentql-page
tcdent Apr 1, 2025
5846b53
Add hyperbrowser tools
shrisukhani Apr 2, 2025
ca0becd
add docs
shrisukhani Apr 2, 2025
87d4d63
Init AgentMail tool
Haakam21 Apr 9, 2025
b0832da
Complete tools
Haakam21 Apr 11, 2025
c3f3a74
Update docs
Haakam21 Apr 11, 2025
062b38c
Fix
Haakam21 Apr 11, 2025
38de84f
add dappier search tool
amaan-ai20 Apr 27, 2025
ccda75d
add an example for stock market researcher using dappier real time data
amaan-ai20 May 1, 2025
edb3692
update inputs.yaml
amaan-ai20 May 1, 2025
5819471
add tesla investment report as an example
amaan-ai20 May 1, 2025
bb12c85
fine tune the prompt to get latest news and stock prices
amaan-ai20 May 1, 2025
20aa461
use current utc time
amaan-ai20 May 1, 2025
e9dd89a
Undo formatting
Haakam21 May 1, 2025
a503287
Merge pull request #348 from Haakam21/agentmail-tool
bboynton97 May 1, 2025
abd1b01
Merge branch 'main' into add-dappier-search-tool
amaan-ai20 May 2, 2025
71e5b8c
update deps
bboynton97 May 5, 2025
12f02c9
version bump
bboynton97 May 5, 2025
0cd6eaa
Merge branch 'main' into add-dappier-search-tool
bboynton97 May 5, 2025
9e383c7
Merge pull request #346 from shrisukhani/feat-add-hyperbrowser-tools
bboynton97 May 5, 2025
56741a5
Merge branch 'main' into adubatl/model_fetching_PoC
bboynton97 May 5, 2025
a793d4e
Merge pull request #351 from amaan-ai20/add-dappier-search-tool
bboynton97 May 5, 2025
6483f7a
Merge branch 'main' into adubatl/model_fetching_PoC
bboynton97 May 5, 2025
d388e06
nullish coalescing
bboynton97 May 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions agentstack/_tools/agentmail/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
from agentmail import AgentMail
from typing import Optional, List


client = AgentMail()


def list_inboxes(limit: Optional[int] = None, last_key: Optional[str] = None):
"""
List inboxes.

Args:
limit: The maximum number of inboxes to return.
last_key: The last key returned from the previous page.

Returns:
A list of inboxes.
"""
return client.inboxes.list(limit=limit, last_key=last_key)


def get_inbox(inbox_id: str):
"""
Get an inbox by ID.

Args:
inbox_id: The ID of the inbox to get.

Returns:
An inbox.
"""
return client.inboxes.get(inbox_id)


def create_inbox(
username: Optional[str] = None,
domain: Optional[str] = None,
display_name: Optional[str] = None,
):
"""
Create an inbox.

Args:
username: The username of the inbox.
domain: The domain of the inbox.
display_name: The display name of the inbox.

Returns:
An inbox.
"""
return client.inboxes.create(
username=username, domain=domain, display_name=display_name
)


def list_threads(
inbox_id: str, limit: Optional[int] = None, last_key: Optional[str] = None
):
"""
List threads in an inbox.

Args:
inbox_id: The ID of the inbox to list threads for.
limit: The maximum number of threads to return.
last_key: The last key returned from the previous page.

Returns:
A list of threads.
"""
return client.threads.list(inbox_id=inbox_id, limit=limit, last_key=last_key)


def get_thread(inbox_id: str, thread_id: str):
"""
Get a thread by ID.

Args:
inbox_id: The ID of the inbox to get the thread for.
thread_id: The ID of the thread to get.

Returns:
A thread.
"""
return client.threads.get(inbox_id=inbox_id, thread_id=thread_id)


def list_messages(
inbox_id: str, limit: Optional[int] = None, last_key: Optional[str] = None
):
"""
List messages in an inbox.

Args:
inbox_id: The ID of the inbox to list messages for.
limit: The maximum number of messages to return.
last_key: The last key returned from the previous page.

Returns:
A list of messages.
"""
return client.messages.list(inbox_id=inbox_id, limit=limit, last_key=last_key)


def get_message(inbox_id: str, message_id: str):
"""
Get a message by ID.

Args:
inbox_id: The ID of the inbox to get the message for.
message_id: The ID of the message to get.

Returns:
A message.
"""
return client.messages.get(inbox_id=inbox_id, message_id=message_id)


def get_attachment(inbox_id: str, message_id: str, attachment_id: str):
"""
Get an attachment by message ID and attachment ID.

Args:
inbox_id: The ID of the inbox to get the attachment for.
message_id: The ID of the message to get the attachment for.
attachment_id: The ID of the attachment to get.

Returns:
An attachment.
"""
return client.messages.get_attachment(
inbox_id=inbox_id, message_id=message_id, attachment_id=attachment_id
)


def send_message(
inbox_id: str,
to: List[str],
cc: Optional[List[str]] = None,
bcc: Optional[List[str]] = None,
subject: Optional[str] = None,
text: Optional[str] = None,
html: Optional[str] = None,
):
"""
Send a message.

Args:
inbox_id: The ID of the inbox to send the message from.
to: The list of recipients.
cc: The list of CC recipients.
bcc: The list of BCC recipients.
subject: The subject of the message.
text: The plain text body of the message.
html: The HTML body of the message.

Returns:
A message.
"""
return client.messages.send(
inbox_id=inbox_id, to=to, cc=cc, bcc=bcc, subject=subject, text=text, html=html
)


def reply_to_message(
inbox_id: str,
message_id: str,
text: Optional[str] = None,
html: Optional[str] = None,
):
"""
Reply to a message.

Args:
inbox_id: The ID of the inbox to reply to the message in.
message_id: The ID of the message to reply to.
text: The plain text body of the reply.
html: The HTML body of the reply.

Returns:
A message.
"""
return client.messages.reply(
inbox_id=inbox_id, message_id=message_id, text=text, html=html
)
13 changes: 13 additions & 0 deletions agentstack/_tools/agentmail/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "agentmail",
"category": "email",
"tools": ["list_inboxes", "get_inbox", "create_inbox", "list_threads", "get_thread", "list_messages", "get_message", "get_attachment", "send_message", "reply_to_message"],
"url": "https://agentmail.to",
"cta": "Get your AgentMail API key at https://agentmail.to",
"env": {
"AGENTMAIL_API_KEY": null
},
"dependencies": [
"agentmail>=0.0.19"
]
}
32 changes: 24 additions & 8 deletions agentstack/_tools/agentql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@

API_KEY = os.getenv("AGENTQL_API_KEY")

def query_data(url: str, query: Optional[str], prompt: Optional[str]) -> dict:

def extract_data(
url: str,
query: Optional[str],
prompt: Optional[str],
is_stealth_mode_enabled: bool = False,
) -> dict:
"""
url: url of website to scrape
query: described below
prompt: Natural language description of the data you want to scrape

is_stealth_mode_enabled: Enable stealth mode for web scraping (default: False)

AgentQL query to scrape the url.

Expand Down Expand Up @@ -47,34 +53,44 @@ def query_data(url: str, query: Optional[str], prompt: Optional[str]) -> dict:
payload = {
"url": url,
"query": query,
"prompt": prompt
"prompt": prompt,
"metadata": {
"experimental_stealth_mode_enabled": is_stealth_mode_enabled,
},
}

headers = {
"X-API-Key": f"{API_KEY}",
"Content-Type": "application/json"
"Content-Type": "application/json",
"X-TF-Request-Origin": "agentstack",
}

try:
response = httpx.post(
QUERY_DATA_ENDPOINT,
headers=headers,
json=payload,
timeout=API_TIMEOUT_SECONDS
timeout=API_TIMEOUT_SECONDS,
)
response.raise_for_status()

except httpx.HTTPStatusError as e:
response = e.response
if response.status_code in [401, 403]:
raise ValueError("Please, provide a valid API Key. You can create one at https://dev.agentql.com.") from e
raise ValueError(
"Please, provide a valid API Key. You can create one at https://dev.agentql.com."
) from e
else:
try:
error_json = response.json()
msg = error_json["error_info"] if "error_info" in error_json else error_json["detail"]
msg = (
error_json["error_info"]
if "error_info" in error_json
else error_json["detail"]
)
except (ValueError, TypeError):
msg = f"HTTP {e}."
raise ValueError(msg) from e
else:
json = response.json()
return json["data"]
return json["data"]
2 changes: 1 addition & 1 deletion agentstack/_tools/agentql/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"env": {
"AGENTQL_API_KEY": "..."
},
"tools": ["query_data"],
"tools": ["extract_data"],
"cta": "Create your AgentQL API key at https://dev.agentql.com"
}
Loading