Skip to content

Commit e55cabb

Browse files
zhengchaolclaude
andcommitted
feat: support V1 native fast search mode
The V1 Search API added a native `fast` mode — high quality search within a one-second latency budget, sitting between turbo and basic — shipped in parallel-web 1.3.0. The CLI still treated `fast` as a Beta-only alias: it downgraded to `basic` and printed a deprecation warning, so the new mode was unreachable. `--mode fast` now passes through as a first-class V1 value with no warning. The remaining Beta-only names (`one-shot`, `agentic`) keep their translation and deprecation notice. Mode choices are reordered to list V1-native values before the legacy aliases, and the parallel-web floor moves to 1.3.0, whose search() typing includes "fast". Verified against the live API: `--mode fast` returns results with a clean stderr. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 59b0b86 commit e55cabb

4 files changed

Lines changed: 18 additions & 31 deletions

File tree

‎parallel_web_tools/cli/commands.py‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,18 +1088,19 @@ def memory_clear(memory_scope_key: str | None, confirm_clear: bool, output_json:
10881088
# Search Command
10891089
# =============================================================================
10901090

1091-
# Beta -> V1 mode mapping. Beta had three modes; V1 has three (turbo/basic/
1092-
# advanced). We keep the old values as accepted CLI inputs and translate them so
1093-
# existing scripts work.
1091+
# Search mode translation. V1 accepts turbo/fast/basic/advanced natively; the
1092+
# Beta-only values stay accepted CLI inputs and are translated so existing
1093+
# scripts keep working. Beta's `fast` used to downgrade to basic, but V1 now has
1094+
# a native fast mode of its own, so the name passes through.
10941095
_SEARCH_MODE_MAP = {
1095-
"fast": "basic",
1096-
"one-shot": "basic",
1097-
"agentic": "advanced",
10981096
"turbo": "turbo",
1097+
"fast": "fast",
10991098
"basic": "basic",
11001099
"advanced": "advanced",
1100+
"one-shot": "basic",
1101+
"agentic": "advanced",
11011102
}
1102-
_DEPRECATED_SEARCH_MODES = {"fast", "one-shot", "agentic"}
1103+
_DEPRECATED_SEARCH_MODES = {"one-shot", "agentic"}
11031104

11041105

11051106
def _emit_deprecation(message: str) -> None:
@@ -1166,7 +1167,8 @@ def build_search_v1_kwargs(
11661167
"--mode",
11671168
type=click.Choice(list(_SEARCH_MODE_MAP.keys())),
11681169
default="basic",
1169-
help="Search mode: turbo (fastest), basic, or advanced (one-shot/fast → basic, agentic → advanced)",
1170+
help="Search mode: turbo (fastest), fast (high quality within ~1s), basic, "
1171+
"or advanced (highest quality; one-shot → basic, agentic → advanced)",
11701172
show_default=True,
11711173
)
11721174
@click.option("--max-results", type=int, help="Maximum results (defaults to server-side default of 10)")

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ classifiers = [
2929
]
3030

3131
dependencies = [
32-
"parallel-web>=1.2.0,<2",
32+
"parallel-web>=1.3.0,<2",
3333
"python-dotenv>=1.0.0",
3434
# CLI dependencies (minimal - search, extract, enrich with CLI args)
3535
"click>=8.1.0",

‎tests/test_cli.py‎

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,20 +1201,6 @@ def test_explicit_queries_override_objective_fallback(self):
12011201
assert kwargs["search_queries"] == ["first query", "second query"]
12021202
assert kwargs["objective"] == "overarching goal"
12031203

1204-
def test_mode_fast_maps_to_basic(self):
1205-
"""Should map old `fast` mode to V1 `basic`."""
1206-
kwargs = build_search_v1_kwargs(
1207-
objective=None,
1208-
query=("q",),
1209-
mode="fast",
1210-
max_results=None,
1211-
source_policy=None,
1212-
excerpt_max_chars_per_result=None,
1213-
excerpt_max_chars_total=None,
1214-
fetch_policy=None,
1215-
)
1216-
assert kwargs["mode"] == "basic"
1217-
12181204
def test_mode_one_shot_maps_to_basic(self):
12191205
"""Should map old `one-shot` mode to V1 `basic`."""
12201206
kwargs = build_search_v1_kwargs(
@@ -1244,8 +1230,8 @@ def test_mode_agentic_maps_to_advanced(self):
12441230
assert kwargs["mode"] == "advanced"
12451231

12461232
def test_new_mode_values_pass_through(self):
1247-
"""Should accept V1-native `turbo`/`basic`/`advanced` values directly."""
1248-
for new_mode in ("turbo", "basic", "advanced"):
1233+
"""Should accept V1-native `turbo`/`fast`/`basic`/`advanced` values directly."""
1234+
for new_mode in ("turbo", "fast", "basic", "advanced"):
12491235
kwargs = build_search_v1_kwargs(
12501236
objective=None,
12511237
query=("q",),
@@ -1621,7 +1607,6 @@ def _setup_mock_search(self, mock_client):
16211607
@pytest.mark.parametrize(
16221608
"deprecated_mode,expected_new",
16231609
[
1624-
("fast", "basic"),
16251610
("one-shot", "basic"),
16261611
("agentic", "advanced"),
16271612
],
@@ -1644,7 +1629,7 @@ def test_deprecated_modes_emit_warning_to_stderr(self, runner, mock_cli_client,
16441629
call_kwargs = mock_cli_client.search.call_args.kwargs
16451630
assert call_kwargs["mode"] == expected_new
16461631

1647-
@pytest.mark.parametrize("new_mode", ["basic", "advanced"])
1632+
@pytest.mark.parametrize("new_mode", ["turbo", "fast", "basic", "advanced"])
16481633
def test_new_modes_do_not_emit_warning(self, runner, mock_cli_client, new_mode):
16491634
"""Should not warn when V1-native mode values are used."""
16501635
self._setup_mock_search(mock_cli_client)

‎uv.lock‎

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)