illuma-agents 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/LICENSE +1 -5
  2. package/dist/cjs/common/enum.cjs +1 -2
  3. package/dist/cjs/common/enum.cjs.map +1 -1
  4. package/dist/cjs/instrumentation.cjs.map +1 -1
  5. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  6. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +79 -2
  7. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  8. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  9. package/dist/cjs/llm/bedrock/index.cjs +99 -0
  10. package/dist/cjs/llm/bedrock/index.cjs.map +1 -0
  11. package/dist/cjs/llm/fake.cjs.map +1 -1
  12. package/dist/cjs/llm/providers.cjs +13 -16
  13. package/dist/cjs/llm/providers.cjs.map +1 -1
  14. package/dist/cjs/llm/text.cjs.map +1 -1
  15. package/dist/cjs/messages/core.cjs +14 -14
  16. package/dist/cjs/messages/core.cjs.map +1 -1
  17. package/dist/cjs/messages/ids.cjs.map +1 -1
  18. package/dist/cjs/messages/prune.cjs.map +1 -1
  19. package/dist/cjs/run.cjs +10 -1
  20. package/dist/cjs/run.cjs.map +1 -1
  21. package/dist/cjs/splitStream.cjs.map +1 -1
  22. package/dist/cjs/stream.cjs +4 -1
  23. package/dist/cjs/stream.cjs.map +1 -1
  24. package/dist/cjs/tools/ToolNode.cjs +10 -1
  25. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  26. package/dist/cjs/tools/handlers.cjs +29 -25
  27. package/dist/cjs/tools/handlers.cjs.map +1 -1
  28. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  29. package/dist/cjs/tools/search/content.cjs.map +1 -1
  30. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  31. package/dist/cjs/tools/search/format.cjs.map +1 -1
  32. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  33. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  34. package/dist/cjs/tools/search/schema.cjs +25 -25
  35. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  36. package/dist/cjs/tools/search/search.cjs +6 -1
  37. package/dist/cjs/tools/search/search.cjs.map +1 -1
  38. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  39. package/dist/cjs/tools/search/tool.cjs +162 -35
  40. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  41. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  42. package/dist/cjs/utils/graph.cjs.map +1 -1
  43. package/dist/cjs/utils/llm.cjs +0 -1
  44. package/dist/cjs/utils/llm.cjs.map +1 -1
  45. package/dist/cjs/utils/misc.cjs.map +1 -1
  46. package/dist/cjs/utils/run.cjs.map +1 -1
  47. package/dist/cjs/utils/title.cjs +7 -7
  48. package/dist/cjs/utils/title.cjs.map +1 -1
  49. package/dist/esm/common/enum.mjs +1 -2
  50. package/dist/esm/common/enum.mjs.map +1 -1
  51. package/dist/esm/instrumentation.mjs.map +1 -1
  52. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  53. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +79 -2
  54. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  55. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  56. package/dist/esm/llm/bedrock/index.mjs +97 -0
  57. package/dist/esm/llm/bedrock/index.mjs.map +1 -0
  58. package/dist/esm/llm/fake.mjs.map +1 -1
  59. package/dist/esm/llm/providers.mjs +2 -5
  60. package/dist/esm/llm/providers.mjs.map +1 -1
  61. package/dist/esm/llm/text.mjs.map +1 -1
  62. package/dist/esm/messages/core.mjs +14 -14
  63. package/dist/esm/messages/core.mjs.map +1 -1
  64. package/dist/esm/messages/ids.mjs.map +1 -1
  65. package/dist/esm/messages/prune.mjs.map +1 -1
  66. package/dist/esm/run.mjs +10 -1
  67. package/dist/esm/run.mjs.map +1 -1
  68. package/dist/esm/splitStream.mjs.map +1 -1
  69. package/dist/esm/stream.mjs +4 -1
  70. package/dist/esm/stream.mjs.map +1 -1
  71. package/dist/esm/tools/ToolNode.mjs +10 -1
  72. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  73. package/dist/esm/tools/handlers.mjs +30 -26
  74. package/dist/esm/tools/handlers.mjs.map +1 -1
  75. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  76. package/dist/esm/tools/search/content.mjs.map +1 -1
  77. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  78. package/dist/esm/tools/search/format.mjs.map +1 -1
  79. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  80. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  81. package/dist/esm/tools/search/schema.mjs +25 -25
  82. package/dist/esm/tools/search/schema.mjs.map +1 -1
  83. package/dist/esm/tools/search/search.mjs +6 -1
  84. package/dist/esm/tools/search/search.mjs.map +1 -1
  85. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  86. package/dist/esm/tools/search/tool.mjs +162 -35
  87. package/dist/esm/tools/search/tool.mjs.map +1 -1
  88. package/dist/esm/tools/search/utils.mjs.map +1 -1
  89. package/dist/esm/utils/graph.mjs.map +1 -1
  90. package/dist/esm/utils/llm.mjs +0 -1
  91. package/dist/esm/utils/llm.mjs.map +1 -1
  92. package/dist/esm/utils/misc.mjs.map +1 -1
  93. package/dist/esm/utils/run.mjs.map +1 -1
  94. package/dist/esm/utils/title.mjs +7 -7
  95. package/dist/esm/utils/title.mjs.map +1 -1
  96. package/dist/types/common/enum.d.ts +1 -2
  97. package/dist/types/llm/bedrock/index.d.ts +36 -0
  98. package/dist/types/tools/search/types.d.ts +2 -0
  99. package/dist/types/types/llm.d.ts +3 -8
  100. package/package.json +15 -11
  101. package/src/common/enum.ts +1 -2
  102. package/src/common/index.ts +1 -1
  103. package/src/instrumentation.ts +22 -22
  104. package/src/llm/anthropic/llm.spec.ts +1442 -1442
  105. package/src/llm/anthropic/types.ts +140 -140
  106. package/src/llm/anthropic/utils/message_inputs.ts +757 -660
  107. package/src/llm/anthropic/utils/output_parsers.ts +133 -133
  108. package/src/llm/anthropic/utils/tools.ts +29 -29
  109. package/src/llm/bedrock/index.ts +128 -0
  110. package/src/llm/fake.ts +133 -133
  111. package/src/llm/google/utils/tools.ts +160 -160
  112. package/src/llm/openai/types.ts +24 -24
  113. package/src/llm/openai/utils/isReasoningModel.test.ts +90 -90
  114. package/src/llm/providers.ts +2 -7
  115. package/src/llm/text.ts +94 -94
  116. package/src/messages/core.ts +463 -463
  117. package/src/messages/formatAgentMessages.tools.test.ts +400 -400
  118. package/src/messages/formatMessage.test.ts +693 -693
  119. package/src/messages/ids.ts +26 -26
  120. package/src/messages/prune.ts +567 -567
  121. package/src/messages/shiftIndexTokenCountMap.test.ts +81 -81
  122. package/src/mockStream.ts +98 -98
  123. package/src/prompts/collab.ts +5 -5
  124. package/src/prompts/index.ts +1 -1
  125. package/src/prompts/taskmanager.ts +61 -61
  126. package/src/run.ts +13 -4
  127. package/src/scripts/ant_web_search_edge_case.ts +162 -0
  128. package/src/scripts/ant_web_search_error_edge_case.ts +148 -0
  129. package/src/scripts/args.ts +48 -48
  130. package/src/scripts/caching.ts +123 -123
  131. package/src/scripts/code_exec_files.ts +193 -193
  132. package/src/scripts/empty_input.ts +137 -137
  133. package/src/scripts/image.ts +178 -178
  134. package/src/scripts/memory.ts +97 -97
  135. package/src/scripts/thinking.ts +149 -149
  136. package/src/specs/anthropic.simple.test.ts +67 -0
  137. package/src/specs/spec.utils.ts +3 -3
  138. package/src/specs/token-distribution-edge-case.test.ts +316 -316
  139. package/src/specs/tool-error.test.ts +193 -193
  140. package/src/splitStream.test.ts +691 -691
  141. package/src/splitStream.ts +234 -234
  142. package/src/stream.test.ts +94 -94
  143. package/src/stream.ts +4 -1
  144. package/src/tools/ToolNode.ts +12 -1
  145. package/src/tools/handlers.ts +32 -28
  146. package/src/tools/search/anthropic.ts +51 -51
  147. package/src/tools/search/content.test.ts +173 -173
  148. package/src/tools/search/content.ts +147 -147
  149. package/src/tools/search/direct-url.test.ts +530 -0
  150. package/src/tools/search/firecrawl.ts +210 -210
  151. package/src/tools/search/format.ts +250 -250
  152. package/src/tools/search/highlights.ts +320 -320
  153. package/src/tools/search/index.ts +2 -2
  154. package/src/tools/search/jina-reranker.test.ts +126 -126
  155. package/src/tools/search/output.md +2775 -2775
  156. package/src/tools/search/rerankers.ts +242 -242
  157. package/src/tools/search/schema.ts +63 -63
  158. package/src/tools/search/search.ts +766 -759
  159. package/src/tools/search/serper-scraper.ts +155 -155
  160. package/src/tools/search/test.html +883 -883
  161. package/src/tools/search/test.md +642 -642
  162. package/src/tools/search/test.ts +159 -159
  163. package/src/tools/search/tool.ts +619 -471
  164. package/src/tools/search/types.ts +689 -687
  165. package/src/tools/search/utils.ts +79 -79
  166. package/src/types/index.ts +6 -6
  167. package/src/types/llm.ts +2 -8
  168. package/src/utils/graph.ts +10 -10
  169. package/src/utils/llm.ts +26 -27
  170. package/src/utils/llmConfig.ts +5 -3
  171. package/src/utils/logging.ts +48 -48
  172. package/src/utils/misc.ts +57 -57
  173. package/src/utils/run.ts +100 -100
  174. package/src/utils/title.ts +165 -165
  175. package/dist/cjs/llm/ollama/index.cjs +0 -70
  176. package/dist/cjs/llm/ollama/index.cjs.map +0 -1
  177. package/dist/cjs/llm/ollama/utils.cjs +0 -158
  178. package/dist/cjs/llm/ollama/utils.cjs.map +0 -1
  179. package/dist/esm/llm/ollama/index.mjs +0 -68
  180. package/dist/esm/llm/ollama/index.mjs.map +0 -1
  181. package/dist/esm/llm/ollama/utils.mjs +0 -155
  182. package/dist/esm/llm/ollama/utils.mjs.map +0 -1
  183. package/dist/types/llm/ollama/index.d.ts +0 -8
  184. package/dist/types/llm/ollama/utils.d.ts +0 -7
  185. package/src/llm/ollama/index.ts +0 -92
  186. package/src/llm/ollama/utils.ts +0 -193
  187. package/src/proto/CollabGraph.ts +0 -269
  188. package/src/proto/TaskManager.ts +0 -243
  189. package/src/proto/collab.ts +0 -200
  190. package/src/proto/collab_design.ts +0 -184
  191. package/src/proto/collab_design_v2.ts +0 -224
  192. package/src/proto/collab_design_v3.ts +0 -255
  193. package/src/proto/collab_design_v4.ts +0 -220
  194. package/src/proto/collab_design_v5.ts +0 -251
  195. package/src/proto/collab_graph.ts +0 -181
  196. package/src/proto/collab_original.ts +0 -123
  197. package/src/proto/example.ts +0 -93
  198. package/src/proto/example_new.ts +0 -68
  199. package/src/proto/example_old.ts +0 -201
  200. package/src/proto/example_test.ts +0 -152
  201. package/src/proto/example_test_anthropic.ts +0 -100
  202. package/src/proto/log_stream.ts +0 -202
  203. package/src/proto/main_collab_community_event.ts +0 -133
  204. package/src/proto/main_collab_design_v2.ts +0 -96
  205. package/src/proto/main_collab_design_v4.ts +0 -100
  206. package/src/proto/main_collab_design_v5.ts +0 -135
  207. package/src/proto/main_collab_global_analysis.ts +0 -122
  208. package/src/proto/main_collab_hackathon_event.ts +0 -153
  209. package/src/proto/main_collab_space_mission.ts +0 -153
  210. package/src/proto/main_philosophy.ts +0 -210
  211. package/src/proto/original_script.ts +0 -126
  212. package/src/proto/standard.ts +0 -100
  213. package/src/proto/stream.ts +0 -56
  214. package/src/proto/tasks.ts +0 -118
  215. package/src/proto/tools/global_analysis_tools.ts +0 -86
  216. package/src/proto/tools/space_mission_tools.ts +0 -60
  217. package/src/proto/vertexai.ts +0 -54
