fabricatio 0.2.7.dev4__cp312-cp312-win_amd64.whl → 0.2.8__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 +4 -11
- fabricatio/actions/article.py +226 -92
- fabricatio/actions/article_rag.py +86 -21
- fabricatio/actions/output.py +71 -3
- fabricatio/actions/rag.py +3 -3
- fabricatio/actions/rules.py +39 -0
- fabricatio/capabilities/advanced_judge.py +23 -0
- fabricatio/capabilities/censor.py +90 -0
- fabricatio/capabilities/check.py +195 -0
- fabricatio/capabilities/correct.py +160 -96
- fabricatio/capabilities/propose.py +20 -4
- fabricatio/capabilities/rag.py +5 -4
- fabricatio/capabilities/rating.py +68 -23
- fabricatio/capabilities/review.py +21 -190
- fabricatio/capabilities/task.py +9 -10
- fabricatio/config.py +11 -3
- fabricatio/fs/curd.py +4 -0
- fabricatio/models/action.py +24 -10
- fabricatio/models/adv_kwargs_types.py +25 -0
- fabricatio/models/extra/__init__.py +1 -0
- fabricatio/models/extra/advanced_judge.py +32 -0
- fabricatio/models/extra/article_base.py +324 -89
- fabricatio/models/extra/article_essence.py +49 -176
- fabricatio/models/extra/article_main.py +48 -127
- fabricatio/models/extra/article_outline.py +12 -152
- fabricatio/models/extra/article_proposal.py +29 -13
- fabricatio/models/extra/patches.py +7 -0
- fabricatio/models/extra/problem.py +153 -0
- fabricatio/models/extra/rule.py +65 -0
- fabricatio/models/generic.py +360 -88
- fabricatio/models/kwargs_types.py +23 -17
- fabricatio/models/role.py +4 -1
- fabricatio/models/task.py +1 -1
- fabricatio/models/tool.py +149 -14
- fabricatio/models/usages.py +61 -47
- fabricatio/models/utils.py +0 -46
- fabricatio/parser.py +7 -8
- fabricatio/rust.cp312-win_amd64.pyd +0 -0
- fabricatio/{_rust.pyi → rust.pyi} +50 -0
- fabricatio/{_rust_instances.py → rust_instances.py} +1 -1
- fabricatio/utils.py +54 -0
- fabricatio-0.2.8.data/scripts/tdown.exe +0 -0
- {fabricatio-0.2.7.dev4.dist-info → fabricatio-0.2.8.dist-info}/METADATA +2 -1
- fabricatio-0.2.8.dist-info/RECORD +58 -0
- fabricatio/_rust.cp312-win_amd64.pyd +0 -0
- fabricatio-0.2.7.dev4.data/scripts/tdown.exe +0 -0
- fabricatio-0.2.7.dev4.dist-info/RECORD +0 -47
- {fabricatio-0.2.7.dev4.dist-info → fabricatio-0.2.8.dist-info}/WHEEL +0 -0
- {fabricatio-0.2.7.dev4.dist-info → fabricatio-0.2.8.dist-info}/licenses/LICENSE +0 -0
fabricatio/models/generic.py
CHANGED
@@ -1,17 +1,20 @@
|
|
1
|
-
"""This module defines generic classes for models in the Fabricatio library."""
|
1
|
+
"""This module defines generic classes for models in the Fabricatio library, providing a foundation for various model functionalities."""
|
2
2
|
|
3
|
-
from abc import abstractmethod
|
3
|
+
from abc import ABC, abstractmethod
|
4
|
+
from datetime import datetime
|
4
5
|
from pathlib import Path
|
5
6
|
from typing import Any, Callable, Dict, Iterable, List, Optional, Self, Union, final, overload
|
6
7
|
|
7
8
|
import orjson
|
8
|
-
|
9
|
-
from fabricatio._rust_instances import TEMPLATE_MANAGER
|
9
|
+
import rtoml
|
10
10
|
from fabricatio.config import configs
|
11
11
|
from fabricatio.fs.readers import MAGIKA, safe_text_read
|
12
12
|
from fabricatio.journal import logger
|
13
|
-
from fabricatio.models.utils import ok
|
14
13
|
from fabricatio.parser import JsonCapture
|
14
|
+
from fabricatio.rust import blake3_hash
|
15
|
+
from fabricatio.rust_instances import TEMPLATE_MANAGER
|
16
|
+
from fabricatio.utils import ok
|
17
|
+
from litellm.utils import token_counter
|
15
18
|
from pydantic import (
|
16
19
|
BaseModel,
|
17
20
|
ConfigDict,
|
@@ -27,13 +30,19 @@ from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
|
|
27
30
|
|
28
31
|
|
29
32
|
class Base(BaseModel):
|
30
|
-
"""Base class for all models with Pydantic configuration.
|
33
|
+
"""Base class for all models with Pydantic configuration.
|
34
|
+
|
35
|
+
This class sets up the basic Pydantic configuration for all models in the Fabricatio library.
|
36
|
+
"""
|
31
37
|
|
32
38
|
model_config = ConfigDict(use_attribute_docstrings=True)
|
33
39
|
|
34
40
|
|
35
41
|
class Display(Base):
|
36
|
-
"""Class that provides a method to display the model in a formatted JSON string.
|
42
|
+
"""Class that provides a method to display the model in a formatted JSON string.
|
43
|
+
|
44
|
+
This class includes methods to display the model in both formatted and compact JSON strings.
|
45
|
+
"""
|
37
46
|
|
38
47
|
def display(self) -> str:
|
39
48
|
"""Display the model in a formatted JSON string.
|
@@ -51,23 +60,45 @@ class Display(Base):
|
|
51
60
|
"""
|
52
61
|
return self.model_dump_json()
|
53
62
|
|
63
|
+
@staticmethod
|
64
|
+
def seq_display(seq: Iterable["Display"], compact: bool = False) -> str:
|
65
|
+
"""Display a sequence of Display objects in a formatted JSON string.
|
66
|
+
|
67
|
+
Args:
|
68
|
+
seq (Iterable[Display]): The sequence of Display objects to display.
|
69
|
+
compact (bool): Whether to display the sequence in a compact format. Defaults to False.
|
70
|
+
|
71
|
+
Returns:
|
72
|
+
str: The formatted JSON string of the sequence.
|
73
|
+
"""
|
74
|
+
return "\n".join(d.compact() if compact else d.display() for d in seq)
|
75
|
+
|
54
76
|
|
55
77
|
class Named(Base):
|
56
|
-
"""Class that includes a name attribute.
|
78
|
+
"""Class that includes a name attribute.
|
57
79
|
|
58
|
-
name
|
80
|
+
This class adds a name attribute to models, which is intended to be a unique identifier.
|
81
|
+
"""
|
82
|
+
|
83
|
+
name: str
|
59
84
|
"""The name of the object."""
|
60
85
|
|
61
86
|
|
62
87
|
class Described(Base):
|
63
|
-
"""Class that includes a description attribute.
|
88
|
+
"""Class that includes a description attribute.
|
89
|
+
|
90
|
+
This class adds a description attribute to models, providing additional context or information.
|
91
|
+
"""
|
64
92
|
|
65
|
-
description: str
|
93
|
+
description: str
|
66
94
|
"""The description of the object."""
|
67
95
|
|
68
96
|
|
69
97
|
class AsPrompt(Base):
|
70
|
-
"""Class that provides a method to generate a prompt from the model.
|
98
|
+
"""Class that provides a method to generate a prompt from the model.
|
99
|
+
|
100
|
+
This class includes a method to generate a prompt based on the model's attributes.
|
101
|
+
"""
|
71
102
|
|
72
103
|
@final
|
73
104
|
def as_prompt(self) -> str:
|
@@ -82,33 +113,81 @@ class AsPrompt(Base):
|
|
82
113
|
)
|
83
114
|
|
84
115
|
@abstractmethod
|
85
|
-
def _as_prompt_inner(self) -> Dict[str, str]:
|
116
|
+
def _as_prompt_inner(self) -> Dict[str, str]:
|
117
|
+
"""Generate the inner part of the prompt.
|
118
|
+
|
119
|
+
This method should be implemented by subclasses to provide the specific data for the prompt.
|
120
|
+
|
121
|
+
Returns:
|
122
|
+
Dict[str, str]: The data for the prompt.
|
123
|
+
"""
|
86
124
|
|
87
125
|
|
88
126
|
class WithRef[T](Base):
|
89
|
-
"""Class that provides a reference to another object.
|
127
|
+
"""Class that provides a reference to another object.
|
128
|
+
|
129
|
+
This class manages a reference to another object, allowing for easy access and updates.
|
130
|
+
"""
|
90
131
|
|
91
132
|
_reference: Optional[T] = PrivateAttr(None)
|
92
133
|
|
93
134
|
@property
|
94
135
|
def referenced(self) -> T:
|
95
|
-
"""Get the referenced object.
|
96
|
-
|
136
|
+
"""Get the referenced object.
|
137
|
+
|
138
|
+
Returns:
|
139
|
+
T: The referenced object.
|
97
140
|
|
98
|
-
|
99
|
-
|
141
|
+
Raises:
|
142
|
+
ValueError: If the reference is not set.
|
143
|
+
"""
|
144
|
+
return ok(
|
145
|
+
self._reference, f"`{self.__class__.__name__}`'s `_reference` field is None. Have you called `update_ref`?"
|
146
|
+
)
|
147
|
+
|
148
|
+
@overload
|
149
|
+
def update_ref[S: WithRef](self: S, reference: T) -> S: ...
|
150
|
+
@overload
|
151
|
+
def update_ref[S: WithRef](self: S, reference: "WithRef[T]") -> S: ...
|
152
|
+
@overload
|
153
|
+
def update_ref[S: WithRef](self: S, reference: None = None) -> S: ...
|
154
|
+
def update_ref[S: WithRef](self: S, reference: Union[T, "WithRef[T]", None] = None) -> S: # noqa: PYI019
|
155
|
+
"""Update the reference of the object.
|
156
|
+
|
157
|
+
Args:
|
158
|
+
reference (Union[T, WithRef[T], None]): The new reference to set.
|
159
|
+
|
160
|
+
Returns:
|
161
|
+
S: The current instance with the updated reference.
|
162
|
+
"""
|
100
163
|
if isinstance(reference, self.__class__):
|
101
164
|
self._reference = reference.referenced
|
102
165
|
else:
|
103
|
-
self._reference = reference
|
166
|
+
self._reference = reference # pyright: ignore [reportAttributeAccessIssue]
|
104
167
|
return self
|
105
168
|
|
169
|
+
def derive[S: WithRef](self: S, reference: Any) -> S: # noqa: PYI019
|
170
|
+
"""Derive a new object from the current object.
|
171
|
+
|
172
|
+
Args:
|
173
|
+
reference (Any): The reference for the new object.
|
174
|
+
|
175
|
+
Returns:
|
176
|
+
S: A new instance derived from the current object with the provided reference.
|
177
|
+
"""
|
178
|
+
new = self.model_copy()
|
179
|
+
new._reference = reference
|
180
|
+
return new
|
181
|
+
|
106
182
|
|
107
183
|
class PersistentAble(Base):
|
108
|
-
"""Class that provides a method to persist the object.
|
184
|
+
"""Class that provides a method to persist the object.
|
185
|
+
|
186
|
+
This class includes methods to persist the object to a file or directory.
|
187
|
+
"""
|
109
188
|
|
110
189
|
def persist(self, path: str | Path) -> Self:
|
111
|
-
"""Persist the object to a file.
|
190
|
+
"""Persist the object to a file or directory.
|
112
191
|
|
113
192
|
Args:
|
114
193
|
path (str | Path): The path to save the object.
|
@@ -118,16 +197,27 @@ class PersistentAble(Base):
|
|
118
197
|
"""
|
119
198
|
p = Path(path)
|
120
199
|
out = self.model_dump_json()
|
200
|
+
|
201
|
+
# Generate a timestamp in the format YYYYMMDD_HHMMSS
|
202
|
+
timestamp = datetime.now().strftime("%Y%m%d")
|
203
|
+
|
204
|
+
# Generate the hash
|
205
|
+
file_hash = blake3_hash(out.encode())[:6]
|
206
|
+
|
207
|
+
# Construct the file name with timestamp and hash
|
208
|
+
file_name = f"{self.__class__.__name__}_{timestamp}_{file_hash}.json"
|
209
|
+
|
121
210
|
if p.is_dir():
|
122
|
-
p.joinpath(
|
123
|
-
|
124
|
-
)
|
125
|
-
|
126
|
-
|
127
|
-
p.
|
211
|
+
p.joinpath(file_name).write_text(out, encoding="utf-8")
|
212
|
+
else:
|
213
|
+
p.mkdir(exist_ok=True, parents=True)
|
214
|
+
p.write_text(out, encoding="utf-8")
|
215
|
+
|
216
|
+
logger.info(f"Persisted `{self.__class__.__name__}` to {p.as_posix()}")
|
128
217
|
return self
|
129
218
|
|
130
|
-
|
219
|
+
@classmethod
|
220
|
+
def from_persistent(cls, path: str | Path) -> Self:
|
131
221
|
"""Load the object from a file.
|
132
222
|
|
133
223
|
Args:
|
@@ -136,11 +226,111 @@ class PersistentAble(Base):
|
|
136
226
|
Returns:
|
137
227
|
Self: The current instance of the object.
|
138
228
|
"""
|
139
|
-
return
|
229
|
+
return cls.model_validate_json(safe_text_read(path))
|
230
|
+
|
231
|
+
|
232
|
+
class ModelHash(Base):
|
233
|
+
"""Class that provides a hash value for the object.
|
234
|
+
|
235
|
+
This class includes a method to calculate a hash value for the object based on its JSON representation.
|
236
|
+
"""
|
237
|
+
|
238
|
+
def __hash__(self) -> int:
|
239
|
+
"""Calculates a hash value for the object based on its model_dump_json representation.
|
240
|
+
|
241
|
+
Returns:
|
242
|
+
int: The hash value of the object.
|
243
|
+
"""
|
244
|
+
return hash(self.model_dump_json())
|
245
|
+
|
246
|
+
|
247
|
+
class UpdateFrom(Base):
|
248
|
+
"""Class that provides a method to update the object from another object.
|
249
|
+
|
250
|
+
This class includes methods to update the current object with the attributes of another object.
|
251
|
+
"""
|
252
|
+
|
253
|
+
def update_pre_check(self, other: Self) -> Self:
|
254
|
+
"""Pre-check for updating the object from another object.
|
255
|
+
|
256
|
+
Args:
|
257
|
+
other (Self): The other object to update from.
|
258
|
+
|
259
|
+
Returns:
|
260
|
+
Self: The current instance after pre-check.
|
261
|
+
|
262
|
+
Raises:
|
263
|
+
TypeError: If the other object is not of the same type.
|
264
|
+
"""
|
265
|
+
if not isinstance(other, self.__class__):
|
266
|
+
raise TypeError(f"Cannot update from a non-{self.__class__.__name__} instance.")
|
267
|
+
|
268
|
+
return self
|
269
|
+
|
270
|
+
@abstractmethod
|
271
|
+
def update_from_inner(self, other: Self) -> Self:
|
272
|
+
"""Updates the current instance with the attributes of another instance.
|
273
|
+
|
274
|
+
This method should be implemented by subclasses to provide the specific update logic.
|
275
|
+
|
276
|
+
Args:
|
277
|
+
other (Self): The other instance to update from.
|
278
|
+
|
279
|
+
Returns:
|
280
|
+
Self: The current instance with updated attributes.
|
281
|
+
"""
|
282
|
+
|
283
|
+
@final
|
284
|
+
def update_from(self, other: Self) -> Self:
|
285
|
+
"""Updates the current instance with the attributes of another instance.
|
286
|
+
|
287
|
+
Args:
|
288
|
+
other (Self): The other instance to update from.
|
289
|
+
|
290
|
+
Returns:
|
291
|
+
Self: The current instance with updated attributes.
|
292
|
+
"""
|
293
|
+
return self.update_pre_check(other).update_from_inner(other)
|
294
|
+
|
295
|
+
|
296
|
+
class ResolveUpdateConflict(Base):
|
297
|
+
"""Class that provides a method to update the object from another object.
|
298
|
+
|
299
|
+
This class includes a method to resolve conflicts when updating the object from another object.
|
300
|
+
"""
|
301
|
+
|
302
|
+
@abstractmethod
|
303
|
+
def resolve_update_conflict(self, other: Self) -> str:
|
304
|
+
"""Resolve the update conflict between two objects.
|
305
|
+
|
306
|
+
Args:
|
307
|
+
other (Self): The other object to resolve the update conflict with.
|
308
|
+
|
309
|
+
Returns:
|
310
|
+
str: The resolved update conflict.
|
311
|
+
"""
|
312
|
+
|
313
|
+
|
314
|
+
class Introspect(Base):
|
315
|
+
"""Class that provides a method to introspect the object.
|
316
|
+
|
317
|
+
This class includes a method to perform internal introspection of the object.
|
318
|
+
"""
|
319
|
+
|
320
|
+
@abstractmethod
|
321
|
+
def introspect(self) -> str:
|
322
|
+
"""Internal introspection of the object.
|
323
|
+
|
324
|
+
Returns:
|
325
|
+
str: The internal introspection of the object.
|
326
|
+
"""
|
140
327
|
|
141
328
|
|
142
329
|
class WithBriefing(Named, Described):
|
143
|
-
"""Class that provides a briefing based on the name and description.
|
330
|
+
"""Class that provides a briefing based on the name and description.
|
331
|
+
|
332
|
+
This class combines the name and description attributes to provide a brief summary of the object.
|
333
|
+
"""
|
144
334
|
|
145
335
|
@property
|
146
336
|
def briefing(self) -> str:
|
@@ -151,47 +341,31 @@ class WithBriefing(Named, Described):
|
|
151
341
|
"""
|
152
342
|
return f"{self.name}: {self.description}" if self.description else self.name
|
153
343
|
|
154
|
-
def _prepend_inner(self, input_text: str) -> str:
|
155
|
-
return f"# your personal briefing: \n{self.briefing}\n{input_text}"
|
156
344
|
|
157
|
-
|
158
|
-
|
345
|
+
class UnsortGenerate(GenerateJsonSchema):
|
346
|
+
"""Class that provides a reverse JSON schema of the model.
|
347
|
+
|
348
|
+
This class overrides the sorting behavior of the JSON schema generation to maintain the original order.
|
349
|
+
"""
|
350
|
+
|
351
|
+
def sort(self, value: JsonSchemaValue, parent_key: str | None = None) -> JsonSchemaValue:
|
352
|
+
"""Not sort.
|
159
353
|
|
160
354
|
Args:
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
case dict(d):
|
168
|
-
d["system_message"] = self._prepend_inner(d.get("system_message", ""))
|
169
|
-
return d
|
170
|
-
case str(s):
|
171
|
-
return {"system_message": self._prepend_inner(s)}
|
172
|
-
case _:
|
173
|
-
raise TypeError(f"{system_msg_like} is not a dict or str")
|
174
|
-
|
175
|
-
|
176
|
-
class ReverseGenerate(GenerateJsonSchema):
|
177
|
-
"""Class that provides a reverse JSON schema of the model."""
|
178
|
-
|
179
|
-
def _sort_recursive(self, value: Any, parent_key: str | None = None) -> Any:
|
180
|
-
if isinstance(value, dict):
|
181
|
-
sorted_dict: dict[str, JsonSchemaValue] = {}
|
182
|
-
# Reverse all keys regardless of parent_key
|
183
|
-
keys = reversed(value.keys())
|
184
|
-
for key in keys:
|
185
|
-
sorted_dict[key] = self._sort_recursive(value[key], parent_key=key)
|
186
|
-
return sorted_dict
|
187
|
-
if isinstance(value, list):
|
188
|
-
# Reverse list order and process each item
|
189
|
-
return [self._sort_recursive(item, parent_key) for item in reversed(value)]
|
355
|
+
value (JsonSchemaValue): The JSON schema value to sort.
|
356
|
+
parent_key (str | None): The parent key of the JSON schema value.
|
357
|
+
|
358
|
+
Returns:
|
359
|
+
JsonSchemaValue: The JSON schema value without sorting.
|
360
|
+
"""
|
190
361
|
return value
|
191
362
|
|
192
363
|
|
193
364
|
class WithFormatedJsonSchema(Base):
|
194
|
-
"""Class that provides a formatted JSON schema of the model.
|
365
|
+
"""Class that provides a formatted JSON schema of the model.
|
366
|
+
|
367
|
+
This class includes a method to generate a formatted JSON schema of the model.
|
368
|
+
"""
|
195
369
|
|
196
370
|
@classmethod
|
197
371
|
def formated_json_schema(cls) -> str:
|
@@ -201,31 +375,32 @@ class WithFormatedJsonSchema(Base):
|
|
201
375
|
str: The JSON schema of the model in a formatted string.
|
202
376
|
"""
|
203
377
|
return orjson.dumps(
|
204
|
-
cls.model_json_schema(schema_generator=
|
378
|
+
cls.model_json_schema(schema_generator=UnsortGenerate),
|
205
379
|
option=orjson.OPT_INDENT_2,
|
206
380
|
).decode()
|
207
381
|
|
208
382
|
|
209
383
|
class CreateJsonObjPrompt(WithFormatedJsonSchema):
|
210
|
-
"""Class that provides a prompt for creating a JSON object.
|
384
|
+
"""Class that provides a prompt for creating a JSON object.
|
385
|
+
|
386
|
+
This class includes a method to create a prompt for creating a JSON object based on the model's schema and a requirement.
|
387
|
+
"""
|
211
388
|
|
212
389
|
@classmethod
|
213
390
|
@overload
|
214
391
|
def create_json_prompt(cls, requirement: List[str]) -> List[str]: ...
|
215
|
-
|
216
392
|
@classmethod
|
217
393
|
@overload
|
218
394
|
def create_json_prompt(cls, requirement: str) -> str: ...
|
219
|
-
|
220
395
|
@classmethod
|
221
396
|
def create_json_prompt(cls, requirement: str | List[str]) -> str | List[str]:
|
222
397
|
"""Create the prompt for creating a JSON object with given requirement.
|
223
398
|
|
224
399
|
Args:
|
225
|
-
requirement (str): The requirement for the JSON object.
|
400
|
+
requirement (str | List[str]): The requirement for the JSON object.
|
226
401
|
|
227
402
|
Returns:
|
228
|
-
str: The prompt for creating a JSON object with given requirement.
|
403
|
+
str | List[str]: The prompt for creating a JSON object with given requirement.
|
229
404
|
"""
|
230
405
|
if isinstance(requirement, str):
|
231
406
|
return TEMPLATE_MANAGER.render_template(
|
@@ -242,7 +417,10 @@ class CreateJsonObjPrompt(WithFormatedJsonSchema):
|
|
242
417
|
|
243
418
|
|
244
419
|
class InstantiateFromString(Base):
|
245
|
-
"""Class that provides a method to instantiate the class from a string.
|
420
|
+
"""Class that provides a method to instantiate the class from a string.
|
421
|
+
|
422
|
+
This class includes a method to instantiate the class from a JSON string representation.
|
423
|
+
"""
|
246
424
|
|
247
425
|
@classmethod
|
248
426
|
def instantiate_from_string(cls, string: str) -> Self | None:
|
@@ -254,15 +432,37 @@ class InstantiateFromString(Base):
|
|
254
432
|
Returns:
|
255
433
|
Self | None: The instance of the class or None if the string is not valid.
|
256
434
|
"""
|
257
|
-
|
435
|
+
obj = JsonCapture.convert_with(string, cls.model_validate_json)
|
436
|
+
logger.debug(f"Instantiate `{cls.__name__}` from string, {'Failed' if obj is None else 'Success'}.")
|
437
|
+
return obj
|
258
438
|
|
259
439
|
|
260
440
|
class ProposedAble(CreateJsonObjPrompt, InstantiateFromString):
|
261
|
-
"""Class that provides a method to propose a JSON object based on the requirement.
|
441
|
+
"""Class that provides a method to propose a JSON object based on the requirement.
|
442
|
+
|
443
|
+
This class combines the functionality to create a prompt for a JSON object and instantiate it from a string.
|
444
|
+
"""
|
445
|
+
|
446
|
+
|
447
|
+
class SketchedAble(ProposedAble, Display):
|
448
|
+
"""Class that provides a method to scratch the object.
|
449
|
+
|
450
|
+
This class combines the functionality to propose a JSON object, instantiate it from a string, and display it.
|
451
|
+
"""
|
452
|
+
|
453
|
+
|
454
|
+
class ProposedUpdateAble(SketchedAble, UpdateFrom, ABC):
|
455
|
+
"""Make the obj can be updated from the proposed obj in place.
|
456
|
+
|
457
|
+
This class provides the ability to update an object in place from a proposed object.
|
458
|
+
"""
|
262
459
|
|
263
460
|
|
264
461
|
class FinalizedDumpAble(Base):
|
265
|
-
"""Class that provides a method to finalize the dump of the object.
|
462
|
+
"""Class that provides a method to finalize the dump of the object.
|
463
|
+
|
464
|
+
This class includes methods to finalize the JSON representation of the object and dump it to a file.
|
465
|
+
"""
|
266
466
|
|
267
467
|
def finalized_dump(self) -> str:
|
268
468
|
"""Finalize the dump of the object.
|
@@ -285,12 +485,11 @@ class FinalizedDumpAble(Base):
|
|
285
485
|
return self
|
286
486
|
|
287
487
|
|
288
|
-
class CensoredAble(ProposedAble, FinalizedDumpAble):
|
289
|
-
"""Class that provides a method to censor the object."""
|
290
|
-
|
291
|
-
|
292
488
|
class WithDependency(Base):
|
293
|
-
"""Class that manages file dependencies.
|
489
|
+
"""Class that manages file dependencies.
|
490
|
+
|
491
|
+
This class includes methods to manage file dependencies required for reading or writing.
|
492
|
+
"""
|
294
493
|
|
295
494
|
dependencies: List[str] = Field(default_factory=list)
|
296
495
|
"""The file dependencies which is needed to read or write to meet a specific requirement, a list of file paths."""
|
@@ -377,30 +576,42 @@ class WithDependency(Base):
|
|
377
576
|
)
|
378
577
|
|
379
578
|
|
380
|
-
class
|
381
|
-
"""Class that prepares the vectorization of the model.
|
579
|
+
class Vectorizable(Base):
|
580
|
+
"""Class that prepares the vectorization of the model.
|
581
|
+
|
582
|
+
This class includes methods to prepare the model for vectorization, ensuring it fits within a specified token length.
|
583
|
+
"""
|
382
584
|
|
383
|
-
@abstractmethod
|
384
585
|
def _prepare_vectorization_inner(self) -> str:
|
385
|
-
|
586
|
+
return rtoml.dumps(self.model_dump())
|
386
587
|
|
588
|
+
@final
|
387
589
|
def prepare_vectorization(self, max_length: Optional[int] = None) -> str:
|
388
590
|
"""Prepare the vectorization of the model.
|
389
591
|
|
592
|
+
Args:
|
593
|
+
max_length (Optional[int]): The maximum token length for the vectorization. Defaults to the configuration.
|
594
|
+
|
390
595
|
Returns:
|
391
596
|
str: The prepared vectorization of the model.
|
597
|
+
|
598
|
+
Raises:
|
599
|
+
ValueError: If the chunk exceeds the maximum sequence length.
|
392
600
|
"""
|
393
601
|
max_length = max_length or configs.embedding.max_sequence_length
|
394
602
|
chunk = self._prepare_vectorization_inner()
|
395
|
-
if
|
396
|
-
logger.error(err := f"Chunk exceeds maximum sequence length {max_length}
|
603
|
+
if max_length and (length := token_counter(text=chunk)) > max_length:
|
604
|
+
logger.error(err := f"Chunk exceeds maximum sequence length {max_length}, got {length}, see {chunk}")
|
397
605
|
raise ValueError(err)
|
398
606
|
|
399
607
|
return chunk
|
400
608
|
|
401
609
|
|
402
610
|
class ScopedConfig(Base):
|
403
|
-
"""Class that manages a scoped configuration.
|
611
|
+
"""Class that manages a scoped configuration.
|
612
|
+
|
613
|
+
This class includes attributes and methods to manage configuration settings scoped to the instance.
|
614
|
+
"""
|
404
615
|
|
405
616
|
llm_api_endpoint: Optional[HttpUrl] = None
|
406
617
|
"""The OpenAI API endpoint."""
|
@@ -458,15 +669,19 @@ class ScopedConfig(Base):
|
|
458
669
|
|
459
670
|
embedding_dimensions: Optional[PositiveInt] = None
|
460
671
|
"""The dimensions of the embedding."""
|
672
|
+
|
461
673
|
embedding_caching: Optional[bool] = False
|
462
674
|
"""Whether to cache the embedding result."""
|
463
675
|
|
464
676
|
milvus_uri: Optional[HttpUrl] = Field(default=None)
|
465
677
|
"""The URI of the Milvus server."""
|
678
|
+
|
466
679
|
milvus_token: Optional[SecretStr] = Field(default=None)
|
467
680
|
"""The token for the Milvus server."""
|
681
|
+
|
468
682
|
milvus_timeout: Optional[PositiveFloat] = Field(default=None)
|
469
683
|
"""The timeout for the Milvus server."""
|
684
|
+
|
470
685
|
milvus_dimensions: Optional[PositiveInt] = Field(default=None)
|
471
686
|
"""The dimensions of the Milvus server."""
|
472
687
|
|
@@ -475,7 +690,7 @@ class ScopedConfig(Base):
|
|
475
690
|
"""Fallback to another instance's attribute values if the current instance's attributes are None.
|
476
691
|
|
477
692
|
Args:
|
478
|
-
other (
|
693
|
+
other (ScopedConfig): Another instance from which to copy attribute values.
|
479
694
|
|
480
695
|
Returns:
|
481
696
|
Self: The current instance, allowing for method chaining.
|
@@ -495,7 +710,7 @@ class ScopedConfig(Base):
|
|
495
710
|
"""Hold to another instance's attribute values if the current instance's attributes are None.
|
496
711
|
|
497
712
|
Args:
|
498
|
-
others (
|
713
|
+
others (Union[ScopedConfig, Iterable[ScopedConfig]]): Another instance or iterable of instances from which to copy attribute values.
|
499
714
|
|
500
715
|
Returns:
|
501
716
|
Self: The current instance, allowing for method chaining.
|
@@ -508,3 +723,60 @@ class ScopedConfig(Base):
|
|
508
723
|
if (attr := getattr(self, attr_name)) is not None and getattr(other, attr_name) is None:
|
509
724
|
setattr(other, attr_name, attr)
|
510
725
|
return self
|
726
|
+
|
727
|
+
|
728
|
+
class Patch[T](ProposedAble):
|
729
|
+
"""Base class for patches.
|
730
|
+
|
731
|
+
This class provides a base implementation for patches that can be applied to other objects.
|
732
|
+
"""
|
733
|
+
|
734
|
+
def apply(self, other: T) -> T:
|
735
|
+
"""Apply the patch to another instance.
|
736
|
+
|
737
|
+
Args:
|
738
|
+
other (T): The instance to apply the patch to.
|
739
|
+
|
740
|
+
Returns:
|
741
|
+
T: The instance with the patch applied.
|
742
|
+
|
743
|
+
Raises:
|
744
|
+
ValueError: If a field in the patch is not found in the target instance.
|
745
|
+
"""
|
746
|
+
for field in self.__class__.model_fields:
|
747
|
+
if not hasattr(other, field):
|
748
|
+
raise ValueError(f"{field} not found in {other}, are you applying to the wrong type?")
|
749
|
+
setattr(other, field, getattr(self, field))
|
750
|
+
return other
|
751
|
+
|
752
|
+
|
753
|
+
class SequencePatch[T](ProposedUpdateAble):
|
754
|
+
"""Base class for patches.
|
755
|
+
|
756
|
+
This class provides a base implementation for patches that can be applied to sequences of objects.
|
757
|
+
"""
|
758
|
+
|
759
|
+
tweaked: List[T]
|
760
|
+
"""Tweaked content list"""
|
761
|
+
|
762
|
+
def update_from_inner(self, other: Self) -> Self:
|
763
|
+
"""Updates the current instance with the attributes of another instance.
|
764
|
+
|
765
|
+
Args:
|
766
|
+
other (Self): The other instance to update from.
|
767
|
+
|
768
|
+
Returns:
|
769
|
+
Self: The current instance with updated attributes.
|
770
|
+
"""
|
771
|
+
self.tweaked.clear()
|
772
|
+
self.tweaked.extend(other.tweaked)
|
773
|
+
return self
|
774
|
+
|
775
|
+
@classmethod
|
776
|
+
def default(cls) -> Self:
|
777
|
+
"""Defaults to empty list.
|
778
|
+
|
779
|
+
Returns:
|
780
|
+
Self: A new instance with an empty list of tweaks.
|
781
|
+
"""
|
782
|
+
return cls(tweaked=[])
|