fabricatio 0.2.13.dev3__cp312-cp312-win_amd64.whl → 0.3.14__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.
Files changed (53) hide show
  1. fabricatio/__init__.py +7 -14
  2. fabricatio/actions/article.py +58 -23
  3. fabricatio/actions/article_rag.py +6 -15
  4. fabricatio/actions/output.py +38 -3
  5. fabricatio/actions/rag.py +4 -4
  6. fabricatio/capabilities/advanced_judge.py +4 -7
  7. fabricatio/capabilities/advanced_rag.py +2 -1
  8. fabricatio/capabilities/censor.py +5 -4
  9. fabricatio/capabilities/check.py +6 -7
  10. fabricatio/capabilities/correct.py +5 -5
  11. fabricatio/capabilities/extract.py +7 -3
  12. fabricatio/capabilities/persist.py +103 -0
  13. fabricatio/capabilities/propose.py +2 -2
  14. fabricatio/capabilities/rag.py +43 -43
  15. fabricatio/capabilities/rating.py +11 -10
  16. fabricatio/capabilities/review.py +8 -6
  17. fabricatio/capabilities/task.py +22 -22
  18. fabricatio/decorators.py +4 -2
  19. fabricatio/{core.py → emitter.py} +35 -39
  20. fabricatio/fs/__init__.py +1 -2
  21. fabricatio/journal.py +2 -11
  22. fabricatio/models/action.py +14 -30
  23. fabricatio/models/extra/aricle_rag.py +14 -8
  24. fabricatio/models/extra/article_base.py +56 -25
  25. fabricatio/models/extra/article_essence.py +2 -1
  26. fabricatio/models/extra/article_main.py +16 -13
  27. fabricatio/models/extra/article_outline.py +2 -1
  28. fabricatio/models/extra/article_proposal.py +1 -1
  29. fabricatio/models/extra/rag.py +2 -2
  30. fabricatio/models/extra/rule.py +2 -1
  31. fabricatio/models/generic.py +56 -166
  32. fabricatio/models/kwargs_types.py +1 -54
  33. fabricatio/models/role.py +49 -26
  34. fabricatio/models/task.py +8 -9
  35. fabricatio/models/tool.py +7 -7
  36. fabricatio/models/usages.py +67 -61
  37. fabricatio/parser.py +60 -100
  38. fabricatio/rust.cp312-win_amd64.pyd +0 -0
  39. fabricatio/rust.pyi +469 -74
  40. fabricatio/utils.py +63 -162
  41. fabricatio-0.3.14.data/scripts/tdown.exe +0 -0
  42. fabricatio-0.3.14.data/scripts/ttm.exe +0 -0
  43. {fabricatio-0.2.13.dev3.dist-info → fabricatio-0.3.14.dist-info}/METADATA +10 -15
  44. fabricatio-0.3.14.dist-info/RECORD +64 -0
  45. {fabricatio-0.2.13.dev3.dist-info → fabricatio-0.3.14.dist-info}/WHEEL +1 -1
  46. fabricatio/config.py +0 -430
  47. fabricatio/constants.py +0 -20
  48. fabricatio/models/events.py +0 -120
  49. fabricatio/rust_instances.py +0 -10
  50. fabricatio-0.2.13.dev3.data/scripts/tdown.exe +0 -0
  51. fabricatio-0.2.13.dev3.data/scripts/ttm.exe +0 -0
  52. fabricatio-0.2.13.dev3.dist-info/RECORD +0 -67
  53. {fabricatio-0.2.13.dev3.dist-info → fabricatio-0.3.14.dist-info}/licenses/LICENSE +0 -0
@@ -1,24 +1,19 @@
1
1
  """This module defines generic classes for models in the Fabricatio library, providing a foundation for various model functionalities."""
2
2
 
3
3
  from abc import ABC, abstractmethod
4
- from datetime import datetime
5
4
  from pathlib import Path
6
- from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Self, Type, Union, final, overload
5
+ from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Self, Sequence, Type, Union, final, overload
7
6
 
8
7
  import ujson
9
- from fabricatio.config import configs
8
+ from fabricatio.fs import dump_text
10
9
  from fabricatio.fs.readers import safe_text_read
11
10
  from fabricatio.journal import logger
12
- from fabricatio.parser import JsonCapture
13
- from fabricatio.rust import blake3_hash, detect_language
14
- from fabricatio.rust_instances import TEMPLATE_MANAGER
11
+ from fabricatio.rust import CONFIG, TEMPLATE_MANAGER, blake3_hash, detect_language
15
12
  from fabricatio.utils import ok
