greentic-flow-builder 0.1.0

AI-powered Adaptive Card flow builder with visual graph editor and demo runner
Documentation
//! Minimal OpenAI chat client used by the `/api/chat` route.
//!
//! The system prompt is built by [`crate::ui::prompt_builder`]; this module
//! only handles the HTTP call.

use serde_json::Value;

pub async fn chat(
    api_key: &str,
    model: &str,
    system_prompt: &str,
    messages: &[Value],
) -> anyhow::Result<String> {
    let client = reqwest::Client::new();

    let mut api_messages = vec![serde_json::json!({
        "role": "system",
        "content": system_prompt,
    })];
    for msg in messages {
        api_messages.push(msg.clone());
    }

    let body = serde_json::json!({
        "model": model,
        "messages": api_messages,
        "response_format": { "type": "json_object" },
    });

    let response = client
        .post("https://api.openai.com/v1/chat/completions")
        .header("Authorization", format!("Bearer {api_key}"))
        .header("Content-Type", "application/json")
        .json(&body)
        .send()
        .await?;

    if !response.status().is_success() {
        let status = response.status();
        let text = response.text().await.unwrap_or_default();
        anyhow::bail!("OpenAI API error {status}: {text}");
    }

    let result: Value = response.json().await?;
    let content = result["choices"][0]["message"]["content"]
        .as_str()
        .unwrap_or("")
        .to_string();

    Ok(content)
}