image-gen-event/client_processing (#13512)

enabling client-side to process with image-generation capabilities
(setting app-server)
This commit is contained in:
Won Park
2026-03-04 16:54:38 -08:00
committed by GitHub
Unverified
parent 84ba9f8e74
commit 229e6d0347
41 changed files with 1244 additions and 6 deletions
@@ -1387,6 +1387,60 @@
"title": "WebSearchEndEventMsg",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"type": {
"enum": [
"image_generation_begin"
],
"title": "ImageGenerationBeginEventMsgType",
"type": "string"
}
},
"required": [
"call_id",
"type"
],
"title": "ImageGenerationBeginEventMsg",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"result": {
"type": "string"
},
"revised_prompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"image_generation_end"
],
"title": "ImageGenerationEndEventMsgType",
"type": "string"
}
},
"required": [
"call_id",
"result",
"status",
"type"
],
"title": "ImageGenerationEndEventMsg",
"type": "object"
},
{
"description": "Notification that the server is about to execute a command.",
"properties": {
@@ -6001,6 +6055,40 @@
"title": "WebSearchTurnItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revised_prompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"ImageGeneration"
],
"title": "ImageGenerationTurnItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationTurnItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -7092,6 +7180,60 @@
"title": "WebSearchEndEventMsg",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"type": {
"enum": [
"image_generation_begin"
],
"title": "ImageGenerationBeginEventMsgType",
"type": "string"
}
},
"required": [
"call_id",
"type"
],
"title": "ImageGenerationBeginEventMsg",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"result": {
"type": "string"
},
"revised_prompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"image_generation_end"
],
"title": "ImageGenerationEndEventMsgType",
"type": "string"
}
},
"required": [
"call_id",
"result",
"status",
"type"
],
"title": "ImageGenerationEndEventMsg",
"type": "object"
},
{
"description": "Notification that the server is about to execute a command.",
"properties": {
@@ -2251,6 +2251,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -2618,6 +2618,60 @@
"title": "WebSearchEndEventMsg",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"type": {
"enum": [
"image_generation_begin"
],
"title": "ImageGenerationBeginEventMsgType",
"type": "string"
}
},
"required": [
"call_id",
"type"
],
"title": "ImageGenerationBeginEventMsg",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"result": {
"type": "string"
},
"revised_prompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"image_generation_end"
],
"title": "ImageGenerationEndEventMsgType",
"type": "string"
}
},
"required": [
"call_id",
"result",
"status",
"type"
],
"title": "ImageGenerationEndEventMsg",
"type": "object"
},
{
"description": "Notification that the server is about to execute a command.",
"properties": {
@@ -7377,6 +7431,40 @@
"title": "WebSearchTurnItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revised_prompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"ImageGeneration"
],
"title": "ImageGenerationTurnItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationTurnItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -13595,6 +13683,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -4155,6 +4155,60 @@
"title": "WebSearchEndEventMsg",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"type": {
"enum": [
"image_generation_begin"
],
"title": "ImageGenerationBeginEventMsgType",
"type": "string"
}
},
"required": [
"call_id",
"type"
],
"title": "ImageGenerationBeginEventMsg",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"result": {
"type": "string"
},
"revised_prompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"image_generation_end"
],
"title": "ImageGenerationEndEventMsgType",
"type": "string"
}
},
"required": [
"call_id",
"result",
"status",
"type"
],
"title": "ImageGenerationEndEventMsg",
"type": "object"
},
{
"description": "Notification that the server is about to execute a command.",
"properties": {
@@ -12258,6 +12312,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -13745,6 +13833,40 @@
"title": "WebSearchTurnItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revised_prompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"ImageGeneration"
],
"title": "ImageGenerationTurnItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationTurnItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -863,6 +863,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -863,6 +863,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -977,6 +977,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1453,6 +1453,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1215,6 +1215,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1215,6 +1215,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1215,6 +1215,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1453,6 +1453,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1215,6 +1215,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1453,6 +1453,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1215,6 +1215,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -1215,6 +1215,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -977,6 +977,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -977,6 +977,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -977,6 +977,40 @@
"title": "ImageViewThreadItem",
"type": "object"
},
{
"properties": {
"id": {
"type": "string"
},
"result": {
"type": "string"
},
"revisedPrompt": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string"
},
"type": {
"enum": [
"imageGeneration"
],
"title": "ImageGenerationThreadItemType",
"type": "string"
}
},
"required": [
"id",
"result",
"status",
"type"
],
"title": "ImageGenerationThreadItem",
"type": "object"
},
{
"properties": {
"id": {
@@ -33,6 +33,8 @@ import type { ExecCommandEndEvent } from "./ExecCommandEndEvent";
import type { ExecCommandOutputDeltaEvent } from "./ExecCommandOutputDeltaEvent";
import type { ExitedReviewModeEvent } from "./ExitedReviewModeEvent";
import type { GetHistoryEntryResponseEvent } from "./GetHistoryEntryResponseEvent";
import type { ImageGenerationBeginEvent } from "./ImageGenerationBeginEvent";
import type { ImageGenerationEndEvent } from "./ImageGenerationEndEvent";
import type { ItemCompletedEvent } from "./ItemCompletedEvent";
import type { ItemStartedEvent } from "./ItemStartedEvent";
import type { ListCustomPromptsResponseEvent } from "./ListCustomPromptsResponseEvent";
@@ -79,4 +81,4 @@ import type { WebSearchEndEvent } from "./WebSearchEndEvent";
* Response event from the agent
* NOTE: Make sure none of these values have optional types, as it will mess up the extension code-gen.
*/
export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "type": "realtime_conversation_started" } & RealtimeConversationStartedEvent | { "type": "realtime_conversation_realtime" } & RealtimeConversationRealtimeEvent | { "type": "realtime_conversation_closed" } & RealtimeConversationClosedEvent | { "type": "model_reroute" } & ModelRerouteEvent | { "type": "context_compacted" } & ContextCompactedEvent | { "type": "thread_rolled_back" } & ThreadRolledBackEvent | { "type": "task_started" } & TurnStartedEvent | { "type": "task_complete" } & TurnCompleteEvent | { "type": "token_count" } & TokenCountEvent | { "type": "agent_message" } & AgentMessageEvent | { "type": "user_message" } & UserMessageEvent | { "type": "agent_message_delta" } & AgentMessageDeltaEvent | { "type": "agent_reasoning" } & AgentReasoningEvent | { "type": "agent_reasoning_delta" } & AgentReasoningDeltaEvent | { "type": "agent_reasoning_raw_content" } & AgentReasoningRawContentEvent | { "type": "agent_reasoning_raw_content_delta" } & AgentReasoningRawContentDeltaEvent | { "type": "agent_reasoning_section_break" } & AgentReasoningSectionBreakEvent | { "type": "session_configured" } & SessionConfiguredEvent | { "type": "thread_name_updated" } & ThreadNameUpdatedEvent | { "type": "mcp_startup_update" } & McpStartupUpdateEvent | { "type": "mcp_startup_complete" } & McpStartupCompleteEvent | { "type": "mcp_tool_call_begin" } & McpToolCallBeginEvent | { "type": "mcp_tool_call_end" } & McpToolCallEndEvent | { "type": "web_search_begin" } & WebSearchBeginEvent | { "type": "web_search_end" } & WebSearchEndEvent | { "type": "exec_command_begin" } & ExecCommandBeginEvent | { "type": "exec_command_output_delta" } & ExecCommandOutputDeltaEvent | { "type": "terminal_interaction" } & TerminalInteractionEvent | { "type": "exec_command_end" } & ExecCommandEndEvent | { "type": "view_image_tool_call" } & ViewImageToolCallEvent | { "type": "exec_approval_request" } & ExecApprovalRequestEvent | { "type": "request_user_input" } & RequestUserInputEvent | { "type": "dynamic_tool_call_request" } & DynamicToolCallRequest | { "type": "dynamic_tool_call_response" } & DynamicToolCallResponseEvent | { "type": "elicitation_request" } & ElicitationRequestEvent | { "type": "apply_patch_approval_request" } & ApplyPatchApprovalRequestEvent | { "type": "deprecation_notice" } & DeprecationNoticeEvent | { "type": "background_event" } & BackgroundEventEvent | { "type": "undo_started" } & UndoStartedEvent | { "type": "undo_completed" } & UndoCompletedEvent | { "type": "stream_error" } & StreamErrorEvent | { "type": "patch_apply_begin" } & PatchApplyBeginEvent | { "type": "patch_apply_end" } & PatchApplyEndEvent | { "type": "turn_diff" } & TurnDiffEvent | { "type": "get_history_entry_response" } & GetHistoryEntryResponseEvent | { "type": "mcp_list_tools_response" } & McpListToolsResponseEvent | { "type": "list_custom_prompts_response" } & ListCustomPromptsResponseEvent | { "type": "list_skills_response" } & ListSkillsResponseEvent | { "type": "list_remote_skills_response" } & ListRemoteSkillsResponseEvent | { "type": "remote_skill_downloaded" } & RemoteSkillDownloadedEvent | { "type": "skills_update_available" } | { "type": "plan_update" } & UpdatePlanArgs | { "type": "turn_aborted" } & TurnAbortedEvent | { "type": "shutdown_complete" } | { "type": "entered_review_mode" } & ReviewRequest | { "type": "exited_review_mode" } & ExitedReviewModeEvent | { "type": "raw_response_item" } & RawResponseItemEvent | { "type": "item_started" } & ItemStartedEvent | { "type": "item_completed" } & ItemCompletedEvent | { "type": "agent_message_content_delta" } & AgentMessageContentDeltaEvent | { "type": "plan_delta" } & PlanDeltaEvent | { "type": "reasoning_content_delta" } & ReasoningContentDeltaEvent | { "type": "reasoning_raw_content_delta" } & ReasoningRawContentDeltaEvent | { "type": "collab_agent_spawn_begin" } & CollabAgentSpawnBeginEvent | { "type": "collab_agent_spawn_end" } & CollabAgentSpawnEndEvent | { "type": "collab_agent_interaction_begin" } & CollabAgentInteractionBeginEvent | { "type": "collab_agent_interaction_end" } & CollabAgentInteractionEndEvent | { "type": "collab_waiting_begin" } & CollabWaitingBeginEvent | { "type": "collab_waiting_end" } & CollabWaitingEndEvent | { "type": "collab_close_begin" } & CollabCloseBeginEvent | { "type": "collab_close_end" } & CollabCloseEndEvent | { "type": "collab_resume_begin" } & CollabResumeBeginEvent | { "type": "collab_resume_end" } & CollabResumeEndEvent;
export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "type": "realtime_conversation_started" } & RealtimeConversationStartedEvent | { "type": "realtime_conversation_realtime" } & RealtimeConversationRealtimeEvent | { "type": "realtime_conversation_closed" } & RealtimeConversationClosedEvent | { "type": "model_reroute" } & ModelRerouteEvent | { "type": "context_compacted" } & ContextCompactedEvent | { "type": "thread_rolled_back" } & ThreadRolledBackEvent | { "type": "task_started" } & TurnStartedEvent | { "type": "task_complete" } & TurnCompleteEvent | { "type": "token_count" } & TokenCountEvent | { "type": "agent_message" } & AgentMessageEvent | { "type": "user_message" } & UserMessageEvent | { "type": "agent_message_delta" } & AgentMessageDeltaEvent | { "type": "agent_reasoning" } & AgentReasoningEvent | { "type": "agent_reasoning_delta" } & AgentReasoningDeltaEvent | { "type": "agent_reasoning_raw_content" } & AgentReasoningRawContentEvent | { "type": "agent_reasoning_raw_content_delta" } & AgentReasoningRawContentDeltaEvent | { "type": "agent_reasoning_section_break" } & AgentReasoningSectionBreakEvent | { "type": "session_configured" } & SessionConfiguredEvent | { "type": "thread_name_updated" } & ThreadNameUpdatedEvent | { "type": "mcp_startup_update" } & McpStartupUpdateEvent | { "type": "mcp_startup_complete" } & McpStartupCompleteEvent | { "type": "mcp_tool_call_begin" } & McpToolCallBeginEvent | { "type": "mcp_tool_call_end" } & McpToolCallEndEvent | { "type": "web_search_begin" } & WebSearchBeginEvent | { "type": "web_search_end" } & WebSearchEndEvent | { "type": "image_generation_begin" } & ImageGenerationBeginEvent | { "type": "image_generation_end" } & ImageGenerationEndEvent | { "type": "exec_command_begin" } & ExecCommandBeginEvent | { "type": "exec_command_output_delta" } & ExecCommandOutputDeltaEvent | { "type": "terminal_interaction" } & TerminalInteractionEvent | { "type": "exec_command_end" } & ExecCommandEndEvent | { "type": "view_image_tool_call" } & ViewImageToolCallEvent | { "type": "exec_approval_request" } & ExecApprovalRequestEvent | { "type": "request_user_input" } & RequestUserInputEvent | { "type": "dynamic_tool_call_request" } & DynamicToolCallRequest | { "type": "dynamic_tool_call_response" } & DynamicToolCallResponseEvent | { "type": "elicitation_request" } & ElicitationRequestEvent | { "type": "apply_patch_approval_request" } & ApplyPatchApprovalRequestEvent | { "type": "deprecation_notice" } & DeprecationNoticeEvent | { "type": "background_event" } & BackgroundEventEvent | { "type": "undo_started" } & UndoStartedEvent | { "type": "undo_completed" } & UndoCompletedEvent | { "type": "stream_error" } & StreamErrorEvent | { "type": "patch_apply_begin" } & PatchApplyBeginEvent | { "type": "patch_apply_end" } & PatchApplyEndEvent | { "type": "turn_diff" } & TurnDiffEvent | { "type": "get_history_entry_response" } & GetHistoryEntryResponseEvent | { "type": "mcp_list_tools_response" } & McpListToolsResponseEvent | { "type": "list_custom_prompts_response" } & ListCustomPromptsResponseEvent | { "type": "list_skills_response" } & ListSkillsResponseEvent | { "type": "list_remote_skills_response" } & ListRemoteSkillsResponseEvent | { "type": "remote_skill_downloaded" } & RemoteSkillDownloadedEvent | { "type": "skills_update_available" } | { "type": "plan_update" } & UpdatePlanArgs | { "type": "turn_aborted" } & TurnAbortedEvent | { "type": "shutdown_complete" } | { "type": "entered_review_mode" } & ReviewRequest | { "type": "exited_review_mode" } & ExitedReviewModeEvent | { "type": "raw_response_item" } & RawResponseItemEvent | { "type": "item_started" } & ItemStartedEvent | { "type": "item_completed" } & ItemCompletedEvent | { "type": "agent_message_content_delta" } & AgentMessageContentDeltaEvent | { "type": "plan_delta" } & PlanDeltaEvent | { "type": "reasoning_content_delta" } & ReasoningContentDeltaEvent | { "type": "reasoning_raw_content_delta" } & ReasoningRawContentDeltaEvent | { "type": "collab_agent_spawn_begin" } & CollabAgentSpawnBeginEvent | { "type": "collab_agent_spawn_end" } & CollabAgentSpawnEndEvent | { "type": "collab_agent_interaction_begin" } & CollabAgentInteractionBeginEvent | { "type": "collab_agent_interaction_end" } & CollabAgentInteractionEndEvent | { "type": "collab_waiting_begin" } & CollabWaitingBeginEvent | { "type": "collab_waiting_end" } & CollabWaitingEndEvent | { "type": "collab_close_begin" } & CollabCloseBeginEvent | { "type": "collab_close_end" } & CollabCloseEndEvent | { "type": "collab_resume_begin" } & CollabResumeBeginEvent | { "type": "collab_resume_end" } & CollabResumeEndEvent;
@@ -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 ImageGenerationBeginEvent = { call_id: string, };
@@ -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 ImageGenerationEndEvent = { call_id: string, status: string, revised_prompt?: string, result: string, };
@@ -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 ImageGenerationItem = { id: string, status: string, revised_prompt?: string, result: string, };
@@ -3,9 +3,10 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AgentMessageItem } from "./AgentMessageItem";
import type { ContextCompactionItem } from "./ContextCompactionItem";
import type { ImageGenerationItem } from "./ImageGenerationItem";
import type { PlanItem } from "./PlanItem";
import type { ReasoningItem } from "./ReasoningItem";
import type { UserMessageItem } from "./UserMessageItem";
import type { WebSearchItem } from "./WebSearchItem";
export type TurnItem = { "type": "UserMessage" } & UserMessageItem | { "type": "AgentMessage" } & AgentMessageItem | { "type": "Plan" } & PlanItem | { "type": "Reasoning" } & ReasoningItem | { "type": "WebSearch" } & WebSearchItem | { "type": "ContextCompaction" } & ContextCompactionItem;
export type TurnItem = { "type": "UserMessage" } & UserMessageItem | { "type": "AgentMessage" } & AgentMessageItem | { "type": "Plan" } & PlanItem | { "type": "Reasoning" } & ReasoningItem | { "type": "WebSearch" } & WebSearchItem | { "type": "ImageGeneration" } & ImageGenerationItem | { "type": "ContextCompaction" } & ContextCompactionItem;
@@ -84,6 +84,9 @@ export type { GitDiffToRemoteResponse } from "./GitDiffToRemoteResponse";
export type { GitSha } from "./GitSha";
export type { HistoryEntry } from "./HistoryEntry";
export type { ImageDetail } from "./ImageDetail";
export type { ImageGenerationBeginEvent } from "./ImageGenerationBeginEvent";
export type { ImageGenerationEndEvent } from "./ImageGenerationEndEvent";
export type { ImageGenerationItem } from "./ImageGenerationItem";
export type { InitializeCapabilities } from "./InitializeCapabilities";
export type { InitializeParams } from "./InitializeParams";
export type { InitializeResponse } from "./InitializeResponse";
@@ -85,4 +85,4 @@ prompt: string | 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: string, } | { "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: string, } | { "type": "imageGeneration", id: string, status: string, revisedPrompt: string | null, result: string, } | { "type": "enteredReviewMode", id: string, review: string, } | { "type": "exitedReviewMode", id: string, review: string, } | { "type": "contextCompaction", id: string, };
@@ -30,6 +30,8 @@ use codex_protocol::protocol::ErrorEvent;
use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::ExecCommandBeginEvent;
use codex_protocol::protocol::ExecCommandEndEvent;
use codex_protocol::protocol::ImageGenerationBeginEvent;
use codex_protocol::protocol::ImageGenerationEndEvent;
use codex_protocol::protocol::ItemCompletedEvent;
use codex_protocol::protocol::ItemStartedEvent;
use codex_protocol::protocol::McpToolCallBeginEvent;
@@ -141,6 +143,8 @@ impl ThreadHistoryBuilder {
EventMsg::McpToolCallBegin(payload) => self.handle_mcp_tool_call_begin(payload),
EventMsg::McpToolCallEnd(payload) => self.handle_mcp_tool_call_end(payload),
EventMsg::ViewImageToolCall(payload) => self.handle_view_image_tool_call(payload),
EventMsg::ImageGenerationBegin(payload) => self.handle_image_generation_begin(payload),
EventMsg::ImageGenerationEnd(payload) => self.handle_image_generation_end(payload),
EventMsg::CollabAgentSpawnBegin(payload) => {
self.handle_collab_agent_spawn_begin(payload)
}
@@ -269,6 +273,7 @@ impl ThreadHistoryBuilder {
| codex_protocol::items::TurnItem::AgentMessage(_)
| codex_protocol::items::TurnItem::Reasoning(_)
| codex_protocol::items::TurnItem::WebSearch(_)
| codex_protocol::items::TurnItem::ImageGeneration(_)
| codex_protocol::items::TurnItem::ContextCompaction(_) => {}
}
}
@@ -288,6 +293,7 @@ impl ThreadHistoryBuilder {
| codex_protocol::items::TurnItem::AgentMessage(_)
| codex_protocol::items::TurnItem::Reasoning(_)
| codex_protocol::items::TurnItem::WebSearch(_)
| codex_protocol::items::TurnItem::ImageGeneration(_)
| codex_protocol::items::TurnItem::ContextCompaction(_) => {}
}
}
@@ -516,6 +522,26 @@ impl ThreadHistoryBuilder {
self.upsert_item_in_current_turn(item);
}
fn handle_image_generation_begin(&mut self, payload: &ImageGenerationBeginEvent) {
let item = ThreadItem::ImageGeneration {
id: payload.call_id.clone(),
status: String::new(),
revised_prompt: None,
result: String::new(),
};
self.upsert_item_in_current_turn(item);
}
fn handle_image_generation_end(&mut self, payload: &ImageGenerationEndEvent) {
let item = ThreadItem::ImageGeneration {
id: payload.call_id.clone(),
status: payload.status.clone(),
revised_prompt: payload.revised_prompt.clone(),
result: payload.result.clone(),
};
self.upsert_item_in_current_turn(item);
}
fn handle_collab_agent_spawn_begin(
&mut self,
payload: &codex_protocol::protocol::CollabAgentSpawnBeginEvent,
@@ -3347,6 +3347,14 @@ pub enum ThreadItem {
ImageView { id: String, path: String },
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
ImageGeneration {
id: String,
status: String,
revised_prompt: Option<String>,
result: String,
},
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
EnteredReviewMode { id: String, review: String },
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
@@ -3370,6 +3378,7 @@ impl ThreadItem {
| ThreadItem::CollabAgentToolCall { id, .. }
| ThreadItem::WebSearch { id, .. }
| ThreadItem::ImageView { id, .. }
| ThreadItem::ImageGeneration { id, .. }
| ThreadItem::EnteredReviewMode { id, .. }
| ThreadItem::ExitedReviewMode { id, .. }
| ThreadItem::ContextCompaction { id, .. } => id,
@@ -3449,6 +3458,12 @@ impl From<CoreTurnItem> for ThreadItem {
query: search.query,
action: Some(WebSearchAction::from(search.action)),
},
CoreTurnItem::ImageGeneration(image) => ThreadItem::ImageGeneration {
id: image.id,
status: image.status,
revised_prompt: image.revised_prompt,
result: image.result,
},
CoreTurnItem::ContextCompaction(compaction) => {
ThreadItem::ContextCompaction { id: compaction.id }
}
+2
View File
@@ -5935,6 +5935,8 @@ fn realtime_text_for_event(msg: &EventMsg) -> Option<String> {
| EventMsg::PatchApplyBegin(_)
| EventMsg::PatchApplyEnd(_)
| EventMsg::ViewImageToolCall(_)
| EventMsg::ImageGenerationBegin(_)
| EventMsg::ImageGenerationEnd(_)
| EventMsg::ExecApprovalRequest(_)
| EventMsg::RequestUserInput(_)
| EventMsg::DynamicToolCallRequest(_)
+13
View File
@@ -142,6 +142,19 @@ pub fn parse_turn_item(item: &ResponseItem) -> Option<TurnItem> {
action,
}))
}
ResponseItem::ImageGenerationCall {
id,
status,
revised_prompt,
result,
} => Some(TurnItem::ImageGeneration(
codex_protocol::items::ImageGenerationItem {
id: id.clone(),
status: status.clone(),
revised_prompt: revised_prompt.clone(),
result: result.clone(),
},
)),
_ => None,
}
}
+3 -1
View File
@@ -118,6 +118,7 @@ fn event_msg_persistence_mode(ev: &EventMsg) -> Option<EventPersistenceMode> {
| EventMsg::PatchApplyEnd(_)
| EventMsg::McpToolCallEnd(_)
| EventMsg::ViewImageToolCall(_)
| EventMsg::ImageGenerationEnd(_)
| EventMsg::CollabAgentSpawnEnd(_)
| EventMsg::CollabAgentInteractionEnd(_)
| EventMsg::CollabWaitingEnd(_)
@@ -172,6 +173,7 @@ fn event_msg_persistence_mode(ev: &EventMsg) -> Option<EventPersistenceMode> {
| EventMsg::CollabAgentInteractionBegin(_)
| EventMsg::CollabWaitingBegin(_)
| EventMsg::CollabCloseBegin(_)
| EventMsg::CollabResumeBegin(_) => None,
| EventMsg::CollabResumeBegin(_)
| EventMsg::ImageGenerationBegin(_) => None,
}
}
+9 -2
View File
@@ -159,8 +159,14 @@ pub(crate) async fn handle_output_item_done(
Ok(None) => {
if let Some(turn_item) = handle_non_tool_response_item(&item, plan_mode) {
if previously_active_item.is_none() {
let mut started_item = turn_item.clone();
if let TurnItem::ImageGeneration(item) = &mut started_item {
item.status = "in_progress".to_string();
item.revised_prompt = None;
item.result.clear();
}
ctx.sess
.emit_turn_item_started(&ctx.turn_context, &turn_item)
.emit_turn_item_started(&ctx.turn_context, &started_item)
.await;
}
@@ -243,7 +249,8 @@ pub(crate) fn handle_non_tool_response_item(
match item {
ResponseItem::Message { .. }
| ResponseItem::Reasoning { .. }
| ResponseItem::WebSearchCall { .. } => {
| ResponseItem::WebSearchCall { .. }
| ResponseItem::ImageGenerationCall { .. } => {
let mut turn_item = parse_turn_item(item)?;
if let TurnItem::AgentMessage(agent_message) = &mut turn_item {
let combined = agent_message
+46
View File
@@ -16,6 +16,7 @@ use codex_protocol::user_input::TextElement;
use codex_protocol::user_input::UserInput;
use core_test_support::responses::ev_assistant_message;
use core_test_support::responses::ev_completed;
use core_test_support::responses::ev_image_generation_call;
use core_test_support::responses::ev_message_item_added;
use core_test_support::responses::ev_output_text_delta;
use core_test_support::responses::ev_reasoning_item;
@@ -262,6 +263,51 @@ async fn web_search_item_is_emitted() -> anyhow::Result<()> {
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn image_generation_call_event_is_emitted() -> anyhow::Result<()> {
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let TestCodex { codex, .. } = test_codex().build(&server).await?;
let first_response = sse(vec![
ev_response_created("resp-1"),
ev_image_generation_call("ig_123", "completed", "A tiny blue square", "Zm9v"),
ev_completed("resp-1"),
]);
mount_sse_once(&server, first_response).await;
codex
.submit(Op::UserInput {
items: vec![UserInput::Text {
text: "generate a tiny blue square".into(),
text_elements: Vec::new(),
}],
final_output_json_schema: None,
})
.await?;
let begin = wait_for_event_match(&codex, |ev| match ev {
EventMsg::ImageGenerationBegin(event) => Some(event.clone()),
_ => None,
})
.await;
let end = wait_for_event_match(&codex, |ev| match ev {
EventMsg::ImageGenerationEnd(event) => Some(event.clone()),
_ => None,
})
.await;
assert_eq!(begin.call_id, "ig_123");
assert_eq!(end.call_id, "ig_123");
assert_eq!(end.status, "completed");
assert_eq!(end.revised_prompt, Some("A tiny blue square".to_string()));
assert_eq!(end.result, "Zm9v");
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn agent_message_content_delta_has_item_metadata() -> anyhow::Result<()> {
skip_if_no_network!(Ok(()));
@@ -448,6 +448,22 @@ impl EventProcessor for EventProcessorWithHumanOutput {
ts_msg!(self, "🌐 Searched: {detail}");
}
}
EventMsg::ImageGenerationBegin(generated) => {
ts_msg!(
self,
"{} {}",
"image generation started".style(self.magenta),
generated.call_id
);
}
EventMsg::ImageGenerationEnd(generated) => {
ts_msg!(
self,
"{} {}",
"generated image".style(self.magenta),
generated.call_id
);
}
EventMsg::PatchApplyBegin(PatchApplyBeginEvent {
call_id,
auto_approved,
@@ -352,6 +352,8 @@ async fn run_codex_tool_session_inner(
| EventMsg::UserMessage(_)
| EventMsg::ShutdownComplete
| EventMsg::ViewImageToolCall(_)
| EventMsg::ImageGenerationBegin(_)
| EventMsg::ImageGenerationEnd(_)
| EventMsg::RawResponseItem(_)
| EventMsg::EnteredReviewMode(_)
| EventMsg::ItemStarted(_)
+25
View File
@@ -5,6 +5,7 @@ use crate::protocol::AgentReasoningEvent;
use crate::protocol::AgentReasoningRawContentEvent;
use crate::protocol::ContextCompactedEvent;
use crate::protocol::EventMsg;
use crate::protocol::ImageGenerationEndEvent;
use crate::protocol::UserMessageEvent;
use crate::protocol::WebSearchEndEvent;
use crate::user_input::ByteRange;
@@ -24,6 +25,7 @@ pub enum TurnItem {
Plan(PlanItem),
Reasoning(ReasoningItem),
WebSearch(WebSearchItem),
ImageGeneration(ImageGenerationItem),
ContextCompaction(ContextCompactionItem),
}
@@ -79,6 +81,16 @@ pub struct WebSearchItem {
pub action: WebSearchAction,
}
#[derive(Debug, Clone, Deserialize, Serialize, TS, JsonSchema, PartialEq)]
pub struct ImageGenerationItem {
pub id: String,
pub status: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub revised_prompt: Option<String>,
pub result: String,
}
#[derive(Debug, Clone, Deserialize, Serialize, TS, JsonSchema)]
pub struct ContextCompactionItem {
pub id: String,
@@ -235,6 +247,17 @@ impl WebSearchItem {
}
}
impl ImageGenerationItem {
pub fn as_legacy_event(&self) -> EventMsg {
EventMsg::ImageGenerationEnd(ImageGenerationEndEvent {
call_id: self.id.clone(),
status: self.status.clone(),
revised_prompt: self.revised_prompt.clone(),
result: self.result.clone(),
})
}
}
impl TurnItem {
pub fn id(&self) -> String {
match self {
@@ -243,6 +266,7 @@ impl TurnItem {
TurnItem::Plan(item) => item.id.clone(),
TurnItem::Reasoning(item) => item.id.clone(),
TurnItem::WebSearch(item) => item.id.clone(),
TurnItem::ImageGeneration(item) => item.id.clone(),
TurnItem::ContextCompaction(item) => item.id.clone(),
}
}
@@ -253,6 +277,7 @@ impl TurnItem {
TurnItem::AgentMessage(item) => item.as_legacy_events(),
TurnItem::Plan(_) => Vec::new(),
TurnItem::WebSearch(item) => vec![item.as_legacy_event()],
TurnItem::ImageGeneration(item) => vec![item.as_legacy_event()],
TurnItem::Reasoning(item) => item.as_legacy_events(show_raw_agent_reasoning),
TurnItem::ContextCompaction(item) => vec![item.as_legacy_event()],
}
+72
View File
@@ -1086,6 +1086,10 @@ pub enum EventMsg {
WebSearchEnd(WebSearchEndEvent),
ImageGenerationBegin(ImageGenerationBeginEvent),
ImageGenerationEnd(ImageGenerationEndEvent),
/// Notification that the server is about to execute a command.
ExecCommandBegin(ExecCommandBeginEvent),
@@ -1367,6 +1371,11 @@ impl HasLegacyEvent for ItemStartedEvent {
TurnItem::WebSearch(item) => vec![EventMsg::WebSearchBegin(WebSearchBeginEvent {
call_id: item.id.clone(),
})],
TurnItem::ImageGeneration(item) => {
vec![EventMsg::ImageGenerationBegin(ImageGenerationBeginEvent {
call_id: item.id.clone(),
})]
}
_ => Vec::new(),
}
}
@@ -1876,6 +1885,21 @@ pub struct WebSearchEndEvent {
pub action: WebSearchAction,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
pub struct ImageGenerationBeginEvent {
pub call_id: String,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
pub struct ImageGenerationEndEvent {
pub call_id: String,
pub status: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub revised_prompt: Option<String>,
pub result: String,
}
// Conversation kept for backward compatibility.
/// Response payload for `Op::GetHistory` containing the current session's
/// in-memory transcript.
@@ -3115,6 +3139,7 @@ pub struct CollabResumeEndEvent {
#[cfg(test)]
mod tests {
use super::*;
use crate::items::ImageGenerationItem;
use crate::items::UserMessageItem;
use crate::items::WebSearchItem;
use anyhow::Result;
@@ -3235,6 +3260,53 @@ mod tests {
assert!(event.as_legacy_events(false).is_empty());
}
#[test]
fn item_started_event_from_image_generation_emits_begin_event() {
let event = ItemStartedEvent {
thread_id: ThreadId::new(),
turn_id: "turn-1".into(),
item: TurnItem::ImageGeneration(ImageGenerationItem {
id: "ig-1".into(),
status: "in_progress".into(),
revised_prompt: None,
result: String::new(),
}),
};
let legacy_events = event.as_legacy_events(false);
assert_eq!(legacy_events.len(), 1);
match &legacy_events[0] {
EventMsg::ImageGenerationBegin(event) => assert_eq!(event.call_id, "ig-1"),
_ => panic!("expected ImageGenerationBegin event"),
}
}
#[test]
fn item_completed_event_from_image_generation_emits_end_event() {
let event = ItemCompletedEvent {
thread_id: ThreadId::new(),
turn_id: "turn-1".into(),
item: TurnItem::ImageGeneration(ImageGenerationItem {
id: "ig-1".into(),
status: "completed".into(),
revised_prompt: Some("A tiny blue square".into()),
result: "Zm9v".into(),
}),
};
let legacy_events = event.as_legacy_events(false);
assert_eq!(legacy_events.len(), 1);
match &legacy_events[0] {
EventMsg::ImageGenerationEnd(event) => {
assert_eq!(event.call_id, "ig-1");
assert_eq!(event.status, "completed");
assert_eq!(event.revised_prompt.as_deref(), Some("A tiny blue square"));
assert_eq!(event.result, "Zm9v");
}
_ => panic!("expected ImageGenerationEnd event"),
}
}
#[test]
fn rollback_failed_error_does_not_affect_turn_status() {
let event = ErrorEvent {
+18
View File
@@ -111,6 +111,8 @@ use codex_protocol::protocol::ExecCommandEndEvent;
use codex_protocol::protocol::ExecCommandOutputDeltaEvent;
use codex_protocol::protocol::ExecCommandSource;
use codex_protocol::protocol::ExitedReviewModeEvent;
use codex_protocol::protocol::ImageGenerationBeginEvent;
use codex_protocol::protocol::ImageGenerationEndEvent;
use codex_protocol::protocol::ListCustomPromptsResponseEvent;
use codex_protocol::protocol::ListSkillsResponseEvent;
use codex_protocol::protocol::McpListToolsResponseEvent;
@@ -2282,6 +2284,20 @@ impl ChatWidget {
self.request_redraw();
}
fn on_image_generation_begin(&mut self, _event: ImageGenerationBeginEvent) {
self.flush_answer_stream_with_separator();
}
fn on_image_generation_end(&mut self, event: ImageGenerationEndEvent) {
self.flush_answer_stream_with_separator();
self.add_to_history(history_cell::new_image_generation_call(
event.call_id,
event.status,
event.revised_prompt,
));
self.request_redraw();
}
fn on_patch_apply_end(&mut self, event: codex_protocol::protocol::PatchApplyEndEvent) {
let ev2 = event.clone();
self.defer_or_handle(
@@ -4738,6 +4754,8 @@ impl ChatWidget {
EventMsg::PatchApplyEnd(ev) => self.on_patch_apply_end(ev),
EventMsg::ExecCommandEnd(ev) => self.on_exec_command_end(ev),
EventMsg::ViewImageToolCall(ev) => self.on_view_image_tool_call(ev),
EventMsg::ImageGenerationBegin(ev) => self.on_image_generation_begin(ev),
EventMsg::ImageGenerationEnd(ev) => self.on_image_generation_end(ev),
EventMsg::McpToolCallBegin(ev) => self.on_mcp_tool_call_begin(ev),
EventMsg::McpToolCallEnd(ev) => self.on_mcp_tool_call_end(ev),
EventMsg::WebSearchBegin(ev) => self.on_web_search_begin(ev),
@@ -0,0 +1,7 @@
---
source: tui/src/chatwidget/tests.rs
assertion_line: 5889
expression: combined
---
• Generated Image
└ completed: A tiny blue square
+21
View File
@@ -72,6 +72,7 @@ use codex_protocol::protocol::ExecCommandStatus as CoreExecCommandStatus;
use codex_protocol::protocol::ExecPolicyAmendment;
use codex_protocol::protocol::ExitedReviewModeEvent;
use codex_protocol::protocol::FileChange;
use codex_protocol::protocol::ImageGenerationEndEvent;
use codex_protocol::protocol::ItemCompletedEvent;
use codex_protocol::protocol::McpStartupCompleteEvent;
use codex_protocol::protocol::McpStartupStatus;
@@ -6041,6 +6042,26 @@ async fn view_image_tool_call_adds_history_cell() {
assert_snapshot!("local_image_attachment_history_snapshot", combined);
}
#[tokio::test]
async fn image_generation_call_adds_history_cell() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;
chat.handle_codex_event(Event {
id: "sub-image-generation".into(),
msg: EventMsg::ImageGenerationEnd(ImageGenerationEndEvent {
call_id: "call-image-generation".into(),
status: "completed".into(),
revised_prompt: Some("A tiny blue square".into()),
result: "Zm9v".into(),
}),
});
let cells = drain_insert_history(&mut rx);
assert_eq!(cells.len(), 1, "expected a single history cell");
let combined = lines_to_single_string(&cells[0]);
assert_snapshot!("image_generation_call_history_snapshot", combined);
}
// Snapshot test: interrupting a running exec finalizes the active cell with a red ✗
// marker (replacing the spinner) and flushes it into history.
#[tokio::test]
+15
View File
@@ -2196,6 +2196,21 @@ pub(crate) fn new_view_image_tool_call(path: PathBuf, cwd: &Path) -> PlainHistor
PlainHistoryCell { lines }
}
pub(crate) fn new_image_generation_call(
call_id: String,
status: String,
revised_prompt: Option<String>,
) -> PlainHistoryCell {
let detail = revised_prompt.unwrap_or_else(|| call_id.clone());
let lines: Vec<Line<'static>> = vec![
vec!["".dim(), "Generated Image".bold()].into(),
vec!["".dim(), format!("{status}: {detail}").dim()].into(),
];
PlainHistoryCell { lines }
}
pub(crate) fn new_reasoning_summary_block(full_reasoning_buffer: String) -> Box<dyn HistoryCell> {
let full_reasoning_buffer = full_reasoning_buffer.trim();
if let Some(open) = full_reasoning_buffer.find("**") {