sync: 0.2.2 Task subagent kind, skill inject budget, claude 2.1.236 - #85
Merged
Conversation
- return the complete terminal snapshot from the bounded output polling helper - wait for expected output before asserting after `wait_for_exit` - apply the same synchronization to all terminal tests with the same timing assumption - preserve exact output, truncation, exit-status, and working-directory assertions - `cargo test -p aionui-ai-agent --lib terminal::tests::output_byte_limit_truncates_from_front -- --exact` - target test repeated 100 times - `cargo test -p aionui-ai-agent` - `cargo clippy -p aionui-ai-agent -- -D warnings` - `just push -u origin fix/terminal-output-test-race` (8,546 passed; 50 skipped) Co-authored-by: zynx <>
Moves `VERIFIED_CLAUDE_VERSION` from 2.1.235 to 2.1.236, and **discharges the hold placed on 2026-08-21**. | Gate | Result | | --- | --- | | A — contract | DEGRADED — claude publishes no protocol schema; gate B carries the weight | | B — live e2e | **PASS 14/14**, 304.35s | | C — release notes | **CLEAR** — 33 notes, 0 REVIEW | ## Why this one was stuck The constant has been sitting **above** the stable channel for eight days. An earlier version of the detector read npm’s `latest` tag, which for `@anthropic-ai/claude-code` points at the bleeding edge rather than the release most users run, so 2.1.235 was qualified off the `next` channel. Once the detector was corrected to track `stable`, every nightly run reported `drift: behind`, and the standing decision was to hold the floor rather than walk it down — walking it down would have flagged the majority of users (who install via `npm` or the native installer, both ahead of stable) as `Newer`. stable has now caught up and passed it, so the normal flow resumes: ``` stable: 2.1.236 next: 2.1.251 latest: 2.1.250 ``` ## The candidate is proven from the suite log ``` version=2.1.236 (Claude Code) ``` with the drift lines that only appear because the binary disagrees with the not-yet-bumped constant. Run through an npm PATH shim into a temp dir; `~/.local/bin/claude` was read before and after and did not move off 2.1.239. ## Gate C Both flagged notes are usage-credits UI — a Fable 5 first-run prompt auto-selecting a fallback model under Remote Control, and a `/usage` spend row for Team and Enterprise members. Neither is a surface this repo drives. ## Also checked The promotion condition this repo does not machine-check: `THINKING_DISPLAY_MIN_VERSION` is `2.1.191` (`claude_flags.rs:34`), comfortably below the new constant. So nobody on exactly the verified release is told they match while thinking display is silently off. ## Tests The literal verified-release assertion moves with the constant, so a future bump that forgets to re-verify still breaks the test. `cargo test -p aionui-session --lib cli_version`: 14/14. `cargo test -p aionui-ai-agent --lib claude_flags`: 5/5. Clippy clean, fmt clean. Record: `~/aion/protocols/samples/claude-cli/2.1.236/` Constants and record only — no source change. Co-authored-by: zk <>
…ns (iOfficeAI#943) ## Summary Scheduled ACP Registry version sync. Two npx pins drifted since iOfficeAI#941, each backed by a fresh serial ACP probe of the exact pinned version. The diff is the lock file plus the one lock-derived test assertion that embeds codebuddy's version. | backend | package | old → new | initialize | session/new | |---|---|---|---|---| | codebuddy | `@tencent-ai/codebuddy-code` | 2.140.0 → **2.141.0** | ok (protocolVersion 1) | auth required (`-32000`, `data.category: auth`) | | dimcode | `dimcode` | 0.3.21 → **0.3.22** | ok (agentInfo version 0.3.22) | auth required (`-32000`, "Provider credentials are required") | Both meet the release-lock criterion: `initialize` succeeds and `session/new` returns a clearly classified authentication requirement. Probes ran serially with no inherited HOME or credentials, and both entrypoints (`--acp` for codebuddy, `acp` for dimcode) are unchanged from the previous snapshot. **Derived assertion updated:** `registry_npx_lock.rs` pins codebuddy's exact version inside a `--package`-form argument list, so it moves with the lock — `2.140.0` → `2.141.0`. Both outgoing versions were grepped across `crates/**/*.rs` before staging: codebuddy's was the only real assertion, and `0.3.21`'s single hit was a false positive (a `"003421"` string literal in `pairing.rs`, matched because `.` is a regex wildcard). `npx_cache_repair.rs` keeps its own version literals: those are cache-path hash fixtures, not lock assertions, and changing them would break their hash expectations. The other 9 Registry-pinned packages (autohand, deepagents, dirac, glm-acp-agent, grok, kilo, nova, pi, sigit) match the snapshot exactly. Package names and entrypoint args are unchanged for all 11. Drifted but not upgraded: none. `mimo-code` remains the one non-Registry builtin (no `registry_json_id`), excluded from drift reconciliation. dimcode continues to self-report `agentInfo.title` as "DimAgent" against a public listing that says "DimCode" — a standing observation since iOfficeAI#814; no metadata change. ## Registry snapshot - Audit pinned to release tag [`v2026.08.28-e9b1b2d`](https://cdn.agentclientprotocol.com/registry/v1/v2026.08.28-e9b1b2d/registry.json) of `agentclientprotocol/registry`, fetched via the versioned CDN path for reproducibility. - 39 ids in the raw snapshot: no newly listed and no delisted agents versus the baseline. (`antigravity-acp` remains listed and deferred as binary-only since 2026-08-21; `fast-agent` and `minion-code` remain listed but uvx-only and therefore out of scope.) ## Validation - `just migration-check` — pass - `just lint-fix` (`cargo fix` + `clippy --fix --workspace -D warnings`) — clean - `just fmt` — clean - **Local `cargo nextest` intentionally skipped, by standing policy for lock-only bumps** (established 2026-08-11). The Test check on this PR is the authority for this change: the merge decision depends on CI rather than the local run, and this host's load only manufactures timeout-shaped test failures, which nothing in the local steps above is subject to. ## Logging No logging changes: lock version bumps plus one test assertion; existing startup/session error paths already identify a failing agent by backend. Co-authored-by: zk <>
WorkMate 0.2.2 pins VERIFIED_CLAUDE_VERSION to 2.1.236; keep the floor-gate fixture on the same release.
…fficeAI#930) Auto-inject skill descriptions are a per-session resident cost: they are injected into every conversation's skills index and count toward a native CLI's always-on catalog, so their length is paid on every conversation whether or not the skill is used. `aionui-config` alone was 666 chars — 47% of the entire index — because its description duplicated the command list that `aioncore config capabilities` already reports at runtime. This PR brings the three over-budget descriptions under 200 chars and adds a guard so new ones cannot regress. | Skill | description before | after | index entry before | after | | --- | --- | --- | --- | --- | | aionui-config | 666 | **194** | 687 | 215 | | skill-creator | 226 | **186** | 247 | 207 | | officecli | 222 | **194** | 239 | 211 | | cron | 121 | unchanged | 133 | 133 | | session-message | 119 | unchanged | 142 | 142 | | **index entries total** | | | **1453** | **908** | Every description keeps the hooks an agent matches user intent against: what the skill configures or does, which CLI it drives, and when to use it. What was dropped is the enumeration of operation verbs, the second restatement of the same trigger inside `Use when ...`, and behavioural contracts that belong in the skill body and are already documented there. All three are now single-line plain scalars instead of `>-` block scalars, consistent with the other auto-inject skills. New guard `auto_inject_skill_descriptions_stay_within_injection_budget` walks the embedded builtin corpus's `auto-inject/` entries and asserts each parsed description is at most 200 chars. It measures the parsed frontmatter value — what actually gets injected — rather than the raw YAML text. No migration needed: startup sync upserts builtin descriptions into the `skills` table, so the new text propagates on the first launch after the corpus fingerprint changes. Automated: - `cargo test -p aionui-extension` — all green - `cargo test -p aionui-app --test config_cli_e2e --test skills_builtin_e2e` — all green; the static SKILL.md body assertions are unaffected since only frontmatter changed - `cargo clippy -p aionui-extension --all-targets -- -D warnings` — clean - `cargo fmt --all -- --check` — clean - Guard test red/green: with the three descriptions reverted it fails and reports 666 / 222 / 226; with them applied it passes Dev build run-through, covering both skill delivery modes: 1. The built binary embeds only the new text; the old text is absent. 2. Startup re-materialized the builtin corpus purely because the corpus fingerprint changed — no version bump was involved. 3. The materialized on-disk tree and the `skills` table rows both report the new lengths. 4. Native-skills backends, where skills are symlinked into the conversation workspace: the linked SKILL.md files carry the new descriptions, and the prompt contains no skills index — the expected light-mode behaviour for that delivery path. 5. Injected-index backend: the first-message `## Available Skills` block measures 1004 chars, down from 1544, with all five entries showing the new text. - [x] Unit and integration tests for the affected crates - [x] Lint and format gates - [x] Guard test fails on an over-budget description - [x] Dev verification of native-skills delivery - [x] Dev verification of injected-index delivery - [ ] Reviewer sanity check: each shortened description still reads clearly on its own in the skills list UI, which renders the same string The `aioncore config capabilities` contract is hand-maintained and has no completeness assertion against the command tree. That is the more likely source of future drift and is left to a separate change. Co-authored-by: zynx <>
…turn is in flight (iOfficeAI#836) Backend half of the mid-turn interjection feature (frontend: iOfficeAI/AionUi#4012). claude and codex sessions can now receive a user message while a turn is in flight; other backends (antigravity, ACP, aionrs) are completely unchanged. Design spec with measured wire data for every CLI-behavior claim lives in the internal design doc (2026-08-12 mid-turn interjection design, verified against claude 2.1.226/2.1.227 and codex 0.144.6). **T1 — capability bit.** New `Capabilities::supports_midturn_delivery` (default false; claude/codex true; antigravity explicitly false — one process per turn, ignores stdin mid-turn; ACP false). Exposed on `ConversationRuntimeSummary` (serde-defaulted). Neither `accepts_proactive_input` nor `can_queue` goes on the wire — only this single-semantic derived bit. **T2 — command_lifecycle.** claude's `command_lifecycle` frames (echoing the uuid we mint on user frames) parse into `SessionEvent::MessageLifecycle { client_msg_id, phase }` with phases queued/started/completed/cancelled. Unknown states degrade to no event. `MessageLifecyclePhase` never goes on the wire. **T3 — agent-driven turn claim.** `claim_for_agent_turn` (None-when-claimed is the normal case, never 409). The background stream claims an agent-started turn only when a TTL-bounded (30s, spec-justified) pending `MessageLifecycle{Started}` marks it as serving a user message; pure background continuations stay unclaimed so iOfficeAI#758's detached-exec flow keeps the input box usable. `mint_turn_id` moved inside the claim branch. **T4 — mid-turn routing (B5).** Active turn + supporting backend → no claim, no new turn id: codex goes through `turn/steer` (with `clientUserMessageId`; both `-32600` rejections discriminated by message text and locked by tests — turn-ended falls back to a new turn, different-turn retries with the id parsed from the message), claude through the resident stdin. Response is 200 with the current active `turn_id` and `delivered_midturn: true`. Pending confirmation (requires_action) still refuses mid-turn delivery (409). `message.userCreated` now carries `client_msg_id` + `status`; new WS event `message.statusChanged` flips pending→finish when the agent consumes the message. codex `accepts_proactive_input` flipped true (B5 now wired). Skill injection is threaded through the mid-turn path. - TDD throughout; targeted suites green per crate (session 553, conversation 399 lib + integration, app midturn e2e), clippy `-D warnings`, fmt; full pre-push gate green. - Live e2e against real claude 2.1.227: mid-turn send 200 into the active turn, real `command_lifecycle` sequence observed, follow-up serving turn claimed (state stays `running`), pending marker clears, later background continuation stays unclaimed. - Live e2e against real codex 0.144.6: steer ack 200 with same turn id, message consumed mid-turn, status flip observed. - Rejection-text matrix, TTL expiry, claim gating (incl. the iOfficeAI#758 no-claim guard), requires_action 409, and wire-hygiene invariants are all locked by tests. - No migrations; message status reuses existing DB CHECK values (`pending`/`finish`). - Logging: routing decision and claim at `info` (ids only), steer rejection at `warn`; message bodies are never logged. - Merge together with iOfficeAI/AionUi#4012 (frontend gate + badge). Old frontend against this backend is unaffected (additive serde-defaulted fields). --------- Co-authored-by: zk <>
…iceAI#890) A Task subagent and a background bash render identically in the step list. Two changes converged on this: - iOfficeAI#758 folded `local_agent` and `local_bash` into one `CardKind::BackgroundTask`, both headlined `bg task <id> · <clock>`. - iOfficeAI#870/iOfficeAI#872 replaced the bare tool-name column (`Agent` vs `Bash` — the last visible difference) with description-derived labels. After that, a 20-minute foreground Task subagent showed as a wall of flat tool calls under a `bg task` chip, indistinguishable from a background shell (live 2026-08-19). The subagent's internal calls were also un-attributable: the adapter reads the frame-level `parent_tool_use_id` (009 H5), but the pump dropped it at the `ToolCallEventData` boundary, so neither the wire event nor the persisted row carried it. 1. **`SubagentTaskKind::AgentContainer`** — `sniff_task` maps `task_started.task_type: "local_agent"` to it (verified: `tests/fixtures/claude_2.1.169_single_tool_turn.ndjson`; the wire declares foreground and background Tasks the same way). `WorkflowContainer` alone still gates the Finish-suppression roster — turn-holding semantics are unchanged. 2. **`WorkflowCard::new_subagent`** — same card machinery as `new_background`, headline word `subagent` instead of `bg task`. The pump picks it for `AgentContainer` tasks. A Task row now reads `修复 AIONUI-151 桌面 401 恢复 · subagent ae859b22dc5afbdca · 22:25`; a background bash keeps `bg task`. 3. **`ToolCallEventData.parent_call_id`** — `translate_event` now carries the frame's `parent_tool_use_id` on ToolCall/ToolResult frames, and it persists into the `tool_call` row's content. This is the enabler for the frontend to group/indent a subagent's internal steps under its launching Task row (frontend change tracked separately). The field is `skip_serializing_if = None`, so the DB's `json_patch` upsert (`sqlite_conversation::upsert_message`) never erases stored attribution when a later parentless frame — the terminal `tool_result`, a card refresh, a turn-end close — merges into the same row. Deliberately NOT changed: a subagent-internal background bash still opens its own card. The card attaches to a real, visible row and is currently the only liveness signal inside a subagent stretch; suppressing it would also perturb the `live_background_tasks` count that - `subagent_card_says_subagent_not_bg_task` (card unit) and `task_subagent_card_is_labelled_subagent_and_children_carry_parent` (pump-level, 2.1.169-shaped script) — headline word + parent attribution on internal calls, `None` on the main-agent launching call. - `sniff_task_emits_subagent_update_lifecycle` extended with a `local_agent` frame → `AgentContainer`. - `parent_call_id` serialization asserted present-when-Some and absent-when-None (merge-patch safety). - Existing background-card, workflow, relay, and persistence suites pass unchanged: `cargo test -p aionui-session --lib sniff_task` (5), `-p aionui-ai-agent --lib background_/workflow/tool_call_event/subagent` (42), `-p aionui-conversation --lib background_stream` (13) + `--test stream_relay_tool_call/thinking_persistence/acp_tool_call_persistence` (7), `-p aionui-channel --test stream_relay_test` (8). `cargo clippy -p aionui-session -p aionui-ai-agent -p aionui-conversation -p aionui-channel --all-targets -- -D warnings` and `cargo fmt --all -- --check` clean. Co-authored-by: zk <>
Version the workspace to 0.2.2 and fill parent_call_id, attachments, and steer mapping so the iOfficeAI#836+iOfficeAI#890 port compiles under tests.
…rn/steer Official Codex turn/steer has a single clientUserMessageId (host mid-turn id). The stale input-1 check could not pass alongside cmsg-7.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
AionCore 0.2.2 — selected upstream ports onto
main(0.2.1). Adapted, not blindly cherry-picked; fork journal / media pairing / input-queue stay intact.Taken
b3bd0158— wait for terminal output before asserting after process exit5a447e15— verify claude against 2.1.236 (+ claude_flags fixture retarget)331d9713— codebuddy 2.141.0, dimcode 0.3.22 registry pins9b7e4cee— slim auto-inject skill descriptions to the 200-char budget (csbu-workmate-configdescription 194 chars, WorkMate branding kept)484327db— mid-turn interjection for claude/codex (supports_midturn_delivery; ACP/aionrs/antigravity stay queued).ConversationRuntimeSummary.supports_midturn_delivery(#[serde(default)]). HTTPsend_msgreturns 200 vs 202 +delivered_midturn. Session-message tests expect Delivered / same-turn merge again for midturn-capable busy targets.a978cf71—SubagentTaskKind::AgentContainer+ToolCallEventData.parent_call_idSkipped
Pins kept
aionui-*; user-visible branding CSBU WorkMateTest plan
cargo fmt --all -- --checkcargo check --workspacecargo test -p aionui-session-message --test delivery_semantics --test e2e_cross_sessioncargo test -p aionui-app --test midturn_e2ecargo test -p aionui-ai-agent --lib terminalcargo test -p aionui-ai-agent --lib claude_flagscargo test -p aionui-extension --lib auto_inject_skill_descriptions_stay_within_injection_budgetcargo test -p aionui-session --lib sniff_taskcargo test -p aionui-session --lib cli_versioncargo test -p aionui-conversation --lib tool_event_pipelinecargo test -p aionui-conversation --lib summary_from_parts_carries_supports_midturn_delivery_throughDo not merge, tag, or
gh release createfrom this PR.