dsh-switchman 1.10.3 → 1.11.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/README.de.md +11 -10
- package/README.es.md +11 -10
- package/README.fr.md +11 -10
- package/README.it.md +11 -10
- package/README.ja.md +11 -10
- package/README.ko.md +11 -10
- package/README.md +19 -10
- package/README.pt.md +11 -10
- package/README.ru.md +11 -10
- package/README.zh-TW.md +11 -10
- package/README.zh.md +11 -10
- package/client.js +326 -43
- package/cordis.patch.yml +24 -21
- package/host/config.js +57 -10
- package/host/context-trim/fork.js +5 -1
- package/host/context-trim/index.js +340 -183
- package/host/context-trim/metrics.js +22 -14
- package/host/context-trim/state.js +351 -50
- package/host/context-trim/summarizer.js +147 -33
- package/host/context-trim/surface.js +222 -2
- package/host/context-trim/trigger.js +170 -51
- package/host/context-trim/view.js +132 -16
- package/host/context-watch.js +81 -73
- package/host/dispatch.js +30 -5
- package/host/routes.js +64 -4
- package/host/teams.js +2 -1
- package/package.json +2 -2
package/client.js
CHANGED
|
@@ -194,7 +194,7 @@ window.__ModuleLoader__.load({
|
|
|
194
194
|
* Host-side default (also the fallback for malformed stored values). */
|
|
195
195
|
const WM_NUMBER_FIELDS = [
|
|
196
196
|
{ field: 'wmSoftTokens', min: 1000, def: 80000 },
|
|
197
|
-
{ field: 'wmHardTokens', min: 2000, def:
|
|
197
|
+
{ field: 'wmHardTokens', min: 2000, def: 95000 },
|
|
198
198
|
{ field: 'wmForceTokens', min: 3000, def: 150000 },
|
|
199
199
|
{ field: 'wmReadBudgetTokens', min: 200, def: 3000 },
|
|
200
200
|
{ field: 'wmSubagentForceTokens', min: 0, def: 0 },
|
|
@@ -265,13 +265,22 @@ window.__ModuleLoader__.load({
|
|
|
265
265
|
|
|
266
266
|
/** Numeric trim fields: settings field, schema minimum, and the
|
|
267
267
|
* Host-side default (also the fallback for malformed stored
|
|
268
|
-
* values). Percent fields cap at 100 like their Host schema.
|
|
268
|
+
* values). Percent fields cap at 100 like their Host schema.
|
|
269
|
+
* MUST mirror host/routes.js TRIM_NUMBER_FIELDS bounds — a field
|
|
270
|
+
* coerced server-side but never sent here fails every fenced
|
|
271
|
+
* write (and vice versa). */
|
|
269
272
|
const TRIM_NUMBER_FIELDS = [
|
|
270
273
|
{ field: 'trimGrowthTokens', min: 1000, def: 22500 },
|
|
271
|
-
{ field: 'trimIncrementTokens', min: 1000, def:
|
|
272
|
-
{ field: 'trimPressurePercent', min: 5, max: 100, def:
|
|
274
|
+
{ field: 'trimIncrementTokens', min: 1000, def: 25000 },
|
|
275
|
+
{ field: 'trimPressurePercent', min: 5, max: 100, def: 65 },
|
|
273
276
|
{ field: 'trimEmergencyPercent', min: 5, max: 100, def: 95 },
|
|
274
277
|
{ field: 'trimWindowTokens', min: 0, def: 0 },
|
|
278
|
+
{ field: 'trimProtectedTail', min: 0, max: 100, def: 10 },
|
|
279
|
+
{ field: 'trimMaxFoldsPerHour', min: 1, max: 60, def: 30 },
|
|
280
|
+
{ field: 'trimLadderT2Tokens', min: 1000, def: 8000 },
|
|
281
|
+
{ field: 'trimLadderT2MinBlocks', min: 2, max: 200, def: 3 },
|
|
282
|
+
{ field: 'trimLadderT3Tokens', min: 1000, def: 6000 },
|
|
283
|
+
{ field: 'trimLadderT3MinBlocks', min: 2, max: 200, def: 2 },
|
|
275
284
|
];
|
|
276
285
|
|
|
277
286
|
/** Dictionary keys per numeric trim row. */
|
|
@@ -293,6 +302,30 @@ window.__ModuleLoader__.load({
|
|
|
293
302
|
label: 'trimWindowLabel',
|
|
294
303
|
help: 'trimWindowHelp',
|
|
295
304
|
},
|
|
305
|
+
trimProtectedTail: {
|
|
306
|
+
label: 'trimProtectedTailLabel',
|
|
307
|
+
help: 'trimProtectedTailHelp',
|
|
308
|
+
},
|
|
309
|
+
trimMaxFoldsPerHour: {
|
|
310
|
+
label: 'trimMaxFoldsPerHourLabel',
|
|
311
|
+
help: 'trimMaxFoldsPerHourHelp',
|
|
312
|
+
},
|
|
313
|
+
trimLadderT2Tokens: {
|
|
314
|
+
label: 'trimLadderT2TokensLabel',
|
|
315
|
+
help: 'trimLadderT2TokensHelp',
|
|
316
|
+
},
|
|
317
|
+
trimLadderT2MinBlocks: {
|
|
318
|
+
label: 'trimLadderT2MinBlocksLabel',
|
|
319
|
+
help: 'trimLadderT2MinBlocksHelp',
|
|
320
|
+
},
|
|
321
|
+
trimLadderT3Tokens: {
|
|
322
|
+
label: 'trimLadderT3TokensLabel',
|
|
323
|
+
help: 'trimLadderT3TokensHelp',
|
|
324
|
+
},
|
|
325
|
+
trimLadderT3MinBlocks: {
|
|
326
|
+
label: 'trimLadderT3MinBlocksLabel',
|
|
327
|
+
help: 'trimLadderT3MinBlocksHelp',
|
|
328
|
+
},
|
|
296
329
|
};
|
|
297
330
|
|
|
298
331
|
/** Every settings field this page edits, in mutate order. */
|
|
@@ -311,6 +344,11 @@ window.__ModuleLoader__.load({
|
|
|
311
344
|
// Context trim (design: context-trim-port-design.md).
|
|
312
345
|
'trimMode',
|
|
313
346
|
'trimEnabled',
|
|
347
|
+
'trimLadderEnabled',
|
|
348
|
+
'surfaceFold',
|
|
349
|
+
'trimSideModel',
|
|
350
|
+
'trimFoldFallbackModel',
|
|
351
|
+
'trimStateDir',
|
|
314
352
|
...TRIM_NUMBER_FIELDS.map(({ field }) => field),
|
|
315
353
|
'teamsMode',
|
|
316
354
|
'syncWhitelist',
|
|
@@ -482,6 +520,15 @@ window.__ModuleLoader__.load({
|
|
|
482
520
|
? value.trimMode
|
|
483
521
|
: 'auto',
|
|
484
522
|
trimEnabled: bool('trimEnabled', true),
|
|
523
|
+
trimLadderEnabled: bool('trimLadderEnabled', true),
|
|
524
|
+
surfaceFold: bool('surfaceFold', true),
|
|
525
|
+
trimSideModel:
|
|
526
|
+
sanitizeRoute(value?.trimSideModel) ??
|
|
527
|
+
({ provider: '', model: '' }),
|
|
528
|
+
trimFoldFallbackModel:
|
|
529
|
+
sanitizeRoute(value?.trimFoldFallbackModel) ??
|
|
530
|
+
({ provider: '', model: '' }),
|
|
531
|
+
trimStateDir: string('trimStateDir'),
|
|
485
532
|
...Object.fromEntries(
|
|
486
533
|
TRIM_NUMBER_FIELDS.map((spec) => [spec.field, number(spec)]),
|
|
487
534
|
),
|
|
@@ -561,6 +608,11 @@ window.__ModuleLoader__.load({
|
|
|
561
608
|
wmSubagentCap: values.wmSubagentCap,
|
|
562
609
|
trimMode: values.trimMode,
|
|
563
610
|
trimEnabled: values.trimEnabled,
|
|
611
|
+
trimLadderEnabled: values.trimLadderEnabled,
|
|
612
|
+
surfaceFold: values.surfaceFold,
|
|
613
|
+
trimSideModel: routeKey(values.trimSideModel),
|
|
614
|
+
trimFoldFallbackModel: routeKey(values.trimFoldFallbackModel),
|
|
615
|
+
trimStateDir: values.trimStateDir,
|
|
564
616
|
...Object.fromEntries(
|
|
565
617
|
TRIM_NUMBER_FIELDS.map(({ field }) => [field, values[field]]),
|
|
566
618
|
),
|
|
@@ -853,6 +905,30 @@ window.__ModuleLoader__.load({
|
|
|
853
905
|
'空闲时何时把历史折叠为摘要:off = 从不折叠,advisory = 仅模型主动调用,auto = 自动折叠。',
|
|
854
906
|
trimEnabledLabel: '启用自动裁剪',
|
|
855
907
|
trimEnabledHelp: '上下文裁剪层的总开关。',
|
|
908
|
+
trimLadderEnabledLabel: '阶梯折叠(T1/T2/T3)',
|
|
909
|
+
trimLadderEnabledHelp: '把累积的 T1 摘要再蒸馏为 T2、T2 再凝聚为 T3,让长会话视图保持平稳。',
|
|
910
|
+
surfaceFoldLabel: '把折叠写入会话表面',
|
|
911
|
+
surfaceFoldHelp: '追加宿主风格的替换事件,让折叠在冻结派发下也能到达线上。建议保持开启。',
|
|
912
|
+
trimSideModelLabel: '摘要模型',
|
|
913
|
+
trimSideModelHelp: '折叠摘要使用的模型路由;默认「跟随会话模型」。阶梯蒸馏同样使用该路由。',
|
|
914
|
+
trimFollowSession: '跟随会话模型',
|
|
915
|
+
trimFoldFallbackModelLabel: '折叠异常兜底模型',
|
|
916
|
+
trimFoldFallbackModelHelp: '摘要模型调用失败时改用该模型重试;仍失败则压力折叠退回机械折叠。尽量选择没有冷却、风控或并发限制的模型,避免与主会话共用同一账号。留空 = 无兜底。',
|
|
917
|
+
trimFallbackUnset: '未设置(失败时直接机械折叠)',
|
|
918
|
+
trimStateDirLabel: '账本目录',
|
|
919
|
+
trimStateDirHelp: '留空 = 默认的裁剪状态目录。',
|
|
920
|
+
trimProtectedTailLabel: '保护尾部(条数)',
|
|
921
|
+
trimProtectedTailHelp: '最后 N 条消息永不折叠。',
|
|
922
|
+
trimMaxFoldsPerHourLabel: '每小时折叠上限',
|
|
923
|
+
trimMaxFoldsPerHourHelp: '带模型调用的折叠节奏上限(紧急机械折叠不受限)。',
|
|
924
|
+
trimLadderT2TokensLabel: '阶梯 T2 质量(token)',
|
|
925
|
+
trimLadderT2TokensHelp: 'T1 摘要总质量达到该值后蒸馏为一个 T2。',
|
|
926
|
+
trimLadderT2MinBlocksLabel: '阶梯 T2 块数',
|
|
927
|
+
trimLadderT2MinBlocksHelp: '一次 T2 蒸馏至少合并的活跃 T1 块数。',
|
|
928
|
+
trimLadderT3TokensLabel: '阶梯 T3 质量(token)',
|
|
929
|
+
trimLadderT3TokensHelp: 'T2 摘要总质量达到该值后凝聚为一个 T3。',
|
|
930
|
+
trimLadderT3MinBlocksLabel: '阶梯 T3 块数',
|
|
931
|
+
trimLadderT3MinBlocksHelp: '一次 T3 凝聚至少合并的活跃 T2 块数。',
|
|
856
932
|
trimGrowthLabel: '增长阈值(token)',
|
|
857
933
|
trimGrowthHelp: '视图较上次折叠增长超过该 token 数后触发折叠。',
|
|
858
934
|
trimIncrementLabel: '增量阈值(token)',
|
|
@@ -903,7 +979,7 @@ window.__ModuleLoader__.load({
|
|
|
903
979
|
intentClassifierEndpointLabel: '决策端点',
|
|
904
980
|
intentClassifierEndpointHelp: '分类器类型为「决策端点」时直接调用的 /v1/systemone 完整 URL(不经 llm 提供方)',
|
|
905
981
|
intentSystemoneModelLabel: '决策端点模型',
|
|
906
|
-
intentSystemoneModelHelp: '发送到决策端点的 model 参数(如
|
|
982
|
+
intentSystemoneModelHelp: '发送到决策端点的 model 参数(如 d3:4b-mxfp8),自由填写,无需存在于模型供应商列表',
|
|
907
983
|
intentEndpointUnset: '未设置',
|
|
908
984
|
intentCandidatesLabel: '候选模型',
|
|
909
985
|
intentCandidatesHelp:
|
|
@@ -1093,6 +1169,36 @@ window.__ModuleLoader__.load({
|
|
|
1093
1169
|
'When to fold history into summaries at idle: off = never, advisory = model-invoked only, auto = automatic folds.',
|
|
1094
1170
|
trimEnabledLabel: 'Enable auto-trim',
|
|
1095
1171
|
trimEnabledHelp: 'Master switch for the context-trim layer.',
|
|
1172
|
+
trimLadderEnabledLabel: 'Ladder folding (T1/T2/T3)',
|
|
1173
|
+
trimLadderEnabledHelp:
|
|
1174
|
+
'Distill accumulated T1 summaries into T2, and T2 into T3, keeping long sessions flat.',
|
|
1175
|
+
surfaceFoldLabel: 'Ship folds to the session surface',
|
|
1176
|
+
surfaceFoldHelp:
|
|
1177
|
+
'Append host-style replace events so folds reach the wire even on frozen dispatches. Leave on.',
|
|
1178
|
+
trimSideModelLabel: 'Summarizer model',
|
|
1179
|
+
trimSideModelHelp:
|
|
1180
|
+
'Route for fold summaries; defaults to following the session model. Also used by ladder distillations.',
|
|
1181
|
+
trimFollowSession: 'Follow session model',
|
|
1182
|
+
trimFoldFallbackModelLabel: 'Fold fallback model',
|
|
1183
|
+
trimFoldFallbackModelHelp:
|
|
1184
|
+
'When the summary route fails, the fold retries on this model before degrading a pressure fold to a mechanical one. Prefer a model with headroom on cooldowns, risk control, and concurrency limits — avoid sharing the pinned account with the main session. Empty = no fallback leg.',
|
|
1185
|
+
trimFallbackUnset: 'Unset (failed folds go straight to mechanical)',
|
|
1186
|
+
trimStateDirLabel: 'Ledger directory',
|
|
1187
|
+
trimStateDirHelp: 'Empty = the default per-host trim state directory.',
|
|
1188
|
+
trimProtectedTailLabel: 'Protected tail (messages)',
|
|
1189
|
+
trimProtectedTailHelp: 'The last N messages are never folded.',
|
|
1190
|
+
trimMaxFoldsPerHourLabel: 'Max folds per hour',
|
|
1191
|
+
trimMaxFoldsPerHourHelp: 'Cadence cap for side-model folds (emergency mechanical folds exempt).',
|
|
1192
|
+
trimLadderT2TokensLabel: 'Ladder T2 mass (tokens)',
|
|
1193
|
+
trimLadderT2TokensHelp:
|
|
1194
|
+
'Distill T1 summaries into one T2 once their combined mass reaches this.',
|
|
1195
|
+
trimLadderT2MinBlocksLabel: 'Ladder T2 blocks',
|
|
1196
|
+
trimLadderT2MinBlocksHelp: 'Minimum active T1 blocks a T2 distillation merges.',
|
|
1197
|
+
trimLadderT3TokensLabel: 'Ladder T3 mass (tokens)',
|
|
1198
|
+
trimLadderT3TokensHelp:
|
|
1199
|
+
'Condense T2 summaries into one T3 once their combined mass reaches this.',
|
|
1200
|
+
trimLadderT3MinBlocksLabel: 'Ladder T3 blocks',
|
|
1201
|
+
trimLadderT3MinBlocksHelp: 'Minimum active T2 blocks a T3 condensation merges.',
|
|
1096
1202
|
trimGrowthLabel: 'Growth threshold (tokens)',
|
|
1097
1203
|
trimGrowthHelp:
|
|
1098
1204
|
'Fold once the view grows this many tokens since the last fold.',
|
|
@@ -1147,7 +1253,7 @@ window.__ModuleLoader__.load({
|
|
|
1147
1253
|
intentClassifierEndpointLabel: 'Decision endpoint',
|
|
1148
1254
|
intentClassifierEndpointHelp: 'Full /v1/systemone URL called directly when the classifier kind is the decision endpoint (no llm provider)',
|
|
1149
1255
|
intentSystemoneModelLabel: 'Decision endpoint model',
|
|
1150
|
-
intentSystemoneModelHelp: 'Model name sent to the decision endpoint (e.g.
|
|
1256
|
+
intentSystemoneModelHelp: 'Model name sent to the decision endpoint (e.g. d3:4b-mxfp8); free text, no provider entry needed',
|
|
1151
1257
|
intentEndpointUnset: 'Not set',
|
|
1152
1258
|
intentCandidatesLabel: 'Candidates',
|
|
1153
1259
|
intentCandidatesHelp:
|
|
@@ -1336,6 +1442,30 @@ window.__ModuleLoader__.load({
|
|
|
1336
1442
|
'閒置時何時將歷史摺疊為摘要:off = 從不摺疊,advisory = 僅模型主動呼叫,auto = 自動摺疊。',
|
|
1337
1443
|
trimEnabledLabel: '啟用自動裁剪',
|
|
1338
1444
|
trimEnabledHelp: '上下文裁剪層的總開關。',
|
|
1445
|
+
trimLadderEnabledLabel: '階梯摺疊(T1/T2/T3)',
|
|
1446
|
+
trimLadderEnabledHelp: '把累積的 T1 摘要再蒸餾為 T2、T2 再凝聚為 T3,讓長會話檢視保持平穩。',
|
|
1447
|
+
surfaceFoldLabel: '把摺疊寫入會話表面',
|
|
1448
|
+
surfaceFoldHelp: '追加宿主風格的替換事件,讓摺疊在凍結派發下也能到達線上。建議保持開啟。',
|
|
1449
|
+
trimSideModelLabel: '摘要模型',
|
|
1450
|
+
trimSideModelHelp: '摺疊摘要使用的模型路由;預設「跟隨對話模型」。階梯蒸餾同樣使用該路由。',
|
|
1451
|
+
trimFollowSession: '跟隨對話模型',
|
|
1452
|
+
trimFoldFallbackModelLabel: '摺疊異常備援模型',
|
|
1453
|
+
trimFoldFallbackModelHelp: '摘要模型呼叫失敗時改用該模型重試;仍失敗則壓力摺疊退回機械摺疊。盡量選擇沒有冷卻、風控或並行限制的模型,避免與主對話共用同一帳號。留空 = 無備援。',
|
|
1454
|
+
trimFallbackUnset: '未設定(失敗時直接機械摺疊)',
|
|
1455
|
+
trimStateDirLabel: '帳本目錄',
|
|
1456
|
+
trimStateDirHelp: '留空 = 預設的裁剪狀態目錄。',
|
|
1457
|
+
trimProtectedTailLabel: '保護尾部(條數)',
|
|
1458
|
+
trimProtectedTailHelp: '最後 N 訊息永不摺疊。',
|
|
1459
|
+
trimMaxFoldsPerHourLabel: '每小時摺疊上限',
|
|
1460
|
+
trimMaxFoldsPerHourHelp: '帶模型呼叫的摺疊節奏上限(緊急機械摺疊不受限)。',
|
|
1461
|
+
trimLadderT2TokensLabel: '階梯 T2 質量(token)',
|
|
1462
|
+
trimLadderT2TokensHelp: 'T1 摘要總質量達到該值後蒸餾為一個 T2。',
|
|
1463
|
+
trimLadderT2MinBlocksLabel: '階梯 T2 塊數',
|
|
1464
|
+
trimLadderT2MinBlocksHelp: '一次 T2 蒸餾至少合併的活躍 T1 塊數。',
|
|
1465
|
+
trimLadderT3TokensLabel: '階梯 T3 質量(token)',
|
|
1466
|
+
trimLadderT3TokensHelp: 'T2 摘要總質量達到該值後凝聚為一個 T3。',
|
|
1467
|
+
trimLadderT3MinBlocksLabel: '階梯 T3 塊數',
|
|
1468
|
+
trimLadderT3MinBlocksHelp: '一次 T3 凝聚至少合併的活躍 T2 塊數。',
|
|
1339
1469
|
trimGrowthLabel: '增長閾值(token)',
|
|
1340
1470
|
trimGrowthHelp: '檢視較上次摺疊增長超過該 token 數後觸發摺疊。',
|
|
1341
1471
|
trimIncrementLabel: '增量閾值(token)',
|
|
@@ -1383,7 +1513,7 @@ window.__ModuleLoader__.load({
|
|
|
1383
1513
|
intentClassifierEndpointLabel: '決策端點',
|
|
1384
1514
|
intentClassifierEndpointHelp: '分類器類型為「決策端點」時直接呼叫的 /v1/systemone 完整 URL(不經 llm 提供方)',
|
|
1385
1515
|
intentSystemoneModelLabel: '決策端點模型',
|
|
1386
|
-
intentSystemoneModelHelp: '傳送到決策端點的 model 參數(如
|
|
1516
|
+
intentSystemoneModelHelp: '傳送到決策端點的 model 參數(如 d3:4b-mxfp8),自由填寫,無需存在於模型供應商清單',
|
|
1387
1517
|
intentEndpointUnset: '未設定',
|
|
1388
1518
|
intentCandidatesLabel: '候選模型',
|
|
1389
1519
|
intentCandidatesHelp:
|
|
@@ -1607,7 +1737,7 @@ window.__ModuleLoader__.load({
|
|
|
1607
1737
|
intentClassifierEndpointLabel: '判定エンドポイント',
|
|
1608
1738
|
intentClassifierEndpointHelp: '分類器の種類が判定エンドポイントのとき直接呼び出す /v1/systemone の完全 URL(LLM プロバイダ不要)',
|
|
1609
1739
|
intentSystemoneModelLabel: '決定エンドポイントのモデル',
|
|
1610
|
-
intentSystemoneModelHelp: '決定エンドポイントへ送る model パラメータ(例:
|
|
1740
|
+
intentSystemoneModelHelp: '決定エンドポイントへ送る model パラメータ(例: d3:4b-mxfp8)。自由入力で、プロバイダー一覧への登録は不要',
|
|
1611
1741
|
intentEndpointUnset: '未設定',
|
|
1612
1742
|
intentCandidatesLabel: '候補モデル',
|
|
1613
1743
|
intentCandidatesHelp:
|
|
@@ -1833,7 +1963,7 @@ window.__ModuleLoader__.load({
|
|
|
1833
1963
|
intentClassifierEndpointLabel: '판정 엔드포인트',
|
|
1834
1964
|
intentClassifierEndpointHelp: '분류기 종류가 판정 엔드포인트일 때 직접 호출하는 /v1/systemone 전체 URL(LLM 공급자 불필요)',
|
|
1835
1965
|
intentSystemoneModelLabel: '결정 엔드포인트 모델',
|
|
1836
|
-
intentSystemoneModelHelp: '결정 엔드포인트로 보내는 model 매개변수(예:
|
|
1966
|
+
intentSystemoneModelHelp: '결정 엔드포인트로 보내는 model 매개변수(예: d3:4b-mxfp8). 자유 입력이며 공급자 목록에 없어도 됨',
|
|
1837
1967
|
intentEndpointUnset: '미설정',
|
|
1838
1968
|
intentCandidatesLabel: '후보 모델',
|
|
1839
1969
|
intentCandidatesHelp:
|
|
@@ -2060,7 +2190,7 @@ window.__ModuleLoader__.load({
|
|
|
2060
2190
|
intentClassifierEndpointLabel: 'Entscheidungs-Endpunkt',
|
|
2061
2191
|
intentClassifierEndpointHelp: 'Vollständige /v1/systemone-URL, die direkt aufgerufen wird, wenn der Klassifikator-Typ der Entscheidungs-Endpunkt ist (ohne LLM-Provider)',
|
|
2062
2192
|
intentSystemoneModelLabel: 'Modell des Entscheidungsendpunkts',
|
|
2063
|
-
intentSystemoneModelHelp: 'Modelname, der an den Entscheidungsendpunkt gesendet wird (z. B.
|
|
2193
|
+
intentSystemoneModelHelp: 'Modelname, der an den Entscheidungsendpunkt gesendet wird (z. B. d3:4b-mxfp8); freier Text, kein Anbieter-Eintrag nötig',
|
|
2064
2194
|
intentEndpointUnset: 'Nicht festgelegt',
|
|
2065
2195
|
intentCandidatesLabel: 'Kandidaten',
|
|
2066
2196
|
intentCandidatesHelp:
|
|
@@ -2290,7 +2420,7 @@ window.__ModuleLoader__.load({
|
|
|
2290
2420
|
intentClassifierEndpointLabel: 'Endpoint de decisión',
|
|
2291
2421
|
intentClassifierEndpointHelp: 'URL /v1/systemone completa que se llama directamente cuando el tipo de clasificador es el endpoint de decisión (sin proveedor LLM)',
|
|
2292
2422
|
intentSystemoneModelLabel: 'Modelo del endpoint de decisión',
|
|
2293
|
-
intentSystemoneModelHelp: 'Parámetro model que se envía al endpoint de decisión (p. ej.
|
|
2423
|
+
intentSystemoneModelHelp: 'Parámetro model que se envía al endpoint de decisión (p. ej. d3:4b-mxfp8); texto libre, no necesita estar en la lista de proveedores',
|
|
2294
2424
|
intentEndpointUnset: 'Sin establecer',
|
|
2295
2425
|
intentCandidatesLabel: 'Candidatos',
|
|
2296
2426
|
intentCandidatesHelp:
|
|
@@ -2520,7 +2650,7 @@ window.__ModuleLoader__.load({
|
|
|
2520
2650
|
intentClassifierEndpointLabel: 'Endpoint de décision',
|
|
2521
2651
|
intentClassifierEndpointHelp: 'URL /v1/systemone complète appelée directement quand le type de classificateur est l\'endpoint de décision (sans fournisseur LLM)',
|
|
2522
2652
|
intentSystemoneModelLabel: 'Modèle du point de décision',
|
|
2523
|
-
intentSystemoneModelHelp: 'Paramètre model envoyé au point de décision (p. ex.
|
|
2653
|
+
intentSystemoneModelHelp: 'Paramètre model envoyé au point de décision (p. ex. d3:4b-mxfp8) ; texte libre, inutile qu\'il figure dans la liste des fournisseurs',
|
|
2524
2654
|
intentEndpointUnset: 'Non défini',
|
|
2525
2655
|
intentCandidatesLabel: 'Candidats',
|
|
2526
2656
|
intentCandidatesHelp:
|
|
@@ -2750,7 +2880,7 @@ window.__ModuleLoader__.load({
|
|
|
2750
2880
|
intentClassifierEndpointLabel: 'Endpoint di decisione',
|
|
2751
2881
|
intentClassifierEndpointHelp: 'URL /v1/systemone completa chiamata direttamente quando il tipo di classificatore è l\'endpoint di decisione (senza provider LLM)',
|
|
2752
2882
|
intentSystemoneModelLabel: 'Modello dell\'endpoint di decisione',
|
|
2753
|
-
intentSystemoneModelHelp: 'Parametro model inviato all\'endpoint di decisione (es.
|
|
2883
|
+
intentSystemoneModelHelp: 'Parametro model inviato all\'endpoint di decisione (es. d3:4b-mxfp8); testo libero, non deve stare nell\'elenco dei provider',
|
|
2754
2884
|
intentEndpointUnset: 'Non impostato',
|
|
2755
2885
|
intentCandidatesLabel: 'Candidati',
|
|
2756
2886
|
intentCandidatesHelp:
|
|
@@ -2980,7 +3110,7 @@ window.__ModuleLoader__.load({
|
|
|
2980
3110
|
intentClassifierEndpointLabel: 'Endpoint de decisão',
|
|
2981
3111
|
intentClassifierEndpointHelp: 'URL /v1/systemone completa chamada diretamente quando o tipo de classificador é o endpoint de decisão (sem provedor LLM)',
|
|
2982
3112
|
intentSystemoneModelLabel: 'Modelo do endpoint de decisão',
|
|
2983
|
-
intentSystemoneModelHelp: 'Parâmetro model enviado ao endpoint de decisão (ex.:
|
|
3113
|
+
intentSystemoneModelHelp: 'Parâmetro model enviado ao endpoint de decisão (ex.: d3:4b-mxfp8); texto livre, não precisa estar na lista de provedores',
|
|
2984
3114
|
intentEndpointUnset: 'Não definido',
|
|
2985
3115
|
intentCandidatesLabel: 'Candidatos',
|
|
2986
3116
|
intentCandidatesHelp:
|
|
@@ -3209,7 +3339,7 @@ window.__ModuleLoader__.load({
|
|
|
3209
3339
|
intentClassifierEndpointLabel: 'Endpoint решений',
|
|
3210
3340
|
intentClassifierEndpointHelp: 'Полный URL /v1/systemone, вызываемый напрямую, когда тип классификатора — endpoint решений (без LLM-провайдера)',
|
|
3211
3341
|
intentSystemoneModelLabel: 'Модель endpoint решений',
|
|
3212
|
-
intentSystemoneModelHelp: 'Параметр model, отправляемый на endpoint решений (напр.
|
|
3342
|
+
intentSystemoneModelHelp: 'Параметр model, отправляемый на endpoint решений (напр. d3:4b-mxfp8); свободный текст, запись в списке провайдеров не нужна',
|
|
3213
3343
|
intentEndpointUnset: 'Не задано',
|
|
3214
3344
|
intentCandidatesLabel: 'Кандидаты',
|
|
3215
3345
|
intentCandidatesHelp:
|
|
@@ -5207,6 +5337,17 @@ window.__ModuleLoader__.load({
|
|
|
5207
5337
|
wmSubagentCap: values.wmSubagentCap,
|
|
5208
5338
|
trimMode: values.trimMode,
|
|
5209
5339
|
trimEnabled: values.trimEnabled,
|
|
5340
|
+
trimLadderEnabled: values.trimLadderEnabled,
|
|
5341
|
+
surfaceFold: values.surfaceFold,
|
|
5342
|
+
trimSideModel: {
|
|
5343
|
+
provider: values.trimSideModel.provider,
|
|
5344
|
+
model: values.trimSideModel.model,
|
|
5345
|
+
},
|
|
5346
|
+
trimFoldFallbackModel: {
|
|
5347
|
+
provider: values.trimFoldFallbackModel.provider,
|
|
5348
|
+
model: values.trimFoldFallbackModel.model,
|
|
5349
|
+
},
|
|
5350
|
+
trimStateDir: values.trimStateDir,
|
|
5210
5351
|
...Object.fromEntries(
|
|
5211
5352
|
TRIM_NUMBER_FIELDS.map(({ field }) => [field, values[field]]),
|
|
5212
5353
|
),
|
|
@@ -5669,6 +5810,78 @@ window.__ModuleLoader__.load({
|
|
|
5669
5810
|
),
|
|
5670
5811
|
);
|
|
5671
5812
|
};
|
|
5813
|
+
/** Trim route rows reuse the intent route picker machinery — the
|
|
5814
|
+
* provider/model option lists are session-wide, only the ids and
|
|
5815
|
+
* bound field differ. The summarizer row leads with a "follow
|
|
5816
|
+
* session model" sentinel standing for the empty route; the
|
|
5817
|
+
* fallback row keeps a plain unset option (empty = no fallback). */
|
|
5818
|
+
const TRIM_ROUTE_FOLLOW = '\0follow';
|
|
5819
|
+
const trimProviderOptions = (followMode, current) => [
|
|
5820
|
+
...(followMode
|
|
5821
|
+
? [h('option', { key: 'follow', value: TRIM_ROUTE_FOLLOW }, t('trimFollowSession'))]
|
|
5822
|
+
: [h('option', { value: '' }, t('intentRouteUnset'))]),
|
|
5823
|
+
...intentProviderOptions(current).filter(
|
|
5824
|
+
(opt) => opt && opt.props && opt.props.value !== '',
|
|
5825
|
+
),
|
|
5826
|
+
];
|
|
5827
|
+
const trimModelOptions = (followMode, route, current) => [
|
|
5828
|
+
...(followMode
|
|
5829
|
+
? [h('option', { key: 'follow', value: TRIM_ROUTE_FOLLOW }, t('trimFollowSession'))]
|
|
5830
|
+
: [h('option', { value: '' }, t('intentRouteUnset'))]),
|
|
5831
|
+
...intentModelOptions(route.provider, current).filter(
|
|
5832
|
+
(opt) => opt && opt.props && opt.props.value !== '',
|
|
5833
|
+
),
|
|
5834
|
+
];
|
|
5835
|
+
const trimRouteControl = (field, label, followMode) => {
|
|
5836
|
+
const route = values[field];
|
|
5837
|
+
return h(
|
|
5838
|
+
'div',
|
|
5839
|
+
{ style: { display: 'flex', gap: '6px', minWidth: 0 } },
|
|
5840
|
+
h('select', {
|
|
5841
|
+
...selectProps(
|
|
5842
|
+
`${trimId}-${field}-provider`,
|
|
5843
|
+
followMode && route.provider === ''
|
|
5844
|
+
? TRIM_ROUTE_FOLLOW
|
|
5845
|
+
: route.provider,
|
|
5846
|
+
(next) => {
|
|
5847
|
+
if (followMode && next === TRIM_ROUTE_FOLLOW) {
|
|
5848
|
+
edit(field, { provider: '', model: '' });
|
|
5849
|
+
return;
|
|
5850
|
+
}
|
|
5851
|
+
if (!followMode && next === '') {
|
|
5852
|
+
edit(field, { provider: '', model: '' });
|
|
5853
|
+
return;
|
|
5854
|
+
}
|
|
5855
|
+
const kept = intentModelsFor(next).some(
|
|
5856
|
+
(meta) => meta.model === route.model,
|
|
5857
|
+
);
|
|
5858
|
+
edit(field, {
|
|
5859
|
+
provider: next,
|
|
5860
|
+
model: kept ? route.model : '',
|
|
5861
|
+
});
|
|
5862
|
+
},
|
|
5863
|
+
),
|
|
5864
|
+
'aria-label': `${label} · provider`,
|
|
5865
|
+
}, ...trimProviderOptions(followMode, route.provider)),
|
|
5866
|
+
h('select', {
|
|
5867
|
+
...selectProps(
|
|
5868
|
+
`${trimId}-${field}-model`,
|
|
5869
|
+
followMode && route.model === ''
|
|
5870
|
+
? TRIM_ROUTE_FOLLOW
|
|
5871
|
+
: route.model,
|
|
5872
|
+
(next) => {
|
|
5873
|
+
if (followMode && next === TRIM_ROUTE_FOLLOW) {
|
|
5874
|
+
edit(field, { ...route, model: '' });
|
|
5875
|
+
return;
|
|
5876
|
+
}
|
|
5877
|
+
edit(field, { ...route, model: next });
|
|
5878
|
+
},
|
|
5879
|
+
),
|
|
5880
|
+
disabled: !editable || route.provider === '',
|
|
5881
|
+
'aria-label': `${label} · model`,
|
|
5882
|
+
}, ...trimModelOptions(followMode, route, route.model)),
|
|
5883
|
+
);
|
|
5884
|
+
};
|
|
5672
5885
|
/** Reasoning-effort select for one intent route: the model's
|
|
5673
5886
|
* wire efforts when the catalog reports them, the EFFORTS
|
|
5674
5887
|
* fallback otherwise; '' = adapter default. A stored value
|
|
@@ -6186,6 +6399,33 @@ window.__ModuleLoader__.load({
|
|
|
6186
6399
|
}),
|
|
6187
6400
|
lines: [],
|
|
6188
6401
|
}),
|
|
6402
|
+
h(SettingsRow, {
|
|
6403
|
+
key: 'intentClassifierKind',
|
|
6404
|
+
id: `${intentId}-kind`,
|
|
6405
|
+
label: t('intentClassifierKindLabel'),
|
|
6406
|
+
help: t('intentClassifierKindHelp'),
|
|
6407
|
+
control: h(
|
|
6408
|
+
'select',
|
|
6409
|
+
selectProps(
|
|
6410
|
+
`${intentId}-kind`,
|
|
6411
|
+
values.intentClassifierKind,
|
|
6412
|
+
(kind) => {
|
|
6413
|
+
if (INTENT_KINDS.includes(kind))
|
|
6414
|
+
edit('intentClassifierKind', kind);
|
|
6415
|
+
},
|
|
6416
|
+
),
|
|
6417
|
+
...INTENT_KINDS.map((kind) =>
|
|
6418
|
+
h(
|
|
6419
|
+
'option',
|
|
6420
|
+
{ key: kind, value: kind },
|
|
6421
|
+
t(
|
|
6422
|
+
`intentClassifierKind${kind[0].toUpperCase()}${kind.slice(1)}`,
|
|
6423
|
+
),
|
|
6424
|
+
),
|
|
6425
|
+
),
|
|
6426
|
+
),
|
|
6427
|
+
lines: [],
|
|
6428
|
+
}),
|
|
6189
6429
|
h(SettingsRow, {
|
|
6190
6430
|
key: 'intentClassifierRoute',
|
|
6191
6431
|
hidden: values.intentClassifierKind === 'systemone',
|
|
@@ -6231,33 +6471,6 @@ window.__ModuleLoader__.load({
|
|
|
6231
6471
|
),
|
|
6232
6472
|
lines: [],
|
|
6233
6473
|
}),
|
|
6234
|
-
h(SettingsRow, {
|
|
6235
|
-
key: 'intentClassifierKind',
|
|
6236
|
-
id: `${intentId}-kind`,
|
|
6237
|
-
label: t('intentClassifierKindLabel'),
|
|
6238
|
-
help: t('intentClassifierKindHelp'),
|
|
6239
|
-
control: h(
|
|
6240
|
-
'select',
|
|
6241
|
-
selectProps(
|
|
6242
|
-
`${intentId}-kind`,
|
|
6243
|
-
values.intentClassifierKind,
|
|
6244
|
-
(kind) => {
|
|
6245
|
-
if (INTENT_KINDS.includes(kind))
|
|
6246
|
-
edit('intentClassifierKind', kind);
|
|
6247
|
-
},
|
|
6248
|
-
),
|
|
6249
|
-
...INTENT_KINDS.map((kind) =>
|
|
6250
|
-
h(
|
|
6251
|
-
'option',
|
|
6252
|
-
{ key: kind, value: kind },
|
|
6253
|
-
t(
|
|
6254
|
-
`intentClassifierKind${kind[0].toUpperCase()}${kind.slice(1)}`,
|
|
6255
|
-
),
|
|
6256
|
-
),
|
|
6257
|
-
),
|
|
6258
|
-
),
|
|
6259
|
-
lines: [],
|
|
6260
|
-
}),
|
|
6261
6474
|
h(SettingsRow, {
|
|
6262
6475
|
key: 'intentClassifierEndpoint',
|
|
6263
6476
|
hidden: values.intentClassifierKind !== 'systemone',
|
|
@@ -6295,7 +6508,7 @@ window.__ModuleLoader__.load({
|
|
|
6295
6508
|
control: h('input', {
|
|
6296
6509
|
type: 'text',
|
|
6297
6510
|
value: values.intentClassifierSystemoneModel,
|
|
6298
|
-
placeholder: '
|
|
6511
|
+
placeholder: 'd3:4b-mxfp8',
|
|
6299
6512
|
onChange: (event) =>
|
|
6300
6513
|
edit('intentClassifierSystemoneModel', event.target.value),
|
|
6301
6514
|
disabled: !editable,
|
|
@@ -6651,6 +6864,76 @@ window.__ModuleLoader__.load({
|
|
|
6651
6864
|
}),
|
|
6652
6865
|
lines: [],
|
|
6653
6866
|
}),
|
|
6867
|
+
h(SettingsRow, {
|
|
6868
|
+
key: 'trimLadderEnabled',
|
|
6869
|
+
id: `${trimId}-ladder`,
|
|
6870
|
+
label: t('trimLadderEnabledLabel'),
|
|
6871
|
+
help: t('trimLadderEnabledHelp'),
|
|
6872
|
+
control: h('input', {
|
|
6873
|
+
type: 'checkbox',
|
|
6874
|
+
id: `${trimId}-ladder`,
|
|
6875
|
+
checked: values.trimLadderEnabled,
|
|
6876
|
+
onChange: () => {
|
|
6877
|
+
edit('trimLadderEnabled', !values.trimLadderEnabled);
|
|
6878
|
+
},
|
|
6879
|
+
disabled: !editable,
|
|
6880
|
+
style: STYLE.checkbox,
|
|
6881
|
+
}),
|
|
6882
|
+
lines: [],
|
|
6883
|
+
}),
|
|
6884
|
+
h(SettingsRow, {
|
|
6885
|
+
key: 'surfaceFold',
|
|
6886
|
+
id: `${trimId}-surface`,
|
|
6887
|
+
label: t('surfaceFoldLabel'),
|
|
6888
|
+
help: t('surfaceFoldHelp'),
|
|
6889
|
+
control: h('input', {
|
|
6890
|
+
type: 'checkbox',
|
|
6891
|
+
id: `${trimId}-surface`,
|
|
6892
|
+
checked: values.surfaceFold,
|
|
6893
|
+
onChange: () => {
|
|
6894
|
+
edit('surfaceFold', !values.surfaceFold);
|
|
6895
|
+
},
|
|
6896
|
+
disabled: !editable,
|
|
6897
|
+
style: STYLE.checkbox,
|
|
6898
|
+
}),
|
|
6899
|
+
lines: [],
|
|
6900
|
+
}),
|
|
6901
|
+
h(SettingsRow, {
|
|
6902
|
+
key: 'trimSideModel',
|
|
6903
|
+
id: `${trimId}-trimSideModel`,
|
|
6904
|
+
label: t('trimSideModelLabel'),
|
|
6905
|
+
help: t('trimSideModelHelp'),
|
|
6906
|
+
control: trimRouteControl('trimSideModel', t('trimSideModelLabel'), true),
|
|
6907
|
+
lines:
|
|
6908
|
+
values.trimSideModel.provider === '' || values.trimSideModel.model === ''
|
|
6909
|
+
? [{ text: t('trimFollowSession'), invalid: false }]
|
|
6910
|
+
: [
|
|
6911
|
+
{
|
|
6912
|
+
text: t('currentValue', {
|
|
6913
|
+
value: `${values.trimSideModel.provider}/${values.trimSideModel.model}`,
|
|
6914
|
+
}),
|
|
6915
|
+
invalid: false,
|
|
6916
|
+
},
|
|
6917
|
+
],
|
|
6918
|
+
}),
|
|
6919
|
+
h(SettingsRow, {
|
|
6920
|
+
key: 'trimFoldFallbackModel',
|
|
6921
|
+
id: `${trimId}-trimFoldFallbackModel`,
|
|
6922
|
+
label: t('trimFoldFallbackModelLabel'),
|
|
6923
|
+
help: t('trimFoldFallbackModelHelp'),
|
|
6924
|
+
control: trimRouteControl('trimFoldFallbackModel', t('trimFoldFallbackModelLabel'), false),
|
|
6925
|
+
lines:
|
|
6926
|
+
values.trimFoldFallbackModel.provider === '' || values.trimFoldFallbackModel.model === ''
|
|
6927
|
+
? [{ text: t('trimFallbackUnset'), invalid: false }]
|
|
6928
|
+
: [
|
|
6929
|
+
{
|
|
6930
|
+
text: t('currentValue', {
|
|
6931
|
+
value: `${values.trimFoldFallbackModel.provider}/${values.trimFoldFallbackModel.model}`,
|
|
6932
|
+
}),
|
|
6933
|
+
invalid: false,
|
|
6934
|
+
},
|
|
6935
|
+
],
|
|
6936
|
+
}),
|
|
6654
6937
|
...TRIM_NUMBER_FIELDS.map((spec) =>
|
|
6655
6938
|
h(SettingsRow, {
|
|
6656
6939
|
key: spec.field,
|