codex_extension_items/lib.rs
1//! Typed display items owned by Codex extensions.
2//!
3//! This crate intentionally sits below `codex-protocol` so core can carry
4//! extension items without owning each extension's display schema.
5
6use schemars::JsonSchema;
7use serde::Deserialize;
8use serde::Serialize;
9use ts_rs::TS;
10
11pub mod image_generation;
12pub mod sleep;
13pub mod web_search;
14
15/// Canonical extension-owned turn item carried through core lifecycle events.
16///
17/// The item is serialized as a flattened, namespaced envelope:
18///
19/// ```json
20/// {
21/// "kind": "image_gen.generation",
22/// "id": "call-id",
23/// "status": "completed",
24/// "revisedPrompt": "A blue square",
25/// "result": "cG5n",
26/// "savedPath": "/tmp/image.png"
27/// }
28/// ```
29///
30/// `kind` values follow `<extension_namespace>.<item_kind>`. Adding a variant
31/// also requires app-server to add its typed public wrapper.
32#[derive(Debug, Clone, Deserialize, Serialize, TS, JsonSchema, PartialEq)]
33#[serde(tag = "kind")]
34#[ts(tag = "kind")]
35pub enum ExtensionItem {
36 #[serde(rename = "image_gen.generation")]
37 #[ts(rename = "image_gen.generation")]
38 ImageGeneration(image_generation::ImageGenerationItem),
39 #[serde(rename = "clock.sleep")]
40 #[ts(rename = "clock.sleep")]
41 Sleep(sleep::SleepItem),
42 #[serde(rename = "web.search")]
43 #[ts(rename = "web.search")]
44 WebSearch(web_search::WebSearchItem),
45}
46
47impl ExtensionItem {
48 /// Returns the stable item identifier without exposing variant fields to
49 /// core or rollout persistence.
50 pub fn id(&self) -> &str {
51 match self {
52 Self::ImageGeneration(item) => &item.id,
53 Self::Sleep(item) => &item.id,
54 Self::WebSearch(item) => &item.id,
55 }
56 }
57}
58
59#[cfg(test)]
60#[path = "tests.rs"]
61mod tests;