Skip to content

Commit 5d7e808

Browse files
committed
feat: q builder id pro subscription flow
- Add better message to indicate when the user has reached their monthly query limit. - Add new command `/subscribe` to initiate a subscription flow to paid usage for builder ID users - IDC users cannot use this flow
1 parent 8473a95 commit 5d7e808

7 files changed

Lines changed: 244 additions & 23 deletions

File tree

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

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@ use amzn_codewhisperer_client::Client as CodewhispererClient;
22
use amzn_codewhisperer_client::operation::create_subscription_token::CreateSubscriptionTokenOutput;
33
use amzn_codewhisperer_client::types::{
44
OptOutPreference,
5-
SubscriptionStatus,
65
TelemetryEvent,
76
UserContext,
87
};
98
use tracing::error;
109

1110
use super::shared::bearer_sdk_config;
12-
use crate::api_client::consts::SUBSCRIPTION_STATUS_ACCOUNT_ID;
1311
use crate::api_client::interceptor::opt_out::OptOutInterceptor;
1412
use crate::api_client::{
1513
ApiClientError,
@@ -125,15 +123,12 @@ impl Client {
125123
}
126124
}
127125

128-
#[allow(dead_code)] // TODO: Remove
129126
pub async fn create_subscription_token(
130127
&self,
131-
account_id: &str,
132128
) -> Result<CreateSubscriptionTokenOutput, ApiClientError> {
133129
match &self.inner {
134130
inner::Inner::Codewhisperer(client) => client
135131
.create_subscription_token()
136-
.account_id(account_id)
137132
.send()
138133
.await
139134
.map_err(ApiClientError::CreateSubscriptionToken),
@@ -142,18 +137,6 @@ impl Client {
142137
.build()?),
143138
}
144139
}
145-
146-
#[allow(dead_code)] // TODO: Remove
147-
pub async fn get_subscription_status(&self) -> Result<SubscriptionStatus, ApiClientError> {
148-
match &self.inner {
149-
inner::Inner::Codewhisperer(_) => Ok(self
150-
.create_subscription_token(SUBSCRIPTION_STATUS_ACCOUNT_ID)
151-
.await?
152-
.status()
153-
.clone()),
154-
inner::Inner::Mock => Ok(SubscriptionStatus::Active),
155-
}
156-
}
157140
}
158141

159142
#[cfg(test)]

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,3 @@ pub const PROD_CODEWHISPERER_FRA_ENDPOINT_REGION: Region = Region::from_static("
1313

1414
// Opt out constants
1515
pub const X_AMZN_CODEWHISPERER_OPT_OUT_HEADER: &str = "x-amzn-codewhisperer-optout";
16-
17-
// Dummy value that simply provides subscription status (for the holder of a given bearer token)
18-
// This is a design decision on the service-side to avoid creating a dedicated status API.
19-
#[allow(dead_code)] // TODO: Remove
20-
pub const SUBSCRIPTION_STATUS_ACCOUNT_ID: &str = "111111111111";

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ use tracing::{
4848
trace,
4949
warn,
5050
};
51+
use eyre::{
52+
Result,
53+
eyre,
54+
};
5155

5256
use crate::api_client::clients::shared::stalled_stream_protection_config;
5357
use crate::auth::AuthError;
@@ -568,6 +572,14 @@ impl ResolveIdentity for BearerResolver {
568572
}
569573
}
570574

575+
pub async fn is_idc_user(database: &Database) -> Result<bool> {
576+
if let Ok(Some(token)) = BuilderIdToken::load(database).await {
577+
return Ok(token.token_type() == TokenType::IamIdentityCenter);
578+
} else {
579+
return Err(eyre!("No auth token found - is the user signed in?"));
580+
}
581+
}
582+
571583
#[cfg(test)]
572584
mod tests {
573585
use super::*;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub enum Command {
5959
force: bool,
6060
},
6161
Mcp,
62+
Subscribe,
6263
}
6364

6465
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -839,6 +840,7 @@ impl Command {
839840
Self::Save { path, force }
840841
},
841842
"mcp" => Self::Mcp,
843+
"subscribe" => Self::Subscribe,
842844
unknown_command => {
843845
let looks_like_path = {
844846
let after_slash_command_str = parts[1..].join(" ");

0 commit comments

Comments
 (0)