16
- from litellm.utils import token_counter
17
13
  from pydantic import (
18
14
  BaseModel,
19
15
  ConfigDict,
20
16
  Field,
21
- HttpUrl,
22
17
  NonNegativeFloat,
23
18
  PositiveFloat,
24
19
  PositiveInt,
@@ -28,7 +23,7 @@ from pydantic import (
28
23
  from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
29
24
 
30
25
 
31
- class Base(BaseModel):
26
+ class Base(BaseModel, ABC):
32
27
  """Base class for all models with Pydantic configuration.
33
28
 
34
29
  This class sets up the basic Pydantic configuration for all models in the Fabricatio library.
@@ -39,7 +34,7 @@ class Base(BaseModel):
39
34
  model_config = ConfigDict(use_attribute_docstrings=True)
40
35
 
41
36
 
42
- class Display(Base):
37
+ class Display(Base, ABC):
43
38
  """Class that provides formatted JSON representation utilities.
44
39
 
45
40
  Provides methods to generate both pretty-printed and compact JSON representations of the model.
@@ -80,7 +75,7 @@ class Display(Base):
80
75
  )
81
76
 
82
77
 
83
- class Named(Base):
78
+ class Named(Base, ABC):
84
79
  """Class that includes a name attribute.
85
80
 
86
81
  This class adds a name attribute to models, which is intended to be a unique identifier.
@@ -90,7 +85,7 @@ class Named(Base):
90
85
  """The name of this object,briefly and conclusively."""
91
86
 
92
87
 
93
- class Described(Base):
88
+ class Described(Base, ABC):
94
89
  """Class that includes a description attribute.
95
90
 
96
91
  This class adds a description attribute to models, providing additional context or information.
@@ -103,21 +98,26 @@ class Described(Base):
103
98
  this object's intent and application."""
104
99
 
105
100
 
106
- class Titled(Base):
101
+ class Titled(Base, ABC):
107
102
  """Class that includes a title attribute."""
108
103
 
109
104
  title: str
110
105
  """The title of this object, make it professional and concise.No prefixed heading number should be included."""
111
106
 
112
107
 
113
- class WordCount(Base):
108
+ class WordCount(Base, ABC):
114
109
  """Class that includes a word count attribute."""
115
110
 
116
111
  expected_word_count: int
117
112
  """Expected word count of this research component."""
118
113
 
114
+ @property
115
+ def exact_word_count(self) -> int:
116
+ """Get the exact word count of this research component."""
117
+ raise NotImplementedError(f"`exact_word_count` is not implemented for {self.__class__.__name__}")
118
+
119
119
 
120
- class FromMapping(Base):
120
+ class FromMapping:
121
121
  """Class that provides a method to generate a list of objects from a mapping."""
122
122
 
123
123
  @classmethod
@@ -126,7 +126,16 @@ class FromMapping(Base):
126
126
  """Generate a list of objects from a mapping."""
127
127
 
128
128
 
129
- class AsPrompt(Base):
129
+ class FromSequence:
130
+ """Class that provides a method to generate a list of objects from a sequence."""
131
+
132
+ @classmethod
133
+ @abstractmethod
134
+ def from_sequence[S](cls: S, sequence: Sequence[Any], **kwargs: Any) -> List[S]:
135
+ """Generate a list of objects from a sequence."""
136
+
137
+
138
+ class AsPrompt:
130
139
  """Class that provides a method to generate a prompt from the model.
131
140
 
132
141
  This class includes a method to generate a prompt based on the model's attributes.
@@ -140,7 +149,7 @@ class AsPrompt(Base):
140
149
  str: The generated prompt.
141
150
  """
142
151
  return TEMPLATE_MANAGER.render_template(
143
- configs.templates.as_prompt_template,
152
+ CONFIG.templates.as_prompt_template,
144
153
  self._as_prompt_inner(),
145
154
  )
146
155
 
@@ -155,7 +164,7 @@ class AsPrompt(Base):
155
164
  """
156
165
 
157
166
 
158
- class WithRef[T](Base):
167
+ class WithRef[T](Base, ABC):
159
168
  """Class that provides a reference to another object.
160
169
 
161
170
  This class manages a reference to another object, allowing for easy access and updates.
@@ -201,112 +210,8 @@ class WithRef[T](Base):
201
210
  self._reference = reference # pyright: ignore [reportAttributeAccessIssue]
202
211
  return self
203
212
 
204
- def derive[S: WithRef](self: S, reference: Any) -> S:
205
- """Derive a new object from the current object.
206
-
207
- Args:
208
- reference (Any): The reference for the new object.
209
-
210
- Returns:
211
- S: A new instance derived from the current object with the provided reference.
212
- """
213
- new = self.model_copy()
214
- new._reference = reference
215
- return new
216
-
217
-
218
- class PersistentAble(Base):
219
- """Class providing file persistence capabilities.
220
213
 
221
- Enables saving model instances to disk with timestamped filenames and loading from persisted files.
222
- Implements basic versioning through filename hashing and timestamping.
223
- """
224
-
225
- def persist(self, path: str | Path) -> Self:
226
- """Save model instance to disk with versioned filename.
227
-
228
- Args:
229
- path (str | Path): Target directory or file path. If directory, filename is auto-generated.
230
-
231
- Returns:
232
- Self: Current instance for method chaining
233
-
234
- Notes:
235
- - Filename format: <ClassName>_<YYYYMMDD_HHMMSS>_<6-char_hash>.json
236
- - Hash generated from JSON content ensures uniqueness
237
- """
238
- p = Path(path)
239
- out = self.model_dump_json(indent=1, by_alias=True)
240
-
241
- # Generate a timestamp in the format YYYYMMDD_HHMMSS
242
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
243
-
244
- # Generate the hash
245
- file_hash = blake3_hash(out.encode())[:6]
246
-
247
- # Construct the file name with timestamp and hash
248
- file_name = f"{self.__class__.__name__}_{timestamp}_{file_hash}.json"
249
-
250
- if p.is_dir():
251
- p.joinpath(file_name).write_text(out, encoding="utf-8")
252
- else:
253
- p.mkdir(exist_ok=True, parents=True)
254
- p.write_text(out, encoding="utf-8")
255
-
256
- logger.info(f"Persisted `{self.__class__.__name__}` to {p.as_posix()}")
257
- return self
258
-
259
- @classmethod
260
- def from_latest_persistent(cls, dir_path: str | Path) -> Optional[Self]:
261
- """Load most recent persisted instance from directory.
262
-
263
- Args:
264
- dir_path (str | Path): Directory containing persisted files
265
-
266
- Returns:
267
- Self: Most recently modified instance
268
-
269
- Raises:
270
- NotADirectoryError: If path is not a valid directory
271
- FileNotFoundError: If no matching files found
272
- """
273
- dir_path = Path(dir_path)
274
- if not dir_path.is_dir():
275
- return None
276
-
277
- pattern = f"{cls.__name__}_*.json"
278
- files = list(dir_path.glob(pattern))
279
-
280
- if not files:
281
- return None
282
-
283
- def _get_timestamp(file_path: Path) -> datetime:
284
- stem = file_path.stem
285
- parts = stem.split("_")
286
- return datetime.strptime(f"{parts[1]}_{parts[2]}", "%Y%m%d_%H%M%S")
287
-
288
- files.sort(key=lambda f: _get_timestamp(f), reverse=True)
289
-
290
- return cls.from_persistent(files.pop(0))
291
-
292
- @classmethod
293
- def from_persistent(cls, path: str | Path) -> Self:
294
- """Load an instance from a specific persisted file.
295
-
296
- Args:
297
- path (str | Path): Path to the JSON file.
298
-
299
- Returns:
300
- Self: The loaded instance from the file.
301
-
302
- Raises:
303
- FileNotFoundError: If the specified file does not exist.
304
- ValueError: If the file content is invalid for the model.
305
- """
306
- return cls.model_validate_json(safe_text_read(path))
307
-
308
-
309
- class Language(Base):
214
+ class Language:
310
215
  """Class that provides a language attribute."""
311
216
 
312
217
  @property
@@ -318,11 +223,10 @@ class Language(Base):
318
223
  return detect_language(self.title)
319
224
  if isinstance(self, Named) and self.name:
320
225
  return detect_language(self.name)
321
-
322
- return detect_language(self.model_dump_json(by_alias=True))
226
+ raise RuntimeError(f"Cannot determine language! class that not support language: {self.__class__.__name__}")
323
227
 
324
228
 
325
- class ModelHash(Base):
229
+ class ModelHash(Base, ABC):
326
230
  """Class that provides a hash value for the object.
327
231
 
328
232
  This class includes a method to calculate a hash value for the object based on its JSON representation.
@@ -337,7 +241,7 @@ class ModelHash(Base):
337
241
  return hash(self.model_dump_json())
338
242
 
339
243
 
340
- class UpdateFrom(Base):
244
+ class UpdateFrom(ABC):
341
245
  """Class that provides a method to update the object from another object.
342
246
 
343
247
  This class includes methods to update the current object with the attributes of another object.
@@ -386,25 +290,7 @@ class UpdateFrom(Base):
386
290
  return self.update_pre_check(other).update_from_inner(other)
387
291
 
388
292
 
389
- class ResolveUpdateConflict(Base):
390
- """Class that provides a method to update the object from another object.
391
-
392
- This class includes a method to resolve conflicts when updating the object from another object.
393
- """
394
-
395
- @abstractmethod
396
- def resolve_update_conflict(self, other: Self) -> str:
397
- """Resolve the update conflict between two objects.
398
-
399
- Args:
400
- other (Self): The other object to resolve the update conflict with.
401
-
402
- Returns:
403
- str: The resolved update conflict.
404
- """
405
-
406
-
407
- class Introspect(Base):
293
+ class Introspect(ABC):
408
294
  """Class that provides a method to introspect the object.
409
295
 
410
296
  This class includes a method to perform internal introspection of the object.
@@ -419,7 +305,7 @@ class Introspect(Base):
419
305
  """
420
306
 
421
307
 
422
- class WithBriefing(Named, Described):
308
+ class WithBriefing(Named, Described, ABC):
423
309
  """Class that provides a briefing based on the name and description.
424
310
 
425
311
  This class combines the name and description attributes to provide a brief summary of the object.
@@ -454,7 +340,7 @@ class UnsortGenerate(GenerateJsonSchema):
454
340
  return value
455
341
 
456
342
 
457
- class WithFormatedJsonSchema(Base):
343
+ class WithFormatedJsonSchema(Base, ABC):
458
344
  """Class that provides a formatted JSON schema of the model.
459
345
 
460
346
  This class includes a method to generate a formatted JSON schema of the model.
@@ -472,7 +358,7 @@ class WithFormatedJsonSchema(Base):
472
358
  )
