fabricatio 0.2.9.dev2__tar.gz → 0.2.9.dev4__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 (163) hide show
  1. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/Cargo.lock +1 -0
  2. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/Cargo.toml +1 -0
  3. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/PKG-INFO +1 -1
  4. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/make_a_rating/rating.py +25 -6
  5. fabricatio-0.2.9.dev4/examples/reviewer/censor.py +32 -0
  6. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/reviewer/review.py +5 -1
  7. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/write_outline/write_outline_corrected.py +1 -7
  8. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/pyproject.toml +1 -1
  9. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/actions/article.py +84 -107
  10. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/actions/article_rag.py +15 -10
  11. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/actions/output.py +20 -4
  12. fabricatio-0.2.9.dev4/python/fabricatio/actions/rules.py +72 -0
  13. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/censor.py +21 -5
  14. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/check.py +40 -22
  15. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/correct.py +30 -11
  16. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/rating.py +53 -47
  17. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/config.py +2 -2
  18. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/fs/readers.py +20 -1
  19. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/action.py +6 -6
  20. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/advanced_judge.py +3 -3
  21. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/article_base.py +117 -57
  22. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/article_main.py +102 -14
  23. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/article_proposal.py +15 -14
  24. fabricatio-0.2.9.dev4/python/fabricatio/models/extra/patches.py +20 -0
  25. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/problem.py +20 -7
  26. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/rule.py +16 -4
  27. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/generic.py +23 -6
  28. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/usages.py +7 -16
  29. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/parser.py +5 -5
  30. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/rust.pyi +33 -0
  31. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/utils.py +5 -5
  32. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/workflows/articles.py +3 -5
  33. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/src/hbs_helpers.rs +7 -4
  34. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/src/language.rs +3 -4
  35. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/src/lib.rs +3 -0
  36. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/src/templates.rs +2 -1
  37. fabricatio-0.2.9.dev4/src/word_split.rs +27 -0
  38. fabricatio-0.2.9.dev4/templates/built-in/check_string.hbs +19 -0
  39. fabricatio-0.2.9.dev4/templates/built-in/co_validation.hbs +7 -0
  40. fabricatio-0.2.9.dev4/templates/built-in/create_json_obj.hbs +26 -0
  41. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/draft_rating_criteria.hbs +1 -0
  42. fabricatio-0.2.9.dev4/templates/built-in/draft_rating_manual.hbs +36 -0
  43. fabricatio-0.2.9.dev4/templates/built-in/draft_rating_weights_klee.hbs +37 -0
  44. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/extract_criteria_from_reasons.hbs +1 -0
  45. fabricatio-0.2.9.dev4/templates/built-in/extract_reasons_from_examples.hbs +39 -0
  46. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/liststr.hbs +10 -7
  47. fabricatio-0.2.9.dev4/templates/built-in/rate_fine_grind.hbs +15 -0
  48. fabricatio-0.2.9.dev4/templates.tar.gz +0 -0
  49. fabricatio-0.2.9.dev4/tests/test_models/test_problem.py +96 -0
  50. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/uv.lock +127 -127
  51. fabricatio-0.2.9.dev2/python/fabricatio/actions/rules.py +0 -39
  52. fabricatio-0.2.9.dev2/python/fabricatio/models/extra/patches.py +0 -20
  53. fabricatio-0.2.9.dev2/templates/built-in/check_string.hbs +0 -19
  54. fabricatio-0.2.9.dev2/templates/built-in/co_validation.hbs +0 -26
  55. fabricatio-0.2.9.dev2/templates/built-in/create_json_obj.hbs +0 -74
  56. fabricatio-0.2.9.dev2/templates/built-in/draft_rating_manual.hbs +0 -41
  57. fabricatio-0.2.9.dev2/templates/built-in/draft_rating_weights_klee.hbs +0 -44
  58. fabricatio-0.2.9.dev2/templates/built-in/extract_reasons_from_examples.hbs +0 -48
  59. fabricatio-0.2.9.dev2/templates/built-in/rate_fine_grind.hbs +0 -51
  60. fabricatio-0.2.9.dev2/templates.tar.gz +0 -0
  61. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/.github/workflows/build-package.yaml +0 -0
  62. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/.github/workflows/ruff.yaml +0 -0
  63. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/.github/workflows/tests.yaml +0 -0
  64. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/.gitignore +0 -0
  65. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/.python-version +0 -0
  66. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/LICENSE +0 -0
  67. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/Makefile +0 -0
  68. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/README.md +0 -0
  69. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/correct/correct.py +0 -0
  70. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/correct/correct_loop.py +0 -0
  71. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/extract_and_inject/.gitignore +0 -0
  72. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/extract_and_inject/article_rag.py +0 -0
  73. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/extract_and_inject/ask.py +0 -0
  74. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/extract_and_inject/extract_and_inject.py +0 -0
  75. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/extract_article/extract.py +0 -0
  76. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/llm_usages/llm_usage.py +0 -0
  77. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/make_diary/commits.json +0 -0
  78. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/make_diary/diary.py +0 -0
  79. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/minor/hello_fabricatio.py +0 -0
  80. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/minor/write_a_poem.py +0 -0
  81. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/propose_task/propose.py +0 -0
  82. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/rules/.gitignore +0 -0
  83. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/rules/draft_ruleset.py +0 -0
  84. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/search_bibtex/.gitignore +0 -0
  85. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/search_bibtex/search.py +0 -0
  86. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/simple_chat/chat.py +0 -0
  87. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/simple_rag/simple_rag.py +0 -0
  88. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/task_handle/handle_task.py +0 -0
  89. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/write_article/.gitignore +0 -0
  90. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/write_article/article_rag.py +0 -0
  91. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/write_article/write_article.py +0 -0
  92. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/write_outline/.gitignore +0 -0
  93. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/examples/write_outline/write_outline.py +0 -0
  94. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/__init__.py +0 -0
  95. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/actions/__init__.py +0 -0
  96. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/actions/rag.py +0 -0
  97. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/__init__.py +0 -0
  98. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/advanced_judge.py +0 -0
  99. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/propose.py +0 -0
  100. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/rag.py +0 -0
  101. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/review.py +0 -0
  102. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/capabilities/task.py +0 -0
  103. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/core.py +0 -0
  104. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/decorators.py +0 -0
  105. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/fs/__init__.py +0 -0
  106. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/fs/curd.py +0 -0
  107. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/journal.py +0 -0
  108. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/adv_kwargs_types.py +0 -0
  109. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/events.py +0 -0
  110. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/__init__.py +0 -0
  111. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/article_essence.py +0 -0
  112. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/extra/article_outline.py +0 -0
  113. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/kwargs_types.py +0 -0
  114. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/role.py +0 -0
  115. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/task.py +0 -0
  116. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/tool.py +0 -0
  117. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/models/utils.py +0 -0
  118. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/py.typed +0 -0
  119. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/rust_instances.py +0 -0
  120. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/toolboxes/__init__.py +0 -0
  121. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/toolboxes/arithmetic.py +0 -0
  122. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/toolboxes/fs.py +0 -0
  123. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/workflows/__init__.py +0 -0
  124. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/python/fabricatio/workflows/rag.py +0 -0
  125. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/src/bib_tools.rs +0 -0
  126. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/src/hash.rs +0 -0
  127. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/as_prompt.hbs +0 -0
  128. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/binary-exploitation-ctf-solver.hbs +0 -0
  129. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/claude-xml.hbs +0 -0
  130. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/clean-up-code.hbs +0 -0
  131. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/cryptography-ctf-solver.hbs +0 -0
  132. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/dependencies.hbs +0 -0
  133. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/document-the-code.hbs +0 -0
  134. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/draft_tool_usage_code.hbs +0 -0
  135. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/find-security-vulnerabilities.hbs +0 -0
  136. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/fix-bugs.hbs +0 -0
  137. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/fix_troubled_obj.hbs +0 -0
  138. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/fix_troubled_string.hbs +0 -0
  139. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/generic_string.hbs +0 -0
  140. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/improve-performance.hbs +0 -0
  141. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/make_choice.hbs +0 -0
  142. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/make_judgment.hbs +0 -0
  143. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/pathstr.hbs +0 -0
  144. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/refactor.hbs +0 -0
  145. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/refined_query.hbs +0 -0
  146. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/retrieved_display.hbs +0 -0
  147. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/reverse-engineering-ctf-solver.hbs +0 -0
  148. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/review_string.hbs +0 -0
  149. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/rule_requirement.hbs +0 -0
  150. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/ruleset_requirement_breakdown.hbs +0 -0
  151. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/task_briefing.hbs +0 -0
  152. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/web-ctf-solver.hbs +0 -0
  153. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/write-git-commit.hbs +0 -0
  154. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/write-github-pull-request.hbs +0 -0
  155. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/templates/built-in/write-github-readme.hbs +0 -0
  156. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/tests/test_config.py +0 -0
  157. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/tests/test_models/test_action.py +0 -0
  158. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/tests/test_models/test_advanced.py +0 -0
  159. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/tests/test_models/test_generic.py +0 -0
  160. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/tests/test_models/test_role.py +0 -0
  161. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/tests/test_models/test_task.py +0 -0
  162. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/tests/test_models/test_tool.py +0 -0
  163. {fabricatio-0.2.9.dev2 → fabricatio-0.2.9.dev4}/tests/test_models/test_usages.py +0 -0
