fabricatio 0.2.11.dev1__tar.gz → 0.2.11.dev3__tar.gz

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 (164) hide show
  1. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/PKG-INFO +4 -2
  2. fabricatio-0.2.11.dev3/examples/write_article/write_article.py +140 -0
  3. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/pyproject.toml +5 -2
  4. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/actions/article.py +20 -4
  5. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/actions/article_rag.py +129 -41
  6. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/decorators.py +27 -10
  7. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/action.py +14 -7
  8. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/aricle_rag.py +6 -0
  9. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/article_base.py +27 -8
  10. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/task.py +13 -1
  11. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/usages.py +1 -1
  12. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/rust.pyi +126 -139
  13. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/utils.py +29 -10
  14. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/src/typst_tools.rs +18 -9
  15. fabricatio-0.2.11.dev3/templates.tar.gz +0 -0
  16. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/uv.lock +43 -10
  17. fabricatio-0.2.11.dev1/examples/write_article/write_article.py +0 -207
  18. fabricatio-0.2.11.dev1/templates.tar.gz +0 -0
  19. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/.github/workflows/build-package.yaml +0 -0
  20. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/.github/workflows/ruff.yaml +0 -0
  21. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/.github/workflows/tests.yaml +0 -0
  22. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/.gitignore +0 -0
  23. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/.python-version +0 -0
  24. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/Cargo.lock +0 -0
  25. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/Cargo.toml +0 -0
  26. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/LICENSE +0 -0
  27. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/Makefile +0 -0
  28. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/README.md +0 -0
  29. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/correct/correct.py +0 -0
  30. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/correct/correct_loop.py +0 -0
  31. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/extract_and_inject/.gitignore +0 -0
  32. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/extract_and_inject/article_rag.py +0 -0
  33. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/extract_and_inject/ask.py +0 -0
  34. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/extract_and_inject/chunk_article.py +0 -0
  35. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/extract_and_inject/extract_and_inject.py +0 -0
  36. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/extract_article/extract.py +0 -0
  37. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/llm_usages/llm_usage.py +0 -0
  38. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/make_a_rating/rating.py +0 -0
  39. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/make_diary/commits.json +0 -0
  40. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/make_diary/diary.py +0 -0
  41. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/minor/hello_fabricatio.py +0 -0
  42. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/minor/write_a_poem.py +0 -0
  43. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/propose_task/.gitignore +0 -0
  44. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/propose_task/propose.py +0 -0
  45. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/reviewer/censor.py +0 -0
  46. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/reviewer/review.py +0 -0
  47. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/rules/.gitignore +0 -0
  48. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/rules/draft_ruleset.py +0 -0
  49. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/search_bibtex/.gitignore +0 -0
  50. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/search_bibtex/search.py +0 -0
  51. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/simple_chat/chat.py +0 -0
  52. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/simple_rag/simple_rag.py +0 -0
  53. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/task_handle/handle_task.py +0 -0
  54. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/write_article/.gitignore +0 -0
  55. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/write_article/article_rag.py +0 -0
  56. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/write_article/post_process.py +0 -0
  57. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/write_outline/.gitignore +0 -0
  58. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/write_outline/write_outline.py +0 -0
  59. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/examples/write_outline/write_outline_corrected.py +0 -0
  60. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/__init__.py +0 -0
  61. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/actions/__init__.py +0 -0
  62. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/actions/fs.py +0 -0
  63. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/actions/output.py +0 -0
  64. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/actions/rag.py +0 -0
  65. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/actions/rules.py +0 -0
  66. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/__init__.py +0 -0
  67. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/advanced_judge.py +0 -0
  68. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/censor.py +0 -0
  69. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/check.py +0 -0
  70. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/correct.py +0 -0
  71. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/extract.py +0 -0
  72. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/propose.py +0 -0
  73. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/rag.py +0 -0
  74. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/rating.py +0 -0
  75. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/review.py +0 -0
  76. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/capabilities/task.py +0 -0
  77. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/config.py +0 -0
  78. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/constants.py +0 -0
  79. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/core.py +0 -0
  80. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/fs/__init__.py +0 -0
  81. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/fs/curd.py +0 -0
  82. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/fs/readers.py +0 -0
  83. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/journal.py +0 -0
  84. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/adv_kwargs_types.py +0 -0
  85. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/events.py +0 -0
  86. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/__init__.py +0 -0
  87. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/advanced_judge.py +0 -0
  88. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/article_essence.py +0 -0
  89. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/article_main.py +0 -0
  90. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/article_outline.py +0 -0
  91. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/article_proposal.py +0 -0
  92. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/patches.py +0 -0
  93. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/problem.py +0 -0
  94. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/rag.py +0 -0
  95. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/extra/rule.py +0 -0
  96. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/generic.py +0 -0
  97. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/kwargs_types.py +0 -0
  98. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/role.py +0 -0
  99. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/models/tool.py +0 -0
  100. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/parser.py +0 -0
  101. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/py.typed +0 -0
  102. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/rust_instances.py +0 -0
  103. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/toolboxes/__init__.py +0 -0
  104. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/toolboxes/arithmetic.py +0 -0
  105. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/toolboxes/fs.py +0 -0
  106. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/workflows/__init__.py +0 -0
  107. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/workflows/articles.py +0 -0
  108. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/python/fabricatio/workflows/rag.py +0 -0
  109. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/src/bib_tools.rs +0 -0
  110. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/src/hash.rs +0 -0
  111. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/src/hbs_helpers.rs +0 -0
  112. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/src/language.rs +0 -0
  113. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/src/lib.rs +0 -0
  114. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/src/templates.rs +0 -0
  115. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/src/word_split.rs +0 -0
  116. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/as_prompt.hbs +0 -0
  117. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/binary-exploitation-ctf-solver.hbs +0 -0
  118. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/check_string.hbs +0 -0
  119. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/claude-xml.hbs +0 -0
  120. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/clean-up-code.hbs +0 -0
  121. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/co_validation.hbs +0 -0
  122. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/create_json_obj.hbs +0 -0
  123. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/cryptography-ctf-solver.hbs +0 -0
  124. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/dependencies.hbs +0 -0
  125. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/document-the-code.hbs +0 -0
  126. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/draft_rating_criteria.hbs +0 -0
  127. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/draft_rating_manual.hbs +0 -0
  128. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/draft_rating_weights_klee.hbs +0 -0
  129. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/draft_tool_usage_code.hbs +0 -0
  130. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/extract.hbs +0 -0
  131. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/extract_criteria_from_reasons.hbs +0 -0
  132. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/extract_reasons_from_examples.hbs +0 -0
  133. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/find-security-vulnerabilities.hbs +0 -0
  134. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/fix-bugs.hbs +0 -0
  135. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/fix_troubled_obj.hbs +0 -0
  136. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/fix_troubled_string.hbs +0 -0
  137. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/generic_string.hbs +0 -0
  138. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/improve-performance.hbs +0 -0
  139. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/liststr.hbs +0 -0
  140. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/make_choice.hbs +0 -0
  141. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/make_judgment.hbs +0 -0
  142. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/pathstr.hbs +0 -0
  143. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/rate_fine_grind.hbs +0 -0
  144. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/refactor.hbs +0 -0
  145. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/refined_query.hbs +0 -0
  146. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/retrieved_display.hbs +0 -0
  147. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/reverse-engineering-ctf-solver.hbs +0 -0
  148. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/review_string.hbs +0 -0
  149. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/rule_requirement.hbs +0 -0
  150. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/ruleset_requirement_breakdown.hbs +0 -0
  151. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/task_briefing.hbs +0 -0
  152. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/web-ctf-solver.hbs +0 -0
  153. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/write-git-commit.hbs +0 -0
  154. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/write-github-pull-request.hbs +0 -0
  155. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/templates/built-in/write-github-readme.hbs +0 -0
  156. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_config.py +0 -0
  157. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_models/test_action.py +0 -0
  158. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_models/test_advanced.py +0 -0
  159. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_models/test_generic.py +0 -0
  160. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_models/test_problem.py +0 -0
  161. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_models/test_role.py +0 -0
  162. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_models/test_task.py +0 -0
  163. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_models/test_tool.py +0 -0
  164. {fabricatio-0.2.11.dev1 → fabricatio-0.2.11.dev3}/tests/test_models/test_usages.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fabricatio
