Compare commits

...

2 Commits

Author SHA1 Message Date
Roy Han
ae2d57fefe add thread turn item paging 2026-05-10 21:03:37 -07:00
Roy Han
18d6bc2d2f add image generation content model 2026-05-10 19:19:07 -07:00
29 changed files with 2331 additions and 16 deletions

View File

@@ -1932,6 +1932,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"ItemCompletedNotification": {
"properties": {
"completedAtMs": {
@@ -3823,6 +3919,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -9892,6 +9892,102 @@
],
"type": "string"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"InputModality": {
"description": "Canonical user-input modality tags advertised by a model.",
"oneOf": [
@@ -16150,6 +16246,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/v2/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -6392,6 +6392,102 @@
],
"type": "string"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"InitializeCapabilities": {
"description": "Client-declared capabilities negotiated during initialize.",
"properties": {
@@ -13974,6 +14070,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -285,6 +285,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1035,6 +1131,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -285,6 +285,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1035,6 +1131,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -422,6 +422,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1179,6 +1275,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -756,6 +756,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -2014,6 +2110,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -448,6 +448,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1471,6 +1567,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -448,6 +448,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1471,6 +1567,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -448,6 +448,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1471,6 +1567,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -756,6 +756,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -2014,6 +2110,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -448,6 +448,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1471,6 +1567,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -756,6 +756,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -2014,6 +2110,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -448,6 +448,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1471,6 +1567,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -448,6 +448,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1471,6 +1567,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -422,6 +422,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1179,6 +1275,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -422,6 +422,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1179,6 +1275,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -422,6 +422,102 @@
],
"type": "object"
},
"ImageGenerationContent": {
"oneOf": [
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"dataBase64": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"inline"
],
"title": "InlineImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"dataBase64",
"mimeType",
"type"
],
"title": "InlineImageGenerationContent",
"type": "object"
},
{
"properties": {
"byteLength": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"contentId": {
"type": "string"
},
"height": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"mimeType": {
"type": "string"
},
"type": {
"enum": [
"deferred"
],
"title": "DeferredImageGenerationContentType",
"type": "string"
},
"width": {
"format": "uint32",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"byteLength",
"contentId",
"mimeType",
"type"
],
"title": "DeferredImageGenerationContent",
"type": "object"
}
]
},
"McpToolCallError": {
"properties": {
"message": {
@@ -1179,6 +1275,17 @@
},
{
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/definitions/ImageGenerationContent"
},
{
"type": "null"
}
],
"default": null
},
"id": {
"type": "string"
},

View File

@@ -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 ImageGenerationContent = { "type": "inline", mimeType: string, dataBase64: string, byteLength: bigint, width: number | null, height: number | null, } | { "type": "deferred", contentId: string, mimeType: string, byteLength: bigint, width: number | null, height: number | null, };

View File

@@ -15,6 +15,7 @@ import type { DynamicToolCallOutputContentItem } from "./DynamicToolCallOutputCo
import type { DynamicToolCallStatus } from "./DynamicToolCallStatus";
import type { FileUpdateChange } from "./FileUpdateChange";
import type { HookPromptFragment } from "./HookPromptFragment";
import type { ImageGenerationContent } from "./ImageGenerationContent";
import type { McpToolCallError } from "./McpToolCallError";
import type { McpToolCallResult } from "./McpToolCallResult";
import type { McpToolCallStatus } from "./McpToolCallStatus";
@@ -98,4 +99,4 @@ reasoningEffort: ReasoningEffort | null,
/**
* Last known status of the target agents, when available.
*/
agentsStates: { [key in string]?: CollabAgentState }, } | { "type": "webSearch", id: string, query: string, action: WebSearchAction | null, } | { "type": "imageView", id: string, path: AbsolutePathBuf, } | { "type": "imageGeneration", id: string, status: string, revisedPrompt: string | null, result: string, savedPath?: AbsolutePathBuf, } | { "type": "enteredReviewMode", id: string, review: string, } | { "type": "exitedReviewMode", id: string, review: string, } | { "type": "contextCompaction", id: string, };
agentsStates: { [key in string]?: CollabAgentState }, } | { "type": "webSearch", id: string, query: string, action: WebSearchAction | null, } | { "type": "imageView", id: string, path: AbsolutePathBuf, } | { "type": "imageGeneration", id: string, status: string, revisedPrompt: string | null, content: ImageGenerationContent | null, result: string, savedPath?: AbsolutePathBuf, } | { "type": "enteredReviewMode", id: string, review: string, } | { "type": "exitedReviewMode", id: string, review: string, } | { "type": "contextCompaction", id: string, };