@@ -1,159 +1,159 @@
1
- /* eslint-disable no-console */
2
- // processWikipedia.ts
3
- import * as fs from 'fs';
4
- import * as path from 'path';
5
- import { processContent } from './content';
6
-
7
- /**
8
- * Process a Wikipedia article (HTML and Markdown) and create a referenced version
9
- */
10
- async function processWikipediaArticle(): Promise<void> {
11
- try {
12
- console.log('Starting Wikipedia article processing...');
13
-
14
- // Define file paths - adapt these to your specific file locations
15
- const htmlPath = path.resolve('./test.html');
16
- const markdownPath = path.resolve('./test.md');
17
- const outputPath = path.resolve('./output.md');
18
-
19
- // Check if input files exist
20
- if (!fs.existsSync(htmlPath)) {
21
- throw new Error(`Wikipedia HTML file not found at ${htmlPath}`);
22
- }
23
-
24
- if (!fs.existsSync(markdownPath)) {
25
- throw new Error(`Wikipedia Markdown file not found at ${markdownPath}`);
26
- }
27
-
28
- console.log('Reading Wikipedia article files...');
29
- const html = fs.readFileSync(htmlPath, 'utf-8');
30
- const markdown = fs.readFileSync(markdownPath, 'utf-8');
31
-
32
- // Extract article title for logging
33
- const titleMatch = /<h1[^>]*>([^<]+)<\/h1>/i.exec(html);
34
- const articleTitle = titleMatch
35
- ? titleMatch[1].trim()
36
- : 'Wikipedia article';
37
-
38
- console.log(`Processing "${articleTitle}"...`);
39
-
40
- // Measure processing time
41
- const startTime = process.hrtime();
42
-
43
- // Process content
44
- const result = processContent(html, markdown);
45
-
46
- // Calculate processing time
47
- const elapsed = process.hrtime(startTime);
48
- const timeInMs = elapsed[0] * 1000 + elapsed[1] / 1000000;
49
-
50
- // Generate reference appendix
51
- const appendix = generateReferenceAppendix(result);
52
-
53
- // Create complete output with the processed content and appendix
54
- const completeOutput = result.markdown + appendix;
55
-
56
- // Write to output file
57
- fs.writeFileSync(outputPath, completeOutput);
58
-
59
- // Print processing statistics
60
- console.log('\nWikipedia article processing complete! ✓');
61
- console.log('-'.repeat(60));
62
- console.log(`Article: ${articleTitle}`);
63
- console.log(`Processing time: ${timeInMs.toFixed(2)}ms`);
64
- console.log('Media references replaced:');
65
- console.log(` - Links: ${result.links.length}`);
66
- console.log(` - Images: ${result.images.length}`);
67
- console.log(` - Videos: ${result.videos.length}`);
68
- console.log(
69
- ` - Total: ${result.links.length + result.images.length + result.videos.length}`
70
- );
71
- console.log(`Output saved to: ${outputPath}`);
72
- console.log('-'.repeat(60));
73
-
74
- // Print sample of the transformation
75
- const sampleLines = result.markdown.split('\n').slice(0, 10).join('\n');
76
- console.log('\nSample of transformed content:');
77
- console.log('-'.repeat(30));
78
- console.log(sampleLines);
79
- console.log('-'.repeat(30));
80
- console.log('... (continued in output file)');
81
- } catch (error) {
82
- console.error('Error processing Wikipedia article:', error);
83
- process.exit(1);
84
- }
85
- }
86
-
87
- /**
88
- * Generate a comprehensive reference appendix with all media links
89
- */
90
- function generateReferenceAppendix(result: {
91
- links: Array<{ originalUrl: string; title?: string; text?: string }>;
92
- images: Array<{ originalUrl: string; title?: string }>;
93
- videos: Array<{ originalUrl: string; title?: string }>;
94
- }): string {
95
- let appendix = '\n\n' + '---'.repeat(10) + '\n\n';
96
- appendix += '# References\n\n';
97
-
98
- if (result.links.length > 0) {
99
- appendix += '## Links\n\n';
100
- result.links.forEach((link, index) => {
101
- // Clean and format text for display
102
- let displayText = '';
103
- if (link.text != null && link.text.trim()) {
104
- // Limit length for very long link text
105
- let cleanText = link.text.trim();
106
- if (cleanText.length > 50) {
107
- cleanText = cleanText.substring(0, 47) + '...';
108
- }
109
- displayText = ` - "${cleanText}"`;
110
- }
111
-
112
- appendix += `**link#${index + 1}**: ${link.originalUrl}${displayText}\n\n`;
113
- });
114
- }
115
-
116
- if (result.images.length > 0) {
117
- appendix += '## Images\n\n';
118
- result.images.forEach((image, index) => {
119
- const displayTitle =
120
- image.title != null && image.title.trim()
121
- ? ` - ${image.title.trim()}`
122
- : '';
123
- appendix += `**image#${index + 1}**: ${image.originalUrl}${displayTitle}\n\n`;
124
- });
125
- }
126
-
127
- if (result.videos.length > 0) {
128
- appendix += '## Videos\n\n';
129
- result.videos.forEach((video, index) => {
130
- const displayTitle =
131
- video.title != null && video.title.trim()
132
- ? ` - ${video.title.trim()}`
133
- : '';
134
- appendix += `**video#${index + 1}**: ${video.originalUrl}${displayTitle}\n\n`;
135
- });
136
- }
137
-
138
- // Add a category breakdown to show what types of links were found
139
- const totalRefs =
140
- result.links.length + result.images.length + result.videos.length;
141
-
142
- appendix += '## Summary\n\n';
143
- appendix += `Total references: **${totalRefs}**\n\n`;
144
- appendix += `- Links: ${result.links.length}\n`;
145
- appendix += `- Images: ${result.images.length}\n`;
146
- appendix += `- Videos: ${result.videos.length}\n`;
147
-
148
- return appendix;
149
- }
150
-
151
- // Using async IIFE to allow for better error handling
152
- (async (): Promise<void> => {
153
- try {
154
- await processWikipediaArticle();
155
- } catch (error) {
156
- console.error('Unhandled error:', error);
157
- process.exit(1);
158
- }
159
- })();
1
+ /* eslint-disable no-console */
2
+ // processWikipedia.ts
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import { processContent } from './content';
6
+
7
+ /**
8
+ * Process a Wikipedia article (HTML and Markdown) and create a referenced version
9
+ */
10
+ async function processWikipediaArticle(): Promise<void> {
11
+ try {
12
+ console.log('Starting Wikipedia article processing...');
13
+
14
+ // Define file paths - adapt these to your specific file locations
15
+ const htmlPath = path.resolve('./test.html');
16
+ const markdownPath = path.resolve('./test.md');
17
+ const outputPath = path.resolve('./output.md');
18
+
19
+ // Check if input files exist
20
+ if (!fs.existsSync(htmlPath)) {
21
+ throw new Error(`Wikipedia HTML file not found at ${htmlPath}`);
22
+ }
23
+
24
+ if (!fs.existsSync(markdownPath)) {
25
+ throw new Error(`Wikipedia Markdown file not found at ${markdownPath}`);
26
+ }
27
+
28
+ console.log('Reading Wikipedia article files...');
29
+ const html = fs.readFileSync(htmlPath, 'utf-8');
30
+ const markdown = fs.readFileSync(markdownPath, 'utf-8');
31
+
32
+ // Extract article title for logging
33
+ const titleMatch = /<h1[^>]*>([^<]+)<\/h1>/i.exec(html);
34
+ const articleTitle = titleMatch
35
+ ? titleMatch[1].trim()
36
+ : 'Wikipedia article';
37
+
38
+ console.log(`Processing "${articleTitle}"...`);
39
+
40
+ // Measure processing time
41
+ const startTime = process.hrtime();
42
+
43
+ // Process content
44
+ const result = processContent(html, markdown);
45
+
46
+ // Calculate processing time
47
+ const elapsed = process.hrtime(startTime);
48
+ const timeInMs = elapsed[0] * 1000 + elapsed[1] / 1000000;
49
+
50
+ // Generate reference appendix
51
+ const appendix = generateReferenceAppendix(result);
52
+
53
+ // Create complete output with the processed content and appendix
54
+ const completeOutput = result.markdown + appendix;
55
+
56
+ // Write to output file
57
+ fs.writeFileSync(outputPath, completeOutput);
58
+
59
+ // Print processing statistics
60
+ console.log('\nWikipedia article processing complete! ✓');
61
+ console.log('-'.repeat(60));
62
+ console.log(`Article: ${articleTitle}`);
63
+ console.log(`Processing time: ${timeInMs.toFixed(2)}ms`);
64
+ console.log('Media references replaced:');
65
+ console.log(` - Links: ${result.links.length}`);
66
+ console.log(` - Images: ${result.images.length}`);
67
+ console.log(` - Videos: ${result.videos.length}`);
68
+ console.log(
69
+ ` - Total: ${result.links.length + result.images.length + result.videos.length}`
70
+ );
71
+ console.log(`Output saved to: ${outputPath}`);
72
+ console.log('-'.repeat(60));
73
+
74
+ // Print sample of the transformation
75
+ const sampleLines = result.markdown.split('\n').slice(0, 10).join('\n');
76
+ console.log('\nSample of transformed content:');
77
+ console.log('-'.repeat(30));
78
+ console.log(sampleLines);
79
+ console.log('-'.repeat(30));
80
+ console.log('... (continued in output file)');
81
+ } catch (error) {
82
+ console.error('Error processing Wikipedia article:', error);
83
+ process.exit(1);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Generate a comprehensive reference appendix with all media links
89
+ */
90
+ function generateReferenceAppendix(result: {
91
+ links: Array<{ originalUrl: string; title?: string; text?: string }>;
92
+ images: Array<{ originalUrl: string; title?: string }>;
93
+ videos: Array<{ originalUrl: string; title?: string }>;
94
+ }): string {
95
+ let appendix = '\n\n' + '---'.repeat(10) + '\n\n';
96
+ appendix += '# References\n\n';
97
+
98
+ if (result.links.length > 0) {
99
+ appendix += '## Links\n\n';
100
+ result.links.forEach((link, index) => {
101
+ // Clean and format text for display
102
+ let displayText = '';
103
+ if (link.text != null && link.text.trim()) {
104
+ // Limit length for very long link text
105
+ let cleanText = link.text.trim();
106
+ if (cleanText.length > 50) {
107
+ cleanText = cleanText.substring(0, 47) + '...';
108
+ }
109
+ displayText = ` - "${cleanText}"`;
110
+ }
111
+
112
+ appendix += `**link#${index + 1}**: ${link.originalUrl}${displayText}\n\n`;
113
+ });
114
+ }
115
+
116
+ if (result.images.length > 0) {
117
+ appendix += '## Images\n\n';
118
+ result.images.forEach((image, index) => {
119
+ const displayTitle =
120
+ image.title != null && image.title.trim()
121
+ ? ` - ${image.title.trim()}`
122
+ : '';
123
+ appendix += `**image#${index + 1}**: ${image.originalUrl}${displayTitle}\n\n`;
124
+ });
125
+ }
126
+
127
+ if (result.videos.length > 0) {
128
+ appendix += '## Videos\n\n';
129
+ result.videos.forEach((video, index) => {
130
+ const displayTitle =
131
+ video.title != null && video.title.trim()
132
+ ? ` - ${video.title.trim()}`
133
+ : '';
134
+ appendix += `**video#${index + 1}**: ${video.originalUrl}${displayTitle}\n\n`;
135
+ });
136
+ }
137
+
138
+ // Add a category breakdown to show what types of links were found
139
+ const totalRefs =
140
+ result.links.length + result.images.length + result.videos.length;
141
+
142
+ appendix += '## Summary\n\n';
143
+ appendix += `Total references: **${totalRefs}**\n\n`;
144
+ appendix += `- Links: ${result.links.length}\n`;
145
+ appendix += `- Images: ${result.images.length}\n`;
146
+ appendix += `- Videos: ${result.videos.length}\n`;
147
+
148
+ return appendix;
149
+ }
150
+
151
+ // Using async IIFE to allow for better error handling
152
+ (async (): Promise<void> => {
153
+ try {
154
+ await processWikipediaArticle();
155
+ } catch (error) {
156
+ console.error('Unhandled error:', error);
157
+ process.exit(1);
158
+ }
159
+ })();