diff --git a/example/src/components/ConversationManager.tsx b/example/src/components/ConversationManager.tsx index 7155c07..27bb796 100644 --- a/example/src/components/ConversationManager.tsx +++ b/example/src/components/ConversationManager.tsx @@ -15,6 +15,82 @@ interface ConversationData extends ConversationInfo { agentStatus?: AgentExecutionStatus; } +// Utility function to extract displayable content from events +const getEventDisplayContent = (event: Event): { title: string; content: string; details?: any } => { + switch (event.kind) { + case 'MessageEvent': + const messageEvent = event as any; + const message = messageEvent.llm_message; + if (message && message.content && Array.isArray(message.content)) { + const textContent = message.content + .filter((c: any) => c.type === 'text') + .map((c: any) => c.text) + .join(' '); + return { + title: `Message from ${messageEvent.source || 'unknown'}`, + content: textContent || 'No text content', + details: message + }; + } + return { + title: `Message from ${messageEvent.source || 'unknown'}`, + content: 'No message content available', + details: messageEvent + }; + + case 'ActionEvent': + const actionEvent = event as any; + const action = actionEvent.action; + return { + title: `Action: ${action?.kind || 'Unknown Action'}`, + content: action?.command || action?.content || JSON.stringify(action, null, 2), + details: action + }; + + case 'ObservationEvent': + const obsEvent = event as any; + return { + title: `Observation: ${obsEvent.tool_name || 'Unknown Tool'}`, + content: typeof obsEvent.observation === 'string' + ? obsEvent.observation + : JSON.stringify(obsEvent.observation, null, 2), + details: obsEvent.observation + }; + + case 'AgentErrorEvent': + const errorEvent = event as any; + return { + title: `Error: ${errorEvent.tool_name || 'Unknown Tool'}`, + content: typeof errorEvent.observation === 'string' + ? errorEvent.observation + : JSON.stringify(errorEvent.observation, null, 2), + details: errorEvent.observation + }; + + case 'SystemPromptEvent': + const sysEvent = event as any; + return { + title: 'System Prompt', + content: sysEvent.system_prompt?.text || 'System prompt updated', + details: sysEvent.system_prompt + }; + + case 'PauseEvent': + return { + title: 'Agent Paused', + content: 'Agent execution was paused', + details: null + }; + + default: + return { + title: event.kind || 'Unknown Event', + content: JSON.stringify(event, null, 2), + details: event + }; + } +}; + export const ConversationManager: React.FC = () => { const { settings } = useSettings(); const [conversations, setConversations] = useState([]); @@ -23,6 +99,7 @@ export const ConversationManager: React.FC = () => { const [manager, setManager] = useState(null); const [selectedConversationId, setSelectedConversationId] = useState(null); const [messageInput, setMessageInput] = useState(''); + const [showAllEvents, setShowAllEvents] = useState(false); // Get selected conversation data const selectedConversation = conversations.find(c => c.id === selectedConversationId); @@ -472,31 +549,93 @@ export const ConversationManager: React.FC = () => {
-

Events & Messages

+
+

Events & Messages

+ {selectedConversation.events && selectedConversation.events.length > 1 && ( + + )} +
{selectedConversation.events && selectedConversation.events.length > 0 ? ( - selectedConversation.events.map((event, index) => ( -
-
- - {event.type} - - - {event.timestamp ? new Date(event.timestamp).toLocaleTimeString() : ''} - -
- {event.message && ( -
- {event.message} + (() => { + // Sort events by timestamp (most recent first) + const sortedEvents = [...selectedConversation.events].sort((a, b) => + new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime() + ); + + // Show only the most recent event unless expanded + const eventsToShow = showAllEvents ? sortedEvents : sortedEvents.slice(0, 1); + + return eventsToShow.map((event, index) => { + const displayContent = getEventDisplayContent(event); + const isRecent = index === 0 && !showAllEvents; + + return ( +
+
+
+ + {event.kind} + + {event.source && ( + + {event.source} + + )} + {isRecent && ( + + Latest + + )} +
+ + {event.timestamp ? new Date(event.timestamp).toLocaleTimeString() : ''} + +
+ +
+ {displayContent.title} +
+ + {displayContent.content && ( +
+
+ {displayContent.content.length > 200 ? ( + <> + {displayContent.content.substring(0, 200)} + ... (truncated) + + ) : ( + displayContent.content + )} +
+
+ )} + + {displayContent.details && ( +
+ + Show raw data + +
+
{JSON.stringify(displayContent.details, null, 2)}
+
+
+ )}
- )} - {event.content && ( -
-
{JSON.stringify(event.content, null, 2)}
-
- )} -
- )) + ); + }); + })() ) : (
No events yet
)} diff --git a/src/index.ts b/src/index.ts index a5dc92d..c0d6c0c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,6 +22,12 @@ export { HttpClient, HttpError } from './client/http-client'; export type { ConversationID, Event, + MessageEvent, + ActionEvent, + ObservationEvent, + AgentErrorEvent, + SystemPromptEvent, + PauseEvent, Message, MessageContent, TextContent, diff --git a/src/types/base.ts b/src/types/base.ts index 9aaa1ef..fd5120e 100644 --- a/src/types/base.ts +++ b/src/types/base.ts @@ -8,9 +8,48 @@ export interface Event { id: string; kind: string; timestamp: string; + source?: 'agent' | 'user' | 'environment'; [key: string]: any; } +// Specific event types for better type safety +export interface MessageEvent extends Event { + kind: 'MessageEvent'; + llm_message: Message; + activated_skills?: string[]; +} + +export interface ActionEvent extends Event { + kind: 'ActionEvent'; + action: any; // The action object varies by action type +} + +export interface ObservationEvent extends Event { + kind: 'ObservationEvent'; + tool_name: string; + tool_call_id: string; + observation: any; + action_id: string; +} + +export interface AgentErrorEvent extends Event { + kind: 'AgentErrorEvent'; + tool_name: string; + tool_call_id: string; + observation: any; + action_id: string; +} + +export interface SystemPromptEvent extends Event { + kind: 'SystemPromptEvent'; + system_prompt: TextContent; + tools: any[]; +} + +export interface PauseEvent extends Event { + kind: 'PauseEvent'; +} + export interface Message { role: 'user' | 'assistant' | 'system'; content: MessageContent[];