mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-07 22:44:16 +00:00
fix(auto-reply): move volatile inbound flags out of system metadata
Co-authored-by: aidiffuser <aidiffuser@users.noreply.github.com>
This commit is contained in:
@@ -35,6 +35,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Agents/Overflow: add Chinese context-overflow pattern detection in `isContextOverflowError` so localized provider errors route through overflow recovery paths. (#22855) Thanks @Clawborn.
|
||||
- Agents/Failover: treat HTTP 502/503/504 errors as failover-eligible transient timeouts so fallback chains can switch providers/models during upstream outages instead of retrying the same failing target. (#20999) Thanks @taw0002 and @vincentkoc.
|
||||
- Auto-reply/Inbound metadata: hide direct-chat `message_id`/`message_id_full` and sender metadata only from normalized chat type (not sender-id sentinels), preserving group metadata visibility and preventing sender-id spoofed direct-mode classification. (#24373) thanks @jd316.
|
||||
- Auto-reply/Inbound metadata: move dynamic inbound `flags` (reply/forward/thread/history) from system metadata to user-context conversation info, preventing turn-by-turn prompt-cache invalidation from flag toggles. (#21785) Thanks @aidiffuser.
|
||||
- Auto-reply/Sessions: remove auth-key labels from `/new` and `/reset` confirmation messages so session reset notices never expose API key prefixes or env-key labels in chat output. (#24384, #24409) Thanks @Clawborn.
|
||||
- Slack/Group policy: move Slack account `groupPolicy` defaulting to provider-level schema defaults so multi-account configs inherit top-level `channels.slack.groupPolicy` instead of silently overriding inheritance with per-account `allowlist`. (#17579) Thanks @ZetiMente.
|
||||
- Providers/Anthropic: skip `context-1m-*` beta injection for OAuth/subscription tokens (`sk-ant-oat-*`) while preserving OAuth-required betas, avoiding Anthropic 401 auth failures when `params.context1m` is enabled. (#10647, #20354) Thanks @ClumsyWizardHands and @dcruver.
|
||||
|
||||
@@ -57,6 +57,24 @@ describe("buildInboundMetaSystemPrompt", () => {
|
||||
expect(payload["sender_id"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not include per-turn flags in system metadata", () => {
|
||||
const prompt = buildInboundMetaSystemPrompt({
|
||||
ReplyToBody: "quoted",
|
||||
ForwardedFrom: "sender",
|
||||
ThreadStarterBody: "starter",
|
||||
InboundHistory: [{ sender: "a", body: "b", timestamp: 1 }],
|
||||
WasMentioned: true,
|
||||
OriginatingTo: "telegram:-1001249586642",
|
||||
OriginatingChannel: "telegram",
|
||||
Provider: "telegram",
|
||||
Surface: "telegram",
|
||||
ChatType: "group",
|
||||
} as TemplateContext);
|
||||
|
||||
const payload = parseInboundMetaPayload(prompt);
|
||||
expect(payload["flags"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("omits sender_id when blank", () => {
|
||||
const prompt = buildInboundMetaSystemPrompt({
|
||||
MessageSid: "458",
|
||||
@@ -183,6 +201,25 @@ describe("buildInboundUserContextPrefix", () => {
|
||||
expect(conversationInfo["sender_id"]).toBe("289522496");
|
||||
});
|
||||
|
||||
it("includes dynamic per-turn flags in conversation info", () => {
|
||||
const text = buildInboundUserContextPrefix({
|
||||
ChatType: "group",
|
||||
WasMentioned: true,
|
||||
ReplyToBody: "quoted",
|
||||
ForwardedFrom: "sender",
|
||||
ThreadStarterBody: "starter",
|
||||
InboundHistory: [{ sender: "a", body: "b", timestamp: 1 }],
|
||||
} as TemplateContext);
|
||||
|
||||
const conversationInfo = parseConversationInfoPayload(text);
|
||||
expect(conversationInfo["is_group_chat"]).toBe(true);
|
||||
expect(conversationInfo["was_mentioned"]).toBe(true);
|
||||
expect(conversationInfo["has_reply_context"]).toBe(true);
|
||||
expect(conversationInfo["has_forwarded_context"]).toBe(true);
|
||||
expect(conversationInfo["has_thread_starter"]).toBe(true);
|
||||
expect(conversationInfo["history_count"]).toBe(1);
|
||||
});
|
||||
|
||||
it("trims sender_id in conversation info", () => {
|
||||
const text = buildInboundUserContextPrefix({
|
||||
ChatType: "group",
|
||||
|
||||
@@ -16,9 +16,9 @@ export function buildInboundMetaSystemPrompt(ctx: TemplateContext): string {
|
||||
|
||||
// Keep system metadata strictly free of attacker-controlled strings (sender names, group subjects, etc.).
|
||||
// Those belong in the user-role "untrusted context" blocks.
|
||||
// Per-message identifiers (message_id, reply_to_id, sender_id) are also excluded here: they change
|
||||
// on every turn and would bust prefix-based prompt caches on local model providers. They are
|
||||
// included in the user-role conversation info block via buildInboundUserContextPrefix() instead.
|
||||
// Per-message identifiers and dynamic flags are also excluded here: they change on turns/replies
|
||||
// and would bust prefix-based prompt caches on providers that use stable system prefixes.
|
||||
// They are included in the user-role conversation info block instead.
|
||||
|
||||
// Resolve channel identity: prefer explicit channel, then surface, then provider.
|
||||
// For webchat/Hub Chat sessions (when Surface is 'webchat' or undefined with no real channel),
|
||||
@@ -43,14 +43,6 @@ export function buildInboundMetaSystemPrompt(ctx: TemplateContext): string {
|
||||
provider: safeTrim(ctx.Provider),
|
||||
surface: safeTrim(ctx.Surface),
|
||||
chat_type: chatType ?? (isDirect ? "direct" : undefined),
|
||||
flags: {
|
||||
is_group_chat: !isDirect ? true : undefined,
|
||||
was_mentioned: ctx.WasMentioned === true ? true : undefined,
|
||||
has_reply_context: Boolean(ctx.ReplyToBody),
|
||||
has_forwarded_context: Boolean(ctx.ForwardedFrom),
|
||||
has_thread_starter: Boolean(safeTrim(ctx.ThreadStarterBody)),
|
||||
history_count: Array.isArray(ctx.InboundHistory) ? ctx.InboundHistory.length : 0,
|
||||
},
|
||||
};
|
||||
|
||||
// Keep the instructions local to the payload so the meaning survives prompt overrides.
|
||||
@@ -92,7 +84,15 @@ export function buildInboundUserContextPrefix(ctx: TemplateContext): string {
|
||||
group_space: safeTrim(ctx.GroupSpace),
|
||||
thread_label: safeTrim(ctx.ThreadLabel),
|
||||
is_forum: ctx.IsForum === true ? true : undefined,
|
||||
is_group_chat: !isDirect ? true : undefined,
|
||||
was_mentioned: ctx.WasMentioned === true ? true : undefined,
|
||||
has_reply_context: ctx.ReplyToBody ? true : undefined,
|
||||
has_forwarded_context: ctx.ForwardedFrom ? true : undefined,
|
||||
has_thread_starter: safeTrim(ctx.ThreadStarterBody) ? true : undefined,
|
||||
history_count:
|
||||
Array.isArray(ctx.InboundHistory) && ctx.InboundHistory.length > 0
|
||||
? ctx.InboundHistory.length
|
||||
: undefined,
|
||||
};
|
||||
if (Object.values(conversationInfo).some((v) => v !== undefined)) {
|
||||
blocks.push(
|
||||
|
||||
Reference in New Issue
Block a user