From 8e4ddbbdff68abadd5ee3e40ff6e339dc580b249 Mon Sep 17 00:00:00 2001 From: Alex Choi Date: Tue, 28 Oct 2025 19:57:47 +0000 Subject: [PATCH 1/6] add icon --- frontend/src/components/ProviderIcons.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/components/ProviderIcons.tsx b/frontend/src/components/ProviderIcons.tsx index 0d2f08f..47a98be 100644 --- a/frontend/src/components/ProviderIcons.tsx +++ b/frontend/src/components/ProviderIcons.tsx @@ -69,3 +69,9 @@ export const LinkedInIcon = () => ( ); + +export const RedditIcon = () => ( + + + +); From 945a84266690d88556133e51750a5c7e3e744a83 Mon Sep 17 00:00:00 2001 From: Alex Choi Date: Tue, 28 Oct 2025 20:01:51 +0000 Subject: [PATCH 2/6] add reddit tools --- frontend/src/lib/tools-config.ts | 227 ++++++++++++++++++++++++++++ frontend/src/lib/tools-providers.ts | 10 ++ 2 files changed, 237 insertions(+) diff --git a/frontend/src/lib/tools-config.ts b/frontend/src/lib/tools-config.ts index 86c0409..1c355a4 100644 --- a/frontend/src/lib/tools-config.ts +++ b/frontend/src/lib/tools-config.ts @@ -647,6 +647,232 @@ const spotifyTools: ToolDefinition[] = [ }, ]; +// Reddit Tools +const redditTools: ToolDefinition[] = [ + { + tool_name: "Reddit.SubmitTextPost", + description: "Submit a text-based post to a subreddit.", + parameters: [ + { + name: "subreddit", + type: "string", + required: true, + description: "The name of the subreddit to which the post will be submitted.", + }, + { + name: "title", + type: "string", + required: true, + description: "The title of the submission.", + }, + { + name: "body", + type: "string", + required: false, + description: "The body of the post in markdown format. Should never be the same as the title.", + }, + { + name: "nsfw", + type: "boolean", + required: false, + description: "Indicates if the submission is NSFW.", + default: false, + }, + { + name: "spoiler", + type: "boolean", + required: false, + description: "Indicates if the post is marked as a spoiler.", + default: false, + }, + { + name: "send_replies", + type: "boolean", + required: false, + description: "If true, sends replies to the user's inbox.", + default: true, + }, + ], + category: "social", + }, + { + tool_name: "Reddit.CommentOnPost", + description: "Comment on a Reddit post.", + parameters: [ + { + name: "post_identifier", + type: "string", + required: true, + description: "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", + }, + { + name: "text", + type: "string", + required: true, + description: "The body of the comment in markdown format.", + }, + ], + category: "social", + }, + { + tool_name: "Reddit.ReplyToComment", + description: "Reply to a Reddit comment.", + parameters: [ + { + name: "comment_identifier", + type: "string", + required: true, + description: "The identifier of the Reddit comment to reply to. The identifier may be a comment ID, a Reddit URL to the comment, a permalink to the comment, or the fullname of the comment.", + }, + { + name: "text", + type: "string", + required: true, + description: "The body of the reply in markdown format.", + }, + ], + category: "social", + }, + { + tool_name: "Reddit.GetPostsInSubreddit", + description: "Gets posts titles, links, and other metadata in the specified subreddit.", + parameters: [ + { + name: "subreddit", + type: "string", + required: true, + description: "The name of the subreddit to fetch posts from.", + }, + { + name: "listing", + type: "string", + required: false, + description: "The type of listing to fetch. Valid values are 'hot', 'new', 'rising', 'top', 'controversial'.", + default: "hot", + }, + { + name: "limit", + type: "integer", + required: false, + description: "The maximum number of posts to fetch. Max is 100.", + default: 10, + }, + { + name: "cursor", + type: "string", + required: false, + description: "The pagination token from a previous call.", + }, + { + name: "time_range", + type: "string", + required: false, + description: "The time range for filtering posts. Must be provided if the listing type is 'top' or 'controversial'. Valid values are 'NOW', 'TODAY', 'THIS_WEEK', 'THIS_MONTH', 'THIS_YEAR', 'ALL_TIME'.", + default: "TODAY", + }, + ], + category: "social", + }, + { + tool_name: "Reddit.GetContentOfPost", + description: "Get the content (body) of a Reddit post by its identifier.", + parameters: [ + { + name: "post_identifier", + type: "string", + required: true, + description: "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", + }, + ], + category: "social", + }, + { + tool_name: "Reddit.GetContentOfMultiplePosts", + description: "Get the content (body) of multiple Reddit posts by their identifiers in a single request.", + parameters: [ + { + name: "post_identifiers", + type: "array", + required: true, + description: "A list of identifiers of the Reddit posts. The identifiers may be Reddit URLs, permalinks, fullnames, or post ids.", + }, + ], + category: "social", + }, + { + tool_name: "Reddit.GetTopLevelComments", + description: "Get the first page of top-level comments of a Reddit post.", + parameters: [ + { + name: "post_identifier", + type: "string", + required: true, + description: "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", + }, + ], + category: "social", + }, + { + tool_name: "Reddit.CheckSubredditAccess", + description: "Checks whether the specified subreddit exists and also if it is accessible to the authenticated user.", + parameters: [ + { + name: "subreddit", + type: "string", + required: true, + description: "The name of the subreddit to check.", + }, + ], + category: "social", + }, + { + tool_name: "Reddit.GetSubredditRules", + description: "Gets the rules of the specified subreddit.", + parameters: [ + { + name: "subreddit", + type: "string", + required: true, + description: "The name of the subreddit for which to fetch rules.", + }, + ], + category: "social", + }, + { + tool_name: "Reddit.GetMyUsername", + description: "Gets the username of the authenticated user.", + parameters: [], + category: "social", + }, + { + tool_name: "Reddit.GetMyPosts", + description: "Get posts that were created by the authenticated user sorted by newest first.", + parameters: [ + { + name: "limit", + type: "integer", + required: false, + description: "The maximum number of posts to fetch. Max is 100.", + default: 10, + }, + { + name: "include_body", + type: "boolean", + required: false, + description: "Whether to include the body of the posts in the response.", + default: true, + }, + { + name: "cursor", + type: "string", + required: false, + description: "The pagination token from a previous call.", + }, + ], + category: "social", + }, +]; + // Combine all tools const allTools: ToolDefinition[] = [ ...twitterTools, @@ -659,6 +885,7 @@ const allTools: ToolDefinition[] = [ ...githubTools, ...notionTools, ...spotifyTools, + ...redditTools, ]; export const toolsConfig: ToolsConfig = { diff --git a/frontend/src/lib/tools-providers.ts b/frontend/src/lib/tools-providers.ts index f111f59..3120a98 100644 --- a/frontend/src/lib/tools-providers.ts +++ b/frontend/src/lib/tools-providers.ts @@ -7,6 +7,7 @@ import { XIcon, SpotifyIcon, LinkedInIcon, + RedditIcon, } from "../components/ProviderIcons"; // Centralized tools configuration for providers @@ -113,6 +114,15 @@ export const toolsProviders: ToolProvider[] = [ enabled: true, tools: [], }, + { + id: "reddit", + name: "Reddit", + description: "Integrate with Reddit", + icon: RedditIcon, + scopes: ["read", "submit"], + enabled: true, + tools: [], + }, ]; export default toolsProviders; From f0e685e3f27fb3ad0036e602256c473a9c9149ec Mon Sep 17 00:00:00 2001 From: Alex Choi Date: Tue, 28 Oct 2025 20:01:56 +0000 Subject: [PATCH 3/6] update skeleton --- frontend/src/app/settings/page.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx index e2e6471..7ade872 100644 --- a/frontend/src/app/settings/page.tsx +++ b/frontend/src/app/settings/page.tsx @@ -37,7 +37,7 @@ export default function SettingsPage() { }); const [authorizingTool, setAuthorizingTool] = useState(null); const [connectedTools, setConnectedTools] = useState>( - {}, + {} ); const [checkingStatus, setCheckingStatus] = useState(true); const router = useRouter(); @@ -101,7 +101,7 @@ export default function SettingsPage() { acc[toolId] = authorized; return acc; }, - {} as Record, + {} as Record ); setConnectedTools(statusMap); @@ -183,7 +183,7 @@ export default function SettingsPage() { } catch (error: any) { console.error("Failed to authorize tool:", error); toast.error( - error.message || "Failed to authorize tool. Please try again.", + error.message || "Failed to authorize tool. Please try again." ); setAuthorizingTool(null); } @@ -348,7 +348,7 @@ export default function SettingsPage() { {checkingStatus ? ( // Skeleton loading state <> - {[1, 2, 3, 4, 5, 6, 7].map((i) => ( + {[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (
Date: Tue, 28 Oct 2025 20:02:56 +0000 Subject: [PATCH 4/6] format --- frontend/src/app/settings/page.tsx | 8 +++--- frontend/src/lib/tools-config.ts | 42 ++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx index 7ade872..7e1e056 100644 --- a/frontend/src/app/settings/page.tsx +++ b/frontend/src/app/settings/page.tsx @@ -37,7 +37,7 @@ export default function SettingsPage() { }); const [authorizingTool, setAuthorizingTool] = useState(null); const [connectedTools, setConnectedTools] = useState>( - {} + {}, ); const [checkingStatus, setCheckingStatus] = useState(true); const router = useRouter(); @@ -101,7 +101,7 @@ export default function SettingsPage() { acc[toolId] = authorized; return acc; }, - {} as Record + {} as Record, ); setConnectedTools(statusMap); @@ -183,7 +183,7 @@ export default function SettingsPage() { } catch (error: any) { console.error("Failed to authorize tool:", error); toast.error( - error.message || "Failed to authorize tool. Please try again." + error.message || "Failed to authorize tool. Please try again.", ); setAuthorizingTool(null); } @@ -420,7 +420,7 @@ export default function SettingsPage() { tool.enabled && handleAuthorizeTool( tool.id, - "scopes" in tool ? tool.scopes : undefined + "scopes" in tool ? tool.scopes : undefined, ) } disabled={isDisabled} diff --git a/frontend/src/lib/tools-config.ts b/frontend/src/lib/tools-config.ts index 1c355a4..916128e 100644 --- a/frontend/src/lib/tools-config.ts +++ b/frontend/src/lib/tools-config.ts @@ -657,7 +657,8 @@ const redditTools: ToolDefinition[] = [ name: "subreddit", type: "string", required: true, - description: "The name of the subreddit to which the post will be submitted.", + description: + "The name of the subreddit to which the post will be submitted.", }, { name: "title", @@ -669,7 +670,8 @@ const redditTools: ToolDefinition[] = [ name: "body", type: "string", required: false, - description: "The body of the post in markdown format. Should never be the same as the title.", + description: + "The body of the post in markdown format. Should never be the same as the title.", }, { name: "nsfw", @@ -703,7 +705,8 @@ const redditTools: ToolDefinition[] = [ name: "post_identifier", type: "string", required: true, - description: "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", + description: + "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", }, { name: "text", @@ -722,7 +725,8 @@ const redditTools: ToolDefinition[] = [ name: "comment_identifier", type: "string", required: true, - description: "The identifier of the Reddit comment to reply to. The identifier may be a comment ID, a Reddit URL to the comment, a permalink to the comment, or the fullname of the comment.", + description: + "The identifier of the Reddit comment to reply to. The identifier may be a comment ID, a Reddit URL to the comment, a permalink to the comment, or the fullname of the comment.", }, { name: "text", @@ -735,7 +739,8 @@ const redditTools: ToolDefinition[] = [ }, { tool_name: "Reddit.GetPostsInSubreddit", - description: "Gets posts titles, links, and other metadata in the specified subreddit.", + description: + "Gets posts titles, links, and other metadata in the specified subreddit.", parameters: [ { name: "subreddit", @@ -747,7 +752,8 @@ const redditTools: ToolDefinition[] = [ name: "listing", type: "string", required: false, - description: "The type of listing to fetch. Valid values are 'hot', 'new', 'rising', 'top', 'controversial'.", + description: + "The type of listing to fetch. Valid values are 'hot', 'new', 'rising', 'top', 'controversial'.", default: "hot", }, { @@ -767,7 +773,8 @@ const redditTools: ToolDefinition[] = [ name: "time_range", type: "string", required: false, - description: "The time range for filtering posts. Must be provided if the listing type is 'top' or 'controversial'. Valid values are 'NOW', 'TODAY', 'THIS_WEEK', 'THIS_MONTH', 'THIS_YEAR', 'ALL_TIME'.", + description: + "The time range for filtering posts. Must be provided if the listing type is 'top' or 'controversial'. Valid values are 'NOW', 'TODAY', 'THIS_WEEK', 'THIS_MONTH', 'THIS_YEAR', 'ALL_TIME'.", default: "TODAY", }, ], @@ -781,20 +788,23 @@ const redditTools: ToolDefinition[] = [ name: "post_identifier", type: "string", required: true, - description: "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", + description: + "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", }, ], category: "social", }, { tool_name: "Reddit.GetContentOfMultiplePosts", - description: "Get the content (body) of multiple Reddit posts by their identifiers in a single request.", + description: + "Get the content (body) of multiple Reddit posts by their identifiers in a single request.", parameters: [ { name: "post_identifiers", type: "array", required: true, - description: "A list of identifiers of the Reddit posts. The identifiers may be Reddit URLs, permalinks, fullnames, or post ids.", + description: + "A list of identifiers of the Reddit posts. The identifiers may be Reddit URLs, permalinks, fullnames, or post ids.", }, ], category: "social", @@ -807,14 +817,16 @@ const redditTools: ToolDefinition[] = [ name: "post_identifier", type: "string", required: true, - description: "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", + description: + "The identifier of the Reddit post. The identifier may be a Reddit URL, a permalink, a fullname, or a post id.", }, ], category: "social", }, { tool_name: "Reddit.CheckSubredditAccess", - description: "Checks whether the specified subreddit exists and also if it is accessible to the authenticated user.", + description: + "Checks whether the specified subreddit exists and also if it is accessible to the authenticated user.", parameters: [ { name: "subreddit", @@ -846,7 +858,8 @@ const redditTools: ToolDefinition[] = [ }, { tool_name: "Reddit.GetMyPosts", - description: "Get posts that were created by the authenticated user sorted by newest first.", + description: + "Get posts that were created by the authenticated user sorted by newest first.", parameters: [ { name: "limit", @@ -859,7 +872,8 @@ const redditTools: ToolDefinition[] = [ name: "include_body", type: "boolean", required: false, - description: "Whether to include the body of the posts in the response.", + description: + "Whether to include the body of the posts in the response.", default: true, }, { From 18900912a1d541c8a6b0b3c9fbe0e587b26e2aa9 Mon Sep 17 00:00:00 2001 From: Alex Choi Date: Tue, 28 Oct 2025 20:08:35 +0000 Subject: [PATCH 5/6] add all scopes --- frontend/src/lib/tools-providers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/lib/tools-providers.ts b/frontend/src/lib/tools-providers.ts index 3120a98..76ecdc2 100644 --- a/frontend/src/lib/tools-providers.ts +++ b/frontend/src/lib/tools-providers.ts @@ -119,7 +119,7 @@ export const toolsProviders: ToolProvider[] = [ name: "Reddit", description: "Integrate with Reddit", icon: RedditIcon, - scopes: ["read", "submit"], + scopes: ["read", "submit", "identity", "subscribe", "history", "account", "announcements", "edit", "flair", "livemanage", "modconfig", "modlog", "modothers", "modtraffic", "modwiki", "mysubreddits", "privatemessages", "report", "save", "vote", "wikiedit", "wikiread"], enabled: true, tools: [], }, From 991072865ce91c155f523f546841576955609aa6 Mon Sep 17 00:00:00 2001 From: Alex Choi Date: Tue, 28 Oct 2025 20:08:48 +0000 Subject: [PATCH 6/6] format --- frontend/src/lib/tools-providers.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/tools-providers.ts b/frontend/src/lib/tools-providers.ts index 76ecdc2..1583716 100644 --- a/frontend/src/lib/tools-providers.ts +++ b/frontend/src/lib/tools-providers.ts @@ -119,7 +119,30 @@ export const toolsProviders: ToolProvider[] = [ name: "Reddit", description: "Integrate with Reddit", icon: RedditIcon, - scopes: ["read", "submit", "identity", "subscribe", "history", "account", "announcements", "edit", "flair", "livemanage", "modconfig", "modlog", "modothers", "modtraffic", "modwiki", "mysubreddits", "privatemessages", "report", "save", "vote", "wikiedit", "wikiread"], + scopes: [ + "read", + "submit", + "identity", + "subscribe", + "history", + "account", + "announcements", + "edit", + "flair", + "livemanage", + "modconfig", + "modlog", + "modothers", + "modtraffic", + "modwiki", + "mysubreddits", + "privatemessages", + "report", + "save", + "vote", + "wikiedit", + "wikiread", + ], enabled: true, tools: [], },