fabricatio 0.2.7.dev4__cp312-cp312-win_amd64.whl → 0.2.8.dev0__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.
@@ -1,13 +1,12 @@
1
1
  """ArticleBase and ArticleSubsection classes for managing hierarchical document components."""
2
2
 
3
3
  from itertools import chain
4
- from typing import Generator, List, Self, Tuple
4
+ from typing import Generator, List, Self, Tuple, override
5
5
 
6
6
  from fabricatio.journal import logger
7
7
  from fabricatio.models.extra.article_base import (
8
8
  ArticleBase,
9
- ArticleMainBase,
10
- ArticleRef,
9
+ ArticleOutlineBase,
11
10
  ChapterBase,
12
11
  SectionBase,
13
12
  SubSectionBase,
@@ -28,26 +27,28 @@ class Paragraph(CensoredAble):
28
27
  writing_aim: List[str]
29
28
  """Specific communicative objectives for this paragraph's content."""
30
29
 
31
- sentences: List[str]
32
- """List of sentences forming the paragraph's content."""
30
+ content: str
31
+ """The actual content of the paragraph, represented as a string."""
33
32
 
34
33
 
35
- class ArticleSubsection(ArticleMainBase, SubSectionBase):
34
+ class ArticleSubsection(SubSectionBase):
36
35
  """Atomic argumentative unit with technical specificity."""
37
36
 
38
37
  paragraphs: List[Paragraph]
39
38
  """List of Paragraph objects containing the content of the subsection."""
40
39
 
41
- def resolve_update_error(self, other: Self) -> str:
42
- """Resolve update errors in the article outline."""
43
- if self.title != other.title:
44
- return f"Title `{other.title}` mismatched, expected `{self.title}`. "
40
+ def introspect(self) -> str:
41
+ """Introspects the subsection and returns a message if it has no paragraphs."""
42
+ if len(self.paragraphs) == 0:
43
+ return f"`{self.__class__.__name__}` titled `{self.title}` have no paragraphs, to achieve the goal of `{self.writing_aim}`."
45
44
  return ""
46
45
 
47
- def _update_from_inner(self, other: Self) -> Self:
46
+ def update_from_inner(self, other: Self) -> Self:
48
47
  """Updates the current instance with the attributes of another instance."""
49
48
  logger.debug(f"Updating SubSection {self.title}")
50
- self.paragraphs = other.paragraphs
49
+ super().update_from_inner(other)
50
+ self.paragraphs.clear()
51
+ self.paragraphs.extend(other.paragraphs)
51
52
  return self
52
53
 
53
54
  def to_typst_code(self) -> str:
@@ -56,102 +57,33 @@ class ArticleSubsection(ArticleMainBase, SubSectionBase):
56
57
  Returns:
57
58
  str: Typst code snippet for rendering.
58
59
  """
59
- return f"=== {self.title}\n" + "\n\n".join("".join(p.sentences) for p in self.paragraphs)
60
+ return f"=== {self.title}\n" + "\n\n".join(p.content for p in self.paragraphs)
60
61
 
61
62
 
62
- class ArticleSection(ArticleMainBase, SectionBase[ArticleSubsection]):
63
+ class ArticleSection(SectionBase[ArticleSubsection]):
63
64
  """Atomic argumentative unit with high-level specificity."""
64
65
 
65
- def resolve_update_error(self, other: Self) -> str:
66
- """Resolve update errors in the article outline."""
67
- if (s_len := len(self.subsections)) == 0:
68
- return ""
69
66
 
70
- if s_len != len(other.subsections):
71
- return f"Subsections length mismatched, expected {len(self.subsections)}, got {len(other.subsections)}"
72
-
73
- sub_sec_err_seq = [
74
- out for s, o in zip(self.subsections, other.subsections, strict=True) if (out := s.resolve_update_error(o))
75
- ]
76
-
77
- if sub_sec_err_seq:
78
- return "\n".join(sub_sec_err_seq)
79
- return ""
80
-
81
- def _update_from_inner(self, other: Self) -> Self:
82
- """Updates the current instance with the attributes of another instance."""
83
- if len(self.subsections) == 0:
84
- self.subsections = other.subsections
85
- return self
86
-
87
- for self_subsec, other_subsec in zip(self.subsections, other.subsections, strict=True):
88
- self_subsec.update_from(other_subsec)
89
- return self
90
-
91
- def to_typst_code(self) -> str:
92
- """Converts the section into a Typst formatted code snippet.
93
-
94
- Returns:
95
- str: The formatted Typst code snippet.
96
- """
97
- return f"== {self.title}\n" + "\n\n".join(subsec.to_typst_code() for subsec in self.subsections)
98
-
99
-
100
- class ArticleChapter(ArticleMainBase, ChapterBase[ArticleSection]):
67
+ class ArticleChapter(ChapterBase[ArticleSection]):
101
68
  """Thematic progression implementing research function."""
102
69
 
103
- def resolve_update_error(self, other: Self) -> str:
104
- """Resolve update errors in the article outline."""
105
- if (s_len := len(self.sections)) == 0:
106
- return ""
107
-
108
- if s_len != len(other.sections):
109
- return f"Sections length mismatched, expected {len(self.sections)}, got {len(other.sections)}"
110
- sec_err_seq = [
111
- out for s, o in zip(self.sections, other.sections, strict=True) if (out := s.resolve_update_error(o))
112
- ]
113
- if sec_err_seq:
114
- return "\n".join(sec_err_seq)
115
- return ""
116
-
117
- def _update_from_inner(self, other: Self) -> Self:
118
- """Updates the current instance with the attributes of another instance."""
119
- if len(self.sections) == 0:
120
- self.sections = other.sections
121
- return self
122
-
123
- for self_sec, other_sec in zip(self.sections, other.sections, strict=True):
124
- self_sec.update_from(other_sec)
125
- return self
126
-
127
- def to_typst_code(self) -> str:
128
- """Converts the chapter into a Typst formatted code snippet for rendering."""
129
- return f"= {self.title}\n" + "\n\n".join(sec.to_typst_code() for sec in self.sections)
130
-
131
70
 
132
- class Article(Display, CensoredAble, WithRef[ArticleOutline], PersistentAble, ArticleBase[ArticleChapter]):
71
+ class Article(
72
+ Display,
73
+ CensoredAble,
74
+ WithRef[ArticleOutline],
75
+ PersistentAble,
76
+ ArticleBase[ArticleChapter],
77
+ ):
133
78
  """Represents a complete academic paper specification, incorporating validation constraints.
134
79
 
135
80
  This class integrates display, censorship processing, article structure referencing, and persistence capabilities,
136
81
  aiming to provide a comprehensive model for academic papers.
137
82
  """
138
83
 
139
- abstract: str
140
- """Contains a summary of the academic paper."""
141
-
142
- title: str
143
- """Represents the title of the academic paper."""
144
-
145
- language: str
146
- """Written language of the article. SHALL be aligned to the language of the article outline provided."""
147
-
148
- def finalized_dump(self) -> str:
149
- """Exports the article in `typst` format.
150
-
151
- Returns:
152
- str: Strictly formatted outline with typst formatting.
153
- """
154
- return "\n\n".join(c.to_typst_code() for c in self.chapters)
84
+ @override
85
+ def iter_subsections(self) -> Generator[Tuple[ArticleChapter, ArticleSection, ArticleSubsection], None, None]:
86
+ return super().iter_subsections()
155
87
 
156
88
  @classmethod
157
89
  def from_outline(cls, outline: ArticleOutline) -> "Article":
@@ -164,7 +96,7 @@ class Article(Display, CensoredAble, WithRef[ArticleOutline], PersistentAble, Ar
164
96
  Article: The generated article.
165
97
  """
166
98
  # Set the title from the outline
167
- article = Article(**outline.model_dump(include={"title", "abstract"}), chapters=[])
99
+ article = Article(**outline.model_dump(exclude={"chapters"}), chapters=[])
168
100
 
169
101
  for chapter in outline.chapters:
170
102
  # Create a new chapter
@@ -189,48 +121,25 @@ class Article(Display, CensoredAble, WithRef[ArticleOutline], PersistentAble, Ar
189
121
  article.chapters.append(article_chapter)
190
122
  return article
191
123
 
192
- def iter_dfs(self) -> Generator[ArticleMainBase, None, None]:
193
- """Performs a depth-first search (DFS) through the article structure.
194
-
195
- Returns:
196
- Generator[ArticleMainBase]: Each component in the article structure.
197
- """
198
- for chap in self.chapters:
199
- for sec in chap.sections:
200
- yield from sec.subsections
201
- yield sec
202
- yield chap
203
-
204
- def deref(self, ref: ArticleRef) -> ArticleMainBase:
205
- """Resolves a reference to the corresponding section or subsection in the article.
206
-
207
- Args:
208
- ref (ArticleRef): The reference to resolve.
209
-
210
- Returns:
211
- ArticleMainBase: The corresponding section or subsection.
212
- """
213
- return ok(ref.deref(self), f"{ref} not found in {self.title}")
214
-
215
- def gather_dependencies(self, article: ArticleMainBase) -> List[ArticleMainBase]:
124
+ def gather_dependencies(self, article: ArticleOutlineBase) -> List[ArticleOutlineBase]:
216
125
  """Gathers dependencies for all sections and subsections in the article.
217
126
 
218
127
  This method should be called after the article is fully constructed.
219
128
  """
220
- depends = [self.deref(a) for a in article.depend_on]
129
+ depends = [ok(a.deref(self)) for a in article.depend_on]
221
130
 
222
131
  supports = []
223
- for a in self.iter_dfs():
224
- if article in {self.deref(b) for b in a.support_to}:
132
+ for a in self.iter_dfs_rev():
133
+ if article in {ok(b.deref(self)) for b in a.support_to}:
225
134
  supports.append(a)
226
135
 
227
136
  return list(set(depends + supports))
228
137
 
229
- def gather_dependencies_recursive(self, article: ArticleMainBase) -> List[ArticleMainBase]:
138
+ def gather_dependencies_recursive(self, article: ArticleOutlineBase) -> List[ArticleOutlineBase]:
230
139
  """Gathers all dependencies recursively for the given article.
231
140
 
232
141
  Args:
233
- article (ArticleMainBase): The article to gather dependencies for.
142
+ article (ArticleOutlineBase): The article to gather dependencies for.
234
143
 
235
144
  Returns:
236
145
  List[ArticleBase]: A list of all dependencies for the given article.
@@ -269,7 +178,7 @@ class Article(Display, CensoredAble, WithRef[ArticleOutline], PersistentAble, Ar
269
178
 
270
179
  def iter_dfs_with_deps(
271
180
  self, chapter: bool = True, section: bool = True, subsection: bool = True
272
- ) -> Generator[Tuple[ArticleMainBase, List[ArticleMainBase]], None, None]:
181
+ ) -> Generator[Tuple[ArticleOutlineBase, List[ArticleOutlineBase]], None, None]:
273
182
  """Iterates through the article in a depth-first manner, yielding each component and its dependencies.
274
183
 
275
184
  Args:
@@ -283,7 +192,7 @@ class Article(Display, CensoredAble, WithRef[ArticleOutline], PersistentAble, Ar
283
192
  if all((not chapter, not section, not subsection)):
284
193
  raise ValueError("At least one of chapter, section, or subsection must be True.")
285
194
 
286
- for component in self.iter_dfs():
195
+ for component in self.iter_dfs_rev():
287
196
  if not chapter and isinstance(component, ArticleChapter):
288
197
  continue
289
198
  if not section and isinstance(component, ArticleSection):
@@ -1,30 +1,25 @@
1
1
  """A module containing the ArticleOutline class, which represents the outline of an academic paper."""
2
2
 
3
- from typing import Generator, List, Optional, Tuple, Union
4
-
5
- import regex
6
3
  from fabricatio.models.extra.article_base import (
7
4
  ArticleBase,
8
- ArticleOutlineBase,
9
5
  ChapterBase,
10
6
  SectionBase,
11
7
  SubSectionBase,
12
8
  )
13
9
  from fabricatio.models.extra.article_proposal import ArticleProposal
14
10
  from fabricatio.models.generic import CensoredAble, Display, PersistentAble, WithRef
15
- from fabricatio.models.utils import ok
16
11
 
17
12
 
18
- class ArticleSubsectionOutline(ArticleOutlineBase, SubSectionBase):
13
+ class ArticleSubsectionOutline(SubSectionBase):
19
14
  """Atomic research component specification for academic paper generation."""
20
15
 
21
16
 
22
- class ArticleSectionOutline(ArticleOutlineBase, SectionBase[ArticleSubsectionOutline]):
23
- """A slightly more detailed research component specification for academic paper generation."""
17
+ class ArticleSectionOutline(SectionBase[ArticleSubsectionOutline]):
18
+ """A slightly more detailed research component specification for academic paper generation, Must contain subsections."""
24
19
 
25
20
 
26
- class ArticleChapterOutline(ArticleOutlineBase, ChapterBase[ArticleSectionOutline]):
27
- """Macro-structural unit implementing standard academic paper organization."""
21
+ class ArticleChapterOutline(ChapterBase[ArticleSectionOutline]):
22
+ """Macro-structural unit implementing standard academic paper organization. Must contain sections."""
28
23
 
29
24
 
30
25
  class ArticleOutline(
@@ -34,148 +29,4 @@ class ArticleOutline(
34
29
  PersistentAble,
35
30
  ArticleBase[ArticleChapterOutline],
36
31
  ):
37
- """Complete academic paper blueprint with hierarchical validation."""
38
-
39
- abstract: str
40
- """The abstract is a concise summary of the academic paper's main findings."""
41
-
42
- prospect: str
43
- """Consolidated research statement with four pillars:
44
- 1. Problem Identification: Current limitations
45
- 2. Methodological Response: Technical approach
46
- 3. Empirical Validation: Evaluation strategy
47
- 4. Scholarly Impact: Field contributions
48
- """
49
-
50
- title: str
51
- """Title of the academic paper."""
52
-
53
- language: str
54
- """Written language of the article. SHALL be aligned to the language of the article proposal provided."""
55
-
56
- def finalized_dump(self) -> str:
57
- """Generates standardized hierarchical markup for academic publishing systems.
58
-
59
- Implements ACL 2024 outline conventions with four-level structure:
60
- = Chapter Title (Level 1)
61
- == Section Title (Level 2)
62
- === Subsection Title (Level 3)
63
- ==== Subsubsection Title (Level 4)
64
-
65
- Returns:
66
- str: Strictly formatted outline with academic sectioning
67
-
68
- Example:
69
- = Methodology
70
- == Neural Architecture Search Framework
71
- === Differentiable Search Space
72
- ==== Constrained Optimization Parameters
73
- === Implementation Details
74
- == Evaluation Protocol
75
- """
76
- lines: List[str] = []
77
- for i, chapter in enumerate(self.chapters, 1):
78
- lines.append(f"= Chapter {i}: {chapter.title}")
79
- for j, section in enumerate(chapter.sections, 1):
80
- lines.append(f"== {i}.{j} {section.title}")
81
- for k, subsection in enumerate(section.subsections, 1):
82
- lines.append(f"=== {i}.{j}.{k} {subsection.title}")
83
- return "\n".join(lines)
84
-
85
- def iter_dfs(self) -> Generator[ArticleOutlineBase, None, None]:
86
- """Iterates through the article outline in a depth-first manner.
87
-
88
- Returns:
89
- ArticleOutlineBase: Each component in the article outline.
90
- """
91
- for chapter in self.chapters:
92
- for section in chapter.sections:
93
- yield from section.subsections
94
- yield section
95
- yield chapter
96
-
97
- def resolve_ref_error(self) -> str:
98
- """Resolve reference errors in the article outline.
99
-
100
- Returns:
101
- str: Error message indicating reference errors in the article outline.
102
-
103
- Notes:
104
- This function is designed to find all invalid `ArticleRef` objs in `depend_on` and `support_to` fields, which will be added to the final error summary.
105
- """
106
- summary = ""
107
- for component in self.iter_dfs():
108
- for ref in component.depend_on:
109
- if not ref.deref(self):
110
- summary += f"Invalid internal reference in {component.__class__.__name__} titled `{component.title}` at `depend_on` field, because the referred {ref.referring_type} is not exists within the article, see the original obj dump: {ref.model_dump()}\n"
111
- for ref in component.support_to:
112
- if not ref.deref(self):
113
- summary += f"Invalid internal reference in {component.__class__.__name__} titled `{component.title}` at `support_to` field, because the referred {ref.referring_type} is not exists within the article, see the original obj dump: {ref.model_dump()}\n"
114
-
115
- return summary
116
-
117
- @classmethod
118
- def from_typst_code(
119
- cls, typst_code: str, title: str = "", article_language: str = "en", prospect: str = "", abstract: str = ""
120
- ) -> "ArticleOutline":
121
- """Parses a Typst code string and creates an ArticleOutline instance."""
122
- self = cls(language=article_language, prospect=prospect, abstract=abstract, chapters=[], title=title)
123
- stack = [self] # 根节点为ArticleOutline实例
124
-
125
- for line in typst_code.splitlines():
126
- parsed = cls._parse_line(line)
127
- if not parsed:
128
- continue
129
- level, title = parsed
130
- cls._adjust_stack(stack, level)
131
- parent = stack[-1]
132
- component = cls._create_component(level, title)
133
- cls._add_to_parent(parent, component, level)
134
- stack.append(component)
135
-
136
- return self
137
-
138
- @classmethod
139
- def _parse_line(cls, line: str) -> Optional[Tuple[int, str]]:
140
- stripped = line.strip()
141
- if not stripped.startswith("="):
142
- return None
143
- match = regex.match(r"^(\=+)(.*)", stripped)
144
- if not match:
145
- return None
146
- eqs, title_part = match.groups()
147
- return len(eqs), title_part.strip()
148
-
149
- @classmethod
150
- def _adjust_stack(cls, stack: List[object], target_level: int) -> None:
151
- while len(stack) > target_level:
152
- stack.pop()
153
-
154
- @classmethod
155
- def _create_component(cls, level: int, title: str) -> ArticleOutlineBase:
156
- default_kwargs = {
157
- "writing_aim": [],
158
- "depend_on": [],
159
- "support_to": [],
160
- "description": [],
161
- }
162
- component_map = {
163
- 1: lambda: ArticleChapterOutline(title=title, sections=[], **default_kwargs),
164
- 2: lambda: ArticleSectionOutline(title=title, subsections=[], **default_kwargs),
165
- 3: lambda: ArticleSubsectionOutline(title=title, **default_kwargs),
166
- }
167
- return ok(component_map.get(level, lambda: None)(), "Invalid level")
168
-
169
- @classmethod
170
- def _add_to_parent(
171
- cls,
172
- parent: Union["ArticleOutline", ArticleChapterOutline, ArticleSectionOutline],
173
- component: ArticleOutlineBase,
174
- level: int,
175
- ) -> None:
176
- if level == 1 and isinstance(component, ArticleChapterOutline):
177
- parent.chapters.append(component)
178
- elif level == 2 and isinstance(component, ArticleSectionOutline): # noqa: PLR2004
179
- parent.sections.append(component)
180
- elif level == 3 and isinstance(component, ArticleSubsectionOutline): # noqa: PLR2004
181
- parent.subsections.append(component)
32
+ """Outline of an academic paper, containing chapters, sections, subsections."""
@@ -11,25 +11,23 @@ class ArticleProposal(CensoredAble, Display, WithRef[str], AsPrompt, PersistentA
11
11
  Guides LLM in generating comprehensive research proposals with clearly defined components.
12
12
  """
13
13
 
14
+ language: str
15
+ """The language in which the article is written. This should align with the language specified in the article briefing."""
16
+
17
+ title: str
18
+ """The title of the academic paper, formatted in Title Case."""
19
+
20
+ focused_problem: List[str]
21
+ """A list of specific research problems or questions that the paper aims to address."""
22
+
14
23
  technical_approaches: List[str]
15
- """Technical approaches"""
24
+ """A list of technical approaches or methodologies used to solve the research problems."""
16
25
 
17
26
  research_methods: List[str]
18
- """Methodological components (list of techniques/tools).
19
- Example: ['Differentiable architecture search', 'Transformer-based search space', 'Multi-lingual perplexity evaluation']"""
27
+ """A list of methodological components, including techniques and tools utilized in the research."""
20
28
 
21
29
  research_aim: List[str]
22
- """Primary research objectives (list of 2-4 measurable goals).
23
- Example: ['Develop parameter-efficient NAS framework', 'Establish cross-lingual architecture transfer metrics']"""
24
-
25
- focused_problem: List[str]
26
- """Specific research problem(s) or question(s) addressed (list of 1-3 concise statements).
27
- Example: ['NAS computational overhead in low-resource settings', 'Architecture transferability across language pairs']"""
28
-
29
- title: str
30
- """Paper title in academic style (Title Case, 8-15 words). Example: 'Exploring Neural Architecture Search for Low-Resource Machine Translation'"""
31
- language: str
32
- """Written language of the article. SHALL be aligned to the language of the article briefing provided."""
30
+ """A list of primary research objectives that the paper seeks to achieve."""
33
31
 
34
32
  def _as_prompt_inner(self) -> Dict[str, str]:
35
33
  return {"ArticleBriefing": self.referenced, "ArticleProposal": self.display()}
@@ -1,6 +1,6 @@
1
1
  """This module defines generic classes for models in the Fabricatio library."""
2
2
 
3
- from abc import abstractmethod
3
+ from abc import ABC, abstractmethod
4
4
  from pathlib import Path
5
5
  from typing import Any, Callable, Dict, Iterable, List, Optional, Self, Union, final, overload
6
6
 
@@ -95,7 +95,7 @@ class WithRef[T](Base):
95
95
  """Get the referenced object."""
96
96
  return ok(self._reference, "_reference is None")
97
97
 
98
- 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
99
99
  """Update the reference of the object."""
100
100
  if isinstance(reference, self.__class__):
101
101
  self._reference = reference.referenced
@@ -108,7 +108,7 @@ class PersistentAble(Base):
108
108
  """Class that provides a method to persist the object."""
109
109
 
110
110
  def persist(self, path: str | Path) -> Self:
111
- """Persist the object to a file.
111
+ """Persist the object to a file or directory.
112
112
 
113
113
  Args:
114
114
  path (str | Path): The path to save the object.
@@ -117,7 +117,7 @@ class PersistentAble(Base):
117
117
  Self: The current instance of the object.
118
118
  """
119
119
  p = Path(path)
120
- out = self.model_dump_json()
120
+ out = self.model_dump_json(indent=1)
121
121
  if p.is_dir():
122
122
  p.joinpath(f"{self.__class__.__name__}_{blake3_hash(out.encode())[:6]}.json").write_text(
123
123
  out, encoding="utf-8"
@@ -125,6 +125,7 @@ class PersistentAble(Base):
125
125
  return self
126
126
  p.mkdir(exist_ok=True, parents=True)
127
127
  p.write_text(out, encoding="utf-8")
128
+ logger.info(f"Persisted {self} to {p.as_posix()}")
128
129
  return self
129
130
 
130
131
  def from_persistent(self, path: str | Path) -> Self:
@@ -139,6 +140,61 @@ class PersistentAble(Base):
139
140
  return self.model_validate_json(Path(path).read_text(encoding="utf-8"))
140
141
 
141
142
 
143
+ class ModelHash(Base):
144
+ """Class that provides a hash value for the object."""
145
+
146
+ def __hash__(self) -> int:
147
+ """Calculates a hash value for the ArticleBase object based on its model_dump_json representation."""
148
+ return hash(self.model_dump_json())
149
+
150
+
151
+ class UpdateFrom(Base):
152
+ """Class that provides a method to update the object from another object."""
153
+
154
+ def update_pre_check(self, other: Self) -> Self:
155
+ """Pre-check for updating the object from another object."""
156
+ if not isinstance(other, self.__class__):
157
+ raise TypeError(f"Cannot update from a non-{self.__class__.__name__} instance.")
158
+
159
+ return self
160
+
161
+ @abstractmethod
162
+ def update_from_inner(self, other: Self) -> Self:
163
+ """Updates the current instance with the attributes of another instance."""
164
+
165
+ @final
166
+ def update_from(self, other: Self) -> Self:
167
+ """Updates the current instance with the attributes of another instance."""
168
+ return self.update_pre_check(other).update_from_inner(other)
169
+
170
+
171
+ class ResolveUpdateConflict(Base):
172
+ """Class that provides a method to update the object from another object."""
173
+
174
+ @abstractmethod
175
+ def resolve_update_conflict(self, other: Self) -> str:
176
+ """Resolve the update conflict between two objects.
177
+
178
+ Args:
179
+ other (Self): The other object to resolve the update conflict with.
180
+
181
+ Returns:
182
+ str: The resolved update conflict.
183
+ """
184
+
185
+
186
+ class Introspect(Base):
187
+ """Class that provides a method to introspect the object."""
188
+
189
+ @abstractmethod
190
+ def introspect(self) -> str:
191
+ """Internal introspection of the object.
192
+
193
+ Returns:
194
+ str: The internal introspection of the object.
195
+ """
196
+
197
+
142
198
  class WithBriefing(Named, Described):
143
199
  """Class that provides a briefing based on the name and description."""
144
200
 
@@ -173,20 +229,11 @@ class WithBriefing(Named, Described):
173
229
  raise TypeError(f"{system_msg_like} is not a dict or str")
174
230
 
175
231
 
176
- class ReverseGenerate(GenerateJsonSchema):
232
+ class UnsortGenerate(GenerateJsonSchema):
177
233
  """Class that provides a reverse JSON schema of the model."""
178
234
 
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)]
235
+ def sort(self, value: JsonSchemaValue, parent_key: str | None = None) -> JsonSchemaValue:
236
+ """Not sort."""
190
237
  return value
191
238
 
192
239
 
@@ -201,7 +248,7 @@ class WithFormatedJsonSchema(Base):
201
248
  str: The JSON schema of the model in a formatted string.
202
249
  """
203
250
  return orjson.dumps(
204
- cls.model_json_schema(schema_generator=ReverseGenerate),
251
+ cls.model_json_schema(schema_generator=UnsortGenerate),
205
252
  option=orjson.OPT_INDENT_2,
206
253
  ).decode()
207
254
 
@@ -261,6 +308,10 @@ class ProposedAble(CreateJsonObjPrompt, InstantiateFromString):
261
308
  """Class that provides a method to propose a JSON object based on the requirement."""
262
309
 
263
310
 
311
+ class ProposedUpdateAble(PersistentAble, UpdateFrom, ABC):
312
+ """Make the obj can be updated from the proposed obj in place."""
313
+
314
+
264
315
  class FinalizedDumpAble(Base):
265
316
  """Class that provides a method to finalize the dump of the object."""
266
317
 
@@ -392,7 +443,7 @@ class PrepareVectorization(Base):
392
443
  """
393
444
  max_length = max_length or configs.embedding.max_sequence_length
394
445
  chunk = self._prepare_vectorization_inner()
395
- if len(chunk) > max_length:
446
+ if max_length and len(chunk) > max_length:
396
447
  logger.error(err := f"Chunk exceeds maximum sequence length {max_length}.")
397
448
  raise ValueError(err)
398
449
 
@@ -475,7 +526,7 @@ class ScopedConfig(Base):
475
526
  """Fallback to another instance's attribute values if the current instance's attributes are None.
476
527
 
477
528
  Args:
478
- other (LLMUsage): Another instance from which to copy attribute values.
529
+ other (ScopedConfig): Another instance from which to copy attribute values.
479
530
 
480
531
  Returns:
481
532
  Self: The current instance, allowing for method chaining.
@@ -495,7 +546,7 @@ class ScopedConfig(Base):
495
546
  """Hold to another instance's attribute values if the current instance's attributes are None.
496
547
 
497
548
  Args:
498
- others (LLMUsage | Iterable[LLMUsage]): Another instance or iterable of instances from which to copy attribute values.
549
+ others (Union[ScopedConfig, Iterable[ScopedConfig]]): Another instance or iterable of instances from which to copy attribute values.
499
550
 
500
551
  Returns:
501
552
  Self: The current instance, allowing for method chaining.