Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ dependencies {
)
)

// Jackson 2
BuildUtils.addExternalDependency(
project,
new ExternalDependency(
Expand Down
110 changes: 106 additions & 4 deletions core/src/org/labkey/core/mpc/McpServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@
import org.springframework.ai.google.genai.text.GoogleGenAiTextEmbeddingModel;
import org.springframework.ai.google.genai.text.GoogleGenAiTextEmbeddingOptions;
import org.springframework.ai.mcp.McpToolUtils;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.definition.ToolDefinition;
import org.springframework.ai.tool.metadata.ToolMetadata;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.filter.Filter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import reactor.core.publisher.Mono;
Expand Down Expand Up @@ -171,7 +177,7 @@ public boolean isReady()
@Override
public void registerTools(@NotNull List<ToolCallback> tools)
{
tools.forEach(tool -> toolMap.put(tool.getToolDefinition().name(), tool));
tools.forEach(tool -> toolMap.put(tool.getToolDefinition().name(), new _LoggingToolCallback(tool)));
}

@Override
Expand Down Expand Up @@ -316,6 +322,65 @@ public void shutdownStarted()
}
}


/** Delegating wrapper that logs vector store similarity searches */
private static class _LoggingVectorStore implements VectorStore
{
private final VectorStore delegate;

_LoggingVectorStore(VectorStore delegate)
{
this.delegate = delegate;
}

@Override
public void add(List<Document> documents)
{
delegate.add(documents);
}

@Override
public void delete(Filter.Expression filterExpression)
{
delegate.delete(filterExpression);
}

@Override
public void delete(List<String> idList)
{
delegate.delete(idList);
}

@Override
public List<Document> similaritySearch(SearchRequest request)
{
LOG.info("Vector store search: query=\"{}\"", request.getQuery());
List<Document> results = delegate.similaritySearch(request);
if (results.isEmpty())
{
LOG.info("Vector store search returned no results");
}
else
{
LOG.info("Vector store search returned {} result(s):", results.size());
for (Document doc : results)
{
String content = doc.getText();
String snippet = content.length() > 200 ? content.substring(0, 200) + "..." : content;
LOG.info(" - [{}] {}", doc.getMetadata(), snippet);
}
}
return results;
}

@Override
public String getName()
{
return delegate.getName();
}
}


@Override
public ChatClient getChat(HttpSession session, String agentName, Supplier<String> systemPromptSupplier, boolean createIfNotExists)
{
Expand Down Expand Up @@ -352,7 +417,7 @@ private ChatClient createSpringChat(HttpSession session, String agentName, Suppl

VectorStore vs = getVectorStore();
if (null != vs)
advisors.add(QuestionAnswerAdvisor.builder(vs).build());
advisors.add(QuestionAnswerAdvisor.builder(new _LoggingVectorStore(vs)).build());

return ChatClient.builder(modelProvider.getChatModel())
.defaultOptions(modelProvider.getChatOptions())
Expand Down Expand Up @@ -558,11 +623,11 @@ class _GeminiProvider implements _ModelProvider
@Override
public String getModel()
{
return "gemini-2.5-flash";
// return "gemini-2.5-flash";
// gemini-2.5-flash
// gemini-2.5-pro
// gemini-3-flash-preview
// gemini-3-pro-preview
return "gemini-3-pro-preview";
}

@Override
Expand Down Expand Up @@ -630,6 +695,43 @@ public EmbeddingModel createEmbeddingModel()
}


private static class _LoggingToolCallback implements ToolCallback
{
private final ToolCallback delegate;

_LoggingToolCallback(ToolCallback delegate)
{
this.delegate = delegate;
}

@Override
public ToolDefinition getToolDefinition()
{
return delegate.getToolDefinition();
}

@Override
public ToolMetadata getToolMetadata()
{
return delegate.getToolMetadata();
}

@Override
public String call(String toolInput)
{
LOG.info("MCP tool invoked: {}", delegate.getToolDefinition().name());
return delegate.call(toolInput);
}

@Override
public String call(String toolInput, ToolContext toolContext)
{
LOG.info("MCP tool invoked: {}", delegate.getToolDefinition().name());
return delegate.call(toolInput, toolContext);
}
}


class _ClaudeProvider implements _ModelProvider
{
@Override
Expand Down