dsh-mnemon-source-skills 0.5.3 → 0.5.4
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/lib/client.js +395 -42
- package/lib/contracts.d.ts +25 -1
- package/lib/index.js +175 -1
- package/lib/types/client/api.d.ts +26 -2
- package/lib/types/client/model-choice.d.ts +45 -0
- package/lib/types/client/skill-tests.d.ts +2 -1
- package/lib/types/contracts.d.ts +24 -0
- package/package.json +3 -3
- package/presentation/locales.json +22 -2
- package/presentation/page.module.css +8 -0
package/lib/client.js
CHANGED
|
@@ -63,6 +63,13 @@ window.__ModuleLoader__.load({
|
|
|
63
63
|
confirmed: true
|
|
64
64
|
}));
|
|
65
65
|
};
|
|
66
|
+
const savedModel = async (slot, input) => {
|
|
67
|
+
if (input.provider !== void 0 || input.model !== void 0) return void 0;
|
|
68
|
+
const preferences = await read("draft-preferences");
|
|
69
|
+
const overrides = slot === "draft" ? preferences.suggestionModels : preferences.skillRunModels;
|
|
70
|
+
const key = slot === "draft" ? input.suggestionId : input.skillName;
|
|
71
|
+
return key !== void 0 && Object.hasOwn(overrides, key) ? overrides[key] : slot === "draft" ? preferences.model : preferences.runModel;
|
|
72
|
+
};
|
|
66
73
|
return {
|
|
67
74
|
overview: () => read("overview"),
|
|
68
75
|
catalog: () => read("catalog"),
|
|
@@ -107,6 +114,8 @@ window.__ModuleLoader__.load({
|
|
|
107
114
|
expectedHash
|
|
108
115
|
}),
|
|
109
116
|
dismissSuggestion: (id) => mutate("suggestion-dismiss", { id }),
|
|
117
|
+
deleteSuggestion: (id) => mutate("suggestion-delete", { id }),
|
|
118
|
+
deleteDraft: (id) => mutate("draft-delete", { id }),
|
|
110
119
|
pinTrajectory: (id, pinned) => mutate("trajectory-pin", {
|
|
111
120
|
id,
|
|
112
121
|
pinned
|
|
@@ -127,6 +136,22 @@ window.__ModuleLoader__.load({
|
|
|
127
136
|
draftId,
|
|
128
137
|
runId
|
|
129
138
|
}),
|
|
139
|
+
draftPreferences: () => read("draft-preferences"),
|
|
140
|
+
saveDraftModel: (model) => mutate("draft-preference", { model }),
|
|
141
|
+
saveSuggestionModel: (id, model) => mutate("draft-preference", {
|
|
142
|
+
suggestionId: id,
|
|
143
|
+
model
|
|
144
|
+
}),
|
|
145
|
+
saveRunModel: (model) => mutate("draft-preference", {
|
|
146
|
+
slot: "run",
|
|
147
|
+
model
|
|
148
|
+
}),
|
|
149
|
+
saveSkillRunModel: (skillName, model) => mutate("draft-preference", {
|
|
150
|
+
slot: "run",
|
|
151
|
+
skillName,
|
|
152
|
+
model
|
|
153
|
+
}),
|
|
154
|
+
models: () => management.models === void 0 ? Promise.reject(/* @__PURE__ */ new Error("model catalog is unavailable")) : management.models(),
|
|
130
155
|
market: () => read("market"),
|
|
131
156
|
marketPreview: (registryId, name) => read("market-preview", {
|
|
132
157
|
registryId,
|
|
@@ -142,8 +167,14 @@ window.__ModuleLoader__.load({
|
|
|
142
167
|
enabled
|
|
143
168
|
}),
|
|
144
169
|
canAssist: (operation) => management.assistance?.operations.includes(operation) === true,
|
|
145
|
-
generateDraft: (input) => assist("skill-draft",
|
|
146
|
-
|
|
170
|
+
generateDraft: async (input) => assist("skill-draft", {
|
|
171
|
+
...await savedModel("draft", input),
|
|
172
|
+
...input
|
|
173
|
+
}),
|
|
174
|
+
backtest: async (input) => assist("skill-backtest", {
|
|
175
|
+
...await savedModel("run", input),
|
|
176
|
+
...input
|
|
177
|
+
}),
|
|
147
178
|
deriveCases: (input) => assist("skill-derive-cases", input),
|
|
148
179
|
reviewNow: () => assist("skill-review-now", {})
|
|
149
180
|
};
|
|
@@ -486,7 +517,17 @@ window.__ModuleLoader__.load({
|
|
|
486
517
|
"trash.original": "原位置",
|
|
487
518
|
"trash.chooseHint": "可选择恢复位置或改名。同名替换需要明确确认,现有技能会保留在回收站。",
|
|
488
519
|
"trash.replace": "替换同名技能,并将现有版本保留在回收站",
|
|
489
|
-
"trash.confirmName": "输入 {name} 确认彻底删除"
|
|
520
|
+
"trash.confirmName": "输入 {name} 确认彻底删除",
|
|
521
|
+
"evolution.model": "全局模型",
|
|
522
|
+
"evolution.modelCard": "所选草案模型",
|
|
523
|
+
"evolution.modelAuto": "跟随默认",
|
|
524
|
+
"evolution.modelAutoHint": "使用当前任务 Agent 的模型",
|
|
525
|
+
"evolution.deleteTitle": "删除这条建议?",
|
|
526
|
+
"evolution.deleteBody": "它生成的草案和证据引用会一起删掉,无法恢复。",
|
|
527
|
+
"evolution.deleted": "已删除",
|
|
528
|
+
"tests.model": "全局模型",
|
|
529
|
+
"tests.modelCard": "所选回测模型",
|
|
530
|
+
"tests.modelAuto": "跟随默认"
|
|
490
531
|
};
|
|
491
532
|
var en = {
|
|
492
533
|
"page.title": "Skills",
|
|
@@ -824,11 +865,21 @@ window.__ModuleLoader__.load({
|
|
|
824
865
|
"trash.original": "Original location",
|
|
825
866
|
"trash.chooseHint": "Choose a location or a different name. Replacing a skill requires confirmation and keeps its current version in the Trash.",
|
|
826
867
|
"trash.replace": "Replace the existing skill and keep its current version in the Trash",
|
|
827
|
-
"trash.confirmName": "Type {name} to confirm permanent deletion"
|
|
868
|
+
"trash.confirmName": "Type {name} to confirm permanent deletion",
|
|
869
|
+
"evolution.model": "Global model",
|
|
870
|
+
"evolution.modelCard": "Selected model",
|
|
871
|
+
"evolution.modelAuto": "Follow default",
|
|
872
|
+
"evolution.modelAutoHint": "Use the model of the current task Agent",
|
|
873
|
+
"evolution.deleteTitle": "Delete this suggestion?",
|
|
874
|
+
"evolution.deleteBody": "Its draft and the evidence references it cites go with it, and this cannot be undone.",
|
|
875
|
+
"evolution.deleted": "Deleted",
|
|
876
|
+
"tests.model": "Global model",
|
|
877
|
+
"tests.modelCard": "Selected model",
|
|
878
|
+
"tests.modelAuto": "Follow default"
|
|
828
879
|
};
|
|
829
880
|
//#endregion
|
|
830
881
|
//#region \0source-css:/home/runner/work/dsh-mnemon/dsh-mnemon/plugins/dsh-mnemon-source-skills/presentation/page.module.css.mjs
|
|
831
|
-
const css$1 = ".IIa07q_skPage{flex-direction:column;gap:12px;min-width:0;animation:.22s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:flex}@keyframes IIa07q_sk-arrive{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}@keyframes IIa07q_sk-pop{0%{opacity:0;transform:scale(.6)}70%{transform:scale(1.08)}to{opacity:1;transform:none}}@keyframes IIa07q_sk-spin{to{transform:rotate(360deg)}}@keyframes IIa07q_sk-breathe{50%{opacity:.35}}.IIa07q_skMuted{color:var(--mn-faint);margin:0;font-size:12px;line-height:18px}.IIa07q_skProse{color:var(--mn-muted);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:21px}.IIa07q_skBusy{color:var(--mn-muted);align-items:center;gap:8px;padding:6px 0;font-size:12px;line-height:18px;display:inline-flex}.IIa07q_skLink{border-radius:var(--dsw-radius-xs,4px);color:var(--dsw-alias-link,var(--mn-accent));font:inherit;cursor:pointer;background:0 0;border:0;padding:0 2px;font-size:12px;line-height:18px;text-decoration:none;transition:color .12s,background-color .12s}.IIa07q_skLink:hover{background:color-mix(in srgb, var(--mn-accent) 8%, transparent)}.IIa07q_skAlert,.IIa07q_skNotice{border-radius:var(--dsw-radius-md);color:var(--mn-text);align-items:center;gap:8px;margin-bottom:12px;padding:8px 10px 8px 12px;font-size:12px;line-height:18px;display:flex}.IIa07q_skAlert{background:color-mix(in srgb, var(--mn-danger) 9%, transparent)}.IIa07q_skNotice{background:color-mix(in srgb, var(--mn-success) 9%, transparent)}.IIa07q_skAlert>span,.IIa07q_skNotice>span{overflow-wrap:anywhere;flex:1;min-width:0}.IIa07q_skDismiss{border-radius:var(--dsw-radius-xs,4px);width:20px;height:20px;color:inherit;opacity:.55;cursor:pointer;background:0 0;border:0;flex:none;place-items:center;padding:0;font-size:15px;line-height:1;transition:opacity .12s,background-color .12s;display:grid}.IIa07q_skDismiss:hover{background:var(--mn-hover);opacity:1}.IIa07q_skWarn,.IIa07q_skSuccess{border-radius:var(--dsw-radius-md);color:var(--mn-text);margin:0;padding:8px 12px;font-size:12px;line-height:18px}.IIa07q_skWarn{background:color-mix(in srgb, var(--mn-warn) 11%, transparent)}.IIa07q_skSuccess{background:color-mix(in srgb, var(--mn-success) 9%, transparent)}.IIa07q_skDangerButton{background:var(--mn-danger)!important}.IIa07q_skClamp{justify-items:start;gap:2px;display:grid}.IIa07q_skClamp>.IIa07q_skProse[data-clamped]{-webkit-line-clamp:var(--sk-lines,3);-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.IIa07q_skClamp>.IIa07q_skChanges{width:100%}.IIa07q_skCaption{color:var(--mn-faint);letter-spacing:.02em;margin:4px 0 0;font-size:11px;font-weight:500;line-height:16px}.IIa07q_skCallout{border-radius:var(--dsw-radius-md);width:100%;color:var(--mn-text);background:color-mix(in srgb, var(--mn-accent) 8%, transparent);font:inherit;text-align:left;cursor:pointer;border:0;justify-content:space-between;align-items:center;gap:12px;padding:8px 12px;font-size:12px;line-height:18px;transition:background-color .14s;display:flex}.IIa07q_skCallout:hover{background:color-mix(in srgb, var(--mn-accent) 13%, transparent)}.IIa07q_skCallout>b{color:var(--dsw-alias-link,var(--mn-accent));flex:none;font-weight:500;transition:transform .16s cubic-bezier(.2,0,0,1)}.IIa07q_skCallout:hover>b{transform:translate(2px)}.IIa07q_skTabBadge{min-width:16px;color:var(--dsw-alias-label-inverse,#fff);background:var(--mn-accent);text-align:center;font-variant-numeric:tabular-nums;border-radius:999px;margin-left:6px;padding:0 5px;font-size:11px;font-weight:500;line-height:16px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-pop;display:inline-block}.IIa07q_skIconButton{border-radius:var(--dsw-radius-sm);width:28px;height:28px;color:var(--mn-muted);cursor:pointer;background:0 0;border:0;flex:none;place-items:center;padding:0;transition:color .12s,background-color .12s;display:grid}.IIa07q_skIconButton:hover:not(:disabled),.IIa07q_skIconButton[aria-expanded=true]{color:var(--mn-text);background:var(--mn-hover)}.IIa07q_skIconButton:disabled{cursor:default;opacity:.45}.IIa07q_skIconButton[data-busy]>svg{animation:.9s linear infinite IIa07q_sk-spin}.IIa07q_skIconButton[data-pulse]>svg{color:var(--mn-accent);animation:1.2s ease-in-out infinite IIa07q_sk-breathe}.IIa07q_skIconButton:focus-visible,.IIa07q_skCallout:focus-visible,.IIa07q_skLink:focus-visible{box-shadow:0 0 0 2px var(--dsw-focus-ring-color,var(--mn-accent));outline:none}.IIa07q_skEmpty{place-content:center;justify-items:center;gap:4px;min-height:280px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skEmptyActions{flex-wrap:wrap;justify-content:center;gap:8px;display:flex}.IIa07q_skSplit{grid-template-columns:minmax(268px,340px) minmax(0,1fr);gap:12px;min-height:560px;display:grid}.IIa07q_skList,.IIa07q_skPane{border:.5px solid var(--mn-card-line);border-radius:var(--dsw-radius-lg);min-width:0}.IIa07q_skList{flex-direction:column;padding-bottom:6px;display:flex;overflow:hidden}.IIa07q_skPane{padding:clamp(16px,2vw,24px);overflow:hidden}.IIa07q_skListBar{border-bottom:.5px solid var(--mn-line);align-items:center;gap:8px;padding:10px;display:flex}.IIa07q_skListBar>:first-child{flex:1;min-width:0}.IIa07q_skListNote{color:var(--mn-faint);text-align:center;margin:0;padding:18px 16px;font-size:12px;line-height:18px}.IIa07q_skListFilter{padding:8px 10px 2px}.IIa07q_skListGroup h5{color:var(--mn-faint);letter-spacing:.02em;text-overflow:ellipsis;white-space:nowrap;margin:14px 16px 4px;font-size:11px;font-weight:500;line-height:16px;overflow:hidden}.IIa07q_skListItem{border-radius:var(--dsw-radius-md);width:calc(100% - 12px);color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;margin:4px 6px 0;padding:9px 10px;transition:background-color .14s;display:block}.IIa07q_skListItem:hover{background:var(--mn-hover)}.IIa07q_skListItem[data-selected]{background:var(--mn-fill)}.IIa07q_skListItem>div{align-items:center;gap:6px;min-width:0;display:flex}.IIa07q_skListItem>div strong{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:13px;font-weight:500;line-height:20px;overflow:hidden}.IIa07q_skListItem p{color:var(--mn-muted);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:3px 0 4px;font-size:12px;line-height:18px;display:-webkit-box;overflow:hidden}.IIa07q_skListItem footer{min-width:0;color:var(--mn-faint);align-items:center;gap:8px;font-size:11px;line-height:16px;display:flex}.IIa07q_skListItem footer time{font-variant-numeric:tabular-nums;flex:none}.IIa07q_skListItem footer span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.IIa07q_skIcon{border-radius:var(--dsw-radius-md);width:30px;height:30px;color:var(--mn-muted);background:var(--mn-fill);flex:none;place-items:center;font-size:13px;font-weight:600;line-height:1;transition:color .14s,background-color .14s;display:grid}.IIa07q_skRow{border-radius:var(--dsw-radius-md);align-items:center;gap:6px;margin:2px 6px 0;padding-right:8px;transition:background-color .14s;display:flex;position:relative}.IIa07q_skRow:hover{background:var(--mn-hover)}.IIa07q_skRow[data-selected]{background:var(--mn-fill)}.IIa07q_skRow[data-selected] .IIa07q_skIcon{color:var(--mn-text);background:var(--mn-layer-1,var(--mn-hover))}.IIa07q_skRow[data-off] .IIa07q_skRowText,.IIa07q_skRow[data-shadowed] .IIa07q_skRowText{opacity:.55}.IIa07q_skRowMain{min-width:0;color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:10px;padding:8px 0 8px 8px;display:flex}.IIa07q_skRowMain:focus-visible{box-shadow:inset 0 0 0 2px var(--dsw-focus-ring-color,var(--mn-accent));border-radius:var(--dsw-radius-md);outline:none}.IIa07q_skRowText{gap:1px;min-width:0;transition:opacity .14s;display:grid}.IIa07q_skRowText strong{white-space:nowrap;align-items:center;gap:6px;min-width:0;font-size:13px;font-weight:500;line-height:20px;display:flex}.IIa07q_skRowText strong>span{text-overflow:ellipsis;min-width:0;overflow:hidden}.IIa07q_skRowText small{color:var(--mn-faint);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}.IIa07q_skScore{min-width:24px;color:var(--mn-muted);font-variant-numeric:tabular-nums;text-align:right;flex:none;font-size:13px;font-weight:500;line-height:20px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-pop}.IIa07q_skScore[data-tone=good]{color:var(--mn-success)}.IIa07q_skScore[data-tone=bad]{color:var(--mn-danger)}.IIa07q_skDot{background:var(--mn-accent);border-radius:999px;flex:none;width:6px;height:6px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-pop}.IIa07q_skRowActions{flex:none;align-items:center;gap:8px;display:flex}.IIa07q_skUse{opacity:0;pointer-events:none;transition:opacity .14s,transform .18s cubic-bezier(.2,0,0,1);transform:translate(4px)}.IIa07q_skRow:hover .IIa07q_skUse,.IIa07q_skRow:focus-within .IIa07q_skUse{opacity:1;pointer-events:auto;transform:none}@media (hover:none){.IIa07q_skUse{opacity:1;pointer-events:auto;transform:none}}.IIa07q_skProblems{color:var(--mn-faint);margin:12px 12px 4px;font-size:12px;line-height:18px}.IIa07q_skProblems summary{border-radius:var(--dsw-radius-xs,4px);cursor:pointer;width:fit-content;padding:0 2px}.IIa07q_skProblems summary:hover{color:var(--mn-muted)}.IIa07q_skProblems ul{gap:6px;margin:8px 0 0;padding:0;list-style:none;display:grid}.IIa07q_skProblems li{gap:2px;display:grid}.IIa07q_skProblems code{color:var(--mn-muted);font:11px/16px var(--mn-code)}.IIa07q_skDetail{grid-template-columns:minmax(0,1fr);gap:14px;min-width:0;animation:.2s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skDetailHead{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.IIa07q_skDetailHead>div:first-child{gap:4px;min-width:0;display:grid}.IIa07q_skDetailHead h3{overflow-wrap:anywhere;margin:0;font-size:17px;font-weight:600;line-height:26px}.IIa07q_skDetailHead p{color:var(--mn-muted);margin:0;font-size:13px;line-height:20px}.IIa07q_skDetailActions{flex-wrap:wrap;flex:none;justify-content:flex-end;align-items:center;gap:6px;display:flex}.IIa07q_skKicker{flex-wrap:wrap;align-items:center;gap:6px;display:inline-flex}.IIa07q_skTitleLink{color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;padding:0}.IIa07q_skTitleLink:hover{color:var(--dsw-alias-link,var(--mn-accent))}.IIa07q_skMeta{min-width:0;color:var(--mn-faint);flex-wrap:wrap;align-items:center;gap:0 6px;font-size:12px;line-height:18px;display:flex}.IIa07q_skMeta>*+:before{content:\"·\";color:var(--mn-line-strong,var(--mn-faint));margin-right:6px}.IIa07q_skMeta code{min-width:0;max-width:100%;font:11px/18px var(--mn-code);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.IIa07q_skInvocation{align-items:center;gap:8px;display:flex}.IIa07q_skWhen{color:var(--mn-muted);margin:0;font-size:12px;line-height:18px}.IIa07q_skDoc{overflow-wrap:anywhere;min-width:0;color:var(--mn-text);font-size:13px;line-height:1.75}.IIa07q_skDoc>:first-child{margin-top:0}.IIa07q_skDoc>:last-child{margin-bottom:0}.IIa07q_skDoc h1,.IIa07q_skDoc h2,.IIa07q_skDoc h3,.IIa07q_skDoc h4{color:var(--mn-text);margin:1.4em 0 .5em;font-weight:600;line-height:1.4}.IIa07q_skDoc h1{font-size:1.25em}.IIa07q_skDoc h2{font-size:1.1em}.IIa07q_skDoc h3,.IIa07q_skDoc h4{font-size:1em}.IIa07q_skDoc p,.IIa07q_skDoc ul,.IIa07q_skDoc ol,.IIa07q_skDoc blockquote,.IIa07q_skDoc table,.IIa07q_skDoc pre{margin:.7em 0}.IIa07q_skDoc ul,.IIa07q_skDoc ol{padding-left:1.5em}.IIa07q_skDoc li+li{margin-top:.25em}.IIa07q_skDoc li::marker{color:var(--mn-faint)}.IIa07q_skDoc blockquote{border-left:2px solid var(--mn-line-strong,var(--mn-line));color:var(--mn-muted);margin-inline:0;padding:.1em 1em}.IIa07q_skDoc code{border-radius:var(--dsw-radius-xs,4px);color:var(--mn-text);background:var(--dsw-alias-markdown-inline-code,var(--mn-fill));font:.9em/1.55 var(--mn-code);padding:.12em .38em}.IIa07q_skDoc pre{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-markdown-code-block,var(--mn-fill));max-width:100%;padding:10px 14px;overflow:auto}.IIa07q_skDoc pre code{background:0 0;padding:0;font-size:12px}.IIa07q_skDoc a{color:var(--dsw-alias-link,var(--mn-accent));text-underline-offset:3px;text-decoration-thickness:1px}.IIa07q_skDoc hr{border:0;border-top:.5px solid var(--mn-line);margin:1.6em 0}.IIa07q_skDoc table{border-collapse:collapse;max-width:100%;font-size:12px;display:block;overflow-x:auto}.IIa07q_skDoc th,.IIa07q_skDoc td{border:.5px solid var(--mn-line);text-align:left;vertical-align:top;padding:6px 10px}.IIa07q_skDoc th{background:var(--mn-fill);font-weight:500}.IIa07q_skDoc img{border-radius:var(--dsw-radius-sm);max-width:100%;height:auto}.IIa07q_skFolds{border-top:.5px solid var(--mn-line);grid-template-columns:minmax(0,1fr);min-width:0;margin-top:4px;display:grid}.IIa07q_skFold{border-bottom:.5px solid var(--mn-line);min-width:0}.IIa07q_skFold>header{justify-content:space-between;align-items:center;gap:12px;min-height:40px;display:flex}.IIa07q_skFold>header>button{border-radius:var(--dsw-radius-sm);min-width:0;color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:8px;margin-left:-4px;padding:8px 4px;font-size:13px;font-weight:500;line-height:20px;display:flex}.IIa07q_skFold>header>button>svg{color:var(--mn-faint);flex:none;transition:transform .18s cubic-bezier(.2,0,0,1),color .12s;transform:rotate(-90deg)}.IIa07q_skFold[data-open]>header>button>svg{transform:none}.IIa07q_skFold>header>button:hover>svg{color:var(--mn-text)}.IIa07q_skFold>header>button>small{min-width:0;color:var(--mn-faint);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:400;overflow:hidden}.IIa07q_skFold>header>button:focus-visible{box-shadow:0 0 0 2px var(--dsw-focus-ring-color,var(--mn-accent));outline:none}.IIa07q_skFold>header>div{align-items:center;gap:6px;display:flex}.IIa07q_skFoldBody{grid-template-columns:minmax(0,1fr);gap:10px;min-width:0;padding:2px 0 14px;display:grid}.IIa07q_skFold[data-link]>header>button{padding-left:24px}.IIa07q_skFold[data-link]>header>button>b{color:var(--mn-faint);margin-left:auto;font-weight:400;transition:transform .16s cubic-bezier(.2,0,0,1),color .12s}.IIa07q_skFold[data-link]>header>button:hover>b{color:var(--dsw-alias-link,var(--mn-accent));transform:translate(2px)}.IIa07q_skVersions{grid-template-columns:minmax(0,1fr);gap:1px;margin:0;padding:0;list-style:none;display:grid}.IIa07q_skVersions li{border-radius:var(--dsw-radius-md);align-items:center;gap:10px;min-height:34px;padding:3px 6px;transition:background-color .12s;display:flex}.IIa07q_skVersions li:hover{background:var(--mn-hover)}.IIa07q_skVersions time{color:var(--mn-muted);font-variant-numeric:tabular-nums;font-size:12px}.IIa07q_skVersions li>span{flex:1}.IIa07q_skTrashList li{flex-wrap:wrap;padding-block:10px}.IIa07q_skTrashList li>span{flex:none}.IIa07q_skTrashList li>.IIa07q_skRowText{flex:220px}.IIa07q_skTrashTags{flex-wrap:wrap;gap:6px;display:flex}.IIa07q_skTrashList li>.IIa07q_skTrashActions{flex:none;gap:6px;margin-left:auto;display:flex}.IIa07q_skResources{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skResources code{color:var(--mn-muted);background:var(--mn-fill);font:11px/17px var(--mn-code);border-radius:999px;padding:1px 8px}.IIa07q_skEditor{resize:vertical;border:.5px solid var(--mn-field-line);border-radius:var(--dsw-radius-md);width:100%;min-height:420px;color:var(--mn-text);background:var(--mn-input);font:12px/1.6 var(--mn-code);tab-size:2;outline:0;padding:10px 12px;transition:border-color .12s}.IIa07q_skEditor:focus{border-color:var(--mn-accent)}.IIa07q_skTimeline{grid-template-columns:minmax(0,1fr);gap:0;min-width:0;margin:0;padding:0;list-style:none;display:grid}.IIa07q_skTimeline>li{min-width:0}.IIa07q_skTurn{color:var(--mn-faint);letter-spacing:.02em;margin:12px 0 4px;font-size:11px;font-weight:500;line-height:16px}.IIa07q_skTimeline>li:first-child>.IIa07q_skTurn{margin-top:0}.IIa07q_skStep{border-radius:0 var(--dsw-radius-sm) var(--dsw-radius-sm) 0;border-left:2px solid #0000;align-items:flex-start;gap:8px;padding:5px 8px;transition:background-color .14s;display:flex}.IIa07q_skTimeline>li[data-annotated] .IIa07q_skStep{border-left-color:color-mix(in srgb, var(--mn-warn) 70%, transparent);background:color-mix(in srgb, var(--mn-warn) 5%, transparent)}.IIa07q_skTimeline>li[data-highlight] .IIa07q_skStep{border-left-color:var(--mn-accent);background:color-mix(in srgb, var(--mn-accent) 6%, transparent)}.IIa07q_skStepIndex{width:22px;color:var(--mn-faint);text-align:right;font-variant-numeric:tabular-nums;flex:none;font-size:11px;line-height:20px}.IIa07q_skStepGlyph{width:14px;color:var(--mn-faint);text-align:center;flex:none;font-size:12px;line-height:20px}.IIa07q_skTimeline>li[data-kind=skill] .IIa07q_skStepGlyph{color:var(--mn-accent)}.IIa07q_skTimeline>li[data-failed] .IIa07q_skStepGlyph{color:var(--mn-danger)}.IIa07q_skStepBody{flex:1;min-width:0}.IIa07q_skStepHead{flex-wrap:wrap;align-items:center;gap:6px;min-width:0;display:flex}.IIa07q_skStepHead strong{font-size:12px;font-weight:500;line-height:20px}.IIa07q_skStepHead code{min-width:0;max-width:100%;color:var(--mn-faint);font:11px/18px var(--mn-code);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.IIa07q_skStepBody>p{overflow-wrap:anywhere;color:var(--mn-muted);white-space:pre-wrap;margin:1px 0 0;font-size:12px;line-height:18px}.IIa07q_skTimeline[data-compact] .IIa07q_skStepBody>p{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.IIa07q_skAnnotation{color:var(--mn-text);align-items:flex-start;gap:6px;margin-top:6px;font-size:12px;line-height:18px;display:flex}.IIa07q_skEvidence+.IIa07q_skEvidence{margin-top:14px}.IIa07q_skEvidence>header{align-items:center;gap:8px;min-width:0;margin-bottom:6px;display:flex}.IIa07q_skEvidence>header strong{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12px;font-weight:500;overflow:hidden}.IIa07q_skEvidence>header span{color:var(--mn-faint);flex:none;font-size:11px}.IIa07q_skEvidence>header button{margin-left:auto}.IIa07q_skChips{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skDeriveBar{border-radius:var(--dsw-radius-md);background:var(--mn-fill);color:var(--mn-muted);flex-wrap:wrap;align-items:center;gap:8px;padding:8px 10px;font-size:12px;line-height:18px;display:flex}.IIa07q_skDeriveBar>span{min-width:0;margin-right:auto}.IIa07q_skDraft{border-top:.5px solid var(--mn-line);grid-template-columns:minmax(0,1fr);gap:12px;min-width:0;padding-top:14px;display:grid}.IIa07q_skSectionHead{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 12px;display:flex}.IIa07q_skSectionHead h4{align-items:baseline;gap:8px;margin:0;font-size:14px;font-weight:600;line-height:22px;display:flex}.IIa07q_skSectionHead h4 small{color:var(--mn-faint);font-size:12px;font-weight:400}.IIa07q_skSectionHead>div{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skChanges{color:var(--mn-muted);gap:3px;margin:0;padding-left:18px;font-size:12px;line-height:18px;display:grid}.IIa07q_skChanges li::marker{color:var(--mn-faint)}.IIa07q_skGuidance{color:var(--mn-faint);gap:2px;margin:0;padding-left:18px;font-size:12px;line-height:18px;display:grid}.IIa07q_skBacktest{border-radius:var(--dsw-radius-md);background:var(--mn-fill);flex-wrap:wrap;align-items:center;gap:6px 10px;min-height:36px;padding:4px 6px 4px 12px;display:flex}.IIa07q_skBacktestLine{min-width:0;color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:10px;padding:4px 0;font-size:12px;line-height:18px;display:flex}.IIa07q_skBacktestLine>span{color:var(--mn-faint);flex:none}.IIa07q_skBacktestLine>strong{text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;min-width:0;font-weight:500;overflow:hidden}.IIa07q_skBacktestLine>em{color:var(--mn-muted);background:var(--mn-hover);font-variant-numeric:tabular-nums;border-radius:999px;flex:none;padding:0 7px;font-style:normal;font-weight:600}.IIa07q_skBacktest[data-tone=good] .IIa07q_skBacktestLine>em{color:var(--mn-success);background:color-mix(in srgb, var(--mn-success) 12%, transparent)}.IIa07q_skBacktest[data-tone=bad] .IIa07q_skBacktestLine>em{color:var(--mn-danger);background:color-mix(in srgb, var(--mn-danger) 12%, transparent)}.IIa07q_skBacktestLine:hover>strong{text-underline-offset:3px;text-decoration:underline;text-decoration-color:var(--mn-line-strong,var(--mn-faint))}.IIa07q_skTable{border-collapse:collapse;width:100%;font-size:12px;line-height:18px;animation:.18s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive}.IIa07q_skTable th{border-bottom:.5px solid var(--mn-line);color:var(--mn-faint);text-align:left;padding:6px 8px;font-weight:500}.IIa07q_skTable td{border-bottom:.5px solid var(--mn-line);vertical-align:top;padding:7px 8px}.IIa07q_skTable td small{color:var(--mn-faint);margin-top:3px;display:block}.IIa07q_skComposer{border-radius:var(--dsw-radius-lg);background:var(--mn-fill);grid-template-columns:minmax(0,1fr);gap:8px;padding:12px;animation:.18s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skComposer label{color:var(--mn-muted);gap:6px;font-size:12px;font-weight:500;line-height:18px;display:grid}.IIa07q_skComposer textarea{resize:vertical;border:.5px solid var(--mn-field-line);border-radius:var(--dsw-radius-md);width:100%;color:var(--mn-text);background:var(--mn-input);font:inherit;outline:0;padding:6px 10px;font-size:13px;line-height:20px;transition:border-color .12s}.IIa07q_skComposer textarea:focus{border-color:var(--mn-accent)}.IIa07q_skComposer>footer{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;display:flex}.IIa07q_skTests{grid-template-columns:minmax(0,1fr);gap:10px;min-width:0;display:grid}.IIa07q_skTestsBar{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skCases{grid-template-columns:minmax(0,1fr);gap:1px;margin:0;padding:0;list-style:none;display:grid}.IIa07q_skCases>li{border-radius:var(--dsw-radius-md);align-items:flex-start;gap:8px;padding:2px 4px 2px 0;transition:background-color .12s,opacity .14s;display:flex}.IIa07q_skCases>li:hover{background:var(--mn-hover)}.IIa07q_skCases>li[data-off]>details{opacity:.5}.IIa07q_skCases>li>details{flex:1;min-width:0}.IIa07q_skCases>li>:not(details){margin-top:6px}.IIa07q_skCases summary{border-radius:var(--dsw-radius-md);cursor:pointer;align-items:baseline;gap:8px;min-width:0;padding:7px 8px;list-style:none;display:flex}.IIa07q_skCases summary::-webkit-details-marker{display:none}.IIa07q_skCases summary strong{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:13px;font-weight:500;line-height:20px;overflow:hidden}.IIa07q_skCases summary small{color:var(--mn-faint);flex:none;font-size:11px}.IIa07q_skCases details[open] summary strong{white-space:normal}.IIa07q_skCases details>p{color:var(--mn-muted);white-space:pre-wrap;overflow-wrap:anywhere;margin:0 8px 8px;font-size:12px;line-height:18px}.IIa07q_skCases details>ul{gap:4px;margin:0 8px 8px;padding:0;list-style:none;display:grid}.IIa07q_skCases details>ul li{color:var(--mn-text);align-items:flex-start;gap:6px;font-size:12px;line-height:18px;display:flex}.IIa07q_skCases details>.IIa07q_skLink{margin:0 6px 8px}.IIa07q_skRuns{grid-template-columns:minmax(0,1fr);gap:1px;margin:0;padding:0;list-style:none;display:grid}.IIa07q_skRuns>li>button{border-radius:var(--dsw-radius-md);width:100%;min-width:0;color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:center;gap:8px;padding:7px 8px;font-size:12px;line-height:18px;transition:background-color .12s;display:flex}.IIa07q_skRuns>li>button:hover,.IIa07q_skRuns>li>button[aria-expanded=true]{background:var(--mn-hover)}.IIa07q_skRuns>li>button>:first-child{flex:none}.IIa07q_skRuns>li>button span{min-width:0;color:var(--mn-muted);text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;flex:1;overflow:hidden}.IIa07q_skRuns>li>button time{color:var(--mn-faint);flex:none;font-size:11px}.IIa07q_skRunDetail{border-left:.5px solid var(--mn-line);grid-template-columns:minmax(0,1fr);gap:2px;margin:4px 0 8px 12px;padding-left:10px;animation:.18s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skRunDetail details{padding:4px 0}.IIa07q_skRunDetail summary{cursor:pointer;align-items:center;gap:8px;min-width:0;font-size:12px;line-height:18px;display:flex}.IIa07q_skRunDetail summary strong{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:500;overflow:hidden}.IIa07q_skRunDetail summary span{color:var(--mn-faint);font-variant-numeric:tabular-nums}.IIa07q_skRunDetail h6{color:var(--mn-faint);margin:8px 0 4px;font-size:11px;font-weight:500}.IIa07q_skVerdicts{grid-template-columns:minmax(0,1fr);gap:2px;margin:6px 0;padding:0;font-size:12px;line-height:18px;list-style:none;display:grid}.IIa07q_skVerdicts li{color:var(--mn-muted);gap:6px;display:flex}.IIa07q_skVerdicts li b{color:var(--mn-danger)}.IIa07q_skVerdicts li[data-pass] b{color:var(--mn-success)}.IIa07q_skRunSteps{color:var(--mn-muted);margin:0;padding-left:18px;font-size:12px;line-height:18px}.IIa07q_skAnswer{border-radius:var(--dsw-radius-md);max-height:240px;color:var(--mn-text);background:var(--mn-fill);font:12px/1.55 var(--mn-code);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;padding:8px 10px;overflow:auto}.IIa07q_skForm{gap:14px;display:grid}.IIa07q_skField{gap:6px;display:grid}.IIa07q_skField>label{color:var(--mn-muted);font-size:12px;font-weight:500;line-height:18px}.IIa07q_skForm input:not([type=checkbox]):not([type=radio]),.IIa07q_skForm textarea{border:.5px solid var(--mn-field-line);border-radius:var(--dsw-radius-md);width:100%;color:var(--mn-text);background:var(--mn-input);font:inherit;outline:0;padding:7px 10px;font-size:13px;line-height:20px;transition:border-color .12s}.IIa07q_skForm input:not([type=checkbox]):not([type=radio]):focus,.IIa07q_skForm textarea:focus{border-color:var(--mn-accent)}.IIa07q_skForm textarea{resize:vertical}.IIa07q_skForm small{color:var(--mn-faint);font-size:11px;line-height:16px}.IIa07q_skFormRow{display:flex}.IIa07q_skFormError{color:var(--mn-danger);margin-right:auto;font-size:12px}.IIa07q_skChecks{border:0;gap:6px;margin:0;padding:0;display:grid}.IIa07q_skChecks legend{color:var(--mn-muted);margin-bottom:6px;font-size:12px;font-weight:500}.IIa07q_skChecks>div{align-items:center;gap:10px;display:flex}.IIa07q_skChecks>div>input{flex:1;min-width:0}.IIa07q_skMust{color:var(--mn-muted);white-space:nowrap;flex:none;font-size:12px}.IIa07q_skChecks>button{justify-self:start}.IIa07q_skMarket{gap:14px;display:grid}.IIa07q_skMarketBar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.IIa07q_skMarketBar>:first-child{flex:1;min-width:220px}.IIa07q_skMarketGrid{grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:12px;display:grid}.IIa07q_skMarketCard{border:.5px solid var(--mn-card-line);border-radius:var(--dsw-radius-lg);background:0 0;flex-direction:column;min-width:0;transition:border-color .16s,box-shadow .2s,transform .2s cubic-bezier(.2,0,0,1);animation:.24s cubic-bezier(.2,0,0,1) backwards IIa07q_sk-arrive;display:flex}.IIa07q_skMarketCard:hover{border-color:var(--mn-line-strong,var(--mn-card-line));box-shadow:var(--dsw-elevation-soft,0 4px 16px #0000000f);transform:translateY(-1px)}.IIa07q_skMarketCard:hover .IIa07q_skIcon{color:var(--mn-text)}.IIa07q_skMarketOpen{color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-content:start;gap:10px;padding:14px 14px 6px;display:grid}.IIa07q_skMarketOpen:focus-visible{box-shadow:inset 0 0 0 2px var(--dsw-focus-ring-color,var(--mn-accent));border-radius:var(--dsw-radius-lg);outline:none}.IIa07q_skMarketOpen>header{align-items:center;gap:10px;min-width:0;display:flex}.IIa07q_skMarketOpen>header>div{min-width:0;display:grid}.IIa07q_skMarketOpen strong{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;line-height:20px;overflow:hidden}.IIa07q_skMarketOpen code{color:var(--mn-faint);font:11px/16px var(--mn-code);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.IIa07q_skMarketOpen p{color:var(--mn-muted);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:0;font-size:12px;line-height:18px;display:-webkit-box;overflow:hidden}.IIa07q_skMarketCard>footer{justify-content:space-between;align-items:center;gap:8px;min-height:42px;padding:0 12px 10px 14px;display:flex}.IIa07q_skMarketCard>footer>span{min-width:0;color:var(--mn-faint);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.IIa07q_skMarketDetail{gap:12px;display:grid}.IIa07q_skInline{align-items:center;gap:8px;display:flex}.IIa07q_skInline>:first-child{flex:1;min-width:0}.IIa07q_skMarketSection{gap:8px;animation:.2s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skMarketGrid{transition:opacity .16s}.IIa07q_skMarketGrid[data-busy]{opacity:.55}.IIa07q_skMarketAdd{border-radius:var(--dsw-radius-md);background:color-mix(in srgb, var(--mn-accent) 7%, transparent);align-items:center;gap:10px;min-width:0;padding:6px 6px 6px 8px;font-size:12px;line-height:18px;animation:.2s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:flex}.IIa07q_skMarketAdd>span:nth-child(2){min-width:0;color:var(--mn-text);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.IIa07q_skMarketAdd .IIa07q_skSourceIcon{background:var(--mn-layer-1,var(--mn-fill));width:26px;height:26px}.IIa07q_skMarketStat{font-variant-numeric:tabular-nums;align-items:center;gap:4px;display:inline-flex}.IIa07q_skMarketCard[data-indexed] .IIa07q_skMarketOpen{padding-bottom:4px}.IIa07q_skMarketMeta{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px 12px;display:flex}.IIa07q_skAudits{gap:6px;display:grid}.IIa07q_skAudits>div{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skAuditsLabel{color:var(--mn-faint);margin-right:2px;font-size:12px;line-height:18px}.IIa07q_skAudit{color:var(--mn-text);background:var(--mn-fill);border-radius:999px;align-items:center;gap:6px;padding:2px 9px 2px 8px;font-size:12px;line-height:18px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-pop;display:inline-flex}.IIa07q_skAudit:before{content:\"\";background:var(--mn-success);border-radius:999px;flex:none;width:6px;height:6px}.IIa07q_skAudit[data-status=warn]:before{background:var(--mn-warn)}.IIa07q_skAudit[data-status=fail]:before{background:var(--mn-danger)}.IIa07q_skAudit small{color:var(--mn-faint);font-size:11px}.IIa07q_skSources{gap:18px;display:grid}.IIa07q_skSourceList{gap:2px;margin:0 -6px;padding:0;list-style:none;display:grid}.IIa07q_skSourceList>li{border-radius:var(--dsw-radius-md);align-items:center;gap:12px;min-width:0;padding:8px 8px 8px 6px;transition:background-color .14s;animation:.2s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:flex}.IIa07q_skSourceList>li:hover{background:var(--mn-hover)}.IIa07q_skSourceIcon{border-radius:var(--dsw-radius-md);width:32px;height:32px;color:var(--mn-muted);background:var(--mn-fill);flex:none;place-items:center;transition:opacity .14s;display:grid}.IIa07q_skSourceText{flex:1;gap:1px;min-width:0;transition:opacity .14s;display:grid}.IIa07q_skSourceText>strong{align-items:center;gap:6px;min-width:0;font-size:13px;font-weight:500;line-height:20px;display:flex}.IIa07q_skSourceText>strong>span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.IIa07q_skSourceText>small,.IIa07q_skSourceText>em{text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-style:normal;line-height:18px;overflow:hidden}.IIa07q_skSourceText>small{color:var(--mn-faint)}.IIa07q_skSourceText>em{color:var(--mn-danger)}.IIa07q_skSourceList>li[data-off] .IIa07q_skSourceText,.IIa07q_skSourceList>li[data-off] .IIa07q_skSourceIcon{opacity:.5}.IIa07q_skSourceActions{flex:none;align-items:center;gap:6px;display:flex}.IIa07q_skSourceAdd{border-top:.5px solid var(--mn-line);gap:6px;padding-top:16px;display:grid}.IIa07q_skSourceAdd>label{font-size:13px;font-weight:500;line-height:20px}.IIa07q_skSourceHint{min-height:18px;color:var(--mn-faint);text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:12px;line-height:18px;transition:color .14s;overflow:hidden}.IIa07q_skSourceHint[data-state=ok]{color:var(--mn-muted)}.IIa07q_skSourceHint[data-state=warn]{color:var(--mn-warn)}.IIa07q_skFormat summary{border-radius:var(--dsw-radius-xs,4px);width:fit-content;color:var(--mn-muted);cursor:pointer;padding:0 2px;font-size:12px;line-height:18px}.IIa07q_skFormat summary:hover{color:var(--mn-text)}.IIa07q_skFormat ul{gap:12px;margin:12px 0 0;padding:0;list-style:none;display:grid}.IIa07q_skFormat li{align-items:flex-start;gap:10px;display:flex}.IIa07q_skFormat li .IIa07q_skSourceIcon{width:26px;height:26px}.IIa07q_skFormat li>div{gap:1px;font-size:12px;line-height:18px;display:grid}.IIa07q_skFormat li strong{font-weight:500}.IIa07q_skFormat li span{color:var(--mn-muted)}@media (width<=860px){.IIa07q_skSplit{grid-template-columns:minmax(0,1fr)}.IIa07q_skList{max-height:360px;overflow-y:auto}}@media (width<=560px){.IIa07q_skDetailHead{flex-direction:column}.IIa07q_skDetailActions{justify-content:flex-start}}@media (prefers-reduced-motion:reduce){.IIa07q_skPage,.IIa07q_skDetail,.IIa07q_skEmpty,.IIa07q_skTable,.IIa07q_skComposer,.IIa07q_skRunDetail,.IIa07q_skMarketCard,.IIa07q_skMarketSection,.IIa07q_skMarketAdd,.IIa07q_skAudit,.IIa07q_skSourceList>li,.IIa07q_skTabBadge,.IIa07q_skDot,.IIa07q_skScore{animation:none}.IIa07q_skUse,.IIa07q_skFold>header>button>svg,.IIa07q_skFold[data-link]>header>button>b,.IIa07q_skCallout>b,.IIa07q_skMarketCard{transition:none}.IIa07q_skIconButton[data-busy]>svg,.IIa07q_skIconButton[data-pulse]>svg{animation:none}}";
|
|
882
|
+
const css$1 = ".IIa07q_skPage{flex-direction:column;gap:12px;min-width:0;animation:.22s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:flex}@keyframes IIa07q_sk-arrive{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}@keyframes IIa07q_sk-pop{0%{opacity:0;transform:scale(.6)}70%{transform:scale(1.08)}to{opacity:1;transform:none}}@keyframes IIa07q_sk-spin{to{transform:rotate(360deg)}}@keyframes IIa07q_sk-breathe{50%{opacity:.35}}.IIa07q_skMuted{color:var(--mn-faint);margin:0;font-size:12px;line-height:18px}.IIa07q_skProse{color:var(--mn-muted);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:21px}.IIa07q_skBusy{color:var(--mn-muted);align-items:center;gap:8px;padding:6px 0;font-size:12px;line-height:18px;display:inline-flex}.IIa07q_skLink{border-radius:var(--dsw-radius-xs,4px);color:var(--dsw-alias-link,var(--mn-accent));font:inherit;cursor:pointer;background:0 0;border:0;padding:0 2px;font-size:12px;line-height:18px;text-decoration:none;transition:color .12s,background-color .12s}.IIa07q_skLink:hover{background:color-mix(in srgb, var(--mn-accent) 8%, transparent)}.IIa07q_skAlert,.IIa07q_skNotice{border-radius:var(--dsw-radius-md);color:var(--mn-text);align-items:center;gap:8px;margin-bottom:12px;padding:8px 10px 8px 12px;font-size:12px;line-height:18px;display:flex}.IIa07q_skAlert{background:color-mix(in srgb, var(--mn-danger) 9%, transparent)}.IIa07q_skNotice{background:color-mix(in srgb, var(--mn-success) 9%, transparent)}.IIa07q_skAlert>span,.IIa07q_skNotice>span{overflow-wrap:anywhere;flex:1;min-width:0}.IIa07q_skDismiss{border-radius:var(--dsw-radius-xs,4px);width:20px;height:20px;color:inherit;opacity:.55;cursor:pointer;background:0 0;border:0;flex:none;place-items:center;padding:0;font-size:15px;line-height:1;transition:opacity .12s,background-color .12s;display:grid}.IIa07q_skDismiss:hover{background:var(--mn-hover);opacity:1}.IIa07q_skWarn,.IIa07q_skSuccess{border-radius:var(--dsw-radius-md);color:var(--mn-text);margin:0;padding:8px 12px;font-size:12px;line-height:18px}.IIa07q_skWarn{background:color-mix(in srgb, var(--mn-warn) 11%, transparent)}.IIa07q_skSuccess{background:color-mix(in srgb, var(--mn-success) 9%, transparent)}.IIa07q_skDangerButton{background:var(--mn-danger)!important}.IIa07q_skClamp{justify-items:start;gap:2px;display:grid}.IIa07q_skClamp>.IIa07q_skProse[data-clamped]{-webkit-line-clamp:var(--sk-lines,3);-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.IIa07q_skClamp>.IIa07q_skChanges{width:100%}.IIa07q_skCaption{color:var(--mn-faint);letter-spacing:.02em;margin:4px 0 0;font-size:11px;font-weight:500;line-height:16px}.IIa07q_skCallout{border-radius:var(--dsw-radius-md);width:100%;color:var(--mn-text);background:color-mix(in srgb, var(--mn-accent) 8%, transparent);font:inherit;text-align:left;cursor:pointer;border:0;justify-content:space-between;align-items:center;gap:12px;padding:8px 12px;font-size:12px;line-height:18px;transition:background-color .14s;display:flex}.IIa07q_skCallout:hover{background:color-mix(in srgb, var(--mn-accent) 13%, transparent)}.IIa07q_skCallout>b{color:var(--dsw-alias-link,var(--mn-accent));flex:none;font-weight:500;transition:transform .16s cubic-bezier(.2,0,0,1)}.IIa07q_skCallout:hover>b{transform:translate(2px)}.IIa07q_skTabBadge{min-width:16px;color:var(--dsw-alias-label-inverse,#fff);background:var(--mn-accent);text-align:center;font-variant-numeric:tabular-nums;border-radius:999px;margin-left:6px;padding:0 5px;font-size:11px;font-weight:500;line-height:16px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-pop;display:inline-block}.IIa07q_skIconButton{border-radius:var(--dsw-radius-sm);width:28px;height:28px;color:var(--mn-muted);cursor:pointer;background:0 0;border:0;flex:none;place-items:center;padding:0;transition:color .12s,background-color .12s;display:grid}.IIa07q_skIconButton:hover:not(:disabled),.IIa07q_skIconButton[aria-expanded=true]{color:var(--mn-text);background:var(--mn-hover)}.IIa07q_skIconButton:disabled{cursor:default;opacity:.45}.IIa07q_skIconButton[data-busy]>svg{animation:.9s linear infinite IIa07q_sk-spin}.IIa07q_skIconButton[data-pulse]>svg{color:var(--mn-accent);animation:1.2s ease-in-out infinite IIa07q_sk-breathe}.IIa07q_skIconButton:focus-visible,.IIa07q_skCallout:focus-visible,.IIa07q_skLink:focus-visible{box-shadow:0 0 0 2px var(--dsw-focus-ring-color,var(--mn-accent));outline:none}.IIa07q_skEmpty{place-content:center;justify-items:center;gap:4px;min-height:280px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skEmptyActions{flex-wrap:wrap;justify-content:center;gap:8px;display:flex}.IIa07q_skSplit{grid-template-columns:minmax(268px,340px) minmax(0,1fr);gap:12px;min-height:560px;display:grid}.IIa07q_skList,.IIa07q_skPane{border:.5px solid var(--mn-card-line);border-radius:var(--dsw-radius-lg);min-width:0}.IIa07q_skList{flex-direction:column;padding-bottom:6px;display:flex;overflow:hidden}.IIa07q_skPane{padding:clamp(16px,2vw,24px);overflow:hidden}.IIa07q_skEvolutionSplit{height:max(320px,100dvh - 320px);min-height:0}.IIa07q_skEvolutionSplit>.IIa07q_skList,.IIa07q_skEvolutionSplit>.IIa07q_skPane{overscroll-behavior-y:contain;min-height:0;overflow-y:auto}.IIa07q_skEvolutionSplit>.IIa07q_skList>*{flex-shrink:0}.IIa07q_skListBar{border-bottom:.5px solid var(--mn-line);align-items:center;gap:8px;padding:10px;display:flex}.IIa07q_skListBar>:first-child{flex:1;min-width:0}.IIa07q_skListNote{color:var(--mn-faint);text-align:center;margin:0;padding:18px 16px;font-size:12px;line-height:18px}.IIa07q_skListFilter{padding:8px 10px 2px}.IIa07q_skListGroup h5{color:var(--mn-faint);letter-spacing:.02em;text-overflow:ellipsis;white-space:nowrap;margin:14px 16px 4px;font-size:11px;font-weight:500;line-height:16px;overflow:hidden}.IIa07q_skListItem{border-radius:var(--dsw-radius-md);width:calc(100% - 12px);color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;margin:4px 6px 0;padding:9px 10px;transition:background-color .14s;display:block}.IIa07q_skListItem:hover{background:var(--mn-hover)}.IIa07q_skListItem[data-selected]{background:var(--mn-fill)}.IIa07q_skListItem>div{align-items:center;gap:6px;min-width:0;display:flex}.IIa07q_skListItem>div strong{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:13px;font-weight:500;line-height:20px;overflow:hidden}.IIa07q_skListItem p{color:var(--mn-muted);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:3px 0 4px;font-size:12px;line-height:18px;display:-webkit-box;overflow:hidden}.IIa07q_skListItem footer{min-width:0;color:var(--mn-faint);align-items:center;gap:8px;font-size:11px;line-height:16px;display:flex}.IIa07q_skListItem footer time{font-variant-numeric:tabular-nums;flex:none}.IIa07q_skListItem footer span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.IIa07q_skIcon{border-radius:var(--dsw-radius-md);width:30px;height:30px;color:var(--mn-muted);background:var(--mn-fill);flex:none;place-items:center;font-size:13px;font-weight:600;line-height:1;transition:color .14s,background-color .14s;display:grid}.IIa07q_skRow{border-radius:var(--dsw-radius-md);align-items:center;gap:6px;margin:2px 6px 0;padding-right:8px;transition:background-color .14s;display:flex;position:relative}.IIa07q_skRow:hover{background:var(--mn-hover)}.IIa07q_skRow[data-selected]{background:var(--mn-fill)}.IIa07q_skRow[data-selected] .IIa07q_skIcon{color:var(--mn-text);background:var(--mn-layer-1,var(--mn-hover))}.IIa07q_skRow[data-off] .IIa07q_skRowText,.IIa07q_skRow[data-shadowed] .IIa07q_skRowText{opacity:.55}.IIa07q_skRowMain{min-width:0;color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:10px;padding:8px 0 8px 8px;display:flex}.IIa07q_skRowMain:focus-visible{box-shadow:inset 0 0 0 2px var(--dsw-focus-ring-color,var(--mn-accent));border-radius:var(--dsw-radius-md);outline:none}.IIa07q_skRowText{gap:1px;min-width:0;transition:opacity .14s;display:grid}.IIa07q_skRowText strong{white-space:nowrap;align-items:center;gap:6px;min-width:0;font-size:13px;font-weight:500;line-height:20px;display:flex}.IIa07q_skRowText strong>span{text-overflow:ellipsis;min-width:0;overflow:hidden}.IIa07q_skRowText small{color:var(--mn-faint);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}.IIa07q_skScore{min-width:24px;color:var(--mn-muted);font-variant-numeric:tabular-nums;text-align:right;flex:none;font-size:13px;font-weight:500;line-height:20px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-pop}.IIa07q_skScore[data-tone=good]{color:var(--mn-success)}.IIa07q_skScore[data-tone=bad]{color:var(--mn-danger)}.IIa07q_skDot{background:var(--mn-accent);border-radius:999px;flex:none;width:6px;height:6px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-pop}.IIa07q_skRowActions{flex:none;align-items:center;gap:8px;display:flex}.IIa07q_skUse{opacity:0;pointer-events:none;transition:opacity .14s,transform .18s cubic-bezier(.2,0,0,1);transform:translate(4px)}.IIa07q_skRow:hover .IIa07q_skUse,.IIa07q_skRow:focus-within .IIa07q_skUse{opacity:1;pointer-events:auto;transform:none}@media (hover:none){.IIa07q_skUse{opacity:1;pointer-events:auto;transform:none}}.IIa07q_skProblems{color:var(--mn-faint);margin:12px 12px 4px;font-size:12px;line-height:18px}.IIa07q_skProblems summary{border-radius:var(--dsw-radius-xs,4px);cursor:pointer;width:fit-content;padding:0 2px}.IIa07q_skProblems summary:hover{color:var(--mn-muted)}.IIa07q_skProblems ul{gap:6px;margin:8px 0 0;padding:0;list-style:none;display:grid}.IIa07q_skProblems li{gap:2px;display:grid}.IIa07q_skProblems code{color:var(--mn-muted);font:11px/16px var(--mn-code)}.IIa07q_skDetail{grid-template-columns:minmax(0,1fr);gap:14px;min-width:0;animation:.2s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skDetailHead{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.IIa07q_skDetailHead>div:first-child{gap:4px;min-width:0;display:grid}.IIa07q_skDetailHead h3{overflow-wrap:anywhere;margin:0;font-size:17px;font-weight:600;line-height:26px}.IIa07q_skDetailHead p{color:var(--mn-muted);margin:0;font-size:13px;line-height:20px}.IIa07q_skDetailActions{flex-wrap:wrap;flex:none;justify-content:flex-end;align-items:center;gap:6px;display:flex}.IIa07q_skKicker{flex-wrap:wrap;align-items:center;gap:6px;display:inline-flex}.IIa07q_skTitleLink{color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;padding:0}.IIa07q_skTitleLink:hover{color:var(--dsw-alias-link,var(--mn-accent))}.IIa07q_skMeta{min-width:0;color:var(--mn-faint);flex-wrap:wrap;align-items:center;gap:0 6px;font-size:12px;line-height:18px;display:flex}.IIa07q_skMeta>*+:before{content:\"·\";color:var(--mn-line-strong,var(--mn-faint));margin-right:6px}.IIa07q_skMeta code{min-width:0;max-width:100%;font:11px/18px var(--mn-code);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.IIa07q_skInvocation{align-items:center;gap:8px;display:flex}.IIa07q_skWhen{color:var(--mn-muted);margin:0;font-size:12px;line-height:18px}.IIa07q_skDoc{overflow-wrap:anywhere;min-width:0;color:var(--mn-text);font-size:13px;line-height:1.75}.IIa07q_skDoc>:first-child{margin-top:0}.IIa07q_skDoc>:last-child{margin-bottom:0}.IIa07q_skDoc h1,.IIa07q_skDoc h2,.IIa07q_skDoc h3,.IIa07q_skDoc h4{color:var(--mn-text);margin:1.4em 0 .5em;font-weight:600;line-height:1.4}.IIa07q_skDoc h1{font-size:1.25em}.IIa07q_skDoc h2{font-size:1.1em}.IIa07q_skDoc h3,.IIa07q_skDoc h4{font-size:1em}.IIa07q_skDoc p,.IIa07q_skDoc ul,.IIa07q_skDoc ol,.IIa07q_skDoc blockquote,.IIa07q_skDoc table,.IIa07q_skDoc pre{margin:.7em 0}.IIa07q_skDoc ul,.IIa07q_skDoc ol{padding-left:1.5em}.IIa07q_skDoc li+li{margin-top:.25em}.IIa07q_skDoc li::marker{color:var(--mn-faint)}.IIa07q_skDoc blockquote{border-left:2px solid var(--mn-line-strong,var(--mn-line));color:var(--mn-muted);margin-inline:0;padding:.1em 1em}.IIa07q_skDoc code{border-radius:var(--dsw-radius-xs,4px);color:var(--mn-text);background:var(--dsw-alias-markdown-inline-code,var(--mn-fill));font:.9em/1.55 var(--mn-code);padding:.12em .38em}.IIa07q_skDoc pre{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-markdown-code-block,var(--mn-fill));max-width:100%;padding:10px 14px;overflow:auto}.IIa07q_skDoc pre code{background:0 0;padding:0;font-size:12px}.IIa07q_skDoc a{color:var(--dsw-alias-link,var(--mn-accent));text-underline-offset:3px;text-decoration-thickness:1px}.IIa07q_skDoc hr{border:0;border-top:.5px solid var(--mn-line);margin:1.6em 0}.IIa07q_skDoc table{border-collapse:collapse;max-width:100%;font-size:12px;display:block;overflow-x:auto}.IIa07q_skDoc th,.IIa07q_skDoc td{border:.5px solid var(--mn-line);text-align:left;vertical-align:top;padding:6px 10px}.IIa07q_skDoc th{background:var(--mn-fill);font-weight:500}.IIa07q_skDoc img{border-radius:var(--dsw-radius-sm);max-width:100%;height:auto}.IIa07q_skFolds{border-top:.5px solid var(--mn-line);grid-template-columns:minmax(0,1fr);min-width:0;margin-top:4px;display:grid}.IIa07q_skFold{border-bottom:.5px solid var(--mn-line);min-width:0}.IIa07q_skFold>header{justify-content:space-between;align-items:center;gap:12px;min-height:40px;display:flex}.IIa07q_skFold>header>button{border-radius:var(--dsw-radius-sm);min-width:0;color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:8px;margin-left:-4px;padding:8px 4px;font-size:13px;font-weight:500;line-height:20px;display:flex}.IIa07q_skFold>header>button>svg{color:var(--mn-faint);flex:none;transition:transform .18s cubic-bezier(.2,0,0,1),color .12s;transform:rotate(-90deg)}.IIa07q_skFold[data-open]>header>button>svg{transform:none}.IIa07q_skFold>header>button:hover>svg{color:var(--mn-text)}.IIa07q_skFold>header>button>small{min-width:0;color:var(--mn-faint);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:400;overflow:hidden}.IIa07q_skFold>header>button:focus-visible{box-shadow:0 0 0 2px var(--dsw-focus-ring-color,var(--mn-accent));outline:none}.IIa07q_skFold>header>div{align-items:center;gap:6px;display:flex}.IIa07q_skFoldBody{grid-template-columns:minmax(0,1fr);gap:10px;min-width:0;padding:2px 0 14px;display:grid}.IIa07q_skFold[data-link]>header>button{padding-left:24px}.IIa07q_skFold[data-link]>header>button>b{color:var(--mn-faint);margin-left:auto;font-weight:400;transition:transform .16s cubic-bezier(.2,0,0,1),color .12s}.IIa07q_skFold[data-link]>header>button:hover>b{color:var(--dsw-alias-link,var(--mn-accent));transform:translate(2px)}.IIa07q_skVersions{grid-template-columns:minmax(0,1fr);gap:1px;margin:0;padding:0;list-style:none;display:grid}.IIa07q_skVersions li{border-radius:var(--dsw-radius-md);align-items:center;gap:10px;min-height:34px;padding:3px 6px;transition:background-color .12s;display:flex}.IIa07q_skVersions li:hover{background:var(--mn-hover)}.IIa07q_skVersions time{color:var(--mn-muted);font-variant-numeric:tabular-nums;font-size:12px}.IIa07q_skVersions li>span{flex:1}.IIa07q_skTrashList li{flex-wrap:wrap;padding-block:10px}.IIa07q_skTrashList li>span{flex:none}.IIa07q_skTrashList li>.IIa07q_skRowText{flex:220px}.IIa07q_skTrashTags{flex-wrap:wrap;gap:6px;display:flex}.IIa07q_skTrashList li>.IIa07q_skTrashActions{flex:none;gap:6px;margin-left:auto;display:flex}.IIa07q_skResources{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skResources code{color:var(--mn-muted);background:var(--mn-fill);font:11px/17px var(--mn-code);border-radius:999px;padding:1px 8px}.IIa07q_skEditor{resize:vertical;border:.5px solid var(--mn-field-line);border-radius:var(--dsw-radius-md);width:100%;min-height:420px;color:var(--mn-text);background:var(--mn-input);font:12px/1.6 var(--mn-code);tab-size:2;outline:0;padding:10px 12px;transition:border-color .12s}.IIa07q_skEditor:focus{border-color:var(--mn-accent)}.IIa07q_skTimeline{grid-template-columns:minmax(0,1fr);gap:0;min-width:0;margin:0;padding:0;list-style:none;display:grid}.IIa07q_skTimeline>li{min-width:0}.IIa07q_skTurn{color:var(--mn-faint);letter-spacing:.02em;margin:12px 0 4px;font-size:11px;font-weight:500;line-height:16px}.IIa07q_skTimeline>li:first-child>.IIa07q_skTurn{margin-top:0}.IIa07q_skStep{border-radius:0 var(--dsw-radius-sm) var(--dsw-radius-sm) 0;border-left:2px solid #0000;align-items:flex-start;gap:8px;padding:5px 8px;transition:background-color .14s;display:flex}.IIa07q_skTimeline>li[data-annotated] .IIa07q_skStep{border-left-color:color-mix(in srgb, var(--mn-warn) 70%, transparent);background:color-mix(in srgb, var(--mn-warn) 5%, transparent)}.IIa07q_skTimeline>li[data-highlight] .IIa07q_skStep{border-left-color:var(--mn-accent);background:color-mix(in srgb, var(--mn-accent) 6%, transparent)}.IIa07q_skStepIndex{width:22px;color:var(--mn-faint);text-align:right;font-variant-numeric:tabular-nums;flex:none;font-size:11px;line-height:20px}.IIa07q_skStepGlyph{width:14px;color:var(--mn-faint);text-align:center;flex:none;font-size:12px;line-height:20px}.IIa07q_skTimeline>li[data-kind=skill] .IIa07q_skStepGlyph{color:var(--mn-accent)}.IIa07q_skTimeline>li[data-failed] .IIa07q_skStepGlyph{color:var(--mn-danger)}.IIa07q_skStepBody{flex:1;min-width:0}.IIa07q_skStepHead{flex-wrap:wrap;align-items:center;gap:6px;min-width:0;display:flex}.IIa07q_skStepHead strong{font-size:12px;font-weight:500;line-height:20px}.IIa07q_skStepHead code{min-width:0;max-width:100%;color:var(--mn-faint);font:11px/18px var(--mn-code);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.IIa07q_skStepBody>p{overflow-wrap:anywhere;color:var(--mn-muted);white-space:pre-wrap;margin:1px 0 0;font-size:12px;line-height:18px}.IIa07q_skTimeline[data-compact] .IIa07q_skStepBody>p{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.IIa07q_skAnnotation{color:var(--mn-text);align-items:flex-start;gap:6px;margin-top:6px;font-size:12px;line-height:18px;display:flex}.IIa07q_skEvidence+.IIa07q_skEvidence{margin-top:14px}.IIa07q_skEvidence>header{align-items:center;gap:8px;min-width:0;margin-bottom:6px;display:flex}.IIa07q_skEvidence>header strong{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12px;font-weight:500;overflow:hidden}.IIa07q_skEvidence>header span{color:var(--mn-faint);flex:none;font-size:11px}.IIa07q_skEvidence>header button{margin-left:auto}.IIa07q_skChips{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skDeriveBar{border-radius:var(--dsw-radius-md);background:var(--mn-fill);color:var(--mn-muted);flex-wrap:wrap;align-items:center;gap:8px;padding:8px 10px;font-size:12px;line-height:18px;display:flex}.IIa07q_skDeriveBar>span{min-width:0;margin-right:auto}.IIa07q_skDraft{border-top:.5px solid var(--mn-line);grid-template-columns:minmax(0,1fr);gap:12px;min-width:0;padding-top:14px;display:grid}.IIa07q_skSectionHead{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 12px;display:flex}.IIa07q_skSectionHead h4{align-items:baseline;gap:8px;margin:0;font-size:14px;font-weight:600;line-height:22px;display:flex}.IIa07q_skSectionHead h4 small{color:var(--mn-faint);font-size:12px;font-weight:400}.IIa07q_skSectionHead>div{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skChanges{color:var(--mn-muted);gap:3px;margin:0;padding-left:18px;font-size:12px;line-height:18px;display:grid}.IIa07q_skChanges li::marker{color:var(--mn-faint)}.IIa07q_skGuidance{color:var(--mn-faint);gap:2px;margin:0;padding-left:18px;font-size:12px;line-height:18px;display:grid}.IIa07q_skBacktest{border-radius:var(--dsw-radius-md);background:var(--mn-fill);flex-wrap:wrap;align-items:center;gap:6px 10px;min-height:36px;padding:4px 6px 4px 12px;display:flex}.IIa07q_skBacktestLine{min-width:0;color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:10px;padding:4px 0;font-size:12px;line-height:18px;display:flex}.IIa07q_skBacktestLine>span{color:var(--mn-faint);flex:none}.IIa07q_skBacktestLine>strong{text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;min-width:0;font-weight:500;overflow:hidden}.IIa07q_skBacktestLine>em{color:var(--mn-muted);background:var(--mn-hover);font-variant-numeric:tabular-nums;border-radius:999px;flex:none;padding:0 7px;font-style:normal;font-weight:600}.IIa07q_skBacktest[data-tone=good] .IIa07q_skBacktestLine>em{color:var(--mn-success);background:color-mix(in srgb, var(--mn-success) 12%, transparent)}.IIa07q_skBacktest[data-tone=bad] .IIa07q_skBacktestLine>em{color:var(--mn-danger);background:color-mix(in srgb, var(--mn-danger) 12%, transparent)}.IIa07q_skBacktestLine:hover>strong{text-underline-offset:3px;text-decoration:underline;text-decoration-color:var(--mn-line-strong,var(--mn-faint))}.IIa07q_skTable{border-collapse:collapse;width:100%;font-size:12px;line-height:18px;animation:.18s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive}.IIa07q_skTable th{border-bottom:.5px solid var(--mn-line);color:var(--mn-faint);text-align:left;padding:6px 8px;font-weight:500}.IIa07q_skTable td{border-bottom:.5px solid var(--mn-line);vertical-align:top;padding:7px 8px}.IIa07q_skTable td small{color:var(--mn-faint);margin-top:3px;display:block}.IIa07q_skComposer{border-radius:var(--dsw-radius-lg);background:var(--mn-fill);grid-template-columns:minmax(0,1fr);gap:8px;padding:12px;animation:.18s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skComposer label{color:var(--mn-muted);gap:6px;font-size:12px;font-weight:500;line-height:18px;display:grid}.IIa07q_skComposer textarea{resize:vertical;border:.5px solid var(--mn-field-line);border-radius:var(--dsw-radius-md);width:100%;color:var(--mn-text);background:var(--mn-input);font:inherit;outline:0;padding:6px 10px;font-size:13px;line-height:20px;transition:border-color .12s}.IIa07q_skComposer textarea:focus{border-color:var(--mn-accent)}.IIa07q_skComposer>footer{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;display:flex}.IIa07q_skTests{grid-template-columns:minmax(0,1fr);gap:10px;min-width:0;display:grid}.IIa07q_skTestsBar{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skCases{grid-template-columns:minmax(0,1fr);gap:1px;margin:0;padding:0;list-style:none;display:grid}.IIa07q_skCases>li{border-radius:var(--dsw-radius-md);align-items:flex-start;gap:8px;padding:2px 4px 2px 0;transition:background-color .12s,opacity .14s;display:flex}.IIa07q_skCases>li:hover{background:var(--mn-hover)}.IIa07q_skCases>li[data-off]>details{opacity:.5}.IIa07q_skCases>li>details{flex:1;min-width:0}.IIa07q_skCases>li>:not(details){margin-top:6px}.IIa07q_skCases summary{border-radius:var(--dsw-radius-md);cursor:pointer;align-items:baseline;gap:8px;min-width:0;padding:7px 8px;list-style:none;display:flex}.IIa07q_skCases summary::-webkit-details-marker{display:none}.IIa07q_skCases summary strong{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:13px;font-weight:500;line-height:20px;overflow:hidden}.IIa07q_skCases summary small{color:var(--mn-faint);flex:none;font-size:11px}.IIa07q_skCases details[open] summary strong{white-space:normal}.IIa07q_skCases details>p{color:var(--mn-muted);white-space:pre-wrap;overflow-wrap:anywhere;margin:0 8px 8px;font-size:12px;line-height:18px}.IIa07q_skCases details>ul{gap:4px;margin:0 8px 8px;padding:0;list-style:none;display:grid}.IIa07q_skCases details>ul li{color:var(--mn-text);align-items:flex-start;gap:6px;font-size:12px;line-height:18px;display:flex}.IIa07q_skCases details>.IIa07q_skLink{margin:0 6px 8px}.IIa07q_skRuns{grid-template-columns:minmax(0,1fr);gap:1px;margin:0;padding:0;list-style:none;display:grid}.IIa07q_skRuns>li>button{border-radius:var(--dsw-radius-md);width:100%;min-width:0;color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:center;gap:8px;padding:7px 8px;font-size:12px;line-height:18px;transition:background-color .12s;display:flex}.IIa07q_skRuns>li>button:hover,.IIa07q_skRuns>li>button[aria-expanded=true]{background:var(--mn-hover)}.IIa07q_skRuns>li>button>:first-child{flex:none}.IIa07q_skRuns>li>button span{min-width:0;color:var(--mn-muted);text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;flex:1;overflow:hidden}.IIa07q_skRuns>li>button time{color:var(--mn-faint);flex:none;font-size:11px}.IIa07q_skRunDetail{border-left:.5px solid var(--mn-line);grid-template-columns:minmax(0,1fr);gap:2px;margin:4px 0 8px 12px;padding-left:10px;animation:.18s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skRunDetail details{padding:4px 0}.IIa07q_skRunDetail summary{cursor:pointer;align-items:center;gap:8px;min-width:0;font-size:12px;line-height:18px;display:flex}.IIa07q_skRunDetail summary strong{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:500;overflow:hidden}.IIa07q_skRunDetail summary span{color:var(--mn-faint);font-variant-numeric:tabular-nums}.IIa07q_skRunDetail h6{color:var(--mn-faint);margin:8px 0 4px;font-size:11px;font-weight:500}.IIa07q_skVerdicts{grid-template-columns:minmax(0,1fr);gap:2px;margin:6px 0;padding:0;font-size:12px;line-height:18px;list-style:none;display:grid}.IIa07q_skVerdicts li{color:var(--mn-muted);gap:6px;display:flex}.IIa07q_skVerdicts li b{color:var(--mn-danger)}.IIa07q_skVerdicts li[data-pass] b{color:var(--mn-success)}.IIa07q_skRunSteps{color:var(--mn-muted);margin:0;padding-left:18px;font-size:12px;line-height:18px}.IIa07q_skAnswer{border-radius:var(--dsw-radius-md);max-height:240px;color:var(--mn-text);background:var(--mn-fill);font:12px/1.55 var(--mn-code);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;padding:8px 10px;overflow:auto}.IIa07q_skForm{gap:14px;display:grid}.IIa07q_skField{gap:6px;display:grid}.IIa07q_skField>label{color:var(--mn-muted);font-size:12px;font-weight:500;line-height:18px}.IIa07q_skForm input:not([type=checkbox]):not([type=radio]),.IIa07q_skForm textarea{border:.5px solid var(--mn-field-line);border-radius:var(--dsw-radius-md);width:100%;color:var(--mn-text);background:var(--mn-input);font:inherit;outline:0;padding:7px 10px;font-size:13px;line-height:20px;transition:border-color .12s}.IIa07q_skForm input:not([type=checkbox]):not([type=radio]):focus,.IIa07q_skForm textarea:focus{border-color:var(--mn-accent)}.IIa07q_skForm textarea{resize:vertical}.IIa07q_skForm small{color:var(--mn-faint);font-size:11px;line-height:16px}.IIa07q_skFormRow{display:flex}.IIa07q_skFormError{color:var(--mn-danger);margin-right:auto;font-size:12px}.IIa07q_skChecks{border:0;gap:6px;margin:0;padding:0;display:grid}.IIa07q_skChecks legend{color:var(--mn-muted);margin-bottom:6px;font-size:12px;font-weight:500}.IIa07q_skChecks>div{align-items:center;gap:10px;display:flex}.IIa07q_skChecks>div>input{flex:1;min-width:0}.IIa07q_skMust{color:var(--mn-muted);white-space:nowrap;flex:none;font-size:12px}.IIa07q_skChecks>button{justify-self:start}.IIa07q_skMarket{gap:14px;display:grid}.IIa07q_skMarketBar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.IIa07q_skMarketBar>:first-child{flex:1;min-width:220px}.IIa07q_skMarketGrid{grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:12px;display:grid}.IIa07q_skMarketCard{border:.5px solid var(--mn-card-line);border-radius:var(--dsw-radius-lg);background:0 0;flex-direction:column;min-width:0;transition:border-color .16s,box-shadow .2s,transform .2s cubic-bezier(.2,0,0,1);animation:.24s cubic-bezier(.2,0,0,1) backwards IIa07q_sk-arrive;display:flex}.IIa07q_skMarketCard:hover{border-color:var(--mn-line-strong,var(--mn-card-line));box-shadow:var(--dsw-elevation-soft,0 4px 16px #0000000f);transform:translateY(-1px)}.IIa07q_skMarketCard:hover .IIa07q_skIcon{color:var(--mn-text)}.IIa07q_skMarketOpen{color:var(--mn-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-content:start;gap:10px;padding:14px 14px 6px;display:grid}.IIa07q_skMarketOpen:focus-visible{box-shadow:inset 0 0 0 2px var(--dsw-focus-ring-color,var(--mn-accent));border-radius:var(--dsw-radius-lg);outline:none}.IIa07q_skMarketOpen>header{align-items:center;gap:10px;min-width:0;display:flex}.IIa07q_skMarketOpen>header>div{min-width:0;display:grid}.IIa07q_skMarketOpen strong{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;line-height:20px;overflow:hidden}.IIa07q_skMarketOpen code{color:var(--mn-faint);font:11px/16px var(--mn-code);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.IIa07q_skMarketOpen p{color:var(--mn-muted);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:0;font-size:12px;line-height:18px;display:-webkit-box;overflow:hidden}.IIa07q_skMarketCard>footer{justify-content:space-between;align-items:center;gap:8px;min-height:42px;padding:0 12px 10px 14px;display:flex}.IIa07q_skMarketCard>footer>span{min-width:0;color:var(--mn-faint);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.IIa07q_skMarketDetail{gap:12px;display:grid}.IIa07q_skInline{align-items:center;gap:8px;display:flex}.IIa07q_skInline>:first-child{flex:1;min-width:0}.IIa07q_skMarketSection{gap:8px;animation:.2s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:grid}.IIa07q_skMarketGrid{transition:opacity .16s}.IIa07q_skMarketGrid[data-busy]{opacity:.55}.IIa07q_skMarketAdd{border-radius:var(--dsw-radius-md);background:color-mix(in srgb, var(--mn-accent) 7%, transparent);align-items:center;gap:10px;min-width:0;padding:6px 6px 6px 8px;font-size:12px;line-height:18px;animation:.2s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:flex}.IIa07q_skMarketAdd>span:nth-child(2){min-width:0;color:var(--mn-text);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.IIa07q_skMarketAdd .IIa07q_skSourceIcon{background:var(--mn-layer-1,var(--mn-fill));width:26px;height:26px}.IIa07q_skMarketStat{font-variant-numeric:tabular-nums;align-items:center;gap:4px;display:inline-flex}.IIa07q_skMarketCard[data-indexed] .IIa07q_skMarketOpen{padding-bottom:4px}.IIa07q_skMarketMeta{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px 12px;display:flex}.IIa07q_skAudits{gap:6px;display:grid}.IIa07q_skAudits>div{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.IIa07q_skAuditsLabel{color:var(--mn-faint);margin-right:2px;font-size:12px;line-height:18px}.IIa07q_skAudit{color:var(--mn-text);background:var(--mn-fill);border-radius:999px;align-items:center;gap:6px;padding:2px 9px 2px 8px;font-size:12px;line-height:18px;animation:.26s cubic-bezier(.2,0,0,1) IIa07q_sk-pop;display:inline-flex}.IIa07q_skAudit:before{content:\"\";background:var(--mn-success);border-radius:999px;flex:none;width:6px;height:6px}.IIa07q_skAudit[data-status=warn]:before{background:var(--mn-warn)}.IIa07q_skAudit[data-status=fail]:before{background:var(--mn-danger)}.IIa07q_skAudit small{color:var(--mn-faint);font-size:11px}.IIa07q_skSources{gap:18px;display:grid}.IIa07q_skSourceList{gap:2px;margin:0 -6px;padding:0;list-style:none;display:grid}.IIa07q_skSourceList>li{border-radius:var(--dsw-radius-md);align-items:center;gap:12px;min-width:0;padding:8px 8px 8px 6px;transition:background-color .14s;animation:.2s cubic-bezier(.2,0,0,1) IIa07q_sk-arrive;display:flex}.IIa07q_skSourceList>li:hover{background:var(--mn-hover)}.IIa07q_skSourceIcon{border-radius:var(--dsw-radius-md);width:32px;height:32px;color:var(--mn-muted);background:var(--mn-fill);flex:none;place-items:center;transition:opacity .14s;display:grid}.IIa07q_skSourceText{flex:1;gap:1px;min-width:0;transition:opacity .14s;display:grid}.IIa07q_skSourceText>strong{align-items:center;gap:6px;min-width:0;font-size:13px;font-weight:500;line-height:20px;display:flex}.IIa07q_skSourceText>strong>span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.IIa07q_skSourceText>small,.IIa07q_skSourceText>em{text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-style:normal;line-height:18px;overflow:hidden}.IIa07q_skSourceText>small{color:var(--mn-faint)}.IIa07q_skSourceText>em{color:var(--mn-danger)}.IIa07q_skSourceList>li[data-off] .IIa07q_skSourceText,.IIa07q_skSourceList>li[data-off] .IIa07q_skSourceIcon{opacity:.5}.IIa07q_skSourceActions{flex:none;align-items:center;gap:6px;display:flex}.IIa07q_skSourceAdd{border-top:.5px solid var(--mn-line);gap:6px;padding-top:16px;display:grid}.IIa07q_skSourceAdd>label{font-size:13px;font-weight:500;line-height:20px}.IIa07q_skSourceHint{min-height:18px;color:var(--mn-faint);text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:12px;line-height:18px;transition:color .14s;overflow:hidden}.IIa07q_skSourceHint[data-state=ok]{color:var(--mn-muted)}.IIa07q_skSourceHint[data-state=warn]{color:var(--mn-warn)}.IIa07q_skFormat summary{border-radius:var(--dsw-radius-xs,4px);width:fit-content;color:var(--mn-muted);cursor:pointer;padding:0 2px;font-size:12px;line-height:18px}.IIa07q_skFormat summary:hover{color:var(--mn-text)}.IIa07q_skFormat ul{gap:12px;margin:12px 0 0;padding:0;list-style:none;display:grid}.IIa07q_skFormat li{align-items:flex-start;gap:10px;display:flex}.IIa07q_skFormat li .IIa07q_skSourceIcon{width:26px;height:26px}.IIa07q_skFormat li>div{gap:1px;font-size:12px;line-height:18px;display:grid}.IIa07q_skFormat li strong{font-weight:500}.IIa07q_skFormat li span{color:var(--mn-muted)}@media (width<=860px){.IIa07q_skSplit{grid-template-columns:minmax(0,1fr)}.IIa07q_skList{max-height:360px;overflow-y:auto}.IIa07q_skEvolutionSplit{height:auto}.IIa07q_skEvolutionSplit>.IIa07q_skPane{overscroll-behavior-y:auto;overflow:visible}}@media (width<=560px){.IIa07q_skDetailHead{flex-direction:column}.IIa07q_skDetailActions{justify-content:flex-start}}@media (prefers-reduced-motion:reduce){.IIa07q_skPage,.IIa07q_skDetail,.IIa07q_skEmpty,.IIa07q_skTable,.IIa07q_skComposer,.IIa07q_skRunDetail,.IIa07q_skMarketCard,.IIa07q_skMarketSection,.IIa07q_skMarketAdd,.IIa07q_skAudit,.IIa07q_skSourceList>li,.IIa07q_skTabBadge,.IIa07q_skDot,.IIa07q_skScore{animation:none}.IIa07q_skUse,.IIa07q_skFold>header>button>svg,.IIa07q_skFold[data-link]>header>button>b,.IIa07q_skCallout>b,.IIa07q_skMarketCard{transition:none}.IIa07q_skIconButton[data-busy]>svg,.IIa07q_skIconButton[data-pulse]>svg{animation:none}}";
|
|
832
883
|
const id = "dsh-mnemon-source-skills/presentation/page.module.css";
|
|
833
884
|
if (typeof document !== "undefined") {
|
|
834
885
|
let tag = document.querySelector("style[data-plugin-css=" + JSON.stringify(id) + "]");
|
|
@@ -874,6 +925,7 @@ window.__ModuleLoader__.load({
|
|
|
874
925
|
"skEmpty": "IIa07q_skEmpty",
|
|
875
926
|
"skEmptyActions": "IIa07q_skEmptyActions",
|
|
876
927
|
"skEvidence": "IIa07q_skEvidence",
|
|
928
|
+
"skEvolutionSplit": "IIa07q_skEvolutionSplit",
|
|
877
929
|
"skField": "IIa07q_skField",
|
|
878
930
|
"skFold": "IIa07q_skFold",
|
|
879
931
|
"skFoldBody": "IIa07q_skFoldBody",
|
|
@@ -1008,6 +1060,148 @@ window.__ModuleLoader__.load({
|
|
|
1008
1060
|
return error instanceof Error ? error.message : String(error);
|
|
1009
1061
|
}
|
|
1010
1062
|
//#endregion
|
|
1063
|
+
//#region src/client/model-choice.tsx
|
|
1064
|
+
/**
|
|
1065
|
+
* The model pickers the Evolution and Evaluation pages share: which model
|
|
1066
|
+
* drafts and backtests run on, globally and per item, offered from the same
|
|
1067
|
+
* directory the task Agent resolves its own route against.
|
|
1068
|
+
*
|
|
1069
|
+
* A pick is stored as `provider|model`, so one menu value names one route, and
|
|
1070
|
+
* an absent pick is `auto`: the page follows the task Agent, as it did before
|
|
1071
|
+
* the user picked anything.
|
|
1072
|
+
*/
|
|
1073
|
+
/** The menu value of a pick; `auto` asks for no pick at all. */
|
|
1074
|
+
function modelOptionValue(model) {
|
|
1075
|
+
if (model === null || model === void 0) return "auto";
|
|
1076
|
+
return `${model.provider}|${model.model}`;
|
|
1077
|
+
}
|
|
1078
|
+
/** The pick a menu value names; `auto` and a malformed value both pick nothing. */
|
|
1079
|
+
function modelOptionPick(value) {
|
|
1080
|
+
const at = value.indexOf("|");
|
|
1081
|
+
if (at <= 0) return null;
|
|
1082
|
+
return {
|
|
1083
|
+
provider: value.slice(0, at),
|
|
1084
|
+
model: value.slice(at + 1)
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Follow-default first, then every Provider's models. The first entry exists
|
|
1089
|
+
* before the directory arrives, so the toolbar holds its place instead of
|
|
1090
|
+
* appearing a round trip later than the rest of the page.
|
|
1091
|
+
*/
|
|
1092
|
+
function modelOptionsFrom(models, t, autoKey) {
|
|
1093
|
+
const options = [{
|
|
1094
|
+
value: "auto",
|
|
1095
|
+
label: models?.effective?.model ?? models?.inherited?.model ?? models?.defaultSelection?.model ?? t(autoKey),
|
|
1096
|
+
detail: t("evolution.modelAutoHint")
|
|
1097
|
+
}];
|
|
1098
|
+
if (models === null) return options;
|
|
1099
|
+
for (const group of models.groups) for (const entry of group.models) options.push({
|
|
1100
|
+
value: `${group.id}|${entry.id}`,
|
|
1101
|
+
label: entry.name,
|
|
1102
|
+
detail: group.name
|
|
1103
|
+
});
|
|
1104
|
+
return options;
|
|
1105
|
+
}
|
|
1106
|
+
/** The same list for one card: follow-default, then the directory without its own default entry. */
|
|
1107
|
+
function modelCardOptionsFrom(modelOptions, t, autoKey) {
|
|
1108
|
+
return [{
|
|
1109
|
+
value: "auto",
|
|
1110
|
+
label: t(autoKey)
|
|
1111
|
+
}, ...modelOptions.slice(1)];
|
|
1112
|
+
}
|
|
1113
|
+
const NO_PREFERENCES = {
|
|
1114
|
+
suggestionModels: {},
|
|
1115
|
+
skillRunModels: {}
|
|
1116
|
+
};
|
|
1117
|
+
/**
|
|
1118
|
+
* Read the directory and the stored picks alongside the page's own data, and
|
|
1119
|
+
* write one pick at a time. A write shows locally first so the menu answers at
|
|
1120
|
+
* once, then takes the Host's answer, which is also what a second window sees.
|
|
1121
|
+
*/
|
|
1122
|
+
function useModelChoice(context, autoKey) {
|
|
1123
|
+
const t = useT();
|
|
1124
|
+
const [models, setModels] = (0, react.useState)(null);
|
|
1125
|
+
const [preferences, setPreferences] = (0, react.useState)(NO_PREFERENCES);
|
|
1126
|
+
(0, react.useEffect)(() => {
|
|
1127
|
+
let active = true;
|
|
1128
|
+
context.client.models().then((value) => {
|
|
1129
|
+
if (active) setModels(value);
|
|
1130
|
+
}).catch(() => void 0);
|
|
1131
|
+
return () => {
|
|
1132
|
+
active = false;
|
|
1133
|
+
};
|
|
1134
|
+
}, [context.client]);
|
|
1135
|
+
(0, react.useEffect)(() => {
|
|
1136
|
+
let active = true;
|
|
1137
|
+
context.client.draftPreferences().then((value) => {
|
|
1138
|
+
if (active) setPreferences(value);
|
|
1139
|
+
}).catch(() => void 0);
|
|
1140
|
+
return () => {
|
|
1141
|
+
active = false;
|
|
1142
|
+
};
|
|
1143
|
+
}, [context.client, context.revision]);
|
|
1144
|
+
/** Show the pick now, then let the Host's answer replace it; a failure shows through and reverts. */
|
|
1145
|
+
const write = (0, react.useCallback)((apply, operation) => {
|
|
1146
|
+
setPreferences((current) => apply(current));
|
|
1147
|
+
operation().then((next) => {
|
|
1148
|
+
setPreferences(next);
|
|
1149
|
+
context.refresh();
|
|
1150
|
+
}).catch((error) => {
|
|
1151
|
+
context.fail(error);
|
|
1152
|
+
context.refresh();
|
|
1153
|
+
});
|
|
1154
|
+
}, [context, context.client]);
|
|
1155
|
+
const options = (0, react.useMemo)(() => modelOptionsFrom(models, t, autoKey), [
|
|
1156
|
+
models,
|
|
1157
|
+
t,
|
|
1158
|
+
autoKey
|
|
1159
|
+
]);
|
|
1160
|
+
return {
|
|
1161
|
+
models,
|
|
1162
|
+
preferences,
|
|
1163
|
+
options,
|
|
1164
|
+
cardOptions: (0, react.useMemo)(() => modelCardOptionsFrom(options, t, autoKey), [
|
|
1165
|
+
options,
|
|
1166
|
+
t,
|
|
1167
|
+
autoKey
|
|
1168
|
+
]),
|
|
1169
|
+
saveDraftModel: (model) => write((current) => model === null ? omit(current, "model") : {
|
|
1170
|
+
...current,
|
|
1171
|
+
model
|
|
1172
|
+
}, () => context.client.saveDraftModel(model)),
|
|
1173
|
+
saveSuggestionModel: (id, model) => write((current) => {
|
|
1174
|
+
const suggestionModels = { ...current.suggestionModels };
|
|
1175
|
+
if (model === null) delete suggestionModels[id];
|
|
1176
|
+
else suggestionModels[id] = model;
|
|
1177
|
+
return {
|
|
1178
|
+
...current,
|
|
1179
|
+
suggestionModels
|
|
1180
|
+
};
|
|
1181
|
+
}, () => context.client.saveSuggestionModel(id, model)),
|
|
1182
|
+
saveRunModel: (model) => write((current) => model === null ? omit(current, "runModel") : {
|
|
1183
|
+
...current,
|
|
1184
|
+
runModel: model
|
|
1185
|
+
}, () => context.client.saveRunModel(model)),
|
|
1186
|
+
saveSkillRunModel: (skillName, model) => write((current) => {
|
|
1187
|
+
const skillRunModels = { ...current.skillRunModels };
|
|
1188
|
+
if (model === null) delete skillRunModels[skillName];
|
|
1189
|
+
else skillRunModels[skillName] = model;
|
|
1190
|
+
return {
|
|
1191
|
+
...current,
|
|
1192
|
+
skillRunModels
|
|
1193
|
+
};
|
|
1194
|
+
}, () => context.client.saveSkillRunModel(skillName, model))
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
/** The preferences without one optional pick, for the case a pick was cleared. */
|
|
1198
|
+
function omit(preferences, key) {
|
|
1199
|
+
if (preferences[key] === void 0) return preferences;
|
|
1200
|
+
const next = { ...preferences };
|
|
1201
|
+
delete next[key];
|
|
1202
|
+
return next;
|
|
1203
|
+
}
|
|
1204
|
+
//#endregion
|
|
1011
1205
|
//#region ../../node_modules/.pnpm/markdown-to-jsx@7.7.17_react@18.3.1/node_modules/markdown-to-jsx/dist/index.module.js
|
|
1012
1206
|
function n() {
|
|
1013
1207
|
return n = Object.assign ? Object.assign.bind() : function(r) {
|
|
@@ -2314,6 +2508,7 @@ window.__ModuleLoader__.load({
|
|
|
2314
2508
|
function SkillTests(props) {
|
|
2315
2509
|
const t = useT();
|
|
2316
2510
|
const { context, skillName } = props;
|
|
2511
|
+
const runModel = props.runModel ?? null;
|
|
2317
2512
|
const [cases, setCases] = (0, react.useState)(null);
|
|
2318
2513
|
const [runs, setRuns] = (0, react.useState)([]);
|
|
2319
2514
|
const [hasFile, setHasFile] = (0, react.useState)(true);
|
|
@@ -2349,7 +2544,11 @@ window.__ModuleLoader__.load({
|
|
|
2349
2544
|
try {
|
|
2350
2545
|
const started = await context.client.backtest({
|
|
2351
2546
|
skillName,
|
|
2352
|
-
target: { kind: hasFile ? "current" : "none" }
|
|
2547
|
+
target: { kind: hasFile ? "current" : "none" },
|
|
2548
|
+
...runModel === null ? {} : {
|
|
2549
|
+
provider: runModel.provider,
|
|
2550
|
+
model: runModel.model
|
|
2551
|
+
}
|
|
2353
2552
|
});
|
|
2354
2553
|
setOpenRun(started.runId);
|
|
2355
2554
|
context.refresh();
|
|
@@ -2716,6 +2915,7 @@ window.__ModuleLoader__.load({
|
|
|
2716
2915
|
const [proposed, setProposed] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
2717
2916
|
const [query, setQuery] = (0, react.useState)("");
|
|
2718
2917
|
const [selected, setSelected] = (0, react.useState)(location.skillName);
|
|
2918
|
+
const choice = useModelChoice(context, "tests.modelAuto");
|
|
2719
2919
|
(0, react.useEffect)(() => {
|
|
2720
2920
|
if (location.skillName !== void 0) setSelected(location.skillName);
|
|
2721
2921
|
}, [location.skillName, location.nonce]);
|
|
@@ -2775,7 +2975,45 @@ window.__ModuleLoader__.load({
|
|
|
2775
2975
|
rows: visible.filter((row) => row.cases === 0)
|
|
2776
2976
|
}].filter((group) => group.rows.length > 0);
|
|
2777
2977
|
const current = rows.find((row) => row.name === selected) ?? groups[0]?.rows[0] ?? rows[0];
|
|
2778
|
-
|
|
2978
|
+
const runOverride = Object.hasOwn(choice.preferences.skillRunModels, current.name) ? choice.preferences.skillRunModels[current.name] : null;
|
|
2979
|
+
const effectiveRunModel = runOverride ?? choice.preferences.runModel ?? null;
|
|
2980
|
+
const saveRun = (value) => choice.saveRunModel(modelOptionPick(value));
|
|
2981
|
+
const saveSkillRun = (value) => choice.saveSkillRunModel(current.name, modelOptionPick(value));
|
|
2982
|
+
const modelBar = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2983
|
+
className: css.skListBar,
|
|
2984
|
+
style: {
|
|
2985
|
+
borderBottom: "none",
|
|
2986
|
+
padding: "0 0 10px"
|
|
2987
|
+
},
|
|
2988
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2989
|
+
className: css.skSplit,
|
|
2990
|
+
style: {
|
|
2991
|
+
minHeight: 0,
|
|
2992
|
+
alignItems: "center",
|
|
2993
|
+
width: "100%"
|
|
2994
|
+
},
|
|
2995
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.SelectField, {
|
|
2996
|
+
label: t("tests.model"),
|
|
2997
|
+
triggerDetail: true,
|
|
2998
|
+
inline: true,
|
|
2999
|
+
size: "sm",
|
|
3000
|
+
value: modelOptionValue(choice.preferences.runModel),
|
|
3001
|
+
disabled: !context.writable || choice.models === null,
|
|
3002
|
+
onChange: saveRun,
|
|
3003
|
+
options: choice.options
|
|
3004
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.SelectField, {
|
|
3005
|
+
label: t("tests.modelCard"),
|
|
3006
|
+
triggerDetail: true,
|
|
3007
|
+
inline: true,
|
|
3008
|
+
size: "sm",
|
|
3009
|
+
value: modelOptionValue(runOverride),
|
|
3010
|
+
disabled: !context.writable || choice.models === null,
|
|
3011
|
+
onChange: saveSkillRun,
|
|
3012
|
+
options: choice.cardOptions
|
|
3013
|
+
})]
|
|
3014
|
+
})
|
|
3015
|
+
});
|
|
3016
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [modelBar, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2779
3017
|
className: css.skSplit,
|
|
2780
3018
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
2781
3019
|
className: css.skList,
|
|
@@ -2843,11 +3081,12 @@ window.__ModuleLoader__.load({
|
|
|
2843
3081
|
})] })] })] })
|
|
2844
3082
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkillTests, {
|
|
2845
3083
|
context,
|
|
2846
|
-
skillName: current.name
|
|
3084
|
+
skillName: current.name,
|
|
3085
|
+
runModel: effectiveRunModel
|
|
2847
3086
|
})]
|
|
2848
3087
|
}, current.name)
|
|
2849
3088
|
})]
|
|
2850
|
-
});
|
|
3089
|
+
})] });
|
|
2851
3090
|
}
|
|
2852
3091
|
//#endregion
|
|
2853
3092
|
//#region src/client/evidence-page.tsx
|
|
@@ -3132,6 +3371,8 @@ window.__ModuleLoader__.load({
|
|
|
3132
3371
|
const [drafts, setDrafts] = (0, react.useState)([]);
|
|
3133
3372
|
const [selected, setSelected] = (0, react.useState)(location.suggestionId ?? location.draftId);
|
|
3134
3373
|
const [reviewing, setReviewing] = (0, react.useState)(false);
|
|
3374
|
+
const [deleting, setDeleting] = (0, react.useState)(void 0);
|
|
3375
|
+
const choice = useModelChoice(context, "evolution.modelAuto");
|
|
3135
3376
|
(0, react.useEffect)(() => {
|
|
3136
3377
|
let active = true;
|
|
3137
3378
|
context.client.suggestions().then((list) => {
|
|
@@ -3242,8 +3483,62 @@ window.__ModuleLoader__.load({
|
|
|
3242
3483
|
location,
|
|
3243
3484
|
bar
|
|
3244
3485
|
});
|
|
3245
|
-
|
|
3246
|
-
|
|
3486
|
+
const currentId = current?.kind === "suggestion" ? current.id : void 0;
|
|
3487
|
+
const canOverride = currentId !== void 0 && current?.kind === "suggestion" && PENDING.includes(current.suggestion.status);
|
|
3488
|
+
const currentOverride = currentId === void 0 ? null : Object.hasOwn(choice.preferences.suggestionModels, currentId) ? choice.preferences.suggestionModels[currentId] : null;
|
|
3489
|
+
const currentModel = currentOverride ?? choice.preferences.model ?? null;
|
|
3490
|
+
const saveDraftModel = (value) => choice.saveDraftModel(modelOptionPick(value));
|
|
3491
|
+
const saveSuggestionModel = (value) => {
|
|
3492
|
+
if (canOverride && currentId !== void 0) choice.saveSuggestionModel(currentId, modelOptionPick(value));
|
|
3493
|
+
};
|
|
3494
|
+
const removeItem = async (item) => {
|
|
3495
|
+
try {
|
|
3496
|
+
if (item.kind === "draft") await context.client.deleteDraft(item.id);
|
|
3497
|
+
else await context.client.deleteSuggestion(item.id);
|
|
3498
|
+
setDeleting(void 0);
|
|
3499
|
+
if (selected === item.id) setSelected(void 0);
|
|
3500
|
+
context.notice(t("evolution.deleted"));
|
|
3501
|
+
context.refresh();
|
|
3502
|
+
} catch (error) {
|
|
3503
|
+
context.fail(error);
|
|
3504
|
+
}
|
|
3505
|
+
};
|
|
3506
|
+
const modelBar = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3507
|
+
className: css.skListBar,
|
|
3508
|
+
style: {
|
|
3509
|
+
borderBottom: "none",
|
|
3510
|
+
padding: "0 0 10px"
|
|
3511
|
+
},
|
|
3512
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3513
|
+
className: css.skSplit,
|
|
3514
|
+
style: {
|
|
3515
|
+
minHeight: 0,
|
|
3516
|
+
alignItems: "center",
|
|
3517
|
+
width: "100%"
|
|
3518
|
+
},
|
|
3519
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.SelectField, {
|
|
3520
|
+
label: t("evolution.model"),
|
|
3521
|
+
triggerDetail: true,
|
|
3522
|
+
inline: true,
|
|
3523
|
+
size: "sm",
|
|
3524
|
+
value: modelOptionValue(choice.preferences.model),
|
|
3525
|
+
disabled: !context.writable || choice.models === null,
|
|
3526
|
+
onChange: saveDraftModel,
|
|
3527
|
+
options: choice.options
|
|
3528
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.SelectField, {
|
|
3529
|
+
label: t("evolution.modelCard"),
|
|
3530
|
+
triggerDetail: true,
|
|
3531
|
+
inline: true,
|
|
3532
|
+
size: "sm",
|
|
3533
|
+
value: modelOptionValue(currentOverride),
|
|
3534
|
+
disabled: !context.writable || !canOverride || choice.models === null,
|
|
3535
|
+
onChange: saveSuggestionModel,
|
|
3536
|
+
options: choice.cardOptions
|
|
3537
|
+
})]
|
|
3538
|
+
})
|
|
3539
|
+
});
|
|
3540
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [modelBar, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3541
|
+
className: (0, dsh_mnemon_client.appearanceClass)(css.skSplit, css.skEvolutionSplit),
|
|
3247
3542
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
3248
3543
|
className: css.skList,
|
|
3249
3544
|
children: [bar, items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ListItem, {
|
|
@@ -3275,22 +3570,44 @@ window.__ModuleLoader__.load({
|
|
|
3275
3570
|
children: t(`evolution.emptyBody.${filter}`)
|
|
3276
3571
|
}) : current.kind === "suggestion" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SuggestionDetail, {
|
|
3277
3572
|
context,
|
|
3278
|
-
id: current.id
|
|
3573
|
+
id: current.id,
|
|
3574
|
+
model: currentModel
|
|
3279
3575
|
}, current.id) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
3280
3576
|
className: css.skDetail,
|
|
3281
|
-
children: [
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3577
|
+
children: [
|
|
3578
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
3579
|
+
className: css.skDetailHead,
|
|
3580
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3581
|
+
className: css.skKicker,
|
|
3582
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionTag, { action: "update" })
|
|
3583
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: current.draft.skillName })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3584
|
+
className: css.skDetailActions,
|
|
3585
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3586
|
+
variant: "ghost",
|
|
3587
|
+
size: "sm",
|
|
3588
|
+
disabled: !context.writable,
|
|
3589
|
+
onClick: () => setDeleting(current.id),
|
|
3590
|
+
children: t("common.delete")
|
|
3591
|
+
})
|
|
3592
|
+
})]
|
|
3593
|
+
}),
|
|
3594
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DraftReview, {
|
|
3595
|
+
context,
|
|
3596
|
+
draftId: current.id,
|
|
3597
|
+
model: currentModel
|
|
3598
|
+
}, current.id),
|
|
3599
|
+
deleting === current.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Confirm, {
|
|
3600
|
+
danger: true,
|
|
3601
|
+
title: t("evolution.deleteTitle"),
|
|
3602
|
+
body: t("evolution.deleteBody"),
|
|
3603
|
+
confirmLabel: t("common.delete"),
|
|
3604
|
+
onClose: () => setDeleting(void 0),
|
|
3605
|
+
onConfirm: () => void removeItem(current)
|
|
3606
|
+
})
|
|
3607
|
+
]
|
|
3291
3608
|
})
|
|
3292
|
-
})]
|
|
3293
|
-
});
|
|
3609
|
+
}, current?.id ?? filter)]
|
|
3610
|
+
})] });
|
|
3294
3611
|
}
|
|
3295
3612
|
function ListItem(props) {
|
|
3296
3613
|
const t = useT();
|
|
@@ -3336,9 +3653,14 @@ window.__ModuleLoader__.load({
|
|
|
3336
3653
|
function SuggestionDetail(props) {
|
|
3337
3654
|
const t = useT();
|
|
3338
3655
|
const { context } = props;
|
|
3656
|
+
const route = props.model === null || props.model === void 0 ? {} : {
|
|
3657
|
+
provider: props.model.provider,
|
|
3658
|
+
model: props.model.model
|
|
3659
|
+
};
|
|
3339
3660
|
const [view, setView] = (0, react.useState)(null);
|
|
3340
3661
|
const [trajectories, setTrajectories] = (0, react.useState)(/* @__PURE__ */ new Map());
|
|
3341
3662
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
3663
|
+
const [deleting, setDeleting] = (0, react.useState)(false);
|
|
3342
3664
|
(0, react.useEffect)(() => {
|
|
3343
3665
|
let active = true;
|
|
3344
3666
|
context.client.suggestion(props.id).then(async (value) => {
|
|
@@ -3406,25 +3728,50 @@ window.__ModuleLoader__.load({
|
|
|
3406
3728
|
})
|
|
3407
3729
|
] }), suggestion.status === "pending" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3408
3730
|
className: css.skDetailActions,
|
|
3409
|
-
children: [
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
onClick: () => void act(async () => {
|
|
3421
|
-
await context.client.dismissSuggestion(suggestion.id);
|
|
3422
|
-
context.notice(t("evolution.dismissed"));
|
|
3731
|
+
children: [
|
|
3732
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3733
|
+
variant: "primary",
|
|
3734
|
+
size: "sm",
|
|
3735
|
+
disabled: !context.writable || busy || !canDraft,
|
|
3736
|
+
title: canDraft ? void 0 : t("evolution.noAgent"),
|
|
3737
|
+
onClick: () => void act(() => context.client.generateDraft({
|
|
3738
|
+
suggestionId: suggestion.id,
|
|
3739
|
+
...route
|
|
3740
|
+
})),
|
|
3741
|
+
children: t("evolution.draft")
|
|
3423
3742
|
}),
|
|
3424
|
-
|
|
3425
|
-
|
|
3743
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3744
|
+
variant: "ghost",
|
|
3745
|
+
size: "sm",
|
|
3746
|
+
disabled: !context.writable || busy,
|
|
3747
|
+
onClick: () => void act(async () => {
|
|
3748
|
+
await context.client.dismissSuggestion(suggestion.id);
|
|
3749
|
+
context.notice(t("evolution.dismissed"));
|
|
3750
|
+
}),
|
|
3751
|
+
children: t("evolution.dismiss")
|
|
3752
|
+
}),
|
|
3753
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3754
|
+
variant: "ghost",
|
|
3755
|
+
size: "sm",
|
|
3756
|
+
disabled: !context.writable || busy,
|
|
3757
|
+
onClick: () => setDeleting(true),
|
|
3758
|
+
children: t("common.delete")
|
|
3759
|
+
})
|
|
3760
|
+
]
|
|
3426
3761
|
})]
|
|
3427
3762
|
}),
|
|
3763
|
+
deleting && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Confirm, {
|
|
3764
|
+
danger: true,
|
|
3765
|
+
title: t("evolution.deleteTitle"),
|
|
3766
|
+
body: t("evolution.deleteBody"),
|
|
3767
|
+
confirmLabel: t("common.delete"),
|
|
3768
|
+
onClose: () => setDeleting(false),
|
|
3769
|
+
onConfirm: () => void act(async () => {
|
|
3770
|
+
await context.client.deleteSuggestion(suggestion.id);
|
|
3771
|
+
setDeleting(false);
|
|
3772
|
+
context.notice(t("evolution.deleted"));
|
|
3773
|
+
})
|
|
3774
|
+
}),
|
|
3428
3775
|
suggestion.rationale !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Clamp, { text: suggestion.rationale }),
|
|
3429
3776
|
suggestion.action === "update" && view.skill === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3430
3777
|
className: css.skWarn,
|
|
@@ -3441,7 +3788,8 @@ window.__ModuleLoader__.load({
|
|
|
3441
3788
|
}),
|
|
3442
3789
|
suggestion.status === "review" && suggestion.draftId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DraftReview, {
|
|
3443
3790
|
context,
|
|
3444
|
-
draftId: suggestion.draftId
|
|
3791
|
+
draftId: suggestion.draftId,
|
|
3792
|
+
model: props.model ?? null
|
|
3445
3793
|
}),
|
|
3446
3794
|
suggestion.status === "adopted" && view.skill !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
3447
3795
|
className: css.skSuccess,
|
|
@@ -3534,6 +3882,10 @@ window.__ModuleLoader__.load({
|
|
|
3534
3882
|
function DraftReview(props) {
|
|
3535
3883
|
const t = useT();
|
|
3536
3884
|
const { context } = props;
|
|
3885
|
+
const route = props.model === null || props.model === void 0 ? {} : {
|
|
3886
|
+
provider: props.model.provider,
|
|
3887
|
+
model: props.model.model
|
|
3888
|
+
};
|
|
3537
3889
|
const [view, setView] = (0, react.useState)(null);
|
|
3538
3890
|
const [cases, setCases] = (0, react.useState)(void 0);
|
|
3539
3891
|
const [editing, setEditing] = (0, react.useState)(null);
|
|
@@ -3604,7 +3956,8 @@ window.__ModuleLoader__.load({
|
|
|
3604
3956
|
});
|
|
3605
3957
|
const redraft = (note) => act(() => context.client.generateDraft({
|
|
3606
3958
|
...draft.suggestionId === void 0 ? { skill: draft.skillName } : { suggestionId: draft.suggestionId },
|
|
3607
|
-
guidance: note
|
|
3959
|
+
guidance: note,
|
|
3960
|
+
...route
|
|
3608
3961
|
}), () => setRedrafting(null));
|
|
3609
3962
|
const ready = draft.status === "ready";
|
|
3610
3963
|
const progress = (run) => run === void 0 ? 0 : run.progress.done;
|
package/lib/contracts.d.ts
CHANGED
|
@@ -239,6 +239,30 @@ interface RunTarget {
|
|
|
239
239
|
draftId?: string;
|
|
240
240
|
versionId?: string;
|
|
241
241
|
}
|
|
242
|
+
/** One Provider and model, as a user picked it; never carries a reasoning effort. */
|
|
243
|
+
interface ModelRoute {
|
|
244
|
+
provider: string;
|
|
245
|
+
model: string;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The models the user picked for skill work, kept beside the ledger. Every
|
|
249
|
+
* entry is optional: absent means "follow the task Agent's own route".
|
|
250
|
+
* `suggestionModels` is keyed by suggestion id, `skillRunModels` by skill name.
|
|
251
|
+
*/
|
|
252
|
+
interface DraftPreferences {
|
|
253
|
+
version: 1;
|
|
254
|
+
draftModel?: ModelRoute;
|
|
255
|
+
runModel?: ModelRoute;
|
|
256
|
+
suggestionModels: Record<string, ModelRoute>;
|
|
257
|
+
skillRunModels: Record<string, ModelRoute>;
|
|
258
|
+
}
|
|
259
|
+
/** What the pickers read: the stored picks, named the way the pages use them. */
|
|
260
|
+
interface DraftPreferencesView {
|
|
261
|
+
model?: ModelRoute;
|
|
262
|
+
runModel?: ModelRoute;
|
|
263
|
+
suggestionModels: Record<string, ModelRoute>;
|
|
264
|
+
skillRunModels: Record<string, ModelRoute>;
|
|
265
|
+
}
|
|
242
266
|
interface CaseResult {
|
|
243
267
|
caseId: string;
|
|
244
268
|
title: string;
|
|
@@ -596,4 +620,4 @@ interface MarketInstall {
|
|
|
596
620
|
installedAt: string;
|
|
597
621
|
}
|
|
598
622
|
//#endregion
|
|
599
|
-
export { BacktestRun, CaseResult, CatalogView, DEFAULT_SKILLS_POLICY, type DetectedSource, DraftStatus, DraftView, EVOLUTION_SIGNALS, EvalCase, EvalCheck, EvidencePack, EvidenceReference, EvolutionSignal, LocalizedText, MarketAudit, MarketEntry, MarketInstall, MarketInstallState, MarketItem, MarketPreview, MarketRegistry, MarketRegistryFile, MarketSearchResult, MarketSource, type MarketSourceKind, MarketView, ReviewLogEntry, ReviewRecordInput, ReviewRecordResult, ReviewScore, RunStatus, RunTarget, RunTargetKind, SKILL_ROOT_KINDS, SKILL_ROOT_RANK, SUGGESTION_STATUSES, SkillCatalog, SkillDocument, SkillDraft, SkillInvocation, SkillProblem, SkillRoot, SkillRootKind, SkillSuggestion, SkillSummary, SkillVersion, SkillVersionReason, SkillsOverview, SkillsPolicy, SuggestionStatus, SuggestionView, Trajectory, TrajectoryAnnotation, TrajectoryStats, TrajectoryStep, TrajectoryStepKind, TrajectorySummary, TrashEntry, TrashRestoreInput, TrashRestorePreview };
|
|
623
|
+
export { BacktestRun, CaseResult, CatalogView, DEFAULT_SKILLS_POLICY, type DetectedSource, DraftPreferences, DraftPreferencesView, DraftStatus, DraftView, EVOLUTION_SIGNALS, EvalCase, EvalCheck, EvidencePack, EvidenceReference, EvolutionSignal, LocalizedText, MarketAudit, MarketEntry, MarketInstall, MarketInstallState, MarketItem, MarketPreview, MarketRegistry, MarketRegistryFile, MarketSearchResult, MarketSource, type MarketSourceKind, MarketView, ModelRoute, ReviewLogEntry, ReviewRecordInput, ReviewRecordResult, ReviewScore, RunStatus, RunTarget, RunTargetKind, SKILL_ROOT_KINDS, SKILL_ROOT_RANK, SUGGESTION_STATUSES, SkillCatalog, SkillDocument, SkillDraft, SkillInvocation, SkillProblem, SkillRoot, SkillRootKind, SkillSuggestion, SkillSummary, SkillVersion, SkillVersionReason, SkillsOverview, SkillsPolicy, SuggestionStatus, SuggestionView, Trajectory, TrajectoryAnnotation, TrajectoryStats, TrajectoryStep, TrajectoryStepKind, TrajectorySummary, TrashEntry, TrashRestoreInput, TrashRestorePreview };
|
package/lib/index.js
CHANGED
|
@@ -489,6 +489,43 @@ var SkillsStore = class {
|
|
|
489
489
|
installs: array(value.installs)
|
|
490
490
|
};
|
|
491
491
|
}
|
|
492
|
+
/**
|
|
493
|
+
* What the user picked for draft and backtest runs, kept out of `fingerprint()`
|
|
494
|
+
* on purpose: changing a picker must not invalidate an open page's revision.
|
|
495
|
+
*/
|
|
496
|
+
preferences() {
|
|
497
|
+
const stored = object$1(this.readJson("preferences.json")) ?? {};
|
|
498
|
+
const route = (value) => {
|
|
499
|
+
const picked = object$1(value);
|
|
500
|
+
const provider = typeof picked?.provider === "string" ? picked.provider : void 0;
|
|
501
|
+
const model = typeof picked?.model === "string" ? picked.model : void 0;
|
|
502
|
+
return provider !== void 0 && model !== void 0 ? {
|
|
503
|
+
provider,
|
|
504
|
+
model
|
|
505
|
+
} : void 0;
|
|
506
|
+
};
|
|
507
|
+
const routes = (value) => {
|
|
508
|
+
const result = {};
|
|
509
|
+
const map = object$1(value);
|
|
510
|
+
if (map !== void 0) for (const [key, item] of Object.entries(map)) {
|
|
511
|
+
const picked = route(item);
|
|
512
|
+
if (picked !== void 0) result[key] = picked;
|
|
513
|
+
}
|
|
514
|
+
return result;
|
|
515
|
+
};
|
|
516
|
+
const draft = route(stored.draftModel);
|
|
517
|
+
const run = route(stored.runModel);
|
|
518
|
+
return {
|
|
519
|
+
version: 1,
|
|
520
|
+
...draft === void 0 ? {} : { draftModel: draft },
|
|
521
|
+
...run === void 0 ? {} : { runModel: run },
|
|
522
|
+
suggestionModels: routes(stored.suggestionModels),
|
|
523
|
+
skillRunModels: routes(stored.skillRunModels)
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
savePreferences(preferences) {
|
|
527
|
+
this.writeJson("preferences.json", preferences);
|
|
528
|
+
}
|
|
492
529
|
saveLedger(ledger) {
|
|
493
530
|
ledger.generation += 1;
|
|
494
531
|
ledger.reviews = ledger.reviews.slice(0, 200);
|
|
@@ -732,13 +769,33 @@ function clip$1(value, maximum) {
|
|
|
732
769
|
const text = value.trim();
|
|
733
770
|
return text.length <= maximum ? text : text.slice(0, maximum - 1) + "…";
|
|
734
771
|
}
|
|
735
|
-
/**
|
|
772
|
+
/**
|
|
773
|
+
* `drafting` was set before this process started, so no live writer owns it any
|
|
774
|
+
* more. A draft write is cancelled only by the Host going away, and the catch
|
|
775
|
+
* that would put the suggestion back never runs then, so the row would sit in
|
|
776
|
+
* "drafting" forever and refuse both a retry and a delete.
|
|
777
|
+
*/
|
|
778
|
+
const PROCESS_STARTED_AT = Date.now() - Math.round(process.uptime() * 1e3);
|
|
779
|
+
const ORPHAN_DRAFT_ERROR = "the host restarted while this draft was being written";
|
|
780
|
+
function orphanedDraft(suggestion) {
|
|
781
|
+
const at = Date.parse(suggestion.updatedAt);
|
|
782
|
+
return !Number.isFinite(at) || at < PROCESS_STARTED_AT;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Move pending suggestions past their expiry to `expired`, and suggestions whose
|
|
786
|
+
* draft was abandoned by a dead process back to `pending`; true when anything changed.
|
|
787
|
+
*/
|
|
736
788
|
function expireSuggestions(ledger, now) {
|
|
737
789
|
let changed = false;
|
|
738
790
|
for (const suggestion of ledger.suggestions) if (suggestion.status === "pending" && Date.parse(suggestion.expiresAt) < now.getTime()) {
|
|
739
791
|
suggestion.status = "expired";
|
|
740
792
|
suggestion.updatedAt = now.toISOString();
|
|
741
793
|
changed = true;
|
|
794
|
+
} else if (suggestion.status === "drafting" && orphanedDraft(suggestion)) {
|
|
795
|
+
suggestion.status = "pending";
|
|
796
|
+
suggestion.updatedAt = now.toISOString();
|
|
797
|
+
suggestion.lastError = ORPHAN_DRAFT_ERROR;
|
|
798
|
+
changed = true;
|
|
742
799
|
}
|
|
743
800
|
return changed;
|
|
744
801
|
}
|
|
@@ -3410,6 +3467,39 @@ var SkillsService = class {
|
|
|
3410
3467
|
return { purged: entries.length };
|
|
3411
3468
|
});
|
|
3412
3469
|
}
|
|
3470
|
+
/** The model the user picked for drafts and backtests, if any. */
|
|
3471
|
+
draftPreferences() {
|
|
3472
|
+
const stored = this.store.preferences();
|
|
3473
|
+
return {
|
|
3474
|
+
...stored.draftModel === void 0 ? {} : { model: stored.draftModel },
|
|
3475
|
+
...stored.runModel === void 0 ? {} : { runModel: stored.runModel },
|
|
3476
|
+
suggestionModels: stored.suggestionModels,
|
|
3477
|
+
skillRunModels: stored.skillRunModels
|
|
3478
|
+
};
|
|
3479
|
+
}
|
|
3480
|
+
/**
|
|
3481
|
+
* Record one picker change. `suggestionId` targets a single suggestion,
|
|
3482
|
+
* `skillName` with `slot: 'run'` a single skill, and a null model clears the
|
|
3483
|
+
* entry so the page falls back to following the task Agent again.
|
|
3484
|
+
*/
|
|
3485
|
+
setDraftPreference(input) {
|
|
3486
|
+
return this.write(() => {
|
|
3487
|
+
const preferences = this.store.preferences();
|
|
3488
|
+
if (input.slot === "run") {
|
|
3489
|
+
if (input.skillName !== void 0) {
|
|
3490
|
+
if (input.model === null) delete preferences.skillRunModels[input.skillName];
|
|
3491
|
+
else preferences.skillRunModels[input.skillName] = input.model;
|
|
3492
|
+
} else if (input.model === null) delete preferences.runModel;
|
|
3493
|
+
else preferences.runModel = input.model;
|
|
3494
|
+
} else if (input.suggestionId !== void 0) {
|
|
3495
|
+
if (input.model === null) delete preferences.suggestionModels[input.suggestionId];
|
|
3496
|
+
else preferences.suggestionModels[input.suggestionId] = input.model;
|
|
3497
|
+
} else if (input.model === null) delete preferences.draftModel;
|
|
3498
|
+
else preferences.draftModel = input.model;
|
|
3499
|
+
this.store.savePreferences(preferences);
|
|
3500
|
+
return this.draftPreferences();
|
|
3501
|
+
});
|
|
3502
|
+
}
|
|
3413
3503
|
restoreVersion(workspace, input) {
|
|
3414
3504
|
return this.write(() => {
|
|
3415
3505
|
const skill = findSkill(this.catalog(workspace), input.key);
|
|
@@ -3449,6 +3539,25 @@ var SkillsService = class {
|
|
|
3449
3539
|
return suggestion;
|
|
3450
3540
|
});
|
|
3451
3541
|
}
|
|
3542
|
+
/** Remove a suggestion for good, together with any draft it produced and its model pick. */
|
|
3543
|
+
deleteSuggestion(id) {
|
|
3544
|
+
return this.write(() => {
|
|
3545
|
+
const ledger = this.store.ledger();
|
|
3546
|
+
expireSuggestions(ledger, this.clock());
|
|
3547
|
+
const index = ledger.suggestions.findIndex((candidate) => candidate.id === id);
|
|
3548
|
+
if (index < 0) throw new Error("suggestion not found: " + id);
|
|
3549
|
+
if (ledger.suggestions[index].status === "drafting") throw new Error("a draft is being written for this suggestion; wait for it to finish");
|
|
3550
|
+
ledger.suggestions.splice(index, 1);
|
|
3551
|
+
ledger.drafts = ledger.drafts.filter((draft) => draft.suggestionId !== id);
|
|
3552
|
+
const preferences = this.store.preferences();
|
|
3553
|
+
if (preferences.suggestionModels[id] !== void 0) {
|
|
3554
|
+
delete preferences.suggestionModels[id];
|
|
3555
|
+
this.store.savePreferences(preferences);
|
|
3556
|
+
}
|
|
3557
|
+
this.store.saveLedger(ledger);
|
|
3558
|
+
return { deleted: id };
|
|
3559
|
+
});
|
|
3560
|
+
}
|
|
3452
3561
|
/** The Host marks a suggestion `drafting` before a task Agent writes, and back to `pending` if it fails. */
|
|
3453
3562
|
suggestionStatus(input) {
|
|
3454
3563
|
return this.withSuggestion(input.id, (suggestion) => {
|
|
@@ -3698,6 +3807,40 @@ var SkillsService = class {
|
|
|
3698
3807
|
return draft;
|
|
3699
3808
|
});
|
|
3700
3809
|
}
|
|
3810
|
+
/** Remove a draft for good; its suggestion goes back to `pending` so it can be drafted again. */
|
|
3811
|
+
deleteDraft(id) {
|
|
3812
|
+
return this.write(() => {
|
|
3813
|
+
const ledger = this.store.ledger();
|
|
3814
|
+
const index = ledger.drafts.findIndex((candidate) => candidate.id === id);
|
|
3815
|
+
if (index < 0) throw new Error("draft not found: " + id);
|
|
3816
|
+
const draft = ledger.drafts[index];
|
|
3817
|
+
ledger.drafts.splice(index, 1);
|
|
3818
|
+
if (draft.suggestionId !== void 0) {
|
|
3819
|
+
const suggestion = ledger.suggestions.find((candidate) => candidate.id === draft.suggestionId);
|
|
3820
|
+
if (suggestion?.draftId === draft.id) {
|
|
3821
|
+
delete suggestion.draftId;
|
|
3822
|
+
if (suggestion.status === "review") suggestion.status = "pending";
|
|
3823
|
+
suggestion.updatedAt = this.clock().toISOString();
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
this.store.saveLedger(ledger);
|
|
3827
|
+
return { deleted: id };
|
|
3828
|
+
});
|
|
3829
|
+
}
|
|
3830
|
+
/**
|
|
3831
|
+
* Put suggestions whose draft write died with the previous Host back to
|
|
3832
|
+
* `pending`, so the page stops showing them as "drafting" forever.
|
|
3833
|
+
*/
|
|
3834
|
+
reclaimOrphanDrafts() {
|
|
3835
|
+
return this.write(() => {
|
|
3836
|
+
const ledger = this.store.ledger();
|
|
3837
|
+
const before = ledger.suggestions.filter((suggestion) => suggestion.status === "drafting").length;
|
|
3838
|
+
if (!expireSuggestions(ledger, this.clock())) return { reclaimed: 0 };
|
|
3839
|
+
this.store.saveLedger(ledger);
|
|
3840
|
+
const after = ledger.suggestions.filter((suggestion) => suggestion.status === "drafting").length;
|
|
3841
|
+
return { reclaimed: Math.max(0, before - after) };
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3701
3844
|
/** The content a run tests, resolved from its target. */
|
|
3702
3845
|
targetContent(workspace, skillName, target) {
|
|
3703
3846
|
if (target.kind === "none") return { target: { kind: "none" } };
|
|
@@ -4291,6 +4434,16 @@ function rootKind(value) {
|
|
|
4291
4434
|
if (typeof value !== "string" || !SKILL_ROOT_KINDS.includes(value)) throw new Error("root must be one of " + SKILL_ROOT_KINDS.join(", "));
|
|
4292
4435
|
return value;
|
|
4293
4436
|
}
|
|
4437
|
+
/** A picked model, or null to clear the pick and follow the task Agent again. */
|
|
4438
|
+
function draftModelInput(value) {
|
|
4439
|
+
if (value === void 0 || value === null) return null;
|
|
4440
|
+
if (typeof value !== "object" || Array.isArray(value)) throw new Error("model must be an object or null");
|
|
4441
|
+
const picked = value;
|
|
4442
|
+
return {
|
|
4443
|
+
provider: memoryInputText(picked.provider, "model.provider", 100),
|
|
4444
|
+
model: memoryInputText(picked.model, "model.model", 200)
|
|
4445
|
+
};
|
|
4446
|
+
}
|
|
4294
4447
|
function caseInput(value, skillName) {
|
|
4295
4448
|
const input = memoryInputRecord(value, "case");
|
|
4296
4449
|
const checks = input.checks;
|
|
@@ -4515,6 +4668,7 @@ function createSkillsMemorySource(config = {}) {
|
|
|
4515
4668
|
...effective.dshHome === void 0 ? {} : { dshHome: effective.dshHome },
|
|
4516
4669
|
...effective.agentsHome === void 0 ? {} : { agentsHome: effective.agentsHome }
|
|
4517
4670
|
});
|
|
4671
|
+
service.reclaimOrphanDrafts().catch(() => void 0);
|
|
4518
4672
|
const facts = (scope, management) => management ? {
|
|
4519
4673
|
sourceInstanceKey: context.sourceInstanceKey,
|
|
4520
4674
|
sourceTypeId: SKILLS_SOURCE_TYPE_ID,
|
|
@@ -4572,6 +4726,7 @@ function createSkillsMemorySource(config = {}) {
|
|
|
4572
4726
|
...optionalText(fields.skill, "skill", 64) === void 0 ? {} : { skill: optionalText(fields.skill, "skill", 64) }
|
|
4573
4727
|
});
|
|
4574
4728
|
case "draft": return service.draft(root, memoryInputText(fields.id, "id", 100));
|
|
4729
|
+
case "draft-preferences": return service.draftPreferences();
|
|
4575
4730
|
case "reviews": return service.reviews({
|
|
4576
4731
|
...typeof fields.sessionId === "string" ? { sessionId: fields.sessionId } : {},
|
|
4577
4732
|
...typeof fields.limit === "number" ? { limit: fields.limit } : {}
|
|
@@ -4659,6 +4814,9 @@ function createSkillsMemorySource(config = {}) {
|
|
|
4659
4814
|
case "suggestion-dismiss":
|
|
4660
4815
|
value = await service.dismissSuggestion(memoryInputText(fields.id, "id", 100));
|
|
4661
4816
|
break;
|
|
4817
|
+
case "suggestion-delete":
|
|
4818
|
+
value = await service.deleteSuggestion(memoryInputText(fields.id, "id", 100));
|
|
4819
|
+
break;
|
|
4662
4820
|
case "suggestion-status": {
|
|
4663
4821
|
const status = fields.status;
|
|
4664
4822
|
if (status !== "drafting" && status !== "pending") throw new Error("status must be drafting or pending");
|
|
@@ -4715,6 +4873,22 @@ function createSkillsMemorySource(config = {}) {
|
|
|
4715
4873
|
case "draft-discard":
|
|
4716
4874
|
value = await service.discardDraft(memoryInputText(fields.id, "id", 100));
|
|
4717
4875
|
break;
|
|
4876
|
+
case "draft-delete":
|
|
4877
|
+
value = await service.deleteDraft(memoryInputText(fields.id, "id", 100));
|
|
4878
|
+
break;
|
|
4879
|
+
case "draft-preference": {
|
|
4880
|
+
const slot = optionalText(fields.slot, "slot", 10);
|
|
4881
|
+
if (slot !== void 0 && slot !== "draft" && slot !== "run") throw new Error("slot must be draft or run");
|
|
4882
|
+
const suggestionId = optionalText(fields.suggestionId, "suggestionId", 100);
|
|
4883
|
+
if (suggestionId !== void 0 && slot === "run") throw new Error("a suggestion pick cannot be a backtest pick");
|
|
4884
|
+
value = await service.setDraftPreference({
|
|
4885
|
+
...slot === void 0 ? {} : { slot },
|
|
4886
|
+
...suggestionId === void 0 ? {} : { suggestionId },
|
|
4887
|
+
...optionalText(fields.skillName, "skillName", 64) === void 0 ? {} : { skillName: optionalText(fields.skillName, "skillName", 64) },
|
|
4888
|
+
model: draftModelInput(fields.model)
|
|
4889
|
+
});
|
|
4890
|
+
break;
|
|
4891
|
+
}
|
|
4718
4892
|
case "run-start":
|
|
4719
4893
|
value = await service.startRun({
|
|
4720
4894
|
skillName: memoryInputText(fields.skillName, "skillName", 64),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { MnemonSourceManagementClient } from 'dsh-mnemon/client';
|
|
2
|
-
import type { BacktestRun, CatalogView, DraftView, EvalCase, MarketPreview, MarketRegistry, MarketSearchResult, MarketView, EvidencePack, ReviewLogEntry, ReviewRecordResult, RunTarget, SkillDocument, SkillDraft, SkillRootKind, SkillSuggestion, SkillSummary, SkillVersion, SkillsOverview, SuggestionStatus, SuggestionView, Trajectory, TrajectorySummary, TrashEntry, TrashRestoreInput, TrashRestorePreview } from '../contracts.ts';
|
|
1
|
+
import type { MnemonSourceManagementClient, TaskAgentModelCatalog } from 'dsh-mnemon/client';
|
|
2
|
+
import type { BacktestRun, CatalogView, DraftPreferencesView, DraftView, EvalCase, MarketPreview, MarketRegistry, MarketSearchResult, MarketView, EvidencePack, ModelRoute, ReviewLogEntry, ReviewRecordResult, RunTarget, SkillDocument, SkillDraft, SkillRootKind, SkillSuggestion, SkillSummary, SkillVersion, SkillsOverview, SuggestionStatus, SuggestionView, Trajectory, TrajectorySummary, TrashEntry, TrashRestoreInput, TrashRestorePreview } from '../contracts.ts';
|
|
3
3
|
export interface CaseDraft {
|
|
4
4
|
id?: string;
|
|
5
5
|
skillName: string;
|
|
@@ -75,6 +75,14 @@ export interface SkillsPageClient {
|
|
|
75
75
|
}>;
|
|
76
76
|
restoreVersion(key: string, versionId: string, expectedHash: string): Promise<SkillSummary>;
|
|
77
77
|
dismissSuggestion(id: string): Promise<SkillSuggestion>;
|
|
78
|
+
/** Delete a waiting suggestion and any draft written for it. */
|
|
79
|
+
deleteSuggestion(id: string): Promise<{
|
|
80
|
+
deleted: string;
|
|
81
|
+
}>;
|
|
82
|
+
/** Delete a draft; its suggestion goes back to waiting. */
|
|
83
|
+
deleteDraft(id: string): Promise<{
|
|
84
|
+
deleted: string;
|
|
85
|
+
}>;
|
|
78
86
|
pinTrajectory(id: string, pinned: boolean): Promise<TrajectorySummary>;
|
|
79
87
|
deleteTrajectory(id: string): Promise<{
|
|
80
88
|
deleted: string;
|
|
@@ -92,6 +100,18 @@ export interface SkillsPageClient {
|
|
|
92
100
|
discardDraft(id: string): Promise<SkillDraft>;
|
|
93
101
|
/** Attach a baseline run to the draft it is compared with. */
|
|
94
102
|
linkRun(draftId: string, runId: string): Promise<void>;
|
|
103
|
+
/** The model each piece of model work follows: the two global picks and their per-item overrides. */
|
|
104
|
+
draftPreferences(): Promise<DraftPreferencesView>;
|
|
105
|
+
/** Pick the model for drafts, for backtests, or for one suggestion or skill; `null` follows the task Agent again. */
|
|
106
|
+
saveDraftModel(model: ModelRoute | null): Promise<DraftPreferencesView>;
|
|
107
|
+
saveSuggestionModel(id: string, model: ModelRoute | null): Promise<DraftPreferencesView>;
|
|
108
|
+
saveRunModel(model: ModelRoute | null): Promise<DraftPreferencesView>;
|
|
109
|
+
saveSkillRunModel(skillName: string, model: ModelRoute | null): Promise<DraftPreferencesView>;
|
|
110
|
+
/**
|
|
111
|
+
* The routes and model directory a page may offer. Rejects when the Host
|
|
112
|
+
* offers none, which is also when the page hides its pickers.
|
|
113
|
+
*/
|
|
114
|
+
models(): Promise<TaskAgentModelCatalog>;
|
|
95
115
|
market(): Promise<MarketView>;
|
|
96
116
|
marketPreview(registryId: string, name: string): Promise<MarketPreview>;
|
|
97
117
|
/** Search the search sources; the page filters the listed ones itself. */
|
|
@@ -118,6 +138,8 @@ export interface SkillsPageClient {
|
|
|
118
138
|
skill?: string;
|
|
119
139
|
guidance?: string;
|
|
120
140
|
targetRoot?: SkillRootKind;
|
|
141
|
+
provider?: string;
|
|
142
|
+
model?: string;
|
|
121
143
|
}): Promise<{
|
|
122
144
|
started: true;
|
|
123
145
|
}>;
|
|
@@ -125,6 +147,8 @@ export interface SkillsPageClient {
|
|
|
125
147
|
skillName: string;
|
|
126
148
|
target: RunTarget;
|
|
127
149
|
caseIds?: string[];
|
|
150
|
+
provider?: string;
|
|
151
|
+
model?: string;
|
|
128
152
|
}): Promise<{
|
|
129
153
|
runId: string;
|
|
130
154
|
}>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { FieldOption, TaskAgentModelCatalog } from 'dsh-mnemon/client';
|
|
2
|
+
import type { DraftPreferencesView, ModelRoute } from '../contracts.ts';
|
|
3
|
+
import { type SkillsTranslate } from './presentation.ts';
|
|
4
|
+
import type { SkillsPageContext } from './ui.tsx';
|
|
5
|
+
/**
|
|
6
|
+
* The model pickers the Evolution and Evaluation pages share: which model
|
|
7
|
+
* drafts and backtests run on, globally and per item, offered from the same
|
|
8
|
+
* directory the task Agent resolves its own route against.
|
|
9
|
+
*
|
|
10
|
+
* A pick is stored as `provider|model`, so one menu value names one route, and
|
|
11
|
+
* an absent pick is `auto`: the page follows the task Agent, as it did before
|
|
12
|
+
* the user picked anything.
|
|
13
|
+
*/
|
|
14
|
+
/** The menu value of a pick; `auto` asks for no pick at all. */
|
|
15
|
+
export declare function modelOptionValue(model: ModelRoute | null | undefined): string;
|
|
16
|
+
/** The pick a menu value names; `auto` and a malformed value both pick nothing. */
|
|
17
|
+
export declare function modelOptionPick(value: string): ModelRoute | null;
|
|
18
|
+
/**
|
|
19
|
+
* Follow-default first, then every Provider's models. The first entry exists
|
|
20
|
+
* before the directory arrives, so the toolbar holds its place instead of
|
|
21
|
+
* appearing a round trip later than the rest of the page.
|
|
22
|
+
*/
|
|
23
|
+
export declare function modelOptionsFrom(models: TaskAgentModelCatalog | null, t: SkillsTranslate, autoKey: 'tests.modelAuto' | 'evolution.modelAuto'): FieldOption<string>[];
|
|
24
|
+
/** The same list for one card: follow-default, then the directory without its own default entry. */
|
|
25
|
+
export declare function modelCardOptionsFrom(modelOptions: readonly FieldOption<string>[], t: SkillsTranslate, autoKey: 'tests.modelAuto' | 'evolution.modelAuto'): FieldOption<string>[];
|
|
26
|
+
/** What the pickers read and write, and the directory behind them. */
|
|
27
|
+
export interface ModelChoice {
|
|
28
|
+
/** `null` until the directory arrives; the pickers are disabled meanwhile. */
|
|
29
|
+
models: TaskAgentModelCatalog | null;
|
|
30
|
+
preferences: DraftPreferencesView;
|
|
31
|
+
/** Every routable model, follow-default first. */
|
|
32
|
+
options: FieldOption<string>[];
|
|
33
|
+
/** The same for one card's own pick. */
|
|
34
|
+
cardOptions: FieldOption<string>[];
|
|
35
|
+
saveDraftModel(model: ModelRoute | null): void;
|
|
36
|
+
saveSuggestionModel(id: string, model: ModelRoute | null): void;
|
|
37
|
+
saveRunModel(model: ModelRoute | null): void;
|
|
38
|
+
saveSkillRunModel(skillName: string, model: ModelRoute | null): void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Read the directory and the stored picks alongside the page's own data, and
|
|
42
|
+
* write one pick at a time. A write shows locally first so the menu answers at
|
|
43
|
+
* once, then takes the Host's answer, which is also what a second window sees.
|
|
44
|
+
*/
|
|
45
|
+
export declare function useModelChoice(context: SkillsPageContext, autoKey: 'tests.modelAuto' | 'evolution.modelAuto'): ModelChoice;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type JSX } from 'react';
|
|
2
|
-
import type { BacktestRun } from '../contracts.ts';
|
|
2
|
+
import type { BacktestRun, ModelRoute } from '../contracts.ts';
|
|
3
3
|
import type { SkillsPageContext } from './ui.tsx';
|
|
4
4
|
/**
|
|
5
5
|
* A skill's test cases and its backtests: the cases with a switch each, one
|
|
@@ -9,6 +9,7 @@ import type { SkillsPageContext } from './ui.tsx';
|
|
|
9
9
|
export declare function SkillTests(props: {
|
|
10
10
|
context: SkillsPageContext;
|
|
11
11
|
skillName: string;
|
|
12
|
+
runModel?: ModelRoute | null;
|
|
12
13
|
}): JSX.Element;
|
|
13
14
|
/** One run's cases: the verdict, each check with the judge's note, and what the simulated run did and answered. */
|
|
14
15
|
export declare function RunDetail(props: {
|
package/lib/types/contracts.d.ts
CHANGED
|
@@ -221,6 +221,30 @@ export interface RunTarget {
|
|
|
221
221
|
draftId?: string;
|
|
222
222
|
versionId?: string;
|
|
223
223
|
}
|
|
224
|
+
/** One Provider and model, as a user picked it; never carries a reasoning effort. */
|
|
225
|
+
export interface ModelRoute {
|
|
226
|
+
provider: string;
|
|
227
|
+
model: string;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* The models the user picked for skill work, kept beside the ledger. Every
|
|
231
|
+
* entry is optional: absent means "follow the task Agent's own route".
|
|
232
|
+
* `suggestionModels` is keyed by suggestion id, `skillRunModels` by skill name.
|
|
233
|
+
*/
|
|
234
|
+
export interface DraftPreferences {
|
|
235
|
+
version: 1;
|
|
236
|
+
draftModel?: ModelRoute;
|
|
237
|
+
runModel?: ModelRoute;
|
|
238
|
+
suggestionModels: Record<string, ModelRoute>;
|
|
239
|
+
skillRunModels: Record<string, ModelRoute>;
|
|
240
|
+
}
|
|
241
|
+
/** What the pickers read: the stored picks, named the way the pages use them. */
|
|
242
|
+
export interface DraftPreferencesView {
|
|
243
|
+
model?: ModelRoute;
|
|
244
|
+
runModel?: ModelRoute;
|
|
245
|
+
suggestionModels: Record<string, ModelRoute>;
|
|
246
|
+
skillRunModels: Record<string, ModelRoute>;
|
|
247
|
+
}
|
|
224
248
|
export interface CaseResult {
|
|
225
249
|
caseId: string;
|
|
226
250
|
title: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mnemon-source-skills",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Skills Source for Composable View Memory: DSH skill management, evolution suggestions, evidence trajectories and eval sets.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
56
|
-
"dsh-mnemon": "^0.5.
|
|
56
|
+
"dsh-mnemon": "^0.5.37",
|
|
57
57
|
"react": "^18.2.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@types/node": "^22.0.0",
|
|
63
63
|
"@types/react": "^18.3.0",
|
|
64
64
|
"@types/react-dom": "^18.3.0",
|
|
65
|
-
"dsh-mnemon": "^0.5.
|
|
65
|
+
"dsh-mnemon": "^0.5.37",
|
|
66
66
|
"jsdom": "^26.0.0",
|
|
67
67
|
"react": "^18.2.0",
|
|
68
68
|
"react-dom": "^18.2.0",
|
|
@@ -335,7 +335,17 @@
|
|
|
335
335
|
"trash.original": "原位置",
|
|
336
336
|
"trash.chooseHint": "可选择恢复位置或改名。同名替换需要明确确认,现有技能会保留在回收站。",
|
|
337
337
|
"trash.replace": "替换同名技能,并将现有版本保留在回收站",
|
|
338
|
-
"trash.confirmName": "输入 {name} 确认彻底删除"
|
|
338
|
+
"trash.confirmName": "输入 {name} 确认彻底删除",
|
|
339
|
+
"evolution.model": "全局模型",
|
|
340
|
+
"evolution.modelCard": "所选草案模型",
|
|
341
|
+
"evolution.modelAuto": "跟随默认",
|
|
342
|
+
"evolution.modelAutoHint": "使用当前任务 Agent 的模型",
|
|
343
|
+
"evolution.deleteTitle": "删除这条建议?",
|
|
344
|
+
"evolution.deleteBody": "它生成的草案和证据引用会一起删掉,无法恢复。",
|
|
345
|
+
"evolution.deleted": "已删除",
|
|
346
|
+
"tests.model": "全局模型",
|
|
347
|
+
"tests.modelCard": "所选回测模型",
|
|
348
|
+
"tests.modelAuto": "跟随默认"
|
|
339
349
|
},
|
|
340
350
|
"en": {
|
|
341
351
|
"page.title": "Skills",
|
|
@@ -673,6 +683,16 @@
|
|
|
673
683
|
"trash.original": "Original location",
|
|
674
684
|
"trash.chooseHint": "Choose a location or a different name. Replacing a skill requires confirmation and keeps its current version in the Trash.",
|
|
675
685
|
"trash.replace": "Replace the existing skill and keep its current version in the Trash",
|
|
676
|
-
"trash.confirmName": "Type {name} to confirm permanent deletion"
|
|
686
|
+
"trash.confirmName": "Type {name} to confirm permanent deletion",
|
|
687
|
+
"evolution.model": "Global model",
|
|
688
|
+
"evolution.modelCard": "Selected model",
|
|
689
|
+
"evolution.modelAuto": "Follow default",
|
|
690
|
+
"evolution.modelAutoHint": "Use the model of the current task Agent",
|
|
691
|
+
"evolution.deleteTitle": "Delete this suggestion?",
|
|
692
|
+
"evolution.deleteBody": "Its draft and the evidence references it cites go with it, and this cannot be undone.",
|
|
693
|
+
"evolution.deleted": "Deleted",
|
|
694
|
+
"tests.model": "Global model",
|
|
695
|
+
"tests.modelCard": "Selected model",
|
|
696
|
+
"tests.modelAuto": "Follow default"
|
|
677
697
|
}
|
|
678
698
|
}
|
|
@@ -180,6 +180,12 @@
|
|
|
180
180
|
.skList { display: flex; flex-direction: column; overflow: hidden; padding-bottom: 6px; }
|
|
181
181
|
.skPane { padding: clamp(16px, 2vw, 24px); overflow: hidden; }
|
|
182
182
|
|
|
183
|
+
/* Keep the evolution inbox beside its detail while browsing long lists. */
|
|
184
|
+
.skEvolutionSplit { height: max(320px, calc(100dvh - 320px)); min-height: 0; }
|
|
185
|
+
.skEvolutionSplit > .skList,
|
|
186
|
+
.skEvolutionSplit > .skPane { min-height: 0; overflow-y: auto; overscroll-behavior-y: contain; }
|
|
187
|
+
.skEvolutionSplit > .skList > * { flex-shrink: 0; }
|
|
188
|
+
|
|
183
189
|
.skListBar { display: flex; align-items: center; gap: 8px; padding: 10px; border-bottom: .5px solid var(--mn-line); }
|
|
184
190
|
.skListBar > :first-child { min-width: 0; flex: 1; }
|
|
185
191
|
.skListNote { margin: 0; padding: 18px 16px; color: var(--mn-faint); font-size: 12px; line-height: 18px; text-align: center; }
|
|
@@ -574,6 +580,8 @@
|
|
|
574
580
|
@media (max-width: 860px) {
|
|
575
581
|
.skSplit { grid-template-columns: minmax(0, 1fr); }
|
|
576
582
|
.skList { max-height: 360px; overflow-y: auto; }
|
|
583
|
+
.skEvolutionSplit { height: auto; }
|
|
584
|
+
.skEvolutionSplit > .skPane { overflow: visible; overscroll-behavior-y: auto; }
|
|
577
585
|
}
|
|
578
586
|
|
|
579
587
|
@media (max-width: 560px) {
|