@@ -452,6 +452,7 @@ dependencies = [
452
452
  "pythonize",
453
453
  "rayon",
454
454
  "serde_json",
455
+ "unicode-segmentation",
455
456
  "walkdir",
456
457
  "whichlang",
457
458
  ]
@@ -14,6 +14,7 @@ pyo3 = { version = "0.23.4", features = ["extension-module"] }
14
14
  pythonize = "0.23.0"
15
15
  rayon = "1.10.0"
16
16
  serde_json = "1.0.138"
17
+ unicode-segmentation = "1.12.0"
17
18
  walkdir = "2.5.0"
18
19
  whichlang = "0.1.1"
19
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fabricatio
3
- Version: 0.2.9.dev2
3
+ Version: 0.2.9.dev4
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -5,11 +5,12 @@ from typing import Dict, List, Set, Unpack
5
5
 
6
6
  import orjson
7
7
  from fabricatio import Action, JsonCapture, Role, WorkFlow, logger
8
+ from fabricatio.capabilities.rating import Rating
8
9
  from fabricatio.models.events import Event
9
10
  from fabricatio.models.task import Task
10
11
 
11
12
 
12
- class Rate(Action):
13
+ class Rate(Action, Rating):
13
14
  """Rate the task."""
14
15
 
15
16
  output_key: str = "task_output"
