@sigrun/sigrun 0.1.6 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +192 -0
- package/README.md +445 -42
- package/dist/blocks/build-stamp.json +13 -0
- package/dist/blocks/builders.d.ts +57 -0
- package/dist/blocks/images.d.ts +26 -0
- package/dist/blocks/index.d.ts +20 -0
- package/dist/blocks/limits.d.ts +25 -0
- package/dist/blocks/placements.d.ts +26 -0
- package/dist/blocks/schema.d.ts +38 -0
- package/dist/blocks/schema.js +9 -2
- package/dist/blocks/validate.d.ts +73 -0
- package/dist/blocks/validate.js +57 -8
- package/dist/cli.js +26 -2
- package/dist/config.js +67 -1
- package/dist/extension.d.ts +230 -22
- package/dist/harness/ambient.js +39 -185
- package/dist/harness/blocks/entries.js +47 -0
- package/dist/harness/blocks/state.js +58 -0
- package/dist/harness/blocks/tools.js +274 -0
- package/dist/harness/boot.js +259 -20
- package/dist/harness/builtins.js +15 -11
- package/dist/harness/event-bus.js +105 -10
- package/dist/harness/identity/accounts.js +186 -0
- package/dist/harness/identity/groups.js +14 -0
- package/dist/harness/identity/index.js +13 -6
- package/dist/harness/identity/json-store.js +15 -4
- package/dist/harness/identity/setup-code-check.js +9 -0
- package/dist/harness/identity/tokens.js +28 -5
- package/dist/harness/identity/users.js +111 -12
- package/dist/harness/interactions.js +292 -136
- package/dist/harness/loader.js +271 -17
- package/dist/harness/packages.js +1 -1
- package/dist/harness/reserved-sections.js +21 -0
- package/dist/harness/seam-host.js +92 -6
- package/dist/harness/sections/context-files.js +1 -1
- package/dist/harness/settings.js +63 -2
- package/dist/harness/stores.js +241 -4
- package/dist/harness/user-services.js +391 -0
- package/dist/harness/user-tools.js +187 -0
- package/dist/harness/workspace.js +61 -57
- package/dist/jobs/fire.js +10 -16
- package/dist/sandbox/availability.js +211 -0
- package/dist/sandbox/command-observer.js +59 -0
- package/dist/sandbox/grants.js +159 -0
- package/dist/sandbox/helper.js +29 -0
- package/dist/sandbox/isolation.js +29 -0
- package/dist/sandbox/launch.js +31 -0
- package/dist/sandbox/os-account.js +49 -0
- package/dist/sandbox/policy.js +274 -0
- package/dist/sandbox/pool.js +548 -0
- package/dist/sandbox/protocol.js +167 -0
- package/dist/sandbox/sandboxed-env.js +245 -0
- package/dist/sandbox/unavailable-env.js +49 -0
- package/dist/sandbox/worker.js +261 -0
- package/dist/serve.js +213 -25
- package/dist/server/auth/access-principal.js +16 -0
- package/dist/server/auth/pipeline.js +99 -36
- package/dist/server/blocks/answers.js +94 -0
- package/dist/server/blocks/chat-surfaces.js +393 -0
- package/dist/server/blocks/notes.js +216 -0
- package/dist/server/blocks/summaries.js +328 -0
- package/dist/server/commands.js +5 -0
- package/dist/server/content-parts-lazy.js +13 -0
- package/dist/server/conversation-handler.js +2 -5
- package/dist/server/conversation-ops.js +138 -37
- package/dist/server/helpers.js +18 -6
- package/dist/server/host-bridge.js +40 -20
- package/dist/server/images/cache.js +213 -0
- package/dist/server/images/convert.js +13 -0
- package/dist/server/images/fetch.js +302 -0
- package/dist/server/images/ranges.js +42 -0
- package/dist/server/images/rewrite.js +94 -0
- package/dist/server/images/sign.js +84 -0
- package/dist/server/images/sniff.js +62 -0
- package/dist/server/index.js +152 -4
- package/dist/server/login/flows.js +126 -0
- package/dist/server/login/http.js +31 -0
- package/dist/server/login/resolve.js +133 -0
- package/dist/server/login/setup-claim.js +55 -0
- package/dist/server/login/usernames.js +15 -0
- package/dist/server/notifications.js +21 -4
- package/dist/server/ownership.js +13 -0
- package/dist/server/routes/admin.js +58 -0
- package/dist/server/routes/auth.js +88 -2
- package/dist/server/routes/conversations.js +3 -6
- package/dist/server/routes/events.js +28 -3
- package/dist/server/routes/extensions.js +37 -5
- package/dist/server/routes/images.js +274 -0
- package/dist/server/routes/interactions.js +57 -68
- package/dist/server/routes/jobs.js +2 -8
- package/dist/server/routes/login.js +223 -0
- package/dist/server/routes/me.js +90 -0
- package/dist/server/routes/meta.js +19 -0
- package/dist/server/routes/onboarding.js +94 -84
- package/dist/server/routes/settings-sections.js +190 -0
- package/dist/server/routes/settings.js +16 -4
- package/dist/server/routes/submissions.js +1 -1
- package/dist/server/routes/surfaces.js +175 -23
- package/dist/server/routes/users.js +116 -20
- package/dist/server/schema-fixture.js +213 -0
- package/dist/server/session-meta.js +3 -0
- package/dist/server/shutdown.js +11 -4
- package/dist/server/static.js +18 -0
- package/dist/server/surfaces/dedup.js +9 -2
- package/dist/server/surfaces/service.js +181 -13
- package/dist/server/surfaces/settings-surfaces.js +597 -0
- package/dist/server/turns/submit-turn.js +26 -0
- package/dist/server/views.js +16 -0
- package/dist/settings/core-sections.js +532 -0
- package/dist/settings/pending.js +181 -0
- package/dist/settings/registry.js +453 -0
- package/dist/skills/index.js +6 -0
- package/node_modules/@sigrun/shared/CHANGELOG.md +11 -0
- package/node_modules/@sigrun/shared/dist/access.d.ts +4 -2
- package/node_modules/@sigrun/shared/dist/access.js +11 -4
- package/node_modules/@sigrun/shared/dist/ambient.d.ts +17 -74
- package/node_modules/@sigrun/shared/dist/ambient.js +8 -6
- package/node_modules/@sigrun/shared/dist/blocks/text.js +16 -2
- package/node_modules/@sigrun/shared/dist/blocks/transport.d.ts +4 -0
- package/node_modules/@sigrun/shared/dist/blocks/types.d.ts +21 -4
- package/node_modules/@sigrun/shared/dist/interactions.d.ts +22 -48
- package/node_modules/@sigrun/shared/dist/interactions.js +9 -7
- package/node_modules/@sigrun/shared/dist/settings.d.ts +27 -2
- package/node_modules/@sigrun/shared/dist/themes.d.ts +2 -3
- package/node_modules/@sigrun/shared/dist/themes.js +2 -3
- package/node_modules/@sigrun/shared/dist/turns.d.ts +14 -0
- package/node_modules/@sigrun/shared/dist/turns.js +53 -3
- package/node_modules/@sigrun/shared/dist/views.d.ts +202 -12
- package/node_modules/@sigrun/shared/dist/views.js +16 -0
- package/node_modules/@sigrun/shared/package.json +1 -1
- package/package.json +13 -9
- package/webui/dist/assets/index-SO2W4jjk.js +55 -0
- package/webui/dist/assets/index-yqkL6BSS.css +1 -0
- package/webui/dist/index.html +2 -2
- package/CONTEXT.md +0 -163
- package/webui/dist/assets/index-CiYInlLx.css +0 -1
- package/webui/dist/assets/index-JDfOQV9z.js +0 -52
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The core settings sections (UI-blocks U4 Task 4, spec §13.4): the
|
|
3
|
+
* sections the webui settings panel has today (General, Tools,
|
|
4
|
+
* Interface, Advanced, Providers, Extensions) declared as
|
|
5
|
+
* `SettingsSectionDef`s under the reserved `core` slug, so core and
|
|
6
|
+
* extensions render settings through ONE renderer (the settings-surface
|
|
7
|
+
* adapter, `src/server/surfaces/settings-surfaces.ts`, mounted under
|
|
8
|
+
* `/v1/ext/core/surfaces/<id>`).
|
|
9
|
+
*
|
|
10
|
+
* Scope rulings (plan Task 4):
|
|
11
|
+
* - **Jobs** stays its own rail panel — NO settings section here (the
|
|
12
|
+
* `jobs` and `jobHistory.*` keys remain file/API-surface only).
|
|
13
|
+
* - **Interface** (client prefs + theme) and **Providers** (the §7.6
|
|
14
|
+
* credential flows) are the special coves: both render as
|
|
15
|
+
* channels-native components, not forms (the Interface fields bind
|
|
16
|
+
* client state, not server data; the credential route family is not
|
|
17
|
+
* a settings-object write). Their declarations still exist so the
|
|
18
|
+
* section LIST and the search index cover them; their forms are
|
|
19
|
+
* minimal and never rendered by the channels.
|
|
20
|
+
* - **Extensions** is likewise cove-rendered: the extension-list editor
|
|
21
|
+
* (raw JSON + write-only secrets) is not a settings form. Its
|
|
22
|
+
* declaration covers the `extensions` install list key in the index.
|
|
23
|
+
*
|
|
24
|
+
* Every field declares its `apply` verbatim from the §13.1 registry
|
|
25
|
+
* (`src/settings/registry.ts`) — the core settings test pins the two
|
|
26
|
+
* against each other (a registry entry whose core section renders it
|
|
27
|
+
* with a different apply fails the suite).
|
|
28
|
+
*/
|
|
29
|
+
import { CORE_SETTING_KEYS } from "./registry.js";
|
|
30
|
+
/** The reserved slug the core sections mount under (spec §13.4). */
|
|
31
|
+
export const CORE_SECTIONS_SLUG = "core";
|
|
32
|
+
/** The registry entry for one key (throws when the registry lost it —
|
|
33
|
+
* the core-sections test's coverage pin makes that impossible). */
|
|
34
|
+
function applyOf(key) {
|
|
35
|
+
const entry = CORE_SETTING_KEYS.find((candidate) => candidate.key === key);
|
|
36
|
+
if (entry === undefined) {
|
|
37
|
+
throw new Error(`core-sections: no registry entry for ${key}`);
|
|
38
|
+
}
|
|
39
|
+
return entry.apply;
|
|
40
|
+
}
|
|
41
|
+
/** Every section's id, in nav order (the sections route serves it). */
|
|
42
|
+
export const CORE_SECTION_IDS = [
|
|
43
|
+
"general",
|
|
44
|
+
"tools",
|
|
45
|
+
"interface",
|
|
46
|
+
"advanced",
|
|
47
|
+
"providers",
|
|
48
|
+
"extensions",
|
|
49
|
+
"accounts",
|
|
50
|
+
];
|
|
51
|
+
/**
|
|
52
|
+
* The core settings sections, in nav order (the sections route serves
|
|
53
|
+
* them first, before the extensions' sections).
|
|
54
|
+
*
|
|
55
|
+
* A `StackBlock` section child inside a `form` keeps fields grouped the
|
|
56
|
+
* way the old panel grouped them (the settings placement allows
|
|
57
|
+
* `section` blocks inside forms; the group's fields keep their own
|
|
58
|
+
* `name`s under the form's `/settings` bind).
|
|
59
|
+
*/
|
|
60
|
+
export const CORE_SETTINGS_SECTIONS = [
|
|
61
|
+
{
|
|
62
|
+
id: "general",
|
|
63
|
+
title: "General",
|
|
64
|
+
icon: "key",
|
|
65
|
+
form: {
|
|
66
|
+
v: 1,
|
|
67
|
+
root: {
|
|
68
|
+
type: "form",
|
|
69
|
+
id: "core-general-form",
|
|
70
|
+
bind: "/settings",
|
|
71
|
+
mode: "submit",
|
|
72
|
+
onSubmit: "save",
|
|
73
|
+
submitLabel: "Save",
|
|
74
|
+
children: [
|
|
75
|
+
{
|
|
76
|
+
type: "section",
|
|
77
|
+
id: "core-general-queue",
|
|
78
|
+
title: "Queueing",
|
|
79
|
+
children: [
|
|
80
|
+
{
|
|
81
|
+
type: "choice",
|
|
82
|
+
name: "steeringMode",
|
|
83
|
+
label: "Steering mode",
|
|
84
|
+
help: "How a message sent while a run is live steers it; empty = the pi-durable default (one-at-a-time)",
|
|
85
|
+
apply: applyOf("steeringMode"),
|
|
86
|
+
options: [
|
|
87
|
+
{ id: "one-at-a-time", label: "One at a time" },
|
|
88
|
+
{ id: "all", label: "All" },
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
type: "choice",
|
|
93
|
+
name: "followUpMode",
|
|
94
|
+
label: "Follow-up mode",
|
|
95
|
+
help: "How queued follow-ups deliver after a run settles; empty = the pi-durable default",
|
|
96
|
+
apply: applyOf("followUpMode"),
|
|
97
|
+
options: [
|
|
98
|
+
{ id: "one-at-a-time", label: "One at a time" },
|
|
99
|
+
{ id: "all", label: "All" },
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
type: "section",
|
|
106
|
+
id: "core-general-models",
|
|
107
|
+
title: "Models",
|
|
108
|
+
children: [
|
|
109
|
+
{
|
|
110
|
+
type: "text",
|
|
111
|
+
name: "defaultModel",
|
|
112
|
+
label: "Default model",
|
|
113
|
+
help: "The boot default model (provider/model-id); env SIGRUN_DEFAULT_MODEL wins over the file — a change applies at restart",
|
|
114
|
+
apply: applyOf("defaultModel"),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: "text",
|
|
118
|
+
name: "namingModel",
|
|
119
|
+
label: "Naming model",
|
|
120
|
+
help: "The model the conversation auto-namer completes through (provider/model-id); absent = the default model",
|
|
121
|
+
apply: applyOf("namingModel"),
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: "section",
|
|
127
|
+
id: "core-general-behaviour",
|
|
128
|
+
title: "Behaviour",
|
|
129
|
+
children: [
|
|
130
|
+
{
|
|
131
|
+
type: "number",
|
|
132
|
+
name: "skills.sectionMaxBytes",
|
|
133
|
+
label: "Skills section size cap",
|
|
134
|
+
help: "The skills prompt section's byte cap (truncation notice included)",
|
|
135
|
+
apply: applyOf("skills.sectionMaxBytes"),
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: "text",
|
|
139
|
+
name: "notifications.runSettled",
|
|
140
|
+
label: "Run-settled notifications",
|
|
141
|
+
help: "When a settled run notifies (default: unwatched)",
|
|
142
|
+
apply: applyOf("notifications.runSettled"),
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "tools",
|
|
152
|
+
title: "Tools",
|
|
153
|
+
icon: "edit",
|
|
154
|
+
form: {
|
|
155
|
+
v: 1,
|
|
156
|
+
root: {
|
|
157
|
+
type: "form",
|
|
158
|
+
id: "core-tools-form",
|
|
159
|
+
bind: "/settings",
|
|
160
|
+
mode: "submit",
|
|
161
|
+
onSubmit: "save",
|
|
162
|
+
submitLabel: "Save",
|
|
163
|
+
children: [
|
|
164
|
+
{
|
|
165
|
+
type: "section",
|
|
166
|
+
id: "core-tools-defaults",
|
|
167
|
+
title: "Defaults",
|
|
168
|
+
children: [
|
|
169
|
+
{
|
|
170
|
+
type: "choice",
|
|
171
|
+
name: "defaultTools",
|
|
172
|
+
label: "Default tools",
|
|
173
|
+
help: "The model-offered tool filter for new conversations (empty = every installed tool); the filter hides listed tools and can never disable them all",
|
|
174
|
+
apply: applyOf("defaultTools"),
|
|
175
|
+
multi: true,
|
|
176
|
+
// The roster is server data (the boot registry's tool
|
|
177
|
+
// names), bound from the core surface's data block — a
|
|
178
|
+
// literal list would drift from the installed tools.
|
|
179
|
+
options: { $: "/toolRoster" },
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
type: "toggle",
|
|
183
|
+
// Absent means ON (boot reads `?? true`): the channels
|
|
184
|
+
// initialize the untouched toggle ON and the save skips
|
|
185
|
+
// the key while it sits at the default.
|
|
186
|
+
default: true,
|
|
187
|
+
name: "autoEnableCodemode",
|
|
188
|
+
label: "Auto-enable codemode",
|
|
189
|
+
help: "When an enabled MCP server exposes codemode, keep the codemode tool (or tool_search) in new conversations' default set",
|
|
190
|
+
apply: applyOf("autoEnableCodemode"),
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: "interface",
|
|
200
|
+
title: "Interface",
|
|
201
|
+
icon: "image",
|
|
202
|
+
// Client-side prefs + theme (usePrefs / useTheme): the channels
|
|
203
|
+
// render their native Interface controls over this section's
|
|
204
|
+
// entry; the empty form satisfies the section contract and keeps
|
|
205
|
+
// the search index's title row.
|
|
206
|
+
form: {
|
|
207
|
+
v: 1,
|
|
208
|
+
root: {
|
|
209
|
+
type: "form",
|
|
210
|
+
id: "core-interface-form",
|
|
211
|
+
bind: "/settings",
|
|
212
|
+
mode: "submit",
|
|
213
|
+
onSubmit: "save",
|
|
214
|
+
submitLabel: "Save",
|
|
215
|
+
children: [],
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: "advanced",
|
|
221
|
+
title: "Advanced",
|
|
222
|
+
icon: "more",
|
|
223
|
+
form: {
|
|
224
|
+
v: 1,
|
|
225
|
+
root: {
|
|
226
|
+
type: "form",
|
|
227
|
+
id: "core-advanced-form",
|
|
228
|
+
bind: "/settings",
|
|
229
|
+
mode: "submit",
|
|
230
|
+
onSubmit: "save",
|
|
231
|
+
submitLabel: "Save",
|
|
232
|
+
children: [
|
|
233
|
+
{
|
|
234
|
+
type: "section",
|
|
235
|
+
id: "core-advanced-resilience",
|
|
236
|
+
title: "Retries and streaming",
|
|
237
|
+
children: [
|
|
238
|
+
{
|
|
239
|
+
type: "toggle",
|
|
240
|
+
// Absent means ON (pi-durable's retry policy defaults on).
|
|
241
|
+
default: true,
|
|
242
|
+
name: "retry.enabled",
|
|
243
|
+
label: "Retry enabled",
|
|
244
|
+
help: "pi-durable's retry policy for failed requests",
|
|
245
|
+
apply: applyOf("retry.enabled"),
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
type: "number",
|
|
249
|
+
name: "retry.maxRetries",
|
|
250
|
+
label: "Max retries",
|
|
251
|
+
help: "pi-durable retry.maxRetries",
|
|
252
|
+
apply: applyOf("retry.maxRetries"),
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
type: "number",
|
|
256
|
+
name: "retry.baseDelayMs",
|
|
257
|
+
label: "Retry base delay (ms)",
|
|
258
|
+
apply: applyOf("retry.baseDelayMs"),
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
type: "number",
|
|
262
|
+
name: "retry.maxAgentDelayMs",
|
|
263
|
+
label: "Max agent delay (ms)",
|
|
264
|
+
apply: applyOf("retry.maxAgentDelayMs"),
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
type: "number",
|
|
268
|
+
name: "stream.timeoutMs",
|
|
269
|
+
label: "Stream timeout (ms)",
|
|
270
|
+
apply: applyOf("stream.timeoutMs"),
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
type: "number",
|
|
274
|
+
name: "stream.maxRetries",
|
|
275
|
+
label: "Stream max retries",
|
|
276
|
+
apply: applyOf("stream.maxRetries"),
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
type: "number",
|
|
280
|
+
name: "stream.maxRetryDelayMs",
|
|
281
|
+
label: "Stream max retry delay (ms)",
|
|
282
|
+
apply: applyOf("stream.maxRetryDelayMs"),
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
type: "section",
|
|
288
|
+
id: "core-advanced-models",
|
|
289
|
+
title: "Model overrides",
|
|
290
|
+
children: [
|
|
291
|
+
{
|
|
292
|
+
type: "longtext",
|
|
293
|
+
name: "perModelThinking",
|
|
294
|
+
label: "Per-model thinking (raw JSON)",
|
|
295
|
+
help: 'A raw JSON object — "provider/modelId": thinking level (off, minimal, low, medium, high, xhigh, max); empty clears',
|
|
296
|
+
apply: applyOf("perModelThinking"),
|
|
297
|
+
syntax: "code",
|
|
298
|
+
lang: "json",
|
|
299
|
+
rows: 6,
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
type: "section",
|
|
305
|
+
id: "core-advanced-server",
|
|
306
|
+
title: "Server",
|
|
307
|
+
children: [
|
|
308
|
+
{
|
|
309
|
+
type: "number",
|
|
310
|
+
name: "server.port",
|
|
311
|
+
label: "Listen port",
|
|
312
|
+
help: "The listener binds at boot — a change applies at restart",
|
|
313
|
+
apply: applyOf("server.port"),
|
|
314
|
+
min: 1,
|
|
315
|
+
max: 65535,
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
type: "text",
|
|
319
|
+
name: "server.publicUrl",
|
|
320
|
+
label: "Public URL",
|
|
321
|
+
help: "The deployment's absolute base URL (extension-route URLs and notification deep links)",
|
|
322
|
+
apply: applyOf("server.publicUrl"),
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
type: "text",
|
|
326
|
+
name: "server.timezone",
|
|
327
|
+
label: "Jobs default timezone",
|
|
328
|
+
help: "The IANA zone jobs without an explicit timezone schedule in",
|
|
329
|
+
apply: applyOf("server.timezone"),
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
type: "section",
|
|
335
|
+
id: "core-advanced-compaction",
|
|
336
|
+
title: "Compaction",
|
|
337
|
+
children: [
|
|
338
|
+
{
|
|
339
|
+
type: "toggle",
|
|
340
|
+
// Absent means ON (the boot compaction policy defaults on).
|
|
341
|
+
default: true,
|
|
342
|
+
name: "server.compaction.enabled",
|
|
343
|
+
label: "Compaction enabled",
|
|
344
|
+
apply: applyOf("server.compaction.enabled"),
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
type: "number",
|
|
348
|
+
name: "server.compaction.reserveTokens",
|
|
349
|
+
label: "Reserve tokens",
|
|
350
|
+
apply: applyOf("server.compaction.reserveTokens"),
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
type: "number",
|
|
354
|
+
name: "server.compaction.keepRecentTokens",
|
|
355
|
+
label: "Keep recent tokens",
|
|
356
|
+
apply: applyOf("server.compaction.keepRecentTokens"),
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
type: "number",
|
|
360
|
+
name: "server.compaction.backgroundTokens",
|
|
361
|
+
label: "Background tokens",
|
|
362
|
+
apply: applyOf("server.compaction.backgroundTokens"),
|
|
363
|
+
},
|
|
364
|
+
],
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
type: "section",
|
|
368
|
+
id: "core-advanced-history",
|
|
369
|
+
title: "Job history retention",
|
|
370
|
+
children: [
|
|
371
|
+
{
|
|
372
|
+
type: "number",
|
|
373
|
+
name: "jobHistory.runs",
|
|
374
|
+
label: "Runs kept per job",
|
|
375
|
+
apply: applyOf("jobHistory.runs"),
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
type: "number",
|
|
379
|
+
name: "jobHistory.revisions",
|
|
380
|
+
label: "Revisions kept per job",
|
|
381
|
+
apply: applyOf("jobHistory.revisions"),
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
id: "providers",
|
|
391
|
+
title: "Providers",
|
|
392
|
+
icon: "cloud",
|
|
393
|
+
// The §7.6 credential flows (readiness rows + write-only key
|
|
394
|
+
// fields + the bounded refresh): the channels render their native
|
|
395
|
+
// Providers cove over this entry. The form carries the one
|
|
396
|
+
// provider-adjacent SETTINGS key (the refresh cadence).
|
|
397
|
+
form: {
|
|
398
|
+
v: 1,
|
|
399
|
+
root: {
|
|
400
|
+
type: "form",
|
|
401
|
+
id: "core-providers-form",
|
|
402
|
+
bind: "/settings",
|
|
403
|
+
mode: "submit",
|
|
404
|
+
onSubmit: "save",
|
|
405
|
+
submitLabel: "Save",
|
|
406
|
+
children: [
|
|
407
|
+
{
|
|
408
|
+
type: "section",
|
|
409
|
+
id: "core-providers-defaults",
|
|
410
|
+
title: "Defaults",
|
|
411
|
+
children: [
|
|
412
|
+
{
|
|
413
|
+
type: "text",
|
|
414
|
+
name: "defaultProvider.baseUrl",
|
|
415
|
+
label: "Default provider base URL",
|
|
416
|
+
help: "The env-driven OpenAI-compatible provider's endpoint (applied when OPENAI_BASE_URL is absent) — a change applies at restart",
|
|
417
|
+
apply: applyOf("defaultProvider.baseUrl"),
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
type: "number",
|
|
421
|
+
name: "server.providers.refreshIntervalMinutes",
|
|
422
|
+
label: "Model catalog refresh (minutes)",
|
|
423
|
+
help: "The provider catalog refresh cadence; a change re-arms the scheduler live",
|
|
424
|
+
apply: applyOf("server.providers.refreshIntervalMinutes"),
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
},
|
|
428
|
+
],
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
id: "extensions",
|
|
434
|
+
title: "Extensions",
|
|
435
|
+
icon: "add",
|
|
436
|
+
// The extension-list editor (per-extension raw JSON + write-only
|
|
437
|
+
// secrets) is the channels' cove; the form carries the core
|
|
438
|
+
// extension knobs (the install list + the built-in toggles).
|
|
439
|
+
form: {
|
|
440
|
+
v: 1,
|
|
441
|
+
root: {
|
|
442
|
+
type: "form",
|
|
443
|
+
id: "core-extensions-form",
|
|
444
|
+
bind: "/settings",
|
|
445
|
+
mode: "submit",
|
|
446
|
+
onSubmit: "save",
|
|
447
|
+
submitLabel: "Save",
|
|
448
|
+
children: [
|
|
449
|
+
{
|
|
450
|
+
type: "section",
|
|
451
|
+
id: "core-extensions-list",
|
|
452
|
+
title: "Installed extensions",
|
|
453
|
+
children: [
|
|
454
|
+
{
|
|
455
|
+
type: "longtext",
|
|
456
|
+
name: "extensions",
|
|
457
|
+
label: "Extension list (raw JSON)",
|
|
458
|
+
help: "The unified install-and-load list (npm specifiers, bare names, file:/git sources, or {source, entry?, ref?, enabled?} objects) — applied at boot reconciliation, so a change applies at restart",
|
|
459
|
+
apply: applyOf("extensions"),
|
|
460
|
+
syntax: "code",
|
|
461
|
+
lang: "json",
|
|
462
|
+
rows: 4,
|
|
463
|
+
},
|
|
464
|
+
],
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
type: "section",
|
|
468
|
+
id: "core-extensions-builtins",
|
|
469
|
+
title: "Built-in extensions",
|
|
470
|
+
children: [
|
|
471
|
+
{
|
|
472
|
+
type: "toggle",
|
|
473
|
+
// Absent means ON (the built-in set defaults enabled).
|
|
474
|
+
default: true,
|
|
475
|
+
name: "builtinExtensions.codemode",
|
|
476
|
+
label: "Codemode",
|
|
477
|
+
help: "The built-in codemode extension (a disabled built-in never loads) — applies at restart",
|
|
478
|
+
apply: applyOf("builtinExtensions.codemode"),
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
type: "toggle",
|
|
482
|
+
// Absent means ON (the built-in set defaults enabled).
|
|
483
|
+
default: true,
|
|
484
|
+
name: "builtinExtensions.mcp",
|
|
485
|
+
label: "MCP",
|
|
486
|
+
help: "The built-in MCP extension — applies at restart",
|
|
487
|
+
apply: applyOf("builtinExtensions.mcp"),
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
type: "toggle",
|
|
491
|
+
// Absent means ON (the built-in set defaults enabled).
|
|
492
|
+
default: true,
|
|
493
|
+
name: "builtinExtensions.toolSearch",
|
|
494
|
+
label: "Tool search",
|
|
495
|
+
help: "The built-in tool-search extension — applies at restart",
|
|
496
|
+
apply: applyOf("builtinExtensions.toolSearch"),
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
type: "toggle",
|
|
500
|
+
default: true,
|
|
501
|
+
name: "builtinExtensions.oauth",
|
|
502
|
+
label: "OAuth login",
|
|
503
|
+
help: "The built-in OIDC/OAuth2 login extension — applies at restart",
|
|
504
|
+
apply: applyOf("builtinExtensions.oauth"),
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
},
|
|
508
|
+
],
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
id: "accounts",
|
|
514
|
+
title: "Account links",
|
|
515
|
+
icon: "key",
|
|
516
|
+
// Per-user identity management, not an administrator-only section.
|
|
517
|
+
admin: false,
|
|
518
|
+
// The channels render their native account-link cove over this entry.
|
|
519
|
+
form: {
|
|
520
|
+
v: 1,
|
|
521
|
+
root: {
|
|
522
|
+
type: "form",
|
|
523
|
+
id: "core-accounts-form",
|
|
524
|
+
bind: "/settings",
|
|
525
|
+
mode: "submit",
|
|
526
|
+
onSubmit: "save",
|
|
527
|
+
submitLabel: "Save",
|
|
528
|
+
children: [],
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
];
|