diff --git a/api/build.gradle b/api/build.gradle index 4631e046e6e..2be9f4fd3da 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1077,45 +1077,6 @@ dependencies { ) ) - BuildUtils.addExternalDependency( - project, - new ExternalDependency( - "org.springframework.ai:spring-ai-starter-model-google-genai:${springAiVersion}", - "spring-ai-starter-google-genai", - "spring-ai", - "https://github.com/spring-projects/spring-ai", - ExternalDependency.APACHE_2_LICENSE_NAME, - ExternalDependency.APACHE_2_LICENSE_URL, - "LLM Chat Client integration for Gemini" - ) - ) - - BuildUtils.addExternalDependency( - project, - new ExternalDependency( - "org.springframework.ai:spring-ai-anthropic:${springAiVersion}", - "spring-ai-anthropic", - "spring-ai", - "https://github.com/spring-projects/spring-ai", - ExternalDependency.APACHE_2_LICENSE_NAME, - ExternalDependency.APACHE_2_LICENSE_URL, - "LLM Chat Client integration for Claude" - ) - ) - - BuildUtils.addExternalDependency( - project, - new ExternalDependency( - "org.springframework.ai:spring-ai-openai:${springAiVersion}", - "spring-ai-openai", - "spring-ai", - "https://github.com/spring-projects/spring-ai", - ExternalDependency.APACHE_2_LICENSE_NAME, - ExternalDependency.APACHE_2_LICENSE_URL, - "LLM Chat Client integration for ChatGPT" - ) - ) - BuildUtils.addExternalDependency( project, new ExternalDependency( @@ -1142,19 +1103,6 @@ dependencies { ) ) - BuildUtils.addExternalDependency( - project, - new ExternalDependency( - "org.springframework.ai:spring-ai-starter-model-google-genai-embedding:${springAiVersion}", - "spring-ai-starter-model-google-genai-embedding", - "spring-ai", - "https://github.com/spring-projects/spring-ai", - ExternalDependency.APACHE_2_LICENSE_NAME, - ExternalDependency.APACHE_2_LICENSE_URL, - "Vector store integration" - ) - ) - jspImplementation files(project.tasks.jar) jspImplementation apache, jackson, spring } diff --git a/api/src/org/labkey/api/mcp/AbstractAgentAction.java b/api/src/org/labkey/api/mcp/AbstractAgentAction.java index a8bb158aab1..102982a6963 100644 --- a/api/src/org/labkey/api/mcp/AbstractAgentAction.java +++ b/api/src/org/labkey/api/mcp/AbstractAgentAction.java @@ -15,8 +15,6 @@ */ package org.labkey.api.mcp; -import com.google.genai.errors.ClientException; -import com.google.genai.errors.ServerException; import jakarta.servlet.http.HttpSession; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; @@ -167,17 +165,13 @@ else if (isNotBlank(response.text())) } return ret; } - catch (ServerException x) + catch (ChatException x) { return new JSONObject(Map.of( "error", x.getMessage(), "text", "ERROR: " + x.getMessage(), "success", Boolean.FALSE)); } - catch (ClientException ex) - { - return errorResponse(ex); - } } protected @NotNull JSONObject errorResponse(Exception ex) diff --git a/api/src/org/labkey/api/mcp/ChatException.java b/api/src/org/labkey/api/mcp/ChatException.java new file mode 100644 index 00000000000..f304ff1a8ed --- /dev/null +++ b/api/src/org/labkey/api/mcp/ChatException.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2026 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.api.mcp; + +// Provider-agnostic wrapper for exceptions thrown by the active _ModelProvider's ChatModel, so callers can handle +// chat failures without depending on any specific vendor SDK (Anthropic/OpenAI/Gemini/Bedrock/Ollama, etc.). +public class ChatException extends RuntimeException +{ + public ChatException(String message, Throwable cause) + { + super(message, cause); + } +} \ No newline at end of file diff --git a/query/src/org/labkey/query/controllers/ExpressionAssistantAgentAction.java b/query/src/org/labkey/query/controllers/ExpressionAssistantAgentAction.java index 297fbb80825..c10cebb0c3d 100644 --- a/query/src/org/labkey/query/controllers/ExpressionAssistantAgentAction.java +++ b/query/src/org/labkey/query/controllers/ExpressionAssistantAgentAction.java @@ -15,8 +15,6 @@ */ package org.labkey.query.controllers; -import com.google.genai.errors.ClientException; -import com.google.genai.errors.ServerException; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -26,6 +24,7 @@ import org.junit.Test; import org.labkey.api.markdown.MarkdownService; import org.labkey.api.mcp.AbstractAgentAction; +import org.labkey.api.mcp.ChatException; import org.labkey.api.mcp.McpContext; import org.labkey.api.mcp.McpService; import org.labkey.api.query.RuntimeValidationException; @@ -96,7 +95,7 @@ public Object execute(ParseForm form, BindException errors) throws Exception LOG.info("Expression assistant prompt: {}", prompt); responses = McpService.get().sendMessageEx(chatSession, composedPrompt); } - catch (ServerException x) + catch (ChatException x) { return new JSONObject(Map.of( "error", x.getMessage(), @@ -110,7 +109,7 @@ public Object execute(ParseForm form, BindException errors) throws Exception "conversationId", getConversationId(), "segments", segments)); } - catch (ClientException x) + catch (ChatException x) { return errorResponse(x); } diff --git a/query/src/org/labkey/query/controllers/QueryController.java b/query/src/org/labkey/query/controllers/QueryController.java index 64743343c08..571cbdbdc7f 100644 --- a/query/src/org/labkey/query/controllers/QueryController.java +++ b/query/src/org/labkey/query/controllers/QueryController.java @@ -19,8 +19,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.genai.errors.ClientException; -import com.google.genai.errors.ServerException; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -153,6 +151,7 @@ import org.labkey.api.files.FileContentService; import org.labkey.api.gwt.client.AuditBehaviorType; import org.labkey.api.mcp.AbstractAgentAction; +import org.labkey.api.mcp.ChatException; import org.labkey.api.mcp.McpContext; import org.labkey.api.mcp.McpService; import org.labkey.api.mcp.PromptForm; @@ -8684,7 +8683,7 @@ public Object execute(SqlPromptForm form, BindException errors) throws Exception responses = McpService.get().sendMessageEx(chatSession, prompt); sqlResponse = extractSql(responses); } - catch (ServerException x) + catch (ChatException x) { return new JSONObject(Map.of( "error", x.getMessage(), @@ -8733,7 +8732,7 @@ public Object execute(SqlPromptForm form, BindException errors) throws Exception ret.put("html", sqlResponse.html()); return ret; } - catch (ClientException ex) + catch (ChatException ex) { return errorResponse(ex); }