From b14a472941ca29364a1980160add89c249089fd6 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Mon, 15 Dec 2025 16:20:47 -0800 Subject: [PATCH] add `agent_id` to search results (#214) Co-authored-by: christinatong01 --- src/cli/components/MessageSearch.tsx | 159 ++++++++++++++++++--------- 1 file changed, 104 insertions(+), 55 deletions(-) diff --git a/src/cli/components/MessageSearch.tsx b/src/cli/components/MessageSearch.tsx index 6374d0c..a494b62 100644 --- a/src/cli/components/MessageSearch.tsx +++ b/src/cli/components/MessageSearch.tsx @@ -1,6 +1,7 @@ import type { Letta } from "@letta-ai/letta-client"; import type { MessageSearchResponse } from "@letta-ai/letta-client/resources/messages"; import { Box, Text, useInput } from "ink"; +import Link from "ink-link"; import { useCallback, useEffect, useRef, useState } from "react"; import { getClient } from "../../agent/client"; import { useTerminalWidth } from "../hooks/useTerminalWidth"; @@ -37,6 +38,28 @@ function formatRelativeTime(dateStr: string | null | undefined): string { return `${diffWeeks}w ago`; } +/** + * Format a timestamp in local timezone + */ +function formatLocalTime(dateStr: string | null | undefined): string { + if (!dateStr) return ""; + + const date = new Date(dateStr); + // Format: "Dec 15, 6:30 PM" or "Dec 15, 2024, 6:30 PM" depending on year + const now = new Date(); + const sameYear = date.getFullYear() === now.getFullYear(); + + const options: Intl.DateTimeFormatOptions = { + month: "short", + day: "numeric", + ...(sameYear ? {} : { year: "numeric" }), + hour: "numeric", + minute: "2-digit", + }; + + return date.toLocaleString(undefined, options); +} + /** * Truncate text to fit width, adding ellipsis if needed */ @@ -109,11 +132,17 @@ export function MessageSearch({ onClose }: MessageSearchProps) { const client = clientRef.current || (await getClient()); clientRef.current = client; - const searchResults = await client.messages.search({ - query: query.trim(), - search_mode: mode, - limit: SEARCH_LIMIT, - }); + // Direct API call since client.messages.search doesn't exist yet in SDK + const searchResults = await client.post( + "/v1/messages/search", + { + body: { + query: query.trim(), + search_mode: mode, + limit: SEARCH_LIMIT, + }, + }, + ); setResults(searchResults); setCurrentPage(0); @@ -269,60 +298,80 @@ export function MessageSearch({ onClose }: MessageSearchProps) { {/* Results list */} {!loading && results.length > 0 && ( - {pageResults.map((msg, index) => { - const isSelected = index === selectedIndex; - const messageText = getMessageText(msg); - // All messages have a date field - const msgWithDate = msg as { date?: string }; - const timestamp = msgWithDate.date - ? formatRelativeTime(msgWithDate.date) - : ""; - const msgType = (msg.message_type || "unknown").replace( - "_message", - "", - ); + {pageResults.map( + (msg: MessageSearchResponse[number], index: number) => { + const isSelected = index === selectedIndex; + const messageText = getMessageText(msg); + // All messages have a date field + const msgWithDate = msg as { + date?: string; + created_at?: string; + agent_id?: string; + }; + const timestamp = msgWithDate.date + ? formatRelativeTime(msgWithDate.date) + : ""; + const msgType = (msg.message_type || "unknown").replace( + "_message", + "", + ); + const agentId = msgWithDate.agent_id || "unknown"; + const createdAt = formatLocalTime(msgWithDate.created_at); - // Calculate available width for message text - const metaWidth = timestamp.length + msgType.length + 10; // padding - const availableWidth = Math.max(20, terminalWidth - metaWidth - 4); - const displayText = truncateText( - messageText.replace(/\n/g, " "), - availableWidth, - ); + // Calculate available width for message text + const metaWidth = timestamp.length + msgType.length + 10; // padding + const availableWidth = Math.max( + 20, + terminalWidth - metaWidth - 4, + ); + const displayText = truncateText( + messageText.replace(/\n/g, " "), + availableWidth, + ); - // Use message id + index for guaranteed uniqueness (search can return same message multiple times) - const msgId = "id" in msg ? String(msg.id) : "result"; - const uniqueKey = `${msgId}-${startIndex + index}`; + // Use message id + index for guaranteed uniqueness (search can return same message multiple times) + const msgId = "id" in msg ? String(msg.id) : "result"; + const uniqueKey = `${msgId}-${startIndex + index}`; - return ( - - - - {isSelected ? ">" : " "} - - - - {displayText} - + return ( + + + + {isSelected ? ">" : " "} + + + + {displayText} + + + + + {msgType} + {timestamp && ` · ${timestamp}`} + + {agentId && ( + <> + · agent: + + {agentId} + + + )} + {createdAt && · {createdAt}} + - - - {msgType} - {timestamp && ` · ${timestamp}`} - - - - ); - })} + ); + }, + )} )}