- Updated iframe documentation to remove token handling from the setup message, clarifying the focus on theme and locale. - Added a new section in MCP documentation detailing HTTP transport configuration for API access, enhancing clarity on authorization. - Revised frontend API documentation to standardize method naming by removing the 'Api' prefix in examples, improving consistency across backend calls. - Enhanced event handling documentation by updating method names in examples, ensuring alignment with the new naming conventions.
8.4 KiB
Agent SUI
Agent SUI is a special SUI configuration designed for AI Agent applications. It automatically loads pages from the /agent/template/ directory and individual assistant pages from /assistants/<name>/pages/.
Directory Structure
<app>/
├── agent/
│ ├── agent.yao # Agent configuration
│ └── template/ # Agent SUI template directory
│ ├── template.json # Optional template configuration
│ ├── __document.html # Global document template
│ ├── __data.json # Global data
│ ├── __assets/ # Global assets (CSS, JS, images)
│ │ ├── css/
│ │ ├── js/
│ │ └── images/
│ ├── pages/ # Global agent pages (login, error, etc.)
│ │ └── login/
│ │ └── login.html
│ └── __locales/ # Internationalization
│
└── assistants/ # Assistants directory
├── demo/ # Assistant: demo
│ ├── package.yao # Assistant configuration
│ └── pages/ # Assistant-specific pages
│ ├── index/
│ │ ├── index.html
│ │ ├── index.css
│ │ └── index.ts
│ └── __assets/ # Optional assistant-specific assets
│
└── another/ # Assistant: another
├── package.yao
└── pages/
└── settings/
└── settings.html
Route Mapping
| File Path | Public URL |
|---|---|
/agent/template/pages/login/login.html |
/agents/login |
/assistants/demo/pages/index/index.html |
/agents/demo/index |
/assistants/another/pages/settings/settings.html |
/agents/another/settings |
Asset Paths
- Global assets:
/agents/assets/...→/agent/template/__assets/... - Assistant assets:
/agents/<assistant-id>/assets/...→/assistants/<assistant-id>/pages/__assets/...
Build Commands
# Build Agent SUI
yao sui build agent
# Watch Agent SUI for changes
yao sui watch agent
Build Output
After running yao sui build agent, the following structure is generated:
<app>/public/
└── agents/ # Public root for Agent SUI
├── assets/ # Static assets
│ ├── libsui.min.js # SUI frontend SDK
│ ├── libsui.min.js.map # Source map
│ ├── css/ # From /agent/template/__assets/css/
│ ├── js/ # From /agent/template/__assets/js/
│ └── images/ # From /agent/template/__assets/images/
│
├── login.sui # Compiled page
├── login.cfg # Page configuration
│
├── demo/ # Assistant: demo
│ ├── index.sui # Compiled page
│ └── index.cfg # Page configuration
│
└── another/ # Assistant: another
├── settings.sui # Compiled page
└── settings.cfg # Page configuration
File Types:
| Extension | Description |
|---|---|
.sui |
Compiled HTML page (includes template, styles, scripts) |
.cfg |
Page configuration (JSON format) |
.jit |
JIT component (for dynamic loading) |
Auto-Loading
Agent SUI is automatically loaded when:
- The
/agent/template/directory exists - At least one assistant has a
pages/directory
No additional configuration is required.
Document Template
Create /agent/template/__document.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{{ $global.title }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/agents/assets/images/favicon.png" />
</head>
<body>
<div class="container">{{ __page }}</div>
</body>
</html>
Global Data
Create /agent/template/__data.json:
{
"title": "AI Agent",
"version": "1.0.0",
"theme": "light"
}
Example Assistant Page
/assistants/demo/pages/index/index.html:
<div id="demo-index" class="page">
<h1>{{ title }}</h1>
<div class="content">
<p>{{ description }}</p>
</div>
</div>
/assistants/demo/pages/index/index.json:
{
"title": "Welcome",
"description": "This is a demo page"
}
/assistants/demo/pages/index/index.css:
.page {
max-width: 800px;
margin: 0 auto;
padding: 24px;
}
Page Configuration
Create <page>.config for page settings:
{
"title": "Page Title",
"guard": "bearer-jwt",
"cache": 3600
}
Backend Scripts
Each page can have a backend script:
/assistants/demo/pages/index/index.backend.ts:
function BeforeRender(request: Request): Record<string, any> {
return {
user: Process("session.Get", "user"),
data: Process("models.data.Get", {}),
};
}
function ApiGetData(request: Request): any {
return Process("models.data.Get", {});
}
Using Components
Pages can use other pages as components:
<import s:as="Header" s:from="/shared/header" />
<import s:as="Footer" s:from="/shared/footer" />
<div class="page">
<header title="Demo" />
<main>
<p>Content here</p>
</main>
<footer />
</div>
Accessing in Templates
Use standard SUI template syntax:
<!-- Data binding -->
<h1>{{ title }}</h1>
<!-- Conditionals -->
<div s:if="{{ isLoggedIn }}">Welcome!</div>
<!-- Loops -->
<ul>
<li s:for="{{ items }}" s:for-item="item">{{ item.name }}</li>
</ul>
<!-- Events -->
<button s:on-click="handleClick">Click Me</button>
Frontend Script
Frontend scripts can be written in two styles:
Direct Style (Simple Pages)
// Runs immediately when script loads
document.addEventListener("DOMContentLoaded", () => {
const form = document.querySelector("#myForm") as HTMLFormElement;
form.addEventListener("submit", async (e) => {
e.preventDefault();
// Handle submission
});
});
// Smooth scrolling
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
anchor.addEventListener("click", function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute("href"));
target?.scrollIntoView({ behavior: "smooth" });
});
});
Component Style (Interactive Pages)
/assistants/demo/pages/index/index.ts:
import { $Backend, Component, EventData } from "@yao/sui";
const self = this as Component;
// Event handler bound to s:on-click="HandleClick"
self.HandleClick = async (event: Event, data: EventData) => {
const result = await $Backend().Call("GetData", data.id);
console.log(result);
};
// Form submission
self.HandleSubmit = async (event: Event) => {
event.preventDefault();
const form = event.target as HTMLFormElement;
const formData = new FormData(form);
await $Backend().Call("Submit", Object.fromEntries(formData));
};
CUI Integration
When Agent SUI pages are embedded in CUI via /web/ routes, they can communicate with the CUI host.
Receiving Context
window.addEventListener("message", (e) => {
if (e.origin !== window.location.origin) return;
if (e.data.type === "setup") {
const { theme, locale } = e.data.message;
document.documentElement.setAttribute("data-theme", theme);
}
});
Sending Actions
// Helper function
const sendAction = (name: string, payload?: any) => {
window.parent.postMessage(
{ type: "action", message: { name, payload } },
window.location.origin
);
};
// Show notification
sendAction("notify.success", { message: "Done!" });
// Navigate
sendAction("navigate", {
route: "/agents/demo/detail",
title: "Details",
});
// Close sidebar
sendAction("event.emit", { key: "app/closeSidebar", value: {} });
See Frontend API - CUI Integration for complete documentation.