@axiom-lattice/gateway 2.1.11 → 2.1.13

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.mjs CHANGED
@@ -223,6 +223,226 @@ async function resume_stream({
223
223
  };
224
224
  }
225
225
 
226
+ // src/stores/assistant_store.ts
227
+ var AssistantStore = class {
228
+ constructor() {
229
+ this.assistants = /* @__PURE__ */ new Map();
230
+ }
231
+ /**
232
+ * Get all assistants
233
+ */
234
+ getAllAssistants() {
235
+ return Array.from(this.assistants.values());
236
+ }
237
+ /**
238
+ * Get assistant by ID
239
+ */
240
+ getAssistantById(id) {
241
+ return this.assistants.get(id);
242
+ }
243
+ /**
244
+ * Create a new assistant
245
+ */
246
+ createAssistant(id, data) {
247
+ const now = /* @__PURE__ */ new Date();
248
+ const assistant = {
249
+ id,
250
+ name: data.name,
251
+ description: data.description,
252
+ graphDefinition: data.graphDefinition,
253
+ createdAt: now,
254
+ updatedAt: now
255
+ };
256
+ this.assistants.set(id, assistant);
257
+ return assistant;
258
+ }
259
+ /**
260
+ * Update an existing assistant
261
+ */
262
+ updateAssistant(id, updates) {
263
+ const existing = this.assistants.get(id);
264
+ if (!existing) {
265
+ return null;
266
+ }
267
+ const updated = {
268
+ ...existing,
269
+ ...updates,
270
+ updatedAt: /* @__PURE__ */ new Date()
271
+ };
272
+ this.assistants.set(id, updated);
273
+ return updated;
274
+ }
275
+ /**
276
+ * Delete an assistant by ID
277
+ */
278
+ deleteAssistant(id) {
279
+ return this.assistants.delete(id);
280
+ }
281
+ /**
282
+ * Check if assistant exists
283
+ */
284
+ hasAssistant(id) {
285
+ return this.assistants.has(id);
286
+ }
287
+ };
288
+ var assistantStore = new AssistantStore();
289
+
290
+ // src/controllers/assistant.ts
291
+ import { randomUUID } from "crypto";
292
+ import { getAllAgentConfigs } from "@axiom-lattice/core";
293
+ function convertAgentConfigToAssistant(config) {
294
+ return {
295
+ id: config.key,
296
+ name: config.name,
297
+ description: config.description,
298
+ graphDefinition: config,
299
+ // Store the full config as graphDefinition
300
+ createdAt: /* @__PURE__ */ new Date(0),
301
+ // Code-configured agents have no creation date
302
+ updatedAt: /* @__PURE__ */ new Date(0)
303
+ // Code-configured agents have no update date
304
+ };
305
+ }
306
+ async function getAssistantList(request, reply) {
307
+ const agentConfigs = await getAllAgentConfigs();
308
+ const codeConfiguredAssistants = agentConfigs.map(
309
+ convertAgentConfigToAssistant
310
+ );
311
+ const storedAssistants = assistantStore.getAllAssistants();
312
+ const assistantMap = /* @__PURE__ */ new Map();
313
+ codeConfiguredAssistants.forEach((assistant) => {
314
+ assistantMap.set(assistant.id, assistant);
315
+ });
316
+ storedAssistants.forEach((assistant) => {
317
+ assistantMap.set(assistant.id, assistant);
318
+ });
319
+ const allAssistants = Array.from(assistantMap.values());
320
+ return {
321
+ success: true,
322
+ message: "Successfully retrieved assistant list",
323
+ data: {
324
+ records: allAssistants,
325
+ total: allAssistants.length
326
+ }
327
+ };
328
+ }
329
+ async function getAssistant(request, reply) {
330
+ const { id } = request.params;
331
+ let assistant = assistantStore.getAssistantById(id);
332
+ if (!assistant) {
333
+ const agentConfigs = await getAllAgentConfigs();
334
+ const agentConfig = agentConfigs.find((config) => config.key === id);
335
+ if (agentConfig) {
336
+ assistant = convertAgentConfigToAssistant(agentConfig);
337
+ }
338
+ }
339
+ if (!assistant) {
340
+ return reply.status(404).send({
341
+ success: false,
342
+ message: "Assistant not found"
343
+ });
344
+ }
345
+ return {
346
+ success: true,
347
+ message: "Successfully retrieved assistant",
348
+ data: assistant
349
+ };
350
+ }
351
+ async function createAssistant(request, reply) {
352
+ const data = request.body;
353
+ if (!data.name) {
354
+ return reply.status(400).send({
355
+ success: false,
356
+ message: "name is required"
357
+ });
358
+ }
359
+ if (!data.graphDefinition) {
360
+ return reply.status(400).send({
361
+ success: false,
362
+ message: "graphDefinition is required"
363
+ });
364
+ }
365
+ const id = randomUUID();
366
+ const newAssistant = assistantStore.createAssistant(id, data);
367
+ return reply.status(201).send({
368
+ success: true,
369
+ message: "Successfully created assistant",
370
+ data: newAssistant
371
+ });
372
+ }
373
+ async function updateAssistant(request, reply) {
374
+ const { id } = request.params;
375
+ const updates = request.body;
376
+ const agentConfigs = await getAllAgentConfigs();
377
+ const isCodeConfigured = agentConfigs.some((config) => config.key === id);
378
+ if (isCodeConfigured) {
379
+ return reply.status(403).send({
380
+ success: false,
381
+ message: "Cannot update code-configured assistant. Only stored assistants can be updated."
382
+ });
383
+ }
384
+ if (!assistantStore.hasAssistant(id)) {
385
+ return reply.status(404).send({
386
+ success: false,
387
+ message: "Assistant not found"
388
+ });
389
+ }
390
+ const updatedAssistant = assistantStore.updateAssistant(id, updates);
391
+ if (!updatedAssistant) {
392
+ return reply.status(500).send({
393
+ success: false,
394
+ message: "Failed to update assistant"
395
+ });
396
+ }
397
+ return {
398
+ success: true,
399
+ message: "Successfully updated assistant",
400
+ data: updatedAssistant
401
+ };
402
+ }
403
+ async function deleteAssistant(request, reply) {
404
+ const { id } = request.params;
405
+ const agentConfigs = await getAllAgentConfigs();
406
+ const isCodeConfigured = agentConfigs.some((config) => config.key === id);
407
+ if (isCodeConfigured) {
408
+ return reply.status(403).send({
409
+ success: false,
410
+ message: "Cannot delete code-configured assistant. Only stored assistants can be deleted."
411
+ });
412
+ }
413
+ if (!assistantStore.hasAssistant(id)) {
414
+ return reply.status(404).send({
415
+ success: false,
416
+ message: "Assistant not found"
417
+ });
418
+ }
419
+ const deleted = assistantStore.deleteAssistant(id);
420
+ if (!deleted) {
421
+ return reply.status(500).send({
422
+ success: false,
423
+ message: "Failed to delete assistant"
424
+ });
425
+ }
426
+ return {
427
+ success: true,
428
+ message: "Successfully deleted assistant"
429
+ };
430
+ }
431
+ var getAgentGraph = async (request, reply) => {
432
+ try {
433
+ const { assistantId } = request.params;
434
+ const imageData = await draw_graph(assistantId);
435
+ reply.header("Content-Type", "application/json").send({
436
+ image: imageData
437
+ });
438
+ } catch (error) {
439
+ reply.status(500).send({
440
+ success: false,
441
+ error: error.message || "Failed to get agent graph"
442
+ });
443
+ }
444
+ };
445
+
226
446
  // src/controllers/run.ts
