@agentlensai/server 0.13.0 → 0.14.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/app.d.ts +27 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +178 -0
- package/dist/app.js.map +1 -0
- package/dist/config.d.ts +2 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -10
- package/dist/config.js.map +1 -1
- package/dist/health.d.ts +22 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +34 -0
- package/dist/health.js.map +1 -0
- package/dist/index.d.ts +17 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -502
- package/dist/index.js.map +1 -1
- package/dist/lib/api-schema.d.ts +126 -0
- package/dist/lib/api-schema.d.ts.map +1 -0
- package/dist/lib/api-schema.js +69 -0
- package/dist/lib/api-schema.js.map +1 -0
- package/dist/lib/api-version.d.ts +21 -0
- package/dist/lib/api-version.d.ts.map +1 -0
- package/dist/lib/api-version.js +36 -0
- package/dist/lib/api-version.js.map +1 -0
- package/dist/lib/lore-client.d.ts +64 -112
- package/dist/lib/lore-client.d.ts.map +1 -1
- package/dist/lib/lore-client.js +120 -155
- package/dist/lib/lore-client.js.map +1 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +73 -0
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/alerts.d.ts.map +1 -1
- package/dist/routes/alerts.js +13 -36
- package/dist/routes/alerts.js.map +1 -1
- package/dist/routes/analytics.d.ts.map +1 -1
- package/dist/routes/analytics.js +93 -0
- package/dist/routes/analytics.js.map +1 -1
- package/dist/routes/api-version.d.ts +9 -0
- package/dist/routes/api-version.d.ts.map +1 -0
- package/dist/routes/api-version.js +19 -0
- package/dist/routes/api-version.js.map +1 -0
- package/dist/routes/audit-verify.d.ts +3 -2
- package/dist/routes/audit-verify.d.ts.map +1 -1
- package/dist/routes/audit-verify.js +91 -27
- package/dist/routes/audit-verify.js.map +1 -1
- package/dist/routes/cost-budgets.d.ts.map +1 -1
- package/dist/routes/cost-budgets.js +19 -36
- package/dist/routes/cost-budgets.js.map +1 -1
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +121 -37
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/helpers.d.ts +27 -0
- package/dist/routes/helpers.d.ts.map +1 -0
- package/dist/routes/helpers.js +46 -0
- package/dist/routes/helpers.js.map +1 -0
- package/dist/routes/lore-proxy.d.ts +8 -6
- package/dist/routes/lore-proxy.d.ts.map +1 -1
- package/dist/routes/lore-proxy.js +39 -193
- package/dist/routes/lore-proxy.js.map +1 -1
- package/dist/routes/mcp-policies.d.ts +40 -0
- package/dist/routes/mcp-policies.d.ts.map +1 -0
- package/dist/routes/mcp-policies.js +200 -0
- package/dist/routes/mcp-policies.js.map +1 -0
- package/dist/routes/optimization-advisor.d.ts +13 -0
- package/dist/routes/optimization-advisor.d.ts.map +1 -0
- package/dist/routes/optimization-advisor.js +42 -0
- package/dist/routes/optimization-advisor.js.map +1 -0
- package/dist/routes/recall.d.ts.map +1 -1
- package/dist/routes/recall.js +7 -3
- package/dist/routes/recall.js.map +1 -1
- package/dist/routes/registration.d.ts +27 -0
- package/dist/routes/registration.d.ts.map +1 -0
- package/dist/routes/registration.js +311 -0
- package/dist/routes/registration.js.map +1 -0
- package/dist/routes/replay.d.ts.map +1 -1
- package/dist/routes/replay.js +51 -0
- package/dist/routes/replay.js.map +1 -1
- package/dist/services/optimization-advisor.d.ts +37 -0
- package/dist/services/optimization-advisor.d.ts.map +1 -0
- package/dist/services/optimization-advisor.js +239 -0
- package/dist/services/optimization-advisor.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,224 +1,70 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lore Proxy Routes —
|
|
2
|
+
* Lore Proxy Routes — read-only proxy to Lore v0.5.0 server for dashboard display.
|
|
3
|
+
*
|
|
4
|
+
* Routes:
|
|
5
|
+
* GET /api/lore/memories → list memories (paginated)
|
|
6
|
+
* GET /api/lore/memories/:id → single memory detail
|
|
7
|
+
* GET /api/lore/stats → aggregate stats by type
|
|
3
8
|
*/
|
|
4
9
|
import { Hono } from 'hono';
|
|
5
10
|
import { LoreError } from '../lib/lore-client.js';
|
|
6
11
|
export function loreProxyRoutes(adapter) {
|
|
7
12
|
const app = new Hono();
|
|
8
|
-
// Error handler for adapter errors
|
|
9
13
|
const handleError = (c, err) => {
|
|
10
14
|
if (err instanceof LoreError) {
|
|
11
|
-
|
|
15
|
+
if (err.statusCode === 401 || err.statusCode === 403) {
|
|
16
|
+
return c.json({ error: 'Lore authentication failed', code: 'LORE_AUTH_ERROR', loreStatus: err.statusCode }, 502);
|
|
17
|
+
}
|
|
18
|
+
if (err.statusCode === 404) {
|
|
19
|
+
return c.json({ error: 'Memory not found', code: 'NOT_FOUND' }, 404);
|
|
20
|
+
}
|
|
21
|
+
if (err.statusCode >= 500) {
|
|
22
|
+
return c.json({ error: 'Lore server error', code: 'LORE_SERVER_ERROR', loreStatus: err.statusCode }, 502);
|
|
23
|
+
}
|
|
24
|
+
return c.json({ error: err.message, code: 'LORE_ERROR', loreStatus: err.statusCode }, err.statusCode);
|
|
25
|
+
}
|
|
26
|
+
if (err instanceof Error && err.name === 'TimeoutError') {
|
|
27
|
+
return c.json({ error: 'Lore request timed out', code: 'LORE_TIMEOUT' }, 504);
|
|
28
|
+
}
|
|
29
|
+
if (err instanceof TypeError && (err.message.includes('fetch') || err.message.includes('ECONNREFUSED'))) {
|
|
30
|
+
return c.json({ error: 'Lore service unavailable', code: 'LORE_UNAVAILABLE' }, 503);
|
|
12
31
|
}
|
|
13
32
|
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
14
|
-
return c.json({ error: message },
|
|
33
|
+
return c.json({ error: message, code: 'LORE_UNAVAILABLE' }, 503);
|
|
15
34
|
};
|
|
16
|
-
//
|
|
17
|
-
app.
|
|
35
|
+
// GET /memories — List memories
|
|
36
|
+
app.get('/memories', async (c) => {
|
|
18
37
|
try {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
catch (err) {
|
|
24
|
-
return handleError(c, err);
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
// GET / — List lessons
|
|
28
|
-
app.get('/', async (c) => {
|
|
29
|
-
try {
|
|
30
|
-
const query = {
|
|
31
|
-
category: c.req.query('category'),
|
|
32
|
-
agentId: c.req.query('agentId'),
|
|
33
|
-
importance: c.req.query('importance'),
|
|
34
|
-
search: c.req.query('search'),
|
|
38
|
+
const result = await adapter.listMemories({
|
|
39
|
+
project: c.req.query('project') || undefined,
|
|
40
|
+
search: c.req.query('search') || undefined,
|
|
35
41
|
limit: c.req.query('limit') ? Number(c.req.query('limit')) : undefined,
|
|
36
42
|
offset: c.req.query('offset') ? Number(c.req.query('offset')) : undefined,
|
|
37
|
-
};
|
|
38
|
-
// Remove undefined keys
|
|
39
|
-
const cleaned = Object.fromEntries(Object.entries(query).filter(([, v]) => v !== undefined));
|
|
40
|
-
const result = await adapter.listLessons(cleaned);
|
|
41
|
-
return c.json(result);
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
return handleError(c, err);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
// GET /:id — Get lesson
|
|
48
|
-
app.get('/:id', async (c) => {
|
|
49
|
-
try {
|
|
50
|
-
const result = await adapter.getLesson(c.req.param('id'));
|
|
51
|
-
return c.json(result);
|
|
52
|
-
}
|
|
53
|
-
catch (err) {
|
|
54
|
-
return handleError(c, err);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
// PUT /:id — Update lesson
|
|
58
|
-
app.put('/:id', async (c) => {
|
|
59
|
-
try {
|
|
60
|
-
const body = await c.req.json();
|
|
61
|
-
const result = await adapter.updateLesson(c.req.param('id'), body);
|
|
62
|
-
return c.json(result);
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
return handleError(c, err);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
// DELETE /:id — Delete lesson
|
|
69
|
-
app.delete('/:id', async (c) => {
|
|
70
|
-
try {
|
|
71
|
-
const result = await adapter.deleteLesson(c.req.param('id'));
|
|
43
|
+
});
|
|
72
44
|
return c.json(result);
|
|
73
45
|
}
|
|
74
46
|
catch (err) {
|
|
75
47
|
return handleError(c, err);
|
|
76
48
|
}
|
|
77
49
|
});
|
|
78
|
-
//
|
|
79
|
-
app.
|
|
50
|
+
// GET /memories/:id — Get single memory
|
|
51
|
+
app.get('/memories/:id', async (c) => {
|
|
80
52
|
try {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
53
|
+
const memory = await adapter.getMemory(c.req.param('id'));
|
|
54
|
+
if (!memory) {
|
|
55
|
+
return c.json({ error: 'Memory not found', code: 'NOT_FOUND' }, 404);
|
|
56
|
+
}
|
|
57
|
+
return c.json(memory);
|
|
84
58
|
}
|
|
85
59
|
catch (err) {
|
|
86
60
|
return handleError(c, err);
|
|
87
61
|
}
|
|
88
62
|
});
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
export function loreCommunityProxyRoutes(adapter) {
|
|
92
|
-
const app = new Hono();
|
|
93
|
-
const handleError = (c, err) => {
|
|
94
|
-
if (err instanceof LoreError) {
|
|
95
|
-
return c.json({ error: err.message }, err.statusCode);
|
|
96
|
-
}
|
|
97
|
-
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
98
|
-
return c.json({ error: message }, 500);
|
|
99
|
-
};
|
|
100
|
-
// GET /search — Search community lessons
|
|
101
|
-
app.get('/search', async (c) => {
|
|
102
|
-
try {
|
|
103
|
-
const query = c.req.query('q') ?? c.req.query('query') ?? '';
|
|
104
|
-
const options = {
|
|
105
|
-
category: c.req.query('category') || undefined,
|
|
106
|
-
limit: c.req.query('limit') ? Number(c.req.query('limit')) : undefined,
|
|
107
|
-
minReputation: c.req.query('minReputation') ? Number(c.req.query('minReputation')) : undefined,
|
|
108
|
-
};
|
|
109
|
-
const result = await adapter.searchCommunity(query, options);
|
|
110
|
-
return c.json(result);
|
|
111
|
-
}
|
|
112
|
-
catch (err) {
|
|
113
|
-
return handleError(c, err);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
// POST /rate — Rate a community lesson
|
|
117
|
-
app.post('/rate', async (c) => {
|
|
118
|
-
try {
|
|
119
|
-
const { lessonId, delta } = await c.req.json();
|
|
120
|
-
const result = await adapter.rateLesson(lessonId, delta);
|
|
121
|
-
return c.json(result);
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
return handleError(c, err);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
// GET /config — Get sharing config
|
|
128
|
-
app.get('/config', async (c) => {
|
|
129
|
-
try {
|
|
130
|
-
return c.json(await adapter.getSharingConfig());
|
|
131
|
-
}
|
|
132
|
-
catch (err) {
|
|
133
|
-
return handleError(c, err);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
// PUT /config — Update sharing config
|
|
137
|
-
app.put('/config', async (c) => {
|
|
138
|
-
try {
|
|
139
|
-
const body = await c.req.json();
|
|
140
|
-
return c.json(await adapter.updateSharingConfig(body));
|
|
141
|
-
}
|
|
142
|
-
catch (err) {
|
|
143
|
-
return handleError(c, err);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
// GET /agents — Get agent sharing configs
|
|
147
|
-
app.get('/agents', async (c) => {
|
|
148
|
-
try {
|
|
149
|
-
return c.json(await adapter.getAgentSharingConfigs());
|
|
150
|
-
}
|
|
151
|
-
catch (err) {
|
|
152
|
-
return handleError(c, err);
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
// PUT /agents/:agentId — Update agent sharing config
|
|
156
|
-
app.put('/agents/:agentId', async (c) => {
|
|
157
|
-
try {
|
|
158
|
-
const body = await c.req.json();
|
|
159
|
-
return c.json(await adapter.updateAgentSharingConfig(c.req.param('agentId'), body));
|
|
160
|
-
}
|
|
161
|
-
catch (err) {
|
|
162
|
-
return handleError(c, err);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
// GET /deny-list — Get deny list
|
|
166
|
-
app.get('/deny-list', async (c) => {
|
|
167
|
-
try {
|
|
168
|
-
return c.json(await adapter.getDenyList());
|
|
169
|
-
}
|
|
170
|
-
catch (err) {
|
|
171
|
-
return handleError(c, err);
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
// POST /deny-list — Add deny list rule
|
|
175
|
-
app.post('/deny-list', async (c) => {
|
|
176
|
-
try {
|
|
177
|
-
const body = await c.req.json();
|
|
178
|
-
return c.json(await adapter.addDenyListRule(body), 201);
|
|
179
|
-
}
|
|
180
|
-
catch (err) {
|
|
181
|
-
return handleError(c, err);
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
// DELETE /deny-list/:id — Delete deny list rule
|
|
185
|
-
app.delete('/deny-list/:id', async (c) => {
|
|
186
|
-
try {
|
|
187
|
-
return c.json(await adapter.deleteDenyListRule(c.req.param('id')));
|
|
188
|
-
}
|
|
189
|
-
catch (err) {
|
|
190
|
-
return handleError(c, err);
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
// GET /audit — Get sharing audit log
|
|
194
|
-
app.get('/audit', async (c) => {
|
|
195
|
-
try {
|
|
196
|
-
const params = {
|
|
197
|
-
eventType: c.req.query('eventType') || undefined,
|
|
198
|
-
from: c.req.query('from') || undefined,
|
|
199
|
-
to: c.req.query('to') || undefined,
|
|
200
|
-
limit: c.req.query('limit') ? Number(c.req.query('limit')) : undefined,
|
|
201
|
-
};
|
|
202
|
-
return c.json(await adapter.getSharingAuditLog(params));
|
|
203
|
-
}
|
|
204
|
-
catch (err) {
|
|
205
|
-
return handleError(c, err);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
// GET /stats — Get sharing stats
|
|
63
|
+
// GET /stats — Aggregate stats
|
|
209
64
|
app.get('/stats', async (c) => {
|
|
210
65
|
try {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
catch (err) {
|
|
214
|
-
return handleError(c, err);
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
// POST /purge — Kill switch
|
|
218
|
-
app.post('/purge', async (c) => {
|
|
219
|
-
try {
|
|
220
|
-
const { confirmation } = await c.req.json();
|
|
221
|
-
return c.json(await adapter.purgeSharing(confirmation));
|
|
66
|
+
const result = await adapter.getStats(c.req.query('project') || undefined);
|
|
67
|
+
return c.json(result);
|
|
222
68
|
}
|
|
223
69
|
catch (err) {
|
|
224
70
|
return handleError(c, err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lore-proxy.js","sourceRoot":"","sources":["../../src/routes/lore-proxy.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"lore-proxy.js","sourceRoot":"","sources":["../../src/routes/lore-proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Policy Enforcement Routes (Phase 2 — Feature 6)
|
|
3
|
+
*
|
|
4
|
+
* GET /api/mcp/policies — List MCP tool usage policies
|
|
5
|
+
* POST /api/mcp/policies — Create a policy
|
|
6
|
+
* DELETE /api/mcp/policies/:id — Delete a policy
|
|
7
|
+
* POST /api/mcp/evaluate — Check if an MCP tool call is allowed
|
|
8
|
+
*/
|
|
9
|
+
import { Hono } from 'hono';
|
|
10
|
+
import type { AuthVariables } from '../middleware/auth.js';
|
|
11
|
+
import type { SqliteDb } from '../db/index.js';
|
|
12
|
+
export interface McpPolicy {
|
|
13
|
+
id: string;
|
|
14
|
+
tenantId: string;
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
tool_name: string;
|
|
19
|
+
agent_id?: string;
|
|
20
|
+
action: 'allow' | 'deny';
|
|
21
|
+
conditions: Record<string, unknown>;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
updatedAt: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class McpPolicyStore {
|
|
26
|
+
private readonly db;
|
|
27
|
+
constructor(db: SqliteDb);
|
|
28
|
+
private _ensureTable;
|
|
29
|
+
createPolicy(policy: McpPolicy): void;
|
|
30
|
+
listPolicies(tenantId: string, toolName?: string): McpPolicy[];
|
|
31
|
+
getPolicy(tenantId: string, id: string): McpPolicy | null;
|
|
32
|
+
deletePolicy(tenantId: string, id: string): boolean;
|
|
33
|
+
/** Get all enabled policies matching tool_name and agent_id */
|
|
34
|
+
findMatchingPolicies(tenantId: string, toolName: string, agentId?: string): McpPolicy[];
|
|
35
|
+
private _map;
|
|
36
|
+
}
|
|
37
|
+
export declare function mcpPolicyRoutes(db: SqliteDb): Hono<{
|
|
38
|
+
Variables: AuthVariables;
|
|
39
|
+
}, import("hono/types").BlankSchema, "/">;
|
|
40
|
+
//# sourceMappingURL=mcp-policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-policies.d.ts","sourceRoot":"","sources":["../../src/routes/mcp-policies.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAiB/C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAIzC,OAAO,CAAC,YAAY;IAkBpB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAUrC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE;IAa9D,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAOzD,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAOnD,+DAA+D;IAC/D,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE;IAYvF,OAAO,CAAC,IAAI;CAeb;AAID,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ;eAER,aAAa;0CA+FhD"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Policy Enforcement Routes (Phase 2 — Feature 6)
|
|
3
|
+
*
|
|
4
|
+
* GET /api/mcp/policies — List MCP tool usage policies
|
|
5
|
+
* POST /api/mcp/policies — Create a policy
|
|
6
|
+
* DELETE /api/mcp/policies/:id — Delete a policy
|
|
7
|
+
* POST /api/mcp/evaluate — Check if an MCP tool call is allowed
|
|
8
|
+
*/
|
|
9
|
+
import { Hono } from 'hono';
|
|
10
|
+
import { ulid } from 'ulid';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { getTenantId } from './tenant-helper.js';
|
|
13
|
+
import { parseBody, notFound, created } from './helpers.js';
|
|
14
|
+
import { sql } from 'drizzle-orm';
|
|
15
|
+
// ─── Schema ──────────────────────────────────────────────
|
|
16
|
+
const CreateMcpPolicySchema = z.object({
|
|
17
|
+
name: z.string().min(1).max(200),
|
|
18
|
+
description: z.string().max(1000).optional(),
|
|
19
|
+
enabled: z.boolean().default(true),
|
|
20
|
+
tool_name: z.string().min(1).max(200),
|
|
21
|
+
agent_id: z.string().optional(),
|
|
22
|
+
action: z.enum(['allow', 'deny']).default('deny'),
|
|
23
|
+
conditions: z.record(z.string(), z.unknown()).optional(),
|
|
24
|
+
});
|
|
25
|
+
// ─── Store ───────────────────────────────────────────────
|
|
26
|
+
export class McpPolicyStore {
|
|
27
|
+
db;
|
|
28
|
+
constructor(db) {
|
|
29
|
+
this.db = db;
|
|
30
|
+
this._ensureTable();
|
|
31
|
+
}
|
|
32
|
+
_ensureTable() {
|
|
33
|
+
this.db.run(sql.raw(`
|
|
34
|
+
CREATE TABLE IF NOT EXISTS mcp_policies (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
tenant_id TEXT NOT NULL,
|
|
37
|
+
name TEXT NOT NULL,
|
|
38
|
+
description TEXT,
|
|
39
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
40
|
+
tool_name TEXT NOT NULL,
|
|
41
|
+
agent_id TEXT,
|
|
42
|
+
action TEXT NOT NULL DEFAULT 'deny',
|
|
43
|
+
conditions TEXT NOT NULL DEFAULT '{}',
|
|
44
|
+
created_at TEXT NOT NULL,
|
|
45
|
+
updated_at TEXT NOT NULL
|
|
46
|
+
)
|
|
47
|
+
`));
|
|
48
|
+
}
|
|
49
|
+
createPolicy(policy) {
|
|
50
|
+
this.db.run(sql `
|
|
51
|
+
INSERT INTO mcp_policies (id, tenant_id, name, description, enabled, tool_name, agent_id, action, conditions, created_at, updated_at)
|
|
52
|
+
VALUES (${policy.id}, ${policy.tenantId}, ${policy.name}, ${policy.description ?? null},
|
|
53
|
+
${policy.enabled ? 1 : 0}, ${policy.tool_name}, ${policy.agent_id ?? null},
|
|
54
|
+
${policy.action}, ${JSON.stringify(policy.conditions)},
|
|
55
|
+
${policy.createdAt}, ${policy.updatedAt})
|
|
56
|
+
`);
|
|
57
|
+
}
|
|
58
|
+
listPolicies(tenantId, toolName) {
|
|
59
|
+
if (toolName) {
|
|
60
|
+
const rows = this.db.all(sql `
|
|
61
|
+
SELECT * FROM mcp_policies WHERE tenant_id = ${tenantId} AND tool_name = ${toolName} ORDER BY created_at DESC
|
|
62
|
+
`);
|
|
63
|
+
return rows.map((r) => this._map(r));
|
|
64
|
+
}
|
|
65
|
+
const rows = this.db.all(sql `
|
|
66
|
+
SELECT * FROM mcp_policies WHERE tenant_id = ${tenantId} ORDER BY created_at DESC
|
|
67
|
+
`);
|
|
68
|
+
return rows.map((r) => this._map(r));
|
|
69
|
+
}
|
|
70
|
+
getPolicy(tenantId, id) {
|
|
71
|
+
const row = this.db.get(sql `
|
|
72
|
+
SELECT * FROM mcp_policies WHERE id = ${id} AND tenant_id = ${tenantId}
|
|
73
|
+
`);
|
|
74
|
+
return row ? this._map(row) : null;
|
|
75
|
+
}
|
|
76
|
+
deletePolicy(tenantId, id) {
|
|
77
|
+
const existing = this.getPolicy(tenantId, id);
|
|
78
|
+
if (!existing)
|
|
79
|
+
return false;
|
|
80
|
+
this.db.run(sql `DELETE FROM mcp_policies WHERE id = ${id} AND tenant_id = ${tenantId}`);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
/** Get all enabled policies matching tool_name and agent_id */
|
|
84
|
+
findMatchingPolicies(tenantId, toolName, agentId) {
|
|
85
|
+
const rows = this.db.all(sql `
|
|
86
|
+
SELECT * FROM mcp_policies
|
|
87
|
+
WHERE tenant_id = ${tenantId}
|
|
88
|
+
AND enabled = 1
|
|
89
|
+
AND tool_name = ${toolName}
|
|
90
|
+
AND (agent_id IS NULL OR agent_id = ${agentId ?? ''})
|
|
91
|
+
ORDER BY created_at ASC
|
|
92
|
+
`);
|
|
93
|
+
return rows.map((r) => this._map(r));
|
|
94
|
+
}
|
|
95
|
+
_map(row) {
|
|
96
|
+
return {
|
|
97
|
+
id: row['id'],
|
|
98
|
+
tenantId: row['tenant_id'],
|
|
99
|
+
name: row['name'],
|
|
100
|
+
description: row['description'] || undefined,
|
|
101
|
+
enabled: row['enabled'] === 1 || row['enabled'] === true,
|
|
102
|
+
tool_name: row['tool_name'],
|
|
103
|
+
agent_id: row['agent_id'] || undefined,
|
|
104
|
+
action: row['action'] ?? 'deny',
|
|
105
|
+
conditions: JSON.parse(row['conditions'] || '{}'),
|
|
106
|
+
createdAt: row['created_at'],
|
|
107
|
+
updatedAt: row['updated_at'],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// ─── Routes ──────────────────────────────────────────────
|
|
112
|
+
export function mcpPolicyRoutes(db) {
|
|
113
|
+
const store = new McpPolicyStore(db);
|
|
114
|
+
const app = new Hono();
|
|
115
|
+
/**
|
|
116
|
+
* @summary List MCP tool usage policies
|
|
117
|
+
* @param {string} [tool_name] — filter by tool name (query param)
|
|
118
|
+
* @returns {200} `{ policies: McpPolicy[] }`
|
|
119
|
+
*/
|
|
120
|
+
app.get('/policies', async (c) => {
|
|
121
|
+
const tenantId = getTenantId(c);
|
|
122
|
+
const toolName = c.req.query('tool_name');
|
|
123
|
+
const policies = store.listPolicies(tenantId, toolName || undefined);
|
|
124
|
+
return c.json({ policies });
|
|
125
|
+
});
|
|
126
|
+
/**
|
|
127
|
+
* @summary Create an MCP tool usage policy
|
|
128
|
+
* @body {CreateMcpPolicy} — name, tool_name, agent_id, action, conditions
|
|
129
|
+
* @returns {201} `McpPolicy`
|
|
130
|
+
* @throws {400} Validation failed
|
|
131
|
+
*/
|
|
132
|
+
app.post('/policies', async (c) => {
|
|
133
|
+
const tenantId = getTenantId(c);
|
|
134
|
+
const parsed = await parseBody(c, CreateMcpPolicySchema);
|
|
135
|
+
if (!parsed.success)
|
|
136
|
+
return parsed.response;
|
|
137
|
+
const now = new Date().toISOString();
|
|
138
|
+
const policy = {
|
|
139
|
+
id: ulid(),
|
|
140
|
+
tenantId,
|
|
141
|
+
name: parsed.data.name,
|
|
142
|
+
description: parsed.data.description,
|
|
143
|
+
enabled: parsed.data.enabled,
|
|
144
|
+
tool_name: parsed.data.tool_name,
|
|
145
|
+
agent_id: parsed.data.agent_id,
|
|
146
|
+
action: parsed.data.action,
|
|
147
|
+
conditions: parsed.data.conditions ?? {},
|
|
148
|
+
createdAt: now,
|
|
149
|
+
updatedAt: now,
|
|
150
|
+
};
|
|
151
|
+
store.createPolicy(policy);
|
|
152
|
+
return created(c, policy);
|
|
153
|
+
});
|
|
154
|
+
/**
|
|
155
|
+
* @summary Delete an MCP policy
|
|
156
|
+
* @param {string} id — Policy ID (path)
|
|
157
|
+
* @returns {200} `{ ok: true }`
|
|
158
|
+
* @throws {404} Policy not found
|
|
159
|
+
*/
|
|
160
|
+
app.delete('/policies/:id', async (c) => {
|
|
161
|
+
const tenantId = getTenantId(c);
|
|
162
|
+
const id = c.req.param('id');
|
|
163
|
+
const deleted = store.deletePolicy(tenantId, id);
|
|
164
|
+
if (!deleted)
|
|
165
|
+
return notFound(c, 'MCP policy');
|
|
166
|
+
return c.json({ ok: true });
|
|
167
|
+
});
|
|
168
|
+
/**
|
|
169
|
+
* @summary Evaluate if an MCP tool call is allowed by policies
|
|
170
|
+
* @body { tool_name: string, agent_id?: string }
|
|
171
|
+
* @returns {200} `{ allowed: boolean, matched_policies: McpPolicy[], reason?: string }`
|
|
172
|
+
* @throws {400} Missing tool_name
|
|
173
|
+
*/
|
|
174
|
+
app.post('/evaluate', async (c) => {
|
|
175
|
+
const tenantId = getTenantId(c);
|
|
176
|
+
const body = await c.req.json().catch(() => null);
|
|
177
|
+
if (!body?.tool_name) {
|
|
178
|
+
return c.json({ error: 'Missing tool_name', status: 400 }, 400);
|
|
179
|
+
}
|
|
180
|
+
const toolName = body.tool_name;
|
|
181
|
+
const agentId = body.agent_id;
|
|
182
|
+
const matching = store.findMatchingPolicies(tenantId, toolName, agentId);
|
|
183
|
+
if (matching.length === 0) {
|
|
184
|
+
// No policies match — allow by default
|
|
185
|
+
return c.json({ allowed: true, matched_policies: [], reason: 'No matching policies' });
|
|
186
|
+
}
|
|
187
|
+
// If any deny policy matches, deny
|
|
188
|
+
const denyPolicy = matching.find((p) => p.action === 'deny');
|
|
189
|
+
if (denyPolicy) {
|
|
190
|
+
return c.json({
|
|
191
|
+
allowed: false,
|
|
192
|
+
matched_policies: matching,
|
|
193
|
+
reason: `Denied by policy "${denyPolicy.name}": tool "${toolName}" ${agentId ? `cannot be called by agent "${agentId}"` : 'is restricted'}`,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return c.json({ allowed: true, matched_policies: matching, reason: 'Allowed by policy' });
|
|
197
|
+
});
|
|
198
|
+
return app;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=mcp-policies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-policies.js","sourceRoot":"","sources":["../../src/routes/mcp-policies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optimization Advisor Endpoints (Feature 10)
|
|
3
|
+
*
|
|
4
|
+
* GET /api/agents/:id/optimize — per-agent optimization suggestions
|
|
5
|
+
* GET /api/optimize/summary — aggregate suggestions across all agents
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from 'hono';
|
|
8
|
+
import type { IEventStore } from '@agentlensai/core';
|
|
9
|
+
import type { AuthVariables } from '../middleware/auth.js';
|
|
10
|
+
export declare function optimizationAdvisorRoutes(store: IEventStore): Hono<{
|
|
11
|
+
Variables: AuthVariables;
|
|
12
|
+
}, import("hono/types").BlankSchema, "/">;
|
|
13
|
+
//# sourceMappingURL=optimization-advisor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimization-advisor.d.ts","sourceRoot":"","sources":["../../src/routes/optimization-advisor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAI3D,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,WAAW;eACxB,aAAa;0CAkChD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optimization Advisor Endpoints (Feature 10)
|
|
3
|
+
*
|
|
4
|
+
* GET /api/agents/:id/optimize — per-agent optimization suggestions
|
|
5
|
+
* GET /api/optimize/summary — aggregate suggestions across all agents
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from 'hono';
|
|
8
|
+
import { getTenantStore } from './tenant-helper.js';
|
|
9
|
+
import { getOptimizationSuggestions, getOptimizationSummary } from '../services/optimization-advisor.js';
|
|
10
|
+
export function optimizationAdvisorRoutes(store) {
|
|
11
|
+
const app = new Hono();
|
|
12
|
+
// GET /api/agents/:id/optimize
|
|
13
|
+
app.get('/agents/:id/optimize', async (c) => {
|
|
14
|
+
const tenantStore = getTenantStore(store, c);
|
|
15
|
+
const agentId = c.req.param('id');
|
|
16
|
+
if (!agentId) {
|
|
17
|
+
return c.json({ error: 'Agent ID is required', status: 400 }, 400);
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const result = await getOptimizationSuggestions(tenantStore, agentId);
|
|
21
|
+
return c.json(result);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
const message = error instanceof Error ? error.message : 'Internal error';
|
|
25
|
+
return c.json({ error: message, status: 500 }, 500);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
// GET /api/optimize/summary
|
|
29
|
+
app.get('/optimize/summary', async (c) => {
|
|
30
|
+
const tenantStore = getTenantStore(store, c);
|
|
31
|
+
try {
|
|
32
|
+
const result = await getOptimizationSummary(tenantStore);
|
|
33
|
+
return c.json(result);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const message = error instanceof Error ? error.message : 'Internal error';
|
|
37
|
+
return c.json({ error: message, status: 500 }, 500);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return app;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=optimization-advisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimization-advisor.js","sourceRoot":"","sources":["../../src/routes/optimization-advisor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAEzG,MAAM,UAAU,yBAAyB,CAAC,KAAkB;IAC1D,MAAM,GAAG,GAAG,IAAI,IAAI,EAAgC,CAAC;IAErD,+BAA+B;IAC/B,GAAG,CAAC,GAAG,CAAC,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1C,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACtE,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;YAC1E,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,4BAA4B;IAC5B,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAE7C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,WAAW,CAAC,CAAC;YACzD,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;YAC1E,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/routes/recall.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,0BAA0B,CAAC;AAMxF,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe;eACd,aAAa;
|
|
1
|
+
{"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/routes/recall.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,0BAA0B,CAAC;AAMxF,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe;eACd,aAAa;0CA0GhD"}
|