@@ -170,23 +170,35 @@ public List<Part> getParts(Chat chat) {
170170 sb .append ("**Legend:**\n " );
171171 sb .append (" - **Roles**: u=user, m=model, t=tool\n " );
172172 sb .append (" - **Names**: " ).append (nameAbbreviations .entrySet ().stream ().map (e -> e .getValue () + "=" + e .getKey ()).collect (Collectors .joining (", " ))).append ("\n " );
173- sb .append (" - **Types**: **O**=Other (Text/Blob/Code), **E**=Ephemeral (Non-stateful tool), **S**=Stateful (File content)\n \n " );
173+ sb .append (" - **Types**: **O**=Other (Text/Blob/etc.), **E**=Ephemeral (Non-stateful tool), **S**=Stateful (File content)\n " );
174+ sb .append (" - **Sig**: **Y**=Contains a thoughtSignature \n \n " );
174175
175176 // --- Table ---
176177 List <String > headers = new ArrayList <>();
177178 headers .add ("Age" );
178179 headers .add ("Name" );
179180 headers .add ("Type" );
181+ headers .add ("Sig" );
180182 headers .add ("Pruning ID" );
181183 headers .add ("Content" );
182184 headers .add ("Size (KB)" );
183185
184186 sb .append ("| " ).append (String .join (" | " , headers )).append (" |\n " );
185- sb .append ("|:---|:---|:---|:---|:---|---:|\n " );
187+ sb .append ("|:---|:---|:---|:---|:---|:---| ---:|\n " );
186188
187189 Instant now = Instant .now ();
188190 ResourceTracker rt = chat .getContextManager ().getResourceTracker ();
189191
192+ // Pre-calculate which tool call IDs are associated with a signature
193+ Set <String > signedToolCallIds = new HashSet <>();
194+ for (ChatMessage msg : messages ) {
195+ for (Part part : msg .getContent ().parts ().orElse (Collections .emptyList ())) {
196+ if (part .thoughtSignature ().isPresent ()) {
197+ GeminiAdapter .getToolCallId (part ).ifPresent (signedToolCallIds ::add );
198+ }
199+ }
200+ }
201+
190202 for (ChatMessage msg : messages ) {
191203 List <Part > parts = msg .getContent ().parts ().orElse (Collections .emptyList ());
192204 String msgName = getMessageName (msg , chat .getContextManager ());
@@ -201,6 +213,11 @@ public List<Part> getParts(Chat chat) {
201213 boolean isStateful = statusOpt .isPresent ();
202214 String toolCallId = GeminiAdapter .getToolCallId (part ).orElse ("" );
203215 boolean isToolCall = !toolCallId .isEmpty ();
216+
217+ // A part is 'signed' if it has a signature OR if it's a tool call/response
218+ // where the other side of the pair has a signature.
219+ boolean hasSignature = part .thoughtSignature ().isPresent () ||
220+ (isToolCall && signedToolCallIds .contains (toolCallId ));
204221
205222 List <String > row = new ArrayList <>();
206223 row .add (i == 0 ? age : "" ); // Only show age for the first part of a message
@@ -209,6 +226,9 @@ public List<Part> getParts(Chat chat) {
209226 // Type Column
210227 String typeCode = isStateful ? "**S**" : (isToolCall ? "**E**" : "**O**" );
211228 row .add (typeCode );
229+
230+ // Sig Column
231+ row .add (hasSignature ? "**Y**" : "" );
212232
213233 // Pruning ID Column
214234 String pruningId = "" ;
0 commit comments