@aigne/doc-smith 0.9.10 → 0.9.11-beta
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 +12 -0
- package/README.md +189 -219
- package/README.zh.md +270 -0
- package/agents/bash-executor/index.mjs +347 -0
- package/agents/clear/ai/intent.md +142 -0
- package/agents/clear/choose-contents.mjs +13 -65
- package/agents/clear/clear-auth-tokens.mjs +17 -21
- package/agents/clear/clear-deployment-config.mjs +33 -24
- package/agents/clear/index.yaml +1 -9
- package/agents/content-checker/ai/intent.md +209 -0
- package/agents/content-checker/clean-invalid-docs.mjs +254 -0
- package/agents/content-checker/index.mjs +191 -0
- package/agents/content-checker/validate-content.mjs +983 -0
- package/agents/generate-images/generate-image.yaml +75 -0
- package/agents/generate-images/generate-summary.mjs +213 -0
- package/agents/generate-images/index.yaml +39 -0
- package/agents/generate-images/prepare-generation.mjs +286 -0
- package/agents/generate-images/prepare-image-generation.mjs +130 -0
- package/{prompts/detail/diagram/generate-image-system.md → agents/generate-images/prompts/system.md} +22 -56
- package/agents/generate-images/prompts/user.md +85 -0
- package/agents/generate-images/save-image-result.mjs +247 -0
- package/agents/generate-images/scan-image-slots.mjs +247 -0
- package/agents/localize/index.yaml +19 -42
- package/{prompts/translate → agents/localize/prompts}/translate-document.md +0 -139
- package/agents/localize/translate-documents/generate-summary.mjs +163 -0
- package/agents/localize/translate-documents/load-glossary.mjs +52 -0
- package/agents/localize/translate-documents/prepare-translation.mjs +249 -0
- package/agents/localize/translate-documents/save-translation.mjs +171 -0
- package/agents/localize/translate-documents/translate-document-to-language.mjs +209 -0
- package/agents/localize/translate-documents/translate-document.yaml +23 -0
- package/agents/localize/translate-documents/translate-to-languages.yaml +10 -0
- package/agents/localize/translate-images/check-image-translation.mjs +225 -0
- package/agents/localize/translate-images/detect-text/detect-and-update-shared.mjs +148 -0
- package/agents/localize/translate-images/detect-text/detect-image-text.yaml +44 -0
- package/agents/localize/translate-images/detect-text/detect-images-text.yaml +21 -0
- package/agents/localize/translate-images/detect-text/prompts/detect-image-text-system.md +43 -0
- package/agents/localize/translate-images/detect-text/prompts/detect-image-text-user.md +14 -0
- package/agents/localize/translate-images/detect-text/save-text-detection.mjs +105 -0
- package/agents/localize/translate-images/prepare-image-input.mjs +124 -0
- package/agents/localize/translate-images/save-image-translation.mjs +172 -0
- package/agents/localize/translate-images/scan-doc-images.mjs +165 -0
- package/agents/localize/translate-images/translate-doc-images.yaml +24 -0
- package/agents/localize/{translate-diagram.yaml → translate-images/translate-image.yaml} +25 -14
- package/agents/publish/ai/intent.md +182 -0
- package/agents/publish/check.mjs +107 -0
- package/agents/publish/index.yaml +9 -14
- package/agents/publish/publish-docs.mjs +81 -61
- package/agents/publish/translate-meta.mjs +79 -58
- package/agents/save-document/index.mjs +260 -0
- package/agents/structure-checker/index.mjs +307 -0
- package/agents/structure-checker/validate-structure.mjs +477 -0
- package/agents/update-image/analyze-feedback.yaml +37 -0
- package/agents/update-image/index.yaml +78 -0
- package/agents/update-image/load-existing-image.mjs +211 -0
- package/agents/update-image/prompts/analyze-feedback-system.md +43 -0
- package/agents/update-image/prompts/analyze-feedback-user.md +15 -0
- package/aigne.yaml +26 -139
- package/package.json +16 -48
- package/scripts/README.md +90 -0
- package/scripts/install.sh +86 -0
- package/scripts/uninstall.sh +52 -0
- package/skills/doc-smith/SKILL.md +285 -0
- package/skills/doc-smith/ai/intent/sources-improve.md +290 -0
- package/skills/doc-smith/references/changeset-guide.md +171 -0
- package/skills/doc-smith/references/document-content-guide.md +214 -0
- package/skills/doc-smith/references/document-structure-schema.md +138 -0
- package/skills/doc-smith/references/patch-guide.md +96 -0
- package/skills/doc-smith/references/structure-confirmation-guide.md +133 -0
- package/skills/doc-smith/references/structure-planning-guide.md +149 -0
- package/skills/doc-smith/references/update-workflow.md +108 -0
- package/skills/doc-smith/references/user-intent-guide.md +175 -0
- package/skills/doc-smith/references/workspace-initialization.md +376 -0
- package/skills/doc-smith-docs-detail/SKILL.md +356 -0
- package/skills/doc-smith-docs-detail/ai/intent.md +271 -0
- package/skills-entry/doc-smith/ai/intent.md +260 -0
- package/skills-entry/doc-smith/index.mjs +66 -0
- package/skills-entry/doc-smith/prompt.md +57 -0
- package/skills-entry/doc-smith/utils.mjs +27 -0
- package/skills-entry/doc-smith-docs-detail/batch.yaml +56 -0
- package/skills-entry/doc-smith-docs-detail/index.mjs +95 -0
- package/skills-entry/doc-smith-docs-detail/prompt.md +64 -0
- package/utils/afs-factory.mjs +183 -0
- package/utils/agent-constants.mjs +97 -0
- package/utils/{auth-utils.mjs → auth.mjs} +6 -9
- package/{agents/utils/update-branding.mjs → utils/branding.mjs} +3 -4
- package/utils/config.mjs +261 -0
- package/utils/constants.mjs +32 -0
- package/utils/deploy.mjs +3 -3
- package/utils/docs-converter.mjs +454 -0
- package/utils/docs.mjs +212 -0
- package/utils/document-paths.mjs +172 -0
- package/utils/files.mjs +74 -0
- package/utils/git.mjs +65 -0
- package/utils/{blocklet.mjs → http.mjs} +18 -0
- package/utils/image-slots.mjs +57 -0
- package/utils/image-utils.mjs +114 -0
- package/utils/project.mjs +95 -0
- package/utils/sources-path-resolver.mjs +76 -0
- package/utils/{upload-files.mjs → upload.mjs} +3 -3
- package/utils/workspace.mjs +371 -0
- package/agents/chat/chat-system.md +0 -38
- package/agents/chat/index.mjs +0 -59
- package/agents/chat/skills/generate-document.yaml +0 -15
- package/agents/chat/skills/list-documents.mjs +0 -15
- package/agents/chat/skills/update-document.yaml +0 -24
- package/agents/clear/clear-document-config.mjs +0 -36
- package/agents/clear/clear-document-structure.mjs +0 -102
- package/agents/clear/clear-generated-docs.mjs +0 -142
- package/agents/clear/clear-media-description.mjs +0 -129
- package/agents/create/aggregate-document-structure.mjs +0 -21
- package/agents/create/analyze-diagram-type-llm.yaml +0 -159
- package/agents/create/analyze-diagram-type.mjs +0 -455
- package/agents/create/check-document-structure.yaml +0 -30
- package/agents/create/check-need-generate-structure.mjs +0 -138
- package/agents/create/document-structure-tools/add-document.mjs +0 -85
- package/agents/create/document-structure-tools/delete-document.mjs +0 -116
- package/agents/create/document-structure-tools/move-document.mjs +0 -109
- package/agents/create/document-structure-tools/update-document.mjs +0 -84
- package/agents/create/generate-diagram-image.yaml +0 -91
- package/agents/create/generate-structure.yaml +0 -106
- package/agents/create/index.yaml +0 -45
- package/agents/create/refine-document-structure.yaml +0 -12
- package/agents/create/replace-d2-with-image.mjs +0 -610
- package/agents/create/update-document-structure.yaml +0 -54
- package/agents/create/user-add-document/add-documents-to-structure.mjs +0 -90
- package/agents/create/user-add-document/find-documents-to-add-links.yaml +0 -47
- package/agents/create/user-add-document/index.yaml +0 -46
- package/agents/create/user-add-document/prepare-documents-to-translate.mjs +0 -22
- package/agents/create/user-add-document/print-add-document-summary.mjs +0 -63
- package/agents/create/user-add-document/review-documents-with-new-links.mjs +0 -110
- package/agents/create/user-remove-document/find-documents-with-invalid-links.mjs +0 -78
- package/agents/create/user-remove-document/index.yaml +0 -40
- package/agents/create/user-remove-document/prepare-documents-to-translate.mjs +0 -22
- package/agents/create/user-remove-document/print-remove-document-summary.mjs +0 -53
- package/agents/create/user-remove-document/remove-documents-from-structure.mjs +0 -99
- package/agents/create/user-remove-document/review-documents-with-invalid-links.mjs +0 -115
- package/agents/create/user-review-document-structure.mjs +0 -139
- package/agents/create/utils/init-current-content.mjs +0 -34
- package/agents/create/utils/merge-document-structures.mjs +0 -36
- package/agents/evaluate/code-snippet.mjs +0 -97
- package/agents/evaluate/document-structure.yaml +0 -67
- package/agents/evaluate/document.yaml +0 -82
- package/agents/evaluate/generate-report.mjs +0 -85
- package/agents/evaluate/index.yaml +0 -46
- package/agents/history/index.yaml +0 -6
- package/agents/history/view.mjs +0 -78
- package/agents/init/check.mjs +0 -16
- package/agents/init/index.mjs +0 -643
- package/agents/init/validate.mjs +0 -16
- package/agents/localize/choose-language.mjs +0 -107
- package/agents/localize/record-translation-history.mjs +0 -23
- package/agents/localize/save-doc-translation-or-skip.mjs +0 -18
- package/agents/localize/set-review-content.mjs +0 -58
- package/agents/localize/translate-document-wrapper.mjs +0 -34
- package/agents/localize/translate-document.yaml +0 -24
- package/agents/localize/translate-multilingual.yaml +0 -57
- package/agents/localize/translate-or-skip-diagram.mjs +0 -52
- package/agents/media/batch-generate-media-description.yaml +0 -46
- package/agents/media/generate-media-description.yaml +0 -50
- package/agents/media/load-media-description.mjs +0 -454
- package/agents/prefs/index.mjs +0 -203
- package/agents/schema/document-structure-item.yaml +0 -26
- package/agents/schema/document-structure-refine-item.yaml +0 -23
- package/agents/schema/document-structure.yaml +0 -29
- package/agents/update/batch-generate-document.yaml +0 -27
- package/agents/update/batch-update-document.yaml +0 -7
- package/agents/update/check-diagram-flag.mjs +0 -116
- package/agents/update/check-document.mjs +0 -162
- package/agents/update/check-generate-diagram.mjs +0 -106
- package/agents/update/check-update-is-single.mjs +0 -53
- package/agents/update/document-tools/update-document-content.mjs +0 -303
- package/agents/update/generate-diagram.yaml +0 -80
- package/agents/update/generate-document.yaml +0 -70
- package/agents/update/handle-document-update.yaml +0 -103
- package/agents/update/index.yaml +0 -69
- package/agents/update/pre-check-generate-diagram.yaml +0 -44
- package/agents/update/save-and-translate-document.mjs +0 -80
- package/agents/update/update-document-detail.yaml +0 -71
- package/agents/update/update-single/update-single-document-detail.mjs +0 -322
- package/agents/update/update-single-document.yaml +0 -7
- package/agents/update/user-review-document.mjs +0 -272
- package/agents/utils/action-success.mjs +0 -16
- package/agents/utils/analyze-document-feedback-intent.yaml +0 -32
- package/agents/utils/analyze-feedback-intent.mjs +0 -253
- package/agents/utils/analyze-structure-feedback-intent.yaml +0 -29
- package/agents/utils/check-detail-result.mjs +0 -51
- package/agents/utils/check-feedback-refiner.mjs +0 -81
- package/agents/utils/choose-docs.mjs +0 -251
- package/agents/utils/document-icon-generate.yaml +0 -52
- package/agents/utils/document-title-streamline.yaml +0 -48
- package/agents/utils/ensure-document-icons.mjs +0 -129
- package/agents/utils/exit.mjs +0 -6
- package/agents/utils/feedback-refiner.yaml +0 -50
- package/agents/utils/find-item-by-path.mjs +0 -114
- package/agents/utils/find-user-preferences-by-path.mjs +0 -37
- package/agents/utils/format-document-structure.mjs +0 -35
- package/agents/utils/generate-document-or-skip.mjs +0 -41
- package/agents/utils/handle-diagram-operations.mjs +0 -263
- package/agents/utils/load-all-document-content.mjs +0 -30
- package/agents/utils/load-document-all-content.mjs +0 -96
- package/agents/utils/load-sources.mjs +0 -405
- package/agents/utils/map-reasoning-effort-level.mjs +0 -15
- package/agents/utils/post-generate.mjs +0 -133
- package/agents/utils/read-current-document-content.mjs +0 -46
- package/agents/utils/save-doc-translation.mjs +0 -30
- package/agents/utils/save-doc.mjs +0 -54
- package/agents/utils/save-output.mjs +0 -26
- package/agents/utils/save-sidebar.mjs +0 -38
- package/agents/utils/skip-if-content-exists.mjs +0 -27
- package/agents/utils/streamline-document-titles-if-needed.mjs +0 -88
- package/agents/utils/transform-detail-data-sources.mjs +0 -45
- package/assets/report-template/report.html +0 -198
- package/docs-mcp/analyze-content-relevance.yaml +0 -50
- package/docs-mcp/analyze-docs-relevance.yaml +0 -59
- package/docs-mcp/docs-search.yaml +0 -42
- package/docs-mcp/get-docs-detail.mjs +0 -41
- package/docs-mcp/get-docs-structure.mjs +0 -16
- package/docs-mcp/read-doc-content.mjs +0 -119
- package/prompts/common/document/content-rules-core.md +0 -20
- package/prompts/common/document/markdown-syntax-rules.md +0 -65
- package/prompts/common/document/media-file-list-usage-rules.md +0 -18
- package/prompts/common/document/openapi-usage-rules.md +0 -189
- package/prompts/common/document/role-and-personality.md +0 -16
- package/prompts/common/document/user-preferences.md +0 -9
- package/prompts/common/document-structure/conflict-resolution-guidance.md +0 -16
- package/prompts/common/document-structure/document-icon-generate.md +0 -116
- package/prompts/common/document-structure/document-structure-rules.md +0 -43
- package/prompts/common/document-structure/document-title-streamline.md +0 -86
- package/prompts/common/document-structure/glossary.md +0 -7
- package/prompts/common/document-structure/intj-traits.md +0 -5
- package/prompts/common/document-structure/openapi-usage-rules.md +0 -28
- package/prompts/common/document-structure/output-constraints.md +0 -18
- package/prompts/common/document-structure/user-locale-rules.md +0 -10
- package/prompts/common/document-structure/user-preferences.md +0 -9
- package/prompts/detail/custom/admonition-usage-rules.md +0 -94
- package/prompts/detail/custom/code-block-usage-rules.md +0 -163
- package/prompts/detail/custom/custom-components/x-card-usage-rules.md +0 -63
- package/prompts/detail/custom/custom-components/x-cards-usage-rules.md +0 -83
- package/prompts/detail/custom/custom-components/x-field-desc-usage-rules.md +0 -120
- package/prompts/detail/custom/custom-components/x-field-group-usage-rules.md +0 -80
- package/prompts/detail/custom/custom-components/x-field-usage-rules.md +0 -189
- package/prompts/detail/custom/custom-components-usage-rules.md +0 -18
- package/prompts/detail/diagram/generate-image-user.md +0 -81
- package/prompts/detail/diagram/guide.md +0 -29
- package/prompts/detail/diagram/official-examples.md +0 -712
- package/prompts/detail/diagram/pre-check.md +0 -23
- package/prompts/detail/diagram/role-and-personality.md +0 -2
- package/prompts/detail/diagram/rules.md +0 -46
- package/prompts/detail/diagram/system-prompt.md +0 -1139
- package/prompts/detail/diagram/user-prompt.md +0 -43
- package/prompts/detail/generate/detail-example.md +0 -457
- package/prompts/detail/generate/document-rules.md +0 -45
- package/prompts/detail/generate/system-prompt.md +0 -61
- package/prompts/detail/generate/user-prompt.md +0 -99
- package/prompts/detail/jsx/rules.md +0 -6
- package/prompts/detail/update/system-prompt.md +0 -121
- package/prompts/detail/update/user-prompt.md +0 -41
- package/prompts/evaluate/document-structure.md +0 -93
- package/prompts/evaluate/document.md +0 -149
- package/prompts/media/media-description/system-prompt.md +0 -43
- package/prompts/media/media-description/user-prompt.md +0 -17
- package/prompts/structure/check-document-structure.md +0 -93
- package/prompts/structure/document-rules.md +0 -21
- package/prompts/structure/find-documents-to-add-links.md +0 -52
- package/prompts/structure/generate/system-prompt.md +0 -13
- package/prompts/structure/generate/user-prompt.md +0 -137
- package/prompts/structure/review/structure-review-system.md +0 -81
- package/prompts/structure/structure-example.md +0 -89
- package/prompts/structure/structure-getting-started.md +0 -10
- package/prompts/structure/update/system-prompt.md +0 -93
- package/prompts/structure/update/user-prompt.md +0 -43
- package/prompts/translate/admonition.md +0 -20
- package/prompts/translate/code-block.md +0 -33
- package/prompts/utils/analyze-document-feedback-intent.md +0 -54
- package/prompts/utils/analyze-structure-feedback-intent.md +0 -43
- package/prompts/utils/feedback-refiner.md +0 -105
- package/types/document-schema.mjs +0 -55
- package/types/document-structure-schema.mjs +0 -261
- package/utils/check-document-has-diagram.mjs +0 -95
- package/utils/conflict-detector.mjs +0 -149
- package/utils/constants/index.mjs +0 -620
- package/utils/constants/linter.mjs +0 -102
- package/utils/d2-utils.mjs +0 -205
- package/utils/debug.mjs +0 -3
- package/utils/delete-diagram-images.mjs +0 -99
- package/utils/diagram-version-utils.mjs +0 -14
- package/utils/docs-finder-utils.mjs +0 -548
- package/utils/evaluate/report-utils.mjs +0 -132
- package/utils/extract-api.mjs +0 -32
- package/utils/file-utils.mjs +0 -960
- package/utils/history-utils.mjs +0 -203
- package/utils/icon-map.mjs +0 -26
- package/utils/image-compress.mjs +0 -154
- package/utils/kroki-utils.mjs +0 -173
- package/utils/linter/index.mjs +0 -50
- package/utils/load-config.mjs +0 -78
- package/utils/markdown/index.mjs +0 -26
- package/utils/markdown-checker.mjs +0 -694
- package/utils/mermaid-validator.mjs +0 -140
- package/utils/mermaid-worker-pool.mjs +0 -250
- package/utils/mermaid-worker.mjs +0 -233
- package/utils/openapi/index.mjs +0 -28
- package/utils/preferences-utils.mjs +0 -175
- package/utils/request.mjs +0 -10
- package/utils/sync-diagram-to-translations.mjs +0 -272
- package/utils/translate-diagram-images.mjs +0 -807
- package/utils/utils.mjs +0 -1354
- /package/{prompts/translate → agents/localize/prompts}/glossary.md +0 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { parse as yamlParse } from "yaml";
|
|
4
|
+
import { calculateFileHash, findImageFile } from "../../../utils/image-utils.mjs";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Check if images need translation
|
|
8
|
+
* @param {Object} input - Input parameters
|
|
9
|
+
* @param {Array} input.slots - Image slot list (from scan-doc-images output)
|
|
10
|
+
* @param {string} input.targetLanguage - Target language
|
|
11
|
+
* @param {string} input.sourceLanguage - Source language (main language)
|
|
12
|
+
* @returns {Promise<Object>} - Check result
|
|
13
|
+
*/
|
|
14
|
+
export default async function checkImageTranslation(input) {
|
|
15
|
+
const { slots, targetLanguage, sourceLanguage } = input;
|
|
16
|
+
|
|
17
|
+
if (!slots || slots.length === 0) {
|
|
18
|
+
return {
|
|
19
|
+
success: true,
|
|
20
|
+
translationTasks: [],
|
|
21
|
+
message: "No images to check",
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const translationTasks = [];
|
|
26
|
+
let sharedCount = 0;
|
|
27
|
+
let alreadyTranslatedCount = 0;
|
|
28
|
+
let needUpdateCount = 0;
|
|
29
|
+
|
|
30
|
+
for (const slot of slots) {
|
|
31
|
+
const { key, desc, assetDir, metaPath, exists } = slot;
|
|
32
|
+
|
|
33
|
+
// If image asset does not exist, skip
|
|
34
|
+
if (!exists) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Read .meta.yaml
|
|
39
|
+
let meta;
|
|
40
|
+
try {
|
|
41
|
+
const metaContent = await readFile(metaPath, "utf8");
|
|
42
|
+
meta = yamlParse(metaContent);
|
|
43
|
+
} catch (_error) {
|
|
44
|
+
// Failed to read .meta.yaml, skip
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 1. Check if it's a text-free shared image
|
|
49
|
+
if (meta.generation?.shared === true) {
|
|
50
|
+
sharedCount++;
|
|
51
|
+
continue; // Skip text-free images
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 2. Check if target language already exists
|
|
55
|
+
const languages = meta.languages || [];
|
|
56
|
+
const alreadyTranslated = languages.includes(targetLanguage);
|
|
57
|
+
|
|
58
|
+
// 3. Find source language image
|
|
59
|
+
const imagesDir = join(assetDir, "images");
|
|
60
|
+
const sourceImagePath = await findImageFile(imagesDir, sourceLanguage);
|
|
61
|
+
if (!sourceImagePath) {
|
|
62
|
+
// Source image does not exist, skip
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 4. Calculate source image hash
|
|
67
|
+
const sourceHash = await calculateFileHash(sourceImagePath);
|
|
68
|
+
|
|
69
|
+
// 5. Determine if translation is needed
|
|
70
|
+
let needsTranslation = false;
|
|
71
|
+
let reason = "";
|
|
72
|
+
|
|
73
|
+
if (!alreadyTranslated) {
|
|
74
|
+
// Target language version does not exist, needs translation
|
|
75
|
+
needsTranslation = true;
|
|
76
|
+
reason = "missing";
|
|
77
|
+
} else {
|
|
78
|
+
// Already translated, check if source image is updated
|
|
79
|
+
const translations = meta.translations || {};
|
|
80
|
+
const translationInfo = translations[targetLanguage];
|
|
81
|
+
|
|
82
|
+
if (!translationInfo || !translationInfo.sourceHash) {
|
|
83
|
+
// No source hash recorded, needs re-translation
|
|
84
|
+
needsTranslation = true;
|
|
85
|
+
reason = "no_hash";
|
|
86
|
+
} else if (translationInfo.sourceHash !== sourceHash) {
|
|
87
|
+
// Source image has been updated, needs re-translation
|
|
88
|
+
needsTranslation = true;
|
|
89
|
+
reason = "source_updated";
|
|
90
|
+
needUpdateCount++;
|
|
91
|
+
} else {
|
|
92
|
+
// Already translated and source image unchanged, skip
|
|
93
|
+
alreadyTranslatedCount++;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (needsTranslation) {
|
|
98
|
+
// Get image aspect ratio (from meta or default)
|
|
99
|
+
const aspectRatio = meta.generation?.aspectRatio || "4:3";
|
|
100
|
+
const size = meta.generation?.size || "2K";
|
|
101
|
+
|
|
102
|
+
translationTasks.push({
|
|
103
|
+
key,
|
|
104
|
+
desc,
|
|
105
|
+
assetDir,
|
|
106
|
+
sourceImagePath,
|
|
107
|
+
sourceHash,
|
|
108
|
+
aspectRatio,
|
|
109
|
+
size,
|
|
110
|
+
reason,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
success: true,
|
|
117
|
+
translationTasks,
|
|
118
|
+
sourceLanguage,
|
|
119
|
+
targetLanguage,
|
|
120
|
+
stats: {
|
|
121
|
+
total: slots.length,
|
|
122
|
+
shared: sharedCount,
|
|
123
|
+
alreadyTranslated: alreadyTranslatedCount,
|
|
124
|
+
needUpdate: needUpdateCount,
|
|
125
|
+
needTranslation: translationTasks.length,
|
|
126
|
+
},
|
|
127
|
+
message:
|
|
128
|
+
`Checked ${slots.length} images: ` +
|
|
129
|
+
`${sharedCount} text-free shared images, ` +
|
|
130
|
+
`${alreadyTranslatedCount} already translated, ` +
|
|
131
|
+
`${translationTasks.length} need translation` +
|
|
132
|
+
(needUpdateCount > 0 ? ` (${needUpdateCount} need update)` : ""),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Add description
|
|
137
|
+
checkImageTranslation.description =
|
|
138
|
+
"Check if images need translation to target language. " +
|
|
139
|
+
"Skip text-free shared images, check source image hash to determine if re-translation is needed. " +
|
|
140
|
+
"Return list of image translation tasks.";
|
|
141
|
+
|
|
142
|
+
// Define input schema
|
|
143
|
+
checkImageTranslation.input_schema = {
|
|
144
|
+
type: "object",
|
|
145
|
+
required: ["slots", "targetLanguage", "sourceLanguage"],
|
|
146
|
+
properties: {
|
|
147
|
+
slots: {
|
|
148
|
+
type: "array",
|
|
149
|
+
description: "Image slot list (from scan-doc-images output)",
|
|
150
|
+
items: {
|
|
151
|
+
type: "object",
|
|
152
|
+
properties: {
|
|
153
|
+
key: { type: "string" },
|
|
154
|
+
desc: { type: "string" },
|
|
155
|
+
assetDir: { type: "string", nullable: true },
|
|
156
|
+
metaPath: { type: "string", nullable: true },
|
|
157
|
+
exists: { type: "boolean" },
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
targetLanguage: {
|
|
162
|
+
type: "string",
|
|
163
|
+
description: "Target language code",
|
|
164
|
+
},
|
|
165
|
+
sourceLanguage: {
|
|
166
|
+
type: "string",
|
|
167
|
+
description: "Source language code (main language)",
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// Define output schema
|
|
173
|
+
checkImageTranslation.output_schema = {
|
|
174
|
+
type: "object",
|
|
175
|
+
required: ["success"],
|
|
176
|
+
properties: {
|
|
177
|
+
success: {
|
|
178
|
+
type: "boolean",
|
|
179
|
+
description: "Whether operation succeeded",
|
|
180
|
+
},
|
|
181
|
+
translationTasks: {
|
|
182
|
+
type: "array",
|
|
183
|
+
description: "List of image translation tasks",
|
|
184
|
+
items: {
|
|
185
|
+
type: "object",
|
|
186
|
+
properties: {
|
|
187
|
+
key: { type: "string", description: "Image key" },
|
|
188
|
+
desc: { type: "string", description: "Image description" },
|
|
189
|
+
assetDir: { type: "string", description: "Image asset directory" },
|
|
190
|
+
sourceImagePath: { type: "string", description: "Source image file path" },
|
|
191
|
+
sourceHash: { type: "string", description: "Source image hash" },
|
|
192
|
+
aspectRatio: { type: "string", description: "Aspect ratio" },
|
|
193
|
+
size: { type: "string", description: "Image size" },
|
|
194
|
+
reason: {
|
|
195
|
+
type: "string",
|
|
196
|
+
description: "Translation reason (missing/no_hash/source_updated)",
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
sourceLanguage: {
|
|
202
|
+
type: "string",
|
|
203
|
+
description: "Source language code",
|
|
204
|
+
},
|
|
205
|
+
targetLanguage: {
|
|
206
|
+
type: "string",
|
|
207
|
+
description: "Target language code",
|
|
208
|
+
},
|
|
209
|
+
stats: {
|
|
210
|
+
type: "object",
|
|
211
|
+
description: "Statistics",
|
|
212
|
+
properties: {
|
|
213
|
+
total: { type: "number", description: "Total image count" },
|
|
214
|
+
shared: { type: "number", description: "Text-free shared image count" },
|
|
215
|
+
alreadyTranslated: { type: "number", description: "Already translated count" },
|
|
216
|
+
needUpdate: { type: "number", description: "Need update count" },
|
|
217
|
+
needTranslation: { type: "number", description: "Need translation count" },
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
message: {
|
|
221
|
+
type: "string",
|
|
222
|
+
description: "Operation result description",
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join, basename } from "node:path";
|
|
3
|
+
import { parse as yamlParse } from "yaml";
|
|
4
|
+
import { findImageFile, getImageMimeType } from "../../../../utils/image-utils.mjs";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Detect if image contains text and update .meta.yaml shared field
|
|
8
|
+
* @param {Object} input - Input parameters
|
|
9
|
+
* @param {Array} input.slots - Image slot list (from scan-doc-images output)
|
|
10
|
+
* @param {string} input.sourceLanguage - Source language (main language)
|
|
11
|
+
* @returns {Promise<Object>} - Processing result
|
|
12
|
+
*/
|
|
13
|
+
export default async function detectAndUpdateShared(input) {
|
|
14
|
+
const { slots, sourceLanguage } = input;
|
|
15
|
+
|
|
16
|
+
if (!slots || slots.length === 0 || !slots.some((s) => s.exists)) {
|
|
17
|
+
return {
|
|
18
|
+
success: true,
|
|
19
|
+
detectionTasks: [],
|
|
20
|
+
message: "No images to detect",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const detectionTasks = [];
|
|
25
|
+
|
|
26
|
+
for (const slot of slots) {
|
|
27
|
+
const { key, assetDir, metaPath, exists } = slot;
|
|
28
|
+
|
|
29
|
+
// If image asset does not exist, skip
|
|
30
|
+
if (!exists) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Read .meta.yaml
|
|
35
|
+
let meta;
|
|
36
|
+
try {
|
|
37
|
+
const metaContent = await readFile(metaPath, "utf8");
|
|
38
|
+
meta = yamlParse(metaContent);
|
|
39
|
+
} catch (_error) {
|
|
40
|
+
// Failed to read .meta.yaml, skip
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Check if shared field has already been detected
|
|
45
|
+
if (meta.generation?.shared === true) {
|
|
46
|
+
// Already detected, skip shared images
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Find main language image
|
|
51
|
+
const imagesDir = join(assetDir, "images");
|
|
52
|
+
const sourceImagePath = await findImageFile(imagesDir, sourceLanguage);
|
|
53
|
+
|
|
54
|
+
if (!sourceImagePath) {
|
|
55
|
+
// Main language image does not exist, skip
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Add to detection task list
|
|
60
|
+
detectionTasks.push({
|
|
61
|
+
key,
|
|
62
|
+
assetDir,
|
|
63
|
+
metaPath,
|
|
64
|
+
sourceImagePath,
|
|
65
|
+
// Prepare imageFile parameter (mediaFile format)
|
|
66
|
+
imageFile: [
|
|
67
|
+
{
|
|
68
|
+
type: "local",
|
|
69
|
+
path: sourceImagePath,
|
|
70
|
+
filename: basename(sourceImagePath),
|
|
71
|
+
mimeType: getImageMimeType(sourceImagePath),
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
success: true,
|
|
79
|
+
detectionTasks,
|
|
80
|
+
sourceLanguage,
|
|
81
|
+
message: `${detectionTasks.length} images need text detection`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Add description
|
|
86
|
+
detectAndUpdateShared.description =
|
|
87
|
+
"Detect if images contain text, prepare batch detection tasks. " +
|
|
88
|
+
"Only detect images without generation.shared field set.";
|
|
89
|
+
|
|
90
|
+
// Define input schema
|
|
91
|
+
detectAndUpdateShared.input_schema = {
|
|
92
|
+
type: "object",
|
|
93
|
+
required: ["slots", "sourceLanguage"],
|
|
94
|
+
properties: {
|
|
95
|
+
slots: {
|
|
96
|
+
type: "array",
|
|
97
|
+
description: "Image slot list (from scan-doc-images output)",
|
|
98
|
+
items: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: {
|
|
101
|
+
key: { type: "string" },
|
|
102
|
+
desc: { type: "string" },
|
|
103
|
+
assetDir: { type: "string", nullable: true },
|
|
104
|
+
metaPath: { type: "string", nullable: true },
|
|
105
|
+
exists: { type: "boolean" },
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
sourceLanguage: {
|
|
110
|
+
type: "string",
|
|
111
|
+
description: "Source language code (main language)",
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Define output schema
|
|
117
|
+
detectAndUpdateShared.output_schema = {
|
|
118
|
+
type: "object",
|
|
119
|
+
required: ["success"],
|
|
120
|
+
properties: {
|
|
121
|
+
success: {
|
|
122
|
+
type: "boolean",
|
|
123
|
+
description: "Whether operation succeeded",
|
|
124
|
+
},
|
|
125
|
+
detectionTasks: {
|
|
126
|
+
type: "array",
|
|
127
|
+
description: "List of image detection tasks",
|
|
128
|
+
items: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
key: { type: "string", description: "Image key" },
|
|
132
|
+
assetDir: { type: "string", description: "Image asset directory" },
|
|
133
|
+
metaPath: { type: "string", description: ".meta.yaml file path" },
|
|
134
|
+
sourceImagePath: { type: "string", description: "Main language image path" },
|
|
135
|
+
imageFile: { type: "array", description: "imageFile mediaFile object array" },
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
sourceLanguage: {
|
|
140
|
+
type: "string",
|
|
141
|
+
description: "Source language code",
|
|
142
|
+
},
|
|
143
|
+
message: {
|
|
144
|
+
type: "string",
|
|
145
|
+
description: "Operation result description",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: detectImageText
|
|
2
|
+
description: Detect if image contains text content
|
|
3
|
+
model: gemini-2.5-flash
|
|
4
|
+
modalities: ["text", "image"]
|
|
5
|
+
instructions:
|
|
6
|
+
- role: system
|
|
7
|
+
url: ./prompts/detect-image-text-system.md
|
|
8
|
+
- role: user
|
|
9
|
+
url: ./prompts/detect-image-text-user.md
|
|
10
|
+
input_file_key: imageFile
|
|
11
|
+
include_input_in_output: true
|
|
12
|
+
input_schema:
|
|
13
|
+
type: object
|
|
14
|
+
properties:
|
|
15
|
+
key:
|
|
16
|
+
type: string
|
|
17
|
+
description: Image key
|
|
18
|
+
imageFile:
|
|
19
|
+
type: array
|
|
20
|
+
description: Array of mediaFile objects for image files
|
|
21
|
+
items:
|
|
22
|
+
type: object
|
|
23
|
+
properties:
|
|
24
|
+
type:
|
|
25
|
+
type: string
|
|
26
|
+
description: File type, should be "local"
|
|
27
|
+
path:
|
|
28
|
+
type: string
|
|
29
|
+
description: Absolute path to the image file
|
|
30
|
+
filename:
|
|
31
|
+
type: string
|
|
32
|
+
description: Image filename
|
|
33
|
+
mimeType:
|
|
34
|
+
type: string
|
|
35
|
+
description: MIME type (e.g., "image/png", "image/jpeg")
|
|
36
|
+
required:
|
|
37
|
+
- key
|
|
38
|
+
- imageFile
|
|
39
|
+
output_schema:
|
|
40
|
+
type: object
|
|
41
|
+
properties:
|
|
42
|
+
hasText:
|
|
43
|
+
type: boolean
|
|
44
|
+
description: Whether the image contains text
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
type: team
|
|
2
|
+
name: detectImagesText
|
|
3
|
+
description: Detect if images contain text and update shared field
|
|
4
|
+
skills:
|
|
5
|
+
- url: ./detect-and-update-shared.mjs # Prepare detection tasks
|
|
6
|
+
- type: team
|
|
7
|
+
name: processTextDetections # Batch detect image text
|
|
8
|
+
skills:
|
|
9
|
+
- type: team
|
|
10
|
+
name: detectSingleImageText
|
|
11
|
+
description: Detect if a single image contains text and save result
|
|
12
|
+
skills:
|
|
13
|
+
- url: ./detect-image-text.yaml # Detect image text
|
|
14
|
+
- url: ./save-text-detection.mjs # Save detection result
|
|
15
|
+
mode: sequential
|
|
16
|
+
include_input_in_output: true
|
|
17
|
+
|
|
18
|
+
iterate_on: detectionTasks
|
|
19
|
+
concurrency: 1
|
|
20
|
+
mode: sequential
|
|
21
|
+
include_input_in_output: true
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
You are an AI assistant specialized in analyzing diagram images to detect the presence of text content.
|
|
2
|
+
|
|
3
|
+
# YOUR TASK
|
|
4
|
+
|
|
5
|
+
Analyze the provided diagram image and determine whether it contains any text or textual labels.
|
|
6
|
+
|
|
7
|
+
# WHAT COUNTS AS TEXT
|
|
8
|
+
|
|
9
|
+
Text includes:
|
|
10
|
+
- ✅ Words, labels, or text annotations in any language
|
|
11
|
+
- ✅ Abbreviations, acronyms, or code snippets
|
|
12
|
+
- ✅ Numbers used as labels or identifiers (e.g., "Step 1", "v2.0")
|
|
13
|
+
- ✅ Technical terms or variable names
|
|
14
|
+
- ✅ Arrows or connectors with text labels
|
|
15
|
+
|
|
16
|
+
# WHAT DOES NOT COUNT AS TEXT
|
|
17
|
+
|
|
18
|
+
The following should NOT be considered as text:
|
|
19
|
+
- ❌ Pure icons or symbols without text
|
|
20
|
+
- ❌ Standalone numbers used decoratively (not as labels)
|
|
21
|
+
- ❌ Colors, shapes, or visual patterns
|
|
22
|
+
- ❌ Logos that are purely graphical
|
|
23
|
+
|
|
24
|
+
# OUTPUT FORMAT
|
|
25
|
+
|
|
26
|
+
You must respond with ONLY one of these two values:
|
|
27
|
+
- `true` - if the image contains ANY text content
|
|
28
|
+
- `false` - if the image contains NO text (pure visual diagram)
|
|
29
|
+
|
|
30
|
+
# IMPORTANT RULES
|
|
31
|
+
|
|
32
|
+
1. Be strict: even a single word or label means the image has text → return `true`
|
|
33
|
+
2. Ignore watermarks or metadata that are not part of the diagram content
|
|
34
|
+
3. Focus on the actual diagram content, not borders or backgrounds
|
|
35
|
+
4. Your response must be ONLY `true` or `false`, nothing else
|
|
36
|
+
|
|
37
|
+
# EXAMPLES
|
|
38
|
+
|
|
39
|
+
**Image with node labels like "User", "API", "Database"** → `true`
|
|
40
|
+
**Flowchart with text like "Start", "Process", "End"** → `true`
|
|
41
|
+
**Architecture diagram with component names** → `true`
|
|
42
|
+
**Pure icon-based diagram with no text labels** → `false`
|
|
43
|
+
**Diagram with only arrows and shapes, no text** → `false`
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Text Detection Task
|
|
2
|
+
|
|
3
|
+
Analyze the provided diagram image and determine if it contains any text content.
|
|
4
|
+
|
|
5
|
+
**Image Key:** {{ key }}
|
|
6
|
+
|
|
7
|
+
[The diagram image is provided as input to the model]
|
|
8
|
+
|
|
9
|
+
**Your task:**
|
|
10
|
+
1. Carefully examine the entire image
|
|
11
|
+
2. Look for any words, labels, text annotations, or textual content
|
|
12
|
+
3. Respond with ONLY `true` (has text) or `false` (no text)
|
|
13
|
+
|
|
14
|
+
**Response:** (true or false only)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { parse as yamlParse, stringify as yamlStringify } from "yaml";
|
|
3
|
+
import { ERROR_CODES } from "../../../../utils/agent-constants.mjs";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Save text detection result to .meta.yaml
|
|
7
|
+
* @param {Object} input - Input parameters
|
|
8
|
+
* @param {string} input.key - Image key
|
|
9
|
+
* @param {string} input.metaPath - .meta.yaml file path
|
|
10
|
+
* @param {boolean} input.hasText - Whether contains text (from detect-image-text.yaml output)
|
|
11
|
+
* @returns {Promise<Object>} - Operation result
|
|
12
|
+
*/
|
|
13
|
+
export default async function saveTextDetection(input) {
|
|
14
|
+
const { key, metaPath, hasText } = input;
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// Read .meta.yaml
|
|
18
|
+
const metaContent = await readFile(metaPath, "utf8");
|
|
19
|
+
const meta = yamlParse(metaContent);
|
|
20
|
+
|
|
21
|
+
// Update generation.shared field
|
|
22
|
+
if (!meta.generation) {
|
|
23
|
+
meta.generation = {};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// shared = !hasText (no text means shared)
|
|
27
|
+
meta.generation.shared = !hasText;
|
|
28
|
+
|
|
29
|
+
// Save updated .meta.yaml
|
|
30
|
+
const updatedMetaContent = yamlStringify(meta);
|
|
31
|
+
await writeFile(metaPath, updatedMetaContent, "utf8");
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
success: true,
|
|
35
|
+
key,
|
|
36
|
+
hasText,
|
|
37
|
+
shared: !hasText,
|
|
38
|
+
message: `Updated shared field: ${key} (hasText=${hasText}, shared=${!hasText})`,
|
|
39
|
+
};
|
|
40
|
+
} catch (error) {
|
|
41
|
+
return {
|
|
42
|
+
success: false,
|
|
43
|
+
error: ERROR_CODES.SAVE_ERROR,
|
|
44
|
+
message: `Error saving text detection result: ${error.message}`,
|
|
45
|
+
key,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Add description
|
|
51
|
+
saveTextDetection.description =
|
|
52
|
+
"Save image text detection result to .meta.yaml file. " +
|
|
53
|
+
"Update generation.shared field based on detection result: text-free images shared=true, images with text shared=false.";
|
|
54
|
+
|
|
55
|
+
// Define input schema
|
|
56
|
+
saveTextDetection.input_schema = {
|
|
57
|
+
type: "object",
|
|
58
|
+
required: ["key", "metaPath", "hasText"],
|
|
59
|
+
properties: {
|
|
60
|
+
key: {
|
|
61
|
+
type: "string",
|
|
62
|
+
description: "Image key",
|
|
63
|
+
},
|
|
64
|
+
metaPath: {
|
|
65
|
+
type: "string",
|
|
66
|
+
description: ".meta.yaml file path",
|
|
67
|
+
},
|
|
68
|
+
hasText: {
|
|
69
|
+
type: "boolean",
|
|
70
|
+
description: "Whether image contains text (from detect-image-text.yaml output)",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Define output schema
|
|
76
|
+
saveTextDetection.output_schema = {
|
|
77
|
+
type: "object",
|
|
78
|
+
required: ["success"],
|
|
79
|
+
properties: {
|
|
80
|
+
success: {
|
|
81
|
+
type: "boolean",
|
|
82
|
+
description: "Whether operation succeeded",
|
|
83
|
+
},
|
|
84
|
+
key: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "Image key",
|
|
87
|
+
},
|
|
88
|
+
hasText: {
|
|
89
|
+
type: "boolean",
|
|
90
|
+
description: "Whether image contains text (present on success)",
|
|
91
|
+
},
|
|
92
|
+
shared: {
|
|
93
|
+
type: "boolean",
|
|
94
|
+
description: "Whether it is a shared image (present on success)",
|
|
95
|
+
},
|
|
96
|
+
message: {
|
|
97
|
+
type: "string",
|
|
98
|
+
description: "Operation result description",
|
|
99
|
+
},
|
|
100
|
+
error: {
|
|
101
|
+
type: "string",
|
|
102
|
+
description: "Error code (present on failure)",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|