diff --git a/src/agents/pi-embedded-runner/compact.hooks.test.ts b/src/agents/pi-embedded-runner/compact.hooks.test.ts index 236578ab15d..e6091af8b9e 100644 --- a/src/agents/pi-embedded-runner/compact.hooks.test.ts +++ b/src/agents/pi-embedded-runner/compact.hooks.test.ts @@ -3,6 +3,7 @@ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { applyExtraParamsToAgentMock, contextEngineCompactMock, + createOpenClawCodingToolsMock, ensureRuntimePluginsLoaded, estimateTokensMock, getMemorySearchManagerMock, @@ -266,6 +267,27 @@ describe("compactEmbeddedPiSessionDirect hooks", () => { ); }); + it("preserves full sender identity when building compaction tools", async () => { + await compactEmbeddedPiSessionDirect({ + sessionId: "session-1", + sessionFile: "/tmp/session.jsonl", + workspaceDir: "/tmp/workspace", + senderId: "sender-1", + senderName: "Alice", + senderUsername: "alice_u", + senderE164: "+15551234567", + }); + + expect(createOpenClawCodingToolsMock).toHaveBeenCalledWith( + expect.objectContaining({ + senderId: "sender-1", + senderName: "Alice", + senderUsername: "alice_u", + senderE164: "+15551234567", + }), + ); + }); + it("emits internal + plugin compaction hooks with counts", async () => { hookRunner.hasHooks.mockReturnValue(true); await runCompactionHooks({ diff --git a/src/agents/pi-embedded-runner/compact.ts b/src/agents/pi-embedded-runner/compact.ts index 5d6f511d254..1a85f854ba2 100644 --- a/src/agents/pi-embedded-runner/compact.ts +++ b/src/agents/pi-embedded-runner/compact.ts @@ -161,6 +161,9 @@ export type CompactEmbeddedPiSessionParams = { currentMessageId?: string | number; /** Trusted sender id from inbound context for scoped message-tool discovery. */ senderId?: string; + senderName?: string; + senderUsername?: string; + senderE164?: string; authProfileId?: string; /** Group id for channel-level tool policy resolution. */ groupId?: string | null; @@ -562,6 +565,10 @@ export async function compactEmbeddedPiSessionDirect( groupChannel: params.groupChannel, groupSpace: params.groupSpace, spawnedBy: params.spawnedBy, + senderId: params.senderId, + senderName: params.senderName, + senderUsername: params.senderUsername, + senderE164: params.senderE164, senderIsOwner: params.senderIsOwner, allowGatewaySubagentBinding: params.allowGatewaySubagentBinding, agentDir, diff --git a/src/auto-reply/reply/agent-runner-memory.ts b/src/auto-reply/reply/agent-runner-memory.ts index 4511f3c6975..fe819953f7f 100644 --- a/src/auto-reply/reply/agent-runner-memory.ts +++ b/src/auto-reply/reply/agent-runner-memory.ts @@ -444,6 +444,10 @@ export async function runPreflightCompactionIfNeeded(params: { groupId: entry.groupId ?? params.followupRun.run.groupId, groupChannel: entry.groupChannel ?? params.followupRun.run.groupChannel, groupSpace: entry.space ?? params.followupRun.run.groupSpace, + senderId: params.followupRun.run.senderId, + senderName: params.followupRun.run.senderName, + senderUsername: params.followupRun.run.senderUsername, + senderE164: params.followupRun.run.senderE164, sessionFile: sessionFile ?? params.followupRun.run.sessionFile, workspaceDir: params.followupRun.run.workspaceDir, agentDir: params.followupRun.run.agentDir, diff --git a/src/auto-reply/reply/commands-compact.test.ts b/src/auto-reply/reply/commands-compact.test.ts index f024236b270..0e0023dafc6 100644 --- a/src/auto-reply/reply/commands-compact.test.ts +++ b/src/auto-reply/reply/commands-compact.test.ts @@ -105,6 +105,9 @@ describe("handleCompactCommand", () => { CommandBody: "/compact: focus on decisions", From: "+15550001", To: "+15550002", + SenderName: "Alice", + SenderUsername: "alice_u", + SenderE164: "+15551234567", }, agentDir: "/tmp/openclaw-agent-compact", sessionEntry: { @@ -134,6 +137,10 @@ describe("handleCompactCommand", () => { groupChannel: "#general", groupSpace: "workspace-1", spawnedBy: "agent:main:parent", + senderId: "owner", + senderName: "Alice", + senderUsername: "alice_u", + senderE164: "+15551234567", agentDir: "/tmp/openclaw-agent-compact", }), ); diff --git a/src/auto-reply/reply/commands-compact.ts b/src/auto-reply/reply/commands-compact.ts index 23c82adc130..5a94e7f053e 100644 --- a/src/auto-reply/reply/commands-compact.ts +++ b/src/auto-reply/reply/commands-compact.ts @@ -108,6 +108,10 @@ export const handleCompactCommand: CommandHandler = async (params) => { groupChannel: params.sessionEntry.groupChannel, groupSpace: params.sessionEntry.space, spawnedBy: params.sessionEntry.spawnedBy, + senderId: params.command.senderId, + senderName: params.ctx.SenderName, + senderUsername: params.ctx.SenderUsername, + senderE164: params.ctx.SenderE164, sessionFile: runtime.resolveSessionFilePath( sessionId, params.sessionEntry, diff --git a/src/auto-reply/reply/commands-system-prompt.test.ts b/src/auto-reply/reply/commands-system-prompt.test.ts index 9efed17fae0..92afb3049e8 100644 --- a/src/auto-reply/reply/commands-system-prompt.test.ts +++ b/src/auto-reply/reply/commands-system-prompt.test.ts @@ -54,12 +54,17 @@ function makeParams(): HandleCommandsParams { return { ctx: { SessionKey: "agent:main:default", + SenderId: "sender-1", + SenderName: "Alice", + SenderUsername: "alice_u", + SenderE164: "+15551234567", }, cfg: {}, command: { surface: "telegram", channel: "telegram", ownerList: [], + senderId: "sender-1", senderIsOwner: true, isAuthorizedSender: true, rawBodyNormalized: "/context", @@ -117,6 +122,10 @@ describe("resolveCommandsSystemPromptBundle", () => { sessionKey: "agent:main:default", workspaceDir: "/tmp/workspace", messageProvider: "telegram", + senderId: "sender-1", + senderName: "Alice", + senderUsername: "alice_u", + senderE164: "+15551234567", }), ); }); diff --git a/src/auto-reply/reply/commands-system-prompt.ts b/src/auto-reply/reply/commands-system-prompt.ts index b03fc88bb1b..f4cd310a564 100644 --- a/src/auto-reply/reply/commands-system-prompt.ts +++ b/src/auto-reply/reply/commands-system-prompt.ts @@ -78,6 +78,10 @@ export async function resolveCommandsSystemPromptBundle( groupChannel: params.sessionEntry?.groupChannel ?? undefined, groupSpace: params.sessionEntry?.space ?? undefined, spawnedBy: params.sessionEntry?.spawnedBy ?? undefined, + senderId: params.command.senderId, + senderName: params.ctx.SenderName, + senderUsername: params.ctx.SenderUsername, + senderE164: params.ctx.SenderE164, senderIsOwner: params.command.senderIsOwner, modelProvider: params.provider, modelId: params.model,