fabricatio 0.2.5.dev4__cp312-cp312-win_amd64.whl → 0.2.6.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.
- fabricatio/_rust.cp312-win_amd64.pyd +0 -0
- fabricatio/actions/article.py +4 -4
- fabricatio/actions/output.py +1 -3
- fabricatio/actions/rag.py +3 -3
- fabricatio/capabilities/propose.py +14 -20
- fabricatio/capabilities/rag.py +17 -14
- fabricatio/capabilities/rating.py +41 -36
- fabricatio/capabilities/review.py +8 -9
- fabricatio/capabilities/task.py +8 -9
- fabricatio/config.py +30 -4
- fabricatio/fs/readers.py +1 -1
- fabricatio/journal.py +1 -0
- fabricatio/models/action.py +3 -3
- fabricatio/models/events.py +6 -4
- fabricatio/models/extra.py +19 -16
- fabricatio/models/generic.py +41 -6
- fabricatio/models/kwargs_types.py +70 -72
- fabricatio/models/tool.py +4 -4
- fabricatio/models/usages.py +101 -75
- fabricatio/parser.py +26 -5
- {fabricatio-0.2.5.dev4.data → fabricatio-0.2.6.dev0.data}/scripts/tdown.exe +0 -0
- {fabricatio-0.2.5.dev4.dist-info → fabricatio-0.2.6.dev0.dist-info}/METADATA +2 -1
- fabricatio-0.2.6.dev0.dist-info/RECORD +41 -0
- fabricatio-0.2.5.dev4.dist-info/RECORD +0 -41
- {fabricatio-0.2.5.dev4.dist-info → fabricatio-0.2.6.dev0.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.5.dev4.dist-info → fabricatio-0.2.6.dev0.dist-info}/licenses/LICENSE +0 -0
fabricatio/models/usages.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
"""This module contains classes that manage the usage of language models and tools in tasks."""
|
2
2
|
|
3
3
|
from asyncio import gather
|
4
|
-
from typing import Callable, Dict, Iterable, List, Optional, Self, Set, Type, Union, Unpack, overload
|
4
|
+
from typing import Callable, Dict, Iterable, List, Optional, Self, Sequence, Set, Type, Union, Unpack, overload
|
5
5
|
|
6
6
|
import asyncstdlib
|
7
7
|
import litellm
|
@@ -9,34 +9,48 @@ from fabricatio._rust_instances import template_manager
|
|
9
9
|
from fabricatio.config import configs
|
10
10
|
from fabricatio.journal import logger
|
11
11
|
from fabricatio.models.generic import ScopedConfig, WithBriefing
|
12
|
-
from fabricatio.models.kwargs_types import ChooseKwargs, EmbeddingKwargs, GenerateKwargs, LLMKwargs
|
12
|
+
from fabricatio.models.kwargs_types import ChooseKwargs, EmbeddingKwargs, GenerateKwargs, LLMKwargs, ValidateKwargs
|
13
13
|
from fabricatio.models.task import Task
|
14
14
|
from fabricatio.models.tool import Tool, ToolBox
|
15
15
|
from fabricatio.models.utils import Messages
|
16
16
|
from fabricatio.parser import JsonCapture
|
17
|
-
from litellm import stream_chunk_builder
|
17
|
+
from litellm import Router, stream_chunk_builder
|
18
|
+
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
18
19
|
from litellm.types.utils import (
|
19
20
|
Choices,
|
20
21
|
EmbeddingResponse,
|
21
22
|
ModelResponse,
|
22
23
|
StreamingChoices,
|
24
|
+
TextChoices,
|
23
25
|
)
|
24
|
-
from litellm.utils import CustomStreamWrapper
|
26
|
+
from litellm.utils import CustomStreamWrapper # pyright: ignore [reportPrivateImportUsage]
|
25
27
|
from more_itertools import duplicates_everseen
|
26
28
|
from pydantic import Field, NonNegativeInt, PositiveInt
|
27
29
|
|
28
|
-
if configs.cache.enabled:
|
30
|
+
if configs.cache.enabled and configs.cache.type:
|
29
31
|
litellm.enable_cache(type=configs.cache.type, **configs.cache.params)
|
30
32
|
logger.success(f"{configs.cache.type.name} Cache enabled")
|
33
|
+
ROUTER = Router(
|
34
|
+
routing_strategy="usage-based-routing-v2",
|
35
|
+
allowed_fails=configs.routing.allowed_fails,
|
36
|
+
retry_after=configs.routing.retry_after,
|
37
|
+
cooldown_time=configs.routing.cooldown_time,
|
38
|
+
)
|
31
39
|
|
32
40
|
|
33
41
|
class LLMUsage(ScopedConfig):
|
34
42
|
"""Class that manages LLM (Large Language Model) usage parameters and methods."""
|
35
43
|
|
44
|
+
def _deploy(self, deployment: Deployment) -> Router:
|
45
|
+
"""Add a deployment to the router."""
|
46
|
+
self._added_deployment = ROUTER.upsert_deployment(deployment)
|
47
|
+
return ROUTER
|
48
|
+
|
36
49
|
@classmethod
|
37
50
|
def _scoped_model(cls) -> Type["LLMUsage"]:
|
38
51
|
return LLMUsage
|
39
52
|
|
53
|
+
# noinspection PyTypeChecker,PydanticTypeChecker
|
40
54
|
async def aquery(
|
41
55
|
self,
|
42
56
|
messages: List[Dict[str, str]],
|
@@ -54,19 +68,33 @@ class LLMUsage(ScopedConfig):
|
|
54
68
|
ModelResponse | CustomStreamWrapper: An object containing the generated response and other metadata from the model.
|
55
69
|
"""
|
56
70
|
# Call the underlying asynchronous completion function with the provided and default parameters
|
57
|
-
|
71
|
+
# noinspection PyTypeChecker,PydanticTypeChecker
|
72
|
+
|
73
|
+
return await self._deploy(
|
74
|
+
Deployment(
|
75
|
+
model_name=(m_name := kwargs.get("model") or self.llm_model or configs.llm.model),
|
76
|
+
litellm_params=(
|
77
|
+
p := LiteLLM_Params(
|
78
|
+
api_key=(self.llm_api_key or configs.llm.api_key).get_secret_value(),
|
79
|
+
api_base=(self.llm_api_endpoint or configs.llm.api_endpoint).unicode_string(),
|
80
|
+
model=m_name,
|
81
|
+
tpm=self.llm_tpm or configs.llm.tpm,
|
82
|
+
rpm=self.llm_rpm or configs.llm.rpm,
|
83
|
+
max_retries=kwargs.get("max_retries") or self.llm_max_retries or configs.llm.max_retries,
|
84
|
+
timeout=kwargs.get("timeout") or self.llm_timeout or configs.llm.timeout,
|
85
|
+
)
|
86
|
+
),
|
87
|
+
model_info=ModelInfo(id=hash(m_name + p.model_dump_json(exclude_none=True))),
|
88
|
+
)
|
89
|
+
).acompletion(
|
58
90
|
messages=messages,
|
59
91
|
n=n or self.llm_generation_count or configs.llm.generation_count,
|
60
|
-
model=
|
92
|
+
model=m_name,
|
61
93
|
temperature=kwargs.get("temperature") or self.llm_temperature or configs.llm.temperature,
|
62
94
|
stop=kwargs.get("stop") or self.llm_stop_sign or configs.llm.stop_sign,
|
63
95
|
top_p=kwargs.get("top_p") or self.llm_top_p or configs.llm.top_p,
|
64
96
|
max_tokens=kwargs.get("max_tokens") or self.llm_max_tokens or configs.llm.max_tokens,
|
65
97
|
stream=kwargs.get("stream") or self.llm_stream or configs.llm.stream,
|
66
|
-
timeout=kwargs.get("timeout") or self.llm_timeout or configs.llm.timeout,
|
67
|
-
max_retries=kwargs.get("max_retries") or self.llm_max_retries or configs.llm.max_retries,
|
68
|
-
api_key=(self.llm_api_key or configs.llm.api_key).get_secret_value(),
|
69
|
-
base_url=(self.llm_api_endpoint or configs.llm.api_endpoint).unicode_string(),
|
70
98
|
cache={
|
71
99
|
"no-cache": kwargs.get("no_cache"),
|
72
100
|
"no-store": kwargs.get("no_store"),
|
@@ -81,7 +109,7 @@ class LLMUsage(ScopedConfig):
|
|
81
109
|
system_message: str = "",
|
82
110
|
n: PositiveInt | None = None,
|
83
111
|
**kwargs: Unpack[LLMKwargs],
|
84
|
-
) ->
|
112
|
+
) -> Sequence[TextChoices | Choices | StreamingChoices]:
|
85
113
|
"""Asynchronously invokes the language model with a question and optional system message.
|
86
114
|
|
87
115
|
Args:
|
@@ -101,13 +129,14 @@ class LLMUsage(ScopedConfig):
|
|
101
129
|
if isinstance(resp, ModelResponse):
|
102
130
|
return resp.choices
|
103
131
|
if isinstance(resp, CustomStreamWrapper):
|
104
|
-
if not configs.debug.streaming_visible:
|
105
|
-
return
|
132
|
+
if not configs.debug.streaming_visible and (pack := stream_chunk_builder(await asyncstdlib.list())):
|
133
|
+
return pack.choices
|
106
134
|
chunks = []
|
107
135
|
async for chunk in resp:
|
108
136
|
chunks.append(chunk)
|
109
137
|
print(chunk.choices[0].delta.content or "", end="") # noqa: T201
|
110
|
-
|
138
|
+
if pack := stream_chunk_builder(chunks):
|
139
|
+
return pack.choices
|
111
140
|
logger.critical(err := f"Unexpected response type: {type(resp)}")
|
112
141
|
raise ValueError(err)
|
113
142
|
|
@@ -166,15 +195,15 @@ class LLMUsage(ScopedConfig):
|
|
166
195
|
for q, sm in zip(q_seq, sm_seq, strict=True)
|
167
196
|
]
|
168
197
|
)
|
169
|
-
return [r.
|
198
|
+
return [r[0].message.content for r in res]
|
170
199
|
case (list(q_seq), str(sm)):
|
171
200
|
res = await gather(*[self.ainvoke(n=1, question=q, system_message=sm, **kwargs) for q in q_seq])
|
172
|
-
return [r.
|
201
|
+
return [r[0].message.content for r in res]
|
173
202
|
case (str(q), list(sm_seq)):
|
174
203
|
res = await gather(*[self.ainvoke(n=1, question=q, system_message=sm, **kwargs) for sm in sm_seq])
|
175
|
-
return [r.
|
204
|
+
return [r[0].message.content for r in res]
|
176
205
|
case (str(q), str(sm)):
|
177
|
-
return ((await self.ainvoke(n=1, question=q, system_message=sm, **kwargs))
|
206
|
+
return ((await self.ainvoke(n=1, question=q, system_message=sm, **kwargs))[0]).message.content
|
178
207
|
case _:
|
179
208
|
raise RuntimeError("Should not reach here.")
|
180
209
|
|
@@ -185,29 +214,45 @@ class LLMUsage(ScopedConfig):
|
|
185
214
|
validator: Callable[[str], T | None],
|
186
215
|
default: T,
|
187
216
|
max_validations: PositiveInt = 2,
|
188
|
-
|
189
|
-
**kwargs: Unpack[LLMKwargs],
|
217
|
+
**kwargs: Unpack[GenerateKwargs],
|
190
218
|
) -> T: ...
|
191
219
|
@overload
|
220
|
+
async def aask_validate[T](
|
221
|
+
self,
|
222
|
+
question: List[str],
|
223
|
+
validator: Callable[[str], T | None],
|
224
|
+
default: T,
|
225
|
+
max_validations: PositiveInt = 2,
|
226
|
+
**kwargs: Unpack[GenerateKwargs],
|
227
|
+
) -> List[T]: ...
|
228
|
+
@overload
|
192
229
|
async def aask_validate[T](
|
193
230
|
self,
|
194
231
|
question: str,
|
195
232
|
validator: Callable[[str], T | None],
|
196
233
|
default: None = None,
|
197
234
|
max_validations: PositiveInt = 2,
|
198
|
-
|
199
|
-
**kwargs: Unpack[LLMKwargs],
|
235
|
+
**kwargs: Unpack[GenerateKwargs],
|
200
236
|
) -> Optional[T]: ...
|
201
237
|
|
238
|
+
@overload
|
202
239
|
async def aask_validate[T](
|
203
240
|
self,
|
204
|
-
question: str,
|
241
|
+
question: List[str],
|
242
|
+
validator: Callable[[str], T | None],
|
243
|
+
default: None = None,
|
244
|
+
max_validations: PositiveInt = 2,
|
245
|
+
**kwargs: Unpack[GenerateKwargs],
|
246
|
+
) -> List[Optional[T]]: ...
|
247
|
+
|
248
|
+
async def aask_validate[T](
|
249
|
+
self,
|
250
|
+
question: str | List[str],
|
205
251
|
validator: Callable[[str], T | None],
|
206
252
|
default: Optional[T] = None,
|
207
253
|
max_validations: PositiveInt = 2,
|
208
|
-
|
209
|
-
|
210
|
-
) -> Optional[T]:
|
254
|
+
**kwargs: Unpack[GenerateKwargs],
|
255
|
+
) -> Optional[T] | List[Optional[T]] | List[T] | T:
|
211
256
|
"""Asynchronously asks a question and validates the response using a given validator.
|
212
257
|
|
213
258
|
Args:
|
@@ -215,59 +260,42 @@ class LLMUsage(ScopedConfig):
|
|
215
260
|
validator (Callable[[str], T | None]): A function to validate the response.
|
216
261
|
default (T | None): Default value to return if validation fails. Defaults to None.
|
217
262
|
max_validations (PositiveInt): Maximum number of validation attempts. Defaults to 2.
|
218
|
-
system_message (str): System message to include in the request. Defaults to an empty string.
|
219
263
|
**kwargs (Unpack[LLMKwargs]): Additional keyword arguments for the LLM usage.
|
220
264
|
|
221
265
|
Returns:
|
222
266
|
T: The validated response.
|
223
267
|
|
224
268
|
"""
|
225
|
-
for i in range(max_validations):
|
226
|
-
if (
|
227
|
-
response := await self.aask(
|
228
|
-
question=question,
|
229
|
-
system_message=system_message,
|
230
|
-
**kwargs,
|
231
|
-
)
|
232
|
-
) and (validated := validator(response)):
|
233
|
-
logger.debug(f"Successfully validated the response at {i}th attempt.")
|
234
|
-
return validated
|
235
|
-
kwargs["no_cache"] = True
|
236
|
-
logger.debug("Closed the cache for the next attempt")
|
237
|
-
if default is None:
|
238
|
-
logger.error(f"Failed to validate the response after {max_validations} attempts.")
|
239
|
-
return default
|
240
|
-
|
241
|
-
async def aask_validate_batch[T](
|
242
|
-
self,
|
243
|
-
questions: List[str],
|
244
|
-
validator: Callable[[str], T | None],
|
245
|
-
**kwargs: Unpack[GenerateKwargs[T]],
|
246
|
-
) -> List[T]:
|
247
|
-
"""Asynchronously asks a batch of questions and validates the responses using a given validator.
|
248
269
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
270
|
+
async def _inner(q: str) -> Optional[T]:
|
271
|
+
for lap in range(max_validations):
|
272
|
+
try:
|
273
|
+
if (response := await self.aask(question=q, **kwargs)) and (validated := validator(response)):
|
274
|
+
logger.debug(f"Successfully validated the response at {lap}th attempt.")
|
275
|
+
return validated
|
276
|
+
except Exception as e: # noqa: BLE001
|
277
|
+
logger.error(f"Error during validation: \n{e}")
|
278
|
+
break
|
279
|
+
kwargs["no_cache"] = True
|
280
|
+
logger.debug("Closed the cache for the next attempt")
|
281
|
+
if default is None:
|
282
|
+
logger.error(f"Failed to validate the response after {max_validations} attempts.")
|
283
|
+
return default
|
284
|
+
|
285
|
+
if isinstance(question, str):
|
286
|
+
return await _inner(question)
|
287
|
+
|
288
|
+
return await gather(*[_inner(q) for q in question])
|
261
289
|
|
262
290
|
async def aliststr(
|
263
|
-
self, requirement: str, k: NonNegativeInt = 0, **kwargs: Unpack[
|
291
|
+
self, requirement: str, k: NonNegativeInt = 0, **kwargs: Unpack[ValidateKwargs[List[str]]]
|
264
292
|
) -> List[str]:
|
265
293
|
"""Asynchronously generates a list of strings based on a given requirement.
|
266
294
|
|
267
295
|
Args:
|
268
296
|
requirement (str): The requirement for the list of strings.
|
269
297
|
k (NonNegativeInt): The number of choices to select, 0 means infinite. Defaults to 0.
|
270
|
-
**kwargs (Unpack[
|
298
|
+
**kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
|
271
299
|
|
272
300
|
Returns:
|
273
301
|
List[str]: The validated response as a list of strings.
|
@@ -299,12 +327,12 @@ class LLMUsage(ScopedConfig):
|
|
299
327
|
**kwargs,
|
300
328
|
)
|
301
329
|
|
302
|
-
async def awhich_pathstr(self, requirement: str, **kwargs: Unpack[
|
330
|
+
async def awhich_pathstr(self, requirement: str, **kwargs: Unpack[ValidateKwargs[List[str]]]) -> str:
|
303
331
|
"""Asynchronously generates a single path string based on a given requirement.
|
304
332
|
|
305
333
|
Args:
|
306
334
|
requirement (str): The requirement for the list of strings.
|
307
|
-
**kwargs (Unpack[
|
335
|
+
**kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
|
308
336
|
|
309
337
|
Returns:
|
310
338
|
str: The validated response as a single string.
|
@@ -322,7 +350,7 @@ class LLMUsage(ScopedConfig):
|
|
322
350
|
instruction: str,
|
323
351
|
choices: List[T],
|
324
352
|
k: NonNegativeInt = 0,
|
325
|
-
**kwargs: Unpack[
|
353
|
+
**kwargs: Unpack[ValidateKwargs[List[T]]],
|
326
354
|
) -> List[T]:
|
327
355
|
"""Asynchronously executes a multi-choice decision-making process, generating a prompt based on the instruction and options, and validates the returned selection results.
|
328
356
|
|
@@ -330,7 +358,7 @@ class LLMUsage(ScopedConfig):
|
|
330
358
|
instruction (str): The user-provided instruction/question description.
|
331
359
|
choices (List[T]): A list of candidate options, requiring elements to have `name` and `briefing` fields.
|
332
360
|
k (NonNegativeInt): The number of choices to select, 0 means infinite. Defaults to 0.
|
333
|
-
**kwargs (Unpack[
|
361
|
+
**kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
|
334
362
|
|
335
363
|
Returns:
|
336
364
|
List[T]: The final validated selection result list, with element types matching the input `choices`.
|
@@ -373,14 +401,14 @@ class LLMUsage(ScopedConfig):
|
|
373
401
|
self,
|
374
402
|
instruction: str,
|
375
403
|
choices: List[T],
|
376
|
-
**kwargs: Unpack[
|
404
|
+
**kwargs: Unpack[ValidateKwargs[List[T]]],
|
377
405
|
) -> T:
|
378
406
|
"""Asynchronously picks a single choice from a list of options using AI validation.
|
379
407
|
|
380
408
|
Args:
|
381
409
|
instruction (str): The user-provided instruction/question description.
|
382
410
|
choices (List[T]): A list of candidate options, requiring elements to have `name` and `briefing` fields.
|
383
|
-
**kwargs (Unpack[
|
411
|
+
**kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
|
384
412
|
|
385
413
|
Returns:
|
386
414
|
T: The single selected item from the choices list.
|
@@ -402,7 +430,7 @@ class LLMUsage(ScopedConfig):
|
|
402
430
|
prompt: str,
|
403
431
|
affirm_case: str = "",
|
404
432
|
deny_case: str = "",
|
405
|
-
**kwargs: Unpack[
|
433
|
+
**kwargs: Unpack[ValidateKwargs[bool]],
|
406
434
|
) -> bool:
|
407
435
|
"""Asynchronously judges a prompt using AI validation.
|
408
436
|
|
@@ -410,7 +438,7 @@ class LLMUsage(ScopedConfig):
|
|
410
438
|
prompt (str): The input prompt to be judged.
|
411
439
|
affirm_case (str): The affirmative case for the AI model. Defaults to an empty string.
|
412
440
|
deny_case (str): The negative case for the AI model. Defaults to an empty string.
|
413
|
-
**kwargs (Unpack[
|
441
|
+
**kwargs (Unpack[ValidateKwargs]): Additional keyword arguments for the LLM usage.
|
414
442
|
|
415
443
|
Returns:
|
416
444
|
bool: The judgment result (True or False) based on the AI's response.
|
@@ -516,7 +544,6 @@ class ToolBoxUsage(LLMUsage):
|
|
516
544
|
async def choose_toolboxes(
|
517
545
|
self,
|
518
546
|
task: Task,
|
519
|
-
system_message: str = "",
|
520
547
|
**kwargs: Unpack[ChooseKwargs[List[ToolBox]]],
|
521
548
|
) -> List[ToolBox]:
|
522
549
|
"""Asynchronously executes a multi-choice decision-making process to choose toolboxes.
|
@@ -535,7 +562,6 @@ class ToolBoxUsage(LLMUsage):
|
|
535
562
|
return await self.achoose(
|
536
563
|
instruction=task.briefing,
|
537
564
|
choices=list(self.toolboxes),
|
538
|
-
system_message=system_message,
|
539
565
|
**kwargs,
|
540
566
|
)
|
541
567
|
|
fabricatio/parser.py
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
"""A module to parse text using regular expressions."""
|
2
2
|
|
3
|
-
from typing import Any, Callable, Optional, Self, Tuple, Type
|
3
|
+
from typing import Any, Callable, Iterable, List, Optional, Self, Tuple, Type
|
4
4
|
|
5
5
|
import orjson
|
6
6
|
import regex
|
7
|
+
from json_repair import repair_json
|
7
8
|
from pydantic import BaseModel, ConfigDict, Field, PositiveInt, PrivateAttr, ValidationError
|
8
9
|
from regex import Pattern, compile
|
9
10
|
|
11
|
+
from fabricatio.config import configs
|
10
12
|
from fabricatio.journal import logger
|
11
13
|
|
12
14
|
|
@@ -25,12 +27,31 @@ class Capture(BaseModel):
|
|
25
27
|
"""The regular expression pattern to search for."""
|
26
28
|
flags: PositiveInt = Field(default=regex.DOTALL | regex.MULTILINE | regex.IGNORECASE, frozen=True)
|
27
29
|
"""The flags to use when compiling the regular expression pattern."""
|
30
|
+
capture_type: Optional[str] = None
|
31
|
+
"""The type of capture to perform, e.g., 'json', which is used to dispatch the fixer accordingly."""
|
28
32
|
_compiled: Pattern = PrivateAttr()
|
29
33
|
|
30
34
|
def model_post_init(self, __context: Any) -> None:
|
31
35
|
"""Initialize the compiled pattern."""
|
32
36
|
self._compiled = compile(self.pattern, self.flags)
|
33
37
|
|
38
|
+
def fix[T](self, text: str | Iterable[str]|T) -> str | List[str]|T:
|
39
|
+
"""Fix the text using the pattern.
|
40
|
+
|
41
|
+
Args:
|
42
|
+
text (str | List[str]): The text to fix.
|
43
|
+
|
44
|
+
Returns:
|
45
|
+
str | List[str]: The fixed text with the same type as input.
|
46
|
+
"""
|
47
|
+
match self.capture_type:
|
48
|
+
case "json":
|
49
|
+
if isinstance(text, str):
|
50
|
+
return repair_json(text,ensure_ascii=False)
|
51
|
+
return [repair_json(item) for item in text]
|
52
|
+
case _:
|
53
|
+
return text
|
54
|
+
|
34
55
|
def capture(self, text: str) -> Tuple[str, ...] | str | None:
|
35
56
|
"""Capture the first occurrence of the pattern in the given text.
|
36
57
|
|
@@ -44,12 +65,12 @@ class Capture(BaseModel):
|
|
44
65
|
match = self._compiled.search(text)
|
45
66
|
if match is None:
|
46
67
|
return None
|
47
|
-
|
68
|
+
groups = self.fix(match.groups()) if configs.general.use_json_repair else match.groups()
|
48
69
|
if self.target_groups:
|
49
|
-
cap = tuple(
|
70
|
+
cap = tuple(groups[g - 1] for g in self.target_groups)
|
50
71
|
logger.debug(f"Captured text: {'\n\n'.join(cap)}")
|
51
72
|
return cap
|
52
|
-
cap =
|
73
|
+
cap = groups[0]
|
53
74
|
logger.debug(f"Captured text: \n{cap}")
|
54
75
|
return cap
|
55
76
|
|
@@ -111,7 +132,7 @@ class Capture(BaseModel):
|
|
111
132
|
Returns:
|
112
133
|
Self: The instance of the class with the captured code block.
|
113
134
|
"""
|
114
|
-
return cls(pattern=f"```{language}\n(.*?)\n```")
|
135
|
+
return cls(pattern=f"```{language}\n(.*?)\n```", capture_type=language)
|
115
136
|
|
116
137
|
|
117
138
|
JsonCapture = Capture.capture_code_block("json")
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fabricatio
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.6.dev0
|
4
4
|
Classifier: License :: OSI Approved :: MIT License
|
5
5
|
Classifier: Programming Language :: Rust
|
6
6
|
Classifier: Programming Language :: Python :: 3.12
|
@@ -11,6 +11,7 @@ Classifier: Typing :: Typed
|
|
11
11
|
Requires-Dist: appdirs>=1.4.4
|
12
12
|
Requires-Dist: asyncio>=3.4.3
|
13
13
|
Requires-Dist: asyncstdlib>=3.13.0
|
14
|
+
Requires-Dist: json-repair>=0.39.1
|
14
15
|
Requires-Dist: litellm>=1.60.0
|
15
16
|
Requires-Dist: loguru>=0.7.3
|
16
17
|
Requires-Dist: magika>=0.5.1
|
@@ -0,0 +1,41 @@
|
|
1
|
+
fabricatio-0.2.6.dev0.dist-info/METADATA,sha256=0rCWeinWl5uI8bzZhMeRORs5dJ8sWa5z5zpoy3Lnj6A,8896
|
2
|
+
fabricatio-0.2.6.dev0.dist-info/WHEEL,sha256=tpW5AN9B-9qsM9WW2FXG2r193YXiqexDadpKp0A2daI,96
|
3
|
+
fabricatio-0.2.6.dev0.dist-info/licenses/LICENSE,sha256=do7J7EiCGbq0QPbMAL_FqLYufXpHnCnXBOuqVPwSV8Y,1088
|
4
|
+
fabricatio/actions/article.py,sha256=yzRwgc203vI3MW_oWyFybDxTz6kaBBvUgN2zOJJ9Amc,2825
|
5
|
+
fabricatio/actions/output.py,sha256=KSSLvEvXsA10ACN2mbqGo98QwKLVUAoMUJNKYk6HhGc,645
|
6
|
+
fabricatio/actions/rag.py,sha256=GpT7YlqOYznZyaT-6Y84_33HtZGT-5s71ZK8iroQA9g,813
|
7
|
+
fabricatio/capabilities/propose.py,sha256=y3kge5g6bb8HYuV8e9h4MdqOMTlsfAIZpqE_cagWPTY,1593
|
8
|
+
fabricatio/capabilities/rag.py,sha256=YYaabej-f6a7gBRbJRcJ_Fj89BloNCw0sHOPqs_W8Bk,15773
|
9
|
+
fabricatio/capabilities/rating.py,sha256=0Xrfp_AW9u2ltHnZXxz3Pt3fr8fMsO0QiFadegh49IU,14406
|
10
|
+
fabricatio/capabilities/review.py,sha256=4FbM8dO-JSPnu22I1lykM9y1gzBtXI5Wj33KtzvULWU,9757
|
11
|
+
fabricatio/capabilities/task.py,sha256=hvyZtgkBdrZmuxGqTe-ZkGp2LjymPNE1RK7Y-ztDb7M,4607
|
12
|
+
fabricatio/config.py,sha256=rh8OkGwvuM0-bkZGqhVjMt7-hpdD-rz3Ai7OucrbbWY,15784
|
13
|
+
fabricatio/core.py,sha256=VQ_JKgUGIy2gZ8xsTBZCdr_IP7wC5aPg0_bsOmjQ588,6458
|
14
|
+
fabricatio/decorators.py,sha256=uzsP4tFKQNjDHBkofsjjoJA0IUAaYOtt6YVedoyOqlo,6551
|
15
|
+
fabricatio/fs/curd.py,sha256=N6l2MncjrFfnXBRtteRouXp5Rjy8EAKC_i29_G-zz98,4618
|
16
|
+
fabricatio/fs/readers.py,sha256=RNWx4T2XXigeprJOxw8YjHfyGlrCtB5MVz01Gw9lvw4,1202
|
17
|
+
fabricatio/fs/__init__.py,sha256=uk4yIlz43Yl2mQZ5QuoMstg0DaIQV9h6XXxU4SbdWpY,588
|
18
|
+
fabricatio/journal.py,sha256=pCpIFk-IOsDmCcjx1fOsWDDxjkeAGYgu2OrFnuItwcA,801
|
19
|
+
fabricatio/models/action.py,sha256=onNzHqb7QaqAQ9dtVKf85DWHiJaGeK9gORi_pT7B5Wc,6445
|
20
|
+
fabricatio/models/events.py,sha256=QvlnS8FEELg6KNabcJMeh2GV_y0ZBzKOPphcteKYWYU,4183
|
21
|
+
fabricatio/models/extra.py,sha256=O8ncZVsaNmlR5f8c_b2HJc-yVZQ2YhB6ddDbfT0Ysh4,7412
|
22
|
+
fabricatio/models/generic.py,sha256=LnXmwdZ8Rjx_lanWOz0T1NsBsFRXfXqubYNzsCvLEH0,13808
|
23
|
+
fabricatio/models/kwargs_types.py,sha256=RKD_EXMlz4vuVpGzB9y5qDotSHNOKjk6R0EI4BoNaCg,4282
|
24
|
+
fabricatio/models/role.py,sha256=M9JVDmLLvJhY3G0hHMdcs1ywJ0eoAb6CLYbzhv-l_8s,1839
|
25
|
+
fabricatio/models/task.py,sha256=sbC0EAZC4rPL2GCJ9i9GlFcZUJ96g39SQ2QP8bbgdqs,10492
|
26
|
+
fabricatio/models/tool.py,sha256=4b-v4WIC_LuLOKzzXL9bvKXr8vmGZ8O2uAFv5-1KRA0,7052
|
27
|
+
fabricatio/models/usages.py,sha256=dpMIIoYGRyer97sSP2sQVpihLl2C3REtUMDVZum0DQw,27825
|
28
|
+
fabricatio/models/utils.py,sha256=QI3bYrKBbzLbKvyzVrZXGcWq3trOOTE-hQAC_WNvjMg,4457
|
29
|
+
fabricatio/parser.py,sha256=pwYAoLbWYXtABcnV3s5GdBM0Ngczq-r7n0jKSnpdAxE,5838
|
30
|
+
fabricatio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
31
|
+
fabricatio/toolboxes/arithmetic.py,sha256=WLqhY-Pikv11Y_0SGajwZx3WhsLNpHKf9drzAqOf_nY,1369
|
32
|
+
fabricatio/toolboxes/fs.py,sha256=l4L1CVxJmjw9Ld2XUpIlWfV0_Fu_2Og6d3E13I-S4aE,736
|
33
|
+
fabricatio/toolboxes/__init__.py,sha256=KBJi5OG_pExscdlM7Bnt_UF43j4I3Lv6G71kPVu4KQU,395
|
34
|
+
fabricatio/workflows/articles.py,sha256=RebdC_BzSXC-xsck5I9ccC_XIgfhtoeM8FZuhtVDn3U,580
|
35
|
+
fabricatio/workflows/rag.py,sha256=-YYp2tlE9Vtfgpg6ROpu6QVO8j8yVSPa6yDzlN3qVxs,520
|
36
|
+
fabricatio/_rust.pyi,sha256=pI747rOciunGuQZDvfC3O0A6pLyOiaHSa3A5kHuQO0E,3169
|
37
|
+
fabricatio/_rust_instances.py,sha256=RybIzB2kCoMeU_1kMm2JTz1ka8i524hAra66joDf--s,314
|
38
|
+
fabricatio/__init__.py,sha256=22KLRAVoJZUrK7gsDjU1NfiLCnZtV-qgx6TO2YMbuH8,1930
|
39
|
+
fabricatio/_rust.cp312-win_amd64.pyd,sha256=AhBvJkNL2zAztAgKdFMhVjnek1VBtetgCX3CCusrM-4,1815552
|
40
|
+
fabricatio-0.2.6.dev0.data/scripts/tdown.exe,sha256=FfiaaE9jKm61UyaQHNF7u-QJc8JQhi9btQjn1ySnQ28,3395072
|
41
|
+
fabricatio-0.2.6.dev0.dist-info/RECORD,,
|
@@ -1,41 +0,0 @@
|
|
1
|
-
fabricatio-0.2.5.dev4.dist-info/METADATA,sha256=qH-LvoH22Lf4rR2kk29GsYDKpDq1PLuD9m1HCet01rk,8861
|
2
|
-
fabricatio-0.2.5.dev4.dist-info/WHEEL,sha256=tpW5AN9B-9qsM9WW2FXG2r193YXiqexDadpKp0A2daI,96
|
3
|
-
fabricatio-0.2.5.dev4.dist-info/licenses/LICENSE,sha256=do7J7EiCGbq0QPbMAL_FqLYufXpHnCnXBOuqVPwSV8Y,1088
|
4
|
-
fabricatio/actions/article.py,sha256=PFO7QJw0SXryReA2kGJgd35NeIxCodpudNQxlXNg8xA,2785
|
5
|
-
fabricatio/actions/output.py,sha256=RWXulsfN_qrCFik0B6lGwXf6MMtgK3CaF1ENbK0l85o,684
|
6
|
-
fabricatio/actions/rag.py,sha256=lZfw9SZ8oxbWPK_bvWsEpVkWJbGP8HUnlNbxLh11Wdg,821
|
7
|
-
fabricatio/capabilities/propose.py,sha256=Vs0kvs_F_MJiT0ySlIIbskyr4yFFpJgOCXM4GZpKtiA,1778
|
8
|
-
fabricatio/capabilities/rag.py,sha256=AQTtFPDluTByl5NXYZZIvAw2qFKpnulzxL7fmStJD0w,15547
|
9
|
-
fabricatio/capabilities/rating.py,sha256=6EjMEBFghGAhKGtRe3UiusY3ytsGN_n2ZvHCwPa-910,14378
|
10
|
-
fabricatio/capabilities/review.py,sha256=DgqlMqqZ3UCAd-YRRFV9iFnSDz4m1auy9iuiSjXC4EU,9705
|
11
|
-
fabricatio/capabilities/task.py,sha256=s6FiC9Wg_l-qSa2LgsoKV9f6wXZN6Q_FlWn3XbSnrys,4618
|
12
|
-
fabricatio/config.py,sha256=N-H3eny1NSBmgtCNmSPaasIf4j4qya-bzYFTut80Q2E,14787
|
13
|
-
fabricatio/core.py,sha256=VQ_JKgUGIy2gZ8xsTBZCdr_IP7wC5aPg0_bsOmjQ588,6458
|
14
|
-
fabricatio/decorators.py,sha256=uzsP4tFKQNjDHBkofsjjoJA0IUAaYOtt6YVedoyOqlo,6551
|
15
|
-
fabricatio/fs/curd.py,sha256=N6l2MncjrFfnXBRtteRouXp5Rjy8EAKC_i29_G-zz98,4618
|
16
|
-
fabricatio/fs/readers.py,sha256=Jw3NQ1AFMy_tZvGomTSu37kMojUoDeaZQS91w-xbNX0,1214
|
17
|
-
fabricatio/fs/__init__.py,sha256=uk4yIlz43Yl2mQZ5QuoMstg0DaIQV9h6XXxU4SbdWpY,588
|
18
|
-
fabricatio/journal.py,sha256=2yo6R7aUq2czV7PgKM5owLvbZdimHMSxUYCMvI7Kp4M,779
|
19
|
-
fabricatio/models/action.py,sha256=XT7u3fDw7EdN___qsbUGGdhj8-RnNEpqbLbmST8SC-g,6443
|
20
|
-
fabricatio/models/events.py,sha256=pt-WkFhhA5SXmp6-3Vb_o_7I5xbKoTCJ22GAK7YYwpA,4101
|
21
|
-
fabricatio/models/extra.py,sha256=1vmtnE0n15ZSRVKmPmtChA34y0y-G07uTywXek_oGzs,7463
|
22
|
-
fabricatio/models/generic.py,sha256=wzFoZIUDrrk1eXEpjw2a-T48c9_dB7KTVUnYuMDstKo,12560
|
23
|
-
fabricatio/models/kwargs_types.py,sha256=8OvlMzK5glmzCX1lA0a-2lunT_W6oIhHRR0KZtjSdHY,5017
|
24
|
-
fabricatio/models/role.py,sha256=M9JVDmLLvJhY3G0hHMdcs1ywJ0eoAb6CLYbzhv-l_8s,1839
|
25
|
-
fabricatio/models/task.py,sha256=sbC0EAZC4rPL2GCJ9i9GlFcZUJ96g39SQ2QP8bbgdqs,10492
|
26
|
-
fabricatio/models/tool.py,sha256=JdpldDqlXZ0TZc9eh6IrdHB3FAldEPxsSxeSm4naJhA,7025
|
27
|
-
fabricatio/models/usages.py,sha256=u-MfB2B-oJp6rBnV8nN04O24evyzCkB_G5EAEHdBf6U,26779
|
28
|
-
fabricatio/models/utils.py,sha256=QI3bYrKBbzLbKvyzVrZXGcWq3trOOTE-hQAC_WNvjMg,4457
|
29
|
-
fabricatio/parser.py,sha256=qNYshYtuwbZHZG1kQKYYHZOzYhDO4DZJJYh2k4Imz3s,4911
|
30
|
-
fabricatio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
31
|
-
fabricatio/toolboxes/arithmetic.py,sha256=WLqhY-Pikv11Y_0SGajwZx3WhsLNpHKf9drzAqOf_nY,1369
|
32
|
-
fabricatio/toolboxes/fs.py,sha256=l4L1CVxJmjw9Ld2XUpIlWfV0_Fu_2Og6d3E13I-S4aE,736
|
33
|
-
fabricatio/toolboxes/__init__.py,sha256=KBJi5OG_pExscdlM7Bnt_UF43j4I3Lv6G71kPVu4KQU,395
|
34
|
-
fabricatio/workflows/articles.py,sha256=RebdC_BzSXC-xsck5I9ccC_XIgfhtoeM8FZuhtVDn3U,580
|
35
|
-
fabricatio/workflows/rag.py,sha256=-YYp2tlE9Vtfgpg6ROpu6QVO8j8yVSPa6yDzlN3qVxs,520
|
36
|
-
fabricatio/_rust.pyi,sha256=pI747rOciunGuQZDvfC3O0A6pLyOiaHSa3A5kHuQO0E,3169
|
37
|
-
fabricatio/_rust_instances.py,sha256=RybIzB2kCoMeU_1kMm2JTz1ka8i524hAra66joDf--s,314
|
38
|
-
fabricatio/__init__.py,sha256=22KLRAVoJZUrK7gsDjU1NfiLCnZtV-qgx6TO2YMbuH8,1930
|
39
|
-
fabricatio/_rust.cp312-win_amd64.pyd,sha256=tDlqCUS34WV9cNuXnd6OMsJGHuptnodQY3WAROnPF6o,1816064
|
40
|
-
fabricatio-0.2.5.dev4.data/scripts/tdown.exe,sha256=TUHa62i_6gpAYxQ1qImUl3araoORpKEAOscXPRF-DjQ,3395072
|
41
|
-
fabricatio-0.2.5.dev4.dist-info/RECORD,,
|
File without changes
|
File without changes
|