Skip to content

Commit 486e601

Browse files
authored
fix: Model selection telemetry events (#165)
* checkpoint * blah * remove local lockfile * remove other branch things * fix tests
1 parent 9f963ff commit 486e601

File tree

9 files changed

+69
-114
lines changed

9 files changed

+69
-114
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl Client {
7878
telemetry_event: TelemetryEvent,
7979
user_context: UserContext,
8080
telemetry_enabled: bool,
81-
model_id: Option<String>,
81+
model: Option<String>,
8282
) -> Result<(), ApiClientError> {
8383
match &self.inner {
8484
inner::Inner::Codewhisperer(client) => {
@@ -91,7 +91,7 @@ impl Client {
9191
false => OptOutPreference::OptOut,
9292
})
9393
.set_profile_arn(self.profile.as_ref().map(|p| p.arn.clone()))
94-
.set_model_id(model_id)
94+
.set_model_id(model)
9595
.send()
9696
.await?;
9797
Ok(())

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub struct ConversationState {
107107
pub updates: Option<SharedWriter>,
108108
/// Model explicitly selected by the user in this conversation state via `/model`.
109109
#[serde(default, skip_serializing_if = "Option::is_none")]
110-
pub current_model_id: Option<String>,
110+
pub model: Option<String>,
111111
}
112112

113113
impl ConversationState {
@@ -161,7 +161,7 @@ impl ConversationState {
161161
context_message_length: None,
162162
latest_summary: None,
163163
updates,
164-
current_model_id,
164+
model: current_model_id,
165165
}
166166
}
167167

@@ -533,7 +533,7 @@ impl ConversationState {
533533
context_messages,
534534
dropped_context_files,
535535
tools: &self.tools,
536-
model_id: self.current_model_id.as_deref(),
536+
model_id: self.model.as_deref(),
537537
}
538538
}
539539

@@ -605,7 +605,7 @@ impl ConversationState {
605605
user_input_message_context: None,
606606
user_intent: None,
607607
images: None,
608-
model_id: self.current_model_id.clone(),
608+
model_id: self.model.clone(),
609609
};
610610

611611
// If the last message contains tool uses, then add cancelled tool results to the summary

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

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ const SMALL_SCREEN_WELCOME_TEXT: &str = color_print::cstr! {"<em>Welcome to <cya
406406
const RESUME_TEXT: &str = color_print::cstr! {"<em>Picking up where we left off...</em>"};
407407

408408
// Only show the model-related tip for now to make users aware of this feature.
409-
const ROTATING_TIPS: [&str; 1] = [
409+
const ROTATING_TIPS: [&str; 2] = [
410410
// color_print::cstr! {"You can resume the last conversation from your current directory by launching with
411411
// <green!>q chat --resume</green!>"}, color_print::cstr! {"Get notified whenever Q CLI finishes responding.
412412
// Just run <green!>q settings chat.enableNotifications true</green!>"}, color_print::cstr! {"You can use
@@ -425,7 +425,7 @@ const ROTATING_TIPS: [&str; 1] = [
425425
// int}</green!>. Servers that takes longer than the specified time will continue to load in the background. Use
426426
// /tools to see pending servers."}, color_print::cstr! {"You can see the server load status as well as any
427427
// warnings or errors associated with <green!>/mcp</green!>"},
428-
// color_print::cstr! {"Use <green!>/model</green!> to select the model to use for this conversation"},
428+
color_print::cstr! {"Use <green!>/model</green!> to select the model to use for this conversation"},
429429
color_print::cstr! {"Set a default model by running <green!>q settings chat.defaultModel MODEL</green!>. Run <green!>/model</green!> to learn more."},
430430
];
431431

@@ -435,18 +435,17 @@ pub struct ModelOption {
435435
}
436436

437437
pub const MODEL_OPTIONS: [ModelOption; 3] = [
438-
// ModelOption { name: "Auto", model_id: "CLAUDE_3_5_SONNET_20241022_V2_0" },
439438
ModelOption {
440-
name: "claude-3.5-sonnet",
441-
model_id: "CLAUDE_3_5_SONNET_20241022_V2_0",
439+
name: "claude-4-sonnet",
440+
model_id: "CLAUDE_SONNET_4_20250514_V1_0",
442441
},
443442
ModelOption {
444443
name: "claude-3.7-sonnet",
445444
model_id: "CLAUDE_3_7_SONNET_20250219_V1_0",
446445
},
447446
ModelOption {
448-
name: "claude-4-sonnet",
449-
model_id: "CLAUDE_SONNET_4_20250514_V1_0",
447+
name: "claude-3.5-sonnet",
448+
model_id: "CLAUDE_3_5_SONNET_20241022_V2_0",
450449
},
451450
];
452451

@@ -839,9 +838,7 @@ impl ChatContext {
839838

840839
execute!(self.output, style::Print(welcome_text), style::Print("\n\n"),)?;
841840

842-
let current_tip_index = database.increment_rotating_tip(ROTATING_TIPS.len());
843-
844-
let tip = ROTATING_TIPS[current_tip_index];
841+
let tip = ROTATING_TIPS[usize::try_from(rand::random::<u32>()).unwrap_or(0) % ROTATING_TIPS.len()];
845842
if is_small_screen {
846843
// If the screen is small, print the tip in a single line
847844
execute!(
@@ -895,7 +892,7 @@ impl ChatContext {
895892
});
896893

897894
if self.interactive {
898-
if let Some(ref id) = self.conversation_state.current_model_id {
895+
if let Some(ref id) = self.conversation_state.model {
899896
if let Some(model_option) = MODEL_OPTIONS.iter().find(|option| option.model_id == *id) {
900897
execute!(
901898
self.output,
@@ -3157,7 +3154,7 @@ impl ChatContext {
31573154
},
31583155
Command::Model => {
31593156
queue!(self.output, style::Print("\n"))?;
3160-
let active_model_id = self.conversation_state.current_model_id.as_deref();
3157+
let active_model_id = self.conversation_state.model.as_deref();
31613158
let labels: Vec<String> = MODEL_OPTIONS
31623159
.iter()
31633160
.map(|opt| {
@@ -3170,14 +3167,11 @@ impl ChatContext {
31703167
}
31713168
})
31723169
.collect();
3173-
let default_index = MODEL_OPTIONS
3174-
.iter()
3175-
.position(|opt| Some(opt.model_id) == active_model_id)
3176-
.unwrap_or(0);
3170+
31773171
let selection: Option<_> = match Select::with_theme(&crate::util::dialoguer_theme())
31783172
.with_prompt("Select a model for this chat session")
31793173
.items(&labels)
3180-
.default(default_index)
3174+
.default(0)
31813175
.interact_on_opt(&dialoguer::console::Term::stdout())
31823176
{
31833177
Ok(sel) => {
@@ -3197,14 +3191,12 @@ impl ChatContext {
31973191
if let Some(index) = selection {
31983192
let selected = &MODEL_OPTIONS[index];
31993193
let model_id_str = selected.model_id.to_string();
3200-
self.conversation_state.current_model_id = Some(model_id_str.clone());
3201-
telemetry.update_model_id(Some(model_id_str.clone()));
3202-
// let _ = database.set_last_used_model_id(model_id_str);
3194+
self.conversation_state.model = Some(model_id_str);
32033195

32043196
queue!(
32053197
self.output,
32063198
style::Print("\n"),
3207-
style::Print(format!(" Switched model to {}\n\n", selected.name)),
3199+
style::Print(format!(" Using {}\n\n", selected.name)),
32083200
style::ResetColor,
32093201
style::SetForegroundColor(Color::Reset),
32103202
style::SetBackgroundColor(Color::Reset),
@@ -3647,10 +3639,14 @@ impl ChatContext {
36473639
for tool_use in tool_uses {
36483640
let tool_use_id = tool_use.id.clone();
36493641
let tool_use_name = tool_use.name.clone();
3650-
let mut tool_telemetry = ToolUseEventBuilder::new(conv_id.clone(), tool_use.id.clone())
3651-
.set_tool_use_id(tool_use_id.clone())
3652-
.set_tool_name(tool_use.name.clone())
3653-
.utterance_id(self.conversation_state.message_id().map(|s| s.to_string()));
3642+
let mut tool_telemetry = ToolUseEventBuilder::new(
3643+
conv_id.clone(),
3644+
tool_use.id.clone(),
3645+
self.conversation_state.model.clone(),
3646+
)
3647+
.set_tool_use_id(tool_use_id.clone())
3648+
.set_tool_name(tool_use.name.clone())
3649+
.utterance_id(self.conversation_state.message_id().map(|s| s.to_string()));
36543650
match self.conversation_state.tool_manager.get_tool_from_tool_use(tool_use) {
36553651
Ok(mut tool) => {
36563652
// Apply non-Q-generated context to tools
@@ -3898,6 +3894,7 @@ impl ChatContext {
38983894
result,
38993895
reason,
39003896
reason_desc,
3897+
self.conversation_state.model.clone(),
39013898
)
39023899
.await
39033900
.ok();

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ use std::io::{
1515
use std::process::ExitCode;
1616

1717
use anstream::println;
18-
pub use chat::{
19-
ConversationState,
20-
DEFAULT_MODEL_ID,
21-
MODEL_OPTIONS,
22-
};
18+
pub use chat::ConversationState;
2319
use clap::{
2420
ArgAction,
2521
CommandFactory,

crates/chat-cli/src/database/mod.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ const START_URL_KEY: &str = "auth.idc.start-url";
6060
const IDC_REGION_KEY: &str = "auth.idc.region";
6161
// We include this key to remove for backwards compatibility
6262
const CUSTOMIZATION_STATE_KEY: &str = "api.selectedCustomization";
63-
const ROTATING_TIP_KEY: &str = "chat.greeting.rotating_tips_current_index";
64-
// const LAST_USED_MODEL_ID: &str = "lastUsedModelId";
6563

6664
const MIGRATIONS: &[Migration] = migrations![
6765
"000_migration_table",
@@ -302,24 +300,6 @@ impl Database {
302300
self.set_json_entry(Table::State, IDC_REGION_KEY, region)
303301
}
304302

305-
/// Get the rotating tip used for chat then post increment.
306-
///
307-
/// If any error is encountered while reading the database, a random index is returned instead.
308-
pub fn increment_rotating_tip(&mut self, max_size: usize) -> usize {
309-
let tip: usize = match self.get_entry(Table::State, ROTATING_TIP_KEY) {
310-
Ok(v) => v.unwrap_or(rand::random_range(0..max_size)),
311-
Err(err) => {
312-
error!(?err, "failed to get incrementing rotating tip");
313-
rand::random_range(0..max_size)
314-
},
315-
};
316-
let next_tip = tip.wrapping_add(1) % max_size;
317-
self.set_entry(Table::State, ROTATING_TIP_KEY, next_tip)
318-
.map_err(|err| error!(?err, next_tip, "failed to update rotating tip key"))
319-
.ok();
320-
tip
321-
}
322-
323303
// /// Get the model id used for last conversation state.
324304
// pub fn get_last_used_model_id(&self) -> Result<Option<String>, DatabaseError> {
325305
// self.get_json_entry::<String>(Table::State, LAST_USED_MODEL_ID)

crates/chat-cli/src/telemetry/core.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,25 @@ impl Event {
103103
}
104104
.into_metric_datum(),
105105
),
106-
EventType::ChatStart { conversation_id } => Some(
106+
EventType::ChatStart { conversation_id, model } => Some(
107107
AmazonqStartChat {
108108
create_time: self.created_time,
109109
value: None,
110110
credential_start_url: self.credential_start_url.map(Into::into),
111111
amazonq_conversation_id: Some(conversation_id.into()),
112112
codewhispererterminal_in_cloudshell: None,
113+
codewhispererterminal_model: model.map(Into::into),
113114
}
114115
.into_metric_datum(),
115116
),
116-
EventType::ChatEnd { conversation_id } => Some(
117+
EventType::ChatEnd { conversation_id, model } => Some(
117118
AmazonqEndChat {
118119
create_time: self.created_time,
119120
value: None,
120121
credential_start_url: self.credential_start_url.map(Into::into),
121122
amazonq_conversation_id: Some(conversation_id.into()),
122123
codewhispererterminal_in_cloudshell: None,
124+
codewhispererterminal_model: model.map(Into::into),
123125
}
124126
.into_metric_datum(),
125127
),
@@ -131,6 +133,7 @@ impl Event {
131133
result,
132134
reason,
133135
reason_desc,
136+
model,
134137
..
135138
} => Some(
136139
CodewhispererterminalAddChatMessage {
@@ -146,6 +149,7 @@ impl Event {
146149
result: result.to_string().into(),
147150
reason: reason.map(Into::into),
148151
reason_desc: reason_desc.map(Into::into),
152+
codewhispererterminal_model: model.map(Into::into),
149153
}
150154
.into_metric_datum(),
151155
),
@@ -162,6 +166,7 @@ impl Event {
162166
input_token_size,
163167
output_token_size,
164168
custom_tool_call_latency,
169+
model,
165170
} => Some(
166171
CodewhispererterminalToolUseSuggested {
167172
create_time: self.created_time,
@@ -182,6 +187,7 @@ impl Event {
182187
.map(|s| CodewhispererterminalCustomToolOutputTokenSize(s as i64)),
183188
codewhispererterminal_custom_tool_latency: custom_tool_call_latency
184189
.map(|l| CodewhispererterminalCustomToolLatency(l as i64)),
190+
codewhispererterminal_model: model.map(Into::into),
185191
}
186192
.into_metric_datum(),
187193
),
@@ -279,9 +285,11 @@ pub enum EventType {
279285
},
280286
ChatStart {
281287
conversation_id: String,
288+
model: Option<String>,
282289
},
283290
ChatEnd {
284291
conversation_id: String,
292+
model: Option<String>,
285293
},
286294
ChatAddedMessage {
287295
conversation_id: String,
@@ -291,6 +299,7 @@ pub enum EventType {
291299
result: TelemetryResult,
292300
reason: Option<String>,
293301
reason_desc: Option<String>,
302+
model: Option<String>,
294303
},
295304
ToolUseSuggested {
296305
conversation_id: String,
@@ -305,6 +314,7 @@ pub enum EventType {
305314
input_token_size: Option<usize>,
306315
output_token_size: Option<usize>,
307316
custom_tool_call_latency: Option<usize>,
317+
model: Option<String>,
308318
},
309319
McpServerInit {
310320
conversation_id: String,
@@ -347,10 +357,11 @@ pub struct ToolUseEventBuilder {
347357
pub input_token_size: Option<usize>,
348358
pub output_token_size: Option<usize>,
349359
pub custom_tool_call_latency: Option<usize>,
360+
pub model: Option<String>,
350361
}
351362

352363
impl ToolUseEventBuilder {
353-
pub fn new(conv_id: String, tool_use_id: String) -> Self {
364+
pub fn new(conv_id: String, tool_use_id: String, model: Option<String>) -> Self {
354365
Self {
355366
conversation_id: conv_id,
356367
utterance_id: None,
@@ -364,6 +375,7 @@ impl ToolUseEventBuilder {
364375
input_token_size: None,
365376
output_token_size: None,
366377
custom_tool_call_latency: None,
378+
model,
367379
}
368380
}
369381

crates/chat-cli/src/telemetry/definitions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mod tests {
3030
result: crate::telemetry::definitions::types::Result::new("Succeeded".to_string()),
3131
reason: None,
3232
reason_desc: None,
33+
codewhispererterminal_model: None,
3334
});
3435

3536
let s = serde_json::to_string_pretty(&metric_datum_init).unwrap();

0 commit comments

Comments
 (0)