gproxy_protocol/transform/generate/claude_gemini/stream/mod.rs
1//! Direct incremental Claude Messages ↔ Gemini GenerateContent streams.
2//!
3//! Source and target native collectors independently validate both lifecycles.
4//! Live text comes from actual fragments. Complete-source conversion is used
5//! only after termination for final usage/metadata and full canonical checks;
6//! emitted text is never replayed. Adjacent plain Gemini text fragments with
7//! the same thought flag are normalized only for canonical comparison.
8//!
9//! Claude blocks retain their native order, including interleaved tools and
10//! thoughts. The first text block remains live; later blocks wait until earlier
11//! blocks close. Initial text/tool input is preserved, and tool JSON completes
12//! before an immutable Gemini function call is emitted.
13//!
14//! Claude target start needs actual model and usage facts. Without them, target
15//! fragments wait in a bounded queue until a coherent native usage observation
16//! arrives. Missing source IDs can allocate stable aliases; late IDs attach to
17//! them. Context input/cache facts are fixed for this invocation. Final thinking
18//! facts do not become initial counters, and older cumulative components are
19//! not mistaken for final values when the native total grows.
20//!
21//! Every failed push poisons the converter. All output events, including start
22//! and terminal events, are charged once before native validation/retention.
23//! Required opaque replay, media/execution output and continuation state need
24//! an invocation adapter. Omitted optional metadata is reported separately.
25//! These contracts do not establish empirical equality of model judgments.
26
27mod claude_blocks;
28mod claude_to_gemini;
29mod common;
30mod gemini_to_claude;
31mod usage;
32
33pub use claude_to_gemini::{ClaudeToGeminiContext, ClaudeToGeminiStream};
34pub use common::{StreamEnd, StreamLimits};
35pub use gemini_to_claude::{GeminiToClaudeContext, GeminiToClaudeStream};