fabricatio 0.2.8.dev3__cp312-cp312-win_amd64.whl → 0.2.9__cp312-cp312-win_amd64.whl

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 (48) hide show
  1. fabricatio/__init__.py +4 -11
  2. fabricatio/actions/__init__.py +1 -0
  3. fabricatio/actions/article.py +128 -165
  4. fabricatio/actions/article_rag.py +62 -46
  5. fabricatio/actions/output.py +60 -4
  6. fabricatio/actions/rag.py +2 -1
  7. fabricatio/actions/rules.py +72 -0
  8. fabricatio/capabilities/__init__.py +1 -0
  9. fabricatio/capabilities/censor.py +104 -0
  10. fabricatio/capabilities/check.py +148 -32
  11. fabricatio/capabilities/correct.py +162 -100
  12. fabricatio/capabilities/rag.py +5 -4
  13. fabricatio/capabilities/rating.py +109 -54
  14. fabricatio/capabilities/review.py +1 -1
  15. fabricatio/capabilities/task.py +2 -1
  16. fabricatio/config.py +14 -6
  17. fabricatio/fs/readers.py +20 -1
  18. fabricatio/models/action.py +63 -41
  19. fabricatio/models/adv_kwargs_types.py +25 -0
  20. fabricatio/models/extra/__init__.py +1 -0
  21. fabricatio/models/extra/advanced_judge.py +7 -4
  22. fabricatio/models/extra/article_base.py +125 -79
  23. fabricatio/models/extra/article_main.py +101 -19
  24. fabricatio/models/extra/article_outline.py +2 -3
  25. fabricatio/models/extra/article_proposal.py +15 -14
  26. fabricatio/models/extra/patches.py +20 -0
  27. fabricatio/models/extra/problem.py +64 -23
  28. fabricatio/models/extra/rule.py +39 -10
  29. fabricatio/models/generic.py +405 -75
  30. fabricatio/models/kwargs_types.py +23 -17
  31. fabricatio/models/task.py +1 -1
  32. fabricatio/models/tool.py +149 -14
  33. fabricatio/models/usages.py +55 -56
  34. fabricatio/parser.py +12 -13
  35. fabricatio/rust.cp312-win_amd64.pyd +0 -0
  36. fabricatio/{_rust.pyi → rust.pyi} +42 -4
  37. fabricatio/{_rust_instances.py → rust_instances.py} +1 -1
  38. fabricatio/utils.py +5 -5
  39. fabricatio/workflows/__init__.py +1 -0
  40. fabricatio/workflows/articles.py +3 -5
  41. fabricatio-0.2.9.data/scripts/tdown.exe +0 -0
  42. {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dist-info}/METADATA +1 -1
  43. fabricatio-0.2.9.dist-info/RECORD +61 -0
  44. fabricatio/_rust.cp312-win_amd64.pyd +0 -0
  45. fabricatio-0.2.8.dev3.data/scripts/tdown.exe +0 -0
  46. fabricatio-0.2.8.dev3.dist-info/RECORD +0 -53
  47. {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dist-info}/WHEEL +0 -0
  48. {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dist-info}/licenses/LICENSE +0 -0
@@ -4,7 +4,7 @@ from types import CodeType
4
4
  from typing import Any, Dict, List, Optional, Tuple, Unpack
5
5
 
6
6
  import orjson
7
- from fabricatio._rust_instances import TEMPLATE_MANAGER
7
+
8
8
  from fabricatio.capabilities.propose import Propose
9
9
  from fabricatio.config import configs
10
10
  from fabricatio.journal import logger
@@ -13,6 +13,7 @@ from fabricatio.models.task import Task
13
13
  from fabricatio.models.tool import Tool, ToolExecutor
14
14
  from fabricatio.models.usages import ToolBoxUsage
15
15
  from fabricatio.parser import JsonCapture, PythonCapture
16
+ from fabricatio.rust_instances import TEMPLATE_MANAGER
16
17
 
17
18
 
18
19
  class ProposeTask(Propose):
fabricatio/config.py CHANGED
@@ -44,7 +44,7 @@ class LLMConfig(BaseModel):
44
44
  top_p (NonNegativeFloat): The top p of the LLM model. Controls diversity via nucleus sampling. Set to 0.35 as per request.