227
447
  import { v4 as v42 } from "uuid";
228
448
  var createRun = async (request, reply) => {
@@ -490,22 +710,6 @@ var clearMemory = async (request, reply) => {
490
710
  }
491
711
  };
492
712
 
493
- // src/controllers/assistant.ts
494
- var getAgentGraph = async (request, reply) => {
495
- try {
496
- const { assistantId } = request.params;
497
- const imageData = await draw_graph(assistantId);
498
- reply.header("Content-Type", "application/json").send({
499
- image: imageData
500
- });
501
- } catch (error) {
502
- reply.status(500).send({
503
- success: false,
504
- error: error.message || "\u83B7\u53D6\u4EE3\u7406\u56FE\u8868\u5931\u8D25"
505
- });
506
- }
507
- };
508
-
509
713
  // src/controllers/agent_task.ts
510
714
  import { AgentManager } from "@axiom-lattice/core";
511
715
  var triggerAgentTask = async (request, reply) => {
@@ -545,6 +749,478 @@ var triggerAgentTask = async (request, reply) => {
545
749
  }
546
750
  };
547
751
 
752
+ // src/stores/thread_store.ts
753
+ var ThreadStore = class {
754
+ constructor() {
755
+ // Map<assistantId, Map<threadId, Thread>>
756
+ this.threads = /* @__PURE__ */ new Map();
757
+ }
758
+ /**
759
+ * Get all threads for a specific assistant
760
+ */
761
+ getThreadsByAssistantId(assistantId) {
762
+ const assistantThreads = this.threads.get(assistantId);
763
+ if (!assistantThreads) {
764
+ return [];
765
+ }
766
+ return Array.from(assistantThreads.values());
767
+ }
768
+ /**
769
+ * Get a thread by ID for a specific assistant
770
+ */
771
+ getThreadById(assistantId, threadId) {
772
+ const assistantThreads = this.threads.get(assistantId);
773
+ if (!assistantThreads) {
774
+ return void 0;
775
+ }
776
+ return assistantThreads.get(threadId);
777
+ }
778
+ /**
779
+ * Create a new thread for an assistant
780
+ */
781
+ createThread(assistantId, threadId, data) {
782
+ const now = /* @__PURE__ */ new Date();
783
+ const thread = {
784
+ id: threadId,
785
+ assistantId,
786
+ metadata: data.metadata || {},
787
+ createdAt: now,
788
+ updatedAt: now
789
+ };
790
+ if (!this.threads.has(assistantId)) {
791
+ this.threads.set(assistantId, /* @__PURE__ */ new Map());
792
+ }
793
+ const assistantThreads = this.threads.get(assistantId);
794
+ assistantThreads.set(threadId, thread);
795
+ return thread;
796
+ }
797
+ /**
798
+ * Update an existing thread
799
+ */
800
+ updateThread(assistantId, threadId, updates) {
801
+ const assistantThreads = this.threads.get(assistantId);
802
+ if (!assistantThreads) {
803
+ return null;
804
+ }
805
+ const existing = assistantThreads.get(threadId);
806
+ if (!existing) {
807
+ return null;
808
+ }
809
+ const updated = {
810
+ ...existing,
811
+ metadata: {
812
+ ...existing.metadata,
813
+ ...updates.metadata || {}
814
+ },
815
+ updatedAt: /* @__PURE__ */ new Date()
816
+ };
817
+ assistantThreads.set(threadId, updated);
818
+ return updated;
819
+ }
820
+ /**
821
+ * Delete a thread by ID
822
+ */
823
+ deleteThread(assistantId, threadId) {
824
+ const assistantThreads = this.threads.get(assistantId);
825
+ if (!assistantThreads) {
826
+ return false;
827
+ }
828
+ return assistantThreads.delete(threadId);
829
+ }
830
+ /**
831
+ * Check if thread exists
832
+ */
833
+ hasThread(assistantId, threadId) {
834
+ const assistantThreads = this.threads.get(assistantId);
835
+ if (!assistantThreads) {
836
+ return false;
837
+ }
838
+ return assistantThreads.has(threadId);
839
+ }
840
+ };
841
+ var threadStore = new ThreadStore();
842
+
843
+ // src/controllers/threads.ts
844
+ import { randomUUID as randomUUID2 } from "crypto";
845
+ async function getThreadList(request, reply) {
846
+ const { assistantId } = request.params;
847
+ const threads = threadStore.getThreadsByAssistantId(assistantId);
848
+ return {
849
+ success: true,
850
+ message: "Successfully retrieved thread list",
851
+ data: {
852
+ records: threads,
853
+ total: threads.length
854
+ }
855
+ };
856
+ }
857
+ async function getThread(request, reply) {
858
+ const { assistantId, threadId } = request.params;
859
+ const thread = threadStore.getThreadById(assistantId, threadId);
860
+ if (!thread) {
861
+ return reply.status(404).send({
862
+ success: false,
863
+ message: "Thread not found"
864
+ });
865
+ }
866
+ return {
867
+ success: true,
868
+ message: "Successfully retrieved thread",
869
+ data: thread
870
+ };
871
+ }
872
+ async function createThread(request, reply) {
873
+ const { assistantId } = request.params;
874
+ const data = request.body;
875
+ const threadId = randomUUID2();
876
+ const newThread = threadStore.createThread(assistantId, threadId, data);
877
+ return reply.status(201).send({
878
+ success: true,
879
+ message: "Successfully created thread",
880
+ data: newThread
881
+ });
882
+ }
883
+ async function updateThread(request, reply) {
884
+ const { assistantId, threadId } = request.params;
885
+ const updates = request.body;
886
+ if (!threadStore.hasThread(assistantId, threadId)) {
887
+ return reply.status(404).send({
888
+ success: false,
889
+ message: "Thread not found"
890
+ });
891
+ }
892
+ const updatedThread = threadStore.updateThread(
893
+ assistantId,
894
+ threadId,
895
+ updates
896
+ );
897
+ if (!updatedThread) {
898
+ return reply.status(500).send({
899
+ success: false,
900
+ message: "Failed to update thread"
901
+ });
902
+ }
903
+ return {
904
+ success: true,
905
+ message: "Successfully updated thread",
906
+ data: updatedThread
907
+ };
908
+ }
909
+ async function deleteThread(request, reply) {
910
+ const { assistantId, threadId } = request.params;
911
+ if (!threadStore.hasThread(assistantId, threadId)) {
912
+ return reply.status(404).send({
913
+ success: false,
914
+ message: "Thread not found"
915
+ });
916
+ }
917
+ const deleted = threadStore.deleteThread(assistantId, threadId);
918
+ if (!deleted) {
919
+ return reply.status(500).send({
920
+ success: false,
921
+ message: "Failed to delete thread"
922
+ });
923
+ }
924
+ return {
925
+ success: true,
926
+ message: "Successfully deleted thread"
927
+ };
928
+ }
929
+
930
+ // src/config.ts
931
+ var ConfigService = class {
932
+ constructor() {
933
+ this.config = this.loadFromEnv();
934
+ }
935
+ /**
936
+ * Load configuration from environment variables
937
+ */
938
+ loadFromEnv() {
939
+ return {
940
+ port: process.env.PORT ? Number(process.env.PORT) : void 0,
941
+ queueServiceType: process.env.QUEUE_SERVICE_TYPE,
942
+ redisUrl: process.env.REDIS_URL,
943
+ redisPassword: process.env.REDIS_PASSWORD,
944
+ queueName: process.env.QUEUE_NAME
945
+ };
946
+ }
947
+ /**
948
+ * Update configuration from JSON object
949
+ * This will update both the internal config and process.env
950
+ */
951
+ updateConfig(jsonConfig) {
952
+ for (const [key, value] of Object.entries(jsonConfig)) {
953
+ if (value !== null && value !== void 0) {
954
+ if (typeof value === "object" && !Array.isArray(value)) {
955
+ for (const [nestedKey, nestedValue] of Object.entries(value)) {
956
+ const envKey = `${key.toUpperCase()}_${nestedKey.toUpperCase()}`;
957
+ process.env[envKey] = String(nestedValue);
958
+ }
959
+ } else {
960
+ process.env[key.toUpperCase()] = String(value);
961
+ }
962
+ }
963
+ }
964
+ this.config = this.loadFromEnv();
965
+ this.config = this.deepMerge(this.config, jsonConfig);
966
+ }
967
+ /**
968
+ * Deep merge two objects
969
+ */
970
+ deepMerge(target, source) {
971
+ const output = { ...target };
972
+ if (this.isObject(target) && this.isObject(source)) {
973
+ Object.keys(source).forEach((key) => {
974
+ if (this.isObject(source[key])) {
975
+ if (!(key in target)) {
976
+ Object.assign(output, { [key]: source[key] });
977
+ } else {
978
+ output[key] = this.deepMerge(target[key], source[key]);
979
+ }
980
+ } else {
981
+ Object.assign(output, { [key]: source[key] });
982
+ }
983
+ });
984
+ }
985
+ return output;
986
+ }
987
+ /**
988
+ * Check if value is a plain object
989
+ */
990
+ isObject(item) {
991
+ return item && typeof item === "object" && !Array.isArray(item);
992
+ }
993
+ /**
994
+ * Get current configuration
995
+ */
996
+ getConfig() {
997
+ return { ...this.config };
998
+ }
999
+ };
1000
+ var configService = new ConfigService();
1001
+
1002
+ // src/services/queue_service.ts
1003
+ import {
1004
+ queueLatticeManager,
1005
+ registerQueueLattice,
1006
+ getQueueLattice
1007
+ } from "@axiom-lattice/core";
1008
+ import { QueueType } from "@axiom-lattice/protocols";
1009
+ import { RedisQueueClient } from "@axiom-lattice/queue-redis";
1010
+ var DEFAULT_QUEUE_KEY = "default";
1011
+ var queueServiceType = process.env.QUEUE_SERVICE_TYPE || "memory";
1012
+ var setQueueServiceType = (type) => {
1013
+ queueServiceType = type;
1014
+ console.log(`Queue service type set to: ${type}`);
1015
+ const queueName = process.env.QUEUE_NAME || "tasks";
1016
+ const config = {
1017
+ name: "Default Queue Service",
1018
+ description: `Default ${type} queue service`,
1019
+ type: type === "redis" ? QueueType.REDIS : QueueType.MEMORY,
1020
+ queueName,
1021
+ options: type === "redis" ? {
1022
+ redisUrl: process.env.REDIS_URL,
1023
+ redisPassword: process.env.REDIS_PASSWORD
1024
+ } : void 0
1025
+ };
1026
+ if (queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {
1027
+ queueLatticeManager.removeLattice(DEFAULT_QUEUE_KEY);
1028
+ }
1029
+ let client;
1030
+ if (type === "redis") {
1031
+ client = new RedisQueueClient(queueName, {
1032
+ redisUrl: process.env.REDIS_URL,
1033
+ redisPassword: process.env.REDIS_PASSWORD
1034
+ });
1035
+ }
1036
+ registerQueueLattice(DEFAULT_QUEUE_KEY, config, client);
1037
+ };
1038
+ var getQueueService = () => {
1039
+ if (!queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {
1040
+ setQueueServiceType(queueServiceType);
1041
+ }
1042
+ return getQueueLattice(DEFAULT_QUEUE_KEY);
1043
+ };
1044
+ var popAgentTaskFromQueue = async () => {
1045
+ const queue = getQueueService();
1046
+ const result = await queue.pop();
1047
+ return result;
1048
+ };
1049
+
1050
+ // src/controllers/config.ts
1051
+ async function updateConfig(request, reply) {
1052
+ try {
1053
+ const { config: jsonConfig } = request.body;
1054
+ if (!jsonConfig || typeof jsonConfig !== "object") {
1055
+ return reply.status(400).send({
1056
+ success: false,
1057
+ error: "Invalid configuration: config must be an object"
1058
+ });
1059
+ }
1060
+ configService.updateConfig(jsonConfig);
1061
+ const warnings = [];
1062
+ const requiresRestart = [];
1063
+ if (jsonConfig.port !== void 0) {
1064
+ requiresRestart.push("PORT");
1065
+ warnings.push("Port change requires server restart to take effect");
1066
+ }
1067
+ if (jsonConfig.queueServiceType) {
1068
+ setQueueServiceType(jsonConfig.queueServiceType);
1069
+ }
1070
+ if ((jsonConfig.redisUrl || jsonConfig.redisPassword) && (process.env.QUEUE_SERVICE_TYPE === "redis" || jsonConfig.queueServiceType === "redis")) {
1071
+ const currentType = jsonConfig.queueServiceType || process.env.QUEUE_SERVICE_TYPE || "memory";
1072
+ if (currentType === "redis") {
1073
+ setQueueServiceType("redis");
1074
+ }
1075
+ }
1076
+ const updatedConfig = configService.getConfig();
1077
+ const safeConfig = {
1078
+ ...updatedConfig,
1079
+ redisPassword: updatedConfig.redisPassword ? "***" : updatedConfig.redisPassword
1080
+ };
1081
+ return reply.send({
1082
+ success: true,
1083
+ message: "Configuration updated successfully",
1084
+ data: safeConfig,
1085
+ warnings: warnings.length > 0 ? warnings : void 0,
1086
+ requiresRestart: requiresRestart.length > 0 ? requiresRestart : void 0
1087
+ });
1088
+ } catch (error) {
1089
+ console.error("Failed to update configuration", {
1090
+ error: error.message,
1091
+ stack: error.stack
1092
+ });
1093
+ return reply.status(500).send({
1094
+ success: false,
1095
+ error: error.message || "Failed to update configuration"
1096
+ });
1097
+ }
1098
+ }
1099
+ async function getConfig(request, reply) {
1100
+ try {
1101
+ const currentConfig = configService.getConfig();
1102
+ const safeConfig = {
1103
+ ...currentConfig,
1104
+ redisPassword: currentConfig.redisPassword ? "***" : currentConfig.redisPassword
1105
+ };
1106
+ return reply.send({
1107
+ success: true,
1108
+ data: safeConfig
1109
+ });
1110
+ } catch (error) {
1111
+ console.error("Failed to get configuration", {
1112
+ error: error.message,
1113
+ stack: error.stack
1114
+ });
1115
+ return reply.status(500).send({
1116
+ success: false,
1117
+ error: error.message || "Failed to get configuration"
1118
+ });
1119
+ }
1120
+ }
1121
+
1122
+ // src/controllers/models.ts
1123
+ import { registerModelLattice, modelLatticeManager } from "@axiom-lattice/core";
1124
+ async function getModels(request, reply) {
1125
+ try {
1126
+ const allLattices = modelLatticeManager.getAllLattices();
1127
+ const models = allLattices.map((lattice) => {
1128
+ const config = lattice.client.config || {};
1129
+ return {
1130
+ key: lattice.key,
1131
+ model: config.model || "",
1132
+ provider: config.provider || "openai",
1133
+ streaming: config.streaming || false,
1134
+ apiKey: config.apiKey || "",
1135
+ baseURL: config.baseURL || "",
1136
+ maxTokens: config.maxTokens,
1137
+ temperature: config.temperature,
1138
+ timeout: config.timeout,
1139
+ maxRetries: config.maxRetries
1140
+ };
1141
+ });
1142
+ return reply.send({
1143
+ success: true,
1144
+ data: models
1145
+ });
1146
+ } catch (error) {
1147
+ console.error("Failed to get models", {
1148
+ error: error.message,
1149
+ stack: error.stack
1150
+ });
1151
+ return reply.status(500).send({
1152
+ success: false,
1153
+ error: error.message || "Failed to get models"
1154
+ });
1155
+ }
1156
+ }
1157
+ async function updateModels(request, reply) {
1158
+ try {
1159
+ const { models } = request.body;
1160
+ if (!models || !Array.isArray(models)) {
1161
+ return reply.status(400).send({
1162
+ success: false,
1163
+ error: "Invalid request: models must be an array"
1164
+ });
1165
+ }
1166
+ const registeredModels = [];
1167
+ const errors = [];
1168
+ for (const modelConfig of models) {
1169
+ if (!modelConfig.key || !modelConfig.model || !modelConfig.provider) {
1170
+ errors.push(
1171
+ `Model configuration is incomplete: key, model, and provider are required`
1172
+ );
1173
+ continue;
1174
+ }
1175
+ try {
1176
+ if (modelLatticeManager.hasLattice(modelConfig.key)) {
1177
+ modelLatticeManager.removeLattice(modelConfig.key);
1178
+ }
1179
+ const llmConfig = {
1180
+ provider: modelConfig.provider,
1181
+ model: modelConfig.model,
1182
+ streaming: modelConfig.streaming ?? false,
1183
+ apiKey: modelConfig.apiKey,
1184
+ baseURL: modelConfig.baseURL,
1185
+ maxTokens: modelConfig.maxTokens,
1186
+ temperature: modelConfig.temperature,
1187
+ timeout: modelConfig.timeout,
1188
+ maxRetries: modelConfig.maxRetries
1189
+ };
1190
+ registerModelLattice(modelConfig.key, llmConfig);
1191
+ registeredModels.push(modelConfig.key);
1192
+ } catch (error) {
1193
+ errors.push(
1194
+ `Failed to register model ${modelConfig.key}: ${error.message}`
1195
+ );
1196
+ }
1197
+ }
1198
+ if (errors.length > 0 && registeredModels.length === 0) {
1199
+ return reply.status(400).send({
1200
+ success: false,
1201
+ error: errors.join("; ")
1202
+ });
1203
+ }
1204
+ return reply.send({
1205
+ success: true,
1206
+ message: `Successfully registered ${registeredModels.length} model(s)`,
1207
+ data: {
1208
+ registered: registeredModels,
1209
+ errors: errors.length > 0 ? errors : void 0
1210
+ }
1211
+ });
1212
+ } catch (error) {
1213
+ console.error("Failed to update models", {
1214
+ error: error.message,
1215
+ stack: error.stack
1216
+ });
1217
+ return reply.status(500).send({
1218
+ success: false,
1219
+ error: error.message || "Failed to update models"
1220
+ });
1221
+ }
1222
+ }
1223
+
548
1224
  // src/schemas/index.ts
549
1225
  var getAllMemoryItemsSchema = {
550
1226
  description: "Get all memory items for an assistant thread",
@@ -713,6 +1389,77 @@ var triggerAgentTaskSchema = {
713
1389
  }
714
1390
  }
715
1391
  };
1392
+ var updateConfigSchema = {
1393
+ description: "Update gateway configuration",
1394
+ tags: ["Configuration"],
1395
+ summary: "Update Configuration",
1396
+ body: {
1397
+ type: "object",
1398
+ properties: {
1399
+ config: {
1400
+ type: "object",
1401
+ description: "Configuration object to update",
1402
+ properties: {
1403
+ port: { type: "number", description: "Server port" },
1404
+ queueServiceType: {
1405
+ type: "string",
1406
+ enum: ["memory", "redis"],
1407
+ description: "Queue service type"
1408
+ },
1409
+ redisUrl: { type: "string", description: "Redis URL" },
1410
+ redisPassword: { type: "string", description: "Redis password" },
1411
+ queueName: { type: "string", description: "Queue name" }
1412
+ }
1413
+ }
1414
+ },
1415
+ required: ["config"]
1416
+ },
1417
+ response: {
1418
+ 200: {
1419
+ type: "object",
1420
+ properties: {
1421
+ success: { type: "boolean" },
1422
+ message: { type: "string" },
1423
+ data: { type: "object" }
1424
+ }
1425
+ },
1426
+ 400: {
1427
+ type: "object",
1428
+ properties: {
1429
+ success: { type: "boolean" },
1430
+ error: { type: "string" }
1431
+ }
1432
+ },
1433
+ 500: {
1434
+ type: "object",
1435
+ properties: {
1436
+ success: { type: "boolean" },
1437
+ error: { type: "string" }
1438
+ }
1439
+ }
1440
+ }
1441
+ };
1442
+ var getConfigSchema = {
1443
+ description: "Get current gateway configuration",
1444
+ tags: ["Configuration"],
1445
+ summary: "Get Configuration",
1446
+ response: {
1447
+ 200: {
1448
+ type: "object",
1449
+ properties: {
1450
+ success: { type: "boolean" },
1451
+ data: { type: "object" }
1452
+ }
1453
+ },
1454
+ 500: {
1455
+ type: "object",
1456
+ properties: {
1457
+ success: { type: "boolean" },
1458
+ error: { type: "string" }
1459
+ }
1460
+ }
1461
+ }
1462
+ };
716
1463
 
717
1464
  // src/routes/index.ts
718
1465
  var registerLatticeRoutes = (app2) => {
@@ -748,6 +1495,11 @@ var registerLatticeRoutes = (app2) => {
748
1495
  { schema: clearMemorySchema },
749
1496
  clearMemory
750
1497
  );
1498
+ app2.get("/api/assistants", getAssistantList);
1499
+ app2.get("/api/assistants/:id", getAssistant);
1500
+ app2.post("/api/assistants", createAssistant);
1501
+ app2.put("/api/assistants/:id", updateAssistant);
1502
+ app2.delete("/api/assistants/:id", deleteAssistant);
751
1503
  app2.get(
752
1504
  "/api/assistants/:assistantId/graph",
753
1505
  { schema: getAgentGraphSchema },
@@ -758,6 +1510,32 @@ var registerLatticeRoutes = (app2) => {
758
1510
  { schema: triggerAgentTaskSchema },
759
1511
  triggerAgentTask
760
1512
  );
1513
+ app2.get("/api/assistants/:assistantId/threads", getThreadList);
1514
+ app2.get(
1515
+ "/api/assistants/:assistantId/threads/:threadId",
1516
+ getThread
1517
+ );
1518
+ app2.post("/api/assistants/:assistantId/threads", createThread);
1519
+ app2.put(
1520
+ "/api/assistants/:assistantId/threads/:threadId",
1521
+ updateThread
1522
+ );
1523
+ app2.delete(
1524
+ "/api/assistants/:assistantId/threads/:threadId",
1525
+ deleteThread
1526
+ );
1527
+ app2.get(
1528
+ "/api/config",
1529
+ { schema: getConfigSchema },
1530
+ getConfig
1531
+ );
1532
+ app2.put(
1533
+ "/api/config",
1534
+ { schema: updateConfigSchema },
1535
+ updateConfig
1536
+ );
1537
+ app2.get("/api/models", getModels);
1538
+ app2.put("/api/models", updateModels);
761
1539
  };
762
1540
 
763
1541
  // src/logger/Logger.ts
@@ -960,54 +1738,6 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
960
1738
  await app2.register(swaggerUi, swaggerUiConfig);
961
1739
  };
962
1740
 
963
- // src/services/queue_service.ts
964
- import {
965
- queueLatticeManager,
966
- registerQueueLattice,
967
- getQueueLattice
968
- } from "@axiom-lattice/core";
969
- import { QueueType } from "@axiom-lattice/protocols";
970
- import { RedisQueueClient } from "@axiom-lattice/queue-redis";
971
- var DEFAULT_QUEUE_KEY = "default";
972
- var queueServiceType = process.env.QUEUE_SERVICE_TYPE || "memory";
973
- var setQueueServiceType = (type) => {
974
- queueServiceType = type;
975
- console.log(`Queue service type set to: ${type}`);
976
- const queueName = process.env.QUEUE_NAME || "tasks";
977
- const config = {
978
- name: "Default Queue Service",
979
- description: `Default ${type} queue service`,
980
- type: type === "redis" ? QueueType.REDIS : QueueType.MEMORY,
981
- queueName,
982
- options: type === "redis" ? {
983
- redisUrl: process.env.REDIS_URL,
984
- redisPassword: process.env.REDIS_PASSWORD
985
- } : void 0
986
- };
987
- if (queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {
988
- queueLatticeManager.removeLattice(DEFAULT_QUEUE_KEY);
989
- }
990
- let client;
991
- if (type === "redis") {
992
- client = new RedisQueueClient(queueName, {
993
- redisUrl: process.env.REDIS_URL,
994
- redisPassword: process.env.REDIS_PASSWORD
995
- });
996
- }
997
- registerQueueLattice(DEFAULT_QUEUE_KEY, config, client);
998
- };
999
- var getQueueService = () => {
1000
- if (!queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {
1001
- setQueueServiceType(queueServiceType);
1002
- }
1003
- return getQueueLattice(DEFAULT_QUEUE_KEY);
1004
- };
1005
- var popAgentTaskFromQueue = async () => {
1006
- const queue = getQueueService();
1007
- const result = await queue.pop();
1008
- return result;
1009
- };
1010
-
1011
1741
  // src/services/agent_task_consumer.ts
1012
1742
  import { eventBus, AGENT_TASK_EVENT } from "@axiom-lattice/core";
1013
1743
  var handleAgentTask = async (taskRequest, retryCount = 0) => {