lionagi 0.10.2__py3-none-any.whl → 0.10.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -141,7 +141,7 @@ class TomlFileAdapter(Adapter):
141
141
  dict | list[dict]
142
142
  The loaded data from file.
143
143
  """
144
- with open(obj, "r", encoding="utf-8") as f:
144
+ with open(obj, encoding="utf-8") as f:
145
145
  result = toml.load(f, **kwargs)
146
146
 
147
147
  # Handle array of tables in TOML for "many" case
@@ -1,7 +1,4 @@
1
- from .action import (
2
- ActionRequestModel,
3
- ActionResponseModel,
4
- )
1
+ from .action import ActionRequestModel, ActionResponseModel
5
2
  from .base import (
6
3
  CodeSnippet,
7
4
  Outline,
@@ -10,11 +7,8 @@ from .base import (
10
7
  Source,
11
8
  TextSnippet,
12
9
  )
13
- from .file import CodeFile, Documentation, File
14
- from .instruct import (
15
- Instruct,
16
- InstructResponse,
17
- )
10
+ from .file import Documentation, File, Module, ResearchSummary
11
+ from .instruct import Instruct, InstructResponse
18
12
  from .reason import Reason
19
13
 
20
14
  __all__ = (
@@ -27,7 +21,8 @@ __all__ = (
27
21
  "OutlineItem",
28
22
  "Outline",
29
23
  "File",
30
- "CodeFile",
24
+ "Module",
25
+ "ResearchSummary",
31
26
  "Documentation",
32
27
  "Instruct",
33
28
  "InstructResponse",
lionagi/fields/code.py ADDED
@@ -0,0 +1,236 @@
1
+ from enum import Enum
2
+
3
+ from pydantic import Field
4
+
5
+ from lionagi.models import HashableModel
6
+
7
+ __all__ = (
8
+ "ParameterKind",
9
+ "Parameter",
10
+ "Decorator",
11
+ "Import",
12
+ "Attribute",
13
+ "Function",
14
+ "Method",
15
+ "Class",
16
+ "Module",
17
+ )
18
+
19
+
20
+ class ParameterKind(str, Enum):
21
+ """
22
+ Distinguishes how a function/method parameter is used.
23
+ Primarily inspired by Python's param categories, but can be ignored by simpler languages.
24
+ Pay attention to the languege's own conventions for parameter handling.
25
+ """
26
+
27
+ POSITIONAL_ONLY = "positional_only" # E.g. Python's '/'-based params
28
+ POSITIONAL_OR_KEYWORD = "positional_or_keyword" # Default for many
29
+ VAR_POSITIONAL = "var_positional" # *args-like
30
+ KEYWORD_ONLY = "keyword_only" # Python's '*' marker
31
+ VAR_KEYWORD = "var_keyword" # **kwargs-like
32
+
33
+
34
+ class Parameter(HashableModel):
35
+ """
36
+ Represents one parameter in a function or method signature.
37
+ """
38
+
39
+ name: str = Field(
40
+ ...,
41
+ description="Exact identifier for the parameter (e.g., 'user_id', 'self', 'arg').",
42
+ )
43
+ type: str | None = Field(
44
+ default=None,
45
+ description=(
46
+ "Type annotation as a string (e.g., 'str', 'int', 'SomeClass'). None if untyped or not declared."
47
+ ),
48
+ )
49
+ default_value_repr: str | None = Field(
50
+ default=None,
51
+ description=(
52
+ "String representation of default value if present (e.g., 'None', '10', '\"hi\"'). "
53
+ "None if parameter is required with no default."
54
+ ),
55
+ )
56
+ kind: ParameterKind = Field(
57
+ default=ParameterKind.POSITIONAL_OR_KEYWORD,
58
+ description=(
59
+ "Parameter's calling convention category. 'positional_or_keyword' is typical if unspecified."
60
+ ),
61
+ )
62
+
63
+
64
+ class Decorator(HashableModel):
65
+ """
66
+ A decorator or annotation attached to a function, class, or method.
67
+ Common in Python (@deco), Java (@Override), .NET ([Attribute]), etc.
68
+ """
69
+
70
+ name: str = Field(
71
+ ...,
72
+ description="Decorator/annotation name (e.g., '@staticmethod', '[ApiController]', '@Override').",
73
+ )
74
+ arguments_repr: list[str] | None = Field(
75
+ default=None,
76
+ description=(
77
+ "If this decorator/annotation is called with arguments, provide them as a list of string expressions "
78
+ "(e.g., `['\"/home\"', 'methods=[\"GET\"]']`). None if no arguments."
79
+ ),
80
+ )
81
+
82
+
83
+ class Import(HashableModel):
84
+ """
85
+ Represents an import/using/include statement. Merges Python's 'import X' and 'from Y import Z' logic.
86
+ Other languages can interpret accordingly.
87
+ """
88
+
89
+ module: str | None = Field(
90
+ default=None,
91
+ description=(
92
+ "The module/package/namespace from which symbols are imported (e.g., 'os.path', 'java.util'). "
93
+ "None for a direct import statement like 'import X' if no sub-path is specified."
94
+ ),
95
+ )
96
+ name: str = Field(
97
+ ...,
98
+ description=(
99
+ "The symbol or module being imported (e.g., 'os', 'List', 'time', '*')."
100
+ ),
101
+ )
102
+ alias: str | None = Field(
103
+ default=None,
104
+ description="Alias name if used ('import X as Y'), else None.",
105
+ )
106
+ level: int = Field(
107
+ default=0,
108
+ description=(
109
+ "For Pythonic relative imports. Number of leading dots. 0 if absolute or not applicable."
110
+ ),
111
+ )
112
+
113
+
114
+ class Attribute(HashableModel):
115
+ """
116
+ A variable/constant/field at class or module level. Possibly static/final, with an initial value.
117
+ """
118
+
119
+ name: str = Field(
120
+ ...,
121
+ description="Identifier for this attribute/field (e.g., 'MAX_CONNECTIONS', 'version').",
122
+ )
123
+ type: str | None = Field(
124
+ default=None,
125
+ description="String type annotation if declared. None if untyped.",
126
+ )
127
+ initial_value_repr: str | None = Field(
128
+ default=None,
129
+ description="String representation of any initial value (e.g., '100', 'true', 'None'). None if uninitialized.",
130
+ )
131
+ is_static: bool = Field(
132
+ default=False,
133
+ description="True if this is a static (class-level) attribute. Otherwise instance-level or module-level.",
134
+ )
135
+ is_final: bool = Field(
136
+ default=False,
137
+ description="True if this attribute/field is read-only/const/final after initialization.",
138
+ )
139
+ visibility: str | None = Field(
140
+ default=None,
141
+ description="Optional access modifier (e.g., 'public', 'private', 'protected'). None if default or not applicable.",
142
+ )
143
+
144
+
145
+ class Function(HashableModel):
146
+ """
147
+ Represents a standalone function or procedure.
148
+ For methods (attached to classes), see 'Method' below.
149
+ """
150
+
151
+ name: str = Field(
152
+ ..., description="Function name identifier (e.g., 'process_data')."
153
+ )
154
+ parameters: list[Parameter] = Field(
155
+ default_factory=list,
156
+ description="Ordered list of Parameter objects for this function.",
157
+ )
158
+ return_type: str | None = Field(
159
+ default=None,
160
+ description="Return type string if declared. None if not declared or no explicit type.",
161
+ )
162
+ is_async: bool = Field(
163
+ default=False,
164
+ description="True if an 'async' function in languages that support it. Else False.",
165
+ )
166
+ docstring: str | None = Field(
167
+ default=None,
168
+ description="Documentation string or comment describing this function.",
169
+ )
170
+ decorators: list[Decorator] = Field(
171
+ default_factory=list,
172
+ description="List of decorators/annotations on this function (e.g., @staticmethod).",
173
+ )
174
+
175
+
176
+ class Method(Function):
177
+ """
178
+ A function bound to a class, including potential method-specific flags (static, abstract, etc.).
179
+ Inherits fields from 'Function.'
180
+ """
181
+
182
+ is_static: bool = Field(
183
+ default=False,
184
+ description="True if method is static (no instance or 'self' needed).",
185
+ )
186
+ is_classmethod: bool = Field(
187
+ default=False,
188
+ description="True if method is recognized as a class method (receives class as first arg).",
189
+ )
190
+ is_abstract: bool = Field(
191
+ default=False,
192
+ description="True if the method is abstract (no concrete implementation).",
193
+ )
194
+ visibility: str | None = Field(
195
+ default=None,
196
+ description="Access level like 'public', 'private', etc., if relevant to the language.",
197
+ )
198
+
199
+
200
+ class Class(HashableModel):
201
+ """
202
+ Represents a class, interface, or other composite type, with optional docstring, attributes, methods, etc.
203
+ """
204
+
205
+ name: str = Field(
206
+ ...,
207
+ description="Class/struct/interface name (e.g., 'UserRepository', 'MyDataClass').",
208
+ )
209
+ base_types: list[str] = Field(
210
+ default_factory=list,
211
+ description="List of parent classes or interfaces by name. Empty if none.",
212
+ )
213
+ is_abstract: bool = Field(
214
+ default=False,
215
+ description="True if this is an abstract class (cannot be instantiated directly).",
216
+ )
217
+ is_interface: bool = Field(
218
+ default=False,
219
+ description="True if this represents an interface definition rather than a concrete class.",
220
+ )
221
+ docstring: str | None = Field(
222
+ default=None,
223
+ description="Documentation for the class/interface, if any.",
224
+ )
225
+ decorators: list[Decorator] = Field(
226
+ default_factory=list,
227
+ description="Class-level decorators/annotations (e.g., @dataclass).",
228
+ )
229
+ attributes: list[Attribute] = Field(
230
+ default_factory=list,
231
+ description="Fields or properties declared at class level.",
232
+ )
233
+ methods: list[Method] = Field(
234
+ default_factory=list,
235
+ description="List of Method objects representing this class's methods.",
236
+ )
lionagi/fields/file.py CHANGED
@@ -1,27 +1,33 @@
1
+ from abc import abstractmethod
1
2
  from pathlib import Path
2
3
 
3
4
  from pydantic import Field, field_validator
4
5
 
5
6
  from .base import HashableModel, Source
7
+ from .code import Class, Function, Import
8
+ from .research import PotentialRisk, ResearchFinding
6
9
 
7
10
  __all__ = (
8
11
  "File",
9
- "CodeFile",
10
12
  "Documentation",
13
+ "ResearchSummary",
14
+ "Module",
11
15
  )
12
16
 
13
17
 
14
18
  class File(HashableModel):
15
19
  """
