mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-07-10 13:29:27 -04:00
fix: Found and fix review mistakes
This commit is contained in:
@@ -56,7 +56,8 @@ Agent::Agent(AgentConfig config, Providers::Provider *providerOwned, QObject *pa
|
||||
}
|
||||
m_provider->setParent(this);
|
||||
m_provider->setPromptCaching(
|
||||
m_config.cachePrompt, m_config.cacheTtl == QLatin1StringView{"1h"},
|
||||
m_config.cachePrompt,
|
||||
m_config.cacheTtl == QLatin1StringView{"1h"},
|
||||
m_config.cacheBreakpoints);
|
||||
|
||||
QString tmplErr;
|
||||
|
||||
@@ -46,8 +46,8 @@ public:
|
||||
|
||||
private:
|
||||
AgentConfig m_config;
|
||||
std::unique_ptr<Templates::JsonPromptTemplate> m_promptTemplate; // owned
|
||||
Providers::Provider *m_provider = nullptr; // child of this
|
||||
std::unique_ptr<Templates::JsonPromptTemplate> m_promptTemplate;
|
||||
Providers::Provider *m_provider = nullptr;
|
||||
QString m_invalidReason;
|
||||
};
|
||||
|
||||
|
||||
@@ -124,8 +124,8 @@ AgentConfig configFromMerged(const QJsonObject &obj)
|
||||
cfg.systemPrompt = obj.value("system_prompt").toString();
|
||||
cfg.enableThinking = obj.value("enable_thinking").toBool(false);
|
||||
cfg.enableTools = obj.value("enable_tools").toBool(false);
|
||||
cfg.cachePrompt = obj.value("cache_prompt").toBool(false);
|
||||
cfg.cacheTtl = obj.value("cache_ttl").toString();
|
||||
cfg.cachePrompt = obj.value("cache_prompt").toBool(false);
|
||||
cfg.cacheTtl = obj.value("cache_ttl").toString();
|
||||
cfg.cacheBreakpoints = stringArray(obj.value("cache_breakpoints"));
|
||||
cfg.tags = stringArray(obj.value("tags"));
|
||||
|
||||
@@ -153,26 +153,34 @@ constexpr int kMaxExtendsDepth = 32;
|
||||
|
||||
void lintUnknownKeys(const QJsonObject &obj, const QString &filePath, QStringList &warnings)
|
||||
{
|
||||
static const QSet<QString> kTopLevelKeys = {
|
||||
QStringLiteral("schema_version"), QStringLiteral("name"),
|
||||
QStringLiteral("description"), QStringLiteral("provider_instance"),
|
||||
QStringLiteral("model"), QStringLiteral("endpoint"),
|
||||
QStringLiteral("system_prompt"), QStringLiteral("tags"),
|
||||
QStringLiteral("match"), QStringLiteral("enable_thinking"),
|
||||
QStringLiteral("enable_tools"), QStringLiteral("cache_prompt"),
|
||||
QStringLiteral("cache_ttl"), QStringLiteral("cache_breakpoints"),
|
||||
QStringLiteral("body"),
|
||||
QStringLiteral("extends"), QStringLiteral("abstract"),
|
||||
QStringLiteral("hidden")};
|
||||
static const QSet<QString> kMatchKeys = {
|
||||
QStringLiteral("file_patterns"),
|
||||
QStringLiteral("path_patterns"),
|
||||
QStringLiteral("project_names")};
|
||||
static const QSet<QString> kTopLevelKeys
|
||||
= {QStringLiteral("schema_version"),
|
||||
QStringLiteral("name"),
|
||||
QStringLiteral("description"),
|
||||
QStringLiteral("provider_instance"),
|
||||
QStringLiteral("model"),
|
||||
QStringLiteral("endpoint"),
|
||||
QStringLiteral("system_prompt"),
|
||||
QStringLiteral("tags"),
|
||||
QStringLiteral("match"),
|
||||
QStringLiteral("enable_thinking"),
|
||||
QStringLiteral("enable_tools"),
|
||||
QStringLiteral("cache_prompt"),
|
||||
QStringLiteral("cache_ttl"),
|
||||
QStringLiteral("cache_breakpoints"),
|
||||
QStringLiteral("body"),
|
||||
QStringLiteral("extends"),
|
||||
QStringLiteral("abstract"),
|
||||
QStringLiteral("hidden")};
|
||||
static const QSet<QString> kMatchKeys
|
||||
= {QStringLiteral("file_patterns"),
|
||||
QStringLiteral("path_patterns"),
|
||||
QStringLiteral("project_names")};
|
||||
|
||||
for (auto it = obj.constBegin(); it != obj.constEnd(); ++it) {
|
||||
if (!kTopLevelKeys.contains(it.key())) {
|
||||
warnings.append(QStringLiteral("Unknown key '%1' in %2 — ignored (typo?)")
|
||||
.arg(it.key(), filePath));
|
||||
warnings.append(
|
||||
QStringLiteral("Unknown key '%1' in %2 — ignored (typo?)").arg(it.key(), filePath));
|
||||
}
|
||||
}
|
||||
const QJsonObject matchObj = obj.value("match").toObject();
|
||||
@@ -183,12 +191,13 @@ void lintUnknownKeys(const QJsonObject &obj, const QString &filePath, QStringLis
|
||||
}
|
||||
}
|
||||
|
||||
static const QSet<QString> kCacheBreakpoints = {
|
||||
QStringLiteral("system"), QStringLiteral("tools"), QStringLiteral("history")};
|
||||
static const QSet<QString> kCacheBreakpoints
|
||||
= {QStringLiteral("system"), QStringLiteral("tools"), QStringLiteral("history")};
|
||||
for (const QJsonValue &bp : obj.value("cache_breakpoints").toArray()) {
|
||||
if (bp.isString() && !kCacheBreakpoints.contains(bp.toString())) {
|
||||
warnings.append(QStringLiteral("Unknown cache_breakpoint '%1' in %2 — ignored "
|
||||
"(use system/tools/history)")
|
||||
warnings.append(QStringLiteral(
|
||||
"Unknown cache_breakpoint '%1' in %2 — ignored "
|
||||
"(use system/tools/history)")
|
||||
.arg(bp.toString(), filePath));
|
||||
}
|
||||
}
|
||||
@@ -201,10 +210,12 @@ void scanDir(
|
||||
QStringList &errors,
|
||||
QStringList *warnings)
|
||||
{
|
||||
if (dir.isEmpty()) return;
|
||||
if (dir.isEmpty())
|
||||
return;
|
||||
QDir d(dir);
|
||||
if (!d.exists()) return;
|
||||
const QStringList files = d.entryList({"*.toml"}, QDir::Files);
|
||||
if (!d.exists())
|
||||
return;
|
||||
const QStringList files = d.entryList({"*.toml"}, QDir::Files, QDir::Name);
|
||||
for (const QString &fname : files) {
|
||||
const QString fullPath = d.filePath(fname);
|
||||
QString err;
|
||||
@@ -222,17 +233,16 @@ void scanDir(
|
||||
lintUnknownKeys(*objOpt, fullPath, *warnings);
|
||||
const auto existing = raw.constFind(name);
|
||||
if (existing != raw.constEnd() && existing->isUserLayer != isUserLayer) {
|
||||
errors.append(
|
||||
QStringLiteral("Agent '%1' at %2 has the same name as a bundled agent — "
|
||||
"bundled agents cannot be replaced; rename it and use "
|
||||
"'extends' to build on the bundled one")
|
||||
.arg(name, fullPath));
|
||||
errors.append(QStringLiteral(
|
||||
"Agent '%1' at %2 has the same name as a bundled agent — "
|
||||
"bundled agents cannot be replaced; rename it and use "
|
||||
"'extends' to build on the bundled one")
|
||||
.arg(name, fullPath));
|
||||
continue;
|
||||
}
|
||||
if (warnings && existing != raw.constEnd()) {
|
||||
warnings->append(
|
||||
QStringLiteral("Agent '%1' is defined in both %2 and %3 — %3 wins")
|
||||
.arg(name, existing->filePath, fullPath));
|
||||
warnings->append(QStringLiteral("Agent '%1' is defined in both %2 and %3 — %3 wins")
|
||||
.arg(name, existing->filePath, fullPath));
|
||||
}
|
||||
raw.insert(name, {*objOpt, fullPath, isUserLayer});
|
||||
}
|
||||
@@ -251,7 +261,7 @@ QJsonObject mergeChild(const QJsonObject &parentMerged, const QJsonObject &self,
|
||||
return merged;
|
||||
}
|
||||
|
||||
QJsonObject resolveExtends(
|
||||
std::optional<QJsonObject> resolveExtends(
|
||||
const QString &name,
|
||||
const QHash<QString, RawEntry> &raw,
|
||||
QSet<QString> &visiting,
|
||||
@@ -262,15 +272,15 @@ QJsonObject resolveExtends(
|
||||
errors.append(QStringLiteral("Agent extends chain too deep (>%1) at '%2'")
|
||||
.arg(kMaxExtendsDepth)
|
||||
.arg(name));
|
||||
return {};
|
||||
return std::nullopt;
|
||||
}
|
||||
if (visiting.contains(name)) {
|
||||
errors.append(QStringLiteral("Cyclic 'extends' involving agent '%1'").arg(name));
|
||||
return {};
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!raw.contains(name)) {
|
||||
errors.append(QStringLiteral("Unknown agent '%1'").arg(name));
|
||||
return {};
|
||||
return std::nullopt;
|
||||
}
|
||||
visiting.insert(name);
|
||||
|
||||
@@ -281,11 +291,14 @@ QJsonObject resolveExtends(
|
||||
errors.append(QStringLiteral("Agent '%1' extends unknown agent '%2' (%3)")
|
||||
.arg(name, parent, raw.value(name).filePath));
|
||||
visiting.remove(name);
|
||||
return {};
|
||||
return std::nullopt;
|
||||
}
|
||||
const QJsonObject parentMerged
|
||||
= resolveExtends(parent, raw, visiting, errors, depth + 1);
|
||||
self = mergeChild(parentMerged, self, name);
|
||||
const auto parentMerged = resolveExtends(parent, raw, visiting, errors, depth + 1);
|
||||
if (!parentMerged) {
|
||||
visiting.remove(name);
|
||||
return std::nullopt;
|
||||
}
|
||||
self = mergeChild(*parentMerged, self, name);
|
||||
}
|
||||
visiting.remove(name);
|
||||
return self;
|
||||
@@ -294,17 +307,15 @@ QJsonObject resolveExtends(
|
||||
} // namespace
|
||||
|
||||
std::optional<AgentConfig> AgentLoader::parseFile(
|
||||
const QString &path,
|
||||
const QString &qrcPrefix,
|
||||
QString *error,
|
||||
QStringList *warnings)
|
||||
const QString &path, const QString &qrcPrefix, QString *error, QStringList *warnings)
|
||||
{
|
||||
auto objOpt = parseTomlFile(path, error);
|
||||
if (!objOpt) return std::nullopt;
|
||||
|
||||
const QString name = objOpt->value("name").toString();
|
||||
if (name.isEmpty()) {
|
||||
if (error) *error = QStringLiteral("Agent at %1 has no 'name'").arg(path);
|
||||
if (error)
|
||||
*error = QStringLiteral("Agent at %1 has no 'name'").arg(path);
|
||||
return std::nullopt;
|
||||
}
|
||||
if (warnings)
|
||||
@@ -312,28 +323,40 @@ std::optional<AgentConfig> AgentLoader::parseFile(
|
||||
|
||||
QHash<QString, RawEntry> raw;
|
||||
QStringList scanErrors;
|
||||
scanDir(qrcPrefix, /*isUserLayer=*/false, raw, scanErrors, nullptr);
|
||||
scanDir(QFileInfo(path).absolutePath(), /*isUserLayer=*/true, raw, scanErrors, nullptr);
|
||||
raw.insert(name, {*objOpt, path, true});
|
||||
scanDir(qrcPrefix, false, raw, scanErrors, nullptr);
|
||||
|
||||
QSet<QString> visiting;
|
||||
QStringList resolveErrors;
|
||||
const QJsonObject merged = resolveExtends(name, raw, visiting, resolveErrors);
|
||||
if (!resolveErrors.isEmpty() || merged.isEmpty()) {
|
||||
const auto bundled = raw.constFind(name);
|
||||
if (bundled != raw.constEnd() && !bundled->isUserLayer) {
|
||||
if (error) {
|
||||
*error = resolveErrors.isEmpty()
|
||||
? QStringLiteral("Agent '%1' resolved to an empty config").arg(name)
|
||||
: resolveErrors.join(QStringLiteral("; "));
|
||||
*error = QStringLiteral(
|
||||
"Agent '%1' at %2 has the same name as a bundled agent — bundled "
|
||||
"agents cannot be replaced; rename it and use 'extends' to build "
|
||||
"on the bundled one")
|
||||
.arg(name, path);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
AgentConfig cfg = configFromMerged(merged);
|
||||
scanDir(QFileInfo(path).absolutePath(), true, raw, scanErrors, nullptr);
|
||||
raw.insert(name, {*objOpt, path, true});
|
||||
|
||||
QSet<QString> visiting;
|
||||
QStringList resolveErrors;
|
||||
const auto merged = resolveExtends(name, raw, visiting, resolveErrors);
|
||||
if (!merged) {
|
||||
if (error)
|
||||
*error = resolveErrors.join(QStringLiteral("; "));
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
AgentConfig cfg = configFromMerged(*merged);
|
||||
cfg.sourcePath = path;
|
||||
if (cfg.abstract) {
|
||||
if (error) {
|
||||
*error = QStringLiteral("Agent '%1' is abstract — extend it instead of "
|
||||
"loading it directly").arg(name);
|
||||
*error = QStringLiteral(
|
||||
"Agent '%1' is abstract — extend it instead of "
|
||||
"loading it directly")
|
||||
.arg(name);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -345,8 +368,8 @@ AgentLoader::LoadResult AgentLoader::load(const QString &qrcPrefix, const QStrin
|
||||
LoadResult result;
|
||||
QHash<QString, RawEntry> raw;
|
||||
|
||||
scanDir(qrcPrefix, /*isUserLayer=*/false, raw, result.errors, &result.warnings);
|
||||
scanDir(userDir, /*isUserLayer=*/true, raw, result.errors, &result.warnings);
|
||||
scanDir(qrcPrefix, false, raw, result.errors, &result.warnings);
|
||||
scanDir(userDir, true, raw, result.errors, &result.warnings);
|
||||
|
||||
for (auto it = raw.constBegin(); it != raw.constEnd(); ++it)
|
||||
result.sourcePathByName.insert(it.key(), it.value().filePath);
|
||||
@@ -355,10 +378,11 @@ AgentLoader::LoadResult AgentLoader::load(const QString &qrcPrefix, const QStrin
|
||||
const QString &name = it.key();
|
||||
|
||||
QSet<QString> visiting;
|
||||
const QJsonObject merged = resolveExtends(name, raw, visiting, result.errors);
|
||||
if (merged.isEmpty()) continue;
|
||||
const auto merged = resolveExtends(name, raw, visiting, result.errors);
|
||||
if (!merged)
|
||||
continue;
|
||||
|
||||
AgentConfig cfg = configFromMerged(merged);
|
||||
AgentConfig cfg = configFromMerged(*merged);
|
||||
cfg.sourcePath = it.value().filePath;
|
||||
|
||||
if (cfg.abstract) continue;
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <vector>
|
||||
|
||||
#include "AgentConfig.hpp"
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@ QRegularExpression compiledGlob(const QString &pattern)
|
||||
const auto it = cache.constFind(pattern);
|
||||
if (it != cache.constEnd())
|
||||
return *it;
|
||||
const QRegularExpression re(
|
||||
QRegularExpression::anchoredPattern(
|
||||
QRegularExpression::wildcardToRegularExpression(
|
||||
pattern, QRegularExpression::NonPathWildcardConversion)),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
const QRegularExpression
|
||||
re(QRegularExpression::anchoredPattern(
|
||||
QRegularExpression::wildcardToRegularExpression(
|
||||
pattern, QRegularExpression::NonPathWildcardConversion)),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
cache.insert(pattern, re);
|
||||
return re;
|
||||
}
|
||||
@@ -67,11 +67,9 @@ bool matchesPathPatterns(const QStringList &patterns, const QString &filePath)
|
||||
bool matchesProjectNames(const QStringList &names, const QString &projectName)
|
||||
{
|
||||
if (names.isEmpty())
|
||||
return true; // dimension unconstrained
|
||||
return true;
|
||||
if (projectName.isEmpty())
|
||||
return false;
|
||||
// Project names are user-facing identifiers, not paths — case
|
||||
// sensitive comparison matches what ProjectExplorer hands us.
|
||||
return names.contains(projectName);
|
||||
}
|
||||
|
||||
@@ -80,7 +78,7 @@ bool matchesProjectNames(const QStringList &names, const QString &projectName)
|
||||
bool matches(const AgentConfig::Match &m, const Context &ctx)
|
||||
{
|
||||
if (m.isEmpty())
|
||||
return true; // explicit catch-all
|
||||
return true;
|
||||
return matchesFilePatterns(m.filePatterns, ctx.filePath)
|
||||
&& matchesPathPatterns(m.pathPatterns, ctx.filePath)
|
||||
&& matchesProjectNames(m.projectNames, ctx.projectName);
|
||||
@@ -92,7 +90,7 @@ QString pickAgent(
|
||||
for (const QString &name : roster) {
|
||||
const AgentConfig *cfg = factory.configByName(name);
|
||||
if (!cfg)
|
||||
continue; // stale roster entry — silently skip
|
||||
continue;
|
||||
if (matches(cfg->match, ctx))
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -61,11 +61,18 @@ QString expandAndResolvePath(const QString &raw, const Bindings &b)
|
||||
return p;
|
||||
}
|
||||
|
||||
bool hasUnresolvedVars(const QString &p)
|
||||
{
|
||||
return p.contains(QStringLiteral("${PROJECT_DIR}"))
|
||||
|| p.contains(QStringLiteral("${CONFIG_DIR}"));
|
||||
}
|
||||
|
||||
[[noreturn]] void throwOutsideRoots(const char *fn, const QString &path)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
QStringLiteral("%1: path is outside the allowed read roots "
|
||||
"(the project directory, ~/qodeassist, or bundled :/ resources): %2")
|
||||
QStringLiteral(
|
||||
"%1: path is outside the allowed read roots "
|
||||
"(the project directory, ~/qodeassist, or bundled :/ resources): %2")
|
||||
.arg(QString::fromLatin1(fn), path)
|
||||
.toStdString());
|
||||
}
|
||||
@@ -77,6 +84,13 @@ void registerReadFile(inja::Environment &env, const Bindings &b)
|
||||
const QString path
|
||||
= expandAndResolvePath(QString::fromStdString(args.at(0)->get<std::string>()), caps);
|
||||
|
||||
if (hasUnresolvedVars(path)) {
|
||||
throw std::runtime_error(QStringLiteral(
|
||||
"read_file: ${PROJECT_DIR}/${CONFIG_DIR} is not available "
|
||||
"(no project open?): %1")
|
||||
.arg(path)
|
||||
.toStdString());
|
||||
}
|
||||
if (!isPathAllowed(path, caps))
|
||||
throwOutsideRoots("read_file", path);
|
||||
|
||||
@@ -97,6 +111,8 @@ void registerFileExists(inja::Environment &env, const Bindings &b)
|
||||
env.add_callback("file_exists", 1, [caps](inja::Arguments &args) -> nlohmann::json {
|
||||
const QString p
|
||||
= expandAndResolvePath(QString::fromStdString(args.at(0)->get<std::string>()), caps);
|
||||
if (hasUnresolvedVars(p))
|
||||
return false;
|
||||
if (!isPathAllowed(p, caps))
|
||||
throwOutsideRoots("file_exists", p);
|
||||
return QFileInfo::exists(p);
|
||||
@@ -110,6 +126,8 @@ void registerReadDir(inja::Environment &env, const Bindings &b)
|
||||
env.add_callback("read_dir", 1, [caps](inja::Arguments &args) -> nlohmann::json {
|
||||
const QString p
|
||||
= expandAndResolvePath(QString::fromStdString(args.at(0)->get<std::string>()), caps);
|
||||
if (hasUnresolvedVars(p))
|
||||
return nlohmann::json::array();
|
||||
if (!isPathAllowed(p, caps))
|
||||
throwOutsideRoots("read_dir", p);
|
||||
QDir dir(p);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
<file>openai_completion.toml</file>
|
||||
<file>openai_compression.toml</file>
|
||||
<file>openai_quick_refactor.toml</file>
|
||||
<file>deepseek_chat.toml</file>
|
||||
<file>qwen_chat.toml</file>
|
||||
<file>google_base_chat.toml</file>
|
||||
<file>google_chat.toml</file>
|
||||
<file>google_completion.toml</file>
|
||||
|
||||
16
sources/agents/deepseek_chat.toml
Normal file
16
sources/agents/deepseek_chat.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "DeepSeek Chat"
|
||||
description = "DeepSeek coding chat (deepseek-chat, V4 family) over the OpenAI-compatible Chat Completions API — conversational assistant with IDE tool use."
|
||||
|
||||
provider_instance = "DeepSeek"
|
||||
model = "deepseek-chat"
|
||||
enable_tools = true
|
||||
tags = ["chat", "deepseek", "cloud"]
|
||||
|
||||
system_prompt = """{{ read_file(":/roles/qt-cpp-developer.md") }}"""
|
||||
|
||||
[body]
|
||||
max_tokens = 8192
|
||||
temperature = 0.3
|
||||
@@ -12,11 +12,11 @@ tags = ["chat", "ollama", "local", "16gb"]
|
||||
system_prompt = """{{ read_file(":/roles/agentic-coder.md") }}"""
|
||||
|
||||
[body]
|
||||
think = true
|
||||
think = true
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
temperature = 1.0
|
||||
top_p = 0.95
|
||||
top_k = 64
|
||||
num_predict = 8096
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -2,14 +2,16 @@ schema_version = 1
|
||||
|
||||
extends = "Ollama Base Chat"
|
||||
name = "Ollama Chat — Simple"
|
||||
description = "Local Ollama coding chat for any model — plain conversational assistant, no tools, no thinking (Qwen2.5-Coder 7B by default)."
|
||||
description = "Local Ollama coding chat for any model — plain conversational assistant, no tools, no thinking (Qwen3.5 4B by default)."
|
||||
|
||||
model = "qwen3.5:4b"
|
||||
tags = ["chat", "ollama", "local", "8gb"]
|
||||
|
||||
system_prompt = """{{ read_file(":/roles/qt-cpp-developer.md") }}"""
|
||||
|
||||
[body]
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 2048
|
||||
temperature = 0.7
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -12,8 +12,8 @@ tags = ["chat", "ollama", "local", "16gb"]
|
||||
system_prompt = """{{ read_file(":/roles/agentic-coder.md") }}"""
|
||||
|
||||
[body]
|
||||
think = true
|
||||
think = true
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 8192
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -15,6 +15,7 @@ system_prompt = """
|
||||
{{ read_file(":/tasks/code-completion.md") }}"""
|
||||
|
||||
[body]
|
||||
keep_alive = "5m"
|
||||
messages = """
|
||||
[
|
||||
{% if existsIn(ctx, "system_prompt") %}
|
||||
@@ -27,5 +28,4 @@ messages = """
|
||||
[body.options]
|
||||
num_predict = 256
|
||||
temperature = 0.2
|
||||
keep_alive = "5m"
|
||||
stop = ["</code_context>"]
|
||||
|
||||
@@ -7,7 +7,9 @@ description = "Native fill-in-the-middle completion — uses the model's OWN FIM
|
||||
model = "qwen2.5-coder:7b-base-q5_K_M"
|
||||
tags = ["completion", "ollama", "local", "fim", "8gb"]
|
||||
|
||||
[body]
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 256
|
||||
temperature = 0
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -11,10 +11,10 @@ tags = ["compression", "ollama", "local", "16gb"]
|
||||
system_prompt = """{{ read_file(":/tasks/chat-compressor.md") }}"""
|
||||
|
||||
[body]
|
||||
think = false
|
||||
think = false
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 2048
|
||||
temperature = 0.3
|
||||
num_ctx = 8192
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -11,10 +11,10 @@ tags = ["compression", "ollama", "local", "32gb"]
|
||||
system_prompt = """{{ read_file(":/tasks/chat-compressor.md") }}"""
|
||||
|
||||
[body]
|
||||
think = false
|
||||
think = false
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 2048
|
||||
temperature = 0.3
|
||||
num_ctx = 24576
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -11,10 +11,10 @@ tags = ["compression", "ollama", "local", "8gb"]
|
||||
system_prompt = """{{ read_file(":/tasks/chat-compressor.md") }}"""
|
||||
|
||||
[body]
|
||||
think = false
|
||||
think = false
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 2048
|
||||
temperature = 0.3
|
||||
num_ctx = 8192
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -12,8 +12,8 @@ tags = ["refactor", "ollama", "local", "16gb"]
|
||||
system_prompt = """{{ read_file(":/tasks/quick-refactor.md") }}"""
|
||||
|
||||
[body]
|
||||
think = true
|
||||
think = true
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 4096
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -12,8 +12,8 @@ tags = ["refactor", "ollama", "local", "16gb"]
|
||||
system_prompt = """{{ read_file(":/tasks/quick-refactor.md") }}"""
|
||||
|
||||
[body]
|
||||
think = true
|
||||
think = true
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 4096
|
||||
keep_alive = "5m"
|
||||
|
||||
@@ -10,7 +10,9 @@ tags = ["refactor", "ollama", "local", "8gb"]
|
||||
|
||||
system_prompt = """{{ read_file(":/tasks/quick-refactor.md") }}"""
|
||||
|
||||
[body]
|
||||
keep_alive = "5m"
|
||||
|
||||
[body.options]
|
||||
num_predict = 2048
|
||||
temperature = 0.2
|
||||
keep_alive = "5m"
|
||||
|
||||
16
sources/agents/qwen_chat.toml
Normal file
16
sources/agents/qwen_chat.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "Qwen Chat"
|
||||
description = "Alibaba Qwen coding chat (qwen-plus stable alias, currently the Qwen3.6 Plus family) over the DashScope OpenAI-compatible Chat Completions API — conversational assistant with IDE tool use."
|
||||
|
||||
provider_instance = "Qwen"
|
||||
model = "qwen-plus"
|
||||
enable_tools = true
|
||||
tags = ["chat", "qwen", "cloud"]
|
||||
|
||||
system_prompt = """{{ read_file(":/roles/qt-cpp-developer.md") }}"""
|
||||
|
||||
[body]
|
||||
max_tokens = 8192
|
||||
temperature = 0.3
|
||||
Reference in New Issue
Block a user