From 03818023ff6c62c544d06c39cfdf7fd9306cef7b Mon Sep 17 00:00:00 2001 From: Peixuan Xia Date: Fri, 11 Jul 2025 16:52:50 +0800 Subject: [PATCH 1/4] add litellmmodel example and finance tool --- examples/llm/README.md | 59 +++++++++++++++++++++ examples/llm/deepseek_tool_agent.py | 27 ++++++++++ isek/tools/finance_toolkit/get_base_info.py | 44 +++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 examples/llm/README.md create mode 100644 examples/llm/deepseek_tool_agent.py create mode 100644 isek/tools/finance_toolkit/get_base_info.py diff --git a/examples/llm/README.md b/examples/llm/README.md new file mode 100644 index 0000000..239d7af --- /dev/null +++ b/examples/llm/README.md @@ -0,0 +1,59 @@ +# 📈 Company Info Agent (Powered by LiteLLMModel and DeepSeek) + +This example demonstrates how to build a company information agent using the [ISEK](https://github.com/isekOS/ISEK) framework. The agent integrates the `deepseek` large language model via [`LiteLLMModel`](** https://github.com/isekOS/ISEK/tree/main/isek/models/litellm**)and can fetch stock codes and company information for companies. + +--- + +## 🚀 Features + +- Query company info by **company name** +- Retrieve **stock code** (e.g. `TSLA`) +- Fetch **basic stock info** and **company details** using tools +- Uses `DeepSeek-chat` LLM via [`LiteLLMModel`](** https://github.com/isekOS/ISEK/tree/main/isek/models/litellm**) +- Fully extensible with other models and tools via ISEK + +--- + +## 🧠 How It Works + +The agent uses the following components: + +- [`LiteLLMModel`](** https://github.com/isekOS/ISEK/tree/main/isek/models/litellm**): Wrapper for any OpenAI-compatible LLM (e.g., DeepSeek, GPT-4, Claude, etc.) +- [`base_info_tools`](https://github.com/isekOS/ISEK/tree/main/isek/tools/finance_toolkit): A collection of tools to retrieve stock codes, stock information, and company details. +- `IsekAgent`: Manages tool usage and reasoning based on instructions. + +--- + +## 🧩 Set Up Environment + +Before you try this example, don't forget to modify your .env file: + +```bash +DEEPSEEK_API_KEY=your_deepseek_apikay +DEEPSEEK_BASE_URL=https://api.deepseek.com/v1 +``` + +## 🔄 Other Example Configs + +You can easily switch to other models and providers using [`LiteLLMModel`](** https://github.com/isekOS/ISEK/tree/main/isek/models/litellm**). Here are some common configurations: + +#### ✅ DeepSeek via Ollama (local deployment) + +```python +LiteLLMModel( + provider="ollama", + model_id="deepseek-chat", + base_url="http://localhost:11434", + api_env_key=None # No API key needed for local use +) +``` + +#### ✅ Claude (Anthropic) + +```python +LiteLLMModel( + provider="anthropic", + model_id="claude-3-opus-20240229", + api_env_key="ANTHROPIC_API_KEY" +) +``` \ No newline at end of file diff --git a/examples/llm/deepseek_tool_agent.py b/examples/llm/deepseek_tool_agent.py new file mode 100644 index 0000000..305e9e2 --- /dev/null +++ b/examples/llm/deepseek_tool_agent.py @@ -0,0 +1,27 @@ +from isek.agent.isek_agent import IsekAgent +from isek.models.litellm import LiteLLMModel +from isek.models.base import SimpleMessage +from isek.tools.finance_toolkit.get_base_info import base_info_tools + + +import dotenv +dotenv.load_dotenv() + +agent = IsekAgent( + name="A-Share Company Info Agent", + model=LiteLLMModel(provider = "deepseek", model_id="deepseek/deepseek-chat"), + tools=[base_info_tools], + description="An assistant that finds stock info and company info given a company name", + instructions=["Be polite", + "Always first retrieve a numeric stock code (e.g. '600519') and a company 'About' or official website URL base on the company name.", + "Then use the appropriate tool with the stock code to retrieve basic stock information.", + "If a valid 'About' or official website URL is available, use the appropriate tool to fetch additional company details and return it.", + "Always return concise and structured information.", + "Only make tool calls when needed.", + "If a valid stock code or official company URL cannot be found, inform the user explicitly and avoid making unnecessary tool calls."], + success_criteria="User receives the correct stock info and basic company information for the given company name.", + debug_mode=True +) + +agent.print_response("hello") +agent.print_response("Give me the base info of Apple company, including its stock info and company info.") \ No newline at end of file diff --git a/isek/tools/finance_toolkit/get_base_info.py b/isek/tools/finance_toolkit/get_base_info.py new file mode 100644 index 0000000..f283db1 --- /dev/null +++ b/isek/tools/finance_toolkit/get_base_info.py @@ -0,0 +1,44 @@ +from isek.tools.toolkit import Toolkit +import efinance as ef + +import requests +from bs4 import BeautifulSoup + +def get_stock_info(stock_code: str ): + """get base info of stock base on stock code""" + + return ef.stock.get_base_info(stock_code) + + +def get_company_info(url: str): + """fetch additional company details base this url""" + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' + } + + try: + response = requests.get(url, headers=headers) + response.encoding = 'utf-8' + soup = BeautifulSoup(response.text, 'html.parser') + return soup.get_text(strip=True) + except: + return "" + + +# Create toolkit with debug enabled +base_info_tools = Toolkit( + name="stock_info_tool", + tools=[get_stock_info, get_company_info], + instructions="Fetch company information based on its stock code and the company's 'About' page or official website URL.", + debug=True, +) + + +# Optionally, for demonstration, call list_functions and execute_function in debug mode +if __name__ == "__main__": + base_info_tools.list_functions() + stock_info = base_info_tools.execute_function("get_stock_info", stock_code="00020") + company_info = base_info_tools.execute_function("get_company_info", url="https://www.sensetime.com/cn/about-index#1") + print("Stock Info:", stock_info) + print("Company Info:", company_info) + From db42e394b4ae40ef779be10dba1d25045f8f22f3 Mon Sep 17 00:00:00 2001 From: Peixuan Xia Date: Fri, 11 Jul 2025 17:03:04 +0800 Subject: [PATCH 2/4] add litellmmodel example and finance tool --- examples/llm/README.md | 2 +- examples/llm/deepseek_tool_agent.py | 4 ++-- .../{get_base_info.py => get_company_base_info.py} | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) rename isek/tools/finance_toolkit/{get_base_info.py => get_company_base_info.py} (79%) diff --git a/examples/llm/README.md b/examples/llm/README.md index 239d7af..7568403 100644 --- a/examples/llm/README.md +++ b/examples/llm/README.md @@ -19,7 +19,7 @@ This example demonstrates how to build a company information agent using the [IS The agent uses the following components: - [`LiteLLMModel`](** https://github.com/isekOS/ISEK/tree/main/isek/models/litellm**): Wrapper for any OpenAI-compatible LLM (e.g., DeepSeek, GPT-4, Claude, etc.) -- [`base_info_tools`](https://github.com/isekOS/ISEK/tree/main/isek/tools/finance_toolkit): A collection of tools to retrieve stock codes, stock information, and company details. +- [`base_info_tools`]: A collection of tools to retrieve stock codes, stock information, and company details. - `IsekAgent`: Manages tool usage and reasoning based on instructions. --- diff --git a/examples/llm/deepseek_tool_agent.py b/examples/llm/deepseek_tool_agent.py index 305e9e2..6c66d1e 100644 --- a/examples/llm/deepseek_tool_agent.py +++ b/examples/llm/deepseek_tool_agent.py @@ -1,7 +1,7 @@ from isek.agent.isek_agent import IsekAgent from isek.models.litellm import LiteLLMModel from isek.models.base import SimpleMessage -from isek.tools.finance_toolkit.get_base_info import base_info_tools +from isek.tools.finance_toolkit.get_company_base_info import company_base_info_tools import dotenv @@ -10,7 +10,7 @@ agent = IsekAgent( name="A-Share Company Info Agent", model=LiteLLMModel(provider = "deepseek", model_id="deepseek/deepseek-chat"), - tools=[base_info_tools], + tools=[company_base_info_tools], description="An assistant that finds stock info and company info given a company name", instructions=["Be polite", "Always first retrieve a numeric stock code (e.g. '600519') and a company 'About' or official website URL base on the company name.", diff --git a/isek/tools/finance_toolkit/get_base_info.py b/isek/tools/finance_toolkit/get_company_base_info.py similarity index 79% rename from isek/tools/finance_toolkit/get_base_info.py rename to isek/tools/finance_toolkit/get_company_base_info.py index f283db1..db84911 100644 --- a/isek/tools/finance_toolkit/get_base_info.py +++ b/isek/tools/finance_toolkit/get_company_base_info.py @@ -26,7 +26,7 @@ def get_company_info(url: str): # Create toolkit with debug enabled -base_info_tools = Toolkit( +company_base_info_tools = Toolkit( name="stock_info_tool", tools=[get_stock_info, get_company_info], instructions="Fetch company information based on its stock code and the company's 'About' page or official website URL.", @@ -36,9 +36,9 @@ def get_company_info(url: str): # Optionally, for demonstration, call list_functions and execute_function in debug mode if __name__ == "__main__": - base_info_tools.list_functions() - stock_info = base_info_tools.execute_function("get_stock_info", stock_code="00020") - company_info = base_info_tools.execute_function("get_company_info", url="https://www.sensetime.com/cn/about-index#1") + company_base_info_tools.list_functions() + stock_info = company_base_info_tools.execute_function("get_stock_info", stock_code="00020") + company_info = company_base_info_tools.execute_function("get_company_info", url="https://www.sensetime.com/cn/about-index#1") print("Stock Info:", stock_info) print("Company Info:", company_info) From 5b0fd8162aaaba38f2ea2ac148af951db2598aea Mon Sep 17 00:00:00 2001 From: Peixuan Xia Date: Fri, 11 Jul 2025 17:11:23 +0800 Subject: [PATCH 3/4] fix: replace bare except and apply ruff formatting --- isek/tools/finance_toolkit/get_company_base_info.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/isek/tools/finance_toolkit/get_company_base_info.py b/isek/tools/finance_toolkit/get_company_base_info.py index db84911..0360ce5 100644 --- a/isek/tools/finance_toolkit/get_company_base_info.py +++ b/isek/tools/finance_toolkit/get_company_base_info.py @@ -21,10 +21,11 @@ def get_company_info(url: str): response.encoding = 'utf-8' soup = BeautifulSoup(response.text, 'html.parser') return soup.get_text(strip=True) - except: + except Exception: return "" + # Create toolkit with debug enabled company_base_info_tools = Toolkit( name="stock_info_tool", From 09477086d34598778b9022c1ed1dfeb294e278f7 Mon Sep 17 00:00:00 2001 From: Peixuan Xia Date: Fri, 11 Jul 2025 17:27:59 +0800 Subject: [PATCH 4/4] style: apply ruff formatting --- .../finance_toolkit/get_company_base_info.py | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/isek/tools/finance_toolkit/get_company_base_info.py b/isek/tools/finance_toolkit/get_company_base_info.py index 0360ce5..29abc78 100644 --- a/isek/tools/finance_toolkit/get_company_base_info.py +++ b/isek/tools/finance_toolkit/get_company_base_info.py @@ -4,7 +4,8 @@ import requests from bs4 import BeautifulSoup -def get_stock_info(stock_code: str ): + +def get_stock_info(stock_code: str): """get base info of stock base on stock code""" return ef.stock.get_base_info(stock_code) @@ -13,19 +14,18 @@ def get_stock_info(stock_code: str ): def get_company_info(url: str): """fetch additional company details base this url""" headers = { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" } - + try: response = requests.get(url, headers=headers) - response.encoding = 'utf-8' - soup = BeautifulSoup(response.text, 'html.parser') + response.encoding = "utf-8" + soup = BeautifulSoup(response.text, "html.parser") return soup.get_text(strip=True) except Exception: return "" - # Create toolkit with debug enabled company_base_info_tools = Toolkit( name="stock_info_tool", @@ -38,8 +38,11 @@ def get_company_info(url: str): # Optionally, for demonstration, call list_functions and execute_function in debug mode if __name__ == "__main__": company_base_info_tools.list_functions() - stock_info = company_base_info_tools.execute_function("get_stock_info", stock_code="00020") - company_info = company_base_info_tools.execute_function("get_company_info", url="https://www.sensetime.com/cn/about-index#1") - print("Stock Info:", stock_info) + stock_info = company_base_info_tools.execute_function( + "get_stock_info", stock_code="00020" + ) + company_info = company_base_info_tools.execute_function( + "get_company_info", url="https://www.sensetime.com/cn/about-index#1" + ) + print("Stock Info:", stock_info) print("Company Info:", company_info) -