Skip to content

Commit 0358aa3

Browse files
authored
Merge pull request #1840 from Wal8800/anthropic-llm-obs
enhance: allow anthropic recorder to add chat model listener
2 parents def13c4 + 20280df commit 0358aa3

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

model-providers/anthropic/deployment/src/main/java/io/quarkiverse/langchain4j/anthropic/deployment/AnthropicProcessor.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88
import jakarta.enterprise.context.ApplicationScoped;
99

1010
import org.jboss.jandex.AnnotationInstance;
11+
import org.jboss.jandex.ClassType;
12+
import org.jboss.jandex.ParameterizedType;
13+
import org.jboss.jandex.Type;
1114

1215
import io.quarkiverse.langchain4j.ModelName;
1316
import io.quarkiverse.langchain4j.anthropic.runtime.AnthropicRecorder;
17+
import io.quarkiverse.langchain4j.deployment.DotNames;
1418
import io.quarkiverse.langchain4j.deployment.items.ChatModelProviderCandidateBuildItem;
1519
import io.quarkiverse.langchain4j.deployment.items.SelectedChatModelProviderBuildItem;
1620
import io.quarkiverse.langchain4j.runtime.NamedConfigUtil;
@@ -56,7 +60,9 @@ void generateBeans(AnthropicRecorder recorder, List<SelectedChatModelProviderBui
5660
.setRuntimeInit()
5761
.defaultBean()
5862
.scope(ApplicationScoped.class)
59-
.supplier(recorder.chatModel(configName));
63+
.addInjectionPoint(ParameterizedType.create(DotNames.CDI_INSTANCE,
64+
new Type[] { ClassType.create(DotNames.CHAT_MODEL_LISTENER) }, null))
65+
.createWith(recorder.chatModel(configName));
6066

6167
addQualifierIfNecessary(builder, configName);
6268
beanProducer.produce(builder.done());
@@ -66,7 +72,9 @@ void generateBeans(AnthropicRecorder recorder, List<SelectedChatModelProviderBui
6672
.setRuntimeInit()
6773
.defaultBean()
6874
.scope(ApplicationScoped.class)
69-
.supplier(recorder.streamingChatModel(configName));
75+
.addInjectionPoint(ParameterizedType.create(DotNames.CDI_INSTANCE,
76+
new Type[] { ClassType.create(DotNames.CHAT_MODEL_LISTENER) }, null))
77+
.createWith(recorder.streamingChatModel(configName));
7078

7179
addQualifierIfNecessary(streamingBuilder, configName);
7280
beanProducer.produce(streamingBuilder.done());

model-providers/anthropic/runtime/src/main/java/io/quarkiverse/langchain4j/anthropic/runtime/AnthropicRecorder.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import static io.quarkiverse.langchain4j.runtime.OptionalUtil.firstOrDefault;
44

55
import java.time.Duration;
6-
import java.util.function.Supplier;
6+
import java.util.function.Function;
7+
import java.util.stream.Collectors;
8+
9+
import jakarta.enterprise.inject.Instance;
10+
import jakarta.enterprise.util.TypeLiteral;
711

812
import org.jboss.logging.Logger;
913

@@ -13,9 +17,11 @@
1317
import dev.langchain4j.model.chat.DisabledChatModel;
1418
import dev.langchain4j.model.chat.DisabledStreamingChatModel;
1519
import dev.langchain4j.model.chat.StreamingChatModel;
20+
import dev.langchain4j.model.chat.listener.ChatModelListener;
1621
import io.quarkiverse.langchain4j.anthropic.runtime.config.ChatModelConfig;
1722
import io.quarkiverse.langchain4j.anthropic.runtime.config.LangChain4jAnthropicConfig;
1823
import io.quarkiverse.langchain4j.runtime.NamedConfigUtil;
24+
import io.quarkus.arc.SyntheticCreationalContext;
1925
import io.quarkus.runtime.RuntimeValue;
2026
import io.quarkus.runtime.annotations.Recorder;
2127
import io.smallrye.config.ConfigValidationException;
@@ -24,6 +30,9 @@
2430
public class AnthropicRecorder {
2531
private static final Logger LOG = Logger.getLogger(AnthropicRecorder.class);
2632

33+
private static final TypeLiteral<Instance<ChatModelListener>> CHAT_MODEL_LISTENER_TYPE_LITERAL = new TypeLiteral<>() {
34+
};
35+
2736
private static final String DUMMY_KEY = "dummy";
2837

2938
private final RuntimeValue<LangChain4jAnthropicConfig> runtimeConfig;
@@ -32,7 +41,7 @@ public AnthropicRecorder(RuntimeValue<LangChain4jAnthropicConfig> runtimeConfig)
3241
this.runtimeConfig = runtimeConfig;
3342
}
3443

35-
public Supplier<ChatModel> chatModel(String configName) {
44+
public Function<SyntheticCreationalContext<ChatModel>, ChatModel> chatModel(String configName) {
3645
var anthropicConfig = correspondingAnthropicConfig(runtimeConfig.getValue(), configName);
3746

3847
if (anthropicConfig.enableIntegration()) {
@@ -89,23 +98,26 @@ public Supplier<ChatModel> chatModel(String configName) {
8998
builder.sendThinking(thinkingConfig.sendThinking().get());
9099
}
91100

92-
return new Supplier<>() {
101+
return new Function<>() {
93102
@Override
94-
public ChatModel get() {
103+
public ChatModel apply(SyntheticCreationalContext<ChatModel> context) {
104+
builder.listeners(context.getInjectedReference(CHAT_MODEL_LISTENER_TYPE_LITERAL).stream()
105+
.collect(Collectors.toList()));
95106
return builder.build();
96107
}
97108
};
98109
} else {
99-
return new Supplier<>() {
110+
return new Function<>() {
100111
@Override
101-
public ChatModel get() {
112+
public ChatModel apply(SyntheticCreationalContext<ChatModel> context) {
102113
return new DisabledChatModel();
103114
}
104115
};
105116
}
106117
}
107118

108-
public Supplier<StreamingChatModel> streamingChatModel(String configName) {
119+
public Function<SyntheticCreationalContext<StreamingChatModel>, StreamingChatModel> streamingChatModel(
120+
String configName) {
109121
var anthropicConfig = correspondingAnthropicConfig(runtimeConfig.getValue(), configName);
110122

111123
if (anthropicConfig.enableIntegration()) {
@@ -160,16 +172,18 @@ public Supplier<StreamingChatModel> streamingChatModel(String configName) {
160172
builder.sendThinking(thinkingConfig.sendThinking().get());
161173
}
162174

163-
return new Supplier<>() {
175+
return new Function<>() {
164176
@Override
165-
public StreamingChatModel get() {
177+
public StreamingChatModel apply(SyntheticCreationalContext<StreamingChatModel> context) {
178+
builder.listeners(context.getInjectedReference(CHAT_MODEL_LISTENER_TYPE_LITERAL).stream()
179+
.collect(Collectors.toList()));
166180
return builder.build();
167181
}
168182
};
169183
} else {
170-
return new Supplier<>() {
184+
return new Function<>() {
171185
@Override
172-
public StreamingChatModel get() {
186+
public StreamingChatModel apply(SyntheticCreationalContext<StreamingChatModel> context) {
173187
return new DisabledStreamingChatModel();
174188
}
175189
};

0 commit comments

Comments
 (0)