lionagi 0.0.208__py3-none-any.whl → 0.0.210__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.
Files changed (104) hide show
  1. lionagi/__init__.py +4 -6
  2. lionagi/api_service/base_endpoint.py +65 -0
  3. lionagi/api_service/base_rate_limiter.py +121 -0
  4. lionagi/api_service/base_service.py +146 -0
  5. lionagi/api_service/chat_completion.py +6 -0
  6. lionagi/api_service/embeddings.py +6 -0
  7. lionagi/api_service/payload_package.py +47 -0
  8. lionagi/api_service/status_tracker.py +29 -0
  9. lionagi/core/__init__.py +5 -9
  10. lionagi/core/branch.py +1191 -0
  11. lionagi/core/flow.py +423 -0
  12. lionagi/core/{instruction_set/instruction_set.py → instruction_set.py} +3 -3
  13. lionagi/core/session.py +872 -0
  14. lionagi/schema/__init__.py +5 -8
  15. lionagi/schema/base_schema.py +821 -0
  16. lionagi/{_services → services}/base_service.py +4 -4
  17. lionagi/{_services → services}/oai.py +4 -4
  18. lionagi/structures/graph.py +1 -1
  19. lionagi/structures/relationship.py +1 -1
  20. lionagi/structures/structure.py +1 -1
  21. lionagi/tools/tool_manager.py +0 -163
  22. lionagi/tools/tool_util.py +2 -1
  23. lionagi/utils/__init__.py +7 -14
  24. lionagi/utils/api_util.py +63 -2
  25. lionagi/utils/core_utils.py +338 -0
  26. lionagi/utils/sys_util.py +3 -3
  27. lionagi/version.py +1 -1
  28. {lionagi-0.0.208.dist-info → lionagi-0.0.210.dist-info}/METADATA +28 -29
  29. lionagi-0.0.210.dist-info/RECORD +56 -0
  30. lionagi/_services/anthropic.py +0 -79
  31. lionagi/_services/anyscale.py +0 -0
  32. lionagi/_services/azure.py +0 -1
  33. lionagi/_services/bedrock.py +0 -0
  34. lionagi/_services/everlyai.py +0 -0
  35. lionagi/_services/gemini.py +0 -0
  36. lionagi/_services/gpt4all.py +0 -0
  37. lionagi/_services/huggingface.py +0 -0
  38. lionagi/_services/litellm.py +0 -33
  39. lionagi/_services/localai.py +0 -0
  40. lionagi/_services/openllm.py +0 -0
  41. lionagi/_services/openrouter.py +0 -44
  42. lionagi/_services/perplexity.py +0 -0
  43. lionagi/_services/predibase.py +0 -0
  44. lionagi/_services/rungpt.py +0 -0
  45. lionagi/_services/vllm.py +0 -0
  46. lionagi/_services/xinference.py +0 -0
  47. lionagi/agents/planner.py +0 -1
  48. lionagi/agents/prompter.py +0 -1
  49. lionagi/agents/scorer.py +0 -1
  50. lionagi/agents/summarizer.py +0 -1
  51. lionagi/agents/validator.py +0 -1
  52. lionagi/bridge/__init__.py +0 -22
  53. lionagi/bridge/langchain.py +0 -195
  54. lionagi/bridge/llama_index.py +0 -266
  55. lionagi/core/branch/__init__.py +0 -0
  56. lionagi/core/branch/branch.py +0 -841
  57. lionagi/core/branch/cluster.py +0 -1
  58. lionagi/core/branch/conversation.py +0 -787
  59. lionagi/core/core_util.py +0 -0
  60. lionagi/core/flow/__init__.py +0 -0
  61. lionagi/core/flow/flow.py +0 -19
  62. lionagi/core/flow/flow_util.py +0 -62
  63. lionagi/core/instruction_set/__init__.py +0 -0
  64. lionagi/core/messages/__init__.py +0 -0
  65. lionagi/core/sessions/__init__.py +0 -0
  66. lionagi/core/sessions/session.py +0 -504
  67. lionagi/datastores/__init__.py +0 -1
  68. lionagi/datastores/chroma.py +0 -1
  69. lionagi/datastores/deeplake.py +0 -1
  70. lionagi/datastores/elasticsearch.py +0 -1
  71. lionagi/datastores/lantern.py +0 -1
  72. lionagi/datastores/pinecone.py +0 -1
  73. lionagi/datastores/postgres.py +0 -1
  74. lionagi/datastores/qdrant.py +0 -1
  75. lionagi/loaders/__init__.py +0 -18
  76. lionagi/loaders/chunker.py +0 -166
  77. lionagi/loaders/load_util.py +0 -240
  78. lionagi/loaders/reader.py +0 -122
  79. lionagi/models/__init__.py +0 -0
  80. lionagi/models/base_model.py +0 -0
  81. lionagi/models/imodel.py +0 -53
  82. lionagi/schema/async_queue.py +0 -158
  83. lionagi/schema/base_condition.py +0 -1
  84. lionagi/schema/base_node.py +0 -422
  85. lionagi/schema/base_tool.py +0 -44
  86. lionagi/schema/data_logger.py +0 -126
  87. lionagi/schema/data_node.py +0 -88
  88. lionagi/schema/status_tracker.py +0 -37
  89. lionagi/tests/test_utils/test_encrypt_util.py +0 -323
  90. lionagi/utils/encrypt_util.py +0 -283
  91. lionagi/utils/url_util.py +0 -55
  92. lionagi-0.0.208.dist-info/RECORD +0 -106
  93. lionagi/{agents → api_service}/__init__.py +0 -0
  94. lionagi/core/{branch/branch_manager.py → branch_manager.py} +0 -0
  95. lionagi/core/{messages/messages.py → messages.py} +3 -3
  96. /lionagi/{_services → services}/__init__.py +0 -0
  97. /lionagi/{_services → services}/mistralai.py +0 -0
  98. /lionagi/{_services → services}/mlx_service.py +0 -0
  99. /lionagi/{_services → services}/ollama.py +0 -0
  100. /lionagi/{_services → services}/services.py +0 -0
  101. /lionagi/{_services → services}/transformers.py +0 -0
  102. {lionagi-0.0.208.dist-info → lionagi-0.0.210.dist-info}/LICENSE +0 -0
  103. {lionagi-0.0.208.dist-info → lionagi-0.0.210.dist-info}/WHEEL +0 -0
  104. {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
@@ -2,7 +2,7 @@ from typing import List, Any
2
2
  from pydantic import Field
3
3
 
4
4
  from ..utils.call_util import lcall
5
- from ..schema.base_node import BaseNode
5
+ from ..schema.base_schema import BaseNode
6
6
  from .relationship import Relationship
7
7
 
8
8
 
@@ -1,6 +1,6 @@
1
1
  from pydantic import Field
2
2
  from typing import Dict, Optional, Any
3
- from ..schema.base_node import BaseNode
3
+ from ..schema.base_schema import BaseNode
4
4
 
5
5
 
6
6
  class Relationship(BaseNode):
@@ -1,5 +1,5 @@
1
1
  from typing import TypeVar
2
- from ..schema import BaseNode
2
+ from ..schema.base_schema import BaseNode
3
3
  from .graph import Graph
4
4
  from .relationship import Relationship
5
5
 
@@ -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
@@ -1,5 +1,6 @@
1
+ from ..schema.base_schema import Tool
2
+
1
3
  import inspect
2
- from ..schema.base_tool import Tool
3
4
 
4
5
  def _extract_docstring_details_google(func):
5
6
  """
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
- "is_package_installed", "install_import", "to_df",
24
- 'get_timestamp', 'create_copy', 'create_path', 'split_path',
25
- 'get_bins', 'change_dict_key', 'str_to_num', 'create_id',
26
- 'as_dict', 'to_list', 'to_readable_dict', 'nfilter', 'nset',
27
- 'nget', 'nmerge', 'ninsert', 'flatten', 'unflatten',
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
- encoding = tiktoken.get_encoding(token_encoding_name)
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
+