lionagi 0.5.1__py3-none-any.whl → 0.5.3__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- lionagi/__init__.py +3 -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 +8 -4
- lionagi/core/session/branch_mixins.py +11 -12
- 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/groq_/GroqModel.py +11 -4
- lionagi/integrations/litellm_/imodel.py +6 -8
- lionagi/integrations/openai_/OpenAIModel.py +8 -3
- lionagi/integrations/openai_/image_token_calculator/image_token_calculator.py +14 -8
- lionagi/integrations/perplexity_/PerplexityModel.py +8 -3
- 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 +4 -4
- lionagi/operations/brainstorm/prompt.py +8 -1
- lionagi/operations/plan/plan.py +3 -3
- lionagi/operations/plan/prompt.py +17 -16
- 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 -8
- lionagi/protocols/operatives/operative.py +9 -21
- lionagi/protocols/operatives/prompts.py +53 -202
- 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/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.1.dist-info → lionagi-0.5.3.dist-info}/METADATA +5 -3
- {lionagi-0.5.1.dist-info → lionagi-0.5.3.dist-info}/RECORD +73 -72
- 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.1.dist-info → lionagi-0.5.3.dist-info}/WHEEL +0 -0
- {lionagi-0.5.1.dist-info → lionagi-0.5.3.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
@@ -42,29 +42,33 @@ class Branch(Component, BranchActionMixin, BranchOperationMixin):
|
|
42
42
|
)
|
43
43
|
if not message_manager.logger:
|
44
44
|
message_manager.logger = LogManager(
|
45
|
-
**Settings.Branch.BRANCH.message_log_config.to_dict(
|
45
|
+
**Settings.Branch.BRANCH.message_log_config.to_dict()
|
46
46
|
)
|
47
47
|
|
48
48
|
acts = data.pop("acts", None)
|
49
49
|
if not acts:
|
50
50
|
acts = ActionManager()
|
51
51
|
acts.logger = LogManager(
|
52
|
-
**Settings.Branch.BRANCH.action_log_config.to_dict(
|
52
|
+
**Settings.Branch.BRANCH.action_log_config.to_dict()
|
53
53
|
)
|
54
54
|
if "tools" in data:
|
55
55
|
acts.register_tools(data.pop("tools"))
|
56
56
|
|
57
57
|
imodel = data.pop(
|
58
58
|
"imodel",
|
59
|
-
|
59
|
+
iModel(**Settings.iModel.CHAT.to_dict()),
|
60
|
+
)
|
61
|
+
parse_imodel = data.pop(
|
62
|
+
"parse_imodel",
|
63
|
+
iModel(**Settings.iModel.PARSE.to_dict()),
|
60
64
|
)
|
61
|
-
|
62
65
|
out = {
|
63
66
|
"user": user,
|
64
67
|
"name": name,
|
65
68
|
"msgs": message_manager,
|
66
69
|
"acts": acts,
|
67
70
|
"imodel": imodel,
|
71
|
+
"parse_imodel": parse_imodel,
|
68
72
|
**data,
|
69
73
|
}
|
70
74
|
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,
|
@@ -321,9 +320,9 @@ class BranchOperationMixin(ABC):
|
|
321
320
|
imodel = imodel or self.imodel
|
322
321
|
api_response = None
|
323
322
|
|
324
|
-
if
|
323
|
+
if not hasattr(imodel, "parse_to_data_model"):
|
325
324
|
api_response = await imodel.invoke(**kwargs)
|
326
|
-
|
325
|
+
else:
|
327
326
|
data_model = imodel.parse_to_data_model(**kwargs)
|
328
327
|
api_response = await imodel.invoke(**data_model)
|
329
328
|
|
@@ -344,12 +343,12 @@ class BranchOperationMixin(ABC):
|
|
344
343
|
progress: ID.IDSeq = None,
|
345
344
|
request_model: type[BaseModel] | BaseModel = None,
|
346
345
|
request_fields: dict | list[str] = None,
|
347
|
-
imodel: iModel
|
346
|
+
imodel: iModel = None,
|
348
347
|
images: list = None,
|
349
348
|
image_detail: Literal["low", "high", "auto"] = None,
|
350
349
|
tools: str | FUNCTOOL | list[FUNCTOOL | str] | bool = None,
|
351
350
|
num_parse_retries: int = 0,
|
352
|
-
retry_imodel: iModel
|
351
|
+
retry_imodel: iModel = None,
|
353
352
|
retry_kwargs: dict = {},
|
354
353
|
handle_validation: Literal[
|
355
354
|
"raise", "return_value", "return_none"
|
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
|
+
]
|
@@ -4,7 +4,6 @@
|
|
4
4
|
|
5
5
|
from pathlib import Path
|
6
6
|
|
7
|
-
import yaml
|
8
7
|
from dotenv import load_dotenv
|
9
8
|
from pydantic import (
|
10
9
|
BaseModel,
|
@@ -34,6 +33,12 @@ price_config_file_name = path / "anthropic_price_data.yaml"
|
|
34
33
|
max_output_token_file_name = path / "anthropic_max_output_token_data.yaml"
|
35
34
|
|
36
35
|
|
36
|
+
class _ModuleImportClass:
|
37
|
+
from lionagi.libs.package.imports import check_import
|
38
|
+
|
39
|
+
yaml = check_import("yaml", pip_name="pyyaml")
|
40
|
+
|
41
|
+
|
37
42
|
class AnthropicModel(BaseModel):
|
38
43
|
model: str = Field(description="ID of the model to use.")
|
39
44
|
|
@@ -234,7 +239,7 @@ class AnthropicModel(BaseModel):
|
|
234
239
|
)
|
235
240
|
if estimated_output_len == 0:
|
236
241
|
with open(max_output_token_file_name) as file:
|
237
|
-
output_token_config = yaml.safe_load(file)
|
242
|
+
output_token_config = _ModuleImportClass.yaml.safe_load(file)
|
238
243
|
estimated_output_len = output_token_config.get(self.model, 0)
|
239
244
|
self.estimated_output_len = estimated_output_len
|
240
245
|
|
@@ -256,7 +261,7 @@ class AnthropicModel(BaseModel):
|
|
256
261
|
num_of_input_tokens = self.text_token_calculator.calculate(input_text)
|
257
262
|
|
258
263
|
with open(price_config_file_name) as file:
|
259
|
-
price_config = yaml.safe_load(file)
|
264
|
+
price_config = _ModuleImportClass.yaml.safe_load(file)
|
260
265
|
|
261
266
|
model_price_info_dict = price_config["model"][self.model]
|
262
267
|
estimated_price = (
|
@@ -5,7 +5,6 @@
|
|
5
5
|
import warnings
|
6
6
|
from pathlib import Path
|
7
7
|
|
8
|
-
import yaml
|
9
8
|
from dotenv import load_dotenv
|
10
9
|
from pydantic import (
|
11
10
|
BaseModel,
|
@@ -34,6 +33,12 @@ max_output_token_file_name = path / "groq_max_output_token_data.yaml"
|
|
34
33
|
rate_limits_file_name = path / "groq_rate_limits.yaml"
|
35
34
|
|
36
35
|
|
36
|
+
class _ModuleImportClass:
|
37
|
+
from lionagi.libs.package.imports import check_import
|
38
|
+
|
39
|
+
yaml = check_import("yaml", pip_name="pyyaml")
|
40
|
+
|
41
|
+
|
37
42
|
class GroqModel(BaseModel):
|
38
43
|
model: str = Field(description="ID of the model to use.")
|
39
44
|
request_model: GroqRequest = Field(description="Making requests")
|
@@ -67,7 +72,7 @@ class GroqModel(BaseModel):
|
|
67
72
|
# Load rate limits from YAML
|
68
73
|
try:
|
69
74
|
with open(rate_limits_file_name) as file:
|
70
|
-
rate_limits = yaml.safe_load(file)
|
75
|
+
rate_limits = _ModuleImportClass.yaml.safe_load(file)
|
71
76
|
model_name = data.get("model")
|
72
77
|
model_limits = None
|
73
78
|
|
@@ -261,7 +266,9 @@ class GroqModel(BaseModel):
|
|
261
266
|
if estimated_output_len == 0:
|
262
267
|
try:
|
263
268
|
with open(max_output_token_file_name) as file:
|
264
|
-
output_token_config = yaml.safe_load(
|
269
|
+
output_token_config = _ModuleImportClass.yaml.safe_load(
|
270
|
+
file
|
271
|
+
)
|
265
272
|
estimated_output_len = output_token_config.get(
|
266
273
|
self.model, 2048
|
267
274
|
) # Default to 2048
|
@@ -297,7 +304,7 @@ class GroqModel(BaseModel):
|
|
297
304
|
|
298
305
|
try:
|
299
306
|
with open(price_config_file_name) as file:
|
300
|
-
price_config = yaml.safe_load(file)
|
307
|
+
price_config = _ModuleImportClass.yaml.safe_load(file)
|
301
308
|
except FileNotFoundError:
|
302
309
|
raise ValueError(
|
303
310
|
f"Price config file not found: {price_config_file_name}"
|