litellm/tests/test_litellm/llms/tinyfish
Chenlu Ji c62e1238d6 feat(tinyfish): surface response headers + top-level response extras
Follow-up to #31411 (superseded and merged as #31997). Two related fixes
so LiteLLM callers see what TinyFish actually returns, plus small
correctness cleanups.

## Response headers surfaced on _hidden_params

TinyFish sets useful response headers (x-request-id on every response,
retry-after and x-ratelimit-limit on 429s). Previously these were only
accessible via BaseLLMException.headers on error paths; on the success
path they were dropped entirely.

Fix: stash headers on both LiteLLM-conventional channels, matching the
pattern used by Gemini / Volcengine / Manus / ChatGPT / OpenAI-responses
providers.

- `_hidden_params["headers"]` -- raw dict from httpx, all keys lowercased.
- `_hidden_params["additional_headers"]` -- passed through
  process_response_headers, which prefixes any x-litellm-* provider
  header with `llm_provider-` so downstream LiteLLM code that trusts
  bare x-litellm-* markers can't be spoofed (values still survive
  under the prefixed key for observability).

## Top-level response extras (query, total_results, page, future fields)

transform_search_response was building a fresh SearchResponse from just
`results`, silently dropping every top-level field TinyFish's response
carries beyond `results` / `object`.

Fix: mutate parsed.results to its truncated slice and return the same
SearchResponse instance rather than reconstructing. Every field pydantic
populated during model_validate -- declared attributes AND extras
(query, total_results, page, parameter_warnings, and any future TinyFish
additions) -- survives regardless of which storage bucket holds it.
Robust against upstream schema evolution: if LiteLLM later promotes a
field from extras to declared, this code needs no change.

## Code cleanup

- List-valued custom params JSON-encoded on the wire (matching the
  existing dict handling), so callers can pass a natural Python list
  for JSON-array wire params.
- URL-encodable-params adapter accepts float in addition to
  str / int / bool; server-side rejection of a wrong-typed float now
  surfaces cleanly with `TinyFish Search:` attribution + docs link.
- Assorted comment / docstring / test-fixture hygiene (no logic changes).

## Tests

70 unit + integration tests pass locally. Live-tested against
production TinyFish with 6 diverse queries (basic / max_results /
country=US / language=ja / domain filter / fetch={"format":"html"}) --
all 6 pass every expected-behavior check.
2026-07-08 01:06:17 -07:00
..
test_tinyfish_search.py feat(tinyfish): surface response headers + top-level response extras 2026-07-08 01:06:17 -07:00