diff --git a/packages/web-ui/example/index.html b/packages/web-ui/example/index.html index e462448..66edc66 100644 --- a/packages/web-ui/example/index.html +++ b/packages/web-ui/example/index.html @@ -1,10 +1,12 @@ + + - Pi Web UI - Example - + Agent JAE +
diff --git a/packages/web-ui/example/public/apple-touch-icon.png b/packages/web-ui/example/public/apple-touch-icon.png new file mode 100644 index 0000000..11bd06c Binary files /dev/null and b/packages/web-ui/example/public/apple-touch-icon.png differ diff --git a/packages/web-ui/example/public/favicon.ico b/packages/web-ui/example/public/favicon.ico new file mode 100644 index 0000000..21648cf Binary files /dev/null and b/packages/web-ui/example/public/favicon.ico differ diff --git a/packages/web-ui/example/src/main.ts b/packages/web-ui/example/src/main.ts index 4d3af13..d330e2e 100644 --- a/packages/web-ui/example/src/main.ts +++ b/packages/web-ui/example/src/main.ts @@ -258,22 +258,38 @@ async function createAgent(initialState?: AgentState) { currentModel = model.modelId || "llama-3.3-70b"; currentProvider = model.provider || "venice"; - // Listen for agent messages to track state - agent.on("message", (msg: AgentMessage) => { - if (!hasMessages && msg.role === "assistant") { - hasMessages = true; - renderApp(); - } - // Track tool usage for mood and auto-open panels - if (msg.role === "assistant" && msg.toolCalls) { - for (const tc of msg.toolCalls) { - if (tc.name === "browser" || tc.name === "web_fetch" || tc.name === "navigate") { + // Subscribe to agent events for UI state tracking + agent.subscribe((event) => { + const typing = document.querySelector("jae-typing-indicator") as JaeTypingIndicator; + const mood = document.querySelector("jae-mood-indicator") as JaeMoodIndicator; + + switch (event.type) { + case "agent_start": + if (typing) typing.show("high"); + break; + + case "agent_end": + if (typing) typing.hide(); + break; + + case "turn_start": + if (typing) typing.show("high"); + break; + + case "turn_end": + if (typing) typing.hide(); + break; + + case "tool_execution_start": + if (typing) typing.show("medium"); + // Auto-open panels based on tool usage + if (event.toolName === "browser" || event.toolName === "web_fetch" || event.toolName === "navigate") { if (rightPanel !== "browser") { rightPanel = "browser"; renderApp(); } } - if (tc.name === "bash") { + if (event.toolName === "bash") { if (rightPanel !== "terminal") { rightPanel = "terminal"; renderApp(); @@ -283,46 +299,46 @@ async function createAgent(initialState?: AgentState) { }); } } - } - } - // Auto-learn from user messages - if (msg.role === "user" && typeof msg.content === "string") { - processMessageForMemory("user", msg.content); - } - // Update mood based on content - const mood = document.querySelector("jae-mood-indicator") as JaeMoodIndicator; - if (mood && msg.role === "assistant" && typeof msg.content === "string") { - const text = msg.content.toLowerCase(); - if (text.includes("error") || text.includes("failed") || text.includes("cannot")) { - mood.setMood("frustrated"); - } else if (text.includes("!") || text.includes("great") || text.includes("success") || text.includes("done")) { - mood.setMood("excited"); - } else if (text.includes("warning") || text.includes("careful") || text.includes("caution")) { - mood.setMood("warning"); - } else { - mood.setMood("focused"); - } - } - }); + break; - agent.on("stateChange", (state: string) => { - const typing = document.querySelector("jae-typing-indicator") as JaeTypingIndicator; - if (typing) { - if (state === "thinking" || state === "running") { - typing.show("high"); - } else if (state === "tool_calling") { - typing.show("medium"); - } else { - typing.hide(); + case "message_start": { + const msg = event.message; + if (!hasMessages && msg.role === "assistant") { + hasMessages = true; + renderApp(); + } + // Auto-learn from user messages + if (msg.role === "user" && typeof msg.content === "string") { + processMessageForMemory("user", msg.content); + } + break; } - } - }); - // Track cost - agent.on("usage", (usage: { inputTokens: number; outputTokens: number; totalTokens: number }) => { - const costEl = document.querySelector("jae-cost-tracker") as CostTracker; - if (costEl && usage) { - costEl.addUsage(usage.inputTokens || 0, usage.outputTokens || 0); + case "message_end": { + const msg = event.message; + // Update mood based on assistant content + if (mood && msg.role === "assistant" && typeof msg.content === "string") { + const text = msg.content.toLowerCase(); + if (text.includes("error") || text.includes("failed") || text.includes("cannot")) { + mood.setMood("frustrated"); + } else if (text.includes("!") || text.includes("great") || text.includes("success") || text.includes("done")) { + mood.setMood("excited"); + } else if (text.includes("warning") || text.includes("careful") || text.includes("caution")) { + mood.setMood("warning"); + } else { + mood.setMood("focused"); + } + } + // Track cost from usage data on the message + const usage = (msg as any).usage; + if (usage) { + const costEl = document.querySelector("jae-cost-tracker") as CostTracker; + if (costEl) { + costEl.addUsage(usage.input || 0, usage.output || 0); + } + } + break; + } } });