@tangle-network/agent-integrations 0.4.0 → 0.5.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 +5 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +56 -3
- package/dist/index.js.map +1 -1
- package/docs/execution-layer-launch-plan.md +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,7 +58,10 @@ The SDK surface for that flow is:
|
|
|
58
58
|
- `toMcpTools` for MCP-compatible tool export.
|
|
59
59
|
- `IntegrationHub.issueCapability` for scoped sandbox handoff.
|
|
60
60
|
- `createDefaultIntegrationPolicyEngine` for allow / approval / deny decisions.
|
|
61
|
-
- `buildIntegrationInvocationEnvelope`
|
|
61
|
+
- `buildIntegrationInvocationEnvelope` and
|
|
62
|
+
`validateIntegrationInvocationEnvelope` for sandbox-safe tool calls with
|
|
63
|
+
action/tool consistency, idempotency-key, metadata-shape, known-tool, and
|
|
64
|
+
input-size checks.
|
|
62
65
|
- `createConnectorAdapterProvider` to run first-party adapters through the hub.
|
|
63
66
|
|
|
64
67
|
```ts
|
|
@@ -143,6 +146,7 @@ without changing agent code.
|
|
|
143
146
|
- Capability tokens contain no provider credential.
|
|
144
147
|
- Secret refs are redacted from public telemetry.
|
|
145
148
|
- Write/destructive actions can be policy-gated.
|
|
149
|
+
- Sandbox invocation envelopes are validated before conversion to hub requests.
|
|
146
150
|
- Action invocation checks connection ownership, status, scopes, allowed
|
|
147
151
|
actions, and expiration.
|
|
148
152
|
- Optional `IntegrationActionGuard` wraps every action invocation for
|
package/dist/index.d.ts
CHANGED
|
@@ -533,6 +533,25 @@ interface GenericHmacVerifyOptions {
|
|
|
533
533
|
lowercaseHex?: boolean;
|
|
534
534
|
}
|
|
535
535
|
declare function verifyHmacSignature(rawBody: string, signatureHeader: string, secret: string, options?: GenericHmacVerifyOptions): boolean;
|
|
536
|
+
interface TwilioVerifyOptions {
|
|
537
|
+
/** Skip verification when the auth token isn't configured. Useful in
|
|
538
|
+
* dev where the receiver wants to accept any payload. Default `false`
|
|
539
|
+
* — production should always require a configured token. */
|
|
540
|
+
skipWhenAuthTokenMissing?: boolean;
|
|
541
|
+
/** When true, sign the raw body instead of the URL-encoded sorted-params
|
|
542
|
+
* reduction. Twilio uses raw-body signing for `application/json`
|
|
543
|
+
* webhook bodies. Default `false`. */
|
|
544
|
+
bodyAsRaw?: boolean;
|
|
545
|
+
/** When `bodyAsRaw` is true, the raw body to sign. Ignored otherwise. */
|
|
546
|
+
rawBody?: string;
|
|
547
|
+
}
|
|
548
|
+
/** Verify a Twilio webhook signature. */
|
|
549
|
+
declare function verifyTwilioSignature(input: {
|
|
550
|
+
authToken: string | null | undefined;
|
|
551
|
+
signatureHeader: string | string[] | undefined;
|
|
552
|
+
fullUrl: string | null | undefined;
|
|
553
|
+
params: Record<string, string> | undefined;
|
|
554
|
+
}, options?: TwilioVerifyOptions): boolean;
|
|
536
555
|
declare function firstHeader(headers: Record<string, string | string[] | undefined>, name: string): string | undefined;
|
|
537
556
|
|
|
538
557
|
/**
|
|
@@ -1008,6 +1027,11 @@ interface IntegrationInvocationEnvelope {
|
|
|
1008
1027
|
dryRun?: boolean;
|
|
1009
1028
|
metadata?: Record<string, unknown>;
|
|
1010
1029
|
}
|
|
1030
|
+
interface IntegrationInvocationEnvelopeValidationOptions {
|
|
1031
|
+
connectors?: IntegrationConnector[];
|
|
1032
|
+
maxInputBytes?: number;
|
|
1033
|
+
requireKnownTool?: boolean;
|
|
1034
|
+
}
|
|
1011
1035
|
type NormalizedIntegrationResult = {
|
|
1012
1036
|
status: 'ok';
|
|
1013
1037
|
action: string;
|
|
@@ -1033,6 +1057,7 @@ declare function buildIntegrationInvocationEnvelope(input: {
|
|
|
1033
1057
|
metadata?: Record<string, unknown>;
|
|
1034
1058
|
}): IntegrationInvocationEnvelope;
|
|
1035
1059
|
declare function invocationRequestFromEnvelope(envelope: IntegrationInvocationEnvelope): InvokeWithCapabilityRequest;
|
|
1060
|
+
declare function validateIntegrationInvocationEnvelope(envelope: IntegrationInvocationEnvelope, options?: IntegrationInvocationEnvelopeValidationOptions): void;
|
|
1036
1061
|
declare function redactInvocationEnvelope(envelope: IntegrationInvocationEnvelope): Omit<IntegrationInvocationEnvelope, 'capabilityToken'> & {
|
|
1037
1062
|
capabilityToken: '[REDACTED]';
|
|
1038
1063
|
};
|
|
@@ -1399,4 +1424,4 @@ declare function createHttpIntegrationProvider(options: HttpIntegrationProviderO
|
|
|
1399
1424
|
declare function signCapability(capability: IntegrationCapability, secret: string): string;
|
|
1400
1425
|
declare function verifyCapabilityToken(token: string, secret: string): IntegrationCapability;
|
|
1401
1426
|
|
|
1402
|
-
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 GraphqlOperationSpec, type HttpIntegrationProviderOptions, type HubSpotOptions, type ImportCatalogOptions, 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 McpCatalog, type McpCatalogTool, type McpToolDefinition, type MicrosoftCalendarOptions, type NormalizedIntegrationResult, type NotionDatabaseOptions, type OAuthFlowStore, type OAuthTokens, type OpenApiDocument, type OpenApiOperation, 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, importGraphqlConnector, importMcpConnector, importOpenApiConnector, 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 };
|
|
1427
|
+
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 GraphqlOperationSpec, type HttpIntegrationProviderOptions, type HubSpotOptions, type ImportCatalogOptions, 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 IntegrationInvocationEnvelopeValidationOptions, 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 McpCatalog, type McpCatalogTool, type McpToolDefinition, type MicrosoftCalendarOptions, type NormalizedIntegrationResult, type NotionDatabaseOptions, type OAuthFlowStore, type OAuthTokens, type OpenApiDocument, type OpenApiOperation, 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, type TwilioVerifyOptions, _resetPendingFlowsForTests, assertValidConnectorManifest, buildApprovalRequest, buildIntegrationInvocationEnvelope, buildIntegrationToolCatalog, consumePendingFlow, createConnectorAdapterProvider, createDefaultIntegrationPolicyEngine, createHttpIntegrationProvider, createMockIntegrationProvider, exchangeAuthorizationCode, firstHeader, googleCalendar, googleSheets, hubspot, importGraphqlConnector, importMcpConnector, importOpenApiConnector, integrationToolName, invocationRequestFromEnvelope, manifestToConnector, microsoftCalendar, normalizeIntegrationResult, notionDatabase, parseIntegrationToolName, parseStripeSignatureHeader, redactApprovalRequest, redactCapability, redactInvocationEnvelope, refreshAccessToken, sanitizeConnection, searchIntegrationTools, signCapability, slack, slackEventsConnector, startOAuthFlow, stripePackConnector, stripeWebhookReceiverConnector, toMcpTools, twilioSmsConnector, validateConnectorManifest, validateIntegrationInvocationEnvelope, verifyCapabilityToken, verifyHmacSignature, verifySlackSignature, verifyStripeSignature, verifyTwilioSignature, webhookConnector };
|
package/dist/index.js
CHANGED
|
@@ -242,6 +242,20 @@ function verifyHmacSignature(rawBody, signatureHeader, secret, options = {}) {
|
|
|
242
242
|
if (sigBuf.length !== expectedBuf.length) return false;
|
|
243
243
|
return timingSafeEqual(sigBuf, expectedBuf);
|
|
244
244
|
}
|
|
245
|
+
function verifyTwilioSignature(input, options = {}) {
|
|
246
|
+
if (!input.authToken) {
|
|
247
|
+
return options.skipWhenAuthTokenMissing === true;
|
|
248
|
+
}
|
|
249
|
+
const signature = input.signatureHeader;
|
|
250
|
+
if (!signature || Array.isArray(signature)) return false;
|
|
251
|
+
if (!input.fullUrl) return false;
|
|
252
|
+
const data = options.bodyAsRaw === true ? input.fullUrl + (options.rawBody ?? "") : Object.keys(input.params ?? {}).sort().reduce((acc, key) => acc + key + (input.params[key] ?? ""), input.fullUrl);
|
|
253
|
+
const expected = createHmac("sha1", input.authToken).update(data).digest("base64");
|
|
254
|
+
const expectedBuf = Buffer.from(expected);
|
|
255
|
+
const sigBuf = Buffer.from(signature);
|
|
256
|
+
if (expectedBuf.length !== sigBuf.length) return false;
|
|
257
|
+
return timingSafeEqual(expectedBuf, sigBuf);
|
|
258
|
+
}
|
|
245
259
|
function firstHeader(headers, name) {
|
|
246
260
|
const v = headers[name] ?? headers[name.toLowerCase()] ?? Object.entries(headers).find(([key]) => key.toLowerCase() === name.toLowerCase())?.[1];
|
|
247
261
|
if (Array.isArray(v)) return v[0];
|
|
@@ -2743,10 +2757,10 @@ function tokenize(value) {
|
|
|
2743
2757
|
return value.toLowerCase().split(/[^a-z0-9]+/g).map((part) => part.trim()).filter(Boolean);
|
|
2744
2758
|
}
|
|
2745
2759
|
function encodeToolPart(value) {
|
|
2746
|
-
return Buffer.from(value, "utf8").toString("base64url");
|
|
2760
|
+
return Buffer.from(value, "utf8").toString("base64url").replace(/_/g, ".");
|
|
2747
2761
|
}
|
|
2748
2762
|
function decodeToolPart(value) {
|
|
2749
|
-
return Buffer.from(value, "base64url").toString("utf8");
|
|
2763
|
+
return Buffer.from(value.replace(/\./g, "_"), "base64url").toString("utf8");
|
|
2750
2764
|
}
|
|
2751
2765
|
function unique(values) {
|
|
2752
2766
|
return [...new Set(values)];
|
|
@@ -2855,7 +2869,7 @@ function redactUnknown(value) {
|
|
|
2855
2869
|
// src/sandbox.ts
|
|
2856
2870
|
function buildIntegrationInvocationEnvelope(input) {
|
|
2857
2871
|
const parsed = parseIntegrationToolName(input.toolName);
|
|
2858
|
-
|
|
2872
|
+
const envelope = {
|
|
2859
2873
|
kind: "integration.invocation",
|
|
2860
2874
|
capabilityToken: input.capabilityToken,
|
|
2861
2875
|
toolName: input.toolName,
|
|
@@ -2865,8 +2879,11 @@ function buildIntegrationInvocationEnvelope(input) {
|
|
|
2865
2879
|
dryRun: input.dryRun,
|
|
2866
2880
|
metadata: input.metadata
|
|
2867
2881
|
};
|
|
2882
|
+
validateIntegrationInvocationEnvelope(envelope);
|
|
2883
|
+
return envelope;
|
|
2868
2884
|
}
|
|
2869
2885
|
function invocationRequestFromEnvelope(envelope) {
|
|
2886
|
+
validateIntegrationInvocationEnvelope(envelope);
|
|
2870
2887
|
return {
|
|
2871
2888
|
action: envelope.action,
|
|
2872
2889
|
input: envelope.input,
|
|
@@ -2875,6 +2892,34 @@ function invocationRequestFromEnvelope(envelope) {
|
|
|
2875
2892
|
metadata: envelope.metadata
|
|
2876
2893
|
};
|
|
2877
2894
|
}
|
|
2895
|
+
function validateIntegrationInvocationEnvelope(envelope, options = {}) {
|
|
2896
|
+
if (!envelope || typeof envelope !== "object") throw new Error("Integration invocation envelope is required.");
|
|
2897
|
+
if (envelope.kind !== "integration.invocation") throw new Error("Invalid integration invocation envelope kind.");
|
|
2898
|
+
if (!isNonEmptyString(envelope.capabilityToken)) throw new Error("Integration invocation envelope is missing capabilityToken.");
|
|
2899
|
+
if (!isNonEmptyString(envelope.toolName)) throw new Error("Integration invocation envelope is missing toolName.");
|
|
2900
|
+
if (!isNonEmptyString(envelope.action)) throw new Error("Integration invocation envelope is missing action.");
|
|
2901
|
+
if (!isNonEmptyString(envelope.idempotencyKey)) throw new Error("Integration invocation envelope is missing idempotencyKey.");
|
|
2902
|
+
if (envelope.metadata !== void 0 && !isPlainRecord(envelope.metadata)) {
|
|
2903
|
+
throw new Error("Integration invocation envelope metadata must be an object.");
|
|
2904
|
+
}
|
|
2905
|
+
const parsed = parseIntegrationToolName(envelope.toolName);
|
|
2906
|
+
if (parsed.actionId !== envelope.action) {
|
|
2907
|
+
throw new Error(`Integration invocation action ${envelope.action} does not match tool ${parsed.actionId}.`);
|
|
2908
|
+
}
|
|
2909
|
+
const inputBytes = Buffer.byteLength(JSON.stringify(envelope.input ?? null), "utf8");
|
|
2910
|
+
const maxInputBytes = options.maxInputBytes ?? 256 * 1024;
|
|
2911
|
+
if (inputBytes > maxInputBytes) {
|
|
2912
|
+
throw new Error(`Integration invocation input exceeds ${maxInputBytes} bytes.`);
|
|
2913
|
+
}
|
|
2914
|
+
if (options.requireKnownTool || options.connectors) {
|
|
2915
|
+
if (!options.connectors) throw new Error("connectors are required when requireKnownTool is true.");
|
|
2916
|
+
const connector = options.connectors.find(
|
|
2917
|
+
(candidate) => candidate.providerId === parsed.providerId && candidate.id === parsed.connectorId
|
|
2918
|
+
);
|
|
2919
|
+
const action = connector?.actions.find((candidate) => candidate.id === parsed.actionId);
|
|
2920
|
+
if (!connector || !action) throw new Error(`Unknown integration tool ${envelope.toolName}.`);
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2878
2923
|
function redactInvocationEnvelope(envelope) {
|
|
2879
2924
|
return {
|
|
2880
2925
|
...envelope,
|
|
@@ -2926,6 +2971,12 @@ function redactUnknown2(value) {
|
|
|
2926
2971
|
}
|
|
2927
2972
|
return out;
|
|
2928
2973
|
}
|
|
2974
|
+
function isNonEmptyString(value) {
|
|
2975
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
2976
|
+
}
|
|
2977
|
+
function isPlainRecord(value) {
|
|
2978
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2979
|
+
}
|
|
2929
2980
|
|
|
2930
2981
|
// src/adapter-provider.ts
|
|
2931
2982
|
function createConnectorAdapterProvider(options) {
|
|
@@ -3552,10 +3603,12 @@ export {
|
|
|
3552
3603
|
toMcpTools,
|
|
3553
3604
|
twilioSmsConnector,
|
|
3554
3605
|
validateConnectorManifest,
|
|
3606
|
+
validateIntegrationInvocationEnvelope,
|
|
3555
3607
|
verifyCapabilityToken,
|
|
3556
3608
|
verifyHmacSignature,
|
|
3557
3609
|
verifySlackSignature,
|
|
3558
3610
|
verifyStripeSignature,
|
|
3611
|
+
verifyTwilioSignature,
|
|
3559
3612
|
webhookConnector
|
|
3560
3613
|
};
|
|
3561
3614
|
//# sourceMappingURL=index.js.map
|