diff --git a/docs.json b/docs.json index 757829608..7e8a46c2d 100644 --- a/docs.json +++ b/docs.json @@ -321,7 +321,8 @@ "en/plugin/dev/components/command", "en/plugin/dev/components/tool", "en/plugin/dev/components/knowledge-engine", - "en/plugin/dev/components/parser" + "en/plugin/dev/components/parser", + "en/plugin/dev/components/page" ] }, "en/plugin/dev/style", @@ -528,7 +529,8 @@ "zh/plugin/dev/components/command", "zh/plugin/dev/components/tool", "zh/plugin/dev/components/knowledge-engine", - "zh/plugin/dev/components/parser" + "zh/plugin/dev/components/parser", + "zh/plugin/dev/components/page" ] }, "zh/plugin/dev/style", diff --git a/en/plugin/dev/components/add.mdx b/en/plugin/dev/components/add.mdx index 3325c390e..4bc82626a 100644 --- a/en/plugin/dev/components/add.mdx +++ b/en/plugin/dev/components/add.mdx @@ -9,6 +9,7 @@ Plugins consist of one or more components that provide different functionalities - Tools (Tool): Called by LLMs during execution of LangBot's built-in Local Agent. - Knowledge Engines (KnowledgeEngine): Provide knowledge base indexing and retrieval capabilities for LangBot, managing document ingestion, retrieval, and deletion. - Parsers (Parser): Parse binary files such as PDF, Word, etc. into structured text before document ingestion, for use by Knowledge Engines. +- Pages (Page): Register custom visual pages in the LangBot WebUI sidebar, providing admin panels, data displays, and interactive interfaces. ## Adding Components @@ -74,3 +75,4 @@ For detailed usage of each component, please refer to: - [Tool](./tool) - [KnowledgeEngine](./knowledge-engine) - [Parser](./parser) +- [Page](./page) diff --git a/en/plugin/dev/components/page.mdx b/en/plugin/dev/components/page.mdx new file mode 100644 index 000000000..13f6efbf8 --- /dev/null +++ b/en/plugin/dev/components/page.mdx @@ -0,0 +1,245 @@ +--- +title: "Component: Page" +--- + +The Page component allows plugins to register custom visual pages in the LangBot WebUI sidebar. Pages run inside an iframe sandbox, communicate with the host via the Page SDK, and can call the plugin's backend API. + +## Use Cases + +- **Admin panels**: Provide visual configuration and data management interfaces (e.g., FAQ management, analytics dashboards) +- **Data displays**: Show runtime statistics, logs, charts, etc. +- **Interactive tools**: Provide forms, editors, and other interactive interfaces + +## Adding a Page Component + +Run the following command in the plugin directory: + +```bash +lbp comp Page +``` + +After entering the page name, the CLI will generate page files under `components/pages/`: + +```bash +├── components +│ └── pages +│ └── dashboard +│ ├── dashboard.yaml # Page manifest +│ ├── dashboard.py # Backend handler +│ ├── index.html # Page entry point +│ └── i18n # Translation files (optional) +│ ├── en_US.json +│ └── zh_Hans.json +``` + +The plugin's `manifest.yaml` will also be updated with the component discovery config: + +```yaml +spec: + components: + Page: + fromDirs: + - path: components/pages/ + maxDepth: 2 +``` + +## Manifest File: Page + +```yaml +apiVersion: v1 # Do not modify +kind: Page # Do not modify +metadata: + name: dashboard # Unique page ID within the plugin + label: + en_US: Dashboard # Display name shown in the WebUI sidebar, supports i18n + zh_Hans: 仪表盘 +spec: + path: index.html # HTML entry file, relative to this YAML file's directory +execution: + python: + path: dashboard.py # Backend handler file + attr: DashboardPage # Handler class name +``` + +## Backend Handler + +The Page component's backend handler extends the `Page` base class and implements `handle_api` to process API requests from the frontend page. + +```python +from langbot_plugin.api.definition.components.page import Page, PageRequest, PageResponse + + +class DashboardPage(Page): + + async def handle_api(self, request: PageRequest) -> PageResponse: + # request.endpoint: API endpoint path, e.g. '/stats' + # request.method: HTTP method (GET, POST, PUT, DELETE) + # request.body: Request body (parsed JSON, or None) + + if request.endpoint == '/stats' and request.method == 'GET': + # Access shared plugin state via self.plugin + return PageResponse.ok({ + 'total': len(self.plugin.entries), + }) + + return PageResponse.fail(f'Unknown endpoint: {request.endpoint}') +``` + +### PageRequest Fields + +| Field | Type | Description | +|-------|------|-------------| +| `endpoint` | `str` | API endpoint path (e.g. `'/entries'`) | +| `method` | `str` | HTTP method (`GET`, `POST`, `PUT`, `DELETE`) | +| `body` | `Any` | Request body (parsed JSON, or `None`) | + +### PageResponse Construction + +| Method | Description | +|--------|-------------| +| `PageResponse.ok(data)` | Success response. `data` can be any JSON-serializable value | +| `PageResponse.fail(error)` | Error response. `error` is a human-readable error string | + +## Frontend Page Development + +Include the Page SDK in your HTML file to communicate with the plugin backend: + +```html + + +
+ + + + +