fabricatio 0.2.0.dev12__cp312-cp312-manylinux_2_34_x86_64.whl → 0.2.0.dev13__cp312-cp312-manylinux_2_34_x86_64.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.
@@ -17,6 +17,7 @@ from pydantic import (
17
17
  Field,
18
18
  HttpUrl,
19
19
  NonNegativeFloat,
20
+ NonNegativeInt,
20
21
  PositiveInt,
21
22
  SecretStr,
22
23
  )
@@ -295,6 +296,7 @@ class LLMUsage(Base):
295
296
  self,
296
297
  instruction: str,
297
298
  choices: List[T],
299
+ k: NonNegativeInt = 0,
298
300
  max_validations: PositiveInt = 2,
299
301
  system_message: str = "",
300
302
  model: str | None = None,
@@ -311,6 +313,7 @@ class LLMUsage(Base):
311
313
  Args:
312
314
  instruction: The user-provided instruction/question description.
313
315
  choices: A list of candidate options, requiring elements to have `name` and `briefing` fields.
316
+ k: The number of choices to select, 0 means infinite.
314
317
  max_validations: Maximum number of validation failures, default is 2.
315
318
  system_message: Custom system-level prompt, defaults to an empty string.
316
319
  model: The name of the LLM model to use.
@@ -332,14 +335,17 @@ class LLMUsage(Base):
332
335
  """
333
336
  prompt = template_manager.render_template(
334
337
  "make_choice",
335
- {"instruction": instruction, "options": [m.model_dump(include={"name", "briefing"}) for m in choices]},
338
+ {
339
+ "instruction": instruction,
340
+ "options": [m.model_dump(include={"name", "briefing"}) for m in choices],
341
+ "k": k,
342
+ },
336
343
  )
337
344
  names = [c.name for c in choices]
338
345
 
339
346
  def _validate(response: str) -> List[T] | None:
340
- cap = JsonCapture.capture(response)
341
- ret = orjson.loads(cap)
342
- if not isinstance(ret, List):
347
+ ret = JsonCapture.convert_with(response, orjson.loads)
348
+ if not isinstance(ret, List) or len(ret) != k:
343
349
  return None
344
350
  if any(n not in names for n in ret):
345
351
  return None
@@ -360,6 +366,70 @@ class LLMUsage(Base):
360
366
  max_retries=max_retries,
361
367
  )
362
368
 
369
+ async def ajudge(
370
+ self,
371
+ prompt: str,
372
+ affirm_case: str = "",
373
+ deny_case: str = "",
374
+ max_validations: PositiveInt = 2,
375
+ system_message: str = "",
376
+ model: str | None = None,
377
+ temperature: NonNegativeFloat | None = None,
378
+ stop: str | List[str] | None = None,
379
+ top_p: NonNegativeFloat | None = None,
380
+ max_tokens: PositiveInt | None = None,
381
+ stream: bool | None = None,
382
+ timeout: PositiveInt | None = None,
383
+ max_retries: PositiveInt | None = None,
384
+ ) -> bool:
385
+ """Asynchronously judges a prompt using AI validation.
386
+
387
+ Args:
388
+ prompt (str): The input prompt to be judged.
389
+ affirm_case (str, optional): The affirmative case for the AI model. Defaults to "".
390
+ deny_case (str, optional): The negative case for the AI model. Defaults to "".
391
+ max_validations (PositiveInt, optional): Maximum number of validation attempts. Defaults to 2.
392
+ system_message (str, optional): System message for the AI model. Defaults to "".
393
+ model (str | None, optional): AI model to use. Defaults to None.
394
+ temperature (NonNegativeFloat | None, optional): Sampling temperature. Defaults to None.
395
+ stop (str | List[str] | None, optional): Stop sequences. Defaults to None.
396
+ top_p (NonNegativeFloat | None, optional): Nucleus sampling parameter. Defaults to None.
397
+ max_tokens (PositiveInt | None, optional): Maximum number of tokens to generate. Defaults to None.
398
+ stream (bool | None, optional): Whether to stream the response. Defaults to None.
399
+ timeout (PositiveInt | None, optional): Timeout in seconds. Defaults to None.
400
+ max_retries (PositiveInt | None, optional): Maximum number of retries. Defaults to None.
401
+
402
+ Returns:
403
+ bool: The judgment result (True or False) based on the AI's response.
404
+
405
+ Notes:
406
+ The method uses an internal validator to ensure the response is a boolean value.
407
+ If the response cannot be converted to a boolean, it will return None.
408
+ """
409
+
410
+ def _validate(response: str) -> bool | None:
411
+ ret = JsonCapture.convert_with(response, orjson.loads)
412
+ if not isinstance(ret, bool):
413
+ return None
414
+ return ret
415
+
416
+ return await self.aask_validate(
417
+ question=template_manager.render_template(
418
+ "make_judgment", {"prompt": prompt, "affirm_case": affirm_case, "deny_case": deny_case}
419
+ ),
420
+ validator=_validate,
421
+ max_validations=max_validations,
422
+ system_message=system_message,
423
+ model=model,
424
+ temperature=temperature,
425
+ stop=stop,
426
+ top_p=top_p,
427
+ max_tokens=max_tokens,
428
+ stream=stream,
429
+ timeout=timeout,
430
+ max_retries=max_retries,
431
+ )
432
+
363
433
  def fallback_to(self, other: "LLMUsage") -> Self:
364
434
  """Fallback to another instance's attribute values if the current instance's attributes are None.
