@cicctencent/agent-midway 0.1.1

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.
Files changed (160) hide show
  1. package/README.md +280 -0
  2. package/dist/adapters/express.d.ts +8 -0
  3. package/dist/adapters/express.js +91 -0
  4. package/dist/adapters/index.d.ts +5 -0
  5. package/dist/adapters/index.js +21 -0
  6. package/dist/adapters/koa.d.ts +3 -0
  7. package/dist/adapters/koa.js +75 -0
  8. package/dist/adapters/midway.d.ts +5 -0
  9. package/dist/adapters/midway.js +11 -0
  10. package/dist/adapters/next.d.ts +12 -0
  11. package/dist/adapters/next.js +89 -0
  12. package/dist/adapters/shared.d.ts +4 -0
  13. package/dist/adapters/shared.js +31 -0
  14. package/dist/channel/dingtalk.d.ts +18 -0
  15. package/dist/channel/dingtalk.js +68 -0
  16. package/dist/channel/feishu.d.ts +20 -0
  17. package/dist/channel/feishu.js +96 -0
  18. package/dist/channel/index.d.ts +46 -0
  19. package/dist/channel/index.js +311 -0
  20. package/dist/channel/types.d.ts +77 -0
  21. package/dist/channel/types.js +7 -0
  22. package/dist/channel/wecom.d.ts +22 -0
  23. package/dist/channel/wecom.js +106 -0
  24. package/dist/component.d.ts +49 -0
  25. package/dist/component.js +129 -0
  26. package/dist/connector/calendar-adapter.d.ts +19 -0
  27. package/dist/connector/calendar-adapter.js +236 -0
  28. package/dist/connector/db-adapter.d.ts +28 -0
  29. package/dist/connector/db-adapter.js +193 -0
  30. package/dist/connector/email-adapter.d.ts +23 -0
  31. package/dist/connector/email-adapter.js +192 -0
  32. package/dist/connector/fs-adapter.d.ts +15 -0
  33. package/dist/connector/fs-adapter.js +199 -0
  34. package/dist/connector/http-adapter.d.ts +29 -0
  35. package/dist/connector/http-adapter.js +181 -0
  36. package/dist/connector/index.d.ts +24 -0
  37. package/dist/connector/index.js +454 -0
  38. package/dist/connector/mcp-adapter.d.ts +27 -0
  39. package/dist/connector/mcp-adapter.js +156 -0
  40. package/dist/connector/mq-adapter.d.ts +25 -0
  41. package/dist/connector/mq-adapter.js +181 -0
  42. package/dist/connector/types.d.ts +205 -0
  43. package/dist/connector/types.js +9 -0
  44. package/dist/controller/a2a.controller.d.ts +41 -0
  45. package/dist/controller/a2a.controller.js +150 -0
  46. package/dist/controller/agent-profile.controller.d.ts +97 -0
  47. package/dist/controller/agent-profile.controller.js +200 -0
  48. package/dist/controller/agent.controller.d.ts +199 -0
  49. package/dist/controller/agent.controller.js +414 -0
  50. package/dist/controller/application.controller.d.ts +113 -0
  51. package/dist/controller/application.controller.js +217 -0
  52. package/dist/controller/automation.controller.d.ts +113 -0
  53. package/dist/controller/automation.controller.js +246 -0
  54. package/dist/controller/channel.controller.d.ts +73 -0
  55. package/dist/controller/channel.controller.js +183 -0
  56. package/dist/controller/chat.controller.d.ts +188 -0
  57. package/dist/controller/chat.controller.js +375 -0
  58. package/dist/controller/connector.controller.d.ts +134 -0
  59. package/dist/controller/connector.controller.js +257 -0
  60. package/dist/controller/knowledge-base.controller.d.ts +157 -0
  61. package/dist/controller/knowledge-base.controller.js +278 -0
  62. package/dist/controller/mcp-server.controller.d.ts +115 -0
  63. package/dist/controller/mcp-server.controller.js +236 -0
  64. package/dist/controller/model-config.controller.d.ts +139 -0
  65. package/dist/controller/model-config.controller.js +274 -0
  66. package/dist/controller/observability.controller.d.ts +124 -0
  67. package/dist/controller/observability.controller.js +142 -0
  68. package/dist/controller/security.controller.d.ts +91 -0
  69. package/dist/controller/security.controller.js +172 -0
  70. package/dist/controller/settings.controller.d.ts +83 -0
  71. package/dist/controller/settings.controller.js +280 -0
  72. package/dist/core/ai-workstation.d.ts +17 -0
  73. package/dist/core/ai-workstation.js +129 -0
  74. package/dist/core/index.d.ts +4 -0
  75. package/dist/core/index.js +20 -0
  76. package/dist/core/service-container.d.ts +12 -0
  77. package/dist/core/service-container.js +54 -0
  78. package/dist/core/sse.d.ts +6 -0
  79. package/dist/core/sse.js +56 -0
  80. package/dist/core/types.d.ts +72 -0
  81. package/dist/core/types.js +2 -0
  82. package/dist/dto/agent.dto.d.ts +21 -0
  83. package/dist/dto/agent.dto.js +79 -0
  84. package/dist/dto/ai-config.dto.d.ts +67 -0
  85. package/dist/dto/ai-config.dto.js +249 -0
  86. package/dist/dto/chat.dto.d.ts +40 -0
  87. package/dist/dto/chat.dto.js +122 -0
  88. package/dist/index.d.ts +101 -0
  89. package/dist/index.js +195 -0
  90. package/dist/memory/db-store.d.ts +33 -0
  91. package/dist/memory/db-store.js +143 -0
  92. package/dist/memory/index.d.ts +187 -0
  93. package/dist/memory/index.js +443 -0
  94. package/dist/model/ai-agent-profile.entity.d.ts +32 -0
  95. package/dist/model/ai-agent-profile.entity.js +289 -0
  96. package/dist/model/ai-application.entity.d.ts +20 -0
  97. package/dist/model/ai-application.entity.js +166 -0
  98. package/dist/model/ai-chat-memory.entity.d.ts +16 -0
  99. package/dist/model/ai-chat-memory.entity.js +123 -0
  100. package/dist/model/ai-chat-message.entity.d.ts +16 -0
  101. package/dist/model/ai-chat-message.entity.js +122 -0
  102. package/dist/model/ai-chat-skill.entity.d.ts +19 -0
  103. package/dist/model/ai-chat-skill.entity.js +155 -0
  104. package/dist/model/ai-chat-thread.entity.d.ts +15 -0
  105. package/dist/model/ai-chat-thread.entity.js +113 -0
  106. package/dist/model/ai-chat-workspace.entity.d.ts +17 -0
  107. package/dist/model/ai-chat-workspace.entity.js +136 -0
  108. package/dist/model/ai-kb-document.entity.d.ts +16 -0
  109. package/dist/model/ai-kb-document.entity.js +122 -0
  110. package/dist/model/ai-knowledge-base.entity.d.ts +22 -0
  111. package/dist/model/ai-knowledge-base.entity.js +185 -0
  112. package/dist/model/ai-mcp-server.entity.d.ts +23 -0
  113. package/dist/model/ai-mcp-server.entity.js +198 -0
  114. package/dist/model/ai-model-config.entity.d.ts +24 -0
  115. package/dist/model/ai-model-config.entity.js +200 -0
  116. package/dist/service/a2a.service.d.ts +142 -0
  117. package/dist/service/a2a.service.js +537 -0
  118. package/dist/service/agent-profile.service.d.ts +34 -0
  119. package/dist/service/agent-profile.service.js +110 -0
  120. package/dist/service/agent-server.service.d.ts +91 -0
  121. package/dist/service/agent-server.service.js +634 -0
  122. package/dist/service/agent-task-queue.service.d.ts +98 -0
  123. package/dist/service/agent-task-queue.service.js +283 -0
  124. package/dist/service/ai-chat.service.d.ts +103 -0
  125. package/dist/service/ai-chat.service.js +431 -0
  126. package/dist/service/ai-skill.service.d.ts +116 -0
  127. package/dist/service/ai-skill.service.js +457 -0
  128. package/dist/service/application.service.d.ts +42 -0
  129. package/dist/service/application.service.js +139 -0
  130. package/dist/service/automation.service.d.ts +37 -0
  131. package/dist/service/automation.service.js +196 -0
  132. package/dist/service/connector.service.d.ts +136 -0
  133. package/dist/service/connector.service.js +524 -0
  134. package/dist/service/knowledge-base.service.d.ts +138 -0
  135. package/dist/service/knowledge-base.service.js +528 -0
  136. package/dist/service/mcp-server.service.d.ts +39 -0
  137. package/dist/service/mcp-server.service.js +143 -0
  138. package/dist/service/model-config.service.d.ts +57 -0
  139. package/dist/service/model-config.service.js +168 -0
  140. package/dist/service/observability.service.d.ts +145 -0
  141. package/dist/service/observability.service.js +281 -0
  142. package/dist/service/openai.service.d.ts +88 -0
  143. package/dist/service/openai.service.js +406 -0
  144. package/dist/service/prompt-builder.service.d.ts +50 -0
  145. package/dist/service/prompt-builder.service.js +246 -0
  146. package/dist/tools/code-exec.tool.d.ts +37 -0
  147. package/dist/tools/code-exec.tool.js +162 -0
  148. package/dist/tools/datetime.tool.d.ts +21 -0
  149. package/dist/tools/datetime.tool.js +379 -0
  150. package/dist/tools/http-request.tool.d.ts +43 -0
  151. package/dist/tools/http-request.tool.js +455 -0
  152. package/dist/tools/registry.d.ts +71 -0
  153. package/dist/tools/registry.js +77 -0
  154. package/dist/tools/text-process.tool.d.ts +7 -0
  155. package/dist/tools/text-process.tool.js +366 -0
  156. package/dist/tools/web-search.tool.d.ts +28 -0
  157. package/dist/tools/web-search.tool.js +304 -0
  158. package/dist/types.d.ts +70 -0
  159. package/dist/types.js +7 -0
  160. package/package.json +69 -0
