@aigne/doc-smith 0.8.15-beta.9 → 0.8.16-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.
Files changed (72) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/agents/chat/chat-system.md +32 -0
  3. package/agents/chat/index.yaml +14 -22
  4. package/agents/chat/skills/generate-document.yaml +15 -0
  5. package/agents/chat/skills/update-document.yaml +24 -0
  6. package/agents/evaluate/document-structure.yaml +3 -1
  7. package/agents/evaluate/document.yaml +3 -1
  8. package/agents/generate/check-need-generate-structure.mjs +4 -0
  9. package/agents/generate/document-structure-tools/add-document.mjs +5 -1
  10. package/agents/generate/document-structure-tools/update-document.mjs +7 -0
  11. package/agents/generate/generate-structure.yaml +1 -5
  12. package/agents/generate/merge-diagram.yaml +4 -4
  13. package/agents/generate/update-document-structure.yaml +51 -45
  14. package/agents/generate/user-review-document-structure.mjs +47 -55
  15. package/agents/generate/utils/merge-document-structures.mjs +4 -4
  16. package/agents/init/check.mjs +1 -1
  17. package/agents/init/index.mjs +52 -2
  18. package/agents/init/validate.mjs +16 -0
  19. package/agents/publish/publish-docs.mjs +16 -10
  20. package/agents/schema/document-execution-structure.yaml +1 -1
  21. package/agents/schema/document-structure-item.yaml +1 -1
  22. package/agents/schema/document-structure.yaml +4 -2
  23. package/agents/update/check-generate-diagram.mjs +74 -16
  24. package/agents/update/generate-document.yaml +1 -13
  25. package/agents/update/handle-document-update.yaml +1 -1
  26. package/agents/update/pre-check-generate-diagram.yaml +44 -0
  27. package/agents/update/update-document-detail.yaml +64 -58
  28. package/agents/update/update-single-document.yaml +1 -1
  29. package/agents/update/user-review-document.mjs +58 -43
  30. package/agents/utils/analyze-feedback-intent.yaml +29 -0
  31. package/agents/utils/choose-docs.mjs +16 -6
  32. package/agents/utils/document-title-streamline.yaml +48 -0
  33. package/agents/utils/find-item-by-path.mjs +4 -2
  34. package/agents/utils/list-docs.mjs +15 -0
  35. package/agents/utils/load-sources.mjs +4 -4
  36. package/agents/utils/map-reasoning-effort-level.mjs +15 -0
  37. package/agents/utils/save-sidebar.mjs +12 -33
  38. package/agents/utils/streamline-document-titles-if-needed.mjs +88 -0
  39. package/agents/utils/{transform-detail-datasources.mjs → transform-detail-data-sources.mjs} +2 -2
  40. package/aigne.yaml +12 -4
  41. package/package.json +11 -9
  42. package/prompts/common/document/content-rules-core.md +5 -5
  43. package/prompts/common/document-structure/conflict-resolution-guidance.md +2 -2
  44. package/prompts/common/document-structure/document-structure-rules.md +8 -8
  45. package/prompts/common/document-structure/document-title-streamline.md +86 -0
  46. package/prompts/common/document-structure/output-constraints.md +3 -3
  47. package/prompts/detail/custom/custom-code-block.md +36 -1
  48. package/prompts/detail/custom/{custom-components.md → custom-components-usage-rules.md} +29 -7
  49. package/prompts/detail/d2-diagram/pre-check.md +23 -0
  50. package/prompts/detail/d2-diagram/rules.md +42 -24
  51. package/prompts/detail/d2-diagram/user-prompt.md +0 -20
  52. package/prompts/detail/generate/document-rules.md +2 -2
  53. package/prompts/detail/generate/system-prompt.md +3 -3
  54. package/prompts/detail/generate/user-prompt.md +5 -5
  55. package/prompts/detail/update/system-prompt.md +4 -3
  56. package/prompts/detail/update/user-prompt.md +8 -4
  57. package/prompts/evaluate/document.md +0 -4
  58. package/prompts/structure/check-document-structure.md +4 -4
  59. package/prompts/structure/generate/system-prompt.md +0 -1
  60. package/prompts/structure/generate/user-prompt.md +14 -9
  61. package/prompts/structure/review/structure-review-system.md +5 -2
  62. package/prompts/structure/update/system-prompt.md +0 -13
  63. package/prompts/structure/update/user-prompt.md +6 -5
  64. package/prompts/translate/translate-document.md +3 -3
  65. package/prompts/utils/analyze-feedback-intent.md +55 -0
  66. package/utils/constants/index.mjs +38 -0
  67. package/utils/deploy.mjs +3 -1
  68. package/utils/docs-finder-utils.mjs +37 -3
  69. package/utils/file-utils.mjs +97 -0
  70. package/utils/load-config.mjs +19 -0
  71. package/agents/utils/docs-fs-actor.yaml +0 -27
  72. package/agents/utils/fs.mjs +0 -60