16
- Represents a generic file with an optional name, content, and brief description.
17
- Useful for capturing and validating metadata about any kind of file within a project.
20
+ Represents a generic file with an optional name, content, and brief
21
+ description. Useful for capturing and validating metadata about any
22
+ kind of file within a project.
18
23
  """
19
24
 
20
25
  file_name: str | None = Field(
21
26
  default=None,
22
27
  description=(
23
- "Provide the name of the file or its relative path in the project. "
24
- "If an absolute path is given, it will be converted to a string. "
28
+ "Provide the name of the file or its relative path in the "
29
+ "project. If an absolute path is given, it will be converted"
30
+ " to a string. "
25
31
  ),
26
32
  examples=[
27
33
  "session.py",
@@ -29,21 +35,12 @@ class File(HashableModel):
29
35
  "/absolute/path/to/my_file.txt",
30
36
  ],
31
37
  )
32
- content: str | None = Field(
33
- default=None,
34
- description=(
35
- "Paste or generate the full textual content of the file here. "
36
- "For example, this might include plain text, Markdown, or any other text format.\n"
37
- "Examples:\n"
38
- " - '# My Title\\nSome description...'\n"
39
- " - 'function greet() { return \"Hello\"; }'"
40
- ),
41
- )
42
38
  description: str | None = Field(
43
39
  default=None,
44
40
  description=(
45
- "Briefly explain the file's purpose or function within the project. "
46
- "This can be a short summary describing why this file exists or what it does.\n"
41
+ "Briefly explain the file's purpose or function within the "
42
+ "project. This can be a short summary describing why this "
43
+ "file is needed and/or what it does."
47
44
  ),
48
45
  examples=[
49
46
  "Manages user session logic for the LionAGI framework.",
@@ -57,40 +54,34 @@ class File(HashableModel):
57
54
  return str(value)
58
55
  return value
59
56
 
57
+ @abstractmethod
58
+ def render_content(
59
+ self,
60
+ header: str | None = None,
61
+ footer: str | None = None,
62
+ ) -> str:
63
+ pass
60
64
 
61
- class CodeFile(File):
62
- """
63
- Represents a code file with an identifiable programming language. Inherits
64
- from the generic File model but specializes for code-related content.
65
- """
65
+ def persist(
66
+ self,
67
+ directory: Path | str,
68
+ overwrite: bool = True,
69
+ timestamp: bool = False,
70
+ random_hash_digits: int = None,
71
+ header: str | None = None,
72
+ footer: str | None = None,
73
+ ) -> Path:
74
+ from lionagi.utils import create_path
66
75
 
67
- language: str | None = Field(
68
- default=None,
69
- description=(
70
- "Indicate the programming language of this code file. "
71
- "LLMs or humans can use this info to apply specific formatting or syntax analysis."
72
- ),
73
- examples=[
74
- "python",
75
- "json",
76
- "typescript",
77
- "html",
78
- "css",
79
- "java",
80
- "cpp",
81
- ],
82
- )
83
- content: str | None = Field(
84
- default=None,
85
- description=(
86
- "Provide or generate the **full source code**. This should be the primary text content "
87
- "of the code file, including all function/class definitions.\n"
88
- ),
89
- examples=[
90
- 'def my_function():\\n print("Hello, world!")',
91
- 'export function greet(): string { return "Hello"; }',
92
- ],
93
- )
76
+ fp = create_path(
77
+ directory=directory,
78
+ filename=self.file_name,
79
+ file_exist_ok=overwrite,
80
+ timestamp=timestamp,
81
+ random_hash_digits=random_hash_digits,
82
+ )
83
+ fp.write_text(self.render_content(header=header, footer=footer))
84
+ return fp
94
85
 
95
86
 
96
87
  class Documentation(File):
@@ -113,10 +104,6 @@ class Documentation(File):
113
104
  "Provide the primary Markdown (or similar) content for the documentation. "
114
105
  "This can include headings, bullet points, tables, code snippets, etc.\n"
115
106
  ),
116
- examples=[
117
- "# Getting Started\\nThis guide walks you through ...",
118
- "# API Reference\\n## Session Class\\n...",
119
- ],
120
107
  )
121
108
  sources: list[Source] | None = Field(
122
109
  default=None,
@@ -126,5 +113,119 @@ class Documentation(File):
126
113
  ),
127
114
  )
128
115
 
116
+ def render_content(
117
+ self,
118
+ header: str | None = None,
119
+ footer: str | None = None,
120
+ include_source: bool = True,
121
+ ) -> str:
122
+ """
123
+ Renders the documentation content, optionally including citations for sources.
124
+ """
125
+ footer = footer or ""
126
+ if include_source and self.sources:
127
+ footer = "\n\n## Sources\n"
128
+ for source in self.sources:
129
+ footer += f"- [{source.title}]({source.url})\n"
130
+ footer += f" - {source.note}\n" if source.note else ""
131
+ return (header or "") + self.content + footer
132
+
133
+
134
+ class ResearchSummary(Documentation):
135
+ """
136
+ Captures the final outcome of the deep research process.
137
+ """
138
+
139
+ scope: str | None = Field(
140
+ default=None,
141
+ description="Brief statement of what was investigated. E.g., 'Surveyed python-based ORMs.'",
142
+ )
143
+ main_takeaways: str = Field(
144
+ ...,
145
+ description="High-level summary of the most critical insights for the project.",
146
+ )
147
+ findings: list[ResearchFinding] = Field(
148
+ default_factory=list,
149
+ description="List of key facts or knowledge gained.",
150
+ )
151
+ risks: list[PotentialRisk] = Field(
152
+ default_factory=list,
153
+ description="Identified obstacles or concerns for the project.",
154
+ )
155
+
156
+ def render_content(
157
+ self,
158
+ header: str | None = None,
159
+ footer: str | None = None,
160
+ ) -> str:
161
+ """
162
+ Renders the documentation content, optionally including citations for sources.
163
+ """
164
+ content = self.model_dump(exclude_unset=True, exclude_none=True)
165
+
166
+ from lionagi.libs.schema.as_readable import as_readable
167
+
168
+ text = as_readable(content, md=True, format_curly=True)
169
+
170
+ footer = footer or ""
171
+ if self.sources:
172
+ footer = "\n\n## Sources\n"
173
+ for source in self.sources:
174
+ footer += f"- [{source.title}]({source.url})\n"
175
+ footer += f" - {source.note}\n" if source.note else ""
176
+ return (header or "") + text + footer
177
+
178
+
179
+ class Module(File):
180
+ """
181
+ Represents a single source file: docstring, imports, top-level functions, classes, etc.
182
+ """
183
+
184
+ name: str = Field(
185
+ ...,
186
+ description="Logical name for this file/module (e.g., 'utils', 'main', 'data_models').",
187
+ )
188
+ path: str | None = Field(
189
+ default=None,
190
+ description="Filesystem path if known (e.g., 'src/utils.py').",
191
+ )
192
+ docstring: str | None = Field(
193
+ default=None, description="File-level docstring or comments if any."
194
+ )
195
+ imports: list[Import] = Field(
196
+ default_factory=list,
197
+ description="All import statements / using directives / includes in this file.",
198
+ )
199
+ classes: list[Class] = Field(
200
+ default_factory=list,
201
+ description="All class or interface definitions in this file.",
202
+ )
203
+ functions: list[Function] = Field(
204
+ default_factory=list,
205
+ description="All top-level (non-class) functions in this file.",
206
+ )
207
+ variables: list = Field(
208
+ default_factory=list,
209
+ description="All top-level variables/constants in this file.",
210
+ )
211
+ language: str = Field(
212
+ default_factory=str,
213
+ description=(
214
+ "Indicate the programming language of this code file. e.g., 'python', 'typescript'. "
215
+ "LLMs or humans can use this info to apply specific formatting or syntax analysis."
216
+ ),
217
+ )
218
+
219
+ def render_content(
220
+ self,
221
+ header: str | None = None,
222
+ footer: str | None = None,
223
+ ) -> str:
224
+ """
225
+ Renders the documentation content, optionally including citations for sources.
226
+ """
227
+ text = self.model_dump_json(exclude_none=True, exclude_unset=True)
228
+ return header or "" + text + footer or ""
229
+
129
230
 
130
231
  # File: lionagi/fields/file.py
lionagi/fields/reason.py CHANGED
@@ -2,15 +2,15 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from pydantic import BaseModel, Field, field_validator
5
+ from pydantic import Field, field_validator
6
6
 
7
- from lionagi.models import FieldModel
7
+ from lionagi.models import FieldModel, HashableModel
8
8
  from lionagi.utils import to_num
9
9
 
10
10
  __all__ = ("Reason",)
11
11
 
12
12
 
13
- class Reason(BaseModel):
13
+ class Reason(HashableModel):
14
14
 
15
15
  title: str | None = None
16
16
  content: str | None = None
@@ -22,10 +22,9 @@ class Reason(BaseModel):
22
22
  "how well you've met user expectations. Use this guide:\n"
23
23
  " • 1.0: Highly confident\n"
24
24
  " • 0.8-1.0: Reasonably sure\n"
25
- " • 0.5-0.8: Re-check or refine\n"
26
- " • 0.0-0.5: Off track"
25
+ " • 0.5-0.8: Re-check, refine or backtrack\n"
26
+ " • 0.0-0.5: Off track, stop"
27
27
  ),
28
- examples=[0.821, 0.257, 0.923, 0.439],
29
28
  )
30
29
 
31
30
  @field_validator("confidence_score", mode="before")
@@ -0,0 +1,49 @@
1
+ from pydantic import Field
2
+
3
+ from lionagi.models import HashableModel
4
+
5
+ from .base import CodeSnippet, TextSnippet
6
+
7
+ __all__ = (
8
+ "ResearchFinding",
9
+ "PotentialRisk",
10
+ "ResearchSummary",
11
+ )
12
+
13
+
14
+ class ResearchFinding(HashableModel):
15
+ """
16
+ A single piece of information or insight from the research phase.
17
+ """
18
+
19
+ summary: str = Field(
20
+ ...,
21
+ description="Concise text describing the discovered fact, concept, or best practice.",
22
+ )
23
+ snippets: list[TextSnippet | CodeSnippet] = Field(
24
+ default_factory=list,
25
+ description="Ordered list of content snippets (text or code) that illustrate or support the finding.",
26
+ )
27
+ relevance: str | None = Field(
28
+ default=None,
29
+ description="Why this finding matters to the project. E.g., 'Helps solve concurrency issue.'",
30
+ )
31
+
32
+
33
+ class PotentialRisk(HashableModel):
34
+ """
35
+ Identifies a risk or challenge discovered during research.
36
+ """
37
+
38
+ description: str = Field(
39
+ ...,
40
+ description="Short text describing the risk. E.g., 'Scalability concerns with chosen DB'.",
41
+ )
42
+ impact: str | None = Field(
43
+ default=None,
44
+ description="Possible consequences if not mitigated. E.g., 'System slowdown, possible downtime.'",
45
+ )
46
+ mitigation_ideas: str | None = Field(
47
+ default=None,
48
+ description="Preliminary ways to reduce or handle this risk.",
49
+ )
@@ -31,7 +31,7 @@ class SynthlangFramework(Resource):
31
31
  import json
32
32
 
33
33
  fp = here / FRAMEWORK_PATH / "framework_options.json"
34
- with open(fp, "r", encoding="utf-8") as f:
34
+ with open(fp, encoding="utf-8") as f:
35
35
  return json.load(f)
36
36
 
37
37
  @classmethod
@@ -58,4 +58,4 @@ False = "⊭"
58
58
  "⧦⧦⧦" = "⧦"
59
59
  " " = "◻︎"
60
60
  "◻︎◻︎" = "◼︎"
61
- "###" = "#"
61
+ "###" = "#"
@@ -38,4 +38,4 @@ False = "⊭"
38
38
  "⧦⧦⧦" = "⧦"
39
39
  " " = "◻︎"
40
40
  "◻︎◻︎" = "◼︎"
41
- "###" = "#"
41
+ "###" = "#"
@@ -57,4 +57,4 @@ self = "自"
57
57
  Clone = "隆"
58
58
  clone = "隆"
59
59
  derive = "衍"
60
- "println!" = "印"
60
+ "println!" = "印"
@@ -4,34 +4,45 @@
4
4
 
5
5
  from typing import ClassVar, Literal
6
6
 
7
- from pydantic import BaseModel, Field
7
+ from pydantic import Field, field_validator
8
8
 
9
+ from lionagi.models import HashableModel
9
10
 
10
- class PlannedAction(BaseModel):
11
+
12
+ class PlannedAction(HashableModel):
11
13
  """
