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.
- lionagi/__init__.py +0 -7
- lionagi/_types.py +0 -1
- lionagi/libs/fields/__init__.py +36 -0
- lionagi/libs/fields/action.py +190 -0
- lionagi/libs/fields/file.py +135 -0
- lionagi/{operatives/instruct → libs/fields}/instruct.py +9 -9
- lionagi/{operatives/instruct → libs/fields}/reason.py +28 -49
- lionagi/libs/schema/function_to_schema.py +1 -1
- lionagi/models/__init__.py +19 -0
- lionagi/models/hashable_model.py +24 -0
- lionagi/{operatives/models → models}/operable_model.py +2 -1
- lionagi/{operatives/models → models}/schema_model.py +1 -1
- lionagi/operations/ReAct/ReAct.py +2 -3
- lionagi/operations/_act/act.py +2 -7
- lionagi/operations/brainstorm/brainstorm.py +1 -1
- lionagi/operations/instruct/instruct.py +1 -1
- lionagi/operations/operate/operate.py +6 -5
- lionagi/operations/parse/parse.py +1 -1
- lionagi/operations/plan/plan.py +1 -1
- lionagi/operations/select/select.py +1 -1
- lionagi/operations/utils.py +1 -1
- lionagi/{operatives → protocols}/action/function_calling.py +4 -1
- lionagi/{operatives → protocols}/action/manager.py +2 -9
- lionagi/{operatives → protocols}/action/tool.py +1 -6
- lionagi/{operatives → protocols}/forms/base.py +8 -2
- lionagi/{operatives → protocols}/forms/flow.py +6 -1
- lionagi/{operatives → protocols}/forms/form.py +6 -1
- lionagi/{operatives → protocols}/forms/report.py +7 -3
- lionagi/protocols/generic/pile.py +9 -5
- lionagi/protocols/graph/node.py +8 -4
- lionagi/protocols/mail/exchange.py +0 -6
- lionagi/protocols/mail/mail.py +0 -6
- lionagi/protocols/mail/mailbox.py +0 -5
- lionagi/protocols/mail/manager.py +0 -5
- lionagi/protocols/mail/package.py +0 -6
- lionagi/protocols/messages/action_request.py +0 -6
- lionagi/protocols/messages/action_response.py +0 -5
- lionagi/protocols/messages/assistant_response.py +0 -4
- lionagi/protocols/messages/base.py +0 -6
- lionagi/protocols/messages/instruction.py +0 -5
- lionagi/protocols/messages/manager.py +0 -6
- lionagi/protocols/messages/message.py +0 -5
- lionagi/protocols/messages/system.py +0 -5
- lionagi/{operatives → protocols/operatives}/operative.py +1 -3
- lionagi/{operatives → protocols/operatives}/step.py +5 -7
- lionagi/protocols/types.py +36 -21
- lionagi/service/endpoints/base.py +1 -1
- lionagi/service/endpoints/rate_limited_processor.py +1 -1
- lionagi/service/providers/ollama_/chat_completions.py +2 -2
- lionagi/session/branch.py +9 -10
- lionagi/session/session.py +24 -8
- lionagi/tools/base.py +1 -1
- lionagi/tools/file/reader.py +1 -1
- lionagi/utils.py +0 -22
- lionagi/version.py +1 -1
- {lionagi-0.9.19.dist-info → lionagi-0.10.0.dist-info}/METADATA +1 -1
- {lionagi-0.9.19.dist-info → lionagi-0.10.0.dist-info}/RECORD +75 -90
- lionagi/operatives/action/request_response_model.py +0 -121
- lionagi/operatives/action/utils.py +0 -147
- lionagi/operatives/instruct/__init__.py +0 -3
- lionagi/operatives/instruct/base.py +0 -81
- lionagi/operatives/instruct/instruct_collection.py +0 -52
- lionagi/operatives/instruct/node.py +0 -13
- lionagi/operatives/instruct/prompts.py +0 -51
- lionagi/operatives/manager.py +0 -9
- lionagi/operatives/models/__init__.py +0 -3
- lionagi/operatives/strategies/__init__.py +0 -3
- lionagi/operatives/strategies/base.py +0 -56
- lionagi/operatives/strategies/concurrent.py +0 -75
- lionagi/operatives/strategies/concurrent_chunk.py +0 -46
- lionagi/operatives/strategies/concurrent_sequential_chunk.py +0 -108
- lionagi/operatives/strategies/params.py +0 -151
- lionagi/operatives/strategies/sequential.py +0 -27
- lionagi/operatives/strategies/sequential_chunk.py +0 -93
- lionagi/operatives/strategies/sequential_concurrent_chunk.py +0 -105
- lionagi/operatives/strategies/utils.py +0 -52
- lionagi/operatives/types.py +0 -72
- /lionagi/{protocols/adapters → adapters}/__init__.py +0 -0
- /lionagi/{protocols/adapters → adapters}/adapter.py +0 -0
- /lionagi/{protocols/adapters → adapters}/json_adapter.py +0 -0
- /lionagi/{protocols/adapters → adapters}/pandas_/__init__.py +0 -0
- /lionagi/{protocols/adapters → adapters}/pandas_/csv_adapter.py +0 -0
- /lionagi/{protocols/adapters → adapters}/pandas_/excel_adapter.py +0 -0
- /lionagi/{protocols/adapters → adapters}/pandas_/pd_dataframe_adapter.py +0 -0
- /lionagi/{protocols/adapters → adapters}/pandas_/pd_series_adapter.py +0 -0
- /lionagi/{protocols/adapters → adapters}/toml_adapter.py +0 -0
- /lionagi/{protocols/adapters → adapters}/types.py +0 -0
- /lionagi/{operatives/models → models}/field_model.py +0 -0
- /lionagi/{operatives/models → models}/model_params.py +0 -0
- /lionagi/{operatives/models → models}/note.py +0 -0
- /lionagi/{operatives → protocols/action}/__init__.py +0 -0
- /lionagi/{operatives/action → protocols/forms}/__init__.py +0 -0
- /lionagi/{operatives/forms → protocols/operatives}/__init__.py +0 -0
- {lionagi-0.9.19.dist-info → lionagi-0.10.0.dist-info}/WHEEL +0 -0
- {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
@@ -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.
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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.
|
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,
|
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)
|
@@ -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.
|
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
|
|
lionagi/operations/_act/act.py
CHANGED
@@ -7,10 +7,10 @@ from typing import TYPE_CHECKING
|
|
7
7
|
|
8
8
|
from pydantic import BaseModel
|
9
9
|
|
10
|
-
from lionagi.
|
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,
|