qmd_py.llm.client¶
Pure HTTP client for the LLM router — embeddings, chat completions (query expansion), and reranking. No local model loading; see Architecture › LLM client.
client ¶
Pure HTTP client for the llama.cpp router (MARQ_LLM_BASE_URL) - no local
model loading concept at all, unlike the TS reference's node-llama-cpp
based src/llm.ts. Prompt formatting is ported from that file's
formatQueryForEmbedding/formatDocForEmbedding/isQwen3EmbeddingModel
since those templates must match exactly for embeddings to be comparable
to the TS reference's.
LlmClient ¶
Thin wrapper over the router's OpenAI-compatible /v1/embeddings,
/v1/chat/completions, /rerank, /tokenize, and /detokenize
endpoints.
transport is httpx's standard injection seam, used by the
tests to serve canned router responses through an
httpx.MockTransport without a live router. Production callers
leave it None and get httpx's real networking.
Source code in src/qmd_py/llm/client.py
list_models
async
¶
Model ids the router currently has presets for - backs doctor's
check that the configured embed/generate/rerank models actually
exist on the router, not just in qmd-py's own settings.
Source code in src/qmd_py/llm/client.py
embed
async
¶
Embed a batch of texts in one request.
Returns:
-
list[list[float]]–Vectors positionally matching
texts. The router keys its -
list[list[float]]–response by
indexrather than guaranteeing order, so the -
list[list[float]]–results are re-sorted here - without that, every chunk in a
-
list[list[float]]–batch could get another chunk's vector.
Raises:
-
HTTPStatusError–The router returned an error status.
-
KeyError–The response had no
dataarray.
Source code in src/qmd_py/llm/client.py
chat_json
async
¶
chat_json(
messages: list[dict[str, str]],
model: str,
json_schema: dict[str, Any],
max_tokens: int = 300,
temperature: float = 0.7,
) -> dict[str, Any]
One chat completion constrained to json_schema via the
router's response_format (an OpenAI-compatible, increasingly
standard llama.cpp server feature) - returns the parsed JSON
object. Used for query expansion (see search/hybrid.py).
Source code in src/qmd_py/llm/client.py
rerank
async
¶
Relevance scores in the same order as documents - the
router's response is keyed by index rather than guaranteed to
preserve input order, so results are re-sorted into place here.
Always returns one score per document (unscored ones stay 0.0);
callers rely on that length, hybrid.py zipping it against its
candidate chunks with strict=True. Out-of-range indices are
dropped rather than assigned: a stray large index would raise
IndexError, and - worse, because it fails silently - a negative
one would write onto the wrong document from the end.
Source code in src/qmd_py/llm/client.py
tokenize
async
¶
Count tokens using the model's own tokenizer.
Used to fit text to the reranker's per-pair budget, where a chars-per-token estimate proved unsafe for dense code.
Returns:
-
list[int]–Token ids; callers generally only need the length.
Raises:
-
HTTPStatusError–The router returned an error status.
Source code in src/qmd_py/llm/client.py
aclose
async
¶
Close the underlying HTTP connection pool.
Prefer the async context manager. Once closed the client cannot
be reused - further calls raise RuntimeError.
is_qwen3_embedding_model ¶
Whether a model slug names a Qwen3 embedding model.
Decides which prompt template the embedding helpers apply. Matched on the slug alone, since the router exposes no model metadata - so a model whose name doesn't say "qwen" and "embed" gets the default template even if it is one.
Source code in src/qmd_py/llm/client.py
format_query_for_embedding ¶
nomic-style task-prefix format (default) vs. Qwen3-Embedding's instruct format - the two embedding-prompt styles the TS reference supports.
Source code in src/qmd_py/llm/client.py
format_doc_for_embedding ¶
Wrap a document chunk in the model's expected document template.
Must match format_query_for_embedding()'s counterpart for the same
model: asymmetric embedding models are trained on a specific query
and document framing, and mixing templates degrades similarity
silently rather than failing.