Skip to content

Commit 83ffe4d

Browse files
fix(data-retention): mask seeded memory messages under block-output redaction
1 parent d55b557 commit 83ffe4d

1 file changed

Lines changed: 25 additions & 13 deletions

File tree

apps/sim/executor/handlers/agent/memory.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,7 @@ export class Memory {
6060
const workspaceId = this.requireWorkspaceId(ctx)
6161
this.validateConversationId(inputs.conversationId)
6262

63-
// Handlers persist their response to memory before the executor redacts the
64-
// block output, so mask here too when the block-output stage is enabled —
65-
// otherwise raw PII would be stored in memory and read back on later runs.
66-
if (ctx.piiBlockOutputRedaction?.enabled && message.content) {
67-
message = {
68-
...message,
69-
content: await redactObjectStrings(message.content, {
70-
entityTypes: ctx.piiBlockOutputRedaction.entityTypes,
71-
language: ctx.piiBlockOutputRedaction.language,
72-
onFailure: 'throw',
73-
}),
74-
}
75-
}
63+
message = await this.maskContentForStorage(ctx, message)
7664

7765
this.validateContent(message.content)
7866

@@ -118,6 +106,10 @@ export class Memory {
118106
messagesToStore = this.applyTokenWindow(conversationMessages, maxTokens, inputs.model)
119107
}
120108

109+
messagesToStore = await Promise.all(
110+
messagesToStore.map((message) => this.maskContentForStorage(ctx, message))
111+
)
112+
121113
await this.seedMemoryRecord(workspaceId, key, messagesToStore)
122114

123115
logger.debug('Seeded memory', {
@@ -127,6 +119,26 @@ export class Memory {
127119
})
128120
}
129121

122+
/**
123+
* Handlers persist messages to memory before the executor redacts block
124+
* output, so mask content here too when the block-output stage is enabled —
125+
* otherwise raw PII is stored in the memory table and read back on later runs.
126+
* `onFailure: 'throw'` aborts rather than persisting unredacted content.
127+
*/
128+
private async maskContentForStorage(ctx: ExecutionContext, message: Message): Promise<Message> {
129+
if (!ctx.piiBlockOutputRedaction?.enabled || !message.content) {
130+
return message
131+
}
132+
return {
133+
...message,
134+
content: await redactObjectStrings(message.content, {
135+
entityTypes: ctx.piiBlockOutputRedaction.entityTypes,
136+
language: ctx.piiBlockOutputRedaction.language,
137+
onFailure: 'throw',
138+
}),
139+
}
140+
}
141+
130142
private requireWorkspaceId(ctx: ExecutionContext): string {
131143
if (!ctx.workspaceId) {
132144
throw new Error('workspaceId is required for memory operations')

0 commit comments

Comments
 (0)