diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3ac015a8..9d62e252 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,7 +2,7 @@ name: lint on: push: - branches: [main] + branches: [master] pull_request: env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dbe86fb3..e3cb4943 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,7 +2,7 @@ name: test on: push: - branches: [main] + branches: [master] pull_request: env: diff --git a/langchain/__init__.py b/langchain/__init__.py index 7b8d028a..8d8179b7 100644 --- a/langchain/__init__.py +++ b/langchain/__init__.py @@ -3,8 +3,8 @@ from langchain.agents import MRKLChain, ReActChain, SelfAskWithSearchChain from langchain.chains import ( ConversationChain, - LLMChain, LLMBashChain, + LLMChain, LLMMathChain, PALChain, QAWithSourcesChain, diff --git a/langchain/chains/llm_bash/base.py b/langchain/chains/llm_bash/base.py index 6828d119..85ea58ce 100644 --- a/langchain/chains/llm_bash/base.py +++ b/langchain/chains/llm_bash/base.py @@ -1,3 +1,4 @@ +"""Chain that interprets a prompt and executes bash code to perform bash operations.""" from typing import Dict, List from pydantic import BaseModel, Extra @@ -5,9 +6,9 @@ from pydantic import BaseModel, Extra from langchain.chains.base import Chain from langchain.chains.llm import LLMChain from langchain.chains.llm_bash.prompt import PROMPT -from langchain.utilities.bash import BashProcess from langchain.input import print_text from langchain.llms.base import LLM +from langchain.utilities.bash import BashProcess class LLMBashChain(Chain, BaseModel): @@ -47,7 +48,7 @@ class LLMBashChain(Chain, BaseModel): """ return [self.output_key] - def _call(self, inputs: Dict[str, str]) -> Dict[str, Dict[str, list[str]]]: + def _call(self, inputs: Dict[str, str]) -> Dict[str, str]: llm_executor = LLMChain(prompt=PROMPT, llm=self.llm) bash_executor = BashProcess() if self.verbose: @@ -60,7 +61,7 @@ class LLMBashChain(Chain, BaseModel): t = t.strip() if t.startswith("```bash"): # Split the string into a list of substrings - command_list = t.split('\n') + command_list = t.split("\n") print(command_list) # Remove the first and last substrings @@ -73,5 +74,4 @@ class LLMBashChain(Chain, BaseModel): else: raise ValueError(f"unknown format from LLM: {t}") - answer = {"commands": command_list, "output": output} - return {self.output_key: answer} + return {self.output_key: output} diff --git a/langchain/utilities/__init__.py b/langchain/utilities/__init__.py index e19d8854..da09cd68 100644 --- a/langchain/utilities/__init__.py +++ b/langchain/utilities/__init__.py @@ -1,6 +1,6 @@ +"""General utilities.""" from langchain.utilities.bash import BashProcess - __all__ = [ - 'BashProcess', + "BashProcess", ] diff --git a/langchain/utilities/bash.py b/langchain/utilities/bash.py index dd12f41d..afc0e34f 100644 --- a/langchain/utilities/bash.py +++ b/langchain/utilities/bash.py @@ -1,14 +1,17 @@ +"""Wrapper around subprocess to run commands.""" import subprocess -from typing import Dict, List, Union +from typing import List + class BashProcess: """Executes bash commands and returns the output.""" def __init__(self, strip_newlines: bool = False): + """Initialize with stripping newlines.""" self.strip_newlines = strip_newlines - - def run(self, commands: List[str]) -> Dict[str, Union[bool, list[str]]]: + def run(self, commands: List[str]) -> str: + """Run commands and return final output.""" outputs = [] for command in commands: try: @@ -17,7 +20,5 @@ class BashProcess: output = output.strip() outputs.append(output) except subprocess.CalledProcessError as error: - outputs.append(str(error)) - return {"success": False, "outputs": outputs} - - return {"success": True, "outputs": outputs} + return str(error) + return outputs[-1] diff --git a/tests/unit_tests/chains/test_llm_bash.py b/tests/unit_tests/chains/test_llm_bash.py index 64123b10..3c2d9ae7 100644 --- a/tests/unit_tests/chains/test_llm_bash.py +++ b/tests/unit_tests/chains/test_llm_bash.py @@ -10,9 +10,9 @@ from tests.unit_tests.llms.fake_llm import FakeLLM @pytest.fixture def fake_llm_bash_chain() -> LLMBashChain: """Fake LLM Bash chain for testing.""" - queries = { - _PROMPT_TEMPLATE.format(question="Please write a bash script that prints 'Hello World' to the console."): "```bash\nexpr 1 + 1\n```", - } + question = "Please write a bash script that prints 'Hello World' to the console." + prompt = _PROMPT_TEMPLATE.format(question=question) + queries = {prompt: "```bash\nexpr 1 + 1\n```"} fake_llm = FakeLLM(queries=queries) return LLMBashChain(llm=fake_llm, input_key="q", output_key="a") @@ -21,4 +21,4 @@ def test_simple_question(fake_llm_bash_chain: LLMBashChain) -> None: """Test simple question that should not need python.""" question = "Please write a bash script that prints 'Hello World' to the console." output = fake_llm_bash_chain.run(question) - assert output == {'commands': ['expr 1 + 1'], 'output': {'outputs': ['2\n'], 'success': True}} + assert output == "2\n" diff --git a/tests/unit_tests/chains/test_bash.py b/tests/unit_tests/test_bash.py similarity index 74% rename from tests/unit_tests/chains/test_bash.py rename to tests/unit_tests/test_bash.py index e7420240..5c4dd785 100644 --- a/tests/unit_tests/chains/test_bash.py +++ b/tests/unit_tests/test_bash.py @@ -1,22 +1,25 @@ +"""Test the bash utility.""" import subprocess from pathlib import Path from langchain.utilities.bash import BashProcess + def test_pwd_command() -> None: """Test correct functionality.""" session = BashProcess() commands = ["pwd"] output = session.run(commands) - print(output) - assert output["outputs"] == [subprocess.check_output("pwd", shell=True).decode()] + assert output == subprocess.check_output("pwd", shell=True).decode() + def test_incorrect_command() -> None: """Test handling of incorrect command.""" session = BashProcess() output = session.run(["invalid_command"]) - assert output["success"] is False + assert output == "Command 'invalid_command' returned non-zero exit status 127." + def test_create_directory_and_files(tmp_path: Path) -> None: """Test creation of a directory and files in a temporary directory.""" @@ -31,14 +34,12 @@ def test_create_directory_and_files(tmp_path: Path) -> None: f"touch {temp_dir}/file1.txt", f"touch {temp_dir}/file2.txt", f"echo 'hello world' > {temp_dir}/file2.txt", - f"cat {temp_dir}/file2.txt" + f"cat {temp_dir}/file2.txt", ] output = session.run(commands) - assert output["success"] is True - assert output["outputs"][-1] == "hello world" + assert output == "hello world" # check that the files were created in the temporary directory output = session.run([f"ls {temp_dir}"]) - assert output["success"] is True - assert output["outputs"] == ["file1.txt\nfile2.txt"] + assert output == "file1.txt\nfile2.txt"