lionagi 0.0.316__py3-none-any.whl → 0.1.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- lionagi/core/__init__.py +19 -8
- lionagi/core/agent/__init__.py +0 -3
- lionagi/core/agent/base_agent.py +26 -30
- lionagi/core/branch/__init__.py +0 -4
- lionagi/core/branch/{base_branch.py → base.py} +13 -14
- lionagi/core/branch/branch.py +22 -20
- lionagi/core/branch/executable_branch.py +0 -347
- lionagi/core/branch/{branch_flow_mixin.py → flow_mixin.py} +6 -6
- lionagi/core/branch/util.py +1 -1
- lionagi/core/direct/__init__.py +10 -1
- lionagi/core/direct/cot.py +61 -26
- lionagi/core/direct/plan.py +10 -8
- lionagi/core/direct/predict.py +5 -5
- lionagi/core/direct/react.py +8 -8
- lionagi/core/direct/score.py +4 -4
- lionagi/core/direct/select.py +4 -4
- lionagi/core/direct/utils.py +7 -4
- lionagi/core/direct/vote.py +2 -2
- lionagi/core/execute/base_executor.py +50 -0
- lionagi/core/execute/branch_executor.py +233 -0
- lionagi/core/execute/instruction_map_executor.py +131 -0
- lionagi/core/execute/structure_executor.py +218 -0
- lionagi/core/flow/monoflow/ReAct.py +4 -4
- lionagi/core/flow/monoflow/chat.py +6 -6
- lionagi/core/flow/monoflow/chat_mixin.py +24 -34
- lionagi/core/flow/monoflow/followup.py +4 -4
- lionagi/core/flow/polyflow/__init__.py +1 -1
- lionagi/core/flow/polyflow/chat.py +15 -12
- lionagi/core/{prompt/action_template.py → form/action_form.py} +2 -2
- lionagi/core/{prompt → form}/field_validator.py +40 -31
- lionagi/core/form/form.py +302 -0
- lionagi/core/form/mixin.py +214 -0
- lionagi/core/{prompt/scored_template.py → form/scored_form.py} +2 -2
- lionagi/core/generic/__init__.py +37 -0
- lionagi/core/generic/action.py +26 -0
- lionagi/core/generic/component.py +457 -0
- lionagi/core/generic/condition.py +44 -0
- lionagi/core/generic/data_logger.py +305 -0
- lionagi/core/generic/edge.py +110 -0
- lionagi/core/generic/mail.py +90 -0
- lionagi/core/generic/mailbox.py +36 -0
- lionagi/core/generic/node.py +285 -0
- lionagi/core/generic/relation.py +70 -0
- lionagi/core/generic/signal.py +22 -0
- lionagi/core/generic/structure.py +362 -0
- lionagi/core/generic/transfer.py +20 -0
- lionagi/core/generic/work.py +40 -0
- lionagi/core/graph/graph.py +126 -0
- lionagi/core/graph/tree.py +190 -0
- lionagi/core/mail/__init__.py +0 -8
- lionagi/core/mail/mail_manager.py +12 -10
- lionagi/core/mail/schema.py +9 -2
- lionagi/core/messages/__init__.py +0 -3
- lionagi/core/messages/schema.py +17 -225
- lionagi/core/session/__init__.py +0 -3
- lionagi/core/session/session.py +25 -23
- lionagi/core/tool/__init__.py +3 -1
- lionagi/core/tool/tool.py +28 -0
- lionagi/core/tool/tool_manager.py +75 -75
- lionagi/integrations/chunker/chunk.py +7 -7
- lionagi/integrations/config/oai_configs.py +4 -4
- lionagi/integrations/loader/load.py +6 -6
- lionagi/integrations/loader/load_util.py +8 -8
- lionagi/libs/ln_api.py +3 -3
- lionagi/libs/ln_parse.py +43 -6
- lionagi/libs/ln_validate.py +288 -0
- lionagi/libs/sys_util.py +28 -6
- lionagi/tests/libs/test_async.py +0 -0
- lionagi/tests/libs/test_field_validators.py +353 -0
- lionagi/tests/test_core/test_base_branch.py +0 -1
- lionagi/tests/test_core/test_branch.py +3 -0
- lionagi/tests/test_core/test_session_base_util.py +1 -0
- lionagi/version.py +1 -1
- {lionagi-0.0.316.dist-info → lionagi-0.1.0.dist-info}/METADATA +1 -1
- lionagi-0.1.0.dist-info/RECORD +136 -0
- lionagi/core/prompt/prompt_template.py +0 -312
- lionagi/core/schema/__init__.py +0 -22
- lionagi/core/schema/action_node.py +0 -29
- lionagi/core/schema/base_mixin.py +0 -296
- lionagi/core/schema/base_node.py +0 -199
- lionagi/core/schema/condition.py +0 -24
- lionagi/core/schema/data_logger.py +0 -354
- lionagi/core/schema/data_node.py +0 -93
- lionagi/core/schema/prompt_template.py +0 -67
- lionagi/core/schema/structure.py +0 -912
- lionagi/core/tool/manual.py +0 -1
- lionagi-0.0.316.dist-info/RECORD +0 -121
- /lionagi/core/{branch/base → execute}/__init__.py +0 -0
- /lionagi/core/flow/{base/baseflow.py → baseflow.py} +0 -0
- /lionagi/core/flow/{base/__init__.py → mono_chat_mixin.py} +0 -0
- /lionagi/core/{prompt → form}/__init__.py +0 -0
- /lionagi/{tests/test_integrations → core/graph}/__init__.py +0 -0
- /lionagi/tests/{test_libs → integrations}/__init__.py +0 -0
- /lionagi/tests/{test_libs/test_async.py → libs/__init__.py} +0 -0
- /lionagi/tests/{test_libs → libs}/test_api.py +0 -0
- /lionagi/tests/{test_libs → libs}/test_convert.py +0 -0
- /lionagi/tests/{test_libs → libs}/test_func_call.py +0 -0
- /lionagi/tests/{test_libs → libs}/test_nested.py +0 -0
- /lionagi/tests/{test_libs → libs}/test_parse.py +0 -0
- /lionagi/tests/{test_libs → libs}/test_sys_util.py +0 -0
- {lionagi-0.0.316.dist-info → lionagi-0.1.0.dist-info}/LICENSE +0 -0
- {lionagi-0.0.316.dist-info → lionagi-0.1.0.dist-info}/WHEEL +0 -0
- {lionagi-0.0.316.dist-info → lionagi-0.1.0.dist-info}/top_level.txt +0 -0
lionagi/core/session/session.py
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
from collections import deque
|
2
2
|
from typing import Tuple
|
3
3
|
|
4
|
-
from
|
4
|
+
from pathlib import Path
|
5
5
|
from lionagi.libs import BaseService, convert, dataframe
|
6
6
|
|
7
|
-
from lionagi.core.
|
8
|
-
from lionagi.core.tool import ToolManager
|
9
|
-
from lionagi.core.mail import MailManager
|
10
|
-
from lionagi.core.messages import System, Instruction
|
11
|
-
from lionagi.core.branch import Branch
|
7
|
+
from lionagi.core.generic import DataLogger
|
8
|
+
from lionagi.core.tool import ToolManager, Tool, TOOL_TYPE
|
9
|
+
from lionagi.core.mail.mail_manager import MailManager
|
10
|
+
from lionagi.core.messages.schema import System, Instruction
|
11
|
+
from lionagi.core.branch.branch import Branch
|
12
12
|
from lionagi.core.flow.polyflow import PolyChat
|
13
13
|
|
14
14
|
|
@@ -41,7 +41,7 @@ class Session:
|
|
41
41
|
tool_manager: ToolManager | None = None,
|
42
42
|
messages: dataframe.ln_DataFrame | None = None,
|
43
43
|
datalogger: None | DataLogger = None,
|
44
|
-
persist_path:
|
44
|
+
persist_path: Path | str | None = None,
|
45
45
|
):
|
46
46
|
"""Initialize a new session with optional configuration for managing conversations.
|
47
47
|
|
@@ -226,7 +226,7 @@ class Session:
|
|
226
226
|
@classmethod
|
227
227
|
def from_csv(
|
228
228
|
cls,
|
229
|
-
filepath:
|
229
|
+
filepath: Path | str,
|
230
230
|
system: dict | list | System | None = None,
|
231
231
|
sender: str | None = None,
|
232
232
|
llmconfig: dict[str, str | int | dict] | None = None,
|
@@ -272,7 +272,7 @@ class Session:
|
|
272
272
|
@classmethod
|
273
273
|
def from_json(
|
274
274
|
cls,
|
275
|
-
filepath:
|
275
|
+
filepath: Path | str,
|
276
276
|
system: dict | list | System | None = None,
|
277
277
|
sender: str | None = None,
|
278
278
|
llmconfig: dict[str, str | int | dict] | None = None,
|
@@ -852,8 +852,8 @@ class Session:
|
|
852
852
|
|
853
853
|
def take_branch(self, branch):
|
854
854
|
self.branches[branch.branch_name] = branch
|
855
|
-
self.mail_manager.sources[branch.
|
856
|
-
self.mail_manager.mails[branch.
|
855
|
+
self.mail_manager.sources[branch.id_] = branch
|
856
|
+
self.mail_manager.mails[branch.id_] = {}
|
857
857
|
|
858
858
|
def collect(self, from_: str | Branch | list[str | Branch] | None = None):
|
859
859
|
"""
|
@@ -872,16 +872,17 @@ class Session:
|
|
872
872
|
>>> session.collect() # Collects from all branches
|
873
873
|
"""
|
874
874
|
if from_ is None:
|
875
|
-
for branch in self.branches.
|
876
|
-
self.mail_manager.collect(branch)
|
875
|
+
for branch in self.branches.values():
|
876
|
+
self.mail_manager.collect(branch.id_)
|
877
877
|
else:
|
878
878
|
if not isinstance(from_, list):
|
879
|
-
from_ =
|
879
|
+
from_ = [from_]
|
880
880
|
for branch in from_:
|
881
|
-
if isinstance(branch, Branch):
|
882
|
-
branch = branch.name
|
883
881
|
if isinstance(branch, str):
|
884
|
-
self.
|
882
|
+
branch = self.branches[branch]
|
883
|
+
self.mail_manager.collect(branch.id_)
|
884
|
+
elif isinstance(branch, Branch):
|
885
|
+
self.mail_manager.collect(branch.id_)
|
885
886
|
|
886
887
|
def send(self, to_: str | Branch | list[str | Branch] | None = None):
|
887
888
|
"""
|
@@ -900,16 +901,17 @@ class Session:
|
|
900
901
|
>>> session.send() # Sends to all branches
|
901
902
|
"""
|
902
903
|
if to_ is None:
|
903
|
-
for branch in self.branches.
|
904
|
-
self.mail_manager.send(branch)
|
904
|
+
for branch in self.branches.values():
|
905
|
+
self.mail_manager.send(branch.id_)
|
905
906
|
else:
|
906
907
|
if not isinstance(to_, list):
|
907
908
|
to_ = [to_]
|
908
909
|
for branch in to_:
|
909
|
-
if isinstance(branch, Branch):
|
910
|
-
branch = branch.name
|
911
910
|
if isinstance(branch, str):
|
912
|
-
self.
|
911
|
+
branch = self.branches[branch]
|
912
|
+
self.mail_manager.send(branch.id_)
|
913
|
+
if isinstance(branch, Branch):
|
914
|
+
self.mail_manager.send(branch.id_)
|
913
915
|
|
914
916
|
def collect_send_all(self, receive_all=False):
|
915
917
|
"""
|
@@ -980,4 +982,4 @@ class Session:
|
|
980
982
|
if system:
|
981
983
|
self.default_branch.add_message(system=system, sender=sender)
|
982
984
|
|
983
|
-
self.llmconfig = self.default_branch.llmconfig
|
985
|
+
self.llmconfig = self.default_branch.llmconfig
|
lionagi/core/tool/__init__.py
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from pydantic import field_serializer
|
4
|
+
from lionagi.core.generic import Node
|
5
|
+
|
6
|
+
|
7
|
+
class Tool(Node):
|
8
|
+
"""
|
9
|
+
Represents a tool, extending BaseNode with specific functionalities and configurations.
|
10
|
+
|
11
|
+
Attributes:
|
12
|
+
func: The main function or capability of the tool.
|
13
|
+
schema_: An optional schema defining the structure and constraints of data the tool works with.
|
14
|
+
manual: Optional documentation or manual for using the tool.
|
15
|
+
parser: An optional parser associated with the tool for data processing or interpretation.
|
16
|
+
"""
|
17
|
+
|
18
|
+
func: Any
|
19
|
+
schema_: dict | None = None
|
20
|
+
manual: Any | None = None
|
21
|
+
parser: Any | None = None
|
22
|
+
|
23
|
+
@field_serializer("func")
|
24
|
+
def serialize_func(self, func):
|
25
|
+
return func.__name__
|
26
|
+
|
27
|
+
|
28
|
+
TOOL_TYPE = bool | Tool | str | list[Tool | str | dict] | dict
|
@@ -1,9 +1,9 @@
|
|
1
|
-
from typing import Tuple, Any, TypeVar, Callable
|
2
|
-
|
3
1
|
import asyncio
|
4
2
|
|
3
|
+
from typing import Tuple, Any, TypeVar, Callable
|
5
4
|
from lionagi.libs import func_call, convert, ParseUtil
|
6
|
-
|
5
|
+
|
6
|
+
from lionagi.core.tool.tool import Tool, TOOL_TYPE
|
7
7
|
|
8
8
|
T = TypeVar("T", bound=Tool)
|
9
9
|
|
@@ -17,7 +17,7 @@ class ToolManager:
|
|
17
17
|
calls.
|
18
18
|
|
19
19
|
Attributes:
|
20
|
-
|
20
|
+
registry (dict[str, Tool]): A dictionary to hold registered tools, keyed by their names.
|
21
21
|
"""
|
22
22
|
|
23
23
|
registry: dict = {}
|
@@ -27,10 +27,10 @@ class ToolManager:
|
|
27
27
|
Checks if a tool name already exists in the registry.
|
28
28
|
|
29
29
|
Args:
|
30
|
-
|
30
|
+
name (str): The name of the tool to check.
|
31
31
|
|
32
32
|
Returns:
|
33
|
-
|
33
|
+
bool: True if the name exists, False otherwise.
|
34
34
|
"""
|
35
35
|
return name in self.registry
|
36
36
|
|
@@ -43,10 +43,10 @@ class ToolManager:
|
|
43
43
|
Registers a tool in the registry. Raises a TypeError if the object is not an instance of Tool.
|
44
44
|
|
45
45
|
Args:
|
46
|
-
|
46
|
+
tool (Tool): The tool instance to register.
|
47
47
|
|
48
48
|
Raises:
|
49
|
-
|
49
|
+
TypeError: If the provided object is not an instance of Tool.
|
50
50
|
"""
|
51
51
|
if isinstance(tool, Callable):
|
52
52
|
tool = func_to_tool(tool)[0]
|
@@ -60,13 +60,13 @@ class ToolManager:
|
|
60
60
|
Invokes a registered tool's function with the given arguments. Supports both coroutine and regular functions.
|
61
61
|
|
62
62
|
Args:
|
63
|
-
|
63
|
+
func_call (Tuple[str, Dict[str, Any]]): A tuple containing the function name and a dictionary of keyword arguments.
|
64
64
|
|
65
65
|
Returns:
|
66
|
-
|
66
|
+
Any: The result of the function call.
|
67
67
|
|
68
68
|
Raises:
|
69
|
-
|
69
|
+
ValueError: If the function name is not registered or if there's an error during function invocation.
|
70
70
|
"""
|
71
71
|
name, kwargs = func_calls
|
72
72
|
if not self.name_existed(name):
|
@@ -93,13 +93,13 @@ class ToolManager:
|
|
93
93
|
Extracts a function call and arguments from a response dictionary.
|
94
94
|
|
95
95
|
Args:
|
96
|
-
|
96
|
+
response (dict): The response dictionary containing the function call information.
|
97
97
|
|
98
98
|
Returns:
|
99
|
-
|
99
|
+
Tuple[str, dict]: A tuple containing the function name and a dictionary of arguments.
|
100
100
|
|
101
101
|
Raises:
|
102
|
-
|
102
|
+
ValueError: If the response does not contain valid function call information.
|
103
103
|
"""
|
104
104
|
try:
|
105
105
|
func = response["action"][7:]
|
@@ -118,7 +118,7 @@ class ToolManager:
|
|
118
118
|
Registers multiple tools in the registry.
|
119
119
|
|
120
120
|
Args:
|
121
|
-
|
121
|
+
tools (list[Tool]): A list of tool instances to register.
|
122
122
|
"""
|
123
123
|
func_call.lcall(tools, self._register_tool)
|
124
124
|
|
@@ -127,7 +127,7 @@ class ToolManager:
|
|
127
127
|
Generates a list of schemas for all registered tools.
|
128
128
|
|
129
129
|
Returns:
|
130
|
-
|
130
|
+
list[dict[str, Any]]: A list of tool schemas.
|
131
131
|
|
132
132
|
"""
|
133
133
|
return [tool.schema_ for tool in self.registry.values()]
|
@@ -137,14 +137,14 @@ class ToolManager:
|
|
137
137
|
Parses tool information and generates a dictionary for tool invocation.
|
138
138
|
|
139
139
|
Args:
|
140
|
-
|
141
|
-
|
140
|
+
tools: Tool information which can be a single Tool instance, a list of Tool instances, a tool name, or a list of tool names.
|
141
|
+
**kwargs: Additional keyword arguments.
|
142
142
|
|
143
143
|
Returns:
|
144
|
-
|
144
|
+
dict: A dictionary containing tool schema information and any additional keyword arguments.
|
145
145
|
|
146
146
|
Raises:
|
147
|
-
|
147
|
+
ValueError: If a tool name is provided that is not registered.
|
148
148
|
"""
|
149
149
|
|
150
150
|
def tool_check(tool):
|
@@ -154,7 +154,7 @@ class ToolManager:
|
|
154
154
|
return tool.schema_
|
155
155
|
elif isinstance(tool, str):
|
156
156
|
if self.name_existed(tool):
|
157
|
-
tool = self.registry[tool]
|
157
|
+
tool: Tool = self.registry[tool]
|
158
158
|
return tool.schema_
|
159
159
|
else:
|
160
160
|
raise ValueError(f"Function {tool} is not registered.")
|
@@ -190,66 +190,66 @@ def func_to_tool(
|
|
190
190
|
objects with structured metadata.
|
191
191
|
|
192
192
|
Args:
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
193
|
+
func_ (Callable): The function to be transformed into a Tool object. This
|
194
|
+
function should have a docstring that follows the
|
195
|
+
specified docstring style for accurate schema generation.
|
196
|
+
parser (Optional[Any]): An optional parser object associated with the Tool.
|
197
|
+
This parameter is currently not utilized in the
|
198
|
+
transformation process but is included for future
|
199
|
+
compatibility and extension purposes.
|
200
|
+
docstring_style (str): The format of the docstring to be parsed, indicating
|
201
|
+
the convention used in the function's docstring.
|
202
|
+
Supports 'google' for Google-style docstrings and
|
203
|
+
'reST' for reStructuredText-style docstrings. The
|
204
|
+
chosen style affects how the docstring is parsed and
|
205
|
+
how the schema is generated.
|
206
206
|
|
207
207
|
Returns:
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
208
|
+
Tool: An object representing the original function wrapped as a Tool, along
|
209
|
+
with its generated schema. This Tool object can be used in systems that
|
210
|
+
require detailed metadata about functions, facilitating tasks such as
|
211
|
+
automatic documentation generation, user interface creation, or
|
212
|
+
integration with other software tools.
|
213
213
|
|
214
214
|
Examples:
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
215
|
+
>>> def example_function_google(param1: int, param2: str) -> bool:
|
216
|
+
... '''
|
217
|
+
... An example function using Google style docstrings.
|
218
|
+
...
|
219
|
+
... Args:
|
220
|
+
... param1 (int): The first parameter, demonstrating an integer input_.
|
221
|
+
... param2 (str): The second parameter, demonstrating a string input_.
|
222
|
+
...
|
223
|
+
... Returns:
|
224
|
+
... bool: A boolean value, illustrating the return type.
|
225
|
+
... '''
|
226
|
+
... return True
|
227
|
+
...
|
228
|
+
>>> tool_google = func_to_tool(example_function_google, docstring_style='google')
|
229
|
+
>>> print(isinstance(tool_google, Tool))
|
230
|
+
True
|
231
|
+
|
232
|
+
>>> def example_function_reST(param1: int, param2: str) -> bool:
|
233
|
+
... '''
|
234
|
+
... An example function using reStructuredText (reST) style docstrings.
|
235
|
+
...
|
236
|
+
... :param param1: The first parameter, demonstrating an integer input_.
|
237
|
+
... :type param1: int
|
238
|
+
... :param param2: The second parameter, demonstrating a string input_.
|
239
|
+
... :type param2: str
|
240
|
+
... :returns: A boolean value, illustrating the return type.
|
241
|
+
... :rtype: bool
|
242
|
+
... '''
|
243
|
+
... return True
|
244
|
+
...
|
245
|
+
>>> tool_reST = func_to_tool(example_function_reST, docstring_style='reST')
|
246
|
+
>>> print(isinstance(tool_reST, Tool))
|
247
|
+
True
|
248
248
|
|
249
249
|
Note:
|
250
|
-
|
251
|
-
|
252
|
-
|
250
|
+
The transformation process relies heavily on the accuracy and completeness of
|
251
|
+
the function's docstring. Functions with incomplete or incorrectly formatted
|
252
|
+
docstrings may result in incomplete or inaccurate Tool schemas.
|
253
253
|
"""
|
254
254
|
|
255
255
|
fs = []
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from typing import Union, Callable
|
2
2
|
|
3
3
|
from lionagi.libs import func_call
|
4
|
-
from lionagi.core.
|
4
|
+
from lionagi.core.generic import Node
|
5
5
|
from ..bridge.langchain_.langchain_bridge import LangchainBridge
|
6
6
|
from ..bridge.llamaindex_.llama_index_bridge import LlamaIndexBridge
|
7
7
|
|
@@ -12,7 +12,7 @@ from ..loader.load_util import ChunkerType, file_to_chunks, _datanode_parser
|
|
12
12
|
def datanodes_convert(documents, chunker_type):
|
13
13
|
|
14
14
|
for i in range(len(documents)):
|
15
|
-
if type(documents[i]) ==
|
15
|
+
if type(documents[i]) == Node:
|
16
16
|
if chunker_type == ChunkerType.LLAMAINDEX:
|
17
17
|
documents[i] = documents[i].to_llama_index()
|
18
18
|
elif chunker_type == ChunkerType.LANGCHAIN:
|
@@ -25,7 +25,7 @@ def text_chunker(documents, args, kwargs):
|
|
25
25
|
def chunk_node(node):
|
26
26
|
chunks = file_to_chunks(node.to_dict(), *args, **kwargs)
|
27
27
|
func_call.lcall(chunks, lambda chunk: chunk.pop("node_id"))
|
28
|
-
return [
|
28
|
+
return [Node.from_obj({**chunk}) for chunk in chunks]
|
29
29
|
|
30
30
|
return [chunk_node(doc) for doc in documents]
|
31
31
|
|
@@ -106,7 +106,7 @@ def _self_defined_chunker(
|
|
106
106
|
) from e
|
107
107
|
|
108
108
|
if isinstance(to_datanode, bool) and to_datanode is True:
|
109
|
-
raise ValueError("Please define a valid parser to
|
109
|
+
raise ValueError("Please define a valid parser to Node.")
|
110
110
|
elif isinstance(to_datanode, Callable):
|
111
111
|
nodes = _datanode_parser(nodes, to_datanode)
|
112
112
|
return nodes
|
@@ -127,7 +127,7 @@ def _llama_index_chunker(
|
|
127
127
|
)
|
128
128
|
|
129
129
|
if isinstance(to_datanode, bool) and to_datanode is True:
|
130
|
-
nodes = [
|
130
|
+
nodes = [Node.from_llama_index(i) for i in nodes]
|
131
131
|
elif isinstance(to_datanode, Callable):
|
132
132
|
nodes = _datanode_parser(nodes, to_datanode)
|
133
133
|
return nodes
|
@@ -148,9 +148,9 @@ def _langchain_chunker(
|
|
148
148
|
)
|
149
149
|
if isinstance(to_datanode, bool) and to_datanode is True:
|
150
150
|
if isinstance(documents, str):
|
151
|
-
nodes = [
|
151
|
+
nodes = [Node(content=i) for i in nodes]
|
152
152
|
else:
|
153
|
-
nodes = [
|
153
|
+
nodes = [Node.from_langchain(i) for i in nodes]
|
154
154
|
elif isinstance(to_datanode, Callable):
|
155
155
|
nodes = _datanode_parser(nodes, to_datanode)
|
156
156
|
return nodes
|
@@ -79,7 +79,7 @@ oai_audio_speech_schema = {
|
|
79
79
|
oai_audio_transcriptions_llmconfig = {
|
80
80
|
"model": "whisper-1",
|
81
81
|
"language": None,
|
82
|
-
"
|
82
|
+
"format_prompt": None,
|
83
83
|
"response_format": "json",
|
84
84
|
"temperature": 0,
|
85
85
|
}
|
@@ -88,7 +88,7 @@ oai_audio_transcriptions_schema = {
|
|
88
88
|
"optional": [
|
89
89
|
"response_format",
|
90
90
|
"language",
|
91
|
-
"
|
91
|
+
"format_prompt",
|
92
92
|
"response_format",
|
93
93
|
"temperature",
|
94
94
|
],
|
@@ -99,14 +99,14 @@ oai_audio_transcriptions_schema = {
|
|
99
99
|
# Audio ------------ translations
|
100
100
|
oai_audio_translations_llmconfig = {
|
101
101
|
"model": "whisper-1",
|
102
|
-
"
|
102
|
+
"format_prompt": None,
|
103
103
|
"response_format": "json",
|
104
104
|
"temperature": 0,
|
105
105
|
}
|
106
106
|
|
107
107
|
oai_audio_translations_schema = {
|
108
108
|
"required": ["model"],
|
109
|
-
"optional": ["response_format", "speed", "
|
109
|
+
"optional": ["response_format", "speed", "format_prompt", "temperature"],
|
110
110
|
"input_": "file",
|
111
111
|
"config": oai_audio_translations_llmconfig,
|
112
112
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from typing import Callable
|
2
2
|
|
3
|
-
from lionagi.core.
|
3
|
+
from lionagi.core.generic import Node
|
4
4
|
from ..bridge.langchain_.langchain_bridge import LangchainBridge
|
5
5
|
from ..bridge.llamaindex_.llama_index_bridge import LlamaIndexBridge
|
6
6
|
|
@@ -9,14 +9,14 @@ from .load_util import dir_to_nodes, ReaderType, _datanode_parser
|
|
9
9
|
|
10
10
|
def text_reader(args, kwargs):
|
11
11
|
"""
|
12
|
-
Reads text files from a directory and converts them to
|
12
|
+
Reads text files from a directory and converts them to Node instances.
|
13
13
|
|
14
14
|
Args:
|
15
15
|
args: Positional arguments for the dir_to_nodes function.
|
16
16
|
kwargs: Keyword arguments for the dir_to_nodes function.
|
17
17
|
|
18
18
|
Returns:
|
19
|
-
A list of
|
19
|
+
A list of Node instances.
|
20
20
|
|
21
21
|
Example usage:
|
22
22
|
>>> args = ['path/to/text/files']
|
@@ -96,7 +96,7 @@ def _plain_reader(reader, reader_args, reader_kwargs):
|
|
96
96
|
def _langchain_reader(reader, reader_args, reader_kwargs, to_datanode: bool | Callable):
|
97
97
|
nodes = LangchainBridge.langchain_loader(reader, reader_args, reader_kwargs)
|
98
98
|
if isinstance(to_datanode, bool) and to_datanode is True:
|
99
|
-
nodes = [
|
99
|
+
nodes = [Node.from_langchain(i) for i in nodes]
|
100
100
|
|
101
101
|
elif isinstance(to_datanode, Callable):
|
102
102
|
nodes = _datanode_parser(nodes, to_datanode)
|
@@ -115,7 +115,7 @@ def _llama_index_reader(
|
|
115
115
|
reader, reader_args, reader_kwargs, load_args, load_kwargs
|
116
116
|
)
|
117
117
|
if isinstance(to_datanode, bool) and to_datanode is True:
|
118
|
-
nodes = [
|
118
|
+
nodes = [Node.from_llama_index(i) for i in nodes]
|
119
119
|
elif isinstance(to_datanode, Callable):
|
120
120
|
nodes = _datanode_parser(nodes, to_datanode)
|
121
121
|
return nodes
|
@@ -138,7 +138,7 @@ def _self_defined_reader(
|
|
138
138
|
) from e
|
139
139
|
|
140
140
|
if isinstance(to_datanode, bool) and to_datanode is True:
|
141
|
-
raise ValueError("Please define a valid parser to
|
141
|
+
raise ValueError("Please define a valid parser to Node.")
|
142
142
|
elif isinstance(to_datanode, Callable):
|
143
143
|
nodes = _datanode_parser(nodes, to_datanode)
|
144
144
|
return nodes
|
@@ -5,7 +5,7 @@ from pathlib import Path
|
|
5
5
|
from typing import List, Union, Dict, Any, Tuple
|
6
6
|
|
7
7
|
from lionagi.libs import convert, func_call
|
8
|
-
from lionagi.core.
|
8
|
+
from lionagi.core.generic import Node
|
9
9
|
|
10
10
|
|
11
11
|
class ReaderType(str, Enum):
|
@@ -62,11 +62,11 @@ def dir_to_nodes(
|
|
62
62
|
recursive: bool = False,
|
63
63
|
flatten: bool = True,
|
64
64
|
clean_text: bool = True,
|
65
|
-
) -> List[
|
65
|
+
) -> List[Node]:
|
66
66
|
"""
|
67
|
-
Converts directory contents into
|
67
|
+
Converts directory contents into Node objects based on specified file extensions.
|
68
68
|
|
69
|
-
This function first retrieves a list of file paths from the specified directory, matching the given file extension. It then reads the content of these files, optionally cleaning the text, and converts each file's content into a
|
69
|
+
This function first retrieves a list of file paths from the specified directory, matching the given file extension. It then reads the content of these files, optionally cleaning the text, and converts each file's content into a Node object.
|
70
70
|
|
71
71
|
Parameters:
|
72
72
|
dir (str): The directory path from which to read files.
|
@@ -76,17 +76,17 @@ def dir_to_nodes(
|
|
76
76
|
clean_text (bool, optional): If True, cleans the text read from files. Defaults to True.
|
77
77
|
|
78
78
|
Returns:
|
79
|
-
list: A list of
|
79
|
+
list: A list of Node objects created from the files in the specified directory.
|
80
80
|
|
81
81
|
Example:
|
82
82
|
nodes = dir_to_nodes("/path/to/dir", ".txt", recursive=True)
|
83
83
|
# This would read all .txt files in /path/to/dir and its subdirectories,
|
84
|
-
# converting them into
|
84
|
+
# converting them into Node objects.
|
85
85
|
"""
|
86
86
|
|
87
87
|
path_list = dir_to_path(dir, ext, recursive, flatten)
|
88
88
|
files_info = func_call.lcall(path_list, read_text, clean=clean_text)
|
89
|
-
return func_call.lcall(files_info, lambda x:
|
89
|
+
return func_call.lcall(files_info, lambda x: Node(content=x[0], metadata=x[1]))
|
90
90
|
|
91
91
|
|
92
92
|
def chunk_text(
|
@@ -263,4 +263,4 @@ def _datanode_parser(nodes, parser):
|
|
263
263
|
try:
|
264
264
|
return parser(nodes)
|
265
265
|
except Exception as e:
|
266
|
-
raise ValueError(f"
|
266
|
+
raise ValueError(f"Node parser {parser} failed. Error:{e}") from e
|
lionagi/libs/ln_api.py
CHANGED
@@ -377,8 +377,8 @@ class APIUtil:
|
|
377
377
|
num_tokens += 2 # every reply is primed with <im_start>assistant
|
378
378
|
return num_tokens + completion_tokens
|
379
379
|
else:
|
380
|
-
prompt = payload["
|
381
|
-
if isinstance(prompt, str): # single
|
380
|
+
prompt = payload["format_prompt"]
|
381
|
+
if isinstance(prompt, str): # single format_prompt
|
382
382
|
prompt_tokens = len(encoding.encode(prompt))
|
383
383
|
return prompt_tokens + completion_tokens
|
384
384
|
elif isinstance(prompt, list): # multiple prompts
|
@@ -386,7 +386,7 @@ class APIUtil:
|
|
386
386
|
return prompt_tokens + completion_tokens * len(prompt)
|
387
387
|
else:
|
388
388
|
raise TypeError(
|
389
|
-
'Expecting either string or list of strings for "
|
389
|
+
'Expecting either string or list of strings for "format_prompt" field in completion request'
|
390
390
|
)
|
391
391
|
elif api_endpoint == "embeddings":
|
392
392
|
input = payload["input"]
|