chore(honcho): drop docs from PR scope, scrub commentary

- Revert website/docs and SKILL.md changes; docs unification handled separately
- Scrub commit/PR refs and process narration from code comments and test
  docstrings (no behavior change)
This commit is contained in:
Erosika
2026-04-18 11:01:45 -04:00
committed by kshitij
parent 78586ce036
commit 5f9907c116
7 changed files with 33 additions and 55 deletions

View File

@@ -145,10 +145,10 @@ Controls **how often** dialectic and context calls happen.
| Key | Default | Description |
|-----|---------|-------------|
| `contextCadence` | `1` | Min turns between context API calls |
| `dialecticCadence` | `1` | Min turns between dialectic API calls |
| `dialecticCadence` | `3` | Min turns between dialectic API calls |
| `injectionFrequency` | `every-turn` | `every-turn` or `first-turn` for base context injection |
Higher cadence values reduce API calls and cost. `dialecticCadence: 1` (default) fires every turn; set to `3` or higher to throttle for cost.
Higher cadence values reduce API calls and cost. `dialecticCadence: 3` (default) means the dialectic engine fires at most every 3rd turn.
### Depth (how many)
@@ -368,7 +368,7 @@ Config file: `$HERMES_HOME/honcho.json` (profile-local) or `~/.honcho/config.jso
| `contextTokens` | uncapped | Max tokens for the combined base context injection (summary + representation + card). Opt-in cap — omit to leave uncapped, set to an integer to bound injection size. |
| `injectionFrequency` | `every-turn` | `every-turn` or `first-turn` |
| `contextCadence` | `1` | Min turns between context API calls |
| `dialecticCadence` | `1` | Min turns between dialectic LLM calls |
| `dialecticCadence` | `3` | Min turns between dialectic LLM calls |
The `contextTokens` budget is enforced at injection time. If the session summary + representation + card exceed the budget, Honcho trims the summary first, then the representation, preserving the card. This prevents context blowup in long sessions.

View File

@@ -393,13 +393,10 @@ class HonchoMemoryProvider(MemoryProvider):
logger.debug("Honcho memory file migration skipped: %s", e)
# ----- B7: Pre-warming at init -----
# Context prewarm: warms peer.context() cache (base layer), consumed
# via pop_context_result() in prefetch().
# Dialectic prewarm: fires a depth-aware cycle against the plugin's
# own _prefetch_result so turn 1 can consume it directly. Without this
# the first-turn sync path pays for a duplicate .chat() — and at
# depth>1 a single-pass session-start dialectic often returns weak
# output that multi-pass audit/reconciliation is meant to catch.
# Context prewarm warms peer.context() (base layer), consumed via
# pop_context_result() in prefetch(). Dialectic prewarm runs the
# full configured depth and writes into _prefetch_result so turn 1
# consumes the result directly.
if self._recall_mode in ("context", "hybrid"):
try:
self._manager.prefetch_context(self._session_key)
@@ -555,8 +552,7 @@ class HonchoMemoryProvider(MemoryProvider):
if self._injection_frequency == "first-turn" and self._turn_count > 1:
return ""
# Skip trivial prompts "ok", "yes", slash commands carry no semantic signal,
# so injecting user context there just burns tokens and can derail the reply.
# Trivial prompts ("ok", "yes", slash commands) carry no semantic signal.
if self._is_trivial_prompt(query):
return ""
@@ -619,8 +615,8 @@ class HonchoMemoryProvider(MemoryProvider):
if r and r.strip():
with self._prefetch_lock:
self._prefetch_result = r
# Only advance cadence on a non-empty result so failures
# don't burn a 3-turn cooldown on nothing.
# Advance cadence only on a non-empty result so the next
# turn retries when the call returned nothing.
self._last_dialectic_turn = _fired_at
self._prefetch_thread = threading.Thread(
@@ -711,9 +707,8 @@ class HonchoMemoryProvider(MemoryProvider):
self._dialectic_cadence, self._turn_count - self._last_dialectic_turn)
return
# Advance cadence only on a non-empty result — otherwise a silent failure
# (empty dialectic, transient API error) would burn the full cadence window
# before the next retry, making it look like dialectic "never fires again".
# Cadence advances only on a non-empty result so empty returns
# (transient API error, sparse representation) retry next turn.
_fired_at = self._turn_count
def _run():
@@ -751,9 +746,7 @@ class HonchoMemoryProvider(MemoryProvider):
_LEVEL_ORDER = ("minimal", "low", "medium", "high", "max")
# Reasoning-level heuristic thresholds (restored from pre-9a0ab34c behavior).
# Promoted to class constants so tests can override without widening the
# config surface. Bump to config fields only if real use shows they're needed.
# Char-count thresholds for the query-length reasoning heuristic.
_HEURISTIC_LENGTH_MEDIUM = 120
_HEURISTIC_LENGTH_HIGH = 400

View File

@@ -463,7 +463,7 @@ def cmd_setup(args) -> None:
current_dialectic = str(hermes_host.get("dialecticCadence") or cfg.get("dialecticCadence") or "1")
print("\n Dialectic cadence:")
print(" How often Honcho rebuilds its user model (LLM call on Honcho backend).")
print(" 1 = every turn (default), 3+ = sparse (cost-saving).")
print(" 1 = every turn (default), 3+ = sparse.")
new_dialectic = _prompt("Dialectic cadence", default=current_dialectic)
try:
val = int(new_dialectic)

View File

@@ -251,13 +251,11 @@ class HonchoClientConfig:
# matching dialectic_depth length. When None, uses proportional defaults
# derived from dialectic_reasoning_level.
dialectic_depth_levels: list[str] | None = None
# Reasoning-level heuristic for auto-injected dialectic calls. When true,
# scales the base level up on longer queries (restored from pre-#10619
# behavior; see plugins/memory/honcho/__init__.py for thresholds).
# Never auto-selects a level above reasoning_level_cap.
# When true, the auto-injected dialectic scales reasoning level up on
# longer queries. See HonchoMemoryProvider for thresholds.
reasoning_heuristic: bool = True
# Ceiling for heuristic-selected reasoning level. "max" is reserved for
# explicit tool-path selection; default "high" matches the old behavior.
# Ceiling for the heuristic-selected reasoning level. "max" is reserved
# for explicit tool-path selection.
reasoning_level_cap: str = "high"
# Honcho API limits — configurable for self-hosted instances
# Max chars per message sent via add_messages() (Honcho cloud: 25000)

View File

@@ -862,9 +862,7 @@ class TestDialecticCadenceDefaults:
return provider
def test_default_is_1(self):
"""Default dialectic_cadence should be 1 (every turn) — restored from
pre-#10619 behavior to avoid a silent regression on upgrade for users
who never set dialecticCadence explicitly."""
"""Default dialectic_cadence is 1 — fires every turn unless overridden."""
provider = self._make_provider()
assert provider._dialectic_cadence == 1
@@ -1112,10 +1110,7 @@ class TestDialecticDepth:
class TestTrivialPromptHeuristic:
"""Trivial prompts ('ok', 'y', slash commands) must short-circuit injection.
Restored after accidental removal during the two-layer prefetch refactor.
"""
"""Trivial prompts ('ok', 'y', slash commands) must short-circuit injection."""
@staticmethod
def _make_provider():
@@ -1173,11 +1168,9 @@ class TestTrivialPromptHeuristic:
class TestDialecticCadenceAdvancesOnSuccess:
"""Cadence tracker must only advance when the dialectic call actually returned.
A silent failure (empty result, API blip) used to burn the full cadence window
before retrying — making it look like dialectic 'never fires again'.
"""
"""Cadence tracker advances only when the dialectic call returns a
non-empty result. Empty results (transient API error, sparse representation)
must retry on the next eligible turn instead of waiting the full cadence."""
@staticmethod
def _make_provider():
@@ -1329,13 +1322,9 @@ class TestSessionStartDialecticPrewarm:
class TestDialecticLifecycleSmoke:
"""End-to-end smoke: walks a realistic multi-turn session through every
behavior we care about — prewarm → turn 1 consume trivial skip cadence
fire → silent-failure retry → heuristic bump session-end flush.
This is the 'velvet circuit' test: one provider, one flow, one set of
assertions. If the suite above lies about intent, this one catches it.
"""
"""End-to-end smoke walking a multi-turn session through prewarm,
turn 1 consume, trivial skip, cadence fire, empty-result retry,
heuristic bump, and session-end flush."""
@staticmethod
def _make_provider(cfg_extra=None):
@@ -1473,11 +1462,9 @@ class TestDialecticLifecycleSmoke:
class TestReasoningHeuristic:
"""Restored char-count heuristic for auto-injected dialectic reasoning level.
Pre-9a0ab34c behavior: scale base up by query length, capped at
reasoning_level_cap. 'max' is reserved for explicit tool-path selection.
"""
"""Char-count heuristic that scales the auto-injected reasoning level by
query length, clamped at reasoning_level_cap. 'max' is reserved for
explicit tool-path selection."""
@staticmethod
def _make_provider(cfg_extra=None):

View File

@@ -77,7 +77,7 @@ Cost and depth are controlled by three independent knobs:
| Knob | Controls | Default |
|------|----------|---------|
| `contextCadence` | Turns between `context()` API calls (base layer refresh) | `1` |
| `dialecticCadence` | Turns between `peer.chat()` LLM calls (dialectic layer refresh) | `1` |
| `dialecticCadence` | Turns between `peer.chat()` LLM calls (dialectic layer refresh) | `3` |
| `dialecticDepth` | Number of `.chat()` passes per dialectic invocation (13) | `1` |
These are orthogonal — you can have frequent context refreshes with infrequent dialectic, or deep multi-pass dialectic at low frequency. Example: `contextCadence: 1, dialecticCadence: 5, dialecticDepth: 2` refreshes base context every turn, runs dialectic every 5 turns, and each dialectic run makes 2 passes.
@@ -104,7 +104,7 @@ Honcho is configured in `~/.honcho/config.json` (global) or `$HERMES_HOME/honcho
|-----|---------|-------------|
| `contextTokens` | `null` (uncapped) | Token budget for auto-injected context per turn. Set to an integer (e.g. 1200) to cap. Truncates at word boundaries |
| `contextCadence` | `1` | Minimum turns between `context()` API calls (base layer refresh) |
| `dialecticCadence` | `1` | Minimum turns between `peer.chat()` LLM calls (dialectic layer). In `tools` mode, irrelevant — model calls explicitly |
| `dialecticCadence` | `3` | Minimum turns between `peer.chat()` LLM calls (dialectic layer). In `tools` mode, irrelevant — model calls explicitly |
| `dialecticDepth` | `1` | Number of `.chat()` passes per dialectic invocation. Clamped to 13 |
| `dialecticDepthLevels` | `null` | Optional array of reasoning levels per pass, e.g. `["minimal", "low", "medium"]`. Overrides proportional defaults |
| `dialecticReasoningLevel` | `'low'` | Base reasoning level: `minimal`, `low`, `medium`, `high`, `max` |

