intention-coding 0.5.6 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/dist/index.cjs +487 -732
  2. package/dist/services/image-analysis/analyzer.d.ts +0 -8
  3. package/dist/services/image-analysis/analyzer.d.ts.map +1 -1
  4. package/dist/services/image-analysis/index.d.ts.map +1 -1
  5. package/dist/services/image-recognition-agent/analyzer.d.ts +3 -1
  6. package/dist/services/image-recognition-agent/analyzer.d.ts.map +1 -1
  7. package/dist/services/image-recognition-agent/index.d.ts +1 -0
  8. package/dist/services/image-recognition-agent/index.d.ts.map +1 -1
  9. package/dist/services/image-recognition-agent/processor.d.ts +1 -1
  10. package/dist/services/image-recognition-agent/processor.d.ts.map +1 -1
  11. package/dist/services/image-recognition-agent/types.d.ts +3 -0
  12. package/dist/services/image-recognition-agent/types.d.ts.map +1 -1
  13. package/dist/services/requirement/index.d.ts.map +1 -1
  14. package/dist/services/requirement-analyzer/core/document-generator.d.ts +18 -2
  15. package/dist/services/requirement-analyzer/core/document-generator.d.ts.map +1 -1
  16. package/dist/services/requirement-analyzer/core/requirement-analyzer-service.d.ts +21 -10
  17. package/dist/services/requirement-analyzer/core/requirement-analyzer-service.d.ts.map +1 -1
  18. package/dist/services/requirement-analyzer/core/types.d.ts +22 -22
  19. package/dist/services/requirement-analyzer/core/types.d.ts.map +1 -1
  20. package/dist/services/requirement-analyzer/index.d.ts +12 -12
  21. package/dist/services/requirement-analyzer/index.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/dist/services/requirement-analyzer/core/parameter-bridge.d.ts +0 -44
  24. package/dist/services/requirement-analyzer/core/parameter-bridge.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -275,7 +275,7 @@ var __webpack_exports__ = {};
275
275
  if (null === _PROJECT_ROOT) _PROJECT_ROOT = detectProjectRoot();
276
276
  return _PROJECT_ROOT;
277
277
  };
