fabricatio 0.2.3.dev2__cp312-cp312-win_amd64.whl → 0.2.3.dev3__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 +8 -0
- fabricatio/_rust.cp312-win_amd64.pyd +0 -0
- fabricatio/capabilities/rag.py +78 -32
- fabricatio/config.py +3 -0
- fabricatio/models/task.py +8 -8
- {fabricatio-0.2.3.dev2.data → fabricatio-0.2.3.dev3.data}/scripts/tdown.exe +0 -0
- {fabricatio-0.2.3.dev2.dist-info → fabricatio-0.2.3.dev3.dist-info}/METADATA +42 -38
- {fabricatio-0.2.3.dev2.dist-info → fabricatio-0.2.3.dev3.dist-info}/RECORD +10 -10
- {fabricatio-0.2.3.dev2.dist-info → fabricatio-0.2.3.dev3.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.3.dev2.dist-info → fabricatio-0.2.3.dev3.dist-info}/licenses/LICENSE +0 -0
fabricatio/__init__.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
"""Fabricatio is a Python library for building llm app using event-based agent structure."""
|
2
2
|
|
3
|
+
from importlib.util import find_spec
|
4
|
+
|
3
5
|
from fabricatio._rust_instances import template_manager
|
4
6
|
from fabricatio.core import env
|
5
7
|
from fabricatio.fs import magika
|
@@ -35,3 +37,9 @@ __all__ = [
|
|
35
37
|
"task_toolbox",
|
36
38
|
"template_manager",
|
37
39
|
]
|
40
|
+
|
41
|
+
|
42
|
+
if find_spec("pymilvus"):
|
43
|
+
from fabricatio.capabilities.rag import Rag
|
44
|
+
|
45
|
+
__all__ += ["Rag"]
|
Binary file
|
fabricatio/capabilities/rag.py
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
"""A module for the RAG (Retrieval Augmented Generation) model."""
|
2
2
|
|
3
|
+
from functools import lru_cache
|
3
4
|
from operator import itemgetter
|
4
5
|
from os import PathLike
|
5
6
|
from pathlib import Path
|
6
|
-
from typing import Any, Callable, Dict, List, Optional, Self, Union
|
7
|
+
from typing import Any, Callable, Dict, List, Optional, Self, Union, Unpack
|
7
8
|
|
9
|
+
from fabricatio import template_manager
|
8
10
|
from fabricatio.config import configs
|
11
|
+
from fabricatio.models.kwargs_types import LLMKwargs
|
9
12
|
from fabricatio.models.usages import LLMUsage
|
10
13
|
from fabricatio.models.utils import MilvusData
|
11
14
|
from more_itertools.recipes import flatten
|
@@ -14,67 +17,77 @@ try:
|
|
14
17
|
from pymilvus import MilvusClient
|
15
18
|
except ImportError as e:
|
16
19
|
raise RuntimeError("pymilvus is not installed. Have you installed `fabricatio[rag]` instead of `fabricatio`") from e
|
17
|
-
from pydantic import PrivateAttr
|
20
|
+
from pydantic import Field, PrivateAttr
|
21
|
+
|
22
|
+
|
23
|
+
@lru_cache(maxsize=None)
|
24
|
+
def create_client(
|
25
|
+
uri: Optional[str] = None, token: Optional[str] = None, timeout: Optional[float] = None
|
26
|
+
) -> MilvusClient:
|
27
|
+
"""Create a Milvus client."""
|
28
|
+
return MilvusClient(
|
29
|
+
uri=uri or configs.rag.milvus_uri.unicode_string(),
|
30
|
+
token=token or configs.rag.milvus_token.get_secret_value() if configs.rag.milvus_token else "",
|
31
|
+
timeout=timeout or configs.rag.milvus_timeout,
|
32
|
+
)
|
18
33
|
|
19
34
|
|
20
35
|
class Rag(LLMUsage):
|
21
36
|
"""A class representing the RAG (Retrieval Augmented Generation) model."""
|
22
37
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
)
|
30
|
-
|
38
|
+
milvus_uri: Optional[str] = Field(default=None, frozen=True)
|
39
|
+
"""The URI of the Milvus server."""
|
40
|
+
milvus_token: Optional[str] = Field(default=None, frozen=True)
|
41
|
+
"""The token for the Milvus server."""
|
42
|
+
milvus_timeout: Optional[float] = Field(default=None, frozen=True)
|
43
|
+
"""The timeout for the Milvus server."""
|
44
|
+
target_collection: Optional[str] = Field(default=None)
|
45
|
+
"""The name of the collection being viewed."""
|
46
|
+
|
47
|
+
_client: MilvusClient = PrivateAttr(None)
|
48
|
+
"""The Milvus client used for the RAG model."""
|
31
49
|
|
32
50
|
@property
|
33
51
|
def client(self) -> MilvusClient:
|
34
|
-
"""
|
52
|
+
"""Return the Milvus client."""
|
35
53
|
return self._client
|
36
54
|
|
37
|
-
def
|
55
|
+
def model_post_init(self, __context: Any) -> None:
|
56
|
+
"""Initialize the RAG model by creating the collection if it does not exist."""
|
57
|
+
self._client = create_client(self.milvus_uri, self.milvus_token, self.milvus_timeout)
|
58
|
+
self.view(self.target_collection, create=True)
|
59
|
+
|
60
|
+
def view(self, collection_name: Optional[str], create: bool = False) -> Self:
|
38
61
|
"""View the specified collection.
|
39
62
|
|
40
63
|
Args:
|
41
64
|
collection_name (str): The name of the collection.
|
42
65
|
create (bool): Whether to create the collection if it does not exist.
|
43
66
|
"""
|
44
|
-
if create and self._client.has_collection(collection_name):
|
67
|
+
if create and collection_name and not self._client.has_collection(collection_name):
|
45
68
|
self._client.create_collection(collection_name)
|
46
69
|
|
47
|
-
self.
|
70
|
+
self.target_collection = collection_name
|
48
71
|
return self
|
49
72
|
|
50
|
-
def
|
73
|
+
def quit_viewing(self) -> Self:
|
51
74
|
"""Quit the current view.
|
52
75
|
|
53
76
|
Returns:
|
54
77
|
Self: The current instance, allowing for method chaining.
|
55
78
|
"""
|
56
|
-
self.
|
57
|
-
return self
|
58
|
-
|
59
|
-
@property
|
60
|
-
def viewing_collection(self) -> Optional[str]:
|
61
|
-
"""Get the name of the collection being viewed.
|
62
|
-
|
63
|
-
Returns:
|
64
|
-
Optional[str]: The name of the collection being viewed.
|
65
|
-
"""
|
66
|
-
return self._target_collection
|
79
|
+
return self.view(None)
|
67
80
|
|
68
81
|
@property
|
69
|
-
def
|
82
|
+
def safe_target_collection(self) -> str:
|
70
83
|
"""Get the name of the collection being viewed, raise an error if not viewing any collection.
|
71
84
|
|
72
85
|
Returns:
|
73
86
|
str: The name of the collection being viewed.
|
74
87
|
"""
|
75
|
-
if self.
|
88
|
+
if self.target_collection is None:
|
76
89
|
raise RuntimeError("No collection is being viewed. Have you called `self.view()`?")
|
77
|
-
return self.
|
90
|
+
return self.target_collection
|
78
91
|
|
79
92
|
def add_document[D: Union[Dict[str, Any], MilvusData]](
|
80
93
|
self, data: D | List[D], collection_name: Optional[str] = None
|
@@ -92,7 +105,7 @@ class Rag(LLMUsage):
|
|
92
105
|
data = data.prepare_insertion()
|
93
106
|
if isinstance(data, list):
|
94
107
|
data = [d.prepare_insertion() if isinstance(d, MilvusData) else d for d in data]
|
95
|
-
self._client.insert(collection_name or self.
|
108
|
+
self._client.insert(collection_name or self.safe_target_collection, data)
|
96
109
|
return self
|
97
110
|
|
98
111
|
def consume(
|
@@ -109,7 +122,7 @@ class Rag(LLMUsage):
|
|
109
122
|
Self: The current instance, allowing for method chaining.
|
110
123
|
"""
|
111
124
|
data = reader(Path(source))
|
112
|
-
self.add_document(data, collection_name or self.
|
125
|
+
self.add_document(data, collection_name or self.safe_target_collection)
|
113
126
|
return self
|
114
127
|
|
115
128
|
async def afetch_document(
|
@@ -132,7 +145,7 @@ class Rag(LLMUsage):
|
|
132
145
|
"""
|
133
146
|
# Step 1: Search for vectors
|
134
147
|
search_results = self._client.search(
|
135
|
-
collection_name or self.
|
148
|
+
collection_name or self.safe_target_collection,
|
136
149
|
vecs,
|
137
150
|
output_fields=desired_fields if isinstance(desired_fields, list) else [desired_fields],
|
138
151
|
limit=result_per_query,
|
@@ -177,3 +190,36 @@ class Rag(LLMUsage):
|
|
177
190
|
collection_name=collection_name,
|
178
191
|
result_per_query=result_per_query,
|
179
192
|
)[:final_limit]
|
193
|
+
|
194
|
+
async def aask_retrieved(
|
195
|
+
self,
|
196
|
+
question: str | List[str],
|
197
|
+
query: List[str] | str,
|
198
|
+
collection_name: Optional[str] = None,
|
199
|
+
result_per_query: int = 10,
|
200
|
+
final_limit: int = 20,
|
201
|
+
**kwargs: Unpack[LLMKwargs],
|
202
|
+
) -> str:
|
203
|
+
"""Asks a question by retrieving relevant documents based on the provided query.
|
204
|
+
|
205
|
+
This method performs document retrieval using the given query, then asks the
|
206
|
+
specified question using the retrieved documents as context.
|
207
|
+
|
208
|
+
Args:
|
209
|
+
question (str | List[str]): The question or list of questions to be asked.
|
210
|
+
query (List[str] | str): The query or list of queries used for document retrieval.
|
211
|
+
collection_name (Optional[str]): The name of the collection to retrieve documents from.
|
212
|
+
If not provided, the currently viewed collection is used.
|
213
|
+
result_per_query (int): The number of results to return per query. Default is 10.
|
214
|
+
final_limit (int): The maximum number of retrieved documents to consider. Default is 20.
|
215
|
+
**kwargs (Unpack[LLMKwargs]): Additional keyword arguments passed to the underlying `aask` method.
|
216
|
+
|
217
|
+
Returns:
|
218
|
+
str: A string response generated after asking with the context of retrieved documents.
|
219
|
+
"""
|
220
|
+
docs = await self.aretrieve(query, collection_name, result_per_query, final_limit)
|
221
|
+
return await self.aask(
|
222
|
+
question,
|
223
|
+
template_manager.render_template(configs.templates.retrieved_display_template, {"docs": docs}),
|
224
|
+
**kwargs,
|
225
|
+
)
|
fabricatio/config.py
CHANGED
@@ -176,6 +176,9 @@ class TemplateConfig(BaseModel):
|
|
176
176
|
draft_rating_weights_klee_template: str = Field(default="draft_rating_weights_klee")
|
177
177
|
"""The name of the draft rating weights klee template which will be used to draft rating weights with Klee method."""
|
178
178
|
|
179
|
+
retrieved_display_template: str = Field(default="retrieved_display")
|
180
|
+
"""The name of the retrieved display template which will be used to display retrieved documents."""
|
181
|
+
|
179
182
|
|
180
183
|
class MagikaConfig(BaseModel):
|
181
184
|
"""Magika configuration class."""
|
fabricatio/models/task.py
CHANGED
@@ -46,19 +46,19 @@ class Task[T](WithBriefing, WithJsonExample, WithDependency):
|
|
46
46
|
"""
|
47
47
|
|
48
48
|
name: str = Field(...)
|
49
|
-
"""The name of the task, which should be
|
49
|
+
"""The name of the task, which should be concise and descriptive."""
|
50
50
|
|
51
51
|
description: str = Field(default="")
|
52
|
-
"""
|
52
|
+
"""A detailed explanation of the task that includes all necessary information. Should be clear and answer what, why, when, where, who, and how questions."""
|
53
53
|
|
54
|
-
|
55
|
-
"""
|
54
|
+
goals: List[str] = Field(default=[])
|
55
|
+
"""A list of objectives that the task aims to accomplish. Each goal should be clear and specific. Complex tasks should be broken into multiple smaller goals."""
|
56
56
|
|
57
57
|
namespace: List[str] = Field(default_factory=list)
|
58
|
-
"""
|
58
|
+
"""A list of string segments that identify the task's location in the system. If not specified, defaults to an empty list."""
|
59
59
|
|
60
60
|
dependencies: List[str] = Field(default_factory=list)
|
61
|
-
"""A list of file paths
|
61
|
+
"""A list of file paths that are needed (either reading or writing) to complete this task. If not specified, defaults to an empty list."""
|
62
62
|
|
63
63
|
_output: Queue[T | None] = PrivateAttr(default_factory=Queue)
|
64
64
|
"""The output queue of the task."""
|
@@ -113,7 +113,7 @@ class Task[T](WithBriefing, WithJsonExample, WithDependency):
|
|
113
113
|
Returns:
|
114
114
|
Task: A new instance of the `Task` class.
|
115
115
|
"""
|
116
|
-
return cls(name=name,
|
116
|
+
return cls(name=name, goals=goal, description=description)
|
117
117
|
|
118
118
|
def update_task(self, goal: Optional[List[str] | str] = None, description: Optional[str] = None) -> Self:
|
119
119
|
"""Update the goal and description of the task.
|
@@ -126,7 +126,7 @@ class Task[T](WithBriefing, WithJsonExample, WithDependency):
|
|
126
126
|
Task: The updated instance of the `Task` class.
|
127
127
|
"""
|
128
128
|
if goal:
|
129
|
-
self.
|
129
|
+
self.goals = goal if isinstance(goal, list) else [goal]
|
130
130
|
if description:
|
131
131
|
self.description = description
|
132
132
|
return self
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fabricatio
|
3
|
-
Version: 0.2.3.
|
3
|
+
Version: 0.2.3.dev3
|
4
4
|
Classifier: License :: OSI Approved :: MIT License
|
5
5
|
Classifier: Programming Language :: Rust
|
6
6
|
Classifier: Programming Language :: Python :: 3.12
|
@@ -98,32 +98,32 @@ from fabricatio import Action, Role, Task, logger
|
|
98
98
|
|
99
99
|
|
100
100
|
class Hello(Action):
|
101
|
-
|
101
|
+
"""Action that says hello."""
|
102
102
|
|
103
|
-
|
104
|
-
|
103
|
+
name: str = "hello"
|
104
|
+
output_key: str = "task_output"
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
106
|
+
async def _execute(self, task_input: Task[str], **_) -> Any:
|
107
|
+
ret = "Hello fabricatio!"
|
108
|
+
logger.info("executing talk action")
|
109
|
+
return ret
|
110
110
|
|
111
111
|
|
112
112
|
async def main() -> None:
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
113
|
+
"""Main function."""
|
114
|
+
role = Role(
|
115
|
+
name="talker",
|
116
|
+
description="talker role",
|
117
|
+
registry={Task.pending_label: WorkFlow(name="talk", steps=(Hello,))}
|
118
|
+
)
|
119
119
|
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
task = Task(name="say hello", goals="say hello", description="say hello to the world")
|
121
|
+
result = await task.delegate()
|
122
|
+
logger.success(f"Result: {result}")
|
123
123
|
|
124
124
|
|
125
125
|
if __name__ == "__main__":
|
126
|
-
|
126
|
+
asyncio.run(main())
|
127
127
|
```
|
128
128
|
|
129
129
|
#### Writing and Dumping Code
|
@@ -311,17 +311,18 @@ from fabricatio.models.task import Task
|
|
311
311
|
|
312
312
|
toolbox_usage = ToolBoxUsage()
|
313
313
|
|
314
|
+
|
314
315
|
async def handle_security_vulnerabilities():
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
316
|
+
task = Task(
|
317
|
+
name="Security Check",
|
318
|
+
goals=["Identify security vulnerabilities"],
|
319
|
+
description="Perform a thorough security review on the project.",
|
320
|
+
dependencies=["./src/main.py"]
|
321
|
+
)
|
322
|
+
|
323
|
+
vulnerabilities = await toolbox_usage.gather_tools_fine_grind(task)
|
324
|
+
for vulnerability in vulnerabilities:
|
325
|
+
print(f"Found vulnerability: {vulnerability.name}")
|
325
326
|
```
|
326
327
|
|
327
328
|
#### Managing CTF Challenges
|
@@ -334,19 +335,22 @@ from fabricatio.models.task import Task
|
|
334
335
|
|
335
336
|
toolbox_usage = ToolBoxUsage()
|
336
337
|
|
338
|
+
|
337
339
|
async def solve_ctf_challenge(challenge_name: str, challenge_description: str, files: list[str]):
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
340
|
+
task = Task(
|
341
|
+
name=challenge_name,
|
342
|
+
goals=[f"Solve {challenge_name} challenge"],
|
343
|
+
description=challenge_description,
|
344
|
+
dependencies=files
|
345
|
+
)
|
346
|
+
|
347
|
+
solution = await toolbox_usage.gather_tools_fine_grind(task)
|
348
|
+
print(f"Challenge Solved: {solution}")
|
349
|
+
|
347
350
|
|
348
351
|
if __name__ == "__main__":
|
349
|
-
|
352
|
+
asyncio.run(
|
353
|
+
solve_ctf_challenge("Binary Exploitation", "CTF Binary Exploitation Challenge", ["./challenges/binary_exploit"]))
|
350
354
|
```
|
351
355
|
|
352
356
|
### Configuration
|
@@ -1,13 +1,13 @@
|
|
1
|
-
fabricatio-0.2.3.
|
2
|
-
fabricatio-0.2.3.
|
3
|
-
fabricatio-0.2.3.
|
1
|
+
fabricatio-0.2.3.dev3.dist-info/METADATA,sha256=_1gGVl7M89bTO5_yTp9V1Tc9GAAlgcB-QY5q-IhUUUQ,12296
|
2
|
+
fabricatio-0.2.3.dev3.dist-info/WHEEL,sha256=tpW5AN9B-9qsM9WW2FXG2r193YXiqexDadpKp0A2daI,96
|
3
|
+
fabricatio-0.2.3.dev3.dist-info/licenses/LICENSE,sha256=do7J7EiCGbq0QPbMAL_FqLYufXpHnCnXBOuqVPwSV8Y,1088
|
4
4
|
fabricatio/actions/communication.py,sha256=NZxIIncKgJSDyBrqNebUtH_haqtxHa8ld2TZxT3CMdU,429
|
5
5
|
fabricatio/actions/transmission.py,sha256=xpvKqbXqgpi1BWy-vUUvmd8NZ1GhRNfsYUBp-l2jLyk,862
|
6
6
|
fabricatio/actions/__init__.py,sha256=eFmFVPQvtNgFynIXBVr3eP-vWQDWCPng60YY5LXvZgg,115
|
7
|
-
fabricatio/capabilities/rag.py,sha256=
|
7
|
+
fabricatio/capabilities/rag.py,sha256=zUOxpX-MV1HVQ2iSjk2j5jMf0ZqAgqB42DbSBML5KGQ,9484
|
8
8
|
fabricatio/capabilities/rating.py,sha256=zmTUvsUfxFgovRQzy4djL2zKRYTHmN6JY7A4lyT5uVQ,14907
|
9
9
|
fabricatio/capabilities/task.py,sha256=d2xtrwQxXWI40UskQCR5YhHarY7ST0ppr8TjY12uWQE,5327
|
10
|
-
fabricatio/config.py,sha256=
|
10
|
+
fabricatio/config.py,sha256=9ZgPn1GJMgDSGt31Xt6oPD10s2o-ssxbGHBc5PD_drs,12222
|
11
11
|
fabricatio/core.py,sha256=VQ_JKgUGIy2gZ8xsTBZCdr_IP7wC5aPg0_bsOmjQ588,6458
|
12
12
|
fabricatio/decorators.py,sha256=uzsP4tFKQNjDHBkofsjjoJA0IUAaYOtt6YVedoyOqlo,6551
|
13
13
|
fabricatio/fs/curd.py,sha256=faMstgGUiQ4k2AW3OXfvvWWTldTtKXco7QINYaMjmyA,3981
|
@@ -19,7 +19,7 @@ fabricatio/models/events.py,sha256=mrihNEFgQ5o7qFWja1z_qX8dnaTLwPBoJdVlzxQV5oM,2
|
|
19
19
|
fabricatio/models/generic.py,sha256=WEjZ96rTyBjaBjkM6e8E4Pg_Naot4xWRvGJteqBiCCI,5133
|
20
20
|
fabricatio/models/kwargs_types.py,sha256=a-e7rdMZJi8xTBL_RLmTC9OPzI-Js7rlS689PR03VvA,1401
|
21
21
|
fabricatio/models/role.py,sha256=gYvleTeKUGDUNKPAC5B0EPMLC4jZ4vHsFHmHiVXkU6c,1830
|
22
|
-
fabricatio/models/task.py,sha256=
|
22
|
+
fabricatio/models/task.py,sha256=M6jeDFE3jX6cNV9bdOwhjHqgBHI3FKtFLWcmlqhYgcs,11419
|
23
23
|
fabricatio/models/tool.py,sha256=WTFnpF6xZ1nJbmIOonLsGQcM-kkDCeZiAFqyil9xg2U,6988
|
24
24
|
fabricatio/models/usages.py,sha256=bzsTDrAekiQyIwKeWds5YdgsXk8qiZkD7OZdno1Q_Ck,28213
|
25
25
|
fabricatio/models/utils.py,sha256=mXea76bd4r2jy_zx74GM4t5kCvkMu0JTOaw_VGvTCxk,3952
|
@@ -31,7 +31,7 @@ fabricatio/toolboxes/task.py,sha256=kU4a501awIDV7GwNDuSlK3_Ym-5OhCp5sS-insTmUmQ,
|
|
31
31
|
fabricatio/toolboxes/__init__.py,sha256=b13KmASO8q5fBLwew964fn9oH86ER5g-S1PgA4fZ_xs,482
|
32
32
|
fabricatio/_rust.pyi,sha256=0wCqtwWkVxxoqprvk8T27T8QYKIAKHS7xgsmdMNjQKc,1756
|
33
33
|
fabricatio/_rust_instances.py,sha256=dl0-yZ4UvT5g20tQgnPJpmqtkjFGXNG_YK4eLfi_ugQ,279
|
34
|
-
fabricatio/__init__.py,sha256=
|
35
|
-
fabricatio/_rust.cp312-win_amd64.pyd,sha256=
|
36
|
-
fabricatio-0.2.3.
|
37
|
-
fabricatio-0.2.3.
|
34
|
+
fabricatio/__init__.py,sha256=5MAnDTbECGJUBwv2_Hg40zCuWgPVTFR34wzu9EqrwXc,1246
|
35
|
+
fabricatio/_rust.cp312-win_amd64.pyd,sha256=EedusrQbVZW1_gQ8NhTCcyNdhopSOEJOKAxU9hB6AWU,1264128
|
36
|
+
fabricatio-0.2.3.dev3.data/scripts/tdown.exe,sha256=19y_6dFzSkW1wYvplySjLMz6KqUgV6-nZzl2smJkyXQ,3397632
|
37
|
+
fabricatio-0.2.3.dev3.dist-info/RECORD,,
|
File without changes
|
File without changes
|