2121import datadog .trace .bootstrap .instrumentation .api .AgentTracer ;
2222import java .io .IOException ;
2323import java .util .Collection ;
24+ import java .util .Collections ;
2425import java .util .HashMap ;
2526import java .util .List ;
2627import java .util .Map ;
3738
3839public class AIGuardInternal implements Evaluator {
3940
41+ public static class BadConfigurationException extends RuntimeException {
42+ public BadConfigurationException (final String message ) {
43+ super (message );
44+ }
45+ }
46+
4047 static final String SPAN_NAME = "ai_guard" ;
4148 static final String TARGET_TAG = "ai_guard.target" ;
4249 static final String TOOL_TAG = "ai_guard.tool" ;
@@ -51,7 +58,7 @@ public static void install() {
5158 final String apiKey = config .getApiKey ();
5259 final String appKey = config .getApplicationKey ();
5360 if (isEmpty (apiKey ) || isEmpty (appKey )) {
54- throw new RuntimeException (
61+ throw new BadConfigurationException (
5562 "AI Guard: Missing api and/or application key, use DD_API_KEY and DD_APP_KEY" );
5663 }
5764 String endpoint = config .getAiGuardEndpoint ();
@@ -98,11 +105,12 @@ private static List<Message> truncate(List<Message> messages) {
98105 final int maxContent = config .getAiGuardMaxContentSize ();
99106 for (int i = 0 ; i < messages .size (); i ++) {
100107 Message source = messages .get (i );
101- if (source .getContent () != null && source .getContent ().length () > maxContent ) {
108+ final String content = source .getContent ();
109+ if (content != null && content .length () > maxContent ) {
102110 source =
103111 new Message (
104112 source .getRole (),
105- source . getContent () .substring (0 , maxContent ),
113+ content .substring (0 , maxContent ),
106114 source .getToolCalls (),
107115 source .getToolCallId ());
108116 messages .set (i , source );
@@ -146,7 +154,7 @@ private boolean isBlockingEnabled(final Object isBlockingEnabled) {
146154 @ Override
147155 public Evaluation evaluate (final List <Message > messages , final Options options ) {
148156 if (messages == null || messages .isEmpty ()) {
149- throw new IllegalArgumentException ("messages must not be empty" );
157+ throw new IllegalArgumentException ("Messages must not be empty" );
150158 }
151159 final AgentTracer .TracerAPI tracer = AgentTracer .get ();
152160 final AgentSpan span = tracer .buildSpan (SPAN_NAME , SPAN_NAME ).start ();
@@ -161,8 +169,8 @@ public Evaluation evaluate(final List<Message> messages, final Options options)
161169 } else {
162170 span .setTag (TARGET_TAG , "prompt" );
163171 }
164- final Map <String , Object > metaStruct = new HashMap <>( 1 );
165- metaStruct . put (META_STRUCT_KEY , truncate (messages ));
172+ final Map <String , Object > metaStruct =
173+ Collections . singletonMap (META_STRUCT_KEY , truncate (messages ));
166174 span .setMetaStruct (META_STRUCT_TAG , metaStruct );
167175 final Request .Builder request =
168176 new Request .Builder ()
@@ -173,7 +181,7 @@ public Evaluation evaluate(final List<Message> messages, final Options options)
173181 final Map <String , Object > result = parseResponseBody (response );
174182 final String actionStr = (String ) result .get ("action" );
175183 if (actionStr == null ) {
176- throw new IllegalArgumentException ("action field is missing in the response" );
184+ throw new IllegalArgumentException ("Action field is missing in the response" );
177185 }
178186 final Action action = Action .valueOf (actionStr );
179187 final String reason = (String ) result .get ("reason" );
@@ -214,7 +222,7 @@ private Map<String, Object> parseResponseBody(final Response response) throws IO
214222 }
215223
216224 private AIGuardClientError fail (final int statusCode , final Object errors ) {
217- return new AIGuardClientError ("AI Guard service call failed, status" + statusCode , errors );
225+ return new AIGuardClientError ("AI Guard service call failed, status: " + statusCode , errors );
218226 }
219227
220228 private static OkHttpClient buildClient (final HttpUrl url , final long timeout ) {
0 commit comments