@dofe/infra-shared-services 0.1.7 → 0.1.9
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/agentx/agentx-client.module.d.ts +10 -0
- package/dist/agentx/agentx-client.module.d.ts.map +1 -0
- package/dist/agentx/agentx-client.module.js +38 -0
- package/dist/agentx/agentx-client.module.js.map +1 -0
- package/dist/agentx/agentx-client.service.d.ts +570 -0
- package/dist/agentx/agentx-client.service.d.ts.map +1 -0
- package/dist/agentx/agentx-client.service.js +912 -0
- package/dist/agentx/agentx-client.service.js.map +1 -0
- package/dist/agentx/agentx-file-client.service.d.ts +48 -0
- package/dist/agentx/agentx-file-client.service.d.ts.map +1 -0
- package/dist/agentx/agentx-file-client.service.js +277 -0
- package/dist/agentx/agentx-file-client.service.js.map +1 -0
- package/dist/agentx/index.d.ts +9 -0
- package/dist/agentx/index.d.ts.map +1 -0
- package/dist/agentx/index.js +27 -0
- package/dist/agentx/index.js.map +1 -0
- package/dist/agentx/interfaces/file.interface.d.ts +21 -0
- package/dist/agentx/interfaces/file.interface.d.ts.map +1 -0
- package/dist/agentx/interfaces/file.interface.js +22 -0
- package/dist/agentx/interfaces/file.interface.js.map +1 -0
- package/dist/agentx/interfaces/task.interface.d.ts +74 -0
- package/dist/agentx/interfaces/task.interface.d.ts.map +1 -0
- package/dist/agentx/interfaces/task.interface.js +16 -0
- package/dist/agentx/interfaces/task.interface.js.map +1 -0
- package/dist/email/email.module.js +2 -2
- package/dist/email/email.module.js.map +1 -1
- package/dist/email/email.service.d.ts +1 -1
- package/dist/email/email.service.d.ts.map +1 -1
- package/dist/email/email.service.js +4 -4
- package/dist/email/email.service.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ocr/ocr.module.js +2 -2
- package/dist/ocr/ocr.module.js.map +1 -1
- package/dist/ocr/ocr.service.d.ts +1 -1
- package/dist/ocr/ocr.service.d.ts.map +1 -1
- package/dist/ocr/ocr.service.js +2 -2
- package/dist/ocr/ocr.service.js.map +1 -1
- package/dist/sms/sms.module.js +2 -2
- package/dist/sms/sms.module.js.map +1 -1
- package/dist/sms/sms.service.d.ts +1 -1
- package/dist/sms/sms.service.d.ts.map +1 -1
- package/dist/sms/sms.service.js +2 -2
- package/dist/sms/sms.service.js.map +1 -1
- package/dist/verify/index.d.ts +3 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +19 -0
- package/dist/verify/index.js.map +1 -0
- package/dist/verify/verify.client.d.ts +12 -0
- package/dist/verify/verify.client.d.ts.map +1 -0
- package/dist/verify/verify.client.js +57 -0
- package/dist/verify/verify.client.js.map +1 -0
- package/dist/verify/verify.module.d.ts +3 -0
- package/dist/verify/verify.module.d.ts.map +1 -0
- package/dist/verify/verify.module.js +23 -0
- package/dist/verify/verify.module.js.map +1 -0
- package/package.json +8 -8
|
@@ -0,0 +1,912 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AgentXClient = exports.ImageGenerationResponseSchema = exports.ImageEditRequestSchema = exports.ImageGenerationRequestSchema = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const nest_winston_1 = require("nest-winston");
|
|
18
|
+
const winston_1 = require("winston");
|
|
19
|
+
const axios_1 = require("@nestjs/axios");
|
|
20
|
+
const config_1 = require("@nestjs/config");
|
|
21
|
+
const rxjs_1 = require("rxjs");
|
|
22
|
+
const zod_1 = require("zod");
|
|
23
|
+
const infra_common_1 = require("@dofe/infra-common");
|
|
24
|
+
const infra_common_2 = require("@dofe/infra-common");
|
|
25
|
+
const infra_utils_1 = require("@dofe/infra-utils");
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Types - Image Generation (Zod-first)
|
|
28
|
+
// ============================================================================
|
|
29
|
+
/**
|
|
30
|
+
* 图像生成请求 Schema
|
|
31
|
+
*/
|
|
32
|
+
exports.ImageGenerationRequestSchema = zod_1.z.object({
|
|
33
|
+
model: zod_1.z.string().min(1, '模型名称不能为空'),
|
|
34
|
+
prompt: zod_1.z.string().min(1, '提示词不能为空'),
|
|
35
|
+
n: zod_1.z.number().int().positive().optional().default(1),
|
|
36
|
+
response_format: zod_1.z
|
|
37
|
+
.enum(['url', 'b64_json'])
|
|
38
|
+
.optional()
|
|
39
|
+
.default('url'),
|
|
40
|
+
aspect_ratio: zod_1.z.string().optional(),
|
|
41
|
+
image_size: zod_1.z.string().optional(),
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* 图像编辑请求 Schema
|
|
45
|
+
*/
|
|
46
|
+
exports.ImageEditRequestSchema = exports.ImageGenerationRequestSchema.extend({
|
|
47
|
+
image: zod_1.z
|
|
48
|
+
.array(zod_1.z.string().url('图片URL格式不正确'))
|
|
49
|
+
.min(1, '至少需要一张图片'),
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* 图像生成响应 Schema
|
|
53
|
+
*/
|
|
54
|
+
exports.ImageGenerationResponseSchema = zod_1.z.object({
|
|
55
|
+
data: zod_1.z.array(zod_1.z.object({
|
|
56
|
+
url: zod_1.z.string().url().optional(),
|
|
57
|
+
b64_json: zod_1.z.string().optional().nullable(),
|
|
58
|
+
})),
|
|
59
|
+
created: zod_1.z.number().int(),
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* AgentX Internal Client
|
|
63
|
+
*
|
|
64
|
+
* 封装所有与 Python AgentX API 的交互
|
|
65
|
+
* - 统一的 HTTP 请求处理
|
|
66
|
+
* - 统一的错误处理和重试机制
|
|
67
|
+
* - 统一的超时管理
|
|
68
|
+
* - 统一的 callback URL 管理
|
|
69
|
+
* - 协同过滤推荐
|
|
70
|
+
* - 健康检查
|
|
71
|
+
*/
|
|
72
|
+
let AgentXClient = class AgentXClient {
|
|
73
|
+
logger;
|
|
74
|
+
httpService;
|
|
75
|
+
configService;
|
|
76
|
+
baseUrl = '';
|
|
77
|
+
internalApiUrl = '';
|
|
78
|
+
agentxConfig;
|
|
79
|
+
constructor(logger, httpService, configService) {
|
|
80
|
+
this.logger = logger;
|
|
81
|
+
this.httpService = httpService;
|
|
82
|
+
this.configService = configService;
|
|
83
|
+
}
|
|
84
|
+
onModuleInit() {
|
|
85
|
+
const keysConfig = (0, infra_common_1.getKeysConfig)();
|
|
86
|
+
this.agentxConfig = keysConfig?.agentx;
|
|
87
|
+
this.baseUrl = this.agentxConfig?.baseUrl || '';
|
|
88
|
+
if (!this.baseUrl) {
|
|
89
|
+
throw new Error('AgentXClient: baseUrl not configured');
|
|
90
|
+
}
|
|
91
|
+
// 初始化 internalApiUrl 用于 callback
|
|
92
|
+
this.internalApiUrl = infra_utils_1.environmentUtil
|
|
93
|
+
.generateEnvironmentUrls()
|
|
94
|
+
.internalApi.replace(/\/+$/, ''); // 去除末尾斜杠
|
|
95
|
+
this.logger.info(`AgentX Client initialized with baseUrl: ${this.baseUrl}`);
|
|
96
|
+
this.logger.info(`Callback URL: ${this.internalApiUrl}/webhook/python-task`);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 获取包含认证头的请求配置
|
|
100
|
+
*/
|
|
101
|
+
getAuthHeaders(additionalHeaders = {}) {
|
|
102
|
+
return {
|
|
103
|
+
...additionalHeaders,
|
|
104
|
+
...infra_common_2.AgentXConfigHelper.getAuthHeaders(),
|
|
105
|
+
...{ 'Content-Type': 'application/json' },
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 创建 Python 任务
|
|
110
|
+
*
|
|
111
|
+
* @param request 创建任务请求参数
|
|
112
|
+
* @returns 任务 ID
|
|
113
|
+
*/
|
|
114
|
+
async createTask(request) {
|
|
115
|
+
this.logger.info(`Creating task: ${request.name}`);
|
|
116
|
+
// 自动添加统一的 callback URL(如果未提供)
|
|
117
|
+
const callbackUrl = request.callback || `${this.internalApiUrl}/webhook/python-task`;
|
|
118
|
+
try {
|
|
119
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}/task`, {
|
|
120
|
+
name: request.name,
|
|
121
|
+
params: request.params,
|
|
122
|
+
callback: callbackUrl,
|
|
123
|
+
}, {
|
|
124
|
+
headers: this.getAuthHeaders(),
|
|
125
|
+
timeout: 30000, // 30 秒超时
|
|
126
|
+
}));
|
|
127
|
+
const taskId = response.data.id;
|
|
128
|
+
this.logger.info(`Task created successfully: ${taskId}, callback: ${callbackUrl}`);
|
|
129
|
+
return taskId;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
this.handleError('createTask', error, {
|
|
133
|
+
taskName: request.name,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 查询任务状态
|
|
139
|
+
*
|
|
140
|
+
* @param taskId 任务 ID
|
|
141
|
+
* @returns 任务状态信息
|
|
142
|
+
*/
|
|
143
|
+
async getTaskStatus(taskId) {
|
|
144
|
+
this.logger.debug(`Getting task status: ${taskId}`);
|
|
145
|
+
try {
|
|
146
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}/task/${taskId}`, {
|
|
147
|
+
headers: this.getAuthHeaders(),
|
|
148
|
+
timeout: 10000, // 10 秒超时
|
|
149
|
+
}));
|
|
150
|
+
return response.data;
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
this.handleError('getTaskStatus', error, { taskId });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 取消任务
|
|
158
|
+
*
|
|
159
|
+
* @param taskId 任务 ID
|
|
160
|
+
* @returns 取消结果
|
|
161
|
+
*/
|
|
162
|
+
async cancelTask(taskId) {
|
|
163
|
+
this.logger.info(`Cancelling task: ${taskId}`);
|
|
164
|
+
try {
|
|
165
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.delete(`${this.baseUrl}/task/${taskId}`, {
|
|
166
|
+
headers: this.getAuthHeaders(),
|
|
167
|
+
timeout: 10000, // 10 秒超时
|
|
168
|
+
}));
|
|
169
|
+
this.logger.info(`Task cancelled successfully: ${taskId}`);
|
|
170
|
+
return response.data;
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
this.handleError('cancelTask', error, { taskId });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* 统一错误处理
|
|
178
|
+
*
|
|
179
|
+
* @param operation 操作名称
|
|
180
|
+
* @param error Axios 错误对象
|
|
181
|
+
* @param context 上下文信息
|
|
182
|
+
*/
|
|
183
|
+
handleError(operation, error, context) {
|
|
184
|
+
const errorMessage = this.extractErrorMessage(error);
|
|
185
|
+
const statusCode = error.response?.status;
|
|
186
|
+
this.logger.error(`AgentX API Error [${operation}]: ${errorMessage}`, {
|
|
187
|
+
statusCode,
|
|
188
|
+
context,
|
|
189
|
+
responseData: error.response?.data,
|
|
190
|
+
});
|
|
191
|
+
// 根据 HTTP 状态码抛出不同的错误
|
|
192
|
+
if (statusCode === 404) {
|
|
193
|
+
throw new Error(`Task not found: ${context?.taskId || 'unknown'}`);
|
|
194
|
+
}
|
|
195
|
+
else if (statusCode === 400) {
|
|
196
|
+
throw new Error(`Invalid request: ${errorMessage}`);
|
|
197
|
+
}
|
|
198
|
+
else if (statusCode === 500) {
|
|
199
|
+
throw new Error(`AgentX server error: ${errorMessage}`);
|
|
200
|
+
}
|
|
201
|
+
else if (statusCode === 503) {
|
|
202
|
+
throw new Error(`AgentX service unavailable: ${errorMessage}`);
|
|
203
|
+
}
|
|
204
|
+
else if (error.code === 'ECONNREFUSED') {
|
|
205
|
+
throw new Error(`Cannot connect to AgentX server: ${this.baseUrl}`);
|
|
206
|
+
}
|
|
207
|
+
else if (error.code === 'ETIMEDOUT') {
|
|
208
|
+
throw new Error(`AgentX request timeout: ${operation}`);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
throw new Error(`AgentX API error: ${errorMessage}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* 提取错误消息
|
|
216
|
+
*
|
|
217
|
+
* @param error Axios 错误对象
|
|
218
|
+
* @returns 错误消息
|
|
219
|
+
*/
|
|
220
|
+
extractErrorMessage(error) {
|
|
221
|
+
if (error.response?.data) {
|
|
222
|
+
const data = error.response.data;
|
|
223
|
+
return data.message || data.error || data.detail || 'Unknown error';
|
|
224
|
+
}
|
|
225
|
+
return error.message || 'Unknown error';
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* 通用 GET 请求
|
|
229
|
+
*/
|
|
230
|
+
async get(url, config) {
|
|
231
|
+
try {
|
|
232
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}${url}`, config));
|
|
233
|
+
return response.data;
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
this.handleError('get', error, { url });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 通用 POST 请求
|
|
241
|
+
*/
|
|
242
|
+
async post(url, data, config) {
|
|
243
|
+
try {
|
|
244
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${url}`, data, config));
|
|
245
|
+
return response.data;
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
this.handleError('post', error, { url });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 通用 PUT 请求
|
|
253
|
+
*/
|
|
254
|
+
async put(url, data, config) {
|
|
255
|
+
try {
|
|
256
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.put(`${this.baseUrl}${url}`, data, config));
|
|
257
|
+
return response.data;
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
this.handleError('put', error, { url });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* 通用 DELETE 请求
|
|
265
|
+
*/
|
|
266
|
+
async delete(url, config) {
|
|
267
|
+
try {
|
|
268
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.delete(`${this.baseUrl}${url}`, config));
|
|
269
|
+
return response.data;
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
this.handleError('delete', error, { url });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* 检查 AgentX 服务是否可用
|
|
277
|
+
*
|
|
278
|
+
* @returns 是否可用
|
|
279
|
+
*/
|
|
280
|
+
async isHealthy() {
|
|
281
|
+
try {
|
|
282
|
+
await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}/health`, {
|
|
283
|
+
timeout: 5000,
|
|
284
|
+
}));
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
this.logger.warn('AgentX health check failed', {
|
|
289
|
+
error: error.message,
|
|
290
|
+
});
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* 健康检查(别名方法,兼容旧代码)
|
|
296
|
+
*/
|
|
297
|
+
async healthCheck() {
|
|
298
|
+
return this.isHealthy();
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* 生成协同过滤推荐
|
|
302
|
+
*
|
|
303
|
+
* @param request - 推荐请求参数
|
|
304
|
+
* @returns 推荐结果
|
|
305
|
+
* @throws 如果 AgentX 服务不可用或返回错误
|
|
306
|
+
*/
|
|
307
|
+
async generateCollaborativeRecommendations(request) {
|
|
308
|
+
const endpoint = '/api/recommendation/collaborative';
|
|
309
|
+
try {
|
|
310
|
+
this.logger.info('[AgentX] Generating collaborative recommendations', {
|
|
311
|
+
teamId: request.team_id,
|
|
312
|
+
userId: request.user_id,
|
|
313
|
+
algorithm: request.algorithm || 'hybrid',
|
|
314
|
+
});
|
|
315
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, request, {
|
|
316
|
+
headers: this.getAuthHeaders(),
|
|
317
|
+
timeout: 30000,
|
|
318
|
+
}));
|
|
319
|
+
this.logger.info('[AgentX] Collaborative recommendations generated', {
|
|
320
|
+
total: response.data.total,
|
|
321
|
+
executionTime: response.data.execution_time_ms,
|
|
322
|
+
});
|
|
323
|
+
return response.data;
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
this.logger.error('[AgentX] Failed to generate collaborative recommendations', {
|
|
327
|
+
error: error.message,
|
|
328
|
+
teamId: request.team_id,
|
|
329
|
+
userId: request.user_id,
|
|
330
|
+
});
|
|
331
|
+
throw new Error(`AgentX collaborative recommendation failed: ${error.message}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* 生成产品关键词
|
|
336
|
+
*
|
|
337
|
+
* @param request - 关键词生成请求参数
|
|
338
|
+
* @returns 关键词数组
|
|
339
|
+
* @throws 如果 AgentX 服务不可用或返回错误
|
|
340
|
+
*/
|
|
341
|
+
async generateProductKeywords(request) {
|
|
342
|
+
const endpoint = '/api/ai/keywords';
|
|
343
|
+
try {
|
|
344
|
+
this.logger.info('[AgentX] Generating product keywords', {
|
|
345
|
+
productName: request.productName,
|
|
346
|
+
});
|
|
347
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, {
|
|
348
|
+
product_name: request.productName,
|
|
349
|
+
product_selling_points: request.productSellingPoints,
|
|
350
|
+
}, {
|
|
351
|
+
headers: this.getAuthHeaders(),
|
|
352
|
+
timeout: 30000,
|
|
353
|
+
}));
|
|
354
|
+
this.logger.info('[AgentX] Product keywords generated', {
|
|
355
|
+
count: response.data.keywords.length,
|
|
356
|
+
});
|
|
357
|
+
return response.data.keywords;
|
|
358
|
+
}
|
|
359
|
+
catch (error) {
|
|
360
|
+
this.logger.error('[AgentX] Failed to generate product keywords', {
|
|
361
|
+
error: error.message,
|
|
362
|
+
productName: request.productName,
|
|
363
|
+
});
|
|
364
|
+
throw new Error(`AgentX product keywords generation failed: ${error.message}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* LLM Chat Completion
|
|
369
|
+
*
|
|
370
|
+
* @param request - LLM 请求参数
|
|
371
|
+
* @returns LLM 响应
|
|
372
|
+
* @throws 如果 AgentX 服务不可用或返回错误
|
|
373
|
+
*/
|
|
374
|
+
async chatCompletion(request) {
|
|
375
|
+
const endpoint = '/ai/v1/chat/completions';
|
|
376
|
+
try {
|
|
377
|
+
this.logger.info('[AgentX] Calling LLM chat completion', {
|
|
378
|
+
model: request.model,
|
|
379
|
+
messageCount: request.messages.length,
|
|
380
|
+
});
|
|
381
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, request, {
|
|
382
|
+
headers: this.getAuthHeaders(),
|
|
383
|
+
timeout: 120000, // 2分钟超时
|
|
384
|
+
}));
|
|
385
|
+
this.logger.info('[AgentX] LLM chat completion successful', {
|
|
386
|
+
model: request.model,
|
|
387
|
+
finishReason: response.data.choices?.[0]?.finish_reason,
|
|
388
|
+
});
|
|
389
|
+
return response.data;
|
|
390
|
+
}
|
|
391
|
+
catch (error) {
|
|
392
|
+
this.logger.error('[AgentX] LLM chat completion failed', {
|
|
393
|
+
error: error.message,
|
|
394
|
+
model: request.model,
|
|
395
|
+
});
|
|
396
|
+
throw new Error(`AgentX LLM chat completion failed: ${error.message}`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* 生成图像
|
|
401
|
+
*
|
|
402
|
+
* @param request - 图像生成请求参数
|
|
403
|
+
* @returns 图像生成响应
|
|
404
|
+
* @throws 如果 AgentX 服务不可用或返回错误
|
|
405
|
+
*/
|
|
406
|
+
async generateImage(request) {
|
|
407
|
+
const endpoint = '/ai/v1/images/generations';
|
|
408
|
+
try {
|
|
409
|
+
// Zod 验证请求参数
|
|
410
|
+
const validatedRequest = exports.ImageGenerationRequestSchema.parse(request);
|
|
411
|
+
this.logger.info('[AgentX] Generating image', {
|
|
412
|
+
model: validatedRequest.model,
|
|
413
|
+
prompt: validatedRequest.prompt.substring(0, 50),
|
|
414
|
+
});
|
|
415
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, {
|
|
416
|
+
model: validatedRequest.model,
|
|
417
|
+
prompt: validatedRequest.prompt,
|
|
418
|
+
n: validatedRequest.n,
|
|
419
|
+
response_format: validatedRequest.response_format,
|
|
420
|
+
aspect_ratio: validatedRequest.aspect_ratio,
|
|
421
|
+
image_size: validatedRequest.image_size,
|
|
422
|
+
}, {
|
|
423
|
+
headers: this.getAuthHeaders(),
|
|
424
|
+
timeout: 120000, // 2分钟超时
|
|
425
|
+
}));
|
|
426
|
+
// Zod 验证响应数据
|
|
427
|
+
const validatedResponse = exports.ImageGenerationResponseSchema.parse(response.data);
|
|
428
|
+
this.logger.info('[AgentX] Image generated successfully', {
|
|
429
|
+
model: validatedRequest.model,
|
|
430
|
+
imageCount: validatedResponse.data.length,
|
|
431
|
+
});
|
|
432
|
+
return validatedResponse;
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
if (error instanceof zod_1.z.ZodError) {
|
|
436
|
+
this.logger.error('[AgentX] Image generation validation failed', {
|
|
437
|
+
errors: error.issues,
|
|
438
|
+
});
|
|
439
|
+
throw new Error(`AgentX image generation validation failed: ${error.issues.map((e) => e.message).join(', ')}`);
|
|
440
|
+
}
|
|
441
|
+
this.logger.error('[AgentX] Image generation failed', {
|
|
442
|
+
error: error.message,
|
|
443
|
+
model: request.model,
|
|
444
|
+
});
|
|
445
|
+
throw new Error(`AgentX image generation failed: ${error.message}`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* 编辑图像
|
|
450
|
+
*
|
|
451
|
+
* @param request - 图像编辑请求参数
|
|
452
|
+
* @returns 图像生成响应
|
|
453
|
+
* @throws 如果 AgentX 服务不可用或返回错误
|
|
454
|
+
*/
|
|
455
|
+
async editImage(request) {
|
|
456
|
+
const endpoint = '/ai/v1/images/edits';
|
|
457
|
+
try {
|
|
458
|
+
// Zod 验证请求参数
|
|
459
|
+
const validatedRequest = exports.ImageEditRequestSchema.parse(request);
|
|
460
|
+
this.logger.info('[AgentX] Editing image', {
|
|
461
|
+
model: validatedRequest.model,
|
|
462
|
+
prompt: validatedRequest.prompt.substring(0, 50),
|
|
463
|
+
imageCount: validatedRequest.image.length,
|
|
464
|
+
});
|
|
465
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, {
|
|
466
|
+
model: validatedRequest.model,
|
|
467
|
+
image: validatedRequest.image,
|
|
468
|
+
prompt: validatedRequest.prompt,
|
|
469
|
+
response_format: validatedRequest.response_format,
|
|
470
|
+
aspect_ratio: validatedRequest.aspect_ratio,
|
|
471
|
+
image_size: validatedRequest.image_size,
|
|
472
|
+
}, {
|
|
473
|
+
headers: this.getAuthHeaders(),
|
|
474
|
+
timeout: 120000,
|
|
475
|
+
}));
|
|
476
|
+
// Zod 验证响应数据
|
|
477
|
+
const validatedResponse = exports.ImageGenerationResponseSchema.parse(response.data);
|
|
478
|
+
this.logger.info('[AgentX] Image edited successfully', {
|
|
479
|
+
model: validatedRequest.model,
|
|
480
|
+
imageCount: validatedResponse.data.length,
|
|
481
|
+
});
|
|
482
|
+
return validatedResponse;
|
|
483
|
+
}
|
|
484
|
+
catch (error) {
|
|
485
|
+
if (error instanceof zod_1.z.ZodError) {
|
|
486
|
+
this.logger.error('[AgentX] Image editing validation failed', {
|
|
487
|
+
errors: error.issues,
|
|
488
|
+
});
|
|
489
|
+
throw new Error(`AgentX image editing validation failed: ${error.issues.map((e) => e.message).join(', ')}`);
|
|
490
|
+
}
|
|
491
|
+
this.logger.error('[AgentX] Image editing failed', {
|
|
492
|
+
error: error.message,
|
|
493
|
+
model: request.model,
|
|
494
|
+
});
|
|
495
|
+
throw new Error(`AgentX image editing failed: ${error.message}`);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
// ============================================================================
|
|
499
|
+
// Memory Management APIs
|
|
500
|
+
// ============================================================================
|
|
501
|
+
/**
|
|
502
|
+
* 创建对话记忆
|
|
503
|
+
*/
|
|
504
|
+
async createConversationMemory(request) {
|
|
505
|
+
const endpoint = '/api/memory/conversations';
|
|
506
|
+
try {
|
|
507
|
+
this.logger.info('[AgentX] Creating conversation memory', {
|
|
508
|
+
teamId: request.team_id,
|
|
509
|
+
userId: request.user_id,
|
|
510
|
+
sessionId: request.session_id,
|
|
511
|
+
});
|
|
512
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, request, {
|
|
513
|
+
headers: this.getAuthHeaders(),
|
|
514
|
+
timeout: 30000,
|
|
515
|
+
}));
|
|
516
|
+
this.logger.info('[AgentX] Conversation memory created', {
|
|
517
|
+
memoryId: response.data.memory_id,
|
|
518
|
+
});
|
|
519
|
+
return response.data;
|
|
520
|
+
}
|
|
521
|
+
catch (error) {
|
|
522
|
+
this.handleError('createConversationMemory', error, {
|
|
523
|
+
teamId: request.team_id,
|
|
524
|
+
userId: request.user_id,
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* 创建任务记忆
|
|
530
|
+
*/
|
|
531
|
+
async createTaskMemory(request) {
|
|
532
|
+
const endpoint = '/api/memory/tasks';
|
|
533
|
+
try {
|
|
534
|
+
this.logger.info('[AgentX] Creating task memory', {
|
|
535
|
+
taskId: request.task_id,
|
|
536
|
+
taskName: request.task_name,
|
|
537
|
+
});
|
|
538
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, {
|
|
539
|
+
...request,
|
|
540
|
+
task_result: JSON.stringify(request.task_result),
|
|
541
|
+
}, {
|
|
542
|
+
headers: this.getAuthHeaders(),
|
|
543
|
+
timeout: 30000,
|
|
544
|
+
}));
|
|
545
|
+
return response.data;
|
|
546
|
+
}
|
|
547
|
+
catch (error) {
|
|
548
|
+
this.handleError('createTaskMemory', error, {
|
|
549
|
+
taskId: request.task_id,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* 创建决策记忆
|
|
555
|
+
*/
|
|
556
|
+
async createDecisionMemory(request) {
|
|
557
|
+
const endpoint = '/api/memory/decisions';
|
|
558
|
+
try {
|
|
559
|
+
this.logger.info('[AgentX] Creating decision memory', {
|
|
560
|
+
userId: request.user_id,
|
|
561
|
+
workflowId: request.workflow_id,
|
|
562
|
+
});
|
|
563
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, {
|
|
564
|
+
...request,
|
|
565
|
+
decision_result: JSON.stringify(request.decision_result),
|
|
566
|
+
}, {
|
|
567
|
+
headers: this.getAuthHeaders(),
|
|
568
|
+
timeout: 30000,
|
|
569
|
+
}));
|
|
570
|
+
return response.data;
|
|
571
|
+
}
|
|
572
|
+
catch (error) {
|
|
573
|
+
this.handleError('createDecisionMemory', error, {
|
|
574
|
+
userId: request.user_id,
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* 搜索记忆 (GET)
|
|
580
|
+
*/
|
|
581
|
+
async searchMemories(params) {
|
|
582
|
+
const endpoint = '/api/memory/search';
|
|
583
|
+
try {
|
|
584
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}${endpoint}`, {
|
|
585
|
+
params,
|
|
586
|
+
headers: this.getAuthHeaders(),
|
|
587
|
+
timeout: 30000,
|
|
588
|
+
}));
|
|
589
|
+
return response.data;
|
|
590
|
+
}
|
|
591
|
+
catch (error) {
|
|
592
|
+
this.handleError('searchMemories', error, {
|
|
593
|
+
query: params.q,
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* 搜索记忆 (POST - 复杂查询)
|
|
599
|
+
*/
|
|
600
|
+
async searchMemoriesPost(data) {
|
|
601
|
+
const endpoint = '/api/memory/search';
|
|
602
|
+
try {
|
|
603
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, data, {
|
|
604
|
+
headers: this.getAuthHeaders(),
|
|
605
|
+
timeout: 30000,
|
|
606
|
+
}));
|
|
607
|
+
return response.data;
|
|
608
|
+
}
|
|
609
|
+
catch (error) {
|
|
610
|
+
this.handleError('searchMemoriesPost', error, {
|
|
611
|
+
query: data.query,
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* 获取记忆详情
|
|
617
|
+
*/
|
|
618
|
+
async getMemoryById(memoryId) {
|
|
619
|
+
const endpoint = `/api/memory/${memoryId}`;
|
|
620
|
+
try {
|
|
621
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}${endpoint}`, {
|
|
622
|
+
headers: this.getAuthHeaders(),
|
|
623
|
+
timeout: 10000,
|
|
624
|
+
}));
|
|
625
|
+
return response.data;
|
|
626
|
+
}
|
|
627
|
+
catch (error) {
|
|
628
|
+
this.handleError('getMemoryById', error, {
|
|
629
|
+
memoryId,
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* 删除记忆
|
|
635
|
+
*/
|
|
636
|
+
async deleteMemory(memoryId) {
|
|
637
|
+
const endpoint = `/api/memory/${memoryId}`;
|
|
638
|
+
try {
|
|
639
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.delete(`${this.baseUrl}${endpoint}`, {
|
|
640
|
+
headers: this.getAuthHeaders(),
|
|
641
|
+
timeout: 10000,
|
|
642
|
+
}));
|
|
643
|
+
return response.data;
|
|
644
|
+
}
|
|
645
|
+
catch (error) {
|
|
646
|
+
this.handleError('deleteMemory', error, {
|
|
647
|
+
memoryId,
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* 获取记忆列表
|
|
653
|
+
*/
|
|
654
|
+
async listMemories(params) {
|
|
655
|
+
const endpoint = '/api/memory/list';
|
|
656
|
+
try {
|
|
657
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}${endpoint}`, {
|
|
658
|
+
params,
|
|
659
|
+
headers: this.getAuthHeaders(),
|
|
660
|
+
timeout: 30000,
|
|
661
|
+
}));
|
|
662
|
+
return response.data;
|
|
663
|
+
}
|
|
664
|
+
catch (error) {
|
|
665
|
+
this.handleError('listMemories', error, {
|
|
666
|
+
userId: params.user_id,
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* 获取记忆统计
|
|
672
|
+
*/
|
|
673
|
+
async getMemoryStats(params) {
|
|
674
|
+
const endpoint = '/api/memory/stats';
|
|
675
|
+
try {
|
|
676
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}${endpoint}`, {
|
|
677
|
+
params,
|
|
678
|
+
headers: this.getAuthHeaders(),
|
|
679
|
+
timeout: 30000,
|
|
680
|
+
}));
|
|
681
|
+
return response.data;
|
|
682
|
+
}
|
|
683
|
+
catch (error) {
|
|
684
|
+
this.handleError('getMemoryStats', error, {
|
|
685
|
+
userId: params.user_id,
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* 获取会话历史
|
|
691
|
+
*/
|
|
692
|
+
async getSessionHistory(sessionId) {
|
|
693
|
+
const endpoint = `/api/memory/sessions/${sessionId}`;
|
|
694
|
+
try {
|
|
695
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}${endpoint}`, {
|
|
696
|
+
headers: this.getAuthHeaders(),
|
|
697
|
+
timeout: 30000,
|
|
698
|
+
}));
|
|
699
|
+
return response.data;
|
|
700
|
+
}
|
|
701
|
+
catch (error) {
|
|
702
|
+
this.handleError('getSessionHistory', error, {
|
|
703
|
+
sessionId,
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
// ============================================================================
|
|
708
|
+
// Preference Management APIs
|
|
709
|
+
// ============================================================================
|
|
710
|
+
/**
|
|
711
|
+
* 推断用户偏好
|
|
712
|
+
*/
|
|
713
|
+
async inferPreference(request) {
|
|
714
|
+
const endpoint = '/preferences/infer';
|
|
715
|
+
try {
|
|
716
|
+
this.logger.info('[AgentX] Inferring user preference', {
|
|
717
|
+
teamId: request.team_id,
|
|
718
|
+
userId: request.user_id,
|
|
719
|
+
category: request.category,
|
|
720
|
+
});
|
|
721
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(`${this.baseUrl}${endpoint}`, request, {
|
|
722
|
+
headers: this.getAuthHeaders(),
|
|
723
|
+
timeout: 30000,
|
|
724
|
+
}));
|
|
725
|
+
return response.data;
|
|
726
|
+
}
|
|
727
|
+
catch (error) {
|
|
728
|
+
this.handleError('inferPreference', error, {
|
|
729
|
+
teamId: request.team_id,
|
|
730
|
+
userId: request.user_id,
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* 获取用户偏好
|
|
736
|
+
*/
|
|
737
|
+
async getUserPreferences(params) {
|
|
738
|
+
const endpoint = '/preferences';
|
|
739
|
+
try {
|
|
740
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}${endpoint}`, {
|
|
741
|
+
params,
|
|
742
|
+
headers: this.getAuthHeaders(),
|
|
743
|
+
timeout: 30000,
|
|
744
|
+
}));
|
|
745
|
+
return response.data;
|
|
746
|
+
}
|
|
747
|
+
catch (error) {
|
|
748
|
+
this.handleError('getUserPreferences', error, {
|
|
749
|
+
userId: params.user_id,
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* 更新用户偏好
|
|
755
|
+
*/
|
|
756
|
+
async updatePreference(preferenceId, data) {
|
|
757
|
+
const endpoint = `/preferences/${preferenceId}`;
|
|
758
|
+
try {
|
|
759
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.put(`${this.baseUrl}${endpoint}`, data, {
|
|
760
|
+
headers: this.getAuthHeaders(),
|
|
761
|
+
timeout: 30000,
|
|
762
|
+
}));
|
|
763
|
+
return response.data;
|
|
764
|
+
}
|
|
765
|
+
catch (error) {
|
|
766
|
+
this.handleError('updatePreference', error, {
|
|
767
|
+
preferenceId,
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* 删除用户偏好
|
|
773
|
+
*/
|
|
774
|
+
async deletePreference(preferenceId, params) {
|
|
775
|
+
const endpoint = `/preferences/${preferenceId}`;
|
|
776
|
+
try {
|
|
777
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.delete(`${this.baseUrl}${endpoint}`, {
|
|
778
|
+
params,
|
|
779
|
+
headers: this.getAuthHeaders(),
|
|
780
|
+
timeout: 10000,
|
|
781
|
+
}));
|
|
782
|
+
return response.data;
|
|
783
|
+
}
|
|
784
|
+
catch (error) {
|
|
785
|
+
this.handleError('deletePreference', error, {
|
|
786
|
+
preferenceId,
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* 获取偏好统计
|
|
792
|
+
*/
|
|
793
|
+
async getPreferenceStats(params) {
|
|
794
|
+
const endpoint = '/preferences/stats';
|
|
795
|
+
try {
|
|
796
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(`${this.baseUrl}${endpoint}`, {
|
|
797
|
+
params,
|
|
798
|
+
headers: this.getAuthHeaders(),
|
|
799
|
+
timeout: 30000,
|
|
800
|
+
}));
|
|
801
|
+
return response.data;
|
|
802
|
+
}
|
|
803
|
+
catch (error) {
|
|
804
|
+
this.handleError('getPreferenceStats', error, {
|
|
805
|
+
userId: params.user_id,
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
// ============================================================================
|
|
810
|
+
// SSE Monitoring
|
|
811
|
+
// ============================================================================
|
|
812
|
+
/**
|
|
813
|
+
* 使用 SSE 监控任务进度
|
|
814
|
+
* @param taskId 任务ID
|
|
815
|
+
* @returns Promise that resolves when task completes
|
|
816
|
+
*/
|
|
817
|
+
async monitorTaskWithSSE(taskId) {
|
|
818
|
+
return new Promise((resolve, reject) => {
|
|
819
|
+
let eventSource = null;
|
|
820
|
+
// 清理函数,确保连接被正确关闭
|
|
821
|
+
const cleanup = () => {
|
|
822
|
+
if (eventSource) {
|
|
823
|
+
eventSource.close();
|
|
824
|
+
eventSource = null;
|
|
825
|
+
this.logger.info('SSE connection closed');
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
try {
|
|
829
|
+
const { EventSource } = require('eventsource');
|
|
830
|
+
eventSource = new EventSource(`${this.baseUrl}/task/${taskId}/sse`);
|
|
831
|
+
eventSource.onmessage = (event) => {
|
|
832
|
+
try {
|
|
833
|
+
const data = JSON.parse(event.data);
|
|
834
|
+
const progress = data.progress ?? 0;
|
|
835
|
+
const currentStep = data.current_step ?? 'Processing';
|
|
836
|
+
this.logger.debug(`Task progress: ${progress}% - ${currentStep}`);
|
|
837
|
+
if (data.ready) {
|
|
838
|
+
cleanup();
|
|
839
|
+
if (data.state === 'SUCCESS') {
|
|
840
|
+
this.logger.info(`Task ${taskId} completed successfully`);
|
|
841
|
+
resolve(data);
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
this.logger.error(`Task ${taskId} failed: ${data.error}`);
|
|
845
|
+
reject(new Error(data.error || 'Task failed'));
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
catch (error) {
|
|
850
|
+
this.logger.error('Failed to parse SSE data', error);
|
|
851
|
+
cleanup();
|
|
852
|
+
reject(new Error('Failed to parse SSE data'));
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
eventSource.onerror = (error) => {
|
|
856
|
+
cleanup();
|
|
857
|
+
this.logger.warn('SSE connection error, falling back to polling');
|
|
858
|
+
// Fallback to polling
|
|
859
|
+
this.pollTaskStatus(taskId).then(resolve).catch(reject);
|
|
860
|
+
};
|
|
861
|
+
eventSource.onopen = () => {
|
|
862
|
+
this.logger.info(`SSE connection established for ${taskId}`);
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
catch (error) {
|
|
866
|
+
this.logger.warn('SSE not available, using polling mode');
|
|
867
|
+
this.pollTaskStatus(taskId).then(resolve).catch(reject);
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* 轮询任务状态(SSE 失败时的降级方案)
|
|
873
|
+
*/
|
|
874
|
+
async pollTaskStatus(taskId, timeout = 300000, checkInterval = 3000) {
|
|
875
|
+
this.logger.info(`Polling task status: ${taskId}`);
|
|
876
|
+
const startTime = Date.now();
|
|
877
|
+
while (Date.now() - startTime < timeout) {
|
|
878
|
+
const result = await this.getTaskStatus(taskId);
|
|
879
|
+
const state = result.state ?? 'UNKNOWN';
|
|
880
|
+
const progress = result.progress ?? 0;
|
|
881
|
+
const currentStep = result.current_step ?? 'Processing';
|
|
882
|
+
this.logger.debug(`Task progress: ${progress}% - ${currentStep} - ${state}`);
|
|
883
|
+
if (result.ready) {
|
|
884
|
+
if (state === 'SUCCESS') {
|
|
885
|
+
this.logger.info(`Task ${taskId} completed successfully`);
|
|
886
|
+
return result;
|
|
887
|
+
}
|
|
888
|
+
else {
|
|
889
|
+
const errorMsg = result.error ?? 'Task failed';
|
|
890
|
+
throw new Error(`Task failed: ${errorMsg}`);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
await this.sleep(checkInterval);
|
|
894
|
+
}
|
|
895
|
+
throw new Error(`Task timeout: ${taskId}`);
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* 睡眠函数
|
|
899
|
+
*/
|
|
900
|
+
sleep(ms) {
|
|
901
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
exports.AgentXClient = AgentXClient;
|
|
905
|
+
exports.AgentXClient = AgentXClient = __decorate([
|
|
906
|
+
(0, common_1.Injectable)(),
|
|
907
|
+
__param(0, (0, common_1.Inject)(nest_winston_1.WINSTON_MODULE_PROVIDER)),
|
|
908
|
+
__metadata("design:paramtypes", [winston_1.Logger,
|
|
909
|
+
axios_1.HttpService,
|
|
910
|
+
config_1.ConfigService])
|
|
911
|
+
], AgentXClient);
|
|
912
|
+
//# sourceMappingURL=agentx-client.service.js.map
|