45
45
  generation_count (PositiveInt): The number of generations to generate. Default is 1.
46
46
  stream (bool): Whether to stream the LLM model's response. Default is False.
47
- max_tokens (PositiveInt): The maximum number of tokens to generate. Set to 8192 as per request.
47
+ max_tokens (PositiveInt): The maximum number of tokens to generate.
48
48
  """
49
49
 
50
50
  model_config = ConfigDict(use_attribute_docstrings=True)
@@ -79,7 +79,7 @@ class LLMConfig(BaseModel):
79
79
  """Whether to stream the LLM model's response. Default is False."""
80
80
 
81
81
  max_tokens: Optional[PositiveInt] = Field(default=None)
82
- """The maximum number of tokens to generate. Set to 8192 as per request."""
82
+ """The maximum number of tokens to generate."""
83
83
 
84
84
  rpm: Optional[PositiveInt] = Field(default=100)
85
85
  """The rate limit of the LLM model in requests per minute. None means not checked."""
@@ -229,9 +229,6 @@ class TemplateConfig(BaseModel):
229
229
  generic_string_template: str = Field(default="generic_string")
230
230
  """The name of the generic string template which will be used to review a string."""
231
231
 
232
- correct_template: str = Field(default="correct")
233
- """The name of the correct template which will be used to correct a string."""
234
-
235
232
  co_validation_template: str = Field(default="co_validation")
236
233
  """The name of the co-validation template which will be used to co-validate a string."""
237
234
 
@@ -241,6 +238,17 @@ class TemplateConfig(BaseModel):
241
238
  check_string_template: str = Field(default="check_string")
242
239
  """The name of the check string template which will be used to check a string."""
243
240
 
241
+ ruleset_requirement_breakdown_template: str = Field(default="ruleset_requirement_breakdown")
242
+ """The name of the ruleset requirement breakdown template which will be used to breakdown a ruleset requirement."""
243
+
244
+ fix_troubled_obj_template: str = Field(default="fix_troubled_obj")
245
+ """The name of the fix troubled object template which will be used to fix a troubled object."""
246
+
247
+ fix_troubled_string_template: str = Field(default="fix_troubled_string")
248
+ """The name of the fix troubled string template which will be used to fix a troubled string."""
249
+
250
+ rule_requirement_template: str = Field(default="rule_requirement")
251
+ """The name of the rule requirement template which will be used to generate a rule requirement."""
244
252
  class MagikaConfig(BaseModel):
245
253
  """Magika configuration class."""
246
254
 
@@ -295,7 +303,7 @@ class CacheConfig(BaseModel):
295
303
 
296
304
  model_config = ConfigDict(use_attribute_docstrings=True)
297
305
 
298
- type: Optional[LiteLLMCacheType] = None
306
+ type: LiteLLMCacheType = LiteLLMCacheType.LOCAL
299
307
  """The type of cache to use. If None, the default cache type will be used."""
300
308
  params: CacheKwargs = Field(default_factory=CacheKwargs)
301
309
  """The parameters for the cache. If type is None, the default parameters will be used."""
fabricatio/fs/readers.py CHANGED
@@ -1,9 +1,10 @@
1
1
  """Filesystem readers for Fabricatio."""
2
2
 
3
3
  from pathlib import Path
4
- from typing import Dict
4
+ from typing import Dict, List, Tuple
5
5
 
6
6
  import orjson
7
+ import regex
7
8
  from magika import Magika
8
9
 
9
10
  from fabricatio.config import configs
@@ -44,3 +45,21 @@ def safe_json_read(path: Path | str) -> Dict:
44
45
  except (orjson.JSONDecodeError, IsADirectoryError, FileNotFoundError) as e:
45
46
  logger.error(f"Failed to read file {path}: {e!s}")
46
47
  return {}
