fix: replace broken agent.on() with subscribe() API, add favicon, fix page title
Some checks are pending
CI / build-check-test (push) Waiting to run
Some checks are pending
CI / build-check-test (push) Waiting to run
- agent.on() does not exist - replaced all 3 calls with single agent.subscribe() handler - Maps AgentEvent types: agent_start/end, turn_start/end, tool_execution_start, message_start/end - Cost tracking now reads usage from message_end event message.usage field - Added favicon.ico and apple-touch-icon.png from mascot - Fixed page title from Pi Web UI to Agent JAE
This commit is contained in:
parent
33f439296f
commit
3bb3caa650
4 changed files with 68 additions and 50 deletions
|
|
@ -1,10 +1,12 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Pi Web UI - Example</title>
|
<title>Agent JAE</title>
|
||||||
<meta name="description" content="Example usage of @mariozechner/pi-web-ui - Reusable AI chat interface" />
|
<meta name="description" content="Agent JAE - AI Coding Agent by JaeSwift" />
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-background">
|
<body class="bg-background">
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
|
||||||
BIN
packages/web-ui/example/public/apple-touch-icon.png
Normal file
BIN
packages/web-ui/example/public/apple-touch-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
BIN
packages/web-ui/example/public/favicon.ico
Normal file
BIN
packages/web-ui/example/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -258,22 +258,38 @@ async function createAgent(initialState?: AgentState) {
|
||||||
currentModel = model.modelId || "llama-3.3-70b";
|
currentModel = model.modelId || "llama-3.3-70b";
|
||||||
currentProvider = model.provider || "venice";
|
currentProvider = model.provider || "venice";
|
||||||
|
|
||||||
// Listen for agent messages to track state
|
// Subscribe to agent events for UI state tracking
|
||||||
agent.on("message", (msg: AgentMessage) => {
|
agent.subscribe((event) => {
|
||||||
if (!hasMessages && msg.role === "assistant") {
|
const typing = document.querySelector("jae-typing-indicator") as JaeTypingIndicator;
|
||||||
hasMessages = true;
|
const mood = document.querySelector("jae-mood-indicator") as JaeMoodIndicator;
|
||||||
renderApp();
|
|
||||||
}
|
switch (event.type) {
|
||||||
// Track tool usage for mood and auto-open panels
|
case "agent_start":
|
||||||
if (msg.role === "assistant" && msg.toolCalls) {
|
if (typing) typing.show("high");
|
||||||
for (const tc of msg.toolCalls) {
|
break;
|
||||||
if (tc.name === "browser" || tc.name === "web_fetch" || tc.name === "navigate") {
|
|
||||||
|
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") {
|
if (rightPanel !== "browser") {
|
||||||
rightPanel = "browser";
|
rightPanel = "browser";
|
||||||
renderApp();
|
renderApp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tc.name === "bash") {
|
if (event.toolName === "bash") {
|
||||||
if (rightPanel !== "terminal") {
|
if (rightPanel !== "terminal") {
|
||||||
rightPanel = "terminal";
|
rightPanel = "terminal";
|
||||||
renderApp();
|
renderApp();
|
||||||
|
|
@ -283,46 +299,46 @@ async function createAgent(initialState?: AgentState) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
// 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
agent.on("stateChange", (state: string) => {
|
case "message_start": {
|
||||||
const typing = document.querySelector("jae-typing-indicator") as JaeTypingIndicator;
|
const msg = event.message;
|
||||||
if (typing) {
|
if (!hasMessages && msg.role === "assistant") {
|
||||||
if (state === "thinking" || state === "running") {
|
hasMessages = true;
|
||||||
typing.show("high");
|
renderApp();
|
||||||
} else if (state === "tool_calling") {
|
}
|
||||||
typing.show("medium");
|
// Auto-learn from user messages
|
||||||
} else {
|
if (msg.role === "user" && typeof msg.content === "string") {
|
||||||
typing.hide();
|
processMessageForMemory("user", msg.content);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Track cost
|
case "message_end": {
|
||||||
agent.on("usage", (usage: { inputTokens: number; outputTokens: number; totalTokens: number }) => {
|
const msg = event.message;
|
||||||
const costEl = document.querySelector("jae-cost-tracker") as CostTracker;
|
// Update mood based on assistant content
|
||||||
if (costEl && usage) {
|
if (mood && msg.role === "assistant" && typeof msg.content === "string") {
|
||||||
costEl.addUsage(usage.inputTokens || 0, usage.outputTokens || 0);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue