mirror of
https://github.com/nomic-ai/gpt4all.git
synced 2025-06-19 04:04:36 +00:00
Stop hardcoding the tool call checking and rely upon the format advocated by ollama for tool calling.
Signed-off-by: Adam Treat <treat.adam@gmail.com>
This commit is contained in:
parent
b9684ff741
commit
7c7558eed3
@ -115,7 +115,9 @@ ChatLLM::ChatLLM(Chat *parent, bool isServer)
|
|||||||
, m_reloadingToChangeVariant(false)
|
, m_reloadingToChangeVariant(false)
|
||||||
, m_processedSystemPrompt(false)
|
, m_processedSystemPrompt(false)
|
||||||
, m_restoreStateFromText(false)
|
, m_restoreStateFromText(false)
|
||||||
|
, m_checkToolCall(false)
|
||||||
, m_maybeToolCall(false)
|
, m_maybeToolCall(false)
|
||||||
|
, m_foundToolCall(false)
|
||||||
{
|
{
|
||||||
moveToThread(&m_llmThread);
|
moveToThread(&m_llmThread);
|
||||||
connect(this, &ChatLLM::shouldBeLoadedChanged, this, &ChatLLM::handleShouldBeLoadedChanged,
|
connect(this, &ChatLLM::shouldBeLoadedChanged, this, &ChatLLM::handleShouldBeLoadedChanged,
|
||||||
@ -705,34 +707,6 @@ bool ChatLLM::handleResponse(int32_t token, const std::string &response)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only valid for llama 3.1 instruct
|
|
||||||
if (m_modelInfo.filename().startsWith("Meta-Llama-3.1-8B-Instruct")) {
|
|
||||||
// Based on https://llama.meta.com/docs/model-cards-and-prompt-formats/llama3_1/#built-in-python-based-tool-calling
|
|
||||||
// For brave_search and wolfram_alpha ipython is always used
|
|
||||||
|
|
||||||
// <|python_tag|>
|
|
||||||
// brave_search.call(query="...")
|
|
||||||
// <|eom_id|>
|
|
||||||
const int eom_id = 128008;
|
|
||||||
const int python_tag = 128010;
|
|
||||||
|
|
||||||
// If we have a built-in tool call, then it should be the first token
|
|
||||||
const bool isFirstResponseToken = m_promptResponseTokens == m_promptTokens;
|
|
||||||
Q_ASSERT(token != python_tag || isFirstResponseToken);
|
|
||||||
if (isFirstResponseToken && token == python_tag) {
|
|
||||||
m_maybeToolCall = true;
|
|
||||||
++m_promptResponseTokens;
|
|
||||||
return !m_stopGenerating;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for end of built-in tool call
|
|
||||||
Q_ASSERT(token != eom_id || !m_maybeToolCall);
|
|
||||||
if (token == eom_id) {
|
|
||||||
++m_promptResponseTokens;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// m_promptResponseTokens is related to last prompt/response not
|
// m_promptResponseTokens is related to last prompt/response not
|
||||||
// the entire context window which we can reset on regenerate prompt
|
// the entire context window which we can reset on regenerate prompt
|
||||||
++m_promptResponseTokens;
|
++m_promptResponseTokens;
|
||||||
@ -740,7 +714,25 @@ bool ChatLLM::handleResponse(int32_t token, const std::string &response)
|
|||||||
Q_ASSERT(!response.empty());
|
Q_ASSERT(!response.empty());
|
||||||
m_response.append(response);
|
m_response.append(response);
|
||||||
|
|
||||||
if (!m_maybeToolCall)
|
// If we're checking for a tool called and the response is equal or exceeds 11 chars
|
||||||
|
// then we check
|
||||||
|
if (m_checkToolCall && m_response.size() >= 11) {
|
||||||
|
if (m_response.starts_with("<tool_call>")) {
|
||||||
|
m_maybeToolCall = true;
|
||||||
|
m_response.erase(0, 11);
|
||||||
|
}
|
||||||
|
m_checkToolCall = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we're at the end of tool call and erase the end tag
|
||||||
|
if (m_maybeToolCall && m_response.ends_with("</tool_call>")) {
|
||||||
|
m_foundToolCall = true;
|
||||||
|
m_response.erase(m_response.length() - 12);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're not checking for tool call and haven't detected one, then send along the response
|
||||||
|
if (!m_checkToolCall && !m_maybeToolCall)
|
||||||
emit responseChanged(QString::fromStdString(remove_leading_whitespace(m_response)));
|
emit responseChanged(QString::fromStdString(remove_leading_whitespace(m_response)));
|
||||||
|
|
||||||
return !m_stopGenerating;
|
return !m_stopGenerating;
|
||||||
@ -822,8 +814,12 @@ bool ChatLLM::promptInternal(const QList<QString> &collectionList, const QString
|
|||||||
/*allowContextShift*/ true, m_ctx);
|
/*allowContextShift*/ true, m_ctx);
|
||||||
m_ctx.n_predict = old_n_predict; // now we are ready for a response
|
m_ctx.n_predict = old_n_predict; // now we are ready for a response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_checkToolCall = !isToolCallResponse; // We can't handle recursive tool calls right now
|
||||||
m_llModelInfo.model->prompt(prompt.toStdString(), promptTemplate.toStdString(), promptFunc, responseFunc,
|
m_llModelInfo.model->prompt(prompt.toStdString(), promptTemplate.toStdString(), promptFunc, responseFunc,
|
||||||
/*allowContextShift*/ true, m_ctx);
|
/*allowContextShift*/ true, m_ctx);
|
||||||
|
m_checkToolCall = false;
|
||||||
|
m_maybeToolCall = false;
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -831,8 +827,8 @@ bool ChatLLM::promptInternal(const QList<QString> &collectionList, const QString
|
|||||||
m_timer->stop();
|
m_timer->stop();
|
||||||
qint64 elapsed = totalTime.elapsed();
|
qint64 elapsed = totalTime.elapsed();
|
||||||
std::string trimmed = trim_whitespace(m_response);
|
std::string trimmed = trim_whitespace(m_response);
|
||||||
if (m_maybeToolCall) {
|
if (m_foundToolCall) {
|
||||||
m_maybeToolCall = false;
|
m_foundToolCall = false;
|
||||||
m_ctx.n_past = std::max(0, m_ctx.n_past);
|
m_ctx.n_past = std::max(0, m_ctx.n_past);
|
||||||
m_ctx.tokens.erase(m_ctx.tokens.end() - m_promptResponseTokens, m_ctx.tokens.end());
|
m_ctx.tokens.erase(m_ctx.tokens.end() - m_promptResponseTokens, m_ctx.tokens.end());
|
||||||
m_promptResponseTokens = 0;
|
m_promptResponseTokens = 0;
|
||||||
@ -860,25 +856,46 @@ bool ChatLLM::promptInternal(const QList<QString> &collectionList, const QString
|
|||||||
bool ChatLLM::toolCallInternal(const QString &toolCall, int32_t n_predict, int32_t top_k, float top_p,
|
bool ChatLLM::toolCallInternal(const QString &toolCall, int32_t n_predict, int32_t top_k, float top_p,
|
||||||
float min_p, float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens)
|
float min_p, float temp, int32_t n_batch, float repeat_penalty, int32_t repeat_penalty_tokens)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_modelInfo.filename().startsWith("Meta-Llama-3.1-8B-Instruct"));
|
QString toolTemplate = MySettings::globalInstance()->modelToolTemplate(m_modelInfo);
|
||||||
emit toolCalled(tr("searching web..."));
|
if (toolTemplate.isEmpty()) {
|
||||||
|
// FIXME: Not sure what to do here. The model attempted a tool call, but there is no way for
|
||||||
// Based on https://llama.meta.com/docs/model-cards-and-prompt-formats/llama3_1/#built-in-python-based-tool-calling
|
// us to process it. We should probably not even attempt further generation and just show an
|
||||||
// For brave_search and wolfram_alpha ipython is always used
|
// error in the chat somehow?
|
||||||
|
qWarning() << "WARNING: The model attempted a toolcall, but there is no valid tool template for this model" << toolCall;
|
||||||
static QRegularExpression re(R"(brave_search\.call\(query=\"([^\"]+)\"\))");
|
return promptInternal(QList<QString>()/*collectionList*/, QString() /*prompt*/,
|
||||||
QRegularExpressionMatch match = re.match(toolCall);
|
MySettings::globalInstance()->modelPromptTemplate(m_modelInfo),
|
||||||
|
|
||||||
QString promptTemplate("<|start_header_id|>ipython<|end_header_id|>\n\n%1<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n%2");
|
|
||||||
QString query;
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
query = match.captured(1);
|
|
||||||
} else {
|
|
||||||
qWarning() << "WARNING: Could not find the tool for " << toolCall;
|
|
||||||
return promptInternal(QList<QString>()/*collectionList*/, QString() /*prompt*/, promptTemplate,
|
|
||||||
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, true /*isToolCallResponse*/);
|
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, true /*isToolCallResponse*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonParseError err;
|
||||||
|
QJsonDocument toolCallDoc = QJsonDocument::fromJson(toolCall.toUtf8(), &err);
|
||||||
|
|
||||||
|
if (toolCallDoc.isNull() || err.error != QJsonParseError::NoError || !toolCallDoc.isObject()) {
|
||||||
|
qWarning() << "WARNING: The tool call had null or invalid json " << toolCall;
|
||||||
|
return promptInternal(QList<QString>()/*collectionList*/, QString() /*prompt*/, toolTemplate,
|
||||||
|
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, true /*isToolCallResponse*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject rootObject = toolCallDoc.object();
|
||||||
|
if (!rootObject.contains("name") || !rootObject.contains("arguments")) {
|
||||||
|
qWarning() << "WARNING: The tool call did not have required name and argument objects " << toolCall;
|
||||||
|
return promptInternal(QList<QString>()/*collectionList*/, QString() /*prompt*/, toolTemplate,
|
||||||
|
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, true /*isToolCallResponse*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString tool = toolCallDoc["name"].toString();
|
||||||
|
const QJsonObject args = toolCallDoc["arguments"].toObject();
|
||||||
|
|
||||||
|
if (tool != "brave_search" || !args.contains("query")) {
|
||||||
|
qWarning() << "WARNING: Could not find the tool and correct arguments for " << toolCall;
|
||||||
|
return promptInternal(QList<QString>()/*collectionList*/, QString() /*prompt*/, toolTemplate,
|
||||||
|
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, true /*isToolCallResponse*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString query = args["query"].toString();
|
||||||
|
|
||||||
|
emit toolCalled(tr("searching web..."));
|
||||||
|
|
||||||
const QString apiKey = MySettings::globalInstance()->braveSearchAPIKey();
|
const QString apiKey = MySettings::globalInstance()->braveSearchAPIKey();
|
||||||
Q_ASSERT(apiKey != "");
|
Q_ASSERT(apiKey != "");
|
||||||
|
|
||||||
@ -887,7 +904,7 @@ bool ChatLLM::toolCallInternal(const QString &toolCall, int32_t n_predict, int32
|
|||||||
|
|
||||||
emit sourceExcerptsChanged(braveResponse.second);
|
emit sourceExcerptsChanged(braveResponse.second);
|
||||||
|
|
||||||
return promptInternal(QList<QString>()/*collectionList*/, braveResponse.first, promptTemplate,
|
return promptInternal(QList<QString>()/*collectionList*/, braveResponse.first, toolTemplate,
|
||||||
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, true /*isToolCallResponse*/);
|
n_predict, top_k, top_p, min_p, temp, n_batch, repeat_penalty, repeat_penalty_tokens, true /*isToolCallResponse*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +242,9 @@ private:
|
|||||||
bool m_reloadingToChangeVariant;
|
bool m_reloadingToChangeVariant;
|
||||||
bool m_processedSystemPrompt;
|
bool m_processedSystemPrompt;
|
||||||
bool m_restoreStateFromText;
|
bool m_restoreStateFromText;
|
||||||
|
bool m_checkToolCall;
|
||||||
bool m_maybeToolCall;
|
bool m_maybeToolCall;
|
||||||
|
bool m_foundToolCall;
|
||||||
// m_pristineLoadedState is set if saveSate is unnecessary, either because:
|
// m_pristineLoadedState is set if saveSate is unnecessary, either because:
|
||||||
// - an unload was queued during LLModel::restoreState()
|
// - an unload was queued during LLModel::restoreState()
|
||||||
// - the chat will be restored from text and hasn't been interacted with yet
|
// - the chat will be restored from text and hasn't been interacted with yet
|
||||||
|
@ -323,6 +323,17 @@ void ModelInfo::setPromptTemplate(const QString &t)
|
|||||||
m_promptTemplate = t;
|
m_promptTemplate = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ModelInfo::toolTemplate() const
|
||||||
|
{
|
||||||
|
return MySettings::globalInstance()->modelToolTemplate(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelInfo::setToolTemplate(const QString &t)
|
||||||
|
{
|
||||||
|
if (shouldSaveMetadata()) MySettings::globalInstance()->setModelToolTemplate(*this, t, true /*force*/);
|
||||||
|
m_toolTemplate = t;
|
||||||
|
}
|
||||||
|
|
||||||
QString ModelInfo::systemPrompt() const
|
QString ModelInfo::systemPrompt() const
|
||||||
{
|
{
|
||||||
return MySettings::globalInstance()->modelSystemPrompt(*this);
|
return MySettings::globalInstance()->modelSystemPrompt(*this);
|
||||||
@ -385,6 +396,7 @@ QVariantMap ModelInfo::getFields() const
|
|||||||
{ "repeatPenalty", m_repeatPenalty },
|
{ "repeatPenalty", m_repeatPenalty },
|
||||||
{ "repeatPenaltyTokens", m_repeatPenaltyTokens },
|
{ "repeatPenaltyTokens", m_repeatPenaltyTokens },
|
||||||
{ "promptTemplate", m_promptTemplate },
|
{ "promptTemplate", m_promptTemplate },
|
||||||
|
{ "toolTemplate", m_toolTemplate },
|
||||||
{ "systemPrompt", m_systemPrompt },
|
{ "systemPrompt", m_systemPrompt },
|
||||||
{ "chatNamePrompt", m_chatNamePrompt },
|
{ "chatNamePrompt", m_chatNamePrompt },
|
||||||
{ "suggestedFollowUpPrompt", m_suggestedFollowUpPrompt },
|
{ "suggestedFollowUpPrompt", m_suggestedFollowUpPrompt },
|
||||||
@ -504,6 +516,7 @@ ModelList::ModelList()
|
|||||||
connect(MySettings::globalInstance(), &MySettings::repeatPenaltyChanged, this, &ModelList::updateDataForSettings);
|
connect(MySettings::globalInstance(), &MySettings::repeatPenaltyChanged, this, &ModelList::updateDataForSettings);
|
||||||
connect(MySettings::globalInstance(), &MySettings::repeatPenaltyTokensChanged, this, &ModelList::updateDataForSettings);;
|
connect(MySettings::globalInstance(), &MySettings::repeatPenaltyTokensChanged, this, &ModelList::updateDataForSettings);;
|
||||||
connect(MySettings::globalInstance(), &MySettings::promptTemplateChanged, this, &ModelList::updateDataForSettings);
|
connect(MySettings::globalInstance(), &MySettings::promptTemplateChanged, this, &ModelList::updateDataForSettings);
|
||||||
|
connect(MySettings::globalInstance(), &MySettings::toolTemplateChanged, this, &ModelList::updateDataForSettings);
|
||||||
connect(MySettings::globalInstance(), &MySettings::systemPromptChanged, this, &ModelList::updateDataForSettings);
|
connect(MySettings::globalInstance(), &MySettings::systemPromptChanged, this, &ModelList::updateDataForSettings);
|
||||||
connect(&m_networkManager, &QNetworkAccessManager::sslErrors, this, &ModelList::handleSslErrors);
|
connect(&m_networkManager, &QNetworkAccessManager::sslErrors, this, &ModelList::handleSslErrors);
|
||||||
|
|
||||||
@ -776,6 +789,8 @@ QVariant ModelList::dataInternal(const ModelInfo *info, int role) const
|
|||||||
return info->repeatPenaltyTokens();
|
return info->repeatPenaltyTokens();
|
||||||
case PromptTemplateRole:
|
case PromptTemplateRole:
|
||||||
return info->promptTemplate();
|
return info->promptTemplate();
|
||||||
|
case ToolTemplateRole:
|
||||||
|
return info->toolTemplate();
|
||||||
case SystemPromptRole:
|
case SystemPromptRole:
|
||||||
return info->systemPrompt();
|
return info->systemPrompt();
|
||||||
case ChatNamePromptRole:
|
case ChatNamePromptRole:
|
||||||
@ -952,6 +967,8 @@ void ModelList::updateData(const QString &id, const QVector<QPair<int, QVariant>
|
|||||||
info->setRepeatPenaltyTokens(value.toInt()); break;
|
info->setRepeatPenaltyTokens(value.toInt()); break;
|
||||||
case PromptTemplateRole:
|
case PromptTemplateRole:
|
||||||
info->setPromptTemplate(value.toString()); break;
|
info->setPromptTemplate(value.toString()); break;
|
||||||
|
case ToolTemplateRole:
|
||||||
|
info->setToolTemplate(value.toString()); break;
|
||||||
case SystemPromptRole:
|
case SystemPromptRole:
|
||||||
info->setSystemPrompt(value.toString()); break;
|
info->setSystemPrompt(value.toString()); break;
|
||||||
case ChatNamePromptRole:
|
case ChatNamePromptRole:
|
||||||
@ -1107,6 +1124,7 @@ QString ModelList::clone(const ModelInfo &model)
|
|||||||
{ ModelList::RepeatPenaltyRole, model.repeatPenalty() },
|
{ ModelList::RepeatPenaltyRole, model.repeatPenalty() },
|
||||||
{ ModelList::RepeatPenaltyTokensRole, model.repeatPenaltyTokens() },
|
{ ModelList::RepeatPenaltyTokensRole, model.repeatPenaltyTokens() },
|
||||||
{ ModelList::PromptTemplateRole, model.promptTemplate() },
|
{ ModelList::PromptTemplateRole, model.promptTemplate() },
|
||||||
|
{ ModelList::ToolTemplateRole, model.toolTemplate() },
|
||||||
{ ModelList::SystemPromptRole, model.systemPrompt() },
|
{ ModelList::SystemPromptRole, model.systemPrompt() },
|
||||||
{ ModelList::ChatNamePromptRole, model.chatNamePrompt() },
|
{ ModelList::ChatNamePromptRole, model.chatNamePrompt() },
|
||||||
{ ModelList::SuggestedFollowUpPromptRole, model.suggestedFollowUpPrompt() },
|
{ ModelList::SuggestedFollowUpPromptRole, model.suggestedFollowUpPrompt() },
|
||||||
@ -1551,6 +1569,8 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
|
|||||||
data.append({ ModelList::RepeatPenaltyTokensRole, obj["repeatPenaltyTokens"].toInt() });
|
data.append({ ModelList::RepeatPenaltyTokensRole, obj["repeatPenaltyTokens"].toInt() });
|
||||||
if (obj.contains("promptTemplate"))
|
if (obj.contains("promptTemplate"))
|
||||||
data.append({ ModelList::PromptTemplateRole, obj["promptTemplate"].toString() });
|
data.append({ ModelList::PromptTemplateRole, obj["promptTemplate"].toString() });
|
||||||
|
if (obj.contains("toolTemplate"))
|
||||||
|
data.append({ ModelList::ToolTemplateRole, obj["toolTemplate"].toString() });
|
||||||
if (obj.contains("systemPrompt"))
|
if (obj.contains("systemPrompt"))
|
||||||
data.append({ ModelList::SystemPromptRole, obj["systemPrompt"].toString() });
|
data.append({ ModelList::SystemPromptRole, obj["systemPrompt"].toString() });
|
||||||
updateData(id, data);
|
updateData(id, data);
|
||||||
@ -1852,6 +1872,10 @@ void ModelList::updateModelsFromSettings()
|
|||||||
const QString promptTemplate = settings.value(g + "/promptTemplate").toString();
|
const QString promptTemplate = settings.value(g + "/promptTemplate").toString();
|
||||||
data.append({ ModelList::PromptTemplateRole, promptTemplate });
|
data.append({ ModelList::PromptTemplateRole, promptTemplate });
|
||||||
}
|
}
|
||||||
|
if (settings.contains(g + "/toolTemplate")) {
|
||||||
|
const QString toolTemplate = settings.value(g + "/toolTemplate").toString();
|
||||||
|
data.append({ ModelList::ToolTemplateRole, toolTemplate });
|
||||||
|
}
|
||||||
if (settings.contains(g + "/systemPrompt")) {
|
if (settings.contains(g + "/systemPrompt")) {
|
||||||
const QString systemPrompt = settings.value(g + "/systemPrompt").toString();
|
const QString systemPrompt = settings.value(g + "/systemPrompt").toString();
|
||||||
data.append({ ModelList::SystemPromptRole, systemPrompt });
|
data.append({ ModelList::SystemPromptRole, systemPrompt });
|
||||||
|
@ -68,6 +68,7 @@ struct ModelInfo {
|
|||||||
Q_PROPERTY(double repeatPenalty READ repeatPenalty WRITE setRepeatPenalty)
|
Q_PROPERTY(double repeatPenalty READ repeatPenalty WRITE setRepeatPenalty)
|
||||||
Q_PROPERTY(int repeatPenaltyTokens READ repeatPenaltyTokens WRITE setRepeatPenaltyTokens)
|
Q_PROPERTY(int repeatPenaltyTokens READ repeatPenaltyTokens WRITE setRepeatPenaltyTokens)
|
||||||
Q_PROPERTY(QString promptTemplate READ promptTemplate WRITE setPromptTemplate)
|
Q_PROPERTY(QString promptTemplate READ promptTemplate WRITE setPromptTemplate)
|
||||||
|
Q_PROPERTY(QString toolTemplate READ toolTemplate WRITE setToolTemplate)
|
||||||
Q_PROPERTY(QString systemPrompt READ systemPrompt WRITE setSystemPrompt)
|
Q_PROPERTY(QString systemPrompt READ systemPrompt WRITE setSystemPrompt)
|
||||||
Q_PROPERTY(QString chatNamePrompt READ chatNamePrompt WRITE setChatNamePrompt)
|
Q_PROPERTY(QString chatNamePrompt READ chatNamePrompt WRITE setChatNamePrompt)
|
||||||
Q_PROPERTY(QString suggestedFollowUpPrompt READ suggestedFollowUpPrompt WRITE setSuggestedFollowUpPrompt)
|
Q_PROPERTY(QString suggestedFollowUpPrompt READ suggestedFollowUpPrompt WRITE setSuggestedFollowUpPrompt)
|
||||||
@ -178,6 +179,8 @@ public:
|
|||||||
void setRepeatPenaltyTokens(int t);
|
void setRepeatPenaltyTokens(int t);
|
||||||
QString promptTemplate() const;
|
QString promptTemplate() const;
|
||||||
void setPromptTemplate(const QString &t);
|
void setPromptTemplate(const QString &t);
|
||||||
|
QString toolTemplate() const;
|
||||||
|
void setToolTemplate(const QString &t);
|
||||||
QString systemPrompt() const;
|
QString systemPrompt() const;
|
||||||
void setSystemPrompt(const QString &p);
|
void setSystemPrompt(const QString &p);
|
||||||
QString chatNamePrompt() const;
|
QString chatNamePrompt() const;
|
||||||
@ -215,6 +218,7 @@ private:
|
|||||||
double m_repeatPenalty = 1.18;
|
double m_repeatPenalty = 1.18;
|
||||||
int m_repeatPenaltyTokens = 64;
|
int m_repeatPenaltyTokens = 64;
|
||||||
QString m_promptTemplate = "### Human:\n%1\n\n### Assistant:\n";
|
QString m_promptTemplate = "### Human:\n%1\n\n### Assistant:\n";
|
||||||
|
QString m_toolTemplate = "";
|
||||||
QString m_systemPrompt = "### System:\nYou are an AI assistant who gives a quality response to whatever humans ask of you.\n\n";
|
QString m_systemPrompt = "### System:\nYou are an AI assistant who gives a quality response to whatever humans ask of you.\n\n";
|
||||||
QString m_chatNamePrompt = "Describe the above conversation in seven words or less.";
|
QString m_chatNamePrompt = "Describe the above conversation in seven words or less.";
|
||||||
QString m_suggestedFollowUpPrompt = "Suggest three very short factual follow-up questions that have not been answered yet or cannot be found inspired by the previous conversation and excerpts.";
|
QString m_suggestedFollowUpPrompt = "Suggest three very short factual follow-up questions that have not been answered yet or cannot be found inspired by the previous conversation and excerpts.";
|
||||||
@ -339,6 +343,7 @@ public:
|
|||||||
RepeatPenaltyRole,
|
RepeatPenaltyRole,
|
||||||
RepeatPenaltyTokensRole,
|
RepeatPenaltyTokensRole,
|
||||||
PromptTemplateRole,
|
PromptTemplateRole,
|
||||||
|
ToolTemplateRole,
|
||||||
SystemPromptRole,
|
SystemPromptRole,
|
||||||
ChatNamePromptRole,
|
ChatNamePromptRole,
|
||||||
SuggestedFollowUpPromptRole,
|
SuggestedFollowUpPromptRole,
|
||||||
@ -393,6 +398,7 @@ public:
|
|||||||
roles[RepeatPenaltyRole] = "repeatPenalty";
|
roles[RepeatPenaltyRole] = "repeatPenalty";
|
||||||
roles[RepeatPenaltyTokensRole] = "repeatPenaltyTokens";
|
roles[RepeatPenaltyTokensRole] = "repeatPenaltyTokens";
|
||||||
roles[PromptTemplateRole] = "promptTemplate";
|
roles[PromptTemplateRole] = "promptTemplate";
|
||||||
|
roles[ToolTemplateRole] = "toolTemplate";
|
||||||
roles[SystemPromptRole] = "systemPrompt";
|
roles[SystemPromptRole] = "systemPrompt";
|
||||||
roles[ChatNamePromptRole] = "chatNamePrompt";
|
roles[ChatNamePromptRole] = "chatNamePrompt";
|
||||||
roles[SuggestedFollowUpPromptRole] = "suggestedFollowUpPrompt";
|
roles[SuggestedFollowUpPromptRole] = "suggestedFollowUpPrompt";
|
||||||
|
@ -194,6 +194,7 @@ void MySettings::restoreModelDefaults(const ModelInfo &info)
|
|||||||
setModelRepeatPenalty(info, info.m_repeatPenalty);
|
setModelRepeatPenalty(info, info.m_repeatPenalty);
|
||||||
setModelRepeatPenaltyTokens(info, info.m_repeatPenaltyTokens);
|
setModelRepeatPenaltyTokens(info, info.m_repeatPenaltyTokens);
|
||||||
setModelPromptTemplate(info, info.m_promptTemplate);
|
setModelPromptTemplate(info, info.m_promptTemplate);
|
||||||
|
setModelToolTemplate(info, info.m_toolTemplate);
|
||||||
setModelSystemPrompt(info, info.m_systemPrompt);
|
setModelSystemPrompt(info, info.m_systemPrompt);
|
||||||
setModelChatNamePrompt(info, info.m_chatNamePrompt);
|
setModelChatNamePrompt(info, info.m_chatNamePrompt);
|
||||||
setModelSuggestedFollowUpPrompt(info, info.m_suggestedFollowUpPrompt);
|
setModelSuggestedFollowUpPrompt(info, info.m_suggestedFollowUpPrompt);
|
||||||
@ -296,6 +297,7 @@ int MySettings::modelGpuLayers (const ModelInfo &info) const
|
|||||||
double MySettings::modelRepeatPenalty (const ModelInfo &info) const { return getModelSetting("repeatPenalty", info).toDouble(); }
|
double MySettings::modelRepeatPenalty (const ModelInfo &info) const { return getModelSetting("repeatPenalty", info).toDouble(); }
|
||||||
int MySettings::modelRepeatPenaltyTokens (const ModelInfo &info) const { return getModelSetting("repeatPenaltyTokens", info).toInt(); }
|
int MySettings::modelRepeatPenaltyTokens (const ModelInfo &info) const { return getModelSetting("repeatPenaltyTokens", info).toInt(); }
|
||||||
QString MySettings::modelPromptTemplate (const ModelInfo &info) const { return getModelSetting("promptTemplate", info).toString(); }
|
QString MySettings::modelPromptTemplate (const ModelInfo &info) const { return getModelSetting("promptTemplate", info).toString(); }
|
||||||
|
QString MySettings::modelToolTemplate (const ModelInfo &info) const { return getModelSetting("toolTemplate", info).toString(); }
|
||||||
QString MySettings::modelSystemPrompt (const ModelInfo &info) const { return getModelSetting("systemPrompt", info).toString(); }
|
QString MySettings::modelSystemPrompt (const ModelInfo &info) const { return getModelSetting("systemPrompt", info).toString(); }
|
||||||
QString MySettings::modelChatNamePrompt (const ModelInfo &info) const { return getModelSetting("chatNamePrompt", info).toString(); }
|
QString MySettings::modelChatNamePrompt (const ModelInfo &info) const { return getModelSetting("chatNamePrompt", info).toString(); }
|
||||||
QString MySettings::modelSuggestedFollowUpPrompt(const ModelInfo &info) const { return getModelSetting("suggestedFollowUpPrompt", info).toString(); }
|
QString MySettings::modelSuggestedFollowUpPrompt(const ModelInfo &info) const { return getModelSetting("suggestedFollowUpPrompt", info).toString(); }
|
||||||
@ -405,6 +407,11 @@ void MySettings::setModelPromptTemplate(const ModelInfo &info, const QString &va
|
|||||||
setModelSetting("promptTemplate", info, value, force, true);
|
setModelSetting("promptTemplate", info, value, force, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MySettings::setModelToolTemplate(const ModelInfo &info, const QString &value, bool force)
|
||||||
|
{
|
||||||
|
setModelSetting("toolTemplate", info, value, force, true);
|
||||||
|
}
|
||||||
|
|
||||||
void MySettings::setModelSystemPrompt(const ModelInfo &info, const QString &value, bool force)
|
void MySettings::setModelSystemPrompt(const ModelInfo &info, const QString &value, bool force)
|
||||||
{
|
{
|
||||||
setModelSetting("systemPrompt", info, value, force, true);
|
setModelSetting("systemPrompt", info, value, force, true);
|
||||||
|
@ -126,6 +126,8 @@ public:
|
|||||||
Q_INVOKABLE void setModelRepeatPenaltyTokens(const ModelInfo &info, int value, bool force = false);
|
Q_INVOKABLE void setModelRepeatPenaltyTokens(const ModelInfo &info, int value, bool force = false);
|
||||||
QString modelPromptTemplate(const ModelInfo &info) const;
|
QString modelPromptTemplate(const ModelInfo &info) const;
|
||||||
Q_INVOKABLE void setModelPromptTemplate(const ModelInfo &info, const QString &value, bool force = false);
|
Q_INVOKABLE void setModelPromptTemplate(const ModelInfo &info, const QString &value, bool force = false);
|
||||||
|
QString modelToolTemplate(const ModelInfo &info) const;
|
||||||
|
Q_INVOKABLE void setModelToolTemplate(const ModelInfo &info, const QString &value, bool force = false);
|
||||||
QString modelSystemPrompt(const ModelInfo &info) const;
|
QString modelSystemPrompt(const ModelInfo &info) const;
|
||||||
Q_INVOKABLE void setModelSystemPrompt(const ModelInfo &info, const QString &value, bool force = false);
|
Q_INVOKABLE void setModelSystemPrompt(const ModelInfo &info, const QString &value, bool force = false);
|
||||||
int modelContextLength(const ModelInfo &info) const;
|
int modelContextLength(const ModelInfo &info) const;
|
||||||
@ -217,6 +219,7 @@ Q_SIGNALS:
|
|||||||
void repeatPenaltyChanged(const ModelInfo &info);
|
void repeatPenaltyChanged(const ModelInfo &info);
|
||||||
void repeatPenaltyTokensChanged(const ModelInfo &info);
|
void repeatPenaltyTokensChanged(const ModelInfo &info);
|
||||||
void promptTemplateChanged(const ModelInfo &info);
|
void promptTemplateChanged(const ModelInfo &info);
|
||||||
|
void toolTemplateChanged(const ModelInfo &info);
|
||||||
void systemPromptChanged(const ModelInfo &info);
|
void systemPromptChanged(const ModelInfo &info);
|
||||||
void chatNamePromptChanged(const ModelInfo &info);
|
void chatNamePromptChanged(const ModelInfo &info);
|
||||||
void suggestedFollowUpPromptChanged(const ModelInfo &info);
|
void suggestedFollowUpPromptChanged(const ModelInfo &info);
|
||||||
|
@ -209,7 +209,7 @@ MySettingsTab {
|
|||||||
id: promptTemplateLabelHelp
|
id: promptTemplateLabelHelp
|
||||||
text: qsTr("Must contain the string \"%1\" to be replaced with the user's input.")
|
text: qsTr("Must contain the string \"%1\" to be replaced with the user's input.")
|
||||||
color: theme.textErrorColor
|
color: theme.textErrorColor
|
||||||
visible: templateTextArea.text.indexOf("%1") === -1
|
visible: promptTemplateTextArea.text.indexOf("%1") === -1
|
||||||
wrapMode: TextArea.Wrap
|
wrapMode: TextArea.Wrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,27 +220,27 @@ MySettingsTab {
|
|||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.minimumHeight: Math.max(100, templateTextArea.contentHeight + 20)
|
Layout.minimumHeight: Math.max(100, promptTemplateTextArea.contentHeight + 20)
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
clip: true
|
clip: true
|
||||||
MyTextArea {
|
MyTextArea {
|
||||||
id: templateTextArea
|
id: promptTemplateTextArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
text: root.currentModelInfo.promptTemplate
|
text: root.currentModelInfo.promptTemplate
|
||||||
Connections {
|
Connections {
|
||||||
target: MySettings
|
target: MySettings
|
||||||
function onPromptTemplateChanged() {
|
function onPromptTemplateChanged() {
|
||||||
templateTextArea.text = root.currentModelInfo.promptTemplate;
|
promptTemplateTextArea.text = root.currentModelInfo.promptTemplate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Connections {
|
Connections {
|
||||||
target: root
|
target: root
|
||||||
function onCurrentModelInfoChanged() {
|
function onCurrentModelInfoChanged() {
|
||||||
templateTextArea.text = root.currentModelInfo.promptTemplate;
|
promptTemplateTextArea.text = root.currentModelInfo.promptTemplate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if (templateTextArea.text.indexOf("%1") !== -1) {
|
if (promptTemplateTextArea.text.indexOf("%1") !== -1) {
|
||||||
MySettings.setModelPromptTemplate(root.currentModelInfo, text)
|
MySettings.setModelPromptTemplate(root.currentModelInfo, text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,18 +250,64 @@ MySettingsTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MySettingsLabel {
|
||||||
|
Layout.row: 11
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.topMargin: 15
|
||||||
|
id: toolTemplateLabel
|
||||||
|
text: qsTr("Tool Template")
|
||||||
|
helpText: qsTr("The template that allows tool calls to inject information into the context.")
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: toolTemplate
|
||||||
|
Layout.row: 12
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: Math.max(100, toolTemplateTextArea.contentHeight + 20)
|
||||||
|
color: "transparent"
|
||||||
|
clip: true
|
||||||
|
MyTextArea {
|
||||||
|
id: toolTemplateTextArea
|
||||||
|
anchors.fill: parent
|
||||||
|
text: root.currentModelInfo.toolTemplate
|
||||||
|
Connections {
|
||||||
|
target: MySettings
|
||||||
|
function onToolTemplateChanged() {
|
||||||
|
toolTemplateTextArea.text = root.currentModelInfo.toolTemplate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
function onCurrentModelInfoChanged() {
|
||||||
|
toolTemplateTextArea.text = root.currentModelInfo.toolTemplate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onTextChanged: {
|
||||||
|
if (toolTemplateTextArea.text.indexOf("%1") !== -1) {
|
||||||
|
MySettings.setModelToolTemplate(root.currentModelInfo, text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: toolTemplateLabel.text
|
||||||
|
Accessible.description: toolTemplateLabel.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MySettingsLabel {
|
MySettingsLabel {
|
||||||
id: chatNamePromptLabel
|
id: chatNamePromptLabel
|
||||||
text: qsTr("Chat Name Prompt")
|
text: qsTr("Chat Name Prompt")
|
||||||
helpText: qsTr("Prompt used to automatically generate chat names.")
|
helpText: qsTr("Prompt used to automatically generate chat names.")
|
||||||
Layout.row: 11
|
Layout.row: 13
|
||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.topMargin: 15
|
Layout.topMargin: 15
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: chatNamePrompt
|
id: chatNamePrompt
|
||||||
Layout.row: 12
|
Layout.row: 14
|
||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@ -297,14 +343,14 @@ MySettingsTab {
|
|||||||
id: suggestedFollowUpPromptLabel
|
id: suggestedFollowUpPromptLabel
|
||||||
text: qsTr("Suggested FollowUp Prompt")
|
text: qsTr("Suggested FollowUp Prompt")
|
||||||
helpText: qsTr("Prompt used to generate suggested follow-up questions.")
|
helpText: qsTr("Prompt used to generate suggested follow-up questions.")
|
||||||
Layout.row: 13
|
Layout.row: 15
|
||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.topMargin: 15
|
Layout.topMargin: 15
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: suggestedFollowUpPrompt
|
id: suggestedFollowUpPrompt
|
||||||
Layout.row: 14
|
Layout.row: 16
|
||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@ -337,7 +383,7 @@ MySettingsTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
Layout.row: 15
|
Layout.row: 17
|
||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
Layout.topMargin: 15
|
Layout.topMargin: 15
|
||||||
@ -833,7 +879,7 @@ MySettingsTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.row: 16
|
Layout.row: 18
|
||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
Layout.topMargin: 15
|
Layout.topMargin: 15
|
||||||
|
Loading…
Reference in New Issue
Block a user