Treat inference hook denials as terminal errors (#60511)

## Why

An explicit denial from a workspace inference hook should stop the request, including retries and compaction model fallback.

## What changed

Recognize `inference_hook_denied` provider errors and preserve the provider's message, with a fallback when none is supplied. Expose the distinct `inferenceHookDenied` error through the app-server protocol and generated schemas and SDK types. Treat the denial as non-retryable during turns, compaction, and guardian review.

## Testing

Add coverage for terminal denials over HTTP, SSE, and WebSocket, error serialization and persistence in `thread/read`, and compaction failures that preserve token usage and history without retrying or falling back to another model.

GitOrigin-RevId: 2ebd480f01e52f4e6bd3db8a0f92d5814d18ccb1
This commit is contained in:
ccui-oai
2026-11-10 03:21:26 +00:00
committed by copyberry
parent 1099fe0694
commit 0811df3976
43 changed files with 292 additions and 51 deletions
@@ -26,6 +26,7 @@ enum CodexErrorInfoWire {
ModelNotFound,
/// Capacity is unavailable on a route restricted by server policy.
PolicyCapacityUnavailable,
InferenceHookDenied,
CyberPolicy,
BioPolicy,
MisalignmentPolicyViolation,
+5
View File
@@ -173,6 +173,9 @@ pub enum CodexErrorDetails {
},
#[error("{message}")]
InvalidPrompt { message: String },
/// The workspace's inference hook explicitly denied this request.
#[error("{message}")]
InferenceHookDenied { message: String },
/// The provider rejected the input under its content policy.
#[error("{message}")]
ContentPolicyViolation {
@@ -463,6 +466,7 @@ impl CodexErr {
| CodexErrorDetails::ResponseIncomplete(_)
| CodexErrorDetails::ModelNotFound { .. }
| CodexErrorDetails::InvalidPrompt { .. }
| CodexErrorDetails::InferenceHookDenied { .. }
| CodexErrorDetails::ContentPolicyViolation { .. }
| CodexErrorDetails::ToolCollision(_)
| CodexErrorDetails::RefreshTokenFailed(_)
@@ -544,6 +548,7 @@ impl CodexErr {
CodexErrorInfo::PolicyCapacityUnavailable
}
CodexErrorDetails::FlexUnavailable => CodexErrorInfo::FlexUnavailable,
CodexErrorDetails::InferenceHookDenied { .. } => CodexErrorInfo::InferenceHookDenied,
CodexErrorDetails::CyberPolicy { .. } => CodexErrorInfo::CyberPolicy,
CodexErrorDetails::BioPolicy { .. } => CodexErrorInfo::BioPolicy,
CodexErrorDetails::ModelNotFound { .. } => CodexErrorInfo::ModelNotFound,
+3
View File
@@ -2106,6 +2106,8 @@ pub enum CodexErrorInfo {
ModelNotFound,
/// Capacity is unavailable on a route restricted by server policy.
PolicyCapacityUnavailable,
/// The workspace's inference hook explicitly denied this request.
InferenceHookDenied,
CyberPolicy,
BioPolicy,
MisalignmentPolicyViolation,
@@ -2153,6 +2155,7 @@ impl CodexErrorInfo {
| Self::ServerOverloaded
| Self::ModelNotFound
| Self::PolicyCapacityUnavailable
| Self::InferenceHookDenied
| Self::CyberPolicy
| Self::BioPolicy
| Self::MisalignmentPolicyViolation