Changelog
You're reading the docs for Semantic Router 0.x. Version 1.0 is out: read this page for v1, or the migration guide to upgrade.
v0.3.3
Security
-
LiteLLM 1.107.0 is excluded. That PyPI release contained malware (a supply-chain attack, live on PyPI on 21 October 2026 from 11:39 to 13:23 UTC), and the
litellmextra allowed it. The extra is nowlitellm>=1.84.0,!=1.107.0. PyPI has removed 1.107.0, but a private mirror may still serve it.If you installed
semantic-router[litellm]or[all]without a lockfile in that window, check without starting Python in that environment: any Python start,pipincluded, runs the malware again. Look at your lockfile or deployment records, or search the environment from a shell, for examplefind <env> -name 'litellm-1.107.0.dist-info' -o -name cook.pth -o -name sitecustomize.py.pip show litellmis safe only in an environment you know is clean, such as one you've just rebuilt.If 1.107.0 was installed, follow LiteLLM's incident guidance: isolate the host, rebuild the environment rather than reinstalling into it, and rotate every credential it could reach, from a clean machine. Finding nothing doesn't prove the environment was never exposed.
-
certifi 2026.10.19 in the lockfile. It removes the
emSign ECC Root CA - G3root, which compromised eMudhra intermediate keys chain to (advisory). semantic-router doesn't pin certifi, sopip install -U certifiupdates the bundle in an existing environment; images and vendored bundles need rebuilding. Connections to Redis or Postgres over TLS may use your operating system's trust store or a CA bundle you configured instead of certifi: update whichever one they use.
v0.3.2
Fixes
RedisIndexreads every record past RediSearch'sMAXSEARCHRESULTSlimit (10,000 on Redis Stack).get_utterancesand the lookups behinddeleteanddelete_allused to stop at the limit without an error, so an index with more records than that synced from an incomplete list and left records behind on delete. Queries are unchanged.RedisIndexdoesn't support open-source Redis Cluster, because it talks to a single endpoint. When the server allowsINFO,RedisIndexnow detects cluster mode and raises a clearValueErrorbefore it writes anything; it used to fail with aMovedErrorafter some writes had landed. If an ACL deniesINFO, the check is skipped, and Cluster is still unsupported.- The Redis guide covers TLS: a
rediss://connection string withssl_ca_certs(and a client certificate and key, if the server needs them) for a private CA.ssl=Truewithhostandporttrusts only the system's CAs.
v0.3.1
Fixes
- Dynamic routes read function inputs that the LLM wraps in a Markdown code block (
```json … ```), alone or after a line of text, instead of failing with aJSONDecodeError. This affects every LLM that asks for the inputs as JSON:OpenAICompatibleLLMand its presets,AzureOpenAILLM,CohereLLM,MistralAILLM,OllamaLLMandOpenRouterLLM.OpenAILLMuses tool calls and is unaffected. Plain JSON is read as before, including backticks inside its strings.
v0.3.0
0.3.0 brings in the features from pull requests that were already open when 0.2.0 shipped, as a one-off exception. It is now the last feature release of the 0.x line: from here, 0.x gets bug fixes only, and new work goes into 1.x. Releases also follow strict semantic versioning from now on: new features raise the minor version, and fixes raise the patch version. These are the changes since 0.2.0, and none of them is breaking.
Features
RedisIndexstores routes in Redis with RediSearch vector search, sync and async. It needs a server with the search module, such as Redis Stack, Redis 8 or Redis Cloud. Installsemantic-router[redis], and see the Redis guide.OpenAICompatibleLLMcalls any OpenAI-compatible chat completions API. Pass itsbase_url, and eitherapi_keyor the name of the environment variable holding the key (api_key_var_name).- Presets built on
OpenAICompatibleLLM, each with its own defaultbase_url:
| LLM | Key variable | Default model |
|---|---|---|
RequestyLLM | REQUESTY_API_KEY | openai/gpt-4o-mini |
OrcaRouterLLM | ORCAROUTER_API_KEY | orcarouter/auto |
AtlasCloudLLM | ATLASCLOUD_API_KEY | deepseek-ai/deepseek-v4-flash |
MiniMaxLLM | MINIMAX_API_KEY | MiniMax-M3.1-Flash |
A preset reads its model from <PROVIDER>_CHAT_MODEL_NAME (REQUESTY_CHAT_MODEL_NAME, for example) when you don't pass name. MiniMaxLLM strips MiniMax-M3's <think> blocks from its replies, and its default max_tokens is 4096 to leave room for thinking.
Limits
RedisIndex on Redis 8 with search workers. With the query engine's worker threads on, Redis 8 can return incomplete results while it re-indexes a key. Redis 8.10 turns them on by default (search-workers 16); 8.0 and 8.2 leave them off. A query that runs while the same keys are being rewritten can miss routes, and so can the scans behind sync and delete. RedisIndex waits for a new or reopened index to finish indexing the keys already in the database (up to index_ready_timeout, 60 seconds by default), but it can't guard against concurrent updates. If routes are updated while the router serves queries, use Redis Stack 7.4 or set search-workers 0. On Redis 8.2 with workers on, a search can also return a record without its score, and RedisIndex raises an error rather than return incomplete results.
OpenAICompatibleLLM and its presets have two limits in 0.x:
- Dynamic routes extract function inputs only when called synchronously.
BaseLLMhas no async extraction, so an async call returns the matched route withfunction_call=Noneand logs an error. - A router config file saves only each LLM's class and model name. A router using
OpenAICompatibleLLMcan't be reloaded from one, because it needs abase_url. A preset reloads with its defaultbase_urland reads its key from its environment variable, so a custombase_urlor a key passed in code is lost.
v0.2.0
0.2.0 is the last feature release of the 0.x line: from here, 0.x gets bug fixes only, and new work goes into 1.x (see the migration guide). These are the changes since 0.1.16.
Breaking changes
- Python 3.10 or later. Python 3.9 is no longer supported, and dependency floors are raised to patched versions.
litellmis optional. Installsemantic-router[litellm]to useLiteLLMEncoder.CohereEncoder,MistralEncoder,VoyageEncoder,JinaEncoderandNimEncodercall their providers directly and no longer need LiteLLM.BM25Encoderscores change. The ATIRE BM25 formula is corrected: document length normalisation, the(k1 + 1)numerator, query IDF weighted by term frequency, and query weights scaled to[0, 1]. Both the document and the query weights change, so vectors stored by 0.1.x don't match queries encoded by 0.2.0: re-encode your documents and rebuild any sparse or hybrid index, then re-check the thresholds you tuned.
Feature
FastEmbedEncodersupports async calls.
Fixes
OpenAIEncoderrejects an empty list, an empty string, non-string items and a barestrwith a clearValueErrorbefore calling the API. It used to retry the API's 400 before failing. Other input is sent unchanged.LocalIndexreturns no results for a route filter that matches no routes, like the other indexes, instead of raising.LocalIndex.addchecks thatmetadata_listis as long as the other inputs.PostgresIndex.aadduses deterministic record ids, asadddoes, so adding a stored utterance again doesn't duplicate it.PostgresIndexno longer fails when two connections create thevectorextension at the same moment.PineconeIndexretries reading the stats of a freshly created index while its host comes up.QdrantIndex: a failed scroll raises instead of reading as an empty index.NimEncoderembeds queries withinput_type="query"instead of"passage".CLIPEncoderandVitEncoderwork with transformers 5.
v0.1.12
The 0.1.12 release brings Pinecone v7 support and AWS Bedrock boto3 client integration, improving compatibility and expanding cloud deployment options.
Feature: Pinecone v7 Upgrade
Semantic Router now supports Pinecone Python SDK v7, providing:
- Improved data plane performance and reliability
- Enhanced async support for high-throughput applications
- Simplified API structure for better developer experience
- Better error handling and retry logic
The upgrade is backward compatible - existing code continues to work without changes. For shared index deployments, set PINECONE_INDEX_NAME to reuse existing indexes and avoid quota limits. Semantic Router automatically isolates data using namespaces.
Feature: Bedrock boto3 Client Support
Added support for custom boto3 clients in the BedrockEncoder, enabling:
- Advanced AWS credential management (IAM roles, cross-account access)
- Custom retry policies and timeout configurations
- VPC endpoint support for private deployments
- Better integration with existing AWS infrastructure
This provides greater flexibility for enterprise AWS deployments while maintaining backward compatibility with the existing credential-based approach.
Chore: Relaxed OpenAI SDK Dependency
Updated OpenAI SDK dependency constraints from <2.0.0 to <3.0.0, allowing compatibility with OpenAI SDK v2.x releases. This provides access to newer OpenAI features and improvements while maintaining stability through the v2 major version.
v0.1.11
The 0.1.11 release introduces new encoder options for local and self-hosted deployments, alongside sparse encoding improvements and CI/CD enhancements.
Feature: Local Encoder
Added LocalEncoder for fully local embedding generation using sentence-transformers:
- No API keys or internet connection required
- Automatic device selection (CUDA, MPS, CPU)
- Support for any sentence-transformers model
- Privacy-first design - all data stays on your machine
Perfect for offline deployments, privacy-sensitive applications, or development environments.
Feature: Local Sparse Encoder
Added sparse encoder support using sentence transformers with LocalSparseEncoder.
- Same offline advantages as the Local Encoder above.
- Better handling of sentence boundaries
- Improved BM25 and TF-IDF implementations
- Enhanced compatibility with
HybridRouter
Feature: Ollama Encoder
Introduced OllamaEncoder for using Ollama-hosted embedding models:
- Works with any Ollama embedding model (nomic-embed-text, mxbai-embed-large, etc.)
- Full control over model versions and hosting
- Low latency with local Ollama instances
- Both sync and async support
Ideal for organizations wanting to self-host embedding models while maintaining API-like convenience.
Feature: Dagger CI
Implemented Dagger for CI/CD pipeline, providing:
- Faster, more reliable builds
- Better caching and parallelization
- Consistent local and remote execution
- Improved developer experience
Chore: Torch Dependency Optimization
Removed torch from main dependencies to reduce installation size. PyTorch is now only installed when needed via semantic-router[local] extras, reducing default installation from ~2GB to <100MB.
v0.1.10
The 0.1.10 release was primarily focused on expanding async support for QdrantIndex, PostgresIndex, and HybridRouter, alongside many synchronization and testing improvements.
Feature: Expanded Async Support
- QdrantIndex: Async methods have been brought inline with our other indexes, ensuring consistent behavior.
- PostgresIndex: Async methods have been added to the
PostgresIndexfor improved performance in async environments. - HybridRouter: Async support for the
HybridRouteris now aligned with theSemanticRouter, providing a more consistent experience.
Fixes and Optimizations
- LocalIndex Bug Fix: Added a
metadataattribute to the local index. This fixes a bug whereLocalIndexembeddings would always be recomputed, as reported in issue #585. - Various other bug fixes and optimizations have been included in this release.
- The
urllib3library has been upgraded. - Test compatibility and synchronization have been optimized.
v0.1.9
The 0.1.9 update focuses on improving support for our local deployment options. We have standardized the PostgresIndex to bring it in line with other index options and prepare it for future feature releases. For local extras (including transformers and llama_cpp support) and postgres extras we have resolved issues making those extras unusable with Python 3.13.
Continue reading below for more detail.
Feature: Improvements to postgres Support
-
Upgrade from psycopg2 to v3 (psycopg): We've upgraded our PostgreSQL driver from psycopg2 to the newer psycopg v3, which provides better performance and modern Python compatibility.
-
Standardization of sync methods: The
PostgresIndexclass now has standardized synchronous methods that integrate seamlessly into our standard pytest test suite, ensuring better testing coverage and reliability. -
Addition of IndexType support: We've introduced
IndexTypewhich includesFLAT,IVFFLAT, andHNSWindex types. BothFLATandIVFFLATmap to theIVFFLATindex in pgvector (pgvector does not currently supportFLATand soIVFFLATis the closest approximation - but our other indexes do).FLATis now the default index type. We recommendHNSWfor high-scale use cases with many millions of utterances due to its higher memory requirements and complexity.
Feature: Configurable Logging
- Environment variable log level control: Logger now supports configurable log levels via environment variables. Set
SEMANTIC_ROUTER_LOG_LEVELorLOG_LEVELto control logging verbosity (e.g.,DEBUG,INFO,WARNING,ERROR). Defaults toINFOif not specified.
Fix: Local Installation for Python 3.13 and up
Python 3.13 and up had originally been incompatible with our local installations due to the lack of compatability with PyTorch and the (then) new version of Python. We have now added the following version support for local libraries:
local = [
"torch>=2.6.0 ; python_version >= '3.13'",
"transformers>=4.50.0 ; python_version >= '3.13'",
"tokenizer>=0.20.2 ; python_version >= '3.13'",
"llama-cpp-python>=0.3.0 ; python_version >= '3.13'",
]Fix: Consistent Index Length Behavior
- Standardized
__len__method across all index implementations: All index types now consistently return0when uninitialized, preventing potentialAttributeErrorexceptions that could occur inPineconeIndexandQdrantIndexwhen checking the length of uninitialized indexes.
Chore: Broader and More Useful Tests
We have broken our tests apart into strict unit and integration test directories. Now, when incoming PRs are raised we will no longer trigger integration tests that require API keys to successfully run. To ensure we're still covering all components of the library we have broadened our testing suite to extensively test LocalIndex, PineconeIndex (via Pinecone Local), PostgresIndex, and QdrantIndex within those unit tests.