dsh-strata-sync 0.10.10 → 0.10.12
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.md +2 -0
- package/dist/client.js +3 -3
- package/dist/core.mjs +4 -1
- package/docs/CAPABILITIES.md +7 -4
- package/docs/README.zh-CN.md +2 -0
- package/docs/README.zh-TW.md +2 -0
- package/docs/VALIDATION.md +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,6 +65,8 @@ Existing conversations keep their selected model route and preset revision. To m
|
|
|
65
65
|
|
|
66
66
|
Keep **Follow Strata output limit** enabled for automatic selection. Turn it off to set a manual override under **Advanced settings**. The preview shows the server default, effective value and source separately.
|
|
67
67
|
|
|
68
|
+
Quantization does not change the choices for a verified model family: Qwen3.8 Flash Next offers `off / low / medium / xhigh`; the current DeepSeek Flash template offers `off / low / medium / high / max` and defaults to `high`. Older verified templates keep their supported choices. Sync updates the available choices without changing the selected effort. See [verified capabilities](https://github.com/ethan741205/dsh-strata-sync/blob/main/docs/CAPABILITIES.md).
|
|
69
|
+
|
|
68
70
|
The fallback follows [Strata's local output formula](https://github.com/Niko1221/Strata/blob/main/apps/host/server/agent/profile.mjs): `max(4096, min(32768, floor(context × 0.3)))`.
|
|
69
71
|
|
|
70
72
|
When synchronizing, the plugin normally sets a 4,096-token summary output cap and compaction headroom. For small windows using calculated output, both are limited to half the remaining conversation budget, rounded down; an 8K window therefore uses 2,048. The effective compaction trigger is the smaller of **80% of context** and **context − response output − headroom**. Recent-content retention is **(context − response output) × 16%**, rounded down. These compaction budgets are calculated by the plugin, not supplied by Strata.
|
package/dist/client.js
CHANGED
|
@@ -406,8 +406,8 @@ window.__ModuleLoader__.load({
|
|
|
406
406
|
model: 'Model', modelId: 'Model', defaultModel: 'Default model',
|
|
407
407
|
thresholdRatio: 'Compaction ratio ceiling', retainRatio: 'Recent conversation retention ratio',
|
|
408
408
|
};
|
|
409
|
-
const css = `.strata-sync{max-width:880px;color:inherit;font:inherit;line-height:1.6}.strata-sync *{box-sizing:border-box}.strata-sync header{
|
|
410
|
-
const workflowCss = ".strata-sync h3{font-size:16px;margin:0 0 8px}.strata-sync .ss-workflow{border:1px solid #21867b66;border-radius:10px;padding:20px;margin-bottom:18px}.strata-sync .ss-workflow>p:first-of-type{margin:0 0 16px}.strata-sync .ss-steps{display:flex;flex-wrap:wrap;gap:10px 20px;list-style:none;margin:0 0 20px;padding:0;font-size:13px}.strata-sync .ss-steps li{display:flex;align-items:center;gap:7px;opacity:.65}.strata-sync .ss-steps li[aria-current]{opacity:1;font-weight:600}.strata-sync .ss-step-number{display:inline-grid;place-items:center;width:25px;height:25px;flex-shrink:0;border:1px solid #8885;border-radius:50%;font-variant-numeric:tabular-nums}.strata-sync [aria-current] .ss-step-number{background:#126c65;color:#fff;border-color:#126c65}.strata-sync .ss-options>summary{cursor:pointer;font-size:14px}.strata-sync .ss-option-title::marker{color:#888}.strata-sync .ss-option-title>span:first-child{font-weight:600}.strata-sync .ss-badge{display:inline-block;margin-left:10px;padding:1px 7px;border:1px solid #8884;border-radius:5px;font-size:11px;vertical-align:middle}.strata-sync .ss-option-description{display:inline-block;margin-left:12px;opacity:.65;font-size:12px}.strata-sync button:focus-visible,.strata-sync summary:focus-visible,.strata-sync select:focus-visible{outline:2px solid #21867b;outline-offset:3px}@media(max-width:520px){.strata-sync .ss-workflow{padding:14px}.strata-sync .ss-option-description{display:block;margin-left:16px;margin-top:3px}.strata-sync .ss-steps{gap:8px 12px}}";
|
|
409
|
+
const css = `.strata-sync{max-width:880px;color:inherit;font:inherit;line-height:1.6}.strata-sync *{box-sizing:border-box}.strata-sync header{margin-bottom:8px}.strata-sync header p{margin:8px 0 0}.strata-sync h2{margin:0;font-size:22px}.strata-sync .ss-muted{opacity:.72;font-size:13px}.strata-sync .ss-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px}.strata-sync label{display:flex;flex-direction:column;gap:5px;font-size:14px}.strata-sync select,.strata-sync input[type=number],.strata-sync textarea{padding:9px;border:1px solid #8886;border-radius:7px;background:transparent;color:inherit;width:100%}.strata-sync textarea{resize:vertical;min-height:112px;font:inherit;line-height:1.5}.strata-sync .ss-prompt-label{margin:12px 0 8px}.strata-sync option{color:#17252b;background:#fff}.strata-sync button{padding:9px 15px;border:1px solid #8885;border-radius:7px;background:transparent;color:inherit;cursor:pointer}.strata-sync button.primary{background:#126c65;border-color:#126c65;color:#fff}.strata-sync button:disabled{opacity:.45;cursor:default}.strata-sync .ss-actions{display:flex;gap:9px;flex-wrap:wrap;margin:18px 0}.strata-sync .ss-check{display:flex;flex-direction:row;align-items:center;margin-top:13px}.strata-sync .ss-card{padding:16px;border:1px solid #8884;border-radius:9px;margin:16px 0}.strata-sync .ss-status{padding:10px 13px;border-left:3px solid #21867b;background:#21867b12;margin:13px 0;overflow-wrap:anywhere}.strata-sync .ss-error{border-color:#ce7140;background:#ce714012}.strata-sync table{width:100%;border-collapse:collapse;font-size:14px}.strata-sync td,.strata-sync th{padding:9px 8px;text-align:left;border-bottom:1px solid #8883;overflow-wrap:anywhere}.strata-sync code{font-size:12px;overflow-wrap:anywhere}.strata-sync .ss-scroll{overflow-x:auto;container-type:inline-size;border:1px solid #8883;border-radius:8px;margin-top:16px}.strata-sync table{table-layout:fixed}.strata-sync th,.strata-sync td{vertical-align:top;padding:12px;line-height:1.5}.strata-sync thead th{font-size:12px;font-weight:600;background:#8881}.strata-sync th:first-child{width:34%}.strata-sync thead th:not(:first-child){width:33%;text-align:right}.strata-sync tbody th{font-weight:500}.strata-sync tbody tr:last-child>*{border-bottom:0}.strata-sync .ss-before,.strata-sync .ss-after{text-align:right;font-variant-numeric:tabular-nums}.strata-sync .ss-before{color:inherit;opacity:.7}.strata-sync .ss-after{background:#21867b0b;font-weight:600}.strata-sync .ss-target{display:block;font-size:11px;font-weight:400;opacity:.65;margin-top:5px;overflow-wrap:anywhere}.strata-sync .ss-values{display:flex;gap:5px;flex-wrap:wrap;justify-content:flex-end}.strata-sync .ss-chip{display:inline-block;padding:2px 7px;border:1px solid #8883;border-radius:5px;font-size:12px;font-weight:400;max-width:100%;overflow-wrap:anywhere}.strata-sync .ss-details{text-align:left;font-weight:400;font-size:12px}.strata-sync .ss-details summary{cursor:pointer;overflow-wrap:anywhere}.strata-sync .ss-details pre{white-space:pre-wrap;overflow-wrap:anywhere;margin:8px 0 0;font-size:11px;line-height:1.5}.strata-sync .ss-empty{font-weight:400;font-size:12px;opacity:.65}@container(max-width:440px){.strata-sync tbody th:first-child{width:100%}.strata-sync table,.strata-sync tbody,.strata-sync tr,.strata-sync tbody th,.strata-sync td{display:block;width:100%}.strata-sync thead{display:none}.strata-sync tbody tr{padding:10px 12px;border-bottom:1px solid #8883}.strata-sync tbody th,.strata-sync td{border:0;padding:5px 0}.strata-sync td::before{content:attr(data-label);float:left;font-size:12px;font-weight:400;opacity:.7}.strata-sync td{display:flow-root;padding:7px}.strata-sync .ss-values{max-width:72%;margin-left:auto}.strata-sync .ss-details{margin-top:24px}}`;
|
|
410
|
+
const workflowCss = ".strata-sync h3{font-size:16px;margin:0 0 8px}.strata-sync .ss-workflow{border:1px solid #21867b66;border-radius:10px;padding:20px;margin-bottom:18px}.strata-sync .ss-workflow>h3:first-child{margin-top:0}.strata-sync .ss-workflow>p:first-of-type{margin:0 0 16px}.strata-sync .ss-steps{display:flex;flex-wrap:wrap;gap:10px 20px;list-style:none;margin:0 0 20px;padding:0;font-size:13px}.strata-sync .ss-steps li{display:flex;align-items:center;gap:7px;opacity:.65}.strata-sync .ss-steps li[aria-current]{opacity:1;font-weight:600}.strata-sync .ss-step-number{display:inline-grid;place-items:center;width:25px;height:25px;flex-shrink:0;border:1px solid #8885;border-radius:50%;font-variant-numeric:tabular-nums}.strata-sync [aria-current] .ss-step-number{background:#126c65;color:#fff;border-color:#126c65}.strata-sync .ss-options>summary{cursor:pointer;font-size:14px}.strata-sync .ss-option-title::marker{color:#888}.strata-sync .ss-option-title>span:first-child{font-weight:600}.strata-sync .ss-badge{display:inline-block;margin-left:10px;padding:1px 7px;border:1px solid #8884;border-radius:5px;font-size:11px;vertical-align:middle}.strata-sync .ss-option-description{display:inline-block;margin-left:12px;opacity:.65;font-size:12px}.strata-sync button:focus-visible,.strata-sync summary:focus-visible,.strata-sync select:focus-visible{outline:2px solid #21867b;outline-offset:3px}@media(max-width:520px){.strata-sync .ss-workflow{padding:14px}.strata-sync .ss-option-description{display:block;margin-left:16px;margin-top:3px}.strata-sync .ss-steps{gap:8px 12px}}";
|
|
411
411
|
const fmt = (v) => v == null ? 'Not set' : typeof v === 'number' ? v.toLocaleString('en-US') : typeof v === 'object' ? JSON.stringify(v) : String(v);
|
|
412
412
|
const warningText = {
|
|
413
413
|
INPUT_UNCONFIRMED: 'Input types are missing or unsupported in server metadata. Existing input settings are preserved.',
|
|
@@ -540,7 +540,7 @@ REASONING_DEFAULT_CONFLICT: 'The provider default reasoning level is not support
|
|
|
540
540
|
['missing','unlimited'].includes(preview.server?.model?.outputLimitStatus)&&h('p',{className:'ss-muted'},t('Server has no fixed output limit.')),
|
|
541
541
|
['unavailable','unverified'].includes(preview.server?.model?.outputLimitStatus)&&h('p',{className:'ss-muted'},t('Server output limit could not be verified.')),
|
|
542
542
|
h('p',null,t('Input types'),': ',preview.server?.model?.capabilities?.input?t(preview.server.model.capabilities.input.includes('image')?'Text + image':'Text'):t('Unconfirmed — keep current setting')),
|
|
543
|
-
h('p',
|
|
543
|
+
h('p',{'data-testid':'reasoning-levels'},t('Reasoning levels'),': ',preview.capabilityEdits?.reasoningEfforts?Object.keys(preview.capabilityEdits.reasoningEfforts).join(' / '):t('Unconfirmed — keep current setting')),
|
|
544
544
|
preview.capabilityEdits?.reasoningEfforts&&h('p',{className:'ss-muted'},t('Verified template: '),preview.server?.model?.capabilities?.reasoning?.family),
|
|
545
545
|
h('p',{className:'ss-muted'},t('Only verified capabilities are synchronized. Unknown fields keep their existing values. Reasoning choices do not change the selected effort.')),
|
|
546
546
|
h('p',{className:'ss-muted'},t('Context source: '),preview.server?.model?.contextSource||t('Server model metadata')),
|
package/dist/core.mjs
CHANGED
|
@@ -22,6 +22,9 @@ const TEMPLATE_PROFILES = {
|
|
|
22
22
|
'6f9bd1f87d9dad376b4c79683934b4254396d826ae514ab0244efa904ce1d1a4': {
|
|
23
23
|
family: 'DeepSeek-V4.1-Flash', efforts: { off: 'none', low: 'low', high: 'high', max: 'max' },
|
|
24
24
|
},
|
|
25
|
+
'06cada875e3a04665f9cf47deae9ef32e16ede2c6511205a4031c8b48140d01b': {
|
|
26
|
+
family: 'DeepSeek-V4.1-Flash', efforts: { off: 'none', low: 'low', medium: 'medium', high: 'high', max: 'max' },
|
|
27
|
+
},
|
|
25
28
|
};
|
|
26
29
|
|
|
27
30
|
export function planModelCapabilities(modalities, evidence = {}) {
|
|
@@ -259,7 +262,7 @@ export async function discoverStrata(baseURL, apiKey = '', options = {}) {
|
|
|
259
262
|
try {
|
|
260
263
|
props = await readJSON(`${normalized.slice(0, -3)}/props?model=${encodeURIComponent(selected.id)}`, apiKey, request);
|
|
261
264
|
evidence = {
|
|
262
|
-
verifiedStrata: typeof props.build_info === 'string' && /^Strata
|
|
265
|
+
verifiedStrata: typeof props.build_info === 'string' && /^Strata (?:ds4-)?\d+\.\d+(?:\.\d+)?(?:\b|$)/u.test(props.build_info),
|
|
263
266
|
modelMatched: selectedIds.has(props.model_alias),
|
|
264
267
|
templateHash: typeof props.chat_template === 'string'
|
|
265
268
|
? createHash('sha256').update(props.chat_template.replace(/\r\n/g, '\n')).digest('hex') : null,
|
package/docs/CAPABILITIES.md
CHANGED
|
@@ -8,16 +8,19 @@ The selected `/v1/models` row must explicitly report `architecture.input_modalit
|
|
|
8
8
|
|
|
9
9
|
## Reasoning choices
|
|
10
10
|
|
|
11
|
-
The optional, authenticated `GET /props?model=...` response must identify Strata in `build_info
|
|
11
|
+
The optional, authenticated `GET /props?model=...` response must identify Strata in `build_info` (including the DeepSeek engine's `Strata ds4-0.1` format), match the selected canonical model or one of its validated loaded aliases in `model_alias`, and return a reviewed `chat_template`. Aliases must resolve through `alias_of` to that loaded canonical text model. An alias belonging to another model is not accepted. The SHA-256 fingerprint is calculated after CRLF-to-LF normalization. Names, quantization labels, and a template merely mentioning reasoning are insufficient. Only matching fingerprints enable automatic reasoning synchronization.
|
|
12
12
|
|
|
13
13
|
| Reviewed template | SHA-256 | DSH selection → template value |
|
|
14
14
|
|---|---|---|
|
|
15
15
|
| Qwen3.8-Flash-Next, checked on Huihui v2 UD-IQ4_XS | `12827f24b742ea4e80cdc12dbcf9622227056b9f797252a3149263d4f9aaadce` | `low → low`, `medium → medium`, `xhigh → xhigh` |
|
|
16
|
-
| DeepSeek-V4.1-Flash,
|
|
16
|
+
| DeepSeek-V4.1-Flash, current served template | `06cada875e3a04665f9cf47deae9ef32e16ede2c6511205a4031c8b48140d01b` | `low → low`, `medium → medium`, `high → high`, `max → max` |
|
|
17
|
+
| DeepSeek-V4.1-Flash, legacy pack template | `6f9bd1f87d9dad376b4c79683934b4254396d826ae514ab0244efa904ce1d1a4` | `low → low`, `high → high`, `max → max` |
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
Every profile includes `off` as an explicit thinking-disabled choice. The current DeepSeek template maps low/medium/high/max to 50/62/75/100 internally and defaults to high. The legacy template lacks named `medium`; this is a template-version difference, not a quantization policy. Numeric 1–100 efforts are not exposed because DSH's selector uses named levels. No duplicate high/max aliases are added to Qwen.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
Quantization names do not select effort options. Qwen variants sharing its reviewed template receive `off / low / medium / xhigh`; DeepSeek variants sharing the current served template receive `off / low / medium / high / max`. The same rule applies to Huihui variants. Unknown templates preserve existing settings rather than guessing from a familiar model or quantization label.
|
|
22
|
+
|
|
23
|
+
Inspection date: 2026-10-30. Qwen and the current DeepSeek template were read from the running server's `/props`; the legacy DeepSeek template was inspected from installed packs. The current server reports `Strata ds4-0.1`, the loaded canonical DeepSeek ID, 65,536 context and unlimited default output. Metadata-only discovery was verified against that snapshot. This verifies template support, not model output quality. Template bytes and private configuration are not distributed with the plugin. Any changed or unreviewed template keeps existing reasoning settings, even if its filename is familiar.
|
|
21
24
|
|
|
22
25
|
## Native DSH dispatch
|
|
23
26
|
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -65,6 +65,8 @@ dsh plugin --profile desktop add dsh-strata-sync --registry=https://registry.npm
|
|
|
65
65
|
|
|
66
66
|
保持**输出上限跟随 Strata**开启,即可自动选择。关闭后可在**高级设置**输入手动覆盖值。预览会分别显示服务器默认值、实际应用值及其来源。
|
|
67
67
|
|
|
68
|
+
量化版本不改变已验证模型家族的选项:Qwen3.8 Flash Next 提供 `off / low / medium / xhigh`;当前 DeepSeek Flash 模板提供 `off / low / medium / high / max`,原生默认是 `high`。旧模板仍采用其实际支持的选项;同步只更新可选等级,不改变当前选择。详见[已验证的能力](https://github.com/ethan741205/dsh-strata-sync/blob/main/docs/CAPABILITIES.md)。
|
|
69
|
+
|
|
68
70
|
自动计算采用 [Strata 官方输出公式](https://github.com/Niko1221/Strata/blob/main/apps/host/server/agent/profile.mjs):`max(4096, min(32768, floor(context × 0.3)))`。
|
|
69
71
|
|
|
70
72
|
同步时,摘要输出上限和压缩余量通常均为 4,096 tokens。小窗口使用自动计算输出时,两者最多为剩余对话预算的一半,向下取整;因此 8K 窗口使用 2,048。实际压缩阈值取**上下文的 80%**与**上下文 − 回复输出预算 − 压缩余量**中的较小值,近期内容保留量为 **(上下文 − 回复输出预算)× 16%**,向下取整。这些压缩预算由插件计算,并非 Strata 提供的设置。
|
package/docs/README.zh-TW.md
CHANGED
|
@@ -65,6 +65,8 @@ dsh plugin --profile desktop add dsh-strata-sync --registry=https://registry.npm
|
|
|
65
65
|
|
|
66
66
|
保持**輸出上限跟隨 Strata**開啟,即可自動選擇。關閉後可在**進階設定**輸入手動覆寫值。預覽會分別顯示伺服器預設值、實際套用值及其來源。
|
|
67
67
|
|
|
68
|
+
量化版本不改變已驗證模型家族的選項:Qwen3.8 Flash Next 提供 `off / low / medium / xhigh`;目前 DeepSeek Flash 範本提供 `off / low / medium / high / max`,原生預設是 `high`。舊範本仍採用其實際支援的選項;同步只更新可選等級,不改變目前選擇。詳見[已驗證的能力](https://github.com/ethan741205/dsh-strata-sync/blob/main/docs/CAPABILITIES.md)。
|
|
69
|
+
|
|
68
70
|
自動計算採用 [Strata 官方輸出公式](https://github.com/Niko1221/Strata/blob/main/apps/host/server/agent/profile.mjs):`max(4096, min(32768, floor(context × 0.3)))`。
|
|
69
71
|
|
|
70
72
|
同步時,摘要輸出上限和壓縮餘裕通常均為 4,096 tokens。小視窗使用自動計算輸出時,兩者最多為剩餘對話預算的一半,向下取整;因此 8K 視窗使用 2,048。實際壓縮門檻取**上下文的 80%**與**上下文 − 回覆輸出預算 − 壓縮餘裕**中的較小值,近期內容保留量為 **(上下文 − 回覆輸出預算)× 16%**,向下取整。這些壓縮預算由外掛計算,並非 Strata 提供的設定。
|
package/docs/VALIDATION.md
CHANGED
|
@@ -11,13 +11,17 @@ Validation date: 2026-10-30 (Asia/Taipei).
|
|
|
11
11
|
|
|
12
12
|
## Automated verification
|
|
13
13
|
|
|
14
|
-
All **
|
|
14
|
+
All **171 automated tests pass** for the current runtime. Coverage includes:
|
|
15
|
+
|
|
16
|
+
- Current DeepSeek recognition accepts the `Strata ds4-0.1` build format and the reviewed served-template fingerprint. Unknown/malformed identities, wrong model aliases and unreviewed templates remain unconfirmed. Both legacy DeepSeek choices and the new `medium` choice are covered.
|
|
17
|
+
- Authenticated metadata-only checks against the running DeepSeek Huihui 2.00 bpw server confirmed 65,536 context, unlimited server output, a 19,660-token fallback, text/image input and `off / low / medium / high / max`, without warnings or configuration changes. No inference request was sent.
|
|
18
|
+
- Qwen and current DeepSeek retain their respective family choices across quantization labels. The three-language UI shows every current DeepSeek option, including `medium`, without introducing Qwen's `xhigh`.
|
|
15
19
|
|
|
16
20
|
- Automatic output matches Strata's 30% formula with a 4,096 floor and 32,768 ceiling. Tests cover 8K through 1M contexts, rounding at the ceiling, unchanged server/manual precedence, valid small-window compaction budgets and all three UI translations. The 8K calculated-output case limits compaction headroom and summary cap to 2,048; 32K and larger retain 4,096.
|
|
17
21
|
|
|
18
22
|
- Actual pi-ai context clamping across multiple input sizes, near-full and exhausted context, independent source length, additional prompt costs, disabled-mode zero discovery and restored native requests.
|
|
19
23
|
- Native Cordis waterfall dispatch, immutable messages, concurrent summaries, duplicate hooks, cancellation, metadata failures, early stream closure, native errors and unload.
|
|
20
|
-
- Verified model discovery, selected-provider/loaded-model matching, alias validation, input types, model-specific reasoning choices and
|
|
24
|
+
- Verified model discovery, selected-provider/loaded-model matching, alias validation, input types, model-specific reasoning choices and thirteen mocked SDK wire cases. Off sends false thinking flags and omits the effort; other choices send true and their exact native effort name. These cases validate request mapping, not generated-answer quality.
|
|
21
25
|
- Preference validation, synchronization write guards, stale-preview rejection, concurrent edits, backup and rollback, startup synchronization, hot reload and enabled Agent preset policies.
|
|
22
26
|
- Synchronization during suspended generation and summary streams, including maintenance status, uses synthetic responses with a mocked ConfigEditor. Requests complete unchanged; simultaneous sync is rejected, new steps wait during writes, and both success and rollback release the barrier. These tests do not exercise a live desktop task or native ConfigEditor reload during a real model stream.
|
|
23
27
|
- Three-language settings rendering, editable prompt preservation, custom divisors, preview ceilings, default-off behavior and preference conflicts.
|
package/package.json
CHANGED