mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 13:54:57 +00:00
* fix(plugins): apply before_agent_start hook systemPrompt to session (#14583) * fix(plugins): apply legacy systemPrompt override and add changelog credit --------- Co-authored-by: yinghaosang <yinghaosang@users.noreply.github.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
@@ -183,6 +183,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
- Agents/Transcripts: validate assistant tool-call names (syntax/length + registered tool allowlist) before transcript persistence and during replay sanitization so malformed failover tool names no longer poison sessions with repeated provider HTTP 400 errors. (#23324) Thanks @johnsantry.
|
- Agents/Transcripts: validate assistant tool-call names (syntax/length + registered tool allowlist) before transcript persistence and during replay sanitization so malformed failover tool names no longer poison sessions with repeated provider HTTP 400 errors. (#23324) Thanks @johnsantry.
|
||||||
- Agents/Mistral: sanitize tool-call IDs in the embedded agent loop and generate strict provider-safe pending tool-call IDs, preventing Mistral strict9 `HTTP 400` failures on tool continuations. (#23698) Thanks @echoVic.
|
- Agents/Mistral: sanitize tool-call IDs in the embedded agent loop and generate strict provider-safe pending tool-call IDs, preventing Mistral strict9 `HTTP 400` failures on tool continuations. (#23698) Thanks @echoVic.
|
||||||
- Agents/Compaction: strip stale assistant usage snapshots from pre-compaction turns when replaying history after a compaction summary so context-token estimation no longer reuses pre-compaction totals and immediately re-triggers destructive follow-up compactions. (#19127) Thanks @tedwatson.
|
- Agents/Compaction: strip stale assistant usage snapshots from pre-compaction turns when replaying history after a compaction summary so context-token estimation no longer reuses pre-compaction totals and immediately re-triggers destructive follow-up compactions. (#19127) Thanks @tedwatson.
|
||||||
|
- Agents/Hooks: honor legacy `before_agent_start` `systemPrompt` values in the embedded prompt-build path so plugin-provided system-prompt overrides are applied instead of being silently ignored. (#13475, #14583) Thanks @yinghaosang and @mushuiyu422.
|
||||||
- Agents/Replies: emit a default completion acknowledgement (`✅ Done.`) only for direct/private tool-only completions with no final assistant text, while suppressing synthetic acknowledgements for channel/group sessions and runs that already delivered output via messaging tools. (#22834) Thanks @Oldshue.
|
- Agents/Replies: emit a default completion acknowledgement (`✅ Done.`) only for direct/private tool-only completions with no final assistant text, while suppressing synthetic acknowledgements for channel/group sessions and runs that already delivered output via messaging tools. (#22834) Thanks @Oldshue.
|
||||||
- Agents/Subagents: honor `tools.subagents.tools.alsoAllow` and explicit subagent `allow` entries when resolving built-in subagent deny defaults, so explicitly granted tools (for example `sessions_send`) are no longer blocked unless re-denied in `tools.subagents.tools.deny`. (#23359) Thanks @goren-beehero.
|
- Agents/Subagents: honor `tools.subagents.tools.alsoAllow` and explicit subagent `allow` entries when resolving built-in subagent deny defaults, so explicitly granted tools (for example `sessions_send`) are no longer blocked unless re-denied in `tools.subagents.tools.deny`. (#23359) Thanks @goren-beehero.
|
||||||
- Agents/Subagents: make announce call timeouts configurable via `agents.defaults.subagents.announceTimeoutMs` and restore a 60s default to prevent false timeout failures on slower announce paths. (#22719) Thanks @Valadon.
|
- Agents/Subagents: make announce call timeouts configurable via `agents.defaults.subagents.announceTimeoutMs` and restore a 60s default to prevent false timeout failures on slower announce paths. (#22719) Thanks @Valadon.
|
||||||
|
|||||||
@@ -560,7 +560,7 @@ export async function runEmbeddedAttempt(
|
|||||||
tools,
|
tools,
|
||||||
});
|
});
|
||||||
const systemPromptOverride = createSystemPromptOverride(appendPrompt);
|
const systemPromptOverride = createSystemPromptOverride(appendPrompt);
|
||||||
const systemPromptText = systemPromptOverride();
|
let systemPromptText = systemPromptOverride();
|
||||||
|
|
||||||
const sessionLock = await acquireSessionWriteLock({
|
const sessionLock = await acquireSessionWriteLock({
|
||||||
sessionFile: params.sessionFile,
|
sessionFile: params.sessionFile,
|
||||||
@@ -1038,6 +1038,13 @@ export async function runEmbeddedAttempt(
|
|||||||
`hooks: prepended context to prompt (${hookResult.prependContext.length} chars)`,
|
`hooks: prepended context to prompt (${hookResult.prependContext.length} chars)`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const legacySystemPrompt =
|
||||||
|
typeof hookResult?.systemPrompt === "string" ? hookResult.systemPrompt.trim() : "";
|
||||||
|
if (legacySystemPrompt) {
|
||||||
|
applySystemPromptOverrideToSession(activeSession, legacySystemPrompt);
|
||||||
|
systemPromptText = legacySystemPrompt;
|
||||||
|
log.debug(`hooks: applied systemPrompt override (${legacySystemPrompt.length} chars)`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug(`embedded run prompt start: runId=${params.runId} sessionId=${params.sessionId}`);
|
log.debug(`embedded run prompt start: runId=${params.runId} sessionId=${params.sessionId}`);
|
||||||
|
|||||||
51
src/agents/pi-embedded-runner/system-prompt.test.ts
Normal file
51
src/agents/pi-embedded-runner/system-prompt.test.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import type { AgentSession } from "@mariozechner/pi-coding-agent";
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { applySystemPromptOverrideToSession, createSystemPromptOverride } from "./system-prompt.js";
|
||||||
|
|
||||||
|
function createMockSession() {
|
||||||
|
const setSystemPrompt = vi.fn();
|
||||||
|
const session = {
|
||||||
|
agent: { setSystemPrompt },
|
||||||
|
} as unknown as AgentSession;
|
||||||
|
return { session, setSystemPrompt };
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("applySystemPromptOverrideToSession", () => {
|
||||||
|
it("applies a string override to the session system prompt", () => {
|
||||||
|
const { session, setSystemPrompt } = createMockSession();
|
||||||
|
const prompt = "You are a helpful assistant with custom context.";
|
||||||
|
|
||||||
|
applySystemPromptOverrideToSession(session, prompt);
|
||||||
|
|
||||||
|
expect(setSystemPrompt).toHaveBeenCalledWith(prompt);
|
||||||
|
const mutable = session as unknown as { _baseSystemPrompt?: string };
|
||||||
|
expect(mutable._baseSystemPrompt).toBe(prompt);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("trims whitespace from string overrides", () => {
|
||||||
|
const { session, setSystemPrompt } = createMockSession();
|
||||||
|
|
||||||
|
applySystemPromptOverrideToSession(session, " padded prompt ");
|
||||||
|
|
||||||
|
expect(setSystemPrompt).toHaveBeenCalledWith("padded prompt");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("applies a function override to the session system prompt", () => {
|
||||||
|
const { session, setSystemPrompt } = createMockSession();
|
||||||
|
const override = createSystemPromptOverride("function-based prompt");
|
||||||
|
|
||||||
|
applySystemPromptOverrideToSession(session, override);
|
||||||
|
|
||||||
|
expect(setSystemPrompt).toHaveBeenCalledWith("function-based prompt");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets _rebuildSystemPrompt that returns the override", () => {
|
||||||
|
const { session } = createMockSession();
|
||||||
|
applySystemPromptOverrideToSession(session, "rebuild test");
|
||||||
|
|
||||||
|
const mutable = session as unknown as {
|
||||||
|
_rebuildSystemPrompt?: (toolNames: string[]) => string;
|
||||||
|
};
|
||||||
|
expect(mutable._rebuildSystemPrompt?.(["tool1"])).toBe("rebuild test");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user