48
+
49
+
50
+ def extract_sections(string: str, level: int, section_char: str = "#") -> List[Tuple[str, str]]:
51
+ """Extract sections from markdown-style text by header level.
52
+
53
+ Args:
54
+ string (str): Input text to parse
55
+ level (int): Header level (e.g., 1 for '#', 2 for '##')
56
+ section_char (str, optional): The character used for headers (default: '#')
57
+
58
+ Returns:
59
+ List[Tuple[str, str]]: List of (header_text, section_content) tuples
60
+ """
61
+ return regex.findall(
62
+ r"^%s{%d}\s+(.+?)\n((?:(?!^%s{%d}\s).|\n)*)" % (section_char, level, section_char, level),
63
+ string,
64
+ regex.MULTILINE,
65
+ )
@@ -1,7 +1,12 @@
1
- """Module that contains the classes for actions and workflows.
1
+ """Module that contains the classes for defining and executing task workflows.
2
2
 
3
- This module defines the Action and WorkFlow classes, which are used for
4
- creating and executing sequences of actions in a task-based context.
3
+ This module provides the Action and WorkFlow classes for creating structured
4
+ task execution pipelines. Actions represent atomic operations, while WorkFlows
5
+ orchestrate sequences of actions with shared context and error handling.
6
+
7
+ Classes:
8
+ Action: Base class for defining executable actions with context management.
9
+ WorkFlow: Manages action sequences, context propagation, and task lifecycle.
5
10
  """
6
11
 
7
12
  import traceback
@@ -9,16 +14,18 @@ from abc import abstractmethod
9
14
  from asyncio import Queue, create_task
10
15
  from typing import Any, Dict, Self, Tuple, Type, Union, final
11
16
 
12
- from fabricatio.capabilities.correct import Correct
13
- from fabricatio.capabilities.task import HandleTask, ProposeTask
14
17
  from fabricatio.journal import logger
15
18
  from fabricatio.models.generic import WithBriefing
16
19
  from fabricatio.models.task import Task
17
- from fabricatio.models.usages import ToolBoxUsage
20
+ from fabricatio.models.usages import LLMUsage, ToolBoxUsage
18
21
  from pydantic import Field, PrivateAttr
19
22
 
23
+ OUTPUT_KEY = "task_output"
24
+
25
+ INPUT_KEY = "task_input"
26
+
20
27
 
21
- class Action(WithBriefing, HandleTask, ProposeTask, Correct):
28
+ class Action(WithBriefing, LLMUsage):
22
29
  """Class that represents an action to be executed in a workflow.
23
30
 
24
31
  Actions are the atomic units of work in a workflow. Each action performs
@@ -48,28 +55,26 @@ class Action(WithBriefing, HandleTask, ProposeTask, Correct):
48
55
  self.description = self.description or self.__class__.__doc__ or ""
49
56
 
50
57
  @abstractmethod
51
- async def _execute(self, *_, **cxt) -> Any: # noqa: ANN002
52
- """Execute the action logic with the provided context arguments.
53
-
54
- This method must be implemented by subclasses to define the actual behavior.
58
+ async def _execute(self, *_:Any, **cxt) -> Any:
59
+ """Implement the core logic of the action.
55
60
 
56
61
  Args:
57
- **cxt: The context dictionary containing input and output data.
62
+ **cxt: Context dictionary containing input/output data.
58
63
 
59
64
  Returns:
60
- Any: The result of the action execution.
65
+ Result of the action execution to be stored in context.
61
66
  """
62
67
  pass
63
68
 
64
69
  @final
65
70
  async def act(self, cxt: Dict[str, Any]) -> Dict[str, Any]:
66
- """Perform the action and update the context with results.
71
+ """Execute action and update context.
67
72
 
68
73
  Args:
69
- cxt: The context dictionary containing input and output data.
74
+ cxt (Dict[str, Any]): Shared context dictionary.
70
75
 
71
76
  Returns:
72
- Dict[str, Any]: The updated context dictionary.
77
+ Updated context dictionary with new/modified entries.
73
78
  """
74
79
  ret = await self._execute(**cxt)
75
80
 
@@ -81,23 +86,33 @@ class Action(WithBriefing, HandleTask, ProposeTask, Correct):
81
86
 
82
87
  @property
83
88
  def briefing(self) -> str:
84
- """Return a formatted description of the action including personality context if available.
89
+ """Generate formatted action description with personality context.
85
90
 
86
91
  Returns:
87
- str: Formatted briefing text with personality and action description.
92
+ Briefing text combining personality and action description.
88
93
  """
89
94
  if self.personality:
90
95
  return f"## Your personality: \n{self.personality}\n# The action you are going to perform: \n{super().briefing}"
91
96
  return f"# The action you are going to perform: \n{super().briefing}"
92
97
 
98
+ def to_task_output(self)->Self:
99
+ """Set the output key to OUTPUT_KEY and return the action instance."""
100
+ self.output_key=OUTPUT_KEY
101
+ return self
93
102
 
94
103
  class WorkFlow(WithBriefing, ToolBoxUsage):
95
- """Class that represents a sequence of actions to be executed for a task.
104
+ """Manages sequences of actions to fulfill tasks.
105
+
106
+ Handles context propagation between actions, error handling, and task lifecycle
107
+ events like cancellation and completion.
96
108
 
97
- A workflow manages the execution of multiple actions in sequence, passing
98
- a shared context between them and handling task lifecycle events.
109
+ Attributes:
110
+ steps (Tuple): Sequence of Action instances or classes to execute.
111
+ task_input_key (str): Key for storing task instance in context.
112
+ task_output_key (str): Key to retrieve final result from context.
99
113
  """
100
- description:str =""
114
+
115
+ description: str = ""
101
116
  """The description of the workflow, which describes the workflow's purpose and requirements."""
102
117
 
103
118
  _context: Queue[Dict[str, Any]] = PrivateAttr(default_factory=lambda: Queue(maxsize=1))
@@ -111,10 +126,10 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
111
126
  )
112
127
  """The sequence of actions to be executed, can be action classes or instances."""
113
128
 
114
- task_input_key: str = Field(default="task_input")
129
+ task_input_key: str = Field(default=INPUT_KEY)
115
130
  """Key used to store the input task in the context dictionary."""
116
131
 
117
- task_output_key: str = Field(default="task_output")
132
+ task_output_key: str = Field(default=OUTPUT_KEY)
118
133
  """Key used to extract the final result from the context dictionary."""
119
134
 
120
135
  extra_init_context: Dict[str, Any] = Field(default_factory=dict, frozen=True)
@@ -130,26 +145,29 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
130
145
  self._instances = tuple(step if isinstance(step, Action) else step() for step in self.steps)
131
146
 
132
147
  def inject_personality(self, personality: str) -> Self:
133
- """Set the personality for all actions that don't have one defined.
148
+ """Set personality for actions without existing personality.
134
149
 
135
150
  Args:
136
- personality: The personality text to inject.
151
+ personality (str): Shared personality context
137
152
 
138
153
  Returns:
139
- Self: The workflow instance for method chaining.
154
+ Workflow instance with updated actions
140
155
  """
141
156
  for action in filter(lambda a: not a.personality, self._instances):
142
157
  action.personality = personality
143
158
  return self
144
159
 
145
160
  async def serve(self, task: Task) -> None:
146
- """Execute the workflow to fulfill the given task.
147
-
148
- This method manages the complete lifecycle of processing a task through
149
- the workflow's sequence of actions.
161
+ """Execute workflow to complete given task.
150
162
 
151
163
  Args:
152
- task: The task to be processed.
164
+ task (Task): Task instance to be processed.
165
+
166
+ Steps:
167
+ 1. Initialize context with task instance and extra data
168
+ 2. Execute each action sequentially
169
+ 3. Handle task cancellation and exceptions
170
+ 4. Extract final result from context
153
171
  """
154
172
  logger.info(f"Start execute workflow: {self.name}")
155
173
 
@@ -159,27 +177,27 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
159
177
  current_action = None
160
178
  try:
161
179
  # Process each action in sequence
162
- for step in self._instances:
180
+ for i,step in enumerate(self._instances):
163
181
  current_action = step.name
164
- logger.info(f"Executing step >> {current_action}")
182
+ logger.info(f"Executing step [{i}] >> {current_action}")
165
183
 
166
184
  # Get current context and execute action
167
185
  context = await self._context.get()
168
186
  act_task = create_task(step.act(context))
169
187
  # Handle task cancellation
170
188
  if task.is_cancelled():
171
- logger.warning(f"Task cancelled by task: {task.name}")
189
+ logger.warning(f"Workflow cancelled by task: {task.name}")
172
190
  act_task.cancel(f"Cancelled by task: {task.name}")
