fix(settings): append Global System Prompt after provider/agent instructions (#2468)

This commit is contained in:
diegosouzapw
2026-05-21 10:52:37 -03:00
parent 298578fec1
commit afa48c64ca
2 changed files with 18 additions and 13 deletions

View File

@@ -44,21 +44,24 @@ export function injectSystemPrompt(body, promptText = null) {
const sysIdx = result.messages.findIndex((m) => m.role === "system" || m.role === "developer");
result.messages = [...result.messages];
if (sysIdx >= 0) {
// Prepend to existing system message
// Append after existing system content so the global prompt is the FINAL
// instruction — provider/agent system blocks (Kiro, OpenCode, Hermes, etc.)
// are injected into the system message later, and recency bias means the
// user's global prompt must come after them to take priority (#2468).
const msg = { ...result.messages[sysIdx] };
msg.content = text + "\n\n" + (msg.content || "");
msg.content = (msg.content || "") + "\n\n" + text;
result.messages[sysIdx] = msg;
} else {
result.messages = [{ role: "system", content: text }, ...result.messages];
}
}
// Claude format (system field)
// Claude format (system field) — append for the same reason as above (#2468).
if (result.system !== undefined) {
if (typeof result.system === "string") {
result.system = text + "\n\n" + result.system;
result.system = result.system + "\n\n" + text;
} else if (Array.isArray(result.system)) {
result.system = [{ type: "text", text }, ...result.system];
result.system = [...result.system, { type: "text", text }];
}
}

View File

@@ -30,7 +30,7 @@ test("injectSystemPrompt: adds system message when none exists", () => {
assert.equal(result.messages.length, 2);
});
test("injectSystemPrompt: prepends to existing system message", () => {
test("injectSystemPrompt: appends after existing system message (#2468)", () => {
setSystemPromptConfig({ enabled: true, prompt: "GLOBAL:" });
const body = {
messages: [
@@ -39,23 +39,24 @@ test("injectSystemPrompt: prepends to existing system message", () => {
],
};
const result = injectSystemPrompt(body);
assert.ok(result.messages[0].content.startsWith("GLOBAL:"));
assert.ok(result.messages[0].content.includes("Original prompt"));
// Global prompt must be the FINAL instruction so it wins over provider/agent blocks.
assert.ok(result.messages[0].content.startsWith("Original prompt"));
assert.ok(result.messages[0].content.trimEnd().endsWith("GLOBAL:"));
assert.equal(result.messages.length, 2);
});
test("injectSystemPrompt: Claude body.system field", () => {
test("injectSystemPrompt: Claude body.system field appends global last (#2468)", () => {
setSystemPromptConfig({ enabled: true, prompt: "GLOBAL:" });
const body = {
system: "Claude prompt",
messages: [{ role: "user", content: "hi" }],
};
const result = injectSystemPrompt(body);
assert.ok(result.system.startsWith("GLOBAL:"));
assert.ok(result.system.includes("Claude prompt"));
assert.ok(result.system.startsWith("Claude prompt"));
assert.ok(result.system.trimEnd().endsWith("GLOBAL:"));
});
test("injectSystemPrompt: Claude array system field", () => {
test("injectSystemPrompt: Claude array system field appends global last (#2468)", () => {
setSystemPromptConfig({ enabled: true, prompt: "GLOBAL:" });
const body = {
system: [{ type: "text", text: "Claude prompt" }],
@@ -63,7 +64,8 @@ test("injectSystemPrompt: Claude array system field", () => {
};
const result = injectSystemPrompt(body);
assert.ok(Array.isArray(result.system));
assert.equal(result.system[0].text, "GLOBAL:");
assert.equal(result.system[0].text, "Claude prompt");
assert.equal(result.system[result.system.length - 1].text, "GLOBAL:");
assert.equal(result.system.length, 2);
});