473
359
 
474
360
 
475
- class CreateJsonObjPrompt(WithFormatedJsonSchema):
361
+ class CreateJsonObjPrompt(WithFormatedJsonSchema, ABC):
476
362
  """Class that provides a prompt for creating a JSON object.
477
363
 
478
364
  This class includes a method to create a prompt for creating a JSON object based on the model's schema and a requirement.
@@ -498,19 +384,19 @@ class CreateJsonObjPrompt(WithFormatedJsonSchema):
498
384
  """
499
385
  if isinstance(requirement, str):
500
386
  return TEMPLATE_MANAGER.render_template(
501
- configs.templates.create_json_obj_template,
387
+ CONFIG.templates.create_json_obj_template,
502
388
  {"requirement": requirement, "json_schema": cls.formated_json_schema()},
503
389
  )
504
390
  return [
505
391
  TEMPLATE_MANAGER.render_template(
506
- configs.templates.create_json_obj_template,
392
+ CONFIG.templates.create_json_obj_template,
507
393
  {"requirement": r, "json_schema": cls.formated_json_schema()},
508
394
  )
509
395
  for r in requirement
510
396
  ]
511
397
 
512
398
 
513
- class InstantiateFromString(Base):
399
+ class InstantiateFromString(Base, ABC):
514
400
  """Class that provides a method to instantiate the class from a string.
515
401
 
516
402
  This class includes a method to instantiate the class from a JSON string representation.
@@ -526,19 +412,21 @@ class InstantiateFromString(Base):
526
412
  Returns:
527
413
  Self | None: The instance of the class or None if the string is not valid.
528
414
  """