278
- const config_PROJECT_ROOT = (()=>{
278
+ (()=>{
279
279
  try {
280
280
  return getProjectRoot();
281
281
  } catch (error) {
@@ -312,7 +312,6 @@ var __webpack_exports__ = {};
312
312
  description: "\u8F6F\u4EF6\u5DE5\u7A0B\u5316\u7684\u9700\u6C42\u5206\u6790\uFF0C\u529F\u80FD\u8BBE\u8BA1\uFF0C\u4EE3\u7801\u7F16\u5199\uFF0C\u6D4B\u8BD5\u8FD0\u884C\u548C\u53D1\u5E03\u90E8\u7F72"
313
313
  };
314
314
  const promises_namespaceObject = require("fs/promises");
315
- var promises_default = /*#__PURE__*/ __webpack_require__.n(promises_namespaceObject);
316
315
  const external_mammoth_namespaceObject = require("mammoth");
317
316
  var external_mammoth_default = /*#__PURE__*/ __webpack_require__.n(external_mammoth_namespaceObject);
318
317
  const external_html_to_md_namespaceObject = require("html-to-md");
@@ -4182,210 +4181,12 @@ var __webpack_exports__ = {};
4182
4181
  }
4183
4182
  }
4184
4183
  };
4185
- class ParameterBridge {
4186
- static ToolParamsSchema = objectType({
4187
- input_type: enumType([
4188
- "text",
4189
- "md_file"
4190
- ]).describe("\u8F93\u5165\u7C7B\u578B\uFF1A\u76F4\u63A5\u6587\u672C\u8F93\u5165\u6216\u5F15\u7528\u5DF2\u751F\u6210\u7684MD\u6587\u4EF6"),
4191
- content: stringType().optional().describe("\u5F53input_type\u4E3Atext\u65F6\uFF0C\u76F4\u63A5\u8F93\u5165\u7684\u9700\u6C42\u5185\u5BB9"),
4192
- md_file_path: stringType().optional().describe("\u5F53input_type\u4E3Amd_file\u65F6\uFF0C\u8981\u5206\u6790\u7684MD\u6587\u4EF6\u8DEF\u5F84"),
4193
- feature_name: stringType().describe("\u529F\u80FD\u540D\u79F0\uFF0C\u7528\u4E8E\u751F\u6210\u8F93\u51FA\u6587\u4EF6\u540D"),
4194
- custom_prompt: stringType().optional().describe("\u81EA\u5B9A\u4E49\u63D0\u793A\u8BCD\uFF0C\u7528\u4E8E\u6307\u5BFCAI\u751F\u6210\u7279\u5B9A\u98CE\u683C\u7684\u9700\u6C42\u6587\u6863"),
4195
- analysis_depth: enumType([
4196
- "basic",
4197
- "detailed",
4198
- "comprehensive"
4199
- ]).default("detailed").describe("\u5206\u6790\u6DF1\u5EA6\uFF1A\u57FA\u7840\u3001\u8BE6\u7EC6\u3001\u7EFC\u5408"),
4200
- use_streaming: booleanType().default(false).describe("\u662F\u5426\u4F7F\u7528\u6D41\u5F0F\u5904\u7406\uFF08\u9002\u7528\u4E8E\u5927\u6587\u4EF6\uFF09"),
4201
- chunk_size: numberType().min(10).max(1000).default(100).describe("\u5206\u5757\u5927\u5C0F\uFF08\u4EC5\u5728use_streaming\u4E3Atrue\u65F6\u6709\u6548\uFF09")
4202
- }).refine((data)=>{
4203
- if ("text" === data.input_type) return data.content && data.content.trim().length > 0;
4204
- if ("md_file" === data.input_type) return data.md_file_path && data.md_file_path.trim().length > 0;
4205
- return false;
4206
- }, {
4207
- message: "\u5F53input_type\u4E3Atext\u65F6content\u5FC5\u586B\uFF0C\u5F53input_type\u4E3Amd_file\u65F6md_file_path\u5FC5\u586B"
4208
- });
4209
- static validateToolParams(args) {
4210
- try {
4211
- const result = ParameterBridge.ToolParamsSchema.safeParse(args);
4212
- if (result.success) return {
4213
- success: true,
4214
- data: result.data
4215
- };
4216
- {
4217
- const errorMessages = result.error.errors.map((err)=>`${err.path.join('.')}: ${err.message}`).join('; ');
4218
- return {
4219
- success: false,
4220
- error: `\u{53C2}\u{6570}\u{9A8C}\u{8BC1}\u{5931}\u{8D25}: ${errorMessages}`
4221
- };
4222
- }
4223
- } catch (error) {
4224
- return {
4225
- success: false,
4226
- error: `\u{53C2}\u{6570}\u{9A8C}\u{8BC1}\u{5F02}\u{5E38}: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
4227
- };
4228
- }
4229
- }
4230
- static convertToServiceParams(toolParams) {
4231
- return {
4232
- input_type: toolParams.input_type,
4233
- content: toolParams.content,
4234
- md_file_path: toolParams.md_file_path,
4235
- feature_name: toolParams.feature_name,
4236
- custom_prompt: toolParams.custom_prompt,
4237
- analysis_depth: toolParams.analysis_depth,
4238
- use_streaming: toolParams.use_streaming,
4239
- chunk_size: toolParams.chunk_size
4240
- };
4241
- }
4242
- static convertToToolResponse(serviceResult) {
4243
- if (false === serviceResult.success) return {
4244
- content: [
4245
- {
4246
- type: "text",
4247
- text: JSON.stringify({
4248
- success: false,
4249
- message: serviceResult.message,
4250
- data: serviceResult.data || null
4251
- })
4252
- }
4253
- ],
4254
- isError: true
4255
- };
4256
- return {
4257
- content: [
4258
- {
4259
- type: "text",
4260
- text: JSON.stringify({
4261
- success: true,
4262
- message: serviceResult.message || "\u9700\u6C42\u5206\u6790\u5B8C\u6210",
4263
- data: {
4264
- outputPath: serviceResult.outputPath,
4265
- generatedFiles: serviceResult.generatedFiles || [],
4266
- analysisInfo: serviceResult.analysisInfo || {}
4267
- }
4268
- })
4269
- }
4270
- ]
4271
- };
4272
- }
4273
- static convertErrorToToolResponse(error) {
4274
- return {
4275
- content: [
4276
- {
4277
- type: "text",
4278
- text: JSON.stringify({
4279
- success: false,
4280
- message: error.message || "\u9700\u6C42\u5206\u6790\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF",
4281
- data: {
4282
- code: error.code || 'UNKNOWN_ERROR',
4283
- context: error.context || null
4284
- }
4285
- })
4286
- }
4287
- ],
4288
- isError: true
4289
- };
4290
- }
4291
- }
4292
- async function readLargeFileContent(filePath, chunkSize = 100) {
4293
- try {
4294
- logger.info("\u5F00\u59CB\u5206\u6BB5\u8BFB\u53D6\u5927\u6587\u4EF6", {
4295
- filePath,
4296
- chunkSize
4297
- });
4298
- const content = await promises_namespaceObject.readFile(filePath, 'utf8');
4299
- const lines = content.split('\n');
4300
- if (lines.length <= chunkSize) {
4301
- logger.info("\u6587\u4EF6\u884C\u6570\u8F83\u5C11\uFF0C\u76F4\u63A5\u8FD4\u56DE\u5B8C\u6574\u5185\u5BB9", {
4302
- totalLines: lines.length
4303
- });
4304
- return content;
4305
- }
4306
- const importantContent = selectImportantContent(lines, chunkSize);
4307
- logger.info("\u5927\u6587\u4EF6\u5206\u6BB5\u8BFB\u53D6\u5B8C\u6210", {
4308
- originalLines: lines.length,
4309
- selectedLines: importantContent.split('\n').length
4310
- });
4311
- return importantContent;
4312
- } catch (error) {
4313
- logger.error("\u5927\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25", {
4314
- error,
4315
- filePath
4316
- });
4317
- throw error;
4318
- }
4319
- }
4320
- function selectImportantContent(lines, maxLines) {
4321
- const importantLines = [];
4322
- const headerLines = [];
4323
- const contentLines = [];
4324
- for (const line of lines){
4325
- const trimmedLine = line.trim();
4326
- if (trimmedLine.startsWith('#')) headerLines.push(line);
4327
- else if (trimmedLine.length > 0 && !isBoilerplate(trimmedLine)) contentLines.push(line);
4328
- }
4329
- importantLines.push(...headerLines);
4330
- const remainingLines = maxLines - headerLines.length;
4331
- if (remainingLines > 0) {
4332
- const selectedContent = selectMostImportantContent(contentLines, remainingLines);
4333
- importantLines.push(...selectedContent);
4334
- }
4335
- return importantLines.join('\n');
4336
- }
4337
- function selectMostImportantContent(contentLines, maxLines) {
4338
- if (contentLines.length <= maxLines) return contentLines;
4339
- const scoredLines = contentLines.map((line)=>({
4340
- line,
4341
- score: calculateImportanceScore(line)
4342
- }));
4343
- scoredLines.sort((a, b)=>b.score - a.score);
4344
- return scoredLines.slice(0, maxLines).map((item)=>item.line);
4345
- }
4346
- function calculateImportanceScore(line) {
4347
- let score = 0;
4348
- const trimmedLine = line.trim().toLowerCase();
4349
- const keywords = [
4350
- "\u9700\u6C42",
4351
- "\u529F\u80FD",
4352
- "\u63A5\u53E3",
4353
- 'api',
4354
- "\u9875\u9762",
4355
- "\u7528\u6237",
4356
- "\u7CFB\u7EDF",
4357
- "\u5B9E\u73B0",
4358
- "\u5F00\u53D1",
4359
- "\u8BBE\u8BA1",
4360
- "\u4E1A\u52A1",
4361
- "\u6D41\u7A0B",
4362
- "\u6570\u636E",
4363
- "\u670D\u52A1"
4364
- ];
4365
- for (const keyword of keywords)if (trimmedLine.includes(keyword)) score += 2;
4366
- if (trimmedLine.length > 10 && trimmedLine.length < 200) score += 1;
4367
- if (trimmedLine.includes("\uFF1A") || trimmedLine.includes(':')) score += 1;
4368
- return score;
4369
- }
4370
- function isBoilerplate(line) {
4371
- const boilerplatePatterns = [
4372
- /^-+$/,
4373
- /^=+$/,
4374
- /^\s*$/,
4375
- /^#+\s*$/,
4376
- /^目录$/,
4377
- /^table of contents$/i,
4378
- /^generated by/i,
4379
- /^created by/i
4380
- ];
4381
- return boilerplatePatterns.some((pattern)=>pattern.test(line.trim()));
4382
- }
4383
4184
  class RequirementAnalysisError extends Error {
4384
4185
  code;
4385
4186
  context;
4386
4187
  constructor(message, code, context){
4387
4188
  super(message), this.code = code, this.context = context;
4388
- this.name = 'RequirementAnalysisError';
4189
+ this.name = "RequirementAnalysisError";
4389
4190
  }
4390
4191
  }
4391
4192
  var types_ErrorCodes = /*#__PURE__*/ function(ErrorCodes) {
@@ -4398,160 +4199,6 @@ var __webpack_exports__ = {};
4398
4199
  ErrorCodes["UNSUPPORTED_REQUIREMENT_TYPE"] = "UNSUPPORTED_REQUIREMENT_TYPE";
4399
4200
  return ErrorCodes;
4400
4201
  }({});
4401
- const external_aico_pack_namespaceObject = require("aico-pack");
4402
- async function packProject(projectPath) {
4403
- const mdDir = external_path_default().join(getStorageDir(), 'tech');
4404
- await promises_default().mkdir(mdDir, {
4405
- recursive: true
4406
- });
4407
- logger.info(`\u{1F4C2} \u{6B63}\u{5728}\u{5206}\u{6790}\u{5F53}\u{524D}\u{672C}\u{5730}\u{9879}\u{76EE}`);
4408
- const mdPath = external_path_default().join(mdDir, `\u{9879}\u{76EE}\u{67B6}\u{6784}\u{5206}\u{6790}.md`);
4409
- const options = {
4410
- output: mdPath,
4411
- style: 'markdown',
4412
- headerText: "\u667A\u80FD\u8F6F\u4EF6\u661F\u5DE5\u5382",
4413
- fileSummary: true,
4414
- removeEmptyLines: true,
4415
- removeComments: true,
4416
- showLineNumbers: true,
4417
- compress: true,
4418
- quiet: true,
4419
- customPatterns: [
4420
- "**/*.md",
4421
- "**/*.log",
4422
- "**/*.json",
4423
- "**/*.txt",
4424
- "**/*.dockerfile",
4425
- "**/*.yml",
4426
- "**/*.yaml",
4427
- "**/*.sh",
4428
- "**/*.env",
4429
- "**/*.env.example",
4430
- "**/LICENSE",
4431
- "**/test/**"
4432
- ]
4433
- };
4434
- const targetPath = projectPath || config_PROJECT_ROOT;
4435
- await (0, external_aico_pack_namespaceObject.runCli)([
4436
- targetPath
4437
- ], process.cwd(), options);
4438
- return mdPath;
4439
- }
4440
- class ProjectAnalyzer {
4441
- async analyzeProject() {
4442
- try {
4443
- logger.info("\u5F00\u59CB\u5206\u6790\u9879\u76EE\u57FA\u672C\u60C5\u51B5");
4444
- const projectAnalysisPath = await packProject();
4445
- logger.info("\u9879\u76EE\u5206\u6790\u5B8C\u6210", {
4446
- analysisPath: projectAnalysisPath
4447
- });
4448
- const projectAnalysisContent = await promises_namespaceObject.readFile(projectAnalysisPath, 'utf8');
4449
- const projectInfo = this.extractProjectInfo(projectAnalysisContent);
4450
- logger.info("\u9879\u76EE\u4FE1\u606F\u63D0\u53D6\u5B8C\u6210", {
4451
- projectInfo
4452
- });
4453
- return projectInfo;
4454
- } catch (error) {
4455
- logger.warn("\u9879\u76EE\u5206\u6790\u5931\u8D25\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E", {
4456
- error
4457
- });
4458
- return this.getDefaultProjectInfo();
4459
- }
4460
- }
4461
- extractProjectInfo(projectAnalysis) {
4462
- const projectInfo = {
4463
- techStack: [],
4464
- frameworks: [],
4465
- language: '',
4466
- projectType: '',
4467
- dependencies: []
4468
- };
4469
- const techStackKeywords = [
4470
- 'React',
4471
- 'Vue',
4472
- 'Angular',
4473
- 'Svelte',
4474
- 'Node.js',
4475
- 'Express',
4476
- 'Koa',
4477
- 'Fastify',
4478
- 'Python',
4479
- 'Django',
4480
- 'Flask',
4481
- 'Java',
4482
- 'Spring',
4483
- 'Spring Boot',
4484
- 'TypeScript',
4485
- 'JavaScript',
4486
- 'PostgreSQL',
4487
- 'MySQL',
4488
- 'MongoDB',
4489
- 'Redis',
4490
- 'Docker',
4491
- 'Kubernetes'
4492
- ];
4493
- const frameworkKeywords = [
4494
- 'React',
4495
- 'Vue',
4496
- 'Angular',
4497
- 'Svelte',
4498
- 'Express',
4499
- 'Koa',
4500
- 'Fastify',
4501
- 'Django',
4502
- 'Flask',
4503
- 'Spring',
4504
- 'Spring Boot',
4505
- 'Next.js',
4506
- 'Nuxt.js'
4507
- ];
4508
- const languageKeywords = [
4509
- 'TypeScript',
4510
- 'JavaScript',
4511
- 'Python',
4512
- 'Java',
4513
- 'Go',
4514
- 'Rust',
4515
- 'C#'
4516
- ];
4517
- for (const keyword of techStackKeywords)if (projectAnalysis.includes(keyword)) projectInfo.techStack.push(keyword);
4518
- for (const keyword of frameworkKeywords)if (projectAnalysis.includes(keyword)) projectInfo.frameworks.push(keyword);
4519
- for (const keyword of languageKeywords)if (projectAnalysis.includes(keyword)) {
4520
- projectInfo.language = keyword;
4521
- break;
4522
- }
4523
- projectInfo.projectType = this.determineProjectType(projectAnalysis);
4524
- projectInfo.dependencies = this.extractDependencies(projectAnalysis);
4525
- return projectInfo;
4526
- }
4527
- determineProjectType(projectAnalysis) {
4528
- if (projectAnalysis.includes('package.json')) return "Node.js\u9879\u76EE";
4529
- if (projectAnalysis.includes('requirements.txt') || projectAnalysis.includes('pyproject.toml')) return "Python\u9879\u76EE";
4530
- if (projectAnalysis.includes('pom.xml') || projectAnalysis.includes('build.gradle')) return "Java\u9879\u76EE";
4531
- if (projectAnalysis.includes('Cargo.toml')) return "Rust\u9879\u76EE";
4532
- if (projectAnalysis.includes('go.mod')) return "Go\u9879\u76EE";
4533
- else return "\u901A\u7528\u9879\u76EE";
4534
- }
4535
- extractDependencies(projectAnalysis) {
4536
- const dependencyMatch = projectAnalysis.match(/## 依赖.*?```.*?\n([\s\S]*?)\n```/);
4537
- if (dependencyMatch && dependencyMatch[1]) return dependencyMatch[1].split('\n').filter((line)=>'' !== line.trim()).map((line)=>line.trim()).slice(0, 10);
4538
- return [];
4539
- }
4540
- getDefaultProjectInfo() {
4541
- return {
4542
- techStack: [],
4543
- frameworks: [],
4544
- language: '',
4545
- projectType: "\u901A\u7528\u9879\u76EE",
4546
- dependencies: []
4547
- };
4548
- }
4549
- validateProjectInfo(projectInfo) {
4550
- if (!projectInfo.projectType) throw new RequirementAnalysisError("\u65E0\u6CD5\u786E\u5B9A\u9879\u76EE\u7C7B\u578B\uFF0C\u8BF7\u68C0\u67E5\u9879\u76EE\u7ED3\u6784", types_ErrorCodes.PROJECT_ANALYSIS_FAILED, {
4551
- projectInfo
4552
- });
4553
- }
4554
- }
4555
4202
  class OpenAIService {
4556
4203
  qwenConfig = {
4557
4204
  apiKey: 'sk-95b0bc60b7464bbbafd64edc2f5bab14',
@@ -7794,21 +7441,49 @@ Scenario Outline: API\u{9650}\u{6D41}\u{4E0E}\u{9519}\u{8BEF}\u{6062}\u{590D}\u{
7794
7441
  }
7795
7442
  class DocumentGenerator {
7796
7443
  templateSelector = new TemplateSelector();
7797
- async generateUnifiedDocument(analysis, projectInfo, featureName, sourceInfo, customPrompt) {
7444
+ async generateUnifiedDocument(analysis, projectInfo, featureName, sourceInfo, customPrompt, currentProjectPath) {
7798
7445
  try {
7799
7446
  logger.info("\u5F00\u59CB\u751F\u6210\u7EDF\u4E00\u6280\u672F\u6587\u6863", {
7800
7447
  featureName,
7801
7448
  requirementType: analysis.requirementType,
7802
- featureCount: analysis.requirements.length
7803
- });
7804
- const { outputPath, requirementDir } = await this.prepareOutputPath(featureName);
7805
- const unifiedContent = this.buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo);
7806
- const document = await this.generateDocument(unifiedContent, featureName, analysis.requirementType, projectInfo, customPrompt);
7807
- await promises_namespaceObject.writeFile(outputPath, document, 'utf8');
7808
- const result = this.buildAnalysisResult(analysis, projectInfo, outputPath, sourceInfo);
7809
- logger.info("\u7EDF\u4E00\u6280\u672F\u6587\u6863\u751F\u6210\u5B8C\u6210", {
7810
- outputPath,
7811
- documentLength: document.length
7449
+ featureCount: analysis.requirements.length,
7450
+ currentProjectPath
7451
+ });
7452
+ const requirementTypes = this.parseRequirementTypes(analysis.requirementType);
7453
+ const reportTasks = requirementTypes.map(async (reqType)=>{
7454
+ logger.info("\u751F\u6210\u62A5\u544A", {
7455
+ requirementType: reqType,
7456
+ featureName
7457
+ });
7458
+ const { outputPath } = await this.prepareOutputPath(featureName, currentProjectPath, reqType);
7459
+ const isUpdate = await this.checkFileExists(outputPath);
7460
+ let existingContent = null;
7461
+ if (isUpdate) {
7462
+ logger.info("\u68C0\u6D4B\u5230\u5DF2\u5B58\u5728\u62A5\u544A\uFF0C\u5C06\u8FDB\u884C\u589E\u91CF\u66F4\u65B0", {
7463
+ outputPath
7464
+ });
7465
+ existingContent = await promises_namespaceObject.readFile(outputPath, "utf8");
7466
+ }
7467
+ const unifiedContent = this.buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo);
7468
+ const document = isUpdate && existingContent ? await this.updateExistingDocument(existingContent, unifiedContent, featureName, reqType, projectInfo, customPrompt) : await this.generateDocument(unifiedContent, featureName, reqType, projectInfo, customPrompt);
7469
+ await promises_namespaceObject.writeFile(outputPath, document, "utf8");
7470
+ logger.info("\u62A5\u544A\u751F\u6210\u5B8C\u6210", {
7471
+ requirementType: reqType,
7472
+ outputPath,
7473
+ documentLength: document.length
7474
+ });
7475
+ return {
7476
+ requirementType: reqType,
7477
+ outputPath,
7478
+ isUpdate
7479
+ };
7480
+ });
7481
+ const analysisInfos = await Promise.all(reportTasks);
7482
+ const generatedFiles = analysisInfos.map((info)=>info.outputPath);
7483
+ const result = this.buildAnalysisResult(analysis, projectInfo, generatedFiles[0], sourceInfo, analysisInfos[0].isUpdate, generatedFiles, analysisInfos);
7484
+ logger.info("\u6240\u6709\u6280\u672F\u6587\u6863\u751F\u6210\u5B8C\u6210", {
7485
+ totalFiles: generatedFiles.length,
7486
+ files: generatedFiles
7812
7487
  });
7813
7488
  return result;
7814
7489
  } catch (error) {
@@ -7823,14 +7498,48 @@ Scenario Outline: API\u{9650}\u{6D41}\u{4E0E}\u{9519}\u{8BEF}\u{6062}\u{590D}\u{
7823
7498
  });
7824
7499
  }
7825
7500
  }
7826
- async prepareOutputPath(featureName) {
7827
- const requirementDir = external_path_default().join(getStorageDir(), 'requirements', sanitizeFileName(featureName));
7501
+ parseRequirementTypes(requirementType) {
7502
+ const validTypes = [
7503
+ "PC",
7504
+ "API",
7505
+ "APP",
7506
+ "SDK"
7507
+ ];
7508
+ if (requirementType.includes("+")) {
7509
+ const types = requirementType.split("+").map((t)=>t.trim().toUpperCase());
7510
+ return types.filter((t)=>validTypes.includes(t));
7511
+ }
7512
+ const normalizedType = requirementType.toUpperCase();
7513
+ if (validTypes.includes(normalizedType)) return [
7514
+ normalizedType
7515
+ ];
7516
+ const typeMapping = {
7517
+ PC页面: "PC",
7518
+ 接口: "API",
7519
+ APP: "APP",
7520
+ SDK集成: "SDK"
7521
+ };
7522
+ return [
7523
+ typeMapping[requirementType] || "API"
7524
+ ];
7525
+ }
7526
+ async prepareOutputPath(featureName, currentProjectPath, requirementType) {
7527
+ const projectRoot = currentProjectPath || process.cwd();
7528
+ const designDir = external_path_default().join(projectRoot, ".aico", "design");
7529
+ const requirementDir = external_path_default().join(designDir, sanitizeFileName(featureName));
7828
7530
  await promises_namespaceObject.mkdir(requirementDir, {
7829
7531
  recursive: true
7830
7532
  });
7831
7533
  const sanitizedFeatureName = sanitizeFileName(featureName);
7832
- const outputFileName = `${sanitizedFeatureName}.md`;
7534
+ const outputFileName = requirementType ? `${sanitizedFeatureName}-${requirementType}.md` : `${sanitizedFeatureName}.md`;
7833
7535
  const outputPath = external_path_default().join(requirementDir, outputFileName);
7536
+ logger.info("\u8F93\u51FA\u8DEF\u5F84\u51C6\u5907\u5B8C\u6210", {
7537
+ projectRoot,
7538
+ designDir,
7539
+ requirementDir,
7540
+ outputPath,
7541
+ requirementType
7542
+ });
7834
7543
  return {
7835
7544
  outputPath,
7836
7545
  requirementDir
@@ -7839,23 +7548,23 @@ Scenario Outline: API\u{9650}\u{6D41}\u{4E0E}\u{9519}\u{8BEF}\u{6062}\u{590D}\u{
7839
7548
  buildUnifiedContent(analysis, projectInfo, featureName, sourceInfo) {
7840
7549
  const featuresToProcess = analysis.featureDependencies?.mergedFeatures || analysis.requirements;
7841
7550
  const combinedFeatureContent = featuresToProcess.map((feature, index)=>{
7842
- const featureTitle = 'title' in feature ? feature.title : feature.featureName;
7843
- const featureContent = 'fullContent' in feature ? feature.fullContent : feature.description;
7551
+ const featureTitle = "title" in feature ? feature.title : feature.featureName;
7552
+ const featureContent = "fullContent" in feature ? feature.fullContent : feature.description;
7844
7553
  return `## \u{529F}\u{80FD}\u{70B9}${index + 1}\u{FF1A}${featureTitle}\n\n${featureContent}`;
7845
- }).join('\n\n');
7554
+ }).join("\n\n");
7846
7555
  return `# ${featureName} - \u{7EDF}\u{4E00}\u{9700}\u{6C42}\u{5206}\u{6790}
7847
7556
 
7848
7557
  ## \u{9879}\u{76EE}\u{57FA}\u{672C}\u{4FE1}\u{606F}
7849
7558
  - **\u{9879}\u{76EE}\u{7C7B}\u{578B}**: ${projectInfo?.projectType || "\u901A\u7528\u9879\u76EE"}
7850
- - **\u{4E3B}\u{8981}\u{6280}\u{672F}\u{6808}**: ${projectInfo?.techStack?.join(', ') || "\u5F85\u786E\u5B9A"}
7851
- - **\u{5F00}\u{53D1}\u{6846}\u{67B6}**: ${projectInfo?.frameworks?.join(', ') || "\u5F85\u786E\u5B9A"}
7559
+ - **\u{4E3B}\u{8981}\u{6280}\u{672F}\u{6808}**: ${projectInfo?.techStack?.join(", ") || "\u5F85\u786E\u5B9A"}
7560
+ - **\u{5F00}\u{53D1}\u{6846}\u{67B6}**: ${projectInfo?.frameworks?.join(", ") || "\u5F85\u786E\u5B9A"}
7852
7561
  - **\u{7F16}\u{7A0B}\u{8BED}\u{8A00}**: ${projectInfo?.language || "\u5F85\u786E\u5B9A"}
7853
7562
 
7854
7563
  ## \u{9700}\u{6C42}\u{7C7B}\u{578B}\u{5206}\u{6790}
7855
7564
  - **\u{8BC6}\u{522B}\u{7C7B}\u{578B}**: ${analysis.requirementType}
7856
7565
  - **\u{63A8}\u{8350}\u{6A21}\u{677F}**: ${analysis.templateRecommendation.primaryTemplate}
7857
7566
  - **\u{529F}\u{80FD}\u{70B9}\u{6570}\u{91CF}**: ${featuresToProcess.length}\u{4E2A}
7858
- - **\u{7F6E}\u{4FE1}\u{5EA6}**: ${analysis.confidence || 'medium'}
7567
+ - **\u{7F6E}\u{4FE1}\u{5EA6}**: ${analysis.confidence || "medium"}
7859
7568
 
7860
7569
  ## \u{529F}\u{80FD}\u{70B9}\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}
7861
7570
 
@@ -7870,7 +7579,7 @@ ${combinedFeatureContent}
7870
7579
  try {
7871
7580
  const template = this.templateSelector.selectTemplate(requirementType);
7872
7581
  this.templateSelector.validateTemplate(template, requirementType);
7873
- const fullPrompt = this.buildDocumentPrompt(template, content, title, projectInfo, customPrompt);
7582
+ const fullPrompt = this.buildDocumentPrompt(template, content, title, projectInfo, customPrompt, requirementType);
7874
7583
  const document = await openAIService.generateText({
7875
7584
  prompt: fullPrompt,
7876
7585
  system_prompt: "\u4F60\u662F\u4E00\u4F4D\u4E13\u4E1A\u7684\u6280\u672F\u6587\u6863\u7F16\u5199\u4E13\u5BB6\uFF0C\u8BF7\u751F\u6210\u5B8C\u6574\u3001\u8BE6\u7EC6\u7684\u6280\u672F\u9700\u6C42\u6587\u6863\u3002"
@@ -7888,14 +7597,91 @@ ${combinedFeatureContent}
7888
7597
  });
7889
7598
  }
7890
7599
  }
7891
- buildDocumentPrompt(template, content, title, projectInfo, customPrompt) {
7892
- let prompt = template.replace(/\{featureName\}/g, title).replace(/\{inputContent\}/g, content).replace(/\{currentTime\}/g, new Date().toISOString()).replace(/\{businessDomain\}/g, projectInfo?.projectType || "\u901A\u7528\u4E1A\u52A1").replace(/\{generateSequenceDiagram\}/g, 'true');
7600
+ buildDocumentPrompt(template, content, title, projectInfo, customPrompt, requirementType) {
7601
+ const businessDomain = this.mapRequirementTypeToBusinessDomain(requirementType);
7602
+ 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");
7893
7603
  if (customPrompt) prompt += `
7894
7604
 
7895
7605
  ## \u{81EA}\u{5B9A}\u{4E49}\u{8981}\u{6C42}
7896
7606
  ${customPrompt}`;
7897
7607
  return prompt;
7898
7608
  }
7609
+ mapRequirementTypeToBusinessDomain(requirementType) {
7610
+ if (!requirementType) return "API";
7611
+ const typeMapping = {
7612
+ PC: "PC",
7613
+ API: "API",
7614
+ APP: "APP",
7615
+ SDK: "SDK",
7616
+ PC页面: "PC",
7617
+ 接口: "API",
7618
+ SDK集成: "SDK"
7619
+ };
7620
+ return typeMapping[requirementType] || requirementType;
7621
+ }
7622
+ async checkFileExists(filePath) {
7623
+ try {
7624
+ await promises_namespaceObject.access(filePath);
7625
+ return true;
7626
+ } catch {
7627
+ return false;
7628
+ }
7629
+ }
7630
+ async updateExistingDocument(existingContent, newContent, title, requirementType, projectInfo, customPrompt) {
7631
+ try {
7632
+ logger.info("\u5F00\u59CB\u667A\u80FD\u5408\u5E76\u66F4\u65B0\u6587\u6863", {
7633
+ title
7634
+ });
7635
+ const template = this.templateSelector.selectTemplate(requirementType);
7636
+ const updatePrompt = `
7637
+ # \u{4EFB}\u{52A1}\u{FF1A}\u{667A}\u{80FD}\u{66F4}\u{65B0}\u{9700}\u{6C42}\u{5206}\u{6790}\u{62A5}\u{544A}
7638
+
7639
+ ## \u{5DF2}\u{5B58}\u{5728}\u{7684}\u{62A5}\u{544A}\u{5185}\u{5BB9}\u{FF1A}
7640
+ \u{3010}\u{3010}\u{3010}\u{65E7}\u{5185}\u{5BB9}\u{5F00}\u{59CB}\u{3011}\u{3011}\u{3011}
7641
+ ${existingContent}
7642
+ \u{3010}\u{3010}\u{3010}\u{65E7}\u{5185}\u{5BB9}\u{7ED3}\u{675F}\u{3011}\u{3011}\u{3011}
7643
+
7644
+ ## \u{65B0}\u{589E}\u{7684}\u{9700}\u{6C42}\u{4FE1}\u{606F}\u{FF1A}
7645
+ \u{3010}\u{3010}\u{3010}\u{65B0}\u{5185}\u{5BB9}\u{5F00}\u{59CB}\u{3011}\u{3011}\u{3011}
7646
+ ${newContent}
7647
+ \u{3010}\u{3010}\u{3010}\u{65B0}\u{5185}\u{5BB9}\u{7ED3}\u{675F}\u{3011}\u{3011}\u{3011}
7648
+
7649
+ ## \u{66F4}\u{65B0}\u{8981}\u{6C42}\u{FF1A}
7650
+ 1. **\u{667A}\u{80FD}\u{5408}\u{5E76}**\u{FF1A}\u{5C06}\u{65B0}\u{5185}\u{5BB9}\u{4E0E}\u{65E7}\u{5185}\u{5BB9}\u{8FDB}\u{884C}\u{667A}\u{80FD}\u{5408}\u{5E76}\u{FF0C}\u{4E0D}\u{662F}\u{7B80}\u{5355}\u{8986}\u{76D6}
7651
+ 2. **\u{4FDD}\u{7559}\u{6709}\u{6548}\u{4FE1}\u{606F}**\u{FF1A}\u{4FDD}\u{7559}\u{65E7}\u{62A5}\u{544A}\u{4E2D}\u{4ECD}\u{7136}\u{6709}\u{6548}\u{7684}\u{5185}\u{5BB9}
7652
+ 3. **\u{66F4}\u{65B0}\u{53D8}\u{5316}\u{9879}**\u{FF1A}\u{5982}\u{679C}\u{65B0}\u{5185}\u{5BB9}\u{4E0E}\u{65E7}\u{5185}\u{5BB9}\u{6709}\u{51B2}\u{7A81}\u{FF0C}\u{4EE5}\u{65B0}\u{5185}\u{5BB9}\u{4E3A}\u{51C6}
7653
+ 4. **\u{589E}\u{91CF}\u{6DFB}\u{52A0}**\u{FF1A}\u{5982}\u{679C}\u{662F}\u{65B0}\u{589E}\u{529F}\u{80FD}\u{70B9}\u{FF0C}\u{5219}\u{6DFB}\u{52A0}\u{5230}\u{539F}\u{6709}\u{529F}\u{80FD}\u{70B9}\u{5217}\u{8868}\u{4E2D}
7654
+ 5. **\u{4FDD}\u{6301}\u{7ED3}\u{6784}**\u{FF1A}\u{4FDD}\u{6301}\u{539F}\u{6709}\u{62A5}\u{544A}\u{7684}\u{6587}\u{6863}\u{7ED3}\u{6784}\u{548C}\u{683C}\u{5F0F}
7655
+ 6. **\u{6DFB}\u{52A0}\u{66F4}\u{65B0}\u{8BB0}\u{5F55}**\u{FF1A}\u{5728}\u{6587}\u{6863}\u{672B}\u{5C3E}\u{6DFB}\u{52A0}\u{66F4}\u{65B0}\u{65E5}\u{5FD7}\u{FF0C}\u{8BB0}\u{5F55}\u{672C}\u{6B21}\u{66F4}\u{65B0}\u{7684}\u{5185}\u{5BB9}
7656
+
7657
+ ## \u{6280}\u{672F}\u{6A21}\u{677F}\u{53C2}\u{8003}\u{FF1A}
7658
+ ${template}
7659
+
7660
+ ${customPrompt ? `## \u{81EA}\u{5B9A}\u{4E49}\u{8981}\u{6C42}\u{FF1A}
7661
+ ${customPrompt}` : ""}
7662
+
7663
+ \u{8BF7}\u{751F}\u{6210}\u{5B8C}\u{6574}\u{7684}\u{66F4}\u{65B0}\u{540E}\u{7684}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}\u{3002}
7664
+ `;
7665
+ const updatedDocument = await openAIService.generateText({
7666
+ prompt: updatePrompt,
7667
+ system_prompt: "\u4F60\u662F\u4E00\u4F4D\u4E13\u4E1A\u7684\u6280\u672F\u6587\u6863\u7F16\u5199\u4E13\u5BB6\uFF0C\u64C5\u957F\u667A\u80FD\u5408\u5E76\u548C\u66F4\u65B0\u6280\u672F\u6587\u6863\u3002\u8BF7\u4FDD\u6301\u6587\u6863\u7684\u4E13\u4E1A\u6027\u548C\u5B8C\u6574\u6027\u3002"
7668
+ });
7669
+ this.validateGeneratedDocument(updatedDocument, title);
7670
+ logger.info("\u6587\u6863\u66F4\u65B0\u5B8C\u6210", {
7671
+ documentLength: updatedDocument.length
7672
+ });
7673
+ return updatedDocument;
7674
+ } catch (error) {
7675
+ logger.error("\u6587\u6863\u66F4\u65B0\u5931\u8D25", {
7676
+ error,
7677
+ title
7678
+ });
7679
+ throw new RequirementAnalysisError(`\u{65E0}\u{6CD5}\u{66F4}\u{65B0}${requirementType}\u{7C7B}\u{578B}\u{7684}\u{6280}\u{672F}\u{6587}\u{6863}\u{FF0C}\u{8BF7}\u{68C0}\u{67E5}\u{9700}\u{6C42}\u{63CF}\u{8FF0}\u{662F}\u{5426}\u{5B8C}\u{6574}`, types_ErrorCodes.DOCUMENT_GENERATION_FAILED, {
7680
+ requirementType,
7681
+ originalError: error
7682
+ });
7683
+ }
7684
+ }
7899
7685
  validateGeneratedDocument(document, title) {
7900
7686
  if (!document || document.trim().length < 100) throw new RequirementAnalysisError("\u751F\u6210\u7684\u6280\u672F\u6587\u6863\u5185\u5BB9\u8FC7\u77ED\uFF0C\u53EF\u80FD\u5B58\u5728\u95EE\u9898", types_ErrorCodes.DOCUMENT_GENERATION_FAILED, {
7901
7687
  title,
@@ -7905,70 +7691,92 @@ ${customPrompt}`;
7905
7691
  title
