dsh-switchman 1.11.6 → 1.11.7
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 +36 -31
- package/README.es.md +36 -31
- package/README.fr.md +36 -31
- package/README.it.md +36 -31
- package/README.ja.md +36 -31
- package/README.ko.md +36 -31
- package/README.md +37 -32
- package/README.pt.md +36 -31
- package/README.ru.md +36 -31
- package/README.zh-TW.md +36 -31
- package/README.zh.md +36 -31
- package/client.js +355 -26
- package/cordis.patch.yml +10 -10
- package/host/config.js +64 -33
- package/host/context-trim/index.js +539 -60
- package/host/context-trim/state.js +3 -2
- package/host/context-trim/surface.js +5 -1
- package/host/context-watch.js +12 -7
- package/host/intent.js +41 -4
- package/host/lang.js +4 -2
- package/host/ptc-bindings.js +510 -0
- package/host/ptc-guard.js +9 -1
- package/host/routes.js +110 -34
- package/host/teams.js +61 -15
- package/host/vision.js +24 -3
- package/index.js +5 -2
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -190,15 +190,16 @@ window.__ModuleLoader__.load({
|
|
|
190
190
|
{ field: 'poolReview', manualField: 'poolReviewManual', effortsField: 'poolReviewEfforts', lane: 'review' },
|
|
191
191
|
];
|
|
192
192
|
|
|
193
|
-
/** Numeric watermark fields: settings field, schema
|
|
194
|
-
* Host-side default (also the fallback for malformed stored values).
|
|
193
|
+
/** Numeric watermark fields: settings field, schema bounds, and the
|
|
194
|
+
* Host-side default (also the fallback for malformed stored values).
|
|
195
|
+
* Bounds MUST mirror host/routes.js WM_BOUNDED_NUMBER_FIELDS. */
|
|
195
196
|
const WM_NUMBER_FIELDS = [
|
|
196
|
-
{ field: 'wmSoftTokens', min: 1000, def: 80000 },
|
|
197
|
-
{ field: 'wmHardTokens', min: 2000, def:
|
|
198
|
-
{ field: 'wmForceTokens', min: 3000, def:
|
|
199
|
-
{ field: 'wmReadBudgetTokens', min: 200, def:
|
|
200
|
-
{ field: 'wmSubagentForceTokens', min: 0, def: 0 },
|
|
201
|
-
{ field: 'wmSubagentWindowRatio', min: 0.1, def: 0.75 },
|
|
197
|
+
{ field: 'wmSoftTokens', min: 1000, max: 10000000, def: 80000 },
|
|
198
|
+
{ field: 'wmHardTokens', min: 2000, max: 10000000, def: 100000 },
|
|
199
|
+
{ field: 'wmForceTokens', min: 3000, max: 10000000, def: 200000 },
|
|
200
|
+
{ field: 'wmReadBudgetTokens', min: 200, max: 10000000, def: 3500 },
|
|
201
|
+
{ field: 'wmSubagentForceTokens', min: 0, max: 10000000, def: 0 },
|
|
202
|
+
{ field: 'wmSubagentWindowRatio', min: 0.1, max: 1, def: 0.75 },
|
|
202
203
|
];
|
|
203
204
|
|
|
204
205
|
/** The three thresholds that must keep a strict ascending order. */
|
|
@@ -234,7 +235,7 @@ window.__ModuleLoader__.load({
|
|
|
234
235
|
{ field: 'intentTimeoutMs', min: 200, max: Infinity, def: 60000 },
|
|
235
236
|
{ field: 'intentHistoryMessages', min: 1, max: 20, def: 6 },
|
|
236
237
|
{ field: 'intentHistoryMaxChars', min: 200, max: 20000, def: 2400 },
|
|
237
|
-
{ field: 'intentContextWindow', min: 1024, max: Infinity, def:
|
|
238
|
+
{ field: 'intentContextWindow', min: 1024, max: Infinity, def: 250000 },
|
|
238
239
|
];
|
|
239
240
|
|
|
240
241
|
/** Dictionary keys per numeric intent row. */
|
|
@@ -276,13 +277,14 @@ window.__ModuleLoader__.load({
|
|
|
276
277
|
* write (and vice versa). */
|
|
277
278
|
const TRIM_NUMBER_FIELDS = [
|
|
278
279
|
{ field: 'trimGrowthTokens', min: 1000, def: 22500 },
|
|
279
|
-
{ field: 'trimIncrementTokens', min: 1000, def:
|
|
280
|
-
{ field: 'trimPressurePercent', min: 5, max: 100, def:
|
|
281
|
-
{ field: 'trimEmergencyPercent', min: 5, max: 100, def:
|
|
282
|
-
{ field: 'trimAdvisoryPercent', min: 5, max: 100, def:
|
|
283
|
-
{ field: 'trimAdvisoryCriticalPercent', min: 5, max: 100, def:
|
|
280
|
+
{ field: 'trimIncrementTokens', min: 1000, def: 45000 },
|
|
281
|
+
{ field: 'trimPressurePercent', min: 5, max: 100, def: 45 },
|
|
282
|
+
{ field: 'trimEmergencyPercent', min: 5, max: 100, def: 90 },
|
|
283
|
+
{ field: 'trimAdvisoryPercent', min: 5, max: 100, def: 50 },
|
|
284
|
+
{ field: 'trimAdvisoryCriticalPercent', min: 5, max: 100, def: 80 },
|
|
285
|
+
{ field: 'trimAdvisoryRepeatMs', min: 5000, max: 3600000, def: 120000 },
|
|
284
286
|
{ field: 'trimWindowTokens', min: 0, def: 0 },
|
|
285
|
-
{ field: 'trimProtectedTail', min: 0, max: 100, def:
|
|
287
|
+
{ field: 'trimProtectedTail', min: 0, max: 100, def: 6 },
|
|
286
288
|
{ field: 'trimMaxFoldsPerHour', min: 1, max: 60, def: 30 },
|
|
287
289
|
{ field: 'trimLadderT2Tokens', min: 1000, def: 8000 },
|
|
288
290
|
{ field: 'trimLadderT2MinBlocks', min: 2, max: 200, def: 3 },
|
|
@@ -313,6 +315,10 @@ window.__ModuleLoader__.load({
|
|
|
313
315
|
label: 'trimAdvisoryCriticalLabel',
|
|
314
316
|
help: 'trimAdvisoryCriticalHelp',
|
|
315
317
|
},
|
|
318
|
+
trimAdvisoryRepeatMs: {
|
|
319
|
+
label: 'trimAdvisoryRepeatLabel',
|
|
320
|
+
help: 'trimAdvisoryRepeatHelp',
|
|
321
|
+
},
|
|
316
322
|
trimWindowTokens: {
|
|
317
323
|
label: 'trimWindowLabel',
|
|
318
324
|
help: 'trimWindowHelp',
|
|
@@ -361,6 +367,7 @@ window.__ModuleLoader__.load({
|
|
|
361
367
|
'trimEnabled',
|
|
362
368
|
'trimLadderEnabled',
|
|
363
369
|
'trimProtectTaskIntent',
|
|
370
|
+
'trimCriticalRelief',
|
|
364
371
|
'surfaceFold',
|
|
365
372
|
'trimSideModel',
|
|
366
373
|
'trimFoldFallbackModel',
|
|
@@ -541,6 +548,8 @@ window.__ModuleLoader__.load({
|
|
|
541
548
|
trimEnabled: bool('trimEnabled', true),
|
|
542
549
|
trimLadderEnabled: bool('trimLadderEnabled', true),
|
|
543
550
|
trimProtectTaskIntent: bool('trimProtectTaskIntent', true),
|
|
551
|
+
trimCriticalRelief: bool('trimCriticalRelief', true),
|
|
552
|
+
trimVerboseLog: bool('trimVerboseLog', false),
|
|
544
553
|
surfaceFold: bool('surfaceFold', true),
|
|
545
554
|
trimSideModel:
|
|
546
555
|
sanitizeRoute(value?.trimSideModel, true) ??
|
|
@@ -630,6 +639,8 @@ window.__ModuleLoader__.load({
|
|
|
630
639
|
trimEnabled: values.trimEnabled,
|
|
631
640
|
trimLadderEnabled: values.trimLadderEnabled,
|
|
632
641
|
trimProtectTaskIntent: values.trimProtectTaskIntent,
|
|
642
|
+
trimCriticalRelief: values.trimCriticalRelief,
|
|
643
|
+
trimVerboseLog: values.trimVerboseLog,
|
|
633
644
|
surfaceFold: values.surfaceFold,
|
|
634
645
|
trimSideModel: `${routeKey(values.trimSideModel)}\0${values.trimSideModel.effort ?? ''}`,
|
|
635
646
|
trimFoldFallbackModel: `${routeKey(values.trimFoldFallbackModel)}\0${values.trimFoldFallbackModel.effort ?? ''}`,
|
|
@@ -903,6 +914,7 @@ window.__ModuleLoader__.load({
|
|
|
903
914
|
wmReadBudgetLabel: '单次读取预算',
|
|
904
915
|
wmReadBudgetHelp: '每次读取的 token 预算;每轮上限为其两倍。',
|
|
905
916
|
wmNumberInvalid: '请输入不小于 {min} 的整数。',
|
|
917
|
+
wmNumberInvalidMax: '请输入 {min} 到 {max} 之间的数。',
|
|
906
918
|
wmOrderInvalid: '三档水位需严格递增:soft < hard < force。',
|
|
907
919
|
wmDenyModeLabel: '硬档行为',
|
|
908
920
|
wmDenyModeCap: '限流放行',
|
|
@@ -928,6 +940,16 @@ window.__ModuleLoader__.load({
|
|
|
928
940
|
trimModeLabel: '自动裁剪模式',
|
|
929
941
|
trimModeHelp:
|
|
930
942
|
'空闲时何时把历史折叠为摘要:off = 从不折叠,advisory = 模型自主折叠(压力达线时引擎在系统提示注入一次性提醒),auto = 自动折叠。',
|
|
943
|
+
trimCriticalReliefLabel: '临界救援折叠',
|
|
944
|
+
trimCriticalReliefHelp: '开启后(默认),advisory 模式压力到达临界线(trimAdvisoryCriticalPercent)时引擎自动执行一次机械折叠(90 秒冷却),不再只依赖提示。',
|
|
945
|
+
trimVerboseLogLabel: '调试模式(详细日志)',
|
|
946
|
+
trimVerboseLogHelp: '默认关闭。开启后引擎的每个执行步骤、闸门判定与决策路径都会写入 decisions.log(debug 行),便于问题追溯;关闭时只记录关键决策行。无论开关与否,异常始终记录完整细节。',
|
|
947
|
+
trimDockLabel: '折叠 {pressure}%(线 {line}%)',
|
|
948
|
+
trimDockTipDomain: '折叠引擎口径:最近一次实付 prompt(max(view, wire))÷ 有效窗口(含上限)——不是输入框旁上下文面板的预测口径,两者本就不同、不应收敛。',
|
|
949
|
+
trimDockTipMass: '实付 {mass} / 窗口 {window} tokens',
|
|
950
|
+
trimDockTipMode: '模式:{mode}(advisory=模型自行折叠;auto=引擎自动折叠)',
|
|
951
|
+
trimDockTipReady: '临界纾缓就绪:达到 80% 线即由引擎机械折叠一次',
|
|
952
|
+
trimDockTipCooldown: '临界纾缓冷却中,剩 {seconds}s',
|
|
931
953
|
trimEnabledLabel: '启用自动裁剪',
|
|
932
954
|
trimEnabledHelp: '上下文裁剪层的总开关。',
|
|
933
955
|
trimLadderEnabledLabel: '阶梯折叠(T1/T2/T3)',
|
|
@@ -969,6 +991,8 @@ window.__ModuleLoader__.load({
|
|
|
969
991
|
trimAdvisoryHelp: '仅 advisory 模式:压力达到窗口的这一百分比时,提醒模型自行折叠。',
|
|
970
992
|
trimAdvisoryCriticalLabel: 'Advisory 升级线(%)',
|
|
971
993
|
trimAdvisoryCriticalHelp: '仅 advisory 模式:达到这一百分比时,提醒升级为本轮必须折叠的指令。',
|
|
994
|
+
trimAdvisoryRepeatLabel: 'Advisory 重贴间隔(ms)',
|
|
995
|
+
trimAdvisoryRepeatHelp: '仅 advisory 模式:提醒贴在会话尾部后,每隔该毫秒数在新尾部重贴一次(临界档取其一半,下限 45 秒);默认 120000。',
|
|
972
996
|
trimModeOff: '关闭',
|
|
973
997
|
trimWindowLabel: '窗口上限(token)',
|
|
974
998
|
trimWindowHelp: '压力与紧急档按 min(模型窗口, 上限) 计算;0 = 跟随强制水位(wmForceTokens)。',
|
|
@@ -1178,6 +1202,7 @@ window.__ModuleLoader__.load({
|
|
|
1178
1202
|
wmReadBudgetLabel: 'Read budget',
|
|
1179
1203
|
wmReadBudgetHelp: 'Token budget per read; each round caps at twice this.',
|
|
1180
1204
|
wmNumberInvalid: 'Enter a whole number of {min} or more.',
|
|
1205
|
+
wmNumberInvalidMax: 'Enter a number between {min} and {max}.',
|
|
1181
1206
|
wmOrderInvalid: 'The three tiers must strictly ascend: soft < hard < force.',
|
|
1182
1207
|
wmDenyModeLabel: 'Hard-tier behavior',
|
|
1183
1208
|
wmDenyModeCap: 'Cap and warn',
|
|
@@ -1203,6 +1228,16 @@ window.__ModuleLoader__.load({
|
|
|
1203
1228
|
trimModeLabel: 'Trim mode',
|
|
1204
1229
|
trimModeHelp:
|
|
1205
1230
|
'When to fold history into summaries at idle: off = never, advisory = the model folds itself (the engine appends a one-off nudge line at the pressure line), auto = automatic folds.',
|
|
1231
|
+
trimCriticalReliefLabel: 'Critical relief fold',
|
|
1232
|
+
trimCriticalReliefHelp: 'When on (default), advisory mode performs one mechanical fold itself at the critical line (trimAdvisoryCriticalPercent, 90 s cooldown) instead of only nudging.',
|
|
1233
|
+
trimVerboseLogLabel: 'Debug mode (verbose log)',
|
|
1234
|
+
trimVerboseLogHelp: 'Off by default. When on, every engine step, gate evaluation and decision path is written to decisions.log (debug rows) for issue tracing; when off, only the key decision rows are kept. Exceptions always log full detail regardless of this switch.',
|
|
1235
|
+
trimDockLabel: 'fold {pressure}% (line {line}%)',
|
|
1236
|
+
trimDockTipDomain: 'Fold-engine domain: last PAID prompt (max of view/wire) over the effective window (cap included) — not the composer context meter projection; the two answer different questions and are not meant to converge.',
|
|
1237
|
+
trimDockTipMass: 'paid {mass} / window {window} tokens',
|
|
1238
|
+
trimDockTipMode: 'mode: {mode} (advisory = the model folds itself; auto = the engine folds)',
|
|
1239
|
+
trimDockTipReady: 'critical relief ready: one mechanical engine fold fires at the critical line',
|
|
1240
|
+
trimDockTipCooldown: 'critical relief cooling down, {seconds}s left',
|
|
1206
1241
|
trimEnabledLabel: 'Enable auto-trim',
|
|
1207
1242
|
trimEnabledHelp: 'Master switch for the context-trim layer.',
|
|
1208
1243
|
trimLadderEnabledLabel: 'Ladder folding (T1/T2/T3)',
|
|
@@ -1252,6 +1287,8 @@ window.__ModuleLoader__.load({
|
|
|
1252
1287
|
trimAdvisoryHelp: 'Advisory mode only: the model is nudged to fold itself at this percent of the window.',
|
|
1253
1288
|
trimAdvisoryCriticalLabel: 'Advisory critical line (%)',
|
|
1254
1289
|
trimAdvisoryCriticalHelp: 'Advisory mode only: at this percent the nudge escalates to a fold-down-this-turn order.',
|
|
1290
|
+
trimAdvisoryRepeatLabel: 'Advisory re-pin interval (ms)',
|
|
1291
|
+
trimAdvisoryRepeatHelp: 'Advisory mode only: after a nudge is pinned to the session tail, it re-pins at the new tail every this many ms (critical band halves it, 45 s floor). Default 120000.',
|
|
1255
1292
|
trimWindowLabel: 'Window cap (tokens)',
|
|
1256
1293
|
trimWindowHelp: 'Pressure and emergency tiers use min(model window, cap); 0 = follow wmForceTokens.',
|
|
1257
1294
|
trimModeOff: 'Off',
|
|
@@ -1464,6 +1501,7 @@ window.__ModuleLoader__.load({
|
|
|
1464
1501
|
wmReadBudgetLabel: '單次讀取預算',
|
|
1465
1502
|
wmReadBudgetHelp: '每次讀取的 token 預算;每輪上限為其兩倍。',
|
|
1466
1503
|
wmNumberInvalid: '請輸入不小於 {min} 的整數。',
|
|
1504
|
+
wmNumberInvalidMax: '請輸入 {min} 到 {max} 之間的數。',
|
|
1467
1505
|
wmOrderInvalid: '三檔水位需嚴格遞增:soft < hard < force。',
|
|
1468
1506
|
wmDenyModeLabel: '硬檔行為',
|
|
1469
1507
|
wmDenyModeCap: '限流放行',
|
|
@@ -1486,6 +1524,16 @@ window.__ModuleLoader__.load({
|
|
|
1486
1524
|
trimModeLabel: '自動裁剪模式',
|
|
1487
1525
|
trimModeHelp:
|
|
1488
1526
|
'閒置時何時將歷史摺疊為摘要:off = 從不摺疊,advisory = 模型自主摺疊(達壓力線時引擎於系統提示注入一次性提醒),auto = 自動摺疊。',
|
|
1527
|
+
trimCriticalReliefLabel: '臨界救援摺疊',
|
|
1528
|
+
trimCriticalReliefHelp: '開啟後(預設),advisory 模式壓力到達臨界線(trimAdvisoryCriticalPercent)時引擎自動執行一次機械摺疊(90 秒冷卻),不再只依賴提示。',
|
|
1529
|
+
trimVerboseLogLabel: '調試模式(詳細日誌)',
|
|
1530
|
+
trimVerboseLogHelp: '預設關閉。開啟後引擎的每個執行步驟、閘門判定與決策路徑都會寫入 decisions.log(debug 行),便於問題追溯;關閉時只記錄關鍵決策行。無論開關與否,異常始終記錄完整細節。',
|
|
1531
|
+
trimDockLabel: '摺疊 {pressure}%(線 {line}%)',
|
|
1532
|
+
trimDockTipDomain: '摺疊引擎口徑:最近一次實付 prompt(max(view, wire))÷ 有效視窗(含上限)——不是輸入框旁上下文面板的預測口徑,兩者本就不同、不應收斂。',
|
|
1533
|
+
trimDockTipMass: '實付 {mass} / 視窗 {window} tokens',
|
|
1534
|
+
trimDockTipMode: '模式:{mode}(advisory=模型自行摺疊;auto=引擎自動摺疊)',
|
|
1535
|
+
trimDockTipReady: '臨界紓緩就緒:達到 80% 線即由引擎機械摺疊一次',
|
|
1536
|
+
trimDockTipCooldown: '臨界紓緩冷卻中,剩 {seconds}s',
|
|
1489
1537
|
trimEnabledLabel: '啟用自動裁剪',
|
|
1490
1538
|
trimEnabledHelp: '上下文裁剪層的總開關。',
|
|
1491
1539
|
trimLadderEnabledLabel: '階梯摺疊(T1/T2/T3)',
|
|
@@ -1718,6 +1766,7 @@ window.__ModuleLoader__.load({
|
|
|
1718
1766
|
wmReadBudgetLabel: '読み取り予算',
|
|
1719
1767
|
wmReadBudgetHelp: '1 回の読み取りあたりの token 予算です。各ラウンドの上限はその 2 倍です。',
|
|
1720
1768
|
wmNumberInvalid: '{min} 以上の整数を入力してください。',
|
|
1769
|
+
wmNumberInvalidMax: '{min} から {max} の間の数値を入力してください。',
|
|
1721
1770
|
wmOrderInvalid: '3 段階の水位は厳密に昇順にしてください:soft < hard < force。',
|
|
1722
1771
|
wmDenyModeLabel: 'ハード段階の動作',
|
|
1723
1772
|
wmDenyModeCap: '制限して警告',
|
|
@@ -1740,6 +1789,16 @@ window.__ModuleLoader__.load({
|
|
|
1740
1789
|
trimModeLabel: 'トリムモード',
|
|
1741
1790
|
trimModeHelp:
|
|
1742
1791
|
'アイドル時に履歴を要約へ折りたたむタイミング:off = 折りたたまない、advisory = モデルが自発的に折りたたむ(圧力しきい値でエンジンがシステムプロンプトに一度だけ注意喚起を追記)、auto = 自動で折りたたむ。',
|
|
1792
|
+
trimCriticalReliefLabel: 'クリティカル救済フォールド',
|
|
1793
|
+
trimCriticalReliefHelp: 'オン(既定)では、advisory モードで圧力が臨界線(trimAdvisoryCriticalPercent)に達した時点でエンジン自身が機械的フォールドを 1 回実行します(90 秒クールダウン)。',
|
|
1794
|
+
trimVerboseLogLabel: 'デバッグモード(詳細ログ)',
|
|
1795
|
+
trimVerboseLogHelp: '既定ではオフ。オンにすると、エンジンの各ステップ・ゲート判定・決定経路が decisions.log に(debug 行として)記録され、問題の追跡に役立ちます。オフ時は主要な決定行のみ記録。例外はこの設定に関係なく常に完全な詳細を記録します。',
|
|
1796
|
+
trimDockLabel: 'fold {pressure}%(線 {line}%)',
|
|
1797
|
+
trimDockTipDomain: 'fold エンジンの基準:最後に支払った prompt(max(view, wire))÷ 実効ウィンドウ(上限込み)——入力欄のコンテキストメーターの推定基準とは別物で、収束しないのが正常です。',
|
|
1798
|
+
trimDockTipMass: '支払い済み {mass} / ウィンドウ {window} トークン',
|
|
1799
|
+
trimDockTipMode: 'モード:{mode}(advisory=モデル自身が fold、auto=エンジンが fold)',
|
|
1800
|
+
trimDockTipReady: 'critical relief 待機中:critical 線に達するとエンジンが 1 回機械的に fold します',
|
|
1801
|
+
trimDockTipCooldown: 'critical relief クールダウン中、残り {seconds}秒',
|
|
1743
1802
|
trimEnabledLabel: '自動トリムを有効化',
|
|
1744
1803
|
trimEnabledHelp: 'コンテキストトリム層のマスタースイッチ。',
|
|
1745
1804
|
trimGrowthLabel: '増加しきい値(token)',
|
|
@@ -1960,6 +2019,7 @@ window.__ModuleLoader__.load({
|
|
|
1960
2019
|
wmReadBudgetLabel: '읽기 예산',
|
|
1961
2020
|
wmReadBudgetHelp: '한 번 읽기당 토큰 예산입니다. 매 라운드 상한은 그 두 배입니다.',
|
|
1962
2021
|
wmNumberInvalid: '{min} 이상의 정수를 입력하세요.',
|
|
2022
|
+
wmNumberInvalidMax: '{min}부터 {max}까지의 숫자를 입력하세요.',
|
|
1963
2023
|
wmOrderInvalid: '세 수위는 엄격히 증가해야 합니다: soft < hard < force.',
|
|
1964
2024
|
wmDenyModeLabel: '하드 단계 동작',
|
|
1965
2025
|
wmDenyModeCap: '제한하고 경고',
|
|
@@ -1989,6 +2049,16 @@ window.__ModuleLoader__.load({
|
|
|
1989
2049
|
trimModeLabel: '트림 모드',
|
|
1990
2050
|
trimModeHelp:
|
|
1991
2051
|
'유휴 시 언제 기록을 요약으로 접을지: off = 접지 않음, advisory = 모델이 스스로 접음(압력 임계값에서 엔진이 시스템 프롬프트에 일회성 알림 추가), auto = 자동 접기.',
|
|
2052
|
+
trimCriticalReliefLabel: '임계 구제 폴드',
|
|
2053
|
+
trimCriticalReliefHelp: '켜면(기본) advisory 모드에서 압력이 임계선(trimAdvisoryCriticalPercent)에 닿을 때 엔진이 직접 기계 폴드를 한 번 실행합니다(90초 쿨다운).',
|
|
2054
|
+
trimVerboseLogLabel: '디버그 모드(상세 로그)',
|
|
2055
|
+
trimVerboseLogHelp: '기본값은 끔입니다. 켜면 엔진의 모든 실행 단계, 게이트 판정, 결정 경로가 decisions.log에(debug 행) 기록되어 문제 추적에 도움이 됩니다. 끄면 핵심 결정 행만 기록됩니다. 예외는 이 설정과 무관하게 항상 전체 세부 정보를 기록합니다.',
|
|
2056
|
+
trimDockLabel: 'fold {pressure}%(선 {line}%)',
|
|
2057
|
+
trimDockTipDomain: 'fold 엔진 기준: 마지막 실제 결제 prompt(max(view, wire)) ÷ 실효 윈도우(상한 포함) — 입력창 컨텍스트 미터의 추정 기준과 다르며 수렴하지 않는 것이 정상입니다.',
|
|
2058
|
+
trimDockTipMass: '결제 {mass} / 윈도우 {window} 토큰',
|
|
2059
|
+
trimDockTipMode: '모드: {mode} (advisory=모델이 직접 fold, auto=엔진이 fold)',
|
|
2060
|
+
trimDockTipReady: 'critical relief 대기 중: critical 선 도달 시 엔진이 한 번 기계적으로 fold합니다',
|
|
2061
|
+
trimDockTipCooldown: 'critical relief 쿨다운 중, {seconds}초 남음',
|
|
1992
2062
|
trimEnabledLabel: '자동 트림 사용',
|
|
1993
2063
|
trimEnabledHelp: '컨텍스트 트림 계층의 마스터 스위치.',
|
|
1994
2064
|
trimGrowthLabel: '증가 임계값(token)',
|
|
@@ -2201,6 +2271,7 @@ window.__ModuleLoader__.load({
|
|
|
2201
2271
|
wmReadBudgetLabel: 'Lese-Budget',
|
|
2202
2272
|
wmReadBudgetHelp: 'Token-Budget pro Lesevorgang; jede Runde ist auf das Doppelte gedeckelt.',
|
|
2203
2273
|
wmNumberInvalid: 'Geben Sie eine ganze Zahl von mindestens {min} ein.',
|
|
2274
|
+
wmNumberInvalidMax: 'Geben Sie eine Zahl zwischen {min} und {max} ein.',
|
|
2204
2275
|
wmOrderInvalid: 'Die drei Stufen müssen strikt aufsteigen: soft < hard < force.',
|
|
2205
2276
|
wmDenyModeLabel: 'Verhalten der Hard-Stufe',
|
|
2206
2277
|
wmDenyModeCap: 'Deckeln und warnen',
|
|
@@ -2230,6 +2301,16 @@ window.__ModuleLoader__.load({
|
|
|
2230
2301
|
trimModeLabel: 'Trim-Modus',
|
|
2231
2302
|
trimModeHelp:
|
|
2232
2303
|
'Wann der Verlauf im Leerlauf zu Zusammenfassungen gefaltet wird: off = nie, advisory = das Modell faltet selbst (der Motor hängt eine einmalige Erinnerung an den Systemprompt an), auto = automatisches Falten.',
|
|
2304
|
+
trimCriticalReliefLabel: 'Kritische Notfaltung',
|
|
2305
|
+
trimCriticalReliefHelp: 'Ein (Standard): Erreicht der Druck im Advisory-Modus die kritische Linie (trimAdvisoryCriticalPercent), faltet die Engine selbst einmal mechanisch (90 s Abklingzeit).',
|
|
2306
|
+
trimVerboseLogLabel: 'Debugmodus (ausführliches Protokoll)',
|
|
2307
|
+
trimVerboseLogHelp: 'Standardmäßig aus. Bei Aktivierung werden jeder Engine-Schritt, jede Gate-Prüfung und jeder Entscheidungspfad in die decisions.log geschrieben (Debug-Zeilen) zur Fehlerverfolgung; bei Deaktivierung bleiben nur die wichtigsten Entscheidungszeilen. Ausnahmen werden unabhängig von dieser Einstellung immer mit vollständigen Details protokolliert.',
|
|
2308
|
+
trimDockLabel: 'Falten {pressure}% (Linie {line}%)',
|
|
2309
|
+
trimDockTipDomain: 'Fold-Engine-Domäne: zuletzt bezahlter Prompt (max aus view/wire) über das effektive Fenster (inkl. Limit) — nicht die Projektion des Kontextmessers; beide beantworten verschiedene Fragen und sollen nicht konvergieren.',
|
|
2310
|
+
trimDockTipMass: 'bezahlt {mass} / Fenster {window} Token',
|
|
2311
|
+
trimDockTipMode: 'Modus: {mode} (advisory = das Modell faltet selbst; auto = die Engine faltet)',
|
|
2312
|
+
trimDockTipReady: 'Critical Relief bereit: an der Critical-Linie faltet die Engine einmal mechanisch',
|
|
2313
|
+
trimDockTipCooldown: 'Critical-Relief-Cooldown, noch {seconds}s',
|
|
2233
2314
|
trimEnabledLabel: 'Auto-Trim aktivieren',
|
|
2234
2315
|
trimEnabledHelp: 'Hauptschalter für die Kontext-Trim-Schicht.',
|
|
2235
2316
|
trimGrowthLabel: 'Wachstumsschwelle (Token)',
|
|
@@ -2445,6 +2526,7 @@ window.__ModuleLoader__.load({
|
|
|
2445
2526
|
wmReadBudgetLabel: 'Presupuesto de lectura',
|
|
2446
2527
|
wmReadBudgetHelp: 'Presupuesto de tokens por lectura; cada ronda se limita al doble.',
|
|
2447
2528
|
wmNumberInvalid: 'Introduce un número entero de {min} o más.',
|
|
2529
|
+
wmNumberInvalidMax: 'Introduzca un número entre {min} y {max}.',
|
|
2448
2530
|
wmOrderInvalid: 'Los tres niveles deben ascender estrictamente: soft < hard < force.',
|
|
2449
2531
|
wmDenyModeLabel: 'Comportamiento del nivel duro',
|
|
2450
2532
|
wmDenyModeCap: 'Limitar y avisar',
|
|
@@ -2474,6 +2556,16 @@ window.__ModuleLoader__.load({
|
|
|
2474
2556
|
trimModeLabel: 'Modo de recorte',
|
|
2475
2557
|
trimModeHelp:
|
|
2476
2558
|
'Cuándo plegar el historial en resúmenes en reposo: off = nunca, advisory = el modelo pliega por sí mismo (el motor añade un aviso puntual al system prompt), auto = plegado automático.',
|
|
2559
|
+
trimCriticalReliefLabel: 'Alivio crítico mecánico',
|
|
2560
|
+
trimCriticalReliefHelp: 'Activado (predeterminado): en modo advisory, al llegar a la línea crítica (trimAdvisoryCriticalPercent), el motor pliega mecánicamente una vez por sí mismo (enfriamiento de 90 s).',
|
|
2561
|
+
trimVerboseLogLabel: 'Modo de depuración (registro detallado)',
|
|
2562
|
+
trimVerboseLogHelp: 'Desactivado por defecto. Al activarlo, cada paso del motor, evaluación de compuerta y ruta de decisión se escribe en decisions.log (líneas debug) para rastrear problemas; al desactivarlo solo se guardan las líneas de decisión clave. Las excepciones siempre se registran con detalle completo, independientemente de esta opción.',
|
|
2563
|
+
trimDockLabel: 'plegar {pressure}% (línea {line}%)',
|
|
2564
|
+
trimDockTipDomain: 'Dominio del motor de plegado: último prompt pagado (máx de view/wire) sobre la ventana efectiva (límite incluido) — no la proyección del medidor de contexto; ambos responden preguntas distintas y no están hechos para converger.',
|
|
2565
|
+
trimDockTipMass: 'pagado {mass} / ventana {window} tokens',
|
|
2566
|
+
trimDockTipMode: 'modo: {mode} (advisory = el modelo pliega; auto = pliega el motor)',
|
|
2567
|
+
trimDockTipReady: 'alivio crítico listo: en la línea crítica el motor pliega una vez mecánicamente',
|
|
2568
|
+
trimDockTipCooldown: 'alivio crítico enfriando, faltan {seconds}s',
|
|
2477
2569
|
trimEnabledLabel: 'Activar recorte automático',
|
|
2478
2570
|
trimEnabledHelp:
|
|
2479
2571
|
'Interruptor maestro de la capa de recorte de contexto.',
|
|
@@ -2690,6 +2782,7 @@ window.__ModuleLoader__.load({
|
|
|
2690
2782
|
wmReadBudgetLabel: 'Budget de lecture',
|
|
2691
2783
|
wmReadBudgetHelp: 'Budget de tokens par lecture ; chaque tour plafonne au double.',
|
|
2692
2784
|
wmNumberInvalid: 'Saisissez un nombre entier d’au moins {min}.',
|
|
2785
|
+
wmNumberInvalidMax: 'Saisissez un nombre compris entre {min} et {max}.',
|
|
2693
2786
|
wmOrderInvalid: 'Les trois paliers doivent strictement monter : soft < hard < force.',
|
|
2694
2787
|
wmDenyModeLabel: 'Comportement au palier hard',
|
|
2695
2788
|
wmDenyModeCap: 'Plafonner et avertir',
|
|
@@ -2719,6 +2812,16 @@ window.__ModuleLoader__.load({
|
|
|
2719
2812
|
trimModeLabel: 'Mode de rognage',
|
|
2720
2813
|
trimModeHelp:
|
|
2721
2814
|
'Quand replier l’historique en résumés au repos : off = jamais, advisory = le modèle replie lui-même (le moteur ajoute un rappel ponctuel au system prompt), auto = repli automatique.',
|
|
2815
|
+
trimCriticalReliefLabel: 'Secours mécanique critique',
|
|
2816
|
+
trimCriticalReliefHelp: 'Activé (par défaut) : en mode advisory, quand la pression atteint la ligne critique (trimAdvisoryCriticalPercent), le moteur plie lui-même une fois mécaniquement (délai de 90 s).',
|
|
2817
|
+
trimVerboseLogLabel: 'Mode débogage (journal détaillé)',
|
|
2818
|
+
trimVerboseLogHelp: 'Désactivé par défaut. Une fois activé, chaque étape du moteur, chaque évaluation de garde et chaque chemin de décision est consigné dans decisions.log (lignes debug) pour faciliter le traçage ; sinon, seules les lignes de décision clés sont conservées. Les exceptions sont toujours journalisées en détail, quoi qu’il arrive.',
|
|
2819
|
+
trimDockLabel: 'replier {pressure}% (ligne {line}%)',
|
|
2820
|
+
trimDockTipDomain: 'Domaine du moteur de repli : dernier prompt payé (max de view/wire) sur la fenêtre effective (plafond inclus) — pas la projection du compteur de contexte ; les deux répondent à des questions différentes et ne sont pas faits pour converger.',
|
|
2821
|
+
trimDockTipMass: 'payé {mass} / fenêtre {window} jetons',
|
|
2822
|
+
trimDockTipMode: 'mode : {mode} (advisory = le modèle replie lui-même ; auto = le moteur replie)',
|
|
2823
|
+
trimDockTipReady: 'soulagement critique prêt : à la ligne critique, le moteur replie une fois mécaniquement',
|
|
2824
|
+
trimDockTipCooldown: 'soulagement critique en refroidissement, {seconds}s restantes',
|
|
2722
2825
|
trimEnabledLabel: 'Activer le rognage automatique',
|
|
2723
2826
|
trimEnabledHelp:
|
|
2724
2827
|
'Interrupteur principal de la couche de rognage de contexte.',
|
|
@@ -2935,6 +3038,7 @@ window.__ModuleLoader__.load({
|
|
|
2935
3038
|
wmReadBudgetLabel: 'Budget di lettura',
|
|
2936
3039
|
wmReadBudgetHelp: 'Budget di token per lettura; ogni turno arriva al massimo al doppio.',
|
|
2937
3040
|
wmNumberInvalid: 'Inserisci un numero intero di almeno {min}.',
|
|
3041
|
+
wmNumberInvalidMax: 'Inserisci un numero compreso tra {min} e {max}.',
|
|
2938
3042
|
wmOrderInvalid: 'Le tre soglie devono salire rigorosamente: soft < hard < force.',
|
|
2939
3043
|
wmDenyModeLabel: 'Comportamento alla soglia hard',
|
|
2940
3044
|
wmDenyModeCap: 'Tetto e avviso',
|
|
@@ -2964,6 +3068,16 @@ window.__ModuleLoader__.load({
|
|
|
2964
3068
|
trimModeLabel: 'Modalità di riduzione',
|
|
2965
3069
|
trimModeHelp:
|
|
2966
3070
|
'Quando comprimere la cronologia in riepiloghi a riposo: off = mai, advisory = il modello comprime da solo (il motore aggiunge un promemoria una tantum al system prompt), auto = riduzione automatica.',
|
|
3071
|
+
trimCriticalReliefLabel: 'Soccorso critico meccanico',
|
|
3072
|
+
trimCriticalReliefHelp: 'Attivo (predefinito): in modalità advisory, al raggiungimento della linea critica (trimAdvisoryCriticalPercent), il motore esegue una piegatura meccanica da sé (cooldown di 90 s).',
|
|
3073
|
+
trimVerboseLogLabel: 'Modalità debug (log dettagliato)',
|
|
3074
|
+
trimVerboseLogHelp: 'Disattivato per impostazione predefinita. Se attivo, ogni passo del motore, ogni valutazione di gate e ogni percorso decisionale viene scritto in decisions.log (righe debug) per la tracciabilità dei problemi; se disattivo restano solo le righe decisionali chiave. Le eccezioni vengono sempre registrate per intero, indipendentemente da questa opzione.',
|
|
3075
|
+
trimDockLabel: 'ripiega {pressure}% (linea {line}%)',
|
|
3076
|
+
trimDockTipDomain: 'Dominio del motore di ripiegamento: ultimo prompt pagato (max di view/wire) sulla finestra effettiva (limite incluso) — non la proiezione del misuratore di contesto; i due rispondono a domande diverse e non sono fatti per convergere.',
|
|
3077
|
+
trimDockTipMass: 'pagato {mass} / finestra {window} token',
|
|
3078
|
+
trimDockTipMode: 'modalità: {mode} (advisory = il modello ripiega da solo; auto = ripiega il motore)',
|
|
3079
|
+
trimDockTipReady: 'sollievo critico pronto: alla linea critica il motore ripiega una volta meccanicamente',
|
|
3080
|
+
trimDockTipCooldown: 'sollievo critico in raffreddamento, {seconds}s rimanenti',
|
|
2967
3081
|
trimEnabledLabel: 'Attiva riduzione automatica',
|
|
2968
3082
|
trimEnabledHelp:
|
|
2969
3083
|
'Interruttore principale del livello di riduzione del contesto.',
|
|
@@ -3180,6 +3294,7 @@ window.__ModuleLoader__.load({
|
|
|
3180
3294
|
wmReadBudgetLabel: 'Orçamento de leitura',
|
|
3181
3295
|
wmReadBudgetHelp: 'Orçamento de tokens por leitura; cada turno se limita ao dobro disso.',
|
|
3182
3296
|
wmNumberInvalid: 'Informe um número inteiro de {min} ou mais.',
|
|
3297
|
+
wmNumberInvalidMax: 'Informe um número entre {min} e {max}.',
|
|
3183
3298
|
wmOrderInvalid: 'Os três limiares devem subir estritamente: soft < hard < force.',
|
|
3184
3299
|
wmDenyModeLabel: 'Comportamento no limiar hard',
|
|
3185
3300
|
wmDenyModeCap: 'Limitar e avisar',
|
|
@@ -3209,6 +3324,16 @@ window.__ModuleLoader__.load({
|
|
|
3209
3324
|
trimModeLabel: 'Modo de corte',
|
|
3210
3325
|
trimModeHelp:
|
|
3211
3326
|
'Quando dobrar o histórico em resumos na ociosidade: off = nunca, advisory = o modelo dobra por si (o motor acrescenta um aviso pontual ao system prompt), auto = dobra automática.',
|
|
3327
|
+
trimCriticalReliefLabel: 'Alívio crítico mecânico',
|
|
3328
|
+
trimCriticalReliefHelp: 'Ligado (padrão): no modo advisory, ao atingir a linha crítica (trimAdvisoryCriticalPercent), o motor dobra mecanicamente uma vez por si (arrefecimento de 90 s).',
|
|
3329
|
+
trimVerboseLogLabel: 'Modo de depuração (registro detalhado)',
|
|
3330
|
+
trimVerboseLogHelp: 'Desligado por padrão. Ativado, cada passo do motor, avaliação de portão e caminho de decisão é gravado no decisions.log (linhas debug) para rastrear problemas; desligado, apenas as linhas-chave de decisão são mantidas. Exceções sempre registram detalhes completos, independentemente desta opção.',
|
|
3331
|
+
trimDockLabel: 'dobrar {pressure}% (linha {line}%)',
|
|
3332
|
+
trimDockTipDomain: 'Domínio do motor de dobra: último prompt pago (máx de view/wire) sobre a janela efetiva (limite incluído) — não a projeção do medidor de contexto; ambos respondem perguntas diferentes e não estão feitos para convergir.',
|
|
3333
|
+
trimDockTipMass: 'pago {mass} / janela {window} tokens',
|
|
3334
|
+
trimDockTipMode: 'modo: {mode} (advisory = o modelo dobra; auto = o motor dobra)',
|
|
3335
|
+
trimDockTipReady: 'alívio crítico pronto: na linha crítica o motor dobra uma vez mecanicamente',
|
|
3336
|
+
trimDockTipCooldown: 'alívio crítico em arrefecimento, faltam {seconds}s',
|
|
3212
3337
|
trimEnabledLabel: 'Ativar corte automático',
|
|
3213
3338
|
trimEnabledHelp:
|
|
3214
3339
|
'Interruptor principal da camada de corte de contexto.',
|
|
@@ -3425,6 +3550,7 @@ window.__ModuleLoader__.load({
|
|
|
3425
3550
|
wmReadBudgetLabel: 'Бюджет чтения',
|
|
3426
3551
|
wmReadBudgetHelp: 'Бюджет токенов на одно чтение; каждый ход ограничен удвоенным значением.',
|
|
3427
3552
|
wmNumberInvalid: 'Введите целое число не меньше {min}.',
|
|
3553
|
+
wmNumberInvalidMax: 'Введите число от {min} до {max}.',
|
|
3428
3554
|
wmOrderInvalid: 'Три линии должны строго возрастать: soft < hard < force.',
|
|
3429
3555
|
wmDenyModeLabel: 'Поведение на линии hard',
|
|
3430
3556
|
wmDenyModeCap: 'Урезать и предупредить',
|
|
@@ -3454,6 +3580,16 @@ window.__ModuleLoader__.load({
|
|
|
3454
3580
|
trimModeLabel: 'Режим обрезки',
|
|
3455
3581
|
trimModeHelp:
|
|
3456
3582
|
'Когда сворачивать историю в сводки в простое: off = никогда, advisory = модель сворачивает сама (движок добавляет разовое напоминание в системный промпт), auto = автоматически.',
|
|
3583
|
+
trimCriticalReliefLabel: 'Критическое авто-сворачивание',
|
|
3584
|
+
trimCriticalReliefHelp: 'Включено (по умолчанию): в режиме advisory при достижении критической линии (trimAdvisoryCriticalPercent) движок сам один раз сворачивает механически (куладдаун 90 с).',
|
|
3585
|
+
trimVerboseLogLabel: 'Режим отладки (подробный журнал)',
|
|
3586
|
+
trimVerboseLogHelp: 'По умолчанию выключено. При включении каждый шаг движка, проверка шлюза и путь решения записываются в decisions.log (строки debug) для отслеживания проблем; при выключении сохраняются только ключевые строки решений. Исключения всегда записываются с полными деталями независимо от этого переключателя.',
|
|
3587
|
+
trimDockLabel: 'свернуть {pressure}% (линия {line}%)',
|
|
3588
|
+
trimDockTipDomain: 'Область движка сворачивания: последний оплаченный prompt (max от view/wire) делённый на эффективное окно (с лимитом) — не прогноз счётчика контекста; эти числа отвечают на разные вопросы и не должны сходиться.',
|
|
3589
|
+
trimDockTipMass: 'оплачено {mass} / окно {window} токенов',
|
|
3590
|
+
trimDockTipMode: 'режим: {mode} (advisory = модель сворачивает сама; auto = сворачивает движок)',
|
|
3591
|
+
trimDockTipReady: 'критическое relief готово: у критической линии движок один раз свернёт механически',
|
|
3592
|
+
trimDockTipCooldown: 'критическое relief на кулдауне, осталось {seconds}с',
|
|
3457
3593
|
trimEnabledLabel: 'Включить автообрезку',
|
|
3458
3594
|
trimEnabledHelp: 'Главный выключатель слоя обрезки контекста.',
|
|
3459
3595
|
trimGrowthLabel: 'Порог роста (токенов)',
|
|
@@ -4054,6 +4190,147 @@ window.__ModuleLoader__.load({
|
|
|
4054
4190
|
);
|
|
4055
4191
|
}
|
|
4056
4192
|
|
|
4193
|
+
/** Composer dock chip for trim pressure (conversation.input.dock,
|
|
4194
|
+
* order 88 — one slot below the intent chip's 89): shows the fold
|
|
4195
|
+
* engine's own pressure figure — the LAST PAID prompt (max of view/
|
|
4196
|
+
* wire) over the effective window (cap included) — next to the
|
|
4197
|
+
* composer. This is the number the trim nudges and tiers act on, and
|
|
4198
|
+
* it is deliberately NOT the composer context meter's projection:
|
|
4199
|
+
* different numerator (paid vs projected) and denominator (effective
|
|
4200
|
+
* window vs model window), so the two figures answer different
|
|
4201
|
+
* questions and legitimately diverge (the tooltip spells this out).
|
|
4202
|
+
* Polls the Host trim-pressure route every 15s; disabled trim, an
|
|
4203
|
+
* unknown window, or any fetch failure renders null (fail-silent).
|
|
4204
|
+
* Pure display — no interactive controls. */
|
|
4205
|
+
function TrimDockEntry({ t, sessionId, useProjection }) {
|
|
4206
|
+
const [snap, setSnap] = React.useState(null);
|
|
4207
|
+
// Realtime trigger ([2026-11-15] user report: after a fold ships the chip
|
|
4208
|
+
// kept the pre-fold percentage for up to one 15s poll — the Host snapshot
|
|
4209
|
+
// recomputes per request, so the lag was entirely client-side). The
|
|
4210
|
+
// contextPressure projection face folds EVERY surface event, including
|
|
4211
|
+
// the trim engine's fold-commit replacements, so its value changes the
|
|
4212
|
+
// moment a fold lands; it is also stable-primitive-safe to observe with
|
|
4213
|
+
// useSyncExternalStore (the shipped ContextMeter does exactly this).
|
|
4214
|
+
// Subscribing to that face makes the poll loop fetch immediately on
|
|
4215
|
+
// each pressure change (fold commit AND normal turn growth) and keeps
|
|
4216
|
+
// the 15s timer only as the drift fallback (cooldown countdown, model
|
|
4217
|
+
// window changes — inputs the projection does not see).
|
|
4218
|
+
const projectionHook =
|
|
4219
|
+
typeof useProjection === 'function' ? useProjection : () => undefined;
|
|
4220
|
+
const pressureFace = projectionHook('contextPressure');
|
|
4221
|
+
const pressureSignal =
|
|
4222
|
+
pressureFace == null
|
|
4223
|
+
? null
|
|
4224
|
+
: `${pressureFace.projectedTokens ?? pressureFace.pressureTokens ?? ''}|${pressureFace.contextWindow ?? ''}`;
|
|
4225
|
+
const [pulse, setPulse] = React.useState(0);
|
|
4226
|
+
React.useEffect(() => {
|
|
4227
|
+
setPulse((n) => n + 1);
|
|
4228
|
+
}, [pressureSignal]);
|
|
4229
|
+
React.useEffect(() => {
|
|
4230
|
+
let stopped = false;
|
|
4231
|
+
let timer = null;
|
|
4232
|
+
const query =
|
|
4233
|
+
typeof sessionId === 'string' && sessionId !== ''
|
|
4234
|
+
? `?session=${encodeURIComponent(sessionId)}`
|
|
4235
|
+
: '';
|
|
4236
|
+
const tick = async () => {
|
|
4237
|
+
let next = null;
|
|
4238
|
+
try {
|
|
4239
|
+
const reply = await api.get(`trim-pressure${query}`);
|
|
4240
|
+
const value = reply?.ok ? reply.value : null;
|
|
4241
|
+
if (
|
|
4242
|
+
value &&
|
|
4243
|
+
typeof value === 'object' &&
|
|
4244
|
+
value.available === true &&
|
|
4245
|
+
typeof value.pressure === 'number' &&
|
|
4246
|
+
typeof value.window === 'number' &&
|
|
4247
|
+
value.window > 0
|
|
4248
|
+
)
|
|
4249
|
+
next = {
|
|
4250
|
+
mode: value.mode === 'advisory' || value.mode === 'auto' ? value.mode : null,
|
|
4251
|
+
pressure: Math.round(value.pressure),
|
|
4252
|
+
mass: typeof value.mass === 'number' ? value.mass : null,
|
|
4253
|
+
window: value.window,
|
|
4254
|
+
advisoryLine:
|
|
4255
|
+
typeof value.advisoryLine === 'number' ? value.advisoryLine : null,
|
|
4256
|
+
criticalLine:
|
|
4257
|
+
typeof value.criticalLine === 'number' ? value.criticalLine : null,
|
|
4258
|
+
reliefCooldown:
|
|
4259
|
+
typeof value.reliefCooldownRemaining === 'number'
|
|
4260
|
+
? Math.max(0, Math.round(value.reliefCooldownRemaining / 1000))
|
|
4261
|
+
: null,
|
|
4262
|
+
reliefReady: value.reliefReady === true,
|
|
4263
|
+
};
|
|
4264
|
+
} catch {
|
|
4265
|
+
next = null;
|
|
4266
|
+
}
|
|
4267
|
+
if (stopped) return;
|
|
4268
|
+
setSnap(next);
|
|
4269
|
+
timer = setTimeout(tick, 15_000);
|
|
4270
|
+
};
|
|
4271
|
+
void tick();
|
|
4272
|
+
return () => {
|
|
4273
|
+
stopped = true;
|
|
4274
|
+
if (timer !== null) clearTimeout(timer);
|
|
4275
|
+
};
|
|
4276
|
+
}, [sessionId, pulse]);
|
|
4277
|
+
if (snap === null) return null;
|
|
4278
|
+
// Same dock-column formula as the sibling chips: keep the chip's
|
|
4279
|
+
// left edge tracking the centered composer card.
|
|
4280
|
+
const tipLines = [
|
|
4281
|
+
t('trimDockTipDomain'),
|
|
4282
|
+
snap.mass !== null
|
|
4283
|
+
? t('trimDockTipMass', { mass: snap.mass, window: snap.window })
|
|
4284
|
+
: null,
|
|
4285
|
+
snap.mode !== null ? t('trimDockTipMode', { mode: snap.mode }) : null,
|
|
4286
|
+
snap.reliefCooldown !== null && snap.reliefCooldown > 0
|
|
4287
|
+
? t('trimDockTipCooldown', { seconds: snap.reliefCooldown })
|
|
4288
|
+
: null,
|
|
4289
|
+
snap.reliefReady ? t('trimDockTipReady') : null,
|
|
4290
|
+
].filter((line) => line !== null);
|
|
4291
|
+
const nearCritical =
|
|
4292
|
+
snap.criticalLine !== null && snap.pressure >= snap.criticalLine;
|
|
4293
|
+
const nearLine =
|
|
4294
|
+
!nearCritical &&
|
|
4295
|
+
snap.advisoryLine !== null &&
|
|
4296
|
+
snap.pressure >= snap.advisoryLine;
|
|
4297
|
+
return h(
|
|
4298
|
+
'div',
|
|
4299
|
+
{
|
|
4300
|
+
'data-dsh-switchman': 'trim-dock-column',
|
|
4301
|
+
style: {
|
|
4302
|
+
boxSizing: 'border-box',
|
|
4303
|
+
width: 'calc(100% - var(--dsh-composer-side-clearance, 16px) - var(--dsh-composer-side-clearance, 16px))',
|
|
4304
|
+
maxWidth: 'var(--dsh-composer-card-max-width, 780px)',
|
|
4305
|
+
margin: '0 auto',
|
|
4306
|
+
flex: 'none',
|
|
4307
|
+
display: 'flex',
|
|
4308
|
+
flexDirection: 'column',
|
|
4309
|
+
gap: 'var(--dsh-composer-stack-gap, 6px)',
|
|
4310
|
+
},
|
|
4311
|
+
},
|
|
4312
|
+
h(
|
|
4313
|
+
'p',
|
|
4314
|
+
{
|
|
4315
|
+
'data-dsh-switchman': 'trim-dock-chip',
|
|
4316
|
+
title: tipLines.join(' · '),
|
|
4317
|
+
style: {
|
|
4318
|
+
margin: '0',
|
|
4319
|
+
padding: '2px 0',
|
|
4320
|
+
color: nearCritical
|
|
4321
|
+
? 'var(--dsw-alias-state-error-primary, inherit)'
|
|
4322
|
+
: nearLine
|
|
4323
|
+
? 'var(--dsw-alias-state-business-primary, inherit)'
|
|
4324
|
+
: 'var(--dsw-alias-label-tertiary, inherit)',
|
|
4325
|
+
fontSize: '12px',
|
|
4326
|
+
lineHeight: '1.6',
|
|
4327
|
+
},
|
|
4328
|
+
},
|
|
4329
|
+
'⚙ ',
|
|
4330
|
+
t('trimDockLabel', { pressure: snap.pressure, line: snap.advisoryLine }),
|
|
4331
|
+
),
|
|
4332
|
+
);
|
|
4333
|
+
}
|
|
4057
4334
|
/** Composer dock chip for intent routing (conversation.input.dock,
|
|
4058
4335
|
* order 89 — one slot above the vision entry's 90): shows where the
|
|
4059
4336
|
* session's auto-selected pseudo-model currently routes AND the
|
|
@@ -5269,7 +5546,7 @@ window.__ModuleLoader__.load({
|
|
|
5269
5546
|
(values.langConversation !== '' &&
|
|
5270
5547
|
!isCandidate(values.langConversation));
|
|
5271
5548
|
/** Per-field numeric validity: raw text (when present) must be a
|
|
5272
|
-
*
|
|
5549
|
+
* plain number within the schema bounds. The trim and intent rows
|
|
5273
5550
|
* share the same raw-text overlay and save gate. */
|
|
5274
5551
|
const numberInvalid = Object.fromEntries(
|
|
5275
5552
|
[
|
|
@@ -5282,7 +5559,7 @@ window.__ModuleLoader__.load({
|
|
|
5282
5559
|
return [
|
|
5283
5560
|
field,
|
|
5284
5561
|
raw !== undefined &&
|
|
5285
|
-
(!/^\d
|
|
5562
|
+
(!/^\d+(?:\.\d+)?$/.test(raw.trim()) ||
|
|
5286
5563
|
Number(raw.trim()) < min ||
|
|
5287
5564
|
Number(raw.trim()) > (max ?? Infinity)),
|
|
5288
5565
|
];
|
|
@@ -5317,12 +5594,13 @@ window.__ModuleLoader__.load({
|
|
|
5317
5594
|
setFailed(false);
|
|
5318
5595
|
}
|
|
5319
5596
|
|
|
5320
|
-
/** Number-input onChange: stage the raw text, commit only
|
|
5321
|
-
* numbers (the draft always holds
|
|
5597
|
+
/** Number-input onChange: stage the raw text, commit only plain
|
|
5598
|
+
* numbers (integers or decimal fractions — the draft always holds
|
|
5599
|
+
* parseable values). */
|
|
5322
5600
|
function editNumber(field, raw) {
|
|
5323
5601
|
setNumText((previous) => ({ ...previous, [field]: raw }));
|
|
5324
5602
|
const trimmed = raw.trim();
|
|
5325
|
-
if (/^\d
|
|
5603
|
+
if (/^\d+(?:\.\d+)?$/.test(trimmed)) edit(field, Number(trimmed));
|
|
5326
5604
|
}
|
|
5327
5605
|
|
|
5328
5606
|
/** Number-input onBlur: drop the overlay so the display falls back
|
|
@@ -5539,6 +5817,8 @@ window.__ModuleLoader__.load({
|
|
|
5539
5817
|
trimEnabled: values.trimEnabled,
|
|
5540
5818
|
trimLadderEnabled: values.trimLadderEnabled,
|
|
5541
5819
|
trimProtectTaskIntent: values.trimProtectTaskIntent,
|
|
5820
|
+
trimCriticalRelief: values.trimCriticalRelief,
|
|
5821
|
+
trimVerboseLog: values.trimVerboseLog,
|
|
5542
5822
|
surfaceFold: values.surfaceFold,
|
|
5543
5823
|
trimSideModel: {
|
|
5544
5824
|
provider: values.trimSideModel.provider,
|
|
@@ -5837,12 +6117,17 @@ window.__ModuleLoader__.load({
|
|
|
5837
6117
|
});
|
|
5838
6118
|
};
|
|
5839
6119
|
|
|
5840
|
-
/**
|
|
6120
|
+
/** Shared invalid-number hint: a finite max gets the range text. */
|
|
6121
|
+
const numberInvalidText = (spec) =>
|
|
6122
|
+
spec.max !== undefined && Number.isFinite(spec.max)
|
|
6123
|
+
? t('wmNumberInvalidMax', { min: spec.min, max: spec.max })
|
|
6124
|
+
: t('wmNumberInvalid', { min: spec.min });
|
|
6125
|
+
/** Status lines under one number row: bounds + order hints. */
|
|
5841
6126
|
const wmNumberLines = (spec) => {
|
|
5842
6127
|
const lines = [];
|
|
5843
6128
|
if (numberInvalid[spec.field])
|
|
5844
6129
|
lines.push({
|
|
5845
|
-
text:
|
|
6130
|
+
text: numberInvalidText(spec),
|
|
5846
6131
|
invalid: true,
|
|
5847
6132
|
});
|
|
5848
6133
|
if (orderInvalid && WM_ORDER_FIELDS.includes(spec.field))
|
|
@@ -5878,10 +6163,10 @@ window.__ModuleLoader__.load({
|
|
|
5878
6163
|
});
|
|
5879
6164
|
};
|
|
5880
6165
|
|
|
5881
|
-
/** Status lines under one intent number row:
|
|
6166
|
+
/** Status lines under one intent number row: bounds hint. */
|
|
5882
6167
|
const intentNumberLines = (spec) =>
|
|
5883
6168
|
numberInvalid[spec.field]
|
|
5884
|
-
? [{ text:
|
|
6169
|
+
? [{ text: numberInvalidText(spec), invalid: true }]
|
|
5885
6170
|
: [];
|
|
5886
6171
|
/** One trim number input: the watermark rows' raw-text overlay
|
|
5887
6172
|
* pattern under the trim section id (invalid text shows the
|
|
@@ -5910,10 +6195,10 @@ window.__ModuleLoader__.load({
|
|
|
5910
6195
|
});
|
|
5911
6196
|
};
|
|
5912
6197
|
|
|
5913
|
-
/** Status lines under one trim number row:
|
|
6198
|
+
/** Status lines under one trim number row: bounds hint. */
|
|
5914
6199
|
const trimNumberLines = (spec) =>
|
|
5915
6200
|
numberInvalid[spec.field]
|
|
5916
|
-
? [{ text:
|
|
6201
|
+
? [{ text: numberInvalidText(spec), invalid: true }]
|
|
5917
6202
|
: [];
|
|
5918
6203
|
|
|
5919
6204
|
/** Intent option sets fed by the DSH model catalog (the same
|
|
@@ -7130,6 +7415,37 @@ window.__ModuleLoader__.load({
|
|
|
7130
7415
|
style: STYLE.checkbox,
|
|
7131
7416
|
}),
|
|
7132
7417
|
lines: [],
|
|
7418
|
+
}),
|
|
7419
|
+
h(SettingsRow, {
|
|
7420
|
+
key: 'trimCriticalRelief',
|
|
7421
|
+
id: `${trimId}-relief`,
|
|
7422
|
+
label: t('trimCriticalReliefLabel'),
|
|
7423
|
+
help: t('trimCriticalReliefHelp'),
|
|
7424
|
+
control: h('input', {
|
|
7425
|
+
type: 'checkbox',
|
|
7426
|
+
id: `${trimId}-relief`,
|
|
7427
|
+
checked: values.trimCriticalRelief,
|
|
7428
|
+
onChange: () => {
|
|
7429
|
+
edit('trimCriticalRelief', !values.trimCriticalRelief);
|
|
7430
|
+
},
|
|
7431
|
+
disabled: !editable,
|
|
7432
|
+
style: STYLE.checkbox,
|
|
7433
|
+
}),
|
|
7434
|
+
key: 'trimVerboseLog',
|
|
7435
|
+
id: `${trimId}-verbose`,
|
|
7436
|
+
label: t('trimVerboseLogLabel'),
|
|
7437
|
+
help: t('trimVerboseLogHelp'),
|
|
7438
|
+
control: h('input', {
|
|
7439
|
+
type: 'checkbox',
|
|
7440
|
+
id: `${trimId}-verbose`,
|
|
7441
|
+
checked: values.trimVerboseLog,
|
|
7442
|
+
onChange: () => {
|
|
7443
|
+
edit('trimVerboseLog', !values.trimVerboseLog);
|
|
7444
|
+
},
|
|
7445
|
+
disabled: !editable,
|
|
7446
|
+
style: STYLE.checkbox,
|
|
7447
|
+
}),
|
|
7448
|
+
lines: [],
|
|
7133
7449
|
}),
|
|
7134
7450
|
h(SettingsRow, {
|
|
7135
7451
|
key: 'surfaceFold',
|
|
@@ -7509,6 +7825,19 @@ window.__ModuleLoader__.load({
|
|
|
7509
7825
|
},
|
|
7510
7826
|
(kit) => h(IntentDockEntry, { ...kit, t }),
|
|
7511
7827
|
),
|
|
7828
|
+
); // Trim-pressure chip (same dock list, order 88 — one slot below
|
|
7829
|
+
// the intent chip): the fold engine's paid-prompt pressure, the
|
|
7830
|
+
// number its nudges/tiers act on. Deliberately NOT the composer
|
|
7831
|
+
// context meter's projection — the tooltip explains the domains.
|
|
7832
|
+
ctx.slots.inject('conversation.input.dock', () =>
|
|
7833
|
+
ctx.slots.register(
|
|
7834
|
+
{
|
|
7835
|
+
name: 'conversation.input.dock',
|
|
7836
|
+
id: 'dsh-switchman-trim',
|
|
7837
|
+
order: 88,
|
|
7838
|
+
},
|
|
7839
|
+
(kit) => h(TrimDockEntry, { ...kit, t }),
|
|
7840
|
+
),
|
|
7512
7841
|
);
|
|
7513
7842
|
// Composer model label (conversation.input.model.label): the
|
|
7514
7843
|
// ui-model-selection shell dispatches EVERY model's label
|