intention-coding 0.5.9 → 0.6.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/dist/index.cjs +1466 -782
- package/dist/services/change-summarizer/index.d.ts +2 -2
- package/dist/services/export-excel/index.d.ts +4 -4
- package/dist/services/image-analysis/analyzer.d.ts +2 -11
- package/dist/services/image-analysis/analyzer.d.ts.map +1 -1
- package/dist/services/image-analysis/index.d.ts +10 -10
- package/dist/services/image-analysis/index.d.ts.map +1 -1
- package/dist/services/image-recognition-agent/analyzer.d.ts +15 -1
- package/dist/services/image-recognition-agent/analyzer.d.ts.map +1 -1
- package/dist/services/image-recognition-agent/index.d.ts +2 -1
- package/dist/services/image-recognition-agent/index.d.ts.map +1 -1
- package/dist/services/image-recognition-agent/processor.d.ts +36 -8
- package/dist/services/image-recognition-agent/processor.d.ts.map +1 -1
- package/dist/services/image-recognition-agent/types.d.ts +3 -0
- package/dist/services/image-recognition-agent/types.d.ts.map +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/read-excel/index.d.ts +2 -2
- package/dist/services/requirement-analyzer/core/document-generator.d.ts +4 -2
- package/dist/services/requirement-analyzer/core/document-generator.d.ts.map +1 -1
- package/dist/services/requirement-analyzer/core/requirement-analyzer-service.d.ts +1 -0
- package/dist/services/requirement-analyzer/core/requirement-analyzer-service.d.ts.map +1 -1
- package/dist/services/requirement-analyzer/core/template-selector.d.ts.map +1 -1
- package/dist/services/requirement-analyzer/core/types.d.ts +4 -1
- package/dist/services/requirement-analyzer/core/types.d.ts.map +1 -1
- package/dist/services/requirement-analyzer/index.d.ts +6 -1
- package/dist/services/requirement-analyzer/index.d.ts.map +1 -1
- package/dist/services/requirement-analyzer/prompt/html-page-template.d.ts +6 -0
- package/dist/services/requirement-analyzer/prompt/html-page-template.d.ts.map +1 -0
- package/dist/services/requirement-analyzer/prompt/intelligent-requirement-analysis.d.ts +1 -1
- package/dist/services/requirement-analyzer/prompt/intelligent-requirement-analysis.d.ts.map +1 -1
- package/dist/services/tech-spec-generator/doc-renderer.d.ts +13 -0
- package/dist/services/tech-spec-generator/doc-renderer.d.ts.map +1 -0
- package/dist/services/tech-spec-generator/index.d.ts +380 -0
- package/dist/services/tech-spec-generator/index.d.ts.map +1 -0
- package/dist/services/tech-spec-generator/types.d.ts +122 -0
- package/dist/services/tech-spec-generator/types.d.ts.map +1 -0
- package/dist/services/world2md/index.d.ts +1 -1
- package/dist/utils/dify.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/openai.d.ts +18 -2
- package/dist/utils/openai.d.ts.map +1 -1
- package/dist//346/212/200/346/234/257/350/247/204/346/240/274/350/257/264/346/230/216/344/271/246/346/250/241/346/235/277.docx +0 -0
- package/package.json +4 -2
- package/bin/intention-coding.cjs +0 -4
- package/dist/services/requirement-analyzer/prompt/app-template.d.ts +0 -2
- package/dist/services/requirement-analyzer/prompt/app-template.d.ts.map +0 -1
- package/dist/services/requirement-analyzer/prompt/pc-page-template.d.ts +0 -2
- package/dist/services/requirement-analyzer/prompt/pc-page-template.d.ts.map +0 -1
- package/dist/services/requirement-analyzer/prompt/sdk-template.d.ts +0 -2
- package/dist/services/requirement-analyzer/prompt/sdk-template.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
|
|
3
|
+
return 'undefined' == typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
|
|
4
|
+
}();
|
|
2
5
|
var __webpack_modules__ = {
|
|
6
|
+
"fs/promises": function(module) {
|
|
7
|
+
module.exports = import("fs/promises").then(function(module) {
|
|
8
|
+
return module;
|
|
9
|
+
});
|
|
10
|
+
},
|
|
11
|
+
path: function(module) {
|
|
12
|
+
module.exports = import("path").then(function(module) {
|
|
13
|
+
return module;
|
|
14
|
+
});
|
|
15
|
+
},
|
|
3
16
|
"pdf-parse/lib/pdf-parse.js": function(module) {
|
|
4
17
|
module.exports = import("pdf-parse/lib/pdf-parse.js").then(function(module) {
|
|
5
18
|
return module;
|
|
@@ -60,18 +73,15 @@ var __webpack_exports__ = {};
|
|
|
60
73
|
var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
|
|
61
74
|
const external_winston_namespaceObject = require("winston");
|
|
62
75
|
var external_winston_default = /*#__PURE__*/ __webpack_require__.n(external_winston_namespaceObject);
|
|
63
|
-
const
|
|
64
|
-
var
|
|
65
|
-
|
|
76
|
+
const external_os_namespaceObject = require("os");
|
|
77
|
+
var external_os_default = /*#__PURE__*/ __webpack_require__.n(external_os_namespaceObject);
|
|
78
|
+
const isProduction = "production" === process.env.NODE_ENV || !process.env.npm_lifecycle_event;
|
|
79
|
+
const logDir = external_path_default().join(external_os_default().homedir(), ".aico", "logs");
|
|
66
80
|
try {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
} catch (error) {
|
|
73
|
-
logDir = process.env.TMPDIR || "/tmp/aico-logs";
|
|
74
|
-
}
|
|
81
|
+
external_fs_default().mkdirSync(logDir, {
|
|
82
|
+
recursive: true
|
|
83
|
+
});
|
|
84
|
+
} catch {}
|
|
75
85
|
const levels = {
|
|
76
86
|
error: 0,
|
|
77
87
|
warn: 1,
|
|
@@ -79,20 +89,6 @@ var __webpack_exports__ = {};
|
|
|
79
89
|
debug: 3,
|
|
80
90
|
verbose: 4
|
|
81
91
|
};
|
|
82
|
-
const colors = {
|
|
83
|
-
error: 'red',
|
|
84
|
-
warn: 'yellow',
|
|
85
|
-
info: 'green',
|
|
86
|
-
debug: 'blue',
|
|
87
|
-
verbose: 'cyan'
|
|
88
|
-
};
|
|
89
|
-
external_winston_default().addColors(colors);
|
|
90
|
-
const consoleFormat = external_winston_default().format.combine(external_winston_default().format.timestamp({
|
|
91
|
-
format: 'YYYY-MM-DD HH:mm:ss'
|
|
92
|
-
}), external_winston_default().format.colorize(), external_winston_default().format.printf(({ timestamp, level, message, ...meta })=>{
|
|
93
|
-
const metaStr = Object.keys(meta).length ? JSON.stringify(meta, null, 2) : '';
|
|
94
|
-
return `${timestamp} [${level}]: ${message} ${metaStr}`;
|
|
95
|
-
}));
|
|
96
92
|
const fileFormat = external_winston_default().format.combine(external_winston_default().format.timestamp(), external_winston_default().format.errors({
|
|
97
93
|
stack: true
|
|
98
94
|
}), external_winston_default().format.json());
|
|
@@ -103,11 +99,11 @@ var __webpack_exports__ = {};
|
|
|
103
99
|
const error = meta.error || meta;
|
|
104
100
|
const errorInfo = {
|
|
105
101
|
timestamp,
|
|
106
|
-
level: level ||
|
|
107
|
-
message: message ||
|
|
108
|
-
stack: stack || error && error.stack ||
|
|
102
|
+
level: level || "error",
|
|
103
|
+
message: message || "Uncaught Exception",
|
|
104
|
+
stack: stack || error && error.stack || "No stack trace available",
|
|
109
105
|
error: {
|
|
110
|
-
name: error && error.name ||
|
|
106
|
+
name: error && error.name || "Error",
|
|
111
107
|
message: error && error.message || String(error || message),
|
|
112
108
|
code: error && error.code || meta.code,
|
|
113
109
|
...meta
|
|
@@ -115,50 +111,48 @@ var __webpack_exports__ = {};
|
|
|
115
111
|
};
|
|
116
112
|
return JSON.stringify(errorInfo, null, 2);
|
|
117
113
|
}));
|
|
118
|
-
const transports = [
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
})
|
|
123
|
-
];
|
|
124
|
-
if (logDir) transports.push(new (external_winston_daily_rotate_file_default())({
|
|
125
|
-
filename: external_path_default().join(logDir, 'application-%DATE%.log'),
|
|
126
|
-
datePattern: 'YYYY-MM-DD',
|
|
127
|
-
zippedArchive: true,
|
|
128
|
-
maxSize: '2m',
|
|
129
|
-
maxFiles: '1d',
|
|
114
|
+
const transports = [];
|
|
115
|
+
transports.push(new (external_winston_default()).transports.File({
|
|
116
|
+
filename: external_path_default().join(logDir, "error.log"),
|
|
117
|
+
level: "error",
|
|
130
118
|
format: fileFormat,
|
|
131
|
-
|
|
119
|
+
maxsize: 5242880,
|
|
120
|
+
maxFiles: 1,
|
|
121
|
+
tailable: true
|
|
122
|
+
}));
|
|
123
|
+
if (!isProduction) transports.push(new (external_winston_default()).transports.File({
|
|
124
|
+
filename: external_path_default().join(logDir, "app.log"),
|
|
125
|
+
level: "info",
|
|
126
|
+
format: fileFormat,
|
|
127
|
+
maxsize: 5242880,
|
|
128
|
+
maxFiles: 1,
|
|
129
|
+
tailable: true
|
|
132
130
|
}));
|
|
133
131
|
const logger = external_winston_default().createLogger({
|
|
134
|
-
level:
|
|
132
|
+
level: isProduction ? "error" : "debug",
|
|
135
133
|
levels,
|
|
136
134
|
format: external_winston_default().format.combine(external_winston_default().format.errors({
|
|
137
135
|
stack: true
|
|
138
136
|
}), external_winston_default().format.splat()),
|
|
139
137
|
transports,
|
|
140
|
-
exceptionHandlers:
|
|
141
|
-
new (
|
|
142
|
-
filename: external_path_default().join(logDir,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
maxFiles: '1d',
|
|
147
|
-
format: exceptionFormat
|
|
138
|
+
exceptionHandlers: [
|
|
139
|
+
new (external_winston_default()).transports.File({
|
|
140
|
+
filename: external_path_default().join(logDir, "error.log"),
|
|
141
|
+
format: exceptionFormat,
|
|
142
|
+
maxsize: 5242880,
|
|
143
|
+
maxFiles: 1
|
|
148
144
|
})
|
|
149
|
-
]
|
|
150
|
-
rejectionHandlers:
|
|
151
|
-
new (
|
|
152
|
-
filename: external_path_default().join(logDir,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
maxFiles: '1d',
|
|
157
|
-
format: exceptionFormat
|
|
145
|
+
],
|
|
146
|
+
rejectionHandlers: [
|
|
147
|
+
new (external_winston_default()).transports.File({
|
|
148
|
+
filename: external_path_default().join(logDir, "error.log"),
|
|
149
|
+
format: exceptionFormat,
|
|
150
|
+
maxsize: 5242880,
|
|
151
|
+
maxFiles: 1
|
|
158
152
|
})
|
|
159
|
-
]
|
|
153
|
+
]
|
|
160
154
|
});
|
|
161
|
-
process.on(
|
|
155
|
+
process.on("SIGINT", ()=>{
|
|
162
156
|
logger.end(()=>{
|
|
163
157
|
logger.info("\u65E5\u5FD7\u5DF2\u5173\u95ED");
|
|
164
158
|
process.exit(0);
|
|
@@ -316,7 +310,6 @@ var __webpack_exports__ = {};
|
|
|
316
310
|
var external_mammoth_default = /*#__PURE__*/ __webpack_require__.n(external_mammoth_namespaceObject);
|
|
317
311
|
const external_html_to_md_namespaceObject = require("html-to-md");
|
|
318
312
|
var external_html_to_md_default = /*#__PURE__*/ __webpack_require__.n(external_html_to_md_namespaceObject);
|
|
319
|
-
const external_os_namespaceObject = require("os");
|
|
320
313
|
const sanitizeFileName = (input)=>input.replace(/[\\/:*?"<>|\n\r#%&]/g, '').trim().replace(/\s+/g, '_').replace(/_+/g, '_').replace(/^_+|_+$/g, '');
|
|
321
314
|
function normalizePath(filePath) {
|
|
322
315
|
if (!filePath || 'string' != typeof filePath) throw new Error("\u6587\u4EF6\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");
|
|
@@ -4199,6 +4192,207 @@ var __webpack_exports__ = {};
|
|
|
4199
4192
|
ErrorCodes["UNSUPPORTED_REQUIREMENT_TYPE"] = "UNSUPPORTED_REQUIREMENT_TYPE";
|
|
4200
4193
|
return ErrorCodes;
|
|
4201
4194
|
}({});
|
|
4195
|
+
async function invokeFlow(params, streamCb) {
|
|
4196
|
+
const { appid = "app-ESTcrkOPOmkxdrO0120mE4s1", data, timeout = 1800000 } = params;
|
|
4197
|
+
const controller = new AbortController();
|
|
4198
|
+
const signal = controller.signal;
|
|
4199
|
+
if ("undefined" == typeof ReadableStream) throw new Error("ReadableStream is not supported in this environment");
|
|
4200
|
+
const fetchData = async (retryCount = 0)=>{
|
|
4201
|
+
try {
|
|
4202
|
+
const fetchOptions = {
|
|
4203
|
+
method: "POST",
|
|
4204
|
+
headers: {
|
|
4205
|
+
Authorization: `Bearer ${appid}`,
|
|
4206
|
+
"Content-Type": "application/json"
|
|
4207
|
+
},
|
|
4208
|
+
body: JSON.stringify({
|
|
4209
|
+
inputs: data,
|
|
4210
|
+
response_mode: "streaming",
|
|
4211
|
+
user: "aico-mcp"
|
|
4212
|
+
}),
|
|
4213
|
+
signal
|
|
4214
|
+
};
|
|
4215
|
+
const res = await fetch("http://11.0.166.20:9199/v1/workflows/run", fetchOptions);
|
|
4216
|
+
if (!res.ok) {
|
|
4217
|
+
if (retryCount < 3) {
|
|
4218
|
+
await new Promise((resolve)=>setTimeout(resolve, 1000));
|
|
4219
|
+
return fetchData(retryCount + 1);
|
|
4220
|
+
}
|
|
4221
|
+
const errorResponse = await res.text();
|
|
4222
|
+
throw new Error(`\u{7F51}\u{7EDC}\u{54CD}\u{5E94}\u{5F02}\u{5E38}: ${res.status} ${res.statusText} - ${errorResponse}`);
|
|
4223
|
+
}
|
|
4224
|
+
if (res.ok) if (res.body) {
|
|
4225
|
+
const reader = res.body.getReader();
|
|
4226
|
+
const decoder = new TextDecoder("utf-8");
|
|
4227
|
+
if (streamCb) return void new ReadableStream({
|
|
4228
|
+
start (controller) {
|
|
4229
|
+
let buffer = "";
|
|
4230
|
+
function push() {
|
|
4231
|
+
reader.read().then(({ done, value })=>{
|
|
4232
|
+
if (done) {
|
|
4233
|
+
const lines = buffer.split("\n");
|
|
4234
|
+
for (const line of lines)handleLine(line, controller);
|
|
4235
|
+
if (streamCb) streamCb({
|
|
4236
|
+
isEnd: true
|
|
4237
|
+
});
|
|
4238
|
+
controller.close();
|
|
4239
|
+
return;
|
|
4240
|
+
}
|
|
4241
|
+
const chunkText = decoder.decode(value, {
|
|
4242
|
+
stream: true
|
|
4243
|
+
});
|
|
4244
|
+
buffer += chunkText;
|
|
4245
|
+
const lines = buffer.split("\n");
|
|
4246
|
+
for(let i = 0; i < lines.length - 1; i++)handleLine(lines[i], controller);
|
|
4247
|
+
buffer = lines[lines.length - 1];
|
|
4248
|
+
push();
|
|
4249
|
+
});
|
|
4250
|
+
}
|
|
4251
|
+
function handleLine(line, controller) {
|
|
4252
|
+
line = line.trim();
|
|
4253
|
+
if (line.startsWith("data:")) {
|
|
4254
|
+
const dataStr = line.slice(5).trim();
|
|
4255
|
+
if ("" === dataStr) return;
|
|
4256
|
+
try {
|
|
4257
|
+
const jsonData = JSON.parse(dataStr);
|
|
4258
|
+
if (jsonData.data?.text) {
|
|
4259
|
+
const wrappedData = {
|
|
4260
|
+
content: jsonData.data.text.toString(),
|
|
4261
|
+
controller
|
|
4262
|
+
};
|
|
4263
|
+
if (streamCb) streamCb(wrappedData);
|
|
4264
|
+
}
|
|
4265
|
+
} catch (e) {
|
|
4266
|
+
console.error("\u89E3\u6790JSON\u5931\u8D25:", e);
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
push();
|
|
4271
|
+
}
|
|
4272
|
+
});
|
|
4273
|
+
{
|
|
4274
|
+
let buffer = "";
|
|
4275
|
+
let accumulatedText = "";
|
|
4276
|
+
let isResponseEnded = false;
|
|
4277
|
+
const readAll = async ()=>{
|
|
4278
|
+
const { done, value } = await reader.read();
|
|
4279
|
+
if (done) {
|
|
4280
|
+
if (!isResponseEnded) throw new Error("\u54CD\u5E94\u63D0\u524D\u7ED3\u675F");
|
|
4281
|
+
return accumulatedText;
|
|
4282
|
+
}
|
|
4283
|
+
const chunkText = decoder.decode(value, {
|
|
4284
|
+
stream: true
|
|
4285
|
+
});
|
|
4286
|
+
buffer += chunkText;
|
|
4287
|
+
const lines = buffer.split("\n");
|
|
4288
|
+
for(let i = 0; i < lines.length - 1; i++){
|
|
4289
|
+
const line = lines[i].trim();
|
|
4290
|
+
if (!line.startsWith("data:")) continue;
|
|
4291
|
+
const dataStr = line.slice(5).trim();
|
|
4292
|
+
if ("" !== dataStr) try {
|
|
4293
|
+
const jsonData = JSON.parse(dataStr);
|
|
4294
|
+
switch(jsonData.event){
|
|
4295
|
+
case "message":
|
|
4296
|
+
case "agent_message":
|
|
4297
|
+
case "text_chunk":
|
|
4298
|
+
{
|
|
4299
|
+
const content = "text_chunk" === jsonData.event ? jsonData.data.text : jsonData.answer;
|
|
4300
|
+
accumulatedText += content;
|
|
4301
|
+
break;
|
|
4302
|
+
}
|
|
4303
|
+
case "workflow_finished":
|
|
4304
|
+
if (jsonData.data?.outputs?.text) accumulatedText = jsonData.data.outputs.text;
|
|
4305
|
+
else if (jsonData.data?.outputs) {
|
|
4306
|
+
const outputs = jsonData.data.outputs;
|
|
4307
|
+
const textValue = Object.values(outputs).find((v)=>"string" == typeof v && v.length > 0);
|
|
4308
|
+
if (textValue) accumulatedText = textValue;
|
|
4309
|
+
}
|
|
4310
|
+
isResponseEnded = true;
|
|
4311
|
+
break;
|
|
4312
|
+
case "message_end":
|
|
4313
|
+
isResponseEnded = true;
|
|
4314
|
+
break;
|
|
4315
|
+
case "error":
|
|
4316
|
+
throw new Error(`\u{670D}\u{52A1}\u{5668}\u{9519}\u{8BEF}: ${jsonData.code}, ${jsonData.message}`);
|
|
4317
|
+
default:
|
|
4318
|
+
break;
|
|
4319
|
+
}
|
|
4320
|
+
} catch (e) {
|
|
4321
|
+
throw new Error("\u89E3\u6790JSON\u5931\u8D25: " + e.message);
|
|
4322
|
+
}
|
|
4323
|
+
}
|
|
4324
|
+
buffer = lines[lines.length - 1];
|
|
4325
|
+
return readAll();
|
|
4326
|
+
};
|
|
4327
|
+
return readAll();
|
|
4328
|
+
}
|
|
4329
|
+
} else throw new Error("\u54CD\u5E94\u4F53\u4E3A\u7A7A");
|
|
4330
|
+
{
|
|
4331
|
+
const errorResponse = await res.text();
|
|
4332
|
+
throw new Error(`\u{7F51}\u{7EDC}\u{54CD}\u{5E94}\u{5F02}\u{5E38}: ${res.status} ${res.statusText} - ${errorResponse}`);
|
|
4333
|
+
}
|
|
4334
|
+
} catch (error) {
|
|
4335
|
+
if ("AbortError" === error.name) throw new Error("\u8BF7\u6C42\u5DF2\u88AB\u4E2D\u6B62\uFF0C\u8D85\u65F6");
|
|
4336
|
+
throw error;
|
|
4337
|
+
}
|
|
4338
|
+
};
|
|
4339
|
+
try {
|
|
4340
|
+
const result = await Promise.race([
|
|
4341
|
+
fetchData(),
|
|
4342
|
+
new Promise((_, reject)=>{
|
|
4343
|
+
setTimeout(()=>{
|
|
4344
|
+
controller.abort();
|
|
4345
|
+
reject(new Error("\u8BF7\u6C42\u8D85\u65F6"));
|
|
4346
|
+
}, timeout);
|
|
4347
|
+
})
|
|
4348
|
+
]);
|
|
4349
|
+
if (streamCb) return;
|
|
4350
|
+
return result;
|
|
4351
|
+
} catch (error) {
|
|
4352
|
+
controller.abort();
|
|
4353
|
+
throw error;
|
|
4354
|
+
}
|
|
4355
|
+
}
|
|
4356
|
+
async function uploadFile(params) {
|
|
4357
|
+
const { appid, filePath, user = "aico-mcp" } = params;
|
|
4358
|
+
try {
|
|
4359
|
+
const fileBuffer = await external_fs_default().promises.readFile(filePath);
|
|
4360
|
+
const fileName = external_path_default().basename(filePath);
|
|
4361
|
+
const fileExtension = external_path_default().extname(filePath).toLowerCase().slice(1);
|
|
4362
|
+
const mimeTypes = {
|
|
4363
|
+
png: "image/png",
|
|
4364
|
+
jpeg: "image/jpeg",
|
|
4365
|
+
jpg: "image/jpeg",
|
|
4366
|
+
webp: "image/webp",
|
|
4367
|
+
gif: "image/gif"
|
|
4368
|
+
};
|
|
4369
|
+
const mimeType = mimeTypes[fileExtension] || "application/octet-stream";
|
|
4370
|
+
const formData = new FormData();
|
|
4371
|
+
formData.append("file", new Blob([
|
|
4372
|
+
fileBuffer.buffer
|
|
4373
|
+
], {
|
|
4374
|
+
type: mimeType
|
|
4375
|
+
}), fileName);
|
|
4376
|
+
formData.append("user", user);
|
|
4377
|
+
const response = await fetch("http://11.0.166.20:9199/v1/files/upload", {
|
|
4378
|
+
method: "POST",
|
|
4379
|
+
headers: {
|
|
4380
|
+
Authorization: `Bearer ${appid}`
|
|
4381
|
+
},
|
|
4382
|
+
body: formData
|
|
4383
|
+
});
|
|
4384
|
+
if (!response.ok) {
|
|
4385
|
+
const errorText = await response.text();
|
|
4386
|
+
throw new Error(`\u{6587}\u{4EF6}\u{4E0A}\u{4F20}\u{5931}\u{8D25}: ${response.status} ${response.statusText} - ${errorText}`);
|
|
4387
|
+
}
|
|
4388
|
+
const result = await response.json();
|
|
4389
|
+
if (!result.id || !result.name) throw new Error("\u65E0\u6548\u7684\u6587\u4EF6\u4E0A\u4F20\u54CD\u5E94\u683C\u5F0F");
|
|
4390
|
+
return result;
|
|
4391
|
+
} catch (error) {
|
|
4392
|
+
if (error instanceof Error) throw new Error(`\u{6587}\u{4EF6}\u{4E0A}\u{4F20}\u{5931}\u{8D25}: ${error.message}`);
|
|
4393
|
+
throw new Error("\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: \u672A\u77E5\u9519\u8BEF");
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4202
4396
|
class OpenAIService {
|
|
4203
4397
|
qwenConfig = {
|
|
4204
4398
|
apiKey: "sk-95b0bc60b7464bbbafd64edc2f5bab14",
|
|
@@ -4220,6 +4414,10 @@ var __webpack_exports__ = {};
|
|
|
4220
4414
|
baseUrl: "https://api.lkeap.cloud.tencent.com/v1/chat/completions",
|
|
4221
4415
|
model: "deepseek-v3.1-terminus"
|
|
4222
4416
|
};
|
|
4417
|
+
difyConfig = {
|
|
4418
|
+
apiKey: "app-AvlLh0nfN4l9oz1MSW4sEAQ6",
|
|
4419
|
+
baseUrl: "http://11.0.166.20:9199/v1"
|
|
4420
|
+
};
|
|
4223
4421
|
constructor(){}
|
|
4224
4422
|
async generateText(params) {
|
|
4225
4423
|
const { prompt, temperature, system_prompt } = params;
|
|
@@ -4576,23 +4774,115 @@ var __webpack_exports__ = {};
|
|
|
4576
4774
|
}
|
|
4577
4775
|
}
|
|
4578
4776
|
}
|
|
4777
|
+
async analyzeImageWithPath(params) {
|
|
4778
|
+
const { prompt, image_path, system_prompt } = params;
|
|
4779
|
+
logger.info("[OpenAI] analyzeImageWithPath \u88AB\u8C03\u7528", {
|
|
4780
|
+
image_path,
|
|
4781
|
+
prompt_length: prompt.length
|
|
4782
|
+
});
|
|
4783
|
+
try {
|
|
4784
|
+
logger.info("[OpenAI] \u5F00\u59CB\u4E0A\u4F20\u6587\u4EF6\u5230 Dify", {
|
|
4785
|
+
image_path
|
|
4786
|
+
});
|
|
4787
|
+
const uploadResult = await uploadFile({
|
|
4788
|
+
appid: this.difyConfig.apiKey,
|
|
4789
|
+
filePath: image_path,
|
|
4790
|
+
user: "aico-mcp"
|
|
4791
|
+
});
|
|
4792
|
+
logger.info("[OpenAI] \u6587\u4EF6\u4E0A\u4F20\u6210\u529F", {
|
|
4793
|
+
upload_file_id: uploadResult.id
|
|
4794
|
+
});
|
|
4795
|
+
const workflowData = {
|
|
4796
|
+
imagePath: {
|
|
4797
|
+
type: "image",
|
|
4798
|
+
transfer_method: "local_file",
|
|
4799
|
+
upload_file_id: uploadResult.id
|
|
4800
|
+
},
|
|
4801
|
+
context: prompt
|
|
4802
|
+
};
|
|
4803
|
+
logger.info("[OpenAI] \u5F00\u59CB\u8C03\u7528 Dify \u5DE5\u4F5C\u6D41");
|
|
4804
|
+
const workflowResponse = await invokeFlow({
|
|
4805
|
+
appid: this.difyConfig.apiKey,
|
|
4806
|
+
data: workflowData,
|
|
4807
|
+
timeout: 120000
|
|
4808
|
+
});
|
|
4809
|
+
logger.info("[OpenAI] Dify \u5DE5\u4F5C\u6D41\u8C03\u7528\u6210\u529F", {
|
|
4810
|
+
response_type: typeof workflowResponse,
|
|
4811
|
+
response_preview: "string" == typeof workflowResponse ? workflowResponse.substring(0, 200) : JSON.stringify(workflowResponse).substring(0, 500)
|
|
4812
|
+
});
|
|
4813
|
+
let summary = "";
|
|
4814
|
+
if ("string" == typeof workflowResponse && workflowResponse.length > 0) summary = workflowResponse;
|
|
4815
|
+
else if (workflowResponse?.outputs?.text) summary = workflowResponse.outputs.text;
|
|
4816
|
+
else if (workflowResponse?.data?.outputs?.text) summary = workflowResponse.data.outputs.text;
|
|
4817
|
+
else if (workflowResponse?.data?.text) summary = workflowResponse.data.text;
|
|
4818
|
+
else if (workflowResponse?.answer) summary = workflowResponse.answer;
|
|
4819
|
+
else if (workflowResponse?.status === "failed") throw new Error(`Dify\u{5DE5}\u{4F5C}\u{6D41}\u{6267}\u{884C}\u{5931}\u{8D25}: ${workflowResponse.error || "\u672A\u77E5\u9519\u8BEF"}`);
|
|
4820
|
+
if (!summary || 0 === summary.length) {
|
|
4821
|
+
logger.error("[OpenAI] Dify \u54CD\u5E94\u89E3\u6790\u5931\u8D25\uFF0C\u65E0\u6CD5\u63D0\u53D6\u6587\u672C\u5185\u5BB9", {
|
|
4822
|
+
response: JSON.stringify(workflowResponse)
|
|
4823
|
+
});
|
|
4824
|
+
throw new Error("Dify\u5DE5\u4F5C\u6D41\u54CD\u5E94\u4E2D\u672A\u627E\u5230\u6709\u6548\u6587\u672C\u5185\u5BB9");
|
|
4825
|
+
}
|
|
4826
|
+
logger.info("[OpenAI] Dify \u5206\u6790\u5B8C\u6210", {
|
|
4827
|
+
summary_length: summary.length
|
|
4828
|
+
});
|
|
4829
|
+
return summary;
|
|
4830
|
+
} catch (difyError) {
|
|
4831
|
+
logger.error("[OpenAI] Dify \u8C03\u7528\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u5176\u4ED6\u670D\u52A1", {
|
|
4832
|
+
error: difyError instanceof Error ? difyError.message : String(difyError)
|
|
4833
|
+
});
|
|
4834
|
+
const fs = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "fs/promises"));
|
|
4835
|
+
const path = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "path"));
|
|
4836
|
+
const imageBuffer = await fs.readFile(image_path);
|
|
4837
|
+
const base64 = imageBuffer.toString("base64");
|
|
4838
|
+
const ext = path.extname(image_path).toLowerCase();
|
|
4839
|
+
let mimeType = "image/jpeg";
|
|
4840
|
+
switch(ext){
|
|
4841
|
+
case ".png":
|
|
4842
|
+
mimeType = "image/png";
|
|
4843
|
+
break;
|
|
4844
|
+
case ".gif":
|
|
4845
|
+
mimeType = "image/gif";
|
|
4846
|
+
break;
|
|
4847
|
+
case ".webp":
|
|
4848
|
+
mimeType = "image/webp";
|
|
4849
|
+
break;
|
|
4850
|
+
case ".jpg":
|
|
4851
|
+
case ".jpeg":
|
|
4852
|
+
mimeType = "image/jpeg";
|
|
4853
|
+
break;
|
|
4854
|
+
}
|
|
4855
|
+
const image_base64 = `data:${mimeType};base64,${base64}`;
|
|
4856
|
+
return this.analyzeImage({
|
|
4857
|
+
prompt,
|
|
4858
|
+
image_base64,
|
|
4859
|
+
system_prompt
|
|
4860
|
+
});
|
|
4861
|
+
}
|
|
4862
|
+
}
|
|
4579
4863
|
async analyzeImage(params) {
|
|
4580
4864
|
const { prompt, image_base64, system_prompt } = params;
|
|
4581
|
-
let lastError = null;
|
|
4582
4865
|
try {
|
|
4583
|
-
const
|
|
4866
|
+
const controller = new AbortController();
|
|
4867
|
+
const timeoutId = setTimeout(()=>controller.abort(), 20000);
|
|
4868
|
+
const response = await fetch(this.kimiConfig.baseUrl, {
|
|
4584
4869
|
method: "POST",
|
|
4585
4870
|
headers: {
|
|
4586
4871
|
"Content-Type": "application/json",
|
|
4587
|
-
Authorization: `Bearer ${this.
|
|
4872
|
+
Authorization: `Bearer ${this.kimiConfig.apiKey}`
|
|
4588
4873
|
},
|
|
4589
4874
|
body: JSON.stringify({
|
|
4590
|
-
model: this.
|
|
4875
|
+
model: this.kimiConfig.model,
|
|
4591
4876
|
messages: [
|
|
4592
4877
|
...system_prompt ? [
|
|
4593
4878
|
{
|
|
4594
4879
|
role: "system",
|
|
4595
|
-
content:
|
|
4880
|
+
content: [
|
|
4881
|
+
{
|
|
4882
|
+
type: "text",
|
|
4883
|
+
text: system_prompt
|
|
4884
|
+
}
|
|
4885
|
+
]
|
|
4596
4886
|
}
|
|
4597
4887
|
] : [],
|
|
4598
4888
|
{
|
|
@@ -4612,36 +4902,34 @@ var __webpack_exports__ = {};
|
|
|
4612
4902
|
}
|
|
4613
4903
|
],
|
|
4614
4904
|
stream: false
|
|
4615
|
-
})
|
|
4905
|
+
}),
|
|
4906
|
+
signal: controller.signal
|
|
4616
4907
|
});
|
|
4908
|
+
clearTimeout(timeoutId);
|
|
4617
4909
|
if (!response.ok) {
|
|
4618
4910
|
const errorText = await response.text();
|
|
4619
|
-
throw new Error(`
|
|
4911
|
+
throw new Error(`Kimi Vision API error: ${response.status} ${response.statusText} - ${errorText}`);
|
|
4620
4912
|
}
|
|
4621
4913
|
const data = await response.json();
|
|
4622
|
-
if (!data.choices || 0 === data.choices.length) throw new Error("No choices returned from
|
|
4914
|
+
if (!data.choices || 0 === data.choices.length) throw new Error("No choices returned from Kimi Vision API");
|
|
4623
4915
|
return data.choices[0].message.content;
|
|
4624
|
-
} catch (
|
|
4625
|
-
lastError = error;
|
|
4916
|
+
} catch (kimiError) {
|
|
4626
4917
|
try {
|
|
4627
|
-
const
|
|
4918
|
+
const controller = new AbortController();
|
|
4919
|
+
const timeoutId = setTimeout(()=>controller.abort(), 15000);
|
|
4920
|
+
const response = await fetch(this.glm4vConfig.baseUrl, {
|
|
4628
4921
|
method: "POST",
|
|
4629
4922
|
headers: {
|
|
4630
4923
|
"Content-Type": "application/json",
|
|
4631
|
-
Authorization: `Bearer ${this.
|
|
4924
|
+
Authorization: `Bearer ${this.glm4vConfig.apiKey}`
|
|
4632
4925
|
},
|
|
4633
4926
|
body: JSON.stringify({
|
|
4634
|
-
model: this.
|
|
4927
|
+
model: this.glm4vConfig.model,
|
|
4635
4928
|
messages: [
|
|
4636
4929
|
...system_prompt ? [
|
|
4637
4930
|
{
|
|
4638
4931
|
role: "system",
|
|
4639
|
-
content:
|
|
4640
|
-
{
|
|
4641
|
-
type: "text",
|
|
4642
|
-
text: system_prompt
|
|
4643
|
-
}
|
|
4644
|
-
]
|
|
4932
|
+
content: system_prompt
|
|
4645
4933
|
}
|
|
4646
4934
|
] : [],
|
|
4647
4935
|
{
|
|
@@ -4661,41 +4949,57 @@ var __webpack_exports__ = {};
|
|
|
4661
4949
|
}
|
|
4662
4950
|
],
|
|
4663
4951
|
stream: false
|
|
4664
|
-
})
|
|
4952
|
+
}),
|
|
4953
|
+
signal: controller.signal
|
|
4665
4954
|
});
|
|
4955
|
+
clearTimeout(timeoutId);
|
|
4666
4956
|
if (!response.ok) {
|
|
4667
4957
|
const errorText = await response.text();
|
|
4668
|
-
throw new Error(`
|
|
4958
|
+
throw new Error(`GLM-4V API error: ${response.status} ${response.statusText} - ${errorText}`);
|
|
4669
4959
|
}
|
|
4670
4960
|
const data = await response.json();
|
|
4671
|
-
if (!data.choices || 0 === data.choices.length) throw new Error("No choices returned from
|
|
4961
|
+
if (!data.choices || 0 === data.choices.length) throw new Error("No choices returned from GLM-4V API");
|
|
4672
4962
|
return data.choices[0].message.content;
|
|
4673
|
-
} catch (
|
|
4674
|
-
throw
|
|
4963
|
+
} catch (glmError) {
|
|
4964
|
+
throw new Error(`All vision services failed. Kimi: ${kimiError instanceof Error ? kimiError.message : String(kimiError)}, GLM-4V: ${glmError instanceof Error ? glmError.message : String(glmError)}`);
|
|
4675
4965
|
}
|
|
4676
4966
|
}
|
|
4677
4967
|
}
|
|
4678
4968
|
}
|
|
4679
4969
|
const openAIService = new OpenAIService();
|
|
4680
|
-
const intelligentRequirementAnalysisPrompt = `\u{4F60}\u{662F}\u{8F6F}\u{4EF6}\u{9700}\u{6C42}\u{5206}\u{6790}\u{5E08}\u{FF0C}\u{
|
|
4970
|
+
const intelligentRequirementAnalysisPrompt = `\u{4F60}\u{662F}\u{8D44}\u{6DF1}\u{8F6F}\u{4EF6}\u{9700}\u{6C42}\u{5206}\u{6790}\u{5E08}\u{FF0C}\u{8D1F}\u{8D23}\u{6DF1}\u{5EA6}\u{5206}\u{6790}\u{7528}\u{6237}\u{9700}\u{6C42}\u{5E76}\u{63D0}\u{53D6}\u{7ED3}\u{6784}\u{5316}\u{4FE1}\u{606F}\u{FF0C}\u{4E3A}\u{540E}\u{7EED}\u{6587}\u{6863}\u{751F}\u{6210}\u{63D0}\u{4F9B}\u{5B8C}\u{6574}\u{7684}\u{4E0A}\u{4E0B}\u{6587}\u{3002}
|
|
4681
4971
|
|
|
4682
4972
|
**\u{8F93}\u{5165}\u{5185}\u{5BB9}**:
|
|
4683
4973
|
{inputContent}
|
|
4684
4974
|
|
|
4685
|
-
## \u{
|
|
4975
|
+
## \u{5206}\u{6790}\u{4EFB}\u{52A1}
|
|
4976
|
+
|
|
4977
|
+
\u{4F60}\u{9700}\u{8981}\u{5B8C}\u{6210}\u{4EE5}\u{4E0B}\u{5206}\u{6790}\u{4EFB}\u{52A1}\u{FF0C}\u{4E3A}MCP\u{5BA2}\u{6237}\u{7AEF}\u{751F}\u{6210}\u{6280}\u{672F}\u{6587}\u{6863}\u{63D0}\u{4F9B}\u{5145}\u{5206}\u{7684}\u{4E0A}\u{4E0B}\u{6587}\u{FF1A}
|
|
4686
4978
|
|
|
4687
|
-
|
|
4688
|
-
**PC\u{9875}\u{9762}**: \u{9875}\u{9762}\u{3001}UI\u{3001}\u{7F51}\u{9875}\u{3001}\u{524D}\u{7AEF}\u{3001}\u{7BA1}\u{7406}\u{540E}\u{53F0} \u{2192} \u{7528}\u{6237}\u{754C}\u{9762}\u{3001}\u{8868}\u{5355}\u{64CD}\u{4F5C}\u{3001}\u{6570}\u{636E}\u{5C55}\u{793A}
|
|
4689
|
-
**APP**: \u{79FB}\u{52A8}\u{5E94}\u{7528}\u{3001}iOS\u{3001}Android\u{3001}\u{5C0F}\u{7A0B}\u{5E8F} \u{2192} \u{79FB}\u{52A8}\u{7AEF}\u{529F}\u{80FD}\u{3001}\u{624B}\u{52BF}\u{64CD}\u{4F5C}\u{3001}\u{8BBE}\u{5907}\u{7279}\u{6027}
|
|
4690
|
-
**SDK\u{96C6}\u{6210}**: \u{7B2C}\u{4E09}\u{65B9}\u{3001}\u{5BF9}\u{63A5}\u{3001}\u{652F}\u{4ED8}\u{3001}\u{5730}\u{56FE}\u{3001}\u{63A8}\u{9001} \u{2192} \u{5916}\u{90E8}\u{670D}\u{52A1}\u{5BF9}\u{63A5}\u{3001}\u{914D}\u{7F6E}\u{53C2}\u{6570}\u{3001}\u{56DE}\u{8C03}\u{5904}\u{7406}
|
|
4691
|
-
**\u{6DF7}\u{5408}**: \u{5305}\u{542B}\u{591A}\u{79CD}\u{7C7B}\u{578B}\u{7279}\u{5F81}
|
|
4979
|
+
### 1. \u{9700}\u{6C42}\u{7C7B}\u{578B}\u{8BC6}\u{522B}
|
|
4692
4980
|
|
|
4693
|
-
|
|
4981
|
+
\u{6839}\u{636E}\u{5173}\u{952E}\u{8BCD}\u{548C}\u{4E1A}\u{52A1}\u{573A}\u{666F}\u{8BC6}\u{522B}\u{9700}\u{6C42}\u{7C7B}\u{578B}\u{FF1A}
|
|
4982
|
+
- **\u{63A5}\u{53E3}(API)**: API\u{3001}REST\u{3001}GraphQL\u{3001}\u{5FAE}\u{670D}\u{52A1}\u{3001}\u{540E}\u{7AEF}\u{670D}\u{52A1}\u{3001}\u{6570}\u{636E}\u{63A5}\u{53E3}
|
|
4983
|
+
- **PC\u{9875}\u{9762}**: \u{9875}\u{9762}\u{3001}UI\u{3001}\u{7F51}\u{9875}\u{3001}\u{524D}\u{7AEF}\u{3001}\u{7BA1}\u{7406}\u{540E}\u{53F0}\u{3001}Web\u{7AEF}
|
|
4984
|
+
- **APP**: \u{79FB}\u{52A8}\u{5E94}\u{7528}\u{3001}iOS\u{3001}Android\u{3001}\u{5C0F}\u{7A0B}\u{5E8F}\u{3001}\u{79FB}\u{52A8}\u{7AEF}
|
|
4985
|
+
- **SDK\u{96C6}\u{6210}**: \u{7B2C}\u{4E09}\u{65B9}\u{3001}\u{5BF9}\u{63A5}\u{3001}\u{652F}\u{4ED8}\u{3001}\u{5730}\u{56FE}\u{3001}\u{63A8}\u{9001}\u{3001}SDK
|
|
4694
4986
|
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4987
|
+
### 2. \u{6DF1}\u{5EA6}\u{9700}\u{6C42}\u{5206}\u{6790}
|
|
4988
|
+
|
|
4989
|
+
\u{5BF9}\u{6BCF}\u{4E2A}\u{529F}\u{80FD}\u{70B9}\u{8FDB}\u{884C}\u{6DF1}\u{5EA6}\u{5206}\u{6790}\u{FF0C}\u{63D0}\u{53D6}\u{FF1A}
|
|
4990
|
+
- **\u{4E1A}\u{52A1}\u{80CC}\u{666F}**: \u{4E3A}\u{4EC0}\u{4E48}\u{9700}\u{8981}\u{8FD9}\u{4E2A}\u{529F}\u{80FD}
|
|
4991
|
+
- **\u{6838}\u{5FC3}\u{6D41}\u{7A0B}**: \u{4E3B}\u{8981}\u{7684}\u{4E1A}\u{52A1}\u{6D41}\u{7A0B}\u{6B65}\u{9AA4}
|
|
4992
|
+
- **\u{6570}\u{636E}\u{5B9E}\u{4F53}**: \u{6D89}\u{53CA}\u{7684}\u{6570}\u{636E}\u{5BF9}\u{8C61}\u{548C}\u{5B57}\u{6BB5}
|
|
4993
|
+
- **\u{4EA4}\u{4E92}\u{903B}\u{8F91}**: \u{7528}\u{6237}\u{64CD}\u{4F5C}\u{548C}\u{7CFB}\u{7EDF}\u{54CD}\u{5E94}
|
|
4994
|
+
- **\u{5F02}\u{5E38}\u{573A}\u{666F}**: \u{53EF}\u{80FD}\u{7684}\u{9519}\u{8BEF}\u{60C5}\u{51B5}\u{548C}\u{5904}\u{7406}\u{65B9}\u{5F0F}
|
|
4995
|
+
|
|
4996
|
+
### 3. \u{6280}\u{672F}\u{4E0A}\u{4E0B}\u{6587}\u{63D0}\u{53D6}
|
|
4997
|
+
|
|
4998
|
+
\u{4ECE}\u{9879}\u{76EE}\u{4FE1}\u{606F}\u{4E2D}\u{63D0}\u{53D6}\u{FF1A}
|
|
4999
|
+
- \u{6280}\u{672F}\u{6808}\u{548C}\u{6846}\u{67B6}
|
|
5000
|
+
- \u{73B0}\u{6709}\u{7684}\u{4EE3}\u{7801}\u{7ED3}\u{6784}
|
|
5001
|
+
- \u{4F9D}\u{8D56}\u{5173}\u{7CFB}
|
|
5002
|
+
- \u{8BBE}\u{8BA1}\u{89C4}\u{8303}
|
|
4699
5003
|
|
|
4700
5004
|
## \u{8F93}\u{51FA}\u{683C}\u{5F0F}
|
|
4701
5005
|
|
|
@@ -4707,14 +5011,36 @@ var __webpack_exports__ = {};
|
|
|
4707
5011
|
"requirementType": "\u{63A5}\u{53E3}|PC\u{9875}\u{9762}|APP|SDK\u{96C6}\u{6210}|\u{6DF7}\u{5408}\u{7C7B}\u{578B}",
|
|
4708
5012
|
"primaryTechnology": "\u{4E3B}\u{8981}\u{6280}\u{672F}\u{6808}\u{63CF}\u{8FF0}",
|
|
4709
5013
|
"confidence": "high|medium|low",
|
|
5014
|
+
"businessContext": {
|
|
5015
|
+
"background": "\u{4E1A}\u{52A1}\u{80CC}\u{666F}\u{63CF}\u{8FF0}",
|
|
5016
|
+
"objectives": ["\u{4E1A}\u{52A1}\u{76EE}\u{6807}1", "\u{4E1A}\u{52A1}\u{76EE}\u{6807}2"],
|
|
5017
|
+
"stakeholders": ["\u{6D89}\u{53CA}\u{7684}\u{89D2}\u{8272}1", "\u{6D89}\u{53CA}\u{7684}\u{89D2}\u{8272}2"]
|
|
5018
|
+
},
|
|
4710
5019
|
"requirements": [
|
|
4711
5020
|
{
|
|
4712
5021
|
"id": "req_001",
|
|
4713
5022
|
"title": "\u{529F}\u{80FD}\u{70B9}\u{540D}\u{79F0}",
|
|
4714
|
-
"fullContent": "\u{529F}\u{80FD}\u{70B9}\u{7684}\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}",
|
|
5023
|
+
"fullContent": "\u{529F}\u{80FD}\u{70B9}\u{7684}\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{FF0C}\u{5305}\u{542B}\u{5B8C}\u{6574}\u{7684}\u{4E1A}\u{52A1}\u{903B}\u{8F91}",
|
|
4715
5024
|
"priority": "high|medium|low",
|
|
4716
5025
|
"complexity": "\u{7B80}\u{5355}|\u{4E2D}\u{7B49}|\u{590D}\u{6742}",
|
|
4717
|
-
"type": "\u{63A5}\u{53E3}|PC\u{9875}\u{9762}|APP|SDK\u{96C6}\u{6210}"
|
|
5026
|
+
"type": "\u{63A5}\u{53E3}|PC\u{9875}\u{9762}|APP|SDK\u{96C6}\u{6210}",
|
|
5027
|
+
"businessFlow": {
|
|
5028
|
+
"preconditions": ["\u{524D}\u{7F6E}\u{6761}\u{4EF6}1"],
|
|
5029
|
+
"mainFlow": ["\u{6B65}\u{9AA4}1", "\u{6B65}\u{9AA4}2", "\u{6B65}\u{9AA4}3"],
|
|
5030
|
+
"alternativeFlows": ["\u{66FF}\u{4EE3}\u{6D41}\u{7A0B}1"],
|
|
5031
|
+
"exceptionFlows": ["\u{5F02}\u{5E38}\u{5904}\u{7406}1"]
|
|
5032
|
+
},
|
|
5033
|
+
"dataEntities": [
|
|
5034
|
+
{
|
|
5035
|
+
"name": "\u{5B9E}\u{4F53}\u{540D}\u{79F0}",
|
|
5036
|
+
"fields": [
|
|
5037
|
+
{"name": "\u{5B57}\u{6BB5}\u{540D}", "type": "\u{7C7B}\u{578B}", "required": true, "description": "\u{8BF4}\u{660E}"}
|
|
5038
|
+
]
|
|
5039
|
+
}
|
|
5040
|
+
],
|
|
5041
|
+
"interactions": [
|
|
5042
|
+
{"trigger": "\u{89E6}\u{53D1}\u{6761}\u{4EF6}", "action": "\u{7CFB}\u{7EDF}\u{52A8}\u{4F5C}", "response": "\u{54CD}\u{5E94}\u{7ED3}\u{679C}"}
|
|
5043
|
+
]
|
|
4718
5044
|
}
|
|
4719
5045
|
],
|
|
4720
5046
|
"templateRecommendation": {
|
|
@@ -4722,13 +5048,29 @@ var __webpack_exports__ = {};
|
|
|
4722
5048
|
"reason": "\u{9009}\u{62E9}\u{8BE5}\u{6A21}\u{677F}\u{7684}\u{539F}\u{56E0}",
|
|
4723
5049
|
"additionalTemplates": ["\u{5982}\u{679C}\u{662F}\u{6DF7}\u{5408}\u{7C7B}\u{578B}\u{FF0C}\u{5217}\u{51FA}\u{9700}\u{8981}\u{7684}\u{5176}\u{4ED6}\u{6A21}\u{677F}"]
|
|
4724
5050
|
},
|
|
4725
|
-
"
|
|
5051
|
+
"technicalContext": {
|
|
5052
|
+
"suggestedTechStack": ["\u{5EFA}\u{8BAE}\u{7684}\u{6280}\u{672F}\u{6808}"],
|
|
5053
|
+
"integrationPoints": ["\u{9700}\u{8981}\u{96C6}\u{6210}\u{7684}\u{7CFB}\u{7EDF}\u{6216}\u{670D}\u{52A1}"],
|
|
5054
|
+
"securityRequirements": ["\u{5B89}\u{5168}\u{8981}\u{6C42}"],
|
|
5055
|
+
"performanceRequirements": ["\u{6027}\u{80FD}\u{8981}\u{6C42}"]
|
|
5056
|
+
},
|
|
5057
|
+
"documentationHints": {
|
|
5058
|
+
"keySequenceDiagrams": ["\u{9700}\u{8981}\u{7ED8}\u{5236}\u{7684}\u{65F6}\u{5E8F}\u{56FE}\u{573A}\u{666F}"],
|
|
5059
|
+
"keyERDiagrams": ["\u{9700}\u{8981}\u{7ED8}\u{5236}\u{7684}ER\u{56FE}\u{5B9E}\u{4F53}"],
|
|
5060
|
+
"keyTables": ["\u{9700}\u{8981}\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}\u{7684}\u{8868}\u{683C}"]
|
|
5061
|
+
}
|
|
4726
5062
|
}
|
|
4727
5063
|
\`\`\`
|
|
4728
5064
|
|
|
5065
|
+
## \u{5206}\u{6790}\u{539F}\u{5219}
|
|
4729
5066
|
|
|
5067
|
+
1. **\u{6DF1}\u{5EA6}\u{4F18}\u{4E8E}\u{5E7F}\u{5EA6}**: \u{5BF9}\u{6BCF}\u{4E2A}\u{529F}\u{80FD}\u{70B9}\u{8FDB}\u{884C}\u{6DF1}\u{5165}\u{5206}\u{6790}\u{FF0C}\u{800C}\u{4E0D}\u{662F}\u{7B80}\u{5355}\u{7F57}\u{5217}
|
|
5068
|
+
2. **\u{4E1A}\u{52A1}\u{9A71}\u{52A8}**: \u{4ECE}\u{4E1A}\u{52A1}\u{4EF7}\u{503C}\u{89D2}\u{5EA6}\u{7406}\u{89E3}\u{9700}\u{6C42}\u{FF0C}\u{800C}\u{4E0D}\u{4EC5}\u{662F}\u{6280}\u{672F}\u{5B9E}\u{73B0}
|
|
5069
|
+
3. **\u{4E0A}\u{4E0B}\u{6587}\u{5B8C}\u{6574}**: \u{63D0}\u{4F9B}\u{8DB3}\u{591F}\u{7684}\u{4E0A}\u{4E0B}\u{6587}\u{4FE1}\u{606F}\u{FF0C}\u{8BA9}\u{540E}\u{7EED}\u{6587}\u{6863}\u{751F}\u{6210}\u{6709}\u{636E}\u{53EF}\u{4F9D}
|
|
5070
|
+
4. **\u{7ED3}\u{6784}\u{5316}\u{8F93}\u{51FA}**: \u{6240}\u{6709}\u{4FE1}\u{606F}\u{90FD}\u{4EE5}\u{7ED3}\u{6784}\u{5316}\u{65B9}\u{5F0F}\u{8F93}\u{51FA}\u{FF0C}\u{4FBF}\u{4E8E}\u{6A21}\u{677F}\u{586B}\u{5145}
|
|
5071
|
+
5. **\u{63A7}\u{5236}\u{6570}\u{91CF}**: \u{6838}\u{5FC3}\u{529F}\u{80FD}\u{70B9}\u{63A7}\u{5236}\u{5728}2-5\u{4E2A}\u{FF0C}\u{907F}\u{514D}\u{8FC7}\u{5EA6}\u{62C6}\u{5206}
|
|
4730
5072
|
|
|
4731
|
-
**\u{8981}\u{6C42}**: \u{
|
|
5073
|
+
**\u{8981}\u{6C42}**: \u{8F93}\u{51FA}\u{5FC5}\u{987B}\u{662F}\u{6709}\u{6548}\u{7684}JSON\u{683C}\u{5F0F}\u{FF0C}\u{6BCF}\u{4E2A}\u{5B57}\u{6BB5}\u{90FD}\u{8981}\u{6709}\u{5B9E}\u{9645}\u{5185}\u{5BB9}\u{FF0C}\u{4E0D}\u{8981}\u{4F7F}\u{7528}\u{5360}\u{4F4D}\u{7B26}\u{3002}`;
|
|
4732
5074
|
class IntelligentAnalyzer {
|
|
4733
5075
|
async analyzeRequirements(inputContent, projectInfo, customPrompt) {
|
|
4734
5076
|
try {
|
|
@@ -5490,9 +5832,9 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5490
5832
|
|
|
5491
5833
|
**\u{8981}\u{6C42}**: \u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{7AE0}\u{8282}\u{6709}\u{5B9E}\u{8D28}\u{5185}\u{5BB9}\u{FF0C}\u{8868}\u{683C}\u{586B}\u{5199}\u{5177}\u{4F53}\u{4FE1}\u{606F}\u{FF0C}\u{57FA}\u{4E8E}\u{539F}\u{59CB}\u{5185}\u{5BB9}\u{5177}\u{4F53}\u{5206}\u{6790}\u{3002}\`;
|
|
5492
5834
|
`;
|
|
5493
|
-
const
|
|
5835
|
+
const htmlPageTemplatePrompt = `\u{4F60}\u{662F}\u{524D}\u{7AEF}\u{6280}\u{672F}\u{6587}\u{6863}\u{4E13}\u{5BB6}\u{3002}\u{57FA}\u{4E8E}\u{8F93}\u{5165}\u{5185}\u{5BB9}\u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}HTML\u{9875}\u{9762}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF08}Markdown\u{683C}\u{5F0F}\u{FF0C}3000\u{5B57}\u{4EE5}\u{4E0A}\u{FF09}\u{3002}
|
|
5494
5836
|
|
|
5495
|
-
**\u{8F93}\u{5165}**: \u{529F}\u{80FD}\u{540D}\u{79F0}={featureName}, \u{4E1A}\u{52A1}\u{9886}\u{57DF}={businessDomain}, \u{
|
|
5837
|
+
**\u{8F93}\u{5165}**: \u{529F}\u{80FD}\u{540D}\u{79F0}={featureName}, \u{4E1A}\u{52A1}\u{9886}\u{57DF}={businessDomain}, \u{9875}\u{9762}\u{7C7B}\u{578B}={pageType}, \u{9875}\u{9762}\u{98CE}\u{683C}={pageStyle}
|
|
5496
5838
|
|
|
5497
5839
|
**\u{539F}\u{59CB}\u{9700}\u{6C42}**:
|
|
5498
5840
|
\`\`\`
|
|
@@ -5502,11 +5844,12 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5502
5844
|
## \u{6587}\u{6863}\u{7ED3}\u{6784}\u{8981}\u{6C42}
|
|
5503
5845
|
\u{8BF7}\u{4E25}\u{683C}\u{6309}\u{7167}\u{4EE5}\u{4E0B}\u{7ED3}\u{6784}\u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{7684}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{4E2A}\u{7AE0}\u{8282}\u{90FD}\u{8981}\u{6709}\u{8BE6}\u{5B9E}\u{7684}\u{5185}\u{5BB9}\u{FF1A}
|
|
5504
5846
|
|
|
5505
|
-
# {featureName} -
|
|
5847
|
+
# {featureName} - HTML\u{9875}\u{9762}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
|
|
5506
5848
|
|
|
5507
5849
|
> **\u{751F}\u{6210}\u{65F6}\u{95F4}**: {currentTime}
|
|
5508
5850
|
> **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: {businessDomain}
|
|
5509
|
-
> **\u{9875}\u{9762}\u{7C7B}\u{578B}**:
|
|
5851
|
+
> **\u{9875}\u{9762}\u{7C7B}\u{578B}**: {pageType}\u{FF08}pc/mobile/responsive\u{FF09}
|
|
5852
|
+
> **\u{9875}\u{9762}\u{98CE}\u{683C}**: TailwindCSS \u{7B80}\u{7EA6}\u{98CE}\u{683C}
|
|
5510
5853
|
|
|
5511
5854
|
---
|
|
5512
5855
|
|
|
@@ -5518,6 +5861,8 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5518
5861
|
|
|
5519
5862
|
**\u{6D89}\u{53CA}\u{89D2}\u{8272}**: [\u{5217}\u{51FA}\u{6240}\u{6709}\u{76F8}\u{5173}\u{7528}\u{6237}\u{89D2}\u{8272}]
|
|
5520
5863
|
|
|
5864
|
+
**\u{76EE}\u{6807}\u{8BBE}\u{5907}**: [\u{6839}\u{636E}pageType\u{63CF}\u{8FF0}\u{76EE}\u{6807}\u{8BBE}\u{5907}\u{FF0C}\u{5982}PC\u{6D4F}\u{89C8}\u{5668}\u{3001}\u{79FB}\u{52A8}\u{7AEF}\u{6D4F}\u{89C8}\u{5668}\u{3001}\u{6216}\u{4E24}\u{8005}\u{517C}\u{987E}]
|
|
5865
|
+
|
|
5521
5866
|
## 2. {featureName}\u{529F}\u{80FD}\u{8BBE}\u{8BA1}\u{8BF4}\u{660E}
|
|
5522
5867
|
|
|
5523
5868
|
| | | | | |
|
|
@@ -5527,14 +5872,17 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5527
5872
|
|**\u{529F}\u{80FD}\u{8BBE}\u{8BA1}\u{7F16}\u{53F7}**|FD001|**\u{7CFB}\u{7EDF}\u{529F}\u{80FD}\u{540D}\u{79F0}**|{featureName}|
|
|
5528
5873
|
|**\u{524D}\u{7F6E}\u{6761}\u{4EF6}**|[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{8BBF}\u{95EE}\u{7684}\u{524D}\u{7F6E}\u{6761}\u{4EF6}]|
|
|
5529
5874
|
|**\u{89D2}\u{8272}\u{FF08}\u{5C97}\u{4F4D}\u{FF09}**|[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{7528}\u{6237}\u{89D2}\u{8272}\u{53CA}\u{5176}\u{6743}\u{9650}]|
|
|
5530
|
-
|**\u{5165}\u{53E3}\u{6E20}\u{9053}**|[\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{8BBF}\u{95EE}\u{5165}\u{53E3}\u{FF0C}\u{5982}\u{83DC}\u{5355}\u{3001}\u{94FE}\u{63A5}\u{7B49}]|
|
|
5875
|
+
|**\u{5165}\u{53E3}\u{6E20}\u{9053}**|[\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{8BBF}\u{95EE}\u{5165}\u{53E3}\u{FF0C}\u{5982}\u{83DC}\u{5355}\u{3001}\u{94FE}\u{63A5}\u{3001}APP\u{5185}\u{5D4C}\u{7B49}]|
|
|
5531
5876
|
|**\u{529F}\u{80FD}\u{63CF}\u{8FF0}**|[\u{8BE6}\u{7EC6}\u{7684}\u{529F}\u{80FD}\u{63CF}\u{8FF0}]|
|
|
5532
5877
|
|**\u{8C03}\u{7528}\u{80FD}\u{529B}\u{57DF}/\u{4E2D}\u{5FC3}**|[\u{5982}\u{9002}\u{7528}\u{7684}\u{540E}\u{7AEF}API\u{63A5}\u{53E3}]|
|
|
5533
5878
|
|
|
5534
5879
|
## 3. \u{9875}\u{9762}\u{5E03}\u{5C40}\u{8BBE}\u{8BA1}
|
|
5535
5880
|
|
|
5536
5881
|
### 3.1 \u{6574}\u{4F53}\u{5E03}\u{5C40}\u{7ED3}\u{6784}
|
|
5537
|
-
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{7684}\u{6574}\u{4F53}\u{5E03}\u{5C40}\u{7ED3}\u{6784}
|
|
5882
|
+
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{7684}\u{6574}\u{4F53}\u{5E03}\u{5C40}\u{7ED3}\u{6784}]
|
|
5883
|
+
- **PC\u{7AEF}\u{5E03}\u{5C40}**: [\u{5982}\u{9002}\u{7528}\u{FF0C}\u{63CF}\u{8FF0}PC\u{7AEF}\u{7684}\u{5934}\u{90E8}\u{3001}\u{4E3B}\u{4F53}\u{3001}\u{4FA7}\u{8FB9}\u{680F}\u{3001}\u{5E95}\u{90E8}\u{7B49}\u{533A}\u{57DF}]
|
|
5884
|
+
- **\u{79FB}\u{52A8}\u{7AEF}\u{5E03}\u{5C40}**: [\u{5982}\u{9002}\u{7528}\u{FF0C}\u{63CF}\u{8FF0}\u{79FB}\u{52A8}\u{7AEF}\u{7684}\u{9876}\u{90E8}\u{5BFC}\u{822A}\u{3001}\u{5185}\u{5BB9}\u{533A}\u{3001}\u{5E95}\u{90E8}\u{5BFC}\u{822A}\u{7B49}\u{533A}\u{57DF}]
|
|
5885
|
+
- **\u{54CD}\u{5E94}\u{5F0F}\u{65AD}\u{70B9}**: [\u{5982}\u{9002}\u{7528}\u{FF0C}\u{63CF}\u{8FF0}\u{4E0D}\u{540C}\u{5C4F}\u{5E55}\u{5C3A}\u{5BF8}\u{4E0B}\u{7684}\u{5E03}\u{5C40}\u{53D8}\u{5316}]
|
|
5538
5886
|
|
|
5539
5887
|
### 3.2 \u{9875}\u{9762}\u{533A}\u{57DF}\u{5212}\u{5206}
|
|
5540
5888
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{5404}\u{4E2A}\u{529F}\u{80FD}\u{533A}\u{57DF}\u{7684}\u{5E03}\u{5C40}\u{FF0C}\u{4F7F}\u{7528}\u{6587}\u{5B57}\u{6216}ASCII\u{56FE}\u{793A}\u{63CF}\u{8FF0}\u{533A}\u{57DF}\u{4F4D}\u{7F6E}\u{5173}\u{7CFB}]
|
|
@@ -5542,13 +5890,34 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5542
5890
|
### 3.3 \u{9875}\u{9762}\u{6D41}\u{7EBF}\u{8BBE}\u{8BA1}
|
|
5543
5891
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{7528}\u{6237}\u{5728}\u{9875}\u{9762}\u{4E2D}\u{7684}\u{89C6}\u{89C9}\u{6D41}\u{7EBF}\u{548C}\u{64CD}\u{4F5C}\u{8DEF}\u{5F84}\u{8BBE}\u{8BA1}]
|
|
5544
5892
|
|
|
5893
|
+
### 3.4 \u{54CD}\u{5E94}\u{5F0F}\u{9002}\u{914D}\u{7B56}\u{7565}
|
|
5894
|
+
[\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{5728}\u{4E0D}\u{540C}\u{8BBE}\u{5907}\u{4E0A}\u{7684}\u{9002}\u{914D}\u{7B56}\u{7565}]
|
|
5895
|
+
- **\u{65AD}\u{70B9}\u{8BBE}\u{7F6E}**: sm(640px), md(768px), lg(1024px), xl(1280px)
|
|
5896
|
+
- **\u{5E03}\u{5C40}\u{53D8}\u{5316}**: [\u{63CF}\u{8FF0}\u{5404}\u{65AD}\u{70B9}\u{4E0B}\u{7684}\u{5E03}\u{5C40}\u{8C03}\u{6574}]
|
|
5897
|
+
- **\u{5143}\u{7D20}\u{9690}\u{85CF}/\u{663E}\u{793A}**: [\u{63CF}\u{8FF0}\u{54EA}\u{4E9B}\u{5143}\u{7D20}\u{5728}\u{4E0D}\u{540C}\u{8BBE}\u{5907}\u{4E0A}\u{663E}\u{793A}\u{6216}\u{9690}\u{85CF}]
|
|
5898
|
+
|
|
5545
5899
|
## 4. \u{6837}\u{5F0F}\u{89C4}\u{8303}\u{8BF4}\u{660E}
|
|
5546
5900
|
|
|
5547
5901
|
### 4.1 \u{8272}\u{5F69}\u{89C4}\u{8303}
|
|
5548
5902
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{4F7F}\u{7528}\u{7684}\u{4E3B}\u{8272}\u{8C03}\u{3001}\u{8F85}\u{52A9}\u{8272}\u{3001}\u{72B6}\u{6001}\u{8272}\u{7B49}\u{914D}\u{8272}\u{65B9}\u{6848}]
|
|
5903
|
+
\`\`\`css
|
|
5904
|
+
:root {
|
|
5905
|
+
--bg: #ffffff;
|
|
5906
|
+
--bg-secondary: #f8f9fa;
|
|
5907
|
+
--border: #e5e5e5;
|
|
5908
|
+
--text: #111111;
|
|
5909
|
+
--text-muted: #666666;
|
|
5910
|
+
--accent: #000000;
|
|
5911
|
+
}
|
|
5912
|
+
\`\`\`
|
|
5913
|
+
|
|
5914
|
+
### 4.2 \u{5B57}\u{4F53}\u{89C4}\u{8303}
|
|
5915
|
+
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{5B57}\u{4F53}\u{65CF}\u{3001}\u{5B57}\u{53F7}\u{3001}\u{884C}\u{9AD8}\u{7B49}\u{6392}\u{7248}\u{89C4}\u{8303}]
|
|
5549
5916
|
|
|
5917
|
+
### 4.3 \u{95F4}\u{8DDD}\u{89C4}\u{8303}
|
|
5918
|
+
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{5143}\u{7D20}\u{7684}\u{95F4}\u{8DDD}\u{89C4}\u{8303}\u{FF0C}\u{4F7F}\u{7528}TailwindCSS\u{7684}\u{95F4}\u{8DDD}\u{7CFB}\u{7EDF}]
|
|
5550
5919
|
|
|
5551
|
-
### 4.
|
|
5920
|
+
### 4.4 \u{54C1}\u{724C}\u{89C6}\u{89C9}\u{89C4}\u{8303}
|
|
5552
5921
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{54C1}\u{724C}\u{89C6}\u{89C9}\u{5143}\u{7D20}\u{5728}\u{9875}\u{9762}\u{4E2D}\u{7684}\u{5E94}\u{7528}\u{89C4}\u{8303}\u{FF0C}\u{5982}Logo\u{3001}\u{56FE}\u{6807}\u{7B49}]
|
|
5553
5922
|
|
|
5554
5923
|
## 5. \u{4EA4}\u{4E92}\u{903B}\u{8F91}\u{8BF4}\u{660E}
|
|
@@ -5565,11 +5934,14 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5565
5934
|
### 5.4 \u{8868}\u{5355}\u{9A8C}\u{8BC1}\u{89C4}\u{5219}
|
|
5566
5935
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{4E2D}\u{8868}\u{5355}\u{5143}\u{7D20}\u{7684}\u{9A8C}\u{8BC1}\u{89C4}\u{5219}\u{548C}\u{9519}\u{8BEF}\u{63D0}\u{793A}]
|
|
5567
5936
|
|
|
5568
|
-
### 5.5 \u{
|
|
5569
|
-
[\u{
|
|
5937
|
+
### 5.5 \u{89E6}\u{6478}/\u{624B}\u{52BF}\u{4EA4}\u{4E92}
|
|
5938
|
+
[\u{5982}\u{9002}\u{7528}\u{4E8E}\u{79FB}\u{52A8}\u{7AEF}\u{FF0C}\u{63CF}\u{8FF0}\u{89E6}\u{6478}\u{548C}\u{624B}\u{52BF}\u{4EA4}\u{4E92}\u{8BBE}\u{8BA1}]
|
|
5939
|
+
- **\u{6ED1}\u{52A8}\u{64CD}\u{4F5C}**: [\u{63CF}\u{8FF0}\u{6ED1}\u{52A8}\u{76F8}\u{5173}\u{7684}\u{4EA4}\u{4E92}]
|
|
5940
|
+
- **\u{957F}\u{6309}\u{64CD}\u{4F5C}**: [\u{63CF}\u{8FF0}\u{957F}\u{6309}\u{76F8}\u{5173}\u{7684}\u{4EA4}\u{4E92}]
|
|
5941
|
+
- **\u{4E0B}\u{62C9}\u{5237}\u{65B0}**: [\u{63CF}\u{8FF0}\u{4E0B}\u{62C9}\u{5237}\u{65B0}\u{7684}\u{4EA4}\u{4E92}]
|
|
5570
5942
|
|
|
5571
|
-
### 5.6 \u{
|
|
5572
|
-
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{4E2D}\u{
|
|
5943
|
+
### 5.6 \u{4E8B}\u{4EF6}\u{5904}\u{7406}\u{673A}\u{5236}
|
|
5944
|
+
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{4E2D}\u{5404}\u{79CD}\u{7528}\u{6237}\u{4E8B}\u{4EF6}\u{7684}\u{5904}\u{7406}\u{673A}\u{5236}]
|
|
5573
5945
|
|
|
5574
5946
|
### 5.7 \u{9519}\u{8BEF}\u{5904}\u{7406}\u{4E0E}\u{6062}\u{590D}
|
|
5575
5947
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{4E2D}\u{9519}\u{8BEF}\u{60C5}\u{51B5}\u{7684}\u{5904}\u{7406}\u{548C}\u{7528}\u{6237}\u{5F15}\u{5BFC}\u{6062}\u{590D}\u{673A}\u{5236}]
|
|
@@ -5579,13 +5951,10 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5579
5951
|
### 6.1 \u{4E3B}\u{8981}\u{6570}\u{636E}\u{5B9E}\u{4F53}
|
|
5580
5952
|
[\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{6D89}\u{53CA}\u{7684}\u{4E3B}\u{8981}\u{6570}\u{636E}\u{5B9E}\u{4F53}]
|
|
5581
5953
|
|
|
5582
|
-
\u{
|
|
5583
|
-
| | | | | |
|
|
5954
|
+
| **\u{5B57}\u{6BB5}\u{540D}\u{79F0}** | **\u{6570}\u{636E}\u{7C7B}\u{578B}** | **\u{957F}\u{5EA6}** | **\u{5FC5}\u{586B}** | **\u{8BF4}\u{660E}** |
|
|
5584
5955
|
|---|---|---|---|---|
|
|
5585
|
-
|**\u{5B57}\u{6BB5}\u{540D}\u{79F0}**|**\u{6570}\u{636E}\u{7C7B}\u{578B}**|**\u{957F}\u{5EA6}**|**\u{5FC5}\u{586B}**|**\u{8BF4}\u{660E}**|
|
|
5586
5956
|
|[\u{5B57}\u{6BB5}1]|[\u{7C7B}\u{578B}]|[\u{957F}\u{5EA6}]|[\u{662F}/\u{5426}]|[\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}]|
|
|
5587
5957
|
|[\u{5B57}\u{6BB5}2]|[\u{7C7B}\u{578B}]|[\u{957F}\u{5EA6}]|[\u{662F}/\u{5426}]|[\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}]|
|
|
5588
|
-
|[\u{6DFB}\u{52A0}\u{66F4}\u{591A}\u{76F8}\u{5173}\u{5B57}\u{6BB5}...]|||
|
|
5589
5958
|
|
|
5590
5959
|
### 6.2 \u{8868}\u{5355}\u{5B57}\u{6BB5}\u{8BF4}\u{660E}
|
|
5591
5960
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{8868}\u{5355}\u{4E2D}\u{5404}\u{5B57}\u{6BB5}\u{7684}\u{542B}\u{4E49}\u{3001}\u{683C}\u{5F0F}\u{8981}\u{6C42}\u{3001}\u{9A8C}\u{8BC1}\u{89C4}\u{5219}\u{7B49}]
|
|
@@ -5595,12 +5964,10 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5595
5964
|
|
|
5596
5965
|
## 7. \u{754C}\u{9762}\u{64CD}\u{4F5C}\u{8BF4}\u{660E}
|
|
5597
5966
|
|
|
5598
|
-
| | | |
|
|
5967
|
+
| **\u{5E8F}\u{53F7}** | **\u{4E1A}\u{52A1}\u{64CD}\u{4F5C}** | **\u{8BF4}\u{660E}** |
|
|
5599
5968
|
|---|---|---|
|
|
5600
|
-
|**\u{5E8F}\u{53F7}**|**\u{4E1A}\u{52A1}\u{64CD}\u{4F5C}**|**\u{8BF4}\u{660E}**|
|
|
5601
5969
|
|1|[\u{64CD}\u{4F5C}1]|[\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}\u{64CD}\u{4F5C}\u{89E6}\u{53D1}\u{6761}\u{4EF6}\u{3001}\u{6267}\u{884C}\u{8FC7}\u{7A0B}\u{548C}\u{7ED3}\u{679C}]|
|
|
5602
5970
|
|2|[\u{64CD}\u{4F5C}2]|[\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}\u{64CD}\u{4F5C}\u{89E6}\u{53D1}\u{6761}\u{4EF6}\u{3001}\u{6267}\u{884C}\u{8FC7}\u{7A0B}\u{548C}\u{7ED3}\u{679C}]|
|
|
5603
|
-
|[\u{6DFB}\u{52A0}\u{66F4}\u{591A}\u{64CD}\u{4F5C}...]|
|
|
5604
5971
|
|
|
5605
5972
|
## 8. \u{7EC4}\u{4EF6}\u{7ED3}\u{6784}\u{8BBE}\u{8BA1}
|
|
5606
5973
|
|
|
@@ -5622,21 +5989,32 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5622
5989
|
|
|
5623
5990
|
\`\`\`mermaid
|
|
5624
5991
|
sequenceDiagram
|
|
5992
|
+
participant User as \u{7528}\u{6237}
|
|
5993
|
+
participant Page as \u{9875}\u{9762}
|
|
5994
|
+
participant API as \u{540E}\u{7AEF}API
|
|
5995
|
+
User->>Page: \u{8BBF}\u{95EE}\u{9875}\u{9762}
|
|
5996
|
+
Page->>API: \u{8BF7}\u{6C42}\u{6570}\u{636E}
|
|
5997
|
+
API-->>Page: \u{8FD4}\u{56DE}\u{6570}\u{636E}
|
|
5998
|
+
Page-->>User: \u{5C55}\u{793A}\u{5185}\u{5BB9}
|
|
5625
5999
|
\`\`\`
|
|
5626
6000
|
|
|
5627
|
-
### 9.2 \u{8FB9}\u{7F18}\u{60C5}\u{51B5}\u{6D41}\u{7A0B}\u{FF08}\u{
|
|
6001
|
+
### 9.2 \u{8FB9}\u{7F18}\u{60C5}\u{51B5}\u{6D41}\u{7A0B}\u{FF08}\u{9519}\u{8BEF}\u{5904}\u{7406}\u{3001}\u{8D85}\u{65F6}\u{7B49}\u{FF09}
|
|
5628
6002
|
|
|
5629
|
-
#### 9.2.1 \u{6027}\u{80FD}\u{4F18}\u{5316}\u{8981}\u{6C42}
|
|
5630
6003
|
\`\`\`mermaid
|
|
5631
6004
|
sequenceDiagram
|
|
6005
|
+
participant User as \u{7528}\u{6237}
|
|
6006
|
+
participant Page as \u{9875}\u{9762}
|
|
6007
|
+
participant API as \u{540E}\u{7AEF}API
|
|
6008
|
+
User->>Page: \u{63D0}\u{4EA4}\u{8868}\u{5355}
|
|
6009
|
+
Page->>API: \u{53D1}\u{9001}\u{8BF7}\u{6C42}
|
|
6010
|
+
API-->>Page: \u{8FD4}\u{56DE}\u{9519}\u{8BEF}
|
|
6011
|
+
Page-->>User: \u{663E}\u{793A}\u{9519}\u{8BEF}\u{63D0}\u{793A}
|
|
5632
6012
|
\`\`\`
|
|
5633
6013
|
|
|
5634
|
-
|
|
5635
6014
|
## 10. \u{4E1A}\u{52A1}\u{72B6}\u{6001}\u{63CF}\u{8FF0}
|
|
5636
6015
|
|
|
5637
|
-
| | | |
|
|
6016
|
+
| **\u{72B6}\u{6001}\u{7F16}\u{53F7}** | **\u{72B6}\u{6001}\u{540D}\u{79F0}** | **\u{63CF}\u{8FF0}** |
|
|
5638
6017
|
|---|---|---|
|
|
5639
|
-
|**\u{72B6}\u{6001}\u{7F16}\u{53F7}**|**\u{72B6}\u{6001}\u{540D}\u{79F0}**|**\u{63CF}\u{8FF0}**|
|
|
5640
6018
|
|01|\u{5F85}\u{52A0}\u{8F7D}|\u{9875}\u{9762}\u{521D}\u{59CB}\u{5316}\u{72B6}\u{6001}|
|
|
5641
6019
|
|02|\u{52A0}\u{8F7D}\u{4E2D}|\u{6570}\u{636E}\u{52A0}\u{8F7D}\u{72B6}\u{6001}|
|
|
5642
6020
|
|03|\u{6B63}\u{5E38}\u{663E}\u{793A}|\u{9875}\u{9762}\u{6B63}\u{5E38}\u{663E}\u{793A}\u{72B6}\u{6001}|
|
|
@@ -5647,174 +6025,19 @@ sequenceDiagram
|
|
|
5647
6025
|
|08|\u{63D0}\u{4EA4}\u{4E2D}|\u{8868}\u{5355}\u{63D0}\u{4EA4}\u{5904}\u{7406}\u{4E2D}\u{72B6}\u{6001}|
|
|
5648
6026
|
|09|\u{63D0}\u{4EA4}\u{6210}\u{529F}|\u{8868}\u{5355}\u{63D0}\u{4EA4}\u{6210}\u{529F}\u{72B6}\u{6001}|
|
|
5649
6027
|
|10|\u{63D0}\u{4EA4}\u{5931}\u{8D25}|\u{8868}\u{5355}\u{63D0}\u{4EA4}\u{5931}\u{8D25}\u{72B6}\u{6001}|
|
|
5650
|
-
|[\u{6DFB}\u{52A0}\u{66F4}\u{591A}\u{72B6}\u{6001}...]||
|
|
5651
6028
|
|
|
5652
6029
|
## 11. \u{7528}\u{6237}\u{6545}\u{4E8B}
|
|
5653
6030
|
|
|
5654
6031
|
### 11.1 \u{6545}\u{4E8B}1
|
|
5655
6032
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{6545}\u{4E8B}\u{7684}\u{5185}\u{5BB9}\u{FF0C}\u{5305}\u{62EC}\u{4EFB}\u{52A1}\u{5B9A}\u{4E49}\u{3001}\u{4E1A}\u{52A1}\u{903B}\u{8F91}\u{63CF}\u{8FF0}\u{3001}\u{6280}\u{672F}\u{65B9}\u{6848}\u{5B9E}\u{73B0}\u{7B49}]
|
|
6033
|
+
|
|
5656
6034
|
### 11.2 \u{6545}\u{4E8B}2
|
|
5657
6035
|
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{6545}\u{4E8B}\u{7684}\u{5185}\u{5BB9}\u{FF0C}\u{5305}\u{62EC}\u{4EFB}\u{52A1}\u{5B9A}\u{4E49}\u{3001}\u{4E1A}\u{52A1}\u{903B}\u{8F91}\u{63CF}\u{8FF0}\u{3001}\u{6280}\u{672F}\u{65B9}\u{6848}\u{5B9E}\u{73B0}\u{7B49}]
|
|
5658
|
-
...
|
|
5659
|
-
### 11.3 \u{66F4}\u{591A}\u{6545}\u{4E8B}
|
|
5660
|
-
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{66F4}\u{591A}\u{6545}\u{4E8B}\u{7684}\u{5185}\u{5BB9}\u{FF0C}\u{5305}\u{62EC}\u{4EFB}\u{52A1}\u{5B9A}\u{4E49}\u{3001}\u{4E1A}\u{52A1}\u{903B}\u{8F91}\u{63CF}\u{8FF0}\u{3001}\u{6280}\u{672F}\u{65B9}\u{6848}\u{5B9E}\u{73B0}\u{7B49}]
|
|
5661
|
-
>
|
|
5662
|
-
|
|
5663
6036
|
|
|
5664
6037
|
---
|
|
5665
6038
|
|
|
5666
|
-
**\u{8981}\u{6C42}**: \u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{7AE0}\u{8282}\u{6709}\u{5B9E}\u{8D28}\u{5185}\u{5BB9}\u{FF0C}\u{8868}\u{683C}\u{586B}\u{5199}\u{5177}\u{4F53}\u{4FE1}\u{606F}\u{FF0C}\u{91CD}\u{70B9}\u{5173}\u{6CE8}\u{9875}\u{9762}\u{5E03}\u{5C40}\u{3001}\u{6837}\u{5F0F}\u{3001}\u{4EA4}\u{4E92}\u{903B}\u{8F91}\u{3002}`;
|
|
5667
|
-
const
|
|
5668
|
-
|
|
5669
|
-
**\u{8F93}\u{5165}**: \u{529F}\u{80FD}\u{540D}\u{79F0}={featureName}, \u{4E1A}\u{52A1}\u{9886}\u{57DF}={businessDomain}
|
|
5670
|
-
|
|
5671
|
-
**\u{539F}\u{59CB}\u{9700}\u{6C42}**:
|
|
5672
|
-
\`\`\`
|
|
5673
|
-
{inputContent}
|
|
5674
|
-
\`\`\`
|
|
5675
|
-
|
|
5676
|
-
## \u{6587}\u{6863}\u{7ED3}\u{6784}\u{8981}\u{6C42}
|
|
5677
|
-
\u{8BF7}\u{4E25}\u{683C}\u{6309}\u{7167}\u{4EE5}\u{4E0B}\u{7ED3}\u{6784}\u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{7684}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{4E2A}\u{7AE0}\u{8282}\u{90FD}\u{8981}\u{6709}\u{8BE6}\u{5B9E}\u{7684}\u{5185}\u{5BB9}\u{FF1A}
|
|
5678
|
-
|
|
5679
|
-
# {featureName} - APP\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
|
|
5680
|
-
|
|
5681
|
-
> **\u{751F}\u{6210}\u{65F6}\u{95F4}**: {currentTime}
|
|
5682
|
-
> **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: {businessDomain}
|
|
5683
|
-
> **\u{5E94}\u{7528}\u{7C7B}\u{578B}**: \u{79FB}\u{52A8}\u{7AEF}\u{5E94}\u{7528}\u{7A0B}\u{5E8F}
|
|
5684
|
-
|
|
5685
|
-
---
|
|
5686
|
-
|
|
5687
|
-
## 1. \u{9700}\u{6C42}\u{6982}\u{8FF0}
|
|
5688
|
-
|
|
5689
|
-
**\u{4E1A}\u{52A1}\u{80CC}\u{666F}**: [\u{63CF}\u{8FF0}APP\u{529F}\u{80FD}\u{80CC}\u{666F}\u{3001}\u{4E1A}\u{52A1}\u{9700}\u{6C42}\u{548C}\u{76EE}\u{6807}]
|
|
5690
|
-
|
|
5691
|
-
**\u{6838}\u{5FC3}\u{529F}\u{80FD}**: [\u{5217}\u{51FA}APP\u{7684}\u{4E3B}\u{8981}\u{529F}\u{80FD}\u{70B9}]
|
|
5692
|
-
|
|
5693
|
-
## 2. \u{754C}\u{9762}\u{8BBE}\u{8BA1}
|
|
5694
|
-
|
|
5695
|
-
### 2.1 \u{9875}\u{9762}\u{5E03}\u{5C40}
|
|
5696
|
-
[\u{63CF}\u{8FF0}\u{4E3B}\u{8981}\u{9875}\u{9762}\u{7684}\u{5E03}\u{5C40}\u{7ED3}\u{6784}\u{548C}\u{754C}\u{9762}\u{5143}\u{7D20}]
|
|
5697
|
-
|
|
5698
|
-
### 2.2 \u{7528}\u{6237}\u{754C}\u{9762}
|
|
5699
|
-
[\u{63CF}\u{8FF0}APP\u{7684}\u{7528}\u{6237}\u{754C}\u{9762}\u{8BBE}\u{8BA1}\u{548C}\u{4EA4}\u{4E92}\u{5143}\u{7D20}]
|
|
5700
|
-
|
|
5701
|
-
## 3. \u{4EA4}\u{4E92}\u{903B}\u{8F91}
|
|
5702
|
-
|
|
5703
|
-
### 3.1 \u{7528}\u{6237}\u{64CD}\u{4F5C}\u{6D41}\u{7A0B}
|
|
5704
|
-
[\u{63CF}\u{8FF0}\u{4E3B}\u{8981}\u{7684}\u{7528}\u{6237}\u{64CD}\u{4F5C}\u{6D41}\u{7A0B}\u{548C}\u{5BFC}\u{822A}\u{8DEF}\u{5F84}]
|
|
5705
|
-
|
|
5706
|
-
### 3.2 \u{4EA4}\u{4E92}\u{89C4}\u{5219}
|
|
5707
|
-
[\u{63CF}\u{8FF0}APP\u{4E2D}\u{7684}\u{4E3B}\u{8981}\u{4EA4}\u{4E92}\u{89C4}\u{5219}\u{548C}\u{54CD}\u{5E94}\u{673A}\u{5236}]
|
|
5708
|
-
|
|
5709
|
-
## 4. \u{6570}\u{636E}\u{5904}\u{7406}
|
|
5710
|
-
|
|
5711
|
-
### 4.1 \u{6570}\u{636E}\u{5C55}\u{793A}
|
|
5712
|
-
[\u{63CF}\u{8FF0}APP\u{4E2D}\u{6570}\u{636E}\u{7684}\u{5C55}\u{793A}\u{65B9}\u{5F0F}\u{548C}\u{683C}\u{5F0F}]
|
|
5713
|
-
|
|
5714
|
-
### 4.2 \u{6570}\u{636E}\u{4EA4}\u{4E92}
|
|
5715
|
-
[\u{63CF}\u{8FF0}APP\u{4E0E}\u{540E}\u{7AEF}\u{7684}\u{6570}\u{636E}\u{4EA4}\u{4E92}\u{65B9}\u{5F0F}]
|
|
5716
|
-
|
|
5717
|
-
## 5. \u{529F}\u{80FD}\u{6A21}\u{5757}
|
|
5718
|
-
|
|
5719
|
-
### 5.1 \u{6838}\u{5FC3}\u{6A21}\u{5757}
|
|
5720
|
-
[\u{63CF}\u{8FF0}APP\u{7684}\u{6838}\u{5FC3}\u{529F}\u{80FD}\u{6A21}\u{5757}]
|
|
5721
|
-
|
|
5722
|
-
### 5.2 \u{4E1A}\u{52A1}\u{903B}\u{8F91}
|
|
5723
|
-
[\u{63CF}\u{8FF0}\u{5404}\u{6A21}\u{5757}\u{7684}\u{4E1A}\u{52A1}\u{903B}\u{8F91}\u{548C}\u{5904}\u{7406}\u{6D41}\u{7A0B}]
|
|
5724
|
-
|
|
5725
|
-
## 6. \u{4E1A}\u{52A1}\u{6D41}\u{7A0B}
|
|
5726
|
-
|
|
5727
|
-
[\u{4F7F}\u{7528}\u{7B80}\u{5355}\u{7684}mermaid\u{6D41}\u{7A0B}\u{56FE}\u{63CF}\u{8FF0}\u{4E3B}\u{8981}\u{4E1A}\u{52A1}\u{6D41}\u{7A0B}]
|
|
5728
|
-
|
|
5729
|
-
\`\`\`mermaid
|
|
5730
|
-
graph TD
|
|
5731
|
-
A[\u{5F00}\u{59CB}] --> B[\u{5904}\u{7406}]
|
|
5732
|
-
B --> C[\u{7ED3}\u{675F}]
|
|
5733
|
-
\`\`\`
|
|
5734
|
-
|
|
5735
|
-
---
|
|
5736
|
-
|
|
5737
|
-
**\u{8981}\u{6C42}**: \u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{7AE0}\u{8282}\u{6709}\u{5B9E}\u{8D28}\u{5185}\u{5BB9}\u{FF0C}\u{91CD}\u{70B9}\u{5173}\u{6CE8}\u{754C}\u{9762}\u{8BBE}\u{8BA1}\u{3001}\u{4EA4}\u{4E92}\u{903B}\u{8F91}\u{548C}\u{6570}\u{636E}\u{5904}\u{7406}\u{3002}`;
|
|
5738
|
-
const sdkTemplatePrompt = `\u{4F60}\u{662F}\u{540E}\u{7AEF}\u{6280}\u{672F}\u{6587}\u{6863}\u{4E13}\u{5BB6}\u{3002}\u{57FA}\u{4E8E}\u{8F93}\u{5165}\u{5185}\u{5BB9}\u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}\u{4E09}\u{65B9}SDK\u{96C6}\u{6210}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF08}Markdown\u{683C}\u{5F0F}\u{FF0C}1500\u{5B57}\u{4EE5}\u{4E0A}\u{FF09}\u{3002}
|
|
5739
|
-
|
|
5740
|
-
**\u{8F93}\u{5165}**: \u{529F}\u{80FD}\u{540D}\u{79F0}={featureName}, \u{4E1A}\u{52A1}\u{9886}\u{57DF}={businessDomain}
|
|
5741
|
-
|
|
5742
|
-
**\u{539F}\u{59CB}\u{9700}\u{6C42}**:
|
|
5743
|
-
\`\`\`
|
|
5744
|
-
{inputContent}
|
|
5745
|
-
\`\`\`
|
|
5746
|
-
|
|
5747
|
-
## \u{6587}\u{6863}\u{7ED3}\u{6784}\u{8981}\u{6C42}
|
|
5748
|
-
\u{8BF7}\u{4E25}\u{683C}\u{6309}\u{7167}\u{4EE5}\u{4E0B}\u{7ED3}\u{6784}\u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{7684}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{4E2A}\u{7AE0}\u{8282}\u{90FD}\u{8981}\u{6709}\u{8BE6}\u{5B9E}\u{7684}\u{5185}\u{5BB9}\u{FF1A}
|
|
5749
|
-
|
|
5750
|
-
# {featureName} - \u{4E09}\u{65B9}SDK\u{96C6}\u{6210}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
|
|
5751
|
-
|
|
5752
|
-
> **\u{751F}\u{6210}\u{65F6}\u{95F4}**: {currentTime}
|
|
5753
|
-
> **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: {businessDomain}
|
|
5754
|
-
> **\u{96C6}\u{6210}\u{7C7B}\u{578B}**: \u{4E09}\u{65B9}SDK\u{96C6}\u{6210}
|
|
5755
|
-
|
|
5756
|
-
---
|
|
5757
|
-
|
|
5758
|
-
## 1. \u{9700}\u{6C42}\u{6982}\u{8FF0}
|
|
5759
|
-
|
|
5760
|
-
**\u{4E1A}\u{52A1}\u{80CC}\u{666F}**: [\u{63CF}\u{8FF0}SDK\u{96C6}\u{6210}\u{7684}\u{80CC}\u{666F}\u{3001}\u{4E1A}\u{52A1}\u{9700}\u{6C42}\u{548C}\u{76EE}\u{6807}]
|
|
5761
|
-
|
|
5762
|
-
**\u{6838}\u{5FC3}\u{529F}\u{80FD}**: [\u{5217}\u{51FA}SDK\u{96C6}\u{6210}\u{7684}\u{4E3B}\u{8981}\u{529F}\u{80FD}\u{70B9}]
|
|
5763
|
-
|
|
5764
|
-
## 2. SDK\u{96C6}\u{6210}\u{8BBE}\u{8BA1}
|
|
5765
|
-
|
|
5766
|
-
### 2.1 \u{63A5}\u{5165}\u{6D41}\u{7A0B}
|
|
5767
|
-
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}SDK\u{63A5}\u{5165}\u{7684}\u{51C6}\u{5907}\u{5DE5}\u{4F5C}\u{548C}\u{914D}\u{7F6E}\u{6D41}\u{7A0B}]
|
|
5768
|
-
|
|
5769
|
-
### 2.2 \u{521D}\u{59CB}\u{5316}\u{914D}\u{7F6E}
|
|
5770
|
-
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}SDK\u{7684}\u{521D}\u{59CB}\u{5316}\u{914D}\u{7F6E}\u{8FC7}\u{7A0B}]
|
|
5771
|
-
|
|
5772
|
-
## 3. \u{63A5}\u{53E3}\u{8C03}\u{7528}\u{8BF4}\u{660E}
|
|
5773
|
-
|
|
5774
|
-
### 3.1 \u{4E3B}\u{8981}API\u{63A5}\u{53E3}
|
|
5775
|
-
[\u{5217}\u{51FA}SDK\u{63D0}\u{4F9B}\u{7684}\u{4E3B}\u{8981}API\u{63A5}\u{53E3}]
|
|
5776
|
-
|
|
5777
|
-
### 3.2 \u{63A5}\u{53E3}\u{8C03}\u{7528}\u{793A}\u{4F8B}
|
|
5778
|
-
[\u{63D0}\u{4F9B}\u{8BE6}\u{7EC6}\u{7684}\u{63A5}\u{53E3}\u{8C03}\u{7528}\u{793A}\u{4F8B}\u{4EE3}\u{7801}]
|
|
5779
|
-
|
|
5780
|
-
### 3.3 \u{53C2}\u{6570}\u{8BF4}\u{660E}
|
|
5781
|
-
[\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}\u{5404}\u{63A5}\u{53E3}\u{7684}\u{8BF7}\u{6C42}\u{53C2}\u{6570}\u{548C}\u{54CD}\u{5E94}\u{6570}\u{636E}\u{7ED3}\u{6784}]
|
|
5782
|
-
|
|
5783
|
-
|\u{53C2}\u{6570}\u{540D}\u{79F0}|\u{7C7B}\u{578B}|\u{662F}\u{5426}\u{5FC5}\u{586B}|\u{8BF4}\u{660E}|
|
|
5784
|
-
|------|------|------|------|
|
|
5785
|
-
|[\u{53C2}\u{6570}1]|[string/number\u{7B49}]|[\u{662F}/\u{5426}]|[\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}]|
|
|
5786
|
-
|[\u{53C2}\u{6570}2]|[string/number\u{7B49}]|[\u{662F}/\u{5426}]|[\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}]|
|
|
5787
|
-
|
|
5788
|
-
## 4. \u{4EA4}\u{4E92}\u{903B}\u{8F91}
|
|
5789
|
-
|
|
5790
|
-
### 4.1 \u{8C03}\u{7528}\u{65F6}\u{5E8F}
|
|
5791
|
-
[\u{63CF}\u{8FF0}SDK\u{8C03}\u{7528}\u{7684}\u{65F6}\u{5E8F}\u{903B}\u{8F91}]
|
|
5792
|
-
|
|
5793
|
-
### 4.2 \u{9519}\u{8BEF}\u{5904}\u{7406}
|
|
5794
|
-
[\u{63CF}\u{8FF0}SDK\u{8C03}\u{7528}\u{5F02}\u{5E38}\u{7684}\u{5904}\u{7406}\u{903B}\u{8F91}]
|
|
5795
|
-
|
|
5796
|
-
## 5. \u{5B89}\u{5168}\u{4E0E}\u{6027}\u{80FD}
|
|
5797
|
-
|
|
5798
|
-
### 5.1 \u{5B89}\u{5168}\u{6027}\u{8003}\u{8651}
|
|
5799
|
-
[\u{63CF}\u{8FF0}\u{6570}\u{636E}\u{52A0}\u{5BC6}\u{3001}\u{8BBF}\u{95EE}\u{63A7}\u{5236}\u{7B49}\u{5B89}\u{5168}\u{8981}\u{6C42}]
|
|
5800
|
-
|
|
5801
|
-
### 5.2 \u{6027}\u{80FD}\u{4F18}\u{5316}
|
|
5802
|
-
[\u{63CF}\u{8FF0}SDK\u{8C03}\u{7528}\u{7684}\u{6027}\u{80FD}\u{8981}\u{6C42}\u{548C}\u{4F18}\u{5316}\u{7B56}\u{7565}]
|
|
5803
|
-
|
|
5804
|
-
## 6. \u{4E1A}\u{52A1}\u{6D41}\u{7A0B}
|
|
5805
|
-
|
|
5806
|
-
[\u{4F7F}\u{7528}\u{7B80}\u{5355}\u{7684}mermaid\u{6D41}\u{7A0B}\u{56FE}\u{63CF}\u{8FF0}\u{4E3B}\u{8981}\u{4E1A}\u{52A1}\u{6D41}\u{7A0B}]
|
|
5807
|
-
|
|
5808
|
-
\`\`\`mermaid
|
|
5809
|
-
graph TD
|
|
5810
|
-
A[\u{5F00}\u{59CB}] --> B[\u{5904}\u{7406}]
|
|
5811
|
-
B --> C[\u{7ED3}\u{675F}]
|
|
5812
|
-
\`\`\`
|
|
5813
|
-
|
|
5814
|
-
---
|
|
5815
|
-
|
|
5816
|
-
**\u{8981}\u{6C42}**: \u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{7AE0}\u{8282}\u{6709}\u{5B9E}\u{8D28}\u{5185}\u{5BB9}\u{FF0C}\u{8868}\u{683C}\u{586B}\u{5199}\u{5177}\u{4F53}\u{4FE1}\u{606F}\u{FF0C}\u{91CD}\u{70B9}\u{5173}\u{6CE8}SDK\u{63A5}\u{5165}\u{6D41}\u{7A0B}\u{3001}\u{63A5}\u{53E3}\u{8C03}\u{7528}\u{548C}\u{6570}\u{636E}\u{7ED3}\u{6784}\u{3002}`;
|
|
5817
|
-
const apiTemplatePrompt = `\u{4F60}\u{662F}\u{540E}\u{7AEF}\u{6280}\u{672F}\u{6587}\u{6863}\u{4E13}\u{5BB6}\u{3002}\u{57FA}\u{4E8E}\u{8F93}\u{5165}\u{5185}\u{5BB9}\u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}API\u{63A5}\u{53E3}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF08}Markdown\u{683C}\u{5F0F}\u{FF0C}3000\u{5B57}\u{4EE5}\u{4E0A}\u{FF09}\u{3002}
|
|
6039
|
+
**\u{8981}\u{6C42}**: \u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{7AE0}\u{8282}\u{6709}\u{5B9E}\u{8D28}\u{5185}\u{5BB9}\u{FF0C}\u{8868}\u{683C}\u{586B}\u{5199}\u{5177}\u{4F53}\u{4FE1}\u{606F}\u{FF0C}\u{91CD}\u{70B9}\u{5173}\u{6CE8}\u{9875}\u{9762}\u{5E03}\u{5C40}\u{3001}\u{6837}\u{5F0F}\u{3001}\u{4EA4}\u{4E92}\u{903B}\u{8F91}\u{3002}\u{6839}\u{636E}pageType\u{8C03}\u{6574}\u{5185}\u{5BB9}\u{4FA7}\u{91CD}\u{70B9}\u{3002}`;
|
|
6040
|
+
const api_template_apiTemplatePrompt = `\u{4F60}\u{662F}\u{540E}\u{7AEF}\u{6280}\u{672F}\u{6587}\u{6863}\u{4E13}\u{5BB6}\u{3002}\u{57FA}\u{4E8E}\u{8F93}\u{5165}\u{5185}\u{5BB9}\u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}API\u{63A5}\u{53E3}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF08}Markdown\u{683C}\u{5F0F}\u{FF0C}3000\u{5B57}\u{4EE5}\u{4E0A}\u{FF09}\u{3002}
|
|
5818
6041
|
|
|
5819
6042
|
**\u{8F93}\u{5165}**: \u{529F}\u{80FD}\u{540D}\u{79F0}={featureName}, \u{4E1A}\u{52A1}\u{9886}\u{57DF}={businessDomain}, \u{751F}\u{6210}\u{65F6}\u{5E8F}\u{56FE}={generateSequenceDiagram}
|
|
5820
6043
|
|
|
@@ -6007,36 +6230,28 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6007
6230
|
class TemplateSelector {
|
|
6008
6231
|
templateMap = new Map([
|
|
6009
6232
|
[
|
|
6010
|
-
"
|
|
6011
|
-
|
|
6012
|
-
],
|
|
6013
|
-
[
|
|
6014
|
-
"APP",
|
|
6015
|
-
appTemplatePrompt
|
|
6233
|
+
"HTML",
|
|
6234
|
+
htmlPageTemplatePrompt
|
|
6016
6235
|
],
|
|
6017
6236
|
[
|
|
6018
|
-
"
|
|
6019
|
-
|
|
6237
|
+
"html",
|
|
6238
|
+
htmlPageTemplatePrompt
|
|
6020
6239
|
],
|
|
6021
6240
|
[
|
|
6022
|
-
"
|
|
6023
|
-
|
|
6241
|
+
"API",
|
|
6242
|
+
api_template_apiTemplatePrompt
|
|
6024
6243
|
],
|
|
6025
6244
|
[
|
|
6026
6245
|
"api",
|
|
6027
|
-
|
|
6028
|
-
],
|
|
6029
|
-
[
|
|
6030
|
-
"pc",
|
|
6031
|
-
pcPageTemplatePrompt
|
|
6246
|
+
api_template_apiTemplatePrompt
|
|
6032
6247
|
],
|
|
6033
6248
|
[
|
|
6034
|
-
"
|
|
6035
|
-
|
|
6249
|
+
"\u63A5\u53E3",
|
|
6250
|
+
api_template_apiTemplatePrompt
|
|
6036
6251
|
],
|
|
6037
6252
|
[
|
|
6038
|
-
"
|
|
6039
|
-
|
|
6253
|
+
"\u9875\u9762",
|
|
6254
|
+
htmlPageTemplatePrompt
|
|
6040
6255
|
]
|
|
6041
6256
|
]);
|
|
6042
6257
|
selectTemplate(requirementType) {
|
|
@@ -6081,33 +6296,18 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6081
6296
|
"ui",
|
|
6082
6297
|
"\u7F51\u9875",
|
|
6083
6298
|
"\u6D4F\u89C8\u5668",
|
|
6084
|
-
"\u524D\u7AEF"
|
|
6085
|
-
|
|
6086
|
-
type: "PC\u9875\u9762",
|
|
6087
|
-
template: pcPageTemplatePrompt
|
|
6088
|
-
};
|
|
6089
|
-
if (this.containsAny(lowerType, [
|
|
6299
|
+
"\u524D\u7AEF",
|
|
6300
|
+
"html",
|
|
6090
6301
|
"app",
|
|
6091
6302
|
"\u79FB\u52A8",
|
|
6092
6303
|
"ios",
|
|
6093
6304
|
"android",
|
|
6094
6305
|
"\u5C0F\u7A0B\u5E8F",
|
|
6095
|
-
"\u79FB\u52A8\u7AEF"
|
|
6306
|
+
"\u79FB\u52A8\u7AEF",
|
|
6307
|
+
"\u54CD\u5E94\u5F0F"
|
|
6096
6308
|
])) return {
|
|
6097
|
-
type: "
|
|
6098
|
-
template:
|
|
6099
|
-
};
|
|
6100
|
-
if (this.containsAny(lowerType, [
|
|
6101
|
-
"sdk",
|
|
6102
|
-
"\u7B2C\u4E09\u65B9",
|
|
6103
|
-
"\u96C6\u6210",
|
|
6104
|
-
"\u5BF9\u63A5",
|
|
6105
|
-
"\u652F\u4ED8",
|
|
6106
|
-
"\u5730\u56FE",
|
|
6107
|
-
"\u63A8\u9001"
|
|
6108
|
-
])) return {
|
|
6109
|
-
type: "SDK\u96C6\u6210",
|
|
6110
|
-
template: sdkTemplatePrompt
|
|
6309
|
+
type: "HTML",
|
|
6310
|
+
template: htmlPageTemplatePrompt
|
|
6111
6311
|
};
|
|
6112
6312
|
if (this.containsAny(lowerType, [
|
|
6113
6313
|
"\u63A5\u53E3",
|
|
@@ -6119,7 +6319,7 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6119
6319
|
"\u670D\u52A1\u7AEF"
|
|
6120
6320
|
])) return {
|
|
6121
6321
|
type: "\u63A5\u53E3",
|
|
6122
|
-
template:
|
|
6322
|
+
template: api_template_apiTemplatePrompt
|
|
6123
6323
|
};
|
|
6124
6324
|
return null;
|
|
6125
6325
|
}
|
|
@@ -6175,9 +6375,9 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6175
6375
|
}
|
|
6176
6376
|
return null;
|
|
6177
6377
|
}
|
|
6178
|
-
saveToCache(cacheKey,
|
|
6378
|
+
saveToCache(cacheKey, document1) {
|
|
6179
6379
|
DocumentGenerator.cache.set(cacheKey, {
|
|
6180
|
-
document,
|
|
6380
|
+
document: document1,
|
|
6181
6381
|
timestamp: Date.now()
|
|
6182
6382
|
});
|
|
6183
6383
|
logger.info("\u6587\u6863\u5DF2\u4FDD\u5B58\u5230\u7F13\u5B58", {
|
|
@@ -6195,7 +6395,7 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6195
6395
|
cleanedCount
|
|
6196
6396
|
});
|
|
6197
6397
|
}
|
|
6198
|
-
async generateUnifiedDocument(analysis, projectInfo, featureName, sourceInfo, customPrompt, currentProjectPath) {
|
|
6398
|
+
async generateUnifiedDocument(analysis, projectInfo, featureName, sourceInfo, customPrompt, currentProjectPath, pageStyle, pageType) {
|
|
6199
6399
|
try {
|
|
6200
6400
|
logger.info("\u51C6\u5907\u751F\u6210\u7EDF\u4E00\u6280\u672F\u6587\u6863\u4EFB\u52A1", {
|
|
6201
6401
|
featureName,
|
|
@@ -6203,7 +6403,10 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6203
6403
|
featureCount: analysis.requirements.length,
|
|
6204
6404
|
currentProjectPath
|
|
6205
6405
|
});
|
|
6206
|
-
const requirementTypes =
|
|
6406
|
+
const requirementTypes = [
|
|
6407
|
+
"API",
|
|
6408
|
+
"HTML"
|
|
6409
|
+
];
|
|
6207
6410
|
const generationTasks = await Promise.all(requirementTypes.map(async (reqType)=>{
|
|
6208
6411
|
logger.info("\u51C6\u5907\u62A5\u544A\u751F\u6210\u4EFB\u52A1", {
|
|
6209
6412
|
requirementType: reqType,
|
|
@@ -6227,13 +6430,19 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6227
6430
|
prompt: promptData.prompt,
|
|
6228
6431
|
systemPrompt: promptData.systemPrompt,
|
|
6229
6432
|
templateContent: promptData.templateContent,
|
|
6230
|
-
templateVariables: "templateVariables" in promptData ?
|
|
6433
|
+
templateVariables: "templateVariables" in promptData ? {
|
|
6434
|
+
...promptData.templateVariables,
|
|
6435
|
+
pageStyle,
|
|
6436
|
+
pageType: pageType || "responsive"
|
|
6437
|
+
} : {
|
|
6231
6438
|
featureName: featureName,
|
|
6232
6439
|
inputContent: this.buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo),
|
|
6233
6440
|
currentTime: new Date().toISOString(),
|
|
6234
6441
|
businessDomain: this.mapRequirementTypeToBusinessDomain(reqType),
|
|
6235
6442
|
generateSequenceDiagram: "true",
|
|
6236
|
-
customPrompt
|
|
6443
|
+
customPrompt,
|
|
6444
|
+
pageStyle,
|
|
6445
|
+
pageType: pageType || "responsive"
|
|
6237
6446
|
},
|
|
6238
6447
|
existingContent: "existingContent" in promptData ? promptData.existingContent : void 0
|
|
6239
6448
|
};
|
|
@@ -6306,18 +6515,72 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6306
6515
|
}
|
|
6307
6516
|
buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo) {
|
|
6308
6517
|
const featuresToProcess = analysis.featureDependencies?.mergedFeatures || analysis.requirements;
|
|
6518
|
+
const enrichedContext = analysis.enrichedContext || {};
|
|
6519
|
+
const businessContext = analysis.businessContext || {};
|
|
6520
|
+
const technicalContext = analysis.technicalContext || {};
|
|
6521
|
+
const documentationHints = analysis.documentationHints || {};
|
|
6309
6522
|
const combinedFeatureContent = featuresToProcess.map((feature, index)=>{
|
|
6310
6523
|
const featureTitle = "title" in feature ? feature.title : feature.featureName;
|
|
6311
6524
|
const featureContent = "fullContent" in feature ? feature.fullContent : feature.description;
|
|
6312
|
-
|
|
6313
|
-
|
|
6525
|
+
const businessFlow = feature.businessFlow || {};
|
|
6526
|
+
const dataEntities = feature.dataEntities || [];
|
|
6527
|
+
const interactions = feature.interactions || [];
|
|
6528
|
+
let content = `## \u{529F}\u{80FD}\u{70B9}${index + 1}\u{FF1A}${featureTitle}\n\n${featureContent}`;
|
|
6529
|
+
if (businessFlow.mainFlow?.length > 0) {
|
|
6530
|
+
content += `
|
|
6531
|
+
|
|
6532
|
+
### \u{4E1A}\u{52A1}\u{6D41}\u{7A0B}
|
|
6533
|
+
`;
|
|
6534
|
+
if (businessFlow.preconditions?.length > 0) content += `**\u{524D}\u{7F6E}\u{6761}\u{4EF6}**: ${businessFlow.preconditions.join("\u3001")}\n`;
|
|
6535
|
+
content += `**\u{4E3B}\u{6D41}\u{7A0B}**:
|
|
6536
|
+
${businessFlow.mainFlow.map((step, i)=>`${i + 1}. ${step}`).join("\n")}\n`;
|
|
6537
|
+
if (businessFlow.exceptionFlows?.length > 0) content += `**\u{5F02}\u{5E38}\u{5904}\u{7406}**: ${businessFlow.exceptionFlows.join("\u3001")}\n`;
|
|
6538
|
+
}
|
|
6539
|
+
if (dataEntities.length > 0) {
|
|
6540
|
+
content += `
|
|
6541
|
+
|
|
6542
|
+
### \u{6570}\u{636E}\u{5B9E}\u{4F53}
|
|
6543
|
+
`;
|
|
6544
|
+
dataEntities.forEach((entity)=>{
|
|
6545
|
+
content += `**${entity.name}**:\n`;
|
|
6546
|
+
if (entity.fields?.length > 0) {
|
|
6547
|
+
content += `| \u{5B57}\u{6BB5}\u{540D} | \u{7C7B}\u{578B} | \u{5FC5}\u{586B} | \u{8BF4}\u{660E} |
|
|
6548
|
+
|---|---|---|---|
|
|
6549
|
+
`;
|
|
6550
|
+
entity.fields.forEach((field)=>{
|
|
6551
|
+
content += `| ${field.name} | ${field.type} | ${field.required ? "\u662F" : "\u5426"} | ${field.description} |\n`;
|
|
6552
|
+
});
|
|
6553
|
+
}
|
|
6554
|
+
});
|
|
6555
|
+
}
|
|
6556
|
+
if (interactions.length > 0) {
|
|
6557
|
+
content += `
|
|
6558
|
+
|
|
6559
|
+
### \u{4EA4}\u{4E92}\u{903B}\u{8F91}
|
|
6560
|
+
`;
|
|
6561
|
+
interactions.forEach((interaction)=>{
|
|
6562
|
+
content += `- **\u{89E6}\u{53D1}**: ${interaction.trigger} \u{2192} **\u{52A8}\u{4F5C}**: ${interaction.action} \u{2192} **\u{54CD}\u{5E94}**: ${interaction.response}\n`;
|
|
6563
|
+
});
|
|
6564
|
+
}
|
|
6565
|
+
return content;
|
|
6566
|
+
}).join("\n\n---\n\n");
|
|
6314
6567
|
return `# ${featureName} - \u{7EDF}\u{4E00}\u{9700}\u{6C42}\u{5206}\u{6790}
|
|
6315
6568
|
|
|
6316
6569
|
## \u{9879}\u{76EE}\u{57FA}\u{672C}\u{4FE1}\u{606F}
|
|
6317
6570
|
- **\u{9879}\u{76EE}\u{7C7B}\u{578B}**: ${projectInfo?.projectType || "\u901A\u7528\u9879\u76EE"}
|
|
6318
|
-
- **\u{4E3B}\u{8981}\u{6280}\u{672F}\u{6808}**: ${projectInfo?.techStack?.join(", ") || "\u5F85\u786E\u5B9A"}
|
|
6571
|
+
- **\u{4E3B}\u{8981}\u{6280}\u{672F}\u{6808}**: ${projectInfo?.techStack?.join(", ") || enrichedContext.techStack?.join(", ") || "\u5F85\u786E\u5B9A"}
|
|
6319
6572
|
- **\u{5F00}\u{53D1}\u{6846}\u{67B6}**: ${projectInfo?.frameworks?.join(", ") || "\u5F85\u786E\u5B9A"}
|
|
6320
6573
|
- **\u{7F16}\u{7A0B}\u{8BED}\u{8A00}**: ${projectInfo?.language || "\u5F85\u786E\u5B9A"}
|
|
6574
|
+
- **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: ${enrichedContext.businessDomain || "\u901A\u7528"}
|
|
6575
|
+
|
|
6576
|
+
## \u{4E1A}\u{52A1}\u{80CC}\u{666F}
|
|
6577
|
+
${businessContext.background || "\u57FA\u4E8E\u7528\u6237\u9700\u6C42\u8FDB\u884C\u529F\u80FD\u5F00\u53D1"}
|
|
6578
|
+
|
|
6579
|
+
### \u{4E1A}\u{52A1}\u{76EE}\u{6807}
|
|
6580
|
+
${businessContext.objectives?.map((obj)=>`- ${obj}`).join("\n") || "- \u6EE1\u8DB3\u7528\u6237\u9700\u6C42\n- \u63D0\u5347\u7CFB\u7EDF\u529F\u80FD"}
|
|
6581
|
+
|
|
6582
|
+
### \u{6D89}\u{53CA}\u{89D2}\u{8272}
|
|
6583
|
+
${businessContext.stakeholders?.map((role)=>`- ${role}`).join("\n") || "- \u7CFB\u7EDF\u7528\u6237\n- \u7CFB\u7EDF\u7BA1\u7406\u5458"}
|
|
6321
6584
|
|
|
6322
6585
|
## \u{9700}\u{6C42}\u{7C7B}\u{578B}\u{5206}\u{6790}
|
|
6323
6586
|
- **\u{8BC6}\u{522B}\u{7C7B}\u{578B}**: ${analysis.requirementType}
|
|
@@ -6325,6 +6588,17 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6325
6588
|
- **\u{529F}\u{80FD}\u{70B9}\u{6570}\u{91CF}**: ${featuresToProcess.length}\u{4E2A}
|
|
6326
6589
|
- **\u{7F6E}\u{4FE1}\u{5EA6}**: ${analysis.confidence || "medium"}
|
|
6327
6590
|
|
|
6591
|
+
## \u{6280}\u{672F}\u{4E0A}\u{4E0B}\u{6587}
|
|
6592
|
+
- **\u{5EFA}\u{8BAE}\u{6280}\u{672F}\u{6808}**: ${technicalContext.suggestedTechStack?.join(", ") || "\u6839\u636E\u9879\u76EE\u73B0\u6709\u6280\u672F\u6808"}
|
|
6593
|
+
- **\u{96C6}\u{6210}\u{70B9}**: ${technicalContext.integrationPoints?.join(", ") || "\u65E0"}
|
|
6594
|
+
- **\u{5B89}\u{5168}\u{8981}\u{6C42}**: ${technicalContext.securityRequirements?.join(", ") || "\u6807\u51C6\u5B89\u5168\u89C4\u8303"}
|
|
6595
|
+
- **\u{6027}\u{80FD}\u{8981}\u{6C42}**: ${technicalContext.performanceRequirements?.join(", ") || "\u6807\u51C6\u6027\u80FD\u8981\u6C42"}
|
|
6596
|
+
|
|
6597
|
+
## \u{6587}\u{6863}\u{751F}\u{6210}\u{63D0}\u{793A}
|
|
6598
|
+
- **\u{9700}\u{8981}\u{7684}\u{65F6}\u{5E8F}\u{56FE}**: ${documentationHints.keySequenceDiagrams?.join(", ") || "\u4E3B\u6D41\u7A0B\u65F6\u5E8F\u56FE"}
|
|
6599
|
+
- **\u{9700}\u{8981}\u{7684}ER\u{56FE}**: ${documentationHints.keyERDiagrams?.join(", ") || "\u6838\u5FC3\u6570\u636E\u5B9E\u4F53"}
|
|
6600
|
+
- **\u{9700}\u{8981}\u{7684}\u{8868}\u{683C}**: ${documentationHints.keyTables?.join(", ") || "\u5B57\u6BB5\u8BF4\u660E\u8868\u3001\u63A5\u53E3\u53C2\u6570\u8868"}
|
|
6601
|
+
|
|
6328
6602
|
## \u{529F}\u{80FD}\u{70B9}\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}
|
|
6329
6603
|
|
|
6330
6604
|
${combinedFeatureContent}
|
|
@@ -6337,19 +6611,19 @@ ${combinedFeatureContent}
|
|
|
6337
6611
|
async generateDocument(content, title, requirementType, projectInfo, customPrompt, outputPath) {
|
|
6338
6612
|
try {
|
|
6339
6613
|
const cacheKey = this.generateCacheKey(content, requirementType, customPrompt);
|
|
6340
|
-
let
|
|
6341
|
-
if (
|
|
6614
|
+
let document1 = this.getCachedDocument(cacheKey);
|
|
6615
|
+
if (document1) {
|
|
6342
6616
|
logger.info("\u4F7F\u7528\u7F13\u5B58\u7684\u6587\u6863", {
|
|
6343
6617
|
title,
|
|
6344
6618
|
requirementType
|
|
6345
6619
|
});
|
|
6346
|
-
return
|
|
6620
|
+
return document1;
|
|
6347
6621
|
}
|
|
6348
6622
|
const template = this.templateSelector.selectTemplate(requirementType);
|
|
6349
6623
|
this.templateSelector.validateTemplate(template, requirementType);
|
|
6350
6624
|
const fullPrompt = this.buildDocumentPrompt(template, content, title, projectInfo, customPrompt, requirementType);
|
|
6351
6625
|
if (outputPath) try {
|
|
6352
|
-
|
|
6626
|
+
document1 = await this.generateDocumentStream(fullPrompt, outputPath, title, "", {
|
|
6353
6627
|
realTimeMode: true
|
|
6354
6628
|
});
|
|
6355
6629
|
} catch (streamError) {
|
|
@@ -6357,18 +6631,18 @@ ${combinedFeatureContent}
|
|
|
6357
6631
|
error: streamError,
|
|
6358
6632
|
requirementType
|
|
6359
6633
|
});
|
|
6360
|
-
|
|
6634
|
+
document1 = await openAIService.generateText({
|
|
6361
6635
|
prompt: fullPrompt,
|
|
6362
6636
|
system_prompt: "\u4F60\u662F\u4E00\u4F4D\u4E13\u4E1A\u7684\u6280\u672F\u6587\u6863\u7F16\u5199\u4E13\u5BB6\uFF0C\u8BF7\u751F\u6210\u5B8C\u6574\u3001\u8BE6\u7EC6\u7684\u6280\u672F\u9700\u6C42\u6587\u6863\u3002"
|
|
6363
6637
|
});
|
|
6364
6638
|
}
|
|
6365
|
-
else
|
|
6639
|
+
else document1 = await openAIService.generateText({
|
|
6366
6640
|
prompt: fullPrompt,
|
|
6367
6641
|
system_prompt: "\u4F60\u662F\u4E00\u4F4D\u4E13\u4E1A\u7684\u6280\u672F\u6587\u6863\u7F16\u5199\u4E13\u5BB6\uFF0C\u8BF7\u751F\u6210\u5B8C\u6574\u3001\u8BE6\u7EC6\u7684\u6280\u672F\u9700\u6C42\u6587\u6863\u3002"
|
|
6368
6642
|
});
|
|
6369
|
-
this.validateGeneratedDocument(
|
|
6370
|
-
this.saveToCache(cacheKey,
|
|
6371
|
-
return
|
|
6643
|
+
this.validateGeneratedDocument(document1, title);
|
|
6644
|
+
this.saveToCache(cacheKey, document1);
|
|
6645
|
+
return document1;
|
|
6372
6646
|
} catch (error) {
|
|
6373
6647
|
logger.error("\u6280\u672F\u6587\u6863\u751F\u6210\u5931\u8D25", {
|
|
6374
6648
|
error,
|
|
@@ -6656,9 +6930,9 @@ ${existingContent}
|
|
|
6656
6930
|
|
|
6657
6931
|
\u{8BF7}\u{7EE7}\u{7EED}\u{751F}\u{6210}\u{FF1A}`;
|
|
6658
6932
|
}
|
|
6659
|
-
isDocumentComplete(
|
|
6660
|
-
const hasEnding =
|
|
6661
|
-
const hasReasonableLength =
|
|
6933
|
+
isDocumentComplete(document1) {
|
|
6934
|
+
const hasEnding = document1.includes("## \u66F4\u65B0\u65E5\u5FD7") || document1.includes("---\n\n**") || document1.trim().endsWith("---") || document1.trim().endsWith("\u3002") || document1.trim().endsWith("\uFF09");
|
|
6935
|
+
const hasReasonableLength = document1.length >= 1000;
|
|
6662
6936
|
return hasEnding && hasReasonableLength;
|
|
6663
6937
|
}
|
|
6664
6938
|
async continueDocumentGeneration(originalPrompt, existingContent, outputPath) {
|
|
@@ -6853,15 +7127,15 @@ ${customPrompt}` : ""}
|
|
|
6853
7127
|
});
|
|
6854
7128
|
}
|
|
6855
7129
|
}
|
|
6856
|
-
validateGeneratedDocument(
|
|
6857
|
-
if (!
|
|
7130
|
+
validateGeneratedDocument(document1, title) {
|
|
7131
|
+
if (!document1 || document1.trim().length < 100) throw new RequirementAnalysisError("\u751F\u6210\u7684\u6280\u672F\u6587\u6863\u5185\u5BB9\u8FC7\u77ED\uFF0C\u53EF\u80FD\u5B58\u5728\u95EE\u9898", types_ErrorCodes.DOCUMENT_GENERATION_FAILED, {
|
|
6858
7132
|
title,
|
|
6859
|
-
documentLength:
|
|
7133
|
+
documentLength: document1?.length || 0
|
|
6860
7134
|
});
|
|
6861
|
-
if (!
|
|
7135
|
+
if (!document1.includes(title)) logger.warn("\u751F\u6210\u7684\u6587\u6863\u53EF\u80FD\u4E0E\u9700\u6C42\u6807\u9898\u4E0D\u5339\u914D", {
|
|
6862
7136
|
title
|
|
6863
7137
|
});
|
|
6864
|
-
if (
|
|
7138
|
+
if (document1.includes("## 3.1 ER\u903B\u8F91\u56FE\u8BBE\u8BA1") && !document1.includes("erDiagram") && !document1.includes("entity")) logger.warn("\u751F\u6210\u7684\u6587\u6863\u53EF\u80FD\u7F3A\u5C11ER\u56FE\u5185\u5BB9", {
|
|
6865
7139
|
title
|
|
6866
7140
|
});
|
|
6867
7141
|
}
|
|
@@ -7010,14 +7284,14 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7010
7284
|
async analyzeRequirements(params) {
|
|
7011
7285
|
try {
|
|
7012
7286
|
logger.info("\u5F00\u59CB\u9700\u6C42\u5206\u6790\u6D41\u7A0B", {
|
|
7013
|
-
|
|
7014
|
-
|
|
7287
|
+
projectPath: params.current_project_path,
|
|
7288
|
+
hasPageStyle: !!params.page_style
|
|
7015
7289
|
});
|
|
7016
|
-
const { requirementContent, projectInfo } = this.parseRequirementAnalysis(params.requirement_analysis);
|
|
7290
|
+
const { requirementContent, projectInfo, enrichedContext } = this.parseRequirementAnalysis(params.requirement_analysis);
|
|
7017
7291
|
const requirementAnalysis = await this.intelligentAnalyzer.analyzeRequirements(requirementContent, projectInfo, void 0);
|
|
7018
|
-
|
|
7019
|
-
requirementAnalysis.
|
|
7020
|
-
return await this.documentGenerator.generateUnifiedDocument(requirementAnalysis, projectInfo, this.extractFeatureName(requirementContent), "requirement-identifier\u5206\u6790\u7ED3\u679C", void 0, params.current_project_path);
|
|
7292
|
+
requirementAnalysis.requirementType = "PC+API";
|
|
7293
|
+
requirementAnalysis.enrichedContext = enrichedContext;
|
|
7294
|
+
return await this.documentGenerator.generateUnifiedDocument(requirementAnalysis, projectInfo, this.extractFeatureName(requirementContent), "requirement-identifier\u5206\u6790\u7ED3\u679C", void 0, params.current_project_path, params.page_style, params.page_type);
|
|
7021
7295
|
} catch (error) {
|
|
7022
7296
|
if (error instanceof RequirementAnalysisError) throw error;
|
|
7023
7297
|
logger.error("\u9700\u6C42\u5206\u6790\u6D41\u7A0B\u5931\u8D25", {
|
|
@@ -7033,15 +7307,32 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7033
7307
|
parseRequirementAnalysis(analysisResult) {
|
|
7034
7308
|
try {
|
|
7035
7309
|
const parsed = JSON.parse(analysisResult);
|
|
7310
|
+
const enrichedContext = {
|
|
7311
|
+
originalRequirement: parsed.requirement_description || parsed.data?.guidance || "",
|
|
7312
|
+
techStack: parsed.project_context?.techStack || [],
|
|
7313
|
+
codeStructure: parsed.project_context?.codeStructure || {},
|
|
7314
|
+
businessDomain: parsed.project_context?.businessDomain || "\u901A\u7528",
|
|
7315
|
+
relatedFiles: parsed.project_context?.relatedFiles || [],
|
|
7316
|
+
dependencies: parsed.project_context?.dependencies || []
|
|
7317
|
+
};
|
|
7036
7318
|
return {
|
|
7037
7319
|
requirementContent: parsed.requirement_description || parsed.data?.guidance || analysisResult,
|
|
7038
|
-
projectInfo: parsed.project_context || this.getDefaultProjectInfo()
|
|
7320
|
+
projectInfo: parsed.project_context || this.getDefaultProjectInfo(),
|
|
7321
|
+
enrichedContext
|
|
7039
7322
|
};
|
|
7040
7323
|
} catch {
|
|
7041
7324
|
logger.info("\u4F7F\u7528\u6587\u672C\u683C\u5F0F\u7684\u9700\u6C42\u5206\u6790\u7ED3\u679C");
|
|
7042
7325
|
return {
|
|
7043
7326
|
requirementContent: analysisResult,
|
|
7044
|
-
projectInfo: this.getDefaultProjectInfo()
|
|
7327
|
+
projectInfo: this.getDefaultProjectInfo(),
|
|
7328
|
+
enrichedContext: {
|
|
7329
|
+
originalRequirement: analysisResult,
|
|
7330
|
+
techStack: [],
|
|
7331
|
+
codeStructure: {},
|
|
7332
|
+
businessDomain: "\u901A\u7528",
|
|
7333
|
+
relatedFiles: [],
|
|
7334
|
+
dependencies: []
|
|
7335
|
+
}
|
|
7045
7336
|
};
|
|
7046
7337
|
}
|
|
7047
7338
|
}
|
|
@@ -7170,23 +7461,178 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7170
7461
|
};
|
|
7171
7462
|
}
|
|
7172
7463
|
}
|
|
7464
|
+
const DEFAULT_PAGE_STYLE = `<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
|
7465
|
+
<style>
|
|
7466
|
+
:root {
|
|
7467
|
+
--bg: #ffffff;
|
|
7468
|
+
--bg-secondary: #f8f9fa;
|
|
7469
|
+
--border: #e5e5e5;
|
|
7470
|
+
--text: #111111;
|
|
7471
|
+
--text-muted: #666666;
|
|
7472
|
+
--accent: #000000;
|
|
7473
|
+
}
|
|
7474
|
+
</style>`;
|
|
7475
|
+
const API_SECTIONS = [
|
|
7476
|
+
{
|
|
7477
|
+
id: "header",
|
|
7478
|
+
title: "\u6587\u6863\u5934\u90E8",
|
|
7479
|
+
prompt: "\u751F\u6210\u6587\u6863\u6807\u9898\u3001\u751F\u6210\u65F6\u95F4\u3001\u4E1A\u52A1\u9886\u57DF\u7B49\u5934\u90E8\u4FE1\u606F"
|
|
7480
|
+
},
|
|
7481
|
+
{
|
|
7482
|
+
id: "background",
|
|
7483
|
+
title: "\u9700\u6C42\u80CC\u666F",
|
|
7484
|
+
prompt: "\u751F\u6210\u9700\u6C42\u80CC\u666F\u3001\u5173\u952E\u529F\u80FD\u3001\u6D89\u53CA\u89D2\u8272"
|
|
7485
|
+
},
|
|
7486
|
+
{
|
|
7487
|
+
id: "design",
|
|
7488
|
+
title: "\u529F\u80FD\u8BBE\u8BA1\u8BF4\u660E",
|
|
7489
|
+
prompt: "\u751F\u6210\u529F\u80FD\u8BBE\u8BA1\u8BF4\u660E\u8868\u683C\uFF0C\u5305\u542B\u6D41\u7A0B\u7F16\u53F7\u3001\u524D\u7F6E\u6761\u4EF6\u3001\u89D2\u8272\u7B49"
|
|
7490
|
+
},
|
|
7491
|
+
{
|
|
7492
|
+
id: "dataModel",
|
|
7493
|
+
title: "\u6570\u636E\u5EFA\u6A21",
|
|
7494
|
+
prompt: "\u751F\u6210ER\u903B\u8F91\u56FE\u8BBE\u8BA1\uFF08\u4F7F\u7528mermaid erDiagram\uFF09\u548C\u6570\u636E\u8868\u5B9E\u4F53\u8BBE\u8BA1"
|
|
7495
|
+
},
|
|
7496
|
+
{
|
|
7497
|
+
id: "apiDesign",
|
|
7498
|
+
title: "API\u63A5\u53E3\u8BBE\u8BA1",
|
|
7499
|
+
prompt: "\u751F\u6210API\u63A5\u53E3\u5217\u8868\u3001\u8BF7\u6C42\u53C2\u6570\u3001\u54CD\u5E94\u53C2\u6570\u3001\u9519\u8BEF\u7801\u7B49"
|
|
7500
|
+
},
|
|
7501
|
+
{
|
|
7502
|
+
id: "sequence",
|
|
7503
|
+
title: "\u4E1A\u52A1\u65F6\u5E8F\u56FE",
|
|
7504
|
+
prompt: "\u751F\u6210\u4E1A\u52A1\u5BF9\u8C61\u65F6\u5E8F\u56FE\uFF08\u4F7F\u7528mermaid sequenceDiagram\uFF09"
|
|
7505
|
+
},
|
|
7506
|
+
{
|
|
7507
|
+
id: "status",
|
|
7508
|
+
title: "\u4E1A\u52A1\u72B6\u6001",
|
|
7509
|
+
prompt: "\u751F\u6210\u4E1A\u52A1\u72B6\u6001\u63CF\u8FF0\u8868\u683C"
|
|
7510
|
+
},
|
|
7511
|
+
{
|
|
7512
|
+
id: "pseudocode",
|
|
7513
|
+
title: "\u4F2A\u4EE3\u7801\u793A\u4F8B",
|
|
7514
|
+
prompt: "\u751F\u6210\u6838\u5FC3\u4E1A\u52A1\u903B\u8F91\u7684\u4F2A\u4EE3\u7801\u793A\u4F8B"
|
|
7515
|
+
}
|
|
7516
|
+
];
|
|
7517
|
+
class ConcurrencyLimiter {
|
|
7518
|
+
maxConcurrent;
|
|
7519
|
+
running = 0;
|
|
7520
|
+
queue = [];
|
|
7521
|
+
constructor(maxConcurrent){
|
|
7522
|
+
this.maxConcurrent = maxConcurrent;
|
|
7523
|
+
}
|
|
7524
|
+
async run(fn) {
|
|
7525
|
+
while(this.running >= this.maxConcurrent)await new Promise((resolve)=>this.queue.push(resolve));
|
|
7526
|
+
this.running++;
|
|
7527
|
+
try {
|
|
7528
|
+
return await fn();
|
|
7529
|
+
} finally{
|
|
7530
|
+
this.running--;
|
|
7531
|
+
const next = this.queue.shift();
|
|
7532
|
+
if (next) next();
|
|
7533
|
+
}
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
const apiLimiter = new ConcurrencyLimiter(18);
|
|
7537
|
+
const EXECUTION_TIMEOUT_MS = 40000;
|
|
7538
|
+
async function generateApiSection(sectionDef, templateVariables) {
|
|
7539
|
+
return apiLimiter.run(async ()=>{
|
|
7540
|
+
try {
|
|
7541
|
+
const prompt = `\u{4F60}\u{662F}\u{6280}\u{672F}\u{6587}\u{6863}\u{4E13}\u{5BB6}\u{3002}\u{8BF7}\u{4E3A}"${templateVariables.featureName}"\u{7684}API\u{6587}\u{6863}\u{751F}\u{6210}"${sectionDef.title}"\u{7AE0}\u{8282}\u{3002}
|
|
7542
|
+
|
|
7543
|
+
## \u{4EFB}\u{52A1}
|
|
7544
|
+
${sectionDef.prompt}
|
|
7545
|
+
|
|
7546
|
+
## \u{9700}\u{6C42}\u{4FE1}\u{606F}
|
|
7547
|
+
- \u{529F}\u{80FD}\u{540D}\u{79F0}: ${templateVariables.featureName}
|
|
7548
|
+
- \u{4E1A}\u{52A1}\u{9886}\u{57DF}: ${templateVariables.businessDomain}
|
|
7549
|
+
- \u{9700}\u{6C42}\u{8BE6}\u{60C5}: ${templateVariables.inputContent?.substring(0, 1500) || ''}
|
|
7550
|
+
|
|
7551
|
+
## \u{8981}\u{6C42}
|
|
7552
|
+
- \u{5185}\u{5BB9}\u{8BE6}\u{5B9E}\u{5177}\u{4F53}\u{FF0C}\u{4E0D}\u{4F7F}\u{7528}\u{5360}\u{4F4D}\u{7B26}
|
|
7553
|
+
- \u{4F7F}\u{7528}\u{6B63}\u{786E}\u{7684}Markdown\u{683C}\u{5F0F}
|
|
7554
|
+
- \u{5982}\u{9700}\u{56FE}\u{8868}\u{4F7F}\u{7528}mermaid\u{8BED}\u{6CD5}
|
|
7555
|
+
- \u{8868}\u{683C}\u{586B}\u{5199}\u{5177}\u{4F53}\u{4FE1}\u{606F}
|
|
7556
|
+
|
|
7557
|
+
\u{76F4}\u{63A5}\u{8F93}\u{51FA}\u{8BE5}\u{7AE0}\u{8282}\u{7684}Markdown\u{5185}\u{5BB9}\u{FF08}\u{5305}\u{542B}\u{7AE0}\u{8282}\u{6807}\u{9898}\u{FF09}\u{3002}`;
|
|
7558
|
+
const content = await openAIService.generateText({
|
|
7559
|
+
prompt,
|
|
7560
|
+
system_prompt: "\u4F60\u662F\u6280\u672F\u6587\u6863\u4E13\u5BB6\uFF0C\u8F93\u51FA\u7B80\u6D01\u4E13\u4E1A\u7684\u6587\u6863\u7AE0\u8282\u3002",
|
|
7561
|
+
temperature: 0.7
|
|
7562
|
+
});
|
|
7563
|
+
return {
|
|
7564
|
+
id: sectionDef.id,
|
|
7565
|
+
title: sectionDef.title,
|
|
7566
|
+
content,
|
|
7567
|
+
success: true
|
|
7568
|
+
};
|
|
7569
|
+
} catch (error) {
|
|
7570
|
+
return {
|
|
7571
|
+
id: sectionDef.id,
|
|
7572
|
+
title: sectionDef.title,
|
|
7573
|
+
content: "",
|
|
7574
|
+
success: false,
|
|
7575
|
+
error: error.message
|
|
7576
|
+
};
|
|
7577
|
+
}
|
|
7578
|
+
});
|
|
7579
|
+
}
|
|
7580
|
+
async function generateInteractiveHtml(templateVariables) {
|
|
7581
|
+
const { featureName, businessDomain, pageType, pageStyle, inputContent } = templateVariables;
|
|
7582
|
+
const prompt = `\u{4F60}\u{662F}\u{4E00}\u{4F4D}\u{4E13}\u{4E1A}\u{7684}\u{524D}\u{7AEF}\u{5F00}\u{53D1}\u{4E13}\u{5BB6}\u{3002}\u{8BF7}\u{6839}\u{636E}\u{4EE5}\u{4E0B}\u{9700}\u{6C42}\u{751F}\u{6210}\u{4E00}\u{4E2A}\u{5B8C}\u{6574}\u{7684}\u{3001}\u{53EF}\u{4EA4}\u{4E92}\u{7684}HTML\u{9875}\u{9762}\u{3002}
|
|
7583
|
+
|
|
7584
|
+
## \u{9700}\u{6C42}\u{4FE1}\u{606F}
|
|
7585
|
+
- \u{529F}\u{80FD}\u{540D}\u{79F0}: ${featureName}
|
|
7586
|
+
- \u{4E1A}\u{52A1}\u{9886}\u{57DF}: ${businessDomain}
|
|
7587
|
+
- \u{9875}\u{9762}\u{7C7B}\u{578B}: ${pageType || 'responsive'}
|
|
7588
|
+
- \u{9700}\u{6C42}\u{8BE6}\u{60C5}:
|
|
7589
|
+
${inputContent || ''}
|
|
7590
|
+
|
|
7591
|
+
## \u{9875}\u{9762}\u{98CE}\u{683C}\u{8981}\u{6C42}
|
|
7592
|
+
\u{5728}<head>\u{4E2D}\u{5305}\u{542B}\u{4EE5}\u{4E0B}\u{6837}\u{5F0F}\u{914D}\u{7F6E}\u{FF1A}
|
|
7593
|
+
${pageStyle}
|
|
7594
|
+
|
|
7595
|
+
## \u{6280}\u{672F}\u{8981}\u{6C42}
|
|
7596
|
+
1. \u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}HTML\u{6587}\u{4EF6}\u{FF0C}\u{5305}\u{542B}<!DOCTYPE html>\u{3001}<html>\u{3001}<head>\u{3001}<body>
|
|
7597
|
+
2. \u{4F7F}\u{7528}TailwindCSS\u{8FDB}\u{884C}\u{6837}\u{5F0F}\u{8BBE}\u{8BA1}\u{FF0C}\u{4F7F}\u{7528}CSS\u{53D8}\u{91CF}\u{5B9E}\u{73B0}\u{4E3B}\u{9898}\u{8272}
|
|
7598
|
+
3. \u{9875}\u{9762}\u{5FC5}\u{987B}\u{662F}${'mobile' === pageType ? "\u79FB\u52A8\u7AEF\u4F18\u5148" : 'pc' === pageType ? "PC\u7AEF" : "\u54CD\u5E94\u5F0F"}\u{5E03}\u{5C40}
|
|
7599
|
+
4. \u{5305}\u{542B}\u{5B8C}\u{6574}\u{7684}\u{8868}\u{5355}\u{9A8C}\u{8BC1}\u{548C}\u{4EA4}\u{4E92}\u{903B}\u{8F91}\u{FF08}\u{4F7F}\u{7528}\u{539F}\u{751F}JavaScript\u{FF09}
|
|
7600
|
+
5. \u{5305}\u{542B}\u{52A0}\u{8F7D}\u{72B6}\u{6001}\u{3001}\u{6210}\u{529F}/\u{5931}\u{8D25}\u{63D0}\u{793A}
|
|
7601
|
+
6. \u{8868}\u{5355}\u{63D0}\u{4EA4}\u{4F7F}\u{7528}console.log\u{6A21}\u{62DF}\u{FF0C}\u{5E76}\u{663E}\u{793A}\u{63D0}\u{4EA4}\u{7ED3}\u{679C}
|
|
7602
|
+
7. \u{6240}\u{6709}\u{6587}\u{672C}\u{4F7F}\u{7528}\u{4E2D}\u{6587}
|
|
7603
|
+
8. \u{8BBE}\u{8BA1}\u{7F8E}\u{89C2}\u{3001}\u{73B0}\u{4EE3}\u{3001}\u{7B80}\u{6D01}
|
|
7604
|
+
|
|
7605
|
+
## \u{8F93}\u{51FA}\u{8981}\u{6C42}
|
|
7606
|
+
\u{76F4}\u{63A5}\u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{7684}HTML\u{4EE3}\u{7801}\u{FF0C}\u{4E0D}\u{8981}\u{5305}\u{542B}\u{4EFB}\u{4F55}\u{89E3}\u{91CA}\u{6216}markdown\u{6807}\u{8BB0}\u{3002}`;
|
|
7607
|
+
const html = await openAIService.generateText({
|
|
7608
|
+
prompt,
|
|
7609
|
+
system_prompt: "\u4F60\u662F\u4E00\u4F4D\u8D44\u6DF1\u7684\u524D\u7AEF\u5F00\u53D1\u4E13\u5BB6\uFF0C\u64C5\u957F\u4F7F\u7528TailwindCSS\u521B\u5EFA\u7F8E\u89C2\u3001\u53EF\u4EA4\u4E92\u7684\u9875\u9762\u3002\u53EA\u8F93\u51FAHTML\u4EE3\u7801\uFF0C\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u5185\u5BB9\u3002",
|
|
7610
|
+
temperature: 0.7
|
|
7611
|
+
});
|
|
7612
|
+
let cleanHtml = html.trim();
|
|
7613
|
+
if (cleanHtml.startsWith("```html")) cleanHtml = cleanHtml.slice(7);
|
|
7614
|
+
else if (cleanHtml.startsWith("```")) cleanHtml = cleanHtml.slice(3);
|
|
7615
|
+
if (cleanHtml.endsWith("```")) cleanHtml = cleanHtml.slice(0, -3);
|
|
7616
|
+
return cleanHtml.trim();
|
|
7617
|
+
}
|
|
7173
7618
|
const requirementAnalyzerTool = {
|
|
7174
|
-
name: "
|
|
7175
|
-
description:
|
|
7619
|
+
name: "requirement-analyzer-report",
|
|
7620
|
+
description: `\u{667A}\u{80FD}\u{5206}\u{6790}\u{9700}\u{6C42}\u{5E76}\u{751F}\u{6210}API\u{6587}\u{6863}\u{548C}HTML\u{9875}\u{9762}\u{8BBE}\u{8BA1}\u{6587}\u{6863}\u{3002}\u{652F}\u{6301}PC\u{7AEF}\u{3001}\u{79FB}\u{52A8}\u{7AEF}\u{7B49}\u{591A}\u{79CD}\u{9875}\u{9762}\u{7C7B}\u{578B}\u{3002}`,
|
|
7176
7621
|
inputSchema: {
|
|
7177
7622
|
requirement_analysis: stringType().describe("requirement-identifier\u751F\u6210\u7684\u9700\u6C42\u5206\u6790\u7ED3\u679C\uFF08\u5305\u542B\u5F53\u524D\u9700\u6C42\u4E0E\u9879\u76EE\u60C5\u51B5\u7684\u5B8C\u6574\u5206\u6790\uFF09"),
|
|
7178
7623
|
current_project_path: stringType().describe("\u5F53\u524D\u9879\u76EE\u8DEF\u5F84\uFF08\u5FC5\u586B\uFF09\uFF0C\u9700\u6C42\u62A5\u544A\u5C06\u751F\u6210\u5230\u8BE5\u8DEF\u5F84\u4E0B\u7684.aico/design\u76EE\u5F55"),
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
"
|
|
7182
|
-
"
|
|
7183
|
-
"
|
|
7184
|
-
|
|
7185
|
-
]).default("PC+API").describe("需求类型(必填):\n- PC+API: 页面+接口(会生成PC报告和API报告)\n- APP+API: 移动端+接口(会生成APP报告和API报告)\n- SDK+API: SDK集成+接口\n- APP+SDK: 移动端+SDK集成\n- PC+APP+API: 全平台(会生成PC、APP、API三份报告)\n根据需求内容选择合适的类型,如果需求提到「接口和页面」,应该使用 PC+API")
|
|
7624
|
+
page_style: stringType().optional().describe("HTML\u9875\u9762\u98CE\u683C\u6837\u5F0F\uFF08\u53EF\u9009\uFF09\uFF0C\u9ED8\u8BA4\u4F7F\u7528 TailwindCSS \u7B80\u7EA6\u98CE\u683C\u3002\u53EF\u81EA\u5B9A\u4E49 CSS \u53D8\u91CF\u548C\u6837\u5F0F\u3002"),
|
|
7625
|
+
page_type: enumType([
|
|
7626
|
+
"pc",
|
|
7627
|
+
"mobile",
|
|
7628
|
+
"responsive"
|
|
7629
|
+
]).default("responsive").describe("页面类型(可选):\n- pc: PC端页面\n- mobile: 移动端页面\n- responsive: 响应式页面(默认,同时支持PC和移动端)")
|
|
7186
7630
|
},
|
|
7187
7631
|
handler: async (args)=>{
|
|
7188
7632
|
try {
|
|
7189
|
-
const { requirement_analysis, current_project_path,
|
|
7633
|
+
const { requirement_analysis, current_project_path, page_style, page_type } = args;
|
|
7634
|
+
const finalPageStyle = page_style || DEFAULT_PAGE_STYLE;
|
|
7635
|
+
const finalPageType = page_type || "responsive";
|
|
7190
7636
|
if (!requirement_analysis || !current_project_path) return {
|
|
7191
7637
|
content: [
|
|
7192
7638
|
{
|
|
@@ -7204,20 +7650,234 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7204
7650
|
const serviceResult = await service.analyzeRequirements({
|
|
7205
7651
|
requirement_analysis,
|
|
7206
7652
|
current_project_path,
|
|
7207
|
-
|
|
7653
|
+
page_style: finalPageStyle,
|
|
7654
|
+
page_type: finalPageType
|
|
7208
7655
|
});
|
|
7209
|
-
|
|
7656
|
+
const generationTasks = serviceResult.generationTasks || [];
|
|
7657
|
+
if (0 === generationTasks.length) return {
|
|
7210
7658
|
content: [
|
|
7211
7659
|
{
|
|
7212
7660
|
type: "text",
|
|
7213
7661
|
text: JSON.stringify({
|
|
7662
|
+
success: false,
|
|
7663
|
+
message: "\u6CA1\u6709\u751F\u6210\u4EFB\u52A1",
|
|
7664
|
+
data: null
|
|
7665
|
+
})
|
|
7666
|
+
}
|
|
7667
|
+
],
|
|
7668
|
+
isError: true
|
|
7669
|
+
};
|
|
7670
|
+
logger.info(`\u{5F00}\u{59CB}\u{5B8C}\u{5168}\u{5E76}\u{884C}\u{751F}\u{6210} ${generationTasks.length} \u{4EFD}\u{6587}\u{6863}\u{FF08}\u{8D85}\u{65F6}: ${EXECUTION_TIMEOUT_MS}ms\u{FF09}...`);
|
|
7671
|
+
const startTime = Date.now();
|
|
7672
|
+
const apiTask = generationTasks.find((t)=>"API" === t.requirementType);
|
|
7673
|
+
const htmlTask = generationTasks.find((t)=>"HTML" === t.requirementType);
|
|
7674
|
+
const taskStatus = new Map();
|
|
7675
|
+
if (apiTask) taskStatus.set("API", {
|
|
7676
|
+
type: "API",
|
|
7677
|
+
content: "",
|
|
7678
|
+
outputPath: apiTask.outputPath,
|
|
7679
|
+
success: false,
|
|
7680
|
+
completed: false
|
|
7681
|
+
});
|
|
7682
|
+
if (htmlTask) {
|
|
7683
|
+
const htmlOutputPath = htmlTask.outputPath.replace(/\.md$/, ".html");
|
|
7684
|
+
taskStatus.set("HTML", {
|
|
7685
|
+
type: "HTML",
|
|
7686
|
+
content: "",
|
|
7687
|
+
outputPath: htmlOutputPath,
|
|
7688
|
+
success: false,
|
|
7689
|
+
completed: false
|
|
7690
|
+
});
|
|
7691
|
+
}
|
|
7692
|
+
const parallelTasks = [];
|
|
7693
|
+
if (apiTask) {
|
|
7694
|
+
const apiPromise = (async ()=>{
|
|
7695
|
+
try {
|
|
7696
|
+
logger.info(`\u{5F00}\u{59CB}\u{5E76}\u{884C}\u{751F}\u{6210}API\u{6587}\u{6863}\u{FF08}${API_SECTIONS.length}\u{4E2A}\u{7AE0}\u{8282}\u{FF09}`);
|
|
7697
|
+
const sectionResults = await Promise.all(API_SECTIONS.map((section)=>generateApiSection(section, apiTask.templateVariables)));
|
|
7698
|
+
const successSections = sectionResults.filter((r)=>r.success);
|
|
7699
|
+
const header = `# ${apiTask.templateVariables.featureName} - API\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
|
|
7700
|
+
|
|
7701
|
+
> **\u{751F}\u{6210}\u{65F6}\u{95F4}**: ${new Date().toISOString()}
|
|
7702
|
+
> **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: ${apiTask.templateVariables.businessDomain}
|
|
7703
|
+
|
|
7704
|
+
---
|
|
7705
|
+
|
|
7706
|
+
`;
|
|
7707
|
+
const document1 = header + successSections.map((s)=>s.content).join("\n\n---\n\n");
|
|
7708
|
+
const outputDir = external_path_default().dirname(apiTask.outputPath);
|
|
7709
|
+
await promises_namespaceObject.mkdir(outputDir, {
|
|
7710
|
+
recursive: true
|
|
7711
|
+
});
|
|
7712
|
+
await promises_namespaceObject.writeFile(apiTask.outputPath, document1, "utf-8");
|
|
7713
|
+
taskStatus.set("API", {
|
|
7714
|
+
type: "API",
|
|
7715
|
+
content: document1,
|
|
7716
|
+
outputPath: apiTask.outputPath,
|
|
7717
|
+
success: true,
|
|
7718
|
+
completed: true
|
|
7719
|
+
});
|
|
7720
|
+
logger.info(`API\u{6587}\u{6863}\u{751F}\u{6210}\u{5B8C}\u{6210}`, {
|
|
7721
|
+
length: document1.length
|
|
7722
|
+
});
|
|
7723
|
+
} catch (error) {
|
|
7724
|
+
taskStatus.set("API", {
|
|
7725
|
+
type: "API",
|
|
7726
|
+
content: "",
|
|
7727
|
+
outputPath: apiTask.outputPath,
|
|
7728
|
+
success: false,
|
|
7729
|
+
error: error.message,
|
|
7730
|
+
completed: true
|
|
7731
|
+
});
|
|
7732
|
+
}
|
|
7733
|
+
})();
|
|
7734
|
+
parallelTasks.push(apiPromise);
|
|
7735
|
+
}
|
|
7736
|
+
if (htmlTask) {
|
|
7737
|
+
const htmlPromise = (async ()=>{
|
|
7738
|
+
try {
|
|
7739
|
+
logger.info(`\u{5F00}\u{59CB}\u{751F}\u{6210}\u{53EF}\u{4EA4}\u{4E92}HTML\u{9875}\u{9762}`);
|
|
7740
|
+
const htmlOutputPath = htmlTask.outputPath.replace(/\.md$/, ".html");
|
|
7741
|
+
const htmlContent = await generateInteractiveHtml(htmlTask.templateVariables);
|
|
7742
|
+
const outputDir = external_path_default().dirname(htmlOutputPath);
|
|
7743
|
+
await promises_namespaceObject.mkdir(outputDir, {
|
|
7744
|
+
recursive: true
|
|
7745
|
+
});
|
|
7746
|
+
await promises_namespaceObject.writeFile(htmlOutputPath, htmlContent, "utf-8");
|
|
7747
|
+
taskStatus.set("HTML", {
|
|
7748
|
+
type: "HTML",
|
|
7749
|
+
content: htmlContent,
|
|
7750
|
+
outputPath: htmlOutputPath,
|
|
7214
7751
|
success: true,
|
|
7215
|
-
|
|
7752
|
+
completed: true
|
|
7753
|
+
});
|
|
7754
|
+
logger.info(`HTML\u{9875}\u{9762}\u{751F}\u{6210}\u{5B8C}\u{6210}`, {
|
|
7755
|
+
length: htmlContent.length
|
|
7756
|
+
});
|
|
7757
|
+
} catch (error) {
|
|
7758
|
+
taskStatus.set("HTML", {
|
|
7759
|
+
type: "HTML",
|
|
7760
|
+
content: "",
|
|
7761
|
+
outputPath: htmlTask.outputPath.replace(/\.md$/, ".html"),
|
|
7762
|
+
success: false,
|
|
7763
|
+
error: error.message,
|
|
7764
|
+
completed: true
|
|
7765
|
+
});
|
|
7766
|
+
}
|
|
7767
|
+
})();
|
|
7768
|
+
parallelTasks.push(htmlPromise);
|
|
7769
|
+
}
|
|
7770
|
+
const timeoutPromise = new Promise((resolve)=>{
|
|
7771
|
+
setTimeout(()=>resolve("timeout"), EXECUTION_TIMEOUT_MS);
|
|
7772
|
+
});
|
|
7773
|
+
const raceResult = await Promise.race([
|
|
7774
|
+
Promise.all(parallelTasks).then(()=>"completed"),
|
|
7775
|
+
timeoutPromise
|
|
7776
|
+
]);
|
|
7777
|
+
const totalDuration = Date.now() - startTime;
|
|
7778
|
+
const isTimeout = "timeout" === raceResult;
|
|
7779
|
+
const results = Array.from(taskStatus.values());
|
|
7780
|
+
const completedResults = results.filter((r)=>r.completed);
|
|
7781
|
+
const pendingResults = results.filter((r)=>!r.completed);
|
|
7782
|
+
const successCount = completedResults.filter((r)=>r.success).length;
|
|
7783
|
+
const failedCount = completedResults.filter((r)=>!r.success && r.completed).length;
|
|
7784
|
+
const generatedFiles = completedResults.filter((r)=>r.success).map((r)=>r.outputPath);
|
|
7785
|
+
logger.info(`\u{5E76}\u{884C}\u{751F}\u{6210}${isTimeout ? "\u8D85\u65F6" : "\u5B8C\u6210"}`, {
|
|
7786
|
+
total: results.length,
|
|
7787
|
+
completed: completedResults.length,
|
|
7788
|
+
pending: pendingResults.length,
|
|
7789
|
+
success: successCount,
|
|
7790
|
+
failed: failedCount,
|
|
7791
|
+
totalDuration: `${totalDuration}ms`,
|
|
7792
|
+
isTimeout
|
|
7793
|
+
});
|
|
7794
|
+
if (isTimeout && pendingResults.length > 0) {
|
|
7795
|
+
const pendingPrompts = pendingResults.map((task)=>{
|
|
7796
|
+
if ("API" === task.type && apiTask) return {
|
|
7797
|
+
type: "API",
|
|
7798
|
+
outputPath: task.outputPath,
|
|
7799
|
+
prompt: `\u{8BF7}\u{4E3A}"${apiTask.templateVariables.featureName}"\u{751F}\u{6210}API\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF0C}\u{5305}\u{542B}\u{4EE5}\u{4E0B}\u{7AE0}\u{8282}\u{FF1A}
|
|
7800
|
+
1. \u{6587}\u{6863}\u{5934}\u{90E8}\u{FF08}\u{6807}\u{9898}\u{3001}\u{751F}\u{6210}\u{65F6}\u{95F4}\u{3001}\u{4E1A}\u{52A1}\u{9886}\u{57DF}\u{FF09}
|
|
7801
|
+
2. \u{9700}\u{6C42}\u{80CC}\u{666F}\u{FF08}\u{9700}\u{6C42}\u{80CC}\u{666F}\u{3001}\u{5173}\u{952E}\u{529F}\u{80FD}\u{3001}\u{6D89}\u{53CA}\u{89D2}\u{8272}\u{FF09}
|
|
7802
|
+
3. \u{529F}\u{80FD}\u{8BBE}\u{8BA1}\u{8BF4}\u{660E}\u{FF08}\u{6D41}\u{7A0B}\u{7F16}\u{53F7}\u{3001}\u{524D}\u{7F6E}\u{6761}\u{4EF6}\u{3001}\u{89D2}\u{8272}\u{7B49}\u{8868}\u{683C}\u{FF09}
|
|
7803
|
+
4. \u{6570}\u{636E}\u{5EFA}\u{6A21}\u{FF08}ER\u{903B}\u{8F91}\u{56FE}mermaid erDiagram + \u{6570}\u{636E}\u{8868}\u{5B9E}\u{4F53}\u{8BBE}\u{8BA1}\u{FF09}
|
|
7804
|
+
5. API\u{63A5}\u{53E3}\u{8BBE}\u{8BA1}\u{FF08}\u{63A5}\u{53E3}\u{5217}\u{8868}\u{3001}\u{8BF7}\u{6C42}\u{53C2}\u{6570}\u{3001}\u{54CD}\u{5E94}\u{53C2}\u{6570}\u{3001}\u{9519}\u{8BEF}\u{7801}\u{FF09}
|
|
7805
|
+
6. \u{4E1A}\u{52A1}\u{65F6}\u{5E8F}\u{56FE}\u{FF08}mermaid sequenceDiagram\u{FF09}
|
|
7806
|
+
7. \u{4E1A}\u{52A1}\u{72B6}\u{6001}\u{FF08}\u{72B6}\u{6001}\u{63CF}\u{8FF0}\u{8868}\u{683C}\u{FF09}
|
|
7807
|
+
8. \u{4F2A}\u{4EE3}\u{7801}\u{793A}\u{4F8B}\u{FF08}\u{6838}\u{5FC3}\u{4E1A}\u{52A1}\u{903B}\u{8F91}\u{FF09}
|
|
7808
|
+
|
|
7809
|
+
\u{4E1A}\u{52A1}\u{9886}\u{57DF}: ${apiTask.templateVariables.businessDomain}
|
|
7810
|
+
\u{9700}\u{6C42}\u{8BE6}\u{60C5}: ${apiTask.templateVariables.inputContent?.substring(0, 500) || ''}
|
|
7811
|
+
|
|
7812
|
+
\u{8BF7}\u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}Markdown\u{6587}\u{6863}\u{5E76}\u{4FDD}\u{5B58}\u{5230}: ${task.outputPath}`
|
|
7813
|
+
};
|
|
7814
|
+
if ("HTML" === task.type && htmlTask) return {
|
|
7815
|
+
type: "HTML",
|
|
7816
|
+
outputPath: task.outputPath,
|
|
7817
|
+
prompt: `\u{8BF7}\u{4E3A}"${htmlTask.templateVariables.featureName}"\u{751F}\u{6210}\u{53EF}\u{4EA4}\u{4E92}\u{7684}HTML\u{9875}\u{9762}\u{FF1A}
|
|
7818
|
+
|
|
7819
|
+
\u{6280}\u{672F}\u{8981}\u{6C42}\u{FF1A}
|
|
7820
|
+
1. \u{5B8C}\u{6574}HTML\u{6587}\u{4EF6}\u{FF08}<!DOCTYPE html>\u{3001}<html>\u{3001}<head>\u{3001}<body>\u{FF09}
|
|
7821
|
+
2. \u{4F7F}\u{7528}TailwindCSS\u{FF08}CDN\u{5F15}\u{5165}\u{FF09}\u{8FDB}\u{884C}\u{6837}\u{5F0F}\u{8BBE}\u{8BA1}
|
|
7822
|
+
3. \u{9875}\u{9762}\u{7C7B}\u{578B}: ${htmlTask.templateVariables.pageType || 'responsive'}\u{5E03}\u{5C40}
|
|
7823
|
+
4. \u{5305}\u{542B}\u{8868}\u{5355}\u{9A8C}\u{8BC1}\u{548C}\u{4EA4}\u{4E92}\u{903B}\u{8F91}\u{FF08}\u{539F}\u{751F}JavaScript\u{FF09}
|
|
7824
|
+
5. \u{5305}\u{542B}\u{52A0}\u{8F7D}\u{72B6}\u{6001}\u{3001}\u{6210}\u{529F}/\u{5931}\u{8D25}\u{63D0}\u{793A}
|
|
7825
|
+
6. \u{6240}\u{6709}\u{6587}\u{672C}\u{4F7F}\u{7528}\u{4E2D}\u{6587}
|
|
7826
|
+
|
|
7827
|
+
\u{9875}\u{9762}\u{98CE}\u{683C}\u{FF1A}
|
|
7828
|
+
${htmlTask.templateVariables.pageStyle || DEFAULT_PAGE_STYLE}
|
|
7829
|
+
|
|
7830
|
+
\u{9700}\u{6C42}\u{8BE6}\u{60C5}: ${htmlTask.templateVariables.inputContent?.substring(0, 500) || ''}
|
|
7831
|
+
|
|
7832
|
+
\u{8BF7}\u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}HTML\u{4EE3}\u{7801}\u{5E76}\u{4FDD}\u{5B58}\u{5230}: ${task.outputPath}`
|
|
7833
|
+
};
|
|
7834
|
+
return null;
|
|
7835
|
+
}).filter(Boolean);
|
|
7836
|
+
return {
|
|
7837
|
+
content: [
|
|
7838
|
+
{
|
|
7839
|
+
type: "text",
|
|
7840
|
+
text: JSON.stringify({
|
|
7841
|
+
success: successCount > 0,
|
|
7842
|
+
timeout: true,
|
|
7843
|
+
message: `\u{6267}\u{884C}\u{8D85}\u{65F6}(${EXECUTION_TIMEOUT_MS}ms)\u{FF1A}${successCount} \u{5B8C}\u{6210}\u{FF0C}${pendingResults.length} \u{5F85}\u{6267}\u{884C}\u{FF0C}\u{8BF7}\u{7EE7}\u{7EED}\u{6267}\u{884C}\u{4EE5}\u{4E0B}\u{4EFB}\u{52A1}`,
|
|
7844
|
+
data: {
|
|
7845
|
+
outputPath: serviceResult.outputPath,
|
|
7846
|
+
generatedFiles,
|
|
7847
|
+
analysisInfo: serviceResult.analysisInfo || {},
|
|
7848
|
+
completedResults: completedResults.map((r)=>({
|
|
7849
|
+
type: r.type,
|
|
7850
|
+
outputPath: r.outputPath,
|
|
7851
|
+
success: r.success,
|
|
7852
|
+
error: r.error,
|
|
7853
|
+
contentLength: r.content?.length || 0
|
|
7854
|
+
})),
|
|
7855
|
+
pendingTasks: pendingPrompts
|
|
7856
|
+
}
|
|
7857
|
+
})
|
|
7858
|
+
}
|
|
7859
|
+
]
|
|
7860
|
+
};
|
|
7861
|
+
}
|
|
7862
|
+
return {
|
|
7863
|
+
content: [
|
|
7864
|
+
{
|
|
7865
|
+
type: "text",
|
|
7866
|
+
text: JSON.stringify({
|
|
7867
|
+
success: successCount > 0,
|
|
7868
|
+
timeout: false,
|
|
7869
|
+
message: `\u{6587}\u{6863}\u{751F}\u{6210}\u{5B8C}\u{6210}\u{FF1A}${successCount} \u{6210}\u{529F}\u{FF0C}${failedCount} \u{5931}\u{8D25}\u{FF0C}\u{603B}\u{8017}\u{65F6} ${totalDuration}ms`,
|
|
7216
7870
|
data: {
|
|
7217
7871
|
outputPath: serviceResult.outputPath,
|
|
7218
|
-
generatedFiles
|
|
7872
|
+
generatedFiles,
|
|
7219
7873
|
analysisInfo: serviceResult.analysisInfo || {},
|
|
7220
|
-
|
|
7874
|
+
results: results.map((r)=>({
|
|
7875
|
+
type: r.type,
|
|
7876
|
+
outputPath: r.outputPath,
|
|
7877
|
+
success: r.success,
|
|
7878
|
+
error: r.error,
|
|
7879
|
+
contentLength: r.content?.length || 0
|
|
7880
|
+
}))
|
|
7221
7881
|
}
|
|
7222
7882
|
})
|
|
7223
7883
|
}
|
|
@@ -7593,214 +8253,18 @@ ${requirementSection}
|
|
|
7593
8253
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
7594
8254
|
const filename = `change-analysis-${timestamp}.${'json' === format ? 'json' : 'md'}`;
|
|
7595
8255
|
const outputPath = external_path_default().join(outputDir, filename);
|
|
7596
|
-
if ('json' === format) {
|
|
7597
|
-
const jsonData = {
|
|
7598
|
-
timestamp: new Date().toISOString(),
|
|
7599
|
-
prompt,
|
|
7600
|
-
type: 'change-analysis'
|
|
7601
|
-
};
|
|
7602
|
-
external_fs_default().writeFileSync(outputPath, JSON.stringify(jsonData, null, 2), 'utf-8');
|
|
7603
|
-
} else external_fs_default().writeFileSync(outputPath, prompt, 'utf-8');
|
|
7604
|
-
return outputPath;
|
|
7605
|
-
}
|
|
7606
|
-
const external_sharp_namespaceObject = require("sharp");
|
|
7607
|
-
var external_sharp_default = /*#__PURE__*/ __webpack_require__.n(external_sharp_namespaceObject);
|
|
7608
|
-
async function invokeFlow(params, streamCb) {
|
|
7609
|
-
const { appid = 'app-ESTcrkOPOmkxdrO0120mE4s1', data, timeout = 1800000 } = params;
|
|
7610
|
-
const controller = new AbortController();
|
|
7611
|
-
const signal = controller.signal;
|
|
7612
|
-
if ('undefined' == typeof ReadableStream) throw new Error('ReadableStream is not supported in this environment');
|
|
7613
|
-
const fetchData = async (retryCount = 0)=>{
|
|
7614
|
-
try {
|
|
7615
|
-
const fetchOptions = {
|
|
7616
|
-
method: 'POST',
|
|
7617
|
-
headers: {
|
|
7618
|
-
Authorization: `Bearer ${appid}`,
|
|
7619
|
-
'Content-Type': 'application/json'
|
|
7620
|
-
},
|
|
7621
|
-
body: JSON.stringify({
|
|
7622
|
-
inputs: data,
|
|
7623
|
-
response_mode: 'streaming',
|
|
7624
|
-
user: "aico-mcp"
|
|
7625
|
-
}),
|
|
7626
|
-
signal
|
|
7627
|
-
};
|
|
7628
|
-
const res = await fetch('http://11.0.166.20:9199/v1/workflows/run', fetchOptions);
|
|
7629
|
-
if (!res.ok) {
|
|
7630
|
-
if (retryCount < 3) {
|
|
7631
|
-
await new Promise((resolve)=>setTimeout(resolve, 1000));
|
|
7632
|
-
return fetchData(retryCount + 1);
|
|
7633
|
-
}
|
|
7634
|
-
const errorResponse = await res.text();
|
|
7635
|
-
throw new Error(`\u{7F51}\u{7EDC}\u{54CD}\u{5E94}\u{5F02}\u{5E38}: ${res.status} ${res.statusText} - ${errorResponse}`);
|
|
7636
|
-
}
|
|
7637
|
-
if (res.ok) if (res.body) {
|
|
7638
|
-
const reader = res.body.getReader();
|
|
7639
|
-
const decoder = new TextDecoder('utf-8');
|
|
7640
|
-
if (streamCb) return void new ReadableStream({
|
|
7641
|
-
start (controller) {
|
|
7642
|
-
let buffer = '';
|
|
7643
|
-
function push() {
|
|
7644
|
-
reader.read().then(({ done, value })=>{
|
|
7645
|
-
if (done) {
|
|
7646
|
-
const lines = buffer.split('\n');
|
|
7647
|
-
for (const line of lines)handleLine(line, controller);
|
|
7648
|
-
if (streamCb) streamCb({
|
|
7649
|
-
isEnd: true
|
|
7650
|
-
});
|
|
7651
|
-
controller.close();
|
|
7652
|
-
return;
|
|
7653
|
-
}
|
|
7654
|
-
const chunkText = decoder.decode(value, {
|
|
7655
|
-
stream: true
|
|
7656
|
-
});
|
|
7657
|
-
buffer += chunkText;
|
|
7658
|
-
const lines = buffer.split('\n');
|
|
7659
|
-
for(let i = 0; i < lines.length - 1; i++)handleLine(lines[i], controller);
|
|
7660
|
-
buffer = lines[lines.length - 1];
|
|
7661
|
-
push();
|
|
7662
|
-
});
|
|
7663
|
-
}
|
|
7664
|
-
function handleLine(line, controller) {
|
|
7665
|
-
line = line.trim();
|
|
7666
|
-
if (line.startsWith('data:')) {
|
|
7667
|
-
const dataStr = line.slice(5).trim();
|
|
7668
|
-
if ('' === dataStr) return;
|
|
7669
|
-
try {
|
|
7670
|
-
const jsonData = JSON.parse(dataStr);
|
|
7671
|
-
if (jsonData.data?.text) {
|
|
7672
|
-
const wrappedData = {
|
|
7673
|
-
content: jsonData.data.text.toString(),
|
|
7674
|
-
controller
|
|
7675
|
-
};
|
|
7676
|
-
if (streamCb) streamCb(wrappedData);
|
|
7677
|
-
}
|
|
7678
|
-
} catch (e) {
|
|
7679
|
-
console.error("\u89E3\u6790JSON\u5931\u8D25:", e);
|
|
7680
|
-
}
|
|
7681
|
-
}
|
|
7682
|
-
}
|
|
7683
|
-
push();
|
|
7684
|
-
}
|
|
7685
|
-
});
|
|
7686
|
-
{
|
|
7687
|
-
let buffer = '';
|
|
7688
|
-
let accumulatedText = '';
|
|
7689
|
-
let isResponseEnded = false;
|
|
7690
|
-
const readAll = async ()=>{
|
|
7691
|
-
const { done, value } = await reader.read();
|
|
7692
|
-
if (done) {
|
|
7693
|
-
if (!isResponseEnded) throw new Error("\u54CD\u5E94\u63D0\u524D\u7ED3\u675F");
|
|
7694
|
-
return accumulatedText;
|
|
7695
|
-
}
|
|
7696
|
-
const chunkText = decoder.decode(value, {
|
|
7697
|
-
stream: true
|
|
7698
|
-
});
|
|
7699
|
-
buffer += chunkText;
|
|
7700
|
-
const lines = buffer.split('\n');
|
|
7701
|
-
for(let i = 0; i < lines.length - 1; i++){
|
|
7702
|
-
const line = lines[i].trim();
|
|
7703
|
-
if (!line.startsWith('data:')) continue;
|
|
7704
|
-
const dataStr = line.slice(5).trim();
|
|
7705
|
-
if ('' !== dataStr) try {
|
|
7706
|
-
const jsonData = JSON.parse(dataStr);
|
|
7707
|
-
switch(jsonData.event){
|
|
7708
|
-
case 'message':
|
|
7709
|
-
case 'agent_message':
|
|
7710
|
-
case 'text_chunk':
|
|
7711
|
-
{
|
|
7712
|
-
const content = 'text_chunk' === jsonData.event ? jsonData.data.text : jsonData.answer;
|
|
7713
|
-
accumulatedText += content;
|
|
7714
|
-
break;
|
|
7715
|
-
}
|
|
7716
|
-
case 'workflow_finished':
|
|
7717
|
-
accumulatedText = jsonData.data;
|
|
7718
|
-
isResponseEnded = true;
|
|
7719
|
-
break;
|
|
7720
|
-
case 'message_end':
|
|
7721
|
-
isResponseEnded = true;
|
|
7722
|
-
break;
|
|
7723
|
-
case 'error':
|
|
7724
|
-
throw new Error(`\u{670D}\u{52A1}\u{5668}\u{9519}\u{8BEF}: ${jsonData.code}, ${jsonData.message}`);
|
|
7725
|
-
default:
|
|
7726
|
-
break;
|
|
7727
|
-
}
|
|
7728
|
-
} catch (e) {
|
|
7729
|
-
throw new Error("\u89E3\u6790JSON\u5931\u8D25: " + e.message);
|
|
7730
|
-
}
|
|
7731
|
-
}
|
|
7732
|
-
buffer = lines[lines.length - 1];
|
|
7733
|
-
return readAll();
|
|
7734
|
-
};
|
|
7735
|
-
return readAll();
|
|
7736
|
-
}
|
|
7737
|
-
} else throw new Error("\u54CD\u5E94\u4F53\u4E3A\u7A7A");
|
|
7738
|
-
{
|
|
7739
|
-
const errorResponse = await res.text();
|
|
7740
|
-
throw new Error(`\u{7F51}\u{7EDC}\u{54CD}\u{5E94}\u{5F02}\u{5E38}: ${res.status} ${res.statusText} - ${errorResponse}`);
|
|
7741
|
-
}
|
|
7742
|
-
} catch (error) {
|
|
7743
|
-
if ('AbortError' === error.name) throw new Error("\u8BF7\u6C42\u5DF2\u88AB\u4E2D\u6B62\uFF0C\u8D85\u65F6");
|
|
7744
|
-
throw error;
|
|
7745
|
-
}
|
|
7746
|
-
};
|
|
7747
|
-
try {
|
|
7748
|
-
const result = await Promise.race([
|
|
7749
|
-
fetchData(),
|
|
7750
|
-
new Promise((_, reject)=>{
|
|
7751
|
-
setTimeout(()=>{
|
|
7752
|
-
controller.abort();
|
|
7753
|
-
reject(new Error("\u8BF7\u6C42\u8D85\u65F6"));
|
|
7754
|
-
}, timeout);
|
|
7755
|
-
})
|
|
7756
|
-
]);
|
|
7757
|
-
if (streamCb) return;
|
|
7758
|
-
return result;
|
|
7759
|
-
} catch (error) {
|
|
7760
|
-
controller.abort();
|
|
7761
|
-
throw error;
|
|
7762
|
-
}
|
|
7763
|
-
}
|
|
7764
|
-
async function uploadFile(params) {
|
|
7765
|
-
const { appid, filePath, user = 'aico-mcp' } = params;
|
|
7766
|
-
try {
|
|
7767
|
-
const fileBuffer = await external_fs_default().promises.readFile(filePath);
|
|
7768
|
-
const fileName = external_path_default().basename(filePath);
|
|
7769
|
-
const fileExtension = external_path_default().extname(filePath).toLowerCase().slice(1);
|
|
7770
|
-
const mimeTypes = {
|
|
7771
|
-
png: 'image/png',
|
|
7772
|
-
jpeg: 'image/jpeg',
|
|
7773
|
-
jpg: 'image/jpeg',
|
|
7774
|
-
webp: 'image/webp',
|
|
7775
|
-
gif: 'image/gif'
|
|
7776
|
-
};
|
|
7777
|
-
const mimeType = mimeTypes[fileExtension] || 'application/octet-stream';
|
|
7778
|
-
const formData = new FormData();
|
|
7779
|
-
formData.append('file', new Blob([
|
|
7780
|
-
fileBuffer.buffer
|
|
7781
|
-
], {
|
|
7782
|
-
type: mimeType
|
|
7783
|
-
}), fileName);
|
|
7784
|
-
formData.append('user', user);
|
|
7785
|
-
const response = await fetch('http://11.0.166.20:9199/v1/files/upload', {
|
|
7786
|
-
method: 'POST',
|
|
7787
|
-
headers: {
|
|
7788
|
-
Authorization: `Bearer ${appid}`
|
|
7789
|
-
},
|
|
7790
|
-
body: formData
|
|
7791
|
-
});
|
|
7792
|
-
if (!response.ok) {
|
|
7793
|
-
const errorText = await response.text();
|
|
7794
|
-
throw new Error(`\u{6587}\u{4EF6}\u{4E0A}\u{4F20}\u{5931}\u{8D25}: ${response.status} ${response.statusText} - ${errorText}`);
|
|
7795
|
-
}
|
|
7796
|
-
const result = await response.json();
|
|
7797
|
-
if (!result.id || !result.name) throw new Error("\u65E0\u6548\u7684\u6587\u4EF6\u4E0A\u4F20\u54CD\u5E94\u683C\u5F0F");
|
|
7798
|
-
return result;
|
|
7799
|
-
} catch (error) {
|
|
7800
|
-
if (error instanceof Error) throw new Error(`\u{6587}\u{4EF6}\u{4E0A}\u{4F20}\u{5931}\u{8D25}: ${error.message}`);
|
|
7801
|
-
throw new Error("\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: \u672A\u77E5\u9519\u8BEF");
|
|
7802
|
-
}
|
|
8256
|
+
if ('json' === format) {
|
|
8257
|
+
const jsonData = {
|
|
8258
|
+
timestamp: new Date().toISOString(),
|
|
8259
|
+
prompt,
|
|
8260
|
+
type: 'change-analysis'
|
|
8261
|
+
};
|
|
8262
|
+
external_fs_default().writeFileSync(outputPath, JSON.stringify(jsonData, null, 2), 'utf-8');
|
|
8263
|
+
} else external_fs_default().writeFileSync(outputPath, prompt, 'utf-8');
|
|
8264
|
+
return outputPath;
|
|
7803
8265
|
}
|
|
8266
|
+
const external_sharp_namespaceObject = require("sharp");
|
|
8267
|
+
var external_sharp_default = /*#__PURE__*/ __webpack_require__.n(external_sharp_namespaceObject);
|
|
7804
8268
|
class ImageAnalysisError extends Error {
|
|
7805
8269
|
code;
|
|
7806
8270
|
context;
|
|
@@ -7837,7 +8301,7 @@ ${requirementSection}
|
|
|
7837
8301
|
});
|
|
7838
8302
|
await this.validateParams(imagePath);
|
|
7839
8303
|
const basicInfo = await this.getImageBasicInfo(imagePath);
|
|
7840
|
-
const analysisContent = await this.performAIAnalysis(imagePath,
|
|
8304
|
+
const analysisContent = await this.performAIAnalysis(imagePath, context);
|
|
7841
8305
|
const processingTime = Date.now() - startTime;
|
|
7842
8306
|
if (!analysisContent) throw new ImageAnalysisError("AI\u5206\u6790\u8FD4\u56DE\u7A7A\u7ED3\u679C", types_AnalysisErrorCodes.ANALYSIS_FAILED, {
|
|
7843
8307
|
params: {
|
|
@@ -7864,16 +8328,15 @@ ${requirementSection}
|
|
|
7864
8328
|
throw error;
|
|
7865
8329
|
}
|
|
7866
8330
|
}
|
|
7867
|
-
async performAIAnalysis(imagePath,
|
|
8331
|
+
async performAIAnalysis(imagePath, context) {
|
|
7868
8332
|
try {
|
|
7869
|
-
const imageBase64 = await this.imageToBase64(imagePath);
|
|
7870
8333
|
const systemPrompt = `You must interpret and analyze images strictly according to the assigned task.
|
|
7871
8334
|
When an image placeholder is provided, your role is to parse the image content only within the scope of the user's instructions.
|
|
7872
8335
|
Do not ignore or deviate from the task.
|
|
7873
8336
|
Always ensure that your response reflects a clear, accurate interpretation of the image aligned with the given objective.`;
|
|
7874
|
-
const userPrompt = context
|
|
7875
|
-
const aiResponse = await openAIService.
|
|
7876
|
-
|
|
8337
|
+
const userPrompt = `${context}, You must provide a complete and detailed description of all content in the image, including scenes, objects, text, colors, layout, relationships, and all other visible elements and details. Ensure the description is detailed enough so that subsequent text-based language models can fully understand the image content through text alone.Always respond in Chinese-simplified`;
|
|
8338
|
+
const aiResponse = await openAIService.analyzeImageWithPath({
|
|
8339
|
+
image_path: imagePath,
|
|
7877
8340
|
prompt: userPrompt,
|
|
7878
8341
|
system_prompt: systemPrompt
|
|
7879
8342
|
});
|
|
@@ -7883,26 +8346,15 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7883
8346
|
tags: []
|
|
7884
8347
|
};
|
|
7885
8348
|
} catch (error) {
|
|
7886
|
-
logger.
|
|
8349
|
+
logger.error("AI\u5206\u6790\u5931\u8D25", {
|
|
7887
8350
|
error,
|
|
7888
8351
|
params: {
|
|
7889
8352
|
image_path: imagePath
|
|
7890
8353
|
}
|
|
7891
8354
|
});
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
}
|
|
7895
|
-
logger.error("Dify\u515C\u5E95\u5206\u6790\u4E5F\u5931\u8D25", {
|
|
7896
|
-
error: fallbackError,
|
|
7897
|
-
params: {
|
|
7898
|
-
image_path: imagePath
|
|
7899
|
-
}
|
|
7900
|
-
});
|
|
7901
|
-
throw new ImageAnalysisError("\u8BC6\u522B\u56FE\u7247\u5931\u8D25", types_AnalysisErrorCodes.ANALYSIS_FAILED, {
|
|
7902
|
-
originalError: error,
|
|
7903
|
-
fallbackError
|
|
7904
|
-
});
|
|
7905
|
-
}
|
|
8355
|
+
throw new ImageAnalysisError("\u8BC6\u522B\u56FE\u7247\u5931\u8D25", types_AnalysisErrorCodes.ANALYSIS_FAILED, {
|
|
8356
|
+
originalError: error
|
|
8357
|
+
});
|
|
7906
8358
|
}
|
|
7907
8359
|
}
|
|
7908
8360
|
async getImageBasicInfo(imagePath) {
|
|
@@ -7911,7 +8363,7 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7911
8363
|
const stats = await promises_namespaceObject.stat(imagePath);
|
|
7912
8364
|
return {
|
|
7913
8365
|
path: imagePath,
|
|
7914
|
-
format: metadata.format ||
|
|
8366
|
+
format: metadata.format || "unknown",
|
|
7915
8367
|
dimensions: {
|
|
7916
8368
|
width: metadata.width || 0,
|
|
7917
8369
|
height: metadata.height || 0
|
|
@@ -7925,37 +8377,6 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7925
8377
|
});
|
|
7926
8378
|
}
|
|
7927
8379
|
}
|
|
7928
|
-
async imageToBase64(imagePath) {
|
|
7929
|
-
try {
|
|
7930
|
-
const imageBuffer = await promises_namespaceObject.readFile(imagePath);
|
|
7931
|
-
const base64 = imageBuffer.toString('base64');
|
|
7932
|
-
const ext = external_path_namespaceObject.extname(imagePath).toLowerCase();
|
|
7933
|
-
let mimeType = 'image/jpeg';
|
|
7934
|
-
switch(ext){
|
|
7935
|
-
case '.png':
|
|
7936
|
-
mimeType = 'image/png';
|
|
7937
|
-
break;
|
|
7938
|
-
case '.gif':
|
|
7939
|
-
mimeType = 'image/gif';
|
|
7940
|
-
break;
|
|
7941
|
-
case '.webp':
|
|
7942
|
-
mimeType = 'image/webp';
|
|
7943
|
-
break;
|
|
7944
|
-
case '.jpg':
|
|
7945
|
-
case '.jpeg':
|
|
7946
|
-
mimeType = 'image/jpeg';
|
|
7947
|
-
break;
|
|
7948
|
-
default:
|
|
7949
|
-
mimeType = 'image/jpeg';
|
|
7950
|
-
}
|
|
7951
|
-
return `data:${mimeType};base64,${base64}`;
|
|
7952
|
-
} catch (error) {
|
|
7953
|
-
throw new ImageAnalysisError(`\u{65E0}\u{6CD5}\u{8BFB}\u{53D6}\u{56FE}\u{7247}\u{6587}\u{4EF6}: ${imagePath}`, types_AnalysisErrorCodes.FILE_NOT_FOUND, {
|
|
7954
|
-
imagePath,
|
|
7955
|
-
originalError: error
|
|
7956
|
-
});
|
|
7957
|
-
}
|
|
7958
|
-
}
|
|
7959
8380
|
async validateParams(imagePath) {
|
|
7960
8381
|
try {
|
|
7961
8382
|
await promises_namespaceObject.access(imagePath);
|
|
@@ -7970,81 +8391,17 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7970
8391
|
supportedFormats: SUPPORTED_IMAGE_FORMATS
|
|
7971
8392
|
});
|
|
7972
8393
|
}
|
|
7973
|
-
formatFileSize(bytes) {
|
|
7974
|
-
if (0 === bytes) return '0 B';
|
|
7975
|
-
const k = 1024;
|
|
7976
|
-
const sizes = [
|
|
7977
|
-
'B',
|
|
7978
|
-
'KB',
|
|
7979
|
-
'MB',
|
|
7980
|
-
'GB'
|
|
7981
|
-
];
|
|
7982
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
7983
|
-
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
7984
|
-
}
|
|
7985
|
-
async fallbackToDifyAnalysis(imagePath, context) {
|
|
7986
|
-
logger.info("\u5F00\u59CBDify\u515C\u5E95\u56FE\u7247\u5206\u6790", {
|
|
7987
|
-
imagePath: imagePath,
|
|
7988
|
-
context: context
|
|
7989
|
-
});
|
|
7990
|
-
try {
|
|
7991
|
-
const uploadResult = await uploadFile({
|
|
7992
|
-
appid: 'app-AvlLh0nfN4l9oz1MSW4sEAQ6',
|
|
7993
|
-
filePath: imagePath,
|
|
7994
|
-
user: 'aico-mcp'
|
|
7995
|
-
});
|
|
7996
|
-
logger.info("\u6587\u4EF6\u4E0A\u4F20\u6210\u529F\uFF0C\u6587\u4EF6ID:", uploadResult.id);
|
|
7997
|
-
const workflowData = {
|
|
7998
|
-
imagePath: {
|
|
7999
|
-
type: 'image',
|
|
8000
|
-
transfer_method: 'local_file',
|
|
8001
|
-
upload_file_id: uploadResult.id
|
|
8002
|
-
},
|
|
8003
|
-
context: context || "\u8BF7\u5206\u6790\u8FD9\u5F20\u56FE\u7247\u7684\u5185\u5BB9"
|
|
8004
|
-
};
|
|
8005
|
-
const workflowResponse = await invokeFlow({
|
|
8006
|
-
appid: 'app-AvlLh0nfN4l9oz1MSW4sEAQ6',
|
|
8007
|
-
data: workflowData
|
|
8008
|
-
});
|
|
8009
|
-
logger.info("Dify\u5DE5\u4F5C\u6D41\u8C03\u7528\u6210\u529F", {
|
|
8010
|
-
response: workflowResponse
|
|
8011
|
-
});
|
|
8012
|
-
let summary = "\u5206\u6790\u5B8C\u6210";
|
|
8013
|
-
if ('string' == typeof workflowResponse) summary = workflowResponse;
|
|
8014
|
-
else if (workflowResponse?.data?.text) summary = workflowResponse.data.text;
|
|
8015
|
-
else if (workflowResponse?.answer) summary = workflowResponse.answer;
|
|
8016
|
-
else if (workflowResponse?.outputs?.text) summary = workflowResponse.outputs.text;
|
|
8017
|
-
else if (workflowResponse?.status === 'failed') throw new Error(`Dify\u{5DE5}\u{4F5C}\u{6D41}\u{6267}\u{884C}\u{5931}\u{8D25}: ${workflowResponse.error || "\u672A\u77E5\u9519\u8BEF"}`);
|
|
8018
|
-
return {
|
|
8019
|
-
summary: summary,
|
|
8020
|
-
details: {
|
|
8021
|
-
dify_response: workflowResponse,
|
|
8022
|
-
fallback_used: true
|
|
8023
|
-
},
|
|
8024
|
-
tags: [
|
|
8025
|
-
'dify-fallback'
|
|
8026
|
-
]
|
|
8027
|
-
};
|
|
8028
|
-
} catch (error) {
|
|
8029
|
-
logger.error("Dify\u670D\u52A1\u8C03\u7528\u5931\u8D25", {
|
|
8030
|
-
error: error instanceof Error ? error.message : String(error),
|
|
8031
|
-
imagePath: imagePath,
|
|
8032
|
-
context: context
|
|
8033
|
-
});
|
|
8034
|
-
throw new ImageAnalysisError(`\u{56FE}\u{7247}\u{5206}\u{6790}\u{670D}\u{52A1}\u{8C03}\u{7528}\u{5931}\u{8D25}: ${error instanceof Error ? error.message : String(error)}`, types_AnalysisErrorCodes.AI_SERVICE_ERROR);
|
|
8035
|
-
}
|
|
8036
|
-
}
|
|
8037
8394
|
}
|
|
8038
8395
|
const ImageAnalysisParamsSchema = objectType({
|
|
8039
8396
|
image_path: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
8040
|
-
context: stringType().
|
|
8397
|
+
context: stringType().min(1).describe("\u4E0A\u4E0B\u6587\u5185\u5BB9\uFF0C\u7528\u4E8E\u6307\u5BFC\u56FE\u7247\u5206\u6790\u7684\u65B9\u5411\u548C\u8303\u56F4")
|
|
8041
8398
|
});
|
|
8042
8399
|
const read_imageTool = {
|
|
8043
8400
|
name: "read_image",
|
|
8044
8401
|
description: "\u4E13\u4E1A\u56FE\u7247\u5185\u5BB9\u5206\u6790\u5DE5\u5177\uFF0C\u63D0\u4F9B\u7CBE\u786E\u7684\u56FE\u7247\u5185\u5BB9\u8BC6\u522B\u3002\u6839\u636E\u7528\u6237\u8F93\u5165\u7684\u4E0A\u4E0B\u6587\u4FE1\u606F\u548C\u56FE\u7247\u5185\u5BB9\uFF0C\u8FDB\u884C\u4E25\u683C\u57FA\u4E8E\u4EFB\u52A1\u6307\u4EE4\u7684\u5206\u6790\uFF0C\u4E0D\u504F\u79BB\u4EFB\u52A1\u8303\u56F4\uFF0C\u8F93\u51FA\u6E05\u6670\u51C6\u786E\u7684\u5206\u6790\u7ED3\u679C\u3002",
|
|
8045
8402
|
inputSchema: {
|
|
8046
8403
|
image_path: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
8047
|
-
context: stringType().
|
|
8404
|
+
context: stringType().min(1).describe("\u4E0A\u4E0B\u6587\u5185\u5BB9\uFF0C\u7528\u4E8E\u6307\u5BFC\u56FE\u7247\u5206\u6790\u7684\u65B9\u5411\u548C\u8303\u56F4")
|
|
8048
8405
|
},
|
|
8049
8406
|
handler: async (args)=>{
|
|
8050
8407
|
const analyzer = new ImageAnalyzer();
|
|
@@ -8370,7 +8727,7 @@ ${error?.message || "\u672A\u77E5\u9519\u8BEF"}`;
|
|
|
8370
8727
|
output_directory: stringType().optional().describe("\u8F93\u51FA\u76EE\u5F55\uFF0C\u4E0D\u6307\u5B9A\u5219\u5728\u539F\u6587\u4EF6\u76EE\u5F55\u751F\u6210")
|
|
8371
8728
|
});
|
|
8372
8729
|
const imageConverterTool = {
|
|
8373
|
-
name: "
|
|
8730
|
+
name: "image-converter",
|
|
8374
8731
|
description: "\u4E13\u4E1A\u56FE\u7247\u683C\u5F0F\u8F6C\u6362\u5DE5\u5177\uFF0C\u652F\u6301\u5355\u5F20\u548C\u6279\u91CF\u8F6C\u6362\uFF0C\u5305\u542B\u5C3A\u5BF8\u8C03\u6574\u548C\u8D28\u91CF\u63A7\u5236\u529F\u80FD",
|
|
8375
8732
|
inputSchema: {
|
|
8376
8733
|
input_paths: unionType([
|
|
@@ -8462,7 +8819,7 @@ ${results.map((r, index)=>`
|
|
|
8462
8819
|
- **\u{8F93}\u{51FA}**: \`${r.output_path}\`
|
|
8463
8820
|
- **\u{683C}\u{5F0F}**: ${r.format?.toUpperCase()}
|
|
8464
8821
|
- **\u{5C3A}\u{5BF8}**: ${r.dimensions?.width} \xd7 ${r.dimensions?.height}
|
|
8465
|
-
- **\u{6587}\u{4EF6}\u{5927}\u{5C0F}**: ${
|
|
8822
|
+
- **\u{6587}\u{4EF6}\u{5927}\u{5C0F}**: ${formatFileSize(r.file_size || 0)}
|
|
8466
8823
|
`).join("")}
|
|
8467
8824
|
|
|
8468
8825
|
${args.width || args.height ? `
|
|
@@ -8498,7 +8855,7 @@ ${successResults.map((r, index)=>`
|
|
|
8498
8855
|
${index + 1}. **${getFileName(r.input_path)}**
|
|
8499
8856
|
- \u{8F93}\u{51FA}: \`${r.output_path}\`
|
|
8500
8857
|
- \u{5C3A}\u{5BF8}: ${r.dimensions?.width} \xd7 ${r.dimensions?.height}
|
|
8501
|
-
- \u{5927}\u{5C0F}: ${
|
|
8858
|
+
- \u{5927}\u{5C0F}: ${formatFileSize(r.file_size || 0)}
|
|
8502
8859
|
`).join("")}
|
|
8503
8860
|
|
|
8504
8861
|
## \u{274C} \u{8F6C}\u{6362}\u{5931}\u{8D25} (${failedResults.length}\u{5F20})
|
|
@@ -8565,7 +8922,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
8565
8922
|
function getFileName(filePath) {
|
|
8566
8923
|
return filePath.split("/").pop() || filePath;
|
|
8567
8924
|
}
|
|
8568
|
-
function
|
|
8925
|
+
function formatFileSize(bytes) {
|
|
8569
8926
|
if (0 === bytes) return "0 B";
|
|
8570
8927
|
const k = 1024;
|
|
8571
8928
|
const sizes = [
|
|
@@ -8636,6 +8993,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
8636
8993
|
RETRY_DELAY_MS: 1000
|
|
8637
8994
|
};
|
|
8638
8995
|
const ImageRecognitionParamsSchema = objectType({
|
|
8996
|
+
projectPath: stringType().min(1).describe("\u5F53\u524D\u9879\u76EE\u8DEF\u5F84\uFF0C\u8BC6\u522B\u7ED3\u679C\u5C06\u4FDD\u5B58\u5230\u8BE5\u8DEF\u5F84\u4E0B\u7684.aico/image-recognition\u76EE\u5F55"),
|
|
8639
8997
|
imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
8640
8998
|
context: stringType().optional().describe("\u4E0A\u4E0B\u6587\u5185\u5BB9\uFF0C\u7528\u4E8E\u6307\u5BFC\u56FE\u7247\u5206\u6790\u7684\u65B9\u5411\u548C\u8303\u56F4")
|
|
8641
8999
|
});
|
|
@@ -9043,8 +9401,8 @@ ${getErrorSuggestion(error.code)}
|
|
|
9043
9401
|
}
|
|
9044
9402
|
class analyzer_ImageAnalyzer {
|
|
9045
9403
|
context;
|
|
9046
|
-
async
|
|
9047
|
-
logger.info("ImageAnalyzer: \u5F00\u59CB\u5206\u6790\u957F\u56FE", {
|
|
9404
|
+
async analyzeLongImageStreaming(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference = 'auto', context, onSegmentComplete) {
|
|
9405
|
+
logger.info("ImageAnalyzer: \u5F00\u59CB\u6D41\u5F0F\u5206\u6790\u957F\u56FE", {
|
|
9048
9406
|
imagePath,
|
|
9049
9407
|
totalSegments: segmentConfig.totalSegments,
|
|
9050
9408
|
maxConcurrency: concurrencyConfig.maxConcurrency,
|
|
@@ -9054,24 +9412,36 @@ ${getErrorSuggestion(error.code)}
|
|
|
9054
9412
|
const startTime = Date.now();
|
|
9055
9413
|
const segmentResults = [];
|
|
9056
9414
|
try {
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
const
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9415
|
+
const segments = await this.generateSegments(imagePath, imageInfo, segmentConfig);
|
|
9416
|
+
for(let i = 0; i < segments.length; i++){
|
|
9417
|
+
const { buffer, info } = segments[i];
|
|
9418
|
+
try {
|
|
9419
|
+
const result = await this.analyzeSegment(buffer, info, apiPreference);
|
|
9420
|
+
segmentResults.push(result);
|
|
9421
|
+
if (onSegmentComplete) await onSegmentComplete(result, {
|
|
9422
|
+
current: i + 1,
|
|
9423
|
+
total: segments.length
|
|
9424
|
+
});
|
|
9425
|
+
} catch (error) {
|
|
9426
|
+
logger.error(`\u{6BB5}\u{843D} ${info.index} \u{5206}\u{6790}\u{5931}\u{8D25}`, {
|
|
9427
|
+
error
|
|
9428
|
+
});
|
|
9429
|
+
const errorResult = {
|
|
9430
|
+
segmentIndex: info.index,
|
|
9431
|
+
textContent: '',
|
|
9432
|
+
imageDescription: '',
|
|
9433
|
+
confidence: 0,
|
|
9434
|
+
processingTimeMs: 0,
|
|
9435
|
+
apiUsed: 'none',
|
|
9436
|
+
error: error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"
|
|
9437
|
+
};
|
|
9438
|
+
segmentResults.push(errorResult);
|
|
9439
|
+
if (onSegmentComplete) await onSegmentComplete(errorResult, {
|
|
9440
|
+
current: i + 1,
|
|
9441
|
+
total: segments.length
|
|
9442
|
+
});
|
|
9443
|
+
}
|
|
9444
|
+
}
|
|
9075
9445
|
const summary = this.generateProcessingSummary(segmentResults, startTime);
|
|
9076
9446
|
const result = {
|
|
9077
9447
|
imageInfo,
|
|
@@ -9080,7 +9450,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9080
9450
|
outputPath: '',
|
|
9081
9451
|
success: 0 === summary.failedSegments
|
|
9082
9452
|
};
|
|
9083
|
-
logger.info("\u957F\u56FE\u5206\u6790\u5B8C\u6210", {
|
|
9453
|
+
logger.info("\u957F\u56FE\u6D41\u5F0F\u5206\u6790\u5B8C\u6210", {
|
|
9084
9454
|
imagePath,
|
|
9085
9455
|
totalSegments: summary.totalSegments,
|
|
9086
9456
|
successfulSegments: summary.successfulSegments,
|
|
@@ -9089,7 +9459,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9089
9459
|
});
|
|
9090
9460
|
return result;
|
|
9091
9461
|
} catch (error) {
|
|
9092
|
-
logger.error("\u957F\u56FE\u5206\u6790\u5931\u8D25", {
|
|
9462
|
+
logger.error("\u957F\u56FE\u6D41\u5F0F\u5206\u6790\u5931\u8D25", {
|
|
9093
9463
|
imagePath,
|
|
9094
9464
|
error
|
|
9095
9465
|
});
|
|
@@ -9099,6 +9469,9 @@ ${getErrorSuggestion(error.code)}
|
|
|
9099
9469
|
});
|
|
9100
9470
|
}
|
|
9101
9471
|
}
|
|
9472
|
+
async analyzeLongImage(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference = 'auto', context) {
|
|
9473
|
+
return this.analyzeLongImageStreaming(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference, context);
|
|
9474
|
+
}
|
|
9102
9475
|
async processSegmentsConcurrently(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference) {
|
|
9103
9476
|
const results = [];
|
|
9104
9477
|
const { maxConcurrency, batchSize, delayBetweenBatches } = concurrencyConfig;
|
|
@@ -9278,7 +9651,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9278
9651
|
let prompt = '';
|
|
9279
9652
|
prompt = this.context ? `${this.context}
|
|
9280
9653
|
|
|
9281
|
-
|
|
9654
|
+
You must provide a complete and detailed description of all content in the image, including scenes, objects, text, colors, layout, relationships, and all other visible elements and details. Ensure the description is detailed enough so that subsequent text-based language models can fully understand the image content through text alone.
|
|
9282
9655
|
|
|
9283
9656
|
` : `\u{8BF7}\u{5BF9}\u{8FD9}\u{5F20}\u{56FE}\u{7247}\u{8FDB}\u{884C}\u{9AD8}\u{7CBE}\u{5EA6}OCR\u{6587}\u{5B57}\u{8BC6}\u{522B}\u{FF0C}\u{53EA}\u{8F93}\u{51FA}\u{56FE}\u{7247}\u{4E2D}\u{7684}\u{539F}\u{59CB}\u{6587}\u{5B57}\u{5185}\u{5BB9}\u{3002}
|
|
9284
9657
|
|
|
@@ -9296,7 +9669,10 @@ ${getErrorSuggestion(error.code)}
|
|
|
9296
9669
|
else prompt += `\u{8FD9}\u{662F}\u{56FE}\u{7247}\u{7684}\u{4E2D}\u{95F4}\u{90E8}\u{5206}\u{3002}`;
|
|
9297
9670
|
if (segmentInfo.hasOverlap) prompt += `\u{6CE8}\u{610F}\u{FF1A}\u{8FD9}\u{4E2A}\u{6BB5}\u{843D}\u{4E0E}\u{4E0A}\u{4E00}\u{6BB5}\u{6709}\u{91CD}\u{53E0}\u{533A}\u{57DF}\u{FF0C}\u{8BF7}\u{907F}\u{514D}\u{91CD}\u{590D}\u{8BC6}\u{522B}\u{76F8}\u{540C}\u{5185}\u{5BB9}\u{3002}`;
|
|
9298
9671
|
}
|
|
9299
|
-
prompt += `
|
|
9672
|
+
if (this.context) prompt += `
|
|
9673
|
+
|
|
9674
|
+
Always respond in Chinese-simplified. \u{8BF7}\u{786E}\u{4FDD}\u{63CF}\u{8FF0}\u{8DB3}\u{591F}\u{8BE6}\u{7EC6}\u{FF0C}\u{4F7F}\u{540E}\u{7EED}\u{7684}\u{7EAF}\u{6587}\u{672C}\u{8BED}\u{8A00}\u{6A21}\u{578B}\u{80FD}\u{591F}\u{5B8C}\u{5168}\u{7406}\u{89E3}\u{56FE}\u{7247}\u{5185}\u{5BB9}\u{3002}`;
|
|
9675
|
+
else prompt += `
|
|
9300
9676
|
|
|
9301
9677
|
\u{8BF7}\u{76F4}\u{63A5}\u{8F93}\u{51FA}\u{8BC6}\u{522B}\u{5230}\u{7684}\u{6587}\u{5B57}\u{5185}\u{5BB9}\u{FF0C}\u{4E0D}\u{8981}\u{6DFB}\u{52A0}\u{4EFB}\u{4F55}\u{683C}\u{5F0F}\u{6807}\u{8BB0}\u{3001}\u{8BF4}\u{660E}\u{6587}\u{5B57}\u{6216}\u{63CF}\u{8FF0}\u{6027}\u{5185}\u{5BB9}\u{3002}
|
|
9302
9678
|
\u{5982}\u{679C}\u{56FE}\u{7247}\u{4E2D}\u{6CA1}\u{6709}\u{6587}\u{5B57}\u{FF0C}\u{8BF7}\u{8F93}\u{51FA}"\u{65E0}\u{6587}\u{5B57}\u{5185}\u{5BB9}"\u{3002}`;
|
|
@@ -9402,11 +9778,13 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9402
9778
|
this.configCalculator = new ConfigCalculator();
|
|
9403
9779
|
this.analyzer = new analyzer_ImageAnalyzer();
|
|
9404
9780
|
}
|
|
9405
|
-
async processImage(imagePath, context) {
|
|
9781
|
+
async processImage(imagePath, projectPath, context, callbacks) {
|
|
9406
9782
|
const startTime = Date.now();
|
|
9407
9783
|
logger.info("ImageRecognitionProcessor: \u5F00\u59CB\u5904\u7406\u56FE\u7247", {
|
|
9408
9784
|
imagePath
|
|
9409
9785
|
});
|
|
9786
|
+
let outputPath = '';
|
|
9787
|
+
const segmentResults = [];
|
|
9410
9788
|
try {
|
|
9411
9789
|
await this.validateImageFile(imagePath);
|
|
9412
9790
|
const validation = await this.preprocessor.validateImage(imagePath);
|
|
@@ -9428,55 +9806,51 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9428
9806
|
segmentHeight: segmentConfig.segmentHeight,
|
|
9429
9807
|
maxConcurrency: concurrencyConfig.maxConcurrency
|
|
9430
9808
|
});
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
const totalTime = Date.now() - startTime;
|
|
9434
|
-
logger.info("\u56FE\u7247\u5904\u7406\u5B8C\u6210", {
|
|
9809
|
+
outputPath = await this.initializeOutputFile(imageInfo, segmentConfig.totalSegments, projectPath);
|
|
9810
|
+
callbacks?.onStart?.({
|
|
9435
9811
|
outputPath,
|
|
9812
|
+
totalSegments: segmentConfig.totalSegments,
|
|
9813
|
+
imageInfo
|
|
9814
|
+
});
|
|
9815
|
+
const analysisResult = await this.analyzer.analyzeLongImageStreaming(imagePath, imageInfo, segmentConfig, concurrencyConfig, 'auto', context, async (result, progress)=>{
|
|
9816
|
+
segmentResults.push(result);
|
|
9817
|
+
await this.appendSegmentToFile(outputPath, result);
|
|
9818
|
+
callbacks?.onSegmentComplete?.(result, progress);
|
|
9819
|
+
});
|
|
9820
|
+
await this.finalizeOutputFile(outputPath, analysisResult.summary);
|
|
9821
|
+
const totalTime = Date.now() - startTime;
|
|
9822
|
+
const summary = {
|
|
9436
9823
|
totalSegments: analysisResult.summary.totalSegments,
|
|
9437
9824
|
successfulSegments: analysisResult.summary.successfulSegments,
|
|
9825
|
+
failedSegments: analysisResult.summary.failedSegments,
|
|
9826
|
+
successRate: analysisResult.summary.successRate,
|
|
9827
|
+
totalTextCharacters: analysisResult.summary.totalTextCharacters,
|
|
9828
|
+
totalProcessingTimeMs: totalTime,
|
|
9829
|
+
averageConfidence: analysisResult.summary.averageConfidence
|
|
9830
|
+
};
|
|
9831
|
+
callbacks?.onComplete?.(analysisResult.summary);
|
|
9832
|
+
logger.info("\u56FE\u7247\u5904\u7406\u5B8C\u6210", {
|
|
9833
|
+
outputPath,
|
|
9834
|
+
totalSegments: summary.totalSegments,
|
|
9835
|
+
successfulSegments: summary.successfulSegments,
|
|
9438
9836
|
totalTimeMs: totalTime
|
|
9439
9837
|
});
|
|
9440
9838
|
return {
|
|
9441
9839
|
outputPath,
|
|
9442
|
-
summary
|
|
9443
|
-
totalSegments: analysisResult.summary.totalSegments,
|
|
9444
|
-
successfulSegments: analysisResult.summary.successfulSegments,
|
|
9445
|
-
failedSegments: analysisResult.summary.failedSegments,
|
|
9446
|
-
successRate: analysisResult.summary.successRate,
|
|
9447
|
-
totalTextCharacters: analysisResult.summary.totalTextCharacters,
|
|
9448
|
-
totalProcessingTimeMs: totalTime,
|
|
9449
|
-
averageConfidence: analysisResult.summary.averageConfidence
|
|
9450
|
-
}
|
|
9840
|
+
summary
|
|
9451
9841
|
};
|
|
9452
9842
|
} catch (error) {
|
|
9453
9843
|
logger.error("\u56FE\u7247\u5904\u7406\u5931\u8D25", {
|
|
9454
9844
|
imagePath,
|
|
9455
9845
|
error
|
|
9456
9846
|
});
|
|
9847
|
+
callbacks?.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
9457
9848
|
throw error;
|
|
9458
9849
|
}
|
|
9459
9850
|
}
|
|
9460
|
-
async
|
|
9461
|
-
try {
|
|
9462
|
-
const stats = await external_fs_namespaceObject.promises.stat(imagePath);
|
|
9463
|
-
if (!stats.isFile()) throw new ImageRecognitionError("\u63D0\u4F9B\u7684\u8DEF\u5F84\u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6", types_ErrorTypes.FILE_NOT_FOUND, {
|
|
9464
|
-
imagePath
|
|
9465
|
-
});
|
|
9466
|
-
} catch (error) {
|
|
9467
|
-
if ('ENOENT' === error.code) throw new ImageRecognitionError("\u56FE\u7247\u6587\u4EF6\u4E0D\u5B58\u5728", types_ErrorTypes.FILE_NOT_FOUND, {
|
|
9468
|
-
imagePath
|
|
9469
|
-
});
|
|
9470
|
-
throw new ImageRecognitionError(`\u{6587}\u{4EF6}\u{8BBF}\u{95EE}\u{9519}\u{8BEF}: ${error.message}`, types_ErrorTypes.VALIDATION_ERROR, {
|
|
9471
|
-
imagePath,
|
|
9472
|
-
originalError: error
|
|
9473
|
-
});
|
|
9474
|
-
}
|
|
9475
|
-
}
|
|
9476
|
-
async generateSingleOutputFile(imageInfo, segmentResults, summary) {
|
|
9477
|
-
const baseDir = getStorageDir();
|
|
9851
|
+
async initializeOutputFile(imageInfo, totalSegments, projectPath) {
|
|
9478
9852
|
const dateDir = new Date().toISOString().split('T')[0];
|
|
9479
|
-
const outputDirectory = external_path_namespaceObject.join(
|
|
9853
|
+
const outputDirectory = external_path_namespaceObject.join(projectPath, '.aico', 'image-recognition', dateDir);
|
|
9480
9854
|
await external_fs_namespaceObject.promises.mkdir(outputDirectory, {
|
|
9481
9855
|
recursive: true
|
|
9482
9856
|
});
|
|
@@ -9484,39 +9858,78 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9484
9858
|
const imageBaseName = external_path_namespaceObject.basename(imageInfo.fileName, external_path_namespaceObject.extname(imageInfo.fileName));
|
|
9485
9859
|
const fileName = `${imageBaseName}-${timestamp}.md`;
|
|
9486
9860
|
const outputPath = external_path_namespaceObject.join(outputDirectory, fileName);
|
|
9487
|
-
const
|
|
9488
|
-
const content = `# ${imageInfo.fileName} - \u{56FE}\u{7247}\u{6587}\u{5B57}\u{8BC6}\u{522B}\u{7ED3}\u{679C}
|
|
9861
|
+
const header = `# ${imageInfo.fileName} - \u{56FE}\u{7247}\u{6587}\u{5B57}\u{8BC6}\u{522B}\u{7ED3}\u{679C}
|
|
9489
9862
|
|
|
9490
9863
|
**\u{8BC6}\u{522B}\u{65F6}\u{95F4}**: ${new Date().toLocaleString('zh-CN')}
|
|
9491
9864
|
**\u{56FE}\u{7247}\u{5C3A}\u{5BF8}**: ${imageInfo.width} \xd7 ${imageInfo.height} \u{50CF}\u{7D20}
|
|
9492
|
-
**\u{
|
|
9493
|
-
**\u{
|
|
9494
|
-
**\u{6587}\u{5B57}\u{5B57}\u{7B26}\u{603B}\u{6570}**: ${summary.totalTextCharacters.toLocaleString()}
|
|
9495
|
-
**\u{5E73}\u{5747}\u{7F6E}\u{4FE1}\u{5EA6}**: ${(100 * summary.averageConfidence).toFixed(1)}%
|
|
9865
|
+
**\u{9884}\u{8BA1}\u{6BB5}\u{6570}**: ${totalSegments}
|
|
9866
|
+
**\u{72B6}\u{6001}**: \u{1F504} \u{8BC6}\u{522B}\u{4E2D}...
|
|
9496
9867
|
|
|
9497
9868
|
---
|
|
9498
9869
|
|
|
9499
9870
|
## \u{8BC6}\u{522B}\u{7684}\u{6587}\u{5B57}\u{5185}\u{5BB9}
|
|
9500
9871
|
|
|
9501
|
-
${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
|
|
9502
|
-
|
|
9503
|
-
---
|
|
9504
|
-
|
|
9505
|
-
**\u{8BC6}\u{522B}\u{5B8C}\u{6210}\u{65F6}\u{95F4}**: ${new Date().toLocaleString('zh-CN')}
|
|
9506
9872
|
`;
|
|
9507
|
-
await external_fs_namespaceObject.promises.writeFile(outputPath,
|
|
9508
|
-
logger.info("\u8F93\u51FA\u6587\u4EF6\
|
|
9873
|
+
await external_fs_namespaceObject.promises.writeFile(outputPath, header, 'utf8');
|
|
9874
|
+
logger.info("\u8F93\u51FA\u6587\u4EF6\u521D\u59CB\u5316\u5B8C\u6210", {
|
|
9509
9875
|
outputPath,
|
|
9510
|
-
|
|
9511
|
-
contentLength: content.length
|
|
9876
|
+
totalSegments
|
|
9512
9877
|
});
|
|
9513
9878
|
return outputPath;
|
|
9514
9879
|
}
|
|
9880
|
+
async appendSegmentToFile(outputPath, result) {
|
|
9881
|
+
let content = '';
|
|
9882
|
+
if (result.error) content = `<!-- \u{6BB5}\u{843D} ${result.segmentIndex + 1} \u{5904}\u{7406}\u{5931}\u{8D25}: ${result.error} -->\n\n`;
|
|
9883
|
+
else if (result.textContent && result.textContent.trim()) content = `${result.textContent.trim()}\n\n`;
|
|
9884
|
+
if (content) await external_fs_namespaceObject.promises.appendFile(outputPath, content, 'utf8');
|
|
9885
|
+
}
|
|
9886
|
+
async finalizeOutputFile(outputPath, summary) {
|
|
9887
|
+
const footer = `
|
|
9888
|
+
---
|
|
9889
|
+
|
|
9890
|
+
## \u{5904}\u{7406}\u{6458}\u{8981}
|
|
9891
|
+
|
|
9892
|
+
- **\u{603B}\u{6BB5}\u{6570}**: ${summary.totalSegments}
|
|
9893
|
+
- **\u{6210}\u{529F}\u{6BB5}\u{6570}**: ${summary.successfulSegments}
|
|
9894
|
+
- **\u{5931}\u{8D25}\u{6BB5}\u{6570}**: ${summary.failedSegments}
|
|
9895
|
+
- **\u{6210}\u{529F}\u{7387}**: ${(100 * summary.successRate).toFixed(1)}%
|
|
9896
|
+
- **\u{6587}\u{5B57}\u{5B57}\u{7B26}\u{603B}\u{6570}**: ${summary.totalTextCharacters.toLocaleString()}
|
|
9897
|
+
- **\u{5E73}\u{5747}\u{7F6E}\u{4FE1}\u{5EA6}**: ${(100 * summary.averageConfidence).toFixed(1)}%
|
|
9898
|
+
- **\u{5904}\u{7406}\u{8017}\u{65F6}**: ${(summary.totalProcessingTimeMs / 1000).toFixed(2)}\u{79D2}
|
|
9899
|
+
|
|
9900
|
+
**\u{72B6}\u{6001}**: \u{2705} \u{8BC6}\u{522B}\u{5B8C}\u{6210}
|
|
9901
|
+
**\u{5B8C}\u{6210}\u{65F6}\u{95F4}**: ${new Date().toLocaleString('zh-CN')}
|
|
9902
|
+
`;
|
|
9903
|
+
await external_fs_namespaceObject.promises.appendFile(outputPath, footer, 'utf8');
|
|
9904
|
+
const content = await external_fs_namespaceObject.promises.readFile(outputPath, 'utf8');
|
|
9905
|
+
const updatedContent = content.replace("**\u72B6\u6001**: \uD83D\uDD04 \u8BC6\u522B\u4E2D...", "**\u72B6\u6001**: \u2705 \u8BC6\u522B\u5B8C\u6210");
|
|
9906
|
+
await external_fs_namespaceObject.promises.writeFile(outputPath, updatedContent, 'utf8');
|
|
9907
|
+
logger.info("\u8F93\u51FA\u6587\u4EF6\u5B8C\u6210", {
|
|
9908
|
+
outputPath
|
|
9909
|
+
});
|
|
9910
|
+
}
|
|
9911
|
+
async validateImageFile(imagePath) {
|
|
9912
|
+
try {
|
|
9913
|
+
const stats = await external_fs_namespaceObject.promises.stat(imagePath);
|
|
9914
|
+
if (!stats.isFile()) throw new ImageRecognitionError("\u63D0\u4F9B\u7684\u8DEF\u5F84\u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6587\u4EF6", types_ErrorTypes.FILE_NOT_FOUND, {
|
|
9915
|
+
imagePath
|
|
9916
|
+
});
|
|
9917
|
+
} catch (error) {
|
|
9918
|
+
if ('ENOENT' === error.code) throw new ImageRecognitionError("\u56FE\u7247\u6587\u4EF6\u4E0D\u5B58\u5728", types_ErrorTypes.FILE_NOT_FOUND, {
|
|
9919
|
+
imagePath
|
|
9920
|
+
});
|
|
9921
|
+
throw new ImageRecognitionError(`\u{6587}\u{4EF6}\u{8BBF}\u{95EE}\u{9519}\u{8BEF}: ${error.message}`, types_ErrorTypes.VALIDATION_ERROR, {
|
|
9922
|
+
imagePath,
|
|
9923
|
+
originalError: error
|
|
9924
|
+
});
|
|
9925
|
+
}
|
|
9926
|
+
}
|
|
9515
9927
|
}
|
|
9516
9928
|
const imageRecognitionAgentTool = {
|
|
9517
9929
|
name: "analyzeLongImage",
|
|
9518
|
-
description: "\u4E13\u95E8\u5904\u7406\u957F\u56FE\u7684\u5185\u5BB9\u8BC6\u522B\u667A\u80FD\u4F53\uFF0C\u652F\u6301\u5206\u6BB5\u5904\u7406\u548C\
|
|
9930
|
+
description: "\u4E13\u95E8\u5904\u7406\u957F\u56FE\u7684\u5185\u5BB9\u8BC6\u522B\u667A\u80FD\u4F53\uFF0C\u652F\u6301\u5206\u6BB5\u5904\u7406\u548C\u6D41\u5F0F\u8F93\u51FA\u3002\u8BC6\u522B\u7ED3\u679C\u5B9E\u65F6\u5199\u5165Markdown\u6587\u4EF6\uFF0C\u53EF\u8FB9\u5904\u7406\u8FB9\u67E5\u770B\u3002\u8FD4\u56DE\u7ED3\u679C\u5305\u542B\u6587\u4EF6\u8DEF\u5F84\u548C\u5B8C\u6574\u8BC6\u522B\u5185\u5BB9\u3002",
|
|
9519
9931
|
inputSchema: {
|
|
9932
|
+
projectPath: stringType().min(1).describe("\u5F53\u524D\u9879\u76EE\u8DEF\u5F84\uFF0C\u8BC6\u522B\u7ED3\u679C\u5C06\u4FDD\u5B58\u5230\u8BE5\u8DEF\u5F84\u4E0B\u7684.aico/image-recognition\u76EE\u5F55"),
|
|
9520
9933
|
imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
9521
9934
|
context: stringType().optional().describe("\u4E0A\u4E0B\u6587\u5185\u5BB9\uFF0C\u7528\u4E8E\u6307\u5BFC\u56FE\u7247\u5206\u6790\u7684\u65B9\u5411\u548C\u8303\u56F4")
|
|
9522
9935
|
},
|
|
@@ -9526,13 +9939,21 @@ ${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
|
|
|
9526
9939
|
args
|
|
9527
9940
|
});
|
|
9528
9941
|
try {
|
|
9529
|
-
const { imagePath, context } = ImageRecognitionParamsSchema.parse(args);
|
|
9942
|
+
const { projectPath, imagePath, context } = ImageRecognitionParamsSchema.parse(args);
|
|
9530
9943
|
const processor = new ImageRecognitionProcessor();
|
|
9531
|
-
const result = await processor.processImage(imagePath, context);
|
|
9944
|
+
const result = await processor.processImage(imagePath, projectPath, context);
|
|
9532
9945
|
logger.info("\u56FE\u7247\u5185\u5BB9\u8BC6\u522B\u667A\u80FD\u4F53: \u5904\u7406\u5B8C\u6210", {
|
|
9533
9946
|
outputPath: result.outputPath,
|
|
9534
9947
|
summary: result.summary
|
|
9535
9948
|
});
|
|
9949
|
+
let fileContent = '';
|
|
9950
|
+
try {
|
|
9951
|
+
fileContent = await external_fs_namespaceObject.promises.readFile(result.outputPath, 'utf8');
|
|
9952
|
+
} catch (readError) {
|
|
9953
|
+
logger.warn("\u8BFB\u53D6\u7ED3\u679C\u6587\u4EF6\u5931\u8D25", {
|
|
9954
|
+
error: readError
|
|
9955
|
+
});
|
|
9956
|
+
}
|
|
9536
9957
|
return {
|
|
9537
9958
|
content: [
|
|
9538
9959
|
{
|
|
@@ -9547,10 +9968,14 @@ ${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
|
|
|
9547
9968
|
- \u{5E73}\u{5747}\u{7F6E}\u{4FE1}\u{5EA6}: ${(100 * result.summary.averageConfidence).toFixed(1)}%
|
|
9548
9969
|
- \u{5904}\u{7406}\u{8017}\u{65F6}: ${(result.summary.totalProcessingTimeMs / 1000).toFixed(2)}\u{79D2}
|
|
9549
9970
|
|
|
9550
|
-
\u{1F4C4} **\u{7ED3}\u{679C}\u{6587}\u{4EF6}**:
|
|
9971
|
+
\u{1F4C4} **\u{7ED3}\u{679C}\u{6587}\u{4EF6}\u{8DEF}\u{5F84}**:
|
|
9551
9972
|
\`${result.outputPath}\`
|
|
9552
9973
|
|
|
9553
|
-
|
|
9974
|
+
---
|
|
9975
|
+
|
|
9976
|
+
## \u{8BC6}\u{522B}\u{7684}\u{5B8C}\u{6574}\u{5185}\u{5BB9}
|
|
9977
|
+
|
|
9978
|
+
${fileContent}`
|
|
9554
9979
|
}
|
|
9555
9980
|
]
|
|
9556
9981
|
};
|
|
@@ -10503,6 +10928,264 @@ ${requirement_description}
|
|
|
10503
10928
|
}
|
|
10504
10929
|
}
|
|
10505
10930
|
};
|
|
10931
|
+
const external_url_namespaceObject = require("url");
|
|
10932
|
+
const external_docxtemplater_namespaceObject = require("docxtemplater");
|
|
10933
|
+
var external_docxtemplater_default = /*#__PURE__*/ __webpack_require__.n(external_docxtemplater_namespaceObject);
|
|
10934
|
+
const external_pizzip_namespaceObject = require("pizzip");
|
|
10935
|
+
var external_pizzip_default = /*#__PURE__*/ __webpack_require__.n(external_pizzip_namespaceObject);
|
|
10936
|
+
function getTemplatePath() {
|
|
10937
|
+
let currentDir;
|
|
10938
|
+
try {
|
|
10939
|
+
currentDir = external_path_namespaceObject.dirname((0, external_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__));
|
|
10940
|
+
} catch {
|
|
10941
|
+
currentDir = __dirname;
|
|
10942
|
+
}
|
|
10943
|
+
return external_path_namespaceObject.resolve(currentDir, "\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u6A21\u677F.docx");
|
|
10944
|
+
}
|
|
10945
|
+
async function renderTechSpecDoc(data, outputDir) {
|
|
10946
|
+
try {
|
|
10947
|
+
const templatePath = getTemplatePath();
|
|
10948
|
+
try {
|
|
10949
|
+
await promises_namespaceObject.access(templatePath);
|
|
10950
|
+
} catch {
|
|
10951
|
+
return {
|
|
10952
|
+
success: false,
|
|
10953
|
+
outputPath: null,
|
|
10954
|
+
error: `\u{6A21}\u{677F}\u{6587}\u{4EF6}\u{4E0D}\u{5B58}\u{5728}: ${templatePath}`
|
|
10955
|
+
};
|
|
10956
|
+
}
|
|
10957
|
+
const templateContent = await promises_namespaceObject.readFile(templatePath);
|
|
10958
|
+
const zip = new (external_pizzip_default())(templateContent);
|
|
10959
|
+
const doc = new (external_docxtemplater_default())(zip, {
|
|
10960
|
+
paragraphLoop: true,
|
|
10961
|
+
linebreaks: true,
|
|
10962
|
+
delimiters: {
|
|
10963
|
+
start: '{',
|
|
10964
|
+
end: '}'
|
|
10965
|
+
}
|
|
10966
|
+
});
|
|
10967
|
+
doc.render(data);
|
|
10968
|
+
const output = doc.getZip().generate({
|
|
10969
|
+
type: 'nodebuffer',
|
|
10970
|
+
compression: 'DEFLATE'
|
|
10971
|
+
});
|
|
10972
|
+
await promises_namespaceObject.mkdir(outputDir, {
|
|
10973
|
+
recursive: true
|
|
10974
|
+
});
|
|
10975
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
10976
|
+
const outputFileName = `\u{6280}\u{672F}\u{89C4}\u{683C}\u{8BF4}\u{660E}\u{4E66}_${data.projectName}_${data.moduleName}_${timestamp}.docx`;
|
|
10977
|
+
const outputPath = external_path_namespaceObject.join(outputDir, outputFileName);
|
|
10978
|
+
await promises_namespaceObject.writeFile(outputPath, output);
|
|
10979
|
+
logger.info("\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u751F\u6210\u6210\u529F", {
|
|
10980
|
+
outputPath
|
|
10981
|
+
});
|
|
10982
|
+
return {
|
|
10983
|
+
success: true,
|
|
10984
|
+
outputPath
|
|
10985
|
+
};
|
|
10986
|
+
} catch (error) {
|
|
10987
|
+
logger.error("\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u751F\u6210\u5931\u8D25", {
|
|
10988
|
+
error: error.message
|
|
10989
|
+
});
|
|
10990
|
+
if (error.properties && error.properties.errors) {
|
|
10991
|
+
const errorMessages = error.properties.errors.map((e)=>e.properties?.explanation || e.message).join('; ');
|
|
10992
|
+
return {
|
|
10993
|
+
success: false,
|
|
10994
|
+
outputPath: null,
|
|
10995
|
+
error: `\u{6A21}\u{677F}\u{6E32}\u{67D3}\u{9519}\u{8BEF}: ${errorMessages}`
|
|
10996
|
+
};
|
|
10997
|
+
}
|
|
10998
|
+
return {
|
|
10999
|
+
success: false,
|
|
11000
|
+
outputPath: null,
|
|
11001
|
+
error: error.message || "\u672A\u77E5\u9519\u8BEF"
|
|
11002
|
+
};
|
|
11003
|
+
}
|
|
11004
|
+
}
|
|
11005
|
+
const TableFieldDetailSchema = objectType({
|
|
11006
|
+
id: stringType().describe("\u5E8F\u53F7"),
|
|
11007
|
+
fieldName: stringType().describe("\u5B57\u6BB5\u540D"),
|
|
11008
|
+
fieldType: stringType().describe("\u5B57\u6BB5\u7C7B\u578B"),
|
|
11009
|
+
fieldDescription: stringType().describe("\u5B57\u6BB5\u63CF\u8FF0"),
|
|
11010
|
+
fieldLength: stringType().describe("\u5B57\u6BB5\u957F\u5EA6")
|
|
11011
|
+
});
|
|
11012
|
+
const TableInfoSchema = objectType({
|
|
11013
|
+
id: stringType().describe("\u5E8F\u53F7"),
|
|
11014
|
+
tableName: stringType().describe("\u8868\u540D\u79F0"),
|
|
11015
|
+
entityName: stringType().describe("\u5BF9\u5E94\u5B9E\u4F53\u540D\u79F0"),
|
|
11016
|
+
tableDescription: stringType().describe("\u63CF\u8FF0"),
|
|
11017
|
+
tableDetailList: arrayType(TableFieldDetailSchema).default([]).describe("\u8868\u5B57\u6BB5\u8BE6\u60C5\u5217\u8868")
|
|
11018
|
+
});
|
|
11019
|
+
const ParameterInfoSchema = objectType({
|
|
11020
|
+
id: stringType().describe("\u5E8F\u53F7"),
|
|
11021
|
+
propertyType: stringType().describe("\u7C7B\u578B"),
|
|
11022
|
+
propertyName: stringType().describe("\u5C5E\u6027\u540D"),
|
|
11023
|
+
required: stringType().describe("\u662F\u5426\u5FC5\u586B"),
|
|
11024
|
+
propertyDesc: stringType().describe("\u63CF\u8FF0")
|
|
11025
|
+
});
|
|
11026
|
+
const ReturnResultInfoSchema = objectType({
|
|
11027
|
+
id: stringType().describe("\u5E8F\u53F7"),
|
|
11028
|
+
propertyType: stringType().describe("\u7C7B\u578B"),
|
|
11029
|
+
propertyName: stringType().describe("\u5C5E\u6027\u540D"),
|
|
11030
|
+
propertyDesc: stringType().describe("\u63CF\u8FF0")
|
|
11031
|
+
});
|
|
11032
|
+
const InterfaceDesignDetailSchema = objectType({
|
|
11033
|
+
functionName: stringType().describe("\u529F\u80FD\u540D\u79F0"),
|
|
11034
|
+
interfaceDesc: stringType().describe("\u63A5\u53E3\u63CF\u8FF0"),
|
|
11035
|
+
className: stringType().describe("\u63A5\u53E3\u7C7B\u540D"),
|
|
11036
|
+
methodName: stringType().describe("\u65B9\u6CD5\u540D"),
|
|
11037
|
+
parameterList: arrayType(ParameterInfoSchema).default([]).describe("\u53C2\u6570\u5217\u8868"),
|
|
11038
|
+
returnResultList: arrayType(ReturnResultInfoSchema).default([]).describe("\u8FD4\u56DE\u7ED3\u679C\u5217\u8868"),
|
|
11039
|
+
implementLogic: stringType().describe("\u5B9E\u73B0\u903B\u8F91")
|
|
11040
|
+
});
|
|
11041
|
+
const DesignDetailSchema = objectType({
|
|
11042
|
+
serviceName: stringType().describe("\u670D\u52A1\u540D\u79F0"),
|
|
11043
|
+
serviceDesc: stringType().describe("\u529F\u80FD\u63CF\u8FF0"),
|
|
11044
|
+
interfaceDesignDetailList: arrayType(InterfaceDesignDetailSchema).default([]).describe("\u63A5\u53E3\u8BBE\u8BA1\u8BE6\u60C5\u5217\u8868")
|
|
11045
|
+
});
|
|
11046
|
+
const InterfaceDetailSchema = objectType({
|
|
11047
|
+
id: stringType().describe("\u5E8F\u53F7"),
|
|
11048
|
+
functionDescription: stringType().describe("\u529F\u80FD\u63CF\u8FF0"),
|
|
11049
|
+
serviceName: stringType().describe("\u670D\u52A1\u540D"),
|
|
11050
|
+
methodName: stringType().describe("\u65B9\u6CD5\u540D")
|
|
11051
|
+
});
|
|
11052
|
+
const ServiceInterfaceSchema = objectType({
|
|
11053
|
+
id: stringType().describe("\u5E8F\u53F7"),
|
|
11054
|
+
serviceType: stringType().describe("\u670D\u52A1\u7C7B\u578B"),
|
|
11055
|
+
serviceEnglishName: stringType().describe("\u670D\u52A1\u82F1\u6587\u540D\u79F0"),
|
|
11056
|
+
serviceChineseName: stringType().describe("\u670D\u52A1\u4E2D\u6587\u540D\u79F0"),
|
|
11057
|
+
serviceDescription: stringType().describe("\u670D\u52A1\u63CF\u8FF0"),
|
|
11058
|
+
interfaceDetailList: arrayType(InterfaceDetailSchema).default([]).describe("\u63A5\u53E3\u8BE6\u60C5\u5217\u8868")
|
|
11059
|
+
});
|
|
11060
|
+
const techSpecGeneratorTool = {
|
|
11061
|
+
name: 'tech-spec-generator',
|
|
11062
|
+
description: `\u{6280}\u{672F}\u{89C4}\u{683C}\u{8BF4}\u{660E}\u{4E66}\u{751F}\u{6210}\u{5DE5}\u{5177} - \u{6839}\u{636E}\u{6536}\u{96C6}\u{7684}\u{4EE3}\u{7801}\u{4FE1}\u{606F}\u{751F}\u{6210}\u{6280}\u{672F}\u{89C4}\u{683C}\u{8BF4}\u{660E}\u{4E66}\u{3002}
|
|
11063
|
+
|
|
11064
|
+
\u{4F7F}\u{7528}\u{6D41}\u{7A0B}\u{FF1A}
|
|
11065
|
+
1. MCP\u{5BA2}\u{6237}\u{7AEF}\u{5148}\u{8BFB}\u{53D6}\u{76EE}\u{6807}\u{4EE3}\u{7801}\u{76EE}\u{5F55}\u{FF0C}\u{5206}\u{6790}\u{5E76}\u{6536}\u{96C6}\u{4EE5}\u{4E0B}\u{4FE1}\u{606F}\u{FF1A}
|
|
11066
|
+
- \u{6570}\u{636E}\u{8868}\u{8BBE}\u{8BA1}\u{FF08}\u{8868}\u{540D}\u{3001}\u{5B57}\u{6BB5}\u{4FE1}\u{606F}\u{7B49}\u{FF09}
|
|
11067
|
+
- \u{670D}\u{52A1}\u{63A5}\u{53E3}\u{8BBE}\u{8BA1}\u{FF08}\u{670D}\u{52A1}\u{540D}\u{3001}\u{63A5}\u{53E3}\u{65B9}\u{6CD5}\u{3001}\u{53C2}\u{6570}\u{3001}\u{8FD4}\u{56DE}\u{503C}\u{7B49}\u{FF09}
|
|
11068
|
+
- \u{529F}\u{80FD}\u{8BBE}\u{8BA1}\u{8BE6}\u{60C5}\u{FF08}\u{529F}\u{80FD}\u{540D}\u{79F0}\u{3001}\u{63CF}\u{8FF0}\u{3001}\u{5B9E}\u{73B0}\u{903B}\u{8F91}\u{7B49}\u{FF09}
|
|
11069
|
+
2. \u{5C06}\u{6536}\u{96C6}\u{7684}\u{6570}\u{636E}\u{901A}\u{8FC7} techSpecData \u{53C2}\u{6570}\u{4F20}\u{9012}\u{7ED9}\u{8BE5}\u{5DE5}\u{5177}
|
|
11070
|
+
3. \u{5DE5}\u{5177}\u{4F7F}\u{7528} .aico/create-tect-docs/\u{6280}\u{672F}\u{89C4}\u{683C}\u{8BF4}\u{660E}\u{4E66}\u{6A21}\u{677F}.docx \u{6A21}\u{677F}\u{6E32}\u{67D3}\u{751F}\u{6210}\u{6587}\u{6863}
|
|
11071
|
+
4. \u{6587}\u{6863}\u{8F93}\u{51FA}\u{5230} projectPath/.aico/tect/ \u{76EE}\u{5F55}`,
|
|
11072
|
+
inputSchema: {
|
|
11073
|
+
projectPath: stringType().min(1).describe("\u5F53\u524D\u9879\u76EE\u8DEF\u5F84\uFF0C\u751F\u6210\u7684\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u4FDD\u5B58\u5230\u8BE5\u8DEF\u5F84\u4E0B\u7684.aico/tect\u76EE\u5F55"),
|
|
11074
|
+
techSpecData: objectType({
|
|
11075
|
+
projectName: stringType().describe("\u9879\u76EE\u540D\u79F0"),
|
|
11076
|
+
moduleName: stringType().describe("\u6A21\u5757\u540D\u79F0"),
|
|
11077
|
+
year: stringType().optional().describe("\u5E74\u4EFD\uFF0C\u9ED8\u8BA4\u5F53\u524D\u5E74\u4EFD"),
|
|
11078
|
+
month: stringType().optional().describe("\u6708\u4EFD\uFF0C\u9ED8\u8BA4\u5F53\u524D\u6708\u4EFD"),
|
|
11079
|
+
referDoc: stringType().optional().describe("\u53C2\u8003\u6587\u6863"),
|
|
11080
|
+
serviceInterfaceList: arrayType(ServiceInterfaceSchema).default([]).describe("\u670D\u52A1\u63A5\u53E3\u6E05\u5355"),
|
|
11081
|
+
designDetailList: arrayType(DesignDetailSchema).default([]).describe("\u670D\u52A1\u63A5\u53E3\u8BBE\u8BA1\u8BE6\u60C5"),
|
|
11082
|
+
tableInfoList: arrayType(TableInfoSchema).default([]).describe("\u6570\u636E\u5E93\u8868\u4FE1\u606F\u5217\u8868")
|
|
11083
|
+
}).describe("\u6280\u672F\u89C4\u683C\u6570\u636E\uFF0C\u7531MCP\u5BA2\u6237\u7AEF\u901A\u8FC7\u5206\u6790\u4EE3\u7801\u76EE\u5F55\u6536\u96C6")
|
|
11084
|
+
},
|
|
11085
|
+
handler: async (args)=>{
|
|
11086
|
+
try {
|
|
11087
|
+
const { projectPath, techSpecData } = args;
|
|
11088
|
+
if (!projectPath) return {
|
|
11089
|
+
content: [
|
|
11090
|
+
{
|
|
11091
|
+
type: 'text',
|
|
11092
|
+
text: JSON.stringify({
|
|
11093
|
+
success: false,
|
|
11094
|
+
message: "\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1AprojectPath",
|
|
11095
|
+
data: null
|
|
11096
|
+
})
|
|
11097
|
+
}
|
|
11098
|
+
],
|
|
11099
|
+
isError: true
|
|
11100
|
+
};
|
|
11101
|
+
if (!techSpecData) return {
|
|
11102
|
+
content: [
|
|
11103
|
+
{
|
|
11104
|
+
type: 'text',
|
|
11105
|
+
text: JSON.stringify({
|
|
11106
|
+
success: false,
|
|
11107
|
+
message: "\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1AtechSpecData",
|
|
11108
|
+
data: null
|
|
11109
|
+
})
|
|
11110
|
+
}
|
|
11111
|
+
],
|
|
11112
|
+
isError: true
|
|
11113
|
+
};
|
|
11114
|
+
const now = new Date();
|
|
11115
|
+
const data = {
|
|
11116
|
+
projectName: techSpecData.projectName || "\u672A\u547D\u540D\u9879\u76EE",
|
|
11117
|
+
moduleName: techSpecData.moduleName || "\u672A\u547D\u540D\u6A21\u5757",
|
|
11118
|
+
year: techSpecData.year || String(now.getFullYear()),
|
|
11119
|
+
month: techSpecData.month || String(now.getMonth() + 1).padStart(2, '0'),
|
|
11120
|
+
referDoc: techSpecData.referDoc || "\u65E0",
|
|
11121
|
+
serviceInterfaceList: techSpecData.serviceInterfaceList || [],
|
|
11122
|
+
designDetailList: techSpecData.designDetailList || [],
|
|
11123
|
+
tableInfoList: techSpecData.tableInfoList || []
|
|
11124
|
+
};
|
|
11125
|
+
const outputDir = external_path_namespaceObject.join(projectPath, '.aico', 'tect');
|
|
11126
|
+
logger.info("\u5F00\u59CB\u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66", {
|
|
11127
|
+
projectPath,
|
|
11128
|
+
outputDir,
|
|
11129
|
+
projectName: data.projectName,
|
|
11130
|
+
moduleName: data.moduleName,
|
|
11131
|
+
tableCount: data.tableInfoList.length,
|
|
11132
|
+
serviceCount: data.serviceInterfaceList.length
|
|
11133
|
+
});
|
|
11134
|
+
const result = await renderTechSpecDoc(data, outputDir);
|
|
11135
|
+
if (result.success) return {
|
|
11136
|
+
content: [
|
|
11137
|
+
{
|
|
11138
|
+
type: 'text',
|
|
11139
|
+
text: JSON.stringify({
|
|
11140
|
+
success: true,
|
|
11141
|
+
message: "\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u751F\u6210\u6210\u529F",
|
|
11142
|
+
data: {
|
|
11143
|
+
outputPath: result.outputPath,
|
|
11144
|
+
projectName: data.projectName,
|
|
11145
|
+
moduleName: data.moduleName,
|
|
11146
|
+
statistics: {
|
|
11147
|
+
tableCount: data.tableInfoList.length,
|
|
11148
|
+
serviceCount: data.serviceInterfaceList.length,
|
|
11149
|
+
designCount: data.designDetailList.length
|
|
11150
|
+
}
|
|
11151
|
+
}
|
|
11152
|
+
})
|
|
11153
|
+
}
|
|
11154
|
+
]
|
|
11155
|
+
};
|
|
11156
|
+
return {
|
|
11157
|
+
content: [
|
|
11158
|
+
{
|
|
11159
|
+
type: 'text',
|
|
11160
|
+
text: JSON.stringify({
|
|
11161
|
+
success: false,
|
|
11162
|
+
message: result.error || "\u6587\u6863\u751F\u6210\u5931\u8D25",
|
|
11163
|
+
data: null
|
|
11164
|
+
})
|
|
11165
|
+
}
|
|
11166
|
+
],
|
|
11167
|
+
isError: true
|
|
11168
|
+
};
|
|
11169
|
+
} catch (error) {
|
|
11170
|
+
logger.error("\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u751F\u6210\u5F02\u5E38", {
|
|
11171
|
+
error: error.message
|
|
11172
|
+
});
|
|
11173
|
+
return {
|
|
11174
|
+
content: [
|
|
11175
|
+
{
|
|
11176
|
+
type: 'text',
|
|
11177
|
+
text: JSON.stringify({
|
|
11178
|
+
success: false,
|
|
11179
|
+
message: error.message || "\u751F\u6210\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF",
|
|
11180
|
+
data: null
|
|
11181
|
+
})
|
|
11182
|
+
}
|
|
11183
|
+
],
|
|
11184
|
+
isError: true
|
|
11185
|
+
};
|
|
11186
|
+
}
|
|
11187
|
+
}
|
|
11188
|
+
};
|
|
10506
11189
|
function createMcpServer() {
|
|
10507
11190
|
const server = new mcp_js_namespaceObject.McpServer({
|
|
10508
11191
|
name: SERVICE_CONFIG.name,
|
|
@@ -10520,7 +11203,8 @@ ${requirement_description}
|
|
|
10520
11203
|
exportExcelTool,
|
|
10521
11204
|
requirementIdentifierTool,
|
|
10522
11205
|
requirementAlignerTool,
|
|
10523
|
-
taskExecutorTool
|
|
11206
|
+
taskExecutorTool,
|
|
11207
|
+
techSpecGeneratorTool
|
|
10524
11208
|
];
|
|
10525
11209
|
tools.forEach((tool)=>{
|
|
10526
11210
|
server.tool(tool.name, tool.description, tool.inputSchema, tool.handler);
|