@@ -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