fabricatio 0.3.14.dev1__cp312-cp312-win_amd64.whl → 0.3.14.dev4__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 (47) hide show
  1. fabricatio/__init__.py +5 -6
  2. fabricatio/actions/article.py +31 -31
  3. fabricatio/actions/article_rag.py +58 -58
  4. fabricatio/actions/output.py +58 -24
  5. fabricatio/actions/rag.py +2 -3
  6. fabricatio/capabilities/advanced_judge.py +4 -7
  7. fabricatio/capabilities/advanced_rag.py +2 -1
  8. fabricatio/capabilities/censor.py +5 -4
  9. fabricatio/capabilities/check.py +27 -27
  10. fabricatio/capabilities/correct.py +22 -22
  11. fabricatio/capabilities/extract.py +33 -33
  12. fabricatio/capabilities/persist.py +103 -0
  13. fabricatio/capabilities/propose.py +2 -2
  14. fabricatio/capabilities/rag.py +37 -37
  15. fabricatio/capabilities/rating.py +66 -70
  16. fabricatio/capabilities/review.py +12 -11
  17. fabricatio/capabilities/task.py +19 -18
  18. fabricatio/decorators.py +9 -9
  19. fabricatio/{core.py → emitter.py} +17 -19
  20. fabricatio/journal.py +2 -1
  21. fabricatio/models/action.py +9 -11
  22. fabricatio/models/extra/aricle_rag.py +15 -12
  23. fabricatio/models/extra/article_base.py +4 -5
  24. fabricatio/models/extra/article_essence.py +2 -1
  25. fabricatio/models/extra/article_main.py +5 -4
  26. fabricatio/models/extra/article_outline.py +2 -1
  27. fabricatio/models/extra/article_proposal.py +1 -1
  28. fabricatio/models/extra/rag.py +2 -2
  29. fabricatio/models/extra/rule.py +2 -1
  30. fabricatio/models/generic.py +48 -131
  31. fabricatio/models/kwargs_types.py +1 -9
  32. fabricatio/models/role.py +14 -13
  33. fabricatio/models/task.py +3 -4
  34. fabricatio/models/tool.py +5 -6
  35. fabricatio/models/usages.py +137 -147
  36. fabricatio/parser.py +59 -99
  37. fabricatio/rust.cp312-win_amd64.pyd +0 -0
  38. fabricatio/rust.pyi +39 -59
  39. fabricatio/utils.py +6 -170
  40. fabricatio-0.3.14.dev4.data/scripts/tdown.exe +0 -0
  41. {fabricatio-0.3.14.dev1.data → fabricatio-0.3.14.dev4.data}/scripts/ttm.exe +0 -0
  42. {fabricatio-0.3.14.dev1.dist-info → fabricatio-0.3.14.dev4.dist-info}/METADATA +3 -7
  43. fabricatio-0.3.14.dev4.dist-info/RECORD +64 -0
  44. fabricatio-0.3.14.dev1.data/scripts/tdown.exe +0 -0
  45. fabricatio-0.3.14.dev1.dist-info/RECORD +0 -63
  46. {fabricatio-0.3.14.dev1.dist-info → fabricatio-0.3.14.dev4.dist-info}/WHEEL +0 -0
  47. {fabricatio-0.3.14.dev1.dist-info → fabricatio-0.3.14.dev4.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,10 @@
1
1
  """A module that provides functionality to rate tasks based on a rating manual and score range."""
2
2
 
3
+ from abc import ABC
3
4
  from itertools import permutations
4
5
  from random import sample
5
6
  from typing import Dict, List, Optional, Set, Tuple, Union, Unpack, overload
6
7
 
7
- from fabricatio.rust import CONFIG, TEMPLATE_MANAGER
8
8
  from more_itertools import flatten, windowed
9
9
  from pydantic import Field, NonNegativeInt, PositiveInt, create_model
10
10
 
@@ -13,10 +13,11 @@ from fabricatio.journal import logger
13
13
  from fabricatio.models.generic import Display, ProposedAble
14
14
  from fabricatio.models.kwargs_types import CompositeScoreKwargs, ValidateKwargs
15
15
  from fabricatio.parser import JsonCapture
16
+ from fabricatio.rust import CONFIG, TEMPLATE_MANAGER
16
17
  from fabricatio.utils import ok, override_kwargs
17
18
 
18
19
 
19
- class Rating(Propose):
20
+ class Rating(Propose, ABC):
20
21
  """A class that provides functionality to rate tasks based on a rating manual and score range.
21
22
 
22
23
  References:
@@ -24,11 +25,11 @@ class Rating(Propose):
24
25
  """
25
26
 
26
27
  async def rate_fine_grind(
27
- self,
28
- to_rate: str | List[str],
29
- rating_manual: Dict[str, str],
30
- score_range: Tuple[float, float],
31
- **kwargs: Unpack[ValidateKwargs[Dict[str, float]]],
28
+ self,
29
+ to_rate: str | List[str],
30
+ rating_manual: Dict[str, str],
31
+ score_range: Tuple[float, float],
32
+ **kwargs: Unpack[ValidateKwargs[Dict[str, float]]],
32
33
  ) -> Dict[str, float] | List[Dict[str, float]] | List[Optional[Dict[str, float]]] | None:
33
34
  """Rate a given string based on a rating manual and score range.
34
35
 
@@ -87,36 +88,34 @@ class Rating(Propose):
87
88
 
88
89
  @overload
89
90
  async def rate(
90
- self,
91
- to_rate: str,
92
- topic: str,
93
- criteria: Set[str],
94
- manual: Optional[Dict[str, str]] = None,
95
- score_range: Tuple[float, float] = (0.0, 1.0),
96
- **kwargs: Unpack[ValidateKwargs],
97
- ) -> Dict[str, float]:
98
- ...
91
+ self,
92
+ to_rate: str,
93
+ topic: str,
94
+ criteria: Set[str],
95
+ manual: Optional[Dict[str, str]] = None,
96
+ score_range: Tuple[float, float] = (0.0, 1.0),
97
+ **kwargs: Unpack[ValidateKwargs],
98
+ ) -> Dict[str, float]: ...
99
99
 
100
100
  @overload
101
101
  async def rate(
102
- self,
103
- to_rate: List[str],
104
- topic: str,
105
- criteria: Set[str],
106
- manual: Optional[Dict[str, str]] = None,
107
- score_range: Tuple[float, float] = (0.0, 1.0),
108
- **kwargs: Unpack[ValidateKwargs],
109
- ) -> List[Dict[str, float]]:
110
- ...
102
+ self,
103
+ to_rate: List[str],
104
+ topic: str,
105
+ criteria: Set[str],
106
+ manual: Optional[Dict[str, str]] = None,
107
+ score_range: Tuple[float, float] = (0.0, 1.0),
108
+ **kwargs: Unpack[ValidateKwargs],
109
+ ) -> List[Dict[str, float]]: ...
111
110
 
112
111
  async def rate(
113
- self,
114
- to_rate: Union[str, List[str]],
115
- topic: str,
116
- criteria: Set[str],
117
- manual: Optional[Dict[str, str]] = None,
118
- score_range: Tuple[float, float] = (0.0, 1.0),
119
- **kwargs: Unpack[ValidateKwargs],
112
+ self,
113
+ to_rate: Union[str, List[str]],
114
+ topic: str,
115
+ criteria: Set[str],
116
+ manual: Optional[Dict[str, str]] = None,
117
+ score_range: Tuple[float, float] = (0.0, 1.0),
118
+ **kwargs: Unpack[ValidateKwargs],
120
119
  ) -> Dict[str, float] | List[Dict[str, float]] | List[Optional[Dict[str, float]]] | None:
121
120
  """Rate a given string or a sequence of strings based on a topic, criteria, and score range.
122
121
 
@@ -133,15 +132,15 @@ class Rating(Propose):
133
132
  or a list of dictionaries with the ratings for each criterion if a sequence of strings is provided.
134
133
  """
135
134
  manual = (
136
- manual
137
- or await self.draft_rating_manual(topic, criteria, **override_kwargs(kwargs, default=None))
138
- or dict(zip(criteria, criteria, strict=True))
135
+ manual
136
+ or await self.draft_rating_manual(topic, criteria, **override_kwargs(kwargs, default=None))
137
+ or dict(zip(criteria, criteria, strict=True))
139
138
  )
140
139
 
141
140
  return await self.rate_fine_grind(to_rate, manual, score_range, **kwargs)
142
141
 
143
142
  async def draft_rating_manual(
144
- self, topic: str, criteria: Optional[Set[str]] = None, **kwargs: Unpack[ValidateKwargs[Dict[str, str]]]
143
+ self, topic: str, criteria: Optional[Set[str]] = None, **kwargs: Unpack[ValidateKwargs[Dict[str, str]]]
145
144
  ) -> Optional[Dict[str, str]]:
146
145
  """Drafts a rating manual based on a topic and dimensions.
147
146
 
@@ -156,9 +155,9 @@ class Rating(Propose):
156
155
 
157
156
  def _validator(response: str) -> Dict[str, str] | None:
158
157
  if (
159
- (json_data := JsonCapture.validate_with(response, target_type=dict, elements_type=str)) is not None
160
- and json_data.keys() == criteria
161
- and all(isinstance(v, str) for v in json_data.values())
158
+ (json_data := JsonCapture.validate_with(response, target_type=dict, elements_type=str)) is not None
159
+ and json_data.keys() == criteria
160
+ and all(isinstance(v, str) for v in json_data.values())
162
161
  ):
163
162
  return json_data
164
163
  return None
@@ -184,10 +183,10 @@ class Rating(Propose):
184
183
  )
