Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completion on available Ollama models support for quarkus.langchain4j.ollama.chat-model.model-id property value #985

Merged
merged 1 commit into from
Sep 13, 2024
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
6 changes: 3 additions & 3 deletions quarkus.ls.ext/com.redhat.quarkus.ls/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format>
<dev.build.timestamp>${maven.build.timestamp}</dev.build.timestamp>
<lsp4j.version>0.14.0</lsp4j.version>
<microprofile.ls.version>0.8.0</microprofile.ls.version>
<microprofile.ls.version>0.12.0-SNAPSHOT</microprofile.ls.version>
<jboss.releases.repo.id>jboss-releases-repository</jboss.releases.repo.id>
<jboss.releases.repo.url>https://repository.jboss.org/nexus/content/repositories/releases/</jboss.releases.repo.url>
<jboss.snapshots.repo.id>jboss-snapshots-repository</jboss.snapshots.repo.id>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.quarkus.extensions.ollama;

/**
* Quarkus Ollama constants.
*/
public class OllamaConstants {

public static final String QUARKUS_LANGCHAIN4J_OLLAMA_CHAT_MODEL_MODEL_ID_KEY = "quarkus.langchain4j.ollama.chat-model.model-id";

public static final String QUARKUS_LANGCHAIN4J_OLLAMA_BASE_URL_KEY = "quarkus.langchain4j.ollama.base-url";
datho7561 marked this conversation as resolved.
Show resolved Hide resolved

public static final String DEFAULT_OLLAMA_BASE_URL = "http://localhost:11434";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.quarkus.extensions.ollama;

import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4mp.services.properties.extensions.IPropertiesFileExtension;
import org.eclipse.lsp4mp.services.properties.extensions.PropertiesFileExtensionRegistry;

/**
* Ollama extension.
*/
public class OllamaExtension implements IPropertiesFileExtension {

private OllamaPropertyValidatorParticipant ollamaPropertyValidatorParticipant = new OllamaPropertyValidatorParticipant();

@Override
public void start(InitializeParams params, PropertiesFileExtensionRegistry registry) {
registry.registerPropertyValidatorParticipant(ollamaPropertyValidatorParticipant);

}

@Override
public void stop(PropertiesFileExtensionRegistry registry) {
registry.unregisterPropertyValidatorParticipant(ollamaPropertyValidatorParticipant);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.quarkus.extensions.ollama;

import static com.redhat.quarkus.extensions.ollama.OllamaConstants.DEFAULT_OLLAMA_BASE_URL;
import static com.redhat.quarkus.extensions.ollama.OllamaConstants.QUARKUS_LANGCHAIN4J_OLLAMA_BASE_URL_KEY;
import static com.redhat.quarkus.extensions.ollama.OllamaConstants.QUARKUS_LANGCHAIN4J_OLLAMA_CHAT_MODEL_MODEL_ID_KEY;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.eclipse.lsp4mp.commons.metadata.ItemHint;
import org.eclipse.lsp4mp.commons.metadata.ItemMetadata;
import org.eclipse.lsp4mp.commons.metadata.ValueHint;
import org.eclipse.lsp4mp.commons.utils.StringUtils;
import org.eclipse.lsp4mp.extensions.ExtendedMicroProfileProjectInfo;
import org.eclipse.lsp4mp.extensions.ItemMetadataProvider;
import org.eclipse.lsp4mp.model.Node;
import org.eclipse.lsp4mp.model.Node.NodeType;
import org.eclipse.lsp4mp.model.PropertiesModel;
import org.eclipse.lsp4mp.model.Property;

import com.redhat.quarkus.extensions.ollama.client.OllamaClient;

/**
* Properties provider to collect available Ollama model values for the property
* 'quarkus.langchain4j.ollama.chat-model.model-id'.
*
* The Ollama models are collected by using Ollama Search Api by using the
* following base url:
*
* <ul>
* <li>defined with 'quarkus.langchain4j.ollama.base-url' property.
* <li>otherwise with 'http://localhost:11434'</li>
* </ul>
*/
public class OllamaItemMetadataProvider implements ItemMetadataProvider {

private ExtendedMicroProfileProjectInfo projectInfo;
private OllamaClient ollamaClient;

public OllamaItemMetadataProvider(ExtendedMicroProfileProjectInfo projectInfo) {
this.projectInfo = projectInfo;
// the Ollama models are collected only if
// 'quarkus.langchain4j.ollama.chat-model.model-id' property exists.
boolean available = this.projectInfo.getProperties().stream()
.anyMatch(p -> QUARKUS_LANGCHAIN4J_OLLAMA_CHAT_MODEL_MODEL_ID_KEY.equals(p.getName()));
if (available) {
ItemHint hint = new ItemHint();
hint.setName(QUARKUS_LANGCHAIN4J_OLLAMA_CHAT_MODEL_MODEL_ID_KEY);
hint.setValues(Collections.emptyList());
projectInfo.getHints().add(hint);
this.ollamaClient = new OllamaClient();
}
}

@Override
public boolean isAvailable() {
return ollamaClient != null;
}

@Override
public void update(PropertiesModel document) {
// Called when application.properties file is opened or updated (when user type
// something in the file).
boolean hasModelProperty = getProperty(document, QUARKUS_LANGCHAIN4J_OLLAMA_CHAT_MODEL_MODEL_ID_KEY) != null;
ItemHint hint = projectInfo.getHint(QUARKUS_LANGCHAIN4J_OLLAMA_CHAT_MODEL_MODEL_ID_KEY);
if (hasModelProperty && hint != null) {
// The application.properties declare the
// 'quarkus.langchain4j.ollama.chat-model.model-id' property,
// we need to collect available Ollama models by using Ollama Search Api
String baseUrl = getSearchBaseUrl(document);
if (ollamaClient.update(baseUrl) || ollamaClient.needToRefreshModels()) {
// The current search url is different with the new, collect Ollama models.
// Update the available models values for the property
// 'quarkus.langchain4j.ollama.chat-model.model-id'
hint.setValues(ollamaClient.getModels() //
.stream() //
.map(m -> {
ValueHint model = new ValueHint();
String modelId = m.getName();
if (modelId.endsWith(":latest")) {
modelId = modelId.substring(0, modelId.length() - 7);
}
model.setValue(modelId);
return model;
}) //
.collect(Collectors.toList()));
}
}
}

@Override
public List<ItemMetadata> getProperties() {
// This provider doesn't contribute to add/remove properties
return null;
}

private static Property getProperty(PropertiesModel document, String propertyName) {
for (Node node : document.getChildren()) {
if (node.getNodeType() == NodeType.PROPERTY) {
Property property = (Property) node;
if (propertyName.equals(property.getPropertyName())) {
return property;
}
}
}
return null;
}

private static String getSearchBaseUrl(PropertiesModel document) {
Property baseUrlProperty = getProperty(document, QUARKUS_LANGCHAIN4J_OLLAMA_BASE_URL_KEY);
if (baseUrlProperty != null) {
String propertyValue = baseUrlProperty.getPropertyValue();
if (StringUtils.hasText(propertyValue)) {
return propertyValue;
}
}
return DEFAULT_OLLAMA_BASE_URL;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.quarkus.extensions.ollama;

import org.eclipse.lsp4mp.extensions.ExtendedMicroProfileProjectInfo;
import org.eclipse.lsp4mp.extensions.ItemMetadataProvider;
import org.eclipse.lsp4mp.extensions.ItemMetadataProviderFactory;

/**
* Factory for creating {@link ItemMetadataProvider} instance to collect
* available Ollama models.
*
* @author Angelo ZERR
*
*/
public class OllamaItemMetadataProviderFactory implements ItemMetadataProviderFactory {

@Override
public ItemMetadataProvider create(ExtendedMicroProfileProjectInfo projectInfo) {
return new OllamaItemMetadataProvider(projectInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.quarkus.extensions.ollama;

import static com.redhat.quarkus.extensions.ollama.OllamaConstants.QUARKUS_LANGCHAIN4J_OLLAMA_CHAT_MODEL_MODEL_ID_KEY;

import org.eclipse.lsp4j.jsonrpc.CancelChecker;
import org.eclipse.lsp4mp.services.properties.ValidationValueContext;
import org.eclipse.lsp4mp.services.properties.extensions.participants.IPropertyValidatorParticipant;

/**
* Custom validation for 'quarkus.langchain4j.ollama.chat-model.model-id'.
*/
public class OllamaPropertyValidatorParticipant implements IPropertyValidatorParticipant {

@Override
public boolean validatePropertyValue(ValidationValueContext context, CancelChecker cancelChecker) {
if (QUARKUS_LANGCHAIN4J_OLLAMA_CHAT_MODEL_MODEL_ID_KEY.equals(context.getPropertyName())) {
// No validation for Ollama model.
return true;
}
return false;
}
}
Loading
Loading