lionagi 0.5.0__py3-none-any.whl → 0.5.2__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 -1
- lionagi/core/action/tool.py +3 -5
- lionagi/core/communication/action_request.py +3 -3
- lionagi/core/communication/message.py +3 -3
- lionagi/core/communication/utils.py +3 -3
- lionagi/core/generic/component.py +4 -4
- lionagi/core/generic/element.py +51 -47
- lionagi/core/generic/graph.py +1 -1
- lionagi/core/generic/log.py +2 -2
- lionagi/core/generic/pile.py +10 -11
- lionagi/core/generic/progression.py +19 -12
- lionagi/core/generic/utils.py +6 -3
- lionagi/core/models/base.py +11 -68
- lionagi/core/models/field_model.py +42 -19
- lionagi/core/models/{new_model_params.py → model_params.py} +5 -6
- lionagi/core/models/note.py +2 -2
- lionagi/core/models/operable_model.py +8 -4
- lionagi/core/models/schema_model.py +9 -31
- lionagi/core/models/types.py +15 -6
- lionagi/core/session/branch.py +10 -7
- lionagi/core/session/branch_mixins.py +52 -15
- lionagi/core/session/session.py +1 -2
- lionagi/core/typing/__init__.py +4 -4
- lionagi/core/typing/{concepts.py → _concepts.py} +43 -2
- lionagi/core/typing/_id.py +104 -0
- lionagi/integrations/anthropic_/AnthropicModel.py +8 -3
- lionagi/integrations/anthropic_/AnthropicService.py +4 -0
- lionagi/integrations/groq_/GroqModel.py +11 -4
- lionagi/integrations/groq_/GroqService.py +4 -0
- lionagi/integrations/litellm_/imodel.py +10 -8
- lionagi/integrations/ollama_/OllamaService.py +4 -0
- lionagi/integrations/openai_/OpenAIModel.py +12 -3
- lionagi/integrations/openai_/image_token_calculator/image_token_calculator.py +14 -8
- lionagi/integrations/perplexity_/PerplexityModel.py +8 -3
- lionagi/integrations/perplexity_/PerplexityService.py +4 -0
- lionagi/libs/func/async_calls/__init__.py +6 -3
- lionagi/libs/func/async_calls/alcall.py +46 -0
- lionagi/libs/func/async_calls/bcall.py +49 -1
- lionagi/libs/func/async_calls/rcall.py +32 -0
- lionagi/libs/utils.py +12 -1
- lionagi/operations/brainstorm/brainstorm.py +3 -3
- lionagi/operations/plan/plan.py +3 -3
- lionagi/protocols/__init__.py +3 -0
- lionagi/protocols/configs/__init__.py +0 -15
- lionagi/protocols/configs/branch_config.py +1 -1
- lionagi/protocols/configs/imodel_config.py +2 -2
- lionagi/protocols/configs/log_config.py +1 -1
- lionagi/protocols/configs/types.py +15 -0
- lionagi/protocols/operatives/__init__.py +3 -15
- lionagi/protocols/operatives/action.py +4 -0
- lionagi/protocols/operatives/instruct.py +6 -2
- lionagi/protocols/operatives/operative.py +9 -21
- lionagi/protocols/operatives/prompts.py +4 -0
- lionagi/protocols/operatives/reason.py +4 -0
- lionagi/protocols/operatives/step.py +11 -23
- lionagi/protocols/operatives/types.py +19 -0
- lionagi/protocols/registries/__init__.py +3 -0
- lionagi/protocols/registries/_component_registry.py +4 -0
- lionagi/protocols/registries/_pile_registry.py +4 -0
- lionagi/service/__init__.py +3 -0
- lionagi/service/imodel.py +22 -7
- lionagi/service/service.py +4 -0
- lionagi/service/service_match_util.py +4 -4
- lionagi/settings.py +10 -18
- lionagi/strategies/base.py +4 -5
- lionagi/strategies/concurrent.py +4 -3
- lionagi/strategies/concurrent_chunk.py +3 -3
- lionagi/strategies/concurrent_sequential_chunk.py +3 -3
- lionagi/strategies/params.py +7 -4
- lionagi/version.py +1 -1
- {lionagi-0.5.0.dist-info → lionagi-0.5.2.dist-info}/METADATA +214 -15
- {lionagi-0.5.0.dist-info → lionagi-0.5.2.dist-info}/RECORD +77 -76
- lionagi/core/typing/config.py +0 -15
- lionagi/core/typing/id.py +0 -221
- /lionagi/core/typing/{pydantic_.py → _pydantic.py} +0 -0
- /lionagi/core/typing/{typing_.py → _typing.py} +0 -0
- /lionagi/integrations/{services.py → _services.py} +0 -0
- {lionagi-0.5.0.dist-info → lionagi-0.5.2.dist-info}/WHEEL +0 -0
- {lionagi-0.5.0.dist-info → lionagi-0.5.2.dist-info}/licenses/LICENSE +0 -0
@@ -2,9 +2,13 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
-
from
|
6
|
-
|
7
|
-
from .
|
5
|
+
from lionagi.libs.utils import is_same_dtype
|
6
|
+
|
7
|
+
from ..typing._pydantic import ConfigDict, Field, FieldInfo, field_validator
|
8
|
+
from ..typing._typing import UNDEFINED, Any, Callable, UndefinedType
|
9
|
+
from .schema_model import SchemaModel
|
10
|
+
|
11
|
+
__all__ = ("FieldModel",)
|
8
12
|
|
9
13
|
|
10
14
|
class FieldModel(SchemaModel):
|
@@ -51,24 +55,34 @@ class FieldModel(SchemaModel):
|
|
51
55
|
"""
|
52
56
|
|
53
57
|
model_config = ConfigDict(
|
54
|
-
extra="allow",
|
58
|
+
extra="allow",
|
59
|
+
validate_default=False,
|
60
|
+
populate_by_name=True,
|
61
|
+
arbitrary_types_allowed=True,
|
62
|
+
use_enum_values=True,
|
55
63
|
)
|
56
64
|
|
57
65
|
# Field configuration attributes
|
58
66
|
default: Any = UNDEFINED # Default value
|
59
|
-
default_factory: Callable
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
default_factory: Callable | UndefinedType = (
|
68
|
+
UNDEFINED # Factory function for default value
|
69
|
+
)
|
70
|
+
title: str | UndefinedType = UNDEFINED # Field title
|
71
|
+
description: str | UndefinedType = UNDEFINED # Field description
|
72
|
+
examples: list | UndefinedType = UNDEFINED # Example values
|
73
|
+
validators: list | UndefinedType = UNDEFINED # Validation functions
|
74
|
+
exclude: bool | UndefinedType = UNDEFINED # Exclude from serialization
|
75
|
+
deprecated: bool | UndefinedType = UNDEFINED # Mark as deprecated
|
76
|
+
frozen: bool | UndefinedType = UNDEFINED # Mark as immutable
|
77
|
+
alias: str | UndefinedType = UNDEFINED # Alternative field name
|
78
|
+
alias_priority: int | UndefinedType = (
|
79
|
+
UNDEFINED # Priority for alias resolution
|
80
|
+
)
|
69
81
|
|
70
82
|
# Core field attributes
|
71
|
-
name: str
|
83
|
+
name: str | UndefinedType = Field(
|
84
|
+
..., exclude=True
|
85
|
+
) # Field name (required)
|
72
86
|
annotation: type | Any = Field(UNDEFINED, exclude=True) # Type annotation
|
73
87
|
validator: Callable | Any = Field(
|
74
88
|
UNDEFINED, exclude=True
|
@@ -77,6 +91,18 @@ class FieldModel(SchemaModel):
|
|
77
91
|
default_factory=dict, exclude=True
|
78
92
|
) # Validator parameters
|
79
93
|
|
94
|
+
@field_validator("validators", mode="before")
|
95
|
+
def _validate_validators(cls, v) -> list[Callable]:
|
96
|
+
if v is None or v is UNDEFINED:
|
97
|
+
return []
|
98
|
+
if isinstance(v, Callable):
|
99
|
+
return [v]
|
100
|
+
if isinstance(v, list) and is_same_dtype(v, Callable):
|
101
|
+
return v
|
102
|
+
raise ValueError(
|
103
|
+
"Validators must be a list of functions or a function"
|
104
|
+
)
|
105
|
+
|
80
106
|
@property
|
81
107
|
def field_info(self) -> FieldInfo:
|
82
108
|
"""Generate Pydantic FieldInfo object from field configuration.
|
@@ -92,7 +118,7 @@ class FieldModel(SchemaModel):
|
|
92
118
|
annotation = (
|
93
119
|
self.annotation if self.annotation is not UNDEFINED else Any
|
94
120
|
)
|
95
|
-
field_obj: FieldInfo = Field(**self.to_dict(
|
121
|
+
field_obj: FieldInfo = Field(**self.to_dict()) # type: ignore
|
96
122
|
field_obj.annotation = annotation
|
97
123
|
return field_obj
|
98
124
|
|
@@ -117,6 +143,3 @@ class FieldModel(SchemaModel):
|
|
117
143
|
self.validator
|
118
144
|
)
|
119
145
|
}
|
120
|
-
|
121
|
-
|
122
|
-
__all__ = ["FieldModel"]
|
@@ -9,7 +9,7 @@ from pydantic import BaseModel
|
|
9
9
|
from lionagi.libs.parse import validate_boolean
|
10
10
|
from lionagi.libs.utils import copy
|
11
11
|
|
12
|
-
from ..typing.
|
12
|
+
from ..typing._pydantic import (
|
13
13
|
Field,
|
14
14
|
FieldInfo,
|
15
15
|
PrivateAttr,
|
@@ -17,12 +17,14 @@ from ..typing.pydantic_ import (
|
|
17
17
|
field_validator,
|
18
18
|
model_validator,
|
19
19
|
)
|
20
|
-
from ..typing.
|
20
|
+
from ..typing._typing import Callable, Self
|
21
21
|
from .field_model import FieldModel
|
22
22
|
from .schema_model import SchemaModel
|
23
23
|
|
24
|
+
__all__ = ("ModelParams",)
|
24
25
|
|
25
|
-
|
26
|
+
|
27
|
+
class ModelParams(SchemaModel):
|
26
28
|
"""Configuration class for dynamically creating new Pydantic models."""
|
27
29
|
|
28
30
|
name: str | None = None
|
@@ -190,6 +192,3 @@ class NewModelParams(SchemaModel):
|
|
190
192
|
if self.frozen:
|
191
193
|
a.model_config["frozen"] = True
|
192
194
|
return a
|
193
|
-
|
194
|
-
|
195
|
-
__all__ = ["NewModelParams"]
|
lionagi/core/models/note.py
CHANGED
@@ -5,8 +5,8 @@
|
|
5
5
|
from lionagi.libs.parse import flatten, nget, ninsert, npop, nset, to_list
|
6
6
|
from lionagi.libs.utils import copy
|
7
7
|
|
8
|
-
from ..typing.
|
9
|
-
from ..typing.
|
8
|
+
from ..typing._pydantic import ConfigDict, Field, field_serializer
|
9
|
+
from ..typing._typing import (
|
10
10
|
UNDEFINED,
|
11
11
|
Any,
|
12
12
|
ItemsView,
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
from lionagi.libs.utils import is_same_dtype
|
6
6
|
|
7
|
-
from ..typing.
|
7
|
+
from ..typing._pydantic import (
|
8
8
|
ConfigDict,
|
9
9
|
Field,
|
10
10
|
FieldInfo,
|
@@ -12,8 +12,8 @@ from ..typing.pydantic_ import (
|
|
12
12
|
field_serializer,
|
13
13
|
field_validator,
|
14
14
|
)
|
15
|
-
from ..typing.
|
16
|
-
from .base import BaseAutoModel
|
15
|
+
from ..typing._typing import UNDEFINED, Any, TypeVar, override
|
16
|
+
from .base import BaseAutoModel
|
17
17
|
from .field_model import FieldModel
|
18
18
|
|
19
19
|
FIELD_NAME = TypeVar("FIELD_NAME", bound=str)
|
@@ -55,7 +55,11 @@ class OperableModel(BaseAutoModel):
|
|
55
55
|
"""
|
56
56
|
|
57
57
|
model_config = ConfigDict(
|
58
|
-
extra="forbid",
|
58
|
+
extra="forbid",
|
59
|
+
validate_default=False,
|
60
|
+
populate_by_name=True,
|
61
|
+
arbitrary_types_allowed=True,
|
62
|
+
use_enum_values=True,
|
59
63
|
)
|
60
64
|
|
61
65
|
extra_fields: dict[str, Any] = Field(default_factory=dict)
|
@@ -2,39 +2,20 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
-
from ..typing.
|
6
|
-
from .base import BaseAutoModel
|
5
|
+
from ..typing._pydantic import ConfigDict
|
6
|
+
from .base import BaseAutoModel
|
7
7
|
|
8
|
+
__all__ = ("SchemaModel",)
|
8
9
|
|
9
|
-
class SchemaModel(BaseAutoModel):
|
10
|
-
"""Schema definition model with strict validation.
|
11
|
-
|
12
|
-
Extends BaseAutoModel to provide:
|
13
|
-
- Extra field forbidding
|
14
|
-
- Disabled default validation
|
15
|
-
- Field name listing
|
16
|
-
- Nested validation
|
17
|
-
|
18
|
-
Example:
|
19
|
-
```python
|
20
|
-
class UserSchema(SchemaModel):
|
21
|
-
name: str = Field(min_length=2)
|
22
|
-
age: int = Field(gt=0)
|
23
|
-
settings: dict[str, Any] = Field(default_factory=dict)
|
24
|
-
|
25
|
-
# Raises error - extra fields forbidden
|
26
|
-
user = UserSchema(name="John", age=30, extra="value")
|
27
|
-
```
|
28
10
|
|
29
|
-
|
30
|
-
model_config: Schema-specific configuration
|
31
|
-
- extra: "forbid" to prevent extra fields
|
32
|
-
- validate_default: False to skip default validation
|
33
|
-
- Plus inherited BaseAutoModel config
|
34
|
-
"""
|
11
|
+
class SchemaModel(BaseAutoModel):
|
35
12
|
|
36
13
|
model_config = ConfigDict(
|
37
|
-
extra="forbid",
|
14
|
+
extra="forbid",
|
15
|
+
validate_default=False,
|
16
|
+
populate_by_name=True,
|
17
|
+
arbitrary_types_allowed=True,
|
18
|
+
use_enum_values=True,
|
38
19
|
)
|
39
20
|
|
40
21
|
@classmethod
|
@@ -45,6 +26,3 @@ class SchemaModel(BaseAutoModel):
|
|
45
26
|
List of field names defined in model schema
|
46
27
|
"""
|
47
28
|
return list(cls.model_fields.keys())
|
48
|
-
|
49
|
-
|
50
|
-
__all__ = ["SchemaModel"]
|
lionagi/core/models/types.py
CHANGED
@@ -2,9 +2,18 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
-
from .base import
|
6
|
-
from .field_model import
|
7
|
-
from .
|
8
|
-
from .note import
|
9
|
-
from .operable_model import
|
10
|
-
from .schema_model import
|
5
|
+
from .base import BaseAutoModel
|
6
|
+
from .field_model import FieldModel
|
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
|
+
"BaseAutoModel",
|
14
|
+
"FieldModel",
|
15
|
+
"ModelParams",
|
16
|
+
"Note",
|
17
|
+
"OperableModel",
|
18
|
+
"SchemaModel",
|
19
|
+
)
|
lionagi/core/session/branch.py
CHANGED
@@ -9,7 +9,6 @@ from pydantic import model_validator
|
|
9
9
|
|
10
10
|
from lionagi.core.generic.types import Component, LogManager, Pile, Progression
|
11
11
|
from lionagi.core.typing import ID
|
12
|
-
from lionagi.integrations.litellm_.imodel import LiteiModel
|
13
12
|
from lionagi.protocols.operatives.instruct import Instruct, OperationInstruct
|
14
13
|
from lionagi.service import iModel
|
15
14
|
from lionagi.settings import Settings
|
@@ -25,8 +24,8 @@ class Branch(Component, BranchActionMixin, BranchOperationMixin):
|
|
25
24
|
name: str | None = None
|
26
25
|
msgs: MessageManager = None
|
27
26
|
acts: ActionManager = None
|
28
|
-
imodel: iModel |
|
29
|
-
parse_imodel: iModel |
|
27
|
+
imodel: iModel | None = None
|
28
|
+
parse_imodel: iModel | None = None
|
30
29
|
|
31
30
|
@model_validator(mode="before")
|
32
31
|
def _validate_data(cls, data: dict) -> dict:
|
@@ -42,29 +41,33 @@ class Branch(Component, BranchActionMixin, BranchOperationMixin):
|
|
42
41
|
)
|
43
42
|
if not message_manager.logger:
|
44
43
|
message_manager.logger = LogManager(
|
45
|
-
**Settings.Branch.BRANCH.message_log_config.to_dict(
|
44
|
+
**Settings.Branch.BRANCH.message_log_config.to_dict()
|
46
45
|
)
|
47
46
|
|
48
47
|
acts = data.pop("acts", None)
|
49
48
|
if not acts:
|
50
49
|
acts = ActionManager()
|
51
50
|
acts.logger = LogManager(
|
52
|
-
**Settings.Branch.BRANCH.action_log_config.to_dict(
|
51
|
+
**Settings.Branch.BRANCH.action_log_config.to_dict()
|
53
52
|
)
|
54
53
|
if "tools" in data:
|
55
54
|
acts.register_tools(data.pop("tools"))
|
56
55
|
|
57
56
|
imodel = data.pop(
|
58
57
|
"imodel",
|
59
|
-
|
58
|
+
iModel(**Settings.iModel.CHAT.to_dict()),
|
59
|
+
)
|
60
|
+
parse_imodel = data.pop(
|
61
|
+
"parse_imodel",
|
62
|
+
iModel(**Settings.iModel.PARSE.to_dict()),
|
60
63
|
)
|
61
|
-
|
62
64
|
out = {
|
63
65
|
"user": user,
|
64
66
|
"name": name,
|
65
67
|
"msgs": message_manager,
|
66
68
|
"acts": acts,
|
67
69
|
"imodel": imodel,
|
70
|
+
"parse_imodel": parse_imodel,
|
68
71
|
**data,
|
69
72
|
}
|
70
73
|
return out
|
@@ -14,13 +14,12 @@ from lionagi.core.typing import (
|
|
14
14
|
UNDEFINED,
|
15
15
|
BaseModel,
|
16
16
|
FieldModel,
|
17
|
-
|
17
|
+
ModelParams,
|
18
18
|
)
|
19
|
-
from lionagi.integrations.litellm_.imodel import LiteiModel
|
20
19
|
from lionagi.integrations.pydantic_ import break_down_pydantic_annotation
|
21
20
|
from lionagi.libs.func.types import alcall
|
22
21
|
from lionagi.libs.parse import to_json, validate_mapping
|
23
|
-
from lionagi.protocols.operatives import (
|
22
|
+
from lionagi.protocols.operatives.types import (
|
24
23
|
ActionRequestModel,
|
25
24
|
ActionResponseModel,
|
26
25
|
Operative,
|
@@ -108,7 +107,7 @@ class BranchOperationMixin(ABC):
|
|
108
107
|
recipient=None,
|
109
108
|
operative_model: type[BaseModel] = None,
|
110
109
|
progress=None,
|
111
|
-
imodel: iModel
|
110
|
+
imodel: iModel = None,
|
112
111
|
reason: bool = False,
|
113
112
|
actions: bool = False,
|
114
113
|
exclude_fields: list | dict | None = None,
|
@@ -120,15 +119,15 @@ class BranchOperationMixin(ABC):
|
|
120
119
|
images: list = None,
|
121
120
|
image_detail: Literal["low", "high", "auto"] = None,
|
122
121
|
max_retries: int = None,
|
123
|
-
retry_imodel: iModel
|
122
|
+
retry_imodel: iModel = None,
|
124
123
|
retry_kwargs: dict = {},
|
125
124
|
auto_retry_parse: bool = True,
|
126
125
|
field_models: list[FieldModel] | None = None,
|
127
126
|
skip_validation: bool = False,
|
128
127
|
tools: str | Tool | list[Tool | str] | bool = None,
|
129
|
-
request_params:
|
128
|
+
request_params: ModelParams = None,
|
130
129
|
request_param_kwargs: dict = {},
|
131
|
-
response_params:
|
130
|
+
response_params: ModelParams = None,
|
132
131
|
response_param_kwargs: dict = {},
|
133
132
|
**kwargs,
|
134
133
|
) -> list | BaseModel | None | dict | str:
|
@@ -269,7 +268,7 @@ class BranchOperationMixin(ABC):
|
|
269
268
|
request_fields=None,
|
270
269
|
request_model: type[BaseModel] = None,
|
271
270
|
progress=None,
|
272
|
-
imodel: iModel
|
271
|
+
imodel: iModel = None,
|
273
272
|
tool_schemas=None,
|
274
273
|
images: list = None,
|
275
274
|
image_detail: Literal["low", "high", "auto"] = None,
|
@@ -288,14 +287,42 @@ class BranchOperationMixin(ABC):
|
|
288
287
|
image_detail=image_detail,
|
289
288
|
tool_schemas=tool_schemas,
|
290
289
|
)
|
291
|
-
kwargs["messages"] = self.msgs.to_chat_msgs(progress)
|
292
|
-
kwargs["messages"].append(ins.chat_msg)
|
293
290
|
|
291
|
+
progress = progress or self.msgs.progress
|
292
|
+
messages = [self.msgs.messages[i] for i in progress]
|
293
|
+
|
294
|
+
if self.msgs.system and "system" not in imodel.allowed_roles:
|
295
|
+
messages = [msg for msg in messages if msg.role != "system"]
|
296
|
+
first_instruction = None
|
297
|
+
|
298
|
+
if len(messages) == 0:
|
299
|
+
first_instruction = ins.model_copy()
|
300
|
+
first_instruction.guidance = self.msgs.system.system_info + (
|
301
|
+
first_instruction.guidance or ""
|
302
|
+
)
|
303
|
+
messages.append(first_instruction)
|
304
|
+
elif len(messages) >= 1:
|
305
|
+
first_instruction = messages[0]
|
306
|
+
if not isinstance(first_instruction, Instruction):
|
307
|
+
raise ValueError(
|
308
|
+
"First message in progress must be an Instruction or System"
|
309
|
+
)
|
310
|
+
first_instruction = first_instruction.model_copy()
|
311
|
+
first_instruction.guidance = self.msgs.system.system_info + (
|
312
|
+
first_instruction.guidance or ""
|
313
|
+
)
|
314
|
+
messages[0] = first_instruction
|
315
|
+
|
316
|
+
else:
|
317
|
+
messages.append(ins)
|
318
|
+
|
319
|
+
kwargs["messages"] = [i.chat_msg for i in messages]
|
294
320
|
imodel = imodel or self.imodel
|
295
321
|
api_response = None
|
296
|
-
|
322
|
+
|
323
|
+
if not hasattr(imodel, "parse_to_data_model"):
|
297
324
|
api_response = await imodel.invoke(**kwargs)
|
298
|
-
|
325
|
+
else:
|
299
326
|
data_model = imodel.parse_to_data_model(**kwargs)
|
300
327
|
api_response = await imodel.invoke(**data_model)
|
301
328
|
|
@@ -316,12 +343,12 @@ class BranchOperationMixin(ABC):
|
|
316
343
|
progress: ID.IDSeq = None,
|
317
344
|
request_model: type[BaseModel] | BaseModel = None,
|
318
345
|
request_fields: dict | list[str] = None,
|
319
|
-
imodel: iModel
|
346
|
+
imodel: iModel = None,
|
320
347
|
images: list = None,
|
321
348
|
image_detail: Literal["low", "high", "auto"] = None,
|
322
349
|
tools: str | FUNCTOOL | list[FUNCTOOL | str] | bool = None,
|
323
350
|
num_parse_retries: int = 0,
|
324
|
-
retry_imodel: iModel
|
351
|
+
retry_imodel: iModel = None,
|
325
352
|
retry_kwargs: dict = {},
|
326
353
|
handle_validation: Literal[
|
327
354
|
"raise", "return_value", "return_none"
|
@@ -329,12 +356,22 @@ class BranchOperationMixin(ABC):
|
|
329
356
|
skip_validation: bool = False,
|
330
357
|
clear_messages: bool = False,
|
331
358
|
invoke_action: bool = True,
|
359
|
+
response_format: (
|
360
|
+
type[BaseModel] | BaseModel
|
361
|
+
) = None, # alias of request_model
|
332
362
|
**kwargs,
|
333
363
|
):
|
364
|
+
if response_format and request_model:
|
365
|
+
raise ValueError(
|
366
|
+
"Cannot specify both response_format and request_model"
|
367
|
+
"as they are aliases for the same parameter."
|
368
|
+
)
|
369
|
+
request_model = request_model or response_format
|
370
|
+
|
334
371
|
imodel = imodel or self.imodel
|
335
372
|
retry_imodel = retry_imodel or imodel
|
336
373
|
if clear_messages:
|
337
|
-
self.clear_messages()
|
374
|
+
self.msgs.clear_messages()
|
338
375
|
|
339
376
|
if num_parse_retries > 5:
|
340
377
|
logging.warning(
|
lionagi/core/session/session.py
CHANGED
@@ -8,7 +8,6 @@ import pandas as pd
|
|
8
8
|
|
9
9
|
from lionagi.core.generic.types import Component, Pile, Progression
|
10
10
|
from lionagi.core.typing import ID, Field, ItemNotFoundError, JsonValue
|
11
|
-
from lionagi.integrations.litellm_.imodel import LiteiModel
|
12
11
|
from lionagi.libs.parse import to_list
|
13
12
|
from lionagi.service import iModel
|
14
13
|
|
@@ -39,7 +38,7 @@ class Session(Component):
|
|
39
38
|
system_datetime: bool | str = None,
|
40
39
|
user: ID.SenderRecipient = None,
|
41
40
|
name: str | None = None,
|
42
|
-
imodel: iModel |
|
41
|
+
imodel: iModel | None = None,
|
43
42
|
messages: Pile[RoledMessage] = None,
|
44
43
|
progress: Progression = None,
|
45
44
|
tool_manager: ActionManager = None,
|
lionagi/core/typing/__init__.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
5
|
from ..models import *
|
6
|
-
from .
|
7
|
-
from .
|
8
|
-
from .
|
9
|
-
from .
|
6
|
+
from ._concepts import *
|
7
|
+
from ._id import *
|
8
|
+
from ._pydantic import *
|
9
|
+
from ._typing import *
|
@@ -2,19 +2,59 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
from __future__ import annotations
|
6
|
+
|
7
|
+
import uuid
|
5
8
|
from abc import ABC, abstractmethod
|
9
|
+
from dataclasses import dataclass
|
6
10
|
from typing import Any, Generic, TypeVar
|
7
11
|
|
12
|
+
from lionagi.settings import Settings
|
13
|
+
|
14
|
+
|
15
|
+
class IDType:
|
16
|
+
|
17
|
+
def __init__(self, _id: uuid.UUID):
|
18
|
+
self._id = _id
|
19
|
+
|
20
|
+
@classmethod
|
21
|
+
def validate(cls, value) -> IDType:
|
22
|
+
if isinstance(value, cls):
|
23
|
+
return value
|
24
|
+
if isinstance(value, str | int):
|
25
|
+
try:
|
26
|
+
_id = uuid.UUID(value, version=Settings.Config.UUID_VERSION)
|
27
|
+
return cls(_id=_id)
|
28
|
+
except Exception as e:
|
29
|
+
raise ValueError(f"Invalid IDType value: {value}") from e
|
30
|
+
raise ValueError(f"Invalid IDType value: {value}")
|
31
|
+
|
32
|
+
def __str__(self):
|
33
|
+
return str(self._id)
|
34
|
+
|
35
|
+
def __repr__(self):
|
36
|
+
return f"{self.__class__.__name__}({self._id})"
|
37
|
+
|
38
|
+
def __hash__(self):
|
39
|
+
return hash(self._id)
|
40
|
+
|
41
|
+
def __eq__(self, other):
|
42
|
+
if not isinstance(other, IDType):
|
43
|
+
return False
|
44
|
+
return self._id == other._id
|
45
|
+
|
46
|
+
__slots__ = ("_id",)
|
47
|
+
|
8
48
|
|
9
49
|
class Observable(ABC):
|
10
50
|
"""
|
11
51
|
Abstract base class for objects that can be uniquely identified and tracked.
|
12
52
|
|
13
|
-
All Observable objects must have a unique identifier (
|
53
|
+
All Observable objects must have a unique identifier (id) that allows them
|
14
54
|
to be tracked and referenced within the Lion system.
|
15
55
|
"""
|
16
56
|
|
17
|
-
ln_id:
|
57
|
+
ln_id: IDType
|
18
58
|
|
19
59
|
|
20
60
|
T = TypeVar("T", bound=Observable)
|
@@ -129,4 +169,5 @@ __all__ = [
|
|
129
169
|
"Condition",
|
130
170
|
"Structure",
|
131
171
|
"RelationError",
|
172
|
+
"IDType",
|
132
173
|
]
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
4
|
+
|
5
|
+
from __future__ import annotations
|
6
|
+
|
7
|
+
import uuid
|
8
|
+
|
9
|
+
from lionagi.settings import Settings
|
10
|
+
|
11
|
+
from ._concepts import (
|
12
|
+
Container,
|
13
|
+
Generic,
|
14
|
+
IDType,
|
15
|
+
ItemError,
|
16
|
+
Observable,
|
17
|
+
Ordering,
|
18
|
+
T,
|
19
|
+
)
|
20
|
+
from ._typing import Container, Mapping, Sequence, TypeAlias
|
21
|
+
|
22
|
+
|
23
|
+
class IDError(ItemError):
|
24
|
+
"""Exception raised when an item does not have a Lion ID."""
|
25
|
+
|
26
|
+
def __init__(
|
27
|
+
self,
|
28
|
+
message: str = "Item must contain a Lion ID.",
|
29
|
+
item_id: str | None = None,
|
30
|
+
):
|
31
|
+
super().__init__(message, item_id)
|
32
|
+
|
33
|
+
|
34
|
+
class ID(Generic[T]):
|
35
|
+
"""
|
36
|
+
A generic class that provides ID-related functionality for Observable objects.
|
37
|
+
|
38
|
+
This class handles the generation, validation, and management of unique identifiers
|
39
|
+
within the Lion system. It provides type aliases for various ID-related operations
|
40
|
+
and methods for working with IDs.
|
41
|
+
"""
|
42
|
+
|
43
|
+
# For functions that accept either ID or item
|
44
|
+
Ref: TypeAlias = IDType | T # type: ignore
|
45
|
+
|
46
|
+
# For functions requiring just the ID
|
47
|
+
ID: TypeAlias = IDType
|
48
|
+
|
49
|
+
# For functions requiring Observable object
|
50
|
+
Item = T # type: ignore
|
51
|
+
|
52
|
+
# For collections
|
53
|
+
IDSeq: TypeAlias = list[IDType] | Ordering
|
54
|
+
ItemSeq: TypeAlias = ( # type: ignore
|
55
|
+
Sequence[T] | Mapping[IDType, T] | Container[IDType | T]
|
56
|
+
)
|
57
|
+
RefSeq: TypeAlias = IDSeq | ItemSeq
|
58
|
+
|
59
|
+
# For system-level interactions
|
60
|
+
SenderRecipient: TypeAlias = IDType | T | str # type: ignore
|
61
|
+
|
62
|
+
@staticmethod
|
63
|
+
def id():
|
64
|
+
return IDType(
|
65
|
+
_id=getattr(uuid, f"uuid{Settings.Config.UUID_VERSION}")()
|
66
|
+
)
|
67
|
+
|
68
|
+
@staticmethod
|
69
|
+
def get_id(item, /) -> IDType:
|
70
|
+
|
71
|
+
if isinstance(item, Observable):
|
72
|
+
return item.ln_id
|
73
|
+
try:
|
74
|
+
return IDType.validate(item)
|
75
|
+
except ValueError as e:
|
76
|
+
raise IDError(
|
77
|
+
f"The input object of type <{type(item).__name__}> does "
|
78
|
+
"not contain or is not a valid Lion ID. Item must be an instance"
|
79
|
+
" of `Observable` or a valid `id`."
|
80
|
+
) from e
|
81
|
+
|
82
|
+
@staticmethod
|
83
|
+
def is_id(item, /) -> bool:
|
84
|
+
"""
|
85
|
+
Check if an item is or contains a valid Lion ID.
|
86
|
+
|
87
|
+
Args:
|
88
|
+
item: The item to check.
|
89
|
+
config: Configuration dictionary for ID validation.
|
90
|
+
|
91
|
+
Returns:
|
92
|
+
True if the item is a valid Lion ID, False otherwise.
|
93
|
+
"""
|
94
|
+
try:
|
95
|
+
ID.get_id(item)
|
96
|
+
return True
|
97
|
+
except IDError:
|
98
|
+
return False
|
99
|
+
|
100
|
+
|
101
|
+
__all__ = [
|
102
|
+
"ID",
|
103
|
+
"IDError",
|
104
|
+
]
|