@@ -0,0 +1,634 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ 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;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.AgentServerService = void 0;
46
+ /**
47
+ * AgentServerService — 封装 @cicctencent/agent-server 的 MidwayJS 服务
48
+ *
49
+ * 作为 work 项目与 agent-server 之间的桥梁:
50
+ * - 初始化时创建 AgentServer 实例(注入 TypeORM Provider + 工具)
51
+ * - 对外暴露 runAgentStream() 供 Controller 调用
52
+ * - 使用 KoaSSEAdapter 简化 SSE 流式输出
53
+ * - 支持多租户:从请求上下文提取 userId 传入 tenant 参数
54
+ *
55
+ * 替代原有的 WorkService + AgentFactory 自研实现。
56
+ */
57
+ const core_1 = require("@midwayjs/core");
58
+ const typeorm_1 = require("@midwayjs/typeorm");
59
+ const agent_server_1 = require("@cicctencent/agent-server");
60
+ const agent_core_1 = require("@cicctencent/agent-core");
61
+ const path = __importStar(require("path"));
62
+ const os = __importStar(require("os"));
63
+ const fs = __importStar(require("fs/promises"));
64
+ const openai_service_1 = require("./openai.service");
65
+ const agent_profile_service_1 = require("./agent-profile.service");
66
+ const application_service_1 = require("./application.service");
67
+ const mcp_server_service_1 = require("./mcp-server.service");
68
+ const model_config_service_1 = require("./model-config.service");
69
+ const ai_chat_service_1 = require("./ai-chat.service");
70
+ const registry_1 = require("../tools/registry");
71
+ // 自定义工具
72
+ const web_search_tool_1 = require("../tools/web-search.tool");
73
+ const code_exec_tool_1 = require("../tools/code-exec.tool");
74
+ /** 共享的用量追踪器实例(用于 getUsageRecords,AgentServer 内部也有自己的实例) */
75
+ const usageTracker = new agent_core_1.InMemoryUsageTracker();
76
+ let AgentServerService = class AgentServerService {
77
+ async init() {
78
+ // 设置应用名称和数据目录
79
+ const dataDir = path.join(os.homedir(), '.ai-workstation');
80
+ (0, agent_core_1.setAppName)('ai-workstation');
81
+ (0, agent_core_1.setProjectDataDir)(dataDir);
82
+ // 确保数据目录存在
83
+ await fs.mkdir(dataDir, { recursive: true });
84
+ // 设置日志传输
85
+ (0, agent_core_1.setLogTransport)((payload) => {
86
+ console.log(`[${payload.level}] ${payload.event}`, payload.data || '');
87
+ });
88
+ // 初始化 AgentServer
89
+ this.agentServer = await this.createAgentServer();
90
+ }
91
+ /** 创建 AgentServer 实例 */
92
+ async createAgentServer() {
93
+ // 获取模型配置(使用 ModelConfigService,按 Application 隔离)
94
+ const modelConfig = await this.modelConfigService.toAgentModelConfig(0);
95
+ // 创建 ChatStoreProvider(使用 AIChatService)
96
+ const chatStoreProvider = {
97
+ getMessages: async (threadId, options, tenant) => {
98
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
99
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
100
+ const result = await this.chatService.getMessages(Number(threadId), userId, applicationId, options);
101
+ return {
102
+ items: result.items.map((m) => ({
103
+ id: m.id,
104
+ threadId: m.threadId,
105
+ role: m.role,
106
+ content: m.content,
107
+ type: m.type || 'text',
108
+ toolCalls: m.meta?.toolCalls,
109
+ toolCallId: m.meta?.toolCallId,
110
+ meta: m.meta,
111
+ createdAt: String(m.createTime || Date.now()),
112
+ })),
113
+ total: result.total,
114
+ hasMore: result.hasMore ?? false,
115
+ };
116
+ },
117
+ addMessage: async (data, tenant) => {
118
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
119
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
120
+ const msg = await this.chatService.addMessage(userId, applicationId, {
121
+ threadId: Number(data.threadId),
122
+ role: data.role,
123
+ content: data.content,
124
+ type: data.type || 'text',
125
+ meta: data.meta,
126
+ });
127
+ return {
128
+ id: msg.id,
129
+ threadId: msg.threadId,
130
+ role: msg.role,
131
+ content: msg.content,
132
+ type: msg.type,
133
+ meta: msg.meta,
134
+ createdAt: String(msg.createTime || Date.now()),
135
+ };
136
+ },
137
+ getThreads: async (workspaceId, tenant) => {
138
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
139
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
140
+ const threads = await this.chatService.getThreads(Number(workspaceId) || 0, userId, applicationId);
141
+ return threads.map((t) => ({
142
+ id: t.id,
143
+ workspaceId: t.workspaceId,
144
+ title: t.title,
145
+ status: t.status,
146
+ messageCount: t.messageCount,
147
+ createdAt: String(t.createTime || Date.now()),
148
+ updatedAt: String(t.updateTime || t.createTime || Date.now()),
149
+ }));
150
+ },
151
+ getThread: async (id, tenant) => {
152
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
153
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
154
+ const t = await this.chatService.getThread(Number(id), userId, applicationId);
155
+ if (!t)
156
+ return undefined;
157
+ return {
158
+ id: t.id,
159
+ workspaceId: t.workspaceId,
160
+ title: t.title,
161
+ status: t.status,
162
+ messageCount: t.messageCount,
163
+ createdAt: String(t.createTime || Date.now()),
164
+ updatedAt: String(t.updateTime || t.createTime || Date.now()),
165
+ };
166
+ },
167
+ createThread: async (data, tenant) => {
168
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
169
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
170
+ const t = await this.chatService.createThread(userId, applicationId, data);
171
+ return {
172
+ id: t.id,
173
+ workspaceId: t.workspaceId,
174
+ title: t.title,
175
+ status: t.status,
176
+ messageCount: t.messageCount,
177
+ createdAt: String(t.createTime || Date.now()),
178
+ updatedAt: String(t.updateTime || t.createTime || Date.now()),
179
+ };
180
+ },
181
+ updateThread: async (id, data, tenant) => {
182
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
183
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
184
+ const t = await this.chatService.updateThread(Number(id), userId, applicationId, data);
185
+ if (!t)
186
+ return undefined;
187
+ return {
188
+ id: t.id,
189
+ workspaceId: t.workspaceId,
190
+ title: t.title,
191
+ status: t.status,
192
+ messageCount: t.messageCount,
193
+ createdAt: String(t.createTime || Date.now()),
194
+ updatedAt: String(t.updateTime || t.createTime || Date.now()),
195
+ };
196
+ },
197
+ deleteThread: async (id, tenant) => {
198
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
199
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
200
+ await this.chatService.deleteThread(Number(id), userId, applicationId);
201
+ return true;
202
+ },
203
+ updateMessage: async (threadId, id, data, tenant) => {
204
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
205
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
206
+ const m = await this.chatService.updateMessage(Number(id), userId, applicationId, data);
207
+ if (!m)
208
+ return undefined;
209
+ return {
210
+ id: m.id,
211
+ threadId: m.threadId,
212
+ role: m.role,
213
+ content: m.content,
214
+ type: m.type,
215
+ meta: m.meta,
216
+ createdAt: String(m.createTime || Date.now()),
217
+ };
218
+ },
219
+ deleteMessage: async (threadId, id, tenant) => {
220
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
221
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
222
+ await this.chatService.deleteMessage(Number(id), userId, applicationId);
223
+ return true;
224
+ },
225
+ clearThreadMessages: async (threadId, tenant) => {
226
+ // no-op: not implemented
227
+ },
228
+ buildThreadHistory: async (threadId, limit, tenant) => {
229
+ const userId = tenant?.userId ? String(tenant.userId) : this.getUserId();
230
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
231
+ const result = await this.chatService.getMessages(Number(threadId), userId, applicationId, { limit });
232
+ return result.items.map((m) => ({
233
+ role: m.role,
234
+ content: m.content,
235
+ }));
236
+ },
237
+ };
238
+ // 创建 AgentProfileProvider(使用 AgentProfileService)
239
+ const agentProfileProvider = {
240
+ listProfiles: async (tenant) => {
241
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
242
+ return await this.agentProfileService.list(applicationId);
243
+ },
244
+ getProfile: async (profileId, tenant) => {
245
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
246
+ const profile = await this.agentProfileService.get(Number(profileId), applicationId);
247
+ if (!profile)
248
+ return undefined;
249
+ return {
250
+ id: profile.id,
251
+ name: profile.name,
252
+ description: profile.description,
253
+ icon: profile.icon,
254
+ color: profile.color,
255
+ basePrompt: profile.basePrompt,
256
+ model: profile.model,
257
+ modelConfigId: profile.modelConfigId,
258
+ maxIterations: profile.maxIterations,
259
+ maxMessages: profile.maxMessages,
260
+ toolTimeout: profile.toolTimeout,
261
+ disabledTools: profile.disabledTools || [],
262
+ mcpServers: profile.mcpServers || [],
263
+ selectedSkills: profile.selectedSkills || [],
264
+ alwaysInjectSkills: profile.alwaysInjectSkills || [],
265
+ connectorIds: profile.connectorIds || [],
266
+ isDefault: profile.isDefault === 1,
267
+ agentType: profile.agentType,
268
+ remoteUrl: profile.remoteUrl,
269
+ remoteCard: profile.remoteCard,
270
+ remoteAuth: profile.remoteAuth,
271
+ a2aProtocol: profile.a2aProtocol,
272
+ restA2AConfig: profile.restA2AConfig,
273
+ domain: profile.domain,
274
+ createdAt: String(profile.createTime || Date.now()),
275
+ updatedAt: String(profile.updateTime || profile.createTime || Date.now()),
276
+ };
277
+ },
278
+ getDefaultProfile: async (tenant) => {
279
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
280
+ const profile = await this.agentProfileService.getDefault(applicationId);
281
+ if (!profile)
282
+ return undefined;
283
+ return {
284
+ id: profile.id,
285
+ name: profile.name,
286
+ description: profile.description,
287
+ icon: profile.icon,
288
+ color: profile.color,
289
+ basePrompt: profile.basePrompt,
290
+ model: profile.model,
291
+ modelConfigId: profile.modelConfigId,
292
+ maxIterations: profile.maxIterations,
293
+ maxMessages: profile.maxMessages,
294
+ toolTimeout: profile.toolTimeout,
295
+ disabledTools: profile.disabledTools || [],
296
+ mcpServers: profile.mcpServers || [],
297
+ selectedSkills: profile.selectedSkills || [],
298
+ alwaysInjectSkills: profile.alwaysInjectSkills || [],
299
+ connectorIds: profile.connectorIds || [],
300
+ isDefault: profile.isDefault === 1,
301
+ agentType: profile.agentType,
302
+ remoteUrl: profile.remoteUrl,
303
+ remoteCard: profile.remoteCard,
304
+ remoteAuth: profile.remoteAuth,
305
+ a2aProtocol: profile.a2aProtocol,
306
+ restA2AConfig: profile.restA2AConfig,
307
+ domain: profile.domain,
308
+ createdAt: String(profile.createTime || Date.now()),
309
+ updatedAt: String(profile.updateTime || profile.createTime || Date.now()),
310
+ };
311
+ },
312
+ createProfile: async (data, tenant) => {
313
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
314
+ return await this.agentProfileService.create(applicationId, data);
315
+ },
316
+ updateProfile: async (id, data, tenant) => {
317
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
318
+ return await this.agentProfileService.update(Number(id), applicationId, data);
319
+ },
320
+ deleteProfile: async (id, tenant) => {
321
+ const applicationId = tenant?.applicationId ? Number(tenant.applicationId) : 0;
322
+ await this.agentProfileService.delete(Number(id), applicationId);
323
+ return true;
324
+ },
325
+ };
326
+ // 创建 LLM Provider
327
+ const modelCfg = modelConfig
328
+ ? { ...modelConfig }
329
+ : {
330
+ provider: 'openai',
331
+ model: 'gpt-4',
332
+ apiKey: '',
333
+ baseUrl: '',
334
+ temperature: 0.7,
335
+ maxTokens: 4096,
336
+ };
337
+ const llmProvider = (0, agent_core_1.createLLMProvider)(modelCfg);
338
+ // 创建 AgentServer
339
+ const server = await (0, agent_server_1.createAgentServer)({
340
+ llmProvider,
341
+ chatStoreProvider,
342
+ agentProfileProvider,
343
+ tools: this.getTools(),
344
+ dataDir: path.join(os.homedir(), '.ai-workstation'),
345
+ });
346
+ return server;
347
+ }
348
+ /** 运行 Agent(流式) */
349
+ async *runAgentStream(prompt, options = {}) {
350
+ if (!this.agentServer) {
351
+ throw new Error('AgentServer not initialized');
352
+ }
353
+ const tenant = {
354
+ userId: options.userId || this.getUserId(),
355
+ applicationId: options.applicationId,
356
+ };
357
+ const params = {
358
+ content: prompt,
359
+ threadId: options.threadId ? String(options.threadId) : undefined,
360
+ agentProfileId: options.profileId,
361
+ tenant,
362
+ };
363
+ // 创建 SSE 适配器
364
+ const sseAdapter = new agent_server_1.KoaSSEAdapter(this.ctx);
365
+ // 创建 AbortController 用于取消
366
+ const abortController = new AbortController();
367
+ // 存储到 registry 以便支持 abort
368
+ const registry = (0, agent_server_1.getRunRegistry)();
369
+ const sessionId = `session-${Date.now()}-${Math.random().toString(36).slice(2)}`;
370
+ try {
371
+ // 调用 AgentServer.runAgentStream
372
+ await this.agentServer.runAgentStream(sseAdapter, params, abortController.signal);
373
+ // 流已结束,发送 done 事件
374
+ yield { type: 'done', data: null, timestamp: Date.now() };
375
+ }
376
+ catch (error) {
377
+ yield { type: 'error', data: error.message, timestamp: Date.now() };
378
+ }
379
+ }
380
+ /** 运行 Agent(非流式) */
381
+ async runAgent(prompt, options = {}) {
382
+ if (!this.agentServer) {
383
+ throw new Error('AgentServer not initialized');
384
+ }
385
+ const tenant = {
386
+ userId: options.userId || this.getUserId(),
387
+ applicationId: options.applicationId,
388
+ };
389
+ // 获取引擎并直接运行
390
+ const engine = await this.agentServer.getEngineForProfile(options.profileId, undefined, false, tenant);
391
+ // 运行引擎
392
+ const result = await engine.run({ message: prompt, sessionId: `thread-${options.threadId || Date.now()}` });
393
+ return result;
394
+ }
395
+ /** 获取当前用户ID */
396
+ getUserId() {
397
+ return String(this.ctx?.currentSession?.userId || 'admin');
398
+ }
399
+ /** 检查服务是否可用 */
400
+ isAvailable() {
401
+ return !!this.agentServer && this.openaiService.isAvailable();
402
+ }
403
+ /** 获取可用工具列表(公开方法,供诊断接口调用) */
404
+ getTools() {
405
+ const tools = [];
406
+ // 添加 agent-server 内置工具
407
+ const builtinTools = (0, agent_server_1.createBuiltinTools)();
408
+ tools.push(...builtinTools);
409
+ // 添加自定义工具(转换为 RegisteredTool 格式)
410
+ const customTools = [web_search_tool_1.webSearchTool, code_exec_tool_1.executeCodeTool];
411
+ for (const tool of customTools) {
412
+ tools.push({
413
+ definition: {
414
+ type: 'function',
415
+ function: {
416
+ name: tool.id,
417
+ description: tool.description,
418
+ parameters: tool.parameters,
419
+ },
420
+ },
421
+ executor: async (args, context) => {
422
+ const result = await tool.execute?.(args, context);
423
+ return typeof result === 'string' ? result : JSON.stringify(result);
424
+ },
425
+ });
426
+ }
427
+ // 从 toolRegistry 获取其他工具
428
+ for (const tool of registry_1.toolRegistry.getAll()) {
429
+ tools.push({
430
+ definition: {
431
+ type: 'function',
432
+ function: {
433
+ name: tool.id,
434
+ description: tool.description,
435
+ parameters: tool.parameters,
436
+ },
437
+ },
438
+ executor: async (args, context) => {
439
+ return await tool.execute(args, context);
440
+ },
441
+ });
442
+ }
443
+ // SubAgent 委派:如果有 specialist profiles,注册 delegate_task 工具
444
+ try {
445
+ const runners = this.getSubAgentRunners();
446
+ if (runners.length > 0) {
447
+ const delegateTool = (0, agent_core_1.createDelegateTool)(runners);
448
+ if (delegateTool) {
449
+ tools.push(delegateTool);
450
+ console.log(`[AgentServerService] delegate_task registered with ${runners.length} runners`);
451
+ }
452
+ }
453
+ }
454
+ catch (e) {
455
+ console.warn('[AgentServerService] Failed to register delegate_task:', e?.message);
456
+ }
457
+ return tools;
458
+ }
459
+ /** 获取可用的 SubAgent runners 列表 */
460
+ getSubAgentRunners() {
461
+ const runners = [];
462
+ // 此处通过异步获取 profiles(在同步上下文中尽力获取)
463
+ // 由于 getTools 是同步方法,这里使用缓存的 profiles
464
+ // 实际的 specialist profiles 在 AgentProfileProvider 中管理
465
+ return runners;
466
+ }
467
+ /** 中止 Agent 执行 */
468
+ async abortAgent(threadId, _userId) {
469
+ if (!this.agentServer)
470
+ return false;
471
+ return this.agentServer.abortAgent(threadId);
472
+ }
473
+ /** SSE 断线重连 */
474
+ async *reconnectStream(threadId, _userId) {
475
+ if (!this.agentServer) {
476
+ throw new Error('AgentServer not initialized');
477
+ }
478
+ const sseAdapter = new agent_server_1.KoaSSEAdapter(this.ctx);
479
+ try {
480
+ await this.agentServer.reconnectAgentStream(sseAdapter, Number(threadId));
481
+ yield { type: 'done', data: null, timestamp: Date.now() };
482
+ }
483
+ catch (error) {
484
+ yield { type: 'error', data: error.message, timestamp: Date.now() };
485
+ }
486
+ }
487
+ /** 编辑消息后重新生成 */
488
+ async editAndRegenerate(threadId, messageId, content, options) {
489
+ const userId = options.userId || this.getUserId();
490
+ // 更新消息内容
491
+ await this.chatService.updateMessage(messageId, userId, options.applicationId || 0, { content });
492
+ // 删除该消息之后的所有消息
493
+ const messages = await this.chatService.getMessages(threadId, userId, options.applicationId || 0);
494
+ const toDelete = messages.items.filter((m) => m.id > messageId);
495
+ for (const msg of toDelete) {
496
+ await this.chatService.deleteMessage(msg.id, userId, options.applicationId || 0);
497
+ }
498
+ // 重新运行 Agent
499
+ return this.runAgent(content, { ...options, threadId });
500
+ }
501
+ /** 重新生成最后一条 AI 回复 */
502
+ async regenerate(threadId, options) {
503
+ const userId = options.userId || this.getUserId();
504
+ const applicationId = options.applicationId || 0;
505
+ // 获取线程消息
506
+ const messages = await this.chatService.getMessages(threadId, userId, applicationId);
507
+ if (messages.items.length === 0) {
508
+ throw new Error('线程中没有消息');
509
+ }
510
+ // 找到最后一条 AI 消息并删除
511
+ const lastAIMessage = [...messages.items]
512
+ .reverse()
513
+ .find((m) => m.role === 'assistant');
514
+ if (lastAIMessage) {
515
+ await this.chatService.deleteMessage(lastAIMessage.id, userId, applicationId);
516
+ }
517
+ // 找到最后一条用户消息作为 prompt
518
+ const lastUserMessage = [...messages.items]
519
+ .reverse()
520
+ .find((m) => m.role === 'user');
521
+ if (!lastUserMessage) {
522
+ throw new Error('没有用户消息可重新生成');
523
+ }
524
+ return this.runAgent(lastUserMessage.content, { ...options, threadId });
525
+ }
526
+ /** 从指定位置分叉创建新对话 */
527
+ async forkThread(threadId, messageId, options) {
528
+ const userId = options.userId || this.getUserId();
529
+ const applicationId = options.applicationId || 0;
530
+ // 获取原线程
531
+ const originalThread = await this.chatService.getThread(threadId, userId, applicationId);
532
+ if (!originalThread) {
533
+ throw new Error('原线程不存在');
534
+ }
535
+ // 创建新线程
536
+ const newThread = await this.chatService.createThread(userId, applicationId, {
537
+ workspaceId: originalThread.workspaceId,
538
+ title: `${originalThread.title} (副本)`,
539
+ });
540
+ // 复制消息到新线程(只复制到 messageId 为止的消息)
541
+ const messages = await this.chatService.getMessages(threadId, userId, applicationId);
542
+ const messagesToCopy = messages.items.filter((m) => m.id <= messageId);
543
+ for (const msg of messagesToCopy) {
544
+ await this.chatService.addMessage(userId, applicationId, {
545
+ threadId: newThread.id,
546
+ role: msg.role,
547
+ content: msg.content,
548
+ type: msg.type,
549
+ meta: msg.meta,
550
+ });
551
+ }
552
+ return { thread: newThread, copiedCount: messagesToCopy.length };
553
+ }
554
+ /** 清空引擎缓存池(强制下次请求重建引擎) */
555
+ clearEnginePool() {
556
+ (0, agent_server_1.getEnginePool)().clear();
557
+ console.log('[AgentServerService] Engine pool cleared');
558
+ }
559
+ /** 向运行中的 Agent 发送 steering 消息(实时转向) */
560
+ steerAgent(sessionId, message) {
561
+ if (!this.agentServer)
562
+ return false;
563
+ return this.agentServer.steerAgent(sessionId, message);
564
+ }
565
+ /** 获取用量统计 */
566
+ getUsageStats(filter) {
567
+ if (!this.agentServer)
568
+ return null;
569
+ return this.agentServer.getUsageStats(filter);
570
+ }
571
+ /** 获取用量记录列表 */
572
+ getUsageRecords(filter) {
573
+ return usageTracker.list(filter);
574
+ }
575
+ /** 诊断:检查引擎工具列表 */
576
+ diagnoseEngineTools(clearPool = false) {
577
+ if (clearPool) {
578
+ this.clearEnginePool();
579
+ }
580
+ const tools = this.getTools();
581
+ return {
582
+ hasDelegateTask: tools.some(t => t.definition?.function?.name === 'delegate_task'),
583
+ toolCount: tools.length,
584
+ tools: tools.map(t => ({
585
+ name: t.definition?.function?.name || 'unknown',
586
+ category: t.category || 'builtin',
587
+ })),
588
+ poolCleared: clearPool,
589
+ };
590
+ }
591
+ };
592
+ exports.AgentServerService = AgentServerService;
593
+ __decorate([
594
+ (0, core_1.Inject)(),
595
+ __metadata("design:type", Object)
596
+ ], AgentServerService.prototype, "ctx", void 0);
597
+ __decorate([
598
+ (0, core_1.Inject)(),
599
+ __metadata("design:type", openai_service_1.OpenAIService)
600
+ ], AgentServerService.prototype, "openaiService", void 0);
601
+ __decorate([
602
+ (0, core_1.Inject)(),
603
+ __metadata("design:type", agent_profile_service_1.AgentProfileService)
604
+ ], AgentServerService.prototype, "agentProfileService", void 0);
605
+ __decorate([
606
+ (0, core_1.Inject)(),
607
+ __metadata("design:type", application_service_1.ApplicationService)
608
+ ], AgentServerService.prototype, "applicationService", void 0);
609
+ __decorate([
610
+ (0, core_1.Inject)(),
611
+ __metadata("design:type", mcp_server_service_1.MCPServerService)
612
+ ], AgentServerService.prototype, "mcpServerService", void 0);
613
+ __decorate([
614
+ (0, core_1.Inject)(),
615
+ __metadata("design:type", model_config_service_1.ModelConfigService)
616
+ ], AgentServerService.prototype, "modelConfigService", void 0);
617
+ __decorate([
618
+ (0, core_1.Inject)(),
619
+ __metadata("design:type", ai_chat_service_1.AIChatService)
620
+ ], AgentServerService.prototype, "chatService", void 0);
621
+ __decorate([
622
+ (0, typeorm_1.InjectDataSource)('default'),
623
+ __metadata("design:type", Function)
624
+ ], AgentServerService.prototype, "dataSource", void 0);
625
+ __decorate([
626
+ (0, core_1.Init)(),
627
+ __metadata("design:type", Function),
628
+ __metadata("design:paramtypes", []),
629
+ __metadata("design:returntype", Promise)
630
+ ], AgentServerService.prototype, "init", null);
631
+ exports.AgentServerService = AgentServerService = __decorate([
632
+ (0, core_1.Provide)(),
633
+ (0, core_1.Scope)(core_1.ScopeEnum.Request, { allowDowngrade: true })
634
+ ], AgentServerService);