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.
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
+