fabricatio 0.2.7.dev3__cp312-cp312-win_amd64.whl → 0.2.7.dev5__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.
@@ -23,6 +23,7 @@ from pydantic import (
23
23
  PrivateAttr,
24
24
  SecretStr,
25
25
  )
26
+ from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
26
27
 
27
28
 
28
29
  class Base(BaseModel):
@@ -94,7 +95,7 @@ class WithRef[T](Base):
94
95
  """Get the referenced object."""
95
96
  return ok(self._reference, "_reference is None")
96
97
 
97
- def update_ref[S](self: S, reference: T | S) -> S: # noqa: PYI019
98
+ def update_ref[S: "WithRef"](self: S, reference: T | S) -> S: # noqa: PYI019
98
99
  """Update the reference of the object."""
99
100
  if isinstance(reference, self.__class__):
100
101
  self._reference = reference.referenced
@@ -138,6 +139,61 @@ class PersistentAble(Base):
138
139
  return self.model_validate_json(Path(path).read_text(encoding="utf-8"))
139
140
 
140
141
 
142
+ class ModelHash(Base):
143
+ """Class that provides a hash value for the object."""
144
+
145
+ def __hash__(self) -> int:
146
+ """Calculates a hash value for the ArticleBase object based on its model_dump_json representation."""
147
+ return hash(self.model_dump_json())
148
+
149
+
150
+ class UpdateFrom(Base):
151
+ """Class that provides a method to update the object from another object."""
152
+
153
+ def update_pre_check(self, other: Self) -> Self:
154
+ """Pre-check for updating the object from another object."""
155
+ if not isinstance(other, self.__class__):
156
+ raise TypeError(f"Cannot update from a non-{self.__class__.__name__} instance.")
157
+
158
+ return self
159
+
160
+ @abstractmethod
161
+ def update_from_inner(self, other: Self) -> Self:
162
+ """Updates the current instance with the attributes of another instance."""
163
+
164
+ @final
165
+ def update_from(self, other: Self) -> Self:
166
+ """Updates the current instance with the attributes of another instance."""
167
+ return self.update_pre_check(other).update_from_inner(other)
168
+
169
+
170
+ class ResolveUpdateConflict(Base):
171
+ """Class that provides a method to update the object from another object."""
172
+
173
+ @abstractmethod
174
+ def resolve_update_conflict(self, other: Self) -> str:
175
+ """Resolve the update conflict between two objects.
176
+
177
+ Args:
178
+ other (Self): The other object to resolve the update conflict with.
179
+
180
+ Returns:
181
+ str: The resolved update conflict.
182
+ """
183
+
184
+
185
+ class Introspect(Base):
186
+ """Class that provides a method to introspect the object."""
187
+
188
+ @abstractmethod
189
+ def introspect(self) -> str:
190
+ """Internal introspection of the object.
191
+
192
+ Returns:
193
+ str: The internal introspection of the object.
194
+ """
195
+
196
+
141
197
  class WithBriefing(Named, Described):
142
198
  """Class that provides a briefing based on the name and description."""
143
199
 
@@ -172,6 +228,23 @@ class WithBriefing(Named, Described):
172
228
  raise TypeError(f"{system_msg_like} is not a dict or str")
173
229
 
174
230
 
231
+ class ReverseGenerate(GenerateJsonSchema):
232
+ """Class that provides a reverse JSON schema of the model."""
233
+
234
+ def _sort_recursive(self, value: Any, parent_key: str | None = None) -> Any:
235
+ if isinstance(value, dict):
236
+ sorted_dict: dict[str, JsonSchemaValue] = {}
237
+ # Reverse all keys regardless of parent_key
238
+ keys = reversed(value.keys())
239
+ for key in keys:
240
+ sorted_dict[key] = self._sort_recursive(value[key], parent_key=key)
241
+ return sorted_dict
242
+ if isinstance(value, list):
243
+ # Reverse list order and process each item
244
+ return [self._sort_recursive(item, parent_key) for item in reversed(value)]
245
+ return value
246
+
247
+
175
248
  class WithFormatedJsonSchema(Base):
176
249
  """Class that provides a formatted JSON schema of the model."""
177
250
 
@@ -183,8 +256,8 @@ class WithFormatedJsonSchema(Base):
183
256
  str: The JSON schema of the model in a formatted string.
184
257
  """
185
258
  return orjson.dumps(
186
- cls.model_json_schema(),
187
- option=orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS,
259
+ cls.model_json_schema(schema_generator=ReverseGenerate),
260
+ option=orjson.OPT_INDENT_2,
188
261
  ).decode()
189
262
 
190
263
 
@@ -374,7 +447,7 @@ class PrepareVectorization(Base):
374
447
  """
375
448
  max_length = max_length or configs.embedding.max_sequence_length
376
449
  chunk = self._prepare_vectorization_inner()
377
- if len(chunk) > max_length:
450
+ if max_length and len(chunk) > max_length:
378
451
  logger.error(err := f"Chunk exceeds maximum sequence length {max_length}.")
379
452
  raise ValueError(err)
380
453
 
@@ -457,7 +530,7 @@ class ScopedConfig(Base):
457
530
  """Fallback to another instance's attribute values if the current instance's attributes are None.
458
531
 
459
532
  Args:
460
- other (LLMUsage): Another instance from which to copy attribute values.
533
+ other (ScopedConfig): Another instance from which to copy attribute values.
461
534
 
462
535
  Returns:
463
536
  Self: The current instance, allowing for method chaining.
@@ -477,7 +550,7 @@ class ScopedConfig(Base):
477
550
  """Hold to another instance's attribute values if the current instance's attributes are None.
478
551
 
479
552
  Args:
480
- others (LLMUsage | Iterable[LLMUsage]): Another instance or iterable of instances from which to copy attribute values.
553
+ others (Union[ScopedConfig, Iterable[ScopedConfig]]): Another instance or iterable of instances from which to copy attribute values.
481
554
 
482
555
  Returns:
483
556
  Self: The current instance, allowing for method chaining.
@@ -0,0 +1,181 @@
1
+ Metadata-Version: 2.4
2
+ Name: fabricatio
3
+ Version: 0.2.7.dev5
4
+ Classifier: License :: OSI Approved :: MIT License
5
+ Classifier: Programming Language :: Rust
6
+ Classifier: Programming Language :: Python :: 3.12
7
+ Classifier: Programming Language :: Python :: Implementation :: CPython
8
+ Classifier: Framework :: AsyncIO
9
+ Classifier: Framework :: Pydantic :: 2
10
+ Classifier: Typing :: Typed
11
+ Requires-Dist: appdirs>=1.4.4
12
+ Requires-Dist: asyncio>=3.4.3
13
+ Requires-Dist: asyncstdlib>=3.13.0
14
+ Requires-Dist: json-repair>=0.39.1
15
+ Requires-Dist: litellm>=1.60.0
16
+ Requires-Dist: loguru>=0.7.3
17
+ Requires-Dist: magika>=0.5.1
18
+ Requires-Dist: more-itertools>=10.6.0
19
+ Requires-Dist: orjson>=3.10.15
20
+ Requires-Dist: pydantic>=2.10.6
21
+ Requires-Dist: pydantic-settings>=2.7.1
22
+ Requires-Dist: pymitter>=1.0.0
23
+ Requires-Dist: questionary>=2.1.0
24
+ Requires-Dist: regex>=2024.11.6
25
+ Requires-Dist: rich>=13.9.4
26
+ Requires-Dist: pymilvus>=2.5.4 ; extra == 'rag'
27
+ Requires-Dist: fabricatio[calc,plot,rag] ; extra == 'full'
28
+ Requires-Dist: sympy>=1.13.3 ; extra == 'calc'
29
+ Requires-Dist: matplotlib>=3.10.1 ; extra == 'plot'
30
+ Provides-Extra: rag
31
+ Provides-Extra: full
32
+ Provides-Extra: calc
33
+ Provides-Extra: plot
34
+ License-File: LICENSE
35
+ Summary: A LLM multi-agent framework.
36
+ Keywords: ai,agents,multi-agent,llm,pyo3
37
+ Author-email: Whth <zettainspector@foxmail.com>
38
+ Requires-Python: >=3.12, <3.13
39
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
40
+ Project-URL: Homepage, https://github.com/Whth/fabricatio
41
+ Project-URL: Repository, https://github.com/Whth/fabricatio
42
+ Project-URL: Issues, https://github.com/Whth/fabricatio/issues
43
+
44
+ # Fabricatio
45
+
46
+ ![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)
47
+ ![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)
48
+ ![Build Status](https://img.shields.io/badge/build-passing-brightgreen)
49
+
50
+ ## Overview
51
+
52
+ Fabricatio is a streamlined Python library for building LLM applications using an event-based agent structure. It leverages Rust for performance-critical tasks, Handlebars for templating, and PyO3 for Python bindings.
53
+
54
+ ## Features
55
+
56
+ - **Event-Driven Architecture**: Robust task management through an EventEmitter pattern.
57
+ - **LLM Integration & Templating**: Seamlessly interact with large language models and dynamic content generation.
58
+ - **Async & Extensible**: Fully asynchronous execution with easy extension via custom actions and workflows.
59
+
60
+ ## Installation
61
+
62
+ ### Using UV (Recommended)
63
+
64
+ ```bash
65
+ # Install uv if not already installed
66
+ pip install uv
67
+
68
+ # Clone the repository
69
+ git clone https://github.com/Whth/fabricatio.git
70
+ cd fabricatio
71
+
72
+ # Install the package in development mode with uv
73
+ uv --with-editable . maturin develop --uv -r
74
+ ```
75
+
76
+ ### Building Distribution
77
+
78
+ ```bash
79
+ # Build distribution packages
80
+ make bdist
81
+ ```
82
+
83
+ ## Usage
84
+
85
+ ### Basic Example
86
+
87
+ ```python
88
+ import asyncio
89
+ from fabricatio import Action, Role, Task, logger, WorkFlow
90
+ from typing import Any
91
+
92
+ class Hello(Action):
93
+ name: str = "hello"
94
+ output_key: str = "task_output"
95
+
96
+ async def _execute(self, task_input: Task[str], **_) -> Any:
97
+ ret = "Hello fabricatio!"
98
+ logger.info("executing talk action")
99
+ return ret
100
+
101
+ async def main() -> None:
102
+ role = Role(
103
+ name="talker",
104
+ description="talker role",
105
+ registry={Task.pending_label: WorkFlow(name="talk", steps=(Hello,))}
106
+ )
107
+
108
+ task = Task(name="say hello", goals="say hello", description="say hello to the world")
109
+ result = await task.delegate()
110
+ logger.success(f"Result: {result}")
111
+
112
+ if __name__ == "__main__":
113
+ asyncio.run(main())
114
+ ```
115
+
116
+ ### Examples
117
+
118
+ For various usage scenarios, refer to the following examples:
119
+ - Simple Chat
120
+ - Retrieval-Augmented Generation (RAG)
121
+ - Article Extraction
122
+ - Propose Task
123
+ - Code Review
124
+ - Write Outline
125
+
126
+ _(For full example details, please check our detailed documentation, see [Examples](./examples))_
127
+
128
+ ## Configuration
129
+
130
+ The configuration for Fabricatio is managed via environment variables or TOML files. For example:
131
+
132
+ ```toml
133
+ [llm]
134
+ api_endpoint = "https://api.openai.com"
135
+ api_key = "your_openai_api_key"
136
+ timeout = 300
137
+ max_retries = 3
138
+ model = "gpt-3.5-turbo"
139
+ temperature = 1.0
140
+ stop_sign = ["\n\n\n", "User:"]
141
+ top_p = 0.35
142
+ generation_count = 1
143
+ stream = false
144
+ max_tokens = 8192
145
+ ```
146
+
147
+ ## Development Setup
148
+
149
+ 1. **Clone the Repository**:
150
+ ```bash
151
+ git clone https://github.com/Whth/fabricatio.git
152
+ cd fabricatio
153
+ ```
154
+ 2. **Install Dependencies**:
155
+ ```bash
156
+ uv --with-editable . maturin develop --uv -r
157
+ ```
158
+ 3. **Run Tests**:
159
+ ```bash
160
+ make test
161
+ ```
162
+
163
+ ## Contributing
164
+
165
+ Contributions are welcome! Follow these steps:
166
+ 1. Fork the repository.
167
+ 2. Create your feature branch (`git checkout -b feature/new-feature`).
168
+ 3. Commit your changes (`git commit -am 'Add new feature'`).
169
+ 4. Push to the branch (`git push origin feature/new-feature`).
170
+ 5. Create a new Pull Request.
171
+
172
+ ## License
173
+
174
+ Fabricatio is licensed under the MIT License. See [LICENSE](LICENSE) for details.
175
+
176
+ ## Acknowledgments
177
+
178
+ Special thanks to the contributors and maintainers of:
179
+ - [PyO3](https://github.com/PyO3/pyo3)
180
+ - [Maturin](https://github.com/PyO3/maturin)
181
+ - [Handlebars.rs](https://github.com/sunng87/handlebars-rust)
@@ -1,7 +1,7 @@
1
- fabricatio-0.2.7.dev3.dist-info/METADATA,sha256=6O8sm_fbzBC9kYdt9UKzf8ZoXEfFcLGWKHOgJMvC52Q,14236
2
- fabricatio-0.2.7.dev3.dist-info/WHEEL,sha256=jABKVkLC9kJr8mi_er5jOqpiQUjARSLXDUIIxDqsS50,96
3
- fabricatio-0.2.7.dev3.dist-info/licenses/LICENSE,sha256=do7J7EiCGbq0QPbMAL_FqLYufXpHnCnXBOuqVPwSV8Y,1088
4
- fabricatio/actions/article.py,sha256=AgxNKIRLXF9T-TdrhLPE8NWmT8QZXz1QvFnouvuoRBc,7684
1
+ fabricatio-0.2.7.dev5.dist-info/METADATA,sha256=ANxpgCb6nTOneCJ-RdQ7ejNoefGzRdKyfQIvwVfCJiU,5259
2
+ fabricatio-0.2.7.dev5.dist-info/WHEEL,sha256=jABKVkLC9kJr8mi_er5jOqpiQUjARSLXDUIIxDqsS50,96
3
+ fabricatio-0.2.7.dev5.dist-info/licenses/LICENSE,sha256=do7J7EiCGbq0QPbMAL_FqLYufXpHnCnXBOuqVPwSV8Y,1088
4
+ fabricatio/actions/article.py,sha256=cv1pyGOvgMVMaHJqVDKY6h5_u1XtVw3lzJCDFqx4aoc,8073
5
5
  fabricatio/actions/article_rag.py,sha256=PiOFxI6VTmLXm3BK-01g_KH1mTE9uOtnA-CwUjt16AU,1456
6
6
  fabricatio/actions/output.py,sha256=K7xsBH8MjXRH6JOy3ZO94KCQzX2jNrwPPK_rRXVkS0E,1161
7
7
  fabricatio/actions/rag.py,sha256=QBdzEM8MloM_ahx5pTBZAETm9_631lTe_0ih_he_Iuo,2759
@@ -20,11 +20,12 @@ fabricatio/fs/__init__.py,sha256=PCf0s_9KDjVfNw7AfPoJzGt3jMq4gJOfbcT4pb0D0ZY,588
20
20
  fabricatio/journal.py,sha256=stnEP88aUBA_GmU9gfTF2EZI8FS2OyMLGaMSTgK4QgA,476
21
21
  fabricatio/models/action.py,sha256=UlflniS__MMrUXglu_U3PDFAtKEjVsKEix17AT9oP3M,8769
22
22
  fabricatio/models/events.py,sha256=QvlnS8FEELg6KNabcJMeh2GV_y0ZBzKOPphcteKYWYU,4183
23
+ fabricatio/models/extra/article_base.py,sha256=Y4ZdC1yabs7jCNKwc-P8GpAJShGJx7EcLyhXuJ194Fo,11469
23
24
  fabricatio/models/extra/article_essence.py,sha256=DUESuK4CGgkRvIMoJCv4l8MNp5MawRYoNOtLCrFRPXY,9229
24
- fabricatio/models/extra/article_main.py,sha256=F6rhHMICErzvtRIEWdxS5AoY9thLhUUeDofoJbNF9ZI,13984
25
- fabricatio/models/extra/article_outline.py,sha256=0t-aI3OtY1O1_dhwDDm1y4kUdqoh4bmQ8voNe6MDU4w,12452
26
- fabricatio/models/extra/article_proposal.py,sha256=eXtomW88urP9M4aKbVNN9dct0GH-fBwYOM_Rcq3d7j4,1771
27
- fabricatio/models/generic.py,sha256=TXNPGeVOWJnCKJ6KZU8T-SWQ913woX4Xt1BLJ0x4V9M,16820
25
+ fabricatio/models/extra/article_main.py,sha256=l6HO3PajaesEET6Evd2A7OOpHRelGYr4y88JyoPmP3Y,8498
26
+ fabricatio/models/extra/article_outline.py,sha256=VV6RUY7VzKwqCXoykDi-vL2nqHouOuo1Q3hLdCdNDpQ,7740
27
+ fabricatio/models/extra/article_proposal.py,sha256=p0NPzqg9x6t65DZqdF52Z1P0JwP6kwo2_eP-NsXgifU,1720
28
+ fabricatio/models/generic.py,sha256=yEpP4cvvmB0sDbs36pIl2KYFsnNRKq7V0m3HqoSQc7o,19492
28
29
  fabricatio/models/kwargs_types.py,sha256=chJ-rHaeBVRUPuORHuGR3DdNxxTUrotz0eflPEh4l4w,5474
29
30
  fabricatio/models/role.py,sha256=mmQbJ6GKr2Gx3wtjEz8d-vYoXs09ffcEkT_eCXaDd3E,2782
30
31
  fabricatio/models/task.py,sha256=8NaR7ojQWyM740EDTqt9stwHKdrD6axCRpLKo0QzS-I,10492
@@ -41,6 +42,6 @@ fabricatio/workflows/rag.py,sha256=-YYp2tlE9Vtfgpg6ROpu6QVO8j8yVSPa6yDzlN3qVxs,5
41
42
  fabricatio/_rust.pyi,sha256=dGTGV7viu3YAGl1cRKIWrdHPc1hlwk3_hbaDaswxdVo,3831
42
43
  fabricatio/_rust_instances.py,sha256=2GwF8aVfYNemRI2feBzH1CZfBGno-XJJE5imJokGEYw,314
43
44
  fabricatio/__init__.py,sha256=SzBYsRhZeL77jLtfJEjmoHOSwHwUGyvMATX6xfndLDM,1135
44
- fabricatio/_rust.cp312-win_amd64.pyd,sha256=JqLbZHAa0qBcJyWzAWC4Px5MTCxV9VN_BMsfm4saGus,1840128
45
- fabricatio-0.2.7.dev3.data/scripts/tdown.exe,sha256=2sqdWL-XEloL8IsQRQ9wZ_4O0aaLO02jgeb8KWCLgdM,3402752
46
- fabricatio-0.2.7.dev3.dist-info/RECORD,,
45
+ fabricatio/_rust.cp312-win_amd64.pyd,sha256=db4DHfetEQMNh7hqmL6All-asJooQxFIIXZkoWKAx4c,1835008
46
+ fabricatio-0.2.7.dev5.data/scripts/tdown.exe,sha256=xZcDsLIn9rJZcM8iDNgS-eNK4ckH5rufC6mU6I2vmOo,3399680
47
+ fabricatio-0.2.7.dev5.dist-info/RECORD,,