12
- Short descriptor for an upcoming action/tool invocation the LLM wants to perform.
13
- The model can hold multiple actions in a single round if needed.
14
+ Short descriptor for an upcoming action/tool invocation the LLM wants to
15
+ perform. The model can hold multiple actions in a single round if needed.
14
16
  """
15
17
 
16
- action_type: str = Field(
17
- ...,
18
- description="The name or type of tool/action to invoke (e.g., 'search_exa', 'reader_tool').",
18
+ action_type: str | None = Field(
19
+ default=None,
20
+ description=(
21
+ "The name or type of tool/action to invoke. "
22
+ "(e.g., 'search_exa', 'reader_tool')"
23
+ ),
19
24
  )
20
- description: str = Field(
21
- ...,
22
- description="A short explanation of why or what is intended to achieve with this action.",
25
+ description: str | None = Field(
26
+ default=None,
27
+ description=(
28
+ "A short description of the action to perform. "
29
+ "This should be a concise summary of what the action entails."
30
+ "Also include your rationale for this action, if applicable."
31
+ ),
23
32
  )
24
33
 
25
34
 
26
- class ReActAnalysis(BaseModel):
35
+ class ReActAnalysis(HashableModel):
27
36
  """
28
37
  Captures the ReAct chain-of-thought output each round:
