va_ai_api_bridge/translator/
mod.rs1mod anthropic;
2pub mod anthropic_messages;
3mod common;
4pub mod gemini_generate_content;
5mod openai;
6pub mod openai_chat;
7pub mod openai_responses;
8
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11
12use crate::{DecodeState, EncodeState, Result, UniversalEvent, UniversalRequest, WireProtocol};
13
14pub use anthropic_messages::AnthropicMessagesTranslator;
15pub use gemini_generate_content::{
16 GeminiGenerateContentTranslator, GEMINI_SKIP_THOUGHT_SIGNATURE_VALIDATOR,
17};
18pub use openai_chat::OpenAiChatTranslator;
19pub use openai_responses::OpenAiResponsesTranslator;
20
21#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
22#[serde(rename_all = "camelCase")]
23pub struct WireEvent {
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 pub event: Option<String>,
26 pub data: Value,
27}
28
29pub trait WireTranslator {
30 fn protocol(&self) -> WireProtocol;
31
32 fn decode_request(&self, raw: Value) -> Result<UniversalRequest>;
33
34 fn encode_request(&self, request: &UniversalRequest) -> Result<Value>;
35
36 fn decode_response(&self, raw: Value) -> Result<Vec<UniversalEvent>>;
37
38 fn decode_stream_chunk(
39 &self,
40 raw: Value,
41 state: &mut DecodeState,
42 ) -> Result<Vec<UniversalEvent>>;
43
44 fn encode_events(
45 &self,
46 events: &[UniversalEvent],
47 state: &mut EncodeState,
48 ) -> Result<Vec<WireEvent>>;
49}
50
51pub fn translator_for_protocol(protocol: WireProtocol) -> Box<dyn WireTranslator> {
52 match protocol {
53 WireProtocol::OpenAiResponses => Box::new(OpenAiResponsesTranslator),
54 WireProtocol::OpenAiChat => Box::new(OpenAiChatTranslator),
55 WireProtocol::AnthropicMessages => Box::new(AnthropicMessagesTranslator),
56 WireProtocol::GeminiGenerateContent => Box::new(GeminiGenerateContentTranslator),
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use crate::{translator::translator_for_protocol, WireProtocol};
63
64 #[test]
65 fn creates_translator_for_each_wire_protocol() {
66 for protocol in [
67 WireProtocol::OpenAiResponses,
68 WireProtocol::OpenAiChat,
69 WireProtocol::AnthropicMessages,
70 WireProtocol::GeminiGenerateContent,
71 ] {
72 assert_eq!(translator_for_protocol(protocol).protocol(), protocol);
73 }
74 }
75}