Releases: lyc-aon/successor-agent
Release list
v0.1.39 — z.ai vision wiring + browser verification loop fix
v0.1.39 — 2026-04-17
GLM / z.ai subscription vision wiring, browser verification loop fix,
and Anthropic tool_result wire format correction. Driven by a real
GLM 5.1 repro where the model got stuck reopening the same page 4-5
times in a row during a verification run.
What changed
-
z.ai vision auto-wiring. The
z.aipreset now carries a
tool_defaults.visionblock pointing atglm-4.6von the same
Anthropic-compatible endpoint that covers the GLM Coding Plan
subscription. Picking that preset insuccessor setupand enabling
thevisiontool wires it end-to-end with zero manual config. Model
choice is deliberate:glm-5v-turbo+/paas/v4is pay-as-you-go
and not covered by the subscription;glm-4.6v+/api/anthropic
is. -
New
VISION_PROVIDER_OPTIONSvalue:anthropic. The vision
tool now supports an Anthropic-compatible dispatch path that posts
to{base_url}/v1/messageswith Anthropic-style image content
blocks (source.{type:"base64", media_type, data}) andx-api-key
auth. Alongside the existingllamacppandopenai_compatpaths. -
Primary-client API key fallback for vision. If the vision
block'sapi_keyis empty, the harness now reuses the active chat
provider's key. Users drop their z.ai key in the provider block
once; the vision tool picks it up automatically. -
New bundled profile:
zai.json. Ships with GLM 5.1 as the
text brain on the Anthropic endpoint and vision routed to
glm-4.6von the same endpoint. Zero-config starting point for
z.ai users. -
ProviderPreset.tool_defaultsfield. New optional
dict[str, dict]mirroringProfile.tool_config. Lets any preset
carry paired tool defaults that flow into new wizard-created
profiles automatically for whichever tools the user enables.
Extensible to browser/holonet/etc. in one-line preset edits. -
Browser verification loop fix. The
browser_runtimeguidance
is now one-shot per user turn instead of re-injected every agent
tick — free-code's memoized-per-session approach, applied to the
turn scope. Repeated re-injection of the verification recipe was
actively keeping capable models (GLM 5.1, Claude) from
self-terminating when their contract was already satisfied. -
Hard refusal on 5th identical browser
open. Previously the
tracker appended the same polite "you reopened the same page"
progress note on every repeat, which the model could ignore
indefinitely. Now the 5th consecutiveopenof the same target
with unchanged state returnsexit_code=1with a clear "Refused:
Nth consecutive open, reply with plain text" stderr. Different
target or state-changed open resets the streak. -
Contract-settled one-shot nudge. When the verification ledger
transitions from has-open-items → all-passed within a user turn,
the harness queues a single "You're done. Reply with plain text
now. Do not run additional browser, screenshot, or vision calls
unless the user asks." Consumed on emit. Gives capable models a
clear stop signal that never existed before. -
Removed "consider more edge cases" and "launch verifier
subagent" nudges. Three lines inverification_contract.pyand
web/verification.pykept re-appearing every turn even after the
contract was all-passed, training the model to always do more.
Free-code has no equivalent; the contract's existence is
sufficient signal. -
Anthropic tool_result wire format fix. Previously each
role="tool"log message became its own{"role": "user"}with a
singletool_resultblock, producing a malformed sequence when
one assistant turn emitted multiple tool_use blocks. Now
consecutive tool results coalesce into one user message with N
tool_resultblocks per Anthropic spec, matching free-code. Also
added a native-tool discriminator inLogMessage.to_api_dict():
non-bash cards with atool_call_idemitrole="tool"for
proper structured wire format; bash keeps its text-fence flatten
for llama.cpp chat-template compatibility. -
Version-aware
_api_rootregex. Bothproviders/openai_compat.py
andweb/vision.pynow recognize any/vNpath segment (not just
/v1) when normalizing a base URL. Latent bug that produced
…/paas/v4/v1/models404s for non-v1 versioned endpoints like
z.ai's/paas/v4.
Verification
pytest -q— 1377 passed- End-to-end probe against z.ai with a real subscription key confirms
the Anthropic vision dispatch returns 200 on the first call
(billing passthrough, no 429s). - New tests cover: preset
tool_defaultspropagation via the wizard,
settled-nudge emission, 5th-identical-open refusal, anthropic
tool_result batching, and the native-tool vs bash-text
discriminator into_api_dict.
v0.1.38 — Agent Loop Hardening + Compaction Overhaul
What changed
Driven by real small-model testing with Qwen 3.6-35B-A3B on local compute.
Interrupt handling
- Ctrl+C double-press — first press interrupts the running stream/tools/compaction, second press within 800ms exits cleanly. No more instant-kill.
Browser tool
js_evalaction —page.evaluate()for running arbitrary JavaScript against the live page. Read DOM state, call functions, inspect variables directly.- Screenshot loop prevention — read-only actions no longer reset the stagnant-state counter. Screenshot streak detector nudges after 3+ consecutive screenshots. Action-repeat tracker nudges after 3+ identical calls.
File tools
edit_fileworks after partial reads — no longer requires a fullread_filefirst. Partial reads accepted; old_string match against disk content is the safety check.
Compaction overhaul
Four changes that collectively double the usable context runway between compaction cycles:
- Tool outputs in kept rounds cleared during compaction (keeps 4 most recent, replaces older ones with placeholders)
- Microcompact keeps 4 most recent tool results (was 8)
- System prompt measurement uses the full assembled prompt instead of the short profile prompt
- Default
keep_recent_roundslowered from 6 to 2 for tool-heavy profiles
Vision
- Thinking-model fix — falls back to
reasoning_contentwhencontentis empty (fixes Qwen 3.x analysis). Defaultmax_tokensraised to 16384.
Testing infrastructure
- New
scripts/sandbox_runner.py+scripts/sandbox_scenarios.py— 4-tier E2E testing framework for small-model behavior observation.
Verification
ruff check src tests— all cleanpytest -q— 1362 passed
v0.1.36 - KV-friendly prompt assembly hotfix
This hotfix fixes a real performance regression in long local-model sessions: Successor now preserves a KV-cache-friendly request shape instead of quietly rewriting earlier prompt bytes as the conversation grows.
What changed
- made prompt assembly append-only in the places that matter for local cache reuse
- runtime-tail context is now always appended as its own synthetic turn instead of being merged into the latest real user message
- adjacent same-role API messages now preserve their original boundaries instead of being merged together later
- stabilized native tool-call serialization
- assistant
tool_calls[].function.argumentsnow use canonical JSON ordering so identical tool payloads serialize to identical bytes
- assistant
- added better cache-shape diagnostics
- turn traces and
/perfnow record request prefix hash, full request hash, and tail kind alongside the existing stable-system hash and llama timing data - this makes it possible to distinguish harness-side request-shape churn from provider-side cache dropout
- turn traces and
Verification
ruff check src testsPYTHONPATH=src pytest -q1277 passed in 25.56s
- live llama.cpp KV verification
- before fix: repeated late-turn
cache_n=0, median first-token latency ~34s, suspected KV misses across many turns - after fix:
cache_ngrows turn-to-turn, hit ratio stays roughly 0.8–0.94, and first-token latency stays sub-second in the extended local-model session
- before fix: repeated late-turn
v0.1.35 - semantic tool cards and compaction floor fix
This release tightens the tool-card surface so long iterative runs are
easier to read while they are happening and easier to trust after the
fact.
What changed
- semantic streamed tool previews are now first-class instead of
bash-biased placeholders- in-flight native tool calls keep stable glyphs and labels while
their arguments stream in - unknown streamed tools now render as explicit unsupported/pending
states instead of temporarily pretending to be bash - the live
↳ toolpreview now attaches directly below the assistant
text without the old stray spacer/cursor line
- in-flight native tool calls keep stable glyphs and labels while
- task and verification cards now use richer card-native rendering
- full task/proof lists are always shown instead of being clipped by
the generic tool-output cap - task and verification rows now have status-specific treatment for
completed, active/running, pending, and failed states - card headers now carry summary badges like
4 tasks,1 active,
3 checks, and1 failed
- full task/proof lists are always shown instead of being clipped by
- verification can now annotate the earlier step it actually judged
- after a
verifyupdate, the most recent substantive prior tool
card gets a retroactive proof badge such asverifiedor
proof failed
- after a
- manual compaction now uses the real structural minimum instead of the
old fake 4-round gate- 2-round sessions can compact when there is one older round to
summarize and one newer round to keep - the stale
Run /burn first to inflate the contextrefusal path is
gone
- 2-round sessions can compact when there is one older round to
Verification
ruff check src testsPYTHONPATH=src pytest -q1275 passed in 25.33s
- render-level visual verification:
- semantic streaming preview matrix
- paper/steel task + verify card inspection
- retroactive proof badge inspection on prior tool cards
- chat-level visual artifacts:
/tmp/successor-proof-renders/verified-paper-light-final.png/tmp/successor-proof-renders/failed-steel-dark-final.png
v0.1.34 — history browser + live stream scroll
This release tightens one of the last rough edges in the terminal UX: prompt recall, wheel scrolling, and live stream rendering now stop fighting each other.
What changed
- replaced shell-style empty-prompt history recall with a dedicated prompt-history browser
Ctrl+Rand/history [query]now open a centered overlay with filter-as-you-type recall, preview, and draft restoration onEsc- bare
↑/↓are now pure scroll keys again
- restored alternate-scroll behavior when
mouse offis active- Successor now enables DECSET
?1007when it is not capturing the mouse, and turns it back off whenmouse onreclaims wheel events
- Successor now enables DECSET
- made live stream rows part of the scrollable viewport
- while the model is thinking or responding, the visible stream rows now contribute to scroll headroom instead of temporarily pinning the viewport harder than the committed transcript
- added first-class prompt/KV diagnostics on top of the cache-friendly llama.cpp loop
- completed stream trace events now record first-token latency, total stream latency, raw provider timings, prompt cache hit ratio, and a conservative suspected-KV-miss flag
/perfwith/kvalias reports the last few completed turns with slot id, stable hash,cache_n,prompt_n, and prompt-eval timing
Verification
ruff check src testsPYTHONPATH=src pytest -q1254 passed in 25.23s
- focused interaction coverage:
- prompt-history browser open/filter/accept/restore paths
- terminal alternate-scroll toggle behavior in
mouse off - live-stream scroll headroom while the model is still talking
v0.1.33 - cache-friendly llama.cpp agent-loop release
v0.1.33, cache-friendly llama.cpp agent-loop release (2026-04-10)
This release turns Successor's local-model loop into something that is
KV-cache-friendly by design instead of by luck.
The core change is architectural: the request builder now keeps the
cache-critical system prefix stable across ordinary turns, moves
volatile ledger/reminder state to a tail context message, and makes the
llama.cpp cache/slot path explicit instead of relying on server
defaults. The budget UI, fill bar, and autocompact gate also now read
from the same canonical outbound request envelope, so context reporting
tracks what the harness actually sends.
What landed
src/successor/chat_agent_loop.py- splits prompt assembly into a stable system bundle and volatile
tail-only runtime sections - caches the stable rendered prompt on the chat instance
- records stable/volatile hashes and cache metadata in trace events
- keeps one-turn reminders, ledger/runtime nudges, and other
per-turn state out of the cache-critical front of the prompt
- splits prompt assembly into a stable system bundle and volatile
src/successor/context_usage.py- new canonical request-envelope layer used for both prompt assembly
accounting and runtime budget reporting - tracks stable-system hash, volatile-tail hash, cache-break reasons,
slot id, and prompt-cache preference per turn
- new canonical request-envelope layer used for both prompt assembly
src/successor/providers/llama.py- explicitly sends
cache_prompt=true - supports preferred
id_slotwhen llama.cpp exposes slot support - adds exact
/tokenizesupport for llama-backed token accounting
- explicitly sends
src/successor/chat.py- applies provider cache preferences on live client/profile changes
- reserves a foreground slot for the parent chat when slot-aware
background scheduling is available - aligns post-compact cache-warmer behavior with the deferred-turn
resume path
src/successor/subagents/manager.py- routes child chats onto non-foreground slots when available
- claims and releases child slot affinity explicitly
src/successor/tasks.py- splits stable task primer guidance from volatile execution state
src/successor/verification_contract.py- splits stable verification primer guidance from volatile runtime
verification state
- splits stable verification primer guidance from volatile runtime
src/successor/runbook.py- splits stable experiment/runbook primer guidance from volatile
attempt/runtime state
- splits stable experiment/runbook primer guidance from volatile
src/successor/providers/openai_compat.py- preserves tool-call fields and
tools=handling so the generic
OpenAI-compatible path stays coherent with the new request envelope
- preserves tool-call fields and
- docs
- adds:
docs/chat-agent-loop-refactor-plan.mddocs/chat-display-runtime-refactor-plan.md
- updates:
docs/chat-runtime-refactor-plan.mdREADME.mdCHANGELOG.md
- adds:
Release verification
- lint:
ruff check src tests
- full suite:
PYTHONPATH=src pytest -q1256 passed in 25.00s
- live supervised E2E:
- workspace:
/home/lycaon/Desktop/successor-kv-cache-e2e-20260410
- trace:
/home/lycaon/.config/successor/logs/20260410-142431-p898945.jsonl
- app:
/home/lycaon/Desktop/successor-kv-cache-e2e-20260410/command-cascade.html
- screenshots:
/tmp/command-cascade-initial.png/tmp/command-cascade-autoplay.png
- observed cache behavior:
- stable system hash remained
e13605d528a0 - volatile tail hash changed independently across turns
- llama requests carried
cache_prompt=true - foreground chat stayed on slot
0
- stable system hash remained
- observed runtime behavior:
- the model adopted
taskandverify - the model authored the app with native file tools
- the model found and fixed a real runtime logger bug on its own
- independent Playwright verification passed for:
- start screen load
- start-game transition
- correct-command scoring
- autoplay/debug flow
- the model adopted
- remaining limitation surfaced by the run:
- browser
typestill failed on a custom input control and the
supervised loop spent too long retrying selector variants instead
of pivoting immediately to a deterministic fallback
- browser
- workspace:
v0.1.32 - llama.cpp continuation-prefill hotfix
v0.1.32, llama.cpp continuation-prefill hotfix (2026-04-10)
This hotfix fixes a concrete local-model failure in the agent loop:
when Successor auto-continued after an assistant turn that contained no
visible content or after a normal assistant reply while a task or
verification item was still in_progress, the next request could be
sent to llama.cpp with the prompt ending on assistant.
That shape is rejected by llama.cpp thinking mode with:
HTTP 400: Assistant response prefill is incompatible with enable_thinking.
What landed
src/successor/chat_agent_loop.py- adds a transient internal user continuation prefill on outbound
internal re-entry turns when the API-visible history would otherwise
end onassistant - keeps the chat transcript unchanged while making the provider-facing
prompt valid for llama.cpp thinking mode - marks the visible
(no answer — model produced only reasoning)
placeholder as synthetic so it no longer leaks back into model
history
- adds a transient internal user continuation prefill on outbound
- tests
- adds regression coverage for task-ledger continuation,
verification-ledger continuation, and the exact reasoning-only
placeholder path that previously triggered the 400
- adds regression coverage for task-ledger continuation,
Release verification
- lint:
ruff check src/successor/chat_agent_loop.py tests/test_chat_tasks.py tests/test_chat_verification.py
- targeted tests:
PYTHONPATH=src pytest -q tests/test_chat_tasks.py tests/test_chat_verification.py9 passed in 0.22sPYTHONPATH=src pytest -q tests/test_chat_subagents.py tests/test_file_tools.py tests/test_chat_bash.py71 passed in 1.60s
- live llama.cpp verification:
- confirmed a raw assistant-ended prompt still returns
HTTP 400 - confirmed the same prompt succeeds once the internal continuation
user prefill is appended
- confirmed a raw assistant-ended prompt still returns
v0.1.31: task adoption nudges and reserved port guards
Highlights
This release hardens the agent loop around two practical local-model failure modes:
- broad, stateful requests that should start with a task ledger but instead jump straight into file writes
- preview-app serving loops that accidentally kill the live local model endpoint while trying to reclaim a familiar port like
8080
The goal is not fewer turns. The goal is a more reliable default path: plan before mutating, verify before stopping, and choose another free port before reclaiming a live runtime.
What Landed
- new long-horizon task-adoption nudges for broad, multi-step, stateful, browser-heavy, and supervised requests
- bounded planning reminders in the agent loop so the model adopts the session task ledger before substantive mutation, process-management, or browser loops
- reserved-port guardrails that refuse obvious kill/reclaim commands targeting the active local provider endpoint
- stronger bash guidance: prefer native file tools for source work, pick another free port instead of blindly reclaiming
8080, and only stop a process when it is clearly yours or the user asked - stronger task and browser-verification guidance so process management and runtime proof paths are explicit earlier
- updated README, file-tools docs, changelog, and version metadata
Verification
ruff checkpassed on the shipped slice- targeted pytest verification passed:
66 passed - supervised live E2E run completed successfully against the local model
- model adopted
taskbefore the first file mutation - model used native
write_filefor all authored files - model served the preview app on
8083instead of touching the provider on8080 - verification contract finished
4/4 passed
- model adopted
Artifact References
- live supervised trace:
~/.config/successor/logs/20260410-121402-p668167.jsonl - verified workspace:
~/.local/share/successor/e2e/supervised-ledger-port-guard-run/
v0.1.30
Highlights
- Added repo-aware final-mile verification hints and stricter verifier-worker support.
- Added stateful/runtime verification nudges so games and other realtime tasks are pushed toward a deterministic driver or autoplay harness plus an observable debug surface.
- Continued the
chat.pycleanup by extracting the display, agent-loop, and tool-runtime seams while keeping the existingSuccessorChatsurface intact. - Updated README and local docs to reflect the stronger runtime verification workflow.
Verification
ruff check src testsPYTHONPATH=src pytest -q1243 passed in 12.71s
- Live supervised E2E bundle:
~/.local/share/successor/e2e/stateful_verify_snake_adoption/
Note
The new stateful verifier-adoption layer improves behavior, but it is not yet a hard guarantee that the model will synthesize the best deterministic driver on its own. The release includes that improvement and keeps the remaining gap explicit in trace and playback artifacts.
Successor v0.1.29
v0.1.29, chat render seam extraction + visual verification harness (2026-04-09)
This pass reduces the risk surface inside src/successor/chat.py
without changing the underlying renderer methodology. The render
primitives, diff layer, and terminal ownership model stay intact; the
chat scene composition gets extracted into dedicated render modules with
new seam tests and explicit visual verification.
What landed
src/successor/render/chat_frame.py- layout dataclasses and frame partition helpers
src/successor/render/chat_header.py- header composition and widget placement
src/successor/render/chat_viewport.py- viewport math, body-width policy, and scroll decisions
src/successor/render/chat_intro.py- intro hero + info rail painting
src/successor/render/chat_overlays.py- help overlay and slash-command dropdown painters
src/successor/render/chat_input.py- input/search/footer painters
src/successor/render/chat_rows.py- extracted row rendering and card flattening helpers
src/successor/chat.py- now delegates scene composition into render modules while remaining
the controller/runtime owner
- now delegates scene composition into render modules while remaining
tests/test_chat_render_layout.py- seam coverage for layout and paint routing
tests/test_chat_render_viewport.py- seam coverage for viewport math and streaming row placement
- docs
- updated
README.md - updated
docs/chat-render-refactor-plan.md - updated
docs/changelog.md
- updated
Verification
- lint:
ruff check src/successor/chat.py src/successor/render/chat_*.py tests/test_chat_render_layout.py tests/test_chat_render_viewport.py
- bytecode:
PYTHONPATH=src python3 -m compileall src/successor
- focused render slice:
PYTHONPATH=src pytest -q tests/test_snapshot_themes.py tests/test_intro_art.py tests/test_intro_sequence.py tests/test_chat_perf.py tests/test_chat_mouse.py tests/test_chat_paste.py tests/test_compaction_animation.py tests/test_playback.py tests/test_terminal.py tests/test_chat_render_layout.py tests/test_chat_render_viewport.py129 passed in 5.10s
- full suite:
PYTHONPATH=src pytest -q1227 passed in 12.34s
- headless human-emulated runtime verification:
- drove
?,/theme paper,/mode light,/density spacious,
/budget,/bash printf 'render-check\n', and two live model turns
throughSuccessorChat.on_key()+on_tick()withRecordingBundle - generated intro/help/autocomplete/runtime playback screenshots and
visually confirmed bounded artboard layout, centered help modal,
input-edge slash palette, and paper/light runtime composition
- drove