Skip to content

Commit 9528f98

Browse files
committed
add AI prompts and completions
1 parent 152c403 commit 9528f98

File tree

42 files changed

+280
-117
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+280
-117
lines changed

core/src/main/java/com/javaaidev/agenticpatterns/core/AbstractAgenticWorkflow.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ public abstract class AbstractAgenticWorkflow<Request, Response> implements
1616

1717
protected AbstractAgenticWorkflow(@Nullable String name,
1818
@Nullable ObservationRegistry observationRegistry) {
19-
this.name = Objects.requireNonNullElseGet(name, () -> this.getClass().getSimpleName());
19+
this.name = Objects.requireNonNullElseGet(name,
20+
() -> this.getClass().getSimpleName());
2021
this.observationRegistry = observationRegistry;
2122
}
2223

@@ -30,7 +31,8 @@ public Response execute(@Nullable Request request) {
3031
if (observationRegistry == null || observationRegistry.isNoop()) {
3132
return doExecute(request);
3233
}
33-
var observationContext = new WorkflowExecutionObservationContext(getName(), request);
34+
var observationContext = new WorkflowExecutionObservationContext(
35+
getName(), request);
3436
var observation =
3537
WorkflowExecutionObservationDocumentation.WORKFLOW_EXECUTION.observation(
3638
null,

core/src/main/java/com/javaaidev/agenticpatterns/core/AgentUtils.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ public class AgentUtils {
2626
*/
2727
public static String loadPromptTemplateFromClasspath(String resource) {
2828
try {
29-
return new ClassPathResource(resource).getContentAsString(StandardCharsets.UTF_8);
29+
return new ClassPathResource(resource).getContentAsString(
30+
StandardCharsets.UTF_8);
3031
} catch (IOException e) {
31-
throw new AgentExecutionException("Prompt template not found: " + resource, e);
32+
throw new AgentExecutionException(
33+
"Prompt template not found: " + resource, e);
3234
}
3335
}
3436

@@ -39,7 +41,8 @@ public static String loadPromptTemplateFromClasspath(String resource) {
3941
* @param map2 Second map
4042
* @return Merged map
4143
*/
42-
public static Map<String, Object> mergeMap(@Nullable Map<String, Object> map1,
44+
public static Map<String, Object> mergeMap(
45+
@Nullable Map<String, Object> map1,
4346
@Nullable Map<String, Object> map2) {
4447
var m1 = Optional.ofNullable(map1)
4548
.orElseGet(HashMap::new);
@@ -51,7 +54,8 @@ public static Map<String, Object> mergeMap(@Nullable Map<String, Object> map1,
5154
return result;
5255
}
5356

54-
public static <T, R> R safeGet(@Nullable T obj, Function<T, R> extractor, R defaultValue) {
57+
public static <T, R> R safeGet(@Nullable T obj, Function<T, R> extractor,
58+
R defaultValue) {
5559
return Optional.ofNullable(obj).map(extractor).orElse(defaultValue);
5660
}
5761

core/src/main/java/com/javaaidev/agenticpatterns/core/CustomWorkflowBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public class CustomWorkflowBuilder<Request, Response> extends
2222
* @param action Action to run
2323
* @return Current builder
2424
*/
25-
public CustomWorkflowBuilder<Request, Response> action(Function<Request, Response> action) {
25+
public CustomWorkflowBuilder<Request, Response> action(
26+
Function<Request, Response> action) {
2627
this.action = Objects.requireNonNull(action, "Action cannot be null");
2728
return this;
2829
}

core/src/main/java/com/javaaidev/agenticpatterns/core/ParameterizedTypeImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
public record ParameterizedTypeImpl(@Nullable Type rawType,
88
Type[] actualTypeArguments,
9-
@Nullable Type ownerType) implements ParameterizedType {
9+
@Nullable Type ownerType) implements
10+
ParameterizedType {
1011

1112
@Override
1213
public Type[] getActualTypeArguments() {

core/src/main/java/com/javaaidev/agenticpatterns/core/TypeResolver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ private static Type doResolveType(final ResolvableType type) {
2424
return Object.class;
2525
}
2626
var generics = type.getGenerics();
27-
var paraType = new ParameterizedTypeImpl(type.resolve(), new Type[generics.length],
27+
var paraType = new ParameterizedTypeImpl(type.resolve(),
28+
new Type[generics.length],
2829
null);
2930
for (int i = 0; i < generics.length; i++) {
3031
var nestedType = generics[i];

core/src/main/java/com/javaaidev/agenticpatterns/core/observation/AgentExecutionObservationContext.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
import io.micrometer.observation.transport.RequestReplySenderContext;
44

5-
public class AgentExecutionObservationContext extends RequestReplySenderContext<Object, Object> {
5+
public class AgentExecutionObservationContext extends
6+
RequestReplySenderContext<Object, Object> {
67

78
private final String agentName;
89

core/src/main/java/com/javaaidev/agenticpatterns/core/observation/AgentExecutionObservationDocumentation.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import io.micrometer.observation.ObservationConvention;
66
import io.micrometer.observation.docs.ObservationDocumentation;
77

8-
public enum AgentExecutionObservationDocumentation implements ObservationDocumentation {
8+
public enum AgentExecutionObservationDocumentation implements
9+
ObservationDocumentation {
910
AGENT_EXECUTION {
1011
@Override
1112
public Class<? extends ObservationConvention<? extends Context>> getDefaultConvention() {
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.javaaidev.agenticpatterns.core.observation;
2+
3+
import io.micrometer.common.KeyValue;
4+
import io.micrometer.observation.Observation;
5+
import io.micrometer.observation.ObservationFilter;
6+
import java.util.List;
7+
import java.util.Objects;
8+
import org.springframework.ai.chat.messages.AbstractMessage;
9+
import org.springframework.ai.chat.model.Generation;
10+
import org.springframework.ai.chat.observation.ChatModelObservationContext;
11+
import org.springframework.ai.content.Content;
12+
import org.springframework.ai.observation.ObservabilityHelper;
13+
import org.springframework.util.CollectionUtils;
14+
import org.springframework.util.StringUtils;
15+
16+
public class ChatModelCompletionContentObservationFilter implements
17+
ObservationFilter {
18+
19+
@Override
20+
public Observation.Context map(Observation.Context context) {
21+
if (!(context instanceof ChatModelObservationContext chatModelObservationContext)) {
22+
return context;
23+
}
24+
25+
var prompts = processPrompts(chatModelObservationContext);
26+
var completions = processCompletion(chatModelObservationContext);
27+
28+
chatModelObservationContext.addHighCardinalityKeyValue(new KeyValue() {
29+
@Override
30+
public String getKey() {
31+
return "gen_ai.prompt";
32+
}
33+
34+
@Override
35+
public String getValue() {
36+
return ObservabilityHelper.concatenateStrings(prompts);
37+
}
38+
});
39+
40+
chatModelObservationContext.addHighCardinalityKeyValue(new KeyValue() {
41+
@Override
42+
public String getKey() {
43+
return "gen_ai.completion";
44+
}
45+
46+
@Override
47+
public String getValue() {
48+
return ObservabilityHelper.concatenateStrings(completions);
49+
}
50+
});
51+
52+
return chatModelObservationContext;
53+
}
54+
55+
private List<String> processPrompts(
56+
ChatModelObservationContext chatModelObservationContext) {
57+
var instructions = chatModelObservationContext.getRequest()
58+
.getInstructions();
59+
return CollectionUtils.isEmpty(instructions)
60+
? List.of()
61+
: instructions.stream().map(Content::getText).toList();
62+
}
63+
64+
private List<String> processCompletion(
65+
ChatModelObservationContext context) {
66+
if (context.getResponse() == null) {
67+
return List.of();
68+
}
69+
70+
var results = context.getResponse().getResults();
71+
if (CollectionUtils.isEmpty(results)) {
72+
return List.of();
73+
}
74+
75+
return results.stream()
76+
.map(Generation::getOutput)
77+
.filter(Objects::nonNull)
78+
.map(AbstractMessage::getText)
79+
.filter(StringUtils::hasText)
80+
.toList();
81+
}
82+
}

core/src/main/java/com/javaaidev/agenticpatterns/core/observation/DefaultAgentExecutionObservationConvention.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ public String getName() {
1818
}
1919

2020
@Override
21-
public KeyValues getLowCardinalityKeyValues(AgentExecutionObservationContext context) {
21+
public KeyValues getLowCardinalityKeyValues(
22+
AgentExecutionObservationContext context) {
2223
return KeyValues.of(agentName(context));
2324
}
2425

2526
@Override
26-
public KeyValues getHighCardinalityKeyValues(AgentExecutionObservationContext context) {
27+
public KeyValues getHighCardinalityKeyValues(
28+
AgentExecutionObservationContext context) {
2729
return KeyValues.of(
2830
agentExecutionInput(context),
2931
agentExecutionOutput(context)
@@ -36,17 +38,21 @@ private KeyValue agentName(AgentExecutionObservationContext context) {
3638
);
3739
}
3840

39-
private KeyValue agentExecutionInput(AgentExecutionObservationContext context) {
41+
private KeyValue agentExecutionInput(
42+
AgentExecutionObservationContext context) {
4043
return KeyValue.of(
4144
HighCardinalityKeyNames.AGENT_EXECUTION_INPUT,
42-
context.getCarrier() != null ? AgentUtils.toJson(context.getCarrier()) : KeyValue.NONE_VALUE
45+
context.getCarrier() != null ? AgentUtils.toJson(context.getCarrier())
46+
: KeyValue.NONE_VALUE
4347
);
4448
}
4549

46-
private KeyValue agentExecutionOutput(AgentExecutionObservationContext context) {
50+
private KeyValue agentExecutionOutput(
51+
AgentExecutionObservationContext context) {
4752
return KeyValue.of(
4853
HighCardinalityKeyNames.AGENT_EXECUTION_OUTPUT,
49-
context.getResponse() != null ? AgentUtils.toJson(context.getResponse())
54+
context.getResponse() != null ? AgentUtils.toJson(
55+
context.getResponse())
5056
: KeyValue.NONE_VALUE
5157
);
5258
}

core/src/main/java/com/javaaidev/agenticpatterns/core/observation/DefaultWorkflowExecutionObservationConvention.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ public String getName() {
1717
}
1818

1919
@Override
20-
public KeyValues getLowCardinalityKeyValues(WorkflowExecutionObservationContext context) {
20+
public KeyValues getLowCardinalityKeyValues(
21+
WorkflowExecutionObservationContext context) {
2122
return KeyValues.of(workflowName(context));
2223
}
2324

2425
@Override
25-
public KeyValues getHighCardinalityKeyValues(WorkflowExecutionObservationContext context) {
26+
public KeyValues getHighCardinalityKeyValues(
27+
WorkflowExecutionObservationContext context) {
2628
return KeyValues.of(
2729
workflowExecutionInput(context),
2830
workflowExecutionOutput(context)
@@ -35,17 +37,21 @@ private KeyValue workflowName(WorkflowExecutionObservationContext context) {
3537
);
3638
}
3739

38-
private KeyValue workflowExecutionInput(WorkflowExecutionObservationContext context) {
40+
private KeyValue workflowExecutionInput(
41+
WorkflowExecutionObservationContext context) {
3942
return KeyValue.of(
4043
HighCardinalityKeyNames.WORKFLOW_EXECUTION_INPUT,
41-
context.getCarrier() != null ? AgentUtils.toJson(context.getCarrier()) : KeyValue.NONE_VALUE
44+
context.getCarrier() != null ? AgentUtils.toJson(context.getCarrier())
45+
: KeyValue.NONE_VALUE
4246
);
4347
}
4448

45-
private KeyValue workflowExecutionOutput(WorkflowExecutionObservationContext context) {
49+
private KeyValue workflowExecutionOutput(
50+
WorkflowExecutionObservationContext context) {
4651
return KeyValue.of(
4752
HighCardinalityKeyNames.WORKFLOW_EXECUTION_OUTPUT,
48-
context.getResponse() != null ? AgentUtils.toJson(context.getResponse())
53+
context.getResponse() != null ? AgentUtils.toJson(
54+
context.getResponse())
4955
: KeyValue.NONE_VALUE
5056
);
5157
}

0 commit comments

Comments
 (0)