fabricatio 0.3.15.dev4__cp313-cp313-win_amd64.whl → 0.4.0__cp313-cp313-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 (58) hide show
  1. fabricatio/__init__.py +9 -8
  2. fabricatio/actions/output.py +21 -22
  3. fabricatio/actions/rules.py +83 -83
  4. fabricatio/rust.cp313-win_amd64.pyd +0 -0
  5. fabricatio/workflows/rag.py +2 -1
  6. fabricatio-0.4.0.data/scripts/tdown.exe +0 -0
  7. {fabricatio-0.3.15.dev4.dist-info → fabricatio-0.4.0.dist-info}/METADATA +18 -16
  8. fabricatio-0.4.0.dist-info/RECORD +18 -0
  9. fabricatio/actions/article.py +0 -415
  10. fabricatio/actions/article_rag.py +0 -407
  11. fabricatio/capabilities/__init__.py +0 -1
  12. fabricatio/capabilities/advanced_judge.py +0 -20
  13. fabricatio/capabilities/advanced_rag.py +0 -61
  14. fabricatio/capabilities/censor.py +0 -105
  15. fabricatio/capabilities/check.py +0 -212
  16. fabricatio/capabilities/correct.py +0 -228
  17. fabricatio/capabilities/extract.py +0 -74
  18. fabricatio/capabilities/persist.py +0 -103
  19. fabricatio/capabilities/propose.py +0 -65
  20. fabricatio/capabilities/rag.py +0 -264
  21. fabricatio/capabilities/rating.py +0 -404
  22. fabricatio/capabilities/review.py +0 -114
  23. fabricatio/capabilities/task.py +0 -113
  24. fabricatio/decorators.py +0 -253
  25. fabricatio/emitter.py +0 -177
  26. fabricatio/fs/__init__.py +0 -35
  27. fabricatio/fs/curd.py +0 -153
  28. fabricatio/fs/readers.py +0 -61
  29. fabricatio/journal.py +0 -12
  30. fabricatio/models/action.py +0 -263
  31. fabricatio/models/adv_kwargs_types.py +0 -63
  32. fabricatio/models/extra/__init__.py +0 -1
  33. fabricatio/models/extra/advanced_judge.py +0 -32
  34. fabricatio/models/extra/aricle_rag.py +0 -286
  35. fabricatio/models/extra/article_base.py +0 -486
  36. fabricatio/models/extra/article_essence.py +0 -101
  37. fabricatio/models/extra/article_main.py +0 -286
  38. fabricatio/models/extra/article_outline.py +0 -46
  39. fabricatio/models/extra/article_proposal.py +0 -52
  40. fabricatio/models/extra/patches.py +0 -20
  41. fabricatio/models/extra/problem.py +0 -165
  42. fabricatio/models/extra/rag.py +0 -98
  43. fabricatio/models/extra/rule.py +0 -52
  44. fabricatio/models/generic.py +0 -812
  45. fabricatio/models/kwargs_types.py +0 -121
  46. fabricatio/models/role.py +0 -99
  47. fabricatio/models/task.py +0 -310
  48. fabricatio/models/tool.py +0 -328
  49. fabricatio/models/usages.py +0 -791
  50. fabricatio/parser.py +0 -114
  51. fabricatio/rust.pyi +0 -846
  52. fabricatio/utils.py +0 -156
  53. fabricatio/workflows/articles.py +0 -24
  54. fabricatio-0.3.15.dev4.data/scripts/tdown.exe +0 -0
  55. fabricatio-0.3.15.dev4.data/scripts/ttm.exe +0 -0
  56. fabricatio-0.3.15.dev4.dist-info/RECORD +0 -64
  57. {fabricatio-0.3.15.dev4.dist-info → fabricatio-0.4.0.dist-info}/WHEEL +0 -0
  58. {fabricatio-0.3.15.dev4.dist-info → fabricatio-0.4.0.dist-info}/licenses/LICENSE +0 -0
