@inkeep/agents-manage-api 0.39.5 → 0.41.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 +163 -57
- 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 +64 -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 +206 -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,188 @@
|
|
|
1
|
+
import dbClient_default from "../data/db/dbClient.js";
|
|
2
|
+
import { requirePermission } from "../middleware/require-permission.js";
|
|
3
|
+
import { speakeasyOffsetLimitPagination } from "./shared.js";
|
|
4
|
+
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
|
|
5
|
+
import { ErrorResponseSchema, PaginationQueryParamsSchema, ProjectApiInsertSchema, ProjectApiUpdateSchema, ProjectListResponse, ProjectResponse, TenantIdParamsSchema, TenantParamsSchema, commonGetErrorResponses, createApiError, createProject, deleteProject, getProject, listProjectsPaginated, updateProject } from "@inkeep/agents-core";
|
|
6
|
+
|
|
7
|
+
//#region src/routes/projects.ts
|
|
8
|
+
const app = new OpenAPIHono();
|
|
9
|
+
app.use("/", async (c, next) => {
|
|
10
|
+
if (c.req.method === "POST") return requirePermission({ project: ["create"] })(c, next);
|
|
11
|
+
return next();
|
|
12
|
+
});
|
|
13
|
+
app.use("/:id", async (c, next) => {
|
|
14
|
+
if (c.req.method === "PATCH") return requirePermission({ project: ["update"] })(c, next);
|
|
15
|
+
if (c.req.method === "DELETE") return requirePermission({ project: ["delete"] })(c, next);
|
|
16
|
+
return next();
|
|
17
|
+
});
|
|
18
|
+
app.openapi(createRoute({
|
|
19
|
+
method: "get",
|
|
20
|
+
path: "/",
|
|
21
|
+
summary: "List Projects",
|
|
22
|
+
description: "List all projects within a tenant with pagination",
|
|
23
|
+
operationId: "list-projects",
|
|
24
|
+
tags: ["Projects"],
|
|
25
|
+
request: {
|
|
26
|
+
params: TenantParamsSchema,
|
|
27
|
+
query: PaginationQueryParamsSchema
|
|
28
|
+
},
|
|
29
|
+
responses: {
|
|
30
|
+
200: {
|
|
31
|
+
description: "List of projects retrieved successfully",
|
|
32
|
+
content: { "application/json": { schema: ProjectListResponse } }
|
|
33
|
+
},
|
|
34
|
+
...commonGetErrorResponses
|
|
35
|
+
},
|
|
36
|
+
...speakeasyOffsetLimitPagination
|
|
37
|
+
}), async (c) => {
|
|
38
|
+
const { tenantId } = c.req.valid("param");
|
|
39
|
+
const page = Number(c.req.query("page")) || 1;
|
|
40
|
+
const limit = Math.min(Number(c.req.query("limit")) || 10, 100);
|
|
41
|
+
const result = await listProjectsPaginated(dbClient_default)({
|
|
42
|
+
tenantId,
|
|
43
|
+
pagination: {
|
|
44
|
+
page,
|
|
45
|
+
limit
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return c.json(result);
|
|
49
|
+
});
|
|
50
|
+
app.openapi(createRoute({
|
|
51
|
+
method: "get",
|
|
52
|
+
path: "/{id}",
|
|
53
|
+
summary: "Get Project",
|
|
54
|
+
description: "Get a single project by ID",
|
|
55
|
+
operationId: "get-project-by-id",
|
|
56
|
+
tags: ["Projects"],
|
|
57
|
+
request: { params: TenantIdParamsSchema },
|
|
58
|
+
responses: {
|
|
59
|
+
200: {
|
|
60
|
+
description: "Project found",
|
|
61
|
+
content: { "application/json": { schema: ProjectResponse } }
|
|
62
|
+
},
|
|
63
|
+
...commonGetErrorResponses
|
|
64
|
+
}
|
|
65
|
+
}), async (c) => {
|
|
66
|
+
const { tenantId, id } = c.req.valid("param");
|
|
67
|
+
const project = await getProject(dbClient_default)({ scopes: {
|
|
68
|
+
tenantId,
|
|
69
|
+
projectId: id
|
|
70
|
+
} });
|
|
71
|
+
if (!project) throw createApiError({
|
|
72
|
+
code: "not_found",
|
|
73
|
+
message: "Project not found"
|
|
74
|
+
});
|
|
75
|
+
return c.json({ data: project });
|
|
76
|
+
});
|
|
77
|
+
app.openapi(createRoute({
|
|
78
|
+
method: "post",
|
|
79
|
+
path: "/",
|
|
80
|
+
summary: "Create Project",
|
|
81
|
+
description: "Create a new project",
|
|
82
|
+
operationId: "create-project",
|
|
83
|
+
tags: ["Projects"],
|
|
84
|
+
request: {
|
|
85
|
+
params: TenantParamsSchema,
|
|
86
|
+
body: { content: { "application/json": { schema: ProjectApiInsertSchema } } }
|
|
87
|
+
},
|
|
88
|
+
responses: {
|
|
89
|
+
201: {
|
|
90
|
+
description: "Project created successfully",
|
|
91
|
+
content: { "application/json": { schema: ProjectResponse } }
|
|
92
|
+
},
|
|
93
|
+
409: {
|
|
94
|
+
description: "Project already exists",
|
|
95
|
+
content: { "application/json": { schema: ErrorResponseSchema } }
|
|
96
|
+
},
|
|
97
|
+
...commonGetErrorResponses
|
|
98
|
+
}
|
|
99
|
+
}), async (c) => {
|
|
100
|
+
const { tenantId } = c.req.valid("param");
|
|
101
|
+
const body = c.req.valid("json");
|
|
102
|
+
try {
|
|
103
|
+
const project = await createProject(dbClient_default)({
|
|
104
|
+
tenantId,
|
|
105
|
+
...body
|
|
106
|
+
});
|
|
107
|
+
return c.json({ data: project }, 201);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (error?.cause?.code === "23505") throw createApiError({
|
|
110
|
+
code: "conflict",
|
|
111
|
+
message: "Project with this ID already exists"
|
|
112
|
+
});
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
app.openapi(createRoute({
|
|
117
|
+
method: "patch",
|
|
118
|
+
path: "/{id}",
|
|
119
|
+
summary: "Update Project",
|
|
120
|
+
description: "Update an existing project",
|
|
121
|
+
operationId: "update-project",
|
|
122
|
+
tags: ["Projects"],
|
|
123
|
+
request: {
|
|
124
|
+
params: TenantIdParamsSchema,
|
|
125
|
+
body: { content: { "application/json": { schema: ProjectApiUpdateSchema } } }
|
|
126
|
+
},
|
|
127
|
+
responses: {
|
|
128
|
+
200: {
|
|
129
|
+
description: "Project updated successfully",
|
|
130
|
+
content: { "application/json": { schema: ProjectResponse } }
|
|
131
|
+
},
|
|
132
|
+
...commonGetErrorResponses
|
|
133
|
+
}
|
|
134
|
+
}), async (c) => {
|
|
135
|
+
const { tenantId, id } = c.req.valid("param");
|
|
136
|
+
const body = c.req.valid("json");
|
|
137
|
+
const project = await updateProject(dbClient_default)({
|
|
138
|
+
scopes: {
|
|
139
|
+
tenantId,
|
|
140
|
+
projectId: id
|
|
141
|
+
},
|
|
142
|
+
data: body
|
|
143
|
+
});
|
|
144
|
+
if (!project) throw createApiError({
|
|
145
|
+
code: "not_found",
|
|
146
|
+
message: "Project not found"
|
|
147
|
+
});
|
|
148
|
+
return c.json({ data: project });
|
|
149
|
+
});
|
|
150
|
+
app.openapi(createRoute({
|
|
151
|
+
method: "delete",
|
|
152
|
+
path: "/{id}",
|
|
153
|
+
summary: "Delete Project",
|
|
154
|
+
description: "Delete a project. Will fail if the project has existing resources.",
|
|
155
|
+
operationId: "delete-project",
|
|
156
|
+
tags: ["Projects"],
|
|
157
|
+
request: { params: TenantIdParamsSchema },
|
|
158
|
+
responses: {
|
|
159
|
+
204: { description: "Project deleted successfully" },
|
|
160
|
+
409: {
|
|
161
|
+
description: "Cannot delete project with existing resources",
|
|
162
|
+
content: { "application/json": { schema: ErrorResponseSchema } }
|
|
163
|
+
},
|
|
164
|
+
...commonGetErrorResponses
|
|
165
|
+
}
|
|
166
|
+
}), async (c) => {
|
|
167
|
+
const { tenantId, id } = c.req.valid("param");
|
|
168
|
+
try {
|
|
169
|
+
if (!await deleteProject(dbClient_default)({ scopes: {
|
|
170
|
+
tenantId,
|
|
171
|
+
projectId: id
|
|
172
|
+
} })) throw createApiError({
|
|
173
|
+
code: "not_found",
|
|
174
|
+
message: "Project not found"
|
|
175
|
+
});
|
|
176
|
+
return c.body(null, 204);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (error.message?.includes("Cannot delete project with existing resources")) throw createApiError({
|
|
179
|
+
code: "conflict",
|
|
180
|
+
message: "Cannot delete project with existing resources"
|
|
181
|
+
});
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
var projects_default = app;
|
|
186
|
+
|
|
187
|
+
//#endregion
|
|
188
|
+
export { projects_default as default };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
//#region src/routes/shared.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared route configurations and helpers
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Speakeasy pagination input configuration
|
|
7
|
+
*/
|
|
8
|
+
type SpeakeasyPaginationInput = {
|
|
9
|
+
name: string;
|
|
10
|
+
in: 'parameters' | 'requestBody';
|
|
11
|
+
type: 'page' | 'limit' | 'offset' | 'cursor';
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Speakeasy pagination output configuration
|
|
15
|
+
* Uses JSONPath expressions to locate pagination values in the response
|
|
16
|
+
*/
|
|
17
|
+
type SpeakeasyPaginationOutputs = {
|
|
18
|
+
numPages?: string;
|
|
19
|
+
nextCursor?: string;
|
|
20
|
+
results?: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Speakeasy pagination extension type
|
|
24
|
+
*/
|
|
25
|
+
type SpeakeasyPaginationExtension = {
|
|
26
|
+
'x-speakeasy-pagination': {
|
|
27
|
+
type: 'offsetLimit' | 'cursor';
|
|
28
|
+
inputs: SpeakeasyPaginationInput[];
|
|
29
|
+
outputs: SpeakeasyPaginationOutputs;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Standard pagination response shape that all paginated endpoints should return.
|
|
34
|
+
* This ensures consistency with the JSONPath '$.pagination.pages' in the Speakeasy extension.
|
|
35
|
+
*/
|
|
36
|
+
type StandardPaginationResponse<T> = {
|
|
37
|
+
data: T[];
|
|
38
|
+
pagination: {
|
|
39
|
+
page: number;
|
|
40
|
+
limit: number;
|
|
41
|
+
total: number;
|
|
42
|
+
pages: number;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Creates a Speakeasy pagination extension configuration.
|
|
47
|
+
* This factory function allows for different pagination strategies while maintaining type safety.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* // Offset-limit pagination (default)
|
|
52
|
+
* const pagination = createSpeakeasyPagination('offsetLimit');
|
|
53
|
+
*
|
|
54
|
+
* // Cursor-based pagination (future use)
|
|
55
|
+
* const cursorPagination = createSpeakeasyPagination('cursor', {
|
|
56
|
+
* inputs: [
|
|
57
|
+
* { name: 'cursor', in: 'parameters', type: 'cursor' },
|
|
58
|
+
* { name: 'limit', in: 'parameters', type: 'limit' },
|
|
59
|
+
* ],
|
|
60
|
+
* outputs: { nextCursor: '$.pagination.nextCursor' },
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
declare function createSpeakeasyPagination(type: 'offsetLimit', config?: Partial<{
|
|
65
|
+
inputs: SpeakeasyPaginationInput[];
|
|
66
|
+
outputs: SpeakeasyPaginationOutputs;
|
|
67
|
+
}>): SpeakeasyPaginationExtension;
|
|
68
|
+
declare function createSpeakeasyPagination(type: 'cursor', config: {
|
|
69
|
+
inputs: SpeakeasyPaginationInput[];
|
|
70
|
+
outputs: SpeakeasyPaginationOutputs;
|
|
71
|
+
}): SpeakeasyPaginationExtension;
|
|
72
|
+
/**
|
|
73
|
+
* Speakeasy pagination extension for offset-limit pagination.
|
|
74
|
+
* Use this in createRoute() calls for list endpoints that support pagination.
|
|
75
|
+
*
|
|
76
|
+
* IMPORTANT: Endpoints using this extension MUST return responses matching
|
|
77
|
+
* the StandardPaginationResponse<T> shape with data from a *Paginated() function
|
|
78
|
+
* (e.g., listAgentsPaginated, listProjectsPaginated) to ensure the JSONPath
|
|
79
|
+
* '$.pagination.pages' correctly resolves.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* createRoute({
|
|
84
|
+
* method: 'get',
|
|
85
|
+
* path: '/',
|
|
86
|
+
* // ... other config
|
|
87
|
+
* ...speakeasyOffsetLimitPagination,
|
|
88
|
+
* })
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
declare const speakeasyOffsetLimitPagination: SpeakeasyPaginationExtension;
|
|
92
|
+
//#endregion
|
|
93
|
+
export { StandardPaginationResponse, createSpeakeasyPagination, speakeasyOffsetLimitPagination };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/routes/shared.ts
|
|
2
|
+
function createSpeakeasyPagination(type, config) {
|
|
3
|
+
if (type === "offsetLimit") return { "x-speakeasy-pagination": {
|
|
4
|
+
type: "offsetLimit",
|
|
5
|
+
inputs: config?.inputs ?? [{
|
|
6
|
+
name: "page",
|
|
7
|
+
in: "parameters",
|
|
8
|
+
type: "page"
|
|
9
|
+
}, {
|
|
10
|
+
name: "limit",
|
|
11
|
+
in: "parameters",
|
|
12
|
+
type: "limit"
|
|
13
|
+
}],
|
|
14
|
+
outputs: config?.outputs ?? { numPages: "$.pagination.pages" }
|
|
15
|
+
} };
|
|
16
|
+
return { "x-speakeasy-pagination": {
|
|
17
|
+
type: "cursor",
|
|
18
|
+
inputs: config?.inputs ?? [],
|
|
19
|
+
outputs: config?.outputs ?? {}
|
|
20
|
+
} };
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Speakeasy pagination extension for offset-limit pagination.
|
|
24
|
+
* Use this in createRoute() calls for list endpoints that support pagination.
|
|
25
|
+
*
|
|
26
|
+
* IMPORTANT: Endpoints using this extension MUST return responses matching
|
|
27
|
+
* the StandardPaginationResponse<T> shape with data from a *Paginated() function
|
|
28
|
+
* (e.g., listAgentsPaginated, listProjectsPaginated) to ensure the JSONPath
|
|
29
|
+
* '$.pagination.pages' correctly resolves.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* createRoute({
|
|
34
|
+
* method: 'get',
|
|
35
|
+
* path: '/',
|
|
36
|
+
* // ... other config
|
|
37
|
+
* ...speakeasyOffsetLimitPagination,
|
|
38
|
+
* })
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
const speakeasyOffsetLimitPagination = createSpeakeasyPagination("offsetLimit");
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { createSpeakeasyPagination, speakeasyOffsetLimitPagination };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseAppVariables } from "../types/app.js";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import * as hono_types3 from "hono/types";
|
|
4
|
+
|
|
5
|
+
//#region src/routes/signoz.d.ts
|
|
6
|
+
declare const app: Hono<{
|
|
7
|
+
Variables: BaseAppVariables;
|
|
8
|
+
}, hono_types3.BlankSchema, "/">;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { app as default };
|
|
@@ -0,0 +1,155 @@
|
|
|
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 { enforceProjectFilter } from "../utils/signoz-helpers.js";
|
|
5
|
+
import { Hono } from "hono";
|
|
6
|
+
import { projectExists } from "@inkeep/agents-core";
|
|
7
|
+
import axios from "axios";
|
|
8
|
+
|
|
9
|
+
//#region src/routes/signoz.ts
|
|
10
|
+
const logger = getLogger$1("signoz-proxy");
|
|
11
|
+
const app = new Hono();
|
|
12
|
+
app.post("/query", async (c) => {
|
|
13
|
+
let payload = await c.req.json();
|
|
14
|
+
const requestedProjectId = payload.projectId;
|
|
15
|
+
const tenantId = c.get("tenantId");
|
|
16
|
+
logger.info({
|
|
17
|
+
tenantId,
|
|
18
|
+
projectId: requestedProjectId,
|
|
19
|
+
hasProjectId: !!requestedProjectId
|
|
20
|
+
}, "Processing SigNoz query request");
|
|
21
|
+
if (requestedProjectId) {
|
|
22
|
+
if (!await projectExists(dbClient_default)({
|
|
23
|
+
tenantId,
|
|
24
|
+
projectId: requestedProjectId
|
|
25
|
+
})) {
|
|
26
|
+
logger.warn({
|
|
27
|
+
tenantId,
|
|
28
|
+
projectId: requestedProjectId
|
|
29
|
+
}, "Project not found or access denied");
|
|
30
|
+
return c.json({
|
|
31
|
+
error: "Forbidden",
|
|
32
|
+
message: "You do not have access to this project"
|
|
33
|
+
}, 403);
|
|
34
|
+
}
|
|
35
|
+
payload = enforceProjectFilter(payload, requestedProjectId);
|
|
36
|
+
logger.debug({ projectId: requestedProjectId }, "Project filter enforced");
|
|
37
|
+
}
|
|
38
|
+
const signozUrl = env.SIGNOZ_URL || env.PUBLIC_SIGNOZ_URL;
|
|
39
|
+
const signozApiKey = env.SIGNOZ_API_KEY;
|
|
40
|
+
if (!signozUrl || !signozApiKey) {
|
|
41
|
+
logger.error({}, "SigNoz not configured");
|
|
42
|
+
return c.json({
|
|
43
|
+
error: "Service Unavailable",
|
|
44
|
+
message: "SigNoz is not configured"
|
|
45
|
+
}, 500);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const signozEndpoint = `${signozUrl}/api/v4/query_range`;
|
|
49
|
+
logger.debug({ endpoint: signozEndpoint }, "Proxying to SigNoz");
|
|
50
|
+
const response = await axios.post(signozEndpoint, payload, {
|
|
51
|
+
headers: {
|
|
52
|
+
"Content-Type": "application/json",
|
|
53
|
+
"SIGNOZ-API-KEY": signozApiKey
|
|
54
|
+
},
|
|
55
|
+
timeout: 3e4
|
|
56
|
+
});
|
|
57
|
+
logger.info({ status: response.status }, "SigNoz query successful");
|
|
58
|
+
return c.json(response.data);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (axios.isAxiosError(error)) {
|
|
61
|
+
if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
|
|
62
|
+
logger.error({ error: error.message }, "SigNoz service unavailable");
|
|
63
|
+
return c.json({
|
|
64
|
+
error: "Service Unavailable",
|
|
65
|
+
message: "SigNoz service is unavailable"
|
|
66
|
+
}, 503);
|
|
67
|
+
}
|
|
68
|
+
if (error.response?.status === 401 || error.response?.status === 403) {
|
|
69
|
+
logger.error({ status: error.response.status }, "SigNoz authentication failed");
|
|
70
|
+
return c.json({
|
|
71
|
+
error: "Internal Server Error",
|
|
72
|
+
message: "SigNoz authentication failed"
|
|
73
|
+
}, 500);
|
|
74
|
+
}
|
|
75
|
+
if (error.response?.status === 400) {
|
|
76
|
+
logger.warn({ status: error.response.status }, "Invalid SigNoz query");
|
|
77
|
+
return c.json({
|
|
78
|
+
error: "Bad Request",
|
|
79
|
+
message: "Invalid query parameters"
|
|
80
|
+
}, 400);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
logger.error({ error }, "SigNoz query failed");
|
|
84
|
+
return c.json({
|
|
85
|
+
error: "Internal Server Error",
|
|
86
|
+
message: "Failed to query SigNoz"
|
|
87
|
+
}, 500);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
app.get("/health", async (c) => {
|
|
91
|
+
const signozUrl = env.SIGNOZ_URL || env.PUBLIC_SIGNOZ_URL;
|
|
92
|
+
const signozApiKey = env.SIGNOZ_API_KEY;
|
|
93
|
+
logger.info({
|
|
94
|
+
hasUrl: !!signozUrl,
|
|
95
|
+
hasApiKey: !!signozApiKey,
|
|
96
|
+
url: signozUrl
|
|
97
|
+
}, "Checking SigNoz configuration");
|
|
98
|
+
if (!signozUrl || !signozApiKey) {
|
|
99
|
+
logger.warn({}, "SigNoz credentials not set");
|
|
100
|
+
return c.json({
|
|
101
|
+
status: "not_configured",
|
|
102
|
+
configured: false,
|
|
103
|
+
error: "SIGNOZ_URL or SIGNOZ_API_KEY not set"
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const testPayload = {
|
|
108
|
+
start: Date.now() - 3e5,
|
|
109
|
+
end: Date.now(),
|
|
110
|
+
step: 60,
|
|
111
|
+
compositeQuery: {
|
|
112
|
+
queryType: "builder",
|
|
113
|
+
panelType: "table",
|
|
114
|
+
builderQueries: {}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const signozEndpoint = `${signozUrl}/api/v4/query_range`;
|
|
118
|
+
logger.info({ endpoint: signozEndpoint }, "Testing SigNoz connection");
|
|
119
|
+
await axios.post(signozEndpoint, testPayload, {
|
|
120
|
+
headers: {
|
|
121
|
+
"Content-Type": "application/json",
|
|
122
|
+
"SIGNOZ-API-KEY": signozApiKey
|
|
123
|
+
},
|
|
124
|
+
timeout: 5e3,
|
|
125
|
+
validateStatus: (status) => status === 200 || status === 400
|
|
126
|
+
});
|
|
127
|
+
logger.info({}, "SigNoz health check successful");
|
|
128
|
+
return c.json({
|
|
129
|
+
status: "ok",
|
|
130
|
+
configured: true
|
|
131
|
+
});
|
|
132
|
+
} catch (error) {
|
|
133
|
+
logger.error({
|
|
134
|
+
error,
|
|
135
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
136
|
+
code: axios.isAxiosError(error) ? error.code : void 0,
|
|
137
|
+
status: axios.isAxiosError(error) ? error.response?.status : void 0
|
|
138
|
+
}, "SigNoz connection test failed");
|
|
139
|
+
let errorMessage = "Failed to connect to SigNoz";
|
|
140
|
+
if (axios.isAxiosError(error)) {
|
|
141
|
+
if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") errorMessage = "Check SIGNOZ_URL";
|
|
142
|
+
else if (error.response?.status === 401 || error.response?.status === 403) errorMessage = "Invalid SIGNOZ_API_KEY";
|
|
143
|
+
else if (error.code === "ETIMEDOUT" || error.code === "ECONNABORTED") errorMessage = "SigNoz connection timed out";
|
|
144
|
+
}
|
|
145
|
+
return c.json({
|
|
146
|
+
status: "connection_failed",
|
|
147
|
+
configured: false,
|
|
148
|
+
error: errorMessage
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
var signoz_default = app;
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
export { signoz_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/subAgentArtifactComponents.d.ts
|
|
5
|
+
declare const app: OpenAPIHono<{
|
|
6
|
+
Variables: BaseAppVariables;
|
|
7
|
+
}, {}, "/">;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { app as default };
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import dbClient_default from "../data/db/dbClient.js";
|
|
2
|
+
import { requirePermission } from "../middleware/require-permission.js";
|
|
3
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
4
|
+
import { ArtifactComponentArrayResponse, ComponentAssociationListResponse, ErrorResponseSchema, ExistsResponseSchema, RemovedResponseSchema, SubAgentArtifactComponentApiInsertSchema, SubAgentArtifactComponentResponse, TenantProjectAgentParamsSchema, TenantProjectAgentSubAgentParamsSchema, associateArtifactComponentWithAgent, commonGetErrorResponses, createApiError, getAgentsUsingArtifactComponent, getArtifactComponentById, getArtifactComponentsForAgent, getSubAgentById, isArtifactComponentAssociatedWithAgent, removeArtifactComponentFromAgent } from "@inkeep/agents-core";
|
|
5
|
+
|
|
6
|
+
//#region src/routes/subAgentArtifactComponents.ts
|
|
7
|
+
const app = new OpenAPIHono();
|
|
8
|
+
app.use("/", async (c, next) => {
|
|
9
|
+
if (c.req.method === "POST") return requirePermission({ sub_agent: ["create"] })(c, next);
|
|
10
|
+
return next();
|
|
11
|
+
});
|
|
12
|
+
app.use("/agent/:subAgentId/component/:artifactComponentId", async (c, next) => {
|
|
13
|
+
if (c.req.method === "DELETE") return requirePermission({ sub_agent: ["delete"] })(c, next);
|
|
14
|
+
return next();
|
|
15
|
+
});
|
|
16
|
+
app.openapi(createRoute({
|
|
17
|
+
method: "get",
|
|
18
|
+
path: "/agent/{subAgentId}",
|
|
19
|
+
summary: "Get Artifact Components for Agent",
|
|
20
|
+
operationId: "get-artifact-components-for-agent",
|
|
21
|
+
tags: ["Agent Artifact Component Relations"],
|
|
22
|
+
request: { params: TenantProjectAgentSubAgentParamsSchema },
|
|
23
|
+
responses: {
|
|
24
|
+
200: {
|
|
25
|
+
description: "Artifact components retrieved successfully",
|
|
26
|
+
content: { "application/json": { schema: ArtifactComponentArrayResponse } }
|
|
27
|
+
},
|
|
28
|
+
...commonGetErrorResponses
|
|
29
|
+
}
|
|
30
|
+
}), async (c) => {
|
|
31
|
+
const { tenantId, projectId, agentId, subAgentId } = c.req.valid("param");
|
|
32
|
+
const artifactComponents = await getArtifactComponentsForAgent(dbClient_default)({ scopes: {
|
|
33
|
+
tenantId,
|
|
34
|
+
projectId,
|
|
35
|
+
agentId,
|
|
36
|
+
subAgentId
|
|
37
|
+
} });
|
|
38
|
+
return c.json({ data: artifactComponents });
|
|
39
|
+
});
|
|
40
|
+
app.openapi(createRoute({
|
|
41
|
+
method: "get",
|
|
42
|
+
path: "/component/{artifactComponentId}/agents",
|
|
43
|
+
summary: "Get Agents Using Artifact Component",
|
|
44
|
+
operationId: "get-agents-using-artifact-component",
|
|
45
|
+
tags: ["Agent Artifact Component Relations"],
|
|
46
|
+
request: { params: TenantProjectAgentParamsSchema.extend({ artifactComponentId: z.string() }) },
|
|
47
|
+
responses: {
|
|
48
|
+
200: {
|
|
49
|
+
description: "Agents retrieved successfully",
|
|
50
|
+
content: { "application/json": { schema: ComponentAssociationListResponse } }
|
|
51
|
+
},
|
|
52
|
+
...commonGetErrorResponses
|
|
53
|
+
}
|
|
54
|
+
}), async (c) => {
|
|
55
|
+
const { tenantId, projectId, artifactComponentId } = c.req.valid("param");
|
|
56
|
+
const agents = await getAgentsUsingArtifactComponent(dbClient_default)({
|
|
57
|
+
scopes: {
|
|
58
|
+
tenantId,
|
|
59
|
+
projectId
|
|
60
|
+
},
|
|
61
|
+
artifactComponentId
|
|
62
|
+
});
|
|
63
|
+
return c.json({ data: agents });
|
|
64
|
+
});
|
|
65
|
+
app.openapi(createRoute({
|
|
66
|
+
method: "post",
|
|
67
|
+
path: "/",
|
|
68
|
+
summary: "Associate Artifact Component with Agent",
|
|
69
|
+
operationId: "associate-artifact-component-with-agent",
|
|
70
|
+
tags: ["Agent Artifact Component Relations"],
|
|
71
|
+
request: {
|
|
72
|
+
params: TenantProjectAgentParamsSchema,
|
|
73
|
+
body: { content: { "application/json": { schema: SubAgentArtifactComponentApiInsertSchema } } }
|
|
74
|
+
},
|
|
75
|
+
responses: {
|
|
76
|
+
201: {
|
|
77
|
+
description: "Agent artifact component association created successfully",
|
|
78
|
+
content: { "application/json": { schema: SubAgentArtifactComponentResponse } }
|
|
79
|
+
},
|
|
80
|
+
409: {
|
|
81
|
+
description: "Association already exists",
|
|
82
|
+
content: { "application/json": { schema: ErrorResponseSchema } }
|
|
83
|
+
},
|
|
84
|
+
...commonGetErrorResponses
|
|
85
|
+
}
|
|
86
|
+
}), async (c) => {
|
|
87
|
+
const { tenantId, projectId, agentId } = c.req.valid("param");
|
|
88
|
+
const { subAgentId, artifactComponentId } = c.req.valid("json");
|
|
89
|
+
const agent = await getSubAgentById(dbClient_default)({
|
|
90
|
+
scopes: {
|
|
91
|
+
tenantId,
|
|
92
|
+
projectId,
|
|
93
|
+
agentId
|
|
94
|
+
},
|
|
95
|
+
subAgentId
|
|
96
|
+
});
|
|
97
|
+
const artifactComponent = await getArtifactComponentById(dbClient_default)({
|
|
98
|
+
scopes: {
|
|
99
|
+
tenantId,
|
|
100
|
+
projectId
|
|
101
|
+
},
|
|
102
|
+
id: artifactComponentId
|
|
103
|
+
});
|
|
104
|
+
if (!agent) throw createApiError({
|
|
105
|
+
code: "not_found",
|
|
106
|
+
message: `Agent with id '${subAgentId}' not found`
|
|
107
|
+
});
|
|
108
|
+
if (!artifactComponent) throw createApiError({
|
|
109
|
+
code: "not_found",
|
|
110
|
+
message: `Artifact component with id '${artifactComponentId}' not found`
|
|
111
|
+
});
|
|
112
|
+
if (await isArtifactComponentAssociatedWithAgent(dbClient_default)({
|
|
113
|
+
scopes: {
|
|
114
|
+
tenantId,
|
|
115
|
+
projectId,
|
|
116
|
+
agentId,
|
|
117
|
+
subAgentId
|
|
118
|
+
},
|
|
119
|
+
artifactComponentId
|
|
120
|
+
})) throw createApiError({
|
|
121
|
+
code: "conflict",
|
|
122
|
+
message: "Agent artifact component association already exists"
|
|
123
|
+
});
|
|
124
|
+
const association = await associateArtifactComponentWithAgent(dbClient_default)({
|
|
125
|
+
scopes: {
|
|
126
|
+
tenantId,
|
|
127
|
+
projectId,
|
|
128
|
+
agentId,
|
|
129
|
+
subAgentId
|
|
130
|
+
},
|
|
131
|
+
artifactComponentId
|
|
132
|
+
});
|
|
133
|
+
return c.json({ data: association }, 201);
|
|
134
|
+
});
|
|
135
|
+
app.openapi(createRoute({
|
|
136
|
+
method: "delete",
|
|
137
|
+
path: "/agent/{subAgentId}/component/{artifactComponentId}",
|
|
138
|
+
summary: "Remove Artifact Component from Agent",
|
|
139
|
+
operationId: "remove-artifact-component-from-agent",
|
|
140
|
+
tags: ["Agent Artifact Component Relations"],
|
|
141
|
+
request: { params: TenantProjectAgentSubAgentParamsSchema.extend({ artifactComponentId: z.string() }) },
|
|
142
|
+
responses: {
|
|
143
|
+
200: {
|
|
144
|
+
description: "Association removed successfully",
|
|
145
|
+
content: { "application/json": { schema: RemovedResponseSchema } }
|
|
146
|
+
},
|
|
147
|
+
...commonGetErrorResponses
|
|
148
|
+
}
|
|
149
|
+
}), async (c) => {
|
|
150
|
+
const { tenantId, projectId, agentId, subAgentId, artifactComponentId } = c.req.valid("param");
|
|
151
|
+
if (!await removeArtifactComponentFromAgent(dbClient_default)({
|
|
152
|
+
scopes: {
|
|
153
|
+
tenantId,
|
|
154
|
+
projectId,
|
|
155
|
+
agentId,
|
|
156
|
+
subAgentId
|
|
157
|
+
},
|
|
158
|
+
artifactComponentId
|
|
159
|
+
})) throw createApiError({
|
|
160
|
+
code: "not_found",
|
|
161
|
+
message: "Agent artifact component association not found"
|
|
162
|
+
});
|
|
163
|
+
return c.json({
|
|
164
|
+
message: "Association removed successfully",
|
|
165
|
+
removed: true
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
app.openapi(createRoute({
|
|
169
|
+
method: "get",
|
|
170
|
+
path: "/agent/{subAgentId}/component/{artifactComponentId}/exists",
|
|
171
|
+
summary: "Check if Artifact Component is Associated with Agent",
|
|
172
|
+
operationId: "check-artifact-component-agent-association",
|
|
173
|
+
tags: ["Agent Artifact Component Relations"],
|
|
174
|
+
request: { params: TenantProjectAgentSubAgentParamsSchema.extend({ artifactComponentId: z.string() }) },
|
|
175
|
+
responses: {
|
|
176
|
+
200: {
|
|
177
|
+
description: "Association status retrieved successfully",
|
|
178
|
+
content: { "application/json": { schema: ExistsResponseSchema } }
|
|
179
|
+
},
|
|
180
|
+
...commonGetErrorResponses
|
|
181
|
+
}
|
|
182
|
+
}), async (c) => {
|
|
183
|
+
const { tenantId, projectId, agentId, subAgentId, artifactComponentId } = c.req.valid("param");
|
|
184
|
+
const exists = await isArtifactComponentAssociatedWithAgent(dbClient_default)({
|
|
185
|
+
scopes: {
|
|
186
|
+
tenantId,
|
|
187
|
+
projectId,
|
|
188
|
+
agentId,
|
|
189
|
+
subAgentId
|
|
190
|
+
},
|
|
191
|
+
artifactComponentId
|
|
192
|
+
});
|
|
193
|
+
return c.json({ exists });
|
|
194
|
+
});
|
|
195
|
+
var subAgentArtifactComponents_default = app;
|
|
196
|
+
|
|
197
|
+
//#endregion
|
|
198
|
+
export { subAgentArtifactComponents_default as default };
|