@redigg/redigg 0.1.0

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 (322) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +145 -0
  3. package/dist/agent/ResearchAgent.d.ts +35 -0
  4. package/dist/agent/ResearchAgent.js +818 -0
  5. package/dist/agent/ResearchAgent.js.map +1 -0
  6. package/dist/agent/subagent/SubAgent.d.ts +23 -0
  7. package/dist/agent/subagent/SubAgent.js +87 -0
  8. package/dist/agent/subagent/SubAgent.js.map +1 -0
  9. package/dist/agent/subagent/SubAgentManager.d.ts +19 -0
  10. package/dist/agent/subagent/SubAgentManager.js +40 -0
  11. package/dist/agent/subagent/SubAgentManager.js.map +1 -0
  12. package/dist/bin.d.ts +2 -0
  13. package/dist/bin.js +34 -0
  14. package/dist/bin.js.map +1 -0
  15. package/dist/cli.d.ts +1 -0
  16. package/dist/cli.js +179 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/events/EventManager.d.ts +39 -0
  19. package/dist/events/EventManager.js +20 -0
  20. package/dist/events/EventManager.js.map +1 -0
  21. package/dist/gateway/index.d.ts +9 -0
  22. package/dist/gateway/index.js +474 -0
  23. package/dist/gateway/index.js.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.js +97 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/llm/LLMClient.d.ts +30 -0
  28. package/dist/llm/LLMClient.js +21 -0
  29. package/dist/llm/LLMClient.js.map +1 -0
  30. package/dist/llm/OpenAIClient.d.ts +16 -0
  31. package/dist/llm/OpenAIClient.js +58 -0
  32. package/dist/llm/OpenAIClient.js.map +1 -0
  33. package/dist/memory/MemoryManager.d.ts +41 -0
  34. package/dist/memory/MemoryManager.js +221 -0
  35. package/dist/memory/MemoryManager.js.map +1 -0
  36. package/dist/memory/evolution/MemoryEvolutionSystem.d.ts +17 -0
  37. package/dist/memory/evolution/MemoryEvolutionSystem.js +71 -0
  38. package/dist/memory/evolution/MemoryEvolutionSystem.js.map +1 -0
  39. package/dist/memory/search/BM25Search.d.ts +22 -0
  40. package/dist/memory/search/BM25Search.js +61 -0
  41. package/dist/memory/search/BM25Search.js.map +1 -0
  42. package/dist/memory/structure/PageIndex.d.ts +26 -0
  43. package/dist/memory/structure/PageIndex.js +156 -0
  44. package/dist/memory/structure/PageIndex.js.map +1 -0
  45. package/dist/quality/QualityManager.d.ts +12 -0
  46. package/dist/quality/QualityManager.js +61 -0
  47. package/dist/quality/QualityManager.js.map +1 -0
  48. package/dist/scheduling/CronManager.d.ts +21 -0
  49. package/dist/scheduling/CronManager.js +66 -0
  50. package/dist/scheduling/CronManager.js.map +1 -0
  51. package/dist/session/SessionManager.d.ts +37 -0
  52. package/dist/session/SessionManager.js +238 -0
  53. package/dist/session/SessionManager.js.map +1 -0
  54. package/dist/skills/SkillManager.d.ts +31 -0
  55. package/dist/skills/SkillManager.js +254 -0
  56. package/dist/skills/SkillManager.js.map +1 -0
  57. package/dist/skills/agent/PACK.md +13 -0
  58. package/dist/skills/agent/agent-orchestration/SKILL.md +37 -0
  59. package/dist/skills/agent/agent-orchestration/index.d.ts +9 -0
  60. package/dist/skills/agent/agent-orchestration/index.js +70 -0
  61. package/dist/skills/agent/agent-orchestration/index.js.map +1 -0
  62. package/dist/skills/agent/evolution/SKILL.md +25 -0
  63. package/dist/skills/agent/evolution/index.d.ts +9 -0
  64. package/dist/skills/agent/evolution/index.js +57 -0
  65. package/dist/skills/agent/evolution/index.js.map +1 -0
  66. package/dist/skills/agent/heartbeat/index.d.ts +8 -0
  67. package/dist/skills/agent/heartbeat/index.js +44 -0
  68. package/dist/skills/agent/heartbeat/index.js.map +1 -0
  69. package/dist/skills/agent/memory-management/SKILL.md +40 -0
  70. package/dist/skills/agent/memory-management/index.d.ts +8 -0
  71. package/dist/skills/agent/memory-management/index.js +44 -0
  72. package/dist/skills/agent/memory-management/index.js.map +1 -0
  73. package/dist/skills/agent/scheduling/SKILL.md +33 -0
  74. package/dist/skills/agent/scheduling/index.d.ts +13 -0
  75. package/dist/skills/agent/scheduling/index.js +80 -0
  76. package/dist/skills/agent/scheduling/index.js.map +1 -0
  77. package/dist/skills/agent/session-management/SKILL.md +35 -0
  78. package/dist/skills/agent/session-management/index.d.ts +11 -0
  79. package/dist/skills/agent/session-management/index.js +54 -0
  80. package/dist/skills/agent/session-management/index.js.map +1 -0
  81. package/dist/skills/agent/skill-management/SKILL.md +31 -0
  82. package/dist/skills/agent/skill-management/index.d.ts +8 -0
  83. package/dist/skills/agent/skill-management/index.js +25 -0
  84. package/dist/skills/agent/skill-management/index.js.map +1 -0
  85. package/dist/skills/evolution/SkillEvolutionSystem.d.ts +12 -0
  86. package/dist/skills/evolution/SkillEvolutionSystem.js +157 -0
  87. package/dist/skills/evolution/SkillEvolutionSystem.js.map +1 -0
  88. package/dist/skills/lib/ScholarTool.d.ts +14 -0
  89. package/dist/skills/lib/ScholarTool.js +71 -0
  90. package/dist/skills/lib/ScholarTool.js.map +1 -0
  91. package/dist/skills/research/PACK.md +7 -0
  92. package/dist/skills/research/academic-survey-self-improve/SKILL.md +17 -0
  93. package/dist/skills/research/academic-survey-self-improve/index.d.ts +10 -0
  94. package/dist/skills/research/academic-survey-self-improve/index.js +75 -0
  95. package/dist/skills/research/academic-survey-self-improve/index.js.map +1 -0
  96. package/dist/skills/research/concept-explainer/SKILL.md +3 -0
  97. package/dist/skills/research/concept-explainer/index.d.ts +8 -0
  98. package/dist/skills/research/concept-explainer/index.js +37 -0
  99. package/dist/skills/research/concept-explainer/index.js.map +1 -0
  100. package/dist/skills/research/literature-review/SKILL.md +25 -0
  101. package/dist/skills/research/literature-review/index.d.ts +9 -0
  102. package/dist/skills/research/literature-review/index.js +132 -0
  103. package/dist/skills/research/literature-review/index.js.map +1 -0
  104. package/dist/skills/research/paper-analysis/SKILL.md +3 -0
  105. package/dist/skills/research/paper-analysis/index.d.ts +9 -0
  106. package/dist/skills/research/paper-analysis/index.js +64 -0
  107. package/dist/skills/research/paper-analysis/index.js.map +1 -0
  108. package/dist/skills/research/pdf-generator/SKILL.md +16 -0
  109. package/dist/skills/research/pdf-generator/index.d.ts +10 -0
  110. package/dist/skills/research/pdf-generator/index.js +88 -0
  111. package/dist/skills/research/pdf-generator/index.js.map +1 -0
  112. package/dist/skills/system/PACK.md +8 -0
  113. package/dist/skills/system/code-analysis/SKILL.md +43 -0
  114. package/dist/skills/system/code-analysis/index.d.ts +12 -0
  115. package/dist/skills/system/code-analysis/index.js +172 -0
  116. package/dist/skills/system/code-analysis/index.js.map +1 -0
  117. package/dist/skills/system/local-file-ops/SKILL.md +55 -0
  118. package/dist/skills/system/local-file-ops/index.d.ts +9 -0
  119. package/dist/skills/system/local-file-ops/index.js +111 -0
  120. package/dist/skills/system/local-file-ops/index.js.map +1 -0
  121. package/dist/skills/types.d.ts +41 -0
  122. package/dist/skills/types.js +2 -0
  123. package/dist/skills/types.js.map +1 -0
  124. package/dist/skills/vendor/PACK.md +11 -0
  125. package/dist/skills/vendor/agent-browser/CONTRIBUTING.md +63 -0
  126. package/dist/skills/vendor/agent-browser/SKILL.md +328 -0
  127. package/dist/skills/vendor/find-skills/SKILL.md +133 -0
  128. package/dist/skills/vendor/proactive-agent/SKILL-v2.3-backup.md +554 -0
  129. package/dist/skills/vendor/proactive-agent/SKILL-v3-draft.md +499 -0
  130. package/dist/skills/vendor/proactive-agent/SKILL.md +632 -0
  131. package/dist/skills/vendor/proactive-agent/assets/AGENTS.md +155 -0
  132. package/dist/skills/vendor/proactive-agent/assets/HEARTBEAT.md +128 -0
  133. package/dist/skills/vendor/proactive-agent/assets/MEMORY.md +47 -0
  134. package/dist/skills/vendor/proactive-agent/assets/ONBOARDING.md +103 -0
  135. package/dist/skills/vendor/proactive-agent/assets/SOUL.md +40 -0
  136. package/dist/skills/vendor/proactive-agent/assets/TOOLS.md +55 -0
  137. package/dist/skills/vendor/proactive-agent/assets/USER.md +36 -0
  138. package/dist/skills/vendor/proactive-agent/references/onboarding-flow.md +158 -0
  139. package/dist/skills/vendor/proactive-agent/references/security-patterns.md +109 -0
  140. package/dist/skills/vendor/searxng/CHANGELOG.md +38 -0
  141. package/dist/skills/vendor/searxng/PUBLISH.md +147 -0
  142. package/dist/skills/vendor/searxng/PUBLISHING_CHECKLIST.md +111 -0
  143. package/dist/skills/vendor/searxng/README.md +168 -0
  144. package/dist/skills/vendor/searxng/SKILL.md +69 -0
  145. package/dist/skills/vendor/self-improving-agent/.learnings/ERRORS.md +5 -0
  146. package/dist/skills/vendor/self-improving-agent/.learnings/FEATURE_REQUESTS.md +5 -0
  147. package/dist/skills/vendor/self-improving-agent/.learnings/LEARNINGS.md +5 -0
  148. package/dist/skills/vendor/self-improving-agent/SKILL.md +647 -0
  149. package/dist/skills/vendor/self-improving-agent/assets/LEARNINGS.md +45 -0
  150. package/dist/skills/vendor/self-improving-agent/assets/SKILL-TEMPLATE.md +177 -0
  151. package/dist/skills/vendor/self-improving-agent/hooks/openclaw/HOOK.md +23 -0
  152. package/dist/skills/vendor/self-improving-agent/hooks/openclaw/handler.d.ts +9 -0
  153. package/dist/skills/vendor/self-improving-agent/hooks/openclaw/handler.js +54 -0
  154. package/dist/skills/vendor/self-improving-agent/hooks/openclaw/handler.js.map +1 -0
  155. package/dist/skills/vendor/self-improving-agent/references/examples.md +374 -0
  156. package/dist/skills/vendor/self-improving-agent/references/hooks-setup.md +223 -0
  157. package/dist/skills/vendor/self-improving-agent/references/openclaw-integration.md +248 -0
  158. package/dist/skills/vendor/skill-vetter/SKILL.md +138 -0
  159. package/dist/src/agent/ResearchAgent.d.ts +35 -0
  160. package/dist/src/agent/ResearchAgent.js +818 -0
  161. package/dist/src/agent/ResearchAgent.js.map +1 -0
  162. package/dist/src/agent/subagent/SubAgent.d.ts +23 -0
  163. package/dist/src/agent/subagent/SubAgent.js +87 -0
  164. package/dist/src/agent/subagent/SubAgent.js.map +1 -0
  165. package/dist/src/agent/subagent/SubAgentManager.d.ts +19 -0
  166. package/dist/src/agent/subagent/SubAgentManager.js +40 -0
  167. package/dist/src/agent/subagent/SubAgentManager.js.map +1 -0
  168. package/dist/src/bin.d.ts +2 -0
  169. package/dist/src/bin.js +34 -0
  170. package/dist/src/bin.js.map +1 -0
  171. package/dist/src/cli.d.ts +1 -0
  172. package/dist/src/cli.js +179 -0
  173. package/dist/src/cli.js.map +1 -0
  174. package/dist/src/events/EventManager.d.ts +39 -0
  175. package/dist/src/events/EventManager.js +20 -0
  176. package/dist/src/events/EventManager.js.map +1 -0
  177. package/dist/src/gateway/index.d.ts +9 -0
  178. package/dist/src/gateway/index.js +474 -0
  179. package/dist/src/gateway/index.js.map +1 -0
  180. package/dist/src/index.d.ts +3 -0
  181. package/dist/src/index.js +105 -0
  182. package/dist/src/index.js.map +1 -0
  183. package/dist/src/llm/LLMClient.d.ts +30 -0
  184. package/dist/src/llm/LLMClient.js +21 -0
  185. package/dist/src/llm/LLMClient.js.map +1 -0
  186. package/dist/src/llm/OpenAIClient.d.ts +16 -0
  187. package/dist/src/llm/OpenAIClient.js +58 -0
  188. package/dist/src/llm/OpenAIClient.js.map +1 -0
  189. package/dist/src/memory/MemoryManager.d.ts +41 -0
  190. package/dist/src/memory/MemoryManager.js +221 -0
  191. package/dist/src/memory/MemoryManager.js.map +1 -0
  192. package/dist/src/memory/evolution/MemoryEvolutionSystem.d.ts +17 -0
  193. package/dist/src/memory/evolution/MemoryEvolutionSystem.js +71 -0
  194. package/dist/src/memory/evolution/MemoryEvolutionSystem.js.map +1 -0
  195. package/dist/src/memory/search/BM25Search.d.ts +22 -0
  196. package/dist/src/memory/search/BM25Search.js +61 -0
  197. package/dist/src/memory/search/BM25Search.js.map +1 -0
  198. package/dist/src/memory/structure/PageIndex.d.ts +26 -0
  199. package/dist/src/memory/structure/PageIndex.js +156 -0
  200. package/dist/src/memory/structure/PageIndex.js.map +1 -0
  201. package/dist/src/quality/QualityManager.d.ts +12 -0
  202. package/dist/src/quality/QualityManager.js +61 -0
  203. package/dist/src/quality/QualityManager.js.map +1 -0
  204. package/dist/src/scheduling/CronManager.d.ts +21 -0
  205. package/dist/src/scheduling/CronManager.js +66 -0
  206. package/dist/src/scheduling/CronManager.js.map +1 -0
  207. package/dist/src/session/SessionManager.d.ts +37 -0
  208. package/dist/src/session/SessionManager.js +238 -0
  209. package/dist/src/session/SessionManager.js.map +1 -0
  210. package/dist/src/skills/SkillManager.d.ts +33 -0
  211. package/dist/src/skills/SkillManager.js +260 -0
  212. package/dist/src/skills/SkillManager.js.map +1 -0
  213. package/dist/src/skills/evolution/SkillEvolutionSystem.d.ts +12 -0
  214. package/dist/src/skills/evolution/SkillEvolutionSystem.js +157 -0
  215. package/dist/src/skills/evolution/SkillEvolutionSystem.js.map +1 -0
  216. package/dist/src/skills/lib/ScholarTool.d.ts +14 -0
  217. package/dist/src/skills/lib/ScholarTool.js +71 -0
  218. package/dist/src/skills/lib/ScholarTool.js.map +1 -0
  219. package/dist/src/skills/types.d.ts +41 -0
  220. package/dist/src/skills/types.js +2 -0
  221. package/dist/src/skills/types.js.map +1 -0
  222. package/dist/src/storage/sqlite.d.ts +8 -0
  223. package/dist/src/storage/sqlite.js +73 -0
  224. package/dist/src/storage/sqlite.js.map +1 -0
  225. package/dist/src/utils/logger.d.ts +12 -0
  226. package/dist/src/utils/logger.js +53 -0
  227. package/dist/src/utils/logger.js.map +1 -0
  228. package/dist/storage/sqlite.d.ts +8 -0
  229. package/dist/storage/sqlite.js +73 -0
  230. package/dist/storage/sqlite.js.map +1 -0
  231. package/dist/utils/logger.d.ts +12 -0
  232. package/dist/utils/logger.js +53 -0
  233. package/dist/utils/logger.js.map +1 -0
  234. package/package.json +71 -0
  235. package/skills/agent/PACK.md +13 -0
  236. package/skills/agent/agent-orchestration/SKILL.md +37 -0
  237. package/skills/agent/agent-orchestration/index.ts +84 -0
  238. package/skills/agent/evolution/SKILL.md +25 -0
  239. package/skills/agent/evolution/index.ts +67 -0
  240. package/skills/agent/heartbeat/index.ts +48 -0
  241. package/skills/agent/memory-management/SKILL.md +40 -0
  242. package/skills/agent/memory-management/index.ts +48 -0
  243. package/skills/agent/scheduling/SKILL.md +33 -0
  244. package/skills/agent/scheduling/index.ts +97 -0
  245. package/skills/agent/session-management/SKILL.md +35 -0
  246. package/skills/agent/session-management/index.ts +65 -0
  247. package/skills/agent/skill-management/SKILL.md +31 -0
  248. package/skills/agent/skill-management/index.ts +32 -0
  249. package/skills/research/PACK.md +7 -0
  250. package/skills/research/academic-survey-self-improve/SKILL.md +17 -0
  251. package/skills/research/academic-survey-self-improve/index.ts +87 -0
  252. package/skills/research/concept-explainer/SKILL.md +3 -0
  253. package/skills/research/concept-explainer/index.ts +42 -0
  254. package/skills/research/literature-review/SKILL.md +25 -0
  255. package/skills/research/literature-review/index.ts +168 -0
  256. package/skills/research/paper-analysis/SKILL.md +3 -0
  257. package/skills/research/paper-analysis/index.ts +73 -0
  258. package/skills/research/pdf-generator/SKILL.md +16 -0
  259. package/skills/research/pdf-generator/index.d.ts +10 -0
  260. package/skills/research/pdf-generator/index.js +114 -0
  261. package/skills/research/pdf-generator/index.js.map +1 -0
  262. package/skills/research/pdf-generator/index.ts +97 -0
  263. package/skills/system/PACK.md +8 -0
  264. package/skills/system/code-analysis/SKILL.md +43 -0
  265. package/skills/system/code-analysis/index.ts +180 -0
  266. package/skills/system/local-file-ops/SKILL.md +55 -0
  267. package/skills/system/local-file-ops/index.ts +123 -0
  268. package/skills/vendor/PACK.md +11 -0
  269. package/skills/vendor/agent-browser/.clawhub/origin.json +7 -0
  270. package/skills/vendor/agent-browser/CONTRIBUTING.md +63 -0
  271. package/skills/vendor/agent-browser/SKILL.md +328 -0
  272. package/skills/vendor/agent-browser/_meta.json +6 -0
  273. package/skills/vendor/find-skills/.clawhub/origin.json +7 -0
  274. package/skills/vendor/find-skills/SKILL.md +133 -0
  275. package/skills/vendor/find-skills/_meta.json +6 -0
  276. package/skills/vendor/proactive-agent/.clawhub/origin.json +7 -0
  277. package/skills/vendor/proactive-agent/SKILL-v2.3-backup.md +554 -0
  278. package/skills/vendor/proactive-agent/SKILL-v3-draft.md +499 -0
  279. package/skills/vendor/proactive-agent/SKILL.md +632 -0
  280. package/skills/vendor/proactive-agent/_meta.json +6 -0
  281. package/skills/vendor/proactive-agent/assets/AGENTS.md +155 -0
  282. package/skills/vendor/proactive-agent/assets/HEARTBEAT.md +128 -0
  283. package/skills/vendor/proactive-agent/assets/MEMORY.md +47 -0
  284. package/skills/vendor/proactive-agent/assets/ONBOARDING.md +103 -0
  285. package/skills/vendor/proactive-agent/assets/SOUL.md +40 -0
  286. package/skills/vendor/proactive-agent/assets/TOOLS.md +55 -0
  287. package/skills/vendor/proactive-agent/assets/USER.md +36 -0
  288. package/skills/vendor/proactive-agent/references/onboarding-flow.md +158 -0
  289. package/skills/vendor/proactive-agent/references/security-patterns.md +109 -0
  290. package/skills/vendor/proactive-agent/scripts/security-audit.sh +149 -0
  291. package/skills/vendor/searxng/.clawdhub/origin.json +7 -0
  292. package/skills/vendor/searxng/CHANGELOG.md +38 -0
  293. package/skills/vendor/searxng/PUBLISH.md +147 -0
  294. package/skills/vendor/searxng/PUBLISHING_CHECKLIST.md +111 -0
  295. package/skills/vendor/searxng/README.md +168 -0
  296. package/skills/vendor/searxng/SKILL.md +69 -0
  297. package/skills/vendor/searxng/_meta.json +6 -0
  298. package/skills/vendor/searxng/config/settings.yml +36 -0
  299. package/skills/vendor/searxng/run-searxng.sh +48 -0
  300. package/skills/vendor/searxng/scripts/searxng.py +211 -0
  301. package/skills/vendor/self-improving-agent/.clawhub/origin.json +7 -0
  302. package/skills/vendor/self-improving-agent/.learnings/ERRORS.md +5 -0
  303. package/skills/vendor/self-improving-agent/.learnings/FEATURE_REQUESTS.md +5 -0
  304. package/skills/vendor/self-improving-agent/.learnings/LEARNINGS.md +5 -0
  305. package/skills/vendor/self-improving-agent/SKILL.md +647 -0
  306. package/skills/vendor/self-improving-agent/_meta.json +6 -0
  307. package/skills/vendor/self-improving-agent/assets/LEARNINGS.md +45 -0
  308. package/skills/vendor/self-improving-agent/assets/SKILL-TEMPLATE.md +177 -0
  309. package/skills/vendor/self-improving-agent/hooks/openclaw/HOOK.md +23 -0
  310. package/skills/vendor/self-improving-agent/hooks/openclaw/handler.js +56 -0
  311. package/skills/vendor/self-improving-agent/hooks/openclaw/handler.ts +62 -0
  312. package/skills/vendor/self-improving-agent/references/examples.md +374 -0
  313. package/skills/vendor/self-improving-agent/references/hooks-setup.md +223 -0
  314. package/skills/vendor/self-improving-agent/references/openclaw-integration.md +248 -0
  315. package/skills/vendor/self-improving-agent/scripts/activator.sh +20 -0
  316. package/skills/vendor/self-improving-agent/scripts/error-detector.sh +55 -0
  317. package/skills/vendor/self-improving-agent/scripts/extract-skill.sh +221 -0
  318. package/skills/vendor/skill-vetter/.clawhub/origin.json +7 -0
  319. package/skills/vendor/skill-vetter/SKILL.md +138 -0
  320. package/skills/vendor/skill-vetter/_meta.json +6 -0
  321. package/web/README.md +73 -0
  322. package/web/package.json +65 -0
