Skip to main content

prompty_foundry/
processor.rs

1//! Foundry/Azure OpenAI processor — delegates to the OpenAI processor.
2//!
3//! Azure OpenAI uses the same response format as OpenAI, so we reuse
4//! the OpenAI processor's `process_response` function directly.
5
6use async_trait::async_trait;
7use serde_json::Value;
8
9use prompty::interfaces::{InvokerError, Processor};
10use prompty::model::Prompty;
11
12/// Foundry/Azure OpenAI processor implementing the `Processor` trait.
13///
14/// Delegates entirely to the OpenAI processor since Azure OpenAI
15/// returns the same response format.
16pub struct FoundryProcessor;
17
18#[async_trait]
19impl Processor for FoundryProcessor {
20    async fn process(&self, agent: &Prompty, response: Value) -> Result<Value, InvokerError> {
21        prompty_openai::process_response(agent, &response)
22    }
23
24    fn process_stream(
25        &self,
26        inner: std::pin::Pin<Box<dyn futures::Stream<Item = Value> + Send>>,
27    ) -> Result<
28        std::pin::Pin<Box<dyn futures::Stream<Item = prompty::types::StreamChunk> + Send>>,
29        InvokerError,
30    > {
31        // Azure uses the same SSE chunk format as OpenAI
32        prompty_openai::OpenAIProcessor.process_stream(inner)
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use prompty::model::context::LoadContext;
40    use serde_json::json;
41
42    fn make_agent() -> Prompty {
43        let data = json!({
44            "name": "test",
45            "kind": "prompt",
46            "model": {
47                "id": "gpt-4",
48                "connection": {
49                    "kind": "key",
50                    "endpoint": "https://myresource.openai.azure.com",
51                    "apiKey": "test-key"
52                }
53            },
54            "instructions": "test"
55        });
56        Prompty::load_from_value(&data, &LoadContext::default())
57    }
58
59    #[tokio::test]
60    async fn test_process_chat_response() {
61        let agent = make_agent();
62        let response = json!({
63            "choices": [{
64                "message": {
65                    "role": "assistant",
66                    "content": "Hello from Azure!"
67                },
68                "finish_reason": "stop"
69            }]
70        });
71
72        let result = FoundryProcessor.process(&agent, response).await.unwrap();
73        assert_eq!(result, "Hello from Azure!");
74    }
75
76    #[tokio::test]
77    async fn test_process_embedding_response() {
78        let agent = make_agent();
79        let response = json!({
80            "object": "list",
81            "data": [
82                {"object": "embedding", "embedding": [0.1, 0.2, 0.3], "index": 0}
83            ]
84        });
85
86        let result = FoundryProcessor.process(&agent, response).await.unwrap();
87        assert!(result.is_array());
88    }
89}