mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:20:43 +00:00
fix(auto-reply): keep consumed reset triggers out of prompt
This commit is contained in:
@@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Fixes
|
||||
|
||||
- Plugins/inspector: keep bundled plugin runtime capture quiet and config-tolerant for Codex, memory-lancedb, Feishu, Mattermost, QQBot, and Tlon so plugin-inspector JSON checks can validate the full bundled set. Thanks @vincentkoc.
|
||||
- Slack/auto-reply: keep fully consumed text reset triggers such as `new session` out of `BodyForAgent` after directive cleanup, so configured Slack reset phrases do not leak into the fresh model turn. Fixes #73137. Thanks @neeravmakwana.
|
||||
- Gateway/startup: start chat channels without waiting for primary model prewarm, keeping model warmup bounded in the background so Slack and other channels come online promptly when provider discovery is slow. Supersedes #73420. Thanks @dorukardahan.
|
||||
- Gateway/install: carry env-backed config SecretRefs such as `channels.discord.token` into generated service environments when they are present only in the installing shell, while keeping gateway auth SecretRefs non-persisted. Fixes #67817; supersedes #73426. Thanks @wdimaculangan and @ztexydt-cqh.
|
||||
- Auto-reply/commands: stop bare `/reset` and `/new` after reset hooks acknowledge the command, so non-ACP channels no longer fall through into empty provider calls while `/reset <message>` and `/new <message>` still seed the next model turn. Fixes #73367 and #73412. Thanks @hoyanhan, @wenxu007, and @amdhelper.
|
||||
|
||||
@@ -128,6 +128,7 @@ async function resolveHelloWithModelDefaults(params: {
|
||||
groupResolution: undefined,
|
||||
isGroup: false,
|
||||
triggerBodyNormalized: "hello",
|
||||
resetTriggered: false,
|
||||
commandAuthorized: false,
|
||||
defaultProvider: "openai",
|
||||
defaultModel: "gpt-4o-mini",
|
||||
@@ -302,6 +303,7 @@ describe("resolveReplyDirectives", () => {
|
||||
groupResolution: undefined,
|
||||
isGroup: false,
|
||||
triggerBodyNormalized: "hello",
|
||||
resetTriggered: false,
|
||||
commandAuthorized: false,
|
||||
defaultProvider: "openai",
|
||||
defaultModel: "gpt-4o-mini",
|
||||
@@ -393,6 +395,7 @@ describe("resolveReplyDirectives", () => {
|
||||
groupResolution: undefined,
|
||||
isGroup: false,
|
||||
triggerBodyNormalized: "/trace on",
|
||||
resetTriggered: false,
|
||||
commandAuthorized: true,
|
||||
defaultProvider: "openai",
|
||||
defaultModel: "gpt-4o-mini",
|
||||
@@ -461,4 +464,69 @@ describe("resolveReplyDirectives", () => {
|
||||
});
|
||||
expect(resolveDefaultReasoningLevel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keeps consumed text reset triggers empty after directive cleanup", async () => {
|
||||
const sessionCtx = {
|
||||
Body: "",
|
||||
BodyStripped: "",
|
||||
BodyForAgent: "",
|
||||
BodyForCommands: "new session",
|
||||
CommandBody: "new session",
|
||||
Provider: "slack",
|
||||
Surface: "slack",
|
||||
} as TemplateContext;
|
||||
|
||||
const result = await resolveReplyDirectives({
|
||||
ctx: buildTestCtx({
|
||||
Body: "new session",
|
||||
BodyForAgent: "new session",
|
||||
BodyForCommands: "new session",
|
||||
CommandBody: "new session",
|
||||
CommandAuthorized: true,
|
||||
Provider: "slack",
|
||||
Surface: "slack",
|
||||
}),
|
||||
cfg: {
|
||||
session: {
|
||||
resetTriggers: ["/new", "/reset", "new session"],
|
||||
},
|
||||
},
|
||||
agentId: "main",
|
||||
agentDir: "/tmp/main-agent",
|
||||
workspaceDir: "/tmp",
|
||||
agentCfg: {},
|
||||
sessionCtx,
|
||||
sessionEntry: makeSessionEntry(),
|
||||
sessionStore: {
|
||||
"agent:main:slack:C123": makeSessionEntry(),
|
||||
},
|
||||
sessionKey: "agent:main:slack:C123",
|
||||
storePath: "/tmp/sessions.json",
|
||||
sessionScope: "per-sender",
|
||||
groupResolution: undefined,
|
||||
isGroup: false,
|
||||
triggerBodyNormalized: "new session",
|
||||
resetTriggered: true,
|
||||
commandAuthorized: true,
|
||||
defaultProvider: "openai",
|
||||
defaultModel: "gpt-4o-mini",
|
||||
aliasIndex: { byAlias: new Map(), byKey: new Map() },
|
||||
provider: "openai",
|
||||
model: "gpt-4o-mini",
|
||||
hasResolvedHeartbeatModelOverride: false,
|
||||
typing: makeTypingController(),
|
||||
opts: undefined,
|
||||
skillFilter: undefined,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
kind: "continue",
|
||||
result: expect.objectContaining({
|
||||
cleanedBody: "",
|
||||
}),
|
||||
});
|
||||
expect(sessionCtx.Body).toBe("");
|
||||
expect(sessionCtx.BodyForAgent).toBe("");
|
||||
expect(sessionCtx.BodyStripped).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -156,6 +156,7 @@ export async function resolveReplyDirectives(params: {
|
||||
groupResolution: Parameters<typeof resolveGroupRequireMention>[0]["groupResolution"];
|
||||
isGroup: boolean;
|
||||
triggerBodyNormalized: string;
|
||||
resetTriggered: boolean;
|
||||
commandAuthorized: boolean;
|
||||
defaultProvider: string;
|
||||
defaultModel: string;
|
||||
@@ -183,6 +184,7 @@ export async function resolveReplyDirectives(params: {
|
||||
groupResolution,
|
||||
isGroup,
|
||||
triggerBodyNormalized,
|
||||
resetTriggered,
|
||||
commandAuthorized,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
@@ -335,6 +337,9 @@ export async function resolveReplyDirectives(params: {
|
||||
const existingBody = sessionCtx.BodyStripped ?? sessionCtx.Body ?? "";
|
||||
let cleanedBody = (() => {
|
||||
if (!existingBody) {
|
||||
if (resetTriggered) {
|
||||
return "";
|
||||
}
|
||||
return parsedDirectives.cleaned;
|
||||
}
|
||||
if (!sessionCtx.CommandBody && !sessionCtx.RawBody) {
|
||||
|
||||
@@ -469,6 +469,7 @@ export async function getReplyFromConfig(
|
||||
groupResolution,
|
||||
isGroup,
|
||||
triggerBodyNormalized,
|
||||
resetTriggered,
|
||||
commandAuthorized,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
|
||||
Reference in New Issue
Block a user