dsh-switchman 1.11.3 → 1.11.5
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 +3 -3
- package/README.es.md +3 -3
- package/README.fr.md +3 -3
- package/README.it.md +3 -3
- package/README.ja.md +3 -3
- package/README.ko.md +3 -3
- package/README.md +7 -7
- package/README.pt.md +3 -3
- package/README.ru.md +3 -3
- package/README.zh-TW.md +3 -3
- package/README.zh.md +4 -4
- package/client.js +154 -52
- package/host/config.js +10 -8
- package/host/context-trim/index.js +6 -9
- package/host/context-trim/summarizer.js +46 -35
- package/host/ptc-guard.js +6 -0
- package/host/routes.js +10 -14
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -373,14 +373,13 @@ window.__ModuleLoader__.load({
|
|
|
373
373
|
const routeKey = (route) => `${route.provider}\0${route.model}`;
|
|
374
374
|
|
|
375
375
|
/** One well-formed {provider, model[, effort]} route, or null. */
|
|
376
|
-
function sanitizeRoute(route) {
|
|
376
|
+
function sanitizeRoute(route, allowEffort = false) {
|
|
377
377
|
if (route === null || typeof route !== 'object') return null;
|
|
378
378
|
if (typeof route.provider !== 'string' || route.provider === '') return null;
|
|
379
379
|
if (typeof route.model !== 'string' || route.model === '') return null;
|
|
380
|
-
//
|
|
381
|
-
// round-trip so a settings save never strips it (intent routes omit it).
|
|
380
|
+
// Preserve effort only for settings routes that expose a dedicated pin.
|
|
382
381
|
const out = { provider: route.provider, model: route.model };
|
|
383
|
-
if (typeof route.effort === 'string' && route.effort !== '') out.effort = route.effort;
|
|
382
|
+
if (allowEffort && typeof route.effort === 'string' && route.effort !== '') out.effort = route.effort;
|
|
384
383
|
return out;
|
|
385
384
|
}
|
|
386
385
|
|
|
@@ -532,10 +531,10 @@ window.__ModuleLoader__.load({
|
|
|
532
531
|
trimLadderEnabled: bool('trimLadderEnabled', true),
|
|
533
532
|
surfaceFold: bool('surfaceFold', true),
|
|
534
533
|
trimSideModel:
|
|
535
|
-
sanitizeRoute(value?.trimSideModel) ??
|
|
534
|
+
sanitizeRoute(value?.trimSideModel, true) ??
|
|
536
535
|
({ provider: '', model: '' }),
|
|
537
536
|
trimFoldFallbackModel:
|
|
538
|
-
|
|
537
|
+
sanitizeRoute(value?.trimFoldFallbackModel, true) ??
|
|
539
538
|
({ provider: '', model: '' }),
|
|
540
539
|
trimStateDir: string('trimStateDir'),
|
|
541
540
|
...Object.fromEntries(
|
|
@@ -565,7 +564,7 @@ window.__ModuleLoader__.load({
|
|
|
565
564
|
INTENT_NUMBER_FIELDS.map((spec) => [spec.field, number(spec)]),
|
|
566
565
|
),
|
|
567
566
|
intentFallbackRoute:
|
|
568
|
-
sanitizeRoute(value?.intentFallbackRoute) ??
|
|
567
|
+
sanitizeRoute(value?.intentFallbackRoute, true) ??
|
|
569
568
|
({ provider: '', model: '' }),
|
|
570
569
|
};
|
|
571
570
|
}
|
|
@@ -619,8 +618,8 @@ window.__ModuleLoader__.load({
|
|
|
619
618
|
trimEnabled: values.trimEnabled,
|
|
620
619
|
trimLadderEnabled: values.trimLadderEnabled,
|
|
621
620
|
surfaceFold: values.surfaceFold,
|
|
622
|
-
trimSideModel: routeKey(values.trimSideModel)
|
|
623
|
-
trimFoldFallbackModel: routeKey(values.trimFoldFallbackModel)
|
|
621
|
+
trimSideModel: `${routeKey(values.trimSideModel)}\0${values.trimSideModel.effort ?? ''}`,
|
|
622
|
+
trimFoldFallbackModel: `${routeKey(values.trimFoldFallbackModel)}\0${values.trimFoldFallbackModel.effort ?? ''}`,
|
|
624
623
|
trimStateDir: values.trimStateDir,
|
|
625
624
|
...Object.fromEntries(
|
|
626
625
|
TRIM_NUMBER_FIELDS.map(({ field }) => [field, values[field]]),
|
|
@@ -645,7 +644,7 @@ window.__ModuleLoader__.load({
|
|
|
645
644
|
...Object.fromEntries(
|
|
646
645
|
INTENT_NUMBER_FIELDS.map(({ field }) => [field, values[field]]),
|
|
647
646
|
),
|
|
648
|
-
intentFallbackRoute: routeKey(values.intentFallbackRoute)
|
|
647
|
+
intentFallbackRoute: `${routeKey(values.intentFallbackRoute)}\0${values.intentFallbackRoute.effort ?? ''}`,
|
|
649
648
|
});
|
|
650
649
|
}
|
|
651
650
|
|
|
@@ -845,6 +844,7 @@ window.__ModuleLoader__.load({
|
|
|
845
844
|
'开启后按列表顺序派发(首个即首选);未开启按能力排序自动排。',
|
|
846
845
|
poolManualSelected: '已选 · 派发优先序',
|
|
847
846
|
poolManualAddable: '可添加',
|
|
847
|
+
poolMoveTop: '登顶',
|
|
848
848
|
poolMoveUp: '上移',
|
|
849
849
|
poolMoveDown: '下移',
|
|
850
850
|
poolRemoveOne: '移除',
|
|
@@ -922,11 +922,11 @@ window.__ModuleLoader__.load({
|
|
|
922
922
|
surfaceFoldLabel: '把折叠写入会话表面',
|
|
923
923
|
surfaceFoldHelp: '追加宿主风格的替换事件,让折叠在冻结派发下也能到达线上。建议保持开启。',
|
|
924
924
|
trimSideModelLabel: '摘要模型',
|
|
925
|
-
trimSideModelHelp: '
|
|
925
|
+
trimSideModelHelp: '折叠摘要使用的模型路由;默认「跟随会话模型」。阶梯蒸馏同样使用该路由。未手动指定思考等级时,按模型元数据自动选择最低开启档;只有开/关思考时取关闭。模型不支持思考或元数据不可用时,不发送思考等级并沿用模型默认。',
|
|
926
926
|
trimFollowSession: '跟随会话模型',
|
|
927
|
-
|
|
927
|
+
trimEffortRecommended: '自动(按模型推荐规则)',
|
|
928
928
|
trimFoldFallbackModelLabel: '折叠异常兜底模型',
|
|
929
|
-
trimFoldFallbackModelHelp: '
|
|
929
|
+
trimFoldFallbackModelHelp: '摘要模型调用失败时改用该模型重试;仍失败则压力折叠退回机械折叠。思考等级可单独指定;留空时按该模型的推荐规则自动选择。尽量选择没有冷却、风控或并发限制的模型,避免与主会话共用同一账号。留空 = 无兜底。',
|
|
930
930
|
trimFallbackUnset: '未设置(失败时直接机械折叠)',
|
|
931
931
|
trimStateDirLabel: '账本目录',
|
|
932
932
|
trimStateDirHelp: '留空 = 默认的裁剪状态目录。',
|
|
@@ -1021,7 +1021,7 @@ window.__ModuleLoader__.load({
|
|
|
1021
1021
|
intentHistoryMaxCharsHelp: '对话摘录的总字符上限(200–20000)。',
|
|
1022
1022
|
intentFallbackRouteLabel: '兜底模型',
|
|
1023
1023
|
intentFallbackRouteHelp:
|
|
1024
|
-
'分类失败时依次:上一轮实际路由 → 兜底模型 →
|
|
1024
|
+
'分类失败时依次:上一轮实际路由 → 兜底模型 → 候选第一位;留空用候选第一位。可选固定思考等级;不指定时使用兜底模型默认等级。',
|
|
1025
1025
|
intentRouteUnset: '未设置',
|
|
1026
1026
|
intentEffortFollow: '跟随模型默认',
|
|
1027
1027
|
intentDockAuto: '自动',
|
|
@@ -1113,6 +1113,7 @@ window.__ModuleLoader__.load({
|
|
|
1113
1113
|
'When on, dispatch follows the listed order (head = first choice); when off, lanes are ordered by capability automatically.',
|
|
1114
1114
|
poolManualSelected: 'Selected · dispatch priority',
|
|
1115
1115
|
poolManualAddable: 'Add models',
|
|
1116
|
+
poolMoveTop: 'Move to top',
|
|
1116
1117
|
poolMoveUp: 'Move up',
|
|
1117
1118
|
poolMoveDown: 'Move down',
|
|
1118
1119
|
poolRemoveOne: 'Remove',
|
|
@@ -1192,13 +1193,12 @@ window.__ModuleLoader__.load({
|
|
|
1192
1193
|
surfaceFoldHelp:
|
|
1193
1194
|
'Append host-style replace events so folds reach the wire even on frozen dispatches. Leave on.',
|
|
1194
1195
|
trimSideModelLabel: 'Summarizer model',
|
|
1195
|
-
trimSideModelHelp:
|
|
1196
|
-
'Route for fold summaries; defaults to following the session model. Also used by ladder distillations.',
|
|
1196
|
+
trimSideModelHelp: 'Route for fold summaries; defaults to following the session model. Also used by ladder distillations. Without a pinned effort, choose the lowest enabled level from model metadata; for a thinking on/off-only model, choose off. If reasoning is unsupported or metadata is unavailable, omit the effort and keep the model default.',
|
|
1197
1197
|
trimFollowSession: 'Follow session model',
|
|
1198
|
-
|
|
1198
|
+
trimEffortRecommended: 'Automatic (model recommendation)',
|
|
1199
1199
|
trimFoldFallbackModelLabel: 'Fold fallback model',
|
|
1200
1200
|
trimFoldFallbackModelHelp:
|
|
1201
|
-
'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.',
|
|
1201
|
+
'When the summary route fails, the fold retries on this model before degrading a pressure fold to a mechanical one. Its effort can be pinned separately; if unset, the model recommendation is used. 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.',
|
|
1202
1202
|
trimFallbackUnset: 'Unset (failed folds go straight to mechanical)',
|
|
1203
1203
|
trimStateDirLabel: 'Ledger directory',
|
|
1204
1204
|
trimStateDirHelp: 'Empty = the default per-host trim state directory.',
|
|
@@ -1303,7 +1303,7 @@ window.__ModuleLoader__.load({
|
|
|
1303
1303
|
'Total character cap of the conversation excerpt (200–20000).',
|
|
1304
1304
|
intentFallbackRouteLabel: 'Fallback model',
|
|
1305
1305
|
intentFallbackRouteHelp:
|
|
1306
|
-
'On classification failure: last routed model → fallback → first candidate; empty = first candidate.',
|
|
1306
|
+
'On classification failure: last routed model → fallback → first candidate; empty = first candidate. Optionally pin a thinking effort; when unset, the fallback model default is used.',
|
|
1307
1307
|
intentRouteUnset: 'Not set',
|
|
1308
1308
|
intentEffortFollow: 'model default',
|
|
1309
1309
|
intentDockAuto: 'Auto',
|
|
@@ -1397,6 +1397,7 @@ window.__ModuleLoader__.load({
|
|
|
1397
1397
|
poolManualHelp: '開啟後按清單順序派發(首個即首選);未開啟按能力排序自動排。',
|
|
1398
1398
|
poolManualSelected: '已選 · 派發優先序',
|
|
1399
1399
|
poolManualAddable: '可新增',
|
|
1400
|
+
poolMoveTop: '登頂',
|
|
1400
1401
|
poolMoveUp: '上移',
|
|
1401
1402
|
poolMoveDown: '下移',
|
|
1402
1403
|
poolRemoveOne: '移除',
|
|
@@ -1467,11 +1468,11 @@ window.__ModuleLoader__.load({
|
|
|
1467
1468
|
surfaceFoldLabel: '把摺疊寫入會話表面',
|
|
1468
1469
|
surfaceFoldHelp: '追加宿主風格的替換事件,讓摺疊在凍結派發下也能到達線上。建議保持開啟。',
|
|
1469
1470
|
trimSideModelLabel: '摘要模型',
|
|
1470
|
-
trimSideModelHelp: '
|
|
1471
|
+
trimSideModelHelp: '摺疊摘要使用的模型路由;預設「跟隨對話模型」。階梯蒸餾同樣使用該路由。未手動指定思考等級時,依模型中繼資料自動選擇最低啟用等級;模型僅提供思考開/關切換時取關閉。不支援思考或中繼資料不可用時,不傳思考等級並沿用模型預設。',
|
|
1471
1472
|
trimFollowSession: '跟隨對話模型',
|
|
1472
|
-
|
|
1473
|
+
trimEffortRecommended: '自動(依模型推薦規則)',
|
|
1473
1474
|
trimFoldFallbackModelLabel: '摺疊異常備援模型',
|
|
1474
|
-
trimFoldFallbackModelHelp: '
|
|
1475
|
+
trimFoldFallbackModelHelp: '摘要模型呼叫失敗時改用該模型重試;仍失敗則壓力摺疊退回機械摺疊。思考等級可單獨指定;留空時依該模型推薦規則自動選擇。盡量選擇沒有冷卻、風控或並行限制的模型,避免與主對話共用同一帳號。留空 = 無備援。',
|
|
1475
1476
|
trimFallbackUnset: '未設定(失敗時直接機械摺疊)',
|
|
1476
1477
|
trimStateDirLabel: '帳本目錄',
|
|
1477
1478
|
trimStateDirHelp: '留空 = 預設的裁剪狀態目錄。',
|
|
@@ -1563,7 +1564,7 @@ window.__ModuleLoader__.load({
|
|
|
1563
1564
|
intentHistoryMaxCharsHelp: '對話摘錄的總字元上限(200–20000)。',
|
|
1564
1565
|
intentFallbackRouteLabel: '備援模型',
|
|
1565
1566
|
intentFallbackRouteHelp:
|
|
1566
|
-
'分類失敗時依次:上一輪實際路由 → 備援模型 →
|
|
1567
|
+
'分類失敗時依次:上一輪實際路由 → 備援模型 → 候選第一位;留空用候選第一位。可選固定思考等級;未指定時使用備援模型預設等級。',
|
|
1567
1568
|
intentRouteUnset: '未設定',
|
|
1568
1569
|
intentEffortFollow: '跟隨模型預設',
|
|
1569
1570
|
intentDockAuto: '自動',
|
|
@@ -1644,6 +1645,7 @@ window.__ModuleLoader__.load({
|
|
|
1644
1645
|
poolManualHelp: 'オンにするとリストの順序でディスパッチします(先頭=第一候補)。オフなら能力順で自動的に並びます。',
|
|
1645
1646
|
poolManualSelected: '選択済み · ディスパッチ優先順',
|
|
1646
1647
|
poolManualAddable: 'モデルを追加',
|
|
1648
|
+
poolMoveTop: '先頭へ',
|
|
1647
1649
|
poolMoveUp: '上へ',
|
|
1648
1650
|
poolMoveDown: '下へ',
|
|
1649
1651
|
poolRemoveOne: '削除',
|
|
@@ -1792,10 +1794,16 @@ window.__ModuleLoader__.load({
|
|
|
1792
1794
|
'会話抜粋の合計文字上限(200–20000)。',
|
|
1793
1795
|
intentFallbackRouteLabel: 'フォールバックモデル',
|
|
1794
1796
|
intentFallbackRouteHelp:
|
|
1795
|
-
'分類失敗時:前回ルート → フォールバック →
|
|
1797
|
+
'分類失敗時:前回ルート → フォールバック → 候補の先頭。空欄は候補の先頭。思考レベルを固定できます。未指定ならモデル既定を使用します。',
|
|
1796
1798
|
intentRouteUnset: '未設定',
|
|
1797
1799
|
intentEffortFollow: 'モデルのデフォルト',
|
|
1798
|
-
|
|
1800
|
+
trimEffortRecommended: '自動(モデル推奨)',
|
|
1801
|
+
trimSideModelLabel: '要約モデル',
|
|
1802
|
+
trimSideModelHelp: '要約に使うモデルルート。既定ではセッションモデルに従いますが、その呼び出しの思考レベルは引き継ぎません。段階的蒸留も同じルートを使います。手動指定がなければ、モデル情報から有効な思考レベルの最低段階を選びます。思考のオン/オフだけのモデルは off を選択します。非対応またはモデル情報がない場合はレベルを送らず、モデルの既定値を使います。',
|
|
1803
|
+
trimFollowSession: 'セッションモデルに従う',
|
|
1804
|
+
trimFoldFallbackModelLabel: '折りたたみ時のフォールバックモデル',
|
|
1805
|
+
trimFoldFallbackModelHelp: '要約モデルの呼び出しに失敗した場合、このモデルで再試行します。これも失敗すると、圧力折りたたみは機械的な折りたたみに切り替わります。思考レベルは個別に指定でき、未指定ならこのモデルの推奨設定を使います。冷却・リスク管理・同時実行の制限に余裕のあるモデルを選び、メインセッションと同じアカウントの共有は避けてください。空欄 = フォールバックなし。',
|
|
1806
|
+
trimFallbackUnset: '未設定(失敗時は機械的な折りたたみに直接移行)',
|
|
1799
1807
|
intentDockAuto: '自動',
|
|
1800
1808
|
intentDockUnrouted: '未ルーティング',
|
|
1801
1809
|
intentDockUsing: '使用中',
|
|
@@ -1875,6 +1883,7 @@ window.__ModuleLoader__.load({
|
|
|
1875
1883
|
poolManualHelp: '켜면 목록 순서대로 디스패치합니다(맨 앞이 제1순위). 끄면 능력 순으로 자동 정렬됩니다.',
|
|
1876
1884
|
poolManualSelected: '선택됨 · 디스패치 우선순위',
|
|
1877
1885
|
poolManualAddable: '모델 추가',
|
|
1886
|
+
poolMoveTop: '맨 위로',
|
|
1878
1887
|
poolMoveUp: '위로',
|
|
1879
1888
|
poolMoveDown: '아래로',
|
|
1880
1889
|
poolRemoveOne: '제거',
|
|
@@ -1934,7 +1943,13 @@ window.__ModuleLoader__.load({
|
|
|
1934
1943
|
'서브에이전트 자체 모델 창에 맞춰 3단계 축소: force = min(정적 기준, 창×비율). soft/hard도 같은 비율로 축소. 완화 없이 강화만.',
|
|
1935
1944
|
wmSubagentFollowForce: 'force 단계 따르기(0)',
|
|
1936
1945
|
wmCommands: '명령: /ctx-pause 수위 개입 일시 중지 · /ctx-resume 재개 · /ctx-handover 지금 핸드오버 문서를 작성하고 압축.',
|
|
1937
|
-
|
|
1946
|
+
trimEffortRecommended: '자동 (모델 권장)',
|
|
1947
|
+
trimSideModelLabel: '요약 모델',
|
|
1948
|
+
trimSideModelHelp: '요약에 사용할 모델 경로입니다. 기본값은 세션 모델을 따르지만 해당 호출의 추론 수준은 상속하지 않습니다. 단계별 증류도 같은 경로를 사용합니다. 수동 지정이 없으면 모델 메타데이터에서 활성화된 가장 낮은 추론 단계를 선택합니다. 추론 켜기/끄기만 지원하는 모델은 off를 선택합니다. 추론을 지원하지 않거나 메타데이터가 없으면 수준을 보내지 않고 모델 기본값을 사용합니다.',
|
|
1949
|
+
trimFollowSession: '세션 모델 따르기',
|
|
1950
|
+
trimFoldFallbackModelLabel: '접기 대체 모델',
|
|
1951
|
+
trimFoldFallbackModelHelp: '요약 모델 호출이 실패하면 이 모델로 재시도합니다. 이것도 실패하면 압력 접기는 기계적 접기로 전환됩니다. 추론 수준은 별도로 지정할 수 있으며, 비워 두면 이 모델의 권장 설정을 사용합니다. 쿨다운, 위험 제어, 동시성 제한에 여유가 있는 모델을 선택하고 주 세션과 같은 계정을 공유하지 않는 편이 좋습니다. 비우면 대체 경로가 없습니다.',
|
|
1952
|
+
trimFallbackUnset: '미설정(실패 시 바로 기계적 접기)',
|
|
1938
1953
|
trimSectionTitle: '컨텍스트 트림',
|
|
1939
1954
|
trimModeLabel: '트림 모드',
|
|
1940
1955
|
trimModeHelp:
|
|
@@ -2023,7 +2038,7 @@ window.__ModuleLoader__.load({
|
|
|
2023
2038
|
'대화 발췌의 총 문자 상한(200–20000).',
|
|
2024
2039
|
intentFallbackRouteLabel: '폴백 모델',
|
|
2025
2040
|
intentFallbackRouteHelp:
|
|
2026
|
-
'분류 실패 시: 이전 라우트 → 폴백 → 첫 후보.
|
|
2041
|
+
'분류 실패 시: 이전 라우트 → 폴백 → 첫 후보. 비어 있으면 첫 후보입니다. 추론 수준을 선택적으로 고정할 수 있으며, 지정하지 않으면 폴백 모델 기본값을 따릅니다.',
|
|
2027
2042
|
intentRouteUnset: '미설정',
|
|
2028
2043
|
intentEffortFollow: '모델 기본값',
|
|
2029
2044
|
intentDockAuto: '자동',
|
|
@@ -2105,6 +2120,7 @@ window.__ModuleLoader__.load({
|
|
|
2105
2120
|
poolManualHelp: 'Ein: Der Versand folgt der gelisteten Reihenfolge (oben = erste Wahl); aus: Lanes werden automatisch nach Fähigkeit sortiert.',
|
|
2106
2121
|
poolManualSelected: 'Ausgewählt · Dispatch-Priorität',
|
|
2107
2122
|
poolManualAddable: 'Modelle hinzufügen',
|
|
2123
|
+
poolMoveTop: 'Ganz nach oben',
|
|
2108
2124
|
poolMoveUp: 'Nach oben',
|
|
2109
2125
|
poolMoveDown: 'Nach unten',
|
|
2110
2126
|
poolRemoveOne: 'Entfernen',
|
|
@@ -2164,7 +2180,13 @@ window.__ModuleLoader__.load({
|
|
|
2164
2180
|
'Skaliert die Stufen auf das eigene Modellfenster des Subagenten: force = min(statische Stufe, Fenster × Quote); soft/hard schrumpfen im selben Faktor. Verengt nur, lockert nie.',
|
|
2165
2181
|
wmSubagentFollowForce: 'Der Force-Stufe folgen (0)',
|
|
2166
2182
|
wmCommands: 'Befehle: /ctx-pause pausiert Wasserstand-Aktionen · /ctx-resume setzt sie fort · /ctx-handover schreibt das Übergabedokument jetzt und komprimiert sofort.',
|
|
2167
|
-
|
|
2183
|
+
trimEffortRecommended: 'Automatisch (Modell-Empfehlung)',
|
|
2184
|
+
trimSideModelLabel: 'Zusammenfassungsmodell',
|
|
2185
|
+
trimSideModelHelp: 'Modellroute für Zusammenfassungen. Standardmäßig folgt sie dem Sitzungsmodell, übernimmt aber nicht dessen Denkstufe. Leiter-Destillationen verwenden dieselbe Route. Ohne manuelle Vorgabe wird anhand der Modellmetadaten die niedrigste aktivierte Denkstufe gewählt; bei Modellen mit reinem Ein/Aus-Schalter wird off gewählt. Bei fehlender Unterstützung oder Metadaten wird keine Denkstufe gesendet und der Modellstandard verwendet.',
|
|
2186
|
+
trimFollowSession: 'Sitzungsmodell folgen',
|
|
2187
|
+
trimFoldFallbackModelLabel: 'Fallback-Modell für Faltungen',
|
|
2188
|
+
trimFoldFallbackModelHelp: 'Wenn der Zusammenfassungsaufruf fehlschlägt, wird mit diesem Modell erneut versucht; schlägt auch das fehl, wird ein Druck-Fold mechanisch ausgeführt. Die Denkstufe kann unabhängig festgelegt werden; ohne Angabe greift die Modellempfehlung. Möglichst ein Modell ohne Cooldown-, Risiko- oder Parallelitätsbeschränkungen wählen und nicht dasselbe Konto wie die Hauptsitzung verwenden. Leer = kein Fallback.',
|
|
2189
|
+
trimFallbackUnset: 'Nicht festgelegt (bei Fehler direkt mechanisch falten)',
|
|
2168
2190
|
trimSectionTitle: 'Kontext-Trim',
|
|
2169
2191
|
trimModeLabel: 'Trim-Modus',
|
|
2170
2192
|
trimModeHelp:
|
|
@@ -2256,7 +2278,7 @@ window.__ModuleLoader__.load({
|
|
|
2256
2278
|
'Gesamtzeichengrenze des Gesprächsauszugs (200–20000).',
|
|
2257
2279
|
intentFallbackRouteLabel: 'Fallback-Modell',
|
|
2258
2280
|
intentFallbackRouteHelp:
|
|
2259
|
-
'Bei Klassifikationsfehler: zuletzt geroutet → Fallback → erster Kandidat; leer = erster Kandidat.',
|
|
2281
|
+
'Bei Klassifikationsfehler: zuletzt geroutet → Fallback → erster Kandidat; leer = erster Kandidat. Der Thinking-Aufwand kann optional festgelegt werden; andernfalls gilt der Modellstandard des Fallbacks.',
|
|
2260
2282
|
intentRouteUnset: 'Nicht festgelegt',
|
|
2261
2283
|
intentEffortFollow: 'Modellstandard',
|
|
2262
2284
|
intentDockAuto: 'Auto',
|
|
@@ -2338,6 +2360,7 @@ window.__ModuleLoader__.load({
|
|
|
2338
2360
|
poolManualHelp: 'Activado, el despacho sigue el orden de la lista (el primero es la primera opción); desactivado, los carriles se ordenan automáticamente por capacidad.',
|
|
2339
2361
|
poolManualSelected: 'Seleccionados · prioridad de despacho',
|
|
2340
2362
|
poolManualAddable: 'Añadir modelos',
|
|
2363
|
+
poolMoveTop: 'Mover al principio',
|
|
2341
2364
|
poolMoveUp: 'Subir',
|
|
2342
2365
|
poolMoveDown: 'Bajar',
|
|
2343
2366
|
poolRemoveOne: 'Quitar',
|
|
@@ -2397,7 +2420,13 @@ window.__ModuleLoader__.load({
|
|
|
2397
2420
|
'Escala los niveles a la ventana del propio modelo del subagente: force = min(nivel estático, ventana × ratio); soft/hard se reducen por el mismo factor. Solo restringe, nunca amplía.',
|
|
2398
2421
|
wmSubagentFollowForce: 'Seguir el nivel forzado (0)',
|
|
2399
2422
|
wmCommands: 'Comandos: /ctx-pause suspende las acciones del nivel · /ctx-resume las reanuda · /ctx-handover escribe el documento y compacta ahora.',
|
|
2400
|
-
|
|
2423
|
+
trimEffortRecommended: 'Automático (recomendación del modelo)',
|
|
2424
|
+
trimSideModelLabel: 'Modelo de resumen',
|
|
2425
|
+
trimSideModelHelp: 'Ruta del modelo para los resúmenes. De forma predeterminada sigue el modelo de la sesión, pero no hereda su nivel de razonamiento. Las destilaciones por niveles usan la misma ruta. Sin una selección manual, los metadatos del modelo determinan el nivel habilitado más bajo; si solo ofrece activar o desactivar el razonamiento, se elige off. Si no admite razonamiento o faltan metadatos, no se envía ningún nivel y se usa el valor predeterminado del modelo.',
|
|
2426
|
+
trimFollowSession: 'Seguir el modelo de la sesión',
|
|
2427
|
+
trimFoldFallbackModelLabel: 'Modelo de respaldo para el plegado',
|
|
2428
|
+
trimFoldFallbackModelHelp: 'Si falla la llamada al modelo de resumen, se reintenta con este modelo; si también falla, el plegado por presión pasa a ser mecánico. El nivel de razonamiento se puede fijar por separado; si se deja vacío, se aplica la recomendación de este modelo. Elige un modelo con margen en límites de enfriamiento, riesgo y concurrencia, y evita compartir cuenta con la sesión principal. Vacío = sin respaldo.',
|
|
2429
|
+
trimFallbackUnset: 'Sin configurar (si falla, pasar directamente al plegado mecánico)',
|
|
2401
2430
|
trimSectionTitle: 'Recorte de contexto',
|
|
2402
2431
|
trimModeLabel: 'Modo de recorte',
|
|
2403
2432
|
trimModeHelp:
|
|
@@ -2490,7 +2519,7 @@ window.__ModuleLoader__.load({
|
|
|
2490
2519
|
'Límite total de caracteres del extracto de conversación (200–20000).',
|
|
2491
2520
|
intentFallbackRouteLabel: 'Modelo de reserva',
|
|
2492
2521
|
intentFallbackRouteHelp:
|
|
2493
|
-
'Si falla la clasificación: último modelo enrutado → reserva → primer candidato; vacío = primer candidato.',
|
|
2522
|
+
'Si falla la clasificación: último modelo enrutado → reserva → primer candidato; vacío = primer candidato. Puedes fijar opcionalmente el nivel de razonamiento; si no, se usa el valor predeterminado del modelo de reserva.',
|
|
2494
2523
|
intentRouteUnset: 'Sin establecer',
|
|
2495
2524
|
intentEffortFollow: 'predeterminado del modelo',
|
|
2496
2525
|
intentDockAuto: 'Auto',
|
|
@@ -2572,6 +2601,7 @@ window.__ModuleLoader__.load({
|
|
|
2572
2601
|
poolManualHelp: 'Activé, le dispatch suit l’ordre affiché (la tête = premier choix) ; désactivé, les couloirs sont ordonnés par capacité automatiquement.',
|
|
2573
2602
|
poolManualSelected: 'Sélectionnés · priorité de dispatch',
|
|
2574
2603
|
poolManualAddable: 'Ajouter des modèles',
|
|
2604
|
+
poolMoveTop: 'Placer en tête',
|
|
2575
2605
|
poolMoveUp: 'Monter',
|
|
2576
2606
|
poolMoveDown: 'Descendre',
|
|
2577
2607
|
poolRemoveOne: 'Retirer',
|
|
@@ -2631,7 +2661,13 @@ window.__ModuleLoader__.load({
|
|
|
2631
2661
|
'Ajuste les paliers à la fenêtre propre du modèle du sous-agent : force = min(palier statique, fenêtre × ratio) ; soft/hard réduits du même facteur. Ne fait que resserrer, jamais relâcher.',
|
|
2632
2662
|
wmSubagentFollowForce: 'Suivre le palier force (0)',
|
|
2633
2663
|
wmCommands: 'Commandes : /ctx-pause suspend les actions de niveau d’eau · /ctx-resume les reprend · /ctx-handover écrit le document et compacte maintenant.',
|
|
2634
|
-
|
|
2664
|
+
trimEffortRecommended: 'Automatique (recommandation du modèle)',
|
|
2665
|
+
trimSideModelLabel: 'Modèle de résumé',
|
|
2666
|
+
trimSideModelHelp: 'Route du modèle pour les résumés. Par défaut, elle suit le modèle de la session sans reprendre son niveau de raisonnement. Les distillations en cascade utilisent la même route. Sans choix manuel, les métadonnées sélectionnent le niveau activé le plus faible ; pour un modèle avec seulement un interrupteur de raisonnement, le niveau choisi est off. Si le raisonnement est indisponible ou que les métadonnées manquent, aucun niveau n’est envoyé et le défaut du modèle s’applique.',
|
|
2667
|
+
trimFollowSession: 'Suivre le modèle de la session',
|
|
2668
|
+
trimFoldFallbackModelLabel: 'Modèle de secours pour le pliage',
|
|
2669
|
+
trimFoldFallbackModelHelp: 'Si l’appel au modèle de résumé échoue, une nouvelle tentative utilise ce modèle ; en cas de nouvel échec, un pliage sous pression devient mécanique. Le niveau de raisonnement se règle séparément ; sans choix, la recommandation de ce modèle s’applique. Choisissez un modèle avec de la marge sur le refroidissement, le contrôle des risques et la concurrence, et évitez le même compte que la session principale. Vide = aucun secours.',
|
|
2670
|
+
trimFallbackUnset: 'Non défini (en cas d’échec, passer directement au pliage mécanique)',
|
|
2635
2671
|
trimSectionTitle: 'Rognage du contexte',
|
|
2636
2672
|
trimModeLabel: 'Mode de rognage',
|
|
2637
2673
|
trimModeHelp:
|
|
@@ -2724,7 +2760,7 @@ window.__ModuleLoader__.load({
|
|
|
2724
2760
|
'Plafond total de caractères de l’extrait de conversation (200–20000).',
|
|
2725
2761
|
intentFallbackRouteLabel: 'Modèle de secours',
|
|
2726
2762
|
intentFallbackRouteHelp:
|
|
2727
|
-
'En cas d’échec : dernier modèle routé → secours → premier candidat ; vide = premier candidat.',
|
|
2763
|
+
'En cas d’échec : dernier modèle routé → secours → premier candidat ; vide = premier candidat. Vous pouvez épingler le niveau de raisonnement ; sinon, le niveau par défaut du modèle de secours est utilisé.',
|
|
2728
2764
|
intentRouteUnset: 'Non défini',
|
|
2729
2765
|
intentEffortFollow: 'par défaut du modèle',
|
|
2730
2766
|
intentDockAuto: 'Auto',
|
|
@@ -2806,6 +2842,7 @@ window.__ModuleLoader__.load({
|
|
|
2806
2842
|
poolManualHelp: 'Attivo, il dispatch segue l’ordine elencato (il primo della lista = prima scelta); spento, le corsie vengono ordinate per capacità automaticamente.',
|
|
2807
2843
|
poolManualSelected: 'Selezionati · priorità di dispatch',
|
|
2808
2844
|
poolManualAddable: 'Aggiungi modelli',
|
|
2845
|
+
poolMoveTop: 'Porta in cima',
|
|
2809
2846
|
poolMoveUp: 'Sposta su',
|
|
2810
2847
|
poolMoveDown: 'Sposta giù',
|
|
2811
2848
|
poolRemoveOne: 'Rimuovi',
|
|
@@ -2865,7 +2902,13 @@ window.__ModuleLoader__.load({
|
|
|
2865
2902
|
'Ridimensiona i livelli alla finestra del modello del subagente: force = min(livello statico, finestra × rapporto); soft/hard si riducono dello stesso fattore. Solo restrizione, mai allentamento.',
|
|
2866
2903
|
wmSubagentFollowForce: 'Segui la soglia force (0)',
|
|
2867
2904
|
wmCommands: 'Comandi: /ctx-pause sospende le azioni da livello dell’acqua · /ctx-resume le riprende · /ctx-handover scrive il documento e compatta subito.',
|
|
2868
|
-
|
|
2905
|
+
trimEffortRecommended: 'Automatico (consigliato dal modello)',
|
|
2906
|
+
trimSideModelLabel: 'Modello di riepilogo',
|
|
2907
|
+
trimSideModelHelp: 'Percorso del modello per i riepiloghi. Per impostazione predefinita segue il modello della sessione, senza ereditarne il livello di ragionamento. Anche le distillazioni a livelli usano lo stesso percorso. Senza una scelta manuale, i metadati determinano il livello attivo più basso; per i modelli con il solo interruttore on/off si usa off. Se il ragionamento non è supportato o mancano i metadati, non viene inviato alcun livello e si usa il valore predefinito del modello.',
|
|
2908
|
+
trimFollowSession: 'Segui il modello della sessione',
|
|
2909
|
+
trimFoldFallbackModelLabel: 'Modello di riserva per la piegatura',
|
|
2910
|
+
trimFoldFallbackModelHelp: 'Se la chiamata al modello di riepilogo fallisce, si riprova con questo modello; se fallisce anche questo, la piegatura sotto pressione diventa meccanica. Il livello di ragionamento si può impostare separatamente; se vuoto, si usa la raccomandazione del modello. Scegli un modello con margine per cooldown, controllo del rischio e concorrenza, evitando di condividere l’account con la sessione principale. Vuoto = nessun fallback.',
|
|
2911
|
+
trimFallbackUnset: 'Non impostato (in caso di errore, passa direttamente alla piegatura meccanica)',
|
|
2869
2912
|
trimSectionTitle: 'Riduzione del contesto',
|
|
2870
2913
|
trimModeLabel: 'Modalità di riduzione',
|
|
2871
2914
|
trimModeHelp:
|
|
@@ -2958,7 +3001,7 @@ window.__ModuleLoader__.load({
|
|
|
2958
3001
|
'Limite totale di caratteri dell’estratto della conversazione (200–20000).',
|
|
2959
3002
|
intentFallbackRouteLabel: 'Modello di riserva',
|
|
2960
3003
|
intentFallbackRouteHelp:
|
|
2961
|
-
'In caso di errore: ultimo modello instradato → riserva → primo candidato; vuoto = primo candidato.',
|
|
3004
|
+
'In caso di errore: ultimo modello instradato → riserva → primo candidato; vuoto = primo candidato. Puoi fissare il livello di ragionamento; se omesso, si usa il valore predefinito del modello di riserva.',
|
|
2962
3005
|
intentRouteUnset: 'Non impostato',
|
|
2963
3006
|
intentEffortFollow: 'predefinito del modello',
|
|
2964
3007
|
intentDockAuto: 'Auto',
|
|
@@ -3040,6 +3083,7 @@ window.__ModuleLoader__.load({
|
|
|
3040
3083
|
poolManualHelp: 'Ligado, o despacho segue a ordem listada (o primeiro = primeira escolha); desligado, as faixas são ordenadas por capacidade automaticamente.',
|
|
3041
3084
|
poolManualSelected: 'Selecionados · prioridade de despacho',
|
|
3042
3085
|
poolManualAddable: 'Adicionar modelos',
|
|
3086
|
+
poolMoveTop: 'Mover para o topo',
|
|
3043
3087
|
poolMoveUp: 'Mover para cima',
|
|
3044
3088
|
poolMoveDown: 'Mover para baixo',
|
|
3045
3089
|
poolRemoveOne: 'Remover',
|
|
@@ -3099,7 +3143,13 @@ window.__ModuleLoader__.load({
|
|
|
3099
3143
|
'Escala os níveis para a janela do próprio modelo do subagente: force = min(nível estático, janela × razão); soft/hard encolhem pelo mesmo fator. Apenas aperta, nunca afrouxa.',
|
|
3100
3144
|
wmSubagentFollowForce: 'Seguir o limiar force (0)',
|
|
3101
3145
|
wmCommands: 'Comandos: /ctx-pause suspende as ações de nível de água · /ctx-resume as retoma · /ctx-handover escreve o documento e compacta agora.',
|
|
3102
|
-
|
|
3146
|
+
trimEffortRecommended: 'Automático (recomendação do modelo)',
|
|
3147
|
+
trimSideModelLabel: 'Modelo de resumo',
|
|
3148
|
+
trimSideModelHelp: 'Rota do modelo para os resumos. Por padrão, segue o modelo da sessão, mas não herda o nível de raciocínio dessa chamada. As destilações em níveis usam a mesma rota. Sem escolha manual, os metadados selecionam o nível ativo mais baixo; para modelos com apenas a opção de ligar/desligar o raciocínio, usa-se off. Se o raciocínio não for compatível ou faltarem metadados, nenhum nível é enviado e vale o padrão do modelo.',
|
|
3149
|
+
trimFollowSession: 'Seguir o modelo da sessão',
|
|
3150
|
+
trimFoldFallbackModelLabel: 'Modelo de reserva para dobra',
|
|
3151
|
+
trimFoldFallbackModelHelp: 'Se a chamada do modelo de resumo falhar, tenta novamente com este modelo; se também falhar, a dobra por pressão passa a ser mecânica. O nível de raciocínio pode ser definido separadamente; se ficar vazio, usa-se a recomendação deste modelo. Escolha um modelo com margem para cooldown, controle de risco e concorrência, evitando compartilhar a conta com a sessão principal. Vazio = sem fallback.',
|
|
3152
|
+
trimFallbackUnset: 'Não configurado (em caso de falha, usar dobra mecânica diretamente)',
|
|
3103
3153
|
trimSectionTitle: 'Corte de contexto',
|
|
3104
3154
|
trimModeLabel: 'Modo de corte',
|
|
3105
3155
|
trimModeHelp:
|
|
@@ -3192,7 +3242,7 @@ window.__ModuleLoader__.load({
|
|
|
3192
3242
|
'Limite total de caracteres do trecho da conversa (200–20000).',
|
|
3193
3243
|
intentFallbackRouteLabel: 'Modelo de reserva',
|
|
3194
3244
|
intentFallbackRouteHelp:
|
|
3195
|
-
'Se a classificação falhar: último modelo roteado → reserva → primeiro candidato; vazio = primeiro candidato.',
|
|
3245
|
+
'Se a classificação falhar: último modelo roteado → reserva → primeiro candidato; vazio = primeiro candidato. É possível fixar o nível de raciocínio; se não definido, usa-se o padrão do modelo de reserva.',
|
|
3196
3246
|
intentRouteUnset: 'Não definido',
|
|
3197
3247
|
intentEffortFollow: 'padrão do modelo',
|
|
3198
3248
|
intentDockAuto: 'Auto',
|
|
@@ -3274,6 +3324,7 @@ window.__ModuleLoader__.load({
|
|
|
3274
3324
|
poolManualHelp: 'Включено — диспетчеризация идёт по списку (голова списка = первый выбор); выключено — полосы упорядочиваются по силе автоматически.',
|
|
3275
3325
|
poolManualSelected: 'Выбрано · приоритет диспетчеризации',
|
|
3276
3326
|
poolManualAddable: 'Добавить модели',
|
|
3327
|
+
poolMoveTop: 'В начало',
|
|
3277
3328
|
poolMoveUp: 'Выше',
|
|
3278
3329
|
poolMoveDown: 'Ниже',
|
|
3279
3330
|
poolRemoveOne: 'Убрать',
|
|
@@ -3333,7 +3384,13 @@ window.__ModuleLoader__.load({
|
|
|
3333
3384
|
'Масштабирует уровни под собственное окно модели субагента: force = min(статический уровень, окно × доля); soft/hard сжимаются на тот же коэффициент. Только ужесточает, не смягчает.',
|
|
3334
3385
|
wmSubagentFollowForce: 'Следовать линии force (0)',
|
|
3335
3386
|
wmCommands: 'Команды: /ctx-pause приостанавливает действия по уровню воды · /ctx-resume возобновляет их · /ctx-handover записывает документ передачи и сжимает прямо сейчас.',
|
|
3336
|
-
|
|
3387
|
+
trimEffortRecommended: 'Авто (рекомендация модели)',
|
|
3388
|
+
trimSideModelLabel: 'Модель сводки',
|
|
3389
|
+
trimSideModelHelp: 'Маршрут модели для сводок. По умолчанию следует модели сессии, но не наследует уровень рассуждения этого вызова. Для ступенчатой дистилляции используется тот же маршрут. Без ручного выбора метаданные задают самый низкий включённый уровень; для модели только с переключателем рассуждений выбирается off. Если рассуждения не поддерживаются или метаданных нет, уровень не передаётся и используется значение модели по умолчанию.',
|
|
3390
|
+
trimFollowSession: 'Следовать модели сессии',
|
|
3391
|
+
trimFoldFallbackModelLabel: 'Резервная модель сворачивания',
|
|
3392
|
+
trimFoldFallbackModelHelp: 'Если вызов модели сводки завершается ошибкой, повтор выполняется на этой модели; при повторном сбое сворачивание под давлением становится механическим. Уровень рассуждения задаётся отдельно; если не указан, действует рекомендация этой модели. Выбирайте модель с запасом по охлаждению, контролю рисков и параллельным запросам и не используйте общий аккаунт с главной сессией. Пусто = без резервного маршрута.',
|
|
3393
|
+
trimFallbackUnset: 'Не задано (при сбое сразу перейти к механическому сворачиванию)',
|
|
3337
3394
|
trimSectionTitle: 'Обрезка контекста',
|
|
3338
3395
|
trimModeLabel: 'Режим обрезки',
|
|
3339
3396
|
trimModeHelp:
|
|
@@ -3425,7 +3482,7 @@ window.__ModuleLoader__.load({
|
|
|
3425
3482
|
'Общий лимит символов выборки диалога (200–20000).',
|
|
3426
3483
|
intentFallbackRouteLabel: 'Резервная модель',
|
|
3427
3484
|
intentFallbackRouteHelp:
|
|
3428
|
-
'При сбое классификации: прошлая модель → резерв → первый кандидат; пусто = первый кандидат.',
|
|
3485
|
+
'При сбое классификации: прошлая модель → резерв → первый кандидат; пусто = первый кандидат. Можно задать уровень reasoning; если он не указан, используется значение резервной модели по умолчанию.',
|
|
3429
3486
|
intentRouteUnset: 'Не задано',
|
|
3430
3487
|
intentEffortFollow: 'по умолчанию модели',
|
|
3431
3488
|
intentDockAuto: 'Авто',
|
|
@@ -4613,6 +4670,7 @@ window.__ModuleLoader__.load({
|
|
|
4613
4670
|
onToggleManual,
|
|
4614
4671
|
onSetEffort,
|
|
4615
4672
|
onMove,
|
|
4673
|
+
onMoveTop,
|
|
4616
4674
|
onRemove,
|
|
4617
4675
|
onSelectAll,
|
|
4618
4676
|
onClear,
|
|
@@ -4774,6 +4832,20 @@ window.__ModuleLoader__.load({
|
|
|
4774
4832
|
h(
|
|
4775
4833
|
'div',
|
|
4776
4834
|
{ style: STYLE.rankActions },
|
|
4835
|
+
h(
|
|
4836
|
+
'button',
|
|
4837
|
+
{
|
|
4838
|
+
type: 'button',
|
|
4839
|
+
onClick: () => {
|
|
4840
|
+
onMoveTop(index);
|
|
4841
|
+
},
|
|
4842
|
+
disabled: !editable || index === 0,
|
|
4843
|
+
title: t('poolMoveTop'),
|
|
4844
|
+
'aria-label': t('poolMoveTop'),
|
|
4845
|
+
style: STYLE.iconButton,
|
|
4846
|
+
},
|
|
4847
|
+
'⤒',
|
|
4848
|
+
),
|
|
4777
4849
|
h(
|
|
4778
4850
|
'button',
|
|
4779
4851
|
{
|
|
@@ -5268,6 +5340,18 @@ window.__ModuleLoader__.load({
|
|
|
5268
5340
|
})));
|
|
5269
5341
|
}
|
|
5270
5342
|
|
|
5343
|
+
/** Manual order: move the route at index to the head of the
|
|
5344
|
+
* pool in one step (boundary-guarded: a no-op when already first). */
|
|
5345
|
+
function movePoolRouteToTop(field, index) {
|
|
5346
|
+
const pool = values[field];
|
|
5347
|
+
if (index <= 0 || index >= pool.length) return;
|
|
5348
|
+
const next = [pool[index], ...pool.slice(0, index), ...pool.slice(index + 1)];
|
|
5349
|
+
edit(field, next.map((route) => ({
|
|
5350
|
+
provider: route.provider,
|
|
5351
|
+
model: route.model,
|
|
5352
|
+
})));
|
|
5353
|
+
}
|
|
5354
|
+
|
|
5271
5355
|
/** Manual order: remove the route at index. */
|
|
5272
5356
|
function removePoolRoute(field, index) {
|
|
5273
5357
|
const next = [...values[field]];
|
|
@@ -5395,10 +5479,12 @@ window.__ModuleLoader__.load({
|
|
|
5395
5479
|
trimSideModel: {
|
|
5396
5480
|
provider: values.trimSideModel.provider,
|
|
5397
5481
|
model: values.trimSideModel.model,
|
|
5482
|
+
...(values.trimSideModel.effort ? { effort: values.trimSideModel.effort } : {}),
|
|
5398
5483
|
},
|
|
5399
5484
|
trimFoldFallbackModel: {
|
|
5400
5485
|
provider: values.trimFoldFallbackModel.provider,
|
|
5401
5486
|
model: values.trimFoldFallbackModel.model,
|
|
5487
|
+
...(values.trimFoldFallbackModel.effort ? { effort: values.trimFoldFallbackModel.effort } : {}),
|
|
5402
5488
|
},
|
|
5403
5489
|
trimStateDir: values.trimStateDir,
|
|
5404
5490
|
...Object.fromEntries(
|
|
@@ -5407,9 +5493,9 @@ window.__ModuleLoader__.load({
|
|
|
5407
5493
|
teamsMode: values.teamsMode,
|
|
5408
5494
|
syncWhitelist: values.syncWhitelist,
|
|
5409
5495
|
// Intent recognition (design: intent-routing.md §2): route
|
|
5410
|
-
// objects materialize {provider, model}
|
|
5411
|
-
//
|
|
5412
|
-
//
|
|
5496
|
+
// Route objects materialize {provider, model[, effort]} as configured;
|
|
5497
|
+
// the classifier route remains effort-free. Candidate effort/note are
|
|
5498
|
+
// always sent (blank string = unset; Host coerces per schema).
|
|
5413
5499
|
intentEnabled: values.intentEnabled,
|
|
5414
5500
|
intentClassifierRoute: {
|
|
5415
5501
|
provider: values.intentClassifierRoute.provider,
|
|
@@ -5434,6 +5520,7 @@ window.__ModuleLoader__.load({
|
|
|
5434
5520
|
intentFallbackRoute: {
|
|
5435
5521
|
provider: values.intentFallbackRoute.provider,
|
|
5436
5522
|
model: values.intentFallbackRoute.model,
|
|
5523
|
+
...(values.intentFallbackRoute.effort ? { effort: values.intentFallbackRoute.effort } : {}),
|
|
5437
5524
|
},
|
|
5438
5525
|
};
|
|
5439
5526
|
if (sameValues(current, desired)) {
|
|
@@ -5837,9 +5924,10 @@ window.__ModuleLoader__.load({
|
|
|
5837
5924
|
(meta) => meta.model === route.model,
|
|
5838
5925
|
);
|
|
5839
5926
|
edit(field, {
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5927
|
+
provider: next,
|
|
5928
|
+
model: kept ? route.model : '',
|
|
5929
|
+
effort: '',
|
|
5930
|
+
});
|
|
5843
5931
|
},
|
|
5844
5932
|
),
|
|
5845
5933
|
'aria-label': `${label} · provider`,
|
|
@@ -5853,7 +5941,7 @@ window.__ModuleLoader__.load({
|
|
|
5853
5941
|
`${intentId}-${field}-model`,
|
|
5854
5942
|
route.model,
|
|
5855
5943
|
(next) => {
|
|
5856
|
-
edit(field, { ...route, model: next });
|
|
5944
|
+
edit(field, { ...route, model: next, effort: '' });
|
|
5857
5945
|
},
|
|
5858
5946
|
),
|
|
5859
5947
|
disabled: !editable || route.provider === '',
|
|
@@ -5861,6 +5949,16 @@ window.__ModuleLoader__.load({
|
|
|
5861
5949
|
},
|
|
5862
5950
|
...intentModelOptions(route.provider, route.model),
|
|
5863
5951
|
),
|
|
5952
|
+
field === 'intentFallbackRoute' && route.provider !== '' && route.model !== ''
|
|
5953
|
+
? intentEffortSelect(
|
|
5954
|
+
`${intentId}-${field}-effort`,
|
|
5955
|
+
route,
|
|
5956
|
+
route.effort ?? '',
|
|
5957
|
+
(next) => edit(field, { ...route, effort: next }),
|
|
5958
|
+
`${label} · effort`,
|
|
5959
|
+
t('intentEffortFollow'),
|
|
5960
|
+
)
|
|
5961
|
+
: null,
|
|
5864
5962
|
);
|
|
5865
5963
|
};
|
|
5866
5964
|
/** Trim route rows reuse the intent route picker machinery — the
|
|
@@ -5912,6 +6010,7 @@ window.__ModuleLoader__.load({
|
|
|
5912
6010
|
...route,
|
|
5913
6011
|
provider: next,
|
|
5914
6012
|
model: kept ? route.model : '',
|
|
6013
|
+
effort: '',
|
|
5915
6014
|
});
|
|
5916
6015
|
},
|
|
5917
6016
|
),
|
|
@@ -5925,10 +6024,10 @@ window.__ModuleLoader__.load({
|
|
|
5925
6024
|
: route.model,
|
|
5926
6025
|
(next) => {
|
|
5927
6026
|
if (followMode && next === TRIM_ROUTE_FOLLOW) {
|
|
5928
|
-
edit(field, { ...route, model: '' });
|
|
6027
|
+
edit(field, { ...route, model: '', effort: '' });
|
|
5929
6028
|
return;
|
|
5930
6029
|
}
|
|
5931
|
-
edit(field, { ...route, model: next });
|
|
6030
|
+
edit(field, { ...route, model: next, effort: '' });
|
|
5932
6031
|
},
|
|
5933
6032
|
),
|
|
5934
6033
|
disabled: !editable || route.provider === '',
|
|
@@ -5938,10 +6037,10 @@ window.__ModuleLoader__.load({
|
|
|
5938
6037
|
? intentEffortSelect(
|
|
5939
6038
|
`${trimId}-${field}-effort`,
|
|
5940
6039
|
route,
|
|
5941
|
-
route.effort,
|
|
6040
|
+
route.effort ?? '',
|
|
5942
6041
|
(next) => edit(field, { ...route, effort: next }),
|
|
5943
6042
|
`${label} · effort`,
|
|
5944
|
-
t('
|
|
6043
|
+
t('trimEffortRecommended'),
|
|
5945
6044
|
)
|
|
5946
6045
|
: null,
|
|
5947
6046
|
);
|
|
@@ -5950,8 +6049,8 @@ window.__ModuleLoader__.load({
|
|
|
5950
6049
|
* wire efforts when the catalog reports them, the EFFORTS
|
|
5951
6050
|
* fallback otherwise; '' = adapter default. A stored value
|
|
5952
6051
|
* missing from the list stays selectable. emptyLabel replaces
|
|
5953
|
-
* the '' option label
|
|
5954
|
-
* the model default
|
|
6052
|
+
* the '' option label. Trim rows use their automatic recommendation;
|
|
6053
|
+
* an empty intent-fallback pin follows the model default. */
|
|
5955
6054
|
const intentEffortSelect = (
|
|
5956
6055
|
id,
|
|
5957
6056
|
route,
|
|
@@ -6383,6 +6482,9 @@ window.__ModuleLoader__.load({
|
|
|
6383
6482
|
onMove: (index, delta) => {
|
|
6384
6483
|
movePoolRoute(field, index, delta);
|
|
6385
6484
|
},
|
|
6485
|
+
onMoveTop: (index) => {
|
|
6486
|
+
movePoolRouteToTop(field, index);
|
|
6487
|
+
},
|
|
6386
6488
|
onRemove: (index) => {
|
|
6387
6489
|
removePoolRoute(field, index);
|
|
6388
6490
|
},
|
package/host/config.js
CHANGED
|
@@ -67,10 +67,9 @@ export const IntentCandidateSchema = z.object({
|
|
|
67
67
|
* ModelRouteSchema this accepts the "unset" `{provider:"", model:""}`
|
|
68
68
|
* pair the settings page round-trips — ModelRouteSchema's `.min(1)`
|
|
69
69
|
* would reject that exact declared default on every settings write.
|
|
70
|
-
* Consumers validate non-empty before trusting the route. effort
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* intent-layer routes leave it unset. */
|
|
70
|
+
* Consumers validate non-empty before trusting the route. `effort` is an
|
|
71
|
+
* optional override for summary routes and intent fallback; the classifier
|
|
72
|
+
* route remains effort-free in its route cleaner. */
|
|
74
73
|
const IntentRouteSchema = z.object({
|
|
75
74
|
provider: z.string(),
|
|
76
75
|
model: z.string(),
|
|
@@ -240,8 +239,9 @@ export const Config = z.object({
|
|
|
240
239
|
* the 0.8×-window auto-compaction (see effectiveContextWindow in
|
|
241
240
|
* host/intent.js). */
|
|
242
241
|
intentContextWindow: z.number().min(1024).default(200000).volatile(),
|
|
243
|
-
/** Optional
|
|
244
|
-
*
|
|
242
|
+
/** Optional fallback route after classification fails when no prior route
|
|
243
|
+
* is available; empty = the first candidate. An optional effort pin
|
|
244
|
+
* overrides the fallback model's default. */
|
|
245
245
|
intentFallbackRoute: IntentRouteSchema.default({ provider: "", model: "" }).volatile(),
|
|
246
246
|
|
|
247
247
|
// --- Context trim: fully-automatic conversation compression ------------
|
|
@@ -292,12 +292,14 @@ export const Config = z.object({
|
|
|
292
292
|
* budget and the ladder starved. */
|
|
293
293
|
trimMaxFoldsPerHour: z.number().min(1).max(60).default(30).volatile(),
|
|
294
294
|
/** Route for the side-model summarizer (L3). Empty = inherit the
|
|
295
|
-
* session's current model
|
|
295
|
+
* session's current provider/model; an optional effort pin overrides
|
|
296
|
+
* the model's automatic recommended effort. */
|
|
296
297
|
trimSideModel: IntentRouteSchema.default({ provider: "", model: "" }).volatile(),
|
|
297
298
|
/** Route for the fold-fallback summarizer. When the primary side route
|
|
298
299
|
* (trimSideModel or the inherited session model) fails, raw folds retry
|
|
299
300
|
* on this route before degrading to a mechanical fold; ladder folds
|
|
300
|
-
* retry but never go mechanical.
|
|
301
|
+
* retry but never go mechanical. An optional effort pin overrides the
|
|
302
|
+
* model's automatic recommendation. Pick a route with headroom on cooldown,
|
|
301
303
|
* risk-control, and concurrency limits. Empty = no fallback leg. */
|
|
302
304
|
trimFoldFallbackModel: IntentRouteSchema.default({ provider: "", model: "" }).volatile(),
|
|
303
305
|
/** T1/T2/T3 ladder folding (docs/ladder-fold.md): master switch for the
|