zames_pro 2.88.2 → 2.89.0

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.
@@ -0,0 +1,554 @@
1
+ // The /config SCHEMA: the settings an operator may change from the menu and
2
+ // from the /config text subcommands. It is DATA ONLY (no disk, no terminal), so
3
+ // the menu, the list renderer and the set/get validation all share it.
4
+ //
5
+ // TWO LEVELS of grouping. `topKey` is the first menu level (Agent, Browser &
6
+ // chat, Providers, Interface, ...) and `groupKey` is the section INSIDE it. The
7
+ // flat 40-entry list this replaced was unusable: every timing knob of every
8
+ // backend sat in one scroll.
9
+ //
10
+ // To add a setting — add it here and to DEFAULTS/types.ts.
11
+ import { themeNames } from './theme.js';
12
+ import { PROVIDER_IDS } from './providers.js';
13
+ /** Top-level menu groups, in menu order. */
14
+ export const CONFIG_TOP_GROUPS = [
15
+ 'cfg.top.agent',
16
+ 'cfg.top.browser',
17
+ 'cfg.top.providers',
18
+ 'cfg.top.ui',
19
+ 'cfg.top.files',
20
+ 'cfg.top.diagnostics',
21
+ ];
22
+ export const CONFIG_SCHEMA = [
23
+ // ---------- Agent ----------
24
+ {
25
+ path: 'provider',
26
+ type: 'enum',
27
+ values: [...PROVIDER_IDS],
28
+ labelKey: 'cfg.f.provider',
29
+ topKey: 'cfg.top.agent',
30
+ groupKey: 'cfg.group.agent',
31
+ },
32
+ {
33
+ path: 'maxIterations',
34
+ type: 'number',
35
+ min: 0,
36
+ max: 100000,
37
+ labelKey: 'cfg.f.maxIterations',
38
+ topKey: 'cfg.top.agent',
39
+ groupKey: 'cfg.group.agent',
40
+ },
41
+ {
42
+ path: 'headless',
43
+ type: 'boolean',
44
+ labelKey: 'cfg.f.headless',
45
+ topKey: 'cfg.top.agent',
46
+ groupKey: 'cfg.group.agent',
47
+ },
48
+ {
49
+ path: 'debug',
50
+ type: 'boolean',
51
+ labelKey: 'cfg.f.debug',
52
+ topKey: 'cfg.top.agent',
53
+ groupKey: 'cfg.group.agent',
54
+ },
55
+ {
56
+ path: 'hotReload',
57
+ type: 'boolean',
58
+ labelKey: 'cfg.f.hotReload',
59
+ topKey: 'cfg.top.agent',
60
+ groupKey: 'cfg.group.agent',
61
+ },
62
+ {
63
+ path: 'browser.subagents',
64
+ type: 'boolean',
65
+ labelKey: 'cfg.f.browser_subagents',
66
+ topKey: 'cfg.top.agent',
67
+ groupKey: 'cfg.group.agent',
68
+ },
69
+ {
70
+ path: 'browser.maxSubagents',
71
+ type: 'number',
72
+ min: 0,
73
+ max: 20,
74
+ labelKey: 'cfg.f.browser_maxSubagents',
75
+ topKey: 'cfg.top.agent',
76
+ groupKey: 'cfg.group.agent',
77
+ },
78
+ // ---------- Browser & chat: session ----------
79
+ {
80
+ path: 'browser.answerTimeoutMs',
81
+ type: 'number',
82
+ min: 1000,
83
+ max: 3600000,
84
+ labelKey: 'cfg.f.browser_answerTimeoutMs',
85
+ topKey: 'cfg.top.browser',
86
+ groupKey: 'cfg.group.chat',
87
+ },
88
+ {
89
+ path: 'browser.askRetries',
90
+ type: 'number',
91
+ min: 1,
92
+ max: 100,
93
+ labelKey: 'cfg.f.browser_askRetries',
94
+ topKey: 'cfg.top.browser',
95
+ groupKey: 'cfg.group.chat',
96
+ },
97
+ {
98
+ path: 'browser.stabilityChecks',
99
+ type: 'number',
100
+ min: 1,
101
+ max: 100,
102
+ labelKey: 'cfg.f.browser_stabilityChecks',
103
+ topKey: 'cfg.top.browser',
104
+ groupKey: 'cfg.group.chat',
105
+ },
106
+ {
107
+ path: 'browser.stabilityDelayMs',
108
+ type: 'number',
109
+ min: 0,
110
+ max: 60000,
111
+ labelKey: 'cfg.f.browser_stabilityDelayMs',
112
+ topKey: 'cfg.top.browser',
113
+ groupKey: 'cfg.group.chat',
114
+ },
115
+ {
116
+ path: 'browser.askDeadlineMs',
117
+ type: 'number',
118
+ min: 30000,
119
+ max: 1800000,
120
+ labelKey: 'cfg.f.browser_askDeadlineMs',
121
+ topKey: 'cfg.top.browser',
122
+ groupKey: 'cfg.group.chat',
123
+ },
124
+ {
125
+ path: 'browser.maxAfterToolRetries',
126
+ type: 'number',
127
+ min: 0,
128
+ max: 50,
129
+ labelKey: 'cfg.f.browser_maxAfterToolRetries',
130
+ topKey: 'cfg.top.browser',
131
+ groupKey: 'cfg.group.chat',
132
+ },
133
+ {
134
+ path: 'browser.deepThinking',
135
+ type: 'boolean',
136
+ labelKey: 'cfg.f.browser_deepThinking',
137
+ topKey: 'cfg.top.browser',
138
+ groupKey: 'cfg.group.chat',
139
+ },
140
+ {
141
+ path: 'browser.webSearch',
142
+ type: 'boolean',
143
+ labelKey: 'cfg.f.browser_webSearch',
144
+ topKey: 'cfg.top.browser',
145
+ groupKey: 'cfg.group.chat',
146
+ },
147
+ {
148
+ path: 'browser.resendPromptOnResume',
149
+ type: 'boolean',
150
+ labelKey: 'cfg.f.browser_resendPromptOnResume',
151
+ topKey: 'cfg.top.browser',
152
+ groupKey: 'cfg.group.chat',
153
+ },
154
+ {
155
+ path: 'ui.contextLimit',
156
+ type: 'number',
157
+ min: 10_000,
158
+ max: 10_000_000,
159
+ labelKey: 'cfg.f.ui_contextLimit',
160
+ topKey: 'cfg.top.browser',
161
+ groupKey: 'cfg.group.chat',
162
+ },
163
+ // ---------- Browser & chat: throttling ----------
164
+ {
165
+ path: 'browser.minSendIntervalMs',
166
+ type: 'number',
167
+ min: 0,
168
+ max: 600000,
169
+ labelKey: 'cfg.f.browser_minSendIntervalMs',
170
+ topKey: 'cfg.top.browser',
171
+ groupKey: 'cfg.group.throttle',
172
+ },
173
+ {
174
+ path: 'browser.thinkingExtraMs',
175
+ type: 'number',
176
+ min: 0,
177
+ max: 600000,
178
+ labelKey: 'cfg.f.browser_thinkingExtraMs',
179
+ topKey: 'cfg.top.browser',
180
+ groupKey: 'cfg.group.throttle',
181
+ },
182
+ {
183
+ path: 'browser.rateLimitWaitMs',
184
+ type: 'number',
185
+ min: 0,
186
+ max: 3600000,
187
+ labelKey: 'cfg.f.browser_rateLimitWaitMs',
188
+ topKey: 'cfg.top.browser',
189
+ groupKey: 'cfg.group.throttle',
190
+ },
191
+ {
192
+ path: 'browser.maxRateLimitRetries',
193
+ type: 'number',
194
+ min: 0,
195
+ max: 100,
196
+ labelKey: 'cfg.f.browser_maxRateLimitRetries',
197
+ topKey: 'cfg.top.browser',
198
+ groupKey: 'cfg.group.throttle',
199
+ },
200
+ // ---------- Browser & chat: truncated turns ----------
201
+ {
202
+ path: 'browser.maxIncompleteRetries',
203
+ type: 'number',
204
+ min: 0,
205
+ max: 100,
206
+ labelKey: 'cfg.f.browser_maxIncompleteRetries',
207
+ topKey: 'cfg.top.browser',
208
+ groupKey: 'cfg.group.recovery',
209
+ },
210
+ {
211
+ path: 'browser.incompleteWaitMs',
212
+ type: 'number',
213
+ min: 0,
214
+ max: 600000,
215
+ labelKey: 'cfg.f.browser_incompleteWaitMs',
216
+ topKey: 'cfg.top.browser',
217
+ groupKey: 'cfg.group.recovery',
218
+ },
219
+ {
220
+ path: 'browser.autoContinue',
221
+ type: 'boolean',
222
+ labelKey: 'cfg.f.browser_autoContinue',
223
+ topKey: 'cfg.top.browser',
224
+ groupKey: 'cfg.group.recovery',
225
+ },
226
+ {
227
+ path: 'browser.continueMinGapMs',
228
+ type: 'number',
229
+ min: 0,
230
+ max: 600000,
231
+ labelKey: 'cfg.f.browser_continueMinGapMs',
232
+ topKey: 'cfg.top.browser',
233
+ groupKey: 'cfg.group.recovery',
234
+ },
235
+ {
236
+ path: 'browser.autoCompact',
237
+ type: 'boolean',
238
+ labelKey: 'cfg.f.browser_autoCompact',
239
+ topKey: 'cfg.top.browser',
240
+ groupKey: 'cfg.group.recovery',
241
+ },
242
+ {
243
+ path: 'browser.autoCompactPct',
244
+ type: 'number',
245
+ min: 50,
246
+ max: 100,
247
+ labelKey: 'cfg.f.browser_autoCompactPct',
248
+ topKey: 'cfg.top.browser',
249
+ groupKey: 'cfg.group.recovery',
250
+ },
251
+ // ---------- Browser & chat: sign-in ----------
252
+ {
253
+ path: 'browser.auth.username',
254
+ type: 'string',
255
+ labelKey: 'cfg.f.browser_authUsername',
256
+ topKey: 'cfg.top.browser',
257
+ groupKey: 'cfg.group.login',
258
+ },
259
+ {
260
+ path: 'browser.auth.password',
261
+ type: 'string',
262
+ labelKey: 'cfg.f.browser_authPassword',
263
+ topKey: 'cfg.top.browser',
264
+ groupKey: 'cfg.group.login',
265
+ },
266
+ {
267
+ path: 'browser.auth.saveSession',
268
+ type: 'boolean',
269
+ labelKey: 'cfg.f.browser_authSaveSession',
270
+ topKey: 'cfg.top.browser',
271
+ groupKey: 'cfg.group.login',
272
+ },
273
+ {
274
+ path: 'browser.loginTimeoutMs',
275
+ type: 'number',
276
+ min: 30_000,
277
+ max: 3_600_000,
278
+ labelKey: 'cfg.f.browser_loginTimeoutMs',
279
+ topKey: 'cfg.top.browser',
280
+ groupKey: 'cfg.group.login',
281
+ },
282
+ // ---------- Browser & chat: telemetry ----------
283
+ {
284
+ path: 'browser.sendTelemetry',
285
+ type: 'boolean',
286
+ labelKey: 'cfg.f.browser_sendTelemetry',
287
+ topKey: 'cfg.top.browser',
288
+ groupKey: 'cfg.group.telemetry',
289
+ },
290
+ // ---------- Providers: Qwen ----------
291
+ {
292
+ path: 'qwen.model',
293
+ type: 'string',
294
+ labelKey: 'cfg.f.qwen_model',
295
+ topKey: 'cfg.top.providers',
296
+ groupKey: 'cfg.group.qwen',
297
+ },
298
+ {
299
+ path: 'qwen.contextLimit',
300
+ type: 'number',
301
+ min: 10_000,
302
+ max: 10_000_000,
303
+ labelKey: 'cfg.f.qwen_contextLimit',
304
+ topKey: 'cfg.top.providers',
305
+ groupKey: 'cfg.group.qwen',
306
+ },
307
+ {
308
+ path: 'qwen.minSendIntervalMs',
309
+ type: 'number',
310
+ min: 0,
311
+ max: 600000,
312
+ labelKey: 'cfg.f.qwen_minSendIntervalMs',
313
+ topKey: 'cfg.top.providers',
314
+ groupKey: 'cfg.group.qwen',
315
+ },
316
+ {
317
+ path: 'qwen.answerTimeoutMs',
318
+ type: 'number',
319
+ min: 1000,
320
+ max: 3600000,
321
+ labelKey: 'cfg.f.qwen_answerTimeoutMs',
322
+ topKey: 'cfg.top.providers',
323
+ groupKey: 'cfg.group.qwen',
324
+ },
325
+ {
326
+ path: 'qwen.auth.username',
327
+ type: 'string',
328
+ labelKey: 'cfg.f.qwen_authUsername',
329
+ topKey: 'cfg.top.providers',
330
+ groupKey: 'cfg.group.qwen',
331
+ },
332
+ {
333
+ path: 'qwen.auth.password',
334
+ type: 'string',
335
+ labelKey: 'cfg.f.qwen_authPassword',
336
+ topKey: 'cfg.top.providers',
337
+ groupKey: 'cfg.group.qwen',
338
+ },
339
+ // ---------- Providers: GLM ----------
340
+ {
341
+ path: 'glm.model',
342
+ type: 'string',
343
+ labelKey: 'cfg.f.glm_model',
344
+ topKey: 'cfg.top.providers',
345
+ groupKey: 'cfg.group.glm',
346
+ },
347
+ {
348
+ path: 'glm.contextLimit',
349
+ type: 'number',
350
+ min: 10_000,
351
+ max: 10_000_000,
352
+ labelKey: 'cfg.f.glm_contextLimit',
353
+ topKey: 'cfg.top.providers',
354
+ groupKey: 'cfg.group.glm',
355
+ },
356
+ {
357
+ path: 'glm.minSendIntervalMs',
358
+ type: 'number',
359
+ min: 0,
360
+ max: 600000,
361
+ labelKey: 'cfg.f.glm_minSendIntervalMs',
362
+ topKey: 'cfg.top.providers',
363
+ groupKey: 'cfg.group.glm',
364
+ },
365
+ {
366
+ path: 'glm.answerTimeoutMs',
367
+ type: 'number',
368
+ min: 1000,
369
+ max: 3600000,
370
+ labelKey: 'cfg.f.glm_answerTimeoutMs',
371
+ topKey: 'cfg.top.providers',
372
+ groupKey: 'cfg.group.glm',
373
+ },
374
+ {
375
+ path: 'glm.auth.username',
376
+ type: 'string',
377
+ labelKey: 'cfg.f.glm_authUsername',
378
+ topKey: 'cfg.top.providers',
379
+ groupKey: 'cfg.group.glm',
380
+ },
381
+ {
382
+ path: 'glm.auth.password',
383
+ type: 'string',
384
+ labelKey: 'cfg.f.glm_authPassword',
385
+ topKey: 'cfg.top.providers',
386
+ groupKey: 'cfg.group.glm',
387
+ },
388
+ // ---------- Interface: language & look ----------
389
+ {
390
+ path: 'ui.locale',
391
+ type: 'enum',
392
+ values: ['ru', 'en'],
393
+ labelKey: 'cfg.f.ui_locale',
394
+ topKey: 'cfg.top.ui',
395
+ groupKey: 'cfg.group.look',
396
+ },
397
+ {
398
+ path: 'ui.theme',
399
+ type: 'enum',
400
+ values: themeNames(),
401
+ labelKey: 'cfg.f.ui_theme',
402
+ topKey: 'cfg.top.ui',
403
+ groupKey: 'cfg.group.look',
404
+ },
405
+ {
406
+ path: 'ui.inputBorder',
407
+ type: 'enum',
408
+ values: ['round', 'single', 'double', 'bold', 'none'],
409
+ labelKey: 'cfg.f.ui_inputBorder',
410
+ topKey: 'cfg.top.ui',
411
+ groupKey: 'cfg.group.look',
412
+ },
413
+ {
414
+ path: 'ui.answerWidth',
415
+ type: 'number',
416
+ min: 0,
417
+ max: 1000,
418
+ labelKey: 'cfg.f.ui_answerWidth',
419
+ topKey: 'cfg.top.ui',
420
+ groupKey: 'cfg.group.look',
421
+ },
422
+ // ---------- Interface: terminal TUI ----------
423
+ {
424
+ path: 'ui.tui',
425
+ type: 'boolean',
426
+ labelKey: 'cfg.f.ui_tui',
427
+ topKey: 'cfg.top.ui',
428
+ groupKey: 'cfg.group.tui',
429
+ },
430
+ {
431
+ path: 'ui.alternateScreen',
432
+ type: 'boolean',
433
+ labelKey: 'cfg.f.ui_alternateScreen',
434
+ topKey: 'cfg.top.ui',
435
+ groupKey: 'cfg.group.tui',
436
+ },
437
+ {
438
+ path: 'ui.mouseScroll',
439
+ type: 'boolean',
440
+ labelKey: 'cfg.f.ui_mouseScroll',
441
+ topKey: 'cfg.top.ui',
442
+ groupKey: 'cfg.group.tui',
443
+ },
444
+ // ---------- Files & history ----------
445
+ {
446
+ path: 'undo.enabled',
447
+ type: 'boolean',
448
+ labelKey: 'cfg.f.undo_enabled',
449
+ topKey: 'cfg.top.files',
450
+ groupKey: 'cfg.group.undo',
451
+ },
452
+ {
453
+ path: 'undo.maxBackups',
454
+ type: 'number',
455
+ min: 1,
456
+ max: 100000,
457
+ labelKey: 'cfg.f.undo_maxBackups',
458
+ topKey: 'cfg.top.files',
459
+ groupKey: 'cfg.group.undo',
460
+ },
461
+ {
462
+ path: 'checkpoint.enabled',
463
+ type: 'boolean',
464
+ labelKey: 'cfg.f.checkpoint_enabled',
465
+ topKey: 'cfg.top.files',
466
+ groupKey: 'cfg.group.checkpoint',
467
+ },
468
+ {
469
+ path: 'checkpoint.maxBackups',
470
+ type: 'number',
471
+ min: 1,
472
+ max: 1000,
473
+ labelKey: 'cfg.f.checkpoint_maxBackups',
474
+ topKey: 'cfg.top.files',
475
+ groupKey: 'cfg.group.checkpoint',
476
+ },
477
+ {
478
+ path: 'transcript.enabled',
479
+ type: 'boolean',
480
+ labelKey: 'cfg.f.transcript_enabled',
481
+ topKey: 'cfg.top.files',
482
+ groupKey: 'cfg.group.transcript',
483
+ },
484
+ // ---------- Diagnostics (post-edit check) ----------
485
+ {
486
+ path: 'diagnostics.enabled',
487
+ type: 'boolean',
488
+ labelKey: 'cfg.f.diagnostics_enabled',
489
+ topKey: 'cfg.top.diagnostics',
490
+ groupKey: 'cfg.group.diagnostics',
491
+ },
492
+ {
493
+ path: 'diagnostics.command',
494
+ type: 'string',
495
+ labelKey: 'cfg.f.diagnostics_command',
496
+ topKey: 'cfg.top.diagnostics',
497
+ groupKey: 'cfg.group.diagnostics',
498
+ },
499
+ {
500
+ path: 'diagnostics.timeoutMs',
501
+ type: 'number',
502
+ min: 1000,
503
+ max: 1800000,
504
+ labelKey: 'cfg.f.diagnostics_timeoutMs',
505
+ topKey: 'cfg.top.diagnostics',
506
+ groupKey: 'cfg.group.diagnostics',
507
+ },
508
+ {
509
+ path: 'diagnostics.maxChars',
510
+ type: 'number',
511
+ min: 200,
512
+ max: 100000,
513
+ labelKey: 'cfg.f.diagnostics_maxChars',
514
+ topKey: 'cfg.top.diagnostics',
515
+ groupKey: 'cfg.group.diagnostics',
516
+ },
517
+ ];
518
+ export function getConfigField(path) {
519
+ return CONFIG_SCHEMA.find((f) => f.path === path);
520
+ }
521
+ /** Fields of one top-level menu group, in schema order. */
522
+ export function fieldsOfTopGroup(topKey) {
523
+ return CONFIG_SCHEMA.filter((f) => f.topKey === topKey && !f.advanced);
524
+ }
525
+ /** Subgroups of one top-level group, in schema order (deduplicated). */
526
+ export function subgroupsOf(topKey) {
527
+ const out = [];
528
+ for (const f of CONFIG_SCHEMA) {
529
+ if (f.topKey !== topKey || f.advanced)
530
+ continue;
531
+ if (!out.includes(f.groupKey))
532
+ out.push(f.groupKey);
533
+ }
534
+ return out;
535
+ }
536
+ /**
537
+ * True when at least one field of `topKey` differs from its default — the
538
+ * menu marks such a group so the operator sees where a change lives without
539
+ * opening every group.
540
+ */
541
+ export function topGroupModified(topKey, get, getDefault) {
542
+ return fieldsOfTopGroup(topKey).some((f) => {
543
+ const cur = get(f.path);
544
+ const def = getDefault(f.path);
545
+ if (cur === undefined)
546
+ return false;
547
+ try {
548
+ return JSON.stringify(cur) !== JSON.stringify(def);
549
+ }
550
+ catch {
551
+ return String(cur) !== String(def);
552
+ }
553
+ });
554
+ }