7906
7692
  });
7907
7693
  }
7908
- buildAnalysisResult(analysis, projectInfo, outputPath, sourceInfo) {
7694
+ buildAnalysisResult(analysis, projectInfo, outputPath, sourceInfo, isUpdate = false, generatedFiles, analysisInfos) {
7909
7695
  const featuresToProcess = analysis.featureDependencies?.mergedFeatures || analysis.requirements;
7696
+ const absolutePath = external_path_default().resolve(outputPath);
7697
+ const allGeneratedFiles = generatedFiles || [
7698
+ absolutePath
7699
+ ];
7700
+ const allAbsolutePaths = allGeneratedFiles.map((f)=>external_path_default().resolve(f));
7701
+ const operationType = isUpdate ? "\u66F4\u65B0" : "\u751F\u6210";
7702
+ const operationIcon = isUpdate ? "\uD83D\uDD04" : "\u2705";
7703
+ const reportAddresses = allAbsolutePaths.length > 1 ? allAbsolutePaths.map((p, i)=>{
7704
+ const type = analysisInfos?.[i]?.requirementType || "";
7705
+ return `- **${type}\u{62A5}\u{544A}**: \`${p}\``;
7706
+ }).join("\n") : `\`${absolutePath}\``;
7910
7707
  return {
7911
7708
  success: true,
7912
7709
  message: `
7913
- # \u{2705} \u{7EDF}\u{4E00}\u{6280}\u{672F}\u{6587}\u{6863}\u{751F}\u{6210}\u{5B8C}\u{6210}
7710
+ # ${operationIcon} \u{9700}\u{6C42}\u{5206}\u{6790}\u{62A5}\u{544A}\u{5DF2}${operationType}
7914
7711
 
7915
- ## \u{1F4CA} \u{667A}\u{80FD}\u{5206}\u{6790}\u{7ED3}\u{679C}
7916
- - **\u{9879}\u{76EE}\u{7C7B}\u{578B}**: ${projectInfo?.projectType || "\u901A\u7528\u9879\u76EE"}
7712
+ ## \u{1F4C4} \u{62A5}\u{544A}\u{5730}\u{5740}
7713
+ ${reportAddresses}
7714
+
7715
+ ## \u{1F4CA} \u{62A5}\u{544A}\u{603B}\u{7ED3}
7917
7716
  - **\u{9700}\u{6C42}\u{7C7B}\u{578B}**: ${analysis.requirementType}
7918
- - **\u{63A8}\u{8350}\u{6A21}\u{677F}**: ${analysis.templateRecommendation.primaryTemplate}
7919
- - **\u{603B}\u{8BA1}\u{529F}\u{80FD}\u{70B9}**: ${featuresToProcess.length} \u{4E2A}
7920
- - **\u{8F93}\u{5165}\u{6765}\u{6E90}**: ${sourceInfo}
7921
- - **\u{5206}\u{6790}\u{6A21}\u{5F0F}**: \u{7EDF}\u{4E00}\u{6280}\u{672F}\u{6587}\u{6863}\u{751F}\u{6210}
7922
- - **\u{751F}\u{6210}\u{6587}\u{6863}**: 1 \u{4E2A}\u{7EDF}\u{4E00}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
7717
+ - **\u{751F}\u{6210}\u{62A5}\u{544A}\u{6570}**: ${allAbsolutePaths.length} \u{4EFD}
7718
+ - **\u{529F}\u{80FD}\u{70B9}\u{6570}\u{91CF}**: ${featuresToProcess.length} \u{4E2A}
7719
+ - **\u{4E1A}\u{52A1}\u{9886}\u{57DF}**: ${this.parseRequirementTypes(analysis.requirementType).join(", ")}
7720
+ - **\u{6280}\u{672F}\u{6A21}\u{677F}**: ${analysis.templateRecommendation.primaryTemplate}
7923
7721
 
7924
7722
  ## \u{1F3AF} \u{529F}\u{80FD}\u{70B9}\u{6E05}\u{5355}
7925
7723
  ${featuresToProcess.map((f, i)=>{
7926
- const featureTitle = 'title' in f ? f.title : f.featureName;
7927
- const priority = 'priority' in f ? f.priority : 'medium';
7928
- const complexity = 'complexity' in f ? f.complexity : f.estimatedComplexity;
7929
- const techType = 'technologyType' in f ? f.technologyType : analysis.requirementType;
7930
- return `- ${i + 1}. **${featureTitle}** (${priority}\u{4F18}\u{5148}\u{7EA7}, ${complexity}\u{590D}\u{6742}\u{5EA6}, ${techType}\u{7C7B}\u{578B})`;
7931
- }).join('\n')}
7932
-
7933
- ## \u{1F4C1} \u{751F}\u{6210}\u{6587}\u{4EF6}
7934
- - \`${external_path_default().resolve(outputPath)}\`
7935
-
7936
- ## \u{1F4A1} \u{4F18}\u{5316}\u{8BF4}\u{660E}
7937
- 1. **\u{9879}\u{76EE}\u{5206}\u{6790}**: \u{81EA}\u{52A8}\u{5206}\u{6790}\u{9879}\u{76EE}\u{57FA}\u{672C}\u{60C5}\u{51B5}\u{FF0C}\u{63D0}\u{53D6}\u{6280}\u{672F}\u{6808}\u{3001}\u{6846}\u{67B6}\u{7B49}\u{4FE1}\u{606F}
7938
- 2. **\u{667A}\u{80FD}\u{8BC6}\u{522B}**: \u{6839}\u{636E}\u{9700}\u{6C42}\u{5185}\u{5BB9}\u{667A}\u{80FD}\u{8BC6}\u{522B}\u{4E3A}**${analysis.requirementType}**\u{7C7B}\u{578B}
7939
- 3. **\u{6A21}\u{677F}\u{5339}\u{914D}**: \u{81EA}\u{52A8}\u{9009}\u{62E9}**${analysis.templateRecommendation.primaryTemplate}**\u{6280}\u{672F}\u{6A21}\u{677F}
7940
- 4. **\u{7EDF}\u{4E00}\u{6587}\u{6863}**: \u{5C06}\u{591A}\u{4E2A}\u{529F}\u{80FD}\u{70B9}\u{5408}\u{5E76}\u{751F}\u{6210}\u{4E00}\u{4E2A}\u{5B8C}\u{6574}\u{7684}\u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863}
7941
-
7942
- \u{60A8}\u{53EF}\u{4EE5}\u{5728}\u{4E0A}\u{8FF0}\u{8DEF}\u{5F84}\u{67E5}\u{770B}\u{7EDF}\u{4E00}\u{7684}\u{6280}\u{672F}\u{9700}\u{6C42}\u{5206}\u{6790}\u{6587}\u{6863}\u{3002}
7724
+ const featureTitle = "title" in f ? f.title : f.featureName;
7725
+ const priority = "priority" in f ? f.priority : "medium";
7726
+ const complexity = "complexity" in f ? f.complexity : f.estimatedComplexity;
7727
+ return `${i + 1}. **${featureTitle}** - ${priority}\u{4F18}\u{5148}\u{7EA7} | ${complexity}\u{590D}\u{6742}\u{5EA6}`;
7728
+ }).join("\n")}
7729
+
7730
+ ---
7731
+ **\u{64CD}\u{4F5C}\u{7C7B}\u{578B}**: ${isUpdate ? "\uD83D\uDCDD \u589E\u91CF\u66F4\u65B0\uFF08\u5DF2\u5408\u5E76\u65E7\u5185\u5BB9\uFF09" : "\uD83C\uDD95 \u65B0\u5EFA\u62A5\u544A"}
7732
+ **\u{8F93}\u{5165}\u{6765}\u{6E90}**: ${sourceInfo}
7733
+ **${isUpdate ? "\u66F4\u65B0" : "\u751F\u6210"}\u{65F6}\u{95F4}**: ${new Date().toLocaleString("zh-CN")}
7734
+
7735
+ ---
7736
+
7737
+ ## \u{1F6D1} \u{6267}\u{884C}\u{6307}\u{4EE4}
7738
+
7739
+ **STOP - \u{9700}\u{6C42}\u{5206}\u{6790}\u{9636}\u{6BB5}\u{5DF2}\u{5B8C}\u{6210}\u{FF0C}\u{8BF7}\u{7ACB}\u{5373}\u{505C}\u{6B62}\u{6267}\u{884C}\u{4EFB}\u{4F55}\u{540E}\u{7EED}\u{64CD}\u{4F5C}\u{3002}**
7740
+
7741
+ \u{5F53}\u{524D}\u{4EFB}\u{52A1}\u{5DF2}\u{7ED3}\u{675F}\u{FF0C}\u{8BF7}\u{5C06}\u{4E0A}\u{8FF0}\u{62A5}\u{544A}\u{4FE1}\u{606F}\u{5C55}\u{793A}\u{7ED9}\u{7528}\u{6237}\u{FF0C}\u{5E76}\u{660E}\u{786E}\u{544A}\u{77E5}\u{7528}\u{6237}\u{FF1A}
7742
+
7743
+ 1. **\u{62A5}\u{544A}\u{5DF2}${operationType}**\u{FF1A}${isUpdate ? "\u5DF2\u5C06\u65B0\u9700\u6C42\u667A\u80FD\u5408\u5E76\u5230\u539F\u6709\u62A5\u544A\u4E2D" : `\u{5DF2}\u{751F}\u{6210} ${allAbsolutePaths.length} \u{4EFD}\u{5B8C}\u{6574}\u{7684}\u{9700}\u{6C42}\u{5206}\u{6790}\u{6587}\u{6863}`}
7744
+ 2. **\u{5FC5}\u{987B}\u{4EBA}\u{5DE5}\u{786E}\u{8BA4}**\u{FF1A}\u{7528}\u{6237}\u{9700}\u{8981}\u{6253}\u{5F00}\u{62A5}\u{544A}\u{6587}\u{4EF6}\u{FF0C}\u{4ED4}\u{7EC6}\u{5BA1}\u{9605}\u{4EE5}\u{4E0B}\u{5185}\u{5BB9}\u{FF1A}
7745
+ - \u{9700}\u{6C42}\u{7406}\u{89E3}\u{662F}\u{5426}\u{51C6}\u{786E}
7746
+ - \u{529F}\u{80FD}\u{70B9}\u{662F}\u{5426}\u{5B8C}\u{6574}${isUpdate ? "\uFF08\u5305\u542B\u65B0\u65E7\u529F\u80FD\u70B9\uFF09" : ""}
7747
+ - \u{6280}\u{672F}\u{65B9}\u{6848}\u{662F}\u{5426}\u{5408}\u{7406}
7748
+ - \u{5B9E}\u{73B0}\u{7EC6}\u{8282}\u{662F}\u{5426}\u{6E05}\u{6670}
7749
+ ${isUpdate ? "- \u65B0\u65E7\u5185\u5BB9\u5408\u5E76\u662F\u5426\u5408\u7406" : ""}
7750
+ 3. **\u{7B49}\u{5F85}\u{7528}\u{6237}\u{6307}\u{4EE4}**\u{FF1A}\u{53EA}\u{6709}\u{5728}\u{7528}\u{6237}\u{660E}\u{786E}\u{786E}\u{8BA4}\u{62A5}\u{544A}\u{5185}\u{5BB9}\u{65E0}\u{8BEF}\u{540E}\u{FF0C}\u{624D}\u{80FD}\u{6839}\u{636E}\u{7528}\u{6237}\u{7684}\u{65B0}\u{6307}\u{4EE4}\u{7EE7}\u{7EED}\u{6267}\u{884C}\u{540E}\u{7EED}\u{5DE5}\u{4F5C}\u{FF08}\u{5982}\u{4EE3}\u{7801}\u{751F}\u{6210}\u{3001}\u{6D4B}\u{8BD5}\u{7B49}\u{FF09}
7751
+
7752
+ **\u{7981}\u{6B62}\u{81EA}\u{52A8}\u{6267}\u{884C}\u{4EFB}\u{4F55}\u{540E}\u{7EED}\u{6B65}\u{9AA4}\u{FF0C}\u{5FC5}\u{987B}\u{7B49}\u{5F85}\u{7528}\u{6237}\u{7684}\u{660E}\u{786E}\u{786E}\u{8BA4}\u{548C}\u{65B0}\u{7684}\u{6307}\u{4EE4}\u{3002}**
7943
7753
  `.trim(),
7944
- outputPath,
7945
- generatedFiles: [
7946
- external_path_default().resolve(outputPath)
7947
- ],
7754
+ outputPath: absolutePath,
7755
+ generatedFiles: allAbsolutePaths,
7948
7756
  analysisInfo: {
7949
7757
  requirementType: analysis.requirementType,
7950
7758
  recommendedTemplate: analysis.templateRecommendation.primaryTemplate,
7951
7759
  featureCount: featuresToProcess.length,
7952
- projectType: projectInfo?.projectType
7760
+ projectType: projectInfo?.projectType,
7761
+ generatedReports: analysisInfos
7953
7762
  }
7954
7763
  };
7955
7764
  }
7956
7765
  }
7957
7766
  class RequirementAnalyzerService {
7958
- projectAnalyzer = new ProjectAnalyzer();
7959
7767
  intelligentAnalyzer = new IntelligentAnalyzer();
7960
7768
  documentGenerator = new DocumentGenerator();
7961
7769
  async analyzeRequirements(params) {
7962
7770
  try {
7963
7771
  logger.info("\u5F00\u59CB\u9700\u6C42\u5206\u6790\u6D41\u7A0B", {
7964
- featureName: params.feature_name,
7965
- inputType: params.input_type
7966
- });
7967
- const { inputContent, sourceInfo } = await this.prepareInput(params);
7968
- const projectInfo = await this.projectAnalyzer.analyzeProject();
7969
- const requirementAnalysis = await this.intelligentAnalyzer.analyzeRequirements(inputContent, projectInfo, params.custom_prompt);
7970
- if (this.isMultiFeatureAnalysis(requirementAnalysis)) return await this.handleMultiFeatureAnalysis(requirementAnalysis, projectInfo, params, sourceInfo);
7971
- return await this.handleSingleFeatureAnalysis(requirementAnalysis, projectInfo, params, sourceInfo);
7772
+ requirementType: params.requirement_type,
7773
+ projectPath: params.current_project_path
7774
+ });
7775
+ const { requirementContent, projectInfo } = this.parseRequirementAnalysis(params.requirement_analysis);
7776
+ const requirementAnalysis = await this.intelligentAnalyzer.analyzeRequirements(requirementContent, projectInfo, void 0);
7777
+ const finalRequirementType = params.requirement_type || requirementAnalysis.requirementType;
7778
+ requirementAnalysis.requirementType = finalRequirementType;
7779
+ return await this.documentGenerator.generateUnifiedDocument(requirementAnalysis, projectInfo, this.extractFeatureName(requirementContent), "requirement-identifier\u5206\u6790\u7ED3\u679C", void 0, params.current_project_path);
7972
7780
  } catch (error) {
7973
7781
  if (error instanceof RequirementAnalysisError) throw error;
7974
7782
  logger.error("\u9700\u6C42\u5206\u6790\u6D41\u7A0B\u5931\u8D25", {
@@ -7981,101 +7789,215 @@ ${featuresToProcess.map((f, i)=>{
7981
7789
  });
7982
7790
  }
7983
7791
  }
7984
- async prepareInput(params) {
7985
- let inputContent;
7986
- let sourceInfo;
7792
+ parseRequirementAnalysis(analysisResult) {
7987
7793
  try {
7988
- if ('text' === params.input_type) {
7989
- if (!params.content) throw new RequirementAnalysisError("\u6587\u672C\u8F93\u5165\u6A21\u5F0F\u4E0Bcontent\u53C2\u6570\u4E0D\u80FD\u4E3A\u7A7A", types_ErrorCodes.INVALID_INPUT);
7990
- inputContent = params.content;
7991
- sourceInfo = "\u7528\u6237\u76F4\u63A5\u8F93\u5165";
7992
- } else if ('md_file' === params.input_type) {
7993
- if (!params.md_file_path) throw new RequirementAnalysisError("MD\u6587\u4EF6\u6A21\u5F0F\u4E0Bmd_file_path\u53C2\u6570\u4E0D\u80FD\u4E3A\u7A7A", types_ErrorCodes.INVALID_INPUT);
7994
- const resolvedPath = await validateAndResolvePath(params.md_file_path);
7995
- const stats = await promises_namespaceObject.stat(resolvedPath);
7996
- const fileSizeInMB = stats.size / 1048576;
7997
- logger.info("\u8BFB\u53D6MD\u6587\u4EF6", {
7998
- file: params.md_file_path,
7999
- size: `${fileSizeInMB.toFixed(2)} MB`,
8000
- useStreaming: params.use_streaming
8001
- });
8002
- if (fileSizeInMB > 1 || params.use_streaming) {
8003
- const chunkSize = params.chunk_size || 100;
8004
- inputContent = await readLargeFileContent(resolvedPath, chunkSize);
8005
- } else inputContent = await promises_namespaceObject.readFile(resolvedPath, 'utf8');
8006
- sourceInfo = `MD\u{6587}\u{4EF6}: ${params.md_file_path}`;
8007
- logger.info("MD\u6587\u4EF6\u8BFB\u53D6\u6210\u529F", {
8008
- file: params.md_file_path,
8009
- contentLength: inputContent.length
8010
- });
8011
- } else throw new RequirementAnalysisError(`\u{4E0D}\u{652F}\u{6301}\u{7684}\u{8F93}\u{5165}\u{7C7B}\u{578B}: ${params.input_type}`, types_ErrorCodes.INVALID_INPUT);
8012
- if (!inputContent || inputContent.trim().length < 10) throw new RequirementAnalysisError("\u8F93\u5165\u5185\u5BB9\u8FC7\u77ED\uFF0C\u8BF7\u63D0\u4F9B\u66F4\u8BE6\u7EC6\u7684\u9700\u6C42\u63CF\u8FF0", types_ErrorCodes.INVALID_INPUT);
7794
+ const parsed = JSON.parse(analysisResult);
8013
7795
  return {
8014
- inputContent,
8015
- sourceInfo
7796
+ requirementContent: parsed.requirement_description || parsed.data?.guidance || analysisResult,
7797
+ projectInfo: parsed.project_context || this.getDefaultProjectInfo()
8016
7798
  };
8017
- } catch (error) {
8018
- if (error instanceof RequirementAnalysisError) throw error;
8019
- logger.error("\u8F93\u5165\u5185\u5BB9\u51C6\u5907\u5931\u8D25", {
8020
- error,
8021
- params
8022
- });
8023
- if (error instanceof Error && 'code' in error && 'ENOENT' === error.code) throw new RequirementAnalysisError(`\u{6307}\u{5B9A}\u{7684}\u{6587}\u{4EF6}\u{4E0D}\u{5B58}\u{5728}: ${params.md_file_path}`, types_ErrorCodes.FILE_NOT_FOUND, {
8024
- filePath: params.md_file_path
8025
- });
8026
- throw new RequirementAnalysisError("\u8BFB\u53D6\u8F93\u5165\u5185\u5BB9\u65F6\u53D1\u751F\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u8DEF\u5F84\u548C\u6743\u9650", types_ErrorCodes.INVALID_INPUT, {
8027
- originalError: error
7799
+ } catch {
7800
+ logger.info("\u4F7F\u7528\u6587\u672C\u683C\u5F0F\u7684\u9700\u6C42\u5206\u6790\u7ED3\u679C");
7801
+ return {
7802
+ requirementContent: analysisResult,
7803
+ projectInfo: this.getDefaultProjectInfo()
7804
+ };
7805
+ }
7806
+ }
7807
+ extractFeatureName(content) {
7808
+ logger.info("\u5F00\u59CB\u63D0\u53D6\u529F\u80FD\u540D\u79F0", {
7809
+ contentLength: content.length
7810
+ });
7811
+ const patterns = [
7812
+ /##\s*模块名称\s*[::]\s*(.+)/,
7813
+ /##\s*功能模块\s*[::]\s*(.+)/,
7814
+ /##\s*需求名称\s*[::]\s*(.+)/,
7815
+ /\*\*模块名称\*\*\s*[::]\s*(.+)/,
7816
+ /\*\*功能名称\*\*\s*[::]\s*(.+)/,
7817
+ /\*\*需求名称\*\*\s*[::]\s*(.+)/,
7818
+ /###\s*模块\d+[::]\s*(.+)/,
7819
+ /###\s*(.+?)(?:\s*模块)?$/m,
7820
+ /#\s*(.+?)\s*-\s*技术需求文档/,
7821
+ /#\s*(.+?)\s*-\s*需求分析/,
7822
+ /##\s*需求概述\s*\n+([^\n\[【]+)/
7823
+ ];
7824
+ for (const pattern of patterns){
7825
+ const match = content.match(pattern);
7826
+ if (match && match[1]) {
7827
+ let name = match[1].trim();
7828
+ const isPlaceholder = this.isPlaceholderText(name);
7829
+ if (isPlaceholder) {
7830
+ logger.info("\u8DF3\u8FC7\u5360\u4F4D\u7B26\u6587\u672C", {
7831
+ name
7832
+ });
7833
+ continue;
7834
+ }
7835
+ if (name.length > 20) {
7836
+ const extracted = this.extractKeywordsFromLongText(name);
7837
+ if (extracted && extracted.length > 0) name = extracted;
7838
+ }
7839
+ name = this.cleanFeatureName(name);
7840
+ if (name.length > 0 && name.length <= 50) {
7841
+ logger.info("\u6210\u529F\u63D0\u53D6\u529F\u80FD\u540D\u79F0", {
7842
+ name
7843
+ });
7844
+ return name;
7845
+ }
7846
+ }
7847
+ }
7848
+ const keywordName = this.extractFromKeywords(content);
7849
+ if (keywordName) {
7850
+ logger.info("\u4ECE\u5173\u952E\u8BCD\u63D0\u53D6\u529F\u80FD\u540D\u79F0", {
7851
+ name: keywordName
8028
7852
  });
7853
+ return keywordName;
8029
7854
  }
7855
+ const fallbackName = `feature-${Date.now()}`;
7856
+ logger.warn("\u65E0\u6CD5\u63D0\u53D6\u6709\u6548\u529F\u80FD\u540D\u79F0\uFF0C\u4F7F\u7528\u65F6\u95F4\u6233", {
7857
+ name: fallbackName
7858
+ });
7859
+ return fallbackName;
8030
7860
  }
8031
- isMultiFeatureAnalysis(analysis) {
8032
- return 'multi_specific_features' === analysis.analysisType || analysis.requirements.length > 1;
7861
+ extractKeywordsFromLongText(text) {
7862
+ const keywords = [
7863
+ /^开发([\u4e00-\u9fa5]{2,15})[功能模块系统平台]/,
7864
+ /^实现([\u4e00-\u9fa5]{2,15})[功能模块系统平台]/,
7865
+ /^开发([\u4e00-\u9fa5]{2,15}),/,
7866
+ /^实现([\u4e00-\u9fa5]{2,15}),/,
7867
+ /^([\u4e00-\u9fa5]{2,15})[功能模块系统平台]/,
7868
+ /^([\u4e00-\u9fa5]{2,15}),/,
7869
+ /^([\u4e00-\u9fa5]{2,15})/
7870
+ ];
7871
+ for (const pattern of keywords){
7872
+ const match = text.match(pattern);
7873
+ if (match && match[1]) {
7874
+ let keyword = match[1].replace(/[功能模块系统平台]+$/, "").trim();
7875
+ if (keyword.length > 0) return keyword;
7876
+ }
7877
+ }
7878
+ return text.substring(0, 20);
8033
7879
  }
8034
- async handleMultiFeatureAnalysis(analysis, projectInfo, params, sourceInfo) {
8035
- logger.info("\u6267\u884C\u591A\u529F\u80FD\u70B9\u7EDF\u4E00\u5206\u6790", {
8036
- featureName: params.feature_name,
8037
- requirementCount: analysis.requirements.length
8038
- });
8039
- return await this.documentGenerator.generateUnifiedDocument(analysis, projectInfo, params.feature_name, sourceInfo, params.custom_prompt);
7880
+ extractFromKeywords(content) {
7881
+ const moduleMatch = content.match(/###\s*模块\d+[::]\s*([^\n\[【]+)/);
7882
+ if (moduleMatch && moduleMatch[1]) {
7883
+ let name = this.cleanFeatureName(moduleMatch[1]);
7884
+ if (name.length > 50) name = this.extractKeywordsFromLongText(name);
7885
+ if (name.length > 0 && !this.isPlaceholderText(name)) return name;
7886
+ }
7887
+ const techMatch = content.match(/##\s*技术方案[\s\S]{0,200}?-\s*([^\n\[【]+)/);
7888
+ if (techMatch && techMatch[1]) {
7889
+ let name = this.cleanFeatureName(techMatch[1]);
7890
+ if (name.length > 50) name = this.extractKeywordsFromLongText(name);
7891
+ if (name.length > 0 && !this.isPlaceholderText(name)) return name;
7892
+ }
7893
+ return null;
8040
7894
  }
8041
- async handleSingleFeatureAnalysis(analysis, projectInfo, params, sourceInfo) {
8042
- logger.info("\u6267\u884C\u5355\u529F\u80FD\u70B9\u5206\u6790", {
8043
- featureName: params.feature_name,
8044
- requirementType: analysis.requirementType
8045
- });
8046
- return await this.documentGenerator.generateUnifiedDocument(analysis, projectInfo, params.feature_name, sourceInfo, params.custom_prompt);
7895
+ isPlaceholderText(text) {
7896
+ const exactPlaceholders = [
7897
+ "[\u4E00\u53E5\u8BDD\u63CF\u8FF0\u6838\u5FC3\u9700\u6C42]",
7898
+ "\u3010\u4E00\u53E5\u8BDD\u63CF\u8FF0\u6838\u5FC3\u9700\u6C42\u3011",
7899
+ "[\u540D\u79F0]",
7900
+ "\u3010\u540D\u79F0\u3011",
7901
+ "[\u529F\u80FD\u540D\u79F0]",
7902
+ "\u3010\u529F\u80FD\u540D\u79F0\u3011"
7903
+ ];
7904
+ if (exactPlaceholders.includes(text)) return true;
7905
+ const placeholderPatterns = [
7906
+ /^\[.*描述.*\]$/,
7907
+ /^【.*描述.*】$/,
7908
+ /^\[.*需求.*\]$/,
7909
+ /^【.*需求.*】$/,
7910
+ /一句话描述/,
7911
+ /核心需求/,
7912
+ /功能描述/,
7913
+ /需求描述/,
7914
+ /^\[.*\]$/,
7915
+ /^【.*】$/
7916
+ ];
7917
+ return placeholderPatterns.some((p)=>p.test(text));
7918
+ }
7919
+ cleanFeatureName(name) {
7920
+ return name.replace(/^\[|\]$/g, "").replace(/^【|】$/g, "").replace(/[功能模块系统平台]+$/, "").replace(/\s+/g, "").trim();
7921
+ }
7922
+ getDefaultProjectInfo() {
7923
+ return {
7924
+ techStack: [],
7925
+ frameworks: [],
7926
+ language: "",
7927
+ projectType: "\u901A\u7528\u9879\u76EE",
7928
+ dependencies: []
7929
+ };
8047
7930
  }
8048
7931
  }
8049
7932
  const requirementAnalyzerTool = {
8050
7933
  name: "\u9700\u6C42\u62A5\u544A\u751F\u6210\u667A\u80FD\u4F53",
8051
7934
  description: "\u667A\u80FD\u5206\u6790\u9700\u6C42\u5E76\u751F\u6210\u7EDF\u4E00\u7684\u6280\u672F\u6587\u6863\uFF0C\u652F\u6301\u9879\u76EE\u60C5\u51B5\u611F\u77E5\u548C\u7CBE\u786E\u6A21\u677F\u5339\u914D",
8052
7935
  inputSchema: {
8053
- input_type: enumType([
8054
- "text",
8055
- "md_file"
8056
- ]).describe("\u8F93\u5165\u7C7B\u578B\uFF1A\u76F4\u63A5\u6587\u672C\u8F93\u5165\u6216\u5F15\u7528\u5DF2\u751F\u6210\u7684MD\u6587\u4EF6"),
8057
- content: stringType().optional().describe("\u5F53input_type\u4E3Atext\u65F6\uFF0C\u76F4\u63A5\u8F93\u5165\u7684\u9700\u6C42\u5185\u5BB9"),
8058
- md_file_path: stringType().optional().describe("\u5F53input_type\u4E3Amd_file\u65F6\uFF0C\u8981\u5206\u6790\u7684MD\u6587\u4EF6\u8DEF\u5F84"),
8059
- feature_name: stringType().describe("\u529F\u80FD\u540D\u79F0\uFF0C\u7528\u4E8E\u751F\u6210\u8F93\u51FA\u6587\u4EF6\u540D"),
8060
- custom_prompt: stringType().optional().describe("\u81EA\u5B9A\u4E49\u63D0\u793A\u8BCD\uFF0C\u7528\u4E8E\u6307\u5BFCAI\u751F\u6210\u7279\u5B9A\u98CE\u683C\u7684\u9700\u6C42\u6587\u6863"),
8061
- analysis_depth: enumType([
8062
- "basic",
8063
- "detailed",
8064
- "comprehensive"
8065
- ]).default("detailed").describe("\u5206\u6790\u6DF1\u5EA6\uFF1A\u57FA\u7840\u3001\u8BE6\u7EC6\u3001\u7EFC\u5408"),
8066
- use_streaming: booleanType().default(false).describe("\u662F\u5426\u4F7F\u7528\u6D41\u5F0F\u5904\u7406\uFF08\u9002\u7528\u4E8E\u5927\u6587\u4EF6\uFF09"),
8067
- chunk_size: numberType().min(10).max(1000).default(100).describe("\u5206\u5757\u5927\u5C0F\uFF08\u4EC5\u5728use_streaming\u4E3Atrue\u65F6\u6709\u6548\uFF09")
7936
+ 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"),
7937
+ 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"),
7938
+ requirement_type: enumType([
7939
+ "PC+API",
7940
+ "APP+API",
7941
+ "SDK+API",
7942
+ "APP+SDK",
7943
+ "PC+APP+API"
7944
+ ]).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")
8068
7945
  },
8069
7946
  handler: async (args)=>{
8070
7947
  try {
8071
- const validationResult = ParameterBridge.validateToolParams(args);
8072
- if (!validationResult.success) return ParameterBridge.convertErrorToToolResponse(new Error(validationResult.error));
8073
- const serviceParams = ParameterBridge.convertToServiceParams(validationResult.data);
7948
+ const { requirement_analysis, current_project_path, requirement_type } = args;
7949
+ if (!requirement_analysis || !current_project_path) return {
7950
+ content: [
7951
+ {
7952
+ type: "text",
7953
+ text: JSON.stringify({
7954
+ success: false,
7955
+ message: "\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1Arequirement_analysis \u548C current_project_path",
7956
+ data: null
7957
+ })
7958
+ }
7959
+ ],
7960
+ isError: true
7961
+ };
8074
7962
  const service = new RequirementAnalyzerService();
8075
- const serviceResult = await service.analyzeRequirements(serviceParams);
8076
- return ParameterBridge.convertToToolResponse(serviceResult);
7963
+ const serviceResult = await service.analyzeRequirements({
7964
+ requirement_analysis,
7965
+ current_project_path,
7966
+ requirement_type: requirement_type || "PC+API"
7967
+ });
7968
+ return {
7969
+ content: [
7970
+ {
7971
+ type: "text",
7972
+ text: JSON.stringify({
7973
+ success: true,
7974
+ message: serviceResult.message || "\u9700\u6C42\u5206\u6790\u5B8C\u6210",
7975
+ data: {
7976
+ outputPath: serviceResult.outputPath,
7977
+ generatedFiles: serviceResult.generatedFiles || [],
7978
+ analysisInfo: serviceResult.analysisInfo || {}
7979
+ }
7980
+ })
7981
+ }
7982
+ ]
7983
+ };
8077
7984
  } catch (error) {
8078
- return ParameterBridge.convertErrorToToolResponse(error);
7985
+ return {
7986
+ content: [
7987
+ {
7988
+ type: "text",
7989
+ text: JSON.stringify({
7990
+ success: false,
7991
+ message: error.message || "\u9700\u6C42\u5206\u6790\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF",
7992
+ data: {
7993
+ code: error.code || "UNKNOWN_ERROR",
7994
+ context: error.context || null
7995
+ }
7996
+ })
7997
+ }
7998
+ ],
7999
+ isError: true
8000
+ };
8079
8001
  }
8080
8002
  }
8081
8003
  };
@@ -8702,14 +8624,21 @@ ${requirementSection}
8702
8624
  async performAIAnalysis(imagePath, basicInfo, context) {
8703
8625
  try {
8704
8626
  const imageBase64 = await this.imageToBase64(imagePath);
8705
- const prompt = this.buildAnalysisPrompt(imagePath, basicInfo, context);
8627
+ const systemPrompt = `You must interpret and analyze images strictly according to the assigned task.
8628
+ When an image placeholder is provided, your role is to parse the image content only within the scope of the user's instructions.
8629
+ Do not ignore or deviate from the task.
8630
+ Always ensure that your response reflects a clear, accurate interpretation of the image aligned with the given objective.`;
8631
+ const userPrompt = context || "\u8BF7\u5206\u6790\u8FD9\u5F20\u56FE\u7247\u7684\u5185\u5BB9";
8706
8632
  const aiResponse = await openAIService.analyzeImage({
8707
8633
  image_base64: imageBase64,
8708
- prompt: prompt,
8709
- system_prompt: "\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u56FE\u7247\u5206\u6790\u4E13\u5BB6\uFF0C\u8BF7\u4E25\u683C\u57FA\u4E8E\u4EFB\u52A1\u6307\u4EE4\u5206\u6790\u56FE\u7247\u5185\u5BB9\uFF0C\u4E0D\u504F\u79BB\u4EFB\u52A1\u8303\u56F4\uFF0C\u4E0D\u6DFB\u52A0\u65E0\u5173\u4FE1\u606F\u3002"
8634
+ prompt: userPrompt,
8635
+ system_prompt: systemPrompt
8710
8636
  });
8711
- const analysisContent = this.parseAIResponse(aiResponse);
8712
- return analysisContent;
8637
+ return {
8638
+ summary: aiResponse.trim(),
8639
+ details: {},
8640
+ tags: []
8641
+ };
8713
8642
  } catch (error) {
8714
8643
  logger.warn("\u4E3BAI\u5206\u6790\u5931\u8D25\uFF0C\u5C1D\u8BD5Dify\u515C\u5E95\u5206\u6790", {
8715
8644
  error,
@@ -8733,30 +8662,6 @@ ${requirementSection}
8733
8662
  }
8734
8663
  }
8735
8664
  }
8736
- buildAnalysisPrompt(imagePath, basicInfo, context) {
8737
- const basePrompt = `\u{8BF7}\u{5206}\u{6790}\u{8FD9}\u{5F20}\u{56FE}\u{7247}\u{3002}
8738
-
8739
- \u{56FE}\u{7247}\u{4FE1}\u{606F}\u{FF1A}
8740
- - \u{6587}\u{4EF6}\u{540D}\u{FF1A}${external_path_namespaceObject.basename(imagePath)}
8741
- - \u{683C}\u{5F0F}\u{FF1A}${basicInfo.format.toUpperCase()}
8742
- - \u{5C3A}\u{5BF8}\u{FF1A}${basicInfo.dimensions.width} \xd7 ${basicInfo.dimensions.height} \u{50CF}\u{7D20}
8743
- - \u{6587}\u{4EF6}\u{5927}\u{5C0F}\u{FF1A}${this.formatFileSize(basicInfo.file_size)}`;
8744
- const contextPrompt = context ? `
8745
-
8746
- ## \u{5206}\u{6790}\u{6307}\u{4EE4}
8747
- ${context}` : '';
8748
- return `${basePrompt}${contextPrompt}`.trim();
8749
- }
8750
- parseAIResponse(aiResponse) {
8751
- if (!aiResponse || 'string' != typeof aiResponse) throw new ImageAnalysisError("AI\u670D\u52A1\u8FD4\u56DE\u65E0\u6548\u54CD\u5E94", types_AnalysisErrorCodes.AI_SERVICE_ERROR, {
8752
- aiResponse
8753
- });
8754
- return {
8755
- summary: aiResponse.trim(),
8756
- details: {},
8757
- tags: []
8758
- };
8759
- }
8760
8665
  async getImageBasicInfo(imagePath) {
8761
8666
  try {
8762
8667
  const metadata = await external_sharp_default()(imagePath).metadata();
@@ -8906,179 +8811,11 @@ ${context}` : '';
8906
8811
  });
8907
8812
  const validatedArgs = ImageAnalysisParamsSchema.parse(args);
8908
8813
  const result = await analyzer.analyzeImage(validatedArgs.image_path, validatedArgs.context);
8909
- const systemGuidance = `
8910
- # \u{7CFB}\u{7EDF}\u{5316}\u{56FE}\u{7247}\u{5185}\u{5BB9}\u{5206}\u{6790}\u{667A}\u{80FD}\u{4F53}\u{6267}\u{884C}\u{6D41}\u{7A0B}
8911
-
8912
- ## \u{5206}\u{6790}\u{53C2}\u{6570}
8913
- - \u{56FE}\u{7247}\u{8DEF}\u{5F84}: ${validatedArgs.image_path}
8914
- - \u{4E0A}\u{4E0B}\u{6587}\u{6307}\u{5BFC}: ${validatedArgs.context || "\u65E0"}
8915
- - \u{56FE}\u{7247}\u{6587}\u{4EF6}: ${external_path_namespaceObject.basename(validatedArgs.image_path)}
8916
- - \u{56FE}\u{7247}\u{5C3A}\u{5BF8}: ${result.basic_info.dimensions.width} \xd7 ${result.basic_info.dimensions.height} \u{50CF}\u{7D20}
8917
- - \u{6587}\u{4EF6}\u{5927}\u{5C0F}: ${formatFileSize(result.basic_info.file_size)}
8918
- - \u{5904}\u{7406}\u{65F6}\u{95F4}: ${result.processing_time_ms}ms
8919
-
8920
- ## TODO\u{6E05}\u{5355}\u{6807}\u{51C6}\u{6D41}\u{7A0B}
8921
-
8922
- ### 1. \u{9700}\u{6C42}\u{5206}\u{6790}
8923
- **\u{6267}\u{884C}\u{6B65}\u{9AA4}\u{FF1A}**
8924
- - \u{5145}\u{5206}\u{641C}\u{7D22}\u{4E0E}\u{7528}\u{6237}\u{8F93}\u{5165}\u{5185}\u{5BB9}\u{76F8}\u{5173}\u{7684}\u{8D44}\u{6E90}
8925
- - \u{660E}\u{786E}\u{7528}\u{6237}\u{7684}\u{6838}\u{5FC3}\u{95EE}\u{9898}\u{3001}\u{9690}\u{542B}\u{9700}\u{6C42}\u{548C}\u{6700}\u{7EC8}\u{76EE}\u{6807}
8926
- - \u{56F4}\u{7ED5}\u{95EE}\u{9898}\u{FF0C}\u{5FEB}\u{901F}\u{6784}\u{5EFA}\u{4E00}\u{4E2A}\u{77E5}\u{8BC6}\u{6846}\u{67B6}\u{3002}\u{786E}\u{5B9A}\u{56DE}\u{7B54}\u{5E94}\u{5305}\u{542B}\u{7684}\u{5173}\u{952E}\u{6982}\u{5FF5}\u{3001}\u{4E0A}\u{4E0B}\u{6587}\u{3001}\u{6B63}\u{53CD}\u{8BBA}\u{70B9}\u{548C}\u{6F5C}\u{5728}\u{7684}\u{5EF6}\u{4F38}\u{9886}\u{57DF}
8927
- - \u{6839}\u{636E}\u{5145}\u{5206}\u{4E86}\u{89E3}\u{5230}\u{7684}\u{4FE1}\u{606F}\u{FF0C}\u{6E05}\u{6670}\u{5B8C}\u{6574}\u{7684}\u{590D}\u{8FF0}\u{7528}\u{6237}\u{9700}\u{6C42}\u{FF0C}\u{5E76}\u{7ED9}\u{51FA}\u{4E00}\u{4E2A}\u{9AD8}\u{5EA6}\u{6D53}\u{7F29}\u{7684}\u{3001}\u{7ED3}\u{8BBA}\u{6027}\u{7684}\u{6838}\u{5FC3}\u{89C2}\u{70B9}
8928
-
8929
- **\u{4E0A}\u{4E0B}\u{6587}\u{5206}\u{6790}\u{FF1A}**
8930
- ${validatedArgs.context ? `
8931
- **\u{7528}\u{6237}\u{63D0}\u{4F9B}\u{7684}\u{4E0A}\u{4E0B}\u{6587}\u{FF1A}**
8932
- \`\`\`
8933
- ${validatedArgs.context}
8934
- \`\`\`
8935
-
8936
- **\u{5206}\u{6790}\u{91CD}\u{70B9}\u{FF1A}**
8937
- - \u{6839}\u{636E}\u{4E0A}\u{4E0B}\u{6587}\u{786E}\u{5B9A}\u{5206}\u{6790}\u{65B9}\u{5411}
8938
- - \u{91CD}\u{70B9}\u{5173}\u{6CE8}\u{4E0A}\u{4E0B}\u{6587}\u{4E2D}\u{63D0}\u{5230}\u{7684}\u{5173}\u{952E}\u{8981}\u{7D20}
8939
- - \u{786E}\u{4FDD}\u{5206}\u{6790}\u{7ED3}\u{679C}\u{7B26}\u{5408}\u{7528}\u{6237}\u{9884}\u{671F}
8940
- ` : `
8941
- **\u{65E0}\u{7279}\u{5B9A}\u{4E0A}\u{4E0B}\u{6587}\u{6307}\u{5BFC}**
8942
- - \u{8FDB}\u{884C}\u{901A}\u{7528}\u{56FE}\u{7247}\u{5185}\u{5BB9}\u{5206}\u{6790}
8943
- - \u{8BC6}\u{522B}\u{56FE}\u{7247}\u{4E2D}\u{7684}\u{4E3B}\u{8981}\u{5143}\u{7D20}\u{548C}\u{7279}\u{5F81}
8944
- - \u{63D0}\u{4F9B}\u{5168}\u{9762}\u{7684}\u{56FE}\u{7247}\u{63CF}\u{8FF0}
8945
- `}
8946
-
8947
- **\u{56FE}\u{7247}\u{57FA}\u{672C}\u{4FE1}\u{606F}\u{FF1A}**
8948
- - \u{6587}\u{4EF6}\u{8DEF}\u{5F84}: ${validatedArgs.image_path}
8949
- - \u{56FE}\u{7247}\u{683C}\u{5F0F}: ${external_path_namespaceObject.extname(validatedArgs.image_path)}
8950
- - \u{5206}\u{8FA8}\u{7387}: ${result.basic_info.dimensions.width} \xd7 ${result.basic_info.dimensions.height}
8951
- - \u{6587}\u{4EF6}\u{5927}\u{5C0F}: ${formatFileSize(result.basic_info.file_size)}
8952
-
8953
- ### 2. \u{573A}\u{666F}\u{8BC6}\u{522B}
8954
- **\u{6267}\u{884C}\u{6B65}\u{9AA4}\u{FF1A}**
8955
- - \u{57FA}\u{4E8E}\u{9700}\u{6C42}\u{5206}\u{6790}\u{7684}\u{5185}\u{5BB9}\u{FF0C}\u{627E}\u{51FA}\u{4E3B}\u{8981}\u{77DB}\u{76FE}\u{70B9}\u{FF0C}\u{5B9A}\u{4F4D}\u{6838}\u{5FC3}\u{95EE}\u{9898}\u{8282}\u{70B9}
8956
- - \u{4ECE}\u{7CFB}\u{7EDF}\u{5C42}\u{9762}\u{62C6}\u{89E3}\u{4E3A}\u{53EF}\u{6267}\u{884C}\u{5B50}\u{4EFB}\u{52A1}\u{FF0C}\u{786E}\u{4FDD}\u{903B}\u{8F91}\u{94FE}\u{6761}\u{6E05}\u{6670}\u{FF0C}\u{4E0A}\u{4E0B}\u{6587}\u{4FE1}\u{606F}\u{5145}\u{8DB3}
8957
-
8958
- **\u{5206}\u{6790}\u{7EF4}\u{5EA6}\u{FF1A}**
8959
- 1. **\u{5185}\u{5BB9}\u{573A}\u{666F}\u{8BC6}\u{522B}**
8960
- - \u{56FE}\u{7247}\u{7C7B}\u{578B}\u{8BC6}\u{522B}\u{FF08}\u{81EA}\u{7136}\u{666F}\u{89C2}\u{3001}\u{4EBA}\u{7269}\u{3001}\u{6587}\u{6863}\u{3001}\u{56FE}\u{8868}\u{7B49}\u{FF09}
8961
- - \u{4E3B}\u{8981}\u{5BF9}\u{8C61}\u{8BC6}\u{522B}
8962
- - \u{573A}\u{666F}\u{73AF}\u{5883}\u{5206}\u{6790}
8963
- - \u{60C5}\u{611F}\u{8272}\u{5F69}\u{5224}\u{65AD}
8964
-
8965
- 2. **\u{6280}\u{672F}\u{573A}\u{666F}\u{8BC6}\u{522B}**
8966
- - \u{56FE}\u{7247}\u{8D28}\u{91CF}\u{8BC4}\u{4F30}
8967
- - \u{5206}\u{8FA8}\u{7387}\u{9002}\u{7528}\u{6027}
8968
- - \u{683C}\u{5F0F}\u{517C}\u{5BB9}\u{6027}
8969
- - \u{538B}\u{7F29}\u{8D28}\u{91CF}\u{5206}\u{6790}
8970
-
8971
- 3. **\u{5E94}\u{7528}\u{573A}\u{666F}\u{8BC6}\u{522B}**
8972
- - \u{4F7F}\u{7528}\u{573A}\u{666F}\u{5206}\u{6790}
8973
- - \u{76EE}\u{6807}\u{53D7}\u{4F17}\u{8BC6}\u{522B}
8974
- - \u{5546}\u{4E1A}\u{4EF7}\u{503C}\u{8BC4}\u{4F30}
8975
- - \u{7248}\u{6743}\u{98CE}\u{9669}\u{5206}\u{6790}
8976
-
8977
- ### 3. \u{65B9}\u{6848}\u{8BBE}\u{8BA1}
8978
- **\u{6267}\u{884C}\u{6B65}\u{9AA4}\u{FF1A}**
8979
- - \u{65B9}\u{6848}\u{8BBE}\u{8BA1}\u{4F18}\u{5148}\u{590D}\u{7528}\u{73B0}\u{6709}\u{65B9}\u{6848}\u{FF0C}\u{7EC4}\u{4EF6}\u{FF0C}\u{5DE5}\u{5177}\u{65B9}\u{6CD5}\u{7B49}\u{FF0C}\u{80FD}\u{590D}\u{7528}\u{7684}\u{5C3D}\u{53EF}\u{80FD}\u{590D}\u{7528}
8980
- - \u{626B}\u{63CF}\u{9879}\u{76EE}\u{4E2D}\u{4F7F}\u{7528}\u{7684}\u{6D4B}\u{8BD5}\u{6846}\u{67B6}\u{548C}\u{811A}\u{672C}\u{FF0C}\u{751F}\u{6210}\u{672C}\u{6B21}\u{9700}\u{6C42}\u{7684}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{FF0C}\u{5982}\u{679C}\u{4E0D}\u{5B58}\u{5728}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{FF0C}\u{5219}\u{7F16}\u{5199}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{5230}.aico/tests\u{4E0B}\u{9762}
8981
-
8982
- **\u{8BBE}\u{8BA1}\u{5185}\u{5BB9}\u{FF1A}**
8983
- 1. **\u{5206}\u{6790}\u{65B9}\u{6848}\u{8BBE}\u{8BA1}**
8984
- - \u{56FE}\u{7247}\u{5185}\u{5BB9}\u{8BC6}\u{522B}\u{7B56}\u{7565}
8985
- - \u{7279}\u{5F81}\u{63D0}\u{53D6}\u{65B9}\u{6CD5}
8986
- - \u{5206}\u{7C7B}\u{6807}\u{6CE8}\u{65B9}\u{6848}
8987
- - \u{8D28}\u{91CF}\u{8BC4}\u{4F30}\u{6807}\u{51C6}
8988
-
8989
- 2. **\u{8F93}\u{51FA}\u{65B9}\u{6848}\u{8BBE}\u{8BA1}**
8990
- - \u{5206}\u{6790}\u{62A5}\u{544A}\u{7ED3}\u{6784}
8991
- - \u{5173}\u{952E}\u{4FE1}\u{606F}\u{63D0}\u{53D6}
8992
- - \u{683C}\u{5F0F}\u{5316}\u{8F93}\u{51FA}\u{89C4}\u{8303}
8993
- - \u{591A}\u{8BED}\u{8A00}\u{652F}\u{6301}\u{65B9}\u{6848}
8994
-
8995
- 3. **\u{6D4B}\u{8BD5}\u{65B9}\u{6848}\u{8BBE}\u{8BA1}**
8996
- - \u{56FE}\u{7247}\u{6837}\u{672C}\u{6D4B}\u{8BD5}
8997
- - \u{51C6}\u{786E}\u{6027}\u{9A8C}\u{8BC1}
8998
- - \u{8FB9}\u{754C}\u{6848}\u{4F8B}\u{6D4B}\u{8BD5}
8999
- - \u{6027}\u{80FD}\u{57FA}\u{51C6}\u{6D4B}\u{8BD5}
9000
-
9001
- ### 4. \u{6267}\u{884C}\u{9A8C}\u{8BC1}
9002
- **\u{6267}\u{884C}\u{6B65}\u{9AA4}\u{FF1A}**
9003
- - \u{6309}\u{65B9}\u{6848}\u{8BBE}\u{8BA1}\u{7684}\u{7ED3}\u{679C}\u{8F93}\u{51FA}\u{4EE3}\u{7801}
9004
- - \u{5982}\u{679C}\u{6709}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{FF0C}\u{8FD0}\u{884C}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{5E76}\u{4FEE}\u{6B63}\u{76F4}\u{5230}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{5168}\u{90E8}\u{901A}\u{8FC7}
9005
-
9006
- **\u{9A8C}\u{8BC1}\u{5185}\u{5BB9}\u{FF1A}**
9007
- 1. **\u{56FE}\u{7247}\u{5185}\u{5BB9}\u{9A8C}\u{8BC1}**
9008
- - \u{4E3B}\u{8981}\u{5BF9}\u{8C61}\u{8BC6}\u{522B}\u{51C6}\u{786E}\u{6027}
9009
- - \u{573A}\u{666F}\u{63CF}\u{8FF0}\u{5B8C}\u{6574}\u{6027}
9010
- - \u{7EC6}\u{8282}\u{7279}\u{5F81}\u{6355}\u{6349}
9011
- - \u{4E0A}\u{4E0B}\u{6587}\u{76F8}\u{5173}\u{6027}
9012
-
9013
- 2. **\u{5206}\u{6790}\u{8D28}\u{91CF}\u{9A8C}\u{8BC1}**
9014
- - \u{63CF}\u{8FF0}\u{51C6}\u{786E}\u{6027}\u{68C0}\u{67E5}
9015
- - \u{5173}\u{952E}\u{4FE1}\u{606F}\u{5B8C}\u{6574}\u{6027}
9016
- - \u{903B}\u{8F91}\u{4E00}\u{81F4}\u{6027}\u{9A8C}\u{8BC1}
9017
- - \u{8BED}\u{8A00}\u{8868}\u{8FBE}\u{6E05}\u{6670}\u{5EA6}
9018
-
9019
- 3. **\u{6280}\u{672F}\u{6307}\u{6807}\u{9A8C}\u{8BC1}**
9020
- - \u{5904}\u{7406}\u{65F6}\u{95F4}\u{6548}\u{7387}
9021
- - \u{5185}\u{5B58}\u{4F7F}\u{7528}\u{4F18}\u{5316}
9022
- - \u{9519}\u{8BEF}\u{5904}\u{7406}\u{673A}\u{5236}
9023
- - \u{683C}\u{5F0F}\u{517C}\u{5BB9}\u{6027}
9024
-
9025
- ### 5. \u{603B}\u{7ED3}\u{53CD}\u{9988}
9026
- **\u{6267}\u{884C}\u{6B65}\u{9AA4}\u{FF1A}**
9027
- - \u{8F93}\u{51FA}\u{6700}\u{7EC8}\u{6267}\u{884C}\u{7684}\u{65B9}\u{6848}
9028
- - \u{66F4}\u{65B0}TODO\u{6E05}\u{5355}
9029
- - \u{6839}\u{636E}\u{60C5}\u{51B5}\u{63D0}\u{4F9B}\u{4E00}\u{4E9B}\u{524D}\u{77BB}\u{6027}\u{7684}\u{601D}\u{8003}\u{6216}\u{5EFA}\u{8BAE}
9030
-
9031
- **\u{8F93}\u{51FA}\u{5185}\u{5BB9}\u{FF1A}**
9032
- 1. **\u{56FE}\u{7247}\u{5206}\u{6790}\u{62A5}\u{544A}**
9033
- - \u{57FA}\u{672C}\u{4FE1}\u{606F}\u{6C47}\u{603B}
9034
- - \u{5185}\u{5BB9}\u{8BE6}\u{7EC6}\u{63CF}\u{8FF0}
9035
- - \u{7279}\u{5F81}\u{63D0}\u{53D6}\u{7ED3}\u{679C}
9036
- - \u{8D28}\u{91CF}\u{8BC4}\u{4F30}\u{62A5}\u{544A}
9037
-
9038
- 2. **\u{5E94}\u{7528}\u{5EFA}\u{8BAE}**
9039
- - \u{4F7F}\u{7528}\u{573A}\u{666F}\u{5EFA}\u{8BAE}
9040
- - \u{4F18}\u{5316}\u{6539}\u{8FDB}\u{5EFA}\u{8BAE}
9041
- - \u{6280}\u{672F}\u{5904}\u{7406}\u{5EFA}\u{8BAE}
9042
- - \u{5546}\u{4E1A}\u{5E94}\u{7528}\u{5EFA}\u{8BAE}
9043
-
9044
- ## \u{5F53}\u{524D}\u{5206}\u{6790}\u{7ED3}\u{679C}
9045
-
9046
- **\u{56FE}\u{7247}\u{63CF}\u{8FF0}\u{FF1A}**
9047
- ${result.content.summary}
9048
-
9049
- **\u{8BE6}\u{7EC6}\u{5206}\u{6790}\u{7ED3}\u{679C}\u{FF1A}**
9050
- - \u{57FA}\u{672C}\u{4FE1}\u{606F}\u{5DF2}\u{83B7}\u{53D6}
9051
- - \u{5185}\u{5BB9}\u{5206}\u{6790}\u{5DF2}\u{5B8C}\u{6210}
9052
- - \u{5904}\u{7406}\u{65F6}\u{95F4}: ${result.processing_time_ms}ms
9053
- - \u{5206}\u{6790}\u{72B6}\u{6001}: \u{6210}\u{529F}
9054
-
9055
- ---
9056
-
9057
- **\u{6267}\u{884C}\u{539F}\u{5219}\u{FF1A}**
9058
- - \u{521B}\u{5EFA}\u{5E76}\u{6301}\u{7EED}\u{66F4}\u{65B0}TODO\u{6E05}\u{5355}
9059
- - \u{6301}\u{7EED}\u{5DE5}\u{4F5C}\u{81F3}\u{5B8C}\u{6210}
9060
- - \u{786E}\u{4FDD}\u{5206}\u{6790}\u{7684}\u{51C6}\u{786E}\u{6027}\u{548C}\u{5168}\u{9762}\u{6027}
9061
- - \u{4E25}\u{683C}\u{57FA}\u{4E8E}\u{4EFB}\u{52A1}\u{6307}\u{4EE4}\u{8FDB}\u{884C}\u{5206}\u{6790}
9062
- - \u{4E0D}\u{504F}\u{79BB}\u{4EFB}\u{52A1}\u{8303}\u{56F4}\u{FF0C}\u{8F93}\u{51FA}\u{6E05}\u{6670}\u{51C6}\u{786E}\u{7684}\u{7ED3}\u{679C}
9063
- `;
9064
8814
  return {
9065
8815
  content: [
9066
8816
  {
9067
8817
  type: "text",
9068
- text: `\u{56FE}\u{7247}\u{5185}\u{5BB9}\u{5206}\u{6790}\u{5B8C}\u{6210}
9069
-
9070
- \u{5206}\u{6790}\u{7ED3}\u{679C}\u{FF1A}
9071
- - \u{56FE}\u{7247}\u{6587}\u{4EF6}\u{FF1A}${external_path_namespaceObject.basename(validatedArgs.image_path)}
9072
- - \u{56FE}\u{7247}\u{5C3A}\u{5BF8}\u{FF1A}${result.basic_info.dimensions.width} \xd7 ${result.basic_info.dimensions.height} \u{50CF}\u{7D20}
9073
- - \u{6587}\u{4EF6}\u{5927}\u{5C0F}\u{FF1A}${formatFileSize(result.basic_info.file_size)}
9074
- - \u{5904}\u{7406}\u{65F6}\u{95F4}\u{FF1A}${result.processing_time_ms}ms
9075
-
9076
- \u{56FE}\u{7247}\u{63CF}\u{8FF0}\u{FF1A}
9077
- ${result.content.summary}
9078
-
9079
- ---
9080
-
9081
- ${systemGuidance}`
8818
+ text: result.content.summary
9082
8819
  }
9083
8820
  ]
9084
8821
  };
@@ -9125,18 +8862,6 @@ ${systemGuidance}`
9125
8862
 
9126
8863
  ${error?.message || "\u672A\u77E5\u9519\u8BEF"}`;
9127
8864
  }
9128
- function formatFileSize(bytes) {
9129
- if (0 === bytes) return "0 B";
9130
- const k = 1024;
9131
- const sizes = [
9132
- "B",
9133
- "KB",
9134
- "MB",
9135
- "GB"
9136
- ];
9137
- const i = Math.floor(Math.log(bytes) / Math.log(k));
9138
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
9139
- }
9140
8865
  class ImageConversionError extends Error {
9141
8866
  code;
9142
8867
  context;
@@ -9668,7 +9393,8 @@ ${getErrorSuggestion(error.code)}
9668
9393
  RETRY_DELAY_MS: 1000
9669
9394
  };
9670
9395
  const ImageRecognitionParamsSchema = objectType({
9671
- imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84")
9396
+ imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
9397
+ context: stringType().optional().describe("\u4E0A\u4E0B\u6587\u5185\u5BB9\uFF0C\u7528\u4E8E\u6307\u5BFC\u56FE\u7247\u5206\u6790\u7684\u65B9\u5411\u548C\u8303\u56F4")
9672
9398
  });
9673
9399
  objectType({
9674
9400
  width: numberType().positive("\u56FE\u7247\u5BBD\u5EA6\u5FC5\u987B\u4E3A\u6B63\u6570"),
@@ -10073,12 +9799,15 @@ ${getErrorSuggestion(error.code)}
10073
9799
  }
10074
9800
  }
10075
9801
  class analyzer_ImageAnalyzer {
10076
- async analyzeLongImage(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference = 'auto') {
9802
+ context;
9803
+ async analyzeLongImage(imagePath, imageInfo, segmentConfig, concurrencyConfig, apiPreference = 'auto', context) {
10077
9804
  logger.info("ImageAnalyzer: \u5F00\u59CB\u5206\u6790\u957F\u56FE", {
10078
9805
  imagePath,
10079
9806
  totalSegments: segmentConfig.totalSegments,
10080
- maxConcurrency: concurrencyConfig.maxConcurrency
9807
+ maxConcurrency: concurrencyConfig.maxConcurrency,
9808
+ hasContext: !!context
10081
9809
  });
9810
+ this.context = context;
10082
9811
  const startTime = Date.now();
10083
9812
  const segmentResults = [];
10084
9813
  try {
@@ -10303,7 +10032,12 @@ ${getErrorSuggestion(error.code)}
10303
10032
  return segments;
10304
10033
  }
10305
10034
  buildAnalysisPrompt(segmentInfo) {
10306
- let prompt = `\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}
10035
+ let prompt = '';
10036
+ prompt = this.context ? `${this.context}
10037
+
10038
+ \u{8BF7}\u{6839}\u{636E}\u{4E0A}\u{8FF0}\u{4EFB}\u{52A1}\u{8981}\u{6C42}\u{FF0C}\u{5206}\u{6790}\u{8FD9}\u{5F20}\u{56FE}\u{7247}\u{5E76}\u{63D0}\u{4F9B}\u{76F8}\u{5173}\u{7ED3}\u{679C}\u{3002}\u{53EA}\u{8F93}\u{51FA}\u{4E0E}\u{4EFB}\u{52A1}\u{76F8}\u{5173}\u{7684}\u{5185}\u{5BB9}\u{FF0C}\u{4E0D}\u{8981}\u{6DFB}\u{52A0}\u{989D}\u{5916}\u{7684}\u{89E3}\u{91CA}\u{6216}\u{63CF}\u{8FF0}\u{3002}
10039
+
10040
+ ` : `\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}
10307
10041
 
10308
10042
  \u{8981}\u{6C42}\u{FF1A}
10309
10043
  1. **\u{53EA}\u{8BC6}\u{522B}\u{6587}\u{5B57}**\u{FF1A}\u{4EC5}\u{63D0}\u{53D6}\u{56FE}\u{7247}\u{4E2D}\u{7684}\u{6240}\u{6709}\u{6587}\u{5B57}\u{5185}\u{5BB9}\u{FF0C}\u{4FDD}\u{6301}\u{539F}\u{6709}\u{7684}\u{683C}\u{5F0F}\u{3001}\u{6362}\u{884C}\u{548C}\u{7ED3}\u{6784}
@@ -10326,15 +10060,10 @@ ${getErrorSuggestion(error.code)}
10326
10060
  return prompt;
10327
10061
  }
10328
10062
  buildSystemPrompt() {
10329
- return `\u{4F60}\u{662F}\u{4E00}\u{4E2A}\u{4E13}\u{4E1A}\u{7684}OCR\u{6587}\u{5B57}\u{8BC6}\u{522B}\u{4E13}\u{5BB6}\u{FF0C}\u{4E13}\u{95E8}\u{8D1F}\u{8D23}\u{4ECE}\u{56FE}\u{7247}\u{4E2D}\u{63D0}\u{53D6}\u{6587}\u{5B57}\u{5185}\u{5BB9}\u{3002}
10330
-
10331
- \u{4F60}\u{7684}\u{4EFB}\u{52A1}\u{662F}\u{FF1A}
10332
- 1. \u{9AD8}\u{7CBE}\u{5EA6}\u{8BC6}\u{522B}\u{56FE}\u{7247}\u{4E2D}\u{7684}\u{6240}\u{6709}\u{6587}\u{5B57}\u{5185}\u{5BB9}\u{FF0C}\u{5305}\u{62EC}\u{4E2D}\u{6587}\u{3001}\u{82F1}\u{6587}\u{3001}\u{6570}\u{5B57}\u{3001}\u{7B26}\u{53F7}\u{3001}\u{6807}\u{70B9}\u{7B26}\u{53F7}\u{7B49}
10333
- 2. \u{4FDD}\u{6301}\u{6587}\u{5B57}\u{7684}\u{539F}\u{59CB}\u{683C}\u{5F0F}\u{548C}\u{6392}\u{7248}\u{7ED3}\u{6784}
10334
- 3. \u{786E}\u{4FDD}\u{8BC6}\u{522B}\u{7ED3}\u{679C}\u{7684}\u{5B8C}\u{6574}\u{6027}\u{548C}\u{51C6}\u{786E}\u{6027}
10335
- 4. \u{4E0D}\u{8981}\u{6DFB}\u{52A0}\u{4EFB}\u{4F55}\u{89E3}\u{91CA}\u{3001}\u{63CF}\u{8FF0}\u{3001}\u{5206}\u{6790}\u{6216}\u{989D}\u{5916}\u{5185}\u{5BB9}
10336
-
10337
- \u{91CD}\u{8981}\u{FF1A}\u{53EA}\u{8F93}\u{51FA}\u{56FE}\u{7247}\u{4E2D}\u{5B9E}\u{9645}\u{5B58}\u{5728}\u{7684}\u{6587}\u{5B57}\u{5185}\u{5BB9}\u{FF0C}\u{4E0D}\u{8981}\u{751F}\u{6210}\u{4EFB}\u{4F55}\u{63CF}\u{8FF0}\u{6027}\u{8BED}\u{8A00}\u{3002}`;
10063
+ return `You must interpret and analyze images strictly according to the assigned task.
10064
+ When an image placeholder is provided, your role is to parse the image content only within the scope of the user's instructions.
10065
+ Do not ignore or deviate from the task.
10066
+ Always ensure that your response reflects a clear, accurate interpretation of the image aligned with the given objective.`;
10338
10067
  }
10339
10068
  parseAIResponse(response) {
10340
10069
  let textContent = '';
@@ -10430,7 +10159,7 @@ ${getErrorSuggestion(error.code)}
10430
10159
  this.configCalculator = new ConfigCalculator();
10431
10160
  this.analyzer = new analyzer_ImageAnalyzer();
10432
10161
  }
10433
- async processImage(imagePath) {
10162
+ async processImage(imagePath, context) {
10434
10163
  const startTime = Date.now();
10435
10164
  logger.info("ImageRecognitionProcessor: \u5F00\u59CB\u5904\u7406\u56FE\u7247", {
10436
10165
  imagePath
@@ -10456,7 +10185,7 @@ ${getErrorSuggestion(error.code)}
10456
10185
  segmentHeight: segmentConfig.segmentHeight,
10457
10186
  maxConcurrency: concurrencyConfig.maxConcurrency
10458
10187
  });
10459
- const analysisResult = await this.analyzer.analyzeLongImage(imagePath, imageInfo, segmentConfig, concurrencyConfig, 'auto');
10188
+ const analysisResult = await this.analyzer.analyzeLongImage(imagePath, imageInfo, segmentConfig, concurrencyConfig, 'auto', context);
10460
10189
  const outputPath = await this.generateSingleOutputFile(imageInfo, analysisResult.segmentResults, analysisResult.summary);
10461
10190
  const totalTime = Date.now() - startTime;
10462
10191
  logger.info("\u56FE\u7247\u5904\u7406\u5B8C\u6210", {
@@ -10545,7 +10274,8 @@ ${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
10545
10274
  name: "analyzeLongImage",
10546
10275
  description: "\u4E13\u95E8\u5904\u7406\u957F\u56FE\u7684\u5185\u5BB9\u8BC6\u522B\u667A\u80FD\u4F53\uFF0C\u652F\u6301\u5206\u6BB5\u5904\u7406\u548C\u7EFC\u5408\u5185\u5BB9\u8BC6\u522B\uFF08\u6587\u5B57+\u56FE\u50CF\u63CF\u8FF0\uFF09\uFF0C\u4EE5\u4E2D\u6587Markdown\u683C\u5F0F\u8F93\u51FA\u3002\u53EA\u9700\u63D0\u4F9B\u56FE\u7247\u8DEF\u5F84\u5373\u53EF\uFF0C\u5176\u4ED6\u53C2\u6570\u81EA\u52A8\u4F18\u5316\u3002",
10547
10276
  inputSchema: {
10548
- imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84")
10277
+ imagePath: stringType().min(1).describe("\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84"),
10278
+ context: stringType().optional().describe("\u4E0A\u4E0B\u6587\u5185\u5BB9\uFF0C\u7528\u4E8E\u6307\u5BFC\u56FE\u7247\u5206\u6790\u7684\u65B9\u5411\u548C\u8303\u56F4")
10549
10279
  },
10550
10280
  handler: async (args)=>{
10551
10281
  initializeProjectRoot();
@@ -10553,9 +10283,9 @@ ${allTextContent || "\u672A\u8BC6\u522B\u5230\u6587\u5B57\u5185\u5BB9"}
10553
10283
  args
10554
10284
  });
10555
10285
  try {
10556
- const { imagePath } = ImageRecognitionParamsSchema.parse(args);
10286
+ const { imagePath, context } = ImageRecognitionParamsSchema.parse(args);
10557
10287
  const processor = new ImageRecognitionProcessor();
10558
- const result = await processor.processImage(imagePath);
10288
+ const result = await processor.processImage(imagePath, context);
10559
10289
  logger.info("\u56FE\u7247\u5185\u5BB9\u8BC6\u522B\u667A\u80FD\u4F53: \u5904\u7406\u5B8C\u6210", {
10560
10290
  outputPath: result.outputPath,
10561
10291
  summary: result.summary
@@ -10926,12 +10656,13 @@ ${user_input}
10926
10656
  - \u{56F4}\u{7ED5}\u{95EE}\u{9898}\u{FF0C}\u{5FEB}\u{901F}\u{6784}\u{5EFA}\u{4E00}\u{4E2A}\u{77E5}\u{8BC6}\u{6846}\u{67B6}\u{3002}\u{786E}\u{5B9A}\u{56DE}\u{7B54}\u{5E94}\u{5305}\u{542B}\u{7684}\u{5173}\u{952E}\u{6982}\u{5FF5}\u{3001}\u{4E0A}\u{4E0B}\u{6587}\u{3001}\u{6B63}\u{53CD}\u{8BBA}\u{70B9}\u{548C}\u{6F5C}\u{5728}\u{7684}\u{5EF6}\u{4F38}\u{9886}\u{57DF}
10927
10657
  - \u{6839}\u{636E}\u{5145}\u{5206}\u{4E86}\u{89E3}\u{5230}\u{7684}\u{4FE1}\u{606F}\u{FF0C}\u{6E05}\u{6670}\u{5B8C}\u{6574}\u{7684}\u{590D}\u{8FF0}\u{7528}\u{6237}\u{9700}\u{6C42}\u{FF0C}\u{5E76}\u{7ED9}\u{51FA}\u{4E00}\u{4E2A}\u{9AD8}\u{5EA6}\u{6D53}\u{7F29}\u{7684}\u{3001}\u{7ED3}\u{8BBA}\u{6027}\u{7684}\u{6838}\u{5FC3}\u{89C2}\u{70B9}
10928
10658
 
10929
- **\u{4F7F}\u{7528}\u{5DE5}\u{5177}\u{FF1A}**
10659
+ **\u{4F7F}\u{7528}\u{5DE5}\u{5177}\u{FF1A}**
10930
10660
  ${project_context ? `
10931
- 1. \u{4F7F}\u{7528} listDirectory \u{67E5}\u{770B}\u{9879}\u{76EE}\u{7ED3}\u{6784}\u{FF1A}\`${project_context}\`
10932
- 2. \u{4F7F}\u{7528} grepSearch \u{641C}\u{7D22}\u{76F8}\u{5173}\u{529F}\u{80FD}\u{6A21}\u{5757}\u{FF0C}\u{4E86}\u{89E3}\u{73B0}\u{6709}\u{5B9E}\u{73B0}\u{6A21}\u{5F0F}
10933
- 3. \u{4F7F}\u{7528} readFile \u{8BFB}\u{53D6}\u{5173}\u{952E}\u{914D}\u{7F6E}\u{6587}\u{4EF6}\u{FF08}package.json, tsconfig.json\u{7B49}\u{FF09}
10934
- 4. \u{5206}\u{6790}\u{6280}\u{672F}\u{6808}\u{3001}\u{4EE3}\u{7801}\u{89C4}\u{8303}\u{3001}\u{67B6}\u{6784}\u{6A21}\u{5F0F}
10661
+ 1. \u{4F7F}\u{7528} readFile \u{8BFB}\u{53D6}\u{9879}\u{76EE}\u{6839}\u{76EE}\u{5F55}\u{7684} CLAUDE.md \u{6587}\u{4EF6}\u{FF0C}\u{83B7}\u{53D6}\u{9879}\u{76EE}\u{67B6}\u{6784}\u{7D22}\u{5F15}
10662
+ 2. \u{57FA}\u{4E8E} CLAUDE.md \u{7D22}\u{5F15}\u{FF0C}\u{5FEB}\u{901F}\u{5B9A}\u{4F4D}\u{5230}\u{4E0E}\u{9700}\u{6C42}\u{76F8}\u{5173}\u{7684}\u{6A21}\u{5757}
10663
+ 3. \u{4F7F}\u{7528} grepSearch \u{5728}\u{7279}\u{5B9A}\u{6A21}\u{5757}\u{76EE}\u{5F55}\u{4E0B}\u{641C}\u{7D22}\u{76F8}\u{5173}\u{529F}\u{80FD}\u{5B9E}\u{73B0}
10664
+ 4. \u{4F7F}\u{7528} readFile \u{8BFB}\u{53D6}\u{5173}\u{952E}\u{914D}\u{7F6E}\u{6587}\u{4EF6}\u{4E86}\u{89E3}\u{9879}\u{76EE}\u{8BBE}\u{7F6E}
10665
+ 5. \u{6839}\u{636E}\u{9879}\u{76EE}\u{4E2D}\u{4E0E}\u{9700}\u{6C42}\u{76F8}\u{5173}\u{7684}\u{6A21}\u{5757}\u{7EC4}\u{4EF6}\u{4EE3}\u{7801}\u{4E0E}\u{7528}\u{6237}\u{8F93}\u{5165}\u{7684}\u{9700}\u{6C42}\u{8FDB}\u{884C}\u{6574}\u{5408}\u{FF0C}\u{603B}\u{7ED3}\u{51FA}\u{5B8C}\u{6574}\u{7684}\u{9700}\u{6C42}
10935
10666
  ` : `
10936
10667
  1. \u{57FA}\u{4E8E}\u{901A}\u{7528}\u{6700}\u{4F73}\u{5B9E}\u{8DF5}\u{8FDB}\u{884C}\u{9700}\u{6C42}\u{5206}\u{6790}
10937
10668
  2. \u{641C}\u{7D22}\u{76F8}\u{5173}\u{6280}\u{672F}\u{6587}\u{6863}\u{548C}\u{6700}\u{4F73}\u{5B9E}\u{8DF5}
@@ -10944,19 +10675,31 @@ ${project_context ? `
10944
10675
 
10945
10676
  **\u{8F93}\u{51FA}\u{FF1A}** \u{573A}\u{666F}\u{5206}\u{6790}\u{62A5}\u{544A}\u{548C}\u{4EFB}\u{52A1}\u{5206}\u{89E3}\u{6E05}\u{5355}
10946
10677
 
10947
- ### 3. \u{65B9}\u{6848}\u{8BBE}\u{8BA1}
10678
+ ### 3. \u{9879}\u{76EE}\u{7D22}\u{5F15}\u{9A71}\u{52A8}\u{5206}\u{6790}
10679
+ **\u{6838}\u{5FC3}\u{539F}\u{5219}\u{FF1A}**
10680
+ - CLAUDE.md \u{4F18}\u{5148}\u{FF1A}\u{5148}\u{8BFB}\u{7D22}\u{5F15}\u{FF0C}\u{518D}\u{5206}\u{6790}\u{4EE3}\u{7801}
10681
+ - \u{7CBE}\u{51C6}\u{5B9A}\u{4F4D}\u{FF1A}\u{57FA}\u{4E8E}\u{7D22}\u{5F15}\u{76F4}\u{63A5}\u{627E}\u{5230}\u{76F8}\u{5173}\u{6A21}\u{5757}
10682
+ - \u{67B6}\u{6784}\u{4E00}\u{81F4}\u{FF1A}\u{786E}\u{4FDD}\u{65B0}\u{529F}\u{80FD}\u{7B26}\u{5408}\u{9879}\u{76EE}\u{6574}\u{4F53}\u{8BBE}\u{8BA1}
10683
+
10684
+ **\u{5177}\u{4F53}\u{64CD}\u{4F5C}\u{FF1A}**
10685
+ - \u{8BFB}\u{53D6} CLAUDE.md \u{7406}\u{89E3}\u{9879}\u{76EE}\u{613F}\u{666F}\u{548C}\u{67B6}\u{6784}
10686
+ - \u{5B9A}\u{4F4D}\u{5230}\u{4E0E}\u{9700}\u{6C42}\u{76F8}\u{5173}\u{7684}\u{670D}\u{52A1}\u{6216}\u{7EC4}\u{4EF6}\u{6A21}\u{5757}
10687
+ - \u{5206}\u{6790}\u{73B0}\u{6709}\u{6A21}\u{5757}\u{7684}\u{5B9E}\u{73B0}\u{6A21}\u{5F0F}\u{548C}\u{63A5}\u{53E3}\u{8BBE}\u{8BA1}
10688
+ - \u{57FA}\u{4E8E}\u{73B0}\u{6709}\u{67B6}\u{6784}\u{5236}\u{5B9A}\u{6280}\u{672F}\u{65B9}\u{6848}
10689
+
10690
+ ### 4. \u{65B9}\u{6848}\u{8BBE}\u{8BA1}
10948
10691
  **\u{6267}\u{884C}\u{6B65}\u{9AA4}\u{FF1A}**
10949
10692
  - \u{65B9}\u{6848}\u{8BBE}\u{8BA1}\u{4F18}\u{5148}\u{590D}\u{7528}\u{73B0}\u{6709}\u{65B9}\u{6848}\u{FF0C}\u{7EC4}\u{4EF6}\u{FF0C}\u{5DE5}\u{5177}\u{65B9}\u{6CD5}\u{7B49}\u{FF0C}\u{80FD}\u{590D}\u{7528}\u{7684}\u{5C3D}\u{53EF}\u{80FD}\u{590D}\u{7528}
10950
10693
  - \u{626B}\u{63CF}\u{9879}\u{76EE}\u{4E2D}\u{4F7F}\u{7528}\u{7684}\u{6D4B}\u{8BD5}\u{6846}\u{67B6}\u{548C}\u{811A}\u{672C}\u{FF0C}\u{751F}\u{6210}\u{672C}\u{6B21}\u{9700}\u{6C42}\u{7684}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{FF0C}\u{5982}\u{679C}\u{4E0D}\u{5B58}\u{5728}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{FF0C}\u{5219}\u{7F16}\u{5199}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{5230}.aico/tests\u{4E0B}\u{9762}
10951
10694
 
10952
10695
  **\u{4F7F}\u{7528}\u{5DE5}\u{5177}\u{FF1A}** grepSearch, readFile \u{67E5}\u{627E}\u{73B0}\u{6709}\u{7EC4}\u{4EF6}\u{548C}\u{5DE5}\u{5177}
10953
10696
 
10954
- ### 4. \u{6267}\u{884C}\u{9A8C}\u{8BC1}
10697
+ ### 5. \u{6267}\u{884C}\u{9A8C}\u{8BC1}
10955
10698
  **\u{6267}\u{884C}\u{6B65}\u{9AA4}\u{FF1A}**
10956
10699
  - \u{6309}\u{65B9}\u{6848}\u{8BBE}\u{8BA1}\u{7684}\u{7ED3}\u{679C}\u{8F93}\u{51FA}\u{4EE3}\u{7801}
10957
10700
  - \u{5982}\u{679C}\u{6709}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{FF0C}\u{8FD0}\u{884C}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{5E76}\u{4FEE}\u{6B63}\u{76F4}\u{5230}\u{6D4B}\u{8BD5}\u{811A}\u{672C}\u{5168}\u{90E8}\u{901A}\u{8FC7}
10958
10701
 
10959
- ### 5. \u{603B}\u{7ED3}\u{53CD}\u{9988}
10702
+ ### 6. \u{603B}\u{7ED3}\u{53CD}\u{9988}
10960
10703
  **\u{6267}\u{884C}\u{6B65}\u{9AA4}\u{FF1A}**
10961
10704
  - \u{8F93}\u{51FA}\u{6700}\u{7EC8}\u{6267}\u{884C}\u{7684}\u{65B9}\u{6848}
10962
10705
  - \u{66F4}\u{65B0}TODO\u{6E05}\u{5355}
@@ -11018,7 +10761,16 @@ ${project_context ? `
11018
10761
  \`\`\`
11019
10762
 
11020
10763
  ## \u{4E0B}\u{4E00}\u{6B65}\u{64CD}\u{4F5C}
11021
- \u{5B8C}\u{6210}\u{9700}\u{6C42}\u{5206}\u{6790}\u{540E}\u{FF0C}\u{8C03}\u{7528} **requirement-aligner** \u{5DE5}\u{5177}\u{FF0C}\u{4F20}\u{5165}\u{FF1A}
10764
+ \u{5B8C}\u{6210}\u{9700}\u{6C42}\u{5206}\u{6790}\u{540E}\u{FF0C}\u{6709}\u{4E24}\u{4E2A}\u{9009}\u{62E9}\u{FF1A}
10765
+
10766
+ ### \u{9009}\u{62E9}1\u{FF1A}\u{751F}\u{6210}\u{9700}\u{6C42}\u{62A5}\u{544A}\u{FF08}\u{63A8}\u{8350}\u{7528}\u{4E8E}\u{6587}\u{6863}\u{751F}\u{6210}\u{573A}\u{666F}\u{FF09}
10767
+ \u{8C03}\u{7528} **\u{9700}\u{6C42}\u{62A5}\u{544A}\u{751F}\u{6210}\u{667A}\u{80FD}\u{4F53}** \u{5DE5}\u{5177}\u{FF0C}\u{4F20}\u{5165}\u{FF1A}
10768
+ - requirement_analysis: \u{4E0A}\u{8FF0}\u{751F}\u{6210}\u{7684}\u{7ED3}\u{6784}\u{5316}\u{9700}\u{6C42}\u{6587}\u{6863}\u{FF08}\u{5305}\u{542B}\u{9879}\u{76EE}\u{60C5}\u{51B5}\u{5206}\u{6790}\u{FF09}
10769
+ - current_project_path: \u{9879}\u{76EE}\u{8DEF}\u{5F84}
10770
+ - requirement_type: \u{9700}\u{6C42}\u{7C7B}\u{578B}\u{FF08}PC+API/APP/SDK/\u{6DF7}\u{5408}\u{FF09}
10771
+
10772
+ ### \u{9009}\u{62E9}2\u{FF1A}\u{751F}\u{6210}\u{5B9E}\u{65BD}\u{8BA1}\u{5212}\u{FF08}\u{63A8}\u{8350}\u{7528}\u{4E8E}\u{4EE3}\u{7801}\u{5B9E}\u{73B0}\u{573A}\u{666F}\u{FF09}
10773
+ \u{8C03}\u{7528} **requirement-aligner** \u{5DE5}\u{5177}\u{FF0C}\u{4F20}\u{5165}\u{FF1A}
11022
10774
  - requirement_description: \u{4E0A}\u{8FF0}\u{751F}\u{6210}\u{7684}\u{7ED3}\u{6784}\u{5316}\u{9700}\u{6C42}\u{6587}\u{6863}
11023
10775
  - user_input: \u{539F}\u{59CB}\u{7528}\u{6237}\u{9700}\u{6C42}
11024
10776
 
@@ -11048,7 +10800,10 @@ ${project_context ? `
11048
10800
  "readFile - \u8BFB\u53D6\u5173\u952E\u6587\u4EF6",
11049
10801
  "fileSearch - \u67E5\u627E\u7279\u5B9A\u6587\u4EF6"
11050
10802
  ],
11051
- next_tool: "requirement-aligner"
10803
+ next_tool_options: {
10804
+ for_documentation: "\u9700\u6C42\u62A5\u544A\u751F\u6210\u667A\u80FD\u4F53",
10805
+ for_implementation: "requirement-aligner"
10806
+ }
11052
10807
  }
11053
10808
  }, null, 2)
11054
10809
  }