fabricatio 0.2.12.dev3__tar.gz → 0.2.13.dev1__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 (167) hide show
  1. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/Cargo.lock +2 -0
  2. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/PKG-INFO +5 -1
  3. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/README.md +4 -0
  4. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/write_article/write_article.py +39 -6
  5. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/pyproject.toml +1 -1
  6. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/actions/article.py +49 -1
  7. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/actions/article_rag.py +10 -1
  8. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/advanced_rag.py +5 -5
  9. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/rag.py +31 -5
  10. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/config.py +8 -3
  11. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/action.py +16 -3
  12. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/adv_kwargs_types.py +3 -1
  13. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/article_base.py +40 -7
  14. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/article_main.py +34 -39
  15. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/generic.py +3 -3
  16. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/kwargs_types.py +9 -1
  17. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/rust.pyi +5 -0
  18. fabricatio-0.2.13.dev1/python/fabricatio/utils.py +255 -0
  19. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/src/typst_tools.rs +26 -3
  20. fabricatio-0.2.13.dev1/templates/built-in/chap_summary.hbs +31 -0
  21. fabricatio-0.2.13.dev1/templates.tar.gz +0 -0
  22. fabricatio-0.2.13.dev1/uv.lock +1706 -0
  23. fabricatio-0.2.12.dev3/python/fabricatio/utils.py +0 -94
  24. fabricatio-0.2.12.dev3/templates.tar.gz +0 -0
  25. fabricatio-0.2.12.dev3/uv.lock +0 -1709
  26. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/.github/workflows/build-package.yaml +0 -0
  27. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/.github/workflows/ruff.yaml +0 -0
  28. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/.github/workflows/tests.yaml +0 -0
  29. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/.gitignore +0 -0
  30. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/.python-version +0 -0
  31. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/Cargo.toml +0 -0
  32. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/LICENSE +0 -0
  33. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/Makefile +0 -0
  34. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/correct/correct.py +0 -0
  35. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/correct/correct_loop.py +0 -0
  36. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/extract_and_inject/.gitignore +0 -0
  37. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/extract_and_inject/article_rag.py +0 -0
  38. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/extract_and_inject/ask.py +0 -0
  39. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/extract_and_inject/chunk_article.py +0 -0
  40. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/extract_and_inject/extract_and_inject.py +0 -0
  41. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/extract_article/extract.py +0 -0
  42. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/llm_usages/llm_usage.py +0 -0
  43. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/make_a_rating/rating.py +0 -0
  44. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/make_diary/commits.json +0 -0
  45. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/make_diary/diary.py +0 -0
  46. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/minor/hello_fabricatio.py +0 -0
  47. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/minor/write_a_poem.py +0 -0
  48. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/propose_task/.gitignore +0 -0
  49. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/propose_task/propose.py +0 -0
  50. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/reviewer/censor.py +0 -0
  51. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/reviewer/review.py +0 -0
  52. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/rules/.gitignore +0 -0
  53. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/rules/draft_ruleset.py +0 -0
  54. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/search_bibtex/.gitignore +0 -0
  55. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/search_bibtex/search.py +0 -0
  56. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/simple_chat/chat.py +0 -0
  57. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/simple_rag/simple_rag.py +0 -0
  58. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/task_handle/handle_task.py +0 -0
  59. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/write_article/.gitignore +0 -0
  60. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/write_article/article_rag.py +0 -0
  61. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/write_article/post_process.py +0 -0
  62. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/write_outline/.gitignore +0 -0
  63. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/write_outline/write_outline.py +0 -0
  64. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/examples/write_outline/write_outline_corrected.py +0 -0
  65. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/__init__.py +0 -0
  66. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/actions/__init__.py +0 -0
  67. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/actions/fs.py +0 -0
  68. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/actions/output.py +0 -0
  69. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/actions/rag.py +0 -0
  70. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/actions/rules.py +0 -0
  71. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/__init__.py +0 -0
  72. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/advanced_judge.py +0 -0
  73. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/censor.py +0 -0
  74. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/check.py +0 -0
  75. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/correct.py +0 -0
  76. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/extract.py +0 -0
  77. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/propose.py +0 -0
  78. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/rating.py +0 -0
  79. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/review.py +0 -0
  80. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/capabilities/task.py +0 -0
  81. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/constants.py +0 -0
  82. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/core.py +0 -0
  83. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/decorators.py +0 -0
  84. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/fs/__init__.py +0 -0
  85. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/fs/curd.py +0 -0
  86. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/fs/readers.py +0 -0
  87. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/journal.py +0 -0
  88. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/events.py +0 -0
  89. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/__init__.py +0 -0
  90. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/advanced_judge.py +0 -0
  91. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/aricle_rag.py +0 -0
  92. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/article_essence.py +0 -0
  93. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/article_outline.py +0 -0
  94. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/article_proposal.py +0 -0
  95. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/patches.py +0 -0
  96. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/problem.py +0 -0
  97. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/rag.py +0 -0
  98. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/extra/rule.py +0 -0
  99. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/role.py +0 -0
  100. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/task.py +0 -0
  101. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/tool.py +0 -0
  102. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/models/usages.py +0 -0
  103. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/parser.py +0 -0
  104. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/py.typed +0 -0
  105. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/rust_instances.py +0 -0
  106. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/toolboxes/__init__.py +0 -0
  107. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/toolboxes/arithmetic.py +0 -0
  108. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/toolboxes/fs.py +0 -0
  109. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/workflows/__init__.py +0 -0
  110. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/workflows/articles.py +0 -0
  111. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/python/fabricatio/workflows/rag.py +0 -0
  112. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/src/bib_tools.rs +0 -0
  113. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/src/hash.rs +0 -0
  114. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/src/hbs_helpers.rs +0 -0
  115. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/src/language.rs +0 -0
  116. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/src/lib.rs +0 -0
  117. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/src/templates.rs +0 -0
  118. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/src/word_split.rs +0 -0
  119. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/as_prompt.hbs +0 -0
  120. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/binary-exploitation-ctf-solver.hbs +0 -0
  121. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/check_string.hbs +0 -0
  122. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/claude-xml.hbs +0 -0
  123. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/clean-up-code.hbs +0 -0
  124. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/co_validation.hbs +0 -0
  125. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/create_json_obj.hbs +0 -0
  126. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/cryptography-ctf-solver.hbs +0 -0
  127. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/dependencies.hbs +0 -0
  128. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/document-the-code.hbs +0 -0
  129. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/draft_rating_criteria.hbs +0 -0
  130. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/draft_rating_manual.hbs +0 -0
  131. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/draft_rating_weights_klee.hbs +0 -0
  132. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/draft_tool_usage_code.hbs +0 -0
  133. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/extract.hbs +0 -0
  134. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/extract_criteria_from_reasons.hbs +0 -0
  135. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/extract_reasons_from_examples.hbs +0 -0
  136. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/find-security-vulnerabilities.hbs +0 -0
  137. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/fix-bugs.hbs +0 -0
  138. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/fix_troubled_obj.hbs +0 -0
  139. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/fix_troubled_string.hbs +0 -0
  140. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/generic_string.hbs +0 -0
  141. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/improve-performance.hbs +0 -0
  142. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/liststr.hbs +0 -0
  143. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/make_choice.hbs +0 -0
  144. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/make_judgment.hbs +0 -0
  145. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/pathstr.hbs +0 -0
  146. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/rate_fine_grind.hbs +0 -0
  147. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/refactor.hbs +0 -0
  148. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/refined_query.hbs +0 -0
  149. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/retrieved_display.hbs +0 -0
  150. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/reverse-engineering-ctf-solver.hbs +0 -0
  151. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/review_string.hbs +0 -0
  152. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/rule_requirement.hbs +0 -0
  153. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/ruleset_requirement_breakdown.hbs +0 -0
  154. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/task_briefing.hbs +0 -0
  155. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/web-ctf-solver.hbs +0 -0
  156. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/write-git-commit.hbs +0 -0
  157. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/write-github-pull-request.hbs +0 -0
  158. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/templates/built-in/write-github-readme.hbs +0 -0
  159. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_config.py +0 -0
  160. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_models/test_action.py +0 -0
  161. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_models/test_advanced.py +0 -0
  162. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_models/test_generic.py +0 -0
  163. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_models/test_problem.py +0 -0
  164. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_models/test_role.py +0 -0
  165. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_models/test_task.py +0 -0
  166. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_models/test_tool.py +0 -0
  167. {fabricatio-0.2.12.dev3 → fabricatio-0.2.13.dev1}/tests/test_models/test_usages.py +0 -0