@@ -0,0 +1,168 @@
1
+ import { Skill, SkillContext, SkillParams, SkillResult } from '../../../src/skills/types.js';
2
+ import { ScholarTool } from '../../../src/skills/lib/ScholarTool.js';
3
+ import chalk from 'chalk';
4
+
5
+ export default class LiteratureReviewSkill implements Skill {
6
+ id = 'literature_review';
7
+ name = 'Literature Review';
8
+ description = 'Search for papers and generate a literature review';
9
+ tags = ['research', 'literature', 'review'];
10
+
11
+ private scholar = new ScholarTool();
12
+
13
+ async execute(ctx: SkillContext, params: SkillParams): Promise<SkillResult> {
14
+ const topic = params.topic;
15
+ if (!topic) {
16
+ throw new Error('Topic is required');
17
+ }
18
+
19
+ ctx.log('thinking', `Starting literature review on topic: ${topic}`);
20
+
21
+ if (ctx.updateProgress) {
22
+ await ctx.updateProgress(10, `Starting literature review on ${topic}`);
23
+ }
24
+
25
+ // 1. Search Papers
26
+ ctx.log('action', 'Initializing academic search');
27
+ ctx.log('tool_call', 'Searching for papers', {
28
+ tool_name: 'ScholarSearch',
29
+ tool_args: { topic, limit: 5 }
30
+ });
31
+
32
+ const papers = await this.scholar.searchPapers(topic, 5);
33
+
34
+ ctx.log('tool_result', `Found ${papers.length} relevant papers`, {
35
+ tool_name: 'ScholarSearch',
36
+ papers_count: papers.length
37
+ });
38
+
39
+ if (ctx.updateProgress) {
40
+ await ctx.updateProgress(50, `Found ${papers.length} papers, analyzing...`);
41
+ }
42
+
43
+ // 2. Add to Memory (Memory Injection)
44
+ for (const paper of papers) {
45
+ // Simulate memory addition (in a real scenario, this would persist the paper as a memory)
46
+ // Actually, we can use ctx.memory.addPaper() if available, but SkillContext might not have it directly exposed as `addPaper` if it's generic
47
+ // But we have `memory` which is `MemoryManager`, so we can call it.
48
+ if (ctx.memory && typeof (ctx.memory as any).addPaper === 'function') {
49
+ await (ctx.memory as any).addPaper(
50
+ ctx.userId,
51
+ paper.title,
52
+ paper.authors,
53
+ paper.url,
54
+ paper.summary
55
+ );
56
+ }
57
+ }
58
+
59
+ // 3. Generate Summary
60
+ ctx.log('thinking', 'Synthesizing literature review');
61
+
62
+ if (ctx.updateProgress) {
63
+ await ctx.updateProgress(75, 'Synthesizing literature review...');
64
+ }
65
+
66
+ const prompt = `
67
+ You are a rigorous academic researcher.
68
+ Write a literature review summary based on the following papers about "${topic}".
69
+
70
+ CRITICAL INSTRUCTIONS:
71
+ 1. ONLY cite papers that are directly relevant to the user's topic.
72
+ 2. If a paper in the list below is irrelevant, ignore it completely.
73
+ 3. At the end of your summary, provide a "Selected Sources" list containing ONLY the papers you actually used/cited in the text.
74
+ 4. Do not include a "Sources" list if you didn't use any.
75
+
76
+ Available Papers:
77
+ ${papers.map((p, i) => `[${i+1}] ${p.title} (${p.year}): ${p.summary}`).join('\n')}
78
+
79
+ Output Format:
80
+ <Summary text with inline citations like [1]>
81
+
82
+ **Selected Sources:**
83
+ [1] Title (Year)
84
+ ...
85
+ `;
86
+
87
+ const summaryResponse = await ctx.llm.complete(prompt);
88
+ const summary = summaryResponse.content;
89
+
90
+ // Parse the LLM response to extract the actually used papers
91
+ // This is a heuristic: we trust the LLM's "Selected Sources" list or we could parse inline citations.
92
+ // For now, let's rely on the LLM's output for the summary, but we need to filter the `papers` array returned in result
93
+ // to match what the user sees.
94
+
95
+ // Actually, the `ResearchAgent.ts` constructs the final response string using `result.papers`.
96
+ // So we should update `result.papers` to only include relevant ones.
97
+
98
+ // Let's ask the LLM to output a JSON list of indices of used papers to be precise.
99
+
100
+ const promptRefinement = `
101
+ Based on the summary you just wrote, which of the provided papers (by index 1-${papers.length}) were actually relevant and cited?
102
+ Return ONLY a JSON array of numbers, e.g., [1, 3, 5]. If none, return [].
103
+ `;
104
+
105
+ // This second call might be expensive. Alternatively, we can just ask for the filtered list in the first prompt
106
+ // and parse it. Let's try a single prompt approach with structured output if possible,
107
+ // or just strict formatting.
108
+
109
+ // Let's stick to the prompt update above, but we need to parse the "Selected Sources" section
110
+ // to filter the `papers` array returned to the agent.
111
+
112
+ // Simple parsing: check if paper title appears in the "Selected Sources" section of the response.
113
+ const relevantPapers = papers.filter(p => summary.includes(p.title));
114
+
115
+ // If the heuristic fails (LLM changes title format), we fall back to all papers
116
+ // OR we can just return the summary as is (which includes the sources list)
117
+ // and pass an empty array for papers so the Agent doesn't duplicate the list.
118
+
119
+ // ResearchAgent.ts does:
120
+ // const response = ... result.summary ... \n\n**Sources:**\n${result.papers.map(...)}
121
+
122
+ // So if we include sources in the summary, we should return empty papers to Agent,
123
+ // OR we strip sources from summary and return filtered papers.
124
+
125
+ // Let's strip the "Selected Sources" from the LLM output and return the filtered list.
126
+
127
+ let finalSummary = summary;
128
+ let finalPapers = papers;
129
+
130
+ if (summary.includes('**Selected Sources:**')) {
131
+ const parts = summary.split('**Selected Sources:**');
132
+ finalSummary = parts[0].trim();
133
+ const sourcesText = parts[1];
134
+
135
+ // Filter papers based on what's in sourcesText
136
+ finalPapers = papers.filter(p => sourcesText.includes(p.title) || sourcesText.includes(p.summary.slice(0, 20)));
137
+ } else if (summary.includes('Selected Sources:')) {
138
+ const parts = summary.split('Selected Sources:');
139
+ finalSummary = parts[0].trim();
140
+ const sourcesText = parts[1];
141
+ finalPapers = papers.filter(p => sourcesText.includes(p.title) || sourcesText.includes(p.summary.slice(0, 20)));
142
+ } else {
143
+ // Fallback: if no explicit sources section, try to filter by inline citations or titles in text
144
+ // This is safer than returning all papers if the user specifically asked to filter.
145
+ // But if LLM didn't follow format, we might lose all sources.
146
+ // Let's keep all papers if format wasn't followed, or maybe try to match titles in summary.
147
+ const papersInText = papers.filter(p => summary.includes(p.title));
148
+ if (papersInText.length > 0) {
149
+ finalPapers = papersInText;
150
+ }
151
+ }
152
+
153
+ if (ctx.updateProgress) {
154
+ await ctx.updateProgress(100, `Completed analysis. Selected ${finalPapers.length} relevant sources.`);
155
+ }
156
+
157
+ ctx.log('result', `Completed literature review on ${topic}`, {
158
+ papers_count: finalPapers.length,
159
+ summary_length: finalSummary.length
160
+ });
161
+
162
+ return {
163
+ topic,
164
+ summary: finalSummary,
165
+ papers: finalPapers
166
+ };
167
+ }
168
+ }
@@ -0,0 +1,3 @@
1
+ # Paper Analysis
2
+
3
+ Analyze a scientific paper in depth, including summary, methodology, results, and critique.
@@ -0,0 +1,73 @@
1
+ import { Skill, SkillContext, SkillParams, SkillResult } from '../../../src/skills/types.js';
2
+ import { ScholarTool } from '../../../src/skills/lib/ScholarTool.js';
3
+
4
+ export default class PaperAnalysisSkill implements Skill {
5
+ id = 'paper_analysis';
6
+ name = 'Paper Analysis';
7
+ description = 'Analyze a scientific paper in depth';
8
+ tags = ['research', 'analysis', 'critique'];
9
+
10
+ private scholar = new ScholarTool();
11
+
12
+ async execute(ctx: SkillContext, params: SkillParams): Promise<SkillResult> {
13
+ const paperTitle = params.paper_title || params.title || params.query;
14
+ if (!paperTitle) {
15
+ throw new Error('Paper title is required');
16
+ }
17
+
18
+ ctx.log('thinking', `Analyzing paper: ${paperTitle}`);
19
+ if (ctx.updateProgress) await ctx.updateProgress(10, `Searching for paper: ${paperTitle}`);
20
+
21
+ // 1. Search for the paper to get metadata/summary if we don't have full text
22
+ // In a real system, we might download the PDF here.
23
+ ctx.log('action', 'Searching for paper details...');
24
+ const papers = await this.scholar.searchPapers(paperTitle, 1);
25
+
26
+ if (papers.length === 0) {
27
+ throw new Error(`Paper not found: ${paperTitle}`);
28
+ }
29
+
30
+ const paper = papers[0];
31
+ ctx.log('thinking', `Found paper: ${paper.title} (${paper.year})`);
32
+ if (ctx.updateProgress) await ctx.updateProgress(40, `Found paper: ${paper.title}`);
33
+
34
+ // 2. Analyze using LLM
35
+ // Since we can't read the full PDF yet (ScholarTool just gets metadata/abstract),
36
+ // we will ask the LLM to analyze based on its internal knowledge + the abstract.
37
+ // If we had PDF reading capability, we'd feed the text here.
38
+
39
+ const prompt = `
40
+ You are an expert research scientist.
41
+ Please perform a deep analysis of the following paper:
42
+
43
+ Title: ${paper.title}
44
+ Authors: ${paper.authors.join(', ')}
45
+ Year: ${paper.year}
46
+ Abstract: ${paper.summary}
47
+ URL: ${paper.url || 'N/A'}
48
+
49
+ If you have internal knowledge about this specific paper (based on title/authors), please use it to enrich the analysis.
50
+
51
+ Structure your response as follows:
52
+ 1. **Executive Summary**: 2-3 sentences.
53
+ 2. **Key Contributions**: Bullet points.
54
+ 3. **Methodology**: How did they do it?
55
+ 4. **Results**: What did they find?
56
+ 5. **Critique & Limitations**: What are the weaknesses?
57
+ 6. **Relevance**: Why does this matter?
58
+ `;
59
+
60
+ if (ctx.updateProgress) await ctx.updateProgress(60, `Analyzing content...`);
61
+
62
+ const response = await ctx.llm.complete(prompt);
63
+ const analysis = response.content;
64
+
65
+ if (ctx.updateProgress) await ctx.updateProgress(100, `Analysis complete.`);
66
+
67
+ return {
68
+ paper: paper,
69
+ analysis: analysis,
70
+ formatted_output: `### Paper Analysis: ${paper.title}\n\n${analysis}\n\n[View Paper](${paper.url})`
71
+ };
72
+ }
73
+ }
@@ -0,0 +1,16 @@
1
+ # PDF Generator (LaTeX)
2
+
3
+ Generate high-quality PDF documents from text or markdown using LaTeX.
4
+ This skill creates a `.tex` file and compiles it to PDF.
5
+
6
+ ## Dependencies
7
+ - `pdflatex` must be installed on the system (e.g., via TeX Live or MacTeX).
8
+ - Node.js `child_process` to run the command.
9
+
10
+ ## Usage
11
+ Provide the `content` (markdown or plain text) and a `title`.
12
+ The skill will:
13
+ 1. Convert the content to LaTeX format (using a template).
14
+ 2. Write the `.tex` file.
15
+ 3. Run `pdflatex` to generate the PDF.
16
+ 4. Return the path to the generated PDF.
@@ -0,0 +1,10 @@
1
+ import { Skill, SkillContext, SkillParams, SkillResult } from '../../../src/skills/types.js';
2
+ export default class PdfGeneratorSkill implements Skill {
3
+ id: string;
4
+ name: string;
5
+ description: string;
6
+ tags: string[];
7
+ private workspaceDir;
8
+ constructor();
9
+ execute(ctx: SkillContext, params: SkillParams): Promise<SkillResult>;
10
+ }
@@ -0,0 +1,114 @@
1
+ import { exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import * as fs from 'fs/promises';
4
+ import * as path from 'path';
5
+ import { v4 as uuidv4 } from 'uuid';
6
+ const execAsync = promisify(exec);
7
+ export default class PdfGeneratorSkill {
8
+ id = 'pdf_generator';
9
+ name = 'PDF Generator (LaTeX)';
10
+ description = 'Generate a PDF from text/markdown using LaTeX';
11
+ tags = ['research', 'document', 'pdf', 'latex'];
12
+ workspaceDir;
13
+ constructor() {
14
+ // Ensure output directory exists
15
+ this.workspaceDir = path.resolve(process.cwd(), 'workspace/output/pdfs');
16
+ }
17
+ async execute(ctx, params) {
18
+ const { title, content, author = 'Redigg AI' } = params;
19
+ if (!content) {
20
+ throw new Error('Content is required to generate PDF');
21
+ }
22
+ // Ensure output directory exists
23
+ await fs.mkdir(this.workspaceDir, { recursive: true });
24
+ ctx.log('thinking', `Generating PDF for "${title || 'Untitled'}"`);
25
+ if (ctx.updateProgress)
26
+ await ctx.updateProgress(10, `Preparing LaTeX template...`);
27
+ // 1. Convert content to LaTeX
28
+ // For now, we'll do a simple conversion or ask LLM to convert if it's complex markdown.
29
+ // Let's ask LLM to convert the markdown/text to LaTeX body content.
30
+ const prompt = `
31
+ Convert the following Markdown/Text content into LaTeX code suitable for the document body.
32
+ Do not include \\documentclass, \\begin{document}, or preamble. Just the body content.
33
+ Use standard LaTeX commands for sections, lists, bold, italics, etc.
34
+ Escape special characters like %, $, _, etc. properly unless they are math.
35
+
36
+ Content:
37
+ ${content}
38
+ `;
39
+ const llmRes = await ctx.llm.complete(prompt);
40
+ const latexBody = llmRes.content;
41
+ if (ctx.updateProgress)
42
+ await ctx.updateProgress(40, `Compiling LaTeX...`);
43
+ // 2. Create full LaTeX document
44
+ const filename = (title || 'document').replace(/[^a-z0-9]/gi, '_').toLowerCase() + '_' + uuidv4().slice(0, 8);
45
+ const texPath = path.join(this.workspaceDir, `${filename}.tex`);
46
+ const pdfPath = path.join(this.workspaceDir, `${filename}.pdf`);
47
+ const latexDoc = `
48
+ \\documentclass[12pt,a4paper]{article}
49
+ \\usepackage[utf8]{inputenc}
50
+ \\usepackage{geometry}
51
+ \\usepackage{hyperref}
52
+ \\usepackage{xcolor}
53
+ \\usepackage{parskip}
54
+
55
+ \\geometry{
56
+ a4paper,
57
+ total={170mm,257mm},
58
+ left=20mm,
59
+ top=20mm,
60
+ }
61
+
62
+ \\title{${title || 'Research Report'}}
63
+ \\author{${author}}
64
+ \\date{\\today}
65
+
66
+ \\begin{document}
67
+
68
+ \\maketitle
69
+
70
+ ${latexBody}
71
+
72
+ \\end{document}
73
+ `;
74
+ await fs.writeFile(texPath, latexDoc);
75
+ // 3. Compile PDF using pdflatex
76
+ try {
77
+ ctx.log('action', `Running pdflatex on ${texPath}`);
78
+ // Check for pdflatex first
79
+ try {
80
+ await execAsync('pdflatex --version');
81
+ }
82
+ catch (e) {
83
+ throw new Error('pdflatex is not installed. Please install it:\nMacOS: brew install --cask basictex\nLinux: apt-get install texlive-latex-base');
84
+ }
85
+ // Run twice for references/toc if needed, but once is usually fine for simple docs
86
+ await execAsync(`pdflatex -interaction=nonstopmode -output-directory=${this.workspaceDir} ${texPath}`);
87
+ }
88
+ catch (error) {
89
+ if (error.message.includes('pdflatex is not installed')) {
90
+ throw error;
91
+ }
92
+ // If compilation failed, maybe read the log file?
93
+ const logPath = texPath.replace('.tex', '.log');
94
+ let logContent = '';
95
+ try {
96
+ logContent = await fs.readFile(logPath, 'utf-8');
97
+ }
98
+ catch (e) { }
99
+ throw new Error(`LaTeX compilation failed: ${error.message}\n\nLog tail:\n${logContent.slice(-500)}`);
100
+ }
101
+ if (ctx.updateProgress)
102
+ await ctx.updateProgress(100, `PDF Generated.`);
103
+ // Return relative path for frontend to access (assuming static serve)
104
+ // We need to make sure the workspace/output is served by express.
105
+ const relativeUrl = `/files/pdfs/${filename}.pdf`;
106
+ return {
107
+ success: true,
108
+ file_path: pdfPath,
109
+ url: relativeUrl,
110
+ formatted_output: `### PDF Generated\n\n[Download PDF](${relativeUrl})`
111
+ };
112
+ }
113
+ }
114
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import { Skill, SkillContext, SkillParams, SkillResult } from '../../../src/skills/types.js';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { v4 as uuidv4 } from 'uuid';
5
+ import PDFDocument from 'pdfkit';
6
+
7
+ export default class PdfGeneratorSkill implements Skill {
8
+ id = 'pdf_generator';
9
+ name = 'PDF Generator';
10
+ description = 'Generate a PDF from text/markdown using PDFKit';
11
+ tags = ['research', 'document', 'pdf'];
12
+
13
+ private workspaceDir: string;
14
+
15
+ constructor() {
16
+ // Ensure output directory exists
17
+ this.workspaceDir = path.resolve(process.cwd(), 'workspace/output/pdfs');
18
+ }
19
+
20
+ async execute(ctx: SkillContext, params: SkillParams): Promise<SkillResult> {
21
+ const { title, content, author = 'Redigg AI' } = params;
22
+
23
+ if (!content) {
24
+ throw new Error('Content is required to generate PDF');
25
+ }
26
+
27
+ // Ensure output directory exists
28
+ if (!fs.existsSync(this.workspaceDir)) {
29
+ fs.mkdirSync(this.workspaceDir, { recursive: true });
30
+ }
31
+
32
+ ctx.log('thinking', `Generating PDF for "${title || 'Untitled'}"`);
33
+ if (ctx.updateProgress) await ctx.updateProgress(10, `Initializing PDF document...`);
34
+
35
+ const filename = (title || 'document').replace(/[^a-z0-9]/gi, '_').toLowerCase() + '_' + uuidv4().slice(0, 8);
36
+ const pdfPath = path.join(this.workspaceDir, `${filename}.pdf`);
37
+
38
+ // Create a document
39
+ const doc = new PDFDocument({ margin: 50 });
40
+ const stream = fs.createWriteStream(pdfPath);
41
+ doc.pipe(stream);
42
+
43
+ // Title Page
44
+ doc.fontSize(24).text(title || 'Research Report', { align: 'center' });
45
+ doc.moveDown();
46
+ doc.fontSize(14).text(`Author: ${author}`, { align: 'center' });
47
+ doc.fontSize(12).text(`Date: ${new Date().toLocaleDateString()}`, { align: 'center' });
48
+ doc.moveDown(2);
49
+
50
+ // Content Rendering (Simple Markdown Parser)
51
+ const lines = content.split('\n');
52
+ let inList = false;
53
+
54
+ for (const line of lines) {
55
+ const trimmed = line.trim();
56
+
57
+ if (trimmed.startsWith('# ')) {
58
+ doc.addPage(); // New page for main chapters? Maybe just space
59
+ doc.fontSize(20).text(trimmed.substring(2), { underline: true });
60
+ doc.moveDown(0.5);
61
+ } else if (trimmed.startsWith('## ')) {
62
+ doc.fontSize(16).text(trimmed.substring(3));
63
+ doc.moveDown(0.5);
64
+ } else if (trimmed.startsWith('### ')) {
65
+ doc.fontSize(14).text(trimmed.substring(4));
66
+ doc.moveDown(0.5);
67
+ } else if (trimmed.startsWith('- ') || trimmed.startsWith('* ')) {
68
+ doc.fontSize(12).text(`• ${trimmed.substring(2)}`, { indent: 20 });
69
+ } else if (trimmed.match(/^\d+\./)) {
70
+ doc.fontSize(12).text(trimmed, { indent: 20 });
71
+ } else if (trimmed === '') {
72
+ doc.moveDown(0.5);
73
+ } else {
74
+ // Normal paragraph
75
+ // Handle bold **text** (simple regex replace won't work easily with pdfkit text flow without mixed fonts)
76
+ // For now, just render plain text
77
+ doc.fontSize(12).text(line, { align: 'justify' });
78
+ }
79
+ }
80
+
81
+ // Finalize PDF file
82
+ doc.end();
83
+
84
+ if (ctx.updateProgress) await ctx.updateProgress(100, `PDF Generated.`);
85
+
86
+ // Return relative path for frontend to access (assuming static serve)
87
+ // We need to make sure the workspace/output is served by express.
88
+ const relativeUrl = `/files/pdfs/${filename}.pdf`;
89
+
90
+ return {
91
+ success: true,
92
+ file_path: pdfPath,
93
+ url: relativeUrl,
94
+ formatted_output: `### PDF Generated\n\n[Download PDF](${relativeUrl})`
95
+ };
96
+ }
97
+ }
@@ -0,0 +1,8 @@
1
+ # System Skills Pack
2
+
3
+ Infrastructure and OS-level capabilities.
4
+
5
+ ## Skills
6
+
7
+ - `code-analysis`: Analyzing project structure and files
8
+ - `local-file-ops`: Reading and writing files
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: code-analysis
3
+ description: Analyze project structure, scan codebase stats, and summarize code files
4
+ tags: [code, analysis, summary, scan]
5
+ ---
6
+
7
+ # Code Analysis
8
+
9
+ This skill provides capabilities to analyze the codebase structure, scan for overall statistics, and summarize individual files.
10
+
11
+ ## Instructions
12
+
13
+ Use this skill when the user asks to:
14
+ - Understand the project structure
15
+ - Get an overview of the codebase (size, languages, key files)
16
+ - Summarize what a specific file does
17
+ - Analyze code statistics (SLOC, imports, exports)
18
+
19
+ ## Actions
20
+
21
+ ### structure
22
+ Recursively lists the file structure of the project, ignoring `node_modules` and hidden files.
23
+
24
+ **Parameters:**
25
+ - `path` (optional): The root directory to analyze. Defaults to current working directory.
26
+
27
+ ### scan
28
+ Scans the codebase to provide a high-level summary including total files, directories, size, SLOC, and language breakdown.
29
+
30
+ **Parameters:**
31
+ - `path` (optional): The root directory to scan. Defaults to current working directory.
32
+
33
+ ### summarize
34
+ Provides a summary of a specific code file or directory. For files, it may use LLM to generate a description.
35
+
36
+ **Parameters:**
37
+ - `path` (required): The path to the file or directory to summarize.
38
+
39
+ ## Examples
40
+
41
+ - "Show me the project structure" -> `structure`
42
+ - "Scan the codebase" -> `scan`
43
+ - "Analyze src/index.ts" -> `summarize(path="src/index.ts")`