@agent-stash/dsh-skill-scout 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -56
- package/dist/client.js +713 -330
- package/dist/client.js.map +1 -1
- package/dist/index.js +1560 -601
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -656,16 +656,23 @@ window.__ModuleLoader__.load({
|
|
|
656
656
|
"recovery",
|
|
657
657
|
"complex"
|
|
658
658
|
]);
|
|
659
|
-
/**
|
|
659
|
+
/**
|
|
660
|
+
* 建议在界面上的状态。summarizing 与 drafting 只存在于 Host 内存,表示发现模型正在写摘要、
|
|
661
|
+
* 生成模型正在写草稿;其余与存储里的状态一致。
|
|
662
|
+
*/
|
|
660
663
|
const ItemStateSchema = /* @__PURE__ */ picklist([
|
|
661
664
|
"detected",
|
|
662
|
-
"
|
|
663
|
-
"
|
|
665
|
+
"summarizing",
|
|
666
|
+
"proposed",
|
|
664
667
|
"skipped",
|
|
668
|
+
"drafting",
|
|
669
|
+
"ready",
|
|
665
670
|
"failed",
|
|
666
671
|
"dismissed",
|
|
667
672
|
"written"
|
|
668
673
|
]);
|
|
674
|
+
/** 模型调用的两个阶段:摘要与草稿。 */
|
|
675
|
+
const StageViewSchema = /* @__PURE__ */ picklist(["summary", "draft"]);
|
|
669
676
|
const DecisionSchema = /* @__PURE__ */ picklist([
|
|
670
677
|
"skip",
|
|
671
678
|
"suggest_create",
|
|
@@ -691,10 +698,24 @@ window.__ModuleLoader__.load({
|
|
|
691
698
|
id: /* @__PURE__ */ string(),
|
|
692
699
|
kind: SignalKindViewSchema,
|
|
693
700
|
state: ItemStateSchema,
|
|
694
|
-
/**
|
|
701
|
+
/** 摘要给出的标题;还没有摘要时为 null,界面用 goal 代替。 */
|
|
695
702
|
title: Nullable(/* @__PURE__ */ string()),
|
|
696
703
|
goal: /* @__PURE__ */ string(),
|
|
697
|
-
/**
|
|
704
|
+
/** 规则在这组任务里找到的共有步骤,原来的写法。 */
|
|
705
|
+
steps: /* @__PURE__ */ array(/* @__PURE__ */ string()),
|
|
706
|
+
/** 摘要:在会话里发现了什么。 */
|
|
707
|
+
found: Nullable(/* @__PURE__ */ string()),
|
|
708
|
+
/** 摘要:Skill 做什么;改进时是追加的内容补上了什么。 */
|
|
709
|
+
description: Nullable(/* @__PURE__ */ string()),
|
|
710
|
+
/** 摘要:什么时候用。 */
|
|
711
|
+
trigger: Nullable(/* @__PURE__ */ string()),
|
|
712
|
+
/** 摘要:打算写进 Skill 的步骤或追加的内容。 */
|
|
713
|
+
outline: /* @__PURE__ */ array(/* @__PURE__ */ string()),
|
|
714
|
+
/** 摘要:照着做的风险。 */
|
|
715
|
+
risks: /* @__PURE__ */ array(/* @__PURE__ */ string()),
|
|
716
|
+
/** 摘要:怎么确认照着做成功了。 */
|
|
717
|
+
verification: Nullable(/* @__PURE__ */ string()),
|
|
718
|
+
/** 摘要判为跳过的理由。 */
|
|
698
719
|
reason: Nullable(/* @__PURE__ */ string()),
|
|
699
720
|
occurrences: /* @__PURE__ */ number(),
|
|
700
721
|
sessions: /* @__PURE__ */ array(SessionRefSchema),
|
|
@@ -706,6 +727,7 @@ window.__ModuleLoader__.load({
|
|
|
706
727
|
skill: Nullable(/* @__PURE__ */ string()),
|
|
707
728
|
cautions: /* @__PURE__ */ array(/* @__PURE__ */ string()),
|
|
708
729
|
failure: Nullable(/* @__PURE__ */ object({
|
|
730
|
+
stage: StageViewSchema,
|
|
709
731
|
kind: FailureKindViewSchema,
|
|
710
732
|
message: /* @__PURE__ */ string(),
|
|
711
733
|
at: /* @__PURE__ */ number(),
|
|
@@ -726,27 +748,37 @@ window.__ModuleLoader__.load({
|
|
|
726
748
|
})),
|
|
727
749
|
dismissedSimilar: /* @__PURE__ */ boolean()
|
|
728
750
|
});
|
|
751
|
+
/** 一个阶段此刻使用的模型;没有可用模型时为 null。 */
|
|
752
|
+
const ModelViewSchema = Nullable(/* @__PURE__ */ object({
|
|
753
|
+
provider: /* @__PURE__ */ string(),
|
|
754
|
+
model: /* @__PURE__ */ string(),
|
|
755
|
+
effort: Nullable(/* @__PURE__ */ string()),
|
|
756
|
+
source: /* @__PURE__ */ picklist(["config", "default"])
|
|
757
|
+
}));
|
|
729
758
|
const InboxViewSchema = /* @__PURE__ */ object({
|
|
730
759
|
status: /* @__PURE__ */ object({
|
|
731
760
|
discovery: /* @__PURE__ */ boolean(),
|
|
732
|
-
|
|
761
|
+
/** 后台自动写摘要。 */
|
|
762
|
+
summarize: /* @__PURE__ */ boolean(),
|
|
733
763
|
notify: /* @__PURE__ */ picklist(["badge", "quiet"]),
|
|
734
764
|
scope: /* @__PURE__ */ picklist(["project", "user"]),
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
})),
|
|
741
|
-
/** 本进程持有工作锁,负责分析与复核。 */
|
|
765
|
+
models: /* @__PURE__ */ object({
|
|
766
|
+
summary: ModelViewSchema,
|
|
767
|
+
draft: ModelViewSchema
|
|
768
|
+
}),
|
|
769
|
+
/** 本进程持有工作锁,负责分析与后台摘要。 */
|
|
742
770
|
lead: /* @__PURE__ */ boolean(),
|
|
743
771
|
scanning: /* @__PURE__ */ boolean(),
|
|
744
772
|
/** 回合已结束、等静默期过去后再分析的会话数。 */
|
|
745
773
|
waiting: /* @__PURE__ */ number(),
|
|
746
|
-
|
|
774
|
+
/** 正在进行的摘要与草稿请求数。 */
|
|
775
|
+
working: /* @__PURE__ */ number(),
|
|
747
776
|
usage: /* @__PURE__ */ object({
|
|
748
|
-
|
|
777
|
+
/** 今天的后台摘要次数与上限。 */
|
|
778
|
+
summaries: /* @__PURE__ */ number(),
|
|
749
779
|
limit: /* @__PURE__ */ number(),
|
|
780
|
+
/** 今天用户发起的摘要与草稿次数。 */
|
|
781
|
+
requested: /* @__PURE__ */ number(),
|
|
750
782
|
inputTokens: /* @__PURE__ */ number(),
|
|
751
783
|
outputTokens: /* @__PURE__ */ number()
|
|
752
784
|
}),
|
|
@@ -783,7 +815,7 @@ window.__ModuleLoader__.load({
|
|
|
783
815
|
"fix",
|
|
784
816
|
"recovered"
|
|
785
817
|
])),
|
|
786
|
-
/**
|
|
818
|
+
/** 摘要或草稿引用了它。 */
|
|
787
819
|
cited: /* @__PURE__ */ boolean()
|
|
788
820
|
});
|
|
789
821
|
const EvidenceEpisodeSchema = /* @__PURE__ */ object({
|
|
@@ -797,6 +829,7 @@ window.__ModuleLoader__.load({
|
|
|
797
829
|
reads: /* @__PURE__ */ number(),
|
|
798
830
|
ops: /* @__PURE__ */ array(EvidenceOpSchema),
|
|
799
831
|
reply: Nullable(/* @__PURE__ */ string()),
|
|
832
|
+
steering: /* @__PURE__ */ array(/* @__PURE__ */ string()),
|
|
800
833
|
followup: Nullable(/* @__PURE__ */ string())
|
|
801
834
|
});
|
|
802
835
|
/** 可编辑的 Skill 字段。 */
|
|
@@ -806,17 +839,20 @@ window.__ModuleLoader__.load({
|
|
|
806
839
|
whenToUse: /* @__PURE__ */ pipe(/* @__PURE__ */ string(), /* @__PURE__ */ trim(), /* @__PURE__ */ maxLength(500)),
|
|
807
840
|
body: /* @__PURE__ */ pipe(/* @__PURE__ */ string(), /* @__PURE__ */ trim(), /* @__PURE__ */ minLength(1), /* @__PURE__ */ maxLength(2e4))
|
|
808
841
|
});
|
|
809
|
-
/**
|
|
842
|
+
/** 一次模型调用的来源与用量。 */
|
|
843
|
+
const CallViewSchema = Nullable(/* @__PURE__ */ object({
|
|
844
|
+
provider: /* @__PURE__ */ string(),
|
|
845
|
+
model: /* @__PURE__ */ string(),
|
|
846
|
+
at: /* @__PURE__ */ number(),
|
|
847
|
+
inputTokens: /* @__PURE__ */ number(),
|
|
848
|
+
outputTokens: /* @__PURE__ */ number()
|
|
849
|
+
}));
|
|
850
|
+
/** 一条建议的完整信息:证据、摘要与草稿。 */
|
|
810
851
|
const DetailViewSchema = /* @__PURE__ */ object({
|
|
811
852
|
item: ItemViewSchema,
|
|
812
853
|
episodes: /* @__PURE__ */ array(EvidenceEpisodeSchema),
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
model: /* @__PURE__ */ string(),
|
|
816
|
-
at: /* @__PURE__ */ number(),
|
|
817
|
-
inputTokens: /* @__PURE__ */ number(),
|
|
818
|
-
outputTokens: /* @__PURE__ */ number()
|
|
819
|
-
})),
|
|
854
|
+
summary: CallViewSchema,
|
|
855
|
+
draftCall: CallViewSchema,
|
|
820
856
|
/** suggest_create 的草稿字段。 */
|
|
821
857
|
draft: Nullable(SkillFieldsSchema),
|
|
822
858
|
/** suggest_improve 的追加内容。 */
|
|
@@ -1003,7 +1039,7 @@ window.__ModuleLoader__.load({
|
|
|
1003
1039
|
}
|
|
1004
1040
|
//#endregion
|
|
1005
1041
|
//#region \0dsh-css:src/client/detail.module.css.mjs
|
|
1006
|
-
const css$2 = ".FSsC8q_tabs{z-index:1;background:var(--dsw-alias-bg-layer-2);padding:0 0 12px;position:sticky;top:0}.FSsC8q_panel{min-width:0}.FSsC8q_stack{flex-direction:column;gap:14px;min-width:0;display:flex}.FSsC8q_heading{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;font-weight:600;line-height:18px}.
|
|
1042
|
+
const css$2 = ".FSsC8q_tabs{z-index:1;background:var(--dsw-alias-bg-layer-2);padding:0 0 12px;position:sticky;top:0}.FSsC8q_panel{min-width:0}.FSsC8q_stack{flex-direction:column;gap:14px;min-width:0;display:flex}.FSsC8q_heading{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;font-weight:600;line-height:18px}.FSsC8q_block{flex-direction:column;gap:6px;display:flex}.FSsC8q_steps{color:var(--dsw-alias-label-tertiary);flex-direction:column;gap:2px;margin:0;padding:0 0 0 20px;font-size:12px;line-height:18px;display:flex}.FSsC8q_steps code{font-family:var(--dsw-font-family-mono,ui-monospace, monospace);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere}.FSsC8q_summary{grid-template-columns:max-content 1fr;gap:10px 16px;margin:0;font-size:13px;line-height:20px;display:grid}.FSsC8q_summary dt{color:var(--dsw-alias-label-tertiary)}.FSsC8q_summary dd{min-width:0;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0}.FSsC8q_planTarget{flex-wrap:wrap;align-items:baseline;gap:6px;margin:0;display:flex}.FSsC8q_planTarget code{font-family:var(--dsw-font-family-mono,ui-monospace, monospace);font-size:12px}.FSsC8q_outline{color:var(--dsw-alias-label-secondary);margin:4px 0 0;padding:0 0 0 20px}.FSsC8q_risks{margin:0;padding:0 0 0 16px}.FSsC8q_working{flex-direction:column;gap:10px;display:flex}.FSsC8q_workingLabel{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:18px}.FSsC8q_skeleton{border-radius:var(--dsw-radius-lg);box-shadow:0 0 0 .5px var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding:16px;display:flex}.FSsC8q_skeletonBar{border-radius:var(--dsw-radius-xs);background:var(--dsw-alias-bg-skeleton);height:10px;animation:1.1s cubic-bezier(.36,0,.64,1) infinite both FSsC8q_scout-skeleton}.FSsC8q_skeletonGap{height:4px}@keyframes FSsC8q_scout-skeleton{0%,to{opacity:1}50%{opacity:.5}}@media (prefers-reduced-motion:reduce){.FSsC8q_skeletonBar{animation:none}}.FSsC8q_callout{border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-interactive-bg-hover);flex-direction:column;gap:8px;margin:0;padding:12px 14px;font-size:13px;line-height:20px;display:flex}.FSsC8q_callout p{margin:0}.FSsC8q_note{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.FSsC8q_caution{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-state-warn-tertiary);color:var(--dsw-alias-state-warn-label);margin:0;padding:8px 12px;font-size:12px;line-height:18px}.FSsC8q_failure{color:var(--dsw-alias-state-error-label,var(--dsw-alias-state-warn-label));flex-direction:column;gap:2px;margin:0;font-size:13px;line-height:20px;display:flex}.FSsC8q_failureDetail{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:12px;line-height:18px}.FSsC8q_episode{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:8px;padding:12px 0 0;display:flex}.FSsC8q_episodeHead{align-items:flex-start;gap:10px;display:flex}.FSsC8q_ref{border-radius:var(--dsw-radius-xs);background:var(--dsw-alias-interactive-bg-hover);min-width:24px;color:var(--dsw-alias-label-secondary);text-align:center;font-variant-numeric:tabular-nums;flex:none;padding:1px 6px;font-size:11px;line-height:18px}.FSsC8q_episodeText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.FSsC8q_goal{-webkit-line-clamp:2;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;-webkit-box-orient:vertical;margin:0;font-size:13px;line-height:20px;display:-webkit-box;overflow:hidden}.FSsC8q_meta{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;gap:4px 10px;margin:0;font-size:12px;line-height:18px;display:flex}.FSsC8q_path{font-family:var(--dsw-font-family-mono,ui-monospace, monospace);font-size:11px}.FSsC8q_ops{flex-direction:column;margin:0;padding:0 0 0 34px;list-style:none;display:flex}.FSsC8q_op{border-radius:var(--dsw-radius-md);align-items:flex-start;gap:8px;padding:4px 8px;font-size:12px;line-height:18px;display:flex}.FSsC8q_op[data-cited]{background:var(--dsw-alias-interactive-bg-hover)}.FSsC8q_opGlyph{width:14px;height:18px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.FSsC8q_op[data-ok=false] .FSsC8q_opGlyph{color:var(--dsw-alias-state-warn-label)}.FSsC8q_opBody{flex-wrap:wrap;flex:1;align-items:baseline;gap:2px 8px;min-width:0;display:flex}.FSsC8q_opLabel{min-width:0;font-family:var(--dsw-font-family-mono,ui-monospace, monospace);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;font-size:12px}.FSsC8q_opLabel[data-kind=edit]{color:var(--dsw-alias-label-secondary)}.FSsC8q_opTags{flex-wrap:wrap;gap:4px;display:inline-flex}.FSsC8q_tag{border-radius:var(--dsw-radius-xs);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);padding:0 6px;font-size:11px;line-height:16px}.FSsC8q_tag[data-cited]{color:var(--dsw-alias-state-business-primary)}.FSsC8q_opError{color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-family-mono,ui-monospace, monospace);overflow-wrap:anywhere;flex-basis:100%;font-size:11px}.FSsC8q_opRef{color:var(--dsw-alias-label-caption,var(--dsw-alias-label-tertiary));font-variant-numeric:tabular-nums;flex:none;font-size:11px}.FSsC8q_toolbar{justify-content:space-between;align-items:center;gap:8px;display:flex}.FSsC8q_toolbarActions{align-items:center;gap:4px;display:flex}.FSsC8q_facts{grid-template-columns:max-content 1fr;gap:4px 16px;margin:0;font-size:13px;line-height:20px;display:grid}.FSsC8q_facts dt{color:var(--dsw-alias-label-tertiary)}.FSsC8q_facts dd{overflow-wrap:anywhere;min-width:0;margin:0}.FSsC8q_markdown{border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-base));box-shadow:0 0 0 .5px var(--dsw-alias-border-l2);padding:4px 16px}.FSsC8q_editor{flex-direction:column;gap:12px;display:flex}.FSsC8q_field{flex-direction:column;gap:4px;display:flex}.FSsC8q_fieldLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.FSsC8q_input{box-sizing:border-box;border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-base));width:100%;box-shadow:0 0 0 .5px var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);font:inherit;resize:vertical;border:0;padding:7px 10px;font-size:13px;line-height:20px}.FSsC8q_input:focus-visible{box-shadow:0 0 0 1.5px var(--dsw-alias-state-business-primary);outline:none}.FSsC8q_mono{font-family:var(--dsw-font-family-mono,ui-monospace, monospace);font-size:12px;line-height:18px}.FSsC8q_spacer{flex:1}.FSsC8q_actionError{color:var(--dsw-alias-state-error-label,var(--dsw-alias-state-warn-label));flex-basis:100%;margin:0;font-size:12px;line-height:18px}.FSsC8q_written{min-width:0;color:var(--dsw-alias-label-secondary);flex-direction:column;margin:0;font-size:12px;line-height:18px;display:flex}.FSsC8q_writtenPath{color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family-mono,ui-monospace, monospace);overflow-wrap:anywhere}";
|
|
1007
1043
|
const tag$2 = "@agent-stash/dsh-skill-scout/detail.module.css";
|
|
1008
1044
|
if (document.querySelector(`style[data-plugin-css=${JSON.stringify(tag$2)}]`) === null) {
|
|
1009
1045
|
const style = document.createElement("style");
|
|
@@ -1014,6 +1050,7 @@ window.__ModuleLoader__.load({
|
|
|
1014
1050
|
}
|
|
1015
1051
|
var detail_module_css_default = {
|
|
1016
1052
|
"actionError": "FSsC8q_actionError",
|
|
1053
|
+
"block": "FSsC8q_block",
|
|
1017
1054
|
"callout": "FSsC8q_callout",
|
|
1018
1055
|
"caution": "FSsC8q_caution",
|
|
1019
1056
|
"editor": "FSsC8q_editor",
|
|
@@ -1040,15 +1077,26 @@ window.__ModuleLoader__.load({
|
|
|
1040
1077
|
"opRef": "FSsC8q_opRef",
|
|
1041
1078
|
"ops": "FSsC8q_ops",
|
|
1042
1079
|
"opTags": "FSsC8q_opTags",
|
|
1080
|
+
"outline": "FSsC8q_outline",
|
|
1043
1081
|
"panel": "FSsC8q_panel",
|
|
1044
1082
|
"path": "FSsC8q_path",
|
|
1083
|
+
"planTarget": "FSsC8q_planTarget",
|
|
1045
1084
|
"ref": "FSsC8q_ref",
|
|
1085
|
+
"risks": "FSsC8q_risks",
|
|
1086
|
+
"scout-skeleton": "FSsC8q_scout-skeleton",
|
|
1087
|
+
"skeleton": "FSsC8q_skeleton",
|
|
1088
|
+
"skeletonBar": "FSsC8q_skeletonBar",
|
|
1089
|
+
"skeletonGap": "FSsC8q_skeletonGap",
|
|
1046
1090
|
"spacer": "FSsC8q_spacer",
|
|
1047
1091
|
"stack": "FSsC8q_stack",
|
|
1092
|
+
"steps": "FSsC8q_steps",
|
|
1093
|
+
"summary": "FSsC8q_summary",
|
|
1048
1094
|
"tabs": "FSsC8q_tabs",
|
|
1049
1095
|
"tag": "FSsC8q_tag",
|
|
1050
1096
|
"toolbar": "FSsC8q_toolbar",
|
|
1051
|
-
"
|
|
1097
|
+
"toolbarActions": "FSsC8q_toolbarActions",
|
|
1098
|
+
"working": "FSsC8q_working",
|
|
1099
|
+
"workingLabel": "FSsC8q_workingLabel",
|
|
1052
1100
|
"written": "FSsC8q_written",
|
|
1053
1101
|
"writtenPath": "FSsC8q_writtenPath"
|
|
1054
1102
|
};
|
|
@@ -1069,10 +1117,18 @@ window.__ModuleLoader__.load({
|
|
|
1069
1117
|
function sessionCount(t, count) {
|
|
1070
1118
|
return t(count === 1 ? "meta.sessions.one" : "meta.sessions.other", { count });
|
|
1071
1119
|
}
|
|
1072
|
-
/**
|
|
1120
|
+
/** 卡片标题:摘要里的标题,还没有摘要时用用户请求。 */
|
|
1073
1121
|
function titleOf(item) {
|
|
1074
1122
|
return item.title ?? item.goal;
|
|
1075
1123
|
}
|
|
1124
|
+
/** 状态文案;失败按阶段区分。 */
|
|
1125
|
+
function stateLabel(t, item) {
|
|
1126
|
+
return item.state === "failed" && item.failure?.stage === "draft" ? t("state.draftFailed") : t(`state.${item.state}`);
|
|
1127
|
+
}
|
|
1128
|
+
/** 模型正在处理这条建议。 */
|
|
1129
|
+
function inFlight(item) {
|
|
1130
|
+
return item.state === "summarizing" || item.state === "drafting";
|
|
1131
|
+
}
|
|
1076
1132
|
/** 一行元信息:信号类型 · 会话数 · 时间。 */
|
|
1077
1133
|
function metaOf(t, item, now) {
|
|
1078
1134
|
return [
|
|
@@ -1081,11 +1137,19 @@ window.__ModuleLoader__.load({
|
|
|
1081
1137
|
ago(t, item.updatedAt, now)
|
|
1082
1138
|
].join(" · ");
|
|
1083
1139
|
}
|
|
1084
|
-
/**
|
|
1140
|
+
/** 失败在草稿阶段的建议仍有摘要,留在待决定的分组里。 */
|
|
1141
|
+
function draftFailed(item) {
|
|
1142
|
+
return item.state === "failed" && item.failure?.stage === "draft";
|
|
1143
|
+
}
|
|
1144
|
+
/** 等用户决定的建议:标题栏的数字只数这些。 */
|
|
1145
|
+
function needsReview(item) {
|
|
1146
|
+
return item.state === "proposed" || item.state === "drafting" || item.state === "ready" || draftFailed(item);
|
|
1147
|
+
}
|
|
1148
|
+
/** 按状态分组:待决定、本地发现、历史。 */
|
|
1085
1149
|
function groupItems(items) {
|
|
1086
1150
|
return {
|
|
1087
|
-
|
|
1088
|
-
found: items.filter((item) => item.state === "detected" || item.state === "
|
|
1151
|
+
review: items.filter(needsReview),
|
|
1152
|
+
found: items.filter((item) => item.state === "detected" || item.state === "summarizing" || item.state === "failed" && !draftFailed(item)),
|
|
1089
1153
|
history: items.filter((item) => item.state === "written" || item.state === "skipped" || item.state === "dismissed")
|
|
1090
1154
|
};
|
|
1091
1155
|
}
|
|
@@ -1097,8 +1161,8 @@ window.__ModuleLoader__.load({
|
|
|
1097
1161
|
//#endregion
|
|
1098
1162
|
//#region src/client/detail.tsx
|
|
1099
1163
|
/**
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1164
|
+
* 一条建议的详情:摘要、证据、Skill 预览与编辑、文件改动,以及生成摘要、同意生成草稿、保存、忽略、撤销。
|
|
1165
|
+
* 证据、摘要与草稿从 Host 读取;建议的状态跟随收件箱刷新,状态或更新时间变化时重新读取详情。
|
|
1102
1166
|
*/
|
|
1103
1167
|
function message(error) {
|
|
1104
1168
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -1235,6 +1299,14 @@ window.__ModuleLoader__.load({
|
|
|
1235
1299
|
className: detail_module_css_default.note,
|
|
1236
1300
|
children: t(episode.reads === 1 ? "evidence.reads.one" : "evidence.reads.other", { count: episode.reads })
|
|
1237
1301
|
}),
|
|
1302
|
+
keyed(episode.steering).map(({ key, text }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1303
|
+
className: detail_module_css_default.note,
|
|
1304
|
+
children: [
|
|
1305
|
+
t("evidence.steering"),
|
|
1306
|
+
": ",
|
|
1307
|
+
text
|
|
1308
|
+
]
|
|
1309
|
+
}, key)),
|
|
1238
1310
|
episode.followup !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1239
1311
|
className: detail_module_css_default.note,
|
|
1240
1312
|
children: [
|
|
@@ -1295,12 +1367,73 @@ window.__ModuleLoader__.load({
|
|
|
1295
1367
|
]
|
|
1296
1368
|
});
|
|
1297
1369
|
}
|
|
1370
|
+
/** 给可能重复的文本行配上稳定的 key:文本加上它第几次出现。 */
|
|
1371
|
+
function keyed(lines) {
|
|
1372
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1373
|
+
return lines.map((text) => {
|
|
1374
|
+
const count = (seen.get(text) ?? 0) + 1;
|
|
1375
|
+
seen.set(text, count);
|
|
1376
|
+
return {
|
|
1377
|
+
key: `${text}#${String(count)}`,
|
|
1378
|
+
text
|
|
1379
|
+
};
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
/** 摘要占位条的宽度:几行短文本。 */
|
|
1383
|
+
const SUMMARY_BARS = [
|
|
1384
|
+
"88%",
|
|
1385
|
+
"72%",
|
|
1386
|
+
"46%"
|
|
1387
|
+
];
|
|
1388
|
+
/** 草稿占位条的宽度,按 SKILL.md 的排版:标题、描述,空一行,一节标题与几行步骤;空串是段间空行。 */
|
|
1389
|
+
const DRAFT_BARS = [
|
|
1390
|
+
"36%",
|
|
1391
|
+
"94%",
|
|
1392
|
+
"82%",
|
|
1393
|
+
"",
|
|
1394
|
+
"22%",
|
|
1395
|
+
"90%",
|
|
1396
|
+
"74%",
|
|
1397
|
+
"84%",
|
|
1398
|
+
"58%"
|
|
1399
|
+
];
|
|
1400
|
+
/** 相邻占位条的起伏错开的时间,连起来是一道自上而下的波。 */
|
|
1401
|
+
const BAR_STAGGER = 70;
|
|
1402
|
+
/** 模型写作时的占位:按最终排版画出的几条横条,依次快速明暗起伏;减少动态效果时静止。 */
|
|
1403
|
+
function Skeleton({ bars }) {
|
|
1404
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1405
|
+
className: detail_module_css_default.skeleton,
|
|
1406
|
+
"aria-hidden": "true",
|
|
1407
|
+
children: keyed(bars).map(({ key, text: width }, index) => width === "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: detail_module_css_default.skeletonGap }, key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1408
|
+
className: detail_module_css_default.skeletonBar,
|
|
1409
|
+
style: {
|
|
1410
|
+
width,
|
|
1411
|
+
animationDelay: `${String(index * BAR_STAGGER)}ms`
|
|
1412
|
+
}
|
|
1413
|
+
}, key))
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
/** 模型正在处理时的一行状态与占位。 */
|
|
1417
|
+
function Working({ label, bars }) {
|
|
1418
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1419
|
+
className: detail_module_css_default.working,
|
|
1420
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1421
|
+
className: detail_module_css_default.workingLabel,
|
|
1422
|
+
role: "status",
|
|
1423
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
|
|
1424
|
+
active: true,
|
|
1425
|
+
children: label
|
|
1426
|
+
})
|
|
1427
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Skeleton, { bars })]
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1298
1430
|
/** 一条建议的详情对话框。 */
|
|
1299
|
-
function Detail({ id, item, inbox, loadDetail,
|
|
1431
|
+
function Detail({ id, item, inbox, loadDetail, models, defaultScope, openSession, t, onClose }) {
|
|
1300
1432
|
const tabsId = (0, react.useId)();
|
|
1301
1433
|
const labels = useLabels(t);
|
|
1302
1434
|
const [detail, setDetail] = (0, react.useState)({ status: "loading" });
|
|
1303
|
-
|
|
1435
|
+
/** 用户选中的页签;为 null 时跟随状态:草稿生成中与可以保存时看 Skill,其余看摘要。 */
|
|
1436
|
+
const [chosenTab, setChosenTab] = (0, react.useState)(null);
|
|
1304
1437
|
const [scope, setScope] = (0, react.useState)(defaultScope);
|
|
1305
1438
|
const [editing, setEditing] = (0, react.useState)(false);
|
|
1306
1439
|
const [fields, setFields] = (0, react.useState)(null);
|
|
@@ -1334,12 +1467,16 @@ window.__ModuleLoader__.load({
|
|
|
1334
1467
|
const value = detail.status === "ready" ? detail.value : null;
|
|
1335
1468
|
const create = item.decision === "suggest_create";
|
|
1336
1469
|
const improve = item.decision === "suggest_improve";
|
|
1337
|
-
const
|
|
1470
|
+
const proposal = create || improve;
|
|
1471
|
+
const drafted = value !== null && (value.draft !== null || value.section !== null);
|
|
1338
1472
|
const draft = fields ?? value?.draft ?? null;
|
|
1339
1473
|
const shownSection = section ?? value?.section ?? null;
|
|
1340
1474
|
const parsed = draft === null ? null : /* @__PURE__ */ safeParse(SkillFieldsSchema, draft);
|
|
1341
1475
|
const invalid = create && parsed !== null && !parsed.success;
|
|
1342
|
-
const
|
|
1476
|
+
const draftFailed = item.state === "failed" && item.failure?.stage === "draft";
|
|
1477
|
+
/** 摘要已经给出计划,等用户同意生成草稿。 */
|
|
1478
|
+
const awaitingConsent = proposal && (item.state === "proposed" || draftFailed);
|
|
1479
|
+
const wantPreview = drafted && item.state === "ready";
|
|
1343
1480
|
(0, react.useEffect)(() => {
|
|
1344
1481
|
if (!wantPreview || invalid) return void 0;
|
|
1345
1482
|
let stale = false;
|
|
@@ -1399,6 +1536,24 @@ window.__ModuleLoader__.load({
|
|
|
1399
1536
|
}
|
|
1400
1537
|
};
|
|
1401
1538
|
const skillName = item.skill ?? "";
|
|
1539
|
+
const summarize = () => {
|
|
1540
|
+
run("summarize", {
|
|
1541
|
+
action: "summarize",
|
|
1542
|
+
id
|
|
1543
|
+
});
|
|
1544
|
+
};
|
|
1545
|
+
/** 同意摘要,生成草稿;之前的编辑与预览作废,页签回到跟随状态。 */
|
|
1546
|
+
const generate = () => {
|
|
1547
|
+
setFields(null);
|
|
1548
|
+
setSection(null);
|
|
1549
|
+
setEditing(false);
|
|
1550
|
+
setPreview(null);
|
|
1551
|
+
setChosenTab(null);
|
|
1552
|
+
run("draft", {
|
|
1553
|
+
action: "draft",
|
|
1554
|
+
id
|
|
1555
|
+
});
|
|
1556
|
+
};
|
|
1402
1557
|
const dismiss = async (similar) => {
|
|
1403
1558
|
if (await run("dismiss", {
|
|
1404
1559
|
action: "dismiss",
|
|
@@ -1433,134 +1588,202 @@ window.__ModuleLoader__.load({
|
|
|
1433
1588
|
setPreview(null);
|
|
1434
1589
|
}
|
|
1435
1590
|
};
|
|
1436
|
-
const tabs = [
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1591
|
+
const tabs = [
|
|
1592
|
+
{
|
|
1593
|
+
value: "summary",
|
|
1594
|
+
label: t("detail.tab.summary")
|
|
1595
|
+
},
|
|
1596
|
+
...item.state === "drafting" || drafted ? [{
|
|
1597
|
+
value: "skill",
|
|
1598
|
+
label: t("detail.tab.skill")
|
|
1599
|
+
}] : [],
|
|
1600
|
+
...item.state === "ready" && drafted ? [{
|
|
1601
|
+
value: "changes",
|
|
1602
|
+
label: t("detail.tab.changes")
|
|
1603
|
+
}] : [],
|
|
1604
|
+
{
|
|
1605
|
+
value: "evidence",
|
|
1606
|
+
label: t("detail.tab.evidence")
|
|
1607
|
+
}
|
|
1608
|
+
];
|
|
1609
|
+
const autoTab = item.state === "drafting" || item.state === "ready" ? "skill" : "summary";
|
|
1610
|
+
const wanted = chosenTab ?? autoTab;
|
|
1611
|
+
const activeTab = tabs.some((entry) => entry.value === wanted) ? wanted : "summary";
|
|
1447
1612
|
const subtitle = [
|
|
1448
1613
|
t(`kind.${item.kind}`),
|
|
1449
1614
|
sessionCount(t, item.occurrences),
|
|
1450
|
-
value?.
|
|
1615
|
+
value?.draftCall != null ? t("detail.draftedBy", { model: value.draftCall.model }) : value?.summary != null ? t("detail.summarizedBy", { model: value.summary.model }) : stateLabel(t, item)
|
|
1451
1616
|
].join(" · ");
|
|
1452
|
-
const
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1617
|
+
const failure = (stage) => item.state === "failed" && item.failure?.stage === stage ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1618
|
+
className: detail_module_css_default.failure,
|
|
1619
|
+
role: "alert",
|
|
1620
|
+
children: [t(stage === "summary" ? "detail.failed.summary" : "detail.failed.draft", { kind: t(`failure.${item.failure.kind}`) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1621
|
+
className: detail_module_css_default.failureDetail,
|
|
1622
|
+
children: item.failure.message
|
|
1623
|
+
})]
|
|
1624
|
+
}) : null;
|
|
1625
|
+
/** 规则匹配到的步骤,原来的写法。 */
|
|
1626
|
+
const steps = () => item.steps.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1627
|
+
className: detail_module_css_default.block,
|
|
1628
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
1629
|
+
className: detail_module_css_default.heading,
|
|
1630
|
+
children: t("detail.steps")
|
|
1631
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
|
|
1632
|
+
className: detail_module_css_default.steps,
|
|
1633
|
+
children: keyed(item.steps).map(({ key, text }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: text }) }, key))
|
|
1634
|
+
})]
|
|
1635
|
+
});
|
|
1636
|
+
/** 摘要里的方案:发现了什么、Skill 做什么、何时使用、将要新建或改进哪个 Skill 与提纲、风险、验证方式。 */
|
|
1637
|
+
const plan = () => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
|
|
1638
|
+
className: detail_module_css_default.summary,
|
|
1639
|
+
children: [
|
|
1640
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("detail.found") }),
|
|
1641
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: item.found }),
|
|
1642
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("detail.description") }),
|
|
1643
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: item.description }),
|
|
1644
|
+
item.trigger !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("detail.trigger") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: item.trigger })] }),
|
|
1645
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("detail.plan") }),
|
|
1646
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dd", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1647
|
+
className: detail_module_css_default.planTarget,
|
|
1648
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(create ? "detail.plan.create" : "detail.plan.improve") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: skillName })]
|
|
1649
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
|
|
1650
|
+
className: detail_module_css_default.outline,
|
|
1651
|
+
children: keyed(item.outline).map(({ key, text }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: text }, key))
|
|
1652
|
+
})] }),
|
|
1653
|
+
item.risks.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("detail.risks") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
1654
|
+
className: detail_module_css_default.risks,
|
|
1655
|
+
children: keyed(item.risks).map(({ key, text }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: text }, key))
|
|
1656
|
+
}) })] }),
|
|
1657
|
+
item.verification !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("detail.verification") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: item.verification })] })
|
|
1658
|
+
]
|
|
1659
|
+
});
|
|
1660
|
+
const summaryTab = () => {
|
|
1661
|
+
if (item.state === "summarizing") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1662
|
+
className: detail_module_css_default.stack,
|
|
1663
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Working, {
|
|
1664
|
+
label: t("detail.summarizing", { model: models.summary ?? "" }),
|
|
1665
|
+
bars: SUMMARY_BARS
|
|
1666
|
+
}), steps()]
|
|
1457
1667
|
});
|
|
1458
|
-
if (
|
|
1459
|
-
className: detail_module_css_default.
|
|
1460
|
-
|
|
1461
|
-
|
|
1668
|
+
if (proposal) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1669
|
+
className: detail_module_css_default.stack,
|
|
1670
|
+
children: [plan(), awaitingConsent && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1671
|
+
className: detail_module_css_default.callout,
|
|
1672
|
+
children: [failure("draft"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1673
|
+
className: detail_module_css_default.note,
|
|
1674
|
+
children: models.draft === null ? t("detail.noDraftModel") : t("detail.consent", { model: models.draft })
|
|
1675
|
+
})]
|
|
1676
|
+
})]
|
|
1462
1677
|
});
|
|
1463
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1464
|
-
className: detail_module_css_default.
|
|
1465
|
-
children: [
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
role: "alert",
|
|
1469
|
-
children: [t("detail.failed", { kind: t(`failure.${item.failure.kind}`) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1470
|
-
className: detail_module_css_default.failureDetail,
|
|
1471
|
-
children: item.failure.message
|
|
1472
|
-
})]
|
|
1473
|
-
}),
|
|
1474
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("detail.local") }),
|
|
1475
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1678
|
+
if (item.decision === "skip") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1679
|
+
className: detail_module_css_default.stack,
|
|
1680
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1681
|
+
className: detail_module_css_default.callout,
|
|
1682
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("detail.skipped") }), item.reason !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1476
1683
|
className: detail_module_css_default.note,
|
|
1477
|
-
children:
|
|
1478
|
-
|
|
1479
|
-
|
|
1684
|
+
children: item.reason
|
|
1685
|
+
})]
|
|
1686
|
+
}), steps()]
|
|
1687
|
+
});
|
|
1688
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1689
|
+
className: detail_module_css_default.stack,
|
|
1690
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1691
|
+
className: detail_module_css_default.callout,
|
|
1692
|
+
children: [
|
|
1693
|
+
failure("summary"),
|
|
1694
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("detail.local") }),
|
|
1695
|
+
item.state !== "written" && item.state !== "dismissed" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1696
|
+
className: detail_module_css_default.note,
|
|
1697
|
+
children: models.summary === null ? t("detail.noSummaryModel") : t("detail.summaryNote", {
|
|
1698
|
+
count: item.sessions.length,
|
|
1699
|
+
model: models.summary
|
|
1700
|
+
})
|
|
1480
1701
|
})
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
size: "sm",
|
|
1484
|
-
variant: "outline",
|
|
1485
|
-
"data-autofocus": "",
|
|
1486
|
-
disabled: modelName === null || busy !== null,
|
|
1487
|
-
onClick: () => void run("review", {
|
|
1488
|
-
action: "analyze",
|
|
1489
|
-
id
|
|
1490
|
-
}),
|
|
1491
|
-
children: item.failure === null ? t("detail.review") : t("detail.retry")
|
|
1492
|
-
}) })
|
|
1493
|
-
]
|
|
1702
|
+
]
|
|
1703
|
+
}), steps()]
|
|
1494
1704
|
});
|
|
1495
1705
|
};
|
|
1496
|
-
const evidence = () => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1706
|
+
const evidence = () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1497
1707
|
className: detail_module_css_default.stack,
|
|
1498
|
-
children:
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
children: t("detail.why")
|
|
1505
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: item.reason })]
|
|
1506
|
-
}),
|
|
1507
|
-
item.cautions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1508
|
-
className: detail_module_css_default.caution,
|
|
1509
|
-
role: "note",
|
|
1510
|
-
children: t("detail.cautions", { list: item.cautions.map((caution) => {
|
|
1511
|
-
const key = `caution.${caution}`;
|
|
1512
|
-
return isCaution(key) ? t(key) : caution;
|
|
1513
|
-
}).join(", ") })
|
|
1514
|
-
}),
|
|
1515
|
-
value?.episodes.map((episode) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Episode, {
|
|
1516
|
-
episode,
|
|
1517
|
-
now,
|
|
1518
|
-
openSession,
|
|
1519
|
-
t
|
|
1520
|
-
}, episode.episodeId))
|
|
1521
|
-
]
|
|
1708
|
+
children: value?.episodes.map((episode) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Episode, {
|
|
1709
|
+
episode,
|
|
1710
|
+
now,
|
|
1711
|
+
openSession,
|
|
1712
|
+
t
|
|
1713
|
+
}, episode.episodeId))
|
|
1522
1714
|
});
|
|
1523
|
-
const
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1715
|
+
const cautions = () => item.cautions.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1716
|
+
className: detail_module_css_default.caution,
|
|
1717
|
+
role: "note",
|
|
1718
|
+
children: t("detail.cautions", { list: item.cautions.map((caution) => {
|
|
1719
|
+
const key = `caution.${caution}`;
|
|
1720
|
+
return isCaution(key) ? t(key) : caution;
|
|
1721
|
+
}).join(", ") })
|
|
1722
|
+
});
|
|
1723
|
+
/** 草稿页签的工具栏:编辑、还原,以及按同一份摘要重新生成。 */
|
|
1724
|
+
const toolbar = (lead) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1725
|
+
className: detail_module_css_default.toolbar,
|
|
1726
|
+
children: [lead, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1727
|
+
className: detail_module_css_default.toolbarActions,
|
|
1728
|
+
children: [
|
|
1729
|
+
item.state === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1529
1730
|
size: "sm",
|
|
1530
1731
|
variant: "ghost",
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
children:
|
|
1534
|
-
}),
|
|
1732
|
+
disabled: busy !== null,
|
|
1733
|
+
onClick: generate,
|
|
1734
|
+
children: t("detail.redraft")
|
|
1735
|
+
}),
|
|
1736
|
+
(create ? fields : section) !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1535
1737
|
size: "sm",
|
|
1536
1738
|
variant: "ghost",
|
|
1537
|
-
onClick: () => setFields(null),
|
|
1739
|
+
onClick: () => create ? setFields(null) : setSection(null),
|
|
1538
1740
|
children: t("skill.reset")
|
|
1539
|
-
})
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
role: "alert",
|
|
1547
|
-
children: t("skill.invalid")
|
|
1548
|
-
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
|
|
1549
|
-
className: detail_module_css_default.facts,
|
|
1550
|
-
children: [
|
|
1551
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("skill.name") }),
|
|
1552
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: draft.name }) }),
|
|
1553
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("skill.description") }),
|
|
1554
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: draft.description }),
|
|
1555
|
-
draft.whenToUse !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("skill.whenToUse") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: draft.whenToUse })] })
|
|
1556
|
-
]
|
|
1557
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1558
|
-
className: detail_module_css_default.markdown,
|
|
1559
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
1560
|
-
text: draft.body,
|
|
1561
|
-
labels: labels.markdown
|
|
1741
|
+
}),
|
|
1742
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1743
|
+
size: "sm",
|
|
1744
|
+
variant: "ghost",
|
|
1745
|
+
onClick: () => setEditing(!editing),
|
|
1746
|
+
disabled: item.state !== "ready",
|
|
1747
|
+
children: editing ? t("skill.preview") : t("skill.edit")
|
|
1562
1748
|
})
|
|
1563
|
-
|
|
1749
|
+
]
|
|
1750
|
+
})]
|
|
1751
|
+
});
|
|
1752
|
+
const skill = () => {
|
|
1753
|
+
if (item.state === "drafting") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Working, {
|
|
1754
|
+
label: t("detail.drafting", { model: models.draft ?? "" }),
|
|
1755
|
+
bars: DRAFT_BARS
|
|
1756
|
+
});
|
|
1757
|
+
if (create && draft !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1758
|
+
className: detail_module_css_default.stack,
|
|
1759
|
+
children: [
|
|
1760
|
+
cautions(),
|
|
1761
|
+
toolbar(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {})),
|
|
1762
|
+
editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldsEditor, {
|
|
1763
|
+
fields: draft,
|
|
1764
|
+
onChange: setFields,
|
|
1765
|
+
t
|
|
1766
|
+
}), invalid && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1767
|
+
className: detail_module_css_default.failure,
|
|
1768
|
+
role: "alert",
|
|
1769
|
+
children: t("skill.invalid")
|
|
1770
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
|
|
1771
|
+
className: detail_module_css_default.facts,
|
|
1772
|
+
children: [
|
|
1773
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("skill.name") }),
|
|
1774
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: draft.name }) }),
|
|
1775
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("skill.description") }),
|
|
1776
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: draft.description }),
|
|
1777
|
+
draft.whenToUse !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("skill.whenToUse") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: draft.whenToUse })] })
|
|
1778
|
+
]
|
|
1779
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1780
|
+
className: detail_module_css_default.markdown,
|
|
1781
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
1782
|
+
text: draft.body,
|
|
1783
|
+
labels: labels.markdown
|
|
1784
|
+
})
|
|
1785
|
+
})] })
|
|
1786
|
+
]
|
|
1564
1787
|
});
|
|
1565
1788
|
if (improve && shownSection !== null) {
|
|
1566
1789
|
const notWritable = preview?.status === "ready" && preview.value.kind === "improve" && !preview.value.writable;
|
|
@@ -1571,19 +1794,11 @@ window.__ModuleLoader__.load({
|
|
|
1571
1794
|
className: detail_module_css_default.caution,
|
|
1572
1795
|
children: t("skill.notWritable", { skill: skillName })
|
|
1573
1796
|
}),
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1580
|
-
size: "sm",
|
|
1581
|
-
variant: "ghost",
|
|
1582
|
-
onClick: () => setEditing(!editing),
|
|
1583
|
-
disabled: item.state !== "ready",
|
|
1584
|
-
children: editing ? t("skill.preview") : t("skill.edit")
|
|
1585
|
-
})]
|
|
1586
|
-
}),
|
|
1797
|
+
cautions(),
|
|
1798
|
+
toolbar(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1799
|
+
className: detail_module_css_default.heading,
|
|
1800
|
+
children: t("skill.section", { skill: skillName })
|
|
1801
|
+
})),
|
|
1587
1802
|
editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
1588
1803
|
className: `${detail_module_css_default.input} ${detail_module_css_default.mono}`,
|
|
1589
1804
|
"aria-label": t("skill.section", { skill: skillName }),
|
|
@@ -1634,6 +1849,56 @@ window.__ModuleLoader__.load({
|
|
|
1634
1849
|
})]
|
|
1635
1850
|
});
|
|
1636
1851
|
};
|
|
1852
|
+
/** 右侧的主操作:随阶段从生成摘要、同意生成草稿到保存。 */
|
|
1853
|
+
const primary = () => {
|
|
1854
|
+
if (item.state === "summarizing" || item.state === "drafting") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1855
|
+
size: "sm",
|
|
1856
|
+
variant: "primary",
|
|
1857
|
+
disabled: true,
|
|
1858
|
+
children: stateLabel(t, item)
|
|
1859
|
+
});
|
|
1860
|
+
if (awaitingConsent) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1861
|
+
size: "sm",
|
|
1862
|
+
variant: "primary",
|
|
1863
|
+
"data-autofocus": "",
|
|
1864
|
+
disabled: models.draft === null || busy !== null,
|
|
1865
|
+
onClick: generate,
|
|
1866
|
+
children: draftFailed ? t("detail.redraft") : create ? t("detail.draft.create") : t("detail.draft.improve")
|
|
1867
|
+
});
|
|
1868
|
+
if (item.state === "ready") {
|
|
1869
|
+
const writable = !(preview?.status === "ready" && preview.value.kind === "improve" && !preview.value.writable);
|
|
1870
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [create && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SegmentedControl, {
|
|
1871
|
+
id: `${tabsId}-scope`,
|
|
1872
|
+
label: t("scope.label"),
|
|
1873
|
+
value: scope,
|
|
1874
|
+
disabled: busy !== null,
|
|
1875
|
+
options: [{
|
|
1876
|
+
value: "project",
|
|
1877
|
+
label: t("scope.project")
|
|
1878
|
+
}, {
|
|
1879
|
+
value: "user",
|
|
1880
|
+
label: t("scope.user")
|
|
1881
|
+
}],
|
|
1882
|
+
onChange: setScope
|
|
1883
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1884
|
+
size: "sm",
|
|
1885
|
+
variant: "primary",
|
|
1886
|
+
"data-autofocus": "",
|
|
1887
|
+
disabled: busy !== null || invalid || !writable,
|
|
1888
|
+
onClick: () => void save(),
|
|
1889
|
+
children: busy === "save" ? t("action.saving") : create ? t("action.save") : t("action.improve", { skill: skillName })
|
|
1890
|
+
})] });
|
|
1891
|
+
}
|
|
1892
|
+
const again = item.decision === "skip" || item.failure !== null;
|
|
1893
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1894
|
+
size: "sm",
|
|
1895
|
+
variant: item.decision === "skip" ? "outline" : "primary",
|
|
1896
|
+
"data-autofocus": "",
|
|
1897
|
+
disabled: models.summary === null || busy !== null,
|
|
1898
|
+
onClick: summarize,
|
|
1899
|
+
children: again ? t("detail.resummarize") : t("detail.summarize")
|
|
1900
|
+
});
|
|
1901
|
+
};
|
|
1637
1902
|
const footer = () => {
|
|
1638
1903
|
if (item.state === "written" && item.write !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1639
1904
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
@@ -1681,7 +1946,6 @@ window.__ModuleLoader__.load({
|
|
|
1681
1946
|
}),
|
|
1682
1947
|
children: t("action.restore")
|
|
1683
1948
|
})] });
|
|
1684
|
-
const writable = !(preview?.status === "ready" && preview.value.kind === "improve" && !preview.value.writable);
|
|
1685
1949
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1686
1950
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1687
1951
|
size: "sm",
|
|
@@ -1698,28 +1962,7 @@ window.__ModuleLoader__.load({
|
|
|
1698
1962
|
children: t("action.dismissSimilar")
|
|
1699
1963
|
}),
|
|
1700
1964
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: detail_module_css_default.spacer }),
|
|
1701
|
-
|
|
1702
|
-
id: `${tabsId}-scope`,
|
|
1703
|
-
label: t("scope.label"),
|
|
1704
|
-
value: scope,
|
|
1705
|
-
disabled: busy !== null,
|
|
1706
|
-
options: [{
|
|
1707
|
-
value: "project",
|
|
1708
|
-
label: t("scope.project")
|
|
1709
|
-
}, {
|
|
1710
|
-
value: "user",
|
|
1711
|
-
label: t("scope.user")
|
|
1712
|
-
}],
|
|
1713
|
-
onChange: setScope
|
|
1714
|
-
}),
|
|
1715
|
-
item.state === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1716
|
-
size: "sm",
|
|
1717
|
-
variant: "primary",
|
|
1718
|
-
"data-autofocus": "",
|
|
1719
|
-
disabled: busy !== null || invalid || !writable,
|
|
1720
|
-
onClick: () => void save(),
|
|
1721
|
-
children: busy === "save" ? t("action.saving") : create ? t("action.save") : t("action.improve", { skill: skillName })
|
|
1722
|
-
})
|
|
1965
|
+
primary()
|
|
1723
1966
|
] });
|
|
1724
1967
|
};
|
|
1725
1968
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Dialog, {
|
|
@@ -1751,20 +1994,21 @@ window.__ModuleLoader__.load({
|
|
|
1751
1994
|
})
|
|
1752
1995
|
]
|
|
1753
1996
|
}),
|
|
1754
|
-
value !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1997
|
+
value !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1755
1998
|
className: detail_module_css_default.tabs,
|
|
1756
1999
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SegmentedControl, {
|
|
1757
2000
|
id: tabsId,
|
|
1758
2001
|
label: t("detail.tabs"),
|
|
1759
2002
|
value: activeTab,
|
|
1760
2003
|
options: tabs,
|
|
1761
|
-
onChange:
|
|
2004
|
+
onChange: setChosenTab
|
|
1762
2005
|
})
|
|
1763
2006
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1764
2007
|
className: detail_module_css_default.panel,
|
|
1765
|
-
role:
|
|
1766
|
-
"aria-labelledby":
|
|
2008
|
+
role: "tabpanel",
|
|
2009
|
+
"aria-labelledby": `${tabsId}-${activeTab}`,
|
|
1767
2010
|
children: [
|
|
2011
|
+
activeTab === "summary" && summaryTab(),
|
|
1768
2012
|
activeTab === "evidence" && evidence(),
|
|
1769
2013
|
activeTab === "skill" && skill(),
|
|
1770
2014
|
activeTab === "changes" && changes()
|
|
@@ -1791,7 +2035,7 @@ window.__ModuleLoader__.load({
|
|
|
1791
2035
|
}
|
|
1792
2036
|
//#endregion
|
|
1793
2037
|
//#region \0dsh-css:src/client/inbox.module.css.mjs
|
|
1794
|
-
const css$1 = ".Wfa-jG_root{margin-left:4px;position:relative}.Wfa-jG_trigger{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:28px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex;position:relative}.Wfa-jG_trigger:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px;color:var(--dsw-alias-label-secondary)}@media (hover:hover){.Wfa-jG_trigger:hover{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover)}}.Wfa-jG_trigger[aria-expanded=true]{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover)}.Wfa-jG_trigger svg{flex:none}.Wfa-jG_badge{box-sizing:border-box;background:var(--dsw-alias-label-secondary);min-width:14px;height:14px;color:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-base));text-align:center;font-variant-numeric:tabular-nums;pointer-events:none;border-radius:7px;padding:0 3px;font-size:9px;font-weight:600;line-height:14px;position:absolute;top:1px;right:0}.Wfa-jG_panel{z-index:100;box-sizing:border-box;background:var(--dsw-specific-menu);width:360px;max-width:calc(100vw - 32px);max-height:min(480px,100vh - 140px);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);animation:Wfa-jG_panel-in .14s var(--ds-ease-in-out,ease);border:0;border-radius:16px;flex-direction:column;padding:4px;display:flex;position:fixed}.Wfa-jG_panel:focus{outline:none}@keyframes Wfa-jG_panel-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}.Wfa-jG_head{flex:none;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px 6px 12px;display:flex}.Wfa-jG_title{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;font-weight:600;line-height:18px}.Wfa-jG_working{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.Wfa-jG_scroll{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);flex-direction:column;flex:auto;gap:6px;min-height:0;display:flex;overflow-y:auto}.Wfa-jG_section{flex-direction:column;display:flex}.Wfa-jG_sectionTitle{color:var(--dsw-alias-label-tertiary);margin:0;padding:5px 12px 2px;font-size:11px;font-weight:500;line-height:16px}.Wfa-jG_list{flex-direction:column;gap:1px;margin:0;padding:0;list-style:none;display:flex}.Wfa-jG_card{border-radius:10px;align-items:flex-start;gap:4px;display:flex;position:relative}@media (hover:hover){.Wfa-jG_card:hover{background:var(--dsw-alias-interactive-bg-hover)}}.Wfa-jG_open{min-width:0;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:10px;flex-direction:column;flex:1;gap:2px;padding:8px 4px 8px 12px;display:flex}.Wfa-jG_open:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}.Wfa-jG_cardTitle{-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;font-size:13px;line-height:18px;display:-webkit-box;overflow:hidden}.Wfa-jG_card[data-state=detected] .Wfa-jG_cardTitle,.Wfa-jG_card[data-state=
|
|
2038
|
+
const css$1 = ".Wfa-jG_root{margin-left:4px;position:relative}.Wfa-jG_trigger{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:28px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex;position:relative}.Wfa-jG_trigger:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px;color:var(--dsw-alias-label-secondary)}@media (hover:hover){.Wfa-jG_trigger:hover{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover)}}.Wfa-jG_trigger[aria-expanded=true]{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover)}.Wfa-jG_trigger svg{flex:none}.Wfa-jG_badge{box-sizing:border-box;background:var(--dsw-alias-label-secondary);min-width:14px;height:14px;color:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-base));text-align:center;font-variant-numeric:tabular-nums;pointer-events:none;border-radius:7px;padding:0 3px;font-size:9px;font-weight:600;line-height:14px;position:absolute;top:1px;right:0}.Wfa-jG_panel{z-index:100;box-sizing:border-box;background:var(--dsw-specific-menu);width:360px;max-width:calc(100vw - 32px);max-height:min(480px,100vh - 140px);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);animation:Wfa-jG_panel-in .14s var(--ds-ease-in-out,ease);border:0;border-radius:16px;flex-direction:column;padding:4px;display:flex;position:fixed}.Wfa-jG_panel:focus{outline:none}@keyframes Wfa-jG_panel-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}.Wfa-jG_head{flex:none;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px 6px 12px;display:flex}.Wfa-jG_title{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;font-weight:600;line-height:18px}.Wfa-jG_working{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.Wfa-jG_scroll{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);flex-direction:column;flex:auto;gap:6px;min-height:0;display:flex;overflow-y:auto}.Wfa-jG_section{flex-direction:column;display:flex}.Wfa-jG_sectionTitle{color:var(--dsw-alias-label-tertiary);margin:0;padding:5px 12px 2px;font-size:11px;font-weight:500;line-height:16px}.Wfa-jG_list{flex-direction:column;gap:1px;margin:0;padding:0;list-style:none;display:flex}.Wfa-jG_card{border-radius:10px;align-items:flex-start;gap:4px;display:flex;position:relative}@media (hover:hover){.Wfa-jG_card:hover{background:var(--dsw-alias-interactive-bg-hover)}}.Wfa-jG_open{min-width:0;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:10px;flex-direction:column;flex:1;gap:2px;padding:8px 4px 8px 12px;display:flex}.Wfa-jG_open:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}.Wfa-jG_cardTitle{-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;font-size:13px;line-height:18px;display:-webkit-box;overflow:hidden}.Wfa-jG_card[data-state=detected] .Wfa-jG_cardTitle,.Wfa-jG_card[data-state=summarizing] .Wfa-jG_cardTitle,.Wfa-jG_card[data-state=failed]:not([data-stage=draft]) .Wfa-jG_cardTitle{color:var(--dsw-alias-label-secondary)}.Wfa-jG_cardSummary{-webkit-line-clamp:2;color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;-webkit-box-orient:vertical;font-size:12px;line-height:17px;display:-webkit-box;overflow:hidden}.Wfa-jG_cardMeta{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;gap:2px 6px;font-size:11px;line-height:16px;display:flex}.Wfa-jG_state{color:var(--dsw-alias-label-secondary)}.Wfa-jG_card[data-state=failed] .Wfa-jG_state{color:var(--dsw-alias-state-warn-label)}.Wfa-jG_dismiss{width:22px;height:22px;color:var(--dsw-alias-label-tertiary);cursor:pointer;opacity:0;background:0 0;border:0;border-radius:6px;flex:none;justify-content:center;align-items:center;margin:7px 6px 0 0;padding:0;display:inline-flex}.Wfa-jG_card:hover .Wfa-jG_dismiss,.Wfa-jG_card:focus-within .Wfa-jG_dismiss{opacity:1}.Wfa-jG_dismiss:focus-visible{opacity:1;outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}@media (hover:hover){.Wfa-jG_dismiss:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}}@media (hover:none){.Wfa-jG_dismiss{opacity:1}}.Wfa-jG_historyToggle{color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:6px;align-self:flex-start;margin:2px 0 2px 8px;padding:2px 4px;font-size:11px;line-height:16px}.Wfa-jG_historyToggle:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary)}@media (hover:hover){.Wfa-jG_historyToggle:hover{color:var(--dsw-alias-label-secondary)}}.Wfa-jG_banner{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:10px;margin:2px 4px 4px;padding:8px 10px;font-size:12px;line-height:18px}.Wfa-jG_empty{flex-direction:column;gap:4px;padding:10px 12px 14px;display:flex}.Wfa-jG_emptyTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:13px;line-height:20px}.Wfa-jG_emptyBody{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:18px}.Wfa-jG_caption{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;padding:0 12px;font-size:11px;line-height:16px}.Wfa-jG_empty .Wfa-jG_caption{padding:0}.Wfa-jG_errorRow{color:var(--dsw-alias-state-warn-label);justify-content:space-between;align-items:center;gap:8px;padding:8px 12px;font-size:12px;line-height:18px;display:flex}.Wfa-jG_link{color:var(--dsw-alias-state-business-primary);font:inherit;cursor:pointer;background:0 0;border:0;padding:0;font-size:12px}.Wfa-jG_link:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px;border-radius:4px}.Wfa-jG_notice{border-top:.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);flex:none;justify-content:space-between;align-items:center;gap:8px;margin-top:4px;padding:8px 12px;font-size:12px;line-height:18px;display:flex}.Wfa-jG_noticeText{overflow-wrap:anywhere;min-width:0}@media (prefers-reduced-motion:reduce){.Wfa-jG_panel{animation:none}}";
|
|
1795
2039
|
const tag$1 = "@agent-stash/dsh-skill-scout/inbox.module.css";
|
|
1796
2040
|
if (document.querySelector(`style[data-plugin-css=${JSON.stringify(tag$1)}]`) === null) {
|
|
1797
2041
|
const style = document.createElement("style");
|
|
@@ -1806,6 +2050,7 @@ window.__ModuleLoader__.load({
|
|
|
1806
2050
|
"caption": "Wfa-jG_caption",
|
|
1807
2051
|
"card": "Wfa-jG_card",
|
|
1808
2052
|
"cardMeta": "Wfa-jG_cardMeta",
|
|
2053
|
+
"cardSummary": "Wfa-jG_cardSummary",
|
|
1809
2054
|
"cardTitle": "Wfa-jG_cardTitle",
|
|
1810
2055
|
"dismiss": "Wfa-jG_dismiss",
|
|
1811
2056
|
"empty": "Wfa-jG_empty",
|
|
@@ -1835,7 +2080,7 @@ window.__ModuleLoader__.load({
|
|
|
1835
2080
|
/**
|
|
1836
2081
|
* 会话标题栏里的经验提炼入口:一个图标按钮,有新建议时带一个小计数;点开是收件箱浮层,
|
|
1837
2082
|
* 点卡片打开详情对话框。入口在第一次读取完成前不渲染,避免标题栏闪动。
|
|
1838
|
-
*
|
|
2083
|
+
* 计数只算打开收件箱之后出现的、等用户决定的摘要与草稿,看过即清零;详情里正打开的那条在眼前,不计入。
|
|
1839
2084
|
*/
|
|
1840
2085
|
const SEEN_KEY = "agent-stash-skill-scout:seen";
|
|
1841
2086
|
const SeenSchema = /* @__PURE__ */ pipe(/* @__PURE__ */ string(), /* @__PURE__ */ parseJson(), /* @__PURE__ */ array(/* @__PURE__ */ string()));
|
|
@@ -1869,32 +2114,45 @@ window.__ModuleLoader__.load({
|
|
|
1869
2114
|
left: 0,
|
|
1870
2115
|
top: 0
|
|
1871
2116
|
};
|
|
1872
|
-
/**
|
|
1873
|
-
function
|
|
1874
|
-
|
|
1875
|
-
|
|
2117
|
+
/** 等用户决定的摘要与草稿。 */
|
|
2118
|
+
function awaiting(inbox) {
|
|
2119
|
+
return (inbox?.items ?? []).filter((item) => item.state === "proposed" || item.state === "ready").map((item) => item.id);
|
|
2120
|
+
}
|
|
2121
|
+
/** 新建议数:等用户决定、还没看过,也不是详情里正打开的那条。 */
|
|
2122
|
+
function unseen(inbox, seen, viewing) {
|
|
2123
|
+
return awaiting(inbox).filter((id) => id !== viewing && !seen.has(id)).length;
|
|
1876
2124
|
}
|
|
1877
2125
|
function Card({ item, now, t, onOpen, onDismiss }) {
|
|
1878
2126
|
const title = titleOf(item);
|
|
1879
|
-
const showState = item.state !== "ready";
|
|
1880
2127
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
1881
2128
|
className: inbox_module_css_default.card,
|
|
1882
2129
|
"data-state": item.state,
|
|
2130
|
+
"data-stage": item.failure?.stage,
|
|
1883
2131
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1884
2132
|
type: "button",
|
|
1885
2133
|
className: inbox_module_css_default.open,
|
|
1886
2134
|
"data-item": item.id,
|
|
1887
2135
|
onClick: () => onOpen(item.id),
|
|
1888
|
-
children: [
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
className: inbox_module_css_default.
|
|
1895
|
-
children:
|
|
1896
|
-
}),
|
|
1897
|
-
|
|
2136
|
+
children: [
|
|
2137
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2138
|
+
className: inbox_module_css_default.cardTitle,
|
|
2139
|
+
children: title
|
|
2140
|
+
}),
|
|
2141
|
+
item.description !== null && item.state !== "written" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2142
|
+
className: inbox_module_css_default.cardSummary,
|
|
2143
|
+
children: item.description
|
|
2144
|
+
}),
|
|
2145
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2146
|
+
className: inbox_module_css_default.cardMeta,
|
|
2147
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2148
|
+
className: inbox_module_css_default.state,
|
|
2149
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
|
|
2150
|
+
active: inFlight(item),
|
|
2151
|
+
children: stateLabel(t, item)
|
|
2152
|
+
})
|
|
2153
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: metaOf(t, item, now) })]
|
|
2154
|
+
})
|
|
2155
|
+
]
|
|
1898
2156
|
}), onDismiss !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1899
2157
|
type: "button",
|
|
1900
2158
|
className: inbox_module_css_default.dismiss,
|
|
@@ -1910,7 +2168,7 @@ window.__ModuleLoader__.load({
|
|
|
1910
2168
|
const pending = inbox.items.some((item) => item.state === "detected" || item.state === "failed");
|
|
1911
2169
|
let key = null;
|
|
1912
2170
|
if (!status.discovery) key = "banner.discoveryOff";
|
|
1913
|
-
else if (status.
|
|
2171
|
+
else if (status.models.summary === null && pending) key = "banner.noModel";
|
|
1914
2172
|
else if (!status.lead) key = "banner.secondary";
|
|
1915
2173
|
if (key === null) return null;
|
|
1916
2174
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -1921,7 +2179,7 @@ window.__ModuleLoader__.load({
|
|
|
1921
2179
|
function PanelBody({ inbox, now, t, onOpen, onDismiss }) {
|
|
1922
2180
|
const [history, setHistory] = (0, react.useState)(false);
|
|
1923
2181
|
const groups = groupItems(inbox.items);
|
|
1924
|
-
if (groups.
|
|
2182
|
+
if (groups.review.length === 0 && groups.found.length === 0 && groups.history.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1925
2183
|
className: inbox_module_css_default.empty,
|
|
1926
2184
|
children: [
|
|
1927
2185
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Banner, {
|
|
@@ -1955,7 +2213,7 @@ window.__ModuleLoader__.load({
|
|
|
1955
2213
|
now,
|
|
1956
2214
|
t,
|
|
1957
2215
|
onOpen,
|
|
1958
|
-
onDismiss: item
|
|
2216
|
+
onDismiss: inFlight(item) ? void 0 : onDismiss
|
|
1959
2217
|
}, item.id))
|
|
1960
2218
|
})]
|
|
1961
2219
|
});
|
|
@@ -1964,7 +2222,7 @@ window.__ModuleLoader__.load({
|
|
|
1964
2222
|
inbox,
|
|
1965
2223
|
t
|
|
1966
2224
|
}),
|
|
1967
|
-
section("section.
|
|
2225
|
+
section("section.review", groups.review),
|
|
1968
2226
|
section("section.found", groups.found),
|
|
1969
2227
|
groups.history.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1970
2228
|
className: inbox_module_css_default.section,
|
|
@@ -2017,23 +2275,24 @@ window.__ModuleLoader__.load({
|
|
|
2017
2275
|
position
|
|
2018
2276
|
]);
|
|
2019
2277
|
(0, react.useEffect)(() => {
|
|
2020
|
-
if (
|
|
2021
|
-
const
|
|
2022
|
-
if (
|
|
2278
|
+
if (state.inbox === null) return;
|
|
2279
|
+
const ids = awaiting(state.inbox).filter((id) => open || id === detailId);
|
|
2280
|
+
if (ids.some((id) => !seen.has(id))) seen.add(ids);
|
|
2023
2281
|
}, [
|
|
2024
2282
|
open,
|
|
2283
|
+
detailId,
|
|
2025
2284
|
state.inbox,
|
|
2026
2285
|
seen
|
|
2027
2286
|
]);
|
|
2028
2287
|
if (state.inbox === null && state.status !== "error") return null;
|
|
2029
|
-
const fresh = unseen(state.inbox, seen);
|
|
2288
|
+
const fresh = unseen(state.inbox, seen, detailId);
|
|
2030
2289
|
const badge = state.inbox?.status.notify === "badge" && fresh > 0;
|
|
2031
2290
|
const label = fresh === 0 ? t("entry.label") : t(fresh === 1 ? "entry.count.one" : "entry.count.other", { count: fresh });
|
|
2032
|
-
const
|
|
2033
|
-
|
|
2291
|
+
const asking = (state.inbox?.status.working ?? 0) > 0;
|
|
2292
|
+
const working = asking || state.inbox?.status.scanning === true;
|
|
2293
|
+
/** 打开收件箱:刷新状态,并把当前的待决定建议记为看过。 */
|
|
2034
2294
|
const show = () => {
|
|
2035
|
-
|
|
2036
|
-
seen.add(ready);
|
|
2295
|
+
seen.add(awaiting(state.inbox));
|
|
2037
2296
|
setSeenVersion((version) => version + 1);
|
|
2038
2297
|
setNow(Date.now());
|
|
2039
2298
|
setOpen(true);
|
|
@@ -2092,7 +2351,10 @@ window.__ModuleLoader__.load({
|
|
|
2092
2351
|
}), working && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2093
2352
|
className: inbox_module_css_default.working,
|
|
2094
2353
|
role: "status",
|
|
2095
|
-
children:
|
|
2354
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
|
|
2355
|
+
active: true,
|
|
2356
|
+
children: asking ? t("panel.working") : t("panel.analyzing")
|
|
2357
|
+
})
|
|
2096
2358
|
})]
|
|
2097
2359
|
}),
|
|
2098
2360
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -2167,7 +2429,10 @@ window.__ModuleLoader__.load({
|
|
|
2167
2429
|
item: detailItem,
|
|
2168
2430
|
inbox,
|
|
2169
2431
|
loadDetail,
|
|
2170
|
-
|
|
2432
|
+
models: {
|
|
2433
|
+
summary: state.inbox?.status.models.summary?.model ?? null,
|
|
2434
|
+
draft: state.inbox?.status.models.draft?.model ?? null
|
|
2435
|
+
},
|
|
2171
2436
|
defaultScope: state.inbox?.status.scope ?? "project",
|
|
2172
2437
|
openSession,
|
|
2173
2438
|
t,
|
|
@@ -2187,19 +2452,18 @@ window.__ModuleLoader__.load({
|
|
|
2187
2452
|
"entry.count.other": "Skill suggestions, {count} new",
|
|
2188
2453
|
"panel.title": "Skill suggestions",
|
|
2189
2454
|
"panel.analyzing": "Analyzing sessions",
|
|
2190
|
-
"panel.
|
|
2455
|
+
"panel.working": "Asking the model",
|
|
2191
2456
|
"panel.loading": "Loading",
|
|
2192
2457
|
"panel.error": "Could not load suggestions.",
|
|
2193
2458
|
"panel.retry": "Retry",
|
|
2194
2459
|
"panel.empty.title": "No suggestions",
|
|
2195
2460
|
"panel.empty.body": "A suggestion appears when a workflow repeats across sessions or a fix passes a check.",
|
|
2196
2461
|
"panel.analyzed": "{sessions} sessions analyzed",
|
|
2197
|
-
"section.
|
|
2462
|
+
"section.review": "Needs your decision",
|
|
2198
2463
|
"section.found": "Found locally",
|
|
2199
2464
|
"history.show": "History ({count})",
|
|
2200
2465
|
"history.hide": "Hide history",
|
|
2201
|
-
"banner.noModel": "No
|
|
2202
|
-
"banner.reviewOff": "Background review is off. Open a finding to review it.",
|
|
2466
|
+
"banner.noModel": "No discovery model is available. Choose one in Skill Scout settings.",
|
|
2203
2467
|
"banner.discoveryOff": "Session analysis is off.",
|
|
2204
2468
|
"banner.secondary": "Another DSH window is analyzing sessions.",
|
|
2205
2469
|
"notice.dismissed": "Dismissed",
|
|
@@ -2213,11 +2477,14 @@ window.__ModuleLoader__.load({
|
|
|
2213
2477
|
"kind.complex": "Long verified task",
|
|
2214
2478
|
"meta.sessions.one": "{count} session",
|
|
2215
2479
|
"meta.sessions.other": "{count} sessions",
|
|
2216
|
-
"state.detected": "
|
|
2217
|
-
"state.
|
|
2218
|
-
"state.
|
|
2480
|
+
"state.detected": "No summary yet",
|
|
2481
|
+
"state.summarizing": "Summarizing",
|
|
2482
|
+
"state.proposed": "Summary ready",
|
|
2219
2483
|
"state.skipped": "Not worth saving",
|
|
2220
|
-
"state.
|
|
2484
|
+
"state.drafting": "Drafting",
|
|
2485
|
+
"state.ready": "Draft ready",
|
|
2486
|
+
"state.failed": "Summary failed",
|
|
2487
|
+
"state.draftFailed": "Draft failed",
|
|
2221
2488
|
"state.dismissed": "Dismissed",
|
|
2222
2489
|
"state.written": "Saved",
|
|
2223
2490
|
"time.now": "just now",
|
|
@@ -2225,6 +2492,7 @@ window.__ModuleLoader__.load({
|
|
|
2225
2492
|
"time.hours": "{count} h ago",
|
|
2226
2493
|
"time.days": "{count} d ago",
|
|
2227
2494
|
"detail.close": "Close",
|
|
2495
|
+
"detail.tab.summary": "Summary",
|
|
2228
2496
|
"detail.tab.evidence": "Evidence",
|
|
2229
2497
|
"detail.tab.skill": "Skill",
|
|
2230
2498
|
"detail.tab.changes": "Changes",
|
|
@@ -2232,15 +2500,32 @@ window.__ModuleLoader__.load({
|
|
|
2232
2500
|
"detail.why": "Why",
|
|
2233
2501
|
"detail.loading": "Loading the evidence",
|
|
2234
2502
|
"detail.error": "Could not load this suggestion.",
|
|
2235
|
-
"detail.
|
|
2236
|
-
"detail.
|
|
2237
|
-
"detail.
|
|
2238
|
-
"detail.
|
|
2239
|
-
"detail.
|
|
2240
|
-
"detail.
|
|
2241
|
-
"detail.
|
|
2242
|
-
"detail.
|
|
2243
|
-
"detail.
|
|
2503
|
+
"detail.summarizedBy": "Summary by {model}",
|
|
2504
|
+
"detail.draftedBy": "Draft by {model}",
|
|
2505
|
+
"detail.local": "Local rules found this in tool results. No model has read it yet.",
|
|
2506
|
+
"detail.steps": "Steps the rules matched",
|
|
2507
|
+
"detail.summaryNote": "A summary sends redacted evidence from {count} tasks to {model}: requests, messages during the task, commands, exit codes, and one error line per failed command. It returns a few lines, not a Skill.",
|
|
2508
|
+
"detail.summarize": "Summarize",
|
|
2509
|
+
"detail.resummarize": "Summarize again",
|
|
2510
|
+
"detail.summarizing": "{model} is writing the summary",
|
|
2511
|
+
"detail.noSummaryModel": "No discovery model is available.",
|
|
2512
|
+
"detail.found": "Found",
|
|
2513
|
+
"detail.description": "Purpose",
|
|
2514
|
+
"detail.trigger": "When to use",
|
|
2515
|
+
"detail.plan": "Plan",
|
|
2516
|
+
"detail.risks": "Risks",
|
|
2517
|
+
"detail.verification": "Verify",
|
|
2518
|
+
"detail.plan.create": "Create",
|
|
2519
|
+
"detail.plan.improve": "Add to",
|
|
2520
|
+
"detail.consent": "Drafting sends the same evidence and this plan to {model}, which writes the Skill. You review and edit it before anything is saved.",
|
|
2521
|
+
"detail.noDraftModel": "No drafting model is available.",
|
|
2522
|
+
"detail.draft.create": "Draft Skill",
|
|
2523
|
+
"detail.draft.improve": "Draft addition",
|
|
2524
|
+
"detail.redraft": "Draft again",
|
|
2525
|
+
"detail.drafting": "{model} is drafting the Skill",
|
|
2526
|
+
"detail.skipped": "The summary found nothing worth saving.",
|
|
2527
|
+
"detail.failed.summary": "Summary failed: {kind}",
|
|
2528
|
+
"detail.failed.draft": "Drafting failed: {kind}",
|
|
2244
2529
|
"detail.openSession": "Open session",
|
|
2245
2530
|
"detail.cautions": "Check before saving: {list}",
|
|
2246
2531
|
"failure.timeout": "timed out",
|
|
@@ -2262,6 +2547,7 @@ window.__ModuleLoader__.load({
|
|
|
2262
2547
|
"evidence.reads.one": "{count} read not shown",
|
|
2263
2548
|
"evidence.reads.other": "{count} reads not shown",
|
|
2264
2549
|
"evidence.exit": "exit {code}",
|
|
2550
|
+
"evidence.steering": "During the task",
|
|
2265
2551
|
"evidence.followup": "Next message",
|
|
2266
2552
|
"evidence.list": "Operations in task {ref}",
|
|
2267
2553
|
"caution.sudo": "uses sudo",
|
|
@@ -2299,8 +2585,8 @@ window.__ModuleLoader__.load({
|
|
|
2299
2585
|
"written.missing": "DSH does not list the Skill yet. Check the file.",
|
|
2300
2586
|
"error.invalid": "This action does not apply to the suggestion in its current state.",
|
|
2301
2587
|
"error.missing": "The suggestion no longer exists.",
|
|
2302
|
-
"error.busy": "
|
|
2303
|
-
"error.no-model": "No
|
|
2588
|
+
"error.busy": "This suggestion is already with the model.",
|
|
2589
|
+
"error.no-model": "No model is available for this step.",
|
|
2304
2590
|
"error.exists": "A Skill file already exists at that path.",
|
|
2305
2591
|
"error.changed": "The file changed after the preview. Nothing was written.",
|
|
2306
2592
|
"error.outside": "The target is outside the project and user Skill folders.",
|
|
@@ -2322,16 +2608,19 @@ window.__ModuleLoader__.load({
|
|
|
2322
2608
|
"settings.save": "Save",
|
|
2323
2609
|
"settings.saving": "Saving",
|
|
2324
2610
|
"settings.section.discovery": "Discovery",
|
|
2325
|
-
"settings.section.
|
|
2611
|
+
"settings.section.summary": "Summaries",
|
|
2612
|
+
"settings.section.draft": "Drafting",
|
|
2326
2613
|
"settings.section.limits": "Limits",
|
|
2327
2614
|
"settings.section.privacy": "Privacy",
|
|
2328
2615
|
"settings.section.inbox": "Inbox",
|
|
2329
2616
|
"settings.discovery": "Analyze finished sessions",
|
|
2330
2617
|
"settings.discoveryHint": "Runs on this machine and reads only the session logs DSH already keeps.",
|
|
2331
|
-
"settings.
|
|
2332
|
-
"settings.
|
|
2333
|
-
"settings.
|
|
2334
|
-
"settings.
|
|
2618
|
+
"settings.summarize": "Summarize in the background",
|
|
2619
|
+
"settings.summarizeHint": "Sends redacted evidence of strong findings to the discovery model for a short summary. A Skill is drafted only after you approve its summary.",
|
|
2620
|
+
"settings.summaryModel": "Discovery model",
|
|
2621
|
+
"settings.summaryModelHint": "Writes the summaries; a small, fast model is enough. The default follows the Agent's default model.",
|
|
2622
|
+
"settings.draftModel": "Drafting model",
|
|
2623
|
+
"settings.draftModelHint": "Writes the Skill after you approve a summary. The default follows the Agent's default model.",
|
|
2335
2624
|
"settings.modelDefault": "Default ({model})",
|
|
2336
2625
|
"settings.modelDefaultUnknown": "Default model",
|
|
2337
2626
|
"settings.modelLoading": "Loading models",
|
|
@@ -2340,12 +2629,14 @@ window.__ModuleLoader__.load({
|
|
|
2340
2629
|
"settings.effort": "Reasoning effort",
|
|
2341
2630
|
"settings.effortHint": "Lower effort is cheaper and faster.",
|
|
2342
2631
|
"settings.effortDefault": "Model default",
|
|
2343
|
-
"settings.
|
|
2344
|
-
"settings.
|
|
2345
|
-
"settings.
|
|
2346
|
-
"settings.
|
|
2347
|
-
"settings.
|
|
2348
|
-
"settings.
|
|
2632
|
+
"settings.summaryTimeout": "Timeout",
|
|
2633
|
+
"settings.summaryTimeoutHint": "Seconds before a summary is abandoned.",
|
|
2634
|
+
"settings.draftTimeout": "Timeout",
|
|
2635
|
+
"settings.draftTimeoutHint": "Seconds before a draft is abandoned.",
|
|
2636
|
+
"settings.dailySummaries": "Summaries per day",
|
|
2637
|
+
"settings.dailySummariesHint": "Background summaries allowed each day. Your own requests do not count.",
|
|
2638
|
+
"settings.summaryInterval": "Summary interval",
|
|
2639
|
+
"settings.summaryIntervalHint": "Minutes between background summaries.",
|
|
2349
2640
|
"settings.quietPeriod": "Quiet period",
|
|
2350
2641
|
"settings.quietPeriodHint": "Minutes a session stays idle before it is analyzed.",
|
|
2351
2642
|
"settings.historyDays": "History",
|
|
@@ -2355,7 +2646,7 @@ window.__ModuleLoader__.load({
|
|
|
2355
2646
|
"settings.minOccurrences": "Repeats needed",
|
|
2356
2647
|
"settings.minOccurrencesHint": "Independent sessions before a repeated workflow counts.",
|
|
2357
2648
|
"settings.evidenceBudget": "Evidence budget",
|
|
2358
|
-
"settings.evidenceBudgetHint": "Characters of evidence sent with one
|
|
2649
|
+
"settings.evidenceBudgetHint": "Characters of evidence sent with one request.",
|
|
2359
2650
|
"settings.readOutput": "Include error lines",
|
|
2360
2651
|
"settings.readOutputHint": "Keep one redacted line from each failed command as evidence.",
|
|
2361
2652
|
"settings.redactPatterns": "Extra redaction",
|
|
@@ -2367,13 +2658,14 @@ window.__ModuleLoader__.load({
|
|
|
2367
2658
|
"settings.notify.quiet": "Icon only",
|
|
2368
2659
|
"settings.scope": "New Skills go to",
|
|
2369
2660
|
"settings.scopeHint": "Project: .agents/skills in the repository. User: ~/.agents/skills.",
|
|
2370
|
-
"settings.prompt": "
|
|
2371
|
-
"settings.promptHint": "Replaces the built-in guidance. The reply format is always added.",
|
|
2661
|
+
"settings.prompt": "Summary guidance",
|
|
2662
|
+
"settings.promptHint": "Replaces the built-in guidance for deciding what is worth saving. The reply format is always added.",
|
|
2372
2663
|
"settings.promptPlaceholder": "Built-in guidance",
|
|
2373
2664
|
"unit.seconds": "s",
|
|
2374
2665
|
"unit.minutes": "min",
|
|
2375
2666
|
"unit.days": "days",
|
|
2376
2667
|
"unit.sessions": "sessions",
|
|
2668
|
+
"unit.requests": "requests",
|
|
2377
2669
|
"unit.characters": "chars"
|
|
2378
2670
|
},
|
|
2379
2671
|
zh: {
|
|
@@ -2382,19 +2674,18 @@ window.__ModuleLoader__.load({
|
|
|
2382
2674
|
"entry.count.other": "Skill 建议,{count} 条新建议",
|
|
2383
2675
|
"panel.title": "Skill 建议",
|
|
2384
2676
|
"panel.analyzing": "正在分析会话",
|
|
2385
|
-
"panel.
|
|
2677
|
+
"panel.working": "正在请求模型",
|
|
2386
2678
|
"panel.loading": "正在加载",
|
|
2387
2679
|
"panel.error": "无法加载建议。",
|
|
2388
2680
|
"panel.retry": "重试",
|
|
2389
2681
|
"panel.empty.title": "暂无建议",
|
|
2390
2682
|
"panel.empty.body": "同一流程在多个会话里重复出现,或某次修复经检查命令验证后,这里会出现建议。",
|
|
2391
2683
|
"panel.analyzed": "已分析 {sessions} 个会话",
|
|
2392
|
-
"section.
|
|
2684
|
+
"section.review": "待你决定",
|
|
2393
2685
|
"section.found": "本地发现",
|
|
2394
2686
|
"history.show": "历史({count})",
|
|
2395
2687
|
"history.hide": "收起历史",
|
|
2396
|
-
"banner.noModel": "
|
|
2397
|
-
"banner.reviewOff": "后台复核已关闭,打开一条发现即可手动复核。",
|
|
2688
|
+
"banner.noModel": "没有可用的发现模型,请在经验提炼的设置里选择。",
|
|
2398
2689
|
"banner.discoveryOff": "会话分析已关闭。",
|
|
2399
2690
|
"banner.secondary": "另一个 DSH 窗口正在分析会话。",
|
|
2400
2691
|
"notice.dismissed": "已忽略",
|
|
@@ -2408,11 +2699,14 @@ window.__ModuleLoader__.load({
|
|
|
2408
2699
|
"kind.complex": "经验证的长任务",
|
|
2409
2700
|
"meta.sessions.one": "{count} 个会话",
|
|
2410
2701
|
"meta.sessions.other": "{count} 个会话",
|
|
2411
|
-
"state.detected": "
|
|
2412
|
-
"state.
|
|
2413
|
-
"state.
|
|
2702
|
+
"state.detected": "尚未摘要",
|
|
2703
|
+
"state.summarizing": "正在摘要",
|
|
2704
|
+
"state.proposed": "摘要待确认",
|
|
2414
2705
|
"state.skipped": "不值得保存",
|
|
2415
|
-
"state.
|
|
2706
|
+
"state.drafting": "正在生成",
|
|
2707
|
+
"state.ready": "草稿待保存",
|
|
2708
|
+
"state.failed": "摘要失败",
|
|
2709
|
+
"state.draftFailed": "生成失败",
|
|
2416
2710
|
"state.dismissed": "已忽略",
|
|
2417
2711
|
"state.written": "已保存",
|
|
2418
2712
|
"time.now": "刚刚",
|
|
@@ -2420,6 +2714,7 @@ window.__ModuleLoader__.load({
|
|
|
2420
2714
|
"time.hours": "{count} 小时前",
|
|
2421
2715
|
"time.days": "{count} 天前",
|
|
2422
2716
|
"detail.close": "关闭",
|
|
2717
|
+
"detail.tab.summary": "摘要",
|
|
2423
2718
|
"detail.tab.evidence": "证据",
|
|
2424
2719
|
"detail.tab.skill": "Skill",
|
|
2425
2720
|
"detail.tab.changes": "改动",
|
|
@@ -2427,15 +2722,32 @@ window.__ModuleLoader__.load({
|
|
|
2427
2722
|
"detail.why": "理由",
|
|
2428
2723
|
"detail.loading": "正在加载证据",
|
|
2429
2724
|
"detail.error": "无法加载这条建议。",
|
|
2430
|
-
"detail.
|
|
2431
|
-
"detail.
|
|
2432
|
-
"detail.
|
|
2433
|
-
"detail.
|
|
2434
|
-
"detail.
|
|
2435
|
-
"detail.
|
|
2436
|
-
"detail.
|
|
2437
|
-
"detail.
|
|
2438
|
-
"detail.
|
|
2725
|
+
"detail.summarizedBy": "摘要:{model}",
|
|
2726
|
+
"detail.draftedBy": "草稿:{model}",
|
|
2727
|
+
"detail.local": "由本地规则依据工具结果发现,还没有发给任何模型。",
|
|
2728
|
+
"detail.steps": "规则匹配到的步骤",
|
|
2729
|
+
"detail.summaryNote": "生成摘要会把 {count} 个任务的脱敏证据发给 {model}:用户请求、任务中的插话、命令、退出码,以及每条失败命令的一行错误输出。模型只返回几行摘要,不写 Skill。",
|
|
2730
|
+
"detail.summarize": "生成摘要",
|
|
2731
|
+
"detail.resummarize": "重新摘要",
|
|
2732
|
+
"detail.summarizing": "{model} 正在写摘要",
|
|
2733
|
+
"detail.noSummaryModel": "没有可用的发现模型。",
|
|
2734
|
+
"detail.found": "发现",
|
|
2735
|
+
"detail.description": "用途",
|
|
2736
|
+
"detail.trigger": "何时使用",
|
|
2737
|
+
"detail.plan": "将要做",
|
|
2738
|
+
"detail.risks": "风险",
|
|
2739
|
+
"detail.verification": "验证方式",
|
|
2740
|
+
"detail.plan.create": "新建",
|
|
2741
|
+
"detail.plan.improve": "追加到",
|
|
2742
|
+
"detail.consent": "生成草稿会把同样的证据和这份计划发给 {model},由它写出 Skill。保存之前你可以审阅和修改。",
|
|
2743
|
+
"detail.noDraftModel": "没有可用的生成模型。",
|
|
2744
|
+
"detail.draft.create": "生成 Skill 草稿",
|
|
2745
|
+
"detail.draft.improve": "生成追加内容",
|
|
2746
|
+
"detail.redraft": "重新生成",
|
|
2747
|
+
"detail.drafting": "{model} 正在生成 Skill",
|
|
2748
|
+
"detail.skipped": "摘要认为没有值得保存的内容。",
|
|
2749
|
+
"detail.failed.summary": "摘要失败:{kind}",
|
|
2750
|
+
"detail.failed.draft": "生成草稿失败:{kind}",
|
|
2439
2751
|
"detail.openSession": "打开会话",
|
|
2440
2752
|
"detail.cautions": "保存前请确认:{list}",
|
|
2441
2753
|
"failure.timeout": "超时",
|
|
@@ -2457,6 +2769,7 @@ window.__ModuleLoader__.load({
|
|
|
2457
2769
|
"evidence.reads.one": "另有 {count} 次读取未列出",
|
|
2458
2770
|
"evidence.reads.other": "另有 {count} 次读取未列出",
|
|
2459
2771
|
"evidence.exit": "退出码 {code}",
|
|
2772
|
+
"evidence.steering": "任务中插话",
|
|
2460
2773
|
"evidence.followup": "下一条消息",
|
|
2461
2774
|
"evidence.list": "任务 {ref} 的操作",
|
|
2462
2775
|
"caution.sudo": "使用 sudo",
|
|
@@ -2494,8 +2807,8 @@ window.__ModuleLoader__.load({
|
|
|
2494
2807
|
"written.missing": "DSH 还没有列出这个 Skill,请检查文件。",
|
|
2495
2808
|
"error.invalid": "这条建议当前的状态不支持这个操作。",
|
|
2496
2809
|
"error.missing": "这条建议已不存在。",
|
|
2497
|
-
"error.busy": "
|
|
2498
|
-
"error.no-model": "
|
|
2810
|
+
"error.busy": "这条建议正在等模型回复。",
|
|
2811
|
+
"error.no-model": "这一步没有可用的模型。",
|
|
2499
2812
|
"error.exists": "这个路径已经有 Skill 文件。",
|
|
2500
2813
|
"error.changed": "预览之后文件被改过,没有写入任何内容。",
|
|
2501
2814
|
"error.outside": "目标不在项目或用户的 Skill 目录里。",
|
|
@@ -2517,16 +2830,19 @@ window.__ModuleLoader__.load({
|
|
|
2517
2830
|
"settings.save": "保存",
|
|
2518
2831
|
"settings.saving": "正在保存",
|
|
2519
2832
|
"settings.section.discovery": "发现",
|
|
2520
|
-
"settings.section.
|
|
2833
|
+
"settings.section.summary": "摘要",
|
|
2834
|
+
"settings.section.draft": "生成 Skill",
|
|
2521
2835
|
"settings.section.limits": "限额",
|
|
2522
2836
|
"settings.section.privacy": "隐私",
|
|
2523
2837
|
"settings.section.inbox": "收件箱",
|
|
2524
2838
|
"settings.discovery": "分析已结束的会话",
|
|
2525
2839
|
"settings.discoveryHint": "在本机运行,只读取 DSH 已保存的会话日志。",
|
|
2526
|
-
"settings.
|
|
2527
|
-
"settings.
|
|
2528
|
-
"settings.
|
|
2529
|
-
"settings.
|
|
2840
|
+
"settings.summarize": "后台生成摘要",
|
|
2841
|
+
"settings.summarizeHint": "把较强发现的脱敏证据发给发现模型,只生成简短摘要。你同意摘要之后才会生成 Skill 草稿。",
|
|
2842
|
+
"settings.summaryModel": "发现模型",
|
|
2843
|
+
"settings.summaryModelHint": "写摘要用,小而快的模型就够。默认跟随 Agent 的默认模型。",
|
|
2844
|
+
"settings.draftModel": "生成模型",
|
|
2845
|
+
"settings.draftModelHint": "你同意摘要后写 Skill 用。默认跟随 Agent 的默认模型。",
|
|
2530
2846
|
"settings.modelDefault": "默认({model})",
|
|
2531
2847
|
"settings.modelDefaultUnknown": "默认模型",
|
|
2532
2848
|
"settings.modelLoading": "正在加载模型",
|
|
@@ -2535,12 +2851,14 @@ window.__ModuleLoader__.load({
|
|
|
2535
2851
|
"settings.effort": "推理强度",
|
|
2536
2852
|
"settings.effortHint": "强度越低,越便宜也越快。",
|
|
2537
2853
|
"settings.effortDefault": "模型默认",
|
|
2538
|
-
"settings.
|
|
2539
|
-
"settings.
|
|
2540
|
-
"settings.
|
|
2541
|
-
"settings.
|
|
2542
|
-
"settings.
|
|
2543
|
-
"settings.
|
|
2854
|
+
"settings.summaryTimeout": "超时",
|
|
2855
|
+
"settings.summaryTimeoutHint": "单次摘要等待的秒数。",
|
|
2856
|
+
"settings.draftTimeout": "超时",
|
|
2857
|
+
"settings.draftTimeoutHint": "单次生成等待的秒数。",
|
|
2858
|
+
"settings.dailySummaries": "每日摘要次数",
|
|
2859
|
+
"settings.dailySummariesHint": "每天允许的后台摘要次数,手动发起的不计入。",
|
|
2860
|
+
"settings.summaryInterval": "摘要间隔",
|
|
2861
|
+
"settings.summaryIntervalHint": "两次后台摘要之间的分钟数。",
|
|
2544
2862
|
"settings.quietPeriod": "静默期",
|
|
2545
2863
|
"settings.quietPeriodHint": "会话空闲多少分钟后开始分析。",
|
|
2546
2864
|
"settings.historyDays": "历史范围",
|
|
@@ -2550,7 +2868,7 @@ window.__ModuleLoader__.load({
|
|
|
2550
2868
|
"settings.minOccurrences": "重复次数",
|
|
2551
2869
|
"settings.minOccurrencesHint": "重复流程至少要出现在多少个独立会话里。",
|
|
2552
2870
|
"settings.evidenceBudget": "证据上限",
|
|
2553
|
-
"settings.evidenceBudgetHint": "
|
|
2871
|
+
"settings.evidenceBudgetHint": "单次请求发送的证据字符数。",
|
|
2554
2872
|
"settings.readOutput": "包含错误行",
|
|
2555
2873
|
"settings.readOutputHint": "每条失败命令保留一行脱敏后的输出作为证据。",
|
|
2556
2874
|
"settings.redactPatterns": "追加脱敏规则",
|
|
@@ -2562,13 +2880,14 @@ window.__ModuleLoader__.load({
|
|
|
2562
2880
|
"settings.notify.quiet": "只显示图标",
|
|
2563
2881
|
"settings.scope": "新 Skill 保存到",
|
|
2564
2882
|
"settings.scopeHint": "项目:仓库里的 .agents/skills。用户:~/.agents/skills。",
|
|
2565
|
-
"settings.prompt": "
|
|
2566
|
-
"settings.promptHint": "
|
|
2883
|
+
"settings.prompt": "摘要要求",
|
|
2884
|
+
"settings.promptHint": "替换内置的「是否值得保存」判断标准,回复格式的约定始终保留。",
|
|
2567
2885
|
"settings.promptPlaceholder": "内置的判断标准",
|
|
2568
2886
|
"unit.seconds": "秒",
|
|
2569
2887
|
"unit.minutes": "分钟",
|
|
2570
2888
|
"unit.days": "天",
|
|
2571
2889
|
"unit.sessions": "个",
|
|
2890
|
+
"unit.requests": "次",
|
|
2572
2891
|
"unit.characters": "字符"
|
|
2573
2892
|
}
|
|
2574
2893
|
};
|
|
@@ -2612,19 +2931,23 @@ window.__ModuleLoader__.load({
|
|
|
2612
2931
|
//#region src/client/settings.tsx
|
|
2613
2932
|
/**
|
|
2614
2933
|
* 插件页里经验提炼条目的配置页。改动先暂存,点保存才按读到的版本号写回 profile;
|
|
2615
|
-
*
|
|
2616
|
-
*
|
|
2934
|
+
* 写入被拒绝或传输失败时保留暂存值并提示。发现模型(写摘要)与生成模型(写 Skill 草稿)
|
|
2935
|
+
* 分别从 Host 的模型目录里选,留空时跟随 Agent 的默认模型。
|
|
2617
2936
|
*/
|
|
2618
2937
|
/** 与 Host `Config` 相同的默认值。 */
|
|
2619
2938
|
const DEFAULT_SETTINGS = {
|
|
2620
2939
|
discovery: true,
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2940
|
+
summarize: false,
|
|
2941
|
+
summaryProvider: "",
|
|
2942
|
+
summaryModel: "",
|
|
2943
|
+
summaryEffort: "",
|
|
2944
|
+
summaryTimeout: 60,
|
|
2945
|
+
draftProvider: "",
|
|
2946
|
+
draftModel: "",
|
|
2947
|
+
draftEffort: "",
|
|
2948
|
+
draftTimeout: 180,
|
|
2949
|
+
dailySummaries: 6,
|
|
2950
|
+
summaryInterval: 10,
|
|
2628
2951
|
quietPeriod: 2,
|
|
2629
2952
|
historyDays: 30,
|
|
2630
2953
|
maxSessions: 200,
|
|
@@ -2638,17 +2961,22 @@ window.__ModuleLoader__.load({
|
|
|
2638
2961
|
};
|
|
2639
2962
|
/** 数值字段的范围与单位,与 Host `Config` 一致。 */
|
|
2640
2963
|
const NUMBERS = {
|
|
2641
|
-
|
|
2964
|
+
summaryTimeout: {
|
|
2642
2965
|
min: 10,
|
|
2643
2966
|
max: 600,
|
|
2644
2967
|
unit: "unit.seconds"
|
|
2645
2968
|
},
|
|
2646
|
-
|
|
2969
|
+
draftTimeout: {
|
|
2970
|
+
min: 10,
|
|
2971
|
+
max: 900,
|
|
2972
|
+
unit: "unit.seconds"
|
|
2973
|
+
},
|
|
2974
|
+
dailySummaries: {
|
|
2647
2975
|
min: 1,
|
|
2648
2976
|
max: 100,
|
|
2649
|
-
unit: "unit.
|
|
2977
|
+
unit: "unit.requests"
|
|
2650
2978
|
},
|
|
2651
|
-
|
|
2979
|
+
summaryInterval: {
|
|
2652
2980
|
min: 1,
|
|
2653
2981
|
max: 1440,
|
|
2654
2982
|
unit: "unit.minutes"
|
|
@@ -2682,13 +3010,17 @@ window.__ModuleLoader__.load({
|
|
|
2682
3010
|
/** 设置服务快照值的结构;缺失或类型不符的字段取默认值。 */
|
|
2683
3011
|
const SettingsSchema = /* @__PURE__ */ object({
|
|
2684
3012
|
discovery: /* @__PURE__ */ fallback(/* @__PURE__ */ boolean(), DEFAULT_SETTINGS.discovery),
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
3013
|
+
summarize: /* @__PURE__ */ fallback(/* @__PURE__ */ boolean(), DEFAULT_SETTINGS.summarize),
|
|
3014
|
+
summaryProvider: /* @__PURE__ */ fallback(/* @__PURE__ */ string(), DEFAULT_SETTINGS.summaryProvider),
|
|
3015
|
+
summaryModel: /* @__PURE__ */ fallback(/* @__PURE__ */ string(), DEFAULT_SETTINGS.summaryModel),
|
|
3016
|
+
summaryEffort: /* @__PURE__ */ fallback(/* @__PURE__ */ string(), DEFAULT_SETTINGS.summaryEffort),
|
|
3017
|
+
summaryTimeout: /* @__PURE__ */ fallback(/* @__PURE__ */ number(), DEFAULT_SETTINGS.summaryTimeout),
|
|
3018
|
+
draftProvider: /* @__PURE__ */ fallback(/* @__PURE__ */ string(), DEFAULT_SETTINGS.draftProvider),
|
|
3019
|
+
draftModel: /* @__PURE__ */ fallback(/* @__PURE__ */ string(), DEFAULT_SETTINGS.draftModel),
|
|
3020
|
+
draftEffort: /* @__PURE__ */ fallback(/* @__PURE__ */ string(), DEFAULT_SETTINGS.draftEffort),
|
|
3021
|
+
draftTimeout: /* @__PURE__ */ fallback(/* @__PURE__ */ number(), DEFAULT_SETTINGS.draftTimeout),
|
|
3022
|
+
dailySummaries: /* @__PURE__ */ fallback(/* @__PURE__ */ number(), DEFAULT_SETTINGS.dailySummaries),
|
|
3023
|
+
summaryInterval: /* @__PURE__ */ fallback(/* @__PURE__ */ number(), DEFAULT_SETTINGS.summaryInterval),
|
|
2692
3024
|
quietPeriod: /* @__PURE__ */ fallback(/* @__PURE__ */ number(), DEFAULT_SETTINGS.quietPeriod),
|
|
2693
3025
|
historyDays: /* @__PURE__ */ fallback(/* @__PURE__ */ number(), DEFAULT_SETTINGS.historyDays),
|
|
2694
3026
|
maxSessions: /* @__PURE__ */ fallback(/* @__PURE__ */ number(), DEFAULT_SETTINGS.maxSessions),
|
|
@@ -2706,13 +3038,17 @@ window.__ModuleLoader__.load({
|
|
|
2706
3038
|
}
|
|
2707
3039
|
const SETTING_KEYS = [
|
|
2708
3040
|
"discovery",
|
|
2709
|
-
"
|
|
2710
|
-
"
|
|
2711
|
-
"
|
|
2712
|
-
"
|
|
2713
|
-
"
|
|
2714
|
-
"
|
|
2715
|
-
"
|
|
3041
|
+
"summarize",
|
|
3042
|
+
"summaryProvider",
|
|
3043
|
+
"summaryModel",
|
|
3044
|
+
"summaryEffort",
|
|
3045
|
+
"summaryTimeout",
|
|
3046
|
+
"draftProvider",
|
|
3047
|
+
"draftModel",
|
|
3048
|
+
"draftEffort",
|
|
3049
|
+
"draftTimeout",
|
|
3050
|
+
"dailySummaries",
|
|
3051
|
+
"summaryInterval",
|
|
2716
3052
|
"quietPeriod",
|
|
2717
3053
|
"historyDays",
|
|
2718
3054
|
"maxSessions",
|
|
@@ -2725,9 +3061,10 @@ window.__ModuleLoader__.load({
|
|
|
2725
3061
|
"prompt"
|
|
2726
3062
|
];
|
|
2727
3063
|
const NUMBER_KEYS = [
|
|
2728
|
-
"
|
|
2729
|
-
"
|
|
2730
|
-
"
|
|
3064
|
+
"summaryTimeout",
|
|
3065
|
+
"draftTimeout",
|
|
3066
|
+
"dailySummaries",
|
|
3067
|
+
"summaryInterval",
|
|
2731
3068
|
"quietPeriod",
|
|
2732
3069
|
"historyDays",
|
|
2733
3070
|
"maxSessions",
|
|
@@ -2785,8 +3122,27 @@ window.__ModuleLoader__.load({
|
|
|
2785
3122
|
function modelValue(provider, model) {
|
|
2786
3123
|
return provider === "" || model === "" ? "" : `${provider}${SEPARATOR}${model}`;
|
|
2787
3124
|
}
|
|
2788
|
-
|
|
3125
|
+
/** 每个阶段的 provider、模型与推理强度对应的设置字段。 */
|
|
3126
|
+
const MODEL_KEYS = {
|
|
3127
|
+
summary: {
|
|
3128
|
+
provider: "summaryProvider",
|
|
3129
|
+
model: "summaryModel",
|
|
3130
|
+
effort: "summaryEffort"
|
|
3131
|
+
},
|
|
3132
|
+
draft: {
|
|
3133
|
+
provider: "draftProvider",
|
|
3134
|
+
model: "draftModel",
|
|
3135
|
+
effort: "draftEffort"
|
|
3136
|
+
}
|
|
3137
|
+
};
|
|
3138
|
+
function ModelFields({ stage, staged: values, catalog, disabled, onChange, t }) {
|
|
2789
3139
|
const id = (0, react.useId)();
|
|
3140
|
+
const keys = MODEL_KEYS[stage];
|
|
3141
|
+
const staged = {
|
|
3142
|
+
provider: values[keys.provider],
|
|
3143
|
+
model: values[keys.model],
|
|
3144
|
+
effort: values[keys.effort]
|
|
3145
|
+
};
|
|
2790
3146
|
const groups = catalog.status === "ready" ? catalog.catalog.groups : [];
|
|
2791
3147
|
const current = modelValue(staged.provider, staged.model);
|
|
2792
3148
|
const fallback = catalog.status === "ready" ? catalog.catalog.default : null;
|
|
@@ -2797,8 +3153,8 @@ window.__ModuleLoader__.load({
|
|
|
2797
3153
|
const listed = groups.some((group) => group.models.some((model) => modelValue(group.id, model.id) === current));
|
|
2798
3154
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Field, {
|
|
2799
3155
|
id: `${id}-model`,
|
|
2800
|
-
label: t("settings.
|
|
2801
|
-
hint: t("settings.
|
|
3156
|
+
label: t(stage === "summary" ? "settings.summaryModel" : "settings.draftModel"),
|
|
3157
|
+
hint: t(stage === "summary" ? "settings.summaryModelHint" : "settings.draftModelHint"),
|
|
2802
3158
|
children: [
|
|
2803
3159
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2804
3160
|
id: `${id}-model`,
|
|
@@ -2808,9 +3164,9 @@ window.__ModuleLoader__.load({
|
|
|
2808
3164
|
onChange: (event) => {
|
|
2809
3165
|
const [provider = "", model = ""] = event.target.value.split(SEPARATOR);
|
|
2810
3166
|
onChange({
|
|
2811
|
-
provider,
|
|
2812
|
-
model,
|
|
2813
|
-
effort: ""
|
|
3167
|
+
[keys.provider]: provider,
|
|
3168
|
+
[keys.model]: model,
|
|
3169
|
+
[keys.effort]: ""
|
|
2814
3170
|
});
|
|
2815
3171
|
},
|
|
2816
3172
|
children: [
|
|
@@ -2850,7 +3206,7 @@ window.__ModuleLoader__.load({
|
|
|
2850
3206
|
className: settings_module_css_default.select,
|
|
2851
3207
|
value: staged.effort,
|
|
2852
3208
|
disabled,
|
|
2853
|
-
onChange: (event) => onChange({ effort: event.target.value }),
|
|
3209
|
+
onChange: (event) => onChange({ [keys.effort]: event.target.value }),
|
|
2854
3210
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2855
3211
|
value: "",
|
|
2856
3212
|
children: t("settings.effortDefault")
|
|
@@ -2991,17 +3347,18 @@ window.__ModuleLoader__.load({
|
|
|
2991
3347
|
children: [
|
|
2992
3348
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2993
3349
|
className: settings_module_css_default.title,
|
|
2994
|
-
children: translate("settings.section.
|
|
3350
|
+
children: translate("settings.section.summary")
|
|
2995
3351
|
}),
|
|
2996
|
-
toggle("
|
|
3352
|
+
toggle("summarize", "settings.summarize", "settings.summarizeHint"),
|
|
2997
3353
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelFields, {
|
|
3354
|
+
stage: "summary",
|
|
2998
3355
|
staged,
|
|
2999
3356
|
catalog: models,
|
|
3000
3357
|
disabled: !writable,
|
|
3001
3358
|
onChange: update,
|
|
3002
3359
|
t: translate
|
|
3003
3360
|
}),
|
|
3004
|
-
number("
|
|
3361
|
+
number("summaryTimeout"),
|
|
3005
3362
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
3006
3363
|
id: `${id}-prompt`,
|
|
3007
3364
|
label: translate("settings.prompt"),
|
|
@@ -3019,6 +3376,24 @@ window.__ModuleLoader__.load({
|
|
|
3019
3376
|
})
|
|
3020
3377
|
]
|
|
3021
3378
|
}),
|
|
3379
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
3380
|
+
className: settings_module_css_default.section,
|
|
3381
|
+
children: [
|
|
3382
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
3383
|
+
className: settings_module_css_default.title,
|
|
3384
|
+
children: translate("settings.section.draft")
|
|
3385
|
+
}),
|
|
3386
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelFields, {
|
|
3387
|
+
stage: "draft",
|
|
3388
|
+
staged,
|
|
3389
|
+
catalog: models,
|
|
3390
|
+
disabled: !writable,
|
|
3391
|
+
onChange: update,
|
|
3392
|
+
t: translate
|
|
3393
|
+
}),
|
|
3394
|
+
number("draftTimeout")
|
|
3395
|
+
]
|
|
3396
|
+
}),
|
|
3022
3397
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
3023
3398
|
className: settings_module_css_default.section,
|
|
3024
3399
|
children: [
|
|
@@ -3026,8 +3401,8 @@ window.__ModuleLoader__.load({
|
|
|
3026
3401
|
className: settings_module_css_default.title,
|
|
3027
3402
|
children: translate("settings.section.limits")
|
|
3028
3403
|
}),
|
|
3029
|
-
number("
|
|
3030
|
-
number("
|
|
3404
|
+
number("dailySummaries"),
|
|
3405
|
+
number("summaryInterval"),
|
|
3031
3406
|
number("evidenceBudget")
|
|
3032
3407
|
]
|
|
3033
3408
|
}),
|
|
@@ -3116,7 +3491,9 @@ window.__ModuleLoader__.load({
|
|
|
3116
3491
|
}
|
|
3117
3492
|
//#endregion
|
|
3118
3493
|
//#region src/client/store.ts
|
|
3119
|
-
/**
|
|
3494
|
+
/** 模型正在写摘要或草稿时的读取间隔:回复一到,界面在一秒内换掉进行中的占位。 */
|
|
3495
|
+
const MODEL_INTERVAL = 1e3;
|
|
3496
|
+
/** 分析会话或核对写入时的读取间隔。 */
|
|
3120
3497
|
const BUSY_INTERVAL = 3e3;
|
|
3121
3498
|
/** 空闲时的读取间隔。 */
|
|
3122
3499
|
const IDLE_INTERVAL = 45e3;
|
|
@@ -3128,9 +3505,15 @@ window.__ModuleLoader__.load({
|
|
|
3128
3505
|
error: null,
|
|
3129
3506
|
notice: null
|
|
3130
3507
|
};
|
|
3131
|
-
/**
|
|
3132
|
-
|
|
3133
|
-
|
|
3508
|
+
/**
|
|
3509
|
+
* 下一次读取的间隔:模型调用进行中最短;分析会话或写入后核对 DSH 能否发现时居中;其余时候最长。
|
|
3510
|
+
* @internal 导出供测试使用。
|
|
3511
|
+
*/
|
|
3512
|
+
function pollInterval(inbox) {
|
|
3513
|
+
if (inbox === null) return IDLE_INTERVAL;
|
|
3514
|
+
if (inbox.status.working > 0) return MODEL_INTERVAL;
|
|
3515
|
+
if (inbox.status.scanning || inbox.items.some((item) => item.write?.checking === true)) return BUSY_INTERVAL;
|
|
3516
|
+
return IDLE_INTERVAL;
|
|
3134
3517
|
}
|
|
3135
3518
|
/**
|
|
3136
3519
|
* 创建收件箱状态。
|
|
@@ -3152,7 +3535,7 @@ window.__ModuleLoader__.load({
|
|
|
3152
3535
|
timer = setTimeout(() => {
|
|
3153
3536
|
if (document.visibilityState === "hidden") schedule();
|
|
3154
3537
|
else refresh();
|
|
3155
|
-
},
|
|
3538
|
+
}, pollInterval(state.inbox));
|
|
3156
3539
|
};
|
|
3157
3540
|
async function refresh() {
|
|
3158
3541
|
const current = ++generation;
|