Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
128 commits
Select commit Hold shift + click to select a range
9a1c325
Add provider API inference smoke-test harness
sfloess Nov 1, 2026
2561a5e
Add provider catalogue inventory utility
sfloess Nov 1, 2026
02da0ee
Document provider API research utilities
sfloess Nov 1, 2026
edda044
Ignore local provider API research outputs
sfloess Nov 1, 2026
c853eb9
Require positive metadata for chat candidate classification
sfloess Nov 1, 2026
026275a
Classify incomplete reasoning responses in provider smoke tests
sfloess Nov 1, 2026
f8bfb27
Filter task-specific models from chat candidate shortlist
sfloess Nov 1, 2026
4984968
Document normalized reasoning evidence and smoke budget
sfloess Nov 1, 2026
70db050
Add exact model selection to provider smoke tests
sfloess Nov 1, 2026
8bf881c
Correct truncated response classification and retain smoke evidence
sfloess Nov 1, 2026
6540bf1
Extract response classification for deterministic tests
sfloess Nov 1, 2026
a9526a8
Restore normalized usage fields before classification
sfloess Nov 1, 2026
e4b89a4
Add deterministic smoke response classification tests
sfloess Nov 1, 2026
6f0efdd
Document corrected classification and append-only evidence
sfloess Nov 1, 2026
631d12d
Identify provider smoke-test HTTP client explicitly
sfloess Nov 1, 2026
ea66724
Test explicit provider HTTP client headers
sfloess Nov 1, 2026
86e45f4
Add DeepInfra representative inference candidate
sfloess Nov 1, 2026
81b6303
Test DeepInfra endpoint configuration
sfloess Nov 1, 2026
30bff47
Document DeepInfra smoke-test candidate
sfloess Nov 1, 2026
9616530
Add NVIDIA NIM representative inference candidate
sfloess Nov 1, 2026
123aab9
Test NVIDIA NIM endpoint configuration
sfloess Nov 1, 2026
2492ee1
Document NVIDIA NIM smoke-test candidate
sfloess Nov 1, 2026
77e37d2
Add Hugging Face Inference Providers smoke candidate
sfloess Nov 1, 2026
9f8d6b7
Add safe all-configured provider batch mode
sfloess Nov 1, 2026
c394bf6
Extract representative provider selection
sfloess Nov 1, 2026
f3453cc
Test all-configured batch selection
sfloess Nov 1, 2026
3da4fb8
Document all-configured provider batch mode
sfloess Nov 1, 2026
eec6644
Add Mistral and Cohere smoke tests; refresh Gemini candidate
sfloess Nov 1, 2026
bdede87
Test refreshed free-tier candidates and deprecated NVIDIA endpoint
sfloess Nov 1, 2026
4d9b0f9
Remove obsolete Gemini 2.5 smoke candidate
sfloess Nov 1, 2026
f6357e8
Document new free-tier providers and deprecated NVIDIA endpoint
sfloess Nov 1, 2026
4c632d2
Improve provider 402 diagnostics
sfloess Nov 1, 2026
a82fe7e
Test provider billing error classification
sfloess Nov 1, 2026
a9cf7e4
Document sanitized provider error diagnostics
sfloess Nov 1, 2026
e1127b1
Add read-only provider error inspection and free DeepSeek routes
sfloess Nov 1, 2026
01b854b
Cover free DeepSeek provider routes
sfloess Nov 1, 2026
4506920
Document no-cost DeepSeek routes and error inspection
sfloess Nov 1, 2026
aaee23d
Support conventional provider credential environment variables
sfloess Nov 1, 2026
5f4125c
Test provider credential aliases and precedence
sfloess Nov 1, 2026
cb07e3d
Document provider credential environment aliases
sfloess Nov 1, 2026
de573cb
Support conventional credentials in catalogue inventory
sfloess Nov 1, 2026
7f6dd92
Clarify credential fallback behavior in provider research docs
sfloess Nov 1, 2026
11d3231
Add read-only credential source diagnostics
sfloess Nov 1, 2026
155064e
Document read-only credential source diagnostic
sfloess Nov 1, 2026
d249322
Plan and report every configured provider in batch runs
sfloess Nov 1, 2026
6034cb8
Test complete all-provider batch planning
sfloess Nov 1, 2026
303b5e3
Document complete all-provider evaluation behavior
sfloess Nov 1, 2026
ef17a65
Clarify provider credential lookup documentation
sfloess Nov 1, 2026
454199d
Discover additional provider credentials from the environment
sfloess Nov 1, 2026
fb1ad2c
Test discovery of unlisted provider API credentials
sfloess Nov 1, 2026
b30b364
Add Anthropic to credentialed catalogue inventory
sfloess Nov 1, 2026
e71e986
Report unsupported discovered providers in batch summary
sfloess Nov 1, 2026
b44e3a0
Document dynamic provider credential discovery
sfloess Nov 1, 2026
21046d8
Discover and test account-scoped provider credentials
sfloess Nov 1, 2026
f826362
Test separate provider account credential discovery
sfloess Nov 1, 2026
0643fa8
Document provider account-scoped credential handling
sfloess Nov 1, 2026
a81b0d3
Normalize Think Machines account credential aliases
sfloess Nov 1, 2026
24b14e1
Test Think Machines credential namespace alias
sfloess Nov 1, 2026
4f8cb13
Raise default smoke-test output budget to 512 tokens
sfloess Nov 1, 2026
f8232be
Test the default smoke-test output budget
sfloess Nov 1, 2026
e8305de
Centralize the default output token budget
sfloess Nov 1, 2026
5405342
Fix output-budget regression test to use constant
sfloess Nov 1, 2026
6d772b6
Fix account identity in direct provider runs
sfloess Nov 1, 2026
47a13e7
Test account identity in direct provider runs
sfloess Nov 1, 2026
b57867b
Add explicit OpenRouter free model account matrix
sfloess Nov 1, 2026
f008e49
Test OpenRouter free model matrix selection
sfloess Nov 1, 2026
952dd93
Classify provider rate limits and sanitize errors
sfloess Nov 1, 2026
da620f5
Test rate-limit classification and error sanitization
sfloess Nov 1, 2026
ad5324e
Document rate-limit diagnostics and error sanitization
sfloess Nov 1, 2026
763bf63
Fix sanitizer regression test imports and assertions
sfloess Nov 1, 2026
7af45df
Harden provider error metadata parsing
sfloess Nov 1, 2026
bf815d4
Classify agentic-only OpenRouter model restrictions
sfloess Nov 1, 2026
a49be29
Test agentic harness restriction classification
sfloess Nov 1, 2026
126de58
Document agentic-harness-only error classification
sfloess Nov 1, 2026
c30a412
Add provider capability and adapter catalogue
sfloess Nov 1, 2026
d3bfe37
Add unified inventory capability planning and evidence reporting
sfloess Nov 1, 2026
0624d46
Fix evidence report grouping and JSONL line endings
sfloess Nov 1, 2026
5b2eade
Test unified provider inventory capability planning and reports
sfloess Nov 1, 2026
c5d2265
Correct evidence fixture JSONL separators
sfloess Nov 1, 2026
98cfc30
Harden unified runner option validation
sfloess Nov 1, 2026
2614505
Document unified provider runner inventory and capabilities
sfloess Nov 1, 2026
c8c3706
Normalize capability planning evidence metadata
sfloess Nov 1, 2026
43c8cba
Implement provider-native embedding adapters and execution
sfloess Nov 1, 2026
7eb3b38
Register Voyage Jina and native embedding adapters
sfloess Nov 1, 2026
3abb29f
Enable explicit embedding execution and safe planning mode
sfloess Nov 1, 2026
165580e
Test embedding adapters response validation and paid opt-in
sfloess Nov 1, 2026
2c64215
Show capability-only providers as adapter available
sfloess Nov 1, 2026
1e65e7d
Account for Google model in embedding URL
sfloess Nov 1, 2026
4792ea7
Report embedding-only adapters in inventory and plans
sfloess Nov 1, 2026
708837b
Document native embedding adapters and explicit execution
sfloess Nov 1, 2026
dfd26f9
Expose per-capability endpoints and guard unsupported capability exec…
sfloess Nov 1, 2026
2330770
Test embedding-only provider inventory and capability plans
sfloess Nov 1, 2026
64e33dc
Use current Gemini embedContent config field
sfloess Nov 1, 2026
59127b8
Assert Gemini retrieval task config uses current API field
sfloess Nov 1, 2026
c50f945
Link to current Mistral embeddings API reference
sfloess Nov 1, 2026
52778e8
Recognize Voyage AI credential names and SDK alias
sfloess Nov 1, 2026
968e4aa
Test canonical Voyage AI credential discovery
sfloess Nov 1, 2026
1ba6eec
Include Voyage AI in all-provider credential planning fixture
sfloess Nov 1, 2026
a0df67b
Require explicit opt-in for Jina embedding account credits
sfloess Nov 1, 2026
89317de
Test Jina account-credit candidate requires explicit opt-in
sfloess Nov 1, 2026
602dac7
Document Jina balance findings and require opt-in for retest
sfloess Nov 1, 2026
be4b654
Classify Jina 403 insufficient balance as billing limitation
sfloess Nov 1, 2026
6c68c16
Test Jina 403 insufficient-balance classification
sfloess Nov 1, 2026
b2a6049
Add fixed semantic retrieval benchmark dataset
sfloess Nov 1, 2026
048a664
Add semantic retrieval benchmark runner
sfloess Nov 1, 2026
72285d2
Test semantic embedding retrieval benchmark
sfloess Nov 1, 2026
5bad962
Support package and direct-script imports in embedding benchmark
sfloess Nov 1, 2026
eff9e88
Correct reciprocal-rank regression fixture
sfloess Nov 1, 2026
298003e
Document semantic retrieval benchmark workflow
sfloess Nov 1, 2026
04d223f
Support local corpus datasets and bounded embedding batches
sfloess Nov 1, 2026
60b53a9
Test external benchmark datasets and bounded batching
sfloess Nov 1, 2026
283271d
Document real corpus benchmark dataset input
sfloess Nov 1, 2026
91a7b4e
Add local private kbase corpus exporter
sfloess Nov 1, 2026
d582027
Support separate reviewed query and relevance files
sfloess Nov 1, 2026
64e4f19
Document local kbase export and reviewed query workflow
sfloess Nov 1, 2026
d89e273
Fix Markdown title parsing in kbase exporter
sfloess Nov 1, 2026
746f7ce
Write valid newline-terminated corpus JSON
sfloess Nov 1, 2026
a31c3f9
Align benchmark examples with separate kbase judgments
sfloess Nov 1, 2026
0909099
Format kbase exporter and annotate loader
sfloess Nov 1, 2026
3c0f3bd
Fix canonical chunking checkout path resolution
sfloess Nov 1, 2026
9d15209
Make corpus exporter independent of FlossWare chunking repo
sfloess Nov 1, 2026
5385ca1
Test standalone corpus export baseline
sfloess Nov 1, 2026
bf079dd
Fix and verify exporter baseline tests
sfloess Nov 1, 2026
114a9f9
Clarify evaluation as independent Ensemble research
sfloess Nov 1, 2026
8aad03b
Document Evaluation to Ensemble research progression
sfloess Nov 1, 2026
8a67b8e
Remove private corpus and kbase workflow from evaluation research docs
sfloess Nov 1, 2026
faf59d4
Remove unnecessary private corpus exporter
sfloess Nov 1, 2026
5ef5c13
Remove tests for deleted private corpus exporter
sfloess Nov 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ env/
.coverage
htmlcov/

