fabricatio 0.2.8.dev3__cp312-cp312-win_amd64.whl → 0.2.9.dev0__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 (42) hide show
  1. fabricatio/__init__.py +4 -11
  2. fabricatio/actions/__init__.py +1 -0
  3. fabricatio/actions/article.py +63 -87
  4. fabricatio/actions/article_rag.py +54 -43
  5. fabricatio/actions/rag.py +2 -1
  6. fabricatio/actions/rules.py +39 -0
  7. fabricatio/capabilities/__init__.py +1 -0
  8. fabricatio/capabilities/censor.py +90 -0
  9. fabricatio/capabilities/check.py +127 -29
  10. fabricatio/capabilities/correct.py +143 -100
  11. fabricatio/capabilities/rag.py +5 -4
  12. fabricatio/capabilities/rating.py +65 -16
  13. fabricatio/capabilities/review.py +1 -1
  14. fabricatio/capabilities/task.py +2 -1
  15. fabricatio/config.py +11 -3
  16. fabricatio/models/action.py +14 -7
  17. fabricatio/models/adv_kwargs_types.py +25 -0
  18. fabricatio/models/extra/__init__.py +1 -0
  19. fabricatio/models/extra/advanced_judge.py +5 -2
  20. fabricatio/models/extra/article_base.py +3 -20
  21. fabricatio/models/extra/article_main.py +2 -3
  22. fabricatio/models/extra/patches.py +20 -0
  23. fabricatio/models/extra/problem.py +41 -8
  24. fabricatio/models/extra/rule.py +26 -9
  25. fabricatio/models/generic.py +310 -55
  26. fabricatio/models/kwargs_types.py +23 -17
  27. fabricatio/models/task.py +1 -1
  28. fabricatio/models/tool.py +149 -14
  29. fabricatio/models/usages.py +50 -42
  30. fabricatio/parser.py +7 -8
  31. fabricatio/rust.cp312-win_amd64.pyd +0 -0
  32. fabricatio/{_rust_instances.py → rust_instances.py} +1 -1
  33. fabricatio/workflows/__init__.py +1 -0
  34. fabricatio-0.2.9.dev0.data/scripts/tdown.exe +0 -0
  35. {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dev0.dist-info}/METADATA +1 -1
  36. fabricatio-0.2.9.dev0.dist-info/RECORD +61 -0
  37. fabricatio/_rust.cp312-win_amd64.pyd +0 -0
  38. fabricatio-0.2.8.dev3.data/scripts/tdown.exe +0 -0
  39. fabricatio-0.2.8.dev3.dist-info/RECORD +0 -53
  40. /fabricatio/{_rust.pyi → rust.pyi} +0 -0
  41. {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dev0.dist-info}/WHEEL +0 -0
  42. {fabricatio-0.2.8.dev3.dist-info → fabricatio-0.2.9.dev0.dist-info}/licenses/LICENSE +0 -0
fabricatio/models/tool.py CHANGED
@@ -1,4 +1,8 @@
1
- """A module for defining tools and toolboxes."""
1
+ """A module for defining tools and toolboxes.
2
+
3
+ This module provides classes for defining tools and toolboxes, which can be used to manage and execute callable functions
4
+ with additional functionalities such as logging, execution info, and briefing.
5
+ """
2
6
 
3
7
  from importlib.machinery import ModuleSpec
4
8
  from importlib.util import module_from_spec
@@ -14,7 +18,16 @@ from pydantic import BaseModel, ConfigDict, Field
14
18
 
15
19
 
16
20
  class Tool[**P, R](WithBriefing):
17
- """A class representing a tool with a callable source function."""
21
+ """A class representing a tool with a callable source function.
22
+
23
+ This class encapsulates a callable function (source) and provides methods to invoke it, log its execution, and generate
24
+ a brief description (briefing) of the tool.
25
+
26
+ Attributes:
27
+ name (str): The name of the tool.
28
+ description (str): The description of the tool.
29
+ source (Callable[P, R]): The source function of the tool.
30
+ """
18
31
 
19
32
  name: str = Field(default="")
20
33
  """The name of the tool."""
@@ -26,7 +39,16 @@ class Tool[**P, R](WithBriefing):
26
39
  """The source function of the tool."""
27
40
 
28
41
  def model_post_init(self, __context: Any) -> None:
29
- """Initialize the tool with a name and a source function."""
42
+ """Initialize the tool with a name and a source function.
43
+
44
+ This method sets the tool's name and description based on the source function's name and docstring.
45
+
46
+ Args:
47
+ __context (Any): Context passed during model initialization.
48
+
49
+ Raises:
50
+ RuntimeError: If the tool does not have a source function.
51
+ """
30
52
  self.name = self.name or self.source.__name__
31
53
 
32
54
  if not self.name:
@@ -36,7 +58,17 @@ class Tool[**P, R](WithBriefing):
36
58
  self.description = self.description.strip()
37
59
 
38
60
  def invoke(self, *args: P.args, **kwargs: P.kwargs) -> R:
39
- """Invoke the tool's source function with the provided arguments."""
61
+ """Invoke the tool's source function with the provided arguments.
62
+
63
+ This method logs the invocation of the tool and then calls the source function with the given arguments.
64
+
65
+ Args:
66
+ *args (P.args): Positional arguments to be passed to the source function.
67
+ **kwargs (P.kwargs): Keyword arguments to be passed to the source function.
68
+
69
+ Returns:
70
+ R: The result of the source function.
71
+ """
40
72
  logger.info(f"Invoking tool: {self.name}")
41
73
  return self.source(*args, **kwargs)
42
74
 
@@ -44,6 +76,8 @@ class Tool[**P, R](WithBriefing):
44
76
  def briefing(self) -> str:
45
77
  """Return a brief description of the tool.
46
78
 
79
+ This method generates a brief description of the tool, including its name, signature, and description.
80
+
47
81
  Returns:
48
82
  str: A brief description of the tool.
49
83
  """
@@ -59,7 +93,18 @@ def _desc_wrapper(desc: str) -> str:
59
93
 
60
94
 
61
95
  class ToolBox(WithBriefing):
62
- """A class representing a collection of tools."""
96
+ """A class representing a collection of tools.
97
+
98
+ This class manages a list of tools and provides methods to add tools, retrieve tools by name, and generate a brief
99
+ description (briefing) of the toolbox.
100
+
101
+ Attributes:
102
+ description (str): The description of the toolbox.
103
+ tools (List[Tool]): A list of tools in the toolbox.
104
+ """
105
+
106
+ description: str = ""
107
+ """The description of the toolbox."""
63
108
 
64
109
  tools: List[Tool] = Field(default_factory=list, frozen=True)
65
110
  """A list of tools in the toolbox."""
@@ -67,6 +112,8 @@ class ToolBox(WithBriefing):
67
112
  def collect_tool[**P, R](self, func: Callable[P, R]) -> Callable[P, R]:
68
113
  """Add a callable function to the toolbox as a tool.
69
114
 
115
+ This method wraps the function with logging execution info and adds it to the toolbox.
116
+
70
117
  Args:
71
118
  func (Callable[P, R]): The function to be added as a tool.
72
119
 
@@ -79,6 +126,8 @@ class ToolBox(WithBriefing):
79
126
  def add_tool[**P, R](self, func: Callable[P, R]) -> Self:
80
127
  """Add a callable function to the toolbox as a tool.
81
128
 
129
+ This method wraps the function with logging execution info and adds it to the toolbox.
130
+
82
131
  Args:
83
132
  func (Callable): The function to be added as a tool.
84
133
 
@@ -92,6 +141,8 @@ class ToolBox(WithBriefing):
92
141
  def briefing(self) -> str:
93
142
  """Return a brief description of the toolbox.
94
143
 
144
+ This method generates a brief description of the toolbox, including its name, description, and a list of tools.
145
+
95
146
  Returns:
96
147
  str: A brief description of the toolbox.
97
148
  """
@@ -102,6 +153,8 @@ class ToolBox(WithBriefing):
102
153
  def get[**P, R](self, name: str) -> Tool[P, R]:
103
154
  """Invoke a tool by name with the provided arguments.
104
155
 
156
+ This method retrieves a tool by its name from the toolbox.
157
+
105
158
  Args:
106
159
  name (str): The name of the tool to invoke.
107
160
 
@@ -120,13 +173,24 @@ class ToolBox(WithBriefing):
120
173
  return tool
121
174
 
122
175
  def __hash__(self) -> int:
123
- """Return a hash of the toolbox based on its briefing."""
176
+ """Return a hash of the toolbox based on its briefing.
177
+
178
+ Returns:
179
+ int: A hash value based on the toolbox's briefing.
180
+ """
124
181
  return hash(self.briefing)
125
182
 
126
183
 
127
184
  class ToolExecutor(BaseModel):
128
- """A class representing a tool executor with a sequence of tools to execute."""
185
+ """A class representing a tool executor with a sequence of tools to execute.
186
+
187
+ This class manages a sequence of tools and provides methods to inject tools and data into a module, execute the tools,
188
+ and retrieve specific outputs.
129
189
 
