coderouter-cli 2.9.1__py3-none-any.whl → 2.9.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coderouter/config/schemas.py +56 -2
- {coderouter_cli-2.9.1.dist-info → coderouter_cli-2.9.2.dist-info}/METADATA +1 -1
- {coderouter_cli-2.9.1.dist-info → coderouter_cli-2.9.2.dist-info}/RECORD +6 -6
- {coderouter_cli-2.9.1.dist-info → coderouter_cli-2.9.2.dist-info}/WHEEL +0 -0
- {coderouter_cli-2.9.1.dist-info → coderouter_cli-2.9.2.dist-info}/entry_points.txt +0 -0
- {coderouter_cli-2.9.1.dist-info → coderouter_cli-2.9.2.dist-info}/licenses/LICENSE +0 -0
coderouter/config/schemas.py
CHANGED
|
@@ -1951,8 +1951,16 @@ class CodeRouterConfig(BaseModel):
|
|
|
1951
1951
|
description="Master switch. ALLOW_PAID=false blocks all paid providers (plan.md §2.3).",
|
|
1952
1952
|
)
|
|
1953
1953
|
default_profile: str = Field(default="default")
|
|
1954
|
-
|
|
1955
|
-
|
|
1954
|
+
# [Unreleased]: relaxed from ``Field(..., min_length=1)`` so a
|
|
1955
|
+
# swap-only deployment (``launcher.swap.enabled`` with a non-empty
|
|
1956
|
+
# ``models`` catalog) can omit both fields entirely instead of
|
|
1957
|
+
# writing an unreachable dummy provider/profile just to satisfy the
|
|
1958
|
+
# schema. The "at least one" invariant is NOT dropped — it moves to
|
|
1959
|
+
# ``_check_providers_and_profiles_nonempty`` below, which still
|
|
1960
|
+
# fail-fasts at load for every other deployment shape (same
|
|
1961
|
+
# philosophy as the min_length constraint it replaces).
|
|
1962
|
+
providers: list[ProviderConfig] = Field(default_factory=list)
|
|
1963
|
+
profiles: list[FallbackChain] = Field(default_factory=list)
|
|
1956
1964
|
mode_aliases: dict[str, str] = Field(
|
|
1957
1965
|
default_factory=dict,
|
|
1958
1966
|
description=(
|
|
@@ -2159,6 +2167,52 @@ class CodeRouterConfig(BaseModel):
|
|
|
2159
2167
|
)
|
|
2160
2168
|
return self
|
|
2161
2169
|
|
|
2170
|
+
@model_validator(mode="after")
|
|
2171
|
+
def _check_providers_and_profiles_nonempty(self) -> CodeRouterConfig:
|
|
2172
|
+
"""[Unreleased]: enforce "at least one" unless launcher.swap covers it.
|
|
2173
|
+
|
|
2174
|
+
``providers`` / ``profiles`` were relaxed from ``min_length=1`` to
|
|
2175
|
+
``default_factory=list`` (see the field comments above) so a
|
|
2176
|
+
swap-only deployment can omit them — every request in that shape
|
|
2177
|
+
is routed through a ``launcher-swap-<name>`` profile that
|
|
2178
|
+
:meth:`_inject_swap_profiles_and_auto_router_rules` synthesizes
|
|
2179
|
+
below, and its backing provider is registered at runtime on first
|
|
2180
|
+
spawn (``SwapManager.register_provider``), so there is genuinely
|
|
2181
|
+
nothing to declare statically.
|
|
2182
|
+
|
|
2183
|
+
Runs BEFORE the swap injection (which only ever *adds* profiles,
|
|
2184
|
+
never providers) so it observes the operator's raw, undecorated
|
|
2185
|
+
input rather than the post-injection state — the injected
|
|
2186
|
+
profiles are not a substitute for a real provider declaration in
|
|
2187
|
+
every other deployment shape, only in the swap-only one this
|
|
2188
|
+
validator carves out.
|
|
2189
|
+
|
|
2190
|
+
Outside that carve-out, an empty ``providers`` or ``profiles``
|
|
2191
|
+
list has always been a load-time error (there would be nothing to
|
|
2192
|
+
route to); this validator keeps that fail-fast guarantee instead
|
|
2193
|
+
of silently trading it away when the ``min_length=1`` field
|
|
2194
|
+
constraint was dropped.
|
|
2195
|
+
"""
|
|
2196
|
+
swap_cfg = self.launcher.swap if self.launcher is not None else None
|
|
2197
|
+
swap_covers_empty = (
|
|
2198
|
+
swap_cfg is not None and swap_cfg.enabled and bool(swap_cfg.models)
|
|
2199
|
+
)
|
|
2200
|
+
if swap_covers_empty:
|
|
2201
|
+
return self
|
|
2202
|
+
if not self.providers:
|
|
2203
|
+
raise ValueError(
|
|
2204
|
+
"providers: at least one entry is required (empty/omitted "
|
|
2205
|
+
"is only allowed when launcher.swap.enabled=true and "
|
|
2206
|
+
"launcher.swap.models has at least one entry)."
|
|
2207
|
+
)
|
|
2208
|
+
if not self.profiles:
|
|
2209
|
+
raise ValueError(
|
|
2210
|
+
"profiles: at least one entry is required (empty/omitted "
|
|
2211
|
+
"is only allowed when launcher.swap.enabled=true and "
|
|
2212
|
+
"launcher.swap.models has at least one entry)."
|
|
2213
|
+
)
|
|
2214
|
+
return self
|
|
2215
|
+
|
|
2162
2216
|
@model_validator(mode="after")
|
|
2163
2217
|
def _inject_swap_profiles_and_auto_router_rules(self) -> CodeRouterConfig:
|
|
2164
2218
|
"""§10 Q7 + design-deviation: bootstrap swap's dedicated profiles.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coderouter-cli
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.2
|
|
4
4
|
Summary: Local-first, free-first, fallback-built-in LLM router. Claude Code / OpenAI compatible.
|
|
5
5
|
Project-URL: Homepage, https://github.com/zephel01/CodeRouter
|
|
6
6
|
Project-URL: Repository, https://github.com/zephel01/CodeRouter
|
|
@@ -25,7 +25,7 @@ coderouter/config/__init__.py,sha256=FODEn74fN-qZnt4INPSHswqhOlEgpL6-_onxsitSx8g
|
|
|
25
25
|
coderouter/config/capability_registry.py,sha256=RZgzHF54dXy0CCDocRCz2ee21qXGbbgTSKTkRI9iLL4,16936
|
|
26
26
|
coderouter/config/env_file.py,sha256=CoMK27fuAXm-NtoLzXb8yN2E-wDFjHQuFwiIlmgTBQw,10356
|
|
27
27
|
coderouter/config/loader.py,sha256=FUEe8m4Tnmj_aul0vSctD8vKvNW-oLRoMRbTpSKqSmc,4077
|
|
28
|
-
coderouter/config/schemas.py,sha256=
|
|
28
|
+
coderouter/config/schemas.py,sha256=zMv6UjL2ebcxc3dMIOa9lQjOGvvuHMWCPqoOVA35CEw,117181
|
|
29
29
|
coderouter/data/__init__.py,sha256=uNyfD9jaCvTWsBAWtaw1Fr25OSxzv3psGMfBjT1z0Cc,328
|
|
30
30
|
coderouter/data/model-capabilities.yaml,sha256=S9jt6SC6-3s2-icZ_n-a14iEMnc2yB1C2R6q-N_tZWQ,19309
|
|
31
31
|
coderouter/guards/__init__.py,sha256=5qliYBqygvVPneej7nx0uSjxDKsz7t8VzvrDgVBJlvU,1170
|
|
@@ -69,8 +69,8 @@ coderouter/translation/__init__.py,sha256=PYXN7XVEwpG1uC8RLy6fvnGbzEZhhrEuUapH8I
|
|
|
69
69
|
coderouter/translation/anthropic.py,sha256=aZkcYH4x82b0x7efJgJb9RWn9Hbyc9pEOthXe4vjUdU,11113
|
|
70
70
|
coderouter/translation/convert.py,sha256=VV4kpu4dvLmGBmJfQnCLY5ryy_AnQcV2NuwjqRtaR8Q,52633
|
|
71
71
|
coderouter/translation/tool_repair.py,sha256=DGOKArM53yfVbIfiAveoul1vGq9NEKmjagf43Qh4IkM,57630
|
|
72
|
-
coderouter_cli-2.9.
|
|
73
|
-
coderouter_cli-2.9.
|
|
74
|
-
coderouter_cli-2.9.
|
|
75
|
-
coderouter_cli-2.9.
|
|
76
|
-
coderouter_cli-2.9.
|
|
72
|
+
coderouter_cli-2.9.2.dist-info/METADATA,sha256=dcDACrTxRsla8y8mcY05IC4KilzZD-co6xkEz9xC_H4,15994
|
|
73
|
+
coderouter_cli-2.9.2.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
74
|
+
coderouter_cli-2.9.2.dist-info/entry_points.txt,sha256=-dnLfD1YZ2WjH2zSdNCvlO65wYltM9bsHt9Fhg3yGss,51
|
|
75
|
+
coderouter_cli-2.9.2.dist-info/licenses/LICENSE,sha256=wkEzoR86jFw33jvfOHjULqmkGEfxTFMgMaJnpR8mPRw,1065
|
|
76
|
+
coderouter_cli-2.9.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|