@@ -1982,9 +1982,11 @@ dependencies = [
1982
1982
  "clap",
1983
1983
  "dirs",
1984
1984
  "flate2",
1985
+ "regex",
1985
1986
  "reqwest",
1986
1987
  "serde_json",
1987
1988
  "tar",
1989
+ "tex2typst-rs",
1988
1990
  ]
1989
1991
 
1990
1992
  [[package]]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fabricatio
3
- Version: 0.2.12.dev3
3
+ Version: 0.2.13.dev1
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -165,6 +165,10 @@ max_tokens = 8192
165
165
  ```bash
166
166
  make test
167
167
  ```
168
+ ## TODO
169
+
170
+ - Add an element based format strategy
171
+
168
172
 
169
173
  ## Contributing
170
174
 
@@ -119,6 +119,10 @@ max_tokens = 8192
119
119
  ```bash
120
120
  make test
121
121
  ```
122
+ ## TODO
123
+
124
+ - Add an element based format strategy
125
+
122
126
 
123
127
  ## Contributing
124
128
 
@@ -2,12 +2,20 @@
2
2
 
3
3
  import asyncio
4
4
  from pathlib import Path
5
+ from typing import Optional
5
6
 
6
7
  import typer
7
8
  from fabricatio import Event, Role, WorkFlow, logger
