Commit graph

448 commits

Author SHA1 Message Date
jottakka
b0c77a04e6
[PROD-186][ClickUp ToolKit][Auth] Update auth modules for ClickUp auth integration (#526)
[https://app.clickup.com/t/9014390315/PROD-186](PROD-186)

Small update for auth modules for ClickUp integration.

---------

Co-authored-by: Francisco Liberal <francisco@arcade.dev>
2025-08-13 14:39:01 -03:00
Renato Byrro
19c1e18a8a
arcade docs: add support for GPT-5 series; improve error handling (#529)
Adds support for GPT-5 series of models in `arcade docs`.

Improves error handling when the LLM does not generate a valid JSON for
a given tool sample inputs. Instead of raising an exception, the CLI
uses an empty input, moves on to the next tool, and prints a warning
message asking the user the fill in the input sample manually in
Javascript and Python files.

This PR also moves the Enumerations from a separate `reference.mdx` file
to the main toolkit file, as requested by @EricGustin to simplify the
docs structure.
2025-08-10 18:14:59 -05:00
Evan Tahler
a85fa76997
Clickhouse Toolkit (#527)
Generated from the postgres toolkit
2025-08-05 14:05:09 -07:00
Sterling Dreyer
7888dc505e
Fix venv files not being found (#525) 2025-08-01 12:12:35 -07:00
Renato Byrro
21f892c0a0
A couple of fixes for the docs generator (#524)
Display "This tool does not take any parameters." when the tool
interface has no arguments other than context.

Prevent the same Enum from being referenced multiple times in the
reference.mdx file.
2025-08-01 11:42:14 -03:00
Mateo Torres
02a0900846
optional github link in docs generation (#522)
This removes the github link to the toolkit code from the template
2025-07-29 14:51:34 -03:00
Eric Gustin
288ff61959
Update arcade new (#520)
This PR updates the `arcade new` CLI command.
* adds support for official arcade tools. 
* removes local libs sources for toolkits that are not a community or
official
* Stopped creating README for community toolkits
2025-07-29 10:35:36 -07:00
Sterling Dreyer
c97f2f7500
Bump CLI version (#521) 2025-07-28 16:22:05 -07:00
Sterling Dreyer
3f5c7aa6ba
Error on invalid toolkit file (#510)
Changes toolkit loading and deployments to error if there are syntax
errors in the file
2025-07-28 16:17:06 -07:00
Renato Byrro
ba8c3d3197
Rename auto-docs command to simply 'docs' and some other small improvements (#518)
Renames the `arcade generate-toolkit-docs` command to `arcade docs`. The
`arcade generate-toolkit-docs` command is preserved for backwards
compatibility, but it's now hidden.

Also some minor improvements to CLI help strings and better error
handling. Better error description when the toolkit is not installed
locally (also now mentioning this requirement in the command help).
2025-07-28 15:46:58 -03:00
Eric Gustin
7f26b83c19
Update examples (#516)
Update code examples to not use the deprecated Google toolkit (use Gmail
instead) and Web toolkit (use Firecrawl instead)
2025-07-28 09:49:00 -07:00
Eric Gustin
ca11ec9fa3
Add toolkits (#514)
Add Linkedin, Zendesk, Math, and Postgres toolkits
2025-07-25 15:44:06 -07:00
Sterling Dreyer
54da08f873
Disable Deployments (#513) 2025-07-24 16:51:53 -07:00
Eric Gustin
b50726d044
Remove Toolkits (#512)
As of today, Arcade's toolkits are moving to closed-source.  

Toolkit source code remains available upon request for our paying
customers. The history of this repository contains the toolkits as of
their most recent publication under their previous license terms.
2025-07-24 16:45:24 -07:00
Sam Partee
27a6cd31a3
Support Tool Output in ValueSchema of ToolDefinition (#487)
## Before

### Tool: ``GoogleNews.SearchNewsStories``

```python
@tool(requires_secrets=["SERP_API_KEY"])
async def search_news_stories(
    context: ToolContext,
    keywords: Annotated[
        str,
        "Keywords to search for news articles. E.g. 'Apple launches new iPhone'.",
    ],
    country_code: Annotated[
        CountryCode | None,
        "2-character country code to search for news articles. "
        "E.g. 'us' (United States). "
        f"Defaults to '{DEFAULT_GOOGLE_NEWS_COUNTRY}'.",
    ] = None,
    language_code: Annotated[
        LanguageCode,
        "2-character language code to search for news articles. E.g. 'en' (English). "
        f"Defaults to '{DEFAULT_GOOGLE_NEWS_LANGUAGE}'.",
    ] = DEFAULT_GOOGLE_NEWS_LANGUAGE,
    limit: Annotated[
        int | None,
        "Maximum number of news articles to return. Defaults to None "
        "(returns all results found by the API).",
    ] = None,
) -> Annotated[dict[str, Any]]:
    """Search for news articles related to a given query."""
    ...
```


### Tool Definition: ``GoogleNews.SearchNewsStories``
```
  {
    "name": "SearchNewsStories",
    "fully_qualified_name": "GoogleNews.SearchNewsStories",
    "description": "Search for news articles related to a given query.",
    "toolkit": {
      "name": "GoogleNews",
      "description": "Arcade.dev LLM tools for getting new via Google News",
      "version": "2.0.0"
    },
    "input": {
      "parameters": [
        {
          "name": "keywords",
          "required": true,
          "description": "Keywords to search for news articles. E.g. 'Apple launches new iPhone'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
          },
          "inferrable": true
        },
        {
          "name": "country_code",
          "required": false,
          "description": "2-character country code to search for news articles. E.g. 'us' (United States). Defaults to 'None'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
          },
          "inferrable": true
        },
        {
          "name": "language_code",
          "required": false,
          "description": "2-character language code to search for news articles. E.g. 'en' (English). Defaults to 'en'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
          },
          "inferrable": true
        },
        {
          "name": "limit",
          "required": false,
          "description": "Maximum number of news articles to return. Defaults to None (returns all results found by the API).",
          "value_schema": {
            "val_type": "integer",
            "inner_val_type": null,
            "enum": null,

          },
          "inferrable": true
        }
      ]
    },
    "output": {
      "description": "News search results with article details.",
      "available_modes": [
        "value",
        "error"
      ],
      "value_schema": {
        "val_type": "json"
      }
    },
    "requirements": {
      "authorization": null,
      "secrets": [
        {
          "key": "serp_api_key"
        }
      ],
      "metadata": null
    },
    "deprecation_message": null
  },
```

## After

### Enhanced Tool: ``GoogleNews.SearchNewsStories``

```python

"""Type definitions for Google News API responses and parameters."""

from typing_extensions import TypedDict

CountryCode = str
LanguageCode = str


class SearchNewsParams(TypedDict):
    """Input parameters for searching news articles."""

    keywords: str
    """Search query terms to find relevant news articles \
    (e.g., 'Apple launches new iPhone')."""

    country_code: CountryCode | None
    """Optional 2-letter country code to filter news by region \
    (e.g., 'us' for United States, 'uk' for United Kingdom)."""

    language_code: LanguageCode | None
    """Optional 2-letter language code to filter news by language \
    (e.g., 'en' for English, 'es' for Spanish)."""

    limit: int | None
    """Optional maximum number of news articles to return. \
    If not specified, returns all results from the API."""


class SourceInfo(TypedDict, total=False):
    """Information about the news source/publication."""

    name: str
    """Name of the publication (e.g., 'CNN', 'BBC News', 'The New York Times')."""

    icon: str
    """URL to the source's favicon or logo image."""

    authors: list[str]
    """List of author names for the article, if available."""


class NewsResult(TypedDict, total=False):
    """Individual news article from the Google News API response."""

    position: int
    """Ranking position of this result in the search results."""

    title: str
    """Headline or title of the news article."""

    link: str
    """Full URL to the original news article."""

    source: SourceInfo
    """Information about the publication source."""

    date: str
    """Publication date and time (e.g., '2 hours ago', 'Dec 15, 2023')."""

    snippet: str
    """Brief excerpt or summary from the article content."""

    thumbnail: str
    """URL to a high-resolution thumbnail image for the article."""

    thumbnail_small: str
    """URL to a low-resolution thumbnail image for the article."""

    story_token: str
    """Token for accessing full coverage of this news story across multiple sources."""

    stories: list["NewsResult"]
    """Related news stories from other sources covering the same topic."""

    highlight: dict
    """Additional highlighted information about the story."""


class SearchMetadata(TypedDict, total=False):
    """Metadata about the search request and processing."""

    id: str
    """Unique identifier for this search request within SerpApi."""

    status: str
    """Current processing status ('Processing', 'Success', or 'Error')."""

    json_endpoint: str
    """URL to retrieve the JSON results for this search."""

    created_at: str
    """Timestamp when the search request was created."""

    processed_at: str
    """Timestamp when the search request was processed."""

    google_news_url: str
    """Original Google News URL that would return these results."""

    total_time_taken: float
    """Total time in seconds taken to process this search."""


class SearchParameters(TypedDict, total=False):
    """Parameters used for the search request."""

    engine: str
    """Search engine used (always 'google_news' for this API)."""

    q: str
    """Search query string."""

    gl: str
    """Country code used for geographic filtering."""

    hl: str
    """Language code used for language filtering."""

    topic_token: str
    """Token for accessing specific news topics (e.g., 'World', 'Business', 'Technology')."""

    publication_token: str
    """Token for accessing news from specific publishers."""


class MenuLink(TypedDict):
    """Navigation link for news categories or topics."""

    title: str
    """Display text for the menu item (e.g., 'Technology', 'Sports', 'Business')."""

    topic_token: str
    """Token to access this specific topic or category."""

    serpapi_link: str
    """SerpApi URL to search within this topic."""


class TopStoriesLink(TypedDict):
    """Link to top stories section."""

    topic_token: str
    """Token to access top stories."""

    serpapi_link: str
    """SerpApi URL to retrieve top stories."""


class GoogleNewsResponse(TypedDict, total=False):
    """Complete response from the Google News API."""

    search_metadata: SearchMetadata
    """Metadata about the search request and processing."""

    search_parameters: SearchParameters
    """Parameters that were used for this search."""

    news_results: list[NewsResult]
    """List of news articles matching the search criteria."""

    menu_links: list[MenuLink]
    """Navigation links to different news categories and topics."""

    top_stories_link: TopStoriesLink
    """Link to access top stories."""

    title: str
    """Title of the page or topic being displayed."""


class SimplifiedNewsResult(TypedDict):
    """Simplified news article format for tool output."""

    title: str
    """Headline of the news article."""

    link: str
    """URL to the full article."""

    source: str | None
    """Name of the publication source."""

    date: str | None
    """When the article was published."""

    snippet: str | None
    """Brief excerpt from the article."""


class SearchNewsOutput(TypedDict):
    """Output format for the search_news_stories tool."""

    news_results: list[SimplifiedNewsResult]
    """List of news articles in simplified format."""

@tool(requires_secrets=["SERP_API_KEY"])
async def search_news_stories(
    context: ToolContext,
    keywords: Annotated[
        str,
        "Keywords to search for news articles. E.g. 'Apple launches new iPhone'.",
    ],
    country_code: Annotated[
        CountryCode | None,
        "2-character country code to search for news articles. "
        "E.g. 'us' (United States). "
        f"Defaults to '{DEFAULT_GOOGLE_NEWS_COUNTRY}'.",
    ] = None,
    language_code: Annotated[
        LanguageCode,
        "2-character language code to search for news articles. E.g. 'en' (English). "
        f"Defaults to '{DEFAULT_GOOGLE_NEWS_LANGUAGE}'.",
    ] = DEFAULT_GOOGLE_NEWS_LANGUAGE,
    limit: Annotated[
        int | None,
        "Maximum number of news articles to return. Defaults to None "
        "(returns all results found by the API).",
    ] = None,
) -> Annotated[SearchNewsOutput, "News search results with article details."]:
    """Search for news articles related to a given query."""
    ...

```

### Enhanced Tool Definition: ``GoogleNews.SearchNewsStories`` 

```json

  {
    "name": "SearchNewsStories",
    "fully_qualified_name": "GoogleNews.SearchNewsStories",
    "description": "Search for news articles related to a given query.",
    "toolkit": {
      "name": "GoogleNews",
      "description": "Arcade.dev LLM tools for getting new via Google News",
      "version": "2.0.0"
    },
    "input": {
      "parameters": [
        {
          "name": "keywords",
          "required": true,
          "description": "Keywords to search for news articles. E.g. 'Apple launches new iPhone'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
            "properties": null,
            "inner_properties": null,
            "description": null
          },
          "inferrable": true
        },
        {
          "name": "country_code",
          "required": false,
          "description": "2-character country code to search for news articles. E.g. 'us' (United States). Defaults to 'None'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
            "properties": null,
            "inner_properties": null,
            "description": null
          },
          "inferrable": true
        },
        {
          "name": "language_code",
          "required": false,
          "description": "2-character language code to search for news articles. E.g. 'en' (English). Defaults to 'en'.",
          "value_schema": {
            "val_type": "string",
            "inner_val_type": null,
            "enum": null,
            "properties": null,
            "inner_properties": null,
            "description": null
          },
          "inferrable": true
        },
        {
          "name": "limit",
          "required": false,
          "description": "Maximum number of news articles to return. Defaults to None (returns all results found by the API).",
          "value_schema": {
            "val_type": "integer",
            "inner_val_type": null,
            "enum": null,
            "properties": null,
            "inner_properties": null,
            "description": null
          },
          "inferrable": true
        }
      ]
    },
    "output": {
      "description": "News search results with article details.",
      "available_modes": [
        "value",
        "error"
      ],
      "value_schema": {
        "val_type": "json",
        "inner_val_type": null,
        "enum": null,
        "properties": {
          "news_results": {
            "val_type": "array",
            "inner_val_type": "json",
            "enum": null,
            "properties": null,
            "inner_properties": {
              "title": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "Headline of the news article."
              },
              "link": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "URL to the full article."
              },
              "source": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "Name of the publication source."
              },
              "date": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "When the article was published."
              },
              "snippet": {
                "val_type": "string",
                "inner_val_type": null,
                "enum": null,
                "properties": null,
                "inner_properties": null,
                "description": "Brief excerpt from the article."
              }
            },
            "description": "List of news articles in simplified format."
          }
        },
        "inner_properties": null,
        "description": null
      }
    },
    "requirements": {
      "authorization": null,
      "secrets": [
        {
          "key": "serp_api_key"
        }
      ],
      "metadata": null
    },
    "deprecation_message": null
  },

```

---------

Co-authored-by: Eric Gustin <eric@arcade.dev>
2025-07-24 15:32:35 -07:00
Evan Tahler
4144a42392
Make the postgres toolikit better (#509)
Per the discussions in the [blog
post](https://docs.google.com/document/d/1wZi1yKWKOyg1dpueA2eBvTtYlUjqqp7e_M1nuAoF8NY/edit?tab=t.0),
let's update the postgres toolkit!

<img width="2141" height="1364" alt="Screenshot 2025-07-22 at 5 28
06 PM"
src="https://github.com/user-attachments/assets/1b6a5e0a-9429-4c16-9a0c-ac36ea520bea"
/>
2025-07-23 15:28:57 -07:00
Renato Byrro
30739dc44a
Support for multiple Atlassian Clouds in the Jira Toolkit (#506)
Adds `Jira.GetAvailableAtlassianClouds` tool, which provides a list of
clouds available (checking which Clouds were actually authorized by the
current auth token).

Refactors the interface of every tool to accept an `atlassian_cloud_id`
argument (when not provided, try to get a unique cloud ID - if multiple
are available, raises a Retryable error with the list of Clouds
available instructing to select one).

Gets rid of all caching. Now storing the global semaphore to the context
object. The global semaphore is important because some tools depend on
others, and each tool instantiates its own Jira HTTP client. Storing the
semaphore in the context object ensures that all HTTP clients will
respect the concurrency limit.

Removes from tool responses the Atlassian URLs linking to objects in the
Jira GUI (users, projects, issues, etc. We do not keep track of the
cloud name anymore, which is required to build the objects' URLs.

Extends/refactors unit tests accordingly.

Evals checking LLM behavior when:

- a cloud ID is explicitly mentioned in the prompt;
- no cloud ID is mentioned;
- a "multiple clouds available" error is raised and the user is prompted
to pick one;
- user request triggers another tool call after having previously picked
a cloud ID (in the same chat context);
2025-07-23 18:09:54 -03:00
Sterling Dreyer
903340bb0c
Fix setuptools install (#508) 2025-07-22 17:38:40 -07:00
Sterling Dreyer
a4468d4426
Update setuptools (#507) 2025-07-22 15:03:48 -07:00
Sterling Dreyer
f4480c3945
Fix arcade worker list endpoints (#504)
We weren't checking that the engine version of the worker was the same
as the cloud version that we were comparing against and incorrectly
saying the URL was wrong

Before
<img width="1447" height="340" alt="Screenshot 2025-07-21 at 1 55 13 PM"
src="https://github.com/user-attachments/assets/cf39ce9f-0c86-45fd-a68e-c92369876292"
/>

After
<img width="1454" height="308" alt="Screenshot 2025-07-21 at 1 55 07 PM"
src="https://github.com/user-attachments/assets/efcfe6c8-b892-45f7-bf4c-71edc66c8325"
/>
2025-07-21 14:43:58 -07:00
Eric Gustin
4598e1e4d4
Updates to Notion toolkit (#476)
### Adds one new tool to the Notion toolkit
* **AppendContentToEndOfPage**: Append markdown content to the end of a
Notion page by its ID or title

### Fixes a bug
* The **CreatePage** would previously fail if the content provided was
broken into more than 100 blocks. I added 'chunking' logic to support >
100 blocks.
2025-07-18 17:35:12 -07:00
Mateo Torres
173cc6994e
bugfix: URL expansion in Twitter (#500)
This solves an edge case where the `"url"` entity does not have an
`"expanded_url"` case when expanding. The behavior for now is simply
don't replace the URL as it seems the display_url is NOT what we want to
keep as it's normally abbreviated

---------

Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
2025-07-18 18:20:06 -03:00
Shub
0b1f513826
Add Simplified Linear Toolkit (#465)
This PR adds a simplified Linear toolkit focused on core functionality:

## What's Included

**Tools:**
- `get_issue` - Get detailed information about Linear issues
- `get_teams` - Get team information and details

**Models:**
- `DateRange` enum with comprehensive date range support (TODAY,
YESTERDAY, THIS_WEEK, LAST_WEEK, THIS_MONTH, LAST_MONTH, THIS_YEAR,
LAST_YEAR, LAST_7_DAYS, LAST_30_DAYS)
- Timezone-aware datetime handling following Google toolkit patterns

## What's Simplified

This toolkit has been streamlined by removing:
- Cycles management tools
- Projects management tools  
- Users management tools
- Workflows management tools
- Corresponding tests and evaluations for removed features

## Quality Assurance

- All linting and formatting checks pass
- Comprehensive test coverage for included functionality
- Follows established patterns from Google toolkit

---------

Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
2025-07-18 14:08:58 -07:00
Eric Gustin
cb7b386a43
Add Linear as wellknown provider (#494)
Blocked by Engine PR
2025-07-18 13:44:26 -07:00
Renato Byrro
d5ae347801
Toolkit docs generator command for Arcade CLI (#414) 2025-07-18 11:22:21 -03:00
Lucas Petralli
1843e411f3
Add Zendesk Toolkit (#458)
This PR adds a new toolkit for integrating with Zendesk Help Center and
ticketing system.

  Features

- Search Articles: Search Help Center knowledge base with filters for
text, categories, labels, and dates
  - List Tickets: Retrieve all open support tickets
- Get Comments: Retrieve all comments for a specific ticket to
understand the context
  - Add Comments: Add public or internal comments to existing tickets
- Solve Tickets: Mark tickets as solved with optional internal
resolution comments

  Testing & Quality
  - Comprehensive test suite 
  - Evaluation scripts for real-world testing
  - All tests passing (make test)
  - Code quality checks passing (make check)
  - All evals passing

---------

Co-authored-by: “lgesuellip” <“lgesuellipinto@uade.edu.ar”>
Co-authored-by: lgesuellip <102637283+lgesuellip@users.noreply.github.com>
Co-authored-by: “lgesuellip” <lgesuellipinto@uade.edu.ar>
2025-07-17 13:34:26 -07:00
Evan Tahler
e1cf58fe1b
skip tests with GHA secrets on forks (#496) 2025-07-17 10:27:24 -07:00
Evan Tahler
b81bb86dfb
Skip tests that require secrets in forks (#495)
We know that forks won't have our secrets, so we separate those toolkits
out to new a new test group and skip them if you aren't in this main
repo. We know if a test suite has a secret via a magic comment

---------

Co-authored-by: Eric Gustin <34000337+EricGustin@users.noreply.github.com>
2025-07-16 16:53:26 -07:00
Eric Gustin
856606f38c
Remove arcade_ prefix requirement and add entry point toolkit discovery (#485)
## Summary
This PR removes the requirement that all toolkits must have the arcade_
prefix and introduces a more flexible toolkit discovery system using
Python entry points.

### 🏷️ Flexible Toolkit Naming
* Community toolkits: Only add arcade_ prefix when the user is in
arcade-ai/toolkits/ directory and explicitly chooses to create a
community contribution.
* External toolkits: No prefix requirement - developers can name their
toolkits however they want
* Toolkit names are now determined by user choice rather than enforced
automatically
### 🔍 Entry Point Discovery
* Added find_arcade_toolkits_from_entrypoints() method to discover
toolkits via entry points
* Entry point group: arcade_toolkits with name: toolkit_name
* Updated pyproject.toml template to include entry point configuration
* Entry point discovery takes precedence over prefix-based discovery for
deduplication
### 📦 Backward Compatibility
* Existing arcade_* prefixed toolkits continue to work via
find_arcade_toolkits_from_prefix()
find_all_arcade_toolkits() now combines both discovery methods
* Deduplication logic prefers entry point toolkits over prefix-based
ones when package names match
### 🛠️ `arcade new` Template Updates
* pyproject.toml template for `arcade new` now includes entry point
configuration: [project.entry-points.arcade_toolkits]
### 🔧 Minor Improvements
* Refactored _strip_arcade_prefix() into a separate method for
reusability
* Updated variable naming for clarity (community_toolkit →
is_community_toolkit)
### Benefits
* Developer Freedom: Toolkit developers are no longer forced to use the
arcade_ prefix. They are also no longer forced to use the package name
as the toolkit name.
* Cleaner Naming: External toolkits can use more natural names (e.g.,
my_company_toolkit instead of arcade_my_company_toolkit)
* Better Discovery: Entry points provide a more standard Python
mechanism for plugin discovery
* Flexible Distribution: Toolkits can be distributed with any package
name while still being discoverable
### Testing
* Added comprehensive tests for the new entry point functionality
* Tests cover edge cases like deduplication, error handling, and
backward compatibility
### Version Bumps
arcade-core: 2.0.0 → 2.1.0
arcade-ai: 2.0.5 → 2.1.0

This change makes the Arcade toolkit ecosystem more flexible and
developer-friendly while maintaining full backward compatibility with
existing toolkits.

---------

Co-authored-by: Mateo Torres <mateo@arcade.dev>
2025-07-16 09:51:21 -07:00
Sterling Dreyer
32292d4b39
Fix login callback (#489) 2025-07-15 11:21:33 -07:00
Renato Byrro
3f6c7a5595
Fix bug in Slack user processing (#488) 2025-07-15 14:52:52 -03:00
Evan Tahler
e715ae912f
custom callback_host for arcade login (#481)
Say you are @shubcodes and running arcade on replit or vs codespaces.
Today, `arcade login` assumes that the browser you've opened for the
auth flow's "localhost" is the same that is running the `arcade login`
command. If you are running on one of these remote code execution
environments, that won't be true.

Usage:
```
arcade login --callback-host "https://replit.com:9999/path/to/my/codespace"
```
2025-07-14 10:53:26 -07:00
Eric Gustin
b1e3c334f0
Update Slack webhook step (#484)
This _should_ fix it
2025-07-11 18:14:05 -07:00
Evan Tahler
40cdf2018d
Postgres Database Toolkit (#459)
Adds an example of a good "general case" SQL tool:
* enforces read-only mode
* hints to the LLM to discover the tables and schemas for the tables it
needs before any query
* uses RetryableToolErrors to hint to the LLM about what to do next

Docs: https://github.com/ArcadeAI/docs/pull/345

For testing, `TEST_POSTGRES_DATABASE_CONNECTION_STRING` has been set in
the repo (from Neon). details in 1 password.

<img width="1178" height="1091"
alt="464977013-49aff5e5-e301-4ca0-83b5-3ea742db2283"
src="https://github.com/user-attachments/assets/9344c27b-015d-4b91-907e-84f2e4193e16"
/>
2025-07-11 17:30:40 -07:00
Renato Byrro
1b0547090c
Temporarily remove Slack mpim:write scope (#482) 2025-07-11 18:57:24 -03:00
Eric Gustin
64c7771e36
Officially publish new split toolkits to PyPI (#480)
No more release candidate versions!
2025-07-11 12:34:21 -07:00
Evan Tahler
6889d8673b
--debug for CLI commands (#454)
```
(base) ➜  arcade-ai git:(debug) ✗ uv run arcade busted-command --host invalid-host
 Login failed with error: Not implemented
^C
Aborted.


(base) ➜  arcade-ai git:(debug) ✗ uv run arcade busted-command --host invalid-host --debug
 Login failed with error: Traceback (most recent call last):
  File "/Users/evan/workspace/arcade/Team/arcade-ai/libs/arcade-cli/arcade_cli/main.py", line 106, in login
    raise Exception("Not implemented")
Exception: Not implemented
```
2025-07-10 14:52:25 -07:00
Eric Gustin
836c890840
Release candidates for new toolkits (#479)
New toolkit versions are release candidates now.

Also fixed a test for e2b toolkit.

Also, I am explicitly not running test for toolkits for the post merge
workflow because they are run on every PR commit (i.e., they must pass
before we even merge)
2025-07-10 10:34:19 -07:00
Renato Byrro
ed89af4b4d
Slack Toolkit Refactoring (#453)
# Backwards-compatible refactoring of the Slack toolkit

Several performance improvements, streamlined tool set, and easier to
understand tool interfaces.

All "old" tools were kept for backwards compatibility, with the same
interfaces and response structure (but using the new and more performant
tools under the hood).

Full revision of unit-tests and evals.

##  Streamlined tool set

Multiple groups of tools were streamlined into a single one:

* "get conversation metadata" from 5 tools to one;
* "send message" from 2 tools to one;
* "get users in conversation" from 3 tools to one;
* "get messages" from 4 tools to one

## New capabilities

* Messages retrieved are now populated with the users' names, apart from
ID: makes it easier for LLMs to reference who sent a message, were
mentioned, or reacted to a message
* Retrieve users by username, email, and/or ID (before we only supported
ID)
* Retrieve multiple users in a single tool call

## Concurrency controls

All operations issuing multiple requests concurrently now have a
`Semaphore` to limit the concurrency level. The limit can be controlled
through the `SLACK_MAX_CONCURRENT_REQUESTS` env var (defaults to 3).

## Networking performance improvement

Various operations that used to make multiple API calls are now executed
more efficiently:

### Find users by username

* Before: a full scan of `users_list` was required (potentially multiple
pages for large workspaces);
* Now it stops as soon as we have all users needed (yes, it was dumb
before)

### Get multiple users by their IDs

* Before: for each user ID, we made one API call to the `users_info`
endpoint
* Now: we call `list_users` and scan the results to match the user IDs
(an estimate of 99.5% of Slack workspaces have < 200 users; for large
workspaces, we may need to paginate `list_users`)

### Get a conversation by its users

* Before:
  * Call to `list_conversations` (potentially paginating)
* For each conversation, one call to `conversations_members`
(potentially paginating)
  * Then loop and find which conversation matches the users' IDs
* Now:
  * A single call to `conversations_open`
2025-07-10 13:50:28 -03:00
Eric Gustin
07c52100f3
Split and rename multiple toolkits (#438)
# PR Description
## Split toolkits

This PR splits the `Microsoft`, `Google`, and `Search` toolkits into
multiple toolkits each.
 * `Microsoft` --> `OutlookCalendar`, `OutlookMail`.
* `Google` -----> `GoogleCalendar`, `GoogleContacts`, `GoogleDocs`,
`GoogleDrive`, `Gmail`, `GoogleSheets`
* `Search` -----> `GoogleFinance`, `GoogleFlights`, `GoogleHotels`,
`GoogleJobs`, `GoogleMaps`, `GoogleNews`, `GoogleSearch`,
`GoogleShopping`, `Walmart`, `Youtube`

> The original monolithic toolkits (`Microsoft`, `Google`, `Search`) are
not removed in this PR. The plan is to keep those toolkits around while
we
> 1. Stop documenting the toolkits, 
> 2. Stop displaying the toolkits in the dashboard, and 
> 3. Help customers migrate over to the new split toolkits.

## Rename toolkits
This PR renames the following toolkits 
* `Web` ------------> `Firecrawl`
* `CodeSandbox` ---> `E2B`

> The `Web` and `CodeSandbox` toolkits are not removed in this PR. The
plan is to keep them around while we
> 1. Stop documenting the toolkits, 
> 2. Stop displaying the toolkits in the dashboard, and 
> 3. Help customers migrate over to the new renamed toolkits.

## Rename tools
Since toolkit names were changed, this called for some tools to be
renamed as well.
* `GoogleSearch.SearchGoogle` ----------------> `GoogleSearch.Search`
* `GoogleShopping.SearchShoppingProducts` --->
`GoogleShopping.SearchProducts`
* `Walmart.SearchWalmartProducts` ------------> `Walmart.SearchProducts`
* `Walmart.GetWalmartProductDetails` --------->
`Walmart.GetProductDetails`
* `Youtube.SearchYoutubeVideos` -------------->
`Youtube.SearchForVideos`

## Google File Picker
Improvements to the Google File Picker experience were also added in
this PR.

The following tools will ALWAYS provide llm_instructions in their
response to "let the end-user know that they have the option to select
more files via the file picker url if they want to":
* `GoogleDocs.SearchDocuments`
* `GoogleDocs.SearchAndRetrieveDocuments`
* `GoogleDrive.GetFileTreeStructure`

The following tools will only provide the file picker URL if a 404 or
403 from the Google API:
* `GoogleDocs.InsertTextAtEndOfDocument`
* `GoogleDocs.GetDocumentById`
* `GoogleSheets.GetSpreadsheet`
* `GoogleSheets.WriteToCell`

Also, a standalone `GoogleDrive.GenerateGoogleFilePickerUrl` tool
exists.

## Other
* The `SearchDocuments` and `SearchAndRetrieveDocuments` tools used to
be organized within the Drive portion of the Google toolkit, but I moved
these into the new GoogleDocs toolkit because they are specific to Docs.

# Progress

- [x] `OutlookCalendar`
- [x] `OutlookMail`
- [x] `GoogleFinance`
- [x] `GoogleFlights`
- [x] `GoogleHotels`
- [x] `GoogleJobs`
- [x] `GoogleMaps`
- [x] `GoogleNews`
- [x] `GoogleSearch`
- [x] `GoogleShopping`
- [x] `Walmart`
- [x] `Youtube`
- [x] `GoogleCalendar`
- [x] `GoogleContacts`
- [x] `GoogleDocs`
- [x] `GoogleDrive`
- [x] `Gmail`
- [x] `GoogleSheets`
- [x] `Firecrawl`
- [x] `E2B`
- [x] File picker

# Discussion
* Repeated code is a consequence of splitting toolkits that use the same
provider. I am open to any ideas that would allow multiple toolkits to
reference common code. Comment your ideas in this PR.
2025-07-09 16:00:09 -07:00
Mateo Torres
a30fc9379a
added ruff toml and pre-comit files to template if community (#477)
This reintroduces a question into `arcade new`, which adds the ruff and
pre-commit files into new toolkits that are aimed to be contributed back
to Arcade AI.

I use it in the toolkit building tutorial

---------

Co-authored-by: Evan Tahler <evantahler@gmail.com>
2025-07-09 14:04:30 -03:00
Sergio Serrano
de7b655214
Update dependencies (#473) 2025-07-02 14:37:13 -03:00
Eric Gustin
490cb8ae38
Fix existing Slack test & bump TK versions (#471) 2025-07-01 14:13:45 -07:00
Eric Gustin
bfd183f06b
Bump versions (#470) 2025-07-01 13:43:33 -07:00
Eric Gustin
a336f43a83
Fix release workflow for toolkits (#469)
The workflow didn't work correctly for toolkits. see run logs for more
info on how it didn't work correctly:
https://github.com/ArcadeAI/arcade-ai/actions/runs/16008156518/job/45159613768

Bumped the code-sandbox toolkit to prove it works. Proof it worked:
https://github.com/ArcadeAI/arcade-ai/actions/runs/16009427831/job/45163629931?pr=469
2025-07-01 13:29:59 -07:00
Eric Gustin
1d9a4f2275
Bump toolkit versions (#468)
The PyPI packages haven't been bumped since migrating them to use the
TDK. This PR excludes bumping Jira since it was bumped last week.
2025-07-01 12:14:41 -07:00
Eric Gustin
87b7d0fdaf
Bump CLI version (#467) 2025-07-01 11:35:13 -07:00
Eric Gustin
a1dcd7667e
Update toolkit Makefiles (#466) 2025-07-01 11:29:12 -07:00
Eric Gustin
ff8675e4b6
Filter out unneeded files/directories before deploying workers (#464)
`arcade deploy` is failing for local packages that have large unneeded
files such as `uv.lock`. It is failing because it is taking too long for
the CLI to compress and PUT to the cloud.
2025-07-01 10:07:15 -07:00
Eric Gustin
30e36e1325
Update slack notification for PyPI publishes (#463)
Update the Slack notification to use the "package" notification instead
of the "toolkit" notification since this workflow runs for not only
toolkits but also our libs.
2025-07-01 10:00:35 -07:00