From 19ee304a25060689ddce1b9d475a9b2e987b6bd1 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sun, 9 Aug 2026 14:32:39 +0200 Subject: fix: skip unusable provider names, name the split ceiling A provider name containing a colon builds ids that split back to a different provider, and an empty name builds ':model'; both routed to the local router under a nonsense name with no error, so parse() now skips them. split() stays non-injective by design, since bare local ids are the premise here, so the residual risk is recorded as a ponytail comment with its upgrade path rather than hidden. Also pin the trailing-colon form Task 9 relies on, and the empty-needle filter, which were correct but untested. Co-Authored-By: Claude Opus 5 --- test_llamachat.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'test_llamachat.py') diff --git a/test_llamachat.py b/test_llamachat.py index 5f6bad6..8b722ae 100755 --- a/test_llamachat.py +++ b/test_llamachat.py @@ -987,7 +987,18 @@ def test_provider_parsing(): "filter": {"a": 1}}}} ) assert odd["n"].filter == ["5"] - assert odd["d"].filter == ["{'a': 1}"] + # The invariant is that the dict was wrapped whole, not iterated into its + # keys. Asserting that rather than its repr, which is not ours to pin. + assert odd["d"].filter != ["a"] and len(odd["d"].filter) == 1 + + # A colon in a provider name would make every id built from it ambiguous, + # so such a provider is skipped rather than silently routed to local. + colonic = providers.parse( + {"providers": {"local": {"base_url": "http://x.example.org"}, + "a:b": {"base_url": "http://y.example.org"}, + "": {"base_url": "http://z.example.org"}}} + ) + assert set(colonic) == {"local"} print("ok provider config parsing") @@ -1023,6 +1034,8 @@ def test_model_ids_and_filtering(): assert providers.split("weird:name", table) == ("local", "weird:name") # Only the first colon splits. assert providers.split("together:a:b", table) == ("together", "a:b") + # Task 9 addresses a provider itself with an empty model name. + assert providers.split("together:", table) == ("together", "") # Filtering is case-insensitive substring, any match wins. listed = [ @@ -1044,6 +1057,10 @@ def test_model_ids_and_filtering(): # A filter matching nothing yields nothing, it does not fall back to all. table["together"].filter = ["zzz"] assert providers.apply_filter(table["together"], listed) == [] + # An empty needle is a typo rather than a request to hide everything, so + # it means no filter. The opposite of the "zzz" case above, deliberately. + table["together"].filter = [""] + assert providers.apply_filter(table["together"], listed) == listed print("ok model ids and filtering") -- cgit v1.2.3