8
- from fabricatio.actions.article import ExtractOutlineFromRaw, GenerateArticleProposal, GenerateInitialOutline
9
+ from fabricatio.actions.article import (
10
+ ExtractOutlineFromRaw,
11
+ GenerateArticleProposal,
12
+ GenerateInitialOutline,
13
+ WriteChapterSummary,
14
+ )
9
15
  from fabricatio.actions.article_rag import ArticleConsultRAG, WriteArticleContentRAG
10
16
  from fabricatio.actions.output import DumpFinalizedOutput, PersistentAll, RenderedDump
17
+ from fabricatio.fs import safe_text_read
18
+ from fabricatio.models.extra.article_main import Article
11
19
  from fabricatio.models.extra.article_outline import ArticleOutline
12
20
  from fabricatio.models.task import Task
13
21
  from fabricatio.utils import ok
@@ -18,7 +26,7 @@ from typer import Typer
18
26
  Role(
19
27
  name="Undergraduate Researcher",
20
28
  description="Write an outline for an article in typst format.",
21
- llm_model="openai/deepseek-v3-250324",
29
+ llm_model="openai/qwen-plus",
22
30
  llm_temperature=0.45,
23
31
  # llm_api_endpoint=HttpUrl("https://dashscope.aliyuncs.com/compatible-mode/v1"),
24
32
  llm_top_p=0.95,
@@ -74,7 +82,12 @@ Role(
74
82
  Event.quick_instantiate(ns4 := "consult"): WorkFlow(
75
83
  name="Consult Article",
76
84
  description="Consult an article with given article outline. dump the outline to the given path. in typst format.",
77
- steps=(ArticleConsultRAG(ref_q_model={"model":"openai/qwen-turbo"}).to_task_output(),),
85
+ steps=(ArticleConsultRAG(ref_q_model={"model": "openai/qwen-turbo"}).to_task_output(),),
86
+ ),
87
+ Event.quick_instantiate(ns5 := "chap-suma"): WorkFlow(
88
+ name="Chapter Summary",
89
+ description="Generate chapter summary based on given article outline. dump the outline to the given path. in typst format.",
90
+ steps=(WriteChapterSummary().to_task_output(),),
78
91
  ),
79
92
  },
80
93
  )
@@ -86,13 +99,12 @@ app = Typer()
86
99
  @app.command()
87
100
  def consult(
88
101
  collection_name: str = typer.Option("article_chunks", "-c", "--collection-name", help="Name of the collection."),
102
+ tei_endpoint: Optional[str] = typer.Option(None, "-t", "--tei-endpoint", help="TEI endpoint."),
89
103
  ) -> None:
90
104
  """Consult an article based on a given article outline."""
91
105
  _ = asyncio.run(
92
106
  Task(name="Answer Question")
93
- .update_init_context(
94
- collection_name=collection_name,
95
- )
107
+ .update_init_context(collection_name=collection_name, tei_endpoint=tei_endpoint)
96
108
  .delegate(ns4)
97
109
  )
98
110
 
