@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 +31 -1
- package/dist/index.d.ts +187 -3
- package/dist/index.js +482 -84
- package/dist/index.js.map +1 -1
- package/docs/execution-layer-launch-plan.md +220 -0
- package/package.json +1 -1
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: [
|
|
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 };
|