Skip to main content

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;