Skip to content

Commit

Permalink
feat: Add automatic template handling for Ollama models (#43)
Browse files Browse the repository at this point in the history
* feat: Add automatic template handling for Ollama models

- Add OllamaAutoFim
- Use native Ollama API format when possible
- Remove need for manual template selection for most Ollama models
- Default to model-specific format from Ollama modelfile
- Fallback to manual template selection if needed

This change simplifies configuration by automatically using
the correct template format for each Ollama model.
  • Loading branch information
Palm1r authored Nov 23, 2024
1 parent 8375d85 commit 80fe388
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 8 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ add_qtc_plugin(QodeAssist
templates/CodeLlamaChat.hpp
templates/Qwen.hpp
templates/StarCoderChat.hpp
templates/Ollama.hpp
providers/OllamaProvider.hpp providers/OllamaProvider.cpp
providers/LMStudioProvider.hpp providers/LMStudioProvider.cpp
providers/OpenAICompatProvider.hpp providers/OpenAICompatProvider.cpp
Expand All @@ -62,5 +63,3 @@ add_qtc_plugin(QodeAssist
chat/NavigationPanel.hpp chat/NavigationPanel.cpp
ConfigurationManager.hpp ConfigurationManager.cpp
)

target_link_libraries(QodeAssist PRIVATE )
10 changes: 10 additions & 0 deletions ChatView/ClientInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,20 @@ void ClientInterface::sendMessage(const QString &message, bool includeCurrentFil
auto providerName = Settings::generalSettings().caProvider();
auto provider = LLMCore::ProvidersManager::instance().getProviderByName(providerName);

if (!provider) {
LOG_MESSAGE(QString("No provider found with name: %1").arg(providerName));
return;
}

auto templateName = Settings::generalSettings().caTemplate();
auto promptTemplate = LLMCore::PromptTemplateManager::instance().getChatTemplateByName(
templateName);

if (!promptTemplate) {
LOG_MESSAGE(QString("No template found with name: %1").arg(templateName));
return;
}

LLMCore::ContextData context;
context.prefix = message;
context.suffix = "";
Expand Down
22 changes: 17 additions & 5 deletions LLMClientInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,30 +152,42 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request)
auto providerName = Settings::generalSettings().ccProvider();
auto provider = LLMCore::ProvidersManager::instance().getProviderByName(providerName);

if (!provider) {
LOG_MESSAGE(QString("No provider found with name: %1").arg(providerName));
return;
}

auto templateName = Settings::generalSettings().ccTemplate();
auto promptTemplate = LLMCore::PromptTemplateManager::instance().getFimTemplateByName(
templateName);

if (!promptTemplate) {
LOG_MESSAGE(QString("No template found with name: %1").arg(templateName));
return;
}

LLMCore::LLMConfig config;
config.requestType = LLMCore::RequestType::Fim;
config.provider = provider;
config.promptTemplate = promptTemplate;
config.url = QUrl(
QString("%1%2").arg(Settings::generalSettings().ccUrl(), provider->completionEndpoint()));

config.providerRequest = {{"model", Settings::generalSettings().ccModel()},
{"stream", true},
{"stop",
QJsonArray::fromStringList(config.promptTemplate->stopWords())}};
config.providerRequest = {{"model", Settings::generalSettings().ccModel()}, {"stream", true}};

config.multiLineCompletion = completeSettings.multiLineCompletion();

QString systemPrompt;
if (completeSettings.useSystemPrompt())
systemPrompt.append(completeSettings.systemPrompt());
if (!updatedContext.fileContext.isEmpty())
systemPrompt.append(updatedContext.fileContext);
if (!systemPrompt.isEmpty())
config.providerRequest["system"] = systemPrompt;

config.providerRequest["system"] = systemPrompt;
const auto stopWords = QJsonArray::fromStringList(config.promptTemplate->stopWords());
if (!stopWords.isEmpty())
config.providerRequest["stop"] = stopWords;

config.promptTemplate->prepareRequest(config.providerRequest, updatedContext);
config.provider->prepareRequest(config.providerRequest, LLMCore::RequestType::Fim);
Expand Down
2 changes: 2 additions & 0 deletions qodeassist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include "templates/CustomFimTemplate.hpp"
#include "templates/DeepSeekCoderChat.hpp"
#include "templates/DeepSeekCoderFim.hpp"
#include "templates/Ollama.hpp"
#include "templates/Qwen.hpp"
#include "templates/StarCoder2Fim.hpp"
#include "templates/StarCoderChat.hpp"
Expand Down Expand Up @@ -99,6 +100,7 @@ class QodeAssistPlugin final : public ExtensionSystem::IPlugin
templateManager.registerTemplate<Templates::StarCoderChat>();
templateManager.registerTemplate<Templates::QwenChat>();
templateManager.registerTemplate<Templates::QwenFim>();
templateManager.registerTemplate<Templates::OllamaAutoFim>();

Utils::Icon QCODEASSIST_ICON(
{{":/resources/images/qoderassist-icon.png", Utils::Theme::IconsBaseColor}});
Expand Down
2 changes: 1 addition & 1 deletion settings/GeneralSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ GeneralSettings::GeneralSettings()
ccModel.setHistoryCompleter(Constants::CC_MODEL_HISTORY);
ccSelectModel.m_buttonText = TrConstants::SELECT;

initStringAspect(ccTemplate, Constants::CC_TEMPLATE, TrConstants::TEMPLATE, "CodeLlama FIM");
initStringAspect(ccTemplate, Constants::CC_TEMPLATE, TrConstants::TEMPLATE, "Ollama Auto FIM");
ccTemplate.setReadOnly(true);
ccSelectTemplate.m_buttonText = TrConstants::SELECT;

Expand Down
41 changes: 41 additions & 0 deletions templates/Ollama.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2024 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include "llmcore/PromptTemplate.hpp"

namespace QodeAssist::Templates {

class OllamaAutoFim : public LLMCore::PromptTemplate
{
public:
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Fim; }
QString name() const override { return "Ollama Auto FIM"; }
QString promptTemplate() const override { return {}; }
QStringList stopWords() const override { return QStringList(); }

void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
{
request["prompt"] = context.prefix;
request["suffix"] = context.suffix;
}
};

} // namespace QodeAssist::Templates

0 comments on commit 80fe388

Please sign in to comment.