Skip to content

CloudAgentNext - broadcast cloud.status ready after terminalization and broaden wrapper terminal error detection#4515

Open
eshurakov wants to merge 4 commits into
mainfrom
eshurakov/cloud-agent-terminal-cloud-status
Open

CloudAgentNext - broadcast cloud.status ready after terminalization and broaden wrapper terminal error detection#4515
eshurakov wants to merge 4 commits into
mainfrom
eshurakov/cloud-agent-terminal-cloud-status

Conversation

@eshurakov

Copy link
Copy Markdown
Contributor

Problem

When a Cloud Agent execution ends abnormally, the web UI's chat input stays disabled (canSend = false) because the DO never broadcasts a cloud.status: ready event to re-enable it. Users are forced to create a new session for every prompt instead of sending follow-ups.

Two independent gaps cause this:

  1. DO gap: When the wrapper disconnects without sending a complete/error/interrupted event, the DO terminalizes messages as failed but never broadcasts any cloud.status event. Even when the wrapper sends a fatal error event, the ingest handler broadcasts cloud.status: error but never follows with cloud.status: ready.

  2. Wrapper gap: getTerminalFailure() only classifies payment/credit/quota/model-not-found errors as terminal. AI SDK errors like AI_InvalidResponseDataError (e.g., when a BYOK model returns a malformed response) are NOT classified as terminal, so the wrapper never sends a fatal error event — it disconnects without any terminal event, triggering gap 1.

Fix 1: DO broadcasts cloud.status: ready after terminalization

  • handleWrapperTerminalEvent broadcasts cloud.status: ready after onTerminalEvent for failed/interrupted status (skips completed since the ingest handler already broadcasts it).
  • Added onSessionTerminalized callback to WrapperSupervisorDependencies, called after checkDisconnectGrace and handleUnhealthyWrapper terminalize accepted work, so the DO broadcasts cloud.status: ready on the disconnect-grace and liveness-expiry paths that don't go through the normal terminal-event flow.

Fix 2: Wrapper detects AI SDK response errors as terminal

  • Added provider_error to WrapperTerminalFailureCodes.
  • Added isAIProviderResponseError helper detecting AI_InvalidResponseDataError, AI_JSONParseError, and the Expected '...' to be a ... message pattern.
  • Wired into getTerminalFailure so these permanent failures send a fatal error event to the DO, which then broadcasts the error and transitions to ready.

Supporting changes

Added provider_error to the shared failure-code contract (CLOUD_AGENT_FAILURE_CODES, DB schema type, safe-failure-projection message map, and non-retryable set) for consistency across run-state reports, client error projection, and telemetry.

Verification

  • pnpm run typecheck — passes
  • pnpm run lint — passes
  • pnpm run test — 2184 unit tests pass
  • pnpm run test:integration — 210 integration tests pass

Comment thread services/cloud-agent-next/src/persistence/CloudAgentSession.ts Outdated
Comment thread services/cloud-agent-next/src/session/wrapper-supervisor.ts Outdated
Comment thread services/cloud-agent-next/src/session/wrapper-supervisor.ts Outdated
Comment thread services/cloud-agent-next/wrapper/src/connection.ts
Comment thread packages/worker-utils/src/cloud-agent-failure.ts
Comment thread packages/db/src/schema.ts
@kilo-code-bot

kilo-code-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
services/cloud-agent-next/src/session/wrapper-supervisor.ts 666 Failed terminal-state rereads can permanently suppress readiness publication
services/cloud-agent-next/src/session/wrapper-supervisor.ts 686 Gate-release failures still have no retry path after messages become terminal
Files Reviewed (5 files)
  • services/cloud-agent-next/src/session/wrapper-supervisor.test.ts - 0 issues
  • services/cloud-agent-next/src/session/wrapper-supervisor.ts - 2 issues
  • services/cloud-agent-next/wrapper/src/lifecycle.test.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/lifecycle.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/main.ts - 0 issues

Fix these issues in Kilo Cloud

Previous Review Summaries (3 snapshots, latest commit 30a1891)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 30a1891)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
services/cloud-agent-next/src/session/wrapper-supervisor.ts 653 Terminalization persistence failures can orphan accepted work after runtime cleanup
services/cloud-agent-next/src/session/wrapper-supervisor.ts 677 Swallowed settlement failures can permanently strand gate-waiting callbacks
services/cloud-agent-next/wrapper/src/lifecycle.ts 229 The 2-second fallback can still close before the first reconnect handshake finishes
Files Reviewed (4 files)
  • services/cloud-agent-next/src/session/wrapper-supervisor.test.ts - 0 issues
  • services/cloud-agent-next/src/session/wrapper-supervisor.ts - 2 issues
  • services/cloud-agent-next/wrapper/src/lifecycle.test.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/lifecycle.ts - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit 387f552)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
services/cloud-agent-next/src/session/wrapper-supervisor.ts 653 Fallible terminal effects can still permanently skip readiness publication
services/cloud-agent-next/wrapper/src/lifecycle.ts 14 The fixed reconnect delay can expire before the first reconnect attempt finishes
Files Reviewed (8 files)
  • services/cloud-agent-next/src/persistence/CloudAgentSession.ts - 0 issues
  • services/cloud-agent-next/src/session/wrapper-supervisor.test.ts - 0 issues
  • services/cloud-agent-next/src/session/wrapper-supervisor.ts - 1 issue
  • services/cloud-agent-next/src/telemetry/queue-reports.test.ts - 0 issues
  • services/cloud-agent-next/src/telemetry/queue-reports.ts - 0 issues
  • services/cloud-agent-next/test/integration/session/disconnect-and-reaper.test.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/lifecycle.test.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/lifecycle.ts - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit 103accc)

