mirror of
https://github.com/openai/codex.git
synced 2026-11-03 19:53:25 +00:00
add session source to telemetry
This commit is contained in:
@@ -1557,6 +1557,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ReasoningItemReasoningSummary"
|
||||
@@ -1697,6 +1707,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -1724,6 +1744,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"output": {
|
||||
"$ref": "#/definitions/FunctionCallOutputBody"
|
||||
},
|
||||
@@ -1799,6 +1829,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -1835,6 +1875,16 @@
|
||||
"execution": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -1878,6 +1928,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -1903,6 +1963,16 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -1937,6 +2007,16 @@
|
||||
"ghost_commit": {
|
||||
"$ref": "#/definitions/GhostCommit"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"ghost_snapshot"
|
||||
@@ -1957,6 +2037,16 @@
|
||||
"encrypted_content": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"compaction"
|
||||
@@ -2018,6 +2108,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"session_source": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SessionSourceMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"user_message_type": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -2418,6 +2518,21 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SessionSourceMetadata": {
|
||||
"enum": [
|
||||
"cli",
|
||||
"vscode",
|
||||
"exec",
|
||||
"mcp",
|
||||
"subagent_review",
|
||||
"subagent_compact",
|
||||
"subagent_memory_consolidation",
|
||||
"subagent_thread_spawn",
|
||||
"subagent_other",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"Settings": {
|
||||
"description": "Settings for a collaboration mode.",
|
||||
"properties": {
|
||||
|
||||
@@ -10224,6 +10224,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/ReasoningItemReasoningSummary"
|
||||
@@ -10364,6 +10374,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -10391,6 +10411,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"output": {
|
||||
"$ref": "#/definitions/v2/FunctionCallOutputBody"
|
||||
},
|
||||
@@ -10466,6 +10496,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -10502,6 +10542,16 @@
|
||||
"execution": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -10545,6 +10595,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -10570,6 +10630,16 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -10604,6 +10674,16 @@
|
||||
"ghost_commit": {
|
||||
"$ref": "#/definitions/v2/GhostCommit"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"ghost_snapshot"
|
||||
@@ -10624,6 +10704,16 @@
|
||||
"encrypted_content": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"compaction"
|
||||
@@ -10685,6 +10775,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"session_source": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/SessionSourceMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"user_message_type": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -11186,6 +11286,21 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"SessionSourceMetadata": {
|
||||
"enum": [
|
||||
"cli",
|
||||
"vscode",
|
||||
"exec",
|
||||
"mcp",
|
||||
"subagent_review",
|
||||
"subagent_compact",
|
||||
"subagent_memory_consolidation",
|
||||
"subagent_thread_spawn",
|
||||
"subagent_other",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"Settings": {
|
||||
"description": "Settings for a collaboration mode.",
|
||||
"properties": {
|
||||
|
||||
@@ -7012,6 +7012,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ReasoningItemReasoningSummary"
|
||||
@@ -7152,6 +7162,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -7179,6 +7199,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"output": {
|
||||
"$ref": "#/definitions/FunctionCallOutputBody"
|
||||
},
|
||||
@@ -7254,6 +7284,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -7290,6 +7330,16 @@
|
||||
"execution": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7333,6 +7383,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -7358,6 +7418,16 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7392,6 +7462,16 @@
|
||||
"ghost_commit": {
|
||||
"$ref": "#/definitions/GhostCommit"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"ghost_snapshot"
|
||||
@@ -7412,6 +7492,16 @@
|
||||
"encrypted_content": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"compaction"
|
||||
@@ -7473,6 +7563,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"session_source": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SessionSourceMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"user_message_type": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -8946,6 +9046,21 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"SessionSourceMetadata": {
|
||||
"enum": [
|
||||
"cli",
|
||||
"vscode",
|
||||
"exec",
|
||||
"mcp",
|
||||
"subagent_review",
|
||||
"subagent_compact",
|
||||
"subagent_memory_consolidation",
|
||||
"subagent_thread_spawn",
|
||||
"subagent_other",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"Settings": {
|
||||
"description": "Settings for a collaboration mode.",
|
||||
"properties": {
|
||||
|
||||
+115
@@ -405,6 +405,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ReasoningItemReasoningSummary"
|
||||
@@ -545,6 +555,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -572,6 +592,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"output": {
|
||||
"$ref": "#/definitions/FunctionCallOutputBody"
|
||||
},
|
||||
@@ -647,6 +677,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -683,6 +723,16 @@
|
||||
"execution": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -726,6 +776,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -751,6 +811,16 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -785,6 +855,16 @@
|
||||
"ghost_commit": {
|
||||
"$ref": "#/definitions/GhostCommit"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"ghost_snapshot"
|
||||
@@ -805,6 +885,16 @@
|
||||
"encrypted_content": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"compaction"
|
||||
@@ -866,6 +956,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"session_source": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SessionSourceMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"user_message_type": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -1007,6 +1107,21 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SessionSourceMetadata": {
|
||||
"enum": [
|
||||
"cli",
|
||||
"vscode",
|
||||
"exec",
|
||||
"mcp",
|
||||
"subagent_review",
|
||||
"subagent_compact",
|
||||
"subagent_memory_consolidation",
|
||||
"subagent_thread_spawn",
|
||||
"subagent_other",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UserMessageType": {
|
||||
"enum": [
|
||||
"prompt",
|
||||
|
||||
@@ -471,6 +471,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ReasoningItemReasoningSummary"
|
||||
@@ -611,6 +621,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -638,6 +658,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"output": {
|
||||
"$ref": "#/definitions/FunctionCallOutputBody"
|
||||
},
|
||||
@@ -713,6 +743,16 @@
|
||||
"call_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -749,6 +789,16 @@
|
||||
"execution": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -792,6 +842,16 @@
|
||||
],
|
||||
"writeOnly": true
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -817,6 +877,16 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -851,6 +921,16 @@
|
||||
"ghost_commit": {
|
||||
"$ref": "#/definitions/GhostCommit"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"ghost_snapshot"
|
||||
@@ -871,6 +951,16 @@
|
||||
"encrypted_content": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ResponseItemMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"compaction"
|
||||
@@ -932,6 +1022,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"session_source": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SessionSourceMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"user_message_type": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -1088,6 +1188,21 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SessionSourceMetadata": {
|
||||
"enum": [
|
||||
"cli",
|
||||
"vscode",
|
||||
"exec",
|
||||
"mcp",
|
||||
"subagent_review",
|
||||
"subagent_compact",
|
||||
"subagent_memory_consolidation",
|
||||
"subagent_thread_spawn",
|
||||
"subagent_other",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UserMessageType": {
|
||||
"enum": [
|
||||
"prompt",
|
||||
|
||||
@@ -12,8 +12,8 @@ import type { ReasoningItemReasoningSummary } from "./ReasoningItemReasoningSumm
|
||||
import type { ResponseItemMetadata } from "./ResponseItemMetadata";
|
||||
import type { WebSearchAction } from "./WebSearchAction";
|
||||
|
||||
export type ResponseItem = { "type": "message", role: string, content: Array<ContentItem>, metadata?: ResponseItemMetadata, end_turn?: boolean, phase?: MessagePhase, } | { "type": "reasoning", summary: Array<ReasoningItemReasoningSummary>, content?: Array<ReasoningItemContent>, encrypted_content: string | null, } | { "type": "local_shell_call",
|
||||
export type ResponseItem = { "type": "message", role: string, content: Array<ContentItem>, metadata?: ResponseItemMetadata, end_turn?: boolean, phase?: MessagePhase, } | { "type": "reasoning", summary: Array<ReasoningItemReasoningSummary>, content?: Array<ReasoningItemContent>, encrypted_content: string | null, metadata?: ResponseItemMetadata, } | { "type": "local_shell_call",
|
||||
/**
|
||||
* Set when using the Responses API.
|
||||
*/
|
||||
call_id: string | null, status: LocalShellStatus, action: LocalShellAction, metadata?: ResponseItemMetadata, } | { "type": "function_call", name: string, namespace?: string, arguments: string, call_id: string, metadata?: ResponseItemMetadata, } | { "type": "tool_search_call", call_id: string | null, status?: string, execution: string, arguments: unknown, } | { "type": "function_call_output", call_id: string, output: FunctionCallOutputBody, } | { "type": "custom_tool_call", status?: string, call_id: string, name: string, input: string, metadata?: ResponseItemMetadata, } | { "type": "custom_tool_call_output", call_id: string, name?: string, output: FunctionCallOutputBody, } | { "type": "tool_search_output", call_id: string | null, status: string, execution: string, tools: unknown[], } | { "type": "web_search_call", status?: string, action?: WebSearchAction, } | { "type": "image_generation_call", id: string, status: string, revised_prompt?: string, result: string, } | { "type": "ghost_snapshot", ghost_commit: GhostCommit, } | { "type": "compaction", encrypted_content: string, } | { "type": "other" };
|
||||
call_id: string | null, status: LocalShellStatus, action: LocalShellAction, metadata?: ResponseItemMetadata, } | { "type": "function_call", name: string, namespace?: string, arguments: string, call_id: string, metadata?: ResponseItemMetadata, } | { "type": "tool_search_call", call_id: string | null, status?: string, execution: string, arguments: unknown, metadata?: ResponseItemMetadata, } | { "type": "function_call_output", call_id: string, output: FunctionCallOutputBody, metadata?: ResponseItemMetadata, } | { "type": "custom_tool_call", status?: string, call_id: string, name: string, input: string, metadata?: ResponseItemMetadata, } | { "type": "custom_tool_call_output", call_id: string, name?: string, output: FunctionCallOutputBody, metadata?: ResponseItemMetadata, } | { "type": "tool_search_output", call_id: string | null, status: string, execution: string, tools: unknown[], metadata?: ResponseItemMetadata, } | { "type": "web_search_call", status?: string, action?: WebSearchAction, metadata?: ResponseItemMetadata, } | { "type": "image_generation_call", id: string, status: string, revised_prompt?: string, result: string, metadata?: ResponseItemMetadata, } | { "type": "ghost_snapshot", ghost_commit: GhostCommit, metadata?: ResponseItemMetadata, } | { "type": "compaction", encrypted_content: string, metadata?: ResponseItemMetadata, } | { "type": "other" };
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ReviewDecisionMetadata } from "./ReviewDecisionMetadata";
|
||||
import type { SandboxPolicyMetadata } from "./SandboxPolicyMetadata";
|
||||
import type { SessionSourceMetadata } from "./SessionSourceMetadata";
|
||||
import type { UserMessageType } from "./UserMessageType";
|
||||
|
||||
export type ResponseItemMetadata = { user_message_type?: UserMessageType,
|
||||
/**
|
||||
* Client-visible UUID generated by Codex for this item.
|
||||
*/
|
||||
uuid?: string, sandbox_policy?: SandboxPolicyMetadata, is_tool_call_escalated?: boolean, review_decision?: ReviewDecisionMetadata, };
|
||||
uuid?: string, sandbox_policy?: SandboxPolicyMetadata, is_tool_call_escalated?: boolean, review_decision?: ReviewDecisionMetadata, session_source?: SessionSourceMetadata, };
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// 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.
|
||||
|
||||
export type SessionSourceMetadata = "cli" | "vscode" | "exec" | "mcp" | "subagent_review" | "subagent_compact" | "subagent_memory_consolidation" | "subagent_thread_spawn" | "subagent_other" | "unknown";
|
||||
@@ -67,6 +67,7 @@ export type { ServerNotification } from "./ServerNotification";
|
||||
export type { ServerRequest } from "./ServerRequest";
|
||||
export type { ServiceTier } from "./ServiceTier";
|
||||
export type { SessionSource } from "./SessionSource";
|
||||
export type { SessionSourceMetadata } from "./SessionSourceMetadata";
|
||||
export type { Settings } from "./Settings";
|
||||
export type { SubAgentSource } from "./SubAgentSource";
|
||||
export type { ThreadId } from "./ThreadId";
|
||||
|
||||
@@ -187,6 +187,7 @@ impl AgentControl {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
output,
|
||||
metadata: None,
|
||||
},
|
||||
));
|
||||
let initial_history = InitialHistory::Forked(forked_rollout_items);
|
||||
|
||||
@@ -551,11 +551,9 @@ async fn spawn_agent_fork_injects_output_for_parent_spawn_call() {
|
||||
.expect("child thread should be registered");
|
||||
let history = child_thread.codex.session.clone_history().await;
|
||||
let injected_output = history.raw_items().iter().find_map(|item| match item {
|
||||
ResponseItem::FunctionCallOutput { call_id, output }
|
||||
if call_id == &parent_spawn_call_id =>
|
||||
{
|
||||
Some(output)
|
||||
}
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id, output, ..
|
||||
} if call_id == &parent_spawn_call_id => Some(output),
|
||||
_ => None,
|
||||
});
|
||||
let injected_output =
|
||||
|
||||
@@ -145,6 +145,7 @@ async fn build_arc_monitor_request_includes_relevant_history_and_null_policies()
|
||||
summary: Vec::new(),
|
||||
content: None,
|
||||
encrypted_content: Some("encrypted-old".to_string()),
|
||||
metadata: None,
|
||||
}],
|
||||
&turn_context,
|
||||
)
|
||||
@@ -174,6 +175,7 @@ async fn build_arc_monitor_request_includes_relevant_history_and_null_policies()
|
||||
summary: Vec::new(),
|
||||
content: None,
|
||||
encrypted_content: Some("encrypted-latest".to_string()),
|
||||
metadata: None,
|
||||
}],
|
||||
&turn_context,
|
||||
)
|
||||
|
||||
@@ -155,6 +155,7 @@ fn reserializes_shell_outputs_for_function_and_custom_tool_calls() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text(raw_output.to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::CustomToolCall {
|
||||
id: None,
|
||||
@@ -168,6 +169,7 @@ fn reserializes_shell_outputs_for_function_and_custom_tool_calls() {
|
||||
call_id: "call-2".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text(raw_output.to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -187,6 +189,7 @@ fn reserializes_shell_outputs_for_function_and_custom_tool_calls() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text(expected_output.to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::CustomToolCall {
|
||||
id: None,
|
||||
@@ -200,6 +203,7 @@ fn reserializes_shell_outputs_for_function_and_custom_tool_calls() {
|
||||
call_id: "call-2".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text(expected_output.to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
+125
-60
@@ -334,6 +334,7 @@ use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::models::ResponseItemMetadata;
|
||||
use codex_protocol::models::SandboxPolicyMetadata;
|
||||
use codex_protocol::models::SessionSourceMetadata;
|
||||
use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig;
|
||||
use codex_protocol::protocol::CodexErrorInfo;
|
||||
use codex_protocol::protocol::InitialHistory;
|
||||
@@ -1043,39 +1044,29 @@ fn user_message_metadata_patch(
|
||||
}
|
||||
}
|
||||
|
||||
fn stamp_message_metadata_on_response_item(
|
||||
item: ResponseItem,
|
||||
patch: Option<ResponseItemMetadata>,
|
||||
) -> ResponseItem {
|
||||
let Some(patch) = patch else {
|
||||
return item;
|
||||
};
|
||||
if patch.is_empty() {
|
||||
return item;
|
||||
}
|
||||
|
||||
match item {
|
||||
ResponseItem::Message {
|
||||
id,
|
||||
role,
|
||||
content,
|
||||
metadata,
|
||||
end_turn,
|
||||
phase,
|
||||
} if role == "user" => {
|
||||
let mut metadata_value = metadata.unwrap_or_default();
|
||||
metadata_value.merge_from(patch);
|
||||
let metadata = (!metadata_value.is_empty()).then_some(metadata_value);
|
||||
ResponseItem::Message {
|
||||
id,
|
||||
role,
|
||||
content,
|
||||
metadata,
|
||||
end_turn,
|
||||
phase,
|
||||
}
|
||||
fn session_source_to_metadata(session_source: &SessionSource) -> SessionSourceMetadata {
|
||||
match session_source {
|
||||
SessionSource::Cli => SessionSourceMetadata::Cli,
|
||||
SessionSource::VSCode => SessionSourceMetadata::Vscode,
|
||||
SessionSource::Exec => SessionSourceMetadata::Exec,
|
||||
SessionSource::Mcp => SessionSourceMetadata::Mcp,
|
||||
SessionSource::SubAgent(SubAgentSource::Review) => SessionSourceMetadata::SubagentReview,
|
||||
SessionSource::SubAgent(SubAgentSource::Compact) => SessionSourceMetadata::SubagentCompact,
|
||||
SessionSource::SubAgent(SubAgentSource::MemoryConsolidation) => {
|
||||
SessionSourceMetadata::SubagentMemoryConsolidation
|
||||
}
|
||||
other => other,
|
||||
SessionSource::SubAgent(SubAgentSource::ThreadSpawn { .. }) => {
|
||||
SessionSourceMetadata::SubagentThreadSpawn
|
||||
}
|
||||
SessionSource::SubAgent(SubAgentSource::Other(_)) => SessionSourceMetadata::SubagentOther,
|
||||
SessionSource::Unknown => SessionSourceMetadata::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
fn session_source_metadata_patch(session_source: &SessionSource) -> ResponseItemMetadata {
|
||||
ResponseItemMetadata {
|
||||
session_source: Some(session_source_to_metadata(session_source)),
|
||||
..ResponseItemMetadata::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1091,25 +1082,35 @@ fn response_item_tool_call_id(item: &ResponseItem) -> Option<&str> {
|
||||
}
|
||||
}
|
||||
|
||||
fn tool_call_metadata_slot_mut(
|
||||
fn response_item_metadata_slot_mut(
|
||||
item: &mut ResponseItem,
|
||||
) -> Option<&mut Option<ResponseItemMetadata>> {
|
||||
match item {
|
||||
ResponseItem::LocalShellCall { metadata, .. }
|
||||
ResponseItem::Message { metadata, .. }
|
||||
| ResponseItem::Reasoning { metadata, .. }
|
||||
| ResponseItem::LocalShellCall { metadata, .. }
|
||||
| ResponseItem::FunctionCall { metadata, .. }
|
||||
| ResponseItem::CustomToolCall { metadata, .. } => Some(metadata),
|
||||
| ResponseItem::ToolSearchCall { metadata, .. }
|
||||
| ResponseItem::FunctionCallOutput { metadata, .. }
|
||||
| ResponseItem::CustomToolCall { metadata, .. }
|
||||
| ResponseItem::CustomToolCallOutput { metadata, .. }
|
||||
| ResponseItem::ToolSearchOutput { metadata, .. }
|
||||
| ResponseItem::WebSearchCall { metadata, .. }
|
||||
| ResponseItem::ImageGenerationCall { metadata, .. }
|
||||
| ResponseItem::GhostSnapshot { metadata, .. }
|
||||
| ResponseItem::Compaction { metadata, .. } => Some(metadata),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn stamp_tool_metadata_on_response_item(
|
||||
fn stamp_response_item_metadata_on_response_item(
|
||||
mut item: ResponseItem,
|
||||
patch: ResponseItemMetadata,
|
||||
) -> ResponseItem {
|
||||
if patch.is_empty() {
|
||||
return item;
|
||||
}
|
||||
let Some(metadata_slot) = tool_call_metadata_slot_mut(&mut item) else {
|
||||
let Some(metadata_slot) = response_item_metadata_slot_mut(&mut item) else {
|
||||
return item;
|
||||
};
|
||||
let mut metadata = metadata_slot.take().unwrap_or_default();
|
||||
@@ -1118,17 +1119,47 @@ fn stamp_tool_metadata_on_response_item(
|
||||
item
|
||||
}
|
||||
|
||||
fn tool_call_metadata_or_default(item: &ResponseItem) -> Option<ResponseItemMetadata> {
|
||||
fn response_item_metadata_or_default(item: &ResponseItem) -> Option<ResponseItemMetadata> {
|
||||
match item {
|
||||
ResponseItem::LocalShellCall { metadata, .. }
|
||||
ResponseItem::Message { metadata, .. }
|
||||
| ResponseItem::Reasoning { metadata, .. }
|
||||
| ResponseItem::LocalShellCall { metadata, .. }
|
||||
| ResponseItem::FunctionCall { metadata, .. }
|
||||
| ResponseItem::CustomToolCall { metadata, .. } => {
|
||||
Some(metadata.clone().unwrap_or_default())
|
||||
}
|
||||
| ResponseItem::ToolSearchCall { metadata, .. }
|
||||
| ResponseItem::FunctionCallOutput { metadata, .. }
|
||||
| ResponseItem::CustomToolCall { metadata, .. }
|
||||
| ResponseItem::CustomToolCallOutput { metadata, .. }
|
||||
| ResponseItem::ToolSearchOutput { metadata, .. }
|
||||
| ResponseItem::WebSearchCall { metadata, .. }
|
||||
| ResponseItem::ImageGenerationCall { metadata, .. }
|
||||
| ResponseItem::GhostSnapshot { metadata, .. }
|
||||
| ResponseItem::Compaction { metadata, .. } => Some(metadata.clone().unwrap_or_default()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn review_decision_to_metadata(decision: &ReviewDecision) -> ReviewDecisionMetadata {
|
||||
match decision {
|
||||
ReviewDecision::Approved => ReviewDecisionMetadata::Approved,
|
||||
ReviewDecision::ApprovedExecpolicyAmendment { .. } => {
|
||||
ReviewDecisionMetadata::ApprovedWithAmendment
|
||||
}
|
||||
ReviewDecision::ApprovedForSession => ReviewDecisionMetadata::ApprovedForSession,
|
||||
ReviewDecision::NetworkPolicyAmendment {
|
||||
network_policy_amendment,
|
||||
} => match network_policy_amendment.action {
|
||||
codex_protocol::protocol::NetworkPolicyRuleAction::Allow => {
|
||||
ReviewDecisionMetadata::ApprovedWithNetworkPolicyAllow
|
||||
}
|
||||
codex_protocol::protocol::NetworkPolicyRuleAction::Deny => {
|
||||
ReviewDecisionMetadata::DeniedWithNetworkPolicyDeny
|
||||
}
|
||||
},
|
||||
ReviewDecision::Denied => ReviewDecisionMetadata::Denied,
|
||||
ReviewDecision::Abort => ReviewDecisionMetadata::Abort,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct ToolApprovalMetadataSnapshot {
|
||||
approval_outcomes_by_call_id: HashMap<String, ApprovalOutcomeMetadata>,
|
||||
@@ -1150,7 +1181,7 @@ fn stamp_tool_approval_metadata_with_snapshot(
|
||||
let outcome = snapshot.approval_outcomes_by_call_id.get(call_id).cloned();
|
||||
let has_pending_approval = snapshot.pending_approval_call_ids.contains(call_id);
|
||||
|
||||
let mut metadata = match tool_call_metadata_or_default(&response_item) {
|
||||
let mut metadata = match response_item_metadata_or_default(&response_item) {
|
||||
Some(metadata) => metadata,
|
||||
None => return response_item,
|
||||
};
|
||||
@@ -1168,11 +1199,11 @@ fn stamp_tool_approval_metadata_with_snapshot(
|
||||
metadata.review_decision = None;
|
||||
}
|
||||
None => {
|
||||
return stamp_tool_metadata_on_response_item(response_item, metadata);
|
||||
return stamp_response_item_metadata_on_response_item(response_item, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
stamp_tool_metadata_on_response_item(response_item, metadata)
|
||||
stamp_response_item_metadata_on_response_item(response_item, metadata)
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -4033,6 +4064,14 @@ impl Session {
|
||||
turn_context: &TurnContext,
|
||||
response_item: ResponseItem,
|
||||
) {
|
||||
let response_item = if self.enabled(Feature::ItemMetadata) {
|
||||
stamp_response_item_metadata_on_response_item(
|
||||
response_item,
|
||||
session_source_metadata_patch(&turn_context.session_source),
|
||||
)
|
||||
} else {
|
||||
response_item
|
||||
};
|
||||
let response_item = self
|
||||
.stamp_tool_approval_metadata(turn_context, response_item)
|
||||
.await;
|
||||
@@ -4060,11 +4099,15 @@ impl Session {
|
||||
patch.sandbox_policy = Some(sandbox_policy_to_metadata(
|
||||
turn_context.sandbox_policy.get(),
|
||||
));
|
||||
patch.merge_from(session_source_metadata_patch(&turn_context.session_source));
|
||||
Some(patch)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let response_item = stamp_message_metadata_on_response_item(response_item, metadata_patch);
|
||||
let response_item = match metadata_patch {
|
||||
Some(patch) => stamp_response_item_metadata_on_response_item(response_item, patch),
|
||||
None => response_item,
|
||||
};
|
||||
|
||||
// Persist the user message to history, but emit the turn item from `UserInput` so
|
||||
// UI-only `text_elements` are preserved. `ResponseItem::Message` does not carry
|
||||
@@ -4165,11 +4208,17 @@ impl Session {
|
||||
}
|
||||
|
||||
let mut input_item: ResponseInputItem = input.into();
|
||||
let metadata = Some(user_message_metadata_patch(
|
||||
let mut metadata = user_message_metadata_patch(
|
||||
UserMessageType::PromptSteering,
|
||||
self.enabled(Feature::ItemMetadata)
|
||||
.then(|| sandbox_policy_to_metadata(active_task.turn_context.sandbox_policy.get())),
|
||||
));
|
||||
);
|
||||
if self.enabled(Feature::ItemMetadata) {
|
||||
metadata.merge_from(session_source_metadata_patch(
|
||||
&active_task.turn_context.session_source,
|
||||
));
|
||||
}
|
||||
let metadata = Some(metadata);
|
||||
if self.enabled(Feature::ItemMetadata)
|
||||
&& let Some(metadata_patch) = metadata.as_ref()
|
||||
{
|
||||
@@ -4189,20 +4238,31 @@ impl Session {
|
||||
let mut active = self.active_turn.lock().await;
|
||||
match active.as_mut() {
|
||||
Some(at) => {
|
||||
let sandbox_policy = at.tasks.first().map(|(_, turn_context)| {
|
||||
sandbox_policy_to_metadata(turn_context.turn_context.sandbox_policy.get())
|
||||
let first_turn_context = at.tasks.first().map(|(_, task)| &task.turn_context);
|
||||
let sandbox_policy = first_turn_context.map(|turn_context| {
|
||||
sandbox_policy_to_metadata(turn_context.sandbox_policy.get())
|
||||
});
|
||||
let session_source =
|
||||
first_turn_context.map(|turn_context| turn_context.session_source.clone());
|
||||
let mut ts = at.turn_state.lock().await;
|
||||
for mut item in input {
|
||||
let metadata = match &item {
|
||||
ResponseInputItem::Message { .. } => Some(user_message_metadata_patch(
|
||||
UserMessageType::PromptQueued,
|
||||
if self.enabled(Feature::ItemMetadata) {
|
||||
sandbox_policy.clone()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
)),
|
||||
ResponseInputItem::Message { .. } => {
|
||||
let mut metadata = user_message_metadata_patch(
|
||||
UserMessageType::PromptQueued,
|
||||
if self.enabled(Feature::ItemMetadata) {
|
||||
sandbox_policy.clone()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
);
|
||||
if self.enabled(Feature::ItemMetadata)
|
||||
&& let Some(session_source) = session_source.as_ref()
|
||||
{
|
||||
metadata.merge_from(session_source_metadata_patch(session_source));
|
||||
}
|
||||
Some(metadata)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@@ -5920,11 +5980,16 @@ pub(crate) async fn run_turn(
|
||||
.await;
|
||||
|
||||
let mut initial_input_for_turn: ResponseInputItem = ResponseInputItem::from(input.clone());
|
||||
let initial_message_metadata = Some(user_message_metadata_patch(
|
||||
let mut initial_message_metadata = user_message_metadata_patch(
|
||||
UserMessageType::Prompt,
|
||||
sess.enabled(Feature::ItemMetadata)
|
||||
.then(|| sandbox_policy_to_metadata(turn_context.sandbox_policy.get())),
|
||||
));
|
||||
);
|
||||
if sess.enabled(Feature::ItemMetadata) {
|
||||
initial_message_metadata
|
||||
.merge_from(session_source_metadata_patch(&turn_context.session_source));
|
||||
}
|
||||
let initial_message_metadata = Some(initial_message_metadata);
|
||||
if sess.enabled(Feature::ItemMetadata)
|
||||
&& let Some(metadata_patch) = initial_message_metadata.as_ref()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,9 @@ use crate::tools::format_exec_output_str;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::models::FunctionCallOutputBody;
|
||||
use codex_protocol::models::FunctionCallOutputPayload;
|
||||
use codex_protocol::models::LocalShellAction;
|
||||
use codex_protocol::models::LocalShellExecAction;
|
||||
use codex_protocol::models::LocalShellStatus;
|
||||
use codex_protocol::permissions::FileSystemAccessMode;
|
||||
use codex_protocol::permissions::FileSystemPath;
|
||||
use codex_protocol::permissions::FileSystemSandboxEntry;
|
||||
@@ -61,6 +64,7 @@ use codex_app_server_protocol::AppInfo;
|
||||
use codex_execpolicy::Decision;
|
||||
use codex_execpolicy::NetworkRuleProtocol;
|
||||
use codex_execpolicy::Policy;
|
||||
use codex_git::GhostCommit;
|
||||
use codex_network_proxy::NetworkProxyConfig;
|
||||
use codex_otel::TelemetryAuthMode;
|
||||
use codex_protocol::models::BaseInstructions;
|
||||
@@ -68,6 +72,7 @@ use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::DeveloperInstructions;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::models::WebSearchAction;
|
||||
use codex_protocol::openai_models::ModelsResponse;
|
||||
use codex_protocol::protocol::ConversationAudioParams;
|
||||
use codex_protocol::protocol::RealtimeAudioFrame;
|
||||
@@ -3679,6 +3684,7 @@ async fn build_initial_context_omits_default_image_save_location_with_image_hist
|
||||
status: "completed".to_string(),
|
||||
revised_prompt: Some("a tiny blue square".to_string()),
|
||||
result: "Zm9v".to_string(),
|
||||
metadata: None,
|
||||
}],
|
||||
None,
|
||||
)
|
||||
@@ -3722,6 +3728,7 @@ async fn handle_output_item_done_records_image_save_history_message() {
|
||||
status: "completed".to_string(),
|
||||
revised_prompt: Some("a tiny blue square".to_string()),
|
||||
result: "Zm9v".to_string(),
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let mut ctx = HandleOutputCtx {
|
||||
@@ -3762,6 +3769,7 @@ async fn handle_output_item_done_skips_image_save_message_when_save_fails() {
|
||||
status: "completed".to_string(),
|
||||
revised_prompt: Some("broken payload".to_string()),
|
||||
result: "_-8".to_string(),
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let mut ctx = HandleOutputCtx {
|
||||
@@ -4355,6 +4363,8 @@ async fn task_finish_emits_prompt_queued_metadata_for_injected_user_input_when_f
|
||||
..
|
||||
} if metadata.user_message_type
|
||||
== Some(codex_protocol::models::UserMessageType::PromptQueued)
|
||||
&& metadata.session_source
|
||||
== Some(codex_protocol::models::SessionSourceMetadata::Exec)
|
||||
)
|
||||
));
|
||||
|
||||
@@ -4389,6 +4399,203 @@ async fn task_finish_emits_prompt_queued_metadata_for_injected_user_input_when_f
|
||||
));
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn record_response_item_stamps_session_source_on_all_supported_variants() {
|
||||
let (mut sess, tc, _rx) = make_session_and_context_with_rx().await;
|
||||
Arc::get_mut(&mut sess)
|
||||
.expect("session should be uniquely owned in this test")
|
||||
.features
|
||||
.enable(crate::features::Feature::ItemMetadata)
|
||||
.expect("feature flag should be enabled for this test");
|
||||
|
||||
sess.spawn_task(
|
||||
Arc::clone(&tc),
|
||||
vec![UserInput::Text {
|
||||
text: "start".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
NeverEndingTask {
|
||||
kind: TaskKind::Regular,
|
||||
listen_to_cancellation_token: false,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
let items = vec![
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
role: "assistant".to_string(),
|
||||
content: vec![ContentItem::OutputText {
|
||||
text: "hello".to_string(),
|
||||
}],
|
||||
metadata: None,
|
||||
end_turn: None,
|
||||
phase: None,
|
||||
},
|
||||
ResponseItem::Reasoning {
|
||||
id: "reasoning-1".to_string(),
|
||||
summary: vec![],
|
||||
content: None,
|
||||
encrypted_content: None,
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::LocalShellCall {
|
||||
id: None,
|
||||
call_id: Some("shell-1".to_string()),
|
||||
status: LocalShellStatus::Completed,
|
||||
action: LocalShellAction::Exec(LocalShellExecAction {
|
||||
command: vec!["echo".to_string(), "hello".to_string()],
|
||||
timeout_ms: None,
|
||||
working_directory: None,
|
||||
env: None,
|
||||
user: None,
|
||||
}),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::FunctionCall {
|
||||
id: None,
|
||||
name: "shell".to_string(),
|
||||
namespace: None,
|
||||
arguments: "{}".to_string(),
|
||||
call_id: "call-1".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::ToolSearchCall {
|
||||
id: None,
|
||||
call_id: Some("search-1".to_string()),
|
||||
status: None,
|
||||
execution: "client".to_string(),
|
||||
arguments: serde_json::json!({"query": "calendar"}),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-output-1".to_string(),
|
||||
output: FunctionCallOutputPayload {
|
||||
body: FunctionCallOutputBody::Text("ok".to_string()),
|
||||
success: None,
|
||||
},
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::CustomToolCall {
|
||||
id: None,
|
||||
status: Some("completed".to_string()),
|
||||
call_id: "custom-1".to_string(),
|
||||
name: "custom".to_string(),
|
||||
input: "payload".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::CustomToolCallOutput {
|
||||
call_id: "custom-output-1".to_string(),
|
||||
output: FunctionCallOutputPayload {
|
||||
body: FunctionCallOutputBody::Text("done".to_string()),
|
||||
success: None,
|
||||
},
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::ToolSearchOutput {
|
||||
call_id: Some("search-out-1".to_string()),
|
||||
status: "completed".to_string(),
|
||||
execution: "client".to_string(),
|
||||
tools: vec![],
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::WebSearchCall {
|
||||
id: None,
|
||||
status: Some("completed".to_string()),
|
||||
action: Some(WebSearchAction::Search {
|
||||
query: Some("weather".to_string()),
|
||||
queries: None,
|
||||
}),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::ImageGenerationCall {
|
||||
id: "image-1".to_string(),
|
||||
status: "completed".to_string(),
|
||||
revised_prompt: Some("cat".to_string()),
|
||||
result: "image-result".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::GhostSnapshot {
|
||||
ghost_commit: GhostCommit::new("deadbeef".to_string(), None, Vec::new(), Vec::new()),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::Compaction {
|
||||
encrypted_content: "blob".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
|
||||
for item in items {
|
||||
sess.record_response_item_and_emit_turn_item(tc.as_ref(), item)
|
||||
.await;
|
||||
}
|
||||
|
||||
let expected_session_source = codex_protocol::models::SessionSourceMetadata::Exec;
|
||||
let stamped_count = sess
|
||||
.clone_history()
|
||||
.await
|
||||
.raw_items()
|
||||
.iter()
|
||||
.filter(|item| match item {
|
||||
ResponseItem::Message {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::Reasoning {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::LocalShellCall {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::FunctionCall {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::ToolSearchCall {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::FunctionCallOutput {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::CustomToolCall {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::CustomToolCallOutput {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::ToolSearchOutput {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::WebSearchCall {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::ImageGenerationCall {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::GhostSnapshot {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
}
|
||||
| ResponseItem::Compaction {
|
||||
metadata: Some(metadata),
|
||||
..
|
||||
} => metadata.session_source == Some(expected_session_source.clone()),
|
||||
_ => false,
|
||||
})
|
||||
.count();
|
||||
|
||||
assert_eq!(stamped_count, 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn review_decision_metadata_mapping_is_stable() {
|
||||
assert_eq!(
|
||||
@@ -4454,6 +4661,59 @@ fn sandbox_policy_metadata_mapping_is_stable() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_source_metadata_mapping_is_stable() {
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::Cli),
|
||||
codex_protocol::models::SessionSourceMetadata::Cli
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::VSCode),
|
||||
codex_protocol::models::SessionSourceMetadata::Vscode
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::Exec),
|
||||
codex_protocol::models::SessionSourceMetadata::Exec
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::Mcp),
|
||||
codex_protocol::models::SessionSourceMetadata::Mcp
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::SubAgent(SubAgentSource::Review)),
|
||||
codex_protocol::models::SessionSourceMetadata::SubagentReview
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::SubAgent(SubAgentSource::Compact)),
|
||||
codex_protocol::models::SessionSourceMetadata::SubagentCompact
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::SubAgent(
|
||||
SubAgentSource::MemoryConsolidation
|
||||
)),
|
||||
codex_protocol::models::SessionSourceMetadata::SubagentMemoryConsolidation
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::SubAgent(SubAgentSource::ThreadSpawn {
|
||||
parent_thread_id: ThreadId::default(),
|
||||
depth: 2,
|
||||
agent_nickname: Some("mini".to_string()),
|
||||
agent_role: Some("reviewer".to_string()),
|
||||
})),
|
||||
codex_protocol::models::SessionSourceMetadata::SubagentThreadSpawn
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::SubAgent(SubAgentSource::Other(
|
||||
"custom".to_string()
|
||||
))),
|
||||
codex_protocol::models::SessionSourceMetadata::SubagentOther
|
||||
);
|
||||
assert_eq!(
|
||||
session_source_to_metadata(&SessionSource::Unknown),
|
||||
codex_protocol::models::SessionSourceMetadata::Unknown
|
||||
);
|
||||
}
|
||||
|
||||
async fn setup_tool_call_metadata_runtime_test() -> (
|
||||
Arc<Session>,
|
||||
Arc<TurnContext>,
|
||||
|
||||
@@ -563,6 +563,8 @@ fn insert_initial_context_before_last_real_user_or_summary_keeps_summary_last()
|
||||
fn insert_initial_context_before_last_real_user_or_summary_keeps_compaction_last() {
|
||||
let compacted_history = vec![ResponseItem::Compaction {
|
||||
encrypted_content: "encrypted".to_string(),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let initial_context = vec![ResponseItem::Message {
|
||||
id: None,
|
||||
@@ -590,6 +592,8 @@ fn insert_initial_context_before_last_real_user_or_summary_keeps_compaction_last
|
||||
},
|
||||
ResponseItem::Compaction {
|
||||
encrypted_content: "encrypted".to_string(),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
assert_eq!(refreshed, expected);
|
||||
|
||||
@@ -348,23 +348,27 @@ impl ContextManager {
|
||||
fn process_item(&self, item: &ResponseItem, policy: TruncationPolicy) -> ResponseItem {
|
||||
let policy_with_serialization_budget = policy * 1.2;
|
||||
match item {
|
||||
ResponseItem::FunctionCallOutput { call_id, output } => {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
output: truncate_function_output_payload(
|
||||
output,
|
||||
policy_with_serialization_budget,
|
||||
),
|
||||
}
|
||||
}
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id,
|
||||
output,
|
||||
metadata,
|
||||
..
|
||||
} => ResponseItem::FunctionCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
output: truncate_function_output_payload(output, policy_with_serialization_budget),
|
||||
metadata: metadata.clone(),
|
||||
},
|
||||
ResponseItem::CustomToolCallOutput {
|
||||
call_id,
|
||||
name,
|
||||
output,
|
||||
metadata,
|
||||
..
|
||||
} => ResponseItem::CustomToolCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
name: name.clone(),
|
||||
output: truncate_function_output_payload(output, policy_with_serialization_budget),
|
||||
metadata: metadata.clone(),
|
||||
},
|
||||
ResponseItem::Message { .. }
|
||||
| ResponseItem::Reasoning { .. }
|
||||
@@ -463,6 +467,7 @@ pub(crate) fn estimate_response_item_model_visible_bytes(item: &ResponseItem) ->
|
||||
}
|
||||
| ResponseItem::Compaction {
|
||||
encrypted_content: content,
|
||||
..
|
||||
} => i64::try_from(estimate_reasoning_length(content.len())).unwrap_or(i64::MAX),
|
||||
item => {
|
||||
let raw = serde_json::to_string(item)
|
||||
|
||||
@@ -78,6 +78,8 @@ fn custom_tool_call_output(call_id: &str, output: &str) -> ResponseItem {
|
||||
call_id: call_id.to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text(output.to_string()),
|
||||
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +93,8 @@ fn reasoning_msg(text: &str) -> ResponseItem {
|
||||
text: text.to_string(),
|
||||
}]),
|
||||
encrypted_content: None,
|
||||
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +106,8 @@ fn reasoning_with_encrypted_content(len: usize) -> ResponseItem {
|
||||
}],
|
||||
content: None,
|
||||
encrypted_content: Some("a".repeat(len)),
|
||||
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +155,8 @@ fn filters_non_api_messages() {
|
||||
text: "thinking...".to_string(),
|
||||
}]),
|
||||
encrypted_content: None,
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
@@ -295,6 +303,8 @@ fn for_prompt_strips_images_when_model_does_not_support_images() {
|
||||
detail: None,
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::CustomToolCall {
|
||||
id: None,
|
||||
@@ -316,6 +326,8 @@ fn for_prompt_strips_images_when_model_does_not_support_images() {
|
||||
detail: None,
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let history = create_history_with_items(items);
|
||||
@@ -361,6 +373,8 @@ fn for_prompt_strips_images_when_model_does_not_support_images() {
|
||||
.to_string(),
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::CustomToolCall {
|
||||
id: None,
|
||||
@@ -382,6 +396,8 @@ fn for_prompt_strips_images_when_model_does_not_support_images() {
|
||||
.to_string(),
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
assert_eq!(stripped, expected);
|
||||
@@ -421,6 +437,8 @@ fn for_prompt_preserves_image_generation_calls_when_images_are_supported() {
|
||||
status: "generating".to_string(),
|
||||
revised_prompt: Some("lobster".to_string()),
|
||||
result: "Zm9v".to_string(),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
@@ -442,6 +460,8 @@ fn for_prompt_preserves_image_generation_calls_when_images_are_supported() {
|
||||
status: "generating".to_string(),
|
||||
revised_prompt: Some("lobster".to_string()),
|
||||
result: "Zm9v".to_string(),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
@@ -475,6 +495,8 @@ fn for_prompt_clears_image_generation_result_when_images_are_unsupported() {
|
||||
status: "completed".to_string(),
|
||||
revised_prompt: Some("lobster".to_string()),
|
||||
result: "Zm9v".to_string(),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -496,6 +518,8 @@ fn for_prompt_clears_image_generation_result_when_images_are_unsupported() {
|
||||
status: "completed".to_string(),
|
||||
revised_prompt: Some("lobster".to_string()),
|
||||
result: String::new(),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -505,6 +529,8 @@ fn for_prompt_clears_image_generation_result_when_images_are_unsupported() {
|
||||
fn get_history_for_prompt_drops_ghost_commits() {
|
||||
let items = vec![ResponseItem::GhostSnapshot {
|
||||
ghost_commit: GhostCommit::new("ghost-1".to_string(), None, Vec::new(), Vec::new()),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let history = create_history_with_items(items);
|
||||
let modalities = default_input_modalities();
|
||||
@@ -548,6 +574,8 @@ fn remove_first_item_removes_matching_output_for_function_call() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let mut h = create_history_with_items(items);
|
||||
@@ -561,6 +589,8 @@ fn remove_first_item_removes_matching_call_for_output() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-2".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::FunctionCall {
|
||||
id: None,
|
||||
@@ -591,6 +621,8 @@ fn remove_last_item_removes_matching_call_for_output() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-delete-last".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let mut h = create_history_with_items(items);
|
||||
@@ -614,6 +646,8 @@ fn replace_last_turn_images_replaces_tool_output_images() {
|
||||
]),
|
||||
success: Some(true),
|
||||
},
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let mut history = create_history_with_items(items);
|
||||
@@ -634,6 +668,8 @@ fn replace_last_turn_images_replaces_tool_output_images() {
|
||||
]),
|
||||
success: Some(true),
|
||||
},
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -676,6 +712,8 @@ fn remove_first_item_handles_local_shell_pair() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-3".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let mut h = create_history_with_items(items);
|
||||
@@ -834,6 +872,8 @@ fn remove_first_item_handles_custom_tool_pair() {
|
||||
call_id: "tool-1".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let mut h = create_history_with_items(items);
|
||||
@@ -860,6 +900,8 @@ fn normalization_retains_local_shell_outputs() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "shell-1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("Total output lines: 1\n\nok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -883,6 +925,8 @@ fn record_items_truncates_function_call_output_content() {
|
||||
body: FunctionCallOutputBody::Text(long_output.clone()),
|
||||
success: Some(true),
|
||||
},
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
history.record_items([&item], policy);
|
||||
@@ -915,6 +959,8 @@ fn record_items_truncates_custom_tool_call_output_content() {
|
||||
call_id: "tool-200".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text(long_output.clone()),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
history.record_items([&item], policy);
|
||||
@@ -948,6 +994,8 @@ fn record_items_respects_custom_token_limit() {
|
||||
body: FunctionCallOutputBody::Text(long_output),
|
||||
success: Some(true),
|
||||
},
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
history.record_items([&item], policy);
|
||||
@@ -1087,6 +1135,8 @@ fn normalize_adds_missing_output_for_function_call() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-x".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -1122,6 +1172,8 @@ fn normalize_adds_missing_output_for_custom_tool_call() {
|
||||
call_id: "tool-x".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -1166,6 +1218,8 @@ fn normalize_adds_missing_output_for_local_shell_call_with_id() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "shell-1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -1177,6 +1231,8 @@ fn normalize_removes_orphan_function_call_output() {
|
||||
let items = vec![ResponseItem::FunctionCallOutput {
|
||||
call_id: "orphan-1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let mut h = create_history_with_items(items);
|
||||
|
||||
@@ -1192,6 +1248,8 @@ fn normalize_removes_orphan_custom_tool_call_output() {
|
||||
call_id: "orphan-2".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let mut h = create_history_with_items(items);
|
||||
|
||||
@@ -1217,6 +1275,8 @@ fn normalize_mixed_inserts_and_removals() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "c2".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
// Will get an inserted custom tool output
|
||||
ResponseItem::CustomToolCall {
|
||||
@@ -1260,6 +1320,8 @@ fn normalize_mixed_inserts_and_removals() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "c1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::CustomToolCall {
|
||||
id: None,
|
||||
@@ -1273,6 +1335,8 @@ fn normalize_mixed_inserts_and_removals() {
|
||||
call_id: "t1".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::LocalShellCall {
|
||||
id: None,
|
||||
@@ -1289,6 +1353,8 @@ fn normalize_mixed_inserts_and_removals() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "s1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -1320,6 +1386,8 @@ fn normalize_adds_missing_output_for_function_call_inserts_output() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-x".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -1333,6 +1401,8 @@ fn normalize_adds_missing_output_for_tool_search_call() {
|
||||
status: Some("completed".to_string()),
|
||||
execution: "client".to_string(),
|
||||
arguments: "{}".into(),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let mut h = create_history_with_items(items);
|
||||
|
||||
@@ -1347,12 +1417,16 @@ fn normalize_adds_missing_output_for_tool_search_call() {
|
||||
status: Some("completed".to_string()),
|
||||
execution: "client".to_string(),
|
||||
arguments: "{}".into(),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::ToolSearchOutput {
|
||||
call_id: Some("search-call-x".to_string()),
|
||||
status: "completed".to_string(),
|
||||
execution: "client".to_string(),
|
||||
tools: Vec::new(),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -1402,6 +1476,8 @@ fn normalize_removes_orphan_function_call_output_panics_in_debug() {
|
||||
let items = vec![ResponseItem::FunctionCallOutput {
|
||||
call_id: "orphan-1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let mut h = create_history_with_items(items);
|
||||
h.normalize_history(&default_input_modalities());
|
||||
@@ -1415,6 +1491,8 @@ fn normalize_removes_orphan_custom_tool_call_output_panics_in_debug() {
|
||||
call_id: "orphan-2".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let mut h = create_history_with_items(items);
|
||||
h.normalize_history(&default_input_modalities());
|
||||
@@ -1428,6 +1506,8 @@ fn normalize_removes_orphan_client_tool_search_output() {
|
||||
status: "completed".to_string(),
|
||||
execution: "client".to_string(),
|
||||
tools: Vec::new(),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let mut h = create_history_with_items(items);
|
||||
|
||||
@@ -1445,6 +1525,8 @@ fn normalize_removes_orphan_client_tool_search_output_panics_in_debug() {
|
||||
status: "completed".to_string(),
|
||||
execution: "client".to_string(),
|
||||
tools: Vec::new(),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let mut h = create_history_with_items(items);
|
||||
h.normalize_history(&default_input_modalities());
|
||||
@@ -1457,6 +1539,8 @@ fn normalize_keeps_server_tool_search_output_without_matching_call() {
|
||||
status: "completed".to_string(),
|
||||
execution: "server".to_string(),
|
||||
tools: Vec::new(),
|
||||
|
||||
metadata: None,
|
||||
}];
|
||||
let mut h = create_history_with_items(items);
|
||||
|
||||
@@ -1469,6 +1553,8 @@ fn normalize_keeps_server_tool_search_output_without_matching_call() {
|
||||
status: "completed".to_string(),
|
||||
execution: "server".to_string(),
|
||||
tools: Vec::new(),
|
||||
|
||||
metadata: None,
|
||||
}]
|
||||
);
|
||||
}
|
||||
@@ -1489,6 +1575,8 @@ fn normalize_mixed_inserts_and_removals_panics_in_debug() {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: "c2".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::CustomToolCall {
|
||||
id: None,
|
||||
@@ -1569,6 +1657,8 @@ fn image_data_url_payload_does_not_dominate_function_call_output_estimate() {
|
||||
detail: None,
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let raw_len = serde_json::to_string(&item).unwrap().len() as i64;
|
||||
@@ -1595,6 +1685,8 @@ fn image_data_url_payload_does_not_dominate_custom_tool_call_output_estimate() {
|
||||
detail: None,
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let raw_len = serde_json::to_string(&item).unwrap().len() as i64;
|
||||
@@ -1625,6 +1717,8 @@ fn non_base64_image_urls_are_unchanged() {
|
||||
detail: None,
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
@@ -1668,6 +1762,8 @@ fn non_image_base64_data_url_is_unchanged() {
|
||||
detail: None,
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let raw_len = serde_json::to_string(&item).unwrap().len() as i64;
|
||||
@@ -1752,6 +1848,8 @@ fn original_detail_images_scale_with_dimensions() {
|
||||
detail: Some(ImageDetail::Original),
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let raw_len = serde_json::to_string(&item).unwrap().len() as i64;
|
||||
@@ -1783,6 +1881,8 @@ fn original_detail_webp_images_scale_with_dimensions() {
|
||||
detail: Some(ImageDetail::Original),
|
||||
},
|
||||
]),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let raw_len = serde_json::to_string(&item).unwrap().len() as i64;
|
||||
|
||||
@@ -34,6 +34,7 @@ pub(crate) fn ensure_call_outputs_present(items: &mut Vec<ResponseItem>) {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
));
|
||||
}
|
||||
@@ -59,6 +60,7 @@ pub(crate) fn ensure_call_outputs_present(items: &mut Vec<ResponseItem>) {
|
||||
status: "completed".to_string(),
|
||||
execution: "client".to_string(),
|
||||
tools: Vec::new(),
|
||||
metadata: None,
|
||||
},
|
||||
));
|
||||
}
|
||||
@@ -81,6 +83,7 @@ pub(crate) fn ensure_call_outputs_present(items: &mut Vec<ResponseItem>) {
|
||||
call_id: call_id.clone(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
));
|
||||
}
|
||||
@@ -104,6 +107,7 @@ pub(crate) fn ensure_call_outputs_present(items: &mut Vec<ResponseItem>) {
|
||||
ResponseItem::FunctionCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
output: FunctionCallOutputPayload::from_text("aborted".to_string()),
|
||||
metadata: None,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ pub fn parse_turn_item(item: &ResponseItem) -> Option<TurnItem> {
|
||||
status,
|
||||
revised_prompt,
|
||||
result,
|
||||
..
|
||||
} => Some(TurnItem::ImageGeneration(
|
||||
codex_protocol::items::ImageGenerationItem {
|
||||
id: id.clone(),
|
||||
|
||||
@@ -323,6 +323,8 @@ fn parses_reasoning_summary_and_raw_content() {
|
||||
text: "raw details".to_string(),
|
||||
}]),
|
||||
encrypted_content: None,
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let turn_item = parse_turn_item(&item).expect("expected reasoning turn item");
|
||||
@@ -355,6 +357,8 @@ fn parses_reasoning_including_raw_content() {
|
||||
},
|
||||
]),
|
||||
encrypted_content: None,
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let turn_item = parse_turn_item(&item).expect("expected reasoning turn item");
|
||||
@@ -380,6 +384,8 @@ fn parses_web_search_call() {
|
||||
query: Some("weather".to_string()),
|
||||
queries: None,
|
||||
}),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let turn_item = parse_turn_item(&item).expect("expected web search turn item");
|
||||
@@ -408,6 +414,8 @@ fn parses_web_search_open_page_call() {
|
||||
action: Some(WebSearchAction::OpenPage {
|
||||
url: Some("https://example.com".to_string()),
|
||||
}),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let turn_item = parse_turn_item(&item).expect("expected web search turn item");
|
||||
@@ -436,6 +444,8 @@ fn parses_web_search_find_in_page_call() {
|
||||
url: Some("https://example.com".to_string()),
|
||||
pattern: Some("needle".to_string()),
|
||||
}),
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let turn_item = parse_turn_item(&item).expect("expected web search turn item");
|
||||
@@ -462,6 +472,8 @@ fn parses_partial_web_search_call_without_action_as_other() {
|
||||
id: Some("ws_partial".to_string()),
|
||||
status: Some("in_progress".to_string()),
|
||||
action: None,
|
||||
|
||||
metadata: None,
|
||||
};
|
||||
|
||||
let turn_item = parse_turn_item(&item).expect("expected web search turn item");
|
||||
|
||||
@@ -103,6 +103,7 @@ async fn seed_guardian_parent_history(session: &Arc<Session>, turn: &Arc<TurnCon
|
||||
output: codex_protocol::models::FunctionCallOutputPayload::from_text(
|
||||
"repo visibility: public".to_string(),
|
||||
),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
@@ -219,6 +220,7 @@ fn collect_guardian_transcript_entries_includes_recent_tool_calls_and_output() {
|
||||
output: codex_protocol::models::FunctionCallOutputPayload::from_text(
|
||||
"repo is public".to_string(),
|
||||
),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
|
||||
@@ -47,6 +47,8 @@ fn truncates_rollout_from_start_before_nth_user_only() {
|
||||
}],
|
||||
content: None,
|
||||
encrypted_content: None,
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::FunctionCall {
|
||||
id: None,
|
||||
|
||||
@@ -386,6 +386,7 @@ pub(crate) fn response_input_to_response_item(input: &ResponseInputItem) -> Opti
|
||||
Some(ResponseItem::FunctionCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
output: output.clone(),
|
||||
metadata: None,
|
||||
})
|
||||
}
|
||||
ResponseInputItem::CustomToolCallOutput {
|
||||
@@ -396,12 +397,14 @@ pub(crate) fn response_input_to_response_item(input: &ResponseInputItem) -> Opti
|
||||
call_id: call_id.clone(),
|
||||
name: name.clone(),
|
||||
output: output.clone(),
|
||||
metadata: None,
|
||||
}),
|
||||
ResponseInputItem::McpToolCallOutput { call_id, output } => {
|
||||
let output = output.as_function_call_output_payload();
|
||||
Some(ResponseItem::FunctionCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
output,
|
||||
metadata: None,
|
||||
})
|
||||
}
|
||||
ResponseInputItem::ToolSearchOutput {
|
||||
@@ -414,6 +417,7 @@ pub(crate) fn response_input_to_response_item(input: &ResponseInputItem) -> Opti
|
||||
status: status.clone(),
|
||||
execution: execution.clone(),
|
||||
tools: tools.clone(),
|
||||
metadata: None,
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
||||
@@ -112,6 +112,7 @@ impl SessionTask for GhostSnapshotTask {
|
||||
.session
|
||||
.record_conversation_items(&ctx, &[ResponseItem::GhostSnapshot {
|
||||
ghost_commit: ghost_commit.clone(),
|
||||
metadata: None,
|
||||
}])
|
||||
.await;
|
||||
info!("ghost commit captured: {}", ghost_commit.id());
|
||||
|
||||
@@ -81,7 +81,7 @@ impl SessionTask for UndoTask {
|
||||
.enumerate()
|
||||
.rev()
|
||||
.find_map(|(idx, item)| match item {
|
||||
ResponseItem::GhostSnapshot { ghost_commit } => {
|
||||
ResponseItem::GhostSnapshot { ghost_commit, .. } => {
|
||||
Some((idx, ghost_commit.clone()))
|
||||
}
|
||||
_ => None,
|
||||
|
||||
@@ -54,6 +54,8 @@ fn drops_from_last_user_only() {
|
||||
}],
|
||||
content: None,
|
||||
encrypted_content: None,
|
||||
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::FunctionCall {
|
||||
id: None,
|
||||
|
||||
@@ -126,6 +126,8 @@ fn response_item_records_turn_ttft_ignores_empty_non_output_items() {
|
||||
&ResponseItem::FunctionCallOutput {
|
||||
call_id: "call-1".to_string(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".to_string()),
|
||||
|
||||
metadata: None,
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
@@ -395,6 +395,7 @@ async fn resume_replays_legacy_js_repl_image_rollout_shapes() {
|
||||
call_id: "legacy-js-call".to_string(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text("legacy js_repl stdout".to_string()),
|
||||
metadata: None,
|
||||
}),
|
||||
},
|
||||
RolloutLine {
|
||||
@@ -537,6 +538,7 @@ async fn resume_replays_image_tool_outputs_with_detail() {
|
||||
detail: Some(ImageDetail::Original),
|
||||
},
|
||||
]),
|
||||
metadata: None,
|
||||
}),
|
||||
},
|
||||
RolloutLine {
|
||||
@@ -561,6 +563,7 @@ async fn resume_replays_image_tool_outputs_with_detail() {
|
||||
detail: Some(ImageDetail::Original),
|
||||
},
|
||||
]),
|
||||
metadata: None,
|
||||
}),
|
||||
},
|
||||
];
|
||||
@@ -1857,6 +1860,7 @@ async fn azure_responses_request_includes_store_and_reasoning_ids() {
|
||||
text: "content".into(),
|
||||
}]),
|
||||
encrypted_content: None,
|
||||
metadata: None,
|
||||
});
|
||||
prompt.input.push(ResponseItem::Message {
|
||||
id: Some("message-id".into()),
|
||||
@@ -1875,6 +1879,7 @@ async fn azure_responses_request_includes_store_and_reasoning_ids() {
|
||||
query: Some("weather".into()),
|
||||
queries: None,
|
||||
}),
|
||||
metadata: None,
|
||||
});
|
||||
prompt.input.push(ResponseItem::FunctionCall {
|
||||
id: Some("function-id".into()),
|
||||
@@ -1887,6 +1892,7 @@ async fn azure_responses_request_includes_store_and_reasoning_ids() {
|
||||
prompt.input.push(ResponseItem::FunctionCallOutput {
|
||||
call_id: "function-call-id".into(),
|
||||
output: FunctionCallOutputPayload::from_text("ok".into()),
|
||||
metadata: None,
|
||||
});
|
||||
prompt.input.push(ResponseItem::LocalShellCall {
|
||||
id: Some("local-shell-id".into()),
|
||||
@@ -1913,6 +1919,7 @@ async fn azure_responses_request_includes_store_and_reasoning_ids() {
|
||||
call_id: "custom-tool-call-id".into(),
|
||||
name: None,
|
||||
output: FunctionCallOutputPayload::from_text("ok".into()),
|
||||
metadata: None,
|
||||
});
|
||||
|
||||
let mut stream = client_session
|
||||
|
||||
@@ -1594,6 +1594,7 @@ async fn auto_compact_runs_after_resume_when_token_usage_is_over_limit() {
|
||||
},
|
||||
codex_protocol::models::ResponseItem::Compaction {
|
||||
encrypted_content: "ENCRYPTED_COMPACTION_SUMMARY".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let compact_mock =
|
||||
@@ -2804,6 +2805,7 @@ async fn auto_compact_counts_encrypted_reasoning_before_last_user() {
|
||||
},
|
||||
codex_protocol::models::ResponseItem::Compaction {
|
||||
encrypted_content: "ENCRYPTED_COMPACTION_SUMMARY".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let compact_mock =
|
||||
@@ -2925,6 +2927,7 @@ async fn auto_compact_runs_when_reasoning_header_clears_between_turns() {
|
||||
},
|
||||
codex_protocol::models::ResponseItem::Compaction {
|
||||
encrypted_content: "ENCRYPTED_COMPACTION_SUMMARY".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let compact_mock =
|
||||
|
||||
@@ -79,6 +79,7 @@ fn format_labeled_requests_snapshot(
|
||||
fn compacted_summary_only_output(summary: &str) -> Vec<ResponseItem> {
|
||||
vec![ResponseItem::Compaction {
|
||||
encrypted_content: summary_with_prefix(summary),
|
||||
metadata: None,
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -221,6 +222,7 @@ async fn remote_compact_replaces_history_for_followups() -> Result<()> {
|
||||
|
||||
let compacted_history = vec![ResponseItem::Compaction {
|
||||
encrypted_content: "ENCRYPTED_COMPACTION_SUMMARY".to_string(),
|
||||
metadata: None,
|
||||
}];
|
||||
let compact_mock = responses::mount_compact_json_once(
|
||||
harness.server(),
|
||||
@@ -1117,6 +1119,7 @@ async fn remote_compact_persists_replacement_history_in_rollout() -> Result<()>
|
||||
let compacted_history = vec![
|
||||
ResponseItem::Compaction {
|
||||
encrypted_content: "ENCRYPTED_COMPACTION_SUMMARY".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
@@ -1172,7 +1175,10 @@ async fn remote_compact_persists_replacement_history_in_rollout() -> Result<()>
|
||||
let has_compaction_item = replacement_history.iter().any(|item| {
|
||||
matches!(
|
||||
item,
|
||||
ResponseItem::Compaction { encrypted_content }
|
||||
ResponseItem::Compaction {
|
||||
encrypted_content,
|
||||
..
|
||||
}
|
||||
if encrypted_content == "ENCRYPTED_COMPACTION_SUMMARY"
|
||||
)
|
||||
});
|
||||
@@ -1268,6 +1274,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res
|
||||
},
|
||||
ResponseItem::Compaction {
|
||||
encrypted_content: "ENCRYPTED_COMPACTION_SUMMARY".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let compact_mock = responses::mount_compact_json_once(
|
||||
@@ -1401,6 +1408,7 @@ async fn remote_compact_refreshes_stale_developer_instructions_without_resume()
|
||||
},
|
||||
ResponseItem::Compaction {
|
||||
encrypted_content: "ENCRYPTED_COMPACTION_SUMMARY".to_string(),
|
||||
metadata: None,
|
||||
},
|
||||
];
|
||||
let compact_mock = responses::mount_compact_json_once(
|
||||
@@ -2412,6 +2420,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_summary_only_reinject
|
||||
|
||||
let compacted_history = vec![ResponseItem::Compaction {
|
||||
encrypted_content: summary_with_prefix("REMOTE_SUMMARY_ONLY"),
|
||||
metadata: None,
|
||||
}];
|
||||
let compact_mock = responses::mount_compact_json_once(
|
||||
harness.server(),
|
||||
|
||||
@@ -215,6 +215,13 @@ async fn user_message_type_metadata_is_emitted_when_feature_enabled() -> anyhow:
|
||||
.and_then(Value::as_str),
|
||||
Some("prompt")
|
||||
);
|
||||
assert_eq!(
|
||||
user_message
|
||||
.get("metadata")
|
||||
.and_then(|metadata| metadata.get("session_source"))
|
||||
.and_then(Value::as_str),
|
||||
Some("exec")
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -344,6 +351,13 @@ async fn user_message_type_prompt_steering_metadata_is_emitted_when_feature_enab
|
||||
.and_then(Value::as_str),
|
||||
Some("prompt_steering")
|
||||
);
|
||||
assert_eq!(
|
||||
steered_message
|
||||
.get("metadata")
|
||||
.and_then(|metadata| metadata.get("session_source"))
|
||||
.and_then(Value::as_str),
|
||||
Some("exec")
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -291,6 +291,22 @@ pub enum SandboxPolicyMetadata {
|
||||
FullAccess,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
pub enum SessionSourceMetadata {
|
||||
Cli,
|
||||
Vscode,
|
||||
Exec,
|
||||
Mcp,
|
||||
SubagentReview,
|
||||
SubagentCompact,
|
||||
SubagentMemoryConsolidation,
|
||||
SubagentThreadSpawn,
|
||||
SubagentOther,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
pub struct ResponseItemMetadata {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
@@ -309,6 +325,9 @@ pub struct ResponseItemMetadata {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub review_decision: Option<ReviewDecisionMetadata>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub session_source: Option<SessionSourceMetadata>,
|
||||
}
|
||||
|
||||
impl ResponseItemMetadata {
|
||||
@@ -318,6 +337,7 @@ impl ResponseItemMetadata {
|
||||
&& self.sandbox_policy.is_none()
|
||||
&& self.is_tool_call_escalated.is_none()
|
||||
&& self.review_decision.is_none()
|
||||
&& self.session_source.is_none()
|
||||
}
|
||||
|
||||
pub fn merge_from(&mut self, other: Self) {
|
||||
@@ -336,6 +356,9 @@ impl ResponseItemMetadata {
|
||||
if other.review_decision.is_some() {
|
||||
self.review_decision = other.review_decision;
|
||||
}
|
||||
if other.session_source.is_some() {
|
||||
self.session_source = other.session_source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,6 +465,9 @@ pub enum ResponseItem {
|
||||
#[ts(optional)]
|
||||
content: Option<Vec<ReasoningItemContent>>,
|
||||
encrypted_content: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
LocalShellCall {
|
||||
/// Legacy id field retained for compatibility with older payloads.
|
||||
@@ -484,6 +510,9 @@ pub enum ResponseItem {
|
||||
execution: String,
|
||||
#[ts(type = "unknown")]
|
||||
arguments: serde_json::Value,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
// NOTE: The `output` field for `function_call_output` uses a dedicated payload type with
|
||||
// custom serialization. On the wire it is either:
|
||||
@@ -495,6 +524,9 @@ pub enum ResponseItem {
|
||||
#[ts(as = "FunctionCallOutputBody")]
|
||||
#[schemars(with = "FunctionCallOutputBody")]
|
||||
output: FunctionCallOutputPayload,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
CustomToolCall {
|
||||
#[serde(default, skip_serializing)]
|
||||
@@ -522,6 +554,9 @@ pub enum ResponseItem {
|
||||
#[ts(as = "FunctionCallOutputBody")]
|
||||
#[schemars(with = "FunctionCallOutputBody")]
|
||||
output: FunctionCallOutputPayload,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
ToolSearchOutput {
|
||||
call_id: Option<String>,
|
||||
@@ -529,6 +564,9 @@ pub enum ResponseItem {
|
||||
execution: String,
|
||||
#[ts(type = "unknown[]")]
|
||||
tools: Vec<serde_json::Value>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
// Emitted by the Responses API when the agent triggers a web search.
|
||||
// Example payload (from SSE `response.output_item.done`):
|
||||
@@ -548,6 +586,9 @@ pub enum ResponseItem {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
action: Option<WebSearchAction>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
// Emitted by the Responses API when the agent triggers image generation.
|
||||
// Example payload:
|
||||
@@ -565,14 +606,23 @@ pub enum ResponseItem {
|
||||
#[ts(optional)]
|
||||
revised_prompt: Option<String>,
|
||||
result: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
// Generated by the harness but considered exactly as a model response.
|
||||
GhostSnapshot {
|
||||
ghost_commit: GhostCommit,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
#[serde(alias = "compaction_summary")]
|
||||
Compaction {
|
||||
encrypted_content: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
metadata: Option<ResponseItemMetadata>,
|
||||
},
|
||||
#[serde(other)]
|
||||
Other,
|
||||
@@ -1136,12 +1186,18 @@ impl From<ResponseInputItem> for ResponseItem {
|
||||
end_turn: None,
|
||||
phase: None,
|
||||
},
|
||||
ResponseInputItem::FunctionCallOutput { call_id, output } => {
|
||||
Self::FunctionCallOutput { call_id, output }
|
||||
}
|
||||
ResponseInputItem::FunctionCallOutput { call_id, output } => Self::FunctionCallOutput {
|
||||
call_id,
|
||||
output,
|
||||
metadata: None,
|
||||
},
|
||||
ResponseInputItem::McpToolCallOutput { call_id, output } => {
|
||||
let output = output.into_function_call_output_payload();
|
||||
Self::FunctionCallOutput { call_id, output }
|
||||
Self::FunctionCallOutput {
|
||||
call_id,
|
||||
output,
|
||||
metadata: None,
|
||||
}
|
||||
}
|
||||
ResponseInputItem::CustomToolCallOutput {
|
||||
call_id,
|
||||
@@ -1151,6 +1207,7 @@ impl From<ResponseInputItem> for ResponseItem {
|
||||
call_id,
|
||||
name,
|
||||
output,
|
||||
metadata: None,
|
||||
},
|
||||
ResponseInputItem::ToolSearchOutput {
|
||||
call_id,
|
||||
@@ -1162,6 +1219,7 @@ impl From<ResponseInputItem> for ResponseItem {
|
||||
status,
|
||||
execution,
|
||||
tools,
|
||||
metadata: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1729,6 +1787,7 @@ mod tests {
|
||||
status: "completed".to_string(),
|
||||
revised_prompt: Some("A small blue square".to_string()),
|
||||
result: "Zm9v".to_string(),
|
||||
metadata: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1750,6 +1809,7 @@ mod tests {
|
||||
status: "completed".to_string(),
|
||||
revised_prompt: None,
|
||||
result: "Zm9v".to_string(),
|
||||
metadata: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -2623,6 +2683,7 @@ mod tests {
|
||||
item,
|
||||
ResponseItem::Compaction {
|
||||
encrypted_content: "abc".into(),
|
||||
metadata: None,
|
||||
}
|
||||
);
|
||||
Ok(())
|
||||
@@ -2703,6 +2764,7 @@ mod tests {
|
||||
id: expected_id.clone(),
|
||||
status: expected_status.clone(),
|
||||
action: expected_action.clone(),
|
||||
metadata: None,
|
||||
};
|
||||
assert_eq!(parsed, expected);
|
||||
|
||||
@@ -2793,6 +2855,7 @@ mod tests {
|
||||
"query": "calendar create",
|
||||
"limit": 1,
|
||||
}),
|
||||
metadata: None,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2853,6 +2916,7 @@ mod tests {
|
||||
"additionalProperties": false,
|
||||
}
|
||||
})],
|
||||
metadata: None,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2906,6 +2970,7 @@ mod tests {
|
||||
arguments: serde_json::json!({
|
||||
"paths": ["crm"],
|
||||
}),
|
||||
metadata: None,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2925,6 +2990,7 @@ mod tests {
|
||||
status: "completed".to_string(),
|
||||
execution: "server".to_string(),
|
||||
tools: vec![],
|
||||
metadata: None,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -3135,4 +3201,35 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn response_item_metadata_helpers_include_session_source() {
|
||||
let mut metadata = ResponseItemMetadata::default();
|
||||
assert!(metadata.is_empty());
|
||||
|
||||
metadata.merge_from(ResponseItemMetadata {
|
||||
session_source: Some(SessionSourceMetadata::Exec),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
assert_eq!(metadata.session_source, Some(SessionSourceMetadata::Exec));
|
||||
assert!(!metadata.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_source_metadata_serializes_snake_case() -> Result<()> {
|
||||
assert_eq!(
|
||||
serde_json::to_value(SessionSourceMetadata::Cli)?,
|
||||
serde_json::Value::String("cli".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_value(SessionSourceMetadata::Vscode)?,
|
||||
serde_json::Value::String("vscode".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_value(SessionSourceMetadata::SubagentThreadSpawn)?,
|
||||
serde_json::Value::String("subagent_thread_spawn".to_string())
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user