gproxy-transform
Convert requests, responses, and streaming events between the OpenAI, Anthropic Claude, and Google Gemini APIs.
gproxy-transform is the transform layer of
GPROXY, built on the wire types in
gproxy-protocol. It is a pure,
synchronous library: no HTTP client, no runtime, no I/O.
Usage
[]
= "=2.3.0"
Resolve a pair from the source/target operation keys, then run the bytes-level dispatch:
use ;
use ;
let source = content_generation;
let target = content_generation;
// Request direction: inbound OpenAI chat body → upstream Claude messages body.
let pair = resolve?;
let ctx = new.with_request;
let converted = request_bytes_detailed?;
let upstream_body = converted.value;
let semantic_losses = converted.diagnostics;
// Response direction uses the REVERSE pair.
let back = resolve?;
let back_ctx = new;
let inbound_body = response_bytes?;
// Streaming is stateful and one input event may yield zero or many outputs.
let mut stream = new?;
let inbound_events = stream.push?;
let final_events = stream.finish?;
Design
- Pairwise, no intermediate representation. Every conversion is a direct
source → targetmodule. This keeps provider-specific quirks in the one file that owns them instead of leaking into a shared IR. - Organized by operation, not by provider.
generate_content,count_tokens,models,embeddings,images,compact. - Same-kind traffic never enters this crate. Route it as passthrough.
extrafields are not preserved. Sourceextrais dropped; targetextrastarts empty.- Streaming is
0..Nand stateful. Retain onedispatch::StreamConverter(orstream_adapter::SseTransformer) for the whole response so multi-part frames and tool calls split across frames are preserved. - The default SSE adapter is strict: malformed/oversized frames and abnormal
EOF return errors and do not synthesize a successful terminator. Lenient
skipping is an explicit
StreamOptionschoice. request_bytes_detailed,response_bytes_detailed,push_detailed, andfinish_detailedreturn structured non-fatal semantic-loss diagnostics.- Routing tables, database rules, and logging policy belong to the host;
gproxy-transformcontains no routing-policy module.
Use dispatch::is_wired to check whether a resolved pair has a bytes-level
implementation before routing traffic through it.
Modules
| Module | Purpose |
|---|---|
dispatch |
Bytes-level (pair, ctx, body) -> body entry points |
generate_content |
Chat/messages/generateContent pairs, streaming included |
count_tokens |
Token-count request/response pairs |
models |
Model list/get pairs |
embeddings |
Embedding pairs |
images |
Image create/edit pairs |
compact |
Context-compaction pairs |
stream_adapter |
Runtime SSE adapter (decode → convert → re-encode) |
common |
Mechanical helpers only (SSE framing, roles, tool ids, usage) |
License
Licensed under the MIT License.