365
435
 
fabricatio/models/task.py CHANGED
@@ -268,8 +268,8 @@ class ProposeTask(LLMUsage, WithBriefing):
268
268
  try:
269
269
  cap = JsonCapture.capture(response)
270
270
  logger.debug(f"Response: \n{response}")
271
- logger.info(f"Captured JSON: \n{cap[0]}")
272
- return Task.model_validate_json(cap[0] if cap else response)
271
+ logger.info(f"Captured JSON: \n{cap}")
272
+ return Task.model_validate_json(cap)
273
273
  except ValidationError as e:
274
274
  logger.error(f"Failed to parse task from JSON: {e}")
275
275
  return None
fabricatio/parser.py CHANGED
@@ -1,11 +1,13 @@
1
1
  """A module to parse text using regular expressions."""
2
2
 
3
- from typing import Any, Self, Tuple
3
+ from typing import Any, Callable, Self, Tuple
4
4
 
5
5
  import regex
6
6
  from pydantic import BaseModel, ConfigDict, Field, PositiveInt, PrivateAttr
7
7
  from regex import Pattern, compile
8
8
 
9
+ from fabricatio.journal import logger
10
+
9
11
 
10
12
  class Capture(BaseModel):
11
13
  """A class to capture patterns in text using regular expressions.
@@ -32,7 +34,7 @@ class Capture(BaseModel):
32
34
  """
33
35
  self._compiled = compile(self.pattern, self.flags)
34
36
 
35
- def capture(self, text: str) -> Tuple[str, ...] | None:
37
+ def capture(self, text: str) -> Tuple[str, ...] | str | None:
36
38
  """Capture the first occurrence of the pattern in the given text.
37
39
 
38
40
  Args:
@@ -48,7 +50,25 @@ class Capture(BaseModel):
48
50
 
49
51
  if self.target_groups:
50
52
  return tuple(match.group(g) for g in self.target_groups)
51
- return (match.group(),)
53
+ return match.group(1)
54
+
55
+ def convert_with[T](self, text: str, convertor: Callable[[Tuple[str, ...]], T] | Callable[[str], T]) -> T | None:
56
+ """Convert the given text using the pattern.
57
+
58
+ Args:
59
+ text (str): The text to search the pattern in.
60
+ convertor (Callable[[Tuple[str, ...]], T] | Callable[[str], T]): The function to convert the captured text.
61
+
62
+ Returns:
63
+ str | None: The converted text if the pattern is found, otherwise None.
64
+ """
65
+ if cap := self.capture(text) is None:
66
+ return None
67
+ try:
68
+ return convertor(cap)
69
+ except ValueError as e:
70
+ logger.error(f"Failed to convert text using convertor: {convertor.__name__}, error: \n{e}")
71
+ return None
52
72
 
53
73
  @classmethod
54
74
  def capture_code_block(cls, language: str) -> Self:
@@ -60,7 +80,7 @@ class Capture(BaseModel):
60
80
  Returns:
61
81
  Self: The instance of the class with the captured code block.
62
82
  """
