forked from innovacion/searchbox
Compare commits
1 Commits
0fa82cff7d
...
embedding-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a7918e3d8 |
@@ -5,6 +5,7 @@ description = "Add your description here"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"openai>=2.0.0",
|
||||||
"qdrant-client==1.13",
|
"qdrant-client==1.13",
|
||||||
"vault-settings>=0.1.0",
|
"vault-settings>=0.1.0",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -11,10 +11,6 @@ from .engine import Backend, get_engine
|
|||||||
from .models import Chunk, Condition
|
from .models import Chunk, Condition
|
||||||
|
|
||||||
|
|
||||||
class QueryError(ValueError):
|
|
||||||
"""Raised when query parameters are invalid."""
|
|
||||||
|
|
||||||
|
|
||||||
class EmbedderNotConfiguredError(ValueError):
|
class EmbedderNotConfiguredError(ValueError):
|
||||||
"""Raised when embedder is required but not configured."""
|
"""Raised when embedder is required but not configured."""
|
||||||
|
|
||||||
@@ -79,8 +75,7 @@ class Client:
|
|||||||
|
|
||||||
async def semantic_search(
|
async def semantic_search(
|
||||||
self,
|
self,
|
||||||
query: str | list[float] | None = None,
|
query: str | list[float],
|
||||||
embedding: list[float] | None = None,
|
|
||||||
limit: int = 10,
|
limit: int = 10,
|
||||||
conditions: list[Condition] | None = None,
|
conditions: list[Condition] | None = None,
|
||||||
threshold: float | None = None,
|
threshold: float | None = None,
|
||||||
@@ -88,8 +83,7 @@ class Client:
|
|||||||
"""Perform semantic search using vector similarity.
|
"""Perform semantic search using vector similarity.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
query: Text query to embed (requires embedder to be configured)
|
query: Text query to embed (requires embedder) or pre-computed vector
|
||||||
embedding: Pre-computed query vector as a list of floats
|
|
||||||
limit: Maximum number of results to return (default: 10)
|
limit: Maximum number of results to return (default: 10)
|
||||||
conditions: Optional list of filter conditions to apply
|
conditions: Optional list of filter conditions to apply
|
||||||
threshold: Optional minimum similarity score threshold
|
threshold: Optional minimum similarity score threshold
|
||||||
@@ -98,28 +92,18 @@ class Client:
|
|||||||
List of search results with chunk IDs, scores, and metadata
|
List of search results with chunk IDs, scores, and metadata
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If neither query nor embedding is provided, or if query
|
EmbedderNotConfiguredError: If query is a string but no embedder is configured
|
||||||
is provided but no embedder is configured
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if query is None and embedding is None:
|
# Handle query parameter
|
||||||
msg = "Either 'query' or 'embedding' must be provided"
|
if isinstance(query, str):
|
||||||
raise QueryError(msg)
|
if self.embedder is None:
|
||||||
|
msg = "Cannot use text query without an embedder"
|
||||||
if query is not None and embedding is not None:
|
raise EmbedderNotConfiguredError(msg)
|
||||||
msg = "Only one of 'query' or 'embedding' should be provided"
|
embedding = self.embedder.embed(query)
|
||||||
raise QueryError(msg)
|
else:
|
||||||
|
# query is already a list[float]
|
||||||
# Handle query string
|
embedding = query
|
||||||
if query is not None:
|
|
||||||
if isinstance(query, str):
|
|
||||||
if self.embedder is None:
|
|
||||||
msg = "Cannot use 'query' parameter without an embedder"
|
|
||||||
raise EmbedderNotConfiguredError(msg)
|
|
||||||
embedding = self.embedder.embed(query)
|
|
||||||
else:
|
|
||||||
# query is already a list[float]
|
|
||||||
embedding = query
|
|
||||||
|
|
||||||
return await self.engine.semantic_search(
|
return await self.engine.semantic_search(
|
||||||
embedding, self.collection, limit, conditions, threshold
|
embedding, self.collection, limit, conditions, threshold
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ class Settings(VaultSettings):
|
|||||||
qdrant_url: The URL endpoint for the vector database server (e.g., Qdrant).
|
qdrant_url: The URL endpoint for the vector database server (e.g., Qdrant).
|
||||||
qdrant_api_key: Optional API key for authenticating with the vector database.
|
qdrant_api_key: Optional API key for authenticating with the vector database.
|
||||||
If None, the connection will be made without authentication.
|
If None, the connection will be made without authentication.
|
||||||
|
azure_openai_endpoint: Azure OpenAI endpoint URL.
|
||||||
|
azure_openai_api_key: Azure OpenAI API key.
|
||||||
|
azure_openai_api_version: Azure OpenAI API version (e.g., "2024-02-01").
|
||||||
|
azure_openai_embedding_model: Azure OpenAI embedding model name.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
>>> settings = Settings()
|
>>> settings = Settings()
|
||||||
@@ -34,3 +38,7 @@ class Settings(VaultSettings):
|
|||||||
|
|
||||||
qdrant_url: str
|
qdrant_url: str
|
||||||
qdrant_api_key: str | None = None
|
qdrant_api_key: str | None = None
|
||||||
|
azure_openai_endpoint: str | None = None
|
||||||
|
azure_openai_api_key: str | None = None
|
||||||
|
azure_openai_api_version: str | None = None
|
||||||
|
azure_openai_embedding_model: str | None = None
|
||||||
|
|||||||
@@ -1 +1,115 @@
|
|||||||
"""Embedder class using Azure AI Foundry."""
|
"""Embedder package.
|
||||||
|
|
||||||
|
This package provides an abstract embedder interface and concrete implementations
|
||||||
|
for different embedding service providers. It uses a factory pattern with caching
|
||||||
|
to provide efficient embedder instantiation.
|
||||||
|
|
||||||
|
The package includes:
|
||||||
|
- Abstract BaseEmbedder class
|
||||||
|
- AzureEmbedder implementation for Azure OpenAI
|
||||||
|
- EmbedderBackend enum for specifying embedder types
|
||||||
|
- Factory function with overloaded type hints for type safety
|
||||||
|
|
||||||
|
Example:
|
||||||
|
>>> from searchbox.embedder import get_embedder, EmbedderBackend
|
||||||
|
>>> embedder = get_embedder(EmbedderBackend.AZURE)
|
||||||
|
>>> embedding = embedder.embed("Hello world")
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from enum import StrEnum
|
||||||
|
from functools import cache
|
||||||
|
from typing import Literal, overload
|
||||||
|
|
||||||
|
from .azure import AzureEmbedder
|
||||||
|
from .base import BaseEmbedder
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownEmbedderError(Exception):
|
||||||
|
"""Exception raised when an unknown embedder is requested."""
|
||||||
|
|
||||||
|
def __init__(self, backend: str):
|
||||||
|
"""Initialize the exception with the unknown backend."""
|
||||||
|
super().__init__(f"Unknown embedder type: {backend}")
|
||||||
|
|
||||||
|
|
||||||
|
class EmbedderBackend(StrEnum):
|
||||||
|
"""Enumeration of supported embedder backends.
|
||||||
|
|
||||||
|
This enum defines the available embedder implementations that can
|
||||||
|
be used with the embedder factory. Each backend corresponds to a specific
|
||||||
|
embedding service provider.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
AZURE: Azure OpenAI embedder backend
|
||||||
|
|
||||||
|
Example:
|
||||||
|
>>> backend = EmbedderBackend.AZURE
|
||||||
|
>>> print(backend) # "azure"
|
||||||
|
>>> embedder = get_embedder(backend)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
AZURE = "azure"
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def get_embedder(backend: Literal["azure"]) -> AzureEmbedder: ...
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def get_embedder(
|
||||||
|
backend: Literal["azure"],
|
||||||
|
model: str,
|
||||||
|
azure_endpoint: str,
|
||||||
|
api_key: str,
|
||||||
|
openai_api_version: str,
|
||||||
|
) -> AzureEmbedder: ...
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def get_embedder(backend: EmbedderBackend, **kwargs: str) -> BaseEmbedder: ...
|
||||||
|
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def get_embedder(backend: EmbedderBackend, **kwargs: str) -> BaseEmbedder:
|
||||||
|
"""Get an embedder instance for the specified backend.
|
||||||
|
|
||||||
|
This factory function creates and returns embedder instances based on the
|
||||||
|
specified backend type. Instances are cached using functools.cache, so
|
||||||
|
multiple calls with the same backend will return the same instance.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
backend: The embedder backend to use. Must be an EmbedderBackend enum value.
|
||||||
|
**kwargs: Additional keyword arguments to pass to the embedder constructor.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An embedder instance implementing the BaseEmbedder interface. The specific
|
||||||
|
type depends on the backend:
|
||||||
|
- EmbedderBackend.AZURE returns AzureEmbedder
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
UnknownEmbedderError: If an unknown backend type is provided.
|
||||||
|
ValueError: If required settings are missing when using from_settings.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
>>> embedder = get_embedder(EmbedderBackend.AZURE)
|
||||||
|
>>> isinstance(embedder, AzureEmbedder) # True
|
||||||
|
|
||||||
|
>>> # Type checker knows the exact type for literals:
|
||||||
|
>>> azure_embedder = get_embedder(EmbedderBackend.AZURE) # Type: AzureEmbedder
|
||||||
|
|
||||||
|
"""
|
||||||
|
if backend == EmbedderBackend.AZURE:
|
||||||
|
return AzureEmbedder(**kwargs) if kwargs else AzureEmbedder.from_settings()
|
||||||
|
else:
|
||||||
|
raise UnknownEmbedderError(backend)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BaseEmbedder",
|
||||||
|
"AzureEmbedder",
|
||||||
|
"EmbedderBackend",
|
||||||
|
"get_embedder",
|
||||||
|
"UnknownEmbedderError",
|
||||||
|
]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from openai import AzureOpenAI
|
from openai import AzureOpenAI
|
||||||
|
|
||||||
|
from ..config import Settings
|
||||||
from .base import BaseEmbedder
|
from .base import BaseEmbedder
|
||||||
|
|
||||||
|
|
||||||
@@ -52,6 +53,42 @@ class AzureEmbedder(BaseEmbedder):
|
|||||||
api_version=openai_api_version,
|
api_version=openai_api_version,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_settings(cls) -> "AzureEmbedder":
|
||||||
|
"""Initialize the Azure embedder from Settings.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Initialized AzureEmbedder instance.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If required settings are not configured.
|
||||||
|
|
||||||
|
"""
|
||||||
|
settings = Settings() # type: ignore[reportCallArgs]
|
||||||
|
|
||||||
|
if not all(
|
||||||
|
[
|
||||||
|
settings.azure_openai_endpoint,
|
||||||
|
settings.azure_openai_api_key,
|
||||||
|
settings.azure_openai_api_version,
|
||||||
|
settings.azure_openai_embedding_model,
|
||||||
|
]
|
||||||
|
):
|
||||||
|
msg = (
|
||||||
|
"Missing required Azure OpenAI settings. "
|
||||||
|
"Ensure AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY, "
|
||||||
|
"AZURE_OPENAI_API_VERSION, and AZURE_OPENAI_EMBEDDING_MODEL "
|
||||||
|
"are set."
|
||||||
|
)
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
return cls(
|
||||||
|
model=settings.azure_openai_embedding_model, # type: ignore[arg-type]
|
||||||
|
azure_endpoint=settings.azure_openai_endpoint, # type: ignore[arg-type]
|
||||||
|
api_key=settings.azure_openai_api_key, # type: ignore[arg-type]
|
||||||
|
openai_api_version=settings.azure_openai_api_version, # type: ignore[arg-type]
|
||||||
|
)
|
||||||
|
|
||||||
def embed(self, text: str) -> list[float]:
|
def embed(self, text: str) -> list[float]:
|
||||||
"""Generate embedding vector for the given text.
|
"""Generate embedding vector for the given text.
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
"""Main MCP server implementation for vector search operations.
|
"""Main MCP server implementation for vector search operations.
|
||||||
|
|
||||||
This module sets up and configures the FastMCP server with vector search capabilities.
|
This module sets up and configures the FastMCP server with vector search capabilities.
|
||||||
It creates a Qdrant engine instance and exposes the semantic search functionality
|
It creates engine and embedder instances and exposes the semantic search functionality
|
||||||
as an MCP tool.
|
as an MCP tool.
|
||||||
|
|
||||||
The server provides:
|
The server provides:
|
||||||
- Semantic search tool for vector similarity queries
|
- Semantic search tool for vector similarity queries
|
||||||
- Support for various search conditions and filters
|
- Support for various search conditions and filters
|
||||||
- Integration with Qdrant vector database
|
- Integration with vector databases and embedding services
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
The server is typically started using the run function from the package:
|
The server is typically started using the run function from the package:
|
||||||
@@ -22,38 +22,36 @@ from fastmcp import FastMCP
|
|||||||
from starlette.requests import Request
|
from starlette.requests import Request
|
||||||
from starlette.responses import JSONResponse
|
from starlette.responses import JSONResponse
|
||||||
|
|
||||||
from ..client import Backend, Client
|
from ..client import Client
|
||||||
from ..embedder.azure import AzureEmbedder
|
from ..embedder import EmbedderBackend, get_embedder
|
||||||
|
|
||||||
mcp = FastMCP("Searchbox MCP")
|
mcp = FastMCP("Searchbox MCP")
|
||||||
|
|
||||||
# Initialize Azure embedder
|
# Initialize embedder map
|
||||||
embedder = AzureEmbedder(
|
embedder_map = {
|
||||||
model="",
|
"azure": get_embedder(EmbedderBackend.AZURE),
|
||||||
azure_endpoint="",
|
}
|
||||||
api_key="",
|
|
||||||
openai_api_version="",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool(exclude_args=["backend", "collection", "limit", "threshold"])
|
@mcp.tool(exclude_args=["backend", "collection", "embedder", "limit", "threshold"])
|
||||||
async def get_information(
|
async def get_information(
|
||||||
query: Annotated[str, "The user query"],
|
query: Annotated[str, "The user query"],
|
||||||
backend: str = "qdrant",
|
backend: str = "qdrant",
|
||||||
collection: str = "default",
|
collection: str = "default",
|
||||||
|
embedder: str = "azure",
|
||||||
limit: int = 10,
|
limit: int = 10,
|
||||||
threshold: float | None = None,
|
threshold: float | None = None,
|
||||||
):
|
):
|
||||||
"""Search a private repository for information using semantic search.
|
"""Search a private repository for information using semantic search.
|
||||||
|
|
||||||
The query will be automatically converted to an embedding vector using
|
The query will be automatically converted to an embedding vector using
|
||||||
Azure OpenAI's text-embedding-3-large model before searching.
|
the specified embedder before searching.
|
||||||
"""
|
"""
|
||||||
# Create client with embedder
|
# Create client with embedder
|
||||||
client = Client(
|
client = Client(
|
||||||
backend=Backend.QDRANT if backend == "qdrant" else Backend.QDRANT,
|
backend=backend, # type: ignore[arg-type]
|
||||||
collection=collection,
|
collection=collection,
|
||||||
embedder=embedder,
|
embedder=embedder_map[embedder],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Perform semantic search with automatic embedding
|
# Perform semantic search with automatic embedding
|
||||||
|
|||||||
68
uv.lock
generated
68
uv.lock
generated
@@ -1,5 +1,5 @@
|
|||||||
version = 1
|
version = 1
|
||||||
revision = 3
|
revision = 2
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -295,6 +295,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/f0/8b/2c95f0645c6f40211896375e6fa51f504b8ccb29c21f6ae661fe87ab044e/cyclopts-3.24.0-py3-none-any.whl", hash = "sha256:809d04cde9108617106091140c3964ee6fceb33cecdd537f7ffa360bde13ed71", size = 86154, upload-time = "2025-09-08T15:40:56.41Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/8b/2c95f0645c6f40211896375e6fa51f504b8ccb29c21f6ae661fe87ab044e/cyclopts-3.24.0-py3-none-any.whl", hash = "sha256:809d04cde9108617106091140c3964ee6fceb33cecdd537f7ffa360bde13ed71", size = 86154, upload-time = "2025-09-08T15:40:56.41Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "distro"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dnspython"
|
name = "dnspython"
|
||||||
version = "2.8.0"
|
version = "2.8.0"
|
||||||
@@ -625,6 +634,42 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl", hash = "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", size = 22320, upload-time = "2024-10-08T23:04:09.501Z" },
|
{ url = "https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl", hash = "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", size = 22320, upload-time = "2024-10-08T23:04:09.501Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jiter"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/9d/c0/a3bb4cc13aced219dd18191ea66e874266bd8aa7b96744e495e1c733aa2d/jiter-0.11.0.tar.gz", hash = "sha256:1d9637eaf8c1d6a63d6562f2a6e5ab3af946c66037eb1b894e8fad75422266e4", size = 167094, upload-time = "2025-09-15T09:20:38.212Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/97/c4/d530e514d0f4f29b2b68145e7b389cbc7cac7f9c8c23df43b04d3d10fa3e/jiter-0.11.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:4441a91b80a80249f9a6452c14b2c24708f139f64de959943dfeaa6cb915e8eb", size = 305021, upload-time = "2025-09-15T09:19:43.523Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7a/77/796a19c567c5734cbfc736a6f987affc0d5f240af8e12063c0fb93990ffa/jiter-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ff85fc6d2a431251ad82dbd1ea953affb5a60376b62e7d6809c5cd058bb39471", size = 314384, upload-time = "2025-09-15T09:19:44.849Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/14/9c/824334de0b037b91b6f3fa9fe5a191c83977c7ec4abe17795d3cb6d174cf/jiter-0.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5e86126d64706fd28dfc46f910d496923c6f95b395138c02d0e252947f452bd", size = 337389, upload-time = "2025-09-15T09:19:46.094Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a2/95/ed4feab69e6cf9b2176ea29d4ef9d01a01db210a3a2c8a31a44ecdc68c38/jiter-0.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad8bd82165961867a10f52010590ce0b7a8c53da5ddd8bbb62fef68c181b921", size = 360519, upload-time = "2025-09-15T09:19:47.494Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/0c/2ad00f38d3e583caba3909d95b7da1c3a7cd82c0aa81ff4317a8016fb581/jiter-0.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b42c2cd74273455ce439fd9528db0c6e84b5623cb74572305bdd9f2f2961d3df", size = 487198, upload-time = "2025-09-15T09:19:49.116Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ea/8b/919b64cf3499b79bdfba6036da7b0cac5d62d5c75a28fb45bad7819e22f0/jiter-0.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0062dab98172dd0599fcdbf90214d0dcde070b1ff38a00cc1b90e111f071982", size = 377835, upload-time = "2025-09-15T09:19:50.468Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/29/7f/8ebe15b6e0a8026b0d286c083b553779b4dd63db35b43a3f171b544de91d/jiter-0.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb948402821bc76d1f6ef0f9e19b816f9b09f8577844ba7140f0b6afe994bc64", size = 347655, upload-time = "2025-09-15T09:19:51.726Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8e/64/332127cef7e94ac75719dda07b9a472af6158ba819088d87f17f3226a769/jiter-0.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25a5b1110cca7329fd0daf5060faa1234be5c11e988948e4f1a1923b6a457fe1", size = 386135, upload-time = "2025-09-15T09:19:53.075Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/20/c8/557b63527442f84c14774159948262a9d4fabb0d61166f11568f22fc60d2/jiter-0.11.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:bf11807e802a214daf6c485037778843fadd3e2ec29377ae17e0706ec1a25758", size = 516063, upload-time = "2025-09-15T09:19:54.447Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/86/13/4164c819df4a43cdc8047f9a42880f0ceef5afeb22e8b9675c0528ebdccd/jiter-0.11.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbb57da40631c267861dd0090461222060960012d70fd6e4c799b0f62d0ba166", size = 508139, upload-time = "2025-09-15T09:19:55.764Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fa/70/6e06929b401b331d41ddb4afb9f91cd1168218e3371972f0afa51c9f3c31/jiter-0.11.0-cp313-cp313-win32.whl", hash = "sha256:8e36924dad32c48d3c5e188d169e71dc6e84d6cb8dedefea089de5739d1d2f80", size = 206369, upload-time = "2025-09-15T09:19:57.048Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f4/0d/8185b8e15de6dce24f6afae63380e16377dd75686d56007baa4f29723ea1/jiter-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:452d13e4fd59698408087235259cebe67d9d49173b4dacb3e8d35ce4acf385d6", size = 202538, upload-time = "2025-09-15T09:19:58.35Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/13/3a/d61707803260d59520721fa326babfae25e9573a88d8b7b9cb54c5423a59/jiter-0.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:089f9df9f69532d1339e83142438668f52c97cd22ee2d1195551c2b1a9e6cf33", size = 313737, upload-time = "2025-09-15T09:19:59.638Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cd/cc/c9f0eec5d00f2a1da89f6bdfac12b8afdf8d5ad974184863c75060026457/jiter-0.11.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ed1fe69a8c69bf0f2a962d8d706c7b89b50f1332cd6b9fbda014f60bd03a03", size = 346183, upload-time = "2025-09-15T09:20:01.442Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a6/87/fc632776344e7aabbab05a95a0075476f418c5d29ab0f2eec672b7a1f0ac/jiter-0.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a4d71d7ea6ea8786291423fe209acf6f8d398a0759d03e7f24094acb8ab686ba", size = 204225, upload-time = "2025-09-15T09:20:03.102Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ee/3b/e7f45be7d3969bdf2e3cd4b816a7a1d272507cd0edd2d6dc4b07514f2d9a/jiter-0.11.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:9a6dff27eca70930bdbe4cbb7c1a4ba8526e13b63dc808c0670083d2d51a4a72", size = 304414, upload-time = "2025-09-15T09:20:04.357Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/06/32/13e8e0d152631fcc1907ceb4943711471be70496d14888ec6e92034e2caf/jiter-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ae2a7593a62132c7d4c2abbee80bbbb94fdc6d157e2c6cc966250c564ef774", size = 314223, upload-time = "2025-09-15T09:20:05.631Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0c/7e/abedd5b5a20ca083f778d96bba0d2366567fcecb0e6e34ff42640d5d7a18/jiter-0.11.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b13a431dba4b059e9e43019d3022346d009baf5066c24dcdea321a303cde9f0", size = 337306, upload-time = "2025-09-15T09:20:06.917Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ac/e2/30d59bdc1204c86aa975ec72c48c482fee6633120ee9c3ab755e4dfefea8/jiter-0.11.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:af62e84ca3889604ebb645df3b0a3f3bcf6b92babbff642bd214616f57abb93a", size = 360565, upload-time = "2025-09-15T09:20:08.283Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fe/88/567288e0d2ed9fa8f7a3b425fdaf2cb82b998633c24fe0d98f5417321aa8/jiter-0.11.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6f3b32bb723246e6b351aecace52aba78adb8eeb4b2391630322dc30ff6c773", size = 486465, upload-time = "2025-09-15T09:20:09.613Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/18/6e/7b72d09273214cadd15970e91dd5ed9634bee605176107db21e1e4205eb1/jiter-0.11.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:adcab442f4a099a358a7f562eaa54ed6456fb866e922c6545a717be51dbed7d7", size = 377581, upload-time = "2025-09-15T09:20:10.884Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/58/52/4db456319f9d14deed325f70102577492e9d7e87cf7097bda9769a1fcacb/jiter-0.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9967c2ab338ee2b2c0102fd379ec2693c496abf71ffd47e4d791d1f593b68e2", size = 347102, upload-time = "2025-09-15T09:20:12.175Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ce/b4/433d5703c38b26083aec7a733eb5be96f9c6085d0e270a87ca6482cbf049/jiter-0.11.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e7d0bed3b187af8b47a981d9742ddfc1d9b252a7235471ad6078e7e4e5fe75c2", size = 386477, upload-time = "2025-09-15T09:20:13.428Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c8/7a/a60bfd9c55b55b07c5c441c5085f06420b6d493ce9db28d069cc5b45d9f3/jiter-0.11.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:f6fe0283e903ebc55f1a6cc569b8c1f3bf4abd026fed85e3ff8598a9e6f982f0", size = 516004, upload-time = "2025-09-15T09:20:14.848Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2e/46/f8363e5ecc179b4ed0ca6cb0a6d3bfc266078578c71ff30642ea2ce2f203/jiter-0.11.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5821e3d66606b29ae5b497230b304f1376f38137d69e35f8d2bd5f310ff73", size = 507855, upload-time = "2025-09-15T09:20:16.176Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/90/33/396083357d51d7ff0f9805852c288af47480d30dd31d8abc74909b020761/jiter-0.11.0-cp314-cp314-win32.whl", hash = "sha256:c2d13ba7567ca8799f17c76ed56b1d49be30df996eb7fa33e46b62800562a5e2", size = 205802, upload-time = "2025-09-15T09:20:17.661Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e7/ab/eb06ca556b2551d41de7d03bf2ee24285fa3d0c58c5f8d95c64c9c3281b1/jiter-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fb4790497369d134a07fc763cc88888c46f734abdd66f9fdf7865038bf3a8f40", size = 313405, upload-time = "2025-09-15T09:20:18.918Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/af/22/7ab7b4ec3a1c1f03aef376af11d23b05abcca3fb31fbca1e7557053b1ba2/jiter-0.11.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e2bbf24f16ba5ad4441a9845e40e4ea0cb9eed00e76ba94050664ef53ef4406", size = 347102, upload-time = "2025-09-15T09:20:20.16Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonschema"
|
name = "jsonschema"
|
||||||
version = "4.25.1"
|
version = "4.25.1"
|
||||||
@@ -933,6 +978,25 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/eb/59/0db51308fa479f9325ade08c343a5164153ad01dbb83b62ff661e1129d2e/onnxruntime-1.23.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ed85686e08cfb29ee96365b9a49e8a350aff7557c13d63d9f07ca3ad68975074", size = 17281939, upload-time = "2025-09-25T19:16:16.16Z" },
|
{ url = "https://files.pythonhosted.org/packages/eb/59/0db51308fa479f9325ade08c343a5164153ad01dbb83b62ff661e1129d2e/onnxruntime-1.23.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ed85686e08cfb29ee96365b9a49e8a350aff7557c13d63d9f07ca3ad68975074", size = 17281939, upload-time = "2025-09-25T19:16:16.16Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openai"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "anyio" },
|
||||||
|
{ name = "distro" },
|
||||||
|
{ name = "httpx" },
|
||||||
|
{ name = "jiter" },
|
||||||
|
{ name = "pydantic" },
|
||||||
|
{ name = "sniffio" },
|
||||||
|
{ name = "tqdm" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/d8/5d/74fa2b0358ef15d113b1a6ca2323cee0034020b085a81a94eeddc6914de9/openai-2.0.0.tar.gz", hash = "sha256:6b9513b485f856b0be6bc44c518831acb58e37a12bed72fcc52b1177d1fb34a8", size = 565732, upload-time = "2025-09-30T17:35:57.632Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/69/41/86ddc9cdd885acc02ee50ec24ea1c5e324eea0c7a471ee841a7088653558/openai-2.0.0-py3-none-any.whl", hash = "sha256:a79f493651f9843a6c54789a83f3b2db56df0e1770f7dcbe98bcf0e967ee2148", size = 955538, upload-time = "2025-09-30T17:35:54.695Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openapi-core"
|
name = "openapi-core"
|
||||||
version = "0.19.5"
|
version = "0.19.5"
|
||||||
@@ -1530,6 +1594,7 @@ name = "searchbox"
|
|||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
{ name = "openai" },
|
||||||
{ name = "qdrant-client" },
|
{ name = "qdrant-client" },
|
||||||
{ name = "vault-settings" },
|
{ name = "vault-settings" },
|
||||||
]
|
]
|
||||||
@@ -1552,6 +1617,7 @@ dev = [
|
|||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "fastmcp", marker = "extra == 'mcp'", specifier = ">=2.12.4" },
|
{ name = "fastmcp", marker = "extra == 'mcp'", specifier = ">=2.12.4" },
|
||||||
|
{ name = "openai", specifier = ">=2.0.0" },
|
||||||
{ name = "qdrant-client", specifier = "==1.13" },
|
{ name = "qdrant-client", specifier = "==1.13" },
|
||||||
{ name = "vault-settings", specifier = ">=0.1.0" },
|
{ name = "vault-settings", specifier = ">=0.1.0" },
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user