Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions apps/web/src/lib/code-reviews/terminal-reason-from-failure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,9 @@ import {
CLOUD_AGENT_FAILURE_CODES,
WORKSPACE_FAILURE_SUBTYPES,
} from '@kilocode/worker-utils/cloud-agent-failure';
import { CLOUD_AGENT_TERMINAL_REASONS } from '@kilocode/worker-utils/cloud-agent-next-client';
import { CODE_REVIEW_TERMINAL_REASONS } from '@kilocode/db/schema-types';
import { terminalReasonFromCloudAgentFailure } from './terminal-reason-from-failure';

describe('terminal reason list parity', () => {
// These two lists live in separate packages that cannot import each other, so
// drift is only caught here. A mismatch makes the orchestrator send a reason
// the callback allowlist rejects, or makes the worker's zod enum silently
// coerce a valid reason to undefined via its `.catch(undefined)`.
it('keeps the db and worker-utils terminal reason lists identical', () => {
expect([...CLOUD_AGENT_TERMINAL_REASONS].sort()).toEqual(
[...CODE_REVIEW_TERMINAL_REASONS].sort()
);
});
});

describe('terminalReasonFromCloudAgentFailure', () => {
it('returns undefined without a structured failure', () => {
expect(terminalReasonFromCloudAgentFailure(undefined)).toBeUndefined();
Expand Down
8 changes: 5 additions & 3 deletions packages/db/src/schema-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2210,9 +2210,11 @@ export type StripeSubscriptionStatus =

/**
* Valid values for cloud_agent_code_reviews.terminal_reason.
* KEEP IN SYNC with CloudAgentTerminalReason in
* packages/worker-utils/src/cloud-agent-next-client.ts — both lists must
* contain the same literal values.
*
* Single source of truth for the code review terminal reason enum. Worker-side
* consumers re-export this as CLOUD_AGENT_TERMINAL_REASONS in
* packages/worker-utils/src/cloud-agent-next-client.ts rather than maintaining
* a second copy.
*/
export const CODE_REVIEW_TERMINAL_REASONS = [
'billing',
Expand Down
60 changes: 10 additions & 50 deletions packages/worker-utils/src/cloud-agent-next-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
* transport layer and response parsing.
*/

import {
CODE_REVIEW_TERMINAL_REASONS,
type CodeReviewTerminalReason as CloudAgentTerminalReason,
} from '@kilocode/db/schema-types';

// ---------------------------------------------------------------------------
// Types — aligned with cloud-agent-next tRPC router contracts
// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -155,57 +160,12 @@ export type CloudAgentInterruptOutput = {
* services/code-review-infra/src/types.ts, where a missing value used to be
* silently coerced to undefined by a `.catch(undefined)` zod enum.
*
* KEEP IN SYNC with CODE_REVIEW_TERMINAL_REASONS in
* packages/db/src/schema-types.ts — both lists must contain the same literal
* values, and a mismatch makes the orchestrator send a reason the callback's
* allowlist rejects. apps/web asserts the two are equal (see
* apps/web/src/lib/code-reviews/terminal-reason-from-failure.test.ts).
* Single source of truth is CODE_REVIEW_TERMINAL_REASONS in
* packages/db/src/schema-types.ts; re-exported here under the worker-side
* name for orchestrator consumers.
*/
export const CLOUD_AGENT_TERMINAL_REASONS = [
'billing',
'model_not_found',
'github_installation_required',
'github_ip_allow_list',
'gitlab_project_access_required',
'byok_invalid_key',
'selected_model_unavailable',
'repeated_repository_clone_timeout',
'user_cancelled',
'superseded',
'interrupted',
'timeout',
'upstream_error',
'sandbox_error',
'workspace_capacity',
'assistant_failed',
'assistant_rate_limited',
'assistant_rate_limited_byok',
'assistant_rate_limited_managed',
'assistant_unavailable',
'assistant_timeout',
'assistant_unauthorized',
'assistant_invalid_request',
'assistant_no_reply',
'wrapper_failed',
'runtime_startup_failed',
'sandbox_connection',
'delivery_failed',
'workspace_setup_failed',
'repository_clone_failed',
'repository_auth_failed',
'repository_checkout_failed',
'session_import_failed',
'setup_command_failed',
'container_shutdown',
// Written only by the stale review reaper on the app side, never sent by the
// orchestrator. It is listed here because this enum and the db one are kept
// identical: the callback allowlist is built from this list, so an omission
// would reject the reason if it ever did arrive on a callback.
'abandoned',
'unknown',
] as const;

export type CloudAgentTerminalReason = (typeof CLOUD_AGENT_TERMINAL_REASONS)[number];
export { CODE_REVIEW_TERMINAL_REASONS as CLOUD_AGENT_TERMINAL_REASONS };
export type { CloudAgentTerminalReason };

export class CloudAgentNextError extends Error {
readonly procedure: string;
Expand Down