fix: inject group activation in system prompt

This commit is contained in:
Peter Steinberger
2025-12-23 13:32:07 +00:00
parent 96d57a18ee
commit cba12a1abd
7 changed files with 81 additions and 7 deletions

View File

@@ -142,6 +142,49 @@ describe("trigger handling", () => {
});
});
it("injects group activation context into the system prompt", async () => {
await withTempHome(async (home) => {
vi.mocked(runEmbeddedPiAgent).mockResolvedValue({
payloads: [{ text: "ok" }],
meta: {
durationMs: 1,
agentMeta: { sessionId: "s", provider: "p", model: "m" },
},
});
const res = await getReplyFromConfig(
{
Body: "hello group",
From: "123@g.us",
To: "+2000",
ChatType: "group",
SenderE164: "+2000",
GroupSubject: "Test Group",
GroupMembers: "Alice (+1), Bob (+2)",
},
{},
{
inbound: {
allowFrom: ["*"],
workspace: join(home, "clawd"),
agent: { provider: "anthropic", model: "claude-opus-4-5" },
session: { store: join(home, "sessions.json") },
groupChat: { requireMention: false },
},
},
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(text).toBe("ok");
expect(runEmbeddedPiAgent).toHaveBeenCalledOnce();
const extra =
vi.mocked(runEmbeddedPiAgent).mock.calls[0]?.[0]?.extraSystemPrompt ??
"";
expect(extra).toContain("Test Group");
expect(extra).toContain("Activation: always-on");
});
});
it("runs a greeting prompt for a bare /new", async () => {
await withTempHome(async (home) => {
vi.mocked(runEmbeddedPiAgent).mockResolvedValue({

View File

@@ -563,6 +563,7 @@ export async function getReplyFromConfig(
}
if (sessionEntry && sessionStore && sessionKey) {
sessionEntry.groupActivation = activationCommand.mode;
sessionEntry.groupActivationNeedsSystemIntro = true;
sessionEntry.updatedAt = Date.now();
sessionStore[sessionKey] = sessionEntry;
await saveSessionStore(storePath, sessionStore);
@@ -648,8 +649,11 @@ export async function getReplyFromConfig(
await startTypingLoop();
const isFirstTurnInSession = isNewSession || !systemSent;
const shouldInjectGroupIntro =
sessionCtx.ChatType === "group" &&
(isFirstTurnInSession || sessionEntry?.groupActivationNeedsSystemIntro);
const groupIntro =
isFirstTurnInSession && sessionCtx.ChatType === "group"
shouldInjectGroupIntro
? (() => {
const activation =
normalizeGroupActivation(sessionEntry?.groupActivation) ??
@@ -713,9 +717,6 @@ export async function getReplyFromConfig(
? "Note: The previous agent run was aborted by the user. Resume carefully or ask for clarification."
: "";
let prefixedBodyBase = baseBodyFinal;
if (groupIntro) {
prefixedBodyBase = `${groupIntro}\n\n${prefixedBodyBase}`;
}
if (abortedHint) {
prefixedBodyBase = `${abortedHint}\n\n${prefixedBodyBase}`;
if (sessionEntry && sessionStore && sessionKey) {
@@ -875,6 +876,7 @@ export async function getReplyFromConfig(
config: cfg,
skillsSnapshot,
prompt: commandBody,
extraSystemPrompt: groupIntro || undefined,
provider,
model,
thinkLevel: resolvedThinkLevel,
@@ -898,6 +900,19 @@ export async function getReplyFromConfig(
: undefined,
});
if (
shouldInjectGroupIntro &&
sessionEntry &&
sessionStore &&
sessionKey &&
sessionEntry.groupActivationNeedsSystemIntro
) {
sessionEntry.groupActivationNeedsSystemIntro = false;
sessionEntry.updatedAt = Date.now();
sessionStore[sessionKey] = sessionEntry;
await saveSessionStore(storePath, sessionStore);
}
const payloadArray = runResult.payloads ?? [];
if (payloadArray.length === 0) return undefined;