fix(perplexity): decode embedding API responses#3344
Conversation
Coverage report (perplexity)Click to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||||||||
|
Let's try to keep test coverage >= 90%. |
|
Thanks for the review @anakin87 — pushed a19c375 to address this. Added unit coverage for the previously-uncovered Perplexity embedding branches: unsupported encoding_format validation + decoding paths in embedding_encoding.py; document usage accumulation across sync and async batches in document_embedder.py; async progress-bar wrapping; and sync/async APIError handling for both raise and skip behavior. |
|
@anakin87 can we please merge this PR? |
anakin87
left a comment
There was a problem hiding this comment.
Thank you for the PR. I left some comments
Now that haystack-core-integrations PR #3344 fixes the embedders to default to encoding_format=base64_int8 and decode responses to list[float], drop the bespoke httpx + np.frombuffer helper and use PerplexityDocumentEmbedder / PerplexityTextEmbedder directly for seeding, querying, and ingest_url chunk embedding. Refs: deepset-ai/haystack-core-integrations#3344
|
Thanks @anakin87 — pushed
Local validation on the integration's Hatch env: |
anakin87
left a comment
There was a problem hiding this comment.
Just a final suggestion/question
| if encoding_format == "float": | ||
| msg = PERPLEXITY_FLOAT_ENCODING_FORMAT_ERROR | ||
| else: | ||
| supported_formats = "', '".join(sorted(SUPPORTED_ENCODING_FORMATS)) | ||
| msg = f"Unsupported encoding_format='{encoding_format}'. Use '{supported_formats}'." |
There was a problem hiding this comment.
| if encoding_format == "float": | |
| msg = PERPLEXITY_FLOAT_ENCODING_FORMAT_ERROR | |
| else: | |
| supported_formats = "', '".join(sorted(SUPPORTED_ENCODING_FORMATS)) | |
| msg = f"Unsupported encoding_format='{encoding_format}'. Use '{supported_formats}'." | |
| supported_formats = "', '".join(sorted(SUPPORTED_ENCODING_FORMATS)) | |
| msg = f"Unsupported encoding_format='{encoding_format}'. Use '{supported_formats}'." |
I'd not distinguish between float and other unsupported formats, no?
Summary
Fixes the Perplexity embedders so they no longer send
encoding_format="float"toPOST /v1/embeddings. Perplexity's embeddings endpoint documentsbase64_int8andbase64_binaryas the supportedencoding_formatvalues: https://docs.perplexity.ai/api-reference/embeddings-postThis PR adds Perplexity-specific response decoding for both sync and async embedding paths:
base64_int8decodes to signed int8 values, casts to float32, and returnslist[float]for HaystackDocument.embedding/ text embedding outputs.base64_binarydecodes packed bits withnp.unpackbits(...)and returns a binary{0, 1}vector aslist[float].encoding_format="float"now fails at construction time with the requested explicit error.Reproduction
Before this change, either embedder sent
encoding_format="float"through the inherited OpenAI embedder request path and Perplexity returned HTTP 400:Approach
Picked Approach A: keep the OpenAI embedder inheritance and override the minimum Perplexity-specific request/response handling.
Live spike status: skipped because
PERPLEXITY_API_KEYis not set in this Buildkite runner. I did run the same SDK behavior check against anhttpx.MockTransport; the OpenAI Python SDK passedencoding_format="base64_int8"through verbatim and exposedresponse.data[0].embeddingas a rawstr, which makes the minimal override viable. Live verification is explicitly marked skipped below rather than faked.Acceptance Criteria
encoding_formatisbase64_int8forPerplexityDocumentEmbedderandPerplexityTextEmbedder.encoding_format="base64_binary"is supported.encoding_format="float"raisesValueErrorwith exactly:Perplexity's /v1/embeddings does not support encoding_format='float'; use 'base64_int8' or 'base64_binary'..to_dict()/from_dict()round-tripencoding_formatwithout renaming or removing existing fields.X-Pplx-Integrationattribution headers remain on outbound embedding requests.base64_int8andbase64_binary.floatand serialization round-trip behavior.@pytest.mark.integrationand now sanity-check the default 1024-dim model response.PERPLEXITY_API_KEYis not set in this runner.Verification