@inkeep/agents-manage-api 0.39.4 → 0.40.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/create-app.d.ts +21 -0
- package/dist/create-app.js +144 -0
- package/dist/data/agentFull.d.ts +15 -0
- package/dist/data/agentFull.js +84 -0
- package/dist/data/conversations.d.ts +77 -0
- package/dist/data/conversations.js +152 -0
- package/dist/data/db/dbClient.d.ts +6 -0
- package/dist/data/db/dbClient.js +17 -0
- package/dist/env.d.ts +61 -0
- package/dist/env.js +55 -0
- package/dist/factory.d.ts +17 -2
- package/dist/factory.js +35 -2
- package/dist/index.d.ts +119 -22
- package/dist/index.js +8 -5
- package/dist/initialization.d.ts +6 -0
- package/dist/initialization.js +79 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.js +3 -0
- package/dist/middleware/auth.d.ts +24 -0
- package/dist/middleware/auth.js +55 -0
- package/dist/middleware/error-handler.d.ts +12 -0
- package/dist/middleware/error-handler.js +88 -0
- package/dist/middleware/require-permission.d.ts +19 -0
- package/dist/middleware/require-permission.js +80 -0
- package/dist/middleware/session-auth.d.ts +6 -0
- package/dist/middleware/session-auth.js +26 -0
- package/dist/middleware/tenant-access.d.ts +12 -0
- package/dist/middleware/tenant-access.js +54 -0
- package/dist/openapi.d.ts +7 -0
- package/dist/openapi.js +157 -0
- package/dist/routes/agent.d.ts +9 -0
- package/dist/routes/agent.js +244 -0
- package/dist/routes/agentFull.d.ts +9 -0
- package/dist/routes/agentFull.js +188 -0
- package/dist/routes/agentToolRelations.d.ts +9 -0
- package/dist/routes/agentToolRelations.js +284 -0
- package/dist/routes/apiKeys.d.ts +9 -0
- package/dist/routes/apiKeys.js +217 -0
- package/dist/routes/artifactComponents.d.ts +9 -0
- package/dist/routes/artifactComponents.js +204 -0
- package/dist/routes/cliAuth.d.ts +9 -0
- package/dist/routes/cliAuth.js +60 -0
- package/dist/routes/contextConfigs.d.ts +9 -0
- package/dist/routes/contextConfigs.js +175 -0
- package/dist/routes/conversations.d.ts +7 -0
- package/dist/routes/conversations.js +59 -0
- package/dist/routes/credentialStores.d.ts +9 -0
- package/dist/routes/credentialStores.js +81 -0
- package/dist/routes/credentials.d.ts +9 -0
- package/dist/routes/credentials.js +204 -0
- package/dist/routes/dataComponents.d.ts +9 -0
- package/dist/routes/dataComponents.js +188 -0
- package/dist/routes/externalAgents.d.ts +9 -0
- package/dist/routes/externalAgents.js +195 -0
- package/dist/routes/functionTools.d.ts +9 -0
- package/dist/routes/functionTools.js +252 -0
- package/dist/routes/functions.d.ts +9 -0
- package/dist/routes/functions.js +281 -0
- package/dist/routes/index.d.ts +7 -0
- package/dist/routes/index.js +54 -0
- package/dist/routes/invitations.d.ts +9 -0
- package/dist/routes/invitations.js +41 -0
- package/dist/routes/mcp.d.ts +7 -0
- package/dist/routes/mcp.js +45 -0
- package/dist/routes/mcpCatalog.d.ts +13 -0
- package/dist/routes/mcpCatalog.js +454 -0
- package/dist/routes/oauth.d.ts +10 -0
- package/dist/routes/oauth.js +314 -0
- package/dist/routes/playgroundToken.d.ts +9 -0
- package/dist/routes/playgroundToken.js +108 -0
- package/dist/routes/projectFull.d.ts +9 -0
- package/dist/routes/projectFull.js +193 -0
- package/dist/routes/projects.d.ts +9 -0
- package/dist/routes/projects.js +188 -0
- package/dist/routes/shared.d.ts +93 -0
- package/dist/routes/shared.js +44 -0
- package/dist/routes/signoz.d.ts +10 -0
- package/dist/routes/signoz.js +155 -0
- package/dist/routes/subAgentArtifactComponents.d.ts +9 -0
- package/dist/routes/subAgentArtifactComponents.js +198 -0
- package/dist/routes/subAgentDataComponents.d.ts +9 -0
- package/dist/routes/subAgentDataComponents.js +197 -0
- package/dist/routes/subAgentExternalAgentRelations.d.ts +9 -0
- package/dist/routes/subAgentExternalAgentRelations.js +213 -0
- package/dist/routes/subAgentRelations.d.ts +9 -0
- package/dist/routes/subAgentRelations.js +259 -0
- package/dist/routes/subAgentTeamAgentRelations.d.ts +9 -0
- package/dist/routes/subAgentTeamAgentRelations.js +213 -0
- package/dist/routes/subAgentToolRelations.d.ts +9 -0
- package/dist/routes/subAgentToolRelations.js +284 -0
- package/dist/routes/subAgents.d.ts +9 -0
- package/dist/routes/subAgents.js +210 -0
- package/dist/routes/thirdPartyMCPServers.d.ts +14 -0
- package/dist/routes/thirdPartyMCPServers.js +72 -0
- package/dist/routes/tools.d.ts +9 -0
- package/dist/routes/tools.js +256 -0
- package/dist/routes/userOrganizations.d.ts +9 -0
- package/dist/routes/userOrganizations.js +58 -0
- package/dist/sso-helpers.d.ts +20 -0
- package/dist/sso-helpers.js +51 -0
- package/dist/types/app.d.ts +47 -0
- package/dist/types/app.js +1 -0
- package/dist/utils/cors.d.ts +33 -0
- package/dist/utils/cors.js +98 -0
- package/dist/utils/oauth-service.d.ts +71 -0
- package/dist/utils/oauth-service.js +106 -0
- package/dist/utils/signoz-helpers.d.ts +9 -0
- package/dist/utils/signoz-helpers.js +33 -0
- package/dist/utils/temp-api-keys.d.ts +17 -0
- package/dist/utils/temp-api-keys.js +26 -0
- package/package.json +6 -13
- package/dist/chunk-VBDAOXYI.js +0 -832
- package/dist/chunk-VBDAOXYI.js.map +0 -1
- package/dist/factory2.d.ts +0 -41
- package/dist/factory2.d.ts.map +0 -1
- package/dist/factory2.js +0 -37085
- package/dist/factory2.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/nodefs.js +0 -27
- package/dist/nodefs.js.map +0 -1
- package/dist/opfs-ahp.js +0 -368
- package/dist/opfs-ahp.js.map +0 -1
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { getLogger as getLogger$1 } from "../logger.js";
|
|
2
|
+
import dbClient_default from "../data/db/dbClient.js";
|
|
3
|
+
import { oauthService, retrievePKCEVerifier } from "../utils/oauth-service.js";
|
|
4
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
5
|
+
import { CredentialReferenceApiSelectSchema, CredentialStoreType, OAuthCallbackQuerySchema, OAuthLoginQuerySchema, createCredentialReference, generateId, getCredentialReferenceWithResources, getToolById, updateTool } from "@inkeep/agents-core";
|
|
6
|
+
|
|
7
|
+
//#region src/routes/oauth.ts
|
|
8
|
+
/**
|
|
9
|
+
* OAuth Callback Handler
|
|
10
|
+
*
|
|
11
|
+
* Handles OAuth 2.1 authorization code flows for MCP tools:
|
|
12
|
+
* - Processes authorization codes from OAuth providers
|
|
13
|
+
* - Exchanges codes for access tokens using PKCE
|
|
14
|
+
* - Stores credentials in Keychain
|
|
15
|
+
* - Updates MCP tool status
|
|
16
|
+
* - Redirects users back to frontend
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Find existing credential or create a new one (idempotent operation)
|
|
20
|
+
*/
|
|
21
|
+
async function findOrCreateCredential(tenantId, projectId, credentialData) {
|
|
22
|
+
try {
|
|
23
|
+
const existingCredential = await getCredentialReferenceWithResources(dbClient_default)({
|
|
24
|
+
scopes: {
|
|
25
|
+
tenantId,
|
|
26
|
+
projectId
|
|
27
|
+
},
|
|
28
|
+
id: credentialData.id
|
|
29
|
+
});
|
|
30
|
+
if (existingCredential) return CredentialReferenceApiSelectSchema.parse(existingCredential);
|
|
31
|
+
} catch {}
|
|
32
|
+
try {
|
|
33
|
+
const credential = await createCredentialReference(dbClient_default)({
|
|
34
|
+
...credentialData,
|
|
35
|
+
tenantId,
|
|
36
|
+
projectId
|
|
37
|
+
});
|
|
38
|
+
return CredentialReferenceApiSelectSchema.parse(credential);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error("Failed to save credential to database:", error);
|
|
41
|
+
throw new Error(`Failed to save credential '${credentialData.id}' to database`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const app = new OpenAPIHono();
|
|
45
|
+
const logger = getLogger$1("oauth-callback");
|
|
46
|
+
/**
|
|
47
|
+
* Extract base URL from request context
|
|
48
|
+
*/
|
|
49
|
+
function getBaseUrlFromRequest(c) {
|
|
50
|
+
const url = new URL(c.req.url);
|
|
51
|
+
return `${url.protocol}//${url.host}`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Generate OAuth callback HTML page
|
|
55
|
+
*/
|
|
56
|
+
function generateOAuthCallbackPage(params) {
|
|
57
|
+
const { title, message, isSuccess } = params;
|
|
58
|
+
return `
|
|
59
|
+
<!DOCTYPE html>
|
|
60
|
+
<html>
|
|
61
|
+
<head>
|
|
62
|
+
<title>${title}</title>
|
|
63
|
+
<meta charset="utf-8">
|
|
64
|
+
<style>
|
|
65
|
+
body {
|
|
66
|
+
background-color: #000;
|
|
67
|
+
color: #fff;
|
|
68
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
height: 100vh;
|
|
73
|
+
margin: 0;
|
|
74
|
+
text-align: center;
|
|
75
|
+
}
|
|
76
|
+
.container {
|
|
77
|
+
max-width: 400px;
|
|
78
|
+
padding: 2rem;
|
|
79
|
+
}
|
|
80
|
+
.title {
|
|
81
|
+
font-size: 1.2rem;
|
|
82
|
+
margin-bottom: 1rem;
|
|
83
|
+
}
|
|
84
|
+
.message {
|
|
85
|
+
color: #ccc;
|
|
86
|
+
line-height: 1.5;
|
|
87
|
+
}
|
|
88
|
+
.countdown {
|
|
89
|
+
margin-top: 1rem;
|
|
90
|
+
font-size: 0.9rem;
|
|
91
|
+
}
|
|
92
|
+
</style>
|
|
93
|
+
</head>
|
|
94
|
+
<body>
|
|
95
|
+
<div class="container">
|
|
96
|
+
<div class="title">${title}</div>
|
|
97
|
+
<div class="message">${message}</div>
|
|
98
|
+
<div class="message countdown">
|
|
99
|
+
${isSuccess ? "Closing automatically..." : ""}
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<script>
|
|
103
|
+
${isSuccess && `
|
|
104
|
+
// Success: Send PostMessage then auto-close
|
|
105
|
+
if (window.opener) {
|
|
106
|
+
try {
|
|
107
|
+
window.opener.postMessage({
|
|
108
|
+
type: 'oauth-success',
|
|
109
|
+
timestamp: Date.now()
|
|
110
|
+
}, '*');
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error('PostMessage failed:', error);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Auto-close after brief delay
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
window.close();
|
|
119
|
+
}, 1000);
|
|
120
|
+
`}
|
|
121
|
+
<\/script>
|
|
122
|
+
</body>
|
|
123
|
+
</html>
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
app.openapi(createRoute({
|
|
127
|
+
method: "get",
|
|
128
|
+
path: "/login",
|
|
129
|
+
summary: "Initiate OAuth login for MCP tool",
|
|
130
|
+
description: "Detects OAuth requirements and redirects to authorization server (public endpoint)",
|
|
131
|
+
operationId: "initiate-oauth-login-public",
|
|
132
|
+
tags: ["OAuth"],
|
|
133
|
+
request: { query: OAuthLoginQuerySchema },
|
|
134
|
+
responses: {
|
|
135
|
+
302: { description: "Redirect to OAuth authorization server" },
|
|
136
|
+
400: {
|
|
137
|
+
description: "OAuth not supported or configuration error",
|
|
138
|
+
content: { "text/html": { schema: z.string() } }
|
|
139
|
+
},
|
|
140
|
+
404: {
|
|
141
|
+
description: "Tool not found",
|
|
142
|
+
content: { "text/html": { schema: z.string() } }
|
|
143
|
+
},
|
|
144
|
+
500: {
|
|
145
|
+
description: "Internal server error",
|
|
146
|
+
content: { "text/html": { schema: z.string() } }
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}), async (c) => {
|
|
150
|
+
const { tenantId, projectId, toolId } = c.req.valid("query");
|
|
151
|
+
try {
|
|
152
|
+
const tool = await getToolById(dbClient_default)({
|
|
153
|
+
scopes: {
|
|
154
|
+
tenantId,
|
|
155
|
+
projectId
|
|
156
|
+
},
|
|
157
|
+
toolId
|
|
158
|
+
});
|
|
159
|
+
if (!tool) {
|
|
160
|
+
logger.error({
|
|
161
|
+
toolId,
|
|
162
|
+
tenantId,
|
|
163
|
+
projectId
|
|
164
|
+
}, "Tool not found for OAuth login");
|
|
165
|
+
return c.text("Tool not found", 404);
|
|
166
|
+
}
|
|
167
|
+
const baseUrl = getBaseUrlFromRequest(c);
|
|
168
|
+
const { redirectUrl } = await oauthService.initiateOAuthFlow({
|
|
169
|
+
tenantId,
|
|
170
|
+
projectId,
|
|
171
|
+
toolId,
|
|
172
|
+
mcpServerUrl: tool.config.mcp.server.url,
|
|
173
|
+
baseUrl
|
|
174
|
+
});
|
|
175
|
+
return c.redirect(redirectUrl, 302);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
logger.error({
|
|
178
|
+
toolId,
|
|
179
|
+
tenantId,
|
|
180
|
+
projectId,
|
|
181
|
+
error
|
|
182
|
+
}, "OAuth login failed");
|
|
183
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to initiate OAuth login";
|
|
184
|
+
return c.text(`OAuth Error: ${errorMessage}`, 500);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
app.openapi(createRoute({
|
|
188
|
+
method: "get",
|
|
189
|
+
path: "/callback",
|
|
190
|
+
summary: "MCP OAuth authorization callback",
|
|
191
|
+
description: "Handles OAuth authorization codes for MCP tools and completes the authentication flow",
|
|
192
|
+
operationId: "mcp-oauth-callback",
|
|
193
|
+
tags: ["OAuth"],
|
|
194
|
+
request: { query: OAuthCallbackQuerySchema },
|
|
195
|
+
responses: {
|
|
196
|
+
302: { description: "Redirect to frontend after successful OAuth" },
|
|
197
|
+
400: {
|
|
198
|
+
description: "OAuth error or invalid request",
|
|
199
|
+
content: { "text/html": { schema: z.string() } }
|
|
200
|
+
},
|
|
201
|
+
500: {
|
|
202
|
+
description: "Internal server error",
|
|
203
|
+
content: { "text/html": { schema: z.string() } }
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}), async (c) => {
|
|
207
|
+
try {
|
|
208
|
+
const { code, state, error, error_description } = c.req.valid("query");
|
|
209
|
+
logger.info({
|
|
210
|
+
state,
|
|
211
|
+
hasCode: !!code
|
|
212
|
+
}, "OAuth callback received");
|
|
213
|
+
if (error) {
|
|
214
|
+
logger.error({
|
|
215
|
+
error,
|
|
216
|
+
error_description
|
|
217
|
+
}, "OAuth authorization failed");
|
|
218
|
+
const errorPage = generateOAuthCallbackPage({
|
|
219
|
+
title: "Authentication Failed",
|
|
220
|
+
message: error_description || error || "OAuth Authorization Failed. Please try again.",
|
|
221
|
+
isSuccess: false
|
|
222
|
+
});
|
|
223
|
+
return c.html(errorPage);
|
|
224
|
+
}
|
|
225
|
+
const pkceData = retrievePKCEVerifier(state);
|
|
226
|
+
if (!pkceData) {
|
|
227
|
+
logger.error({ state }, "Invalid or expired OAuth state");
|
|
228
|
+
const expiredPage = generateOAuthCallbackPage({
|
|
229
|
+
title: "Session Expired",
|
|
230
|
+
message: "OAuth Session Expired: The OAuth session has expired or is invalid. Please try again.",
|
|
231
|
+
isSuccess: false
|
|
232
|
+
});
|
|
233
|
+
return c.html(expiredPage);
|
|
234
|
+
}
|
|
235
|
+
const { codeVerifier, toolId, tenantId, projectId, clientInformation, metadata, resourceUrl } = pkceData;
|
|
236
|
+
const tool = await getToolById(dbClient_default)({
|
|
237
|
+
scopes: {
|
|
238
|
+
tenantId,
|
|
239
|
+
projectId
|
|
240
|
+
},
|
|
241
|
+
toolId
|
|
242
|
+
});
|
|
243
|
+
if (!tool) throw new Error(`Tool ${toolId} not found`);
|
|
244
|
+
logger.info({
|
|
245
|
+
toolId,
|
|
246
|
+
tenantId,
|
|
247
|
+
projectId
|
|
248
|
+
}, "Processing OAuth callback");
|
|
249
|
+
logger.info({ toolId }, "Exchanging authorization code for access token");
|
|
250
|
+
const credentialStores = c.get("credentialStores");
|
|
251
|
+
const baseUrl = getBaseUrlFromRequest(c);
|
|
252
|
+
const { tokens } = await oauthService.exchangeCodeForTokens({
|
|
253
|
+
code,
|
|
254
|
+
codeVerifier,
|
|
255
|
+
clientInformation,
|
|
256
|
+
metadata,
|
|
257
|
+
resourceUrl,
|
|
258
|
+
mcpServerUrl: tool.config.mcp.server.url,
|
|
259
|
+
baseUrl
|
|
260
|
+
});
|
|
261
|
+
logger.info({
|
|
262
|
+
toolId,
|
|
263
|
+
tokenType: tokens.token_type,
|
|
264
|
+
hasRefresh: !!tokens.refresh_token
|
|
265
|
+
}, "Token exchange successful");
|
|
266
|
+
const credentialTokenKey = `oauth_token_${toolId}`;
|
|
267
|
+
let newCredentialData;
|
|
268
|
+
const keychainStore = credentialStores.get("keychain-default");
|
|
269
|
+
if (keychainStore) try {
|
|
270
|
+
await keychainStore.set(credentialTokenKey, JSON.stringify(tokens));
|
|
271
|
+
newCredentialData = {
|
|
272
|
+
id: generateId(),
|
|
273
|
+
name: tool.name,
|
|
274
|
+
type: CredentialStoreType.keychain,
|
|
275
|
+
credentialStoreId: "keychain-default",
|
|
276
|
+
retrievalParams: { key: credentialTokenKey }
|
|
277
|
+
};
|
|
278
|
+
} catch (error$1) {
|
|
279
|
+
logger.info({ error: error$1 instanceof Error ? error$1.message : error$1 }, "Keychain store not available.");
|
|
280
|
+
}
|
|
281
|
+
if (!newCredentialData) throw new Error("No credential store found");
|
|
282
|
+
const newCredential = await findOrCreateCredential(tenantId, projectId, newCredentialData);
|
|
283
|
+
await updateTool(dbClient_default)({
|
|
284
|
+
scopes: {
|
|
285
|
+
tenantId,
|
|
286
|
+
projectId
|
|
287
|
+
},
|
|
288
|
+
toolId,
|
|
289
|
+
data: { credentialReferenceId: newCredential.id }
|
|
290
|
+
});
|
|
291
|
+
logger.info({
|
|
292
|
+
toolId,
|
|
293
|
+
credentialId: newCredential.id
|
|
294
|
+
}, "OAuth flow completed successfully");
|
|
295
|
+
const successPage = generateOAuthCallbackPage({
|
|
296
|
+
title: "Authentication Complete",
|
|
297
|
+
message: "You have been successfully authenticated.",
|
|
298
|
+
isSuccess: true
|
|
299
|
+
});
|
|
300
|
+
return c.html(successPage);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
logger.error({ error }, "OAuth callback processing failed");
|
|
303
|
+
const errorPage = generateOAuthCallbackPage({
|
|
304
|
+
title: "Processing Failed",
|
|
305
|
+
message: "OAuth Processing Failed. Please try again.",
|
|
306
|
+
isSuccess: false
|
|
307
|
+
});
|
|
308
|
+
return c.html(errorPage);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
var oauth_default = app;
|
|
312
|
+
|
|
313
|
+
//#endregion
|
|
314
|
+
export { oauth_default as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseAppVariables } from "../types/app.js";
|
|
2
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
3
|
+
|
|
4
|
+
//#region src/routes/playgroundToken.d.ts
|
|
5
|
+
declare const app: OpenAPIHono<{
|
|
6
|
+
Variables: BaseAppVariables;
|
|
7
|
+
}, {}, "/">;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { app as default };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { env } from "../env.js";
|
|
2
|
+
import { getLogger as getLogger$1 } from "../logger.js";
|
|
3
|
+
import dbClient_default from "../data/db/dbClient.js";
|
|
4
|
+
import { requirePermission } from "../middleware/require-permission.js";
|
|
5
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
6
|
+
import { ErrorResponseSchema, TenantParamsSchema, createApiError, getAgentById, projectExists, signTempToken } from "@inkeep/agents-core";
|
|
7
|
+
|
|
8
|
+
//#region src/routes/playgroundToken.ts
|
|
9
|
+
const logger = getLogger$1("playgroundToken");
|
|
10
|
+
const app = new OpenAPIHono();
|
|
11
|
+
app.use("/", requirePermission({ agent: ["create"] }));
|
|
12
|
+
const PlaygroundTokenRequestSchema = z.object({
|
|
13
|
+
projectId: z.string(),
|
|
14
|
+
agentId: z.string()
|
|
15
|
+
});
|
|
16
|
+
const PlaygroundTokenResponseSchema = z.object({
|
|
17
|
+
apiKey: z.string().describe("Temporary API key for playground use"),
|
|
18
|
+
expiresAt: z.string().describe("ISO 8601 timestamp when the key expires")
|
|
19
|
+
});
|
|
20
|
+
app.openapi(createRoute({
|
|
21
|
+
method: "post",
|
|
22
|
+
path: "/",
|
|
23
|
+
summary: "Generate temporary API key for playground",
|
|
24
|
+
operationId: "create-playground-token",
|
|
25
|
+
tags: ["Playground"],
|
|
26
|
+
description: "Generates a short-lived API key (1 hour expiry) for authenticated users to access the run-api from the playground",
|
|
27
|
+
security: [{ cookieAuth: [] }],
|
|
28
|
+
request: {
|
|
29
|
+
params: TenantParamsSchema,
|
|
30
|
+
body: { content: { "application/json": { schema: PlaygroundTokenRequestSchema } } }
|
|
31
|
+
},
|
|
32
|
+
responses: {
|
|
33
|
+
200: {
|
|
34
|
+
description: "Temporary API key generated successfully",
|
|
35
|
+
content: { "application/json": { schema: PlaygroundTokenResponseSchema } }
|
|
36
|
+
},
|
|
37
|
+
401: {
|
|
38
|
+
description: "Unauthorized - session required",
|
|
39
|
+
content: { "application/json": { schema: ErrorResponseSchema } }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}), async (c) => {
|
|
43
|
+
const userId = c.get("userId");
|
|
44
|
+
const tenantId = c.get("tenantId");
|
|
45
|
+
const { projectId, agentId } = c.req.valid("json");
|
|
46
|
+
logger.info({
|
|
47
|
+
userId,
|
|
48
|
+
tenantId,
|
|
49
|
+
projectId,
|
|
50
|
+
agentId
|
|
51
|
+
}, "Generating temporary JWT token for playground");
|
|
52
|
+
if (!await projectExists(dbClient_default)({
|
|
53
|
+
tenantId,
|
|
54
|
+
projectId
|
|
55
|
+
})) {
|
|
56
|
+
logger.warn({
|
|
57
|
+
userId,
|
|
58
|
+
tenantId,
|
|
59
|
+
projectId
|
|
60
|
+
}, "Project not found or access denied");
|
|
61
|
+
throw createApiError({
|
|
62
|
+
code: "not_found",
|
|
63
|
+
message: "Project not found"
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (!await getAgentById(dbClient_default)({ scopes: {
|
|
67
|
+
tenantId,
|
|
68
|
+
projectId,
|
|
69
|
+
agentId
|
|
70
|
+
} })) {
|
|
71
|
+
logger.warn({
|
|
72
|
+
userId,
|
|
73
|
+
tenantId,
|
|
74
|
+
projectId,
|
|
75
|
+
agentId
|
|
76
|
+
}, "Agent not found or access denied");
|
|
77
|
+
throw createApiError({
|
|
78
|
+
code: "not_found",
|
|
79
|
+
message: "Agent not found"
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (!env.INKEEP_AGENTS_TEMP_JWT_PRIVATE_KEY) throw createApiError({
|
|
83
|
+
code: "internal_server_error",
|
|
84
|
+
message: "Temporary token signing not configured"
|
|
85
|
+
});
|
|
86
|
+
const result = await signTempToken(Buffer.from(env.INKEEP_AGENTS_TEMP_JWT_PRIVATE_KEY, "base64").toString("utf-8"), {
|
|
87
|
+
tenantId,
|
|
88
|
+
projectId,
|
|
89
|
+
agentId,
|
|
90
|
+
type: "temporary",
|
|
91
|
+
initiatedBy: {
|
|
92
|
+
type: "user",
|
|
93
|
+
id: userId
|
|
94
|
+
}
|
|
95
|
+
}, userId);
|
|
96
|
+
logger.info({
|
|
97
|
+
userId,
|
|
98
|
+
expiresAt: result.expiresAt
|
|
99
|
+
}, "Temporary JWT token generated");
|
|
100
|
+
return c.json({
|
|
101
|
+
apiKey: result.token,
|
|
102
|
+
expiresAt: result.expiresAt
|
|
103
|
+
}, 200);
|
|
104
|
+
});
|
|
105
|
+
var playgroundToken_default = app;
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
export { playgroundToken_default as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseAppVariables } from "../types/app.js";
|
|
2
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
3
|
+
|
|
4
|
+
//#region src/routes/projectFull.d.ts
|
|
5
|
+
declare const app: OpenAPIHono<{
|
|
6
|
+
Variables: BaseAppVariables;
|
|
7
|
+
}, {}, "/">;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { app as default };
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { getLogger as getLogger$1 } from "../logger.js";
|
|
2
|
+
import dbClient_default from "../data/db/dbClient.js";
|
|
3
|
+
import { requirePermission } from "../middleware/require-permission.js";
|
|
4
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
5
|
+
import { ErrorResponseSchema, FullProjectDefinitionResponse, FullProjectDefinitionSchema, TenantParamsSchema, TenantProjectParamsSchema, commonGetErrorResponses, createApiError, createFullProjectServerSide, deleteFullProject, getFullProject, updateFullProjectServerSide } from "@inkeep/agents-core";
|
|
6
|
+
|
|
7
|
+
//#region src/routes/projectFull.ts
|
|
8
|
+
const logger = getLogger$1("projectFull");
|
|
9
|
+
const app = new OpenAPIHono();
|
|
10
|
+
app.use("/project-full", async (c, next) => {
|
|
11
|
+
if (c.req.method === "POST") return requirePermission({ project: ["create"] })(c, next);
|
|
12
|
+
return next();
|
|
13
|
+
});
|
|
14
|
+
app.use("/project-full/:projectId", async (c, next) => {
|
|
15
|
+
if (c.req.method === "PUT") return requirePermission({ project: ["update"] })(c, next);
|
|
16
|
+
if (c.req.method === "DELETE") return requirePermission({ project: ["delete"] })(c, next);
|
|
17
|
+
return next();
|
|
18
|
+
});
|
|
19
|
+
app.openapi(createRoute({
|
|
20
|
+
method: "post",
|
|
21
|
+
path: "/project-full",
|
|
22
|
+
summary: "Create Full Project",
|
|
23
|
+
operationId: "create-full-project",
|
|
24
|
+
tags: ["Full Project"],
|
|
25
|
+
description: "Create a complete project with all Agents, Sub Agents, tools, and relationships from JSON definition",
|
|
26
|
+
request: {
|
|
27
|
+
params: TenantParamsSchema,
|
|
28
|
+
body: { content: { "application/json": { schema: FullProjectDefinitionSchema } } }
|
|
29
|
+
},
|
|
30
|
+
responses: {
|
|
31
|
+
201: {
|
|
32
|
+
description: "Full project created successfully",
|
|
33
|
+
content: { "application/json": { schema: FullProjectDefinitionResponse } }
|
|
34
|
+
},
|
|
35
|
+
409: {
|
|
36
|
+
description: "Project already exists",
|
|
37
|
+
content: { "application/json": { schema: ErrorResponseSchema } }
|
|
38
|
+
},
|
|
39
|
+
...commonGetErrorResponses
|
|
40
|
+
}
|
|
41
|
+
}), async (c) => {
|
|
42
|
+
const { tenantId } = c.req.valid("param");
|
|
43
|
+
const projectData = c.req.valid("json");
|
|
44
|
+
const validatedProjectData = FullProjectDefinitionSchema.parse(projectData);
|
|
45
|
+
try {
|
|
46
|
+
const createdProject = await createFullProjectServerSide(dbClient_default, logger)({
|
|
47
|
+
tenantId,
|
|
48
|
+
projectId: validatedProjectData.id
|
|
49
|
+
}, validatedProjectData);
|
|
50
|
+
return c.json({ data: createdProject }, 201);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
logger.error({ error }, "Error creating project");
|
|
53
|
+
if (error?.cause?.code === "23505") throw createApiError({
|
|
54
|
+
code: "conflict",
|
|
55
|
+
message: `Project with ID '${projectData.id}' already exists`
|
|
56
|
+
});
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
app.openapi(createRoute({
|
|
61
|
+
method: "get",
|
|
62
|
+
path: "/project-full/{projectId}",
|
|
63
|
+
summary: "Get Full Project",
|
|
64
|
+
operationId: "get-full-project",
|
|
65
|
+
tags: ["Full Project"],
|
|
66
|
+
description: "Retrieve a complete project definition with all Agents, Sub Agents, tools, and relationships",
|
|
67
|
+
request: { params: TenantProjectParamsSchema },
|
|
68
|
+
responses: {
|
|
69
|
+
200: {
|
|
70
|
+
description: "Full project found",
|
|
71
|
+
content: { "application/json": { schema: FullProjectDefinitionResponse } }
|
|
72
|
+
},
|
|
73
|
+
...commonGetErrorResponses
|
|
74
|
+
}
|
|
75
|
+
}), async (c) => {
|
|
76
|
+
const { tenantId, projectId } = c.req.valid("param");
|
|
77
|
+
try {
|
|
78
|
+
const project = await getFullProject(dbClient_default, logger)({ scopes: {
|
|
79
|
+
tenantId,
|
|
80
|
+
projectId
|
|
81
|
+
} });
|
|
82
|
+
if (!project) throw createApiError({
|
|
83
|
+
code: "not_found",
|
|
84
|
+
message: "Project not found"
|
|
85
|
+
});
|
|
86
|
+
return c.json({ data: project });
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (error instanceof Error && error.message.includes("not found")) throw createApiError({
|
|
89
|
+
code: "not_found",
|
|
90
|
+
message: "Project not found"
|
|
91
|
+
});
|
|
92
|
+
throw createApiError({
|
|
93
|
+
code: "internal_server_error",
|
|
94
|
+
message: error instanceof Error ? error.message : "Failed to retrieve project"
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
app.openapi(createRoute({
|
|
99
|
+
method: "put",
|
|
100
|
+
path: "/project-full/{projectId}",
|
|
101
|
+
summary: "Update Full Project",
|
|
102
|
+
operationId: "update-full-project",
|
|
103
|
+
tags: ["Full Project"],
|
|
104
|
+
description: "Update or create a complete project with all Agents, Sub Agents, tools, and relationships from JSON definition",
|
|
105
|
+
request: {
|
|
106
|
+
params: TenantProjectParamsSchema,
|
|
107
|
+
body: { content: { "application/json": { schema: FullProjectDefinitionSchema } } }
|
|
108
|
+
},
|
|
109
|
+
responses: {
|
|
110
|
+
200: {
|
|
111
|
+
description: "Full project updated successfully",
|
|
112
|
+
content: { "application/json": { schema: FullProjectDefinitionResponse } }
|
|
113
|
+
},
|
|
114
|
+
201: {
|
|
115
|
+
description: "Full project created successfully",
|
|
116
|
+
content: { "application/json": { schema: FullProjectDefinitionResponse } }
|
|
117
|
+
},
|
|
118
|
+
...commonGetErrorResponses
|
|
119
|
+
}
|
|
120
|
+
}), async (c) => {
|
|
121
|
+
const { tenantId, projectId } = c.req.valid("param");
|
|
122
|
+
const projectData = c.req.valid("json");
|
|
123
|
+
try {
|
|
124
|
+
const validatedProjectData = FullProjectDefinitionSchema.parse(projectData);
|
|
125
|
+
if (projectId !== validatedProjectData.id) throw createApiError({
|
|
126
|
+
code: "bad_request",
|
|
127
|
+
message: `Project ID mismatch: expected ${projectId}, got ${validatedProjectData.id}`
|
|
128
|
+
});
|
|
129
|
+
const isCreate = !await getFullProject(dbClient_default, logger)({ scopes: {
|
|
130
|
+
tenantId,
|
|
131
|
+
projectId
|
|
132
|
+
} });
|
|
133
|
+
const updatedProject = isCreate ? await createFullProjectServerSide(dbClient_default, logger)({
|
|
134
|
+
tenantId,
|
|
135
|
+
projectId
|
|
136
|
+
}, validatedProjectData) : await updateFullProjectServerSide(dbClient_default, logger)({
|
|
137
|
+
tenantId,
|
|
138
|
+
projectId
|
|
139
|
+
}, validatedProjectData);
|
|
140
|
+
return c.json({ data: updatedProject }, isCreate ? 201 : 200);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
if (error instanceof z.ZodError) throw createApiError({
|
|
143
|
+
code: "bad_request",
|
|
144
|
+
message: "Invalid project definition"
|
|
145
|
+
});
|
|
146
|
+
if (error instanceof Error && error.message.includes("ID mismatch")) throw createApiError({
|
|
147
|
+
code: "bad_request",
|
|
148
|
+
message: error.message
|
|
149
|
+
});
|
|
150
|
+
throw createApiError({
|
|
151
|
+
code: "internal_server_error",
|
|
152
|
+
message: error instanceof Error ? error.message : "Failed to update project"
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
app.openapi(createRoute({
|
|
157
|
+
method: "delete",
|
|
158
|
+
path: "/project-full/{projectId}",
|
|
159
|
+
summary: "Delete Full Project",
|
|
160
|
+
operationId: "delete-full-project",
|
|
161
|
+
tags: ["Full Project"],
|
|
162
|
+
description: "Delete a complete project and cascade to all related entities (Agents, Sub Agents, tools, relationships)",
|
|
163
|
+
request: { params: TenantProjectParamsSchema },
|
|
164
|
+
responses: {
|
|
165
|
+
204: { description: "Project deleted successfully" },
|
|
166
|
+
...commonGetErrorResponses
|
|
167
|
+
}
|
|
168
|
+
}), async (c) => {
|
|
169
|
+
const { tenantId, projectId } = c.req.valid("param");
|
|
170
|
+
try {
|
|
171
|
+
if (!await deleteFullProject(dbClient_default, logger)({ scopes: {
|
|
172
|
+
tenantId,
|
|
173
|
+
projectId
|
|
174
|
+
} })) throw createApiError({
|
|
175
|
+
code: "not_found",
|
|
176
|
+
message: "Project not found"
|
|
177
|
+
});
|
|
178
|
+
return c.body(null, 204);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
if (error instanceof Error && error.message.includes("not found")) throw createApiError({
|
|
181
|
+
code: "not_found",
|
|
182
|
+
message: "Project not found"
|
|
183
|
+
});
|
|
184
|
+
throw createApiError({
|
|
185
|
+
code: "internal_server_error",
|
|
186
|
+
message: error instanceof Error ? error.message : "Failed to delete project"
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
var projectFull_default = app;
|
|
191
|
+
|
|
192
|
+
//#endregion
|
|
193
|
+
export { projectFull_default as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseAppVariables } from "../types/app.js";
|
|
2
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
3
|
+
|
|
4
|
+
//#region src/routes/projects.d.ts
|
|
5
|
+
declare const app: OpenAPIHono<{
|
|
6
|
+
Variables: BaseAppVariables;
|
|
7
|
+
}, {}, "/">;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { app as default };
|