Closed edeandrea closed 3 weeks ago
IIRC Menu Access Control support has been added in quarkus hilla 24.5. Could you try with the beta version?
i think that does it! I bumped quarkus-hilla to 24.5.0-beta1
and vaadin to 24.5.2
and it works!
well, the UI comes up, but other things are broken, but I'm definitely further along!
For the record, in Vaadin 24.4 MenuAccessControl
is used only by Hilla, that is currently not supported by the official extension.
In Vaadin 24.5 the class is used also in Flow, so the related vaadin-quarkus version has been updated to support the change, but it has not been back-ported.
https://github.com/vaadin/quarkus/pull/176#issuecomment-2413079453
@edeandrea thank you for giving this extension a try. Please let us know if you need any help with the porting of Marcus project.
Thank you @mcollovati for the help! This is the first time I've dipped my toes into Vaadin or Hilla, so I'm quite a newbie. Quarkus, LangChain4j, Spring, etc, I'm all good.
I have it (somewhat) working now, but whats not working seems to be the error handling. For example, the original implementation throws some IllegalArgumentException
s under certain circumstances, for instance:
When trying to replicate this with Quarkus I'm seeing the 500
error propagate back to the browser:
and I'm not quite sure what the right "fix" is. Sure I could handle it on the browser side, but it isn't currently handled on the browser side in the Spring version, so I'm curious where the error handling is happening.
Is your branch updated? Maybe I can take a look
It is now. By default it needs an OpenAI key, but if you have Ollama installed you can run ./mvnw clean quarkus:dev -Dquarkus.profile=ollama
2024-10-31 15:18:46,966 ERROR [com.vaa.hil.EndpointInvoker] (executor-thread-3) Endpoint AssistantService method chat execution failure
Exception in FlightService.java:68
66 .filter(b -> b.getCustomer().getLastName().equalsIgnoreCase(lastName))
67 .findFirst()
-> 68 .orElseThrow(() -> new IllegalArgumentException("Booking not found"));
69 }
70
Exception in FlightService.java:68
66 .filter(b -> b.getCustomer().getLastName().equalsIgnoreCase(lastName))
67 .findFirst()
-> 68 .orElseThrow(() -> new IllegalArgumentException("Booking not found"));
69 }
70
Exception in FlightService.java:72
70
71 public BookingDetails getBookingDetails(String bookingNumber, String firstName, String lastName) {
-> 72 var booking = findBooking(bookingNumber, firstName, lastName);
73 return toBookingDetails(booking);
74 }
Exception in LangChain4jTools.java:26
24 """)
25 public BookingDetails getBookingDetails(String bookingNumber, String firstName, String lastName) {
-> 26 return service.getBookingDetails(bookingNumber, firstName, lastName);
27 }
28
Exception in AssistantService.java:19
17
18 public String chat(String chatId, String userMessage) {
-> 19 return langChain4JAssistant.chat(chatId, userMessage);
20 }
21 }
: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at com.vaadin.hilla.EndpointInvoker.invokeVaadinEndpointMethod(EndpointInvoker.java:454)
at com.vaadin.hilla.EndpointInvoker.invoke(EndpointInvoker.java:203)
at com.vaadin.hilla.EndpointController.doServeEndpoint(EndpointController.java:251)
at com.vaadin.hilla.EndpointController.serveEndpoint(EndpointController.java:199)
at com.github.mcollovati.quarkus.hilla.QuarkusEndpointController.serveEndpoint(QuarkusEndpointController.java:79)
at com.github.mcollovati.quarkus.hilla.QuarkusEndpointController$quarkusrestinvoker$serveEndpoint_19ea4aa8e36421f8414cd9ce9157408f2c9d0890.invoke(Unknown Source)
at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:7)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.invokeHandler(AbstractResteasyReactiveContext.java:231)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:48)
at io.quarkus.resteasy.reactive.server.servlet.runtime.ResteasyReactiveServlet.service(ResteasyReactiveServlet.java:31)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63)
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:67)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:247)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:111)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:108)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1.call(UndertowDeploymentRecorder.java:645)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:152)
at io.undertow.server.handlers.CanonicalPathHandler.handleRequest(CanonicalPathHandler.java:49)
at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$1.handleRequest(UndertowDeploymentRecorder.java:126)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:284)
at io.undertow.server.DefaultExchangeHandler.handle(DefaultExchangeHandler.java:18)
at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$5$2.run(UndertowDeploymentRecorder.java:445)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:635)
at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.lang.IllegalArgumentException: Booking not found
at org.vaadin.marcus.service.FlightService.lambda$findBooking$4(FlightService.java:68)
at java.base/java.util.Optional.orElseThrow(Optional.java:403)
at org.vaadin.marcus.service.FlightService.findBooking(FlightService.java:68)
at org.vaadin.marcus.service.FlightService.getBookingDetails(FlightService.java:72)
at org.vaadin.marcus.service.FlightService_ClientProxy.getBookingDetails(Unknown Source)
at org.vaadin.marcus.langchain4j.LangChain4jTools.getBookingDetails(LangChain4jTools.java:26)
at org.vaadin.marcus.langchain4j.LangChain4jTools_ClientProxy.getBookingDetails(Unknown Source)
at org.vaadin.marcus.langchain4j.LangChain4jTools$$QuarkusInvoker$getBookingDetails_c9de469e11ecf91bd37ed7d4fda40fa527ff3a5d.invoke(Unknown Source)
at io.quarkiverse.langchain4j.runtime.tool.QuarkusToolExecutor.execute(QuarkusToolExecutor.java:48)
at io.quarkiverse.langchain4j.runtime.trkusToolExecutorFactory$1$1.apply(QuarkusToolExecutorFactory.java:37)
at io.quarkiverse.langchain4j.runtime.tool.QuarkusToolExecutorFactory$1$1.apply(QuarkusToolExecutorFactory.java:34)
at io.quarkiverse.langchain4j.runtime.tool.ToolSpanWrapper.wrap(ToolSpanWrapper.java:26)
at io.quarkiverse.langchain4j.runtime.tool.QuarkusToolExecutorFactory$1$2.apply(QuarkusToolExecutorFactory.java:46)
at io.quarkiverse.langchain4j.runtime.tool.QuarkusToolExecutorFactory$1$2.apply(QuarkusToolExecutorFactory.java:43)
at io.quarkiverse.langchain4j.runtime.tool.QuarkusToolExecutorFactory$1.execute(QuarkusToolExecutorFactory.java:52)
at io.quarkiverse.langchain4j.runtime.aiservice.AiServiceMethodImplementationSupport.doImplement(AiServiceMethodImplementationSupport.java:284)
at io.quarkiverse.langchain4j.runtime.aiservice.AiServiceMethodImplementationSupport.implement(AiServiceMethodImplementationSupport.java:122)
at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer$1$1.apply(MethodImplementationSupportProducer.java:31)
at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer$1$1.apply(MethodImplementationSupportProducer.java:28)
at io.quarkiverse.langchain4j.runtime.aiservice.SpanWrapper.wrap(SpanWrapper.java:32)
at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer$1$2.apply(MethodImplementationSupportProducer.java:40)
at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer$1$2.apply(MethodImplementationSupportProducer.java:37)
at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer$1.implement(MethodImplementationSupportProducer.java:46)
at org.vaadin.marcus.langchain4j.LangChain4jAssistant$$QuarkusImpl.chat(Unknown Source)
at org.vaadin.marcus.langchain4j.LangChain4jAssistant$$QuarkusImpl_ClientProxy.chat(Unknown Source)
at org.vaadin.marcus.client.AssistantService.chat(AssistantService.java:19)
at org.vaadin.marcus.client.AssistantService_ClientProxy.chat(Unknown Source)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
... 53 more
I think I figured it out. I think because its just throwing IllegalArgumentException
rather than something else that the Quarkus LangChain4j tool invocation isn't handling it properly. When I switch to use some custom exceptions:
public class Exceptions {
public static class BookingCannotBeChangedException extends RuntimeException {
public BookingCannotBeChangedException(String bookingNumber) {
super("Booking %s cannot be changed within 24 hours of the start date".formatted(bookingNumber));
}
}
public static class BookingCannotBeCancelledException extends RuntimeException {
public BookingCannotBeCancelledException(String bookingNumber) {
super("Booking %s cannot be cancelled within 48 hours of the start date".formatted(bookingNumber));
}
}
public static class BookingNotFoundException extends RuntimeException {
public BookingNotFoundException(String bookingNumber) {
super("Booking %s not found".formatted(bookingNumber));
}
}
}
Everything seems to work fine
Great catch!
I got it all to work, and even got some Playwright tests to verify the components all work.
Thanks for the help!
Describe the bug This could totally be user error as I'm not really too familiar with Vaadin nor Hilla.
I'm attempting to create a Quarkus version of https://github.com/marcushellberg/java-ai-playground (see marcushellberg/java-ai-playground#21 - source code of what I'm trying to do is at https://github.com/edeandrea/java-ai-playground/tree/quarkus).
Everything builds, but when I try and load the app in the browser I'm getting
Expected behavior Again, this could be 110% user error here, but I've been banging my head against my desk for a day now and I can't figure out how to move forward.
Context (please complete the following information):