From 8e4f421b87e06b410572776cb9f2dfc1d01b86dc Mon Sep 17 00:00:00 2001 From: Himanshu Dixit Date: Thu, 9 Jan 2025 20:54:54 +0530 Subject: [PATCH 1/2] feat: switch from client.actions to getToolsSchema --- js/src/frameworks/vercel.spec.ts | 32 ++++++++++++++++++++++++++ js/src/frameworks/vercel.ts | 39 ++++++++++++++++---------------- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/js/src/frameworks/vercel.spec.ts b/js/src/frameworks/vercel.spec.ts index 560584e6e31..fcff883cb88 100644 --- a/js/src/frameworks/vercel.spec.ts +++ b/js/src/frameworks/vercel.spec.ts @@ -1,5 +1,7 @@ import { beforeAll, describe, expect, it } from "@jest/globals"; +import { z } from "zod"; import { getTestConfig } from "../../config/getTestConfig"; +import { ActionExecuteResponse } from "../sdk/models/actions"; import { VercelAIToolSet } from "./vercel"; describe("Apps class tests", () => { @@ -25,4 +27,34 @@ describe("Apps class tests", () => { }); expect(Object.keys(tools).length).toBe(1); }); + + it("Should create custom action to star a repository", async () => { + await vercelAIToolSet.createAction({ + actionName: "starRepositoryCustomAction", + toolName: "github", + description: "This action stars a repository", + inputParams: z.object({ + owner: z.string(), + repo: z.string(), + }), + callback: async ( + inputParams, + _authCredentials, + executeRequest + ): Promise => { + const res = await executeRequest({ + endpoint: `/user/starred/${inputParams.owner}/${inputParams.repo}`, + method: "PUT", + parameters: [], + }); + return res; + }, + }); + + const tools = await vercelAIToolSet.getTools({ + actions: ["starRepositoryCustomAction"], + }); + + await expect(Object.keys(tools).length).toBe(1); + }); }); diff --git a/js/src/frameworks/vercel.ts b/js/src/frameworks/vercel.ts index 75a3b7c9ed2..8ac4726426f 100644 --- a/js/src/frameworks/vercel.ts +++ b/js/src/frameworks/vercel.ts @@ -1,4 +1,4 @@ -import { jsonSchema, tool } from "ai"; +import { CoreTool, jsonSchema, tool } from "ai"; import { z } from "zod"; import { ComposioToolSet as BaseComposioToolSet } from "../sdk/base.toolset"; import { TELEMETRY_LOGGER } from "../sdk/utils/telemetry"; @@ -62,7 +62,7 @@ export class VercelAIToolSet extends BaseComposioToolSet { useCase?: Optional; usecaseLimit?: Optional; filterByAvailableApps?: Optional; - }): Promise<{ [key: string]: RawActionData }> { + }): Promise<{ [key: string]: CoreTool }> { TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { method: "getTools", file: this.fileName, @@ -78,25 +78,24 @@ export class VercelAIToolSet extends BaseComposioToolSet { actions, } = ZExecuteToolCallParams.parse(filters); - const actionsList = await this.client.actions.list({ - ...(apps && { apps: apps?.join(",") }), - ...(tags && { tags: tags?.join(",") }), - ...(useCase && { useCase: useCase }), - ...(actions && { actions: actions?.join(",") }), - ...(usecaseLimit && { usecaseLimit: usecaseLimit }), - filterByAvailableApps: filterByAvailableApps ?? undefined, - }); - - const tools = {}; - actionsList.items?.forEach((actionSchema) => { - // @ts-ignore - tools[actionSchema.name!] = this.generateVercelTool( - // @ts-ignore - actionSchema as ActionData - ); - }); + const tools = await this.getToolsSchema( + { + apps, + tags, + useCase, + filterByAvailableApps, + actions, + useCaseLimit: usecaseLimit, + }, + this.entityId + ); - return tools; + return Object.fromEntries( + tools.map((tool) => [ + tool.name, + this.generateVercelTool(tool as RawActionData), + ]) + ); } async executeToolCall( From 806f9e15fa1baab9534a18e1a184a04d93ef115d Mon Sep 17 00:00:00 2001 From: Himanshu Dixit Date: Fri, 10 Jan 2025 09:21:13 +0530 Subject: [PATCH 2/2] feat: remove trailing slash if exist --- js/src/sdk/client/core/OpenAPI.ts | 2 +- js/src/sdk/utils/config.ts | 6 +++++- js/src/utils/string.ts | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 js/src/utils/string.ts diff --git a/js/src/sdk/client/core/OpenAPI.ts b/js/src/sdk/client/core/OpenAPI.ts index 3687c05fcdf..e395cb6bad0 100644 --- a/js/src/sdk/client/core/OpenAPI.ts +++ b/js/src/sdk/client/core/OpenAPI.ts @@ -39,7 +39,7 @@ export type OpenAPIConfig = { }; }; -export const COMPOSIO_BASE_URL = "https://backend.composio.dev/"; +export const COMPOSIO_BASE_URL = "https://backend.composio.dev"; export const OpenAPI: OpenAPIConfig = { BASE: COMPOSIO_BASE_URL, diff --git a/js/src/sdk/utils/config.ts b/js/src/sdk/utils/config.ts index 485590ee5b9..9993a37b80f 100644 --- a/js/src/sdk/utils/config.ts +++ b/js/src/sdk/utils/config.ts @@ -8,6 +8,7 @@ import { AxiosInstance } from "axios"; import { getUUID } from "../../utils/common"; import logger from "../../utils/logger"; import { getEnvVariable } from "../../utils/shared"; +import { removeTrailingSlashIfExists } from "../../utils/string"; import apiClient from "../client/client"; import { client as axiosClient } from "../client/services.gen"; declare module "axios" { @@ -117,7 +118,10 @@ export function getSDKConfig(baseUrl?: string, apiKey?: string) { const apiKeyParsed = apiKey || getEnvVariable("COMPOSIO_API_KEY") || apiKeyFromUserConfig || ""; - return { baseURL: baseURLParsed, apiKey: apiKeyParsed }; + return { + baseURL: removeTrailingSlashIfExists(baseURLParsed), + apiKey: apiKeyParsed, + }; } // Get the API client diff --git a/js/src/utils/string.ts b/js/src/utils/string.ts new file mode 100644 index 00000000000..d97a8027fcf --- /dev/null +++ b/js/src/utils/string.ts @@ -0,0 +1,2 @@ +export const removeTrailingSlashIfExists = (str: string) => + str.replace(/\/$/, "");