@tangle-network/agent-integrations 0.7.0 → 0.7.1
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 +146 -161
- package/examples/basic-hub.ts +47 -0
- package/examples/declarative-rest.ts +27 -0
- package/examples/first-party-adapter.ts +32 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,173 +1,158 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
# @tangle-network/agent-integrations
|
|
2
|
+
|
|
3
|
+
Vendor-neutral integration contracts for agent apps, sandboxes, and generated
|
|
4
|
+
software that need user-authorized access to external systems.
|
|
5
|
+
|
|
6
|
+
The package standardizes connector catalogs, user connections, scoped sandbox
|
|
7
|
+
capabilities, action invocation, trigger events, provider adapters, and
|
|
8
|
+
first-party connector adapters. Product code can route through Nango, Pipedream,
|
|
9
|
+
Activepieces, a custom gateway, or first-party adapters without changing the
|
|
10
|
+
agent-facing tool contract.
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- [What It Provides](#what-it-provides)
|
|
15
|
+
- [Architecture](#architecture)
|
|
16
|
+
- [Install](#install)
|
|
17
|
+
- [Core Primitives](#core-primitives)
|
|
18
|
+
- [Provider Strategy](#provider-strategy)
|
|
19
|
+
- [Executable Coverage](#executable-coverage)
|
|
20
|
+
- [Examples](#examples)
|
|
21
|
+
- [Security Model](#security-model)
|
|
22
|
+
- [Development](#development)
|
|
23
|
+
|
|
24
|
+
## What It Provides
|
|
25
|
+
|
|
26
|
+
- A normalized connector/action/trigger catalog.
|
|
27
|
+
- User-owned connection records that reference secrets without storing raw
|
|
28
|
+
credentials in public shapes.
|
|
29
|
+
- Short-lived capability tokens for sandbox-safe access to a subset of a user's
|
|
30
|
+
connection.
|
|
31
|
+
- Policy checks for read/write/destructive actions.
|
|
32
|
+
- Invocation-envelope validation before sandbox tool calls reach the hub.
|
|
33
|
+
- A generic HTTP provider boundary for hosted integration gateways.
|
|
34
|
+
- A first-party `ConnectorAdapter` boundary for direct provider execution.
|
|
35
|
+
- A declarative REST adapter factory for promoting REST APIs from reviewed specs.
|
|
36
|
+
- A broad coverage catalog for planning hundreds of integrations without
|
|
37
|
+
pretending every catalog item is executable.
|
|
38
|
+
|
|
39
|
+
## Architecture
|
|
12
40
|
|
|
13
41
|
```txt
|
|
14
|
-
|
|
42
|
+
connector catalog
|
|
43
|
+
-> user connection
|
|
44
|
+
-> scoped capability
|
|
45
|
+
-> policy decision
|
|
46
|
+
-> provider/action invocation
|
|
47
|
+
-> audit-safe result or normalized trigger event
|
|
15
48
|
```
|
|
16
49
|
|
|
17
|
-
|
|
18
|
-
HubSpot, webhooks, internal tools.
|
|
19
|
-
- **Connections** are user/team-owned grants. They carry secret references, not
|
|
20
|
-
raw credentials.
|
|
21
|
-
- **Capabilities** are short-lived, sandbox-safe tokens that authorize a subset
|
|
22
|
-
of actions on a connection.
|
|
23
|
-
- **Actions** are read/write/destructive operations.
|
|
24
|
-
- **Triggers** normalize inbound events from providers into one event shape.
|
|
25
|
-
|
|
26
|
-
## Why This Exists
|
|
27
|
-
|
|
28
|
-
Agent Builder and sandbox apps need to support prompts like:
|
|
29
|
-
|
|
30
|
-
```txt
|
|
31
|
-
At Gmail, build me an app that summarizes unread support emails and drafts replies.
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
The generated app should be able to request Gmail access, instantiate inside the
|
|
35
|
-
user's sandbox, and let the agent read/write through a scoped integration
|
|
36
|
-
capability. The sandbox should never receive reusable provider secrets.
|
|
37
|
-
|
|
38
|
-
## Core Usage
|
|
39
|
-
|
|
40
|
-
### Product Flow
|
|
50
|
+
Main boundaries:
|
|
41
51
|
|
|
42
|
-
|
|
52
|
+
- `IntegrationHub`: product-facing facade for catalogs, connections,
|
|
53
|
+
capabilities, and action invocation.
|
|
54
|
+
- `IntegrationProvider`: vendor or gateway implementation boundary.
|
|
55
|
+
- `ConnectorAdapter`: first-party connector boundary for direct API execution.
|
|
56
|
+
- `IntegrationActionGuard`: optional cross-cutting hook for idempotency,
|
|
57
|
+
approval, audit logging, rate limits, and conflict handling.
|
|
43
58
|
|
|
44
|
-
|
|
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
|
-
```
|
|
59
|
+
## Install
|
|
53
60
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- `buildIntegrationToolCatalog` and `searchIntegrationTools` for discoverable
|
|
57
|
-
tool catalogs.
|
|
58
|
-
- `buildIntegrationCoverageConnectors` for broad planning coverage across
|
|
59
|
-
100+ high-value integrations before each one has a first-party executor.
|
|
60
|
-
- `toMcpTools` for MCP-compatible tool export.
|
|
61
|
-
- `IntegrationHub.issueCapability` for scoped sandbox handoff.
|
|
62
|
-
- `createDefaultIntegrationPolicyEngine` for allow / approval / deny decisions.
|
|
63
|
-
- `buildIntegrationInvocationEnvelope` and
|
|
64
|
-
`validateIntegrationInvocationEnvelope` for sandbox-safe tool calls with
|
|
65
|
-
action/tool consistency, idempotency-key, metadata-shape, known-tool, and
|
|
66
|
-
input-size checks.
|
|
67
|
-
- `createConnectorAdapterProvider` to run first-party adapters through the hub.
|
|
68
|
-
- `declarativeRestConnector` to promote REST-shaped providers from compact,
|
|
69
|
-
reviewed specs instead of hand-writing one brittle adapter per API.
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
import {
|
|
73
|
-
InMemoryConnectionStore,
|
|
74
|
-
IntegrationHub,
|
|
75
|
-
buildIntegrationToolCatalog,
|
|
76
|
-
createMockIntegrationProvider,
|
|
77
|
-
searchIntegrationTools,
|
|
78
|
-
} from '@tangle-network/agent-integrations'
|
|
79
|
-
|
|
80
|
-
const provider = createMockIntegrationProvider()
|
|
81
|
-
const hub = new IntegrationHub({
|
|
82
|
-
providers: [provider],
|
|
83
|
-
store: new InMemoryConnectionStore(),
|
|
84
|
-
capabilitySecret: 'dev-secret',
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
const catalog = buildIntegrationToolCatalog(await hub.listConnectors())
|
|
88
|
-
const tools = searchIntegrationTools(catalog, 'search unread gmail', { maxRisk: 'read' })
|
|
89
|
-
|
|
90
|
-
const connection = await hub.upsertConnection({
|
|
91
|
-
id: 'conn_1',
|
|
92
|
-
owner: { type: 'user', id: 'user_1' },
|
|
93
|
-
providerId: 'mock',
|
|
94
|
-
connectorId: 'gmail',
|
|
95
|
-
status: 'active',
|
|
96
|
-
grantedScopes: ['email.read'],
|
|
97
|
-
createdAt: new Date().toISOString(),
|
|
98
|
-
updatedAt: new Date().toISOString(),
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
const capability = await hub.issueCapability({
|
|
102
|
-
subject: { type: 'sandbox', id: 'sandbox_1' },
|
|
103
|
-
connectionId: connection.id,
|
|
104
|
-
scopes: ['email.read'],
|
|
105
|
-
allowedActions: ['messages.search'],
|
|
106
|
-
ttlMs: 60_000,
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
const result = await hub.invokeWithCapability(capability.token, {
|
|
110
|
-
action: 'messages.search',
|
|
111
|
-
input: { q: 'is:unread' },
|
|
112
|
-
})
|
|
61
|
+
```sh
|
|
62
|
+
pnpm add @tangle-network/agent-integrations
|
|
113
63
|
```
|
|
114
64
|
|
|
115
|
-
##
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
65
|
+
## Core Primitives
|
|
66
|
+
|
|
67
|
+
| Primitive | Purpose |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `IntegrationConnector` | Normalized catalog entry for a provider connection. |
|
|
70
|
+
| `IntegrationConnection` | User/team/agent-owned grant with scopes and secret references. |
|
|
71
|
+
| `IntegrationHub` | Facade for provider catalogs, connection storage, capabilities, and invocation. |
|
|
72
|
+
| `IntegrationCapability` | Short-lived authorization for a specific subject, connection, scope set, and action set. |
|
|
73
|
+
| `buildIntegrationToolCatalog` | Converts connector actions into agent/tool definitions. |
|
|
74
|
+
| `searchIntegrationTools` | Intent search over normalized integration tools. |
|
|
75
|
+
| `buildIntegrationCoverageConnectors` | Planning catalog for 100+ high-value integrations. |
|
|
76
|
+
| `buildIntegrationInvocationEnvelope` | Sandbox-safe action envelope. |
|
|
77
|
+
| `validateIntegrationInvocationEnvelope` | Runtime validation for tool/action consistency and input limits. |
|
|
78
|
+
| `createHttpIntegrationProvider` | Adapter for hosted integration gateways. |
|
|
79
|
+
| `createConnectorAdapterProvider` | Runs first-party `ConnectorAdapter`s through the same provider contract. |
|
|
80
|
+
| `declarativeRestConnector` | Builds REST-backed first-party adapters from compact specs. |
|
|
81
|
+
|
|
82
|
+
## Provider Strategy
|
|
83
|
+
|
|
84
|
+
The package deliberately avoids vendor lock-in.
|
|
85
|
+
|
|
86
|
+
- Use a hosted gateway when it compresses long-tail OAuth/API coverage.
|
|
87
|
+
- Promote high-volume, sensitive, or strategically important integrations to
|
|
88
|
+
first-party adapters.
|
|
89
|
+
- Keep product and sandbox code on `IntegrationHub` contracts so provider changes
|
|
90
|
+
do not alter generated apps or agent tool calls.
|
|
91
|
+
- Treat catalog coverage and executable coverage as different states.
|
|
92
|
+
|
|
93
|
+
See [Provider Decision Matrix](./docs/provider-decision-matrix.md).
|
|
94
|
+
|
|
95
|
+
## Executable Coverage
|
|
96
|
+
|
|
97
|
+
Current first-party adapters:
|
|
98
|
+
|
|
99
|
+
- Google Calendar
|
|
100
|
+
- Microsoft Calendar
|
|
101
|
+
- Google Sheets
|
|
102
|
+
- Slack
|
|
103
|
+
- Slack Events
|
|
104
|
+
- HubSpot
|
|
105
|
+
- Notion database
|
|
106
|
+
- Stripe payments pack
|
|
107
|
+
- Stripe webhook receiver
|
|
108
|
+
- Twilio SMS
|
|
109
|
+
- Generic webhook
|
|
110
|
+
- GitHub
|
|
111
|
+
- GitLab
|
|
112
|
+
- Airtable
|
|
113
|
+
- Asana
|
|
114
|
+
- Salesforce
|
|
115
|
+
|
|
116
|
+
Broad planning coverage is generated from
|
|
117
|
+
`buildIntegrationCoverageConnectors()` and tracked in
|
|
118
|
+
[Integration Coverage Checklist](./docs/integration-coverage-checklist.md).
|
|
119
|
+
|
|
120
|
+
## Examples
|
|
121
|
+
|
|
122
|
+
Runnable examples live in [`examples/`](./examples):
|
|
123
|
+
|
|
124
|
+
- [`examples/basic-hub.ts`](./examples/basic-hub.ts) - catalog search,
|
|
125
|
+
connection storage, capability issue, and action invocation.
|
|
126
|
+
- [`examples/first-party-adapter.ts`](./examples/first-party-adapter.ts) -
|
|
127
|
+
first-party adapter provider wiring.
|
|
128
|
+
- [`examples/declarative-rest.ts`](./examples/declarative-rest.ts) - compact
|
|
129
|
+
REST connector spec.
|
|
130
|
+
|
|
131
|
+
The README stays short; examples are separate so they can be copied and expanded
|
|
132
|
+
without obscuring the package contract.
|
|
133
|
+
|
|
134
|
+
## Security Model
|
|
135
|
+
|
|
136
|
+
- Capability tokens expire.
|
|
137
|
+
- Capability tokens do not contain provider credentials.
|
|
138
|
+
- Connection records carry secret references, not raw secrets.
|
|
139
|
+
- Write and destructive actions can require approval.
|
|
140
|
+
- Invocation envelopes validate action/tool consistency, idempotency keys,
|
|
141
|
+
metadata shape, known tools, and input size.
|
|
142
|
+
- Action invocation checks ownership, connection status, scopes, allowed actions,
|
|
143
|
+
and expiration.
|
|
144
|
+
- `IntegrationActionGuard` can enforce idempotency, approval, audit logging,
|
|
145
|
+
conflict handling, and rate limits across all providers.
|
|
146
|
+
|
|
147
|
+
## Development
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
pnpm install
|
|
151
|
+
pnpm typecheck
|
|
152
|
+
pnpm test
|
|
153
|
+
pnpm build
|
|
136
154
|
```
|
|
137
155
|
|
|
138
|
-
|
|
139
|
-
Nango, Pipedream, Activepieces, a Zapier-style service, or an internal gateway.
|
|
140
|
-
|
|
141
|
-
For first-party REST APIs, use the declarative adapter factory:
|
|
142
|
-
|
|
143
|
-
```ts
|
|
144
|
-
import { createConnectorAdapterProvider, githubConnector } from '@tangle-network/agent-integrations'
|
|
145
|
-
|
|
146
|
-
const provider = createConnectorAdapterProvider({
|
|
147
|
-
adapters: [githubConnector],
|
|
148
|
-
resolveDataSource: async (connection) => loadSourceAndCredentials(connection),
|
|
149
|
-
})
|
|
150
|
-
```
|
|
156
|
+
## License
|
|
151
157
|
|
|
152
|
-
|
|
153
|
-
Google Sheets, Slack, HubSpot, Notion database, Stripe, Twilio, webhooks,
|
|
154
|
-
GitHub, GitLab, Airtable, Asana, and Salesforce.
|
|
155
|
-
|
|
156
|
-
See [Provider Decision Matrix](./docs/provider-decision-matrix.md) for the
|
|
157
|
-
build-vs-buy policy. The short version: use a vendor gateway only to compress
|
|
158
|
-
time-to-coverage, but keep all product and sandbox code on this package's
|
|
159
|
-
contracts so high-volume or strategic connectors can be moved first-party
|
|
160
|
-
without changing agent code.
|
|
161
|
-
|
|
162
|
-
## Security Defaults
|
|
163
|
-
|
|
164
|
-
- Capabilities expire.
|
|
165
|
-
- Capability tokens contain no provider credential.
|
|
166
|
-
- Secret refs are redacted from public telemetry.
|
|
167
|
-
- Write/destructive actions can be policy-gated.
|
|
168
|
-
- Sandbox invocation envelopes are validated before conversion to hub requests.
|
|
169
|
-
- Action invocation checks connection ownership, status, scopes, allowed
|
|
170
|
-
actions, and expiration.
|
|
171
|
-
- Optional `IntegrationActionGuard` wraps every action invocation for
|
|
172
|
-
idempotency, audit logging, conflict detection, rate limits, and
|
|
173
|
-
approval gates.
|
|
158
|
+
MIT
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
InMemoryConnectionStore,
|
|
3
|
+
IntegrationHub,
|
|
4
|
+
buildIntegrationToolCatalog,
|
|
5
|
+
createMockIntegrationProvider,
|
|
6
|
+
searchIntegrationTools,
|
|
7
|
+
} from '@tangle-network/agent-integrations'
|
|
8
|
+
|
|
9
|
+
const provider = createMockIntegrationProvider()
|
|
10
|
+
const store = new InMemoryConnectionStore()
|
|
11
|
+
const hub = new IntegrationHub({
|
|
12
|
+
providers: [provider],
|
|
13
|
+
store,
|
|
14
|
+
capabilitySecret: 'replace-with-secret-manager-value',
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const tools = searchIntegrationTools(
|
|
18
|
+
buildIntegrationToolCatalog(await hub.listConnectors()),
|
|
19
|
+
'email search',
|
|
20
|
+
{ maxRisk: 'read' },
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const connection = await hub.upsertConnection({
|
|
24
|
+
id: 'conn_1',
|
|
25
|
+
owner: { type: 'user', id: 'user_1' },
|
|
26
|
+
providerId: 'mock',
|
|
27
|
+
connectorId: 'gmail',
|
|
28
|
+
status: 'active',
|
|
29
|
+
grantedScopes: ['email.read'],
|
|
30
|
+
createdAt: new Date().toISOString(),
|
|
31
|
+
updatedAt: new Date().toISOString(),
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const capability = await hub.issueCapability({
|
|
35
|
+
subject: { type: 'sandbox', id: 'sandbox_1' },
|
|
36
|
+
connectionId: connection.id,
|
|
37
|
+
scopes: ['email.read'],
|
|
38
|
+
allowedActions: [tools[0]!.tool.action.id],
|
|
39
|
+
ttlMs: 60_000,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const result = await hub.invokeWithCapability(capability.token, {
|
|
43
|
+
action: tools[0]!.tool.action.id,
|
|
44
|
+
input: { q: 'is:unread' },
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
console.log(result)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { declarativeRestConnector } from '@tangle-network/agent-integrations'
|
|
2
|
+
|
|
3
|
+
export const statusApiConnector = declarativeRestConnector({
|
|
4
|
+
kind: 'status-api',
|
|
5
|
+
displayName: 'Status API',
|
|
6
|
+
description: 'Read service health from an internal status endpoint.',
|
|
7
|
+
auth: { kind: 'api-key', hint: 'Status API token.' },
|
|
8
|
+
category: 'other',
|
|
9
|
+
defaultConsistencyModel: 'authoritative',
|
|
10
|
+
baseUrl: 'https://status.example.com/api',
|
|
11
|
+
capabilities: [
|
|
12
|
+
{
|
|
13
|
+
name: 'services.get',
|
|
14
|
+
class: 'read',
|
|
15
|
+
description: 'Read one service status.',
|
|
16
|
+
parameters: {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: { serviceId: { type: 'string' } },
|
|
19
|
+
required: ['serviceId'],
|
|
20
|
+
},
|
|
21
|
+
request: {
|
|
22
|
+
method: 'GET',
|
|
23
|
+
path: '/services/{serviceId}',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createConnectorAdapterProvider,
|
|
3
|
+
githubConnector,
|
|
4
|
+
type IntegrationConnection,
|
|
5
|
+
type ResolvedDataSource,
|
|
6
|
+
} from '@tangle-network/agent-integrations'
|
|
7
|
+
|
|
8
|
+
const provider = createConnectorAdapterProvider({
|
|
9
|
+
adapters: [githubConnector],
|
|
10
|
+
resolveDataSource,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const connectors = await provider.listConnectors()
|
|
14
|
+
console.log(connectors.map((connector) => connector.id))
|
|
15
|
+
|
|
16
|
+
async function resolveDataSource(connection: IntegrationConnection): Promise<ResolvedDataSource> {
|
|
17
|
+
return {
|
|
18
|
+
id: `source_${connection.id}`,
|
|
19
|
+
projectId: 'project_1',
|
|
20
|
+
publishedAgentId: null,
|
|
21
|
+
kind: connection.connectorId,
|
|
22
|
+
label: connection.connectorId,
|
|
23
|
+
consistencyModel: 'authoritative',
|
|
24
|
+
scopes: connection.grantedScopes,
|
|
25
|
+
metadata: {},
|
|
26
|
+
credentials: {
|
|
27
|
+
kind: 'api-key',
|
|
28
|
+
apiKey: process.env.GITHUB_TOKEN ?? '',
|
|
29
|
+
},
|
|
30
|
+
status: 'active',
|
|
31
|
+
}
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-integrations",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Vendor-neutral integration contracts and runtime helpers for sandbox and agent apps.",
|
|
5
5
|
"homepage": "https://github.com/tangle-network/agent-integrations#readme",
|
|
6
6
|
"repository": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"files": [
|
|
24
24
|
"dist",
|
|
25
25
|
"docs",
|
|
26
|
+
"examples",
|
|
26
27
|
"README.md"
|
|
27
28
|
],
|
|
28
29
|
"publishConfig": {
|