190
+ Attributes:
191
+ candidates (List[Tool]): The sequence of tools to execute.
192
+ data (Dict[str, Any]): The data that could be used when invoking the tools.
193
+ """
130
194
  model_config = ConfigDict(use_attribute_docstrings=True)
131
195
  candidates: List[Tool] = Field(default_factory=list, frozen=True)
132
196
  """The sequence of tools to execute."""
@@ -135,7 +199,16 @@ class ToolExecutor(BaseModel):
135
199
  """The data that could be used when invoking the tools."""
136
200
 
137
201
  def inject_tools[M: ModuleType](self, module: Optional[M] = None) -> M:
138
- """Inject the tools into the provided module or default."""
202
+ """Inject the tools into the provided module or default.
203
+
204
+ This method injects the tools into the provided module or creates a new module if none is provided.
205
+
206
+ Args:
207
+ module (Optional[M]): The module to inject tools into. If None, a new module is created.
208
+
209
+ Returns:
210
+ M: The module with injected tools.
211
+ """
139
212
  module = module or cast(
140
213
  "M", module_from_spec(spec=ModuleSpec(name=configs.toolbox.tool_module_name, loader=None))
141
214
  )
@@ -145,7 +218,16 @@ class ToolExecutor(BaseModel):
145
218
  return module
146
219
 
147
220
  def inject_data[M: ModuleType](self, module: Optional[M] = None) -> M:
148
- """Inject the data into the provided module or default."""
221
+ """Inject the data into the provided module or default.
222
+
223
+ This method injects the data into the provided module or creates a new module if none is provided.
224
+
225
+ Args:
226
+ module (Optional[M]): The module to inject data into. If None, a new module is created.
227
+
228
+ Returns:
229
+ M: The module with injected data.
230
+ """
149
231
  module = module or cast(
150
232
  'M', module_from_spec(spec=ModuleSpec(name=configs.toolbox.data_module_name, loader=None))
151
233
  )
@@ -155,7 +237,17 @@ class ToolExecutor(BaseModel):
155
237
  return module
156
238
 
157
239
  def execute[C: Dict[str, Any]](self, source: CodeType, cxt: Optional[C] = None) -> C:
158
- """Execute the sequence of tools with the provided context."""
240
+ """Execute the sequence of tools with the provided context.
241
+
242
+ This method executes the tools in the sequence with the provided context.
243
+
244
+ Args:
245
+ source (CodeType): The source code to execute.
246
+ cxt (Optional[C]): The context to execute the tools with. If None, an empty dictionary is used.
247
+
248
+ Returns:
249
+ C: The context after executing the tools.
250
+ """
159
251
  cxt = cxt or {}
160
252
 
161
253
  @use_temp_module([self.inject_data(), self.inject_tools()])
@@ -167,16 +259,49 @@ class ToolExecutor(BaseModel):
167
259
 
168
260
  @overload
169
261
  def take[C: Dict[str, Any]](self, keys: List[str], source: CodeType, cxt: Optional[C] = None) -> C:
170
- """Check the output of the tools with the provided context."""
262
+ """Check the output of the tools with the provided context.
263
+
264
+ This method executes the tools and retrieves specific keys from the context.
265
+
266
+ Args:
267
+ keys (List[str]): The keys to retrieve from the context.
268
+ source (CodeType): The source code to execute.
269
+ cxt (Optional[C]): The context to execute the tools with. If None, an empty dictionary is used.
270
+
271
+ Returns:
272
+ C: A dictionary containing the retrieved keys and their values.
273
+ """
171
274
  ...
172
275
 
173
276
  @overload
174
277
  def take[C: Dict[str, Any]](self, keys: str, source: CodeType, cxt: Optional[C] = None) -> Any:
175
- """Check the output of the tools with the provided context."""
278
+ """Check the output of the tools with the provided context.
279
+
280
+ This method executes the tools and retrieves a specific key from the context.
281
+
282
+ Args:
283
+ keys (str): The key to retrieve from the context.
284
+ source (CodeType): The source code to execute.
285
+ cxt (Optional[C]): The context to execute the tools with. If None, an empty dictionary is used.
286
+
287
+ Returns:
288
+ Any: The value of the retrieved key.
289
+ """
176
290
  ...
177
291
 
178
292
  def take[C: Dict[str, Any]](self, keys: List[str] | str, source: CodeType, cxt: Optional[C] = None) -> C | Any:
179
- """Check the output of the tools with the provided context."""
293
+ """Check the output of the tools with the provided context.
294
+
295
+ This method executes the tools and retrieves specific keys or a specific key from the context.
296
+
297
+ Args:
298
+ keys (List[str] | str): The keys to retrieve from the context. Can be a single key or a list of keys.
299
+ source (CodeType): The source code to execute.
300
+ cxt (Optional[C]): The context to execute the tools with. If None, an empty dictionary is used.
301
+
302
+ Returns:
303
+ C | Any: A dictionary containing the retrieved keys and their values, or the value of the retrieved key.
304
+ """
180
305
  cxt = self.execute(source, cxt)
181
306
  if isinstance(keys, str):
182
307
  return cxt[keys]
@@ -184,7 +309,17 @@ class ToolExecutor(BaseModel):
184
309
 
185
310
  @classmethod
186
311
  def from_recipe(cls, recipe: List[str], toolboxes: List[ToolBox]) -> Self:
187
- """Create a tool executor from a recipe and a list of toolboxes."""
312
+ """Create a tool executor from a recipe and a list of toolboxes.
313
+
314
+ This method creates a tool executor by retrieving tools from the provided toolboxes based on the recipe.
315
+
316
+ Args:
317
+ recipe (List[str]): The recipe specifying the names of the tools to be added.
318
+ toolboxes (List[ToolBox]): The list of toolboxes to retrieve tools from.
319
+
320
+ Returns:
321
+ Self: A new instance of the tool executor with the specified tools.
322
+ """
188
323
  tools = []
189
324
  while tool_name := recipe.pop(0):
190
325
  for toolbox in toolboxes:
@@ -2,11 +2,10 @@
2
2
 
3
3
  import traceback
4
4
  from asyncio import gather
5
- from typing import Callable, Dict, Iterable, List, Optional, Self, Sequence, Set, Type, Union, Unpack, overload
5
+ from typing import Callable, Dict, Iterable, List, Optional, Self, Sequence, Set, Union, Unpack, overload
6
6
 
7
7
  import asyncstdlib
8
8
  import litellm
9
- from fabricatio._rust_instances import TEMPLATE_MANAGER
10
9
  from fabricatio.config import configs
11
10
  from fabricatio.decorators import logging_exec_time
12
11
  from fabricatio.journal import logger
@@ -16,6 +15,7 @@ from fabricatio.models.task import Task
16
15
  from fabricatio.models.tool import Tool, ToolBox
17
16
  from fabricatio.models.utils import Messages
18
17
  from fabricatio.parser import GenericCapture, JsonCapture
18
+ from fabricatio.rust_instances import TEMPLATE_MANAGER
19
19
  from fabricatio.utils import ok
20
20
  from litellm import RateLimitError, Router, stream_chunk_builder # pyright: ignore [reportPrivateImportUsage]
21
21
  from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
@@ -46,17 +46,24 @@ ROUTER = Router(
46
46
 
47
47
 
48
48
  class LLMUsage(ScopedConfig):
49
- """Class that manages LLM (Large Language Model) usage parameters and methods."""
49
+ """Class that manages LLM (Large Language Model) usage parameters and methods.
50
+
51
+ This class provides methods to deploy LLMs, query them for responses, and handle various configurations
52
+ related to LLM usage such as API keys, endpoints, and rate limits.
53
+ """
50
54
 
51
55
  def _deploy(self, deployment: Deployment) -> Router:
52
- """Add a deployment to the router."""
56
+ """Add a deployment to the router.
57
+
58
+ Args:
59
+ deployment (Deployment): The deployment to be added to the router.
60
+
61
+ Returns:
62
+ Router: The updated router with the added deployment.
63
+ """
53
64
  self._added_deployment = ROUTER.upsert_deployment(deployment)
54
65
  return ROUTER
55
66
 
56
- @classmethod
57
- def _scoped_model(cls) -> Type["LLMUsage"]:
58
- return LLMUsage
59
-
60
67
  # noinspection PyTypeChecker,PydanticTypeChecker
61
68
  async def aquery(
62
69
  self,
@@ -136,7 +143,7 @@ class LLMUsage(ScopedConfig):
136
143
  **kwargs (Unpack[LLMKwargs]): Additional keyword arguments for the LLM usage.
137
144
 
138
145
  Returns:
139
- List[Choices | StreamingChoices]: A list of choices or streaming choices from the model response.
146
+ Sequence[TextChoices | Choices | StreamingChoices]: A sequence of choices or streaming choices from the model response.
140
147
  """
