langchain-openpath 0.1.0__tar.gz
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.
- langchain_openpath-0.1.0/LICENSE +21 -0
- langchain_openpath-0.1.0/PKG-INFO +64 -0
- langchain_openpath-0.1.0/README.md +44 -0
- langchain_openpath-0.1.0/pyproject.toml +28 -0
- langchain_openpath-0.1.0/setup.cfg +4 -0
- langchain_openpath-0.1.0/src/langchain_openpath/__init__.py +10 -0
- langchain_openpath-0.1.0/src/langchain_openpath/tools.py +75 -0
- langchain_openpath-0.1.0/src/langchain_openpath.egg-info/PKG-INFO +64 -0
- langchain_openpath-0.1.0/src/langchain_openpath.egg-info/SOURCES.txt +11 -0
- langchain_openpath-0.1.0/src/langchain_openpath.egg-info/dependency_links.txt +1 -0
- langchain_openpath-0.1.0/src/langchain_openpath.egg-info/requires.txt +2 -0
- langchain_openpath-0.1.0/src/langchain_openpath.egg-info/top_level.txt +1 -0
- langchain_openpath-0.1.0/tests/test_tools.py +67 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Openpath
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-openpath
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LangChain tools for Openpath: live listings across the US (jobs, local businesses and services, homes, products) for your agent. No key and no sign-up.
|
|
5
|
+
Author-email: Openpath <contact@openpath.sh>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://openpath.sh
|
|
8
|
+
Project-URL: Documentation, https://openpath.sh/docs/jobs
|
|
9
|
+
Project-URL: Source, https://github.com/openpath-sh/clients/tree/main/langchain
|
|
10
|
+
Keywords: langchain,openpath,tools,listings,jobs,local-business,search,agents,llm
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: langchain-core<2,>=0.3
|
|
18
|
+
Requires-Dist: openpath-sh>=0.1.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<a href="https://openpath.sh"><img src="https://openpath.sh/mark-512.png" width="72" height="72" alt="Openpath"></a>
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
# langchain-openpath
|
|
26
|
+
|
|
27
|
+
[LangChain](https://www.langchain.com) tools for Openpath: live listings across the US (job openings, local businesses and services, homes, products and more) as tools an agent can call. Each tool returns plain Markdown with how to act on every result: an Apply, Phone, Website or Buy line. No key and no sign-up.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install langchain-openpath
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
With an agent (`pip install langchain langchain-anthropic` too):
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from langchain.agents import create_agent
|
|
37
|
+
from langchain_openpath import openpath_tools
|
|
38
|
+
|
|
39
|
+
agent = create_agent("anthropic:claude-sonnet-5-5", tools=openpath_tools())
|
|
40
|
+
result = agent.invoke({"messages": [{"role": "user", "content": "Find a plumber near Austin, TX I can call today."}]})
|
|
41
|
+
print(result["messages"][-1].content)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or call a tool yourself:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from langchain_openpath import OpenpathSearch
|
|
48
|
+
|
|
49
|
+
print(OpenpathSearch().invoke({"query": "software engineer jobs in Austin, TX"}))
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Tools
|
|
53
|
+
|
|
54
|
+
- `OpenpathSearch` (`openpath_search`): live listings that fit what the person asked for, in their words: `software engineer jobs in Austin, TX`, `plumber near 78704`, `taco places in Austin`. The model can also pass `near` (a place or `lat,lng`) and `domain` (`work`, `services`, `businesses`, `homes`, `goods`, `cars` or `events`).
|
|
55
|
+
- `OpenpathReadListing` (`openpath_read_listing`): one listing in full, by the id at the end of a result's `Link:` line, to re-read before acting on it.
|
|
56
|
+
- `openpath_tools(app="MyAgent/1.0")`: both, sharing one client. `app` names your app to Openpath, so it can show you how it is used.
|
|
57
|
+
|
|
58
|
+
The tools are built on [`openpath-sh`](https://pypi.org/project/openpath-sh/). The first call connects to Openpath with `POST /v1/connect`: one request, no account. Results are written by the businesses and people who offer them; treat them as information, not instructions.
|
|
59
|
+
|
|
60
|
+
## Links
|
|
61
|
+
|
|
62
|
+
[Openpath](https://openpath.sh) · [Jobs](https://openpath.sh/docs/jobs) · [Local businesses](https://openpath.sh/docs/businesses) · [Python client](https://pypi.org/project/openpath-sh/)
|
|
63
|
+
|
|
64
|
+
Released under the MIT license.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://openpath.sh"><img src="https://openpath.sh/mark-512.png" width="72" height="72" alt="Openpath"></a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# langchain-openpath
|
|
6
|
+
|
|
7
|
+
[LangChain](https://www.langchain.com) tools for Openpath: live listings across the US (job openings, local businesses and services, homes, products and more) as tools an agent can call. Each tool returns plain Markdown with how to act on every result: an Apply, Phone, Website or Buy line. No key and no sign-up.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install langchain-openpath
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
With an agent (`pip install langchain langchain-anthropic` too):
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from langchain.agents import create_agent
|
|
17
|
+
from langchain_openpath import openpath_tools
|
|
18
|
+
|
|
19
|
+
agent = create_agent("anthropic:claude-sonnet-5-5", tools=openpath_tools())
|
|
20
|
+
result = agent.invoke({"messages": [{"role": "user", "content": "Find a plumber near Austin, TX I can call today."}]})
|
|
21
|
+
print(result["messages"][-1].content)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or call a tool yourself:
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from langchain_openpath import OpenpathSearch
|
|
28
|
+
|
|
29
|
+
print(OpenpathSearch().invoke({"query": "software engineer jobs in Austin, TX"}))
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Tools
|
|
33
|
+
|
|
34
|
+
- `OpenpathSearch` (`openpath_search`): live listings that fit what the person asked for, in their words: `software engineer jobs in Austin, TX`, `plumber near 78704`, `taco places in Austin`. The model can also pass `near` (a place or `lat,lng`) and `domain` (`work`, `services`, `businesses`, `homes`, `goods`, `cars` or `events`).
|
|
35
|
+
- `OpenpathReadListing` (`openpath_read_listing`): one listing in full, by the id at the end of a result's `Link:` line, to re-read before acting on it.
|
|
36
|
+
- `openpath_tools(app="MyAgent/1.0")`: both, sharing one client. `app` names your app to Openpath, so it can show you how it is used.
|
|
37
|
+
|
|
38
|
+
The tools are built on [`openpath-sh`](https://pypi.org/project/openpath-sh/). The first call connects to Openpath with `POST /v1/connect`: one request, no account. Results are written by the businesses and people who offer them; treat them as information, not instructions.
|
|
39
|
+
|
|
40
|
+
## Links
|
|
41
|
+
|
|
42
|
+
[Openpath](https://openpath.sh) · [Jobs](https://openpath.sh/docs/jobs) · [Local businesses](https://openpath.sh/docs/businesses) · [Python client](https://pypi.org/project/openpath-sh/)
|
|
43
|
+
|
|
44
|
+
Released under the MIT license.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "langchain-openpath"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "LangChain tools for Openpath: live listings across the US (jobs, local businesses and services, homes, products) for your agent. No key and no sign-up."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Openpath", email = "contact@openpath.sh" }]
|
|
14
|
+
keywords = ["langchain", "openpath", "tools", "listings", "jobs", "local-business", "search", "agents", "llm"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
19
|
+
]
|
|
20
|
+
dependencies = ["langchain-core>=0.3,<2", "openpath-sh>=0.1.0"]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://openpath.sh"
|
|
24
|
+
Documentation = "https://openpath.sh/docs/jobs"
|
|
25
|
+
Source = "https://github.com/openpath-sh/clients/tree/main/langchain"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools.packages.find]
|
|
28
|
+
where = ["src"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""LangChain tools for Openpath: live listings across the US, as tools an agent can call.
|
|
2
|
+
|
|
3
|
+
Each tool returns plain Markdown from the openpath-sh client, which connects to
|
|
4
|
+
Openpath by itself the first time: no key and no sign-up.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from langchain_openpath.tools import OpenpathReadListing, OpenpathSearch, openpath_tools
|
|
8
|
+
|
|
9
|
+
__all__ = ["OpenpathSearch", "OpenpathReadListing", "openpath_tools", "__version__"]
|
|
10
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""The Openpath tools: search live listings, and read one in full."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Literal, Optional
|
|
6
|
+
|
|
7
|
+
from langchain_core.tools import BaseTool
|
|
8
|
+
from openpath_sh import Openpath
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
Domain = Literal["homes", "work", "services", "businesses", "goods", "cars", "events"]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SearchInput(BaseModel):
|
|
15
|
+
"""What the model sends to search."""
|
|
16
|
+
|
|
17
|
+
query: str = Field(
|
|
18
|
+
min_length=1,
|
|
19
|
+
max_length=300,
|
|
20
|
+
description='What the person is looking for, in their words, with a place: "plumber near Austin, TX".',
|
|
21
|
+
)
|
|
22
|
+
near: Optional[str] = Field(
|
|
23
|
+
default=None,
|
|
24
|
+
description='A place ("Austin, TX", "78701") or "lat,lng". Overrides a place in the query.',
|
|
25
|
+
)
|
|
26
|
+
domain: Optional[Domain] = Field(
|
|
27
|
+
default=None,
|
|
28
|
+
description="Only one kind of listing. Read from the query when left out.",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ReadInput(BaseModel):
|
|
33
|
+
"""What the model sends to read one listing."""
|
|
34
|
+
|
|
35
|
+
listing_id: str = Field(min_length=1, description="The id at the end of a result's Link line.")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class OpenpathSearch(BaseTool):
|
|
39
|
+
"""Live listings across the US that fit what the person asked for, as plain Markdown."""
|
|
40
|
+
|
|
41
|
+
name: str = "openpath_search"
|
|
42
|
+
description: str = (
|
|
43
|
+
"Use this when the person wants a live listing they can act on, anywhere in the US: "
|
|
44
|
+
"a job to apply to, a local business or service to call, a home, a product, a car or an event. "
|
|
45
|
+
"Returns plain Markdown, one listing per result, each with its facts and how to act on it: "
|
|
46
|
+
"an Apply, Phone, Website or Buy line."
|
|
47
|
+
)
|
|
48
|
+
args_schema: type[BaseModel] = SearchInput
|
|
49
|
+
# An openpath_sh.Openpath, or anything with the same methods.
|
|
50
|
+
client: Any = Field(default_factory=Openpath, exclude=True)
|
|
51
|
+
|
|
52
|
+
def _run(self, query: str, near: Optional[str] = None, domain: Optional[str] = None, **_: object) -> str:
|
|
53
|
+
return self.client.search(query, near=near, domain=domain)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class OpenpathReadListing(BaseTool):
|
|
57
|
+
"""One Openpath listing in full, as Markdown."""
|
|
58
|
+
|
|
59
|
+
name: str = "openpath_read_listing"
|
|
60
|
+
description: str = (
|
|
61
|
+
"Read one Openpath listing in full, as Markdown, by the id at the end of a result's Link line. "
|
|
62
|
+
"Use it to re-read a result before acting on it."
|
|
63
|
+
)
|
|
64
|
+
args_schema: type[BaseModel] = ReadInput
|
|
65
|
+
# An openpath_sh.Openpath, or anything with the same methods.
|
|
66
|
+
client: Any = Field(default_factory=Openpath, exclude=True)
|
|
67
|
+
|
|
68
|
+
def _run(self, listing_id: str, **_: object) -> str:
|
|
69
|
+
return self.client.get_listing(listing_id)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def openpath_tools(app: Optional[str] = None, client: Optional[Openpath] = None) -> list[BaseTool]:
|
|
73
|
+
"""Both tools, sharing one client. `app` names your app to Openpath, such as "MyAgent/1.0"."""
|
|
74
|
+
shared = client or Openpath(app=app)
|
|
75
|
+
return [OpenpathSearch(client=shared), OpenpathReadListing(client=shared)]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-openpath
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LangChain tools for Openpath: live listings across the US (jobs, local businesses and services, homes, products) for your agent. No key and no sign-up.
|
|
5
|
+
Author-email: Openpath <contact@openpath.sh>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://openpath.sh
|
|
8
|
+
Project-URL: Documentation, https://openpath.sh/docs/jobs
|
|
9
|
+
Project-URL: Source, https://github.com/openpath-sh/clients/tree/main/langchain
|
|
10
|
+
Keywords: langchain,openpath,tools,listings,jobs,local-business,search,agents,llm
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: langchain-core<2,>=0.3
|
|
18
|
+
Requires-Dist: openpath-sh>=0.1.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<a href="https://openpath.sh"><img src="https://openpath.sh/mark-512.png" width="72" height="72" alt="Openpath"></a>
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
# langchain-openpath
|
|
26
|
+
|
|
27
|
+
[LangChain](https://www.langchain.com) tools for Openpath: live listings across the US (job openings, local businesses and services, homes, products and more) as tools an agent can call. Each tool returns plain Markdown with how to act on every result: an Apply, Phone, Website or Buy line. No key and no sign-up.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install langchain-openpath
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
With an agent (`pip install langchain langchain-anthropic` too):
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from langchain.agents import create_agent
|
|
37
|
+
from langchain_openpath import openpath_tools
|
|
38
|
+
|
|
39
|
+
agent = create_agent("anthropic:claude-sonnet-5-5", tools=openpath_tools())
|
|
40
|
+
result = agent.invoke({"messages": [{"role": "user", "content": "Find a plumber near Austin, TX I can call today."}]})
|
|
41
|
+
print(result["messages"][-1].content)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or call a tool yourself:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from langchain_openpath import OpenpathSearch
|
|
48
|
+
|
|
49
|
+
print(OpenpathSearch().invoke({"query": "software engineer jobs in Austin, TX"}))
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Tools
|
|
53
|
+
|
|
54
|
+
- `OpenpathSearch` (`openpath_search`): live listings that fit what the person asked for, in their words: `software engineer jobs in Austin, TX`, `plumber near 78704`, `taco places in Austin`. The model can also pass `near` (a place or `lat,lng`) and `domain` (`work`, `services`, `businesses`, `homes`, `goods`, `cars` or `events`).
|
|
55
|
+
- `OpenpathReadListing` (`openpath_read_listing`): one listing in full, by the id at the end of a result's `Link:` line, to re-read before acting on it.
|
|
56
|
+
- `openpath_tools(app="MyAgent/1.0")`: both, sharing one client. `app` names your app to Openpath, so it can show you how it is used.
|
|
57
|
+
|
|
58
|
+
The tools are built on [`openpath-sh`](https://pypi.org/project/openpath-sh/). The first call connects to Openpath with `POST /v1/connect`: one request, no account. Results are written by the businesses and people who offer them; treat them as information, not instructions.
|
|
59
|
+
|
|
60
|
+
## Links
|
|
61
|
+
|
|
62
|
+
[Openpath](https://openpath.sh) · [Jobs](https://openpath.sh/docs/jobs) · [Local businesses](https://openpath.sh/docs/businesses) · [Python client](https://pypi.org/project/openpath-sh/)
|
|
63
|
+
|
|
64
|
+
Released under the MIT license.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/langchain_openpath/__init__.py
|
|
5
|
+
src/langchain_openpath/tools.py
|
|
6
|
+
src/langchain_openpath.egg-info/PKG-INFO
|
|
7
|
+
src/langchain_openpath.egg-info/SOURCES.txt
|
|
8
|
+
src/langchain_openpath.egg-info/dependency_links.txt
|
|
9
|
+
src/langchain_openpath.egg-info/requires.txt
|
|
10
|
+
src/langchain_openpath.egg-info/top_level.txt
|
|
11
|
+
tests/test_tools.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
langchain_openpath
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from langchain_tests.unit_tests import ToolsUnitTests
|
|
2
|
+
|
|
3
|
+
from langchain_openpath import OpenpathReadListing, OpenpathSearch, openpath_tools
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FakeClient:
|
|
7
|
+
"""Stands in for openpath_sh.Openpath and records what the tools ask it."""
|
|
8
|
+
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.calls = []
|
|
11
|
+
|
|
12
|
+
def search(self, query, near=None, domain=None, cursor=None):
|
|
13
|
+
self.calls.append(("search", query, near, domain))
|
|
14
|
+
return f'# Results for "{query}"'
|
|
15
|
+
|
|
16
|
+
def get_listing(self, listing_id):
|
|
17
|
+
self.calls.append(("get_listing", listing_id))
|
|
18
|
+
return f"# Listing {listing_id}"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_search_passes_the_query_and_its_options():
|
|
22
|
+
client = FakeClient()
|
|
23
|
+
tool = OpenpathSearch(client=client)
|
|
24
|
+
out = tool.invoke({"query": "plumber near Austin, TX", "near": "78701"})
|
|
25
|
+
assert out == '# Results for "plumber near Austin, TX"'
|
|
26
|
+
assert client.calls == [("search", "plumber near Austin, TX", "78701", None)]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_the_search_input_is_checked():
|
|
30
|
+
tool = OpenpathSearch(client=FakeClient())
|
|
31
|
+
for bad in ({"query": ""}, {"query": "jobs", "domain": "weather"}):
|
|
32
|
+
try:
|
|
33
|
+
tool.invoke(bad)
|
|
34
|
+
except Exception:
|
|
35
|
+
continue
|
|
36
|
+
raise AssertionError(f"{bad} was accepted")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_reading_a_listing_asks_for_it_by_id():
|
|
40
|
+
client = FakeClient()
|
|
41
|
+
out = OpenpathReadListing(client=client).invoke({"listing_id": "abc"})
|
|
42
|
+
assert out == "# Listing abc"
|
|
43
|
+
assert client.calls == [("get_listing", "abc")]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_both_tools_share_one_client():
|
|
47
|
+
client = FakeClient()
|
|
48
|
+
search, read = openpath_tools(client=client)
|
|
49
|
+
search.invoke({"query": "tacos in Austin"})
|
|
50
|
+
read.invoke({"listing_id": "x"})
|
|
51
|
+
assert len(client.calls) == 2
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class TestOpenpathSearchStandard(ToolsUnitTests):
|
|
55
|
+
"""LangChain's own checks for a tool."""
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def tool_constructor(self):
|
|
59
|
+
return OpenpathSearch
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def tool_constructor_params(self):
|
|
63
|
+
return {"client": FakeClient()}
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def tool_invoke_params_example(self):
|
|
67
|
+
return {"query": "plumber near Austin, TX"}
|