Skip to content

fix(acp): stream agent-initiated turns - #2392

Closed
lurenjia534 wants to merge 3 commits into
MoonshotAI:mainfrom
lurenjia534:fix/acp-agent-initiated-updates-2163
Closed

fix(acp): stream agent-initiated turns#2392
lurenjia534 wants to merge 3 commits into
MoonshotAI:mainfrom
lurenjia534:fix/acp-agent-initiated-updates-2163

Conversation

@lurenjia534

@lurenjia534 lurenjia534 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Related Issue

Resolves #2163

Problem

ACP projected updates only while a session/prompt request was active. A task- or cron-triggered main-agent turn could therefore complete in the engine while a connected ACP client received no session/update notifications.

Cold session/load/resume also had snapshot/live and lifecycle races: restored producers could emit before ACP attached; overlapping create/resume/close/archive operations could invalidate the wrong materialization; failed startup could leave a stale MiniDB summary; and v1 crash recovery could duplicate, lose, or mis-correlate deferred producer input. A UserPromptSubmit hook that blocked or failed before turn creation also had no correlated terminal event, while a prompt accepted during resume handoff could be persisted into the wrong turn.

What changed

  • Keep a session-lifetime ACP projection for main-agent updates, including display-safe task/cron triggers, reasoning, tool lifecycle, and assistant output. Prompt settlement remains correlated by promptId/activationId, so an autonomous turn cannot complete an unrelated prompt.
  • Establish an exact snapshot/live handoff through the same transport cut marker. Events and interactions are buffered until snapshot readiness; session/load replays only the persisted prefix, then drains the post-cut FIFO. Safe-trigger fallback is emitted before later tool/assistant history.
  • Serialize ordinary and handoff resume paths per normalized session id in both public RPC clients and KimiHarness. A failed caller cannot roll back a successful caller or remove handlers/session wrappers it does not own.
  • Make v1 deferred producer input durable with turn.defer/turn.defer.consume, blob rehydration, ordered matching for identical legacy inputs, and a stable deferred id on context.append_message. Reject prompts before persistence while resume handoff owns the turn-start gate, returning a retryable busy error instead of folding the prompt into another producer's turn.
  • Make v2 materialization ownership explicit per handle in both global-id and path chains. Cleanup splices only the exact generation, serializes path mutation, and uses a monotonic durability boundary so failures remove only fresh uncommitted state.
  • Validate cached session-index entries against the authoritative storage directory and invalidate them only when the expected workspace still owns the summary. Failed fresh startup no longer leaves a phantom session, while durable or ambiguous append state remains resumable.
  • Harden create/resume/fork/close/archive event boundaries, delayed or detached creation-hook next() calls, and terminal cleanup so stale materializations cannot publish or delete a newer session.
  • Correlate pre-turn hook completion through the v1/v2 protocol, server, and klient layers so ACP returns the terminal refusal/error and admits the next prompt.
  • Update vis consumers for the durable defer records and add a patch changeset for @moonshot-ai/kimi-code.

Verification

Before, on an untouched upstream worktree at 691ec467 with the real-engine regression E2Es copied byte-for-byte:

  • 4/4 failed: v1/v2 autonomous task turns produced no ACP updates, and both pre-turn hook cases timed out.

The follow-up review regressions were also run against the prior PR head 3ba3afa7 before applying this hardening:

  • v1 handoff prompt isolation: 3/3 failed.
  • v2 materialization/current-generation race cases: 6/7 failed; the remaining case was a control proving that ordinary resume retry already worked.
  • stale session-index ownership cases: 4/4 failed.
  • detached void next() coverage: 68 passed and 1 failed with an observed unhandledRejection.

After, at 58f499e1 rebased on upstream f1a3475a:

  • Real v1/v2 autonomous task + cron E2Es: 6/6 passed.
  • Final ACP/v1/v2 lifecycle and persistence-focused regression set: 240/240 passed.
  • ACP adapter full suite: 372 passed.
  • agent-core full suite: 4,133 passed, 3 expected failures, 30 skipped, 1 todo.
  • agent-core-v2 full suite: 4,278 passed.
  • Final pnpm test: 1,019 passed test files (12 skipped); 16,884 passed tests, 3 expected failures, 83 skipped, 2 todo.
  • Final pnpm typecheck, pnpm lint (0 errors), and pnpm build passed.
  • pnpm sherif, pnpm lint:pkg, domain-layer validation, SDK API Extractor/declaration build, changeset status, and all config/wire/state manifest freshness checks passed.
  • git diff --check is clean, and an independent read-only diff hygiene audit found no unrelated files, sensitive/internal identifiers, personal paths, or attribution metadata.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update. No command, configuration, or documented UI contract changed.

@changeset-bot

changeset-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 58f499e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@lurenjia534
lurenjia534 marked this pull request as ready for review July 30, 2026 04:00

Copy link
Copy Markdown
Contributor Author

@codex review

@pkg-pr-new

pkg-pr-new Bot commented Jul 30, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@58f499e
npx https://pkg.pr.new/@moonshot-ai/kimi-code@58f499e

commit: 58f499e

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d7614cba8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/acp-adapter/src/server.ts Outdated
@lurenjia534
lurenjia534 force-pushed the fix/acp-agent-initiated-updates-2163 branch from 0d7614c to 3ba3afa Compare July 30, 2026 08:06

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ba3afa7d4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/agent-core/src/agent/turn/index.ts
Comment thread packages/agent-core-v2/src/app/sessionLifecycle/sessionLifecycleService.ts Outdated
@lurenjia534
lurenjia534 force-pushed the fix/acp-agent-initiated-updates-2163 branch from 3ba3afa to 58f499e Compare July 30, 2026 10:53

Copy link
Copy Markdown
Contributor Author

@codex review

@lurenjia534
lurenjia534 marked this pull request as draft July 30, 2026 11:01

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58f499e1f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

.hooks.onDidCreateSession.register(
'node-sdk-event-wiring',
async (event, next) => {
this.wireSession(event.handle);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Replace wiring when the session handle changes

When concurrent lifecycle operations materialize the same session ID, this hook can receive a newer handle while sessionWirings still contains the older handle. wireSession() treats the ID alone as idempotent, so it leaves event and interaction subscriptions attached to the obsolete scope; if the older operation then fails, its catch also removes the ID's only wiring. The successfully retained/current session consequently emits no SDK events and pending approvals or questions can hang. Make wiring ownership handle-aware so a new generation replaces the old subscription and cleanup removes only the generation installed by this hook invocation.

Useful? React with 👍 / 👎.

@lurenjia534

Copy link
Copy Markdown
Contributor Author

Closing this draft because its scope expanded beyond #2163 into unrelated cross-engine session lifecycle and persistence work. I will replace it with a focused adapter-only fix based on the latest main, with before/after default-engine E2E evidence. This PR remains available only as a testing and design reference.

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.

ACP: agent-initiated turns (background task completions, cron fires) never emit session/update while no prompt is in flight

1 participant