langchain-openpath 0.1.0__py3-none-any.whl

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.
@@ -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,7 @@
1
+ langchain_openpath/__init__.py,sha256=a0SOkb2bdXUPRlPuR0eHIGKaWJ7J1mujnXhyljlI0Hg,431
2
+ langchain_openpath/tools.py,sha256=tp9XbFMXnQRte0ov5bQuVLfc8iCegAM-bGdEjACErjM,2937
3
+ langchain_openpath-0.1.0.dist-info/licenses/LICENSE,sha256=e_-SnBIPjOLgpXWy27cQRmGz95G1IPG7fuDuVAVD1x8,1065
4
+ langchain_openpath-0.1.0.dist-info/METADATA,sha256=OcuGzjN-NhWKOuBSL6574fZuM70FlYWaa66dzIZFkDk,3112
5
+ langchain_openpath-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
6
+ langchain_openpath-0.1.0.dist-info/top_level.txt,sha256=wEXba2-22hNVWFsGC5fkLO3dEqyF9ROgU3hwvlkSD54,19
7
+ langchain_openpath-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -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 @@
1
+ langchain_openpath