mirror of
https://github.com/openai/codex.git
synced 2026-11-08 20:40:33 +00:00
Preserve display instructions in answer moderation (#60172)
## Why Recovered answer history needs presentation instructions alongside the moderation flag so clients can apply the intended display behavior. ## What changed - Add optional `display` metadata with an `action` and optional `blockType`, `cyberTrustedAccess`, and `checkTrustedContacts` fields. - Carry display metadata through final answers, legacy events, thread history reconstruction, and legacy rollout migration. - Expose the metadata in the app-server protocol and update generated JSON schemas, TypeScript types, and Python SDK models. Missing display fields remain compatible with existing stored moderation data; the app-server emits absent optional values as `null`. ## Testing Extend the final-answer moderation test to cover display metadata in answer items and legacy events. Add serialization coverage for missing display data, nullable fields, and preservation of an explicit `false` value. GitOrigin-RevId: b798a2ecc53c2a94c7659ef3d9663b3143b70a1a
This commit is contained in:
@@ -177,8 +177,49 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
+41
@@ -7408,6 +7408,37 @@
|
||||
"title": "AgentMessageDeltaNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageInputContent": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -7454,6 +7485,16 @@
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
+41
@@ -523,6 +523,37 @@
|
||||
"title": "AgentMessageDeltaNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageInputContent": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -569,6 +600,16 @@
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -31,8 +31,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
+41
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -31,8 +31,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -31,8 +31,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,49 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AgentMessageDisplay": {
|
||||
"description": "A presentation instruction for Chat to apply to this answer when recovering history.",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "Unknown actions must be left for the producing client to handle.",
|
||||
"type": "string"
|
||||
},
|
||||
"blockType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"checkTrustedContacts": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cyberTrustedAccess": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AgentMessageModeration": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AgentMessageDisplay"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"moderated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
// 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.
|
||||
|
||||
/**
|
||||
* A presentation instruction for Chat to apply to this answer when recovering history.
|
||||
*/
|
||||
export type AgentMessageDisplay = {
|
||||
/**
|
||||
* Unknown actions must be left for the producing client to handle.
|
||||
*/
|
||||
action: string, blockType: string | null, cyberTrustedAccess: boolean | null, checkTrustedContacts: boolean | null, };
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
// 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 { AgentMessageDisplay } from "./AgentMessageDisplay";
|
||||
|
||||
export type AgentMessageModeration = { moderated: boolean, };
|
||||
export type AgentMessageModeration = { moderated: boolean, display: AgentMessageDisplay | null, };
|
||||
|
||||
@@ -22,6 +22,7 @@ export type { AdditionalNetworkPermissions } from "./AdditionalNetworkPermission
|
||||
export type { AdditionalPermissionProfile } from "./AdditionalPermissionProfile";
|
||||
export type { AgentMessageDelivery } from "./AgentMessageDelivery";
|
||||
export type { AgentMessageDeltaNotification } from "./AgentMessageDeltaNotification";
|
||||
export type { AgentMessageDisplay } from "./AgentMessageDisplay";
|
||||
export type { AgentMessageModeration } from "./AgentMessageModeration";
|
||||
export type { AllowDenyRequirement } from "./AllowDenyRequirement";
|
||||
export type { AnalyticsConfig } from "./AnalyticsConfig";
|
||||
|
||||
@@ -638,6 +638,7 @@ impl ThreadHistoryBuilder {
|
||||
.as_ref()
|
||||
.map(|decision| AgentMessageModeration {
|
||||
moderated: decision.moderated,
|
||||
display: decision.display.clone().map(Into::into),
|
||||
}),
|
||||
id,
|
||||
text: payload.message.clone(),
|
||||
|
||||
@@ -28,6 +28,7 @@ use codex_protocol::approvals::GuardianAssessmentDecisionSource as CoreGuardianA
|
||||
use codex_protocol::approvals::GuardianCommandSource as CoreGuardianCommandSource;
|
||||
use codex_protocol::items::AgentMessageContent as CoreAgentMessageContent;
|
||||
pub use codex_protocol::items::AgentMessageDelivery;
|
||||
use codex_protocol::items::AgentMessageDisplay as CoreAgentMessageDisplay;
|
||||
use codex_protocol::items::AgentMessageModeration as CoreAgentMessageModeration;
|
||||
pub use codex_protocol::items::AsyncUserInputQuestion;
|
||||
use codex_protocol::items::CollabAgentTool as CoreCollabAgentTool;
|
||||
@@ -150,17 +151,42 @@ pub enum CommandAction {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AgentMessageModeration {
|
||||
pub moderated: bool,
|
||||
pub display: Option<AgentMessageDisplay>,
|
||||
}
|
||||
|
||||
impl From<CoreAgentMessageModeration> for AgentMessageModeration {
|
||||
fn from(value: CoreAgentMessageModeration) -> Self {
|
||||
Self {
|
||||
moderated: value.moderated,
|
||||
display: value.display.map(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A presentation instruction for Chat to apply to this answer when recovering history.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AgentMessageDisplay {
|
||||
/// Unknown actions must be left for the producing client to handle.
|
||||
pub action: String,
|
||||
pub block_type: Option<String>,
|
||||
pub cyber_trusted_access: Option<bool>,
|
||||
pub check_trusted_contacts: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<CoreAgentMessageDisplay> for AgentMessageDisplay {
|
||||
fn from(value: CoreAgentMessageDisplay) -> Self {
|
||||
Self {
|
||||
action: value.action,
|
||||
block_type: value.block_type,
|
||||
cyber_trusted_access: value.cyber_trusted_access,
|
||||
check_trusted_contacts: value.check_trusted_contacts,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3170,6 +3170,35 @@ fn audio_references_round_trip_through_core_and_json() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn answer_moderation_exposes_nullable_display_fields() {
|
||||
for (stored, expected) in [
|
||||
(
|
||||
json!({"moderated": false}),
|
||||
json!({"moderated": false, "display": null}),
|
||||
),
|
||||
(
|
||||
json!({"moderated": true, "display": {
|
||||
"action": "answerHelpline",
|
||||
"checkTrustedContacts": false,
|
||||
}}),
|
||||
json!({"moderated": true, "display": {
|
||||
"action": "answerHelpline",
|
||||
"blockType": null,
|
||||
"cyberTrustedAccess": null,
|
||||
"checkTrustedContacts": false,
|
||||
}}),
|
||||
),
|
||||
] {
|
||||
let core: codex_protocol::items::AgentMessageModeration =
|
||||
serde_json::from_value(stored).unwrap();
|
||||
assert_eq!(
|
||||
serde_json::to_value(AgentMessageModeration::from(core)).unwrap(),
|
||||
expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn core_turn_item_into_thread_item_converts_supported_variants() {
|
||||
let user_item = TurnItem::UserMessage(UserMessageItem {
|
||||
@@ -3297,7 +3326,10 @@ fn core_turn_item_into_thread_item_converts_supported_variants() {
|
||||
);
|
||||
|
||||
let agent_item_with_phase = TurnItem::AgentMessage(AgentMessageItem {
|
||||
moderation: Some(codex_protocol::items::AgentMessageModeration { moderated: true }),
|
||||
moderation: Some(codex_protocol::items::AgentMessageModeration {
|
||||
moderated: true,
|
||||
display: None,
|
||||
}),
|
||||
id: "agent-2".to_string(),
|
||||
content: vec![AgentMessageContent::Text {
|
||||
text: "final".to_string(),
|
||||
@@ -3319,7 +3351,10 @@ fn core_turn_item_into_thread_item_converts_supported_variants() {
|
||||
assert_eq!(
|
||||
ThreadItemPayload::from(agent_item_with_phase),
|
||||
ThreadItemPayload::AgentMessage {
|
||||
moderation: Some(AgentMessageModeration { moderated: true }),
|
||||
moderation: Some(AgentMessageModeration {
|
||||
moderated: true,
|
||||
display: None
|
||||
}),
|
||||
id: "agent-2".to_string(),
|
||||
text: "final".to_string(),
|
||||
phase: Some(MessagePhase::FinalAnswer),
|
||||
|
||||
@@ -342,6 +342,7 @@ pub(crate) fn apply_answer_moderation(
|
||||
{
|
||||
answer.moderation = Some(codex_protocol::items::AgentMessageModeration {
|
||||
moderated: decision.moderated,
|
||||
display: decision.display.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ async fn final_answer_carries_its_moderation_decision() -> Result<()> {
|
||||
responses::sse(vec![
|
||||
responses::ev_response_created("resp-1"),
|
||||
json!({"type":"response.metadata","metadata":{"openai_chatgpt_moderation_metadata":{
|
||||
"final_answer_moderation":{"item_id":"msg-42","moderated":true},
|
||||
"final_answer_moderation":{"item_id":"msg-42","moderated":true,"display":{"action":"answerHelpline"}},
|
||||
"generation":{"private":"classifier details"}
|
||||
}}}),
|
||||
answer,
|
||||
@@ -494,13 +494,16 @@ async fn final_answer_carries_its_moderation_decision() -> Result<()> {
|
||||
panic!("expected assistant answer");
|
||||
};
|
||||
let public = serde_json::to_value(&message)?;
|
||||
assert_eq!(public["moderation"], json!({"moderated": true}));
|
||||
assert_eq!(
|
||||
public["moderation"],
|
||||
json!({"moderated": true,"display":{"action":"answerHelpline"}})
|
||||
);
|
||||
let [EventMsg::AgentMessage(legacy)] = &message.as_legacy_events()[..] else {
|
||||
panic!("expected one legacy answer");
|
||||
};
|
||||
assert_eq!(
|
||||
serde_json::to_value(&legacy.moderation)?,
|
||||
json!({"item_id":"msg-42","moderated":true})
|
||||
json!({"item_id":"msg-42","moderated":true,"display":{"action":"answerHelpline"}})
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -151,9 +151,30 @@ pub struct AsyncUserInputQuestion {
|
||||
pub options: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, TS, JsonSchema)]
|
||||
/// A presentation instruction for Chat to apply to this answer when recovering history.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, TS, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AgentMessageDisplay {
|
||||
/// Unknown actions must be left for the producing client to handle.
|
||||
pub action: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub block_type: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub cyber_trusted_access: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub check_trusted_contacts: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, TS, JsonSchema)]
|
||||
pub struct AgentMessageModeration {
|
||||
pub moderated: bool,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub display: Option<AgentMessageDisplay>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, TS, JsonSchema)]
|
||||
|
||||
@@ -139,13 +139,14 @@ impl AgentMessageItem {
|
||||
questions: self.questions.clone(),
|
||||
})
|
||||
};
|
||||
if let Some(decision) = self.moderation {
|
||||
if let Some(decision) = &self.moderation {
|
||||
// The canonical answer has one ID even when the model supplied multiple text parts.
|
||||
return vec![event(
|
||||
texts.collect(),
|
||||
Some(crate::protocol::TargetedAnswerModeration {
|
||||
item_id: self.id.clone(),
|
||||
moderated: decision.moderated,
|
||||
display: decision.display.clone(),
|
||||
}),
|
||||
)];
|
||||
}
|
||||
|
||||
@@ -2400,6 +2400,9 @@ pub struct ModelVerificationEvent {
|
||||
pub struct TargetedAnswerModeration {
|
||||
pub item_id: String,
|
||||
pub moderated: bool,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub display: Option<crate::items::AgentMessageDisplay>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, TS)]
|
||||
|
||||
@@ -161,6 +161,7 @@ pub(super) fn completed_item(
|
||||
moderation: event.moderation.as_ref().map(|decision| {
|
||||
codex_protocol::items::AgentMessageModeration {
|
||||
moderated: decision.moderated,
|
||||
display: decision.display.clone(),
|
||||
}
|
||||
}),
|
||||
id: event
|
||||
|
||||
@@ -149,6 +149,18 @@ class AgentMessageDeltaNotification(BaseModel):
|
||||
turn_id: Annotated[str, Field(alias="turnId")]
|
||||
|
||||
|
||||
class AgentMessageDisplay(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
)
|
||||
action: Annotated[
|
||||
str, Field(description="Unknown actions must be left for the producing client to handle.")
|
||||
]
|
||||
block_type: Annotated[str | None, Field(alias="blockType")] = None
|
||||
check_trusted_contacts: Annotated[bool | None, Field(alias="checkTrustedContacts")] = None
|
||||
cyber_trusted_access: Annotated[bool | None, Field(alias="cyberTrustedAccess")] = None
|
||||
|
||||
|
||||
class InputTextAgentMessageInputContent(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
@@ -177,6 +189,7 @@ class AgentMessageModeration(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
)
|
||||
display: AgentMessageDisplay | None = None
|
||||
moderated: bool
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user