@@ -49,7 +50,7 @@ class WhatToRate(Action):
49
50
  )
50
51
 
51
52
 
52
- class MakeCriteria(Action):
53
+ class MakeCriteria(Action, Rating):
53
54
  """Make criteria for rating."""
54
55
 
55
56
  output_key: str = "criteria"
@@ -60,7 +61,7 @@ class MakeCriteria(Action):
60
61
  return set(criteria)
61
62
 
62
63
 
63
- class MakeCompositeScore(Action):
64
+ class MakeCompositeScore(Action, Rating):
64
65
  """Make a composite score."""
65
66
 
66
67
  output_key: str = "task_output"
@@ -72,6 +73,15 @@ class MakeCompositeScore(Action):
72
73
  )
73
74
 
74
75
 
76
+ class Best(Action, Rating):
77
+ """Select the best."""
78
+
79
+ output_key: str = "task_output"
80
+
81
+ async def _execute(self, rate_topic: str, to_rate: List[str], **cxt: Unpack) -> str:
82
+ return (await self.best(to_rate, topic=rate_topic)).pop(0)
83
+
84
+
75
85
  async def main() -> None:
76
86
  """Main function."""
77
87
  role = Role(
@@ -100,23 +110,32 @@ async def main() -> None:
100
110
  "rate_topic": "if the food is 'good'",
101
111
  },
102
112
  ),
113
+ Event.quick_instantiate("best"): WorkFlow(
114
+ name="choose the best",
115
+ steps=(WhatToRate, Best),
116
+ extra_init_context={"rate_topic": "if the food is 'good'"},
117
+ ),
103
118
  },
104
119
  )
105
120
  task = await role.propose_task(
106
121
  "rate these food, so that i can decide what to eat today. choco cake, strawberry icecream, giga burger, cup of coffee, rotten bread from the trash bin, and a salty of fruit salad",
107
122
  )
108
- rating = await task.move_to("rate_food").delegate()
123
+ rating = await task.delegate("rate_food")
109
124
 
110
125
  logger.success(f"Result: \n{rating}")
111
126
 
112
- generated_criteria = await task.move_to("make_criteria_for_food").delegate()
127
+ generated_criteria = await task.delegate("make_criteria_for_food")
113
128
 
114
129
  logger.success(f"Generated Criteria: \n{generated_criteria}")
115
130
 
116
- composite_score = await task.move_to("make_composite_score").delegate()
131
+ composite_score = await task.delegate("make_composite_score")
117
132
 
118
133
  logger.success(f"Composite Score: \n{composite_score}")
119
134
 
135
+ best = await task.delegate("best")
136
+
137
+ logger.success(f"Best: \n{best}")
138
+
120
139
 
121
140
  if __name__ == "__main__":
122
141
  asyncio.run(main())
@@ -0,0 +1,32 @@
1
+ """Example of review usage."""
2
+
3
+ import asyncio
4
+
5
+ from fabricatio import Role, logger
6
+ from fabricatio.capabilities.censor import Censor
7
+
8
+
9
+ class Coder(Role, Censor):
10
+ """Reviewer role."""
11
+
12
+
13
+ async def main() -> None:
14
+ """Main function."""
15
+ role = Coder(
16
+ name="Bob",
17
+ description="A role that reviews the code.",
18
+ )
19
+
20
+ code = await role.aask(
21
+ "write a cli app using rust with clap which can generate a basic manifest of a standard rust project, output code only,no extra explanation"
22
+ )
23
+
24
+ ruleset = await role.draft_ruleset("should not use clap to write cli.", rule_count=1)
25
+ logger.success(f"Code: \n{code}")
26
+ code = await role.censor_string(code, ruleset)
27
+
28
+ logger.success(f"Code: \n{code}")
29
+
30
+
31
+ if __name__ == "__main__":
32
+ asyncio.run(main())
@@ -3,11 +3,15 @@
3
3
  import asyncio
