From 0475ecad35e0a6e49cfa850a7e6f48f40d532416 Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Wed, 11 Feb 2026 09:21:03 -0800 Subject: [PATCH 1/2] ChatGPT checkpoint --- api/build.gradle | 13 ++++ .../org/labkey/core/mpc/McpServiceImpl.java | 66 ++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/api/build.gradle b/api/build.gradle index ed797da8c47..e142ec96186 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1081,6 +1081,19 @@ dependencies { ) ) + 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( diff --git a/core/src/org/labkey/core/mpc/McpServiceImpl.java b/core/src/org/labkey/core/mpc/McpServiceImpl.java index 422d0140223..8c8ae97c6ea 100644 --- a/core/src/org/labkey/core/mpc/McpServiceImpl.java +++ b/core/src/org/labkey/core/mpc/McpServiceImpl.java @@ -35,6 +35,12 @@ import org.labkey.api.util.logging.LogHelper; import org.springframework.ai.anthropic.AnthropicChatModel; import org.springframework.ai.anthropic.AnthropicChatOptions; +import org.springframework.ai.openai.OpenAiChatModel; +import org.springframework.ai.openai.OpenAiChatOptions; +import org.springframework.ai.openai.OpenAiEmbeddingModel; +import org.springframework.ai.openai.OpenAiEmbeddingOptions; +import org.springframework.ai.openai.api.OpenAiApi; +import org.springframework.ai.document.MetadataMode; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; import org.springframework.ai.chat.client.advisor.api.Advisor; @@ -108,9 +114,16 @@ public McpServiceImpl() { model = new _ClaudeProvider(); } + if (isNotBlank(System.getenv("OPENAI_API_KEY"))) + { + embedding = new _ChatGptProvider(); + if (null == model) + model = embedding; + } if (isNotBlank(System.getenv("GEMINI_API_KEY"))) { - embedding = new _GeminiProvider(); + if (null == embedding) + embedding = new _GeminiProvider(); if (null == model) model = new _GeminiProvider(); } @@ -603,4 +616,55 @@ public EmbeddingModel createEmbeddingModel() return null; } } + + class _ChatGptProvider implements _ModelProvider + { + @Override + public String getModel() + { + return "gpt-4o"; + } + + @Override + public String getEmbeddingModel() + { + return "text-embedding-3-small"; + } + + @Override + public OpenAiChatOptions getChatOptions() + { + return OpenAiChatOptions.builder() + .model(getModel()) + .toolCallbacks(getToolCallbacks()) + .build(); + } + + @Override + public OpenAiChatModel getChatModel() + { + OpenAiApi openAiApi = OpenAiApi.builder() + .apiKey(System.getenv("OPENAI_API_KEY")) + .build(); + + return OpenAiChatModel.builder() + .openAiApi(openAiApi) + .defaultOptions(getChatOptions()) + .build(); + } + + @Override + public EmbeddingModel createEmbeddingModel() + { + OpenAiApi openAiApi = OpenAiApi.builder() + .apiKey(System.getenv("OPENAI_API_KEY")) + .build(); + + OpenAiEmbeddingOptions embeddingOptions = OpenAiEmbeddingOptions.builder() + .model(getEmbeddingModel()) + .build(); + + return new OpenAiEmbeddingModel(openAiApi, MetadataMode.EMBED, embeddingOptions); + } + } } From bb28e9ade4e69def9ef14bfe5d3c209f266caeac Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Wed, 11 Feb 2026 15:24:22 -0800 Subject: [PATCH 2/2] ChatGpt suppport --- core/src/org/labkey/core/mpc/McpServiceImpl.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/core/src/org/labkey/core/mpc/McpServiceImpl.java b/core/src/org/labkey/core/mpc/McpServiceImpl.java index 8c8ae97c6ea..c1f3f98d7fd 100644 --- a/core/src/org/labkey/core/mpc/McpServiceImpl.java +++ b/core/src/org/labkey/core/mpc/McpServiceImpl.java @@ -116,16 +116,19 @@ public McpServiceImpl() } if (isNotBlank(System.getenv("OPENAI_API_KEY"))) { - embedding = new _ChatGptProvider(); + var openai = new _ChatGptProvider(); + if (null == embedding) + embedding = openai; if (null == model) - model = embedding; + model = openai; } if (isNotBlank(System.getenv("GEMINI_API_KEY"))) { + var gemini = new _GeminiProvider(); if (null == embedding) - embedding = new _GeminiProvider(); + embedding = gemini; if (null == model) - model = new _GeminiProvider(); + model = gemini; } modelProvider = model; embeddingProvider = embedding;