@aigne/doc-smith 0.8.15-beta.7 → 0.8.15-beta.9

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 (44) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/agents/evaluate/index.yaml +1 -3
  3. package/agents/generate/check-diagram.mjs +1 -1
  4. package/agents/generate/check-need-generate-structure.mjs +2 -7
  5. package/agents/generate/generate-structure.yaml +117 -65
  6. package/agents/generate/index.yaml +1 -2
  7. package/agents/generate/{merge-d2-diagram.yaml → merge-diagram.yaml} +7 -6
  8. package/agents/generate/update-document-structure.yaml +1 -1
  9. package/agents/generate/user-review-document-structure.mjs +1 -0
  10. package/agents/generate/utils/merge-document-structures.mjs +30 -0
  11. package/agents/schema/document-structure-item.yaml +23 -0
  12. package/agents/schema/document-structure-refine-item.yaml +20 -0
  13. package/agents/schema/document-structure.yaml +1 -3
  14. package/agents/update/batch-generate-document.yaml +1 -1
  15. package/agents/update/check-generate-diagram.mjs +26 -0
  16. package/agents/update/generate-diagram.yaml +0 -1
  17. package/agents/update/generate-document.yaml +17 -5
  18. package/agents/update/handle-document-update.yaml +8 -0
  19. package/agents/update/update-document-detail.yaml +2 -2
  20. package/agents/update/update-single-document.yaml +0 -1
  21. package/agents/update/user-review-document.mjs +6 -5
  22. package/agents/utils/load-sources.mjs +53 -13
  23. package/agents/utils/transform-detail-datasources.mjs +3 -3
  24. package/aigne.yaml +9 -4
  25. package/package.json +2 -1
  26. package/prompts/common/document/content-rules-core.md +4 -4
  27. package/prompts/common/document/openapi-usage-rules.md +36 -0
  28. package/prompts/common/document/role-and-personality.md +1 -2
  29. package/prompts/detail/d2-diagram/rules.md +11 -14
  30. package/prompts/detail/d2-diagram/system-prompt.md +0 -14
  31. package/prompts/detail/d2-diagram/user-prompt.md +30 -1
  32. package/prompts/detail/generate/document-rules.md +1 -1
  33. package/prompts/detail/generate/system-prompt.md +0 -6
  34. package/prompts/detail/generate/user-prompt.md +13 -60
  35. package/prompts/detail/update/system-prompt.md +0 -6
  36. package/prompts/detail/update/user-prompt.md +3 -3
  37. package/prompts/structure/generate/system-prompt.md +0 -30
  38. package/prompts/structure/generate/user-prompt.md +66 -27
  39. package/prompts/structure/review/structure-review-system.md +78 -0
  40. package/types/document-structure-schema.mjs +3 -3
  41. package/utils/extract-api.mjs +32 -0
  42. package/utils/file-utils.mjs +14 -87
  43. package/agents/generate/document-structure-tools/generate-sub-structure.mjs +0 -131
  44. package/agents/generate/generate-structure-without-tools.yaml +0 -65
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.15-beta.9](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.15-beta.8...v0.8.15-beta.9) (2025-11-03)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * optimize the draw diagram process ([#234](https://github.com/AIGNE-io/aigne-doc-smith/issues/234)) ([7bdc0d9](https://github.com/AIGNE-io/aigne-doc-smith/commit/7bdc0d939df05b9d31e06ea0f0285ed0eafe74ae))
9
+ * simplify document structure merging and add deletion support ([#235](https://github.com/AIGNE-io/aigne-doc-smith/issues/235)) ([7f10242](https://github.com/AIGNE-io/aigne-doc-smith/commit/7f1024294bde241f41034d3e01a542451030cbdc))
10
+
11
+ ## [0.8.15-beta.8](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.15-beta.7...v0.8.15-beta.8) (2025-11-01)
12
+
13
+
14
+ ### Features
15
+
16
+ * smarter structure generation with team-based architecture ([#225](https://github.com/AIGNE-io/aigne-doc-smith/issues/225)) ([eb3404a](https://github.com/AIGNE-io/aigne-doc-smith/commit/eb3404a8889364912a077e84688cfcd48d69ef47))
17
+
3
18
  ## [0.8.15-beta.7](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.15-beta.6...v0.8.15-beta.7) (2025-10-31)
4
19
 
5
20
 
@@ -16,9 +16,7 @@ skills:
16
16
  $merge([
17
17
  $,
18
18
  {
19
- "documentStructure": originalDocumentStructure,
20
- "datasources": "",
21
- "datasourcesList": ""
19
+ "documentStructure": originalDocumentStructure
22
20
  }
23
21
  ])
24
22
  - ./document-structure.yaml
@@ -9,7 +9,7 @@ export default async function checkD2DiagramIsValid({ diagramSourceCode }) {
9
9
  } catch (err) {
10
10
  return {
11
11
  isValid: false,
12
- error: err.message,
12
+ diagramError: err.message,
13
13
  };
14
14
  }
15
15
  }
@@ -3,7 +3,7 @@ import { getActiveRulesForScope } from "../../utils/preferences-utils.mjs";
3
3
  import { getProjectInfo, loadConfigFromFile, saveValueToConfig } from "../../utils/utils.mjs";
4
4
 
5
5
  export default async function checkNeedGenerateStructure(
6
- { originalDocumentStructure, forceRegenerate, isLargeContext, ...rest },
6
+ { originalDocumentStructure, forceRegenerate, ...rest },
7
7
  options,
8
8
  ) {
9
9
  // Check if originalDocumentStructure is empty and prompt user
@@ -53,11 +53,7 @@ export default async function checkNeedGenerateStructure(
53
53
  };
54
54
  }
55
55
 
56
- // Performance optimization: Using both structured output and tools with the Gemini model can cause redundant calls.
57
- // Only use tools when the context is very large.
58
- const generateStructureAgent = isLargeContext
59
- ? options.context.agents["generateStructure"]
60
- : options.context.agents["generateStructureWithoutTools"];
56
+ const generateStructureAgent = options.context.agents["generateStructure"];
61
57
 
62
58
  const structureRules = getActiveRulesForScope("structure", []);
63
59
  const globalRules = getActiveRulesForScope("global", []);
@@ -72,7 +68,6 @@ export default async function checkNeedGenerateStructure(
72
68
  originalDocumentStructure,
73
69
  userPreferences,
74
70
  feedback: finalFeedback || "",
75
- isLargeContext,
76
71
  });
77
72
 
78
73
  let message = "";
@@ -1,68 +1,120 @@
1
+ type: team
1
2
  name: generateStructure
2
3
  description: Generate the structure and organization of your documentation
3
- instructions:
4
- - role: system
5
- url: ../../prompts/structure/generate/system-prompt.md
6
- - role: user
7
- url: ../../prompts/structure/generate/user-prompt.md
8
4
  skills:
9
- - ./document-structure-tools/generate-sub-structure.mjs
10
- task_render_mode: collapse
11
- task_title: Generate the structure of the documentation
12
- tool_calls_concurrency: 5
13
- input_schema:
14
- type: object
15
- properties:
16
- rules:
17
- type: string
18
- description: Your specific requirements for documentation structure
19
- locale:
20
- type: string
21
- description: Primary language for documentation (e.g., zh, en, ja)
22
- datasources:
23
- type: string
24
- description: Project content and context to help generate documentation structure
25
- targetAudience:
26
- type: string
27
- description: Target audience for the documentation
28
- nodeName:
29
- type: string
30
- description: Specific section or page name to focus on
31
- glossary:
32
- type: string
33
- description: Glossary for consistent terminology
34
- feedback:
35
- type: string
36
- description: Tell us how to improve the documentation structure
37
- userPreferences:
38
- type: string
39
- description: Your saved preferences for structure and documentation style
40
- docsType:
41
- type: string
42
- description: "Documentation type (options: general, getting-started, reference, faq)"
43
- default: general
44
- required:
45
- - rules
46
- - datasources
47
- output_schema:
48
- type: object
49
- properties:
50
- projectName:
51
- type: string
52
- description: Project name identified from your content sources
53
- projectDesc:
54
- type: string
55
- description: Brief project description generated from content analysis (under 50 words)
56
- documentStructure: ../schema/document-structure.yaml
57
- documentStructureTree:
58
- type: string
59
- description: |
60
- Visual tree structure showing documentation hierarchy with indented levels for easy review:
61
- ```
62
- - Home
63
- - Getting Started
64
- - Installation
65
- - Requirements
66
- ```
67
- required:
68
- - documentStructure
5
+ - type: team
6
+ name: generateStructureWorker
7
+ iterate_on: datasources
8
+ skills:
9
+ - type: ai
10
+ model:
11
+ reasoning_effort: 500
12
+ instructions:
13
+ - role: system
14
+ url: ../../prompts/structure/generate/system-prompt.md
15
+ - role: user
16
+ url: ../../prompts/structure/generate/user-prompt.md
17
+ task_render_mode: collapse
18
+ task_title: Generate the structure of the documentation
19
+ tool_calls_concurrency: 5
20
+ input_schema:
21
+ type: object
22
+ properties:
23
+ rules:
24
+ type: string
25
+ description: Your specific requirements for documentation structure
26
+ locale:
27
+ type: string
28
+ description: Primary language for documentation (e.g., zh, en, ja)
29
+ dataSourceChunk:
30
+ type: string
31
+ description: Project content and context to help generate documentation structure
32
+ targetAudience:
33
+ type: string
34
+ description: Target audience for the documentation
35
+ nodeName:
36
+ type: string
37
+ description: Specific section or page name to focus on
38
+ glossary:
39
+ type: string
40
+ description: Glossary for consistent terminology
41
+ feedback:
42
+ type: string
43
+ description: Tell us how to improve the documentation structure
44
+ userPreferences:
45
+ type: string
46
+ description: Your saved preferences for structure and documentation style
47
+ docsType:
48
+ type: string
49
+ description: "Documentation type (options: general, getting-started, reference, faq)"
50
+ default: general
51
+ required:
52
+ - rules
53
+ - dataSourceChunk
54
+ output_schema:
55
+ type: object
56
+ properties:
57
+ projectName:
58
+ type: string
59
+ description: Project name identified from your content sources
60
+ projectDesc:
61
+ type: string
62
+ description: Brief project description generated from content analysis (under 50 words)
63
+ structures:
64
+ type: array
65
+ description: List of document structure items to add or update
66
+ items: ../schema/document-structure-item.yaml
67
+
68
+ - ./utils/merge-document-structures.mjs
69
+
70
+ - type: function
71
+ name: aggregateDocumentStructure
72
+ process: |
73
+ return {
74
+ documentStructure: options.context.userContext.originalDocumentStructure.map((i, index) => ({
75
+ ...i,
76
+ id: i.title.toLowerCase().replace(/\s+/g, '-'),
77
+ index
78
+ })),
79
+ projectName: options.context.userContext.projectName,
80
+ projectDesc: options.context.userContext.projectDesc,
81
+ }
82
+
83
+ - type: ai
84
+ name: refineStructure
85
+ model:
86
+ reasoning_effort: 500
87
+ instructions:
88
+ - role: system
89
+ url: ../../prompts/structure/review/structure-review-system.md
90
+ output_schema:
91
+ type: object
92
+ properties:
93
+ structures:
94
+ type: array
95
+ description: Document structure items that need to be updated or changed
96
+ items: ../schema/document-structure-refine-item.yaml
97
+ required:
98
+ - structures
99
+
100
+ - type: function
101
+ name: finalizeDocumentStructure
102
+ process: |
103
+ return {
104
+ projectName: input.projectName,
105
+ projectDesc: input.projectDesc,
106
+ documentStructure: input.structures.map(refinedItem => {
107
+ // Find original item to get sourceIds and other fields
108
+ const originalItem = input.documentStructure.find(orig => orig.id === refinedItem.id)
109
+
110
+ const newItem = {
111
+ title: refinedItem.title,
112
+ description: refinedItem.description,
113
+ path: refinedItem.path,
114
+ parentId: refinedItem.parentPath || null, // Convert parentPath to parentId
115
+ sourceIds: originalItem?.sourceIds || [],
116
+ }
117
+
118
+ return newItem
119
+ })
120
+ }
@@ -38,8 +38,7 @@ skills:
38
38
  'translates': [$map(translateLanguages, function($lang) { {"language": $lang} })]
39
39
  }
40
40
  ])
41
- }),
42
- "datasources": ""
41
+ })
43
42
  }
