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::anthropic_tool_definition::AnthropicToolDefinition;

use super::anthropic_wire_message::AnthropicWireMessage;

/// The full request body for the Anthropic Messages API (ยง7.5).
#[derive(Debug, Clone, Default)]
pub struct AnthropicMessagesRequest {
    /// The model identifier
    pub model: String,
    /// The non-system messages to send
    pub messages: Vec<AnthropicWireMessage>,
    /// Maximum number of tokens to generate (required by Anthropic)
    pub max_tokens: i32,
    /// System prompt text (extracted from system-role messages)
    pub system: Option<String>,
    /// Sampling temperature
    pub temperature: Option<f32>,
    /// Top-P sampling value
    pub top_p: Option<f32>,
    /// Top-K sampling value
    pub top_k: Option<i32>,
    /// Stop sequences to end generation
    pub stop_sequences: Option<Vec<String>>,
    /// Tool definitions available to the model
    pub tools: Vec<AnthropicToolDefinition>,
}

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

    /// Load AnthropicMessagesRequest 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 AnthropicMessagesRequest 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 AnthropicMessagesRequest 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());
        Self {
            model: value
                .get("model")
                .and_then(|v| v.as_str())
                .unwrap_or_default()
                .to_string(),
            messages: value
                .get("messages")
                .map(|v| Self::load_messages(v, ctx))
                .unwrap_or_default(),
            max_tokens: value
                .get("max_tokens")
                .and_then(|v| v.as_i64())
                .unwrap_or(0) as i32,
            system: value
                .get("system")
                .and_then(|v| v.as_str())
                .map(|s| s.to_string()),
            temperature: value
                .get("temperature")
                .and_then(|v| v.as_f64())
                .map(|v| v as f32),
            top_p: value
                .get("top_p")
                .and_then(|v| v.as_f64())
                .map(|v| v as f32),
            top_k: value
                .get("top_k")
                .and_then(|v| v.as_i64())
                .map(|v| v as i32),
            stop_sequences: value
                .get("stop_sequences")
                .and_then(|v| v.as_array())
                .map(|arr| {
                    arr.iter()
                        .filter_map(|v| v.as_str().map(|s| s.to_string()))
                        .collect()
                }),
            tools: value
                .get("tools")
                .map(|v| Self::load_tools(v, ctx))
                .unwrap_or_default(),
        }
    }

    /// Serialize AnthropicMessagesRequest 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 base fields
        if !self.model.is_empty() {
            result.insert(
                "model".to_string(),
                serde_json::Value::String(self.model.clone()),
            );
        }
        if !self.messages.is_empty() {
            result.insert(
                "messages".to_string(),
                Self::save_messages(&self.messages, ctx),
            );
        }
        if self.max_tokens != 0 {
            result.insert(
                "max_tokens".to_string(),
                serde_json::Value::Number(serde_json::Number::from(self.max_tokens)),
            );
        }
        if let Some(ref val) = self.system {
            result.insert("system".to_string(), serde_json::Value::String(val.clone()));
        }
        if let Some(val) = self.temperature {
            result.insert(
                "temperature".to_string(),
                serde_json::Number::from_f64(val as f64)
                    .map(serde_json::Value::Number)
                    .unwrap_or(serde_json::Value::Null),
            );
        }
        if let Some(val) = self.top_p {
            result.insert(
                "top_p".to_string(),
                serde_json::Number::from_f64(val as f64)
                    .map(serde_json::Value::Number)
                    .unwrap_or(serde_json::Value::Null),
            );
        }
        if let Some(val) = self.top_k {
            result.insert(
                "top_k".to_string(),
                serde_json::Value::Number(serde_json::Number::from(val)),
            );
        }
        if let Some(ref items) = self.stop_sequences {
            result.insert(
                "stop_sequences".to_string(),
                serde_json::to_value(items).unwrap_or(serde_json::Value::Null),
            );
        }
        if !self.tools.is_empty() {
            result.insert("tools".to_string(), Self::save_tools(&self.tools, ctx));
        }
        ctx.process_dict(serde_json::Value::Object(result))
    }

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

    /// Load a collection of AnthropicWireMessage from a JSON value.
    /// Handles both array format `[{...}]`.
    fn load_messages(data: &serde_json::Value, ctx: &LoadContext) -> Vec<AnthropicWireMessage> {
        match data {
            serde_json::Value::Array(arr) => arr
                .iter()
                .map(|v| AnthropicWireMessage::load_from_value(v, ctx))
                .collect(),

            _ => Vec::new(),
        }
    }

    /// Save a collection of AnthropicWireMessage to a JSON value.
    fn save_messages(items: &[AnthropicWireMessage], ctx: &SaveContext) -> serde_json::Value {
        serde_json::Value::Array(
            items
                .iter()
                .map(|item| item.to_value(ctx))
                .collect::<Vec<_>>(),
        )
    }

    /// Load a collection of AnthropicToolDefinition from a JSON value.
    /// Handles both array format `[{...}]` and dict format `{"name": {...}}`.
    fn load_tools(data: &serde_json::Value, ctx: &LoadContext) -> Vec<AnthropicToolDefinition> {
        match data {
            serde_json::Value::Array(arr) => arr
                .iter()
                .map(|v| AnthropicToolDefinition::load_from_value(v, ctx))
                .collect(),

            serde_json::Value::Object(obj) => obj
                .iter()
                .filter_map(|(name, value)| {
                    if value.is_array() {
                        return None;
                    }
                    let mut v = if value.is_object() {
                        value.clone()
                    } else {
                        serde_json::json!({ "description": value })
                    };
                    if let serde_json::Value::Object(ref mut m) = v {
                        m.entry("name".to_string())
                            .or_insert_with(|| serde_json::Value::String(name.clone()));
                    }
                    Some(AnthropicToolDefinition::load_from_value(&v, ctx))
                })
                .collect(),
            _ => Vec::new(),
        }
    }

    /// Save a collection of AnthropicToolDefinition to a JSON value.
    fn save_tools(items: &[AnthropicToolDefinition], ctx: &SaveContext) -> serde_json::Value {
        if ctx.collection_format == "array" {
            return serde_json::Value::Array(
                items
                    .iter()
                    .map(|item| item.to_value(ctx))
                    .collect::<Vec<_>>(),
            );
        }
        // Object format: use name as key
        let mut result = serde_json::Map::new();
        for item in items {
            let mut item_data = match item.to_value(ctx) {
                serde_json::Value::Object(m) => m,
                other => {
                    let mut m = serde_json::Map::new();
                    m.insert("value".to_string(), other);
                    m
                }
            };
            if let Some(serde_json::Value::String(name)) = item_data.remove("name") {
                result.insert(name, serde_json::Value::Object(item_data));
            }
        }
        serde_json::Value::Object(result)
    }
}