mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-06-14 02:09:22 -04:00
refactor: add to template agent roles
This commit is contained in:
@@ -248,6 +248,15 @@ void AgentFactory::setModelOverride(const QString &agentName, const QString &mod
|
||||
saveModelOverrides();
|
||||
}
|
||||
|
||||
QString AgentFactory::effectiveModel(const QString &agentName) const
|
||||
{
|
||||
const QString ov = m_modelOverrides.value(agentName);
|
||||
if (!ov.isEmpty())
|
||||
return ov;
|
||||
const AgentConfig *cfg = configByName(agentName);
|
||||
return cfg ? cfg->model : QString();
|
||||
}
|
||||
|
||||
namespace {
|
||||
QString modelOverridesPath()
|
||||
{
|
||||
|
||||
@@ -59,6 +59,10 @@ public:
|
||||
[[nodiscard]] QString modelOverride(const QString &agentName) const;
|
||||
void setModelOverride(const QString &agentName, const QString &model);
|
||||
|
||||
// The model that will actually be sent for this agent: the settings
|
||||
// override if set, otherwise the agent TOML's default `model`.
|
||||
[[nodiscard]] QString effectiveModel(const QString &agentName) const;
|
||||
|
||||
[[nodiscard]] Providers::ProviderInstanceFactory *instanceFactory() const noexcept;
|
||||
[[nodiscard]] Providers::ProviderSecretsStore *secretsStore() const noexcept;
|
||||
|
||||
|
||||
@@ -8,8 +8,12 @@
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QStringList>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <inja/inja.hpp>
|
||||
@@ -155,6 +159,45 @@ void registerStringHelpers(inja::Environment &env)
|
||||
});
|
||||
}
|
||||
|
||||
// Read a role's system prompt from the role JSON written by the settings Roles
|
||||
// UI (AgentRolesManager). Returns "" if the role doesn't exist.
|
||||
std::string roleSystemPrompt(const QString &id)
|
||||
{
|
||||
if (id.isEmpty())
|
||||
return {};
|
||||
const QString path
|
||||
= Core::ICore::userResourcePath(
|
||||
QStringLiteral("qodeassist/agent_roles/%1.json").arg(id))
|
||||
.toFSPathString();
|
||||
QFile f(path);
|
||||
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qWarning("[QodeAssist] agent_role: role '%s' not found at %s",
|
||||
qUtf8Printable(id), qUtf8Printable(path));
|
||||
return {};
|
||||
}
|
||||
return QJsonDocument::fromJson(f.readAll())
|
||||
.object()
|
||||
.value("systemPrompt")
|
||||
.toString()
|
||||
.toStdString();
|
||||
}
|
||||
|
||||
// Building blocks for composing a profile's `system_prompt` (alongside
|
||||
// read_file/file_exists):
|
||||
// {{ agent_role() }} — the runtime-selected role (Bindings.roleId, which
|
||||
// the chat sets; falls back to "developer")
|
||||
// {{ agent_role("<id>") }} — a specific role by id
|
||||
void registerAgentRole(inja::Environment &env, const Bindings &b)
|
||||
{
|
||||
const QString runtimeRole = b.roleId.isEmpty() ? QStringLiteral("developer") : b.roleId;
|
||||
env.add_callback("agent_role", 0, [runtimeRole](inja::Arguments &) -> nlohmann::json {
|
||||
return roleSystemPrompt(runtimeRole);
|
||||
});
|
||||
env.add_callback("agent_role", 1, [](inja::Arguments &args) -> nlohmann::json {
|
||||
return roleSystemPrompt(QString::fromStdString(args.at(0)->get<std::string>()));
|
||||
});
|
||||
}
|
||||
|
||||
void registerSandbox(inja::Environment &env)
|
||||
{
|
||||
|
||||
@@ -183,6 +226,7 @@ QString render(const QString &templateSource, const Bindings &bindings, QString
|
||||
registerFileExists(env, bindings);
|
||||
registerReadDir(env, bindings);
|
||||
registerStringHelpers(env);
|
||||
registerAgentRole(env, bindings);
|
||||
|
||||
inja::Template tpl;
|
||||
try {
|
||||
|
||||
@@ -12,6 +12,9 @@ struct Bindings
|
||||
{
|
||||
QString projectDir;
|
||||
QString homeDir;
|
||||
// Role id selected at runtime (e.g. in the chat). Used by the no-arg
|
||||
// `{{ agent_role() }}` template callback; empty falls back to "developer".
|
||||
QString roleId;
|
||||
};
|
||||
|
||||
QString render(const QString &templateSource, const Bindings &bindings,
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<file>partials/google_part.jinja</file>
|
||||
<file>partials/ollama_messages.jinja</file>
|
||||
|
||||
<file>chat_base.toml</file>
|
||||
<file>openai_base_chat.toml</file>
|
||||
<file>openai_responses_base.toml</file>
|
||||
<file>anthropic_base_chat.toml</file>
|
||||
|
||||
@@ -3,16 +3,18 @@ schema_version = 1
|
||||
name = "Anthropic Base Chat"
|
||||
description = "Anthropic Messages API request body (/v1/messages). Abstract — extend it and set model."
|
||||
abstract = true
|
||||
extends = "Chat Base"
|
||||
|
||||
provider_instance = "Claude"
|
||||
endpoint = "/v1/messages"
|
||||
enable_tools = true
|
||||
tags = ["chat", "claude", "anthropic", "cloud"]
|
||||
|
||||
system_prompt = """{{ agent_role() }}"""
|
||||
|
||||
[body]
|
||||
max_tokens = 8192
|
||||
temperature = 1
|
||||
stream = true
|
||||
system = """{% if existsIn(ctx, "system_prompt") %}{{ tojson(ctx.system_prompt) }}{% endif %}"""
|
||||
messages = """
|
||||
[ {% include "partials/anthropic_messages.jinja" %} ]
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
schema_version = 1
|
||||
|
||||
name = "Chat Base"
|
||||
description = "Shared system prompt for coding-chat agents. Abstract — not selectable."
|
||||
abstract = true
|
||||
|
||||
system_prompt = """
|
||||
You are a helpful coding assistant integrated into Qt Creator.
|
||||
Answer concisely. Prefer concrete diffs or minimal patches over rewriting
|
||||
whole files. Use markdown code blocks with language tags.
|
||||
|
||||
{% if file_exists("${PROJECT_DIR}/README.md") %}
|
||||
## Project README.md
|
||||
{{ read_file("${PROJECT_DIR}/README.md") }}
|
||||
{% endif %}
|
||||
"""
|
||||
@@ -3,12 +3,13 @@ schema_version = 1
|
||||
name = "Google Base Chat"
|
||||
description = "Google Gemini generateContent request body. Abstract — extend it and set model/endpoint."
|
||||
abstract = true
|
||||
extends = "Chat Base"
|
||||
|
||||
provider_instance = "Google AI"
|
||||
enable_tools = true
|
||||
tags = ["chat", "gemini", "google", "cloud"]
|
||||
|
||||
system_prompt = """{{ agent_role() }}"""
|
||||
|
||||
[body]
|
||||
system_instruction = """{% if existsIn(ctx, "system_prompt") %}{ "parts": [ { "text": {{ tojson(ctx.system_prompt) }} } ] }{% endif %}"""
|
||||
contents = """
|
||||
|
||||
@@ -4,7 +4,7 @@ extends = "Google Base Chat"
|
||||
name = "Gemini Chat"
|
||||
description = "Google Gemini 2.5 Flash (generateContent API) — coding chat with thinking."
|
||||
|
||||
endpoint = "/models/gemini-2.5-flash:streamGenerateContent?alt=sse"
|
||||
endpoint = "/models/${MODEL}:streamGenerateContent?alt=sse"
|
||||
model = "gemini-2.5-flash"
|
||||
|
||||
enable_thinking = true
|
||||
|
||||
@@ -3,12 +3,13 @@ schema_version = 1
|
||||
name = "Ollama Base Chat"
|
||||
description = "Ollama native /api/chat request body. Abstract — extend it and set model/options."
|
||||
abstract = true
|
||||
extends = "Chat Base"
|
||||
|
||||
provider_instance = "Ollama (Native)"
|
||||
endpoint = "/api/chat"
|
||||
tags = ["ollama", "local"]
|
||||
|
||||
system_prompt = """{{ agent_role() }}"""
|
||||
|
||||
[body]
|
||||
stream = true
|
||||
messages = """
|
||||
|
||||
@@ -3,16 +3,18 @@ schema_version = 1
|
||||
name = "OpenAI Base Chat"
|
||||
description = "OpenAI Chat Completions request body. Abstract — extend it and set provider/endpoint/model."
|
||||
abstract = true
|
||||
extends = "Chat Base"
|
||||
|
||||
provider_instance = "OpenAI (Chat Completions)"
|
||||
endpoint = "/chat/completions"
|
||||
enable_tools = true
|
||||
tags = ["chat", "openai", "cloud"]
|
||||
|
||||
system_prompt = """{{ agent_role() }}"""
|
||||
|
||||
[body]
|
||||
max_tokens = 8192
|
||||
temperature = 0.7
|
||||
stream = true
|
||||
messages = """
|
||||
[ {% include "partials/openai_messages.jinja" %} ]
|
||||
"""
|
||||
|
||||
@@ -3,16 +3,18 @@ schema_version = 1
|
||||
name = "OpenAI Responses Base"
|
||||
description = "OpenAI Responses API request body (/responses). Abstract — extend it and set provider/endpoint/model."
|
||||
abstract = true
|
||||
extends = "Chat Base"
|
||||
|
||||
provider_instance = "OpenAI (Responses API)"
|
||||
endpoint = "/responses"
|
||||
enable_tools = true
|
||||
tags = ["chat", "openai", "responses", "cloud"]
|
||||
|
||||
system_prompt = """{{ agent_role() }}"""
|
||||
|
||||
[body]
|
||||
max_output_tokens = 8192
|
||||
temperature = 0.7
|
||||
stream = true
|
||||
instructions = """{% if existsIn(ctx, "system_prompt") %}{{ tojson(ctx.system_prompt) }}{% endif %}"""
|
||||
input = """
|
||||
[ {% include "partials/openai_responses_input.jinja" %} ]
|
||||
|
||||
Reference in New Issue
Block a user