const logEl = document.querySelector("#log"); const toolListEl = document.querySelector("#tool-list"); const nativeStatusEl = document.querySelector("#native-status"); const orderStateEl = document.querySelector("#order-state"); const nativeModelContext = window.navigator.modelContext; const registry = new Map(); const demoOrders = { "CHR-2026-0614": { orderId: "CHR-2026-0614", status: "delivered", risk: "missing_accessory", customerTier: "enterprise", nextAction: "open_refund_review", }, }; const modelContext = nativeModelContext ?? createMockModelContext(); nativeStatusEl.textContent = nativeModelContext ? "Native WebMCP detected" : "Mock WebMCP runtime"; nativeStatusEl.className = `pill ${nativeModelContext ? "native" : "mock"}`; registerDeclarativeForms(); registerImperativeTools(); renderTools(); log("runtime.ready", { nativeWebMcp: Boolean(nativeModelContext), registeredTools: Array.from(registry.keys()), }); document.querySelector("#ticket-form").addEventListener("submit", async (event) => { event.preventDefault(); const form = event.currentTarget; const toolName = form.getAttribute("toolname"); const payload = Object.fromEntries(new FormData(form).entries()); const result = await runTool(toolName, payload); log("form.submit", result); }); document.querySelectorAll("[data-run-tool]").forEach((button) => { button.addEventListener("click", async () => { const name = button.getAttribute("data-run-tool"); const input = sampleInputFor(name); const result = await runTool(name, input); log(`tool.${name}`, result); }); }); document.querySelector("#run-workflow").addEventListener("click", async () => { log("agent.plan", { task: "客户反馈缺少配件,请查询订单、判断是否进入退款审核,并生成回复草稿。", }); const order = await runTool("lookup_order_status", { orderId: "CHR-2026-0614" }); const refund = await runTool("approve_refund_review", { orderId: order.orderId, reason: "missing_accessory", }); const reply = await runTool("draft_customer_reply", { email: "dev@example.com", category: "refund", orderId: order.orderId, }); log("agent.workflow.complete", { order, refund, reply }); }); function createMockModelContext() { return { registerTool(tool) { registry.set(tool.name, tool); return Promise.resolve({ name: tool.name, mock: true }); }, }; } function registerDeclarativeForms() { document.querySelectorAll("form[toolname]").forEach((form) => { const name = form.getAttribute("toolname"); const description = form.getAttribute("tooldescription") || `Submit ${name}`; const inputSchema = schemaFromForm(form); registerTool({ source: "declarative", name, description, inputSchema, execute: async (input) => { const ticketId = `SUP-${Date.now().toString().slice(-6)}`; return { ticketId, status: "created", summary: `${input.category} issue for ${input.email}`, visibleUpdate: "工单已创建,页面保留原有人类操作流程。", }; }, }); }); } function registerImperativeTools() { registerTool({ source: "imperative", name: "lookup_order_status", description: "Look up order status, risk and recommended next action by order id.", inputSchema: { type: "object", properties: { orderId: { type: "string", description: "Order id shown in the support workspace." }, }, required: ["orderId"], }, execute: async ({ orderId }) => { const order = demoOrders[orderId] ?? { orderId, status: "unknown", risk: "not_found", customerTier: "unknown", nextAction: "ask_user_for_more_information", }; orderStateEl.textContent = order.nextAction; return order; }, }); registerTool({ source: "imperative", name: "approve_refund_review", description: "Move an eligible order into refund review after checking business policy.", inputSchema: { type: "object", properties: { orderId: { type: "string" }, reason: { type: "string", enum: ["missing_accessory", "damaged_item", "delivery_delay"], }, }, required: ["orderId", "reason"], }, execute: async ({ orderId, reason }) => { orderStateEl.textContent = "已进入退款审核"; return { orderId, reason, approvedForReview: true, needsHumanConfirmation: true, message: "敏感动作只进入审核,不直接退款。", }; }, }); registerTool({ source: "imperative", name: "draft_customer_reply", description: "Draft a support reply based on customer issue category and order id.", inputSchema: { type: "object", properties: { email: { type: "string", format: "email" }, category: { type: "string", enum: ["refund", "delivery", "account"] }, orderId: { type: "string" }, }, required: ["email", "category", "orderId"], }, execute: async ({ email, category, orderId }) => ({ to: email, category, orderId, draft: "我们已经定位到该订单的缺件问题,并将它提交到退款审核。审核完成前不会自动扣改账户,请等待人工确认。", }), }); } function registerTool(tool) { registry.set(tool.name, tool); const nativePayload = { name: tool.name, description: tool.description, inputSchema: tool.inputSchema, execute: tool.execute, }; try { modelContext.registerTool(nativePayload); } catch (error) { log("register.error", { tool: tool.name, message: error.message }); } } async function runTool(name, input) { const tool = registry.get(name); if (!tool) { throw new Error(`Unknown tool: ${name}`); } const result = await tool.execute(input); return { tool: name, input, output: result }; } function schemaFromForm(form) { const properties = {}; const required = []; form.querySelectorAll("input[name], select[name], textarea[name]").forEach((field) => { const name = field.getAttribute("name"); properties[name] = { type: inputTypeToJsonSchema(field), description: field.closest("label")?.firstChild?.textContent?.trim() || name, }; if (field.hasAttribute("required")) { required.push(name); } }); return { type: "object", properties, required }; } function inputTypeToJsonSchema(field) { if (field.tagName === "SELECT" || field.tagName === "TEXTAREA") { return "string"; } if (field.type === "number" || field.type === "range") { return "number"; } if (field.type === "checkbox") { return "boolean"; } return "string"; } function renderTools() { toolListEl.innerHTML = ""; registry.forEach((tool) => { const card = document.createElement("article"); card.className = "tool-card"; card.innerHTML = `
${tool.description}
${tool.source}${escapeHtml(JSON.stringify(tool.inputSchema, null, 2))}
`;
toolListEl.append(card);
});
}
function sampleInputFor(name) {
const samples = {
create_support_ticket: {
email: "dev@example.com",
category: "refund",
description: "订单 CHR-2026-0614 到货后发现配件缺失。",
},
lookup_order_status: { orderId: "CHR-2026-0614" },
approve_refund_review: { orderId: "CHR-2026-0614", reason: "missing_accessory" },
draft_customer_reply: {
email: "dev@example.com",
category: "refund",
orderId: "CHR-2026-0614",
},
};
return samples[name] ?? {};
}
function log(title, payload) {
const entry = document.createElement("div");
entry.className = "entry";
entry.innerHTML = `${title}${escapeHtml(JSON.stringify(payload, null, 2))}`;
logEl.prepend(entry);
}
function escapeHtml(value) {
return String(value)
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """);
}