@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.
- package/README.md +280 -0
- package/dist/adapters/express.d.ts +8 -0
- package/dist/adapters/express.js +91 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.js +21 -0
- package/dist/adapters/koa.d.ts +3 -0
- package/dist/adapters/koa.js +75 -0
- package/dist/adapters/midway.d.ts +5 -0
- package/dist/adapters/midway.js +11 -0
- package/dist/adapters/next.d.ts +12 -0
- package/dist/adapters/next.js +89 -0
- package/dist/adapters/shared.d.ts +4 -0
- package/dist/adapters/shared.js +31 -0
- package/dist/channel/dingtalk.d.ts +18 -0
- package/dist/channel/dingtalk.js +68 -0
- package/dist/channel/feishu.d.ts +20 -0
- package/dist/channel/feishu.js +96 -0
- package/dist/channel/index.d.ts +46 -0
- package/dist/channel/index.js +311 -0
- package/dist/channel/types.d.ts +77 -0
- package/dist/channel/types.js +7 -0
- package/dist/channel/wecom.d.ts +22 -0
- package/dist/channel/wecom.js +106 -0
- package/dist/component.d.ts +49 -0
- package/dist/component.js +129 -0
- package/dist/connector/calendar-adapter.d.ts +19 -0
- package/dist/connector/calendar-adapter.js +236 -0
- package/dist/connector/db-adapter.d.ts +28 -0
- package/dist/connector/db-adapter.js +193 -0
- package/dist/connector/email-adapter.d.ts +23 -0
- package/dist/connector/email-adapter.js +192 -0
- package/dist/connector/fs-adapter.d.ts +15 -0
- package/dist/connector/fs-adapter.js +199 -0
- package/dist/connector/http-adapter.d.ts +29 -0
- package/dist/connector/http-adapter.js +181 -0
- package/dist/connector/index.d.ts +24 -0
- package/dist/connector/index.js +454 -0
- package/dist/connector/mcp-adapter.d.ts +27 -0
- package/dist/connector/mcp-adapter.js +156 -0
- package/dist/connector/mq-adapter.d.ts +25 -0
- package/dist/connector/mq-adapter.js +181 -0
- package/dist/connector/types.d.ts +205 -0
- package/dist/connector/types.js +9 -0
- package/dist/controller/a2a.controller.d.ts +41 -0
- package/dist/controller/a2a.controller.js +150 -0
- package/dist/controller/agent-profile.controller.d.ts +97 -0
- package/dist/controller/agent-profile.controller.js +200 -0
- package/dist/controller/agent.controller.d.ts +199 -0
- package/dist/controller/agent.controller.js +414 -0
- package/dist/controller/application.controller.d.ts +113 -0
- package/dist/controller/application.controller.js +217 -0
- package/dist/controller/automation.controller.d.ts +113 -0
- package/dist/controller/automation.controller.js +246 -0
- package/dist/controller/channel.controller.d.ts +73 -0
- package/dist/controller/channel.controller.js +183 -0
- package/dist/controller/chat.controller.d.ts +188 -0
- package/dist/controller/chat.controller.js +375 -0
- package/dist/controller/connector.controller.d.ts +134 -0
- package/dist/controller/connector.controller.js +257 -0
- package/dist/controller/knowledge-base.controller.d.ts +157 -0
- package/dist/controller/knowledge-base.controller.js +278 -0
- package/dist/controller/mcp-server.controller.d.ts +115 -0
- package/dist/controller/mcp-server.controller.js +236 -0
- package/dist/controller/model-config.controller.d.ts +139 -0
- package/dist/controller/model-config.controller.js +274 -0
- package/dist/controller/observability.controller.d.ts +124 -0
- package/dist/controller/observability.controller.js +142 -0
- package/dist/controller/security.controller.d.ts +91 -0
- package/dist/controller/security.controller.js +172 -0
- package/dist/controller/settings.controller.d.ts +83 -0
- package/dist/controller/settings.controller.js +280 -0
- package/dist/core/ai-workstation.d.ts +17 -0
- package/dist/core/ai-workstation.js +129 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +20 -0
- package/dist/core/service-container.d.ts +12 -0
- package/dist/core/service-container.js +54 -0
- package/dist/core/sse.d.ts +6 -0
- package/dist/core/sse.js +56 -0
- package/dist/core/types.d.ts +72 -0
- package/dist/core/types.js +2 -0
- package/dist/dto/agent.dto.d.ts +21 -0
- package/dist/dto/agent.dto.js +79 -0
- package/dist/dto/ai-config.dto.d.ts +67 -0
- package/dist/dto/ai-config.dto.js +249 -0
- package/dist/dto/chat.dto.d.ts +40 -0
- package/dist/dto/chat.dto.js +122 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +195 -0
- package/dist/memory/db-store.d.ts +33 -0
- package/dist/memory/db-store.js +143 -0
- package/dist/memory/index.d.ts +187 -0
- package/dist/memory/index.js +443 -0
- package/dist/model/ai-agent-profile.entity.d.ts +32 -0
- package/dist/model/ai-agent-profile.entity.js +289 -0
- package/dist/model/ai-application.entity.d.ts +20 -0
- package/dist/model/ai-application.entity.js +166 -0
- package/dist/model/ai-chat-memory.entity.d.ts +16 -0
- package/dist/model/ai-chat-memory.entity.js +123 -0
- package/dist/model/ai-chat-message.entity.d.ts +16 -0
- package/dist/model/ai-chat-message.entity.js +122 -0
- package/dist/model/ai-chat-skill.entity.d.ts +19 -0
- package/dist/model/ai-chat-skill.entity.js +155 -0
- package/dist/model/ai-chat-thread.entity.d.ts +15 -0
- package/dist/model/ai-chat-thread.entity.js +113 -0
- package/dist/model/ai-chat-workspace.entity.d.ts +17 -0
- package/dist/model/ai-chat-workspace.entity.js +136 -0
- package/dist/model/ai-kb-document.entity.d.ts +16 -0
- package/dist/model/ai-kb-document.entity.js +122 -0
- package/dist/model/ai-knowledge-base.entity.d.ts +22 -0
- package/dist/model/ai-knowledge-base.entity.js +185 -0
- package/dist/model/ai-mcp-server.entity.d.ts +23 -0
- package/dist/model/ai-mcp-server.entity.js +198 -0
- package/dist/model/ai-model-config.entity.d.ts +24 -0
- package/dist/model/ai-model-config.entity.js +200 -0
- package/dist/service/a2a.service.d.ts +142 -0
- package/dist/service/a2a.service.js +537 -0
- package/dist/service/agent-profile.service.d.ts +34 -0
- package/dist/service/agent-profile.service.js +110 -0
- package/dist/service/agent-server.service.d.ts +91 -0
- package/dist/service/agent-server.service.js +634 -0
- package/dist/service/agent-task-queue.service.d.ts +98 -0
- package/dist/service/agent-task-queue.service.js +283 -0
- package/dist/service/ai-chat.service.d.ts +103 -0
- package/dist/service/ai-chat.service.js +431 -0
- package/dist/service/ai-skill.service.d.ts +116 -0
- package/dist/service/ai-skill.service.js +457 -0
- package/dist/service/application.service.d.ts +42 -0
- package/dist/service/application.service.js +139 -0
- package/dist/service/automation.service.d.ts +37 -0
- package/dist/service/automation.service.js +196 -0
- package/dist/service/connector.service.d.ts +136 -0
- package/dist/service/connector.service.js +524 -0
- package/dist/service/knowledge-base.service.d.ts +138 -0
- package/dist/service/knowledge-base.service.js +528 -0
- package/dist/service/mcp-server.service.d.ts +39 -0
- package/dist/service/mcp-server.service.js +143 -0
- package/dist/service/model-config.service.d.ts +57 -0
- package/dist/service/model-config.service.js +168 -0
- package/dist/service/observability.service.d.ts +145 -0
- package/dist/service/observability.service.js +281 -0
- package/dist/service/openai.service.d.ts +88 -0
- package/dist/service/openai.service.js +406 -0
- package/dist/service/prompt-builder.service.d.ts +50 -0
- package/dist/service/prompt-builder.service.js +246 -0
- package/dist/tools/code-exec.tool.d.ts +37 -0
- package/dist/tools/code-exec.tool.js +162 -0
- package/dist/tools/datetime.tool.d.ts +21 -0
- package/dist/tools/datetime.tool.js +379 -0
- package/dist/tools/http-request.tool.d.ts +43 -0
- package/dist/tools/http-request.tool.js +455 -0
- package/dist/tools/registry.d.ts +71 -0
- package/dist/tools/registry.js +77 -0
- package/dist/tools/text-process.tool.d.ts +7 -0
- package/dist/tools/text-process.tool.js +366 -0
- package/dist/tools/web-search.tool.d.ts +28 -0
- package/dist/tools/web-search.tool.js +304 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.js +7 -0
- package/package.json +69 -0
|
@@ -0,0 +1,406 @@
|
|
|
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.OpenAIService = void 0;
|
|
46
|
+
const core_1 = require("@midwayjs/core");
|
|
47
|
+
/**
|
|
48
|
+
* OpenAI 基础服务
|
|
49
|
+
* 封装 OpenAI API 调用,提供通用对话、流式输出、模型容错降级等基础能力
|
|
50
|
+
*/
|
|
51
|
+
let OpenAIService = class OpenAIService {
|
|
52
|
+
constructor() {
|
|
53
|
+
this.client = null;
|
|
54
|
+
}
|
|
55
|
+
async init() {
|
|
56
|
+
try {
|
|
57
|
+
const { default: OpenAI } = await Promise.resolve().then(() => __importStar(require('openai')));
|
|
58
|
+
if (this.openaiConfig?.apiKey) {
|
|
59
|
+
this.client = new OpenAI({
|
|
60
|
+
apiKey: this.openaiConfig.apiKey,
|
|
61
|
+
baseURL: this.openaiConfig.baseUrl,
|
|
62
|
+
});
|
|
63
|
+
console.log('[OpenAI] initialized, model:', this.openaiConfig.model, 'baseUrl:', this.openaiConfig.baseUrl);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.warn('[OpenAI] apiKey not configured, AI generation will be unavailable');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
console.warn('[OpenAI] openai package not installed, run: npm install openai');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
isAvailable() {
|
|
74
|
+
return !!this.client;
|
|
75
|
+
}
|
|
76
|
+
// ===================== 通用对话流式接口 =====================
|
|
77
|
+
/**
|
|
78
|
+
* 通用 AI 对话流式输出
|
|
79
|
+
* 支持多轮对话上下文,返回 SSE 事件流
|
|
80
|
+
*/
|
|
81
|
+
async *chatStream(messages, systemPrompt) {
|
|
82
|
+
if (!this.client) {
|
|
83
|
+
throw new Error('OpenAI 未配置或 openai 包未安装');
|
|
84
|
+
}
|
|
85
|
+
const defaultSystemPrompt = systemPrompt ||
|
|
86
|
+
'你是一个智能助手,能够帮助用户完成各种任务。请用中文回答,回答要专业但易于理解。';
|
|
87
|
+
const finalMessages = [];
|
|
88
|
+
if (systemPrompt) {
|
|
89
|
+
finalMessages.push({ role: 'system', content: systemPrompt });
|
|
90
|
+
}
|
|
91
|
+
finalMessages.push(...messages);
|
|
92
|
+
try {
|
|
93
|
+
const response = await this.client.chat.completions.create({
|
|
94
|
+
model: this.openaiConfig.model,
|
|
95
|
+
messages: finalMessages,
|
|
96
|
+
max_tokens: this.openaiConfig.maxTokens,
|
|
97
|
+
temperature: this.openaiConfig.temperature,
|
|
98
|
+
stream: true,
|
|
99
|
+
});
|
|
100
|
+
let reasoningContent = '';
|
|
101
|
+
let contentBuffer = '';
|
|
102
|
+
for await (const chunk of response) {
|
|
103
|
+
const delta = chunk.choices?.[0]?.delta;
|
|
104
|
+
if (!delta)
|
|
105
|
+
continue;
|
|
106
|
+
// 推理内容
|
|
107
|
+
const reasoning = delta?.reasoning_content ||
|
|
108
|
+
delta?.reasoning ||
|
|
109
|
+
delta?.thinking ||
|
|
110
|
+
'';
|
|
111
|
+
if (reasoning) {
|
|
112
|
+
reasoningContent += reasoning;
|
|
113
|
+
yield { event: 'reasoning', data: reasoning };
|
|
114
|
+
}
|
|
115
|
+
// 正文内容
|
|
116
|
+
if (delta.content) {
|
|
117
|
+
contentBuffer += delta.content;
|
|
118
|
+
yield { event: 'content', data: delta.content };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (reasoningContent) {
|
|
122
|
+
yield { event: 'reasoning-done', data: null };
|
|
123
|
+
}
|
|
124
|
+
yield { event: 'done', data: contentBuffer };
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
// 如果流式不支持,降级为普通调用
|
|
128
|
+
console.warn('[OpenAI] 流式调用失败,降级为普通调用:', e.message);
|
|
129
|
+
const result = await this.chatCompletion(defaultSystemPrompt, messages.map(m => m.content).join('\n') ||
|
|
130
|
+
messages[messages.length - 1]?.content ||
|
|
131
|
+
'');
|
|
132
|
+
if (result.reasoningContent) {
|
|
133
|
+
yield { event: 'reasoning', data: result.reasoningContent };
|
|
134
|
+
yield { event: 'reasoning-done', data: null };
|
|
135
|
+
}
|
|
136
|
+
yield { event: 'content', data: result.content };
|
|
137
|
+
yield { event: 'done', data: result.content };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// ===================== 通用完成接口 =====================
|
|
141
|
+
/**
|
|
142
|
+
* 通用 AI 对话完整调用(非流式)
|
|
143
|
+
*/
|
|
144
|
+
async chatCompletion(systemPrompt, userMessage, modelOverride) {
|
|
145
|
+
if (!this.client) {
|
|
146
|
+
throw new Error('OpenAI 未配置或 openai 包未安装');
|
|
147
|
+
}
|
|
148
|
+
const response = await this.client.chat.completions.create({
|
|
149
|
+
model: modelOverride || this.openaiConfig.model,
|
|
150
|
+
messages: [
|
|
151
|
+
{ role: 'system', content: systemPrompt },
|
|
152
|
+
{ role: 'user', content: userMessage },
|
|
153
|
+
],
|
|
154
|
+
max_tokens: this.openaiConfig.maxTokens,
|
|
155
|
+
temperature: this.openaiConfig.temperature,
|
|
156
|
+
});
|
|
157
|
+
const message = response.choices?.[0]?.message;
|
|
158
|
+
return {
|
|
159
|
+
content: message?.content || '',
|
|
160
|
+
reasoningContent: message?.reasoning_content ||
|
|
161
|
+
message?.reasoning ||
|
|
162
|
+
message?.thinking ||
|
|
163
|
+
'',
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// ===================== 流式辅助方法 =====================
|
|
167
|
+
/**
|
|
168
|
+
* 带工具调用的单轮流式对话
|
|
169
|
+
* 子类可传入自定义 tools 参数覆盖默认行为
|
|
170
|
+
*/
|
|
171
|
+
async *streamToolRound(messages, modelOverride, tools) {
|
|
172
|
+
if (!this.client) {
|
|
173
|
+
throw new Error('OpenAI 未配置或 openai 包未安装');
|
|
174
|
+
}
|
|
175
|
+
const createParams = {
|
|
176
|
+
model: modelOverride || this.openaiConfig.model,
|
|
177
|
+
messages,
|
|
178
|
+
max_tokens: this.openaiConfig.maxTokens,
|
|
179
|
+
temperature: this.openaiConfig.temperature,
|
|
180
|
+
stream: true,
|
|
181
|
+
};
|
|
182
|
+
if (tools && tools.length > 0) {
|
|
183
|
+
createParams.tools = tools;
|
|
184
|
+
createParams.tool_choice = 'auto';
|
|
185
|
+
}
|
|
186
|
+
const stream = await this.client.chat.completions.create(createParams);
|
|
187
|
+
const toolCalls = [];
|
|
188
|
+
let reasoningContent = '';
|
|
189
|
+
let content = '';
|
|
190
|
+
for await (const chunk of stream) {
|
|
191
|
+
const delta = chunk?.choices?.[0]?.delta || {};
|
|
192
|
+
const reasoningText = this.extractReasoningText(delta);
|
|
193
|
+
if (reasoningText) {
|
|
194
|
+
reasoningContent += reasoningText;
|
|
195
|
+
yield { kind: 'reasoning', text: reasoningText };
|
|
196
|
+
}
|
|
197
|
+
const contentText = this.extractContentText(delta);
|
|
198
|
+
if (contentText) {
|
|
199
|
+
content += contentText;
|
|
200
|
+
yield { kind: 'content', text: contentText };
|
|
201
|
+
}
|
|
202
|
+
if (Array.isArray(delta.tool_calls)) {
|
|
203
|
+
for (const deltaToolCall of delta.tool_calls) {
|
|
204
|
+
this.mergeToolCallDelta(toolCalls, deltaToolCall);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
yield {
|
|
209
|
+
kind: 'result',
|
|
210
|
+
message: {
|
|
211
|
+
role: 'assistant',
|
|
212
|
+
content,
|
|
213
|
+
tool_calls: this.normalizeToolCalls(toolCalls),
|
|
214
|
+
reasoning_content: reasoningContent,
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* 从消息列表中流式输出对话内容
|
|
220
|
+
*/
|
|
221
|
+
async *streamCompletionFromMessages(messages, modelOverride) {
|
|
222
|
+
if (!this.client) {
|
|
223
|
+
throw new Error('OpenAI 未配置或 openai 包未安装');
|
|
224
|
+
}
|
|
225
|
+
const stream = await this.client.chat.completions.create({
|
|
226
|
+
model: modelOverride || this.openaiConfig.model,
|
|
227
|
+
messages,
|
|
228
|
+
max_tokens: this.openaiConfig.maxTokens,
|
|
229
|
+
temperature: this.openaiConfig.temperature,
|
|
230
|
+
stream: true,
|
|
231
|
+
});
|
|
232
|
+
for await (const chunk of stream) {
|
|
233
|
+
const delta = chunk?.choices?.[0]?.delta || {};
|
|
234
|
+
const reasoningText = this.extractReasoningText(delta);
|
|
235
|
+
if (reasoningText) {
|
|
236
|
+
yield { kind: 'reasoning', text: reasoningText };
|
|
237
|
+
}
|
|
238
|
+
const contentText = this.extractContentText(delta);
|
|
239
|
+
if (contentText) {
|
|
240
|
+
yield { kind: 'content', text: contentText };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// ===================== 文本提取辅助 =====================
|
|
245
|
+
normalizeTextPayload(payload) {
|
|
246
|
+
if (!payload)
|
|
247
|
+
return '';
|
|
248
|
+
if (typeof payload === 'string')
|
|
249
|
+
return payload;
|
|
250
|
+
if (Array.isArray(payload)) {
|
|
251
|
+
return payload
|
|
252
|
+
.map(item => {
|
|
253
|
+
if (typeof item === 'string')
|
|
254
|
+
return item;
|
|
255
|
+
if (typeof item?.text === 'string')
|
|
256
|
+
return item.text;
|
|
257
|
+
if (typeof item?.content === 'string')
|
|
258
|
+
return item.content;
|
|
259
|
+
return '';
|
|
260
|
+
})
|
|
261
|
+
.join('');
|
|
262
|
+
}
|
|
263
|
+
if (typeof payload?.text === 'string')
|
|
264
|
+
return payload.text;
|
|
265
|
+
if (typeof payload?.content === 'string')
|
|
266
|
+
return payload.content;
|
|
267
|
+
return '';
|
|
268
|
+
}
|
|
269
|
+
extractReasoningText(message) {
|
|
270
|
+
return this.normalizeTextPayload(message?.reasoning_content ||
|
|
271
|
+
message?.reasoning ||
|
|
272
|
+
message?.thinking);
|
|
273
|
+
}
|
|
274
|
+
extractContentText(message) {
|
|
275
|
+
return this.normalizeTextPayload(message?.content);
|
|
276
|
+
}
|
|
277
|
+
// ===================== 工具调用辅助 =====================
|
|
278
|
+
parseToolArguments(rawArgs) {
|
|
279
|
+
if (!rawArgs)
|
|
280
|
+
return {};
|
|
281
|
+
try {
|
|
282
|
+
return JSON.parse(rawArgs);
|
|
283
|
+
}
|
|
284
|
+
catch (e) {
|
|
285
|
+
console.warn('[OpenAI] 工具参数解析失败:', rawArgs);
|
|
286
|
+
return {};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
mergeToolCallDelta(target, deltaToolCall) {
|
|
290
|
+
const index = typeof deltaToolCall?.index === 'number'
|
|
291
|
+
? deltaToolCall.index
|
|
292
|
+
: target.length;
|
|
293
|
+
if (!target[index]) {
|
|
294
|
+
target[index] = {
|
|
295
|
+
id: '',
|
|
296
|
+
type: 'function',
|
|
297
|
+
function: {
|
|
298
|
+
name: '',
|
|
299
|
+
arguments: '',
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
if (deltaToolCall?.id) {
|
|
304
|
+
target[index].id += deltaToolCall.id;
|
|
305
|
+
}
|
|
306
|
+
if (deltaToolCall?.type) {
|
|
307
|
+
target[index].type = deltaToolCall.type;
|
|
308
|
+
}
|
|
309
|
+
if (deltaToolCall?.function?.name) {
|
|
310
|
+
target[index].function.name += deltaToolCall.function.name;
|
|
311
|
+
}
|
|
312
|
+
if (deltaToolCall?.function?.arguments) {
|
|
313
|
+
target[index].function.arguments +=
|
|
314
|
+
deltaToolCall.function.arguments;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
normalizeToolCalls(toolCalls) {
|
|
318
|
+
return toolCalls
|
|
319
|
+
.filter(Boolean)
|
|
320
|
+
.map(toolCall => ({
|
|
321
|
+
id: toolCall.id,
|
|
322
|
+
type: toolCall.type || 'function',
|
|
323
|
+
function: {
|
|
324
|
+
name: toolCall.function?.name || '',
|
|
325
|
+
arguments: toolCall.function?.arguments || '',
|
|
326
|
+
},
|
|
327
|
+
}))
|
|
328
|
+
.filter(toolCall => toolCall.id ||
|
|
329
|
+
toolCall.function.name ||
|
|
330
|
+
toolCall.function.arguments);
|
|
331
|
+
}
|
|
332
|
+
// ===================== 错误处理与容错 =====================
|
|
333
|
+
isModelEngineError(error) {
|
|
334
|
+
const message = String(error?.message || '').toLowerCase();
|
|
335
|
+
const status = Number(error?.status || error?.statusCode || 0);
|
|
336
|
+
const code = String(error?.code || error?.error?.code || '').toLowerCase();
|
|
337
|
+
return (message.includes('model engine error') ||
|
|
338
|
+
message.includes('internal server error') ||
|
|
339
|
+
code.includes('model_engine_error') ||
|
|
340
|
+
status >= 500);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* 判断是否为网络连接错误(ECONNRESET / ETIMEDOUT 等)
|
|
344
|
+
* 这类错误通常可以通过重试或降级恢复
|
|
345
|
+
*/
|
|
346
|
+
isNetworkError(error) {
|
|
347
|
+
const code = String(error?.code || '').toUpperCase();
|
|
348
|
+
const message = String(error?.message || '').toLowerCase();
|
|
349
|
+
const networkCodes = new Set([
|
|
350
|
+
'ECONNRESET',
|
|
351
|
+
'ETIMEDOUT',
|
|
352
|
+
'ECONNREFUSED',
|
|
353
|
+
'ENOTFOUND',
|
|
354
|
+
'EAI_AGAIN',
|
|
355
|
+
'EPIPE',
|
|
356
|
+
'EHOSTUNREACH',
|
|
357
|
+
'ENETUNREACH',
|
|
358
|
+
]);
|
|
359
|
+
return (networkCodes.has(code) ||
|
|
360
|
+
message.includes('socket hang up') ||
|
|
361
|
+
message.includes('network error') ||
|
|
362
|
+
message.includes('fetch failed') ||
|
|
363
|
+
message.includes('aborted'));
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* 判断是否为可恢复错误(模型引擎错误 + 网络错误)
|
|
367
|
+
* 可恢复错误会触发降级/重试,而非直接抛出
|
|
368
|
+
*/
|
|
369
|
+
isRecoverableError(error) {
|
|
370
|
+
return this.isModelEngineError(error) || this.isNetworkError(error);
|
|
371
|
+
}
|
|
372
|
+
logModelError(scope, error) {
|
|
373
|
+
console.error(`[OpenAI] ${scope} 失败:`, {
|
|
374
|
+
message: error?.message,
|
|
375
|
+
status: error?.status || error?.statusCode,
|
|
376
|
+
code: error?.code || error?.error?.code,
|
|
377
|
+
type: error?.type || error?.error?.type,
|
|
378
|
+
cause: error?.cause?.message,
|
|
379
|
+
response: error?.response?.data || error?.error || null,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
getFallbackModels() {
|
|
383
|
+
const configured = Array.isArray(this.openaiConfig.fallbackModels)
|
|
384
|
+
? this.openaiConfig.fallbackModels
|
|
385
|
+
: [];
|
|
386
|
+
return Array.from(new Set([...configured, 'glm-5.1', 'deepseek-v3.2', 'kimi-k2.5'].filter(model => !!model && model !== this.openaiConfig.model)));
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
exports.OpenAIService = OpenAIService;
|
|
390
|
+
__decorate([
|
|
391
|
+
(0, core_1.Inject)(),
|
|
392
|
+
__metadata("design:type", Object)
|
|
393
|
+
], OpenAIService.prototype, "ctx", void 0);
|
|
394
|
+
__decorate([
|
|
395
|
+
(0, core_1.Config)('openai'),
|
|
396
|
+
__metadata("design:type", Object)
|
|
397
|
+
], OpenAIService.prototype, "openaiConfig", void 0);
|
|
398
|
+
__decorate([
|
|
399
|
+
(0, core_1.Init)(),
|
|
400
|
+
__metadata("design:type", Function),
|
|
401
|
+
__metadata("design:paramtypes", []),
|
|
402
|
+
__metadata("design:returntype", Promise)
|
|
403
|
+
], OpenAIService.prototype, "init", null);
|
|
404
|
+
exports.OpenAIService = OpenAIService = __decorate([
|
|
405
|
+
(0, core_1.Provide)()
|
|
406
|
+
], OpenAIService);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Context } from '@midwayjs/koa';
|
|
2
|
+
import { AgentProfileService } from './agent-profile.service';
|
|
3
|
+
import { MCPServerService } from './mcp-server.service';
|
|
4
|
+
import { AISkillService } from './ai-skill.service';
|
|
5
|
+
import AIAgentProfileEntity from '../model/ai-agent-profile.entity';
|
|
6
|
+
import type { ToolRegistry, SkillManager } from '@cicctencent/agent-core';
|
|
7
|
+
/**
|
|
8
|
+
* Prompt 构建服务
|
|
9
|
+
*
|
|
10
|
+
* 负责构建 Agent 的系统提示词,包括:
|
|
11
|
+
* - 基础 Prompt(来自 Agent Profile)
|
|
12
|
+
* - 工具说明注入
|
|
13
|
+
* - 记忆上下文
|
|
14
|
+
* - Skill 上下文
|
|
15
|
+
*/
|
|
16
|
+
export declare class PromptBuilderService {
|
|
17
|
+
ctx: Context;
|
|
18
|
+
agentProfileService: AgentProfileService;
|
|
19
|
+
mcpServerService: MCPServerService;
|
|
20
|
+
skillService: AISkillService;
|
|
21
|
+
/**
|
|
22
|
+
* 构建完整的系统提示词
|
|
23
|
+
*/
|
|
24
|
+
buildSystemPrompt(applicationId: number, profileId?: number, options?: {
|
|
25
|
+
includeTools?: boolean;
|
|
26
|
+
includeSkills?: boolean;
|
|
27
|
+
includeMemory?: boolean;
|
|
28
|
+
memoryContext?: string;
|
|
29
|
+
}): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* 构建工具说明部分(使用 agent-server 共享片段)
|
|
32
|
+
*/
|
|
33
|
+
private buildToolSection;
|
|
34
|
+
/**
|
|
35
|
+
* 构建 Skill 上下文部分
|
|
36
|
+
*/
|
|
37
|
+
private buildSkillSection;
|
|
38
|
+
/**
|
|
39
|
+
* 构建默认 Agent 的系统提示词(使用 agent-server 共享片段)
|
|
40
|
+
*/
|
|
41
|
+
private getDefaultPrompt;
|
|
42
|
+
/**
|
|
43
|
+
* 构建 Specialist Agent 的系统提示词(使用 agent-server 共享片段)
|
|
44
|
+
*/
|
|
45
|
+
buildSpecialistPrompt(profile: AIAgentProfileEntity, toolRegistry?: ToolRegistry, skillManager?: SkillManager): string;
|
|
46
|
+
/**
|
|
47
|
+
* 解析工具显示名(delegate_task → "分发任务 → {agentName}")
|
|
48
|
+
*/
|
|
49
|
+
resolveToolDisplayName(toolName: string, args: Record<string, unknown>, toolRegistry?: ToolRegistry): string;
|
|
50
|
+
}
|