4
4
 
5
5
  from fabricatio import Role, logger
6
+ from fabricatio.capabilities.review import Review
6
7
 
7
8
 
9
+ class Reviewer(Role, Review):
10
+ """Reviewer role."""
11
+
8
12
  async def main() -> None:
9
13
  """Main function."""
10
- role = Role(
14
+ role = Reviewer(
11
15
  name="Reviewer",
12
16
  description="A role that reviews the code.",
13
17
  )
@@ -3,7 +3,7 @@
3
3
  import asyncio
4
4
 
5
5
  from fabricatio import Event, Role, WorkFlow, logger
6
- from fabricatio.actions.article import CorrectOutline, CorrectProposal, GenerateArticleProposal, GenerateInitialOutline
6
+ from fabricatio.actions.article import GenerateArticleProposal, GenerateInitialOutline
7
7
  from fabricatio.actions.output import DumpFinalizedOutput
8
8
 
9
9
 
@@ -20,13 +20,7 @@ async def main() -> None:
20
20
  description="Generate an outline for an article. dump the outline to the given path. in typst format.",
21
21
  steps=(
22
22
  GenerateArticleProposal(llm_model="deepseek/deepseek-reasoner", llm_temperature=1.3),
23
- CorrectProposal(
24
- output_key="article_proposal",
25
- llm_model="deepseek/deepseek-reasoner",
26
- llm_temperature=1.3,
27
- ),
28
23
  GenerateInitialOutline(llm_model="deepseek/deepseek-chat", llm_temperature=1.4, llm_top_p=0.5),
29
- CorrectOutline(output_key="to_dump", llm_temperature=1.4, llm_top_p=0.45),
30
24
  DumpFinalizedOutput(output_key="task_output"),
31
25
  ),
32
26
  )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fabricatio"
3
- version = "0.2.9-dev2"
3
+ version = "0.2.9-dev4"
4
4
  description = "A LLM multi-agent framework."
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -2,24 +2,23 @@
2
2
 
3
3
  from asyncio import gather
4
4
  from pathlib import Path
5
- from typing import Any, Callable, List, Optional
5
+ from typing import Callable, List, Optional
6
6
 
7
7
  from more_itertools import filter_map
8
8
 
9
9
  from fabricatio.capabilities.censor import Censor
10
- from fabricatio.capabilities.correct import Correct
11
10
  from fabricatio.capabilities.propose import Propose
12
11
  from fabricatio.fs import safe_text_read
13
12
  from fabricatio.journal import logger
14
13
  from fabricatio.models.action import Action
15
- from fabricatio.models.extra.article_base import ArticleRefSequencePatch
14
+ from fabricatio.models.extra.article_base import SubSectionBase
16
15
  from fabricatio.models.extra.article_essence import ArticleEssence
17
16
  from fabricatio.models.extra.article_main import Article
18
17
  from fabricatio.models.extra.article_outline import ArticleOutline
19
18
  from fabricatio.models.extra.article_proposal import ArticleProposal
20
19
  from fabricatio.models.extra.rule import RuleSet
21
20
  from fabricatio.models.task import Task
22
- from fabricatio.rust import BibManager
21
+ from fabricatio.rust import BibManager, detect_language
23
22
  from fabricatio.utils import ok
24
23
 
25
24
 
@@ -53,7 +52,7 @@ class ExtractArticleEssence(Action, Propose):
53
52
  for ess in await self.propose(
54
53
  ArticleEssence,
55
54
  [
56
- f"{c}\n\n\nBased the provided academic article above, you need to extract the essence from it."
55
+ f"{c}\n\n\nBased the provided academic article above, you need to extract the essence from it.\n\nWrite the value string using `{detect_language(c)}`"
57
56
  for c in contents
58
57
  ],
59
58
  ):
@@ -106,35 +105,30 @@ class GenerateArticleProposal(Action, Propose):
106
105
  task_input: Optional[Task] = None,
107
106
  article_briefing: Optional[str] = None,
108
107
  article_briefing_path: Optional[str] = None,
109
- langauge: Optional[str] = None,
110
108
  **_,
111
109
  ) -> Optional[ArticleProposal]:
112
110
  if article_briefing is None and article_briefing_path is None and task_input is None:
113
111
  logger.error("Task not approved, since all inputs are None.")
114
112
  return None
115
113
 
