The Agent Experience (AX) Framework for Dual Human-Agent Web Applications
AgentLayerWeb is a framework-agnostic, client-side TypeScript library that introduces an Agent Experience (AX) design system. It allows developers to build web applications that are natively optimized and usable by both humans and AI browser agents.
It does not replace HTML, React, or your UI library. Instead, it adds a lightweight, zero-overhead semantic AX layer on top of existing components.
Application
βββ UI Layer (Optimized UX for humans)
βββ AgentLayerWeb (Optimized AX for AI agents)
By annotating your markup, humans continue using your visual interface normally, while AI agents (like Claude, GPT-4, or other WebMCP browsers/agents) gain a structured, programmatic understanding of page intent, available actions, form requirements, and state feedback. This establishes the web as a dual-medium interface.
Install the core annotations package or any framework wrapper from the monorepo:
# Core framework-agnostic package
pnpm add @agentlayerweb/core
# React wrappers (clones elements and attaches attributes)
pnpm add @agentlayerweb/react
# Vue directive bindings
pnpm add @agentlayerweb/vue
# Svelte action bindings
pnpm add @agentlayerweb/svelteReact wrapper components accept configurations and clone their direct children, attaching the semantic metadata:
import { AgentAction } from "@agentlayerweb/react";
<AgentAction id="checkout" intent="checkout" priority="primary">
<button onClick={handleCheckout}>Continue</button>
</AgentAction>;Bind attributes dynamically using the Vue custom directive v-agent:
<button v-agent="agent.action({ id: 'checkout', intent: 'checkout' })">
Checkout
</button>Attach attributes cleanly using Svelte action directives:
<button use:agentAction={agent.action({ id: 'checkout' })}>
Checkout
</button>Directly annotate DOM elements programmatically:
import { agent } from "@agentlayerweb/core";
const btn = document.querySelector("#checkout-btn");
agent.attach(btn, agent.action({ id: "checkout", intent: "checkout" }));Here is how to use every semantic primitive in the AgentLayerWeb API. In React, these are exported as components with prefix Agent (e.g. <AgentApp>). In Vue, Svelte, and Plain HTML, they are accessed under the agent namespace object.
Declares the root application metadata.
- React:
<AgentApp name="Portal" version="1.0" environment="production" description="Dashboard"> - Core API:
agent.app({ name: 'Portal', version: '1.0' })
Represents an active view or page route.
- React:
<AgentPage id="dashboard" title="Admin Dashboard" purpose="Manage billing"> - Core API:
agent.page({ id: 'dashboard', title: 'Admin Dashboard' })
A logical grouping of visual components.
- React:
<AgentSection id="profile_settings" title="Profile Details"> - Core API:
agent.section({ id: 'profile_settings', title: 'Profile Details' })
Marks standard navigation menus or navbars.
- React:
<AgentNavigation type="sidebar"> - Core API:
agent.navigation({ type: 'sidebar' })
An interactive action the agent can trigger (buttons, links).
- React:
<AgentAction id="save" intent="save" priority="primary" confirmation destructive> - Core API:
agent.action({ id: 'save', intent: 'save', priority: 'primary' })
Identifies user inputs forms and their submission action targets.
- React:
<AgentForm purpose="Update Email" submitAction="save_email"> - Core API:
agent.form({ purpose: 'Update Email', submitAction: 'save_email' })
Defines input field parameters, units, formats, and constraints.
- React:
<AgentField name="price" type="currency" label="Amount" required unit="AUD"> - Core API:
agent.field({ name: 'price', type: 'currency', required: true })
Marks specific business data objects (e.g. users, products).
- React:
<AgentEntity type="Invoice" id="inv_2026_99"> - Core API:
agent.entity({ type: 'Invoice', id: 'inv_99' })
Represents lists, grids, or collections of items.
- React:
<AgentCollection entity="Product" searchable filterable sortable> - Core API:
agent.collection({ entity: 'Product', searchable: true })
Specifies data tabular grids and active columns.
- React:
<AgentTable columns={['Name', 'Email']} sorting="Name" pagination="page-1"> - Core API:
agent.table({ columns: ['Name', 'Email'], sorting: 'Name' })
Search bars and input filters.
- React:
<AgentSearch target="Invoices"> - Core API:
agent.search({ target: 'Invoices' })
Active filter toggles or dropdowns.
- React:
<AgentFilter field="Status"> - Core API:
agent.filter({ field: 'Status' })
Sort order trigger controls.
- React:
<AgentSort field="Price"> - Core API:
agent.sort({ field: 'Price' })
Container for step-by-step user procedures.
- React:
<AgentWorkflow id="checkout_flow"> - Core API:
agent.workflow({ id: 'checkout_flow' })
Represent a single step in a workflow.
- React:
<AgentStep id="billing_step" current={true} completed={false} next="shipping_step"> - Core API:
agent.step({ id: 'billing_step', current: true })
Modals, dialog overlays, or warnings.
- React:
<AgentDialog purpose="Delete Property Warning"> - Core API:
agent.dialog({ purpose: 'Delete Property Warning' })
Asks the user or agent for confirmation.
- React:
<AgentConfirmation action="publish_listing"> - Core API:
agent.confirmation({ action: 'publish_listing' })
Indicates background server actions or rendering loading states.
- React:
<AgentLoading operation="Uploading documents..."> - Core API:
agent.loading({ operation: 'Uploading documents...' })
Success message prompts or states.
- React:
<AgentSuccess message="Item created successfully."> - Core API:
agent.success({ message: 'Success' })
Detailed error warning codes for agent recovery.
- React:
<AgentError code="EXPIRED_TOKEN"> - Core API:
agent.error({ code: 'EXPIRED_TOKEN' })
Lifecycle status indicators (e.g. active, draft).
- React:
<AgentStatus value="published"> - Core API:
agent.status({ value: 'published' })
Empty container warnings.
- React:
<AgentEmptyState reason="No documents uploaded yet."> - Core API:
agent.emptyState({ reason: 'No documents uploaded yet.' })
Nesting navigation hierarchies.
- React:
<AgentBreadcrumb path="Home > Listings > Edit"> - Core API:
agent.breadcrumb({ path: 'Home > Listings > Edit' })
Sidebar panels.
- React:
<AgentSidebar name="Control Center"> - Core API:
agent.sidebar({ name: 'Control Center' })
Tabbed interfaces.
- React:
<AgentTabs active="profile"> - Core API:
agent.tabs({ active: 'profile' })
Command menu search palettes.
- React:
<AgentCommand name="Quick Actions"> - Core API:
agent.command({ name: 'Quick Actions' })
Keyboard shortcut triggers.
- React:
<AgentShortcut keys="Ctrl+S"> - Core API:
agent.shortcut({ keys: 'Ctrl+S' })
Help hover tips.
- React:
<AgentTooltip text="Click to delete this list permanently."> - Core API:
agent.tooltip({ text: 'Click to delete this list permanently.' })
AgentLayerWeb primitives align closely with evolving open standards like the Web Model Context Protocol (WebMCP) so that WebMCP-compliant web browsers can read your tags out of the box.
When you annotate elements with AgentLayerWeb, the primitives automatically output standard declarative WebMCP HTML attributes alongside standard data-agent-* metadata:
toolname: The unique identifier of the tool/action (defaults to the primitive'sidorsubmitAction).tooldescription: Natural language description detailing what the tool does (defaults to the primitive'spurposeordescription).toolautosubmit: Boolean configuration specifying whether form tools should submit immediately upon being filled by an agent.
This allows browsers supporting WebMCP (such as Chrome Canary with the WebMCP flag enabled) to detect, register, and execute actions on your website natively as tools.
Audit your layout dynamically in the browser (or unit test environment) using the built-in validator. It catches nesting, reference, and registry violations:
import { validateAgentLayerWeb } from "@agentlayerweb/core";
// Scans the active DOM tree and logs warning summaries to console
const warnings = validateAgentLayerWeb();We run interactive benchmarks of AI browser agents executing multi-step workflows. The tests are executed directly against the local page files:
- Human Page (No Annotations): Website/src/app/example/human/page.tsx
- Agent Page (AgentLayerWeb): Website/src/app/example/agentlayerweb/page.tsx
The AI agent is given a complex form validation, modal approval, and state wait workflow task:
"Add a new client entity. Fill the Company Legal Name with 'error', fill the Billing Email with 'test@example.com', select 'Enterprise Tier' as the Billing Tier, click the 'Enable Auto-Charge billing sweeps' checkbox, and click the 'Create client profile' button. Wait for the validation error message to appear, then change the Company Legal Name to 'Acme Corp' and click 'Create client profile' again. Once the confirmation modal appears, click 'Confirm'. Wait until the loading state finishes, and verify that the success notice is shown."
To compare the approaches fairly, both scenarios run using the Model Context Protocol (MCP) to connect the AI Agent to the browser environment:
-
Scenario 1: Playwright MCP + Agent (Human Page)
- Setup: The agent connects to the official
@playwright/mcpserver. - Execution: The server launches a headed Chromium instance and exposes generic, low-level browser automation tools (
browser_click,browser_fill_form,browser_snapshot). The agent inspects the raw Accessibility Tree to locate element coordinates and CSS selectors, executing the workflow step-by-step. - Task Target: Visually optimized page with no agentic annotations.
- Setup: The agent connects to the official
-
Scenario 2: AgentLayerWeb + Agent (Agent Page)
- Setup: The agent connects to a custom semantic MCP server.
- Execution: The server exposes high-level, page-specific semantic tools (
get_page_state,create_client_profile,confirm_modal_action,wait_for_loader) directly generated from the AgentLayerWeb AX component properties. The agent operates purely on these high-level APIs without interacting with coordinates or selectors. - Task Target: Page optimized with AgentLayerWeb.
| Model | Scenario | Duration | Steps | Total Tokens | API Cost (USD) | Speedup & Savings |
|---|---|---|---|---|---|---|
| claude-haiku-4-5 | Human Page Agent Page |
76.11s 34.71s |
12 steps 8 steps |
135,110 13,346 |
$0.010633 $0.001309 |
2.19x speedup 90.1% token savings 87.7% cost reduction |
| gpt-4o-mini | Human Page Agent Page |
52.33s 15.49s |
11 steps 6 steps |
65,468 2,807 |
$0.005087 $0.000260 |
3.38x speedup 95.7% token savings 94.9% cost reduction |
Note: LLM planning noise is common on lower-tier models where reasoning loop variations occur.
- Dramatic Efficiency Gains: For capable models (like
gpt-4o-mini), using high-level semantic tools generated by AgentLayerWeb yields a 3.38x speedup and 95.7% token savings. - Minimal Steps: Instead of wasting steps writing custom CSS selectors, dealing with browser syntax errors (e.g.
:contains), or fetching raw page HTML repeatedly, the agent performs actions directly, resolving the form validation flow in just 6 steps vs 11 steps on the raw DOM.
Web scraping is a core capability of AI agents. To test how AgentLayerWeb affects scraping efficiency, we benchmarked the extraction of the onboarding portal layout using Crawl4AI and the tiktoken library (average of 3 runs). The results are saved in docs/crawl4ai-benchmark-results.json.
When scraping the full dashboard, traditional HTML is bloated with visual presentation classes (like Tailwind utilities) and visual structural wrappers. AgentLayerWeb pages allow scrapers to completely discard the styling layer while preserving semantic context:
| Metric | Human Page (Raw HTML) | AgentLayer Page (Cleaned & Stripped AX HTML)* | Savings / Speedup |
|---|---|---|---|
| Crawl Duration | 1.36s | 1.01s | β‘ 1.35x speedup |
| Page Size (Tokens) | 9,445 tokens | 2,620 tokens | π 72.3% token savings |
| Estimated Input Cost | $0.000708 | $0.000197 | π° 72.3% cost reduction |
If the scraper targets only the primary interactive form (#new-client-form):
| Metric | Human Form (Raw HTML) | AgentLayer Form (Stripped Class/Style AX HTML)* | Savings / Speedup |
|---|---|---|---|
| Form Size (Tokens) | 659 tokens | 418 tokens | π 36.6% token savings |
| Estimated Input Cost | $0.000049 | $0.000031 | π° 36.6% cost reduction |
*Note: Cleaned & Stripped AX HTML refers to removing all class and style attributes, scripts, SVGs, and visual wrappers. Because the AgentLayer page uses semantic data-agent-* metadata, the crawler can strip all presentation styling without degrading the agent's comprehension.
Scraping visually optimized human layouts (UX) presents major problems for AI models, which are solved by the Agent Experience (AX) layout model:
Traditional HTML requires styling classes to provide visual hierarchy hints to humans. However, style class strings (e.g. className="w-full px-12 py-8 bg-background-base border border-border-loud...") bloat the page size and consume unnecessary context window tokens.
- The AX Solution: Because AgentLayerWeb annotates elements directly with semantic descriptions (e.g.
data-agent-field="billing_email"), your crawler can completely strip theclassandstyleattributes before passing the HTML to the LLM. - The Impact: This yields a 72.3% reduction in input tokens. Scrapers operate on a clean semantic tree, cutting API cost and latency drastically.
Visually optimized pages frequently change class names, element nesting, or IDs during framework upgrades or site redesigns.
- The AX Solution: Scrapers use stable selectors targeting developer-defined agent attributes (e.g.
css=[data-agent-field="company_name"]orcss=[data-agent-role="form"]). - The Impact: Web scrapers remain immune to visual refreshes and design updates. Locators continue to work as long as the underlying page logic doesn't change.
To scrape form specifications, agents must read label tags, associate them with inputs, and guess validator constraints.
- The AX Solution: AgentLayerWeb forms provide explicit validation metadata:
<input type="text" data-agent-field="company_name" data-agent-label="Company legal corporate name" data-agent-required="true" data-agent-type="text" />
- The Impact: Crawling frameworks can instantly convert these inputs into clean, JSON-schema tool parameters, enabling AI scrapers to interact with pages as if they were structured Web APIs.
- docs/browser-use-results.json: Contains the consolidated summary workflow comparison statistics across all models.
- docs/browser-use-raw-traces.json: Contains the detailed step-by-step tool invocation traces and durations for each model run.
- docs/crawl4ai-benchmark-results.json: Contains the raw Crawl4AI page size, crawl time, token count, and cost data.