173
191
  break
174
192
 
175
193
  # Update context with modified values
176
194
  modified_ctx = await act_task
177
- logger.success(f"Step execution finished: {current_action}")
195
+ logger.success(f"Step [{i}] `{current_action}` execution finished.")
178
196
  if step.output_key:
179
- logger.success(f"Setting output to `{step.output_key}`")
197
+ logger.success(f"Setting action `{current_action}` output to `{step.output_key}`")
180
198
  await self._context.put(modified_ctx)
181
199
 
182
- logger.success(f"Workflow execution finished: {self.name}")
200
+ logger.success(f"Workflow `{self.name}` execution finished.")
183
201
 
184
202
  # Get final context and extract result
185
203
  final_ctx = await self._context.get()
@@ -199,10 +217,14 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
199
217
  await task.fail()
200
218
 
201
219
  async def _init_context[T](self, task: Task[T]) -> None:
202
- """Initialize the context dictionary for workflow execution.
220
+ """Initialize workflow execution context.
203
221
 
204
222
  Args:
205
- task: The task being served by this workflow.
223
+ task (Task[T]): Task being processed
224
+
225
+ Context includes:
226
+ - Task instance stored under task_input_key
227
+ - Any extra_init_context values
206
228
  """
207
229
  logger.debug(f"Initializing context for workflow: {self.name}")
208
230
  initial_context = {self.task_input_key: task, **dict(self.extra_init_context)}
@@ -223,7 +245,7 @@ class WorkFlow(WithBriefing, ToolBoxUsage):
223
245
  Returns:
224
246
  Self: The workflow instance for method chaining.
225
247
  """
226
- self.provide_tools_to(self._instances)
248
+ self.provide_tools_to(i for i in self._instances if isinstance(i,ToolBoxUsage))
227
249
  return self
228
250
 
229
251
  def update_init_context(self, /, **kwargs) -> Self:
@@ -0,0 +1,25 @@
1
+ """A module containing kwargs types for content correction and checking operations."""
2
+ from fabricatio.models.extra.problem import Improvement
3
+ from fabricatio.models.extra.rule import RuleSet
4
+ from fabricatio.models.generic import SketchedAble
5
+ from fabricatio.models.kwargs_types import ReferencedKwargs
6
+
7
+
8
+ class CorrectKwargs[T: SketchedAble](ReferencedKwargs[T], total=False):
9
+ """Arguments for content correction operations.
10
+
11
+ Extends GenerateKwargs with parameters for correcting content based on
12
+ specific criteria and templates.
13
+ """
14
+
15
+ improvement: Improvement
16
+
17
+
18
+ class CheckKwargs(ReferencedKwargs[Improvement], total=False):
19
+ """Arguments for content checking operations.
20
+
21
+ Extends GenerateKwargs with parameters for checking content against
22
+ specific criteria and templates.
23
+ """
24
+
25
+ ruleset: RuleSet
@@ -0,0 +1 @@
1
+ """A module contains extra models for fabricatio."""
@@ -2,23 +2,26 @@
2
2
 
3
3
  from typing import List
4
4
 
5
- from fabricatio.models.generic import Display, ProposedAble
5
+ from fabricatio.models.generic import SketchedAble
6
6
 
7
7
 
8
- class JudgeMent(ProposedAble,Display):
8
+ class JudgeMent(SketchedAble):
9
9
  """Represents a judgment result containing supporting/denying evidence and final verdict.
10
10
 
11
11
  The class stores both affirmative and denies evidence, truth and reasons lists along with the final boolean judgment.
12
12
  """
13
+
14
+ issue_to_judge: str
15
+ """The issue to be judged, including the original question and context"""
16
+
13
17
  deny_evidence: List[str]
14
18
  """List of clues supporting the denial."""
15
19
 
16
20
  affirm_evidence: List[str]
17
21
  """List of clues supporting the affirmation."""
18
22
 
19
-
20
23
  final_judgement: bool
21
- """The final judgment made according to all extracted clues."""
24
+ """The final judgment made according to all extracted clues. true for the `issue_to_judge` is correct and false for incorrect."""
22
25
 
23
26
  def __bool__(self) -> bool:
24
27
  """Return the final judgment value.