116
- proposal = ok(
114
+ briefing = article_briefing or safe_text_read(
115
+ ok(
116
+ article_briefing_path
117
+ or await self.awhich_pathstr(
118
+ f"{ok(task_input).briefing}\nExtract the path of file which contains the article briefing."
119
+ ),
120
+ "Could not find the path of file to read.",
121
+ )
122
+ )
123
+
124
+ logger.info("Start generating the proposal.")
125
+ return ok(
117
126
  await self.propose(
118
127
  ArticleProposal,
119
- briefing := (
120
- article_briefing
121
- or safe_text_read(
122
- ok(
123
- article_briefing_path
124
- or await self.awhich_pathstr(
125
- f"{ok(task_input).briefing}\nExtract the path of file which contains the article briefing."
126
- ),
127
- "Could not find the path of file to read.",
128
- )
129
- )
130
- ),
128
+ f"{briefing}\n\nWrite the value string using `{detect_language(briefing)}` as written language.",
131
129
  ),
132
130
  "Could not generate the proposal.",
133
131
  ).update_ref(briefing)
134
- if langauge:
135
- proposal.language = langauge
136
-
137
- return proposal
138
132
 
139
133
 
140
134
  class GenerateInitialOutline(Action, Propose):
@@ -151,7 +145,8 @@ class GenerateInitialOutline(Action, Propose):
151
145
  return ok(
152
146
  await self.propose(
153
147
  ArticleOutline,
154
- article_proposal.as_prompt(),
148
+ f"{(article_proposal.as_prompt())}\n\nNote that you should use `{article_proposal.language}` to write the `ArticleOutline`\n"
149
+ f"You Must make sure every chapter have sections, and every section have subsections.",
155
150
  ),
156
151
  "Could not generate the initial outline.",
157
152
  ).update_ref(article_proposal)
@@ -165,25 +160,33 @@ class FixIntrospectedErrors(Action, Censor):
165
160
 
166
161
  ruleset: Optional[RuleSet] = None
167
162
  """The ruleset to use to fix the introspected errors."""
163
+ max_error_count: Optional[int] = None
164
+ """The maximum number of errors to fix."""
168
165
 
169
166
  async def _execute(
170
167
  self,
171
168
  article_outline: ArticleOutline,
172
- ruleset: Optional[RuleSet] = None,
169
+ intro_fix_ruleset: Optional[RuleSet] = None,
173
170
  **_,
174
171
  ) -> Optional[ArticleOutline]:
175
- while pack := article_outline.find_introspected():
176
- component, err = ok(pack)
177
- logger.warning(f"Found introspected error: {err}")
178
- corrected = ok(
172
+ counter = 0
173
+ origin = article_outline
174
+ while pack := article_outline.gather_introspected():
175
+ logger.info(f"Found {counter}th introspected errors")
176
+ logger.warning(f"Found introspected error: {pack}")
177
+ article_outline = ok(
179
178
  await self.censor_obj(
180
- component,
181
- ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
182
- reference=f"# Original Article Outline\n{article_outline.display()}\n# Some Basic errors found from `{component.title}` that need to be fixed\n{err}",
179
+ article_outline,
180
+ ruleset=ok(intro_fix_ruleset or self.ruleset, "No ruleset provided"),
181
+ reference=f"{article_outline.as_prompt()}\n # Fatal Error of the Original Article Outline\n{pack}",
183
182
  ),
184
183
  "Could not correct the component.",
185
- )
186
- component.update_from(corrected)
184
+ ).update_ref(origin)
185
+
186
+ if self.max_error_count and counter > self.max_error_count:
187
+ logger.warning("Max error count reached, stopping.")
188
+ break
189
+ counter += 1
187
190
 
188
191
  return article_outline
189
192
 
@@ -196,27 +199,36 @@ class FixIllegalReferences(Action, Censor):
196
199
 
197
200
  ruleset: Optional[RuleSet] = None
198
201
  """Ruleset to use to fix the illegal references."""
202
+ max_error_count: Optional[int] = None
203
+ """The maximum number of errors to fix."""
199
204
 
200
205
  async def _execute(
201
206
  self,
202
207
  article_outline: ArticleOutline,
203
- ruleset: Optional[RuleSet] = None,
208
+ ref_fix_ruleset: Optional[RuleSet] = None,
204
209
  **_,
205
210
  ) -> Optional[ArticleOutline]:
211
+ counter = 0
206
212
  while pack := article_outline.find_illegal_ref(gather_identical=True):
207
- refs, err = ok(pack)
213
+ logger.info(f"Found {counter}th illegal references")
214
+ ref_seq, err = ok(pack)
208
215
  logger.warning(f"Found illegal referring error: {err}")
209
- corrected_ref = ok(
216
+ new = ok(
210
217
  await self.censor_obj(
211
- refs[0], # pyright: ignore [reportIndexIssue]
212
- ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
213
- reference=f"# Original Article Outline\n{article_outline.display()}\n# Some Basic errors found that need to be fixed\n{err}",
214
- )
218
+ ref_seq[0],
219
+ ruleset=ok(ref_fix_ruleset or self.ruleset, "No ruleset provided"),
220
+ reference=f"{article_outline.as_prompt()}\n# Some Basic errors found that need to be fixed\n{err}",
221
+ ),
222
+ "Could not correct the component",
215
223
  )
216
- for ref in refs:
217
- ref.update_from(corrected_ref) # pyright: ignore [reportAttributeAccessIssue]
224
+ for r in ref_seq:
225
+ r.update_from(new)
226
+ if self.max_error_count and counter > self.max_error_count:
227
+ logger.warning("Max error count reached, stopping.")
228
+ break
229
+ counter += 1
218
230
 
219
- return article_outline.update_ref(article_outline)
231
+ return article_outline
220
232
 
221
233
 
222
234
  class TweakOutlineForwardRef(Action, Censor):
@@ -230,32 +242,36 @@ class TweakOutlineForwardRef(Action, Censor):
230
242
  """Ruleset to use to fix the illegal references."""
231
243
 
232
244
  async def _execute(
233
- self, article_outline: ArticleOutline, ruleset: Optional[RuleSet] = None, **cxt
245
+ self, article_outline: ArticleOutline, ref_twk_ruleset: Optional[RuleSet] = None, **cxt
234
246
  ) -> ArticleOutline:
235
247
  return await self._inner(
236
248
  article_outline,
237
- ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
249
+ ruleset=ok(ref_twk_ruleset or self.ruleset, "No ruleset provided"),
238
250
  field_name="support_to",
239
251
  )
240
252
 
241
253
  async def _inner(self, article_outline: ArticleOutline, ruleset: RuleSet, field_name: str) -> ArticleOutline:
242
- for a in article_outline.iter_dfs():
243
- if judge := await self.evidently_judge(
244
- f"{article_outline.as_prompt()}\n\n{a.display()}\n"
245
- f"Does the `{a.__class__.__name__}`'s `{field_name}` field need to be extended or tweaked?"
246
- ):
247
- patch = ArticleRefSequencePatch.default()
248
- patch.tweaked = getattr(a, field_name)
249
-
250
- await self.censor_obj_inplace(
251
- patch,
252
- ruleset=ruleset,
253
- reference=f"{article_outline.as_prompt()}\n"
254
- f"The Article component titled `{a.title}` whose `{field_name}` field needs to be extended or tweaked.\n"
255
- f"# Judgement\n{judge.display()}",
256
- )
254
+ await gather(
255
+ *[self._loop(a[-1], article_outline, field_name, ruleset) for a in article_outline.iter_subsections()],
256
+ )
257
+
257
258
  return article_outline
258
259
 
260
+ async def _loop(
261
+ self, a: SubSectionBase, article_outline: ArticleOutline, field_name: str, ruleset: RuleSet
262
+ ) -> None:
263
+ if judge := await self.evidently_judge(
264
+ f"{article_outline.as_prompt()}\n\n{a.display()}\n"
265
+ f"Does the `{a.__class__.__name__}`'s `{field_name}` field need to be extended or tweaked?"
266
+ ):
267
+ await self.censor_obj_inplace(
268
+ a,
269
+ ruleset=ruleset,
270
+ reference=f"{article_outline.as_prompt()}\n"
271
+ f"The Article component titled `{a.title}` whose `{field_name}` field needs to be extended or tweaked.\n"
272
+ f"# Judgement\n{judge.display()}",
273
+ )
274
+
259
275
 
260
276
  class TweakOutlineBackwardRef(TweakOutlineForwardRef):
261
277
  """Tweak the backward references in the article outline.
@@ -267,11 +283,11 @@ class TweakOutlineBackwardRef(TweakOutlineForwardRef):
267
283
  ruleset: Optional[RuleSet] = None
268
284
 
269
285
  async def _execute(
270
- self, article_outline: ArticleOutline, ruleset: Optional[RuleSet] = None, **cxt
286
+ self, article_outline: ArticleOutline, ref_twk_ruleset: Optional[RuleSet] = None, **cxt
271
287
  ) -> ArticleOutline:
272
288
  return await self._inner(
273
289
  article_outline,
274
- ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
290
+ ruleset=ok(ref_twk_ruleset or self.ruleset, "No ruleset provided"),
275
291
  field_name="depend_on",
276
292
  )
277
293
 
@@ -286,7 +302,7 @@ class GenerateArticle(Action, Censor):
286
302
  async def _execute(
287
303
  self,
288
304
  article_outline: ArticleOutline,
289
- ruleset: Optional[RuleSet] = None,
305
+ article_gen_ruleset: Optional[RuleSet] = None,
290
306
  **_,
291
307
  ) -> Optional[Article]:
292
308
  article: Article = Article.from_outline(ok(article_outline, "Article outline not specified.")).update_ref(
@@ -297,51 +313,12 @@ class GenerateArticle(Action, Censor):
297
313
  *[
298
314
  self.censor_obj_inplace(
299
315
  subsec,
300
- ruleset=ok(ruleset or self.ruleset, "No ruleset provided"),
301
- reference=f"# Original Article Outline\n{article_outline.display()}\n# Error Need to be fixed\n{err}",
316
+ ruleset=ok(article_gen_ruleset or self.ruleset, "No ruleset provided"),
317
+ reference=f"{article_outline.as_prompt()}\n# Error Need to be fixed\n{err}\nYou should use `{subsec.language}` to write the new `Subsection`.",
302
318
  )
303
- for _, __, subsec in article.iter_subsections()
304
- if (err := subsec.introspect())
319
+ for _, _, subsec in article.iter_subsections()
320
+ if (err := subsec.introspect()) and logger.warning(f"Found Introspection Error:\n{err}") is None
305
321
  ],
306
- return_exceptions=True,
307
322
  )
308
323
 
309
324
  return article
310
-
311
-
312
- class CorrectProposal(Action, Censor):
313
- """Correct the proposal of the article."""
314
-
315
- output_key: str = "corrected_proposal"
316
-
317
- async def _execute(self, article_proposal: ArticleProposal, **_) -> Any:
318
- raise NotImplementedError("Not implemented.")
319
-
320
-
321
- class CorrectOutline(Action, Correct):
322
- """Correct the outline of the article."""
323
-
324
- output_key: str = "corrected_outline"
325
- """The key of the output data."""
326
-
327
- async def _execute(
328
- self,
329
- article_outline: ArticleOutline,
330
- **_,
331
- ) -> ArticleOutline:
332
- raise NotImplementedError("Not implemented.")
333
-
334
-
335
- class CorrectArticle(Action, Correct):
336
- """Correct the article based on the outline."""
337
-
338
- output_key: str = "corrected_article"
339
- """The key of the output data."""
340
-
341
- async def _execute(
342
- self,
343
- article: Article,
344
- article_outline: ArticleOutline,
345
- **_,
346
- ) -> Article:
347
- raise NotImplementedError("Not implemented.")
@@ -6,7 +6,7 @@ from typing import Optional
6
6
  from fabricatio.capabilities.censor import Censor
7
7
  from fabricatio.capabilities.rag import RAG
8
8
  from fabricatio.models.action import Action
9
- from fabricatio.models.extra.article_main import Article, ArticleParagraphSequencePatch, ArticleSubsection
9
+ from fabricatio.models.extra.article_main import Article, ArticleSubsection
10
10
  from fabricatio.models.extra.rule import RuleSet
11
11
  from fabricatio.utils import ok
12
12
 
@@ -29,11 +29,14 @@ class TweakArticleRAG(Action, RAG, Censor):
29
29
  ruleset: Optional[RuleSet] = None
30
30
  """The ruleset to be used for censoring the article."""
31
31
 
32
+ ref_limit: int = 30
33
+ """The limit of references to be retrieved"""
34
+
32
35
  async def _execute(
33
36
  self,
34
37
  article: Article,
35
38
  collection_name: str = "article_essence",
36
- ruleset: Optional[RuleSet] = None,
39
+ twk_rag_ruleset: Optional[RuleSet] = None,
37
40
  parallel: bool = False,
38
41
  **cxt,
39
42
  ) -> Optional[Article]:
@@ -45,7 +48,7 @@ class TweakArticleRAG(Action, RAG, Censor):
45
48
  Args:
46
49
  article (Article): The article to be processed.
47
50
  collection_name (str): The name of the collection to view for processing.
48
- ruleset (Optional[RuleSet]): The ruleset to apply for censoring. If not provided, the class's ruleset is used.
51
+ twk_rag_ruleset (Optional[RuleSet]): The ruleset to apply for censoring. If not provided, the class's ruleset is used.
49
52
  parallel (bool): If True, process subsections in parallel. Otherwise, process them sequentially.
50
53
  **cxt: Additional context parameters.
51
54
 
@@ -57,14 +60,14 @@ class TweakArticleRAG(Action, RAG, Censor):
57
60
  if parallel:
58
61
  await gather(
59
62
  *[
60
- self._inner(article, subsec, ok(ruleset or self.ruleset, "No ruleset provided!"))
63
+ self._inner(article, subsec, ok(twk_rag_ruleset or self.ruleset, "No ruleset provided!"))
61
64
  for _, __, subsec in article.iter_subsections()
62
65
  ],
63
66
  return_exceptions=True,
64
67
  )
65
68
  else:
66
69
  for _, __, subsec in article.iter_subsections():
67
- await self._inner(article, subsec, ok(ruleset or self.ruleset, "No ruleset provided!"))
70
+ await self._inner(article, subsec, ok(twk_rag_ruleset or self.ruleset, "No ruleset provided!"))
68
71
  return article
69
72
 
70
73
  async def _inner(self, article: Article, subsec: ArticleSubsection, ruleset: RuleSet) -> None:
@@ -88,13 +91,15 @@ class TweakArticleRAG(Action, RAG, Censor):
88
91
  f"{subsec.display()}\n"
89
92
  f"# Requirement\n"
90
93
  f"Search related articles in the base to find reference candidates, "
91
- f"prioritizing both original article language and English usage",
94
+ f"provide queries in both `English` and `{subsec.language}` can get more accurate results.",
92
95
  )
93
96
  )
94
- patch = ArticleParagraphSequencePatch.default()
95
- patch.tweaked = subsec.paragraphs
96
97
  await self.censor_obj_inplace(
97
- patch,
98
+ subsec,
98
99
  ruleset=ruleset,
99
- reference=await self.aretrieve_compact(refind_q, final_limit=30),
100
+ reference=f"{await self.aretrieve_compact(refind_q, final_limit=self.ref_limit)}\n\n"
101
+ f"You can use Reference above to rewrite the `{subsec.__class__.__name__}`.\n"
102
+ f"You should Always use `{subsec.language}` as written language, "
103
+ f"which is the original language of the `{subsec.title}`. "
104
+ f"since rewrite a `{subsec.__class__.__name__}` in a different language is usually a bad choice",
100
105
  )
@@ -103,7 +103,7 @@ class RetrieveFromPersistent[T: PersistentAble](Action):
103
103
  retrieve_cls: Type[T]
104
104
  """The class of the object to retrieve."""
105
105
 
106
- async def _execute(self, /, **__) -> Optional[T | List[T]]:
106
+ async def _execute(self, /, **_) -> Optional[T | List[T]]:
107
107
  logger.info(f"Retrieve `{self.retrieve_cls.__name__}` from {self.load_path}")
108
108
  if not (p := Path(self.load_path)).exists():
109
109
  logger.warning(f"Path {self.load_path} does not exist")
@@ -115,12 +115,29 @@ class RetrieveFromPersistent[T: PersistentAble](Action):
115
115
  return self.retrieve_cls.from_persistent(self.load_path)
116
116
 
117
117
 
118
+ class RetrieveFromLatest[T: PersistentAble](RetrieveFromPersistent[T]):
119
+ """Retrieve the object from the latest persistent file in the dir at `load_path`."""
120
+
121
+ async def _execute(self, /, **_) -> Optional[T]:
122
+ logger.info(f"Retrieve latest `{self.retrieve_cls.__name__}` from {self.load_path}")
123
+ if not (p := Path(self.load_path)).exists():
124
+ logger.warning(f"Path {self.load_path} does not exist")
125
+ return None
126
+
127
+ if p.is_dir():
128
+ logger.info(f"Found directory with {len(list(p.glob('*')))} items")
129
+ return self.retrieve_cls.from_latest_persistent(self.load_path)
130
+ logger.error(f"Path {self.load_path} is not a directory")
131
+ return None
132
+
133
+
118
134
  class GatherAsList(Action):
119
135
  """Gather the objects from the context as a list.
120
136
 
121
137
  Notes:
122
138
  If both `gather_suffix` and `gather_prefix` are specified, only the objects with the suffix will be gathered.
123
139
  """
140
+
124
141
  output_key: str = "gathered"
125
142
  """Gather the objects from the context as a list."""
126
143
  gather_suffix: Optional[str] = None
@@ -129,13 +146,12 @@ class GatherAsList(Action):
129
146
  """Gather the objects from the context as a list."""
130
147
 
131
148
  async def _execute(self, **cxt) -> List[Any]:
132
-
133
149
  if self.gather_suffix is not None:
134
150
  result = [cxt[k] for k in cxt if k.endswith(self.gather_suffix)]
135
151
  logger.debug(f"Gathered {len(result)} items with suffix {self.gather_suffix}")
136
152
  return result
137
- if self.gather_prefix is None:
138
- logger.error(err:="Either `gather_suffix` or `gather_prefix` must be specified.")
153
+ if self.gather_prefix is None:
154
+ logger.error(err := "Either `gather_suffix` or `gather_prefix` must be specified.")
139
155
  raise ValueError(err)
140
156
  result = [cxt[k] for k in cxt if k.startswith(self.gather_prefix)]
141
157
  logger.debug(f"Gathered {len(result)} items with prefix {self.gather_prefix}")