Skip to content

feat(search): add TinyFish as search provider#30158

Closed
simantak-dabhade wants to merge 6 commits into
BerriAI:litellm_oss_staging_120626from
simantak-dabhade:feat/add-tinyfish-search-provider
Closed

feat(search): add TinyFish as search provider#30158
simantak-dabhade wants to merge 6 commits into
BerriAI:litellm_oss_staging_120626from
simantak-dabhade:feat/add-tinyfish-search-provider

Conversation

@simantak-dabhade

Copy link
Copy Markdown

Summary

Adds TinyFish as the 14th search provider in LiteLLM, following the same GET-based pattern as Brave/Serper.

  • Implements TinyfishSearchConfig(BaseSearchConfig) with full request/response transformation
  • Maps unified LiteLLM params (countrylocation, search_domain_filtersite: operators, max_results → client-side truncation)
  • Auth via X-API-Key header (from api_key param or TINYFISH_API_KEY env var)
  • 7 unit tests covering: basic search, country mapping, domain filter injection, language passthrough, max_results truncation, empty results, missing API key

Note: This is a backend-only search provider addition with no UI changes (no visible output to screenshot).

Files changed (8)

File Change
litellm/llms/tinyfish/search/__init__.py New module export
litellm/llms/tinyfish/search/transformation.py Core TinyfishSearchConfig implementation
litellm/types/utils.py Add TINYFISH to SearchProviders enum
litellm/utils.py Register config in get_provider_search_config()
model_prices_and_context_window.json Add tinyfish/search pricing entry
provider_endpoints_support.json Add tinyfish endpoint metadata
tests/code_coverage_tests/enforce_llms_folder_style.py Add tinyfish to SEARCH_PROVIDERS
tests/search_tests/test_tinyfish_search.py 7 unit tests

Proof of testing

$ uv run pytest tests/search_tests/test_tinyfish_search.py -v
tests/search_tests/test_tinyfish_search.py::TestTinyfishSearch::test_basic_search PASSED
tests/search_tests/test_tinyfish_search.py::TestTinyfishSearch::test_country_maps_to_location PASSED
tests/search_tests/test_tinyfish_search.py::TestTinyfishSearch::test_domain_filter_injection PASSED
tests/search_tests/test_tinyfish_search.py::TestTinyfishSearch::test_language_passthrough PASSED
tests/search_tests/test_tinyfish_search.py::TestTinyfishSearch::test_max_results_truncates_response PASSED
tests/search_tests/test_tinyfish_search.py::TestTinyfishSearch::test_empty_results PASSED
tests/search_tests/test_tinyfish_search.py::TestTinyfishSearch::test_missing_api_key PASSED
======================== 7 passed in 1.28s =========================

Live integration test against real TinyFish API also confirmed working (basic search, country, domain filter, max_results all return correct results).

Test plan

  • All 7 unit tests pass
  • Live integration test confirmed working
  • Black formatting applied

🤖 Generated with Claude Code

Terrajlz and others added 5 commits May 22, 2026 13:45
Squash-merged by litellm-agent from devauxbr's PR.
…erriAI#28505) (BerriAI#28575)