185
184
 
186
185
  async def draft_rating_criteria(
187
- self,
188
- topic: str,
189
- criteria_count: NonNegativeInt = 0,
190
- **kwargs: Unpack[ValidateKwargs[Set[str]]],
186
+ self,
187
+ topic: str,
188
+ criteria_count: NonNegativeInt = 0,
189
+ **kwargs: Unpack[ValidateKwargs[Set[str]]],
191
190
  ) -> Optional[Set[str]]:
192
191
  """Drafts rating dimensions based on a topic.
193
192
 
@@ -216,13 +215,13 @@ class Rating(Propose):
216
215
  )
217
216
 
218
217
  async def draft_rating_criteria_from_examples(
219
- self,
220
- topic: str,
221
- examples: List[str],
222
- m: NonNegativeInt = 0,
223
- reasons_count: PositiveInt = 2,
224
- criteria_count: PositiveInt = 5,
225
- **kwargs: Unpack[ValidateKwargs],
218
+ self,
219
+ topic: str,
220
+ examples: List[str],
221
+ m: NonNegativeInt = 0,
222
+ reasons_count: PositiveInt = 2,
223
+ criteria_count: PositiveInt = 5,
224
+ **kwargs: Unpack[ValidateKwargs],
226
225
  ) -> Optional[Set[str]]:
227
226
  """Asynchronously drafts a set of rating criteria based on provided examples.
