fabricatio 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.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 +24 -18
- fabricatio/config.py +87 -13
- fabricatio/core.py +165 -148
- fabricatio/{logger.py → journal.py} +7 -2
- fabricatio/models/action.py +77 -9
- fabricatio/models/events.py +26 -28
- fabricatio/models/generic.py +208 -119
- fabricatio/models/role.py +22 -7
- fabricatio/models/task.py +220 -0
- fabricatio/models/tool.py +101 -80
- fabricatio/models/utils.py +10 -15
- fabricatio/parser.py +63 -0
- fabricatio/toolboxes/__init__.py +7 -0
- fabricatio/toolboxes/task.py +4 -0
- {fabricatio-0.1.0.dist-info → fabricatio-0.1.1.dist-info}/METADATA +83 -3
- fabricatio-0.1.1.dist-info/RECORD +19 -0
- fabricatio/fs.py +0 -1
- fabricatio-0.1.0.dist-info/RECORD +0 -16
- {fabricatio-0.1.0.dist-info → fabricatio-0.1.1.dist-info}/WHEEL +0 -0
- {fabricatio-0.1.0.dist-info → fabricatio-0.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
"""This module defines the Task class, which represents a task with a status and output.
|
2
|
+
|
3
|
+
It includes methods to manage the task's lifecycle, such as starting, finishing, cancelling, and failing the task.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from asyncio import Queue
|
7
|
+
from enum import Enum
|
8
|
+
from typing import Optional, Self
|
9
|
+
|
10
|
+
from pydantic import Field, PrivateAttr
|
11
|
+
|
12
|
+
from fabricatio.config import configs
|
13
|
+
from fabricatio.core import env
|
14
|
+
from fabricatio.journal import logger
|
15
|
+
from fabricatio.models.generic import WithBriefing
|
16
|
+
|
17
|
+
|
18
|
+
class TaskStatus(Enum):
|
19
|
+
"""Enum that represents the status of a task."""
|
20
|
+
|
21
|
+
Pending = "pending"
|
22
|
+
Running = "running"
|
23
|
+
Finished = "finished"
|
24
|
+
Failed = "failed"
|
25
|
+
Cancelled = "cancelled"
|
26
|
+
|
27
|
+
|
28
|
+
class Task[T](WithBriefing):
|
29
|
+
"""Class that represents a task with a status and output.
|
30
|
+
|
31
|
+
Attributes:
|
32
|
+
name (str): The name of the task.
|
33
|
+
description (str): The description of the task.
|
34
|
+
_output (Queue): The output queue of the task.
|
35
|
+
status (TaskStatus): The status of the task.
|
36
|
+
goal (str): The goal of the task.
|
37
|
+
"""
|
38
|
+
|
39
|
+
name: str = Field(...)
|
40
|
+
"""The name of the task."""
|
41
|
+
description: str = Field(default="")
|
42
|
+
"""The description of the task."""
|
43
|
+
_output: Queue = PrivateAttr(default_factory=lambda: Queue(maxsize=1))
|
44
|
+
status: TaskStatus = Field(default=TaskStatus.Pending)
|
45
|
+
"""The status of the task."""
|
46
|
+
goal: str = Field(default="")
|
47
|
+
"""The goal of the task."""
|
48
|
+
|
49
|
+
@classmethod
|
50
|
+
def simple_task(cls, name: str, goal: str, description: str) -> Self:
|
51
|
+
"""Create a simple task with a name, goal, and description.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
name (str): The name of the task.
|
55
|
+
goal (str): The goal of the task.
|
56
|
+
description (str): The description of the task.
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
Self: A new instance of the Task class.
|
60
|
+
"""
|
61
|
+
return cls(name=name, goal=goal, description=description)
|
62
|
+
|
63
|
+
def update_task(self, goal: Optional[str] = None, description: Optional[str] = None) -> Self:
|
64
|
+
"""Update the goal and description of the task.
|
65
|
+
|
66
|
+
Args:
|
67
|
+
goal (Optional[str]): The new goal of the task.
|
68
|
+
description (Optional[str]): The new description of the task.
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
Self: The updated instance of the Task class.
|
72
|
+
"""
|
73
|
+
if goal:
|
74
|
+
self.goal = goal
|
75
|
+
if description:
|
76
|
+
self.description = description
|
77
|
+
return self
|
78
|
+
|
79
|
+
async def get_output(self) -> T:
|
80
|
+
"""Get the output of the task.
|
81
|
+
|
82
|
+
Returns:
|
83
|
+
T: The output of the task.
|
84
|
+
"""
|
85
|
+
logger.debug(f"Getting output for task {self.name}")
|
86
|
+
return await self._output.get()
|
87
|
+
|
88
|
+
def status_label(self, status: TaskStatus) -> str:
|
89
|
+
"""Return a formatted status label for the task.
|
90
|
+
|
91
|
+
Args:
|
92
|
+
status (TaskStatus): The status of the task.
|
93
|
+
|
94
|
+
Returns:
|
95
|
+
str: The formatted status label.
|
96
|
+
"""
|
97
|
+
return f"{self.name}{configs.pymitter.delimiter}{status.value}"
|
98
|
+
|
99
|
+
@property
|
100
|
+
def pending_label(self) -> str:
|
101
|
+
"""Return the pending status label for the task.
|
102
|
+
|
103
|
+
Returns:
|
104
|
+
str: The pending status label.
|
105
|
+
"""
|
106
|
+
return self.status_label(TaskStatus.Pending)
|
107
|
+
|
108
|
+
@property
|
109
|
+
def running_label(self) -> str:
|
110
|
+
"""Return the running status label for the task.
|
111
|
+
|
112
|
+
Returns:
|
113
|
+
str: The running status label.
|
114
|
+
"""
|
115
|
+
return self.status_label(TaskStatus.Running)
|
116
|
+
|
117
|
+
@property
|
118
|
+
def finished_label(self) -> str:
|
119
|
+
"""Return the finished status label for the task.
|
120
|
+
|
121
|
+
Returns:
|
122
|
+
str: The finished status label.
|
123
|
+
"""
|
124
|
+
return self.status_label(TaskStatus.Finished)
|
125
|
+
|
126
|
+
@property
|
127
|
+
def failed_label(self) -> str:
|
128
|
+
"""Return the failed status label for the task.
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
str: The failed status label.
|
132
|
+
"""
|
133
|
+
return self.status_label(TaskStatus.Failed)
|
134
|
+
|
135
|
+
@property
|
136
|
+
def cancelled_label(self) -> str:
|
137
|
+
"""Return the cancelled status label for the task.
|
138
|
+
|
139
|
+
Returns:
|
140
|
+
str: The cancelled status label.
|
141
|
+
"""
|
142
|
+
return self.status_label(TaskStatus.Cancelled)
|
143
|
+
|
144
|
+
async def finish(self, output: T) -> Self:
|
145
|
+
"""Mark the task as finished and set the output.
|
146
|
+
|
147
|
+
Args:
|
148
|
+
output (T): The output of the task.
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
Self: The finished instance of the Task class.
|
152
|
+
"""
|
153
|
+
logger.info(f"Finishing task {self.name}")
|
154
|
+
self.status = TaskStatus.Finished
|
155
|
+
await self._output.put(output)
|
156
|
+
logger.debug(f"Output set for task {self.name}")
|
157
|
+
await env.emit_async(self.finished_label, self)
|
158
|
+
logger.debug(f"Emitted finished event for task {self.name}")
|
159
|
+
return self
|
160
|
+
|
161
|
+
async def start(self) -> Self:
|
162
|
+
"""Mark the task as running.
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
Self: The running instance of the Task class.
|
166
|
+
"""
|
167
|
+
logger.info(f"Starting task {self.name}")
|
168
|
+
self.status = TaskStatus.Running
|
169
|
+
await env.emit_async(self.running_label, self)
|
170
|
+
return self
|
171
|
+
|
172
|
+
async def cancel(self) -> Self:
|
173
|
+
"""Mark the task as cancelled.
|
174
|
+
|
175
|
+
Returns:
|
176
|
+
Self: The cancelled instance of the Task class.
|
177
|
+
"""
|
178
|
+
self.status = TaskStatus.Cancelled
|
179
|
+
await env.emit_async(self.cancelled_label, self)
|
180
|
+
return self
|
181
|
+
|
182
|
+
async def fail(self) -> Self:
|
183
|
+
"""Mark the task as failed.
|
184
|
+
|
185
|
+
Returns:
|
186
|
+
Self: The failed instance of the Task class.
|
187
|
+
"""
|
188
|
+
logger.error(f"Task {self.name} failed")
|
189
|
+
self.status = TaskStatus.Failed
|
190
|
+
await env.emit_async(self.failed_label, self)
|
191
|
+
return self
|
192
|
+
|
193
|
+
async def publish(self) -> Self:
|
194
|
+
"""Publish the task to the environment.
|
195
|
+
|
196
|
+
Returns:
|
197
|
+
Self: The published instance of the Task class.
|
198
|
+
"""
|
199
|
+
logger.info(f"Publishing task {self.name}")
|
200
|
+
await env.emit_async(self.pending_label, self)
|
201
|
+
return self
|
202
|
+
|
203
|
+
async def delegate(self) -> T:
|
204
|
+
"""Delegate the task to the environment.
|
205
|
+
|
206
|
+
Returns:
|
207
|
+
T: The output of the task.
|
208
|
+
"""
|
209
|
+
logger.info(f"Delegating task {self.name}")
|
210
|
+
await env.emit_async(self.pending_label, self)
|
211
|
+
return await self.get_output()
|
212
|
+
|
213
|
+
@property
|
214
|
+
def briefing(self) -> str:
|
215
|
+
"""Return a briefing of the task including its goal.
|
216
|
+
|
217
|
+
Returns:
|
218
|
+
str: The briefing of the task.
|
219
|
+
"""
|
220
|
+
return f"{super().briefing}\n{self.goal}"
|
fabricatio/models/tool.py
CHANGED
@@ -1,80 +1,101 @@
|
|
1
|
-
from inspect import
|
2
|
-
from typing import Callable, List
|
3
|
-
|
4
|
-
from pydantic import Field
|
5
|
-
|
6
|
-
from fabricatio.models.generic import WithBriefing
|
7
|
-
|
8
|
-
|
9
|
-
class Tool[**P, R](WithBriefing):
|
10
|
-
"""A class representing a tool with a callable source function."""
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
"""
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
Returns:
|
57
|
-
|
58
|
-
"""
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
1
|
+
from inspect import getfullargspec, signature
|
2
|
+
from typing import Any, Callable, List, Self
|
3
|
+
|
4
|
+
from pydantic import Field
|
5
|
+
|
6
|
+
from fabricatio.models.generic import WithBriefing
|
7
|
+
|
8
|
+
|
9
|
+
class Tool[**P, R](WithBriefing):
|
10
|
+
"""A class representing a tool with a callable source function."""
|
11
|
+
|
12
|
+
name: str = Field(default="")
|
13
|
+
"""The name of the tool."""
|
14
|
+
|
15
|
+
description: str = Field(default="")
|
16
|
+
"""The description of the tool."""
|
17
|
+
|
18
|
+
source: Callable[P, R]
|
19
|
+
"""The source function of the tool."""
|
20
|
+
|
21
|
+
def model_post_init(self, __context: Any) -> None:
|
22
|
+
"""Initialize the tool with a name and a source function."""
|
23
|
+
self.name = self.name or self.source.__name__
|
24
|
+
assert self.name, "The tool must have a name."
|
25
|
+
self.description = self.description or self.source.__doc__ or ""
|
26
|
+
|
27
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
|
28
|
+
"""Invoke the tool's source function with the provided arguments."""
|
29
|
+
return self.source(*args, **kwargs)
|
30
|
+
|
31
|
+
@property
|
32
|
+
def briefing(self) -> str:
|
33
|
+
"""Return a brief description of the tool.
|
34
|
+
|
35
|
+
Returns:
|
36
|
+
str: A brief description of the tool.
|
37
|
+
"""
|
38
|
+
source_signature = str(signature(self.source))
|
39
|
+
# 获取源函数的返回类型
|
40
|
+
return_annotation = getfullargspec(self.source).annotations.get("return", "None")
|
41
|
+
return f"{self.name}{source_signature} -> {return_annotation}\n{self.description}"
|
42
|
+
|
43
|
+
|
44
|
+
class ToolBox(WithBriefing):
|
45
|
+
"""A class representing a collection of tools."""
|
46
|
+
|
47
|
+
tools: List[Tool] = Field(default_factory=list)
|
48
|
+
"""A list of tools in the toolbox."""
|
49
|
+
|
50
|
+
def collect_tool[**P, R](self, func: Callable[P, R]) -> Callable[P, R]:
|
51
|
+
"""Add a callable function to the toolbox as a tool.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
func (Callable[P, R]): The function to be added as a tool.
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
Callable[P, R]: The added function.
|
58
|
+
"""
|
59
|
+
self.tools.append(Tool(source=func))
|
60
|
+
return func
|
61
|
+
|
62
|
+
def add_tool[**P, R](self, func: Callable[P, R]) -> Self:
|
63
|
+
"""Add a callable function to the toolbox as a tool.
|
64
|
+
|
65
|
+
Args:
|
66
|
+
func (Callable): The function to be added as a tool.
|
67
|
+
|
68
|
+
Returns:
|
69
|
+
Self: The current instance of the toolbox.
|
70
|
+
"""
|
71
|
+
self.tools.append(Tool(source=func))
|
72
|
+
return self
|
73
|
+
|
74
|
+
@property
|
75
|
+
def briefing(self) -> str:
|
76
|
+
"""Return a brief description of the toolbox.
|
77
|
+
|
78
|
+
Returns:
|
79
|
+
str: A brief description of the toolbox.
|
80
|
+
"""
|
81
|
+
list_out = "\n\n".join([f"- {tool.briefing}" for tool in self.tools])
|
82
|
+
toc = f"## {self.name}: {self.description}\n## {len(self.tools)} tools available:"
|
83
|
+
return f"{toc}\n\n{list_out}"
|
84
|
+
|
85
|
+
def invoke_tool[**P, R](self, name: str, *args: P.args, **kwargs: P.kwargs) -> R:
|
86
|
+
"""Invoke a tool by name with the provided arguments.
|
87
|
+
|
88
|
+
Args:
|
89
|
+
name (str): The name of the tool to invoke.
|
90
|
+
*args (P.args): Positional arguments to pass to the tool.
|
91
|
+
**kwargs (P.kwargs): Keyword arguments to pass to the tool.
|
92
|
+
|
93
|
+
Returns:
|
94
|
+
R: The result of the tool's execution.
|
95
|
+
|
96
|
+
Raises:
|
97
|
+
AssertionError: If no tool with the specified name is found.
|
98
|
+
"""
|
99
|
+
tool = next((tool for tool in self.tools if tool.name == name), None)
|
100
|
+
assert tool, f"No tool named {name} found."
|
101
|
+
return tool(*args, **kwargs)
|
fabricatio/models/utils.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Dict, List, Literal, Self
|
2
2
|
|
3
|
-
from pydantic import BaseModel,
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field
|
4
4
|
|
5
5
|
|
6
6
|
class Message(BaseModel):
|
7
|
+
"""A class representing a message."""
|
8
|
+
|
7
9
|
model_config = ConfigDict(use_attribute_docstrings=True)
|
8
10
|
role: Literal["user", "system", "assistant"] = Field(default="user")
|
9
11
|
"""
|
@@ -16,13 +18,10 @@ class Message(BaseModel):
|
|
16
18
|
|
17
19
|
|
18
20
|
class Messages(list):
|
19
|
-
"""
|
20
|
-
A list of messages.
|
21
|
-
"""
|
21
|
+
"""A list of messages."""
|
22
22
|
|
23
23
|
def add_message(self, role: Literal["user", "system", "assistant"], content: str) -> Self:
|
24
|
-
"""
|
25
|
-
Adds a message to the list with the specified role and content.
|
24
|
+
"""Adds a message to the list with the specified role and content.
|
26
25
|
|
27
26
|
Args:
|
28
27
|
role (Literal["user", "system", "assistant"]): The role of the message sender.
|
@@ -36,8 +35,7 @@ class Messages(list):
|
|
36
35
|
return self
|
37
36
|
|
38
37
|
def add_user_message(self, content: str) -> Self:
|
39
|
-
"""
|
40
|
-
Adds a user message to the list with the specified content.
|
38
|
+
"""Adds a user message to the list with the specified content.
|
41
39
|
|
42
40
|
Args:
|
43
41
|
content (str): The content of the user message.
|
@@ -48,8 +46,7 @@ class Messages(list):
|
|
48
46
|
return self.add_message("user", content)
|
49
47
|
|
50
48
|
def add_system_message(self, content: str) -> Self:
|
51
|
-
"""
|
52
|
-
Adds a system message to the list with the specified content.
|
49
|
+
"""Adds a system message to the list with the specified content.
|
53
50
|
|
54
51
|
Args:
|
55
52
|
content (str): The content of the system message.
|
@@ -60,8 +57,7 @@ class Messages(list):
|
|
60
57
|
return self.add_message("system", content)
|
61
58
|
|
62
59
|
def add_assistant_message(self, content: str) -> Self:
|
63
|
-
"""
|
64
|
-
Adds an assistant message to the list with the specified content.
|
60
|
+
"""Adds an assistant message to the list with the specified content.
|
65
61
|
|
66
62
|
Args:
|
67
63
|
content (str): The content of the assistant message.
|
@@ -72,8 +68,7 @@ class Messages(list):
|
|
72
68
|
return self.add_message("assistant", content)
|
73
69
|
|
74
70
|
def as_list(self) -> List[Dict[str, str]]:
|
75
|
-
"""
|
76
|
-
Converts the messages to a list of dictionaries.
|
71
|
+
"""Converts the messages to a list of dictionaries.
|
77
72
|
|
78
73
|
Returns:
|
79
74
|
list[dict]: A list of dictionaries representing the messages.
|
fabricatio/parser.py
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
from typing import Any, Self, Tuple
|
2
|
+
|
3
|
+
from pydantic import Field, PrivateAttr
|
4
|
+
from regex import Pattern, compile
|
5
|
+
|
6
|
+
from fabricatio.models.generic import Base
|
7
|
+
|
8
|
+
|
9
|
+
class Capture(Base):
|
10
|
+
"""A class to capture patterns in text using regular expressions.
|
11
|
+
|
12
|
+
Attributes:
|
13
|
+
pattern (str): The regular expression pattern to search for.
|
14
|
+
_compiled (Pattern): The compiled regular expression pattern.
|
15
|
+
"""
|
16
|
+
|
17
|
+
target_groups: Tuple[int, ...] = Field(default_factory=tuple)
|
18
|
+
"""The target groups to capture from the pattern."""
|
19
|
+
pattern: str = Field(frozen=True)
|
20
|
+
"""The regular expression pattern to search for."""
|
21
|
+
_compiled: Pattern = PrivateAttr()
|
22
|
+
|
23
|
+
def model_post_init(self, __context: Any) -> None:
|
24
|
+
"""Initialize the compiled regular expression pattern after the model is initialized.
|
25
|
+
|
26
|
+
Args:
|
27
|
+
__context (Any): The context in which the model is initialized.
|
28
|
+
"""
|
29
|
+
self._compiled = compile(self.pattern)
|
30
|
+
|
31
|
+
def capture(self, text: str) -> Tuple[str, ...] | None:
|
32
|
+
"""Capture the first occurrence of the pattern in the given text.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
text (str): The text to search the pattern in.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
str | None: The captured text if the pattern is found, otherwise None.
|
39
|
+
|
40
|
+
"""
|
41
|
+
match = self._compiled.search(text)
|
42
|
+
if match is None:
|
43
|
+
return None
|
44
|
+
|
45
|
+
if self.target_groups:
|
46
|
+
return tuple(match.group(g) for g in self.target_groups)
|
47
|
+
return (match.group(),)
|
48
|
+
|
49
|
+
@classmethod
|
50
|
+
def capture_code_block(cls, language: str) -> Self:
|
51
|
+
"""Capture the first occurrence of a code block in the given text.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
language (str): The text containing the code block.
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
Self: The instance of the class with the captured code block.
|
58
|
+
"""
|
59
|
+
return cls(pattern=f"```{language}\n(.*?)\n```", target_groups=(1,))
|
60
|
+
|
61
|
+
|
62
|
+
JsonCapture = Capture.capture_code_block("json")
|
63
|
+
PythonCapture = Capture.capture_code_block("python")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fabricatio
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.1
|
4
4
|
Summary: A LLM multi-agent framework.
|
5
5
|
Author-email: Whth <zettainspector@foxmail.com>
|
6
6
|
License: MIT License
|
@@ -25,6 +25,7 @@ License: MIT License
|
|
25
25
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26
26
|
SOFTWARE.
|
27
27
|
License-File: LICENSE
|
28
|
+
Keywords: agents,ai,llm,multi-agent
|
28
29
|
Classifier: Framework :: AsyncIO
|
29
30
|
Classifier: Framework :: Pydantic :: 2
|
30
31
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -36,11 +37,90 @@ Requires-Dist: aiohttp>=3.11.11
|
|
36
37
|
Requires-Dist: aiomultiprocess>=0.9.1
|
37
38
|
Requires-Dist: appdirs>=1.4.4
|
38
39
|
Requires-Dist: asyncio>=3.4.3
|
40
|
+
Requires-Dist: gitpython>=3.1.44
|
39
41
|
Requires-Dist: litellm>=1.60.0
|
40
42
|
Requires-Dist: loguru>=0.7.3
|
41
43
|
Requires-Dist: pydantic-settings>=2.7.1
|
42
44
|
Requires-Dist: pydantic>=2.10.6
|
43
45
|
Requires-Dist: pymitter>=1.0.0
|
46
|
+
Requires-Dist: regex>=2024.11.6
|
44
47
|
Requires-Dist: rich>=13.9.4
|
45
|
-
|
46
|
-
|
48
|
+
Requires-Dist: shutilwhich>=1.1.0
|
49
|
+
Description-Content-Type: text/markdown
|
50
|
+
|
51
|
+
## Usage
|
52
|
+
|
53
|
+
### Defining a Task
|
54
|
+
|
55
|
+
```python
|
56
|
+
from fabricatio.models.task import Task
|
57
|
+
|
58
|
+
task = Task(name="say hello", goal="say hello", description="say hello to the world")
|
59
|
+
```
|
60
|
+
|
61
|
+
|
62
|
+
### Creating an Action
|
63
|
+
|
64
|
+
```python
|
65
|
+
from fabricatio import Action, logger
|
66
|
+
from fabricatio.models.task import Task
|
67
|
+
|
68
|
+
class Talk(Action):
|
69
|
+
async def _execute(self, task_input: Task[str], **_) -> Any:
|
70
|
+
ret = "Hello fabricatio!"
|
71
|
+
logger.info("executing talk action")
|
72
|
+
return ret
|
73
|
+
```
|
74
|
+
|
75
|
+
|
76
|
+
### Assigning a Role
|
77
|
+
|
78
|
+
```python
|
79
|
+
from fabricatio.models.role import Role
|
80
|
+
from fabricatio.models.action import WorkFlow
|
81
|
+
|
82
|
+
class TestWorkflow(WorkFlow):
|
83
|
+
pass
|
84
|
+
|
85
|
+
role = Role(name="Test Role", actions=[TestWorkflow()])
|
86
|
+
```
|
87
|
+
|
88
|
+
|
89
|
+
### Logging
|
90
|
+
|
91
|
+
Fabricatio uses Loguru for logging. You can configure the log level and file in the `config.py` file.
|
92
|
+
|
93
|
+
```python
|
94
|
+
from fabricatio.config import DebugConfig
|
95
|
+
|
96
|
+
debug_config = DebugConfig(log_level="DEBUG", log_file="fabricatio.log")
|
97
|
+
```
|
98
|
+
|
99
|
+
|
100
|
+
## Configuration
|
101
|
+
|
102
|
+
Fabricatio uses Pydantic for configuration management. You can define your settings in the `config.py` file.
|
103
|
+
|
104
|
+
```python
|
105
|
+
from fabricatio.config import Settings
|
106
|
+
|
107
|
+
settings = Settings(llm=LLMConfig(api_endpoint="https://api.example.com"))
|
108
|
+
```
|
109
|
+
|
110
|
+
|
111
|
+
## Testing
|
112
|
+
|
113
|
+
Fabricatio includes a set of tests to ensure the framework works as expected. You can run the tests using `pytest`.
|
114
|
+
|
115
|
+
```bash
|
116
|
+
pytest
|
117
|
+
```
|
118
|
+
|
119
|
+
|
120
|
+
## Contributing
|
121
|
+
|
122
|
+
Contributions to Fabricatio are welcome! Please submit a pull request with your changes.
|
123
|
+
|
124
|
+
## License
|
125
|
+
|
126
|
+
Fabricatio is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
fabricatio/__init__.py,sha256=nFPtohqceECRYzU-WlVT6o4oSaKN0vGok-w9JIaiJfs,644
|
2
|
+
fabricatio/config.py,sha256=Y-XPY23p6DrNk9YUMMpu1ECNON-hRUMUDePqeW6Qx0w,6954
|
3
|
+
fabricatio/core.py,sha256=B6KBIfBRF023HF0UUaUprEkQd6sT7G_pexGXQ9btJnE,5788
|
4
|
+
fabricatio/journal.py,sha256=CW9HePtgTiboOyPTExq9GjG5BseZcbc-S6lxDXrpmv0,667
|
5
|
+
fabricatio/parser.py,sha256=Nxrfw-m0DVaI0wIE1b6LK67zXiYbQdXtv8ZqiZd3hbw,2096
|
6
|
+
fabricatio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
fabricatio/models/action.py,sha256=M-12dc-nQiNJU6Y9j-dr4Ef3642vRvzHlzxekBepzaU,3358
|
8
|
+
fabricatio/models/events.py,sha256=0p42QmNDzmC76DhMwW1H_Mlg15MQ_XjEqkCJc8UkIB8,2055
|
9
|
+
fabricatio/models/generic.py,sha256=_1HKN3tdU-SI1uEnMZnAaUFH1_7IvEOfyE0I8JP9TX8,14929
|
10
|
+
fabricatio/models/role.py,sha256=0P8Ys84cHNYk1uhPfkJdIOl8-GiqO5y3gAE2IZX_MbQ,1123
|
11
|
+
fabricatio/models/task.py,sha256=1ZTMktQGuCe7LGWfNFQEL-7M4adoKA_esmZgVS23CnU,6772
|
12
|
+
fabricatio/models/tool.py,sha256=UkEp1Nzbl5wZX21q_Z2VkpiJmVDSdoGDzINQniO8hSY,3536
|
13
|
+
fabricatio/models/utils.py,sha256=2mgXla9_K3dnRrz6hIKzmltTYPmvDk0MBjjEBkCXTdg,2474
|
14
|
+
fabricatio/toolboxes/__init__.py,sha256=bjefmPd7wBaWhbZzdMPXvrjMTeRzlUh_Dev2PUAc124,158
|
15
|
+
fabricatio/toolboxes/task.py,sha256=xgyPetm2R_HlQwpzE8YPnBN7QOYLd0-T8E6QPZG1PPQ,204
|
16
|
+
fabricatio-0.1.1.dist-info/METADATA,sha256=2y5f2Z9wK_sOyKJpLHO6-CBRXZq9Z4JeMKnL7LFafD8,3766
|
17
|
+
fabricatio-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
18
|
+
fabricatio-0.1.1.dist-info/licenses/LICENSE,sha256=do7J7EiCGbq0QPbMAL_FqLYufXpHnCnXBOuqVPwSV8Y,1088
|
19
|
+
fabricatio-0.1.1.dist-info/RECORD,,
|
fabricatio/fs.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
# TODO: fs capabilities impl
|