@aigne/doc-smith 0.8.12-beta → 0.8.12-beta.2
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/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +20 -0
- package/agents/generate/check-diagram.mjs +40 -0
- package/agents/generate/draw-diagram.yaml +23 -0
- package/agents/generate/generate-structure.yaml +5 -1
- package/agents/generate/merge-d2-diagram.yaml +3 -3
- package/agents/generate/update-document-structure.yaml +5 -2
- package/agents/generate/user-review-document-structure.mjs +7 -0
- package/agents/generate/wrap-diagram-code.mjs +35 -0
- package/agents/history/index.yaml +6 -0
- package/agents/history/view.mjs +75 -0
- package/agents/translate/index.yaml +3 -2
- package/agents/translate/record-translation-history.mjs +19 -0
- package/agents/translate/translate-multilingual.yaml +2 -1
- package/agents/update/batch-update-document.yaml +1 -1
- package/agents/update/check-document.mjs +5 -1
- package/agents/update/generate-document.yaml +31 -25
- package/agents/update/{generate-and-translate-document.yaml → handle-document-update.yaml} +2 -11
- package/agents/update/index.yaml +1 -0
- package/agents/update/save-and-translate-document.mjs +106 -0
- package/agents/update/update-document-detail.yaml +5 -1
- package/agents/update/update-single-document.yaml +1 -10
- package/agents/update/user-review-document.mjs +10 -1
- package/aigne.yaml +8 -1
- package/package.json +1 -1
- package/prompts/detail/d2-diagram/guide.md +19 -0
- package/prompts/detail/d2-diagram/role-and-personality.md +2 -0
- package/prompts/detail/d2-diagram/rules.md +24 -0
- package/prompts/detail/d2-diagram/{rules-system.md → system-prompt.md} +3 -9
- package/prompts/detail/{document-rules.md → generate/document-rules.md} +1 -1
- package/prompts/detail/generate/system-prompt.md +72 -0
- package/prompts/detail/generate/user-prompt.md +54 -0
- package/prompts/detail/{update-document.md → update/system-prompt.md} +43 -67
- package/prompts/detail/update/user-prompt.md +33 -0
- package/prompts/structure/{generate-structure-system.md → generate/system-prompt.md} +7 -40
- package/prompts/structure/{generate-structure-user.md → generate/user-prompt.md} +17 -13
- package/prompts/structure/{update-document-structure.md → update/system-prompt.md} +16 -27
- package/prompts/structure/update/user-prompt.md +19 -0
- package/tests/agents/generate/user-review-document-structure.test.mjs +2 -0
- package/tests/agents/update/check-document.test.mjs +1 -1
- package/tests/agents/update/save-and-translate-document.test.mjs +369 -0
- package/tests/agents/utils/check-detail-result.test.mjs +13 -0
- package/tests/utils/d2-utils.test.mjs +14 -0
- package/tests/utils/docs-finder-utils.test.mjs +13 -0
- package/tests/utils/history-utils.test.mjs +178 -0
- package/utils/d2-utils.mjs +9 -0
- package/utils/docs-finder-utils.mjs +10 -1
- package/utils/history-utils.mjs +191 -0
- package/utils/markdown-checker.mjs +20 -0
- package/agents/generate/check-d2-diagram-valid.mjs +0 -26
- package/agents/generate/generate-d2-diagram.yaml +0 -23
- package/prompts/detail/generate-document.md +0 -125
- /package/prompts/detail/d2-diagram/{rules-user.md → user-prompt.md} +0 -0
- /package/prompts/detail/{detail-example.md → generate/detail-example.md} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.12-beta.2](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.12-beta.1...v0.8.12-beta.2) (2025-10-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* fix update document include path ([#166](https://github.com/AIGNE-io/aigne-doc-smith/issues/166)) ([40c3aa2](https://github.com/AIGNE-io/aigne-doc-smith/commit/40c3aa2739cb35d36fb1daed87a0e23c81285328))
|
|
9
|
+
* resolve failure in document update and generate ([#168](https://github.com/AIGNE-io/aigne-doc-smith/issues/168)) ([c00c759](https://github.com/AIGNE-io/aigne-doc-smith/commit/c00c759473a01ce3d16b89f2bfa974f43420b82a))
|
|
10
|
+
|
|
11
|
+
## [0.8.12-beta.1](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.12-beta...v0.8.12-beta.1) (2025-10-08)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* add history tracking and make translation optional during update ([#165](https://github.com/AIGNE-io/aigne-doc-smith/issues/165)) ([e1d3d97](https://github.com/AIGNE-io/aigne-doc-smith/commit/e1d3d97c7e57c1c663c0478870aab7421de9d4bc))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* split generate/update document & structure to system & user ([#159](https://github.com/AIGNE-io/aigne-doc-smith/issues/159)) ([ad1802d](https://github.com/AIGNE-io/aigne-doc-smith/commit/ad1802d1aecefc414ab3d1217a9ba31655479e86))
|
|
22
|
+
|
|
3
23
|
## [0.8.12-beta](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.8.11...v0.8.12-beta) (2025-10-07)
|
|
4
24
|
|
|
5
25
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { checkContent } from "../../utils/d2-utils.mjs";
|
|
2
|
+
|
|
3
|
+
export default async function checkD2DiagramIsValid({ diagramSourceCode }) {
|
|
4
|
+
try {
|
|
5
|
+
await checkContent({ content: diagramSourceCode });
|
|
6
|
+
return {
|
|
7
|
+
isValid: true,
|
|
8
|
+
};
|
|
9
|
+
} catch (err) {
|
|
10
|
+
return {
|
|
11
|
+
isValid: false,
|
|
12
|
+
error: err.message,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
checkD2DiagramIsValid.input_schema = {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
diagramSourceCode: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Source code of d2 diagram",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ["diagramSourceCode"],
|
|
26
|
+
};
|
|
27
|
+
checkD2DiagramIsValid.output_schema = {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
isValid: {
|
|
31
|
+
type: "boolean",
|
|
32
|
+
description: "Indicates whether the provided d2 diagram source passes validation",
|
|
33
|
+
},
|
|
34
|
+
error: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Validation error details when the diagram does not pass",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["isValid"],
|
|
40
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: drawDiagram
|
|
2
|
+
description: Generate a D2 diagram from document content.
|
|
3
|
+
instructions:
|
|
4
|
+
- role: system
|
|
5
|
+
url: ../../prompts/detail/d2-diagram/system-prompt.md
|
|
6
|
+
- role: user
|
|
7
|
+
url: ../../prompts/detail/d2-diagram/user-prompt.md
|
|
8
|
+
input_schema:
|
|
9
|
+
type: object
|
|
10
|
+
properties:
|
|
11
|
+
documentContent:
|
|
12
|
+
type: string
|
|
13
|
+
description: The **raw text content** of the current document. (**Note:** This is the original document and **does not include** any existing diagram source code.)
|
|
14
|
+
required:
|
|
15
|
+
- documentContent
|
|
16
|
+
output_schema:
|
|
17
|
+
type: object
|
|
18
|
+
properties:
|
|
19
|
+
diagramSourceCode:
|
|
20
|
+
type: string
|
|
21
|
+
description: The **diagram source code** generated from the input text.
|
|
22
|
+
required:
|
|
23
|
+
- diagramSourceCode
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
name: generateStructure
|
|
2
2
|
description: Generate the structure and organization of your documentation
|
|
3
3
|
instructions:
|
|
4
|
-
|
|
4
|
+
- role: system
|
|
5
|
+
url: ../../prompts/structure/generate/system-prompt.md
|
|
6
|
+
- role: user
|
|
7
|
+
url: ../../prompts/structure/generate/user-prompt.md
|
|
8
|
+
|
|
5
9
|
input_schema:
|
|
6
10
|
type: object
|
|
7
11
|
properties:
|
|
@@ -7,7 +7,7 @@ instructions: |
|
|
|
7
7
|
{{ content }}
|
|
8
8
|
</datasources>
|
|
9
9
|
<datasources>
|
|
10
|
-
{{
|
|
10
|
+
{{ diagramSourceCode }}
|
|
11
11
|
</datasources>
|
|
12
12
|
|
|
13
13
|
Given the source content of a document and the D2 diagram source code, your task is to:
|
|
@@ -22,12 +22,12 @@ input_schema:
|
|
|
22
22
|
content:
|
|
23
23
|
type: string
|
|
24
24
|
description: Source content of the document
|
|
25
|
-
|
|
25
|
+
diagramSourceCode:
|
|
26
26
|
type: string
|
|
27
27
|
description: Source content of D2 Diagram
|
|
28
28
|
required:
|
|
29
29
|
- content
|
|
30
|
-
-
|
|
30
|
+
- diagramSourceCode
|
|
31
31
|
output_schema:
|
|
32
32
|
type: object
|
|
33
33
|
properties:
|
|
@@ -2,7 +2,10 @@ type: ai
|
|
|
2
2
|
name: updateDocumentStructure
|
|
3
3
|
description: Update documentation structure based on user feedback and intentions using structure modification tools
|
|
4
4
|
instructions:
|
|
5
|
-
|
|
5
|
+
- role: system
|
|
6
|
+
url: ../../prompts/structure/update/system-prompt.md
|
|
7
|
+
- role: user
|
|
8
|
+
url: ../../prompts/structure/update/user-prompt.md
|
|
6
9
|
input_schema:
|
|
7
10
|
type: object
|
|
8
11
|
properties:
|
|
@@ -33,4 +36,4 @@ skills:
|
|
|
33
36
|
- ./document-structure-tools/add-document.mjs
|
|
34
37
|
- ./document-structure-tools/delete-document.mjs
|
|
35
38
|
- ./document-structure-tools/update-document.mjs
|
|
36
|
-
- ./document-structure-tools/move-document.mjs
|
|
39
|
+
- ./document-structure-tools/move-document.mjs
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getActiveRulesForScope } from "../../utils/preferences-utils.mjs";
|
|
2
|
+
import { recordUpdate } from "../../utils/history-utils.mjs";
|
|
2
3
|
|
|
3
4
|
function formatDocumentStructure(structure) {
|
|
4
5
|
// Build a tree structure for better display
|
|
@@ -158,6 +159,12 @@ export default async function userReviewDocumentStructure({ documentStructure, .
|
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
|
|
162
|
+
// Record update in history
|
|
163
|
+
recordUpdate({
|
|
164
|
+
operation: "structure_update",
|
|
165
|
+
feedback: feedback.trim(),
|
|
166
|
+
});
|
|
167
|
+
|
|
161
168
|
// Print current documentation structure in a user-friendly format
|
|
162
169
|
printDocumentStructure(currentStructure);
|
|
163
170
|
} catch (error) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { wrapCode } from "../../utils/d2-utils.mjs";
|
|
2
|
+
|
|
3
|
+
export default async function wrapDiagramCode({ diagramSourceCode }) {
|
|
4
|
+
try {
|
|
5
|
+
const result = await wrapCode({ content: diagramSourceCode });
|
|
6
|
+
return {
|
|
7
|
+
diagramSourceCode: result,
|
|
8
|
+
};
|
|
9
|
+
} catch {
|
|
10
|
+
return {
|
|
11
|
+
diagramSourceCode,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
wrapDiagramCode.input_schema = {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
diagramSourceCode: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "Source code of d2 diagram",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
required: ["diagramSourceCode"],
|
|
25
|
+
};
|
|
26
|
+
wrapDiagramCode.output_schema = {
|
|
27
|
+
type: "object",
|
|
28
|
+
properties: {
|
|
29
|
+
diagramSourceCode: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Source code of d2 diagram",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
required: ["diagramSourceCode"],
|
|
35
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { getHistory } from "../../utils/history-utils.mjs";
|
|
3
|
+
|
|
4
|
+
export default function viewHistory() {
|
|
5
|
+
const history = getHistory();
|
|
6
|
+
|
|
7
|
+
if (!history.entries || history.entries.length === 0) {
|
|
8
|
+
console.log(chalk.yellow("\nNo update history found\n"));
|
|
9
|
+
return {};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
console.log(chalk.cyan("\n📜 Update History\n"));
|
|
13
|
+
|
|
14
|
+
history.entries.forEach((entry) => {
|
|
15
|
+
// Format: <short-hash> <date> <operation> <feedback>
|
|
16
|
+
const hash = generateShortHash(entry.timestamp);
|
|
17
|
+
const date = formatRelativeDate(entry.timestamp);
|
|
18
|
+
const operation = entry.operation;
|
|
19
|
+
|
|
20
|
+
// Handle document path (now a string)
|
|
21
|
+
const documentInfo = entry.documentPath ? chalk.dim(` (${entry.documentPath})`) : "";
|
|
22
|
+
|
|
23
|
+
// Git-style oneline format
|
|
24
|
+
console.log(
|
|
25
|
+
`${chalk.yellow(hash)} ${chalk.dim(date)} ${chalk.cyan(operation)}${documentInfo}: ${entry.feedback}`,
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
console.log(); // Empty line at end
|
|
30
|
+
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Generate a short hash from timestamp (git-style)
|
|
36
|
+
*/
|
|
37
|
+
function generateShortHash(timestamp) {
|
|
38
|
+
const hash = timestamp.replace(/[-:.TZ]/g, "");
|
|
39
|
+
return hash.substring(hash.length - 7); // Last 7 chars
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Format date in relative time (git-style)
|
|
44
|
+
*/
|
|
45
|
+
function formatRelativeDate(timestamp) {
|
|
46
|
+
const date = new Date(timestamp);
|
|
47
|
+
const now = new Date();
|
|
48
|
+
const diffMs = now - date;
|
|
49
|
+
const diffSecs = Math.floor(diffMs / 1000);
|
|
50
|
+
const diffMins = Math.floor(diffSecs / 60);
|
|
51
|
+
const diffHours = Math.floor(diffMins / 60);
|
|
52
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
53
|
+
|
|
54
|
+
if (diffSecs < 60) {
|
|
55
|
+
return `${diffSecs} seconds ago`;
|
|
56
|
+
}
|
|
57
|
+
if (diffMins < 60) {
|
|
58
|
+
return `${diffMins} minute${diffMins === 1 ? "" : "s"} ago`;
|
|
59
|
+
}
|
|
60
|
+
if (diffHours < 24) {
|
|
61
|
+
return `${diffHours} hour${diffHours === 1 ? "" : "s"} ago`;
|
|
62
|
+
}
|
|
63
|
+
if (diffDays < 7) {
|
|
64
|
+
return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`;
|
|
65
|
+
}
|
|
66
|
+
// Show actual date for older entries
|
|
67
|
+
return date.toLocaleDateString("en-US", {
|
|
68
|
+
month: "short",
|
|
69
|
+
day: "numeric",
|
|
70
|
+
year: date.getFullYear() !== now.getFullYear() ? "numeric" : undefined,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
viewHistory.description = "View update history in compact format";
|
|
75
|
+
viewHistory.taskTitle = "View update history";
|
|
@@ -32,6 +32,7 @@ skills:
|
|
|
32
32
|
name: batchTranslateDocument
|
|
33
33
|
skills:
|
|
34
34
|
- ../translate/translate-multilingual.yaml
|
|
35
|
+
- url: ./record-translation-history.mjs
|
|
35
36
|
- url: ../utils/save-single-doc.mjs
|
|
36
37
|
default_input:
|
|
37
38
|
isTranslate: true
|
|
@@ -42,7 +43,7 @@ skills:
|
|
|
42
43
|
stage: translation_refine
|
|
43
44
|
- url: ../utils/action-success.mjs
|
|
44
45
|
default_input:
|
|
45
|
-
action:
|
|
46
|
+
action: '✅ Translation completed'
|
|
46
47
|
input_schema:
|
|
47
48
|
type: object
|
|
48
49
|
properties:
|
|
@@ -58,7 +59,7 @@ input_schema:
|
|
|
58
59
|
type: array
|
|
59
60
|
items:
|
|
60
61
|
type: string
|
|
61
|
-
description:
|
|
62
|
+
description: 'Target languages (available: en, zh, zh-TW, ja, fr, de, es, it, ru, ko, pt, ar)'
|
|
62
63
|
feedback:
|
|
63
64
|
type: string
|
|
64
65
|
description: Tell us how to improve the translation style
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { recordUpdate } from "../../utils/history-utils.mjs";
|
|
2
|
+
|
|
3
|
+
export default function recordTranslationHistory({ feedback, path }) {
|
|
4
|
+
// Skip if no feedback provided
|
|
5
|
+
if (!feedback?.trim()) {
|
|
6
|
+
return {};
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Record translation history for this document
|
|
10
|
+
recordUpdate({
|
|
11
|
+
operation: "translation_update",
|
|
12
|
+
feedback: feedback.trim(),
|
|
13
|
+
documentPath: path,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
recordTranslationHistory.task_render_mode = "hide";
|
|
@@ -112,7 +112,11 @@ export default async function checkDocument(
|
|
|
112
112
|
|
|
113
113
|
const teamAgent = TeamAgent.from({
|
|
114
114
|
name: "generateDocument",
|
|
115
|
-
skills: [
|
|
115
|
+
skills: [
|
|
116
|
+
options.context.agents["handleDocumentUpdate"],
|
|
117
|
+
options.context.agents["translateMultilingual"],
|
|
118
|
+
options.context.agents["saveSingleDoc"],
|
|
119
|
+
],
|
|
116
120
|
});
|
|
117
121
|
|
|
118
122
|
const result = await options.context.invoke(teamAgent, {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
name: generateDocument
|
|
2
2
|
description: Comprehensive content generator for documentation that creates detailed, high-quality document content from various data sources with intelligent analysis.
|
|
3
3
|
instructions:
|
|
4
|
-
|
|
4
|
+
- role: system
|
|
5
|
+
url: ../../prompts/detail/generate/system-prompt.md
|
|
6
|
+
- role: user
|
|
7
|
+
url: ../../prompts/detail/generate/user-prompt.md
|
|
5
8
|
input_schema:
|
|
6
9
|
type: object
|
|
7
10
|
properties:
|
|
@@ -46,27 +49,30 @@ skills:
|
|
|
46
49
|
- fs-tools/glob.mjs
|
|
47
50
|
- fs-tools/grep.mjs
|
|
48
51
|
- fs-tools/read-file.mjs
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
52
|
+
# FIXME: @zhanghan temporary disable diagram tool
|
|
53
|
+
# - type: team
|
|
54
|
+
# task_render_mode: collapse
|
|
55
|
+
# name: generateDiagram
|
|
56
|
+
# skills:
|
|
57
|
+
# - ../generate/draw-diagram.yaml
|
|
58
|
+
# - ../generate/wrap-diagram-code.mjs
|
|
59
|
+
# reflection:
|
|
60
|
+
# reviewer: ../generate/check-diagram.mjs
|
|
61
|
+
# is_approved: isValid
|
|
62
|
+
# max_iterations: 5
|
|
63
|
+
# return_last_on_max_iterations: false
|
|
64
|
+
# custom_error_message: "MUST NOT generate any diagram: validation failed after max iterations."
|
|
65
|
+
# input_schema:
|
|
66
|
+
# type: object
|
|
67
|
+
# properties:
|
|
68
|
+
# documentContent:
|
|
69
|
+
# type: string
|
|
70
|
+
# description: The **raw text content** of the current document. (**Note:** This is the original document and **does not include** any existing diagram source code.)
|
|
71
|
+
# required:
|
|
72
|
+
# - documentContent
|
|
73
|
+
# output_schema:
|
|
74
|
+
# type: object
|
|
75
|
+
# properties:
|
|
76
|
+
# diagramSourceCode:
|
|
77
|
+
# type: string
|
|
78
|
+
# description: The **diagram source code** generated from the input text.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
type: team
|
|
2
|
-
name:
|
|
3
|
-
description:
|
|
2
|
+
name: handleDocumentUpdate
|
|
3
|
+
description: Update a document in a batch
|
|
4
4
|
skills:
|
|
5
5
|
- ../utils/transform-detail-datasources.mjs
|
|
6
6
|
- type: team
|
|
@@ -23,15 +23,6 @@ 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
|
-
task_render_mode: hide
|
|
28
|
-
jsonata: |
|
|
29
|
-
$merge([
|
|
30
|
-
$,
|
|
31
|
-
{ "feedback": "" }
|
|
32
|
-
])
|
|
33
|
-
- ../translate/translate-multilingual.yaml
|
|
34
|
-
- ../utils/save-single-doc.mjs
|
|
35
26
|
input_schema:
|
|
36
27
|
type: object
|
|
37
28
|
properties:
|
package/agents/update/index.yaml
CHANGED
|
@@ -31,6 +31,7 @@ skills:
|
|
|
31
31
|
requiredFeedback: false
|
|
32
32
|
- ../utils/format-document-structure.mjs
|
|
33
33
|
- ../update/check-update-is-single.mjs
|
|
34
|
+
- ../update/save-and-translate-document.mjs
|
|
34
35
|
- url: ../utils/action-success.mjs
|
|
35
36
|
default_input:
|
|
36
37
|
action: "✅ Documents updated successfully"
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { recordUpdate } from "../../utils/history-utils.mjs";
|
|
2
|
+
|
|
3
|
+
export default async function saveAndTranslateDocument(input, options) {
|
|
4
|
+
const { selectedDocs, docsDir, translateLanguages, locale } = input;
|
|
5
|
+
|
|
6
|
+
if (!Array.isArray(selectedDocs) || selectedDocs.length === 0) {
|
|
7
|
+
return {};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Saves a document with optional translation data
|
|
11
|
+
const saveDocument = async (doc, translates = null, isTranslate = false) => {
|
|
12
|
+
const saveAgent = options.context.agents["saveSingleDoc"];
|
|
13
|
+
|
|
14
|
+
return await options.context.invoke(saveAgent, {
|
|
15
|
+
path: doc.path,
|
|
16
|
+
content: doc.content,
|
|
17
|
+
docsDir: docsDir,
|
|
18
|
+
locale: locale,
|
|
19
|
+
translates: translates || doc.translates,
|
|
20
|
+
labels: doc.labels,
|
|
21
|
+
isTranslate: isTranslate,
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Only prompt user if translation is actually needed
|
|
26
|
+
let shouldTranslate = false;
|
|
27
|
+
if (
|
|
28
|
+
Array.isArray(translateLanguages) &&
|
|
29
|
+
translateLanguages.filter((lang) => lang !== locale).length > 0
|
|
30
|
+
) {
|
|
31
|
+
const choice = await options.prompts.select({
|
|
32
|
+
message: "Document update completed. Would you like to translate these documents now?",
|
|
33
|
+
choices: [
|
|
34
|
+
{
|
|
35
|
+
name: "Review documents first, translate later",
|
|
36
|
+
value: "no",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Translate now",
|
|
40
|
+
value: "yes",
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
shouldTranslate = choice === "yes";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Save documents in batches
|
|
48
|
+
const batchSize = 3;
|
|
49
|
+
for (let i = 0; i < selectedDocs.length; i += batchSize) {
|
|
50
|
+
const batch = selectedDocs.slice(i, i + batchSize);
|
|
51
|
+
|
|
52
|
+
const savePromises = batch.map(async (doc) => {
|
|
53
|
+
try {
|
|
54
|
+
await saveDocument(doc);
|
|
55
|
+
|
|
56
|
+
// Record history for each document if feedback is provided
|
|
57
|
+
if (doc.feedback?.trim()) {
|
|
58
|
+
recordUpdate({
|
|
59
|
+
operation: "document_update",
|
|
60
|
+
feedback: doc.feedback.trim(),
|
|
61
|
+
documentPath: doc.path,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error(`❌ Failed to save document ${doc.path}:`, error.message);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await Promise.all(savePromises);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Return results if user chose to skip translation
|
|
73
|
+
if (!shouldTranslate) {
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Translate documents in batches
|
|
78
|
+
const translateAgent = options.context.agents["translateMultilingual"];
|
|
79
|
+
|
|
80
|
+
for (let i = 0; i < selectedDocs.length; i += batchSize) {
|
|
81
|
+
const batch = selectedDocs.slice(i, i + batchSize);
|
|
82
|
+
|
|
83
|
+
const translatePromises = batch.map(async (doc) => {
|
|
84
|
+
try {
|
|
85
|
+
// Clear feedback to ensure translation is not affected by update feedback
|
|
86
|
+
doc.feedback = "";
|
|
87
|
+
|
|
88
|
+
const result = await options.context.invoke(translateAgent, {
|
|
89
|
+
...input, // context is required
|
|
90
|
+
content: doc.content,
|
|
91
|
+
translates: doc.translates,
|
|
92
|
+
title: doc.title,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Save the translated content
|
|
96
|
+
await saveDocument(doc, result.translates, true);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error(`❌ Failed to translate document ${doc.path}:`, error.message);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
await Promise.all(translatePromises);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {};
|
|
106
|
+
}
|
|
@@ -2,7 +2,11 @@ type: ai
|
|
|
2
2
|
name: updateDocumentDetail
|
|
3
3
|
description: Update and optimize document content based on user feedback using diff patches
|
|
4
4
|
instructions:
|
|
5
|
-
|
|
5
|
+
- role: system
|
|
6
|
+
url: ../../prompts/detail/update/system-prompt.md
|
|
7
|
+
- role: user
|
|
8
|
+
url: ../../prompts/detail/update/user-prompt.md
|
|
9
|
+
|
|
6
10
|
input_schema:
|
|
7
11
|
type: object
|
|
8
12
|
properties:
|
|
@@ -3,14 +3,5 @@ name: updateSingleDocument
|
|
|
3
3
|
skills:
|
|
4
4
|
- ../utils/transform-detail-datasources.mjs
|
|
5
5
|
- ../update/user-review-document.mjs
|
|
6
|
-
- type: transform
|
|
7
|
-
task_render_mode: hide
|
|
8
|
-
jsonata: |
|
|
9
|
-
$merge([
|
|
10
|
-
$,
|
|
11
|
-
{ "feedback": "" }
|
|
12
|
-
])
|
|
13
|
-
- ../translate/translate-multilingual.yaml
|
|
14
|
-
- ../utils/save-single-doc.mjs
|
|
15
6
|
iterate_on: selectedDocs
|
|
16
|
-
concurrency: 1
|
|
7
|
+
concurrency: 1
|
|
@@ -138,6 +138,7 @@ export default async function userReviewDocument(
|
|
|
138
138
|
options.context.userContext.currentContent = content;
|
|
139
139
|
|
|
140
140
|
const MAX_ITERATIONS = 100;
|
|
141
|
+
const feedbacks = [];
|
|
141
142
|
let iterationCount = 0;
|
|
142
143
|
while (iterationCount < MAX_ITERATIONS) {
|
|
143
144
|
iterationCount++;
|
|
@@ -185,6 +186,8 @@ export default async function userReviewDocument(
|
|
|
185
186
|
break;
|
|
186
187
|
}
|
|
187
188
|
|
|
189
|
+
feedbacks.push(feedback.trim());
|
|
190
|
+
|
|
188
191
|
// Get the updateDocument agent
|
|
189
192
|
const updateAgent = options.context.agents["updateDocumentDetail"];
|
|
190
193
|
if (!updateAgent) {
|
|
@@ -242,7 +245,13 @@ export default async function userReviewDocument(
|
|
|
242
245
|
}
|
|
243
246
|
}
|
|
244
247
|
|
|
245
|
-
return {
|
|
248
|
+
return {
|
|
249
|
+
title,
|
|
250
|
+
description,
|
|
251
|
+
...rest,
|
|
252
|
+
content: options.context.userContext.currentContent,
|
|
253
|
+
feedback: feedbacks.join(". "),
|
|
254
|
+
};
|
|
246
255
|
}
|
|
247
256
|
|
|
248
257
|
userReviewDocument.taskTitle = "User review and modify document content";
|
package/aigne.yaml
CHANGED
|
@@ -27,13 +27,14 @@ agents:
|
|
|
27
27
|
# Document Content Generation & Updates
|
|
28
28
|
- ./agents/update/batch-generate-document.yaml
|
|
29
29
|
- ./agents/update/generate-document.yaml
|
|
30
|
-
- ./agents/update/
|
|
30
|
+
- ./agents/update/handle-document-update.yaml
|
|
31
31
|
- ./agents/update/check-document.mjs
|
|
32
32
|
- ./agents/update/update-document-detail.yaml
|
|
33
33
|
- ./agents/update/user-review-document.mjs
|
|
34
34
|
- ./agents/update/batch-update-document.yaml
|
|
35
35
|
- ./agents/update/update-single-document.yaml
|
|
36
36
|
- ./agents/update/check-update-is-single.mjs
|
|
37
|
+
- ./agents/update/save-and-translate-document.mjs
|
|
37
38
|
- ./agents/update/index.yaml
|
|
38
39
|
|
|
39
40
|
|
|
@@ -94,6 +95,12 @@ cli:
|
|
|
94
95
|
- ./agents/clear/index.yaml
|
|
95
96
|
- ./agents/prefs/index.mjs
|
|
96
97
|
- ./agents/evaluate/index.yaml
|
|
98
|
+
- name: history
|
|
99
|
+
description: View update history
|
|
100
|
+
agents:
|
|
101
|
+
- url: ./agents/history/view.mjs
|
|
102
|
+
name: view
|
|
103
|
+
alias: ["log", "list"]
|
|
97
104
|
mcp_server:
|
|
98
105
|
agents:
|
|
99
106
|
- ./docs-mcp/get-docs-structure.mjs
|