# Provider API research outputs (local evidence, never commit by default)
provider-model-catalogue.json
provider-smoke-results*.jsonl

# OS
.DS_Store
Thumbs.db
135 changes: 135 additions & 0 deletions README.md

Large diffs are not rendered by default.

169 changes: 169 additions & 0 deletions tests/test_embedding_benchmark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
"""Tests for the deterministic embedding retrieval benchmark."""
from __future__ import annotations

import json
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

from tools.provider_api.embedding_benchmark import (
embed_in_batches,
embedding_batch_spec,
extract_batch_vectors,
load_dataset,
ranking_metrics,
select_account,
)


class EmbeddingBenchmarkTests(unittest.TestCase):
def test_dataset_has_valid_gold_relevance(self):
dataset = load_dataset()
doc_ids = {item["id"] for item in dataset["documents"]}
self.assertEqual(len(doc_ids), len(dataset["documents"]))
self.assertEqual(len(dataset["queries"]), 8)
self.assertTrue(all(set(item["relevant"]) <= doc_ids for item in dataset["queries"]))

def test_dataset_rejects_unknown_relevance_id(self):
bad = {
"version": 1,
"documents": [{"id": "d1", "text": "doc"}],
"queries": [{"id": "q1", "text": "query", "relevant": ["missing"]}],
}
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "bad.json"
path.write_text(json.dumps(bad), encoding="utf-8")
with self.assertRaises(ValueError):
load_dataset(path)

