@tangle-network/agent-integrations 0.2.0 → 0.3.0

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/README.md CHANGED
@@ -37,19 +37,49 @@ capability. The sandbox should never receive reusable provider secrets.
37
37
 
38
38
  ## Core Usage
39
39
 
40
+ ### Product Flow
41
+
42
+ For Agent Builder and sandbox apps, the intended flow is:
43
+
44
+ ```txt
45
+ generated app declares required tools
46
+ -> app searches the integration catalog by intent
47
+ -> user connects the missing accounts
48
+ -> runtime issues a short-lived capability to the sandbox
49
+ -> reads run immediately
50
+ -> writes pause for policy approval
51
+ -> every call returns an audit-safe result
52
+ ```
53
+
54
+ The SDK surface for that flow is:
55
+
56
+ - `buildIntegrationToolCatalog` and `searchIntegrationTools` for discoverable
57
+ tool catalogs.
58
+ - `toMcpTools` for MCP-compatible tool export.
59
+ - `IntegrationHub.issueCapability` for scoped sandbox handoff.
60
+ - `createDefaultIntegrationPolicyEngine` for allow / approval / deny decisions.
61
+ - `buildIntegrationInvocationEnvelope` for sandbox-safe tool calls.
62
+ - `createConnectorAdapterProvider` to run first-party adapters through the hub.
63
+
40
64
  ```ts
41
65
  import {
42
66
  InMemoryConnectionStore,
43
67
  IntegrationHub,
68
+ buildIntegrationToolCatalog,
44
69
  createMockIntegrationProvider,
70
+ searchIntegrationTools,
45
71
  } from '@tangle-network/agent-integrations'
46
72
 
73
+ const provider = createMockIntegrationProvider()
47
74
  const hub = new IntegrationHub({
48
- providers: [createMockIntegrationProvider()],
75
+ providers: [provider],
49
76
  store: new InMemoryConnectionStore(),
50
77
  capabilitySecret: 'dev-secret',
51
78
  })
52
79
 
80
+ const catalog = buildIntegrationToolCatalog(await hub.listConnectors())
81
+ const tools = searchIntegrationTools(catalog, 'search unread gmail', { maxRisk: 'read' })
82
+
53
83
  const connection = await hub.upsertConnection({
54
84
  id: 'conn_1',
55
85
  owner: { type: 'user', id: 'user_1' },
package/dist/index.d.ts CHANGED
@@ -903,6 +903,152 @@ declare const stripeWebhookReceiverConnector: ConnectorAdapter;
903
903
 
904
904
  declare const slackEventsConnector: ConnectorAdapter;
905
905
 
906
+ interface IntegrationToolDefinition {
907
+ name: string;
908
+ title: string;
909
+ description: string;
910
+ providerId: string;
911
+ connectorId: string;
912
+ connectorTitle: string;
913
+ category: IntegrationConnectorCategory;
914
+ action: IntegrationConnectorAction;
915
+ risk: IntegrationActionRisk;
916
+ dataClass: IntegrationDataClass;
917
+ requiredScopes: string[];
918
+ inputSchema?: unknown;
919
+ outputSchema?: unknown;
920
+ tags: string[];
921
+ }
922
+ interface IntegrationToolSearchFilters {
923
+ providerId?: string;
924
+ connectorId?: string;
925
+ category?: IntegrationConnectorCategory;
926
+ maxRisk?: IntegrationActionRisk;
927
+ dataClass?: IntegrationDataClass;
928
+ limit?: number;
929
+ }
930
+ interface IntegrationToolSearchResult {
931
+ tool: IntegrationToolDefinition;
932
+ score: number;
933
+ matched: string[];
934
+ }
935
+ interface McpToolDefinition {
936
+ name: string;
937
+ description: string;
938
+ inputSchema: unknown;
939
+ }
940
+ declare function integrationToolName(providerId: string, connectorId: string, actionId: string): string;
941
+ declare function parseIntegrationToolName(name: string): {
942
+ providerId: string;
943
+ connectorId: string;
944
+ actionId: string;
945
+ };
946
+ declare function buildIntegrationToolCatalog(connectors: IntegrationConnector[]): IntegrationToolDefinition[];
947
+ declare function searchIntegrationTools(catalog: IntegrationToolDefinition[], query: string, filters?: IntegrationToolSearchFilters): IntegrationToolSearchResult[];
948
+ declare function toMcpTools(tools: IntegrationToolDefinition[]): McpToolDefinition[];
949
+
950
+ type IntegrationPolicyEffect = 'allow' | 'require_approval' | 'deny';
951
+ interface IntegrationPolicyRule {
952
+ id: string;
953
+ effect: IntegrationPolicyEffect;
954
+ reason: string;
955
+ providerId?: string;
956
+ connectorId?: string;
957
+ action?: string;
958
+ maxRisk?: IntegrationActionRisk;
959
+ risk?: IntegrationActionRisk;
960
+ dataClass?: IntegrationDataClass;
961
+ }
962
+ interface StaticIntegrationPolicyOptions {
963
+ rules?: IntegrationPolicyRule[];
964
+ defaultReadEffect?: IntegrationPolicyEffect;
965
+ defaultWriteEffect?: IntegrationPolicyEffect;
966
+ defaultDestructiveEffect?: IntegrationPolicyEffect;
967
+ now?: () => Date;
968
+ }
969
+ interface IntegrationApprovalResolution {
970
+ approvalId: string;
971
+ approved: boolean;
972
+ resolvedBy: string;
973
+ resolvedAt: string;
974
+ reason?: string;
975
+ metadata?: Record<string, unknown>;
976
+ }
977
+ declare class StaticIntegrationPolicyEngine implements IntegrationPolicyEngine {
978
+ private readonly rules;
979
+ private readonly defaultReadEffect;
980
+ private readonly defaultWriteEffect;
981
+ private readonly defaultDestructiveEffect;
982
+ private readonly now;
983
+ constructor(options?: StaticIntegrationPolicyOptions);
984
+ decide(ctx: IntegrationGuardContext & {
985
+ subject: {
986
+ type: string;
987
+ id: string;
988
+ };
989
+ }): IntegrationPolicyDecision;
990
+ private defaultEffect;
991
+ }
992
+ declare function createDefaultIntegrationPolicyEngine(options?: Omit<StaticIntegrationPolicyOptions, 'rules'>): StaticIntegrationPolicyEngine;
993
+ declare function buildApprovalRequest(ctx: IntegrationGuardContext & {
994
+ subject: {
995
+ type: string;
996
+ id: string;
997
+ };
998
+ }, reason: string, requestedAt: Date): IntegrationApprovalRequest;
999
+ declare function redactApprovalRequest(request: IntegrationApprovalRequest): IntegrationApprovalRequest;
1000
+
1001
+ interface IntegrationInvocationEnvelope {
1002
+ kind: 'integration.invocation';
1003
+ capabilityToken: string;
1004
+ toolName: string;
1005
+ action: string;
1006
+ input?: unknown;
1007
+ idempotencyKey: string;
1008
+ dryRun?: boolean;
1009
+ metadata?: Record<string, unknown>;
1010
+ }
1011
+ type NormalizedIntegrationResult = {
1012
+ status: 'ok';
1013
+ action: string;
1014
+ output?: unknown;
1015
+ metadata?: Record<string, unknown>;
1016
+ } | {
1017
+ status: 'approval_required';
1018
+ action: string;
1019
+ approval: IntegrationApprovalRequest;
1020
+ metadata?: Record<string, unknown>;
1021
+ } | {
1022
+ status: 'failed';
1023
+ action: string;
1024
+ error: string;
1025
+ metadata?: Record<string, unknown>;
1026
+ };
1027
+ declare function buildIntegrationInvocationEnvelope(input: {
1028
+ capabilityToken: string;
1029
+ toolName: string;
1030
+ args?: unknown;
1031
+ idempotencyKey: string;
1032
+ dryRun?: boolean;
1033
+ metadata?: Record<string, unknown>;
1034
+ }): IntegrationInvocationEnvelope;
1035
+ declare function invocationRequestFromEnvelope(envelope: IntegrationInvocationEnvelope): InvokeWithCapabilityRequest;
1036
+ declare function redactInvocationEnvelope(envelope: IntegrationInvocationEnvelope): Omit<IntegrationInvocationEnvelope, 'capabilityToken'> & {
1037
+ capabilityToken: '[REDACTED]';
1038
+ };
1039
+ declare function redactCapability(capability: IntegrationCapability): IntegrationCapability;
1040
+ declare function normalizeIntegrationResult(result: IntegrationActionResult): NormalizedIntegrationResult;
1041
+
1042
+ interface ConnectorAdapterProviderOptions {
1043
+ id?: string;
1044
+ kind?: IntegrationProviderKind;
1045
+ adapters: ConnectorAdapter[];
1046
+ resolveDataSource: (connection: IntegrationConnection) => Promise<ResolvedDataSource> | ResolvedDataSource;
1047
+ now?: () => Date;
1048
+ }
1049
+ declare function createConnectorAdapterProvider(options: ConnectorAdapterProviderOptions): IntegrationProvider;
1050
+ declare function manifestToConnector(providerId: string, adapter: ConnectorAdapter): IntegrationConnector;
1051
+
906
1052
  type IntegrationProviderKind = 'first_party' | 'nango' | 'pipedream' | 'zapier' | 'activepieces' | 'executor' | 'custom';
907
1053
  type IntegrationConnectorCategory = 'email' | 'calendar' | 'chat' | 'crm' | 'storage' | 'docs' | 'database' | 'webhook' | 'workflow' | 'internal' | 'other';
908
1054
  type IntegrationActionRisk = 'read' | 'write' | 'destructive';
@@ -1100,6 +1246,39 @@ interface IntegrationGuardContext {
1100
1246
  /** The action descriptor from the connector manifest, if discovered. */
1101
1247
  action?: IntegrationConnectorAction;
1102
1248
  }
1249
+ type IntegrationPolicyDecision = {
1250
+ decision: 'allow';
1251
+ reason: string;
1252
+ metadata?: Record<string, unknown>;
1253
+ } | {
1254
+ decision: 'require_approval';
1255
+ reason: string;
1256
+ approval: IntegrationApprovalRequest;
1257
+ metadata?: Record<string, unknown>;
1258
+ } | {
1259
+ decision: 'deny';
1260
+ reason: string;
1261
+ metadata?: Record<string, unknown>;
1262
+ };
1263
+ interface IntegrationApprovalRequest {
1264
+ id: string;
1265
+ connectionId: string;
1266
+ providerId: string;
1267
+ connectorId: string;
1268
+ action: string;
1269
+ actor: IntegrationActor;
1270
+ risk: IntegrationActionRisk;
1271
+ dataClass: IntegrationDataClass;
1272
+ reason: string;
1273
+ requestedAt: string;
1274
+ inputPreview?: unknown;
1275
+ metadata?: Record<string, unknown>;
1276
+ }
1277
+ interface IntegrationPolicyEngine {
1278
+ decide(ctx: IntegrationGuardContext & {
1279
+ subject: IntegrationActor;
1280
+ }): Promise<IntegrationPolicyDecision> | IntegrationPolicyDecision;
1281
+ }
1103
1282
  interface IntegrationHubOptions {
1104
1283
  providers: IntegrationProvider[];
1105
1284
  store: IntegrationConnectionStore;
@@ -1107,6 +1286,10 @@ interface IntegrationHubOptions {
1107
1286
  /** Optional cross-cutting guard. If provided, every invokeAction call
1108
1287
  * passes through it before reaching the provider. See {@link IntegrationActionGuard}. */
1109
1288
  guard?: IntegrationActionGuard;
1289
+ /** Optional policy engine. Runs after capability/scope checks and before
1290
+ * provider invocation. Use it to pause writes, deny destructive actions,
1291
+ * or apply tenant-specific allow rules. */
1292
+ policy?: IntegrationPolicyEngine;
1110
1293
  now?: () => Date;
1111
1294
  }
1112
1295
  interface HttpIntegrationProviderOptions {
@@ -1121,8 +1304,8 @@ interface InvokeWithCapabilityRequest extends Omit<IntegrationActionRequest, 'co
1121
1304
  connectionId?: never;
1122
1305
  }
1123
1306
  declare class IntegrationError extends Error {
1124
- readonly code: 'provider_not_found' | 'connector_not_found' | 'connection_not_found' | 'connection_not_active' | 'auth_not_supported' | 'capability_invalid' | 'capability_expired' | 'scope_denied' | 'action_denied' | 'action_not_found';
1125
- constructor(message: string, code: 'provider_not_found' | 'connector_not_found' | 'connection_not_found' | 'connection_not_active' | 'auth_not_supported' | 'capability_invalid' | 'capability_expired' | 'scope_denied' | 'action_denied' | 'action_not_found');
1307
+ readonly code: 'provider_not_found' | 'connector_not_found' | 'connection_not_found' | 'connection_not_active' | 'auth_not_supported' | 'capability_invalid' | 'capability_expired' | 'scope_denied' | 'action_denied' | 'action_not_found' | 'approval_required' | 'policy_denied';
1308
+ constructor(message: string, code: 'provider_not_found' | 'connector_not_found' | 'connection_not_found' | 'connection_not_active' | 'auth_not_supported' | 'capability_invalid' | 'capability_expired' | 'scope_denied' | 'action_denied' | 'action_not_found' | 'approval_required' | 'policy_denied');
1126
1309
  }
1127
1310
  declare class InMemoryConnectionStore implements IntegrationConnectionStore {
1128
1311
  private readonly connections;
@@ -1136,6 +1319,7 @@ declare class IntegrationHub {
1136
1319
  private readonly store;
1137
1320
  private readonly capabilitySecret;
1138
1321
  private readonly guard;
1322
+ private readonly policy;
1139
1323
  private readonly now;
1140
1324
  constructor(options: IntegrationHubOptions);
1141
1325
  listConnectors(): Promise<IntegrationConnector[]>;
@@ -1161,4 +1345,4 @@ declare function createHttpIntegrationProvider(options: HttpIntegrationProviderO
1161
1345
  declare function signCapability(capability: IntegrationCapability, secret: string): string;
1162
1346
  declare function verifyCapabilityToken(token: string, secret: string): IntegrationCapability;
1163
1347
 
1164
- export { type AuthSpec, type CASStrategy, type Capability, type CapabilityClass, type CapabilityMutation, type CapabilityMutationResult, type CapabilityParameterSchema, type CapabilityRead, type CapabilityReadResult, type CompleteAuthRequest, type ConnectorAdapter, type ConnectorCredentials, type ConnectorInvocation, type ConnectorManifest, type ConnectorManifestValidationIssue, type ConnectorManifestValidationResult, type ConsistencyModel, CredentialsExpired, DEFAULT_SIGNATURE_TOLERANCE_SECONDS, type DataSourceMetadata, type EventHandlerResult, type ExchangeCodeInput, type GenericHmacVerifyOptions, type GoogleCalendarOptions, type GoogleSheetsOptions, type HttpIntegrationProviderOptions, type HubSpotOptions, InMemoryConnectionStore, InMemoryOAuthFlowStore, type InboundEvent, type IntegrationActionGuard, type IntegrationActionRequest, type IntegrationActionResult, type IntegrationActionRisk, type IntegrationActor, type IntegrationCapability, type IntegrationConnection, type IntegrationConnectionStore, type IntegrationConnector, type IntegrationConnectorAction, type IntegrationConnectorCategory, type IntegrationConnectorTrigger, type IntegrationDataClass, IntegrationError, type IntegrationGuardContext, IntegrationHub, type IntegrationHubOptions, type IntegrationProvider, type IntegrationProviderKind, type IntegrationTriggerEvent, type IntegrationTriggerSubscription, type InvokeWithCapabilityRequest, type IssueCapabilityRequest, type IssuedIntegrationCapability, type MicrosoftCalendarOptions, type NotionDatabaseOptions, type OAuthFlowStore, type OAuthTokens, type ParsedStripeSignatureHeader, type PendingOAuthFlow, type RateLimitSpec, type RefreshInput, type ResolvedDataSource, ResourceContention, type SecretRef, type SlackOptions, type SlackVerifyOptions, type StartAuthRequest, type StartAuthResult, type StartOAuthInput, type StartOAuthOutput, type StripeVerifyOptions, _resetPendingFlowsForTests, assertValidConnectorManifest, consumePendingFlow, createHttpIntegrationProvider, createMockIntegrationProvider, exchangeAuthorizationCode, firstHeader, googleCalendar, googleSheets, hubspot, microsoftCalendar, notionDatabase, parseStripeSignatureHeader, refreshAccessToken, sanitizeConnection, signCapability, slack, slackEventsConnector, startOAuthFlow, stripePackConnector, stripeWebhookReceiverConnector, twilioSmsConnector, validateConnectorManifest, verifyCapabilityToken, verifyHmacSignature, verifySlackSignature, verifyStripeSignature, webhookConnector };
1348
+ export { type AuthSpec, type CASStrategy, type Capability, type CapabilityClass, type CapabilityMutation, type CapabilityMutationResult, type CapabilityParameterSchema, type CapabilityRead, type CapabilityReadResult, type CompleteAuthRequest, type ConnectorAdapter, type ConnectorAdapterProviderOptions, type ConnectorCredentials, type ConnectorInvocation, type ConnectorManifest, type ConnectorManifestValidationIssue, type ConnectorManifestValidationResult, type ConsistencyModel, CredentialsExpired, DEFAULT_SIGNATURE_TOLERANCE_SECONDS, type DataSourceMetadata, type EventHandlerResult, type ExchangeCodeInput, type GenericHmacVerifyOptions, type GoogleCalendarOptions, type GoogleSheetsOptions, type HttpIntegrationProviderOptions, type HubSpotOptions, InMemoryConnectionStore, InMemoryOAuthFlowStore, type InboundEvent, type IntegrationActionGuard, type IntegrationActionRequest, type IntegrationActionResult, type IntegrationActionRisk, type IntegrationActor, type IntegrationApprovalRequest, type IntegrationApprovalResolution, type IntegrationCapability, type IntegrationConnection, type IntegrationConnectionStore, type IntegrationConnector, type IntegrationConnectorAction, type IntegrationConnectorCategory, type IntegrationConnectorTrigger, type IntegrationDataClass, IntegrationError, type IntegrationGuardContext, IntegrationHub, type IntegrationHubOptions, type IntegrationInvocationEnvelope, type IntegrationPolicyDecision, type IntegrationPolicyEffect, type IntegrationPolicyEngine, type IntegrationPolicyRule, type IntegrationProvider, type IntegrationProviderKind, type IntegrationToolDefinition, type IntegrationToolSearchFilters, type IntegrationToolSearchResult, type IntegrationTriggerEvent, type IntegrationTriggerSubscription, type InvokeWithCapabilityRequest, type IssueCapabilityRequest, type IssuedIntegrationCapability, type McpToolDefinition, type MicrosoftCalendarOptions, type NormalizedIntegrationResult, type NotionDatabaseOptions, type OAuthFlowStore, type OAuthTokens, type ParsedStripeSignatureHeader, type PendingOAuthFlow, type RateLimitSpec, type RefreshInput, type ResolvedDataSource, ResourceContention, type SecretRef, type SlackOptions, type SlackVerifyOptions, type StartAuthRequest, type StartAuthResult, type StartOAuthInput, type StartOAuthOutput, StaticIntegrationPolicyEngine, type StaticIntegrationPolicyOptions, type StripeVerifyOptions, _resetPendingFlowsForTests, assertValidConnectorManifest, buildApprovalRequest, buildIntegrationInvocationEnvelope, buildIntegrationToolCatalog, consumePendingFlow, createConnectorAdapterProvider, createDefaultIntegrationPolicyEngine, createHttpIntegrationProvider, createMockIntegrationProvider, exchangeAuthorizationCode, firstHeader, googleCalendar, googleSheets, hubspot, integrationToolName, invocationRequestFromEnvelope, manifestToConnector, microsoftCalendar, normalizeIntegrationResult, notionDatabase, parseIntegrationToolName, parseStripeSignatureHeader, redactApprovalRequest, redactCapability, redactInvocationEnvelope, refreshAccessToken, sanitizeConnection, searchIntegrationTools, signCapability, slack, slackEventsConnector, startOAuthFlow, stripePackConnector, stripeWebhookReceiverConnector, toMcpTools, twilioSmsConnector, validateConnectorManifest, verifyCapabilityToken, verifyHmacSignature, verifySlackSignature, verifyStripeSignature, webhookConnector };