Skip to content

Commit b8d6a8e

Browse files
committed
update ui extensions
1 parent a155320 commit b8d6a8e

File tree

1 file changed

+38
-34
lines changed

1 file changed

+38
-34
lines changed

content/docs/extensions/ui.mdx

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
---
22
title: UI Extensions API
3-
description: This guide provides a walkthrough of the LLM UI Extensions API (`ctx.mjs`), using the `xmas` extension as a practical example. The Extensions API allows you to customize the UI, add new pages, modify the layout, and intercept chat functionality.
3+
description: This guide provides a walkthrough of the LLM UI Extensions API which allows you to customize the UI, add new pages, modify the layout, and intercept chat functionality.
44
---
55

6+
We'll use the [xmas extension](https://github.com/llmspy/xmas/blob/main/ui/index.mjs) as a practical example to explore the capabilities
7+
in the App Extensions API which starts from [ctx.mjs](https://github.com/ServiceStack/llms/blob/main/llms/ui/ctx.mjs).
68

79
## Extension Entry Point
810

911
Every UI extension must export an object with an `install(ctx)` method. `ctx` is the `AppContext` instance which provides access to the core UI functionality.
1012

1113
```js
14+
let ext
15+
1216
export default {
1317
install(ctx) {
18+
// Manage state, stored prefs and API Integrations scoped to this ExtensionScope
19+
ext = ctx.scope('xmas')
20+
1421
// Registration logic goes here
1522
},
1623
async load(ctx) {
@@ -25,10 +32,9 @@ export default {
2532
You can register custom Vue components to be used throughout the application or to replace existing ones. This is done using `ctx.components()`.
2633

2734
### Replacing Core Components
28-
Overrides default components like `Brand`, `Welcome`, or `HomeTools` by registering components with the same name.
35+
Overrides default `Brand`, `Welcome`, and `HomeTools` components by registering components with the same name.
2936

3037
```js
31-
// Replace Brand component with a custom Christmas theme
3238
const Brand = {
3339
template: `
3440
<div class="flex-shrink-0 p-2 border-b border-gray-200 dark:border-gray-700 select-none">
@@ -38,37 +44,57 @@ const Brand = {
3844
</div>
3945
`,
4046
}
41-
4247
const Welcome = {
4348
template: `<!-- Custom Welcome Screen -->`,
4449
setup() { /* ... */ }
4550
}
46-
4751
const HomeTools = {
4852
template: `<DarkModeToggle class="mt-4" />`,
4953
}
5054

5155
export default {
5256
install(ctx) {
5357
ctx.components({
58+
// Replaces built-in UI Components
5459
Brand,
5560
Welcome,
5661
HomeTools,
57-
// Register other custom components
62+
// Registers other custom components used in this UI Extension
5863
XmasPage,
5964
XmasTopPanel,
6065
})
6166
}
6267
}
6368
```
6469

70+
## Full Example Component: Top Panel
71+
72+
This is how you define a complex UI component like a Top Panel. It's just a standard Vue 3 component.
73+
74+
```js
75+
const XmasTopPanel = {
76+
template: `
77+
<div class="w-full bg-red-800 ...">
78+
<!-- Panel Content -->
79+
<h1>Ask Santa</h1>
80+
<p>Chat directly with Santa Claus...</p>
81+
</div>
82+
`,
83+
setup() {
84+
return {
85+
// ... setup logic
86+
}
87+
}
88+
}
89+
```
90+
6591
## 2. Adding Navigation Icons
6692

6793
### Left Sidebar Icons
6894
Use `ctx.setLeftIcons(icons)` to add icons to the left sidebar.
6995

7096
* `component`: The Vue component for the icon button.
71-
* `isActive`: A function receiving `{ path }` to determine active state.
97+
* `isActive`: A function receiving layout parts like `{ path }` to determine active state.
7298

7399
```js
74100
ctx.setLeftIcons({
@@ -85,7 +111,7 @@ ctx.setLeftIcons({
85111
Use `ctx.setTopIcons(icons)` to add icons to the top navigation bar.
86112

87113
* `component`: The Vue component for the icon button.
88-
* `isActive`: A function receiving `{ top }` to determine active state.
114+
* `isActive`: A function receiving layout parts like `{ top }` to determine active state.
89115

90116
```js
91117
ctx.setTopIcons({
@@ -181,7 +207,7 @@ Use `ctx.chatRequestFilters` to modify the request body before it is sent to the
181207
ctx.chatRequestFilters.push(({ request, thread }) => {
182208
if (!isTopOpen()) return
183209

184-
// Enforce the system prompt for every request
210+
// Use Santa's system prompt for every request when XmasTopPanel is open
185211
request.messages = request.messages.filter(x => x.role !== 'system')
186212
request.messages.unshift({
187213
role: 'system',
@@ -231,9 +257,8 @@ The `XmasPage` component uses `ctx.chat.completion` to generate a Christmas stor
231257
```js
232258
onMounted(async () => {
233259
// 1. Find an available model
234-
const freeStoryModelNames = ['Kimi K2 0905', 'Kimi K2 Instruct', 'Kimi K2 (free)', 'Kimi Dev 72b (free)', 'GPT OSS 120B']
235-
const availableStoryModel = freeStoryModelNames.map(name => ctx.chat.getModel(name)).find(x => !!x)
236-
260+
const storyModelNames = ['Kimi K2 0905', 'Kimi K2 Instruct', 'Kimi K2 (free)', 'GPT OSS 120B']
261+
const availableStoryModel = storyModelNames.map(name => ctx.chat.getModel(name)).find(x => !!x)
237262
if (!availableStoryModel) {
238263
console.log('No story models available')
239264
return
@@ -244,7 +269,7 @@ onMounted(async () => {
244269
// 2. Create the request
245270
const request = ctx.chat.createRequest({
246271
model: availableStoryModel,
247-
text: `Write a short, feel-good Christmas story set on a quiet winter evening. Focus on simple kindness, cozy details, and gentle magic—twinkling lights, warm drinks, falling snow, and a small act of generosity that brings people together. Keep the tone hopeful and comforting, with a soft, joyful ending that leaves the reader smiling.`,
272+
text: `Write a short, feel-good Christmas story set on a quiet winter evening...`,
248273
systemPrompt: santaSystemPrompt,
249274
})
250275

@@ -261,24 +286,3 @@ onMounted(async () => {
261286
}
262287
})
263288
```
264-
265-
## Full Example Component: Top Panel
266-
267-
This is how you define a complex UI component like a Top Panel. It's just a standard Vue 3 component.
268-
269-
```js
270-
const XmasTopPanel = {
271-
template: `
272-
<div class="w-full bg-red-800 ...">
273-
<!-- Panel Content -->
274-
<h1>Ask Santa</h1>
275-
<p>Chat directly with Santa Claus...</p>
276-
</div>
277-
`,
278-
setup() {
279-
return {
280-
// ... setup logic
281-
}
282-
}
283-
}
284-
```

0 commit comments

Comments
 (0)