Commit graph

251 commits

Author SHA1 Message Date
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
Eric Gustin
4608cce862
Fix parameterized type bug & better error message (#273)
## PR Description
### 1. Bug Fix
A bug was observed where tools that were using [parameterized
generics](https://docs.python.org/3/library/stdtypes.html#types-genericalias)
(e.g., `dict[str, Any]`) for their input parameters or output, then this
would cause the Worker to fail on startup with the error `issubclass()
arg 1 must be a class` for Python3.13+. This error would not occur for
Python versions less than 3.13.

In Python <3.13, parameterized generics would implicitly be treated as
their underlying type (its origin), so it was possible to treat
`dict[str, Any]` as a class and pass it to `issubclass`. This is not the
case for Python 3.13, so we need to explicitly strip the GenericAlias
(e.g., `dict[str, Any]`) down to its origin (e.g., `dict`), before
checking if it is a subclass of `Enum`.

### 2. Better Error Message
When a tool used an unsupported parameter/output type, then Arcade would
display the following message:
```
Failed to start Arcade Worker: 
Type error encountered while adding tool get_website_map from arcade_web.tools.firecrawl. 
Reason: issubclass() arg 1 must be a class
```

But now it displays
```
Failed to start Arcade Worker: 
Error encountered while adding tool get_website_map from arcade_web.tools.firecrawl. 
Reason: Unsupported type: tuple[str, str]
```
2025-03-07 11:46:42 -08:00
Eric Gustin
fb69e9ef77
Add Notion Auth Provider (#277)
<img width="409" alt="Screenshot 2025-03-06 at 11 01 24 AM"
src="https://github.com/user-attachments/assets/27cb160e-c8cc-4107-a455-aa1ee9b392c4"
/>
2025-03-06 16:06:52 -08:00
Nate Barbettini
3638038ddf
fix: Package version in pyproject.toml is wrong (#276)
Package [1.0.5](https://pypi.org/project/arcade-ai/1.0.5/) is currently
the latest on pypi. The version number in pyproject.toml got out of
sync.

The next release should be 1.1.0 to take into account these minor
version changes that _should_ have bumped the version:
- https://github.com/ArcadeAI/arcade-ai/pull/243
- https://github.com/ArcadeAI/arcade-ai/pull/252
2025-03-05 16:15:23 -08:00
Nate Barbettini
4a0e2b8667
fix: Tool secret keys must use a case-insensitive comparison (#275)
Missed one test case here.
2025-03-04 14:33:55 -08: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
Nate Barbettini
3f7226709f
feat: Tool secrets (#252)
SDK support for tool secrets (stored and managed by the engine):
- [x] New `requires_secrets=` option in the `@tool` decorator
- [x] Internal plumbing in the catalog and `ToolContext`
- [x] Full test coverage of all added code
- [x] Bumped minor version (new feature)

This PR can be merged without waiting for Engine changes, because it is
additive only (no breaking changes).

After this is merged, I will open another PR to update existing toolkits
that will benefit from this feature!
2025-02-27 15:56:11 -08:00
Nate Barbettini
7466543bde
fix: add missing --model option (#270)
Fixes an inconsistency in `arcade chat --help`.

Before:
<img width="590" alt="image"
src="https://github.com/user-attachments/assets/bf643e3c-ee12-421a-8cd3-e0d322c0972a"
/>

After:
<img width="588" alt="image"
src="https://github.com/user-attachments/assets/c0a40cdf-3429-468c-9bf1-9e3710907796"
/>
2025-02-27 15:45:47 -08: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
Sam Partee
f997ca9449
Langchain-arcade README update (#268) 2025-02-26 00:08:06 -08:00
Eric Gustin
ad66667bdb
Update CrewAI example: Custom Auth Flow (#260) 2025-02-21 16:25:43 -08: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
Nate Barbettini
668e92934e
fix: Rename actor->worker in gh workflow dispatch (#263)
Fixes a typo (will be relevant later with future CI changes).
2025-02-20 14:15:30 -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
Eric Gustin
936319ccba
Fix langchain-arcade SyncOffsetPage iteration (#262)
## PR Description
The `ArcadeToolManager` was retrieving tools from the Arcade client
incorrectly as it was only returning the first page of results.

This PR removes the use of `SyncOffsetPage`'s `.items` attribute since
`.items` only contains the tools in the **current page**. Since
`SyncOffsetPage` implements an `__iter__` that iterates over all pages,
we can simply drop the `.items`.

## Try it for yourself
Run the following code without the changes in this PR and notice that
only 25 tools are in the internal tool list, which also happens to be
the size of a page. Now run again, but with the changes in this PR and
notice that all tools hosted by Arcade are in the internal tool list.
```python
import os

from langchain_arcade import ArcadeToolManager

arcade_api_key = os.environ.get("ARCADE_API_KEY")
manager = ArcadeToolManager(api_key=arcade_api_key)

tools = manager.init_tools()
print(len(manager.tools))
```
2025-02-20 13:24:03 -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
Eric Gustin
1e0def78df
CrewAI Arcade (#253)
# CrewAI Integration
crewai-arcade enables you to add Arcade tools and Arcade Auth into your
CrewAI applications. Just create an `ArcadeToolManager` and add your
tools to your CrewAI Agent/Tasks.

## Initializing the ArcadeToolManager
There are two main ways to initialize your `ArcadeToolManager`
1. Default handling of tool authorization and execution:
    ```py
    """
    When you provide a user id to the ArcadeToolManger, 
    it will handle the tool authorization and tool execution for you
    """
manager = ArcadeToolManager(default_user_id="me@example.com,
api_key="...")
    ```
2. Custom handling of tool authorization and execution
    ```py
    """
    Provide a callback function to the `ArcadeToolManager` that handles 
tool authorization and tool execution. The callback function will be
called whenever your CrewAI
    application wants to call a tool.
    """
    
    
    def custom_tool_executor(
manager: ArcadeToolManager, tool_name: str, **tool_input: dict[str, Any]
    ) -> Any:
        """Custom tool executor for the ArcadeToolManager
    
ArcadeToolManager's default executor handles authorization and tool
execution.
This function overrides the default executor to handle authorization and
tool execution
        in a custom way.
        """
        # Your custom tool auth logic goes here
        # Your custom tool execution logic goes here
        ...
    
manager = ArcadeToolManager(executor=custom_tool_executor,
api_key="...")
    ```

## Tool Registration
1. Initialize the tools in the manager
    ```py
    """
Clears any existing tools in the manager and replaces them with tools
and toolkits that are provided.
    """
    manager.init_tools(tools=["Google.ListEmails"], toolkits=["Slack"])
    ```
2. Add tools to the manager
    ```py
    """
    Adds tools and toolkits to the manager's internal tool list.
    """
    manager.add_tools(tools=["Google.ListEmails"], toolkits=["Slack"])
    ```
3. Retrieve tools and toolkits from the manager
    ```py
    """
    Retrieves the provided tools and toolkits as CrewAI StructuredTools.
    """
    manager.get_tools(tools=["Google.ListEmails"], toolkits=["Slack"])
    ```
    
 ## Auth Helpers
The `ArcadeToolManager` provides multiple helper methods for when you
need to create
a custom auth flow.
1. `authorize_tool` handles the whole authorization flow for you. This
is used internally when a custom auth flow is not needed.
2. `requires_auth(tool_name)` checks if the provided tool has
authorization requirements.
3. `authorize(tool_name, user_id)` authorizes the use of the provided
tool for the provided user ID
4. `is_authorized(tool_name, user_id)` checks if a tool is authorized
for use by the provided user ID
5. `wait_for_auth(auth_response)` waits for an authorization process to
complete before returning

## Tool Execution Helpers
1. `execute_tool` handles the whole tool execution flow for you. This is
used internally when a custom tool execution flow is not needed.

---------

Co-authored-by: lgesuellip <lgesuellipinto@uade.edu.ar>
Co-authored-by: lpetralli <123559656+lpetralli@users.noreply.github.com>
Co-authored-by: lgesuellip <102637283+lgesuellip@users.noreply.github.com>
Co-authored-by: “lgesuellip” <“lgesuellipinto@uade.edu.ar”>
2025-02-19 15:02:42 -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
3f655f7dca
Update README (#257)
Fixes some broken links in the Readme file
2025-02-18 13:53:34 -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
e636b686c1
Add @tool.deprecated (#247)
## PR Description
Add the ability to mark a tool as deprecated and display the warning in
the user's runtime. This PR also lays the foundation for future work for
emitting other levels of logs (debug, info, etc) that occur during the
tool's execution.

NOTE: Updates to the Arcade Clients (Python and JS) still need to be
done before the deprecation warning is emitted, but this PR needs to be
merged before those updates!

Let's cross our fingers that we'll never need to deprecate
`@tool.deprecated`!

### Example

1. Mark your tool as deprecated
```python
from typing import Annotated

from arcade.sdk import tool


@tool.deprecated("Use the 'Math.AddInt' tool instead.") # order of decorators does not matter
@tool
def add(
    a: Annotated[int, "The first number"], b: Annotated[int, "The second number"]
) -> Annotated[int, "The sum of the two numbers"]:
"""
Add two numbers together
"""
return a + b
```

2. Call the deprecated tool
```python
from arcadepy import Arcade

client = Arcade()

tool_input = {"a": 9001, "b": 42}

response = client.tools.execute(
    tool_name="Math.Add",
    input=tool_input,
    user_id="me@example.com",
)
print(f"The result of adding {tool_input['a']} and {tool_input['b']} is: {response.output.value}")
```

3. Observe the DeprecationWarning:
``` 
❯ python examples/call_a_tool_directly.py 
/Users/ericgustin/repos/Team/arcade-ai/examples/call_a_tool_directly.py:22: DeprecationWarning: 'Math.Add' is deprecated: Use the `Math.AddInt` tool instead.
  response = client.tools.execute(
The result of adding 9001 and 42 is: 9043
```
2025-02-18 13:27:49 -08:00
Eric Gustin
3870e84108
Workerup doesnt need to be logged in (#255) 2025-02-18 11:11:15 -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
Nate Barbettini
cb5cb7b730
fix: use correct UTF-8 encoding on Windows in arcade new (#246)
Fixes the linked issue. Tested on Windows 10
2025-02-12 14:50:46 -08:00
Sterling Dreyer
f31cabdf2b
Give release permissions (#245) 2025-02-10 16:07:25 -08:00
Eric Gustin
19086818d2
Make fastapi a regular dependency (#243)
## PR Description
Changes `pip install 'arcade-ai[fastapi]'` to `pip install arcade-ai`. 
In other words, FastAPI is now a required dependecy of arcade-ai.


Additionally, I snuck in some minor cleanup changes.
2025-02-10 15:30:51 -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
df969d9d73
Improve Arcade CLI (#244) 2025-02-08 10:56:04 -08: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
Nate Barbettini
9d49572f09
Update CDN URL to cdn.arcade.dev (#238)
Updates our public CDN URL.
2025-01-30 11:58:41 -08:00
Eric Gustin
a344cc0a8b
Use cross platform paths (#237)
# PR Description
Tiny PR to use `os.path.join` instead of hardcoding paths with forward
slashes.
2025-01-30 09:51:57 -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
Sterling Dreyer
8226cb3316
Fix CICD test wait (#235) 2025-01-27 14:48:33 -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
Sam Partee
778b7af83f
Update Langgraph examples (#231)
Clean up of the Langgraph examples that are used for the documentation.
Mostly just a restructuring for the update to
``langchain_arcade==1.0.0``
2025-01-26 23:38:59 -08:00
Sam Partee
7960158ee8
Update langchain integration to 1.0.0 (#230)
This PR updates the LangChain Arcade integration to v1.0.0, making the
following key changes:
• Bumped the package version in pyproject.toml from 0.2.0 to 1.0.0.
• Changed the default parameter in ArcadeToolManager from
langgraph=False to langgraph=True.
• Updated dependencies to require langgraph≥0.2.67,<0.3.0 and simplified
extras.
• Adjusted example scripts to remove explicit authorization_url
references in favor of a unified URL field.
• Updated docs and environment references to align with new usage
patterns and emphasize environment variables.
These changes unify and streamline the LangGraph-based tooling while
ensuring compatibility with the latest 1.0.0 release.
2025-01-26 22:23:14 -08:00
Nate Barbettini
4b5ce8d321
Fix dashboard redirect in docker compose (#229)
When the Engine is running via `docker compose`, the login redirect for
the Dashboard was ending up at `0.0.0.0` instead of `localhost`.
2025-01-24 16:40:33 -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
Sterling Dreyer
e78ff00831
Docker compose fixes (#226) 2025-01-24 10:29:15 -08:00
Nate Barbettini
a1db8a9f33
Fix login URL (fixes CSRF issues) (#225)
The CLI was starting the login process on the old domain, which is why
we were seeing a CSRF error. The cookie was placed on `arcade-ai.com`
not `arcade.dev`!
2025-01-23 22:44:57 -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
4c95b7bebb
arcade-ai Version 1.0.0 (#224) 2025-01-23 19:28:35 -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
6fb45c8797
Use AuthorizationResponse and ToolDefinition (#221) 2025-01-23 18:32:00 -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