Status: 6 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 6
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
services/cloud-agent-next/src/persistence/CloudAgentSession.ts 3274 Stale terminal events can incorrectly broadcast ready during a newer active run
services/cloud-agent-next/src/session/wrapper-supervisor.ts 670 Finalizing liveness expiry can omit ready when no accepted messages remain
services/cloud-agent-next/src/session/wrapper-supervisor.ts 671 Fallible terminal effects can permanently skip readiness publication
services/cloud-agent-next/wrapper/src/connection.ts 890 Provider terminal frames are discarded when detected during ingest reconnect
packages/worker-utils/src/cloud-agent-failure.ts 31 Run-report validation rejects the new provider error classification
packages/db/src/schema.ts 5536 Database constraint and migration do not permit the new failure code
Files Reviewed (11 files)
  • packages/db/src/schema.ts - 1 issue
  • packages/worker-utils/src/cloud-agent-failure.ts - 1 issue
  • services/cloud-agent-next/src/persistence/CloudAgentSession.ts - 1 issue
  • services/cloud-agent-next/src/session/safe-failure-projection.ts - 0 issues
  • services/cloud-agent-next/src/session/terminal-error-projector.ts - 0 issues
  • services/cloud-agent-next/src/session/wrapper-supervisor.test.ts - 0 issues
  • services/cloud-agent-next/src/session/wrapper-supervisor.ts - 2 issues
  • services/cloud-agent-next/src/shared/protocol.ts - 0 issues
  • services/cloud-agent-next/test/integration/session/disconnect-and-reaper.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/wrapper/reconnection.test.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/connection.ts - 1 issue

Fix these issues in Kilo Cloud


Reviewed by gpt-5.6-sol · Input: 126.7K · Output: 15.2K · Cached: 1M

Review guidance: REVIEW.md from base branch main

…ast and provider error classification

- onTerminalEvent returns boolean; only broadcast cloud.status: ready for
  accepted terminal events so stale events don't re-enable input mid-run
- Tie onSessionTerminalized to the durable terminalization transition (before
  fallible downstream effects) and invoke unconditionally so finalizing runs
  with no accepted messages still publish readiness
- Extend drain delay to 2s when aborted while disconnected so the buffered
  fatal error frame survives reconnect delivery before close() clears it
- Remap provider_error to assistant_error in persistedFailureCode (matching
  the existing model_missing/payment_required pattern) so run-state reports
  validate against the queue-report schema without a DB migration
…mmediately on reconnect during aborted drain
failureStage: activityObserved ? 'agent_activity' : 'post_dispatch_no_activity',
failureCode: activityObserved ? 'wrapper_error_after_activity' : failureCode,
});
} catch (terminalizeError) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: Terminalization persistence failures now orphan accepted work

This catch also handles failures from the durable state write itself, as the new test demonstrates. In that case the message remains accepted, but execution continues through readiness publication and clears the wrapper runtime identity, so later maintenance has neither a connection nor a liveness deadline with which to retry terminalization. Only effect failures after a successful durable transition can be safely swallowed here; a persistence failure must preserve or schedule supervision for the still-accepted message.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

allowWithoutObservedIdle: true,
});
}
} catch (settlementError) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: Swallowing settlement failures can permanently strand gate callbacks

If releaseWrapperTerminalWaitForIdleBatch() fails before persisting wrapperTerminalWaitReleasedAt, this catch continues and the runtime identity is cleared. No later maintenance path retries that release: terminal-effect repair only repairs message effects, while callback retry only sees already-finalized batches. A completed gate-waiting callback can therefore remain blocked forever. Keep this settlement retryable instead of consuming the failure.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

…ure and defer close during in-progress reconnect
const persistedState = await getSessionMessageState(storage, message.messageId);
durableTransitionSucceeded =
persistedState !== undefined && isTerminalMessageState(persistedState);
} catch {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[WARNING]: A failed terminal-state reread can permanently suppress readiness

If the terminal transition commits but a later terminal effect throws, this verification read can itself fail transiently. The catch then assumes the transition did not succeed and rethrows; on the next maintenance pass the message is already terminal, so handleUnhealthyWrapper() is not entered again and onSessionTerminalized never publishes cloud.status: ready. Terminal-effect repair does not perform that broadcast. Preserve a durable/retryable readiness obligation instead of treating a failed reread as proof that the transition failed.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

}
}
await onSessionTerminalized?.();
await messageSettlementOutbox.releaseWrapperTerminalWaitForIdleBatch();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[WARNING]: Gate-release failures still have no retry path

Propagating this failure avoids clearing the runtime immediately, but it does not make the release retryable. The accepted messages are already terminal, so on the next alarm a non-finalizing run fails hasActiveWrapperWork(), clears its liveness fields, and never re-enters handleUnhealthyWrapper() to retry releaseWrapperTerminalWaitForIdleBatch(). A completed gate-waiting callback can therefore remain blocked permanently. Persist or reconcile this release independently of active-message liveness.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

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.

1 participant