View File

@@ -164,6 +164,7 @@ export type { HookTrustStatus } from "./HookTrustStatus";
export type { HooksListEntry } from "./HooksListEntry";
export type { HooksListParams } from "./HooksListParams";
export type { HooksListResponse } from "./HooksListResponse";
export type { ImageGenerationContent } from "./ImageGenerationContent";
export type { ItemCompletedNotification } from "./ItemCompletedNotification";
export type { ItemGuardianApprovalReviewCompletedNotification } from "./ItemGuardianApprovalReviewCompletedNotification";
export type { ItemGuardianApprovalReviewStartedNotification } from "./ItemGuardianApprovalReviewStartedNotification";

View File

@@ -586,6 +586,7 @@ impl ThreadHistoryBuilder {
id: payload.call_id.clone(),
status: String::new(),
revised_prompt: None,
content: None,
result: String::new(),
saved_path: None,
};
@@ -597,6 +598,7 @@ impl ThreadHistoryBuilder {
id: payload.call_id.clone(),
status: payload.status.clone(),
revised_prompt: payload.revised_prompt.clone(),
content: None,
result: payload.result.clone(),
saved_path: payload.saved_path.clone(),
};
@@ -1469,6 +1471,7 @@ mod tests {
id: "ig_123".into(),
status: "completed".into(),
revised_prompt: Some("final prompt".into()),
content: None,
result: "Zm9v".into(),
saved_path: Some(test_path_buf("/tmp/ig_123.png").abs()),
},

View File