228
227
 
@@ -287,10 +286,10 @@ class Rating(Propose):
287
286
  )
288
287
 
289
288
  async def drafting_rating_weights_klee(
290
- self,
291
- topic: str,
292
- criteria: Set[str],
293
- **kwargs: Unpack[ValidateKwargs[float]],
289
+ self,
290
+ topic: str,
291
+ criteria: Set[str],
292
+ **kwargs: Unpack[ValidateKwargs[float]],
294
293
  ) -> Dict[str, float]:
295
294
  """Drafts rating weights for a given topic and criteria using the Klee method.
296
295
 
@@ -333,14 +332,14 @@ class Rating(Propose):
333
332
  return dict(zip(criteria_seq, [w / total for w in weights], strict=True))
334
333
 
335
334
  async def composite_score(
336
- self,
337
- topic: str,
338
- to_rate: List[str],
339
- criteria: Optional[Set[str]] = None,
340
- weights: Optional[Dict[str, float]] = None,
341
- manual: Optional[Dict[str, str]] = None,
342
- approx: bool = False,
343
- **kwargs: Unpack[ValidateKwargs[List[Dict[str, float]]]],
335
+ self,
336
+ topic: str,
337
+ to_rate: List[str],
338
+ criteria: Optional[Set[str]] = None,
339
+ weights: Optional[Dict[str, float]] = None,
340
+ manual: Optional[Dict[str, str]] = None,
341
+ approx: bool = False,
342
+ **kwargs: Unpack[ValidateKwargs[List[Dict[str, float]]]],
344
343
  ) -> List[float]:
345
344
  """Calculates the composite scores for a list of items based on a given topic and criteria.
