@mastra/editor 0.13.8 → 0.13.9

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.
package/dist/composio.cjs CHANGED
@@ -1,375 +1,350 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/composio.ts
21
- var composio_exports = {};
22
- __export(composio_exports, {
23
- ComposioToolProvider: () => ComposioToolProvider
24
- });
25
- module.exports = __toCommonJS(composio_exports);
26
-
27
- // src/providers/composio.ts
28
- var import_tool_provider = require("@mastra/core/tool-provider");
29
- var import_request_context = require("@mastra/core/request-context");
30
- var import_core = require("@composio/core");
31
- var import_mastra = require("@composio/mastra");
32
- var COMPOSIO_PROVIDER_ID = "composio";
33
- var DEFAULT_INTERNAL_USER_ID = "default";
34
- var ComposioToolProvider = class extends import_tool_provider.BaseToolProvider {
35
- constructor(config) {
36
- super({
37
- allowedToolkits: config.allowedToolkits,
38
- allowedTools: config.allowedTools,
39
- defaultScope: config.defaultScope
40
- });
41
- this.info = {
42
- id: COMPOSIO_PROVIDER_ID,
43
- name: "Composio",
44
- description: "Access 10,000+ tools from 150+ apps via Composio"
45
- };
46
- this.capabilities = {
47
- multipleConnectionsPerToolkit: true,
48
- batchConnectionStatus: true,
49
- reauthorizeReusesConnectionId: true,
50
- supportsRevoke: true
51
- };
52
- this.rawClient = null;
53
- this.mastraClient = null;
54
- this.apiKey = config.apiKey;
55
- }
56
- // ── client cache ──────────────────────────────────────────────────────
57
- getRawClient() {
58
- if (!this.rawClient) {
59
- this.rawClient = new import_core.Composio({ apiKey: this.apiKey });
60
- }
61
- return this.rawClient;
62
- }
63
- getMastraClient() {
64
- if (!this.mastraClient) {
65
- this.mastraClient = new import_core.Composio({
66
- apiKey: this.apiKey,
67
- provider: new import_mastra.MastraProvider()
68
- });
69
- }
70
- return this.mastraClient;
71
- }
72
- // ── catalog (BaseToolProvider adds allowlist filter on top) ───────────
73
- async listAllToolkits() {
74
- const composio = this.getRawClient();
75
- const toolkits = await composio.toolkits.get({});
76
- return toolkits.map((tk) => ({
77
- slug: tk.slug,
78
- name: tk.name,
79
- description: tk.meta?.description,
80
- icon: tk.meta?.logo
81
- }));
82
- }
83
- async listAllTools(opts) {
84
- const composio = this.getRawClient();
85
- const limit = opts.perPage;
86
- const fallbackToolkits = this.allowedToolkits.length > 0 ? [...this.allowedToolkits] : void 0;
87
- const query = opts.toolkit ? { toolkits: [opts.toolkit], limit, search: opts.search } : fallbackToolkits ? { toolkits: fallbackToolkits, limit, search: opts.search } : opts.search ? { search: opts.search, limit } : { toolkits: [], limit };
88
- let rawTools = [];
89
- try {
90
- rawTools = await composio.tools.getRawComposioTools(query);
91
- } catch (err) {
92
- console.warn(
93
- `[ComposioToolProvider] listAllTools failed for query ${JSON.stringify(query)} \u2014 returning empty page`,
94
- err
95
- );
96
- }
97
- const data = rawTools.map((tool) => ({
98
- slug: tool.slug,
99
- name: tool.name ?? tool.slug,
100
- description: tool.description,
101
- toolkit: tool.toolkit?.slug ?? opts.toolkit ?? ""
102
- }));
103
- return {
104
- data,
105
- pagination: {
106
- page: opts.page ?? 1,
107
- perPage: limit,
108
- hasMore: limit !== void 0 && rawTools.length >= limit
109
- }
110
- };
111
- }
112
- // ── runtime ───────────────────────────────────────────────────────────
113
- async resolveToolsVNext(opts) {
114
- if (opts.toolSlugs.length === 0) return {};
115
- const internalUserId = opts.authorId && opts.authorId.length > 0 ? opts.authorId : resolveInternalUserId(opts.requestContext);
116
- const composio = this.getMastraClient();
117
- const modifiers = {
118
- // `connectedAccountId` is not threaded through Composio's `execute`
119
- // option bag in @composio/mastra; the only documented per-call hook
120
- // is `beforeExecute`, which receives the params object that flows
121
- // into the API call. Mutating `params.connectedAccountId` routes
122
- // the call to a specific account.
123
- beforeExecute: ({ params }) => {
124
- if (opts.scope !== "caller-supplied") {
125
- params.connectedAccountId = opts.connectionId;
126
- }
127
- return params;
128
- }
129
- };
130
- const mastraTools = await composio.tools.get(
131
- internalUserId,
132
- { tools: opts.toolSlugs },
133
- modifiers
134
- );
135
- const result = {};
136
- for (const [key, tool] of Object.entries(mastraTools ?? {})) {
137
- if (!tool) continue;
138
- const slug = tool.id ?? key;
139
- try {
140
- tool.outputSchema = void 0;
141
- } catch {
142
- }
143
- const descOverride = opts.toolMeta?.[slug]?.description;
144
- if (descOverride) {
145
- try {
146
- tool.description = descOverride;
147
- } catch {
148
- }
149
- }
150
- result[slug] = tool;
151
- }
152
- return result;
153
- }
154
- // ── auth surface ──────────────────────────────────────────────────────
155
- async authorize(opts) {
156
- const composio = this.getRawClient();
157
- const { id: authConfigId, authScheme } = await this.resolveAuthConfig(opts.toolkit);
158
- const internalUserId = opts.connectionId || DEFAULT_INTERNAL_USER_ID;
159
- const initiateConfig = opts.config && Object.keys(opts.config).length > 0 && authScheme ? { authScheme, val: opts.config } : void 0;
160
- const request = initiateConfig ? await composio.connectedAccounts.initiate(internalUserId, authConfigId, {
161
- allowMultiple: true,
162
- config: initiateConfig
163
- }) : await composio.connectedAccounts.link(internalUserId, authConfigId);
164
- if (!request.redirectUrl) {
165
- throw new Error(`[composio] authorize did not return a redirectUrl for toolkit "${opts.toolkit}"`);
166
- }
167
- return { url: request.redirectUrl, authId: request.id };
168
- }
169
- async listConnectionFields({ toolkit }) {
170
- const composio = this.getRawClient();
171
- const { authScheme } = await this.resolveAuthConfig(toolkit);
172
- if (!authScheme) {
173
- return [];
174
- }
175
- const fields = await composio.toolkits.getConnectedAccountInitiationFields(toolkit, authScheme, {
176
- requiredOnly: false
177
- });
178
- return fields.map((f) => ({
179
- name: f.name,
180
- displayName: f.displayName,
181
- description: f.description,
182
- type: coerceFieldType(f.type),
183
- required: f.required ?? false,
184
- default: f.default ?? void 0
185
- }));
186
- }
187
- async getAuthStatus(authId) {
188
- const composio = this.getRawClient();
189
- const account = await composio.connectedAccounts.get(authId);
190
- switch (account.status) {
191
- case "ACTIVE":
192
- return "completed";
193
- case "INITIALIZING":
194
- case "INITIATED":
195
- return "pending";
196
- case "FAILED":
197
- case "EXPIRED":
198
- case "INACTIVE":
199
- return "failed";
200
- default:
201
- return "pending";
202
- }
203
- }
204
- async getConnectionStatus(opts) {
205
- if (opts.items.length === 0) return {};
206
- const composio = this.getRawClient();
207
- const toolkitSlugs = Array.from(new Set(opts.items.map((i) => i.toolkit)));
208
- const list = await composio.connectedAccounts.list({
209
- toolkitSlugs
210
- });
211
- const liveById = /* @__PURE__ */ new Map();
212
- for (const item of list.items) {
213
- liveById.set(item.id, { status: item.status, isDisabled: item.isDisabled });
214
- }
215
- const result = {};
216
- for (const { connectionId } of opts.items) {
217
- const live = liveById.get(connectionId);
218
- result[connectionId] = { connected: live ? live.status === "ACTIVE" && !live.isDisabled : false };
219
- }
220
- return result;
221
- }
222
- async listConnections(opts) {
223
- const composio = this.getRawClient();
224
- const page = opts.page ?? 1;
225
- const perPage = clampLimit(opts.perPage);
226
- const userIds = resolveUserIds(opts);
227
- if (userIds && userIds.length === 0) {
228
- return { items: [], pagination: { page, perPage, hasMore: false } };
229
- }
230
- const list = await composio.connectedAccounts.list({
231
- toolkitSlugs: [opts.toolkit],
232
- ...userIds ? { userIds } : {},
233
- limit: perPage
234
- });
235
- const items = (list.items ?? []).map((account) => ({
236
- connectionId: account.id,
237
- status: mapComposioStatus(account.status, account.isDisabled),
238
- createdAt: account.createdAt,
239
- // `user_id` is preserved by the Composio SDK transform via spread but
240
- // isn't on the typed shape. Read it via a narrow cast.
241
- authorId: account.user_id
242
- }));
243
- const nextCursor = list.nextCursor ?? null;
244
- const hasMore = typeof nextCursor === "string" && nextCursor.length > 0;
245
- return { items, pagination: { page, perPage, hasMore } };
246
- }
247
- /**
248
- * Revoke a Composio connected account via
249
- * `DELETE /api/v3/connected_accounts/:nanoid`. Composio performs a soft
250
- * delete and responds with `{ success: boolean }`.
251
- *
252
- * Treats a 404 (account already deleted or never existed) as success so
253
- * the caller can drop its local pin without an error path. A `success:
254
- * false` response means the provider refused the delete and is surfaced
255
- * as an error so the caller does not delete its local row.
256
- */
257
- async revokeConnection(connectionId) {
258
- const composio = this.getRawClient();
259
- try {
260
- const res = await composio.connectedAccounts.delete(connectionId);
261
- if (res && res.success === false) {
262
- throw new Error(`Composio refused to delete connected account ${connectionId} (success=false)`);
263
- }
264
- } catch (err) {
265
- if (isNotFoundError(err)) return;
266
- throw err;
267
- }
268
- }
269
- async getHealth() {
270
- try {
271
- const composio = this.getRawClient();
272
- await composio.toolkits.get({ limit: 1 });
273
- return { ok: true };
274
- } catch (err) {
275
- return {
276
- ok: false,
277
- message: err instanceof Error ? err.message : "Composio SDK reachability check failed"
278
- };
279
- }
280
- }
281
- // ── helpers ───────────────────────────────────────────────────────────
282
- /**
283
- * Resolve the single ENABLED auth config for `toolkit`. Throws if zero
284
- * or multiple configs match — the admin must enable exactly one in the
285
- * Composio dashboard before agents can connect.
286
- */
287
- async resolveAuthConfig(toolkit) {
288
- const composio = this.getRawClient();
289
- const response = await composio.authConfigs.list({ toolkit });
290
- const enabled = response.items.filter((item) => item.status === "ENABLED");
291
- if (enabled.length === 0) {
292
- throw new Error(
293
- `[composio] No ENABLED auth config for toolkit "${toolkit}". Enable one in the Composio dashboard.`
294
- );
295
- }
296
- if (enabled.length > 1) {
297
- const ids = enabled.map((item) => item.id).join(", ");
298
- throw new Error(
299
- `[composio] Multiple ENABLED auth configs for toolkit "${toolkit}" (${ids}). Keep exactly one enabled.`
300
- );
301
- }
302
- return { id: enabled[0].id, authScheme: enabled[0].authScheme };
303
- }
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _mastra_core_tool_provider = require("@mastra/core/tool-provider");
3
+ let _mastra_core_request_context = require("@mastra/core/request-context");
4
+ let _composio_core = require("@composio/core");
5
+ let _composio_mastra = require("@composio/mastra");
6
+ //#region src/providers/composio.ts
7
+ const COMPOSIO_PROVIDER_ID = "composio";
8
+ const DEFAULT_INTERNAL_USER_ID = "default";
9
+ /**
10
+ * Composio implementation of the {@link BaseToolProvider} contract.
11
+ *
12
+ * Discovery (`listAllToolkits`, `listAllTools`) uses the raw Composio
13
+ * client. Runtime (`resolveToolsVNext`) uses {@link MastraProvider} so resolved
14
+ * tools are already in `createTool()` shape; each tool gets a
15
+ * `beforeExecute` modifier that injects
16
+ * `connectedAccountId = connectionId`, and `outputSchema` is cleared
17
+ * because Composio returns union schemas that Mastra's runtime rejects.
18
+ *
19
+ * Allowlist filtering is layered by {@link BaseToolProvider}; this class
20
+ * never reads `allowedToolkits` / `allowedTools` directly.
21
+ */
22
+ var ComposioToolProvider = class extends _mastra_core_tool_provider.BaseToolProvider {
23
+ constructor(config) {
24
+ super({
25
+ allowedToolkits: config.allowedToolkits,
26
+ allowedTools: config.allowedTools,
27
+ defaultScope: config.defaultScope
28
+ });
29
+ this.info = {
30
+ id: COMPOSIO_PROVIDER_ID,
31
+ name: "Composio",
32
+ description: "Access 10,000+ tools from 150+ apps via Composio"
33
+ };
34
+ this.capabilities = {
35
+ multipleConnectionsPerToolkit: true,
36
+ batchConnectionStatus: true,
37
+ reauthorizeReusesConnectionId: true,
38
+ supportsRevoke: true
39
+ };
40
+ this.rawClient = null;
41
+ this.mastraClient = null;
42
+ this.apiKey = config.apiKey;
43
+ }
44
+ getRawClient() {
45
+ if (!this.rawClient) this.rawClient = new _composio_core.Composio({ apiKey: this.apiKey });
46
+ return this.rawClient;
47
+ }
48
+ getMastraClient() {
49
+ if (!this.mastraClient) this.mastraClient = new _composio_core.Composio({
50
+ apiKey: this.apiKey,
51
+ provider: new _composio_mastra.MastraProvider()
52
+ });
53
+ return this.mastraClient;
54
+ }
55
+ async listAllToolkits() {
56
+ return (await this.getRawClient().toolkits.get({})).map((tk) => ({
57
+ slug: tk.slug,
58
+ name: tk.name,
59
+ description: tk.meta?.description,
60
+ icon: tk.meta?.logo
61
+ }));
62
+ }
63
+ async listAllTools(opts) {
64
+ const composio = this.getRawClient();
65
+ const limit = opts.perPage;
66
+ const fallbackToolkits = this.allowedToolkits.length > 0 ? [...this.allowedToolkits] : void 0;
67
+ const query = opts.toolkit ? {
68
+ toolkits: [opts.toolkit],
69
+ limit,
70
+ search: opts.search
71
+ } : fallbackToolkits ? {
72
+ toolkits: fallbackToolkits,
73
+ limit,
74
+ search: opts.search
75
+ } : opts.search ? {
76
+ search: opts.search,
77
+ limit
78
+ } : {
79
+ toolkits: [],
80
+ limit
81
+ };
82
+ let rawTools = [];
83
+ try {
84
+ rawTools = await composio.tools.getRawComposioTools(query);
85
+ } catch (err) {
86
+ console.warn(`[ComposioToolProvider] listAllTools failed for query ${JSON.stringify(query)} returning empty page`, err);
87
+ }
88
+ return {
89
+ data: rawTools.map((tool) => ({
90
+ slug: tool.slug,
91
+ name: tool.name ?? tool.slug,
92
+ description: tool.description,
93
+ toolkit: tool.toolkit?.slug ?? opts.toolkit ?? ""
94
+ })),
95
+ pagination: {
96
+ page: opts.page ?? 1,
97
+ perPage: limit,
98
+ hasMore: limit !== void 0 && rawTools.length >= limit
99
+ }
100
+ };
101
+ }
102
+ async resolveToolsVNext(opts) {
103
+ if (opts.toolSlugs.length === 0) return {};
104
+ const internalUserId = opts.authorId && opts.authorId.length > 0 ? opts.authorId : resolveInternalUserId(opts.requestContext);
105
+ const mastraTools = await this.getMastraClient().tools.get(internalUserId, { tools: opts.toolSlugs }, { beforeExecute: ({ params }) => {
106
+ if (opts.scope !== "caller-supplied") params.connectedAccountId = opts.connectionId;
107
+ return params;
108
+ } });
109
+ const result = {};
110
+ for (const [key, tool] of Object.entries(mastraTools ?? {})) {
111
+ if (!tool) continue;
112
+ const slug = tool.id ?? key;
113
+ try {
114
+ tool.outputSchema = void 0;
115
+ } catch {}
116
+ const descOverride = opts.toolMeta?.[slug]?.description;
117
+ if (descOverride) try {
118
+ tool.description = descOverride;
119
+ } catch {}
120
+ result[slug] = tool;
121
+ }
122
+ return result;
123
+ }
124
+ async authorize(opts) {
125
+ const composio = this.getRawClient();
126
+ const { id: authConfigId, authScheme } = await this.resolveAuthConfig(opts.toolkit);
127
+ const internalUserId = opts.connectionId || DEFAULT_INTERNAL_USER_ID;
128
+ const initiateConfig = opts.config && Object.keys(opts.config).length > 0 && authScheme ? {
129
+ authScheme,
130
+ val: opts.config
131
+ } : void 0;
132
+ const request = initiateConfig ? await composio.connectedAccounts.initiate(internalUserId, authConfigId, {
133
+ allowMultiple: true,
134
+ config: initiateConfig
135
+ }) : await composio.connectedAccounts.link(internalUserId, authConfigId);
136
+ if (!request.redirectUrl) throw new Error(`[composio] authorize did not return a redirectUrl for toolkit "${opts.toolkit}"`);
137
+ return {
138
+ url: request.redirectUrl,
139
+ authId: request.id
140
+ };
141
+ }
142
+ async listConnectionFields({ toolkit }) {
143
+ const composio = this.getRawClient();
144
+ const { authScheme } = await this.resolveAuthConfig(toolkit);
145
+ if (!authScheme) return [];
146
+ return (await composio.toolkits.getConnectedAccountInitiationFields(toolkit, authScheme, { requiredOnly: false })).map((f) => ({
147
+ name: f.name,
148
+ displayName: f.displayName,
149
+ description: f.description,
150
+ type: coerceFieldType(f.type),
151
+ required: f.required ?? false,
152
+ default: f.default ?? void 0
153
+ }));
154
+ }
155
+ async getAuthStatus(authId) {
156
+ switch ((await this.getRawClient().connectedAccounts.get(authId)).status) {
157
+ case "ACTIVE": return "completed";
158
+ case "INITIALIZING":
159
+ case "INITIATED": return "pending";
160
+ case "FAILED":
161
+ case "EXPIRED":
162
+ case "INACTIVE": return "failed";
163
+ default: return "pending";
164
+ }
165
+ }
166
+ async getConnectionStatus(opts) {
167
+ if (opts.items.length === 0) return {};
168
+ const composio = this.getRawClient();
169
+ const toolkitSlugs = Array.from(new Set(opts.items.map((i) => i.toolkit)));
170
+ const list = await composio.connectedAccounts.list({ toolkitSlugs });
171
+ const liveById = /* @__PURE__ */ new Map();
172
+ for (const item of list.items) liveById.set(item.id, {
173
+ status: item.status,
174
+ isDisabled: item.isDisabled
175
+ });
176
+ const result = {};
177
+ for (const { connectionId } of opts.items) {
178
+ const live = liveById.get(connectionId);
179
+ result[connectionId] = { connected: live ? live.status === "ACTIVE" && !live.isDisabled : false };
180
+ }
181
+ return result;
182
+ }
183
+ async listConnections(opts) {
184
+ const composio = this.getRawClient();
185
+ const page = opts.page ?? 1;
186
+ const perPage = clampLimit(opts.perPage);
187
+ const userIds = resolveUserIds(opts);
188
+ if (userIds && userIds.length === 0) return {
189
+ items: [],
190
+ pagination: {
191
+ page,
192
+ perPage,
193
+ hasMore: false
194
+ }
195
+ };
196
+ const list = await composio.connectedAccounts.list({
197
+ toolkitSlugs: [opts.toolkit],
198
+ ...userIds ? { userIds } : {},
199
+ limit: perPage
200
+ });
201
+ const items = (list.items ?? []).map((account) => ({
202
+ connectionId: account.id,
203
+ status: mapComposioStatus(account.status, account.isDisabled),
204
+ createdAt: account.createdAt,
205
+ authorId: account.user_id
206
+ }));
207
+ const nextCursor = list.nextCursor ?? null;
208
+ return {
209
+ items,
210
+ pagination: {
211
+ page,
212
+ perPage,
213
+ hasMore: typeof nextCursor === "string" && nextCursor.length > 0
214
+ }
215
+ };
216
+ }
217
+ /**
218
+ * Revoke a Composio connected account via
219
+ * `DELETE /api/v3/connected_accounts/:nanoid`. Composio performs a soft
220
+ * delete and responds with `{ success: boolean }`.
221
+ *
222
+ * Treats a 404 (account already deleted or never existed) as success so
223
+ * the caller can drop its local pin without an error path. A `success:
224
+ * false` response means the provider refused the delete and is surfaced
225
+ * as an error so the caller does not delete its local row.
226
+ */
227
+ async revokeConnection(connectionId) {
228
+ const composio = this.getRawClient();
229
+ try {
230
+ const res = await composio.connectedAccounts.delete(connectionId);
231
+ if (res && res.success === false) throw new Error(`Composio refused to delete connected account ${connectionId} (success=false)`);
232
+ } catch (err) {
233
+ if (isNotFoundError(err)) return;
234
+ throw err;
235
+ }
236
+ }
237
+ async getHealth() {
238
+ try {
239
+ await this.getRawClient().toolkits.get({ limit: 1 });
240
+ return { ok: true };
241
+ } catch (err) {
242
+ return {
243
+ ok: false,
244
+ message: err instanceof Error ? err.message : "Composio SDK reachability check failed"
245
+ };
246
+ }
247
+ }
248
+ /**
249
+ * Resolve the single ENABLED auth config for `toolkit`. Throws if zero
250
+ * or multiple configs match the admin must enable exactly one in the
251
+ * Composio dashboard before agents can connect.
252
+ */
253
+ async resolveAuthConfig(toolkit) {
254
+ const enabled = (await this.getRawClient().authConfigs.list({ toolkit })).items.filter((item) => item.status === "ENABLED");
255
+ if (enabled.length === 0) throw new Error(`[composio] No ENABLED auth config for toolkit "${toolkit}". Enable one in the Composio dashboard.`);
256
+ if (enabled.length > 1) {
257
+ const ids = enabled.map((item) => item.id).join(", ");
258
+ throw new Error(`[composio] Multiple ENABLED auth configs for toolkit "${toolkit}" (${ids}). Keep exactly one enabled.`);
259
+ }
260
+ return {
261
+ id: enabled[0].id,
262
+ authScheme: enabled[0].authScheme
263
+ };
264
+ }
304
265
  };
266
+ /**
267
+ * Best-effort 404 detection across the various error shapes the Composio
268
+ * SDK surfaces (typed error with `statusCode`, HTTP-like error with
269
+ * `status`, or a plain message containing "404" / "not found").
270
+ */
305
271
  function isNotFoundError(err) {
306
- if (!err || typeof err !== "object") return false;
307
- const e = err;
308
- if (e.statusCode === 404 || e.status === 404) return true;
309
- const msg = typeof e.message === "string" ? e.message.toLowerCase() : "";
310
- return msg.includes("not found") || msg.includes("404");
272
+ if (!err || typeof err !== "object") return false;
273
+ const e = err;
274
+ if (e.statusCode === 404 || e.status === 404) return true;
275
+ const msg = typeof e.message === "string" ? e.message.toLowerCase() : "";
276
+ return msg.includes("not found") || msg.includes("404");
311
277
  }
278
+ /**
279
+ * Composio reports a free-form `type` string. Map common values to our
280
+ * generic ConnectionField type vocabulary; everything else falls back to
281
+ * `'string'`.
282
+ */
312
283
  function coerceFieldType(type) {
313
- switch (type.toLowerCase()) {
314
- case "number":
315
- case "integer":
316
- case "int":
317
- case "float":
318
- return "number";
319
- case "bool":
320
- case "boolean":
321
- return "boolean";
322
- default:
323
- return "string";
324
- }
284
+ switch (type.toLowerCase()) {
285
+ case "number":
286
+ case "integer":
287
+ case "int":
288
+ case "float": return "number";
289
+ case "bool":
290
+ case "boolean": return "boolean";
291
+ default: return "string";
292
+ }
325
293
  }
294
+ /**
295
+ * Map Composio account status + `isDisabled` to the {@link ExistingConnection}
296
+ * status vocabulary surfaced to the picker UI.
297
+ */
326
298
  function mapComposioStatus(status, isDisabled) {
327
- if (isDisabled) return "inactive";
328
- switch (status) {
329
- case "ACTIVE":
330
- return "active";
331
- case "INITIALIZING":
332
- case "INITIATED":
333
- return "pending";
334
- case "FAILED":
335
- case "EXPIRED":
336
- return "failed";
337
- case "INACTIVE":
338
- return "inactive";
339
- default:
340
- return "pending";
341
- }
299
+ if (isDisabled) return "inactive";
300
+ switch (status) {
301
+ case "ACTIVE": return "active";
302
+ case "INITIALIZING":
303
+ case "INITIATED": return "pending";
304
+ case "FAILED":
305
+ case "EXPIRED": return "failed";
306
+ case "INACTIVE": return "inactive";
307
+ default: return "pending";
308
+ }
342
309
  }
343
- var MASTRA_USER_KEY = "mastra__user";
310
+ const MASTRA_USER_KEY = "mastra__user";
311
+ /**
312
+ * Read the internal user id (Composio `userId`) from per-request context.
313
+ *
314
+ * The runtime fan-out is responsible for stamping the agent's resolved
315
+ * author id (or `'default'`) into `requestContext` under
316
+ * {@link MASTRA_RESOURCE_ID_KEY}.
317
+ */
344
318
  function resolveInternalUserId(requestContext) {
345
- const resourceId = requestContext?.[import_request_context.MASTRA_RESOURCE_ID_KEY];
346
- if (typeof resourceId === "string" && resourceId.length > 0) {
347
- return resourceId;
348
- }
349
- const user = requestContext?.[MASTRA_USER_KEY];
350
- if (user && typeof user === "object" && "id" in user) {
351
- const id = user.id;
352
- if (typeof id === "string" && id.length > 0) {
353
- return id;
354
- }
355
- }
356
- return DEFAULT_INTERNAL_USER_ID;
319
+ const resourceId = requestContext?.[_mastra_core_request_context.MASTRA_RESOURCE_ID_KEY];
320
+ if (typeof resourceId === "string" && resourceId.length > 0) return resourceId;
321
+ const user = requestContext?.[MASTRA_USER_KEY];
322
+ if (user && typeof user === "object" && "id" in user) {
323
+ const id = user.id;
324
+ if (typeof id === "string" && id.length > 0) return id;
325
+ }
326
+ return DEFAULT_INTERNAL_USER_ID;
357
327
  }
328
+ /**
329
+ * Resolve `userIds[]` from `listConnections` opts.
330
+ *
331
+ * - If `userIds` is provided, use it as-is (including empty array, which
332
+ * means "no buckets to list against").
333
+ * - If `userId` is provided, normalize to `[userId]`.
334
+ * - Otherwise fall back to the default internal user id (single-bucket).
335
+ */
358
336
  function resolveUserIds(opts) {
359
- if (Array.isArray(opts.userIds)) return opts.userIds;
360
- if (typeof opts.userId === "string" && opts.userId.length > 0) return [opts.userId];
361
- return [DEFAULT_INTERNAL_USER_ID];
337
+ if (Array.isArray(opts.userIds)) return opts.userIds;
338
+ if (typeof opts.userId === "string" && opts.userId.length > 0) return [opts.userId];
339
+ return [DEFAULT_INTERNAL_USER_ID];
362
340
  }
363
- var DEFAULT_LIMIT = 50;
364
- var MAX_LIMIT = 200;
341
+ const DEFAULT_LIMIT = 50;
342
+ const MAX_LIMIT = 200;
365
343
  function clampLimit(limit) {
366
- if (typeof limit !== "number" || !Number.isFinite(limit) || limit <= 0) {
367
- return DEFAULT_LIMIT;
368
- }
369
- return Math.min(Math.floor(limit), MAX_LIMIT);
344
+ if (typeof limit !== "number" || !Number.isFinite(limit) || limit <= 0) return DEFAULT_LIMIT;
345
+ return Math.min(Math.floor(limit), MAX_LIMIT);
370
346
  }
371
- // Annotate the CommonJS export names for ESM import in node:
372
- 0 && (module.exports = {
373
- ComposioToolProvider
374
- });
347
+ //#endregion
348
+ exports.ComposioToolProvider = ComposioToolProvider;
349
+
375
350
  //# sourceMappingURL=composio.cjs.map