11import { BedrockRuntimeClient , InvokeModelCommand } from '@aws-sdk/client-bedrock-runtime' ;
22import { fetchAuthSession } from '@aws-amplify/auth' ;
33import { REGION } from '../../config/aws-config' ;
4+ import i18n from '../../utils/i18n' ;
5+
6+ // This function gets the translated message from i18n
7+ const getContentFilteredMessage = ( ) : string => {
8+ return i18n . t ( 'ai.content_filtered' , { ns : 'errors' } ) ;
9+ } ;
410
511export interface ChatMessage {
612 role : 'user' | 'assistant' | 'system' ;
@@ -14,11 +20,24 @@ export interface ChatSession {
1420 updatedAt : Date ;
1521}
1622
23+ // Interfaces for Bedrock API responses
24+ interface BedrockResult {
25+ tokenCount : number ;
26+ outputText : string ;
27+ completionReason : 'CONTENT_FILTERED' | 'COMPLETE' | 'LENGTH' | 'STOP_SEQUENCE' | string ;
28+ }
29+
30+ interface BedrockResponse {
31+ inputTextTokenCount : number ;
32+ results : BedrockResult [ ] ;
33+ }
34+
1735class BedrockService {
1836 private client : BedrockRuntimeClient | null = null ;
1937 private readonly MODEL_ID = 'amazon.titan-text-lite-v1' ;
2038 private sessions : Map < string , ChatSession > = new Map ( ) ;
2139 private isTestEnvironment : boolean ;
40+ private contentFilteredCount : number = 0 ; // Track number of filtered responses
2241
2342 constructor ( ) {
2443 // Check if we're in a test environment (Node.js environment with no window)
@@ -67,6 +86,27 @@ class BedrockService {
6786 }
6887 }
6988
89+ private handleBedrockResponse ( parsedResponse : BedrockResponse ) : string {
90+ // Check if we have results
91+ if ( ! parsedResponse . results || ! parsedResponse . results . length ) {
92+ throw new Error ( 'Invalid response structure: missing results' ) ;
93+ }
94+
95+ const result = parsedResponse . results [ 0 ] ;
96+
97+ // Check for content filtering
98+ if ( result . completionReason === "CONTENT_FILTERED" ) {
99+ // Increment counter for analytics
100+ this . contentFilteredCount ++ ;
101+
102+ // Return the translated message
103+ return getContentFilteredMessage ( ) ;
104+ }
105+
106+
107+ return result . outputText ;
108+ }
109+
70110 private async invokeModel ( prompt : string ) : Promise < string > {
71111 // In test environment, return a mock response
72112 if ( this . isTestEnvironment || ! this . client ) {
@@ -92,8 +132,9 @@ class BedrockService {
92132 const command = new InvokeModelCommand ( input ) ;
93133 const response = await this . client . send ( command ) ;
94134 const responseBody = new TextDecoder ( ) . decode ( response . body ) ;
95- const parsedResponse = JSON . parse ( responseBody ) ;
96- return parsedResponse . results [ 0 ] . outputText ;
135+ const parsedResponse = JSON . parse ( responseBody ) as BedrockResponse ;
136+
137+ return this . handleBedrockResponse ( parsedResponse ) ;
97138 } catch ( error ) {
98139 console . error ( 'Error invoking Bedrock model:' , error ) ;
99140 throw error ;
@@ -162,6 +203,11 @@ class BedrockService {
162203 public getAllSessions ( ) : ChatSession [ ] {
163204 return Array . from ( this . sessions . values ( ) ) ;
164205 }
206+
207+ // Add a method to get stats
208+ public getContentFilteredStats ( ) : { count : number } {
209+ return { count : this . contentFilteredCount } ;
210+ }
165211}
166212
167213export const bedrockService = new BedrockService ( ) ;
0 commit comments