mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-06-14 02:09:22 -04:00
refactor: final Agent loader
This commit is contained in:
@@ -48,7 +48,6 @@ struct AgentConfig
|
||||
bool hidden = false;
|
||||
|
||||
QString sourcePath;
|
||||
bool overridesBundled = false;
|
||||
bool isUserSource() const { return !sourcePath.startsWith(QLatin1StringView{":/"}); }
|
||||
|
||||
static QString validate(const AgentConfig &config);
|
||||
|
||||
@@ -59,6 +59,7 @@ void AgentFactory::reload()
|
||||
Q_ASSERT(thread() == QThread::currentThread());
|
||||
clear();
|
||||
|
||||
QDir().mkpath(userAgentsDir());
|
||||
auto result = Agents::AgentLoader::load(agentQrcPrefix(), userAgentsDir());
|
||||
for (const QString &err : result.errors)
|
||||
LOG_MESSAGE(QString("[Agents] error: %1").arg(err));
|
||||
|
||||
@@ -145,16 +145,49 @@ struct RawEntry
|
||||
{
|
||||
QJsonObject obj;
|
||||
QString filePath;
|
||||
bool overridesBundled = false;
|
||||
bool isUserLayer = false;
|
||||
};
|
||||
|
||||
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("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));
|
||||
}
|
||||
}
|
||||
const QJsonObject matchObj = obj.value("match").toObject();
|
||||
for (auto it = matchObj.constBegin(); it != matchObj.constEnd(); ++it) {
|
||||
if (!kMatchKeys.contains(it.key())) {
|
||||
warnings.append(QStringLiteral("Unknown key 'match.%1' in %2 — ignored (typo?)")
|
||||
.arg(it.key(), filePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scanDir(
|
||||
const QString &dir,
|
||||
bool isUserLayer,
|
||||
QHash<QString, RawEntry> &raw,
|
||||
QStringList &errors)
|
||||
QStringList &errors,
|
||||
QStringList *warnings)
|
||||
{
|
||||
if (dir.isEmpty()) return;
|
||||
QDir d(dir);
|
||||
@@ -173,11 +206,39 @@ void scanDir(
|
||||
errors.append(QStringLiteral("Agent at %1 has no 'name'").arg(fullPath));
|
||||
continue;
|
||||
}
|
||||
const bool overrides = isUserLayer && raw.contains(name);
|
||||
raw.insert(name, {*objOpt, fullPath, overrides});
|
||||
if (warnings)
|
||||
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));
|
||||
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));
|
||||
}
|
||||
raw.insert(name, {*objOpt, fullPath, isUserLayer});
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject mergeChild(const QJsonObject &parentMerged, const QJsonObject &self, const QString &name)
|
||||
{
|
||||
QJsonObject merged = deepMerge(parentMerged, self);
|
||||
merged["name"] = name;
|
||||
for (const QString &key : {QStringLiteral("abstract"), QStringLiteral("hidden")}) {
|
||||
if (self.contains(key))
|
||||
merged[key] = self.value(key);
|
||||
else
|
||||
merged.remove(key);
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
QJsonObject resolveExtends(
|
||||
const QString &name,
|
||||
const QHash<QString, RawEntry> &raw,
|
||||
@@ -196,7 +257,7 @@ QJsonObject resolveExtends(
|
||||
return {};
|
||||
}
|
||||
if (!raw.contains(name)) {
|
||||
errors.append(QStringLiteral("Unknown parent agent '%1'").arg(name));
|
||||
errors.append(QStringLiteral("Unknown agent '%1'").arg(name));
|
||||
return {};
|
||||
}
|
||||
visiting.insert(name);
|
||||
@@ -204,15 +265,15 @@ QJsonObject resolveExtends(
|
||||
QJsonObject self = raw.value(name).obj;
|
||||
const QString parent = self.value("extends").toString();
|
||||
if (!parent.isEmpty()) {
|
||||
if (!raw.contains(parent)) {
|
||||
errors.append(QStringLiteral("Agent '%1' extends unknown agent '%2' (%3)")
|
||||
.arg(name, parent, raw.value(name).filePath));
|
||||
visiting.remove(name);
|
||||
return {};
|
||||
}
|
||||
const QJsonObject parentMerged
|
||||
= resolveExtends(parent, raw, visiting, errors, depth + 1);
|
||||
QJsonObject merged = deepMerge(parentMerged, self);
|
||||
merged["name"] = name;
|
||||
if (self.contains("abstract"))
|
||||
merged["abstract"] = self.value("abstract");
|
||||
else
|
||||
merged.remove("abstract");
|
||||
self = merged;
|
||||
self = mergeChild(parentMerged, self, name);
|
||||
}
|
||||
visiting.remove(name);
|
||||
return self;
|
||||
@@ -224,7 +285,7 @@ std::optional<AgentConfig> AgentLoader::parseFile(
|
||||
const QString &path,
|
||||
const QString &qrcPrefix,
|
||||
QString *error,
|
||||
QStringList * /*warnings*/)
|
||||
QStringList *warnings)
|
||||
{
|
||||
auto objOpt = parseTomlFile(path, error);
|
||||
if (!objOpt) return std::nullopt;
|
||||
@@ -234,12 +295,14 @@ std::optional<AgentConfig> AgentLoader::parseFile(
|
||||
if (error) *error = QStringLiteral("Agent at %1 has no 'name'").arg(path);
|
||||
return std::nullopt;
|
||||
}
|
||||
if (warnings)
|
||||
lintUnknownKeys(*objOpt, path, *warnings);
|
||||
|
||||
QHash<QString, RawEntry> raw;
|
||||
QStringList scanErrors;
|
||||
scanDir(qrcPrefix, /*isUserLayer=*/false, raw, scanErrors);
|
||||
scanDir(QFileInfo(path).absolutePath(), /*isUserLayer=*/true, raw, scanErrors);
|
||||
raw.insert(name, {*objOpt, path, raw.contains(name)});
|
||||
scanDir(qrcPrefix, /*isUserLayer=*/false, raw, scanErrors, nullptr);
|
||||
scanDir(QFileInfo(path).absolutePath(), /*isUserLayer=*/true, raw, scanErrors, nullptr);
|
||||
raw.insert(name, {*objOpt, path, true});
|
||||
|
||||
QSet<QString> visiting;
|
||||
QStringList resolveErrors;
|
||||
@@ -270,8 +333,8 @@ AgentLoader::LoadResult AgentLoader::load(const QString &qrcPrefix, const QStrin
|
||||
LoadResult result;
|
||||
QHash<QString, RawEntry> raw;
|
||||
|
||||
scanDir(qrcPrefix, /*isUserLayer=*/false, raw, result.errors);
|
||||
scanDir(userDir, /*isUserLayer=*/true, raw, result.errors);
|
||||
scanDir(qrcPrefix, /*isUserLayer=*/false, raw, result.errors, &result.warnings);
|
||||
scanDir(userDir, /*isUserLayer=*/true, raw, result.errors, &result.warnings);
|
||||
|
||||
for (auto it = raw.constBegin(); it != raw.constEnd(); ++it) {
|
||||
const QString &name = it.key();
|
||||
@@ -282,7 +345,6 @@ AgentLoader::LoadResult AgentLoader::load(const QString &qrcPrefix, const QStrin
|
||||
|
||||
AgentConfig cfg = configFromMerged(merged);
|
||||
cfg.sourcePath = it.value().filePath;
|
||||
cfg.overridesBundled = it.value().overridesBundled;
|
||||
|
||||
if (cfg.abstract) continue;
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "AgentRouter.hpp"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QHash>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "AgentFactory.hpp"
|
||||
@@ -13,16 +16,29 @@ namespace QodeAssist::AgentRouter {
|
||||
|
||||
namespace {
|
||||
|
||||
QRegularExpression compiledGlob(const QString &pattern)
|
||||
{
|
||||
static QHash<QString, QRegularExpression> cache;
|
||||
static QMutex mutex;
|
||||
QMutexLocker lock(&mutex);
|
||||
const auto it = cache.constFind(pattern);
|
||||
if (it != cache.constEnd())
|
||||
return *it;
|
||||
const QRegularExpression re(
|
||||
QRegularExpression::anchoredPattern(
|
||||
QRegularExpression::wildcardToRegularExpression(
|
||||
pattern, QRegularExpression::NonPathWildcardConversion)),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
cache.insert(pattern, re);
|
||||
return re;
|
||||
}
|
||||
|
||||
bool matchesAnyGlob(const QStringList &patterns, const QString &subject)
|
||||
{
|
||||
if (subject.isEmpty())
|
||||
return false;
|
||||
for (const QString &pat : patterns) {
|
||||
const QRegularExpression re(
|
||||
QRegularExpression::anchoredPattern(
|
||||
QRegularExpression::wildcardToRegularExpression(
|
||||
pat, QRegularExpression::NonPathWildcardConversion)),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
const QRegularExpression re = compiledGlob(pat);
|
||||
if (re.isValid() && re.match(subject).hasMatch())
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,15 @@
|
||||
<file>google_base_chat.toml</file>
|
||||
<file>ollama_base_chat.toml</file>
|
||||
<file>ollama_base_fim.toml</file>
|
||||
<file>mistral_base_chat.toml</file>
|
||||
<file>codestral_base_chat.toml</file>
|
||||
<file>codestral_fim_base.toml</file>
|
||||
<file>openrouter_base_chat.toml</file>
|
||||
<file>lmstudio_base_chat.toml</file>
|
||||
<file>lmstudio_responses_base.toml</file>
|
||||
<file>llamacpp_base_chat.toml</file>
|
||||
<file>ollama_openai_base_chat.toml</file>
|
||||
<file>openai_compatible_base_chat.toml</file>
|
||||
|
||||
<file>openai_chat.toml</file>
|
||||
<file>openai_compatible_chat.toml</file>
|
||||
@@ -35,8 +44,8 @@
|
||||
<file>ollama_gemma4_e4b_chat.toml</file>
|
||||
<file>ollama_codellama_7b_code_fim.toml</file>
|
||||
<file>ollama_codellama_13b_qml_fim.toml</file>
|
||||
<file>ollama_qwen25_coder_fim.toml</file>
|
||||
|
||||
<file>claude_sonnet_chat.toml</file>
|
||||
<file>claude_sonnet46_chat.toml</file>
|
||||
<file>claude_haiku45_chat.toml</file>
|
||||
<file>claude_opus_max.toml</file>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "Anthropic Base Chat"
|
||||
name = "Claude Sonnet Chat"
|
||||
description = "Anthropic Claude Sonnet 4.6 (Messages API) — coding chat assistant with thinking."
|
||||
|
||||
model = "claude-sonnet-4-6"
|
||||
|
||||
enable_thinking = true
|
||||
tags = ["chat", "claude", "anthropic", "cloud"]
|
||||
|
||||
[body]
|
||||
max_tokens = 8192
|
||||
thinking = { type = "enabled", budget_tokens = 4096 }
|
||||
11
sources/agents/codestral_base_chat.toml
Normal file
11
sources/agents/codestral_base_chat.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "Codestral Base Chat"
|
||||
description = "Mistral Codestral Chat Completions. Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "Codestral"
|
||||
endpoint = "/v1/chat/completions"
|
||||
|
||||
tags = ["chat", "codestral", "mistral", "cloud"]
|
||||
@@ -1,11 +1,7 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "Codestral Base Chat"
|
||||
name = "Codestral Chat"
|
||||
description = "Mistral Codestral (Chat Completions API) — coding chat assistant."
|
||||
|
||||
provider_instance = "Codestral"
|
||||
endpoint = "/v1/chat/completions"
|
||||
model = "codestral-latest"
|
||||
|
||||
tags = ["chat", "codestral", "mistral", "cloud"]
|
||||
model = "codestral-latest"
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "Codestral FIM Base"
|
||||
name = "Codestral FIM"
|
||||
description = "Mistral Codestral fill-in-the-middle code completion (/v1/fim/completions)."
|
||||
|
||||
provider_instance = "Mistral AI"
|
||||
endpoint = "/v1/fim/completions"
|
||||
model = "codestral-latest"
|
||||
model = "codestral-latest"
|
||||
|
||||
enable_thinking = false
|
||||
enable_tools = false
|
||||
tags = ["fim", "codestral", "mistral", "cloud", "completion"]
|
||||
|
||||
[body]
|
||||
max_tokens = 256
|
||||
temperature = 0.2
|
||||
stream = true
|
||||
prompt = """{{ tojson(ctx.prefix) }}"""
|
||||
suffix = """{% if existsIn(ctx, "suffix") %}{{ tojson(ctx.suffix) }}{% endif %}"""
|
||||
|
||||
17
sources/agents/codestral_fim_base.toml
Normal file
17
sources/agents/codestral_fim_base.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
schema_version = 1
|
||||
|
||||
name = "Codestral FIM Base"
|
||||
description = "Mistral fill-in-the-middle completion (/v1/fim/completions). Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "Mistral AI"
|
||||
endpoint = "/v1/fim/completions"
|
||||
|
||||
tags = ["fim", "mistral", "cloud", "completion"]
|
||||
|
||||
[body]
|
||||
max_tokens = 256
|
||||
temperature = 0.2
|
||||
stream = true
|
||||
prompt = """{{ tojson(ctx.prefix) }}"""
|
||||
suffix = """{% if existsIn(ctx, "suffix") %}{{ tojson(ctx.suffix) }}{% endif %}"""
|
||||
11
sources/agents/llamacpp_base_chat.toml
Normal file
11
sources/agents/llamacpp_base_chat.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "llama.cpp Base Chat"
|
||||
description = "llama.cpp server (OpenAI-compatible Chat Completions). Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "llama.cpp"
|
||||
endpoint = "/v1/chat/completions"
|
||||
|
||||
tags = ["chat", "llamacpp", "local"]
|
||||
@@ -1,11 +1,7 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "llama.cpp Base Chat"
|
||||
name = "llama.cpp Chat"
|
||||
description = "llama.cpp server (OpenAI-compatible Chat Completions) — local coding chat assistant."
|
||||
|
||||
provider_instance = "llama.cpp"
|
||||
endpoint = "/v1/chat/completions"
|
||||
model = "llama"
|
||||
|
||||
tags = ["chat", "llamacpp", "local"]
|
||||
model = "llama"
|
||||
|
||||
11
sources/agents/lmstudio_base_chat.toml
Normal file
11
sources/agents/lmstudio_base_chat.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "LM Studio Base Chat"
|
||||
description = "LM Studio Chat Completions. Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "LM Studio (Chat Completions)"
|
||||
endpoint = "/v1/chat/completions"
|
||||
|
||||
tags = ["chat", "lmstudio", "local"]
|
||||
@@ -1,11 +1,7 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "LM Studio Base Chat"
|
||||
name = "LM Studio Chat"
|
||||
description = "LM Studio (Chat Completions API) — local coding chat assistant."
|
||||
|
||||
provider_instance = "LM Studio (Chat Completions)"
|
||||
endpoint = "/v1/chat/completions"
|
||||
model = "local-model"
|
||||
|
||||
tags = ["chat", "lmstudio", "local"]
|
||||
model = "local-model"
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Responses Base"
|
||||
extends = "LM Studio Responses Base"
|
||||
name = "LM Studio Responses"
|
||||
description = "LM Studio (Responses API) — local coding chat assistant."
|
||||
|
||||
provider_instance = "LM Studio (Responses API)"
|
||||
endpoint = "/v1/responses"
|
||||
model = "local-model"
|
||||
|
||||
tags = ["chat", "lmstudio", "responses", "local"]
|
||||
model = "local-model"
|
||||
|
||||
11
sources/agents/lmstudio_responses_base.toml
Normal file
11
sources/agents/lmstudio_responses_base.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Responses Base"
|
||||
name = "LM Studio Responses Base"
|
||||
description = "LM Studio Responses API. Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "LM Studio (Responses API)"
|
||||
endpoint = "/v1/responses"
|
||||
|
||||
tags = ["chat", "lmstudio", "responses", "local"]
|
||||
11
sources/agents/mistral_base_chat.toml
Normal file
11
sources/agents/mistral_base_chat.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "Mistral Base Chat"
|
||||
description = "Mistral AI Chat Completions. Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "Mistral AI"
|
||||
endpoint = "/v1/chat/completions"
|
||||
|
||||
tags = ["chat", "mistral", "cloud"]
|
||||
@@ -1,11 +1,7 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "Mistral Base Chat"
|
||||
name = "Mistral Chat"
|
||||
description = "Mistral Large (Chat Completions API) — coding chat assistant."
|
||||
|
||||
provider_instance = "Mistral AI"
|
||||
endpoint = "/v1/chat/completions"
|
||||
model = "mistral-large-latest"
|
||||
|
||||
tags = ["chat", "mistral", "cloud"]
|
||||
model = "mistral-large-latest"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "Mistral Base Chat"
|
||||
name = "Mistral Medium Chat"
|
||||
description = "Mistral Medium 3.5 (Chat Completions API) — frontier coding/agentic chat."
|
||||
|
||||
provider_instance = "Mistral AI"
|
||||
endpoint = "/v1/chat/completions"
|
||||
model = "mistral-medium-latest"
|
||||
model = "mistral-medium-latest"
|
||||
|
||||
tags = ["chat", "mistral", "medium", "cloud"]
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "Mistral Base Chat"
|
||||
name = "Mistral Reasoning Chat"
|
||||
description = "Mistral Magistral Medium — native chain-of-thought reasoning model."
|
||||
|
||||
provider_instance = "Mistral AI"
|
||||
endpoint = "/v1/chat/completions"
|
||||
model = "magistral-medium-latest"
|
||||
model = "magistral-medium-latest"
|
||||
|
||||
enable_thinking = true
|
||||
tags = ["chat", "mistral", "reasoning", "cloud"]
|
||||
|
||||
11
sources/agents/ollama_openai_base_chat.toml
Normal file
11
sources/agents/ollama_openai_base_chat.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "Ollama (OpenAI-compatible) Base Chat"
|
||||
description = "Ollama via its OpenAI-compatible Chat Completions endpoint. Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "Ollama (OpenAI-compatible)"
|
||||
endpoint = "/v1/chat/completions"
|
||||
|
||||
tags = ["chat", "ollama", "local"]
|
||||
@@ -1,11 +1,7 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "Ollama (OpenAI-compatible) Base Chat"
|
||||
name = "Ollama (OpenAI-compatible) Chat"
|
||||
description = "Ollama via its OpenAI-compatible Chat Completions endpoint — local coding chat assistant."
|
||||
|
||||
provider_instance = "Ollama (OpenAI-compatible)"
|
||||
endpoint = "/v1/chat/completions"
|
||||
model = "qwen2.5-coder"
|
||||
|
||||
tags = ["chat", "ollama", "local"]
|
||||
model = "qwen2.5-coder"
|
||||
|
||||
15
sources/agents/ollama_qwen25_coder_fim.toml
Normal file
15
sources/agents/ollama_qwen25_coder_fim.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "Ollama FIM Base"
|
||||
name = "Ollama Qwen2.5-Coder FIM"
|
||||
description = "Local Qwen2.5-Coder on Ollama, FIM completion via <|fim_*|> markers."
|
||||
|
||||
model = "qwen2.5-coder"
|
||||
|
||||
tags = ["fim", "ollama", "local", "qwen"]
|
||||
|
||||
[body]
|
||||
prompt = """{% if existsIn(ctx, "suffix") and length(ctx.suffix) > 0 %}{{ tojson("<|fim_prefix|>" + ctx.prefix + "<|fim_suffix|>" + ctx.suffix + "<|fim_middle|>") }}{% else %}{{ tojson("<|fim_prefix|>" + ctx.prefix + "<|fim_middle|>") }}{% endif %}"""
|
||||
|
||||
[body.options]
|
||||
stop = ["<|endoftext|>", "<|fim_prefix|>", "<|fim_suffix|>", "<|fim_middle|>", "<|fim_pad|>", "<|repo_name|>", "<|file_sep|>"]
|
||||
10
sources/agents/openai_compatible_base_chat.toml
Normal file
10
sources/agents/openai_compatible_base_chat.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "OpenAI Compatible Base Chat"
|
||||
description = "Any OpenAI-compatible Chat Completions endpoint. Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "OpenAI Compatible"
|
||||
|
||||
tags = ["chat", "openai", "compatible"]
|
||||
@@ -1,10 +1,7 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "OpenAI Compatible Base Chat"
|
||||
name = "OpenAI Compatible Chat"
|
||||
description = "Any OpenAI-compatible Chat Completions endpoint — set the model to match your server."
|
||||
|
||||
provider_instance = "OpenAI Compatible"
|
||||
model = "default"
|
||||
|
||||
tags = ["chat", "openai", "compatible"]
|
||||
model = "default"
|
||||
|
||||
11
sources/agents/openrouter_base_chat.toml
Normal file
11
sources/agents/openrouter_base_chat.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
name = "OpenRouter Base Chat"
|
||||
description = "OpenRouter (OpenAI-compatible Chat Completions). Abstract — extend it and set model."
|
||||
abstract = true
|
||||
|
||||
provider_instance = "OpenRouter"
|
||||
endpoint = "/chat/completions"
|
||||
|
||||
tags = ["chat", "openrouter", "cloud"]
|
||||
@@ -1,11 +1,7 @@
|
||||
schema_version = 1
|
||||
|
||||
extends = "OpenAI Base Chat"
|
||||
extends = "OpenRouter Base Chat"
|
||||
name = "OpenRouter Chat"
|
||||
description = "OpenRouter (OpenAI-compatible Chat Completions) — coding chat assistant."
|
||||
|
||||
provider_instance = "OpenRouter"
|
||||
endpoint = "/chat/completions"
|
||||
model = "openai/gpt-4o"
|
||||
|
||||
tags = ["chat", "openrouter", "cloud"]
|
||||
model = "openai/gpt-4o"
|
||||
|
||||
Reference in New Issue
Block a user