346
345
 
@@ -370,17 +369,15 @@ class Rating(Propose):
370
369
  return [sum(ratings[c] * weights[c] for c in criteria) for ratings in ratings_seq]
371
370
 
372
371
  @overload
373
- async def best(self, candidates: List[str], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]) -> List[str]:
374
- ...
372
+ async def best(self, candidates: List[str], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]) -> List[str]: ...
375
373
 
376
374
  @overload
377
375
  async def best[T: Display](
378
- self, candidates: List[T], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]
379
- ) -> List[T]:
380
- ...
376
+ self, candidates: List[T], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]
377
+ ) -> List[T]: ...
381
378
 
382
379
  async def best[T: Display](
383
- self, candidates: List[str] | List[T], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]
380
+ self, candidates: List[str] | List[T], k: int = 1, **kwargs: Unpack[CompositeScoreKwargs]
384
381
  ) -> Optional[List[str] | List[T]]:
385
382
  """Choose the best candidates from the list of candidates based on the composite score.
386
383
 
@@ -404,5 +401,4 @@ class Rating(Propose):
404
401
  rating_seq = await self.composite_score(
405
402
  to_rate=[c.display() if isinstance(c, Display) else c for c in candidates], **kwargs
406
403
  )
407
- return [a[0] for a in sorted(zip(candidates, rating_seq, strict=True), key=lambda x: x[1], reverse=True)[
408
- :k]] # pyright: ignore [reportReturnType]
404
+ return [a[0] for a in sorted(zip(candidates, rating_seq, strict=True), key=lambda x: x[1], reverse=True)[:k]] # pyright: ignore [reportReturnType]
@@ -1,19 +1,19 @@
1
1
  """A module that provides functionality to rate tasks based on a rating manual and score range."""
2
2
 
3
+ from abc import ABC
3
4
  from typing import Dict, Optional, Set, Unpack
4
5
 
5
- from fabricatio.rust import CONFIG, TEMPLATE_MANAGER
6
-
7
6
  from fabricatio.capabilities.propose import Propose
8
7
  from fabricatio.capabilities.rating import Rating
9
8
  from fabricatio.models.extra.problem import Improvement
10
9
  from fabricatio.models.generic import Display, WithBriefing
11
10
  from fabricatio.models.kwargs_types import ReviewKwargs, ValidateKwargs
12
11
  from fabricatio.models.task import Task
12
+ from fabricatio.rust import CONFIG, TEMPLATE_MANAGER
13
13
  from fabricatio.utils import ok
14
14
 
15
15
 
16
- class Review(Rating, Propose):
16
+ class Review(Rating, Propose, ABC):
17
17
  """Class that provides functionality to review tasks and strings using a language model.
18
18
 
19
19
  This class extends GiveRating and Propose capabilities to analyze content,
@@ -41,12 +41,12 @@ class Review(Rating, Propose):
41
41
  return await self.review_obj(task, **kwargs)
42
42
 
43
43
  async def review_string(
44
- self,
45
- input_text: str,
46
- topic: str,
47
- criteria: Optional[Set[str]] = None,
48
- rating_manual: Optional[Dict[str, str]] = None,
49
- **kwargs: Unpack[ValidateKwargs[Improvement]],
44
+ self,
45
+ input_text: str,
46
+ topic: str,
47
+ criteria: Optional[Set[str]] = None,
48
+ rating_manual: Optional[Dict[str, str]] = None,
49
+ **kwargs: Unpack[ValidateKwargs[Improvement]],
50
50
  ) -> Optional[Improvement]:
