@tangle-network/agent-integrations 0.25.4 → 0.25.5

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,7 +1,3 @@
1
- import {
2
- buildIntegrationToolCatalog,
3
- parseIntegrationToolName
4
- } from "./chunk-6KWCC42J.js";
5
1
  import {
6
2
  integrationSpecToConnector,
7
3
  listIntegrationSpecs
@@ -1222,6 +1218,9 @@ async function receiveIntegrationWebhook(input) {
1222
1218
  if (!input.adapter.handleInboundEvent) {
1223
1219
  return { status: 405, body: { ok: false, error: "Connector does not support inbound webhooks." }, received: [], duplicates: [] };
1224
1220
  }
1221
+ if (!input.adapter.verifySignature && !input.allowUnsignedWebhook) {
1222
+ return { status: 401, body: { ok: false, error: "Webhook signature verification is required." }, received: [], duplicates: [] };
1223
+ }
1225
1224
  const signature = input.adapter.verifySignature?.({
1226
1225
  rawBody: input.rawBody,
1227
1226
  headers: input.headers,
@@ -1305,16 +1304,28 @@ var DefaultIntegrationActionGuard = class {
1305
1304
  idempotency;
1306
1305
  audit;
1307
1306
  rateLimiter;
1307
+ requireIdempotencyForMutations;
1308
1308
  now;
1309
1309
  constructor(options = {}) {
1310
1310
  this.idempotency = options.idempotency;
1311
1311
  this.audit = options.audit;
1312
1312
  this.rateLimiter = options.rateLimiter;
1313
+ this.requireIdempotencyForMutations = options.requireIdempotencyForMutations ?? false;
1313
1314
  this.now = options.now ?? (() => /* @__PURE__ */ new Date());
1314
1315
  }
1315
1316
  async invokeAction(ctx, proceed) {
1316
1317
  const idempotencyKey = ctx.request.idempotencyKey;
1317
1318
  const requestHash = hashRequest(ctx);
1319
+ if (this.requireIdempotencyForMutations && ctx.action?.risk !== "read" && !idempotencyKey) {
1320
+ return {
1321
+ ok: false,
1322
+ action: ctx.request.action,
1323
+ output: {
1324
+ idempotencyRequired: true,
1325
+ message: "State-changing integration actions require an idempotency key."
1326
+ }
1327
+ };
1328
+ }
1318
1329
  if (idempotencyKey && this.idempotency) {
1319
1330
  const existing = await this.idempotency.get(idempotencyKey);
1320
1331
  if (existing) {
@@ -2934,6 +2945,260 @@ async function checkActivepiecesPublicCatalog(input) {
2934
2945
  }
2935
2946
  }
2936
2947
 
2948
+ // src/runtime.ts
2949
+ var InMemoryIntegrationGrantStore = class {
2950
+ grants = /* @__PURE__ */ new Map();
2951
+ get(grantId) {
2952
+ return this.grants.get(grantId);
2953
+ }
2954
+ put(grant) {
2955
+ this.grants.set(grant.id, grant);
2956
+ }
2957
+ listByManifest(manifestId, grantee) {
2958
+ return [...this.grants.values()].filter(
2959
+ (grant) => grant.manifestId === manifestId && (!grantee || sameActor(grant.grantee, grantee))
2960
+ );
2961
+ }
2962
+ listByGrantee(grantee) {
2963
+ return [...this.grants.values()].filter((grant) => sameActor(grant.grantee, grantee));
2964
+ }
2965
+ listByIds(grantIds) {
2966
+ const wanted = new Set(grantIds);
2967
+ return [...this.grants.values()].filter((grant) => wanted.has(grant.id));
2968
+ }
2969
+ delete(grantId) {
2970
+ this.grants.delete(grantId);
2971
+ }
2972
+ };
2973
+ var IntegrationRuntime = class {
2974
+ hub;
2975
+ grants;
2976
+ now;
2977
+ constructor(options) {
2978
+ this.hub = options.hub;
2979
+ this.grants = options.grants ?? new InMemoryIntegrationGrantStore();
2980
+ this.now = options.now ?? (() => /* @__PURE__ */ new Date());
2981
+ }
2982
+ async registry() {
2983
+ return this.hub.listRegistry();
2984
+ }
2985
+ async resolveManifest(manifest, owner) {
2986
+ const registry = await this.registry();
2987
+ const connections = await this.hub.listConnections(owner);
2988
+ const resolutions = manifest.requirements.map(
2989
+ (requirement) => resolveRequirement(requirement, owner, registry, connections)
2990
+ );
2991
+ return {
2992
+ manifest,
2993
+ owner,
2994
+ ready: resolutions.filter((resolution) => resolution.status === "ready"),
2995
+ missing: resolutions.filter((resolution) => resolution.status !== "ready" && !resolution.requirement.optional),
2996
+ optionalMissing: resolutions.filter((resolution) => resolution.status !== "ready" && resolution.requirement.optional === true)
2997
+ };
2998
+ }
2999
+ async createGrants(input) {
3000
+ const resolution = await this.resolveManifest(input.manifest, input.owner);
3001
+ if (resolution.missing.length > 0) {
3002
+ throw new Error(`Cannot create integration grants; missing requirements: ${resolution.missing.map((r) => r.requirement.id).join(", ")}`);
3003
+ }
3004
+ const now = this.now().toISOString();
3005
+ const grants = resolution.ready.map((ready) => ({
3006
+ id: `grant_${input.manifest.id}_${ready.requirement.id}_${ready.connection.id}`,
3007
+ manifestId: input.manifest.id,
3008
+ requirementId: ready.requirement.id,
3009
+ owner: input.owner,
3010
+ grantee: input.grantee,
3011
+ connectionId: ready.connection.id,
3012
+ connectorId: ready.connector.id,
3013
+ scopes: requiredScopes(ready.requirement, ready.connector),
3014
+ allowedActions: requiredActions(ready.requirement, ready.connector),
3015
+ allowedTriggers: requiredTriggers(ready.requirement, ready.connector),
3016
+ status: "active",
3017
+ createdAt: now,
3018
+ updatedAt: now,
3019
+ metadata: input.metadata
3020
+ }));
3021
+ for (const grant of grants) await this.grants.put(grant);
3022
+ return grants;
3023
+ }
3024
+ async buildSandboxBundle(input) {
3025
+ const grants = await this.resolveBundleGrants(input);
3026
+ const registry = await this.registry();
3027
+ const bindings = [];
3028
+ const connectors = [];
3029
+ let expiresAt = "";
3030
+ for (const grant of grants) {
3031
+ const connection = await this.hub.getConnection(grant.connectionId);
3032
+ if (!connection) {
3033
+ throw new Error(`Cannot build integration bundle; connection ${grant.connectionId} not found.`);
3034
+ }
3035
+ if (!sameActor(connection.owner, input.owner)) {
3036
+ throw new Error(`Cannot build integration bundle; connection ${connection.id} belongs to a different owner.`);
3037
+ }
3038
+ if (connection.status !== "active") {
3039
+ throw new Error(`Cannot build integration bundle; connection ${connection.id} is ${connection.status}.`);
3040
+ }
3041
+ const entry = registry.byId.get(grant.connectorId);
3042
+ if (!entry) continue;
3043
+ const connector = {
3044
+ ...entry.connector,
3045
+ actions: entry.connector.actions.filter((action) => grant.allowedActions.includes(action.id)),
3046
+ triggers: entry.connector.triggers?.filter((trigger2) => grant.allowedTriggers.includes(trigger2.id)),
3047
+ scopes: entry.connector.scopes.filter((scope) => grant.scopes.includes(scope))
3048
+ };
3049
+ const capability = await this.hub.issueCapability({
3050
+ subject: input.subject,
3051
+ connectionId: grant.connectionId,
3052
+ scopes: grant.scopes,
3053
+ allowedActions: grant.allowedActions,
3054
+ ttlMs: input.ttlMs,
3055
+ metadata: {
3056
+ manifestId: grant.manifestId,
3057
+ grantId: grant.id,
3058
+ requirementId: grant.requirementId
3059
+ }
3060
+ });
3061
+ bindings.push({
3062
+ requirementId: grant.requirementId,
3063
+ connectorId: grant.connectorId,
3064
+ connectionId: grant.connectionId,
3065
+ grantId: grant.id,
3066
+ scopes: grant.scopes,
3067
+ allowedActions: grant.allowedActions,
3068
+ allowedTriggers: grant.allowedTriggers,
3069
+ capability
3070
+ });
3071
+ connectors.push(connector);
3072
+ expiresAt = capability.capability.expiresAt;
3073
+ }
3074
+ return {
3075
+ manifestId: input.manifestId ?? grants[0]?.manifestId ?? "explicit-grants",
3076
+ subject: input.subject,
3077
+ capabilities: bindings,
3078
+ connectors,
3079
+ tools: buildIntegrationToolCatalog(connectors),
3080
+ expiresAt
3081
+ };
3082
+ }
3083
+ async resolveBundleGrants(input) {
3084
+ if (input.grantIds?.length) {
3085
+ const uniqueGrantIds = unique5(input.grantIds);
3086
+ const grants = this.grants.listByIds ? await this.grants.listByIds(uniqueGrantIds) : await Promise.all(uniqueGrantIds.map((grantId) => this.grants.get(grantId)));
3087
+ const found = grants.filter((grant) => Boolean(grant));
3088
+ const foundIds = new Set(found.map((grant) => grant.id));
3089
+ const missing2 = uniqueGrantIds.filter((grantId) => !foundIds.has(grantId));
3090
+ if (missing2.length > 0) {
3091
+ throw new Error(`Cannot build integration bundle; unknown grant id(s): ${missing2.join(", ")}`);
3092
+ }
3093
+ const badOwner = found.find((grant) => !sameActor(grant.owner, input.owner));
3094
+ if (badOwner) {
3095
+ throw new Error(`Cannot build integration bundle; grant ${badOwner.id} belongs to a different owner.`);
3096
+ }
3097
+ const badGrantee = input.grantee ? found.find((grant) => !sameActor(grant.grantee, input.grantee)) : void 0;
3098
+ if (badGrantee) {
3099
+ throw new Error(`Cannot build integration bundle; grant ${badGrantee.id} belongs to a different grantee.`);
3100
+ }
3101
+ const badManifest = input.manifestId ? found.find((grant) => grant.manifestId !== input.manifestId) : void 0;
3102
+ if (badManifest) {
3103
+ throw new Error(`Cannot build integration bundle; grant ${badManifest.id} is not for manifest ${input.manifestId}.`);
3104
+ }
3105
+ const inactive = found.find((grant) => grant.status !== "active");
3106
+ if (inactive) {
3107
+ throw new Error(`Cannot build integration bundle; grant ${inactive.id} is ${inactive.status}.`);
3108
+ }
3109
+ return found;
3110
+ }
3111
+ if (!input.manifestId) {
3112
+ throw new Error("Cannot build integration bundle; manifestId or grantIds is required.");
3113
+ }
3114
+ return (await this.grants.listByManifest(input.manifestId, input.grantee)).filter((grant) => sameActor(grant.owner, input.owner)).filter((grant) => grant.status === "active");
3115
+ }
3116
+ };
3117
+ function createIntegrationRuntime(options) {
3118
+ return new IntegrationRuntime(options);
3119
+ }
3120
+ function resolveRequirement(requirement, owner, registry, connections) {
3121
+ const entry = registry.byId.get(requirement.connectorId);
3122
+ if (!entry) {
3123
+ return missing(requirement, "unknown_connector", `Unknown connector ${requirement.connectorId}.`);
3124
+ }
3125
+ const connector = entry.connector;
3126
+ if (connector.actions.length === 0 && (connector.triggers?.length ?? 0) === 0) {
3127
+ return missing(requirement, "not_executable", `${connector.title} is catalog-only and cannot be invoked yet.`, connector, entry);
3128
+ }
3129
+ const scopes = requiredScopes(requirement, connector);
3130
+ const actions = requiredActions(requirement, connector);
3131
+ const triggers = requiredTriggers(requirement, connector);
3132
+ const connection = connections.find(
3133
+ (candidate) => sameActor(candidate.owner, owner) && candidate.status === "active" && (candidate.connectorId === connector.id || entry.aliases.includes(candidate.connectorId)) && scopes.every((scope) => candidate.grantedScopes.includes(scope))
3134
+ );
3135
+ if (!connection) {
3136
+ return {
3137
+ requirement,
3138
+ status: "missing_connection",
3139
+ connector,
3140
+ registryEntry: entry,
3141
+ missingScopes: scopes,
3142
+ missingActions: actions,
3143
+ missingTriggers: triggers,
3144
+ message: `${connector.title} needs an active user connection with the required scopes.`
3145
+ };
3146
+ }
3147
+ return {
3148
+ requirement,
3149
+ status: "ready",
3150
+ connector,
3151
+ registryEntry: entry,
3152
+ connection,
3153
+ missingScopes: [],
3154
+ missingActions: [],
3155
+ missingTriggers: [],
3156
+ message: `${connector.title} is ready.`
3157
+ };
3158
+ }
3159
+ function missing(requirement, status, message, connector, registryEntry2) {
3160
+ return {
3161
+ requirement,
3162
+ status,
3163
+ connector,
3164
+ registryEntry: registryEntry2,
3165
+ missingScopes: [],
3166
+ missingActions: [],
3167
+ missingTriggers: [],
3168
+ message
3169
+ };
3170
+ }
3171
+ function requiredActions(requirement, connector) {
3172
+ if (requirement.mode === "trigger") return [];
3173
+ if (requirement.requiredActions?.length) return unique5(requirement.requiredActions);
3174
+ const actions = connector.actions.filter((action) => {
3175
+ if (requirement.mode === "read") return action.risk === "read";
3176
+ if (requirement.mode === "write") return action.risk === "write";
3177
+ return false;
3178
+ });
3179
+ return unique5(actions.map((action) => action.id));
3180
+ }
3181
+ function requiredTriggers(requirement, connector) {
3182
+ if (requirement.requiredTriggers?.length) return unique5(requirement.requiredTriggers);
3183
+ if (requirement.mode !== "trigger") return [];
3184
+ return unique5((connector.triggers ?? []).map((trigger2) => trigger2.id));
3185
+ }
3186
+ function requiredScopes(requirement, connector) {
3187
+ if (requirement.requiredScopes?.length) return unique5(requirement.requiredScopes);
3188
+ const actionIds = new Set(requiredActions(requirement, connector));
3189
+ const triggerIds = new Set(requiredTriggers(requirement, connector));
3190
+ return unique5([
3191
+ ...connector.actions.filter((action) => actionIds.has(action.id)).flatMap((action) => action.requiredScopes),
3192
+ ...(connector.triggers ?? []).filter((trigger2) => triggerIds.has(trigger2.id)).flatMap((trigger2) => trigger2.requiredScopes)
3193
+ ]);
3194
+ }
3195
+ function sameActor(a, b) {
3196
+ return a.type === b.type && a.id === b.id;
3197
+ }
3198
+ function unique5(values) {
3199
+ return [...new Set(values)];
3200
+ }
3201
+
2937
3202
  // src/workflow.ts
2938
3203
  var InMemoryIntegrationWorkflowStore = class {
2939
3204
  workflows = /* @__PURE__ */ new Map();
@@ -2950,7 +3215,7 @@ var InMemoryIntegrationWorkflowStore = class {
2950
3215
  return [...this.workflows.values()].filter((workflow) => workflow.workflowId === workflowId);
2951
3216
  }
2952
3217
  listByOwner(owner) {
2953
- return [...this.workflows.values()].filter((workflow) => sameActor(workflow.owner, owner));
3218
+ return [...this.workflows.values()].filter((workflow) => sameActor2(workflow.owner, owner));
2954
3219
  }
2955
3220
  };
2956
3221
  var IntegrationWorkflowRuntime = class {
@@ -3012,7 +3277,7 @@ function findTriggerGrant(grants, requirementId, triggerId) {
3012
3277
  if (!grant) throw new Error(`Missing trigger grant ${requirementId}/${triggerId}.`);
3013
3278
  return grant;
3014
3279
  }
3015
- function sameActor(a, b) {
3280
+ function sameActor2(a, b) {
3016
3281
  return a.type === b.type && a.id === b.id;
3017
3282
  }
3018
3283
 
@@ -3091,6 +3356,9 @@ var IntegrationHub = class {
3091
3356
  async listConnections(owner) {
3092
3357
  return this.store.listByOwner(owner);
3093
3358
  }
3359
+ async getConnection(connectionId) {
3360
+ return this.store.get(connectionId);
3361
+ }
3094
3362
  async issueCapability(request) {
3095
3363
  const connection = await this.requireConnection(request.connectionId);
3096
3364
  this.assertConnectionActive(connection);
@@ -3100,8 +3368,8 @@ var IntegrationHub = class {
3100
3368
  id: `cap_${randomUUID5()}`,
3101
3369
  subject: request.subject,
3102
3370
  connectionId: request.connectionId,
3103
- scopes: unique5(request.scopes),
3104
- allowedActions: unique5(request.allowedActions),
3371
+ scopes: unique6(request.scopes),
3372
+ allowedActions: unique6(request.allowedActions),
3105
3373
  issuedAt: now.toISOString(),
3106
3374
  expiresAt: new Date(now.getTime() + request.ttlMs).toISOString(),
3107
3375
  metadata: request.metadata
@@ -3329,9 +3597,9 @@ async function postJson(fetcher, url, body, bearer) {
3329
3597
  if (!response.ok) throw new IntegrationError(`Integration provider returned HTTP ${response.status}.`, "provider_not_found");
3330
3598
  return response.json();
3331
3599
  }
3332
- function assertScopes(connection, requiredScopes) {
3333
- const missing = requiredScopes.filter((scope) => !connection.grantedScopes.includes(scope));
3334
- if (missing.length > 0) throw new IntegrationError(`Missing integration scopes: ${missing.join(", ")}`, "scope_denied");
3600
+ function assertScopes(connection, requiredScopes2) {
3601
+ const missing2 = requiredScopes2.filter((scope) => !connection.grantedScopes.includes(scope));
3602
+ if (missing2.length > 0) throw new IntegrationError(`Missing integration scopes: ${missing2.join(", ")}`, "scope_denied");
3335
3603
  }
3336
3604
  function hmac(payload, secret) {
3337
3605
  return createHmac2("sha256", secret).update(payload).digest("base64url");
@@ -3347,7 +3615,7 @@ function base64UrlEncode(value) {
3347
3615
  function base64UrlDecode(value) {
3348
3616
  return Buffer.from(value, "base64url").toString("utf8");
3349
3617
  }
3350
- function unique5(values) {
3618
+ function unique6(values) {
3351
3619
  return [...new Set(values)];
3352
3620
  }
3353
3621
 
@@ -3770,12 +4038,12 @@ function registryEntry(canonicalId, candidates, precedence, aliases) {
3770
4038
  const primary = ordered[0];
3771
4039
  const actions = mergeActions(ordered);
3772
4040
  const triggers = mergeTriggers(ordered);
3773
- const scopes = unique6(toolBindableCandidates(ordered).flatMap((candidate) => candidate.connector.scopes ?? []));
4041
+ const scopes = unique7(toolBindableCandidates(ordered).flatMap((candidate) => candidate.connector.scopes ?? []));
3774
4042
  const supportTier = ordered.reduce(
3775
4043
  (best, candidate) => SUPPORT_RANK[candidate.supportTier] > SUPPORT_RANK[best] ? candidate.supportTier : best,
3776
4044
  primary.supportTier
3777
4045
  );
3778
- const aliasesForEntry = unique6([
4046
+ const aliasesForEntry = unique7([
3779
4047
  ...ordered.map((candidate) => candidate.connector.id),
3780
4048
  ...Object.entries(aliases).filter(([, target]) => canonicalConnectorId(target, aliases) === canonicalId).map(([alias]) => alias)
3781
4049
  ].map(slug2).filter((id) => id && id !== canonicalId)).sort();
@@ -3871,9 +4139,157 @@ function isSupportTier(value) {
3871
4139
  function slug2(value) {
3872
4140
  return value.trim().toLowerCase().replace(/&/g, "and").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
3873
4141
  }
3874
- function unique6(values) {
4142
+ function unique7(values) {
4143
+ return [...new Set(values)];
4144
+ }
4145
+
4146
+ // src/catalog.ts
4147
+ var riskRank2 = {
4148
+ read: 0,
4149
+ write: 1,
4150
+ destructive: 2
4151
+ };
4152
+ function integrationToolName(providerId, connectorId, actionId) {
4153
+ return `int_${encodeToolPart(providerId)}_${encodeToolPart(connectorId)}_${encodeToolPart(actionId)}`;
4154
+ }
4155
+ function parseIntegrationToolName(name) {
4156
+ const parts = name.split("_");
4157
+ if (parts.length !== 4 || parts[0] !== "int") {
4158
+ throw new Error(`Invalid integration tool name: ${name}`);
4159
+ }
4160
+ return {
4161
+ providerId: decodeToolPart(parts[1]),
4162
+ connectorId: decodeToolPart(parts[2]),
4163
+ actionId: decodeToolPart(parts[3])
4164
+ };
4165
+ }
4166
+ function buildIntegrationToolCatalog(connectors) {
4167
+ const tools = [];
4168
+ for (const connector of connectors) {
4169
+ for (const action of connector.actions) {
4170
+ const tags = unique8([
4171
+ connector.id,
4172
+ connector.providerId,
4173
+ connector.title,
4174
+ connector.category,
4175
+ action.id,
4176
+ action.title,
4177
+ action.risk,
4178
+ action.dataClass,
4179
+ ...connector.scopes ?? [],
4180
+ ...action.requiredScopes ?? []
4181
+ ].flatMap(tokenize));
4182
+ tools.push({
4183
+ name: integrationToolName(connector.providerId, connector.id, action.id),
4184
+ title: `${connector.title}: ${action.title}`,
4185
+ description: action.description ?? `${action.risk} action ${action.id} on ${connector.title}`,
4186
+ providerId: connector.providerId,
4187
+ connectorId: connector.id,
4188
+ connectorTitle: connector.title,
4189
+ category: connector.category,
4190
+ action,
4191
+ risk: action.risk,
4192
+ dataClass: action.dataClass,
4193
+ requiredScopes: action.requiredScopes,
4194
+ inputSchema: action.inputSchema,
4195
+ outputSchema: action.outputSchema,
4196
+ tags,
4197
+ supportTier: toolSupportTier(connector),
4198
+ runnable: toolRunnable(connector)
4199
+ });
4200
+ }
4201
+ }
4202
+ return tools;
4203
+ }
4204
+ function buildIntegrationCatalogView(input) {
4205
+ const runtimeConnectors = input.executableRegistry?.connectors ?? input.discoveryRegistry.connectors.filter((connector) => toolRunnable(connector));
4206
+ const runtimeTools = buildIntegrationToolCatalog(runtimeConnectors);
4207
+ const discoveryTools = buildIntegrationToolCatalog(input.discoveryRegistry.connectors);
4208
+ return {
4209
+ connectors: input.discoveryRegistry.connectors,
4210
+ conflicts: input.discoveryRegistry.entries.flatMap((entry) => entry.conflicts),
4211
+ summary: summarizeIntegrationRegistry(input.discoveryRegistry),
4212
+ tools: runtimeTools,
4213
+ runtimeTools,
4214
+ discoveryTools
4215
+ };
4216
+ }
4217
+ function searchIntegrationTools(catalog, query, filters = {}) {
4218
+ const terms = tokenize(query);
4219
+ const filtered = catalog.filter((tool) => {
4220
+ if (filters.providerId && tool.providerId !== filters.providerId) return false;
4221
+ if (filters.connectorId && tool.connectorId !== filters.connectorId) return false;
4222
+ if (filters.category && tool.category !== filters.category) return false;
4223
+ if (filters.dataClass && tool.dataClass !== filters.dataClass) return false;
4224
+ if (filters.maxRisk && riskRank2[tool.risk] > riskRank2[filters.maxRisk]) return false;
4225
+ return true;
4226
+ });
4227
+ const scored = filtered.map((tool) => scoreTool(tool, terms));
4228
+ return scored.filter((result) => terms.length === 0 || result.score > 0).sort((a, b) => b.score - a.score || a.tool.name.localeCompare(b.tool.name)).slice(0, filters.limit ?? 20);
4229
+ }
4230
+ function toMcpTools(tools) {
4231
+ return tools.map((tool) => ({
4232
+ name: tool.name,
4233
+ description: `${tool.title}. ${tool.description}`,
4234
+ inputSchema: tool.inputSchema ?? {
4235
+ type: "object",
4236
+ additionalProperties: true,
4237
+ properties: {}
4238
+ }
4239
+ }));
4240
+ }
4241
+ function scoreTool(tool, terms) {
4242
+ if (terms.length === 0) return { tool, score: 1, matched: [] };
4243
+ const haystack = new Set(tool.tags);
4244
+ const matched = [];
4245
+ let score = 0;
4246
+ for (const term of terms) {
4247
+ if (haystack.has(term)) {
4248
+ matched.push(term);
4249
+ score += 4;
4250
+ continue;
4251
+ }
4252
+ if (tool.tags.some((tag) => tag.includes(term))) {
4253
+ matched.push(term);
4254
+ score += 1;
4255
+ }
4256
+ }
4257
+ if (tool.risk === "read") score += 0.25;
4258
+ return { tool, score, matched: unique8(matched) };
4259
+ }
4260
+ function tokenize(value) {
4261
+ return value.toLowerCase().split(/[^a-z0-9]+/g).map((part) => part.trim()).filter(Boolean);
4262
+ }
4263
+ function encodeToolPart(value) {
4264
+ return Buffer.from(value, "utf8").toString("base64url").replace(/_/g, ".");
4265
+ }
4266
+ function decodeToolPart(value) {
4267
+ return Buffer.from(value.replace(/\./g, "_"), "base64url").toString("utf8");
4268
+ }
4269
+ function unique8(values) {
3875
4270
  return [...new Set(values)];
3876
4271
  }
4272
+ function toolSupportTier(connector) {
4273
+ const registry = connector.metadata?.registry;
4274
+ if (registry && typeof registry === "object" && !Array.isArray(registry)) {
4275
+ const supportTier2 = registry.supportTier;
4276
+ return isIntegrationSupportTier(supportTier2) ? supportTier2 : void 0;
4277
+ }
4278
+ const supportTier = connector.metadata?.supportTier;
4279
+ return isIntegrationSupportTier(supportTier) ? supportTier : void 0;
4280
+ }
4281
+ function toolRunnable(connector) {
4282
+ const registry = connector.metadata?.registry;
4283
+ if (registry && typeof registry === "object" && !Array.isArray(registry)) {
4284
+ const toolBindable = registry.toolBindable;
4285
+ if (typeof toolBindable === "boolean") return toolBindable;
4286
+ }
4287
+ const tier = toolSupportTier(connector);
4288
+ return tier === "gatewayExecutable" || tier === "firstPartyExecutable" || tier === "sandboxExecutable";
4289
+ }
4290
+ function isIntegrationSupportTier(value) {
4291
+ return value === "catalogOnly" || value === "setupReady" || value === "gatewayExecutable" || value === "firstPartyExecutable" || value === "sandboxExecutable";
4292
+ }
3877
4293
 
3878
4294
  export {
3879
4295
  ACTIVEPIECES_OVERRIDES,
@@ -3882,6 +4298,12 @@ export {
3882
4298
  buildActivepiecesConnectors,
3883
4299
  createCatalogExecutorProvider,
3884
4300
  createActivepiecesExecutorProvider,
4301
+ integrationToolName,
4302
+ parseIntegrationToolName,
4303
+ buildIntegrationToolCatalog,
4304
+ buildIntegrationCatalogView,
4305
+ searchIntegrationTools,
4306
+ toMcpTools,
3885
4307
  ACTIVEPIECES_PUBLIC_CATALOG_URL,
3886
4308
  extractActivepiecesPublicPieceCount,
3887
4309
  auditIntegrationCatalogFreshness,
@@ -3988,6 +4410,9 @@ export {
3988
4410
  tangleCatalogAuthValue,
3989
4411
  createTangleCatalogRuntimeNodeRequestListener,
3990
4412
  startTangleCatalogRuntimeNodeServer,
4413
+ InMemoryIntegrationGrantStore,
4414
+ IntegrationRuntime,
4415
+ createIntegrationRuntime,
3991
4416
  InMemoryIntegrationWorkflowStore,
3992
4417
  IntegrationWorkflowRuntime,
3993
4418
  createIntegrationWorkflowRuntime,
@@ -4000,4 +4425,4 @@ export {
4000
4425
  signCapability,
4001
4426
  verifyCapabilityToken
4002
4427
  };
4003
- //# sourceMappingURL=chunk-IOO75SJH.js.map
4428
+ //# sourceMappingURL=chunk-ZEDXLDOV.js.map