Every page your app serves to humans gets a parallel agent view.
Like i18n, but the target locale is "agent."
Marketing page, blog post, product detail, authenticated dashboard. Any page that means something to a human means something to an agent. AVL ships that meaning directly — so agents don't have to reverse-engineer it from pixels.
Same data, different render. Token-efficient by design. Works for static sites, content sites, and authenticated apps.
AINode.dev is the first production site shipping AVL. Try it right now:
# Agent view — structured product spec, features, hardware, actions
curl -s https://ainode.dev/.agent
# Content negotiation
curl -s -H "Accept: text/agent-view" https://ainode.dev/
# Discovery manifest
curl -s https://ainode.dev/agent.txtSee Signaling Agent-Readiness below for how to add the badge to your site with structured metadata.
Before going deep, here's the shape of AVL across four common page types. Each example is the agent.ts that sits next to its page.tsx (or, for static sites, that feeds a build-time generator). See examples/ for runnable versions of each.
// examples/marketing-site/pages/austin.agent.ts
import { defineStaticAgentView } from "@frontier-infra/avl";
export default defineStaticAgentView({
intent: {
purpose: "Plumbing services in Austin, TX",
audience: ["homeowner", "property-manager"],
capability: ["call", "book", "quote"],
},
state: {
city: "Austin, TX",
services: ["leak repair", "water heater install", "drain cleaning"],
service_area: ["78701", "78704", "78745"],
hours: "24/7 emergency",
starting_price_usd: 89,
},
actions: [
{ id: "call_dispatch", method: "GET", href: "tel:+15125550123" },
{ id: "request_quote", method: "GET", href: "mailto:quotes@example.com" },
{ id: "directions", method: "GET", href: "https://maps.google.com/?q=..." },
],
});// examples/blog/posts/hello-world.agent.ts
import { defineStaticAgentView } from "@frontier-infra/avl";
export default defineStaticAgentView({
intent: {
purpose: "Blog post: Hello, AVL",
audience: ["reader", "developer"],
capability: ["read", "share", "subscribe"],
},
state: {
title: "Hello, AVL",
author: "Jason Brashear",
published: "2026-04-20",
reading_time_min: 4,
tags: ["avl", "agents", "announcement"],
},
actions: [
{ id: "subscribe", method: "POST", href: "/api/subscribe" },
{ id: "share", method: "GET", href: "https://twitter.com/intent/tweet?..." },
],
});// examples/product-page/products/stainless-kettle.agent.ts
import { defineStaticAgentView } from "@frontier-infra/avl";
export default defineStaticAgentView({
intent: {
purpose: "Product detail — stainless steel electric kettle",
audience: ["shopper"],
capability: ["buy", "save", "share"],
},
state: {
sku: "KTL-17-SS",
name: "1.7L Electric Kettle — Stainless",
price_usd: 49.0,
variants: ["brushed", "polished"],
inventory_count: 132,
rating: 4.6,
},
actions: [
{ id: "add_to_cart", method: "POST", href: "/api/cart/add" },
{ id: "save_for_later", method: "POST", href: "/api/wishlist/add" },
],
});// app/dashboard/agent.ts
import { defineAgentView } from "@frontier-infra/avl";
export default defineAgentView({
intent: {
purpose: "Project dashboard for active accounts",
audience: ["admin", "member"],
capability: ["review", "manage", "export"],
},
state: async ({ user }) => ({
projects: await getProjects({ userId: user.id }),
}),
actions: ({ user }) => [
{ id: "view_project", method: "GET", href: "/project/{id}.agent" },
user.role === "admin"
? { id: "advance_stage", method: "POST", href: "/api/project/{id}/advance" }
: null,
],
});Same six sections in every case. Static or dynamic, public or authenticated — the shape of an agent view never changes. What changes is whether the content is known at build time or resolved per-request against a session.
Web applications are built for humans with eyeballs and mice. When an AI agent arrives, it reverse-engineers pixels: scraping HTML, parsing the DOM, inferring intent from button colors, reconstructing what the server already knew.
This is backwards.
The page already holds:
- The structured data it's rendering (post bodies, product specs, service lists, user's projects)
- The reason the page exists (sell a product, explain a service, triage cases)
- The things a visitor can do from here (call, buy, subscribe, advance)
- The identity context, when applicable (the authenticated user and their permissions)
Then it throws all of it away to render HTML. When an agent arrives, it spends tokens and inference cycles recovering an approximation of what was just discarded.
AVL fills this gap. For every page your application serves to humans — static marketing page, blog post, docs page, product detail, authenticated app view — it serves a parallel agent-native view at the same URL with an .agent suffix.
/about-us → human view (HTML)
/about-us.agent → agent view (text/agent-view; version=1)
/blog/hello-world → human view
/blog/hello-world.agent → agent view
/dashboard → human view
/dashboard.agent → agent view
The agent view is not a summary of the HTML. It's a parallel rendering of the same server-side (or build-time) data, optimized for a consumer that reads tokens instead of pixels.
Three things are true right now:
-
AI agents are crossing from "read the web" to "use the web." Every major lab has shipped agent capabilities. Agents are logging in, navigating, clicking buttons, submitting forms. The demand is here.
-
Browser-use and computer-use agents are hitting their ceiling. They're expensive, fragile, and break on redesigns. The industry is investing enormous resources in making agents better at reverse-engineering pixels. This is a local maximum, not a solution.
-
Server-side rendering — and static site generation — are mainstream. Next.js, Remix, SvelteKit, Nuxt, Astro, 11ty, Hugo. The data is already structured, already on the server (or on disk), already in the author's hands — right before it gets turned into pixels. The incremental cost of adding a second rendering target is low.
AVL doesn't require a new web. It requires the web that already exists to ship one more rendering target for a consumer that's already at the door.
| System | Granularity | Intent | Actions | Auth-scoped | Producer | Static-friendly |
|---|---|---|---|---|---|---|
| Scraping (Firecrawl, Jina) | Page | No | No | No | No | n/a |
llms.txt |
Site | Light | No | No | Yes | Yes |
| OpenAPI / GraphQL | API | No | Yes | Sometimes | Yes | No |
| Schema.org | DOM | SEO | No | No | Yes | Yes |
| ARIA | Element | A11y | Partial | No | Yes | Yes |
| MCP | Tool | Yes | Yes | Yes | Yes | No |
| AVL | Page | Yes | Yes | When applicable | Yes | Yes |
AVL's wedge: page-level, intent-rich, action-affordant, producer-owned — and equally at home on a static marketing site and an authenticated SaaS dashboard.
MCP is the hands. AVL is the eyes.
An AVL document at any .agent URL contains six sections. Every section is optional except @meta and @intent.
Version, route, generation timestamp, TTL, and — if the page is authenticated — the identity the document was rendered for. Housekeeping.
Why this page exists. Three fields: purpose, audience, capability. An agent reads this first and decides in four lines whether this page is relevant to its task. This is the section scrapers can never recover — DOM structure tells you what a page contains, not why it exists or who it's for.
The structured data backing this page. Encoded in TOON (Token-Oriented Object Notation) for 50–70% token savings over JSON. The shape of @state varies by page type:
| Page type | @state holds |
|---|---|
| Marketing / service area | Facts — city, services, prices, service area zip codes, hours |
| Blog post | Title, author, published date, tags, reading time |
| Docs page | Section, topic, last-updated, prev/next |
| Product page | SKU, price, variants, inventory count, rating |
| Authenticated dashboard | The user's projects, alerts, recent activity — RBAC-filtered |
For authenticated routes, @state is filtered server-side per role. For static pages, it's just facts — the same facts a human sees on the rendered page.
What the visitor can do from here. Each action has an ID, an HTTP method, a URL, and an optional input schema. Actions aren't limited to in-app endpoints:
| Scheme | Example use |
|---|---|
tel: |
Call dispatch from a service-area page |
mailto: |
Request a quote, subscribe to a newsletter |
| External URL | "Get directions" to Google Maps, share to Twitter |
| Same-origin POST | Add-to-cart, advance-stage, submit-form |
| Same-origin GET | Navigate to a detail page's .agent view |
For authenticated routes, @actions are filtered per role — a read-only user simply doesn't see write-capable entries. The absence of an action is the authorization signal.
Narrative markdown capturing the "so what." What would an analyst, a copywriter, or an editor say about this page in one sentence? "3 active projects, 1 high-risk, deadline in 6 days." "Licensed master plumbers in Austin since 1998." "This post explains how AVL differs from MCP in 250 words."
Where to go next. Self link, parents, peers, drilldown templates. The agent can walk the site's information architecture without parsing <a> tags.
Not every page has an authenticated session behind it. Most pages on the public web — service-area pages, blog posts, doc sites, product catalogs, company pages, support articles — are static content. AVL's static support treats these as a first-class case, not an afterthought.
The static primitive has the same six AVL sections as defineAgentView — but no request context, no auth, no RBAC filtering. Each field accepts a plain value or a zero-arg (possibly async) producer, so you can pull from markdown frontmatter, JSON, or an external content API at build time.
import { defineStaticAgentView } from "@frontier-infra/avl";
export default defineStaticAgentView({
intent: {
purpose: "About page for a licensed Austin plumber",
audience: ["prospective-customer"],
capability: ["call", "quote", "learn"],
},
state: {
founded: 1998,
city: "Austin, TX",
credentials: ["Master Plumber #M-39214", "TCEQ Licensed"],
},
actions: [
{ id: "call_dispatch", method: "GET", href: "tel:+15125550123" },
{ id: "email_quote", method: "GET", href: "mailto:quotes@example.com" },
],
context: "Family-owned plumbing contractor serving greater Austin since 1998.",
});A framework-agnostic build-time generator. Pass a list of { url, view } pairs plus an output directory; the generator emits one .agent file per page alongside your static HTML:
import { generateStaticAgentViews } from "@frontier-infra/avl";
import home from "./pages/index.agent";
import about from "./pages/about.agent";
import austin from "./pages/services/austin.agent";
await generateStaticAgentViews({
outDir: "dist",
pages: [
{ url: "/", view: home },
{ url: "/about-us", view: about },
{ url: "/services/austin", view: austin },
],
// Optional: shared timestamp for reproducible builds
generatedAt: process.env.BUILD_TIME ?? new Date().toISOString(),
});Default output convention: /about-us → about-us.agent at the output-dir root (mirrors AVL's URL convention /about-us ↔ /about-us.agent). Override per-page (outputPath) or globally (resolveOutputPath) if your SSG prefers a different layout.
Runnable examples:
examples/marketing-site— 3-page service businessexamples/blog— blog index + articlesexamples/docs-site— a small docs setexamples/product-page— e-commerce product detail
Public CMS pages are a natural fit for AVL: the CMS already owns the route,
title, excerpt, taxonomy, author, and permalink. An AVL plugin just renders
that same CMS record as a .agent companion and advertises discovery from the
human page.
The first production CMS plugin lives in plugins/WordPress:
GET /agent.txtpublishes a site-level AVL manifest.GET /.agentpublishes the front page companion.GET /some-page.agentpublishes an agent view for public posts, pages, and custom post types.- Public human pages advertise their companion with head links,
Linkheaders, and badge metadata. - The admin panel controls badge type, colors, placement, post types, TTL, and WordPress framework compatibility.
- Optional page-builder add-ons support Divi, Elementor, and Beaver Builder.
The Ghost work area lives in plugins/Ghost. Ghost does not
map cleanly to WordPress-style plugins, so that adapter is structured as a
helper service and document renderer that can be connected through Ghost Content
API, theme, static-generation, or reverse-proxy routes.
The folder is intentionally named by CMS so additional adapters can follow the
same pattern later: plugins/Drupal, plugins/Joomla, plugins/ConcreteCMS,
plugins/TYPO3, plugins/Grav, and so on. See
docs/cms-adapters.md for the shared adapter contract.
AVL also ships an agent skill for building CMS adapters consistently across Codex, Claude Code, Gemini CLI, and future agent runtimes.
The canonical skill lives in agent-skills/avl-cms-adapter.
Generated deploy copies live in:
.codex/skills/avl-cms-adapter.claude/skills/avl-cms-adapter.gemini/skills/avl-cms-adapteragent-marketplaces/claudefor Claude Code marketplace packagingagent-extensions/gemini/avl-agent-skillsfor Gemini CLI extension packaging
After editing the canonical skill, sync and validate every deploy target:
agent-skills/scripts/sync-skill-targets.sh
agent-skills/scripts/validate-skills.shSee docs/agent-skills.md and
docs/skill-deployment.md for the full workflow.
npm install @frontier-infra/avlIf you want an AI coding agent to add AVL to a project, point it at
AI-IMPLEMENTATION.md. It is a self-contained
implementation brief with required routes, document sections, discovery
signals, security rules, framework patterns, and a validation checklist.
Author a defineStaticAgentView config per page (see AVL for Static Sites above) and call generateStaticAgentViews as a final step of your build.
Colocate an agent.ts next to your page.tsx:
// app/dashboard/agent.ts
import { defineAgentView } from "@frontier-infra/avl";
export default defineAgentView({
intent: {
purpose: "Project dashboard for active accounts",
audience: ["admin", "member"],
capability: ["review", "manage", "export"],
},
state: async ({ user }) => ({
projects: await getProjects({ userId: user.id }),
}),
actions: ({ user }) => [
{ id: "view_project", method: "GET", href: "/project/{id}.agent" },
user.role === "admin"
? { id: "advance_stage", method: "POST", href: "/api/project/{id}/advance" }
: null,
],
context: ({ state }) =>
`${state.projects.length} active projects.`,
nav: {
parents: ["/"],
drilldown: "/project/{id}",
},
meta: { ttl: "30s" },
});Wire the catch-all handler:
// app/agent/[[...path]]/route.ts
import { createAgentViewHandler } from "@frontier-infra/avl/next";
export const GET = createAgentViewHandler({
resolveSession: async (req) => {
const session = await getServerSession(authOptions);
if (!session?.user) return null;
return {
id: session.user.id,
role: session.user.role,
name: session.user.name,
};
},
routes: [
{ pattern: "/dashboard", view: dashboardAgent },
{ pattern: "/project/:id", view: projectAgent },
],
});That's it. Every page with an agent.ts now ships a parallel agent view. The framework handles routing, serialization, and caching.
This is what a fully rendered authenticated AVL document looks like — meta, intent, all six sections.
@meta
v: 1
route: /dashboard
generated: 2026-04-16T14:02:00Z
ttl: 30s
auth: session(admin:42)
@intent
purpose: Active case dashboard
audience: attorney, paralegal
capability: review, triage, advance
@state
user{id,role,firm}: u-42,attorney,Smith Law
journeys[3]{id,client,stage,deadline,risk}:
J-101,Doe v Acme,Discovery,2026-05-01,low
J-102,Roe v Beta,Settlement,2026-04-22,high
J-103,Vega v Gamma,Treatment,2026-04-30,med
@actions
- id: view_journey
method: GET
href: /journey/{id}.agent
- id: advance_stage
method: POST
href: /api/journey/{id}/advance
inputs[2]{name,type,required}:
target_stage_id,string,true
note,string,false
@context
> 3 active matters. 1 high-risk.
> J-102 (Settlement) — demand expires in 6 days.
@nav
self: /dashboard.agent
parents: [/]
peers: [/clients, /reports]
drilldown: /journey/{id}
The static examples in examples/ ship .agent files of the same shape — just with no auth line, and @state containing facts rather than per-user data.
Start at L0. Ship value at every step.
| Level | Sections | Effort | Value |
|---|---|---|---|
| L0 | @meta, @intent, page-specific body anchor |
Hours | Agents can triage routes — "Is this relevant?" — and fetchers can discover the companion URL |
| L1 | L0 + @state |
Days | Agents can read structured data without DOM parsing |
| L2 | L1 + @actions |
Days | Agents can operate — call, buy, submit forms |
| L3 | L2 + @nav, @context |
Weeks | Agents can traverse and understand the "so what" |
A static site can hit L3 in an afternoon. A medium-sized app can ship L0 across every route in a single day. No data integration, no action wiring for L0 — just a minimal agent.ts per route declaring intent plus a page-specific body link to the companion view. Any AI agent can already scan the site and build a map of what every page does and who it's for.
Public pages have no session — their @meta has no auth field, and their @state/@actions are whatever the static content dictates. No further discussion needed.
For authenticated pages, AVL's position is straightforward:
The agent is not a new principal. It is a delegate of an existing human session.
When a user authenticates, their session is valid for both the human view and the agent view. The agent inherits the user's identity, role, and permissions. It sees exactly what the user sees — no more, no less.
Three delivery mechanisms serve one identity model:
- Cookie forwarding — Browser-embedded agents (the cookie is already there)
- Bearer token — Local AI agents (user generates a scoped token)
- OAuth delegation — Third-party AI services (standard OAuth2 flow)
All three resolve to the same session. AVL doesn't define auth; it provides one contract:
resolveSession: (req: Request) => Promise<AgentSession | null>Your app implements it. AVL renders accordingly.
The invariant is Surface Equivalence: every @state field is visible to this user in the human UI, and every @actions entry corresponds to a UI affordance the user can invoke. If either fails, the AVL view is leaking.
AI agents are priced per token. @state uses TOON (Token-Oriented Object Notation) instead of JSON for a 50–70% reduction in serialization size.
// JSON: ~156 tokens
{"journeys":[{"id":"J-101","client":"Doe v Acme","stage":"Discovery"},
{"id":"J-102","client":"Roe v Beta","stage":"Settlement"}]}
// TOON: ~50 tokens
journeys[2]{id,client,stage}:
J-101,Doe v Acme,Discovery
J-102,Roe v Beta,Settlement
TOON is simple enough for any LLM to parse natively. The grammar is intentionally lean — no formal specification needed yet. Real-world use will guide evolution.
Three mechanisms, plus HTML signals that make the agent view discoverable from the human page itself:
GET /about-us
Accept: text/agent-view
This has the lowest discovery cost for agents that can send custom headers: the user-provided URL stays the URL, and the agent asks for the agent-native representation.
/about-us.agent
/blog/hello-world.agent
/product/kettle-17-ss.agent
/dashboard.agent
Cacheable by any HTTP cache, shareable, debuggable in any browser, curl-able without special headers.
<link rel="alternate" type="text/agent-view" href="/about-us.agent">
<a href="/about-us.agent" rel="alternate agent-view" type="text/agent-view">
Agent view of this page
</a>
GET /agent.txt
version: 1
discovery: [accept-header, suffix]
routes:
- GET /about-us.agent
- GET /blog/{slug}.agent
- GET /dashboard.agent # session required
agent_views:
- GET /.agent
- GET /about-us.agent
- GET /blog/hello-world.agent
- GET /dashboard.agent
AVL has three discovery layers (URL suffix, content negotiation, agent.txt). But there's a fourth — the HTML itself. When your site already knows it's agent-ready, it should ship that knowledge in the markup, not leave it implicit.
For API fetchers with URL-provenance gates, a body <a href> to the current
page's companion is the strongest discovery signal. Head links, badges, and
data-* attributes are still useful, but they are not substitutes for a
navigable per-page anchor.
A badge serves three audiences from one HTML element:
| Audience | What they get |
|---|---|
| Humans | A visual indicator that the site is agent-ready |
| AI crawlers | Structured metadata in alt and title attributes |
| Programmatic scrapers | data-* attributes for machine-readable discovery |
<link rel="alternate" type="text/agent-view" href="/services/water-heater-installation.agent">
<a
href="/services/water-heater-installation.agent"
rel="alternate agent-view"
type="text/agent-view"
data-avl-companion="page"
>
Agent view of this page
</a>If a visible link does not fit the design, keep the anchor crawlable and visually hide it:
<a
href="/services/water-heater-installation.agent"
rel="alternate agent-view"
type="text/agent-view"
data-avl-companion="page"
style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0"
>
Agent view of this page
</a>The badge should point at the current page's .agent companion, not only
the site root. Pack the alt text with structured discovery metadata, but
keep the page-specific href as the primary machine-readable signal:
<div
role="group"
aria-label="Platform capabilities"
data-agent-discovery="true"
data-avl-endpoint="/services/water-heater-installation.agent"
data-avl-manifest="/agent.txt"
data-avl-package="@frontier-infra/avl"
>
<a
href="/services/water-heater-installation.agent"
rel="alternate agent-view"
type="text/agent-view"
title="AVL (Agent View Layer) — This site serves parallel structured views
for AI agents. Same session, zero scraping."
>
<img
src="https://raw.githubusercontent.com/frontier-infra/avl/main/assets/avl-badge.svg"
alt="AVL agent-ready — This page ships an AVL companion at
/services/water-heater-installation.agent. Structured @intent,
@state, @actions, and @context for AI agents. Discovery:
/agent.txt | npm: @frontier-infra/avl |
Spec: https://github.com/frontier-infra/avl"
/>
<span title="This site exposes structured agent views at *.agent URLs">
agent-ready
</span>
</a>
</div>The AVL philosophy is: the site already knows what it means — ship that knowledge. This applies at every layer:
- Pages know their intent, state, and actions → ship them via
.agentviews - The site knows its routes and discovery model → ship them via
agent.txt - The HTML knows it's agent-ready → ship that via head alternates, body links, and badges with structured metadata
A decorative badge that says "agent-ready" is a missed opportunity. The same badge with a page-specific href, structured alt, title, and data-* attributes becomes a discovery mechanism. An AI crawler parsing the DOM finds the AVL endpoints without making a single extra request.
This is how AINode.dev uses badges — each one carries the full tech stack metadata (AVL endpoints, cluster specs, inference engine, model support) in alt text that agents can parse directly.
- Full Specification — Format grammar, conformance levels, security model
- AI Implementation Brief — One file to give an AI coding agent so it can implement AVL in a project
- Conformance — L0-L3 checks, discovery requirements, and validator roadmap
- Governance — Proposal process, spec versioning, and standards-track path
- vNext Proposals — Companion links, provenance, well-known discovery, media, and validator ideas
- TOON Grammar Draft — Draft grammar and fixtures for token-efficient state
- Discovery —
.agent,/agent.txt,llms.txt, well-known, HTML, HTTP, and robots hints - AVL Thesis — The problem, the solution, why now
- Auth Thesis — Same session, different render. Zero new auth surface.
- Adoption Strategy — Ecosystem rollout, validation, CMS plugins, and standards positioning
- Non-Next.js Guide — Universal implementation pattern for other stacks
- Badge Program — L0-L3 badge criteria and adopter directory concept
- Announcement Draft — Launch copy for the v0.2 release candidate
- CMS Adapters — WordPress, Ghost, page builders, and the shared plugin contract
- Agent Skills — Canonical AVL CMS adapter skill and runtime deploy targets
- Skill Deployment — Codex, Claude Code marketplace, and Gemini CLI extension setup
- Examples — Runnable demos across four page types
| Example | What it shows |
|---|---|
examples/marketing-site |
3-page local-services site. tel:, mailto:, directions actions. |
examples/blog |
Blog index + posts. Subscribe, share actions. |
examples/docs-site |
A small docs set. Prev/next, edit-on-github. |
examples/product-page |
E-commerce product detail. Add-to-cart, save-for-later. |
examples/next-app |
Authenticated Next.js dashboard + detail views. |
Each static example ships its expected .agent output checked in under samples/ — you can read them without running the build.
git clone https://github.com/frontier-infra/avl.git
cd avl
npm install && npm run build
cd examples/next-app
npm install
npm run devThen:
# Human views
open http://localhost:3002/dashboard
open http://localhost:3002/journey/J-101
# Agent views
curl -s http://localhost:3002/dashboard.agent
curl -s http://localhost:3002/journey/J-101.agent
# Content negotiation
curl -s -H "Accept: text/agent-view" http://localhost:3002/dashboard
# Site manifest
curl -s http://localhost:3002/agent.txtcd examples/marketing-site # or blog / docs-site / product-page
npm install
npm run build
ls dist/*.agent- v0.1 (current) — npm package, Next.js adapter, static site generator, format spec, example apps across four page types
- v0.2 — MCP bridge adapter (derive MCP tools from
agent.tsmanifests), conformance test suite, auto-discovery ofagent.tsfiles at build time - v0.3 — Streaming state, delta requests
- v0.4 — Production caching, distributed rate limits
- v1.0 — RFC + reference implementations for SvelteKit, Remix, Nuxt, Astro, Rails
We're looking for early adopters, framework implementations, and real-world feedback. If you're building an agent-driven application — or just a static marketing site that you'd like agents to understand natively — AVL is for you.
- Contributing Guide — How to get started
- Code of Conduct — Community standards
- Open an issue to discuss your use case
- Submit a PR for adapters, examples, or spec improvements
AVL is the substrate that Argent OS uses to drive any host application. Where human users navigate via DOM and CSS, Argent OS navigates via AVL routes and action affordances. An app — or a static site — that ships AVL is a site Argent OS can drive without scraping, training, or human translation.
AVL mirrors how i18n works:
- One data pipeline. A locale parameter selects the rendering target.
- Different output format. Human view renders HTML. Agent view renders structured text.
- Colocated authoring. Developer writes
agent.tsnext topage.tsx(or next to the markdown file, or in the static-site config). - No duplication. Both views reuse the same data fetchers or the same source content.
- Easy to adopt. Start with L0 (just intent). Expand incrementally.
The server already does this for every other non-default audience. AVL is just the agent locale.