3
- Version: 0.2.11.dev1
3
+ Version: 0.2.11.dev3
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -20,18 +20,20 @@ Requires-Dist: pydantic-settings>=2.7.1
20
20
  Requires-Dist: pymitter>=1.0.0
21
21
  Requires-Dist: rich>=13.9.4
22
22
  Requires-Dist: ujson>=5.10.0
23
- Requires-Dist: fabricatio[calc,ftd,plot,qa,rag] ; extra == 'full'
23
+ Requires-Dist: fabricatio[calc,ftd,plot,qa,rag,cli] ; extra == 'full'
24
24
  Requires-Dist: pymilvus>=2.5.4 ; extra == 'rag'
25
25
  Requires-Dist: sympy>=1.13.3 ; extra == 'calc'
26
26
  Requires-Dist: matplotlib>=3.10.1 ; extra == 'plot'
27
27
  Requires-Dist: questionary>=2.1.0 ; extra == 'qa'
28
28
  Requires-Dist: magika>=0.6.1 ; extra == 'ftd'
29
+ Requires-Dist: typer-slim[standard]>=0.15.2 ; extra == 'cli'
29
30
  Provides-Extra: full
30
31
  Provides-Extra: rag
31
32
  Provides-Extra: calc
32
33
  Provides-Extra: plot
33
34
  Provides-Extra: qa
34
35
  Provides-Extra: ftd
36
+ Provides-Extra: cli
35
37
  License-File: LICENSE
36
38
  Summary: A LLM multi-agent framework.
37
39
  Keywords: ai,agents,multi-agent,llm,pyo3
