From 857f6b8a5d78f87fa53cf04e23c823240575ddf6 Mon Sep 17 00:00:00 2001 From: SystemSolution21 <156997764+SystemSolution21@users.noreply.github.com> Date: Mon, 1 Sep 2025 13:05:43 +0900 Subject: [PATCH 1/6] modified: langchain-crash-course/2_prompt_templates/prompt_template.py --- .../2_prompt_templates/prompt_template.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/langchain-crash-course/2_prompt_templates/prompt_template.py b/langchain-crash-course/2_prompt_templates/prompt_template.py index c643b6d..d617099 100644 --- a/langchain-crash-course/2_prompt_templates/prompt_template.py +++ b/langchain-crash-course/2_prompt_templates/prompt_template.py @@ -1,16 +1,15 @@ +from dotenv import load_dotenv from langchain_core.messages.base import BaseMessage -from langchain_core.prompts import PromptTemplate -from langchain_core.prompts import ChatPromptTemplate from langchain_core.prompt_values import PromptValue -from langchain_openai import ChatOpenAI +from langchain_core.prompts import ChatPromptTemplate, PromptTemplate from langchain_ollama import ChatOllama -from dotenv import load_dotenv +from langchain_openai import ChatOpenAI # Load Environment Variables load_dotenv() # Create OpenAI Chat Model -openai_model = ChatOpenAI(model="gpt-4o-mini") +openai_model = ChatOpenAI(model="gpt-4.1-nano") # 1. String Prompt Template prompt_template: PromptTemplate = PromptTemplate.from_template( From bcfe93a4a99585d746c89c6b8eb13c47332c6524 Mon Sep 17 00:00:00 2001 From: SystemSolution21 <156997764+SystemSolution21@users.noreply.github.com> Date: Mon, 1 Sep 2025 18:40:33 +0900 Subject: [PATCH 2/6] new file: langchain-crash-course/5_agents_tools/tests/test_agent_tools_basic.py --- .../tests/test_agent_tools_basic.py | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 langchain-crash-course/5_agents_tools/tests/test_agent_tools_basic.py diff --git a/langchain-crash-course/5_agents_tools/tests/test_agent_tools_basic.py b/langchain-crash-course/5_agents_tools/tests/test_agent_tools_basic.py new file mode 100644 index 0000000..2d2dd34 --- /dev/null +++ b/langchain-crash-course/5_agents_tools/tests/test_agent_tools_basic.py @@ -0,0 +1,90 @@ +import importlib +import os +import re +import sys +from pathlib import Path + +import pytest + + +# Helper to import the module with a clean environment +def import_module_with_env(env_vars): + """Import agent_tools_basic.py after setting env variables.""" + # Backup current env + backup_env = {k: os.getenv(k) for k in env_vars} + + # Add parent directory to sys.path to allow for module import + module_path = str(Path(__file__).parent.parent.resolve()) + sys.path.insert(0, module_path) + + try: + # Explicitly clear any existing LLM env vars + for var in ("OPENAI_API_KEY", "OPENAI_LLM", "OLLAMA_LLM"): + os.environ.pop(var, None) + + # Set the env vars supplied by the test + for k, v in env_vars.items(): + os.environ[k] = v + + # Invalidate any cached import + if "agent_tools_basic" in sys.modules: + del sys.modules["agent_tools_basic"] + module = importlib.import_module("agent_tools_basic") + return module + finally: + # Restore original env + for k, v in backup_env.items(): + if v is None: + os.environ.pop(k, None) + else: + os.environ[k] = v + # Clean up sys.path + if sys.path and sys.path[0] == module_path: + sys.path.pop(0) + + +@pytest.fixture +def agent_module(monkeypatch): + """Fixture that imports the module with dummy LLM configuration.""" + # Provide dummy values for OpenAI or Ollama + monkeypatch.setenv("OPENAI_API_KEY", "dummy_key") + monkeypatch.setenv("OPENAI_LLM", "dummy-model") + # Ensure no Ollama config interferes + monkeypatch.delenv("OLLAMA_LLM", raising=False) + return import_module_with_env( + {"OPENAI_API_KEY": "dummy_key", "OPENAI_LLM": "dummy-model"} + ) + + +def test_get_current_time_format(agent_module): + """get_current_time should return a string in YYYY-MM-DD HH:MM:SS format.""" + current_time = agent_module.get_current_time() + assert isinstance(current_time, str) + # Regex for the expected datetime format + pattern = r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$" + assert re.match(pattern, current_time), f"Unexpected format: {current_time}" + + +def test_tools_list_contains_current_time(agent_module): + """The tools list must contain a Tool named 'Current Time'.""" + tools = agent_module.tools + assert isinstance(tools, list) + # Find tool by name + names = [tool.name for tool in tools] + assert "Current Time" in names, f"Tool 'Current Time' not found in {names}" + + +def test_module_import_with_missing_llm(monkeypatch): + """Importing the module without any LLM configuration should raise ValueError.""" + # Remove all relevant env vars + monkeypatch.delenv("OPENAI_API_KEY", raising=False) + monkeypatch.delenv("OPENAI_LLM", raising=False) + monkeypatch.delenv("OLLAMA_LLM", raising=False) + + # Patch dotenv.load_dotenv to prevent loading from a .env file, + # which would interfere with this test. + monkeypatch.setattr("dotenv.load_dotenv", lambda *args, **kwargs: False) + + with pytest.raises(ValueError) as excinfo: + import_module_with_env({}) + assert "Neither OpenAI" in str(excinfo.value) From 8c7382453a5e90b890c6c18aa7d82b23282cd5a4 Mon Sep 17 00:00:00 2001 From: SystemSolution21 <156997764+SystemSolution21@users.noreply.github.com> Date: Mon, 1 Sep 2025 19:23:26 +0900 Subject: [PATCH 3/6] Added Pytest workflows --- .github/workflows/pytest.yaml | 26 ++++++++++++++++++++++++++ requirements.txt | 1 + 2 files changed, 27 insertions(+) create mode 100644 .github/workflows/pytest.yaml create mode 100644 requirements.txt diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml new file mode 100644 index 0000000..3497225 --- /dev/null +++ b/.github/workflows/pytest.yaml @@ -0,0 +1,26 @@ +name: Run Pytest + +on: + pull_request: + branches: + - main + +jobs: + pytest: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.11 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run pytest + run: pytest diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d852363 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pytest==8.3.5 \ No newline at end of file From 05838cd98edb0c194b73011d9f15ae7a6706782f Mon Sep 17 00:00:00 2001 From: SystemSolution21 <156997764+SystemSolution21@users.noreply.github.com> Date: Mon, 1 Sep 2025 19:45:41 +0900 Subject: [PATCH 4/6] modified requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d852363..38a0344 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -pytest==8.3.5 \ No newline at end of file +pytest==8.3.5 +langchain-community==0.3.15 \ No newline at end of file From d00ed370e58cf4ca6bb03b2b667b079e7f52da56 Mon Sep 17 00:00:00 2001 From: SystemSolution21 <156997764+SystemSolution21@users.noreply.github.com> Date: Mon, 1 Sep 2025 19:51:37 +0900 Subject: [PATCH 5/6] modified requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 38a0344..d2227ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ pytest==8.3.5 -langchain-community==0.3.15 \ No newline at end of file +langchain-community==0.3.15 +langchain-ollama==0.2.3 \ No newline at end of file From 33aca7276336f07aec60028d104c7ac09b6c9b9d Mon Sep 17 00:00:00 2001 From: SystemSolution21 <156997764+SystemSolution21@users.noreply.github.com> Date: Mon, 1 Sep 2025 19:55:23 +0900 Subject: [PATCH 6/6] modified requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d2227ff..56530e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ pytest==8.3.5 langchain-community==0.3.15 -langchain-ollama==0.2.3 \ No newline at end of file +langchain-ollama==0.2.3 +langchain-openai==0.3.1 \ No newline at end of file