51
51
  """Review a string based on specified topic and criteria.
52
52
 
@@ -84,8 +84,9 @@ class Review(Rating, Propose):
84
84
  **kwargs,
85
85
  )
86
86
 
87
- async def review_obj[M: (Display, WithBriefing)](self, obj: M, **kwargs: Unpack[ReviewKwargs[Improvement]]) -> \
88
- Optional[Improvement]:
87
+ async def review_obj[M: (Display, WithBriefing)](
88
+ self, obj: M, **kwargs: Unpack[ReviewKwargs[Improvement]]
89
+ ) -> Optional[Improvement]:
89
90
  """Review an object that implements Display or WithBriefing interface.
90
91
 
91
92
  This method extracts displayable text from the object and performs a review
@@ -1,10 +1,10 @@
1
1
  """A module for the task capabilities of the Fabricatio library."""
2
2
 
3
+ from abc import ABC
3
4
  from types import CodeType
4
5
  from typing import Any, Dict, List, Optional, Tuple, Unpack
5
6
 
6
7
  import ujson
7
- from fabricatio.rust import CONFIG, TEMPLATE_MANAGER
8
8
 
9
9
  from fabricatio.capabilities.propose import Propose
10
10
  from fabricatio.journal import logger
@@ -13,15 +13,16 @@ 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 import CONFIG, TEMPLATE_MANAGER
16
17
 
17
18
 
18
- class ProposeTask(Propose):
19
+ class ProposeTask(Propose, ABC):
19
20
  """A class that proposes a task based on a prompt."""
20
21
 
21
22
  async def propose_task[T](
22
- self,
23
- prompt: str,
24
- **kwargs: Unpack[ValidateKwargs[Task[T]]],
23
+ self,
24
+ prompt: str,
25
+ **kwargs: Unpack[ValidateKwargs[Task[T]]],
25
26
  ) -> Optional[Task[T]]:
26
27
  """Asynchronously proposes a task based on a given prompt and parameters.
27
28
 
@@ -39,15 +40,15 @@ class ProposeTask(Propose):
39
40
  return await self.propose(Task, prompt, **kwargs)
40
41
 
41
42
 
42
- class HandleTask(ToolBoxUsage):
43
+ class HandleTask(ToolBoxUsage,ABC):
43
44
  """A class that handles a task based on a task object."""
44
45
 
45
46
  async def draft_tool_usage_code(
46
- self,
47
- task: Task,
48
- tools: List[Tool],
49
- data: Dict[str, Any],
50
- **kwargs: Unpack[ValidateKwargs],
47
+ self,
48
+ task: Task,
49
+ tools: List[Tool],
50
+ data: Dict[str, Any],
51
+ **kwargs: Unpack[ValidateKwargs],
51
52
  ) -> Optional[Tuple[CodeType, List[str]]]:
52
53
  """Asynchronously drafts the tool usage code for a task based on a given task object and tools."""
53
54
  logger.info(f"Drafting tool usage code for task: {task.briefing}")
@@ -59,7 +60,7 @@ class HandleTask(ToolBoxUsage):
59
60
 
60
61
  def _validator(response: str) -> Tuple[CodeType, List[str]] | None:
61
62
  if (source := PythonCapture.convert_with(response, lambda resp: compile(resp, "<string>", "exec"))) and (
62
- to_extract := JsonCapture.convert_with(response, ujson.loads)
63
+ to_extract := JsonCapture.convert_with(response, ujson.loads)
63
64
  ):
64
65
  return source, to_extract
65
66
 
@@ -84,12 +85,12 @@ class HandleTask(ToolBoxUsage):
84
85
  )
85
86
 
86
87
  async def handle_fine_grind(
87
- self,
88
- task: Task,
89
- data: Dict[str, Any],
90
- box_choose_kwargs: Optional[ChooseKwargs] = None,
91
- tool_choose_kwargs: Optional[ChooseKwargs] = None,
92
- **kwargs: Unpack[ValidateKwargs],
88
+ self,
89
+ task: Task,
90
+ data: Dict[str, Any],
91
+ box_choose_kwargs: Optional[ChooseKwargs] = None,
92
+ tool_choose_kwargs: Optional[ChooseKwargs] = None,
93
+ **kwargs: Unpack[ValidateKwargs],
93
94
  ) -> Optional[Tuple]:
94
95
  """Asynchronously handles a task based on a given task object and parameters."""
95
96
  logger.info(f"Handling task: \n{task.briefing}")
fabricatio/decorators.py CHANGED
@@ -8,9 +8,8 @@ from shutil import which
8
8
  from types import ModuleType
9
9
  from typing import Callable, Coroutine, List, Optional
10
10
 
11
- from fabricatio.rust import CONFIG
12
-
13
11
  from fabricatio.journal import logger
12
+ from fabricatio.rust import CONFIG
14
13
 
15
14
 
16
15
  def precheck_package[**P, R](package_name: str, msg: str) -> Callable[[Callable[P, R]], Callable[P, R]]:
@@ -25,7 +24,7 @@ def precheck_package[**P, R](package_name: str, msg: str) -> Callable[[Callable[
25
24
  """
