personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add parameter pills to tool placards in chat UI

Display key parameters (facet, day, topic) as compact pills on tool
call cards so users can see at a glance what filters/context the agent
used. Dates are formatted from YYYYMMDD to M/D for readability.

Also consolidates three duplicate date formatting implementations into
a single shared formatDay() helper.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+70 -13
+70 -13
apps/chat/workspace.html
··· 107 107 } 108 108 #messages .tool-placard .tool-name { font-weight: bold; color: #1976d2; } 109 109 #messages .tool-placard .tool-status { font-size: 0.9em; color: #666; margin-left: 0.5em; } 110 + #messages .tool-placard .tool-params { margin-left: 0.5em; display: inline; } 111 + #messages .tool-placard .tool-param { 112 + display: inline-block; 113 + background: rgba(0,0,0,0.08); 114 + border-radius: 3px; 115 + padding: 0.1em 0.4em; 116 + margin-left: 0.3em; 117 + font-size: 0.9em; 118 + color: #555; 119 + } 120 + #messages .tool-placard .tool-param .param-label { color: #888; } 110 121 #messages .tool-placard.completed { background: #e8f5e9; border-color: #4caf50; } 111 122 #messages .tool-placard.completed:hover { background: #d4f0d7; } 112 123 #messages .tool-placard.completed .tool-name { color: #2e7d32; } 124 + #messages .tool-placard.completed .tool-param { background: rgba(0,0,0,0.06); } 113 125 114 126 #messages .agent-update { 115 127 background: #fff3e0; ··· 283 295 284 296 // Recent chats data 285 297 let allChats = []; 298 + 299 + // Format day from YYYYMMDD to M/D 300 + function formatDay(dayStr) { 301 + if (!dayStr || dayStr.length !== 8) return dayStr; 302 + const month = parseInt(dayStr.substring(4, 6), 10); 303 + const day = parseInt(dayStr.substring(6, 8), 10); 304 + return `${month}/${day}`; 305 + } 286 306 287 307 // Format timestamp as relative time 288 308 function formatRelativeTime(ts) { ··· 947 967 } 948 968 } 949 969 970 + // Format tool args into display-friendly params (query, facet, day, topic, etc.) 971 + function formatToolParams(args) { 972 + if (!args) return []; 973 + const params = []; 974 + 975 + if (args.query) { 976 + params.push({label: 'query', value: args.query}); 977 + } 978 + if (args.facet) { 979 + params.push({label: 'facet', value: args.facet}); 980 + } 981 + if (args.day) { 982 + params.push({label: 'day', value: formatDay(args.day)}); 983 + } 984 + if (args.day_from) { 985 + params.push({label: 'from', value: formatDay(args.day_from)}); 986 + } 987 + if (args.day_to) { 988 + params.push({label: 'to', value: formatDay(args.day_to)}); 989 + } 990 + if (args.topic) { 991 + params.push({label: 'topic', value: args.topic}); 992 + } 993 + 994 + return params; 995 + } 996 + 950 997 function addToolPlacard(toolName, event, callId){ 951 998 const div=document.createElement('div'); 952 999 div.className='tool-placard'; ··· 955 1002 nameSpan.className='tool-name'; 956 1003 nameSpan.textContent='🔧 ' + toolName; 957 1004 div.appendChild(nameSpan); 1005 + 1006 + // Add parameter pills if args present 1007 + const args = event && event.args; 1008 + const params = formatToolParams(args); 1009 + if (params.length > 0) { 1010 + const paramsSpan = document.createElement('span'); 1011 + paramsSpan.className = 'tool-params'; 1012 + params.forEach(p => { 1013 + const pill = document.createElement('span'); 1014 + pill.className = 'tool-param'; 1015 + const label = document.createElement('span'); 1016 + label.className = 'param-label'; 1017 + label.textContent = p.label + ': '; 1018 + pill.appendChild(label); 1019 + pill.appendChild(document.createTextNode(p.value)); 1020 + paramsSpan.appendChild(pill); 1021 + }); 1022 + div.appendChild(paramsSpan); 1023 + } 958 1024 959 1025 const statusSpan=document.createElement('span'); 960 1026 statusSpan.className='tool-status'; ··· 1259 1325 const dateMatch = args.query.match(/\b(\d{8}|\d{4}-\d{2}-\d{2})\b/); 1260 1326 if(dateMatch) { 1261 1327 const dateRaw = dateMatch[1].replace(/-/g, ''); 1262 - const month = parseInt(dateRaw.substring(4, 6), 10); 1263 - const day = parseInt(dateRaw.substring(6, 8), 10); 1264 - dateStr = ` on ${month}/${day}`; 1328 + dateStr = ` on ${formatDay(dateRaw)}`; 1265 1329 } 1266 1330 1267 1331 const url = searchBase + '#q=' + encodeURIComponent(args.query); ··· 1285 1349 1286 1350 // Create resource card for get_resource tool 1287 1351 function createResourceCard(uri) { 1288 - // Helper to format date from YYYYMMDD to M/D 1289 - function formatDate(dateStr) { 1290 - const month = parseInt(dateStr.substring(4, 6), 10); 1291 - const day = parseInt(dateStr.substring(6, 8), 10); 1292 - return `${month}/${day}`; 1293 - } 1294 - 1295 1352 // Helper to format time from HHMMSS to HH:MM 1296 1353 function formatTime(timeStr) { 1297 1354 const hours = timeStr.substring(0, 2); ··· 1304 1361 if(match) { 1305 1362 const date = match[1]; 1306 1363 const topic = match[2]; 1307 - const dateStr = formatDate(date); 1364 + const dateStr = formatDay(date); 1308 1365 const topicDisplay = topic.charAt(0).toUpperCase() + topic.slice(1); 1309 1366 1310 1367 return { ··· 1320 1377 const date = match[2]; 1321 1378 const time = match[3]; 1322 1379 const length = match[4]; 1323 - const dateStr = formatDate(date); 1380 + const dateStr = formatDay(date); 1324 1381 const timeStr = formatTime(time); 1325 1382 1326 1383 const modeText = mode === 'full' ? 'full' : mode === 'audio' ? 'audio-only' : 'screen-only'; ··· 1336 1393 if(match) { 1337 1394 const date = match[1]; 1338 1395 const filename = match[2]; 1339 - const dateStr = formatDate(date); 1396 + const dateStr = formatDay(date); 1340 1397 1341 1398 // Determine media type from filename 1342 1399 let description = filename;