Skip to content

Commit c5c687d

Browse files
committed
Merge branch 'main' into persona-enablement
2 parents 17cb0e0 + 65da39d commit c5c687d

File tree

14 files changed

+232
-106
lines changed

14 files changed

+232
-106
lines changed

build-config/buildspec-macos.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ phases:
2424
- mise install
2525
- eval "$(mise activate zsh --shims)"
2626
# Install python deps
27-
- python3 -m venv scripts/.env
27+
- python3 -m venv build-scripts/.env
2828
- source build-scripts/.env/bin/activate
2929
- pip3 install -r build-scripts/requirements.txt
3030
build:

build-scripts/signing.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,9 @@ def apple_notarize_file(file: pathlib.Path, signing_data: CdSigningData):
298298

299299
def get_secretmanager_json(secret_id: str):
300300
info(f"Loading secretmanager value: {secret_id}")
301-
secret_value = run_cmd_output(["aws", "secretsmanager", "get-secret-value", "--secret-id", secret_id])
301+
secret_value = run_cmd_output(
302+
["aws", "--region", REGION, "secretsmanager", "get-secret-value", "--secret-id", secret_id]
303+
)
302304
secret_string = json.loads(secret_value)["SecretString"]
303305
return json.loads(secret_string)
304306

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ impl BuilderIdToken {
458458
Some(_) => TokenType::IamIdentityCenter,
459459
}
460460
}
461+
462+
/// Check if the token is for the internal amzn start URL (`https://amzn.awsapps.com/start`),
463+
/// this implies the user will use midway for private specs
464+
pub fn is_amzn_user(&self) -> bool {
465+
matches!(&self.start_url, Some(url) if url == AMZN_START_URL)
466+
}
461467
}
462468