@@ -193,5 +205,26 @@ def write(
193
205
  logger.success(f"The outline is saved in:\n{path}")
194
206
 
195
207
 
208
+ @app.command()
209
+ def suma(
210
+ article_path: Path = typer.Option( # noqa: B008
211
+ Path("article.typ"), "-a", "--article-path", help="Path to the article file."
212
+ ),
213
+ dump_path: Path = typer.Option(Path("out.typ"), "-d", "--dump-path", help="Path to dump the final output."), # noqa: B008
214
+ ) -> None:
215
+ path = ok(
216
+ asyncio.run(
217
+ Task(name="write an article")
218
+ .update_init_context(
219
+ article=Article.from_typst_code("article", body=safe_text_read(article_path)),
220
+ write_to=dump_path,
221
+ )
222
+ .delegate(ns5)
223
+ ),
224
+ "Failed to generate an article ",
225
+ )
226
+ logger.success(f"The outline is saved in:\n{path}")
227
+
228
+
196
229
  if __name__ == "__main__":
197
230
  app()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fabricatio"
3
- version = "0.2.12-dev3"
3
+ version = "0.2.13-dev1"
4
4
  description = "A LLM multi-agent framework."
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -8,10 +8,12 @@ from more_itertools import filter_map
8
8
  from pydantic import Field
9
9
  from rich import print as r_print
10
10
 
11
+ from fabricatio import TEMPLATE_MANAGER
11
12
  from fabricatio.capabilities.censor import Censor
12
13
  from fabricatio.capabilities.extract import Extract
13
14
  from fabricatio.capabilities.propose import Propose
14
- from fabricatio.fs import safe_text_read
15
+ from fabricatio.config import configs
16
+ from fabricatio.fs import dump_text, safe_text_read
15
17
  from fabricatio.journal import logger
16
18
  from fabricatio.models.action import Action
17
19
  from fabricatio.models.extra.article_essence import ArticleEssence
@@ -21,6 +23,7 @@ from fabricatio.models.extra.article_proposal import ArticleProposal
21
23
  from fabricatio.models.extra.rule import RuleSet
22
24
  from fabricatio.models.kwargs_types import ValidateKwargs
23
25
  from fabricatio.models.task import Task
26
+ from fabricatio.models.usages import LLMUsage
24
27
  from fabricatio.rust import BibManager, detect_language
25
28
  from fabricatio.utils import ok, wrapp_in_block
26
29
 
@@ -271,3 +274,48 @@ class LoadArticle(Action):
271
274
 
272
275
  async def _execute(self, article_outline: ArticleOutline, typst_code: str, **cxt) -> Article:
273
276
  return Article.from_mixed_source(article_outline, typst_code)
277
+
278
+
279
+ class WriteChapterSummary(Action, LLMUsage):
280
+ """Write the chapter summary."""
281
+
282
+ output_key: str = "chapter_summaries"
283
+
284
+ paragraph_count: int = 1
285
+
286
+ summary_word_count: int = 200
287
+
288
+ summary_title: str = "Chapter Summary"
289
+ write_to: Optional[Path] = None
290
+
291
+ async def _execute(self, article: Article, write_to: Optional[Path] = None, **cxt) -> List[str]:
292
+ logger.info(";".join(a.title for a in article.chapters))
293
+
294
+ ret = [
295
+ f"== {self.summary_title}\n{raw}"
296
+ for raw in (
297
+ await self.aask(
298
+ TEMPLATE_MANAGER.render_template(
299
+ configs.templates.chap_summary_template,
300
+ [
301
+ {
302
+ "chapter": a.to_typst_code(),
303
+ "title": a.title,
304
+ "language": a.language,
305
+ "summary_word_count": self.summary_word_count,
306
+ "paragraph_count": self.paragraph_count,
307
+ }
308
+ for a in article.chapters
309
+ ],
310
+ )
311
+ )
312
+ )
313
+ ]
314
+
315
+ if (to := (self.write_to or write_to)) is not None:
316
+ dump_text(
317
+ to,
318
+ "\n\n\n".join(f"//{a.title}\n\n{s}" for a, s in zip(article.chapters, ret, strict=True)),
319
+ )
320
+
321
+ return ret
@@ -2,7 +2,7 @@
2
2
 
3
3
  from asyncio import gather
4
4
  from pathlib import Path
5
- from typing import List, Optional
5
+ from typing import ClassVar, List, Optional
6
6
 
7
7
  from pydantic import Field, PositiveInt
8
8
 
@@ -20,6 +20,7 @@ from fabricatio.models.extra.article_main import Article, ArticleChapter, Articl
20
20
  from fabricatio.models.extra.article_outline import ArticleOutline
21
21
  from fabricatio.models.extra.rule import RuleSet
22
22
  from fabricatio.models.kwargs_types import ChooseKwargs, LLMKwargs
23
+ from fabricatio.rust import convert_to_block_formula, convert_to_inline_formula
23
24
  from fabricatio.utils import ask_retain, ok
24
25
 
25
26
  TYPST_CITE_USAGE = (
@@ -162,6 +163,7 @@ class WriteArticleContentRAG(Action, RAG, Extract):
162
163
  )
163
164
  for p in new_subsec.paragraphs:
164
165
  p.content = cm.apply(p.content)
166
+ p.description = cm.apply(p.description)
165
167
  subsec.update_from(new_subsec)
166
168
  logger.debug(f"{subsec.title}:rpl\n{subsec.display()}")
167
169
  return subsec
@@ -255,6 +257,7 @@ class WriteArticleContentRAG(Action, RAG, Extract):
255
257
  class ArticleConsultRAG(Action, AdvancedRAG):
256
258
  """Write an article based on the provided outline."""
257
259
 
260
+ ctx_override: ClassVar[bool] = True
258
261
  output_key: str = "consult_count"
259
262
  search_increment_multiplier: float = 1.6
260
263
  """The multiplier to increase the limit of references to retrieve per query."""
@@ -268,6 +271,7 @@ class ArticleConsultRAG(Action, AdvancedRAG):
268
271
  """The model to use for refining query."""
269
272
  req: str = TYPST_CITE_USAGE
270
273
  """The request for the rag model."""
274
+ tei_endpoint: Optional[str] = None
271
275
 
272
276
  @precheck_package(
273
277
  "questionary", "`questionary` is required for supervisor mode, please install it by `fabricatio[qa]`"
@@ -286,6 +290,10 @@ class ArticleConsultRAG(Action, AdvancedRAG):
286
290
  while (req := await text("User: ").ask_async()) is not None:
287
291
  if await confirm("Empty the cm?").ask_async():
288
292
  cm.empty()
293
+
294
+ req = convert_to_block_formula(req)
295
+ req = convert_to_inline_formula(req)
296
+
289
297
  await self.clued_search(
290
298
  req,
291
299
  cm,
@@ -294,6 +302,7 @@ class ArticleConsultRAG(Action, AdvancedRAG):
294
302
  base_accepted=self.ref_limit,
295
303
  result_per_query=self.ref_per_q,
296
304
  similarity_threshold=self.similarity_threshold,
305
+ tei_endpoint=self.tei_endpoint,
297
306
  )
298
307
 
299
308
  ret = await self.aask(f"{cm.as_prompt()}\n{self.req}\n{req}")
@@ -24,7 +24,7 @@ class AdvancedRAG(RAG):
24
24
  **kwargs: Unpack[FetchKwargs],
25
25
  ) -> CitationManager:
26
26
  """Asynchronously performs a clued search based on a given requirement and citation manager."""
27
- if max_round<=0:
27
+ if max_round <= 0:
28
28
  raise ValueError("max_round should be greater than 0")
29
29
  if max_round == 1:
30
30
  logger.warning(
@@ -33,21 +33,21 @@ class AdvancedRAG(RAG):
33
33
 
34
34
  refinery_kwargs = refinery_kwargs or {}
35
35
 
36
- for i in range(max_round + 1, 1):
37
- logger.info(f"Round [{i + 1}/{max_round}] search started.")
36
+ for i in range(1, max_round + 1):
37
+ logger.info(f"Round [{i}/{max_round}] search started.")
38
38
  ref_q = await self.arefined_query(
39
39
  f"{cm.as_prompt()}\n\nAbove is the retrieved references in the {i - 1}th RAG, now we need to perform the {i}th RAG."
40
40
  f"\n\n{requirement}",
41
41
  **refinery_kwargs,
42
42
  )
43
43
  if ref_q is None:
44
- logger.error(f"At round [{i + 1}/{max_round}] search, failed to refine the query, exit.")
44
+ logger.error(f"At round [{i}/{max_round}] search, failed to refine the query, exit.")
45
45
  return cm
46
46
  refs = await self.aretrieve(ref_q, ArticleChunk, base_accepted, **kwargs)
47
47
 
48
48
  if (max_capacity := max_capacity - len(refs)) < 0:
49
49
  cm.add_chunks(refs[0:max_capacity])
50
- logger.debug(f"At round [{i + 1}/{max_round}] search, the capacity is not enough, exit.")
50
+ logger.debug(f"At round [{i}/{max_round}] search, the capacity is not enough, exit.")
51
51
  return cm
52
52
 
53
53
  cm.add_chunks(refs)
@@ -143,21 +143,25 @@ class RAG(EmbeddingUsage):
143
143
 
144
144
  async def afetch_document[D: MilvusDataBase](
145
145
  self,
146
- vecs: List[List[float]],
146
+ query: List[str],
147
147
  document_model: Type[D],
148
148
  collection_name: Optional[str] = None,
149
149
  similarity_threshold: float = 0.37,
150
150
  result_per_query: int = 10,
151
+ tei_endpoint: Optional[str] = None,
152
+ reranker_threshold: float = 0.7,
151
153
  ) -> List[D]:
152
154
  """Asynchronously fetches documents from a Milvus database based on input vectors.
153
155
 
154
156
  Args:
155
- vecs (List[List[float]]): A list of vectors to search for in the database.
157
+ query (List[str]): A list of vectors to search for in the database.
156
158
  document_model (Type[D]): The model class used to convert fetched data into document objects.
157
159
  collection_name (Optional[str]): The name of the collection to search within.
158
160
  If None, the currently viewed collection is used.
159
161
  similarity_threshold (float): The similarity threshold for vector search. Defaults to 0.37.
160
162
  result_per_query (int): The maximum number of results to return per query. Defaults to 10.
163
+ tei_endpoint (str): the endpoint of the TEI api.
164
+ reranker_threshold (float): The threshold used to filtered low relativity document.
161
165
 
162
166
  Returns:
163
167
  List[D]: A list of document objects created from the fetched data.
@@ -165,15 +169,34 @@ class RAG(EmbeddingUsage):
165
169
  # Step 1: Search for vectors
166
170
  search_results = self.check_client().client.search(
167
171
  collection_name or self.safe_target_collection,
168
- vecs,
172
+ await self.vectorize(query),
169
173
  search_params={"radius": similarity_threshold},
170
174
  output_fields=list(document_model.model_fields),
171
175
  limit=result_per_query,
172
176
  )
177
+ if tei_endpoint is not None:
178
+ from fabricatio.utils import RerankerAPI
179
+
180
+ reranker = RerankerAPI(base_url=tei_endpoint)
181
+
182
+ retrieved_id = set()
183
+ raw_result = []
184
+
185
+ for q, g in zip(query, search_results, strict=True):
186
+ models = document_model.from_sequence([res["entity"] for res in g if res["id"] not in retrieved_id])
187
+ retrieved_id.update(res["id"] for res in g)
188
+ rank_scores = await reranker.arerank(q, [m.prepare_vectorization() for m in models])
189
+ raw_result.extend(
190
+ (models[s["index"]], s["score"]) for s in rank_scores if s["score"] > reranker_threshold
191
+ )
192
+
193
+ raw_result_sorted = sorted(raw_result, key=lambda x: x[1], reverse=True)
194
+ return [r[0] for r in raw_result_sorted]
173
195
 
174
196
  # Step 2: Flatten the search results
175
197
  flattened_results = flatten(search_results)
176
198
  unique_results = unique(flattened_results, key=itemgetter("id"))
199
+
177
200
  # Step 3: Sort by distance (descending)
178
201
  sorted_results = sorted(unique_results, key=itemgetter("distance"), reverse=True)
179
202
 
@@ -205,15 +228,18 @@ class RAG(EmbeddingUsage):
205
228
  """
206
229
  if isinstance(query, str):
207
230
  query = [query]
231
+
208
232
  return (
209
233
  await self.afetch_document(
210
- vecs=(await self.vectorize(query)),
234
+ query=query,
211
235
  document_model=document_model,
212
236
  **kwargs,
213
237
  )
214
238
  )[:max_accepted]
215
239
 
216
- async def arefined_query(self, question: List[str] | str, **kwargs: Unpack[ChooseKwargs[Optional[List[str]]]]) -> Optional[List[str]]:
240
+ async def arefined_query(
241
+ self, question: List[str] | str, **kwargs: Unpack[ChooseKwargs[Optional[List[str]]]]
242
+ ) -> Optional[List[str]]:
217
243
  """Refines the given question using a template.
218
244
 
219
245
  Args:
@@ -86,10 +86,12 @@ class LLMConfig(BaseModel):
86
86
 
87
87
  tpm: Optional[PositiveInt] = Field(default=1000000)
88
88
  """The rate limit of the LLM model in tokens per minute. None means not checked."""
89
- presence_penalty:Optional[PositiveFloat]=None
89
+ presence_penalty: Optional[PositiveFloat] = None
90
90
  """The presence penalty of the LLM model."""
91
- frequency_penalty:Optional[PositiveFloat]=None
91
+ frequency_penalty: Optional[PositiveFloat] = None
92
92
  """The frequency penalty of the LLM model."""
93
+
94
+
93
95
  class EmbeddingConfig(BaseModel):
94
96
  """Embedding configuration class."""
95
97
 
@@ -252,10 +254,13 @@ class TemplateConfig(BaseModel):
252
254
  rule_requirement_template: str = Field(default="rule_requirement")
253
255
  """The name of the rule requirement template which will be used to generate a rule requirement."""
254
256
 
255
-
256
257
  extract_template: str = Field(default="extract")
257
258
  """The name of the extract template which will be used to extract model from string."""
258
259
 
260
+ chap_summary_template: str = Field(default="chap_summary")
261
+ """The name of the chap summary template which will be used to generate a chapter summary."""
262
+
263
+
259
264
  class MagikaConfig(BaseModel):
260
265
  """Magika configuration class."""
261
266
 
@@ -12,7 +12,7 @@ Classes:
12
12
  import traceback
13
13
  from abc import abstractmethod
14
14
  from asyncio import Queue, create_task
15
- from typing import Any, Dict, Self, Sequence, Tuple, Type, Union, final
15
+ from typing import Any, ClassVar, Dict, Self, Sequence, Tuple, Type, Union, final
16
16
 
17
17
  from fabricatio.journal import logger
18
18
  from fabricatio.models.generic import WithBriefing
@@ -33,6 +33,9 @@ class Action(WithBriefing):
33
33
  a specific operation and can modify the shared context data.
34
34
  """
35
35
 
36
+ ctx_override: ClassVar[bool] = False
37
+ """Whether to override the instance attr by the context variable."""
38
+
36
39
  name: str = Field(default="")
37
40
  """The name of the action."""
38
41
 
@@ -157,6 +160,15 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
157
160
  action.personality = personality
158
161
  return self
159
162
 
163
+ def override_action_variable(self, action: Action, ctx: Dict[str, Any]) -> Self:
164
+ """Override action variable with context values."""
165
+ if action.ctx_override:
166
+ for k, v in ctx.items():
167
+ if hasattr(action, k):
168
+ setattr(action, k, v)
169
+
170
+ return self
171
+
160
172
  async def serve(self, task: Task) -> None:
161
173
  """Execute workflow to complete given task.
162
174
 
@@ -178,11 +190,12 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
178
190
  try:
179
191
  # Process each action in sequence
180
192
  for i, step in enumerate(self._instances):
181
- current_action = step.name
182
- logger.info(f"Executing step [{i}] >> {current_action}")
193
+ logger.info(f"Executing step [{i}] >> {(current_action := step.name)}")
183
194
 
184
195
  # Get current context and execute action
185
196
  context = await self._context.get()
197
+
198
+ self.override_action_variable(step, context)
186
199
  act_task = create_task(step.act(context))
187
200
  # Handle task cancellation
188
201
  if task.is_cancelled():
@@ -1,7 +1,7 @@
1
1
  """A module containing kwargs types for content correction and checking operations."""
2
2
 
3
3
  from importlib.util import find_spec
4
- from typing import NotRequired, TypedDict
4
+ from typing import NotRequired, Optional, TypedDict
5
5
 
6
6
  from fabricatio.models.extra.problem import Improvement
7
7
  from fabricatio.models.extra.rule import RuleSet
@@ -58,3 +58,5 @@ if find_spec("pymilvus"):
58
58
  collection_name: NotRequired[str | None]
59
59
  similarity_threshold: NotRequired[float]
60
60
  result_per_query: NotRequired[int]
61
+ tei_endpoint: NotRequired[Optional[str]]
62
+ reranker_threshold: NotRequired[float]
@@ -2,8 +2,9 @@
2
2
 
3
3
  from abc import ABC
4
4
  from enum import StrEnum
5
- from typing import Generator, List, Optional, Self, Tuple
5
+ from typing import ClassVar, Generator, List, Optional, Self, Tuple, Type
6
6
 
7
+ from fabricatio.fs.readers import extract_sections
7
8
  from fabricatio.models.generic import (
8
9
  AsPrompt,
9
10
  Described,
@@ -105,12 +106,6 @@ class ArticleOutlineBase(
105
106
  self.description = other.description
106
107
  return self
107
108
 
108
- def display_metadata(self) -> str:
109
- """Displays the metadata of the current instance."""
110
- return self.model_dump_json(
111
- indent=1, include={"title", "writing_aim", "description", "support_to", "depend_on"}
112
- )
113
-
114
109
  def update_from_inner(self, other: Self) -> Self:
115
110
  """Updates the current instance with the attributes of another instance."""
116
111
  return self.update_metadata(other)
@@ -140,6 +135,8 @@ class SectionBase[T: SubSectionBase](ArticleOutlineBase):
140
135
  subsections: List[T]
141
136
  """Subsections of the section. Contains at least one subsection. You can also add more as needed."""
142
137
 
138
+ child_type: ClassVar[Type[SubSectionBase]]
139
+
143
140
  def to_typst_code(self) -> str:
144
141
  """Converts the section into a Typst formatted code snippet.
145
142
 
@@ -148,6 +145,17 @@ class SectionBase[T: SubSectionBase](ArticleOutlineBase):
148
145
  """
149
146
  return f"== {super().to_typst_code()}" + "\n\n".join(subsec.to_typst_code() for subsec in self.subsections)
150
147
 
148
+ @classmethod
149
+ def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
150
+ """Creates an Article object from the given Typst code."""
151
+ return super().from_typst_code(
152
+ title,
153
+ body,
154
+ subsections=[
155
+ cls.child_type.from_typst_code(*pack) for pack in extract_sections(body, level=3, section_char="=")
156
+ ],
157
+ )
158
+
151
159
  def resolve_update_conflict(self, other: Self) -> str:
152
160
  """Resolve update errors in the article outline."""
153
161
  out = ""
@@ -186,11 +194,23 @@ class ChapterBase[T: SectionBase](ArticleOutlineBase):
186
194
 
187
195
  sections: List[T]
188
196
  """Sections of the chapter. Contains at least one section. You can also add more as needed."""
197
+ child_type: ClassVar[Type[SectionBase]]
189
198
 
190
199
  def to_typst_code(self) -> str:
191
200
  """Converts the chapter into a Typst formatted code snippet for rendering."""
192
201
  return f"= {super().to_typst_code()}" + "\n\n".join(sec.to_typst_code() for sec in self.sections)
193
202
 
203
+ @classmethod
204
+ def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
205
+ """Creates an Article object from the given Typst code."""
206
+ return super().from_typst_code(
207
+ title,
208
+ body,
209
+ sections=[
210
+ cls.child_type.from_typst_code(*pack) for pack in extract_sections(body, level=2, section_char="=")
211
+ ],
212
+ )
213
+
194
214
  def resolve_update_conflict(self, other: Self) -> str:
195
215
  """Resolve update errors in the article outline."""
196
216
  out = ""
@@ -238,6 +258,19 @@ class ArticleBase[T: ChapterBase](FinalizedDumpAble, AsPrompt, FromTypstCode, To
238
258
  chapters: List[T]
239
259
  """Chapters of the article. Contains at least one chapter. You can also add more as needed."""
240
260
 
261
+ child_type: ClassVar[Type[ChapterBase]]
262
+
263
+ @classmethod
264
+ def from_typst_code(cls, title: str, body: str, **kwargs) -> Self:
265
+ """Generates an article from the given Typst code."""
266
+ return super().from_typst_code(
267
+ title,
268
+ body,
269
+ chapters=[
270
+ cls.child_type.from_typst_code(*pack) for pack in extract_sections(body, level=1, section_char="=")
271
+ ],
272
+ )
273
+
241
274
  def iter_dfs_rev(
242
275
  self,
243
276
  ) -> Generator[ArticleOutlineBase, None, None]: