@aigne/doc-smith 0.2.5 → 0.2.6
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/CHANGELOG.md +7 -0
- package/README.md +1 -0
- package/agents/check-detail-result.mjs +15 -136
- package/agents/check-structure-plan.mjs +56 -7
- package/agents/detail-generator-and-translate.yaml +7 -1
- package/agents/detail-regenerator.yaml +3 -1
- package/agents/docs-generator.yaml +2 -1
- package/agents/find-item-by-path.mjs +63 -14
- package/agents/input-generator.mjs +25 -6
- package/agents/language-selector.mjs +101 -0
- package/agents/publish-docs.mjs +44 -153
- package/agents/retranslate.yaml +74 -0
- package/agents/save-docs.mjs +12 -2
- package/agents/save-single-doc.mjs +19 -0
- package/agents/structure-planning.yaml +6 -0
- package/agents/translate.yaml +3 -0
- package/aigne.yaml +5 -1
- package/package.json +16 -7
- package/prompts/check-structure-planning-result.md +4 -7
- package/prompts/content-detail-generator.md +1 -2
- package/prompts/structure-planning.md +7 -2
- package/prompts/translator.md +4 -0
- package/tests/test-all-validation-cases.mjs +707 -0
- package/utils/markdown-checker.mjs +386 -0
- package/utils/mermaid-validator.mjs +158 -0
- package/utils/mermaid-worker-pool.mjs +254 -0
- package/utils/mermaid-worker.mjs +242 -0
- package/utils/utils.mjs +119 -19
package/agents/publish-docs.mjs
CHANGED
|
@@ -7,119 +7,12 @@ import { existsSync, mkdirSync } from "node:fs";
|
|
|
7
7
|
import { readFile, writeFile } from "node:fs/promises";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import { parse, stringify } from "yaml";
|
|
10
|
-
import { execSync } from "node:child_process";
|
|
11
10
|
import { basename } from "node:path";
|
|
12
11
|
import { loadConfigFromFile, saveValueToConfig } from "../utils/utils.mjs";
|
|
13
12
|
|
|
14
13
|
const WELLKNOWN_SERVICE_PATH_PREFIX = "/.well-known/service";
|
|
15
14
|
const DEFAULT_APP_URL = "https://docsmith.aigne.io";
|
|
16
15
|
|
|
17
|
-
/**
|
|
18
|
-
* Get GitHub repository information
|
|
19
|
-
* @param {string} repoUrl - The repository URL
|
|
20
|
-
* @returns {Promise<Object>} - Repository information
|
|
21
|
-
*/
|
|
22
|
-
async function getGitHubRepoInfo(repoUrl) {
|
|
23
|
-
try {
|
|
24
|
-
// Extract owner and repo from GitHub URL
|
|
25
|
-
const match = repoUrl.match(
|
|
26
|
-
/github\.com[\/:]([^\/]+)\/([^\/]+?)(?:\.git)?$/
|
|
27
|
-
);
|
|
28
|
-
if (!match) return null;
|
|
29
|
-
|
|
30
|
-
const [, owner, repo] = match;
|
|
31
|
-
const apiUrl = `https://api.github.com/repos/${owner}/${repo}`;
|
|
32
|
-
|
|
33
|
-
const response = await fetch(apiUrl);
|
|
34
|
-
if (!response.ok) return null;
|
|
35
|
-
|
|
36
|
-
const data = await response.json();
|
|
37
|
-
return {
|
|
38
|
-
name: data.name,
|
|
39
|
-
description: data.description || "",
|
|
40
|
-
icon: data.owner?.avatar_url || "",
|
|
41
|
-
};
|
|
42
|
-
} catch (error) {
|
|
43
|
-
console.warn("Failed to fetch GitHub repository info:", error.message);
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Get project information with user confirmation
|
|
50
|
-
* @param {Object} options - Options object containing prompts
|
|
51
|
-
* @returns {Promise<Object>} - Project information including name, description, and icon
|
|
52
|
-
*/
|
|
53
|
-
async function getProjectInfo(options) {
|
|
54
|
-
let repoInfo = null;
|
|
55
|
-
let defaultName = basename(process.cwd());
|
|
56
|
-
let defaultDescription = "";
|
|
57
|
-
let defaultIcon = "";
|
|
58
|
-
|
|
59
|
-
// Check if we're in a git repository
|
|
60
|
-
try {
|
|
61
|
-
const gitRemote = execSync("git remote get-url origin", {
|
|
62
|
-
encoding: "utf8",
|
|
63
|
-
stdio: ["pipe", "pipe", "ignore"],
|
|
64
|
-
}).trim();
|
|
65
|
-
|
|
66
|
-
// Extract repository name from git remote URL
|
|
67
|
-
const repoName = gitRemote.split("/").pop().replace(".git", "");
|
|
68
|
-
defaultName = repoName;
|
|
69
|
-
|
|
70
|
-
// If it's a GitHub repository, try to get additional info
|
|
71
|
-
if (gitRemote.includes("github.com")) {
|
|
72
|
-
repoInfo = await getGitHubRepoInfo(gitRemote);
|
|
73
|
-
if (repoInfo) {
|
|
74
|
-
defaultDescription = repoInfo.description;
|
|
75
|
-
defaultIcon = repoInfo.icon;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
} catch (error) {
|
|
79
|
-
// Not in git repository or no origin remote, use current directory name
|
|
80
|
-
console.warn("No git repository found, using current directory name");
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Prompt user for project information
|
|
84
|
-
console.log("\n📋 Project Information for Documentation Platform");
|
|
85
|
-
|
|
86
|
-
const projectName = await options.prompts.input({
|
|
87
|
-
message: "Project name:",
|
|
88
|
-
default: defaultName,
|
|
89
|
-
validate: (input) => {
|
|
90
|
-
if (!input || input.trim() === "") {
|
|
91
|
-
return "Project name cannot be empty";
|
|
92
|
-
}
|
|
93
|
-
return true;
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const projectDescription = await options.prompts.input({
|
|
98
|
-
message: "Project description (optional):",
|
|
99
|
-
default: defaultDescription,
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const projectIcon = await options.prompts.input({
|
|
103
|
-
message: "Project icon URL (optional):",
|
|
104
|
-
default: defaultIcon,
|
|
105
|
-
validate: (input) => {
|
|
106
|
-
if (!input || input.trim() === "") return true;
|
|
107
|
-
try {
|
|
108
|
-
new URL(input);
|
|
109
|
-
return true;
|
|
110
|
-
} catch {
|
|
111
|
-
return "Please enter a valid URL";
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
name: projectName.trim(),
|
|
118
|
-
description: projectDescription.trim(),
|
|
119
|
-
icon: projectIcon.trim(),
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
16
|
/**
|
|
124
17
|
* Get access token from environment, config file, or prompt user for authorization
|
|
125
18
|
* @param {string} appUrl - The application URL
|
|
@@ -207,7 +100,7 @@ async function getAccessToken(appUrl) {
|
|
|
207
100
|
}
|
|
208
101
|
|
|
209
102
|
export default async function publishDocs(
|
|
210
|
-
{ docsDir, appUrl, boardId,
|
|
103
|
+
{ docsDir, appUrl, boardId, projectName, projectDesc, projectLogo },
|
|
211
104
|
options
|
|
212
105
|
) {
|
|
213
106
|
// Check if DOC_DISCUSS_KIT_URL is set in environment variables
|
|
@@ -260,58 +153,56 @@ export default async function publishDocs(
|
|
|
260
153
|
|
|
261
154
|
const sidebarPath = join(docsDir, "_sidebar.md");
|
|
262
155
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
156
|
+
// Get project info from config
|
|
157
|
+
const projectInfo = {
|
|
158
|
+
name: projectName || config?.projectName || basename(process.cwd()),
|
|
159
|
+
description: projectDesc || config?.projectDesc || "",
|
|
160
|
+
icon: projectLogo || config?.projectLogo || "",
|
|
267
161
|
};
|
|
268
162
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
await
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
163
|
+
try {
|
|
164
|
+
const {
|
|
165
|
+
success,
|
|
166
|
+
boardId: newBoardId,
|
|
167
|
+
docsUrl,
|
|
168
|
+
} = await publishDocsFn({
|
|
169
|
+
sidebarPath,
|
|
170
|
+
accessToken,
|
|
171
|
+
appUrl,
|
|
172
|
+
boardId,
|
|
173
|
+
autoCreateBoard: true,
|
|
174
|
+
// Pass additional project information if available
|
|
175
|
+
boardName: projectInfo.name,
|
|
176
|
+
boardDesc: projectInfo.description,
|
|
177
|
+
boardCover: projectInfo.icon,
|
|
178
|
+
});
|
|
278
179
|
|
|
279
|
-
|
|
280
|
-
success
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
accessToken,
|
|
286
|
-
appUrl,
|
|
287
|
-
boardId,
|
|
288
|
-
autoCreateBoard: true,
|
|
289
|
-
// Pass additional project information if available
|
|
290
|
-
boardName: projectInfo.name,
|
|
291
|
-
boardDesc: projectInfo.description,
|
|
292
|
-
boardCover: projectInfo.icon,
|
|
293
|
-
});
|
|
180
|
+
// Save values to config.yaml if publish was successful
|
|
181
|
+
if (success) {
|
|
182
|
+
// Save appUrl to config only when not using environment variable
|
|
183
|
+
if (!useEnvAppUrl) {
|
|
184
|
+
await saveValueToConfig("appUrl", appUrl);
|
|
185
|
+
}
|
|
294
186
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
187
|
+
// Save boardId to config if it was auto-created
|
|
188
|
+
if (boardId !== newBoardId) {
|
|
189
|
+
await saveValueToConfig(
|
|
190
|
+
"boardId",
|
|
191
|
+
newBoardId,
|
|
192
|
+
"⚠️ Warning: boardId is auto-generated by system, please do not edit manually"
|
|
193
|
+
);
|
|
194
|
+
}
|
|
300
195
|
}
|
|
301
196
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
197
|
+
const message = `✅ Documentation Published Successfully!`;
|
|
198
|
+
return {
|
|
199
|
+
message,
|
|
200
|
+
};
|
|
201
|
+
} catch (error) {
|
|
202
|
+
return {
|
|
203
|
+
message: `❌ Failed to publish docs: ${error.message}`,
|
|
204
|
+
};
|
|
306
205
|
}
|
|
307
|
-
|
|
308
|
-
// const message = `## ✅ Documentation Published Successfully!
|
|
309
|
-
|
|
310
|
-
// Documentation is now available at: \`${docsUrl}\`
|
|
311
|
-
// `;
|
|
312
|
-
return {
|
|
313
|
-
// message,
|
|
314
|
-
};
|
|
315
206
|
}
|
|
316
207
|
|
|
317
208
|
publishDocs.input_schema = {
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
type: team
|
|
2
|
+
name: retranslate
|
|
3
|
+
alias:
|
|
4
|
+
- rt
|
|
5
|
+
- translate-again
|
|
6
|
+
description: Re-translate individual document content to selected languages
|
|
7
|
+
skills:
|
|
8
|
+
- url: ./input-generator.mjs
|
|
9
|
+
default_input:
|
|
10
|
+
skipIfExists: true
|
|
11
|
+
- ./load-config.mjs
|
|
12
|
+
- ./load-sources.mjs
|
|
13
|
+
- type: transform
|
|
14
|
+
jsonata: |
|
|
15
|
+
$merge([
|
|
16
|
+
$,
|
|
17
|
+
{
|
|
18
|
+
'structurePlan': originalStructurePlan,
|
|
19
|
+
'structurePlanResult': $map(originalStructurePlan, function($item) {
|
|
20
|
+
$merge([
|
|
21
|
+
$item,
|
|
22
|
+
{
|
|
23
|
+
'translates': [$map(translateLanguages, function($lang) { {"language": $lang} })]
|
|
24
|
+
}
|
|
25
|
+
])
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
])
|
|
29
|
+
- url: ./find-item-by-path.mjs
|
|
30
|
+
default_input:
|
|
31
|
+
isTranslate: true
|
|
32
|
+
- ./language-selector.mjs
|
|
33
|
+
- type: transform
|
|
34
|
+
jsonata: |
|
|
35
|
+
$merge([
|
|
36
|
+
$,
|
|
37
|
+
{
|
|
38
|
+
'translates': [$map(selectedLanguages, function($lang) { {"language": $lang} })]
|
|
39
|
+
}
|
|
40
|
+
])
|
|
41
|
+
- ./batch-translate.yaml
|
|
42
|
+
- url: ./save-single-doc.mjs
|
|
43
|
+
default_input:
|
|
44
|
+
isTranslate: true
|
|
45
|
+
isShowMessage: true
|
|
46
|
+
input_schema:
|
|
47
|
+
type: object
|
|
48
|
+
properties:
|
|
49
|
+
glossary:
|
|
50
|
+
type: string
|
|
51
|
+
description: Glossary of terms for consistent terminology
|
|
52
|
+
doc-path:
|
|
53
|
+
type: string
|
|
54
|
+
description: Document path to retranslate
|
|
55
|
+
# languages:
|
|
56
|
+
# type: array
|
|
57
|
+
# items:
|
|
58
|
+
# type: string
|
|
59
|
+
# description: Languages to translate to
|
|
60
|
+
feedback:
|
|
61
|
+
type: string
|
|
62
|
+
description: Feedback for translation improvement
|
|
63
|
+
output_schema:
|
|
64
|
+
type: object
|
|
65
|
+
properties:
|
|
66
|
+
title:
|
|
67
|
+
type: string
|
|
68
|
+
description:
|
|
69
|
+
type: string
|
|
70
|
+
path:
|
|
71
|
+
type: string
|
|
72
|
+
content:
|
|
73
|
+
type: string
|
|
74
|
+
mode: sequential
|
package/agents/save-docs.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { writeFile, readdir, unlink } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { getCurrentGitHead, saveGitHeadToConfig } from "../utils/utils.mjs";
|
|
4
|
+
import { shutdownMermaidWorkerPool } from "../utils/mermaid-worker-pool.mjs";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* @param {Object} params
|
|
@@ -14,6 +15,7 @@ export default async function saveDocs({
|
|
|
14
15
|
docsDir,
|
|
15
16
|
translateLanguages = [],
|
|
16
17
|
locale,
|
|
18
|
+
projectInfoMessage,
|
|
17
19
|
}) {
|
|
18
20
|
const results = [];
|
|
19
21
|
// Save current git HEAD to config.yaml for change detection
|
|
@@ -47,8 +49,9 @@ export default async function saveDocs({
|
|
|
47
49
|
|
|
48
50
|
const message = `## ✅ Documentation Generated Successfully!
|
|
49
51
|
|
|
50
|
-
Successfully generated **${structurePlan.length}** documents and saved to:
|
|
51
|
-
|
|
52
|
+
Successfully generated **${structurePlan.length}** documents and saved to:
|
|
53
|
+
\`${docsDir}\`
|
|
54
|
+
${projectInfoMessage || ""}
|
|
52
55
|
### 🚀 Next Steps
|
|
53
56
|
|
|
54
57
|
1. Publish Documentation
|
|
@@ -78,6 +81,13 @@ export default async function saveDocs({
|
|
|
78
81
|
---
|
|
79
82
|
`;
|
|
80
83
|
|
|
84
|
+
// Shutdown mermaid worker pool to ensure clean exit
|
|
85
|
+
try {
|
|
86
|
+
await shutdownMermaidWorkerPool();
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.warn("Failed to shutdown mermaid worker pool:", error.message);
|
|
89
|
+
}
|
|
90
|
+
|
|
81
91
|
return {
|
|
82
92
|
message,
|
|
83
93
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { saveDocWithTranslations } from "../utils/utils.mjs";
|
|
2
|
+
import { shutdownMermaidWorkerPool } from "../utils/mermaid-worker-pool.mjs";
|
|
2
3
|
|
|
3
4
|
export default async function saveSingleDoc({
|
|
4
5
|
path,
|
|
@@ -7,6 +8,8 @@ export default async function saveSingleDoc({
|
|
|
7
8
|
translates,
|
|
8
9
|
labels,
|
|
9
10
|
locale,
|
|
11
|
+
isTranslate = false,
|
|
12
|
+
isShowMessage = false,
|
|
10
13
|
}) {
|
|
11
14
|
const results = await saveDocWithTranslations({
|
|
12
15
|
path,
|
|
@@ -15,6 +18,22 @@ export default async function saveSingleDoc({
|
|
|
15
18
|
translates,
|
|
16
19
|
labels,
|
|
17
20
|
locale,
|
|
21
|
+
isTranslate,
|
|
18
22
|
});
|
|
23
|
+
|
|
24
|
+
if (isShowMessage) {
|
|
25
|
+
// Shutdown mermaid worker pool to ensure clean exit
|
|
26
|
+
try {
|
|
27
|
+
await shutdownMermaidWorkerPool();
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.warn("Failed to shutdown mermaid worker pool:", error.message);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const message = isTranslate
|
|
33
|
+
? `✅ Translation completed successfully`
|
|
34
|
+
: `✅ Document updated successfully`;
|
|
35
|
+
return { message };
|
|
36
|
+
}
|
|
37
|
+
|
|
19
38
|
return {};
|
|
20
39
|
}
|
|
@@ -36,6 +36,12 @@ input_schema:
|
|
|
36
36
|
output_schema:
|
|
37
37
|
type: object
|
|
38
38
|
properties:
|
|
39
|
+
projectName:
|
|
40
|
+
type: string
|
|
41
|
+
description: 根据 DataSources 分析项目名称,注意是原始项目名称
|
|
42
|
+
projectDesc:
|
|
43
|
+
type: string
|
|
44
|
+
description: 根据 DataSources 分析生成当前项目描述,为原始项目生成描述,描述简洁,不超过 50 个单词
|
|
39
45
|
structurePlan: ./schema/structure-plan.yaml
|
|
40
46
|
structurePlanTree:
|
|
41
47
|
type: string
|
package/agents/translate.yaml
CHANGED
package/aigne.yaml
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
chat_model:
|
|
4
4
|
provider: google
|
|
5
|
-
name: gemini-2.5-pro
|
|
5
|
+
# name: gemini-2.5-pro
|
|
6
|
+
name: gemini-2.5-flash
|
|
6
7
|
temperature: 0.8
|
|
7
8
|
agents:
|
|
8
9
|
- ./agents/structure-planning.yaml
|
|
@@ -28,6 +29,8 @@ agents:
|
|
|
28
29
|
- ./agents/load-config.mjs
|
|
29
30
|
- ./agents/team-publish-docs.yaml
|
|
30
31
|
- ./agents/find-item-by-path.mjs
|
|
32
|
+
- ./agents/retranslate.yaml
|
|
33
|
+
- ./agents/language-selector.mjs
|
|
31
34
|
- ./docs-mcp/get-docs-structure.mjs
|
|
32
35
|
- ./docs-mcp/get-docs-detail.mjs
|
|
33
36
|
- ./docs-mcp/docs-search.yaml
|
|
@@ -40,6 +43,7 @@ cli:
|
|
|
40
43
|
- ./agents/docs-generator.yaml
|
|
41
44
|
- ./agents/detail-regenerator.yaml
|
|
42
45
|
- ./agents/team-publish-docs.yaml
|
|
46
|
+
- ./agents/retranslate.yaml
|
|
43
47
|
mcp_server:
|
|
44
48
|
agents:
|
|
45
49
|
- ./docs-mcp/get-docs-structure.mjs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/doc-smith",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -12,17 +12,26 @@
|
|
|
12
12
|
"author": "Arcblock <blocklet@arcblock.io> https://github.com/blocklet",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@aigne/anthropic": "^0.10.
|
|
16
|
-
"@aigne/cli": "^1.
|
|
17
|
-
"@aigne/core": "^1.
|
|
18
|
-
"@aigne/gemini": "^0.8.
|
|
19
|
-
"@aigne/openai": "^0.10.
|
|
20
|
-
"@aigne/publish-docs": "^0.5.
|
|
15
|
+
"@aigne/anthropic": "^0.10.13",
|
|
16
|
+
"@aigne/cli": "^1.33.1",
|
|
17
|
+
"@aigne/core": "^1.48.0",
|
|
18
|
+
"@aigne/gemini": "^0.8.17",
|
|
19
|
+
"@aigne/openai": "^0.10.17",
|
|
20
|
+
"@aigne/publish-docs": "^0.5.4",
|
|
21
21
|
"chalk": "^5.5.0",
|
|
22
|
+
"dompurify": "^3.2.6",
|
|
22
23
|
"glob": "^11.0.3",
|
|
24
|
+
"jsdom": "^26.1.0",
|
|
25
|
+
"mermaid": "^11.9.0",
|
|
23
26
|
"open": "^10.2.0",
|
|
27
|
+
"remark-gfm": "^4.0.1",
|
|
28
|
+
"remark-lint": "^10.0.1",
|
|
29
|
+
"remark-parse": "^11.0.0",
|
|
24
30
|
"terminal-link": "^4.0.0",
|
|
25
31
|
"ufo": "^1.6.1",
|
|
32
|
+
"unified": "^11.0.5",
|
|
33
|
+
"unist-util-visit": "^5.0.0",
|
|
34
|
+
"vfile": "^6.0.3",
|
|
26
35
|
"yaml": "^2.8.0"
|
|
27
36
|
},
|
|
28
37
|
"scripts": {
|
|
@@ -16,15 +16,13 @@
|
|
|
16
16
|
- **用户反馈**:
|
|
17
17
|
```
|
|
18
18
|
{{ feedback }}
|
|
19
|
-
|
|
20
|
-
根据最新的 Data Sources 按需要更新节点的 sourceIds。
|
|
21
19
|
```
|
|
22
20
|
</context>
|
|
23
21
|
|
|
24
22
|
<goal>
|
|
25
|
-
|
|
23
|
+
你的主要目标是验证三条关键规则:
|
|
26
24
|
1. **反馈的实现**:新的结构规划**必须**正确地实现用户反馈中要求的所有变更。
|
|
27
|
-
2. **无关节点的稳定性**:没有在用户反馈中被提及的节点 ** path 属性不能被修改 **。`path` 是关联现有内容的关键标识符,其稳定性至关重要。
|
|
25
|
+
2. **无关节点的稳定性**:没有在用户反馈中被提及的节点 ** path、sourcesIds 属性不能被修改 **。`path`、`sourcesIds` 是关联现有内容的关键标识符,其稳定性至关重要。
|
|
28
26
|
3. **数据有效性**: 所有 {{ nodeName }} 都有关联数据源,sourceIds 中都有值。
|
|
29
27
|
</goal>
|
|
30
28
|
|
|
@@ -40,9 +38,8 @@
|
|
|
40
38
|
1. **分析反馈**:仔细阅读并理解 `<context>` 中 用户反馈 提出的每一项变更要求。明确哪些节点是需要被修改、添加或删除的目标。
|
|
41
39
|
2. **验证反馈的实现**:对比 `<context>` 中的 `structurePlan` 和 `originalStructurePlan`,确认所要求的变更是否已执行。例如,如果反馈是“移除‘示例’部分”,你必须检查该部分在 `structurePlan` 中是否已不存在。
|
|
42
40
|
3. **验证无关节点的稳定性**:这是最关键的检查。遍历 `structurePlan` 中的所有节点。对于每一个在 `originalStructurePlan` 中也存在、但并未在反馈中被提及的节点:
|
|
43
|
-
* **至关重要**:其 `path` 属性**必须**与 `originalStructurePlan` 中的完全相同。
|
|
44
|
-
* 理想情况下,其他属性(如 `title
|
|
45
|
-
4. **`sourcesIds` 是允许变更的**,每次结构规划可以根据最新的 DataSources 变更依赖的数据源,sourceIds 不能为空。
|
|
41
|
+
* **至关重要**:其 `path`、`sourcesIds` 属性**必须**与 `originalStructurePlan` 中的完全相同。
|
|
42
|
+
* 理想情况下,其他属性(如 `title`、`description`)也应保持稳定,除非这些变更是由某个被要求的变更直接导致的,或者是 DataSource 变更导致。
|
|
46
43
|
</rules>
|
|
47
44
|
|
|
48
45
|
<output>
|
|
@@ -27,10 +27,15 @@
|
|
|
27
27
|
{{originalStructurePlan}}
|
|
28
28
|
</last_structure_plan>
|
|
29
29
|
|
|
30
|
+
<last_structure_plan_rule>
|
|
31
|
+
如果提供了上一轮生成的结构规划(last_structure_plan),需要遵循以下规则:
|
|
32
|
+
1. **反馈的实现**:新的结构规划**必须**正确地实现用户反馈中要求的所有变更。
|
|
33
|
+
2. **无关节点的稳定性**:没有在用户反馈中被提及的节点 ** path、sourcesIds 属性不能被修改 **。`path`、`sourcesIds` 是关联现有内容的关键标识符,其稳定性至关重要。
|
|
34
|
+
理想情况下,其他属性(如 `title`、`description`)也应保持稳定,除非这些变更是由某个被要求的变更直接导致的,或者是 DataSource 变更导致。
|
|
35
|
+
</last_structure_plan_rule>
|
|
36
|
+
|
|
30
37
|
<structure_plan_feedback>
|
|
31
38
|
{{ feedback }}
|
|
32
|
-
|
|
33
|
-
根据最新的 Data Sources 按需要更新节点的 sourceIds,如没有大的变化,可以不更新。
|
|
34
39
|
</structure_plan_feedback>
|
|
35
40
|
|
|
36
41
|
<review_structure_plan>
|