Skip to content

LW-406 [FIX] send page_separator under both spellings - #36

Merged
johnyrahul merged 1 commit into
mainfrom
LW-406-emit-both-page-separator-spellings
Aug 18, 2026
Merged

LW-406 [FIX] send page_separator under both spellings#36
johnyrahul merged 1 commit into
mainfrom
LW-406-emit-both-page-separator-spellings

Conversation

@chandrasekharan-zipstack

Copy link
Copy Markdown
Collaborator

What

whisper() now sends the page separator value under both page_separator and page_seperator. One line in the params dict, plus tests.

The Python signature is unchanged — this is a wire-level fix only.

Why

2.8.0 renamed the wire param from page_seperator to page_separator. The service only learned to read the corrected name in v2.64.2 (Zipstack/unstract-llm-whisperer#721). Against any older service, 2.8.0 drops the key entirely and the caller's page separator silently reverts to <<< — HTTP 200, no error, no warning.

That constraint is real for self-hosted and on-prem installs, which pick their own service version and supply their own base_url. Nothing in the shipped artifact records the requirement: it lives only in the #34 PR body, which is invisible to anyone running pip install -U llmwhisperer-client.

Note the asymmetry with the other two params 2.8.0 renamed. For line_splitter_strategy and file_name the client was the one misspelling, so the corrected names are what the service has always read and 2.8.0 is a strict improvement at any service version. For page_separator the service carried the typo, so the corrected name is the one that only recent builds understand. It is the only param where the rename can regress.

How

Emitting both keys makes the client version-agnostic and removes the version constraint rather than documenting it:

  • A service on v2.64.2+ reads page_separator and ignores the extra key.
  • An older service reads page_seperator and ignores the one it does not know.

Flask drops unrecognised query params, so neither side errors on the key it does not read. The old key can come out at the next major, alongside the deprecated kwargs.

Notes on Testing

33 passed, offline, no network.

  • New parametrized test asserts both keys carry the same value, on the default path and with an explicit page_separator=.
  • test_whisper_deprecated_page_seperator_is_forwarded extended to assert both keys.
  • test_whisper_sends_corrected_param_names dropped its assert "page_seperator" not in query, which this change deliberately invalidates. The line_spitter_strategy and filename absence assertions are untouched — those keys are still correctly gone.

Release

Patch bump. __version__ is not touched here — the release workflow owns it via workflow_dispatch.

Related

Still open from the #34 review, not addressed here

file_name is sent as an empty string on every default call, and the service's request.args.get("file_name", "sample.pdf") returns "" for a present-but-empty key, so document_name lands blank in usage records for every caller who never set it. Worth folding into the same patch release if you want it — say the word and I will add it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EVoa8BMCNnhdkATd7A9U4J

2.8.0 renamed the wire param from `page_seperator` to `page_separator`, which
only works against a service that reads the corrected name (v2.64.2 and later).
Against an older service the key is dropped and the caller's page separator
silently reverts to `<<<` with a 200 response.

Sending both keys makes the client version-agnostic for the deprecation window:
newer services prefer `page_separator`, older ones read `page_seperator`, and
neither errors on the key it does not recognise.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EVoa8BMCNnhdkATd7A9U4J
@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR restores compatibility with older service versions by sending the page separator under both its corrected and legacy spellings.

  • Adds page_seperator to the query parameters alongside page_separator, using the same resolved value.
  • Adds coverage for default, explicit, and deprecated-argument paths.

Confidence Score: 5/5

The PR appears safe to merge with no actionable defects identified.

The client resolves the separator to one value before constructing the request, emits that identical value under two distinct query keys, and tests cover all supported argument paths.

Important Files Changed

Filename Overview
src/unstract/llmwhisperer/client_v2.py Duplicates the resolved page-separator value under both wire-level spellings without changing the public signature or argument-resolution behavior.
tests/unit/client_v2_test.py Verifies that both spellings carry identical values for default, explicit, and deprecated inputs.

Reviews (1): Last reviewed commit: "fix: send page_separator under both spel..." | Re-trigger Greptile

@github-actions

Copy link
Copy Markdown
Contributor
filepath function $$\textcolor{#23d18b}{\tt{passed}}$$ SUBTOTAL
$$\textcolor{#23d18b}{\tt{tests/integration/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_usage\_info}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/integration/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_v2}}$$ $$\textcolor{#23d18b}{\tt{9}}$$ $$\textcolor{#23d18b}{\tt{9}}$$
$$\textcolor{#23d18b}{\tt{tests/integration/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_highlight}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/integration/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_v2\_url\_in\_post}}$$ $$\textcolor{#23d18b}{\tt{4}}$$ $$\textcolor{#23d18b}{\tt{4}}$$
$$\textcolor{#23d18b}{\tt{tests/integration/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_webhook}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/integration/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_detail}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/integration/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_detail\_not\_found}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/integration/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_line\_splitter\_strategy\_reaches\_service}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_register\_webhook}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_webhook\_details}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_detail\_success}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_detail\_not\_found}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_json\_string\_response\_error}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_json\_string\_response\_202}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_invalid\_json\_response\_error}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_invalid\_json\_response\_202}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_default\_word\_confidence\_threshold}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_custom\_word\_confidence\_threshold}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_sends\_corrected\_param\_names}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_sends\_page\_separator\_under\_both\_spellings}}$$ $$\textcolor{#23d18b}{\tt{2}}$$ $$\textcolor{#23d18b}{\tt{2}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_defaults\_when\_no\_param\_passed}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_deprecated\_page\_seperator\_is\_forwarded}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_deprecated\_filename\_is\_forwarded}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_deprecated\_line\_spitter\_strategy\_is\_ignored}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_rejects\_both\_spellings}}$$ $$\textcolor{#23d18b}{\tt{3}}$$ $$\textcolor{#23d18b}{\tt{3}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_retry\_on\_connection\_error}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_retry\_on\_timeout}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_retry\_on\_429}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_retry\_on\_500}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_no\_retry\_on\_400}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_no\_retry\_on\_401}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_retries\_exhausted\_raises}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_retries\_exhausted\_500\_returns\_response}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_retry\_disabled}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_post\_uses\_min\_of\_api\_timeout\_and\_wait\_timeout}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_whisper\_post\_uses\_wait\_timeout\_when\_smaller}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_send\_request\_deadline\_caps\_timeout}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/unit/client\_v2\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_send\_request\_deadline\_stops\_retries}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_redact\_key\_normal}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_redact\_key\_different\_reveal\_length}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils\_test.py}}$$ $$\textcolor{#23d18b}{\tt{test\_redact\_key\_non\_string\_input}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{TOTAL}}$$ $$\textcolor{#23d18b}{\tt{55}}$$ $$\textcolor{#23d18b}{\tt{55}}$$

@johnyrahul
johnyrahul merged commit 4f2a4ac into main Aug 18, 2026
2 checks passed
@johnyrahul
johnyrahul deleted the LW-406-emit-both-page-separator-spellings branch August 18, 2026 11:05
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.

2 participants