lionagi 0.7.0__py3-none-any.whl → 0.7.1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- lionagi/operations/ReAct/ReAct.py +2 -2
- lionagi/operations/communicate/communicate.py +0 -59
- lionagi/operations/interpret/interpret.py +1 -2
- lionagi/operations/operate/operate.py +10 -5
- lionagi/operations/parse/parse.py +0 -36
- lionagi/operations/plan/plan.py +3 -3
- lionagi/operatives/action/manager.py +105 -82
- lionagi/operatives/action/request_response_model.py +31 -0
- lionagi/operatives/action/tool.py +50 -20
- lionagi/protocols/_concepts.py +1 -1
- lionagi/protocols/adapters/adapter.py +25 -0
- lionagi/protocols/adapters/json_adapter.py +107 -27
- lionagi/protocols/adapters/pandas_/csv_adapter.py +55 -11
- lionagi/protocols/adapters/pandas_/excel_adapter.py +52 -10
- lionagi/protocols/adapters/pandas_/pd_dataframe_adapter.py +54 -4
- lionagi/protocols/adapters/pandas_/pd_series_adapter.py +40 -0
- lionagi/protocols/generic/element.py +1 -1
- lionagi/protocols/generic/pile.py +5 -8
- lionagi/protocols/graph/edge.py +1 -1
- lionagi/protocols/graph/graph.py +16 -8
- lionagi/protocols/graph/node.py +1 -1
- lionagi/protocols/mail/exchange.py +126 -15
- lionagi/protocols/mail/mail.py +33 -0
- lionagi/protocols/mail/mailbox.py +62 -0
- lionagi/protocols/mail/manager.py +97 -41
- lionagi/protocols/mail/package.py +57 -3
- lionagi/protocols/messages/action_request.py +77 -26
- lionagi/protocols/messages/action_response.py +55 -26
- lionagi/protocols/messages/assistant_response.py +50 -15
- lionagi/protocols/messages/base.py +36 -0
- lionagi/protocols/messages/instruction.py +175 -145
- lionagi/protocols/messages/manager.py +152 -56
- lionagi/protocols/messages/message.py +61 -25
- lionagi/protocols/messages/system.py +54 -19
- lionagi/service/imodel.py +24 -0
- lionagi/session/branch.py +40 -32
- lionagi/utils.py +1 -0
- lionagi/version.py +1 -1
- {lionagi-0.7.0.dist-info → lionagi-0.7.1.dist-info}/METADATA +1 -1
- {lionagi-0.7.0.dist-info → lionagi-0.7.1.dist-info}/RECORD +42 -42
- {lionagi-0.7.0.dist-info → lionagi-0.7.1.dist-info}/WHEEL +0 -0
- {lionagi-0.7.0.dist-info → lionagi-0.7.1.dist-info}/licenses/LICENSE +0 -0
@@ -2,6 +2,12 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
"""
|
6
|
+
Defines `Package` and `PackageCategory`, encapsulating the contents
|
7
|
+
and classification of mail items. Also includes a simple validator
|
8
|
+
to ensure categories are valid.
|
9
|
+
"""
|
10
|
+
|
5
11
|
from enum import Enum
|
6
12
|
from typing import Any
|
7
13
|
|
@@ -12,7 +18,20 @@ from .._concepts import Communicatable, Observable
|
|
12
18
|
|
13
19
|
|
14
20
|
class PackageCategory(str, Enum):
|
15
|
-
"""
|
21
|
+
"""
|
22
|
+
Enumeration of common package categories in LionAGI:
|
23
|
+
|
24
|
+
- MESSAGE: General message content
|
25
|
+
- TOOL: A tool or action to be invoked
|
26
|
+
- IMODEL: Some internal model reference
|
27
|
+
- NODE: A node in a graph
|
28
|
+
- NODE_LIST: A list of nodes
|
29
|
+
- NODE_ID: A node ID
|
30
|
+
- START: A 'start' signal
|
31
|
+
- END: An 'end' signal
|
32
|
+
- CONDITION: A condition or gating logic
|
33
|
+
- SIGNAL: A more generic signal or marker
|
34
|
+
"""
|
16
35
|
|
17
36
|
MESSAGE = "message"
|
18
37
|
TOOL = "tool"
|
@@ -27,7 +46,24 @@ class PackageCategory(str, Enum):
|
|
27
46
|
|
28
47
|
|
29
48
|
def validate_category(value: Any) -> PackageCategory:
|
30
|
-
"""
|
49
|
+
"""
|
50
|
+
Validate and convert the input to a valid PackageCategory.
|
51
|
+
|
52
|
+
Parameters
|
53
|
+
----------
|
54
|
+
value : Any
|
55
|
+
The input to interpret as a `PackageCategory`.
|
56
|
+
|
57
|
+
Returns
|
58
|
+
-------
|
59
|
+
PackageCategory
|
60
|
+
The validated category.
|
61
|
+
|
62
|
+
Raises
|
63
|
+
------
|
64
|
+
ValueError
|
65
|
+
If the value cannot be converted into a valid package category.
|
66
|
+
"""
|
31
67
|
if isinstance(value, PackageCategory):
|
32
68
|
return value
|
33
69
|
try:
|
@@ -37,6 +73,23 @@ def validate_category(value: Any) -> PackageCategory:
|
|
37
73
|
|
38
74
|
|
39
75
|
class Package(Observable):
|
76
|
+
"""
|
77
|
+
A self-contained package that can be attached to `Mail` items.
|
78
|
+
Includes a unique ID, creation timestamp, category, payload item,
|
79
|
+
and an optional request source for context.
|
80
|
+
|
81
|
+
Attributes
|
82
|
+
----------
|
83
|
+
category : PackageCategory
|
84
|
+
The classification or type of package.
|
85
|
+
item : Any
|
86
|
+
The main payload or data of this package.
|
87
|
+
request_source : ID[Communicatable] | None
|
88
|
+
An optional reference indicating the origin or context
|
89
|
+
for this package.
|
90
|
+
"""
|
91
|
+
|
92
|
+
__slots__ = ("id", "created_at", "category", "item", "request_source")
|
40
93
|
|
41
94
|
def __init__(
|
42
95
|
self,
|
@@ -52,4 +105,5 @@ class Package(Observable):
|
|
52
105
|
self.item = item
|
53
106
|
self.request_source = request_source
|
54
107
|
|
55
|
-
|
108
|
+
|
109
|
+
# File: lionagi/protocols/mail/package.py
|
@@ -2,6 +2,12 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
"""
|
6
|
+
Defines the `ActionRequest` class, a specific `RoledMessage` for requesting
|
7
|
+
a function or action call within LionAGI. It is typically accompanied by
|
8
|
+
arguments and can later be answered by an `ActionResponse`.
|
9
|
+
"""
|
10
|
+
|
5
11
|
from collections.abc import Callable
|
6
12
|
from typing import Any
|
7
13
|
|
@@ -16,7 +22,23 @@ def prepare_action_request(
|
|
16
22
|
function: str | Callable,
|
17
23
|
arguments: dict,
|
18
24
|
) -> dict[str, Any]:
|
19
|
-
|
25
|
+
"""
|
26
|
+
Build a structured dict describing the request details.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
function (str | Callable):
|
30
|
+
The name (or callable) representing the function to invoke.
|
31
|
+
arguments (dict):
|
32
|
+
The arguments necessary for the function call.
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
dict[str, Any]: A standardized dictionary containing
|
36
|
+
'action_request' -> {'function':..., 'arguments':...}
|
37
|
+
|
38
|
+
Raises:
|
39
|
+
ValueError: If `function` is neither a string nor callable, or
|
40
|
+
if `arguments` cannot be turned into a dictionary.
|
41
|
+
"""
|
20
42
|
if isinstance(function, Callable):
|
21
43
|
function = function.__name__
|
22
44
|
if hasattr(function, "function"):
|
@@ -36,6 +58,11 @@ def prepare_action_request(
|
|
36
58
|
|
37
59
|
|
38
60
|
class ActionRequest(RoledMessage):
|
61
|
+
"""
|
62
|
+
A message that requests an action or function to be executed.
|
63
|
+
It inherits from `RoledMessage` and includes function name,
|
64
|
+
arguments, and optional linking to a subsequent `ActionResponse`.
|
65
|
+
"""
|
39
66
|
|
40
67
|
template: Template | str | None = jinja_env.get_template(
|
41
68
|
"action_request.jinja2"
|
@@ -44,50 +71,44 @@ class ActionRequest(RoledMessage):
|
|
44
71
|
@property
|
45
72
|
def action_response_id(self) -> IDType | None:
|
46
73
|
"""
|
47
|
-
Get the ID of the corresponding action response.
|
74
|
+
Get or set the ID of the corresponding action response.
|
48
75
|
|
49
76
|
Returns:
|
50
|
-
IDType | None: The ID of the action response, or None if
|
77
|
+
IDType | None: The ID of the action response, or None if none assigned.
|
51
78
|
"""
|
52
79
|
return self.content.get("action_response_id", None)
|
53
80
|
|
54
81
|
@action_response_id.setter
|
55
82
|
def action_response_id(self, action_response_id: IDType) -> None:
|
56
|
-
"""
|
57
|
-
Set the ID of the corresponding action response.
|
58
|
-
|
59
|
-
Args:
|
60
|
-
action_response_id: The ID of the action response
|
61
|
-
"""
|
62
83
|
self.content["action_response_id"] = action_response_id
|
63
84
|
|
64
85
|
@property
|
65
86
|
def request(self) -> dict[str, Any]:
|
66
87
|
"""
|
67
|
-
Get the
|
88
|
+
Get the entire 'action_request' dictionary if present.
|
68
89
|
|
69
90
|
Returns:
|
70
|
-
dict[str, Any]: The request content
|
91
|
+
dict[str, Any]: The request content or empty dict if missing.
|
71
92
|
"""
|
72
93
|
return copy(self.content.get("action_request", {}))
|
73
94
|
|
74
95
|
@property
|
75
96
|
def arguments(self) -> dict[str, Any]:
|
76
97
|
"""
|
77
|
-
|
98
|
+
Access just the 'arguments' from the action request.
|
78
99
|
|
79
100
|
Returns:
|
80
|
-
dict[str, Any]: The arguments
|
101
|
+
dict[str, Any]: The arguments to be used by the function call.
|
81
102
|
"""
|
82
103
|
return self.request.get("arguments", {})
|
83
104
|
|
84
105
|
@property
|
85
106
|
def function(self) -> str:
|
86
107
|
"""
|
87
|
-
|
108
|
+
Name of the function to be invoked.
|
88
109
|
|
89
110
|
Returns:
|
90
|
-
str: The name
|
111
|
+
str: The function name or empty string if none provided.
|
91
112
|
"""
|
92
113
|
return self.request.get("function", "")
|
93
114
|
|
@@ -102,16 +123,24 @@ class ActionRequest(RoledMessage):
|
|
102
123
|
**kwargs,
|
103
124
|
) -> "ActionRequest":
|
104
125
|
"""
|
105
|
-
|
126
|
+
Build a new ActionRequest.
|
106
127
|
|
107
128
|
Args:
|
108
|
-
function
|
109
|
-
|
110
|
-
|
111
|
-
|
129
|
+
function (str | Callable | None):
|
130
|
+
The function or callable name.
|
131
|
+
arguments (dict | None):
|
132
|
+
Arguments for that function call.
|
133
|
+
sender (SenderRecipient | None):
|
134
|
+
The sender identifier or role.
|
135
|
+
recipient (SenderRecipient | None):
|
136
|
+
The recipient identifier or role.
|
137
|
+
template (Template | str | None):
|
138
|
+
Optional custom template.
|
139
|
+
**kwargs:
|
140
|
+
Extra key-value pairs to merge into the content.
|
112
141
|
|
113
142
|
Returns:
|
114
|
-
ActionRequest:
|
143
|
+
ActionRequest: A newly constructed instance.
|
115
144
|
"""
|
116
145
|
content = prepare_action_request(function, arguments)
|
117
146
|
content.update(kwargs)
|
@@ -135,15 +164,36 @@ class ActionRequest(RoledMessage):
|
|
135
164
|
template: Template | str | None = None,
|
136
165
|
**kwargs,
|
137
166
|
):
|
167
|
+
"""
|
168
|
+
Update this request with new function, arguments, or link to an
|
169
|
+
action response.
|
170
|
+
|
171
|
+
Args:
|
172
|
+
function (str): New function name, if changing.
|
173
|
+
arguments (dict): New arguments dictionary, if changing.
|
174
|
+
sender (SenderRecipient): New sender.
|
175
|
+
recipient (SenderRecipient): New recipient.
|
176
|
+
action_response (ActionResponse):
|
177
|
+
If provided, this request is flagged as responded.
|
178
|
+
template (Template | str | None):
|
179
|
+
Optional new template.
|
180
|
+
**kwargs:
|
181
|
+
Additional fields to store in content.
|
182
|
+
|
183
|
+
Raises:
|
184
|
+
ValueError: If the request is already responded to.
|
185
|
+
"""
|
138
186
|
if self.is_responded():
|
139
187
|
raise ValueError("Cannot update a responded action request.")
|
140
188
|
|
189
|
+
# Link action response if given
|
141
190
|
if (
|
142
191
|
isinstance(action_response, RoledMessage)
|
143
192
|
and action_response.class_name() == "ActionResponse"
|
144
193
|
):
|
145
194
|
self.action_response_id = action_response.id
|
146
195
|
|
196
|
+
# If new function or arguments, create new 'action_request' content
|
147
197
|
if any([function, arguments]):
|
148
198
|
action_request = prepare_action_request(
|
149
199
|
function or self.function, arguments or self.arguments
|
@@ -155,11 +205,12 @@ class ActionRequest(RoledMessage):
|
|
155
205
|
|
156
206
|
def is_responded(self) -> bool:
|
157
207
|
"""
|
158
|
-
Check if
|
208
|
+
Check if there's a linked action response.
|
159
209
|
|
160
210
|
Returns:
|
161
|
-
bool: True if
|
211
|
+
bool: True if an action response ID is present.
|
162
212
|
"""
|
163
|
-
|
164
|
-
|
165
|
-
|
213
|
+
return self.action_response_id is not None
|
214
|
+
|
215
|
+
|
216
|
+
# File: lionagi/protocols/messages/action_request.py
|
@@ -2,6 +2,11 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
"""
|
6
|
+
Defines `ActionResponse`, an `RoledMessage` that answers an `ActionRequest`
|
7
|
+
with output from a function call or action.
|
8
|
+
"""
|
9
|
+
|
5
10
|
from typing import Any
|
6
11
|
|
7
12
|
from typing_extensions import override
|
@@ -18,6 +23,16 @@ def prepare_action_response_content(
|
|
18
23
|
action_request: ActionRequest,
|
19
24
|
output: Any,
|
20
25
|
) -> dict:
|
26
|
+
"""
|
27
|
+
Convert an ActionRequest + function output into response-friendly dictionary.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
action_request (ActionRequest): The original action request.
|
31
|
+
output (Any): The result of the function call.
|
32
|
+
|
33
|
+
Returns:
|
34
|
+
dict: A dictionary containing `action_request_id` and `action_response`.
|
35
|
+
"""
|
21
36
|
return {
|
22
37
|
"action_request_id": str(action_request.id),
|
23
38
|
"action_response": {
|
@@ -29,6 +44,10 @@ def prepare_action_response_content(
|
|
29
44
|
|
30
45
|
|
31
46
|
class ActionResponse(RoledMessage):
|
47
|
+
"""
|
48
|
+
A message fulfilling an `ActionRequest`. It stores the function name,
|
49
|
+
the arguments used, and the output produced by the function.
|
50
|
+
"""
|
32
51
|
|
33
52
|
template: Template | str | None = jinja_env.get_template(
|
34
53
|
"action_response.jinja2"
|
@@ -36,52 +55,32 @@ class ActionResponse(RoledMessage):
|
|
36
55
|
|
37
56
|
@property
|
38
57
|
def function(self) -> str:
|
39
|
-
"""
|
40
|
-
Get the function name from the action response.
|
41
|
-
|
42
|
-
Returns:
|
43
|
-
str: The name of the function that was executed
|
44
|
-
"""
|
58
|
+
"""Name of the function that was executed."""
|
45
59
|
return self.content.get("action_response", {}).get("function", None)
|
46
60
|
|
47
61
|
@property
|
48
62
|
def arguments(self) -> dict[str, Any]:
|
49
|
-
"""
|
50
|
-
Get the function arguments from the action response.
|
51
|
-
|
52
|
-
Returns:
|
53
|
-
dict[str, Any]: The arguments that were used
|
54
|
-
"""
|
63
|
+
"""Arguments used for the executed function."""
|
55
64
|
return self.content.get("action_response", {}).get("arguments", {})
|
56
65
|
|
57
66
|
@property
|
58
67
|
def output(self) -> Any:
|
59
|
-
"""
|
60
|
-
Get the function output from the action response.
|
61
|
-
|
62
|
-
Returns:
|
63
|
-
Any: The result returned by the function
|
64
|
-
"""
|
68
|
+
"""The result or returned data from the function call."""
|
65
69
|
return self.content.get("action_response", {}).get("output", None)
|
66
70
|
|
67
71
|
@property
|
68
72
|
def response(self) -> dict[str, Any]:
|
69
73
|
"""
|
70
|
-
|
74
|
+
A helper to get the entire 'action_response' dictionary.
|
71
75
|
|
72
76
|
Returns:
|
73
|
-
dict[str, Any]: The response including function
|
77
|
+
dict[str, Any]: The entire response, including function, arguments, and output.
|
74
78
|
"""
|
75
79
|
return copy(self.content.get("action_response", {}))
|
76
80
|
|
77
81
|
@property
|
78
82
|
def action_request_id(self) -> IDType:
|
79
|
-
"""
|
80
|
-
Get the ID of the corresponding action request.
|
81
|
-
|
82
|
-
Returns:
|
83
|
-
ID[ActionRequest].ID | None: The ID of the original request
|
84
|
-
"""
|
83
|
+
"""The ID of the original action request."""
|
85
84
|
return IDType.validate(self.content.get("action_request_id"))
|
86
85
|
|
87
86
|
@override
|
@@ -94,7 +93,22 @@ class ActionResponse(RoledMessage):
|
|
94
93
|
sender: SenderRecipient | None = None,
|
95
94
|
recipient: SenderRecipient | None = None,
|
96
95
|
) -> "ActionResponse":
|
96
|
+
"""
|
97
|
+
Build an ActionResponse from a matching `ActionRequest` and output.
|
98
|
+
|
99
|
+
Args:
|
100
|
+
action_request (ActionRequest): The original request being fulfilled.
|
101
|
+
output (Any, optional): The function output or result.
|
102
|
+
response_model (Any, optional):
|
103
|
+
If present and has `.output`, this is used instead of `output`.
|
104
|
+
sender (SenderRecipient, optional):
|
105
|
+
The role or ID of the sender (defaults to the request's recipient).
|
106
|
+
recipient (SenderRecipient, optional):
|
107
|
+
The role or ID of the recipient (defaults to the request's sender).
|
97
108
|
|
109
|
+
Returns:
|
110
|
+
ActionResponse: A new instance referencing the `ActionRequest`.
|
111
|
+
"""
|
98
112
|
if response_model:
|
99
113
|
output = response_model.output
|
100
114
|
|
@@ -119,6 +133,18 @@ class ActionResponse(RoledMessage):
|
|
119
133
|
template: Template | str | None = None,
|
120
134
|
**kwargs,
|
121
135
|
):
|
136
|
+
"""
|
137
|
+
Update this response with a new request reference or new output.
|
138
|
+
|
139
|
+
Args:
|
140
|
+
action_request (ActionRequest): The updated request.
|
141
|
+
output (Any): The new function output data.
|
142
|
+
response_model: If present, uses response_model.output.
|
143
|
+
sender (SenderRecipient): New sender ID or role.
|
144
|
+
recipient (SenderRecipient): New recipient ID or role.
|
145
|
+
template (Template | str | None): Optional new template.
|
146
|
+
**kwargs: Additional fields to store in content.
|
147
|
+
"""
|
122
148
|
if response_model:
|
123
149
|
output = response_model.output
|
124
150
|
|
@@ -130,3 +156,6 @@ class ActionResponse(RoledMessage):
|
|
130
156
|
super().update(
|
131
157
|
sender=sender, recipient=recipient, template=template, **kwargs
|
132
158
|
)
|
159
|
+
|
160
|
+
|
161
|
+
# File: lionagi/protocols/messages/action_response.py
|
@@ -2,6 +2,10 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
"""
|
6
|
+
Defines `AssistantResponse`, a specialized `RoledMessage` for the AI's
|
7
|
+
assistant replies (usually from LLM or related).
|
8
|
+
"""
|
5
9
|
from typing import Any
|
6
10
|
|
7
11
|
from pydantic import BaseModel
|
@@ -69,6 +73,11 @@ def prepare_assistant_response(
|
|
69
73
|
|
70
74
|
|
71
75
|
class AssistantResponse(RoledMessage):
|
76
|
+
"""
|
77
|
+
A message representing the AI assistant's reply, typically
|
78
|
+
from a model or LLM call. If the raw model output is available,
|
79
|
+
it's placed in `metadata["model_response"]`.
|
80
|
+
"""
|
72
81
|
|
73
82
|
template: Template | str | None = jinja_env.get_template(
|
74
83
|
"assistant_response.jinja2"
|
@@ -76,31 +85,20 @@ class AssistantResponse(RoledMessage):
|
|
76
85
|
|
77
86
|
@property
|
78
87
|
def response(self) -> str:
|
79
|
-
"""
|
80
|
-
Get the assistant response content.
|
81
|
-
|
82
|
-
Returns:
|
83
|
-
str: The formatted content of the assistant's response
|
84
|
-
"""
|
88
|
+
"""Get or set the text portion of the assistant's response."""
|
85
89
|
return copy(self.content["assistant_response"])
|
86
90
|
|
87
91
|
@response.setter
|
88
92
|
def response(self, value: str) -> None:
|
89
|
-
"""
|
90
|
-
Set the assistant response content.
|
91
|
-
|
92
|
-
Args:
|
93
|
-
value: The new response content
|
94
|
-
"""
|
95
93
|
self.content["assistant_response"] = value
|
96
94
|
|
97
95
|
@property
|
98
96
|
def model_response(self) -> dict | list[dict]:
|
99
97
|
"""
|
100
|
-
|
98
|
+
Access the underlying model's raw data, if available.
|
101
99
|
|
102
100
|
Returns:
|
103
|
-
|
101
|
+
dict or list[dict]: The stored model output data.
|
104
102
|
"""
|
105
103
|
return copy(self.metadata.get("model_response", {}))
|
106
104
|
|
@@ -112,7 +110,26 @@ class AssistantResponse(RoledMessage):
|
|
112
110
|
recipient: SenderRecipient | None = None,
|
113
111
|
template: Template | str | None = None,
|
114
112
|
**kwargs,
|
115
|
-
):
|
113
|
+
) -> "AssistantResponse":
|
114
|
+
"""
|
115
|
+
Build an AssistantResponse from arbitrary assistant data.
|
116
|
+
|
117
|
+
Args:
|
118
|
+
assistant_response:
|
119
|
+
A pydantic model, list, dict, or string representing
|
120
|
+
an LLM or system response.
|
121
|
+
sender (SenderRecipient | None):
|
122
|
+
The ID or role denoting who sends this response.
|
123
|
+
recipient (SenderRecipient | None):
|
124
|
+
The ID or role to receive it.
|
125
|
+
template (Template | str | None):
|
126
|
+
Optional custom template.
|
127
|
+
**kwargs:
|
128
|
+
Additional content key-value pairs.
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
AssistantResponse: The constructed instance.
|
132
|
+
"""
|
116
133
|
content = prepare_assistant_response(assistant_response)
|
117
134
|
model_response = content.pop("model_response", {})
|
118
135
|
content.update(kwargs)
|
@@ -139,9 +156,27 @@ class AssistantResponse(RoledMessage):
|
|
139
156
|
template: Template | str | None = None,
|
140
157
|
**kwargs,
|
141
158
|
):
|
159
|
+
"""
|
160
|
+
Update this AssistantResponse with new data or fields.
|
161
|
+
|
162
|
+
Args:
|
163
|
+
assistant_response:
|
164
|
+
Additional or replaced assistant model output.
|
165
|
+
sender (SenderRecipient | None):
|
166
|
+
Updated sender.
|
167
|
+
recipient (SenderRecipient | None):
|
168
|
+
Updated recipient.
|
169
|
+
template (Template | str | None):
|
170
|
+
Optional new template.
|
171
|
+
**kwargs:
|
172
|
+
Additional content updates for `self.content`.
|
173
|
+
"""
|
142
174
|
if assistant_response:
|
143
175
|
content = prepare_assistant_response(assistant_response)
|
144
176
|
self.content.update(content)
|
145
177
|
super().update(
|
146
178
|
sender=sender, recipient=recipient, template=template, **kwargs
|
147
179
|
)
|
180
|
+
|
181
|
+
|
182
|
+
# File: lionagi/protocols/messages/assistant_response.py
|
@@ -2,6 +2,12 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
"""
|
6
|
+
Holds foundational enumerations and types for messages, including
|
7
|
+
roles like `SYSTEM`, `USER`, and helper functions for validating
|
8
|
+
sender/recipient fields.
|
9
|
+
"""
|
10
|
+
|
5
11
|
from enum import Enum
|
6
12
|
from typing import Any, TypeAlias
|
7
13
|
|
@@ -17,6 +23,9 @@ __all__ = (
|
|
17
23
|
|
18
24
|
|
19
25
|
class MessageRole(str, Enum):
|
26
|
+
"""
|
27
|
+
Predefined roles for conversation participants or message semantics.
|
28
|
+
"""
|
20
29
|
|
21
30
|
SYSTEM = "system"
|
22
31
|
USER = "user"
|
@@ -26,15 +35,27 @@ class MessageRole(str, Enum):
|
|
26
35
|
|
27
36
|
|
28
37
|
class MessageFlag(str, Enum):
|
38
|
+
"""
|
39
|
+
Internal flags for certain message states, e.g., clones or loads.
|
40
|
+
"""
|
29
41
|
|
30
42
|
MESSAGE_CLONE = "MESSAGE_CLONE"
|
31
43
|
MESSAGE_LOAD = "MESSAGE_LOAD"
|
32
44
|
|
33
45
|
|
34
46
|
SenderRecipient: TypeAlias = IDType | MessageRole | str
|
47
|
+
"""
|
48
|
+
A union type indicating that a sender or recipient could be:
|
49
|
+
- A lionagi IDType,
|
50
|
+
- A string-based role or ID,
|
51
|
+
- A specific enum role from `MessageRole`.
|
52
|
+
"""
|
35
53
|
|
36
54
|
|
37
55
|
class MessageField(str, Enum):
|
56
|
+
"""
|
57
|
+
Common field names used in message objects.
|
58
|
+
"""
|
38
59
|
|
39
60
|
CREATED_AT = "created_at"
|
40
61
|
ROLE = "role"
|
@@ -49,6 +70,18 @@ MESSAGE_FIELDS = [i.value for i in MessageField.__members__.values()]
|
|
49
70
|
|
50
71
|
|
51
72
|
def validate_sender_recipient(value: Any, /) -> SenderRecipient:
|
73
|
+
"""
|
74
|
+
Normalize a sender/recipient value into a recognized type.
|
75
|
+
|
76
|
+
Args:
|
77
|
+
value (Any): Input to interpret as a role or ID.
|
78
|
+
|
79
|
+
Returns:
|
80
|
+
SenderRecipient: A validated and normalized entity.
|
81
|
+
|
82
|
+
Raises:
|
83
|
+
ValueError: If the input cannot be recognized as a role or ID.
|
84
|
+
"""
|
52
85
|
if isinstance(value, MessageRole | MessageFlag):
|
53
86
|
return value
|
54
87
|
|
@@ -71,3 +104,6 @@ def validate_sender_recipient(value: Any, /) -> SenderRecipient:
|
|
71
104
|
return ID.get_id(value)
|
72
105
|
except IDError as e:
|
73
106
|
raise ValueError("Invalid sender or recipient") from e
|
107
|
+
|
108
|
+
|
109
|
+
# File: lionagi/protocols/messages/base.py
|