415
+ from fabricatio.parser import JsonCapture
416
+
529
417
  obj = JsonCapture.convert_with(string, cls.model_validate_json)
530
418
  logger.debug(f"Instantiate `{cls.__name__}` from string, {'Failed' if obj is None else 'Success'}.")
531
419
  return obj
532
420
 
533
421
 
534
- class ProposedAble(CreateJsonObjPrompt, InstantiateFromString):
422
+ class ProposedAble(CreateJsonObjPrompt, InstantiateFromString, ABC):
535
423
  """Class that provides a method to propose a JSON object based on the requirement.
536
424
 
537
425
  This class combines the functionality to create a prompt for a JSON object and instantiate it from a string.
538
426
  """
539
427
 
540
428
 
541
- class SketchedAble(ProposedAble, Display):
429
+ class SketchedAble(ProposedAble, Display, ABC):
542
430
  """Class that provides a method to scratch the object.
543
431
 
544
432
  This class combines the functionality to propose a JSON object, instantiate it from a string, and display it.
@@ -552,7 +440,7 @@ class ProposedUpdateAble(SketchedAble, UpdateFrom, ABC):
552
440
  """
553
441
 
554
442
 
555
- class FinalizedDumpAble(Base):
443
+ class FinalizedDumpAble(Base, ABC):
556
444
  """Class that provides a method to finalize the dump of the object.
557
445
 
558
446
  This class includes methods to finalize the JSON representation of the object and dump it to a file.
@@ -575,11 +463,11 @@ class FinalizedDumpAble(Base):
575
463
  Returns:
576
464
  Self: The current instance of the object.
577
465
  """
