| 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.
110 lines
4.6 KiB
Python
110 lines
4.6 KiB
Python
import logging
|
|
from pathlib import Path
|
|
from typing import Union, get_args
|
|
|
|
from stripe_agent_toolkit.functions import * # noqa: F403
|
|
from stripe_agent_toolkit.prompts import * # noqa: F403
|
|
from stripe_agent_toolkit.schema import * # noqa: F403
|
|
from stripe_agent_toolkit.tools import tools
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def get_type_str(arg_type):
|
|
"""Extract type name, handling Optional/Union types."""
|
|
if hasattr(arg_type, "__origin__") and arg_type.__origin__ is Union:
|
|
non_none = [a for a in get_args(arg_type) if a is not type(None)]
|
|
if len(non_none) == 1:
|
|
return non_none[0].__name__
|
|
return arg_type.__name__ if hasattr(arg_type, "__name__") else str(arg_type)
|
|
|
|
|
|
def generate_stripe_tools(
|
|
output_file: Path = Path("arcade_stripe") / "tools" / "stripe.py",
|
|
) -> None:
|
|
"""
|
|
Generate the Arcade AI Stripe Toolkit file from the stripe agent toolkit definitions.
|
|
"""
|
|
logger.info("Generating stripe tools file at %s", output_file)
|
|
try:
|
|
output_file.touch(exist_ok=True)
|
|
with output_file.open("w") as f:
|
|
f.write("""import os
|
|
from typing import Annotated, Optional
|
|
|
|
from stripe_agent_toolkit.api import StripeAPI
|
|
|
|
from arcade.sdk import ToolContext, tool
|
|
|
|
def run_stripe_tool(context: ToolContext, method_name: str, params: dict) -> str:
|
|
\"\"\"
|
|
Helper function that retrieves the Stripe secret key, initializes the API,
|
|
and executes the specified method with the provided parameters.
|
|
\"\"\"
|
|
api_key = context.get_secret("STRIPE_SECRET_KEY")
|
|
stripe_api = StripeAPI(secret_key=api_key, context=None)
|
|
params = {k: v for k, v in params.items() if v is not None}
|
|
return stripe_api.run(method_name, **params) # type: ignore[no-any-return]
|
|
|
|
""")
|
|
# Generate each tool function from the stripe agent toolkit
|
|
for tool_info in tools:
|
|
method_name = tool_info["method"]
|
|
method = globals().get(method_name)
|
|
if not method:
|
|
logger.warning("Method %s not found.", method_name)
|
|
continue
|
|
|
|
args_schema = tool_info["args_schema"]
|
|
description = tool_info["description"].strip()
|
|
|
|
arg_names = list(args_schema.__annotations__.keys())
|
|
arg_types = [args_schema.__annotations__[field] for field in arg_names]
|
|
|
|
params_list = []
|
|
for name, arg_type in zip(arg_names, arg_types, strict=False):
|
|
field = args_schema.model_fields[name]
|
|
# Check if the type annotation already includes Optional (i.e. Union[..., None])
|
|
is_optional_type = (
|
|
hasattr(arg_type, "__origin__")
|
|
and arg_type.__origin__ is Union
|
|
and type(None) in get_args(arg_type)
|
|
)
|
|
if field.is_required:
|
|
if is_optional_type:
|
|
params_list.append(
|
|
f"{name}: Annotated[{get_type_str(arg_type)} | None, "
|
|
f'"{field.description}"] = None'
|
|
)
|
|
else:
|
|
params_list.append(
|
|
f"{name}: Annotated[{get_type_str(arg_type)}, "
|
|
f'"{field.description}"]'
|
|
)
|
|
else:
|
|
default_repr = "None" if field.default is None else repr(field.default)
|
|
params_list.append(
|
|
f"{name}: Annotated[Optional[{get_type_str(arg_type)}], "
|
|
f'"{field.description}"] = {default_repr}'
|
|
)
|
|
params_str = ", ".join(params_list)
|
|
dict_items = ", ".join([f'"{name}": {name}' for name in arg_names])
|
|
arcade_tool_code = (
|
|
f'@tool(requires_secrets=["STRIPE_SECRET_KEY"])\n'
|
|
f"def {method_name}(context: ToolContext, {params_str}) -> "
|
|
f'Annotated[str, "{description.splitlines()[0]}"]:\n'
|
|
f' """{description.splitlines()[0]}"""\n'
|
|
f' return run_stripe_tool(context, "{method_name}", '
|
|
+ "{"
|
|
+ dict_items
|
|
+ "})\n\n"
|
|
)
|
|
f.write(arcade_tool_code)
|
|
except Exception:
|
|
logger.exception("An error occurred while generating stripe tools")
|
|
raise
|
|
|
|
|
|
if __name__ == "__main__":
|
|
generate_stripe_tools()
|