lionagi 0.9.19__py3-none-any.whl → 0.10.0__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.
Files changed (95) hide show
  1. lionagi/__init__.py +0 -7
  2. lionagi/_types.py +0 -1
  3. lionagi/libs/fields/__init__.py +36 -0
  4. lionagi/libs/fields/action.py +190 -0
  5. lionagi/libs/fields/file.py +135 -0
  6. lionagi/{operatives/instruct → libs/fields}/instruct.py +9 -9
  7. lionagi/{operatives/instruct → libs/fields}/reason.py +28 -49
  8. lionagi/libs/schema/function_to_schema.py +1 -1
  9. lionagi/models/__init__.py +19 -0
  10. lionagi/models/hashable_model.py +24 -0
  11. lionagi/{operatives/models → models}/operable_model.py +2 -1
  12. lionagi/{operatives/models → models}/schema_model.py +1 -1
  13. lionagi/operations/ReAct/ReAct.py +2 -3
  14. lionagi/operations/_act/act.py +2 -7
  15. lionagi/operations/brainstorm/brainstorm.py +1 -1
  16. lionagi/operations/instruct/instruct.py +1 -1
  17. lionagi/operations/operate/operate.py +6 -5
  18. lionagi/operations/parse/parse.py +1 -1
  19. lionagi/operations/plan/plan.py +1 -1
  20. lionagi/operations/select/select.py +1 -1
  21. lionagi/operations/utils.py +1 -1
  22. lionagi/{operatives → protocols}/action/function_calling.py +4 -1
  23. lionagi/{operatives → protocols}/action/manager.py +2 -9
  24. lionagi/{operatives → protocols}/action/tool.py +1 -6
  25. lionagi/{operatives → protocols}/forms/base.py +8 -2
  26. lionagi/{operatives → protocols}/forms/flow.py +6 -1
  27. lionagi/{operatives → protocols}/forms/form.py +6 -1
  28. lionagi/{operatives → protocols}/forms/report.py +7 -3
  29. lionagi/protocols/generic/pile.py +9 -5
  30. lionagi/protocols/graph/node.py +8 -4
  31. lionagi/protocols/mail/exchange.py +0 -6
  32. lionagi/protocols/mail/mail.py +0 -6
  33. lionagi/protocols/mail/mailbox.py +0 -5
  34. lionagi/protocols/mail/manager.py +0 -5
  35. lionagi/protocols/mail/package.py +0 -6
  36. lionagi/protocols/messages/action_request.py +0 -6
  37. lionagi/protocols/messages/action_response.py +0 -5
  38. lionagi/protocols/messages/assistant_response.py +0 -4
  39. lionagi/protocols/messages/base.py +0 -6
  40. lionagi/protocols/messages/instruction.py +0 -5
  41. lionagi/protocols/messages/manager.py +0 -6
  42. lionagi/protocols/messages/message.py +0 -5
  43. lionagi/protocols/messages/system.py +0 -5
  44. lionagi/{operatives → protocols/operatives}/operative.py +1 -3
  45. lionagi/{operatives → protocols/operatives}/step.py +5 -7
  46. lionagi/protocols/types.py +36 -21
  47. lionagi/service/endpoints/base.py +1 -1
  48. lionagi/service/endpoints/rate_limited_processor.py +1 -1
  49. lionagi/service/providers/ollama_/chat_completions.py +2 -2
  50. lionagi/session/branch.py +9 -10
  51. lionagi/session/session.py +24 -8
  52. lionagi/tools/base.py +1 -1
  53. lionagi/tools/file/reader.py +1 -1
  54. lionagi/utils.py +0 -22
  55. lionagi/version.py +1 -1
  56. {lionagi-0.9.19.dist-info → lionagi-0.10.0.dist-info}/METADATA +1 -1
  57. {lionagi-0.9.19.dist-info → lionagi-0.10.0.dist-info}/RECORD +75 -90
  58. lionagi/operatives/action/request_response_model.py +0 -121
  59. lionagi/operatives/action/utils.py +0 -147
  60. lionagi/operatives/instruct/__init__.py +0 -3
  61. lionagi/operatives/instruct/base.py +0 -81
  62. lionagi/operatives/instruct/instruct_collection.py +0 -52
  63. lionagi/operatives/instruct/node.py +0 -13
  64. lionagi/operatives/instruct/prompts.py +0 -51
  65. lionagi/operatives/manager.py +0 -9
  66. lionagi/operatives/models/__init__.py +0 -3
  67. lionagi/operatives/strategies/__init__.py +0 -3
  68. lionagi/operatives/strategies/base.py +0 -56
  69. lionagi/operatives/strategies/concurrent.py +0 -75
  70. lionagi/operatives/strategies/concurrent_chunk.py +0 -46
  71. lionagi/operatives/strategies/concurrent_sequential_chunk.py +0 -108
  72. lionagi/operatives/strategies/params.py +0 -151
  73. lionagi/operatives/strategies/sequential.py +0 -27
  74. lionagi/operatives/strategies/sequential_chunk.py +0 -93
  75. lionagi/operatives/strategies/sequential_concurrent_chunk.py +0 -105
  76. lionagi/operatives/strategies/utils.py +0 -52
  77. lionagi/operatives/types.py +0 -72
  78. /lionagi/{protocols/adapters → adapters}/__init__.py +0 -0
  79. /lionagi/{protocols/adapters → adapters}/adapter.py +0 -0
  80. /lionagi/{protocols/adapters → adapters}/json_adapter.py +0 -0
  81. /lionagi/{protocols/adapters → adapters}/pandas_/__init__.py +0 -0
  82. /lionagi/{protocols/adapters → adapters}/pandas_/csv_adapter.py +0 -0
  83. /lionagi/{protocols/adapters → adapters}/pandas_/excel_adapter.py +0 -0
  84. /lionagi/{protocols/adapters → adapters}/pandas_/pd_dataframe_adapter.py +0 -0
  85. /lionagi/{protocols/adapters → adapters}/pandas_/pd_series_adapter.py +0 -0
  86. /lionagi/{protocols/adapters → adapters}/toml_adapter.py +0 -0
  87. /lionagi/{protocols/adapters → adapters}/types.py +0 -0
  88. /lionagi/{operatives/models → models}/field_model.py +0 -0
  89. /lionagi/{operatives/models → models}/model_params.py +0 -0
  90. /lionagi/{operatives/models → models}/note.py +0 -0
  91. /lionagi/{operatives → protocols/action}/__init__.py +0 -0
  92. /lionagi/{operatives/action → protocols/forms}/__init__.py +0 -0
  93. /lionagi/{operatives/forms → protocols/operatives}/__init__.py +0 -0
  94. {lionagi-0.9.19.dist-info → lionagi-0.10.0.dist-info}/WHEEL +0 -0
  95. {lionagi-0.9.19.dist-info → lionagi-0.10.0.dist-info}/licenses/LICENSE +0 -0
lionagi/__init__.py CHANGED
@@ -7,14 +7,10 @@ import logging
7
7
  from pydantic import BaseModel, Field
8
8
 
9
9
  from . import _types as types
10
- from .operations import types as op
11
- from .operatives import types as ops_types # deprecated
12
10
  from .service.imodel import iModel
13
11
  from .session.session import Branch, Session
14
12
  from .version import __version__
15
13
 
16
- LiteiModel = iModel
17
-
18
14
  logger = logging.getLogger(__name__)
19
15
  logger.setLevel(logging.INFO)
20
16
 
@@ -22,10 +18,7 @@ __all__ = (
22
18
  "Session",
23
19
  "Branch",
24
20
  "iModel",
25
- "LiteiModel",
26
21
  "types",
27
- "ops_types",
28
- "op",
29
22
  "__version__",
30
23
  "BaseModel",
31
24
  "Field",
lionagi/_types.py CHANGED
@@ -1,2 +1 @@
1
- from .operatives.types import *
2
1
  from .protocols.types import *
@@ -0,0 +1,36 @@
1
+ from .action import (
2
+ ACTION_REQUESTS_FIELD,
3
+ ACTION_REQUIRED_FIELD,
4
+ ACTION_RESPONSES_FIELD,
5
+ ActionRequestModel,
6
+ ActionResponseModel,
7
+ )
8
+ from .file import (
9
+ CODE_FILE_FIELD,
10
+ DOCUMENTATION_FIELD,
11
+ FILE_FIELD,
12
+ CodeFile,
13
+ Documentation,
14
+ File,
15
+ )
16
+ from .instruct import INSTRUCT_FIELD, Instruct, InstructResponse
17
+ from .reason import REASON_FIELD, Reason
18
+
19
+ __all__ = (
20
+ "ActionRequestModel",
21
+ "ActionResponseModel",
22
+ "ACTION_REQUESTS_FIELD",
23
+ "ACTION_REQUIRED_FIELD",
24
+ "ACTION_RESPONSES_FIELD",
25
+ "File",
26
+ "Documentation",
27
+ "CodeFile",
28
+ "CODE_FILE_FIELD",
29
+ "DOCUMENTATION_FIELD",
30
+ "FILE_FIELD",
31
+ "Instruct",
32
+ "InstructResponse",
33
+ "INSTRUCT_FIELD",
34
+ "Reason",
35
+ "REASON_FIELD",
36
+ )
@@ -0,0 +1,190 @@
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ import re
6
+ from typing import Any
7
+
8
+ from pydantic import BaseModel, Field, field_validator
9
+
10
+ from lionagi.libs.validate.common_field_validators import (
11
+ validate_boolean_field,
12
+ validate_nullable_string_field,
13
+ )
14
+ from lionagi.models import FieldModel, HashableModel
15
+ from lionagi.utils import to_dict, to_json, to_list
16
+
17
+ __all__ = (
18
+ "ActionRequestModel",
19
+ "ACTION_REQUESTS_FIELD",
20
+ "ActionResponseModel",
21
+ "ACTION_RESPONSES_FIELD",
22
+ )
23
+
24
+
25
+ def parse_action_request(content: str | dict) -> list[dict]:
26
+
27
+ json_blocks = []
28
+
29
+ if isinstance(content, BaseModel):
30
+ json_blocks = [content.model_dump()]
31
+
32
+ elif isinstance(content, str):
33
+ json_blocks = to_json(content, fuzzy_parse=True)
34
+ if not json_blocks:
35
+ pattern2 = r"```python\s*(.*?)\s*```"
36
+ _d = re.findall(pattern2, content, re.DOTALL)
37
+ json_blocks = [to_json(match, fuzzy_parse=True) for match in _d]
38
+ json_blocks = to_list(json_blocks, dropna=True)
39
+
40
+ print(json_blocks)
41
+
42
+ elif content and isinstance(content, dict):
43
+ json_blocks = [content]
44
+
45
+ if json_blocks and not isinstance(json_blocks, list):
46
+ json_blocks = [json_blocks]
47
+
48
+ out = []
49
+
50
+ for i in json_blocks:
51
+ j = {}
52
+ if isinstance(i, dict):
53
+ if "function" in i and isinstance(i["function"], dict):
54
+ if "name" in i["function"]:
55
+ i["function"] = i["function"]["name"]
56
+ for k, v in i.items():
57
+ k = (
58
+ k.replace("action_", "")
59
+ .replace("recipient_", "")
60
+ .replace("s", "")
61
+ )
62
+ if k in ["name", "function", "recipient"]:
63
+ j["function"] = v
64
+ elif k in ["parameter", "argument", "arg", "param"]:
65
+ j["arguments"] = to_dict(
66
+ v, str_type="json", fuzzy_parse=True, suppress=True
67
+ )
68
+ if (
69
+ j
70
+ and all(key in j for key in ["function", "arguments"])
71
+ and j["arguments"]
72
+ ):
73
+ out.append(j)
74
+
75
+ return out
76
+
77
+
78
+ class ActionRequestModel(HashableModel):
79
+ """
80
+ Captures a single action request, typically from a user or system message.
81
+ Includes the name of the function and the arguments to be passed.
82
+ """
83
+
84
+ function: str | None = Field(
85
+ None,
86
+ title="Function",
87
+ description=(
88
+ "Name of the function to call from the provided `tool_schemas`. "
89
+ "If no `tool_schemas` exist, set to None or leave blank. "
90
+ "Never invent new function names outside what's given."
91
+ ),
92
+ examples=["multiply", "create_user"],
93
+ )
94
+ arguments: dict[str, Any] | None = Field(
95
+ None,
96
+ title="Arguments",
97
+ description=(
98
+ "Dictionary of arguments for the chosen function. "
99
+ "Use only argument names/types defined in `tool_schemas`. "
100
+ "Never introduce extra argument names."
101
+ ),
102
+ )
103
+
104
+ @field_validator("arguments", mode="before")
105
+ def validate_arguments(cls, value: Any) -> dict[str, Any]:
106
+ """
107
+ Coerce arguments into a dictionary if possible, recursively.
108
+
109
+ Raises:
110
+ ValueError if the data can't be coerced.
111
+ """
112
+ return to_dict(
113
+ value,
114
+ fuzzy_parse=True,
115
+ recursive=True,
116
+ recursive_python_only=False,
117
+ )
118
+
119
+ @field_validator("function", mode="before")
120
+ def validate_function(cls, value: str) -> str:
121
+ """
122
+ Ensure the function name is a valid non-empty string (if provided).
123
+ """
124
+ return validate_nullable_string_field(cls, value, "function", False)
125
+
126
+ @classmethod
127
+ def create(cls, content: str):
128
+ """
129
+ Attempt to parse a string (usually from a conversation or JSON) into
130
+ one or more ActionRequestModel instances.
131
+
132
+ If no valid structure is found, returns an empty list.
133
+ """
134
+ try:
135
+ content = parse_action_request(content)
136
+ if content:
137
+ return [cls.model_validate(i) for i in content]
138
+ return []
139
+ except Exception:
140
+ return []
141
+
142
+
143
+ ACTION_REQUESTS_FIELD = FieldModel(
144
+ name="action_requests",
145
+ annotation=list[ActionRequestModel],
146
+ default_factory=list,
147
+ title="Actions",
148
+ description=(
149
+ "List of actions to be executed when `action_required` is true. "
150
+ "Each action must align with the available `tool_schemas`. "
151
+ "Leave empty if no actions are needed."
152
+ ),
153
+ )
154
+
155
+
156
+ class ActionResponseModel(HashableModel):
157
+ """
158
+ Encapsulates a function's output after being called. Typically
159
+ references the original function name, arguments, and the result.
160
+ """
161
+
162
+ function: str = Field(default_factory=str, title="Function")
163
+ arguments: dict[str, Any] = Field(default_factory=dict)
164
+ output: Any = None
165
+
166
+
167
+ ACTION_RESPONSES_FIELD = FieldModel(
168
+ name="action_responses",
169
+ annotation=list[ActionResponseModel],
170
+ default_factory=list,
171
+ title="Actions",
172
+ description="**do not fill**",
173
+ )
174
+
175
+
176
+ ACTION_REQUIRED_FIELD = FieldModel(
177
+ name="action_required",
178
+ annotation=bool,
179
+ default=False,
180
+ title="Action Required",
181
+ description=(
182
+ "Whether this step strictly requires performing actions. "
183
+ "If true, the requests in `action_requests` must be fulfilled, "
184
+ "assuming `tool_schemas` are available. "
185
+ "If false or no `tool_schemas` exist, actions are optional."
186
+ ),
187
+ validator=lambda cls, v: validate_boolean_field(cls, v, False),
188
+ validator_kwargs={"mode": "before"},
189
+ )
190
+ # File: lionagi/libs/fields/action.py
@@ -0,0 +1,135 @@
1
+ from pathlib import Path
2
+
3
+ from pydantic import BaseModel, Field, field_validator
4
+
5
+ from lionagi.models import FieldModel
6
+
7
+
8
+ class File(BaseModel):
9
+ """
10
+ Represents a generic file with an optional name, content, and brief description.
11
+ Useful for capturing and validating metadata about any kind of file within a project.
12
+ """
13
+
14
+ file_name: str | None = Field(
15
+ default=None,
16
+ description=(
17
+ "Provide the name of the file or its relative path in the project. "
18
+ "If an absolute path is given, it will be converted to a string. "
19
+ ),
20
+ examples=[
21
+ "session.py",
22
+ "src/components/UserCard.tsx",
23
+ "/absolute/path/to/my_file.txt",
24
+ ],
25
+ )
26
+ content: str | None = Field(
27
+ default=None,
28
+ description=(
29
+ "Paste or generate the full textual content of the file here. "
30
+ "For example, this might include plain text, Markdown, or any other text format.\n"
31
+ "Examples:\n"
32
+ " - '# My Title\\nSome description...'\n"
33
+ " - 'function greet() { return \"Hello\"; }'"
34
+ ),
35
+ )
36
+ description: str | None = Field(
37
+ default=None,
38
+ description=(
39
+ "Briefly explain the file's purpose or function within the project. "
40
+ "This can be a short summary describing why this file exists or what it does.\n"
41
+ ),
42
+ examples=[
43
+ "Manages user session logic for the LionAGI framework.",
44
+ "Contains CSS styles for the navbar component.",
45
+ ],
46
+ )
47
+
48
+ @field_validator("file_name", mode="before")
49
+ def validate_file_name(cls, value):
50
+ if isinstance(value, Path):
51
+ return str(value)
52
+ return value
53
+
54
+
55
+ class CodeFile(File):
56
+ """
57
+ Represents a code file with an identifiable programming language. Inherits
58
+ from the generic File model but specializes for code-related content.
59
+ """
60
+
61
+ language: str | None = Field(
62
+ default=None,
63
+ description=(
64
+ "Indicate the programming language of this code file. "
65
+ "LLMs or humans can use this info to apply specific formatting or syntax analysis."
66
+ ),
67
+ examples=[
68
+ "python",
69
+ "json",
70
+ "typescript",
71
+ "html",
72
+ "css",
73
+ "java",
74
+ "cpp",
75
+ ],
76
+ )
77
+ content: str | None = Field(
78
+ default=None,
79
+ description=(
80
+ "Provide or generate the **full source code**. This should be the primary text content "
81
+ "of the code file, including all function/class definitions.\n"
82
+ ),
83
+ examples=[
84
+ 'def my_function():\\n print("Hello, world!")',
85
+ 'export function greet(): string { return "Hello"; }',
86
+ ],
87
+ )
88
+
89
+
90
+ class Documentation(File):
91
+ """
92
+ Represents a documentation file, typically Markdown-based, that includes
93
+ a title and main content explaining or describing some aspect of the project.
94
+ """
95
+
96
+ title: str = Field(
97
+ default_factory=str,
98
+ description=(
99
+ "Specify the title of this documentation entry or page. "
100
+ "For instance, this might be the top-level heading in a Markdown file.\n"
101
+ ),
102
+ examples=["Getting Started", "API Reference: LionAGI Session Module"],
103
+ )
104
+ content: str = Field(
105
+ default_factory=str,
106
+ description=(
107
+ "Provide the primary Markdown (or similar) content for the documentation. "
108
+ "This can include headings, bullet points, tables, code snippets, etc.\n"
109
+ ),
110
+ examples=[
111
+ "# Getting Started\\nThis guide walks you through ...",
112
+ "# API Reference\\n## Session Class\\n...",
113
+ ],
114
+ )
115
+
116
+
117
+ FILE_FIELD = FieldModel(
118
+ name="file",
119
+ annotation=File | None,
120
+ default=None,
121
+ )
122
+
123
+ CODE_FILE_FIELD = FieldModel(
124
+ name="code_file",
125
+ annotation=CodeFile | None,
126
+ default=None,
127
+ )
128
+
129
+ DOCUMENTATION_FIELD = FieldModel(
130
+ name="documentation",
131
+ annotation=Documentation | None,
132
+ default=None,
133
+ )
134
+
135
+ # File: lionagi/libs/fields/file.py
@@ -10,9 +10,8 @@ from lionagi.libs.validate.common_field_validators import (
10
10
  validate_boolean_field,
11
11
  validate_nullable_jsonvalue_field,
12
12
  )
13
- from lionagi.utils import HashableModel, to_num
14
-
15
- from ..models.field_model import FieldModel
13
+ from lionagi.models import FieldModel, HashableModel
14
+ from lionagi.utils import to_num
16
15
 
17
16
  __all__ = (
18
17
  "Instruct",
@@ -134,20 +133,21 @@ class Instruct(HashableModel):
134
133
  return None
135
134
 
136
135
 
136
+ class InstructResponse(HashableModel):
137
+ instruct: Instruct
138
+ response: Any | None = None
139
+
140
+
137
141
  INSTRUCT_FIELD = FieldModel(
138
142
  name="instruct_model",
139
143
  annotation=Instruct | None,
140
144
  default=None,
141
145
  )
142
146
 
143
-
144
- class InstructResponse(HashableModel):
145
- instruct: Instruct
146
- response: Any | None = None
147
-
148
-
149
147
  LIST_INSTRUCT_FIELD_MODEL = FieldModel(
150
148
  name="instruct_models",
151
149
  annotation=list[Instruct] | None,
152
150
  default=None,
153
151
  )
152
+
153
+ # File: lionagi/libs/fields/instruct.py
@@ -4,50 +4,14 @@
4
4
 
5
5
  from pydantic import BaseModel, Field, field_validator
6
6
 
7
+ from lionagi.models import FieldModel
7
8
  from lionagi.utils import to_num
8
9
 
9
- from ..models.field_model import FieldModel
10
-
11
10
  __all__ = (
12
11
  "Reason",
13
12
  "REASON_FIELD",
14
- )
15
-
16
-
17
- # deprecated
18
- def validate_confidence_score(cls, value) -> float:
19
- try:
20
- return to_num(
21
- value,
22
- upper_bound=1,
23
- lower_bound=0,
24
- num_type=float,
25
- precision=3,
26
- )
27
- except Exception:
28
- return -1
29
-
30
-
31
- # deprecated
32
- confidence_description = (
33
- "Numeric confidence score (0.0 to 1.0, up to three decimals) indicating "
34
- "how well you've met user expectations. Use this guide:\n"
35
- " • 1.0: Highly confident\n"
36
- " • 0.8-1.0: Reasonably sure\n"
37
- " • 0.5-0.8: Re-check or refine\n"
38
- " • 0.0-0.5: Off track"
39
- )
40
-
41
- # deprecated
42
- CONFIDENCE_SCORE_FIELD = FieldModel(
43
- name="confidence_score",
44
- annotation=float | None,
45
- default=None,
46
- title="Confidence Score",
47
- description=confidence_description,
48
- examples=[0.821, 0.257, 0.923, 0.439],
49
- validator=validate_confidence_score,
50
- validator_kwargs={"mode": "before"},
13
+ "CONFIDENCE_SCORE_FIELD",
14
+ "validate_confidence_score",
51
15
  )
52
16
 
53
17
 
@@ -71,16 +35,29 @@ class Reason(BaseModel):
71
35
 
72
36
  @field_validator("confidence_score", mode="before")
73
37
  def _validate_confidence(cls, v):
74
- try:
75
- return to_num(
76
- v,
77
- upper_bound=1,
78
- lower_bound=0,
79
- num_type=float,
80
- precision=3,
81
- )
82
- except Exception:
83
- return -1
38
+ return validate_confidence_score(cls, v)
39
+
40
+
41
+ def validate_confidence_score(cls, v):
42
+ try:
43
+ return to_num(
44
+ v,
45
+ upper_bound=1,
46
+ lower_bound=0,
47
+ num_type=float,
48
+ precision=3,
49
+ )
50
+ except Exception:
51
+ return -1
52
+
53
+
54
+ CONFIDENCE_SCORE_FIELD = FieldModel(
55
+ name="confidence_score",
56
+ annotation=float | None,
57
+ default=None,
58
+ validator=validate_confidence_score,
59
+ validator_kwargs={"mode": "before"},
60
+ )
84
61
 
85
62
 
86
63
  REASON_FIELD = FieldModel(
@@ -89,3 +66,5 @@ REASON_FIELD = FieldModel(
89
66
  title="Reason",
90
67
  description="**Provide a concise reason for the decision made.**",
91
68
  )
69
+
70
+ # File: lionagi/libs/fields/reason.py
@@ -11,7 +11,7 @@ from lionagi.libs.schema.extract_docstring import extract_docstring
11
11
  from lionagi.libs.validate.common_field_validators import (
12
12
  validate_model_to_type,
13
13
  )
14
- from lionagi.operatives.models.schema_model import SchemaModel
14
+ from lionagi.models import SchemaModel
15
15
 
16
16
  py_json_msp = {
17
17
  "str": "string",
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from .field_model import FieldModel
6
+ from .hashable_model import HashableModel
7
+ from .model_params import ModelParams
8
+ from .note import Note
9
+ from .operable_model import OperableModel
10
+ from .schema_model import SchemaModel
11
+
12
+ __all__ = (
13
+ "FieldModel",
14
+ "ModelParams",
15
+ "OperableModel",
16
+ "Note",
17
+ "SchemaModel",
18
+ "HashableModel",
19
+ )
@@ -0,0 +1,24 @@
1
+ from pydantic import BaseModel
2
+ from typing_extensions import Self
3
+
4
+ from lionagi.utils import UNDEFINED, hash_dict
5
+
6
+
7
+ class HashableModel(BaseModel):
8
+
9
+ def to_dict(self, **kwargs) -> dict:
10
+ """provides interface, specific methods need to be implemented in subclass kwargs for pydantic model_dump"""
11
+ return {
12
+ k: v
13
+ for k, v in self.model_dump(**kwargs).items()
14
+ if v is not UNDEFINED
15
+ }
16
+
17
+ @classmethod
18
+ def from_dict(cls, data: dict, **kwargs) -> Self:
19
+ """provides interface, specific methods need to be implemented in subclass kwargs for pydantic model_validate"""
20
+ return cls.model_validate(data, **kwargs)
21
+
22
+ def __hash__(self):
23
+ # Convert kwargs to a hashable format by serializing unhashable types
24
+ return hash_dict(self.to_dict())
@@ -15,9 +15,10 @@ from pydantic.fields import FieldInfo
15
15
  from pydantic_core import PydanticUndefined
16
16
  from typing_extensions import Self, override
17
17
 
18
- from lionagi.utils import UNDEFINED, HashableModel, is_same_dtype
18
+ from lionagi.utils import UNDEFINED, is_same_dtype
19
19
 
20
20
  from .field_model import FieldModel
21
+ from .hashable_model import HashableModel
21
22
  from .model_params import ModelParams
22
23
 
23
24
  FieldName = TypeVar("FieldName", bound=str)
@@ -4,7 +4,7 @@
4
4
 
5
5
  from pydantic import ConfigDict
6
6
 
7
- from lionagi.utils import HashableModel
7
+ from .hashable_model import HashableModel
8
8
 
9
9
  __all__ = ("SchemaModel",)
10
10
 
@@ -8,13 +8,12 @@ from typing import TYPE_CHECKING, Any, Literal
8
8
 
9
9
  from pydantic import BaseModel
10
10
 
11
+ from lionagi.libs.fields.instruct import Instruct
11
12
  from lionagi.libs.schema.as_readable import as_readable
12
13
  from lionagi.libs.validate.common_field_validators import (
13
14
  validate_model_to_type,
14
15
  )
15
- from lionagi.operatives.models.field_model import FieldModel
16
- from lionagi.operatives.models.model_params import ModelParams
17
- from lionagi.operatives.types import Instruct
16
+ from lionagi.models import FieldModel, ModelParams
18
17
  from lionagi.service.imodel import iModel
19
18
  from lionagi.utils import copy
20
19
 
@@ -7,10 +7,10 @@ from typing import TYPE_CHECKING
7
7
 
8
8
  from pydantic import BaseModel
9
9
 
10
- from lionagi.protocols.types import Log
10
+ from lionagi.libs.fields.action import ActionResponseModel
11
+ from lionagi.protocols.types import ActionRequest, Log
11
12
 
12
13
  if TYPE_CHECKING:
13
- from lionagi.operatives.types import ActionResponseModel
14
14
  from lionagi.session.branch import Branch
15
15
 
16
16
 
@@ -65,8 +65,6 @@ async def _act(
65
65
 
66
66
  branch._log_manager.log(Log.create(func_call))
67
67
 
68
- from lionagi.protocols.types import ActionRequest
69
-
70
68
  if not isinstance(action_request, ActionRequest):
71
69
  action_request = ActionRequest.create(
72
70
  sender=branch.id,
@@ -83,9 +81,6 @@ async def _act(
83
81
  action_output=func_call.response,
84
82
  )
85
83
 
86
- # Return an ActionResponse object
87
- from lionagi.operatives.types import ActionResponseModel
88
-
89
84
  return ActionResponseModel(
90
85
  function=action_request.function,
91
86
  arguments=action_request.arguments,
@@ -7,7 +7,7 @@ from typing import Any, Literal
7
7
 
8
8
  from pydantic import BaseModel
9
9
 
10
- from lionagi.operatives.instruct.instruct import (
10
+ from lionagi.libs.fields.instruct import (
11
11
  LIST_INSTRUCT_FIELD_MODEL,
12
12
  Instruct,
13
13
  InstructResponse,
@@ -4,7 +4,7 @@
4
4
 
5
5
  from typing import TYPE_CHECKING, Any
6
6
 
7
- from lionagi.operatives.types import Instruct
7
+ from lionagi.libs.fields.instruct import Instruct
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from lionagi.session.branch import Branch