578
- Path(path).write_text(self.finalized_dump(), encoding="utf-8")
466
+ dump_text(path, self.finalized_dump())
579
467
  return self
580
468
 
581
469
 
582
- class WithDependency(Base):
470
+ class WithDependency(Base, ABC):
583
471
  """Class that manages file dependencies.
584
472
 
585
473
  This class includes methods to manage file dependencies required for reading or writing.
@@ -655,7 +543,7 @@ class WithDependency(Base):
655
543
  from fabricatio.fs import MAGIKA
656
544
 
657
545
  return TEMPLATE_MANAGER.render_template(
658
- configs.templates.dependencies_template,
546
+ CONFIG.templates.dependencies_template,
659
547
  {
660
548
  (pth := Path(p)).name: {
661
549
  "path": pth.as_posix(),
@@ -672,7 +560,7 @@ class WithDependency(Base):
672
560
  )
673
561
 
674
562
 
675
- class Vectorizable(Base):
563
+ class Vectorizable(ABC):
676
564
  """Class that prepares the vectorization of the model.
677
565
 
678
566
  This class includes methods to prepare the model for vectorization, ensuring it fits within a specified token length.
@@ -695,7 +583,9 @@ class Vectorizable(Base):
695
583
  Raises:
696
584
  ValueError: If the chunk exceeds the maximum sequence length.
697
585
  """
698
- max_length = max_length or configs.embedding.max_sequence_length
586
+ from litellm.utils import token_counter
587
+
588
+ max_length = max_length or CONFIG.embedding.max_sequence_length
699
589
  chunk = self._prepare_vectorization_inner()
700
590
  if max_length and (length := token_counter(text=chunk)) > max_length:
701
591
  raise ValueError(f"Chunk exceeds maximum sequence length {max_length}, got {length}, see \n{chunk}")
@@ -703,14 +593,14 @@ class Vectorizable(Base):
703
593
  return chunk
704
594
 
705
595
 
706
- class ScopedConfig(Base):
596
+ class ScopedConfig(Base, ABC):
707
597
  """Configuration holder with hierarchical fallback mechanism.
708
598
 
709
599
  Manages LLM, embedding, and vector database configurations with fallback logic.
710
600
  Allows configuration values to be overridden in a hierarchical manner.
711
601
  """
712
602
 
713
- llm_api_endpoint: Optional[HttpUrl] = None
603
+ llm_api_endpoint: Optional[str] = None
714
604
  """The OpenAI API endpoint."""
715
605
 
716
606
  llm_api_key: Optional[SecretStr] = None
@@ -755,7 +645,7 @@ class ScopedConfig(Base):
755
645
  llm_frequency_penalty: Optional[PositiveFloat] = None
756
646
  """The frequency penalty of the LLM model."""
757
647
 
758
- embedding_api_endpoint: Optional[HttpUrl] = None
648
+ embedding_api_endpoint: Optional[str] = None
759
649
  """The OpenAI API endpoint."""
760
650
 
761
651
  embedding_api_key: Optional[SecretStr] = None
@@ -776,7 +666,7 @@ class ScopedConfig(Base):
776
666
  embedding_caching: Optional[bool] = False
777
667
  """Whether to cache the embedding result."""
778
668
 
779
- milvus_uri: Optional[HttpUrl] = Field(default=None)
669
+ milvus_uri: Optional[str] = Field(default=None)
780
670
  """The URI of the Milvus server."""
781
671
 
782
672
  milvus_token: Optional[SecretStr] = Field(default=None)
@@ -836,7 +726,7 @@ class ScopedConfig(Base):
836
726
  return self
837
727
 
838
728
 
839
- class Patch[T](ProposedAble):
729
+ class Patch[T](ProposedAble, ABC):
840
730
  """Base class for patches.
