From 10d06344b9893ed3564ba91a2919034bfc24a7c2 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 1 Dec 2023 10:05:58 +0200 Subject: [PATCH 1/3] Add basic OpenTelemetry support --- .../deployment/AiServicesProcessor.java | 38 ++++++-- core/runtime/pom.xml | 10 +++ .../aiservice/AiServiceMethodCreateInfo.java | 24 +++++- .../MethodImplementationSupportProducer.java | 1 - .../runtime/aiservice/SpanWrapper.java | 86 +++++++++++++++++++ samples/email-a-poem/pom.xml | 10 ++- 6 files changed, 161 insertions(+), 8 deletions(-) create mode 100644 core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/SpanWrapper.java diff --git a/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/AiServicesProcessor.java b/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/AiServicesProcessor.java index 11ff6e658..26240583e 100644 --- a/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/AiServicesProcessor.java +++ b/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/AiServicesProcessor.java @@ -53,6 +53,7 @@ import io.quarkiverse.langchain4j.runtime.aiservice.AiServiceMethodImplementationSupport; import io.quarkiverse.langchain4j.runtime.aiservice.DeclarativeAiServiceCreateInfo; import io.quarkiverse.langchain4j.runtime.aiservice.MetricsWrapper; +import io.quarkiverse.langchain4j.runtime.aiservice.SpanWrapper; import io.quarkus.arc.Arc; import io.quarkus.arc.ArcContainer; import io.quarkus.arc.InstanceHandle; @@ -60,6 +61,8 @@ import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.deployment.UnremovableBeanBuildItem; import io.quarkus.builder.item.MultiBuildItem; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; import io.quarkus.deployment.GeneratedClassGizmoAdaptor; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -333,7 +336,8 @@ public void handleAiServices(AiServicesRecorder recorder, BuildProducer reflectiveClassProducer, BuildProducer aiServicesMethodProducer, BuildProducer additionalBeanProducer, - Optional metricsCapability) { + Optional metricsCapability, + Capabilities capabilities) { IndexView index = indexBuildItem.getIndex(); @@ -400,11 +404,15 @@ public void handleAiServices(AiServicesRecorder recorder, var addMicrometerMetrics = metricsCapability.isPresent() && metricsCapability.get().metricsSupported(MetricsFactory.MICROMETER); - if (addMicrometerMetrics) { additionalBeanProducer.produce(AdditionalBeanBuildItem.builder().addBeanClass(MetricsWrapper.class).build()); } + var addOpenTelemetrySpan = capabilities.isPresent(Capability.OPENTELEMETRY_TRACER); + if (addOpenTelemetrySpan) { + additionalBeanProducer.produce(AdditionalBeanBuildItem.builder().addBeanClass(SpanWrapper.class).build()); + } + Map perClassMetadata = new HashMap<>(); if (!ifacesForCreate.isEmpty()) { ClassOutput classOutput = new GeneratedClassGizmoAdaptor(generatedClassProducer, true); @@ -439,7 +447,8 @@ public void handleAiServices(AiServicesRecorder recorder, // MethodImplementationSupport#implement String methodId = createMethodId(methodInfo); - perMethodMetadata.put(methodId, gatherMethodMetadata(methodInfo, addMicrometerMetrics)); + perMethodMetadata.put(methodId, + gatherMethodMetadata(methodInfo, addMicrometerMetrics, addOpenTelemetrySpan)); MethodCreator constructor = classCreator.getMethodCreator(MethodDescriptor.INIT, "V", AiServiceContext.class); constructor.invokeSpecialMethod(OBJECT_CONSTRUCTOR, constructor.getThis()); @@ -521,7 +530,8 @@ private static void addCreatedAware(IndexView index, Set detectedForCrea } } - private AiServiceMethodCreateInfo gatherMethodMetadata(MethodInfo method, boolean addMicrometerMetrics) { + private AiServiceMethodCreateInfo gatherMethodMetadata(MethodInfo method, boolean addMicrometerMetrics, + boolean addOpenTelemetrySpans) { if (method.returnType().kind() == Type.Kind.VOID) { throw illegalConfiguration("Return type of method '%s' cannot be void", method); } @@ -537,9 +547,10 @@ private AiServiceMethodCreateInfo gatherMethodMetadata(MethodInfo method, boolea returnType); Optional memoryIdParamPosition = gatherMemoryIdParamName(method); Optional metricsInfo = gatherMetricsInfo(method, addMicrometerMetrics); + Optional spanInfo = gatherSpanInfo(method, addOpenTelemetrySpans); return new AiServiceMethodCreateInfo(systemMessageInfo, userMessageInfo, memoryIdParamPosition, requiresModeration, - returnType, metricsInfo); + returnType, metricsInfo, spanInfo); } private List gatherTemplateParamInfo(List params) { @@ -712,10 +723,27 @@ private Optional gatherMetricsInfo(Method return Optional.of(builder.build()); } + private Optional gatherSpanInfo(MethodInfo method, + boolean addOpenTelemetrySpans) { + if (!addOpenTelemetrySpans) { + return Optional.empty(); + } + + String name = defaultAiServiceSpanName(method); + + // TODO: add more + + return Optional.of(new AiServiceMethodCreateInfo.SpanInfo(name)); + } + private String defaultAiServiceMetricName(MethodInfo method) { return "langchain4j.aiservices." + method.declaringClass().name().withoutPackagePrefix() + "." + method.name(); } + private String defaultAiServiceSpanName(MethodInfo method) { + return "langchain4j.aiservices." + method.declaringClass().name().withoutPackagePrefix() + "." + method.name(); + } + private static class TemplateParameterInfo { private final int position; private final String name; diff --git a/core/runtime/pom.xml b/core/runtime/pom.xml index a0f99cb51..208eacd4a 100644 --- a/core/runtime/pom.xml +++ b/core/runtime/pom.xml @@ -26,6 +26,16 @@ micrometer-core true + + io.micrometer + micrometer-core + true + + + io.opentelemetry.instrumentation + opentelemetry-instrumentation-api + true + dev.langchain4j diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/AiServiceMethodCreateInfo.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/AiServiceMethodCreateInfo.java index 5125d5372..01c73414a 100644 --- a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/AiServiceMethodCreateInfo.java +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/AiServiceMethodCreateInfo.java @@ -17,16 +17,21 @@ public class AiServiceMethodCreateInfo { private final Optional metricsInfo; + private final Optional spanInfo; + @RecordableConstructor public AiServiceMethodCreateInfo(Optional systemMessageInfo, UserMessageInfo userMessageInfo, Optional memoryIdParamPosition, - boolean requiresModeration, Class returnType, Optional metricsInfo) { + boolean requiresModeration, Class returnType, + Optional metricsInfo, + Optional spanInfo) { this.systemMessageInfo = systemMessageInfo; this.userMessageInfo = userMessageInfo; this.memoryIdParamPosition = memoryIdParamPosition; this.requiresModeration = requiresModeration; this.returnType = returnType; this.metricsInfo = metricsInfo; + this.spanInfo = spanInfo; } public Optional getSystemMessageInfo() { @@ -53,6 +58,10 @@ public Optional getMetricsInfo() { return metricsInfo; } + public Optional getSpanInfo() { + return spanInfo; + } + public static class UserMessageInfo { private final Optional template; private final Optional paramPosition; @@ -205,4 +214,17 @@ public AiServiceMethodCreateInfo.MetricsInfo build() { } } } + + public static class SpanInfo { + private final String name; + + @RecordableConstructor + public SpanInfo(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } } diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/MethodImplementationSupportProducer.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/MethodImplementationSupportProducer.java index c2e9d09f8..89d1a918e 100644 --- a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/MethodImplementationSupportProducer.java +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/MethodImplementationSupportProducer.java @@ -34,7 +34,6 @@ public Object apply(Input input) { for (Wrapper wrapper : wrappers) { Function currentFun = funRef.get(); - wrapper.wrap(input, currentFun); Function newFunction = new Function() { @Override public Object apply(Input input) { diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/SpanWrapper.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/SpanWrapper.java new file mode 100644 index 000000000..2bec12a62 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/SpanWrapper.java @@ -0,0 +1,86 @@ +package io.quarkiverse.langchain4j.runtime.aiservice; + +import java.util.Optional; +import java.util.function.Function; + +import jakarta.inject.Inject; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder; +import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; + +public class SpanWrapper implements AiServiceMethodImplementationSupport.Wrapper { + + private static final String INSTRUMENTATION_NAME = "io.quarkus.opentelemetry"; + + private final Instrumenter instrumenter; + + @Inject + public SpanWrapper(OpenTelemetry openTelemetry) { + InstrumenterBuilder builder = Instrumenter.builder( + openTelemetry, + INSTRUMENTATION_NAME, + InputSpanNameExtractor.INSTANCE); + + // TODO: there is probably more information here we need to set + this.instrumenter = builder + .buildInstrumenter(new SpanKindExtractor() { + @Override + public SpanKind extract(AiServiceMethodImplementationSupport.Input input) { + return SpanKind.INTERNAL; + } + }); + } + + @Override + public Object wrap(AiServiceMethodImplementationSupport.Input input, + Function fun) { + + Context parentContext = Context.current(); + Context spanContext = null; + Scope scope = null; + boolean shouldStart = instrumenter.shouldStart(parentContext, input); + if (shouldStart) { + spanContext = instrumenter.start(parentContext, input); + scope = spanContext.makeCurrent(); + } + + try { + Object result = fun.apply(input); + + if (shouldStart) { + instrumenter.end(spanContext, input, null, null); + } + + return result; + } catch (Throwable t) { + if (shouldStart) { + instrumenter.end(spanContext, input, null, t); + } + throw t; + } finally { + if (scope != null) { + scope.close(); + } + } + } + + private static class InputSpanNameExtractor implements SpanNameExtractor { + + private static final InputSpanNameExtractor INSTANCE = new InputSpanNameExtractor(); + + @Override + public String extract(AiServiceMethodImplementationSupport.Input input) { + Optional spanInfoOpt = input.createInfo.getSpanInfo(); + if (spanInfoOpt.isPresent()) { + return spanInfoOpt.get().getName(); + } + return null; + } + } +} diff --git a/samples/email-a-poem/pom.xml b/samples/email-a-poem/pom.xml index c6c1e0ae3..b208f9c84 100644 --- a/samples/email-a-poem/pom.xml +++ b/samples/email-a-poem/pom.xml @@ -26,6 +26,14 @@ io.quarkus quarkus-mailer + + io.quarkus + quarkus-opentelemetry + + + io.quarkus + quarkus-micrometer-registry-prometheus + @@ -95,4 +103,4 @@ - \ No newline at end of file + From 4b4f212c788cb0b894e96611d42aac187dfce01a Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 1 Dec 2023 12:22:03 +0200 Subject: [PATCH 2/3] Add OpenTelemetry support to tool execution --- .../langchain4j/deployment/ToolProcessor.java | 12 +++ .../langchain4j/test/ToolExecutorTest.java | 5 +- .../langchain4j/QuarkusAiServicesFactory.java | 13 ++- .../MethodImplementationSupportProducer.java | 4 +- .../runtime/aiservice/SpanWrapper.java | 2 +- .../runtime/tool/QuarkusToolExecutor.java | 41 ++++++---- .../tool/QuarkusToolExecutorFactory.java | 56 +++++++++++++ .../runtime/tool/ToolSpanWrapper.java | 81 +++++++++++++++++++ 8 files changed, 189 insertions(+), 25 deletions(-) create mode 100644 core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/QuarkusToolExecutorFactory.java create mode 100644 core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/ToolSpanWrapper.java diff --git a/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/ToolProcessor.java b/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/ToolProcessor.java index 32c570e9c..541ed3a12 100644 --- a/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/ToolProcessor.java +++ b/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/ToolProcessor.java @@ -43,8 +43,12 @@ import io.quarkiverse.langchain4j.runtime.tool.ToolInvoker; import io.quarkiverse.langchain4j.runtime.tool.ToolMethodCreateInfo; import io.quarkiverse.langchain4j.runtime.tool.ToolParametersObjectSubstitution; +import io.quarkiverse.langchain4j.runtime.tool.ToolSpanWrapper; import io.quarkiverse.langchain4j.runtime.tool.ToolSpecificationObjectSubstitution; +import io.quarkus.arc.deployment.AdditionalBeanBuildItem; import io.quarkus.arc.deployment.ValidationPhaseBuildItem; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; import io.quarkus.deployment.GeneratedClassGizmoAdaptor; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -75,6 +79,14 @@ public class ToolProcessor { public static final MethodDescriptor MAP_PUT = MethodDescriptor.ofMethod(Map.class, "put", Object.class, Object.class, Object.class); + @BuildStep + public void telemetry(Capabilities capabilities, BuildProducer additionalBeanProducer) { + var addOpenTelemetrySpan = capabilities.isPresent(Capability.OPENTELEMETRY_TRACER); + if (addOpenTelemetrySpan) { + additionalBeanProducer.produce(AdditionalBeanBuildItem.builder().addBeanClass(ToolSpanWrapper.class).build()); + } + } + @BuildStep @Record(ExecutionTime.STATIC_INIT) public void handleTools(CombinedIndexBuildItem indexBuildItem, diff --git a/core/deployment/src/test/java/io/quarkiverse/langchain4j/test/ToolExecutorTest.java b/core/deployment/src/test/java/io/quarkiverse/langchain4j/test/ToolExecutorTest.java index 717b0aeff..3d2593445 100644 --- a/core/deployment/src/test/java/io/quarkiverse/langchain4j/test/ToolExecutorTest.java +++ b/core/deployment/src/test/java/io/quarkiverse/langchain4j/test/ToolExecutorTest.java @@ -271,8 +271,9 @@ private ToolExecutor getToolExecutor(String methodName) { ToolSpecification toolSpecification = methodCreateInfo.getToolSpecification(); if (methodName.equals( toolSpecification.name())) { // this only works because TestTool does not contain overloaded methods - toolExecutor = new QuarkusToolExecutor(testTool, invokerClassName, methodCreateInfo.getMethodName(), - methodCreateInfo.getArgumentMapperClassName()); + toolExecutor = new QuarkusToolExecutor( + new QuarkusToolExecutor.Context(testTool, invokerClassName, methodCreateInfo.getMethodName(), + methodCreateInfo.getArgumentMapperClassName())); break; } } diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/QuarkusAiServicesFactory.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/QuarkusAiServicesFactory.java index 490ee0f61..96aca42a1 100644 --- a/core/runtime/src/main/java/io/quarkiverse/langchain4j/QuarkusAiServicesFactory.java +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/QuarkusAiServicesFactory.java @@ -18,7 +18,9 @@ import io.quarkiverse.langchain4j.runtime.aiservice.AiServiceClassCreateInfo; import io.quarkiverse.langchain4j.runtime.aiservice.AiServiceMethodCreateInfo; import io.quarkiverse.langchain4j.runtime.tool.QuarkusToolExecutor; +import io.quarkiverse.langchain4j.runtime.tool.QuarkusToolExecutorFactory; import io.quarkiverse.langchain4j.runtime.tool.ToolMethodCreateInfo; +import io.quarkus.arc.Arc; import io.quarkus.arc.ClientProxy; public class QuarkusAiServicesFactory implements AiServicesFactory { @@ -33,8 +35,12 @@ public static class InstanceHolder { } public static class QuarkusAiServices extends AiServices { + + private final QuarkusToolExecutorFactory toolExecutorFactory; + public QuarkusAiServices(AiServiceContext context) { super(context); + toolExecutorFactory = Arc.container().instance(QuarkusToolExecutorFactory.class).get(); } @Override @@ -54,9 +60,10 @@ public AiServices tools(List objectsWithTools) { String invokerClassName = methodCreateInfo.getInvokerClassName(); ToolSpecification toolSpecification = methodCreateInfo.getToolSpecification(); context.toolSpecifications.add(toolSpecification); - context.toolExecutors.put(toolSpecification.name(), - new QuarkusToolExecutor(objectWithTool, invokerClassName, methodCreateInfo.getMethodName(), - methodCreateInfo.getArgumentMapperClassName())); + QuarkusToolExecutor.Context executorContext = new QuarkusToolExecutor.Context(objectWithTool, + invokerClassName, methodCreateInfo.getMethodName(), + methodCreateInfo.getArgumentMapperClassName()); + context.toolExecutors.put(toolSpecification.name(), toolExecutorFactory.create(executorContext)); } } diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/MethodImplementationSupportProducer.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/MethodImplementationSupportProducer.java index 89d1a918e..02703b21c 100644 --- a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/MethodImplementationSupportProducer.java +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/MethodImplementationSupportProducer.java @@ -33,8 +33,8 @@ public Object apply(Input input) { }); for (Wrapper wrapper : wrappers) { - Function currentFun = funRef.get(); - Function newFunction = new Function() { + var currentFun = funRef.get(); + var newFunction = new Function() { @Override public Object apply(Input input) { return wrapper.wrap(input, currentFun); diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/SpanWrapper.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/SpanWrapper.java index 2bec12a62..a37025c5b 100644 --- a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/SpanWrapper.java +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/SpanWrapper.java @@ -29,7 +29,7 @@ public SpanWrapper(OpenTelemetry openTelemetry) { // TODO: there is probably more information here we need to set this.instrumenter = builder - .buildInstrumenter(new SpanKindExtractor() { + .buildInstrumenter(new SpanKindExtractor<>() { @Override public SpanKind extract(AiServiceMethodImplementationSupport.Input input) { return SpanKind.INTERNAL; diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/QuarkusToolExecutor.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/QuarkusToolExecutor.java index 5a9b63582..65b5dd5c8 100644 --- a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/QuarkusToolExecutor.java +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/QuarkusToolExecutor.java @@ -3,6 +3,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.Map; +import java.util.function.BiFunction; import org.jboss.logging.Logger; @@ -18,17 +19,19 @@ public class QuarkusToolExecutor implements ToolExecutor { private static final Logger log = Logger.getLogger(QuarkusToolExecutor.class); - private final Object tool; - private final String toolInvokerName; - private final String methodName; + private final Context context; - private final String argumentMapperClassName; + public record Context(Object tool, String toolInvokerName, String methodName, String argumentMapperClassName) { + } + + public interface Wrapper { - public QuarkusToolExecutor(Object tool, String toolInvokerName, String methodName, String argumentMapperClassName) { - this.tool = tool; - this.toolInvokerName = toolInvokerName; - this.methodName = methodName; - this.argumentMapperClassName = argumentMapperClassName; + String wrap(ToolExecutionRequest toolExecutionRequest, Object memoryId, + BiFunction fun); + } + + public QuarkusToolExecutor(Context context) { + this.context = context; } public String execute(ToolExecutionRequest toolExecutionRequest, Object memoryId) { @@ -39,9 +42,9 @@ public String execute(ToolExecutionRequest toolExecutionRequest, Object memoryId Object[] params = prepareArguments(toolExecutionRequest, invokerInstance.methodMetadata()); try { if (log.isDebugEnabled()) { - log.debugv("Attempting to invoke tool '{0}' with parameters '{1}'", tool, Arrays.toString(params)); + log.debugv("Attempting to invoke tool '{0}' with parameters '{1}'", context.tool, Arrays.toString(params)); } - Object invocationResult = invokerInstance.invoke(tool, + Object invocationResult = invokerInstance.invoke(context.tool, params); String result = handleResult(invokerInstance, invocationResult); log.debugv("Tool execution result: '{0}'", result); @@ -50,7 +53,7 @@ public String execute(ToolExecutionRequest toolExecutionRequest, Object memoryId if (e instanceof IllegalArgumentException) { throw (IllegalArgumentException) e; } - log.error("Error while executing tool '" + tool.getClass() + "'", e); + log.error("Error while executing tool '" + context.tool.getClass() + "'", e); return e.getMessage(); } } @@ -66,12 +69,14 @@ private static String handleResult(ToolInvoker invokerInstance, Object invocatio private ToolInvoker createInvokerInstance() { ToolInvoker invokerInstance; try { - invokerInstance = (ToolInvoker) Class.forName(toolInvokerName, true, Thread.currentThread() + invokerInstance = (ToolInvoker) Class.forName(context.toolInvokerName, true, Thread.currentThread() .getContextClassLoader()).getConstructor().newInstance(); } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { throw new IllegalStateException( - "Unable to create instance of '" + toolInvokerName + "'. Please report this issue to the maintainers", e); + "Unable to create instance of '" + context.toolInvokerName + + "'. Please report this issue to the maintainers", + e); } return invokerInstance; } @@ -113,18 +118,20 @@ private Map convertJsonToArguments(String argumentsJsonStr) thro @SuppressWarnings("unchecked") private Class loadMapperClass() { try { - return (Class) Class.forName(argumentMapperClassName, true, Thread.currentThread() + return (Class) Class.forName(context.argumentMapperClassName, true, Thread.currentThread() .getContextClassLoader()); } catch (ClassNotFoundException e) { throw new IllegalStateException( - "Unable to load argument mapper of '" + toolInvokerName + "'. Please report this issue to the maintainers", + "Unable to load argument mapper of '" + context.toolInvokerName + + "'. Please report this issue to the maintainers", e); } } private void invalidMethodParams(String argumentsJsonStr) { throw new IllegalArgumentException("params '" + argumentsJsonStr - + "' from request do not map onto the parameters needed by '" + tool.getClass().getName() + "#" + methodName + + "' from request do not map onto the parameters needed by '" + context.tool.getClass().getName() + "#" + + context.methodName + "'"); } diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/QuarkusToolExecutorFactory.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/QuarkusToolExecutorFactory.java new file mode 100644 index 000000000..e465d5ee3 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/QuarkusToolExecutorFactory.java @@ -0,0 +1,56 @@ +package io.quarkiverse.langchain4j.runtime.tool; + +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiFunction; + +import jakarta.inject.Singleton; + +import dev.langchain4j.agent.tool.ToolExecutionRequest; +import io.quarkus.arc.All; +import io.quarkus.arc.Unremovable; + +@Singleton +@Unremovable +public class QuarkusToolExecutorFactory { + + private final List wrappers; + + public QuarkusToolExecutorFactory(@All List wrappers) { + this.wrappers = wrappers; + } + + public QuarkusToolExecutor create(QuarkusToolExecutor.Context context) { + if (wrappers.isEmpty()) { + return new QuarkusToolExecutor(context); + } + + return new QuarkusToolExecutor(context) { + final QuarkusToolExecutor originalTool = new QuarkusToolExecutor(context); + + @Override + public String execute(ToolExecutionRequest toolExecutionRequest, Object memoryId) { + AtomicReference> funRef = new AtomicReference<>( + new BiFunction<>() { + @Override + public String apply(ToolExecutionRequest toolExecutionRequest, Object o) { + return originalTool.execute(toolExecutionRequest, memoryId); + } + }); + + for (QuarkusToolExecutor.Wrapper wrapper : wrappers) { + var currentFun = funRef.get(); + BiFunction newFunction = new BiFunction<>() { + @Override + public String apply(ToolExecutionRequest toolExecutionRequest, Object memoryId) { + return wrapper.wrap(toolExecutionRequest, memoryId, currentFun); + } + }; + funRef.set(newFunction); + } + + return funRef.get().apply(toolExecutionRequest, memoryId); + } + }; + } +} diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/ToolSpanWrapper.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/ToolSpanWrapper.java new file mode 100644 index 000000000..d135683ef --- /dev/null +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/tool/ToolSpanWrapper.java @@ -0,0 +1,81 @@ +package io.quarkiverse.langchain4j.runtime.tool; + +import java.util.function.BiFunction; + +import jakarta.inject.Inject; + +import dev.langchain4j.agent.tool.ToolExecutionRequest; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder; +import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; + +public class ToolSpanWrapper implements QuarkusToolExecutor.Wrapper { + + private static final String INSTRUMENTATION_NAME = "io.quarkus.opentelemetry"; + + private final Instrumenter instrumenter; + + @Inject + public ToolSpanWrapper(OpenTelemetry openTelemetry) { + InstrumenterBuilder builder = Instrumenter.builder( + openTelemetry, + INSTRUMENTATION_NAME, + InputSpanNameExtractor.INSTANCE); + + // TODO: there is probably more information here we need to set + this.instrumenter = builder + .buildInstrumenter(new SpanKindExtractor<>() { + @Override + public SpanKind extract(ToolExecutionRequest toolExecutionRequest) { + return SpanKind.INTERNAL; + } + }); + } + + @Override + public String wrap(ToolExecutionRequest toolExecutionRequest, Object memoryId, + BiFunction fun) { + Context parentContext = Context.current(); + Context spanContext = null; + Scope scope = null; + boolean shouldStart = instrumenter.shouldStart(parentContext, toolExecutionRequest); + if (shouldStart) { + spanContext = instrumenter.start(parentContext, toolExecutionRequest); + scope = spanContext.makeCurrent(); + } + + try { + String result = fun.apply(toolExecutionRequest, memoryId); + + if (shouldStart) { + instrumenter.end(spanContext, toolExecutionRequest, null, null); + } + + return result; + } catch (Throwable t) { + if (shouldStart) { + instrumenter.end(spanContext, toolExecutionRequest, null, t); + } + throw t; + } finally { + if (scope != null) { + scope.close(); + } + } + } + + private static class InputSpanNameExtractor implements SpanNameExtractor { + + private static final InputSpanNameExtractor INSTANCE = new InputSpanNameExtractor(); + + @Override + public String extract(ToolExecutionRequest toolExecutionRequest) { + return "langchain4j.tools." + toolExecutionRequest.name(); + } + } +} From 61ab6df6e9ccd785b9b2527a27a723a6bac723e9 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 1 Dec 2023 14:50:14 +0200 Subject: [PATCH 3/3] Add documentation about observability --- docs/modules/ROOT/assets/images/trace.png | Bin 0 -> 75134 bytes docs/modules/ROOT/pages/ai-services.adoc | 106 ++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 docs/modules/ROOT/assets/images/trace.png diff --git a/docs/modules/ROOT/assets/images/trace.png b/docs/modules/ROOT/assets/images/trace.png new file mode 100644 index 0000000000000000000000000000000000000000..550111fb1ae2fabd6bfb76ecb4c2e7934b73bad7 GIT binary patch literal 75134 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

rC1c4h1 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