-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.html
More file actions
209 lines (203 loc) · 310 KB
/
Copy pathindex.html
File metadata and controls
209 lines (203 loc) · 310 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-tutorial/Plugins/agent" data-has-hydrated="false">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v3.9.2">
<title data-rh="true">Agent | Agent-first open-source admin panel framework</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://adminforth.dev/img/og.jpg"><meta data-rh="true" name="twitter:image" content="https://adminforth.dev/img/og.jpg"><meta data-rh="true" property="og:url" content="https://adminforth.dev/docs/tutorial/Plugins/agent/"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Agent | Agent-first open-source admin panel framework"><meta data-rh="true" name="description" content="Guide to the AdminForth Agent plugin, including installation, model and mode configuration, self-hosted usage, session storage, skills, and custom tools."><meta data-rh="true" property="og:description" content="Guide to the AdminForth Agent plugin, including installation, model and mode configuration, self-hosted usage, session storage, skills, and custom tools."><meta data-rh="true" name="twitter:title" content="Agent"><meta data-rh="true" name="twitter:description" content="Guide to the AdminForth Agent plugin, including installation, model and mode configuration, self-hosted usage, session storage, skills, and custom tools."><link data-rh="true" rel="icon" href="/img/favicon.png"><link data-rh="true" rel="canonical" href="https://adminforth.dev/docs/tutorial/Plugins/agent/"><link data-rh="true" rel="alternate" href="https://adminforth.dev/docs/tutorial/Plugins/agent/" hreflang="en"><link data-rh="true" rel="alternate" href="https://adminforth.dev/docs/tutorial/Plugins/agent/" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://VSIPOF54AV-dsn.algolia.net" crossorigin="anonymous"><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"TechArticle","headline":"Agent","description":"Guide to the AdminForth Agent plugin, including installation, model and mode configuration, self-hosted usage, session storage, skills, and custom tools.","url":"https://adminforth.dev/docs/tutorial/Plugins/agent","dateModified":"2026-08-17T05:01:16.000Z"}</script><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Plugins","item":"https://adminforth.dev/docs/tutorial/ListOfPlugins"},{"@type":"ListItem","position":2,"name":"Agent","item":"https://adminforth.dev/docs/tutorial/Plugins/agent"}]}</script><link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="Agent-first open-source admin panel framework RSS Feed">
<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Agent-first open-source admin panel framework Atom Feed">
<link rel="preconnect" href="https://www.google-analytics.com">
<link rel="preconnect" href="https://www.googletagmanager.com">
<script async src="https://www.googletagmanager.com/gtag/js?id=G-7K99Q2BH04"></script>
<script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-7K99Q2BH04",{anonymize_ip:!0})</script>
<link rel="search" type="application/opensearchdescription+xml" title="Agent-first open-source admin panel framework" href="/opensearch.xml">
<meta name="application-name" content="AdminForth">
<meta name="robots" content="index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1">
<meta name="googlebot" content="index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1">
<meta name="keywords" content="agent-first admin panel framework, open-source admin panel, agentic back office, tailwind admin framework, vue typescript admin panel, internal admin agent">
<link rel="image_src" href="https://adminforth.dev/img/adminforth_screenshot.png">
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"AdminForth","url":"https://adminforth.dev","description":"Agent-first open-source admin panel framework. Build robust and powerful agentic back-office panels for your projects while maintaining full control over the code.","keywords":"backoffice, vue backoffice, agent-first admin panel framework, open-source admin panel, agentic back office, tailwind admin framework, vue typescript admin panel, internal admin agent"}</script>
<script src="/scripts/adminforth.js"></script>
<script src="/scripts/tluma-config.js"></script>
<script src="https://tluma.ai/widget.js" async></script><link rel="stylesheet" href="/assets/css/styles.e5bdffa0.css">
<script src="/assets/js/runtime~main.ee0f97d0.js" defer="defer"></script>
<script src="/assets/js/main.a1324122.js" defer="defer"></script>
</head>
<body class="navigation-with-keyboard">
<svg style="display: none;"><defs>
<symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol>
</defs></svg>
<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||"light"),document.documentElement.setAttribute("data-theme-choice",t||"light")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/logo.svg" alt="AdminForth Logo" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="/img/logo.svg" alt="AdminForth Logo" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div><b class="navbar__title text--truncate">AdminForth</b></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/docs/tutorial/gettingStarted/">Tutorial</a><a class="navbar__item navbar__link" href="/docs/api/">API</a><a class="navbar__item navbar__link" href="/blog/">Blog</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><div class="navbarSearchContainer_Bca1"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search (Command+K)"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div><a href="https://demo.adminforth.dev/" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Live Demo<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><a href="https://github.com/devforth/adminforth" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP systemToggleIcon_QzmC"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_z2l0"><div class="docsWrapper_hBAB"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docRoot_UBD9"><aside class="theme-doc-sidebar-container docSidebarContainer_YfHR"><div class="sidebarViewport_aRkj"><div class="sidebar_njMd"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/gettingStarted/"><span title="Getting Started" class="linkLabel_WmDU">Getting Started</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item hidden-sidebar"><a class="menu__link" href="/docs/tutorial/hello-world/"><span title="Hello world app without CLI" class="linkLabel_WmDU">Hello world app without CLI</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/glossary/"><span title="Glossary" class="linkLabel_WmDU">Glossary</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="true" href="/docs/tutorial/Customization/branding/"><span title="Customization" class="categoryLinkLabel_W154">Customization</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/branding/"><span title="Branding and Theming" class="linkLabel_WmDU">Branding and Theming</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/customFieldRendering/"><span title="Custom record field rendering" class="linkLabel_WmDU">Custom record field rendering</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/virtualColumns/"><span title="Virtual columns" class="linkLabel_WmDU">Virtual columns</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/hooks/"><span title="Hooks" class="linkLabel_WmDU">Hooks</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/limitingAccess/"><span title="Limiting actions access" class="linkLabel_WmDU">Limiting actions access</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/customPages/"><span title="Custom pages" class="linkLabel_WmDU">Custom pages</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/alert/"><span title="Alerts and confirmations" class="linkLabel_WmDU">Alerts and confirmations</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/pageInjections/"><span title="Page Injections" class="linkLabel_WmDU">Page Injections</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/Actions/"><span title="Actions" class="linkLabel_WmDU">Actions</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/menuConfiguration/"><span title="Menu & Header" class="linkLabel_WmDU">Menu & Header</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/dataApi/"><span title="Data API" class="linkLabel_WmDU">Data API</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/security/"><span title="Security" class="linkLabel_WmDU">Security</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/standardPagesTuning/"><span title="Standard pages tuning" class="linkLabel_WmDU">Standard pages tuning</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/afcl/"><span title="AdminForth Components Library" class="linkLabel_WmDU">AdminForth Components Library</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/websocket/"><span title="Websocket" class="linkLabel_WmDU">Websocket</span></a></li></ul></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/connectors/"><span title="Connectors" class="linkLabel_WmDU">Connectors</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/deploy/"><span title="Deploy in Docker" class="linkLabel_WmDU">Deploy in Docker</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist" href="/docs/tutorial/ListOfAdapters/"><span title="Adapters" class="categoryLinkLabel_W154">Adapters</span></a><button aria-label="Expand sidebar category 'Adapters'" aria-expanded="false" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/CLICommands/"><span title="CLI Commands" class="linkLabel_WmDU">CLI Commands</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/UsageOfLogger/"><span title="Usage of the logger" class="linkLabel_WmDU">Usage of the logger</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--active" href="/docs/tutorial/ListOfPlugins/"><span title="Plugins" class="categoryLinkLabel_W154">Plugins</span></a><button aria-label="Collapse sidebar category 'Plugins'" aria-expanded="true" type="button" class="clean-btn menu__caret"></button></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/docs/tutorial/Plugins/agent/"><span title="Agent" class="linkLabel_WmDU">Agent</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/two-factors-auth/"><span title="Two-Factor Authentication Plugin" class="linkLabel_WmDU">Two-Factor Authentication Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/foreign-inline-list/"><span title="Foreign Inline List" class="linkLabel_WmDU">Foreign Inline List</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/audit-log/"><span title="Audit Log" class="linkLabel_WmDU">Audit Log</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/markdown/"><span title="Markdown" class="linkLabel_WmDU">Markdown</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/email-password-reset/"><span title="Email Password Reset" class="linkLabel_WmDU">Email Password Reset</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/import-export/"><span title="Import Export" class="linkLabel_WmDU">Import Export</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/open-signup/"><span title="Open Signup" class="linkLabel_WmDU">Open Signup</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/i18n/"><span title="Internationalization (i18n)" class="linkLabel_WmDU">Internationalization (i18n)</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/oauth/"><span title="OAuth Authentication" class="linkLabel_WmDU">OAuth Authentication</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/inline-create/"><span title="Inline Create" class="linkLabel_WmDU">Inline Create</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/list-in-place-edit/"><span title="List In-Place Edit" class="linkLabel_WmDU">List In-Place Edit</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/text-complete/"><span title="Text Complete" class="linkLabel_WmDU">Text Complete</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/foreign-inline-show/"><span title="Foreign Inline Show" class="linkLabel_WmDU">Foreign Inline Show</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/email-invite/"><span title="Email Invite" class="linkLabel_WmDU">Email Invite</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/bulk-ai-flow/"><span title="Bulk AI Flow" class="linkLabel_WmDU">Bulk AI Flow</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/universal-search/"><span title="Universal Search (Legacy)" class="linkLabel_WmDU">Universal Search (Legacy)</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/login-captcha/"><span title="Login Captcha" class="linkLabel_WmDU">Login Captcha</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/user-soft-delete/"><span title="User Soft Delete" class="linkLabel_WmDU">User Soft Delete</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/clone-row/"><span title="Clone Row" class="linkLabel_WmDU">Clone Row</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/many2many/"><span title="Many to Many" class="linkLabel_WmDU">Many to Many</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/background-jobs/"><span title="Background Jobs" class="linkLabel_WmDU">Background Jobs</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/quick-filters/"><span title="Quick Filters" class="linkLabel_WmDU">Quick Filters</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/auto-remove/"><span title="Auto Remove Plugin" class="linkLabel_WmDU">Auto Remove Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/rich-editor/"><span title="Rich Editor" class="linkLabel_WmDU">Rich Editor</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/CRUDApprove/"><span title="CRUD Approve Plugin" class="linkLabel_WmDU">CRUD Approve Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/json-form/"><span title="JSON Form" class="linkLabel_WmDU">JSON Form</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/upload/"><span title="Upload" class="linkLabel_WmDU">Upload</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/05-1-upload-api/"><span title="Upload API" class="linkLabel_WmDU">Upload API</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/dashboard/"><span title="Dashboard plugin" class="linkLabel_WmDU">Dashboard plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/dashboard-reference/"><span title="Dashboard Query Reference" class="linkLabel_WmDU">Dashboard Query Reference</span></a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="true" href="/docs/tutorial/Advanced/plugin-development/"><span title="Advanced" class="categoryLinkLabel_W154">Advanced</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Advanced/plugin-development/"><span title="Plugin development guide" class="linkLabel_WmDU">Plugin development guide</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Advanced/working-without-direct-database-connection/"><span title="Working without direct database connection" class="linkLabel_WmDU">Working without direct database connection</span></a></li></ul></li></ul></nav></div></div></aside><main class="docMainContainer_TBSr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><a class="breadcrumbs__link" href="/docs/tutorial/ListOfPlugins/"><span>Plugins</span></a></li><li class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link">Agent</span></li></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><blockquote>
<p>TODO: this plugin tutorial is in progress, some information might be missing, we are actively working on it now. If you have any questions regarding this plugin, please reach out to us in GitHub issues</p>
</blockquote>
<header><h1>Agent Plugin</h1></header>
<p>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.</p>
<p>It stores session history in your own resources and generates responses using one of the configured <code>modes</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="installation">Installation<a href="#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation" translate="no"></a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">add</span><span class="token plain"> @adminforth/agent </span><span class="token parameter variable" style="color:#f8f8f2">--save</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">add</span><span class="token plain"> @adminforth/completion-adapter-openai-responses </span><span class="token parameter variable" style="color:#f8f8f2">--save</span><br></span></code></pre></div></div>
<p>Add your LLM credentials to <code>.env</code>:</p>
<div class="language-env codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-env codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">...</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">OPENAI_API_KEY=your_key</span><br></span></code></pre></div></div>
<p>Each mode accepts any AdminForth completion adapter, so you can replace the OpenAI adapter with another adapter from <a class="" href="/docs/tutorial/ListOfAdapters/">List of adapters</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setup">Setup<a href="#setup" class="hash-link" aria-label="Direct link to Setup" title="Direct link to Setup" translate="no"></a></h2>
<p>First create two resources for sessions and turns:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./resources/agent_resources/sessions.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> AdminForth</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthDataTypes </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> randomUUID </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'crypto'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> adminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">Promise</span><span class="token operator" style="color:#66d9ef"><</span><span class="token builtin" style="color:#e6db74">boolean</span><span class="token operator" style="color:#66d9ef">></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">role </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'superadmin'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">default</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> dataSource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'maindb'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> table</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'sessions'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'sessions'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Sessions'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> columns</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> primaryKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">fillOnCreate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token function" style="color:#e6db74">randomUUID</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'title'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">INTEGER</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'asker_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">DATETIME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">fillOnCreate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">Date</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">toISOString</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> options</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedActions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> show</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">delete</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./resources/agent_resources/turns.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> AdminForth</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthDataTypes </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> randomUUID </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'crypto'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> adminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">Promise</span><span class="token operator" style="color:#66d9ef"><</span><span class="token builtin" style="color:#e6db74">boolean</span><span class="token operator" style="color:#66d9ef">></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">role </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'superadmin'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">default</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> dataSource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'maindb'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> table</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> columns</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> primaryKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">fillOnCreate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token function" style="color:#e6db74">randomUUID</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'session_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">DATETIME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">fillOnCreate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">Date</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">toISOString</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'prompt'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">TEXT</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'response'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">TEXT</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> show</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> filter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> options</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedActions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> show</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">delete</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p><code>asker_id</code> must store the current admin user's primary key, and <code>created_at</code> should be filled automatically because the plugin sorts sessions and turns by it. The <code>turns</code> field can stay nullable, but the plugin configuration still expects it. The optional <code>checkpoint_id</code> field stores the checkpoint attached to each visible turn and enables editing or forking old messages when <code>checkpointResource</code> is configured.</p>
<p>Add matching tables to your schema:</p>
<div class="language-prisma codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./schema.prisma</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-prisma codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">model sessions {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id String @id</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> title String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turns Int?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> asker_id String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> created_at DateTime</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">model turns {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id String @id</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> session_id String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> created_at DateTime</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> prompt String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> response String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpoint_id String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>Run migration:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> makemigration </span><span class="token parameter variable" style="color:#f8f8f2">--name</span><span class="token plain"> add-adminforth-agent-tables </span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> migrate:local</span><br></span></code></pre></div></div>
<p>Register both resources in your app:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> sessions_resource </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'./resources/agent_resources/sessions.js'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> turns_resource </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'./resources/agent_resources/turns.js'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> admin </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForth</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resources</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sessions_resource</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turns_resource</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>Then attach the plugin once in <code>index.ts</code> as global plugin:</p>
<p>Configure the plugin with <code>modes</code>. The legacy top-level <code>completionAdapter</code> setup is no longer used.</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> AdminForthAgent </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/agent'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> CompletionAdapterOpenAIResponses </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/completion-adapter-openai-responses'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">globalPlugins</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAgent</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// optional, can be used to suggest example prompts in the UI</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// placeholderMessages: async ({ adminUser, httpExtra }) => {</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// return [</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// 'What is a cars count in SQLite',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// 'Build average car price by days chart in SQLite',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// ];</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// },</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> modes</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Balanced'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> completionAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">CompletionAdapterOpenAIResponses</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> openAiApiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">OPENAI_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> model</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gpt-5.4-mini'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> extraRequestBodyParameters</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> reasoning</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> effort</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'medium'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Fast'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> completionAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">CompletionAdapterOpenAIResponses</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> openAiApiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">OPENAI_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> model</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gpt-5.4-mini'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> extraRequestBodyParameters</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> reasoning</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> effort</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'low'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Smart Thinking'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> completionAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">CompletionAdapterOpenAIResponses</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> openAiApiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">OPENAI_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> model</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gpt-5.4'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> extraRequestBodyParameters</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> reasoning</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> effort</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'xhigh'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> maxTokens</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">10000</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sessionResource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'sessions'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> idField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> titleField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'title'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turnsField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> askerIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'asker_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> createdAtField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turnResource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> idField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sessionIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'session_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> createdAtField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> promptField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'prompt'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> responseField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'response'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// optional</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// debugField: 'debug',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpointIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// optional, see the "Persistent checkpointer" section below</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// checkpointResource: { ... },</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">]</span><br></span></code></pre></div></div>
<p>Each item in <code>modes</code> defines a user-selectable preset in the chat UI. The selected mode is sent to the backend and the plugin uses that mode's <code>completionAdapter</code> for the response.</p>
<p>The plugin adds a chat surface to the admin UI, keeps session history per admin user, and shows a mode picker when <code>modes</code> are configured.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="chat-surfaces-telegram-etc">Chat surfaces (Telegram, etc.)<a href="#chat-surfaces-telegram-etc" class="hash-link" aria-label="Direct link to Chat surfaces (Telegram, etc.)" title="Direct link to Chat surfaces (Telegram, etc.)" translate="no"></a></h2>
<p>By default, the Agent plugin exposes a chat surface inside the AdminForth admin UI.
If you want to talk to the same agent from external chat products (Telegram, Slack, Teams, etc.), configure both:</p>
<ul>
<li class="">a <strong>chat surface adapter</strong> that receives messages from the external chat product</li>
<li class="">an <strong>OAuth adapter</strong> for the same provider so users can connect that external account in <strong>Connected Accounts</strong></li>
</ul>
<p>For example, Telegram Agent access needs both <code>@adminforth/chat-surface-adapter-telegram</code> and <code>@adminforth/oauth-adapter-telegram</code>.</p>
<p>Register adapters through <code>chatSurfaceAdapters</code>:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> AdminForthAgent </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/agent'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> TelegramChatSurfaceAdapter </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/chat-surface-adapter-telegram'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAgent</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// ...modes, sessionResource, turnResource, etc.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> chatSurfaceAdapters</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">TelegramChatSurfaceAdapter</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> botToken</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">TELEGRAM_BOT_TOKEN</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> webhookSecret</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">TELEGRAM_WEBHOOK_SECRET</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> chatExternalIdentityResource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'admin_user_external_identities'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> surfaces</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> telegram</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> provider</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'AdminForthAdapterTelegramOauth2'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>External chat users are resolved through the OAuth external identities resource. The <code>provider</code> value in <code>chatExternalIdentityResource.surfaces</code> must match the OAuth adapter class that writes connected accounts, for example <code>AdminForthAdapterTelegramOauth2</code>.</p>
<p>Users connect their Telegram account from <strong>Settings -> Connected Accounts</strong>. After that, messages from the Telegram bot can be matched to the AdminForth user through the external identity <code>externalUserId</code>.</p>
<p>For Telegram setup, including required user fields, webhook URL, environment variables, and adapter options, see:</p>
<ul>
<li class=""><a href="https://adminforth.dev/docs/tutorial/Adapters/chat-surface-adapter-telegram/" target="_blank" rel="noopener noreferrer" class="">Telegram Chat Surface Adapter</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="debugging-agent-turns">Debugging agent turns<a href="#debugging-agent-turns" class="hash-link" aria-label="Direct link to Debugging agent turns" title="Direct link to Debugging agent turns" translate="no"></a></h2>
<p>Agent debug traces are optional and are intended for auditability and debugging. When enabled, they let you reconstruct why an agent produced a response or made a change by storing the full execution sequence for the turn: LLM steps, tool calls, tool inputs and outputs, token usage, and cache information.</p>
<p>By default, only the user prompt and agent response are persisted. Full debug traces are not stored unless you configure a <code>debugField</code>, because they can be large and may significantly increase database size.</p>
<p>Add a <code>debug</code> JSON column to the turns resource:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./resources/agent_resources/turns.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> AdminForth</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthDataTypes </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> randomUUID </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'crypto'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> adminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">Promise</span><span class="token operator" style="color:#66d9ef"><</span><span class="token builtin" style="color:#e6db74">boolean</span><span class="token operator" style="color:#66d9ef">></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">role </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'superadmin'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">default</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> dataSource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'maindb'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> table</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> columns</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> primaryKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">fillOnCreate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token function" style="color:#e6db74">randomUUID</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'session_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">DATETIME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">fillOnCreate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">Date</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">toISOString</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'prompt'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">TEXT</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'response'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">TEXT</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'debug'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">JSON</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> components</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> show</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> file</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@@/TurnDebugShow.vue'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> show</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> filter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> options</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedActions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> show</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allowedForSuperAdmins</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">delete</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>Add the matching field to your schema:</p>
<div class="language-prisma codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./schema.prisma</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-prisma codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">model turns {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id String @id</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> session_id String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> created_at DateTime</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> prompt String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> response String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> debug Json? //diff-add</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>If you use SQLite with Prisma, store the same field as text:</p>
<div class="language-prisma codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./schema.prisma</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-prisma codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">model turns {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id String @id</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> session_id String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> created_at DateTime</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> prompt String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> response String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> debug String? //diff-add</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>AdminForth should still define this resource column as <code>AdminForthDataTypes.JSON</code>; the SQLite connector serializes it into the text column and parses it back for the renderer.</p>
<p>Run migration:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> makemigration </span><span class="token parameter variable" style="color:#f8f8f2">--name</span><span class="token plain"> add-adminforth-agent-turn-debug </span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> migrate:local</span><br></span></code></pre></div></div>
<p>Tell the plugin where to store debug data:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAgent</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> modes</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sessionResource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'sessions'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> idField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> titleField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'title'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turnsField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> askerIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'asker_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> createdAtField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turnResource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> idField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sessionIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'session_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> createdAtField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> promptField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'prompt'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> responseField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'response'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> debugField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'debug'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre></div></div>
<p>The <code>debugField</code> value must match the turns resource column name. You can use another column name, but then use the same name in the resource, database schema, and <code>debugField</code>.</p>
<p>Create a renderer in your app custom folder:</p>
<div class="language-vue codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./custom/TurnDebugShow.vue</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-vue codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain"><template></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> <div class="space-y-3"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> <div class="rounded-lg bg-slate-50 p-3 text-sm text-slate-700 dark:bg-slate-800 dark:text-slate-200"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> <div class="font-semibold text-slate-900 dark:text-white">Agent Debug</div></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> <div class="mt-1"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> {{ debugSequences.length }} sequences,</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> {{ totalToolCalls }} tool calls,</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> {{ totalUncachedInputTokens.toLocaleString() }} uncached input tokens,</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> {{ totalCachedInputTokens.toLocaleString() }} cached input tokens,</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> {{ totalOutputTokens.toLocaleString() }} output tokens</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </div></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </div></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> <JsonViewer :value="debugSequences" :expandDepth="2" /></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </div></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></template></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"><script setup lang="ts"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">import { computed } from 'vue';</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">import { JsonViewer } from '@/afcl';</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">import type { AdminForthResourceColumnCommon } from '@/types/Common';</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">type DebugToolCall = {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> toolName: string;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">};</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">type DebugSequence = {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> uncachedInputTokens?: number;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> cachedInputTokens?: number;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> outputTokens?: number;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> cachedTokens: number;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> promptTokens: number;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> reasoningTokens: number;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> textTokens: number;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> toolCalls: DebugToolCall[];</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">};</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">const props = defineProps<{</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> column: AdminForthResourceColumnCommon;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> record: Record<string, DebugSequence[]>;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}>();</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">const debugSequences = computed(() => props.record[props.column.name] ?? []);</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">const totalToolCalls = computed(() =></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> debugSequences.value.reduce((sum, sequence) => sum + sequence.toolCalls.length, 0),</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">);</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">const totalUncachedInputTokens = computed(() =></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> debugSequences.value.reduce((sum, sequence) => sum + sequenceUncachedInputTokens(sequence), 0),</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">);</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">const totalCachedInputTokens = computed(() =></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> debugSequences.value.reduce((sum, sequence) => sum + sequenceCachedInputTokens(sequence), 0),</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">);</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">const totalOutputTokens = computed(() =></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> debugSequences.value.reduce((sum, sequence) => sum + sequenceOutputTokens(sequence), 0),</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">);</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">function sequenceUncachedInputTokens(sequence: DebugSequence) {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> return sequence.uncachedInputTokens ?? Math.max(sequence.promptTokens - sequenceCachedInputTokens(sequence), 0);</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">function sequenceCachedInputTokens(sequence: DebugSequence) {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> return sequence.cachedInputTokens ?? sequence.cachedTokens;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">function sequenceOutputTokens(sequence: DebugSequence) {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> return sequence.outputTokens ?? sequence.reasoningTokens + sequence.textTokens;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></script></span><br></span></code></pre></div></div>
<h1>Using with self-hosted models</h1>
<p><code>CompletionAdapterOpenAIResponses</code> when works with agent plugin, under the hood uses the LangChain internal proxy called <code>OpenAIChat</code> (in LangChain they call it "provider"). This proxy is capable with a fresh versions of OpenAI-compatible Responses APIs, for example <a href="https://devforth.io/insights/self-hosted-gpt-real-response-time-token-throughput-and-cost-on-l4-l40s-and-h100-for-gpt-oss-20b/" target="_blank" rel="noopener noreferrer" class="">self-hosted latest versions of vLLM installations</a>
To use them, just point the adapter to your local vLLM server:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">completionAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">CompletionAdapterOpenAIResponses</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> openAiApiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">MY_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// if you use authorization</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> baseUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'http://my_local_vllm_server:8000/v1'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> model</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gpt-oss-120b'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre></div></div>
<p>However some of 3rd party providers might serve outdated vLLM and still don't fully support the Responses API needed for langchain internal implmentation, for example <a href="https://www.ovhcloud.com/en/public-cloud/ai-endpoints/" target="_blank" rel="noopener noreferrer" class="">OVH AI Endpoints</a> in Responses mode still don't play well with langchain proxy (25 Apr 2026)</p>
<p>In that case you can try to use the OpenAI Chat Completions API mode of the plugin, which is less efficient but more compatible with older APIs, you can force Chat Completions API mode with <code>useCompletionApi: true</code>:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">completionAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">CompletionAdapterOpenAIResponses</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> openAiApiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">OVH_AI_ENDPOINTS_ACCESS_TOKEN</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> baseUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'https://oai.endpoints.kepler.ai.cloud.ovh.net/v1'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> model</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'gpt-oss-120b'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> useCompletionApi</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre></div></div>
<p>OVH AI Endpoints still does not fully support the OpenAI <code>responses</code> API, so <code>useCompletionApi: false</code> may work unstably there.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="turn-on-audio-chat-support">Turn on audio chat support<a href="#turn-on-audio-chat-support" class="hash-link" aria-label="Direct link to Turn on audio chat support" title="Direct link to Turn on audio chat support" translate="no"></a></h2>
<p>If you want to have an ability to talk with agent usng voice, you can setup it:</p>
<ol>
<li class="">Install audio adapter:</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">add</span><span class="token plain"> @adminforth/audio-adapter-openai</span><br></span></code></pre></div></div>
<ol start="2">
<li class="">Import it in your users resource and add to the plugin config</li>
</ol>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> OpenAIAudioAdapter </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/audio-adapter-openai'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAgent</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> audioAdapter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">OpenAIAudioAdapter</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> apiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">OPENAI_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> defaultVoice</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'alloy'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> defaultSpeed</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1.25</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="writing-own-skills">Writing own skills<a href="#writing-own-skills" class="hash-link" aria-label="Direct link to Writing own skills" title="Direct link to Writing own skills" translate="no"></a></h2>
<p>You can write own skills by following <a href="https://agentskills.io/" target="_blank" rel="noopener noreferrer" class="">SKILL.md Agennt Skills</a></p>
<p>For example we will write a skill which can summarizes backoffice data stats like record counts by resources and send it to user email.</p>
<p>It may handle prompts like</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">Please send record counts for all resources to my email</span><br></span></code></pre></div></div>
<p>Or:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">Please send record counts to all admin users</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="writing-custom-tools">Writing custom tools<a href="#writing-custom-tools" class="hash-link" aria-label="Direct link to Writing custom tools" title="Direct link to Writing custom tools" translate="no"></a></h3>
<p>To define a custom tool, register an API endpoint with <code>admin.express.endpoint</code>. The endpoint schema makes the API visible in OpenAPI, and the endpoint <code>handler</code> gives the agent a direct function it can call as a tool.</p>
<p><code>admin.express.withSchema</code> is useful when you already have a regular Express route and want it to appear in the generated OpenAPI document. However, a route registered only with <code>withSchema</code> is not a directly callable agent tool, because it does not register a direct OpenAPI handler. For agent tools, use <code>admin.express.endpoint</code>.</p>
<p>By default, <code>admin.express.endpoint</code> applies AdminForth authorization. The endpoint handler receives <code>adminUser</code> from the user who is controlling the agent. In other words, all permissions and access rights of the agent are defined by that admin user. At the same time, actions done by the agent are automatically attributed in the audit log to the admin user who is controlling the agent.</p>
<p>If a tool is risky, you can attach AdminForth agent metadata directly to the endpoint with the <code>agent</code> field.</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AgentRiskLevel</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'safe'</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">|</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'danger'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AgentToolMeta</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> riskLevel</span><span class="token operator" style="color:#66d9ef">?</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AgentRiskLevel</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> confirmation</span><span class="token operator" style="color:#66d9ef">?</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> title</span><span class="token operator" style="color:#66d9ef">?</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> message</span><span class="token operator" style="color:#66d9ef">?</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> confirmLabel</span><span class="token operator" style="color:#66d9ef">?</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>Use it in <code>.endpoint(...)</code> like this:</p>
<ul>
<li class=""><code>riskLevel: 'safe'</code> marks the tool as low-risk.</li>
<li class=""><code>riskLevel: 'danger'</code> marks the tool as dangerous.</li>
<li class=""><code>confirmation</code> customizes the confirmation dialog shown before the tool is executed.</li>
</ul>
<p>This metadata is rendered into the generated OpenAPI document, so the agent can understand that a tool is dangerous and requires an explicit confirmation UI before execution.</p>
<p>This example uses the same email adapter pattern shown in the Email Invite and Email Password Reset plugins. The transport below uses Mailgun only to keep the snippet short; you can replace it with SES or any other adapter from <a class="" href="/docs/tutorial/ListOfAdapters/">List of adapters</a>.</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./api.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> Filters</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">IAdminForth</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> EmailAdapterMailgun </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'@adminforth/email-adapter-mailgun'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> agentEmailAdapter </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">EmailAdapterMailgun</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> apiKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">MAILGUN_API_KEY</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> domain</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">MAILGUN_DOMAIN</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> baseUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">MAILGUN_REGION_URL</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">||</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'api.mailgun.net'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> agentSendFrom </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">AGENT_SEND_FROM_EMAIL</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">escapeHtml</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">value</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> value</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">replace</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token regex regex-delimiter">/</span><span class="token regex regex-source language-regex">&</span><span class="token regex regex-delimiter">/</span><span class="token regex regex-flags">g</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'&amp;'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">replace</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token regex regex-delimiter">/</span><span class="token regex regex-source language-regex"><</span><span class="token regex regex-delimiter">/</span><span class="token regex regex-flags">g</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'&lt;'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">replace</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token regex regex-delimiter">/</span><span class="token regex regex-source language-regex">></span><span class="token regex regex-delimiter">/</span><span class="token regex regex-flags">g</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'&gt;'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">renderEmailHtml</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">body</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e"><html><body><pre style="font-family: sans-serif; white-space: pre-wrap;"></span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation function" style="color:#e6db74">escapeHtml</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">(</span><span class="token template-string interpolation">body</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e"></pre></body></html></span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">SendEmailBody</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> userId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> subject</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> body</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> htmlBody</span><span class="token operator" style="color:#66d9ef">?</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">initApi</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">app</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> Express</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> admin</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> IAdminForth</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">express</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">endpoint</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> method</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'POST'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> path</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'/send_email_to_user'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> description</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Send an email to one AdminForth user by id. Use this after the user row is resolved.'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> agent</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> riskLevel</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'danger'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> confirmation</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> title</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Send email to user'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> message</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'This action will send a real email to the selected user.'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> confirmLabel</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Send email'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> request_schema</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'object'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> additionalProperties</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> required</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">'userId'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'subject'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'body'</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> properties</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> userId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'string'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> subject</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'string'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> minLength</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> body</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'string'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> minLength</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> htmlBody</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'string'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> minLength</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> response_schema</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'object'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> additionalProperties</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> required</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">'ok'</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> properties</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> ok</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'boolean'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> email</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'string'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> error</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'string'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">handler</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> body</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> response </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> userId</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> subject</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> body</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> emailBody</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> htmlBody </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> body </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> SendEmailBody</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> agentEmailAdapter</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">validate</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> user </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">resource</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'adminuser'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">get</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> Filters</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">EQ</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> userId</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token operator" style="color:#66d9ef">!</span><span class="token plain">user</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> response</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">setStatus</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token number" style="color:#ae81ff">404</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'User not found'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> ok</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> error</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'User not found'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> result </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> agentEmailAdapter</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">sendEmail</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> agentSendFrom</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> user</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">email </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> emailBody</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> htmlBody </span><span class="token operator" style="color:#66d9ef">??</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">renderEmailHtml</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">emailBody</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> subject</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token operator" style="color:#66d9ef">!</span><span class="token plain">result</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">ok</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> response</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">setStatus</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token number" style="color:#ae81ff">500</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Failed to send email'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> ok</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> error</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> result</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">error </span><span class="token operator" style="color:#66d9ef">??</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Failed to send email'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> ok</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> email</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> user</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">email </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="define-skills-instructions">Define skills instructions<a href="#define-skills-instructions" class="hash-link" aria-label="Direct link to Define skills instructions" title="Direct link to Define skills instructions" translate="no"></a></h2>
<p>Custom skills live in your app's custom directory. The agent loads project skills from:</p>
<ul>
<li class=""><code>custom/skills/<skill_name>/SKILL.md</code></li>
</ul>
<p>Also it can load skills from plugins, it allows other plugins to expose their own skills and tools:</p>
<ul>
<li class=""><code>custom/plugins/adminforth-agent/skills/<skill_name>/SKILL.md</code></li>
</ul>
<p>Each skill needs YAML frontmatter with <code>name</code> and <code>description</code>. The <code>description</code> is the discovery surface, so include the phrases the admin is likely to type in chat. Skills are not loaded automcatically, agent loads them
on demand once understands that <code>description</code> of the skill matches the user intent, so keep the description clear and concise.</p>
<p>Tools are also not loaded automatically, the agent loads them only if they are mentioned in the skill instructions. Then agent calls <code>fetch_tool_schema</code> meta tool to load actual schema of your custom tool.</p>
<p>Tool names are derived from route paths. If you want the tool name to be exactly <code>send_email_to_user</code>, register the route as <code>/send_email_to_user</code>.</p>
<p>The example below creates a minimal user skill which:</p>
<ul>
<li class="">resolves a user row</li>
<li class="">reads the <code>total</code> count for each resource with <code>get_resource_data</code></li>
<li class="">sends the final report by email with <code>send_email_to_user</code></li>
</ul>
<p>Create the skill in your app custom folder:</p>
<div class="language-md codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./custom/skills/email_resource_counts/SKILL.md</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-md codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token front-matter-block punctuation" style="color:#f8f8f2">---</span><span class="token front-matter-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token front-matter-block"></span><span class="token front-matter-block front-matter yaml language-yaml key atrule">name</span><span class="token front-matter-block front-matter yaml language-yaml punctuation" style="color:#f8f8f2">:</span><span class="token front-matter-block front-matter yaml language-yaml"> email_resource_counts</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token front-matter-block front-matter yaml language-yaml"></span><span class="token front-matter-block front-matter yaml language-yaml key atrule">description</span><span class="token front-matter-block front-matter yaml language-yaml punctuation" style="color:#f8f8f2">:</span><span class="token front-matter-block front-matter yaml language-yaml"> Email record counts for each AdminForth resource to a user. Use when the user asks to send resource counts or all</span><span class="token front-matter-block front-matter yaml language-yaml punctuation" style="color:#f8f8f2">-</span><span class="token front-matter-block front-matter yaml language-yaml">record statistics by email.</span><span class="token front-matter-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token front-matter-block"></span><span class="token front-matter-block punctuation" style="color:#f8f8f2">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token title important punctuation" style="color:#f8f8f2">#</span><span class="token title important"> Involved tools</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">Use </span><span class="token code-snippet code keyword" style="color:#66d9ef">`send_email_to_user`</span><span class="token plain"> to send the final report after you have one exact target user row.</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token title important punctuation" style="color:#f8f8f2">#</span><span class="token title important"> Instructions</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token list punctuation" style="color:#f8f8f2">-</span><span class="token plain"> For each resource in system use fetch data default skill to collect total count of records in each resource.</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token list punctuation" style="color:#f8f8f2">-</span><span class="token plain"> Create both a plain text report and an HTML report in format </span><span class="token code-snippet code keyword" style="color:#66d9ef">`Resource Label (resourceId): count`</span><span class="token plain"> for each resource on a new line, sort resources by count in descending order.</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token list punctuation" style="color:#f8f8f2">-</span><span class="token plain"> Use modern, stylish but compatible html formatting in the email.</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token list punctuation" style="color:#f8f8f2">-</span><span class="token plain"> Call </span><span class="token code-snippet code keyword" style="color:#66d9ef">`send_email_to_user`</span><span class="token plain"> with the resolved user primary key, the final subject, the final plain text </span><span class="token code-snippet code keyword" style="color:#66d9ef">`body`</span><span class="token plain">, and the final HTML markup in </span><span class="token code-snippet code keyword" style="color:#66d9ef">`htmlBody`</span><span class="token plain">.</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token list punctuation" style="color:#f8f8f2">-</span><span class="token plain"> After the tool succeeds, tell the user the email was sent and include a short summary in chat.</span><br></span></code></pre></div></div>
<p>This way allows to extend your agent with literally any custom instructions and tools and make it do complex tasks related to your backoffice data and operations.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="standard-skills">Standard skills<a href="#standard-skills" class="hash-link" aria-label="Direct link to Standard skills" title="Direct link to Standard skills" translate="no"></a></h2>
<p>The plugin ships with bundled skills from <code>plugins/adminforth-agent/custom/skills/</code>. These are available out of the box and can be combined with your own custom skills.</p>
<table><thead><tr><th>Folder</th><th>Skill name</th><th>Description</th></tr></thead><tbody><tr><td><code>analyze_data</code></td><td><code>analyze_data</code></td><td>Analyze AdminForth resource data, summarize trends, and create charts from fetched rows. Prefer server-side aggregation when possible and return Vega-Lite specs for charts.</td></tr><tr><td><code>fetch_data</code></td><td><code>fetch_data</code></td><td>Fetch one or more exact records with filters after inspecting the resource schema. This skill is for finding rows, not for aggregations.</td></tr><tr><td><code>mutate_data</code></td><td><code>mutate_data</code></td><td>Create, update, delete, or run actions on records. Before any mutation it must show the exact target row and ask the user for confirmation.</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="persistent-agent-memory">Persistent agent memory<a href="#persistent-agent-memory" class="hash-link" aria-label="Direct link to Persistent agent memory" title="Direct link to Persistent agent memory" translate="no"></a></h2>
<p>The plugin stores visible chat history in the <code>sessions</code> and <code>turns</code> resources. This is what users see in the chat sidebar and in old conversations.</p>
<p>The agent also needs its own internal conversation state to continue an existing chat. If you do not configure <code>checkpointResource</code>, that internal state is kept only in the Node.js process memory. This is fine for local testing and for new chats, but it is not durable:</p>
<ul>
<li class="">after a server restart, users can still see old chat messages because <code>sessions</code> and <code>turns</code> are stored in your database</li>
<li class="">after a server restart, users can continue an old chat, but the agent will treat it like a new conversation because its internal state was lost</li>
<li class="">new chats will work normally again until the next restart</li>
</ul>
<p>For production, configure <code>checkpointResource</code> so the agent can safely continue old chats after restarts and deployments.</p>
<p>You can use your own table and field names. The plugin does not require a specific schema name, only a mapping for these logical fields:</p>
<ul>
<li class=""><code>idField</code></li>
<li class=""><code>threadIdField</code></li>
<li class=""><code>checkpointNamespaceField</code></li>
<li class=""><code>checkpointIdField</code></li>
<li class=""><code>parentCheckpointIdField</code></li>
<li class=""><code>rowKindField</code></li>
<li class=""><code>taskIdField</code></li>
<li class=""><code>sequenceField</code></li>
<li class=""><code>createdAtField</code></li>
<li class=""><code>checkpointPayloadField</code></li>
<li class=""><code>metadataPayloadField</code></li>
<li class=""><code>writesPayloadField</code></li>
<li class=""><code>schemaVersionField</code></li>
</ul>
<p>Create a resource for checkpoint rows:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./resources/agent_resources/checkpoints.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthDataTypes </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthResourceInput </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">default</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> dataSource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'maindb'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> table</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'agent_checkpoints'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'agent_checkpoints'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Agent Checkpoints'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">recordLabel</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">record</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> record</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">id</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> options</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedActions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> columns</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> primaryKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'thread_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_namespace'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'parent_checkpoint_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'row_kind'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">enum</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> value</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Checkpoint'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> value</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'writes'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Writes'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'task_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'sequence'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">INTEGER</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">DATETIME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_payload'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">JSON</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'metadata_payload'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">JSON</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'writes_payload'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">JSON</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'schema_version'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">INTEGER</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>Add a matching table to your schema:</p>
<div class="language-prisma codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./schema.prisma</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-prisma codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">model agent_checkpoints {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id String @id</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> thread_id String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpoint_namespace String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpoint_id String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> parent_checkpoint_id String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> row_kind String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> task_id String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sequence Int</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> created_at DateTime</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpoint_payload String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> metadata_payload String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> writes_payload String?</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> schema_version Int</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> @@index([thread_id, checkpoint_namespace, checkpoint_id])</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>The payload fields can be stored as strings. The plugin serializes and deserializes checkpoint JSON on its own. The composite index on <code>(thread_id, checkpoint_namespace, checkpoint_id)</code> is recommended because the checkpointer filters rows by these columns.</p>
<p>Run migration:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> makemigration </span><span class="token parameter variable" style="color:#f8f8f2">--name</span><span class="token plain"> add-adminforth-agent-checkpoints </span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> migrate:local</span><br></span></code></pre></div></div>
<p>Register the resource in your app:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> checkpoints_resource </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'./resources/agent_resources/checkpoints.js'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> sessions_resource </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'./resources/agent_resources/sessions.js'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> turns_resource </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'./resources/agent_resources/turns.js'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> admin </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForth</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resources</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sessions_resource</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turns_resource</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpoints_resource</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>Then connect it to the plugin:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForthAgent</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> modes</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sessionResource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'sessions'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> idField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> titleField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'title'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turnsField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> askerIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'asker_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> createdAtField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> turnResource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'turns'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> idField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sessionIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'session_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> createdAtField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> promptField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'prompt'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> responseField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'response'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpointIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpointResource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'agent_checkpoints'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> idField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> threadIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'thread_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpointNamespaceField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_namespace'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpointIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> parentCheckpointIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'parent_checkpoint_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> rowKindField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'row_kind'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> taskIdField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'task_id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sequenceField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'sequence'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> createdAtField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> checkpointPayloadField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'checkpoint_payload'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> metadataPayloadField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'metadata_payload'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> writesPayloadField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'writes_payload'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> schemaVersionField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'schema_version'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>If your existing checkpoint table already uses different column names, keep your schema and only change the field mapping in <code>checkpointResource</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="reverse-proxy-and-cdn-configuration-for-streaming">Reverse proxy and CDN configuration for streaming<a href="#reverse-proxy-and-cdn-configuration-for-streaming" class="hash-link" aria-label="Direct link to Reverse proxy and CDN configuration for streaming" title="Direct link to Reverse proxy and CDN configuration for streaming" translate="no"></a></h2>
<p>The agent streams responses from <code><baseURL>/adminapi/v1/agent/response</code> using server-sent events, where <code><baseURL></code> is your AdminForth base path or an empty string when deployed at the domain root. Voice mode also streams from <code><baseURL>/adminapi/v1/agent/speech-response</code> after uploading the recorded audio. If your proxy buffers responses, the UI will receive the answer only after generation is finished.</p>
<p>For Nginx, disable response buffering on both endpoints. The critical line is <code>proxy_buffering off;</code>.</p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">location <baseURL>/adminapi/v1/agent/response {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_http_version 1.1;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_read_timeout 600s;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_set_header Host $http_host;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_set_header Connection "";</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_buffering off; # required for streaming</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_pass http://127.0.0.1:3500;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">location <baseURL>/adminapi/v1/agent/speech-response {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_http_version 1.1;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_read_timeout 600s;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_set_header Host $http_host;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_set_header Connection "";</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_buffering off; # required for streaming voice responses</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> proxy_pass http://127.0.0.1:3500;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>Traefik forwards streaming responses immediately by default. The line that must stay off these routes is any buffering middleware attachment such as <code>traefik.http.routers.adminforth-agent.middlewares=buffering@docker</code>. If your main router uses extra middlewares, create a dedicated router for the agent stream endpoints and do not attach buffering to it:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./compose.yml</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token key atrule">services</span><span class="token punctuation" style="color:#f8f8f2">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token key atrule">adminforth</span><span class="token punctuation" style="color:#f8f8f2">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token key atrule">labels</span><span class="token punctuation" style="color:#f8f8f2">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.enable=true"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.services.adminforth.loadbalancer.server.port=3500"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth.rule=PathPrefix(`/`)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth.tls=true"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth.tls.certresolver=myresolver"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth.middlewares=secure-headers,buffering@docker"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth-agent.rule=Path(`<baseURL>/adminapi/v1/agent/response`) || Path(`<baseURL>/adminapi/v1/agent/speech-response`)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth-agent.priority=100"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth-agent.service=adminforth"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth-agent.tls=true"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">-</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"traefik.http.routers.adminforth-agent.tls.certresolver=myresolver"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic"># keep buffering OFF for SSE</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic"># do not add:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic"># - "traefik.http.routers.adminforth-agent.middlewares=buffering@docker"</span><br></span></code></pre></div></div>
<p>Replace <code><baseURL></code> with the same base path you use for AdminForth. For example, when <code>ADMIN_BASE_URL = '/admin/'</code>, the endpoints become <code>/admin/adminapi/v1/agent/response</code> and <code>/admin/adminapi/v1/agent/speech-response</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cdn">CDN<a href="#cdn" class="hash-link" aria-label="Direct link to CDN" title="Direct link to CDN" translate="no"></a></h3>
<p>Cloudflare by default buffers responses, which breaks streaming. To fix it, create a page rule for your domain with a "Response Body Buffering" setting turned off for the agent stream endpoints (<code><baseURL>/adminapi/v1/agent/response</code> and <code><baseURL>/adminapi/v1/agent/speech-response</code>).</p>
<p>If Cloudflare returns a 403 response with <code>cf-mitigated: challenge</code> for <code><baseURL>/adminapi/v1/agent/speech-response</code>, the request was blocked before it reached AdminForth. Create a WAF or bot rule exception for authenticated requests to this endpoint, because browser <code>fetch</code> calls with <code>multipart/form-data</code> cannot complete an HTML challenge page.</p>
<p><img decoding="async" loading="lazy" alt="alt text" src="/assets/images/image-6-78540fb6861d2af8a2387f9f215b3814.png" width="1961" height="515" class="img_ev3q"></p></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="row margin-top--sm theme-doc-footer-edit-meta-row"><div class="col noPrint_WFHX"></div><div class="col lastUpdated_JAkA"><span class="theme-last-updated">Last updated<!-- --> on <b><time datetime="2026-08-17T05:01:16.000Z" itemprop="dateModified">Aug 17, 2026</time></b></span></div></div></footer></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/docs/tutorial/ListOfPlugins/"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">Plugins</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/docs/tutorial/Plugins/two-factors-auth/"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Two-Factor Authentication Plugin</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#installation" class="table-of-contents__link toc-highlight">Installation</a></li><li><a href="#setup" class="table-of-contents__link toc-highlight">Setup</a></li><li><a href="#chat-surfaces-telegram-etc" class="table-of-contents__link toc-highlight">Chat surfaces (Telegram, etc.)</a></li><li><a href="#debugging-agent-turns" class="table-of-contents__link toc-highlight">Debugging agent turns</a></li><li><a href="#turn-on-audio-chat-support" class="table-of-contents__link toc-highlight">Turn on audio chat support</a></li><li><a href="#writing-own-skills" class="table-of-contents__link toc-highlight">Writing own skills</a><ul><li><a href="#writing-custom-tools" class="table-of-contents__link toc-highlight">Writing custom tools</a></li></ul></li><li><a href="#define-skills-instructions" class="table-of-contents__link toc-highlight">Define skills instructions</a></li><li><a href="#standard-skills" class="table-of-contents__link toc-highlight">Standard skills</a></li><li><a href="#persistent-agent-memory" class="table-of-contents__link toc-highlight">Persistent agent memory</a></li><li><a href="#reverse-proxy-and-cdn-configuration-for-streaming" class="table-of-contents__link toc-highlight">Reverse proxy and CDN configuration for streaming</a><ul><li><a href="#cdn" class="table-of-contents__link toc-highlight">CDN</a></li></ul></li></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/docs/tutorial/gettingStarted/">Tutorial</a></li><li class="footer__item"><a href="https://demo.adminforth.dev/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Live Demo</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/api/">API</a></li><li class="footer__item"><a class="footer__link-item" href="/blog/archive/">Blog Archive</a></li><li class="footer__item"><a class="footer__link-item" href="/search/">Find anything</a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">More</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://devforth.io" target="_blank" rel="noopener noreferrer" class="footer__link-item">DevForth.io<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://devforth.io/contact" target="_blank" rel="noopener noreferrer" class="footer__link-item">We can develop admin panel for your project<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://github.com/devforth/adminforth" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2026 Devforth sp. z o.o.</div></div></div></footer></div>
</body>
</html>