diff --git a/app/settings/connectors/page.tsx b/app/settings/connectors/page.tsx new file mode 100644 index 000000000..442f6db3e --- /dev/null +++ b/app/settings/connectors/page.tsx @@ -0,0 +1,18 @@ +"use client"; + +import { Suspense } from "react"; +import { ConnectorsPage } from "@/components/ConnectorsPage"; + +export default function SettingsConnectorsPage() { + return ( + +

Loading...

+ + } + > + +
+ ); +} diff --git a/components/ConnectorsPage/ConnectorCard.tsx b/components/ConnectorsPage/ConnectorCard.tsx new file mode 100644 index 000000000..1dbeca5e9 --- /dev/null +++ b/components/ConnectorsPage/ConnectorCard.tsx @@ -0,0 +1,65 @@ +"use client"; + +import { ConnectorInfo } from "@/hooks/useConnectors"; +import { useConnectorHandlers } from "@/hooks/useConnectorHandlers"; +import { getConnectorMeta } from "@/lib/composio/connectorMetadata"; +import { formatConnectorName } from "@/lib/composio/formatConnectorName"; +import { getConnectorIcon } from "@/lib/composio/getConnectorIcon"; +import { ConnectorConnectedMenu } from "./ConnectorConnectedMenu"; +import { ConnectorEnableButton } from "./ConnectorEnableButton"; + +interface ConnectorCardProps { + connector: ConnectorInfo; + onConnect: (slug: string) => Promise; + onDisconnect: (connectedAccountId: string) => Promise; +} + +/** + * Card component for a single connector. + */ +export function ConnectorCard({ + connector, + onConnect, + onDisconnect, +}: ConnectorCardProps) { + const { isConnecting, isDisconnecting, handleConnect, handleDisconnect } = + useConnectorHandlers({ + slug: connector.slug, + connectedAccountId: connector.connectedAccountId, + onConnect, + onDisconnect, + }); + const meta = getConnectorMeta(connector.slug); + + return ( +
+
+ {getConnectorIcon(connector.slug, 22)} +
+ +
+

+ {formatConnectorName(connector.name, connector.slug)} +

+

+ {meta.description} +

+
+ +
+ {connector.isConnected ? ( + + ) : ( + + )} +
+
+ ); +} diff --git a/components/ConnectorsPage/ConnectorConnectedMenu.tsx b/components/ConnectorsPage/ConnectorConnectedMenu.tsx new file mode 100644 index 000000000..ac1850ce2 --- /dev/null +++ b/components/ConnectorsPage/ConnectorConnectedMenu.tsx @@ -0,0 +1,56 @@ +import { Loader2, MoreVertical, RefreshCw, Unlink, CheckCircle } from "lucide-react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; + +interface ConnectorConnectedMenuProps { + isDisconnecting: boolean; + onReconnect: () => void; + onDisconnect: () => void; +} + +export function ConnectorConnectedMenu({ + isDisconnecting, + onReconnect, + onDisconnect, +}: ConnectorConnectedMenuProps) { + return ( +
+ + Connected + + + + + + + + + + Reconnect + + + {isDisconnecting ? ( + + ) : ( + + )} + {isDisconnecting ? "Disconnecting..." : "Disconnect"} + + + +
+ ); +} diff --git a/components/ConnectorsPage/ConnectorEnableButton.tsx b/components/ConnectorsPage/ConnectorEnableButton.tsx new file mode 100644 index 000000000..5fb5868a3 --- /dev/null +++ b/components/ConnectorsPage/ConnectorEnableButton.tsx @@ -0,0 +1,22 @@ +import { Loader2 } from "lucide-react"; + +interface ConnectorEnableButtonProps { + isConnecting: boolean; + onClick: () => void; +} + +export function ConnectorEnableButton({ + isConnecting, + onClick, +}: ConnectorEnableButtonProps) { + return ( + + ); +} diff --git a/components/ConnectorsPage/ConnectorsEmptyState.tsx b/components/ConnectorsPage/ConnectorsEmptyState.tsx new file mode 100644 index 000000000..4966c07e6 --- /dev/null +++ b/components/ConnectorsPage/ConnectorsEmptyState.tsx @@ -0,0 +1,7 @@ +export function ConnectorsEmptyState() { + return ( +

+ No connectors available. +

+ ); +} diff --git a/components/ConnectorsPage/ConnectorsErrorBanner.tsx b/components/ConnectorsPage/ConnectorsErrorBanner.tsx new file mode 100644 index 000000000..c8d07ec96 --- /dev/null +++ b/components/ConnectorsPage/ConnectorsErrorBanner.tsx @@ -0,0 +1,13 @@ +interface ConnectorsErrorBannerProps { + error: string | null; +} + +export function ConnectorsErrorBanner({ error }: ConnectorsErrorBannerProps) { + if (!error) return null; + + return ( +
+ {error} +
+ ); +} diff --git a/components/ConnectorsPage/ConnectorsHeader.tsx b/components/ConnectorsPage/ConnectorsHeader.tsx new file mode 100644 index 000000000..ea32e302e --- /dev/null +++ b/components/ConnectorsPage/ConnectorsHeader.tsx @@ -0,0 +1,32 @@ +import { Plug, RefreshCw } from "lucide-react"; + +interface ConnectorsHeaderProps { + onRefresh: () => void; + isLoading: boolean; +} + +export function ConnectorsHeader({ onRefresh, isLoading }: ConnectorsHeaderProps) { + return ( +
+
+

+ + Connectors +

+

+ Connect your tools to enable AI-powered automation +

+
+ +
+ ); +} diff --git a/components/ConnectorsPage/ConnectorsLoadingState.tsx b/components/ConnectorsPage/ConnectorsLoadingState.tsx new file mode 100644 index 000000000..6f573b0cf --- /dev/null +++ b/components/ConnectorsPage/ConnectorsLoadingState.tsx @@ -0,0 +1,9 @@ +import { Loader2 } from "lucide-react"; + +export function ConnectorsLoadingState() { + return ( +
+ +
+ ); +} diff --git a/components/ConnectorsPage/ConnectorsPage.tsx b/components/ConnectorsPage/ConnectorsPage.tsx new file mode 100644 index 000000000..1a48a886f --- /dev/null +++ b/components/ConnectorsPage/ConnectorsPage.tsx @@ -0,0 +1,81 @@ +"use client"; + +import { Fragment, useEffect, useState } from "react"; +import { usePrivy } from "@privy-io/react-auth"; +import { useSearchParams } from "next/navigation"; +import { useUserProvider } from "@/providers/UserProvder"; +import { useConnectors } from "@/hooks/useConnectors"; +import { ConnectorsSuccessBanner } from "./ConnectorsSuccessBanner"; +import { ConnectorsErrorBanner } from "./ConnectorsErrorBanner"; +import { ConnectorsLoadingState } from "./ConnectorsLoadingState"; +import { ConnectorsEmptyState } from "./ConnectorsEmptyState"; +import { ConnectorsSection } from "./ConnectorsSection"; +import { ConnectorsHeader } from "./ConnectorsHeader"; + +/** + * Main connectors page component. + * Redesigned to match Perplexity's Connectors style. + */ +export function ConnectorsPage() { + const { userData } = useUserProvider(); + const { ready } = usePrivy(); + const { connectors, isLoading, error, refetch, authorize, disconnect } = + useConnectors(); + const searchParams = useSearchParams(); + const [showSuccess, setShowSuccess] = useState(false); + + useEffect(() => { + if (searchParams.get("connected") === "true") { + setShowSuccess(true); + refetch(); + window.history.replaceState({}, "", "/settings/connectors"); + const timer = setTimeout(() => setShowSuccess(false), 5000); + return () => clearTimeout(timer); + } + }, [searchParams, refetch]); + + if (!ready) return ; + + if (!userData?.account_id) { + return ( +
+

+ Please sign in to manage connectors. +

+
+ ); + } + + const connected = connectors.filter((c) => c.isConnected); + const available = connectors.filter((c) => !c.isConnected); + + return ( +
+ + + + + {isLoading ? ( + + ) : ( +
+ + + {connectors.length === 0 && } +
+ )} +
+ ); +} diff --git a/components/ConnectorsPage/ConnectorsSection.tsx b/components/ConnectorsPage/ConnectorsSection.tsx new file mode 100644 index 000000000..b214aa404 --- /dev/null +++ b/components/ConnectorsPage/ConnectorsSection.tsx @@ -0,0 +1,39 @@ +import { ConnectorInfo } from "@/hooks/useConnectors"; +import { ConnectorCard } from "./ConnectorCard"; + +interface ConnectorsSectionProps { + title: string; + description: string; + connectors: ConnectorInfo[]; + onConnect: (slug: string) => Promise; + onDisconnect: (connectedAccountId: string) => Promise; +} + +export function ConnectorsSection({ + title, + description, + connectors, + onConnect, + onDisconnect, +}: ConnectorsSectionProps) { + if (connectors.length === 0) return null; + + return ( +
+
+

{title}

+

{description}

+
+
+ {connectors.map((connector) => ( + + ))} +
+
+ ); +} diff --git a/components/ConnectorsPage/ConnectorsSuccessBanner.tsx b/components/ConnectorsPage/ConnectorsSuccessBanner.tsx new file mode 100644 index 000000000..27f8244a6 --- /dev/null +++ b/components/ConnectorsPage/ConnectorsSuccessBanner.tsx @@ -0,0 +1,18 @@ +import { CheckCircle } from "lucide-react"; + +interface ConnectorsSuccessBannerProps { + show: boolean; +} + +export function ConnectorsSuccessBanner({ show }: ConnectorsSuccessBannerProps) { + if (!show) return null; + + return ( +
+ + + Connector enabled successfully! + +
+ ); +} diff --git a/components/ConnectorsPage/index.ts b/components/ConnectorsPage/index.ts new file mode 100644 index 000000000..1227de718 --- /dev/null +++ b/components/ConnectorsPage/index.ts @@ -0,0 +1,2 @@ +export { ConnectorsPage } from "./ConnectorsPage"; +export { ConnectorCard } from "./ConnectorCard"; diff --git a/components/Sidebar/UserProfileDropdown/ConnectorsMenuItem.tsx b/components/Sidebar/UserProfileDropdown/ConnectorsMenuItem.tsx new file mode 100644 index 000000000..88eee5c1d --- /dev/null +++ b/components/Sidebar/UserProfileDropdown/ConnectorsMenuItem.tsx @@ -0,0 +1,16 @@ +import Link from "next/link"; +import { Plug } from "lucide-react"; +import { DropdownMenuItem } from "@/components/ui/dropdown-menu"; + +const ConnectorsMenuItem = () => { + return ( + + + + Connectors + + + ); +}; + +export default ConnectorsMenuItem; diff --git a/components/Sidebar/UserProfileDropdown/UserProfileDropdown.tsx b/components/Sidebar/UserProfileDropdown/UserProfileDropdown.tsx index 71eebc4c2..3522e4f4c 100644 --- a/components/Sidebar/UserProfileDropdown/UserProfileDropdown.tsx +++ b/components/Sidebar/UserProfileDropdown/UserProfileDropdown.tsx @@ -14,6 +14,7 @@ import { useUserProvider } from "@/providers/UserProvder"; import CreditsUsage from "./CreditsUsage"; import AccountIdDisplay from "@/components/ArtistSetting/AccountIdDisplay"; import ManageSubscriptionButton from "./ManageSubscriptionButton"; +import ConnectorsMenuItem from "./ConnectorsMenuItem"; import OrgSelector from "./OrgSelector"; import { useTheme } from "next-themes"; import { Check } from "lucide-react"; @@ -50,6 +51,7 @@ const UserProfileDropdown = () => { + {getThemeIcon()} diff --git a/components/VercelChat/ToolComponents.tsx b/components/VercelChat/ToolComponents.tsx index 1629efbc4..44ebe03e2 100644 --- a/components/VercelChat/ToolComponents.tsx +++ b/components/VercelChat/ToolComponents.tsx @@ -101,8 +101,7 @@ import { UpdateFileResult, UpdateFileResultType, } from "./tools/files/UpdateFileResult"; -import GoogleSheetsLoginResult from "./tools/googleSheets/GoogleSheetsLoginResult"; -import GoogleSheetsLoginLoading from "./tools/googleSheets/GoogleSheetsLoginLoading"; +import ComposioAuthResult from "./tools/composio/ComposioAuthResult"; import { TextContent } from "@modelcontextprotocol/sdk/types.js"; type CallToolResult = { @@ -277,12 +276,6 @@ export function getToolCallComponent(part: ToolUIPart) { ); - } else if (toolName === "googleSheetsLoginTool") { - return ( -
- -
- ); } // Default for other tools @@ -542,10 +535,10 @@ export function getToolResultComponent(part: ToolUIPart | DynamicToolUIPart) { ); - } else if (toolName === "googleSheetsLoginTool") { + } else if (toolName === "COMPOSIO_MANAGE_CONNECTIONS") { return (
- +
); } diff --git a/components/VercelChat/tools/composio/ComposioAuthResult.tsx b/components/VercelChat/tools/composio/ComposioAuthResult.tsx new file mode 100644 index 000000000..e2cc7be7f --- /dev/null +++ b/components/VercelChat/tools/composio/ComposioAuthResult.tsx @@ -0,0 +1,51 @@ +"use client"; + +import React from "react"; +import { formatConnectorName } from "@/lib/composio/formatConnectorName"; +import { findAuthResult } from "@/lib/composio/findAuthResult"; +import { hasValidAuthData } from "@/lib/composio/hasValidAuthData"; +import { ComposioConnectedState } from "./ComposioConnectedState"; +import { ComposioConnectPrompt } from "./ComposioConnectPrompt"; + +interface ComposioAuthResultProps { + result: unknown; +} + +/** + * Component to display Composio authentication result. + * Shows different UI based on connection status: + * - "Active": Shows connected confirmation + * - "initiated": Shows connect button + * Returns null if no valid auth result is found. + */ +export function ComposioAuthResult({ result }: ComposioAuthResultProps) { + if (!hasValidAuthData(result)) { + return null; + } + + const authResult = findAuthResult(result.data?.results); + if (!authResult) { + return null; + } + + const connector = authResult.toolkit || "Connector"; + const displayName = formatConnectorName(connector); + + if (authResult.status?.toLowerCase() === "active") { + return ; + } + + if (!authResult.redirect_url) { + return null; + } + + return ( + + ); +} + +export default ComposioAuthResult; diff --git a/components/VercelChat/tools/composio/ComposioConnectPrompt.tsx b/components/VercelChat/tools/composio/ComposioConnectPrompt.tsx new file mode 100644 index 000000000..3f77184fe --- /dev/null +++ b/components/VercelChat/tools/composio/ComposioConnectPrompt.tsx @@ -0,0 +1,51 @@ +import { FileSpreadsheet, Link2 } from "lucide-react"; + +interface ComposioConnectPromptProps { + displayName: string; + redirectUrl: string; + connector: string; +} + +/** + * Component shown when a connector needs to be connected. + */ +export function ComposioConnectPrompt({ + displayName, + redirectUrl, + connector, +}: ComposioConnectPromptProps) { + const getIcon = (className = "h-5 w-5") => { + if (connector.toLowerCase().includes("sheet")) { + return ; + } + return ; + }; + + return ( +
+
+ {getIcon("h-5 w-5 text-muted-foreground")} + + {displayName} Access Required + +
+ +

+ Connect your {displayName} account to enable this connector. +

+ + + {getIcon("h-4 w-4")} + Connect {displayName} + + +

+ You'll be redirected to authorize access. Link expires in 10 + minutes. +

+
+ ); +} diff --git a/components/VercelChat/tools/composio/ComposioConnectedState.tsx b/components/VercelChat/tools/composio/ComposioConnectedState.tsx new file mode 100644 index 000000000..8e69440ff --- /dev/null +++ b/components/VercelChat/tools/composio/ComposioConnectedState.tsx @@ -0,0 +1,26 @@ +import { CheckCircle } from "lucide-react"; + +interface ComposioConnectedStateProps { + displayName: string; +} + +/** + * Component shown when a connector is successfully connected. + */ +export function ComposioConnectedState({ + displayName, +}: ComposioConnectedStateProps) { + return ( +
+
+ + + {displayName} Connected + +
+

+ Your {displayName} account is connected and ready to use. +

+
+ ); +} diff --git a/components/VercelChat/tools/googleSheets/GoogleSheetsLoginLoading.tsx b/components/VercelChat/tools/googleSheets/GoogleSheetsLoginLoading.tsx deleted file mode 100644 index 31ba450e6..000000000 --- a/components/VercelChat/tools/googleSheets/GoogleSheetsLoginLoading.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { Loader } from "lucide-react"; - -export function GoogleSheetsLoginLoading() { - return ( -
- - Initializing Google Sheets login... -
- ); -} - -export default GoogleSheetsLoginLoading; diff --git a/components/VercelChat/tools/googleSheets/GoogleSheetsLoginResult.tsx b/components/VercelChat/tools/googleSheets/GoogleSheetsLoginResult.tsx deleted file mode 100644 index 7359dedeb..000000000 --- a/components/VercelChat/tools/googleSheets/GoogleSheetsLoginResult.tsx +++ /dev/null @@ -1,57 +0,0 @@ -"use client"; - -import React from "react"; -import { FileSpreadsheet } from "lucide-react"; -import { Button } from "@/components/ui/button"; -import { useUserProvider } from "@/providers/UserProvder"; -import AccountIdDisplay from "@/components/ArtistSetting/AccountIdDisplay"; -import { useGoogleSheetsLogin } from "@/hooks/useGoogleSheetsLogin"; - -export function GoogleSheetsLoginResult() { - const { userData } = useUserProvider(); - const accountId = userData?.account_id; - const { isLoading, handleLogin } = useGoogleSheetsLogin(); - - return ( -
-
- - - Google Sheets Access Required - -
- -

- Connect your Google Sheets account to enable reading and writing to - spreadsheets. -

- - {accountId && } - - - -

- You'll be redirected to Google to authorize access to your Google - Sheets for this account. -

-
- ); -} - -export default GoogleSheetsLoginResult; diff --git a/hooks/useConnectorHandlers.ts b/hooks/useConnectorHandlers.ts new file mode 100644 index 000000000..d7182872f --- /dev/null +++ b/hooks/useConnectorHandlers.ts @@ -0,0 +1,58 @@ +import { useState } from "react"; + +interface UseConnectorHandlersProps { + slug: string; + connectedAccountId?: string; + onConnect: (slug: string) => Promise; + onDisconnect: (connectedAccountId: string) => Promise; +} + +interface UseConnectorHandlersReturn { + isConnecting: boolean; + isDisconnecting: boolean; + handleConnect: () => Promise; + handleDisconnect: () => Promise; +} + +/** + * Hook for managing connector connect/disconnect state and handlers. + */ +export function useConnectorHandlers({ + slug, + connectedAccountId, + onConnect, + onDisconnect, +}: UseConnectorHandlersProps): UseConnectorHandlersReturn { + const [isConnecting, setIsConnecting] = useState(false); + const [isDisconnecting, setIsDisconnecting] = useState(false); + + const handleConnect = async () => { + setIsConnecting(true); + try { + const redirectUrl = await onConnect(slug); + if (redirectUrl) { + window.location.href = redirectUrl; + } + } finally { + setIsConnecting(false); + } + }; + + const handleDisconnect = async () => { + if (!connectedAccountId) return; + + setIsDisconnecting(true); + try { + await onDisconnect(connectedAccountId); + } finally { + setIsDisconnecting(false); + } + }; + + return { + isConnecting, + isDisconnecting, + handleConnect, + handleDisconnect, + }; +} diff --git a/hooks/useConnectors.ts b/hooks/useConnectors.ts new file mode 100644 index 000000000..436053bf7 --- /dev/null +++ b/hooks/useConnectors.ts @@ -0,0 +1,138 @@ +"use client"; + +import { useState, useEffect, useCallback } from "react"; +import { NEW_API_BASE_URL } from "@/lib/consts"; +import { useAccessToken } from "@/hooks/useAccessToken"; + +/** + * Connector info from the API. + */ +export interface ConnectorInfo { + slug: string; + name: string; + isConnected: boolean; + connectedAccountId?: string; +} + +/** + * Connectors visible to end users. + * Only these connectors will be shown on the settings page. + */ +const ALLOWED_CONNECTORS = ["googlesheets"]; + +/** + * Hook for managing connectors. + * Fetches connector status and provides authorize function. + */ +export function useConnectors() { + const accessToken = useAccessToken(); + + const [connectors, setConnectors] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + + const fetchConnectors = useCallback(async () => { + if (!accessToken) { + setIsLoading(false); + return; + } + + setIsLoading(true); + setError(null); + + try { + const response = await fetch(`${NEW_API_BASE_URL}/api/connectors`, { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }); + + if (!response.ok) { + throw new Error("Failed to fetch connectors"); + } + + const data = await response.json(); + const visible = data.data.connectors.filter((c: ConnectorInfo) => + ALLOWED_CONNECTORS.includes(c.slug.toLowerCase()), + ); + setConnectors(visible); + } catch (err) { + setError(err instanceof Error ? err.message : "Unknown error"); + } finally { + setIsLoading(false); + } + }, [accessToken]); + + const authorize = useCallback( + async (connector: string): Promise => { + if (!accessToken) return null; + + try { + const response = await fetch( + `${NEW_API_BASE_URL}/api/connectors/authorize`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ connector }), + }, + ); + + if (!response.ok) { + throw new Error("Failed to authorize connector"); + } + + const data = await response.json(); + return data.data.redirectUrl; + } catch (err) { + setError(err instanceof Error ? err.message : "Unknown error"); + return null; + } + }, + [accessToken], + ); + + const disconnect = useCallback( + async (connectedAccountId: string): Promise => { + if (!accessToken) return false; + + try { + const response = await fetch(`${NEW_API_BASE_URL}/api/connectors`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ connected_account_id: connectedAccountId }), + }); + + if (!response.ok) { + throw new Error("Failed to disconnect connector"); + } + + // Refresh the connectors list after disconnect + await fetchConnectors(); + return true; + } catch (err) { + setError(err instanceof Error ? err.message : "Unknown error"); + return false; + } + }, + [accessToken, fetchConnectors], + ); + + useEffect(() => { + fetchConnectors(); + }, [fetchConnectors]); + + return { + connectors, + isLoading, + error, + refetch: fetchConnectors, + authorize, + disconnect, + }; +} diff --git a/hooks/useGoogleSheetsLogin.ts b/hooks/useGoogleSheetsLogin.ts deleted file mode 100644 index ef602bc05..000000000 --- a/hooks/useGoogleSheetsLogin.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { useState } from "react"; -import { useUserProvider } from "@/providers/UserProvder"; -import { useVercelChatContext } from "@/providers/VercelChatProvider"; -import getLatestUserMessageText from "@/lib/messages/getLatestUserMessageText"; -import { fetchConnectedAccountsRefresh } from "@/lib/composio/googleSheets/fetchConnectedAccountsRefresh"; -import { toast } from "sonner"; - -export function useGoogleSheetsLogin() { - const [isLoading, setIsLoading] = useState(false); - const { userData } = useUserProvider(); - const { messages } = useVercelChatContext(); - const accountId = userData?.account_id as string; - - const handleLogin = async () => { - const latestUserMessageText = getLatestUserMessageText(messages); - const redirectUrl = `https://chat.recoupable.com?q=${encodeURIComponent( - latestUserMessageText - )}`; - - setIsLoading(true); - - try { - const data = await fetchConnectedAccountsRefresh({ - accountId, - redirectUrl, - }); - - if (data.redirect_url) { - window.open(data.redirect_url, "_blank", "noopener,noreferrer"); - } - } catch (error) { - console.error("Error initiating Google Sheets login:", error); - toast.error("Failed to initiate Google Sheets login. Please try again."); - } finally { - setIsLoading(false); - } - }; - - return { - isLoading, - handleLogin, - }; -} diff --git a/lib/agents/googleSheetsAgent/getGoogleSheetsTools.ts b/lib/agents/googleSheetsAgent/getGoogleSheetsTools.ts deleted file mode 100644 index 1baeb28c5..000000000 --- a/lib/agents/googleSheetsAgent/getGoogleSheetsTools.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { ToolSet } from "ai"; -import { CreateConnectedAccountOptions } from "@composio/core"; -import { getComposioClient } from "@/lib/composio/client"; -import { ChatRequestBody } from "@/lib/chat/validateChatRequest"; -import getLatestUserMessageText from "@/lib/messages/getLatestUserMessageText"; -import getConnectedAccount, { - GOOGLE_SHEETS_TOOLKIT_SLUG, -} from "@/lib/composio/googleSheets/getConnectedAccount"; -import googleSheetsLoginTool from "@/lib/tools/composio/googleSheetsLoginTool"; - -export default async function getGoogleSheetsTools( - body: ChatRequestBody -): Promise { - const { accountId, messages } = body; - - const latestUserMessageText = getLatestUserMessageText(messages); - - const options: CreateConnectedAccountOptions = { - callbackUrl: `https://chat.recoupable.com?q=${encodeURIComponent( - latestUserMessageText - )}`, - }; - - const composio = await getComposioClient(); - const userAccounts = await getConnectedAccount(accountId, options); - const isAuthenticated = userAccounts.items[0]?.data?.status === "ACTIVE"; - - const tools = isAuthenticated - ? await composio.tools.get(accountId, { - toolkits: [GOOGLE_SHEETS_TOOLKIT_SLUG], - }) - : { - googleSheetsLoginTool, - }; - - return tools; -} diff --git a/lib/agents/googleSheetsAgent/index.ts b/lib/agents/googleSheetsAgent/index.ts deleted file mode 100644 index 79bd8f91d..000000000 --- a/lib/agents/googleSheetsAgent/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import getGoogleSheetsTools from "./getGoogleSheetsTools"; - -export { getGoogleSheetsTools }; diff --git a/lib/chat/setupToolsForRequest.ts b/lib/chat/setupToolsForRequest.ts index 1f22a74c3..e6e6eca0b 100644 --- a/lib/chat/setupToolsForRequest.ts +++ b/lib/chat/setupToolsForRequest.ts @@ -6,12 +6,16 @@ import { withPayment } from "x402-mcp"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import { getOrCreatePurchaserAccount } from "@/lib/coinbase/getOrCreatePurchaserAccount"; import { NEW_API_BASE_URL } from "@/lib/consts"; -import { getGoogleSheetsTools } from "@/lib/agents/googleSheetsAgent"; import { ChatRequestBody } from "./validateChatRequest"; /** - * Sets up and filters tools for a chat request - * @param excludeTools - Optional array of tool names to exclude + * Sets up and filters tools for a chat request. + * + * Tools are sourced from: + * - MCP client (Recoup-API) - includes Composio Tool Router for Google Sheets, etc. + * - Local tools (getMcpTools) + * + * @param body - The chat request body * @returns Filtered tool set ready for use */ export async function setupToolsForRequest( @@ -34,10 +38,8 @@ export async function setupToolsForRequest( }).then((client) => withPayment(client, { account, network: "base" })); const mcpClientTools = await mcpClient.tools(); - const googleSheetsTools = await getGoogleSheetsTools(body); const allTools: ToolSet = { ...mcpClientTools, - ...googleSheetsTools, ...localTools, }; diff --git a/lib/composio/client.ts b/lib/composio/client.ts deleted file mode 100644 index 8701acd28..000000000 --- a/lib/composio/client.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Composio } from "@composio/core"; -import { VercelProvider } from "@composio/vercel"; - -const apiKey = process.env.COMPOSIO_API_KEY; - -if (!apiKey) { - console.warn("COMPOSIO_API_KEY not found in environment variables"); - throw new Error("COMPOSIO_API_KEY not found in environment variables"); -} - -export const getComposioClient = (): Composio => { - return new Composio({ - apiKey, - provider: new VercelProvider(), - }); -}; diff --git a/lib/composio/connectorMetadata.ts b/lib/composio/connectorMetadata.ts new file mode 100644 index 000000000..5fc78bb3c --- /dev/null +++ b/lib/composio/connectorMetadata.ts @@ -0,0 +1,27 @@ +/** + * Metadata for each connector. + */ + +export interface ConnectorMeta { + description: string; +} + +/** + * Metadata map for all supported connectors. + * Keys are connector slugs (lowercase). + */ +export const connectorMetadata: Record = { + googlesheets: { description: "Read, create, and update spreadsheets" }, +}; + +/** + * Get metadata for a connector by slug. + * Returns default values if not found. + */ +export function getConnectorMeta(slug: string): ConnectorMeta { + return ( + connectorMetadata[slug.toLowerCase()] || { + description: "Connect to enable this connector", + } + ); +} diff --git a/lib/composio/findAuthResult.ts b/lib/composio/findAuthResult.ts new file mode 100644 index 000000000..126cd97ad --- /dev/null +++ b/lib/composio/findAuthResult.ts @@ -0,0 +1,18 @@ +import { ComposioResultEntry } from "./types"; + +/** + * Find the auth result entry that has redirect_url or active status. + * Returns null if no valid auth result is found. + */ +export function findAuthResult( + results: Record | undefined +): ComposioResultEntry | null { + if (!results) return null; + + const entries = Object.values(results); + return ( + entries.find( + (r) => r.redirect_url || r.status?.toLowerCase() === "active" + ) || null + ); +} diff --git a/lib/composio/formatConnectorName.ts b/lib/composio/formatConnectorName.ts new file mode 100644 index 000000000..118dc524d --- /dev/null +++ b/lib/composio/formatConnectorName.ts @@ -0,0 +1,24 @@ +/** + * Format connector slug to human-readable name. + * + * Why: Composio returns slugs like "googlesheets" but we need + * to display "Google Sheets" to users. + */ + +const CONNECTOR_DISPLAY_NAMES: Record = { + googlesheets: "Google Sheets", +}; + +export function formatConnectorName(name: string, slug?: string): string { + const key = (slug || name).toLowerCase(); + + if (CONNECTOR_DISPLAY_NAMES[key]) { + return CONNECTOR_DISPLAY_NAMES[key]; + } + + // Fallback: capitalize and add spaces before capitals + return name + .replace(/([A-Z])/g, " $1") + .replace(/^./, (str) => str.toUpperCase()) + .trim(); +} diff --git a/lib/composio/getConnectorIcon.tsx b/lib/composio/getConnectorIcon.tsx new file mode 100644 index 000000000..bc94856ff --- /dev/null +++ b/lib/composio/getConnectorIcon.tsx @@ -0,0 +1,20 @@ +import { SiGooglesheets } from "@icons-pack/react-simple-icons"; +import { Link2 } from "lucide-react"; + +/** + * Get branded icon for a connector. + * Uses Simple Icons for brand logos, falls back to Lucide for others. + */ +export function getConnectorIcon(slug: string, size = 24): React.ReactNode { + const iconProps = { size, className: "shrink-0" }; + + const icons: Record = { + googlesheets: , + }; + + return ( + icons[slug] || ( + + ) + ); +} diff --git a/lib/composio/googleSheets/authenticateGoogleSheetsToolkit.ts b/lib/composio/googleSheets/authenticateGoogleSheetsToolkit.ts deleted file mode 100644 index 2e3d4d22c..000000000 --- a/lib/composio/googleSheets/authenticateGoogleSheetsToolkit.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { CreateConnectedAccountOptions } from "@composio/core"; -import { getComposioClient } from "../client"; - -const googleSheetsAuthConfigId = process.env - ?.COMPOSIO_GOOGLE_SHEETS_AUTH_CONFIG_ID as string; -if (!googleSheetsAuthConfigId) { - throw new Error( - "COMPOSIO_GOOGLE_SHEETS_AUTH_CONFIG_ID not found in environment variables" - ); -} - -async function authenticateGoogleSheetsToolkit( - userId: string, - options?: CreateConnectedAccountOptions -) { - const composio = await getComposioClient(); - const connectionRequest = await composio.connectedAccounts.initiate( - userId, - googleSheetsAuthConfigId, - options - ); - return connectionRequest; -} - -export default authenticateGoogleSheetsToolkit; diff --git a/lib/composio/googleSheets/fetchConnectedAccountsRefresh.ts b/lib/composio/googleSheets/fetchConnectedAccountsRefresh.ts deleted file mode 100644 index 1eae9b636..000000000 --- a/lib/composio/googleSheets/fetchConnectedAccountsRefresh.ts +++ /dev/null @@ -1,37 +0,0 @@ -interface FetchConnectedAccountsRefreshParams { - accountId: string; - redirectUrl: string; -} - -interface FetchConnectedAccountsRefreshResponse { - message: string; - id: string; - status: string; - redirect_url: string; -} - -export async function fetchConnectedAccountsRefresh({ - accountId, - redirectUrl, -}: FetchConnectedAccountsRefreshParams): Promise { - const response = await fetch( - "https://recoup-api.vercel.app/api/connectedAccounts/refresh", - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - accountId, - redirectUrl, - }), - } - ); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - const data = await response.json(); - return data; -} diff --git a/lib/composio/googleSheets/getConnectedAccount.ts b/lib/composio/googleSheets/getConnectedAccount.ts deleted file mode 100644 index 34722c37e..000000000 --- a/lib/composio/googleSheets/getConnectedAccount.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { getComposioClient } from "@/lib/composio/client"; -import authenticateGoogleSheetsToolkit from "./authenticateGoogleSheetsToolkit"; -import { CreateConnectedAccountOptions } from "@composio/core"; - -export const GOOGLE_SHEETS_TOOLKIT_SLUG = "GOOGLESHEETS"; - -export default async function getConnectedAccount( - accountId: string, - options?: CreateConnectedAccountOptions -) { - const composio = await getComposioClient(); - let userAccounts = await composio.connectedAccounts.list({ - userIds: [accountId], - toolkitSlugs: [GOOGLE_SHEETS_TOOLKIT_SLUG], - }); - - if (userAccounts.items.length === 0) { - await authenticateGoogleSheetsToolkit(accountId, options); - userAccounts = await composio.connectedAccounts.list({ - userIds: [accountId], - toolkitSlugs: [GOOGLE_SHEETS_TOOLKIT_SLUG], - }); - } - - return userAccounts; -} diff --git a/lib/composio/hasValidAuthData.ts b/lib/composio/hasValidAuthData.ts new file mode 100644 index 000000000..b4c17bac5 --- /dev/null +++ b/lib/composio/hasValidAuthData.ts @@ -0,0 +1,12 @@ +import { ComposioResultEntry } from "./types"; + +/** + * Check if the result contains valid auth data. + */ +export function hasValidAuthData(result: unknown): result is { + data?: { results?: Record }; +} { + if (!result || typeof result !== "object") return false; + const r = result as { data?: { results?: unknown } }; + return r.data?.results !== undefined; +} diff --git a/lib/composio/index.ts b/lib/composio/index.ts new file mode 100644 index 000000000..a839629de --- /dev/null +++ b/lib/composio/index.ts @@ -0,0 +1,2 @@ +export { getConnectorMeta, connectorMetadata, type ConnectorMeta } from "./connectorMetadata"; +export { formatConnectorName } from "./formatConnectorName"; diff --git a/lib/composio/types.ts b/lib/composio/types.ts new file mode 100644 index 000000000..1690ae9c1 --- /dev/null +++ b/lib/composio/types.ts @@ -0,0 +1,6 @@ +export interface ComposioResultEntry { + toolkit?: string; + status?: string; + redirect_url?: string; + instruction?: string; +} diff --git a/lib/tools/composio/googleSheetsLoginTool.ts b/lib/tools/composio/googleSheetsLoginTool.ts deleted file mode 100644 index 433af0709..000000000 --- a/lib/tools/composio/googleSheetsLoginTool.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { z } from "zod"; -import { tool } from "ai"; -import getConnectedAccount from "@/lib/composio/googleSheets/getConnectedAccount"; - -const schema = z.object({ - account_id: z - .string() - .min( - 1, - "account_id is required and should be pulled from the system prompt." - ), -}); - -const googleSheetsLoginTool = tool({ - description: - "Initiate the authentication flow for the Google Sheets account.", - inputSchema: schema, - execute: async ({ account_id }) => { - await getConnectedAccount(account_id); - return { - success: true, - message: - "Google Sheets login initiated successfully. Please click the button above to login with Google Sheets.", - }; - }, -}); - -export default googleSheetsLoginTool; diff --git a/lib/tools/get-tools-name.ts b/lib/tools/get-tools-name.ts index 508c9eab7..56986faab 100644 --- a/lib/tools/get-tools-name.ts +++ b/lib/tools/get-tools-name.ts @@ -7,6 +7,14 @@ export const getDisplayToolName = (name: string) => { switch (cleanName) { case "search_web": return "Search Internet"; + case "COMPOSIO_MANAGE_CONNECTIONS": + return "Manage Connections"; + case "COMPOSIO_SEARCH_TOOLS": + return "Search Tools"; + case "COMPOSIO_GET_TOOL_SCHEMAS": + return "Get Tool Details"; + case "COMPOSIO_MULTI_EXECUTE_TOOL": + return "Execute Action"; default: return cleanName .split("_") diff --git a/lib/utils/getToolsInfo.ts b/lib/utils/getToolsInfo.ts index 31b276601..e67925b95 100644 --- a/lib/utils/getToolsInfo.ts +++ b/lib/utils/getToolsInfo.ts @@ -44,6 +44,24 @@ function getToolInfo(toolName: string): { message: string } { message: "Information retrieved", }; } + // Connector tools + else if (toolName === "COMPOSIO_MANAGE_CONNECTIONS") { + return { + message: "Connection managed", + }; + } else if (toolName === "COMPOSIO_SEARCH_TOOLS") { + return { + message: "Tools discovered", + }; + } else if (toolName === "COMPOSIO_GET_TOOL_SCHEMAS") { + return { + message: "Tool details retrieved", + }; + } else if (toolName === "COMPOSIO_MULTI_EXECUTE_TOOL") { + return { + message: "Action executed", + }; + } // Default for any other tool else { return { diff --git a/package.json b/package.json index ee05e9099..a3bddfcc8 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@farcaster/frame-wagmi-connector": "^0.0.37", "@google/genai": "^1.24.0", "@hookform/resolvers": "^3.9.1", + "@icons-pack/react-simple-icons": "^13.8.0", "@modelcontextprotocol/sdk": "^1.24.3", "@privy-io/react-auth": "^1.88.4", "@radix-ui/react-alert-dialog": "^1.1.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d138fdff..538e31787 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,16 +31,16 @@ importers: version: 2.5.4(bufferutil@4.0.9)(deepmerge@4.3.1)(dotenv@16.6.1)(encoding@0.1.13)(react@19.2.1)(utf-8-validate@5.0.10)(zod@3.25.76) '@coinbase/cdp-sdk': specifier: ^1.4.0 - version: 1.39.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 1.39.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@coinbase/onchainkit': specifier: ^0.38.8 - version: 0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + version: 0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) '@composio/core': specifier: ^0.2.4 - version: 0.2.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + version: 0.2.6(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) '@composio/vercel': specifier: ^0.2.16 - version: 0.2.18(@composio/core@0.2.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ai@6.0.0-beta.99(zod@3.25.76)) + version: 0.2.18(@composio/core@0.2.6(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ai@6.0.0-beta.99(zod@3.25.76)) '@farcaster/frame-sdk': specifier: ^0.0.44 version: 0.0.44(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -53,6 +53,9 @@ importers: '@hookform/resolvers': specifier: ^3.9.1 version: 3.10.0(react-hook-form@7.68.0(react@19.2.1)) + '@icons-pack/react-simple-icons': + specifier: ^13.8.0 + version: 13.8.0(react@19.2.1) '@modelcontextprotocol/sdk': specifier: ^1.24.3 version: 1.24.3(zod@3.25.76) @@ -136,7 +139,7 @@ importers: version: 1.15.7 autoevals: specifier: ^0.0.129 - version: 0.0.129(encoding@0.1.13)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.0.129(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) braintrust: specifier: ^0.4.9 version: 0.4.10(zod@3.25.76) @@ -208,7 +211,7 @@ importers: version: 0.66.0(request@2.88.2) openai: specifier: ^4.67.3 - version: 4.104.0(encoding@0.1.13)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + version: 4.104.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) papaparse: specifier: ^5.5.3 version: 5.5.3 @@ -292,10 +295,10 @@ importers: version: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.15.4 - version: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + version: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) x402-mcp: specifier: ^0.1.1 - version: 0.1.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(ai@6.0.0-beta.99(zod@3.25.76))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(next@16.0.7(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.1.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(ai@6.0.0-beta.99(zod@3.25.76))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(next@16.0.7(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) zod: specifier: ^3.25.0 version: 3.25.76 @@ -1733,6 +1736,11 @@ packages: '@iconify/utils@3.1.0': resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + '@icons-pack/react-simple-icons@13.8.0': + resolution: {integrity: sha512-iZrhL1fSklfCCVn68IYHaAoKfcby3RakUTn2tRPyHBkhr2tkYqeQbjJWf+NizIYBzKBn2IarDJXmTdXd6CuEfw==} + peerDependencies: + react: ^16.13 || ^17 || ^18 || ^19 + '@img/colour@1.0.0': resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} engines: {node: '>=18'} @@ -10905,9 +10913,9 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@base-org/account@2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': + '@base-org/account@2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': dependencies: - '@coinbase/cdp-sdk': 1.39.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@coinbase/cdp-sdk': 1.39.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@noble/hashes': 1.4.0 clsx: 1.2.1 eventemitter3: 5.0.1 @@ -11008,11 +11016,11 @@ snapshots: '@chevrotain/utils@11.0.3': {} - '@coinbase/cdp-sdk@1.39.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@coinbase/cdp-sdk@1.39.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@solana-program/system': 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana-program/system': 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10) abitype: 1.0.6(typescript@5.9.3)(zod@3.25.76) axios: 1.13.2 @@ -11031,7 +11039,7 @@ snapshots: - utf-8-validate - ws - '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': + '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': dependencies: '@farcaster/frame-sdk': 0.1.12(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@farcaster/miniapp-wagmi-connector': 1.1.0(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) @@ -11045,7 +11053,7 @@ snapshots: react-dom: 19.2.1(react@19.2.1) tailwind-merge: 2.6.0 viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -11130,13 +11138,13 @@ snapshots: '@composio/client@0.1.0-alpha.40': {} - '@composio/core@0.2.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': + '@composio/core@0.2.6(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': dependencies: '@composio/client': 0.1.0-alpha.40 '@composio/json-schema-to-zod': 0.1.19(zod@3.25.76) '@types/json-schema': 7.0.15 chalk: 4.1.2 - openai: 5.23.2(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + openai: 5.23.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) pusher-js: 8.4.0 semver: 7.7.3 uuid: 13.0.0 @@ -11149,9 +11157,9 @@ snapshots: dependencies: zod: 3.25.76 - '@composio/vercel@0.2.18(@composio/core@0.2.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ai@6.0.0-beta.99(zod@3.25.76))': + '@composio/vercel@0.2.18(@composio/core@0.2.6(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ai@6.0.0-beta.99(zod@3.25.76))': dependencies: - '@composio/core': 0.2.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + '@composio/core': 0.2.6(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) ai: 6.0.0-beta.99(zod@3.25.76) '@crawlee/types@3.15.3': @@ -11850,6 +11858,10 @@ snapshots: '@iconify/types': 2.0.0 mlly: 1.8.0 + '@icons-pack/react-simple-icons@13.8.0(react@19.2.1)': + dependencies: + react: 19.2.1 + '@img/colour@1.0.0': {} '@img/sharp-darwin-arm64@0.34.5': @@ -13788,13 +13800,13 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} - '@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + '@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: - '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + '@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: - '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/accounts@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': dependencies: @@ -13924,7 +13936,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -13938,11 +13950,11 @@ snapshots: '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/rpc-parsed-types': 3.0.3(typescript@5.9.3) '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) - '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/signers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/transaction-confirmation': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-confirmation': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) typescript: 5.9.3 @@ -14021,14 +14033,14 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 3.0.3(typescript@5.9.3) '@solana/functional': 3.0.3(typescript@5.9.3) '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) '@solana/subscribable': 3.0.3(typescript@5.9.3) typescript: 5.9.3 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@solana/rpc-subscriptions-spec@3.0.3(typescript@5.9.3)': dependencies: @@ -14038,7 +14050,7 @@ snapshots: '@solana/subscribable': 3.0.3(typescript@5.9.3) typescript: 5.9.3 - '@solana/rpc-subscriptions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@solana/rpc-subscriptions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 3.0.3(typescript@5.9.3) '@solana/fast-stable-stringify': 3.0.3(typescript@5.9.3) @@ -14046,7 +14058,7 @@ snapshots: '@solana/promises': 3.0.3(typescript@5.9.3) '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) '@solana/rpc-subscriptions-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-subscriptions-channel-websocket': 3.0.3(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-channel-websocket': 3.0.3(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -14131,7 +14143,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -14139,7 +14151,7 @@ snapshots: '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/promises': 3.0.3(typescript@5.9.3) '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -14999,9 +15011,9 @@ snapshots: '@vitest/pretty-format': 4.0.15 tinyrainbow: 3.0.3 - '@wagmi/connectors@6.2.0(71e4b280fc3084a257ee2fd657fc6d1a)': + '@wagmi/connectors@6.2.0(6dff3bc991ac35e5054745104ae5001e)': dependencies: - '@base-org/account': 2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + '@base-org/account': 2.4.0(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.27)(bufferutil@4.0.9)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(utf-8-validate@5.0.10)(zod@3.25.76) '@gemini-wallet/core': 0.3.2(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -15010,7 +15022,7 @@ snapshots: '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - porto: 0.2.35(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + porto: 0.2.35(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.3 @@ -16475,7 +16487,7 @@ snapshots: attr-accept@2.2.5: {} - autoevals@0.0.129(encoding@0.1.13)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + autoevals@0.0.129(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: '@braintrust/core': 0.0.87 ajv: 8.17.1 @@ -16484,7 +16496,7 @@ snapshots: js-yaml: 4.1.1 linear-sum-assignment: 1.0.9 mustache: 4.2.0 - openai: 4.104.0(encoding@0.1.13)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + openai: 4.104.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 zod-to-json-schema: 3.25.0(zod@3.25.76) transitivePeerDependencies: @@ -17639,8 +17651,8 @@ snapshots: '@typescript-eslint/parser': 8.48.1(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.5(eslint@8.57.1) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) @@ -17659,7 +17671,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 @@ -17670,22 +17682,22 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.48.1(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -17696,7 +17708,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -20284,21 +20296,6 @@ snapshots: regex: 6.0.1 regex-recursion: 6.0.2 - openai@4.104.0(encoding@0.1.13)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): - dependencies: - '@types/node': 18.19.130 - '@types/node-fetch': 2.6.13 - abort-controller: 3.0.0 - agentkeepalive: 4.6.0 - form-data-encoder: 1.7.2 - formdata-node: 4.4.1 - node-fetch: 2.7.0(encoding@0.1.13) - optionalDependencies: - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - zod: 3.25.76 - transitivePeerDependencies: - - encoding - openai@4.104.0(encoding@0.1.13)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): dependencies: '@types/node': 18.19.130 @@ -20314,9 +20311,9 @@ snapshots: transitivePeerDependencies: - encoding - openai@5.23.2(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): + openai@5.23.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): optionalDependencies: - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 openapi-fetch@0.13.8: @@ -20699,7 +20696,7 @@ snapshots: pony-cause@2.1.11: {} - porto@0.2.35(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): + porto@0.2.35(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): dependencies: '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) hono: 4.10.7 @@ -20713,7 +20710,7 @@ snapshots: '@tanstack/react-query': 5.90.12(react@19.2.1) react: 19.2.1 typescript: 5.9.3 - wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) transitivePeerDependencies: - '@types/react' - immer @@ -22562,10 +22559,10 @@ snapshots: vscode-uri@3.0.8: {} - wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): + wagmi@2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): dependencies: '@tanstack/react-query': 5.90.12(react@19.2.1) - '@wagmi/connectors': 6.2.0(71e4b280fc3084a257ee2fd657fc6d1a) + '@wagmi/connectors': 6.2.0(6dff3bc991ac35e5054745104ae5001e) '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.12)(@types/react@18.3.27)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.2.1 use-sync-external-store: 1.4.0(react@19.2.1) @@ -23010,13 +23007,13 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 - x402-mcp@0.1.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(ai@6.0.0-beta.99(zod@3.25.76))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(next@16.0.7(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + x402-mcp@0.1.1(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(ai@6.0.0-beta.99(zod@3.25.76))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(next@16.0.7(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: '@modelcontextprotocol/sdk': 1.24.3(zod@3.25.76) ai: 6.0.0-beta.99(zod@3.25.76) mcp-handler: 1.0.4(@modelcontextprotocol/sdk@1.24.3(zod@3.25.76))(next@16.0.7(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)) viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - x402: 0.5.3(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + x402: 0.5.3(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -23058,10 +23055,10 @@ snapshots: - utf-8-validate - ws - x402@0.5.3(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + x402@0.5.3(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + wagmi: 2.19.5(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.1))(@types/react@18.3.27)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration'