intention-coding 0.5.8 → 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 +1127 -754
- 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/api-template.d.ts +1 -1
- package/dist/services/requirement-analyzer/prompt/api-template.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
|
-
|
|
5685
|
-
---
|
|
5686
|
-
|
|
5687
|
-
## 1. \u{9700}\u{6C42}\u{6982}\u{8FF0}
|
|
5688
|
-
|
|
5689
|
-
**\u{4E1A}\u{52A1}\u{80CC}\u{666F}**: [\u{63CF}\u{8FF0}APP\u{529F}\u{80FD}\u{80CC}\u{666F}\u{3001}\u{4E1A}\u{52A1}\u{9700}\u{6C42}\u{548C}\u{76EE}\u{6807}]
|
|
5690
|
-
|
|
5691
|
-
**\u{6838}\u{5FC3}\u{529F}\u{80FD}**: [\u{5217}\u{51FA}APP\u{7684}\u{4E3B}\u{8981}\u{529F}\u{80FD}\u{70B9}]
|
|
5692
|
-
|
|
5693
|
-
## 2. \u{754C}\u{9762}\u{8BBE}\u{8BA1}
|
|
5694
|
-
|
|
5695
|
-
### 2.1 \u{9875}\u{9762}\u{5E03}\u{5C40}
|
|
5696
|
-
[\u{63CF}\u{8FF0}\u{4E3B}\u{8981}\u{9875}\u{9762}\u{7684}\u{5E03}\u{5C40}\u{7ED3}\u{6784}\u{548C}\u{754C}\u{9762}\u{5143}\u{7D20}]
|
|
5697
|
-
|
|
5698
|
-
### 2.2 \u{7528}\u{6237}\u{754C}\u{9762}
|
|
5699
|
-
[\u{63CF}\u{8FF0}APP\u{7684}\u{7528}\u{6237}\u{754C}\u{9762}\u{8BBE}\u{8BA1}\u{548C}\u{4EA4}\u{4E92}\u{5143}\u{7D20}]
|
|
5700
|
-
|
|
5701
|
-
## 3. \u{4EA4}\u{4E92}\u{903B}\u{8F91}
|
|
5702
|
-
|
|
5703
|
-
### 3.1 \u{7528}\u{6237}\u{64CD}\u{4F5C}\u{6D41}\u{7A0B}
|
|
5704
|
-
[\u{63CF}\u{8FF0}\u{4E3B}\u{8981}\u{7684}\u{7528}\u{6237}\u{64CD}\u{4F5C}\u{6D41}\u{7A0B}\u{548C}\u{5BFC}\u{822A}\u{8DEF}\u{5F84}]
|
|
5705
|
-
|
|
5706
|
-
### 3.2 \u{4EA4}\u{4E92}\u{89C4}\u{5219}
|
|
5707
|
-
[\u{63CF}\u{8FF0}APP\u{4E2D}\u{7684}\u{4E3B}\u{8981}\u{4EA4}\u{4E92}\u{89C4}\u{5219}\u{548C}\u{54CD}\u{5E94}\u{673A}\u{5236}]
|
|
5708
|
-
|
|
5709
|
-
## 4. \u{6570}\u{636E}\u{5904}\u{7406}
|
|
5710
|
-
|
|
5711
|
-
### 4.1 \u{6570}\u{636E}\u{5C55}\u{793A}
|
|
5712
|
-
[\u{63CF}\u{8FF0}APP\u{4E2D}\u{6570}\u{636E}\u{7684}\u{5C55}\u{793A}\u{65B9}\u{5F0F}\u{548C}\u{683C}\u{5F0F}]
|
|
5713
|
-
|
|
5714
|
-
### 4.2 \u{6570}\u{636E}\u{4EA4}\u{4E92}
|
|
5715
|
-
[\u{63CF}\u{8FF0}APP\u{4E0E}\u{540E}\u{7AEF}\u{7684}\u{6570}\u{636E}\u{4EA4}\u{4E92}\u{65B9}\u{5F0F}]
|
|
5716
|
-
|
|
5717
|
-
## 5. \u{529F}\u{80FD}\u{6A21}\u{5757}
|
|
5718
|
-
|
|
5719
|
-
### 5.1 \u{6838}\u{5FC3}\u{6A21}\u{5757}
|
|
5720
|
-
[\u{63CF}\u{8FF0}APP\u{7684}\u{6838}\u{5FC3}\u{529F}\u{80FD}\u{6A21}\u{5757}]
|
|
5721
|
-
|
|
5722
|
-
### 5.2 \u{4E1A}\u{52A1}\u{903B}\u{8F91}
|
|
5723
|
-
[\u{63CF}\u{8FF0}\u{5404}\u{6A21}\u{5757}\u{7684}\u{4E1A}\u{52A1}\u{903B}\u{8F91}\u{548C}\u{5904}\u{7406}\u{6D41}\u{7A0B}]
|
|
5724
|
-
|
|
5725
|
-
## 6. \u{4E1A}\u{52A1}\u{6D41}\u{7A0B}
|
|
5726
|
-
|
|
5727
|
-
[\u{4F7F}\u{7528}\u{7B80}\u{5355}\u{7684}mermaid\u{6D41}\u{7A0B}\u{56FE}\u{63CF}\u{8FF0}\u{4E3B}\u{8981}\u{4E1A}\u{52A1}\u{6D41}\u{7A0B}]
|
|
5728
|
-
|
|
5729
|
-
\`\`\`mermaid
|
|
5730
|
-
graph TD
|
|
5731
|
-
A[\u{5F00}\u{59CB}] --> B[\u{5904}\u{7406}]
|
|
5732
|
-
B --> C[\u{7ED3}\u{675F}]
|
|
5733
|
-
\`\`\`
|
|
5734
|
-
|
|
5735
|
-
---
|
|
5736
|
-
|
|
5737
|
-
**\u{8981}\u{6C42}**: \u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{7AE0}\u{8282}\u{6709}\u{5B9E}\u{8D28}\u{5185}\u{5BB9}\u{FF0C}\u{91CD}\u{70B9}\u{5173}\u{6CE8}\u{754C}\u{9762}\u{8BBE}\u{8BA1}\u{3001}\u{4EA4}\u{4E92}\u{903B}\u{8F91}\u{548C}\u{6570}\u{636E}\u{5904}\u{7406}\u{3002}`;
|
|
5738
|
-
const sdkTemplatePrompt = `\u{4F60}\u{662F}\u{540E}\u{7AEF}\u{6280}\u{672F}\u{6587}\u{6863}\u{4E13}\u{5BB6}\u{3002}\u{57FA}\u{4E8E}\u{8F93}\u{5165}\u{5185}\u{5BB9}\u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}\u{4E09}\u{65B9}SDK\u{96C6}\u{6210}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF08}Markdown\u{683C}\u{5F0F}\u{FF0C}1500\u{5B57}\u{4EE5}\u{4E0A}\u{FF09}\u{3002}
|
|
5739
|
-
|
|
5740
|
-
**\u{8F93}\u{5165}**: \u{529F}\u{80FD}\u{540D}\u{79F0}={featureName}, \u{4E1A}\u{52A1}\u{9886}\u{57DF}={businessDomain}
|
|
5741
|
-
|
|
5742
|
-
**\u{539F}\u{59CB}\u{9700}\u{6C42}**:
|
|
5743
|
-
\`\`\`
|
|
5744
|
-
{inputContent}
|
|
5745
|
-
\`\`\`
|
|
5746
|
-
|
|
5747
|
-
## \u{6587}\u{6863}\u{7ED3}\u{6784}\u{8981}\u{6C42}
|
|
5748
|
-
\u{8BF7}\u{4E25}\u{683C}\u{6309}\u{7167}\u{4EE5}\u{4E0B}\u{7ED3}\u{6784}\u{8F93}\u{51FA}\u{5B8C}\u{6574}\u{7684}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF0C}\u{6BCF}\u{4E2A}\u{7AE0}\u{8282}\u{90FD}\u{8981}\u{6709}\u{8BE6}\u{5B9E}\u{7684}\u{5185}\u{5BB9}\u{FF1A}
|
|
5749
|
-
|
|
5750
|
-
# {featureName} - \u{4E09}\u{65B9}SDK\u{96C6}\u{6210}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
|
|
5751
|
-
|
|
5752
|
-
> **\u{751F}\u{6210}\u{65F6}\u{95F4}**: {currentTime}
|
|
5753
|
-
> **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: {businessDomain}
|
|
5754
|
-
> **\u{96C6}\u{6210}\u{7C7B}\u{578B}**: \u{4E09}\u{65B9}SDK\u{96C6}\u{6210}
|
|
5755
6033
|
|
|
5756
6034
|
---
|
|
5757
6035
|
|
|
5758
|
-
|
|
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
|
|
|
@@ -5858,11 +6078,61 @@ graph TD
|
|
|
5858
6078
|
## 3. \u{6570}\u{636E}\u{5EFA}\u{6A21}
|
|
5859
6079
|
## 3.1 ER\u{903B}\u{8F91}\u{56FE}\u{8BBE}\u{8BA1}
|
|
5860
6080
|
|
|
5861
|
-
|
|
6081
|
+
\u{57FA}\u{4E8E}\u{9700}\u{6C42}\u{5206}\u{6790}\u{FF0C}\u{8BBE}\u{8BA1}\u{4EE5}\u{4E0B}\u{6570}\u{636E}\u{5E93}\u{8868}\u{5173}\u{7CFB}\u{FF1A}
|
|
6082
|
+
- \u{7528}\u{6237}\u{8868} (users): \u{5B58}\u{50A8}\u{7528}\u{6237}\u{57FA}\u{672C}\u{4FE1}\u{606F}\u{FF0C}\u{5982}\u{7528}\u{6237}\u{540D}\u{3001}\u{90AE}\u{7BB1}\u{3001}\u{5BC6}\u{7801}\u{7B49}
|
|
6083
|
+
- \u{8BA2}\u{5355}\u{8868} (orders): \u{5B58}\u{50A8}\u{8BA2}\u{5355}\u{4FE1}\u{606F}\u{FF0C}\u{4E0E}\u{7528}\u{6237}\u{8868}\u{4E00}\u{5BF9}\u{591A}\u{5173}\u{7CFB}
|
|
6084
|
+
- \u{4EA7}\u{54C1}\u{8868} (products): \u{5B58}\u{50A8}\u{4EA7}\u{54C1}\u{4FE1}\u{606F}\u{FF0C}\u{4E0E}\u{8BA2}\u{5355}\u{8868}\u{591A}\u{5BF9}\u{591A}\u{5173}\u{7CFB}\u{FF08}\u{901A}\u{8FC7}\u{8BA2}\u{5355}\u{9879}\u{8868}\u{5173}\u{8054}\u{FF09}
|
|
6085
|
+
|
|
6086
|
+
\u{8BF7}\u{6839}\u{636E}\u{5177}\u{4F53}\u{9700}\u{6C42}\u{8BBE}\u{8BA1}\u{6570}\u{636E}\u{5E93}\u{8868}\u{7ED3}\u{6784}\u{FF0C}\u{5305}\u{62EC}\u{FF1A}
|
|
6087
|
+
1. \u{8868}\u{7684}\u{4E2D}\u{82F1}\u{6587}\u{540D}\u{79F0}
|
|
6088
|
+
2. \u{8868}\u{5B57}\u{6BB5}\u{5B9A}\u{4E49}\u{FF08}\u{5B57}\u{6BB5}\u{540D}\u{3001}\u{7C7B}\u{578B}\u{3001}\u{7EA6}\u{675F}\u{6761}\u{4EF6}\u{FF09}
|
|
6089
|
+
3. \u{8868}\u{4E4B}\u{95F4}\u{7684}\u{5173}\u{7CFB}\u{FF08}\u{4E00}\u{5BF9}\u{4E00}\u{3001}\u{4E00}\u{5BF9}\u{591A}\u{3001}\u{591A}\u{5BF9}\u{591A}\u{FF09}
|
|
6090
|
+
4. \u{4E3B}\u{952E}\u{548C}\u{5916}\u{952E}\u{7EA6}\u{675F}
|
|
6091
|
+
|
|
5862
6092
|
\`\`\`mermaid
|
|
6093
|
+
erDiagram
|
|
6094
|
+
users ||--o{ orders : "\u{62E5}\u{6709}"
|
|
6095
|
+
orders ||--o{ order_items : "\u{5305}\u{542B}"
|
|
6096
|
+
products ||--o{ order_items : "\u{88AB}\u{8D2D}\u{4E70}"
|
|
6097
|
+
users {
|
|
6098
|
+
int id PK
|
|
6099
|
+
string username
|
|
6100
|
+
string email
|
|
6101
|
+
string password_hash
|
|
6102
|
+
datetime created_at
|
|
6103
|
+
datetime updated_at
|
|
6104
|
+
}
|
|
6105
|
+
orders {
|
|
6106
|
+
int id PK
|
|
6107
|
+
int user_id FK
|
|
6108
|
+
decimal total_amount
|
|
6109
|
+
string status
|
|
6110
|
+
datetime order_date
|
|
6111
|
+
datetime created_at
|
|
6112
|
+
}
|
|
6113
|
+
products {
|
|
6114
|
+
int id PK
|
|
6115
|
+
string name
|
|
6116
|
+
string description
|
|
6117
|
+
decimal price
|
|
6118
|
+
int stock_quantity
|
|
6119
|
+
datetime created_at
|
|
6120
|
+
}
|
|
6121
|
+
order_items {
|
|
6122
|
+
int id PK
|
|
6123
|
+
int order_id FK
|
|
6124
|
+
int product_id FK
|
|
6125
|
+
int quantity
|
|
6126
|
+
decimal unit_price
|
|
6127
|
+
decimal subtotal
|
|
6128
|
+
}
|
|
5863
6129
|
\`\`\`
|
|
5864
6130
|
|
|
5865
|
-
|
|
6131
|
+
**\u{6570}\u{636E}\u{5E93}\u{8868}\u{5173}\u{7CFB}\u{8BF4}\u{660E}\u{FF1A}**
|
|
6132
|
+
- **\u{7528}\u{6237}-\u{8BA2}\u{5355}\u{5173}\u{7CFB}**: \u{4E00}\u{5BF9}\u{591A}\u{5173}\u{7CFB}\u{FF0C}\u{4E00}\u{4E2A}\u{7528}\u{6237}\u{53EF}\u{4EE5}\u{62E5}\u{6709}\u{591A}\u{4E2A}\u{8BA2}\u{5355}
|
|
6133
|
+
- **\u{8BA2}\u{5355}-\u{8BA2}\u{5355}\u{9879}\u{5173}\u{7CFB}**: \u{4E00}\u{5BF9}\u{591A}\u{5173}\u{7CFB}\u{FF0C}\u{4E00}\u{4E2A}\u{8BA2}\u{5355}\u{53EF}\u{4EE5}\u{5305}\u{542B}\u{591A}\u{4E2A}\u{8BA2}\u{5355}\u{9879}
|
|
6134
|
+
- **\u{4EA7}\u{54C1}-\u{8BA2}\u{5355}\u{9879}\u{5173}\u{7CFB}**: \u{4E00}\u{5BF9}\u{591A}\u{5173}\u{7CFB}\u{FF0C}\u{4E00}\u{4E2A}\u{4EA7}\u{54C1}\u{53EF}\u{4EE5}\u{88AB}\u{591A}\u{4E2A}\u{8BA2}\u{5355}\u{9879}\u{8D2D}\u{4E70}
|
|
6135
|
+
- **\u{8BA2}\u{5355}\u{9879}\u{8868}**: \u{4F5C}\u{4E3A}\u{4E2D}\u{95F4}\u{8868}\u{FF0C}\u{5B9E}\u{73B0}\u{8BA2}\u{5355}\u{548C}\u{4EA7}\u{54C1}\u{7684}\u{591A}\u{5BF9}\u{591A}\u{5173}\u{7CFB}
|
|
5866
6136
|
|
|
5867
6137
|
## 4. \u{6570}\u{636E}\u{8868}\u{5B9E}\u{4F53}\u{8BBE}\u{8BA1}
|
|
5868
6138
|
|
|
@@ -5957,36 +6227,28 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
5957
6227
|
class TemplateSelector {
|
|
5958
6228
|
templateMap = new Map([
|
|
5959
6229
|
[
|
|
5960
|
-
"
|
|
5961
|
-
|
|
5962
|
-
],
|
|
5963
|
-
[
|
|
5964
|
-
"APP",
|
|
5965
|
-
appTemplatePrompt
|
|
6230
|
+
"HTML",
|
|
6231
|
+
htmlPageTemplatePrompt
|
|
5966
6232
|
],
|
|
5967
6233
|
[
|
|
5968
|
-
"
|
|
5969
|
-
|
|
6234
|
+
"html",
|
|
6235
|
+
htmlPageTemplatePrompt
|
|
5970
6236
|
],
|
|
5971
6237
|
[
|
|
5972
|
-
"
|
|
5973
|
-
|
|
6238
|
+
"API",
|
|
6239
|
+
api_template_apiTemplatePrompt
|
|
5974
6240
|
],
|
|
5975
6241
|
[
|
|
5976
6242
|
"api",
|
|
5977
|
-
|
|
5978
|
-
],
|
|
5979
|
-
[
|
|
5980
|
-
"pc",
|
|
5981
|
-
pcPageTemplatePrompt
|
|
6243
|
+
api_template_apiTemplatePrompt
|
|
5982
6244
|
],
|
|
5983
6245
|
[
|
|
5984
|
-
"
|
|
5985
|
-
|
|
6246
|
+
"\u63A5\u53E3",
|
|
6247
|
+
api_template_apiTemplatePrompt
|
|
5986
6248
|
],
|
|
5987
6249
|
[
|
|
5988
|
-
"
|
|
5989
|
-
|
|
6250
|
+
"\u9875\u9762",
|
|
6251
|
+
htmlPageTemplatePrompt
|
|
5990
6252
|
]
|
|
5991
6253
|
]);
|
|
5992
6254
|
selectTemplate(requirementType) {
|
|
@@ -6031,33 +6293,18 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6031
6293
|
"ui",
|
|
6032
6294
|
"\u7F51\u9875",
|
|
6033
6295
|
"\u6D4F\u89C8\u5668",
|
|
6034
|
-
"\u524D\u7AEF"
|
|
6035
|
-
|
|
6036
|
-
type: "PC\u9875\u9762",
|
|
6037
|
-
template: pcPageTemplatePrompt
|
|
6038
|
-
};
|
|
6039
|
-
if (this.containsAny(lowerType, [
|
|
6296
|
+
"\u524D\u7AEF",
|
|
6297
|
+
"html",
|
|
6040
6298
|
"app",
|
|
6041
6299
|
"\u79FB\u52A8",
|
|
6042
6300
|
"ios",
|
|
6043
6301
|
"android",
|
|
6044
6302
|
"\u5C0F\u7A0B\u5E8F",
|
|
6045
|
-
"\u79FB\u52A8\u7AEF"
|
|
6046
|
-
|
|
6047
|
-
type: "APP",
|
|
6048
|
-
template: appTemplatePrompt
|
|
6049
|
-
};
|
|
6050
|
-
if (this.containsAny(lowerType, [
|
|
6051
|
-
"sdk",
|
|
6052
|
-
"\u7B2C\u4E09\u65B9",
|
|
6053
|
-
"\u96C6\u6210",
|
|
6054
|
-
"\u5BF9\u63A5",
|
|
6055
|
-
"\u652F\u4ED8",
|
|
6056
|
-
"\u5730\u56FE",
|
|
6057
|
-
"\u63A8\u9001"
|
|
6303
|
+
"\u79FB\u52A8\u7AEF",
|
|
6304
|
+
"\u54CD\u5E94\u5F0F"
|
|
6058
6305
|
])) return {
|
|
6059
|
-
type: "
|
|
6060
|
-
template:
|
|
6306
|
+
type: "HTML",
|
|
6307
|
+
template: htmlPageTemplatePrompt
|
|
6061
6308
|
};
|
|
6062
6309
|
if (this.containsAny(lowerType, [
|
|
6063
6310
|
"\u63A5\u53E3",
|
|
@@ -6069,7 +6316,7 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6069
6316
|
"\u670D\u52A1\u7AEF"
|
|
6070
6317
|
])) return {
|
|
6071
6318
|
type: "\u63A5\u53E3",
|
|
6072
|
-
template:
|
|
6319
|
+
template: api_template_apiTemplatePrompt
|
|
6073
6320
|
};
|
|
6074
6321
|
return null;
|
|
6075
6322
|
}
|
|
@@ -6145,7 +6392,7 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6145
6392
|
cleanedCount
|
|
6146
6393
|
});
|
|
6147
6394
|
}
|
|
6148
|
-
async generateUnifiedDocument(analysis, projectInfo, featureName, sourceInfo, customPrompt, currentProjectPath) {
|
|
6395
|
+
async generateUnifiedDocument(analysis, projectInfo, featureName, sourceInfo, customPrompt, currentProjectPath, pageStyle, pageType) {
|
|
6149
6396
|
try {
|
|
6150
6397
|
logger.info("\u51C6\u5907\u751F\u6210\u7EDF\u4E00\u6280\u672F\u6587\u6863\u4EFB\u52A1", {
|
|
6151
6398
|
featureName,
|
|
@@ -6153,7 +6400,10 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6153
6400
|
featureCount: analysis.requirements.length,
|
|
6154
6401
|
currentProjectPath
|
|
6155
6402
|
});
|
|
6156
|
-
const requirementTypes =
|
|
6403
|
+
const requirementTypes = [
|
|
6404
|
+
"API",
|
|
6405
|
+
"HTML"
|
|
6406
|
+
];
|
|
6157
6407
|
const generationTasks = await Promise.all(requirementTypes.map(async (reqType)=>{
|
|
6158
6408
|
logger.info("\u51C6\u5907\u62A5\u544A\u751F\u6210\u4EFB\u52A1", {
|
|
6159
6409
|
requirementType: reqType,
|
|
@@ -6177,13 +6427,19 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6177
6427
|
prompt: promptData.prompt,
|
|
6178
6428
|
systemPrompt: promptData.systemPrompt,
|
|
6179
6429
|
templateContent: promptData.templateContent,
|
|
6180
|
-
templateVariables: "templateVariables" in promptData ?
|
|
6430
|
+
templateVariables: "templateVariables" in promptData ? {
|
|
6431
|
+
...promptData.templateVariables,
|
|
6432
|
+
pageStyle,
|
|
6433
|
+
pageType: pageType || "responsive"
|
|
6434
|
+
} : {
|
|
6181
6435
|
featureName: featureName,
|
|
6182
6436
|
inputContent: this.buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo),
|
|
6183
6437
|
currentTime: new Date().toISOString(),
|
|
6184
6438
|
businessDomain: this.mapRequirementTypeToBusinessDomain(reqType),
|
|
6185
6439
|
generateSequenceDiagram: "true",
|
|
6186
|
-
customPrompt
|
|
6440
|
+
customPrompt,
|
|
6441
|
+
pageStyle,
|
|
6442
|
+
pageType: pageType || "responsive"
|
|
6187
6443
|
},
|
|
6188
6444
|
existingContent: "existingContent" in promptData ? promptData.existingContent : void 0
|
|
6189
6445
|
};
|
|
@@ -6256,18 +6512,72 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6256
6512
|
}
|
|
6257
6513
|
buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo) {
|
|
6258
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 || {};
|
|
6259
6519
|
const combinedFeatureContent = featuresToProcess.map((feature, index)=>{
|
|
6260
6520
|
const featureTitle = "title" in feature ? feature.title : feature.featureName;
|
|
6261
6521
|
const featureContent = "fullContent" in feature ? feature.fullContent : feature.description;
|
|
6262
|
-
|
|
6263
|
-
|
|
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");
|
|
6264
6564
|
return `# ${featureName} - \u{7EDF}\u{4E00}\u{9700}\u{6C42}\u{5206}\u{6790}
|
|
6265
6565
|
|
|
6266
6566
|
## \u{9879}\u{76EE}\u{57FA}\u{672C}\u{4FE1}\u{606F}
|
|
6267
6567
|
- **\u{9879}\u{76EE}\u{7C7B}\u{578B}**: ${projectInfo?.projectType || "\u901A\u7528\u9879\u76EE"}
|
|
6268
|
-
- **\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"}
|
|
6269
6569
|
- **\u{5F00}\u{53D1}\u{6846}\u{67B6}**: ${projectInfo?.frameworks?.join(", ") || "\u5F85\u786E\u5B9A"}
|
|
6270
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"}
|
|
6271
6581
|
|
|
6272
6582
|
## \u{9700}\u{6C42}\u{7C7B}\u{578B}\u{5206}\u{6790}
|
|
6273
6583
|
- **\u{8BC6}\u{522B}\u{7C7B}\u{578B}**: ${analysis.requirementType}
|
|
@@ -6275,6 +6585,17 @@ Scenario Outline: \u{7528}\u{6237}\u{901A}\u{8FC7}API\u{67E5}\u{8BE2}\u{8BA2}\u{
|
|
|
6275
6585
|
- **\u{529F}\u{80FD}\u{70B9}\u{6570}\u{91CF}**: ${featuresToProcess.length}\u{4E2A}
|
|
6276
6586
|
- **\u{7F6E}\u{4FE1}\u{5EA6}**: ${analysis.confidence || "medium"}
|
|
6277
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
|
+
|
|
6278
6599
|
## \u{529F}\u{80FD}\u{70B9}\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}
|
|
6279
6600
|
|
|
6280
6601
|
${combinedFeatureContent}
|
|
@@ -6650,6 +6971,7 @@ ${existingContent}
|
|
|
6650
6971
|
currentTime: new Date().toISOString(),
|
|
6651
6972
|
businessDomain,
|
|
6652
6973
|
generateSequenceDiagram: "true",
|
|
6974
|
+
generateERDiagram: "true",
|
|
6653
6975
|
customPrompt
|
|
6654
6976
|
};
|
|
6655
6977
|
let prompt = template;
|
|
@@ -6673,6 +6995,7 @@ ${customPrompt}`;
|
|
|
6673
6995
|
currentTime: new Date().toISOString(),
|
|
6674
6996
|
businessDomain,
|
|
6675
6997
|
generateSequenceDiagram: "true",
|
|
6998
|
+
generateERDiagram: "true",
|
|
6676
6999
|
customPrompt,
|
|
6677
7000
|
existingContent
|
|
6678
7001
|
};
|
|
@@ -6715,7 +7038,7 @@ ${customPrompt}` : ""}
|
|
|
6715
7038
|
}
|
|
6716
7039
|
buildDocumentPrompt(template, content, title, projectInfo, customPrompt, requirementType) {
|
|
6717
7040
|
const businessDomain = this.mapRequirementTypeToBusinessDomain(requirementType);
|
|
6718
|
-
let prompt = template.replace(/\{featureName\}/g, title).replace(/\{inputContent\}/g, content).replace(/\{currentTime\}/g, new Date().toISOString()).replace(/\{businessDomain\}/g, businessDomain).replace(/\{generateSequenceDiagram\}/g, "true");
|
|
7041
|
+
let prompt = template.replace(/\{featureName\}/g, title).replace(/\{inputContent\}/g, content).replace(/\{currentTime\}/g, new Date().toISOString()).replace(/\{businessDomain\}/g, businessDomain).replace(/\{generateSequenceDiagram\}/g, "true").replace(/\{generateERDiagram\}/g, "true");
|
|
6719
7042
|
if (customPrompt) prompt += `
|
|
6720
7043
|
|
|
6721
7044
|
## \u{81EA}\u{5B9A}\u{4E49}\u{8981}\u{6C42}
|
|
@@ -6809,6 +7132,9 @@ ${customPrompt}` : ""}
|
|
|
6809
7132
|
if (!document.includes(title)) logger.warn("\u751F\u6210\u7684\u6587\u6863\u53EF\u80FD\u4E0E\u9700\u6C42\u6807\u9898\u4E0D\u5339\u914D", {
|
|
6810
7133
|
title
|
|
6811
7134
|
});
|
|
7135
|
+
if (document.includes("## 3.1 ER\u903B\u8F91\u56FE\u8BBE\u8BA1") && !document.includes("erDiagram") && !document.includes("entity")) logger.warn("\u751F\u6210\u7684\u6587\u6863\u53EF\u80FD\u7F3A\u5C11ER\u56FE\u5185\u5BB9", {
|
|
7136
|
+
title
|
|
7137
|
+
});
|
|
6812
7138
|
}
|
|
6813
7139
|
buildAnalysisResult(analysis, projectInfo, outputPath, sourceInfo, isUpdate = false, generatedFiles, analysisInfos) {
|
|
6814
7140
|
const featuresToProcess = analysis.featureDependencies?.mergedFeatures || analysis.requirements;
|
|
@@ -6955,14 +7281,14 @@ ${generationTasks?.map((task, i)=>`
|
|
|
6955
7281
|
async analyzeRequirements(params) {
|
|
6956
7282
|
try {
|
|
6957
7283
|
logger.info("\u5F00\u59CB\u9700\u6C42\u5206\u6790\u6D41\u7A0B", {
|
|
6958
|
-
|
|
6959
|
-
|
|
7284
|
+
projectPath: params.current_project_path,
|
|
7285
|
+
hasPageStyle: !!params.page_style
|
|
6960
7286
|
});
|
|
6961
|
-
const { requirementContent, projectInfo } = this.parseRequirementAnalysis(params.requirement_analysis);
|
|
7287
|
+
const { requirementContent, projectInfo, enrichedContext } = this.parseRequirementAnalysis(params.requirement_analysis);
|
|
6962
7288
|
const requirementAnalysis = await this.intelligentAnalyzer.analyzeRequirements(requirementContent, projectInfo, void 0);
|
|
6963
|
-
|
|
6964
|
-
requirementAnalysis.
|
|
6965
|
-
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);
|
|
6966
7292
|
} catch (error) {
|
|
6967
7293
|
if (error instanceof RequirementAnalysisError) throw error;
|
|
6968
7294
|
logger.error("\u9700\u6C42\u5206\u6790\u6D41\u7A0B\u5931\u8D25", {
|
|
@@ -6978,15 +7304,32 @@ ${generationTasks?.map((task, i)=>`
|
|
|
6978
7304
|
parseRequirementAnalysis(analysisResult) {
|
|
6979
7305
|
try {
|
|
6980
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
|
+
};
|
|
6981
7315
|
return {
|
|
6982
7316
|
requirementContent: parsed.requirement_description || parsed.data?.guidance || analysisResult,
|
|
6983
|
-
projectInfo: parsed.project_context || this.getDefaultProjectInfo()
|
|
7317
|
+
projectInfo: parsed.project_context || this.getDefaultProjectInfo(),
|
|
7318
|
+
enrichedContext
|
|
6984
7319
|
};
|
|
6985
7320
|
} catch {
|
|
6986
7321
|
logger.info("\u4F7F\u7528\u6587\u672C\u683C\u5F0F\u7684\u9700\u6C42\u5206\u6790\u7ED3\u679C");
|
|
6987
7322
|
return {
|
|
6988
7323
|
requirementContent: analysisResult,
|
|
6989
|
-
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
|
+
}
|
|
6990
7333
|
};
|
|
6991
7334
|
}
|
|
6992
7335
|
}
|
|
@@ -7115,23 +7458,177 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7115
7458
|
};
|
|
7116
7459
|
}
|
|
7117
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
|
+
}
|
|
7118
7614
|
const requirementAnalyzerTool = {
|
|
7119
|
-
name: "
|
|
7120
|
-
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}`,
|
|
7121
7617
|
inputSchema: {
|
|
7122
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"),
|
|
7123
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"),
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
"
|
|
7127
|
-
"
|
|
7128
|
-
"
|
|
7129
|
-
|
|
7130
|
-
]).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和移动端)")
|
|
7131
7626
|
},
|
|
7132
7627
|
handler: async (args)=>{
|
|
7133
7628
|
try {
|
|
7134
|
-
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";
|
|
7135
7632
|
if (!requirement_analysis || !current_project_path) return {
|
|
7136
7633
|
content: [
|
|
7137
7634
|
{
|
|
@@ -7149,20 +7646,131 @@ ${generationTasks?.map((task, i)=>`
|
|
|
7149
7646
|
const serviceResult = await service.analyzeRequirements({
|
|
7150
7647
|
requirement_analysis,
|
|
7151
7648
|
current_project_path,
|
|
7152
|
-
|
|
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`
|
|
7153
7755
|
});
|
|
7154
7756
|
return {
|
|
7155
7757
|
content: [
|
|
7156
7758
|
{
|
|
7157
7759
|
type: "text",
|
|
7158
7760
|
text: JSON.stringify({
|
|
7159
|
-
success:
|
|
7160
|
-
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`,
|
|
7161
7763
|
data: {
|
|
7162
7764
|
outputPath: serviceResult.outputPath,
|
|
7163
|
-
generatedFiles
|
|
7765
|
+
generatedFiles,
|
|
7164
7766
|
analysisInfo: serviceResult.analysisInfo || {},
|
|
7165
|
-
|
|
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
|
+
}))
|
|
7166
7774
|
}
|
|
7167
7775
|
})
|
|
7168
7776
|
}
|
|
@@ -7550,202 +8158,6 @@ ${requirementSection}
|
|
|
7550
8158
|
}
|
|
7551
8159
|
const external_sharp_namespaceObject = require("sharp");
|
|
7552
8160
|
var external_sharp_default = /*#__PURE__*/ __webpack_require__.n(external_sharp_namespaceObject);
|
|
7553
|
-
async function invokeFlow(params, streamCb) {
|
|
7554
|
-
const { appid = 'app-ESTcrkOPOmkxdrO0120mE4s1', data, timeout = 1800000 } = params;
|
|
7555
|
-
const controller = new AbortController();
|
|
7556
|
-
const signal = controller.signal;
|
|
7557
|
-
if ('undefined' == typeof ReadableStream) throw new Error('ReadableStream is not supported in this environment');
|
|
7558
|
-
const fetchData = async (retryCount = 0)=>{
|
|
7559
|
-
try {
|
|
7560
|
-
const fetchOptions = {
|
|
7561
|
-
method: 'POST',
|
|
7562
|
-
headers: {
|
|
7563
|
-
Authorization: `Bearer ${appid}`,
|
|
7564
|
-
'Content-Type': 'application/json'
|
|
7565
|
-
},
|
|
7566
|
-
body: JSON.stringify({
|
|
7567
|
-
inputs: data,
|
|
7568
|
-
response_mode: 'streaming',
|
|
7569
|
-
user: "aico-mcp"
|
|
7570
|
-
}),
|
|
7571
|
-
signal
|
|
7572
|
-
};
|
|
7573
|
-
const res = await fetch('http://11.0.166.20:9199/v1/workflows/run', fetchOptions);
|
|
7574
|
-
if (!res.ok) {
|
|
7575
|
-
if (retryCount < 3) {
|
|
7576
|
-
await new Promise((resolve)=>setTimeout(resolve, 1000));
|
|
7577
|
-
return fetchData(retryCount + 1);
|
|
7578
|
-
}
|
|
7579
|
-
const errorResponse = await res.text();
|
|
7580
|
-
throw new Error(`\u{7F51}\u{7EDC}\u{54CD}\u{5E94}\u{5F02}\u{5E38}: ${res.status} ${res.statusText} - ${errorResponse}`);
|
|
7581
|
-
}
|
|
7582
|
-
if (res.ok) if (res.body) {
|
|
7583
|
-
const reader = res.body.getReader();
|
|
7584
|
-
const decoder = new TextDecoder('utf-8');
|
|
7585
|
-
if (streamCb) return void new ReadableStream({
|
|
7586
|
-
start (controller) {
|
|
7587
|
-
let buffer = '';
|
|
7588
|
-
function push() {
|
|
7589
|
-
reader.read().then(({ done, value })=>{
|
|
7590
|
-
if (done) {
|
|
7591
|
-
const lines = buffer.split('\n');
|
|
7592
|
-
for (const line of lines)handleLine(line, controller);
|
|
7593
|
-
if (streamCb) streamCb({
|
|
7594
|
-
isEnd: true
|
|
7595
|
-
});
|
|
7596
|
-
controller.close();
|
|
7597
|
-
return;
|
|
7598
|
-
}
|
|
7599
|
-
const chunkText = decoder.decode(value, {
|
|
7600
|
-
stream: true
|
|
7601
|
-
});
|
|
7602
|
-
buffer += chunkText;
|
|
7603
|
-
const lines = buffer.split('\n');
|
|
7604
|
-
for(let i = 0; i < lines.length - 1; i++)handleLine(lines[i], controller);
|
|
7605
|
-
buffer = lines[lines.length - 1];
|
|
7606
|
-
push();
|
|
7607
|
-
});
|
|
7608
|
-
}
|
|
7609
|
-
function handleLine(line, controller) {
|
|
7610
|
-
line = line.trim();
|
|
7611
|
-
if (line.startsWith('data:')) {
|
|
7612
|
-
const dataStr = line.slice(5).trim();
|
|
7613
|
-
if ('' === dataStr) return;
|
|
7614
|
-
try {
|
|
7615
|
-
const jsonData = JSON.parse(dataStr);
|
|
7616
|
-
if (jsonData.data?.text) {
|
|
7617
|
-
const wrappedData = {
|
|
7618
|
-
content: jsonData.data.text.toString(),
|
|
7619
|
-
controller
|
|
7620
|
-
};
|
|
7621
|
-
if (streamCb) streamCb(wrappedData);
|
|
7622
|
-
}
|
|
7623
|
-
} catch (e) {
|
|
7624
|
-
console.error("\u89E3\u6790JSON\u5931\u8D25:", e);
|
|
7625
|
-
}
|
|
7626
|
-
}
|
|
7627
|
-
}
|
|
7628
|
-
push();
|
|
7629
|
-
}
|
|
7630
|
-
});
|
|
7631
|
-
{
|
|
7632
|
-
let buffer = '';
|
|
7633
|
-
let accumulatedText = '';
|
|
7634
|
-
let isResponseEnded = false;
|
|
7635
|
-
const readAll = async ()=>{
|
|
7636
|
-
const { done, value } = await reader.read();
|
|
7637
|
-
if (done) {
|
|
7638
|
-
if (!isResponseEnded) throw new Error("\u54CD\u5E94\u63D0\u524D\u7ED3\u675F");
|
|
7639
|
-
return accumulatedText;
|
|
7640
|
-
}
|
|
7641
|
-
const chunkText = decoder.decode(value, {
|
|
7642
|
-
stream: true
|
|
7643
|
-
});
|
|
7644
|
-
buffer += chunkText;
|
|
7645
|
-
const lines = buffer.split('\n');
|
|
7646
|
-
for(let i = 0; i < lines.length - 1; i++){
|
|
7647
|
-
const line = lines[i].trim();
|
|
7648
|
-
if (!line.startsWith('data:')) continue;
|
|
7649
|
-
const dataStr = line.slice(5).trim();
|
|
7650
|
-
if ('' !== dataStr) try {
|
|
7651
|
-
const jsonData = JSON.parse(dataStr);
|
|
7652
|
-
switch(jsonData.event){
|
|
7653
|
-
case 'message':
|
|
7654
|
-
case 'agent_message':
|
|
7655
|
-
case 'text_chunk':
|
|
7656
|
-
{
|
|
7657
|
-
const content = 'text_chunk' === jsonData.event ? jsonData.data.text : jsonData.answer;
|
|
7658
|
-
accumulatedText += content;
|
|
7659
|
-
break;
|
|
7660
|
-
}
|
|
7661
|
-
case 'workflow_finished':
|
|
7662
|
-
accumulatedText = jsonData.data;
|
|
7663
|
-
isResponseEnded = true;
|
|
7664
|
-
break;
|
|
7665
|
-
case 'message_end':
|
|
7666
|
-
isResponseEnded = true;
|
|
7667
|
-
break;
|
|
7668
|
-
case 'error':
|
|
7669
|
-
throw new Error(`\u{670D}\u{52A1}\u{5668}\u{9519}\u{8BEF}: ${jsonData.code}, ${jsonData.message}`);
|
|
7670
|
-
default:
|
|
7671
|
-
break;
|
|
7672
|
-
}
|
|
7673
|
-
} catch (e) {
|
|
7674
|
-
throw new Error("\u89E3\u6790JSON\u5931\u8D25: " + e.message);
|
|
7675
|
-
}
|
|
7676
|
-
}
|
|
7677
|
-
buffer = lines[lines.length - 1];
|
|
7678
|
-
return readAll();
|
|
7679
|
-
};
|
|
7680
|
-
return readAll();
|
|
7681
|
-
}
|
|
7682
|
-
} else throw new Error("\u54CD\u5E94\u4F53\u4E3A\u7A7A");
|
|
7683
|
-
{
|
|
7684
|
-
const errorResponse = await res.text();
|
|
7685
|
-
throw new Error(`\u{7F51}\u{7EDC}\u{54CD}\u{5E94}\u{5F02}\u{5E38}: ${res.status} ${res.statusText} - ${errorResponse}`);
|
|
7686
|
-
}
|
|
7687
|
-
} catch (error) {
|
|
7688
|
-
if ('AbortError' === error.name) throw new Error("\u8BF7\u6C42\u5DF2\u88AB\u4E2D\u6B62\uFF0C\u8D85\u65F6");
|
|
7689
|
-
throw error;
|
|
7690
|
-
}
|
|
7691
|
-
};
|
|
7692
|
-
try {
|
|
7693
|
-
const result = await Promise.race([
|
|
7694
|
-
fetchData(),
|
|
7695
|
-
new Promise((_, reject)=>{
|
|
7696
|
-
setTimeout(()=>{
|
|
7697
|
-
controller.abort();
|
|
7698
|
-
reject(new Error("\u8BF7\u6C42\u8D85\u65F6"));
|
|
7699
|
-
}, timeout);
|
|
7700
|
-
})
|
|
7701
|
-
]);
|
|
7702
|
-
if (streamCb) return;
|
|
7703
|
-
return result;
|
|
7704
|
-
} catch (error) {
|
|
7705
|
-
controller.abort();
|
|
7706
|
-
throw error;
|
|
7707
|
-
}
|
|
7708
|
-
}
|
|
7709
|
-
async function uploadFile(params) {
|
|
7710
|
-
const { appid, filePath, user = 'aico-mcp' } = params;
|
|
7711
|
-
try {
|
|
7712
|
-
const fileBuffer = await external_fs_default().promises.readFile(filePath);
|
|
7713
|
-
const fileName = external_path_default().basename(filePath);
|
|
7714
|
-
const fileExtension = external_path_default().extname(filePath).toLowerCase().slice(1);
|
|
7715
|
-
const mimeTypes = {
|
|
7716
|
-
png: 'image/png',
|
|
7717
|
-
jpeg: 'image/jpeg',
|
|
7718
|
-
jpg: 'image/jpeg',
|
|
7719
|
-
webp: 'image/webp',
|
|
7720
|
-
gif: 'image/gif'
|
|
7721
|
-
};
|
|
7722
|
-
const mimeType = mimeTypes[fileExtension] || 'application/octet-stream';
|
|
7723
|
-
const formData = new FormData();
|
|
7724
|
-
formData.append('file', new Blob([
|
|
7725
|
-
fileBuffer.buffer
|
|
7726
|
-
], {
|
|
7727
|
-
type: mimeType
|
|
7728
|
-
}), fileName);
|
|
7729
|
-
formData.append('user', user);
|
|
7730
|
-
const response = await fetch('http://11.0.166.20:9199/v1/files/upload', {
|
|
7731
|
-
method: 'POST',
|
|
7732
|
-
headers: {
|
|
7733
|
-
Authorization: `Bearer ${appid}`
|
|
7734
|
-
},
|
|
7735
|
-
body: formData
|
|
7736
|
-
});
|
|
7737
|
-
if (!response.ok) {
|
|
7738
|
-
const errorText = await response.text();
|
|
7739
|
-
throw new Error(`\u{6587}\u{4EF6}\u{4E0A}\u{4F20}\u{5931}\u{8D25}: ${response.status} ${response.statusText} - ${errorText}`);
|
|
7740
|
-
}
|
|
7741
|
-
const result = await response.json();
|
|
7742
|
-
if (!result.id || !result.name) throw new Error("\u65E0\u6548\u7684\u6587\u4EF6\u4E0A\u4F20\u54CD\u5E94\u683C\u5F0F");
|
|
7743
|
-
return result;
|
|
7744
|
-
} catch (error) {
|
|
7745
|
-
if (error instanceof Error) throw new Error(`\u{6587}\u{4EF6}\u{4E0A}\u{4F20}\u{5931}\u{8D25}: ${error.message}`);
|
|
7746
|
-
throw new Error("\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: \u672A\u77E5\u9519\u8BEF");
|
|
7747
|
-
}
|
|
7748
|
-
}
|
|
7749
8161
|
class ImageAnalysisError extends Error {
|
|
7750
8162
|
code;
|
|
7751
8163
|
context;
|
|
@@ -7782,7 +8194,7 @@ ${requirementSection}
|
|
|
7782
8194
|
});
|
|
7783
8195
|
await this.validateParams(imagePath);
|
|
7784
8196
|
const basicInfo = await this.getImageBasicInfo(imagePath);
|
|
7785
|
-
const analysisContent = await this.performAIAnalysis(imagePath,
|
|
8197
|
+
const analysisContent = await this.performAIAnalysis(imagePath, context);
|
|
7786
8198
|
const processingTime = Date.now() - startTime;
|
|
7787
8199
|
if (!analysisContent) throw new ImageAnalysisError("AI\u5206\u6790\u8FD4\u56DE\u7A7A\u7ED3\u679C", types_AnalysisErrorCodes.ANALYSIS_FAILED, {
|
|
7788
8200
|
params: {
|
|
@@ -7809,16 +8221,15 @@ ${requirementSection}
|
|
|
7809
8221
|
throw error;
|
|
7810
8222
|
}
|
|
7811
8223
|
}
|
|
7812
|
-
async performAIAnalysis(imagePath,
|
|
8224
|
+
async performAIAnalysis(imagePath, context) {
|
|
7813
8225
|
try {
|
|
7814
|
-
const imageBase64 = await this.imageToBase64(imagePath);
|
|
7815
8226
|
const systemPrompt = `You must interpret and analyze images strictly according to the assigned task.
|
|
7816
8227
|
When an image placeholder is provided, your role is to parse the image content only within the scope of the user's instructions.
|
|
7817
8228
|
Do not ignore or deviate from the task.
|
|
7818
8229
|
Always ensure that your response reflects a clear, accurate interpretation of the image aligned with the given objective.`;
|
|
7819
|
-
const userPrompt = context
|
|
7820
|
-
const aiResponse = await openAIService.
|
|
7821
|
-
|
|
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,
|
|
7822
8233
|
prompt: userPrompt,
|
|
7823
8234
|
system_prompt: systemPrompt
|
|
7824
8235
|
});
|
|
@@ -7828,26 +8239,15 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7828
8239
|
tags: []
|
|
7829
8240
|
};
|
|
7830
8241
|
} catch (error) {
|
|
7831
|
-
logger.
|
|
8242
|
+
logger.error("AI\u5206\u6790\u5931\u8D25", {
|
|
7832
8243
|
error,
|
|
7833
8244
|
params: {
|
|
7834
8245
|
image_path: imagePath
|
|
7835
8246
|
}
|
|
7836
8247
|
});
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
}
|
|
7840
|
-
logger.error("Dify\u515C\u5E95\u5206\u6790\u4E5F\u5931\u8D25", {
|
|
7841
|
-
error: fallbackError,
|
|
7842
|
-
params: {
|
|
7843
|
-
image_path: imagePath
|
|
7844
|
-
}
|
|
7845
|
-
});
|
|
7846
|
-
throw new ImageAnalysisError("\u8BC6\u522B\u56FE\u7247\u5931\u8D25", types_AnalysisErrorCodes.ANALYSIS_FAILED, {
|
|
7847
|
-
originalError: error,
|
|
7848
|
-
fallbackError
|
|
7849
|
-
});
|
|
7850
|
-
}
|
|
8248
|
+
throw new ImageAnalysisError("\u8BC6\u522B\u56FE\u7247\u5931\u8D25", types_AnalysisErrorCodes.ANALYSIS_FAILED, {
|
|
8249
|
+
originalError: error
|
|
8250
|
+
});
|
|
7851
8251
|
}
|
|
7852
8252
|
}
|
|
7853
8253
|
async getImageBasicInfo(imagePath) {
|
|
@@ -7856,7 +8256,7 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7856
8256
|
const stats = await promises_namespaceObject.stat(imagePath);
|
|
7857
8257
|
return {
|
|
7858
8258
|
path: imagePath,
|
|
7859
|
-
format: metadata.format ||
|
|
8259
|
+
format: metadata.format || "unknown",
|
|
7860
8260
|
dimensions: {
|
|
7861
8261
|
width: metadata.width || 0,
|
|
7862
8262
|
height: metadata.height || 0
|
|
@@ -7870,37 +8270,6 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7870
8270
|
});
|
|
7871
8271
|
}
|
|
7872
8272
|
}
|
|
7873
|
-
async imageToBase64(imagePath) {
|
|
7874
|
-
try {
|
|
7875
|
-
const imageBuffer = await promises_namespaceObject.readFile(imagePath);
|
|
7876
|
-
const base64 = imageBuffer.toString('base64');
|
|
7877
|
-
const ext = external_path_namespaceObject.extname(imagePath).toLowerCase();
|
|
7878
|
-
let mimeType = 'image/jpeg';
|
|
7879
|
-
switch(ext){
|
|
7880
|
-
case '.png':
|
|
7881
|
-
mimeType = 'image/png';
|
|
7882
|
-
break;
|
|
7883
|
-
case '.gif':
|
|
7884
|
-
mimeType = 'image/gif';
|
|
7885
|
-
break;
|
|
7886
|
-
case '.webp':
|
|
7887
|
-
mimeType = 'image/webp';
|
|
7888
|
-
break;
|
|
7889
|
-
case '.jpg':
|
|
7890
|
-
case '.jpeg':
|
|
7891
|
-
mimeType = 'image/jpeg';
|
|
7892
|
-
break;
|
|
7893
|
-
default:
|
|
7894
|
-
mimeType = 'image/jpeg';
|
|
7895
|
-
}
|
|
7896
|
-
return `data:${mimeType};base64,${base64}`;
|
|
7897
|
-
} catch (error) {
|
|
7898
|
-
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, {
|
|
7899
|
-
imagePath,
|
|
7900
|
-
originalError: error
|
|
7901
|
-
});
|
|
7902
|
-
}
|
|
7903
|
-
}
|
|
7904
8273
|
async validateParams(imagePath) {
|
|
7905
8274
|
try {
|
|
7906
8275
|
await promises_namespaceObject.access(imagePath);
|
|
@@ -7915,81 +8284,17 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
7915
8284
|
supportedFormats: SUPPORTED_IMAGE_FORMATS
|
|
7916
8285
|
});
|
|
7917
8286
|
}
|
|
7918
|
-
formatFileSize(bytes) {
|
|
7919
|
-
if (0 === bytes) return '0 B';
|
|
7920
|
-
const k = 1024;
|
|
7921
|
-
const sizes = [
|
|
7922
|
-
'B',
|
|
7923
|
-
'KB',
|
|
7924
|
-
'MB',
|
|
7925
|
-
'GB'
|
|
7926
|
-
];
|
|
7927
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
7928
|
-
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
7929
|
-
}
|
|
7930
|
-
async fallbackToDifyAnalysis(imagePath, context) {
|
|
7931
|
-
logger.info("\u5F00\u59CBDify\u515C\u5E95\u56FE\u7247\u5206\u6790", {
|
|
7932
|
-
imagePath: imagePath,
|
|
7933
|
-
context: context
|
|
7934
|
-
});
|
|
7935
|
-
try {
|
|
7936
|
-
const uploadResult = await uploadFile({
|
|
7937
|
-
appid: 'app-AvlLh0nfN4l9oz1MSW4sEAQ6',
|
|
7938
|
-
filePath: imagePath,
|
|
7939
|
-
user: 'aico-mcp'
|
|
7940
|
-
});
|
|
7941
|
-
logger.info("\u6587\u4EF6\u4E0A\u4F20\u6210\u529F\uFF0C\u6587\u4EF6ID:", uploadResult.id);
|
|
7942
|
-
const workflowData = {
|
|
7943
|
-
imagePath: {
|
|
7944
|
-
type: 'image',
|
|
7945
|
-
transfer_method: 'local_file',
|
|
7946
|
-
upload_file_id: uploadResult.id
|
|
7947
|
-
},
|
|
7948
|
-
context: context || "\u8BF7\u5206\u6790\u8FD9\u5F20\u56FE\u7247\u7684\u5185\u5BB9"
|
|
7949
|
-
};
|
|
7950
|
-
const workflowResponse = await invokeFlow({
|
|
7951
|
-
appid: 'app-AvlLh0nfN4l9oz1MSW4sEAQ6',
|
|
7952
|
-
data: workflowData
|
|
7953
|
-
});
|
|
7954
|
-
logger.info("Dify\u5DE5\u4F5C\u6D41\u8C03\u7528\u6210\u529F", {
|
|
7955
|
-
response: workflowResponse
|
|
7956
|
-
});
|
|
7957
|
-
let summary = "\u5206\u6790\u5B8C\u6210";
|
|
7958
|
-
if ('string' == typeof workflowResponse) summary = workflowResponse;
|
|
7959
|
-
else if (workflowResponse?.data?.text) summary = workflowResponse.data.text;
|
|
7960
|
-
else if (workflowResponse?.answer) summary = workflowResponse.answer;
|
|
7961
|
-
else if (workflowResponse?.outputs?.text) summary = workflowResponse.outputs.text;
|
|
7962
|
-
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"}`);
|
|
7963
|
-
return {
|
|
7964
|
-
summary: summary,
|
|
7965
|
-
details: {
|
|
7966
|
-
dify_response: workflowResponse,
|
|
7967
|
-
fallback_used: true
|
|
7968
|
-
},
|
|
7969
|
-
tags: [
|
|
7970
|
-
'dify-fallback'
|
|
7971
|
-
]
|
|
7972
|
-
};
|
|
7973
|
-
} catch (error) {
|
|
7974
|
-
logger.error("Dify\u670D\u52A1\u8C03\u7528\u5931\u8D25", {
|
|
7975
|
-
error: error instanceof Error ? error.message : String(error),
|
|
7976
|
-
imagePath: imagePath,
|
|
7977
|
-
context: context
|
|
7978
|
-
});
|
|
7979
|
-
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);
|
|
7980
|
-
}
|
|
7981
|
-
}
|
|
7982
8287
|
}
|
|
7983
8288
|
const ImageAnalysisParamsSchema = objectType({
|
|
7984
8289
|
image_path: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
7985
|
-
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")
|
|
7986
8291
|
});
|
|
7987
8292
|
const read_imageTool = {
|
|
7988
8293
|
name: "read_image",
|
|
7989
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",
|
|
7990
8295
|
inputSchema: {
|
|
7991
8296
|
image_path: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
7992
|
-
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")
|
|
7993
8298
|
},
|
|
7994
8299
|
handler: async (args)=>{
|
|
7995
8300
|
const analyzer = new ImageAnalyzer();
|
|
@@ -8315,7 +8620,7 @@ ${error?.message || "\u672A\u77E5\u9519\u8BEF"}`;
|
|
|
8315
8620
|
output_directory: stringType().optional().describe("\u8F93\u51FA\u76EE\u5F55\uFF0C\u4E0D\u6307\u5B9A\u5219\u5728\u539F\u6587\u4EF6\u76EE\u5F55\u751F\u6210")
|
|
8316
8621
|
});
|
|
8317
8622
|
const imageConverterTool = {
|
|
8318
|
-
name: "
|
|
8623
|
+
name: "image-converter",
|
|
8319
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",
|
|
8320
8625
|
inputSchema: {
|
|
8321
8626
|
input_paths: unionType([
|
|
@@ -8407,7 +8712,7 @@ ${results.map((r, index)=>`
|
|
|
8407
8712
|
- **\u{8F93}\u{51FA}**: \`${r.output_path}\`
|
|
8408
8713
|
- **\u{683C}\u{5F0F}**: ${r.format?.toUpperCase()}
|
|
8409
8714
|
- **\u{5C3A}\u{5BF8}**: ${r.dimensions?.width} \xd7 ${r.dimensions?.height}
|
|
8410
|
-
- **\u{6587}\u{4EF6}\u{5927}\u{5C0F}**: ${
|
|
8715
|
+
- **\u{6587}\u{4EF6}\u{5927}\u{5C0F}**: ${formatFileSize(r.file_size || 0)}
|
|
8411
8716
|
`).join("")}
|
|
8412
8717
|
|
|
8413
8718
|
${args.width || args.height ? `
|
|
@@ -8443,7 +8748,7 @@ ${successResults.map((r, index)=>`
|
|
|
8443
8748
|
${index + 1}. **${getFileName(r.input_path)}**
|
|
8444
8749
|
- \u{8F93}\u{51FA}: \`${r.output_path}\`
|
|
8445
8750
|
- \u{5C3A}\u{5BF8}: ${r.dimensions?.width} \xd7 ${r.dimensions?.height}
|
|
8446
|
-
- \u{5927}\u{5C0F}: ${
|
|
8751
|
+
- \u{5927}\u{5C0F}: ${formatFileSize(r.file_size || 0)}
|
|
8447
8752
|
`).join("")}
|
|
8448
8753
|
|
|
8449
8754
|
## \u{274C} \u{8F6C}\u{6362}\u{5931}\u{8D25} (${failedResults.length}\u{5F20})
|
|
@@ -8510,7 +8815,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
8510
8815
|
function getFileName(filePath) {
|
|
8511
8816
|
return filePath.split("/").pop() || filePath;
|
|
8512
8817
|
}
|
|
8513
|
-
function
|
|
8818
|
+
function formatFileSize(bytes) {
|
|
8514
8819
|
if (0 === bytes) return "0 B";
|
|
8515
8820
|
const k = 1024;
|
|
8516
8821
|
const sizes = [
|
|
@@ -8581,6 +8886,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
8581
8886
|
RETRY_DELAY_MS: 1000
|
|
8582
8887
|
};
|
|
8583
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"),
|
|
8584
8890
|
imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
8585
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")
|
|
8586
8892
|
});
|
|
@@ -8988,8 +9294,8 @@ ${getErrorSuggestion(error.code)}
|
|
|
8988
9294
|
}
|
|
8989
9295
|
class analyzer_ImageAnalyzer {
|
|
8990
9296
|
context;
|
|
8991
|
-
async
|
|
8992
|
-
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", {
|
|
8993
9299
|
imagePath,
|
|
8994
9300
|
totalSegments: segmentConfig.totalSegments,
|
|
8995
9301
|
maxConcurrency: concurrencyConfig.maxConcurrency,
|
|
@@ -8999,24 +9305,36 @@ ${getErrorSuggestion(error.code)}
|
|
|
8999
9305
|
const startTime = Date.now();
|
|
9000
9306
|
const segmentResults = [];
|
|
9001
9307
|
try {
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
const
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
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
|
+
}
|
|
9020
9338
|
const summary = this.generateProcessingSummary(segmentResults, startTime);
|
|
9021
9339
|
const result = {
|
|
9022
9340
|
imageInfo,
|
|
@@ -9025,7 +9343,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9025
9343
|
outputPath: '',
|
|
9026
9344
|
success: 0 === summary.failedSegments
|
|
9027
9345
|
};
|
|
9028
|
-
logger.info("\u957F\u56FE\u5206\u6790\u5B8C\u6210", {
|
|
9346
|
+
logger.info("\u957F\u56FE\u6D41\u5F0F\u5206\u6790\u5B8C\u6210", {
|
|
9029
9347
|
imagePath,
|
|
9030
9348
|
totalSegments: summary.totalSegments,
|
|
9031
9349
|
successfulSegments: summary.successfulSegments,
|
|
@@ -9034,7 +9352,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9034
9352
|
});
|
|
9035
9353
|
return result;
|
|
9036
9354
|
} catch (error) {
|
|
9037
|
-
logger.error("\u957F\u56FE\u5206\u6790\u5931\u8D25", {
|
|
9355
|
+
logger.error("\u957F\u56FE\u6D41\u5F0F\u5206\u6790\u5931\u8D25", {
|
|
9038
9356
|
imagePath,
|
|
9039
9357
|
error
|
|
9040
9358
|
});
|
|
@@ -9044,6 +9362,9 @@ ${getErrorSuggestion(error.code)}
|
|
|
9044
9362
|
});
|
|
9045
9363
|
}
|
|
9046
9364
|
}
|
|
9365
|
+
async analyzeLongImage(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference = 'auto', context) {
|
|
9366
|
+
return this.analyzeLongImageStreaming(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference, context);
|
|
9367
|
+
}
|
|
9047
9368
|
async processSegmentsConcurrently(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference) {
|
|
9048
9369
|
const results = [];
|
|
9049
9370
|
const { maxConcurrency, batchSize, delayBetweenBatches } = concurrencyConfig;
|
|
@@ -9223,7 +9544,7 @@ ${getErrorSuggestion(error.code)}
|
|
|
9223
9544
|
let prompt = '';
|
|
9224
9545
|
prompt = this.context ? `${this.context}
|
|
9225
9546
|
|
|
9226
|
-
|
|
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.
|
|
9227
9548
|
|
|
9228
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}
|
|
9229
9550
|
|
|
@@ -9241,7 +9562,10 @@ ${getErrorSuggestion(error.code)}
|
|
|
9241
9562
|
else prompt += `\u{8FD9}\u{662F}\u{56FE}\u{7247}\u{7684}\u{4E2D}\u{95F4}\u{90E8}\u{5206}\u{3002}`;
|
|
9242
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}`;
|
|
9243
9564
|
}
|
|
9244
|
-
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 += `
|
|
9245
9569
|
|
|
9246
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}
|
|
9247
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}`;
|
|
@@ -9347,11 +9671,13 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9347
9671
|
this.configCalculator = new ConfigCalculator();
|
|
9348
9672
|
this.analyzer = new analyzer_ImageAnalyzer();
|
|
9349
9673
|
}
|
|
9350
|
-
async processImage(imagePath, context) {
|
|
9674
|
+
async processImage(imagePath, projectPath, context, callbacks) {
|
|
9351
9675
|
const startTime = Date.now();
|
|
9352
9676
|
logger.info("ImageRecognitionProcessor: \u5F00\u59CB\u5904\u7406\u56FE\u7247", {
|
|
9353
9677
|
imagePath
|
|
9354
9678
|
});
|
|
9679
|
+
let outputPath = '';
|
|
9680
|
+
const segmentResults = [];
|
|
9355
9681
|
try {
|
|
9356
9682
|
await this.validateImageFile(imagePath);
|
|
9357
9683
|
const validation = await this.preprocessor.validateImage(imagePath);
|
|
@@ -9373,55 +9699,51 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9373
9699
|
segmentHeight: segmentConfig.segmentHeight,
|
|
9374
9700
|
maxConcurrency: concurrencyConfig.maxConcurrency
|
|
9375
9701
|
});
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
const totalTime = Date.now() - startTime;
|
|
9379
|
-
logger.info("\u56FE\u7247\u5904\u7406\u5B8C\u6210", {
|
|
9702
|
+
outputPath = await this.initializeOutputFile(imageInfo, segmentConfig.totalSegments, projectPath);
|
|
9703
|
+
callbacks?.onStart?.({
|
|
9380
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 = {
|
|
9381
9716
|
totalSegments: analysisResult.summary.totalSegments,
|
|
9382
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,
|
|
9383
9729
|
totalTimeMs: totalTime
|
|
9384
9730
|
});
|
|
9385
9731
|
return {
|
|
9386
9732
|
outputPath,
|
|
9387
|
-
summary
|
|
9388
|
-
totalSegments: analysisResult.summary.totalSegments,
|
|
9389
|
-
successfulSegments: analysisResult.summary.successfulSegments,
|
|
9390
|
-
failedSegments: analysisResult.summary.failedSegments,
|
|
9391
|
-
successRate: analysisResult.summary.successRate,
|
|
9392
|
-
totalTextCharacters: analysisResult.summary.totalTextCharacters,
|
|
9393
|
-
totalProcessingTimeMs: totalTime,
|
|
9394
|
-
averageConfidence: analysisResult.summary.averageConfidence
|
|
9395
|
-
}
|
|
9733
|
+
summary
|
|
9396
9734
|
};
|
|
9397
9735
|
} catch (error) {
|
|
9398
9736
|
logger.error("\u56FE\u7247\u5904\u7406\u5931\u8D25", {
|
|
9399
9737
|
imagePath,
|
|
9400
9738
|
error
|
|
9401
9739
|
});
|
|
9740
|
+
callbacks?.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
9402
9741
|
throw error;
|
|
9403
9742
|
}
|
|
9404
9743
|
}
|
|
9405
|
-
async
|
|
9406
|
-
try {
|
|
9407
|
-
const stats = await external_fs_namespaceObject.promises.stat(imagePath);
|
|
9408
|
-
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, {
|
|
9409
|
-
imagePath
|
|
9410
|
-
});
|
|
9411
|
-
} catch (error) {
|
|
9412
|
-
if ('ENOENT' === error.code) throw new ImageRecognitionError("\u56FE\u7247\u6587\u4EF6\u4E0D\u5B58\u5728", types_ErrorTypes.FILE_NOT_FOUND, {
|
|
9413
|
-
imagePath
|
|
9414
|
-
});
|
|
9415
|
-
throw new ImageRecognitionError(`\u{6587}\u{4EF6}\u{8BBF}\u{95EE}\u{9519}\u{8BEF}: ${error.message}`, types_ErrorTypes.VALIDATION_ERROR, {
|
|
9416
|
-
imagePath,
|
|
9417
|
-
originalError: error
|
|
9418
|
-
});
|
|
9419
|
-
}
|
|
9420
|
-
}
|
|
9421
|
-
async generateSingleOutputFile(imageInfo, segmentResults, summary) {
|
|
9422
|
-
const baseDir = getStorageDir();
|
|
9744
|
+
async initializeOutputFile(imageInfo, totalSegments, projectPath) {
|
|
9423
9745
|
const dateDir = new Date().toISOString().split('T')[0];
|
|
9424
|
-
const outputDirectory = external_path_namespaceObject.join(
|
|
9746
|
+
const outputDirectory = external_path_namespaceObject.join(projectPath, '.aico', 'image-recognition', dateDir);
|
|
9425
9747
|
await external_fs_namespaceObject.promises.mkdir(outputDirectory, {
|
|
9426
9748
|
recursive: true
|
|
9427
9749
|
});
|
|
@@ -9429,39 +9751,78 @@ Always ensure that your response reflects a clear, accurate interpretation of th
|
|
|
9429
9751
|
const imageBaseName = external_path_namespaceObject.basename(imageInfo.fileName, external_path_namespaceObject.extname(imageInfo.fileName));
|
|
9430
9752
|
const fileName = `${imageBaseName}-${timestamp}.md`;
|
|
9431
9753
|
const outputPath = external_path_namespaceObject.join(outputDirectory, fileName);
|
|
9432
|
-
const
|
|
9433
|
-
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}
|
|
9434
9755
|
|
|
9435
9756
|
**\u{8BC6}\u{522B}\u{65F6}\u{95F4}**: ${new Date().toLocaleString('zh-CN')}
|
|
9436
9757
|
**\u{56FE}\u{7247}\u{5C3A}\u{5BF8}**: ${imageInfo.width} \xd7 ${imageInfo.height} \u{50CF}\u{7D20}
|
|
9437
|
-
**\u{
|
|
9438
|
-
**\u{
|
|
9439
|
-
**\u{6587}\u{5B57}\u{5B57}\u{7B26}\u{603B}\u{6570}**: ${summary.totalTextCharacters.toLocaleString()}
|
|
9440
|
-
**\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}...
|
|
9441
9760
|
|
|
9442
9761
|
---
|
|
9443
9762
|
|
|
9444
9763
|
## \u{8BC6}\u{522B}\u{7684}\u{6587}\u{5B57}\u{5185}\u{5BB9}
|
|
9445
9764
|
|
|
9446
|
-
${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
|
|
9447
|
-
|
|
9448
|
-
---
|
|
9449
|
-
|
|
9450
|
-
**\u{8BC6}\u{522B}\u{5B8C}\u{6210}\u{65F6}\u{95F4}**: ${new Date().toLocaleString('zh-CN')}
|
|
9451
9765
|
`;
|
|
9452
|
-
await external_fs_namespaceObject.promises.writeFile(outputPath,
|
|
9453
|
-
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", {
|
|
9454
9768
|
outputPath,
|
|
9455
|
-
|
|
9456
|
-
contentLength: content.length
|
|
9769
|
+
totalSegments
|
|
9457
9770
|
});
|
|
9458
9771
|
return outputPath;
|
|
9459
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
|
+
}
|
|
9460
9820
|
}
|
|
9461
9821
|
const imageRecognitionAgentTool = {
|
|
9462
9822
|
name: "analyzeLongImage",
|
|
9463
|
-
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",
|
|
9464
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"),
|
|
9465
9826
|
imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
|
|
9466
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")
|
|
9467
9828
|
},
|
|
@@ -9471,13 +9832,21 @@ ${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
|
|
|
9471
9832
|
args
|
|
9472
9833
|
});
|
|
9473
9834
|
try {
|
|
9474
|
-
const { imagePath, context } = ImageRecognitionParamsSchema.parse(args);
|
|
9835
|
+
const { projectPath, imagePath, context } = ImageRecognitionParamsSchema.parse(args);
|
|
9475
9836
|
const processor = new ImageRecognitionProcessor();
|
|
9476
|
-
const result = await processor.processImage(imagePath, context);
|
|
9837
|
+
const result = await processor.processImage(imagePath, projectPath, context);
|
|
9477
9838
|
logger.info("\u56FE\u7247\u5185\u5BB9\u8BC6\u522B\u667A\u80FD\u4F53: \u5904\u7406\u5B8C\u6210", {
|
|
9478
9839
|
outputPath: result.outputPath,
|
|
9479
9840
|
summary: result.summary
|
|
9480
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
|
+
}
|
|
9481
9850
|
return {
|
|
9482
9851
|
content: [
|
|
9483
9852
|
{
|
|
@@ -9492,10 +9861,14 @@ ${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
|
|
|
9492
9861
|
- \u{5E73}\u{5747}\u{7F6E}\u{4FE1}\u{5EA6}: ${(100 * result.summary.averageConfidence).toFixed(1)}%
|
|
9493
9862
|
- \u{5904}\u{7406}\u{8017}\u{65F6}: ${(result.summary.totalProcessingTimeMs / 1000).toFixed(2)}\u{79D2}
|
|
9494
9863
|
|
|
9495
|
-
\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}**:
|
|
9496
9865
|
\`${result.outputPath}\`
|
|
9497
9866
|
|
|
9498
|
-
|
|
9867
|
+
---
|
|
9868
|
+
|
|
9869
|
+
## \u{8BC6}\u{522B}\u{7684}\u{5B8C}\u{6574}\u{5185}\u{5BB9}
|
|
9870
|
+
|
|
9871
|
+
${fileContent}`
|
|
9499
9872
|
}
|
|
9500
9873
|
]
|
|
9501
9874
|
};
|