63
- return cls(pattern=f"```{language}\n(.*?)\n```", target_groups=(1,))
83
+ return cls(pattern=f"```{language}\n(.*?)\n```")
64
84
 
65
85
 
66
86
  JsonCapture = Capture.capture_code_block("json")
@@ -1,3 +1,5 @@
1
+ """Arithmetic tools for Fabricatio."""
2
+
1
3
  from fabricatio.models.tool import ToolBox
2
4
 
3
5
  arithmetic_tools = ToolBox(name="ArithmeticToolBox", description="A toolbox for arithmetic operations.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fabricatio
3
- Version: 0.2.0.dev12
3
+ Version: 0.2.0.dev13
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -28,6 +28,9 @@ Keywords: ai,agents,multi-agent,llm,pyo3
28
28
  Author-email: Whth <zettainspector@foxmail.com>
29
29
  Requires-Python: >=3.12
30
30
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
31
+ Project-URL: Homepage, https://github.com/Whth/fabricatio
32
+ Project-URL: Repository, https://github.com/Whth/fabricatio
33
+ Project-URL: Issues, https://github.com/Whth/fabricatio/issues
31
34
 
32
35
  # Fabricatio
33
36
 
@@ -1,19 +1,19 @@
1
- fabricatio-0.2.0.dev12.dist-info/METADATA,sha256=gWEeKNwVXLETbzTMO9Qd2rkbN_TLH4sdpedRVvW8myc,5824
2
- fabricatio-0.2.0.dev12.dist-info/WHEEL,sha256=RIvmwLDYujv60MYBx2jxyP4vdn1DD7X0kBgz1TQvZuc,108
3
- fabricatio-0.2.0.dev12.dist-info/licenses/LICENSE,sha256=yDZaTLnOi03bi3Dk6f5IjhLUc5old2yOsihHWU0z-i0,1067
1
+ fabricatio-0.2.0.dev13.dist-info/METADATA,sha256=Q4r0vbpk3dJdnWiK1pnt8aj19fPelsaKZH1XXtAw68E,6005
2
+ fabricatio-0.2.0.dev13.dist-info/WHEEL,sha256=RIvmwLDYujv60MYBx2jxyP4vdn1DD7X0kBgz1TQvZuc,108
3
+ fabricatio-0.2.0.dev13.dist-info/licenses/LICENSE,sha256=yDZaTLnOi03bi3Dk6f5IjhLUc5old2yOsihHWU0z-i0,1067
4
4
  fabricatio/fs/__init__.py,sha256=bYE9r8uR0dtknzbg_YaGv_6Wwa27ntkQt0Tl7Kb3HFI,117
5
5
  fabricatio/fs/readers.py,sha256=E219Pef7gknltkHjL9iZXwjI841_EPFpNvDG9KBUG3g,118
6
6
  fabricatio/toolboxes/__init__.py,sha256=8gd8yPhhQBO0A37w1zqVLfbOG-pyCPrveEtO0MX042A,151
7
7
  fabricatio/toolboxes/task.py,sha256=G_nNYT8Sy5ll6YmXES458MUmgJnDSBNwlozyJewdnzY,200
8
- fabricatio/toolboxes/arithmetic.py,sha256=MbS1-a4uLGqs7ZypH2dtrTa0d2-Rr8ifok-1mrVfVb4,1257
8
+ fabricatio/toolboxes/arithmetic.py,sha256=bG4ngqBrTaj4zHxpMTbK-JQ4Si96UiiHz7fufSQWu-0,1297
9
9
  fabricatio/__init__.py,sha256=UE2qARwRgL3T1NgnzK9b4Cx3eksUvNZmN_rf-dycM4E,881
10
10
  fabricatio/core.py,sha256=apwXgI94DCWpGujGlsmXsTZQvJOQMB9llmuUo7ohd-4,5771
11
11
  fabricatio/config.py,sha256=Or_PzOzXy_4Rqje1r788sID4bxILXhNC3r7eelcZJy0,7852
12
12
  fabricatio/decorators.py,sha256=UgW8_pV_RUm0a69co1POnKvJHh9Qy2R0pyh1BtEKzFI,1169
13
13
  fabricatio/journal.py,sha256=u6YTKrD9EoebbR8guvAe5zSqWV1nS-BGyKxZR_Sw2ik,684
14
- fabricatio/models/generic.py,sha256=Q92xkAL1S8zWMCGDUNQahT9atFamZKhHzKbI1OXjBmk,19264
14
+ fabricatio/models/generic.py,sha256=pV84sWgZZItgotFTchfyixSLSnmv5GkumSv_0frPK38,22402
15
15
  fabricatio/models/action.py,sha256=VL_A8BWOuCYQCjwCAm0vExA88KSwm6VkluXHOtHijUw,4882
16
- fabricatio/models/task.py,sha256=-YB9SGqOYrPmk7ce5Go3OO5Cc7Q_KB7QdmeG49GeZpY,9090
16
+ fabricatio/models/task.py,sha256=2jSttV7Yod2Waz16RByFZrRZT07YThs5Vw5pgbjbD1s,9063
17
17
  fabricatio/models/role.py,sha256=1vhpHRKJ6f7PDBLl6jYRZbxTJyrVhNN3FEEh_HAwU3o,990
18
18
  fabricatio/models/tool.py,sha256=PCsX5hdf6YnslkyoPA8FwybGvrO0fJFJpHsheBwg2bo,4886
19
19
  fabricatio/models/events.py,sha256=S0E7l5iQoJYdUn0pSSziHdXqPzIvvLy8ifVPQxXeAho,2570
@@ -24,7 +24,7 @@ fabricatio/actions/__init__.py,sha256=eLa_5ACZ-FqdrLtOfCHk5nQBxzhIs1kgMIXWmkm2P8
24
24
  fabricatio/actions/communication.py,sha256=4hNzyv5_j4HU291dDuBmBEb66VihQPI9SLRVZrxWu1Y,412
25
25
  fabricatio/actions/transmission.py,sha256=gLLKoi4keL64uaEkHDxwVrBGciheupQrO2fW3GkjfEw,1156
26
26
  fabricatio/_rust.pyi,sha256=EwMPoCZFOCYZ5h_9PZLvO3YrgBEG0Hwae0ux0hcBabM,1487
27
- fabricatio/parser.py,sha256=CAI7S3u2xI_-s1JWb4v2GkhiNeX1kr_C2olxy98KLR8,2400
28
- fabricatio/_rust.cpython-312-x86_64-linux-gnu.so,sha256=JUDe4N51fXgkY7c-vEXnFJaTBWzwwh93AwJPk_QWoGE,1190824
29
- fabricatio-0.2.0.dev12.data/scripts/tdown,sha256=7IEbm2H2hkcCNmm8b4BEfHtnauc5oO9fIiGn_UXYb3M,4549648
30
- fabricatio-0.2.0.dev12.dist-info/RECORD,,
27
+ fabricatio/parser.py,sha256=Ef-uOmrx-1wQqNlcPyPf_LgKg4WLuCzjWgbHGtTTK5o,3190
28
+ fabricatio/_rust.cpython-312-x86_64-linux-gnu.so,sha256=MXQf097U_QTbRfeJjDbsmUt68b-5bXBUmgIIRNuTQ7w,1189720
29
+ fabricatio-0.2.0.dev13.data/scripts/tdown,sha256=Rzx0OwwHeu8DOmxOeyI_3m4EmyU70iWG4oR8NgLmoes,4549888
30
+ fabricatio-0.2.0.dev13.dist-info/RECORD,,