lionagi 0.1.0__py3-none-any.whl → 0.1.1__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/core/agent/base_agent.py +2 -3
- lionagi/core/branch/base.py +1 -1
- lionagi/core/branch/branch.py +2 -1
- lionagi/core/branch/flow_mixin.py +1 -1
- lionagi/core/branch/util.py +1 -1
- lionagi/core/execute/base_executor.py +1 -4
- lionagi/core/execute/branch_executor.py +66 -3
- lionagi/core/execute/instruction_map_executor.py +48 -0
- lionagi/core/execute/neo4j_executor.py +381 -0
- lionagi/core/execute/structure_executor.py +99 -3
- lionagi/core/flow/monoflow/ReAct.py +18 -18
- lionagi/core/flow/monoflow/chat_mixin.py +1 -1
- lionagi/core/flow/monoflow/followup.py +11 -12
- lionagi/core/flow/polyflow/__init__.py +1 -1
- lionagi/core/generic/component.py +0 -2
- lionagi/core/generic/condition.py +1 -1
- lionagi/core/generic/edge.py +52 -0
- lionagi/core/mail/mail_manager.py +3 -2
- lionagi/core/session/session.py +1 -1
- lionagi/experimental/__init__.py +0 -0
- lionagi/experimental/directive/__init__.py +0 -0
- lionagi/experimental/directive/evaluator/__init__.py +0 -0
- lionagi/experimental/directive/evaluator/ast_evaluator.py +115 -0
- lionagi/experimental/directive/evaluator/base_evaluator.py +202 -0
- lionagi/experimental/directive/evaluator/sandbox_.py +14 -0
- lionagi/experimental/directive/evaluator/script_engine.py +83 -0
- lionagi/experimental/directive/parser/__init__.py +0 -0
- lionagi/experimental/directive/parser/base_parser.py +215 -0
- lionagi/experimental/directive/schema.py +36 -0
- lionagi/experimental/directive/template_/__init__.py +0 -0
- lionagi/experimental/directive/template_/base_template.py +63 -0
- lionagi/experimental/tool/__init__.py +0 -0
- lionagi/experimental/tool/function_calling.py +43 -0
- lionagi/experimental/tool/manual.py +66 -0
- lionagi/experimental/tool/schema.py +59 -0
- lionagi/experimental/tool/tool_manager.py +138 -0
- lionagi/experimental/tool/util.py +16 -0
- lionagi/experimental/work/__init__.py +0 -0
- lionagi/experimental/work/_logger.py +25 -0
- lionagi/experimental/work/exchange.py +0 -0
- lionagi/experimental/work/schema.py +30 -0
- lionagi/experimental/work/tests.py +72 -0
- lionagi/experimental/work/util.py +0 -0
- lionagi/experimental/work/work_function.py +89 -0
- lionagi/experimental/work/worker.py +12 -0
- lionagi/integrations/bridge/autogen_/__init__.py +0 -0
- lionagi/integrations/bridge/autogen_/autogen_.py +124 -0
- lionagi/integrations/bridge/llamaindex_/get_index.py +294 -0
- lionagi/integrations/bridge/llamaindex_/llama_pack.py +227 -0
- lionagi/integrations/bridge/transformers_/__init__.py +0 -0
- lionagi/integrations/bridge/transformers_/install_.py +36 -0
- lionagi/integrations/config/oai_configs.py +1 -1
- lionagi/integrations/config/ollama_configs.py +1 -1
- lionagi/integrations/config/openrouter_configs.py +1 -1
- lionagi/integrations/storage/__init__.py +3 -0
- lionagi/integrations/storage/neo4j.py +673 -0
- lionagi/integrations/storage/storage_util.py +289 -0
- lionagi/integrations/storage/to_csv.py +63 -0
- lionagi/integrations/storage/to_excel.py +67 -0
- lionagi/libs/ln_knowledge_graph.py +405 -0
- lionagi/libs/ln_queue.py +101 -0
- lionagi/libs/ln_tokenizer.py +57 -0
- lionagi/libs/sys_util.py +1 -1
- lionagi/lions/__init__.py +0 -0
- lionagi/lions/coder/__init__.py +0 -0
- lionagi/lions/coder/add_feature.py +20 -0
- lionagi/lions/coder/base_prompts.py +22 -0
- lionagi/lions/coder/coder.py +121 -0
- lionagi/lions/coder/util.py +91 -0
- lionagi/lions/researcher/__init__.py +0 -0
- lionagi/lions/researcher/data_source/__init__.py +0 -0
- lionagi/lions/researcher/data_source/finhub_.py +191 -0
- lionagi/lions/researcher/data_source/google_.py +199 -0
- lionagi/lions/researcher/data_source/wiki_.py +96 -0
- lionagi/lions/researcher/data_source/yfinance_.py +21 -0
- lionagi/tests/libs/test_queue.py +67 -0
- lionagi/tests/test_core/test_branch.py +0 -1
- lionagi/version.py +1 -1
- {lionagi-0.1.0.dist-info → lionagi-0.1.1.dist-info}/METADATA +1 -1
- {lionagi-0.1.0.dist-info → lionagi-0.1.1.dist-info}/RECORD +83 -29
- {lionagi-0.1.0.dist-info → lionagi-0.1.1.dist-info}/LICENSE +0 -0
- {lionagi-0.1.0.dist-info → lionagi-0.1.1.dist-info}/WHEEL +0 -0
- {lionagi-0.1.0.dist-info → lionagi-0.1.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
import asyncio
|
2
|
+
from lionagi.core import Session
|
3
|
+
|
4
|
+
from .base_prompts import CODER_PROMPTS
|
5
|
+
from .util import extract_code_blocks, install_missing_dependencies, set_up_interpreter
|
6
|
+
|
7
|
+
|
8
|
+
class Coder:
|
9
|
+
def __init__(
|
10
|
+
self, prompts=None, session=None, session_kwargs=None, required_libraries=None
|
11
|
+
):
|
12
|
+
print("Initializing Coder...")
|
13
|
+
self.prompts = prompts or CODER_PROMPTS
|
14
|
+
self.session = session or self._create_session(session_kwargs)
|
15
|
+
self.required_libraries = required_libraries or ["lionagi"]
|
16
|
+
print("Coder initialized.")
|
17
|
+
|
18
|
+
def _create_session(self, session_kwargs=None):
|
19
|
+
print("Creating session...")
|
20
|
+
session_kwargs = session_kwargs or {}
|
21
|
+
session = Session(system=self.prompts["system"], **session_kwargs)
|
22
|
+
print("Session created.")
|
23
|
+
return session
|
24
|
+
|
25
|
+
async def _plan_code(self, context):
|
26
|
+
print("Planning code...")
|
27
|
+
plans = await self.session.chat(self.prompts["plan_code"], context=context)
|
28
|
+
print("Code planning completed.")
|
29
|
+
return plans
|
30
|
+
|
31
|
+
async def _write_code(self, context=None):
|
32
|
+
print("Writing code...")
|
33
|
+
code = await self.session.chat(self.prompts["write_code"], context=context)
|
34
|
+
print("Code writing completed.")
|
35
|
+
return extract_code_blocks(code)
|
36
|
+
|
37
|
+
async def _review_code(self, context=None):
|
38
|
+
print("Reviewing code...")
|
39
|
+
code = await self.session.chat(self.prompts["review_code"], context=context)
|
40
|
+
print("Code review completed.")
|
41
|
+
return code
|
42
|
+
|
43
|
+
async def _modify_code(self, context=None):
|
44
|
+
print("Modifying code...")
|
45
|
+
code = await self.session.chat(self.prompts["modify_code"], context=context)
|
46
|
+
print("Code modification completed.")
|
47
|
+
return code
|
48
|
+
|
49
|
+
async def _debug_code(self, context=None):
|
50
|
+
print("Debugging code...")
|
51
|
+
code = await self.session.chat(self.prompts["debug_code"], context=context)
|
52
|
+
print("Code debugging completed.")
|
53
|
+
return code
|
54
|
+
|
55
|
+
def _handle_execution_error(self, execution, required_libraries=None):
|
56
|
+
print("Handling execution error...")
|
57
|
+
if execution.error and execution.error.name == "ModuleNotFoundError":
|
58
|
+
print("ModuleNotFoundError detected. Installing missing dependencies...")
|
59
|
+
install_missing_dependencies(required_libraries)
|
60
|
+
print("Dependencies installed. Retrying execution.")
|
61
|
+
return "try again"
|
62
|
+
elif execution.error:
|
63
|
+
print(f"Execution error: {execution.error}")
|
64
|
+
return execution.error
|
65
|
+
|
66
|
+
def execute_code(self, code, **kwargs):
|
67
|
+
print("Executing code...")
|
68
|
+
interpreter = set_up_interpreter()
|
69
|
+
with interpreter as sandbox:
|
70
|
+
print("Running code in sandbox...")
|
71
|
+
execution = sandbox.notebook.exec_cell(code, **kwargs)
|
72
|
+
error = self._handle_execution_error(
|
73
|
+
execution, required_libraries=kwargs.get("required_libraries")
|
74
|
+
)
|
75
|
+
if error == "try again":
|
76
|
+
print("Retrying code execution...")
|
77
|
+
execution = sandbox.notebook.exec_cell(code, **kwargs)
|
78
|
+
print("Code execution completed.")
|
79
|
+
return execution
|
80
|
+
|
81
|
+
|
82
|
+
async def main():
|
83
|
+
print("Starting main function...")
|
84
|
+
coder = Coder()
|
85
|
+
|
86
|
+
code_prompt = """
|
87
|
+
write a pure python function that takes a list of integers and returns the sum of all the integers in the list. write a couple tests as well
|
88
|
+
"""
|
89
|
+
|
90
|
+
print(f"Code prompt: {code_prompt}")
|
91
|
+
|
92
|
+
print("Planning code...")
|
93
|
+
code_plan = await coder._plan_code(context=code_prompt)
|
94
|
+
print("Code plan generated.")
|
95
|
+
|
96
|
+
print("Writing code...")
|
97
|
+
code = await coder._write_code()
|
98
|
+
print("Code written.")
|
99
|
+
|
100
|
+
print("Executing code...")
|
101
|
+
execution_result = coder.execute_code(code)
|
102
|
+
print("Code execution completed.")
|
103
|
+
|
104
|
+
from IPython.display import Markdown
|
105
|
+
|
106
|
+
print("Displaying code plan...")
|
107
|
+
Markdown(code_plan)
|
108
|
+
|
109
|
+
print("Displaying generated code...")
|
110
|
+
print(code)
|
111
|
+
|
112
|
+
print("Displaying execution result...")
|
113
|
+
print(execution_result)
|
114
|
+
|
115
|
+
print("Main function completed.")
|
116
|
+
|
117
|
+
|
118
|
+
if __name__ == "__main__":
|
119
|
+
print("Running script...")
|
120
|
+
asyncio.run(main())
|
121
|
+
print("Script execution completed.")
|
@@ -0,0 +1,91 @@
|
|
1
|
+
E2B_key_scheme = "E2B_API_KEY"
|
2
|
+
|
3
|
+
|
4
|
+
def set_up_interpreter(interpreter_provider="e2b", key_scheme=E2B_key_scheme):
|
5
|
+
|
6
|
+
if interpreter_provider == "e2b":
|
7
|
+
from dotenv import load_dotenv
|
8
|
+
|
9
|
+
load_dotenv()
|
10
|
+
|
11
|
+
from lionagi.libs import SysUtil
|
12
|
+
|
13
|
+
SysUtil.check_import("e2b_code_interpreter")
|
14
|
+
|
15
|
+
from e2b_code_interpreter import CodeInterpreter # type: ignore
|
16
|
+
from os import getenv
|
17
|
+
|
18
|
+
return CodeInterpreter(api_key=getenv(key_scheme))
|
19
|
+
|
20
|
+
else:
|
21
|
+
raise ValueError("Invalid interpreter provider")
|
22
|
+
|
23
|
+
|
24
|
+
def extract_code_blocks(code):
|
25
|
+
print("Extracting code blocks...")
|
26
|
+
code_blocks = []
|
27
|
+
lines = code.split("\n")
|
28
|
+
inside_code_block = False
|
29
|
+
current_block = []
|
30
|
+
|
31
|
+
for line in lines:
|
32
|
+
if line.startswith("```"):
|
33
|
+
if inside_code_block:
|
34
|
+
code_blocks.append("\n".join(current_block))
|
35
|
+
current_block = []
|
36
|
+
inside_code_block = False
|
37
|
+
else:
|
38
|
+
inside_code_block = True
|
39
|
+
elif inside_code_block:
|
40
|
+
current_block.append(line)
|
41
|
+
|
42
|
+
if current_block:
|
43
|
+
code_blocks.append("\n".join(current_block))
|
44
|
+
|
45
|
+
print(f"Extracted {len(code_blocks)} code block(s).")
|
46
|
+
return "\n\n".join(code_blocks)
|
47
|
+
|
48
|
+
|
49
|
+
def install_missing_dependencies(required_libraries):
|
50
|
+
print("Checking for missing dependencies...")
|
51
|
+
missing_libraries = [
|
52
|
+
library for library in required_libraries if not is_library_installed(library)
|
53
|
+
]
|
54
|
+
|
55
|
+
if missing_libraries:
|
56
|
+
print(f"Missing libraries: {', '.join(missing_libraries)}")
|
57
|
+
for library in missing_libraries:
|
58
|
+
print(f"Installing {library}...")
|
59
|
+
install_library(library)
|
60
|
+
print("Installation completed.")
|
61
|
+
else:
|
62
|
+
print("All required dependencies are already installed.")
|
63
|
+
|
64
|
+
|
65
|
+
def is_library_installed(library):
|
66
|
+
try:
|
67
|
+
import importlib
|
68
|
+
|
69
|
+
importlib.import_module(library)
|
70
|
+
print(f"{library} is already installed.")
|
71
|
+
return True
|
72
|
+
except ImportError:
|
73
|
+
print(f"{library} is not installed.")
|
74
|
+
return False
|
75
|
+
|
76
|
+
|
77
|
+
def install_library(library):
|
78
|
+
try:
|
79
|
+
import subprocess
|
80
|
+
import sys
|
81
|
+
|
82
|
+
subprocess.check_call([sys.executable, "-m", "pip", "install", library])
|
83
|
+
print(f"Successfully installed {library}.")
|
84
|
+
except subprocess.CalledProcessError as e:
|
85
|
+
print(f"Error occurred while installing {library}: {str(e)}")
|
86
|
+
print(
|
87
|
+
"Please check the error message and ensure you have the necessary permissions to install packages."
|
88
|
+
)
|
89
|
+
print(
|
90
|
+
"You may need to run the script with administrative privileges or use a virtual environment."
|
91
|
+
)
|
File without changes
|
File without changes
|
@@ -0,0 +1,191 @@
|
|
1
|
+
import os
|
2
|
+
from lionagi.libs import convert
|
3
|
+
|
4
|
+
finnhub_key_scheme = "FINNHUB_API_KEY"
|
5
|
+
|
6
|
+
|
7
|
+
class FinnHub:
|
8
|
+
"""
|
9
|
+
A utility class for interacting with the FinnHub API to retrieve financial and market data.
|
10
|
+
|
11
|
+
Attributes:
|
12
|
+
api_key (str): The API key used for authenticating with the FinnHub API.
|
13
|
+
|
14
|
+
Methods:
|
15
|
+
get_client(api_key=None):
|
16
|
+
Returns a FinnHub API client instance for making API calls.
|
17
|
+
|
18
|
+
get_info_df(info_kind="company_news", api_key=None, **kwargs):
|
19
|
+
Retrieves data from the FinnHub API based on the specified 'info_kind' and returns it as a Pandas DataFrame.
|
20
|
+
"""
|
21
|
+
|
22
|
+
api_key = os.getenv(finnhub_key_scheme)
|
23
|
+
|
24
|
+
@classmethod
|
25
|
+
def get_client(cls, api_key=None):
|
26
|
+
"""
|
27
|
+
Creates and returns a FinnHub API client instance.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
api_key (str): The API key used for authenticating with the FinnHub API. If not provided,
|
31
|
+
the class-level API key (if set) will be used.
|
32
|
+
|
33
|
+
Returns:
|
34
|
+
finnhub.Client: A FinnHub API client instance.
|
35
|
+
|
36
|
+
Raises:
|
37
|
+
ImportError: If there is an error while importing the 'finnhub' library.
|
38
|
+
"""
|
39
|
+
try:
|
40
|
+
from lionagi.libs import SysUtil
|
41
|
+
|
42
|
+
SysUtil.check_import("finnhub")
|
43
|
+
|
44
|
+
import finnhub
|
45
|
+
|
46
|
+
return finnhub.Client(api_key=api_key or cls.api_key)
|
47
|
+
except Exception as e:
|
48
|
+
raise ImportError(f"Error occured during importing finnhub: {e}")
|
49
|
+
|
50
|
+
@classmethod
|
51
|
+
def get_info_df(cls, info_kind="company_news", api_key=None, **kwargs):
|
52
|
+
"""
|
53
|
+
Retrieves data from the FinnHub API based on the specified 'info_kind' and returns it as a Pandas DataFrame.
|
54
|
+
|
55
|
+
Args:
|
56
|
+
info_kind (str): The type of information to retrieve from FinnHub. Default is "company_news".
|
57
|
+
api_key (str): The API key used for authenticating with the FinnHub API. If not provided,
|
58
|
+
the class-level API key (if set) will be used.
|
59
|
+
**kwargs: Additional keyword arguments to customize the API query.
|
60
|
+
|
61
|
+
Returns:
|
62
|
+
pandas.DataFrame: A Pandas DataFrame containing the retrieved data.
|
63
|
+
|
64
|
+
Raises:
|
65
|
+
ValueError: If there is an error during the API call or while converting the data to a DataFrame.
|
66
|
+
"""
|
67
|
+
client = cls.get_client(api_key)
|
68
|
+
info_func = cls.get_finnhub_method(client, info_kind)
|
69
|
+
try:
|
70
|
+
results = info_func(**kwargs)
|
71
|
+
try:
|
72
|
+
df = convert.to_df(results)
|
73
|
+
return df
|
74
|
+
except Exception as e:
|
75
|
+
raise ValueError(
|
76
|
+
f"Error occured during converting {info_kind} to DataFrame: {e}"
|
77
|
+
)
|
78
|
+
except Exception as e:
|
79
|
+
raise ValueError(
|
80
|
+
f"Error occured during getting {info_kind} from FinnHub: {e}"
|
81
|
+
)
|
82
|
+
|
83
|
+
@staticmethod
|
84
|
+
def get_finnhub_method(client, info_kind):
|
85
|
+
"""
|
86
|
+
Returns the appropriate FinnHub API method based on the specified 'info_kind'.
|
87
|
+
|
88
|
+
Args:
|
89
|
+
client (finnhub.Client): The FinnHub API client instance.
|
90
|
+
info_kind (str): The type of information to retrieve from FinnHub.
|
91
|
+
|
92
|
+
Returns:
|
93
|
+
Callable or None: The corresponding FinnHub API method, or None if 'info_kind' is not recognized.
|
94
|
+
"""
|
95
|
+
info_func = {
|
96
|
+
"aggregate_indicator": client.aggregate_indicator,
|
97
|
+
"company_basic_financials": client.company_basic_financials,
|
98
|
+
"company_earnings": client.company_earnings,
|
99
|
+
"company_eps_estimates": client.company_eps_estimates,
|
100
|
+
"company_executive": client.company_executive,
|
101
|
+
"company_news": client.company_news,
|
102
|
+
"company_peers": client.company_peers,
|
103
|
+
"company_profile": client.company_profile,
|
104
|
+
"company_profile2": client.company_profile2,
|
105
|
+
"company_revenue_estimates": client.company_revenue_estimates,
|
106
|
+
"country": client.country,
|
107
|
+
"crypto_exchanges": client.crypto_exchanges,
|
108
|
+
"crypto_symbols": client.crypto_symbols,
|
109
|
+
"economic_data": client.economic_data,
|
110
|
+
"filings": client.filings,
|
111
|
+
"financials": client.financials,
|
112
|
+
"financials_reported": client.financials_reported,
|
113
|
+
"forex_exchanges": client.forex_exchanges,
|
114
|
+
"forex_rates": client.forex_rates,
|
115
|
+
"forex_symbols": client.forex_symbols,
|
116
|
+
"fund_ownership": client.fund_ownership,
|
117
|
+
"general_news": client.general_news,
|
118
|
+
"ownership": client.ownership,
|
119
|
+
"ipo_calendar": client.ipo_calendar,
|
120
|
+
"press_releases": client.press_releases,
|
121
|
+
"news_sentiment": client.news_sentiment,
|
122
|
+
"pattern_recognition": client.pattern_recognition,
|
123
|
+
"price_target": client.price_target,
|
124
|
+
"quote": client.quote,
|
125
|
+
"recommendation_trends": client.recommendation_trends,
|
126
|
+
"stock_dividends": client.stock_dividends,
|
127
|
+
"stock_basic_dividends": client.stock_basic_dividends,
|
128
|
+
"stock_symbols": client.stock_symbols,
|
129
|
+
"transcripts": client.transcripts,
|
130
|
+
"transcripts_list": client.transcripts_list,
|
131
|
+
"earnings_calendar": client.earnings_calendar,
|
132
|
+
"covid19": client.covid19,
|
133
|
+
"upgrade_downgrade": client.upgrade_downgrade,
|
134
|
+
"economic_code": client.economic_code,
|
135
|
+
"calendar_economic": client.calendar_economic,
|
136
|
+
"support_resistance": client.support_resistance,
|
137
|
+
"technical_indicator": client.technical_indicator,
|
138
|
+
"stock_splits": client.stock_splits,
|
139
|
+
"forex_candles": client.forex_candles,
|
140
|
+
"crypto_candles": client.crypto_candles,
|
141
|
+
"stock_tick": client.stock_tick,
|
142
|
+
"stock_nbbo": client.stock_nbbo,
|
143
|
+
"indices_const": client.indices_const,
|
144
|
+
"indices_hist_const": client.indices_hist_const,
|
145
|
+
"etfs_profile": client.etfs_profile,
|
146
|
+
"etfs_holdings": client.etfs_holdings,
|
147
|
+
"etfs_sector_exp": client.etfs_sector_exp,
|
148
|
+
"etfs_country_exp": client.etfs_country_exp,
|
149
|
+
"international_filings": client.international_filings,
|
150
|
+
"sec_sentiment_analysis": client.sec_sentiment_analysis,
|
151
|
+
"sec_similarity_index": client.sec_similarity_index,
|
152
|
+
"last_bid_ask": client.last_bid_ask,
|
153
|
+
"fda_calendar": client.fda_calendar,
|
154
|
+
"symbol_lookup": client.symbol_lookup,
|
155
|
+
"stock_insider_transactions": client.stock_insider_transactions,
|
156
|
+
"mutual_fund_profile": client.mutual_fund_profile,
|
157
|
+
"mutual_fund_holdings": client.mutual_fund_holdings,
|
158
|
+
"mutual_fund_sector_exp": client.mutual_fund_sector_exp,
|
159
|
+
"mutual_fund_country_exp": client.mutual_fund_country_exp,
|
160
|
+
"stock_revenue_breakdown": client.stock_revenue_breakdown,
|
161
|
+
"stock_social_sentiment": client.stock_social_sentiment,
|
162
|
+
"stock_investment_theme": client.stock_investment_theme,
|
163
|
+
"stock_supply_chain": client.stock_supply_chain,
|
164
|
+
"company_esg_score": client.company_esg_score,
|
165
|
+
"company_earnings_quality_score": client.company_earnings_quality_score,
|
166
|
+
"crypto_profile": client.crypto_profile,
|
167
|
+
"company_ebitda_estimates": client.company_ebitda_estimates,
|
168
|
+
"company_ebit_estimates": client.company_ebit_estimates,
|
169
|
+
"stock_uspto_patent": client.stock_uspto_patent,
|
170
|
+
"stock_visa_application": client.stock_visa_application,
|
171
|
+
"stock_insider_sentiment": client.stock_insider_sentiment,
|
172
|
+
"bond_profile": client.bond_profile,
|
173
|
+
"bond_price": client.bond_price,
|
174
|
+
"stock_lobbying": client.stock_lobbying,
|
175
|
+
"stock_usa_spending": client.stock_usa_spending,
|
176
|
+
"sector_metric": client.sector_metric,
|
177
|
+
"mutual_fund_eet": client.mutual_fund_eet,
|
178
|
+
"mutual_fund_eet_pai": client.mutual_fund_eet_pai,
|
179
|
+
"isin_change": client.isin_change,
|
180
|
+
"symbol_change": client.symbol_change,
|
181
|
+
"institutional_profile": client.institutional_profile,
|
182
|
+
"institutional_portfolio": client.institutional_portfolio,
|
183
|
+
"institutional_ownership": client.institutional_ownership,
|
184
|
+
"bond_yield_curve": client.bond_yield_curve,
|
185
|
+
"bond_tick": client.bond_tick,
|
186
|
+
"congressional_trading": client.congressional_trading,
|
187
|
+
"price_metrics": client.price_metrics,
|
188
|
+
"market_holiday": client.market_holiday,
|
189
|
+
"market_status": client.market_status,
|
190
|
+
}
|
191
|
+
return info_func.get(info_kind, None)
|
@@ -0,0 +1,199 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
google_key_scheme = "GOOGLE_API_KEY"
|
4
|
+
google_engine_scheme = "GOOGLE_CSE_ID"
|
5
|
+
|
6
|
+
google_api_key = os.getenv(google_key_scheme)
|
7
|
+
google_engine = os.getenv(google_engine_scheme)
|
8
|
+
|
9
|
+
|
10
|
+
class GoogleSearch:
|
11
|
+
"""
|
12
|
+
A utility class for performing Google searches and retrieving search results.
|
13
|
+
|
14
|
+
Attributes:
|
15
|
+
api_key (str): The Google API key used for search (can be set via environment variable).
|
16
|
+
search_engine (str): The Google Custom Search Engine ID (can be set via environment variable).
|
17
|
+
|
18
|
+
Methods:
|
19
|
+
create_agent_engine(api_key=None, search_engine=None, verbose=False):
|
20
|
+
Create an OpenAIAgent for Google search operations.
|
21
|
+
|
22
|
+
url_get_content(url: str):
|
23
|
+
Retrieve and parse the content from a given URL.
|
24
|
+
|
25
|
+
search(title: str = None, url: str = None):
|
26
|
+
Perform a Google search for a given title or URL and retrieve relevant content.
|
27
|
+
"""
|
28
|
+
|
29
|
+
api_key = google_api_key
|
30
|
+
search_engine = google_engine
|
31
|
+
search_url = """
|
32
|
+
https://www.googleapis.com/customsearch/v1?key={key}&cx={engine}&q={query}&start={start}
|
33
|
+
"""
|
34
|
+
|
35
|
+
@classmethod
|
36
|
+
def create_agent(cls, api_key=None, search_engine=None, verbose=False):
|
37
|
+
"""
|
38
|
+
Create an OpenAIAgent for Google search operations.
|
39
|
+
|
40
|
+
Args:
|
41
|
+
api_key (str, optional): The Google API key for search. Defaults to None (uses class attribute).
|
42
|
+
search_engine (str, optional): The Google Custom Search Engine ID. Defaults to None (uses class attribute).
|
43
|
+
verbose (bool, optional): Whether to enable verbose mode for the agent. Defaults to False.
|
44
|
+
|
45
|
+
Returns:
|
46
|
+
OpenAIAgent: An instance of the OpenAIAgent for performing Google searches.
|
47
|
+
|
48
|
+
Raises:
|
49
|
+
ImportError: If there is an issue during the agent creation.
|
50
|
+
"""
|
51
|
+
try:
|
52
|
+
from lionagi.libs import SysUtil
|
53
|
+
|
54
|
+
SysUtil.check_import(package_name="llama_index", pip_name="llama-index")
|
55
|
+
|
56
|
+
SysUtil.check_import(
|
57
|
+
package_name="llama_index",
|
58
|
+
module_name="agent.openai",
|
59
|
+
import_name="OpenAIAgent",
|
60
|
+
pip_name="llama-index-agent-openai",
|
61
|
+
)
|
62
|
+
|
63
|
+
SysUtil.check_import(
|
64
|
+
package_name="llama_index",
|
65
|
+
module_name="tools.google",
|
66
|
+
import_name="GoogleSearchToolSpec",
|
67
|
+
pip_name="llama-index-tools-google",
|
68
|
+
)
|
69
|
+
|
70
|
+
from llama_index.agent import OpenAIAgent
|
71
|
+
from llama_index.tools.tool_spec.load_and_search.base import (
|
72
|
+
LoadAndSearchToolSpec,
|
73
|
+
)
|
74
|
+
from llama_index.tools.google import GoogleSearchToolSpec
|
75
|
+
from llama_index.llms.openai import OpenAI
|
76
|
+
|
77
|
+
llm = OpenAI(model="gpt-4-turbo", temperature=0.1)
|
78
|
+
|
79
|
+
api_key = api_key if api_key else cls.api_key
|
80
|
+
search_engine = search_engine if search_engine else cls.search_engine
|
81
|
+
google_spec = GoogleSearchToolSpec(key=api_key, engine=search_engine)
|
82
|
+
|
83
|
+
# Wrap the google search tool as it returns large payloads
|
84
|
+
tools = LoadAndSearchToolSpec.from_defaults(
|
85
|
+
google_spec.to_tool_list()[0],
|
86
|
+
).to_tool_list()
|
87
|
+
|
88
|
+
# Create the Agent with our tools
|
89
|
+
agent = OpenAIAgent.from_tools(tools, verbose=verbose, llm=llm)
|
90
|
+
return agent
|
91
|
+
|
92
|
+
except Exception as e:
|
93
|
+
raise ImportError(f"Error in importing OpenAIAgent from llama_index: {e}")
|
94
|
+
|
95
|
+
|
96
|
+
# responses_google = []
|
97
|
+
# async def query_google(query: str):
|
98
|
+
# """
|
99
|
+
# Search Google and retrieve a natural language answer to a given query.
|
100
|
+
|
101
|
+
# Args:
|
102
|
+
# query (str): The search query to find an answer for.
|
103
|
+
|
104
|
+
# Returns:
|
105
|
+
# str: A natural language answer obtained from Google search results.
|
106
|
+
|
107
|
+
# Raises:
|
108
|
+
# Exception: If there is an issue with making the request or parsing the response.
|
109
|
+
# """
|
110
|
+
# google_agent = GoogleSearch.create_agent()
|
111
|
+
# response = await google_agent.achat(query)
|
112
|
+
# responses_google.append(response)
|
113
|
+
# return str(response.response)
|
114
|
+
|
115
|
+
|
116
|
+
# @staticmethod
|
117
|
+
# def search(title: str = None, url: str = None):
|
118
|
+
# """
|
119
|
+
# Perform a Google search for a given title or URL and retrieve relevant content.
|
120
|
+
|
121
|
+
# Args:
|
122
|
+
# title (str, optional): The title or query for the Google search. Defaults to None.
|
123
|
+
# url (str, optional): The URL to retrieve content from. Defaults to None.
|
124
|
+
|
125
|
+
# Returns:
|
126
|
+
# str: The retrieved information from the Google search or URL, or an error message if no results are found.
|
127
|
+
|
128
|
+
# Raises:
|
129
|
+
# ValueError: If there is an issue during the search or content retrieval.
|
130
|
+
# """
|
131
|
+
# if not title and not url:
|
132
|
+
# raise 'No search input.'
|
133
|
+
# from ..utils.url_util import get_url_content
|
134
|
+
|
135
|
+
# if url:
|
136
|
+
# return get_url_content(url)
|
137
|
+
# else:
|
138
|
+
# from googlesearch import search
|
139
|
+
# search_result = search(title)
|
140
|
+
|
141
|
+
# for url in search_result:
|
142
|
+
# try:
|
143
|
+
# return get_url_content(url)
|
144
|
+
|
145
|
+
# except:
|
146
|
+
# continue
|
147
|
+
# return 'No matched or valid source'
|
148
|
+
|
149
|
+
|
150
|
+
# get fields of a google search item
|
151
|
+
# @classmethod
|
152
|
+
# def _get_search_item_field(cls, item: Dict[str, Any]) -> Dict[str, str]:
|
153
|
+
# try:
|
154
|
+
# long_description = item["pagemap"]["metatags"][0]["og:description"]
|
155
|
+
# except KeyError:
|
156
|
+
# long_description = "N/A"
|
157
|
+
# url = item.get("link")
|
158
|
+
#
|
159
|
+
# return {
|
160
|
+
# "title": item.get("title"),
|
161
|
+
# "snippet": item.get("snippet"),
|
162
|
+
# "url": item.get("link"),
|
163
|
+
# "long_description": long_description,
|
164
|
+
# "content": get_url_content(url)
|
165
|
+
# }
|
166
|
+
#
|
167
|
+
# @classmethod
|
168
|
+
# def _format_search_url(cls, url, api_key, search_engine, query, start):
|
169
|
+
# url = url or cls.search_url
|
170
|
+
# url = url.format(
|
171
|
+
# key=api_key or cls.api_key,
|
172
|
+
# engine=search_engine or cls.search_engine,
|
173
|
+
# query=query,
|
174
|
+
# start=start
|
175
|
+
# )
|
176
|
+
# return url
|
177
|
+
#
|
178
|
+
# @classmethod
|
179
|
+
# def search(
|
180
|
+
# cls,
|
181
|
+
# query: str =None,
|
182
|
+
# search_url = None,
|
183
|
+
# api_key = None,
|
184
|
+
# search_engine=None,
|
185
|
+
# start: int = 1,
|
186
|
+
# timeout: tuple = (0.5, 0.5),
|
187
|
+
# content=True,
|
188
|
+
# num=5
|
189
|
+
# ):
|
190
|
+
# url = cls._format_search_url(
|
191
|
+
# url = search_url, query=query, api_key=api_key,
|
192
|
+
# search_engine=search_engine, start=start
|
193
|
+
# )
|
194
|
+
# response = get_url_response(url, timeout=timeout)
|
195
|
+
# response_dict = response.json()
|
196
|
+
# items = response_dict.get('items')[:num]
|
197
|
+
# if content:
|
198
|
+
# items = lcall(items, cls._get_search_item_field, dropna=True)
|
199
|
+
# return items
|