Skip to content

Commit 8af40e3

Browse files
authored
feat: add history to ConversationState in StreamingClient::send_message (#280)
1 parent 85be9c3 commit 8af40e3

File tree

4 files changed

+123
-3
lines changed

4 files changed

+123
-3
lines changed

crates/fig_api_client/src/clients/streaming_client.rs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ impl StreamingClient {
8686
let ConversationState {
8787
conversation_id,
8888
user_input_message,
89+
history,
8990
} = conversation_state;
9091

9192
match &self.0 {
@@ -98,7 +99,12 @@ impl StreamingClient {
9899
user_input_message.into(),
99100
),
100101
)
101-
.chat_trigger_type(amzn_codewhisperer_streaming_client::types::ChatTriggerType::Manual);
102+
.chat_trigger_type(amzn_codewhisperer_streaming_client::types::ChatTriggerType::Manual)
103+
.set_history(
104+
history
105+
.map(|v| v.into_iter().map(|i| i.try_into()).collect::<Result<Vec<_>, _>>())
106+
.transpose()?,
107+
);
102108

103109
Ok(SendMessageOutput::Codewhisperer(
104110
client
@@ -114,7 +120,12 @@ impl StreamingClient {
114120
.current_message(amzn_qdeveloper_streaming_client::types::ChatMessage::UserInputMessage(
115121
user_input_message.into(),
116122
))
117-
.chat_trigger_type(amzn_qdeveloper_streaming_client::types::ChatTriggerType::Manual);
123+
.chat_trigger_type(amzn_qdeveloper_streaming_client::types::ChatTriggerType::Manual)
124+
.set_history(
125+
history
126+
.map(|v| v.into_iter().map(|i| i.try_into()).collect::<Result<Vec<_>, _>>())
127+
.transpose()?,
128+
);
118129

119130
Ok(SendMessageOutput::QDeveloper(
120131
client
@@ -168,7 +179,11 @@ impl RequestId for SendMessageOutput {
168179
#[cfg(test)]
169180
mod tests {
170181
use super::*;
171-
use crate::model::UserInputMessage;
182+
use crate::model::{
183+
AssistantResponseMessage,
184+
ChatMessage,
185+
UserInputMessage,
186+
};
172187

173188
#[tokio::test]
174189
async fn create_clients() {
@@ -194,6 +209,7 @@ mod tests {
194209
user_input_message_context: None,
195210
user_intent: None,
196211
},
212+
history: None,
197213
})
198214
.await
199215
.unwrap();
@@ -204,4 +220,36 @@ mod tests {
204220
}
205221
assert_eq!(output_content, "Hello! How can I assist you today?");
206222
}
223+
224+
#[ignore]
225+
#[tokio::test]
226+
async fn assistant_response() {
227+
let client = StreamingClient::new().await.unwrap();
228+
let mut response = client
229+
.send_message(ConversationState {
230+
conversation_id: None,
231+
user_input_message: UserInputMessage {
232+
content: "How about rustc?".into(),
233+
user_input_message_context: None,
234+
user_intent: None,
235+
},
236+
history: Some(vec![
237+
ChatMessage::UserInputMessage(UserInputMessage {
238+
content: "What language is the linux kernel written in, and who wrote it?".into(),
239+
user_input_message_context: None,
240+
user_intent: None,
241+
}),
242+
ChatMessage::AssistantResponseMessage(AssistantResponseMessage {
243+
content: "It is written in C by Linus Torvalds.".into(),
244+
message_id: None,
245+
}),
246+
]),
247+
})
248+
.await
249+
.unwrap();
250+
251+
while let Some(event) = response.recv().await.unwrap() {
252+
println!("{:?}", event);
253+
}
254+
}
207255
}

crates/fig_api_client/src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ pub enum Error {
4444
#[error("{}", SdkErrorDisplay(.0))]
4545
QDeveloperChatResponseStream(#[from] SdkError<QDeveloperChatResponseStreamError, RawMessage>),
4646

47+
#[error(transparent)]
48+
SmithyBuild(#[from] aws_smithy_types::error::operation::BuildError),
49+
4750
#[error("unsupported action by consolas: {0}")]
4851
UnsupportedConsolas(&'static str),
4952
}
@@ -62,6 +65,7 @@ impl Error {
6265
Error::QDeveloperSendMessage(e) => e.as_service_error().map_or(false, |e| e.is_throttling_error()),
6366
Error::CodewhispererChatResponseStream(_)
6467
| Error::QDeveloperChatResponseStream(_)
68+
| Error::SmithyBuild(_)
6569
| Error::UnsupportedConsolas(_) => false,
6670
}
6771
}
@@ -77,6 +81,7 @@ impl Error {
7781
Error::QDeveloperSendMessage(e) => e.as_service_error().is_some(),
7882
Error::CodewhispererChatResponseStream(_)
7983
| Error::QDeveloperChatResponseStream(_)
84+
| Error::SmithyBuild(_)
8085
| Error::UnsupportedConsolas(_) => false,
8186
}
8287
}
@@ -135,6 +140,7 @@ mod tests {
135140
QDeveloperChatResponseStreamError::unhandled("<unhandled>"),
136141
raw_message(),
137142
)),
143+
Error::SmithyBuild(aws_smithy_types::error::operation::BuildError::other("<other>")),
138144
Error::UnsupportedConsolas("test"),
139145
]
140146
}

crates/fig_api_client/src/model.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,71 @@ pub struct Recommendation {
7777
pub struct ConversationState {
7878
pub conversation_id: Option<String>,
7979
pub user_input_message: UserInputMessage,
80+
pub history: Option<Vec<ChatMessage>>,
81+
}
82+
83+
#[derive(Debug, Clone)]
84+
pub enum ChatMessage {
85+
AssistantResponseMessage(AssistantResponseMessage),
86+
UserInputMessage(UserInputMessage),
87+
}
88+
89+
impl TryFrom<ChatMessage> for amzn_codewhisperer_streaming_client::types::ChatMessage {
90+
type Error = aws_smithy_types::error::operation::BuildError;
91+
92+
fn try_from(value: ChatMessage) -> Result<Self, Self::Error> {
93+
Ok(match value {
94+
ChatMessage::AssistantResponseMessage(message) => {
95+
amzn_codewhisperer_streaming_client::types::ChatMessage::AssistantResponseMessage(message.try_into()?)
96+
},
97+
ChatMessage::UserInputMessage(message) => {
98+
amzn_codewhisperer_streaming_client::types::ChatMessage::UserInputMessage(message.into())
99+
},
100+
})
101+
}
102+
}
103+
104+
impl TryFrom<ChatMessage> for amzn_qdeveloper_streaming_client::types::ChatMessage {
105+
type Error = aws_smithy_types::error::operation::BuildError;
106+
107+
fn try_from(value: ChatMessage) -> Result<Self, Self::Error> {
108+
Ok(match value {
109+
ChatMessage::AssistantResponseMessage(message) => {
110+
amzn_qdeveloper_streaming_client::types::ChatMessage::AssistantResponseMessage(message.try_into()?)
111+
},
112+
ChatMessage::UserInputMessage(message) => {
113+
amzn_qdeveloper_streaming_client::types::ChatMessage::UserInputMessage(message.into())
114+
},
115+
})
116+
}
117+
}
118+
119+
#[derive(Debug, Clone)]
120+
pub struct AssistantResponseMessage {
121+
pub message_id: Option<String>,
122+
pub content: String,
123+
}
124+
125+
impl TryFrom<AssistantResponseMessage> for amzn_codewhisperer_streaming_client::types::AssistantResponseMessage {
126+
type Error = aws_smithy_types::error::operation::BuildError;
127+
128+
fn try_from(value: AssistantResponseMessage) -> Result<Self, Self::Error> {
129+
Self::builder()
130+
.content(value.content)
131+
.set_message_id(value.message_id)
132+
.build()
133+
}
134+
}
135+
136+
impl TryFrom<AssistantResponseMessage> for amzn_qdeveloper_streaming_client::types::AssistantResponseMessage {
137+
type Error = aws_smithy_types::error::operation::BuildError;
138+
139+
fn try_from(value: AssistantResponseMessage) -> Result<Self, Self::Error> {
140+
Self::builder()
141+
.content(value.content)
142+
.set_message_id(value.message_id)
143+
.build()
144+
}
80145
}
81146

82147
#[non_exhaustive]

crates/q_cli/src/cli/chat/api.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ pub(super) async fn send_message(
311311
let conversation_state = ConversationState {
312312
conversation_id,
313313
user_input_message,
314+
history: None,
314315
};
315316

316317
tokio::spawn(async move {

0 commit comments

Comments
 (0)