From dc1f578ca508843b6021f507810294616f1cac86 Mon Sep 17 00:00:00 2001 From: Min Kim Date: Thu, 2 Jul 2026 13:30:29 -0700 Subject: [PATCH] Add turbo search mode support Adds `turbo` to the accepted Search API modes in ParallelWebSearchTool (the lowest-latency/lowest-cost tier, Parallel Search Turbo). Valid modes are now turbo, basic, and advanced (default advanced). - _VALID_MODES, mode Literal, field description, and class docstring updated - test_passthrough asserts turbo is accepted - CHANGELOG + version bump 0.4.0 -> 0.5.0 Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 8 ++++++++ examples/search_example.py | 2 +- langchain_parallel/search_tool.py | 17 +++++++++-------- pyproject.toml | 2 +- tests/unit_tests/test_search_tool.py | 1 + 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 386d2c7..b8c9aa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.5.0] - 2026-07-XX + +This release adds support for Parallel Search **Turbo** mode. + +### Added + +- **`turbo` search mode** — `ParallelWebSearchTool` now accepts `mode="turbo"`, the lowest-latency and lowest-cost tier (Parallel Search Turbo, ~200ms p50). Valid modes are now `turbo`, `basic`, and `advanced` (default `advanced`). + ## [0.4.0] - 2026-04-28 This is a feature release covering Phase 2 of the modernization roadmap. Adds five new public surfaces (retriever, Task API, FindAll, Monitor, MCP toolkit) and removes the deprecation paths that 0.3.0 introduced. diff --git a/examples/search_example.py b/examples/search_example.py index c776ecf..66b79e6 100644 --- a/examples/search_example.py +++ b/examples/search_example.py @@ -287,7 +287,7 @@ async def main() -> None: print(" - Multi-query search") print(" - Domain filtering with SourcePolicy") print(" - FetchPolicy for cache control") - print(" - Search modes: basic (low-latency) and advanced (high-quality)") + print(" - Search modes: turbo (fastest/cheapest), basic (low-latency), advanced (high-quality)") print(" - Async + parallel execution") print(" - Metadata collection") diff --git a/langchain_parallel/search_tool.py b/langchain_parallel/search_tool.py index e7cb2d9..cbc9977 100644 --- a/langchain_parallel/search_tool.py +++ b/langchain_parallel/search_tool.py @@ -16,15 +16,15 @@ from ._client import get_api_key, get_async_parallel_client, get_parallel_client from ._types import ExcerptSettings, FetchPolicy, SourcePolicy -_VALID_MODES = {"basic", "advanced"} +_VALID_MODES = {"turbo", "basic", "advanced"} def _validate_mode(mode: Optional[str]) -> Optional[str]: - """Validate that ``mode`` is ``"basic"``, ``"advanced"``, or ``None``.""" + """Validate that ``mode`` is ``"turbo"``, ``"basic"``, ``"advanced"``, or ``None``.""" if mode is None or mode in _VALID_MODES: return mode msg = ( - f"Invalid mode '{mode}'. Expected one of: 'basic', 'advanced'. " + f"Invalid mode '{mode}'. Expected one of: 'turbo', 'basic', 'advanced'. " f"(Legacy values 'fast', 'one-shot', 'agentic' were removed in 0.4.0; " f"map 'fast'/'one-shot' to 'basic' and 'agentic' to 'advanced'.)" ) @@ -122,11 +122,12 @@ def _check_query_length(cls, qs: list[str]) -> list[str]: "Useful for capping context size when feeding results to an LLM." ), ) - mode: Optional[Literal["basic", "advanced"]] = Field( + mode: Optional[Literal["turbo", "basic", "advanced"]] = Field( default=None, description=( - "Search mode: 'basic' for low-latency searches, 'advanced' (default) " - "for higher quality with more retrieval and compression." + "Search mode: 'turbo' for the lowest latency and cost, 'basic' for " + "low-latency searches, 'advanced' (default) for higher quality " + "with more retrieval and compression." ), ) source_policy: Optional[Union[SourcePolicy, dict[str, Any]]] = Field( @@ -185,8 +186,8 @@ class ParallelWebSearchTool(BaseTool): This tool calls Parallel's Search API, which streamlines the traditional search -> scrape -> extract pipeline into a single API call. It supports - natural-language objectives, keyword queries, domain filters, two modes - (`basic`, `advanced`), location targeting, and async usage. + natural-language objectives, keyword queries, domain filters, three modes + (`turbo`, `basic`, `advanced`), location targeting, and async usage. Setup: Install `langchain-parallel` and set environment variable diff --git a/pyproject.toml b/pyproject.toml index f293bc8..1e8c533 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "langchain-parallel" -version = "0.4.0" +version = "0.5.0" description = "A LangChain integration for Parallel Web AI services, including Chat and Search." authors = ["Parallel Team "] readme = "README.md" diff --git a/tests/unit_tests/test_search_tool.py b/tests/unit_tests/test_search_tool.py index dd44991..d4774bf 100644 --- a/tests/unit_tests/test_search_tool.py +++ b/tests/unit_tests/test_search_tool.py @@ -293,6 +293,7 @@ def test_parallel_search_tool_is_alias_of_parallel_web_search_tool() -> None: class TestValidateMode: def test_passthrough(self) -> None: + assert _validate_mode("turbo") == "turbo" assert _validate_mode("basic") == "basic" assert _validate_mode("advanced") == "advanced" assert _validate_mode(None) is None