Skip to content

Commit f351678

Browse files
committed
Merge branch 'next' of github.com:devforth/adminforth into next
2 parents a53aea9 + dd6901e commit f351678

30 files changed

Lines changed: 2070 additions & 292 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
[![Ask AI](http://tluma.ai/badge)](http://tluma.ai/ask-ai/devforth/adminforth)
77

8-
* [Try live demo](https://demo.adminforth.dev/) (Read-only mode)
8+
* [Try live demo](https://demo.adminforth.dev/)
99

1010
* [Hello world in 5 minutes](https://adminforth.dev/docs/tutorial/gettingStarted) with AdminForth
1111

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
export interface PluginOptions {
1+
import {type PluginsCommonOptions } from "adminforth";
2+
3+
export interface PluginOptions extends PluginsCommonOptions {
24

35
}

adminforth/documentation/docs/tutorial/08-Plugins/26-agent.md

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
This plugin adds an AI agent with a chat surface to AdminForth which is capable of default skills like searching/editing data and extending with custom skills.
77

8-
It stores session history in your own resources and uses any AdminForth completion adapter to generate responses.
8+
It stores session history in your own resources and generates responses using one of the configured `modes`.
99

1010
## Installation
1111

@@ -21,17 +21,21 @@ Add your LLM credentials to `.env`:
2121
OPENAI_API_KEY=your_key
2222
```
2323

24-
You can replace the OpenAI adapter with any completion adapter from [List of adapters](/docs/tutorial/ListOfAdapters/).
24+
Each mode accepts any AdminForth completion adapter, so you can replace the OpenAI adapter with another adapter from [List of adapters](/docs/tutorial/ListOfAdapters/).
2525

2626
## Setup
2727

2828
First create two resources for sessions and turns:
2929

3030
```ts title="./resources/agent_resources/sessions.ts"
3131
import AdminForth, { AdminForthDataTypes } from 'adminforth';
32-
import type { AdminForthResourceInput } from 'adminforth';
32+
import type { AdminForthResourceInput, AdminUser } from 'adminforth';
3333
import { randomUUID } from 'crypto';
3434

35+
async function allowedForSuperAdmins({ adminUser }: { adminUser: AdminUser }): Promise<boolean> {
36+
return adminUser.dbUser.role === 'superadmin';
37+
}
38+
3539
export default {
3640
dataSource: 'sqlite',
3741
table: 'sessions',
@@ -70,14 +74,27 @@ export default {
7074
},
7175
},
7276
],
77+
options: {
78+
allowedActions: {
79+
list: allowedForSuperAdmins,
80+
show: allowedForSuperAdmins,
81+
create: false,
82+
edit: false,
83+
delete: false,
84+
},
85+
},
7386
} as AdminForthResourceInput;
7487
```
7588

7689
```ts title="./resources/agent_resources/turns.ts"
7790
import AdminForth, { AdminForthDataTypes } from 'adminforth';
78-
import type { AdminForthResourceInput } from 'adminforth';
91+
import type { AdminForthResourceInput, AdminUser } from 'adminforth';
7992
import { randomUUID } from 'crypto';
8093

94+
async function allowedForSuperAdmins({ adminUser }: { adminUser: AdminUser }): Promise<boolean> {
95+
return adminUser.dbUser.role === 'superadmin';
96+
}
97+
8198
export default {
8299
dataSource: 'sqlite',
83100
table: 'turns',
@@ -116,6 +133,15 @@ export default {
116133
type: AdminForthDataTypes.TEXT,
117134
},
118135
],
136+
options: {
137+
allowedActions: {
138+
list: allowedForSuperAdmins,
139+
show: allowedForSuperAdmins,
140+
create: false,
141+
edit: false,
142+
delete: false,
143+
},
144+
},
119145
} as AdminForthResourceInput;
120146
```
121147

@@ -166,6 +192,8 @@ export const admin = new AdminForth({
166192

167193
Then attach the plugin once, usually to your `adminuser` resource:
168194

195+
Configure the plugin with `modes`. The legacy top-level `completionAdapter` setup is no longer used.
196+
169197
```ts title="./resources/adminuser.ts"
170198
import AdminForthAgent from '@adminforth/agent';
171199
import CompletionAdapterOpenAIChatGPT from '@adminforth/completion-adapter-open-ai-chat-gpt';
@@ -175,12 +203,45 @@ import CompletionAdapterOpenAIChatGPT from '@adminforth/completion-adapter-open-
175203
plugins: [
176204
...
177205
new AdminForthAgent({
178-
completionAdapter: new CompletionAdapterOpenAIChatGPT({
179-
openAiApiKey: process.env.OPENAI_API_KEY as string,
180-
model: 'gpt-5.4-mini',
181-
}),
206+
modes: [
207+
{
208+
name: 'Balanced',
209+
completionAdapter: new CompletionAdapterOpenAIChatGPT({
210+
openAiApiKey: process.env.OPENAI_API_KEY as string,
211+
model: 'gpt-5.4-mini',
212+
extraRequestBodyParameters: {
213+
reasoning: {
214+
effort: 'medium',
215+
},
216+
},
217+
}),
218+
},
219+
{
220+
name: 'Fast',
221+
completionAdapter: new CompletionAdapterOpenAIChatGPT({
222+
openAiApiKey: process.env.OPENAI_API_KEY as string,
223+
model: 'gpt-5.4-mini',
224+
extraRequestBodyParameters: {
225+
reasoning: {
226+
effort: 'low',
227+
},
228+
},
229+
}),
230+
},
231+
{
232+
name: 'Smart Thinking',
233+
completionAdapter: new CompletionAdapterOpenAIChatGPT({
234+
openAiApiKey: process.env.OPENAI_API_KEY as string,
235+
model: 'gpt-5.4',
236+
extraRequestBodyParameters: {
237+
reasoning: {
238+
effort: 'xhigh',
239+
},
240+
},
241+
}),
242+
},
243+
],
182244
maxTokens: 10000,
183-
reasoning: 'none',
184245
sessionResource: {
185246
resourceId: 'sessions',
186247
idField: 'id',
@@ -203,7 +264,9 @@ plugins: [
203264
]
204265
```
205266

206-
The plugin adds a chat surface to the admin UI and keeps session history per admin user.
267+
Each item in `modes` defines a user-selectable preset in the chat UI. The selected mode is sent to the backend and the plugin uses that mode's `completionAdapter` for the response.
268+
269+
The plugin adds a chat surface to the admin UI, keeps session history per admin user, and shows a mode picker when `modes` are configured.
207270

208271
## Reverse proxy and CDN configuration for streaming
209272

@@ -270,5 +333,3 @@ In skills markdown file, merge which tool exactlu agent should load.
270333
Skill example:
271334

272335
// TODO
273-
274-

adminforth/documentation/docs/tutorial/09-Advanced/01-plugin-development.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ In plugin options we will pass field name and `OPENAI_API_KEY`.
6060

6161

6262
```ts title='./af-plugin-chatgpt/types.ts'
63+
import {type PluginsCommonOptions } from "adminforth";
6364

64-
export interface PluginOptions {
65+
export interface PluginOptions extends PluginsCommonOptions {
6566

6667
//diff-add
6768
/**
@@ -557,9 +558,9 @@ To use adapter in plugin you should define it in plugin options:
557558
558559
```ts title='./af-plugin-any-complete/types.ts'
559560

560-
import { CompletionAdapter } from "adminforth";
561+
import { CompletionAdapter, type PluginsCommonOptions } from "adminforth";
561562

562-
export interface PluginOptions {
563+
export interface PluginOptions extends PluginsCommonOptions{
563564
...
564565

565566
//diff-add

adminforth/documentation/src/css/custom.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,17 @@ pre code:has(.code-block-diff-remove-line) {
130130
position: relative;
131131
z-index: 1;
132132
padding: 3%;
133+
overflow: hidden;
133134
border-radius: 2vw;
134135
background: #ecf1f7;
135136
background-image: linear-gradient(to bottom, #333, #111);
136137
box-shadow: 0 0.1rem 0 #cfcfcf;
137138
border: 2px solid #ccc;
138139
}
139-
.laptop .laptop__screen img {
140+
.laptop .laptop__screen img,
141+
.laptop .laptop__screen iframe {
140142
display: block;
141143
max-width: 100%;
142-
height: auto;
143-
aspect-ratio: attr(width) / attr(height);
144144
background: #000;
145145
}
146146
.laptop .laptop__bottom {

adminforth/documentation/src/pages/index.module.css

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,22 @@
3636
max-width: 500px;
3737
}
3838

39+
.demoFrame {
40+
display: block;
41+
width: 100%;
42+
aspect-ratio: 16 / 10;
43+
border: 0;
44+
border-radius: 1.2vw;
45+
background: #000;
46+
}
47+
3948
.cardsWrapper {
4049
display: grid;
41-
grid-template-columns: repeat(3, minmax(300px, 500px));
50+
grid-template-columns: repeat(2, minmax(300px, 500px));
4251
gap: 4rem;
4352
justify-content: center;
4453
padding: 1rem;
4554

46-
@media (max-width: 1200px) {
47-
grid-template-columns: repeat(2, minmax(300px, 500px));
48-
}
4955
@media (max-width: 768px) {
5056
grid-template-columns: repeat(1, minmax(300px, 500px));
5157
}

0 commit comments

Comments
 (0)