aboutsummaryrefslogtreecommitdiffstats
path: root/llamachat/providers.py
diff options
context:
space:
mode:
Diffstat (limited to 'llamachat/providers.py')
-rw-r--r--llamachat/providers.py20
1 files changed, 15 insertions, 5 deletions
diff --git a/llamachat/providers.py b/llamachat/providers.py
index 48b4883..d955436 100644
--- a/llamachat/providers.py
+++ b/llamachat/providers.py
@@ -63,11 +63,15 @@ def parse(values: dict) -> dict[str, Provider]:
"""
table = dict(values.get("providers") or {})
- # An old config has only a bare base_url. Synthesize the local provider
- # from it so nothing needs migrating, but never override an explicit one.
+ # An old config has only a bare base_url. Fill it in as the local
+ # provider's URL so nothing needs migrating, but never override an
+ # explicit one. The test is the URL rather than the key: a
+ # [providers.local] that only sets an api_key is adding detail to the
+ # provider the user already has, not replacing it, and treating it as a
+ # replacement would silently delete local entirely.
bare = values.get("base_url")
- if bare and LOCAL not in table:
- table[LOCAL] = {"base_url": bare}
+ if bare and not (table.get(LOCAL) or {}).get("base_url"):
+ table[LOCAL] = {**(table.get(LOCAL) or {}), "base_url": bare}
out: dict[str, Provider] = {}
for name, entry in table.items():
@@ -77,12 +81,18 @@ def parse(values: dict) -> dict[str, Provider]:
# ponytail: a provider with no URL is misconfigured, not a
# partial one. Skipping beats inventing a default endpoint.
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 = entry.get("filter") or []
+ if isinstance(needles, str):
+ needles = [needles]
vision = entry.get("vision")
out[str(name)] = Provider(
name=str(name),
base_url=base_url,
api_key=str(entry.get("api_key") or ""),
- filter=[str(f) for f in (entry.get("filter") or [])],
+ filter=[str(f) for f in needles],
ctx_size=_number(entry.get("ctx_size"), int),
vision=None if vision is None else bool(vision),
price_in=_number(entry.get("price_in"), float),