LangChain (and LangGraph) tools for iFlow Search (心流搜索) — web search, image search, and web-page fetching.
Project description
iflow-search-langchain
LangChain (and LangGraph) tools for iFlow Search (心流搜索) — web search, image search, and web-page fetching, exposed as langchain_core.tools.BaseTool instances.
- Core SDK:
iflow-search— this package wraps it; do not skip installing it. - Sibling adapter:
iflow-search-mcp— MCP stdio server. - API docs: https://platform.iflow.cn/docs/
- Status: alpha pre-release (
0.1.0a0). Requirespip install --pre.
Install
pip install --pre iflow-search-langchain
--pre is required while the version is still a PEP 440 prerelease.
Quick start — agent with all three tools
import os
from iflow_search_langchain import create_iflow_search_tools
tools = create_iflow_search_tools(api_key=os.environ["IFLOW_API_KEY"])
# tools is a list of three langchain_core BaseTool instances, in fixed order:
# [iflow_web_search, iflow_image_search, iflow_web_fetch]
# All three share one sync + one async client (one connection pool per direction).
# Wire `tools` into your agent of choice (LangChain create_react_agent,
# LangGraph ToolNode, etc.) the same way you would any other LangChain tool.
Single-tool factories
from iflow_search_langchain import (
create_iflow_web_search_tool,
create_iflow_image_search_tool,
create_iflow_web_fetch_tool,
)
web = create_iflow_web_search_tool() # reads IFLOW_API_KEY from env
out = web.invoke({"query": "latest LLM benchmarks", "count": 3})
print(out) # short LLM-facing text summary
Return shape — content_and_artifact
Each tool sets response_format = "content_and_artifact". From _run / _arun you get a tuple[str, dict[str, Any]]:
content— a short LLM-friendly text summary (titles, URLs, snippets).artifact— the core SDK's normalized response as a JSON-serializable dict, including the raw envelope onartifact["raw"].
LangChain's tool.invoke({...}) returns just the content string. To get the artifact, use a ToolCall-shaped input per the LangChain docs for your installed langchain-core version, or call the underlying client directly.
LangGraph
LangGraph consumes LangChain tools directly — there is no separate iflow-search-langgraph package.
import os
from langgraph.prebuilt import create_react_agent
from iflow_search_langchain import create_iflow_search_tools
# Replace `chat_model_of_your_choice` with any LangChain chat model. The
# adapter is provider-free; bring your own LLM.
agent = create_react_agent(
model=chat_model_of_your_choice,
tools=create_iflow_search_tools(api_key=os.environ["IFLOW_API_KEY"]),
)
Configuration
| Argument | Default | Notes |
|---|---|---|
api_key |
IFLOW_API_KEY env var |
Required for auto-built clients. Raises IFlowConfigError at factory-call time (not at first tool invocation) if missing. |
base_url |
core SDK default | Useful for staging / proxy environments. |
timeout |
core SDK default | Applied to each individual request. |
client |
newly built IFlowSearchClient |
Pass your own for connection pooling or test injection. |
async_client |
newly built AsyncIFlowSearchClient |
Pass your own for connection pooling or test injection. |
Attribution and telemetry — read this if it matters to you
When the factory auto-builds the underlying clients (the common case), they carry adapter attribution: IFlow-Source: langchain, IFlow-Integration: iflow-search-langchain, IFlow-Integration-Version: <package version>.
When you pass your own client / async_client, the factory does not mutate them. Whatever attribution your client was built with is what reaches iFlow's telemetry — so a bare AsyncIFlowSearchClient(api_key=...) lands as source="python" (the core's default), not langchain.
If you want your LangChain-driven traffic correctly attributed:
-
Recommended: let the factory build the client (don't pass
client=/async_client=). -
Or: construct the client yourself with the matching attribution kwargs and pass it in:
from iflow_search import IFlowSearchClient IFlowSearchClient( api_key=..., source="langchain", integration_name="iflow-search-langchain", integration_version="0.1.0a0", )
Errors
The adapter does not wrap or remap errors — every IFlowError from the core SDK propagates through the tool boundary with its stable code intact.
from iflow_search import IFlowError, IFlowRateLimitError
from iflow_search_langchain import create_iflow_web_search_tool
tool = create_iflow_web_search_tool()
try:
out = tool.invoke({"query": "x"})
except IFlowRateLimitError:
...
except IFlowError as exc:
print(exc.code, exc.message)
asyncio.CancelledError is not wrapped — it propagates as itself so LangGraph's ToolNode and asyncio.wait_for(...) keep working.
Lifecycle
Auto-built clients are owned by the tool instance. For long-running services that need deterministic cleanup, pass caller-managed clients and close them yourself:
import asyncio
from iflow_search import AsyncIFlowSearchClient
from iflow_search_langchain import create_iflow_search_tools
async def main() -> None:
async with AsyncIFlowSearchClient() as ac:
tools = create_iflow_search_tools(async_client=ac)
# ... use tools ...
What's not included in v0.1.0a0
BaseRetriever,BaseLoader,BaseToolkit— tools only.- A separate
iflow-search-langgraphpackage — LangGraph consumes the tools above directly. - A CLI. The package is a library.
- Streaming. iFlow Search is request/response.
- Bundled LLM-provider code.
Local development
From packages/iflow-search-langchain/:
python -m pip install -e ".[dev]"
python -m pytest -q
python -m ruff check .
python -m mypy src/iflow_search_langchain
python -m build
Real-API smoke
cd packages/iflow-search-langchain
export IFLOW_API_KEY="your-api-key"
export IFLOW_LANGCHAIN_SMOKE=1
python scripts/smoke_real_api.py
The script:
- Is opt-in — without
IFLOW_LANGCHAIN_SMOKE=1it refuses to call the live API. - Reads
IFLOW_API_KEYfrom the environment only — never from disk. - Redacts the key in all log output.
- Does not write any file.
- Does not import LangGraph or any LLM provider — the adapter contract is
(content, artifact)shape correctness, not "an LLM picks the right tool."
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file iflow_search_langchain-0.1.0a0.tar.gz.
File metadata
- Download URL: iflow_search_langchain-0.1.0a0.tar.gz
- Upload date:
- Size: 8.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2458692a2ace01e7f1550ae01a79a488acf1ac7d31e012c327d117c8c74b5e00
|
|
| MD5 |
f366c44c9ca67341fcff6da0d689eae1
|
|
| BLAKE2b-256 |
991eb3393dbe08a08bad69f5cbb417c72cc6d5a4bd88dafd94989927137ca3ee
|
File details
Details for the file iflow_search_langchain-0.1.0a0-py3-none-any.whl.
File metadata
- Download URL: iflow_search_langchain-0.1.0a0-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d33ca3638fb7cfe10bdaac0eef14c97f352e81a1c62ce3ec45f71176efe49f8
|
|
| MD5 |
ba60707a73bc19aead8ba09b450067ee
|
|
| BLAKE2b-256 |
b41746814d6986e8bf18f87e9bbcbd3ee5d6628b98d5eecaa8160352d2dce0f0
|