463469
pub enum PollCreateToken {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,8 @@ pub(crate) const CLIENT_TYPE: &str = "public";
2121
// The start URL for public builder ID users
2222
pub const START_URL: &str = "https://view.awsapps.com/start";
2323

24+
// The start URL for internal amzn users
25+
pub const AMZN_START_URL: &str = "https://amzn.awsapps.com/start";
26+
2427
pub(crate) const DEVICE_GRANT_TYPE: &str = "urn:ietf:params:oauth:grant-type:device_code";
2528
pub(crate) const REFRESH_GRANT_TYPE: &str = "refresh_token";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ pub struct CompactArgs {
3535

3636
impl CompactArgs {
3737
pub async fn execute(self, os: &Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
38-
session.compact_history(os, self.prompt, self.show_summary).await
38+
session.compact_history(os, self.prompt, self.show_summary, true).await
3939
}
4040
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ pub enum ContextSubcommand {
5656
paths: Vec<String>,
5757
},
5858
/// Remove specified rules from current profile
59-
Remove { paths: Vec<String> },
59+
#[command(alias = "rm")]
60+
Remove {
61+
#[arg(required = true)]
62+
paths: Vec<String>,
63+
},
6064
/// Remove all rules from current profile
6165
Clear,
6266
#[command(hide = true)]

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ use crossterm::{
99
};
1010
use dialoguer::Select;
1111

12+
use crate::auth::builder_id::{
13+
BuilderIdToken,
14+
TokenType,
15+
};
1216
use crate::cli::chat::{
1317
ChatError,
1418
ChatSession,
@@ -98,10 +102,23 @@ impl ModelArgs {
98102
}
99103
}
100104

101-
/// Currently, Sonnet 4 is set as the default model for non-FRA users.
102-
pub fn default_model_id(os: &Os) -> &'static str {
103-
match os.database.get_auth_profile() {
104-
Ok(Some(profile)) if profile.arn.split(':').nth(3) == Some("eu-central-1") => "CLAUDE_3_7_SONNET_20250219_V1_0",
105-
_ => "CLAUDE_SONNET_4_20250514_V1_0",
105+
/// Returns Claude 3.7 for: Amazon IDC users, FRA region users
106+
/// Returns Claude 4.0 for: Builder ID users, other regions
107+
pub async fn default_model_id(os: &Os) -> &'static str {
108+
// Check FRA region first
109+
if let Ok(Some(profile)) = os.database.get_auth_profile() {
110+
if profile.arn.split(':').nth(3) == Some("eu-central-1") {
111+
return "CLAUDE_3_7_SONNET_20250219_V1_0";
112+
}
113+
}
114+
115+
// Check if Amazon IDC user
116+
if let Ok(Some(token)) = BuilderIdToken::load(&os.database).await {
117+
if matches!(token.token_type(), TokenType::IamIdentityCenter) && token.is_amzn_user() {
118+
return "CLAUDE_3_7_SONNET_20250219_V1_0";
119+
}
106120
}
121+
122+
// Default to 4.0
123+
"CLAUDE_SONNET_4_20250514_V1_0"
107124
}

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

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -496,16 +496,10 @@ impl ConversationState {
496496
})
497497
}
498498

499-
/// Whether or not it is possible to create a summary out of this conversation state.
500-
///
501-
/// Currently only checks if we have enough messages in the history to create a summary out of.
502-
pub async fn can_create_summary_request(&mut self, os: &Os) -> Result<bool, ChatError> {
503-
Ok(self
504-
.backend_conversation_state(os, false, &mut vec![])
505-
.await?
506-
.history
507-
.len()
508-
>= 2)
499+
pub async fn truncate_large_user_messages(&mut self) {
500+
for (user_message, _) in &mut self.history {
501+
user_message.truncate_safe(25_000);
502+
}
509503
}
510504

511505
/// Returns a [FigConversationState] capable of replacing the history of the current
@@ -559,14 +553,7 @@ impl ConversationState {
559553
};
560554

561555
let conv_state = self.backend_conversation_state(os, false, &mut vec![]).await?;
562-
563-
// Include everything but the last message in the history.
564-
let history_len = conv_state.history.len();
565-
let history = if history_len < 2 {
566-
vec![]
567-
} else {
568-
flatten_history(conv_state.history.take(history_len.saturating_sub(1)))
569-
};
556+
let history = flatten_history(conv_state.history);
570557

571558
let user_input_message_context = UserInputMessageContext {
572559
env_state: Some(build_env_state()),

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

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use serde::{
44
Deserialize,
55
Serialize,
66
};
7-
use tracing::error;
7+
use tracing::{
8+
error,
9+
warn,
10+
};
811

912
use super::consts::MAX_CURRENT_WORKING_DIRECTORY_LEN;
1013
use super::tools::{
@@ -15,6 +18,7 @@ use super::util::{
1518
document_to_serde_value,
1619
serde_value_to_document,
1720
truncate_safe,
21+
truncate_safe_in_place,
1822
};
1923
use crate::api_client::model::{
2024
AssistantResponseMessage,
@@ -55,6 +59,30 @@ pub enum UserMessageContent {
5559
},
5660
}
5761

62+
impl UserMessageContent {
63+
fn truncate_safe(&mut self, max_bytes: usize) {
64+
match self {
65+
UserMessageContent::Prompt { prompt } => {
66+
truncate_safe_in_place(prompt, max_bytes);
67+
},
68+
UserMessageContent::CancelledToolUses {
69+
prompt,
70+
tool_use_results,
71+
} => {
72+
if let Some(prompt) = prompt {
73+
truncate_safe_in_place(prompt, max_bytes / 2);
74+
truncate_safe_tool_use_results(tool_use_results.as_mut_slice(), max_bytes / 2);
75+
} else {
76+
truncate_safe_tool_use_results(tool_use_results.as_mut_slice(), max_bytes);
77+
}
78+
},
79+
UserMessageContent::ToolUseResults { tool_use_results } => {
80+
truncate_safe_tool_use_results(tool_use_results.as_mut_slice(), max_bytes);
81+
},
82+
}
83+
}
84+
}
85+
5886
impl UserMessage {
5987
/// Creates a new [UserMessage::Prompt], automatically detecting and adding the user's
6088
/// environment [UserEnvContext].
@@ -193,6 +221,14 @@ impl UserMessage {
193221
UserMessageContent::ToolUseResults { .. } => None,
194222
}
195223
}
224+
225+
/// Truncates the content contained in this user message to a maximum length of `max_bytes`.
226+
///
227+
/// This isn't a perfect truncation - JSON tool use results are ignored, and only the content
228+
/// of the user message is truncated, ignoring extra context fields.
229+
pub fn truncate_safe(&mut self, max_bytes: usize) {
230+
self.content.truncate_safe(max_bytes);
231+
}
196232
}
197233

198234
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -225,6 +261,20 @@ impl From<ToolUseResult> for ToolResult {
225261
}
226262
}
227263

264+
fn truncate_safe_tool_use_results(tool_use_results: &mut [ToolUseResult], max_bytes: usize) {
265+
let max_bytes = max_bytes / tool_use_results.len();
266+
for result in tool_use_results {
267+
for content in &mut result.content {
268+
match content {
269+
ToolUseResultBlock::Json(_) => {
270+
warn!("Unable to truncate JSON safely");
271+
},
272+
ToolUseResultBlock::Text(t) => truncate_safe_in_place(t, max_bytes),
273+
}
274+
}
275+
}
276+
}
277+
228278
#[derive(Debug, Clone, Serialize, Deserialize)]
229279
pub enum ToolUseResultBlock {
230280
Json(serde_json::Value),

0 commit comments

Comments
 (0)