26
25
 
27
26
  def _wrapper(
28
- func: Callable[P, R] | Callable[P, Coroutine[None, None, R]],
27
+ func: Callable[P, R] | Callable[P, Coroutine[None, None, R]],
29
28
  ) -> Callable[P, R] | Callable[P, Coroutine[None, None, R]]:
30
29
  if iscoroutinefunction(func):
31
30
 
@@ -49,7 +48,7 @@ def precheck_package[**P, R](package_name: str, msg: str) -> Callable[[Callable[
49
48
 
50
49
 
51
50
  def depend_on_external_cmd[**P, R](
52
- bin_name: str, install_tip: Optional[str], homepage: Optional[str] = None
51
+ bin_name: str, install_tip: Optional[str], homepage: Optional[str] = None
53
52
  ) -> Callable[[Callable[P, R]], Callable[P, R]]:
54
53
  """Decorator to check for the presence of an external command.
55
54
 
@@ -124,8 +123,8 @@ def confirm_to_execute[**P, R](func: Callable[P, R]) -> Callable[P, Optional[R]]
124
123
  @wraps(func)
125
124
  async def _wrapper(*args: P.args, **kwargs: P.kwargs) -> Optional[R]:
126
125
  if await confirm(
127
- f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n🔑 Kwargs:{kwargs}\n",
128
- instruction="Please input [Yes/No] to proceed (default: Yes):",
126
+ f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n🔑 Kwargs:{kwargs}\n",
127
+ instruction="Please input [Yes/No] to proceed (default: Yes):",
129
128
  ).ask_async():
130
129
  return await func(*args, **kwargs)
131
130
  logger.warning(f"Function: {func.__name__}{signature(func)} canceled by user.")
@@ -136,8 +135,8 @@ def confirm_to_execute[**P, R](func: Callable[P, R]) -> Callable[P, Optional[R]]
136
135
  @wraps(func)
137
136
  def _wrapper(*args: P.args, **kwargs: P.kwargs) -> Optional[R]:
138
137
  if confirm(
139
- f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n��� Kwargs:{kwargs}\n",
140
- instruction="Please input [Yes/No] to proceed (default: Yes):",
138
+ f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n��� Kwargs:{kwargs}\n",
139
+ instruction="Please input [Yes/No] to proceed (default: Yes):",
141
140
  ).ask():
142
141
  return func(*args, **kwargs)
143
142
  logger.warning(f"Function: {func.__name__}{signature(func)} canceled by user.")
@@ -219,7 +218,7 @@ def use_temp_module[**P, R](modules: ModuleType | List[ModuleType]) -> Callable[
219
218
 
220
219
 
221
220
  def logging_exec_time[**P, R](
222
- func: Callable[P, R] | Callable[P, Coroutine[None, None, R]],
221
+ func: Callable[P, R] | Callable[P, Coroutine[None, None, R]],
223
222
  ) -> Callable[P, R] | Callable[P, Coroutine[None, None, R]]:
224
223
  """Decorator to log the execution time of a function.
225
224
 
@@ -232,6 +231,7 @@ def logging_exec_time[**P, R](
232
231
  from time import time
233
232
 
234
233
  if iscoroutinefunction(func):
234
+
235
235
  @wraps(func)
236
236
  async def _async_wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
237
237
  start_time = time()
@@ -1,23 +1,21 @@
1
1
  """Core module that contains the Env class for managing event handling."""
2
+ from dataclasses import dataclass
3
+ from typing import Callable, ClassVar, Optional, Self, overload
2
4
 
3
- from typing import Callable, Optional, Self, overload
5
+ from pymitter import EventEmitter
4
6
 
5
7
  from fabricatio.rust import CONFIG, Event
6
- from pydantic import BaseModel, ConfigDict, PrivateAttr
7
- from pymitter import EventEmitter
8
8
 
9
9
 
10
- class Env(BaseModel):
10
+ @dataclass
11
+ class Env:
11
12
  """Environment class that manages event handling using EventEmitter."""
12
13
 
13
- model_config = ConfigDict(use_attribute_docstrings=True)
14
- _ee: EventEmitter = PrivateAttr(
15
- default_factory=lambda: EventEmitter(
16
- delimiter=CONFIG.pymitter.delimiter,
17
- new_listener=CONFIG.pymitter.new_listener_event,
18
- max_listeners=CONFIG.pymitter.max_listeners,
19
- wildcard=True,
20
- )
14
+ ee: ClassVar[EventEmitter] = EventEmitter(
15
+ delimiter=CONFIG.pymitter.delimiter,
16
+ new_listener=CONFIG.pymitter.new_listener_event,
17
+ max_listeners=CONFIG.pymitter.max_listeners,
18
+ wildcard=True,
21
19
  )
22
20
 
23
21
  @overload
@@ -75,8 +73,8 @@ class Env(BaseModel):
75
73
  if isinstance(event, Event):
76
74
  event = event.collapse()
77
75
  if func is None:
78
- return self._ee.on(event, ttl=ttl)
79
- self._ee.on(event, func, ttl=ttl)
76
+ return self.ee.on(event, ttl=ttl)
77
+ self.ee.on(event, func, ttl=ttl)
80
78
  return self
81
79
 
82
80
  @overload
@@ -130,9 +128,9 @@ class Env(BaseModel):
130
128
  if isinstance(event, Event):
131
129
  event = event.collapse()
132
130
  if func is None:
133
- return self._ee.once(event)
131
+ return self.ee.once(event)
134
132
 
135
- self._ee.once(event, func)
133
+ self.ee.once(event, func)
136
134
  return self
137
135
 
138
136
  def emit[**P](self, event: str | Event, *args: P.args, **kwargs: P.kwargs) -> None:
@@ -146,7 +144,7 @@ class Env(BaseModel):
146
144
  if isinstance(event, Event):
147
145
  event = event.collapse()
148
146
 
149
- self._ee.emit(event, *args, **kwargs)
147
+ self.ee.emit(event, *args, **kwargs)
150
148
 
151
149
  async def emit_async[**P](self, event: str | Event, *args: P.args, **kwargs: P.kwargs) -> None:
152
150
  """Asynchronously emits an event to all registered listeners.
@@ -158,7 +156,7 @@ class Env(BaseModel):
158
156
  """
159
157
  if isinstance(event, Event):
160
158
  event = event.collapse()
161
- return await self._ee.emit_async(event, *args, **kwargs)
159
+ return await self.ee.emit_async(event, *args, **kwargs)
162
160
 
163
161
  def emit_future[**P](self, event: str | Event, *args: P.args, **kwargs: P.kwargs) -> None:
164
162
  """Emits an event to all registered listeners and returns a future object.
@@ -173,7 +171,7 @@ class Env(BaseModel):
173
171
  """
174
172
  if isinstance(event, Event):
175
173
  event = event.collapse()
176
- return self._ee.emit_future(event, *args, **kwargs)
174
+ return self.ee.emit_future(event, *args, **kwargs)
177
175
 
178
176
 
179
177
  env = Env()
fabricatio/journal.py CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  import sys
4
4
 
5
- from fabricatio.rust import CONFIG
6
5
  from loguru import logger
7
6
 
7
+ from fabricatio.rust import CONFIG
8
+
8
9
  logger.remove()
9
10
  logger.add(sys.stderr, level=CONFIG.debug.log_level)
10
11
 
@@ -14,12 +14,11 @@ from abc import abstractmethod
14
14
  from asyncio import Queue, create_task
15
15
  from typing import Any, ClassVar, Dict, Generator, Self, Sequence, Tuple, Type, Union, final
16
16
 
17
- from pydantic import Field, PrivateAttr
18
-
19
17
  from fabricatio.journal import logger
20
18
  from fabricatio.models.generic import WithBriefing
21
19
  from fabricatio.models.task import Task
22
20
  from fabricatio.utils import override_kwargs
21
+ from pydantic import Field, PrivateAttr
23
22
 
24
23
  OUTPUT_KEY = "task_output"
25
24
 
@@ -99,9 +98,9 @@ class Action(WithBriefing):
99
98
  return f"## Your personality: \n{self.personality}\n# The action you are going to perform: \n{super().briefing}"
100
99
  return f"# The action you are going to perform: \n{super().briefing}"
101
100
 
102
- def to_task_output(self, task_output_key: str = OUTPUT_KEY) -> Self:
101
+ def to_task_output(self, to: Union[str, "WorkFlow"] = OUTPUT_KEY) -> Self:
103
102
  """Set the output key to OUTPUT_KEY and return the action instance."""
104
- self.output_key = task_output_key
103
+ self.output_key = to.task_output_key if isinstance(to, WorkFlow) else to
105
104
  return self
106
105
 
107
106
 
@@ -110,13 +109,10 @@ class WorkFlow(WithBriefing):
110
109
 
111
110
  Handles context propagation between actions, error handling, and task lifecycle
112
111
  events like cancellation and completion.
113
-
114
- Attributes:
115
- steps (Tuple): Sequence of Action instances or classes to execute.
116
- task_input_key (str): Key for storing task instance in context.
117
- task_output_key (str): Key to retrieve final result from context.
118
112
  """
119
113
 
114
+ name: str = "WorkFlow"
115
+ """The name of the workflow, which is used to identify and describe the workflow."""
120
116
  description: str = ""
121
117
  """The description of the workflow, which describes the workflow's purpose and requirements."""
122
118
 
@@ -129,10 +125,10 @@ class WorkFlow(WithBriefing):
129
125
  steps: Sequence[Union[Type[Action], Action]] = Field(frozen=True)
130
126
  """The sequence of actions to be executed, can be action classes or instances."""
131
127
 
132
- task_input_key: str = Field(default=INPUT_KEY)
128
+ task_input_key: ClassVar[str] = INPUT_KEY
133
129
  """Key used to store the input task in the context dictionary."""
134
130
 
135
- task_output_key: str = Field(default=OUTPUT_KEY)
131
+ task_output_key: ClassVar[str] = OUTPUT_KEY
136
132
  """Key used to extract the final result from the context dictionary."""
137
133
 
138
134
  extra_init_context: Dict[str, Any] = Field(default_factory=dict, frozen=True)
@@ -143,7 +139,9 @@ class WorkFlow(WithBriefing):
143
139
 
144
140
  Args:
145
141
  __context: The context to be used for initialization.
142
+
146
143
  """
144
+ self.name = self.name or self.__class__.__name__
147
145
  # Convert any action classes to instances
148
146
  self._instances = tuple(step if isinstance(step, Action) else step() for step in self.steps)
149
147