Skip to main content

gproxy_protocol/aws/converse/
stream.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use crate::aws::{ConversationRole, Rest, StopReason};
5
6use super::{
7    ContentBlockDelta, ContentBlockStart, ConverseMetrics, ConverseStreamTrace,
8    PerformanceConfiguration, ServiceTier, TokenUsage,
9};
10
11/// A decoded Smithy event-stream item. The discriminant comes from the
12/// `:event-type` or `:exception-type` header; the inner struct is the frame's
13/// JSON payload.
14#[derive(Debug, Clone, PartialEq)]
15#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
16pub enum ConverseStreamEvent {
17    MessageStart(MessageStartEvent),
18    ContentBlockStart(ContentBlockStartEvent),
19    ContentBlockDelta(ContentBlockDeltaEvent),
20    ContentBlockStop(ContentBlockStopEvent),
21    MessageStop(MessageStopEvent),
22    Metadata(Box<ConverseStreamMetadataEvent>),
23    InternalServerException(StreamException),
24    ModelStreamErrorException(ModelStreamErrorException),
25    ValidationException(StreamException),
26    ThrottlingException(StreamException),
27    ServiceUnavailableException(StreamException),
28    Unknown { event_type: String, payload: Value },
29}
30
31#[derive(
32    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
33)]
34#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
35pub struct MessageStartEvent {
36    pub role: ConversationRole,
37    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
38    pub rest: Rest,
39}
40
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43#[derive(gproxy_protocol_macros::WireBuilder)]
44#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
45pub struct ContentBlockStartEvent {
46    pub start: ContentBlockStart,
47    pub content_block_index: u64,
48    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
49    pub rest: Rest,
50}
51
52#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53#[serde(rename_all = "camelCase")]
54#[derive(gproxy_protocol_macros::WireBuilder)]
55#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
56pub struct ContentBlockDeltaEvent {
57    pub delta: ContentBlockDelta,
58    pub content_block_index: u64,
59    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
60    pub rest: Rest,
61}
62
63#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
64#[serde(rename_all = "camelCase")]
65#[derive(gproxy_protocol_macros::WireBuilder)]
66#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
67pub struct ContentBlockStopEvent {
68    pub content_block_index: u64,
69    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
70    pub rest: Rest,
71}
72
73#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74#[serde(rename_all = "camelCase")]
75#[derive(gproxy_protocol_macros::WireBuilder)]
76#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
77pub struct MessageStopEvent {
78    pub stop_reason: StopReason,
79    /// `upstream_docs/aws/docs/ConverseStream.md`,
80    /// `messageStop.additionalModelResponseFields`: model-specific fields as a JSON value.
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub additional_model_response_fields: Option<Value>,
83    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
84    pub rest: Rest,
85}
86
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
88#[serde(rename_all = "camelCase")]
89#[derive(gproxy_protocol_macros::WireBuilder)]
90#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
91pub struct ConverseStreamMetadataEvent {
92    pub usage: TokenUsage,
93    pub metrics: ConverseMetrics,
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub performance_config: Option<PerformanceConfiguration>,
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub service_tier: Option<ServiceTier>,
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub trace: Option<ConverseStreamTrace>,
100    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
101    pub rest: Rest,
102}
103
104#[derive(
105    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
106)]
107#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
108pub struct StreamException {
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub message: Option<String>,
111    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
112    pub rest: Rest,
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
116#[serde(rename_all = "camelCase")]
117#[derive(gproxy_protocol_macros::WireBuilder)]
118#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
119pub struct ModelStreamErrorException {
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub message: Option<String>,
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub original_status_code: Option<u16>,
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub original_message: Option<String>,
126    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
127    pub rest: Rest,
128}