This repository was archived by the owner on May 26, 2026. It is now read-only.
feat(kora): KR-PLUGIN-COST-LADDER — first plugin extraction (cost-ladder)#185
Merged
rafe-walker merged 1 commit intoMay 24, 2026
Merged
Conversation
…der)
First plugin extraction per the bucket spec. Moves cost-router code
into the canonical Hermes plugin sub-directory shape; sets the
template for KR-PLUGIN-AUDIT / KR-PLUGIN-CACHING / etc. follow-ons.
Behavior: unchanged. KORA_REASONING_USE_GATEWAY stays default OFF;
the bypass path + the route-through path both keep working.
# Canonical location
kora_cli/reasoning/kora_hermes_plugin/
__init__.py — re-exports KoraHermesPlugin + register
plugin.py — orchestrator (6 hooks); delegates to sub-plugins
cost_ladder/
__init__.py — re-exports cost-ladder public surface
constants.py — DEFAULT_HAIKU_MODEL / regex defaults / rungs
selector.py — RoutingDecision + select_model_pre_call + …
plugin.py — pre_api_request_mutable hook handler + register
# Backward-compat shims (pure re-exports; old import paths keep working)
kora_cli/router/cost_router.py — 431 → 75 lines (shim only)
plugins/kora_hermes/__init__.py — 527 → 70 lines (discovery shim)
# Tests
tests/kora_cli/reasoning/kora_hermes_plugin/cost_ladder/test_selector.py
50 behavioral tests moved 1:1 from
tests/kora_cli/router/test_cost_router.py; only the import path
changed (now canonical).
tests/kora_cli/router/test_cost_router.py — converted to a small
3-test shim-verification suite (asserts every public symbol still
re-exports, via identity-against-canonical).
# Scoped regression (xdist)
tests/kora_cli/reasoning/kora_hermes_plugin/cost_ladder/ 50 pass
tests/kora_cli/router/ 3 pass
tests/plugins/test_kora_hermes_plugin*.py 67 pass
tests/kora_cli/snapshot/test_state_snapshot.py … pass
tests/kora_cli/reasoning/test_anthropic_engine_router.py … pass
Total directly-affected surface: 180/180 passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merged
9 tasks
rafe-walker
added a commit
that referenced
this pull request
May 24, 2026
…ircuit + state-holders (#188) 4 extractions following the #185 template. Audit (post_tool_call + post_llm_call writer), Caching (markers extracted from anthropic_engine.py; cost-ladder hook now imports from canonical), Short-Circuit (333 LOC matcher moved; dm_phrasebook.py shim), State-Holders (on_session_start registry). Each with backward-compat shim + identity-against-canonical drift guard. Cross-dep cleanup confirmed: cost_ladder/plugin.py no longer imports from anthropic_engine.py. Asserted by test_cost_ladder_plugin_imports_markers_from_canonical_location via patched-canonical sentinel. 337/337 directly-affected tests pass under xdist. After this: 5 of 7 plugin extractions complete; KR-PLUGIN-IDENTITY deferred per Lock R3-2; KR-HAIKU-ROUTER-PLUGIN waits on KR-HERMES-LOCAL-EXT-REISSUE.
Merged
13 tasks
rafe-walker
added a commit
that referenced
this pull request
May 24, 2026
…ck R3-2 Phase C completion (#189) Substantial paired bundle. Deliverable 1 — New local Hermes hook post_llm_call_can_reissue at agent/conversation_loop.py. First-non-None override semantics matching #172/#181 family. Anti-loop safety: at most one reissue per iteration. Backward compat: post_api_request observer sees FINAL (post-reissue) response only. Deliverable 2 — kora_hermes_plugin/haiku_router/ following #185 template. Plugin consumes should_escalate_post_call (from cost_ladder/selector.py since #185 but no caller until now). Implements parallel-Claude pattern from R3: low-confidence Haiku response → reissue to Opus with Haiku response in messages context. record_inference fires twice per iteration (Haiku + Opus reissue) with escalated_to_opus tagged correctly. Sample trace: Haiku reply uncertain (i"m not sure...) → escalates → Opus response includes Haiku context → Opus confirms terser. Two consecutive record_inference calls, only second tagged escalated_to_opus=True. What this completes: 6 of 7 plugin extractions (KR-PLUGIN-IDENTITY still deferred per Lock R3-2); all KR-HAIKU-ROUTER #165 escalation paths now functional end-to-end; Lock R3-2 Phase C closed. Two non-blocking follow-ups flagged in PR body: escalation_reason as structured telemetry field (one-line CostStateHolder.record_inference bump); per-call api_call_count accounting (transparent-upgrade vs per-call — currently transparent). 125 directly-affected tests green; 56 broader-suite failures verified pre-existing on base (fastapi/blake3/HERMES_HOME environmental, not regressions).
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First plugin extraction per the KR-PLUGIN-COST-LADDER bucket spec. Sets the template for subsequent extractions (KR-PLUGIN-AUDIT, KR-PLUGIN-CACHING, KR-PLUGIN-CONSTITUTION, …).
kora_cli/router/cost_router.pyinto the canonical Hermes plugin tree atkora_cli/reasoning/kora_hermes_plugin/cost_ladder/{constants,selector,plugin}.pykora_hermes_plugin/plugin.py) that delegates to sub-plugins and registers the 6 remaining hookskora_cli/router/cost_router.py+plugins/kora_hermes/__init__.py) so every existing import keeps workingBehavior: unchanged.
KORA_REASONING_USE_GATEWAYstays default OFF. The bypass path and the route-through path both keep working through the same external API.File-structure diagram
```
kora_cli/reasoning/kora_hermes_plugin/ ← NEW canonical location
├── init.py re-exports KoraHermesPlugin + register
├── plugin.py orchestrator (6 hooks); delegates to sub-plugins
└── cost_ladder/ ← first extracted sub-plugin
├── init.py re-exports cost-ladder public surface
├── constants.py DEFAULT_HAIKU_MODEL, regex defaults, rungs
├── selector.py RoutingDecision + select_model_pre_call + …
└── plugin.py pre_api_request_mutable hook + register()
kora_cli/router/cost_router.py ← shim (431 → 75 lines)
plugins/kora_hermes/init.py ← shim (527 → 70 lines)
tests/kora_cli/reasoning/kora_hermes_plugin/cost_ladder/test_selector.py
50 behavioral tests moved 1:1; imports now canonical.
tests/kora_cli/router/test_cost_router.py
Converted to 3-test shim-verification suite (identity-against-canonical).
```
Import-path-changes summary
Both old and new paths are valid after this PR. Existing in-tree callers (`kora_cli/snapshot/state_snapshot.py`, `kora_cli/reasoning/anthropic_engine.py`, every `tests/plugins/test_kora_hermes_plugin*.py`) were left untouched and pass; the shim-verification tests in `tests/kora_cli/router/test_cost_router.py` assert the shim stays in sync via identity-against-canonical.
Recommendation for next plugin extraction
KR-PLUGIN-AUDIT — per the spec's closing note. Audit logic (`_emit_audit` + the `post_tool_call` write path inside `_execute_single_tool_block`) is similarly self-contained: pure functions + a single hook handler, no shared mutable state with the rest of the orchestrator. Same shape as cost-ladder — one constants file (audit event types / route literals), one writer module, one hook handler. Should fit the template this PR established with minimal new design work.
After audit: KR-PLUGIN-CACHING is a natural follow-on (lifts `_wrap_system_as_cacheable` + `_wrap_tools_as_cacheable` from `anthropic_engine.py` into `cost_ladder/`'s sibling sub-plugin — currently the hook handler in `cost_ladder/plugin.py` imports them from `anthropic_engine`, which is the next refactor seam).
Test plan
🤖 Generated with Claude Code