Releases: CocoRoF/geny-executor
v0.29.0 — Unified LLM client + per-stage model routing
Minor release bundling cycle 20260421_4.
Highlights
PipelineState.shared+Stage.local_state(state)— pipeline-lifetime shared scratchpad and per-stage scratchpad convention. Ergonomic replacements for stuffing working state intostate.metadata.Stage.resolve_model_config(state) -> ModelConfig— full sampling + thinking bundle (not just a model string). Honoured by every stage that calls an LLM in this release.geny_executor.llm_client— new top-level package withBaseClient,ClientCapabilities,ClientRegistry, and per-vendorAnthropicClient/OpenAIClient/GoogleClient/VLLMClient. One surface for all LLM calls; feature-detection via capability flags; unsupported fields silently dropped withllm_client.feature_unsupportedevents.state.llm_client— optionalBaseClientslot populated viaPipeline.attach_runtime(llm_client=…). Any stage reaches for it when it needs an LLM.PipelineMutator.set_stage_model(order, cfg)— public entry point for per-stage model overrides (raisesMutationErroron missing order).- s06_api on the unified client. The per-vendor
APIProviderartifact system is deleted;APIStagenow selects viaprovider: strconfig +state.llm_client. - Memory stages honour overrides. s02
LLMSummaryCompactorreplaces the placeholder stub; s15ReflectionResolvergivesGenyMemoryStrategya native reflection path. Both consumestate.llm_clientwhen aModelConfigoverride is installed; both stay cost-free when no override is present.
Breaking changes
The per-vendor APIProvider classes under stages/s06_api/artifact/{default,openai,google}/providers.py are deleted. Hosts that constructed them directly switch to ClientRegistry.get(provider)(api_key=…, base_url=…) and inject via attach_runtime(llm_client=…). Geny does this in cycle-4 PR-6 (Geny 16690d7).
See CHANGELOG.md for the complete Added / Changed / Removed / Upgrade notes.
Merge provenance
v0.28.0 — L0 recent-turns retriever layer
Highlights
GenyMemoryRetriever gains a new L0 recent turns layer that injects the tail of the short-term-memory transcript verbatim before any semantic/keyword matching runs. The goal is to restore conversational continuity on trigger-style turns — idle reflection, sub-worker auto-reports, and inter-agent DMs — whose query text has no lexical overlap with the prior dialogue and would otherwise miss the last few turns entirely.
API
GenyMemoryRetriever(..., recent_turns: int = 6)— controls tail size; pass0to disable.- Layer budget is capped at 40% of
max_inject_charsso downstream layers (session summary, MEMORY.md, vector, keyword, backlink, curated) still fit. - Entries inject verbatim as
[<role>] <content>lines, readingmetadata["role"]from each STM entry (falling back to"user"), so new roles such asinternal_triggerandassistant_dmflow through unmodified.
Tests
- 7 new cases in
tests/unit/test_geny_retriever_recent_turns.py - Full unit suite green: 615 passed
- Lint, security, and 3.11/3.12/3.13 build matrix all green on PR #36
See CHANGELOG.md for the full notes.
v0.26.0 — attach_runtime(system_builder, tool_context)
Additive release. Extends Pipeline.attach_runtime(...) with two new kwargs:
system_builder→ Stage 3 (System) slotbuilder. Lets hosts attach multi-blockPromptBuilderinstances (e.g.ComposablePromptBuilderofPersonaBlock+DateTimeBlock+MemoryContextBlock) that cannot be serialized into a manifest.tool_context→ Stage 10 (Tool)_contextattribute. Lets hosts supply session-scopedToolContext(withworking_dir/storage_path/ etc.) that is allocated at session-creation time.
Both kwargs are additive on top of the v0.24.0 memory_* kwargs — no breaking changes. Manifest-built pipelines now carry every session-scoped runtime object through one call.
Tests
tests/unit/test_pipeline_attach_runtime.py — 6 new tests (14 total, all passing). Full suite: 1035 passed, 18 skipped. Ruff clean.
Why
Prerequisite for Geny's master-plan PR 17 (Geny/dev_docs/20260420_3/plan/02_default_env_per_role.md) — the last PR of Phase 2, which collapses AgentSession._build_pipeline into a single attach_runtime call.
v0.25.0 — binary_classify in default registry
Register binary_classify
Additive release. Makes the adaptive binary_classify evaluation strategy resolvable from EnvironmentManifest without import-time plumbing.
Added
binary_classifyin the defaultEvaluateStagestrategy slot registry — manifests withstrategies={\"strategy\": \"binary_classify\"}now restore to a realBinaryClassifyEvaluationinstance.BinaryClassifyEvaluation.configure(config)— applieseasy_max_turnsandnot_easy_max_turnsfrom manifeststrategy_configs.
Why
Unblocks Geny's manifest-first cutover (PR 10 of the 20260420_3 cycle): serializing the worker_adaptive preset through an EnvironmentManifest no longer silently degrades to signal-based evaluation.
Backwards compatibility
No breaking changes. The adaptive artifact remains strategy-only; its import path is unchanged. The default registry keeps every pre-existing strategy.
Tests
tests/unit/test_binary_classify_manifest.py — 6 new tests.
Full suite: 1029 passed, 18 skipped.
PR: #31
v0.24.0 — Pipeline.attach_runtime()
Pipeline.attach_runtime()
Additive release. Introduces a single explicit injection point for the session-scoped runtime objects that EnvironmentManifest cannot express (memory retriever, memory update strategy, conversation persistence).
Added
-
Pipeline.attach_runtime(*, memory_retriever=None, memory_strategy=None, memory_persistence=None)— walks registered stages and replaces the relevant slot strategies:memory_retriever→ Stage 2 (Context), slotretrievermemory_strategy→ Stage 15 (Memory), slotstrategymemory_persistence→ Stage 15 (Memory), slotpersistence
Kwargs are keyword-only. Omitted kwargs preserve the prior slot. Missing stages are silently skipped.
-
Pipeline._has_startedflag.attach_runtimeraisesRuntimeErrorafter the firstrun()/run_stream()call — prior stage state has already captured slot references.
Backwards compatibility
No breaking changes. Pipelines that never call attach_runtime behave identically to 0.23.0. GenyPresets.worker_adaptive(...) / GenyPresets.vtuber(...) builders remain unchanged.
Tests
tests/unit/test_pipeline_attach_runtime.py — 8 new tests.
Full suite: 1023 passed, 18 skipped. Ruff + format clean.
PR: #30
v0.23.0 — per-call tool events
Additive release on top of 0.22.1. Extends the Stage 10 tool event vocabulary with per-call events so downstream log consumers can render the input, outcome, and latency of individual tool calls.
Non-breaking. Existing tool.execute_start / tool.execute_complete summary events are preserved byte-for-byte. Consumers that listen only to tool.execute_* see no behavior change. Third-party ToolExecutor implementations continue to work without modification.
Added
tool.call_startevent — fired before each dispatch, payload{tool_use_id, name, input}.tool.call_completeevent — fired after each dispatch, payload{tool_use_id, name, is_error, duration_ms}.on_eventkeyword-only kwarg onToolExecutor.execute_all(...). Shape:Callable[[str, dict], None]. The defaultToolStagewires it tostate.add_event.ToolEventCallbacktype alias ingeny_executor.stages.s10_tool.interface.
Why
Host-side log UIs need the per-call input dict to render a call-by-call detail pane. The 0.22.1 summary events omit this, and the pipeline-internal pending_tool_calls field is not a stable event contract. This release upgrades the contract so hosts can stop reaching into pipeline state.
Tests
1015 passed, 18 skipped. 6 new tests in tests/unit/test_tool_call_events.py covering sequential ordering, parallel pairing by tool_use_id, is_error propagation, on_event=None no-op, and nesting inside tool.execute_* brackets.
PR: #29
v0.22.1
CI hygiene patch on top of v0.22.0. No runtime behavior change — same public API, same import surface, identical test outcomes (1003 passed, 5 skipped).
Fixed
ruff checknow passes onmain: dropped two unused imports that slipped through the 0.22.0 PRs (ToolErrorintools/mcp/adapter.py,MCPServerConfigintests/unit/test_adhoc_providers.py). (#27)ruff format --checknow passes onmain: eleven files that the 0.22.0 PRs touched diverged from the project's default ruff formatter; appliedruff formatso CI stays green. (#28)
Upgrade note
Geny pin moves from >=0.22.0,<0.23.0 to >=0.22.1,<0.23.0 in the follow-on Geny bump PR so downstream installs pick up the cleaned-up release.
v0.22.0 — Tool / MCP integration hardening
Tool / MCP integration hardening release. Bundles four breaking changes into a single atomic bump so downstream hosts can pin geny-executor>=0.22.0,<0.23.0 in one cutover.
Breaking
- MCP tool names are always
mcp__{server}__{tool}(no bare names). - MCP lifecycle is fail-fast — broken servers block session start with
MCPConnectionError. MCPServerConnection.call_toolreturn type expanded tostr | list[dict].ToolRegistry.registerwarns on same-name-different-instance.- Default router emits structured
{error: {code, message, details}}payloads; plain-string error content is gone.
Additive
ToolError/ToolFailure/ToolErrorCodestructured error model +validate_inputjsonschema helper.Pipeline.from_manifest_async— MCP-aware async entry point.MCPManager.add_server/remove_serverwith registry sync.AdhocToolProviderProtocol +ToolsSnapshot.externalwhitelist for host tools that can't round-trip throughAdhocToolDefinition.Pipeline.from_manifest[_async](adhoc_providers=, tool_registry=)kwargs.
Dependency
- Adds
jsonschema>=4.0.
PRs
- #22 structured
ToolError+ jsonschema validation - #23
mcp__namespace prefix - #24 MCP fail-fast lifecycle +
from_manifest_async - #25
AdhocToolProvider+tools.external - #26 release chore
See CHANGELOG.md for migration notes.