coderouter-cli 2.8.1__py3-none-any.whl → 2.9.0__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.
@@ -18,12 +18,27 @@ logger = get_logger(__name__)
18
18
  # in-core kinds, in resolution order. Kept as a tuple (not derived from
19
19
  # the if-chain below) so the "Unknown adapter kind" error message and
20
20
  # the plugin-shadow guard have a single source of truth.
21
- _IN_CORE_KINDS: tuple[str, ...] = ("openai_compat", "anthropic", "agent_cli")
22
-
23
- # Module-level flag so the Phase 2b in-core agent_cli deprecation warning
24
- # (docs/designs/agent-cli-plugin-extraction.md §5.1) fires at most once per
25
- # process, regardless of how many agent_cli providers are built.
26
- _agent_cli_deprecation_logged = False
21
+ #
22
+ # Phase 2c (docs/designs/agent-cli-plugin-extraction.md §7 row "2c"):
23
+ # "agent_cli" is no longer in this tuple. It is served exclusively by
24
+ # the coderouter-plugin-agents adapter plugin now that the in-core
25
+ # AgentCliAdapter and its build_adapter branch have been removed.
26
+ _IN_CORE_KINDS: tuple[str, ...] = ("openai_compat", "anthropic")
27
+
28
+ # Phase 2c migration hint (docs/designs/agent-cli-plugin-extraction.md
29
+ # §5.2): shown ONLY for kind="agent_cli" when no plugin resolves it, so
30
+ # operators upgrading from pre-2c configs get a targeted fix instead of
31
+ # the generic unknown-kind message.
32
+ _AGENT_CLI_MIGRATION_HINT = (
33
+ "kind='agent_cli' is served by the coderouter-plugin-agents plugin "
34
+ "(Core no longer ships an in-core agent_cli adapter as of Phase 2c). "
35
+ 'Install it with: pip install "coderouter-plugin-agents @ '
36
+ 'git+https://github.com/zephel01/coderouter-plugin-agents" and add '
37
+ "'agents' to plugins.enabled in providers.yaml, e.g.:\n"
38
+ "plugins:\n"
39
+ " enabled:\n"
40
+ " - agents"
41
+ )
27
42
 
28
43
 
29
44
  def _plugin_kinds(plugin_registry: PluginRegistry | None) -> list[str]:
@@ -33,36 +48,6 @@ def _plugin_kinds(plugin_registry: PluginRegistry | None) -> list[str]:
33
48
  return [factory.kind for factory in plugin_registry.adapters]
34
49
 
35
50
 