@@ -4,6 +4,8 @@ import chalk from "chalk";
4
4
  import { stringify as yamlStringify } from "yaml";
5
5
  import { getFilteredOptions } from "../../utils/conflict-detector.mjs";
6
6
  import {
7
+ DEFAULT_REASONING_EFFORT_LEVEL,
8
+ DEFAULT_THINKING_EFFORT_LEVEL,
7
9
  DEPTH_RECOMMENDATION_LOGIC,
8
10
  DOCUMENT_STYLES,
9
11
  DOCUMENTATION_DEPTH,
@@ -21,6 +23,8 @@ import {
21
23
  validatePath,
22
24
  } from "../../utils/utils.mjs";
23
25
  import { isRemoteFile } from "../../utils/file-utils.mjs";
26
+ import { validateDocDir } from "./validate.mjs";
27
+ import mapReasoningEffortLevel from "../utils/map-reasoning-effort-level.mjs";
24
28
 
25
29
  const _PRESS_ENTER_TO_FINISH = "Press Enter to finish";
26
30
 
@@ -31,7 +35,23 @@ const _PRESS_ENTER_TO_FINISH = "Press Enter to finish";
31
35
  * @param {string} params.fileName - The name of the file.
32
36
  * @returns {Promise<Object>}
33
37
  */
34
- export default async function init(
38
+ export default async function init(input, options) {
39
+ const config = await _init(input, options);
40
+
41
+ // Set thinking effort (lite/standard/pro) and map to reasoningEffort
42
+ options.context.userContext.thinkingEffort =
43
+ config.thinking?.effort || DEFAULT_THINKING_EFFORT_LEVEL;
44
+
45
+ // Set global reasoningEffort based on thinkingEffort
46
+ options.context.userContext.reasoningEffort = mapReasoningEffortLevel(
47
+ { level: DEFAULT_REASONING_EFFORT_LEVEL },
48
+ options,
49
+ )?.reasoningEffort;
50
+
51
+ return config;
52
+ }
53
+
54
+ async function _init(
35
55
  {
36
56
  outputPath = ".aigne/doc-smith",
37
57
  fileName = "config.yaml",
@@ -64,7 +84,19 @@ export default async function init(
64
84
  // Only skip if file exists AND has non-empty content
65
85
  if (configContent && configContent.trim() !== "") {
66
86
  // load config from file
67
- return loadConfig({ config: filePath, appUrl });
87
+ const config = await loadConfig({ config: filePath, appUrl });
88
+ const isValid = validateDocDir(config.docsDir);
89
+ if (typeof isValid === "string") {
90
+ console.log(
91
+ `${chalk.red("Invalid docsDir")}: ${isValid}\nPlease check your configuration.`,
92
+ );
93
+ process.exit(1);
94
+ }
95
+ if (!isValid) {
96
+ console.log(`${chalk.red("Invalid docsDir")}, please check your configuration.`);
97
+ process.exit(1);
98
+ }
99
+ return config;
68
100
  }
69
101
  }
70
102
 
@@ -241,6 +273,7 @@ export default async function init(
241
273
  const docsDirInput = await options.prompts.input({
242
274
  message: `📁 [7/9]: Where should we save your documentation?`,
243
275
  default: `${outputPath}/docs`,
276
+ validate: validateDocDir,
244
277
  });
245
278
  input.docsDir = docsDirInput.trim() || `${outputPath}/docs`;
246
279
 
@@ -424,6 +457,10 @@ export function generateYAML(input) {
424
457
  projectDesc: input.projectDesc || "",
425
458
  projectLogo: input.projectLogo || "",
426
459
 
460
+ thinking: {
461
+ effort: input.thinking?.effort || DEFAULT_THINKING_EFFORT_LEVEL,
462
+ },
463
+
427
464
  // Documentation configuration
428
465
  documentPurpose: input.documentPurpose || [],
429
466
  targetAudienceTypes: input.targetAudienceTypes || [],
@@ -459,6 +496,19 @@ export function generateYAML(input) {
459
496
 
460
497
  yaml += `${projectSection}\n\n`;
461
498
 
499
+ const modelSection = yamlStringify({
500
+ thinking: config.thinking,
501
+ }).trim();
502
+
503
+ yaml += `\
504
+ # AI Thinking Configuration
505
+ # thinking.effort: Determines the depth of reasoning and cognitive effort the AI uses when responding, available options:
506
+ # - lite: Fast responses with basic reasoning
507
+ # - standard: Balanced speed and reasoning capability
508
+ # - pro: In-depth reasoning with longer response times
509
+ ${modelSection}
510
+ \n`;
511
+
462
512
  // Add documentation configuration with comments
463
513
  yaml += "# =============================================================================\n";
464
514
  yaml += "# Documentation Configuration\n";
@@ -0,0 +1,16 @@
1
+ import path from "node:path";
2
+ export function validateDocDir(input) {
3
+ const currentDir = process.cwd();
4
+ const targetDir = path.resolve(input);
5
+ const relativePath = path.relative(currentDir, targetDir);
6
+ if (relativePath.length === 0) {
7
+ return `Can't use current directory: ${targetDir}`;
8
+ }
9
+ if (relativePath.startsWith("..")) {
10
+ return `Can't use directory outside current directory: ${targetDir}`;
11
+ }
12
+ if (path.isAbsolute(relativePath)) {
13
+ return `Can't use absolute path: ${targetDir}`;
14
+ }
15
+ return true;
16
+ }
@@ -163,8 +163,13 @@ export default async function publishDocs(
163
163
  } else {
164
164
  console.log(`\nCreating a new website for your documentation...`);
165
165
  }
166
- const { appUrl: homeUrl, token: ltToken } = (await deploy(id, paymentLink)) || {};
166
+ const {
167
+ appUrl: homeUrl,
168
+ token: ltToken,
169
+ sessionId: newSessionId,
170
+ } = (await deploy(id, paymentLink)) || {};
167
171
 
172
+ sessionId = newSessionId;
168
173
  appUrl = homeUrl;
169
174
  token = ltToken;
170
175
  } catch (error) {
@@ -174,13 +179,7 @@ export default async function publishDocs(
174
179
  }
175
180
  }
176
181
 
177
- if (sessionId) {
178
- authToken = await getOfficialAccessToken(BASE_URL, false);
179
- client = client || new BrokerClient({ baseUrl: BASE_URL, authToken });
180
-
181
- const { vendors } = await client.getSessionDetail(sessionId, false);
182
- token = vendors?.find((vendor) => vendor.vendorType === "launcher" && vendor.token)?.token;
183
- }
182
+ appUrl = appUrl ?? CLOUD_SERVICE_URL_PROD;
184
183
 
185
184
  console.log(`\nPublishing your documentation to ${chalk.cyan(appUrl)}\n`);
186
185
 
@@ -264,8 +263,15 @@ export default async function publishDocs(
264
263
  await saveValueToConfig("shouldSyncBranding", "", "Should sync branding for documentation");
265
264
  } else {
266
265
  // If the error is 401 or 403, it means the access token is invalid
267
- if (error?.includes("401") || error?.includes("403")) {
268
- message = `❌ Publishing failed due to an authorization error. Please run ${chalk.cyan("aigne doc clear")} to reset your credentials and try again.`;
266
+ try {
267
+ const obj = JSON.parse(error);
268
+ message = `❌ Publishing failed with error: \n💡 ${obj.message || error}`;
269
+ } catch {
270
+ if (error?.includes("401")) {
271
+ message = `❌ Publishing failed due to an authorization error: \n💡 Please run ${chalk.cyan("aigne doc clear")} to reset your credentials and try again.`;
272
+ } else if (error?.includes("403")) {
273
+ message = `❌ Publishing failed due to an authorization error: \n💡 You’re not the creator of this document (Board ID: ${boardId}). You can change the board ID and try again. \n💡 Or run ${chalk.cyan("aigne doc clear")} to reset your credentials and try again.`;
274
+ }
269
275
  }
270
276
  }
271
277
 
@@ -25,7 +25,7 @@ items:
25
25
  type: array
26
26
  items:
27
27
  type: string
28
- description: Associated sourceId from dataSources for subsequent translation and content generation, must come from sourceId in datasources, cannot have fake ids, cannot be empty
28
+ description: Associated sourceId from `<data_sources>` for subsequent translation and content generation, must come from sourceId in `<data_sources>`, cannot have fake ids, cannot be empty
29
29
  required:
30
30
  - title
31
31
  - description
@@ -13,7 +13,7 @@ properties:
13
13
  description: Parent node path, if null indicates it is a top-level node
14
14
  sourceIds:
15
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**
16
+ description: Associated sourceId from `<data_sources>` for subsequent translation and content generation, must come from sourceId in `<data_sources>`, cannot have fake ids, **cannot be empty**
17
17
  items:
18
18
  type: string
19
19
  required:
@@ -10,11 +10,13 @@ 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: string
13
+ type:
14
+ - string
15
+ - "null"
14
16
  description: Parent node path, if null indicates it is a top-level node
15
17
  sourceIds:
16
18
  type: array
17
- description: Associated sourceId from dataSources for subsequent translation and content generation, must come from sourceId in datasources, cannot have fake ids, **cannot be empty**
19
+ description: Associated sourceId from `<data_sources>` for subsequent translation and content generation, must come from sourceId in `<data_sources>`, cannot have fake ids, **cannot be empty**
18
20
  items:
19
21
  type: string
20
22
  required:
@@ -1,26 +1,84 @@
1
- const placeholder = "DIAGRAM_PLACEHOLDER";
1
+ const PLACEHOLDER = "DIAGRAM_PLACEHOLDER";
2
+ const DEFAULT_DIAGRAMMING_EFFORT = 5;
3
+ const MIN_DIAGRAMMING_EFFORT = 0;
4
+ const MAX_DIAGRAMMING_EFFORT = 10;
2
5
 
3
6
  export default async function checkGenerateDiagram(
4
- { needDiagram, documentContent, locale },
7
+ {
8
+ documentContent,
9
+ locale,
10
+ feedback,
11
+ detailFeedback,
12
+ originalContent,
13
+ path: docPath,
14
+ diagramming,
15
+ },
5
16
  options,
6
17
  ) {
7
- if (!needDiagram) {
8
- return {};
18
+ let content = documentContent;
19
+ let diagramSourceCode;
20
+ let skipGenerateDiagram = false;
21
+
22
+ const preCheckAgent = options.context?.agents?.["preCheckGenerateDiagram"];
23
+
24
+ const preCheckResult = await options.context.invoke(preCheckAgent, {
25
+ documentContent,
26
+ feedback,
27
+ detailFeedback,
28
+ previousGenerationContent: originalContent,
29
+ });
30
+
31
+ const totalScore = (preCheckResult.details || []).reduce((acc, curr) => acc + curr.score, 0);
32
+ if (![false, "false", "", undefined, null].includes(preCheckResult.content)) {
33
+ content = preCheckResult.content;
9
34
  }
10
35
 
11
- const generateAgent = options.context?.agents?.["generateDiagram"];
12
- let content = documentContent;
36
+ let diagrammingEffort = diagramming?.effort
37
+ ? Number(diagramming?.effort)
38
+ : DEFAULT_DIAGRAMMING_EFFORT;
13
39
 
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}`);
40
+ if (Number.isNaN(diagrammingEffort)) {
41
+ diagrammingEffort = DEFAULT_DIAGRAMMING_EFFORT;
42
+ } else {
43
+ diagrammingEffort = Math.min(
44
+ Math.max(MIN_DIAGRAMMING_EFFORT, diagrammingEffort),
45
+ MAX_DIAGRAMMING_EFFORT,
46
+ );
24
47
  }
48
+
49
+ if (totalScore <= diagrammingEffort) {
50
+ skipGenerateDiagram = true;
51
+ }
52
+
53
+ if (skipGenerateDiagram) {
54
+ content = documentContent;
55
+ } else {
56
+ try {
57
+ const generateAgent = options.context?.agents?.["generateDiagram"];
58
+ ({ diagramSourceCode } = await options.context.invoke(generateAgent, {
59
+ documentContent: content,
60
+ locale,
61
+ }));
62
+ } catch (error) {
63
+ diagramSourceCode = "";
64
+ skipGenerateDiagram = true;
65
+ console.log(`⚠️ Skip generate any diagram for ${docPath}: ${error.message}`);
66
+ }
67
+
68
+ if (diagramSourceCode && !skipGenerateDiagram) {
69
+ if (content.includes(PLACEHOLDER)) {
70
+ content = content.replace(PLACEHOLDER, diagramSourceCode);
71
+ } else {
72
+ const mergeAgent = options.context?.agents?.["mergeDiagramToDocument"];
73
+ ({ content } = await options.context.invoke(mergeAgent, {
74
+ diagramSourceCode,
75
+ content,
76
+ }));
77
+ }
78
+ } else {
79
+ content = documentContent;
80
+ }
81
+ }
82
+
25
83
  return { content };
26
84
  }
@@ -46,19 +46,7 @@ input_schema:
46
46
  - rules
47
47
  - detailDataSource
48
48
  - originalDocumentStructure
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
49
+ output_key: content
62
50
  afs:
63
51
  modules:
64
52
  - module: system-fs
@@ -2,7 +2,7 @@ type: team
2
2
  name: handleDocumentUpdate
3
3
  description: Update a document in a batch
4
4
  skills:
5
- - ../utils/transform-detail-datasources.mjs
5
+ - ../utils/transform-detail-data-sources.mjs
6
6
  - type: team
7
7
  task_render_mode: collapse
8
8
  name: generateDocumentContent
@@ -0,0 +1,44 @@
1
+ name: preCheckGenerateDiagram
2
+ description: Pre-check for generating diagram
3
+ model:
4
+ reasoning_effort: 1
5
+ instructions:
6
+ url: ../../prompts/detail/d2-diagram/pre-check.md
7
+ input_schema:
8
+ type: object
9
+ properties:
10
+ documentContent:
11
+ type: string
12
+ description: Source content of the document
13
+ feedback:
14
+ type: string
15
+ description: User generation feedback
16
+ detailFeedback:
17
+ type: string
18
+ description: Current document detail feedback
19
+ previousGenerationContent:
20
+ type: string
21
+ description: Previous document content
22
+ required:
23
+ - documentContent
24
+ output_schema:
25
+ type: object
26
+ properties:
27
+ content:
28
+ type: string
29
+ description: Document content
30
+ details:
31
+ type: array
32
+ description: Detailed needDiagram score
33
+ items:
34
+ type: object
35
+ properties:
36
+ type:
37
+ type: string
38
+ score:
39
+ type: number
40
+ reason:
41
+ type: string
42
+ required:
43
+ - content
44
+
@@ -1,61 +1,67 @@
1
- type: ai
1
+ type: team
2
2
  name: updateDocumentDetail
3
3
  description: Update and optimize document content based on user feedback using diff patches
4
- instructions:
5
- - role: system
6
- url: ../../prompts/detail/update/system-prompt.md
7
- - role: user
8
- url: ../../prompts/detail/update/user-prompt.md
9
- auto_reorder_system_messages: true
10
- auto_merge_system_messages: true
11
- input_schema:
12
- type: object
13
- properties:
14
- originalContent:
15
- type: string
16
- description: Original markdown content to be updated
17
- feedback:
18
- type: string
19
- description: User feedback for content improvements
20
- rules:
21
- type: string
22
- description: User configuration rules
23
- locale:
24
- type: string
25
- description: User language, e.g. zh, en
26
- detailDataSource:
27
- type: string
28
- description: Context for document content
29
- glossary:
30
- type: string
31
- description: Glossary of terms
32
- userPreferences:
33
- type: string
34
- description: User's saved preferences for content and documentation style
35
- targetAudience:
36
- type: string
37
- description: Target audience for the documentation
38
- title:
39
- type: string
40
- description: Document title
41
- description:
42
- type: string
43
- description: Document description
44
- required:
45
- - originalContent
46
- - feedback
47
- output_key: message
48
- afs:
49
- modules:
50
- - module: system-fs
51
- options:
52
- mount: /sources
53
- path: .
54
- description: |
55
- Codebase of the project to be documented used as context for document generation,
56
- should search and read as needed while generating document content
57
- keep_text_in_tool_uses: false
58
- skills:
59
- - ./document-tools/update-document-content.mjs
60
- # - ./generate-diagram.yaml
61
4
  task_render_mode: collapse
5
+ skills:
6
+ - url: ../utils/analyze-feedback-intent.yaml
7
+ - type: ai
8
+ instructions:
9
+ - role: system
10
+ url: ../../prompts/detail/update/system-prompt.md
11
+ - role: user
12
+ url: ../../prompts/detail/update/user-prompt.md
13
+ auto_reorder_system_messages: true
14
+ auto_merge_system_messages: true
15
+ input_schema:
16
+ type: object
17
+ properties:
18
+ originalContent:
19
+ type: string
20
+ description: Original markdown content to be updated
21
+ feedback:
22
+ type: string
23
+ description: User feedback for content improvements
24
+ rules:
25
+ type: string
26
+ description: User configuration rules
27
+ locale:
28
+ type: string
29
+ description: User language, e.g. zh, en
30
+ detailDataSource:
31
+ type: string
32
+ description: Context for document content
33
+ glossary:
34
+ type: string
35
+ description: Glossary of terms
36
+ userPreferences:
37
+ type: string
38
+ description: User's saved preferences for content and documentation style
39
+ targetAudience:
40
+ type: string
41
+ description: Target audience for the documentation
42
+ title:
43
+ type: string
44
+ description: Document title
45
+ description:
46
+ type: string
47
+ description: Document description
48
+ needDataSources:
49
+ type: boolean
50
+ description: Whether data sources are needed for content modifications
51
+ required:
52
+ - originalContent
53
+ - feedback
54
+ output_key: message
55
+ afs:
56
+ modules:
57
+ - module: system-fs
58
+ options:
59
+ mount: /sources
60
+ path: .
61
+ description: |
62
+ Codebase of the project to be documented used as context for document generation,
63
+ should search and read as needed while generating document content
64
+ keep_text_in_tool_uses: false
65
+ skills:
66
+ - ./document-tools/update-document-content.mjs
67
+ # - ./generate-diagram.yaml
@@ -1,7 +1,7 @@
1
1
  type: team
2
2
  name: updateSingleDocument
3
3
  skills:
4
- - ../utils/transform-detail-datasources.mjs
4
+ - ../utils/transform-detail-data-sources.mjs
5
5
  - ../update/user-review-document.mjs
6
6
  iterate_on: selectedDocs
7
7
  concurrency: 1
@@ -132,7 +132,9 @@ export default async function userReviewDocument({ content, description, ...rest
132
132
  const title = rest.documentStructure?.find((x) => x.path === rest.path)?.title;
133
133
 
134
134
  // Print current document headings structure
135
- printDocumentHeadings(content, title || "Untitled Document");
135
+ if (!rest.isChat) {
136
+ printDocumentHeadings(content, title || "Untitled Document");
137
+ }
136
138
 
137
139
  // Initialize shared context with current content
138
140
  options.context.userContext.currentContent = content;
@@ -140,54 +142,62 @@ export default async function userReviewDocument({ content, description, ...rest
140
142
  const MAX_ITERATIONS = 100;
141
143
  const feedbacks = [];
142
144
  let iterationCount = 0;
145
+
146
+ let feedback = "";
147
+
143
148
  while (iterationCount < MAX_ITERATIONS) {
149
+ feedback = "";
144
150
  iterationCount++;
145
151
 
146
- // Ask user what they want to do
147
- const action = await options.prompts.select({
148
- message: "What would you like to do next?",
149
- choices: [
150
- {
151
- name: "View document",
152
- value: "view",
153
- },
154
- {
155
- name: "Give feedback",
156
- value: "feedback",
157
- },
158
- {
159
- name: "Done",
160
- value: "finish",
161
- },
162
- ],
163
- });
152
+ if (rest.isChat && rest.feedback) {
153
+ feedback = rest.feedback;
154
+ } else {
155
+ // Ask user what they want to do
156
+ const action = await options.prompts.select({
157
+ message: "What would you like to do next?",
158
+ choices: [
159
+ {
160
+ name: "View document",
161
+ value: "view",
162
+ },
163
+ {
164
+ name: "Give feedback",
165
+ value: "feedback",
166
+ },
167
+ {
168
+ name: "Done",
169
+ value: "finish",
170
+ },
171
+ ],
172
+ });
164
173
 
165
- if (action === "finish") {
166
- break;
167
- } else if (action === "view") {
168
- await showDocumentDetail(
169
- options.context.userContext.currentContent,
170
- title || "Untitled Document",
171
- );
172
- }
174
+ if (action === "finish") {
175
+ break;
176
+ } else if (action === "view") {
177
+ await showDocumentDetail(
178
+ options.context.userContext.currentContent,
179
+ title || "Untitled Document",
180
+ );
181
+ }
173
182
 
174
- // Ask for feedback
175
- const feedback = await options.prompts.input({
176
- message:
177
- "How would you like to improve this document?\n" +
178
- "Examples:\n" +
179
- " • Add troubleshooting section for common errors\n" +
180
- " • Simplify the explanation for beginners\n" +
181
- " • Remove the outdated information about version 1.0\n\n" +
182
- " Your feedback:",
183
- });
183
+ // Ask for feedback
184
+ feedback = await options.prompts.input({
185
+ message:
186
+ "How would you like to improve this document?\n" +
187
+ "Examples:\n" +
188
+ " • Add troubleshooting section for common errors\n" +
189
+ " • Simplify the explanation for beginners\n" +
190
+ " • Remove the outdated information about version 1.0\n\n" +
191
+ " Your feedback:",
192
+ });
184
193
 
185
- // If no feedback, finish the loop
186
- if (!feedback?.trim()) {
187
- break;
188
- }
194
+ // If no feedback, finish the loop
195
+ if (!feedback?.trim()) {
196
+ break;
197
+ }
189
198
 
190
- feedbacks.push(feedback.trim());
199
+ feedbacks.push(feedback.trim());
200
+ }
191
201
 
192
202
  // Get the updateDocument agent
193
203
  const updateAgent = options.context.agents["handleDocumentUpdate"];
@@ -208,13 +218,14 @@ export default async function userReviewDocument({ content, description, ...rest
208
218
 
209
219
  try {
210
220
  // Call updateDocument agent with feedback
211
- await options.context.invoke(updateAgent, {
221
+ const result = await options.context.invoke(updateAgent, {
212
222
  ...rest,
213
223
  originalContent: options.context.userContext.currentContent,
214
224
  feedback: feedback.trim(),
215
225
  userPreferences,
216
226
  title,
217
227
  });
228
+ options.context.userContext.currentContent = result.content;
218
229
 
219
230
  // Check if feedback should be saved as user preference
220
231
  const feedbackRefinerAgent = options.context.agents["checkFeedbackRefiner"];
@@ -235,6 +246,10 @@ export default async function userReviewDocument({ content, description, ...rest
235
246
  options.context.userContext.currentContent,
236
247
  title || "Untitled Document",
237
248
  );
249
+
250
+ if (rest.isChat) {
251
+ break;
252
+ }
238
253
  } catch (error) {
239
254
  console.error("Error processing your feedback:");
240
255
  console.error(`Type: ${error.name}`);