@axiom-lattice/gateway 2.1.2 → 2.1.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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +16 -0
- package/dist/index.d.mts +65 -4
- package/dist/index.d.ts +65 -4
- package/dist/index.js +584 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +590 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/controllers/agent_task.ts +65 -0
- package/src/controllers/run.ts +1 -1
- package/src/index.ts +30 -4
- package/src/routes/index.ts +11 -0
- package/src/schemas/index.ts +53 -0
- package/src/services/AgentManager.ts +25 -21
- package/src/services/agent_task_consumer.ts +325 -0
- package/src/services/queue_service.ts +32 -71
- package/src/services/queue_service_memory.ts +85 -0
- package/src/services/queue_service_redis.ts +86 -0
package/dist/index.js
CHANGED
|
@@ -338,7 +338,7 @@ var resumeStream = async (request, reply) => {
|
|
|
338
338
|
const stream = await resume_stream({
|
|
339
339
|
thread_id,
|
|
340
340
|
message_id,
|
|
341
|
-
known_content
|
|
341
|
+
known_content,
|
|
342
342
|
poll_interval: poll_interval || 100
|
|
343
343
|
});
|
|
344
344
|
for await (const chunk of stream) {
|
|
@@ -534,6 +534,282 @@ var getAgentGraph = async (request, reply) => {
|
|
|
534
534
|
}
|
|
535
535
|
};
|
|
536
536
|
|
|
537
|
+
// src/services/agent_task_types.ts
|
|
538
|
+
var AGENT_TASK_EVENT = "agent:execute";
|
|
539
|
+
|
|
540
|
+
// src/services/event_bus.ts
|
|
541
|
+
var import_events = require("events");
|
|
542
|
+
|
|
543
|
+
// src/services/queue_service_memory.ts
|
|
544
|
+
var queue_service_memory_exports = {};
|
|
545
|
+
__export(queue_service_memory_exports, {
|
|
546
|
+
popAgentTaskFromQueue: () => popAgentTaskFromQueue,
|
|
547
|
+
pushAgentTaskToQueue: () => pushAgentTaskToQueue
|
|
548
|
+
});
|
|
549
|
+
var queue_name = process.env.QUEUE_NAME || "tasks";
|
|
550
|
+
var queues = /* @__PURE__ */ new Map();
|
|
551
|
+
var ensureQueue = (queueName) => {
|
|
552
|
+
if (!queues.has(queueName)) {
|
|
553
|
+
queues.set(queueName, []);
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
var sendToQueue = async (queueName, message) => {
|
|
557
|
+
try {
|
|
558
|
+
ensureQueue(queueName);
|
|
559
|
+
const queue = queues.get(queueName);
|
|
560
|
+
queue.unshift(message);
|
|
561
|
+
const result = queue.length;
|
|
562
|
+
console.log("lPush (memory)", result);
|
|
563
|
+
return { data: result, error: null };
|
|
564
|
+
} catch (error) {
|
|
565
|
+
console.error(error);
|
|
566
|
+
return { data: null, error };
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
var popFromQueue = async (queueName) => {
|
|
570
|
+
try {
|
|
571
|
+
ensureQueue(queueName);
|
|
572
|
+
const queue = queues.get(queueName);
|
|
573
|
+
const message = queue.pop();
|
|
574
|
+
if (message) {
|
|
575
|
+
return { data: message, error: null };
|
|
576
|
+
}
|
|
577
|
+
return { data: null, error: null };
|
|
578
|
+
} catch (error) {
|
|
579
|
+
console.error(error);
|
|
580
|
+
return { data: null, error };
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
var createTenantQueue = async () => {
|
|
584
|
+
try {
|
|
585
|
+
ensureQueue(queue_name);
|
|
586
|
+
const queue = queues.get(queue_name);
|
|
587
|
+
const exists = queue !== void 0;
|
|
588
|
+
return { success: true, queue_name };
|
|
589
|
+
} catch (error) {
|
|
590
|
+
console.error(error);
|
|
591
|
+
return { success: false, error };
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
var pushAgentTaskToQueue = async (agentTask) => {
|
|
595
|
+
const tenantId = agentTask["x-tenant-id"];
|
|
596
|
+
try {
|
|
597
|
+
await createTenantQueue();
|
|
598
|
+
const result = await sendToQueue(`${queue_name}`, agentTask);
|
|
599
|
+
return result;
|
|
600
|
+
} catch (error) {
|
|
601
|
+
console.error(error);
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
var popAgentTaskFromQueue = async () => {
|
|
606
|
+
const result = await popFromQueue(`${queue_name}`);
|
|
607
|
+
return result;
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
// src/services/queue_service_redis.ts
|
|
611
|
+
var queue_service_redis_exports = {};
|
|
612
|
+
__export(queue_service_redis_exports, {
|
|
613
|
+
popAgentTaskFromQueue: () => popAgentTaskFromQueue2,
|
|
614
|
+
pushAgentTaskToQueue: () => pushAgentTaskToQueue2
|
|
615
|
+
});
|
|
616
|
+
var import_redis = require("redis");
|
|
617
|
+
var queue_name2 = process.env.QUEUE_NAME || "tasks";
|
|
618
|
+
var redisOptions = {
|
|
619
|
+
url: process.env.REDIS_URL || "redis://localhost:6379",
|
|
620
|
+
password: process.env.REDIS_PASSWORD
|
|
621
|
+
};
|
|
622
|
+
var redisClient = (0, import_redis.createClient)(redisOptions);
|
|
623
|
+
(async () => {
|
|
624
|
+
redisClient.on(
|
|
625
|
+
"error",
|
|
626
|
+
(err) => console.error("Redis Client Error", err)
|
|
627
|
+
);
|
|
628
|
+
try {
|
|
629
|
+
await redisClient.connect();
|
|
630
|
+
console.log("Redis connection successful");
|
|
631
|
+
} catch (error) {
|
|
632
|
+
console.error("Redis connection failed:", error);
|
|
633
|
+
}
|
|
634
|
+
})();
|
|
635
|
+
var sendToQueue2 = async (queueName, message) => {
|
|
636
|
+
try {
|
|
637
|
+
const result = await redisClient.lPush(queueName, JSON.stringify(message));
|
|
638
|
+
console.log("lPush", result);
|
|
639
|
+
return { data: result, error: null };
|
|
640
|
+
} catch (error) {
|
|
641
|
+
console.error(error);
|
|
642
|
+
return { data: null, error };
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
var popFromQueue2 = async (queueName) => {
|
|
646
|
+
try {
|
|
647
|
+
const message = await redisClient.rPop(queueName);
|
|
648
|
+
if (message) {
|
|
649
|
+
return { data: JSON.parse(message), error: null };
|
|
650
|
+
}
|
|
651
|
+
return { data: null, error: null };
|
|
652
|
+
} catch (error) {
|
|
653
|
+
console.error(error);
|
|
654
|
+
return { data: null, error };
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
var createTenantQueue2 = async () => {
|
|
658
|
+
try {
|
|
659
|
+
const exists = await redisClient.exists(queue_name2);
|
|
660
|
+
return { success: true, queue_name: queue_name2 };
|
|
661
|
+
} catch (error) {
|
|
662
|
+
console.error(error);
|
|
663
|
+
return { success: false, error };
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
var pushAgentTaskToQueue2 = async (agentTask) => {
|
|
667
|
+
const tenantId = agentTask["x-tenant-id"];
|
|
668
|
+
try {
|
|
669
|
+
await createTenantQueue2();
|
|
670
|
+
const result = await sendToQueue2(`${queue_name2}`, agentTask);
|
|
671
|
+
return result;
|
|
672
|
+
} catch (error) {
|
|
673
|
+
console.error(error);
|
|
674
|
+
return null;
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
var popAgentTaskFromQueue2 = async () => {
|
|
678
|
+
const result = await popFromQueue2(`${queue_name2}`);
|
|
679
|
+
return result;
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
// src/services/queue_service.ts
|
|
683
|
+
var queueServiceType = process.env.QUEUE_SERVICE_TYPE || "memory";
|
|
684
|
+
var setQueueServiceType = (type) => {
|
|
685
|
+
queueServiceType = type;
|
|
686
|
+
console.log(`Queue service type set to: ${type}`);
|
|
687
|
+
};
|
|
688
|
+
var getQueueService = () => {
|
|
689
|
+
return queueServiceType === "redis" ? queue_service_redis_exports : queue_service_memory_exports;
|
|
690
|
+
};
|
|
691
|
+
var pushAgentTaskToQueue3 = async (agentTask) => {
|
|
692
|
+
const service = getQueueService();
|
|
693
|
+
return service.pushAgentTaskToQueue(agentTask);
|
|
694
|
+
};
|
|
695
|
+
var popAgentTaskFromQueue3 = async () => {
|
|
696
|
+
const service = getQueueService();
|
|
697
|
+
return service.popAgentTaskFromQueue();
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
// src/services/event_bus.ts
|
|
701
|
+
var EventBus = class {
|
|
702
|
+
constructor() {
|
|
703
|
+
this.emitter = new import_events.EventEmitter();
|
|
704
|
+
this.emitter.setMaxListeners(100);
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* 发布事件
|
|
708
|
+
* @param eventName 事件名称
|
|
709
|
+
* @param data 事件数据
|
|
710
|
+
*/
|
|
711
|
+
publish(eventName, data, useQueue = false) {
|
|
712
|
+
if (useQueue) {
|
|
713
|
+
pushAgentTaskToQueue3(data);
|
|
714
|
+
} else {
|
|
715
|
+
this.emitter.emit(eventName, data);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* 订阅事件
|
|
720
|
+
* @param eventName 事件名称
|
|
721
|
+
* @param callback 回调函数
|
|
722
|
+
*/
|
|
723
|
+
subscribe(eventName, callback) {
|
|
724
|
+
this.emitter.on(eventName, callback);
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* 取消订阅事件
|
|
728
|
+
* @param eventName 事件名称
|
|
729
|
+
* @param callback 回调函数
|
|
730
|
+
*/
|
|
731
|
+
unsubscribe(eventName, callback) {
|
|
732
|
+
this.emitter.off(eventName, callback);
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* 只订阅一次事件
|
|
736
|
+
* @param eventName 事件名称
|
|
737
|
+
* @param callback 回调函数
|
|
738
|
+
*/
|
|
739
|
+
subscribeOnce(eventName, callback) {
|
|
740
|
+
this.emitter.once(eventName, callback);
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
var eventBus = new EventBus();
|
|
744
|
+
var event_bus_default = eventBus;
|
|
745
|
+
|
|
746
|
+
// src/services/AgentManager.ts
|
|
747
|
+
var AgentManager = class _AgentManager {
|
|
748
|
+
constructor() {
|
|
749
|
+
this.agents = [];
|
|
750
|
+
}
|
|
751
|
+
static getInstance() {
|
|
752
|
+
if (!_AgentManager.instance) {
|
|
753
|
+
_AgentManager.instance = new _AgentManager();
|
|
754
|
+
}
|
|
755
|
+
return _AgentManager.instance;
|
|
756
|
+
}
|
|
757
|
+
callAgentInQueue(queue) {
|
|
758
|
+
return new Promise((resolve, reject) => {
|
|
759
|
+
try {
|
|
760
|
+
event_bus_default.publish(
|
|
761
|
+
AGENT_TASK_EVENT,
|
|
762
|
+
{
|
|
763
|
+
...queue
|
|
764
|
+
},
|
|
765
|
+
true
|
|
766
|
+
);
|
|
767
|
+
resolve(true);
|
|
768
|
+
} catch (error) {
|
|
769
|
+
reject(error);
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
// src/controllers/agent_task.ts
|
|
776
|
+
var triggerAgentTask = async (request, reply) => {
|
|
777
|
+
try {
|
|
778
|
+
const { assistant_id, thread_id, input, command } = request.body;
|
|
779
|
+
const tenant_id = request.headers["x-tenant-id"];
|
|
780
|
+
if (!assistant_id) {
|
|
781
|
+
reply.status(400).send({
|
|
782
|
+
success: false,
|
|
783
|
+
error: "assistant_id is required"
|
|
784
|
+
});
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
if (!thread_id) {
|
|
788
|
+
reply.status(400).send({
|
|
789
|
+
success: false,
|
|
790
|
+
error: "thread_id is required"
|
|
791
|
+
});
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
const agentManager = AgentManager.getInstance();
|
|
795
|
+
const result = await agentManager.callAgentInQueue({
|
|
796
|
+
assistant_id,
|
|
797
|
+
thread_id,
|
|
798
|
+
input,
|
|
799
|
+
command,
|
|
800
|
+
"x-tenant-id": tenant_id
|
|
801
|
+
});
|
|
802
|
+
reply.status(200).send({
|
|
803
|
+
success: true
|
|
804
|
+
});
|
|
805
|
+
} catch (error) {
|
|
806
|
+
reply.status(500).send({
|
|
807
|
+
success: false,
|
|
808
|
+
error: `Failed to trigger agent task: ${error.message}`
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
|
|
537
813
|
// src/schemas/index.ts
|
|
538
814
|
var getAllMemoryItemsSchema = {
|
|
539
815
|
description: "Get all memory items for an assistant thread",
|
|
@@ -651,6 +927,57 @@ var getAgentGraphSchema = {
|
|
|
651
927
|
200: {}
|
|
652
928
|
}
|
|
653
929
|
};
|
|
930
|
+
var triggerAgentTaskSchema = {
|
|
931
|
+
description: "Trigger an agent task",
|
|
932
|
+
tags: ["Agent Tasks"],
|
|
933
|
+
summary: "Trigger Agent Task",
|
|
934
|
+
body: {
|
|
935
|
+
type: "object",
|
|
936
|
+
properties: {
|
|
937
|
+
assistant_id: {
|
|
938
|
+
type: "string",
|
|
939
|
+
description: "Assistant ID"
|
|
940
|
+
},
|
|
941
|
+
thread_id: {
|
|
942
|
+
type: "string",
|
|
943
|
+
description: "Thread ID"
|
|
944
|
+
},
|
|
945
|
+
input: {
|
|
946
|
+
type: "object",
|
|
947
|
+
description: "Task input data"
|
|
948
|
+
},
|
|
949
|
+
command: {
|
|
950
|
+
type: "object",
|
|
951
|
+
description: "Command data for the task",
|
|
952
|
+
nullable: true
|
|
953
|
+
}
|
|
954
|
+
},
|
|
955
|
+
required: ["assistant_id", "thread_id"]
|
|
956
|
+
},
|
|
957
|
+
response: {
|
|
958
|
+
200: {
|
|
959
|
+
type: "object",
|
|
960
|
+
properties: {
|
|
961
|
+
success: { type: "boolean" },
|
|
962
|
+
result: { type: "object" }
|
|
963
|
+
}
|
|
964
|
+
},
|
|
965
|
+
400: {
|
|
966
|
+
type: "object",
|
|
967
|
+
properties: {
|
|
968
|
+
success: { type: "boolean" },
|
|
969
|
+
error: { type: "string" }
|
|
970
|
+
}
|
|
971
|
+
},
|
|
972
|
+
500: {
|
|
973
|
+
type: "object",
|
|
974
|
+
properties: {
|
|
975
|
+
success: { type: "boolean" },
|
|
976
|
+
error: { type: "string" }
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
};
|
|
654
981
|
|
|
655
982
|
// src/routes/index.ts
|
|
656
983
|
var registerLatticeRoutes = (app2) => {
|
|
@@ -691,6 +1018,11 @@ var registerLatticeRoutes = (app2) => {
|
|
|
691
1018
|
{ schema: getAgentGraphSchema },
|
|
692
1019
|
getAgentGraph
|
|
693
1020
|
);
|
|
1021
|
+
app2.post(
|
|
1022
|
+
"/api/agent-tasks/trigger",
|
|
1023
|
+
{ schema: triggerAgentTaskSchema },
|
|
1024
|
+
triggerAgentTask
|
|
1025
|
+
);
|
|
694
1026
|
};
|
|
695
1027
|
|
|
696
1028
|
// src/logger/Logger.ts
|
|
@@ -893,6 +1225,244 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
|
|
|
893
1225
|
await app2.register(import_swagger_ui.default, swaggerUiConfig);
|
|
894
1226
|
};
|
|
895
1227
|
|
|
1228
|
+
// src/services/agent_task_consumer.ts
|
|
1229
|
+
var handleAgentTask = async (taskRequest, retryCount = 0) => {
|
|
1230
|
+
const {
|
|
1231
|
+
assistant_id,
|
|
1232
|
+
input = {},
|
|
1233
|
+
thread_id,
|
|
1234
|
+
"x-tenant-id": tenant_id,
|
|
1235
|
+
command,
|
|
1236
|
+
callback_event
|
|
1237
|
+
} = taskRequest;
|
|
1238
|
+
try {
|
|
1239
|
+
console.log(
|
|
1240
|
+
`\u5F00\u59CB\u5904\u7406\u4EFB\u52A1 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
|
|
1241
|
+
);
|
|
1242
|
+
const apiUrl = AgentTaskConsumer.agent_run_endpoint;
|
|
1243
|
+
console.log(`apiUrl: ${apiUrl}`);
|
|
1244
|
+
const response = await fetch(apiUrl, {
|
|
1245
|
+
method: "POST",
|
|
1246
|
+
body: JSON.stringify({
|
|
1247
|
+
assistant_id,
|
|
1248
|
+
streaming: true,
|
|
1249
|
+
...input,
|
|
1250
|
+
thread_id,
|
|
1251
|
+
command
|
|
1252
|
+
}),
|
|
1253
|
+
headers: {
|
|
1254
|
+
"Content-Type": "application/json",
|
|
1255
|
+
"x-tenant-id": tenant_id
|
|
1256
|
+
}
|
|
1257
|
+
}).catch((err) => {
|
|
1258
|
+
console.error(`fetch\u8BF7\u6C42\u5931\u8D25: ${err.message || String(err)}`);
|
|
1259
|
+
throw new Error(`fetch\u5931\u8D25: ${err.message || String(err)}`);
|
|
1260
|
+
});
|
|
1261
|
+
if (!response.ok) {
|
|
1262
|
+
throw new Error(`API\u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`);
|
|
1263
|
+
}
|
|
1264
|
+
if (callback_event) {
|
|
1265
|
+
event_bus_default.publish(callback_event, {
|
|
1266
|
+
success: true,
|
|
1267
|
+
config: { assistant_id, thread_id, tenant_id }
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
console.log(
|
|
1271
|
+
`\u4EFB\u52A1\u5904\u7406\u6210\u529F [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
|
|
1272
|
+
);
|
|
1273
|
+
return true;
|
|
1274
|
+
} catch (error) {
|
|
1275
|
+
console.error(
|
|
1276
|
+
`Agent\u4EFB\u52A1\u6267\u884C\u5931\u8D25: ${assistant_id}, \u7EBF\u7A0B: ${thread_id}`,
|
|
1277
|
+
error
|
|
1278
|
+
);
|
|
1279
|
+
const maxRetries = 0;
|
|
1280
|
+
if (retryCount < maxRetries) {
|
|
1281
|
+
const nextRetryCount = retryCount + 1;
|
|
1282
|
+
const delayMs = Math.pow(2, nextRetryCount) * 1e3;
|
|
1283
|
+
console.log(
|
|
1284
|
+
`\u5C06\u5728 ${delayMs}ms \u540E\u91CD\u8BD5\u4EFB\u52A1 (${nextRetryCount}/${maxRetries})`
|
|
1285
|
+
);
|
|
1286
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
1287
|
+
return handleAgentTask(taskRequest, nextRetryCount);
|
|
1288
|
+
}
|
|
1289
|
+
if (callback_event) {
|
|
1290
|
+
event_bus_default.publish(callback_event, {
|
|
1291
|
+
success: false,
|
|
1292
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1293
|
+
config: { assistant_id, thread_id, tenant_id }
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
console.error(
|
|
1297
|
+
`\u4EFB\u52A1\u5904\u7406\u5931\u8D25\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
|
|
1298
|
+
);
|
|
1299
|
+
return false;
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1302
|
+
var _AgentTaskConsumer = class _AgentTaskConsumer {
|
|
1303
|
+
constructor(gatewayPort, pollingIntervalMs) {
|
|
1304
|
+
this.isPolling = false;
|
|
1305
|
+
this.pollingInterval = null;
|
|
1306
|
+
this.pollingIntervalMs = 5e3;
|
|
1307
|
+
// 默认5秒轮询一次
|
|
1308
|
+
this.maxConcurrentTasks = 15;
|
|
1309
|
+
// 最大并发任务数
|
|
1310
|
+
this.activeTasks = 0;
|
|
1311
|
+
// 当前活跃的任务数
|
|
1312
|
+
this.processing = false;
|
|
1313
|
+
// 是否正在处理任务批次
|
|
1314
|
+
this.immediateProcessingEnabled = true;
|
|
1315
|
+
// 是否启用即时处理模式
|
|
1316
|
+
this.gatewayPort = 4001;
|
|
1317
|
+
this.gatewayPort = gatewayPort;
|
|
1318
|
+
_AgentTaskConsumer.agent_run_endpoint = `http://localhost:${this.gatewayPort}/api/runs`;
|
|
1319
|
+
if (pollingIntervalMs) {
|
|
1320
|
+
this.pollingIntervalMs = pollingIntervalMs;
|
|
1321
|
+
}
|
|
1322
|
+
this.initialize();
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* 初始化事件监听和队列轮询
|
|
1326
|
+
*/
|
|
1327
|
+
initialize() {
|
|
1328
|
+
event_bus_default.subscribe(AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
|
|
1329
|
+
this.startPollingQueue();
|
|
1330
|
+
console.log("Agent\u4EFB\u52A1\u6D88\u8D39\u8005\u5DF2\u542F\u52A8\u5E76\u76D1\u542C\u4EFB\u52A1\u4E8B\u4EF6\u548C\u961F\u5217");
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* 启动队列轮询
|
|
1334
|
+
*/
|
|
1335
|
+
startPollingQueue() {
|
|
1336
|
+
if (this.isPolling) {
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
this.isPolling = true;
|
|
1340
|
+
this.pollingInterval = setInterval(async () => {
|
|
1341
|
+
try {
|
|
1342
|
+
if (this.processing) {
|
|
1343
|
+
console.log("\u961F\u5217\u5904\u7406\u4E2D\uFF0C\u8DF3\u8FC7\u672C\u6B21\u8F6E\u8BE2");
|
|
1344
|
+
return;
|
|
1345
|
+
}
|
|
1346
|
+
await this.consumeFromQueue();
|
|
1347
|
+
} catch (error) {
|
|
1348
|
+
console.error("\u961F\u5217\u8F6E\u8BE2\u51FA\u9519:", error);
|
|
1349
|
+
}
|
|
1350
|
+
}, this.pollingIntervalMs);
|
|
1351
|
+
console.log(
|
|
1352
|
+
`\u5F00\u59CB\u8F6E\u8BE2\u961F\u5217\uFF0C\u95F4\u9694: ${this.pollingIntervalMs}ms\uFF0C\u6700\u5927\u5E76\u53D1\u4EFB\u52A1\u6570: ${this.maxConcurrentTasks}`
|
|
1353
|
+
);
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* 停止队列轮询
|
|
1357
|
+
*/
|
|
1358
|
+
stopPollingQueue() {
|
|
1359
|
+
if (this.pollingInterval) {
|
|
1360
|
+
clearInterval(this.pollingInterval);
|
|
1361
|
+
this.pollingInterval = null;
|
|
1362
|
+
this.isPolling = false;
|
|
1363
|
+
console.log("\u5DF2\u505C\u6B62\u961F\u5217\u8F6E\u8BE2");
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* 处理单个任务并在完成后立即尝试处理下一个
|
|
1368
|
+
*/
|
|
1369
|
+
async processNextTask() {
|
|
1370
|
+
try {
|
|
1371
|
+
const queueResult = await popAgentTaskFromQueue3();
|
|
1372
|
+
if (queueResult && queueResult.data) {
|
|
1373
|
+
const taskItem = queueResult.data;
|
|
1374
|
+
if (taskItem && typeof taskItem === "object") {
|
|
1375
|
+
const taskRequest = taskItem;
|
|
1376
|
+
console.log(
|
|
1377
|
+
`\u4ECE\u961F\u5217\u4E2D\u83B7\u53D6\u5230\u4EFB\u52A1 [assistant: ${taskRequest.assistant_id}, thread: ${taskRequest.thread_id}]`
|
|
1378
|
+
);
|
|
1379
|
+
this.activeTasks++;
|
|
1380
|
+
handleAgentTask(taskRequest).then((success) => {
|
|
1381
|
+
if (!success) {
|
|
1382
|
+
console.error(`\u4EFB\u52A1 \u5904\u7406\u5931\u8D25`);
|
|
1383
|
+
} else {
|
|
1384
|
+
console.log(`\u4EFB\u52A1 \u5904\u7406\u6210\u529F`);
|
|
1385
|
+
}
|
|
1386
|
+
}).catch((error) => {
|
|
1387
|
+
console.error(`\u4EFB\u52A1 \u5904\u7406\u65F6\u51FA\u9519:`, error);
|
|
1388
|
+
}).finally(() => {
|
|
1389
|
+
this.activeTasks--;
|
|
1390
|
+
if (this.immediateProcessingEnabled && !this.processing) {
|
|
1391
|
+
this.checkQueueForTasks();
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
1394
|
+
return true;
|
|
1395
|
+
} else {
|
|
1396
|
+
console.log("\u961F\u5217\u4EFB\u52A1\u683C\u5F0F\u65E0\u6548:", taskItem);
|
|
1397
|
+
return false;
|
|
1398
|
+
}
|
|
1399
|
+
} else {
|
|
1400
|
+
return false;
|
|
1401
|
+
}
|
|
1402
|
+
} catch (error) {
|
|
1403
|
+
console.error("\u5904\u7406\u4EFB\u52A1\u5931\u8D25:", error);
|
|
1404
|
+
return false;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* 检查队列中是否有任务并处理
|
|
1409
|
+
*/
|
|
1410
|
+
async checkQueueForTasks() {
|
|
1411
|
+
if (this.processing || this.activeTasks >= this.maxConcurrentTasks) {
|
|
1412
|
+
return;
|
|
1413
|
+
}
|
|
1414
|
+
this.processing = true;
|
|
1415
|
+
try {
|
|
1416
|
+
while (this.activeTasks < this.maxConcurrentTasks) {
|
|
1417
|
+
const taskProcessed = await this.processNextTask();
|
|
1418
|
+
if (!taskProcessed) {
|
|
1419
|
+
break;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
} catch (error) {
|
|
1423
|
+
console.error("\u68C0\u67E5\u961F\u5217\u4EFB\u52A1\u5931\u8D25:", error);
|
|
1424
|
+
} finally {
|
|
1425
|
+
this.processing = false;
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
/**
|
|
1429
|
+
* 从队列中消费任务
|
|
1430
|
+
*/
|
|
1431
|
+
async consumeFromQueue() {
|
|
1432
|
+
if (this.processing) {
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
await this.checkQueueForTasks();
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* 处理通过事件触发的任务
|
|
1439
|
+
*/
|
|
1440
|
+
trigger_agent_task(taskRequest) {
|
|
1441
|
+
console.log(
|
|
1442
|
+
`\u901A\u8FC7\u4E8B\u4EF6\u89E6\u53D1\u4EFB\u52A1: [assistant: ${taskRequest.assistant_id}, thread: ${taskRequest.thread_id}]`
|
|
1443
|
+
);
|
|
1444
|
+
handleAgentTask(taskRequest).catch((error) => {
|
|
1445
|
+
console.error("\u5904\u7406Agent\u4EFB\u52A1\u65F6\u53D1\u751F\u672A\u6355\u83B7\u7684\u9519\u8BEF:", error);
|
|
1446
|
+
if (taskRequest.callback_event) {
|
|
1447
|
+
event_bus_default.publish(taskRequest.callback_event, {
|
|
1448
|
+
success: false,
|
|
1449
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1450
|
+
config: {
|
|
1451
|
+
assistant_id: taskRequest.assistant_id,
|
|
1452
|
+
thread_id: taskRequest.thread_id,
|
|
1453
|
+
tenant_id: taskRequest["x-tenant-id"]
|
|
1454
|
+
}
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
});
|
|
1458
|
+
if (this.immediateProcessingEnabled && this.activeTasks < this.maxConcurrentTasks) {
|
|
1459
|
+
setImmediate(() => this.checkQueueForTasks());
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1463
|
+
_AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
|
|
1464
|
+
var AgentTaskConsumer = _AgentTaskConsumer;
|
|
1465
|
+
|
|
896
1466
|
// src/index.ts
|
|
897
1467
|
process.on("unhandledRejection", (reason, promise) => {
|
|
898
1468
|
console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
|
|
@@ -953,11 +1523,19 @@ app.setErrorHandler((error, request, reply) => {
|
|
|
953
1523
|
});
|
|
954
1524
|
});
|
|
955
1525
|
app.decorate("logger", logger);
|
|
956
|
-
var start = async (
|
|
1526
|
+
var start = async (config) => {
|
|
957
1527
|
try {
|
|
958
|
-
const target_port = port || Number(process.env.PORT) || 4001;
|
|
1528
|
+
const target_port = config?.port || Number(process.env.PORT) || 4001;
|
|
959
1529
|
await app.listen({ port: target_port, host: "0.0.0.0" });
|
|
960
|
-
logger.info(`Lattice Gateway is running on port: ${
|
|
1530
|
+
logger.info(`Lattice Gateway is running on port: ${target_port}`);
|
|
1531
|
+
const queueServiceConfig = config?.queueServiceConfig;
|
|
1532
|
+
if (queueServiceConfig) {
|
|
1533
|
+
setQueueServiceType(queueServiceConfig.type);
|
|
1534
|
+
if (queueServiceConfig.defaultStartPollingQueue) {
|
|
1535
|
+
const agentTaskConsumer = new AgentTaskConsumer(target_port);
|
|
1536
|
+
agentTaskConsumer.startPollingQueue();
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
961
1539
|
} catch (err) {
|
|
962
1540
|
logger.error("Server start failed", { error: err });
|
|
963
1541
|
process.exit(1);
|
|
@@ -967,7 +1545,8 @@ var LatticeGateway = {
|
|
|
967
1545
|
startAsHttpEndpoint: start,
|
|
968
1546
|
configureSwagger,
|
|
969
1547
|
registerLatticeRoutes,
|
|
970
|
-
app
|
|
1548
|
+
app,
|
|
1549
|
+
AgentTaskConsumer
|
|
971
1550
|
};
|
|
972
1551
|
// Annotate the CommonJS export names for ESM import in node:
|
|
973
1552
|
0 && (module.exports = {
|