36
- def _warn_agent_cli_in_core_deprecated_once() -> None:
37
- """Log ``agent-cli-in-core-deprecated`` once per process (§5.1).
38
-
39
- Only called when the in-core ``agent_cli`` branch is taken AND an
40
- adapter plugin has also registered a ``kind="agent_cli"`` factory —
41
- i.e. the operator already has ``coderouter-plugin-agents`` installed
42
- and enabled, but Core's in-core copy still wins resolution order
43
- (§3.2) during the Phase 2b migration window. Nudges them toward the
44
- plugin path ahead of its Phase 2c removal from Core.
45
- """
46
- global _agent_cli_deprecation_logged
47
- if _agent_cli_deprecation_logged:
48
- return
49
- _agent_cli_deprecation_logged = True
50
- logger.warning(
51
- "agent-cli-in-core-deprecated",
52
- extra={
53
- "hint": (
54
- "an 'agent_cli' adapter plugin is installed and enabled, "
55
- "but Core's in-core agent_cli implementation still served "
56
- "this request (in-core wins resolution during the Phase 2b "
57
- "migration window). The in-core copy will be removed in "
58
- "Phase 2c — no action is required yet, but new setups "
59
- "should already be relying on the plugin path "
60
- "(coderouter-plugin-agents)."
61
- ),
62
- },
63
- )
64
-
65
-
66
51
  def build_adapter(
67
52
  provider: ProviderConfig,
68
53
  plugin_registry: PluginRegistry | None = None,
@@ -72,27 +57,25 @@ def build_adapter(
72
57
  Resolution order (docs/designs/agent-cli-plugin-extraction.md §3.2):
73
58
  in-core kinds first, then plugin-provided kinds, then a fail-fast
74
59
  error. In-core kinds are checked first so a plugin can never shadow
75
- a kind Core itself guarantees (``openai_compat`` / ``anthropic`` /,
76
- during the Phase 2b migration window, ``agent_cli``).
60
+ a kind Core itself guarantees (``openai_compat`` / ``anthropic``).
61
+
62
+ As of Phase 2c, ``agent_cli`` is no longer an in-core kind — it
63
+ resolves ONLY via the plugin path (``coderouter-plugin-agents``).
77
64
  """
78
65
  if provider.kind == "openai_compat":
79
66
  return OpenAICompatAdapter(provider)
80
67
  if provider.kind == "anthropic":
81
68
  return AnthropicAdapter(provider)
82
- if provider.kind == "agent_cli":
83
- # Imported lazily so the external-agent adapter (and its subprocess /
84
- # os plumbing) is only pulled in when a config actually uses it.
85
- from coderouter.adapters.agent_cli import AgentCliAdapter
86
-
87
- if plugin_registry is not None and any(
88
- factory.kind == "agent_cli" for factory in plugin_registry.adapters
89
- ):
90
- _warn_agent_cli_in_core_deprecated_once()
91
- return AgentCliAdapter(provider)
92
69
  if plugin_registry is not None:
93
70
  for factory in plugin_registry.adapters:
94
71
  if factory.kind == provider.kind:
95
72
  return factory.build(provider)
73
+ if provider.kind == "agent_cli":
74
+ # Targeted migration hint (§5.2) instead of the generic message
75
+ # below — this is the single most common post-2c misconfiguration
76
+ # (an un-migrated providers.yaml that still relies on the removed
77
+ # in-core adapter).
78
+ raise ValueError(f"Unknown adapter kind {provider.kind!r}. {_AGENT_CLI_MIGRATION_HINT}")
96
79
  raise ValueError(
97
80
  f"Unknown adapter kind {provider.kind!r}. "
98
81
  f"in-core kinds: {', '.join(_IN_CORE_KINDS)}; "
@@ -166,8 +166,21 @@ class CostConfig(BaseModel):
166
166
  class AgentCliConfig(BaseModel):
167
167
  """External coding-agent CLI settings for ``kind="agent_cli"`` providers.
168
168
 
169
- Introduced by the external-agents-adapter design (Phase 1). One
170
- ``agent_cli`` sub-config drives the :class:`AgentCliAdapter`, which
169
+ Introduced by the external-agents-adapter design (Phase 1). As of the
170
+ agent_cli plugin extraction's Phase 2c
171
+ (``docs/designs/agent-cli-plugin-extraction.md`` §4.4 case (b), §7),
172
+ the adapter that actually invokes the CLI (``AgentCliAdapter``,
173
+ argv construction / output parsing / sandbox flag tables) has moved
174
+ to the separately-distributed ``coderouter-plugin-agents`` plugin
175
+ (``pip install coderouter-plugin-agents`` + ``plugins.enabled:
176
+ [agents]``) — Core no longer ships it in-core. ``AgentCliConfig``
177
+ itself REMAINS in Core: it is a stable schema contract that has not
178
+ changed since Phase 1 (unlike the adapter body, which absorbs
179
+ per-CLI churn), so keeping it here preserves ``extra="forbid"``
180
+ fail-fast validation at config-load time regardless of whether the
181
+ plugin is installed.
182
+
183
+ One ``agent_cli`` sub-config drives the plugin's adapter, which
171
184
  invokes an external coding-agent CLI (codex / gemini / grok / claude /
172
185
  antigravity) in a single one-shot ``exec`` and returns the final answer
173
186
  as one ``prompt in → text out`` transformation. ``claude`` (Claude Code
@@ -355,10 +368,13 @@ class ProviderConfig(BaseModel):
355
368
  description=(
356
369
  "Adapter type. 'openai_compat' covers llama.cpp / Ollama / "
357
370
  "OpenRouter / LM Studio / Together / Groq. 'anthropic' is the "
358
- "native Anthropic Messages API passthrough (v0.3.x). 'agent_cli' "
359
- "invokes an external coding-agent CLI one-shot (see AgentCliConfig). "
360
- "Other values must be served by an adapter plugin listed in "
361
- "plugins.enabled."
371
+ "native Anthropic Messages API passthrough (v0.3.x). These two "
372
+ "are Core's only in-core kinds. 'agent_cli' invokes an external "
373
+ "coding-agent CLI one-shot (see AgentCliConfig) but, as of "
374
+ "Phase 2c, is served by the coderouter-plugin-agents adapter "
375
+ "plugin — install it and list 'agents' in plugins.enabled. "
376
+ "Any other value must likewise be served by an adapter plugin "
377
+ "listed in plugins.enabled."
362
378
  ),
363
379
  )
364
380
  # base_url is required for HTTP-backed adapters (openai_compat / anthropic)
@@ -428,9 +444,18 @@ class ProviderConfig(BaseModel):
428
444
  # kind="agent_cli": required external coding-agent CLI settings. Opt-in
429
445
  # (default None) exactly like ``restart_command`` — only meaningful when
430
446
  # ``kind == "agent_cli"``, and enforced by ``_check_kind_requirements``.
447
+ # The schema (this field + AgentCliConfig + the kind literal) stays in
448
+ # Core; the adapter that consumes it is the coderouter-plugin-agents
449
+ # plugin as of Phase 2c (docs/designs/agent-cli-plugin-extraction.md
450
+ # §4.4 case (b)).
431
451
  agent_cli: AgentCliConfig | None = Field(
432
452
  default=None,
433
- description="Required when kind='agent_cli': external agent CLI settings.",
453
+ description=(
454
+ "Required when kind='agent_cli': external agent CLI settings. "
455
+ "Served by the coderouter-plugin-agents adapter plugin — "
456
+ "`pip install coderouter-plugin-agents` and add 'agents' to "
457
+ "plugins.enabled."
458
+ ),
434
459
  )
435
460
 
436
461
  cost: CostConfig | None = Field(
coderouter/doctor.py CHANGED
@@ -1834,6 +1834,56 @@ async def _probe_cache(
1834
1834
  )
1835
1835
 
1836
1836
 
1837
+ # ---------------------------------------------------------------------------
1838
+ # Phase 2c migration guard (docs/designs/agent-cli-plugin-extraction.md §5.2,
1839
+ # §7 "2c" row): a config-level pre-check, not an HTTP probe. Core removed
1840
+ # its in-core agent_cli adapter in Phase 2c — kind="agent_cli" now resolves
1841
+ # ONLY via the coderouter-plugin-agents adapter plugin
1842
+ # (coderouter/adapters/registry.py's build_adapter). A provider that still
1843
+ # declares kind="agent_cli" without the plugin enabled will fail at engine
1844
+ # startup with a ValueError; surfacing it here lets `coderouter doctor`
1845
+ # catch it ahead of `coderouter serve`, with a copy-paste-able fix.
1846
+ # ---------------------------------------------------------------------------
1847
+
1848
+
1849
+ def _check_agent_cli_plugin_migration(
1850
+ config: CodeRouterConfig, provider: ProviderConfig
1851
+ ) -> ProbeResult | None:
1852
+ """Warn when ``provider`` needs the agent_cli plugin but it isn't enabled.
1853
+
1854
+ Returns ``None`` (no finding) when ``provider.kind`` isn't
1855
+ ``"agent_cli"``, or when ``"agents"`` is already listed in
1856
+ ``plugins.enabled`` — i.e. nothing actionable to report.
1857
+ """
1858
+ if provider.kind != "agent_cli":
1859
+ return None
1860
+ enabled = config.plugins.enabled if config.plugins is not None else []
1861
+ if "agents" in enabled:
1862
+ return None
1863
+ return ProbeResult(
1864
+ name="agent-cli-plugin-migration",
1865
+ verdict=ProbeVerdict.NEEDS_TUNING,
1866
+ detail=(
1867
+ f"provider {provider.name!r} declares kind='agent_cli', but the "
1868
+ "coderouter-plugin-agents adapter plugin is not enabled. As of "
1869
+ "v2.9.0 (Phase 2c), Core no longer ships an in-core agent_cli "
1870
+ "adapter — this provider cannot serve requests until the "
1871
+ "plugin is installed and listed in plugins.enabled."
1872
+ ),
1873
+ target_file="providers.yaml",
1874
+ suggested_patch=(
1875
+ "# install the plugin:\n"
1876
+ 'pip install "coderouter-plugin-agents @ '
1877
+ 'git+https://github.com/zephel01/coderouter-plugin-agents"\n'
1878
+ "\n"
1879
+ "# providers.yaml — enable it (merge into any existing list):\n"
1880
+ "plugins:\n"
1881
+ " enabled:\n"
1882
+ " - agents\n"
1883
+ ),
1884
+ )
1885
+
1886
+
1837
1887
  # ---------------------------------------------------------------------------
1838
1888
  # Orchestration
1839
1889
  # ---------------------------------------------------------------------------
@@ -1872,6 +1922,14 @@ async def check_model(
1872
1922
  resolved_caps=resolved,
1873
1923
  )
1874
1924
 
1925
+ migration = _check_agent_cli_plugin_migration(config, provider)
1926
+ if migration is not None:
1927
+ # Nothing to probe over HTTP — the provider has no adapter until
1928
+ # the plugin is enabled. Report the finding and stop here rather
1929
+ # than sending HTTP probes at a (kind-wise meaningless) base_url.
1930
+ report.results.append(migration)
1931
+ return report
1932
+
1875
1933
  auth_result = await _probe_auth_and_basic_chat(provider)
1876
1934
  report.results.append(auth_result)
1877
1935
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coderouter-cli
3
- Version: 2.8.1
3
+ Version: 2.9.0
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
@@ -3,7 +3,7 @@ coderouter/__main__.py,sha256=-LCgxJnvgUV240HjQKv7ly-mn2NuKHpC4nCpvTHjeSU,130
3
3
  coderouter/cli.py,sha256=7zxt6riKPTpHGiDms9SVaPbe-n4ytfCrhIVtuPII-oU,30173
4
4
  coderouter/cli_stats.py,sha256=CCjzc1G4hTRHZ2gG1XhxhDpUkJnnl3NXbcbp1T18jpg,29894
5
5
  coderouter/cost.py,sha256=32h6uzb4nxh2eA5d2Hn3kD9yJbtis6CFDAbeIy5KRkM,7431
6
- coderouter/doctor.py,sha256=2luNk6BHSRvpQStJnHcqzNvNi-SKdOuKV0WZdorZhVk,82854
6
+ coderouter/doctor.py,sha256=x0OqWUMGPzYaX2poWSH2UA90sEr4Z69-gVYLXYQFCFU,85483
7
7
  coderouter/doctor_apply.py,sha256=r_J6xbu5-HivofPNriw4_vjNYs_VRs7GsGTS0oMEX10,24209
8
8
  coderouter/env_security.py,sha256=FEBZnXfJ0xE39kmMMn39zk0W_DRRnmcB_REmP9f4xWo,14796
9
9
  coderouter/errors.py,sha256=Xmq67lheyw8iv3Ox39jh2c4tvNI5RcUR4QkoxVDN6l4,1130
@@ -16,16 +16,15 @@ coderouter/output_filters.py,sha256=0ry_rPiS_kC-FnHgaNVP6v7e6Al2djxzu9vBzZ8kEkE,
16
16
  coderouter/token_estimation.py,sha256=iz22vZEEW2P7uKLB2pYvPNpIbZGbgXRO5MtfkS_-9Sk,7531
17
17
  coderouter/token_estimation_accurate.py,sha256=GTfzrBVnvAGjeVzmzAeUdOYZvWZKLAxcxPpFiJGlzjk,4609
18
18
  coderouter/adapters/__init__.py,sha256=7dIDSZ-FE_0iSqLSDc_lK1idRdLTKcM2hP9tCJipgPI,463
19
- coderouter/adapters/agent_cli.py,sha256=0g0V92drEQLJACXq-Dn0hE-J6e3vmsuBr5UdnAkXJyk,52430
20
19
  coderouter/adapters/anthropic_native.py,sha256=CT9Hitun-c3z83YHT2zZXgwZpY3_t6eRnOfAmNud2aw,23610
21
20
  coderouter/adapters/base.py,sha256=ykKMaiIVVGr23oFFXilK2iP_YhI8-CtsEiJyFXaC9bE,10396
22
21
  coderouter/adapters/openai_compat.py,sha256=wcrd_UpV7N6ISpUyKvdFPGU-YjCrX5oMqGpjAFEeWfg,20356
23
- coderouter/adapters/registry.py,sha256=hwMhdBg-wurjJKa4MJIuDoMn1ClOOsorGppJ-s5pnF0,4311
22
+ coderouter/adapters/registry.py,sha256=XNc1wmFv_oZlqKS0rA693TRDdbq1sZ-OIcofXOVOtq0,3680
24
23
  coderouter/config/__init__.py,sha256=FODEn74fN-qZnt4INPSHswqhOlEgpL6-_onxsitSx8g,274
25
24
  coderouter/config/capability_registry.py,sha256=RZgzHF54dXy0CCDocRCz2ee21qXGbbgTSKTkRI9iLL4,16936
26
25
  coderouter/config/env_file.py,sha256=CoMK27fuAXm-NtoLzXb8yN2E-wDFjHQuFwiIlmgTBQw,10356
27
26
  coderouter/config/loader.py,sha256=FUEe8m4Tnmj_aul0vSctD8vKvNW-oLRoMRbTpSKqSmc,4077
28
- coderouter/config/schemas.py,sha256=AJIJ-zrEgI5czTlcD6YxWQe9rnJFsr6AcKSwwlCaLk8,89447
27
+ coderouter/config/schemas.py,sha256=PUx-WwjFfa4UVaBd0dt3s7mCwE5D2Vp0hPD2S4mOcH4,90894
29
28
  coderouter/data/__init__.py,sha256=uNyfD9jaCvTWsBAWtaw1Fr25OSxzv3psGMfBjT1z0Cc,328
30
29
  coderouter/data/model-capabilities.yaml,sha256=S9jt6SC6-3s2-icZ_n-a14iEMnc2yB1C2R6q-N_tZWQ,19309
31
30
  coderouter/guards/__init__.py,sha256=5qliYBqygvVPneej7nx0uSjxDKsz7t8VzvrDgVBJlvU,1170
@@ -69,8 +68,8 @@ coderouter/translation/__init__.py,sha256=PYXN7XVEwpG1uC8RLy6fvnGbzEZhhrEuUapH8I
69
68
  coderouter/translation/anthropic.py,sha256=aZkcYH4x82b0x7efJgJb9RWn9Hbyc9pEOthXe4vjUdU,11113
70
69
  coderouter/translation/convert.py,sha256=VV4kpu4dvLmGBmJfQnCLY5ryy_AnQcV2NuwjqRtaR8Q,52633
71
70
  coderouter/translation/tool_repair.py,sha256=DGOKArM53yfVbIfiAveoul1vGq9NEKmjagf43Qh4IkM,57630
72
- coderouter_cli-2.8.1.dist-info/METADATA,sha256=qRLxuyz0gjzAwHy4eSWMXl_E23g7fwG6AYuVonimdlg,15546
73
- coderouter_cli-2.8.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
74
- coderouter_cli-2.8.1.dist-info/entry_points.txt,sha256=-dnLfD1YZ2WjH2zSdNCvlO65wYltM9bsHt9Fhg3yGss,51
75
- coderouter_cli-2.8.1.dist-info/licenses/LICENSE,sha256=wkEzoR86jFw33jvfOHjULqmkGEfxTFMgMaJnpR8mPRw,1065
76
- coderouter_cli-2.8.1.dist-info/RECORD,,
71
+ coderouter_cli-2.9.0.dist-info/METADATA,sha256=REKGn1AQx-as9IHvUBwA0ApEzwcrgKQCyQekxiqJOXo,15546
72
+ coderouter_cli-2.9.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
73
+ coderouter_cli-2.9.0.dist-info/entry_points.txt,sha256=-dnLfD1YZ2WjH2zSdNCvlO65wYltM9bsHt9Fhg3yGss,51
74
+ coderouter_cli-2.9.0.dist-info/licenses/LICENSE,sha256=wkEzoR86jFw33jvfOHjULqmkGEfxTFMgMaJnpR8mPRw,1065
75
+ coderouter_cli-2.9.0.dist-info/RECORD,,