@@ -0,0 +1,140 @@
1
+ """Example of using the library."""
2
+
3
+ import asyncio
4
+ from pathlib import Path
5
+
6
+ import typer
7
+ from fabricatio import Event, Role, WorkFlow, logger
8
+ from fabricatio.actions.article import ExtractOutlineFromRaw, GenerateArticleProposal, GenerateInitialOutline
9
+ from fabricatio.actions.article_rag import WriteArticleContentRAG
10
+ from fabricatio.actions.output import (
11
+ DumpFinalizedOutput,
12
+ PersistentAll,
13
+ )
14
+ from fabricatio.models.task import Task
15
+ from fabricatio.utils import ok
16
+ from typer import Typer
17
+
18
+ Role(
19
+ name="Undergraduate Researcher",
20
+ description="Write an outline for an article in typst format.",
21
+ llm_model="openai/qwen-max",
22
+ llm_temperature=0.63,
23
+ llm_stream=True,
24
+ llm_top_p=0.85,
25
+ llm_max_tokens=8191,
26
+ llm_rpm=600,
27
+ llm_tpm=900000,
28
+ registry={
29
+ Event.quick_instantiate(ns := "article"): WorkFlow(
30
+ name="Generate Article",
31
+ description="Generate an article. dump the outline to the given path. in typst format.",
32
+ steps=(
33
+ GenerateArticleProposal,
34
+ GenerateInitialOutline(output_key="article_outline"),
35
+ PersistentAll,
36
+ WriteArticleContentRAG(
37
+ output_key="to_dump",
38
+ llm_top_p=0.9,
39
+ ref_limit=35,
40
+ llm_model="openai/qwq-plus",
41
+ target_collection="article_chunks",
42
+ extractor_model="openai/qwen-plus",
43
+ query_model="openai/qwen-max",
44
+ ),
45
+ DumpFinalizedOutput(output_key="task_output"),
46
+ PersistentAll,
47
+ ),
48
+ ),
49
+ Event.quick_instantiate(ns2 := ""): WorkFlow(
50
+ name="Generate Article",
51
+ description="Generate an article with given raw article outline. dump the outline to the given path. in typst format.",
52
+ steps=(
53
+ ExtractOutlineFromRaw,
54
+ PersistentAll,
55
+ WriteArticleContentRAG(
56
+ output_key="to_dump",
57
+ llm_top_p=0.9,
58
+ ref_limit=35,
59
+ llm_model="openai/qwq-plus",
60
+ target_collection="article_chunks",
61
+ extractor_model="openai/qwen-plus",
62
+ query_model="openai/qwen-max",
63
+ ),
64
+ DumpFinalizedOutput(output_key="task_output"),
65
+ PersistentAll,
66
+ ),
67
+ ),
68
+ },
69
+ )
70
+
71
+
72
+ app = Typer()
73
+
74
+
75
+ @app.command()
76
+ def completion(
77
+ article_outline_raw_path: Path = typer.Option( # noqa: B008
78
+ Path("article_outline_raw.txt"), "-a", "--article-outline-raw", help="Path to the article outline raw file."
79
+ ),
80
+ dump_path: Path = typer.Option(Path("out.typ"), "-d", "--dump-path", help="Path to dump the final output."), # noqa: B008
81
+ persist_dir: Path = typer.Option( # noqa: B008
82
+ Path("persistent"), "-p", "--persist-dir", help="Directory to persist the output."
83
+ ),
84
+ collection_name: str = typer.Option("article_chunks", "-c", "--collection-name", help="Name of the collection."),
85
+ supervisor: bool = typer.Option(False, "-s", "--supervisor", help="Whether to use the supervisor mode."),
86
+ ) -> None:
87
+ """Write an article based on a raw article outline."""
88
+ path = ok(
89
+ asyncio.run(
90
+ Task(name="write an article")
91
+ .update_init_context(
92
+ article_outline_raw_path=article_outline_raw_path,
93
+ dump_path=dump_path,
94
+ persist_dir=persist_dir,
95
+ collection_name=collection_name,
96
+ supervisor=supervisor,
97
+ )
98
+ .delegate(ns)
99
+ ),
100
+ "Failed to generate an article ",
101
+ )
102
+ logger.success(f"The outline is saved in:\n{path}")
103
+
104
+
105
+ @app.command()
106
+ def write(
107
+ article_briefing: Path = typer.Option( # noqa: B008
108
+ Path("article_briefing.txt"), "-a", "--article-briefing", help="Path to the article briefing file."
109
+ ),
110
+ dump_path: Path = typer.Option(Path("out.typ"), "-d", "--dump-path", help="Path to dump the final output."), # noqa: B008
111
+ persist_dir: Path = typer.Option( # noqa: B008
112
+ Path("persistent"), "-p", "--persist-dir", help="Directory to persist the output."
113
+ ),
114
+ collection_name: str = typer.Option("article_chunks", "-c", "--collection-name", help="Name of the collection."),
115
+ supervisor: bool = typer.Option(False, "-s", "--supervisor", help="Whether to use the supervisor mode."),
116
+ ) -> None:
117
+ """Write an article based on a briefing.
118
+
119
+ This function generates an article outline and content based on the provided briefing.
120
+ The outline and content are then dumped to the specified path and persisted in the given directory.
121
+ """
122
+ path = ok(
123
+ asyncio.run(
124
+ Task(name="write an article")
125
+ .update_init_context(
126
+ article_briefing=article_briefing.read_text(),
127
+ dump_path=dump_path,
128
+ persist_dir=persist_dir,
129
+ collection_name=collection_name,
130
+ supervisor=supervisor,
131
+ )
132
+ .delegate(ns)
133
+ ),
134
+ "Failed to generate an article ",
135
+ )
136
+ logger.success(f"The outline is saved in:\n{path}")
137
+
138
+
139
+ if __name__ == "__main__":
140
+ app()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fabricatio"
3
- version = "0.2.11-dev1"
3
+ version = "0.2.11-dev3"
4
4
  description = "A LLM multi-agent framework."
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -74,7 +74,7 @@ dev = [
74
74
 
75
75
  [project.optional-dependencies]
76
76
  full = [
77
- "fabricatio[calc,ftd,plot,qa,rag]",
77
+ "fabricatio[calc,ftd,plot,qa,rag,cli]",
78
78
  ]
79
79
  rag = [
80
80
  "pymilvus>=2.5.4",
@@ -92,6 +92,9 @@ qa = [
92
92
  ftd = [
93
93
  "magika>=0.6.1",
94
94
  ]
95
+ cli = [
96
+ "typer-slim[standard]>=0.15.2",
97
+ ]
95
98
 
96
99
  [tool.ruff]
97
100
  include = ["pyproject.toml", "python/fabricatio/*.py", "python/fabricatio/*.pyi", "examples/*.py"]
@@ -149,10 +149,10 @@ class GenerateInitialOutline(Action, Extract):
149
149
  async def _execute(
150
150
  self,
151
151
  article_proposal: ArticleProposal,
152
+ supervisor: Optional[bool] = None,
152
153
  **_,
153
154
  ) -> Optional[ArticleOutline]:
154
- raw_outline = await self.aask(
155
- f"{(article_proposal.as_prompt())}\n"
155
+ req = (
156
156
  f"Design each chapter of a proper and academic and ready for release manner.\n"
157
157
  f"You Must make sure every chapter have sections, and every section have subsections.\n"
158
158
  f"Make the chapter and sections and subsections bing divided into a specific enough article component.\n"
@@ -160,14 +160,16 @@ class GenerateInitialOutline(Action, Extract):
160
160
  f"Note that you SHALL use `{article_proposal.language}` as written language",
161
161
  )
162
162
 
163
- if self.supervisor:
163
+ raw_outline = await self.aask(f"{(article_proposal.as_prompt())}\n{req}")
164
+
165
+ if supervisor or (supervisor is None and self.supervisor):
164
166
  from questionary import confirm, text
165
167
 
166
168
  r_print(raw_outline)
167
169
  while not await confirm("Accept this version and continue?", default=True).ask_async():
168
170
  imp = await text("Enter the improvement:").ask_async()
169
171
  raw_outline = await self.aask(
170
- f"{article_proposal.as_prompt()}\n{wrapp_in_block(raw_outline, 'Previous ArticleOutline')}\n{imp}"
172
+ f"{article_proposal.as_prompt()}\n{wrapp_in_block(raw_outline, 'Previous ArticleOutline')}\n{req}\n{wrapp_in_block(imp, title='Improvement')}"
171
173
  )
172
174
  r_print(raw_outline)
173
175
 
@@ -177,6 +179,20 @@ class GenerateInitialOutline(Action, Extract):
177
179
  ).update_ref(article_proposal)
178
180
 
179
181
 
182
+ class ExtractOutlineFromRaw(Action, Extract):
183
+ """Extract the outline from the raw outline."""
184
+
185
+ output_key: str = "article_outline_from_raw"
186
+
187
+ async def _execute(self, article_outline_raw_path: str | Path, **cxt) -> ArticleOutline:
188
+ logger.info(f"Extracting outline from raw: {Path(article_outline_raw_path).as_posix()}")
189
+
190
+ return ok(
191
+ await self.extract(ArticleOutline, safe_text_read(article_outline_raw_path)),
192
+ "Could not extract the outline from raw.",
193
+ )
194
+
195
+
180
196
  class FixIntrospectedErrors(Action, Censor):
181
197
  """Fix introspected errors in the article outline."""
182
198
 
@@ -8,6 +8,7 @@ from fabricatio import BibManager
8
8
  from fabricatio.capabilities.censor import Censor
9
9
  from fabricatio.capabilities.extract import Extract
10
10
  from fabricatio.capabilities.rag import RAG
11
+ from fabricatio.decorators import precheck_package
11
12
  from fabricatio.journal import logger
12
13
  from fabricatio.models.action import Action
13
14
  from fabricatio.models.extra.aricle_rag import ArticleChunk, CitationManager
@@ -15,7 +16,7 @@ from fabricatio.models.extra.article_essence import ArticleEssence
15
16
  from fabricatio.models.extra.article_main import Article, ArticleChapter, ArticleSection, ArticleSubsection
16
17
  from fabricatio.models.extra.article_outline import ArticleOutline
17
18
  from fabricatio.models.extra.rule import RuleSet
18
- from fabricatio.utils import ok
19
+ from fabricatio.utils import ask_retain, ok
19
20
 
20
21
 
21
22
  class WriteArticleContentRAG(Action, RAG, Extract):
@@ -23,11 +24,14 @@ class WriteArticleContentRAG(Action, RAG, Extract):
23
24
 
24
25
  ref_limit: int = 35
25
26
  """The limit of references to be retrieved"""
27
+ threshold: float = 0.55
28
+ """The threshold of relevance"""
26
29
  extractor_model: str
27
30
  """The model to use for extracting the content from the retrieved references."""
28
31
  query_model: str
29
32
  """The model to use for querying the database"""
30
-
33
+ supervisor: bool = False
34
+ """Whether to use supervisor mode"""
31
35
  req: str = (
32
36
  "citation number is REQUIRED to cite any reference!\n"
33
37
  "Everything is build upon the typst language, which is similar to latex, \n"
@@ -40,31 +44,75 @@ class WriteArticleContentRAG(Action, RAG, Extract):
40
44
  "you can refer to that label by using the syntax with prefix of `@eqt:`"
41
45
  "Below is a usage example:\n"
42
46
  "```typst\n"
43
- "See @eqt:mass-energy-equation , it's the equation.\n"
47
+ "See @eqt:mass-energy-equation , it's the foundation of physics.\n"
44
48
  "$$\n"
45
49
  "E = m c^2"
46
50
  "$$\n"
47
- "<mass-energy-equation>"
48
- "In @eqt:mass-energy-equation , we get the foundation of physics.\n"
51
+ "<mass-energy-equation>\n\n"
52
+ "In @eqt:mass-energy-equation , $m$ stands for mass, $c$ stands for speed of light, and $E$ stands for energy. \n"
49
53
  "```"
50
54
  )
51
55
 
52
56
  async def _execute(
53
57
  self,
54
58
  article_outline: ArticleOutline,
55
- writing_ruleset: RuleSet,
56
59
  collection_name: str = "article_chunks",
60
+ supervisor: Optional[bool] = None,
57
61
  **cxt,
58
62
  ) -> Article:
59
63
  article = Article.from_outline(article_outline).update_ref(article_outline)
60
- await gather(
61
- *[
62
- self._inner(article, article_outline, chap, sec, subsec)
63
- for chap, sec, subsec in article.iter_subsections()
64
- ]
65
- )
64
+
65
+ if supervisor or (supervisor is None and self.supervisor):
66
+ await gather(
67
+ *[
68
+ self._supervisor_inner(article, article_outline, chap, sec, subsec)
69
+ for chap, sec, subsec in article.iter_subsections()
70
+ ]
71
+ )
72
+ else:
73
+ await gather(
74
+ *[
75
+ self._inner(article, article_outline, chap, sec, subsec)
76
+ for chap, sec, subsec in article.iter_subsections()
77
+ ]
78
+ )
66
79
  return article.convert_tex()
67
80
 
81
+ @precheck_package(
82
+ "questionary", "`questionary` is required for supervisor mode, please install it by `fabricatio[qa]`"
83
+ )
84
+ async def _supervisor_inner(
85
+ self,
86
+ article: Article,
87
+ article_outline: ArticleOutline,
88
+ chap: ArticleChapter,
89
+ sec: ArticleSection,
90
+ subsec: ArticleSubsection,
91
+ ) -> ArticleSubsection:
92
+ from questionary import confirm, text
93
+ from rich import print as r_print
94
+
95
+ ret = await self.search_database(article, article_outline, chap, sec, subsec)
96
+
97
+ cm = CitationManager(article_chunks=await ask_retain([r.chunk for r in ret], ret)).set_cite_number_all()
98
+
99
+ raw = await self.write_raw(article, article_outline, chap, sec, subsec, cm)
100
+ r_print(raw)
101
+
102
+ while not await confirm("Accept this version and continue?").ask_async():
103
+ if await confirm("Search for more refs?").ask_async():
104
+ new_refs = await self.search_database(article, article_outline, chap, sec, subsec, supervisor=True)
105
+ cm.add_chunks(await ask_retain([r.chunk for r in new_refs], new_refs))
106
+
107
+ instruction = await text("Enter the instructions to improve").ask_async()
108
+ raw = await self.write_raw(article, article_outline, chap, sec, subsec, cm, instruction)
109
+ if await confirm("Edit it?").ask_async():
110
+ raw = await text("Edit", default=raw).ask_async() or raw
111
+
112
+ r_print(raw)
113
+
114
+ return await self.extract_new_subsec(subsec, raw, cm)
115
+
68
116
  async def _inner(
69
117
  self,
70
118
  article: Article,
@@ -73,35 +121,17 @@ class WriteArticleContentRAG(Action, RAG, Extract):
73
121
  sec: ArticleSection,
74
122
  subsec: ArticleSubsection,
75
123
  ) -> ArticleSubsection:
76
- ref_q = ok(
77
- await self.arefined_query(
78
- f"{article_outline.display()}\n\nAbove is my article outline, I m writing graduate thesis titled `{article.title}`. "
79
- f"More specifically, i m witting the Chapter `{chap.title}` >> Section `{sec.title}` >> Subsection `{subsec.title}`.\n"
80
- f"I need to search related references to build up the content of the subsec mentioned above, which is `{subsec.title}`.\n"
81
- f"plus, you can search required formulas by using latex equation code.\n"
82
- f"provide 10 queries as possible, to get best result!\n"
83
- f"You should provide both English version and chinese version of the refined queries!\n",
84
- model=self.query_model,
85
- ),
86
- "Failed to refine query.",
87
- )
88
- ret = await self.aretrieve(ref_q, ArticleChunk, final_limit=self.ref_limit, result_per_query=6)
89
- ret.reverse()
90
- cm = CitationManager().update_chunks(ret)
91
-
92
- raw_paras = await self.aask(
93
- f"{cm.as_prompt()}\nAbove is some related reference retrieved for you."
94
- f"{article.referenced.display()}\n\nAbove is my article outline, I m writing graduate thesis titled `{article.title}`. "
95
- f"More specifically, i m witting the Chapter `{chap.title}` >> Section `{sec.title}` >> Subsection `{subsec.title}`.\n"
96
- f"Please help me write the paragraphs of the subsec mentioned above, which is `{subsec.title}`.\n"
97
- f"{self.req}\n"
98
- f"You SHALL use `{article.language}` as writing language."
99
- )
124
+ ret = await self.search_database(article, article_outline, chap, sec, subsec)
125
+ cm = CitationManager(article_chunks=ret).set_cite_number_all()
100
126
 
101
- raw_paras = (
102
- raw_paras.replace(r" \( ", "$").replace(r" \) ", "$").replace("\\[\n", "$$\n").replace("\n\\]", "\n$$")
103
- )
127
+ raw_paras = await self.write_raw(article, article_outline, chap, sec, subsec, cm)
128
+
129
+ return await self.extract_new_subsec(subsec, raw_paras, cm)
104
130
 
131
+ async def extract_new_subsec(
132
+ self, subsec: ArticleSubsection, raw_paras: str, cm: CitationManager
133
+ ) -> ArticleSubsection:
134
+ """Extract the new subsec."""
105
135
  new_subsec = ok(
106
136
  await self.extract(
107
137
  ArticleSubsection,
@@ -112,14 +142,72 @@ class WriteArticleContentRAG(Action, RAG, Extract):
112
142
  ),
113
143
  "Failed to propose new subsection.",
114
144
  )
115
-
116
145
  for p in new_subsec.paragraphs:
117
146
  p.content = cm.apply(p.content).replace("$$", "\n$$\n")
118
-
119
147
  subsec.update_from(new_subsec)
120
148
  logger.debug(f"{subsec.title}:rpl\n{subsec.display()}")
121
149
  return subsec
122
150
 
151
+ async def write_raw(
152
+ self,
153
+ article: Article,
154
+ article_outline: ArticleOutline,
155
+ chap: ArticleChapter,
156
+ sec: ArticleSection,
157
+ subsec: ArticleSubsection,
158
+ cm: CitationManager,
159
+ extra_instruction: str = "",
160
+ ) -> str:
161
+ """Write the raw paragraphs of the subsec."""
162
+ return (
163
+ (
164
+ await self.aask(
165
+ f"{cm.as_prompt()}\nAbove is some related reference retrieved for you."
166
+ f"{article_outline.finalized_dump()}\n\nAbove is my article outline, I m writing graduate thesis titled `{article.title}`. "
167
+ f"More specifically, i m witting the Chapter `{chap.title}` >> Section `{sec.title}` >> Subsection `{subsec.title}`.\n"
168
+ f"Please help me write the paragraphs of the subsec mentioned above, which is `{subsec.title}`.\n"
169
+ f"{self.req}\n"
170
+ f"You SHALL use `{article.language}` as writing language.\n{extra_instruction}"
171
+ )
172
+ )
173
+ .replace(r" \( ", "$")
174
+ .replace(r" \) ", "$")
175
+ .replace(r"\(", "$")
176
+ .replace(r"\)", "$")
177
+ .replace("\\[\n", "$$\n")
178
+ .replace("\n\\]", "\n$$")
179
+ )
180
+
181
+ async def search_database(
182
+ self,
183
+ article: Article,
184
+ article_outline: ArticleOutline,
185
+ chap: ArticleChapter,
186
+ sec: ArticleSection,
187
+ subsec: ArticleSubsection,
188
+ extra_instruction: str = "",
189
+ supervisor: bool = False,
190
+ ) -> List[ArticleChunk]:
191
+ """Search database for related references."""
192
+ ref_q = ok(
193
+ await self.arefined_query(
194
+ f"{article_outline.finalized_dump()}\n\nAbove is my article outline, I m writing graduate thesis titled `{article.title}`. "
195
+ f"More specifically, i m witting the Chapter `{chap.title}` >> Section `{sec.title}` >> Subsection `{subsec.title}`.\n"
196
+ f"I need to search related references to build up the content of the subsec mentioned above, which is `{subsec.title}`.\n"
197
+ f"provide 10~16 queries as possible, to get best result!\n"
198
+ f"You should provide both English version and chinese version of the refined queries!\n{extra_instruction}\n",
199
+ model=self.query_model,
200
+ ),
201
+ "Failed to refine query.",
202
+ )
203
+
204
+ if supervisor:
205
+ ref_q = await ask_retain(ref_q)
206
+
207
+ return await self.aretrieve(
208
+ ref_q, ArticleChunk, final_limit=self.ref_limit, result_per_query=3, similarity_threshold=self.threshold
209
+ )
210
+
123
211
 
124
212
  class TweakArticleRAG(Action, RAG, Censor):
125
213
  """Write an article based on the provided outline.
@@ -6,7 +6,7 @@ from importlib.util import find_spec
6
6
  from inspect import signature
7
7
  from shutil import which
8
8
  from types import ModuleType
9
- from typing import Callable, List, Optional
9
+ from typing import Callable, Coroutine, List, Optional
10
10
 
11
11
  from fabricatio.config import configs
12
12
  from fabricatio.journal import logger
@@ -23,7 +23,20 @@ def precheck_package[**P, R](package_name: str, msg: str) -> Callable[[Callable[
23
23
  bool: True if the package exists, False otherwise.
24
24
  """
25
25
 
26
- def _wrapper(func: Callable[P, R]) -> Callable[P, R]:
26
+ def _wrapper(
27
+ func: Callable[P, R] | Callable[P, Coroutine[None, None, R]],
28
+ ) -> Callable[P, R] | Callable[P, Coroutine[None, None, R]]:
29
+ if iscoroutinefunction(func):
30
+
31
+ @wraps(func)
32
+ async def _async_inner(*args: P.args, **kwargs: P.kwargs) -> R:
33
+ if find_spec(package_name):
34
+ return await func(*args, **kwargs)
35
+ raise RuntimeError(msg)
36
+
37
+ return _async_inner
38
+
39
+ @wraps(func)
27
40
  def _inner(*args: P.args, **kwargs: P.kwargs) -> R:
28
41
  if find_spec(package_name):
29
42
  return func(*args, **kwargs)
@@ -35,7 +48,7 @@ def precheck_package[**P, R](package_name: str, msg: str) -> Callable[[Callable[
35
48
 
36
49
 
37
50
  def depend_on_external_cmd[**P, R](
38
- bin_name: str, install_tip: Optional[str], homepage: Optional[str] = None
51
+ bin_name: str, install_tip: Optional[str], homepage: Optional[str] = None
39
52
  ) -> Callable[[Callable[P, R]], Callable[P, R]]:
40
53
  """Decorator to check for the presence of an external command.
41
54
 
@@ -88,8 +101,9 @@ def logging_execution_info[**P, R](func: Callable[P, R]) -> Callable[P, R]:
88
101
  return _wrapper
89
102
 
90
103
 
91
- @precheck_package("questionary",
92
- "'questionary' is required to run this function. Have you installed `fabricatio[qa]`?.")
104
+ @precheck_package(
105
+ "questionary", "'questionary' is required to run this function. Have you installed `fabricatio[qa]`?."
106
+ )
93
107
  def confirm_to_execute[**P, R](func: Callable[P, R]) -> Callable[P, Optional[R]] | Callable[P, R]:
94
108
  """Decorator to confirm before executing a function.
95
109
 
@@ -109,8 +123,8 @@ def confirm_to_execute[**P, R](func: Callable[P, R]) -> Callable[P, Optional[R]]
109
123
  @wraps(func)
110
124
  async def _wrapper(*args: P.args, **kwargs: P.kwargs) -> Optional[R]:
111
125
  if await confirm(
112
- f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n🔑 Kwargs:{kwargs}\n",
113
- instruction="Please input [Yes/No] to proceed (default: Yes):",
126
+ f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n🔑 Kwargs:{kwargs}\n",
127
+ instruction="Please input [Yes/No] to proceed (default: Yes):",
114
128
  ).ask_async():
115
129
  return await func(*args, **kwargs)
116
130
  logger.warning(f"Function: {func.__name__}{signature(func)} canceled by user.")
@@ -121,8 +135,8 @@ def confirm_to_execute[**P, R](func: Callable[P, R]) -> Callable[P, Optional[R]]
121
135
  @wraps(func)
122
136
  def _wrapper(*args: P.args, **kwargs: P.kwargs) -> Optional[R]:
123
137
  if confirm(
124
- f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n��� Kwargs:{kwargs}\n",
125
- instruction="Please input [Yes/No] to proceed (default: Yes):",
138
+ f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n��� Kwargs:{kwargs}\n",
139
+ instruction="Please input [Yes/No] to proceed (default: Yes):",
126
140
  ).ask():
127
141
  return func(*args, **kwargs)
128
142
  logger.warning(f"Function: {func.__name__}{signature(func)} canceled by user.")
@@ -203,7 +217,9 @@ def use_temp_module[**P, R](modules: ModuleType | List[ModuleType]) -> Callable[
203
217
  return _decorator
204
218
 
205
219
 
206
- def logging_exec_time[**P, R](func: Callable[P, R]) -> Callable[P, R]:
220
+ def logging_exec_time[**P, R](
221
+ func: Callable[P, R] | Callable[P, Coroutine[None, None, R]],
222
+ ) -> Callable[P, R] | Callable[P, Coroutine[None, None, R]]:
207
223
  """Decorator to log the execution time of a function.
208
224
 
209
225
  Args:
@@ -215,6 +231,7 @@ def logging_exec_time[**P, R](func: Callable[P, R]) -> Callable[P, R]:
215
231
  from time import time
216
232
 
217
233
  if iscoroutinefunction(func):
234
+
218
235
  @wraps(func)
219
236
  async def _async_wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
220
237
  start_time = time()
@@ -18,6 +18,7 @@ from fabricatio.journal import logger
18
18
  from fabricatio.models.generic import WithBriefing
19
19
  from fabricatio.models.task import Task
20
20
  from fabricatio.models.usages import LLMUsage, ToolBoxUsage
21
+ from fabricatio.utils import override_kwargs
21
22
  from pydantic import Field, PrivateAttr
22
23
 
23
24
  OUTPUT_KEY = "task_output"
@@ -55,7 +56,7 @@ class Action(WithBriefing, LLMUsage):
55
56
  self.description = self.description or self.__class__.__doc__ or ""
56
57
 
57
58
  @abstractmethod
58
- async def _execute(self, *_:Any, **cxt) -> Any:
59
+ async def _execute(self, *_: Any, **cxt) -> Any:
59
60
  """Implement the core logic of the action.
60
61
 
61
62
  Args:
@@ -95,11 +96,12 @@ class Action(WithBriefing, LLMUsage):
95
96
  return f"## Your personality: \n{self.personality}\n# The action you are going to perform: \n{super().briefing}"
96
97
  return f"# The action you are going to perform: \n{super().briefing}"
97
98
 
98
- def to_task_output(self)->Self:
99
+ def to_task_output(self) -> Self:
99
100
  """Set the output key to OUTPUT_KEY and return the action instance."""
100
- self.output_key=OUTPUT_KEY
101
+ self.output_key = OUTPUT_KEY
101
102
  return self
102
103
 
104
+
103
105
  class WorkFlow(WithBriefing, ToolBoxUsage):
104
106
  """Manages sequences of actions to fulfill tasks.
105
107
 
@@ -177,7 +179,7 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
177
179
  current_action = None
178
180
  try:
179
181
  # Process each action in sequence
180
- for i,step in enumerate(self._instances):
182
+ for i, step in enumerate(self._instances):
181
183
  current_action = step.name
182
184
  logger.info(f"Executing step [{i}] >> {current_action}")
183
185
 
@@ -227,8 +229,13 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
227
229
  - Any extra_init_context values
228
230
  """
229
231
  logger.debug(f"Initializing context for workflow: {self.name}")
230
- initial_context = {self.task_input_key: task, **dict(self.extra_init_context)}
231
- await self._context.put(initial_context)
232
+ ctx = override_kwargs(self.extra_init_context, **task.extra_init_context)
233
+ if self.task_input_key in ctx:
234
+ raise ValueError(
235
+ f"Task input key: `{self.task_input_key}`, which is reserved, is already set in the init context"
236
+ )
237
+
238
+ await self._context.put({self.task_input_key: task, **ctx})
232
239
 
233
240
  def steps_fallback_to_self(self) -> Self:
234
241
  """Configure all steps to use this workflow's configuration as fallback.
@@ -245,7 +252,7 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
245
252
  Returns:
246
253
  Self: The workflow instance for method chaining.
247
254
  """
248
- self.provide_tools_to(i for i in self._instances if isinstance(i,ToolBoxUsage))
255
+ self.provide_tools_to(i for i in self._instances if isinstance(i, ToolBoxUsage))
249
256
  return self
250
257
 
251
258
  def update_init_context(self, /, **kwargs) -> Self:
@@ -190,6 +190,12 @@ class CitationManager(AsPrompt):
190
190
  self.set_cite_number_all()
191
191
  return self
192
192
 
193
+ def add_chunks(self, article_chunks: List[ArticleChunk], set_cite_number: bool = True)-> Self:
194
+ """Add article chunks."""
195
+ self.article_chunks.extend(article_chunks)
196
+ if set_cite_number:
197
+ self.set_cite_number_all()
198
+ return self
193
199
  def set_cite_number_all(self) -> Self:
194
200
  """Set citation numbers for all article chunks."""
195
201
  for i, a in enumerate(self.article_chunks, 1):