diff --git a/codex-rs/app-server-protocol/schema/json/ServerNotification.json b/codex-rs/app-server-protocol/schema/json/ServerNotification.json index 5b06ab539c..0b221a1e19 100644 --- a/codex-rs/app-server-protocol/schema/json/ServerNotification.json +++ b/codex-rs/app-server-protocol/schema/json/ServerNotification.json @@ -725,6 +725,56 @@ } ] }, + "CommandExecutionGuardianApprovalReviewCompletedNotification": { + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a command execution item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "type": "object" + }, + "CommandExecutionGuardianApprovalReviewStartedNotification": { + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a command execution item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "type": "object" + }, "CommandExecutionOutputDeltaNotification": { "properties": { "delta": { @@ -934,6 +984,56 @@ ], "type": "object" }, + "FileChangeGuardianApprovalReviewCompletedNotification": { + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a file change item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "type": "object" + }, + "FileChangeGuardianApprovalReviewStartedNotification": { + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a file change item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "type": "object" + }, "FileChangeOutputDeltaNotification": { "properties": { "delta": { @@ -1081,7 +1181,7 @@ "type": "object" }, "GuardianApprovalReview": { - "description": "[UNSTABLE] Temporary guardian approval review payload used by `item/autoApprovalReview/*` notifications. This shape is expected to change soon.", + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", "properties": { "rationale": { "type": [ @@ -1349,7 +1449,7 @@ "type": "object" }, "ItemGuardianApprovalReviewCompletedNotification": { - "description": "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.\n\n[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", "properties": { "action": true, "review": { @@ -1374,7 +1474,7 @@ "type": "object" }, "ItemGuardianApprovalReviewStartedNotification": { - "description": "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.\n\n[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", "properties": { "action": true, "review": { @@ -1479,6 +1579,56 @@ ], "type": "object" }, + "McpToolCallGuardianApprovalReviewCompletedNotification": { + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on an MCP tool call item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "type": "object" + }, + "McpToolCallGuardianApprovalReviewStartedNotification": { + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on an MCP tool call item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "type": "object" + }, "McpToolCallProgressNotification": { "properties": { "itemId": { @@ -4043,6 +4193,127 @@ "type": "object" }, { + "properties": { + "method": { + "enum": [ + "item/commandExecution/guardianApprovalReview/started" + ], + "title": "Item/commandExecution/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/CommandExecutionGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/commandExecution/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/commandExecution/guardianApprovalReview/completed" + ], + "title": "Item/commandExecution/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/CommandExecutionGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/commandExecution/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/fileChange/guardianApprovalReview/started" + ], + "title": "Item/fileChange/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/FileChangeGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/fileChange/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/fileChange/guardianApprovalReview/completed" + ], + "title": "Item/fileChange/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/FileChangeGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/fileChange/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/mcpToolCall/guardianApprovalReview/started" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/McpToolCallGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/mcpToolCall/guardianApprovalReview/completed" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/McpToolCallGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.", "properties": { "method": { "enum": [ @@ -4063,6 +4334,7 @@ "type": "object" }, { + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.", "properties": { "method": { "enum": [ diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index c24c8ac249..dbcfcb78dc 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -3732,6 +3732,127 @@ "type": "object" }, { + "properties": { + "method": { + "enum": [ + "item/commandExecution/guardianApprovalReview/started" + ], + "title": "Item/commandExecution/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CommandExecutionGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/commandExecution/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/commandExecution/guardianApprovalReview/completed" + ], + "title": "Item/commandExecution/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CommandExecutionGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/commandExecution/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/fileChange/guardianApprovalReview/started" + ], + "title": "Item/fileChange/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FileChangeGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/fileChange/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/fileChange/guardianApprovalReview/completed" + ], + "title": "Item/fileChange/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FileChangeGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/fileChange/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/mcpToolCall/guardianApprovalReview/started" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpToolCallGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/mcpToolCall/guardianApprovalReview/completed" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpToolCallGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.", "properties": { "method": { "enum": [ @@ -3752,6 +3873,7 @@ "type": "object" }, { + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.", "properties": { "method": { "enum": [ @@ -6167,6 +6289,60 @@ "title": "CommandExecWriteResponse", "type": "object" }, + "CommandExecutionGuardianApprovalReviewCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a command execution item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/v2/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "CommandExecutionGuardianApprovalReviewCompletedNotification", + "type": "object" + }, + "CommandExecutionGuardianApprovalReviewStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a command execution item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/v2/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "CommandExecutionGuardianApprovalReviewStartedNotification", + "type": "object" + }, "CommandExecutionOutputDeltaNotification": { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { @@ -7371,6 +7547,60 @@ "title": "FeedbackUploadResponse", "type": "object" }, + "FileChangeGuardianApprovalReviewCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a file change item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/v2/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "FileChangeGuardianApprovalReviewCompletedNotification", + "type": "object" + }, + "FileChangeGuardianApprovalReviewStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a file change item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/v2/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "FileChangeGuardianApprovalReviewStartedNotification", + "type": "object" + }, "FileChangeOutputDeltaNotification": { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { @@ -7893,7 +8123,7 @@ "type": "object" }, "GuardianApprovalReview": { - "description": "[UNSTABLE] Temporary guardian approval review payload used by `item/autoApprovalReview/*` notifications. This shape is expected to change soon.", + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", "properties": { "rationale": { "type": [ @@ -8196,7 +8426,7 @@ }, "ItemGuardianApprovalReviewCompletedNotification": { "$schema": "http://json-schema.org/draft-07/schema#", - "description": "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.\n\n[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", "properties": { "action": true, "review": { @@ -8223,7 +8453,7 @@ }, "ItemGuardianApprovalReviewStartedNotification": { "$schema": "http://json-schema.org/draft-07/schema#", - "description": "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.\n\n[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", "properties": { "action": true, "review": { @@ -8692,6 +8922,60 @@ ], "type": "object" }, + "McpToolCallGuardianApprovalReviewCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on an MCP tool call item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/v2/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "McpToolCallGuardianApprovalReviewCompletedNotification", + "type": "object" + }, + "McpToolCallGuardianApprovalReviewStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on an MCP tool call item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/v2/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "McpToolCallGuardianApprovalReviewStartedNotification", + "type": "object" + }, "McpToolCallProgressNotification": { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index c479da94e4..c67c370712 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -2760,6 +2760,60 @@ "title": "CommandExecWriteResponse", "type": "object" }, + "CommandExecutionGuardianApprovalReviewCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a command execution item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "CommandExecutionGuardianApprovalReviewCompletedNotification", + "type": "object" + }, + "CommandExecutionGuardianApprovalReviewStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a command execution item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "CommandExecutionGuardianApprovalReviewStartedNotification", + "type": "object" + }, "CommandExecutionOutputDeltaNotification": { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { @@ -3964,6 +4018,60 @@ "title": "FeedbackUploadResponse", "type": "object" }, + "FileChangeGuardianApprovalReviewCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a file change item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "FileChangeGuardianApprovalReviewCompletedNotification", + "type": "object" + }, + "FileChangeGuardianApprovalReviewStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a file change item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "FileChangeGuardianApprovalReviewStartedNotification", + "type": "object" + }, "FileChangeOutputDeltaNotification": { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { @@ -4597,7 +4705,7 @@ "type": "object" }, "GuardianApprovalReview": { - "description": "[UNSTABLE] Temporary guardian approval review payload used by `item/autoApprovalReview/*` notifications. This shape is expected to change soon.", + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", "properties": { "rationale": { "type": [ @@ -4944,7 +5052,7 @@ }, "ItemGuardianApprovalReviewCompletedNotification": { "$schema": "http://json-schema.org/draft-07/schema#", - "description": "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.\n\n[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", "properties": { "action": true, "review": { @@ -4971,7 +5079,7 @@ }, "ItemGuardianApprovalReviewStartedNotification": { "$schema": "http://json-schema.org/draft-07/schema#", - "description": "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.\n\n[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", "properties": { "action": true, "review": { @@ -5440,6 +5548,60 @@ ], "type": "object" }, + "McpToolCallGuardianApprovalReviewCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on an MCP tool call item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "McpToolCallGuardianApprovalReviewCompletedNotification", + "type": "object" + }, + "McpToolCallGuardianApprovalReviewStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on an MCP tool call item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "McpToolCallGuardianApprovalReviewStartedNotification", + "type": "object" + }, "McpToolCallProgressNotification": { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { @@ -8167,6 +8329,127 @@ "type": "object" }, { + "properties": { + "method": { + "enum": [ + "item/commandExecution/guardianApprovalReview/started" + ], + "title": "Item/commandExecution/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/CommandExecutionGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/commandExecution/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/commandExecution/guardianApprovalReview/completed" + ], + "title": "Item/commandExecution/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/CommandExecutionGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/commandExecution/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/fileChange/guardianApprovalReview/started" + ], + "title": "Item/fileChange/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/FileChangeGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/fileChange/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/fileChange/guardianApprovalReview/completed" + ], + "title": "Item/fileChange/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/FileChangeGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/fileChange/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/mcpToolCall/guardianApprovalReview/started" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/McpToolCallGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/mcpToolCall/guardianApprovalReview/completed" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/McpToolCallGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/mcpToolCall/guardianApprovalReview/completedNotification", + "type": "object" + }, + { + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.", "properties": { "method": { "enum": [ @@ -8187,6 +8470,7 @@ "type": "object" }, { + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.", "properties": { "method": { "enum": [ diff --git a/codex-rs/app-server-protocol/schema/json/v2/CommandExecutionGuardianApprovalReviewCompletedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/CommandExecutionGuardianApprovalReviewCompletedNotification.json new file mode 100644 index 0000000000..113439d71c --- /dev/null +++ b/codex-rs/app-server-protocol/schema/json/v2/CommandExecutionGuardianApprovalReviewCompletedNotification.json @@ -0,0 +1,84 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "GuardianApprovalReview": { + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", + "properties": { + "rationale": { + "type": [ + "string", + "null" + ] + }, + "riskLevel": { + "anyOf": [ + { + "$ref": "#/definitions/GuardianRiskLevel" + }, + { + "type": "null" + } + ] + }, + "riskScore": { + "format": "uint8", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "status": { + "$ref": "#/definitions/GuardianApprovalReviewStatus" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "GuardianApprovalReviewStatus": { + "description": "[UNSTABLE] Lifecycle state for a guardian approval review.", + "enum": [ + "inProgress", + "approved", + "denied", + "aborted" + ], + "type": "string" + }, + "GuardianRiskLevel": { + "description": "[UNSTABLE] Risk level assigned by guardian approval review.", + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" + } + }, + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a command execution item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "CommandExecutionGuardianApprovalReviewCompletedNotification", + "type": "object" +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/json/v2/CommandExecutionGuardianApprovalReviewStartedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/CommandExecutionGuardianApprovalReviewStartedNotification.json new file mode 100644 index 0000000000..e643e9ca85 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/json/v2/CommandExecutionGuardianApprovalReviewStartedNotification.json @@ -0,0 +1,84 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "GuardianApprovalReview": { + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", + "properties": { + "rationale": { + "type": [ + "string", + "null" + ] + }, + "riskLevel": { + "anyOf": [ + { + "$ref": "#/definitions/GuardianRiskLevel" + }, + { + "type": "null" + } + ] + }, + "riskScore": { + "format": "uint8", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "status": { + "$ref": "#/definitions/GuardianApprovalReviewStatus" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "GuardianApprovalReviewStatus": { + "description": "[UNSTABLE] Lifecycle state for a guardian approval review.", + "enum": [ + "inProgress", + "approved", + "denied", + "aborted" + ], + "type": "string" + }, + "GuardianRiskLevel": { + "description": "[UNSTABLE] Risk level assigned by guardian approval review.", + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" + } + }, + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a command execution item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "CommandExecutionGuardianApprovalReviewStartedNotification", + "type": "object" +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/json/v2/FileChangeGuardianApprovalReviewCompletedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/FileChangeGuardianApprovalReviewCompletedNotification.json new file mode 100644 index 0000000000..e796bcf539 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/json/v2/FileChangeGuardianApprovalReviewCompletedNotification.json @@ -0,0 +1,84 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "GuardianApprovalReview": { + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", + "properties": { + "rationale": { + "type": [ + "string", + "null" + ] + }, + "riskLevel": { + "anyOf": [ + { + "$ref": "#/definitions/GuardianRiskLevel" + }, + { + "type": "null" + } + ] + }, + "riskScore": { + "format": "uint8", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "status": { + "$ref": "#/definitions/GuardianApprovalReviewStatus" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "GuardianApprovalReviewStatus": { + "description": "[UNSTABLE] Lifecycle state for a guardian approval review.", + "enum": [ + "inProgress", + "approved", + "denied", + "aborted" + ], + "type": "string" + }, + "GuardianRiskLevel": { + "description": "[UNSTABLE] Risk level assigned by guardian approval review.", + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" + } + }, + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a file change item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "FileChangeGuardianApprovalReviewCompletedNotification", + "type": "object" +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/json/v2/FileChangeGuardianApprovalReviewStartedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/FileChangeGuardianApprovalReviewStartedNotification.json new file mode 100644 index 0000000000..9f17b9ebe9 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/json/v2/FileChangeGuardianApprovalReviewStartedNotification.json @@ -0,0 +1,84 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "GuardianApprovalReview": { + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", + "properties": { + "rationale": { + "type": [ + "string", + "null" + ] + }, + "riskLevel": { + "anyOf": [ + { + "$ref": "#/definitions/GuardianRiskLevel" + }, + { + "type": "null" + } + ] + }, + "riskScore": { + "format": "uint8", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "status": { + "$ref": "#/definitions/GuardianApprovalReviewStatus" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "GuardianApprovalReviewStatus": { + "description": "[UNSTABLE] Lifecycle state for a guardian approval review.", + "enum": [ + "inProgress", + "approved", + "denied", + "aborted" + ], + "type": "string" + }, + "GuardianRiskLevel": { + "description": "[UNSTABLE] Risk level assigned by guardian approval review.", + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" + } + }, + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on a file change item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "FileChangeGuardianApprovalReviewStartedNotification", + "type": "object" +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/json/v2/ItemGuardianApprovalReviewCompletedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/ItemGuardianApprovalReviewCompletedNotification.json index df96e86d16..ef7c93b73c 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ItemGuardianApprovalReviewCompletedNotification.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ItemGuardianApprovalReviewCompletedNotification.json @@ -2,7 +2,7 @@ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "GuardianApprovalReview": { - "description": "[UNSTABLE] Temporary guardian approval review payload used by `item/autoApprovalReview/*` notifications. This shape is expected to change soon.", + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", "properties": { "rationale": { "type": [ @@ -57,7 +57,7 @@ "type": "string" } }, - "description": "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.\n\n[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", "properties": { "action": true, "review": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ItemGuardianApprovalReviewStartedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/ItemGuardianApprovalReviewStartedNotification.json index 339396a50b..10558264fd 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ItemGuardianApprovalReviewStartedNotification.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ItemGuardianApprovalReviewStartedNotification.json @@ -2,7 +2,7 @@ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "GuardianApprovalReview": { - "description": "[UNSTABLE] Temporary guardian approval review payload used by `item/autoApprovalReview/*` notifications. This shape is expected to change soon.", + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", "properties": { "rationale": { "type": [ @@ -57,7 +57,7 @@ "type": "string" } }, - "description": "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", + "description": "Deprecated: Use the parent item-specific `item/*/guardianApprovalReview/*` notifications instead.\n\n[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`.", "properties": { "action": true, "review": { diff --git a/codex-rs/app-server-protocol/schema/json/v2/McpToolCallGuardianApprovalReviewCompletedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/McpToolCallGuardianApprovalReviewCompletedNotification.json new file mode 100644 index 0000000000..a1aa8518c0 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/json/v2/McpToolCallGuardianApprovalReviewCompletedNotification.json @@ -0,0 +1,84 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "GuardianApprovalReview": { + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", + "properties": { + "rationale": { + "type": [ + "string", + "null" + ] + }, + "riskLevel": { + "anyOf": [ + { + "$ref": "#/definitions/GuardianRiskLevel" + }, + { + "type": "null" + } + ] + }, + "riskScore": { + "format": "uint8", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "status": { + "$ref": "#/definitions/GuardianApprovalReviewStatus" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "GuardianApprovalReviewStatus": { + "description": "[UNSTABLE] Lifecycle state for a guardian approval review.", + "enum": [ + "inProgress", + "approved", + "denied", + "aborted" + ], + "type": "string" + }, + "GuardianRiskLevel": { + "description": "[UNSTABLE] Risk level assigned by guardian approval review.", + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" + } + }, + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on an MCP tool call item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "McpToolCallGuardianApprovalReviewCompletedNotification", + "type": "object" +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/json/v2/McpToolCallGuardianApprovalReviewStartedNotification.json b/codex-rs/app-server-protocol/schema/json/v2/McpToolCallGuardianApprovalReviewStartedNotification.json new file mode 100644 index 0000000000..59234eed64 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/json/v2/McpToolCallGuardianApprovalReviewStartedNotification.json @@ -0,0 +1,84 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "GuardianApprovalReview": { + "description": "[UNSTABLE] Temporary guardian approval review payload used by guardian approval review notifications. This shape is expected to change soon.", + "properties": { + "rationale": { + "type": [ + "string", + "null" + ] + }, + "riskLevel": { + "anyOf": [ + { + "$ref": "#/definitions/GuardianRiskLevel" + }, + { + "type": "null" + } + ] + }, + "riskScore": { + "format": "uint8", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "status": { + "$ref": "#/definitions/GuardianApprovalReviewStatus" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "GuardianApprovalReviewStatus": { + "description": "[UNSTABLE] Lifecycle state for a guardian approval review.", + "enum": [ + "inProgress", + "approved", + "denied", + "aborted" + ], + "type": "string" + }, + "GuardianRiskLevel": { + "description": "[UNSTABLE] Risk level assigned by guardian approval review.", + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" + } + }, + "description": "[UNSTABLE] Temporary notification payload for guardian approval review on an MCP tool call item. This shape is expected to change soon.", + "properties": { + "action": true, + "itemId": { + "type": "string" + }, + "review": { + "$ref": "#/definitions/GuardianApprovalReview" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "review", + "threadId", + "turnId" + ], + "title": "McpToolCallGuardianApprovalReviewStartedNotification", + "type": "object" +} \ No newline at end of file diff --git a/codex-rs/app-server-protocol/schema/typescript/ServerNotification.ts b/codex-rs/app-server-protocol/schema/typescript/ServerNotification.ts index d9e2df7797..f1dc210117 100644 --- a/codex-rs/app-server-protocol/schema/typescript/ServerNotification.ts +++ b/codex-rs/app-server-protocol/schema/typescript/ServerNotification.ts @@ -9,11 +9,15 @@ import type { AccountUpdatedNotification } from "./v2/AccountUpdatedNotification import type { AgentMessageDeltaNotification } from "./v2/AgentMessageDeltaNotification"; import type { AppListUpdatedNotification } from "./v2/AppListUpdatedNotification"; import type { CommandExecOutputDeltaNotification } from "./v2/CommandExecOutputDeltaNotification"; +import type { CommandExecutionGuardianApprovalReviewCompletedNotification } from "./v2/CommandExecutionGuardianApprovalReviewCompletedNotification"; +import type { CommandExecutionGuardianApprovalReviewStartedNotification } from "./v2/CommandExecutionGuardianApprovalReviewStartedNotification"; import type { CommandExecutionOutputDeltaNotification } from "./v2/CommandExecutionOutputDeltaNotification"; import type { ConfigWarningNotification } from "./v2/ConfigWarningNotification"; import type { ContextCompactedNotification } from "./v2/ContextCompactedNotification"; import type { DeprecationNoticeNotification } from "./v2/DeprecationNoticeNotification"; import type { ErrorNotification } from "./v2/ErrorNotification"; +import type { FileChangeGuardianApprovalReviewCompletedNotification } from "./v2/FileChangeGuardianApprovalReviewCompletedNotification"; +import type { FileChangeGuardianApprovalReviewStartedNotification } from "./v2/FileChangeGuardianApprovalReviewStartedNotification"; import type { FileChangeOutputDeltaNotification } from "./v2/FileChangeOutputDeltaNotification"; import type { HookCompletedNotification } from "./v2/HookCompletedNotification"; import type { HookStartedNotification } from "./v2/HookStartedNotification"; @@ -23,6 +27,8 @@ import type { ItemGuardianApprovalReviewStartedNotification } from "./v2/ItemGua import type { ItemStartedNotification } from "./v2/ItemStartedNotification"; import type { McpServerOauthLoginCompletedNotification } from "./v2/McpServerOauthLoginCompletedNotification"; import type { McpServerStatusUpdatedNotification } from "./v2/McpServerStatusUpdatedNotification"; +import type { McpToolCallGuardianApprovalReviewCompletedNotification } from "./v2/McpToolCallGuardianApprovalReviewCompletedNotification"; +import type { McpToolCallGuardianApprovalReviewStartedNotification } from "./v2/McpToolCallGuardianApprovalReviewStartedNotification"; import type { McpToolCallProgressNotification } from "./v2/McpToolCallProgressNotification"; import type { ModelReroutedNotification } from "./v2/ModelReroutedNotification"; import type { PlanDeltaNotification } from "./v2/PlanDeltaNotification"; @@ -56,4 +62,4 @@ import type { WindowsWorldWritableWarningNotification } from "./v2/WindowsWorldW /** * Notification sent from the server to the client. */ -export type ServerNotification = { "method": "error", "params": ErrorNotification } | { "method": "thread/started", "params": ThreadStartedNotification } | { "method": "thread/status/changed", "params": ThreadStatusChangedNotification } | { "method": "thread/archived", "params": ThreadArchivedNotification } | { "method": "thread/unarchived", "params": ThreadUnarchivedNotification } | { "method": "thread/closed", "params": ThreadClosedNotification } | { "method": "skills/changed", "params": SkillsChangedNotification } | { "method": "thread/name/updated", "params": ThreadNameUpdatedNotification } | { "method": "thread/tokenUsage/updated", "params": ThreadTokenUsageUpdatedNotification } | { "method": "turn/started", "params": TurnStartedNotification } | { "method": "hook/started", "params": HookStartedNotification } | { "method": "turn/completed", "params": TurnCompletedNotification } | { "method": "hook/completed", "params": HookCompletedNotification } | { "method": "turn/diff/updated", "params": TurnDiffUpdatedNotification } | { "method": "turn/plan/updated", "params": TurnPlanUpdatedNotification } | { "method": "item/started", "params": ItemStartedNotification } | { "method": "item/autoApprovalReview/started", "params": ItemGuardianApprovalReviewStartedNotification } | { "method": "item/autoApprovalReview/completed", "params": ItemGuardianApprovalReviewCompletedNotification } | { "method": "item/completed", "params": ItemCompletedNotification } | { "method": "rawResponseItem/completed", "params": RawResponseItemCompletedNotification } | { "method": "item/agentMessage/delta", "params": AgentMessageDeltaNotification } | { "method": "item/plan/delta", "params": PlanDeltaNotification } | { "method": "command/exec/outputDelta", "params": CommandExecOutputDeltaNotification } | { "method": "item/commandExecution/outputDelta", "params": CommandExecutionOutputDeltaNotification } | { "method": "item/commandExecution/terminalInteraction", "params": TerminalInteractionNotification } | { "method": "item/fileChange/outputDelta", "params": FileChangeOutputDeltaNotification } | { "method": "serverRequest/resolved", "params": ServerRequestResolvedNotification } | { "method": "item/mcpToolCall/progress", "params": McpToolCallProgressNotification } | { "method": "mcpServer/oauthLogin/completed", "params": McpServerOauthLoginCompletedNotification } | { "method": "mcpServer/startupStatus/updated", "params": McpServerStatusUpdatedNotification } | { "method": "account/updated", "params": AccountUpdatedNotification } | { "method": "account/rateLimits/updated", "params": AccountRateLimitsUpdatedNotification } | { "method": "app/list/updated", "params": AppListUpdatedNotification } | { "method": "item/reasoning/summaryTextDelta", "params": ReasoningSummaryTextDeltaNotification } | { "method": "item/reasoning/summaryPartAdded", "params": ReasoningSummaryPartAddedNotification } | { "method": "item/reasoning/textDelta", "params": ReasoningTextDeltaNotification } | { "method": "thread/compacted", "params": ContextCompactedNotification } | { "method": "model/rerouted", "params": ModelReroutedNotification } | { "method": "deprecationNotice", "params": DeprecationNoticeNotification } | { "method": "configWarning", "params": ConfigWarningNotification } | { "method": "fuzzyFileSearch/sessionUpdated", "params": FuzzyFileSearchSessionUpdatedNotification } | { "method": "fuzzyFileSearch/sessionCompleted", "params": FuzzyFileSearchSessionCompletedNotification } | { "method": "thread/realtime/started", "params": ThreadRealtimeStartedNotification } | { "method": "thread/realtime/itemAdded", "params": ThreadRealtimeItemAddedNotification } | { "method": "thread/realtime/transcriptUpdated", "params": ThreadRealtimeTranscriptUpdatedNotification } | { "method": "thread/realtime/outputAudio/delta", "params": ThreadRealtimeOutputAudioDeltaNotification } | { "method": "thread/realtime/error", "params": ThreadRealtimeErrorNotification } | { "method": "thread/realtime/closed", "params": ThreadRealtimeClosedNotification } | { "method": "windows/worldWritableWarning", "params": WindowsWorldWritableWarningNotification } | { "method": "windowsSandbox/setupCompleted", "params": WindowsSandboxSetupCompletedNotification } | { "method": "account/login/completed", "params": AccountLoginCompletedNotification }; +export type ServerNotification = { "method": "error", "params": ErrorNotification } | { "method": "thread/started", "params": ThreadStartedNotification } | { "method": "thread/status/changed", "params": ThreadStatusChangedNotification } | { "method": "thread/archived", "params": ThreadArchivedNotification } | { "method": "thread/unarchived", "params": ThreadUnarchivedNotification } | { "method": "thread/closed", "params": ThreadClosedNotification } | { "method": "skills/changed", "params": SkillsChangedNotification } | { "method": "thread/name/updated", "params": ThreadNameUpdatedNotification } | { "method": "thread/tokenUsage/updated", "params": ThreadTokenUsageUpdatedNotification } | { "method": "turn/started", "params": TurnStartedNotification } | { "method": "hook/started", "params": HookStartedNotification } | { "method": "turn/completed", "params": TurnCompletedNotification } | { "method": "hook/completed", "params": HookCompletedNotification } | { "method": "turn/diff/updated", "params": TurnDiffUpdatedNotification } | { "method": "turn/plan/updated", "params": TurnPlanUpdatedNotification } | { "method": "item/started", "params": ItemStartedNotification } | { "method": "item/commandExecution/guardianApprovalReview/started", "params": CommandExecutionGuardianApprovalReviewStartedNotification } | { "method": "item/commandExecution/guardianApprovalReview/completed", "params": CommandExecutionGuardianApprovalReviewCompletedNotification } | { "method": "item/fileChange/guardianApprovalReview/started", "params": FileChangeGuardianApprovalReviewStartedNotification } | { "method": "item/fileChange/guardianApprovalReview/completed", "params": FileChangeGuardianApprovalReviewCompletedNotification } | { "method": "item/mcpToolCall/guardianApprovalReview/started", "params": McpToolCallGuardianApprovalReviewStartedNotification } | { "method": "item/mcpToolCall/guardianApprovalReview/completed", "params": McpToolCallGuardianApprovalReviewCompletedNotification } | { "method": "item/autoApprovalReview/started", "params": ItemGuardianApprovalReviewStartedNotification } | { "method": "item/autoApprovalReview/completed", "params": ItemGuardianApprovalReviewCompletedNotification } | { "method": "item/completed", "params": ItemCompletedNotification } | { "method": "rawResponseItem/completed", "params": RawResponseItemCompletedNotification } | { "method": "item/agentMessage/delta", "params": AgentMessageDeltaNotification } | { "method": "item/plan/delta", "params": PlanDeltaNotification } | { "method": "command/exec/outputDelta", "params": CommandExecOutputDeltaNotification } | { "method": "item/commandExecution/outputDelta", "params": CommandExecutionOutputDeltaNotification } | { "method": "item/commandExecution/terminalInteraction", "params": TerminalInteractionNotification } | { "method": "item/fileChange/outputDelta", "params": FileChangeOutputDeltaNotification } | { "method": "serverRequest/resolved", "params": ServerRequestResolvedNotification } | { "method": "item/mcpToolCall/progress", "params": McpToolCallProgressNotification } | { "method": "mcpServer/oauthLogin/completed", "params": McpServerOauthLoginCompletedNotification } | { "method": "mcpServer/startupStatus/updated", "params": McpServerStatusUpdatedNotification } | { "method": "account/updated", "params": AccountUpdatedNotification } | { "method": "account/rateLimits/updated", "params": AccountRateLimitsUpdatedNotification } | { "method": "app/list/updated", "params": AppListUpdatedNotification } | { "method": "item/reasoning/summaryTextDelta", "params": ReasoningSummaryTextDeltaNotification } | { "method": "item/reasoning/summaryPartAdded", "params": ReasoningSummaryPartAddedNotification } | { "method": "item/reasoning/textDelta", "params": ReasoningTextDeltaNotification } | { "method": "thread/compacted", "params": ContextCompactedNotification } | { "method": "model/rerouted", "params": ModelReroutedNotification } | { "method": "deprecationNotice", "params": DeprecationNoticeNotification } | { "method": "configWarning", "params": ConfigWarningNotification } | { "method": "fuzzyFileSearch/sessionUpdated", "params": FuzzyFileSearchSessionUpdatedNotification } | { "method": "fuzzyFileSearch/sessionCompleted", "params": FuzzyFileSearchSessionCompletedNotification } | { "method": "thread/realtime/started", "params": ThreadRealtimeStartedNotification } | { "method": "thread/realtime/itemAdded", "params": ThreadRealtimeItemAddedNotification } | { "method": "thread/realtime/transcriptUpdated", "params": ThreadRealtimeTranscriptUpdatedNotification } | { "method": "thread/realtime/outputAudio/delta", "params": ThreadRealtimeOutputAudioDeltaNotification } | { "method": "thread/realtime/error", "params": ThreadRealtimeErrorNotification } | { "method": "thread/realtime/closed", "params": ThreadRealtimeClosedNotification } | { "method": "windows/worldWritableWarning", "params": WindowsWorldWritableWarningNotification } | { "method": "windowsSandbox/setupCompleted", "params": WindowsSandboxSetupCompletedNotification } | { "method": "account/login/completed", "params": AccountLoginCompletedNotification }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionGuardianApprovalReviewCompletedNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionGuardianApprovalReviewCompletedNotification.ts new file mode 100644 index 0000000000..79b54528ec --- /dev/null +++ b/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionGuardianApprovalReviewCompletedNotification.ts @@ -0,0 +1,11 @@ +// GENERATED CODE! DO NOT MODIFY BY HAND! + +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { JsonValue } from "../serde_json/JsonValue"; +import type { GuardianApprovalReview } from "./GuardianApprovalReview"; + +/** + * [UNSTABLE] Temporary notification payload for guardian approval review on a + * command execution item. This shape is expected to change soon. + */ +export type CommandExecutionGuardianApprovalReviewCompletedNotification = { threadId: string, turnId: string, itemId: string, review: GuardianApprovalReview, action: JsonValue | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionGuardianApprovalReviewStartedNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionGuardianApprovalReviewStartedNotification.ts new file mode 100644 index 0000000000..fcfca55654 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionGuardianApprovalReviewStartedNotification.ts @@ -0,0 +1,11 @@ +// GENERATED CODE! DO NOT MODIFY BY HAND! + +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { JsonValue } from "../serde_json/JsonValue"; +import type { GuardianApprovalReview } from "./GuardianApprovalReview"; + +/** + * [UNSTABLE] Temporary notification payload for guardian approval review on a + * command execution item. This shape is expected to change soon. + */ +export type CommandExecutionGuardianApprovalReviewStartedNotification = { threadId: string, turnId: string, itemId: string, review: GuardianApprovalReview, action: JsonValue | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/FileChangeGuardianApprovalReviewCompletedNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/FileChangeGuardianApprovalReviewCompletedNotification.ts new file mode 100644 index 0000000000..5c26ff7259 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/typescript/v2/FileChangeGuardianApprovalReviewCompletedNotification.ts @@ -0,0 +1,11 @@ +// GENERATED CODE! DO NOT MODIFY BY HAND! + +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { JsonValue } from "../serde_json/JsonValue"; +import type { GuardianApprovalReview } from "./GuardianApprovalReview"; + +/** + * [UNSTABLE] Temporary notification payload for guardian approval review on a + * file change item. This shape is expected to change soon. + */ +export type FileChangeGuardianApprovalReviewCompletedNotification = { threadId: string, turnId: string, itemId: string, review: GuardianApprovalReview, action: JsonValue | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/FileChangeGuardianApprovalReviewStartedNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/FileChangeGuardianApprovalReviewStartedNotification.ts new file mode 100644 index 0000000000..2b19890ad3 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/typescript/v2/FileChangeGuardianApprovalReviewStartedNotification.ts @@ -0,0 +1,11 @@ +// GENERATED CODE! DO NOT MODIFY BY HAND! + +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { JsonValue } from "../serde_json/JsonValue"; +import type { GuardianApprovalReview } from "./GuardianApprovalReview"; + +/** + * [UNSTABLE] Temporary notification payload for guardian approval review on a + * file change item. This shape is expected to change soon. + */ +export type FileChangeGuardianApprovalReviewStartedNotification = { threadId: string, turnId: string, itemId: string, review: GuardianApprovalReview, action: JsonValue | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/GuardianApprovalReview.ts b/codex-rs/app-server-protocol/schema/typescript/v2/GuardianApprovalReview.ts index e26282be02..d5e7d11bcb 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/GuardianApprovalReview.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/GuardianApprovalReview.ts @@ -5,8 +5,7 @@ import type { GuardianApprovalReviewStatus } from "./GuardianApprovalReviewStatu import type { GuardianRiskLevel } from "./GuardianRiskLevel"; /** - * [UNSTABLE] Temporary guardian approval review payload used by - * `item/autoApprovalReview/*` notifications. This shape is expected to change - * soon. + * [UNSTABLE] Temporary guardian approval review payload used by guardian + * approval review notifications. This shape is expected to change soon. */ export type GuardianApprovalReview = { status: GuardianApprovalReviewStatus, riskScore: number | null, riskLevel: GuardianRiskLevel | null, rationale: string | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ItemGuardianApprovalReviewCompletedNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ItemGuardianApprovalReviewCompletedNotification.ts index ac4ae1b78a..e7e310dfbf 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ItemGuardianApprovalReviewCompletedNotification.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ItemGuardianApprovalReviewCompletedNotification.ts @@ -5,6 +5,9 @@ import type { JsonValue } from "../serde_json/JsonValue"; import type { GuardianApprovalReview } from "./GuardianApprovalReview"; /** + * Deprecated: Use the parent item-specific + * `item/*/guardianApprovalReview/*` notifications instead. + * * [UNSTABLE] Temporary notification payload for guardian automatic approval * review. This shape is expected to change soon. * diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ItemGuardianApprovalReviewStartedNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ItemGuardianApprovalReviewStartedNotification.ts index b229626817..52abada59c 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ItemGuardianApprovalReviewStartedNotification.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ItemGuardianApprovalReviewStartedNotification.ts @@ -5,6 +5,9 @@ import type { JsonValue } from "../serde_json/JsonValue"; import type { GuardianApprovalReview } from "./GuardianApprovalReview"; /** + * Deprecated: Use the parent item-specific + * `item/*/guardianApprovalReview/*` notifications instead. + * * [UNSTABLE] Temporary notification payload for guardian automatic approval * review. This shape is expected to change soon. * diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/McpToolCallGuardianApprovalReviewCompletedNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/McpToolCallGuardianApprovalReviewCompletedNotification.ts new file mode 100644 index 0000000000..52bdfaec79 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/typescript/v2/McpToolCallGuardianApprovalReviewCompletedNotification.ts @@ -0,0 +1,11 @@ +// GENERATED CODE! DO NOT MODIFY BY HAND! + +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { JsonValue } from "../serde_json/JsonValue"; +import type { GuardianApprovalReview } from "./GuardianApprovalReview"; + +/** + * [UNSTABLE] Temporary notification payload for guardian approval review on + * an MCP tool call item. This shape is expected to change soon. + */ +export type McpToolCallGuardianApprovalReviewCompletedNotification = { threadId: string, turnId: string, itemId: string, review: GuardianApprovalReview, action: JsonValue | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/McpToolCallGuardianApprovalReviewStartedNotification.ts b/codex-rs/app-server-protocol/schema/typescript/v2/McpToolCallGuardianApprovalReviewStartedNotification.ts new file mode 100644 index 0000000000..df5a687812 --- /dev/null +++ b/codex-rs/app-server-protocol/schema/typescript/v2/McpToolCallGuardianApprovalReviewStartedNotification.ts @@ -0,0 +1,11 @@ +// GENERATED CODE! DO NOT MODIFY BY HAND! + +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { JsonValue } from "../serde_json/JsonValue"; +import type { GuardianApprovalReview } from "./GuardianApprovalReview"; + +/** + * [UNSTABLE] Temporary notification payload for guardian approval review on + * an MCP tool call item. This shape is expected to change soon. + */ +export type McpToolCallGuardianApprovalReviewStartedNotification = { threadId: string, turnId: string, itemId: string, review: GuardianApprovalReview, action: JsonValue | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/index.ts b/codex-rs/app-server-protocol/schema/typescript/v2/index.ts index d9cc4758bc..baa326da17 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/index.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/index.ts @@ -51,6 +51,8 @@ export type { CommandExecTerminateResponse } from "./CommandExecTerminateRespons export type { CommandExecWriteParams } from "./CommandExecWriteParams"; export type { CommandExecWriteResponse } from "./CommandExecWriteResponse"; export type { CommandExecutionApprovalDecision } from "./CommandExecutionApprovalDecision"; +export type { CommandExecutionGuardianApprovalReviewCompletedNotification } from "./CommandExecutionGuardianApprovalReviewCompletedNotification"; +export type { CommandExecutionGuardianApprovalReviewStartedNotification } from "./CommandExecutionGuardianApprovalReviewStartedNotification"; export type { CommandExecutionOutputDeltaNotification } from "./CommandExecutionOutputDeltaNotification"; export type { CommandExecutionRequestApprovalParams } from "./CommandExecutionRequestApprovalParams"; export type { CommandExecutionRequestApprovalResponse } from "./CommandExecutionRequestApprovalResponse"; @@ -93,6 +95,8 @@ export type { ExternalAgentConfigMigrationItemType } from "./ExternalAgentConfig export type { FeedbackUploadParams } from "./FeedbackUploadParams"; export type { FeedbackUploadResponse } from "./FeedbackUploadResponse"; export type { FileChangeApprovalDecision } from "./FileChangeApprovalDecision"; +export type { FileChangeGuardianApprovalReviewCompletedNotification } from "./FileChangeGuardianApprovalReviewCompletedNotification"; +export type { FileChangeGuardianApprovalReviewStartedNotification } from "./FileChangeGuardianApprovalReviewStartedNotification"; export type { FileChangeOutputDeltaNotification } from "./FileChangeOutputDeltaNotification"; export type { FileChangeRequestApprovalParams } from "./FileChangeRequestApprovalParams"; export type { FileChangeRequestApprovalResponse } from "./FileChangeRequestApprovalResponse"; @@ -175,6 +179,8 @@ export type { McpServerStartupState } from "./McpServerStartupState"; export type { McpServerStatus } from "./McpServerStatus"; export type { McpServerStatusUpdatedNotification } from "./McpServerStatusUpdatedNotification"; export type { McpToolCallError } from "./McpToolCallError"; +export type { McpToolCallGuardianApprovalReviewCompletedNotification } from "./McpToolCallGuardianApprovalReviewCompletedNotification"; +export type { McpToolCallGuardianApprovalReviewStartedNotification } from "./McpToolCallGuardianApprovalReviewStartedNotification"; export type { McpToolCallProgressNotification } from "./McpToolCallProgressNotification"; export type { McpToolCallResult } from "./McpToolCallResult"; export type { McpToolCallStatus } from "./McpToolCallStatus"; diff --git a/codex-rs/app-server-protocol/src/protocol/common.rs b/codex-rs/app-server-protocol/src/protocol/common.rs index 56897566d9..2947ec3876 100644 --- a/codex-rs/app-server-protocol/src/protocol/common.rs +++ b/codex-rs/app-server-protocol/src/protocol/common.rs @@ -889,7 +889,35 @@ server_notification_definitions! { TurnDiffUpdated => "turn/diff/updated" (v2::TurnDiffUpdatedNotification), TurnPlanUpdated => "turn/plan/updated" (v2::TurnPlanUpdatedNotification), ItemStarted => "item/started" (v2::ItemStartedNotification), + #[experimental("item/commandExecution/guardianApprovalReview/started")] + CommandExecutionGuardianApprovalReviewStarted => + "item/commandExecution/guardianApprovalReview/started" + (v2::CommandExecutionGuardianApprovalReviewStartedNotification), + #[experimental("item/commandExecution/guardianApprovalReview/completed")] + CommandExecutionGuardianApprovalReviewCompleted => + "item/commandExecution/guardianApprovalReview/completed" + (v2::CommandExecutionGuardianApprovalReviewCompletedNotification), + #[experimental("item/fileChange/guardianApprovalReview/started")] + FileChangeGuardianApprovalReviewStarted => + "item/fileChange/guardianApprovalReview/started" + (v2::FileChangeGuardianApprovalReviewStartedNotification), + #[experimental("item/fileChange/guardianApprovalReview/completed")] + FileChangeGuardianApprovalReviewCompleted => + "item/fileChange/guardianApprovalReview/completed" + (v2::FileChangeGuardianApprovalReviewCompletedNotification), + #[experimental("item/mcpToolCall/guardianApprovalReview/started")] + McpToolCallGuardianApprovalReviewStarted => + "item/mcpToolCall/guardianApprovalReview/started" + (v2::McpToolCallGuardianApprovalReviewStartedNotification), + #[experimental("item/mcpToolCall/guardianApprovalReview/completed")] + McpToolCallGuardianApprovalReviewCompleted => + "item/mcpToolCall/guardianApprovalReview/completed" + (v2::McpToolCallGuardianApprovalReviewCompletedNotification), + /// Deprecated: Use the parent item-specific + /// `item/*/guardianApprovalReview/*` notifications instead. ItemGuardianApprovalReviewStarted => "item/autoApprovalReview/started" (v2::ItemGuardianApprovalReviewStartedNotification), + /// Deprecated: Use the parent item-specific + /// `item/*/guardianApprovalReview/*` notifications instead. ItemGuardianApprovalReviewCompleted => "item/autoApprovalReview/completed" (v2::ItemGuardianApprovalReviewCompletedNotification), ItemCompleted => "item/completed" (v2::ItemCompletedNotification), /// This event is internal-only. Used by Codex Cloud. diff --git a/codex-rs/app-server-protocol/src/protocol/v2.rs b/codex-rs/app-server-protocol/src/protocol/v2.rs index 57017833a6..d78cd0fc25 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2.rs @@ -4344,9 +4344,8 @@ impl From for GuardianRiskLevel { } } -/// [UNSTABLE] Temporary guardian approval review payload used by -/// `item/autoApprovalReview/*` notifications. This shape is expected to change -/// soon. +/// [UNSTABLE] Temporary guardian approval review payload used by guardian +/// approval review notifications. This shape is expected to change soon. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] @@ -4829,6 +4828,87 @@ pub struct ItemStartedNotification { #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] +/// [UNSTABLE] Temporary notification payload for guardian approval review on a +/// command execution item. This shape is expected to change soon. +pub struct CommandExecutionGuardianApprovalReviewStartedNotification { + pub thread_id: String, + pub turn_id: String, + pub item_id: String, + pub review: GuardianApprovalReview, + pub action: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export_to = "v2/")] +/// [UNSTABLE] Temporary notification payload for guardian approval review on a +/// command execution item. This shape is expected to change soon. +pub struct CommandExecutionGuardianApprovalReviewCompletedNotification { + pub thread_id: String, + pub turn_id: String, + pub item_id: String, + pub review: GuardianApprovalReview, + pub action: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export_to = "v2/")] +/// [UNSTABLE] Temporary notification payload for guardian approval review on a +/// file change item. This shape is expected to change soon. +pub struct FileChangeGuardianApprovalReviewStartedNotification { + pub thread_id: String, + pub turn_id: String, + pub item_id: String, + pub review: GuardianApprovalReview, + pub action: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export_to = "v2/")] +/// [UNSTABLE] Temporary notification payload for guardian approval review on a +/// file change item. This shape is expected to change soon. +pub struct FileChangeGuardianApprovalReviewCompletedNotification { + pub thread_id: String, + pub turn_id: String, + pub item_id: String, + pub review: GuardianApprovalReview, + pub action: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export_to = "v2/")] +/// [UNSTABLE] Temporary notification payload for guardian approval review on +/// an MCP tool call item. This shape is expected to change soon. +pub struct McpToolCallGuardianApprovalReviewStartedNotification { + pub thread_id: String, + pub turn_id: String, + pub item_id: String, + pub review: GuardianApprovalReview, + pub action: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export_to = "v2/")] +/// [UNSTABLE] Temporary notification payload for guardian approval review on +/// an MCP tool call item. This shape is expected to change soon. +pub struct McpToolCallGuardianApprovalReviewCompletedNotification { + pub thread_id: String, + pub turn_id: String, + pub item_id: String, + pub review: GuardianApprovalReview, + pub action: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export_to = "v2/")] +/// Deprecated: Use the parent item-specific +/// `item/*/guardianApprovalReview/*` notifications instead. +/// /// [UNSTABLE] Temporary notification payload for guardian automatic approval /// review. This shape is expected to change soon. /// @@ -4846,6 +4926,9 @@ pub struct ItemGuardianApprovalReviewStartedNotification { #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] +/// Deprecated: Use the parent item-specific +/// `item/*/guardianApprovalReview/*` notifications instead. +/// /// [UNSTABLE] Temporary notification payload for guardian automatic approval /// review. This shape is expected to change soon. /// diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index 3248a44424..6410149dca 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -876,10 +876,16 @@ All items emit shared lifecycle events: - `item/started` — emits the full `item` when a new unit of work begins so the UI can render it immediately; the `item.id` in this payload matches the `itemId` used by deltas. - `item/completed` — sends the final `item` once that work itself finishes (for example, after a tool call or message completes); treat this as the authoritative execution/result state. -- `item/autoApprovalReview/started` — [UNSTABLE] temporary guardian notification carrying `{threadId, turnId, targetItemId, review, action?}` when guardian approval review begins. This shape is expected to change soon. -- `item/autoApprovalReview/completed` — [UNSTABLE] temporary guardian notification carrying `{threadId, turnId, targetItemId, review, action?}` when guardian approval review resolves. This shape is expected to change soon. +- `item/commandExecution/guardianApprovalReview/started` — [UNSTABLE, experimental API] temporary guardian notification carrying `{threadId, turnId, itemId, review, action?}` when guardian approval review begins for a `commandExecution` item. +- `item/commandExecution/guardianApprovalReview/completed` — [UNSTABLE, experimental API] temporary guardian notification carrying `{threadId, turnId, itemId, review, action?}` when guardian approval review resolves for a `commandExecution` item. +- `item/fileChange/guardianApprovalReview/started` — [UNSTABLE, experimental API] temporary guardian notification carrying `{threadId, turnId, itemId, review, action?}` when guardian approval review begins for a `fileChange` item. +- `item/fileChange/guardianApprovalReview/completed` — [UNSTABLE, experimental API] temporary guardian notification carrying `{threadId, turnId, itemId, review, action?}` when guardian approval review resolves for a `fileChange` item. +- `item/mcpToolCall/guardianApprovalReview/started` — [UNSTABLE, experimental API] temporary guardian notification carrying `{threadId, turnId, itemId, review, action?}` when guardian approval review begins for an `mcpToolCall` item. +- `item/mcpToolCall/guardianApprovalReview/completed` — [UNSTABLE, experimental API] temporary guardian notification carrying `{threadId, turnId, itemId, review, action?}` when guardian approval review resolves for an `mcpToolCall` item. +- `item/autoApprovalReview/started` — [UNSTABLE] deprecated compatibility alias carrying `{threadId, turnId, targetItemId, review, action?}` when guardian approval review begins. +- `item/autoApprovalReview/completed` — [UNSTABLE] deprecated compatibility alias carrying `{threadId, turnId, targetItemId, review, action?}` when guardian approval review resolves. -`review` is [UNSTABLE] and currently has `{status, riskScore?, riskLevel?, rationale?}`, where `status` is one of `inProgress`, `approved`, `denied`, or `aborted`. `action` is the guardian action summary payload from core when available and is intended to support temporary standalone pending-review UI. These notifications are separate from the target item's own `item/completed` lifecycle and are intentionally temporary while the guardian app protocol is still being designed. +`review` is [UNSTABLE] and currently has `{status, riskScore?, riskLevel?, rationale?}`, where `status` is one of `inProgress`, `approved`, `denied`, or `aborted`. `action` is the guardian action summary payload from core when available and is intended to support temporary pending-review UI. Parent-scoped guardian notifications are emitted when app-server can map the guardian review to a concrete parent item; the deprecated top-level alias remains for older clients and for review kinds that are not yet parent-scoped. There are additional item-specific events: diff --git a/codex-rs/app-server/src/bespoke_event_handling.rs b/codex-rs/app-server/src/bespoke_event_handling.rs index 34640a50cf..dde37a1bd1 100644 --- a/codex-rs/app-server/src/bespoke_event_handling.rs +++ b/codex-rs/app-server/src/bespoke_event_handling.rs @@ -23,6 +23,8 @@ use codex_app_server_protocol::CollabAgentTool; use codex_app_server_protocol::CollabAgentToolCallStatus as V2CollabToolCallStatus; use codex_app_server_protocol::CommandAction as V2ParsedCommand; use codex_app_server_protocol::CommandExecutionApprovalDecision; +use codex_app_server_protocol::CommandExecutionGuardianApprovalReviewCompletedNotification; +use codex_app_server_protocol::CommandExecutionGuardianApprovalReviewStartedNotification; use codex_app_server_protocol::CommandExecutionOutputDeltaNotification; use codex_app_server_protocol::CommandExecutionRequestApprovalParams; use codex_app_server_protocol::CommandExecutionRequestApprovalResponse; @@ -39,6 +41,8 @@ use codex_app_server_protocol::ExecCommandApprovalParams; use codex_app_server_protocol::ExecCommandApprovalResponse; use codex_app_server_protocol::ExecPolicyAmendment as V2ExecPolicyAmendment; use codex_app_server_protocol::FileChangeApprovalDecision; +use codex_app_server_protocol::FileChangeGuardianApprovalReviewCompletedNotification; +use codex_app_server_protocol::FileChangeGuardianApprovalReviewStartedNotification; use codex_app_server_protocol::FileChangeOutputDeltaNotification; use codex_app_server_protocol::FileChangeRequestApprovalParams; use codex_app_server_protocol::FileChangeRequestApprovalResponse; @@ -60,6 +64,8 @@ use codex_app_server_protocol::McpServerElicitationRequestResponse; use codex_app_server_protocol::McpServerStartupState; use codex_app_server_protocol::McpServerStatusUpdatedNotification; use codex_app_server_protocol::McpToolCallError; +use codex_app_server_protocol::McpToolCallGuardianApprovalReviewCompletedNotification; +use codex_app_server_protocol::McpToolCallGuardianApprovalReviewStartedNotification; use codex_app_server_protocol::McpToolCallResult; use codex_app_server_protocol::McpToolCallStatus; use codex_app_server_protocol::ModelReroutedNotification; @@ -160,6 +166,13 @@ struct CommandExecutionCompletionItem { command_actions: Vec, } +#[derive(Clone, Copy)] +enum GuardianApprovalReviewItemKind { + CommandExecution, + FileChange, + McpToolCall, +} + async fn resolve_server_request_on_thread_listener( thread_state: &Arc>, request_id: RequestId, @@ -192,20 +205,21 @@ async fn resolve_server_request_on_thread_listener( } } -fn guardian_auto_approval_review_notification( - conversation_id: &ThreadId, +fn guardian_approval_review_turn_id( event_turn_id: &str, assessment: &GuardianAssessmentEvent, -) -> ServerNotification { - // TODO(ccunningham): Attach guardian review state to the reviewed tool - // item's lifecycle instead of sending standalone review notifications so - // the app-server API can persist and replay review state via `thread/read`. - let turn_id = if assessment.turn_id.is_empty() { +) -> String { + if assessment.turn_id.is_empty() { event_turn_id.to_string() } else { assessment.turn_id.clone() - }; - let review = GuardianApprovalReview { + } +} + +fn guardian_approval_review_payload( + assessment: &GuardianAssessmentEvent, +) -> GuardianApprovalReview { + GuardianApprovalReview { status: match assessment.status { codex_protocol::protocol::GuardianAssessmentStatus::InProgress => { GuardianApprovalReviewStatus::InProgress @@ -223,7 +237,31 @@ fn guardian_auto_approval_review_notification( risk_score: assessment.risk_score, risk_level: assessment.risk_level.map(Into::into), rationale: assessment.rationale.clone(), - }; + } +} + +fn guardian_approval_review_item_kind( + action: Option<&JsonValue>, +) -> Option { + match action + .and_then(|value| value.get("tool")) + .and_then(serde_json::Value::as_str) + { + Some("shell") | Some("exec_command") => { + Some(GuardianApprovalReviewItemKind::CommandExecution) + } + Some("apply_patch") => Some(GuardianApprovalReviewItemKind::FileChange), + Some("mcp_tool_call") => Some(GuardianApprovalReviewItemKind::McpToolCall), + Some(_) | None => None, + } +} + +fn legacy_guardian_approval_review_notification( + conversation_id: &ThreadId, + turn_id: String, + assessment: &GuardianAssessmentEvent, + review: GuardianApprovalReview, +) -> ServerNotification { match assessment.status { codex_protocol::protocol::GuardianAssessmentStatus::InProgress => { ServerNotification::ItemGuardianApprovalReviewStarted( @@ -252,6 +290,137 @@ fn guardian_auto_approval_review_notification( } } +fn parent_guardian_approval_review_notification( + conversation_id: &ThreadId, + turn_id: String, + assessment: &GuardianAssessmentEvent, + review: GuardianApprovalReview, +) -> Option { + let item_kind = guardian_approval_review_item_kind(assessment.action.as_ref())?; + let thread_id = conversation_id.to_string(); + let item_id = assessment.id.clone(); + let action = assessment.action.clone(); + + match (item_kind, assessment.status) { + ( + GuardianApprovalReviewItemKind::CommandExecution, + codex_protocol::protocol::GuardianAssessmentStatus::InProgress, + ) => Some( + ServerNotification::CommandExecutionGuardianApprovalReviewStarted( + CommandExecutionGuardianApprovalReviewStartedNotification { + thread_id, + turn_id, + item_id, + review, + action, + }, + ), + ), + ( + GuardianApprovalReviewItemKind::CommandExecution, + codex_protocol::protocol::GuardianAssessmentStatus::Approved + | codex_protocol::protocol::GuardianAssessmentStatus::Denied + | codex_protocol::protocol::GuardianAssessmentStatus::Aborted, + ) => Some( + ServerNotification::CommandExecutionGuardianApprovalReviewCompleted( + CommandExecutionGuardianApprovalReviewCompletedNotification { + thread_id, + turn_id, + item_id, + review, + action, + }, + ), + ), + ( + GuardianApprovalReviewItemKind::FileChange, + codex_protocol::protocol::GuardianAssessmentStatus::InProgress, + ) => Some(ServerNotification::FileChangeGuardianApprovalReviewStarted( + FileChangeGuardianApprovalReviewStartedNotification { + thread_id, + turn_id, + item_id, + review, + action, + }, + )), + ( + GuardianApprovalReviewItemKind::FileChange, + codex_protocol::protocol::GuardianAssessmentStatus::Approved + | codex_protocol::protocol::GuardianAssessmentStatus::Denied + | codex_protocol::protocol::GuardianAssessmentStatus::Aborted, + ) => Some( + ServerNotification::FileChangeGuardianApprovalReviewCompleted( + FileChangeGuardianApprovalReviewCompletedNotification { + thread_id, + turn_id, + item_id, + review, + action, + }, + ), + ), + ( + GuardianApprovalReviewItemKind::McpToolCall, + codex_protocol::protocol::GuardianAssessmentStatus::InProgress, + ) => Some( + ServerNotification::McpToolCallGuardianApprovalReviewStarted( + McpToolCallGuardianApprovalReviewStartedNotification { + thread_id, + turn_id, + item_id, + review, + action, + }, + ), + ), + ( + GuardianApprovalReviewItemKind::McpToolCall, + codex_protocol::protocol::GuardianAssessmentStatus::Approved + | codex_protocol::protocol::GuardianAssessmentStatus::Denied + | codex_protocol::protocol::GuardianAssessmentStatus::Aborted, + ) => Some( + ServerNotification::McpToolCallGuardianApprovalReviewCompleted( + McpToolCallGuardianApprovalReviewCompletedNotification { + thread_id, + turn_id, + item_id, + review, + action, + }, + ), + ), + } +} + +fn guardian_approval_review_notifications( + conversation_id: &ThreadId, + event_turn_id: &str, + assessment: &GuardianAssessmentEvent, +) -> Vec { + let turn_id = guardian_approval_review_turn_id(event_turn_id, assessment); + let review = guardian_approval_review_payload(assessment); + let mut notifications = Vec::new(); + + if let Some(notification) = parent_guardian_approval_review_notification( + conversation_id, + turn_id.clone(), + assessment, + review.clone(), + ) { + notifications.push(notification); + } + + notifications.push(legacy_guardian_approval_review_notification( + conversation_id, + turn_id, + assessment, + review, + )); + + notifications +} + #[allow(clippy::too_many_arguments)] pub(crate) async fn apply_bespoke_event_handling( event: Event, @@ -344,12 +513,14 @@ pub(crate) async fn apply_bespoke_event_handling( EventMsg::Warning(_warning_event) => {} EventMsg::GuardianAssessment(assessment) => { if let ApiVersion::V2 = api_version { - let notification = guardian_auto_approval_review_notification( + let notifications = guardian_approval_review_notifications( &conversation_id, &event_turn_id, &assessment, ); - outgoing.send_server_notification(notification).await; + for notification in notifications { + outgoing.send_server_notification(notification).await; + } } } EventMsg::ModelReroute(event) => { @@ -2907,13 +3078,13 @@ mod tests { } #[test] - fn guardian_assessment_started_uses_event_turn_id_fallback() { + fn guardian_assessment_started_emits_command_execution_and_legacy_notifications() { let conversation_id = ThreadId::new(); let action = json!({ "tool": "shell", "command": "rm -rf /tmp/example.sqlite", }); - let notification = guardian_auto_approval_review_notification( + let notifications = guardian_approval_review_notifications( &conversation_id, "turn-from-event", &GuardianAssessmentEvent { @@ -2926,33 +3097,51 @@ mod tests { action: Some(action.clone()), }, ); + assert_eq!(notifications.len(), 2); - match notification { - ServerNotification::ItemGuardianApprovalReviewStarted(payload) => { - assert_eq!(payload.thread_id, conversation_id.to_string()); - assert_eq!(payload.turn_id, "turn-from-event"); - assert_eq!(payload.target_item_id, "item-1"); + match (¬ifications[0], ¬ifications[1]) { + ( + ServerNotification::CommandExecutionGuardianApprovalReviewStarted(parent), + ServerNotification::ItemGuardianApprovalReviewStarted(legacy), + ) => { + assert_eq!(parent.thread_id, conversation_id.to_string()); + assert_eq!(parent.turn_id, "turn-from-event"); + assert_eq!(parent.item_id, "item-1"); assert_eq!( - payload.review.status, + parent.review.status, GuardianApprovalReviewStatus::InProgress ); - assert_eq!(payload.review.risk_score, None); - assert_eq!(payload.review.risk_level, None); - assert_eq!(payload.review.rationale, None); - assert_eq!(payload.action, Some(action)); + assert_eq!(parent.review.risk_score, None); + assert_eq!(parent.review.risk_level, None); + assert_eq!(parent.review.rationale, None); + assert_eq!(parent.action, Some(action.clone())); + + assert_eq!(legacy.thread_id, conversation_id.to_string()); + assert_eq!(legacy.turn_id, "turn-from-event"); + assert_eq!(legacy.target_item_id, "item-1"); + assert_eq!( + legacy.review.status, + GuardianApprovalReviewStatus::InProgress + ); + assert_eq!(legacy.review.risk_score, None); + assert_eq!(legacy.review.risk_level, None); + assert_eq!(legacy.review.rationale, None); + assert_eq!(legacy.action, Some(action)); } - other => panic!("unexpected notification: {other:?}"), + other => panic!("unexpected notifications: {other:?}"), } } #[test] - fn guardian_assessment_completed_emits_review_payload() { + fn guardian_assessment_completed_emits_file_change_and_legacy_notifications() { let conversation_id = ThreadId::new(); let action = json!({ - "tool": "shell", - "command": "rm -rf /tmp/example.sqlite", + "tool": "apply_patch", + "cwd": "/tmp/project", + "files": ["/tmp/project/src/main.rs"], + "change_count": 1, }); - let notification = guardian_auto_approval_review_notification( + let notifications = guardian_approval_review_notifications( &conversation_id, "turn-from-event", &GuardianAssessmentEvent { @@ -2965,37 +3154,109 @@ mod tests { action: Some(action.clone()), }, ); + assert_eq!(notifications.len(), 2); - match notification { - ServerNotification::ItemGuardianApprovalReviewCompleted(payload) => { - assert_eq!(payload.thread_id, conversation_id.to_string()); - assert_eq!(payload.turn_id, "turn-from-assessment"); - assert_eq!(payload.target_item_id, "item-2"); - assert_eq!(payload.review.status, GuardianApprovalReviewStatus::Denied); - assert_eq!(payload.review.risk_score, Some(91)); + match (¬ifications[0], ¬ifications[1]) { + ( + ServerNotification::FileChangeGuardianApprovalReviewCompleted(parent), + ServerNotification::ItemGuardianApprovalReviewCompleted(legacy), + ) => { + assert_eq!(parent.thread_id, conversation_id.to_string()); + assert_eq!(parent.turn_id, "turn-from-assessment"); + assert_eq!(parent.item_id, "item-2"); + assert_eq!(parent.review.status, GuardianApprovalReviewStatus::Denied); + assert_eq!(parent.review.risk_score, Some(91)); assert_eq!( - payload.review.risk_level, + parent.review.risk_level, Some(codex_app_server_protocol::GuardianRiskLevel::High) ); - assert_eq!(payload.review.rationale.as_deref(), Some("too risky")); - assert_eq!(payload.action, Some(action)); + assert_eq!(parent.review.rationale.as_deref(), Some("too risky")); + assert_eq!(parent.action, Some(action.clone())); + + assert_eq!(legacy.thread_id, conversation_id.to_string()); + assert_eq!(legacy.turn_id, "turn-from-assessment"); + assert_eq!(legacy.target_item_id, "item-2"); + assert_eq!(legacy.review.status, GuardianApprovalReviewStatus::Denied); + assert_eq!(legacy.review.risk_score, Some(91)); + assert_eq!( + legacy.review.risk_level, + Some(codex_app_server_protocol::GuardianRiskLevel::High) + ); + assert_eq!(legacy.review.rationale.as_deref(), Some("too risky")); + assert_eq!(legacy.action, Some(action)); } - other => panic!("unexpected notification: {other:?}"), + other => panic!("unexpected notifications: {other:?}"), } } #[test] - fn guardian_assessment_aborted_emits_completed_review_payload() { + fn guardian_assessment_completed_emits_mcp_and_legacy_notifications() { + let conversation_id = ThreadId::new(); + let action = json!({ + "tool": "mcp_tool_call", + "server": "github", + "tool_name": "create_issue", + }); + let notifications = guardian_approval_review_notifications( + &conversation_id, + "turn-from-event", + &GuardianAssessmentEvent { + id: "item-3".to_string(), + turn_id: "turn-from-assessment".to_string(), + status: codex_protocol::protocol::GuardianAssessmentStatus::Approved, + risk_score: Some(12), + risk_level: Some(codex_protocol::protocol::GuardianRiskLevel::Low), + rationale: Some("safe enough".to_string()), + action: Some(action.clone()), + }, + ); + assert_eq!(notifications.len(), 2); + + match (¬ifications[0], ¬ifications[1]) { + ( + ServerNotification::McpToolCallGuardianApprovalReviewCompleted(parent), + ServerNotification::ItemGuardianApprovalReviewCompleted(legacy), + ) => { + assert_eq!(parent.thread_id, conversation_id.to_string()); + assert_eq!(parent.turn_id, "turn-from-assessment"); + assert_eq!(parent.item_id, "item-3"); + assert_eq!(parent.review.status, GuardianApprovalReviewStatus::Approved); + assert_eq!(parent.review.risk_score, Some(12)); + assert_eq!( + parent.review.risk_level, + Some(codex_app_server_protocol::GuardianRiskLevel::Low) + ); + assert_eq!(parent.review.rationale.as_deref(), Some("safe enough")); + assert_eq!(parent.action, Some(action.clone())); + + assert_eq!(legacy.thread_id, conversation_id.to_string()); + assert_eq!(legacy.turn_id, "turn-from-assessment"); + assert_eq!(legacy.target_item_id, "item-3"); + assert_eq!(legacy.review.status, GuardianApprovalReviewStatus::Approved); + assert_eq!(legacy.review.risk_score, Some(12)); + assert_eq!( + legacy.review.risk_level, + Some(codex_app_server_protocol::GuardianRiskLevel::Low) + ); + assert_eq!(legacy.review.rationale.as_deref(), Some("safe enough")); + assert_eq!(legacy.action, Some(action)); + } + other => panic!("unexpected notifications: {other:?}"), + } + } + + #[test] + fn guardian_assessment_aborted_emits_legacy_notification_for_unmapped_tool() { let conversation_id = ThreadId::new(); let action = json!({ "tool": "network_access", "target": "api.openai.com:443", }); - let notification = guardian_auto_approval_review_notification( + let notifications = guardian_approval_review_notifications( &conversation_id, "turn-from-event", &GuardianAssessmentEvent { - id: "item-3".to_string(), + id: "item-4".to_string(), turn_id: "turn-from-assessment".to_string(), status: codex_protocol::protocol::GuardianAssessmentStatus::Aborted, risk_score: None, @@ -3004,17 +3265,18 @@ mod tests { action: Some(action.clone()), }, ); + assert_eq!(notifications.len(), 1); - match notification { + match ¬ifications[0] { ServerNotification::ItemGuardianApprovalReviewCompleted(payload) => { assert_eq!(payload.thread_id, conversation_id.to_string()); assert_eq!(payload.turn_id, "turn-from-assessment"); - assert_eq!(payload.target_item_id, "item-3"); + assert_eq!(payload.target_item_id, "item-4"); assert_eq!(payload.review.status, GuardianApprovalReviewStatus::Aborted); assert_eq!(payload.review.risk_score, None); assert_eq!(payload.review.risk_level, None); assert_eq!(payload.review.rationale, None); - assert_eq!(payload.action, Some(action)); + assert_eq!(payload.action, Some(action.clone())); } other => panic!("unexpected notification: {other:?}"), }