@@ -30,6 +30,7 @@ import {
3030 PromptInputOptionChangeParams ,
3131 TextDocument ,
3232 ChatUpdateParams ,
33+ MessageType ,
3334} from '@aws/language-server-runtimes/protocol'
3435import {
3536 ApplyWorkspaceEditParams ,
@@ -132,6 +133,7 @@ import { URI } from 'vscode-uri'
132133import { AgenticChatError , customerFacingErrorCodes , isRequestAbortedError , unactionableErrorCodes } from './errors'
133134import { CommandCategory } from './tools/executeBash'
134135import { UserWrittenCodeTracker } from '../../shared/userWrittenCodeTracker'
136+ import { PaidTierMode } from '../paidTier/paidTier'
135137
136138type ChatHandlers = Omit <
137139 LspHandlers < Chat > ,
@@ -163,7 +165,7 @@ export class AgenticChatController implements ChatHandlers {
163165 #userWrittenCodeTracker: UserWrittenCodeTracker | undefined
164166 #toolUseStartTimes: Record < string , number > = { }
165167 #toolUseLatencies: Array < { toolName : string ; toolUseId : string ; latency : number } > = [ ]
166- #freeTierLimit = false
168+ #paidTierMode: PaidTierMode | undefined
167169
168170 /**
169171 * Determines the appropriate message ID for a tool use based on tool type and name
@@ -277,29 +279,47 @@ export class AgenticChatController implements ChatHandlers {
277279 . createSubscriptionToken ( {
278280 accountId : awsAccountId ,
279281 } )
282+
280283 if ( ! r . encodedVerificationUrl ) {
281284 this . #log( 'missing encodedVerificationUrl in server response' )
285+ this . #features. lsp . window
286+ . showMessage ( {
287+ message : 'Subscription request failed. Check the account id.' ,
288+ type : MessageType . Error ,
289+ } )
290+ . catch ( e => {
291+ this . #log( `showMessage failed: ${ ( e as Error ) . message } ` )
292+ } )
282293 return {
283294 success : false ,
284295 failureReason : 'missing encodedVerificationUrl in server response' ,
285296 }
286297 }
287298
288- this . #log ( `encodedVerificationUrl ${ r . encodedVerificationUrl } ` )
299+ const uri = r . encodedVerificationUrl
289300
290301 try {
291- URI . parse ( r . encodedVerificationUrl )
302+ URI . parse ( uri )
292303 } catch ( e ) {
293- this . #log( `invalid encodedVerificationUrl: '${ r . encodedVerificationUrl } ': ${ ( e as Error ) . message } ` )
304+ this . #log( `invalid encodedVerificationUrl: '${ uri } ': ${ ( e as Error ) . message } ` )
294305 return {
295306 success : false ,
296307 failureReason : 'invalid encodedVerificationUrl' ,
297308 }
298309 }
299310
311+ this . #features. lsp . window
312+ . showMessage ( {
313+ message : 'Upgraded to [Amazon Q Pro](https://aws.amazon.com/q/)' ,
314+ type : MessageType . Info ,
315+ } )
316+ . catch ( e => {
317+ this . #log( `showMessage failed: ${ ( e as Error ) . message } ` )
318+ } )
319+
300320 this . #features. lsp . window . showDocument ( {
301321 external : true , // Client is expected to open the URL in a web browser.
302- uri : r . encodedVerificationUrl ,
322+ uri : uri ,
303323 } )
304324 } catch ( e ) {
305325 return {
@@ -308,7 +328,7 @@ export class AgenticChatController implements ChatHandlers {
308328 }
309329 }
310330
311- this . setUpgradeQMode ( params . tabId , 'paidtier' )
331+ this . setPaidTierMode ( params . tabId , 'paidtier-success ' )
312332 return { success : true }
313333 } else {
314334 return {
@@ -1971,7 +1991,7 @@ export class AgenticChatController implements ChatHandlers {
19711991
19721992 // TODO handle free tier limit exceeded
19731993 if ( isFreeTierLimitError ( err ) ) {
1974- this . setUpgradeQMode ( tabId , 'freetier-limit' )
1994+ this . setPaidTierMode ( tabId , 'freetier-limit' )
19751995 // throw new AmazonQFreeTierLimitError()
19761996 }
19771997
@@ -2239,12 +2259,6 @@ export class AgenticChatController implements ChatHandlers {
22392259 } catch ( error ) {
22402260 this . #log( 'Error initializing context commands: ' + error )
22412261 }
2242-
2243- try {
2244- this . setUpgradeQMode ( )
2245- } catch ( err ) {
2246- this . #log( 'Error initializing Free Tier state: ' + ( err as Error ) . message )
2247- }
22482262 }
22492263
22502264 onSendFeedback ( { tabId, feedbackPayload } : FeedbackParams ) {
@@ -2271,7 +2285,7 @@ export class AgenticChatController implements ChatHandlers {
22712285
22722286 this . #chatSessionManagementService. createSession ( params . tabId )
22732287
2274- this . setUpgradeQMode ( params . tabId )
2288+ this . setPaidTierMode ( params . tabId )
22752289 }
22762290
22772291 onTabChange ( params : TabChangeParams ) {
@@ -2434,57 +2448,44 @@ export class AgenticChatController implements ChatHandlers {
24342448 * Updates the "Upgrade Q" (subscription tier) state of the UI in the chat component. If `mode` is not given, the user's subscription status is checked by calling the Q service.
24352449 *
24362450 * `mode` behavior:
2437- * - 'freetier': always show "Upgrade Q" button .
2451+ * - 'freetier': treated as 'freetier-limit' if `this.#paidTierMode='freetier-limit'` .
24382452 * - 'freetier-limit': also show "Free Tier limit reached" card in chat.
24392453 * - This mode is "sticky" until 'paidtier' is passed to override it.
2440- * - 'paidtier': don't show "Upgrade Q" button .
2454+ * - 'paidtier': disable any "free-tier limit" UI .
24412455 */
2442- async setUpgradeQMode (
2443- tabId ?: string ,
2444- mode ?: 'paidtier' | 'freetier' | 'freetier-limit' /*, session: ChatSessionService*/
2445- ) {
2446- this . #log(
2447- `xxx setUpgradeQMode: mode=${ mode } getCodewhispererService=${ ! ! this . #serviceManager?. getCodewhispererService ( ) } `
2448- )
2456+ setPaidTierMode ( tabId ?: string , mode ?: PaidTierMode ) {
2457+ this . #log( `xxx setPaidTierMode: mode=${ mode } ` )
2458+
24492459 if ( mode === 'freetier-limit' ) {
2450- this . #freeTierLimit = true // Sticky until 'paidtier' is sent.
2460+ this . #paidTierMode = mode // Sticky until 'paidtier' is sent.
24512461 } else if ( mode === 'paidtier' ) {
2452- this . #freeTierLimit = false
2453- } else if ( this . #freeTierLimit && ( ! mode || mode === 'freetier' ) ) {
2462+ this . #paidTierMode = mode
2463+ } else if ( this . #paidTierMode === 'freetier-limit' && mode === 'freetier' ) {
24542464 mode = 'freetier-limit'
24552465 } else if ( ! mode ) {
2456- try {
2457- // Note: intentionally async.
2458- AmazonQTokenServiceManager . getInstance ( )
2459- ?. getCodewhispererService ( )
2460- . getSubscriptionStatus ( )
2461- . then ( o => {
2462- this . #log( `xxx getSubscriptionStatus: ${ o . status } ${ o . encodedVerificationUrl } ` )
2463- this . setUpgradeQMode ( tabId , o . status === 'ACTIVE' ? 'paidtier' : 'freetier' )
2464- } )
2465- . catch ( err => {
2466- this . #log( `xxx getSubscriptionStatus failed: ${ JSON . stringify ( err ) } ` )
2467- } )
2468-
2469- // const isFreeTierUser = getSsoConnectionType(this.#features.credentialsProvider) === 'builderId'
2470- // mode = isFreeTierUser ? 'freetier' : 'paidtier'
2471- } catch {
2472- this . #log( `xxx yucky` )
2473- }
2466+ // Note: intentionally async.
2467+ AmazonQTokenServiceManager . getInstance ( )
2468+ ?. getCodewhispererService ( )
2469+ . getSubscriptionStatus ( )
2470+ . then ( o => {
2471+ this . #log( `xxx getSubscriptionStatus: ${ o . status } ${ o . encodedVerificationUrl } ` )
2472+ this . setPaidTierMode ( tabId , o . status === 'ACTIVE' ? 'paidtier' : 'freetier' )
2473+ } )
2474+ . catch ( err => {
2475+ this . #log( `xxx getSubscriptionStatus failed: ${ JSON . stringify ( err ) } ` )
2476+ } )
2477+ // const isFreeTierUser = getSsoConnectionType(this.#features.credentialsProvider) === 'builderId'
2478+ // mode = isFreeTierUser ? 'freetier' : 'paidtier'
24742479
24752480 return
24762481 }
24772482
24782483 const o : ChatUpdateParams = {
2479- tabId : tabId ?? 'xxx' ,
2480- state : { inProgress : false } ,
2481- data : {
2482- // Special flag recognized by `chat-client/src/client/mynahUi.ts`.
2483- placeholderText : 'upgrade-q' ,
2484- messages : [ ] ,
2485- } ,
2484+ tabId : tabId ?? '' ,
2485+ // data: { messages: [] },
24862486 }
2487- ; ( o as any ) . upgradeQMode = mode
2487+ // Special flag recognized by `chat-client/src/client/mynahUi.ts`.
2488+ ; ( o as any ) . paidTierMode = mode
24882489 this . #features. chat . sendChatUpdate ( o )
24892490 }
24902491
@@ -2735,6 +2736,9 @@ export class AgenticChatController implements ChatHandlers {
27352736 const updatedOptOutPreference = newConfig . optOutTelemetryPreference
27362737 this . #telemetryService. updateOptOutPreference ( updatedOptOutPreference )
27372738 this . #log( `Chat configuration telemetry preference to ${ updatedOptOutPreference } ` )
2739+
2740+ // Force a service request to get current Q user subscription status.
2741+ this . #paidTierMode = undefined
27382742 }
27392743
27402744 #getTools( session : ChatSessionService ) {
0 commit comments