141
148
  resp = await self.aquery(
142
149
  messages=Messages().add_system_message(system_message).add_user_message(question).as_list(),
@@ -288,27 +295,25 @@ class LLMUsage(ScopedConfig):
288
295
  """Asynchronously asks a question and validates the response using a given validator.
289
296
 
290
297
  Args:
291
- question (str): The question to ask.
298
+ question (str | List[str]): The question to ask.
292
299
  validator (Callable[[str], T | None]): A function to validate the response.
293
300
  default (T | None): Default value to return if validation fails. Defaults to None.
294
- max_validations (PositiveInt): Maximum number of validation attempts. Defaults to 2.
301
+ max_validations (PositiveInt): Maximum number of validation attempts. Defaults to 3.
295
302
  co_extractor (Optional[GenerateKwargs]): Keyword arguments for the co-extractor, if provided will enable co-extraction.
296
- **kwargs (Unpack[LLMKwargs]): Additional keyword arguments for the LLM usage.
303
+ **kwargs (Unpack[GenerateKwargs]): Additional keyword arguments for the LLM usage.
297
304
 
298
305
  Returns:
299
- T: The validated response.
300
-
306
+ Optional[T] | List[Optional[T]] | List[T] | T: The validated response.
301
307
  """
302
308
 
303
309
  async def _inner(q: str) -> Optional[T]:
304
310
  for lap in range(max_validations):
305
311
  try:
306
- if (
307
- (response := await self.aask(question=q, **kwargs))
308
- or (
309
- co_extractor
310
- and (
311
- response := await self.aask(
312
+ if ((validated := validator(response := await self.aask(question=q, **kwargs))) is not None) or (
313
+ co_extractor
314
+ and (
315
+ validated := validator(
316
+ await self.aask(
312
317
  question=(
313
318
  TEMPLATE_MANAGER.render_template(
314
319
  configs.templates.co_validation_template,
@@ -319,7 +324,8 @@ class LLMUsage(ScopedConfig):
319
324
  )
320
325
  )
321
326
  )
322
- ) and (validated := validator(response)):
327
+ is not None
328
+ ):
323
329
  logger.debug(f"Successfully validated the response at {lap}th attempt.")
324
330
  return validated
325
331
 
@@ -350,7 +356,7 @@ class LLMUsage(ScopedConfig):
350
356
  **kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
351
357
 
352
358
  Returns:
353
- List[str]: The validated response as a list of strings.
359
+ Optional[List[str]]: The validated response as a list of strings.
354
360
  """
355
361
  return await self.aask_validate(
356
362
  TEMPLATE_MANAGER.render_template(
@@ -361,7 +367,6 @@ class LLMUsage(ScopedConfig):
361
367
  **kwargs,
362
368
  )
363
369
 
364
-
365
370
  async def apathstr(self, requirement: str, **kwargs: Unpack[ChooseKwargs[List[str]]]) -> Optional[List[str]]:
366
371
  """Asynchronously generates a list of strings based on a given requirement.
367
372
 
@@ -370,7 +375,7 @@ class LLMUsage(ScopedConfig):
370
375
  **kwargs (Unpack[ChooseKwargs]): Additional keyword arguments for the LLM usage.
371
376
 
372
377
  Returns:
373
- List[str]: The validated response as a list of strings.
378
+ Optional[List[str]]: The validated response as a list of strings.
374
379
  """
375
380
  return await self.alist_str(
376
381
  TEMPLATE_MANAGER.render_template(
@@ -388,7 +393,7 @@ class LLMUsage(ScopedConfig):
388
393
  **kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
389
394
 
390
395
  Returns:
391
- str: The validated response as a single string.
396
+ Optional[str]: The validated response as a single string.
392
397
  """
393
398
  if paths := await self.apathstr(
394
399
  requirement,
@@ -407,7 +412,7 @@ class LLMUsage(ScopedConfig):
407
412
  **kwargs (Unpack[GenerateKwargs]): Additional keyword arguments for the LLM usage.
408
413
 
409
414
  Returns:
410
- str: The generated string.
415
+ Optional[str]: The generated string.
411
416
  """
412
417
  return await self.aask_validate( # pyright: ignore [reportReturnType]
413
418
  TEMPLATE_MANAGER.render_template(
@@ -434,12 +439,7 @@ class LLMUsage(ScopedConfig):
434
439
  **kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
435
440
 
436
441
  Returns:
437
- List[T]: The final validated selection result list, with element types matching the input `choices`.
438
-
439
- Important:
440
- - Uses a template engine to generate structured prompts.
441
- - Ensures response compliance through JSON parsing and format validation.
442
- - Relies on `aask_validate` to implement retry mechanisms with validation.
442
+ Optional[List[T]]: The final validated selection result list, with element types matching the input `choices`.
443
443
  """
444
444
  if dup := duplicates_everseen(choices, key=lambda x: x.name):
445
445
  logger.error(err := f"Redundant choices: {dup}")
@@ -527,7 +527,10 @@ class LLMUsage(ScopedConfig):
527
527
 
528
528
 
529
529
  class EmbeddingUsage(LLMUsage):
530
- """A class representing the embedding model."""
530
+ """A class representing the embedding model.
531
+
532
+ This class extends LLMUsage and provides methods to generate embeddings for input text using various models.
533
+ """
531
534
 
532
535
  async def aembedding(
533
536
  self,
@@ -546,13 +549,12 @@ class EmbeddingUsage(LLMUsage):
546
549
  timeout (Optional[PositiveInt]): The timeout for the embedding request. Defaults to the instance's `llm_timeout` or the global configuration.
547
550
  caching (Optional[bool]): Whether to cache the embedding result. Defaults to False.
548
551
 
549
-
550
552
  Returns:
551
553
  EmbeddingResponse: The response containing the embeddings.
552
554
  """
553
555
  # check seq length
554
556
  max_len = self.embedding_max_sequence_length or configs.embedding.max_sequence_length
555
- if max_len and any(length:=(token_counter(text=t)) > max_len for t in input_text):
557
+ if max_len and any(length := (token_counter(text=t)) > max_len for t in input_text):
556
558
  logger.error(err := f"Input text exceeds maximum sequence length {max_len}, got {length}.")
557
559
  raise ValueError(err)
558
560
 
@@ -604,14 +606,21 @@ class EmbeddingUsage(LLMUsage):
604
606
 
605
607
 
606
608
  class ToolBoxUsage(LLMUsage):
607
- """A class representing the usage of tools in a task."""
609
+ """A class representing the usage of tools in a task.
610
+
611
+ This class extends LLMUsage and provides methods to manage and use toolboxes and tools within tasks.
612
+ """
608
613
 
609
614
  toolboxes: Set[ToolBox] = Field(default_factory=set)
610
615
  """A set of toolboxes used by the instance."""
611
616
 
612
617
  @property
613
618
  def available_toolbox_names(self) -> List[str]:
614
- """Return a list of available toolbox names."""
619
+ """Return a list of available toolbox names.
620
+
621
+ Returns:
622
+ List[str]: A list of names of the available toolboxes.
623
+ """
615
624
  return [toolbox.name for toolbox in self.toolboxes]
616
625
 
617
626
  async def choose_toolboxes(
@@ -623,11 +632,10 @@ class ToolBoxUsage(LLMUsage):
623
632
 
624
633
  Args:
625
634
  task (Task): The task for which to choose toolboxes.
626
- system_message (str): Custom system-level prompt, defaults to an empty string.
627
635
  **kwargs (Unpack[LLMKwargs]): Additional keyword arguments for the LLM usage.
628
636
 
629
637
  Returns:
630
- List[ToolBox]: The selected toolboxes.
638
+ Optional[List[ToolBox]]: The selected toolboxes.
631
639
  """
632
640
  if not self.toolboxes:
633
641
  logger.warning("No toolboxes available.")
@@ -652,7 +660,7 @@ class ToolBoxUsage(LLMUsage):
652
660
  **kwargs (Unpack[LLMKwargs]): Additional keyword arguments for the LLM usage.
653
661
 
654
662
  Returns:
655
- List[Tool]: The selected tools.
663
+ Optional[List[Tool]]: The selected tools.
656
664
  """
657
665
  if not toolbox.tools:
658
666
  logger.warning(f"No tools available in toolbox {toolbox.name}.")
@@ -714,7 +722,7 @@ class ToolBoxUsage(LLMUsage):
714
722
  """
715
723
  if isinstance(others, ToolBoxUsage):
716
724
  others = [others]
717
- for other in others:
725
+ for other in (x for x in others if isinstance(x, ToolBoxUsage)):
718
726
  self.toolboxes.update(other.toolboxes)
719
727
  return self
720
728
 
@@ -730,6 +738,6 @@ class ToolBoxUsage(LLMUsage):
730
738
  """
731
739
  if isinstance(others, ToolBoxUsage):
732
740
  others = [others]
733
- for other in others:
741
+ for other in (x for x in others if isinstance(x, ToolBoxUsage)):
734
742
  other.toolboxes.update(self.toolboxes)
735
743
  return self
fabricatio/parser.py CHANGED
@@ -45,14 +45,14 @@ class Capture(BaseModel):
45
45
  str | List[str]: The fixed text with the same type as input.
46
46
  """
47
47
  match self.capture_type:
48
- case "json":
48
+ case "json" if configs.general.use_json_repair:
49
+ logger.debug("Applying json repair to text.")
49
50
  if isinstance(text, str):
50
51
  return repair_json(text, ensure_ascii=False)
51
52
  return [repair_json(item, ensure_ascii=False) for item in text]
52
53
  case _:
53
54
  return text
54
55
 
55
-
56
56
  def capture(self, text: str) -> Tuple[str, ...] | str | None:
57
57
  """Capture the first occurrence of the pattern in the given text.
58
58
 
@@ -63,11 +63,10 @@ class Capture(BaseModel):
63
63
  str | None: The captured text if the pattern is found, otherwise None.
64
64
 
65
65
  """
66
- match = self._compiled.search(text)
67
- if match is None:
68
- logger.debug(f"Capture Failed: \n{text}")
66
+ if (match :=self._compiled.match(text) or self._compiled.search(text) ) is None:
67
+ logger.debug(f"Capture Failed {type(text)}: \n{text}")
69
68
  return None
70
- groups = self.fix(match.groups()) if configs.general.use_json_repair else match.groups()
69
+ groups = self.fix(match.groups())
71
70
  if self.target_groups:
72
71
  cap = tuple(groups[g - 1] for g in self.target_groups)
73
72
  logger.debug(f"Captured text: {'\n\n'.join(cap)}")
@@ -134,7 +133,7 @@ class Capture(BaseModel):
134
133
  Returns:
135
134
  Self: The instance of the class with the captured code block.
136
135
  """
137
- return cls(pattern=f"```{language}\n(.*?)\n```", capture_type=language)
136
+ return cls(pattern=f"```{language}(.*?)```", capture_type=language)
138
137
 
139
138
  @classmethod
140
139
  def capture_generic_block(cls, language: str) -> Self:
@@ -143,7 +142,7 @@ class Capture(BaseModel):
143
142
  Returns:
144
143
  Self: The instance of the class with the captured code block.
145
144
  """
146
- return cls(pattern=f"--- Start of {language} ---\n(.*?)\n--- end of {language} ---", capture_type=language)
145
+ return cls(pattern=f"--- Start of {language} ---(.*?)--- end of {language} ---", capture_type=language)
147
146
 
148
147
 
149
148
  JsonCapture = Capture.capture_code_block("json")
Binary file
@@ -1,7 +1,7 @@
1
1
  """Some necessary instances."""
2
2
 
3
- from fabricatio._rust import TemplateManager
4
3
  from fabricatio.config import configs
4
+ from fabricatio.rust import TemplateManager
5
5
 
6
6
  TEMPLATE_MANAGER = TemplateManager(
7
7
  template_dirs=configs.templates.template_dir,
@@ -0,0 +1 @@
1
+ """A module containing some builtin workflows."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fabricatio
3
- Version: 0.2.8.dev3
3
+ Version: 0.2.9.dev0
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -0,0 +1,61 @@
1
+ fabricatio-0.2.9.dev0.dist-info/METADATA,sha256=BMpvwW9IuEvcJ_WzIZQmvQc4bGRogNfCZlyuCYNo0M8,5288
2
+ fabricatio-0.2.9.dev0.dist-info/WHEEL,sha256=jABKVkLC9kJr8mi_er5jOqpiQUjARSLXDUIIxDqsS50,96
3
+ fabricatio-0.2.9.dev0.dist-info/licenses/LICENSE,sha256=do7J7EiCGbq0QPbMAL_FqLYufXpHnCnXBOuqVPwSV8Y,1088
4
+ fabricatio/actions/article.py,sha256=D-9aGLC1eW9w_aNICGNpdkUm7jx01h8nBcAPSW_Da7E,12788
5
+ fabricatio/actions/article_rag.py,sha256=dkfskNqntVPi81Xm_NFdTQM8v2nR9FJIexzkK9rg-NU,4352
6
+ fabricatio/actions/output.py,sha256=-FfTzXEHIb_zOT-j4T4b5ND96zHLDEGdjlmmPviIbiM,3754
7
+ fabricatio/actions/rag.py,sha256=5nSih3YUkdt1uU02hSAMW6sADq9mkMOR1wDv7zIrIGQ,2737
8
+ fabricatio/actions/rules.py,sha256=pA6ADNgpPWBp2a3FTEuF--0INHg0QJxc0kfxF1zMDXQ,1541
9
+ fabricatio/actions/__init__.py,sha256=wVENCFtpVb1rLFxoOFJt9-8smLWXuJV7IwA8P3EfFz4,48
10
+ fabricatio/capabilities/advanced_judge.py,sha256=selB0Gwf1F4gGJlwBiRo6gI4KOUROgh3WnzO3mZFEls,706
11
+ fabricatio/capabilities/censor.py,sha256=J-YgwnDus3vKDpeFENhGvUSxvpC8FnhhnWJe1RffcqI,3869
12
+ fabricatio/capabilities/check.py,sha256=uzxiar7bHGgxu7JqU8tRSncN3KP6xo5r3c8wvyBd3M8,8287
13
+ fabricatio/capabilities/correct.py,sha256=I9RWmFjwXEjbYzIgtyFbqc0RvTpHeMHdGT9tuKHwCtY,9177
14
+ fabricatio/capabilities/propose.py,sha256=hkBeSlmcTdfYWT-ph6nlbtHXBozi_JXqXlWcnBy3W78,2007
15
+ fabricatio/capabilities/rag.py,sha256=8TTJSV2Tz0naXyOQ5c_RQ4h9ZxyOOSE7BvyWxKkQMU0,17722
16
+ fabricatio/capabilities/rating.py,sha256=5HjWGk-tFscnMo4cFTAE820yeOaXT9utNSRKVrSTbSA,17012
17
+ fabricatio/capabilities/review.py,sha256=-EMZe0ADFPT6fPGmra16UPjJC1M3rAs6dPFdTZ88Fgg,5060
18
+ fabricatio/capabilities/task.py,sha256=JahC61X233UIPsjovxJgc_yqj_BjWZJBCzJZq11M2Xk,4417
19
+ fabricatio/capabilities/__init__.py,sha256=v1cHRHIJ2gxyqMLNCs6ERVcCakSasZNYzmMI4lqAcls,57
20
+ fabricatio/config.py,sha256=Q9VHk4T8ajJEPPckjUuhJ0vjvqc79zufUbek_5GHTbE,17679
21
+ fabricatio/core.py,sha256=VQ_JKgUGIy2gZ8xsTBZCdr_IP7wC5aPg0_bsOmjQ588,6458
22
+ fabricatio/decorators.py,sha256=C0Gi7wcXC-0sWITqsSv3JdBGcgVJOlRvOt0FfO0aUsA,7554
23
+ fabricatio/fs/curd.py,sha256=p8y0LGKgVDk-CWOlm37E6wg7RK6RCD6denKo-VsW28c,4763
24
+ fabricatio/fs/readers.py,sha256=EZKN_AZdrp8DggJECP53QHw3uHeSDf-AwCAA_V7fNKU,1202
25
+ fabricatio/fs/__init__.py,sha256=PCf0s_9KDjVfNw7AfPoJzGt3jMq4gJOfbcT4pb0D0ZY,588
26
+ fabricatio/journal.py,sha256=stnEP88aUBA_GmU9gfTF2EZI8FS2OyMLGaMSTgK4QgA,476
27
+ fabricatio/models/action.py,sha256=C0PnZ5ycLcqcQ5s1h4KcLJXc1ZZmxYRfCQvz2DuSAOo,9229
28
+ fabricatio/models/adv_kwargs_types.py,sha256=dcYMLn6xcnWLZTLTBdtpgUZWi-VBeub721GzHRZFT1g,860
29
+ fabricatio/models/events.py,sha256=QvlnS8FEELg6KNabcJMeh2GV_y0ZBzKOPphcteKYWYU,4183
30
+ fabricatio/models/extra/advanced_judge.py,sha256=mi3KiB8FUuSYICzXPXKwVhCyRE1GL3gHLkwuc-4mh3c,999
31
+ fabricatio/models/extra/article_base.py,sha256=1Fg3iWbod1TCU3nIJK9mOq_8K3oGBtSW03VUwi2I5tg,17058
32
+ fabricatio/models/extra/article_essence.py,sha256=xd6j-PDqjhrMjgUmyfk6HqkyMLu-sS9feUo0sZ3QABY,2825
33
+ fabricatio/models/extra/article_main.py,sha256=0Xj54pRxUw5Iaj9npYmHKT-ZMvEIBlZ6G1ysNJRgceM,8225
34
+ fabricatio/models/extra/article_outline.py,sha256=jFbVgiwlo7rnwCGS6ToVgeMUOoRe99Edgbx95THR6z8,1450
35
+ fabricatio/models/extra/article_proposal.py,sha256=L2kPvH1XCCQSNcI1KQU3ULGq7C24Y88ssugX43LgbsE,2043
36
+ fabricatio/models/extra/patches.py,sha256=-nBsse7g1astJh_IWZLXJdEQxpRla-DkHWqSHE-zbMU,989
37
+ fabricatio/models/extra/problem.py,sha256=KwYkc7kjoEG7cwj9C8sWLoZgtBqJVuxlU_7KkvtSgO0,5828
38
+ fabricatio/models/extra/rule.py,sha256=SDAPub17OzVJlPby358MQpKCyxmmojWucfuyr5zogeI,2091
39
+ fabricatio/models/extra/__init__.py,sha256=XlYnS_2B9nhLhtQkjE7rvvfPmAAtXVdNi9bSDAR-Ge8,54
40
+ fabricatio/models/generic.py,sha256=ioofSuSxJrgij6ZwucCV7RkVEU9XkW3C359k7s8ZhPA,28274
41
+ fabricatio/models/kwargs_types.py,sha256=sMDA85SoC1AOJ5k6qC8qUiUv0Ne0_5ThU9FZITRNen4,5673
42
+ fabricatio/models/role.py,sha256=-CRcj5_M3_ciLPzwiNn92grBmwoSLQ-n4koVZiCNTBM,2953
43
+ fabricatio/models/task.py,sha256=YXvO3upJkTqMQjPgUGfp0bIiSyZzek2f4IagHdMW5Ik,10491
44
+ fabricatio/models/tool.py,sha256=jQ51g4lwTPfsMF1nbreDJtBczbxIHoXcPuLSOqHliq8,12506
45
+ fabricatio/models/usages.py,sha256=atMrA1MlPthpKYjV5lIrvJwe-BFomOQXQAWAS85YFqw,32319
46
+ fabricatio/models/utils.py,sha256=Ac5g-8ic6q_w7dhNuh-iiofpL1sqOACxbjPPTljP2LY,4417
47
+ fabricatio/parser.py,sha256=UOSvXigEXK-eXsr3m3b7glOhbBWs4kDJTeTNyuqA9ic,6315
48
+ fabricatio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
+ fabricatio/rust.pyi,sha256=_N8Jw1DMOFAaoibSQolxkKZ07nCfJao7Z9qkojHtLy0,5104
50
+ fabricatio/rust_instances.py,sha256=Byeo8KHW_dJiXujJq7YPGDLBX5bHNDYbBc4sY3uubVY,313
51
+ fabricatio/toolboxes/arithmetic.py,sha256=WLqhY-Pikv11Y_0SGajwZx3WhsLNpHKf9drzAqOf_nY,1369
52
+ fabricatio/toolboxes/fs.py,sha256=l4L1CVxJmjw9Ld2XUpIlWfV0_Fu_2Og6d3E13I-S4aE,736
53
+ fabricatio/toolboxes/__init__.py,sha256=KBJi5OG_pExscdlM7Bnt_UF43j4I3Lv6G71kPVu4KQU,395
54
+ fabricatio/utils.py,sha256=QJR00IuclL2nNTSfpTNBRYJmNjc_DNXGtrYWjatWpq8,1681
55
+ fabricatio/workflows/articles.py,sha256=G5HGRr-DHuYuEcfhFdFAuDvTTJ9aSU_UQ2yYXEjTMtM,1047
56
+ fabricatio/workflows/rag.py,sha256=-YYp2tlE9Vtfgpg6ROpu6QVO8j8yVSPa6yDzlN3qVxs,520
57
+ fabricatio/workflows/__init__.py,sha256=5ScFSTA-bvhCesj3U9Mnmi6Law6N1fmh5UKyh58L3u8,51
58
+ fabricatio/__init__.py,sha256=Rmvq2VgdS2u68vnOi2i5RbeWbAwrJDbk8D8D883PJWE,1022
59
+ fabricatio/rust.cp312-win_amd64.pyd,sha256=zttODmJfFoJUea2oaoWsbQK9u1wsQFCZXvLmlaFouts,1896960
60
+ fabricatio-0.2.9.dev0.data/scripts/tdown.exe,sha256=hAuKtjV8oj1fsMlF6_2W5Asc8tgsPFVPSQhcBPzKnFM,3395072
61
+ fabricatio-0.2.9.dev0.dist-info/RECORD,,
Binary file