v0.2.12
Agentao 0.2.12
0.2.12 ships the Headless Runtime v1 contract for ACPManager —
the non-interactive embedding target described in
docs/features/headless-runtime.md —
together with the Week 2 diagnostics surface, the Week 3
InteractionPolicy model, and the Week 4 lifecycle / recovery story.
A second, independent track lands in the same release: the
/crystallize evidence + feedback loop, which grounds skill-draft
generation in actual tool activity and adds a durable user-feedback
rewrite path.
Two breaking changes ride along: ACPManager.get_status() converges on
the typed list[ServerStatus] shape, and .agentao/acp.json no longer
accepts the bare-string form of nonInteractivePolicy. Migration
guidance is in the changelog entry and in developer-guide appendix E.7.
Highlights
- Public headless entry points:
prompt_once,send_prompt, with
single-active-turn concurrency pinned toAcpErrorCode.SERVER_BUSY.
send_prompt_nonblockingis classified internal / unstable and is
not part of the embedding contract. - Typed status snapshot (
ServerStatus): v1 core fields —
server/state/pid/has_active_turn— extended additively
by Week 2 diagnostics (active_session_id,last_error,
last_error_at,inbox_pending,interaction_pending,
config_warnings). ACPManager.readiness(name)/.is_ready(name): typed 4-valued
gating signal ("ready" | "busy" | "failed" | "not_ready") — prefer
over string-matching onstate.InteractionPolicy+interaction_policy=override on
send_prompt/prompt_once: per-call override wins over the server
default (nonInteractivePolicy);Nonefalls back to the default.- Lifecycle & recovery: deterministic release order on every
failure path,classify_process_deathpure classifier, sticky
is_fatal(name)/restart_count(name)surfaces,
AcpServerConfig.max_recoverable_restarts(default 3). - Daemon-style regression suite pinned in
tests/test_headless_runtime.py::TestDaemonRegression. /crystallizeevidence + feedback loop:SkillEvidenceand
SkillFeedbackEntrydataclasses extendSkillDraftwith structured
tool-activity grounding (tool calls, results, key files, workflow
steps) and a durablefeedback_history.collect_crystallize_evidence
/render_crystallize_contextproduce the evidence block;
feedback_prompt+FEEDBACK_SYSTEM_PROMPTdrive user-feedback
rewrites.suggest_prompt()andrefine_prompt()gained an optional
evidence_text=so all three prompts share the same grounding. Draft
JSON is forward- and backward-compatible (legacy payloads load with
empty evidence/history). Covered by
tests/test_skill_crystallize_enhancement.py(15 tests).
See the CHANGELOG.md [0.2.12] entry for the
full Added / Changed breakdown including the two breaking changes.
Breaking Changes
ACPManager.get_status()returnslist[ServerStatus](not
list[dict]). The legacy"name"dict key becomes
ServerStatus.server. Noget_status_typed()side channel and no
permanent dict alias — this is a one-shot convergence.nonInteractivePolicybare-string config form is removed.
.agentao/acp.jsonmust use the structured object form —
"nonInteractivePolicy": {"mode": "reject_all" | "accept_all"}.
Bare strings raiseAcpConfigErrorat config-load time.
Migration: see
developer-guide appendix E.7
(zh mirror exists).