def test_external_dataset_metadata_and_validation(self):
data = {
"name": "flossware-corpus-v1",
"source": "postgresql-export",
"version": 1,
"documents": [{"id": "chunk-1", "text": "A representative chunk."}],
"queries": [{"id": "query-1", "text": "Find a representative chunk.", "relevant": ["chunk-1"]}],
}
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "external.json"
path.write_text(json.dumps(data), encoding="utf-8")
loaded = load_dataset(path)
self.assertEqual(loaded["name"], "flossware-corpus-v1")
self.assertEqual(loaded["source"], "postgresql-export")

def test_dataset_rejects_empty_text_and_duplicate_query_ids(self):
bad_datasets = [
{
"documents": [{"id": "d1", "text": "doc"}],
"queries": [{"id": "q1", "text": " ", "relevant": ["d1"]}],
},
{
"documents": [{"id": "d1", "text": "doc"}],
"queries": [
{"id": "q1", "text": "query one", "relevant": ["d1"]},
{"id": "q1", "text": "query two", "relevant": ["d1"]},
],
},
]
with tempfile.TemporaryDirectory() as directory:
for index, data in enumerate(bad_datasets):
path = Path(directory) / f"bad-{index}.json"
path.write_text(json.dumps(data), encoding="utf-8")
with self.assertRaises(ValueError):
load_dataset(path)

