Marketplace
Supercharge your workflow
Discover and install custom actions for the tee extension. Browse automation tools built by the community or publish your own powerful workflows.
Page Chatbot
byAnonymous
A floating AI chatbot that can answer questions about the current page.
// ==============================================
// 🤖 UNIVERSAL PAGE CHATBOT (Widget SDK)
// ==============================================
const logoBase64 = "data:image/png;base64,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";
// --- STATE ---
let chatHistory = [
{ role: "assistant", text: "Hi! I'm your AI Page Assistant. Ask me anything about this page." }
];
let isThinking = false;
let messageCount = 0;
let pageSummary = "";
// --- UI COMPONENTS ---
/** @returns {WidgetComponent[]} */
function chatView() {
/** @type {WidgetComponent[]} */
const chatBubbles = chatHistory.map((msg) => ({
type: "row",
justify: msg.role === "user" ? "end" : "start",
components: [
{
type: "column", gap: "sm", padding: msg.role === "assistant" ? "md" : "none",
bg: msg.role === "assistant" ? "card2" : "transparent", rounded: true,
components: [
{
type: "text",
text: msg.role === "user" ? "You" : "AI",
size: "sm", weight: "bold",
color: msg.role === "user" ? "accent" : "muted"
},
{ type: "text", text: msg.text, size: "md", markdown: msg.role === "assistant" }
]
}
]
}));
return [
{
type: "column", padding: "sm", gap: "md",
components: [
// Header
{
type: "row", align: "center", justify: "between",
components: [
{
type: "row", align: "center", gap: "sm",
components: [
{ type: "image", src: logoBase64, width: "24px", height: "24px", rounded: true },
]
},
]
},
{ type: "divider" },
// Chat Area
{
type: "column", gap: "md", scroll: true, maxHeight: "350px",
components: [
...chatBubbles,
...(isThinking ? [
{
type: "row", align: "center", gap: "sm", padding: "sm",
components: [
{ type: "text", text: "AI is thinking...", size: "sm", color: "muted" }
]
}
] : [])
]
},
{ type: "divider" },
// Input Area
{
type: "row", gap: "sm", align: "center",
components: [
{ type: "input", id: "chatInput", placeholder: "Ask a question..." },
{ type: "button", id: "sendBtn", icon: "Send", variant: "primary" }
]
}
]
}
];
}
async function renderUI() {
await widget.show(chatView(), "bottom-right", { hideCloseButton: false });
}
// --- CORE LOGIC ---
async function handleSend() {
const userText = await widget.getValue("chatInput");
if (!userText || !userText.trim()) return;
chatHistory.push({ role: "user", text: userText });
isThinking = true;
await renderUI();
if (messageCount >= 5) {
chatHistory.push({ role: "assistant", text: "Liked it? You can make it your own! Upgrade to tee Premium to unlock unlimited messages, custom UI, and the ability to edit this exact script." });
isThinking = false;
await renderUI();
return;
}
try {
if (!pageSummary) {
const rawText = await page.getText();
pageSummary = await ai.prompt(
"Summarize the main content, context, and key details of this webpage to be used as context for answering user questions later. \n\n" + rawText.substring(0, 15000),
"You are a helpful summarization assistant."
);
}
let prompt = "You are a helpful AI assistant residing on a webpage. Use the following webpage content to answer the user's latest question. Be concise.\n\nPAGE CONTENT:\n" + pageSummary + "\n\nCHAT HISTORY:\n";
for (const msg of chatHistory) {
prompt += msg.role.toUpperCase() + ": " + msg.text + "\n";
}
prompt += "ASSISTANT: ";
const response = await ai.prompt(prompt);
messageCount++;
chatHistory.push({ role: "assistant", text: response });
} catch (err) {
chatHistory.push({ role: "assistant", text: "Error: " + err.message });
}
isThinking = false;
await renderUI();
}
// --- EVENT BINDING ENGINE ---
widget.on("sendBtn", "click", async () => {
await handleSend();
});
widget.on("chatInput", "enter", async () => {
await handleSend();
});
// --- LAUNCH ---
await renderUI();
await widget.waitForEvent("FOREVER_EVENT", "click");