841
731
 
842
732
  This class provides a base implementation for patches that can be applied to other objects.
@@ -890,7 +780,7 @@ class Patch[T](ProposedAble):
890
780
  return ujson.dumps(my_schema, indent=2, ensure_ascii=False, sort_keys=False)
891
781
 
892
782
 
893
- class SequencePatch[T](ProposedUpdateAble):
783
+ class SequencePatch[T](ProposedUpdateAble, ABC):
894
784
  """Base class for patches.
895
785
 
896
786
  This class provides a base implementation for patches that can be applied to sequences of objects.
@@ -1,9 +1,6 @@
1
1
  """This module contains the types for the keyword arguments of the methods in the models module."""
2
2
 
3
- from typing import Any, Dict, List, Literal, NotRequired, Optional, Required, TypedDict
4
-
5
- from litellm.caching.caching import CacheMode
6
- from litellm.types.caching import CachingSupportedCallTypes
3
+ from typing import Dict, List, NotRequired, Optional, Required, TypedDict
7
4
 
8
5
 
9
6
  class ChunkKwargs(TypedDict):
@@ -70,7 +67,6 @@ class ValidateKwargs[T](GenerateKwargs, total=False):
70
67
  max_validations: int
71
68
 
72
69
 
73
-
74
70
  class CompositeScoreKwargs(ValidateKwargs[List[Dict[str, float]]], total=False):
75
71
  """Arguments for composite score generation operations.
76
72
 
@@ -123,52 +119,3 @@ class ChooseKwargs[T](ValidateKwargs[T], total=False):
123
119
  """
124
120
 
125
121
  k: int
126
-
127
-
128
- class CacheKwargs(TypedDict, total=False):
129
- """Configuration parameters for the caching system.
130
-
131
- These arguments control the behavior of various caching backends,
132
- including in-memory, Redis, S3, and vector database caching options.
133
- """
134
-
135
- mode: CacheMode # when default_on cache is always on, when default_off cache is opt in
136
- host: str
137
- port: str
138
- password: str
139
- namespace: str
140
- ttl: float
141
- default_in_memory_ttl: float
142
- default_in_redis_ttl: float
143
- similarity_threshold: float
144
- supported_call_types: list[CachingSupportedCallTypes]
145
- # s3 Bucket, boto3 configuration
146
- s3_bucket_name: str
147
- s3_region_name: str
148
- s3_api_version: str
149
- s3_use_ssl: bool
150
- s3_verify: bool | str
151
- s3_endpoint_url: str
152
- s3_aws_access_key_id: str
153
- s3_aws_secret_access_key: str
154
- s3_aws_session_token: str
155
- s3_config: Any
156
- s3_path: str
157
- redis_semantic_cache_use_async: bool
158
- redis_semantic_cache_embedding_model: str
159
- redis_flush_size: int
160
- redis_startup_nodes: list
161
- disk_cache_dir: Any
162
- qdrant_api_base: str
163
- qdrant_api_key: str
164
- qdrant_collection_name: str
165
- qdrant_quantization_config: str
166
- qdrant_semantic_cache_embedding_model: str
167
-
168
-
169
- class RerankOptions(TypedDict, total=False):
170
- """Optional keyword arguments for the rerank method."""
171
-
172
- raw_scores: bool
173
- truncate: bool
174
- truncation_direction: Literal["Left", "Right"]
fabricatio/models/role.py CHANGED
@@ -1,44 +1,44 @@
1
1
  """Module that contains the Role class for managing workflows and their event registrations."""
2
2
 
3
- from typing import Any, Self, Set
3
+ from functools import partial
4
+ from typing import Any, Callable, Dict, Self, Type
4
5
 
5
- from fabricatio.capabilities.propose import Propose
6
- from fabricatio.core import env
6
+ from fabricatio.emitter import env
7
7
  from fabricatio.journal import logger
8
8
  from fabricatio.models.action import WorkFlow
9
- from fabricatio.models.events import Event
10
9
  from fabricatio.models.generic import WithBriefing
11
- from fabricatio.models.tool import ToolBox
12
- from fabricatio.models.usages import ToolBoxUsage
13
- from pydantic import Field
10
+ from fabricatio.rust import Event
11
+ from fabricatio.utils import is_subclass_of_base
12
+ from pydantic import ConfigDict, Field
14
13
 
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")
15
16
 
16
- class Role(WithBriefing, Propose, ToolBoxUsage):
17
+
18
+ class Role(WithBriefing):
17
19
  """Class that represents a role with a registry of events and workflows.
