@inkeep/agents-api 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/.well-known/workflow/v1/manifest.debug.json +6 -6
- package/dist/.well-known/workflow/v1/step.cjs +220467 -203416
- package/dist/_virtual/rolldown_runtime.js +7 -0
- package/dist/createApp.js +47 -17
- package/dist/domains/evals/api/.well-known/workflow/v1/flow.d.ts +4 -0
- package/dist/domains/evals/api/.well-known/workflow/v1/flow.js +12 -0
- package/dist/domains/evals/api/.well-known/workflow/v1/step.d.ts +4 -0
- package/dist/domains/evals/api/.well-known/workflow/v1/step.js +12 -0
- package/dist/domains/evals/routes/datasetTriggers.d.ts +2 -2
- package/dist/domains/evals/routes/index.d.ts +2 -2
- package/dist/domains/evals/scripts/build-workflow.js +2 -2
- package/dist/domains/evals/workflow/world.js +3 -2
- package/dist/domains/manage/index.js +6 -2
- package/dist/domains/manage/routes/agent.js +7 -4
- package/dist/domains/manage/routes/agentFull.js +9 -6
- package/dist/domains/manage/routes/apiKeys.js +1 -2
- package/dist/domains/manage/routes/artifactComponents.js +5 -5
- package/dist/domains/manage/routes/cliAuth.js +3 -3
- package/dist/domains/manage/routes/contextConfigs.js +5 -5
- package/dist/domains/manage/routes/conversations.d.ts +2 -2
- package/dist/domains/manage/routes/credentialStores.js +2 -2
- package/dist/domains/manage/routes/credentials.js +6 -7
- package/dist/domains/manage/routes/dataComponents.js +6 -7
- package/dist/domains/manage/routes/externalAgents.js +1 -2
- package/dist/domains/manage/routes/github.d.ts +16 -0
- package/dist/domains/manage/routes/github.js +511 -0
- package/dist/domains/manage/routes/index.d.ts +2 -2
- package/dist/domains/manage/routes/index.js +4 -0
- package/dist/domains/manage/routes/invitations.js +1 -1
- package/dist/domains/manage/routes/mcp.d.ts +2 -2
- package/dist/domains/manage/routes/{agentToolRelations.d.ts → mcpToolGithubAccess.d.ts} +1 -1
- package/dist/domains/manage/routes/mcpToolGithubAccess.js +205 -0
- package/dist/domains/manage/routes/playgroundToken.js +1 -2
- package/dist/domains/manage/routes/projectFull.js +33 -11
- package/dist/domains/manage/routes/projectGithubAccess.d.ts +9 -0
- package/dist/domains/manage/routes/projectGithubAccess.js +167 -0
- package/dist/domains/manage/routes/projectMembers.js +12 -44
- package/dist/domains/manage/routes/projectPermissions.js +11 -11
- package/dist/domains/manage/routes/projects.js +15 -18
- package/dist/domains/manage/routes/signoz.d.ts +2 -2
- package/dist/domains/manage/routes/signoz.js +7 -4
- package/dist/domains/manage/routes/subAgentArtifactComponents.js +5 -5
- package/dist/domains/manage/routes/subAgentDataComponents.js +5 -5
- package/dist/domains/manage/routes/subAgentExternalAgentRelations.js +5 -5
- package/dist/domains/manage/routes/subAgentFunctionTools.js +5 -5
- package/dist/domains/manage/routes/subAgentRelations.js +6 -6
- package/dist/domains/manage/routes/subAgentTeamAgentRelations.js +6 -6
- package/dist/domains/manage/routes/subAgentToolRelations.js +6 -6
- package/dist/domains/manage/routes/subAgents.js +5 -5
- package/dist/domains/manage/routes/tools.js +28 -5
- package/dist/domains/manage/routes/triggers.js +49 -24
- package/dist/domains/manage/routes/userOrganizations.js +4 -4
- package/dist/domains/manage/routes/userProjectMemberships.d.ts +9 -0
- package/dist/domains/manage/routes/userProjectMemberships.js +44 -0
- package/dist/domains/mcp/routes/mcp.d.ts +7 -0
- package/dist/domains/mcp/routes/mcp.js +45 -0
- package/dist/domains/run/agents/Agent.d.ts +1 -0
- package/dist/domains/run/agents/Agent.js +235 -45
- package/dist/domains/run/agents/relationTools.d.ts +2 -2
- package/dist/domains/run/constants/execution-limits/defaults.d.ts +1 -1
- package/dist/domains/run/constants/execution-limits/defaults.js +1 -1
- package/dist/domains/run/constants/execution-limits/index.d.ts +1 -1
- package/dist/domains/run/context/ContextFetcher.js +8 -7
- package/dist/domains/run/context/validation.d.ts +1 -1
- package/dist/domains/run/handlers/executionHandler.js +143 -79
- package/dist/domains/run/routes/agents.js +1 -1
- package/dist/domains/run/routes/chat.js +47 -1
- package/dist/domains/run/routes/chatDataStream.js +107 -14
- package/dist/domains/run/routes/webhooks.js +40 -348
- package/dist/domains/run/services/AgentSession.d.ts +3 -0
- package/dist/domains/run/services/AgentSession.js +14 -1
- package/dist/domains/run/services/ToolApprovalUiBus.d.ts +28 -0
- package/dist/domains/run/services/ToolApprovalUiBus.js +44 -0
- package/dist/domains/run/services/TriggerService.d.ts +31 -0
- package/dist/domains/run/services/TriggerService.js +545 -0
- package/dist/domains/run/tools/NativeSandboxExecutor.d.ts +3 -2
- package/dist/domains/run/tools/NativeSandboxExecutor.js +76 -48
- package/dist/domains/run/tools/SandboxExecutorFactory.d.ts +11 -1
- package/dist/domains/run/tools/SandboxExecutorFactory.js +27 -3
- package/dist/domains/run/tools/VercelSandboxExecutor.d.ts +3 -11
- package/dist/domains/run/tools/VercelSandboxExecutor.js +137 -127
- package/dist/domains/run/tools/sandbox-utils.js +1 -1
- package/dist/domains/run/types/executionContext.js +3 -1
- package/dist/domains/run/utils/stream-helpers.d.ts +134 -0
- package/dist/domains/run/utils/stream-helpers.js +182 -0
- package/dist/domains/run/utils/token-estimator.d.ts +2 -2
- package/dist/env.d.ts +12 -2
- package/dist/env.js +37 -32
- package/dist/factory.d.ts +31 -31
- package/dist/factory.js +4 -10
- package/dist/index.d.ts +30 -29
- package/dist/index.js +3 -5
- package/dist/middleware/branchScopedDb.d.ts +1 -1
- package/dist/middleware/cors.js +1 -1
- package/dist/middleware/evalsAuth.d.ts +2 -2
- package/dist/middleware/manageAuth.d.ts +2 -2
- package/dist/middleware/projectAccess.d.ts +4 -20
- package/dist/middleware/projectAccess.js +7 -49
- package/dist/middleware/projectConfig.d.ts +3 -3
- package/dist/middleware/ref.d.ts +1 -1
- package/dist/middleware/requirePermission.d.ts +2 -2
- package/dist/middleware/requirePermission.js +1 -2
- package/dist/middleware/runAuth.d.ts +4 -4
- package/dist/middleware/sessionAuth.d.ts +3 -3
- package/dist/middleware/sessionAuth.js +1 -2
- package/dist/middleware/tenantAccess.d.ts +2 -2
- package/dist/middleware/tenantAccess.js +4 -4
- package/dist/middleware/tracing.d.ts +3 -3
- package/dist/openapi.d.ts +36 -1
- package/dist/openapi.js +40 -95
- package/dist/routes/healthChecks.d.ts +10 -0
- package/dist/routes/healthChecks.js +75 -0
- package/dist/types/app.d.ts +2 -0
- package/dist/types/runExecutionContext.js +3 -1
- package/dist/utils/healthChecks.d.ts +8 -0
- package/dist/utils/healthChecks.js +38 -0
- package/dist/utils/signozHelpers.d.ts +2 -2
- package/dist/utils/signozHelpers.js +15 -3
- package/package.json +8 -9
- package/dist/domains/evals/services/startEvaluation.d.ts +0 -19
- package/dist/domains/evals/services/startEvaluation.js +0 -18
- package/dist/domains/index.d.ts +0 -4
- package/dist/domains/index.js +0 -5
- package/dist/domains/manage/routes/agentToolRelations.js +0 -289
- package/dist/domains/run/agents/ModelFactory.d.ts +0 -63
- package/dist/domains/run/agents/ModelFactory.js +0 -194
- package/dist/domains/run/data/agent.d.ts +0 -7
- package/dist/domains/run/data/agent.js +0 -67
- package/dist/domains/run/services/evaluationRunConfigMatcher.d.ts +0 -4
- package/dist/domains/run/services/evaluationRunConfigMatcher.js +0 -7
- package/dist/domains/run/utils/cleanup.d.ts +0 -21
- package/dist/domains/run/utils/cleanup.js +0 -59
- package/dist/initialization.d.ts +0 -6
- package/dist/initialization.js +0 -65
- package/dist/utils/tempApiKeys.d.ts +0 -17
- package/dist/utils/tempApiKeys.js +0 -26
- package/dist/utils/workflowApiHelpers.d.ts +0 -1
- package/dist/utils/workflowApiHelpers.js +0 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { getLogger as getLogger$1 } from "../../../logger.js";
|
|
2
|
+
import runDbClient_default from "../../../data/db/runDbClient.js";
|
|
3
|
+
import { requireProjectPermission } from "../../../middleware/projectAccess.js";
|
|
4
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
5
|
+
import { TenantProjectParamsSchema, WorkAppGitHubAccessModeSchema, WorkAppGitHubAccessSetRequestSchema, WorkAppGitHubAccessSetResponseSchema, WorkAppGitHubRepositorySelectSchema, commonGetErrorResponses, commonUpdateErrorResponses, createApiError, getMcpToolAccessMode, getMcpToolRepositoryAccessWithDetails, getToolById, setMcpToolAccessMode, setMcpToolRepositoryAccess, validateRepositoryOwnership } from "@inkeep/agents-core";
|
|
6
|
+
|
|
7
|
+
//#region src/domains/manage/routes/mcpToolGithubAccess.ts
|
|
8
|
+
const logger = getLogger$1("mcp-tool-github-access");
|
|
9
|
+
const app = new OpenAPIHono();
|
|
10
|
+
const TenantProjectToolParamsSchema = TenantProjectParamsSchema.extend({ toolId: z.string().min(1).describe("The tool ID") });
|
|
11
|
+
const McpToolGitHubAccessModeSchema = WorkAppGitHubAccessModeSchema.describe("Access mode: \"all\" means the MCP tool has access to all project repositories, \"selected\" means the tool is scoped to specific repositories");
|
|
12
|
+
const SetGitHubAccessRequestSchema = WorkAppGitHubAccessSetRequestSchema.extend({ mode: McpToolGitHubAccessModeSchema });
|
|
13
|
+
const GetGitHubAccessResponseSchema = z.object({
|
|
14
|
+
mode: McpToolGitHubAccessModeSchema,
|
|
15
|
+
repositories: z.array(WorkAppGitHubRepositorySelectSchema.extend({ installationAccountLogin: z.string().describe("The GitHub account login for the installation") })).describe("List of repositories the MCP tool has access to (only populated when mode=\"selected\")")
|
|
16
|
+
});
|
|
17
|
+
const SetGitHubAccessResponseSchema = WorkAppGitHubAccessSetResponseSchema.extend({
|
|
18
|
+
mode: McpToolGitHubAccessModeSchema,
|
|
19
|
+
repositoryCount: z.number().describe("Number of repositories the MCP tool now has access to (0 when mode=\"all\")")
|
|
20
|
+
});
|
|
21
|
+
async function validateGitHubWorkappTool(db, tenantId, projectId, toolId) {
|
|
22
|
+
const tool = await getToolById(db)({
|
|
23
|
+
scopes: {
|
|
24
|
+
tenantId,
|
|
25
|
+
projectId
|
|
26
|
+
},
|
|
27
|
+
toolId
|
|
28
|
+
});
|
|
29
|
+
if (!tool) throw createApiError({
|
|
30
|
+
code: "not_found",
|
|
31
|
+
message: `Tool not found: ${toolId}`
|
|
32
|
+
});
|
|
33
|
+
if (!tool.isWorkApp) throw createApiError({
|
|
34
|
+
code: "bad_request",
|
|
35
|
+
message: "GitHub access can only be configured for workapp MCP tools"
|
|
36
|
+
});
|
|
37
|
+
if (!tool.config.mcp.server.url?.includes("/github")) throw createApiError({
|
|
38
|
+
code: "bad_request",
|
|
39
|
+
message: "GitHub access can only be configured for GitHub MCP tools"
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
app.use("/", requireProjectPermission("edit"));
|
|
43
|
+
app.openapi(createRoute({
|
|
44
|
+
method: "get",
|
|
45
|
+
path: "/",
|
|
46
|
+
summary: "Get MCP tool GitHub repository access",
|
|
47
|
+
operationId: "get-mcp-tool-github-access",
|
|
48
|
+
tags: ["Tools"],
|
|
49
|
+
description: "Returns the current GitHub repository access configuration for an MCP tool. If mode is \"all\", the tool has access to all repositories the project can access. If mode is \"selected\", the tool is scoped to specific repositories. ",
|
|
50
|
+
request: { params: TenantProjectToolParamsSchema },
|
|
51
|
+
responses: {
|
|
52
|
+
200: {
|
|
53
|
+
description: "GitHub access configuration retrieved successfully",
|
|
54
|
+
content: { "application/json": { schema: GetGitHubAccessResponseSchema } }
|
|
55
|
+
},
|
|
56
|
+
...commonGetErrorResponses
|
|
57
|
+
}
|
|
58
|
+
}), async (c) => {
|
|
59
|
+
const { tenantId, projectId, toolId } = c.req.valid("param");
|
|
60
|
+
const db = c.get("db");
|
|
61
|
+
logger.info({
|
|
62
|
+
tenantId,
|
|
63
|
+
projectId,
|
|
64
|
+
toolId
|
|
65
|
+
}, "Getting MCP tool GitHub access configuration");
|
|
66
|
+
await validateGitHubWorkappTool(db, tenantId, projectId, toolId);
|
|
67
|
+
if (await getMcpToolAccessMode(runDbClient_default)(toolId) === "all") {
|
|
68
|
+
logger.info({
|
|
69
|
+
tenantId,
|
|
70
|
+
projectId,
|
|
71
|
+
toolId
|
|
72
|
+
}, "MCP tool has access to all project repositories (mode=all)");
|
|
73
|
+
return c.json({
|
|
74
|
+
mode: "all",
|
|
75
|
+
repositories: []
|
|
76
|
+
}, 200);
|
|
77
|
+
}
|
|
78
|
+
const repositoriesWithDetails = await getMcpToolRepositoryAccessWithDetails(runDbClient_default)(toolId);
|
|
79
|
+
logger.info({
|
|
80
|
+
tenantId,
|
|
81
|
+
projectId,
|
|
82
|
+
toolId,
|
|
83
|
+
repositoryCount: repositoriesWithDetails.length
|
|
84
|
+
}, "Got MCP tool GitHub access configuration (mode=selected)");
|
|
85
|
+
return c.json({
|
|
86
|
+
mode: "selected",
|
|
87
|
+
repositories: repositoriesWithDetails.map((repo) => ({
|
|
88
|
+
id: repo.id,
|
|
89
|
+
installationDbId: repo.installationDbId,
|
|
90
|
+
repositoryId: repo.repositoryId,
|
|
91
|
+
repositoryName: repo.repositoryName,
|
|
92
|
+
repositoryFullName: repo.repositoryFullName,
|
|
93
|
+
private: repo.private,
|
|
94
|
+
createdAt: repo.createdAt,
|
|
95
|
+
updatedAt: repo.updatedAt,
|
|
96
|
+
installationAccountLogin: repo.installationAccountLogin
|
|
97
|
+
}))
|
|
98
|
+
}, 200);
|
|
99
|
+
});
|
|
100
|
+
app.openapi(createRoute({
|
|
101
|
+
method: "put",
|
|
102
|
+
path: "/",
|
|
103
|
+
summary: "Set MCP tool GitHub repository access",
|
|
104
|
+
operationId: "set-mcp-tool-github-access",
|
|
105
|
+
tags: ["Tools"],
|
|
106
|
+
description: "Configures which GitHub repositories an MCP tool can access. When mode is \"all\", the tool has access to all repositories the project can access. When mode is \"selected\", the tool is scoped to specific repositories (repositoryIds required). This replaces any existing access configuration. This endpoint only works for GitHub workapp MCP tools (isWorkApp=true and URL contains /github).",
|
|
107
|
+
request: {
|
|
108
|
+
params: TenantProjectToolParamsSchema,
|
|
109
|
+
body: { content: { "application/json": { schema: SetGitHubAccessRequestSchema } } }
|
|
110
|
+
},
|
|
111
|
+
responses: {
|
|
112
|
+
200: {
|
|
113
|
+
description: "GitHub access configuration updated successfully",
|
|
114
|
+
content: { "application/json": { schema: SetGitHubAccessResponseSchema } }
|
|
115
|
+
},
|
|
116
|
+
...commonUpdateErrorResponses
|
|
117
|
+
}
|
|
118
|
+
}), async (c) => {
|
|
119
|
+
const { tenantId, projectId, toolId } = c.req.valid("param");
|
|
120
|
+
const { mode, repositoryIds } = c.req.valid("json");
|
|
121
|
+
const db = c.get("db");
|
|
122
|
+
logger.info({
|
|
123
|
+
tenantId,
|
|
124
|
+
projectId,
|
|
125
|
+
toolId,
|
|
126
|
+
mode
|
|
127
|
+
}, "Setting MCP tool GitHub access configuration");
|
|
128
|
+
await validateGitHubWorkappTool(db, tenantId, projectId, toolId);
|
|
129
|
+
if (mode === "selected") {
|
|
130
|
+
if (!repositoryIds || repositoryIds.length === 0) {
|
|
131
|
+
logger.warn({
|
|
132
|
+
tenantId,
|
|
133
|
+
projectId,
|
|
134
|
+
toolId
|
|
135
|
+
}, "repositoryIds required when mode is selected");
|
|
136
|
+
throw createApiError({
|
|
137
|
+
code: "bad_request",
|
|
138
|
+
message: "repositoryIds is required when mode is \"selected\""
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const invalidRepoIds = await validateRepositoryOwnership(runDbClient_default)({
|
|
142
|
+
tenantId,
|
|
143
|
+
repositoryIds
|
|
144
|
+
});
|
|
145
|
+
if (invalidRepoIds.length > 0) {
|
|
146
|
+
logger.warn({
|
|
147
|
+
tenantId,
|
|
148
|
+
projectId,
|
|
149
|
+
toolId,
|
|
150
|
+
invalidRepoIds
|
|
151
|
+
}, "Some repository IDs do not belong to tenant installations");
|
|
152
|
+
throw createApiError({
|
|
153
|
+
code: "bad_request",
|
|
154
|
+
message: `Invalid repository IDs: ${invalidRepoIds.join(", ")}. Repositories must belong to GitHub installations owned by this tenant.`
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
await setMcpToolAccessMode(runDbClient_default)({
|
|
158
|
+
toolId,
|
|
159
|
+
tenantId,
|
|
160
|
+
projectId,
|
|
161
|
+
mode: "selected"
|
|
162
|
+
});
|
|
163
|
+
await setMcpToolRepositoryAccess(runDbClient_default)({
|
|
164
|
+
toolId,
|
|
165
|
+
tenantId,
|
|
166
|
+
projectId,
|
|
167
|
+
repositoryIds
|
|
168
|
+
});
|
|
169
|
+
logger.info({
|
|
170
|
+
tenantId,
|
|
171
|
+
projectId,
|
|
172
|
+
toolId,
|
|
173
|
+
repositoryCount: repositoryIds.length
|
|
174
|
+
}, "MCP tool GitHub access set to selected repositories");
|
|
175
|
+
return c.json({
|
|
176
|
+
mode: "selected",
|
|
177
|
+
repositoryCount: repositoryIds.length
|
|
178
|
+
}, 200);
|
|
179
|
+
}
|
|
180
|
+
await setMcpToolAccessMode(runDbClient_default)({
|
|
181
|
+
toolId,
|
|
182
|
+
tenantId,
|
|
183
|
+
projectId,
|
|
184
|
+
mode: "all"
|
|
185
|
+
});
|
|
186
|
+
await setMcpToolRepositoryAccess(runDbClient_default)({
|
|
187
|
+
toolId,
|
|
188
|
+
tenantId,
|
|
189
|
+
projectId,
|
|
190
|
+
repositoryIds: []
|
|
191
|
+
});
|
|
192
|
+
logger.info({
|
|
193
|
+
tenantId,
|
|
194
|
+
projectId,
|
|
195
|
+
toolId
|
|
196
|
+
}, "MCP tool GitHub access set to all project repositories");
|
|
197
|
+
return c.json({
|
|
198
|
+
mode: "all",
|
|
199
|
+
repositoryCount: 0
|
|
200
|
+
}, 200);
|
|
201
|
+
});
|
|
202
|
+
var mcpToolGithubAccess_default = app;
|
|
203
|
+
|
|
204
|
+
//#endregion
|
|
205
|
+
export { mcpToolGithubAccess_default as default };
|
|
@@ -19,7 +19,7 @@ app.openapi(createRoute({
|
|
|
19
19
|
path: "/",
|
|
20
20
|
summary: "Generate temporary API key for playground",
|
|
21
21
|
operationId: "create-playground-token",
|
|
22
|
-
tags: ["
|
|
22
|
+
tags: ["API Keys"],
|
|
23
23
|
description: "Generates a short-lived API key (1 hour expiry) for authenticated users to access the run-api from the playground",
|
|
24
24
|
security: [{ cookieAuth: [] }],
|
|
25
25
|
request: {
|
|
@@ -53,7 +53,6 @@ app.openapi(createRoute({
|
|
|
53
53
|
agentId
|
|
54
54
|
}, "Generating temporary JWT token for playground");
|
|
55
55
|
if (!await canUseProject({
|
|
56
|
-
tenantId,
|
|
57
56
|
userId,
|
|
58
57
|
projectId,
|
|
59
58
|
orgRole: tenantRole
|
|
@@ -14,16 +14,33 @@ app.use("/project-full", async (c, next) => {
|
|
|
14
14
|
return next();
|
|
15
15
|
});
|
|
16
16
|
app.use("/project-full/:projectId", async (c, next) => {
|
|
17
|
-
if (c.req.method === "
|
|
18
|
-
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
17
|
+
if (c.req.method === "GET") return requireProjectPermission("view")(c, next);
|
|
19
18
|
return next();
|
|
20
19
|
});
|
|
20
|
+
app.use("/project-full/:projectId/with-relation-ids", async (c, next) => {
|
|
21
|
+
if (c.req.method === "GET") return requireProjectPermission("view")(c, next);
|
|
22
|
+
return next();
|
|
23
|
+
});
|
|
24
|
+
const requireProjectUpsertPermission = async (c, next) => {
|
|
25
|
+
const tenantId = c.get("tenantId");
|
|
26
|
+
const projectId = c.req.param("projectId");
|
|
27
|
+
if (!tenantId || !projectId) throw createApiError({
|
|
28
|
+
code: "bad_request",
|
|
29
|
+
message: "Missing tenantId or projectId"
|
|
30
|
+
});
|
|
31
|
+
const exists = await getProjectMetadata(runDbClient_default)({
|
|
32
|
+
tenantId,
|
|
33
|
+
projectId
|
|
34
|
+
});
|
|
35
|
+
c.set("isProjectCreate", !exists);
|
|
36
|
+
return exists ? requireProjectPermission("edit")(c, next) : requirePermission({ project: ["create"] })(c, next);
|
|
37
|
+
};
|
|
21
38
|
app.openapi(createRoute({
|
|
22
39
|
method: "post",
|
|
23
40
|
path: "/project-full",
|
|
24
41
|
summary: "Create Full Project",
|
|
25
42
|
operationId: "create-full-project",
|
|
26
|
-
tags: ["
|
|
43
|
+
tags: ["Projects"],
|
|
27
44
|
description: "Create a complete project with all Agents, Sub Agents, tools, and relationships from JSON definition",
|
|
28
45
|
request: {
|
|
29
46
|
params: TenantParamsSchema,
|
|
@@ -90,7 +107,7 @@ app.openapi(createRoute({
|
|
|
90
107
|
path: "/project-full/{projectId}",
|
|
91
108
|
summary: "Get Full Project",
|
|
92
109
|
operationId: "get-full-project",
|
|
93
|
-
tags: ["
|
|
110
|
+
tags: ["Projects"],
|
|
94
111
|
description: "Retrieve a complete project definition with all Agents, Sub Agents, tools, and relationships",
|
|
95
112
|
request: { params: TenantProjectParamsSchema },
|
|
96
113
|
responses: {
|
|
@@ -129,7 +146,7 @@ app.openapi(createRoute({
|
|
|
129
146
|
path: "/project-full/{projectId}/with-relation-ids",
|
|
130
147
|
summary: "Get Full Project with Relation IDs",
|
|
131
148
|
operationId: "get-full-project-with-relation-ids",
|
|
132
|
-
tags: ["
|
|
149
|
+
tags: ["Projects"],
|
|
133
150
|
description: "Retrieve a complete project definition with all Agents, Sub Agents, tools, and relationships",
|
|
134
151
|
request: { params: TenantProjectParamsSchema },
|
|
135
152
|
responses: {
|
|
@@ -163,12 +180,16 @@ app.openapi(createRoute({
|
|
|
163
180
|
});
|
|
164
181
|
}
|
|
165
182
|
});
|
|
183
|
+
app.use("/project-full/:projectId", async (c, next) => {
|
|
184
|
+
if (c.req.method === "PUT") return requireProjectUpsertPermission(c, next);
|
|
185
|
+
return next();
|
|
186
|
+
});
|
|
166
187
|
app.openapi(createRoute({
|
|
167
188
|
method: "put",
|
|
168
189
|
path: "/project-full/{projectId}",
|
|
169
190
|
summary: "Update Full Project",
|
|
170
191
|
operationId: "update-full-project",
|
|
171
|
-
tags: ["
|
|
192
|
+
tags: ["Projects"],
|
|
172
193
|
description: "Update or create a complete project with all Agents, Sub Agents, tools, and relationships from JSON definition",
|
|
173
194
|
request: {
|
|
174
195
|
params: TenantProjectParamsSchema,
|
|
@@ -196,10 +217,7 @@ app.openapi(createRoute({
|
|
|
196
217
|
code: "bad_request",
|
|
197
218
|
message: `Project ID mismatch: expected ${projectId}, got ${validatedProjectData.id}`
|
|
198
219
|
});
|
|
199
|
-
const isCreate =
|
|
200
|
-
tenantId,
|
|
201
|
-
projectId
|
|
202
|
-
});
|
|
220
|
+
const isCreate = c.get("isProjectCreate") ?? false;
|
|
203
221
|
if (isCreate) {
|
|
204
222
|
await createProjectMetadataAndBranch(runDbClient_default, configDb)({
|
|
205
223
|
tenantId,
|
|
@@ -245,12 +263,16 @@ app.openapi(createRoute({
|
|
|
245
263
|
});
|
|
246
264
|
}
|
|
247
265
|
});
|
|
266
|
+
app.use("/project-full/:projectId", async (c, next) => {
|
|
267
|
+
if (c.req.method === "DELETE") return requirePermission({ project: ["delete"] })(c, next);
|
|
268
|
+
return next();
|
|
269
|
+
});
|
|
248
270
|
app.openapi(createRoute({
|
|
249
271
|
method: "delete",
|
|
250
272
|
path: "/project-full/{projectId}",
|
|
251
273
|
summary: "Delete Full Project",
|
|
252
274
|
operationId: "delete-full-project",
|
|
253
|
-
tags: ["
|
|
275
|
+
tags: ["Projects"],
|
|
254
276
|
description: "Delete a complete project and cascade to all related entities (Agents, Sub Agents, tools, relationships)",
|
|
255
277
|
request: { params: TenantProjectParamsSchema },
|
|
256
278
|
responses: {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ManageAppVariables } from "../../../types/app.js";
|
|
2
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
3
|
+
|
|
4
|
+
//#region src/domains/manage/routes/projectGithubAccess.d.ts
|
|
5
|
+
declare const app: OpenAPIHono<{
|
|
6
|
+
Variables: ManageAppVariables;
|
|
7
|
+
}, {}, "/">;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { app as default };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { getLogger as getLogger$1 } from "../../../logger.js";
|
|
2
|
+
import runDbClient_default from "../../../data/db/runDbClient.js";
|
|
3
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
4
|
+
import { TenantProjectParamsSchema, WorkAppGitHubAccessGetResponseSchema, WorkAppGitHubAccessModeSchema, WorkAppGitHubAccessSetRequestSchema, WorkAppGitHubAccessSetResponseSchema, commonGetErrorResponses, commonUpdateErrorResponses, createApiError, getProjectAccessMode, getProjectRepositoryAccessWithDetails, setProjectAccessMode, setProjectRepositoryAccess, validateRepositoryOwnership } from "@inkeep/agents-core";
|
|
5
|
+
|
|
6
|
+
//#region src/domains/manage/routes/projectGithubAccess.ts
|
|
7
|
+
const logger = getLogger$1("project-github-access");
|
|
8
|
+
const app = new OpenAPIHono();
|
|
9
|
+
const ProjectGitHubAccessModeSchema = WorkAppGitHubAccessModeSchema.describe("Access mode: \"all\" means project has access to all tenant repositories, \"selected\" means project is scoped to specific repositories");
|
|
10
|
+
const SetGitHubAccessRequestSchema = WorkAppGitHubAccessSetRequestSchema.extend({ mode: ProjectGitHubAccessModeSchema });
|
|
11
|
+
const GetGitHubAccessResponseSchema = WorkAppGitHubAccessGetResponseSchema.extend({ mode: ProjectGitHubAccessModeSchema }).describe("GitHub access configuration for a project");
|
|
12
|
+
const SetGitHubAccessResponseSchema = WorkAppGitHubAccessSetResponseSchema.extend({
|
|
13
|
+
mode: ProjectGitHubAccessModeSchema,
|
|
14
|
+
repositoryCount: z.number().describe("Number of repositories the project now has access to (0 when mode=\"all\")")
|
|
15
|
+
});
|
|
16
|
+
app.openapi(createRoute({
|
|
17
|
+
method: "get",
|
|
18
|
+
path: "/",
|
|
19
|
+
summary: "Get project GitHub repository access",
|
|
20
|
+
operationId: "get-project-github-access",
|
|
21
|
+
tags: ["Projects"],
|
|
22
|
+
description: "Returns the current GitHub repository access configuration for a project. If mode is \"all\", the project has access to all repositories from tenant GitHub installations. If mode is \"selected\", the project is scoped to specific repositories.",
|
|
23
|
+
request: { params: TenantProjectParamsSchema },
|
|
24
|
+
responses: {
|
|
25
|
+
200: {
|
|
26
|
+
description: "GitHub access configuration retrieved successfully",
|
|
27
|
+
content: { "application/json": { schema: GetGitHubAccessResponseSchema } }
|
|
28
|
+
},
|
|
29
|
+
...commonGetErrorResponses
|
|
30
|
+
}
|
|
31
|
+
}), async (c) => {
|
|
32
|
+
const { tenantId, projectId } = c.req.valid("param");
|
|
33
|
+
logger.info({
|
|
34
|
+
tenantId,
|
|
35
|
+
projectId
|
|
36
|
+
}, "Getting project GitHub access configuration");
|
|
37
|
+
if (await getProjectAccessMode(runDbClient_default)({
|
|
38
|
+
tenantId,
|
|
39
|
+
projectId
|
|
40
|
+
}) === "all") {
|
|
41
|
+
logger.info({
|
|
42
|
+
tenantId,
|
|
43
|
+
projectId
|
|
44
|
+
}, "Project has access to all repositories (mode=all)");
|
|
45
|
+
return c.json({
|
|
46
|
+
mode: "all",
|
|
47
|
+
repositories: []
|
|
48
|
+
}, 200);
|
|
49
|
+
}
|
|
50
|
+
const repositoriesWithDetails = await getProjectRepositoryAccessWithDetails(runDbClient_default)({
|
|
51
|
+
tenantId,
|
|
52
|
+
projectId
|
|
53
|
+
});
|
|
54
|
+
logger.info({
|
|
55
|
+
tenantId,
|
|
56
|
+
projectId,
|
|
57
|
+
repositoryCount: repositoriesWithDetails.length
|
|
58
|
+
}, "Got project GitHub access configuration (mode=selected)");
|
|
59
|
+
return c.json({
|
|
60
|
+
mode: "selected",
|
|
61
|
+
repositories: repositoriesWithDetails.map((repo) => ({
|
|
62
|
+
id: repo.id,
|
|
63
|
+
installationDbId: repo.installationDbId,
|
|
64
|
+
repositoryId: repo.repositoryId,
|
|
65
|
+
repositoryName: repo.repositoryName,
|
|
66
|
+
repositoryFullName: repo.repositoryFullName,
|
|
67
|
+
private: repo.private,
|
|
68
|
+
createdAt: repo.createdAt,
|
|
69
|
+
updatedAt: repo.updatedAt
|
|
70
|
+
}))
|
|
71
|
+
}, 200);
|
|
72
|
+
});
|
|
73
|
+
app.openapi(createRoute({
|
|
74
|
+
method: "put",
|
|
75
|
+
path: "/",
|
|
76
|
+
summary: "Set project GitHub repository access",
|
|
77
|
+
operationId: "set-project-github-access",
|
|
78
|
+
tags: ["Projects"],
|
|
79
|
+
description: "Configures which GitHub repositories a project can access. When mode is \"all\", the project has access to all repositories from tenant GitHub installations. When mode is \"selected\", the project is scoped to specific repositories (repositoryIds required). This replaces any existing access configuration.",
|
|
80
|
+
request: {
|
|
81
|
+
params: TenantProjectParamsSchema,
|
|
82
|
+
body: { content: { "application/json": { schema: SetGitHubAccessRequestSchema } } }
|
|
83
|
+
},
|
|
84
|
+
responses: {
|
|
85
|
+
200: {
|
|
86
|
+
description: "GitHub access configuration updated successfully",
|
|
87
|
+
content: { "application/json": { schema: SetGitHubAccessResponseSchema } }
|
|
88
|
+
},
|
|
89
|
+
...commonUpdateErrorResponses
|
|
90
|
+
}
|
|
91
|
+
}), async (c) => {
|
|
92
|
+
const { tenantId, projectId } = c.req.valid("param");
|
|
93
|
+
const { mode, repositoryIds } = c.req.valid("json");
|
|
94
|
+
logger.info({
|
|
95
|
+
tenantId,
|
|
96
|
+
projectId,
|
|
97
|
+
mode
|
|
98
|
+
}, "Setting project GitHub access configuration");
|
|
99
|
+
if (mode === "selected") {
|
|
100
|
+
if (!repositoryIds || repositoryIds.length === 0) {
|
|
101
|
+
logger.warn({
|
|
102
|
+
tenantId,
|
|
103
|
+
projectId
|
|
104
|
+
}, "repositoryIds required when mode is selected");
|
|
105
|
+
throw createApiError({
|
|
106
|
+
code: "bad_request",
|
|
107
|
+
message: "repositoryIds is required when mode is \"selected\""
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const invalidRepoIds = await validateRepositoryOwnership(runDbClient_default)({
|
|
111
|
+
tenantId,
|
|
112
|
+
repositoryIds
|
|
113
|
+
});
|
|
114
|
+
if (invalidRepoIds.length > 0) {
|
|
115
|
+
logger.warn({
|
|
116
|
+
tenantId,
|
|
117
|
+
projectId,
|
|
118
|
+
invalidRepoIds
|
|
119
|
+
}, "Some repository IDs do not belong to tenant installations");
|
|
120
|
+
throw createApiError({
|
|
121
|
+
code: "bad_request",
|
|
122
|
+
message: `Invalid repository IDs: ${invalidRepoIds.join(", ")}. Repositories must belong to GitHub installations owned by this tenant.`
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
await setProjectAccessMode(runDbClient_default)({
|
|
126
|
+
tenantId,
|
|
127
|
+
projectId,
|
|
128
|
+
mode: "selected"
|
|
129
|
+
});
|
|
130
|
+
await setProjectRepositoryAccess(runDbClient_default)({
|
|
131
|
+
tenantId,
|
|
132
|
+
projectId,
|
|
133
|
+
repositoryIds
|
|
134
|
+
});
|
|
135
|
+
logger.info({
|
|
136
|
+
tenantId,
|
|
137
|
+
projectId,
|
|
138
|
+
repositoryCount: repositoryIds.length
|
|
139
|
+
}, "Project GitHub access set to selected repositories");
|
|
140
|
+
return c.json({
|
|
141
|
+
mode: "selected",
|
|
142
|
+
repositoryCount: repositoryIds.length
|
|
143
|
+
}, 200);
|
|
144
|
+
}
|
|
145
|
+
await setProjectAccessMode(runDbClient_default)({
|
|
146
|
+
tenantId,
|
|
147
|
+
projectId,
|
|
148
|
+
mode: "all"
|
|
149
|
+
});
|
|
150
|
+
await setProjectRepositoryAccess(runDbClient_default)({
|
|
151
|
+
tenantId,
|
|
152
|
+
projectId,
|
|
153
|
+
repositoryIds: []
|
|
154
|
+
});
|
|
155
|
+
logger.info({
|
|
156
|
+
tenantId,
|
|
157
|
+
projectId
|
|
158
|
+
}, "Project GitHub access set to all repositories");
|
|
159
|
+
return c.json({
|
|
160
|
+
mode: "all",
|
|
161
|
+
repositoryCount: 0
|
|
162
|
+
}, 200);
|
|
163
|
+
});
|
|
164
|
+
var projectGithubAccess_default = app;
|
|
165
|
+
|
|
166
|
+
//#endregion
|
|
167
|
+
export { projectGithubAccess_default as default };
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import { requireProjectPermission } from "../../../middleware/projectAccess.js";
|
|
2
2
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
3
|
-
import { changeProjectRole, commonGetErrorResponses, createApiError, grantProjectAccess,
|
|
3
|
+
import { ProjectRoles, changeProjectRole, commonGetErrorResponses, createApiError, grantProjectAccess, listProjectMembers, revokeProjectAccess } from "@inkeep/agents-core";
|
|
4
4
|
|
|
5
5
|
//#region src/domains/manage/routes/projectMembers.ts
|
|
6
6
|
const app = new OpenAPIHono();
|
|
7
|
+
const projectRoleEnum = z.enum([
|
|
8
|
+
ProjectRoles.ADMIN,
|
|
9
|
+
ProjectRoles.MEMBER,
|
|
10
|
+
ProjectRoles.VIEWER
|
|
11
|
+
]);
|
|
7
12
|
const ProjectMemberSchema = z.object({
|
|
8
13
|
userId: z.string().min(1),
|
|
9
|
-
role:
|
|
10
|
-
"project_admin",
|
|
11
|
-
"project_member",
|
|
12
|
-
"project_viewer"
|
|
13
|
-
])
|
|
14
|
+
role: projectRoleEnum
|
|
14
15
|
});
|
|
15
16
|
const ProjectMemberResponseSchema = z.object({ data: z.object({
|
|
16
17
|
userId: z.string(),
|
|
17
|
-
role:
|
|
18
|
-
"project_admin",
|
|
19
|
-
"project_member",
|
|
20
|
-
"project_viewer"
|
|
21
|
-
]),
|
|
18
|
+
role: projectRoleEnum,
|
|
22
19
|
projectId: z.string()
|
|
23
20
|
}) });
|
|
24
21
|
const ProjectMemberParamsSchema = z.object({
|
|
@@ -31,16 +28,8 @@ const ProjectMemberUserParamsSchema = z.object({
|
|
|
31
28
|
userId: z.string()
|
|
32
29
|
});
|
|
33
30
|
const UpdateRoleSchema = z.object({
|
|
34
|
-
role:
|
|
35
|
-
|
|
36
|
-
"project_member",
|
|
37
|
-
"project_viewer"
|
|
38
|
-
]),
|
|
39
|
-
previousRole: z.enum([
|
|
40
|
-
"project_admin",
|
|
41
|
-
"project_member",
|
|
42
|
-
"project_viewer"
|
|
43
|
-
]).optional()
|
|
31
|
+
role: projectRoleEnum,
|
|
32
|
+
previousRole: projectRoleEnum.optional()
|
|
44
33
|
});
|
|
45
34
|
app.openapi(createRoute({
|
|
46
35
|
method: "get",
|
|
@@ -55,18 +44,13 @@ app.openapi(createRoute({
|
|
|
55
44
|
description: "List of project members",
|
|
56
45
|
content: { "application/json": { schema: z.object({ data: z.array(z.object({
|
|
57
46
|
userId: z.string(),
|
|
58
|
-
role:
|
|
59
|
-
"project_admin",
|
|
60
|
-
"project_member",
|
|
61
|
-
"project_viewer"
|
|
62
|
-
])
|
|
47
|
+
role: projectRoleEnum
|
|
63
48
|
})) }) } }
|
|
64
49
|
},
|
|
65
50
|
...commonGetErrorResponses
|
|
66
51
|
}
|
|
67
52
|
}), async (c) => {
|
|
68
53
|
const { projectId, tenantId } = c.req.valid("param");
|
|
69
|
-
if (!isAuthzEnabled(tenantId)) return c.json({ data: [] });
|
|
70
54
|
const members = await listProjectMembers({
|
|
71
55
|
tenantId,
|
|
72
56
|
projectId
|
|
@@ -98,10 +82,6 @@ app.openapi(createRoute({
|
|
|
98
82
|
}), async (c) => {
|
|
99
83
|
const { projectId, tenantId } = c.req.valid("param");
|
|
100
84
|
const { userId, role } = c.req.valid("json");
|
|
101
|
-
if (!isAuthzEnabled(tenantId)) throw createApiError({
|
|
102
|
-
code: "bad_request",
|
|
103
|
-
message: "Project member management requires authorization to be enabled (ENABLE_AUTHZ=true)"
|
|
104
|
-
});
|
|
105
85
|
await grantProjectAccess({
|
|
106
86
|
tenantId,
|
|
107
87
|
projectId,
|
|
@@ -135,10 +115,6 @@ app.openapi(createRoute({
|
|
|
135
115
|
}), async (c) => {
|
|
136
116
|
const { projectId, userId, tenantId } = c.req.valid("param");
|
|
137
117
|
const { role: newRole, previousRole } = c.req.valid("json");
|
|
138
|
-
if (!isAuthzEnabled(tenantId)) throw createApiError({
|
|
139
|
-
code: "bad_request",
|
|
140
|
-
message: "Project member management requires authorization to be enabled (ENABLE_AUTHZ=true)"
|
|
141
|
-
});
|
|
142
118
|
if (!previousRole) throw createApiError({
|
|
143
119
|
code: "bad_request",
|
|
144
120
|
message: "previousRole is required to update a member role"
|
|
@@ -170,11 +146,7 @@ app.openapi(createRoute({
|
|
|
170
146
|
tags: ["Project Members"],
|
|
171
147
|
request: {
|
|
172
148
|
params: ProjectMemberUserParamsSchema,
|
|
173
|
-
query: z.object({ role:
|
|
174
|
-
"project_admin",
|
|
175
|
-
"project_member",
|
|
176
|
-
"project_viewer"
|
|
177
|
-
]) })
|
|
149
|
+
query: z.object({ role: projectRoleEnum })
|
|
178
150
|
},
|
|
179
151
|
responses: {
|
|
180
152
|
204: { description: "Member removed successfully" },
|
|
@@ -183,10 +155,6 @@ app.openapi(createRoute({
|
|
|
183
155
|
}), async (c) => {
|
|
184
156
|
const { projectId, userId, tenantId } = c.req.valid("param");
|
|
185
157
|
const { role } = c.req.valid("query");
|
|
186
|
-
if (!isAuthzEnabled(tenantId)) throw createApiError({
|
|
187
|
-
code: "bad_request",
|
|
188
|
-
message: "Project member management requires authorization to be enabled (ENABLE_AUTHZ=true)"
|
|
189
|
-
});
|
|
190
158
|
await revokeProjectAccess({
|
|
191
159
|
tenantId,
|
|
192
160
|
projectId,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
|
-
import {
|
|
2
|
+
import { OrgRoles, SpiceDbProjectPermissions, SpiceDbResourceTypes, checkBulkPermissions, commonGetErrorResponses, createApiError } from "@inkeep/agents-core";
|
|
3
3
|
|
|
4
4
|
//#region src/domains/manage/routes/projectPermissions.ts
|
|
5
5
|
const app = new OpenAPIHono();
|
|
@@ -28,18 +28,18 @@ app.openapi(createRoute({
|
|
|
28
28
|
...commonGetErrorResponses
|
|
29
29
|
}
|
|
30
30
|
}), async (c) => {
|
|
31
|
-
const { projectId
|
|
31
|
+
const { projectId } = c.req.valid("param");
|
|
32
32
|
const userId = c.get("userId");
|
|
33
33
|
const tenantRole = c.get("tenantRole");
|
|
34
|
-
if (
|
|
34
|
+
if (process.env.ENVIRONMENT === "test") return c.json({ data: {
|
|
35
35
|
canView: true,
|
|
36
36
|
canUse: true,
|
|
37
37
|
canEdit: true
|
|
38
38
|
} });
|
|
39
|
-
if (
|
|
39
|
+
if (tenantRole === OrgRoles.OWNER || tenantRole === OrgRoles.ADMIN) return c.json({ data: {
|
|
40
40
|
canView: true,
|
|
41
41
|
canUse: true,
|
|
42
|
-
canEdit:
|
|
42
|
+
canEdit: true
|
|
43
43
|
} });
|
|
44
44
|
if (!userId) throw createApiError({
|
|
45
45
|
code: "unauthorized",
|
|
@@ -49,17 +49,17 @@ app.openapi(createRoute({
|
|
|
49
49
|
resourceType: SpiceDbResourceTypes.PROJECT,
|
|
50
50
|
resourceId: projectId,
|
|
51
51
|
permissions: [
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
SpiceDbProjectPermissions.VIEW,
|
|
53
|
+
SpiceDbProjectPermissions.USE,
|
|
54
|
+
SpiceDbProjectPermissions.EDIT
|
|
55
55
|
],
|
|
56
56
|
subjectType: SpiceDbResourceTypes.USER,
|
|
57
57
|
subjectId: userId
|
|
58
58
|
});
|
|
59
59
|
return c.json({ data: {
|
|
60
|
-
canView: permissions[
|
|
61
|
-
canUse: permissions[
|
|
62
|
-
canEdit: permissions[
|
|
60
|
+
canView: permissions[SpiceDbProjectPermissions.VIEW] ?? false,
|
|
61
|
+
canUse: permissions[SpiceDbProjectPermissions.USE] ?? false,
|
|
62
|
+
canEdit: permissions[SpiceDbProjectPermissions.EDIT] ?? false
|
|
63
63
|
} });
|
|
64
64
|
});
|
|
65
65
|
var projectPermissions_default = app;
|