@axiom-lattice/gateway 3.0.2 → 3.0.4
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 +37 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37 -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
package/src/controllers/tasks.ts
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { FastifyRequest, FastifyReply } from "fastify";
|
|
2
|
-
import { getStoreLattice } from "@axiom-lattice/core";
|
|
3
|
-
import type { TaskStore, TaskItem, CreateTaskRequest, UpdateTaskRequest, TaskWorkItemStore } from "@axiom-lattice/protocols";
|
|
4
|
-
|
|
5
|
-
function getTenantId(request: FastifyRequest): string {
|
|
6
|
-
const userTenantId = (request as any).user?.tenantId;
|
|
7
|
-
if (userTenantId) return userTenantId;
|
|
8
|
-
return (request.headers["x-tenant-id"] as string) || "default";
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function getUserId(request: FastifyRequest): string {
|
|
12
|
-
const userId = (request as any).user?.id
|
|
13
|
-
|| (request.headers["x-user-id"] as string);
|
|
14
|
-
if (!userId) throw new Error("User ID is required");
|
|
15
|
-
return userId;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function getStore(): TaskStore {
|
|
19
|
-
return getStoreLattice("default", "task").store as TaskStore;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export async function listTasks(
|
|
23
|
-
request: FastifyRequest,
|
|
24
|
-
reply: FastifyReply
|
|
25
|
-
): Promise<{ success: boolean; data?: TaskItem[]; count?: number; error?: string }> {
|
|
26
|
-
try {
|
|
27
|
-
const tenantId = getTenantId(request);
|
|
28
|
-
const query = request.query as Record<string, string>;
|
|
29
|
-
|
|
30
|
-
const store = getStore();
|
|
31
|
-
const tasks = await store.list({
|
|
32
|
-
tenantId,
|
|
33
|
-
status: query.status,
|
|
34
|
-
priority: query.priority,
|
|
35
|
-
...(query.ownerId && { ownerId: query.ownerId }),
|
|
36
|
-
...(query.ownerType && { ownerType: query.ownerType as 'user' | 'agent' }),
|
|
37
|
-
metadata: query.metadata ? JSON.parse(query.metadata) : undefined,
|
|
38
|
-
projectId: query.projectId,
|
|
39
|
-
limit: query.limit ? parseInt(query.limit) : undefined,
|
|
40
|
-
offset: query.offset ? parseInt(query.offset) : undefined,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
return { success: true, data: tasks, count: tasks.length };
|
|
44
|
-
} catch (error: any) {
|
|
45
|
-
return { success: false, error: error.message };
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export async function getTask(
|
|
50
|
-
request: FastifyRequest<{ Params: { id: string } }>,
|
|
51
|
-
reply: FastifyReply
|
|
52
|
-
): Promise<{ success: boolean; data?: TaskItem; error?: string }> {
|
|
53
|
-
try {
|
|
54
|
-
const tenantId = getTenantId(request);
|
|
55
|
-
const userId = getUserId(request);
|
|
56
|
-
const { id } = request.params;
|
|
57
|
-
|
|
58
|
-
const store = getStore();
|
|
59
|
-
const task = await store.getById(tenantId, id);
|
|
60
|
-
if (!task) {
|
|
61
|
-
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (task.ownerType === 'user' && task.ownerId !== userId) {
|
|
65
|
-
return reply.status(403).send({ success: false, error: "Access denied" });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return { success: true, data: task };
|
|
69
|
-
} catch (error: any) {
|
|
70
|
-
return { success: false, error: error.message };
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export async function createTask(
|
|
75
|
-
request: FastifyRequest<{ Body: CreateTaskRequest }>,
|
|
76
|
-
reply: FastifyReply
|
|
77
|
-
): Promise<{ success: boolean; data?: TaskItem; error?: string }> {
|
|
78
|
-
try {
|
|
79
|
-
const tenantId = getTenantId(request);
|
|
80
|
-
const userId = getUserId(request);
|
|
81
|
-
const body = request.body;
|
|
82
|
-
|
|
83
|
-
if (!body.title) {
|
|
84
|
-
return reply.status(400).send({ success: false, error: "title is required" });
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const store = getStore();
|
|
88
|
-
const task = await store.create({
|
|
89
|
-
...body,
|
|
90
|
-
tenantId,
|
|
91
|
-
ownerType: (body.ownerType || "user") as 'user' | 'agent',
|
|
92
|
-
ownerId: body.ownerId || userId,
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
return reply.status(201).send({ success: true, data: task });
|
|
96
|
-
} catch (error: any) {
|
|
97
|
-
return reply.status(500).send({ success: false, error: error.message });
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export async function updateTask(
|
|
102
|
-
request: FastifyRequest<{ Params: { id: string }; Body: UpdateTaskRequest }>,
|
|
103
|
-
reply: FastifyReply
|
|
104
|
-
): Promise<{ success: boolean; data?: TaskItem; error?: string }> {
|
|
105
|
-
try {
|
|
106
|
-
const tenantId = getTenantId(request);
|
|
107
|
-
const userId = getUserId(request);
|
|
108
|
-
const { id } = request.params;
|
|
109
|
-
|
|
110
|
-
const store = getStore();
|
|
111
|
-
const existing = await store.getById(tenantId, id);
|
|
112
|
-
if (!existing) {
|
|
113
|
-
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (existing.ownerType === 'user' && existing.ownerId !== userId) {
|
|
117
|
-
return reply.status(403).send({ success: false, error: "Access denied" });
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const task = await store.update(tenantId, id, request.body);
|
|
121
|
-
if (!task) {
|
|
122
|
-
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
123
|
-
}
|
|
124
|
-
return { success: true, data: task };
|
|
125
|
-
} catch (error: any) {
|
|
126
|
-
return reply.status(500).send({ success: false, error: error.message });
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export async function deleteTask(
|
|
131
|
-
request: FastifyRequest<{ Params: { id: string } }>,
|
|
132
|
-
reply: FastifyReply
|
|
133
|
-
): Promise<{ success: boolean; message?: string; error?: string }> {
|
|
134
|
-
try {
|
|
135
|
-
const tenantId = getTenantId(request);
|
|
136
|
-
const userId = getUserId(request);
|
|
137
|
-
const { id } = request.params;
|
|
138
|
-
|
|
139
|
-
const store = getStore();
|
|
140
|
-
const existing = await store.getById(tenantId, id);
|
|
141
|
-
if (!existing) {
|
|
142
|
-
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (existing.ownerType === 'user' && existing.ownerId !== userId) {
|
|
146
|
-
return reply.status(403).send({ success: false, error: "Access denied" });
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const deleted = await store.delete(tenantId, id);
|
|
150
|
-
if (!deleted) {
|
|
151
|
-
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return { success: true, message: "Task deleted" };
|
|
155
|
-
} catch (error: any) {
|
|
156
|
-
return reply.status(500).send({ success: false, error: error.message });
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export async function completeTask(
|
|
161
|
-
request: FastifyRequest<{ Params: { id: string } }>,
|
|
162
|
-
reply: FastifyReply
|
|
163
|
-
): Promise<{ success: boolean; data?: TaskItem; error?: string }> {
|
|
164
|
-
try {
|
|
165
|
-
const tenantId = getTenantId(request);
|
|
166
|
-
const userId = getUserId(request);
|
|
167
|
-
const { id } = request.params;
|
|
168
|
-
|
|
169
|
-
const store = getStore();
|
|
170
|
-
const existing = await store.getById(tenantId, id);
|
|
171
|
-
if (!existing) {
|
|
172
|
-
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (existing.ownerType === 'user' && existing.ownerId !== userId) {
|
|
176
|
-
return reply.status(403).send({ success: false, error: "Access denied" });
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const task = await store.update(tenantId, id, { status: "completed" });
|
|
180
|
-
if (!task) {
|
|
181
|
-
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
182
|
-
}
|
|
183
|
-
return { success: true, data: task };
|
|
184
|
-
} catch (error: any) {
|
|
185
|
-
return reply.status(500).send({ success: false, error: error.message });
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function getTaskWorkItemStore(): TaskWorkItemStore {
|
|
190
|
-
return getStoreLattice("default", "taskWorkItem").store as TaskWorkItemStore;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export async function listTaskWorkItems(
|
|
194
|
-
request: FastifyRequest<{
|
|
195
|
-
Params: { id: string };
|
|
196
|
-
Querystring: { action?: string; limit?: number; offset?: number }
|
|
197
|
-
}>,
|
|
198
|
-
reply: FastifyReply
|
|
199
|
-
) {
|
|
200
|
-
const tenantId = getTenantId(request);
|
|
201
|
-
const { id } = request.params;
|
|
202
|
-
const { action, limit, offset } = request.query;
|
|
203
|
-
|
|
204
|
-
const store = getTaskWorkItemStore();
|
|
205
|
-
const items = await store.list({
|
|
206
|
-
tenantId,
|
|
207
|
-
taskId: id,
|
|
208
|
-
action,
|
|
209
|
-
limit: limit ? Number(limit) : undefined,
|
|
210
|
-
offset: offset ? Number(offset) : undefined
|
|
211
|
-
});
|
|
212
|
-
return reply.send({ success: true, data: items });
|
|
213
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TenantsController
|
|
3
|
-
*
|
|
4
|
-
* Controller for tenant management
|
|
5
|
-
* Handles CRUD operations for tenants (top-level entities)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
|
9
|
-
import { getStoreLattice } from "@axiom-lattice/core";
|
|
10
|
-
import type {
|
|
11
|
-
CreateTenantRequest,
|
|
12
|
-
UpdateTenantRequest,
|
|
13
|
-
} from "@axiom-lattice/protocols";
|
|
14
|
-
import { v4 as uuidv4 } from "uuid";
|
|
15
|
-
|
|
16
|
-
interface TenantParams {
|
|
17
|
-
tenantId: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export class TenantsController {
|
|
21
|
-
private tenantStore;
|
|
22
|
-
|
|
23
|
-
constructor() {
|
|
24
|
-
this.tenantStore = getStoreLattice("default", "tenant").store;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// ==================== Tenant CRUD ====================
|
|
28
|
-
|
|
29
|
-
async listTenants(request: FastifyRequest, reply: FastifyReply) {
|
|
30
|
-
const tenants = await this.tenantStore.getAllTenants();
|
|
31
|
-
return { success: true, data: tenants };
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async createTenant(
|
|
35
|
-
request: FastifyRequest<{ Body: CreateTenantRequest }>,
|
|
36
|
-
reply: FastifyReply
|
|
37
|
-
) {
|
|
38
|
-
const data = request.body;
|
|
39
|
-
const id = uuidv4();
|
|
40
|
-
|
|
41
|
-
const tenant = await this.tenantStore.createTenant(id, data);
|
|
42
|
-
return reply.status(201).send({ success: true, data: tenant });
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async getTenant(
|
|
46
|
-
request: FastifyRequest<{ Params: TenantParams }>,
|
|
47
|
-
reply: FastifyReply
|
|
48
|
-
) {
|
|
49
|
-
const { tenantId } = request.params;
|
|
50
|
-
|
|
51
|
-
const tenant = await this.tenantStore.getTenantById(tenantId);
|
|
52
|
-
|
|
53
|
-
if (!tenant) {
|
|
54
|
-
return reply.status(404).send({
|
|
55
|
-
success: false,
|
|
56
|
-
error: "Tenant not found",
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return { success: true, data: tenant };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async updateTenant(
|
|
64
|
-
request: FastifyRequest<{
|
|
65
|
-
Params: TenantParams;
|
|
66
|
-
Body: UpdateTenantRequest;
|
|
67
|
-
}>,
|
|
68
|
-
reply: FastifyReply
|
|
69
|
-
) {
|
|
70
|
-
const { tenantId } = request.params;
|
|
71
|
-
const updates = request.body;
|
|
72
|
-
|
|
73
|
-
const tenant = await this.tenantStore.updateTenant(tenantId, updates);
|
|
74
|
-
|
|
75
|
-
if (!tenant) {
|
|
76
|
-
return reply.status(404).send({
|
|
77
|
-
success: false,
|
|
78
|
-
error: "Tenant not found",
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return { success: true, data: tenant };
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async deleteTenant(
|
|
86
|
-
request: FastifyRequest<{ Params: TenantParams }>,
|
|
87
|
-
reply: FastifyReply
|
|
88
|
-
) {
|
|
89
|
-
const { tenantId } = request.params;
|
|
90
|
-
|
|
91
|
-
// Prevent deletion of the default tenant
|
|
92
|
-
if (tenantId === "default") {
|
|
93
|
-
return reply.status(403).send({
|
|
94
|
-
success: false,
|
|
95
|
-
error: "Cannot delete the default tenant",
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const deleted = await this.tenantStore.deleteTenant(tenantId);
|
|
100
|
-
|
|
101
|
-
if (!deleted) {
|
|
102
|
-
return reply.status(404).send({
|
|
103
|
-
success: false,
|
|
104
|
-
error: "Tenant not found",
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return { success: true };
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function registerTenantRoutes(app: FastifyInstance) {
|
|
113
|
-
const controller = new TenantsController();
|
|
114
|
-
|
|
115
|
-
// Tenant routes
|
|
116
|
-
app.get("/api/tenants", controller.listTenants.bind(controller));
|
|
117
|
-
app.post("/api/tenants", controller.createTenant.bind(controller));
|
|
118
|
-
app.get("/api/tenants/:tenantId", controller.getTenant.bind(controller));
|
|
119
|
-
app.patch("/api/tenants/:tenantId", controller.updateTenant.bind(controller));
|
|
120
|
-
app.delete("/api/tenants/:tenantId", controller.deleteTenant.bind(controller));
|
|
121
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { FastifyRequest, FastifyReply } from "fastify";
|
|
2
|
-
import { agentInstanceManager } from "@axiom-lattice/core";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* DELETE /api/assistants/:assistant_id/threads/:thread_id/pending-messages/:message_id
|
|
6
|
-
* Remove pending message from queue
|
|
7
|
-
*/
|
|
8
|
-
export async function removePendingMessageHandler(
|
|
9
|
-
request: FastifyRequest,
|
|
10
|
-
reply: FastifyReply
|
|
11
|
-
) {
|
|
12
|
-
try {
|
|
13
|
-
const { assistant_id, thread_id, message_id } = request.params as {
|
|
14
|
-
assistant_id: string;
|
|
15
|
-
thread_id: string;
|
|
16
|
-
message_id: string;
|
|
17
|
-
};
|
|
18
|
-
const tenant_id = request.headers["x-tenant-id"] as string;
|
|
19
|
-
const workspace_id = request.headers["x-workspace-id"] as string;
|
|
20
|
-
const project_id = request.headers["x-project-id"] as string;
|
|
21
|
-
|
|
22
|
-
if (!tenant_id) {
|
|
23
|
-
return reply.code(400).send({ error: "Missing x-tenant-id header" });
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (!assistant_id) {
|
|
27
|
-
return reply.code(400).send({ error: "Missing assistant_id parameter" });
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Get agent instance
|
|
31
|
-
const agent = agentInstanceManager.getAgent({
|
|
32
|
-
assistant_id,
|
|
33
|
-
thread_id,
|
|
34
|
-
tenant_id,
|
|
35
|
-
workspace_id,
|
|
36
|
-
project_id,
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
if (!agent) {
|
|
40
|
-
return reply.code(404).send({
|
|
41
|
-
error: "Thread not found",
|
|
42
|
-
threadId: thread_id,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const success = await agent.removePendingMessage(message_id);
|
|
47
|
-
|
|
48
|
-
if (!success) {
|
|
49
|
-
return reply.code(404).send({
|
|
50
|
-
error: "Message not found",
|
|
51
|
-
messageId: message_id,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return reply.send({
|
|
56
|
-
success: true,
|
|
57
|
-
messageId: message_id,
|
|
58
|
-
});
|
|
59
|
-
} catch (error) {
|
|
60
|
-
console.error("Error removing pending message:", error);
|
|
61
|
-
return reply.code(500).send({
|
|
62
|
-
error: "Internal server error",
|
|
63
|
-
message: error instanceof Error ? error.message : String(error),
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
import { FastifyRequest, FastifyReply } from "fastify";
|
|
2
|
-
import { getStoreLattice } from "@axiom-lattice/core";
|
|
3
|
-
import { Thread, CreateThreadRequest } from "../types";
|
|
4
|
-
import { randomUUID } from "crypto";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Thread Controller
|
|
8
|
-
* Handles thread-related CRUD operations for a specific assistant
|
|
9
|
-
* All operations are scoped to a tenant ID and assistant ID
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Get tenant ID from authenticated user context
|
|
14
|
-
* Falls back to request headers for backward compatibility
|
|
15
|
-
*/
|
|
16
|
-
function getTenantId(request: FastifyRequest): string {
|
|
17
|
-
// First try to get from authenticated user context
|
|
18
|
-
const userTenantId = (request as any).user?.tenantId;
|
|
19
|
-
if (userTenantId) {
|
|
20
|
-
return userTenantId;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Fallback to request headers for backward compatibility
|
|
24
|
-
return (request.headers["x-tenant-id"] as string) || "default";
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Thread list response interface
|
|
29
|
-
*/
|
|
30
|
-
interface ThreadListResponse {
|
|
31
|
-
success: boolean;
|
|
32
|
-
message: string;
|
|
33
|
-
data: {
|
|
34
|
-
records: Thread[];
|
|
35
|
-
total: number;
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Thread response interface
|
|
41
|
-
*/
|
|
42
|
-
interface ThreadResponse {
|
|
43
|
-
success: boolean;
|
|
44
|
-
message: string;
|
|
45
|
-
data?: Thread;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Thread update request body interface
|
|
50
|
-
*/
|
|
51
|
-
interface ThreadUpdateBody {
|
|
52
|
-
metadata?: Record<string, any>;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Get list of all threads for a specific assistant
|
|
57
|
-
*/
|
|
58
|
-
export async function getThreadList(
|
|
59
|
-
request: FastifyRequest<{
|
|
60
|
-
Params: { assistantId: string };
|
|
61
|
-
}>,
|
|
62
|
-
reply: FastifyReply
|
|
63
|
-
): Promise<ThreadListResponse> {
|
|
64
|
-
const tenantId = getTenantId(request);
|
|
65
|
-
const { assistantId } = request.params;
|
|
66
|
-
|
|
67
|
-
// Build metadata filter from headers (workspace/project isolation)
|
|
68
|
-
const metadataFilter: Record<string, string> = {};
|
|
69
|
-
const workspaceId = request.headers["x-workspace-id"] as string | undefined;
|
|
70
|
-
const projectId = request.headers["x-project-id"] as string | undefined;
|
|
71
|
-
|
|
72
|
-
if (workspaceId) {
|
|
73
|
-
metadataFilter.workspaceId = workspaceId;
|
|
74
|
-
}
|
|
75
|
-
if (projectId) {
|
|
76
|
-
metadataFilter.projectId = projectId;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const storeLattice = getStoreLattice("default", "thread");
|
|
80
|
-
const threadStore = storeLattice.store;
|
|
81
|
-
const threads = await threadStore.getThreadsByAssistantId(
|
|
82
|
-
tenantId,
|
|
83
|
-
assistantId,
|
|
84
|
-
Object.keys(metadataFilter).length > 0 ? metadataFilter : undefined
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
success: true,
|
|
89
|
-
message: "Successfully retrieved thread list",
|
|
90
|
-
data: {
|
|
91
|
-
records: threads,
|
|
92
|
-
total: threads.length,
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Get a single thread by ID for a specific tenant
|
|
99
|
-
*/
|
|
100
|
-
export async function getThread(
|
|
101
|
-
request: FastifyRequest<{
|
|
102
|
-
Params: { assistantId: string; threadId: string };
|
|
103
|
-
}>,
|
|
104
|
-
reply: FastifyReply
|
|
105
|
-
): Promise<ThreadResponse> {
|
|
106
|
-
const tenantId = getTenantId(request);
|
|
107
|
-
const { threadId } = request.params;
|
|
108
|
-
|
|
109
|
-
const storeLattice = getStoreLattice("default", "thread");
|
|
110
|
-
const threadStore = storeLattice.store;
|
|
111
|
-
const thread = await threadStore.getThreadById(tenantId, threadId);
|
|
112
|
-
|
|
113
|
-
if (!thread) {
|
|
114
|
-
return reply.status(404).send({
|
|
115
|
-
success: false,
|
|
116
|
-
message: "Thread not found",
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
success: true,
|
|
122
|
-
message: "Successfully retrieved thread",
|
|
123
|
-
data: thread,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Create a new thread for an assistant
|
|
129
|
-
*/
|
|
130
|
-
export async function createThread(
|
|
131
|
-
request: FastifyRequest<{
|
|
132
|
-
Params: { assistantId: string };
|
|
133
|
-
Body: CreateThreadRequest;
|
|
134
|
-
}>,
|
|
135
|
-
reply: FastifyReply
|
|
136
|
-
): Promise<ThreadResponse> {
|
|
137
|
-
const tenantId = getTenantId(request);
|
|
138
|
-
const { assistantId } = request.params;
|
|
139
|
-
const data = request.body;
|
|
140
|
-
|
|
141
|
-
// Generate thread ID if not provided
|
|
142
|
-
const threadId = randomUUID();
|
|
143
|
-
|
|
144
|
-
// Extract workspace and project from headers
|
|
145
|
-
const workspaceId = request.headers["x-workspace-id"] as string | undefined;
|
|
146
|
-
const projectId = request.headers["x-project-id"] as string | undefined;
|
|
147
|
-
|
|
148
|
-
// Enrich metadata with tenant/workspace/project
|
|
149
|
-
const enrichedMetadata: Record<string, any> = {
|
|
150
|
-
...data.metadata,
|
|
151
|
-
tenantId,
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
if (workspaceId) {
|
|
155
|
-
enrichedMetadata.workspaceId = workspaceId;
|
|
156
|
-
}
|
|
157
|
-
if (projectId) {
|
|
158
|
-
enrichedMetadata.projectId = projectId;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Create thread with enriched metadata
|
|
162
|
-
const storeLattice = getStoreLattice("default", "thread");
|
|
163
|
-
const threadStore = storeLattice.store;
|
|
164
|
-
const newThread = await threadStore.createThread(tenantId, assistantId, threadId, {
|
|
165
|
-
metadata: enrichedMetadata,
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
return reply.status(201).send({
|
|
169
|
-
success: true,
|
|
170
|
-
message: "Successfully created thread",
|
|
171
|
-
data: newThread,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Update an existing thread by ID
|
|
177
|
-
*/
|
|
178
|
-
export async function updateThread(
|
|
179
|
-
request: FastifyRequest<{
|
|
180
|
-
Params: { assistantId: string; threadId: string };
|
|
181
|
-
Body: ThreadUpdateBody;
|
|
182
|
-
}>,
|
|
183
|
-
reply: FastifyReply
|
|
184
|
-
): Promise<ThreadResponse> {
|
|
185
|
-
const tenantId = getTenantId(request);
|
|
186
|
-
const { threadId } = request.params;
|
|
187
|
-
const updates = request.body;
|
|
188
|
-
|
|
189
|
-
const storeLattice = getStoreLattice("default", "thread");
|
|
190
|
-
const threadStore = storeLattice.store;
|
|
191
|
-
|
|
192
|
-
// Check if thread exists
|
|
193
|
-
const exists = await threadStore.hasThread(tenantId, threadId);
|
|
194
|
-
if (!exists) {
|
|
195
|
-
return reply.status(404).send({
|
|
196
|
-
success: false,
|
|
197
|
-
message: "Thread not found",
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Update thread
|
|
202
|
-
const updatedThread = await threadStore.updateThread(
|
|
203
|
-
tenantId,
|
|
204
|
-
threadId,
|
|
205
|
-
updates
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
if (!updatedThread) {
|
|
209
|
-
return reply.status(500).send({
|
|
210
|
-
success: false,
|
|
211
|
-
message: "Failed to update thread",
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return {
|
|
216
|
-
success: true,
|
|
217
|
-
message: "Successfully updated thread",
|
|
218
|
-
data: updatedThread,
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Delete a thread by ID
|
|
224
|
-
*/
|
|
225
|
-
export async function deleteThread(
|
|
226
|
-
request: FastifyRequest<{
|
|
227
|
-
Params: { assistantId: string; threadId: string };
|
|
228
|
-
}>,
|
|
229
|
-
reply: FastifyReply
|
|
230
|
-
): Promise<{ success: boolean; message: string }> {
|
|
231
|
-
const tenantId = getTenantId(request);
|
|
232
|
-
const { threadId } = request.params;
|
|
233
|
-
|
|
234
|
-
const storeLattice = getStoreLattice("default", "thread");
|
|
235
|
-
const threadStore = storeLattice.store;
|
|
236
|
-
|
|
237
|
-
// Check if thread exists
|
|
238
|
-
const exists = await threadStore.hasThread(tenantId, threadId);
|
|
239
|
-
if (!exists) {
|
|
240
|
-
return reply.status(404).send({
|
|
241
|
-
success: false,
|
|
242
|
-
message: "Thread not found",
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Delete the thread
|
|
247
|
-
const deleted = await threadStore.deleteThread(tenantId, threadId);
|
|
248
|
-
|
|
249
|
-
if (!deleted) {
|
|
250
|
-
return reply.status(500).send({
|
|
251
|
-
success: false,
|
|
252
|
-
message: "Failed to delete thread",
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return {
|
|
257
|
-
success: true,
|
|
258
|
-
message: "Successfully deleted thread",
|
|
259
|
-
};
|
|
260
|
-
}
|