18
20
 
19
21
  A Role serves as a container for workflows, managing their registration to events
20
22
  and providing them with shared configuration like tools and personality.
21
-
22
- Attributes:
23
- registry: Mapping of events to workflows that handle them
24
- toolboxes: Set of toolboxes available to this role and its workflows
25
23
  """
26
24
 
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
 
30
- registry: dict[Event | str, WorkFlow] = Field(default_factory=dict)
31
+ registry: Dict[Event, WorkFlow] = Field(default_factory=dict)
31
32
  """The registry of events and workflows."""
32
33
 
33
- toolboxes: Set[ToolBox] = Field(default_factory=set)
34
- """Collection of tools available to this role."""
35
-
36
34
  def model_post_init(self, __context: Any) -> None:
37
35
  """Initialize the role by resolving configurations and registering workflows.
38
36
 
39
37
  Args:
40
38
  __context: The context used for initialization
41
39
  """
40
+ self.name = self.name or self.__class__.__name__
41
+
42
42
  self.resolve_configuration().register_workflows()
43
43
 
44
44
  def register_workflows(self) -> Self:
@@ -48,9 +48,7 @@ class Role(WithBriefing, Propose, ToolBoxUsage):
48
48
  Self: The role instance for method chaining
49
49
  """
50
50
  for event, workflow in self.registry.items():
51
- logger.debug(
52
- f"Registering workflow: `{workflow.name}` for event: `{Event.instantiate_from(event).collapse()}`"
53
- )
51
+ logger.debug(f"Registering workflow: `{workflow.name}` for event: `{event.collapse()}`")
54
52
  env.on(event, workflow.serve)
55
53
  return self
56
54
 
@@ -65,12 +63,37 @@ class Role(WithBriefing, Propose, ToolBoxUsage):
65
63
  """
66
64
  for workflow in self.registry.values():
67
65
  logger.debug(f"Resolving config for workflow: `{workflow.name}`")
68
- (
69
- workflow.fallback_to(self)
70
- .steps_fallback_to_self()
71
- .inject_personality(self.briefing)
72
- .supply_tools_from(self)
73
- .steps_supply_tools_from_self()
66
+ self._configure_scoped_config(workflow)
67
+ self._configure_toolbox_usage(workflow)
68
+ workflow.inject_personality(self.briefing)
69
+ return self
70
+
71
+ def _propagate_config(
72
+ self,
73
+ workflow: WorkFlow,
74
+ has_capability: Callable[[Type], bool],
75
+ config_method_name: str,
76
+ capability_description: str,
77
+ ) -> None:
78
+ """Propagates configuration to workflow and its actions if they have a given capability."""
79
+ if not has_capability(self.__class__):
80
+ return
81
+
82
+ config_source_for_actions = self
83
+ if has_capability(workflow.__class__):
84
+ logger.debug(
85
+ f"Configuring {capability_description} inherited from `{self.name}` for workflow: `{workflow.name}`"
74
86
  )
87
+ getattr(workflow, config_method_name)(self)
88
+ config_source_for_actions = workflow
75
89
 
76
- return self
90
+ for action in (act for act in workflow.iter_actions() if has_capability(act.__class__)):
91
+ getattr(action, config_method_name)(config_source_for_actions)
92
+
93
+ def _configure_scoped_config(self, workflow: WorkFlow) -> None:
94
+ """Configure scoped configuration for workflow and its actions."""
95
+ self._propagate_config(workflow, is_scoped_config, "fallback_to", "scoped config")
96
+
97
+ def _configure_toolbox_usage(self, workflow: WorkFlow) -> None:
98
+ """Configure toolbox usage for workflow and its actions."""
99
+ self._propagate_config(workflow, is_toolbox_usage, "supply_tools_from", "toolbox usage")