mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-01 19:32:40 +02:00
Refactor listToolkits function to remove cursor parameter and implement pagination
- Updated listToolkits in composio-handler.ts to paginate through API results, collecting all curated toolkits. - Adjusted IPC handler in ipc.ts to call the modified listToolkits without cursor argument. - Made properties in ToolkitInfo optional in settings-dialog.tsx for improved flexibility. - Removed the unused enabled-tools-repo.ts file to clean up the codebase.
This commit is contained in:
parent
7f8d2e64af
commit
0edc89b4a0
4 changed files with 19 additions and 155 deletions
|
|
@ -309,7 +309,7 @@ export async function useComposioForGoogleCalendar(): Promise<{ enabled: boolean
|
|||
/**
|
||||
* List available Composio toolkits — filtered to curated list only
|
||||
*/
|
||||
export async function listToolkits(cursor?: string): Promise<{
|
||||
export async function listToolkits(): Promise<{
|
||||
items: Array<{
|
||||
slug: string;
|
||||
name: string;
|
||||
|
|
@ -321,12 +321,21 @@ export async function listToolkits(cursor?: string): Promise<{
|
|||
nextCursor: string | null;
|
||||
totalItems: number;
|
||||
}> {
|
||||
// Fetch all toolkits and filter to curated list
|
||||
const result = await composioClient.listToolkits(cursor || null);
|
||||
const filtered = result.items.filter(item => CURATED_TOOLKIT_SLUGS.has(item.slug));
|
||||
// Paginate through all API pages to collect every curated toolkit
|
||||
type ToolkitItem = Awaited<ReturnType<typeof composioClient.listToolkits>>['items'][number];
|
||||
const allItems: ToolkitItem[] = [];
|
||||
let cursor: string | null = null;
|
||||
const maxPages = 10; // safety limit
|
||||
for (let page = 0; page < maxPages; page++) {
|
||||
const result = await composioClient.listToolkits(cursor);
|
||||
allItems.push(...result.items);
|
||||
cursor = result.next_cursor;
|
||||
if (!cursor) break;
|
||||
}
|
||||
const filtered = allItems.filter(item => CURATED_TOOLKIT_SLUGS.has(item.slug));
|
||||
return {
|
||||
items: filtered,
|
||||
nextCursor: result.next_cursor,
|
||||
nextCursor: null,
|
||||
totalItems: filtered.length,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -564,8 +564,8 @@ export function setupIpcHandlers() {
|
|||
return composioHandler.listConnected();
|
||||
},
|
||||
// Composio Tools Library handlers
|
||||
'composio:list-toolkits': async (_event, args) => {
|
||||
return composioHandler.listToolkits(args.cursor);
|
||||
'composio:list-toolkits': async () => {
|
||||
return composioHandler.listToolkits();
|
||||
},
|
||||
'composio:use-composio-for-google': async () => {
|
||||
return composioHandler.useComposioForGoogle();
|
||||
|
|
|
|||
|
|
@ -719,9 +719,9 @@ interface ToolkitInfo {
|
|||
slug: string
|
||||
name: string
|
||||
meta: { description: string; logo: string; tools_count: number; triggers_count: number }
|
||||
no_auth: boolean
|
||||
auth_schemes: string[]
|
||||
composio_managed_auth_schemes: string[]
|
||||
no_auth?: boolean
|
||||
auth_schemes?: string[]
|
||||
composio_managed_auth_schemes?: string[]
|
||||
}
|
||||
|
||||
function ToolsLibrarySettings({ dialogOpen }: { dialogOpen: boolean }) {
|
||||
|
|
|
|||
|
|
@ -1,145 +0,0 @@
|
|||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { z } from "zod";
|
||||
import { WorkDir } from "../config/config.js";
|
||||
|
||||
const ENABLED_TOOLS_FILE = path.join(WorkDir, 'data', 'composio', 'enabled_tools.json');
|
||||
|
||||
/**
|
||||
* Schema for an enabled Composio tool
|
||||
*/
|
||||
export const ZEnabledTool = z.object({
|
||||
slug: z.string(),
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
toolkitSlug: z.string(),
|
||||
inputParameters: z.object({
|
||||
type: z.literal('object').optional().default('object'),
|
||||
properties: z.record(z.string(), z.unknown()).optional().default({}),
|
||||
required: z.array(z.string()).optional(),
|
||||
}).optional().default({ type: 'object', properties: {} }),
|
||||
});
|
||||
|
||||
export type EnabledTool = z.infer<typeof ZEnabledTool>;
|
||||
|
||||
/**
|
||||
* Schema for the enabled tools storage file
|
||||
*/
|
||||
const ZEnabledToolsStorage = z.object({
|
||||
tools: z.record(z.string(), ZEnabledTool), // keyed by tool slug
|
||||
});
|
||||
|
||||
type EnabledToolsStorage = z.infer<typeof ZEnabledToolsStorage>;
|
||||
|
||||
/**
|
||||
* Interface for Composio enabled tools repository
|
||||
*/
|
||||
export interface IComposioEnabledToolsRepo {
|
||||
getAll(): Record<string, EnabledTool>;
|
||||
getByToolkit(toolkitSlug: string): EnabledTool[];
|
||||
enable(tool: EnabledTool): void;
|
||||
enableBatch(tools: EnabledTool[]): void;
|
||||
disable(toolSlug: string): void;
|
||||
disableBatch(toolSlugs: string[]): void;
|
||||
disableAllForToolkit(toolkitSlug: string): void;
|
||||
isEnabled(toolSlug: string): boolean;
|
||||
}
|
||||
|
||||
function ensureStorageDir(): void {
|
||||
const dir = path.dirname(ENABLED_TOOLS_FILE);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
function loadStorageFromDisk(): EnabledToolsStorage {
|
||||
try {
|
||||
if (fs.existsSync(ENABLED_TOOLS_FILE)) {
|
||||
const data = fs.readFileSync(ENABLED_TOOLS_FILE, 'utf-8');
|
||||
return ZEnabledToolsStorage.parse(JSON.parse(data));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[ComposioEnabledTools] Failed to load storage:', error);
|
||||
}
|
||||
return { tools: {} };
|
||||
}
|
||||
|
||||
function saveStorageToDisk(storage: EnabledToolsStorage): void {
|
||||
ensureStorageDir();
|
||||
fs.writeFileSync(ENABLED_TOOLS_FILE, JSON.stringify(storage, null, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository for managing enabled Composio tools.
|
||||
* Uses an in-memory cache loaded once from disk. Mutations write through to disk.
|
||||
*/
|
||||
export class ComposioEnabledToolsRepo implements IComposioEnabledToolsRepo {
|
||||
private cache: EnabledToolsStorage | null = null;
|
||||
|
||||
private getStorage(): EnabledToolsStorage {
|
||||
if (!this.cache) {
|
||||
this.cache = loadStorageFromDisk();
|
||||
}
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
private persist(): void {
|
||||
if (this.cache) {
|
||||
saveStorageToDisk(this.cache);
|
||||
}
|
||||
}
|
||||
|
||||
getAll(): Record<string, EnabledTool> {
|
||||
return this.getStorage().tools;
|
||||
}
|
||||
|
||||
getByToolkit(toolkitSlug: string): EnabledTool[] {
|
||||
const storage = this.getStorage();
|
||||
return Object.values(storage.tools).filter(t => t.toolkitSlug === toolkitSlug);
|
||||
}
|
||||
|
||||
enable(tool: EnabledTool): void {
|
||||
const storage = this.getStorage();
|
||||
storage.tools[tool.slug] = tool;
|
||||
this.persist();
|
||||
}
|
||||
|
||||
enableBatch(tools: EnabledTool[]): void {
|
||||
const storage = this.getStorage();
|
||||
for (const tool of tools) {
|
||||
storage.tools[tool.slug] = tool;
|
||||
}
|
||||
this.persist();
|
||||
}
|
||||
|
||||
disable(toolSlug: string): void {
|
||||
const storage = this.getStorage();
|
||||
delete storage.tools[toolSlug];
|
||||
this.persist();
|
||||
}
|
||||
|
||||
disableBatch(toolSlugs: string[]): void {
|
||||
const storage = this.getStorage();
|
||||
for (const slug of toolSlugs) {
|
||||
delete storage.tools[slug];
|
||||
}
|
||||
this.persist();
|
||||
}
|
||||
|
||||
disableAllForToolkit(toolkitSlug: string): void {
|
||||
const storage = this.getStorage();
|
||||
for (const [slug, tool] of Object.entries(storage.tools)) {
|
||||
if (tool.toolkitSlug === toolkitSlug) {
|
||||
delete storage.tools[slug];
|
||||
}
|
||||
}
|
||||
this.persist();
|
||||
}
|
||||
|
||||
isEnabled(toolSlug: string): boolean {
|
||||
const storage = this.getStorage();
|
||||
return toolSlug in storage.tools;
|
||||
}
|
||||
}
|
||||
|
||||
export const composioEnabledToolsRepo = new ComposioEnabledToolsRepo();
|
||||
Loading…
Add table
Add a link
Reference in a new issue