@@ -345,6 +345,8 @@ pub enum ThreadItem {
id: String,
status: String,
revised_prompt: Option<String>,
#[serde(default)]
content: Option<ImageGenerationContent>,
result: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
@@ -361,6 +363,30 @@ pub enum ThreadItem {
ContextCompaction { id: String },
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "camelCase")]
#[ts(tag = "type", export_to = "v2/")]
pub enum ImageGenerationContent {
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
Inline {
mime_type: String,
data_base64: String,
byte_length: u64,
width: Option<u32>,
height: Option<u32>,
},
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
Deferred {
content_id: String,
mime_type: String,
byte_length: u64,
width: Option<u32>,
height: Option<u32>,
},
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase", export_to = "v2/")]
@@ -822,6 +848,7 @@ impl From<CoreTurnItem> for ThreadItem {
id: image.id,
status: image.status,
revised_prompt: image.revised_prompt,
content: None,
result: image.result,
saved_path: image.saved_path,
},

View File

@@ -148,6 +148,147 @@ fn thread_turns_items_list_round_trips() {
);
}
#[test]
fn image_generation_accepts_missing_content_for_legacy_payloads() {
let item: ThreadItem = serde_json::from_value(json!({
"type": "imageGeneration",
"id": "ig_123",
"status": "completed",
"revisedPrompt": null,
"result": "Zm9v",
"savedPath": null
}))
.expect("legacy image generation item should deserialize");
assert_eq!(
item,
ThreadItem::ImageGeneration {
id: "ig_123".to_string(),
status: "completed".to_string(),
revised_prompt: None,
content: None,
result: "Zm9v".to_string(),
saved_path: None,
}
);
}
#[test]
fn image_generation_serializes_missing_content_as_null() {
let item = ThreadItem::ImageGeneration {
id: "ig_123".to_string(),
status: "completed".to_string(),
revised_prompt: None,
content: None,
result: "Zm9v".to_string(),
saved_path: None,
};
assert_eq!(
serde_json::to_value(item).expect("image generation item should serialize"),
json!({
"type": "imageGeneration",
"id": "ig_123",
"status": "completed",
"revisedPrompt": null,
"content": null,
"result": "Zm9v",
})
);
}
#[test]
fn image_generation_inline_content_round_trips() {
let item = ThreadItem::ImageGeneration {
id: "ig_inline".to_string(),
status: "completed".to_string(),
revised_prompt: Some("final prompt".to_string()),
content: Some(ImageGenerationContent::Inline {
mime_type: "image/png".to_string(),
data_base64: "Zm9v".to_string(),
byte_length: 3,
width: Some(512),
height: Some(512),
}),
result: "Zm9v".to_string(),
saved_path: None,
};
let serialized =
serde_json::to_value(&item).expect("inline image generation item should serialize");
assert_eq!(
serialized,
json!({
"type": "imageGeneration",
"id": "ig_inline",
"status": "completed",
"revisedPrompt": "final prompt",
"content": {
"type": "inline",
"mimeType": "image/png",
"dataBase64": "Zm9v",
"byteLength": 3,
"width": 512,
"height": 512,
},
"result": "Zm9v",
})
);
assert_eq!(
serde_json::from_value::<ThreadItem>(serialized)
.expect("inline image generation item should deserialize"),
item
);
}
#[test]
fn image_generation_deferred_content_round_trips() {
let item = ThreadItem::ImageGeneration {
id: "ig_deferred".to_string(),
status: "completed".to_string(),
revised_prompt: None,
content: Some(ImageGenerationContent::Deferred {
content_id: "content_123".to_string(),
mime_type: "image/png".to_string(),
byte_length: 3,
width: None,
height: None,
}),
result: String::new(),
saved_path: None,
};
let serialized =
serde_json::to_value(&item).expect("deferred image generation item should serialize");
assert_eq!(
serialized,
json!({
"type": "imageGeneration",
"id": "ig_deferred",
"status": "completed",
"revisedPrompt": null,
"content": {
"type": "deferred",
"contentId": "content_123",
"mimeType": "image/png",
"byteLength": 3,
"width": null,
"height": null,
},
"result": "",
})
);
assert_eq!(
serde_json::from_value::<ThreadItem>(serialized)
.expect("deferred image generation item should deserialize"),
item
);
}
#[test]
fn thread_list_params_accepts_single_cwd() {
let params = serde_json::from_value::<ThreadListParams>(json!({

View File

@@ -150,7 +150,7 @@ Example with notification opt-out:
- `thread/loaded/list` — list the thread ids currently loaded in memory.
- `thread/read` — read a stored thread by id without resuming it; optionally include turns via `includeTurns`. The returned `thread` includes `status` (`ThreadStatus`), defaulting to `notLoaded` when the thread is not currently loaded.
- `thread/turns/list` — experimental; page through a stored threads turn history without resuming it; supports cursor-based pagination with `sortDirection`, `itemsView`, `nextCursor`, and `backwardsCursor`.
- `thread/turns/items/list` — experimental; reserved for paging full items for one turn. The API shape is present, but app-server currently returns an unsupported-method JSON-RPC error.
- `thread/turns/items/list` — experimental; page through one stored turns items with the same cursor model.
- `thread/metadata/update` — patch stored thread metadata in sqlite; currently supports updating persisted `gitInfo` fields and returns the refreshed `thread`.
- `thread/memoryMode/set` — experimental; set a threads persisted memory eligibility to `"enabled"` or `"disabled"` for either a loaded thread or a stored rollout; returns `{}` on success.
- `memory/reset` — experimental; clear the current `CODEX_HOME/memories` directory and reset persisted memory stage data in sqlite while preserving existing thread memory modes; returns `{}` on success.

View File

@@ -220,6 +220,7 @@ use codex_app_server_protocol::ThreadStartResponse;
use codex_app_server_protocol::ThreadStartedNotification;
use codex_app_server_protocol::ThreadStatus;
use codex_app_server_protocol::ThreadTurnsItemsListParams;
use codex_app_server_protocol::ThreadTurnsItemsListResponse;
use codex_app_server_protocol::ThreadTurnsListParams;
use codex_app_server_protocol::ThreadTurnsListResponse;
use codex_app_server_protocol::ThreadUnarchiveParams;

View File

@@ -1,4 +1,6 @@
use super::*;
use crate::error_code::INTERNAL_ERROR_CODE;
use crate::error_code::INVALID_REQUEST_ERROR_CODE;
use crate::error_code::method_not_found;
const THREAD_LIST_DEFAULT_LIMIT: usize = 25;
@@ -597,11 +599,11 @@ impl ThreadRequestProcessor {
pub(crate) async fn thread_turns_items_list(
&self,
_params: ThreadTurnsItemsListParams,
params: ThreadTurnsItemsListParams,
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
Err(method_not_found(
"thread/turns/items/list is not supported yet",
))
self.thread_turns_items_list_response_inner(params)
.await
.map(|response| Some(response.into()))
}
pub(crate) async fn thread_shell_command(
@@ -2173,6 +2175,62 @@ impl ThreadRequestProcessor {
})
}
async fn thread_turns_items_list_response_inner(
&self,
params: ThreadTurnsItemsListParams,
) -> Result<ThreadTurnsItemsListResponse, JSONRPCErrorError> {
let ThreadTurnsItemsListParams {
thread_id,
turn_id,
cursor,
limit,
sort_direction,
} = params;
let thread_uuid = ThreadId::from_string(&thread_id)
.map_err(|err| invalid_request(format!("invalid thread id: {err}")))?;
let items = self
.load_thread_turns_list_history(thread_uuid)
.await
.map_err(thread_read_view_error)?;
let loaded_thread = self.thread_manager.get_thread(thread_uuid).await.ok();
let has_live_running_thread = match loaded_thread.as_ref() {
Some(thread) => matches!(thread.agent_status().await, AgentStatus::Running),
None => false,
};
let active_turn = if loaded_thread.is_some() {
let thread_state = self.thread_state_manager.thread_state(thread_uuid).await;
let state = thread_state.lock().await;
state.active_turn_snapshot()
} else {
None
};
let turns = reconstruct_thread_turns_for_turns_list(
&items,
self.thread_watch_manager
.loaded_status_for_thread(&thread_uuid.to_string())
.await,
has_live_running_thread,
active_turn,
);
let turn_items = turns
.into_iter()
.find(|turn| turn.id == turn_id)
.ok_or_else(|| invalid_request(format!("turn not found: {turn_id}")))?
.items;
let page = paginate_thread_items(
turn_items,
cursor.as_deref(),
limit,
sort_direction.unwrap_or(SortDirection::Asc),
)?;
Ok(ThreadTurnsItemsListResponse {
data: page.items,
next_cursor: page.next_cursor,
backwards_cursor: page.backwards_cursor,
})
}
async fn load_thread_turns_list_history(
&self,
thread_id: ThreadId,
@@ -3389,6 +3447,8 @@ fn xcode_26_4_mcp_elicitations_auto_deny(
const THREAD_TURNS_DEFAULT_LIMIT: usize = 25;
const THREAD_TURNS_MAX_LIMIT: usize = 100;
const THREAD_ITEMS_DEFAULT_LIMIT: usize = 100;
const THREAD_ITEMS_MAX_LIMIT: usize = 500;
fn thread_backwards_cursor_for_sort_key(
thread: &StoredThread,
@@ -3414,6 +3474,12 @@ struct ThreadTurnsPage {
pub(super) backwards_cursor: Option<String>,
}
struct ThreadItemsPage {
pub(super) items: Vec<ThreadItem>,
pub(super) next_cursor: Option<String>,
pub(super) backwards_cursor: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct ThreadTurnsCursor {
@@ -3421,6 +3487,13 @@ struct ThreadTurnsCursor {
include_anchor: bool,
}
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct ThreadItemsCursor {
item_id: String,
include_anchor: bool,
}
fn paginate_thread_turns(
turns: Vec<Turn>,
cursor: Option<&str>,
@@ -3515,6 +3588,112 @@ fn parse_thread_turns_cursor(cursor: &str) -> Result<ThreadTurnsCursor, JSONRPCE
serde_json::from_str(cursor).map_err(|_| invalid_request(format!("invalid cursor: {cursor}")))
}
fn paginate_thread_items(
items: Vec<ThreadItem>,
cursor: Option<&str>,
limit: Option<u32>,
sort_direction: SortDirection,
) -> Result<ThreadItemsPage, JSONRPCErrorError> {
if items.is_empty() {
return Ok(ThreadItemsPage {
items: Vec::new(),
next_cursor: None,
backwards_cursor: None,
});
}
let anchor = cursor.map(parse_thread_items_cursor).transpose()?;
let page_size = limit
.map(|value| value as usize)
.unwrap_or(THREAD_ITEMS_DEFAULT_LIMIT)
.clamp(1, THREAD_ITEMS_MAX_LIMIT);
let anchor_index = anchor
.as_ref()
.and_then(|anchor| items.iter().position(|item| item.id() == anchor.item_id));
if anchor.is_some() && anchor_index.is_none() {
return Err(JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: "invalid cursor: anchor item is no longer present".to_string(),
data: None,
});
}
let mut keyed_items: Vec<_> = items.into_iter().enumerate().collect();
match sort_direction {
SortDirection::Asc => {
if let (Some(anchor), Some(anchor_index)) = (anchor.as_ref(), anchor_index) {
keyed_items.retain(|(index, _)| {
if anchor.include_anchor {
*index >= anchor_index
} else {
*index > anchor_index
}
});
}
}
SortDirection::Desc => {
keyed_items.reverse();
if let (Some(anchor), Some(anchor_index)) = (anchor.as_ref(), anchor_index) {
keyed_items.retain(|(index, _)| {
if anchor.include_anchor {
*index <= anchor_index
} else {
*index < anchor_index
}
});
}
}
}
let more_items_available = keyed_items.len() > page_size;
keyed_items.truncate(page_size);
let backwards_cursor = keyed_items
.first()
.map(|(_, item)| serialize_thread_items_cursor(item.id(), /*include_anchor*/ true))
.transpose()?;
let next_cursor = if more_items_available {
keyed_items
.last()
.map(|(_, item)| {
serialize_thread_items_cursor(item.id(), /*include_anchor*/ false)
})
.transpose()?
} else {
None
};
let items = keyed_items.into_iter().map(|(_, item)| item).collect();
Ok(ThreadItemsPage {
items,
next_cursor,
backwards_cursor,
})
}
fn serialize_thread_items_cursor(
item_id: &str,
include_anchor: bool,
) -> Result<String, JSONRPCErrorError> {
serde_json::to_string(&ThreadItemsCursor {
item_id: item_id.to_string(),
include_anchor,
})
.map_err(|err| JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to serialize cursor: {err}"),
data: None,
})
}
fn parse_thread_items_cursor(cursor: &str) -> Result<ThreadItemsCursor, JSONRPCErrorError> {
serde_json::from_str(cursor).map_err(|_| JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: format!("invalid cursor: {cursor}"),
data: None,
})
}
fn reconstruct_thread_turns_for_turns_list(
items: &[RolloutItem],
loaded_status: ThreadStatus,

View File

@@ -32,6 +32,7 @@ use codex_app_server_protocol::ThreadStartParams;
use codex_app_server_protocol::ThreadStartResponse;
use codex_app_server_protocol::ThreadStatus;
use codex_app_server_protocol::ThreadTurnsItemsListParams;
use codex_app_server_protocol::ThreadTurnsItemsListResponse;
use codex_app_server_protocol::ThreadTurnsListParams;
use codex_app_server_protocol::ThreadTurnsListResponse;
use codex_app_server_protocol::TurnItemsView;
@@ -1061,34 +1062,57 @@ async fn thread_turns_list_rejects_unmaterialized_loaded_thread() -> Result<()>
}
#[tokio::test]
async fn thread_turns_items_list_returns_unsupported() -> Result<()> {
async fn thread_turns_items_list_returns_turn_items() -> Result<()> {
let server = create_mock_responses_server_repeating_assistant("Done").await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let filename_ts = "2025-01-05T12-00-00";
let conversation_id = create_fake_rollout_with_text_elements(
codex_home.path(),
filename_ts,
"2025-01-05T12:00:00Z",
"first",
vec![],
Some("mock_provider"),
/*git_info*/ None,
)?;
let rollout_path = rollout_path(codex_home.path(), filename_ts, &conversation_id);
append_agent_message(rollout_path.as_path(), "2025-01-05T12:01:00Z", "draft")?;
append_agent_message(rollout_path.as_path(), "2025-01-05T12:02:00Z", "final")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let turn = read_single_turn_items_view(
&mut mcp,
conversation_id.as_str(),
Some(TurnItemsView::Full),
)
.await?;
let read_id = mcp
.send_thread_turns_items_list_request(ThreadTurnsItemsListParams {
thread_id: "thr_123".to_string(),
turn_id: "turn_456".to_string(),
thread_id: conversation_id,
turn_id: turn.id,
cursor: None,
limit: None,
sort_direction: None,
})
.await?;
let read_err: JSONRPCError = timeout(
let read_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_error_message(RequestId::Integer(read_id)),
mcp.read_stream_until_response_message(RequestId::Integer(read_id)),
)
.await??;
let ThreadTurnsItemsListResponse {
data,
next_cursor,
backwards_cursor,
} = to_response::<ThreadTurnsItemsListResponse>(read_resp)?;
assert_eq!(read_err.error.code, -32601);
assert_eq!(
read_err.error.message,
"thread/turns/items/list is not supported yet"
);
assert_eq!(data, turn.items);
assert_eq!(next_cursor, None);
assert!(backwards_cursor.is_some());
Ok(())
}

View File

@@ -706,6 +706,13 @@ pub(super) fn handle_image_generation_end(
id: call_id.into(),
status: "completed".to_string(),
revised_prompt,
content: Some(codex_app_server_protocol::ImageGenerationContent::Inline {
mime_type: "image/png".to_string(),
data_base64: String::new(),
byte_length: 0,
width: None,
height: None,
}),
result: String::new(),
saved_path,
},