@anchrd/intel-api 0.2.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 +96 -0
- package/bin/intel.mjs +134 -0
- package/dist/adapters/cloudflare/cloudflare-flow-workflow.d.ts +21 -0
- package/dist/adapters/cloudflare/cloudflare-flow-workflow.js +39 -0
- package/dist/adapters/cloudflare/cloudflare.d.ts +8 -0
- package/dist/adapters/cloudflare/cloudflare.js +200 -0
- package/dist/adapters/cloudflare/cloudflare.types.d.ts +29 -0
- package/dist/adapters/cloudflare/cloudflare.types.js +1 -0
- package/dist/adapters/content/content.d.ts +3 -0
- package/dist/adapters/content/content.js +22 -0
- package/dist/adapters/content/content.types.d.ts +14 -0
- package/dist/adapters/content/content.types.js +1 -0
- package/dist/adapters/db/db-flows.d.ts +6 -0
- package/dist/adapters/db/db-flows.js +466 -0
- package/dist/adapters/db/db-indexing.d.ts +3 -0
- package/dist/adapters/db/db-indexing.js +70 -0
- package/dist/adapters/db/db-oauth.d.ts +3 -0
- package/dist/adapters/db/db-oauth.js +26 -0
- package/dist/adapters/db/db-tools.d.ts +6 -0
- package/dist/adapters/db/db-tools.js +200 -0
- package/dist/adapters/db/db.d.ts +6 -0
- package/dist/adapters/db/db.js +755 -0
- package/dist/adapters/db/db.types.d.ts +16 -0
- package/dist/adapters/db/db.types.js +1 -0
- package/dist/adapters/document-converter/document-converter.d.ts +2 -0
- package/dist/adapters/document-converter/document-converter.js +25 -0
- package/dist/adapters/document-converter/document-converter.types.d.ts +9 -0
- package/dist/adapters/document-converter/document-converter.types.js +1 -0
- package/dist/adapters/flow-runtime/flow-runtime.d.ts +3 -0
- package/dist/adapters/flow-runtime/flow-runtime.js +22 -0
- package/dist/adapters/flow-runtime/flow-runtime.types.d.ts +19 -0
- package/dist/adapters/flow-runtime/flow-runtime.types.js +1 -0
- package/dist/adapters/index-queue/index-queue.d.ts +10 -0
- package/dist/adapters/index-queue/index-queue.js +12 -0
- package/dist/adapters/index-queue/index-queue.types.d.ts +11 -0
- package/dist/adapters/index-queue/index-queue.types.js +1 -0
- package/dist/adapters/json-schema/json-schema.d.ts +2 -0
- package/dist/adapters/json-schema/json-schema.js +31 -0
- package/dist/adapters/openid/openid.d.ts +5 -0
- package/dist/adapters/openid/openid.js +159 -0
- package/dist/adapters/portal-tokens/portal-tokens.d.ts +8 -0
- package/dist/adapters/portal-tokens/portal-tokens.js +71 -0
- package/dist/adapters/remote-tools/remote-tools.d.ts +5 -0
- package/dist/adapters/remote-tools/remote-tools.js +109 -0
- package/dist/adapters/semantic-index/semantic-index.d.ts +2 -0
- package/dist/adapters/semantic-index/semantic-index.js +57 -0
- package/dist/adapters/semantic-index/semantic-index.types.d.ts +32 -0
- package/dist/adapters/semantic-index/semantic-index.types.js +1 -0
- package/dist/adapters/session-cookie/session-cookie.d.ts +5 -0
- package/dist/adapters/session-cookie/session-cookie.js +81 -0
- package/dist/adapters/tool-source-policy/tool-source-policy.d.ts +1 -0
- package/dist/adapters/tool-source-policy/tool-source-policy.js +22 -0
- package/dist/auth/auth.d.ts +2 -0
- package/dist/auth/auth.js +176 -0
- package/dist/auth/auth.types.d.ts +104 -0
- package/dist/auth/auth.types.js +1 -0
- package/dist/build/build.d.ts +2 -0
- package/dist/build/build.js +125 -0
- package/dist/build/build.types.d.ts +17 -0
- package/dist/build/build.types.js +1 -0
- package/dist/cli/cli.d.ts +4 -0
- package/dist/cli/cli.js +141 -0
- package/dist/cli/cli.types.d.ts +14 -0
- package/dist/cli/cli.types.js +1 -0
- package/dist/flows/flows.d.ts +4 -0
- package/dist/flows/flows.js +409 -0
- package/dist/flows/flows.types.d.ts +108 -0
- package/dist/flows/flows.types.js +1 -0
- package/dist/http/http.d.ts +8 -0
- package/dist/http/http.js +286 -0
- package/dist/http/http.types.d.ts +14 -0
- package/dist/http/http.types.js +1 -0
- package/dist/indexing/indexing.d.ts +6 -0
- package/dist/indexing/indexing.js +48 -0
- package/dist/indexing/indexing.types.d.ts +10 -0
- package/dist/indexing/indexing.types.js +1 -0
- package/dist/intel/intel.d.ts +3 -0
- package/dist/intel/intel.js +77 -0
- package/dist/intel/intel.types.d.ts +14 -0
- package/dist/intel/intel.types.js +1 -0
- package/dist/knowledge/knowledge.d.ts +2 -0
- package/dist/knowledge/knowledge.js +479 -0
- package/dist/knowledge/knowledge.types.d.ts +162 -0
- package/dist/knowledge/knowledge.types.js +1 -0
- package/dist/mcp/mcp.d.ts +2 -0
- package/dist/mcp/mcp.js +484 -0
- package/dist/mcp/mcp.types.d.ts +10 -0
- package/dist/mcp/mcp.types.js +1 -0
- package/dist/prepare/prepare.d.ts +4 -0
- package/dist/prepare/prepare.js +16 -0
- package/dist/prepare/prepare.types.d.ts +9 -0
- package/dist/prepare/prepare.types.js +1 -0
- package/dist/shared/gate-authorization/gate-authorization.d.ts +4 -0
- package/dist/shared/gate-authorization/gate-authorization.js +19 -0
- package/dist/shared/intel-error/intel-error.d.ts +5 -0
- package/dist/shared/intel-error/intel-error.js +10 -0
- package/dist/shared/problem-details/problem-details.d.ts +8 -0
- package/dist/shared/problem-details/problem-details.js +4 -0
- package/dist/shared/safe-return-path/safe-return-path.d.ts +2 -0
- package/dist/shared/safe-return-path/safe-return-path.js +11 -0
- package/dist/shared/sha256/sha256.d.ts +1 -0
- package/dist/shared/sha256/sha256.js +9 -0
- package/dist/tools/tools.d.ts +2 -0
- package/dist/tools/tools.js +107 -0
- package/dist/tools/tools.types.d.ts +56 -0
- package/dist/tools/tools.types.js +1 -0
- package/examples/branding/favicon.svg +5 -0
- package/examples/branding/logo.svg +5 -0
- package/examples/branding/theme.css +16 -0
- package/examples/dev.vars.example +7 -0
- package/examples/intel.json +9 -0
- package/migrations/0000_intel_foundation.sql +203 -0
- package/migrations/0001_portal_native_tools.sql +21 -0
- package/package.json +62 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { ToolAnnotations, ToolCapability, ToolSource, } from "@anchrd/intel-contract";
|
|
2
|
+
const sourceColumns = `source.id, source.name, source.url, source.connection_handle,
|
|
3
|
+
source.enabled, source.created_by, source.created_at, source.updated_at,
|
|
4
|
+
source.last_discovered_at`;
|
|
5
|
+
const catalogColumns = `${sourceColumns}, tool.name AS tool_name, tool.title AS tool_title,
|
|
6
|
+
tool.description AS tool_description, tool.input_schema_json, tool.output_schema_json,
|
|
7
|
+
tool.annotations_json, tool.fingerprint, tool.discovered_at`;
|
|
8
|
+
// Predicate and bindings are produced together: the placeholder count depends on the roles filter,
|
|
9
|
+
// so returning them separately would let a caller shift every binding without the compiler noticing.
|
|
10
|
+
// An empty roles array means "any role", because `IN ()` is invalid SQL.
|
|
11
|
+
function access(actor, now, roles = []) {
|
|
12
|
+
const role = roles.length ? `AND grant_row.role IN (${roles.map(() => "?").join(", ")})` : "";
|
|
13
|
+
return {
|
|
14
|
+
sql: `(source.created_by = ? OR EXISTS (
|
|
15
|
+
SELECT 1 FROM resource_grants grant_row
|
|
16
|
+
WHERE grant_row.resource_type = 'tool-source' AND grant_row.resource_id = source.id
|
|
17
|
+
AND (
|
|
18
|
+
(grant_row.principal_type = 'user' AND grant_row.principal_id = ?)
|
|
19
|
+
OR (grant_row.principal_type = 'email' AND lower(grant_row.principal_id) = lower(?))
|
|
20
|
+
OR (grant_row.principal_type = 'organization' AND grant_row.principal_id = '*')
|
|
21
|
+
)
|
|
22
|
+
${role}
|
|
23
|
+
AND (grant_row.expires_at IS NULL OR grant_row.expires_at > ?)
|
|
24
|
+
))`,
|
|
25
|
+
bindings: [actor.id, actor.id, actor.email, ...roles, now],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function mapSource(row) {
|
|
29
|
+
return ToolSource.parse({
|
|
30
|
+
id: row.id,
|
|
31
|
+
name: row.name,
|
|
32
|
+
url: row.url,
|
|
33
|
+
connectionHandle: row.connection_handle,
|
|
34
|
+
enabled: row.enabled === 1,
|
|
35
|
+
createdBy: row.created_by,
|
|
36
|
+
createdAt: row.created_at,
|
|
37
|
+
updatedAt: row.updated_at,
|
|
38
|
+
lastDiscoveredAt: row.last_discovered_at,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function mapCapability(row) {
|
|
42
|
+
return ToolCapability.parse({
|
|
43
|
+
sourceId: row.id,
|
|
44
|
+
name: row.tool_name,
|
|
45
|
+
title: row.tool_title,
|
|
46
|
+
description: row.tool_description,
|
|
47
|
+
inputSchema: JSON.parse(row.input_schema_json),
|
|
48
|
+
outputSchema: row.output_schema_json ? JSON.parse(row.output_schema_json) : null,
|
|
49
|
+
annotations: ToolAnnotations.parse(JSON.parse(row.annotations_json)),
|
|
50
|
+
fingerprint: row.fingerprint,
|
|
51
|
+
discoveredAt: row.discovered_at,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export function createToolRepository(deps) {
|
|
55
|
+
const db = deps.db;
|
|
56
|
+
return {
|
|
57
|
+
async listVisible(actor) {
|
|
58
|
+
const allowed = access(actor, deps.now().toISOString());
|
|
59
|
+
const result = await db
|
|
60
|
+
.prepare(`SELECT ${sourceColumns} FROM tool_sources source
|
|
61
|
+
WHERE ${allowed.sql} ORDER BY lower(source.name), source.id`)
|
|
62
|
+
.bind(...allowed.bindings)
|
|
63
|
+
.all();
|
|
64
|
+
return (result.results ?? []).map(mapSource);
|
|
65
|
+
},
|
|
66
|
+
async getVisible(actor, sourceId) {
|
|
67
|
+
const allowed = access(actor, deps.now().toISOString());
|
|
68
|
+
const row = await db
|
|
69
|
+
.prepare(`SELECT ${sourceColumns} FROM tool_sources source
|
|
70
|
+
WHERE source.id = ? AND ${allowed.sql}`)
|
|
71
|
+
.bind(sourceId, ...allowed.bindings)
|
|
72
|
+
.first();
|
|
73
|
+
return row ? mapSource(row) : null;
|
|
74
|
+
},
|
|
75
|
+
async canManage(actor, sourceId) {
|
|
76
|
+
const permitted = access(actor, deps.now().toISOString(), ["manager"]);
|
|
77
|
+
const row = await db
|
|
78
|
+
.prepare(`SELECT 1 AS allowed FROM tool_sources source
|
|
79
|
+
WHERE source.id = ? AND ${permitted.sql}`)
|
|
80
|
+
.bind(sourceId, ...permitted.bindings)
|
|
81
|
+
.first();
|
|
82
|
+
return row?.allowed === 1;
|
|
83
|
+
},
|
|
84
|
+
async findIdempotent(actorId, operation, key) {
|
|
85
|
+
const row = await db
|
|
86
|
+
.prepare(`SELECT resource_id FROM idempotency_keys
|
|
87
|
+
WHERE actor_id = ? AND operation = ? AND idempotency_key = ?`)
|
|
88
|
+
.bind(actorId, operation, key)
|
|
89
|
+
.first();
|
|
90
|
+
return row?.resource_id ?? null;
|
|
91
|
+
},
|
|
92
|
+
async insertSource(input) {
|
|
93
|
+
const source = input.source;
|
|
94
|
+
try {
|
|
95
|
+
await db.batch([
|
|
96
|
+
db
|
|
97
|
+
.prepare(`INSERT INTO tool_sources (
|
|
98
|
+
id, name, url, connection_handle, enabled, created_by,
|
|
99
|
+
created_at, updated_at, last_discovered_at
|
|
100
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
101
|
+
.bind(source.id, source.name, source.url, source.connectionHandle, source.enabled ? 1 : 0, source.createdBy, source.createdAt, source.updatedAt, source.lastDiscoveredAt),
|
|
102
|
+
db
|
|
103
|
+
.prepare(`INSERT INTO resource_grants (
|
|
104
|
+
id, resource_type, resource_id, principal_type, principal_id, role,
|
|
105
|
+
expires_at, created_by, created_at
|
|
106
|
+
) VALUES (?, 'tool-source', ?, 'organization', '*', 'viewer', NULL, ?, ?)`)
|
|
107
|
+
.bind(input.grantId, source.id, source.createdBy, source.createdAt),
|
|
108
|
+
db
|
|
109
|
+
.prepare(`INSERT INTO idempotency_keys (
|
|
110
|
+
actor_id, operation, idempotency_key, resource_id, created_at
|
|
111
|
+
) VALUES (?, 'tools.create', ?, ?, ?)`)
|
|
112
|
+
.bind(source.createdBy, input.idempotencyKey, source.id, source.createdAt),
|
|
113
|
+
db
|
|
114
|
+
.prepare(`INSERT INTO audit_events (
|
|
115
|
+
id, actor_id, action, resource_type, resource_id, metadata_json, occurred_at
|
|
116
|
+
) VALUES (?, ?, 'tools.create', 'tool-source', ?, ?, ?)`)
|
|
117
|
+
.bind(input.auditId, source.createdBy, source.id, JSON.stringify({ name: source.name, url: source.url }), source.createdAt),
|
|
118
|
+
]);
|
|
119
|
+
return source;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
const replayedId = await this.findIdempotent(source.createdBy, "tools.create", input.idempotencyKey);
|
|
123
|
+
const replayed = replayedId
|
|
124
|
+
? await db
|
|
125
|
+
.prepare(`SELECT ${sourceColumns} FROM tool_sources source WHERE source.id = ?`)
|
|
126
|
+
.bind(replayedId)
|
|
127
|
+
.first()
|
|
128
|
+
: null;
|
|
129
|
+
if (replayed)
|
|
130
|
+
return mapSource(replayed);
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
async replaceCatalog(input) {
|
|
135
|
+
const replayed = await this.findIdempotent(input.actorId, "tools.discover", input.idempotencyKey);
|
|
136
|
+
if (replayed)
|
|
137
|
+
return;
|
|
138
|
+
const statements = [
|
|
139
|
+
db.prepare("DELETE FROM tool_catalog WHERE source_id = ?").bind(input.sourceId),
|
|
140
|
+
...input.capabilities.map((capability) => db
|
|
141
|
+
.prepare(`INSERT INTO tool_catalog (
|
|
142
|
+
source_id, name, title, description, input_schema_json, output_schema_json,
|
|
143
|
+
annotations_json, fingerprint, discovered_at
|
|
144
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
145
|
+
.bind(capability.sourceId, capability.name, capability.title, capability.description, JSON.stringify(capability.inputSchema), capability.outputSchema ? JSON.stringify(capability.outputSchema) : null, JSON.stringify(capability.annotations), capability.fingerprint, capability.discoveredAt)),
|
|
146
|
+
db
|
|
147
|
+
.prepare(`UPDATE tool_sources
|
|
148
|
+
SET last_discovered_at = ?, updated_at = ?
|
|
149
|
+
WHERE id = ?`)
|
|
150
|
+
.bind(input.discoveredAt, input.discoveredAt, input.sourceId),
|
|
151
|
+
db
|
|
152
|
+
.prepare(`INSERT INTO idempotency_keys (
|
|
153
|
+
actor_id, operation, idempotency_key, resource_id, created_at
|
|
154
|
+
) VALUES (?, 'tools.discover', ?, ?, ?)`)
|
|
155
|
+
.bind(input.actorId, input.idempotencyKey, input.sourceId, input.discoveredAt),
|
|
156
|
+
db
|
|
157
|
+
.prepare(`INSERT INTO audit_events (
|
|
158
|
+
id, actor_id, action, resource_type, resource_id, metadata_json, occurred_at
|
|
159
|
+
) VALUES (?, ?, 'tools.discover', 'tool-source', ?, ?, ?)`)
|
|
160
|
+
.bind(input.auditId, input.actorId, input.sourceId, JSON.stringify({ toolCount: input.capabilities.length }), input.discoveredAt),
|
|
161
|
+
];
|
|
162
|
+
try {
|
|
163
|
+
await db.batch(statements);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
const concurrentReplay = await this.findIdempotent(input.actorId, "tools.discover", input.idempotencyKey);
|
|
167
|
+
if (concurrentReplay === input.sourceId)
|
|
168
|
+
return;
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
async listCatalogVisible(actor) {
|
|
173
|
+
const allowed = access(actor, deps.now().toISOString());
|
|
174
|
+
const result = await db
|
|
175
|
+
.prepare(`SELECT ${catalogColumns}
|
|
176
|
+
FROM tool_catalog tool
|
|
177
|
+
JOIN tool_sources source ON source.id = tool.source_id
|
|
178
|
+
WHERE source.enabled = 1 AND ${allowed.sql}
|
|
179
|
+
ORDER BY lower(source.name), lower(coalesce(tool.title, tool.name)), tool.name`)
|
|
180
|
+
.bind(...allowed.bindings)
|
|
181
|
+
.all();
|
|
182
|
+
return (result.results ?? []).map((row) => ({
|
|
183
|
+
source: mapSource(row),
|
|
184
|
+
capability: mapCapability(row),
|
|
185
|
+
}));
|
|
186
|
+
},
|
|
187
|
+
async getCapabilityVisible(actor, sourceId, name) {
|
|
188
|
+
const allowed = access(actor, deps.now().toISOString());
|
|
189
|
+
const row = await db
|
|
190
|
+
.prepare(`SELECT ${catalogColumns}
|
|
191
|
+
FROM tool_catalog tool
|
|
192
|
+
JOIN tool_sources source ON source.id = tool.source_id
|
|
193
|
+
WHERE source.id = ? AND tool.name = ? AND source.enabled = 1
|
|
194
|
+
AND ${allowed.sql}`)
|
|
195
|
+
.bind(sourceId, name, ...allowed.bindings)
|
|
196
|
+
.first();
|
|
197
|
+
return row ? mapCapability(row) : null;
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
}
|