lionagi 0.12.2__py3-none-any.whl → 0.12.4__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/config.py +123 -0
- lionagi/fields/file.py +1 -1
- lionagi/fields/reason.py +1 -1
- lionagi/libs/file/concat.py +1 -6
- lionagi/libs/file/concat_files.py +1 -5
- lionagi/libs/file/save.py +1 -1
- lionagi/libs/package/imports.py +8 -177
- lionagi/libs/parse.py +30 -0
- lionagi/libs/schema/load_pydantic_model_from_schema.py +259 -0
- lionagi/libs/token_transform/perplexity.py +2 -4
- lionagi/libs/token_transform/synthlang_/resources/frameworks/framework_options.json +46 -46
- lionagi/libs/token_transform/synthlang_/translate_to_synthlang.py +1 -1
- lionagi/operations/chat/chat.py +2 -2
- lionagi/operations/communicate/communicate.py +20 -5
- lionagi/operations/parse/parse.py +131 -43
- lionagi/protocols/generic/log.py +1 -2
- lionagi/protocols/generic/pile.py +18 -4
- lionagi/protocols/messages/assistant_response.py +20 -1
- lionagi/protocols/messages/templates/README.md +6 -10
- lionagi/service/connections/__init__.py +15 -0
- lionagi/service/connections/api_calling.py +230 -0
- lionagi/service/connections/endpoint.py +410 -0
- lionagi/service/connections/endpoint_config.py +137 -0
- lionagi/service/connections/header_factory.py +56 -0
- lionagi/service/connections/match_endpoint.py +49 -0
- lionagi/service/connections/providers/__init__.py +3 -0
- lionagi/service/connections/providers/anthropic_.py +87 -0
- lionagi/service/connections/providers/exa_.py +33 -0
- lionagi/service/connections/providers/oai_.py +166 -0
- lionagi/service/connections/providers/ollama_.py +122 -0
- lionagi/service/connections/providers/perplexity_.py +29 -0
- lionagi/service/imodel.py +36 -144
- lionagi/service/manager.py +1 -7
- lionagi/service/{endpoints/rate_limited_processor.py → rate_limited_processor.py} +4 -2
- lionagi/service/resilience.py +545 -0
- lionagi/service/third_party/README.md +71 -0
- lionagi/service/third_party/__init__.py +0 -0
- lionagi/service/third_party/anthropic_models.py +159 -0
- lionagi/service/third_party/exa_models.py +165 -0
- lionagi/service/third_party/openai_models.py +18241 -0
- lionagi/service/third_party/pplx_models.py +156 -0
- lionagi/service/types.py +5 -4
- lionagi/session/branch.py +12 -7
- lionagi/tools/file/reader.py +1 -1
- lionagi/tools/memory/tools.py +497 -0
- lionagi/utils.py +921 -123
- lionagi/version.py +1 -1
- {lionagi-0.12.2.dist-info → lionagi-0.12.4.dist-info}/METADATA +33 -16
- {lionagi-0.12.2.dist-info → lionagi-0.12.4.dist-info}/RECORD +53 -63
- lionagi/libs/file/create_path.py +0 -80
- lionagi/libs/file/file_util.py +0 -358
- lionagi/libs/parse/__init__.py +0 -3
- lionagi/libs/parse/fuzzy_parse_json.py +0 -117
- lionagi/libs/parse/to_dict.py +0 -336
- lionagi/libs/parse/to_json.py +0 -61
- lionagi/libs/parse/to_num.py +0 -378
- lionagi/libs/parse/to_xml.py +0 -57
- lionagi/libs/parse/xml_parser.py +0 -148
- lionagi/libs/schema/breakdown_pydantic_annotation.py +0 -48
- lionagi/service/endpoints/__init__.py +0 -3
- lionagi/service/endpoints/base.py +0 -706
- lionagi/service/endpoints/chat_completion.py +0 -116
- lionagi/service/endpoints/match_endpoint.py +0 -72
- lionagi/service/providers/__init__.py +0 -3
- lionagi/service/providers/anthropic_/__init__.py +0 -3
- lionagi/service/providers/anthropic_/messages.py +0 -99
- lionagi/service/providers/exa_/models.py +0 -3
- lionagi/service/providers/exa_/search.py +0 -80
- lionagi/service/providers/exa_/types.py +0 -7
- lionagi/service/providers/groq_/__init__.py +0 -3
- lionagi/service/providers/groq_/chat_completions.py +0 -56
- lionagi/service/providers/ollama_/__init__.py +0 -3
- lionagi/service/providers/ollama_/chat_completions.py +0 -134
- lionagi/service/providers/openai_/__init__.py +0 -3
- lionagi/service/providers/openai_/chat_completions.py +0 -101
- lionagi/service/providers/openai_/spec.py +0 -14
- lionagi/service/providers/openrouter_/__init__.py +0 -3
- lionagi/service/providers/openrouter_/chat_completions.py +0 -62
- lionagi/service/providers/perplexity_/__init__.py +0 -3
- lionagi/service/providers/perplexity_/chat_completions.py +0 -44
- lionagi/service/providers/perplexity_/models.py +0 -5
- lionagi/service/providers/types.py +0 -17
- /lionagi/{service/providers/exa_/__init__.py → py.typed} +0 -0
- /lionagi/service/{endpoints/token_calculator.py → token_calculator.py} +0 -0
- {lionagi-0.12.2.dist-info → lionagi-0.12.4.dist-info}/WHEEL +0 -0
- {lionagi-0.12.2.dist-info → lionagi-0.12.4.dist-info}/licenses/LICENSE +0 -0
lionagi/libs/parse/to_dict.py
DELETED
@@ -1,336 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import json
|
4
|
-
from collections.abc import Callable, Iterable, Mapping, Sequence
|
5
|
-
from enum import Enum
|
6
|
-
from functools import partial
|
7
|
-
from typing import Any, Literal
|
8
|
-
|
9
|
-
from pydantic import BaseModel
|
10
|
-
|
11
|
-
from lionagi.utils import PydanticUndefinedType, UndefinedType
|
12
|
-
|
13
|
-
|
14
|
-
def to_dict(
|
15
|
-
input_: Any,
|
16
|
-
/,
|
17
|
-
*,
|
18
|
-
use_model_dump: bool = True,
|
19
|
-
fuzzy_parse: bool = False,
|
20
|
-
suppress: bool = False,
|
21
|
-
str_type: Literal["json", "xml"] | None = "json",
|
22
|
-
parser: Callable[[str], Any] | None = None,
|
23
|
-
recursive: bool = False,
|
24
|
-
max_recursive_depth: int = None,
|
25
|
-
recursive_python_only: bool = True,
|
26
|
-
use_enum_values: bool = False,
|
27
|
-
**kwargs: Any,
|
28
|
-
) -> dict[str, Any]:
|
29
|
-
"""
|
30
|
-
Convert various input types to a dictionary, with optional recursive processing.
|
31
|
-
|
32
|
-
Args:
|
33
|
-
input_: The input to convert.
|
34
|
-
use_model_dump: Use model_dump() for Pydantic models if available.
|
35
|
-
fuzzy_parse: Use fuzzy parsing for string inputs.
|
36
|
-
suppress: Return empty dict on errors if True.
|
37
|
-
str_type: Input string type ("json" or "xml").
|
38
|
-
parser: Custom parser function for string inputs.
|
39
|
-
recursive: Enable recursive conversion of nested structures.
|
40
|
-
max_recursive_depth: Maximum recursion depth (default 5, max 10).
|
41
|
-
recursive_python_only: If False, attempts to convert custom types recursively.
|
42
|
-
use_enum_values: Use enum values instead of names.
|
43
|
-
**kwargs: Additional arguments for parsing functions.
|
44
|
-
|
45
|
-
Returns:
|
46
|
-
dict[str, Any]: A dictionary derived from the input.
|
47
|
-
|
48
|
-
Raises:
|
49
|
-
ValueError: If parsing fails and suppress is False.
|
50
|
-
|
51
|
-
Examples:
|
52
|
-
>>> to_dict({"a": 1, "b": [2, 3]})
|
53
|
-
{'a': 1, 'b': [2, 3]}
|
54
|
-
>>> to_dict('{"x": 10}', str_type="json")
|
55
|
-
{'x': 10}
|
56
|
-
>>> to_dict({"a": {"b": {"c": 1}}}, recursive=True, max_recursive_depth=2)
|
57
|
-
{'a': {'b': {'c': 1}}}
|
58
|
-
"""
|
59
|
-
|
60
|
-
try:
|
61
|
-
if recursive:
|
62
|
-
input_ = recursive_to_dict(
|
63
|
-
input_,
|
64
|
-
use_model_dump=use_model_dump,
|
65
|
-
fuzzy_parse=fuzzy_parse,
|
66
|
-
str_type=str_type,
|
67
|
-
parser=parser,
|
68
|
-
max_recursive_depth=max_recursive_depth,
|
69
|
-
recursive_custom_types=not recursive_python_only,
|
70
|
-
use_enum_values=use_enum_values,
|
71
|
-
**kwargs,
|
72
|
-
)
|
73
|
-
|
74
|
-
return _to_dict(
|
75
|
-
input_,
|
76
|
-
fuzzy_parse=fuzzy_parse,
|
77
|
-
parser=parser,
|
78
|
-
str_type=str_type,
|
79
|
-
use_model_dump=use_model_dump,
|
80
|
-
use_enum_values=use_enum_values,
|
81
|
-
**kwargs,
|
82
|
-
)
|
83
|
-
except Exception as e:
|
84
|
-
if suppress or input_ == "":
|
85
|
-
return {}
|
86
|
-
raise e
|
87
|
-
|
88
|
-
|
89
|
-
def recursive_to_dict(
|
90
|
-
input_: Any,
|
91
|
-
/,
|
92
|
-
*,
|
93
|
-
max_recursive_depth: int = None,
|
94
|
-
recursive_custom_types: bool = False,
|
95
|
-
**kwargs: Any,
|
96
|
-
) -> Any:
|
97
|
-
|
98
|
-
if not isinstance(max_recursive_depth, int):
|
99
|
-
max_recursive_depth = 5
|
100
|
-
else:
|
101
|
-
if max_recursive_depth < 0:
|
102
|
-
raise ValueError(
|
103
|
-
"max_recursive_depth must be a non-negative integer"
|
104
|
-
)
|
105
|
-
if max_recursive_depth == 0:
|
106
|
-
return input_
|
107
|
-
if max_recursive_depth > 10:
|
108
|
-
raise ValueError(
|
109
|
-
"max_recursive_depth must be less than or equal to 10"
|
110
|
-
)
|
111
|
-
|
112
|
-
return _recur_to_dict(
|
113
|
-
input_,
|
114
|
-
max_recursive_depth=max_recursive_depth,
|
115
|
-
current_depth=0,
|
116
|
-
recursive_custom_types=recursive_custom_types,
|
117
|
-
**kwargs,
|
118
|
-
)
|
119
|
-
|
120
|
-
|
121
|
-
def _recur_to_dict(
|
122
|
-
input_: Any,
|
123
|
-
/,
|
124
|
-
*,
|
125
|
-
max_recursive_depth: int,
|
126
|
-
current_depth: int = 0,
|
127
|
-
recursive_custom_types: bool = False,
|
128
|
-
**kwargs: Any,
|
129
|
-
) -> Any:
|
130
|
-
|
131
|
-
if current_depth >= max_recursive_depth:
|
132
|
-
return input_
|
133
|
-
|
134
|
-
if isinstance(input_, str):
|
135
|
-
try:
|
136
|
-
# Attempt to parse the string
|
137
|
-
parsed = _to_dict(input_, **kwargs)
|
138
|
-
# Recursively process the parsed result
|
139
|
-
return _recur_to_dict(
|
140
|
-
parsed,
|
141
|
-
max_recursive_depth=max_recursive_depth,
|
142
|
-
current_depth=current_depth + 1,
|
143
|
-
recursive_custom_types=recursive_custom_types,
|
144
|
-
**kwargs,
|
145
|
-
)
|
146
|
-
except Exception:
|
147
|
-
# Return the original string if parsing fails
|
148
|
-
return input_
|
149
|
-
|
150
|
-
elif isinstance(input_, dict):
|
151
|
-
# Recursively process dictionary values
|
152
|
-
return {
|
153
|
-
key: _recur_to_dict(
|
154
|
-
value,
|
155
|
-
max_recursive_depth=max_recursive_depth,
|
156
|
-
current_depth=current_depth + 1,
|
157
|
-
recursive_custom_types=recursive_custom_types,
|
158
|
-
**kwargs,
|
159
|
-
)
|
160
|
-
for key, value in input_.items()
|
161
|
-
}
|
162
|
-
|
163
|
-
elif isinstance(input_, (list, tuple, set)):
|
164
|
-
# Recursively process list or tuple elements
|
165
|
-
processed = [
|
166
|
-
_recur_to_dict(
|
167
|
-
element,
|
168
|
-
max_recursive_depth=max_recursive_depth,
|
169
|
-
current_depth=current_depth + 1,
|
170
|
-
recursive_custom_types=recursive_custom_types,
|
171
|
-
**kwargs,
|
172
|
-
)
|
173
|
-
for element in input_
|
174
|
-
]
|
175
|
-
return type(input_)(processed)
|
176
|
-
|
177
|
-
elif isinstance(input_, type) and issubclass(input_, Enum):
|
178
|
-
try:
|
179
|
-
obj_dict = _to_dict(input_, **kwargs)
|
180
|
-
return _recur_to_dict(
|
181
|
-
obj_dict,
|
182
|
-
max_recursive_depth=max_recursive_depth,
|
183
|
-
current_depth=current_depth + 1,
|
184
|
-
**kwargs,
|
185
|
-
)
|
186
|
-
except Exception:
|
187
|
-
return input_
|
188
|
-
|
189
|
-
elif recursive_custom_types:
|
190
|
-
# Process custom classes if enabled
|
191
|
-
try:
|
192
|
-
obj_dict = _to_dict(input_, **kwargs)
|
193
|
-
return _recur_to_dict(
|
194
|
-
obj_dict,
|
195
|
-
max_recursive_depth=max_recursive_depth,
|
196
|
-
current_depth=current_depth + 1,
|
197
|
-
recursive_custom_types=recursive_custom_types,
|
198
|
-
**kwargs,
|
199
|
-
)
|
200
|
-
except Exception:
|
201
|
-
return input_
|
202
|
-
|
203
|
-
else:
|
204
|
-
# Return the input as is for other data types
|
205
|
-
return input_
|
206
|
-
|
207
|
-
|
208
|
-
def _enum_to_dict(input_, /, use_enum_values: bool = True):
|
209
|
-
dict_ = dict(input_.__members__).copy()
|
210
|
-
if use_enum_values:
|
211
|
-
return {key: value.value for key, value in dict_.items()}
|
212
|
-
return dict_
|
213
|
-
|
214
|
-
|
215
|
-
def _str_to_dict(
|
216
|
-
input_: str,
|
217
|
-
/,
|
218
|
-
fuzzy_parse: bool = False,
|
219
|
-
str_type: Literal["json", "xml"] | None = "json",
|
220
|
-
parser: Callable[[str], Any] | None = None,
|
221
|
-
remove_root: bool = False,
|
222
|
-
root_tag: str = "root",
|
223
|
-
**kwargs: Any,
|
224
|
-
):
|
225
|
-
"""
|
226
|
-
kwargs for parser
|
227
|
-
"""
|
228
|
-
if not parser:
|
229
|
-
if str_type == "xml" and not parser:
|
230
|
-
from lionagi.libs.parse.xml_parser import xml_to_dict
|
231
|
-
|
232
|
-
parser = partial(
|
233
|
-
xml_to_dict, remove_root=remove_root, root_tag=root_tag
|
234
|
-
)
|
235
|
-
|
236
|
-
elif fuzzy_parse:
|
237
|
-
|
238
|
-
from lionagi.libs.parse.fuzzy_parse_json import fuzzy_parse_json
|
239
|
-
|
240
|
-
parser = fuzzy_parse_json
|
241
|
-
else:
|
242
|
-
parser = json.loads
|
243
|
-
|
244
|
-
return parser(input_, **kwargs)
|
245
|
-
|
246
|
-
|
247
|
-
def _na_to_dict(input_: type[None] | UndefinedType | PydanticUndefinedType, /):
|
248
|
-
return {}
|
249
|
-
|
250
|
-
|
251
|
-
def _model_to_dict(input_: Any, /, use_model_dump=True, **kwargs):
|
252
|
-
"""
|
253
|
-
kwargs: built-in serialization methods kwargs
|
254
|
-
accepted built-in serialization methods:
|
255
|
-
- mdoel_dump
|
256
|
-
- to_dict
|
257
|
-
- to_json
|
258
|
-
- dict
|
259
|
-
- json
|
260
|
-
"""
|
261
|
-
|
262
|
-
if use_model_dump and hasattr(input_, "model_dump"):
|
263
|
-
return input_.model_dump(**kwargs)
|
264
|
-
|
265
|
-
methods = (
|
266
|
-
"to_dict",
|
267
|
-
"to_json",
|
268
|
-
"json",
|
269
|
-
"dict",
|
270
|
-
)
|
271
|
-
for method in methods:
|
272
|
-
if hasattr(input_, method):
|
273
|
-
result = getattr(input_, method)(**kwargs)
|
274
|
-
return json.loads(result) if isinstance(result, str) else result
|
275
|
-
|
276
|
-
if hasattr(input_, "__dict__"):
|
277
|
-
return input_.__dict__
|
278
|
-
|
279
|
-
try:
|
280
|
-
return dict(input_)
|
281
|
-
except Exception as e:
|
282
|
-
raise ValueError(f"Unable to convert input to dictionary: {e}")
|
283
|
-
|
284
|
-
|
285
|
-
def _set_to_dict(input_: set, /) -> dict:
|
286
|
-
return {v: v for v in input_}
|
287
|
-
|
288
|
-
|
289
|
-
def _iterable_to_dict(input_: Iterable, /) -> dict:
|
290
|
-
return {idx: v for idx, v in enumerate(input_)}
|
291
|
-
|
292
|
-
|
293
|
-
def _to_dict(
|
294
|
-
input_: Any,
|
295
|
-
/,
|
296
|
-
*,
|
297
|
-
fuzzy_parse: bool = False,
|
298
|
-
str_type: Literal["json", "xml"] | None = "json",
|
299
|
-
parser: Callable[[str], Any] | None = None,
|
300
|
-
remove_root: bool = False,
|
301
|
-
root_tag: str = "root",
|
302
|
-
use_model_dump: bool = True,
|
303
|
-
use_enum_values: bool = True,
|
304
|
-
**kwargs: Any,
|
305
|
-
) -> dict[str, Any]:
|
306
|
-
|
307
|
-
if isinstance(input_, set):
|
308
|
-
return _set_to_dict(input_)
|
309
|
-
|
310
|
-
if isinstance(input_, type) and issubclass(input_, Enum):
|
311
|
-
return _enum_to_dict(input_, use_enum_values=use_enum_values)
|
312
|
-
|
313
|
-
if isinstance(input_, Mapping):
|
314
|
-
return dict(input_)
|
315
|
-
|
316
|
-
if isinstance(input_, type(None) | UndefinedType | PydanticUndefinedType):
|
317
|
-
return _na_to_dict(input_)
|
318
|
-
|
319
|
-
if isinstance(input_, str):
|
320
|
-
return _str_to_dict(
|
321
|
-
input_,
|
322
|
-
fuzzy_parse=fuzzy_parse,
|
323
|
-
str_type=str_type,
|
324
|
-
parser=parser,
|
325
|
-
remove_root=remove_root,
|
326
|
-
root_tag=root_tag,
|
327
|
-
**kwargs,
|
328
|
-
)
|
329
|
-
|
330
|
-
if isinstance(input_, BaseModel) or not isinstance(input_, Sequence):
|
331
|
-
return _model_to_dict(input_, use_model_dump=use_model_dump, **kwargs)
|
332
|
-
|
333
|
-
if isinstance(input_, Iterable):
|
334
|
-
return _iterable_to_dict(input_)
|
335
|
-
|
336
|
-
return dict(input_)
|
lionagi/libs/parse/to_json.py
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import re
|
3
|
-
from typing import Any
|
4
|
-
|
5
|
-
from .fuzzy_parse_json import fuzzy_parse_json
|
6
|
-
|
7
|
-
# Precompile the regex for extracting JSON code blocks
|
8
|
-
_JSON_BLOCK_PATTERN = re.compile(r"```json\s*(.*?)\s*```", re.DOTALL)
|
9
|
-
|
10
|
-
|
11
|
-
def to_json(
|
12
|
-
input_data: str | list[str], /, *, fuzzy_parse: bool = False
|
13
|
-
) -> dict[str, Any] | list[dict[str, Any]]:
|
14
|
-
"""
|
15
|
-
Extract and parse JSON content from a string or markdown code blocks.
|
16
|
-
|
17
|
-
Attempts direct JSON parsing first. If that fails, looks for JSON content
|
18
|
-
within markdown code blocks denoted by ```json.
|
19
|
-
|
20
|
-
Args:
|
21
|
-
input_data (str | list[str]): The input string or list of strings to parse.
|
22
|
-
fuzzy_parse (bool): If True, attempts fuzzy JSON parsing on failed attempts.
|
23
|
-
|
24
|
-
Returns:
|
25
|
-
dict or list of dicts:
|
26
|
-
- If a single JSON object is found: returns a dict.
|
27
|
-
- If multiple JSON objects are found: returns a list of dicts.
|
28
|
-
- If no valid JSON found: returns an empty list.
|
29
|
-
"""
|
30
|
-
|
31
|
-
# If input_data is a list, join into a single string
|
32
|
-
if isinstance(input_data, list):
|
33
|
-
input_str = "\n".join(input_data)
|
34
|
-
else:
|
35
|
-
input_str = input_data
|
36
|
-
|
37
|
-
# 1. Try direct parsing
|
38
|
-
try:
|
39
|
-
if fuzzy_parse:
|
40
|
-
return fuzzy_parse_json(input_str)
|
41
|
-
return json.loads(input_str)
|
42
|
-
except Exception:
|
43
|
-
pass
|
44
|
-
|
45
|
-
# 2. Attempt extracting JSON blocks from markdown
|
46
|
-
matches = _JSON_BLOCK_PATTERN.findall(input_str)
|
47
|
-
if not matches:
|
48
|
-
return []
|
49
|
-
|
50
|
-
# If only one match, return single dict; if multiple, return list of dicts
|
51
|
-
if len(matches) == 1:
|
52
|
-
data_str = matches[0]
|
53
|
-
return (
|
54
|
-
fuzzy_parse_json(data_str) if fuzzy_parse else json.loads(data_str)
|
55
|
-
)
|
56
|
-
|
57
|
-
# Multiple matches
|
58
|
-
if fuzzy_parse:
|
59
|
-
return [fuzzy_parse_json(m) for m in matches]
|
60
|
-
else:
|
61
|
-
return [json.loads(m) for m in matches]
|