lionagi 0.0.208__py3-none-any.whl → 0.0.210__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- lionagi/__init__.py +4 -6
- lionagi/api_service/base_endpoint.py +65 -0
- lionagi/api_service/base_rate_limiter.py +121 -0
- lionagi/api_service/base_service.py +146 -0
- lionagi/api_service/chat_completion.py +6 -0
- lionagi/api_service/embeddings.py +6 -0
- lionagi/api_service/payload_package.py +47 -0
- lionagi/api_service/status_tracker.py +29 -0
- lionagi/core/__init__.py +5 -9
- lionagi/core/branch.py +1191 -0
- lionagi/core/flow.py +423 -0
- lionagi/core/{instruction_set/instruction_set.py → instruction_set.py} +3 -3
- lionagi/core/session.py +872 -0
- lionagi/schema/__init__.py +5 -8
- lionagi/schema/base_schema.py +821 -0
- lionagi/{_services → services}/base_service.py +4 -4
- lionagi/{_services → services}/oai.py +4 -4
- lionagi/structures/graph.py +1 -1
- lionagi/structures/relationship.py +1 -1
- lionagi/structures/structure.py +1 -1
- lionagi/tools/tool_manager.py +0 -163
- lionagi/tools/tool_util.py +2 -1
- lionagi/utils/__init__.py +7 -14
- lionagi/utils/api_util.py +63 -2
- lionagi/utils/core_utils.py +338 -0
- lionagi/utils/sys_util.py +3 -3
- lionagi/version.py +1 -1
- {lionagi-0.0.208.dist-info → lionagi-0.0.210.dist-info}/METADATA +28 -29
- lionagi-0.0.210.dist-info/RECORD +56 -0
- lionagi/_services/anthropic.py +0 -79
- lionagi/_services/anyscale.py +0 -0
- lionagi/_services/azure.py +0 -1
- lionagi/_services/bedrock.py +0 -0
- lionagi/_services/everlyai.py +0 -0
- lionagi/_services/gemini.py +0 -0
- lionagi/_services/gpt4all.py +0 -0
- lionagi/_services/huggingface.py +0 -0
- lionagi/_services/litellm.py +0 -33
- lionagi/_services/localai.py +0 -0
- lionagi/_services/openllm.py +0 -0
- lionagi/_services/openrouter.py +0 -44
- lionagi/_services/perplexity.py +0 -0
- lionagi/_services/predibase.py +0 -0
- lionagi/_services/rungpt.py +0 -0
- lionagi/_services/vllm.py +0 -0
- lionagi/_services/xinference.py +0 -0
- lionagi/agents/planner.py +0 -1
- lionagi/agents/prompter.py +0 -1
- lionagi/agents/scorer.py +0 -1
- lionagi/agents/summarizer.py +0 -1
- lionagi/agents/validator.py +0 -1
- lionagi/bridge/__init__.py +0 -22
- lionagi/bridge/langchain.py +0 -195
- lionagi/bridge/llama_index.py +0 -266
- lionagi/core/branch/__init__.py +0 -0
- lionagi/core/branch/branch.py +0 -841
- lionagi/core/branch/cluster.py +0 -1
- lionagi/core/branch/conversation.py +0 -787
- lionagi/core/core_util.py +0 -0
- lionagi/core/flow/__init__.py +0 -0
- lionagi/core/flow/flow.py +0 -19
- lionagi/core/flow/flow_util.py +0 -62
- lionagi/core/instruction_set/__init__.py +0 -0
- lionagi/core/messages/__init__.py +0 -0
- lionagi/core/sessions/__init__.py +0 -0
- lionagi/core/sessions/session.py +0 -504
- lionagi/datastores/__init__.py +0 -1
- lionagi/datastores/chroma.py +0 -1
- lionagi/datastores/deeplake.py +0 -1
- lionagi/datastores/elasticsearch.py +0 -1
- lionagi/datastores/lantern.py +0 -1
- lionagi/datastores/pinecone.py +0 -1
- lionagi/datastores/postgres.py +0 -1
- lionagi/datastores/qdrant.py +0 -1
- lionagi/loaders/__init__.py +0 -18
- lionagi/loaders/chunker.py +0 -166
- lionagi/loaders/load_util.py +0 -240
- lionagi/loaders/reader.py +0 -122
- lionagi/models/__init__.py +0 -0
- lionagi/models/base_model.py +0 -0
- lionagi/models/imodel.py +0 -53
- lionagi/schema/async_queue.py +0 -158
- lionagi/schema/base_condition.py +0 -1
- lionagi/schema/base_node.py +0 -422
- lionagi/schema/base_tool.py +0 -44
- lionagi/schema/data_logger.py +0 -126
- lionagi/schema/data_node.py +0 -88
- lionagi/schema/status_tracker.py +0 -37
- lionagi/tests/test_utils/test_encrypt_util.py +0 -323
- lionagi/utils/encrypt_util.py +0 -283
- lionagi/utils/url_util.py +0 -55
- lionagi-0.0.208.dist-info/RECORD +0 -106
- lionagi/{agents → api_service}/__init__.py +0 -0
- lionagi/core/{branch/branch_manager.py → branch_manager.py} +0 -0
- lionagi/core/{messages/messages.py → messages.py} +3 -3
- /lionagi/{_services → services}/__init__.py +0 -0
- /lionagi/{_services → services}/mistralai.py +0 -0
- /lionagi/{_services → services}/mlx_service.py +0 -0
- /lionagi/{_services → services}/ollama.py +0 -0
- /lionagi/{_services → services}/services.py +0 -0
- /lionagi/{_services → services}/transformers.py +0 -0
- {lionagi-0.0.208.dist-info → lionagi-0.0.210.dist-info}/LICENSE +0 -0
- {lionagi-0.0.208.dist-info → lionagi-0.0.210.dist-info}/WHEEL +0 -0
- {lionagi-0.0.208.dist-info → lionagi-0.0.210.dist-info}/top_level.txt +0 -0
@@ -103,7 +103,7 @@ class BaseRateLimiter(ABC):
|
|
103
103
|
api_key: str,
|
104
104
|
max_attempts: int = 3,
|
105
105
|
method: str = "post",
|
106
|
-
payload: Dict[str, any]=None
|
106
|
+
payload: Dict[str, any]=None, **kwargs
|
107
107
|
) -> Optional[Dict[str, any]]:
|
108
108
|
"""
|
109
109
|
Makes an API call to the specified endpoint using the provided HTTP session.
|
@@ -125,7 +125,7 @@ class BaseRateLimiter(ABC):
|
|
125
125
|
if self.available_request_capacity < 1 or self.available_token_capacity < 10: # Minimum token count
|
126
126
|
await asyncio.sleep(1) # Wait for capacity
|
127
127
|
continue
|
128
|
-
required_tokens = APIUtil.calculate_num_token(payload, endpoint, self.token_encoding_name)
|
128
|
+
required_tokens = APIUtil.calculate_num_token(payload, endpoint, self.token_encoding_name, **kwargs)
|
129
129
|
|
130
130
|
if await self.request_permission(required_tokens):
|
131
131
|
request_headers = {"Authorization": f"Bearer {api_key}"}
|
@@ -343,7 +343,7 @@ class BaseService:
|
|
343
343
|
if not self.endpoints[ep]._has_initialized:
|
344
344
|
await self.endpoints[ep].init_rate_limiter()
|
345
345
|
|
346
|
-
async def call_api(self, payload, endpoint, method):
|
346
|
+
async def call_api(self, payload, endpoint, method, **kwargs):
|
347
347
|
"""
|
348
348
|
Calls the specified API endpoint with the given payload and method.
|
349
349
|
|
@@ -363,7 +363,7 @@ class BaseService:
|
|
363
363
|
async with aiohttp.ClientSession() as http_session:
|
364
364
|
completion = await self.endpoints[endpoint].rate_limiter._call_api(
|
365
365
|
http_session=http_session, endpoint=endpoint, base_url=self.base_url, api_key=self.api_key,
|
366
|
-
method=method, payload=payload)
|
366
|
+
method=method, payload=payload, **kwargs)
|
367
367
|
return completion
|
368
368
|
|
369
369
|
|
@@ -38,7 +38,7 @@ class OpenAIService(BaseService):
|
|
38
38
|
)
|
39
39
|
self.active_endpoint = []
|
40
40
|
|
41
|
-
async def serve(self, input_, endpoint="chat/completions", method="post", **kwargs):
|
41
|
+
async def serve(self, input_, endpoint="chat/completions", method="post", tokenizer_kwargs={}, **kwargs):
|
42
42
|
"""
|
43
43
|
Serves the input using the specified endpoint and method.
|
44
44
|
|
@@ -66,11 +66,11 @@ class OpenAIService(BaseService):
|
|
66
66
|
if endpoint not in self.active_endpoint:
|
67
67
|
await self. init_endpoint(endpoint)
|
68
68
|
if endpoint == "chat/completions":
|
69
|
-
return await self.serve_chat(input_, **kwargs)
|
69
|
+
return await self.serve_chat(input_, tokenizer_kwargs=tokenizer_kwargs, **kwargs)
|
70
70
|
else:
|
71
71
|
return ValueError(f'{endpoint} is currently not supported')
|
72
72
|
|
73
|
-
async def serve_chat(self, messages, **kwargs):
|
73
|
+
async def serve_chat(self, messages, tokenizer_kwargs={}, **kwargs):
|
74
74
|
"""
|
75
75
|
Serves the chat completion request with the given messages.
|
76
76
|
|
@@ -91,7 +91,7 @@ class OpenAIService(BaseService):
|
|
91
91
|
messages, self.endpoints["chat/completions"].config, self.schema["chat/completions"], **kwargs)
|
92
92
|
|
93
93
|
try:
|
94
|
-
completion = await self.call_api(payload, "chat/completions", "post")
|
94
|
+
completion = await self.call_api(payload, "chat/completions", "post", **tokenizer_kwargs)
|
95
95
|
return payload, completion
|
96
96
|
except Exception as e:
|
97
97
|
self.status_tracker.num_tasks_failed += 1
|
lionagi/structures/graph.py
CHANGED
lionagi/structures/structure.py
CHANGED
lionagi/tools/tool_manager.py
CHANGED
@@ -1,163 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import asyncio
|
3
|
-
from typing import Dict, Union, List, Tuple, Any
|
4
|
-
from lionagi.utils.call_util import lcall, is_coroutine_func, _call_handler, alcall
|
5
|
-
from lionagi.schema import BaseNode, Tool
|
6
|
-
|
7
|
-
|
8
|
-
class ToolManager(BaseNode):
|
9
|
-
"""
|
10
|
-
A manager class for handling the registration and invocation of tools that are subclasses of Tool.
|
11
|
-
|
12
|
-
This class maintains a registry of tool instances, allowing for dynamic invocation based on
|
13
|
-
tool name and provided arguments. It supports both synchronous and asynchronous tool function
|
14
|
-
calls.
|
15
|
-
|
16
|
-
Attributes:
|
17
|
-
registry (Dict[str, Tool]): A dictionary to hold registered tools, keyed by their names.
|
18
|
-
"""
|
19
|
-
registry: Dict = {}
|
20
|
-
|
21
|
-
def name_existed(self, name: str) -> bool:
|
22
|
-
"""
|
23
|
-
Checks if a tool name already exists in the registry.
|
24
|
-
|
25
|
-
Args:
|
26
|
-
name (str): The name of the tool to check.
|
27
|
-
|
28
|
-
Returns:
|
29
|
-
bool: True if the name exists, False otherwise.
|
30
|
-
"""
|
31
|
-
return True if name in self.registry.keys() else False
|
32
|
-
|
33
|
-
def _register_tool(self, tool: Tool) -> None:
|
34
|
-
"""
|
35
|
-
Registers a tool in the registry. Raises a TypeError if the object is not an instance of Tool.
|
36
|
-
|
37
|
-
Args:
|
38
|
-
tool (Tool): The tool instance to register.
|
39
|
-
|
40
|
-
Raises:
|
41
|
-
TypeError: If the provided object is not an instance of Tool.
|
42
|
-
"""
|
43
|
-
if not isinstance(tool, Tool):
|
44
|
-
raise TypeError('Please register a Tool object.')
|
45
|
-
name = tool.schema_['function']['name']
|
46
|
-
self.registry.update({name: tool})
|
47
|
-
|
48
|
-
async def invoke(self, func_call: Tuple[str, Dict[str, Any]]) -> Any:
|
49
|
-
"""
|
50
|
-
Invokes a registered tool's function with the given arguments. Supports both coroutine and regular functions.
|
51
|
-
|
52
|
-
Args:
|
53
|
-
func_call (Tuple[str, Dict[str, Any]]): A tuple containing the function name and a dictionary of keyword arguments.
|
54
|
-
|
55
|
-
Returns:
|
56
|
-
Any: The result of the function call.
|
57
|
-
|
58
|
-
Raises:
|
59
|
-
ValueError: If the function name is not registered or if there's an error during function invocation.
|
60
|
-
"""
|
61
|
-
name, kwargs = func_call
|
62
|
-
if self.name_existed(name):
|
63
|
-
tool = self.registry[name]
|
64
|
-
func = tool.func
|
65
|
-
parser = tool.parser
|
66
|
-
try:
|
67
|
-
if is_coroutine_func(func):
|
68
|
-
tasks = [_call_handler(func, **kwargs)]
|
69
|
-
out = await asyncio.gather(*tasks)
|
70
|
-
return parser(out[0]) if parser else out[0]
|
71
|
-
else:
|
72
|
-
out = func(**kwargs)
|
73
|
-
return parser(out) if parser else out
|
74
|
-
except Exception as e:
|
75
|
-
raise ValueError(f"Error when invoking function {name} with arguments {kwargs} with error message {e}")
|
76
|
-
else:
|
77
|
-
raise ValueError(f"Function {name} is not registered.")
|
78
|
-
|
79
|
-
@staticmethod
|
80
|
-
def get_function_call(response: Dict) -> Tuple[str, Dict]:
|
81
|
-
"""
|
82
|
-
Extracts a function call and arguments from a response dictionary.
|
83
|
-
|
84
|
-
Args:
|
85
|
-
response (Dict): The response dictionary containing the function call information.
|
86
|
-
|
87
|
-
Returns:
|
88
|
-
Tuple[str, Dict]: A tuple containing the function name and a dictionary of arguments.
|
89
|
-
|
90
|
-
Raises:
|
91
|
-
ValueError: If the response does not contain valid function call information.
|
92
|
-
"""
|
93
|
-
try:
|
94
|
-
func = response['action'][7:]
|
95
|
-
args = json.loads(response['arguments'])
|
96
|
-
return (func, args)
|
97
|
-
except:
|
98
|
-
try:
|
99
|
-
func = response['recipient_name'].split('.')[-1]
|
100
|
-
args = response['parameters']
|
101
|
-
return (func, args)
|
102
|
-
except:
|
103
|
-
raise ValueError('response is not a valid function call')
|
104
|
-
|
105
|
-
def register_tools(self, tools: List[Tool]) -> None:
|
106
|
-
"""
|
107
|
-
Registers multiple tools in the registry.
|
108
|
-
|
109
|
-
Args:
|
110
|
-
tools (List[Tool]): A list of tool instances to register.
|
111
|
-
"""
|
112
|
-
lcall(tools, self._register_tool)
|
113
|
-
|
114
|
-
def to_tool_schema_list(self) -> List[Dict[str, Any]]:
|
115
|
-
"""
|
116
|
-
Generates a list of schemas for all registered tools.
|
117
|
-
|
118
|
-
Returns:
|
119
|
-
List[Dict[str, Any]]: A list of tool schemas.
|
120
|
-
|
121
|
-
"""
|
122
|
-
schema_list = []
|
123
|
-
for tool in self.registry.values():
|
124
|
-
schema_list.append(tool.schema_)
|
125
|
-
return schema_list
|
126
|
-
|
127
|
-
def _tool_parser(self, tools: Union[Dict, Tool, List[Tool], str, List[str], List[Dict]], **kwargs) -> Dict:
|
128
|
-
"""
|
129
|
-
Parses tool information and generates a dictionary for tool invocation.
|
130
|
-
|
131
|
-
Args:
|
132
|
-
tools: Tool information which can be a single Tool instance, a list of Tool instances, a tool name, or a list of tool names.
|
133
|
-
**kwargs: Additional keyword arguments.
|
134
|
-
|
135
|
-
Returns:
|
136
|
-
Dict: A dictionary containing tool schema information and any additional keyword arguments.
|
137
|
-
|
138
|
-
Raises:
|
139
|
-
ValueError: If a tool name is provided that is not registered.
|
140
|
-
"""
|
141
|
-
def tool_check(tool):
|
142
|
-
if isinstance(tool, dict):
|
143
|
-
return tool
|
144
|
-
elif isinstance(tool, Tool):
|
145
|
-
return tool.schema_
|
146
|
-
elif isinstance(tool, str):
|
147
|
-
if self.name_existed(tool):
|
148
|
-
tool = self.registry[tool]
|
149
|
-
return tool.schema_
|
150
|
-
else:
|
151
|
-
raise ValueError(f'Function {tool} is not registered.')
|
152
|
-
|
153
|
-
if isinstance(tools, bool):
|
154
|
-
tool_kwarg = {"tools": self.to_tool_schema_list()}
|
155
|
-
kwargs = {**tool_kwarg, **kwargs}
|
156
|
-
|
157
|
-
else:
|
158
|
-
if not isinstance(tools, list):
|
159
|
-
tools = [tools]
|
160
|
-
tool_kwarg = {"tools": lcall(tools, tool_check)}
|
161
|
-
kwargs = {**tool_kwarg, **kwargs}
|
162
|
-
|
163
|
-
return kwargs
|
lionagi/tools/tool_util.py
CHANGED
lionagi/utils/__init__.py
CHANGED
@@ -1,16 +1,12 @@
|
|
1
|
-
from .sys_util import
|
2
|
-
get_timestamp, create_copy, create_path, split_path,
|
3
|
-
get_bins, change_dict_key, str_to_num, create_id,
|
4
|
-
as_dict, is_package_installed, install_import, to_df
|
5
|
-
)
|
1
|
+
from .sys_util import as_dict, create_copy, get_bins, get_timestamp, str_to_num, to_df
|
6
2
|
|
7
3
|
from .nested_util import (
|
8
4
|
to_readable_dict, nfilter, nset, nget,
|
9
5
|
nmerge, ninsert, flatten, unflatten,
|
10
6
|
is_structure_homogeneous, get_flattened_keys)
|
11
7
|
|
8
|
+
from .core_utils import CoreUtil
|
12
9
|
from .api_util import APIUtil
|
13
|
-
from .encrypt_util import EncrytionUtil
|
14
10
|
from .io_util import IOUtil
|
15
11
|
|
16
12
|
from .call_util import (
|
@@ -20,12 +16,9 @@ from .call_util import (
|
|
20
16
|
|
21
17
|
|
22
18
|
__all__ = [
|
23
|
-
"
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
'is_structure_homogeneous', 'get_flattened_keys', 'APIUtil',
|
29
|
-
'EncrytionUtil', 'IOUtil', 'lcall', 'alcall', 'mcall', 'tcall',
|
30
|
-
'bcall', 'rcall', 'CallDecorator'
|
19
|
+
"as_dict", "create_copy", "get_bins", "get_timestamp", "str_to_num", "to_df",
|
20
|
+
"to_readable_dict", "nfilter", "nset", "nget", "nmerge", "ninsert",
|
21
|
+
"flatten", "unflatten", "is_structure_homogeneous", "get_flattened_keys",
|
22
|
+
"CoreUtil", "APIUtil", "IOUtil",
|
23
|
+
"to_list", "lcall", "alcall", "mcall", "tcall", "bcall", "rcall", "CallDecorator"
|
31
24
|
]
|
lionagi/utils/api_util.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# import requests
|
1
2
|
import aiohttp
|
2
3
|
import asyncio
|
3
4
|
import hashlib
|
@@ -8,6 +9,7 @@ import tiktoken
|
|
8
9
|
from functools import lru_cache
|
9
10
|
from aiocache import cached
|
10
11
|
from typing import Any, Callable, Dict, Optional
|
12
|
+
# from bs4 import BeautifulSoup
|
11
13
|
|
12
14
|
from .sys_util import strip_lower
|
13
15
|
|
@@ -284,6 +286,8 @@ class APIUtil:
|
|
284
286
|
payload: Dict[str, Any] = None,
|
285
287
|
api_endpoint: str = None,
|
286
288
|
token_encoding_name: str = None,
|
289
|
+
disallowed_special = None,
|
290
|
+
**kwargs
|
287
291
|
) -> int:
|
288
292
|
"""
|
289
293
|
Calculates the number of tokens required for a request based on the payload and API endpoint.
|
@@ -309,7 +313,10 @@ class APIUtil:
|
|
309
313
|
# Expected token calculation for the given payload and endpoint.
|
310
314
|
"""
|
311
315
|
|
312
|
-
|
316
|
+
if disallowed_special:
|
317
|
+
kwargs['disallowed_special'] = disallowed_special
|
318
|
+
|
319
|
+
encoding = tiktoken.get_encoding(token_encoding_name, **kwargs)
|
313
320
|
if api_endpoint.endswith("completions"):
|
314
321
|
max_tokens = payload.get("max_tokens", 15)
|
315
322
|
n = payload.get("n", 1)
|
@@ -373,4 +380,58 @@ class APIUtil:
|
|
373
380
|
payload.update({key: config[key]})
|
374
381
|
|
375
382
|
return payload
|
376
|
-
|
383
|
+
|
384
|
+
# @staticmethod
|
385
|
+
# def get_url_response(url: str, timeout: tuple = (1, 1), **kwargs) -> requests.Response:
|
386
|
+
# """
|
387
|
+
# Sends a GET request to a URL and returns the response.
|
388
|
+
|
389
|
+
# Args:
|
390
|
+
# url (str): The URL to send the GET request to.
|
391
|
+
# timeout (tuple): A tuple specifying the connection and read timeouts in seconds.
|
392
|
+
# Defaults to (1, 1).
|
393
|
+
# **kwargs: Additional keyword arguments to be passed to the requests.get() function.
|
394
|
+
|
395
|
+
# Returns:
|
396
|
+
# requests.Response: A Response object containing the server's response to the GET request.
|
397
|
+
|
398
|
+
# Raises:
|
399
|
+
# TimeoutError: If a timeout occurs while requesting or reading the response.
|
400
|
+
# Exception: If an error other than a timeout occurs during the request.
|
401
|
+
# """
|
402
|
+
# try:
|
403
|
+
# response = requests.get(url, timeout=timeout, **kwargs)
|
404
|
+
# response.raise_for_status()
|
405
|
+
# return response
|
406
|
+
# except requests.exceptions.ConnectTimeout:
|
407
|
+
# raise TimeoutError(f"Timeout: requesting >{timeout[0]} seconds.")
|
408
|
+
# except requests.exceptions.ReadTimeout:
|
409
|
+
# raise TimeoutError(f"Timeout: reading >{timeout[1]} seconds.")
|
410
|
+
# except Exception as e:
|
411
|
+
# raise e
|
412
|
+
|
413
|
+
# @staticmethod
|
414
|
+
# def get_url_content(url: str) -> str:
|
415
|
+
# """
|
416
|
+
# Retrieve and parse the content from a given URL.
|
417
|
+
|
418
|
+
# Args:
|
419
|
+
# url (str): The URL to fetch and parse.
|
420
|
+
|
421
|
+
# Returns:
|
422
|
+
# str: The text content extracted from the URL.
|
423
|
+
|
424
|
+
# Raises:
|
425
|
+
# ValueError: If there is an issue during content retrieval or parsing.
|
426
|
+
# """
|
427
|
+
# try:
|
428
|
+
# response = requests.get(url)
|
429
|
+
# response.raise_for_status()
|
430
|
+
|
431
|
+
# soup = BeautifulSoup(response.text, 'html.parser')
|
432
|
+
|
433
|
+
# text_content = ' '.join([p.get_text() for p in soup.find_all('p')])
|
434
|
+
# return text_content
|
435
|
+
# except Exception as e:
|
436
|
+
# raise f"Error fetching content for {url}: {e}"
|
437
|
+
|