@mastra/editor 0.10.2-alpha.0 → 0.11.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers/composio.ts"],"sourcesContent":["import type {\n ToolProvider,\n ToolProviderInfo,\n ToolProviderToolkit,\n ToolProviderToolInfo,\n ToolProviderListResult,\n ListToolProviderToolsOptions,\n ResolveToolProviderToolsOptions,\n} from '@mastra/core/tool-provider';\nimport type { ToolAction } from '@mastra/core/tools';\nimport type { StorageToolConfig } from '@mastra/core/storage';\nimport { MASTRA_RESOURCE_ID_KEY } from '@mastra/core/request-context';\n\nimport { Composio } from '@composio/core';\nimport type { Tool as ComposioTool, ToolKitItem, ToolListParams as ComposioToolListParams } from '@composio/core';\nimport { MastraProvider } from '@composio/mastra';\nimport type { MastraTool, MastraToolCollection } from '@composio/mastra';\n\nexport interface ComposioToolProviderConfig {\n /** Composio API key */\n apiKey: string;\n}\n\n/**\n * Composio tool provider adapter.\n *\n * Uses `@composio/core` + `@composio/mastra` SDKs for both tool discovery\n * and runtime resolution. Both packages are optional peer dependencies and\n * tree-shaken if this provider class isn't imported.\n *\n * Discovery methods (`listToolkits`, `listTools`, `getToolSchema`) use the\n * raw Composio client (no userId required).\n *\n * Runtime method (`resolveTools`) uses the MastraProvider so returned tools are\n * already in Mastra's `createTool()` format.\n */\nexport class ComposioToolProvider implements ToolProvider {\n readonly info: ToolProviderInfo = {\n id: 'composio',\n name: 'Composio',\n description: 'Access 10,000+ tools from 150+ apps via Composio',\n };\n\n private apiKey: string;\n private rawClient: Composio | null = null;\n private mastraClient: Composio<MastraProvider> | null = null;\n\n constructor(config: ComposioToolProviderConfig) {\n this.apiKey = config.apiKey;\n }\n\n /**\n * Get or create a raw Composio client (no provider — for discovery only).\n */\n private getRawClient(): Composio {\n if (!this.rawClient) {\n this.rawClient = new Composio({ apiKey: this.apiKey });\n }\n return this.rawClient;\n }\n\n /**\n * Get or create a Composio client with MastraProvider (for runtime tools).\n */\n private getMastraClient(): Composio<MastraProvider> {\n if (!this.mastraClient) {\n this.mastraClient = new Composio({\n apiKey: this.apiKey,\n provider: new MastraProvider(),\n });\n }\n return this.mastraClient;\n }\n\n /**\n * List available toolkits via `composio.toolkits.get({})`.\n * Returns: `ToolKitListResponse` — an array of `{ slug, name, meta: { description, logo, ... } }`.\n */\n async listToolkits(): Promise<ToolProviderListResult<ToolProviderToolkit>> {\n const composio = this.getRawClient();\n const toolkits: ToolKitItem[] = await composio.toolkits.get({});\n\n const data: ToolProviderToolkit[] = toolkits.map(tk => ({\n slug: tk.slug,\n name: tk.name,\n description: tk.meta?.description,\n icon: tk.meta?.logo,\n }));\n return { data };\n }\n\n /**\n * List available tools via `composio.tools.getRawComposioTools()`.\n * No userId required — returns raw tool definitions for UI browsing.\n */\n async listTools(options?: ListToolProviderToolsOptions): Promise<ToolProviderListResult<ToolProviderToolInfo>> {\n const composio = this.getRawClient();\n\n // ToolListParams is a discriminated union in TypeScript but the\n // underlying Zod schema accepts `limit` on every variant. We cast\n // through the base type so `limit` is always forwarded.\n const limit = options?.perPage;\n const query: ComposioToolListParams = (\n options?.toolkit\n ? { toolkits: [options.toolkit], limit, search: options?.search }\n : options?.search\n ? { search: options.search, limit }\n : { toolkits: [] as string[], limit }\n ) as ComposioToolListParams;\n\n const rawTools: ComposioTool[] = await composio.tools.getRawComposioTools(query);\n\n const data: ToolProviderToolInfo[] = rawTools.map(tool => ({\n slug: tool.slug,\n name: tool.name ?? tool.slug,\n description: tool.description,\n toolkit: tool.toolkit?.slug,\n }));\n\n return {\n data,\n pagination: {\n page: options?.page ?? 1,\n perPage: limit,\n hasMore: limit !== undefined && rawTools.length >= limit,\n },\n };\n }\n\n /**\n * Get JSON schema for a specific tool via `composio.tools.getRawComposioToolBySlug()`.\n */\n async getToolSchema(toolSlug: string): Promise<Record<string, unknown> | null> {\n try {\n const composio = this.getRawClient();\n const tool: ComposioTool = await composio.tools.getRawComposioToolBySlug(toolSlug);\n if (!tool) return null;\n return (tool.inputParameters ?? {}) as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n\n /**\n * Resolve executable tools in Mastra format via `composio.tools.get(userId, { tools: [...] })`.\n *\n * Uses MastraProvider so returned tools are `ReturnType<typeof createTool>` — compatible\n * with Mastra's `ToolAction` interface.\n */\n async resolveTools(\n toolSlugs: string[],\n toolConfigs?: Record<string, StorageToolConfig>,\n options?: ResolveToolProviderToolsOptions,\n ): Promise<Record<string, ToolAction<unknown, unknown>>> {\n if (toolSlugs.length === 0) return {};\n\n const resourceId = options?.requestContext?.[MASTRA_RESOURCE_ID_KEY];\n const userId = typeof resourceId === 'string' ? resourceId : (options?.userId ?? 'default');\n const composio = this.getMastraClient();\n\n // composio.tools.get returns MastraToolCollection = Record<string, MastraTool>\n const mastraTools: MastraToolCollection = await composio.tools.get(userId, { tools: toolSlugs });\n\n const result: Record<string, ToolAction<unknown, unknown>> = {};\n const entries: [string, MastraTool][] = Object.entries(mastraTools ?? {});\n\n for (const [key, tool] of entries) {\n if (!tool) continue;\n const slug = tool.id ?? key;\n const descOverride = toolConfigs?.[slug]?.description;\n if (descOverride) {\n result[slug] = { ...tool, description: descOverride };\n } else {\n result[slug] = tool;\n }\n }\n\n return result;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/providers/composio.ts"],"sourcesContent":["import type {\n AuthFlowStatus,\n AuthorizeOpts,\n ConnectionField,\n ExistingConnection,\n ListConnectionsOpts,\n ListConnectionsResult,\n ListToolsOpts,\n ListToolsResult,\n ResolveToolsOpts,\n ToolProviderCapabilities,\n ToolProviderHealth,\n ToolProviderInfo,\n ToolProviderToolkit,\n} from '@mastra/core/tool-provider';\nimport { BaseToolProvider } from '@mastra/core/tool-provider';\nimport type { BaseToolProviderOptions } from '@mastra/core/tool-provider';\nimport type { ToolAction } from '@mastra/core/tools';\nimport { MASTRA_RESOURCE_ID_KEY } from '@mastra/core/request-context';\n\nimport { Composio } from '@composio/core';\nimport type {\n ConnectedAccountListResponse,\n Tool as ComposioTool,\n ToolListParams as ComposioToolListParams,\n ToolKitItem,\n} from '@composio/core';\nimport { MastraProvider } from '@composio/mastra';\nimport type { MastraToolCollection } from '@composio/mastra';\n\nexport interface ComposioToolProviderConfig extends BaseToolProviderOptions {\n /** Composio API key. */\n apiKey: string;\n}\n\nconst COMPOSIO_PROVIDER_ID = 'composio' as const;\nconst DEFAULT_INTERNAL_USER_ID = 'default';\n\n/**\n * Composio implementation of the {@link BaseToolProvider} contract.\n *\n * Discovery (`listAllToolkits`, `listAllTools`) uses the raw Composio\n * client. Runtime (`resolveToolsVNext`) uses {@link MastraProvider} so resolved\n * tools are already in `createTool()` shape; each tool gets a\n * `beforeExecute` modifier that injects\n * `connectedAccountId = connectionId`, and `outputSchema` is cleared\n * because Composio returns union schemas that Mastra's runtime rejects.\n *\n * Allowlist filtering is layered by {@link BaseToolProvider}; this class\n * never reads `allowedToolkits` / `allowedTools` directly.\n */\nexport class ComposioToolProvider extends BaseToolProvider {\n readonly info: ToolProviderInfo = {\n id: COMPOSIO_PROVIDER_ID,\n name: 'Composio',\n description: 'Access 10,000+ tools from 150+ apps via Composio',\n };\n readonly capabilities: ToolProviderCapabilities = {\n multipleConnectionsPerToolkit: true,\n batchConnectionStatus: true,\n reauthorizeReusesConnectionId: true,\n supportsRevoke: true,\n };\n\n private readonly apiKey: string;\n private rawClient: Composio | null = null;\n private mastraClient: Composio<MastraProvider> | null = null;\n\n constructor(config: ComposioToolProviderConfig) {\n super({\n allowedToolkits: config.allowedToolkits,\n allowedTools: config.allowedTools,\n });\n this.apiKey = config.apiKey;\n }\n\n // ── client cache ──────────────────────────────────────────────────────\n\n private getRawClient(): Composio {\n if (!this.rawClient) {\n this.rawClient = new Composio({ apiKey: this.apiKey });\n }\n return this.rawClient;\n }\n\n private getMastraClient(): Composio<MastraProvider> {\n if (!this.mastraClient) {\n this.mastraClient = new Composio({\n apiKey: this.apiKey,\n provider: new MastraProvider(),\n });\n }\n return this.mastraClient;\n }\n\n // ── catalog (BaseToolProvider adds allowlist filter on top) ───────────\n\n protected async listAllToolkits(): Promise<ToolProviderToolkit[]> {\n const composio = this.getRawClient();\n const toolkits: ToolKitItem[] = await composio.toolkits.get({});\n return toolkits.map(tk => ({\n slug: tk.slug,\n name: tk.name,\n description: tk.meta?.description,\n icon: tk.meta?.logo,\n }));\n }\n\n protected async listAllTools(opts: ListToolsOpts): Promise<ListToolsResult> {\n const composio = this.getRawClient();\n\n // Composio's `getRawComposioTools` query is a discriminated union — every\n // variant accepts `limit`, but the toolkits/search keys are exclusive in\n // the TS types. We build the variant we need, then cast to the union.\n //\n // When the caller doesn't scope to a specific toolkit, we fall back to\n // the admin allowlist so the SDK returns a flat list across allowed\n // toolkits in a single hop (vs. fanning out per toolkit).\n const limit = opts.perPage;\n const fallbackToolkits = this.allowedToolkits.length > 0 ? [...this.allowedToolkits] : undefined;\n const query: ComposioToolListParams = (\n opts.toolkit\n ? { toolkits: [opts.toolkit], limit, search: opts.search }\n : fallbackToolkits\n ? { toolkits: fallbackToolkits, limit, search: opts.search }\n : opts.search\n ? { search: opts.search, limit }\n : { toolkits: [] as string[], limit }\n ) as ComposioToolListParams;\n\n // Composio's SDK validates every tool's input/output schema against an\n // internal zod shape and throws on the first malformed tool — so one bad\n // toolkit can poison a multi-toolkit query. Treat validation errors as a\n // soft failure and return an empty page rather than a 500.\n let rawTools: ComposioTool[] = [];\n try {\n rawTools = await composio.tools.getRawComposioTools(query);\n } catch (err) {\n console.warn(\n `[ComposioToolProvider] listAllTools failed for query ${JSON.stringify(query)} — returning empty page`,\n err,\n );\n }\n\n const data = rawTools.map(tool => ({\n slug: tool.slug,\n name: tool.name ?? tool.slug,\n description: tool.description,\n toolkit: tool.toolkit?.slug ?? opts.toolkit ?? '',\n }));\n\n return {\n data,\n pagination: {\n page: opts.page ?? 1,\n perPage: limit,\n hasMore: limit !== undefined && rawTools.length >= limit,\n },\n };\n }\n\n // ── runtime ───────────────────────────────────────────────────────────\n\n async resolveToolsVNext(opts: ResolveToolsOpts): Promise<Record<string, ToolAction<any, any, any>>> {\n if (opts.toolSlugs.length === 0) return {};\n\n // For author-bound connections, the runtime fan-out passes the agent's\n // author id explicitly. Use it as the Composio user bucket so the pin\n // resolves for any invoker (not just the original author).\n const internalUserId =\n opts.authorId && opts.authorId.length > 0 ? opts.authorId : resolveInternalUserId(opts.requestContext);\n const composio = this.getMastraClient();\n\n const modifiers = {\n // `connectedAccountId` is not threaded through Composio's `execute`\n // option bag in @composio/mastra; the only documented per-call hook\n // is `beforeExecute`, which receives the params object that flows\n // into the API call. Mutating `params.connectedAccountId` routes\n // the call to a specific account.\n beforeExecute: ({ params }: { params: { connectedAccountId?: string; userId?: string } }) => {\n params.connectedAccountId = opts.connectionId;\n return params;\n },\n };\n\n const mastraTools = (await composio.tools.get(\n internalUserId,\n { tools: opts.toolSlugs },\n modifiers,\n )) as MastraToolCollection;\n\n const result: Record<string, ToolAction<any, any, any>> = {};\n\n for (const [key, tool] of Object.entries(mastraTools ?? {})) {\n if (!tool) continue;\n const slug = (tool as { id?: string }).id ?? key;\n\n // Composio returns union output schemas (`successful: true | false`) that\n // Mastra's runtime cannot validate; clearing avoids per-tool validation\n // errors at execute time. The property may be non-writable on some SDK\n // versions, so we swallow assignment errors.\n try {\n (tool as unknown as { outputSchema: unknown }).outputSchema = undefined;\n } catch {\n // ignore\n }\n\n const descOverride = opts.toolMeta?.[slug]?.description;\n if (descOverride) {\n try {\n (tool as unknown as { description: string }).description = descOverride;\n } catch {\n // ignore\n }\n }\n\n result[slug] = tool as ToolAction<any, any, any>;\n }\n\n return result;\n }\n\n // ── auth surface ──────────────────────────────────────────────────────\n\n async authorize(opts: AuthorizeOpts): Promise<{ url: string; authId: string }> {\n const composio = this.getRawClient();\n const { id: authConfigId, authScheme } = await this.resolveAuthConfig(opts.toolkit);\n\n // `connectionId` carries the internal user bucket for the runtime fan-out;\n // for authorize we treat it as the Composio `userId` so the new connected\n // account lands under the same bucket as the agent's resolved identity.\n const internalUserId = opts.connectionId || DEFAULT_INTERNAL_USER_ID;\n // `allowMultiple: true` — we explicitly support N connected accounts per\n // (user, auth config) and disambiguate at runtime via per-connection labels.\n // `config` carries provider-specific user-supplied fields (e.g. Confluence\n // subdomain) collected by the picker via `listConnectionFields`. Composio\n // expects a discriminated `{ authScheme, val }` shape; we cast through\n // `unknown` because our generic interface keeps it Record-shaped.\n const initiateConfig =\n opts.config && Object.keys(opts.config).length > 0 && authScheme\n ? ({ authScheme, val: opts.config } as unknown as Parameters<\n typeof composio.connectedAccounts.initiate\n >[2] extends infer O\n ? O extends { config?: infer C }\n ? C\n : never\n : never)\n : undefined;\n const request = await composio.connectedAccounts.initiate(internalUserId, authConfigId, {\n allowMultiple: true,\n ...(initiateConfig ? { config: initiateConfig } : {}),\n });\n\n if (!request.redirectUrl) {\n throw new Error(`[composio] initiate did not return a redirectUrl for toolkit \"${opts.toolkit}\"`);\n }\n\n return { url: request.redirectUrl, authId: request.id };\n }\n\n async listConnectionFields({ toolkit }: { toolkit: string }): Promise<ConnectionField[]> {\n const composio = this.getRawClient();\n const { authScheme } = await this.resolveAuthConfig(toolkit);\n if (!authScheme) {\n // Without a known auth scheme we can't query the field schema — fall\n // back to no fields rather than blocking the user.\n return [];\n }\n const fields = await composio.toolkits.getConnectedAccountInitiationFields(toolkit, authScheme, {\n requiredOnly: false,\n });\n return fields.map(f => ({\n name: f.name,\n displayName: f.displayName,\n description: f.description,\n type: coerceFieldType(f.type),\n required: f.required ?? false,\n default: f.default ?? undefined,\n }));\n }\n\n async getAuthStatus(authId: string): Promise<AuthFlowStatus> {\n const composio = this.getRawClient();\n const account = await composio.connectedAccounts.get(authId);\n switch (account.status) {\n case 'ACTIVE':\n return 'completed';\n case 'INITIALIZING':\n case 'INITIATED':\n return 'pending';\n case 'FAILED':\n case 'EXPIRED':\n case 'INACTIVE':\n return 'failed';\n default:\n return 'pending';\n }\n }\n\n async getConnectionStatus(opts: {\n items: Array<{ connectionId: string; toolkit: string }>;\n }): Promise<Record<string, { connected: boolean }>> {\n if (opts.items.length === 0) return {};\n\n const composio = this.getRawClient();\n const toolkitSlugs = Array.from(new Set(opts.items.map(i => i.toolkit)));\n\n // One SDK call per `getConnectionStatus`, regardless of N items.\n // Filter by all referenced toolkits, then bucket locally by id.\n const list: ConnectedAccountListResponse = await composio.connectedAccounts.list({\n toolkitSlugs,\n });\n\n const liveById = new Map<string, { status: string; isDisabled: boolean }>();\n for (const item of list.items) {\n liveById.set(item.id, { status: item.status, isDisabled: item.isDisabled });\n }\n\n const result: Record<string, { connected: boolean }> = {};\n for (const { connectionId } of opts.items) {\n const live = liveById.get(connectionId);\n result[connectionId] = { connected: live ? live.status === 'ACTIVE' && !live.isDisabled : false };\n }\n return result;\n }\n\n async listConnections(opts: ListConnectionsOpts): Promise<ListConnectionsResult> {\n const composio = this.getRawClient();\n const page = opts.page ?? 1;\n const perPage = clampLimit(opts.perPage);\n\n // Normalize userIds[] / userId. Empty array = no buckets to list against,\n // short-circuit to avoid an unbounded Composio response.\n const userIds = resolveUserIds(opts);\n if (userIds && userIds.length === 0) {\n return { items: [], pagination: { page, perPage, hasMore: false } };\n }\n\n // Composio SDK 0.6.x uses cursor-based pagination on the wire. We surface\n // page-based pagination to keep the Mastra contract consistent with every\n // other list API. For now we only fetch the first page (page=1); paginated\n // requests for page > 1 are a follow-up — the UI does not yet paginate.\n const list: ConnectedAccountListResponse = await composio.connectedAccounts.list({\n toolkitSlugs: [opts.toolkit],\n ...(userIds ? { userIds } : {}),\n limit: perPage,\n });\n\n // Defensive: tolerate undocumented SDK shape drift where `items` is\n // missing or `nextCursor` is `null`/`undefined`/`''`.\n const items: ExistingConnection[] = (list.items ?? []).map(account => ({\n connectionId: account.id,\n status: mapComposioStatus(account.status, account.isDisabled),\n createdAt: account.createdAt,\n // `user_id` is preserved by the Composio SDK transform via spread but\n // isn't on the typed shape. Read it via a narrow cast.\n authorId: (account as unknown as { user_id?: string }).user_id,\n }));\n\n const nextCursor = (list as { nextCursor?: string | null }).nextCursor ?? null;\n const hasMore = typeof nextCursor === 'string' && nextCursor.length > 0;\n return { items, pagination: { page, perPage, hasMore } };\n }\n\n /**\n * Revoke a Composio connected account via\n * `DELETE /api/v3/connected_accounts/:nanoid`. Composio performs a soft\n * delete and responds with `{ success: boolean }`.\n *\n * Treats a 404 (account already deleted or never existed) as success so\n * the caller can drop its local pin without an error path. A `success:\n * false` response means the provider refused the delete and is surfaced\n * as an error so the caller does not delete its local row.\n */\n async revokeConnection(connectionId: string): Promise<void> {\n const composio = this.getRawClient();\n try {\n const res = (await composio.connectedAccounts.delete(connectionId)) as { success?: boolean } | undefined;\n if (res && res.success === false) {\n throw new Error(`Composio refused to delete connected account ${connectionId} (success=false)`);\n }\n } catch (err) {\n if (isNotFoundError(err)) return;\n throw err;\n }\n }\n\n async getHealth(): Promise<ToolProviderHealth> {\n try {\n const composio = this.getRawClient();\n await composio.toolkits.get({ limit: 1 } as Parameters<typeof composio.toolkits.get>[0]);\n return { ok: true };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : 'Composio SDK reachability check failed',\n };\n }\n }\n\n // ── helpers ───────────────────────────────────────────────────────────\n\n /**\n * Resolve the single ENABLED auth config for `toolkit`. Throws if zero\n * or multiple configs match — the admin must enable exactly one in the\n * Composio dashboard before agents can connect.\n */\n private async resolveAuthConfig(toolkit: string): Promise<{ id: string; authScheme?: ComposioAuthScheme }> {\n const composio = this.getRawClient();\n const response = await composio.authConfigs.list({ toolkit });\n const enabled = response.items.filter(item => item.status === 'ENABLED');\n\n if (enabled.length === 0) {\n throw new Error(\n `[composio] No ENABLED auth config for toolkit \"${toolkit}\". Enable one in the Composio dashboard.`,\n );\n }\n if (enabled.length > 1) {\n const ids = enabled.map(item => item.id).join(', ');\n throw new Error(\n `[composio] Multiple ENABLED auth configs for toolkit \"${toolkit}\" (${ids}). Keep exactly one enabled.`,\n );\n }\n return { id: enabled[0]!.id, authScheme: enabled[0]!.authScheme };\n }\n}\n\ntype ComposioAuthScheme = NonNullable<\n Awaited<ReturnType<Composio['authConfigs']['list']>>['items'][number]['authScheme']\n>;\n\n/**\n * Best-effort 404 detection across the various error shapes the Composio\n * SDK surfaces (typed error with `statusCode`, HTTP-like error with\n * `status`, or a plain message containing \"404\" / \"not found\").\n */\nfunction isNotFoundError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const e = err as { statusCode?: number; status?: number; message?: string };\n if (e.statusCode === 404 || e.status === 404) return true;\n const msg = typeof e.message === 'string' ? e.message.toLowerCase() : '';\n return msg.includes('not found') || msg.includes('404');\n}\n\n/**\n * Composio reports a free-form `type` string. Map common values to our\n * generic ConnectionField type vocabulary; everything else falls back to\n * `'string'`.\n */\nfunction coerceFieldType(type: string): 'string' | 'number' | 'boolean' {\n switch (type.toLowerCase()) {\n case 'number':\n case 'integer':\n case 'int':\n case 'float':\n return 'number';\n case 'bool':\n case 'boolean':\n return 'boolean';\n default:\n return 'string';\n }\n}\n\n/**\n * Map Composio account status + `isDisabled` to the {@link ExistingConnection}\n * status vocabulary surfaced to the picker UI.\n */\nfunction mapComposioStatus(status: string, isDisabled: boolean): ExistingConnection['status'] {\n if (isDisabled) return 'inactive';\n switch (status) {\n case 'ACTIVE':\n return 'active';\n case 'INITIALIZING':\n case 'INITIATED':\n return 'pending';\n case 'FAILED':\n case 'EXPIRED':\n return 'failed';\n case 'INACTIVE':\n return 'inactive';\n default:\n return 'pending';\n }\n}\n\n// Mirror of `MASTRA_USER_KEY` from `@mastra/server`. Inlined to avoid a\n// reverse dependency from `editor` onto `server`.\nconst MASTRA_USER_KEY = 'mastra__user';\n\n/**\n * Read the internal user id (Composio `userId`) from per-request context.\n *\n * The runtime fan-out is responsible for stamping the agent's resolved\n * author id (or `'default'`) into `requestContext` under\n * {@link MASTRA_RESOURCE_ID_KEY}.\n */\nfunction resolveInternalUserId(requestContext?: Record<string, unknown>): string {\n const resourceId = requestContext?.[MASTRA_RESOURCE_ID_KEY];\n if (typeof resourceId === 'string' && resourceId.length > 0) {\n return resourceId;\n }\n\n const user = requestContext?.[MASTRA_USER_KEY];\n if (user && typeof user === 'object' && 'id' in user) {\n const id = (user as { id: unknown }).id;\n if (typeof id === 'string' && id.length > 0) {\n return id;\n }\n }\n\n return DEFAULT_INTERNAL_USER_ID;\n}\n\n/**\n * Resolve `userIds[]` from `listConnections` opts.\n *\n * - If `userIds` is provided, use it as-is (including empty array, which\n * means \"no buckets to list against\").\n * - If `userId` is provided, normalize to `[userId]`.\n * - Otherwise fall back to the default internal user id (single-bucket).\n */\nfunction resolveUserIds(opts: ListConnectionsOpts): string[] | undefined {\n if (Array.isArray(opts.userIds)) return opts.userIds;\n if (typeof opts.userId === 'string' && opts.userId.length > 0) return [opts.userId];\n return [DEFAULT_INTERNAL_USER_ID];\n}\n\nconst DEFAULT_LIMIT = 50;\nconst MAX_LIMIT = 200;\n\nfunction clampLimit(limit: number | undefined): number {\n if (typeof limit !== 'number' || !Number.isFinite(limit) || limit <= 0) {\n return DEFAULT_LIMIT;\n }\n return Math.min(Math.floor(limit), MAX_LIMIT);\n}\n"],"mappings":"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","names":[]}
package/dist/index.cjs CHANGED
@@ -342,6 +342,7 @@ __export(index_exports, {
342
342
  });
343
343
  module.exports = __toCommonJS(index_exports);
344
344
  var import_processor_provider2 = require("@mastra/core/processor-provider");
345
+ var import_tool_provider2 = require("@mastra/core/tool-provider");
345
346
 
346
347
  // src/namespaces/base.ts
347
348
  var EditorNamespace = class {
@@ -468,6 +469,7 @@ var import_agent = require("@mastra/core/agent");
468
469
  var import_workspace = require("@mastra/core/workspace");
469
470
  var import_schema_compat = require("@mastra/schema-compat");
470
471
  var import_request_context = require("@mastra/core/request-context");
472
+ var import_tool_provider = require("@mastra/core/tool-provider");
471
473
 
472
474
  // src/rule-evaluator.ts
473
475
  function resolvePath(context, path2) {
@@ -1073,11 +1075,13 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1073
1075
  const hasStoredTools = storedConfig.tools != null;
1074
1076
  const hasStoredMCPClients = storedConfig.mcpClients != null;
1075
1077
  const hasStoredIntegrationTools = storedConfig.integrationTools != null;
1076
- if (hasStoredTools || hasStoredMCPClients || hasStoredIntegrationTools) {
1078
+ const hasStoredToolProviders = storedConfig.toolProviders != null && Object.keys(storedConfig.toolProviders).length > 0;
1079
+ if (hasStoredTools || hasStoredMCPClients || hasStoredIntegrationTools || hasStoredToolProviders) {
1077
1080
  const hasConditionalTools = this.isConditionalVariants(storedConfig.tools);
1078
1081
  const hasConditionalMCPClients = storedConfig.mcpClients != null && this.isConditionalVariants(storedConfig.mcpClients);
1079
1082
  const hasConditionalIntegrationTools = storedConfig.integrationTools != null && this.isConditionalVariants(storedConfig.integrationTools);
1080
- const isDynamicTools = hasConditionalTools || hasConditionalMCPClients || hasConditionalIntegrationTools || hasStoredIntegrationTools;
1083
+ const hasConditionalToolProviders = storedConfig.toolProviders != null && this.isConditionalVariants(storedConfig.toolProviders);
1084
+ const isDynamicTools = hasConditionalTools || hasConditionalMCPClients || hasConditionalIntegrationTools || hasStoredIntegrationTools || hasConditionalToolProviders || hasStoredToolProviders;
1081
1085
  if (isDynamicTools) {
1082
1086
  const originalTools = agent.listTools.bind(agent);
1083
1087
  const toolsFn = async ({ requestContext: requestContext2 }) => {
@@ -1101,7 +1105,20 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1101
1105
  resolvedIntegrationToolsConfig,
1102
1106
  requestContext2
1103
1107
  );
1104
- return { ...codeTools, ...registryTools, ...mcpTools, ...integrationTools };
1108
+ const resolvedToolProvidersConfig = hasConditionalToolProviders ? this.accumulateObjectVariants(
1109
+ storedConfig.toolProviders,
1110
+ ctx
1111
+ ) : storedConfig.toolProviders;
1112
+ const providerTools = await (0, import_tool_provider.resolveStoredToolProviders)(
1113
+ resolvedToolProvidersConfig,
1114
+ (providerId) => this.editor.getToolProviderOrThrow(providerId),
1115
+ {
1116
+ requestContext: ctx,
1117
+ authorId: storedConfig.authorId,
1118
+ logger: this.logger
1119
+ }
1120
+ );
1121
+ return { ...codeTools, ...registryTools, ...mcpTools, ...integrationTools, ...providerTools };
1105
1122
  };
1106
1123
  fork.__setTools(toolsFn);
1107
1124
  } else {
@@ -1173,6 +1190,8 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1173
1190
  const hasConditionalTools = storedAgent.tools != null && this.isConditionalVariants(storedAgent.tools);
1174
1191
  const hasConditionalMCPClients = storedAgent.mcpClients != null && this.isConditionalVariants(storedAgent.mcpClients);
1175
1192
  const hasConditionalIntegrationTools = storedAgent.integrationTools != null && this.isConditionalVariants(storedAgent.integrationTools);
1193
+ const hasToolProviders = storedAgent.toolProviders != null && Object.keys(storedAgent.toolProviders).length > 0;
1194
+ const hasConditionalToolProviders = storedAgent.toolProviders != null && this.isConditionalVariants(storedAgent.toolProviders);
1176
1195
  const hasConditionalWorkflows = storedAgent.workflows != null && this.isConditionalVariants(storedAgent.workflows);
1177
1196
  const hasConditionalAgents = storedAgent.agents != null && this.isConditionalVariants(storedAgent.agents);
1178
1197
  const hasConditionalMemory = storedAgent.memory != null && this.isConditionalVariants(storedAgent.memory);
@@ -1184,7 +1203,7 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1184
1203
  const hasConditionalWorkspace = storedAgent.workspace != null && this.isConditionalVariants(storedAgent.workspace);
1185
1204
  const hasConditionalBrowser = storedAgent.browser != null && this.isConditionalVariants(storedAgent.browser);
1186
1205
  const hasIntegrationTools = storedAgent.integrationTools != null;
1187
- const isDynamicTools = hasConditionalTools || hasConditionalMCPClients || hasConditionalIntegrationTools || hasIntegrationTools;
1206
+ const isDynamicTools = hasConditionalTools || hasConditionalMCPClients || hasConditionalIntegrationTools || hasIntegrationTools || hasConditionalToolProviders || hasToolProviders;
1188
1207
  let tools;
1189
1208
  if (isDynamicTools) {
1190
1209
  tools = async ({ requestContext }) => {
@@ -1207,7 +1226,17 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1207
1226
  resolvedIntegrationToolsConfig,
1208
1227
  requestContext
1209
1228
  );
1210
- return { ...registryTools, ...mcpTools, ...integrationTools };
1229
+ const resolvedToolProvidersConfig = hasConditionalToolProviders ? this.accumulateObjectVariants(storedAgent.toolProviders, ctx) : storedAgent.toolProviders;
1230
+ const providerTools = await (0, import_tool_provider.resolveStoredToolProviders)(
1231
+ resolvedToolProvidersConfig,
1232
+ (providerId) => this.editor.getToolProviderOrThrow(providerId),
1233
+ {
1234
+ requestContext: ctx,
1235
+ authorId: storedAgent.authorId,
1236
+ logger: this.logger
1237
+ }
1238
+ );
1239
+ return { ...registryTools, ...mcpTools, ...integrationTools, ...providerTools };
1211
1240
  };
1212
1241
  } else {
1213
1242
  const registryTools = this.resolveStoredTools(storedAgent.tools);
@@ -2716,9 +2745,7 @@ var MastraEditor = class {
2716
2745
  getToolProviderOrThrow(id) {
2717
2746
  const provider = this.__toolProviders[id];
2718
2747
  if (!provider) {
2719
- throw new Error(
2720
- `Unknown tool provider "${id}". Available: ${Object.keys(this.__toolProviders).join(", ") || "(none)"}`
2721
- );
2748
+ throw new import_tool_provider2.UnknownToolProviderError(id, Object.keys(this.__toolProviders));
2722
2749
  }
2723
2750
  return provider;
2724
2751
  }