prompty 2.0.0-beta.1

Prompty is an asset class and format for LLM prompts
Documentation
// Code generated by Prompty emitter; DO NOT EDIT.

#![allow(
    unused_imports,
    dead_code,
    non_camel_case_types,
    unused_variables,
    clippy::all
)]

use super::super::context::{LoadContext, SaveContext};

use super::super::conversation::tool_call::ToolCall;

/// Variant-specific data for [`StreamChunk`], discriminated by `kind`.
#[derive(Debug, Clone)]
pub enum StreamChunkKind {
    /// `kind` = `"text"`
    TextChunk {
        /// The text content of the chunk
        value: String,
    },
    /// `kind` = `"thinking"`
    ThinkingChunk {
        /// The thinking content of the chunk
        value: String,
    },
    /// `kind` = `"tool"`
    ToolChunk {
        /// The tool call data
        tool_call: ToolCall,
    },
    /// `kind` = `"error"`
    ErrorChunk {
        /// The error message
        message: String,
    },
}

impl Default for StreamChunkKind {
    fn default() -> Self {
        StreamChunkKind::TextChunk {
            value: String::from(""),
        }
    }
}
/// A chunk of data from a streaming LLM response. Stream chunks are discriminated on the `kind` field.
#[derive(Debug, Clone, Default)]
pub struct StreamChunk {
    /// Variant-specific data, discriminated by `kind`.
    pub kind: StreamChunkKind,
}

impl StreamChunk {
    /// Create a new StreamChunk with default values.
    pub fn new() -> Self {
        Self::default()
    }

    /// Load StreamChunk from a JSON string.
    pub fn from_json(json: &str, ctx: &LoadContext) -> Result<Self, serde_json::Error> {
        let value: serde_json::Value = serde_json::from_str(json)?;
        Ok(Self::load_from_value(&value, ctx))
    }

    /// Load StreamChunk from a YAML string.
    pub fn from_yaml(yaml: &str, ctx: &LoadContext) -> Result<Self, serde_yaml::Error> {
        let value: serde_json::Value = serde_yaml::from_str(yaml)?;
        Ok(Self::load_from_value(&value, ctx))
    }

    /// Load StreamChunk from a `serde_json::Value`.
    ///
    /// Calls `ctx.process_input` before field extraction.
    pub fn load_from_value(value: &serde_json::Value, ctx: &LoadContext) -> Self {
        let value = ctx.process_input(value.clone());
        let kind_str = value.get("kind").and_then(|v| v.as_str()).unwrap_or("");
        let kind = match kind_str {
            "text" => StreamChunkKind::TextChunk {
                value: value
                    .get("value")
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string(),
            },
            "thinking" => StreamChunkKind::ThinkingChunk {
                value: value
                    .get("value")
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string(),
            },
            "tool" => StreamChunkKind::ToolChunk {
                tool_call: value
                    .get("toolCall")
                    .filter(|v| v.is_object() || v.is_array() || v.is_string())
                    .map(|v| ToolCall::load_from_value(v, ctx))
                    .unwrap_or_default(),
            },
            "error" => StreamChunkKind::ErrorChunk {
                message: value
                    .get("message")
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string(),
            },
            _ => StreamChunkKind::default(),
        };
        Self { kind: kind }
    }

    /// Returns the `kind` discriminator string for this instance.
    pub fn kind_str(&self) -> &str {
        match &self.kind {
            StreamChunkKind::TextChunk { .. } => "text",
            StreamChunkKind::ThinkingChunk { .. } => "thinking",
            StreamChunkKind::ToolChunk { .. } => "tool",
            StreamChunkKind::ErrorChunk { .. } => "error",
        }
    }

    /// Serialize StreamChunk to a `serde_json::Value`.
    ///
    /// Calls `ctx.process_dict` after serialization.
    pub fn to_value(&self, ctx: &SaveContext) -> serde_json::Value {
        let mut result = serde_json::Map::new();
        // Write the discriminator
        result.insert(
            "kind".to_string(),
            serde_json::Value::String(self.kind_str().to_string()),
        );
        // Write base fields
        // Write variant-specific fields
        match &self.kind {
            StreamChunkKind::TextChunk { value, .. } => {
                if !value.is_empty() {
                    result.insert(
                        "value".to_string(),
                        serde_json::Value::String(value.clone()),
                    );
                }
            }
            StreamChunkKind::ThinkingChunk { value, .. } => {
                if !value.is_empty() {
                    result.insert(
                        "value".to_string(),
                        serde_json::Value::String(value.clone()),
                    );
                }
            }
            StreamChunkKind::ToolChunk { tool_call, .. } => {
                let nested = tool_call.to_value(ctx);
                if !nested.is_null() {
                    result.insert("toolCall".to_string(), nested);
                }
            }
            StreamChunkKind::ErrorChunk { message, .. } => {
                if !message.is_empty() {
                    result.insert(
                        "message".to_string(),
                        serde_json::Value::String(message.clone()),
                    );
                }
            }
        }
        ctx.process_dict(serde_json::Value::Object(result))
    }

    /// Serialize StreamChunk to a JSON string.
    pub fn to_json(&self, ctx: &SaveContext) -> Result<String, serde_json::Error> {
        serde_json::to_string_pretty(&self.to_value(ctx))
    }

    /// Serialize StreamChunk to a YAML string.
    pub fn to_yaml(&self, ctx: &SaveContext) -> Result<String, serde_yaml::Error> {
        serde_yaml::to_string(&self.to_value(ctx))
    }
}