fabricatio 0.3.14.dev0__cp312-cp312-win_amd64.whl → 0.3.14.dev2__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/__init__.py +3 -5
- fabricatio/actions/article.py +31 -31
- fabricatio/actions/article_rag.py +58 -58
- fabricatio/actions/output.py +58 -24
- fabricatio/actions/rag.py +2 -3
- fabricatio/capabilities/advanced_judge.py +4 -7
- fabricatio/capabilities/advanced_rag.py +2 -1
- fabricatio/capabilities/censor.py +5 -4
- fabricatio/capabilities/check.py +27 -27
- fabricatio/capabilities/correct.py +22 -22
- fabricatio/capabilities/extract.py +33 -33
- fabricatio/capabilities/persist.py +103 -0
- fabricatio/capabilities/propose.py +2 -2
- fabricatio/capabilities/rag.py +37 -37
- fabricatio/capabilities/rating.py +66 -70
- fabricatio/capabilities/review.py +12 -11
- fabricatio/capabilities/task.py +19 -18
- fabricatio/decorators.py +9 -9
- fabricatio/{core.py → emitter.py} +17 -19
- fabricatio/journal.py +2 -4
- fabricatio/models/action.py +10 -12
- fabricatio/models/extra/aricle_rag.py +15 -12
- fabricatio/models/extra/article_base.py +4 -5
- fabricatio/models/extra/article_essence.py +2 -1
- fabricatio/models/extra/article_main.py +12 -12
- fabricatio/models/extra/article_outline.py +2 -1
- fabricatio/models/extra/article_proposal.py +1 -1
- fabricatio/models/extra/rag.py +2 -2
- fabricatio/models/extra/rule.py +2 -1
- fabricatio/models/generic.py +53 -136
- fabricatio/models/kwargs_types.py +1 -9
- fabricatio/models/role.py +15 -16
- fabricatio/models/task.py +3 -4
- fabricatio/models/tool.py +4 -4
- fabricatio/models/usages.py +139 -146
- fabricatio/parser.py +59 -99
- fabricatio/rust.cp312-win_amd64.pyd +0 -0
- fabricatio/rust.pyi +40 -60
- fabricatio/utils.py +37 -170
- fabricatio-0.3.14.dev2.data/scripts/tdown.exe +0 -0
- {fabricatio-0.3.14.dev0.data → fabricatio-0.3.14.dev2.data}/scripts/ttm.exe +0 -0
- {fabricatio-0.3.14.dev0.dist-info → fabricatio-0.3.14.dev2.dist-info}/METADATA +7 -7
- fabricatio-0.3.14.dev2.dist-info/RECORD +64 -0
- fabricatio-0.3.14.dev0.data/scripts/tdown.exe +0 -0
- fabricatio-0.3.14.dev0.dist-info/RECORD +0 -63
- {fabricatio-0.3.14.dev0.dist-info → fabricatio-0.3.14.dev2.dist-info}/WHEEL +0 -0
- {fabricatio-0.3.14.dev0.dist-info → fabricatio-0.3.14.dev2.dist-info}/licenses/LICENSE +0 -0
fabricatio/models/role.py
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
"""Module that contains the Role class for managing workflows and their event registrations."""
|
2
|
-
from functools import partial
|
3
|
-
from typing import Any, Self, Dict
|
4
2
|
|
5
|
-
from
|
6
|
-
from
|
3
|
+
from functools import partial
|
4
|
+
from typing import Any, Dict, Self
|
7
5
|
|
8
|
-
from fabricatio.
|
6
|
+
from fabricatio.emitter import env
|
9
7
|
from fabricatio.journal import logger
|
10
8
|
from fabricatio.models.action import WorkFlow
|
11
9
|
from fabricatio.models.generic import WithBriefing
|
10
|
+
from fabricatio.rust import Event
|
12
11
|
from fabricatio.utils import is_subclass_of_base
|
12
|
+
from pydantic import ConfigDict, Field
|
13
13
|
|
14
|
-
is_toolbox_usage = partial(is_subclass_of_base, base_module="fabricatio.models.usages",
|
15
|
-
|
16
|
-
is_scoped_config = partial(is_subclass_of_base, base_module="fabricatio.models.generic",
|
17
|
-
base_name="ScopedConfig")
|
14
|
+
is_toolbox_usage = partial(is_subclass_of_base, base_module="fabricatio.models.usages", base_name="ToolBoxUsage")
|
15
|
+
is_scoped_config = partial(is_subclass_of_base, base_module="fabricatio.models.generic", base_name="ScopedConfig")
|
18
16
|
|
19
17
|
|
20
18
|
class Role(WithBriefing):
|
@@ -23,7 +21,10 @@ class Role(WithBriefing):
|
|
23
21
|
A Role serves as a container for workflows, managing their registration to events
|
24
22
|
and providing them with shared configuration like tools and personality.
|
25
23
|
"""
|
24
|
+
|
26
25
|
model_config = ConfigDict(use_attribute_docstrings=True, arbitrary_types_allowed=True)
|
26
|
+
name: str = ""
|
27
|
+
"""The name of the role."""
|
27
28
|
description: str = ""
|
28
29
|
"""A brief description of the role's responsibilities and capabilities."""
|
29
30
|
|
@@ -36,6 +37,8 @@ class Role(WithBriefing):
|
|
36
37
|
Args:
|
37
38
|
__context: The context used for initialization
|
38
39
|
"""
|
40
|
+
self.name = self.name or self.__class__.__name__
|
41
|
+
|
39
42
|
self.resolve_configuration().register_workflows()
|
40
43
|
|
41
44
|
def register_workflows(self) -> Self:
|
@@ -45,9 +48,7 @@ class Role(WithBriefing):
|
|
45
48
|
Self: The role instance for method chaining
|
46
49
|
"""
|
47
50
|
for event, workflow in self.registry.items():
|
48
|
-
logger.debug(
|
49
|
-
f"Registering workflow: `{workflow.name}` for event: `{event.collapse()}`"
|
50
|
-
)
|
51
|
+
logger.debug(f"Registering workflow: `{workflow.name}` for event: `{event.collapse()}`")
|
51
52
|
env.on(event, workflow.serve)
|
52
53
|
return self
|
53
54
|
|
@@ -67,9 +68,8 @@ class Role(WithBriefing):
|
|
67
68
|
workflow.inject_personality(self.briefing)
|
68
69
|
return self
|
69
70
|
|
70
|
-
def _configure_scoped_config(self, workflow) -> None:
|
71
|
+
def _configure_scoped_config(self, workflow: WorkFlow) -> None:
|
71
72
|
"""Configure scoped configuration for workflow and its actions."""
|
72
|
-
|
73
73
|
if not is_scoped_config(self.__class__):
|
74
74
|
return
|
75
75
|
|
@@ -81,9 +81,8 @@ class Role(WithBriefing):
|
|
81
81
|
for action in (a for a in workflow.iter_actions() if is_scoped_config(a)):
|
82
82
|
action.fallback_to(fallback_target)
|
83
83
|
|
84
|
-
def _configure_toolbox_usage(self, workflow) -> None:
|
84
|
+
def _configure_toolbox_usage(self, workflow: WorkFlow) -> None:
|
85
85
|
"""Configure toolbox usage for workflow and its actions."""
|
86
|
-
|
87
86
|
if not is_toolbox_usage(self.__class__):
|
88
87
|
return
|
89
88
|
|
fabricatio/models/task.py
CHANGED
@@ -6,12 +6,11 @@ It includes methods to manage the task's lifecycle, such as starting, finishing,
|
|
6
6
|
from asyncio import Queue
|
7
7
|
from typing import Any, Dict, List, Optional, Self, Union
|
8
8
|
|
9
|
-
from fabricatio.
|
10
|
-
from pydantic import Field, PrivateAttr
|
11
|
-
|
12
|
-
from fabricatio.core import env
|
9
|
+
from fabricatio.emitter import env
|
13
10
|
from fabricatio.journal import logger
|
14
11
|
from fabricatio.models.generic import ProposedAble, WithBriefing, WithDependency
|
12
|
+
from fabricatio.rust import CONFIG, TEMPLATE_MANAGER, Event, TaskStatus
|
13
|
+
from pydantic import Field, PrivateAttr
|
15
14
|
|
16
15
|
type EventLike = Union[str, Event, List[str]]
|
17
16
|
|
fabricatio/models/tool.py
CHANGED
@@ -10,12 +10,11 @@ from inspect import iscoroutinefunction, signature
|
|
10
10
|
from types import CodeType, ModuleType
|
11
11
|
from typing import Any, Callable, Dict, List, Optional, Self, cast, overload
|
12
12
|
|
13
|
-
from fabricatio.rust import CONFIG
|
14
|
-
from pydantic import BaseModel, ConfigDict, Field
|
15
|
-
|
16
13
|
from fabricatio.decorators import logging_execution_info, use_temp_module
|
17
14
|
from fabricatio.journal import logger
|
18
15
|
from fabricatio.models.generic import WithBriefing
|
16
|
+
from fabricatio.rust import CONFIG
|
17
|
+
from pydantic import BaseModel, ConfigDict, Field
|
19
18
|
|
20
19
|
|
21
20
|
class Tool[**P, R](WithBriefing):
|
@@ -192,6 +191,7 @@ class ToolExecutor(BaseModel):
|
|
192
191
|
candidates (List[Tool]): The sequence of tools to execute.
|
193
192
|
data (Dict[str, Any]): The data that could be used when invoking the tools.
|
194
193
|
"""
|
194
|
+
|
195
195
|
model_config = ConfigDict(use_attribute_docstrings=True)
|
196
196
|
candidates: List[Tool] = Field(default_factory=list, frozen=True)
|
197
197
|
"""The sequence of tools to execute."""
|
@@ -230,7 +230,7 @@ class ToolExecutor(BaseModel):
|
|
230
230
|
M: The module with injected data.
|
231
231
|
"""
|
232
232
|
module = module or cast(
|
233
|
-
|
233
|
+
"M", module_from_spec(spec=ModuleSpec(name=CONFIG.toolbox.data_module_name, loader=None))
|
234
234
|
)
|
235
235
|
for key, value in self.data.items():
|
236
236
|
logger.debug(f"Injecting data: {key}")
|
fabricatio/models/usages.py
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
"""This module contains classes that manage the usage of language models and tools in tasks."""
|
2
2
|
|
3
3
|
import traceback
|
4
|
+
from abc import ABC
|
4
5
|
from asyncio import gather
|
5
6
|
from typing import Callable, Dict, Iterable, List, Literal, Optional, Self, Sequence, Set, Union, Unpack, overload
|
6
7
|
|
7
8
|
import asyncstdlib
|
8
9
|
import litellm
|
10
|
+
from fabricatio.decorators import logging_exec_time
|
11
|
+
from fabricatio.journal import logger
|
12
|
+
from fabricatio.models.generic import ScopedConfig, WithBriefing
|
13
|
+
from fabricatio.models.kwargs_types import ChooseKwargs, EmbeddingKwargs, GenerateKwargs, LLMKwargs, ValidateKwargs
|
14
|
+
from fabricatio.models.task import Task
|
15
|
+
from fabricatio.models.tool import Tool, ToolBox
|
9
16
|
from fabricatio.rust import CONFIG, TEMPLATE_MANAGER
|
17
|
+
from fabricatio.utils import first_available, ok
|
10
18
|
from litellm import RateLimitError, Router, stream_chunk_builder # pyright: ignore [reportPrivateImportUsage]
|
11
19
|
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
12
20
|
from litellm.types.utils import (
|
@@ -20,15 +28,6 @@ from litellm.utils import CustomStreamWrapper, token_counter # pyright: ignore
|
|
20
28
|
from more_itertools import duplicates_everseen
|
21
29
|
from pydantic import BaseModel, ConfigDict, Field, NonNegativeInt, PositiveInt
|
22
30
|
|
23
|
-
from fabricatio.decorators import logging_exec_time
|
24
|
-
from fabricatio.journal import logger
|
25
|
-
from fabricatio.models.generic import ScopedConfig, WithBriefing
|
26
|
-
from fabricatio.models.kwargs_types import ChooseKwargs, EmbeddingKwargs, GenerateKwargs, LLMKwargs, ValidateKwargs
|
27
|
-
from fabricatio.models.task import Task
|
28
|
-
from fabricatio.models.tool import Tool, ToolBox
|
29
|
-
from fabricatio.parser import GenericCapture, JsonCapture
|
30
|
-
from fabricatio.utils import ok
|
31
|
-
|
32
31
|
ROUTER = Router(
|
33
32
|
routing_strategy="usage-based-routing-v2",
|
34
33
|
default_max_parallel_requests=CONFIG.routing.max_parallel_requests,
|
@@ -38,7 +37,7 @@ ROUTER = Router(
|
|
38
37
|
)
|
39
38
|
|
40
39
|
|
41
|
-
class LLMUsage(ScopedConfig):
|
40
|
+
class LLMUsage(ScopedConfig, ABC):
|
42
41
|
"""Class that manages LLM (Large Language Model) usage parameters and methods.
|
43
42
|
|
44
43
|
This class provides methods to deploy LLMs, query them for responses, and handle various configurations
|
@@ -59,10 +58,10 @@ class LLMUsage(ScopedConfig):
|
|
59
58
|
|
60
59
|
# noinspection PyTypeChecker,PydanticTypeChecker,t
|
61
60
|
async def aquery(
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
self,
|
62
|
+
messages: List[Dict[str, str]],
|
63
|
+
n: PositiveInt | None = None,
|
64
|
+
**kwargs: Unpack[LLMKwargs],
|
66
65
|
) -> ModelResponse | CustomStreamWrapper:
|
67
66
|
"""Asynchronously queries the language model to generate a response based on the provided messages and parameters.
|
68
67
|
|
@@ -91,7 +90,7 @@ class LLMUsage(ScopedConfig):
|
|
91
90
|
api_base=ok(
|
92
91
|
self.llm_api_endpoint or CONFIG.llm.api_endpoint,
|
93
92
|
"llm api endpoint is not set at any place",
|
94
|
-
)
|
93
|
+
),
|
95
94
|
model=m_name,
|
96
95
|
tpm=self.llm_tpm or CONFIG.llm.tpm,
|
97
96
|
rpm=self.llm_rpm or CONFIG.llm.rpm,
|
@@ -109,27 +108,27 @@ class LLMUsage(ScopedConfig):
|
|
109
108
|
stop=kwargs.get("stop") or self.llm_stop_sign or CONFIG.llm.stop_sign,
|
110
109
|
top_p=kwargs.get("top_p") or self.llm_top_p or CONFIG.llm.top_p,
|
111
110
|
max_tokens=kwargs.get("max_tokens") or self.llm_max_tokens or CONFIG.llm.max_tokens,
|
112
|
-
stream=
|
111
|
+
stream=first_available(
|
112
|
+
(kwargs.get("stream"), self.llm_stream, CONFIG.llm.stream), "stream is not set at any place"
|
113
|
+
),
|
113
114
|
cache={
|
114
115
|
"no-cache": kwargs.get("no_cache"),
|
115
116
|
"no-store": kwargs.get("no_store"),
|
116
117
|
"cache-ttl": kwargs.get("cache_ttl"),
|
117
118
|
"s-maxage": kwargs.get("s_maxage"),
|
118
119
|
},
|
119
|
-
presence_penalty=kwargs.get("presence_penalty")
|
120
|
-
or self.llm_presence_penalty
|
121
|
-
or CONFIG.llm.presence_penalty,
|
120
|
+
presence_penalty=kwargs.get("presence_penalty") or self.llm_presence_penalty or CONFIG.llm.presence_penalty,
|
122
121
|
frequency_penalty=kwargs.get("frequency_penalty")
|
123
|
-
|
124
|
-
|
122
|
+
or self.llm_frequency_penalty
|
123
|
+
or CONFIG.llm.frequency_penalty,
|
125
124
|
)
|
126
125
|
|
127
126
|
async def ainvoke(
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
127
|
+
self,
|
128
|
+
question: str,
|
129
|
+
system_message: str = "",
|
130
|
+
n: PositiveInt | None = None,
|
131
|
+
**kwargs: Unpack[LLMKwargs],
|
133
132
|
) -> Sequence[TextChoices | Choices | StreamingChoices]:
|
134
133
|
"""Asynchronously invokes the language model with a question and optional system message.
|
135
134
|
|
@@ -149,54 +148,49 @@ class LLMUsage(ScopedConfig):
|
|
149
148
|
)
|
150
149
|
if isinstance(resp, ModelResponse):
|
151
150
|
return resp.choices
|
152
|
-
if isinstance(resp, CustomStreamWrapper):
|
153
|
-
|
154
|
-
return pack.choices
|
151
|
+
if isinstance(resp, CustomStreamWrapper) and (pack := stream_chunk_builder(await asyncstdlib.list(resp))):
|
152
|
+
return pack.choices
|
155
153
|
logger.critical(err := f"Unexpected response type: {type(resp)}")
|
156
154
|
raise ValueError(err)
|
157
155
|
|
158
156
|
@overload
|
159
157
|
async def aask(
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
) -> List[str]:
|
165
|
-
...
|
158
|
+
self,
|
159
|
+
question: List[str],
|
160
|
+
system_message: List[str],
|
161
|
+
**kwargs: Unpack[LLMKwargs],
|
162
|
+
) -> List[str]: ...
|
166
163
|
|
167
164
|
@overload
|
168
165
|
async def aask(
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
) -> List[str]:
|
174
|
-
...
|
166
|
+
self,
|
167
|
+
question: str,
|
168
|
+
system_message: List[str],
|
169
|
+
**kwargs: Unpack[LLMKwargs],
|
170
|
+
) -> List[str]: ...
|
175
171
|
|
176
172
|
@overload
|
177
173
|
async def aask(
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
) -> List[str]:
|
183
|
-
...
|
174
|
+
self,
|
175
|
+
question: List[str],
|
176
|
+
system_message: Optional[str] = None,
|
177
|
+
**kwargs: Unpack[LLMKwargs],
|
178
|
+
) -> List[str]: ...
|
184
179
|
|
185
180
|
@overload
|
186
181
|
async def aask(
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
) -> str:
|
192
|
-
...
|
182
|
+
self,
|
183
|
+
question: str,
|
184
|
+
system_message: Optional[str] = None,
|
185
|
+
**kwargs: Unpack[LLMKwargs],
|
186
|
+
) -> str: ...
|
193
187
|
|
194
188
|
@logging_exec_time
|
195
189
|
async def aask(
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
190
|
+
self,
|
191
|
+
question: str | List[str],
|
192
|
+
system_message: Optional[str | List[str]] = None,
|
193
|
+
**kwargs: Unpack[LLMKwargs],
|
200
194
|
) -> str | List[str]:
|
201
195
|
"""Asynchronously asks the language model a question and returns the response content.
|
202
196
|
|
@@ -224,8 +218,7 @@ class LLMUsage(ScopedConfig):
|
|
224
218
|
res = await gather(*[self.ainvoke(n=1, question=q, system_message=sm, **kwargs) for sm in sm_seq])
|
225
219
|
out = [r[0].message.content for r in res] # pyright: ignore [reportAttributeAccessIssue]
|
226
220
|
case (str(q), str(sm)):
|
227
|
-
out = ((await self.ainvoke(n=1, question=q, system_message=sm, **kwargs))[
|
228
|
-
0]).message.content # pyright: ignore [reportAttributeAccessIssue]
|
221
|
+
out = ((await self.ainvoke(n=1, question=q, system_message=sm, **kwargs))[0]).message.content # pyright: ignore [reportAttributeAccessIssue]
|
229
222
|
case _:
|
230
223
|
raise RuntimeError("Should not reach here.")
|
231
224
|
|
@@ -237,55 +230,51 @@ class LLMUsage(ScopedConfig):
|
|
237
230
|
|
238
231
|
@overload
|
239
232
|
async def aask_validate[T](
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
) -> T:
|
247
|
-
...
|
233
|
+
self,
|
234
|
+
question: str,
|
235
|
+
validator: Callable[[str], T | None],
|
236
|
+
default: T = ...,
|
237
|
+
max_validations: PositiveInt = 2,
|
238
|
+
**kwargs: Unpack[GenerateKwargs],
|
239
|
+
) -> T: ...
|
248
240
|
|
249
241
|
@overload
|
250
242
|
async def aask_validate[T](
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
) -> List[T]:
|
258
|
-
...
|
243
|
+
self,
|
244
|
+
question: List[str],
|
245
|
+
validator: Callable[[str], T | None],
|
246
|
+
default: T = ...,
|
247
|
+
max_validations: PositiveInt = 2,
|
248
|
+
**kwargs: Unpack[GenerateKwargs],
|
249
|
+
) -> List[T]: ...
|
259
250
|
|
260
251
|
@overload
|
261
252
|
async def aask_validate[T](
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
) -> Optional[T]:
|
269
|
-
...
|
253
|
+
self,
|
254
|
+
question: str,
|
255
|
+
validator: Callable[[str], T | None],
|
256
|
+
default: None = None,
|
257
|
+
max_validations: PositiveInt = 2,
|
258
|
+
**kwargs: Unpack[GenerateKwargs],
|
259
|
+
) -> Optional[T]: ...
|
270
260
|
|
271
261
|
@overload
|
272
262
|
async def aask_validate[T](
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
) -> List[Optional[T]]:
|
280
|
-
...
|
263
|
+
self,
|
264
|
+
question: List[str],
|
265
|
+
validator: Callable[[str], T | None],
|
266
|
+
default: None = None,
|
267
|
+
max_validations: PositiveInt = 2,
|
268
|
+
**kwargs: Unpack[GenerateKwargs],
|
269
|
+
) -> List[Optional[T]]: ...
|
281
270
|
|
282
271
|
async def aask_validate[T](
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
272
|
+
self,
|
273
|
+
question: str | List[str],
|
274
|
+
validator: Callable[[str], T | None],
|
275
|
+
default: Optional[T] = None,
|
276
|
+
max_validations: PositiveInt = 3,
|
277
|
+
**kwargs: Unpack[GenerateKwargs],
|
289
278
|
) -> Optional[T] | List[Optional[T]] | List[T] | T:
|
290
279
|
"""Asynchronously asks a question and validates the response using a given validator.
|
291
280
|
|
@@ -325,7 +314,7 @@ class LLMUsage(ScopedConfig):
|
|
325
314
|
return await (gather(*[_inner(q) for q in question]) if isinstance(question, list) else _inner(question))
|
326
315
|
|
327
316
|
async def alist_str(
|
328
|
-
|
317
|
+
self, requirement: str, k: NonNegativeInt = 0, **kwargs: Unpack[ValidateKwargs[List[str]]]
|
329
318
|
) -> Optional[List[str]]:
|
330
319
|
"""Asynchronously generates a list of strings based on a given requirement.
|
331
320
|
|
@@ -337,6 +326,8 @@ class LLMUsage(ScopedConfig):
|
|
337
326
|
Returns:
|
338
327
|
Optional[List[str]]: The validated response as a list of strings.
|
339
328
|
"""
|
329
|
+
from fabricatio.parser import JsonCapture
|
330
|
+
|
340
331
|
return await self.aask_validate(
|
341
332
|
TEMPLATE_MANAGER.render_template(
|
342
333
|
CONFIG.templates.liststr_template,
|
@@ -375,9 +366,9 @@ class LLMUsage(ScopedConfig):
|
|
375
366
|
Optional[str]: The validated response as a single string.
|
376
367
|
"""
|
377
368
|
if paths := await self.apathstr(
|
378
|
-
|
379
|
-
|
380
|
-
|
369
|
+
requirement,
|
370
|
+
k=1,
|
371
|
+
**kwargs,
|
381
372
|
):
|
382
373
|
return paths.pop()
|
383
374
|
|
@@ -393,6 +384,8 @@ class LLMUsage(ScopedConfig):
|
|
393
384
|
Returns:
|
394
385
|
Optional[str]: The generated string.
|
395
386
|
"""
|
387
|
+
from fabricatio.parser import GenericCapture
|
388
|
+
|
396
389
|
return await self.aask_validate( # pyright: ignore [reportReturnType]
|
397
390
|
TEMPLATE_MANAGER.render_template(
|
398
391
|
CONFIG.templates.generic_string_template,
|
@@ -403,11 +396,11 @@ class LLMUsage(ScopedConfig):
|
|
403
396
|
)
|
404
397
|
|
405
398
|
async def achoose[T: WithBriefing](
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
399
|
+
self,
|
400
|
+
instruction: str,
|
401
|
+
choices: List[T],
|
402
|
+
k: NonNegativeInt = 0,
|
403
|
+
**kwargs: Unpack[ValidateKwargs[List[T]]],
|
411
404
|
) -> Optional[List[T]]:
|
412
405
|
"""Asynchronously executes a multi-choice decision-making process, generating a prompt based on the instruction and options, and validates the returned selection results.
|
413
406
|
|
@@ -420,6 +413,8 @@ class LLMUsage(ScopedConfig):
|
|
420
413
|
Returns:
|
421
414
|
Optional[List[T]]: The final validated selection result list, with element types matching the input `choices`.
|
422
415
|
"""
|
416
|
+
from fabricatio.parser import JsonCapture
|
417
|
+
|
423
418
|
if dup := duplicates_everseen(choices, key=lambda x: x.name):
|
424
419
|
logger.error(err := f"Redundant choices: {dup}")
|
425
420
|
raise ValueError(err)
|
@@ -450,10 +445,10 @@ class LLMUsage(ScopedConfig):
|
|
450
445
|
)
|
451
446
|
|
452
447
|
async def apick[T: WithBriefing](
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
448
|
+
self,
|
449
|
+
instruction: str,
|
450
|
+
choices: List[T],
|
451
|
+
**kwargs: Unpack[ValidateKwargs[List[T]]],
|
457
452
|
) -> T:
|
458
453
|
"""Asynchronously picks a single choice from a list of options using AI validation.
|
459
454
|
|
@@ -478,11 +473,11 @@ class LLMUsage(ScopedConfig):
|
|
478
473
|
)[0]
|
479
474
|
|
480
475
|
async def ajudge(
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
476
|
+
self,
|
477
|
+
prompt: str,
|
478
|
+
affirm_case: str = "",
|
479
|
+
deny_case: str = "",
|
480
|
+
**kwargs: Unpack[ValidateKwargs[bool]],
|
486
481
|
) -> Optional[bool]:
|
487
482
|
"""Asynchronously judges a prompt using AI validation.
|
488
483
|
|
@@ -495,6 +490,8 @@ class LLMUsage(ScopedConfig):
|
|
495
490
|
Returns:
|
496
491
|
bool: The judgment result (True or False) based on the AI's response.
|
497
492
|
"""
|
493
|
+
from fabricatio.parser import JsonCapture
|
494
|
+
|
498
495
|
return await self.aask_validate(
|
499
496
|
question=TEMPLATE_MANAGER.render_template(
|
500
497
|
CONFIG.templates.make_judgment_template,
|
@@ -505,19 +502,19 @@ class LLMUsage(ScopedConfig):
|
|
505
502
|
)
|
506
503
|
|
507
504
|
|
508
|
-
class EmbeddingUsage(LLMUsage):
|
505
|
+
class EmbeddingUsage(LLMUsage, ABC):
|
509
506
|
"""A class representing the embedding model.
|
510
507
|
|
511
508
|
This class extends LLMUsage and provides methods to generate embeddings for input text using various models.
|
512
509
|
"""
|
513
510
|
|
514
511
|
async def aembedding(
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
512
|
+
self,
|
513
|
+
input_text: List[str],
|
514
|
+
model: Optional[str] = None,
|
515
|
+
dimensions: Optional[int] = None,
|
516
|
+
timeout: Optional[PositiveInt] = None,
|
517
|
+
caching: Optional[bool] = False,
|
521
518
|
) -> EmbeddingResponse:
|
522
519
|
"""Asynchronously generates embeddings for the given input text.
|
523
520
|
|
@@ -543,10 +540,10 @@ class EmbeddingUsage(LLMUsage):
|
|
543
540
|
dimensions=dimensions or self.embedding_dimensions or CONFIG.embedding.dimensions,
|
544
541
|
model=model or self.embedding_model or CONFIG.embedding.model or self.llm_model or CONFIG.llm.model,
|
545
542
|
timeout=timeout
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
543
|
+
or self.embedding_timeout
|
544
|
+
or CONFIG.embedding.timeout
|
545
|
+
or self.llm_timeout
|
546
|
+
or CONFIG.llm.timeout,
|
550
547
|
api_key=ok(
|
551
548
|
self.embedding_api_key or CONFIG.embedding.api_key or self.llm_api_key or CONFIG.llm.api_key
|
552
549
|
).get_secret_value(),
|
@@ -555,22 +552,18 @@ class EmbeddingUsage(LLMUsage):
|
|
555
552
|
or CONFIG.embedding.api_endpoint
|
556
553
|
or self.llm_api_endpoint
|
557
554
|
or CONFIG.llm.api_endpoint
|
558
|
-
)
|
559
|
-
.unicode_string()
|
560
|
-
.rstrip("/"),
|
555
|
+
).rstrip("/"),
|
561
556
|
# seems embedding function takes no base_url end with a slash
|
562
557
|
)
|
563
558
|
|
564
559
|
@overload
|
565
|
-
async def vectorize(self, input_text: List[str], **kwargs: Unpack[EmbeddingKwargs]) -> List[List[float]]:
|
566
|
-
...
|
560
|
+
async def vectorize(self, input_text: List[str], **kwargs: Unpack[EmbeddingKwargs]) -> List[List[float]]: ...
|
567
561
|
|
568
562
|
@overload
|
569
|
-
async def vectorize(self, input_text: str, **kwargs: Unpack[EmbeddingKwargs]) -> List[float]:
|
570
|
-
...
|
563
|
+
async def vectorize(self, input_text: str, **kwargs: Unpack[EmbeddingKwargs]) -> List[float]: ...
|
571
564
|
|
572
565
|
async def vectorize(
|
573
|
-
|
566
|
+
self, input_text: List[str] | str, **kwargs: Unpack[EmbeddingKwargs]
|
574
567
|
) -> List[List[float]] | List[float]:
|
575
568
|
"""Asynchronously generates vector embeddings for the given input text.
|
576
569
|
|
@@ -587,7 +580,7 @@ class EmbeddingUsage(LLMUsage):
|
|
587
580
|
return [o.get("embedding") for o in (await self.aembedding(input_text, **kwargs)).data]
|
588
581
|
|
589
582
|
|
590
|
-
class ToolBoxUsage(LLMUsage):
|
583
|
+
class ToolBoxUsage(LLMUsage, ABC):
|
591
584
|
"""A class representing the usage of tools in a task.
|
592
585
|
|
593
586
|
This class extends LLMUsage and provides methods to manage and use toolboxes and tools within tasks.
|
@@ -606,9 +599,9 @@ class ToolBoxUsage(LLMUsage):
|
|
606
599
|
return [toolbox.name for toolbox in self.toolboxes]
|
607
600
|
|
608
601
|
async def choose_toolboxes(
|
609
|
-
|
610
|
-
|
611
|
-
|
602
|
+
self,
|
603
|
+
task: Task,
|
604
|
+
**kwargs: Unpack[ChooseKwargs[List[ToolBox]]],
|
612
605
|
) -> Optional[List[ToolBox]]:
|
613
606
|
"""Asynchronously executes a multi-choice decision-making process to choose toolboxes.
|
614
607
|
|
@@ -629,10 +622,10 @@ class ToolBoxUsage(LLMUsage):
|
|
629
622
|
)
|
630
623
|
|
631
624
|
async def choose_tools(
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
625
|
+
self,
|
626
|
+
task: Task,
|
627
|
+
toolbox: ToolBox,
|
628
|
+
**kwargs: Unpack[ChooseKwargs[List[Tool]]],
|
636
629
|
) -> Optional[List[Tool]]:
|
637
630
|
"""Asynchronously executes a multi-choice decision-making process to choose tools.
|
638
631
|
|
@@ -654,10 +647,10 @@ class ToolBoxUsage(LLMUsage):
|
|
654
647
|
)
|
655
648
|
|
656
649
|
async def gather_tools_fine_grind(
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
650
|
+
self,
|
651
|
+
task: Task,
|
652
|
+
box_choose_kwargs: Optional[ChooseKwargs] = None,
|
653
|
+
tool_choose_kwargs: Optional[ChooseKwargs] = None,
|
661
654
|
) -> List[Tool]:
|
662
655
|
"""Asynchronously gathers tools based on the provided task and toolbox and tool selection criteria.
|
663
656
|
|