Skip to main content

gproxy_protocol/transform/
mod.rs

1//! Cross-protocol transforms for LLM API requests and responses.
2//!
3//! Transforms are organized in a three-dimensional matrix:
4//! **source protocol** x **operation** x **target protocol**.
5//!
6//! ```text
7//! transform/
8//! ├── claude/                          # Source: Claude Messages API
9//! │   ├── generate_content/
10//! │   │   ├── gemini/                  # → Gemini GenerateContent
11//! │   │   ├── openai_chat_completions/ # → OpenAI ChatCompletions
12//! │   │   └── openai_response/         # → OpenAI Responses
13//! │   ├── stream_generate_content/     # Same targets, streaming variant
14//! │   ├── count_tokens/                # Token counting
15//! │   ├── model_list/ & model_get/     # Model catalog
16//! │   ├── nonstream_to_stream          # Full response → stream events
17//! │   └── stream_to_nonstream          # Stream events → full response
18//! ├── openai/                          # Source: OpenAI APIs
19//! │   ├── generate_content/
20//! │   │   ├── openai_chat_completions/ # ChatCompletions → other targets
21//! │   │   └── openai_response/         # Responses → other targets
22//! │   ├── stream_generate_content/     # Streaming variants
23//! │   ├── compact/                     # Responses API compaction
24//! │   ├── create_image/ & create_video/# Media generation
25//! │   └── websocket/                   # WebSocket ↔ HTTP bridge
26//! └── gemini/                          # Source: Gemini API
27//!     ├── generate_content/            # → Claude / OpenAI targets
28//!     ├── stream_generate_content/     # Streaming variants
29//!     └── websocket/                   # Live API WebSocket ↔ HTTP bridge
30//! ```
31//!
32//! # Non-streaming transforms
33//!
34//! Non-streaming transforms use `TryFrom` for type-safe conversion:
35//!
36//! ```rust,ignore
37//! use gproxy_protocol::claude::create_message::request::ClaudeCreateMessageRequest;
38//! use gproxy_protocol::openai::create_chat_completions::request::OpenAiChatCompletionsRequest;
39//!
40//! let openai_req = OpenAiChatCompletionsRequest::try_from(claude_req)?;
41//! ```
42//!
43//! # Streaming transforms
44//!
45//! Stream converters are stateful. They process one chunk at a time and push
46//! output events into a caller-provided buffer (zero allocation after warmup):
47//!
48//! ```rust,ignore
49//! let mut converter = OpenAiChatCompletionsToClaudeStream::default();
50//! let mut buf = Vec::new();
51//!
52//! // Per chunk:
53//! converter.on_chunk(chunk, &mut buf);
54//! for event in buf.drain(..) { /* forward downstream */ }
55//!
56//! // On stream end:
57//! converter.finish(&mut buf);
58//! for event in buf.drain(..) { /* forward remaining */ }
59//! ```
60//!
61//! # Format conversion utilities
62//!
63//! Each source protocol provides `nonstream_to_stream` and `stream_to_nonstream`
64//! converters for bridging between streaming and non-streaming representations:
65//!
66//! ```rust,ignore
67//! use gproxy_protocol::transform::claude::nonstream_to_stream::nonstream_to_stream;
68//! use gproxy_protocol::claude::create_message::stream::ClaudeStreamEvent;
69//!
70//! let mut events = Vec::new();
71//! nonstream_to_stream(full_response, &mut events)?;
72//! ```
73//!
74//! # WebSocket bridge
75//!
76//! OpenAI and Gemini provide `websocket/from_http` and `websocket/to_http` submodules
77//! that bridge between HTTP request/response types and WebSocket frame types.
78//! A `context` struct collects non-fatal warnings about dropped fields or
79//! downgraded features during conversion.
80
81pub mod claude;
82pub mod dispatch;
83pub mod gemini;
84pub mod openai;
85pub mod utils;
86
87pub use utils::{TransformError, TransformResult};