Skip to content

feat(memory): s02/s15 honour per-stage model override via unified client#45

Merged
CocoRoF merged 1 commit intomainfrom
feat/memory-stages-use-model-override
Apr 21, 2026
Merged

feat(memory): s02/s15 honour per-stage model override via unified client#45
CocoRoF merged 1 commit intomainfrom
feat/memory-stages-use-model-override

Conversation

@CocoRoF
Copy link
Copy Markdown
Owner

@CocoRoF CocoRoF commented Apr 21, 2026

Replaces #41 (auto-closed when its base branch was deleted on merge). Rebased onto main.

Summary

  • s02 Context gets LLMSummaryCompactor(SummaryCompactor) that routes through state.llm_client with the resolved ModelConfig when an override and client are both set. Otherwise falls back to the placeholder summary (no regression).
  • s15 Memory grows a ReflectionResolver dataclass. GenyMemoryStrategy._reflect resolves in priority: user callback → native resolver+client → deferred needs_reflection flag.
  • Both stages flip model_override_supported=True so UIs can honestly surface a model-selector.
  • Failures fall back to the placeholder/queue and emit memory.compaction.llm_failed / memory.reflection.llm_failed.

Test plan

  • 13 new tests across test_llm_summary_compactor.py (6) and test_strategy_native_reflect.py (7).
  • test_introspection.py extended: _MODEL_OVERRIDE_STAGES = {"s02_context", "s06_api", "s15_memory"}.
  • Full suite: 1111 passed, 18 skipped.

Original PR: #41. Part of cycle 20260421_4 (plan 05).

🤖 Generated with Claude Code

s02 Context gets an LLMSummaryCompactor that calls state.llm_client
with the resolved ModelConfig when the stage carries a model override
and a client is attached — otherwise it falls back to the placeholder
summary, preserving existing behavior. Failures of the LLM path fall
back to the same placeholder and emit memory.compaction.llm_failed.

s15 Memory grows a ReflectionResolver that lets GenyMemoryStrategy
run a native JSON-reflection pass against state.llm_client when no
custom callback was provided. The three-mode resolution order is:
user callback → native resolver+client → deferred needs_reflection
flag (unchanged pre-cycle behavior when resolver is absent).

Both stages flip model_override_supported=True in introspection so
UIs can surface a model selector without the capability flag lying.

- src/geny_executor/stages/s02_context/artifact/default/compactors.py:
  add LLMSummaryCompactor(SummaryCompactor) — closures for resolve_cfg
  / has_override / client_getter keep the compactor decoupled from the
  stage class.
- src/geny_executor/memory/strategy.py:
  ReflectionResolver dataclass + native _reflect path with JSON-fence
  stripping, should_save gating, memory.reflection.native event.
- src/geny_executor/core/introspection.py:
  _STAGE_CAPABILITIES extended with s02_context / s15_memory.
- tests/unit/test_llm_summary_compactor.py (6 tests) +
  tests/unit/test_strategy_native_reflect.py (7 tests): cover every
  gate — no override, override+no client, override+client, callback
  wins, should_save=False, JSON parse error, no-resolver back-compat.
- tests/unit/test_introspection.py:
  extend _MODEL_OVERRIDE_STAGES to {s02_context, s06_api, s15_memory}
  and add positive assertions for s02/s15.

Suite: 1111 passed, 18 skipped.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@CocoRoF CocoRoF merged commit 4d5f93f into main Apr 21, 2026
7 checks passed
@CocoRoF CocoRoF deleted the feat/memory-stages-use-model-override branch April 21, 2026 09:28
@CocoRoF CocoRoF mentioned this pull request Apr 21, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant