mirror of
https://github.com/hwchase17/langchain.git
synced 2025-09-11 07:50:47 +00:00
Add a SQL agent for interacting with SQL Databases and JSON Agent for interacting with large JSON blobs (#1150)
This PR adds * `ZeroShotAgent.as_sql_agent`, which returns an agent for interacting with a sql database. This builds off of `SQLDatabaseChain`. The main advantages are 1) answering general questions about the db, 2) access to a tool for double checking queries, and 3) recovering from errors * `ZeroShotAgent.as_json_agent` which returns an agent for interacting with json blobs. * Several examples in notebooks --------- Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
This commit is contained in:
@@ -16,7 +16,7 @@ class FakeRequestsChain(RequestsWrapper):
|
||||
|
||||
output: str
|
||||
|
||||
def run(self, url: str) -> str:
|
||||
def get(self, url: str) -> str:
|
||||
"""Just return the specified output."""
|
||||
return self.output
|
||||
|
||||
|
@@ -9,11 +9,13 @@ def test_python_repl() -> None:
|
||||
|
||||
# Run a simple initial command.
|
||||
repl.run("foo = 1")
|
||||
assert repl._locals["foo"] == 1
|
||||
assert repl.locals is not None
|
||||
assert repl.locals["foo"] == 1
|
||||
|
||||
# Now run a command that accesses `foo` to make sure it still has it.
|
||||
repl.run("bar = foo * 2")
|
||||
assert repl._locals["bar"] == 2
|
||||
assert repl.locals is not None
|
||||
assert repl.locals["bar"] == 2
|
||||
|
||||
|
||||
def test_python_repl_no_previous_variables() -> None:
|
||||
@@ -29,7 +31,8 @@ def test_python_repl_pass_in_locals() -> None:
|
||||
_locals = {"foo": 4}
|
||||
repl = PythonREPL(_locals=_locals)
|
||||
repl.run("bar = foo * 2")
|
||||
assert repl._locals["bar"] == 8
|
||||
assert repl.locals is not None
|
||||
assert repl.locals["bar"] == 8
|
||||
|
||||
|
||||
def test_functionality() -> None:
|
||||
@@ -38,3 +41,15 @@ def test_functionality() -> None:
|
||||
code = "print(1 + 1)"
|
||||
output = chain.run(code)
|
||||
assert output == "2\n"
|
||||
|
||||
|
||||
def test_function() -> None:
|
||||
"""Test correct functionality."""
|
||||
chain = PythonREPL()
|
||||
code = "def add(a, b): " " return a + b"
|
||||
output = chain.run(code)
|
||||
assert output == ""
|
||||
|
||||
code = "print(add(1, 2))"
|
||||
output = chain.run(code)
|
||||
assert output == "3\n"
|
||||
|
1
tests/unit_tests/tools/__init__.py
Normal file
1
tests/unit_tests/tools/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Test suite for the tools module."""
|
49
tests/unit_tests/tools/test_json.py
Normal file
49
tests/unit_tests/tools/test_json.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""Test functionality of JSON tools."""
|
||||
from pathlib import Path
|
||||
|
||||
from langchain.tools.json.tool import JsonSpec
|
||||
|
||||
|
||||
def test_json_spec_from_file(tmp_path: Path) -> None:
|
||||
"""Test JsonSpec can be constructed from a file."""
|
||||
path = tmp_path / "test.json"
|
||||
path.write_text('{"foo": "bar"}')
|
||||
spec = JsonSpec.from_file(path)
|
||||
assert spec.dict_ == {"foo": "bar"}
|
||||
|
||||
|
||||
def test_json_spec_keys() -> None:
|
||||
"""Test JsonSpec can return keys of a dict at given path."""
|
||||
spec = JsonSpec(dict_={"foo": "bar", "baz": {"test": {"foo": [1, 2, 3]}}})
|
||||
assert spec.keys("data") == "['foo', 'baz']"
|
||||
assert "ValueError" in spec.keys('data["foo"]')
|
||||
assert spec.keys('data["baz"]') == "['test']"
|
||||
assert spec.keys('data["baz"]["test"]') == "['foo']"
|
||||
assert "ValueError" in spec.keys('data["baz"]["test"]["foo"]')
|
||||
|
||||
|
||||
def test_json_spec_value() -> None:
|
||||
"""Test JsonSpec can return value of a dict at given path."""
|
||||
spec = JsonSpec(dict_={"foo": "bar", "baz": {"test": {"foo": [1, 2, 3]}}})
|
||||
assert spec.value("data") == "{'foo': 'bar', 'baz': {'test': {'foo': [1, 2, 3]}}}"
|
||||
assert spec.value('data["foo"]') == "bar"
|
||||
assert spec.value('data["baz"]') == "{'test': {'foo': [1, 2, 3]}}"
|
||||
assert spec.value('data["baz"]["test"]') == "{'foo': [1, 2, 3]}"
|
||||
assert spec.value('data["baz"]["test"]["foo"]') == "[1, 2, 3]"
|
||||
|
||||
|
||||
def test_json_spec_value_max_length() -> None:
|
||||
"""Test JsonSpec can return value of a dict at given path."""
|
||||
spec = JsonSpec(
|
||||
dict_={"foo": "bar", "baz": {"test": {"foo": [1, 2, 3]}}}, max_value_length=5
|
||||
)
|
||||
assert spec.value('data["foo"]') == "bar"
|
||||
assert (
|
||||
spec.value('data["baz"]')
|
||||
== "Value is a large dictionary, should explore its keys directly"
|
||||
)
|
||||
assert (
|
||||
spec.value('data["baz"]["test"]')
|
||||
== "Value is a large dictionary, should explore its keys directly"
|
||||
)
|
||||
assert spec.value('data["baz"]["test"]["foo"]') == "[1, 2..."
|
Reference in New Issue
Block a user