aboutsummaryrefslogtreecommitdiffstats
path: root/llamachat/providers.py
diff options
context:
space:
mode:
Diffstat (limited to 'llamachat/providers.py')
-rw-r--r--llamachat/providers.py40
1 files changed, 38 insertions, 2 deletions
diff --git a/llamachat/providers.py b/llamachat/providers.py
index d955436..5874b32 100644
--- a/llamachat/providers.py
+++ b/llamachat/providers.py
@@ -83,9 +83,12 @@ def parse(values: dict) -> dict[str, Provider]:
continue
# filter = "qwen" is an easy TOML slip for filter = ["qwen"], and
# iterating the string would turn it into four single-character
- # needles that match nearly every model id.
+ # needles that match nearly every model id. The same goes for every
+ # other non-sequence shape: a number would raise on iteration and a
+ # dict would quietly degrade into its keys, so wrap anything that is
+ # not a list as a single needle and let it simply match nothing.
needles = entry.get("filter") or []
- if isinstance(needles, str):
+ if not isinstance(needles, (list, tuple)):
needles = [needles]
vision = entry.get("vision")
out[str(name)] = Provider(
@@ -99,3 +102,36 @@ def parse(values: dict) -> dict[str, Provider]:
price_out=_number(entry.get("price_out"), float),
)
return out
+
+
+def qualify(provider: str, model: str) -> str:
+ """The stored, displayed id for one model. Local models stay bare."""
+ if provider == LOCAL:
+ return model
+ return f"{provider}:{model}"
+
+
+def split(model_id: str, table: dict[str, Provider]) -> tuple[str, str]:
+ """Inverse of qualify, resolved against the configured providers.
+
+ A prefix that is not a configured provider is treated as part of the
+ model name, which keeps a bare local model containing a colon working.
+ """
+ prefix, sep, rest = model_id.partition(":")
+ if sep and prefix in table and prefix != LOCAL:
+ return prefix, rest
+ return LOCAL, model_id
+
+
+def apply_filter(provider: Provider, listed: list[str]) -> list[str]:
+ """Keep models matching any of the provider's substrings.
+
+ Case-insensitive, because provider ids capitalise inconsistently:
+ "qwen" has to match "Qwen/Qwen2.5-72B-Instruct-Turbo".
+ """
+ if provider.is_local or not provider.filter:
+ return list(listed)
+ needles = [f.lower() for f in provider.filter if f]
+ if not needles:
+ return list(listed)
+ return [m for m in listed if any(n in m.lower() for n in needles)]