Commit graph

188 commits

Author SHA1 Message Date
Nate Barbettini
e46b985cc9
fix: Typo in Sqrt tool description (#378) 2025-04-23 10:28:12 -03:00
Renato Byrro
3e35c70f85
Update Hubspot toolkit to use Hubspot auth class (#375) 2025-04-22 21:55:39 -03:00
Renato Byrro
9346498edb
Fix google type errors (#376) 2025-04-22 21:26:45 -03:00
Renato Byrro
de227c5f51
Hubspot toolkit (#363)
Reviewer:

1. DM me to get a client ID/secret for the Hubspot app and login
credentials for a sample Hubspot account
2. For now, you'll need to run the engine on the branch
`nate/token-introspection` for the auth flow to work with Hubspot
3. Add the following to `auth.providers` in your engine yaml:

```yaml
- id: arcade-hubspot
  description: 'Hubspot provider'
  enabled: true
  type: oauth2
  provider_id: hubspot
  client_id: ${env:HUBSPOT_CLIENT_ID}
  client_secret: ${env:HUBSPOT_CLIENT_SECRET}
```
2025-04-22 17:43:15 -03:00
Renato Byrro
52807bfd0e
Update Salesforce provider id (#373)
Updating the auth provider's `id` to simply `salesforce`. We don't want
it to be confused with a future well-known `provider_id` of
`arcade-salesforce`.

Also, what the toolkit was referring to as `org_domain` is actually the
organization's SUBdomain. We changed all references to "subdomain" to be
more precise. The documentation has been updated accordingly.
2025-04-22 16:32:05 -03:00
Eric Gustin
81ada1d9b9
Add Google File Picker Tool (#361)
## Google File Picker
The Google Picker lets users select or upload Google Drive files. Users
can grant permission to your apps to access their Drive data, providing
a secure and authorized way to interact with their files.

The `generate_google_file_picker_url` returns a URL to a Google File
Picker for the user.
2025-04-18 18:25:05 -07:00
Eric Gustin
09e86e9005
Toolkit Release: Reddit 0.1.0 (#370)
Associated PR: https://github.com/ArcadeAI/arcade-ai/pull/352
2025-04-18 11:01:28 -07:00
Renato Byrro
e1c293ee4f
Salesforce toolkit (#360)
Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
2025-04-18 14:28:27 -03:00
Mateo Torres
eb6b7f3987
Mateo/google calendar list (#367)
Adds "ListCalendars" to the calendar toolkit
2025-04-18 10:05:39 -07:00
Eric Gustin
2dc70a7814
Add More Reddit Tools (#352)
| Name | Description |

|----------------------------------|-------------------------------------------------------------------------|
| Reddit.CheckSubredditAccess | Checks whether the specified subreddit
exists and also if it is accessible |
| Reddit.GetSubredditRules | Gets the rules of the specified subreddit |
| Reddit.GetMyUsername | Get the Reddit username of the authenticated
user |
| Reddit.GetMyPosts | Get posts that were created by the authenticated
user sorted by newest |


Four new tools that I had to create for my demo app.
2025-04-17 19:51:28 -07:00
Eric Gustin
89f3ab13ce
Google Calendar - Strip 'Z' from datetimes (#366) 2025-04-17 16:58:14 -07:00
Eric Gustin
c7fba25488
Add Stripe toolkit (#333)
| Name | Description | Package | Version |

|-----------------------------------|---------------------------------------------------------------------------|---------|---------|
| Stripe.CreateCustomer | This tool will create a customer in Stripe. |
Stripe | 0.0.1 |
| Stripe.ListCustomers | This tool will fetch a list of Customers from
Stripe. | Stripe | 0.0.1 |
| Stripe.CreateProduct | This tool will create a product in Stripe. |
Stripe | 0.0.1 |
| Stripe.ListProducts | This tool will fetch a list of Products from
Stripe. | Stripe | 0.0.1 |
| Stripe.CreatePrice | This tool will create a price in Stripe. If a
product has not already been | Stripe | 0.0.1 |
| Stripe.ListPrices | This tool will fetch a list of Prices from Stripe.
| Stripe | 0.0.1 |
| Stripe.CreatePaymentLink | This tool will create a payment link in
Stripe. | Stripe | 0.0.1 |
| Stripe.ListInvoices | This tool will list invoices in Stripe. | Stripe
| 0.0.1 |
| Stripe.CreateInvoice | This tool will create an invoice in Stripe. |
Stripe | 0.0.1 |
| Stripe.CreateInvoiceItem | This tool will create an invoice item in
Stripe. | Stripe | 0.0.1 |
| Stripe.FinalizeInvoice | This tool will finalize an invoice in Stripe.
| Stripe | 0.0.1 |
| Stripe.RetrieveBalance | This tool will retrieve the balance from
Stripe. It takes no input. | Stripe | 0.0.1 |
| Stripe.CreateRefund | This tool will refund a payment intent in
Stripe. | Stripe | 0.0.1 |
| Stripe.ListPaymentIntents | This tool will list payment intents in
Stripe. | Stripe | 0.0.1 |
| Stripe.CreateBillingPortalSession | This tool will create a billing
portal session. | Stripe | 0.0.1 |

-------------------------

This PR implements the tools in
[stripe-agent-toolkit](https://github.com/stripe/agent-toolkit)
verbatim. This means that the logic needed to implement these tools is
minimal since stripe has already done the heavy lifting.

The tools added in this toolkit are the same tools that are in the
stripe-agent-toolkit, but formatted as Arcade tools. This means that the
names of the tools, the parameter annotations, and tool docstrings are
taken from the stripe-agent-toolkit. I have omitted evals since the tool
definitions are taken from the stripe-agent-toolkit.

The tools in this PR are generated via a script. I have included this
script in the PR (`_generate.py`) so that if the stripe-agent-toolkit
ever adds more tools, then we can simply run that script to generate the
new tools.
2025-04-14 10:29:23 -07:00
Eric Gustin
a3ff278640
Increase httpx timeout for a Notion Tool (#358)
Increasing this helps with large pages
2025-04-10 11:39:33 -07:00
Eric Gustin
8f11fce4b4
Fix Import Path In Google Calendar Eval (#355) 2025-04-08 15:02:11 -07:00
Eric Gustin
e3fe630c27
Toolkit Release: Slack (#351)
https://github.com/ArcadeAI/arcade-ai/pull/345 made changes to the Slack
toolkit & made it such that the pipe syntax is used for the return type
for some of its tools. This syntax requires arcade-ai >= 1.2.0
2025-04-07 15:00:45 -07:00
Renato Byrro
ae5ceed016
Fix missing dependency in Dropbox toolkit pyproject (#346) 2025-04-04 14:40:05 -03:00
Eric Gustin
6af49ef068
Common changes in all toolkits (#345)
Addresses general improvements to all toolkits including changing ruff
from python 3.9 to python 3.10 which is the reason for the removal of
Optional[] among others.

Also, turns out that our `make install` for toolkits wasn't correctly
checking for whether poetry was installed (&> /dev/null syntax isn't
supported by our check-toolkits GitHub action, so we were installing
poetry twice. I replaced with the more portable >/dev/null 2>&1)

Question: Should we also change ruff to py310 for the `arcade/` package
in a later PR?

-------------------

CU-86b4gzyp6
2025-04-04 09:32:37 -07:00
Eric Gustin
7c6a739f25
Add Reddit Toolkit (#336)
| Name | Description | Package | Version |

|----------------------------|------------------------------------------------------------------|---------|---------|
| Reddit.SubmitTextPost | Submit a text-based post to a subreddit |
Reddit | 0.0.1 |
| Reddit.CommentOnPost | Comment on a Reddit post | Reddit | 0.0.1 |
| Reddit.ReplyToComment | Reply to a Reddit comment | Reddit | 0.0.1 |
| Reddit.GetPostsInSubreddit | Gets posts titles, links, and other
metadata in the specified subreddit | Reddit | 0.0.1 |
| Reddit.GetContentOfPost | Get the content (body) of a Reddit post by
its identifier. | Reddit | 0.0.1 |
| Reddit.GetContentOfMultiplePosts | Get the content (body) of multiple
Reddit posts by their identifiers. | Reddit | 0.0.1 |
| Reddit.GetTopLevelComments | Get the first page of top-level comments
of a Reddit post. | Reddit | 0.0.1 |


### Why not use an SDK?
Reddit API does not have an official SDK, although
[PRAW](https://github.com/praw-dev/praw) has large community support.

I played around with PRAW, but ultimately decided to not use an SDK.
PRAW made it incredibly easy to work with Reddit Objects, but there were
a few drawbacks that ultimately swayed me to not use it:
1. PRAW assumes that it will do the auth for you. A client ID and secret
must be passed to PRAW, but a tool only has the auth token. I was able
to hack around this by manipulating private properties - but it felt too
hacky
2. PRAW does not support Python 3.13
3. PRAW is not async. There is
[AsyncPRAW](https://github.com/praw-dev/asyncpraw), but the community
does not look active there.
2025-04-03 14:07:10 -07:00
Renato Byrro
cb1fff151b
Fix issue in get_channel_metadata_by_name: missing scope for private channels and conversation types filter (#338) 2025-04-01 17:01:25 -03:00
Renato Byrro
79e3b03a8e
Google Calendar tool to find time slots when one or more people (within the same org domain) are simultaneously free (#279) 2025-04-01 14:53:27 -03:00
Renato Byrro
c1e8fc795a
Dropbox Toolkit (#332)
Basic tools to list items in a folder, search for files / folders, and
download a file content.
2025-03-27 18:34:10 -03:00
Eric Gustin
887ded441e
Toolkit Release 03-25-25 (#329)
Minor version releases for Google and Search Toolkits.

Related PRs:

Google:
https://github.com/ArcadeAI/arcade-ai/pull/321

Search:
https://github.com/ArcadeAI/arcade-ai/pull/316
https://github.com/ArcadeAI/arcade-ai/pull/320
https://github.com/ArcadeAI/arcade-ai/pull/317
2025-03-25 12:01:55 -07:00
Eric Gustin
e7daa1edba
Fix Failing Slack Toolkit Build (#326)
`typing` was being installed and causing builds to fail. [See logs
here](https://github.com/ArcadeAI/arcade-ai/actions/runs/14041206262/job/39311571300)

This PR also removes the `typing-extensions` dependency
2025-03-24 13:45:04 -07:00
Eric Gustin
04bda3cc45
Google Sheets Tools (#321)
| Name | Description |

|--------------------------|---------------------------------------------------------------------------------------|
| Google.CreateSpreadsheet | Create a new spreadsheet with the provided
title and data in its first sheet |
| Google.GetSpreadsheet | Get the user entered and formatted data for
all sheets in the spreadsheet |
| Google.WriteToCell | Write a value to a single cell in a spreadsheet.
|


## Google.CreateSpreadsheet
This tool can create a new spreadsheet with data in its first sheet
This tool takes in the data as a JSON string. Here's an example input: 
```
// Good at large payloads, sparse payloads, and contiguous data payloads.
// For example data[1]["D"] represents the value of the cell in the first row in the D column
{
  // All data in row 1
  1: {
    "A": 42, 
    "B": 2, 
    "D":"=A1+B1"
  },
  // All data in row 54
  54: {
    "A": "my string",
    "QQ": "my far away string"
  }
}
```
The above data format performed better on evals than the other two that
I tested:
```
// Performed poorly at sparse data and also at larger amounts of data
[
  [42, 2, "", "=A1+B1"], 
  [], 
  [],
  ..., 
  ["A": "my string", "", "", ..., "my far away string"]
]
```
```
// Good at small payloads and sparse payloads, but very bad at payloads with contiguous data
{
  "A1": 42", "B1": 2, "D1": "=A1+B1", "A54": "my string", "QQ": "my far away string"
}
```

## Google.GetSpreadsheet
Gets the formatted values for all non empty cells in all sheets of the
spreadsheet. The data returned is in a similar format as the
`Google.CreateSpreadsheet` tool's `data` input parameter. The difference
is that `get_spreadsheet` will return the user entered value (=A1+B1)
and also the formatted value (23.4) for each cell.

## Google.WriteToCell
Writes to a single cell. At this point in time we do not support batch
updating a sheet.
2025-03-24 09:52:51 -07:00
Renato Byrro
c9ed5ce123
Google Shopping search tool (#317) 2025-03-21 21:09:54 -03:00
Renato Byrro
f6765bed67
Walmart shopping search tools (#320) 2025-03-21 21:02:45 -03:00
Sterling Dreyer
227f02d2fd
Add Notion and Youtube toolkits to worker (#322) 2025-03-21 15:33:21 -07:00
Renato Byrro
2338e823cf
YouTube Search tools (#316) 2025-03-21 19:26:52 -03:00
Eric Gustin
a3371d71ac
Fix Search.SearchJobs for Anthropic Models (#319)
Fixes this error:

```bash
openai.InternalServerError: Error code: 503 - {'name': 'all_models_unavailable', 'message': "failed to chat with models; Attempt 0: anthropic - anthropic (type = error, message = tools.75.custom.input_schema.properties: Property keys should match pattern '^[a-zA-Z0-9_-]{1,64}$'); Attempt 1: anthropic - anthropic (type = error, message = tools.75.custom.input_schema.properties: Property keys should match pattern '^[a-zA-Z0-9_-]{1,64}$'); Attempt 2: anthropic - anthropic (type = error, message = tools.75.custom.input_schema.properties: Property keys should match pattern '^[a-zA-Z0-9_-]{1,64}$')"}
```
2025-03-19 20:53:46 -07:00
Eric Gustin
86696ea794
Bump math toolkit version (#318) 2025-03-19 18:05:46 -07:00
Renato Byrro
81b2624c1a
Fix Slack bug when sending msg to a private channel (#313) 2025-03-19 17:45:03 -07:00
Mateo Torres
ab735eb442
increased precision of decimal-based math tools to 100 digits (#315)
Some edge cases of a benchmark were failing due to low precision,
increased the precision to 100 digits.
2025-03-19 13:48:18 -03:00
Renato Byrro
1867443b84
Bump search toolkit version (#312) 2025-03-18 11:30:01 -07:00
Renato Byrro
a3f55378ca
Add Google News, Jobs, and Maps Tools (#311)
Documentation PR: https://github.com/ArcadeAI/docs/pull/190
2025-03-18 15:23:36 -03:00
Eric Gustin
a92f86d783
Bump notion version (#310)
when testing earlier, 0.1.0 was used for a failed pypi upload. I'm
assuming this is why `This filename has already been used, use a
different version` is occuring
2025-03-17 21:28:10 -07:00
Eric Gustin
7edaa0a996
Update Notion Toolkit (#309)
1. The Arcade Worker doesn't like it when the package name is different
than the directory name. This PR renames the directory from
`arcade_notion` to `arcade_notion_toolkit`
2. `Notion` is not a well-known provider name in `arcade-ai==1.0.5`,
I've updated the dep to represent this.
2025-03-17 21:15:00 -07:00
Eric Gustin
a787b6dbe3
Explicitly define notion directory name (#307) 2025-03-17 17:02:45 -07:00
Eric Gustin
ca2ca50a1f
Rename notion toolkit PyPI package (#306) 2025-03-17 16:46:57 -07:00
Eric Gustin
53a12802f6
More updates to Publish Toolkit Workflow (#305) 2025-03-17 16:33:51 -07:00
Eric Gustin
29e895ca44
Change notion version (#304) 2025-03-17 16:13:28 -07:00
Eric Gustin
e048f277fd
Fix publish toolkit workflow (#302)
There was a bug where if the poetry publish failed, then the slack
message would say that it succeeded.

I am setting the notion toolkit version to 0.0.1. This is expected to
fail. I'm doing this to ensure the E2E issue is fixed.

The grep'd string comes from
https://github.com/python-poetry/poetry/blob/main/src/poetry/publishing/uploader.py#L246-L249
2025-03-17 15:40:32 -07:00
Eric Gustin
cd7eca306a
Release Arcade Math 1.0.0 (#300) 2025-03-17 12:58:17 -07:00
Eric Gustin
25c9f76ca8
Fix secrets for firecrawl tool (#299) 2025-03-16 15:38:04 -07:00
Eric Gustin
b7d5736995
Replace changed-files GH Action (#295) 2025-03-15 15:15:01 -07:00
Eric Gustin
7428397318
Notion Toolkit (#283) 2025-03-15 11:08:10 -08:00
Eric Gustin
99ff11d30e
Various Search Toolkits (#285)
1. Add the following tools:
* Google Finance
    - get_stock_summary
    - get_stock_historical_data
* Google Flights
    - search_roundtrip_flights
    - search_one_way_flights
* Google Hotels
    - search_hotels
    
2. Add some common helper functions for serpAPI tools.
2025-03-14 14:23:14 -07:00
Mateo Torres
f04087b389
Math tools expanded (#293)
Migrated all interfaces to get and return strings.

Added tests and evals for all functions (except the random generation)
Math functions are now organized into different math categories

---------

Co-authored-by: Nate Barbettini <nate@arcade-ai.com>
2025-03-14 09:47:04 -03:00
Eric Gustin
2fe907e5dd
Release Google Toolkit version 1.0.0 (#280)
Updates to the Google Toolkit:
https://github.com/ArcadeAI/arcade-ai/pull/264 (google patch)
https://github.com/ArcadeAI/arcade-ai/pull/188 (google minor)
https://github.com/ArcadeAI/arcade-ai/pull/272 (google major)
https://github.com/ArcadeAI/arcade-ai/pull/269 (google minor)
https://github.com/ArcadeAI/arcade-ai/pull/265 (google major)
2025-03-12 14:25:50 -07:00
Renato Byrro
ac0f5aa10c
Search Google Drive documents and retrieve contents (#265)
This tool will be useful in scenarios akin to RAG, where someone wants
to ask questions or request the production of a summary, for instance,
about a bunch of documents related to a particular topic. Currently, to
fulfill such requests, the LLM needs to first `list_documents`, then
`get_document_by_id` for each document.

We also implement a utility functions to return documents in Markdown
and HTML, since the Drive API JSON is verbose and would waste too many
tokens unnecessarily.

Limitations: the Markdown/HTML utilities do not handle table of contents
(which I think aren't really useful here), headers, footers, or
footnotes.

---
This PR deprecates `list_documents` and implements `search_documents`,
apart from `search_and_retrieve_documents`). This configuration makes it
easier for LLMs to understand when to call each tool.

Both tools had their interfaces refactored to remove Google API-specific
arguments that were confusing LLMs sometimes, such as "corpora" and
"support_all_drives". It now accepts arguments that better relate to
expected user requests.

---------

Co-authored-by: Eric Gustin <eric@arcade.dev>
2025-03-07 18:42:12 -03:00
Renato Byrro
2135101acd
Tool to retrieve file tree structure from Google 'My Drive' and 'Shared Drives' (#269) 2025-03-07 18:02:09 -03:00
Nate Barbettini
e9ee3bba40
fix: Use tool secrets in toolkits (#271)
~~Note: Don't merge until the correct secrets have been added to Arcade
Cloud.~~

Ready to merge, the feature is already on its way to prod.

---------

Co-authored-by: Eric Gustin <eric@arcade.dev>
2025-03-04 13:35:36 -08:00
Renato Byrro
75da4bf8b0
Make search_contacts interface more LLM-friendly (#272)
Break down `search_contacts` into `search_contacts_by_name` and
`search_contacts_by_email`. The search_contacts' `query` argument was
not clear enough for LLMs.
2025-02-28 16:47:03 -03:00
Alex Salazar
7b1110f2b7
Alex gmail improvements (#188)
Improved gmail toolkit. Added support for threading in draft replies,
multipart email parsing, and label management. Fixed the DateRange
parameter issue in list_emails_by_headers. Added logging and removed
print statements. Created custom exceptions for each specific google
toolkit.

-----
Summary of changes by @byrro:

- Fixed minor bug related to the `date_range` argument of
`list_emails_by_header`
- A few utility functions (`build_email_message`,
`build_reply_recipients`, `build_reply_body`) to centralize logic and
remove repeated code from email-sending tools
- New `reply_to_email` tool (apart from `write_draft_reply_email`,
implemented by Alex) to keep the toolkit consistent
- Evals and unit tests
- Handling of reply-to (only sender) and reply-to-all recipients
- Removed some unnecessary debug messages, which Alex had added to
replace print statements
- Removed HTML handling implemented by Alex in `write_draft_reply_email`
> I think we should either support HTML across all applicable tools or
not at all; I decided to remove it and leave this feature for a future
PR.

---------

Co-authored-by: Renato Byrro <rmbyrro@gmail.com>
2025-02-27 11:56:32 -03:00
Nate Barbettini
62173da343
Update scope on Google.ListDocuments (#264)
Updating the scope on this unreleased tool to be more granular.
2025-02-20 21:36:46 -08:00
Eric Gustin
eeb47dbec5
[Toolkit Release] Weekly Toolkit Release 02-20-25 (#261)
# Weekly Toolkit Release 02-20-25
Previous Toolkit Release: #248 

## Google Toolkit Minor Release
https://github.com/ArcadeAI/arcade-ai/pull/249
#259 

## Slack Toolkit Minor Release
#254 

## X Toolkit Patch Release
#256
2025-02-20 13:27:35 -08:00
Nate Barbettini
274e63c9e5
Polish up Google.SearchContacts and CreateContact (#259)
Adding the missing polish (evals, tests) for #249
2025-02-20 08:53:12 -08:00
Renato Byrro
8efa9a51df
Slack tools to retrieve messages & metadata from multi-person DM conversation (#254) 2025-02-19 16:51:45 -03:00
Nate Barbettini
becd86da0c
Google toolkit: Search and create contacts POC (#249)
This is an initial sketch of what Contacts (People) API tools could look
like. But I haven't yet thought like an MX Engineer @byrro 😉
2025-02-18 17:27:33 -08:00
Eric Gustin
7d45a99722
X Toolkit: Handle no tweets returned in search (#256)
## PR Description
Search ([see API docs
here](https://docs.x.com/x-api/posts/recent-search)) returns a 'data'
field that maps to a list of tweets returned. We've observed that the
'data' field is not present if no tweets match the search. This PR
handles that case safely.
2025-02-18 13:28:33 -08:00
Eric Gustin
49ff013e80
[Toolkit Release] Weekly Toolkit Release 02-13-25 (#248)
# Weekly Toolkit Release 02-13-25
Previous Toolkit Release: #236 

## Associated PRs
* Minor #241
2025-02-13 13:06:11 -08:00
Renato Byrro
a00bd4734e
Tool to retrieve Slack messages from a DM conversation with a given username (#241)
Currently, retrieving DMs with a given username requires several
actions: first get the current user's ID; list all users and find the ID
of the username; then scan all DM conversations and find the one with
the current user's ID and the username's ID, to finally retrieve the
messages using that conversation ID.

This tool abstracts all that in a single call.

PS: we'll implement a similar tool for multi-person DM conversations in
a subsequent PR.
2025-02-10 09:01:04 -03:00
Eric Gustin
be2539602f
Evals New Features (#208)
# PR Description
This PR adds ~~four~~ three improvements to evals.

~~## 1. Add parameterized eval cases~~
~~Adds a new method named `add_parameterized_case`. Just like pytest’s
parameterized tests, eval cases can be parameterized with multiple user
messages. Adds a case to the `EvalSuite` for each user message. All
cases have the same expected tool call(s), params, additional_messages.
This reduces duplicate code and makes it easy to observe how a model
performs based on increasingly more difficult prompts.~~
```python
""" NO LONGER IN THIS PR
user_messages = [
    "Call the delete tweet by id tool with the tweet ID '148975632'.",
    "Delete the tweet with ID '148975632'.",
    "I don't want to have this tweet (148975632) on my account anymore.",
    "do the opposite of post for https://x.com/x/status/148975632",
]

suite.add_parameterized_case(
    name="Delete a tweet by ID",
    user_messages=user_messages,
    expected_tool_calls=[
        ExpectedToolCall(
            func=delete_tweet_by_id,
            args={"tweet_id": "148975632"},
        )
    ],
    critics=[
        BinaryCritic(
            critic_field="tweet_id",
            weight=1.0,
        ),
    ],
)
"""
```

~~PASSED Delete a tweet by ID (user_message 1 of 4) -- Score: 100.00%~~
~~PASSED Delete a tweet by ID (user_message 2 of 4) -- Score: 100.00%~~
~~PASSED Delete a tweet by ID (user_message 3 of 4) -- Score: 100.00%~~
~~FAILED Delete a tweet by ID (user_message 4 of 4) -- Score: 0.00%~~
~~Summary -- Total: 4 -- Passed: 3 -- Failed: 1~~

## 2. Parameters that are not explicitly criticized are assigned a
`NoneCritic`.
A NoneCritic has no effect on the evaluation results and does not
actually evaluate. Parameters that have a NoneCritic will be displayed
as ‘un-criticized’ in the evaluation summary (if `-d` flag is used).

![image](https://github.com/user-attachments/assets/300756ec-9b53-436a-9cf9-fc61d0b00c01)


## 3. Add a hardcoded `seed` parameter for evals.
The seed parameter aides in receiving (mostly) consistent outputs -
aiding in reproducibility for evaluations.

## 4. Disallow more than one critic for the same field.
Raises a `ValueError` if more than one critic is assigned to a field.

---------

Co-authored-by: Eric Gustin <eric@arcade-ai.com>
2025-02-05 15:22:08 -08:00
Renato Byrro
149c25d967
Fix missing scopes in tools that call other tools (#240) 2025-02-03 17:39:34 -08:00
Eric Gustin
aaf1dbd795
[Toolkit Release] Weekly Toolkit Release 01-29-25 (#236)
# Weekly Toolkit Release 01-29-25
Previous Toolkit Release: #222 
## Associated PRs
Slack Patch: #232 
GitHub Patch: #227
2025-01-29 09:51:16 -08:00
Eric Gustin
ce2fb0f6c1
Update Examples & Various Renames (#233)
# PR Description
* This PR updates code in `examples/` to be compatible with version
1.0.0
* This PR removes the Spotify examples since the Arcade hosted worker
doesn't currently cataloge the Spotify toolkit. We can reintroduce these
examples when it does.
* This PR performs various renames across the codebase for
`arcade-ai.com` --> `arcade.dev` and `Arcade AI` --> `Arcade`
2025-01-28 17:17:29 -08:00
Eric Gustin
3657fc79b6
Whitelist Toolkit Release Managers (#234)
# PR Description
The `github.event.pull_request.author_association` in the "Prevent
Unauthorized Version Updates" workflow was returning inconsistent
results by saying that MEMBERS were CONTRIBUTORS. This PR moves away
from `author_association` in favor of a whitelist text file containing
the GitHub usernames of authorized toolkit release managers.

A toolkit release manager has the following special permissions:
* Can change the version of an existing toolkit
* Can delete an existing toolkit 
* Can rename an existing toolkit
2025-01-27 14:35:45 -08:00
Renato Byrro
27d8aa7f43
Fix bug in slack tool pagination (#232)
The `get_conversation_metadata_by_name` tool retrieves conversation
metadata from another tool, `list_conversations_metadata`, but was
accessing the `next_cursor` using the Slack API response dict structure,
instead of the tool response structure. As a result, in that tool, the
tool would never actually paginate to the second page. This PR fixes it
and also adjust tests to capture the issue appropriately.
2025-01-27 12:23:00 -08:00
Renato Byrro
aa0cd02fe9
Make starred = True by default in Github tool (#227)
`starred` is a required argument of the
`arcade_github.activity.set_starred` tool, but when it is not provided
in the tool call, the engine is somehow passing it with a falsy value,
instead of raising an error. the falsy value makes the tool unstar a
repo by default, which is not the desired behavior.

we're setting the `starred` arg to True in the tool interface to prevent
that.
2025-01-24 13:50:30 -08:00
Eric Gustin
ca90b31262
Update README and LICENSE (#220)
Updates README to point to updated URLs

---------

Co-authored-by: Nate Barbettini <nate@arcade-ai.com>
2025-01-23 19:43:48 -08:00
Eric Gustin
d5d6942ed1
Weekly Toolkit Release (#222)
# Relevant PRs
Google: #207 
Spotify: #204 

Slack: #162

Also relaxes arcade-ai dependency for all toolkits
2025-01-23 18:46:05 -08:00
Eric Gustin
66e54d7cde
Slack Tools (#162)
implements additional tools for Slack related to retrieving
conversations metadata, list of members, history of messages, as well as
sending messages to private/public channels and DMs / multi-person DMs.

---------

Co-authored-by: Eric Gustin <eric@arcade-ai.com>
Co-authored-by: Renato Byrro <rmbyrro@gmail.com>
2025-01-23 18:15:52 -08:00
Eric Gustin
48c9870eac
Removed unused param (#207)
# PR Description
For the `Google.GetThread` tool, we had a parameter named
`metadata_headers`. This parameter only makes a difference if the format
is "metadata", but the tool will never have the format "metadata". So,
the input parameter is useless. This parameter should have never been
added to the tool and we should remove it before public beta.
2025-01-16 09:41:26 -08:00
Eric Gustin
e314ac5ed5
Remove deprecated eval imports (#206)
# PR Description
Continuation of PR #196
2025-01-15 17:40:25 -08:00
Renato Byrro
62327c30a7
Pytests for Spotify tools (#204) 2025-01-14 12:45:32 -08:00
Eric Gustin
8795871d51
Check if toolkit version changed before attempting publish (#198)
# PR Description
Changes to a toolkit without changes to the toolkit's version fail the
'Publish Toolkit' workflow with `HTTP Error 400: File already exists
('arcade_zoom-0.1.7.tar.gz', with blake2_256 hash
'02183cda607f06616e7edb17e3d22bc11d1d83b074b3e44066b78ec72602fb37'). See
https://pypi.org/help/#file-name-reuse for more information.`, for
example.

This PR adds the `--skip-existing` flag to `poetry publish` to avoid
attempting to publish an existing version. Skips slack notification if
publish is skipped.


The `grep`'d string comes from
https://github.com/python-poetry/poetry/blob/main/src/poetry/publishing/uploader.py#L246-L249
2025-01-13 10:00:24 -08:00
Renato Byrro
c5e29693e7
Remove tools relying on deprecated Spotify endpoints (#196)
Spotify deprecated several endpoints in Nov, 2024. Two of them were
being used in Tracks tools. We're removing those from the Toolkit.

Spotify announcement:
https://developer.spotify.com/blog/2024-11-27-changes-to-the-web-api
Archive: https://archive.is/LMBe5
2025-01-08 16:40:36 -03:00
Renato Byrro
cd837a363d
Separate tools & helper funcs in separate files (#192)
Separates utility and helper functions, as well as constant values (e.g.
base URLs), in dedicated files, apart from tools files.
2025-01-08 16:39:25 -03:00
Renato Byrro
cd1fb648bd
Return media attachments metadata when retrieving X tweets (#191)
Modifies X tweet tools to return metadata about media attachments
(photo, GIF or video) when retrieving a tweet by ID, username or
keywords.

The tool will always return media attachments by default. Since it's
only metadata, it shouldn't add significant network overhead to existing
implementations of the tool.

My guess is more often than not people will want this info included.
When not needed, it doesn't hurt to include by default. It'd be annoying
to have to ask the LLM to include it every time they need.
2025-01-08 16:36:43 -03:00
Eric Gustin
b2bdfe2459
Least Privileged Scope for Update Calendar (#195) 2025-01-08 10:03:04 -08:00
Eric Gustin
d5067af023
Bump toolkit versions (#194) 2025-01-07 13:32:36 -08:00
Eric Gustin
feb83c95ca
Pin poetry to 1.8.5 (#193)
# PR Description
Poetry released v2 with many breaking changes a couple days ago. The
`install-poetry` action that our workflows use default to that v2
version, so many of our workflows are failing. This PR forces that
action to use poetry version 1.8.5 and also uses 1.8.5 for toolkits

A ticket to migrate to 2.0.0 has been filed for future work
2025-01-07 13:21:55 -08:00
Eric Gustin
ab889f9f1d
Lint all toolkits (#183)
# PR Description
* Adds/updates the following files to all toolkits:
    - `.pre-commit-config.yaml`
    - `.ruff.toml`
    - `LICENSE`
    - `Makefile`
    - `pyproject.toml`
* Lint all toolkits such that they pass `make check` and `make test` (a
total doozy). This includes adding some unit tests and evals.
* Github workflow for testing toolkits before merge into main (courtesy
of @sdreyer)
* Added a QOL improvement for tool developers for when they need to get
the context's auth token.
* Minor updates to `arcade new` template.
2024-12-20 09:49:45 -08:00
Sterling Dreyer
950a8600f8
Remove lock flag from check (#181) 2024-12-19 11:36:32 -08:00
Sterling Dreyer
1512d0699e
Testing for Math Toolkit (#180) 2024-12-19 11:28:03 -08:00
Sterling Dreyer
70faf7af5a
Test Version Override (#179)
Testing to make sure pypi versions don't override. This should fail
2024-12-19 11:13:18 -08:00
Eric Gustin
7c228a59d5
Update Evals SDK (#175)
# PR Description
This PR renames `ExpectedToolCall` to `NamedExpectedToolCall` and then
creates a new dataclass called `ExpectedToolCall`. `ExpectedToolCall`
can be passed to the `EvalSuite.add_case` and `EvalSuite.extend_case`
methods.

1. Enhance `EvalSuite.add_case` and `EvalSuite.extend_case` by accepting
a list of `ExpectedToolCall` as their `expected_tool_calls` input
parameter. This helps create a scaffolding for developers. Previously,
the expected type was `list[tuple[Callable, dict[str, Any]]]`, which is
still valid for backward compatibility.
```python
# Before (still valid for backward compatibility)
expected_tool_calls=[
    (
        adjust_playback_position,
        {
            "absolute_position_ms": 10000,
        },
    )
]
        

# After
expected_tool_calls=[
    ExpectedToolCall(
        func=adjust_playback_position,
        args={"absolute_position_ms": 10000},
    )
]
```
2. Removed any references to arcade.core in toolkits directory.
3. Some linting for import organization.
2024-12-19 10:29:13 -08:00
Eric Gustin
02eee63884
X Toolkit: Support tweets longer than 280 characters (#171)
# PR Description
* Update `search_recent_tweets_by_username`,
`search_recent_tweets_by_keywords`, and `lookup_tweet_by_id` to support
long tweets. Previously, only the first 280 characters of the tweet's
text were returned by the tool.
2024-12-13 09:04:50 -08:00
Eric Gustin
00d5babcd7
Add next_token to X Search tools (#169)
# PR Description
Adds an optional `next_token` input parameter to the
`X.SearchRecentTweetsByUsername` and `X.SearchRecentTweetsByKeywords`
tools.

This allows users to paginate through tweets. A `next_token` is provided
in the tools's response.

For example, to access the `next_token` when using the `tools.execute`,
you can do `next_token = response.output.value["meta"].get("next_token",
None)` and then pass it to the tool on your next call through the tools'
`next_token` input parameter.
2024-12-10 12:35:20 -08:00
Sam Partee
bebfcab1e9
Add lookup_tweet_by_id to X Toolkit (#165)
This PR introduces the `lookup_tweet_by_id` tool to the X toolkit,
enabling users to retrieve tweet details by tweet ID. This enhancement
extends the toolkit's capabilities, allowing for more comprehensive
interactions with the X (Twitter) API.

**Key Changes:**

- **Added `lookup_tweet_by_id` Tool:**
- Implemented the `lookup_tweet_by_id` function in `tools/tweets.py`,
which allows users to fetch tweet information using a tweet ID.
- Included error handling for API response codes and expanded URLs in
tweets to assist language models in avoiding hallucinations due to
shortened URLs.

- **Enhanced Toolkit Structure:**
- Added several configuration files to the X toolkit to establish a
standardized project structure, which in the future will be generated by
`arcade new`. These include:
- `.pre-commit-config.yaml`: Defines pre-commit hooks for code quality
checks.
    - `.ruff.toml`: Configuration for the Ruff linter.
    - `LICENSE`: MIT License file for the toolkit.
- `Makefile`: Contains common commands for building, testing, and
linting the toolkit.

- **Updated Makefile:**
- Added `make check-toolkits` command to the top-level `Makefile`. This
command runs code quality tools for each toolkit that contains a
`Makefile`.

**Additional Notes:**

- **Tests:**
- Added unit tests for the new `lookup_tweet_by_id` tool in
`tests/test_tweets.py`.
- Included tests for the user lookup functionality in
`tests/test_users.py`.

- **Linting and Code Quality:**
- Configured pre-commit hooks and Ruff linter to enforce code standards.
- Updated the `pyproject.toml` file with development dependencies for
testing and linting.

-

---------

Co-authored-by: Eric Gustin <eric@arcade-ai.com>
2024-11-27 17:07:12 -08:00
Eric Gustin
2798cc0820
Add Gmail Thread Tools (#159)
# PR Description
1. This PR adds three new tools:
    - GetThread (by ID)
    - ListThreads
    - SearchThreads
2. This PR updates the return type for various Gmail tools from str to
dict.
3. This PR adds evals and tests for the added tools
2024-11-20 11:26:09 -08:00
Eric Gustin
8b46e4f7f9
Add Code Sandbox Tools (#114)
# PR Description
This PR creates a new toolkit called CodeSandbox. This toolkit has two
tools:
1. `RunCode`: Creates an E2B sandbox and runs the provided code in that
sandbox. Returns the execution logs, result, and errors. Supports
Python, JavaScript, R, Java, and Bash code.
2. `CreateStaticMatplotlibChart`: Creates a sandbox, runs the provided
python code that uses matplotlib, and returns the base64 encoded image
of the chart along with any logs or errors.
- I recommend not using `tool_choice="generate"` since the return object
contains a base64 image can be a lot of tokens that will not provide
much value to a generate's response.
    
    
    
Example of creating a pie chart:
```python
import base64
import json
import os

from openai import OpenAI


def call_tool_with_openai(client: OpenAI) -> dict:
    response = client.chat.completions.create(
        messages=[
            {
                "role": "user",
                "content": "There are 17 red apples, 4 green apples, and 10 yellow apples. Create a pie chart for this data.",
            },
        ],
        model="gpt-4o-mini",
        user="you@example.com",
        tools=["CodeSandbox.CreateStaticMatplotlibChart"],
        tool_choice="execute",
    )

    return response


arcade_api_key = os.environ.get("ARCADE_API_KEY")
cloud_host = "http://localhost:9099/v1"

openai_client = OpenAI(
    api_key=arcade_api_key,
    base_url=cloud_host,
)

chat_result = call_tool_with_openai(openai_client)
tool_call_id = chat_result.choices[0].message.tool_calls[0].id

content = json.loads(chat_result.choices[0].message.content)
base64_image = content[tool_call_id]["value"]["base64_image"]

image_data = base64.b64decode(base64_image)
with open("output_image.png", "wb") as image_file:
    image_file.write(image_data)

```
2024-11-15 13:29:52 -08:00
Eric Gustin
081865733a
Add examples (#136)
## PR Description
This PR adds 7 examples.

* `call_a_tool_directly_with_auth.py` - Simple example that uses Arcade
client to execute a tool that lists Gmail emails
* `call_a_tool_directly.py` - Simple example that uses Arcade client to
execute a tool that adds two numbers together
* `call_a_tool_with_llm.py` - Simple example that uses the LLM api to
star the arcade-ai repository
* `get_auth_token.py` - Simple example that gets a Google auth token and
then calls the Google API
* `call_multiple_tools_directly_with_auth.py` - A more involved example
that directly calls multiple spotify tools sequentially
* `call_multiple_tools_with_llm.py` - A more involved example that uses
an llm to call multiple spotify tools sequentially
* `simple_chatbot.py` - Simple chatbot that uses arcade tools and has
history

---------

Co-authored-by: Nate Barbettini <nathanaelb@gmail.com>
2024-11-06 11:02:41 -08:00
Eric Gustin
6d1bc6c084
Random int and random float tools (#148)
As requested by D&D fans
2024-11-06 09:28:05 -08:00
Eric Gustin
bc393db305
Return success message if playback is altered (#145)
# PR Description
Previously, if a tool adjusted the playback state, then the tool would
return the current playback state after the modification had occurred.
The problem with this approach was that Spotify would not update the
playback state in time (sometimes), so the tools were returning stale
data!
2024-11-04 17:22:10 -08:00
Eric Gustin
efee9589fa
More Spotify Tools (#140)
# PR Description
This PR adds three new spotify tools that are natural language friendly.

1. `search` - Search Spotify Catalog information
2. `play_artist_by_name` - Gets 5 songs by the specified artist and
plays them. Uses `search`, and `start_tracks_playback_by_id` under the
hood
3. `play_track_by_name` - Plays the specified song, optionally provide
the artist name who plays the song. Uses `search`, and
`start_tracks_playback_by_id` under the hood
2024-11-01 13:15:43 -07:00
Eric Gustin
c8e686c04e
Add tools to Spotify Toolkit (#132)
# PR Description
1. `adjust_playback_position` - Adjust the playback position within the
currently playing track
2. `skip_to_previous_track` - Skip to the previous track in the user's
queue, if any
3. `skip_to_next_track` - Skip to the next track in the user's queue, if
any
4. `pause_playback` - Pause the currently playing track, if any
5. `resume_playback` - Resume the currently playing track, if any
6. `start_tracks_playback_by_id` - Start playback of a list of tracks
(songs)
7. `get_playback_state` - Get information about the user's current
playback state, including track or episode, and active device
8. `get_currently_playing` - Get information about the user's currently
playing track
9. `get_track_from_id` - Get information about a track
10. `get_recommendations` - Get track (song) recommendations based on
seed artists, genres, and tracks, and multiple target audio stats
11. `get_tracks_audio_features` - Get audio features for a list of
tracks (songs)
----------------------

My favorite feature of this toolkit is
1. Start playing my favorite song
2. Get the song that I'm currently playing
3. Get audio features of that song
4. Ask for recommended songs that are similar to it
5. Jam out

------------
2024-10-30 18:26:39 -07:00
Eric Gustin
ddaeb4db53
Add list stargazers tool (#130)
# PR Description
As a celebration for arcade-ai becoming open sourced, this PR adds a
tool to list the stargazers for a particular repository


### Example `arcade chat -h localhost` usage:

![image](https://github.com/user-attachments/assets/c4ba9ce6-d3ec-461b-b356-72e78a09249b)
2024-10-30 18:13:36 -07:00
Nate Barbettini
036ad54ac6
Remove arcade.core from all examples (#121)
This PR ensures that `arcade.core` does not show up anywhere in "user
space". This is crucial for helping developers understand what objects
are safe to use, and helps maintain a good developer experience.

Specific changes:
- `ToolAuthorizationContext` and `ToolContext` are now visible via
`arcade.sdk`
- `ToolCatalog` is now visible via `arcade.sdk`
- `Toolkit` is now visible via `arcade.sdk`
- `config` is now visible via `arcade.sdk.config`
2024-10-24 17:08:04 -07:00
Eric Gustin
fd8190e216
Update arcade version in web toolkit toml (#113)
When #110 was merged the build failed with:
```
9.372 Installing toolkit ./toolkits/arcade_web-2024.10.17.dev0-py3-none-any.whl
9.687 Processing ./toolkits/arcade_web-2024.10.17.dev0-py3-none-any.whl
9.749 Collecting firecrawl-py<2.0.0,>=1.3.1
9.872   Downloading firecrawl_py-1.3.1-py3-none-any.whl (15 kB)
9.911 ERROR: Could not find a version that satisfies the requirement arcade-ai<0.2.0,>=0.1.0 (from arcade-web) (from versions: 0.0.1, 0.0.13)
9.911 ERROR: No matching distribution found for arcade-ai<0.2.0,>=0.1.0
```

and I believe this fixes the issue
2024-10-17 16:36:29 -07:00
Eric Gustin
cc2a08ec34
Add Firecrawl Tools For The New arcade_web` Toolkit (#110)
# PR Description
This PR adds 6 new tools inside the new `arcade_web` toolkit. None of
these tools require auth. They do, however, require the
`FIRECRAWL_API_KEY` API Key to be set.

The new tools implement the [Firecrawl](https://www.firecrawl.dev/) APIs
`/scrape (POST)`, `/crawl (POST)`, `/crawl/{id} (GET)`, `/crawl/{id}
(DELETE)`, and `/map (POST)`.

The six tools are:
* `Web.ScrapeUrl`: 
- In the future I would like this tool to support actions (clicking,
scrolling, screenshotting, etc) and extract (specify what you want to
scrape) parameters. Firecrawl supports both of these parameters.
* `Web.CrawlWebsite`:
- If `async_crawl` is true, then the tool just returns the id of the
crawl job, which you can retrieve later with the `Web.GetCrawlData`
tool. If `async_crawl` is false, then the entire contents of the crawl
are returned.
* `Web.GetCrawlStatus`
- Works for in progress or recently finished crawl jobs (Firecrawl's
limitation)
* `Web.GetCrawlData`
- Works for in progress or recently finished crawl jobs (Firecrawl's
limitation)
* `Web.CancelCrawl`
    - You can cancel an in progress async crawl job
* `Web.MapWebsite`
- This endpoint is in alpha, but it can give you all of the links of an
entire website, or optionally, you can specify in natural language what
type of links you want to map by using the `search` parameter. For
example "only map webpages that are about AI"
2024-10-17 16:10:53 -07:00