44
43
  ])
45
44
  - ../utils/format-document-structure.mjs
@@ -1,14 +1,15 @@
1
- name: mergeD2DiagramToDocument
2
- description: Merge D2 Diagram source code into document
1
+ name: mergeDiagramToDocument
2
+ description: Merge Diagram source code into document
3
3
  instructions: |
4
4
  You are an AI assistant that helps to merge d2 diagram into document.
5
5
 
6
- <datasources>
6
+ <detail_dataSource>
7
7
  {{ content }}
8
- </datasources>
9
- <datasources>
8
+ </detail_dataSource>
9
+
10
+ <diagramSourceCode>
10
11
  {{ diagramSourceCode }}
11
- </datasources>
12
+ </diagramSourceCode>
12
13
 
13
14
  Given the source content of a document and the D2 diagram source code, your task is to:
14
15
  - **Keep the original content as soon as possible.**
@@ -16,7 +16,7 @@ input_schema:
16
16
  locale:
17
17
  type: string
18
18
  description: User language, e.g. zh, en
19
- datasources:
19
+ dataSourceChunk:
20
20
  type: string
21
21
  description: Context for documentation structure
22
22
  glossary:
@@ -140,6 +140,7 @@ export default async function userReviewDocumentStructure({ documentStructure, .
140
140
  // Call refineDocumentStructure agent with feedback
141
141
  await options.context.invoke(refineAgent, {
142
142
  ...rest,
143
+ dataSourceChunk: rest.datasources[0].dataSourceChunk,
143
144
  feedback: feedback.trim(),
144
145
  documentStructure: currentStructure,
145
146
  userPreferences,
@@ -0,0 +1,30 @@
1
+ export default async function mergeDocumentStructures(input, options) {
2
+ if (input.projectName) {
3
+ options.context.userContext.projectName = input.projectName;
4
+ }
5
+ if (input.projectDesc) {
6
+ options.context.userContext.projectDesc = input.projectDesc;
7
+ }
8
+
9
+ input.projectName = options.context.userContext.projectName;
10
+ input.projectDesc = options.context.userContext.projectDesc;
11
+
12
+ options.context.userContext.originalDocumentStructure ??= [];
13
+
14
+ const originalStructures = options.context.userContext.originalDocumentStructure;
15
+
16
+ if (input.structures) {
17
+ for (const item of input.structures) {
18
+ const old = originalStructures.find((s) => s.path === item.path);
19
+ if (old) {
20
+ Object.assign(old, item);
21
+ } else {
22
+ originalStructures.push(item);
23
+ }
24
+ }
25
+ }
26
+
27
+ options.context.userContext.originalDocumentStructure = originalStructures;
28
+
29
+ return {};
30
+ }
@@ -0,0 +1,23 @@
1
+ type: object
2
+ description: Document structure item representing a node in the document hierarchy
3
+ properties:
4
+ title:
5
+ type: string
6
+ description:
7
+ type: string
8
+ path:
9
+ type: string
10
+ description: Path in URL format, cannot be empty, cannot contain spaces or special characters, must start with /, no need to include language level, e.g., /zh/about should return /about
11
+ parentPath:
12
+ type: string
13
+ description: Parent node path, if null indicates it is a top-level node
14
+ sourceIds:
15
+ type: array
16
+ description: Associated sourceId from dataSources for subsequent translation and content generation, must come from sourceId in datasources, cannot have fake ids, **cannot be empty**
17
+ items:
18
+ type: string
19
+ required:
20
+ - title
21
+ - description
22
+ - path
23
+ - sourceIds
@@ -0,0 +1,20 @@
1
+ type: object
2
+ description: Document structure item representing a node in the document hierarchy
3
+ properties:
4
+ id:
5
+ type: string
6
+ description: Unique identifier for the document structure item
7
+ title:
8
+ type: string
9
+ description:
10
+ type: string
11
+ path:
12
+ type: string
13
+ description: Path in URL format, cannot be empty, cannot contain spaces or special characters, must start with /, no need to include language level, e.g., /zh/about should return /about
14
+ parentPath:
15
+ type: string
16
+ description: Parent node path, if null indicates it is a top-level node
17
+ required:
18
+ - title
19
+ - description
20
+ - path
@@ -10,9 +10,7 @@ items:
10
10
  type: string
11
11
  description: Path in URL format, cannot be empty, cannot contain spaces or special characters, must start with /, no need to include language level, e.g., /zh/about should return /about
12
12
  parentId:
13
- type:
14
- - string
15
- - "null"
13
+ type: string
16
14
  description: Parent node path, if null indicates it is a top-level node
17
15
  sourceIds:
18
16
  type: array
@@ -6,7 +6,7 @@ skills:
6
6
  input_schema:
7
7
  type: object
8
8
  properties:
9
- datasources:
9
+ detailDataSource:
10
10
  type: string
11
11
  description: Context for documentation structure generation, used to assist generate documentation structure
12
12
  documentExecutionStructure: ../schema/document-execution-structure.yaml
@@ -0,0 +1,26 @@
1
+ const placeholder = "DIAGRAM_PLACEHOLDER";
2
+
3
+ export default async function checkGenerateDiagram(
4
+ { needDiagram, documentContent, locale },
5
+ options,
6
+ ) {
7
+ if (!needDiagram) {
8
+ return {};
9
+ }
10
+
11
+ const generateAgent = options.context?.agents?.["generateDiagram"];
12
+ let content = documentContent;
13
+
14
+ try {
15
+ const { diagramSourceCode } = await options.context.invoke(generateAgent, {
16
+ documentContent,
17
+ locale,
18
+ });
19
+ content = content.replace(placeholder, diagramSourceCode);
20
+ } catch (error) {
21
+ // FIXME: @zhanghan should regenerate document without diagram
22
+ content = content.replace(placeholder, "");
23
+ console.log(`⚠️ Skip generate any diagram: ${error.message}`);
24
+ }
25
+ return { content };
26
+ }
@@ -9,7 +9,6 @@ reflection:
9
9
  is_approved: isValid
10
10
  max_iterations: 5
11
11
  return_last_on_max_iterations: false
12
- custom_error_message: "MUST NOT generate any diagram: validation failed after max iterations."
13
12
  input_schema:
14
13
  type: object
15
14
  properties:
@@ -16,7 +16,7 @@ input_schema:
16
16
  locale:
17
17
  type: string
18
18
  description: User language, such as zh, en
19
- datasources:
19
+ detailDataSource:
20
20
  type: string
21
21
  description: Source data and context for document content generation
22
22
  targetAudience:
@@ -44,9 +44,21 @@ input_schema:
44
44
  description: Additional supplementary information
45
45
  required:
46
46
  - rules
47
- - datasources
47
+ - detailDataSource
48
48
  - originalDocumentStructure
49
- output_key: content
49
+ # output_key: content
50
+ output_schema:
51
+ type: object
52
+ properties:
53
+ content:
54
+ type: string
55
+ description: Document content
56
+ needDiagram:
57
+ type: boolean
58
+ description: Does this document need to generate diagram?
59
+ required:
60
+ - content
61
+ - detailDataSource
50
62
  afs:
51
63
  modules:
52
64
  - module: system-fs
@@ -57,5 +69,5 @@ afs:
57
69
  Codebase of the project to be documented used as context for document generation,
58
70
  should search and read as needed while generating document content
59
71
  keep_text_in_tool_uses: false
60
- skills:
61
- - ./generate-diagram.yaml
72
+ # skills:
73
+ # - ./generate-diagram.yaml
@@ -23,6 +23,14 @@ skills:
23
23
  max_iterations: 5
24
24
  return_last_on_max_iterations: true
25
25
  task_title: Generate document for '{{ title }}'
26
+ - type: transform
27
+ jsonata: |
28
+ $merge([
29
+ $,
30
+ { "documentContent": content }
31
+ ])
32
+ - ./check-generate-diagram.mjs
33
+ # - ../generate/merge-diagram.yaml
26
34
  - ../utils/save-doc.mjs
27
35
  input_schema:
28
36
  type: object
@@ -23,7 +23,7 @@ input_schema:
23
23
  locale:
24
24
  type: string
25
25
  description: User language, e.g. zh, en
26
- datasources:
26
+ detailDataSource:
27
27
  type: string
28
28
  description: Context for document content
29
29
  glossary:
@@ -57,5 +57,5 @@ afs:
57
57
  keep_text_in_tool_uses: false
58
58
  skills:
59
59
  - ./document-tools/update-document-content.mjs
60
- - ./generate-diagram.yaml
60
+ # - ./generate-diagram.yaml
61
61
  task_render_mode: collapse
@@ -3,6 +3,5 @@ name: updateSingleDocument
3
3
  skills:
4
4
  - ../utils/transform-detail-datasources.mjs
5
5
  - ../update/user-review-document.mjs
6
- - ../utils/save-doc.mjs
7
6
  iterate_on: selectedDocs
8
7
  concurrency: 1
@@ -105,6 +105,7 @@ async function showDocumentDetail(content, title) {
105
105
  renderer: new markedTerminal(),
106
106
  });
107
107
 
108
+ // FIXME: @zhanghan fix error "Could not find the language 'd2', did you forget to load/include a language module?"
108
109
  const renderedMarkdown = marked(content);
109
110
 
110
111
  // Restore original console.error
@@ -121,16 +122,15 @@ async function showDocumentDetail(content, title) {
121
122
  }
122
123
  }
123
124
 
124
- export default async function userReviewDocument(
125
- { content, title, description, ...rest },
126
- options,
127
- ) {
125
+ export default async function userReviewDocument({ content, description, ...rest }, options) {
128
126
  // Check if document content exists
129
127
  if (!content || typeof content !== "string" || content.trim().length === 0) {
130
128
  console.log("Please provide document content to review.");
131
129
  return { content };
132
130
  }
133
131
 
132
+ const title = rest.documentStructure?.find((x) => x.path === rest.path)?.title;
133
+
134
134
  // Print current document headings structure
135
135
  printDocumentHeadings(content, title || "Untitled Document");
136
136
 
@@ -190,7 +190,7 @@ export default async function userReviewDocument(
190
190
  feedbacks.push(feedback.trim());
191
191
 
192
192
  // Get the updateDocument agent
193
- const updateAgent = options.context.agents["updateDocumentDetail"];
193
+ const updateAgent = options.context.agents["handleDocumentUpdate"];
194
194
  if (!updateAgent) {
195
195
  console.log(
196
196
  "We can't process your feedback right now. The document update feature is temporarily unavailable.",
@@ -213,6 +213,7 @@ export default async function userReviewDocument(
213
213
  originalContent: options.context.userContext.currentContent,
214
214
  feedback: feedback.trim(),
215
215
  userPreferences,
216
+ title,
216
217
  });
217
218
 
218
219
  // Check if feedback should be saved as user preference