@@ -117,8 +117,12 @@ test('SearchHistory returns typed message hits from current and other sessions',
117117 assert . ok ( messageRows . every ( ( row ) => typeof row . message_id === 'string' ) ) ;
118118 assert . ok ( messageRows . every ( ( row ) => typeof row . message_timestamp === 'number' ) ) ;
119119 assert . deepEqual (
120- new Set ( result . rows . map ( ( row ) => row . match_kind ) ) ,
121- new Set ( [ 'session_title' , 'user_message' , 'assistant_message' ] ) ,
120+ new Map ( result . rows . map ( ( row ) => [ row . match_kind , row . summary ] ) ) ,
121+ new Map ( [
122+ [ 'session_title' , 'Session title' ] ,
123+ [ 'user_message' , 'User message' ] ,
124+ [ 'assistant_message' , 'Assistant response' ] ,
125+ ] ) ,
122126 ) ;
123127 assert . equal ( result . rows . find ( ( row ) => row . session_id === 'current' ) ?. is_current_session , true ) ;
124128 assert . ok ( result . rows . every ( ( row ) => row . turn_id !== 'current-turn' ) ) ;
@@ -158,6 +162,68 @@ test('SearchHistory exposes and consumes an opaque session continuation', async
158162 assert . equal ( second . next_cursor , undefined ) ;
159163} ) ;
160164
165+ test ( 'SearchHistory summaries echo invoked wire tool names and cover tool outcomes' , async ( ) => {
166+ const needle = 'history summary needle' ;
167+ const messages = new Map < string , StoredMessage [ ] > ( [
168+ [
169+ 'past' ,
170+ [
171+ {
172+ type : 'tool_call' ,
173+ id : 'legacy-browser' ,
174+ turnId : 'turn-1' ,
175+ ts : 1 ,
176+ toolName : 'mcp__desktop_browser__browser_navigate' ,
177+ displayName : '浏览器导航' ,
178+ intent : needle ,
179+ args : { } ,
180+ } ,
181+ {
182+ type : 'tool_call' ,
183+ id : 'secret-tool' ,
184+ turnId : 'turn-1' ,
185+ ts : 2 ,
186+ toolName : 'sk-ant-test-secret-token-12345' ,
187+ displayName : 'Acme Lookup' ,
188+ intent : needle ,
189+ args : { } ,
190+ } ,
191+ {
192+ type : 'tool_result' ,
193+ id : 'success-result' ,
194+ turnId : 'turn-1' ,
195+ ts : 3 ,
196+ toolUseId : 'legacy-browser' ,
197+ isError : false ,
198+ content : { note : needle } as never ,
199+ } ,
200+ {
201+ type : 'tool_result' ,
202+ id : 'failure-result' ,
203+ turnId : 'turn-1' ,
204+ ts : 4 ,
205+ toolUseId : 'secret-tool' ,
206+ isError : true ,
207+ content : { note : needle } as never ,
208+ } ,
209+ ] ,
210+ ] ,
211+ ] ) ;
212+ const result = ( await buildSearchHistoryTool (
213+ historyDeps ( [ session ( 'past' , 'Past' , 1 ) ] , messages ) ,
214+ ) . impl ( { query : needle , limit : 10 } , context ( ) ) ) as {
215+ rows : Array < { summary : string } > ;
216+ } ;
217+
218+ assert . ok (
219+ result . rows . some ( ( row ) => row . summary === 'Tool call: mcp__desktop_browser__browser_navigate' ) ,
220+ ) ;
221+ assert . ok ( result . rows . some ( ( row ) => row . summary === 'Tool result: Succeeded' ) ) ;
222+ assert . ok ( result . rows . some ( ( row ) => row . summary === 'Tool result: Failed' ) ) ;
223+ assert . match ( JSON . stringify ( result . rows ) , / \[ r e d a c t e d \] / u) ;
224+ assert . doesNotMatch ( JSON . stringify ( result . rows ) , / s k - a n t - t e s t - s e c r e t - t o k e n - 1 2 3 4 5 / u) ;
225+ } ) ;
226+
161227test ( 'ReadHistory returns a bounded visible excerpt without reasoning or raw tool data' , async ( ) => {
162228 const huge = `finished ${ 'x' . repeat ( HISTORY_READ_MAX_BYTES * 2 ) } ` ;
163229 const messages = new Map < string , StoredMessage [ ] > ( [
0 commit comments