@axiom-lattice/gateway 3.0.2 → 3.0.3
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/index.js +31 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -6
- package/.eslintrc.json +0 -22
- package/.turbo/turbo-build.log +0 -46
- package/AGENTS.md +0 -112
- package/CHANGELOG.md +0 -1190
- package/LOGGER_CONFIG.md +0 -135
- package/RESUME_STREAM_CONTENT_BASED.md +0 -326
- package/RESUME_STREAM_README.md +0 -388
- package/jest.config.js +0 -72
- package/public/sdk/README.md +0 -695
- package/public/sdk/dashboard-engine-skill.md +0 -1122
- package/public/sdk/dashboard-single-file-spec.md +0 -357
- package/public/sdk/data-query-sdk-skill.md +0 -307
- package/public/sdk/data-query-sdk.d.ts +0 -252
- package/public/sdk/data-query-sdk.js +0 -970
- package/public/sdk/occupancy-dashboard.html +0 -363
- package/public/sdk/test-dashboard.html +0 -690
- package/scripts/seed-lark-installation.ts +0 -54
- package/src/__tests__/__mocks__/e2b.ts +0 -1
- package/src/__tests__/a2a.test.ts +0 -428
- package/src/__tests__/channel-installations.test.ts +0 -199
- package/src/__tests__/data-query.test.ts +0 -77
- package/src/__tests__/sandbox-provider-registration.test.ts +0 -74
- package/src/__tests__/setup.ts +0 -5
- package/src/__tests__/workspace.test.ts +0 -400
- package/src/channels/__tests__/routes.test.ts +0 -50
- package/src/channels/lark/LarkChannelAdapter.ts +0 -217
- package/src/channels/lark/README.md +0 -187
- package/src/channels/lark/__tests__/controller.test.ts +0 -136
- package/src/channels/lark/__tests__/mapping-service.test.ts +0 -118
- package/src/channels/lark/__tests__/parser.test.ts +0 -72
- package/src/channels/lark/__tests__/sender.test.ts +0 -37
- package/src/channels/lark/__tests__/verification.test.ts +0 -157
- package/src/channels/lark/controller.ts +0 -48
- package/src/channels/lark/mapping-service.ts +0 -138
- package/src/channels/lark/parser.ts +0 -68
- package/src/channels/lark/routes.ts +0 -22
- package/src/channels/lark/sender.ts +0 -58
- package/src/channels/lark/types.ts +0 -20
- package/src/channels/lark/verification.ts +0 -32
- package/src/channels/registry.ts +0 -20
- package/src/channels/routes.ts +0 -30
- package/src/channels/wechat/WechatChannelAdapter.ts +0 -294
- package/src/channels/wechat/__tests__/context-store.test.ts +0 -148
- package/src/channels/wechat/context-store.ts +0 -54
- package/src/channels/wechat/controller.ts +0 -59
- package/src/channels/wechat/routes.ts +0 -7
- package/src/channels/wechat/types.ts +0 -62
- package/src/channels/wechat/wechat-client.ts +0 -162
- package/src/config/local-a2a-templates.ts +0 -59
- package/src/config.ts +0 -124
- package/src/controllers/__tests__/assistant-local-a2a.test.ts +0 -147
- package/src/controllers/__tests__/local-a2a-templates.test.ts +0 -112
- package/src/controllers/__tests__/mime.test.ts +0 -74
- package/src/controllers/__tests__/resources.test.ts +0 -122
- package/src/controllers/__tests__/run.test.ts +0 -115
- package/src/controllers/__tests__/tasks.test.ts +0 -215
- package/src/controllers/__tests__/workflow-tracking.test.ts +0 -113
- package/src/controllers/agent_task.ts +0 -72
- package/src/controllers/assistant.ts +0 -490
- package/src/controllers/auth.ts +0 -524
- package/src/controllers/channel-bindings.ts +0 -135
- package/src/controllers/channel-installations.ts +0 -409
- package/src/controllers/collections.ts +0 -176
- package/src/controllers/config.ts +0 -126
- package/src/controllers/connections.ts +0 -181
- package/src/controllers/data-query.ts +0 -236
- package/src/controllers/database-configs.ts +0 -440
- package/src/controllers/embeddings.ts +0 -22
- package/src/controllers/entries.ts +0 -167
- package/src/controllers/eval.ts +0 -513
- package/src/controllers/export-import.ts +0 -166
- package/src/controllers/health.ts +0 -36
- package/src/controllers/local-a2a-templates.ts +0 -18
- package/src/controllers/local-a2a.ts +0 -149
- package/src/controllers/mcp-configs.ts +0 -673
- package/src/controllers/memory.ts +0 -257
- package/src/controllers/menu-items.ts +0 -114
- package/src/controllers/metrics-configs.ts +0 -1061
- package/src/controllers/middleware-types.ts +0 -15
- package/src/controllers/models.ts +0 -199
- package/src/controllers/personal-assistant.ts +0 -191
- package/src/controllers/resources.ts +0 -477
- package/src/controllers/run.ts +0 -338
- package/src/controllers/sandbox.ts +0 -255
- package/src/controllers/schedules.ts +0 -336
- package/src/controllers/skills.ts +0 -256
- package/src/controllers/tasks.ts +0 -213
- package/src/controllers/tenants.ts +0 -121
- package/src/controllers/thread_status.ts +0 -66
- package/src/controllers/threads.ts +0 -260
- package/src/controllers/tools.ts +0 -139
- package/src/controllers/users.ts +0 -135
- package/src/controllers/workflow-tracking.ts +0 -693
- package/src/controllers/workspace.ts +0 -879
- package/src/export_registrations/a2a-api-key.registration.ts +0 -89
- package/src/export_registrations/agent.registration.ts +0 -80
- package/src/export_registrations/binding.registration.ts +0 -106
- package/src/export_registrations/channel-installation.registration.ts +0 -88
- package/src/export_registrations/collection.registration.ts +0 -85
- package/src/export_registrations/connection.registration.ts +0 -97
- package/src/export_registrations/database-config.registration.ts +0 -94
- package/src/export_registrations/eval.registration.ts +0 -334
- package/src/export_registrations/index.ts +0 -31
- package/src/export_registrations/mcp-config.registration.ts +0 -97
- package/src/export_registrations/menu.registration.ts +0 -91
- package/src/export_registrations/metrics-config.registration.ts +0 -94
- package/src/export_registrations/skill.registration.ts +0 -88
- package/src/export_registrations/task.registration.ts +0 -99
- package/src/index.ts +0 -497
- package/src/logger/Logger.ts +0 -186
- package/src/router/MessageContext.ts +0 -14
- package/src/router/MessageRouter.ts +0 -490
- package/src/router/middlewares/auditLogger.ts +0 -34
- package/src/router/middlewares/deduplication.ts +0 -38
- package/src/router/middlewares/index.ts +0 -3
- package/src/router/middlewares/rateLimit.ts +0 -46
- package/src/routes/__tests__/a2a-test-connection.test.ts +0 -177
- package/src/routes/a2a-bridge.ts +0 -266
- package/src/routes/a2a-test-connection.ts +0 -126
- package/src/routes/a2a.ts +0 -851
- package/src/routes/channel-bindings.ts +0 -11
- package/src/routes/channel-installations.ts +0 -33
- package/src/routes/index.ts +0 -640
- package/src/routes/menu-items.ts +0 -10
- package/src/routes/resource-routes.ts +0 -35
- package/src/routes/stt.ts +0 -102
- package/src/schemas/data-query.ts +0 -69
- package/src/schemas/index.ts +0 -852
- package/src/services/ExportImportService.ts +0 -296
- package/src/services/__tests__/ExportImportService.test.ts +0 -130
- package/src/services/__tests__/eval-runner.test.ts +0 -131
- package/src/services/__tests__/local-a2a.test.ts +0 -124
- package/src/services/agent_task_consumer.ts +0 -348
- package/src/services/collection_service.ts +0 -258
- package/src/services/eval-runner.ts +0 -283
- package/src/services/local-a2a.ts +0 -354
- package/src/services/queue_service.ts +0 -104
- package/src/services/sandbox_service.ts +0 -223
- package/src/services/skill_service.ts +0 -97
- package/src/services/supabase.ts +0 -60
- package/src/swagger.ts +0 -77
- package/src/types/index.ts +0 -118
- package/src/types/koa.d.ts +0 -7
- package/src/utils/__tests__/local-a2a-runtime.test.ts +0 -77
- package/src/utils/__tests__/path-containment.test.ts +0 -35
- package/src/utils/a2a-url.ts +0 -20
- package/src/utils/local-a2a-runtime.ts +0 -107
- package/src/utils/mime.ts +0 -44
- package/src/utils/path-containment.ts +0 -38
- package/tsconfig.json +0 -26
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
import { FastifyRequest, FastifyReply } from "fastify";
|
|
2
|
-
import { scheduleLatticeManager } from "@axiom-lattice/core";
|
|
3
|
-
import {
|
|
4
|
-
ScheduledTaskDefinition,
|
|
5
|
-
ScheduledTaskStatus,
|
|
6
|
-
} from "@axiom-lattice/protocols";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Schedule Controller
|
|
10
|
-
* Handles schedule-related operations for viewing and managing scheduled tasks
|
|
11
|
-
* All operations are scoped to a tenant ID
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Get tenant ID from request headers or user context
|
|
16
|
-
*/
|
|
17
|
-
function getTenantId(request: FastifyRequest): string {
|
|
18
|
-
// First try to get from authenticated user context
|
|
19
|
-
const userTenantId = (request as any).user?.tenantId;
|
|
20
|
-
if (userTenantId) {
|
|
21
|
-
return userTenantId;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Fallback to request headers for backward compatibility
|
|
25
|
-
return (request.headers["x-tenant-id"] as string) || "default";
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Scheduled tasks list response interface
|
|
30
|
-
*/
|
|
31
|
-
interface ScheduledTasksListResponse {
|
|
32
|
-
success: boolean;
|
|
33
|
-
message: string;
|
|
34
|
-
data: {
|
|
35
|
-
records: ScheduledTaskDefinition[];
|
|
36
|
-
total: number;
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Scheduled task response interface
|
|
42
|
-
*/
|
|
43
|
-
interface ScheduledTaskResponse {
|
|
44
|
-
success: boolean;
|
|
45
|
-
message: string;
|
|
46
|
-
data?: ScheduledTaskDefinition | null;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Helper function to get the schedule lattice safely
|
|
51
|
-
* Returns null if no schedule lattice is registered
|
|
52
|
-
*/
|
|
53
|
-
function getScheduleLattice() {
|
|
54
|
-
// Try to get the first available schedule lattice
|
|
55
|
-
const keys = scheduleLatticeManager.getLatticeKeys();
|
|
56
|
-
if (keys.length === 0) {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
// Use "default" if available, otherwise use the first one
|
|
60
|
-
if (scheduleLatticeManager.hasLattice("default")) {
|
|
61
|
-
return scheduleLatticeManager.getScheduleLattice("default");
|
|
62
|
-
}
|
|
63
|
-
return scheduleLatticeManager.getScheduleLattice(keys[0]);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Get scheduled tasks for a specific thread
|
|
68
|
-
*/
|
|
69
|
-
export async function getThreadSchedules(
|
|
70
|
-
request: FastifyRequest<{
|
|
71
|
-
Params: { assistantId: string; threadId: string };
|
|
72
|
-
Querystring: {
|
|
73
|
-
status?: ScheduledTaskStatus;
|
|
74
|
-
limit?: string;
|
|
75
|
-
offset?: string;
|
|
76
|
-
};
|
|
77
|
-
}>,
|
|
78
|
-
reply: FastifyReply
|
|
79
|
-
): Promise<ScheduledTasksListResponse> {
|
|
80
|
-
const { assistantId, threadId } = request.params;
|
|
81
|
-
const { status, limit, offset } = request.query;
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
const scheduleLattice = getScheduleLattice();
|
|
85
|
-
|
|
86
|
-
// If no schedule lattice is registered, return empty result
|
|
87
|
-
if (!scheduleLattice) {
|
|
88
|
-
return {
|
|
89
|
-
success: true,
|
|
90
|
-
message: "No schedule lattice configured",
|
|
91
|
-
data: {
|
|
92
|
-
records: [],
|
|
93
|
-
total: 0,
|
|
94
|
-
},
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const storage = scheduleLattice.client.getStorage();
|
|
99
|
-
|
|
100
|
-
if (!storage) {
|
|
101
|
-
return {
|
|
102
|
-
success: true,
|
|
103
|
-
message: "No schedule storage configured",
|
|
104
|
-
data: {
|
|
105
|
-
records: [],
|
|
106
|
-
total: 0,
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const tenantId = getTenantId(request);
|
|
112
|
-
|
|
113
|
-
const filters: {
|
|
114
|
-
tenantId: string;
|
|
115
|
-
threadId: string;
|
|
116
|
-
assistantId?: string;
|
|
117
|
-
status?: ScheduledTaskStatus;
|
|
118
|
-
limit?: number;
|
|
119
|
-
offset?: number;
|
|
120
|
-
} = {
|
|
121
|
-
tenantId,
|
|
122
|
-
threadId,
|
|
123
|
-
assistantId,
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
if (status) {
|
|
127
|
-
filters.status = status;
|
|
128
|
-
}
|
|
129
|
-
if (limit) {
|
|
130
|
-
filters.limit = parseInt(limit, 10);
|
|
131
|
-
}
|
|
132
|
-
if (offset) {
|
|
133
|
-
filters.offset = parseInt(offset, 10);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const tasks = await storage.getAllTasks(filters);
|
|
137
|
-
const total = await storage.countTasks({
|
|
138
|
-
tenantId,
|
|
139
|
-
threadId,
|
|
140
|
-
assistantId,
|
|
141
|
-
status,
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
return {
|
|
145
|
-
success: true,
|
|
146
|
-
message: "Successfully retrieved scheduled tasks",
|
|
147
|
-
data: {
|
|
148
|
-
records: tasks,
|
|
149
|
-
total,
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
} catch (error) {
|
|
153
|
-
request.log.error(error, "Failed to get thread schedules");
|
|
154
|
-
return reply.status(500).send({
|
|
155
|
-
success: false,
|
|
156
|
-
message: "Failed to retrieve scheduled tasks",
|
|
157
|
-
data: {
|
|
158
|
-
records: [],
|
|
159
|
-
total: 0,
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Get a single scheduled task by ID
|
|
167
|
-
*/
|
|
168
|
-
export async function getScheduledTask(
|
|
169
|
-
request: FastifyRequest<{
|
|
170
|
-
Params: { taskId: string };
|
|
171
|
-
}>,
|
|
172
|
-
reply: FastifyReply
|
|
173
|
-
): Promise<ScheduledTaskResponse> {
|
|
174
|
-
const { taskId } = request.params;
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
const scheduleLattice = getScheduleLattice();
|
|
178
|
-
|
|
179
|
-
if (!scheduleLattice) {
|
|
180
|
-
return reply.status(404).send({
|
|
181
|
-
success: false,
|
|
182
|
-
message: "No schedule lattice configured",
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const task = await scheduleLattice.client.getTask(taskId);
|
|
187
|
-
|
|
188
|
-
if (!task) {
|
|
189
|
-
return reply.status(404).send({
|
|
190
|
-
success: false,
|
|
191
|
-
message: "Scheduled task not found",
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return {
|
|
196
|
-
success: true,
|
|
197
|
-
message: "Successfully retrieved scheduled task",
|
|
198
|
-
data: task,
|
|
199
|
-
};
|
|
200
|
-
} catch (error) {
|
|
201
|
-
request.log.error(error, "Failed to get scheduled task");
|
|
202
|
-
return reply.status(500).send({
|
|
203
|
-
success: false,
|
|
204
|
-
message: "Failed to retrieve scheduled task",
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Cancel a scheduled task
|
|
211
|
-
*/
|
|
212
|
-
export async function cancelScheduledTask(
|
|
213
|
-
request: FastifyRequest<{
|
|
214
|
-
Params: { taskId: string };
|
|
215
|
-
}>,
|
|
216
|
-
reply: FastifyReply
|
|
217
|
-
): Promise<{ success: boolean; message: string }> {
|
|
218
|
-
const { taskId } = request.params;
|
|
219
|
-
|
|
220
|
-
try {
|
|
221
|
-
const scheduleLattice = getScheduleLattice();
|
|
222
|
-
|
|
223
|
-
if (!scheduleLattice) {
|
|
224
|
-
return reply.status(404).send({
|
|
225
|
-
success: false,
|
|
226
|
-
message: "No schedule lattice configured",
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const result = await scheduleLattice.client.cancel(taskId);
|
|
231
|
-
|
|
232
|
-
if (!result) {
|
|
233
|
-
return reply.status(404).send({
|
|
234
|
-
success: false,
|
|
235
|
-
message: "Scheduled task not found or already cancelled",
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return {
|
|
240
|
-
success: true,
|
|
241
|
-
message: "Successfully cancelled scheduled task",
|
|
242
|
-
};
|
|
243
|
-
} catch (error) {
|
|
244
|
-
request.log.error(error, "Failed to cancel scheduled task");
|
|
245
|
-
return reply.status(500).send({
|
|
246
|
-
success: false,
|
|
247
|
-
message: "Failed to cancel scheduled task",
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Pause a scheduled cron task
|
|
254
|
-
*/
|
|
255
|
-
export async function pauseScheduledTask(
|
|
256
|
-
request: FastifyRequest<{
|
|
257
|
-
Params: { taskId: string };
|
|
258
|
-
}>,
|
|
259
|
-
reply: FastifyReply
|
|
260
|
-
): Promise<{ success: boolean; message: string }> {
|
|
261
|
-
const { taskId } = request.params;
|
|
262
|
-
|
|
263
|
-
try {
|
|
264
|
-
const scheduleLattice = getScheduleLattice();
|
|
265
|
-
|
|
266
|
-
if (!scheduleLattice) {
|
|
267
|
-
return reply.status(404).send({
|
|
268
|
-
success: false,
|
|
269
|
-
message: "No schedule lattice configured",
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const result = await scheduleLattice.client.pause(taskId);
|
|
274
|
-
|
|
275
|
-
if (!result) {
|
|
276
|
-
return reply.status(404).send({
|
|
277
|
-
success: false,
|
|
278
|
-
message: "Scheduled task not found or cannot be paused",
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return {
|
|
283
|
-
success: true,
|
|
284
|
-
message: "Successfully paused scheduled task",
|
|
285
|
-
};
|
|
286
|
-
} catch (error) {
|
|
287
|
-
request.log.error(error, "Failed to pause scheduled task");
|
|
288
|
-
return reply.status(500).send({
|
|
289
|
-
success: false,
|
|
290
|
-
message: "Failed to pause scheduled task",
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Resume a paused cron task
|
|
297
|
-
*/
|
|
298
|
-
export async function resumeScheduledTask(
|
|
299
|
-
request: FastifyRequest<{
|
|
300
|
-
Params: { taskId: string };
|
|
301
|
-
}>,
|
|
302
|
-
reply: FastifyReply
|
|
303
|
-
): Promise<{ success: boolean; message: string }> {
|
|
304
|
-
const { taskId } = request.params;
|
|
305
|
-
|
|
306
|
-
try {
|
|
307
|
-
const scheduleLattice = getScheduleLattice();
|
|
308
|
-
|
|
309
|
-
if (!scheduleLattice) {
|
|
310
|
-
return reply.status(404).send({
|
|
311
|
-
success: false,
|
|
312
|
-
message: "No schedule lattice configured",
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const result = await scheduleLattice.client.resume(taskId);
|
|
317
|
-
|
|
318
|
-
if (!result) {
|
|
319
|
-
return reply.status(404).send({
|
|
320
|
-
success: false,
|
|
321
|
-
message: "Scheduled task not found or cannot be resumed",
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
return {
|
|
326
|
-
success: true,
|
|
327
|
-
message: "Successfully resumed scheduled task",
|
|
328
|
-
};
|
|
329
|
-
} catch (error) {
|
|
330
|
-
request.log.error(error, "Failed to resume scheduled task");
|
|
331
|
-
return reply.status(500).send({
|
|
332
|
-
success: false,
|
|
333
|
-
message: "Failed to resume scheduled task",
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
}
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { FastifyRequest, FastifyReply } from "fastify";
|
|
2
|
-
import { SkillService } from "../services/skill_service";
|
|
3
|
-
import type { Skill, CreateSkillRequest } from "@axiom-lattice/protocols";
|
|
4
|
-
|
|
5
|
-
const skillService = new SkillService();
|
|
6
|
-
|
|
7
|
-
function serializeSkill(skill: Skill): any {
|
|
8
|
-
const serialized: any = {
|
|
9
|
-
id: skill.id,
|
|
10
|
-
name: skill.name,
|
|
11
|
-
description: skill.description,
|
|
12
|
-
license: skill.license,
|
|
13
|
-
compatibility: skill.compatibility,
|
|
14
|
-
metadata: skill.metadata || {},
|
|
15
|
-
content: skill.content,
|
|
16
|
-
subSkills: skill.subSkills,
|
|
17
|
-
createdAt: skill.createdAt instanceof Date ? skill.createdAt.toISOString() : new Date().toISOString(),
|
|
18
|
-
updatedAt: skill.updatedAt instanceof Date ? skill.updatedAt.toISOString() : new Date().toISOString(),
|
|
19
|
-
};
|
|
20
|
-
Object.keys(serialized).forEach((key) => {
|
|
21
|
-
if (serialized[key] === undefined) delete serialized[key];
|
|
22
|
-
});
|
|
23
|
-
return serialized;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface SkillListResponse {
|
|
27
|
-
success: boolean;
|
|
28
|
-
message: string;
|
|
29
|
-
data: { records: any[]; total: number };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface SkillResponse {
|
|
33
|
-
success: boolean;
|
|
34
|
-
message: string;
|
|
35
|
-
data?: any;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
interface SkillUpdateBody {
|
|
39
|
-
name?: string;
|
|
40
|
-
description?: string;
|
|
41
|
-
license?: string;
|
|
42
|
-
compatibility?: string;
|
|
43
|
-
metadata?: Record<string, string>;
|
|
44
|
-
content?: string;
|
|
45
|
-
subSkills?: string[];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export async function getSkillList(request: FastifyRequest, reply: FastifyReply): Promise<SkillListResponse> {
|
|
49
|
-
try {
|
|
50
|
-
const skills = await skillService.getAllSkills(request);
|
|
51
|
-
return {
|
|
52
|
-
success: true,
|
|
53
|
-
message: "Successfully retrieved skill list",
|
|
54
|
-
data: { records: skills.map(serializeSkill), total: skills.length },
|
|
55
|
-
};
|
|
56
|
-
} catch (error: any) {
|
|
57
|
-
return reply.status(500).send({
|
|
58
|
-
success: false,
|
|
59
|
-
message: `Failed to retrieve skills: ${error.message}`,
|
|
60
|
-
data: { records: [], total: 0 },
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export async function getSkill(
|
|
66
|
-
request: FastifyRequest<{ Params: { id: string } }>,
|
|
67
|
-
reply: FastifyReply
|
|
68
|
-
): Promise<SkillResponse> {
|
|
69
|
-
try {
|
|
70
|
-
const { id } = request.params;
|
|
71
|
-
const skill = await skillService.getSkillById(request, id);
|
|
72
|
-
|
|
73
|
-
if (!skill) {
|
|
74
|
-
return reply.status(404).send({ success: false, message: "Skill not found" });
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return { success: true, message: "Successfully retrieved skill", data: serializeSkill(skill) };
|
|
78
|
-
} catch (error: any) {
|
|
79
|
-
return reply.status(500).send({ success: false, message: `Failed to retrieve skill: ${error.message}` });
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export async function createSkill(
|
|
84
|
-
request: FastifyRequest<{ Body: CreateSkillRequest }>,
|
|
85
|
-
reply: FastifyReply
|
|
86
|
-
): Promise<SkillResponse> {
|
|
87
|
-
try {
|
|
88
|
-
const data = request.body;
|
|
89
|
-
if (!data.name) {
|
|
90
|
-
return reply.status(400).send({ success: false, message: "name is required" });
|
|
91
|
-
}
|
|
92
|
-
if (!data.description) {
|
|
93
|
-
return reply.status(400).send({ success: false, message: "description is required" });
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const id = (request.body as any).id || data.name;
|
|
97
|
-
if (id !== data.name) {
|
|
98
|
-
return reply.status(400).send({
|
|
99
|
-
success: false,
|
|
100
|
-
message: `id "${id}" must equal name "${data.name}"`,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const skill = await skillService.createSkill(request, id, data);
|
|
105
|
-
return reply.status(201).send({
|
|
106
|
-
success: true,
|
|
107
|
-
message: "Successfully created skill",
|
|
108
|
-
data: serializeSkill(skill),
|
|
109
|
-
});
|
|
110
|
-
} catch (error: any) {
|
|
111
|
-
if (error.message?.includes("already exists")) {
|
|
112
|
-
return reply.status(409).send({ success: false, message: error.message });
|
|
113
|
-
}
|
|
114
|
-
if (error.message?.includes("built-in skill")) {
|
|
115
|
-
return reply.status(403).send({ success: false, message: error.message });
|
|
116
|
-
}
|
|
117
|
-
if (error.message?.includes("must equal name") || error.message?.includes("Invalid skill name")) {
|
|
118
|
-
return reply.status(400).send({ success: false, message: error.message });
|
|
119
|
-
}
|
|
120
|
-
return reply.status(500).send({ success: false, message: `Failed to create skill: ${error.message}` });
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export async function updateSkill(
|
|
125
|
-
request: FastifyRequest<{ Params: { id: string }; Body: SkillUpdateBody }>,
|
|
126
|
-
reply: FastifyReply
|
|
127
|
-
): Promise<SkillResponse> {
|
|
128
|
-
try {
|
|
129
|
-
const { id } = request.params;
|
|
130
|
-
const updates = request.body;
|
|
131
|
-
|
|
132
|
-
const skill = await skillService.updateSkill(request, id, updates);
|
|
133
|
-
|
|
134
|
-
if (!skill) {
|
|
135
|
-
return reply.status(404).send({ success: false, message: "Skill not found" });
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return { success: true, message: "Successfully updated skill", data: serializeSkill(skill) };
|
|
139
|
-
} catch (error: any) {
|
|
140
|
-
if (error.message?.includes("built-in skill")) {
|
|
141
|
-
return reply.status(403).send({ success: false, message: error.message });
|
|
142
|
-
}
|
|
143
|
-
if (error.message?.includes("Invalid skill name")) {
|
|
144
|
-
return reply.status(400).send({ success: false, message: error.message });
|
|
145
|
-
}
|
|
146
|
-
return reply.status(500).send({ success: false, message: `Failed to update skill: ${error.message}` });
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export async function deleteSkill(
|
|
151
|
-
request: FastifyRequest<{ Params: { id: string } }>,
|
|
152
|
-
reply: FastifyReply
|
|
153
|
-
): Promise<{ success: boolean; message: string }> {
|
|
154
|
-
try {
|
|
155
|
-
const { id } = request.params;
|
|
156
|
-
const result = await skillService.deleteSkill(request, id);
|
|
157
|
-
|
|
158
|
-
if (!result) {
|
|
159
|
-
return reply.status(404).send({ success: false, message: "Skill not found" });
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return { success: true, message: "Successfully deleted skill" };
|
|
163
|
-
} catch (error: any) {
|
|
164
|
-
if (error.message?.includes("built-in skill")) {
|
|
165
|
-
return reply.status(403).send({ success: false, message: error.message });
|
|
166
|
-
}
|
|
167
|
-
return reply.status(500).send({ success: false, message: `Failed to delete skill: ${error.message}` });
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export async function searchSkillsByMetadata(
|
|
172
|
-
request: FastifyRequest<{ Querystring: { key: string; value: string } }>,
|
|
173
|
-
reply: FastifyReply
|
|
174
|
-
): Promise<SkillListResponse> {
|
|
175
|
-
try {
|
|
176
|
-
const { key, value } = request.query;
|
|
177
|
-
if (!key || !value) {
|
|
178
|
-
return reply.status(400).send({
|
|
179
|
-
success: false,
|
|
180
|
-
message: "key and value query parameters are required",
|
|
181
|
-
data: { records: [], total: 0 },
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const skills = await skillService.searchByMetadata(request, key, value);
|
|
186
|
-
return {
|
|
187
|
-
success: true,
|
|
188
|
-
message: "Successfully searched skills",
|
|
189
|
-
data: { records: skills.map(serializeSkill), total: skills.length },
|
|
190
|
-
};
|
|
191
|
-
} catch (error: any) {
|
|
192
|
-
return reply.status(500).send({
|
|
193
|
-
success: false,
|
|
194
|
-
message: `Failed to search skills: ${error.message}`,
|
|
195
|
-
data: { records: [], total: 0 },
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export async function filterSkillsByCompatibility(
|
|
201
|
-
request: FastifyRequest<{ Querystring: { compatibility: string } }>,
|
|
202
|
-
reply: FastifyReply
|
|
203
|
-
): Promise<SkillListResponse> {
|
|
204
|
-
try {
|
|
205
|
-
const { compatibility } = request.query;
|
|
206
|
-
if (!compatibility) {
|
|
207
|
-
return reply.status(400).send({
|
|
208
|
-
success: false,
|
|
209
|
-
message: "compatibility query parameter is required",
|
|
210
|
-
data: { records: [], total: 0 },
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const skills = await skillService.filterByCompatibility(request, compatibility);
|
|
215
|
-
return {
|
|
216
|
-
success: true,
|
|
217
|
-
message: "Successfully filtered skills",
|
|
218
|
-
data: { records: skills.map(serializeSkill), total: skills.length },
|
|
219
|
-
};
|
|
220
|
-
} catch (error: any) {
|
|
221
|
-
return reply.status(500).send({
|
|
222
|
-
success: false,
|
|
223
|
-
message: `Failed to filter skills: ${error.message}`,
|
|
224
|
-
data: { records: [], total: 0 },
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
export async function filterSkillsByLicense(
|
|
230
|
-
request: FastifyRequest<{ Querystring: { license: string } }>,
|
|
231
|
-
reply: FastifyReply
|
|
232
|
-
): Promise<SkillListResponse> {
|
|
233
|
-
try {
|
|
234
|
-
const { license } = request.query;
|
|
235
|
-
if (!license) {
|
|
236
|
-
return reply.status(400).send({
|
|
237
|
-
success: false,
|
|
238
|
-
message: "license query parameter is required",
|
|
239
|
-
data: { records: [], total: 0 },
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const skills = await skillService.filterByLicense(request, license);
|
|
244
|
-
return {
|
|
245
|
-
success: true,
|
|
246
|
-
message: "Successfully filtered skills",
|
|
247
|
-
data: { records: skills.map(serializeSkill), total: skills.length },
|
|
248
|
-
};
|
|
249
|
-
} catch (error: any) {
|
|
250
|
-
return reply.status(500).send({
|
|
251
|
-
success: false,
|
|
252
|
-
message: `Failed to filter skills: ${error.message}`,
|
|
253
|
-
data: { records: [], total: 0 },
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
}
|