Skip to content

Commit e4b9d44

Browse files
committed
Merge branch 'main' into auto-tool-name-resolution
2 parents 5fbf76c + 3220d81 commit e4b9d44

File tree

27 files changed

+1084
-151
lines changed

27 files changed

+1084
-151
lines changed

crates/chat-cli/src/api_client/clients/streaming_client.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ mod tests {
291291
.send_message(ConversationState {
292292
conversation_id: None,
293293
user_input_message: UserInputMessage {
294+
images: None,
294295
content: "Hello".into(),
295296
user_input_message_context: None,
296297
user_intent: None,
@@ -315,12 +316,14 @@ mod tests {
315316
.send_message(ConversationState {
316317
conversation_id: None,
317318
user_input_message: UserInputMessage {
319+
images: None,
318320
content: "How about rustc?".into(),
319321
user_input_message_context: None,
320322
user_intent: None,
321323
},
322324
history: Some(vec![
323325
ChatMessage::UserInputMessage(UserInputMessage {
326+
images: None,
324327
content: "What language is the linux kernel written in, and who wrote it?".into(),
325328
user_input_message_context: None,
326329
user_intent: None,

crates/chat-cli/src/api_client/model.rs

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use aws_smithy_types::Document;
1+
use aws_smithy_types::{
2+
Blob,
3+
Document,
4+
};
25
use serde::{
36
Deserialize,
47
Serialize,
@@ -565,17 +568,113 @@ impl From<GitState> for amzn_qdeveloper_streaming_client::types::GitState {
565568
}
566569
}
567570

571+
#[derive(Debug, Clone, Serialize, Deserialize)]
572+
pub struct ImageBlock {
573+
pub format: ImageFormat,
574+
pub source: ImageSource,
575+
}
576+
577+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
578+
pub enum ImageFormat {
579+
Gif,
580+
Jpeg,
581+
Png,
582+
Webp,
583+
}
584+
585+
impl std::str::FromStr for ImageFormat {
586+
type Err = String;
587+
588+
fn from_str(s: &str) -> Result<Self, Self::Err> {
589+
match s.trim().to_lowercase().as_str() {
590+
"gif" => Ok(ImageFormat::Gif),
591+
"jpeg" => Ok(ImageFormat::Jpeg),
592+
"jpg" => Ok(ImageFormat::Jpeg),
593+
"png" => Ok(ImageFormat::Png),
594+
"webp" => Ok(ImageFormat::Webp),
595+
_ => Err(format!("Failed to parse '{}' as ImageFormat", s)),
596+
}
597+
}
598+
}
599+
600+
impl From<ImageFormat> for amzn_codewhisperer_streaming_client::types::ImageFormat {
601+
fn from(value: ImageFormat) -> Self {
602+
match value {
603+
ImageFormat::Gif => Self::Gif,
604+
ImageFormat::Jpeg => Self::Jpeg,
605+
ImageFormat::Png => Self::Png,
606+
ImageFormat::Webp => Self::Webp,
607+
}
608+
}
609+
}
610+
impl From<ImageFormat> for amzn_qdeveloper_streaming_client::types::ImageFormat {
611+
fn from(value: ImageFormat) -> Self {
612+
match value {
613+
ImageFormat::Gif => Self::Gif,
614+
ImageFormat::Jpeg => Self::Jpeg,
615+
ImageFormat::Png => Self::Png,
616+
ImageFormat::Webp => Self::Webp,
617+
}
618+
}
619+
}
620+
621+
#[non_exhaustive]
622+
#[derive(Debug, Clone, Serialize, Deserialize)]
623+
pub enum ImageSource {
624+
Bytes(Vec<u8>),
625+
#[non_exhaustive]
626+
Unknown,
627+
}
628+
629+
impl From<ImageSource> for amzn_codewhisperer_streaming_client::types::ImageSource {
630+
fn from(value: ImageSource) -> Self {
631+
match value {
632+
ImageSource::Bytes(bytes) => Self::Bytes(Blob::new(bytes)),
633+
ImageSource::Unknown => Self::Unknown,
634+
}
635+
}
636+
}
637+
impl From<ImageSource> for amzn_qdeveloper_streaming_client::types::ImageSource {
638+
fn from(value: ImageSource) -> Self {
639+
match value {
640+
ImageSource::Bytes(bytes) => Self::Bytes(Blob::new(bytes)),
641+
ImageSource::Unknown => Self::Unknown,
642+
}
643+
}
644+
}
645+
646+
impl From<ImageBlock> for amzn_codewhisperer_streaming_client::types::ImageBlock {
647+
fn from(value: ImageBlock) -> Self {
648+
Self::builder()
649+
.format(value.format.into())
650+
.source(value.source.into())
651+
.build()
652+
.expect("Failed to build ImageBlock")
653+
}
654+
}
655+
impl From<ImageBlock> for amzn_qdeveloper_streaming_client::types::ImageBlock {
656+
fn from(value: ImageBlock) -> Self {
657+
Self::builder()
658+
.format(value.format.into())
659+
.source(value.source.into())
660+
.build()
661+
.expect("Failed to build ImageBlock")
662+
}
663+
}
664+
568665
#[derive(Debug, Clone)]
569666
pub struct UserInputMessage {
570667
pub content: String,
571668
pub user_input_message_context: Option<UserInputMessageContext>,
572669
pub user_intent: Option<UserIntent>,
670+
pub images: Option<Vec<ImageBlock>>,
573671
}
574672

575673
impl From<UserInputMessage> for amzn_codewhisperer_streaming_client::types::UserInputMessage {
576674
fn from(value: UserInputMessage) -> Self {
577675
Self::builder()
578676
.content(value.content)
677+
.set_images(value.images.map(|images| images.into_iter().map(Into::into).collect()))
579678
.set_user_input_message_context(value.user_input_message_context.map(Into::into))
580679
.set_user_intent(value.user_intent.map(Into::into))
581680
.origin(amzn_codewhisperer_streaming_client::types::Origin::Cli)
@@ -588,6 +687,7 @@ impl From<UserInputMessage> for amzn_qdeveloper_streaming_client::types::UserInp
588687
fn from(value: UserInputMessage) -> Self {
589688
Self::builder()
590689
.content(value.content)
690+
.set_images(value.images.map(|images| images.into_iter().map(Into::into).collect()))
591691
.set_user_input_message_context(value.user_input_message_context.map(Into::into))
592692
.set_user_intent(value.user_intent.map(Into::into))
593693
.origin(amzn_qdeveloper_streaming_client::types::Origin::Cli)
@@ -654,6 +754,10 @@ mod tests {
654754
#[test]
655755
fn build_user_input_message() {
656756
let user_input_message = UserInputMessage {
757+
images: Some(vec![ImageBlock {
758+
format: ImageFormat::Png,
759+
source: ImageSource::Bytes(vec![1, 2, 3]),
760+
}]),
657761
content: "test content".to_string(),
658762
user_input_message_context: Some(UserInputMessageContext {
659763
env_state: Some(EnvState {
@@ -690,6 +794,7 @@ mod tests {
690794
assert_eq!(format!("{codewhisper_input:?}"), format!("{qdeveloper_input:?}"));
691795

692796
let minimal_message = UserInputMessage {
797+
images: None,
693798
content: "test content".to_string(),
694799
user_input_message_context: None,
695800
user_intent: None,

crates/chat-cli/src/auth/builder_id.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl std::fmt::Display for OAuthFlow {
6969
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7070
match *self {
7171
OAuthFlow::DeviceCode => write!(f, "DeviceCode"),
72-
OAuthFlow::Pkce => write!(f, "PKCE"),
72+
OAuthFlow::Pkce => write!(f, "Pkce"),
7373
}
7474
}
7575
}
@@ -593,7 +593,7 @@ mod tests {
593593
#[test]
594594
fn test_oauth_flow_ser_deser() {
595595
test_ser_deser!(OAuthFlow, OAuthFlow::DeviceCode, "DeviceCode");
596-
test_ser_deser!(OAuthFlow, OAuthFlow::Pkce, "PKCE");
596+
test_ser_deser!(OAuthFlow, OAuthFlow::Pkce, "Pkce");
597597
}
598598

599599
#[test]

crates/chat-cli/src/auth/secret_store/sqlite.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![allow(dead_code)]
22
use super::Secret;
3-
use crate::Result;
43
use crate::auth::AuthError;
54
use crate::settings::sqlite::{
65
Db,

crates/chat-cli/src/cli/chat/consts.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ pub const MAX_USER_MESSAGE_SIZE: usize = 600_000;
1616
/// In tokens
1717
pub const CONTEXT_WINDOW_SIZE: usize = 200_000;
1818

19+
pub const CONTEXT_FILES_MAX_SIZE: usize = 150_000;
20+
1921
pub const MAX_CHARS: usize = TokenCounter::token_to_chars(CONTEXT_WINDOW_SIZE); // Character-based warning threshold
2022

2123
pub const DUMMY_TOOL_NAME: &str = "dummy";
24+
25+
pub const MAX_NUMBER_OF_IMAGES_PER_REQUEST: usize = 10;
26+
27+
/// In bytes - 10 MB
28+
pub const MAX_IMAGE_SIZE: usize = 10 * 1024 * 1024;

0 commit comments

Comments
 (0)