View File

@@ -82,7 +82,7 @@ hermes memory setup # select "honcho"
| `workspace` | host key | Shared workspace ID |
| `contextTokens` | `null` (uncapped) | Token budget for auto-injected context per turn. Truncates at word boundaries |
| `contextCadence` | `1` | Minimum turns between `context()` API calls (base layer refresh) |
| `dialecticCadence` | `1` | Minimum turns between `peer.chat()` LLM calls. Only applies to `hybrid`/`context` modes |
| `dialecticCadence` | `3` | Minimum turns between `peer.chat()` LLM calls. Only applies to `hybrid`/`context` modes |
| `dialecticDepth` | `1` | Number of `.chat()` passes per dialectic invocation. Clamped 13. Pass 0: cold/warm prompt, pass 1: self-audit, pass 2: reconciliation |
| `dialecticDepthLevels` | `null` | Optional array of reasoning levels per pass, e.g. `["minimal", "low", "medium"]`. Overrides proportional defaults |
| `dialecticReasoningLevel` | `'low'` | Base reasoning level: `minimal`, `low`, `medium`, `high`, `max` |
@@ -181,7 +181,7 @@ This inherits settings from the default `hermes` host block and creates new AI p
},
"dialecticReasoningLevel": "low",
"dialecticDynamic": true,
"dialecticCadence": 1,
"dialecticCadence": 3,
"dialecticDepth": 1,
"dialecticMaxChars": 600,
"contextCadence": 1,