@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
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { FastifyInstance } from "fastify";
|
|
2
|
-
import { PluginRegistry } from "@axiom-lattice/core";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* GET /api/middleware-types
|
|
6
|
-
*
|
|
7
|
-
* Returns all registered plugin metas (builtin + custom).
|
|
8
|
-
* hasTest / hasDiscover are auto-detected by serializePluginMeta.
|
|
9
|
-
*/
|
|
10
|
-
export function middlewareTypesRoutes(fastify: FastifyInstance): void {
|
|
11
|
-
fastify.get("/api/middleware-types", async (_request, reply) => {
|
|
12
|
-
const metas = PluginRegistry.listMeta();
|
|
13
|
-
return reply.send(metas);
|
|
14
|
-
});
|
|
15
|
-
}
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { FastifyRequest, FastifyReply } from "fastify";
|
|
2
|
-
import { registerModelLattice, modelLatticeManager } from "@axiom-lattice/core";
|
|
3
|
-
import type { LLMConfig } from "@axiom-lattice/protocols";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Models Controller
|
|
7
|
-
* Handles model lattice registration and management
|
|
8
|
-
* Models are tenant-isolated using key prefix: {tenantId}:{modelKey}
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Get tenant ID from request headers or user context
|
|
13
|
-
*/
|
|
14
|
-
function getTenantId(request: FastifyRequest): string {
|
|
15
|
-
// First try to get from authenticated user context
|
|
16
|
-
const userTenantId = (request as any).user?.tenantId;
|
|
17
|
-
if (userTenantId) {
|
|
18
|
-
return userTenantId;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Fallback to request headers for backward compatibility
|
|
22
|
-
return (request.headers["x-tenant-id"] as string) || "default";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Get tenant-scoped model key
|
|
27
|
-
*/
|
|
28
|
-
function getTenantModelKey(tenantId: string, modelKey: string): string {
|
|
29
|
-
return `${tenantId}:${modelKey}`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Extract model key from tenant-scoped key
|
|
34
|
-
*/
|
|
35
|
-
function extractModelKey(tenantId: string, tenantModelKey: string): string {
|
|
36
|
-
const prefix = `${tenantId}:`;
|
|
37
|
-
if (tenantModelKey.startsWith(prefix)) {
|
|
38
|
-
return tenantModelKey.substring(prefix.length);
|
|
39
|
-
}
|
|
40
|
-
return tenantModelKey;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
interface ModelConfig {
|
|
44
|
-
key: string;
|
|
45
|
-
model: string;
|
|
46
|
-
displayName?: string;
|
|
47
|
-
provider: "azure" | "openai" | "deepseek" | "siliconcloud" | "volcengine";
|
|
48
|
-
streaming?: boolean;
|
|
49
|
-
apiKey?: string;
|
|
50
|
-
baseURL?: string;
|
|
51
|
-
maxTokens?: number;
|
|
52
|
-
temperature?: number;
|
|
53
|
-
timeout?: number;
|
|
54
|
-
maxRetries?: number;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
interface UpdateModelsRequest {
|
|
58
|
-
Body: {
|
|
59
|
-
models: ModelConfig[];
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
interface UpdateModelsRequest {
|
|
64
|
-
Body: {
|
|
65
|
-
models: ModelConfig[];
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Get all registered models
|
|
71
|
-
*/
|
|
72
|
-
export async function getModels(request: FastifyRequest, reply: FastifyReply) {
|
|
73
|
-
try {
|
|
74
|
-
const allLattices = modelLatticeManager.getAllLattices();
|
|
75
|
-
const models = allLattices.map((lattice) => {
|
|
76
|
-
// Extract config from the lattice client
|
|
77
|
-
// Note: This is a simplified approach - you may need to adjust based on actual implementation
|
|
78
|
-
const config = (lattice.client as any).config || {};
|
|
79
|
-
// Use provided displayName or auto-generate from key
|
|
80
|
-
const displayName = config.displayName || lattice.key
|
|
81
|
-
.split('-')
|
|
82
|
-
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
83
|
-
.join(' ');
|
|
84
|
-
return {
|
|
85
|
-
key: lattice.key,
|
|
86
|
-
model: config.model || "",
|
|
87
|
-
provider: config.provider || "openai",
|
|
88
|
-
displayName: displayName,
|
|
89
|
-
streaming: config.streaming || false,
|
|
90
|
-
apiKey: config.apiKey || "",
|
|
91
|
-
baseURL: config.baseURL || "",
|
|
92
|
-
maxTokens: config.maxTokens,
|
|
93
|
-
temperature: config.temperature,
|
|
94
|
-
timeout: config.timeout,
|
|
95
|
-
maxRetries: config.maxRetries,
|
|
96
|
-
};
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
return reply.send({
|
|
100
|
-
success: true,
|
|
101
|
-
data: models,
|
|
102
|
-
});
|
|
103
|
-
} catch (error: any) {
|
|
104
|
-
console.error("Failed to get models", {
|
|
105
|
-
error: error.message,
|
|
106
|
-
stack: error.stack,
|
|
107
|
-
});
|
|
108
|
-
return reply.status(500).send({
|
|
109
|
-
success: false,
|
|
110
|
-
error: error.message || "Failed to get models",
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Update models configuration
|
|
117
|
-
* Registers or updates model lattices
|
|
118
|
-
*/
|
|
119
|
-
export async function updateModels(
|
|
120
|
-
request: FastifyRequest<UpdateModelsRequest>,
|
|
121
|
-
reply: FastifyReply
|
|
122
|
-
) {
|
|
123
|
-
try {
|
|
124
|
-
const { models } = request.body;
|
|
125
|
-
|
|
126
|
-
if (!models || !Array.isArray(models)) {
|
|
127
|
-
return reply.status(400).send({
|
|
128
|
-
success: false,
|
|
129
|
-
error: "Invalid request: models must be an array",
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const registeredModels: string[] = [];
|
|
134
|
-
const errors: string[] = [];
|
|
135
|
-
|
|
136
|
-
for (const modelConfig of models) {
|
|
137
|
-
if (!modelConfig.key || !modelConfig.model || !modelConfig.provider) {
|
|
138
|
-
errors.push(
|
|
139
|
-
`Model configuration is incomplete: key, model, and provider are required`
|
|
140
|
-
);
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
// Remove existing model with the same key if it exists
|
|
146
|
-
if (modelLatticeManager.hasLattice(modelConfig.key)) {
|
|
147
|
-
modelLatticeManager.removeLattice(modelConfig.key);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Convert to LLMConfig format
|
|
151
|
-
const llmConfig: LLMConfig = {
|
|
152
|
-
provider: modelConfig.provider,
|
|
153
|
-
model: modelConfig.model,
|
|
154
|
-
displayName: modelConfig.displayName,
|
|
155
|
-
streaming: modelConfig.streaming ?? false,
|
|
156
|
-
apiKey: modelConfig.apiKey,
|
|
157
|
-
baseURL: modelConfig.baseURL,
|
|
158
|
-
maxTokens: modelConfig.maxTokens,
|
|
159
|
-
temperature: modelConfig.temperature,
|
|
160
|
-
timeout: modelConfig.timeout,
|
|
161
|
-
maxRetries: modelConfig.maxRetries,
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
// Register the new model lattice
|
|
165
|
-
registerModelLattice(modelConfig.key, llmConfig);
|
|
166
|
-
registeredModels.push(modelConfig.key);
|
|
167
|
-
} catch (error: any) {
|
|
168
|
-
errors.push(
|
|
169
|
-
`Failed to register model ${modelConfig.key}: ${error.message}`
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (errors.length > 0 && registeredModels.length === 0) {
|
|
175
|
-
return reply.status(400).send({
|
|
176
|
-
success: false,
|
|
177
|
-
error: errors.join("; "),
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return reply.send({
|
|
182
|
-
success: true,
|
|
183
|
-
message: `Successfully registered ${registeredModels.length} model(s)`,
|
|
184
|
-
data: {
|
|
185
|
-
registered: registeredModels,
|
|
186
|
-
errors: errors.length > 0 ? errors : undefined,
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
} catch (error: any) {
|
|
190
|
-
console.error("Failed to update models", {
|
|
191
|
-
error: error.message,
|
|
192
|
-
stack: error.stack,
|
|
193
|
-
});
|
|
194
|
-
return reply.status(500).send({
|
|
195
|
-
success: false,
|
|
196
|
-
error: error.message || "Failed to update models",
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { FastifyRequest, FastifyReply } from "fastify";
|
|
2
|
-
import { getStoreLattice, PersonalAssistantConfig } from "@axiom-lattice/core";
|
|
3
|
-
import type { Assistant, CreateAssistantRequest } from "@axiom-lattice/protocols";
|
|
4
|
-
import { randomUUID } from "crypto";
|
|
5
|
-
function getWorkspaceId(request: FastifyRequest): string {
|
|
6
|
-
return (request.headers["x-workspace-id"] as string) || "default";
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function getTenantId(request: FastifyRequest): string {
|
|
10
|
-
const userTenantId = (request as any).user?.tenantId;
|
|
11
|
-
if (userTenantId) return userTenantId;
|
|
12
|
-
return (request.headers["x-tenant-id"] as string) || "default";
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function getUserId(request: FastifyRequest): string {
|
|
16
|
-
const userId = (request as any).user?.id
|
|
17
|
-
|| (request.headers["x-user-id"] as string);
|
|
18
|
-
if (!userId) throw new Error("User ID is required");
|
|
19
|
-
return userId;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface CreatePersonalAssistantBody {
|
|
23
|
-
name: string;
|
|
24
|
-
personality: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface PersonalAssistantStatus {
|
|
28
|
-
id: string;
|
|
29
|
-
name: string;
|
|
30
|
-
projectId: string;
|
|
31
|
-
workspaceId?: string;
|
|
32
|
-
createdAt: Date;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface PersonalAssistantResponse {
|
|
36
|
-
success: boolean;
|
|
37
|
-
message: string;
|
|
38
|
-
data?: PersonalAssistantStatus;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function getLinkStore() {
|
|
42
|
-
return getStoreLattice("default", "userTenantLink").store;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function getAssistantStore() {
|
|
46
|
-
return getStoreLattice("default", "assistant").store;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function getProjectStore() {
|
|
50
|
-
return getStoreLattice("default", "project").store;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function getLinkMeta(userId: string, tenantId: string) {
|
|
54
|
-
const link = await getLinkStore().getLink(userId, tenantId);
|
|
55
|
-
return (link?.metadata || {}) as Record<string, unknown>;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async function updateLinkMeta(userId: string, tenantId: string, meta: Record<string, unknown>) {
|
|
59
|
-
await getLinkStore().updateLink(userId, tenantId, { metadata: meta } as any);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Create a personal assistant for the authenticated user.
|
|
64
|
-
* Random IDs for both assistant and project, stored in UserTenantLink.metadata.
|
|
65
|
-
*/
|
|
66
|
-
export async function createPersonalAssistant(
|
|
67
|
-
request: FastifyRequest<{ Body: CreatePersonalAssistantBody }>,
|
|
68
|
-
reply: FastifyReply
|
|
69
|
-
): Promise<PersonalAssistantResponse> {
|
|
70
|
-
const tenantId = getTenantId(request);
|
|
71
|
-
const userId = getUserId(request);
|
|
72
|
-
const { name, personality } = request.body;
|
|
73
|
-
|
|
74
|
-
if (!name || !personality) {
|
|
75
|
-
return reply.status(400).send({ success: false, message: "name and personality are required" });
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const store = getAssistantStore();
|
|
79
|
-
|
|
80
|
-
const existing = await store.getByOwner(tenantId, userId);
|
|
81
|
-
if (existing) {
|
|
82
|
-
return reply.status(409).send({ success: false, message: "You already have a personal assistant" });
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const assistantId = randomUUID();
|
|
86
|
-
|
|
87
|
-
// Create a personal project under the current workspace
|
|
88
|
-
const projectStore = getProjectStore();
|
|
89
|
-
const projectId = randomUUID();
|
|
90
|
-
const wsId = getWorkspaceId(request);
|
|
91
|
-
await projectStore.createProject(tenantId, wsId, projectId, {
|
|
92
|
-
name: `${name}'s Space`,
|
|
93
|
-
description: "Personal workspace for your assistant",
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const config = PersonalAssistantConfig.get();
|
|
97
|
-
config.key = assistantId;
|
|
98
|
-
PersonalAssistantConfig.render(config, name, personality);
|
|
99
|
-
|
|
100
|
-
const data: CreateAssistantRequest = { name, graphDefinition: config, ownerUserId: userId };
|
|
101
|
-
const assistant = await store.createAssistant(tenantId, assistantId, data);
|
|
102
|
-
|
|
103
|
-
// Store in UserTenantLink.metadata
|
|
104
|
-
const meta = await getLinkMeta(userId, tenantId);
|
|
105
|
-
meta.personalAssistantId = assistantId;
|
|
106
|
-
meta.personalProjectId = projectId;
|
|
107
|
-
meta.personalWorkspaceId = wsId;
|
|
108
|
-
await updateLinkMeta(userId, tenantId, meta);
|
|
109
|
-
|
|
110
|
-
return reply.status(201).send({
|
|
111
|
-
success: true,
|
|
112
|
-
message: "Personal assistant created",
|
|
113
|
-
data: { id: assistant.id, name: assistant.name, projectId, workspaceId: wsId, createdAt: assistant.createdAt },
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Get the authenticated user's personal assistant.
|
|
119
|
-
*/
|
|
120
|
-
export async function getPersonalAssistant(
|
|
121
|
-
request: FastifyRequest,
|
|
122
|
-
reply: FastifyReply
|
|
123
|
-
): Promise<PersonalAssistantResponse> {
|
|
124
|
-
const tenantId = getTenantId(request);
|
|
125
|
-
const userId = getUserId(request);
|
|
126
|
-
|
|
127
|
-
const store = getAssistantStore();
|
|
128
|
-
const assistant = await store.getByOwner(tenantId, userId);
|
|
129
|
-
|
|
130
|
-
if (!assistant) {
|
|
131
|
-
return reply.status(404).send({ success: false, message: "No personal assistant found" });
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const meta = await getLinkMeta(userId, tenantId);
|
|
135
|
-
const projectId = (meta.personalProjectId as string) || "default";
|
|
136
|
-
const workspaceId = (meta.personalWorkspaceId as string) || "default";
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
success: true,
|
|
140
|
-
message: "Personal assistant found",
|
|
141
|
-
data: { id: assistant.id, name: assistant.name, projectId, workspaceId, createdAt: assistant.createdAt },
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Delete the authenticated user's personal assistant.
|
|
147
|
-
*/
|
|
148
|
-
export async function deletePersonalAssistant(
|
|
149
|
-
request: FastifyRequest,
|
|
150
|
-
reply: FastifyReply
|
|
151
|
-
): Promise<{ success: boolean; message: string }> {
|
|
152
|
-
const tenantId = getTenantId(request);
|
|
153
|
-
const userId = getUserId(request);
|
|
154
|
-
|
|
155
|
-
const store = getAssistantStore();
|
|
156
|
-
const assistant = await store.getByOwner(tenantId, userId);
|
|
157
|
-
|
|
158
|
-
if (!assistant) {
|
|
159
|
-
return reply.status(404).send({ success: false, message: "No personal assistant found" });
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const deleted = await store.deleteAssistant(tenantId, assistant.id);
|
|
163
|
-
if (!deleted) {
|
|
164
|
-
return reply.status(500).send({ success: false, message: "Failed to delete personal assistant" });
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Delete all threads
|
|
168
|
-
const threadStore = getStoreLattice("default", "thread").store;
|
|
169
|
-
try {
|
|
170
|
-
const threads = await threadStore.getThreadsByAssistantId(tenantId, assistant.id);
|
|
171
|
-
for (const t of threads) {
|
|
172
|
-
await threadStore.deleteThread(tenantId, t.id);
|
|
173
|
-
}
|
|
174
|
-
} catch { /* best effort */ }
|
|
175
|
-
|
|
176
|
-
// Clean up the project
|
|
177
|
-
const meta = await getLinkMeta(userId, tenantId);
|
|
178
|
-
const projectId = meta.personalProjectId as string;
|
|
179
|
-
const wsId = meta.personalWorkspaceId as string;
|
|
180
|
-
if (projectId && wsId) {
|
|
181
|
-
try { await getProjectStore().deleteProject(tenantId, projectId); } catch { /* best effort */ }
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Clean up UserTenantLink.metadata
|
|
185
|
-
delete meta.personalAssistantId;
|
|
186
|
-
delete meta.personalProjectId;
|
|
187
|
-
delete meta.personalWorkspaceId;
|
|
188
|
-
await updateLinkMeta(userId, tenantId, meta);
|
|
189
|
-
|
|
190
|
-
return { success: true, message: "Personal assistant deleted" };
|
|
191
|
-
}
|