29
38
  1) The LLM's 'analysis' (reasoning),
30
39
  2) A list of planned actions to perform before finalizing,
31
40
  3) Indication whether more expansions/rounds are needed,
32
41
  4) Additional tuning knobs: how to handle validation, how to execute actions, etc.
33
- Remember do not repeat yourself, and aim to use the most efficient way to achieve
34
- the goal to user's satisfaction.
42
+
43
+ Note:
44
+ - Retain from repeating yourself
45
+ - use the most efficient way to achieve the goal to user's satisfaction
35
46
  """
36
47
 
37
48
  # Standard ReAct strings for controlling expansions:
@@ -101,6 +112,16 @@ class ReActAnalysis(BaseModel):
101
112
  )
102
113
 
103
114
 
104
- class Analysis(BaseModel):
115
+ class Analysis(HashableModel):
116
+
117
+ answer: str | None = None
105
118
 
106
- answer: str
119
+ @field_validator("answer", mode="before")
120
+ def _validate_answer(cls, value):
121
+ if not value:
122
+ return None
123
+ if isinstance(value, str) and not value.strip():
124
+ return None
125
+ if not isinstance(value, str):
126
+ raise ValueError("Answer must be a non-empty string.")
127
+ return value.strip()
lionagi/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.10.2"
1
+ __version__ = "0.10.4"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.10.2
3
+ Version: 0.10.4
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -221,11 +221,11 @@ Classifier: Programming Language :: Python :: 3.13
221
221
  Requires-Python: >=3.10
222
222
  Requires-Dist: aiocache>=0.12.0
223
223
  Requires-Dist: aiohttp>=3.11.0
224
- Requires-Dist: jinja2>=3.1.0
224
+ Requires-Dist: jinja2>=3.0.0
225
225
  Requires-Dist: pandas>=2.0.0
226
226
  Requires-Dist: pillow>=10.0.0
227
227
  Requires-Dist: pydantic>=2.0.0
228
- Requires-Dist: python-dotenv>=1.0.1
228
+ Requires-Dist: python-dotenv>=1.1.0
229
229
  Requires-Dist: tiktoken>=0.8.0
230
230
  Requires-Dist: toml>=0.9.0
231
231
  Provides-Extra: llms
@@ -4,23 +4,25 @@ lionagi/_errors.py,sha256=JlBTFJnRWtVYcRxKb7fWFiJHLbykl1E19mSJ8sXYVxg,455
4
4
  lionagi/_types.py,sha256=iDdYewsP9rDrM7QY19_NDTcWUk7swp8vnGCrloHMtUM,53
5
5
  lionagi/settings.py,sha256=W52mM34E6jXF3GyqCFzVREKZrmnUqtZm_BVDsUiDI_s,1627
6
6
  lionagi/utils.py,sha256=uLTJKl7aTnFXV6ehA6zwiwEB7G2nQYKsO2pZ6mqFzUk,78908
7
- lionagi/version.py,sha256=A_AARqtxTOj_AQTpjpgOxNx-UOBio5wYFfZ2mrdMKfs,23
7
+ lionagi/version.py,sha256=fGZMaoPHZfTX9I4TDkr07gp-kj_1U_SD-gjQC_2flQs,23
8
8
  lionagi/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  lionagi/adapters/adapter.py,sha256=aW7s1OKAdxHd8HBv2UcThn-r2Q08EyArssNyFobMLuA,3357
10
10
  lionagi/adapters/json_adapter.py,sha256=EJj0Jev46ZhU3ZMnlYwyzN2rLxjLCVrMDpHkEuggBvk,4561
11
- lionagi/adapters/toml_adapter.py,sha256=WyfMDgp49jH0u_ksZ_vLxdnm6KTrYLIlWDo7GBWaST8,5446
11
+ lionagi/adapters/toml_adapter.py,sha256=XOx0Q41g9FoNVuGrce96ck3gxPo4G-3mwqSin5kGq9s,5441
12
12
  lionagi/adapters/types.py,sha256=CHfB39BSeyU11SDkXXkU_vzqy4v7kaR-2r0y6DYkhXc,660
13
13
  lionagi/adapters/pandas_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  lionagi/adapters/pandas_/csv_adapter.py,sha256=HWie6Jlt8nR-EVJC_zmCFilaWszLNuk7EWUp8Xvr-H8,2358
15
15
  lionagi/adapters/pandas_/excel_adapter.py,sha256=ZqRT2xF93NLKNyMp16ePNzwUN3ntNkUy1dO3nbsrfak,2287
16
16
  lionagi/adapters/pandas_/pd_dataframe_adapter.py,sha256=ULGZVhK5aaOuTrmFq4x5SiuDScYetyYYUHeL8Hh13Eg,2279
17
17
  lionagi/adapters/pandas_/pd_series_adapter.py,sha256=TX3cqFtgEip8JqVqkjdJYOu4PQGpW1yYU6POhvz8Jeg,1388
18
- lionagi/fields/__init__.py,sha256=kaKavoiVZ_S49DHr2uPzN3KiX5AHFsUs5JzWUJkbz4c,593
18
+ lionagi/fields/__init__.py,sha256=8oU7Vfk-fKiULFKqhM6VpJMqdZcVXPTM7twVfNDN_SQ,603
19
19
  lionagi/fields/action.py,sha256=iWSApCM77jS0Oc28lb7G601Etkp-yjx5U1hfI_FQgfA,5792
20
20
  lionagi/fields/base.py,sha256=5CJc7j8kTTWzXwpYzkSAFzx4BglABfx3AElIATKB7bg,3857
21
- lionagi/fields/file.py,sha256=gzR2rZF2rU76AJJLjdD6TUJCj9VKXPaAH_Ow4oCsTfQ,4124
21
+ lionagi/fields/code.py,sha256=TFym51obzaSfCmeRoHZJyBtjfDI4tvl9F-1sjFc9rMw,7713
22
+ lionagi/fields/file.py,sha256=DhQ_HE0RvTNzkvBGQHRgbMYSokDkzE8GEu814i6jw5Q,7297
22
23
  lionagi/fields/instruct.py,sha256=sMbCxEv0HQLa31JkJDmdrWWEzIfeKbcmN2hYOehz3Q0,4773
23
- lionagi/fields/reason.py,sha256=TY2zQbounGU4DGDhbBqBW-jJPuJHmcoePSCKLgJxaL0,1460
24
+ lionagi/fields/reason.py,sha256=3Ksz9_40dI-oQ9VtmpnYAmJdeDDIO-TwLDrf1ijbXGM,1438
25
+ lionagi/fields/research.py,sha256=2x6SFDwMSwzl4uHHUBbhT8mgwa49MsEy1NaUIb84MHU,1405
24
26
  lionagi/libs/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
25
27
  lionagi/libs/parse.py,sha256=JRS3bql0InHJqATnAatl-hQv4N--XXw4P77JHhTFnrc,1011
26
28
  lionagi/libs/file/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
@@ -58,20 +60,20 @@ lionagi/libs/token_transform/perplexity.py,sha256=tcVRjPBX3nuVqsoTkowCf6RBXuybO-
58
60
  lionagi/libs/token_transform/symbolic_compress_context.py,sha256=Nr4vSJSN6sUQgaA1QxHhidWH3pUG_5RnoYeLHjMsoLA,4603
59
61
  lionagi/libs/token_transform/synthlang.py,sha256=W6e-_265UXqVosM9X0TLKW53rNHvWCKhsWbVAop49Ac,259
60
62
  lionagi/libs/token_transform/types.py,sha256=4HgAfNDlJ_Hu18kLt59GHr_76eF3xLpNCTbOXlAYVlA,491
61
- lionagi/libs/token_transform/synthlang_/base.py,sha256=diDFrm-1Zf3PerKjODo-uFQMEjxPeaGtbZ5N1lK59Kg,4114
63
+ lionagi/libs/token_transform/synthlang_/base.py,sha256=GDle72c8EjFz_3hg_k-y0YmksBsn5TSRVTw5_cwfWTo,4109
62
64
  lionagi/libs/token_transform/synthlang_/translate_to_synthlang.py,sha256=lRBpeKGhyNlf8ngigjYAw56QbIAVZWLQUzRg2wpwMfQ,4956
63
65
  lionagi/libs/token_transform/synthlang_/resources/frameworks/abstract_algebra.toml,sha256=2TuOAo97g8mNhdPH96HP8vYZpnC8neiP-KlhVqbp1Us,970
64
66
  lionagi/libs/token_transform/synthlang_/resources/frameworks/category_theory.toml,sha256=Stg9W3h8o7VkQ9tdAfSZmR3LctFqcH6OhOPdaw9BlIg,1064
65
67
  lionagi/libs/token_transform/synthlang_/resources/frameworks/complex_analysis.toml,sha256=iE6FS7Cn5_uJRG5-StLuMM4XVAk95bxhbYWwlstw_tA,1044
66
- lionagi/libs/token_transform/synthlang_/resources/frameworks/framework_options.json,sha256=42I5bRegSUp-60LNWa7k6eXurdWf8aCemhrFqw2s7qc,1759
68
+ lionagi/libs/token_transform/synthlang_/resources/frameworks/framework_options.json,sha256=phAkedPGrwgNGW8hgPyH6pKU47pvKEAnG7vheWFvOLc,1760
67
69
  lionagi/libs/token_transform/synthlang_/resources/frameworks/group_theory.toml,sha256=iVlcS250YMosNRv3l8bz3BT9Tx1xCmiwhfNt4CjjRYc,713
68
70
  lionagi/libs/token_transform/synthlang_/resources/frameworks/math_logic.toml,sha256=jeFOF8gjRhb4hYXpW7AxTX8uk9c6DvGulJK5Bowxhq4,1037
69
71
  lionagi/libs/token_transform/synthlang_/resources/frameworks/reflective_patterns.toml,sha256=LxBIVLHNLfvVdXjLAzqivrYaHNix514DLNYsbA-VSQ4,5730
70
72
  lionagi/libs/token_transform/synthlang_/resources/frameworks/set_theory.toml,sha256=SZpBvUySZ3_0pIrRko24a3KfbPHd55LyNwzFHyznjs4,1457
71
73
  lionagi/libs/token_transform/synthlang_/resources/frameworks/topology_fundamentals.toml,sha256=nnhfbIJQ5pTGlX7lo1XzjyOevaZOHuusvBuhwWHzbLk,1008
72
- lionagi/libs/token_transform/synthlang_/resources/mapping/lion_emoji_mapping.toml,sha256=CPbqoh691wfZ3Xe49iLEWGJoaIbRUyDgn2_bFlvH72E,1322
73
- lionagi/libs/token_transform/synthlang_/resources/mapping/python_math_mapping.toml,sha256=3ElxIfm7Kn_f8n6fHDENhC29Z3IlofUXjwNTEAjRQMQ,963
74
- lionagi/libs/token_transform/synthlang_/resources/mapping/rust_chinese_mapping.toml,sha256=IU5qOB-a_ZJI_wMOa0OJu3foAp6tIdvegnVt-yw5URM,1216
74
+ lionagi/libs/token_transform/synthlang_/resources/mapping/lion_emoji_mapping.toml,sha256=THLrry9RTHMCMv-g6VCwrlaE4_9_fjXkABgyAyhokew,1323
75
+ lionagi/libs/token_transform/synthlang_/resources/mapping/python_math_mapping.toml,sha256=Q0MqTf9t5rWuKHLsKu9WS8NSBSb9FsGAAaG5EYQiGCA,964
76
+ lionagi/libs/token_transform/synthlang_/resources/mapping/rust_chinese_mapping.toml,sha256=o-7KACVDQYkpAGSFgsMCeIy_S93CilUP9w1ZKM0w62A,1217
75
77
  lionagi/libs/token_transform/synthlang_/resources/utility/base_synthlang_system_prompt.toml,sha256=8xhY14WdDRF6GIToqzRPM7EjM6-uO6-hQ9Muei1A2Iw,3458
76
78
  lionagi/libs/validate/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
77
79
  lionagi/libs/validate/common_field_validators.py,sha256=1BHznXnJYcLQrHqvHKUnP6aqCptuQ0qN7KJRCExcJBU,4778
@@ -92,7 +94,7 @@ lionagi/operations/types.py,sha256=fM8HphnbBifMzhoKKvdl3JxGCBHlEGPJEYkLWj9b7vE,7
92
94
  lionagi/operations/utils.py,sha256=Cl4HuWQ1nCGkTexwOtDx7fpEWMc2L3ZQMCqylRBDy74,1219
93
95
  lionagi/operations/ReAct/ReAct.py,sha256=uoJnFMoPP1kzzmgLDFNBwEbWdfGNfG37IT22N1AM-hE,13504
94
96
  lionagi/operations/ReAct/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
95
- lionagi/operations/ReAct/utils.py,sha256=84Giel5ToqfbN5F6Tm0uw8yZTTnxiM_jWuFEhnKOxM8,3800
97
+ lionagi/operations/ReAct/utils.py,sha256=w8hf8-L1VCV5ZF8gjeFBfR81tmO9u2Ud2Wz3VlUn7AU,4437
96
98
  lionagi/operations/_act/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
97
99
  lionagi/operations/_act/act.py,sha256=l1-mrOoWLP0reATBD4PTqGyuSUSH41sL6YbfzzFfJMk,2811
98
100
  lionagi/operations/brainstorm/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
@@ -220,7 +222,7 @@ lionagi/tools/file/writer.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,
220
222
  lionagi/tools/file/providers/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
221
223
  lionagi/tools/file/providers/docling_.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
222
224
  lionagi/tools/query/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
223
- lionagi-0.10.2.dist-info/METADATA,sha256=Z0QWQpl1aCFgNhWCem5QNx5BJmYPOG_gXyDpiiLQW3E,18464
224
- lionagi-0.10.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
225
- lionagi-0.10.2.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
226
- lionagi-0.10.2.dist-info/RECORD,,
225
+ lionagi-0.10.4.dist-info/METADATA,sha256=NQTeKO05k_YvV-OvrUO3ZwOemMxHwvzqdidzxPeJJNk,18464
226
+ lionagi-0.10.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
227
+ lionagi-0.10.4.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
228
+ lionagi-0.10.4.dist-info/RECORD,,