intention-coding 0.5.9 → 0.6.0
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 +1069 -751
- 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/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 +2 -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/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/package.json +1 -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,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_modules__ = {
|
|
3
|
+
"fs/promises": function(module) {
|
|
4
|
+
module.exports = import("fs/promises").then(function(module) {
|
|
5
|
+
return module;
|
|
6
|
+
});
|
|
7
|
+
},
|
|
8
|
+
path: function(module) {
|
|
9
|
+
module.exports = import("path").then(function(module) {
|
|
10
|
+
return module;
|
|
11
|
+
});
|
|
12
|
+
},
|
|
3
13
|
"pdf-parse/lib/pdf-parse.js": function(module) {
|
|
4
14
|
module.exports = import("pdf-parse/lib/pdf-parse.js").then(function(module) {
|
|
5
15
|
return module;
|
|
@@ -60,18 +70,15 @@ var __webpack_exports__ = {};
|
|
|
60
70
|
var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
|
|
61
71
|
const external_winston_namespaceObject = require("winston");
|
|
62
72
|
var external_winston_default = /*#__PURE__*/ __webpack_require__.n(external_winston_namespaceObject);
|
|
63
|
-
const
|
|
64
|
-
var
|
|
65
|
-
|
|
73
|
+
const external_os_namespaceObject = require("os");
|
|
74
|
+
var external_os_default = /*#__PURE__*/ __webpack_require__.n(external_os_namespaceObject);
|
|
75
|
+
const isProduction = "production" === process.env.NODE_ENV || !process.env.npm_lifecycle_event;
|
|
76
|
+
const logDir = external_path_default().join(external_os_default().homedir(), ".aico", "logs");
|
|
66
77
|
try {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
} catch (error) {
|
|
73
|
-
logDir = process.env.TMPDIR || "/tmp/aico-logs";
|
|
74
|
-
}
|
|
78
|
+
external_fs_default().mkdirSync(logDir, {
|
|
79
|
+
recursive: true
|
|
80
|
+
});
|
|
81
|
+
} catch {}
|
|
75
82
|
const levels = {
|
|
76
83
|
error: 0,
|
|
77
84
|
warn: 1,
|
|
@@ -79,20 +86,6 @@ var __webpack_exports__ = {};
|
|
|
79
86
|
debug: 3,
|
|
80
87
|
verbose: 4
|
|
81
88
|
};
|
|
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
89
|
const fileFormat = external_winston_default().format.combine(external_winston_default().format.timestamp(), external_winston_default().format.errors({
|
|
97
90
|
stack: true
|
|
98
91
|
}), external_winston_default().format.json());
|
|
@@ -103,11 +96,11 @@ var __webpack_exports__ = {};
|
|
|
103
96
|
const error = meta.error || meta;
|
|
104
97
|
const errorInfo = {
|
|
105
98
|
timestamp,
|
|
106
|
-
level: level ||
|
|
107
|
-
message: message ||
|
|
108
|
-
stack: stack || error && error.stack ||
|
|
99
|
+
level: level || "error",
|
|
100
|
+
message: message || "Uncaught Exception",
|
|
101
|
+
stack: stack || error && error.stack || "No stack trace available",
|
|
109
102
|
error: {
|
|
110
|
-
name: error && error.name ||
|
|
103
|
+
name: error && error.name || "Error",
|
|
111
104
|
message: error && error.message || String(error || message),
|
|
112
105
|
code: error && error.code || meta.code,
|
|
113
106
|
...meta
|
|
@@ -115,50 +108,48 @@ var __webpack_exports__ = {};
|
|
|
115
108
|
};
|
|
116
109
|
return JSON.stringify(errorInfo, null, 2);
|
|
117
110
|
}));
|
|
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',
|
|
111
|
+
const transports = [];
|
|
112
|
+
transports.push(new (external_winston_default()).transports.File({
|
|
113
|
+
filename: external_path_default().join(logDir, "error.log"),
|
|
114
|
+
level: "error",
|
|
130
115
|
format: fileFormat,
|
|
131
|
-
|
|
116
|
+
maxsize: 5242880,
|
|
117
|
+
maxFiles: 1,
|
|
118
|
+
tailable: true
|
|
119
|
+
}));
|
|
120
|
+
if (!isProduction) transports.push(new (external_winston_default()).transports.File({
|
|
121
|
+
filename: external_path_default().join(logDir, "app.log"),
|
|
122
|
+
level: "info",
|
|
123
|
+
format: fileFormat,
|
|
124
|
+
maxsize: 5242880,
|
|
125
|
+
maxFiles: 1,
|
|
126
|
+
tailable: true
|
|
132
127
|
}));
|
|
133
128
|
const logger = external_winston_default().createLogger({
|
|
134
|
-
level:
|
|
129
|
+
level: isProduction ? "error" : "debug",
|
|
135
130
|
levels,
|
|
136
131
|
format: external_winston_default().format.combine(external_winston_default().format.errors({
|
|
137
132
|
stack: true
|
|
138
133
|
}), external_winston_default().format.splat()),
|
|
139
134
|
transports,
|
|
140
|
-
exceptionHandlers:
|
|
141
|
-
new (
|
|
142
|
-
filename: external_path_default().join(logDir,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
maxFiles: '1d',
|
|
147
|
-
format: exceptionFormat
|
|
135
|
+
exceptionHandlers: [
|
|
136
|
+
new (external_winston_default()).transports.File({
|
|
137
|
+
filename: external_path_default().join(logDir, "error.log"),
|
|
138
|
+
format: exceptionFormat,
|
|
139
|
+
maxsize: 5242880,
|
|
140
|
+
maxFiles: 1
|
|
148
141
|
})
|
|
149
|
-
]
|
|
150
|
-
rejectionHandlers:
|
|
151
|
-
new (
|
|
152
|
-
filename: external_path_default().join(logDir,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
maxFiles: '1d',
|
|
157
|
-
format: exceptionFormat
|
|
142
|
+
],
|
|
143
|
+
rejectionHandlers: [
|
|
144
|
+
new (external_winston_default()).transports.File({
|
|
145
|
+
filename: external_path_default().join(logDir, "error.log"),
|
|
146
|
+
format: exceptionFormat,
|
|
147
|
+
maxsize: 5242880,
|
|
148
|
+
maxFiles: 1
|
|
158
149
|
})
|
|
159
|
-
]
|
|
150
|
+
]
|
|
160
151
|
});
|
|
161
|
-
process.on(
|
|
152
|
+
process.on("SIGINT", ()=>{
|
|
162
153
|
logger.end(()=>{
|
|
163
154
|
logger.info("\u65E5\u5FD7\u5DF2\u5173\u95ED");
|
|
164
155
|
process.exit(0);
|
|
@@ -316,7 +307,6 @@ var __webpack_exports__ = {};
|
|
|
316
307
|
var external_mammoth_default = /*#__PURE__*/ __webpack_require__.n(external_mammoth_namespaceObject);
|
|
317
308
|
const external_html_to_md_namespaceObject = require("html-to-md");
|
|
318
309
|
var external_html_to_md_default = /*#__PURE__*/ __webpack_require__.n(external_html_to_md_namespaceObject);
|
|
319
|
-
const external_os_namespaceObject = require("os");
|
|
320
310
|
const sanitizeFileName = (input)=>input.replace(/[\\/:*?"<>|\n\r#%&]/g, '').trim().replace(/\s+/g, '_').replace(/_+/g, '_').replace(/^_+|_+$/g, '');
|
|
321
311
|
function normalizePath(filePath) {
|
|
322
312
|
if (!filePath || 'string' != typeof filePath) throw new Error("\u6587\u4EF6\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");
|
|
@@ -4199,6 +4189,207 @@ var __webpack_exports__ = {};
|
|
|
4199
4189
|
ErrorCodes["UNSUPPORTED_REQUIREMENT_TYPE"] = "UNSUPPORTED_REQUIREMENT_TYPE";
|
|
4200
4190
|
return ErrorCodes;
|
|
4201
4191
|
}({});
|
|
4192
|
+
async function invokeFlow(params, streamCb) {
|
|
4193
|
+
const { appid = "app-ESTcrkOPOmkxdrO0120mE4s1", data, timeout = 1800000 } = params;
|
|
4194
|
+
const controller = new AbortController();
|
|
4195
|
+
const signal = controller.signal;
|
|
4196
|
+
if ("undefined" == typeof ReadableStream) throw new Error("ReadableStream is not supported in this environment");
|
|
4197
|
+
const fetchData = async (retryCount = 0)=>{
|
|
4198
|
+
try {
|
|
4199
|
+
const fetchOptions = {
|
|
4200
|
+
method: "POST",
|
|
4201
|
+
headers: {
|
|
4202
|
+
Authorization: `Bearer ${appid}`,
|
|
4203
|
+
"Content-Type": "application/json"
|
|
4204
|
+
},
|
|
4205
|
+
body: JSON.stringify({
|
|
4206
|
+
inputs: data,
|
|
4207
|
+
response_mode: "streaming",
|
|
4208
|
+
user: "aico-mcp"
|
|
4209
|
+
}),
|
|
4210
|
+
signal
|
|
4211
|
+
};
|
|
4212
|
+
const res = await fetch("http://11.0.166.20:9199/v1/workflows/run", fetchOptions);
|
|
4213
|
+
if (!res.ok) {
|
|
4214
|
+
if (retryCount < 3) {
|
|
4215
|
+
await new Promise((resolve)=>setTimeout(resolve, 1000));
|
|
4216
|
+
return fetchData(retryCount + 1);
|
|
4217
|
+
}
|
|
4218
|
+
const errorResponse = await res.text();
|
|
4219
|
+
throw new Error(`\u{7F51}\u{7EDC}\u{54CD}\u{5E94}\u{5F02}\u{5E38}: ${res.status} ${res.statusText} - ${errorResponse}`);
|
|
4220
|
+
}
|
|
4221
|
+
if (res.ok) if (res.body) {
|
|
4222
|
+
const reader = res.body.getReader();
|
|
4223
|
+
const decoder = new TextDecoder("utf-8");
|
|
4224
|
+
if (streamCb) return void new ReadableStream({
|
|
4225
|
+
start (controller) {
|
|
4226
|
+
let buffer = "";
|
|
4227
|
+
function push() {
|
|
4228
|
+
reader.read().then(({ done, value })=>{
|
|
4229
|
+
if (done) {
|
|
4230
|
+
const lines = buffer.split("\n");
|
|
4231
|
+
for (const line of lines)handleLine(line, controller);
|
|
4232
|
+
if (streamCb) streamCb({
|
|
4233
|
+
isEnd: true
|
|
4234
|
+
});
|
|
4235
|
+
controller.close();
|
|
4236
|
+
return;
|
|
4237
|
+
}
|
|
4238
|
+
const chunkText = decoder.decode(value, {
|
|
4239
|
+
stream: true
|
|
4240
|
+
});
|
|
4241
|
+
buffer += chunkText;
|
|
4242
|
+
const lines = buffer.split("\n");
|
|
4243
|
+
for(let i = 0; i < lines.length - 1; i++)handleLine(lines[i], controller);
|
|
4244
|
+
buffer = lines[lines.length - 1];
|
|
4245
|
+
push();
|
|
4246
|
+
});
|
|
4247
|
+
}
|
|
4248
|
+
function handleLine(line, controller) {
|
|
4249
|
+
line = line.trim();
|
|
4250
|
+
if (line.startsWith("data:")) {
|
|
4251
|
+
const dataStr = line.slice(5).trim();
|
|
4252
|
+
if ("" === dataStr) return;
|
|
4253
|
+
try {
|
|
4254
|
+
const jsonData = JSON.parse(dataStr);
|
|
4255
|
+
if (jsonData.data?.text) {
|
|
4256
|
+
const wrappedData = {
|
|
4257
|
+
content: jsonData.data.text.toString(),
|
|
4258
|
+
controller
|
|
4259
|
+
};
|
|
4260
|
+
if (streamCb) streamCb(wrappedData);
|
|
4261
|
+
}
|
|
4262
|
+
} catch (e) {
|
|
4263
|
+
console.error("\u89E3\u6790JSON\u5931\u8D25:", e);
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4267
|
+
push();
|
|
4268
|
+
}
|
|
4269
|
+
});
|
|
4270
|
+
{
|
|
4271
|
+
let buffer = "";
|
|
4272
|
+
let accumulatedText = "";
|
|
4273
|
+
let isResponseEnded = false;
|
|
4274
|
+
const readAll = async ()=>{
|
|
4275
|
+
const { done, value } = await reader.read();
|
|
4276
|
+
if (done) {
|
|
4277
|
+
if (!isResponseEnded) throw new Error("\u54CD\u5E94\u63D0\u524D\u7ED3\u675F");
|
|
4278
|
+
return accumulatedText;
|
|
4279
|
+
}
|
|
4280
|
+
const chunkText = decoder.decode(value, {
|
|
4281
|
+
stream: true
|
|
4282
|
+
});
|
|
4283
|
+
buffer += chunkText;
|
|
4284
|
+
const lines = buffer.split("\n");
|
|
4285
|
+
for(let i = 0; i < lines.length - 1; i++){
|
|
4286
|
+
const line = lines[i].trim();
|
|
4287
|
+
if (!line.startsWith("data:")) continue;
|
|
4288
|
+
const dataStr = line.slice(5).trim();
|
|
4289
|
+
if ("" !== dataStr) try {
|
|
4290
|
+
const jsonData = JSON.parse(dataStr);
|
|
4291
|
+
switch(jsonData.event){
|
|
4292
|
+
case "message":
|
|
4293
|
+
case "agent_message":
|
|
4294
|
+
case "text_chunk":
|
|
4295
|
+
{
|
|
4296
|
+
const content = "text_chunk" === jsonData.event ? jsonData.data.text : jsonData.answer;
|
|
4297
|
+
accumulatedText += content;
|
|
4298
|
+
break;
|
|
4299
|
+
}
|
|
4300
|
+
case "workflow_finished":
|
|
4301
|
+
if (jsonData.data?.outputs?.text) accumulatedText = jsonData.data.outputs.text;
|
|
4302
|
+
else if (jsonData.data?.outputs) {
|
|
4303
|
+
const outputs = jsonData.data.outputs;
|
|
4304
|
+
const textValue = Object.values(outputs).find((v)=>"string" == typeof v && v.length > 0);
|
|
4305
|
+
if (textValue) accumulatedText = textValue;
|
|
4306
|
+
}
|
|
4307
|
+
isResponseEnded = true;
|
|
4308
|
+
break;
|
|
4309
|
+
case "message_end":
|
|
4310
|
+
isResponseEnded = true;
|
|
4311
|
+
break;
|
|
4312
|
+
case "error":
|
|
4313
|
+
throw new Error(`\u{670D}\u{52A1}\u{5668}\u{9519}\u{8BEF}: ${jsonData.code}, ${jsonData.message}`);
|
|
4314
|
+
default:
|
|
4315
|
+
break;
|
|
4316
|
+
}
|
|
4317
|
+
} catch (e) {
|
|
4318
|
+
throw new Error("\u89E3\u6790JSON\u5931\u8D25: " + e.message);
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
buffer = lines[lines.length - 1];
|
|
4322
|
+
return readAll();
|
|
4323
|
+
};
|
|
4324
|
+
return readAll();
|
|
4325
|
+
}
|
|
4326
|
+
} else throw new Error("\u54CD\u5E94\u4F53\u4E3A\u7A7A");
|
|
4327
|
+
{
|
|
4328
|
+
const errorResponse = await res.text();
|
|
4329
|
+
throw new Error(`\u{7F51}\u{7EDC}\u{54CD}\u{5E94}\u{5F02}\u{5E38}: ${res.status} ${res.statusText} - ${errorResponse}`);
|
|
4330
|
+
}
|
|
4331
|
+
} catch (error) {
|
|
4332
|
+
if ("AbortError" === error.name) throw new Error("\u8BF7\u6C42\u5DF2\u88AB\u4E2D\u6B62\uFF0C\u8D85\u65F6");
|
|
4333
|
+
throw error;
|
|
4334
|
+
}
|
|
4335
|
+
};
|
|
4336
|
+
try {
|
|
4337
|
+
const result = await Promise.race([
|
|
4338
|
+
fetchData(),
|
|
4339
|
+
new Promise((_, reject)=>{
|
|
4340
|
+
setTimeout(()=>{
|
|
4341
|
+
controller.abort();
|
|
4342
|
+
reject(new Error("\u8BF7\u6C42\u8D85\u65F6"));
|
|
4343
|
+
}, timeout);
|
|
4344
|
+
})
|
|
4345
|
+
]);
|
|
4346
|
+
if (streamCb) return;
|
|
4347
|
+
return result;
|
|
4348
|
+
} catch (error) {
|
|
4349
|
+
controller.abort();
|
|
4350
|
+
throw error;
|
|
4351
|
+
}
|
|
4352
|
+
}
|
|
4353
|
+
async function uploadFile(params) {
|
|
4354
|
+
const { appid, filePath, user = "aico-mcp" } = params;
|
|
4355
|
+
try {
|
|
4356
|
+
const fileBuffer = await external_fs_default().promises.readFile(filePath);
|
|
4357
|
+
const fileName = external_path_default().basename(filePath);
|
|
4358
|
+
const fileExtension = external_path_default().extname(filePath).toLowerCase().slice(1);
|
|
4359
|
+
const mimeTypes = {
|
|
4360
|
+
png: "image/png",
|
|
4361
|
+
jpeg: "image/jpeg",
|
|
4362
|
+
jpg: "image/jpeg",
|
|
4363
|
+
webp: "image/webp",
|
|
4364
|
+
gif: "image/gif"
|
|
4365
|
+
};
|
|
4366
|
+
const mimeType = mimeTypes[fileExtension] || "application/octet-stream";
|
|
4367
|
+
const formData = new FormData();
|
|
4368
|
+
formData.append("file", new Blob([
|
|
4369
|
+
fileBuffer.buffer
|
|
4370
|
+
], {
|
|
4371
|
+
type: mimeType
|
|
4372
|
+
}), fileName);
|
|
4373
|
+
formData.append("user", user);
|
|
4374
|
+
const response = await fetch("http://11.0.166.20:9199/v1/files/upload", {
|
|
4375
|
+
method: "POST",
|
|
4376
|
+
headers: {
|
|
4377
|
+
Authorization: `Bearer ${appid}`
|
|
4378
|
+
},
|
|
4379
|
+
body: formData
|
|
4380
|
+
});
|
|
4381
|
+
if (!response.ok) {
|
|
4382
|
+
const errorText = await response.text();
|
|
4383
|
+
throw new Error(`\u{6587}\u{4EF6}\u{4E0A}\u{4F20}\u{5931}\u{8D25}: ${response.status} ${response.statusText} - ${errorText}`);
|
|
4384
|
+
}
|
|
4385
|
+
const result = await response.json();
|
|
4386
|
+
if (!result.id || !result.name) throw new Error("\u65E0\u6548\u7684\u6587\u4EF6\u4E0A\u4F20\u54CD\u5E94\u683C\u5F0F");
|
|
4387
|
+
return result;
|
|
4388
|
+
} catch (error) {
|
|
4389
|
+
if (error instanceof Error) throw new Error(`\u{6587}\u{4EF6}\u{4E0A}\u{4F20}\u{5931}\u{8D25}: ${error.message}`);
|
|
4390
|
+
throw new Error("\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: \u672A\u77E5\u9519\u8BEF");
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4202
4393
|
class OpenAIService {
|
|
4203
4394
|
qwenConfig = {
|
|
4204
4395
|
apiKey: "sk-95b0bc60b7464bbbafd64edc2f5bab14",
|
|
@@ -4220,6 +4411,10 @@ var __webpack_exports__ = {};
|
|
|
4220
4411
|
baseUrl: "https://api.lkeap.cloud.tencent.com/v1/chat/completions",
|
|
4221
4412
|
model: "deepseek-v3.1-terminus"
|
|
4222
4413
|
};
|
|
4414
|
+
difyConfig = {
|
|
4415
|
+
apiKey: "app-AvlLh0nfN4l9oz1MSW4sEAQ6",
|
|
4416
|
+
baseUrl: "http://11.0.166.20:9199/v1"
|
|
4417
|
+
};
|
|
4223
4418
|
constructor(){}
|
|
4224
4419
|
async generateText(params) {
|
|
4225
4420
|
const { prompt, temperature, system_prompt } = params;
|
|
@@ -4576,23 +4771,115 @@ var __webpack_exports__ = {};
|
|
|
4576
4771
|
}
|
|
4577
4772
|
}
|
|
4578
4773
|
}
|
|
4774
|
+
async analyzeImageWithPath(params) {
|
|
4775
|
+
const { prompt, image_path, system_prompt } = params;
|
|
4776
|
+
logger.info("[OpenAI] analyzeImageWithPath \u88AB\u8C03\u7528", {
|
|
4777
|
+
image_path,
|
|
4778
|
+
prompt_length: prompt.length
|
|
4779
|
+
});
|
|
4780
|
+
try {
|
|
4781
|
+
logger.info("[OpenAI] \u5F00\u59CB\u4E0A\u4F20\u6587\u4EF6\u5230 Dify", {
|
|
4782
|
+
image_path
|
|
4783
|
+
});
|
|
4784
|
+
const uploadResult = await uploadFile({
|
|
4785
|
+
appid: this.difyConfig.apiKey,
|
|
4786
|
+
filePath: image_path,
|
|
4787
|
+
user: "aico-mcp"
|
|
4788
|
+
});
|
|
4789
|
+
logger.info("[OpenAI] \u6587\u4EF6\u4E0A\u4F20\u6210\u529F", {
|
|
4790
|
+
upload_file_id: uploadResult.id
|
|
4791
|
+
});
|
|
4792
|
+
const workflowData = {
|
|
4793
|
+
imagePath: {
|
|
4794
|
+
type: "image",
|
|
4795
|
+
transfer_method: "local_file",
|
|
4796
|
+
upload_file_id: uploadResult.id
|
|
4797
|
+
},
|
|
4798
|
+
context: prompt
|
|
4799
|
+
};
|
|
4800
|
+
logger.info("[OpenAI] \u5F00\u59CB\u8C03\u7528 Dify \u5DE5\u4F5C\u6D41");
|
|
4801
|
+
const workflowResponse = await invokeFlow({
|
|
4802
|
+
appid: this.difyConfig.apiKey,
|
|
4803
|
+
data: workflowData,
|
|
4804
|
+
timeout: 120000
|
|
4805
|
+
});
|
|
4806
|
+
logger.info("[OpenAI] Dify \u5DE5\u4F5C\u6D41\u8C03\u7528\u6210\u529F", {
|
|
4807
|
+
response_type: typeof workflowResponse,
|
|
4808
|
+
response_preview: "string" == typeof workflowResponse ? workflowResponse.substring(0, 200) : JSON.stringify(workflowResponse).substring(0, 500)
|
|
4809
|
+
});
|
|
4810
|
+
let summary = "";
|
|
4811
|
+
if ("string" == typeof workflowResponse && workflowResponse.length > 0) summary = workflowResponse;
|
|
4812
|
+
else if (workflowResponse?.outputs?.text) summary = workflowResponse.outputs.text;
|
|
4813
|
+
else if (workflowResponse?.data?.outputs?.text) summary = workflowResponse.data.outputs.text;
|
|
4814
|
+
else if (workflowResponse?.data?.text) summary = workflowResponse.data.text;
|
|
4815
|
+
else if (workflowResponse?.answer) summary = workflowResponse.answer;
|
|
4816
|
+
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"}`);
|
|
4817
|
+
if (!summary || 0 === summary.length) {
|
|
4818
|
+
logger.error("[OpenAI] Dify \u54CD\u5E94\u89E3\u6790\u5931\u8D25\uFF0C\u65E0\u6CD5\u63D0\u53D6\u6587\u672C\u5185\u5BB9", {
|
|
4819
|
+
response: JSON.stringify(workflowResponse)
|
|
4820
|
+
});
|
|
4821
|
+
throw new Error("Dify\u5DE5\u4F5C\u6D41\u54CD\u5E94\u4E2D\u672A\u627E\u5230\u6709\u6548\u6587\u672C\u5185\u5BB9");
|
|
4822
|
+
}
|
|
4823
|
+
logger.info("[OpenAI] Dify \u5206\u6790\u5B8C\u6210", {
|
|
4824
|
+
summary_length: summary.length
|
|
4825
|
+
});
|
|
4826
|
+
return summary;
|
|
4827
|
+
} catch (difyError) {
|
|
4828
|
+
logger.error("[OpenAI] Dify \u8C03\u7528\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u5176\u4ED6\u670D\u52A1", {
|
|
4829
|
+
error: difyError instanceof Error ? difyError.message : String(difyError)
|
|
4830
|
+
});
|
|
4831
|
+
const fs = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "fs/promises"));
|
|
4832
|
+
const path = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "path"));
|
|
4833
|
+
const imageBuffer = await fs.readFile(image_path);
|
|
4834
|
+
const base64 = imageBuffer.toString("base64");
|
|
4835
|
+
const ext = path.extname(image_path).toLowerCase();
|
|
4836
|
+
let mimeType = "image/jpeg";
|
|
4837
|
+
switch(ext){
|
|
4838
|
+
case ".png":
|
|
4839
|
+
mimeType = "image/png";
|
|
4840
|
+
break;
|
|
4841
|
+
case ".gif":
|
|
4842
|
+
mimeType = "image/gif";
|
|
4843
|
+
break;
|
|
4844
|
+
case ".webp":
|
|
4845
|
+
mimeType = "image/webp";
|
|
4846
|
+
break;
|
|
4847
|
+
case ".jpg":
|
|
4848
|
+
case ".jpeg":
|
|
4849
|
+
mimeType = "image/jpeg";
|
|
4850
|
+
break;
|
|
4851
|
+
}
|
|
4852
|
+
const image_base64 = `data:${mimeType};base64,${base64}`;
|
|
4853
|
+
return this.analyzeImage({
|
|
4854
|
+
prompt,
|
|
4855
|
+
image_base64,
|
|
4856
|
+
system_prompt
|
|
4857
|
+
});
|
|
4858
|
+
}
|
|
4859
|
+
}
|
|
4579
4860
|
async analyzeImage(params) {
|
|
4580
4861
|
const { prompt, image_base64, system_prompt } = params;
|
|
4581
|
-
let lastError = null;
|
|
4582
4862
|
try {
|
|
4583
|
-
const
|
|
4863
|
+
const controller = new AbortController();
|
|
4864
|
+
const timeoutId = setTimeout(()=>controller.abort(), 20000);
|
|
4865
|
+
const response = await fetch(this.kimiConfig.baseUrl, {
|
|
4584
4866
|
method: "POST",
|
|
4585
4867
|
headers: {
|
|
4586
4868
|
"Content-Type": "application/json",
|
|
4587
|
-
Authorization: `Bearer ${this.
|
|
4869
|
+
Authorization: `Bearer ${this.kimiConfig.apiKey}`
|
|
4588
4870
|
},
|
|
4589
4871
|
body: JSON.stringify({
|
|
4590
|
-
model: this.
|
|
4872
|
+
model: this.kimiConfig.model,
|
|
4591
4873
|
messages: [
|
|
4592
4874
|
...system_prompt ? [
|
|
4593
4875
|
{
|
|
4594
4876
|
role: "system",
|
|
4595
|
-
content:
|
|
4877
|
+
content: [
|
|
4878
|
+
{
|
|
4879
|
+
type: "text",
|
|
4880
|
+
text: system_prompt
|
|
4881
|
+
}
|
|
4882
|
+
]
|
|
4596
4883
|
}
|
|
4597
4884
|
] : [],
|
|
4598
4885
|
{
|
|
@@ -4612,36 +4899,34 @@ var __webpack_exports__ = {};
|
|
|
4612
4899
|
}
|
|
4613
4900
|
],
|
|
4614
4901
|
stream: false
|
|
4615
|
-
})
|
|
4902
|
+
}),
|
|
4903
|
+
signal: controller.signal
|
|
4616
4904
|
});
|
|
4905
|
+
clearTimeout(timeoutId);
|
|
4617
4906
|
if (!response.ok) {
|
|
4618
4907
|
const errorText = await response.text();
|
|
4619
|
-
throw new Error(`
|
|
4908
|
+
throw new Error(`Kimi Vision API error: ${response.status} ${response.statusText} - ${errorText}`);
|
|
4620
4909
|
}
|
|
4621
4910
|
const data = await response.json();
|
|
4622
|
-
if (!data.choices || 0 === data.choices.length) throw new Error("No choices returned from
|
|
4911
|
+
if (!data.choices || 0 === data.choices.length) throw new Error("No choices returned from Kimi Vision API");
|
|
4623
4912
|
return data.choices[0].message.content;
|
|
4624
|
-
} catch (
|
|
4625
|
-
lastError = error;
|
|
4913
|
+
} catch (kimiError) {
|
|
4626
4914
|
try {
|
|
4627
|
-
const
|
|
4915
|
+
const controller = new AbortController();
|
|
4916
|
+
const timeoutId = setTimeout(()=>controller.abort(), 15000);
|
|
4917
|
+
const response = await fetch(this.glm4vConfig.baseUrl, {
|
|
4628
4918
|
method: "POST",
|
|
4629
4919
|
headers: {
|
|
4630
4920
|
"Content-Type": "application/json",
|
|
4631
|
-
Authorization: `Bearer ${this.
|
|
4921
|
+
Authorization: `Bearer ${this.glm4vConfig.apiKey}`
|
|
4632
4922
|
},
|
|
4633
4923
|
body: JSON.stringify({
|
|
4634
|
-
model: this.
|
|
4924
|
+
model: this.glm4vConfig.model,
|
|
4635
4925
|
messages: [
|
|
4636
4926
|
...system_prompt ? [
|
|
4637
4927
|
{
|
|
4638
4928
|
role: "system",
|
|
4639
|
-
content:
|
|
4640
|
-
{
|
|
4641
|
-
type: "text",
|
|
4642
|
-
text: system_prompt
|
|
4643
|
-
}
|
|
4644
|
-
]
|
|
4929
|
+
content: system_prompt
|
|
4645
4930
|
}
|
|
4646
4931
|
] : [],
|
|
4647
4932
|
{
|
|
@@ -4661,41 +4946,57 @@ var __webpack_exports__ = {};
|
|
|
4661
4946
|
}
|
|
4662
4947
|
],
|
|
4663
4948
|
stream: false
|
|
4664
|
-
})
|
|
4949
|
+
}),
|
|
4950
|
+
signal: controller.signal
|
|
4665
4951
|
});
|
|
4952
|
+
clearTimeout(timeoutId);
|
|
4666
4953
|
if (!response.ok) {
|
|
4667
4954
|
const errorText = await response.text();
|
|
4668
|
-
throw new Error(`
|
|
4955
|
+
throw new Error(`GLM-4V API error: ${response.status} ${response.statusText} - ${errorText}`);
|
|
4669
4956
|
}
|
|
4670
4957
|
const data = await response.json();
|
|
4671
|
-
if (!data.choices || 0 === data.choices.length) throw new Error("No choices returned from
|
|
4958
|
+
if (!data.choices || 0 === data.choices.length) throw new Error("No choices returned from GLM-4V API");
|
|
4672
4959
|
return data.choices[0].message.content;
|
|
4673
|
-
} catch (
|
|
4674
|
-
throw
|
|
4960
|
+
} catch (glmError) {
|
|
4961
|
+
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
4962
|
}
|
|
4676
4963
|
}
|
|
4677
4964
|
}
|
|
4678
4965
|
}
|
|
4679
4966
|
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{
|
|
4967
|
+
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
4968
|
|
|
4682
4969
|
**\u{8F93}\u{5165}\u{5185}\u{5BB9}**:
|
|
4683
4970
|
{inputContent}
|
|
4684
4971
|
|
|
4685
|
-
## \u{
|
|
4972
|
+
## \u{5206}\u{6790}\u{4EFB}\u{52A1}
|
|
4973
|
+
|
|
4974
|
+
\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
4975
|
|
|
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}
|
|
4976
|
+
### 1. \u{9700}\u{6C42}\u{7C7B}\u{578B}\u{8BC6}\u{522B}
|
|
4692
4977
|
|
|
4693
|
-
|
|
4978
|
+
\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}
|
|
4979
|
+
- **\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}
|
|
4980
|
+
- **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}
|
|
4981
|
+
- **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}
|
|
4982
|
+
- **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
4983
|
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4984
|
+
### 2. \u{6DF1}\u{5EA6}\u{9700}\u{6C42}\u{5206}\u{6790}
|
|
4985
|
+
|
|
4986
|
+
\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}
|
|
4987
|
+
- **\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}
|
|
4988
|
+
- **\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}
|
|
4989
|
+
- **\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}
|
|
4990
|
+
- **\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}
|
|
4991
|
+
- **\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}
|
|
4992
|
+
|
|
4993
|
+
### 3. \u{6280}\u{672F}\u{4E0A}\u{4E0B}\u{6587}\u{63D0}\u{53D6}
|
|
4994
|
+
|
|
4995
|
+
\u{4ECE}\u{9879}\u{76EE}\u{4FE1}\u{606F}\u{4E2D}\u{63D0}\u{53D6}\u{FF1A}
|
|
4996
|
+
- \u{6280}\u{672F}\u{6808}\u{548C}\u{6846}\u{67B6}
|
|
4997
|
+
- \u{73B0}\u{6709}\u{7684}\u{4EE3}\u{7801}\u{7ED3}\u{6784}
|
|
4998
|
+
- \u{4F9D}\u{8D56}\u{5173}\u{7CFB}
|
|
4999
|
+
- \u{8BBE}\u{8BA1}\u{89C4}\u{8303}
|
|
4699
5000
|
|
|
4700
5001
|
## \u{8F93}\u{51FA}\u{683C}\u{5F0F}
|
|
4701
5002
|
|
|
@@ -4707,14 +5008,36 @@ var __webpack_exports__ = {};
|
|
|
4707
5008
|
"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
5009
|
"primaryTechnology": "\u{4E3B}\u{8981}\u{6280}\u{672F}\u{6808}\u{63CF}\u{8FF0}",
|
|
4709
5010
|
"confidence": "high|medium|low",
|
|
5011
|
+
"businessContext": {
|
|
5012
|
+
"background": "\u{4E1A}\u{52A1}\u{80CC}\u{666F}\u{63CF}\u{8FF0}",
|
|
5013
|
+
"objectives": ["\u{4E1A}\u{52A1}\u{76EE}\u{6807}1", "\u{4E1A}\u{52A1}\u{76EE}\u{6807}2"],
|
|
5014
|
+
"stakeholders": ["\u{6D89}\u{53CA}\u{7684}\u{89D2}\u{8272}1", "\u{6D89}\u{53CA}\u{7684}\u{89D2}\u{8272}2"]
|
|
5015
|
+
},
|
|
4710
5016
|
"requirements": [
|
|
4711
5017
|
{
|
|
4712
5018
|
"id": "req_001",
|
|
4713
5019
|
"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}",
|
|
5020
|
+
"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
5021
|
"priority": "high|medium|low",
|
|
4716
5022
|
"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}"
|
|
5023
|
+
"type": "\u{63A5}\u{53E3}|PC\u{9875}\u{9762}|APP|SDK\u{96C6}\u{6210}",
|
|
5024
|
+
"businessFlow": {
|
|
5025
|
+
"preconditions": ["\u{524D}\u{7F6E}\u{6761}\u{4EF6}1"],
|
|
5026
|
+
"mainFlow": ["\u{6B65}\u{9AA4}1", "\u{6B65}\u{9AA4}2", "\u{6B65}\u{9AA4}3"],
|
|
5027
|
+
"alternativeFlows": ["\u{66FF}\u{4EE3}\u{6D41}\u{7A0B}1"],
|
|
5028
|
+
"exceptionFlows": ["\u{5F02}\u{5E38}\u{5904}\u{7406}1"]
|
|
5029
|
+
},
|
|
5030
|
+
"dataEntities": [
|
|
5031
|
+
{
|
|
5032
|
+
"name": "\u{5B9E}\u{4F53}\u{540D}\u{79F0}",
|
|
5033
|
+
"fields": [
|
|
5034
|
+
{"name": "\u{5B57}\u{6BB5}\u{540D}", "type": "\u{7C7B}\u{578B}", "required": true, "description": "\u{8BF4}\u{660E}"}
|
|
5035
|
+
]
|
|
5036
|
+
}
|
|
5037
|
+
],
|
|
5038
|
+
"interactions": [
|
|
5039
|
+
{"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}"}
|
|
5040
|
+
]
|
|
4718
5041
|
}
|
|
4719
5042
|
],
|
|
4720
5043
|
"templateRecommendation": {
|
|
@@ -4722,13 +5045,29 @@ var __webpack_exports__ = {};
|
|
|
4722
5045
|
"reason": "\u{9009}\u{62E9}\u{8BE5}\u{6A21}\u{677F}\u{7684}\u{539F}\u{56E0}",
|
|
4723
5046
|
"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
5047
|
},
|
|
4725
|
-
"
|
|
5048
|
+
"technicalContext": {
|
|
5049
|
+
"suggestedTechStack": ["\u{5EFA}\u{8BAE}\u{7684}\u{6280}\u{672F}\u{6808}"],
|
|
5050
|
+
"integrationPoints": ["\u{9700}\u{8981}\u{96C6}\u{6210}\u{7684}\u{7CFB}\u{7EDF}\u{6216}\u{670D}\u{52A1}"],
|
|
5051
|
+
"securityRequirements": ["\u{5B89}\u{5168}\u{8981}\u{6C42}"],
|
|
5052
|
+
"performanceRequirements": ["\u{6027}\u{80FD}\u{8981}\u{6C42}"]
|
|
5053
|
+
},
|
|
5054
|
+
"documentationHints": {
|
|
5055
|
+
"keySequenceDiagrams": ["\u{9700}\u{8981}\u{7ED8}\u{5236}\u{7684}\u{65F6}\u{5E8F}\u{56FE}\u{573A}\u{666F}"],
|
|
5056
|
+
"keyERDiagrams": ["\u{9700}\u{8981}\u{7ED8}\u{5236}\u{7684}ER\u{56FE}\u{5B9E}\u{4F53}"],
|
|
5057
|
+
"keyTables": ["\u{9700}\u{8981}\u{8BE6}\u{7EC6}\u{8BF4}\u{660E}\u{7684}\u{8868}\u{683C}"]
|
|
5058
|
+
}
|
|
4726
5059
|
}
|
|
4727
5060
|
\`\`\`
|
|
4728
5061
|
|
|
5062
|
+
## \u{5206}\u{6790}\u{539F}\u{5219}
|
|
4729
5063
|
|
|
5064
|
+
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}
|
|
5065
|
+
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}
|
|
5066
|
+
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}
|
|
5067
|
+
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}
|
|
5068
|
+
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
5069
|
|
|
4731
|
-
**\u{8981}\u{6C42}**: \u{
|
|
5070
|
+
**\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
5071
|
class IntelligentAnalyzer {
|
|
4733
5072
|
async analyzeRequirements(inputContent, projectInfo, customPrompt) {
|
|
4734
5073
|
try {
|
|
@@ -5490,9 +5829,9 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5490
5829
|
|
|
5491
5830
|
**\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
5831
|
`;
|
|
5493
|
-
const
|
|
5832
|
+
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
5833
|
|
|
5495
|
-
**\u{8F93}\u{5165}**: \u{529F}\u{80FD}\u{540D}\u{79F0}={featureName}, \u{4E1A}\u{52A1}\u{9886}\u{57DF}={businessDomain}, \u{
|
|
5834
|
+
**\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
5835
|
|
|
5497
5836
|
**\u{539F}\u{59CB}\u{9700}\u{6C42}**:
|
|
5498
5837
|
\`\`\`
|
|
@@ -5502,11 +5841,12 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5502
5841
|
## \u{6587}\u{6863}\u{7ED3}\u{6784}\u{8981}\u{6C42}
|
|
5503
5842
|
\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
5843
|
|
|
5505
|
-
# {featureName} -
|
|
5844
|
+
# {featureName} - HTML\u{9875}\u{9762}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
|
|
5506
5845
|
|
|
5507
5846
|
> **\u{751F}\u{6210}\u{65F6}\u{95F4}**: {currentTime}
|
|
5508
5847
|
> **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: {businessDomain}
|
|
5509
|
-
> **\u{9875}\u{9762}\u{7C7B}\u{578B}**:
|
|
5848
|
+
> **\u{9875}\u{9762}\u{7C7B}\u{578B}**: {pageType}\u{FF08}pc/mobile/responsive\u{FF09}
|
|
5849
|
+
> **\u{9875}\u{9762}\u{98CE}\u{683C}**: TailwindCSS \u{7B80}\u{7EA6}\u{98CE}\u{683C}
|
|
5510
5850
|
|
|
5511
5851
|
---
|
|
5512
5852
|
|
|
@@ -5518,6 +5858,8 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5518
5858
|
|
|
5519
5859
|
**\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
5860
|
|
|
5861
|
+
**\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}]
|
|
5862
|
+
|
|
5521
5863
|
## 2. {featureName}\u{529F}\u{80FD}\u{8BBE}\u{8BA1}\u{8BF4}\u{660E}
|
|
5522
5864
|
|
|
5523
5865
|
| | | | | |
|
|
@@ -5527,14 +5869,17 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5527
5869
|
|**\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
5870
|
|**\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
5871
|
|**\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}]|
|
|
5872
|
+
|**\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
5873
|
|**\u{529F}\u{80FD}\u{63CF}\u{8FF0}**|[\u{8BE6}\u{7EC6}\u{7684}\u{529F}\u{80FD}\u{63CF}\u{8FF0}]|
|
|
5532
5874
|
|**\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
5875
|
|
|
5534
5876
|
## 3. \u{9875}\u{9762}\u{5E03}\u{5C40}\u{8BBE}\u{8BA1}
|
|
5535
5877
|
|
|
5536
5878
|
### 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}
|
|
5879
|
+
[\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}]
|
|
5880
|
+
- **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}]
|
|
5881
|
+
- **\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}]
|
|
5882
|
+
- **\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
5883
|
|
|
5539
5884
|
### 3.2 \u{9875}\u{9762}\u{533A}\u{57DF}\u{5212}\u{5206}
|
|
5540
5885
|
[\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 +5887,34 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5542
5887
|
### 3.3 \u{9875}\u{9762}\u{6D41}\u{7EBF}\u{8BBE}\u{8BA1}
|
|
5543
5888
|
[\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
5889
|
|
|
5890
|
+
### 3.4 \u{54CD}\u{5E94}\u{5F0F}\u{9002}\u{914D}\u{7B56}\u{7565}
|
|
5891
|
+
[\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}]
|
|
5892
|
+
- **\u{65AD}\u{70B9}\u{8BBE}\u{7F6E}**: sm(640px), md(768px), lg(1024px), xl(1280px)
|
|
5893
|
+
- **\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}]
|
|
5894
|
+
- **\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}]
|
|
5895
|
+
|
|
5545
5896
|
## 4. \u{6837}\u{5F0F}\u{89C4}\u{8303}\u{8BF4}\u{660E}
|
|
5546
5897
|
|
|
5547
5898
|
### 4.1 \u{8272}\u{5F69}\u{89C4}\u{8303}
|
|
5548
5899
|
[\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}]
|
|
5900
|
+
\`\`\`css
|
|
5901
|
+
:root {
|
|
5902
|
+
--bg: #ffffff;
|
|
5903
|
+
--bg-secondary: #f8f9fa;
|
|
5904
|
+
--border: #e5e5e5;
|
|
5905
|
+
--text: #111111;
|
|
5906
|
+
--text-muted: #666666;
|
|
5907
|
+
--accent: #000000;
|
|
5908
|
+
}
|
|
5909
|
+
\`\`\`
|
|
5910
|
+
|
|
5911
|
+
### 4.2 \u{5B57}\u{4F53}\u{89C4}\u{8303}
|
|
5912
|
+
[\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
5913
|
|
|
5914
|
+
### 4.3 \u{95F4}\u{8DDD}\u{89C4}\u{8303}
|
|
5915
|
+
[\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
5916
|
|
|
5551
|
-
### 4.
|
|
5917
|
+
### 4.4 \u{54C1}\u{724C}\u{89C6}\u{89C9}\u{89C4}\u{8303}
|
|
5552
5918
|
[\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
5919
|
|
|
5554
5920
|
## 5. \u{4EA4}\u{4E92}\u{903B}\u{8F91}\u{8BF4}\u{660E}
|
|
@@ -5565,11 +5931,14 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5565
5931
|
### 5.4 \u{8868}\u{5355}\u{9A8C}\u{8BC1}\u{89C4}\u{5219}
|
|
5566
5932
|
[\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
5933
|
|
|
5568
|
-
### 5.5 \u{
|
|
5569
|
-
[\u{
|
|
5934
|
+
### 5.5 \u{89E6}\u{6478}/\u{624B}\u{52BF}\u{4EA4}\u{4E92}
|
|
5935
|
+
[\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}]
|
|
5936
|
+
- **\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}]
|
|
5937
|
+
- **\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}]
|
|
5938
|
+
- **\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
5939
|
|
|
5571
|
-
### 5.6 \u{
|
|
5572
|
-
[\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}\u{9875}\u{9762}\u{4E2D}\u{
|
|
5940
|
+
### 5.6 \u{4E8B}\u{4EF6}\u{5904}\u{7406}\u{673A}\u{5236}
|
|
5941
|
+
[\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
5942
|
|
|
5574
5943
|
### 5.7 \u{9519}\u{8BEF}\u{5904}\u{7406}\u{4E0E}\u{6062}\u{590D}
|
|
5575
5944
|
[\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 +5948,10 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5579
5948
|
### 6.1 \u{4E3B}\u{8981}\u{6570}\u{636E}\u{5B9E}\u{4F53}
|
|
5580
5949
|
[\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
5950
|
|
|
5582
|
-
\u{
|
|
5583
|
-
| | | | | |
|
|
5951
|
+
| **\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
5952
|
|---|---|---|---|---|
|
|
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
5953
|
|[\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
5954
|
|[\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
5955
|
|
|
5590
5956
|
### 6.2 \u{8868}\u{5355}\u{5B57}\u{6BB5}\u{8BF4}\u{660E}
|
|
5591
5957
|
[\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 +5961,10 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5595
5961
|
|
|
5596
5962
|
## 7. \u{754C}\u{9762}\u{64CD}\u{4F5C}\u{8BF4}\u{660E}
|
|
5597
5963
|
|
|
5598
|
-
| | | |
|
|
5964
|
+
| **\u{5E8F}\u{53F7}** | **\u{4E1A}\u{52A1}\u{64CD}\u{4F5C}** | **\u{8BF4}\u{660E}** |
|
|
5599
5965
|
|---|---|---|
|
|
5600
|
-
|**\u{5E8F}\u{53F7}**|**\u{4E1A}\u{52A1}\u{64CD}\u{4F5C}**|**\u{8BF4}\u{660E}**|
|
|
5601
5966
|
|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
5967
|
|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
5968
|
|
|
5605
5969
|
## 8. \u{7EC4}\u{4EF6}\u{7ED3}\u{6784}\u{8BBE}\u{8BA1}
|
|
5606
5970
|
|
|
@@ -5622,21 +5986,32 @@ Scenario Outline: UI\u{7EC4}\u{4EF6}\u{4EA4}\u{4E92}\u{5904}\u{7406}\u{6D41}\u{7
|
|
|
5622
5986
|
|
|
5623
5987
|
\`\`\`mermaid
|
|
5624
5988
|
sequenceDiagram
|
|
5989
|
+
participant User as \u{7528}\u{6237}
|
|
5990
|
+
participant Page as \u{9875}\u{9762}
|
|
5991
|
+
participant API as \u{540E}\u{7AEF}API
|
|
5992
|
+
User->>Page: \u{8BBF}\u{95EE}\u{9875}\u{9762}
|
|
5993
|
+
Page->>API: \u{8BF7}\u{6C42}\u{6570}\u{636E}
|
|
5994
|
+
API-->>Page: \u{8FD4}\u{56DE}\u{6570}\u{636E}
|
|
5995
|
+
Page-->>User: \u{5C55}\u{793A}\u{5185}\u{5BB9}
|
|
5625
5996
|
\`\`\`
|
|
5626
5997
|
|
|
5627
|
-
### 9.2 \u{8FB9}\u{7F18}\u{60C5}\u{51B5}\u{6D41}\u{7A0B}\u{FF08}\u{
|
|
5998
|
+
### 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
5999
|
|
|
5629
|
-
#### 9.2.1 \u{6027}\u{80FD}\u{4F18}\u{5316}\u{8981}\u{6C42}
|
|
5630
6000
|
\`\`\`mermaid
|
|
5631
6001
|
sequenceDiagram
|
|
6002
|
+
participant User as \u{7528}\u{6237}
|
|
6003
|
+
participant Page as \u{9875}\u{9762}
|
|
6004
|
+
participant API as \u{540E}\u{7AEF}API
|
|
6005
|
+
User->>Page: \u{63D0}\u{4EA4}\u{8868}\u{5355}
|
|
6006
|
+
Page->>API: \u{53D1}\u{9001}\u{8BF7}\u{6C42}
|
|
6007
|
+
API-->>Page: \u{8FD4}\u{56DE}\u{9519}\u{8BEF}
|
|
6008
|
+
Page-->>User: \u{663E}\u{793A}\u{9519}\u{8BEF}\u{63D0}\u{793A}
|
|
5632
6009
|
\`\`\`
|
|
5633
6010
|
|
|
5634
|
-
|
|
5635
6011
|
## 10. \u{4E1A}\u{52A1}\u{72B6}\u{6001}\u{63CF}\u{8FF0}
|
|
5636
6012
|
|
|
5637
|
-
| | | |
|
|
6013
|
+
| **\u{72B6}\u{6001}\u{7F16}\u{53F7}** | **\u{72B6}\u{6001}\u{540D}\u{79F0}** | **\u{63CF}\u{8FF0}** |
|
|
5638
6014
|
|---|---|---|
|
|
5639
|
-
|**\u{72B6}\u{6001}\u{7F16}\u{53F7}**|**\u{72B6}\u{6001}\u{540D}\u{79F0}**|**\u{63CF}\u{8FF0}**|
|
|
5640
6015
|
|01|\u{5F85}\u{52A0}\u{8F7D}|\u{9875}\u{9762}\u{521D}\u{59CB}\u{5316}\u{72B6}\u{6001}|
|
|
5641
6016
|
|02|\u{52A0}\u{8F7D}\u{4E2D}|\u{6570}\u{636E}\u{52A0}\u{8F7D}\u{72B6}\u{6001}|
|
|
5642
6017
|
|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 +6022,19 @@ sequenceDiagram
|
|
|
5647
6022
|
|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
6023
|
|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
6024
|
|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
6025
|
|
|
5652
6026
|
## 11. \u{7528}\u{6237}\u{6545}\u{4E8B}
|
|
5653
6027
|
|
|
5654
6028
|
### 11.1 \u{6545}\u{4E8B}1
|
|
5655
6029
|
[\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}]
|
|
6030
|
+
|
|
5656
6031
|
### 11.2 \u{6545}\u{4E8B}2
|
|
5657
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}]
|
|
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
|
-
|
|
5664
|
-
---
|
|
5665
|
-
|
|
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 appTemplatePrompt = `\u{4F60}\u{662F}\u{79FB}\u{52A8}\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}APP\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}
|
|
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
6033
|
|
|
5685
6034
|
---
|
|
5686
6035
|
|
|
5687
|
-
|
|
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}
|
|
6036
|
+
**\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}`;
|
|
6037
|
+
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
6038
|
|
|
5819
6039
|
**\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
6040
|
|
|
@@ -6007,36 +6227,28 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6007
6227
|
class TemplateSelector {
|
|
6008
6228
|
templateMap = new Map([
|
|
6009
6229
|
[
|
|
6010
|
-
"
|
|
6011
|
-
|
|
6012
|
-
],
|
|
6013
|
-
[
|
|
6014
|
-
"APP",
|
|
6015
|
-
appTemplatePrompt
|
|
6230
|
+
"HTML",
|
|
6231
|
+
htmlPageTemplatePrompt
|
|
6016
6232
|
],
|
|
6017
6233
|
[
|
|
6018
|
-
"
|
|
6019
|
-
|
|
6234
|
+
"html",
|
|
6235
|
+
htmlPageTemplatePrompt
|
|
6020
6236
|
],
|
|
6021
6237
|
[
|
|
6022
|
-
"
|
|
6023
|
-
|
|
6238
|
+
"API",
|
|
6239
|
+
api_template_apiTemplatePrompt
|
|
6024
6240
|
],
|
|
6025
6241
|
[
|
|
6026
6242
|
"api",
|
|
6027
|
-
|
|
6243
|
+
api_template_apiTemplatePrompt
|
|
6028
6244
|
],
|
|
6029
6245
|
[
|
|
6030
|
-
"
|
|
6031
|
-
|
|
6032
|
-
],
|
|
6033
|
-
[
|
|
6034
|
-
"app",
|
|
6035
|
-
appTemplatePrompt
|
|
6246
|
+
"\u63A5\u53E3",
|
|
6247
|
+
api_template_apiTemplatePrompt
|
|
6036
6248
|
],
|
|
6037
6249
|
[
|
|
6038
|
-
"
|
|
6039
|
-
|
|
6250
|
+
"\u9875\u9762",
|
|
6251
|
+
htmlPageTemplatePrompt
|
|
6040
6252
|
]
|
|
6041
6253
|
]);
|
|
6042
6254
|
selectTemplate(requirementType) {
|
|
@@ -6081,33 +6293,18 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6081
6293
|
"ui",
|
|
6082
6294
|
"\u7F51\u9875",
|
|
6083
6295
|
"\u6D4F\u89C8\u5668",
|
|
6084
|
-
"\u524D\u7AEF"
|
|
6085
|
-
|
|
6086
|
-
type: "PC\u9875\u9762",
|
|
6087
|
-
template: pcPageTemplatePrompt
|
|
6088
|
-
};
|
|
6089
|
-
if (this.containsAny(lowerType, [
|
|
6296
|
+
"\u524D\u7AEF",
|
|
6297
|
+
"html",
|
|
6090
6298
|
"app",
|
|
6091
6299
|
"\u79FB\u52A8",
|
|
6092
6300
|
"ios",
|
|
6093
6301
|
"android",
|
|
6094
6302
|
"\u5C0F\u7A0B\u5E8F",
|
|
6095
|
-
"\u79FB\u52A8\u7AEF"
|
|
6096
|
-
|
|
6097
|
-
type: "APP",
|
|
6098
|
-
template: appTemplatePrompt
|
|
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"
|
|
6303
|
+
"\u79FB\u52A8\u7AEF",
|
|
6304
|
+
"\u54CD\u5E94\u5F0F"
|
|
6108
6305
|
])) return {
|
|
6109
|
-
type: "
|
|
6110
|
-
template:
|
|
6306
|
+
type: "HTML",
|
|
6307
|
+
template: htmlPageTemplatePrompt
|
|
6111
6308
|
};
|
|
6112
6309
|
if (this.containsAny(lowerType, [
|
|
6113
6310
|
"\u63A5\u53E3",
|
|
@@ -6119,7 +6316,7 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6119
6316
|
"\u670D\u52A1\u7AEF"
|
|
6120
6317
|
])) return {
|
|
6121
6318
|
type: "\u63A5\u53E3",
|
|
6122
|
-
template:
|
|
6319
|
+
template: api_template_apiTemplatePrompt
|
|
6123
6320
|
};
|
|
6124
6321
|
return null;
|
|
6125
6322
|
}
|
|
@@ -6195,7 +6392,7 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6195
6392
|
cleanedCount
|
|
6196
6393
|
});
|
|
6197
6394
|
}
|
|
6198
|
-
async generateUnifiedDocument(analysis, projectInfo, featureName, sourceInfo, customPrompt, currentProjectPath) {
|
|
6395
|
+
async generateUnifiedDocument(analysis, projectInfo, featureName, sourceInfo, customPrompt, currentProjectPath, pageStyle, pageType) {
|
|
6199
6396
|
try {
|
|
6200
6397
|
logger.info("\u51C6\u5907\u751F\u6210\u7EDF\u4E00\u6280\u672F\u6587\u6863\u4EFB\u52A1", {
|
|
6201
6398
|
featureName,
|
|
@@ -6203,7 +6400,10 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6203
6400
|
featureCount: analysis.requirements.length,
|
|
6204
6401
|
currentProjectPath
|
|
6205
6402
|
});
|
|
6206
|
-
const requirementTypes =
|
|
6403
|
+
const requirementTypes = [
|
|
6404
|
+
"API",
|
|
6405
|
+
"HTML"
|
|
6406
|
+
];
|
|
6207
6407
|
const generationTasks = await Promise.all(requirementTypes.map(async (reqType)=>{
|
|
6208
6408
|
logger.info("\u51C6\u5907\u62A5\u544A\u751F\u6210\u4EFB\u52A1", {
|
|
6209
6409
|
requirementType: reqType,
|
|
@@ -6227,13 +6427,19 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6227
6427
|
prompt: promptData.prompt,
|
|
6228
6428
|
systemPrompt: promptData.systemPrompt,
|
|
6229
6429
|
templateContent: promptData.templateContent,
|
|
6230
|
-
templateVariables: "templateVariables" in promptData ?
|
|
6430
|
+
templateVariables: "templateVariables" in promptData ? {
|
|
6431
|
+
...promptData.templateVariables,
|
|
6432
|
+
pageStyle,
|
|
6433
|
+
pageType: pageType || "responsive"
|
|
6434
|
+
} : {
|
|
6231
6435
|
featureName: featureName,
|
|
6232
6436
|
inputContent: this.buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo),
|
|
6233
6437
|
currentTime: new Date().toISOString(),
|
|
6234
6438
|
businessDomain: this.mapRequirementTypeToBusinessDomain(reqType),
|
|
6235
6439
|
generateSequenceDiagram: "true",
|
|
6236
|
-
customPrompt
|
|
6440
|
+
customPrompt,
|
|
6441
|
+
pageStyle,
|
|
6442
|
+
pageType: pageType || "responsive"
|
|
6237
6443
|
},
|
|
6238
6444
|
existingContent: "existingContent" in promptData ? promptData.existingContent : void 0
|
|
6239
6445
|
};
|
|
@@ -6306,18 +6512,72 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6306
6512
|
}
|
|
6307
6513
|
buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo) {
|
|
6308
6514
|
const featuresToProcess = analysis.featureDependencies?.mergedFeatures || analysis.requirements;
|
|
6515
|
+
const enrichedContext = analysis.enrichedContext || {};
|
|
6516
|
+
const businessContext = analysis.businessContext || {};
|
|
6517
|
+
const technicalContext = analysis.technicalContext || {};
|
|
6518
|
+
const documentationHints = analysis.documentationHints || {};
|
|
6309
6519
|
const combinedFeatureContent = featuresToProcess.map((feature, index)=>{
|
|
6310
6520
|
const featureTitle = "title" in feature ? feature.title : feature.featureName;
|
|
6311
6521
|
const featureContent = "fullContent" in feature ? feature.fullContent : feature.description;
|
|
6312
|
-
|
|
6313
|
-
|
|
6522
|
+
const businessFlow = feature.businessFlow || {};
|
|
6523
|
+
const dataEntities = feature.dataEntities || [];
|
|
6524
|
+
const interactions = feature.interactions || [];
|
|
6525
|
+
let content = `## \u{529F}\u{80FD}\u{70B9}${index + 1}\u{FF1A}${featureTitle}\n\n${featureContent}`;
|
|
6526
|
+
if (businessFlow.mainFlow?.length > 0) {
|
|
6527
|
+
content += `
|
|
6528
|
+
|
|
6529
|
+
### \u{4E1A}\u{52A1}\u{6D41}\u{7A0B}
|
|
6530
|
+
`;
|
|
6531
|
+
if (businessFlow.preconditions?.length > 0) content += `**\u{524D}\u{7F6E}\u{6761}\u{4EF6}**: ${businessFlow.preconditions.join("\u3001")}\n`;
|
|
6532
|
+
content += `**\u{4E3B}\u{6D41}\u{7A0B}**:
|
|
6533
|
+
${businessFlow.mainFlow.map((step, i)=>`${i + 1}. ${step}`).join("\n")}\n`;
|
|
6534
|
+
if (businessFlow.exceptionFlows?.length > 0) content += `**\u{5F02}\u{5E38}\u{5904}\u{7406}**: ${businessFlow.exceptionFlows.join("\u3001")}\n`;
|
|
6535
|
+
}
|
|
6536
|
+
if (dataEntities.length > 0) {
|
|
6537
|
+
content += `
|
|
6538
|
+
|
|
6539
|
+
### \u{6570}\u{636E}\u{5B9E}\u{4F53}
|
|
6540
|
+
`;
|
|
6541
|
+
dataEntities.forEach((entity)=>{
|
|
6542
|
+
content += `**${entity.name}**:\n`;
|
|
6543
|
+
if (entity.fields?.length > 0) {
|
|
6544
|
+
content += `| \u{5B57}\u{6BB5}\u{540D} | \u{7C7B}\u{578B} | \u{5FC5}\u{586B} | \u{8BF4}\u{660E} |
|
|
6545
|
+
|---|---|---|---|
|
|
6546
|
+
`;
|
|
6547
|
+
entity.fields.forEach((field)=>{
|
|
6548
|
+
content += `| ${field.name} | ${field.type} | ${field.required ? "\u662F" : "\u5426"} | ${field.description} |\n`;
|
|
6549
|
+
});
|
|
6550
|
+
}
|
|
6551
|
+
});
|
|
6552
|
+
}
|
|
6553
|
+
if (interactions.length > 0) {
|
|
6554
|
+
content += `
|
|
6555
|
+
|
|
6556
|
+
### \u{4EA4}\u{4E92}\u{903B}\u{8F91}
|
|
6557
|
+
`;
|
|
6558
|
+
interactions.forEach((interaction)=>{
|
|
6559
|
+
content += `- **\u{89E6}\u{53D1}**: ${interaction.trigger} \u{2192} **\u{52A8}\u{4F5C}**: ${interaction.action} \u{2192} **\u{54CD}\u{5E94}**: ${interaction.response}\n`;
|
|
6560
|
+
});
|
|
6561
|
+
}
|
|
6562
|
+
return content;
|
|
6563
|
+
}).join("\n\n---\n\n");
|
|
6314
6564
|
return `# ${featureName} - \u{7EDF}\u{4E00}\u{9700}\u{6C42}\u{5206}\u{6790}
|
|
6315
6565
|
|
|
6316
6566
|
## \u{9879}\u{76EE}\u{57FA}\u{672C}\u{4FE1}\u{606F}
|
|
6317
6567
|
- **\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"}
|
|
6568
|
+
- **\u{4E3B}\u{8981}\u{6280}\u{672F}\u{6808}**: ${projectInfo?.techStack?.join(", ") || enrichedContext.techStack?.join(", ") || "\u5F85\u786E\u5B9A"}
|
|
6319
6569
|
- **\u{5F00}\u{53D1}\u{6846}\u{67B6}**: ${projectInfo?.frameworks?.join(", ") || "\u5F85\u786E\u5B9A"}
|
|
6320
6570
|
- **\u{7F16}\u{7A0B}\u{8BED}\u{8A00}**: ${projectInfo?.language || "\u5F85\u786E\u5B9A"}
|
|
6571
|
+
- **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: ${enrichedContext.businessDomain || "\u901A\u7528"}
|
|
6572
|
+
|
|
6573
|
+
## \u{4E1A}\u{52A1}\u{80CC}\u{666F}
|
|
6574
|
+
${businessContext.background || "\u57FA\u4E8E\u7528\u6237\u9700\u6C42\u8FDB\u884C\u529F\u80FD\u5F00\u53D1"}
|
|
6575
|
+
|
|
6576
|
+
### \u{4E1A}\u{52A1}\u{76EE}\u{6807}
|
|
6577
|
+
${businessContext.objectives?.map((obj)=>`- ${obj}`).join("\n") || "- \u6EE1\u8DB3\u7528\u6237\u9700\u6C42\n- \u63D0\u5347\u7CFB\u7EDF\u529F\u80FD"}
|
|
6578
|
+
|
|
6579
|
+
### \u{6D89}\u{53CA}\u{89D2}\u{8272}
|
|
6580
|
+
${businessContext.stakeholders?.map((role)=>`- ${role}`).join("\n") || "- \u7CFB\u7EDF\u7528\u6237\n- \u7CFB\u7EDF\u7BA1\u7406\u5458"}
|
|
6321
6581
|
|
|
6322
6582
|
## \u{9700}\u{6C42}\u{7C7B}\u{578B}\u{5206}\u{6790}
|
|
6323
6583
|
- **\u{8BC6}\u{522B}\u{7C7B}\u{578B}**: ${analysis.requirementType}
|
|
@@ -6325,6 +6585,17 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6325
6585
|
- **\u{529F}\u{80FD}\u{70B9}\u{6570}\u{91CF}**: ${featuresToProcess.length}\u{4E2A}
|
|
6326
6586
|
- **\u{7F6E}\u{4FE1}\u{5EA6}**: ${analysis.confidence || "medium"}
|
|
6327
6587
|
|
|
6588
|
+
## \u{6280}\u{672F}\u{4E0A}\u{4E0B}\u{6587}
|
|
6589
|
+
- **\u{5EFA}\u{8BAE}\u{6280}\u{672F}\u{6808}**: ${technicalContext.suggestedTechStack?.join(", ") || "\u6839\u636E\u9879\u76EE\u73B0\u6709\u6280\u672F\u6808"}
|
|
6590
|
+
- **\u{96C6}\u{6210}\u{70B9}**: ${technicalContext.integrationPoints?.join(", ") || "\u65E0"}
|
|
6591
|
+
- **\u{5B89}\u{5168}\u{8981}\u{6C42}**: ${technicalContext.securityRequirements?.join(", ") || "\u6807\u51C6\u5B89\u5168\u89C4\u8303"}
|
|
6592
|
+
- **\u{6027}\u{80FD}\u{8981}\u{6C42}**: ${technicalContext.performanceRequirements?.join(", ") || "\u6807\u51C6\u6027\u80FD\u8981\u6C42"}
|
|
6593
|
+
|
|
6594
|
+
## \u{6587}\u{6863}\u{751F}\u{6210}\u{63D0}\u{793A}
|
|
6595
|
+
- **\u{9700}\u{8981}\u{7684}\u{65F6}\u{5E8F}\u{56FE}**: ${documentationHints.keySequenceDiagrams?.join(", ") || "\u4E3B\u6D41\u7A0B\u65F6\u5E8F\u56FE"}
|
|
6596
|
+
- **\u{9700}\u{8981}\u{7684}ER\u{56FE}**: ${documentationHints.keyERDiagrams?.join(", ") || "\u6838\u5FC3\u6570\u636E\u5B9E\u4F53"}
|
|
6597
|
+
- **\u{9700}\u{8981}\u{7684}\u{8868}\u{683C}**: ${documentationHints.keyTables?.join(", ") || "\u5B57\u6BB5\u8BF4\u660E\u8868\u3001\u63A5\u53E3\u53C2\u6570\u8868"}
|
|
6598
|
+
|
|
6328
6599
|
## \u{529F}\u{80FD}\u{70B9}\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}
|
|
6329
6600
|
|
|
6330
6601
|
${combinedFeatureContent}
|
|
@@ -7010,14 +7281,14 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7010
7281
|
async analyzeRequirements(params) {
|
|
7011
7282
|
try {
|
|
7012
7283
|
logger.info("\u5F00\u59CB\u9700\u6C42\u5206\u6790\u6D41\u7A0B", {
|
|
7013
|
-
|
|
7014
|
-
|
|
7284
|
+
projectPath: params.current_project_path,
|
|
7285
|
+
hasPageStyle: !!params.page_style
|
|
7015
7286
|
});
|
|
7016
|
-
const { requirementContent, projectInfo } = this.parseRequirementAnalysis(params.requirement_analysis);
|
|
7287
|
+
const { requirementContent, projectInfo, enrichedContext } = this.parseRequirementAnalysis(params.requirement_analysis);
|
|
7017
7288
|
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);
|
|
7289
|
+
requirementAnalysis.requirementType = "PC+API";
|
|
7290
|
+
requirementAnalysis.enrichedContext = enrichedContext;
|
|
7291
|
+
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
7292
|
} catch (error) {
|
|
7022
7293
|
if (error instanceof RequirementAnalysisError) throw error;
|
|
7023
7294
|
logger.error("\u9700\u6C42\u5206\u6790\u6D41\u7A0B\u5931\u8D25", {
|
|
@@ -7033,15 +7304,32 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7033
7304
|
parseRequirementAnalysis(analysisResult) {
|
|
7034
7305
|
try {
|
|
7035
7306
|
const parsed = JSON.parse(analysisResult);
|
|
7307
|
+
const enrichedContext = {
|
|
7308
|
+
originalRequirement: parsed.requirement_description || parsed.data?.guidance || "",
|
|
7309
|
+
techStack: parsed.project_context?.techStack || [],
|
|
7310
|
+
codeStructure: parsed.project_context?.codeStructure || {},
|
|
7311
|
+
businessDomain: parsed.project_context?.businessDomain || "\u901A\u7528",
|
|
7312
|
+
relatedFiles: parsed.project_context?.relatedFiles || [],
|
|
7313
|
+
dependencies: parsed.project_context?.dependencies || []
|
|
7314
|
+
};
|
|
7036
7315
|
return {
|
|
7037
7316
|
requirementContent: parsed.requirement_description || parsed.data?.guidance || analysisResult,
|
|
7038
|
-
projectInfo: parsed.project_context || this.getDefaultProjectInfo()
|
|
7317
|
+
projectInfo: parsed.project_context || this.getDefaultProjectInfo(),
|
|
7318
|
+
enrichedContext
|
|
7039
7319
|
};
|
|
7040
7320
|
} catch {
|
|
7041
7321
|
logger.info("\u4F7F\u7528\u6587\u672C\u683C\u5F0F\u7684\u9700\u6C42\u5206\u6790\u7ED3\u679C");
|
|
7042
7322
|
return {
|
|
7043
7323
|
requirementContent: analysisResult,
|
|
7044
|
-
projectInfo: this.getDefaultProjectInfo()
|
|
7324
|
+
projectInfo: this.getDefaultProjectInfo(),
|
|
7325
|
+
enrichedContext: {
|
|
7326
|
+
originalRequirement: analysisResult,
|
|
7327
|
+
techStack: [],
|
|
7328
|
+
codeStructure: {},
|
|
7329
|
+
businessDomain: "\u901A\u7528",
|
|
7330
|
+
relatedFiles: [],
|
|
7331
|
+
dependencies: []
|
|
7332
|
+
}
|
|
7045
7333
|
};
|
|
7046
7334
|
}
|
|
7047
7335
|
}
|
|
@@ -7170,23 +7458,177 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7170
7458
|
};
|
|
7171
7459
|
}
|
|
7172
7460
|
}
|
|
7461
|
+
const DEFAULT_PAGE_STYLE = `<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
|
7462
|
+
<style>
|
|
7463
|
+
:root {
|
|
7464
|
+
--bg: #ffffff;
|
|
7465
|
+
--bg-secondary: #f8f9fa;
|
|
7466
|
+
--border: #e5e5e5;
|
|
7467
|
+
--text: #111111;
|
|
7468
|
+
--text-muted: #666666;
|
|
7469
|
+
--accent: #000000;
|
|
7470
|
+
}
|
|
7471
|
+
</style>`;
|
|
7472
|
+
const API_SECTIONS = [
|
|
7473
|
+
{
|
|
7474
|
+
id: "header",
|
|
7475
|
+
title: "\u6587\u6863\u5934\u90E8",
|
|
7476
|
+
prompt: "\u751F\u6210\u6587\u6863\u6807\u9898\u3001\u751F\u6210\u65F6\u95F4\u3001\u4E1A\u52A1\u9886\u57DF\u7B49\u5934\u90E8\u4FE1\u606F"
|
|
7477
|
+
},
|
|
7478
|
+
{
|
|
7479
|
+
id: "background",
|
|
7480
|
+
title: "\u9700\u6C42\u80CC\u666F",
|
|
7481
|
+
prompt: "\u751F\u6210\u9700\u6C42\u80CC\u666F\u3001\u5173\u952E\u529F\u80FD\u3001\u6D89\u53CA\u89D2\u8272"
|
|
7482
|
+
},
|
|
7483
|
+
{
|
|
7484
|
+
id: "design",
|
|
7485
|
+
title: "\u529F\u80FD\u8BBE\u8BA1\u8BF4\u660E",
|
|
7486
|
+
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"
|
|
7487
|
+
},
|
|
7488
|
+
{
|
|
7489
|
+
id: "dataModel",
|
|
7490
|
+
title: "\u6570\u636E\u5EFA\u6A21",
|
|
7491
|
+
prompt: "\u751F\u6210ER\u903B\u8F91\u56FE\u8BBE\u8BA1\uFF08\u4F7F\u7528mermaid erDiagram\uFF09\u548C\u6570\u636E\u8868\u5B9E\u4F53\u8BBE\u8BA1"
|
|
7492
|
+
},
|
|
7493
|
+
{
|
|
7494
|
+
id: "apiDesign",
|
|
7495
|
+
title: "API\u63A5\u53E3\u8BBE\u8BA1",
|
|
7496
|
+
prompt: "\u751F\u6210API\u63A5\u53E3\u5217\u8868\u3001\u8BF7\u6C42\u53C2\u6570\u3001\u54CD\u5E94\u53C2\u6570\u3001\u9519\u8BEF\u7801\u7B49"
|
|
7497
|
+
},
|
|
7498
|
+
{
|
|
7499
|
+
id: "sequence",
|
|
7500
|
+
title: "\u4E1A\u52A1\u65F6\u5E8F\u56FE",
|
|
7501
|
+
prompt: "\u751F\u6210\u4E1A\u52A1\u5BF9\u8C61\u65F6\u5E8F\u56FE\uFF08\u4F7F\u7528mermaid sequenceDiagram\uFF09"
|
|
7502
|
+
},
|
|
7503
|
+
{
|
|
7504
|
+
id: "status",
|
|
7505
|
+
title: "\u4E1A\u52A1\u72B6\u6001",
|
|
7506
|
+
prompt: "\u751F\u6210\u4E1A\u52A1\u72B6\u6001\u63CF\u8FF0\u8868\u683C"
|
|
7507
|
+
},
|
|
7508
|
+
{
|
|
7509
|
+
id: "pseudocode",
|
|
7510
|
+
title: "\u4F2A\u4EE3\u7801\u793A\u4F8B",
|
|
7511
|
+
prompt: "\u751F\u6210\u6838\u5FC3\u4E1A\u52A1\u903B\u8F91\u7684\u4F2A\u4EE3\u7801\u793A\u4F8B"
|
|
7512
|
+
}
|
|
7513
|
+
];
|
|
7514
|
+
class ConcurrencyLimiter {
|
|
7515
|
+
maxConcurrent;
|
|
7516
|
+
running = 0;
|
|
7517
|
+
queue = [];
|
|
7518
|
+
constructor(maxConcurrent){
|
|
7519
|
+
this.maxConcurrent = maxConcurrent;
|
|
7520
|
+
}
|
|
7521
|
+
async run(fn) {
|
|
7522
|
+
while(this.running >= this.maxConcurrent)await new Promise((resolve)=>this.queue.push(resolve));
|
|
7523
|
+
this.running++;
|
|
7524
|
+
try {
|
|
7525
|
+
return await fn();
|
|
7526
|
+
} finally{
|
|
7527
|
+
this.running--;
|
|
7528
|
+
const next = this.queue.shift();
|
|
7529
|
+
if (next) next();
|
|
7530
|
+
}
|
|
7531
|
+
}
|
|
7532
|
+
}
|
|
7533
|
+
const apiLimiter = new ConcurrencyLimiter(18);
|
|
7534
|
+
async function generateApiSection(sectionDef, templateVariables) {
|
|
7535
|
+
return apiLimiter.run(async ()=>{
|
|
7536
|
+
try {
|
|
7537
|
+
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}
|
|
7538
|
+
|
|
7539
|
+
## \u{4EFB}\u{52A1}
|
|
7540
|
+
${sectionDef.prompt}
|
|
7541
|
+
|
|
7542
|
+
## \u{9700}\u{6C42}\u{4FE1}\u{606F}
|
|
7543
|
+
- \u{529F}\u{80FD}\u{540D}\u{79F0}: ${templateVariables.featureName}
|
|
7544
|
+
- \u{4E1A}\u{52A1}\u{9886}\u{57DF}: ${templateVariables.businessDomain}
|
|
7545
|
+
- \u{9700}\u{6C42}\u{8BE6}\u{60C5}: ${templateVariables.inputContent?.substring(0, 1500) || ''}
|
|
7546
|
+
|
|
7547
|
+
## \u{8981}\u{6C42}
|
|
7548
|
+
- \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}
|
|
7549
|
+
- \u{4F7F}\u{7528}\u{6B63}\u{786E}\u{7684}Markdown\u{683C}\u{5F0F}
|
|
7550
|
+
- \u{5982}\u{9700}\u{56FE}\u{8868}\u{4F7F}\u{7528}mermaid\u{8BED}\u{6CD5}
|
|
7551
|
+
- \u{8868}\u{683C}\u{586B}\u{5199}\u{5177}\u{4F53}\u{4FE1}\u{606F}
|
|
7552
|
+
|
|
7553
|
+
\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}`;
|
|
7554
|
+
const content = await openAIService.generateText({
|
|
7555
|
+
prompt,
|
|
7556
|
+
system_prompt: "\u4F60\u662F\u6280\u672F\u6587\u6863\u4E13\u5BB6\uFF0C\u8F93\u51FA\u7B80\u6D01\u4E13\u4E1A\u7684\u6587\u6863\u7AE0\u8282\u3002",
|
|
7557
|
+
temperature: 0.7
|
|
7558
|
+
});
|
|
7559
|
+
return {
|
|
7560
|
+
id: sectionDef.id,
|
|
7561
|
+
title: sectionDef.title,
|
|
7562
|
+
content,
|
|
7563
|
+
success: true
|
|
7564
|
+
};
|
|
7565
|
+
} catch (error) {
|
|
7566
|
+
return {
|
|
7567
|
+
id: sectionDef.id,
|
|
7568
|
+
title: sectionDef.title,
|
|
7569
|
+
content: "",
|
|
7570
|
+
success: false,
|
|
7571
|
+
error: error.message
|
|
7572
|
+
};
|
|
7573
|
+
}
|
|
7574
|
+
});
|
|
7575
|
+
}
|
|
7576
|
+
async function generateInteractiveHtml(templateVariables) {
|
|
7577
|
+
const { featureName, businessDomain, pageType, pageStyle, inputContent } = templateVariables;
|
|
7578
|
+
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}
|
|
7579
|
+
|
|
7580
|
+
## \u{9700}\u{6C42}\u{4FE1}\u{606F}
|
|
7581
|
+
- \u{529F}\u{80FD}\u{540D}\u{79F0}: ${featureName}
|
|
7582
|
+
- \u{4E1A}\u{52A1}\u{9886}\u{57DF}: ${businessDomain}
|
|
7583
|
+
- \u{9875}\u{9762}\u{7C7B}\u{578B}: ${pageType || 'responsive'}
|
|
7584
|
+
- \u{9700}\u{6C42}\u{8BE6}\u{60C5}:
|
|
7585
|
+
${inputContent || ''}
|
|
7586
|
+
|
|
7587
|
+
## \u{9875}\u{9762}\u{98CE}\u{683C}\u{8981}\u{6C42}
|
|
7588
|
+
\u{5728}<head>\u{4E2D}\u{5305}\u{542B}\u{4EE5}\u{4E0B}\u{6837}\u{5F0F}\u{914D}\u{7F6E}\u{FF1A}
|
|
7589
|
+
${pageStyle}
|
|
7590
|
+
|
|
7591
|
+
## \u{6280}\u{672F}\u{8981}\u{6C42}
|
|
7592
|
+
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>
|
|
7593
|
+
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}
|
|
7594
|
+
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}
|
|
7595
|
+
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}
|
|
7596
|
+
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}
|
|
7597
|
+
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}
|
|
7598
|
+
7. \u{6240}\u{6709}\u{6587}\u{672C}\u{4F7F}\u{7528}\u{4E2D}\u{6587}
|
|
7599
|
+
8. \u{8BBE}\u{8BA1}\u{7F8E}\u{89C2}\u{3001}\u{73B0}\u{4EE3}\u{3001}\u{7B80}\u{6D01}
|
|
7600
|
+
|
|
7601
|
+
## \u{8F93}\u{51FA}\u{8981}\u{6C42}
|
|
7602
|
+
\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}`;
|
|
7603
|
+
const html = await openAIService.generateText({
|
|
7604
|
+
prompt,
|
|
7605
|
+
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",
|
|
7606
|
+
temperature: 0.7
|
|
7607
|
+
});
|
|
7608
|
+
let cleanHtml = html.trim();
|
|
7609
|
+
if (cleanHtml.startsWith("```html")) cleanHtml = cleanHtml.slice(7);
|
|
7610
|
+
else if (cleanHtml.startsWith("```")) cleanHtml = cleanHtml.slice(3);
|
|
7611
|
+
if (cleanHtml.endsWith("```")) cleanHtml = cleanHtml.slice(0, -3);
|
|
7612
|
+
return cleanHtml.trim();
|
|
7613
|
+
}
|
|
7173
7614
|
const requirementAnalyzerTool = {
|
|
7174
|
-
name: "
|
|
7175
|
-
description:
|
|
7615
|
+
name: "requirement-analyzer-report",
|
|
7616
|
+
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
7617
|
inputSchema: {
|
|
7177
7618
|
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
7619
|
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")
|
|
7620
|
+
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"),
|
|
7621
|
+
page_type: enumType([
|
|
7622
|
+
"pc",
|
|
7623
|
+
"mobile",
|
|
7624
|
+
"responsive"
|
|
7625
|
+
]).default("responsive").describe("页面类型(可选):\n- pc: PC端页面\n- mobile: 移动端页面\n- responsive: 响应式页面(默认,同时支持PC和移动端)")
|
|
7186
7626
|
},
|
|
7187
7627
|
handler: async (args)=>{
|
|
7188
7628
|
try {
|
|
7189
|
-
const { requirement_analysis, current_project_path,
|
|
7629
|
+
const { requirement_analysis, current_project_path, page_style, page_type } = args;
|
|
7630
|
+
const finalPageStyle = page_style || DEFAULT_PAGE_STYLE;
|
|
7631
|
+
const finalPageType = page_type || "responsive";
|
|
7190
7632
|
if (!requirement_analysis || !current_project_path) return {
|
|
7191
7633
|
content: [
|
|
7192
7634
|
{
|
|
@@ -7204,20 +7646,131 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7204
7646
|
const serviceResult = await service.analyzeRequirements({
|
|
7205
7647
|
requirement_analysis,
|
|
7206
7648
|
current_project_path,
|
|
7207
|
-
|
|
7649
|
+
page_style: finalPageStyle,
|
|
7650
|
+
page_type: finalPageType
|
|
7651
|
+
});
|
|
7652
|
+
const generationTasks = serviceResult.generationTasks || [];
|
|
7653
|
+
if (0 === generationTasks.length) return {
|
|
7654
|
+
content: [
|
|
7655
|
+
{
|
|
7656
|
+
type: "text",
|
|
7657
|
+
text: JSON.stringify({
|
|
7658
|
+
success: false,
|
|
7659
|
+
message: "\u6CA1\u6709\u751F\u6210\u4EFB\u52A1",
|
|
7660
|
+
data: null
|
|
7661
|
+
})
|
|
7662
|
+
}
|
|
7663
|
+
],
|
|
7664
|
+
isError: true
|
|
7665
|
+
};
|
|
7666
|
+
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}...`);
|
|
7667
|
+
const startTime = Date.now();
|
|
7668
|
+
const apiTask = generationTasks.find((t)=>"API" === t.requirementType);
|
|
7669
|
+
const htmlTask = generationTasks.find((t)=>"HTML" === t.requirementType);
|
|
7670
|
+
const results = [];
|
|
7671
|
+
const parallelTasks = [];
|
|
7672
|
+
if (apiTask) {
|
|
7673
|
+
const apiPromise = (async ()=>{
|
|
7674
|
+
try {
|
|
7675
|
+
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}`);
|
|
7676
|
+
const sectionResults = await Promise.all(API_SECTIONS.map((section)=>generateApiSection(section, apiTask.templateVariables)));
|
|
7677
|
+
const successSections = sectionResults.filter((r)=>r.success);
|
|
7678
|
+
const header = `# ${apiTask.templateVariables.featureName} - API\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
|
|
7679
|
+
|
|
7680
|
+
> **\u{751F}\u{6210}\u{65F6}\u{95F4}**: ${new Date().toISOString()}
|
|
7681
|
+
> **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: ${apiTask.templateVariables.businessDomain}
|
|
7682
|
+
|
|
7683
|
+
---
|
|
7684
|
+
|
|
7685
|
+
`;
|
|
7686
|
+
const document = header + successSections.map((s)=>s.content).join("\n\n---\n\n");
|
|
7687
|
+
const outputDir = external_path_default().dirname(apiTask.outputPath);
|
|
7688
|
+
await promises_namespaceObject.mkdir(outputDir, {
|
|
7689
|
+
recursive: true
|
|
7690
|
+
});
|
|
7691
|
+
await promises_namespaceObject.writeFile(apiTask.outputPath, document, "utf-8");
|
|
7692
|
+
results.push({
|
|
7693
|
+
type: "API",
|
|
7694
|
+
content: document,
|
|
7695
|
+
outputPath: apiTask.outputPath,
|
|
7696
|
+
success: true
|
|
7697
|
+
});
|
|
7698
|
+
logger.info(`API\u{6587}\u{6863}\u{751F}\u{6210}\u{5B8C}\u{6210}`, {
|
|
7699
|
+
length: document.length
|
|
7700
|
+
});
|
|
7701
|
+
} catch (error) {
|
|
7702
|
+
results.push({
|
|
7703
|
+
type: "API",
|
|
7704
|
+
content: "",
|
|
7705
|
+
outputPath: apiTask.outputPath,
|
|
7706
|
+
success: false,
|
|
7707
|
+
error: error.message
|
|
7708
|
+
});
|
|
7709
|
+
}
|
|
7710
|
+
})();
|
|
7711
|
+
parallelTasks.push(apiPromise);
|
|
7712
|
+
}
|
|
7713
|
+
if (htmlTask) {
|
|
7714
|
+
const htmlPromise = (async ()=>{
|
|
7715
|
+
try {
|
|
7716
|
+
logger.info(`\u{5F00}\u{59CB}\u{751F}\u{6210}\u{53EF}\u{4EA4}\u{4E92}HTML\u{9875}\u{9762}`);
|
|
7717
|
+
const htmlOutputPath = htmlTask.outputPath.replace(/\.md$/, ".html");
|
|
7718
|
+
const htmlContent = await generateInteractiveHtml(htmlTask.templateVariables);
|
|
7719
|
+
const outputDir = external_path_default().dirname(htmlOutputPath);
|
|
7720
|
+
await promises_namespaceObject.mkdir(outputDir, {
|
|
7721
|
+
recursive: true
|
|
7722
|
+
});
|
|
7723
|
+
await promises_namespaceObject.writeFile(htmlOutputPath, htmlContent, "utf-8");
|
|
7724
|
+
results.push({
|
|
7725
|
+
type: "HTML",
|
|
7726
|
+
content: htmlContent,
|
|
7727
|
+
outputPath: htmlOutputPath,
|
|
7728
|
+
success: true
|
|
7729
|
+
});
|
|
7730
|
+
logger.info(`HTML\u{9875}\u{9762}\u{751F}\u{6210}\u{5B8C}\u{6210}`, {
|
|
7731
|
+
length: htmlContent.length
|
|
7732
|
+
});
|
|
7733
|
+
} catch (error) {
|
|
7734
|
+
results.push({
|
|
7735
|
+
type: "HTML",
|
|
7736
|
+
content: "",
|
|
7737
|
+
outputPath: htmlTask.outputPath,
|
|
7738
|
+
success: false,
|
|
7739
|
+
error: error.message
|
|
7740
|
+
});
|
|
7741
|
+
}
|
|
7742
|
+
})();
|
|
7743
|
+
parallelTasks.push(htmlPromise);
|
|
7744
|
+
}
|
|
7745
|
+
await Promise.all(parallelTasks);
|
|
7746
|
+
const totalDuration = Date.now() - startTime;
|
|
7747
|
+
const successCount = results.filter((r)=>r.success).length;
|
|
7748
|
+
const failedCount = results.filter((r)=>!r.success).length;
|
|
7749
|
+
const generatedFiles = results.filter((r)=>r.success).map((r)=>r.outputPath);
|
|
7750
|
+
logger.info(`\u{5E76}\u{884C}\u{751F}\u{6210}\u{5B8C}\u{6210}`, {
|
|
7751
|
+
total: results.length,
|
|
7752
|
+
success: successCount,
|
|
7753
|
+
failed: failedCount,
|
|
7754
|
+
totalDuration: `${totalDuration}ms`
|
|
7208
7755
|
});
|
|
7209
7756
|
return {
|
|
7210
7757
|
content: [
|
|
7211
7758
|
{
|
|
7212
7759
|
type: "text",
|
|
7213
7760
|
text: JSON.stringify({
|
|
7214
|
-
success:
|
|
7215
|
-
message:
|
|
7761
|
+
success: successCount > 0,
|
|
7762
|
+
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
7763
|
data: {
|
|
7217
7764
|
outputPath: serviceResult.outputPath,
|
|
7218
|
-
generatedFiles
|
|
7765
|
+
generatedFiles,
|
|
7219
7766
|
analysisInfo: serviceResult.analysisInfo || {},
|
|
7220
|
-
|
|
7767
|
+
results: results.map((r)=>({
|
|
7768
|
+
type: r.type,
|
|
7769
|
+
outputPath: r.outputPath,
|
|
7770
|
+
success: r.success,
|
|
7771
|
+
error: r.error,
|
|
7772
|
+
contentLength: r.content?.length || 0
|
|
7773
|
+
}))
|
|
7221
7774
|
}
|
|
7222
7775
|
})
|
|
7223
7776
|
}
|
|
@@ -7605,202 +8158,6 @@ ${requirementSection}
|
|
|
7605
8158
|
}
|
|
7606
8159
|
const external_sharp_namespaceObject = require("sharp");
|
|
7607
8160
|
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
|
-
}
|
|
7803
|
-
}
|
|
7804
8161
|
class ImageAnalysisError extends Error {
|
|
7805
8162
|
code;
|
|
7806
8163
|
context;
|
|
@@ -7837,7 +8194,7 @@ ${requirementSection}
|
|
|
7837
8194
|
});
|
|
7838
8195
|
await this.validateParams(imagePath);
|
|
7839
8196
|
const basicInfo = await this.getImageBasicInfo(imagePath);
|
|
7840
|
-
const analysisContent = await this.performAIAnalysis(imagePath,
|
|
8197
|
+
const analysisContent = await this.performAIAnalysis(imagePath, context);
|
|
7841
8198
|
const processingTime = Date.now() - startTime;
|
|
7842
8199
|
if (!analysisContent) throw new ImageAnalysisError("AI\u5206\u6790\u8FD4\u56DE\u7A7A\u7ED3\u679C", types_AnalysisErrorCodes.ANALYSIS_FAILED, {
|
|
7843
8200
|
params: {
|
|
@@ -7864,16 +8221,15 @@ ${requirementSection}
|
|
|
7864
8221
|
throw error;
|
|
7865
8222
|
}
|
|
7866
8223
|
}
|
|
7867
|
-
async performAIAnalysis(imagePath,
|
|
8224
|
+
async performAIAnalysis(imagePath, context) {
|
|
7868
8225
|
try {
|
|
7869
|
-
const imageBase64 = await this.imageToBase64(imagePath);
|
|
7870
8226
|
const systemPrompt = `You must interpret and analyze images strictly according to the assigned task.
|
|
7871
8227
|
When an image placeholder is provided, your role is to parse the image content only within the scope of the user's instructions.
|
|
7872
8228
|
Do not ignore or deviate from the task.
|
|
7873
8229
|
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
|
-
|
|
8230
|
+
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`;
|
|
8231
|
+
const aiResponse = await openAIService.analyzeImageWithPath({
|
|
8232
|
+
image_path: imagePath,
|
|
7877
8233
|
prompt: userPrompt,
|
|
7878
8234
|
system_prompt: systemPrompt
|
|
7879
8235
|
});
|
|
@@ -7883,26 +8239,15 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7883
8239
|
tags: []
|
|
7884
8240
|
};
|
|
7885
8241
|
} catch (error) {
|
|
7886
|
-
logger.
|
|
8242
|
+
logger.error("AI\u5206\u6790\u5931\u8D25", {
|
|
7887
8243
|
error,
|
|
7888
8244
|
params: {
|
|
7889
8245
|
image_path: imagePath
|
|
7890
8246
|
}
|
|
7891
8247
|
});
|
|
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
|
-
}
|
|
8248
|
+
throw new ImageAnalysisError("\u8BC6\u522B\u56FE\u7247\u5931\u8D25", types_AnalysisErrorCodes.ANALYSIS_FAILED, {
|
|
8249
|
+
originalError: error
|
|
8250
|
+
});
|
|
7906
8251
|
}
|
|
7907
8252
|
}
|
|
7908
8253
|
async getImageBasicInfo(imagePath) {
|
|
@@ -7911,7 +8256,7 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7911
8256
|
const stats = await promises_namespaceObject.stat(imagePath);
|
|
7912
8257
|
return {
|
|
7913
8258
|
path: imagePath,
|
|
7914
|
-
format: metadata.format ||
|
|
8259
|
+
format: metadata.format || "unknown",
|
|
7915
8260
|
dimensions: {
|
|
7916
8261
|
width: metadata.width || 0,
|
|
7917
8262
|
height: metadata.height || 0
|
|
@@ -7925,37 +8270,6 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7925
8270
|
});
|
|
7926
8271
|
}
|
|
7927
8272
|
}
|
|
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
8273
|
async validateParams(imagePath) {
|
|
7960
8274
|
try {
|
|
7961
8275
|
await promises_namespaceObject.access(imagePath);
|
|
@@ -7970,81 +8284,17 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7970
8284
|
supportedFormats: SUPPORTED_IMAGE_FORMATS
|
|
7971
8285
|
});
|
|
7972
8286
|
}
|
|
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
8287
|
}
|
|
8038
8288
|
const ImageAnalysisParamsSchema = objectType({
|
|
8039
8289
|
image_path: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
8040
|
-
context: stringType().
|
|
8290
|
+
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
8291
|
});
|
|
8042
8292
|
const read_imageTool = {
|
|
8043
8293
|
name: "read_image",
|
|
8044
8294
|
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
8295
|
inputSchema: {
|
|
8046
8296
|
image_path: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
8047
|
-
context: stringType().
|
|
8297
|
+
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
8298
|
},
|
|
8049
8299
|
handler: async (args)=>{
|
|
8050
8300
|
const analyzer = new ImageAnalyzer();
|
|
@@ -8370,7 +8620,7 @@ ${error?.message || "\u672A\u77E5\u9519\u8BEF"}`;
|
|
|
8370
8620
|
output_directory: stringType().optional().describe("\u8F93\u51FA\u76EE\u5F55\uFF0C\u4E0D\u6307\u5B9A\u5219\u5728\u539F\u6587\u4EF6\u76EE\u5F55\u751F\u6210")
|
|
8371
8621
|
});
|
|
8372
8622
|
const imageConverterTool = {
|
|
8373
|
-
name: "
|
|
8623
|
+
name: "image-converter",
|
|
8374
8624
|
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
8625
|
inputSchema: {
|
|
8376
8626
|
input_paths: unionType([
|
|
@@ -8462,7 +8712,7 @@ ${results.map((r, index)=>`
|
|
|
8462
8712
|
- **\u{8F93}\u{51FA}**: \`${r.output_path}\`
|
|
8463
8713
|
- **\u{683C}\u{5F0F}**: ${r.format?.toUpperCase()}
|
|
8464
8714
|
- **\u{5C3A}\u{5BF8}**: ${r.dimensions?.width} \xd7 ${r.dimensions?.height}
|
|
8465
|
-
- **\u{6587}\u{4EF6}\u{5927}\u{5C0F}**: ${
|
|
8715
|
+
- **\u{6587}\u{4EF6}\u{5927}\u{5C0F}**: ${formatFileSize(r.file_size || 0)}
|
|
8466
8716
|
`).join("")}
|
|
8467
8717
|
|
|
8468
8718
|
${args.width || args.height ? `
|
|
@@ -8498,7 +8748,7 @@ ${successResults.map((r, index)=>`
|
|
|
8498
8748
|
${index + 1}. **${getFileName(r.input_path)}**
|
|
8499
8749
|
- \u{8F93}\u{51FA}: \`${r.output_path}\`
|
|
8500
8750
|
- \u{5C3A}\u{5BF8}: ${r.dimensions?.width} \xd7 ${r.dimensions?.height}
|
|
8501
|
-
- \u{5927}\u{5C0F}: ${
|
|
8751
|
+
- \u{5927}\u{5C0F}: ${formatFileSize(r.file_size || 0)}
|
|
8502
8752
|
`).join("")}
|
|
8503
8753
|
|
|
8504
8754
|
## \u{274C} \u{8F6C}\u{6362}\u{5931}\u{8D25} (${failedResults.length}\u{5F20})
|
|
@@ -8565,7 +8815,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
8565
8815
|
function getFileName(filePath) {
|
|
8566
8816
|
return filePath.split("/").pop() || filePath;
|
|
8567
8817
|
}
|
|
8568
|
-
function
|
|
8818
|
+
function formatFileSize(bytes) {
|
|
8569
8819
|
if (0 === bytes) return "0 B";
|
|
8570
8820
|
const k = 1024;
|
|
8571
8821
|
const sizes = [
|
|
@@ -8636,6 +8886,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
8636
8886
|
RETRY_DELAY_MS: 1000
|
|
8637
8887
|
};
|
|
8638
8888
|
const ImageRecognitionParamsSchema = objectType({
|
|
8889
|
+
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
8890
|
imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
8640
8891
|
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
8892
|
});
|
|
@@ -9043,8 +9294,8 @@ ${getErrorSuggestion(error.code)}
|
|
|
9043
9294
|
}
|
|
9044
9295
|
class analyzer_ImageAnalyzer {
|
|
9045
9296
|
context;
|
|
9046
|
-
async
|
|
9047
|
-
logger.info("ImageAnalyzer: \u5F00\u59CB\u5206\u6790\u957F\u56FE", {
|
|
9297
|
+
async analyzeLongImageStreaming(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference = 'auto', context, onSegmentComplete) {
|
|
9298
|
+
logger.info("ImageAnalyzer: \u5F00\u59CB\u6D41\u5F0F\u5206\u6790\u957F\u56FE", {
|
|
9048
9299
|
imagePath,
|
|
9049
9300
|
totalSegments: segmentConfig.totalSegments,
|
|
9050
9301
|
maxConcurrency: concurrencyConfig.maxConcurrency,
|
|
@@ -9054,24 +9305,36 @@ ${getErrorSuggestion(error.code)}
|
|
|
9054
9305
|
const startTime = Date.now();
|
|
9055
9306
|
const segmentResults = [];
|
|
9056
9307
|
try {
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
const
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9308
|
+
const segments = await this.generateSegments(imagePath, imageInfo, segmentConfig);
|
|
9309
|
+
for(let i = 0; i < segments.length; i++){
|
|
9310
|
+
const { buffer, info } = segments[i];
|
|
9311
|
+
try {
|
|
9312
|
+
const result = await this.analyzeSegment(buffer, info, apiPreference);
|
|
9313
|
+
segmentResults.push(result);
|
|
9314
|
+
if (onSegmentComplete) await onSegmentComplete(result, {
|
|
9315
|
+
current: i + 1,
|
|
9316
|
+
total: segments.length
|
|
9317
|
+
});
|
|
9318
|
+
} catch (error) {
|
|
9319
|
+
logger.error(`\u{6BB5}\u{843D} ${info.index} \u{5206}\u{6790}\u{5931}\u{8D25}`, {
|
|
9320
|
+
error
|
|
9321
|
+
});
|
|
9322
|
+
const errorResult = {
|
|
9323
|
+
segmentIndex: info.index,
|
|
9324
|
+
textContent: '',
|
|
9325
|
+
imageDescription: '',
|
|
9326
|
+
confidence: 0,
|
|
9327
|
+
processingTimeMs: 0,
|
|
9328
|
+
apiUsed: 'none',
|
|
9329
|
+
error: error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"
|
|
9330
|
+
};
|
|
9331
|
+
segmentResults.push(errorResult);
|
|
9332
|
+
if (onSegmentComplete) await onSegmentComplete(errorResult, {
|
|
9333
|
+
current: i + 1,
|
|
9334
|
+
total: segments.length
|
|
9335
|
+
});
|
|
9336
|
+
}
|
|
9337
|
+
}
|
|
9075
9338
|
const summary = this.generateProcessingSummary(segmentResults, startTime);
|
|
9076
9339
|
const result = {
|
|
9077
9340
|
imageInfo,
|
|
@@ -9080,7 +9343,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9080
9343
|
outputPath: '',
|
|
9081
9344
|
success: 0 === summary.failedSegments
|
|
9082
9345
|
};
|
|
9083
|
-
logger.info("\u957F\u56FE\u5206\u6790\u5B8C\u6210", {
|
|
9346
|
+
logger.info("\u957F\u56FE\u6D41\u5F0F\u5206\u6790\u5B8C\u6210", {
|
|
9084
9347
|
imagePath,
|
|
9085
9348
|
totalSegments: summary.totalSegments,
|
|
9086
9349
|
successfulSegments: summary.successfulSegments,
|
|
@@ -9089,7 +9352,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9089
9352
|
});
|
|
9090
9353
|
return result;
|
|
9091
9354
|
} catch (error) {
|
|
9092
|
-
logger.error("\u957F\u56FE\u5206\u6790\u5931\u8D25", {
|
|
9355
|
+
logger.error("\u957F\u56FE\u6D41\u5F0F\u5206\u6790\u5931\u8D25", {
|
|
9093
9356
|
imagePath,
|
|
9094
9357
|
error
|
|
9095
9358
|
});
|
|
@@ -9099,6 +9362,9 @@ ${getErrorSuggestion(error.code)}
|
|
|
9099
9362
|
});
|
|
9100
9363
|
}
|
|
9101
9364
|
}
|
|
9365
|
+
async analyzeLongImage(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference = 'auto', context) {
|
|
9366
|
+
return this.analyzeLongImageStreaming(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference, context);
|
|
9367
|
+
}
|
|
9102
9368
|
async processSegmentsConcurrently(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference) {
|
|
9103
9369
|
const results = [];
|
|
9104
9370
|
const { maxConcurrency, batchSize, delayBetweenBatches } = concurrencyConfig;
|
|
@@ -9278,7 +9544,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9278
9544
|
let prompt = '';
|
|
9279
9545
|
prompt = this.context ? `${this.context}
|
|
9280
9546
|
|
|
9281
|
-
|
|
9547
|
+
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
9548
|
|
|
9283
9549
|
` : `\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
9550
|
|
|
@@ -9296,7 +9562,10 @@ ${getErrorSuggestion(error.code)}
|
|
|
9296
9562
|
else prompt += `\u{8FD9}\u{662F}\u{56FE}\u{7247}\u{7684}\u{4E2D}\u{95F4}\u{90E8}\u{5206}\u{3002}`;
|
|
9297
9563
|
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
9564
|
}
|
|
9299
|
-
prompt += `
|
|
9565
|
+
if (this.context) prompt += `
|
|
9566
|
+
|
|
9567
|
+
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}`;
|
|
9568
|
+
else prompt += `
|
|
9300
9569
|
|
|
9301
9570
|
\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
9571
|
\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 +9671,13 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9402
9671
|
this.configCalculator = new ConfigCalculator();
|
|
9403
9672
|
this.analyzer = new analyzer_ImageAnalyzer();
|
|
9404
9673
|
}
|
|
9405
|
-
async processImage(imagePath, context) {
|
|
9674
|
+
async processImage(imagePath, projectPath, context, callbacks) {
|
|
9406
9675
|
const startTime = Date.now();
|
|
9407
9676
|
logger.info("ImageRecognitionProcessor: \u5F00\u59CB\u5904\u7406\u56FE\u7247", {
|
|
9408
9677
|
imagePath
|
|
9409
9678
|
});
|
|
9679
|
+
let outputPath = '';
|
|
9680
|
+
const segmentResults = [];
|
|
9410
9681
|
try {
|
|
9411
9682
|
await this.validateImageFile(imagePath);
|
|
9412
9683
|
const validation = await this.preprocessor.validateImage(imagePath);
|
|
@@ -9428,55 +9699,51 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9428
9699
|
segmentHeight: segmentConfig.segmentHeight,
|
|
9429
9700
|
maxConcurrency: concurrencyConfig.maxConcurrency
|
|
9430
9701
|
});
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
const totalTime = Date.now() - startTime;
|
|
9434
|
-
logger.info("\u56FE\u7247\u5904\u7406\u5B8C\u6210", {
|
|
9702
|
+
outputPath = await this.initializeOutputFile(imageInfo, segmentConfig.totalSegments, projectPath);
|
|
9703
|
+
callbacks?.onStart?.({
|
|
9435
9704
|
outputPath,
|
|
9705
|
+
totalSegments: segmentConfig.totalSegments,
|
|
9706
|
+
imageInfo
|
|
9707
|
+
});
|
|
9708
|
+
const analysisResult = await this.analyzer.analyzeLongImageStreaming(imagePath, imageInfo, segmentConfig, concurrencyConfig, 'auto', context, async (result, progress)=>{
|
|
9709
|
+
segmentResults.push(result);
|
|
9710
|
+
await this.appendSegmentToFile(outputPath, result);
|
|
9711
|
+
callbacks?.onSegmentComplete?.(result, progress);
|
|
9712
|
+
});
|
|
9713
|
+
await this.finalizeOutputFile(outputPath, analysisResult.summary);
|
|
9714
|
+
const totalTime = Date.now() - startTime;
|
|
9715
|
+
const summary = {
|
|
9436
9716
|
totalSegments: analysisResult.summary.totalSegments,
|
|
9437
9717
|
successfulSegments: analysisResult.summary.successfulSegments,
|
|
9718
|
+
failedSegments: analysisResult.summary.failedSegments,
|
|
9719
|
+
successRate: analysisResult.summary.successRate,
|
|
9720
|
+
totalTextCharacters: analysisResult.summary.totalTextCharacters,
|
|
9721
|
+
totalProcessingTimeMs: totalTime,
|
|
9722
|
+
averageConfidence: analysisResult.summary.averageConfidence
|
|
9723
|
+
};
|
|
9724
|
+
callbacks?.onComplete?.(analysisResult.summary);
|
|
9725
|
+
logger.info("\u56FE\u7247\u5904\u7406\u5B8C\u6210", {
|
|
9726
|
+
outputPath,
|
|
9727
|
+
totalSegments: summary.totalSegments,
|
|
9728
|
+
successfulSegments: summary.successfulSegments,
|
|
9438
9729
|
totalTimeMs: totalTime
|
|
9439
9730
|
});
|
|
9440
9731
|
return {
|
|
9441
9732
|
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
|
-
}
|
|
9733
|
+
summary
|
|
9451
9734
|
};
|
|
9452
9735
|
} catch (error) {
|
|
9453
9736
|
logger.error("\u56FE\u7247\u5904\u7406\u5931\u8D25", {
|
|
9454
9737
|
imagePath,
|
|
9455
9738
|
error
|
|
9456
9739
|
});
|
|
9740
|
+
callbacks?.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
9457
9741
|
throw error;
|
|
9458
9742
|
}
|
|
9459
9743
|
}
|
|
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();
|
|
9744
|
+
async initializeOutputFile(imageInfo, totalSegments, projectPath) {
|
|
9478
9745
|
const dateDir = new Date().toISOString().split('T')[0];
|
|
9479
|
-
const outputDirectory = external_path_namespaceObject.join(
|
|
9746
|
+
const outputDirectory = external_path_namespaceObject.join(projectPath, '.aico', 'image-recognition', dateDir);
|
|
9480
9747
|
await external_fs_namespaceObject.promises.mkdir(outputDirectory, {
|
|
9481
9748
|
recursive: true
|
|
9482
9749
|
});
|
|
@@ -9484,39 +9751,78 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9484
9751
|
const imageBaseName = external_path_namespaceObject.basename(imageInfo.fileName, external_path_namespaceObject.extname(imageInfo.fileName));
|
|
9485
9752
|
const fileName = `${imageBaseName}-${timestamp}.md`;
|
|
9486
9753
|
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}
|
|
9754
|
+
const header = `# ${imageInfo.fileName} - \u{56FE}\u{7247}\u{6587}\u{5B57}\u{8BC6}\u{522B}\u{7ED3}\u{679C}
|
|
9489
9755
|
|
|
9490
9756
|
**\u{8BC6}\u{522B}\u{65F6}\u{95F4}**: ${new Date().toLocaleString('zh-CN')}
|
|
9491
9757
|
**\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)}%
|
|
9758
|
+
**\u{9884}\u{8BA1}\u{6BB5}\u{6570}**: ${totalSegments}
|
|
9759
|
+
**\u{72B6}\u{6001}**: \u{1F504} \u{8BC6}\u{522B}\u{4E2D}...
|
|
9496
9760
|
|
|
9497
9761
|
---
|
|
9498
9762
|
|
|
9499
9763
|
## \u{8BC6}\u{522B}\u{7684}\u{6587}\u{5B57}\u{5185}\u{5BB9}
|
|
9500
9764
|
|
|
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
9765
|
`;
|
|
9507
|
-
await external_fs_namespaceObject.promises.writeFile(outputPath,
|
|
9508
|
-
logger.info("\u8F93\u51FA\u6587\u4EF6\
|
|
9766
|
+
await external_fs_namespaceObject.promises.writeFile(outputPath, header, 'utf8');
|
|
9767
|
+
logger.info("\u8F93\u51FA\u6587\u4EF6\u521D\u59CB\u5316\u5B8C\u6210", {
|
|
9509
9768
|
outputPath,
|
|
9510
|
-
|
|
9511
|
-
contentLength: content.length
|
|
9769
|
+
totalSegments
|
|
9512
9770
|
});
|
|
9513
9771
|
return outputPath;
|
|
9514
9772
|
}
|
|
9773
|
+
async appendSegmentToFile(outputPath, result) {
|
|
9774
|
+
let content = '';
|
|
9775
|
+
if (result.error) content = `<!-- \u{6BB5}\u{843D} ${result.segmentIndex + 1} \u{5904}\u{7406}\u{5931}\u{8D25}: ${result.error} -->\n\n`;
|
|
9776
|
+
else if (result.textContent && result.textContent.trim()) content = `${result.textContent.trim()}\n\n`;
|
|
9777
|
+
if (content) await external_fs_namespaceObject.promises.appendFile(outputPath, content, 'utf8');
|
|
9778
|
+
}
|
|
9779
|
+
async finalizeOutputFile(outputPath, summary) {
|
|
9780
|
+
const footer = `
|
|
9781
|
+
---
|
|
9782
|
+
|
|
9783
|
+
## \u{5904}\u{7406}\u{6458}\u{8981}
|
|
9784
|
+
|
|
9785
|
+
- **\u{603B}\u{6BB5}\u{6570}**: ${summary.totalSegments}
|
|
9786
|
+
- **\u{6210}\u{529F}\u{6BB5}\u{6570}**: ${summary.successfulSegments}
|
|
9787
|
+
- **\u{5931}\u{8D25}\u{6BB5}\u{6570}**: ${summary.failedSegments}
|
|
9788
|
+
- **\u{6210}\u{529F}\u{7387}**: ${(100 * summary.successRate).toFixed(1)}%
|
|
9789
|
+
- **\u{6587}\u{5B57}\u{5B57}\u{7B26}\u{603B}\u{6570}**: ${summary.totalTextCharacters.toLocaleString()}
|
|
9790
|
+
- **\u{5E73}\u{5747}\u{7F6E}\u{4FE1}\u{5EA6}**: ${(100 * summary.averageConfidence).toFixed(1)}%
|
|
9791
|
+
- **\u{5904}\u{7406}\u{8017}\u{65F6}**: ${(summary.totalProcessingTimeMs / 1000).toFixed(2)}\u{79D2}
|
|
9792
|
+
|
|
9793
|
+
**\u{72B6}\u{6001}**: \u{2705} \u{8BC6}\u{522B}\u{5B8C}\u{6210}
|
|
9794
|
+
**\u{5B8C}\u{6210}\u{65F6}\u{95F4}**: ${new Date().toLocaleString('zh-CN')}
|
|
9795
|
+
`;
|
|
9796
|
+
await external_fs_namespaceObject.promises.appendFile(outputPath, footer, 'utf8');
|
|
9797
|
+
const content = await external_fs_namespaceObject.promises.readFile(outputPath, 'utf8');
|
|
9798
|
+
const updatedContent = content.replace("**\u72B6\u6001**: \uD83D\uDD04 \u8BC6\u522B\u4E2D...", "**\u72B6\u6001**: \u2705 \u8BC6\u522B\u5B8C\u6210");
|
|
9799
|
+
await external_fs_namespaceObject.promises.writeFile(outputPath, updatedContent, 'utf8');
|
|
9800
|
+
logger.info("\u8F93\u51FA\u6587\u4EF6\u5B8C\u6210", {
|
|
9801
|
+
outputPath
|
|
9802
|
+
});
|
|
9803
|
+
}
|
|
9804
|
+
async validateImageFile(imagePath) {
|
|
9805
|
+
try {
|
|
9806
|
+
const stats = await external_fs_namespaceObject.promises.stat(imagePath);
|
|
9807
|
+
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, {
|
|
9808
|
+
imagePath
|
|
9809
|
+
});
|
|
9810
|
+
} catch (error) {
|
|
9811
|
+
if ('ENOENT' === error.code) throw new ImageRecognitionError("\u56FE\u7247\u6587\u4EF6\u4E0D\u5B58\u5728", types_ErrorTypes.FILE_NOT_FOUND, {
|
|
9812
|
+
imagePath
|
|
9813
|
+
});
|
|
9814
|
+
throw new ImageRecognitionError(`\u{6587}\u{4EF6}\u{8BBF}\u{95EE}\u{9519}\u{8BEF}: ${error.message}`, types_ErrorTypes.VALIDATION_ERROR, {
|
|
9815
|
+
imagePath,
|
|
9816
|
+
originalError: error
|
|
9817
|
+
});
|
|
9818
|
+
}
|
|
9819
|
+
}
|
|
9515
9820
|
}
|
|
9516
9821
|
const imageRecognitionAgentTool = {
|
|
9517
9822
|
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\
|
|
9823
|
+
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
9824
|
inputSchema: {
|
|
9825
|
+
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
9826
|
imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
9521
9827
|
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
9828
|
},
|
|
@@ -9526,13 +9832,21 @@ ${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
|
|
|
9526
9832
|
args
|
|
9527
9833
|
});
|
|
9528
9834
|
try {
|
|
9529
|
-
const { imagePath, context } = ImageRecognitionParamsSchema.parse(args);
|
|
9835
|
+
const { projectPath, imagePath, context } = ImageRecognitionParamsSchema.parse(args);
|
|
9530
9836
|
const processor = new ImageRecognitionProcessor();
|
|
9531
|
-
const result = await processor.processImage(imagePath, context);
|
|
9837
|
+
const result = await processor.processImage(imagePath, projectPath, context);
|
|
9532
9838
|
logger.info("\u56FE\u7247\u5185\u5BB9\u8BC6\u522B\u667A\u80FD\u4F53: \u5904\u7406\u5B8C\u6210", {
|
|
9533
9839
|
outputPath: result.outputPath,
|
|
9534
9840
|
summary: result.summary
|
|
9535
9841
|
});
|
|
9842
|
+
let fileContent = '';
|
|
9843
|
+
try {
|
|
9844
|
+
fileContent = await external_fs_namespaceObject.promises.readFile(result.outputPath, 'utf8');
|
|
9845
|
+
} catch (readError) {
|
|
9846
|
+
logger.warn("\u8BFB\u53D6\u7ED3\u679C\u6587\u4EF6\u5931\u8D25", {
|
|
9847
|
+
error: readError
|
|
9848
|
+
});
|
|
9849
|
+
}
|
|
9536
9850
|
return {
|
|
9537
9851
|
content: [
|
|
9538
9852
|
{
|
|
@@ -9547,10 +9861,14 @@ ${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
|
|
|
9547
9861
|
- \u{5E73}\u{5747}\u{7F6E}\u{4FE1}\u{5EA6}: ${(100 * result.summary.averageConfidence).toFixed(1)}%
|
|
9548
9862
|
- \u{5904}\u{7406}\u{8017}\u{65F6}: ${(result.summary.totalProcessingTimeMs / 1000).toFixed(2)}\u{79D2}
|
|
9549
9863
|
|
|
9550
|
-
\u{1F4C4} **\u{7ED3}\u{679C}\u{6587}\u{4EF6}**:
|
|
9864
|
+
\u{1F4C4} **\u{7ED3}\u{679C}\u{6587}\u{4EF6}\u{8DEF}\u{5F84}**:
|
|
9551
9865
|
\`${result.outputPath}\`
|
|
9552
9866
|
|
|
9553
|
-
|
|
9867
|
+
---
|
|
9868
|
+
|
|
9869
|
+
## \u{8BC6}\u{522B}\u{7684}\u{5B8C}\u{6574}\u{5185}\u{5BB9}
|
|
9870
|
+
|
|
9871
|
+
${fileContent}`
|
|
9554
9872
|
}
|
|
9555
9873
|
]
|
|
9556
9874
|
};
|