* Forward custom_llm_provider through the Responses API bridge (Fixes BerriAI#28505)

When a Chat Completions request to a GPT-5.4+ model contains both
`tools` and `reasoning_effort`, `completion()` auto-routes through
`responses_api_bridge`. The bridge handler called
`litellm.responses()` / `litellm.aresponses()` without forwarding the
already-resolved `custom_llm_provider`, so the downstream call
re-invoked `get_llm_provider()` with `custom_llm_provider=None` and
stripped a second provider prefix from a `provider/provider/model`
deployment string.

For a deployment configured as `openai/openai/openai/gpt-5.5`,
the bridge flow sent `openai/gpt-5.5` to the upstream API instead of
the correct `openai/openai/gpt-5.5`. Upstream APIs that enforce
model-name allow-lists rejected this as `key_model_access_denied`.

Fix: pass the locally-resolved `custom_llm_provider` into both the
sync `responses()` and async `aresponses()` calls so the downstream
`_resolve_model_provider_for_responses` sees an explicit provider
and skips the second prefix-strip.

New regression test
`tests/test_litellm/completion_extras/test_responses_bridge_provider_propagation.py`
pins both call sites: each must forward `custom_llm_provider`.

* fix(28505): set custom_llm_provider on request_data instead of as duplicate kwarg

Greptile flagged that the previous patch passed custom_llm_provider as an
explicit kwarg to responses()/aresponses() while request_data already
carried it via the spread of sanitized_litellm_params, which would raise
TypeError: got multiple values for keyword argument on every real bridge
call.

Switches to assigning request_data['custom_llm_provider'] before the call
so the resolved provider wins over whatever sanitized_litellm_params spread
in, without duplicating the kwarg.

Updates the regression test to seed request_data with a sentinel
custom_llm_provider so it actually exercises the overwrite path (the
previous test mocked transform_request with a minimal dict and never hit
the conflict).

* chore: trigger shin-agent re-eval on retargeted staging base

* chore: trigger shin-agent re-eval against updated Greptile state
Add TinyFish (https://tinyfish.ai) as a new search provider for the
LiteLLM Search API. TinyFish provides web search results via
GET https://api.search.tinyfish.ai with X-API-Key authentication.

Supports unified params (query, country, search_domain_filter) and
TinyFish-specific passthrough params (language, page, include_thumbnail).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…thumbnail type

Address Greptile review feedback:
- Map max_results to query param and truncate results client-side (TinyFish API has no count param)
- Fix include_thumbnail type annotation from str to bool
- Add test for max_results truncation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds TinyFish as the 14th search provider in LiteLLM, following the established GET-based pattern used by Brave and Serper. The implementation is self-contained in litellm/llms/tinyfish/, with the standard registration hooks in types/utils.py and utils.py.

  • TinyfishSearchConfig maps unified LiteLLM params (countrylocation, search_domain_filtersite: operators, max_results → client-side truncation) and passes through TinyFish-native params (e.g., language) via the existing passthrough loop.
  • Auth is via X-API-Key header, resolved from the api_key argument or TINYFISH_API_KEY env var; the missing-key path raises a clear ValueError.
  • Seven mock-only unit tests cover the main parameter transformations; no real network calls are made in the test suite.

Confidence Score: 5/5

Additive provider integration with no changes to existing code paths; safe to merge.

The change is purely additive: new files under litellm/llms/tinyfish/, a single enum entry, and one line in the provider config map. It follows the same GET-based provider pattern as Brave and Serper exactly. No existing behaviour is modified.

No files require special attention.

Important Files Changed

Filename Overview
litellm/llms/tinyfish/search/transformation.py Core TinyfishSearchConfig implementation following the Brave/GET-based provider pattern; max_results clamping is consistent between request and response.
litellm/llms/tinyfish/search/init.py Minimal module export following the same convention as other search providers.
litellm/types/utils.py Adds TINYFISH to the SearchProviders enum; minimal additive change.
litellm/utils.py Registers TinyfishSearchConfig in get_provider_search_config(); follows the established provider registration pattern.
tests/search_tests/test_tinyfish_search.py 7 mock-only unit tests; no real network calls.
model_prices_and_context_window.json Adds tinyfish/search pricing entry with input_cost_per_query=0.0.
provider_endpoints_support.json Adds tinyfish endpoint metadata.
tests/code_coverage_tests/enforce_llms_folder_style.py Registers tinyfish in SEARCH_PROVIDERS list.

Reviews (2): Last reviewed commit: "fix(search/tinyfish): clamp max_results ..." | Re-trigger Greptile

Comment thread litellm/llms/tinyfish/search/transformation.py Outdated
Comment thread litellm/llms/tinyfish/search/transformation.py
…ch_request

Address Greptile P2 feedback: apply max(1, ...) in transform_search_request
so the API receives the same clamped value that transform_search_response uses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Sameerlite

Copy link
Copy Markdown
Collaborator

Thanks for adding TinyFish as a search provider! Two small things to get this review-ready:

  • New commits have landed since Greptile's last pass, so I'm re-triggering a fresh review (below).
  • Could you add proof for the live integration run — captured request/response output or a short transcript? The unit tests are great; a real call would round it out.

@greptileai

Once that's in we'll take another look!

@simantak-dabhade

Copy link
Copy Markdown
Author

Thanks @Sameerlite! Here's the live integration test output against the real TinyFish API:

=== Live Integration Test: TinyFish Search Provider ===

--- Test 1: Basic search ---
Query: "what is litellm proxy"
Results returned: 9
Response object type: search
  [1] GitHub - BerriAI/litellm: Python SDK, Proxy Server (AI Gateway) to ...
      URL: https://github.com/BerriAI/litellm/
      Snippet: LiteLLM is an open source AI Gateway that gives you a single, unified interface to call 100+ LLM providers...
  [2] LiteLLM AI Gateway (LLM Proxy)
      URL: https://docs.litellm.ai/docs/simple_proxy
      Snippet: OpenAI Proxy Server (LLM Gateway) to call 100+ LLMs in a unified interface & track spend, set budgets...
  [3] What is LiteLLM and How to Use it - Codecademy
      URL: https://www.codecademy.com/article/what-is-litellm
      Snippet: The LiteLLM Proxy Server acts as a centralized gateway to manage multiple LLM providers...

--- Test 2: Domain filter (arxiv.org only) ---
Query: "transformer architecture" + domain filter: ["arxiv.org"]
Results returned: 10
All results from arxiv.org: True
  [1] [2304.10557] An Introduction to Transformers - arXiv
      URL: https://arxiv.org/abs/2304.10557
  [2] [1706.03762] Attention Is All You Need - arXiv
      URL: https://arxiv.org/abs/1706.03762
  [3] [2402.08164] On Limitations of the Transformer Architecture - arXiv
      URL: https://arxiv.org/abs/2402.08164

--- Test 3: max_results=2 ---
Query: "python web frameworks" + max_results=2
Results returned: 2
  [1] Which web framework is "king"? : r/Python - Reddit
  [2] WebFrameworks - Python Wiki

--- Test 4: Country="US" ---
Query: "best coffee shops" + country="US"
Results returned: 10
  [1] THE BEST 10 COFFEE & TEA IN WICHITA FALLS, TX - Yelp
      URL: https://www.yelp.com/search?cflt=coffee&find_loc=Wichita+Falls%2C+TX
  [2] THE 5 BEST Cafés in Wichita Falls (Updated 2026) - Tripadvisor
      URL: https://www.tripadvisor.com/Restaurants-g56891-c8-Wichita_Falls_Texas.html

=== All live integration tests passed ===

All features working end-to-end: basic search, domain filtering (site: injection), max_results truncation, and countrylocation mapping.

@Sameerlite Sameerlite changed the base branch from shin_agent_oss_staging_05_22_2026 to litellm_oss_staging_120626 June 12, 2026 10:46

@Sameerlite Sameerlite left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Sameerlite

Copy link
Copy Markdown
Collaborator

@simantak-dabhade Can you fix these merge conflicts? Thanks!

@mateo-berri mateo-berri deleted the branch BerriAI:litellm_oss_staging_120626 June 12, 2026 16:49
simantak-dabhade added a commit to simantak-dabhade/litellm that referenced this pull request Jun 17, 2026
Drop explicit AND from domain filter query to match the approved
implementation. Set pricing to zero. Rename test to match behavior.
tin-berri pushed a commit to simantak-dabhade/litellm that referenced this pull request Jun 17, 2026
Drop explicit AND from domain filter query to match the approved
implementation. Set pricing to zero. Rename test to match behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants