@synsci/cli-darwin-x64 1.1.70 → 1.1.72

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 (339) hide show
  1. package/bin/skills/citation-management/SKILL.md +1109 -0
  2. package/bin/skills/citation-management/assets/bibtex_template.bib +264 -0
  3. package/bin/skills/citation-management/assets/citation_checklist.md +386 -0
  4. package/bin/skills/citation-management/references/bibtex_formatting.md +908 -0
  5. package/bin/skills/citation-management/references/citation_validation.md +794 -0
  6. package/bin/skills/citation-management/references/google_scholar_search.md +725 -0
  7. package/bin/skills/citation-management/references/metadata_extraction.md +870 -0
  8. package/bin/skills/citation-management/references/pubmed_search.md +839 -0
  9. package/bin/skills/citation-management/scripts/doi_to_bibtex.py +182 -0
  10. package/bin/skills/citation-management/scripts/extract_metadata.py +570 -0
  11. package/bin/skills/citation-management/scripts/format_bibtex.py +349 -0
  12. package/bin/skills/citation-management/scripts/search_google_scholar.py +251 -0
  13. package/bin/skills/citation-management/scripts/search_pubmed.py +348 -0
  14. package/bin/skills/citation-management/scripts/validate_citations.py +494 -0
  15. package/bin/skills/clinical-decision-support/README.md +129 -0
  16. package/bin/skills/clinical-decision-support/SKILL.md +506 -0
  17. package/bin/skills/clinical-decision-support/assets/biomarker_report_template.tex +380 -0
  18. package/bin/skills/clinical-decision-support/assets/clinical_pathway_template.tex +222 -0
  19. package/bin/skills/clinical-decision-support/assets/cohort_analysis_template.tex +359 -0
  20. package/bin/skills/clinical-decision-support/assets/color_schemes.tex +149 -0
  21. package/bin/skills/clinical-decision-support/assets/example_gbm_cohort.md +208 -0
  22. package/bin/skills/clinical-decision-support/assets/recommendation_strength_guide.md +328 -0
  23. package/bin/skills/clinical-decision-support/assets/treatment_recommendation_template.tex +529 -0
  24. package/bin/skills/clinical-decision-support/references/biomarker_classification.md +719 -0
  25. package/bin/skills/clinical-decision-support/references/clinical_decision_algorithms.md +604 -0
  26. package/bin/skills/clinical-decision-support/references/evidence_synthesis.md +840 -0
  27. package/bin/skills/clinical-decision-support/references/outcome_analysis.md +640 -0
  28. package/bin/skills/clinical-decision-support/references/patient_cohort_analysis.md +427 -0
  29. package/bin/skills/clinical-decision-support/references/treatment_recommendations.md +521 -0
  30. package/bin/skills/clinical-decision-support/scripts/biomarker_classifier.py +383 -0
  31. package/bin/skills/clinical-decision-support/scripts/build_decision_tree.py +417 -0
  32. package/bin/skills/clinical-decision-support/scripts/create_cohort_tables.py +509 -0
  33. package/bin/skills/clinical-decision-support/scripts/generate_survival_analysis.py +441 -0
  34. package/bin/skills/clinical-decision-support/scripts/validate_cds_document.py +326 -0
  35. package/bin/skills/clinical-reports/IMPLEMENTATION_SUMMARY.md +641 -0
  36. package/bin/skills/clinical-reports/README.md +236 -0
  37. package/bin/skills/clinical-reports/SKILL.md +1127 -0
  38. package/bin/skills/clinical-reports/assets/case_report_template.md +352 -0
  39. package/bin/skills/clinical-reports/assets/clinical_trial_csr_template.md +353 -0
  40. package/bin/skills/clinical-reports/assets/clinical_trial_sae_template.md +359 -0
  41. package/bin/skills/clinical-reports/assets/consult_note_template.md +305 -0
  42. package/bin/skills/clinical-reports/assets/discharge_summary_template.md +453 -0
  43. package/bin/skills/clinical-reports/assets/hipaa_compliance_checklist.md +395 -0
  44. package/bin/skills/clinical-reports/assets/history_physical_template.md +305 -0
  45. package/bin/skills/clinical-reports/assets/lab_report_template.md +309 -0
  46. package/bin/skills/clinical-reports/assets/pathology_report_template.md +249 -0
  47. package/bin/skills/clinical-reports/assets/quality_checklist.md +338 -0
  48. package/bin/skills/clinical-reports/assets/radiology_report_template.md +318 -0
  49. package/bin/skills/clinical-reports/assets/soap_note_template.md +253 -0
  50. package/bin/skills/clinical-reports/references/case_report_guidelines.md +570 -0
  51. package/bin/skills/clinical-reports/references/clinical_trial_reporting.md +693 -0
  52. package/bin/skills/clinical-reports/references/data_presentation.md +530 -0
  53. package/bin/skills/clinical-reports/references/diagnostic_reports_standards.md +629 -0
  54. package/bin/skills/clinical-reports/references/medical_terminology.md +588 -0
  55. package/bin/skills/clinical-reports/references/patient_documentation.md +744 -0
  56. package/bin/skills/clinical-reports/references/peer_review_standards.md +585 -0
  57. package/bin/skills/clinical-reports/references/regulatory_compliance.md +577 -0
  58. package/bin/skills/clinical-reports/scripts/check_deidentification.py +332 -0
  59. package/bin/skills/clinical-reports/scripts/compliance_checker.py +78 -0
  60. package/bin/skills/clinical-reports/scripts/extract_clinical_data.py +97 -0
  61. package/bin/skills/clinical-reports/scripts/format_adverse_events.py +97 -0
  62. package/bin/skills/clinical-reports/scripts/generate_report_template.py +149 -0
  63. package/bin/skills/clinical-reports/scripts/terminology_validator.py +126 -0
  64. package/bin/skills/clinical-reports/scripts/validate_case_report.py +323 -0
  65. package/bin/skills/clinical-reports/scripts/validate_trial_report.py +88 -0
  66. package/bin/skills/fireworks-ai/SKILL.md +665 -0
  67. package/bin/skills/generate-image/SKILL.md +178 -0
  68. package/bin/skills/generate-image/scripts/generate_image.py +254 -0
  69. package/bin/skills/groq/SKILL.md +347 -0
  70. package/bin/skills/hypothesis-generation/SKILL.md +293 -0
  71. package/bin/skills/hypothesis-generation/assets/FORMATTING_GUIDE.md +672 -0
  72. package/bin/skills/hypothesis-generation/assets/hypothesis_generation.sty +307 -0
  73. package/bin/skills/hypothesis-generation/assets/hypothesis_report_template.tex +572 -0
  74. package/bin/skills/hypothesis-generation/references/experimental_design_patterns.md +329 -0
  75. package/bin/skills/hypothesis-generation/references/hypothesis_quality_criteria.md +198 -0
  76. package/bin/skills/hypothesis-generation/references/literature_search_strategies.md +622 -0
  77. package/bin/skills/latex-posters/README.md +417 -0
  78. package/bin/skills/latex-posters/SKILL.md +1602 -0
  79. package/bin/skills/latex-posters/assets/baposter_template.tex +257 -0
  80. package/bin/skills/latex-posters/assets/beamerposter_template.tex +244 -0
  81. package/bin/skills/latex-posters/assets/poster_quality_checklist.md +358 -0
  82. package/bin/skills/latex-posters/assets/tikzposter_template.tex +251 -0
  83. package/bin/skills/latex-posters/references/latex_poster_packages.md +745 -0
  84. package/bin/skills/latex-posters/references/poster_content_guide.md +748 -0
  85. package/bin/skills/latex-posters/references/poster_design_principles.md +806 -0
  86. package/bin/skills/latex-posters/references/poster_layout_design.md +900 -0
  87. package/bin/skills/latex-posters/scripts/review_poster.sh +214 -0
  88. package/bin/skills/literature-review/SKILL.md +641 -0
  89. package/bin/skills/literature-review/assets/review_template.md +412 -0
  90. package/bin/skills/literature-review/references/citation_styles.md +166 -0
  91. package/bin/skills/literature-review/references/database_strategies.md +455 -0
  92. package/bin/skills/literature-review/scripts/generate_pdf.py +184 -0
  93. package/bin/skills/literature-review/scripts/search_databases.py +310 -0
  94. package/bin/skills/literature-review/scripts/verify_citations.py +218 -0
  95. package/bin/skills/market-research-reports/SKILL.md +904 -0
  96. package/bin/skills/market-research-reports/assets/FORMATTING_GUIDE.md +428 -0
  97. package/bin/skills/market-research-reports/assets/market_report_template.tex +1380 -0
  98. package/bin/skills/market-research-reports/assets/market_research.sty +564 -0
  99. package/bin/skills/market-research-reports/references/data_analysis_patterns.md +548 -0
  100. package/bin/skills/market-research-reports/references/report_structure_guide.md +999 -0
  101. package/bin/skills/market-research-reports/references/visual_generation_guide.md +1077 -0
  102. package/bin/skills/market-research-reports/scripts/generate_market_visuals.py +472 -0
  103. package/bin/skills/markitdown/INSTALLATION_GUIDE.md +318 -0
  104. package/bin/skills/markitdown/LICENSE.txt +22 -0
  105. package/bin/skills/markitdown/OPENROUTER_INTEGRATION.md +359 -0
  106. package/bin/skills/markitdown/QUICK_REFERENCE.md +309 -0
  107. package/bin/skills/markitdown/README.md +184 -0
  108. package/bin/skills/markitdown/SKILL.md +486 -0
  109. package/bin/skills/markitdown/SKILL_SUMMARY.md +307 -0
  110. package/bin/skills/markitdown/assets/example_usage.md +463 -0
  111. package/bin/skills/markitdown/references/api_reference.md +399 -0
  112. package/bin/skills/markitdown/references/file_formats.md +542 -0
  113. package/bin/skills/markitdown/scripts/batch_convert.py +195 -0
  114. package/bin/skills/markitdown/scripts/convert_literature.py +262 -0
  115. package/bin/skills/markitdown/scripts/convert_with_ai.py +224 -0
  116. package/bin/skills/ml-paper-writing/SKILL.md +937 -0
  117. package/bin/skills/ml-paper-writing/references/checklists.md +361 -0
  118. package/bin/skills/ml-paper-writing/references/citation-workflow.md +562 -0
  119. package/bin/skills/ml-paper-writing/references/reviewer-guidelines.md +367 -0
  120. package/bin/skills/ml-paper-writing/references/sources.md +159 -0
  121. package/bin/skills/ml-paper-writing/references/writing-guide.md +476 -0
  122. package/bin/skills/ml-paper-writing/templates/README.md +251 -0
  123. package/bin/skills/ml-paper-writing/templates/aaai2026/README.md +534 -0
  124. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026-unified-supp.tex +144 -0
  125. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026-unified-template.tex +952 -0
  126. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.bib +111 -0
  127. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.bst +1493 -0
  128. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.sty +315 -0
  129. package/bin/skills/ml-paper-writing/templates/acl/README.md +50 -0
  130. package/bin/skills/ml-paper-writing/templates/acl/acl.sty +312 -0
  131. package/bin/skills/ml-paper-writing/templates/acl/acl_latex.tex +377 -0
  132. package/bin/skills/ml-paper-writing/templates/acl/acl_lualatex.tex +101 -0
  133. package/bin/skills/ml-paper-writing/templates/acl/acl_natbib.bst +1940 -0
  134. package/bin/skills/ml-paper-writing/templates/acl/anthology.bib.txt +26 -0
  135. package/bin/skills/ml-paper-writing/templates/acl/custom.bib +70 -0
  136. package/bin/skills/ml-paper-writing/templates/acl/formatting.md +326 -0
  137. package/bin/skills/ml-paper-writing/templates/colm2025/README.md +3 -0
  138. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.bib +11 -0
  139. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.bst +1440 -0
  140. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.pdf +0 -0
  141. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.sty +218 -0
  142. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.tex +305 -0
  143. package/bin/skills/ml-paper-writing/templates/colm2025/fancyhdr.sty +485 -0
  144. package/bin/skills/ml-paper-writing/templates/colm2025/math_commands.tex +508 -0
  145. package/bin/skills/ml-paper-writing/templates/colm2025/natbib.sty +1246 -0
  146. package/bin/skills/ml-paper-writing/templates/iclr2026/fancyhdr.sty +485 -0
  147. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.bib +24 -0
  148. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.bst +1440 -0
  149. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.pdf +0 -0
  150. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.sty +246 -0
  151. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.tex +414 -0
  152. package/bin/skills/ml-paper-writing/templates/iclr2026/math_commands.tex +508 -0
  153. package/bin/skills/ml-paper-writing/templates/iclr2026/natbib.sty +1246 -0
  154. package/bin/skills/ml-paper-writing/templates/icml2026/algorithm.sty +79 -0
  155. package/bin/skills/ml-paper-writing/templates/icml2026/algorithmic.sty +201 -0
  156. package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.bib +75 -0
  157. package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.pdf +0 -0
  158. package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.tex +662 -0
  159. package/bin/skills/ml-paper-writing/templates/icml2026/fancyhdr.sty +864 -0
  160. package/bin/skills/ml-paper-writing/templates/icml2026/icml2026.bst +1443 -0
  161. package/bin/skills/ml-paper-writing/templates/icml2026/icml2026.sty +767 -0
  162. package/bin/skills/ml-paper-writing/templates/icml2026/icml_numpapers.pdf +0 -0
  163. package/bin/skills/ml-paper-writing/templates/neurips2025/Makefile +36 -0
  164. package/bin/skills/ml-paper-writing/templates/neurips2025/extra_pkgs.tex +53 -0
  165. package/bin/skills/ml-paper-writing/templates/neurips2025/main.tex +38 -0
  166. package/bin/skills/ml-paper-writing/templates/neurips2025/neurips.sty +382 -0
  167. package/bin/skills/paper-2-web/SKILL.md +491 -0
  168. package/bin/skills/paper-2-web/references/installation.md +141 -0
  169. package/bin/skills/paper-2-web/references/paper2poster.md +346 -0
  170. package/bin/skills/paper-2-web/references/paper2video.md +305 -0
  171. package/bin/skills/paper-2-web/references/paper2web.md +187 -0
  172. package/bin/skills/paper-2-web/references/usage_examples.md +436 -0
  173. package/bin/skills/peer-review/SKILL.md +702 -0
  174. package/bin/skills/peer-review/references/calibration_guidelines.md +196 -0
  175. package/bin/skills/peer-review/references/common_issues.md +552 -0
  176. package/bin/skills/peer-review/references/paper_mechanics.md +269 -0
  177. package/bin/skills/peer-review/references/reporting_standards.md +290 -0
  178. package/bin/skills/peer-review/references/scoring_rubric.md +239 -0
  179. package/bin/skills/pptx-posters/SKILL.md +410 -0
  180. package/bin/skills/pptx-posters/assets/poster_html_template.html +257 -0
  181. package/bin/skills/pptx-posters/assets/poster_quality_checklist.md +358 -0
  182. package/bin/skills/pptx-posters/references/poster_content_guide.md +748 -0
  183. package/bin/skills/pptx-posters/references/poster_design_principles.md +806 -0
  184. package/bin/skills/pptx-posters/references/poster_layout_design.md +900 -0
  185. package/bin/skills/research-grants/README.md +285 -0
  186. package/bin/skills/research-grants/SKILL.md +938 -0
  187. package/bin/skills/research-grants/assets/budget_justification_template.md +453 -0
  188. package/bin/skills/research-grants/assets/nih_specific_aims_template.md +166 -0
  189. package/bin/skills/research-grants/assets/nsf_project_summary_template.md +92 -0
  190. package/bin/skills/research-grants/references/broader_impacts.md +392 -0
  191. package/bin/skills/research-grants/references/darpa_guidelines.md +636 -0
  192. package/bin/skills/research-grants/references/doe_guidelines.md +586 -0
  193. package/bin/skills/research-grants/references/nih_guidelines.md +851 -0
  194. package/bin/skills/research-grants/references/nsf_guidelines.md +570 -0
  195. package/bin/skills/research-grants/references/specific_aims_guide.md +458 -0
  196. package/bin/skills/research-lookup/README.md +156 -0
  197. package/bin/skills/research-lookup/SKILL.md +606 -0
  198. package/bin/skills/research-lookup/examples.py +174 -0
  199. package/bin/skills/research-lookup/lookup.py +187 -0
  200. package/bin/skills/research-lookup/research_lookup.py +483 -0
  201. package/bin/skills/research-lookup/scripts/research_lookup.py +483 -0
  202. package/bin/skills/scholar-evaluation/SKILL.md +289 -0
  203. package/bin/skills/scholar-evaluation/references/evaluation_framework.md +663 -0
  204. package/bin/skills/scholar-evaluation/scripts/calculate_scores.py +366 -0
  205. package/bin/skills/scientific-critical-thinking/SKILL.md +566 -0
  206. package/bin/skills/scientific-critical-thinking/references/common_biases.md +364 -0
  207. package/bin/skills/scientific-critical-thinking/references/evidence_hierarchy.md +484 -0
  208. package/bin/skills/scientific-critical-thinking/references/experimental_design.md +496 -0
  209. package/bin/skills/scientific-critical-thinking/references/logical_fallacies.md +478 -0
  210. package/bin/skills/scientific-critical-thinking/references/scientific_method.md +169 -0
  211. package/bin/skills/scientific-critical-thinking/references/statistical_pitfalls.md +506 -0
  212. package/bin/skills/scientific-schematics/QUICK_REFERENCE.md +207 -0
  213. package/bin/skills/scientific-schematics/README.md +327 -0
  214. package/bin/skills/scientific-schematics/SKILL.md +615 -0
  215. package/bin/skills/scientific-schematics/example_usage.sh +89 -0
  216. package/bin/skills/scientific-schematics/references/best_practices.md +559 -0
  217. package/bin/skills/scientific-schematics/scripts/generate_schematic.py +135 -0
  218. package/bin/skills/scientific-schematics/scripts/generate_schematic_ai.py +807 -0
  219. package/bin/skills/scientific-schematics/test_ai_generation.py +243 -0
  220. package/bin/skills/scientific-slides/SKILL.md +942 -0
  221. package/bin/skills/scientific-slides/assets/timing_guidelines.md +597 -0
  222. package/bin/skills/scientific-slides/references/data_visualization_slides.md +708 -0
  223. package/bin/skills/scientific-slides/references/presentation_structure.md +642 -0
  224. package/bin/skills/scientific-slides/references/slide_design_principles.md +849 -0
  225. package/bin/skills/scientific-slides/references/talk_types_guide.md +687 -0
  226. package/bin/skills/scientific-slides/references/visual_review_workflow.md +775 -0
  227. package/bin/skills/scientific-slides/scripts/generate_slide_image.py +143 -0
  228. package/bin/skills/scientific-slides/scripts/generate_slide_image_ai.py +748 -0
  229. package/bin/skills/scientific-slides/scripts/pdf_to_images.py +201 -0
  230. package/bin/skills/scientific-slides/scripts/slides_to_pdf.py +220 -0
  231. package/bin/skills/scientific-slides/scripts/validate_presentation.py +367 -0
  232. package/bin/skills/scientific-writing/SKILL.md +714 -0
  233. package/bin/skills/scientific-writing/assets/REPORT_FORMATTING_GUIDE.md +574 -0
  234. package/bin/skills/scientific-writing/assets/scientific_report.sty +606 -0
  235. package/bin/skills/scientific-writing/assets/scientific_report_template.tex +449 -0
  236. package/bin/skills/scientific-writing/references/citation_styles.md +720 -0
  237. package/bin/skills/scientific-writing/references/figures_tables.md +806 -0
  238. package/bin/skills/scientific-writing/references/imrad_structure.md +686 -0
  239. package/bin/skills/scientific-writing/references/professional_report_formatting.md +664 -0
  240. package/bin/skills/scientific-writing/references/reporting_guidelines.md +748 -0
  241. package/bin/skills/scientific-writing/references/writing_principles.md +824 -0
  242. package/bin/skills/tinker/SKILL.md +2 -3
  243. package/bin/skills/together-ai/SKILL.md +722 -0
  244. package/bin/skills/treatment-plans/README.md +488 -0
  245. package/bin/skills/treatment-plans/SKILL.md +1579 -0
  246. package/bin/skills/treatment-plans/assets/STYLING_QUICK_REFERENCE.md +185 -0
  247. package/bin/skills/treatment-plans/assets/chronic_disease_management_plan.tex +665 -0
  248. package/bin/skills/treatment-plans/assets/general_medical_treatment_plan.tex +547 -0
  249. package/bin/skills/treatment-plans/assets/medical_treatment_plan.sty +222 -0
  250. package/bin/skills/treatment-plans/assets/mental_health_treatment_plan.tex +774 -0
  251. package/bin/skills/treatment-plans/assets/one_page_treatment_plan.tex +193 -0
  252. package/bin/skills/treatment-plans/assets/pain_management_plan.tex +799 -0
  253. package/bin/skills/treatment-plans/assets/perioperative_care_plan.tex +753 -0
  254. package/bin/skills/treatment-plans/assets/quality_checklist.md +471 -0
  255. package/bin/skills/treatment-plans/assets/rehabilitation_treatment_plan.tex +756 -0
  256. package/bin/skills/treatment-plans/references/goal_setting_frameworks.md +411 -0
  257. package/bin/skills/treatment-plans/references/intervention_guidelines.md +507 -0
  258. package/bin/skills/treatment-plans/references/regulatory_compliance.md +476 -0
  259. package/bin/skills/treatment-plans/references/specialty_specific_guidelines.md +655 -0
  260. package/bin/skills/treatment-plans/references/treatment_plan_standards.md +485 -0
  261. package/bin/skills/treatment-plans/scripts/check_completeness.py +322 -0
  262. package/bin/skills/treatment-plans/scripts/generate_template.py +233 -0
  263. package/bin/skills/treatment-plans/scripts/timeline_generator.py +385 -0
  264. package/bin/skills/treatment-plans/scripts/validate_treatment_plan.py +369 -0
  265. package/bin/skills/unsloth/SKILL.md +565 -47
  266. package/bin/skills/unsloth/docs/advanced-rl.md +222 -0
  267. package/bin/skills/unsloth/docs/chat-templates.md +141 -0
  268. package/bin/skills/unsloth/docs/datasets.md +489 -0
  269. package/bin/skills/unsloth/docs/docker-extended.md +99 -0
  270. package/bin/skills/unsloth/docs/dynamic-ggufs-2.0.md +116 -0
  271. package/bin/skills/unsloth/docs/dynamic-ggufs-aider.md +118 -0
  272. package/bin/skills/unsloth/docs/faq.md +91 -0
  273. package/bin/skills/unsloth/docs/fp16-vs-bf16.md +61 -0
  274. package/bin/skills/unsloth/docs/fp8-rl.md +224 -0
  275. package/bin/skills/unsloth/docs/glm-4.7-flash.md +997 -0
  276. package/bin/skills/unsloth/docs/inference-deployment-overview.md +17 -0
  277. package/bin/skills/unsloth/docs/inference.md +27 -0
  278. package/bin/skills/unsloth/docs/installation-docker.md +155 -0
  279. package/bin/skills/unsloth/docs/installation-pip.md +148 -0
  280. package/bin/skills/unsloth/docs/kernels-packing.md +190 -0
  281. package/bin/skills/unsloth/docs/kimi-k2.5.md +634 -0
  282. package/bin/skills/unsloth/docs/lm-studio.md +235 -0
  283. package/bin/skills/unsloth/docs/lora-hot-swapping.md +75 -0
  284. package/bin/skills/unsloth/docs/lora-hyperparameters.md +363 -0
  285. package/bin/skills/unsloth/docs/memory-efficient-rl.md +267 -0
  286. package/bin/skills/unsloth/docs/model-selection.md +70 -0
  287. package/bin/skills/unsloth/docs/models.md +532 -0
  288. package/bin/skills/unsloth/docs/multi-gpu-ddp.md +90 -0
  289. package/bin/skills/unsloth/docs/notebooks.md +223 -0
  290. package/bin/skills/unsloth/docs/overview.md +110 -0
  291. package/bin/skills/unsloth/docs/qwen3-coder-next-extended.md +900 -0
  292. package/bin/skills/unsloth/docs/qwen3-coder-next.md +900 -0
  293. package/bin/skills/unsloth/docs/requirements.md +45 -0
  294. package/bin/skills/unsloth/docs/reward-hacking.md +25 -0
  295. package/bin/skills/unsloth/docs/saving-to-gguf.md +138 -0
  296. package/bin/skills/unsloth/docs/saving-to-ollama.md +46 -0
  297. package/bin/skills/unsloth/docs/sglang-guide.md +278 -0
  298. package/bin/skills/unsloth/docs/speculative-decoding.md +70 -0
  299. package/bin/skills/unsloth/docs/tool-calling.md +334 -0
  300. package/bin/skills/unsloth/docs/troubleshooting-faq.md +204 -0
  301. package/bin/skills/unsloth/docs/troubleshooting-inference.md +26 -0
  302. package/bin/skills/unsloth/docs/tts-fine-tuning.md +149 -0
  303. package/bin/skills/unsloth/docs/tutorial-grpo.md +273 -0
  304. package/bin/skills/unsloth/docs/tutorial-llama3-ollama.md +356 -0
  305. package/bin/skills/unsloth/docs/vision-fine-tuning.md +135 -0
  306. package/bin/skills/unsloth/docs/vision-rl.md +170 -0
  307. package/bin/skills/unsloth/docs/vllm-engine-arguments.md +43 -0
  308. package/bin/skills/unsloth/docs/vllm-guide.md +98 -0
  309. package/bin/skills/venue-templates/SKILL.md +686 -0
  310. package/bin/skills/venue-templates/assets/examples/cell_summary_example.md +247 -0
  311. package/bin/skills/venue-templates/assets/examples/medical_structured_abstract.md +313 -0
  312. package/bin/skills/venue-templates/assets/examples/nature_abstract_examples.md +213 -0
  313. package/bin/skills/venue-templates/assets/examples/neurips_introduction_example.md +245 -0
  314. package/bin/skills/venue-templates/assets/grants/nih_specific_aims.tex +235 -0
  315. package/bin/skills/venue-templates/assets/grants/nsf_proposal_template.tex +375 -0
  316. package/bin/skills/venue-templates/assets/journals/nature_article.tex +171 -0
  317. package/bin/skills/venue-templates/assets/journals/neurips_article.tex +283 -0
  318. package/bin/skills/venue-templates/assets/journals/plos_one.tex +317 -0
  319. package/bin/skills/venue-templates/assets/posters/beamerposter_academic.tex +311 -0
  320. package/bin/skills/venue-templates/references/cell_press_style.md +483 -0
  321. package/bin/skills/venue-templates/references/conferences_formatting.md +564 -0
  322. package/bin/skills/venue-templates/references/cs_conference_style.md +463 -0
  323. package/bin/skills/venue-templates/references/grants_requirements.md +787 -0
  324. package/bin/skills/venue-templates/references/journals_formatting.md +486 -0
  325. package/bin/skills/venue-templates/references/medical_journal_styles.md +535 -0
  326. package/bin/skills/venue-templates/references/ml_conference_style.md +556 -0
  327. package/bin/skills/venue-templates/references/nature_science_style.md +405 -0
  328. package/bin/skills/venue-templates/references/posters_guidelines.md +628 -0
  329. package/bin/skills/venue-templates/references/reviewer_expectations.md +417 -0
  330. package/bin/skills/venue-templates/references/venue_writing_styles.md +321 -0
  331. package/bin/skills/venue-templates/scripts/customize_template.py +195 -0
  332. package/bin/skills/venue-templates/scripts/query_template.py +266 -0
  333. package/bin/skills/venue-templates/scripts/validate_format.py +250 -0
  334. package/bin/synsc +0 -0
  335. package/package.json +1 -1
  336. package/bin/skills/unsloth/references/index.md +0 -7
  337. package/bin/skills/unsloth/references/llms-full.md +0 -16799
  338. package/bin/skills/unsloth/references/llms-txt.md +0 -12044
  339. package/bin/skills/unsloth/references/llms.md +0 -82
@@ -0,0 +1,748 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AI-powered slide image generation using Nano Banana Pro.
4
+
5
+ This script generates presentation slides or slide visuals using AI:
6
+ - full_slide mode: Generate complete slides with title, content, and visuals (for PDF workflow)
7
+ - visual_only mode: Generate just images/figures to place on slides (for PPT workflow)
8
+
9
+ Supports attaching reference images for context (e.g., "create a slide about this chart").
10
+
11
+ Uses smart iterative refinement:
12
+ 1. Generate initial image with Nano Banana Pro
13
+ 2. Quality review using Gemini 3 Pro
14
+ 3. Only regenerate if quality is below threshold
15
+ 4. Repeat until quality meets standards (max iterations)
16
+
17
+ Requirements:
18
+ - OPENROUTER_API_KEY environment variable
19
+ - requests library
20
+
21
+ Usage:
22
+ # Full slide for PDF workflow
23
+ python generate_slide_image_ai.py "Title: Introduction to ML\nKey points: supervised learning, neural networks" -o slide_01.png
24
+
25
+ # Visual only for PPT workflow
26
+ python generate_slide_image_ai.py "Neural network architecture diagram" -o figure.png --visual-only
27
+
28
+ # With reference images attached
29
+ python generate_slide_image_ai.py "Create a slide explaining this chart" -o slide.png --attach chart.png --attach logo.png
30
+ """
31
+
32
+ import argparse
33
+ import base64
34
+ import json
35
+ import os
36
+ import sys
37
+ import time
38
+ from pathlib import Path
39
+ from typing import Any, Dict, List, Optional, Tuple
40
+
41
+
42
+ try:
43
+ import requests
44
+ except ImportError:
45
+ print("Error: requests library not found. Install with: pip install requests")
46
+ sys.exit(1)
47
+
48
+
49
+ def _load_env_file():
50
+ """Load .env file from current directory, parent directories, or package directory."""
51
+ try:
52
+ from dotenv import load_dotenv
53
+ except ImportError:
54
+ return False
55
+
56
+ # Try current working directory first
57
+ env_path = Path.cwd() / ".env"
58
+ if env_path.exists():
59
+ load_dotenv(dotenv_path=env_path, override=False)
60
+ return True
61
+
62
+ # Try parent directories (up to 5 levels)
63
+ cwd = Path.cwd()
64
+ for _ in range(5):
65
+ env_path = cwd / ".env"
66
+ if env_path.exists():
67
+ load_dotenv(dotenv_path=env_path, override=False)
68
+ return True
69
+ cwd = cwd.parent
70
+ if cwd == cwd.parent:
71
+ break
72
+
73
+ # Try the package's parent directory
74
+ script_dir = Path(__file__).resolve().parent
75
+ for _ in range(5):
76
+ env_path = script_dir / ".env"
77
+ if env_path.exists():
78
+ load_dotenv(dotenv_path=env_path, override=False)
79
+ return True
80
+ script_dir = script_dir.parent
81
+ if script_dir == script_dir.parent:
82
+ break
83
+
84
+ return False
85
+
86
+
87
+ class SlideImageGenerator:
88
+ """Generate presentation slides or visuals using AI with iterative refinement.
89
+
90
+ Two modes:
91
+ - full_slide: Generate complete slide with title, content, visuals (for PDF workflow)
92
+ - visual_only: Generate just the image/figure for a slide (for PPT workflow)
93
+ """
94
+
95
+ # Quality threshold for presentations (lower than journal/conference papers)
96
+ QUALITY_THRESHOLD = 6.5
97
+
98
+ # Guidelines for generating full slides (complete slide images)
99
+ FULL_SLIDE_GUIDELINES = """
100
+ Create a professional presentation slide image with these requirements:
101
+
102
+ SLIDE LAYOUT (16:9 aspect ratio):
103
+ - Clean, modern slide design
104
+ - Clear visual hierarchy: title at top, content below
105
+ - Generous margins (at least 5% on all sides)
106
+ - Balanced composition with intentional white space
107
+
108
+ TYPOGRAPHY:
109
+ - LARGE, bold title text (easily readable from distance)
110
+ - Clear, sans-serif fonts throughout
111
+ - High contrast text (dark on light or light on dark)
112
+ - Bullet points or key phrases, NOT paragraphs
113
+ - Maximum 5-6 lines of text content
114
+ - Default author/presenter: "K-Dense" (use this unless another name is specified)
115
+
116
+ VISUAL ELEMENTS:
117
+ - Use GENERIC, simple images and icons - avoid overly specific or detailed imagery
118
+ - MINIMAL extra elements - no decorative borders, shadows, or flourishes
119
+ - Visuals should support and enhance the message, not distract
120
+ - Professional, clean aesthetic with restraint
121
+ - Consistent color scheme (2-3 main colors only)
122
+ - Prefer abstract/conceptual visuals over literal representations
123
+
124
+ PROFESSIONAL MINIMALISM:
125
+ - Less is more: favor empty space over additional elements
126
+ - No unnecessary decorations, gradients, or visual noise
127
+ - Clean lines and simple shapes
128
+ - Focused content without visual clutter
129
+ - Corporate/academic level of professionalism
130
+
131
+ PRESENTATION QUALITY:
132
+ - Designed for projection (high contrast)
133
+ - Bold, impactful design that commands attention
134
+ - Professional and polished appearance
135
+ - No cluttered or busy layouts
136
+ - Consistent styling throughout the deck
137
+ """
138
+
139
+ # Guidelines for generating slide visuals only (figures/images for PPT)
140
+ VISUAL_ONLY_GUIDELINES = """
141
+ Create a high-quality visual/figure for a presentation slide:
142
+
143
+ IMAGE QUALITY:
144
+ - Clean, professional appearance
145
+ - High resolution and sharp details
146
+ - Suitable for embedding in a slide
147
+
148
+ DESIGN:
149
+ - Simple, clear composition with MINIMAL elements
150
+ - High contrast for projection readability
151
+ - No text unless essential to the visual
152
+ - Transparent or white background preferred
153
+ - GENERIC imagery - avoid overly specific or detailed visuals
154
+
155
+ PROFESSIONAL MINIMALISM:
156
+ - Favor simplicity over complexity
157
+ - No decorative elements, shadows, or flourishes
158
+ - Clean lines and simple shapes only
159
+ - Remove any unnecessary visual noise
160
+ - Abstract/conceptual rather than literal representations
161
+
162
+ STYLE:
163
+ - Modern, professional aesthetic
164
+ - Colorblind-friendly colors
165
+ - Bold but restrained imagery
166
+ - Suitable for scientific/professional presentations
167
+ - Corporate/academic level of polish
168
+ """
169
+
170
+ def __init__(self, api_key: Optional[str] = None, verbose: bool = False):
171
+ """
172
+ Initialize the generator.
173
+
174
+ Args:
175
+ api_key: OpenRouter API key (or use OPENROUTER_API_KEY env var)
176
+ verbose: Print detailed progress information
177
+ """
178
+ self.api_key = api_key or os.getenv("OPENROUTER_API_KEY")
179
+
180
+ if not self.api_key:
181
+ _load_env_file()
182
+ self.api_key = os.getenv("OPENROUTER_API_KEY")
183
+
184
+ if not self.api_key:
185
+ raise ValueError(
186
+ "OPENROUTER_API_KEY not found. Please either:\n"
187
+ " 1. Set the OPENROUTER_API_KEY environment variable\n"
188
+ " 2. Add OPENROUTER_API_KEY to your .env file\n"
189
+ " 3. Pass api_key parameter to the constructor\n"
190
+ "Get your API key from: https://openrouter.ai/keys"
191
+ )
192
+
193
+ self.verbose = verbose
194
+ self._last_error = None
195
+ self.base_url = "https://openrouter.ai/api/v1"
196
+ # Nano Banana Pro for image generation
197
+ self.image_model = "google/gemini-3-pro-image-preview"
198
+ # Gemini 3 Pro for quality review
199
+ self.review_model = "google/gemini-3-pro"
200
+
201
+ def _log(self, message: str):
202
+ """Log message if verbose mode is enabled."""
203
+ if self.verbose:
204
+ print(f"[{time.strftime('%H:%M:%S')}] {message}")
205
+
206
+ def _make_request(
207
+ self, model: str, messages: List[Dict[str, Any]], modalities: Optional[List[str]] = None
208
+ ) -> Dict[str, Any]:
209
+ """Make a request to OpenRouter API."""
210
+ headers = {
211
+ "Authorization": f"Bearer {self.api_key}",
212
+ "Content-Type": "application/json",
213
+ "HTTP-Referer": "https://github.com/scientific-writer",
214
+ "X-Title": "Scientific Slide Generator",
215
+ }
216
+
217
+ payload = {"model": model, "messages": messages}
218
+
219
+ if modalities:
220
+ payload["modalities"] = modalities
221
+
222
+ self._log(f"Making request to {model}...")
223
+
224
+ try:
225
+ response = requests.post(f"{self.base_url}/chat/completions", headers=headers, json=payload, timeout=120)
226
+
227
+ try:
228
+ response_json = response.json()
229
+ except json.JSONDecodeError:
230
+ response_json = {"raw_text": response.text[:500]}
231
+
232
+ if response.status_code != 200:
233
+ error_detail = response_json.get("error", response_json)
234
+ self._log(f"HTTP {response.status_code}: {error_detail}")
235
+ raise RuntimeError(f"API request failed (HTTP {response.status_code}): {error_detail}")
236
+
237
+ return response_json
238
+ except requests.exceptions.Timeout:
239
+ raise RuntimeError("API request timed out after 120 seconds")
240
+ except requests.exceptions.RequestException as e:
241
+ raise RuntimeError(f"API request failed: {str(e)}")
242
+
243
+ def _extract_image_from_response(self, response: Dict[str, Any]) -> Optional[bytes]:
244
+ """Extract base64-encoded image from API response."""
245
+ try:
246
+ choices = response.get("choices", [])
247
+ if not choices:
248
+ self._log("No choices in response")
249
+ return None
250
+
251
+ message = choices[0].get("message", {})
252
+
253
+ # Nano Banana Pro returns images in the 'images' field
254
+ images = message.get("images", [])
255
+ if images and len(images) > 0:
256
+ self._log(f"Found {len(images)} image(s) in 'images' field")
257
+
258
+ first_image = images[0]
259
+ if isinstance(first_image, dict):
260
+ if first_image.get("type") == "image_url":
261
+ url = first_image.get("image_url", {})
262
+ if isinstance(url, dict):
263
+ url = url.get("url", "")
264
+
265
+ if url and url.startswith("data:image"):
266
+ if "," in url:
267
+ base64_str = url.split(",", 1)[1]
268
+ base64_str = base64_str.replace('\n', '').replace('\r', '').replace(' ', '')
269
+ self._log(f"Extracted base64 data (length: {len(base64_str)})")
270
+ return base64.b64decode(base64_str)
271
+
272
+ # Fallback: check content field
273
+ content = message.get("content", "")
274
+
275
+ if isinstance(content, str) and "data:image" in content:
276
+ import re
277
+
278
+ match = re.search(r'data:image/[^;]+;base64,([A-Za-z0-9+/=\n\r]+)', content, re.DOTALL)
279
+ if match:
280
+ base64_str = match.group(1).replace('\n', '').replace('\r', '').replace(' ', '')
281
+ self._log(f"Found image in content field (length: {len(base64_str)})")
282
+ return base64.b64decode(base64_str)
283
+
284
+ if isinstance(content, list):
285
+ for i, block in enumerate(content):
286
+ if isinstance(block, dict) and block.get("type") == "image_url":
287
+ url = block.get("image_url", {})
288
+ if isinstance(url, dict):
289
+ url = url.get("url", "")
290
+ if url and url.startswith("data:image") and "," in url:
291
+ base64_str = url.split(",", 1)[1].replace('\n', '').replace('\r', '').replace(' ', '')
292
+ self._log(f"Found image in content block {i}")
293
+ return base64.b64decode(base64_str)
294
+
295
+ self._log("No image data found in response")
296
+ return None
297
+
298
+ except Exception as e:
299
+ self._log(f"Error extracting image: {str(e)}")
300
+ return None
301
+
302
+ def _image_to_base64(self, image_path: str) -> str:
303
+ """Convert image file to base64 data URL."""
304
+ with open(image_path, "rb") as f:
305
+ image_data = f.read()
306
+
307
+ ext = Path(image_path).suffix.lower()
308
+ mime_type = {
309
+ ".png": "image/png",
310
+ ".jpg": "image/jpeg",
311
+ ".jpeg": "image/jpeg",
312
+ ".gif": "image/gif",
313
+ ".webp": "image/webp",
314
+ }.get(ext, "image/png")
315
+
316
+ base64_data = base64.b64encode(image_data).decode("utf-8")
317
+ return f"data:{mime_type};base64,{base64_data}"
318
+
319
+ def generate_image(self, prompt: str, attachments: Optional[List[str]] = None) -> Optional[bytes]:
320
+ """
321
+ Generate an image using Nano Banana Pro.
322
+
323
+ Args:
324
+ prompt: Text description of the image to generate
325
+ attachments: Optional list of image file paths to attach as context
326
+
327
+ Returns:
328
+ Image bytes or None if generation failed
329
+ """
330
+ self._last_error = None
331
+
332
+ # Build content with text and optional image attachments
333
+ content = []
334
+
335
+ # Add text prompt
336
+ content.append({"type": "text", "text": prompt})
337
+
338
+ # Add attached images as context
339
+ if attachments:
340
+ for img_path in attachments:
341
+ try:
342
+ img_data_url = self._image_to_base64(img_path)
343
+ content.append({"type": "image_url", "image_url": {"url": img_data_url}})
344
+ self._log(f"Attached image: {img_path}")
345
+ except Exception as e:
346
+ self._log(f"Warning: Could not attach {img_path}: {e}")
347
+
348
+ messages = [{"role": "user", "content": content if attachments else prompt}]
349
+
350
+ try:
351
+ response = self._make_request(model=self.image_model, messages=messages, modalities=["image", "text"])
352
+
353
+ if self.verbose:
354
+ self._log(f"Response keys: {response.keys()}")
355
+ if "error" in response:
356
+ self._log(f"API Error: {response['error']}")
357
+
358
+ if "error" in response:
359
+ error_msg = response["error"]
360
+ if isinstance(error_msg, dict):
361
+ error_msg = error_msg.get("message", str(error_msg))
362
+ self._last_error = f"API Error: {error_msg}"
363
+ print(f"✗ {self._last_error}")
364
+ return None
365
+
366
+ image_data = self._extract_image_from_response(response)
367
+ if image_data:
368
+ self._log(f"✓ Generated image ({len(image_data)} bytes)")
369
+ else:
370
+ self._last_error = "No image data in API response"
371
+ self._log(f"✗ {self._last_error}")
372
+
373
+ return image_data
374
+ except RuntimeError as e:
375
+ self._last_error = str(e)
376
+ self._log(f"✗ Generation failed: {self._last_error}")
377
+ return None
378
+ except Exception as e:
379
+ self._last_error = f"Unexpected error: {str(e)}"
380
+ self._log(f"✗ Generation failed: {self._last_error}")
381
+ return None
382
+
383
+ def review_image(
384
+ self, image_path: str, original_prompt: str, iteration: int, visual_only: bool = False, max_iterations: int = 2
385
+ ) -> Tuple[str, float, bool]:
386
+ """Review generated image using Gemini 3 Pro."""
387
+ image_data_url = self._image_to_base64(image_path)
388
+ threshold = self.QUALITY_THRESHOLD
389
+
390
+ image_type = "slide visual/figure" if visual_only else "presentation slide"
391
+
392
+ review_prompt = f"""You are an expert reviewer evaluating a {image_type} for presentation quality.
393
+
394
+ ORIGINAL REQUEST: {original_prompt}
395
+
396
+ QUALITY THRESHOLD: {threshold}/10
397
+ ITERATION: {iteration}/{max_iterations}
398
+
399
+ Evaluate this {image_type} on these criteria:
400
+
401
+ 1. **Visual Impact** (0-2 points)
402
+ - Bold, attention-grabbing design
403
+ - Professional appearance
404
+ - Suitable for projection
405
+
406
+ 2. **Clarity** (0-2 points)
407
+ - Easy to understand at a glance
408
+ - Clear visual hierarchy
409
+ - Not cluttered or busy
410
+
411
+ 3. **Readability** (0-2 points)
412
+ - Text is large and readable (if present)
413
+ - High contrast
414
+ - Clean typography
415
+
416
+ 4. **Composition** (0-2 points)
417
+ - Balanced layout
418
+ - Good use of space
419
+ - Appropriate margins
420
+
421
+ 5. **Relevance** (0-2 points)
422
+ - Matches the requested content
423
+ - Appropriate style for presentations
424
+ - Professional quality
425
+
426
+ RESPOND IN THIS EXACT FORMAT:
427
+ SCORE: [total score 0-10]
428
+
429
+ STRENGTHS:
430
+ - [strength 1]
431
+ - [strength 2]
432
+
433
+ ISSUES:
434
+ - [issue 1 if any]
435
+ - [issue 2 if any]
436
+
437
+ VERDICT: [ACCEPTABLE or NEEDS_IMPROVEMENT]
438
+
439
+ If score >= {threshold}, the image is ACCEPTABLE.
440
+ If score < {threshold}, mark as NEEDS_IMPROVEMENT with specific suggestions."""
441
+
442
+ messages = [
443
+ {
444
+ "role": "user",
445
+ "content": [
446
+ {"type": "text", "text": review_prompt},
447
+ {"type": "image_url", "image_url": {"url": image_data_url}},
448
+ ],
449
+ }
450
+ ]
451
+
452
+ try:
453
+ response = self._make_request(model=self.review_model, messages=messages)
454
+
455
+ choices = response.get("choices", [])
456
+ if not choices:
457
+ return "Image generated successfully", 7.0, False
458
+
459
+ message = choices[0].get("message", {})
460
+ content = message.get("content", "")
461
+
462
+ reasoning = message.get("reasoning", "")
463
+ if reasoning and not content:
464
+ content = reasoning
465
+
466
+ if isinstance(content, list):
467
+ text_parts = []
468
+ for block in content:
469
+ if isinstance(block, dict) and block.get("type") == "text":
470
+ text_parts.append(block.get("text", ""))
471
+ content = "\n".join(text_parts)
472
+
473
+ # Extract score
474
+ score = 7.0
475
+ import re
476
+
477
+ score_match = re.search(r'SCORE:\s*(\d+(?:\.\d+)?)', content, re.IGNORECASE)
478
+ if score_match:
479
+ score = float(score_match.group(1))
480
+ else:
481
+ score_match = re.search(r'(?:score|rating|quality)[:\s]+(\d+(?:\.\d+)?)', content, re.IGNORECASE)
482
+ if score_match:
483
+ score = float(score_match.group(1))
484
+
485
+ needs_improvement = False
486
+ if "NEEDS_IMPROVEMENT" in content.upper():
487
+ needs_improvement = True
488
+ elif score < threshold:
489
+ needs_improvement = True
490
+
491
+ self._log(f"✓ Review complete (Score: {score}/10, Threshold: {threshold}/10)")
492
+
493
+ return (content if content else "Image generated successfully", score, needs_improvement)
494
+ except Exception as e:
495
+ self._log(f"Review skipped: {str(e)}")
496
+ return "Image generated successfully (review skipped)", 7.0, False
497
+
498
+ def improve_prompt(self, original_prompt: str, critique: str, iteration: int, visual_only: bool = False) -> str:
499
+ """Improve the generation prompt based on critique."""
500
+ guidelines = self.VISUAL_ONLY_GUIDELINES if visual_only else self.FULL_SLIDE_GUIDELINES
501
+
502
+ return f"""{guidelines}
503
+
504
+ USER REQUEST: {original_prompt}
505
+
506
+ ITERATION {iteration}: Based on previous feedback, address these specific improvements:
507
+ {critique}
508
+
509
+ Generate an improved version that addresses all the critique points."""
510
+
511
+ def generate_slide(
512
+ self,
513
+ user_prompt: str,
514
+ output_path: str,
515
+ visual_only: bool = False,
516
+ iterations: int = 2,
517
+ attachments: Optional[List[str]] = None,
518
+ ) -> Dict[str, Any]:
519
+ """
520
+ Generate a slide image or visual with iterative refinement.
521
+
522
+ Args:
523
+ user_prompt: Description of the slide/visual to generate
524
+ output_path: Path to save final image
525
+ visual_only: If True, generate just the visual (for PPT workflow)
526
+ iterations: Maximum refinement iterations (default: 2)
527
+ attachments: Optional list of image file paths to attach as context
528
+
529
+ Returns:
530
+ Dictionary with generation results and metadata
531
+ """
532
+ output_path = Path(output_path)
533
+ output_dir = output_path.parent
534
+ output_dir.mkdir(parents=True, exist_ok=True)
535
+
536
+ base_name = output_path.stem
537
+ extension = output_path.suffix or ".png"
538
+
539
+ mode = "visual_only" if visual_only else "full_slide"
540
+ guidelines = self.VISUAL_ONLY_GUIDELINES if visual_only else self.FULL_SLIDE_GUIDELINES
541
+
542
+ results = {
543
+ "user_prompt": user_prompt,
544
+ "mode": mode,
545
+ "quality_threshold": self.QUALITY_THRESHOLD,
546
+ "attachments": attachments or [],
547
+ "iterations": [],
548
+ "final_image": None,
549
+ "final_score": 0.0,
550
+ "success": False,
551
+ "early_stop": False,
552
+ }
553
+
554
+ current_prompt = f"""{guidelines}
555
+
556
+ USER REQUEST: {user_prompt}
557
+
558
+ Generate a high-quality {'visual/figure' if visual_only else 'presentation slide'} that meets all the guidelines above."""
559
+
560
+ print(f"\n{'=' * 60}")
561
+ print(f"Generating Slide {'Visual' if visual_only else 'Image'}")
562
+ print(f"{'=' * 60}")
563
+ print(f"Description: {user_prompt[:100]}{'...' if len(user_prompt) > 100 else ''}")
564
+ print(f"Mode: {mode}")
565
+ if attachments:
566
+ print(f"Attachments: {len(attachments)} image(s)")
567
+ for att in attachments:
568
+ print(f" - {att}")
569
+ print(f"Quality Threshold: {self.QUALITY_THRESHOLD}/10")
570
+ print(f"Max Iterations: {iterations}")
571
+ print(f"Output: {output_path}")
572
+ print(f"{'=' * 60}\n")
573
+
574
+ # Track temporary files for cleanup
575
+ temp_files = []
576
+ final_image_data = None
577
+
578
+ for i in range(1, iterations + 1):
579
+ print(f"\n[Iteration {i}/{iterations}]")
580
+ print("-" * 40)
581
+
582
+ print("Generating image with Nano Banana Pro...")
583
+ image_data = self.generate_image(current_prompt, attachments=attachments)
584
+
585
+ if not image_data:
586
+ error_msg = self._last_error or 'Image generation failed'
587
+ print(f"✗ Generation failed: {error_msg}")
588
+ results["iterations"].append({"iteration": i, "success": False, "error": error_msg})
589
+ continue
590
+
591
+ # Save to temporary file for review (will be cleaned up)
592
+ import tempfile
593
+
594
+ temp_fd, temp_path = tempfile.mkstemp(suffix=extension)
595
+ os.close(temp_fd)
596
+ temp_path = Path(temp_path)
597
+ temp_files.append(temp_path)
598
+
599
+ with open(temp_path, "wb") as f:
600
+ f.write(image_data)
601
+ print(f"✓ Generated image (iteration {i})")
602
+
603
+ print("Reviewing image with Gemini 3 Pro...")
604
+ critique, score, needs_improvement = self.review_image(
605
+ str(temp_path), user_prompt, i, visual_only, iterations
606
+ )
607
+ print(f"✓ Score: {score}/10 (threshold: {self.QUALITY_THRESHOLD}/10)")
608
+
609
+ results["iterations"].append(
610
+ {
611
+ "iteration": i,
612
+ "critique": critique,
613
+ "score": score,
614
+ "needs_improvement": needs_improvement,
615
+ "success": True,
616
+ }
617
+ )
618
+
619
+ if not needs_improvement:
620
+ print(f"\n✓ Quality meets threshold ({score} >= {self.QUALITY_THRESHOLD})")
621
+ final_image_data = image_data
622
+ results["final_score"] = score
623
+ results["success"] = True
624
+ results["early_stop"] = True
625
+ break
626
+
627
+ if i == iterations:
628
+ print("\n⚠ Maximum iterations reached")
629
+ final_image_data = image_data
630
+ results["final_score"] = score
631
+ results["success"] = True
632
+ break
633
+
634
+ print(f"\n⚠ Quality below threshold ({score} < {self.QUALITY_THRESHOLD})")
635
+ print("Improving prompt...")
636
+ current_prompt = self.improve_prompt(user_prompt, critique, i + 1, visual_only)
637
+
638
+ # Clean up temporary files
639
+ for temp_file in temp_files:
640
+ try:
641
+ if temp_file.exists():
642
+ temp_file.unlink()
643
+ except Exception:
644
+ pass
645
+
646
+ # Save only the final image to output path
647
+ if results["success"] and final_image_data:
648
+ with open(output_path, "wb") as f:
649
+ f.write(final_image_data)
650
+ results["final_image"] = str(output_path)
651
+ print(f"\n✓ Final image: {output_path}")
652
+
653
+ print(f"\n{'=' * 60}")
654
+ print("Generation Complete!")
655
+ print(f"Final Score: {results['final_score']}/10")
656
+ if results["early_stop"]:
657
+ success_count = len([r for r in results['iterations'] if r.get('success')])
658
+ print(f"Iterations Used: {success_count}/{iterations} (early stop)")
659
+ print(f"{'=' * 60}\n")
660
+
661
+ return results
662
+
663
+
664
+ def main():
665
+ """Command-line interface."""
666
+ parser = argparse.ArgumentParser(
667
+ description="Generate presentation slides or visuals using Nano Banana Pro AI",
668
+ formatter_class=argparse.RawDescriptionHelpFormatter,
669
+ epilog="""
670
+ Examples:
671
+ # Generate a full slide (for PDF workflow)
672
+ python generate_slide_image_ai.py "Title: Machine Learning Basics\\nKey points: supervised learning, neural networks, deep learning" -o slide_01.png
673
+
674
+ # Generate just a visual/figure (for PPT workflow)
675
+ python generate_slide_image_ai.py "Neural network architecture diagram with input, hidden, and output layers" -o figure.png --visual-only
676
+
677
+ # With reference images attached (Nano Banana Pro will see these)
678
+ python generate_slide_image_ai.py "Create a slide explaining this chart with key insights" -o slide.png --attach chart.png
679
+ python generate_slide_image_ai.py "Combine these images into a comparison slide" -o compare.png --attach before.png --attach after.png
680
+
681
+ # With custom iterations
682
+ python generate_slide_image_ai.py "Title slide for AI Conference 2025" -o title.png --iterations 2
683
+
684
+ # Verbose output
685
+ python generate_slide_image_ai.py "Data flow diagram" -o flow.png -v
686
+
687
+ Environment:
688
+ OPENROUTER_API_KEY OpenRouter API key (required)
689
+ """,
690
+ )
691
+
692
+ parser.add_argument("prompt", help="Description of the slide or visual to generate")
693
+ parser.add_argument("-o", "--output", required=True, help="Output image path")
694
+ parser.add_argument(
695
+ "--attach",
696
+ action="append",
697
+ dest="attachments",
698
+ metavar="IMAGE",
699
+ help="Attach image file(s) as context for generation (can use multiple times)",
700
+ )
701
+ parser.add_argument("--visual-only", action="store_true", help="Generate just the visual/figure (for PPT workflow)")
702
+ parser.add_argument("--iterations", type=int, default=2, help="Maximum refinement iterations (default: 2)")
703
+ parser.add_argument("--api-key", help="OpenRouter API key (or set OPENROUTER_API_KEY)")
704
+ parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output")
705
+
706
+ args = parser.parse_args()
707
+
708
+ api_key = args.api_key or os.getenv("OPENROUTER_API_KEY")
709
+ if not api_key:
710
+ print("Error: OPENROUTER_API_KEY environment variable not set")
711
+ print("\nSet it with:")
712
+ print(" export OPENROUTER_API_KEY='your_api_key'")
713
+ sys.exit(1)
714
+
715
+ if args.iterations < 1 or args.iterations > 2:
716
+ print("Error: Iterations must be between 1 and 2")
717
+ sys.exit(1)
718
+
719
+ # Validate attachments exist
720
+ if args.attachments:
721
+ for att in args.attachments:
722
+ if not Path(att).exists():
723
+ print(f"Error: Attachment file not found: {att}")
724
+ sys.exit(1)
725
+
726
+ try:
727
+ generator = SlideImageGenerator(api_key=api_key, verbose=args.verbose)
728
+ results = generator.generate_slide(
729
+ user_prompt=args.prompt,
730
+ output_path=args.output,
731
+ visual_only=args.visual_only,
732
+ iterations=args.iterations,
733
+ attachments=args.attachments,
734
+ )
735
+
736
+ if results["success"]:
737
+ print(f"\n✓ Success! Image saved to: {args.output}")
738
+ sys.exit(0)
739
+ else:
740
+ print("\n✗ Generation failed. Check review log for details.")
741
+ sys.exit(1)
742
+ except Exception as e:
743
+ print(f"\n✗ Error: {str(e)}")
744
+ sys.exit(1)
745
+
746
+
747
+ if __name__ == "__main__":
748
+ main()