def test_embedding_batches_preserve_order_and_aggregate_metadata(self):
with patch(
"tools.provider_api.embedding_benchmark.post_embeddings",
side_effect=[
([[1.0, 0.0], [0.0, 1.0]], {"latency_seconds": 0.2, "http_status": 200}),
([[-1.0, 0.0]], {"latency_seconds": 0.3, "http_status": 200}),
],
) as request:
vectors, metadata = embed_in_batches(
"COHERE", "embed-v4.0", "secret", ["one", "two", "three"],
"document", 10.0, 2,
)
self.assertEqual(vectors, [[1.0, 0.0], [0.0, 1.0], [-1.0, 0.0]])
self.assertEqual(metadata["request_count"], 2)
self.assertEqual(metadata["latency_seconds"], 0.5)
self.assertEqual(request.call_count, 2)

def test_provider_native_document_and_query_modes(self):
url, payload = embedding_batch_spec(
"COHERE", "embed-v4.0", ["text"], "document"
)
self.assertEqual(url, "https://api.cohere.com/v2/embed")
self.assertEqual(payload["input_type"], "search_document")
_, payload = embedding_batch_spec("COHERE", "embed-v4.0", ["text"], "query")
self.assertEqual(payload["input_type"], "search_query")

url, payload = embedding_batch_spec(
"GOOGLE", "models/gemini-embedding-001", ["text"], "query"
)
self.assertTrue(url.endswith(":batchEmbedContents"))
self.assertEqual(payload["requests"][0]["taskType"], "RETRIEVAL_QUERY")

_, payload = embedding_batch_spec(
"JINA", "jina-embeddings-v3", ["text"], "query"
)
self.assertEqual(payload["task"], "retrieval.query")

def test_batch_response_envelopes(self):
self.assertEqual(
extract_batch_vectors("GOOGLE", {"embeddings": [{"values": [1, 0]}]}),
[[1.0, 0.0]],
)
self.assertEqual(
extract_batch_vectors("COHERE", {"embeddings": {"float": [[1, 0]]}}),
[[1.0, 0.0]],
)
self.assertEqual(
extract_batch_vectors("OPENAI", {"data": [{"embedding": [1, 0]}]}),
[[1.0, 0.0]],
)

def test_batch_response_rejects_non_finite_or_inconsistent_vectors(self):
with self.assertRaises(ValueError):
extract_batch_vectors("OPENAI", {"data": [{"embedding": [1, float("nan")]}]})
with self.assertRaises(ValueError):
extract_batch_vectors("OPENAI", {
"data": [{"embedding": [1, 0]}, {"embedding": [1]}]
})

def test_metrics_for_perfect_retrieval(self):
docs = [[1, 0], [0, 1], [-1, 0]]
queries = [[1, 0]]
relevance = [{"id": "q1", "relevant": ["d1"]}]
metrics = ranking_metrics(queries, docs, ["d1", "d2", "d3"], relevance, k=2)
self.assertEqual(metrics["recall_at_2"], 1.0)
self.assertEqual(metrics["mrr_at_2"], 1.0)
self.assertEqual(metrics["ndcg_at_2"], 1.0)
self.assertEqual(metrics["per_query"][0]["top_document_ids"][0], "d1")

def test_metrics_penalize_lower_rank_and_missing_relevant_docs(self):
docs = [[0, 1], [1, 0], [-1, 0]]
queries = [[1, 0]]
relevance = [{"id": "q1", "relevant": ["d1"]}]
metrics = ranking_metrics(queries, docs, ["d1", "d2", "d3"], relevance, k=2)
self.assertLess(metrics["mrr_at_2"], 1.0)
self.assertEqual(metrics["recall_at_2"], 1.0)

def test_metrics_reject_dimension_mismatch(self):
with self.assertRaises(ValueError):
ranking_metrics([[1, 0]], [[1, 0, 0]], ["d1"], [{"id": "q", "relevant": ["d1"]}])

def test_default_account_selection_is_single_preferred_account(self):
with patch.dict("os.environ", {
"COHERE_API_KEY_HOTMAIL": "hotmail-secret",
"COHERE_API_KEY_FLOSSWARE": "flossware-secret",
}, clear=True):
accounts = select_account("COHERE")
self.assertEqual(len(accounts), 1)
self.assertEqual(accounts[0]["account"], "FLOSSWARE")
self.assertEqual(accounts[0]["credential"], "flossware-secret")


if __name__ == "__main__":
unittest.main()
Loading
Loading