@aigne/doc-smith 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +9 -5
- package/agents/check-structure-planning-result.yaml +1 -1
- package/agents/check-structure-planning.mjs +4 -4
- package/agents/detail-generator-and-translate.yaml +1 -1
- package/agents/detail-regenerator.yaml +2 -2
- package/agents/docs-generator.yaml +2 -2
- package/agents/find-item-by-path.mjs +5 -5
- package/agents/load-sources.mjs +30 -8
- package/agents/structure-planning.yaml +1 -1
- package/aigne.yaml +12 -0
- package/docs-mcp/get-docs-detail.mjs +2 -3
- package/docs-mcp/get-docs-structure.mjs +8 -3
- package/package.json +1 -1
- package/prompts/check-structure-planning-result.md +7 -5
- package/prompts/structure-planning.md +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.0](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.0.2...v0.1.0) (2025-07-31)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add entry agents for mcp server and cli ([fa85d65](https://github.com/AIGNE-io/aigne-doc-smith/commit/fa85d651e8dc723e2b97150fc2258b115c6c5bb0))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* polish command param ([#3](https://github.com/AIGNE-io/aigne-doc-smith/issues/3)) ([003f6b8](https://github.com/AIGNE-io/aigne-doc-smith/commit/003f6b8ae2c9e1af55ba1841458fa8567a0eb2f0))
|
|
14
|
+
* polish docs mcp agent ([8654cd4](https://github.com/AIGNE-io/aigne-doc-smith/commit/8654cd4ea38034f3af0244f56b27acf66ba704e1))
|
|
15
|
+
|
|
3
16
|
## 0.0.2 (2025-07-30)
|
|
4
17
|
|
|
5
18
|
|
package/README.md
CHANGED
|
@@ -64,14 +64,14 @@ npx --no doc-smith run --entry-agent init
|
|
|
64
64
|
npx --no doc-smith run --entry-agent generator --model gemini:gemini-2.5-flash
|
|
65
65
|
|
|
66
66
|
# 重新生成单篇
|
|
67
|
-
npx --no doc-smith run --entry-agent regenerator --input-path bitnet-
|
|
67
|
+
npx --no doc-smith run --entry-agent regenerator --input-path bitnet-getting-started
|
|
68
68
|
|
|
69
69
|
# 结构规划优化
|
|
70
|
-
npx --no doc-smith run --
|
|
70
|
+
npx --no doc-smith run --entry-agent generator --input-feedback "补充节点的 sourceIds,确保所有节点 sourceIds 都有值" --model gemini:gemini-2.5-pro
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
# 发布文档
|
|
74
|
-
npx --no doc-smith run --
|
|
74
|
+
npx --no doc-smith run --entry-agent publish
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
```
|
|
@@ -83,10 +83,14 @@ npx --no doc-smith run --input @./doc-smith/config.yaml --format yaml --entry-ag
|
|
|
83
83
|
aigne doc init
|
|
84
84
|
|
|
85
85
|
# 生成文档
|
|
86
|
-
aigne doc
|
|
86
|
+
aigne doc generate
|
|
87
|
+
|
|
88
|
+
# 优化结构规划
|
|
89
|
+
aigne doc generate --feedback "删除 About 文档"
|
|
87
90
|
|
|
88
91
|
# 优化单篇文档
|
|
89
|
-
|
|
92
|
+
# 可使用 structure-plan.json 中的 path ,或 Discuss Kit 中访问的 path
|
|
93
|
+
aigne doc update --doc-path /faq --feedback "添加更多的 FAQ"
|
|
90
94
|
|
|
91
95
|
# 发布文档
|
|
92
96
|
aigne doc publish
|
|
@@ -9,11 +9,11 @@ import { OpenAIChatModel } from "@aigne/openai";
|
|
|
9
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
|
|
11
11
|
export default async function checkStructurePlanning(
|
|
12
|
-
{ originalStructurePlan,
|
|
12
|
+
{ originalStructurePlan, feedback, ...rest },
|
|
13
13
|
options
|
|
14
14
|
) {
|
|
15
15
|
// If originalStructurePlan exists, return directly
|
|
16
|
-
if (originalStructurePlan && !
|
|
16
|
+
if (originalStructurePlan && !feedback) {
|
|
17
17
|
return {
|
|
18
18
|
structurePlan: originalStructurePlan,
|
|
19
19
|
};
|
|
@@ -39,14 +39,14 @@ export default async function checkStructurePlanning(
|
|
|
39
39
|
const panningAgent = aigne.agents["reflective-structure-planner"];
|
|
40
40
|
|
|
41
41
|
const result = await options.context.invoke(panningAgent, {
|
|
42
|
-
|
|
42
|
+
feedback: feedback || "",
|
|
43
43
|
originalStructurePlan,
|
|
44
44
|
...rest,
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
return {
|
|
48
48
|
...result,
|
|
49
|
-
|
|
49
|
+
feedback: "", // clear feedback
|
|
50
50
|
originalStructurePlan: originalStructurePlan
|
|
51
51
|
? originalStructurePlan
|
|
52
52
|
: JSON.parse(JSON.stringify(result.structurePlan || [])),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type: team
|
|
2
|
-
name:
|
|
2
|
+
name: update
|
|
3
3
|
description: Optimize and regenerate individual document content and translations
|
|
4
4
|
skills:
|
|
5
5
|
- ./load-config.mjs
|
|
@@ -43,7 +43,7 @@ input_schema:
|
|
|
43
43
|
glossary:
|
|
44
44
|
type: string
|
|
45
45
|
description: Glossary of terms for consistent terminology
|
|
46
|
-
path:
|
|
46
|
+
doc-path:
|
|
47
47
|
type: string
|
|
48
48
|
description: Document path to regenerate
|
|
49
49
|
feedback:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type: team
|
|
2
|
-
name:
|
|
2
|
+
name: generate
|
|
3
3
|
description: Automatically generates comprehensive project documentation
|
|
4
4
|
skills:
|
|
5
5
|
- ./load-config.mjs
|
|
@@ -94,7 +94,7 @@ input_schema:
|
|
|
94
94
|
# type: string
|
|
95
95
|
# description: Type of documentation (general, getting-started, reference, faq)
|
|
96
96
|
# default: general
|
|
97
|
-
|
|
97
|
+
feedback:
|
|
98
98
|
type: string
|
|
99
99
|
description: Feedback for structure planning adjustments
|
|
100
100
|
# labels:
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
export default async function findItemByPath({
|
|
2
|
-
path,
|
|
2
|
+
"doc-path": docPath,
|
|
3
3
|
structurePlanResult,
|
|
4
4
|
boardId,
|
|
5
5
|
}) {
|
|
6
6
|
let foundItem = null;
|
|
7
7
|
|
|
8
8
|
// First try direct path matching
|
|
9
|
-
foundItem = structurePlanResult.find((item) => item.path ===
|
|
9
|
+
foundItem = structurePlanResult.find((item) => item.path === docPath);
|
|
10
10
|
|
|
11
11
|
// If not found and boardId is provided, try boardId-flattenedPath format matching
|
|
12
12
|
if (!foundItem && boardId) {
|
|
13
13
|
// Check if path starts with boardId followed by a dash
|
|
14
|
-
if (
|
|
14
|
+
if (docPath.startsWith(`${boardId}-`)) {
|
|
15
15
|
// Extract the flattened path part after boardId-
|
|
16
|
-
const flattenedPath =
|
|
16
|
+
const flattenedPath = docPath.substring(boardId.length + 1);
|
|
17
17
|
|
|
18
18
|
// Find item by comparing flattened paths
|
|
19
19
|
foundItem = structurePlanResult.find((item) => {
|
|
@@ -28,7 +28,7 @@ export default async function findItemByPath({
|
|
|
28
28
|
|
|
29
29
|
if (!foundItem) {
|
|
30
30
|
throw new Error(
|
|
31
|
-
`Item with path "${
|
|
31
|
+
`Item with path "${docPath}" not found in structurePlanResult`
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
34
|
|
package/agents/load-sources.mjs
CHANGED
|
@@ -155,7 +155,8 @@ export default async function loadSources({
|
|
|
155
155
|
excludePatterns,
|
|
156
156
|
outputDir,
|
|
157
157
|
docsDir,
|
|
158
|
-
|
|
158
|
+
"doc-path": docPath,
|
|
159
|
+
boardId,
|
|
159
160
|
useDefaultPatterns = true,
|
|
160
161
|
} = {}) {
|
|
161
162
|
let files = Array.isArray(sources) ? [...sources] : [];
|
|
@@ -250,15 +251,32 @@ export default async function loadSources({
|
|
|
250
251
|
|
|
251
252
|
// Get the last output result of the specified path
|
|
252
253
|
let content;
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
if (docPath) {
|
|
255
|
+
let fileFullName;
|
|
256
|
+
|
|
257
|
+
// First try direct path matching (original format)
|
|
258
|
+
const flatName = docPath.replace(/^\//, "").replace(/\//g, "-");
|
|
259
|
+
fileFullName = `${flatName}.md`;
|
|
260
|
+
let filePath = path.join(docsDir, fileFullName);
|
|
261
|
+
|
|
257
262
|
try {
|
|
258
263
|
await access(filePath);
|
|
259
264
|
content = await readFile(filePath, "utf8");
|
|
260
265
|
} catch {
|
|
261
|
-
//
|
|
266
|
+
// If not found and boardId is provided, try boardId-flattenedPath format
|
|
267
|
+
if (boardId && docPath.startsWith(`${boardId}-`)) {
|
|
268
|
+
// Extract the flattened path part after boardId-
|
|
269
|
+
const flattenedPath = docPath.substring(boardId.length + 1);
|
|
270
|
+
fileFullName = `${flattenedPath}.md`;
|
|
271
|
+
filePath = path.join(docsDir, fileFullName);
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
await access(filePath);
|
|
275
|
+
content = await readFile(filePath, "utf8");
|
|
276
|
+
} catch {
|
|
277
|
+
// The file does not exist, content remains undefined
|
|
278
|
+
}
|
|
279
|
+
}
|
|
262
280
|
}
|
|
263
281
|
}
|
|
264
282
|
|
|
@@ -298,9 +316,13 @@ loadSources.input_schema = {
|
|
|
298
316
|
description:
|
|
299
317
|
"Whether to use default include/exclude patterns. Defaults to true.",
|
|
300
318
|
},
|
|
301
|
-
|
|
319
|
+
"doc-path": {
|
|
320
|
+
type: "string",
|
|
321
|
+
description: "The document path to load content for",
|
|
322
|
+
},
|
|
323
|
+
boardId: {
|
|
302
324
|
type: "string",
|
|
303
|
-
description: "The
|
|
325
|
+
description: "The board ID for boardId-flattenedPath format matching",
|
|
304
326
|
},
|
|
305
327
|
},
|
|
306
328
|
required: [],
|
package/aigne.yaml
CHANGED
|
@@ -29,3 +29,15 @@ agents:
|
|
|
29
29
|
- ./agents/load-config.mjs
|
|
30
30
|
- ./agents/team-publish-docs.yaml
|
|
31
31
|
- ./agents/find-item-by-path.mjs
|
|
32
|
+
mcp_server:
|
|
33
|
+
agents:
|
|
34
|
+
- ./agents/input-generator.mjs
|
|
35
|
+
- ./agents/docs-generator.yaml
|
|
36
|
+
- ./agents/detail-regenerator.yaml
|
|
37
|
+
- ./agents/publish-docs.mjs
|
|
38
|
+
cli:
|
|
39
|
+
agents:
|
|
40
|
+
- ./agents/input-generator.mjs
|
|
41
|
+
- ./agents/docs-generator.yaml
|
|
42
|
+
- ./agents/detail-regenerator.yaml
|
|
43
|
+
- ./agents/publish-docs.mjs
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
|
-
const docsDir =
|
|
5
|
-
"/Users/lban/arcblock/code/arcblock-sdk-docs/packages/aigne-framework/docs/";
|
|
4
|
+
const docsDir = path.join(process.cwd(), "doc-smith", "docs");
|
|
6
5
|
|
|
7
6
|
export default async function getDocDetail({ path: docPath }) {
|
|
8
7
|
try {
|
|
@@ -39,4 +38,4 @@ getDocDetail.input_schema = {
|
|
|
39
38
|
},
|
|
40
39
|
};
|
|
41
40
|
|
|
42
|
-
getDocDetail.description = "Get
|
|
41
|
+
getDocDetail.description = "Get single docs detail";
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
|
|
3
|
-
const structureDir =
|
|
4
|
-
|
|
4
|
+
const structureDir = path.join(
|
|
5
|
+
process.cwd(),
|
|
6
|
+
"doc-smith",
|
|
7
|
+
"output",
|
|
8
|
+
"structure-plan.json"
|
|
9
|
+
);
|
|
5
10
|
|
|
6
11
|
export default async function getDocsStructure() {
|
|
7
12
|
const structure = await fs.readFile(structureDir, "utf-8");
|
|
8
13
|
return { structure };
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
getDocsStructure.description = "Get
|
|
16
|
+
getDocsStructure.description = "Get docs structure";
|
package/package.json
CHANGED
|
@@ -13,16 +13,18 @@
|
|
|
13
13
|
{{ structurePlan }}
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
-
|
|
16
|
+
- **用户反馈**:
|
|
17
17
|
```
|
|
18
|
-
{{
|
|
18
|
+
{{ feedback }}
|
|
19
|
+
|
|
20
|
+
根据最新的 Data Sources 按需要更新节点的 sourceIds ,更新至状态。
|
|
19
21
|
```
|
|
20
22
|
</context>
|
|
21
23
|
|
|
22
24
|
<goal>
|
|
23
25
|
你的主要目标是验证两条关键规则:
|
|
24
26
|
1. **反馈的实现**:新的结构规划**必须**正确地实现用户反馈中要求的所有变更。
|
|
25
|
-
2.
|
|
27
|
+
2. **无关节点的稳定性**:没有在用户反馈中被提及的节点 ** path 属性不能被修改 **。`path` 是关联现有内容的关键标识符,其稳定性至关重要。
|
|
26
28
|
3. **数据有效性**: 所有 {{ nodeName }} 都有关联数据源,sourceIds 中都有值。
|
|
27
29
|
</goal>
|
|
28
30
|
|
|
@@ -35,12 +37,12 @@
|
|
|
35
37
|
这是主要场景。你必须执行详细的比较。
|
|
36
38
|
|
|
37
39
|
**分步分析**:
|
|
38
|
-
1. **分析反馈**:仔细阅读并理解 `<context>` 中
|
|
40
|
+
1. **分析反馈**:仔细阅读并理解 `<context>` 中 用户反馈 提出的每一项变更要求。明确哪些节点是需要被修改、添加或删除的目标。
|
|
39
41
|
2. **验证反馈的实现**:对比 `<context>` 中的 `structurePlan` 和 `originalStructurePlan`,确认所要求的变更是否已执行。例如,如果反馈是“移除‘示例’部分”,你必须检查该部分在 `structurePlan` 中是否已不存在。
|
|
40
42
|
3. **验证无关节点的稳定性**:这是最关键的检查。遍历 `structurePlan` 中的所有节点。对于每一个在 `originalStructurePlan` 中也存在、但并未在反馈中被提及的节点:
|
|
41
43
|
* **至关重要**:其 `path` 属性**必须**与 `originalStructurePlan` 中的完全相同。
|
|
42
44
|
* 理想情况下,其他属性(如 `title`)也应保持稳定,除非这些变更是由某个被要求的变更直接导致的。
|
|
43
|
-
|
|
45
|
+
4. **`sourcesIds` 是允许变更的**,每次结构规划可以根据最新的 DataSources 变更依赖的数据源,sourceIds 不能为空。
|
|
44
46
|
</rules>
|
|
45
47
|
|
|
46
48
|
<output>
|