fabricatio/fs/curd.py DELETED
@@ -1,153 +0,0 @@
1
- """File system create, update, read, delete operations."""
2
-
3
- import shutil
4
- import subprocess
5
- from os import PathLike
6
- from pathlib import Path
7
- from typing import Union
8
-
9
- from fabricatio.decorators import depend_on_external_cmd
10
- from fabricatio.journal import logger
11
-
12
-
13
- def dump_text(path: Union[str, Path], text: str) -> None:
14
- """Dump text to a file. you need to make sure the file's parent directory exists.
15
-
16
- Args:
17
- path(str, Path): Path to the file
18
- text(str): Text to write to the file
19
-
20
- Returns:
21
- None
22
- """
23
- Path(path).write_text(text, encoding="utf-8", errors="ignore", newline="\n")
24
-
25
-
26
- def copy_file(src: Union[str, Path], dst: Union[str, Path]) -> None:
27
- """Copy a file from source to destination.
28
-
29
- Args:
30
- src: Source file path
31
- dst: Destination file path
32
-
33
- Raises:
34
- FileNotFoundError: If source file doesn't exist
35
- shutil.SameFileError: If source and destination are the same
36
- """
37
- try:
38
- shutil.copy(src, dst)
39
- logger.info(f"Copied file from {src} to {dst}")
40
- except OSError as e:
41
- logger.error(f"Failed to copy file from {src} to {dst}: {e!s}")
42
- raise
43
-
44
-
45
- def move_file(src: Union[str, Path], dst: Union[str, Path]) -> None:
46
- """Move a file from source to destination.
47
-
48
- Args:
49
- src: Source file path
50
- dst: Destination file path
51
-
52
- Raises:
53
- FileNotFoundError: If source file doesn't exist
54
- shutil.SameFileError: If source and destination are the same
55
- """
56
- try:
57
- shutil.move(src, dst)
58
- logger.info(f"Moved file from {src} to {dst}")
59
- except OSError as e:
60
- logger.error(f"Failed to move file from {src} to {dst}: {e!s}")
61
- raise
62
-
63
-
64
- def delete_file(file_path: Union[str, Path]) -> None:
65
- """Delete a file.
66
-
67
- Args:
68
- file_path: Path to the file to be deleted
69
-
70
- Raises:
71
- FileNotFoundError: If file doesn't exist
72
- PermissionError: If no permission to delete the file
73
- """
74
- try:
75
- Path(file_path).unlink()
76
- logger.info(f"Deleted file: {file_path}")
77
- except OSError as e:
78
- logger.error(f"Failed to delete file {file_path}: {e!s}")
79
- raise
80
-
81
-
82
- def create_directory(dir_path: Union[str, Path], parents: bool = True, exist_ok: bool = True) -> None:
83
- """Create a directory.
84
-
85
- Args:
86
- dir_path: Path to the directory to create
87
- parents: Create parent directories if they don't exist
88
- exist_ok: Don't raise error if directory already exists
89
- """
90
- try:
91
- Path(dir_path).mkdir(parents=parents, exist_ok=exist_ok)
92
- logger.info(f"Created directory: {dir_path}")
93
- except OSError as e:
94
- logger.error(f"Failed to create directory {dir_path}: {e!s}")
95
- raise
96
-
97
-
98
- @depend_on_external_cmd(
99
- "erd",
100
- "Please install `erd` using `cargo install erdtree` or `scoop install erdtree`.",
101
- "https://github.com/solidiquis/erdtree",
102
- )
103
- def tree(dir_path: Union[str, Path]) -> str:
104
- """Generate a tree representation of the directory structure. Requires `erd` to be installed."""
105
- dir_path = Path(dir_path)
106
- return subprocess.check_output(("erd", dir_path.as_posix()), encoding="utf-8") # noqa: S603
107
-
108
-
109
- def delete_directory(dir_path: Union[str, Path]) -> None:
110
- """Delete a directory and its contents.
111
-
112
- Args:
113
- dir_path: Path to the directory to delete
114
-
115
- Raises:
116
- FileNotFoundError: If directory doesn't exist
117
- OSError: If directory is not empty and can't be removed
118
- """
119
- try:
120
- shutil.rmtree(dir_path)
121
- logger.info(f"Deleted directory: {dir_path}")
122
- except OSError as e:
123
- logger.error(f"Failed to delete directory {dir_path}: {e!s}")
124
- raise
125
-
126
-
127
- def absolute_path(path: str | Path | PathLike) -> str:
128
- """Get the absolute path of a file or directory.
129
-
130
- Args:
131
- path (str, Path, PathLike): The path to the file or directory.
132
-
133
- Returns:
134
- str: The absolute path of the file or directory.
135
- """
136
- return Path(path).expanduser().resolve().as_posix()
137
-
138
-
139
- def gather_files(directory: str | Path | PathLike, extension: str) -> list[str]:
140
- """Gather all files with a specific extension in a directory.
141
-
142
- Args:
143
- directory (str, Path, PathLike): The directory to search in.
144
- extension (str): The file extension to look for.
145
-
146
- Returns:
147
- list[str]: A list of file paths with the specified extension.
148
-
149
- Example:
150
- >>> gather_files('/path/to/directory', 'txt')
151
- ['/path/to/directory/file1.txt', '/path/to/directory/file2.txt']
152
- """
153
- return [file.as_posix() for file in Path(directory).rglob(f"*.{extension}")]
fabricatio/fs/readers.py DELETED
@@ -1,61 +0,0 @@
1
- """Filesystem readers for Fabricatio."""
2
-
3
- import re
4
- from pathlib import Path
5
- from typing import Dict, List, Tuple
6
-
7
- import ujson
8
-
9
- from fabricatio.journal import logger
10
-
11
-
12
- def safe_text_read(path: Path | str) -> str:
13
- """Safely read the text from a file.
14
-
15
- Args:
16
- path (Path|str): The path to the file.
17
-
18
- Returns:
19
- str: The text from the file.
20
- """
21
- path = Path(path)
22
- try:
23
- return path.read_text(encoding="utf-8")
24
- except (UnicodeDecodeError, IsADirectoryError, FileNotFoundError) as e:
25
- logger.error(f"Failed to read file {path}: {e!s}")
26
- return ""
27
-
28
-
29
- def safe_json_read(path: Path | str) -> Dict:
30
- """Safely read the JSON from a file.
31
-
32
- Args:
33
- path (Path|str): The path to the file.
34
-
35
- Returns:
36
- dict: The JSON from the file.
37
- """
38
- path = Path(path)
39
- try:
40
- return ujson.loads(path.read_text(encoding="utf-8"))
41
- except (ujson.JSONDecodeError, IsADirectoryError, FileNotFoundError) as e:
42
- logger.error(f"Failed to read file {path}: {e!s}")
43
- return {}
44
-
45
-
46
- def extract_sections(string: str, level: int, section_char: str = "#") -> List[Tuple[str, str]]:
47
- """Extract sections from markdown-style text by header level.
48
-
49
- Args:
50
- string (str): Input text to parse
51
- level (int): Header level (e.g., 1 for '#', 2 for '##')
52
- section_char (str, optional): The character used for headers (default: '#')
53
-
54
- Returns:
55
- List[Tuple[str, str]]: List of (header_text, section_content) tuples
56
- """
57
- return re.findall(
58
- r"^%s{%d}\s+(.+?)\n((?:(?!^%s{%d}\s).|\n)*)" % (section_char, level, section_char, level),
59
- string,
60
- re.MULTILINE,
61
- )
fabricatio/journal.py DELETED
@@ -1,12 +0,0 @@
1
- """Logging setup for the project."""
2
-
3
- import sys
4
-
5
- from loguru import logger
6
-
7
- from fabricatio.rust import CONFIG
8
-
9
- logger.remove()
10
- logger.add(sys.stderr, level=CONFIG.debug.log_level)
11
-
12
- __all__ = ["logger"]
@@ -1,263 +0,0 @@
1
- """Module that contains the classes for defining and executing task workflows.
2
-
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.
10
- """
11
-
12
- import traceback
13
- from abc import abstractmethod
14
- from asyncio import Queue, create_task
15
- from typing import Any, ClassVar, Dict, Generator, Self, Sequence, Tuple, Type, Union, final
16
-
17
- from fabricatio.journal import logger
18
- from fabricatio.models.generic import WithBriefing
19
- from fabricatio.models.task import Task
20
- from fabricatio.utils import override_kwargs
21
- from pydantic import Field, PrivateAttr
22
-
23
- OUTPUT_KEY = "task_output"
24
-
25
- INPUT_KEY = "task_input"
26
-
27
-
28
- class Action(WithBriefing):
29
- """Class that represents an action to be executed in a workflow.
30
-
31
- Actions are the atomic units of work in a workflow. Each action performs
32
- a specific operation and can modify the shared context data.
33
- """
34
-
35
- ctx_override: ClassVar[bool] = False
36
- """Whether to override the instance attr by the context variable."""
37
-
38
- name: str = Field(default="")
39
- """The name of the action."""
40
-
41
- description: str = Field(default="")
42
- """The description of the action."""
43
-
44
- personality: str = Field(default="")
45
- """The personality traits or context for the action executor."""
46
-
47
- output_key: str = Field(default="")
48
- """The key used to store this action's output in the context dictionary."""
49
-
50
- @final
51
- def model_post_init(self, __context: Any) -> None:
52
- """Initialize the action by setting default name and description if not provided.
53
-
54
- Args:
55
- __context: The context to be used for initialization.
56
- """
57
- self.name = self.name or self.__class__.__name__
58
- self.description = self.description or self.__class__.__doc__ or ""
59
-
60
- @abstractmethod
61
- async def _execute(self, *_: Any, **cxt) -> Any:
62
- """Implement the core logic of the action.
63
-
64
- Args:
65
- **cxt: Context dictionary containing input/output data.
66
-
67
- Returns:
68
- Result of the action execution to be stored in context.
69
- """
70
- pass
71
-
72
- @final
73
- async def act(self, cxt: Dict[str, Any]) -> Dict[str, Any]:
74
- """Execute action and update context.
75
-
76
- Args:
77
- cxt (Dict[str, Any]): Shared context dictionary.
78
-
79
- Returns:
80
- Updated context dictionary with new/modified entries.
81
- """
82
- ret = await self._execute(**cxt)
83
-
84
- if self.output_key:
85
- logger.debug(f"Setting output: {self.output_key}")
86
- cxt[self.output_key] = ret
87
-
88
- return cxt
89
-
90
- @property
91
- def briefing(self) -> str:
92
- """Generate formatted action description with personality context.
93
-
94
- Returns:
95
- Briefing text combining personality and action description.
96
- """
97
- if self.personality:
98
- return f"## Your personality: \n{self.personality}\n# The action you are going to perform: \n{super().briefing}"
99
- return f"# The action you are going to perform: \n{super().briefing}"
100
-
101
- def to_task_output(self, to: Union[str, "WorkFlow"] = OUTPUT_KEY) -> Self:
102
- """Set the output key to OUTPUT_KEY and return the action instance."""
103
- self.output_key = to.task_output_key if isinstance(to, WorkFlow) else to
104
- return self
105
-
106
-
107
- class WorkFlow(WithBriefing):
108
- """Manages sequences of actions to fulfill tasks.
109
-
110
- Handles context propagation between actions, error handling, and task lifecycle
111
- events like cancellation and completion.
112
- """
113
-
114
- name: str = "WorkFlow"
115
- """The name of the workflow, which is used to identify and describe the workflow."""
116
- description: str = ""
117
- """The description of the workflow, which describes the workflow's purpose and requirements."""
118
-
119
- _context: Queue[Dict[str, Any]] = PrivateAttr(default_factory=lambda: Queue(maxsize=1))
120
- """Queue for storing the workflow execution context."""
121
-
122
- _instances: Tuple[Action, ...] = PrivateAttr(default_factory=tuple)
123
- """Instantiated action objects to be executed in this workflow."""
124
-
125
- steps: Sequence[Union[Type[Action], Action]] = Field(frozen=True)
126
- """The sequence of actions to be executed, can be action classes or instances."""
127
-
128
- task_input_key: ClassVar[str] = INPUT_KEY
129
- """Key used to store the input task in the context dictionary."""
130
-
131
- task_output_key: ClassVar[str] = OUTPUT_KEY
132
- """Key used to extract the final result from the context dictionary."""
133
-
134
- extra_init_context: Dict[str, Any] = Field(default_factory=dict, frozen=True)
135
- """Additional initial context values to be included at workflow start."""
136
-
137
- def model_post_init(self, __context: Any) -> None:
138
- """Initialize the workflow by instantiating any action classes.
139
-
140
- Args:
141
- __context: The context to be used for initialization.
142
-
143
- """
144
- self.name = self.name or self.__class__.__name__
145
- # Convert any action classes to instances
146
- self._instances = tuple(step if isinstance(step, Action) else step() for step in self.steps)
147
-
148
- def iter_actions(self) -> Generator[Action, None, None]:
149
- """Iterate over action instances."""
150
- yield from self._instances
151
-
152
- def inject_personality(self, personality: str) -> Self:
153
- """Set personality for actions without existing personality.
154
-
155
- Args:
156
- personality (str): Shared personality context
157
-
158
- Returns:
159
- Workflow instance with updated actions
160
- """
161
- for action in filter(lambda a: not a.personality, self._instances):
162
- action.personality = personality
163
- return self
164
-
165
- def override_action_variable(self, action: Action, ctx: Dict[str, Any]) -> Self:
166
- """Override action variable with context values."""
167
- if action.ctx_override:
168
- for k, v in ctx.items():
169
- if hasattr(action, k):
170
- setattr(action, k, v)
171
-
172
- return self
173
-
174
- async def serve(self, task: Task) -> None:
175
- """Execute workflow to complete given task.
176
-
177
- Args:
178
- task (Task): Task instance to be processed.
179
-
180
- Steps:
181
- 1. Initialize context with task instance and extra data
182
- 2. Execute each action sequentially
183
- 3. Handle task cancellation and exceptions
184
- 4. Extract final result from context
185
- """
186
- logger.info(f"Start execute workflow: {self.name}")
187
-
188
- await task.start()
189
- await self._init_context(task)
190
-
191
- current_action = None
192
- try:
193
- # Process each action in sequence
194
- for i, step in enumerate(self._instances):
195
- logger.info(f"Executing step [{i}] >> {(current_action := step.name)}")
196
-
197
- # Get current context and execute action
198
- context = await self._context.get()
199
-
200
- self.override_action_variable(step, context)
201
- act_task = create_task(step.act(context))
202
- # Handle task cancellation
203
- if task.is_cancelled():
204
- logger.warning(f"Workflow cancelled by task: {task.name}")
205
- act_task.cancel(f"Cancelled by task: {task.name}")
206
- break
207
-
208
- # Update context with modified values
209
- modified_ctx = await act_task
210
- logger.success(f"Step [{i}] `{current_action}` execution finished.")
211
- if step.output_key:
212
- logger.success(f"Setting action `{current_action}` output to `{step.output_key}`")
213
- await self._context.put(modified_ctx)
214
-
215
- logger.success(f"Workflow `{self.name}` execution finished.")
216
-
217
- # Get final context and extract result
218
- final_ctx = await self._context.get()
219
- result = final_ctx.get(self.task_output_key)
220
-
221
- if self.task_output_key not in final_ctx:
222
- logger.warning(
223
- f"Task output key: `{self.task_output_key}` not found in the context, None will be returned. "
224
- f"You can check if `Action.output_key` is set the same as `WorkFlow.task_output_key`."
225
- )
226
-
227
- await task.finish(result)
228
-
229
- except Exception as e: # noqa: BLE001
230
- logger.critical(f"Error during task: {current_action} execution: {e}")
231
- logger.critical(traceback.format_exc())
232
- await task.fail()
233
-
234
- async def _init_context[T](self, task: Task[T]) -> None:
235
- """Initialize workflow execution context.
236
-
237
- Args:
238
- task (Task[T]): Task being processed
239
-
240
- Context includes:
241
- - Task instance stored under task_input_key
242
- - Any extra_init_context values
243
- """
244
- logger.debug(f"Initializing context for workflow: {self.name}")
245
- ctx = override_kwargs(self.extra_init_context, **task.extra_init_context)
246
- if self.task_input_key in ctx:
247
- raise ValueError(
248
- f"Task input key: `{self.task_input_key}`, which is reserved, is already set in the init context"
249
- )
250
-
251
- await self._context.put({self.task_input_key: task, **ctx})
252
-
253
- def update_init_context(self, /, **kwargs) -> Self:
254
- """Update the initial context with additional key-value pairs.
255
-
256
- Args:
257
- **kwargs: Key-value pairs to add to the initial context.
258
-
259
- Returns:
260
- Self: The workflow instance for method chaining.
261
- """
262
- self.extra_init_context.update(kwargs)
263
- return self
@@ -1,63 +0,0 @@
1
- """A module containing kwargs types for content correction and checking operations."""
2
-
3
- from importlib.util import find_spec
4
- from typing import NotRequired, Optional, TypedDict
5
-
6
- from fabricatio.models.extra.problem import Improvement
7
- from fabricatio.models.extra.rule import RuleSet
8
- from fabricatio.models.generic import SketchedAble
9
- from fabricatio.models.kwargs_types import ReferencedKwargs
10
-
11
-
12
- class CorrectKwargs[T: SketchedAble](ReferencedKwargs[T], total=False):
13
- """Arguments for content correction operations.
14
-
15
- Extends GenerateKwargs with parameters for correcting content based on
16
- specific criteria and templates.
17
- """
18
-
19
- improvement: Improvement
20
-
21
-
22
- class CheckKwargs(ReferencedKwargs[Improvement], total=False):
23
- """Arguments for content checking operations.
24
-
25
- Extends GenerateKwargs with parameters for checking content against
26
- specific criteria and templates.
27
- """
28
-
29
- ruleset: RuleSet
30
-
31
-
32
- if find_spec("pymilvus"):
33
- from pymilvus import CollectionSchema
34
- from pymilvus.milvus_client import IndexParams
35
-
36
- class CollectionConfigKwargs(TypedDict, total=False):
37
- """Configuration parameters for a vector collection.
38
-
39
- These arguments are typically used when configuring connections to vector databases.
40
- """
41
-
42
- dimension: int | None
43
- primary_field_name: str
44
- id_type: str
45
- vector_field_name: str
46
- metric_type: str
47
- timeout: float | None
48
- schema: CollectionSchema | None
49
- index_params: IndexParams | None
50
-
51
- class FetchKwargs(TypedDict):
52
- """Arguments for fetching data from vector collections.
53
-
54
- Controls how data is retrieved from vector databases, including filtering
55
- and result limiting parameters.
56
- """
57
-
58
- collection_name: NotRequired[str | None]
59
- similarity_threshold: NotRequired[float]
60
- result_per_query: NotRequired[int]
61
- tei_endpoint: NotRequired[Optional[str]]
62
- reranker_threshold: NotRequired[float]
63
- filter_expr: NotRequired[str]
@@ -1 +0,0 @@
1
- """A module contains extra models for fabricatio."""
@@ -1,32 +0,0 @@
1
- """Module containing the JudgeMent class for holding judgment results."""
2
-
3
- from typing import List
4
-
5
- from fabricatio.models.generic import SketchedAble
6
-
7
-
8
- class JudgeMent(SketchedAble):
9
- """Represents a judgment result containing supporting/denying evidence and final verdict.
10
-
11
- The class stores both affirmative and denies evidence, truth and reasons lists along with the final boolean judgment.
12
- """
13
-
14
- issue_to_judge: str
15
- """The issue to be judged, including the original question and context"""
16
-
17
- deny_evidence: List[str]
18
- """List of clues supporting the denial."""
19
-
20
- affirm_evidence: List[str]
21
- """List of clues supporting the affirmation."""
22
-
23
- final_judgement: bool
24
- """The final judgment made according to all extracted clues. true for the `issue_to_judge` is correct and false for incorrect."""
25
-
26
- def __bool__(self) -> bool:
27
- """Return the final judgment value.
28
-
29
- Returns:
30
- bool: The stored final_judgement value indicating the judgment result.
31
- """
32
- return self.final_judgement