dsh-decision-layer 0.5.1 → 0.5.2
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.en.md +2 -2
- package/README.md +2 -2
- package/lib/client.js +60 -46
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
`dsh-decision-layer` adds structured, explicitly scoped decisions to the DeepSeek Harness (DSH) agent loop, backed by a pluggable adjudication backend. Dangerous-call gating, output self-check, tool narrowing, and loop prevention hook into the agent loop as automatic interventions.
|
|
6
6
|
|
|
7
|
-
> **0.5.
|
|
7
|
+
> **0.5.2 is a preview release.** The plugin works, but how much real value the adjudication interventions add is still being explored — every threshold is an unvalidated heuristic default. Treat it as something to observe, not a proven guarantee of impact. See [ROADMAP.md](<ROADMAP.md>) for scope and progress.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -49,4 +49,4 @@ Restart `dsh web` and refresh after installing or updating: the host and client
|
|
|
49
49
|
|
|
50
50
|
## Safety boundary and development
|
|
51
51
|
|
|
52
|
-
Automatic intervention only subtracts: the gate only denies, narrowing only removes tools, and neither grants new permissions. The gate defers to native DSH approval on backend failure rather than allowing; self-check, narrowing, and loop-guard errors skip intervention. The redacted summary sent to the backend carries only tool name and command/path with secret redaction — never file content. Node.js `>=20.11`; `npm test` and `npm run build:client` run local checks. Rebuild and commit `lib/client.js` with any client change. 0.5.
|
|
52
|
+
Automatic intervention only subtracts: the gate only denies, narrowing only removes tools, and neither grants new permissions. The gate defers to native DSH approval on backend failure rather than allowing; self-check, narrowing, and loop-guard errors skip intervention. The redacted summary sent to the backend carries only tool name and command/path with secret redaction — never file content. Node.js `>=20.11`; `npm test` and `npm run build:client` run local checks. Rebuild and commit `lib/client.js` with any client change. 0.5.2 is a preview: the interventions work, but their real value and thresholds are still being explored — feedback on misjudgments and feel observed in the decision log is welcome.
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
DeepSeek Harness(DSH)的结构化裁决插件。它把有明确判断标准的问题交给同协议的裁决后端,供 agent 在需要时使用,并在 agent loop 上接入危险门控、产出自检、工具收窄和防循环等自动介入。
|
|
6
6
|
|
|
7
|
-
> **0.5.
|
|
7
|
+
> **0.5.2 是体验版。** 插件功能已可用,但裁决介入能带来多少实际价值仍在探索中——各决策点的阈值都是未经验证的启发式默认值,建议先以观察心态体验,别当成经过验证的效果保证。功能与后续进度以 [ROADMAP.md](<ROADMAP.md>) 为准。
|
|
8
8
|
|
|
9
9
|
## 安装
|
|
10
10
|
|
|
@@ -53,4 +53,4 @@ dsh plugin --profile web add file:/绝对路径/dsh-decision-layer
|
|
|
53
53
|
|
|
54
54
|
## 开发
|
|
55
55
|
|
|
56
|
-
服务端使用 Node.js `>=20.11`(`.mjs`,无需构建);客户端用 TypeScript + esbuild 构建。`npm test` 跑本地测试,`npm run build:client` 生成 `lib/client.js`。改动客户端后需重建并连同 `lib/client.js` 一起提交,否则 GitHub 安装拿到的是旧 bundle。0.5.
|
|
56
|
+
服务端使用 Node.js `>=20.11`(`.mjs`,无需构建);客户端用 TypeScript + esbuild 构建。`npm test` 跑本地测试,`npm run build:client` 生成 `lib/client.js`。改动客户端后需重建并连同 `lib/client.js` 一起提交,否则 GitHub 安装拿到的是旧 bundle。0.5.2 为体验版:介入能力已可用,但实际价值与阈值仍在探索,欢迎反馈决策日志观察到的误判与体感。
|
package/lib/client.js
CHANGED
|
@@ -69,7 +69,7 @@ var dictionaries = {
|
|
|
69
69
|
checkPassRate: "\u901A\u8FC7\u7387",
|
|
70
70
|
narrowApplyRate: "\u6536\u7A84\u7387",
|
|
71
71
|
rateNa: "\u2014",
|
|
72
|
-
enabled: "\u542F\u7528\u81EA\u52A8\u4ECB\u5165",
|
|
72
|
+
enabled: "\u672C\u4F1A\u8BDD\u5185\u542F\u7528\u81EA\u52A8\u4ECB\u5165",
|
|
73
73
|
backendStatus: "\u540E\u7AEF\u8FDE\u63A5",
|
|
74
74
|
statusChecking: "\u68C0\u6D4B\u4E2D\u2026",
|
|
75
75
|
statusIdle: "\u672A\u68C0\u6D4B",
|
|
@@ -218,7 +218,7 @@ var dictionaries = {
|
|
|
218
218
|
checkPassRate: "Pass rate",
|
|
219
219
|
narrowApplyRate: "Narrow rate",
|
|
220
220
|
rateNa: "\u2014",
|
|
221
|
-
enabled: "Enable automatic interventions",
|
|
221
|
+
enabled: "Enable automatic interventions in this session",
|
|
222
222
|
backendStatus: "Backend",
|
|
223
223
|
statusChecking: "Checking\u2026",
|
|
224
224
|
statusIdle: "Not checked",
|
|
@@ -619,7 +619,6 @@ function SessionPanel({ sessionId, t }) {
|
|
|
619
619
|
const [busy, setBusy] = (0, import_react2.useState)(false);
|
|
620
620
|
const [metrics, setMetrics] = (0, import_react2.useState)(null);
|
|
621
621
|
const [log, setLog] = (0, import_react2.useState)([]);
|
|
622
|
-
const [analysis, setAnalysis] = (0, import_react2.useState)(null);
|
|
623
622
|
const [status, setStatus] = (0, import_react2.useState)("idle");
|
|
624
623
|
const [message, setMessage] = (0, import_react2.useState)("");
|
|
625
624
|
const { ratings, seed, annotate } = useAnnotations(sessionId, () => setMessage(t("annotateFailed")));
|
|
@@ -663,10 +662,7 @@ function SessionPanel({ sessionId, t }) {
|
|
|
663
662
|
}).catch(() => {
|
|
664
663
|
});
|
|
665
664
|
void request(`logs?sessionId=${encodeURIComponent(sessionId)}`).then((value) => {
|
|
666
|
-
if (alive)
|
|
667
|
-
setAnalysis(value);
|
|
668
|
-
seed(value);
|
|
669
|
-
}
|
|
665
|
+
if (alive) seed(value);
|
|
670
666
|
}).catch(() => {
|
|
671
667
|
});
|
|
672
668
|
return () => {
|
|
@@ -817,9 +813,16 @@ function SessionPanel({ sessionId, t }) {
|
|
|
817
813
|
metrics.check && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("article", { className: "decision-card", children: [
|
|
818
814
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("header", { className: "decision-card-head", children: [
|
|
819
815
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-card-title", children: t("cardCheck") }),
|
|
820
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-
|
|
821
|
-
|
|
822
|
-
|
|
816
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-head-metrics", children: [
|
|
817
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-rate-inline", children: [
|
|
818
|
+
t("checkPassRate"),
|
|
819
|
+
" ",
|
|
820
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: checkPassRate === null ? t("rateNa") : `${checkPassRate}%` })
|
|
821
|
+
] }),
|
|
822
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-total", children: [
|
|
823
|
+
metrics.check.attempts,
|
|
824
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { children: t("cardTimes") })
|
|
825
|
+
] })
|
|
823
826
|
] })
|
|
824
827
|
] }),
|
|
825
828
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "decision-card-stats", children: [
|
|
@@ -835,18 +838,21 @@ function SessionPanel({ sessionId, t }) {
|
|
|
835
838
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-stat-num decision-stat-muted", children: metrics.check.failures }),
|
|
836
839
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-stat-label", children: t("failures") })
|
|
837
840
|
] })
|
|
838
|
-
] })
|
|
839
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("footer", { className: "decision-card-foot decision-card-rate", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
|
|
840
|
-
t("checkPassRate"),
|
|
841
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: checkPassRate === null ? t("rateNa") : `${checkPassRate}%` })
|
|
842
|
-
] }) })
|
|
841
|
+
] })
|
|
843
842
|
] }),
|
|
844
843
|
metrics.narrow && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("article", { className: "decision-card", children: [
|
|
845
844
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("header", { className: "decision-card-head", children: [
|
|
846
845
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-card-title", children: t("cardNarrow") }),
|
|
847
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-
|
|
848
|
-
|
|
849
|
-
|
|
846
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-head-metrics", children: [
|
|
847
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-rate-inline", children: [
|
|
848
|
+
t("narrowApplyRate"),
|
|
849
|
+
" ",
|
|
850
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: narrowApplyRate === null ? t("rateNa") : `${narrowApplyRate}%` })
|
|
851
|
+
] }),
|
|
852
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-total", children: [
|
|
853
|
+
metrics.narrow.attempts,
|
|
854
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { children: t("cardTimes") })
|
|
855
|
+
] })
|
|
850
856
|
] })
|
|
851
857
|
] }),
|
|
852
858
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "decision-card-stats", children: [
|
|
@@ -862,18 +868,21 @@ function SessionPanel({ sessionId, t }) {
|
|
|
862
868
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-stat-num decision-stat-muted", children: metrics.narrow.failures }),
|
|
863
869
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-stat-label", children: t("failures") })
|
|
864
870
|
] })
|
|
865
|
-
] })
|
|
866
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("footer", { className: "decision-card-foot decision-card-rate", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
|
|
867
|
-
t("narrowApplyRate"),
|
|
868
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: narrowApplyRate === null ? t("rateNa") : `${narrowApplyRate}%` })
|
|
869
|
-
] }) })
|
|
871
|
+
] })
|
|
870
872
|
] }),
|
|
871
873
|
metrics.complete && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("article", { className: "decision-card", children: [
|
|
872
874
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("header", { className: "decision-card-head", children: [
|
|
873
875
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-card-title", children: t("cardComplete") }),
|
|
874
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-
|
|
875
|
-
|
|
876
|
-
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-head-metrics", children: [
|
|
877
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-rate-inline", children: [
|
|
878
|
+
t("failures"),
|
|
879
|
+
" ",
|
|
880
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: metrics.complete.failures })
|
|
881
|
+
] }),
|
|
882
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "decision-card-total", children: [
|
|
883
|
+
metrics.complete.attempts,
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { children: t("cardTimes") })
|
|
885
|
+
] })
|
|
877
886
|
] })
|
|
878
887
|
] }),
|
|
879
888
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "decision-card-stats", children: [
|
|
@@ -889,18 +898,13 @@ function SessionPanel({ sessionId, t }) {
|
|
|
889
898
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-stat-num decision-stat-muted", children: metrics.complete.insufficient }),
|
|
890
899
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "decision-stat-label", children: t("completeInsufficient") })
|
|
891
900
|
] })
|
|
892
|
-
] })
|
|
893
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("footer", { className: "decision-card-foot decision-card-rate", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
|
|
894
|
-
t("failures"),
|
|
895
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: metrics.complete.failures })
|
|
896
|
-
] }) })
|
|
901
|
+
] })
|
|
897
902
|
] })
|
|
898
903
|
] })
|
|
899
904
|
] }),
|
|
900
905
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { children: [
|
|
901
906
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: t("log") }),
|
|
902
|
-
log.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "decision-empty", role: "status", children: t("logEmpty") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DecisionLogList, { entries: log, ratings, onRate: (id, rating) => void annotate(id, rating), t })
|
|
903
|
-
analysis && analysis.annotations.rated > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "decision-muted decision-rate-summary", children: t("rateSummary", { rated: analysis.annotations.rated, good: analysis.annotations.good, bad: analysis.annotations.bad, unsure: analysis.annotations.unsure }) })
|
|
907
|
+
log.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "decision-empty", role: "status", children: t("logEmpty") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DecisionLogList, { entries: log, ratings, onRate: (id, rating) => void annotate(id, rating), t })
|
|
904
908
|
] }),
|
|
905
909
|
message && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", className: "decision-message decision-message-warn", children: message })
|
|
906
910
|
] })
|
|
@@ -913,12 +917,17 @@ function SessionPanel({ sessionId, t }) {
|
|
|
913
917
|
// src/client/analysis-view.tsx
|
|
914
918
|
var import_react3 = require("react");
|
|
915
919
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
916
|
-
function Stat({ label, value, tone }) {
|
|
920
|
+
function Stat({ label, value, pct, tone }) {
|
|
917
921
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "decision-stat", children: [
|
|
918
922
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `decision-stat-num${tone ? ` decision-stat-${tone}` : ""}`, children: value }),
|
|
923
|
+
typeof pct === "number" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "decision-stat-pct", children: [
|
|
924
|
+
pct,
|
|
925
|
+
"%"
|
|
926
|
+
] }),
|
|
919
927
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "decision-stat-label", children: label })
|
|
920
928
|
] });
|
|
921
929
|
}
|
|
930
|
+
var share = (n, total) => total > 0 ? Math.round(n / total * 100) : null;
|
|
922
931
|
function AnalysisView({ sessionId, t }) {
|
|
923
932
|
const [analysis, setAnalysis] = (0, import_react3.useState)(null);
|
|
924
933
|
const [log, setLog] = (0, import_react3.useState)([]);
|
|
@@ -950,6 +959,7 @@ function AnalysisView({ sessionId, t }) {
|
|
|
950
959
|
const backtest = analysis?.trendBacktest;
|
|
951
960
|
const annotations = analysis?.annotations;
|
|
952
961
|
const meanScore = profile && profile.check.scoreCount > 0 ? Math.round(profile.check.scoreSum / profile.check.scoreCount * 10) / 10 : null;
|
|
962
|
+
const completeTotal = profile ? profile.complete.satisfied + profile.complete.unsatisfied + profile.complete.insufficient : 0;
|
|
953
963
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "decision-analysis", role: "region", "aria-label": t("analysisTitle"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "decision-analysis-inner", children: [
|
|
954
964
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "decision-analysis-title", children: t("analysisTitle") }),
|
|
955
965
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "decision-muted decision-analysis-intro", children: t("analysisIntro") }),
|
|
@@ -966,10 +976,10 @@ function AnalysisView({ sessionId, t }) {
|
|
|
966
976
|
] })
|
|
967
977
|
] }),
|
|
968
978
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "decision-card-stats", children: [
|
|
969
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("deny"), value: profile.gate.deny, tone: "warn" }),
|
|
970
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("allow"), value: profile.gate.allow }),
|
|
971
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("ask"), value: profile.gate.ask }),
|
|
972
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("failures"), value: profile.gate.error, tone: "muted" })
|
|
979
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("deny"), value: profile.gate.deny, pct: share(profile.gate.deny, profile.gate.attempts), tone: "warn" }),
|
|
980
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("allow"), value: profile.gate.allow, pct: share(profile.gate.allow, profile.gate.attempts) }),
|
|
981
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("ask"), value: profile.gate.ask, pct: share(profile.gate.ask, profile.gate.attempts) }),
|
|
982
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("failures"), value: profile.gate.error, pct: share(profile.gate.error, profile.gate.attempts), tone: "muted" })
|
|
973
983
|
] })
|
|
974
984
|
] }),
|
|
975
985
|
profile.check.attempts > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: "decision-card", children: [
|
|
@@ -981,10 +991,10 @@ function AnalysisView({ sessionId, t }) {
|
|
|
981
991
|
] })
|
|
982
992
|
] }),
|
|
983
993
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "decision-card-stats", children: [
|
|
984
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("checkLow"), value: profile.check.low, tone: "warn" }),
|
|
985
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("checkOk"), value: profile.check.ok }),
|
|
994
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("checkLow"), value: profile.check.low, pct: share(profile.check.low, profile.check.attempts), tone: "warn" }),
|
|
995
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("checkOk"), value: profile.check.ok, pct: share(profile.check.ok, profile.check.attempts) }),
|
|
986
996
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("analysisMeanScore"), value: meanScore === null ? t("rateNa") : `${meanScore}/2` }),
|
|
987
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("failures"), value: profile.check.error, tone: "muted" })
|
|
997
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("failures"), value: profile.check.error, pct: share(profile.check.error, profile.check.attempts), tone: "muted" })
|
|
988
998
|
] })
|
|
989
999
|
] }),
|
|
990
1000
|
profile.narrow.attempts > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: "decision-card", children: [
|
|
@@ -996,9 +1006,9 @@ function AnalysisView({ sessionId, t }) {
|
|
|
996
1006
|
] })
|
|
997
1007
|
] }),
|
|
998
1008
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "decision-card-stats", children: [
|
|
999
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("narrowAppliedLabel"), value: profile.narrow.applied }),
|
|
1009
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("narrowAppliedLabel"), value: profile.narrow.applied, pct: share(profile.narrow.applied, profile.narrow.attempts) }),
|
|
1000
1010
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("narrowDroppedLabel"), value: profile.narrow.droppedSum }),
|
|
1001
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("failures"), value: profile.narrow.error, tone: "muted" })
|
|
1011
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("failures"), value: profile.narrow.error, pct: share(profile.narrow.error, profile.narrow.attempts), tone: "muted" })
|
|
1002
1012
|
] })
|
|
1003
1013
|
] }),
|
|
1004
1014
|
profile.complete.attempts > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: "decision-card", children: [
|
|
@@ -1010,9 +1020,9 @@ function AnalysisView({ sessionId, t }) {
|
|
|
1010
1020
|
] })
|
|
1011
1021
|
] }),
|
|
1012
1022
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "decision-card-stats", children: [
|
|
1013
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("completeSatisfied"), value: profile.complete.satisfied }),
|
|
1014
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("completeUnsatisfied"), value: profile.complete.unsatisfied, tone: "warn" }),
|
|
1015
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("completeInsufficient"), value: profile.complete.insufficient, tone: "muted" })
|
|
1023
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("completeSatisfied"), value: profile.complete.satisfied, pct: share(profile.complete.satisfied, completeTotal) }),
|
|
1024
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("completeUnsatisfied"), value: profile.complete.unsatisfied, pct: share(profile.complete.unsatisfied, completeTotal), tone: "warn" }),
|
|
1025
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: t("completeInsufficient"), value: profile.complete.insufficient, pct: share(profile.complete.insufficient, completeTotal), tone: "muted" })
|
|
1016
1026
|
] })
|
|
1017
1027
|
] })
|
|
1018
1028
|
] })
|
|
@@ -1538,6 +1548,9 @@ var css = `
|
|
|
1538
1548
|
.decision-card-title{font-size:.8rem;font-weight:600;color:var(--dsw-alias-label-secondary,#59636e);letter-spacing:.02em}
|
|
1539
1549
|
.decision-card-total{font-size:1.5rem;font-weight:700;line-height:1;color:var(--dsw-alias-label-primary,#202124);font-variant-numeric:tabular-nums}
|
|
1540
1550
|
.decision-card-total small{font-size:.7rem;font-weight:500;color:var(--dsw-alias-label-tertiary,#77818b);margin-left:.15rem}
|
|
1551
|
+
.decision-card-head-metrics{display:flex;align-items:baseline;gap:.6rem}
|
|
1552
|
+
.decision-card-rate-inline{font-size:.76rem;color:var(--dsw-alias-label-secondary,#59636e);white-space:nowrap}
|
|
1553
|
+
.decision-card-rate-inline b{color:var(--dsw-alias-label-primary,#202124);font-variant-numeric:tabular-nums;margin-left:.2rem;font-weight:600}
|
|
1541
1554
|
.decision-bar{display:flex;height:8px;border-radius:999px;overflow:hidden;background:var(--dsw-alias-bg-layer-1,#eef1f3)}
|
|
1542
1555
|
.decision-bar-empty{background:var(--dsw-alias-bg-layer-1,#eef1f3)}
|
|
1543
1556
|
.decision-bar-allow{background:#1f8a70}
|
|
@@ -1556,6 +1569,7 @@ var css = `
|
|
|
1556
1569
|
.decision-card-stats{display:flex;gap:.6rem}
|
|
1557
1570
|
.decision-stat{flex:1 1 0;display:flex;flex-direction:column;align-items:center;gap:.2rem;padding:.5rem .3rem;border-radius:10px;background:var(--dsw-alias-bg-layer-1,#f6f8fa)}
|
|
1558
1571
|
.decision-stat-num{font-size:1.35rem;font-weight:700;line-height:1;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary,#202124)}
|
|
1572
|
+
.decision-stat-pct{font-size:.74rem;font-weight:600;line-height:1;color:var(--dsw-alias-label-tertiary,#77818b);font-variant-numeric:tabular-nums}
|
|
1559
1573
|
.decision-stat-warn{color:#c98a1e}
|
|
1560
1574
|
.decision-stat-muted{color:var(--dsw-alias-label-tertiary,#9aa5b1)}
|
|
1561
1575
|
.decision-stat-label{font-size:.72rem;color:var(--dsw-alias-label-secondary,#59636e)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-decision-layer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "A structured decision layer for the DeepSeek Harness agent loop: a danger-call gate, output self-check, tool narrowing, and loop guard backed by a pluggable adjudication model.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|