@inkeep/agents-core 0.42.0 → 0.44.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/dist/auth/auth.d.ts +28 -26
- package/dist/auth/auth.js +21 -16
- package/dist/auth/authz/client.d.ts +8 -3
- package/dist/auth/authz/client.js +23 -17
- package/dist/auth/authz/config.d.ts +50 -29
- package/dist/auth/authz/config.js +42 -33
- package/dist/auth/authz/index.d.ts +3 -3
- package/dist/auth/authz/index.js +3 -3
- package/dist/auth/authz/permissions.d.ts +0 -4
- package/dist/auth/authz/permissions.js +9 -13
- package/dist/auth/authz/sync.d.ts +23 -2
- package/dist/auth/authz/sync.js +127 -53
- package/dist/auth/init.d.ts +1 -0
- package/dist/auth/init.js +115 -0
- package/dist/auth/permissions.d.ts +9 -9
- package/dist/client-exports.d.ts +3 -6
- package/dist/client-exports.js +4 -7
- package/dist/constants/execution-limits-shared/defaults.d.ts +1 -1
- package/dist/constants/execution-limits-shared/defaults.js +1 -1
- package/dist/constants/execution-limits-shared/index.d.ts +1 -1
- package/dist/constants/otel-attributes.d.ts +5 -0
- package/dist/constants/otel-attributes.js +8 -3
- package/dist/constants/signoz-queries.d.ts +1 -0
- package/dist/constants/signoz-queries.js +2 -1
- package/dist/context/TemplateEngine.d.ts +0 -6
- package/dist/context/TemplateEngine.js +4 -18
- package/dist/credential-stores/keychain-store.d.ts +20 -8
- package/dist/credential-stores/keychain-store.js +107 -43
- package/dist/data-access/index.d.ts +5 -4
- package/dist/data-access/index.js +5 -4
- package/dist/data-access/manage/agentFull.js +70 -25
- package/dist/data-access/manage/agents.d.ts +41 -41
- package/dist/data-access/manage/agents.js +29 -21
- package/dist/data-access/manage/artifactComponents.d.ts +12 -12
- package/dist/data-access/manage/artifactComponents.js +1 -1
- package/dist/data-access/manage/contextConfigs.d.ts +12 -12
- package/dist/data-access/manage/dataComponents.d.ts +6 -6
- package/dist/data-access/manage/dataComponents.js +1 -1
- package/dist/data-access/manage/functionTools.d.ts +44 -21
- package/dist/data-access/manage/functionTools.js +34 -22
- package/dist/data-access/manage/subAgentExternalAgentRelations.d.ts +24 -24
- package/dist/data-access/manage/subAgentRelations.d.ts +26 -26
- package/dist/data-access/manage/subAgentTeamAgentRelations.d.ts +18 -18
- package/dist/data-access/manage/subAgents.d.ts +15 -15
- package/dist/data-access/manage/tools.d.ts +39 -28
- package/dist/data-access/manage/tools.js +73 -31
- package/dist/data-access/manage/triggers.d.ts +27 -1
- package/dist/data-access/runtime/apiKeys.d.ts +20 -20
- package/dist/data-access/runtime/cascade-delete.d.ts +48 -1
- package/dist/data-access/runtime/cascade-delete.js +52 -2
- package/dist/data-access/runtime/conversations.d.ts +24 -24
- package/dist/data-access/runtime/github-work-app-installations.d.ts +261 -0
- package/dist/data-access/runtime/github-work-app-installations.js +457 -0
- package/dist/data-access/runtime/messages.d.ts +18 -18
- package/dist/data-access/runtime/organizations.d.ts +2 -2
- package/dist/data-access/runtime/organizations.js +4 -4
- package/dist/data-access/runtime/tasks.d.ts +6 -6
- package/dist/db/manage/manage-schema.d.ts +533 -402
- package/dist/db/manage/manage-schema.js +38 -27
- package/dist/db/runtime/runtime-schema.d.ts +1021 -177
- package/dist/db/runtime/runtime-schema.js +173 -5
- package/dist/db/utils.d.ts +6 -0
- package/dist/db/utils.js +42 -0
- package/dist/dolt/branch.js +1 -1
- package/dist/dolt/branches-api.js +1 -1
- package/dist/dolt/index.d.ts +2 -2
- package/dist/dolt/index.js +4 -4
- package/dist/dolt/migrate-all-branches.js +6 -1
- package/dist/dolt/migrate-dolt.js +4 -1
- package/dist/dolt/ref-helpers.js +1 -1
- package/dist/dolt/ref-middleware.js +1 -1
- package/dist/dolt/ref-scope.js +1 -1
- package/dist/dolt/schema-sync.d.ts +2 -1
- package/dist/dolt/schema-sync.js +10 -1
- package/dist/env.d.ts +6 -4
- package/dist/env.js +11 -10
- package/dist/index.d.ts +15 -16
- package/dist/index.js +23 -24
- package/dist/types/@napi-rs__keyring/index.d.ts +14 -0
- package/dist/types/entities.d.ts +9 -2
- package/dist/types/index.d.ts +3 -3
- package/dist/types/utility.d.ts +17 -3
- package/dist/types/utility.js +2 -1
- package/dist/utils/JsonTransformer.d.ts +1 -3
- package/dist/utils/JsonTransformer.js +14 -23
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +3 -3
- package/dist/utils/jmespath-utils.d.ts +152 -0
- package/dist/utils/jmespath-utils.js +213 -0
- package/dist/utils/mcp-client.d.ts +1 -1
- package/dist/utils/mcp-client.js +1 -1
- package/dist/utils/signature-validation.d.ts +2 -0
- package/dist/utils/signature-validation.js +3 -0
- package/dist/utils/third-party-mcp-servers/composio-client.d.ts +13 -1
- package/dist/utils/third-party-mcp-servers/composio-client.js +24 -6
- package/dist/utils/third-party-mcp-servers/index.d.ts +2 -2
- package/dist/utils/third-party-mcp-servers/index.js +2 -2
- package/dist/utils/trigger-auth.d.ts +31 -8
- package/dist/utils/trigger-auth.js +121 -13
- package/dist/validation/agentFull.js +1 -1
- package/dist/validation/drizzle-schema-helpers.d.ts +4 -23
- package/dist/validation/drizzle-schema-helpers.js +3 -30
- package/dist/validation/index.d.ts +3 -5
- package/dist/validation/index.js +5 -7
- package/dist/validation/render-validation.js +19 -0
- package/dist/validation/schemas.d.ts +3675 -1665
- package/dist/validation/schemas.js +409 -94
- package/dist/validation/stream-event-schemas.d.ts +96 -1
- package/dist/validation/stream-event-schemas.js +67 -2
- package/drizzle/manage/0003_tiny_captain_universe.sql +8 -0
- package/drizzle/manage/0004_curious_phil_sheldon.sql +2 -0
- package/drizzle/manage/0005_silent_shatterstar.sql +53 -0
- package/drizzle/manage/0006_fixed_umar.sql +1 -0
- package/drizzle/manage/meta/0003_snapshot.json +3134 -0
- package/drizzle/manage/meta/0004_snapshot.json +3141 -0
- package/drizzle/manage/meta/0005_snapshot.json +3141 -0
- package/drizzle/manage/meta/0006_snapshot.json +3148 -0
- package/drizzle/manage/meta/_journal.json +28 -0
- package/drizzle/runtime/0010_previous_black_knight.sql +84 -0
- package/drizzle/runtime/meta/0010_snapshot.json +3066 -0
- package/drizzle/runtime/meta/_journal.json +7 -0
- package/package.json +12 -5
- package/spicedb/schema.zed +114 -0
- package/dist/validation/id-validation.d.ts +0 -24
- package/dist/validation/id-validation.js +0 -52
|
@@ -7,28 +7,35 @@ import "../../index.js";
|
|
|
7
7
|
import { McpTool, ToolInsert, ToolSelect, ToolUpdate } from "../../types/entities.js";
|
|
8
8
|
|
|
9
9
|
//#region src/data-access/manage/tools.d.ts
|
|
10
|
+
/**
|
|
11
|
+
* Convert DB result to McpTool skeleton WITHOUT MCP discovery.
|
|
12
|
+
* This is a fast path that returns status='unknown' and empty availableTools.
|
|
13
|
+
* Use this for list views where you want instant page load.
|
|
14
|
+
*/
|
|
15
|
+
declare const dbResultToMcpToolSkeleton: (dbResult: ToolSelect, relationshipId?: string) => McpTool;
|
|
10
16
|
declare const dbResultToMcpTool: (dbResult: ToolSelect, dbClient: AgentsManageDatabaseClient, credentialStoreRegistry?: CredentialStoreRegistry, relationshipId?: string, userId?: string) => Promise<McpTool>;
|
|
11
17
|
declare const getToolById: (db: AgentsManageDatabaseClient) => (params: {
|
|
12
18
|
scopes: ProjectScopeConfig;
|
|
13
19
|
toolId: string;
|
|
14
20
|
}) => Promise<{
|
|
15
|
-
tenantId: string;
|
|
16
|
-
projectId: string;
|
|
17
21
|
id: string;
|
|
18
22
|
name: string;
|
|
23
|
+
createdAt: string;
|
|
24
|
+
updatedAt: string;
|
|
19
25
|
description: string | null;
|
|
26
|
+
headers: Record<string, string> | null;
|
|
27
|
+
projectId: string;
|
|
28
|
+
tenantId: string;
|
|
20
29
|
config: {
|
|
21
30
|
type: "mcp";
|
|
22
31
|
mcp: ToolMcpConfig;
|
|
23
32
|
};
|
|
24
33
|
credentialReferenceId: string | null;
|
|
25
|
-
createdAt: string;
|
|
26
|
-
updatedAt: string;
|
|
27
|
-
headers: Record<string, string> | null;
|
|
28
34
|
credentialScope: string;
|
|
29
35
|
imageUrl: string | null;
|
|
30
36
|
capabilities: ToolServerCapabilities | null;
|
|
31
37
|
lastError: string | null;
|
|
38
|
+
isWorkApp: boolean;
|
|
32
39
|
} | null>;
|
|
33
40
|
declare const getMcpToolById: (db: AgentsManageDatabaseClient) => (params: {
|
|
34
41
|
scopes: ProjectScopeConfig;
|
|
@@ -56,6 +63,7 @@ declare const listTools: (db: AgentsManageDatabaseClient) => (params: {
|
|
|
56
63
|
imageUrl: string | null;
|
|
57
64
|
capabilities: ToolServerCapabilities | null;
|
|
58
65
|
lastError: string | null;
|
|
66
|
+
isWorkApp: boolean;
|
|
59
67
|
projectId: string;
|
|
60
68
|
tenantId: string;
|
|
61
69
|
id: string;
|
|
@@ -68,23 +76,24 @@ declare const listTools: (db: AgentsManageDatabaseClient) => (params: {
|
|
|
68
76
|
};
|
|
69
77
|
}>;
|
|
70
78
|
declare const createTool: (db: AgentsManageDatabaseClient) => (params: ToolInsert) => Promise<{
|
|
71
|
-
tenantId: string;
|
|
72
|
-
projectId: string;
|
|
73
79
|
id: string;
|
|
74
80
|
name: string;
|
|
81
|
+
createdAt: string;
|
|
82
|
+
updatedAt: string;
|
|
75
83
|
description: string | null;
|
|
84
|
+
headers: Record<string, string> | null;
|
|
85
|
+
projectId: string;
|
|
86
|
+
tenantId: string;
|
|
76
87
|
config: {
|
|
77
88
|
type: "mcp";
|
|
78
89
|
mcp: ToolMcpConfig;
|
|
79
90
|
};
|
|
80
91
|
credentialReferenceId: string | null;
|
|
81
|
-
createdAt: string;
|
|
82
|
-
updatedAt: string;
|
|
83
|
-
headers: Record<string, string> | null;
|
|
84
92
|
credentialScope: string;
|
|
85
93
|
imageUrl: string | null;
|
|
86
94
|
capabilities: ToolServerCapabilities | null;
|
|
87
95
|
lastError: string | null;
|
|
96
|
+
isWorkApp: boolean;
|
|
88
97
|
}>;
|
|
89
98
|
declare const updateTool: (db: AgentsManageDatabaseClient) => (params: {
|
|
90
99
|
scopes: ProjectScopeConfig;
|
|
@@ -105,6 +114,7 @@ declare const updateTool: (db: AgentsManageDatabaseClient) => (params: {
|
|
|
105
114
|
imageUrl: string | null;
|
|
106
115
|
capabilities: ToolServerCapabilities | null;
|
|
107
116
|
lastError: string | null;
|
|
117
|
+
isWorkApp: boolean;
|
|
108
118
|
projectId: string;
|
|
109
119
|
tenantId: string;
|
|
110
120
|
id: string;
|
|
@@ -123,18 +133,18 @@ declare const addToolToAgent: (db: AgentsManageDatabaseClient) => (params: {
|
|
|
123
133
|
needsApproval?: boolean;
|
|
124
134
|
}> | null;
|
|
125
135
|
}) => Promise<{
|
|
126
|
-
tenantId: string;
|
|
127
|
-
projectId: string;
|
|
128
136
|
id: string;
|
|
129
|
-
agentId: string;
|
|
130
137
|
createdAt: string;
|
|
131
138
|
updatedAt: string;
|
|
132
|
-
toolId: string;
|
|
133
139
|
headers: Record<string, string> | null;
|
|
140
|
+
agentId: string;
|
|
141
|
+
projectId: string;
|
|
142
|
+
tenantId: string;
|
|
134
143
|
toolPolicies: Record<string, {
|
|
135
144
|
needsApproval?: boolean;
|
|
136
145
|
}> | null;
|
|
137
146
|
subAgentId: string;
|
|
147
|
+
toolId: string;
|
|
138
148
|
selectedTools: string[] | null;
|
|
139
149
|
}>;
|
|
140
150
|
declare const removeToolFromAgent: (db: AgentsManageDatabaseClient) => (params: {
|
|
@@ -142,18 +152,18 @@ declare const removeToolFromAgent: (db: AgentsManageDatabaseClient) => (params:
|
|
|
142
152
|
subAgentId: string;
|
|
143
153
|
toolId: string;
|
|
144
154
|
}) => Promise<{
|
|
145
|
-
tenantId: string;
|
|
146
|
-
projectId: string;
|
|
147
155
|
id: string;
|
|
148
|
-
agentId: string;
|
|
149
156
|
createdAt: string;
|
|
150
157
|
updatedAt: string;
|
|
151
|
-
toolId: string;
|
|
152
158
|
headers: Record<string, string> | null;
|
|
159
|
+
agentId: string;
|
|
160
|
+
projectId: string;
|
|
161
|
+
tenantId: string;
|
|
153
162
|
toolPolicies: Record<string, {
|
|
154
163
|
needsApproval?: boolean;
|
|
155
164
|
}> | null;
|
|
156
165
|
subAgentId: string;
|
|
166
|
+
toolId: string;
|
|
157
167
|
selectedTools: string[] | null;
|
|
158
168
|
}>;
|
|
159
169
|
/**
|
|
@@ -170,18 +180,18 @@ declare const upsertSubAgentToolRelation: (db: AgentsManageDatabaseClient) => (p
|
|
|
170
180
|
}> | null;
|
|
171
181
|
relationId?: string;
|
|
172
182
|
}) => Promise<{
|
|
173
|
-
tenantId: string;
|
|
174
|
-
projectId: string;
|
|
175
183
|
id: string;
|
|
176
|
-
agentId: string;
|
|
177
184
|
createdAt: string;
|
|
178
185
|
updatedAt: string;
|
|
179
|
-
toolId: string;
|
|
180
186
|
headers: Record<string, string> | null;
|
|
187
|
+
agentId: string;
|
|
188
|
+
projectId: string;
|
|
189
|
+
tenantId: string;
|
|
181
190
|
toolPolicies: Record<string, {
|
|
182
191
|
needsApproval?: boolean;
|
|
183
192
|
}> | null;
|
|
184
193
|
subAgentId: string;
|
|
194
|
+
toolId: string;
|
|
185
195
|
selectedTools: string[] | null;
|
|
186
196
|
}>;
|
|
187
197
|
/**
|
|
@@ -190,23 +200,24 @@ declare const upsertSubAgentToolRelation: (db: AgentsManageDatabaseClient) => (p
|
|
|
190
200
|
declare const upsertTool: (db: AgentsManageDatabaseClient) => (params: {
|
|
191
201
|
data: ToolInsert;
|
|
192
202
|
}) => Promise<{
|
|
193
|
-
tenantId: string;
|
|
194
|
-
projectId: string;
|
|
195
203
|
id: string;
|
|
196
204
|
name: string;
|
|
205
|
+
createdAt: string;
|
|
206
|
+
updatedAt: string;
|
|
197
207
|
description: string | null;
|
|
208
|
+
headers: Record<string, string> | null;
|
|
209
|
+
projectId: string;
|
|
210
|
+
tenantId: string;
|
|
198
211
|
config: {
|
|
199
212
|
type: "mcp";
|
|
200
213
|
mcp: ToolMcpConfig;
|
|
201
214
|
};
|
|
202
215
|
credentialReferenceId: string | null;
|
|
203
|
-
createdAt: string;
|
|
204
|
-
updatedAt: string;
|
|
205
|
-
headers: Record<string, string> | null;
|
|
206
216
|
credentialScope: string;
|
|
207
217
|
imageUrl: string | null;
|
|
208
218
|
capabilities: ToolServerCapabilities | null;
|
|
209
219
|
lastError: string | null;
|
|
220
|
+
isWorkApp: boolean;
|
|
210
221
|
}>;
|
|
211
222
|
//#endregion
|
|
212
|
-
export { addToolToAgent, createTool, dbResultToMcpTool, deleteTool, getMcpToolById, getToolById, listTools, removeToolFromAgent, updateTool, upsertSubAgentToolRelation, upsertTool };
|
|
223
|
+
export { addToolToAgent, createTool, dbResultToMcpTool, dbResultToMcpToolSkeleton, deleteTool, getMcpToolById, getToolById, listTools, removeToolFromAgent, updateTool, upsertSubAgentToolRelation, upsertTool };
|
|
@@ -1,20 +1,41 @@
|
|
|
1
1
|
import { CredentialStoreType, MCPServerType, MCPTransportType } from "../../types/utility.js";
|
|
2
2
|
import { subAgentToolRelations, tools } from "../../db/manage/manage-schema.js";
|
|
3
3
|
import { detectAuthenticationRequired } from "../../utils/auth-detection.js";
|
|
4
|
+
import { env } from "../../env.js";
|
|
4
5
|
import { getLogger } from "../../utils/logger.js";
|
|
5
6
|
import { getCredentialStoreLookupKeyFromRetrievalParams } from "../../utils/credential-store-utils.js";
|
|
6
7
|
import { CredentialStuffer } from "../../credential-stuffer/CredentialStuffer.js";
|
|
7
8
|
import "../../credential-stuffer/index.js";
|
|
9
|
+
import { createAgentsRunDatabaseClient } from "../../db/runtime/runtime-client.js";
|
|
8
10
|
import { generateId } from "../../utils/conversations.js";
|
|
9
11
|
import { updateAgentToolRelation } from "./subAgentRelations.js";
|
|
12
|
+
import { getActiveBranch } from "../../dolt/schema-sync.js";
|
|
10
13
|
import { toISODateString } from "../../utils/date.js";
|
|
11
14
|
import { McpClient } from "../../utils/mcp-client.js";
|
|
15
|
+
import { buildComposioMCPUrl } from "../../utils/third-party-mcp-servers/composio-client.js";
|
|
12
16
|
import { isThirdPartyMCPServerAuthenticated } from "../../utils/third-party-mcp-servers/third-party-check.js";
|
|
13
17
|
import "../../utils/index.js";
|
|
18
|
+
import { cascadeDeleteByTool } from "../runtime/cascade-delete.js";
|
|
19
|
+
import { isGithubWorkAppTool } from "../runtime/github-work-app-installations.js";
|
|
14
20
|
import { getCredentialReference, getUserScopedCredentialReference } from "./credentialReferences.js";
|
|
15
21
|
import { and, count, desc, eq } from "drizzle-orm";
|
|
22
|
+
import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
16
23
|
|
|
17
24
|
//#region src/data-access/manage/tools.ts
|
|
25
|
+
/**
|
|
26
|
+
* Check if an error is a timeout/connection error.
|
|
27
|
+
* Uses MCP SDK ErrorCode for proper type safety.
|
|
28
|
+
*/
|
|
29
|
+
function isTimeoutOrConnectionError(error) {
|
|
30
|
+
if (error instanceof McpError) return error.code === ErrorCode.RequestTimeout || error.code === ErrorCode.ConnectionClosed;
|
|
31
|
+
if (error instanceof Error) {
|
|
32
|
+
const message = error.message.toLowerCase();
|
|
33
|
+
const cause = error.cause;
|
|
34
|
+
if (message.includes("timed out") || message.includes("timeout")) return true;
|
|
35
|
+
if (cause?.code === "ETIMEDOUT" || cause?.code === "ECONNABORTED" || cause?.code === "ECONNRESET") return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
18
39
|
const logger = getLogger("tools");
|
|
19
40
|
/**
|
|
20
41
|
* Extract expiration date from credential data stored in credential store
|
|
@@ -70,24 +91,10 @@ const convertToMCPToolConfig = (tool) => {
|
|
|
70
91
|
toolOverrides: tool.config.mcp.toolOverrides
|
|
71
92
|
};
|
|
72
93
|
};
|
|
73
|
-
const discoverToolsFromServer = async (tool,
|
|
94
|
+
const discoverToolsFromServer = async (tool, credentialReference, credentialStoreRegistry, userId) => {
|
|
74
95
|
if (tool.config.type !== "mcp") throw new Error(`Cannot discover tools from non-MCP tool: ${tool.id}`);
|
|
75
96
|
try {
|
|
76
97
|
let serverConfig;
|
|
77
|
-
const credentialReference = tool.credentialReferenceId && tool.credentialScope !== "user" ? await getCredentialReference(dbClient)({
|
|
78
|
-
scopes: {
|
|
79
|
-
tenantId: tool.tenantId,
|
|
80
|
-
projectId: tool.projectId
|
|
81
|
-
},
|
|
82
|
-
id: tool.credentialReferenceId
|
|
83
|
-
}) : userId && tool.credentialScope === "user" ? await getUserScopedCredentialReference(dbClient)({
|
|
84
|
-
scopes: {
|
|
85
|
-
tenantId: tool.tenantId,
|
|
86
|
-
projectId: tool.projectId
|
|
87
|
-
},
|
|
88
|
-
toolId: tool.id,
|
|
89
|
-
userId
|
|
90
|
-
}) : void 0;
|
|
91
98
|
if (credentialReference) {
|
|
92
99
|
const storeReference = {
|
|
93
100
|
credentialStoreId: credentialReference.credentialStoreId,
|
|
@@ -111,12 +118,12 @@ const discoverToolsFromServer = async (tool, dbClient, credentialStoreRegistry,
|
|
|
111
118
|
reconnectionOptions: tool.config.mcp.transport?.reconnectionOptions,
|
|
112
119
|
sessionId: tool.config.mcp.transport?.sessionId
|
|
113
120
|
};
|
|
114
|
-
if (serverConfig.url
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
121
|
+
if (serverConfig.url) serverConfig.url = buildComposioMCPUrl(serverConfig.url.toString(), tool.tenantId, tool.projectId, tool.credentialScope === "user" ? "user" : "project", userId);
|
|
122
|
+
if (isGithubWorkAppTool(tool)) serverConfig.headers = {
|
|
123
|
+
...serverConfig.headers,
|
|
124
|
+
"x-inkeep-tool-id": tool.id,
|
|
125
|
+
Authorization: `Bearer ${env.GITHUB_MCP_API_KEY}`
|
|
126
|
+
};
|
|
120
127
|
const client = new McpClient({
|
|
121
128
|
name: tool.name,
|
|
122
129
|
server: serverConfig
|
|
@@ -141,6 +148,27 @@ const discoverToolsFromServer = async (tool, dbClient, credentialStoreRegistry,
|
|
|
141
148
|
throw error;
|
|
142
149
|
}
|
|
143
150
|
};
|
|
151
|
+
/**
|
|
152
|
+
* Convert DB result to McpTool skeleton WITHOUT MCP discovery.
|
|
153
|
+
* This is a fast path that returns status='unknown' and empty availableTools.
|
|
154
|
+
* Use this for list views where you want instant page load.
|
|
155
|
+
*/
|
|
156
|
+
const dbResultToMcpToolSkeleton = (dbResult, relationshipId) => {
|
|
157
|
+
const { headers, capabilities, credentialReferenceId, imageUrl, createdAt, ...rest } = dbResult;
|
|
158
|
+
return {
|
|
159
|
+
...rest,
|
|
160
|
+
status: "unknown",
|
|
161
|
+
availableTools: [],
|
|
162
|
+
capabilities: capabilities || void 0,
|
|
163
|
+
credentialReferenceId: credentialReferenceId || void 0,
|
|
164
|
+
createdAt: toISODateString(createdAt),
|
|
165
|
+
updatedAt: toISODateString(dbResult.updatedAt),
|
|
166
|
+
lastError: dbResult.lastError || null,
|
|
167
|
+
headers: headers || void 0,
|
|
168
|
+
imageUrl: imageUrl || void 0,
|
|
169
|
+
relationshipId
|
|
170
|
+
};
|
|
171
|
+
};
|
|
144
172
|
const dbResultToMcpTool = async (dbResult, dbClient, credentialStoreRegistry, relationshipId, userId) => {
|
|
145
173
|
const { headers, capabilities, credentialReferenceId, imageUrl, createdAt, ...rest } = dbResult;
|
|
146
174
|
if (dbResult.config.type !== "mcp") return {
|
|
@@ -181,18 +209,23 @@ const dbResultToMcpTool = async (dbResult, dbClient, credentialStoreRegistry, re
|
|
|
181
209
|
}
|
|
182
210
|
const mcpServerUrl = dbResult.config.mcp.server.url;
|
|
183
211
|
try {
|
|
184
|
-
availableTools = await discoverToolsFromServer(dbResult,
|
|
212
|
+
availableTools = await discoverToolsFromServer(dbResult, credentialReference, credentialStoreRegistry, userId);
|
|
185
213
|
status = "healthy";
|
|
186
214
|
lastErrorComputed = null;
|
|
187
215
|
} catch (error) {
|
|
188
|
-
const toolNeedsAuth = error instanceof Error && await detectAuthenticationRequired({
|
|
189
|
-
serverUrl: mcpServerUrl,
|
|
190
|
-
error,
|
|
191
|
-
logger
|
|
192
|
-
});
|
|
193
|
-
status = toolNeedsAuth ? "needs_auth" : "unhealthy";
|
|
194
216
|
const errorMessage = error instanceof Error ? error.message : "Tool discovery failed";
|
|
195
|
-
|
|
217
|
+
if (isTimeoutOrConnectionError(error)) {
|
|
218
|
+
status = "unavailable";
|
|
219
|
+
lastErrorComputed = `Connection failed - the MCP server may be slow or temporarily unreachable.${error instanceof McpError ? ` (MCP error ${error.code})` : ""} ${errorMessage}`;
|
|
220
|
+
} else {
|
|
221
|
+
const toolNeedsAuth = await detectAuthenticationRequired({
|
|
222
|
+
serverUrl: mcpServerUrl,
|
|
223
|
+
error: error instanceof Error ? error : void 0,
|
|
224
|
+
logger
|
|
225
|
+
});
|
|
226
|
+
status = toolNeedsAuth ? "needs_auth" : "unhealthy";
|
|
227
|
+
lastErrorComputed = toolNeedsAuth ? `Authentication required - OAuth login needed. ${errorMessage}` : errorMessage;
|
|
228
|
+
}
|
|
196
229
|
}
|
|
197
230
|
if (dbResult.config.mcp.server.url.includes("composio.dev")) {
|
|
198
231
|
const credentialScope = dbResult.credentialScope || "project";
|
|
@@ -284,7 +317,16 @@ const updateTool = (db) => async (params) => {
|
|
|
284
317
|
};
|
|
285
318
|
const deleteTool = (db) => async (params) => {
|
|
286
319
|
const [deleted] = await db.delete(tools).where(and(eq(tools.tenantId, params.scopes.tenantId), eq(tools.projectId, params.scopes.projectId), eq(tools.id, params.toolId))).returning();
|
|
287
|
-
return
|
|
320
|
+
if (!deleted) return false;
|
|
321
|
+
if (deleted.isWorkApp && deleted.config.mcp.server.url.includes("/github/mcp")) try {
|
|
322
|
+
if (await getActiveBranch(db)() === `${params.scopes.tenantId}_${params.scopes.projectId}_main`) await cascadeDeleteByTool(createAgentsRunDatabaseClient())({ toolId: params.toolId });
|
|
323
|
+
} catch (error) {
|
|
324
|
+
logger.debug({
|
|
325
|
+
error,
|
|
326
|
+
toolId: params.toolId
|
|
327
|
+
}, "Skipping cascade delete - active_branch() not available");
|
|
328
|
+
}
|
|
329
|
+
return true;
|
|
288
330
|
};
|
|
289
331
|
const addToolToAgent = (db) => async (params) => {
|
|
290
332
|
const id = generateId();
|
|
@@ -351,4 +393,4 @@ const upsertTool = (db) => async (params) => {
|
|
|
351
393
|
};
|
|
352
394
|
|
|
353
395
|
//#endregion
|
|
354
|
-
export { addToolToAgent, createTool, dbResultToMcpTool, deleteTool, getMcpToolById, getToolById, listTools, removeToolFromAgent, updateTool, upsertSubAgentToolRelation, upsertTool };
|
|
396
|
+
export { addToolToAgent, createTool, dbResultToMcpTool, dbResultToMcpToolSkeleton, deleteTool, getMcpToolById, getToolById, listTools, removeToolFromAgent, updateTool, upsertSubAgentToolRelation, upsertTool };
|
|
@@ -35,7 +35,33 @@ declare const listTriggersPaginated: (db: AgentsManageDatabaseClient) => (params
|
|
|
35
35
|
} | null;
|
|
36
36
|
messageTemplate: string | null;
|
|
37
37
|
authentication: unknown;
|
|
38
|
-
|
|
38
|
+
signingSecretCredentialReferenceId: string | null;
|
|
39
|
+
signatureVerification: {
|
|
40
|
+
algorithm: "sha256" | "sha512" | "sha384" | "sha1" | "md5";
|
|
41
|
+
encoding: "hex" | "base64";
|
|
42
|
+
signature: {
|
|
43
|
+
source: "query" | "body" | "header";
|
|
44
|
+
key: string;
|
|
45
|
+
prefix?: string | undefined;
|
|
46
|
+
regex?: string | undefined;
|
|
47
|
+
};
|
|
48
|
+
signedComponents: {
|
|
49
|
+
source: "literal" | "body" | "header";
|
|
50
|
+
required: boolean;
|
|
51
|
+
key?: string | undefined;
|
|
52
|
+
value?: string | undefined;
|
|
53
|
+
regex?: string | undefined;
|
|
54
|
+
}[];
|
|
55
|
+
componentJoin: {
|
|
56
|
+
strategy: "concatenate";
|
|
57
|
+
separator: string;
|
|
58
|
+
};
|
|
59
|
+
validation?: {
|
|
60
|
+
headerCaseSensitive: boolean;
|
|
61
|
+
allowEmptyBody: boolean;
|
|
62
|
+
normalizeUnicode: boolean;
|
|
63
|
+
} | undefined;
|
|
64
|
+
} | null;
|
|
39
65
|
name: string;
|
|
40
66
|
description: string | null;
|
|
41
67
|
agentId: string;
|
|
@@ -7,49 +7,49 @@ declare const getApiKeyById: (db: AgentsRunDatabaseClient) => (params: {
|
|
|
7
7
|
scopes: ProjectScopeConfig;
|
|
8
8
|
id: string;
|
|
9
9
|
}) => Promise<{
|
|
10
|
-
tenantId: string;
|
|
11
|
-
projectId: string;
|
|
12
10
|
id: string;
|
|
13
11
|
name: string | null;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
updatedAt: string;
|
|
14
|
+
expiresAt: string | null;
|
|
14
15
|
agentId: string;
|
|
16
|
+
projectId: string;
|
|
17
|
+
tenantId: string;
|
|
15
18
|
publicId: string;
|
|
16
19
|
keyHash: string;
|
|
17
20
|
keyPrefix: string;
|
|
18
21
|
lastUsedAt: string | null;
|
|
19
|
-
expiresAt: string | null;
|
|
20
|
-
createdAt: string;
|
|
21
|
-
updatedAt: string;
|
|
22
22
|
} | undefined>;
|
|
23
23
|
declare const getApiKeyByPublicId: (db: AgentsRunDatabaseClient) => (publicId: string) => Promise<{
|
|
24
|
-
tenantId: string;
|
|
25
|
-
projectId: string;
|
|
26
24
|
id: string;
|
|
27
25
|
name: string | null;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
updatedAt: string;
|
|
28
|
+
expiresAt: string | null;
|
|
28
29
|
agentId: string;
|
|
30
|
+
projectId: string;
|
|
31
|
+
tenantId: string;
|
|
29
32
|
publicId: string;
|
|
30
33
|
keyHash: string;
|
|
31
34
|
keyPrefix: string;
|
|
32
35
|
lastUsedAt: string | null;
|
|
33
|
-
expiresAt: string | null;
|
|
34
|
-
createdAt: string;
|
|
35
|
-
updatedAt: string;
|
|
36
36
|
} | undefined>;
|
|
37
37
|
declare const listApiKeys: (db: AgentsRunDatabaseClient) => (params: {
|
|
38
38
|
scopes: ProjectScopeConfig;
|
|
39
39
|
agentId?: string;
|
|
40
40
|
}) => Promise<{
|
|
41
|
-
tenantId: string;
|
|
42
|
-
projectId: string;
|
|
43
41
|
id: string;
|
|
44
42
|
name: string | null;
|
|
43
|
+
createdAt: string;
|
|
44
|
+
updatedAt: string;
|
|
45
|
+
expiresAt: string | null;
|
|
45
46
|
agentId: string;
|
|
47
|
+
projectId: string;
|
|
48
|
+
tenantId: string;
|
|
46
49
|
publicId: string;
|
|
47
50
|
keyHash: string;
|
|
48
51
|
keyPrefix: string;
|
|
49
52
|
lastUsedAt: string | null;
|
|
50
|
-
expiresAt: string | null;
|
|
51
|
-
createdAt: string;
|
|
52
|
-
updatedAt: string;
|
|
53
53
|
}[]>;
|
|
54
54
|
declare const listApiKeysPaginated: (db: AgentsRunDatabaseClient) => (params: {
|
|
55
55
|
scopes: ProjectScopeConfig;
|
|
@@ -65,18 +65,18 @@ declare const listApiKeysPaginated: (db: AgentsRunDatabaseClient) => (params: {
|
|
|
65
65
|
};
|
|
66
66
|
}>;
|
|
67
67
|
declare const createApiKey: (db: AgentsRunDatabaseClient) => (params: ApiKeyInsert) => Promise<{
|
|
68
|
-
tenantId: string;
|
|
69
|
-
projectId: string;
|
|
70
68
|
id: string;
|
|
71
69
|
name: string | null;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
updatedAt: string;
|
|
72
|
+
expiresAt: string | null;
|
|
72
73
|
agentId: string;
|
|
74
|
+
projectId: string;
|
|
75
|
+
tenantId: string;
|
|
73
76
|
publicId: string;
|
|
74
77
|
keyHash: string;
|
|
75
78
|
keyPrefix: string;
|
|
76
79
|
lastUsedAt: string | null;
|
|
77
|
-
expiresAt: string | null;
|
|
78
|
-
createdAt: string;
|
|
79
|
-
updatedAt: string;
|
|
80
80
|
}>;
|
|
81
81
|
declare const updateApiKey: (db: AgentsRunDatabaseClient) => (params: {
|
|
82
82
|
scopes: ProjectScopeConfig;
|
|
@@ -73,5 +73,52 @@ declare const cascadeDeleteByContextConfig: (db: AgentsRunDatabaseClient) => (pa
|
|
|
73
73
|
}) => Promise<{
|
|
74
74
|
contextCacheDeleted: number;
|
|
75
75
|
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Result of a tool cascade delete operation
|
|
78
|
+
*/
|
|
79
|
+
type ToolCascadeDeleteResult = {
|
|
80
|
+
mcpToolRepositoryAccessDeleted: number;
|
|
81
|
+
mcpToolAccessModeDeleted: boolean;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Delete all runtime entities for a specific MCP tool.
|
|
85
|
+
* Called when an MCP tool is deleted from the manage database.
|
|
86
|
+
*
|
|
87
|
+
* Cleans up:
|
|
88
|
+
* - workAppGitHubMcpToolRepositoryAccess entries
|
|
89
|
+
* - workAppGitHubMcpToolAccessMode entry
|
|
90
|
+
*
|
|
91
|
+
* @param db - Runtime database client
|
|
92
|
+
* @returns Function that performs the cascade delete
|
|
93
|
+
*/
|
|
94
|
+
declare const cascadeDeleteByTool: (db: AgentsRunDatabaseClient) => (params: {
|
|
95
|
+
toolId: string;
|
|
96
|
+
}) => Promise<ToolCascadeDeleteResult>;
|
|
97
|
+
/**
|
|
98
|
+
* Result of a project cascade delete operation (GitHub access only)
|
|
99
|
+
*/
|
|
100
|
+
type ProjectGitHubAccessCascadeDeleteResult = {
|
|
101
|
+
projectRepositoryAccessDeleted: number;
|
|
102
|
+
projectAccessModeDeleted: boolean;
|
|
103
|
+
mcpToolRepositoryAccessDeleted: number;
|
|
104
|
+
mcpToolAccessModesDeleted: number;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Delete all GitHub access runtime entities for a specific project.
|
|
108
|
+
* Called when a project is deleted from the manage database.
|
|
109
|
+
*
|
|
110
|
+
* Cleans up:
|
|
111
|
+
* - workAppGitHubProjectRepositoryAccess entries
|
|
112
|
+
* - workAppGitHubProjectAccessMode entry
|
|
113
|
+
* - workAppGitHubMcpToolRepositoryAccess entries (for tools in this project)
|
|
114
|
+
* - workAppGitHubMcpToolAccessMode entries (for tools in this project)
|
|
115
|
+
*
|
|
116
|
+
* @param db - Runtime database client
|
|
117
|
+
* @returns Function that performs the cascade delete
|
|
118
|
+
*/
|
|
119
|
+
declare const cascadeDeleteGitHubAccessByProject: (db: AgentsRunDatabaseClient) => (params: {
|
|
120
|
+
tenantId: string;
|
|
121
|
+
projectId: string;
|
|
122
|
+
}) => Promise<ProjectGitHubAccessCascadeDeleteResult>;
|
|
76
123
|
//#endregion
|
|
77
|
-
export { CascadeDeleteResult, cascadeDeleteByAgent, cascadeDeleteByBranch, cascadeDeleteByContextConfig, cascadeDeleteByProject, cascadeDeleteBySubAgent };
|
|
124
|
+
export { CascadeDeleteResult, ProjectGitHubAccessCascadeDeleteResult, ToolCascadeDeleteResult, cascadeDeleteByAgent, cascadeDeleteByBranch, cascadeDeleteByContextConfig, cascadeDeleteByProject, cascadeDeleteBySubAgent, cascadeDeleteByTool, cascadeDeleteGitHubAccessByProject };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { apiKeys, contextCache, conversations, tasks } from "../../db/runtime/runtime-schema.js";
|
|
1
|
+
import { apiKeys, contextCache, conversations, tasks, workAppGitHubMcpToolAccessMode, workAppGitHubMcpToolRepositoryAccess, workAppGitHubProjectAccessMode, workAppGitHubProjectRepositoryAccess } from "../../db/runtime/runtime-schema.js";
|
|
2
2
|
import { and, eq, inArray, sql } from "drizzle-orm";
|
|
3
3
|
|
|
4
4
|
//#region src/data-access/runtime/cascade-delete.ts
|
|
@@ -35,6 +35,10 @@ const cascadeDeleteByProject = (db) => async (params) => {
|
|
|
35
35
|
const conversationsResult = await db.delete(conversations).where(and(eq(conversations.tenantId, scopes.tenantId), eq(conversations.projectId, scopes.projectId), sql`${conversations.ref}->>'name' = ${fullBranchName}`)).returning();
|
|
36
36
|
const tasksResult = await db.delete(tasks).where(and(eq(tasks.tenantId, scopes.tenantId), eq(tasks.projectId, scopes.projectId), sql`${tasks.ref}->>'name' = ${fullBranchName}`)).returning();
|
|
37
37
|
const apiKeysResult = await db.delete(apiKeys).where(and(eq(apiKeys.tenantId, scopes.tenantId), eq(apiKeys.projectId, scopes.projectId))).returning();
|
|
38
|
+
await cascadeDeleteGitHubAccessByProject(db)({
|
|
39
|
+
tenantId: scopes.tenantId,
|
|
40
|
+
projectId: scopes.projectId
|
|
41
|
+
});
|
|
38
42
|
return {
|
|
39
43
|
conversationsDeleted: conversationsResult.length,
|
|
40
44
|
tasksDeleted: tasksResult.length,
|
|
@@ -106,6 +110,52 @@ const cascadeDeleteByContextConfig = (db) => async (params) => {
|
|
|
106
110
|
const { scopes, contextConfigId, fullBranchName } = params;
|
|
107
111
|
return { contextCacheDeleted: (await db.delete(contextCache).where(and(eq(contextCache.tenantId, scopes.tenantId), eq(contextCache.projectId, scopes.projectId), eq(contextCache.contextConfigId, contextConfigId), sql`${contextCache.ref}->>'name' = ${fullBranchName}`)).returning()).length };
|
|
108
112
|
};
|
|
113
|
+
/**
|
|
114
|
+
* Delete all runtime entities for a specific MCP tool.
|
|
115
|
+
* Called when an MCP tool is deleted from the manage database.
|
|
116
|
+
*
|
|
117
|
+
* Cleans up:
|
|
118
|
+
* - workAppGitHubMcpToolRepositoryAccess entries
|
|
119
|
+
* - workAppGitHubMcpToolAccessMode entry
|
|
120
|
+
*
|
|
121
|
+
* @param db - Runtime database client
|
|
122
|
+
* @returns Function that performs the cascade delete
|
|
123
|
+
*/
|
|
124
|
+
const cascadeDeleteByTool = (db) => async (params) => {
|
|
125
|
+
const { toolId } = params;
|
|
126
|
+
const repositoryAccessResult = await db.delete(workAppGitHubMcpToolRepositoryAccess).where(eq(workAppGitHubMcpToolRepositoryAccess.toolId, toolId)).returning();
|
|
127
|
+
const accessModeResult = await db.delete(workAppGitHubMcpToolAccessMode).where(eq(workAppGitHubMcpToolAccessMode.toolId, toolId)).returning();
|
|
128
|
+
return {
|
|
129
|
+
mcpToolRepositoryAccessDeleted: repositoryAccessResult.length,
|
|
130
|
+
mcpToolAccessModeDeleted: accessModeResult.length > 0
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Delete all GitHub access runtime entities for a specific project.
|
|
135
|
+
* Called when a project is deleted from the manage database.
|
|
136
|
+
*
|
|
137
|
+
* Cleans up:
|
|
138
|
+
* - workAppGitHubProjectRepositoryAccess entries
|
|
139
|
+
* - workAppGitHubProjectAccessMode entry
|
|
140
|
+
* - workAppGitHubMcpToolRepositoryAccess entries (for tools in this project)
|
|
141
|
+
* - workAppGitHubMcpToolAccessMode entries (for tools in this project)
|
|
142
|
+
*
|
|
143
|
+
* @param db - Runtime database client
|
|
144
|
+
* @returns Function that performs the cascade delete
|
|
145
|
+
*/
|
|
146
|
+
const cascadeDeleteGitHubAccessByProject = (db) => async (params) => {
|
|
147
|
+
const { tenantId, projectId } = params;
|
|
148
|
+
const projectRepoAccessResult = await db.delete(workAppGitHubProjectRepositoryAccess).where(and(eq(workAppGitHubProjectRepositoryAccess.tenantId, tenantId), eq(workAppGitHubProjectRepositoryAccess.projectId, projectId))).returning();
|
|
149
|
+
const projectAccessModeResult = await db.delete(workAppGitHubProjectAccessMode).where(and(eq(workAppGitHubProjectAccessMode.tenantId, tenantId), eq(workAppGitHubProjectAccessMode.projectId, projectId))).returning();
|
|
150
|
+
const mcpToolRepoAccessResult = await db.delete(workAppGitHubMcpToolRepositoryAccess).where(and(eq(workAppGitHubMcpToolRepositoryAccess.tenantId, tenantId), eq(workAppGitHubMcpToolRepositoryAccess.projectId, projectId))).returning();
|
|
151
|
+
const mcpToolAccessModeResult = await db.delete(workAppGitHubMcpToolAccessMode).where(and(eq(workAppGitHubMcpToolAccessMode.tenantId, tenantId), eq(workAppGitHubMcpToolAccessMode.projectId, projectId))).returning();
|
|
152
|
+
return {
|
|
153
|
+
projectRepositoryAccessDeleted: projectRepoAccessResult.length,
|
|
154
|
+
projectAccessModeDeleted: projectAccessModeResult.length > 0,
|
|
155
|
+
mcpToolRepositoryAccessDeleted: mcpToolRepoAccessResult.length,
|
|
156
|
+
mcpToolAccessModesDeleted: mcpToolAccessModeResult.length
|
|
157
|
+
};
|
|
158
|
+
};
|
|
109
159
|
|
|
110
160
|
//#endregion
|
|
111
|
-
export { cascadeDeleteByAgent, cascadeDeleteByBranch, cascadeDeleteByContextConfig, cascadeDeleteByProject, cascadeDeleteBySubAgent };
|
|
161
|
+
export { cascadeDeleteByAgent, cascadeDeleteByBranch, cascadeDeleteByContextConfig, cascadeDeleteByProject, cascadeDeleteBySubAgent, cascadeDeleteByTool, cascadeDeleteGitHubAccessByProject };
|