dsh-decision-layer 0.7.3 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +8 -6
- package/README.md +8 -6
- package/docs/en/DETAIL.md +2 -1
- package/docs/zh/DETAIL.md +2 -1
- package/lib/client.js +371 -20
- package/lib/host/backend.d.ts +3 -2
- package/lib/host/backend.js +61 -43
- package/lib/host/checkpoint-review.d.ts +27 -0
- package/lib/host/checkpoint-review.js +334 -0
- package/lib/host/config-store.js +21 -1
- package/lib/host/danger-gate.js +8 -6
- package/lib/host/decision-context.js +20 -1
- package/lib/host/evaluation-trace.d.ts +8 -0
- package/lib/host/evaluation-trace.js +70 -0
- package/lib/host/execution-observer.d.ts +26 -0
- package/lib/host/execution-observer.js +168 -0
- package/lib/host/index.d.ts +1 -0
- package/lib/host/index.js +61 -16
- package/lib/host/log-analyze.d.ts +20 -1
- package/lib/host/log-analyze.js +66 -8
- package/lib/host/log-row.d.ts +3 -0
- package/lib/host/log-row.js +66 -0
- package/lib/host/manager-api.d.ts +1 -0
- package/lib/host/manager-api.js +5 -2
- package/lib/host/narrowing.js +11 -9
- package/lib/host/self-check.js +23 -6
- package/lib/host/session-state.d.ts +3 -1
- package/lib/host/session-state.js +30 -46
- package/lib/host/task-completion.js +6 -4
- package/lib/host/types.d.ts +43 -3
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -38,6 +38,7 @@ var zh = {
|
|
|
38
38
|
metrics: "\u81EA\u52A8\u88C1\u51B3\u7EDF\u8BA1",
|
|
39
39
|
triggerDecisions: "\u51B3\u7B56",
|
|
40
40
|
empty: "\u5C1A\u65E0\u81EA\u52A8\u88C1\u51B3\u3002\u624B\u52A8\u88C1\u51B3\u4E0D\u8BA1\u5165\u8FD9\u91CC\u3002",
|
|
41
|
+
checkpointDockHint: "\u53E6\u6709 {count} \u6B21\u53EA\u8BFB\u8FC7\u7A0B\u68C0\u67E5\uFF0C\u89C1\u300C\u51B3\u7B56\u5206\u6790\u300D\u9875\u3002",
|
|
41
42
|
attempts: "\u8BC4\u4F30\u6B21\u6570",
|
|
42
43
|
failures: "\u5931\u8D25\u56DE\u9000",
|
|
43
44
|
suggestions: "\u6A21\u578B\u5EFA\u8BAE\uFF08\u653E\u884C / \u8BE2\u95EE / \u62D2\u7EDD\uFF09",
|
|
@@ -62,7 +63,7 @@ var zh = {
|
|
|
62
63
|
narrowKeptCount: "\u4FDD\u7559",
|
|
63
64
|
narrowMore: " \u7B49 {count} \u4E2A",
|
|
64
65
|
narrowObserve: "\u4EC5\u89C2\u5BDF",
|
|
65
|
-
narrowEnforce: "\u5DF2\u751F\u6548",
|
|
66
|
+
narrowEnforce: "\u5DF2\u751F\u6548\uFF08\u4E0B\u4E00\u6B65\u8D77\uFF09",
|
|
66
67
|
narrowNotApplied: "\u672A\u751F\u6548",
|
|
67
68
|
checkPassRate: "\u901A\u8FC7\u7387",
|
|
68
69
|
narrowApplyRate: "\u6536\u7A84\u7387",
|
|
@@ -92,8 +93,8 @@ var zh = {
|
|
|
92
93
|
logPathLabel: "\u8DEF\u5F84\uFF1A",
|
|
93
94
|
logSubjectLabel: "\u8BF7\u6C42\uFF1A",
|
|
94
95
|
logScoreHint: "\u5F97\u5206\u4E3A\u5404\u6863\u4F4D\u6309\u6982\u7387\u52A0\u6743\u7684\u7ED3\u679C\uFF0C\u53EF\u80FD\u662F\u5C0F\u6570\uFF08\u5982 1.4\uFF09\uFF0C\u6EE1\u5206\u4E3A\u9876\u6863\u53F7 2\u3002",
|
|
95
|
-
logCheckHint: "\u6BCF\u56DE\u5408\u7ED3\u675F\u540E\uFF0C\u628A\u8FD9\u8F6E AI \u7684\u6700\u7EC8\u56DE\u590D\u8FDE\u540C\u672C\u8F6E\u8BF7\u6C42\u4E0E\u5FC5\u8981\u524D\u6587\uFF08\u6700\u8FD1\u4E00\u6761\u7528\u6237\u8981\u6C42\u4E0E AI \u56DE\u590D\uFF0C\u4F5C\u80CC\u666F\uFF0C\u5747\u5DF2\u906E\u853D\u51ED\u636E\uFF09\u4EA4\u7ED9\u88C1\u51B3\u6A21\u578B\uFF0C\u6309\u300C\u4E25\u91CD\u9057\u6F0F/\u81EA\u76F8\u77DB\u76FE \u2192 \u6709\u5C0F\u9057\u6F0F \u2192 \u5B8C\u6574\u51C6\u786E\u300D\u4E09\u6863\u6253\u4E00\u4E2A 0\u20132 \u7684\u8D28\u91CF\u5206\uFF0C\u7528\u6765\u53D1\u73B0\u9057\u6F0F\u6216\u77DB\u76FE\uFF1B\u81EA\u68C0\u884C\uFF08\u542B\u540E\u7AEF\u5931\u8D25\u884C\uFF09\u4F1A\u5E26\u672C\u56DE\u5408\u7684\u4EFB\u52A1\u8282\u9009\uFF08\u6700\u591A 512 \u5B57\uFF0C\u5DF2\u906E\u853D\u51ED\u636E\uFF09\u3002",
|
|
96
|
-
logNarrowHint: "\u6BCF\u56DE\u5408\u5F00\u59CB\u65F6\uFF0C\u4EE5\u53CA\u540C\u4E00\u56DE\u5408\u5185\u4F60\u63D0\u51FA\u65B0\u8981\u6C42\u65F6\uFF0C\u628A\u5F53\u524D\u8BF7\u6C42\u3001\u5FC5\u8981\u524D\u6587\u4E0E\u6700\u8FD1\u6267\u884C\u8FDB\u5C55\u8FDE\u540C\u53EF\u7528\u5DE5\u5177\u9010\u4E2A\u4EA4\u7ED9\u88C1\u51B3\u6A21\u578B\u5224\u65AD\u76F8\u5173\u6027\uFF08noul\uFF09\uFF0C\u6458\u6389\u660E\u663E\u7528\u4E0D\u4E0A\u7684\u5DE5\u5177\uFF0C\u53EA\u5728\u5F53\u524D\u5BBF\u4E3B\u5DF2\u5141\u8BB8\u7684\u96C6\u5408\u5185\u53D6\u4EA4\u96C6\u3001\u7EDD\u4E0D\u6269\u6743\uFF1B\u300C\u4EC5\u89C2\u5BDF\u300D\u53EA\u8BB0\u5F55\u5EFA\u8BAE\uFF0C\u300C\u5DF2\u751F\u6548\u300D\u624D\u771F\u6B63\
|
|
96
|
+
logCheckHint: "\u6BCF\u56DE\u5408\u7ED3\u675F\u540E\uFF0C\u628A\u8FD9\u8F6E AI \u7684\u6700\u7EC8\u56DE\u590D\u8FDE\u540C\u672C\u8F6E\u8BF7\u6C42\u4E0E\u5FC5\u8981\u524D\u6587\uFF08\u6700\u8FD1\u4E00\u6761\u7528\u6237\u8981\u6C42\u4E0E AI \u56DE\u590D\uFF0C\u4F5C\u80CC\u666F\uFF0C\u5747\u5DF2\u906E\u853D\u51ED\u636E\uFF09\u4EA4\u7ED9\u88C1\u51B3\u6A21\u578B\uFF0C\u6309\u300C\u4E25\u91CD\u9057\u6F0F/\u81EA\u76F8\u77DB\u76FE \u2192 \u6709\u5C0F\u9057\u6F0F \u2192 \u5B8C\u6574\u51C6\u786E\u300D\u4E09\u6863\u6253\u4E00\u4E2A 0\u20132 \u7684\u8D28\u91CF\u5206\uFF0C\u7528\u6765\u53D1\u73B0\u9057\u6F0F\u6216\u77DB\u76FE\uFF1B\u81EA\u68C0\u884C\uFF08\u542B\u540E\u7AEF\u5931\u8D25\u884C\uFF09\u4F1A\u5E26\u672C\u56DE\u5408\u7684\u4EFB\u52A1\u8282\u9009\uFF08\u6700\u591A 512 \u5B57\uFF0C\u5DF2\u906E\u853D\u51ED\u636E\uFF09\u3002\u4F4E\u5206\u884C\u5E26\u300C\u4F4E\u8BC4\u5206\u300D\u6807\u8BB0\uFF0C\u53EF\u5728\u51B3\u7B56\u5206\u6790\u9875\u53EA\u770B\u4F4E\u8BC4\u5206\u3002",
|
|
97
|
+
logNarrowHint: "\u6BCF\u56DE\u5408\u5F00\u59CB\u65F6\uFF0C\u4EE5\u53CA\u540C\u4E00\u56DE\u5408\u5185\u4F60\u63D0\u51FA\u65B0\u8981\u6C42\u65F6\uFF0C\u628A\u5F53\u524D\u8BF7\u6C42\u3001\u5FC5\u8981\u524D\u6587\u4E0E\u6700\u8FD1\u6267\u884C\u8FDB\u5C55\u8FDE\u540C\u53EF\u7528\u5DE5\u5177\u9010\u4E2A\u4EA4\u7ED9\u88C1\u51B3\u6A21\u578B\u5224\u65AD\u76F8\u5173\u6027\uFF08noul\uFF09\uFF0C\u6458\u6389\u660E\u663E\u7528\u4E0D\u4E0A\u7684\u5DE5\u5177\uFF0C\u53EA\u5728\u5F53\u524D\u5BBF\u4E3B\u5DF2\u5141\u8BB8\u7684\u96C6\u5408\u5185\u53D6\u4EA4\u96C6\u3001\u7EDD\u4E0D\u6269\u6743\uFF1B\u300C\u4EC5\u89C2\u5BDF\u300D\u53EA\u8BB0\u5F55\u5EFA\u8BAE\uFF0C\u300C\u5DF2\u751F\u6548\u300D\u624D\u771F\u6B63\u9650\u5236\u5DE5\u5177\uFF08\u5BBF\u4E3B\u5148\u89E3\u6790\u672C\u6B65\u5DE5\u5177\u96C6\uFF0C\u56E0\u6B64\u4ECE\u4E0B\u4E00\u6B65\u8D77\u751F\u6548\uFF09\u3002\u65F6\u95F4\u63D0\u793A\u3001\u540E\u53F0\u901A\u77E5\u7B49\u975E\u7528\u6237\u8981\u6C42\u4E0D\u4F1A\u89E6\u53D1\u91CD\u65B0\u5224\u65AD\u3002",
|
|
97
98
|
actionDeny: "\u5DF2\u62D2\u7EDD",
|
|
98
99
|
actionAsk: "\u8F6C\u4EA4\u5BA1\u6279",
|
|
99
100
|
actionPass: "\u672A\u5E72\u9884",
|
|
@@ -101,6 +102,10 @@ var zh = {
|
|
|
101
102
|
checkResultLow: "\u5F97\u5206\u504F\u4F4E",
|
|
102
103
|
checkResultOk: "\u901A\u8FC7",
|
|
103
104
|
checkResultLowNoisy: "\u5F97\u5206\u504F\u4F4E\uFF08\u4F4E\u7F6E\u4FE1\uFF09",
|
|
105
|
+
logLowBadge: "\u4F4E\u8BC4\u5206",
|
|
106
|
+
logLowOnly: "\u53EA\u770B\u4F4E\u8BC4\u5206",
|
|
107
|
+
logLowOnlyHint: "\u4EC5\u663E\u793A\u81EA\u68C0\u5F97\u5206\u504F\u4F4E\u7684\u8BB0\u5F55\uFF08\u542B\u4F4E\u7F6E\u4FE1\u566A\u58F0\uFF09\uFF0C\u7528\u4E8E\u5FEB\u901F\u5B9A\u4F4D\u662F\u54EA\u4E00\u56DE\u5408\u3002",
|
|
108
|
+
logLowEmpty: "\u672C\u4F1A\u8BDD\u6CA1\u6709\u4F4E\u8BC4\u5206\u8BB0\u5F55\u3002",
|
|
104
109
|
checkNoiseTag: "\u566A\u58F0\uFF0C\u53EF\u5FFD\u7565",
|
|
105
110
|
checkNoiseHint: "\u6A21\u578B\u5BF9\u8FD9\u6B21\u6253\u5206\u51E0\u4E4E\u6CA1\u6709\u628A\u63E1\uFF08\u7F6E\u4FE1\u5EA6\u6781\u4F4E\uFF09\uFF0C\u8FD9\u6761\u4F4E\u5206\u4E0D\u8BA1\u5165\u8D28\u91CF\u8D8B\u52BF\u3001\u4E5F\u4E0D\u89E6\u53D1\u4EFB\u4F55\u8865\u5B8C\uFF0C\u89C6\u4F5C\u566A\u58F0\u5FFD\u7565\u5373\u53EF\u3002\u771F\u6B63\u503C\u5F97\u5173\u6CE8\u7684\u662F\u8FDE\u7EED\u591A\u6B21\u9AD8\u7F6E\u4FE1\u7684\u4F4E\u5206\u3002",
|
|
106
111
|
reasonUnavailable: "\u540E\u7AEF\u4E0D\u53EF\u8FBE",
|
|
@@ -118,7 +123,7 @@ var zh = {
|
|
|
118
123
|
selfCheckHint: "\u6BCF\u56DE\u5408\u7ED3\u675F\u7ED9\u6700\u7EC8\u56DE\u590D\u6253\u5206\uFF080\u20132\uFF0C\u6309\u5404\u6863\u4F4D\u6982\u7387\u52A0\u6743\uFF0C\u53EF\u80FD\u662F\u5C0F\u6570\u5982 1.4\uFF09\u3002\u5173\u95ED\uFF1A\u53EA\u628A\u4F4E\u5206\u8BB0\u8FDB\u65E5\u5FD7\u548C\u7EDF\u8BA1\uFF0C\u4E0D\u6253\u65AD\u5BF9\u8BDD\u3002\u5F00\u542F\uFF1A\u5F97\u5206\u504F\u4F4E\uFF08\u22641\uFF09\u4E14\u6A21\u578B\u6709\u628A\u63E1\u65F6\uFF0C\u81EA\u52A8\u4EE5\u4F60\u7684\u540D\u4E49\u8FFD\u52A0\u4E00\u6761\u63D0\u793A\uFF0C\u8BA9 AI \u590D\u6838\u6709\u65E0\u9057\u6F0F\u6216\u77DB\u76FE\u5E76\u8865\u5B8C\uFF1B\u7F6E\u4FE1\u5EA6\u504F\u4F4E\u7684\u6253\u5206\u53EA\u8BB0\u5F55\u3001\u4E0D\u6253\u65AD\uFF0C\u540C\u4E00\u56DE\u5408\u6700\u591A\u8865\u4E00\u6B21\u3002",
|
|
119
124
|
narrow: "\u5DE5\u5177\u6536\u7A84",
|
|
120
125
|
narrowObserveLabel: "\u4EC5\u89C2\u5BDF\uFF08\u4E0D\u771F\u6B63\u9650\u5236\u5DE5\u5177\uFF09",
|
|
121
|
-
narrowHint: "\u6BCF\u56DE\u5408\u5F00\u59CB\u65F6\u3001\u4EE5\u53CA\u540C\u4E00\u56DE\u5408\u5185\u4F60\u63D0\u51FA\u65B0\u8981\u6C42\u65F6\uFF0C\u7528\u88C1\u51B3\u6A21\u578B\u5224\u65AD\u5F53\u524D\u53EF\u9009\u5DE5\u5177\u4E0E\u4EFB\u52A1\u7684\u76F8\u5173\u6027\uFF0C\u6458\u6389\u7528\u4E0D\u4E0A\u7684\uFF1B\u8BFB\u5199\u3001\u7F16\u8F91\u3001Shell\u3001\u68C0\u7D22\u3001\u5F85\u529E\u7B49\u6838\u5FC3\u5DE5\u5177\u59CB\u7EC8\u4FDD\u7559\u3001\u4E0D\u53C2\u4E0E\u5224\u5B9A\u3002\u9ED8\u8BA4\u771F\u6B63\u751F\u6548\uFF1A\
|
|
126
|
+
narrowHint: "\u6BCF\u56DE\u5408\u5F00\u59CB\u65F6\u3001\u4EE5\u53CA\u540C\u4E00\u56DE\u5408\u5185\u4F60\u63D0\u51FA\u65B0\u8981\u6C42\u65F6\uFF0C\u7528\u88C1\u51B3\u6A21\u578B\u5224\u65AD\u5F53\u524D\u53EF\u9009\u5DE5\u5177\u4E0E\u4EFB\u52A1\u7684\u76F8\u5173\u6027\uFF0C\u6458\u6389\u7528\u4E0D\u4E0A\u7684\uFF1B\u8BFB\u5199\u3001\u7F16\u8F91\u3001Shell\u3001\u68C0\u7D22\u3001\u5F85\u529E\u7B49\u6838\u5FC3\u5DE5\u5177\u59CB\u7EC8\u4FDD\u7559\u3001\u4E0D\u53C2\u4E0E\u5224\u5B9A\u3002\u9ED8\u8BA4\u771F\u6B63\u751F\u6548\uFF1A\u4ECE\u4E0B\u4E00\u6B65\u8D77\u53EA\u4FDD\u7559\u5224\u4E3A\u76F8\u5173\u7684\u5DE5\u5177\uFF0C\u4E14\u53EA\u5728\u5BBF\u4E3B\u5DF2\u5141\u8BB8\u7684\u8303\u56F4\u5185\u53D6\u4EA4\u96C6\u3001\u4E0D\u6269\u6743\uFF1B\u5BBF\u4E3B\u5728\u672C\u6B65\u51B3\u7B56\u70B9\u89E6\u53D1\u524D\u5DF2\u786E\u5B9A\u5DE5\u5177\u96C6\uFF0C\u56E0\u6B64\u672C\u6B65\u81EA\u8EAB\u7684\u8C03\u7528\u4ECD\u6309\u539F\u96C6\u5408\u653E\u884C\u3002\u6536\u7A84\u53EA\u4F5C\u7528\u4E8E\u5DE5\u5177\u901A\u9053\uFF1A\u56DE\u590D\u6B63\u6587\u91CC\u7684 UI \u56F4\u680F\u3001\u6280\u80FD\u8BF4\u660E\u7B49\u975E\u5DE5\u5177\u80FD\u529B\u4E0D\u53D7\u5F71\u54CD\u3002\u5F00\u542F\u300C\u4EC5\u89C2\u5BDF\u300D\u540E\u53EA\u628A\u53EF\u6458\u6389\u7684\u5DE5\u5177\u8BB0\u8FDB\u65E5\u5FD7\u548C\u7EDF\u8BA1\uFF0C\u4E0D\u6539\u52A8\u5DE5\u5177\u96C6\u3002\u4E09\u91CD\u4FDD\u62A4\uFF1A\u6838\u5FC3\u5DE5\u5177\u59CB\u7EC8\u4FDD\u7559\uFF1B\u53EF\u9009\u5DE5\u5177\u8D85\u8FC7 20 \u4E2A\u65F6\u81EA\u52A8\u53EA\u89C2\u5BDF\u4E0D\u9650\u5236\uFF1B\u4FDD\u7559\u4E0B\u6765\u4E0D\u8DB3 5 \u4E2A\u65F6\u89C6\u4E3A\u5224\u5B9A\u4E0D\u53EF\u4FE1\u3001\u8DF3\u8FC7\u3002",
|
|
122
127
|
narrowKeepLabel: "\u59CB\u7EC8\u4FDD\u7559\u7684\u5DE5\u5177\u524D\u7F00",
|
|
123
128
|
narrowKeepHint: "\u540D\u5B57\u4EE5\u8FD9\u4E9B\u524D\u7F00\u5F00\u5934\u7684\u5DE5\u5177\u6C38\u8FDC\u4FDD\u7559\u3001\u4E0D\u53C2\u4E0E\u76F8\u5173\u6027\u5224\u5B9A\uFF0C\u9002\u5408\u8BB0\u5FC6/\u68C0\u7D22\u8FD9\u7C7B\u300C\u5E38\u9A7B\u3001\u6309\u9700\u89E6\u53D1\u300D\u7684\u5DE5\u5177\uFF08\u9ED8\u8BA4\u53EA\u6709 mcp__openviking\uFF09\u3002\u7528\u82F1\u6587\u9017\u53F7\u6216\u6362\u884C\u5206\u9694\u591A\u4E2A\u524D\u7F00\uFF1B\u7559\u7A7A\u5219\u4E0D\u989D\u5916\u4FDD\u7559\u3002",
|
|
124
129
|
narrowMaxLabel: "\u5019\u9009\u5DE5\u5177\u4E0A\u9650",
|
|
@@ -181,6 +186,49 @@ var zh = {
|
|
|
181
186
|
completeUnsatisfied: "\u672A\u6EE1\u8DB3",
|
|
182
187
|
completeInsufficient: "\u8BC1\u636E\u4E0D\u8DB3",
|
|
183
188
|
completeSteered: "\u5DF2\u8865\u4E00\u8F6E",
|
|
189
|
+
checkpointSettings: "\u8FC7\u7A0B\u68C0\u67E5\uFF08\u53EA\u8BFB\uFF09",
|
|
190
|
+
checkpointEnabled: "\u542F\u7528\u53EA\u8BFB\u8FC7\u7A0B\u68C0\u67E5",
|
|
191
|
+
checkpointHint: "\u9ED8\u8BA4\u5173\u95ED\uFF0C\u5E76\u4ECD\u53D7\u4F1A\u8BDD\u603B\u5F00\u5173\u63A7\u5236\u3002\u663E\u5F0F\u5F00\u542F\u5E76\u4FDD\u5B58\u540E\uFF0C\u4F1A\u628A\u5F53\u524D\u8981\u6C42\u4E0E\u6709\u754C\u7684\u8131\u654F\u8FC7\u7A0B\u8BC1\u636E\uFF08\u5DE5\u5177\u540D\u3001\u6210\u8D25\u3001\u547D\u4EE4\u3001\u8DEF\u5F84\u548C Shell \u6458\u5F55\uFF09\u53D1\u9001\u5230\u5DF2\u914D\u7F6E\u7684\u88C1\u51B3\u7AEF\u70B9\uFF0C\u5728\u540E\u53F0\u505A\u53EA\u8BFB\u5224\u65AD\uFF1B\u4E0D\u81EA\u52A8\u8FFD\u52A0\u63D0\u793A\uFF0C\u4E5F\u4E0D\u6539\u53D8\u5DE5\u5177\u9650\u5236\u3002\u4E0D\u53D1\u9001\u8BFB\u6587\u4EF6\u3001\u641C\u7D22\u6216\u7F51\u9875\u7ED3\u679C\u539F\u6587\u3002",
|
|
192
|
+
checkpointHeartbeatLabel: "\u5FC3\u8DF3\u6B65\u6570",
|
|
193
|
+
checkpointHeartbeatHint: "\u7D2F\u8BA1\u591A\u5C11\u6B65\u540E\u5B89\u6392\u4E00\u6B21\u8FC7\u7A0B\u68C0\u67E5\uFF0C\u9ED8\u8BA4 6\uFF1B\u6574\u6570\uFF0C2\u2013100\u3002",
|
|
194
|
+
checkpointFailureLabel: "\u8FDE\u7EED\u5931\u8D25\u9608\u503C",
|
|
195
|
+
checkpointFailureHint: "\u672A\u89E3\u51B3\u5931\u8D25\u8FBE\u5230\u6B64\u6570\u91CF\u65F6\u5B89\u6392\u68C0\u67E5\uFF0C\u9ED8\u8BA4 3\uFF1B\u6574\u6570\uFF0C2\u201310\u3002",
|
|
196
|
+
checkpointTimeoutLabel: "\u8FC7\u7A0B\u68C0\u67E5\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09",
|
|
197
|
+
checkpointTimeoutHint: "\u5355\u6B21\u540E\u53F0\u68C0\u67E5\u7684\u622A\u6B62\u65F6\u95F4\uFF0C\u9ED8\u8BA4 1500\uFF1B\u6574\u6570\uFF0C100\u201310000\u3002\u8D85\u65F6\u4E0D\u5F71\u54CD\u6267\u884C\u3002",
|
|
198
|
+
logCheckpoint: "\u8FC7\u7A0B\u68C0\u67E5",
|
|
199
|
+
checkpointReadOnly: "\u53EA\u8BFB",
|
|
200
|
+
checkpointHeartbeat: "\u5FC3\u8DF3\u68C0\u67E5",
|
|
201
|
+
checkpointFailure: "\u672A\u89E3\u51B3\u5931\u8D25",
|
|
202
|
+
checkpointVerification: "\u4FEE\u6539\u540E\u9A8C\u8BC1",
|
|
203
|
+
checkpointTriggerUnknown: "\u68C0\u67E5\u89E6\u53D1",
|
|
204
|
+
checkpointOk: "\u89C2\u5BDF\u672A\u89C1\u7591\u70B9",
|
|
205
|
+
checkpointConcern: "\u89C2\u5BDF\u5230\u5F85\u590D\u6838\u4FE1\u53F7",
|
|
206
|
+
checkpointUncertain: "\u5224\u65AD\u4E0D\u786E\u5B9A",
|
|
207
|
+
checkpointSkipped: "\u5DF2\u8DF3\u8FC7",
|
|
208
|
+
checkpointThroughSeq: "\u8BC1\u636E\u622A\u81F3 #{seq}",
|
|
209
|
+
checkpointEvidenceCount: "\u5019\u9009\u8BC1\u636E {count} \u6761",
|
|
210
|
+
checkpointReasonUnknown: "\u672A\u4EA7\u751F\u53EF\u7528\u5224\u65AD",
|
|
211
|
+
checkpointReasonCanceled: "\u5DF2\u53D6\u6D88 / \u7ED3\u679C\u5DF2\u5931\u6548",
|
|
212
|
+
checkpointReasonDisabled: "\u8FC7\u7A0B\u68C0\u67E5\u5DF2\u5173\u95ED",
|
|
213
|
+
checkpointReasonNoTask: "\u65E0\u7ED1\u5B9A\u4EFB\u52A1",
|
|
214
|
+
checkpointReasonStale: "\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316",
|
|
215
|
+
checkpointReasonTimeout: "\u68C0\u67E5\u8D85\u65F6",
|
|
216
|
+
checkpointReasonBusy: "\u68C0\u67E5\u9884\u7B97\u6216\u961F\u5217\u5DF2\u6EE1",
|
|
217
|
+
checkpointReasonUnchanged: "\u6CA1\u6709\u65B0\u8BC1\u636E",
|
|
218
|
+
checkpointProfileNote: "\u53EA\u8BFB\u89C2\u5BDF\u4FE1\u53F7\uFF1B\u8DF3\u8FC7\u4E0D\u8BA1\u5165\u8BC4\u4F30\u6B21\u6570\uFF0C\u4E5F\u4E0D\u5F71\u54CD\u6700\u7EC8\u56DE\u590D\u8D28\u91CF\u8D8B\u52BF\u3002\u89C2\u5BDF\u672A\u89C1\u7591\u70B9\u4E0D\u4EE3\u8868\u4EFB\u52A1\u901A\u8FC7\u9A8C\u6536\u3002",
|
|
219
|
+
cardCheckpoint: "\u8FC7\u7A0B\u68C0\u67E5",
|
|
220
|
+
telemetryTitle: "\u51B3\u7B56\u6D4B\u91CF",
|
|
221
|
+
telemetryCoverage: "\u8017\u65F6\u6D4B\u91CF\u8986\u76D6",
|
|
222
|
+
telemetryUsageCoverage: "\u7528\u91CF\u6D4B\u91CF\u8986\u76D6",
|
|
223
|
+
telemetryMeanLatency: "\u5E73\u5747\u8017\u65F6",
|
|
224
|
+
telemetryP95Latency: "P95 \u8017\u65F6",
|
|
225
|
+
telemetryInputTokens: "\u8F93\u5165 token",
|
|
226
|
+
telemetryOutputTokens: "\u8F93\u51FA token",
|
|
227
|
+
telemetryBackendAttempts: "\u540E\u7AEF\u8BF7\u6C42\u6B21\u6570",
|
|
228
|
+
telemetryMeasuredCount: "\u5DF2\u6D4B {count} \u6B21",
|
|
229
|
+
telemetryUnknown: "\u672A\u77E5",
|
|
230
|
+
telemetryMs: "{value} ms",
|
|
231
|
+
telemetryNote: "\u8986\u76D6\u6309\u5DF2\u8BC4\u4F30\u7684\u51B3\u7B56\u884C\u8BA1\u7B97\uFF0C\u4E0D\u542B\u8FC7\u7A0B\u68C0\u67E5\u7684\u8DF3\u8FC7\uFF1B\u7528\u91CF\u4EC5\u6C47\u603B\u5DF2\u8BB0\u5F55\u6837\u672C\u3002\u7F3A\u5931\u4E0D\u7B49\u4E8E\u96F6\uFF0C\u8FD9\u4E9B\u6D4B\u91CF\u4E0D\u8BC1\u660E\u51C6\u786E\u7387\u6216\u6210\u672C\u6536\u76CA\u3002",
|
|
184
232
|
backend: "\u88C1\u51B3\u540E\u7AEF",
|
|
185
233
|
url: "\u670D\u52A1\u5730\u5740",
|
|
186
234
|
model: "\u6A21\u578B",
|
|
@@ -236,6 +284,7 @@ var en = {
|
|
|
236
284
|
metrics: "Automatic decisions",
|
|
237
285
|
triggerDecisions: "decisions",
|
|
238
286
|
empty: "No automatic decisions yet. Manual verdicts are not counted here.",
|
|
287
|
+
checkpointDockHint: "Also {count} read-only process checks; see the Decision analysis tab.",
|
|
239
288
|
attempts: "Evaluations",
|
|
240
289
|
failures: "Fallback failures",
|
|
241
290
|
suggestions: "Model suggestions (allow / ask / deny)",
|
|
@@ -260,7 +309,7 @@ var en = {
|
|
|
260
309
|
narrowKeptCount: "kept",
|
|
261
310
|
narrowMore: " and {count} in total",
|
|
262
311
|
narrowObserve: "observe",
|
|
263
|
-
narrowEnforce: "enforced",
|
|
312
|
+
narrowEnforce: "enforced (from next step)",
|
|
264
313
|
narrowNotApplied: "not applied",
|
|
265
314
|
checkPassRate: "Pass rate",
|
|
266
315
|
narrowApplyRate: "Narrow rate",
|
|
@@ -290,8 +339,8 @@ var en = {
|
|
|
290
339
|
logPathLabel: "path: ",
|
|
291
340
|
logSubjectLabel: "request: ",
|
|
292
341
|
logScoreHint: "The score is a probability-weighted mean across the levels, so it can be fractional (e.g. 1.4); the top score is the highest level number, 2.",
|
|
293
|
-
logCheckHint: "After each turn, the AI\u2019s final reply for that turn, together with the request and the necessary recent background (the last user ask and AI reply, credentials masked), is sent to the adjudication model, which grades its quality on three levels (severe omission/contradiction \u2192 minor gaps \u2192 complete and accurate) as a 0\u20132 score, to catch omissions or contradictions; every self-check row (including a failed one) carries this turn\u2019s task excerpt (up to 512 characters, credentials masked).",
|
|
294
|
-
logNarrowHint: "At the start of each turn, and again when a new user request arrives inside it, the current request, the necessary background and the latest execution progress are sent with each available tool to the adjudication model (a noul per tool) to judge relevance, dropping tools clearly not needed. It only intersects the host-allowed set and never expands it; observe merely logs the suggestion, enforced actually restricts the tools for
|
|
342
|
+
logCheckHint: "After each turn, the AI\u2019s final reply for that turn, together with the request and the necessary recent background (the last user ask and AI reply, credentials masked), is sent to the adjudication model, which grades its quality on three levels (severe omission/contradiction \u2192 minor gaps \u2192 complete and accurate) as a 0\u20132 score, to catch omissions or contradictions; every self-check row (including a failed one) carries this turn\u2019s task excerpt (up to 512 characters, credentials masked). Low rows carry a \u201Clow score\u201D badge and can be filtered in the decision analysis tab.",
|
|
343
|
+
logNarrowHint: "At the start of each turn, and again when a new user request arrives inside it, the current request, the necessary background and the latest execution progress are sent with each available tool to the adjudication model (a noul per tool) to judge relevance, dropping tools clearly not needed. It only intersects the host-allowed set and never expands it; observe merely logs the suggestion, enforced actually restricts the tools, starting from the next step because the host resolves the tool set for the current step before the hook runs.",
|
|
295
344
|
actionDeny: "denied",
|
|
296
345
|
actionAsk: "sent to approval",
|
|
297
346
|
actionPass: "no intervention",
|
|
@@ -299,6 +348,10 @@ var en = {
|
|
|
299
348
|
checkResultLow: "low score",
|
|
300
349
|
checkResultOk: "passed",
|
|
301
350
|
checkResultLowNoisy: "low score (low confidence)",
|
|
351
|
+
logLowBadge: "low score",
|
|
352
|
+
logLowOnly: "Low scores only",
|
|
353
|
+
logLowOnlyHint: "Show only low self-check scores (including low-confidence noise), to find which turn was scored low.",
|
|
354
|
+
logLowEmpty: "No low self-check scores in this session.",
|
|
302
355
|
checkNoiseTag: "noise, ignore",
|
|
303
356
|
checkNoiseHint: "The model had almost no confidence in this score (near-zero confidence). This low score does not count toward the quality trend and triggers no re-prompt \u2014 treat it as noise. What matters is several consecutive high-confidence low scores.",
|
|
304
357
|
reasonUnavailable: "backend unreachable",
|
|
@@ -316,7 +369,7 @@ var en = {
|
|
|
316
369
|
selfCheckHint: "Each turn ends by scoring the final reply (0\u20132, a probability-weighted mean across the levels, so it can be fractional like 1.4). Off: low scores are only logged, the conversation is not interrupted. On: when the score is low (\u22641) and the model is confident enough, one prompt is appended on your behalf asking the AI to review for gaps or contradictions and finish the work; low-confidence scores are only logged, never interrupt, and at most one prompt per turn.",
|
|
317
370
|
narrow: "Tool narrowing",
|
|
318
371
|
narrowObserveLabel: "Observe only (do not restrict tools)",
|
|
319
|
-
narrowHint: "At the start of each turn, and again when a new user request arrives inside it, the adjudication model judges how relevant each optional tool is to the task and drops the ones not needed; core tools (read, write, edit, shell, search, todos) are always kept and never judged. Enforced by default: only the relevant tools are kept
|
|
372
|
+
narrowHint: "At the start of each turn, and again when a new user request arrives inside it, the adjudication model judges how relevant each optional tool is to the task and drops the ones not needed; core tools (read, write, edit, shell, search, todos) are always kept and never judged. Enforced by default: from the next step on, only the relevant tools are kept, intersected with the host-allowed set and never expanded; the host fixes the tool set for the current step before the decision point fires, so that step still runs with the original set. Narrowing covers the tool channel only: UI fences in the reply body and skill instructions are unaffected. Turn on Observe only to just log the tools that could be dropped, without changing the tool set. Three safeguards: core tools always kept; more than 20 optional tools falls back to observe only; fewer than 5 tools remaining is treated as untrustworthy and skipped.",
|
|
320
373
|
narrowKeepLabel: "Always-kept tool prefixes",
|
|
321
374
|
narrowKeepHint: "Tools whose names start with any of these prefixes are always kept and never judged for relevance \u2014 good for resident, on-demand tools like memory/retrieval (defaults to mcp__openviking only). Separate prefixes with commas or newlines; leave empty to keep nothing extra.",
|
|
322
375
|
narrowMaxLabel: "Candidate tool cap",
|
|
@@ -379,6 +432,49 @@ var en = {
|
|
|
379
432
|
completeUnsatisfied: "unmet",
|
|
380
433
|
completeInsufficient: "insufficient",
|
|
381
434
|
completeSteered: "re-prompted",
|
|
435
|
+
checkpointSettings: "Process checks (read-only)",
|
|
436
|
+
checkpointEnabled: "Enable read-only process checks",
|
|
437
|
+
checkpointHint: "Off by default and still subject to the session switch. After you explicitly enable and save, the current request and bounded, redacted process evidence (tool names, outcomes, commands, paths and shell excerpts) are sent to the configured decision endpoint for a background, read-only judgement. No prompts are added and no tool restrictions change. File-read, search and webpage result bodies are not sent.",
|
|
438
|
+
checkpointHeartbeatLabel: "Heartbeat steps",
|
|
439
|
+
checkpointHeartbeatHint: "Schedule a process check after this many steps; default 6. Integer, 2\u2013100.",
|
|
440
|
+
checkpointFailureLabel: "Consecutive failure threshold",
|
|
441
|
+
checkpointFailureHint: "Schedule a check when unresolved failures reach this count; default 3. Integer, 2\u201310.",
|
|
442
|
+
checkpointTimeoutLabel: "Process check timeout (ms)",
|
|
443
|
+
checkpointTimeoutHint: "Deadline for one background check; default 1500. Integer, 100\u201310000. A timeout does not affect execution.",
|
|
444
|
+
logCheckpoint: "Process check",
|
|
445
|
+
checkpointReadOnly: "read-only",
|
|
446
|
+
checkpointHeartbeat: "heartbeat",
|
|
447
|
+
checkpointFailure: "unresolved failures",
|
|
448
|
+
checkpointVerification: "verification after change",
|
|
449
|
+
checkpointTriggerUnknown: "check trigger",
|
|
450
|
+
checkpointOk: "no concern observed",
|
|
451
|
+
checkpointConcern: "signal for review observed",
|
|
452
|
+
checkpointUncertain: "uncertain judgement",
|
|
453
|
+
checkpointSkipped: "skipped",
|
|
454
|
+
checkpointThroughSeq: "evidence through #{seq}",
|
|
455
|
+
checkpointEvidenceCount: "{count} candidate evidence items",
|
|
456
|
+
checkpointReasonUnknown: "no usable judgement",
|
|
457
|
+
checkpointReasonCanceled: "canceled / result discarded",
|
|
458
|
+
checkpointReasonDisabled: "process checks disabled",
|
|
459
|
+
checkpointReasonNoTask: "no bound task",
|
|
460
|
+
checkpointReasonStale: "context changed",
|
|
461
|
+
checkpointReasonTimeout: "check timed out",
|
|
462
|
+
checkpointReasonBusy: "check budget or queue full",
|
|
463
|
+
checkpointReasonUnchanged: "no new evidence",
|
|
464
|
+
checkpointProfileNote: "Read-only observation signals. Skips do not count as evaluations or affect final-reply quality trends. No concern observed does not mean the task passed acceptance.",
|
|
465
|
+
cardCheckpoint: "Process checks",
|
|
466
|
+
telemetryTitle: "Decision measurements",
|
|
467
|
+
telemetryCoverage: "Latency coverage",
|
|
468
|
+
telemetryUsageCoverage: "Usage coverage",
|
|
469
|
+
telemetryMeanLatency: "Mean latency",
|
|
470
|
+
telemetryP95Latency: "P95 latency",
|
|
471
|
+
telemetryInputTokens: "Input tokens",
|
|
472
|
+
telemetryOutputTokens: "Output tokens",
|
|
473
|
+
telemetryBackendAttempts: "Backend requests",
|
|
474
|
+
telemetryMeasuredCount: "{count} measured",
|
|
475
|
+
telemetryUnknown: "unknown",
|
|
476
|
+
telemetryMs: "{value} ms",
|
|
477
|
+
telemetryNote: "Coverage uses evaluated decision rows and excludes skipped process checks. Usage totals cover measured samples only. Missing is not zero; these measurements do not establish accuracy or cost benefits.",
|
|
382
478
|
backend: "Decision backend",
|
|
383
479
|
url: "Server URL",
|
|
384
480
|
model: "Model",
|
|
@@ -556,9 +652,10 @@ function renderCheck({ t }, entry) {
|
|
|
556
652
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { title: t("logCheckHint"), children: t("logCheck") }),
|
|
557
653
|
turnTag(t, entry)
|
|
558
654
|
] });
|
|
559
|
-
const
|
|
655
|
+
const subjectText = entry.subject ?? entry.task;
|
|
656
|
+
const subject = subjectText ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "decision-log-subject", title: `${t("logSubjectLabel")}${subjectText}`, children: [
|
|
560
657
|
"\u300C",
|
|
561
|
-
|
|
658
|
+
subjectText.length > 60 ? `${subjectText.slice(0, 60)}\u2026` : subjectText,
|
|
562
659
|
"\u300D"
|
|
563
660
|
] }) : null;
|
|
564
661
|
if (entry.outcome === "error") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
@@ -573,8 +670,10 @@ function renderCheck({ t }, entry) {
|
|
|
573
670
|
entry.reason ? ` \xB7 ${failDetail(t, entry)}` : ""
|
|
574
671
|
] })
|
|
575
672
|
] });
|
|
576
|
-
const
|
|
577
|
-
const
|
|
673
|
+
const low = entry.outcome === "low";
|
|
674
|
+
const noisy = low && entry.lowConfidence === true;
|
|
675
|
+
const badge = low ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `decision-log-badge ${noisy ? "decision-log-badge-noise" : "decision-log-badge-low"}`, children: t("logLowBadge") }) : null;
|
|
676
|
+
const result = low ? noisy ? t("checkResultLowNoisy") : t("checkResultLow") : t("checkResultOk");
|
|
578
677
|
const verdict = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: noisy ? "decision-log-muted-verdict" : "decision-log-verdict", children: result });
|
|
579
678
|
const score = entry.score !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "decision-log-detail", title: t("logScoreHint"), children: [
|
|
580
679
|
" \xB7 ",
|
|
@@ -600,6 +699,7 @@ function renderCheck({ t }, entry) {
|
|
|
600
699
|
subject
|
|
601
700
|
] }) : null,
|
|
602
701
|
" \xB7 ",
|
|
702
|
+
badge,
|
|
603
703
|
verdict,
|
|
604
704
|
score,
|
|
605
705
|
conf,
|
|
@@ -709,7 +809,86 @@ function renderComplete({ t }, entry) {
|
|
|
709
809
|
steer
|
|
710
810
|
] });
|
|
711
811
|
}
|
|
812
|
+
function checkpointReason(t, reason) {
|
|
813
|
+
switch (reason) {
|
|
814
|
+
case "disabled":
|
|
815
|
+
return t("checkpointReasonDisabled");
|
|
816
|
+
case "no-task":
|
|
817
|
+
return t("checkpointReasonNoTask");
|
|
818
|
+
case "stale":
|
|
819
|
+
case "superseded":
|
|
820
|
+
return t("checkpointReasonStale");
|
|
821
|
+
case "canceled":
|
|
822
|
+
case "aborted":
|
|
823
|
+
return t("checkpointReasonCanceled");
|
|
824
|
+
case "timeout":
|
|
825
|
+
return t("checkpointReasonTimeout");
|
|
826
|
+
case "queue-full":
|
|
827
|
+
case "budget":
|
|
828
|
+
return t("checkpointReasonBusy");
|
|
829
|
+
case "unchanged":
|
|
830
|
+
case "no-evidence":
|
|
831
|
+
return t("checkpointReasonUnchanged");
|
|
832
|
+
case "low-confidence":
|
|
833
|
+
return t("reasonLowConfidence");
|
|
834
|
+
case "unavailable":
|
|
835
|
+
case "unreachable":
|
|
836
|
+
return t("reasonUnavailable");
|
|
837
|
+
case "http-error":
|
|
838
|
+
return t("reasonHttpError");
|
|
839
|
+
case "invalid-response":
|
|
840
|
+
return t("reasonInvalidResponse");
|
|
841
|
+
case "config":
|
|
842
|
+
return t("reasonConfig");
|
|
843
|
+
default:
|
|
844
|
+
return t("checkpointReasonUnknown");
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
var checkpointOutcome = (entry) => entry.outcome === "concern" && entry.lowConfidence === true ? "uncertain" : entry.outcome;
|
|
848
|
+
function renderCheckpoint({ t }, entry) {
|
|
849
|
+
const outcome = checkpointOutcome(entry);
|
|
850
|
+
const discarded = outcome === "error" && (entry.reason === "canceled" || entry.reason === "aborted");
|
|
851
|
+
const result = discarded ? t("checkpointReasonCanceled") : outcome === "ok" ? t("checkpointOk") : outcome === "concern" ? t("checkpointConcern") : outcome === "error" ? t("logEvalFailed") : outcome === "skipped" ? t("checkpointSkipped") : t("checkpointUncertain");
|
|
852
|
+
const trigger = entry.trigger === "heartbeat" ? t("checkpointHeartbeat") : entry.trigger === "unresolved_failure" ? t("checkpointFailure") : entry.trigger === "verification_after_change" ? t("checkpointVerification") : t("checkpointTriggerUnknown");
|
|
853
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
854
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("logCheckpoint") }),
|
|
855
|
+
turnTag(t, entry),
|
|
856
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "decision-log-detail", children: [
|
|
857
|
+
" \xB7 ",
|
|
858
|
+
t("checkpointReadOnly"),
|
|
859
|
+
" \xB7 ",
|
|
860
|
+
trigger
|
|
861
|
+
] }),
|
|
862
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: outcome === "uncertain" || outcome === "skipped" || discarded ? "decision-log-muted-verdict" : "decision-log-verdict", children: [
|
|
863
|
+
" \xB7 ",
|
|
864
|
+
result
|
|
865
|
+
] }),
|
|
866
|
+
Number.isSafeInteger(entry.throughSeq) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "decision-log-detail", children: [
|
|
867
|
+
" \xB7 ",
|
|
868
|
+
t("checkpointThroughSeq", { seq: entry.throughSeq })
|
|
869
|
+
] }),
|
|
870
|
+
Number.isSafeInteger(entry.evidenceCount) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "decision-log-detail", children: [
|
|
871
|
+
" \xB7 ",
|
|
872
|
+
t("checkpointEvidenceCount", { count: entry.evidenceCount })
|
|
873
|
+
] }),
|
|
874
|
+
typeof entry.confidence === "number" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "decision-log-detail", children: [
|
|
875
|
+
" \xB7 ",
|
|
876
|
+
t("logConfidence"),
|
|
877
|
+
" ",
|
|
878
|
+
entry.confidence
|
|
879
|
+
] }),
|
|
880
|
+
entry.reason && !discarded && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "decision-log-detail", children: [
|
|
881
|
+
" \xB7 ",
|
|
882
|
+
checkpointReason(t, entry.reason)
|
|
883
|
+
] })
|
|
884
|
+
] });
|
|
885
|
+
}
|
|
712
886
|
function outcomeTagOf(entry) {
|
|
887
|
+
if (entry.kind === "checkpoint") {
|
|
888
|
+
const outcome = checkpointOutcome(entry);
|
|
889
|
+
const discarded = outcome === "error" && (entry.reason === "canceled" || entry.reason === "aborted");
|
|
890
|
+
return discarded ? "muted" : outcome === "concern" ? "warn" : outcome === "error" ? "error" : outcome === "ok" ? "ok" : "muted";
|
|
891
|
+
}
|
|
713
892
|
if (entry.kind === "narrow") return entry.outcome === "error" ? "error" : "ok";
|
|
714
893
|
if (entry.kind === "complete") return entry.outcome === "error" ? "error" : entry.outcome === "unsatisfied" ? "warn" : "ok";
|
|
715
894
|
if (entry.outcome === "deny") return "deny";
|
|
@@ -718,7 +897,7 @@ function outcomeTagOf(entry) {
|
|
|
718
897
|
return "ok";
|
|
719
898
|
}
|
|
720
899
|
function renderBody(props, entry) {
|
|
721
|
-
return entry.kind === "gate" ? renderGate(props, entry) : entry.kind === "narrow" ? renderNarrow(props, entry) : entry.kind === "complete" ? renderComplete(props, entry) : renderCheck(props, entry);
|
|
900
|
+
return entry.kind === "gate" ? renderGate(props, entry) : entry.kind === "narrow" ? renderNarrow(props, entry) : entry.kind === "complete" ? renderComplete(props, entry) : entry.kind === "checkpoint" ? renderCheckpoint(props, entry) : renderCheck(props, entry);
|
|
722
901
|
}
|
|
723
902
|
function RatingButtons({ id, t, ratings, onRate }) {
|
|
724
903
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "decision-rate", role: "group", "aria-label": t("rateGroup"), children: [
|
|
@@ -739,7 +918,7 @@ function RatingButtons({ id, t, ratings, onRate }) {
|
|
|
739
918
|
}
|
|
740
919
|
function DecisionLogList({ entries, ratings, onRate, t, newestFirst = true }) {
|
|
741
920
|
const rows = newestFirst ? entries.slice().reverse() : entries.slice();
|
|
742
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "decision-log", children: rows.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: `decision-log-item decision-log-${outcomeTagOf(entry)}`, children: [
|
|
921
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "decision-log", children: rows.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: `decision-log-item decision-log-${outcomeTagOf(entry)}${entry.kind === "check" && entry.outcome === "low" ? " decision-log-low" : ""}`, children: [
|
|
743
922
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "decision-log-time", children: time(entry.at) }),
|
|
744
923
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "decision-log-body", children: [
|
|
745
924
|
renderBody({ t }, entry),
|
|
@@ -1002,7 +1181,10 @@ function SessionPanel({ sessionId, t, useProjection }) {
|
|
|
1002
1181
|
] }),
|
|
1003
1182
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { children: [
|
|
1004
1183
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: t("metrics") }),
|
|
1005
|
-
!metrics?.gate && !metrics?.check && !metrics?.narrow && !metrics?.complete ? /* @__PURE__ */ (0, import_jsx_runtime3.
|
|
1184
|
+
!metrics?.gate && !metrics?.check && !metrics?.narrow && !metrics?.complete ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1185
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "decision-empty", role: "status", children: t("empty") }),
|
|
1186
|
+
metrics?.checkpoint && metrics.checkpoint.attempts + metrics.checkpoint.skipped > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "decision-muted", children: t("checkpointDockHint", { count: metrics.checkpoint.attempts + metrics.checkpoint.skipped }) })
|
|
1187
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "decision-cards", children: [
|
|
1006
1188
|
metrics.gate && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: "decision-card decision-card-wide", children: [
|
|
1007
1189
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "decision-card-head", children: [
|
|
1008
1190
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "decision-card-title", children: t("cardGate") }),
|
|
@@ -1114,6 +1296,7 @@ function AnalysisView({ sessionId, t }) {
|
|
|
1114
1296
|
const [analysis, setAnalysis] = (0, import_react3.useState)(null);
|
|
1115
1297
|
const [rows, setRows] = (0, import_react3.useState)(null);
|
|
1116
1298
|
const [logPage, setLogPage] = (0, import_react3.useState)(1);
|
|
1299
|
+
const [lowOnly, setLowOnly] = (0, import_react3.useState)(false);
|
|
1117
1300
|
const [loaded, setLoaded] = (0, import_react3.useState)(false);
|
|
1118
1301
|
const [message, setMessage] = (0, import_react3.useState)("");
|
|
1119
1302
|
const [enabled, setEnabled] = (0, import_react3.useState)(null);
|
|
@@ -1135,6 +1318,7 @@ function AnalysisView({ sessionId, t }) {
|
|
|
1135
1318
|
active.current = sessionId;
|
|
1136
1319
|
setBusy(false);
|
|
1137
1320
|
setMessage("");
|
|
1321
|
+
setLowOnly(false);
|
|
1138
1322
|
loadSession();
|
|
1139
1323
|
}, [sessionId]);
|
|
1140
1324
|
(0, import_react3.useEffect)(() => onSessionEnabled((change) => {
|
|
@@ -1187,17 +1371,23 @@ function AnalysisView({ sessionId, t }) {
|
|
|
1187
1371
|
};
|
|
1188
1372
|
(0, import_react3.useEffect)(() => {
|
|
1189
1373
|
let alive = true;
|
|
1190
|
-
void request(`logrows?sessionId=${encodeURIComponent(sessionId)}&page=${logPage}&pageSize=${LOG_PAGE_SIZE}`).then((value) => {
|
|
1374
|
+
void request(`logrows?sessionId=${encodeURIComponent(sessionId)}&page=${logPage}&pageSize=${LOG_PAGE_SIZE}${lowOnly ? "&lowOnly=1" : ""}`).then((value) => {
|
|
1191
1375
|
if (alive) setRows(value);
|
|
1192
1376
|
}).catch(() => {
|
|
1193
1377
|
});
|
|
1194
1378
|
return () => {
|
|
1195
1379
|
alive = false;
|
|
1196
1380
|
};
|
|
1197
|
-
}, [sessionId, logPage]);
|
|
1381
|
+
}, [sessionId, logPage, lowOnly]);
|
|
1198
1382
|
const profile = analysis?.profile;
|
|
1199
1383
|
const backtest = analysis?.trendBacktest;
|
|
1200
1384
|
const annotations = analysis?.annotations;
|
|
1385
|
+
const checkpoint = profile?.checkpoint;
|
|
1386
|
+
const telemetry = profile?.telemetry;
|
|
1387
|
+
const measuredTotal = profile ? profile.gate.attempts + profile.check.attempts + profile.narrow.attempts + profile.complete.attempts + (checkpoint?.attempts ?? 0) : 0;
|
|
1388
|
+
const latency = (value) => typeof value === "number" && Number.isFinite(value) ? t("telemetryMs", { value: Math.round(value * 10) / 10 }) : t("telemetryUnknown");
|
|
1389
|
+
const transport = telemetry && typeof telemetry.transportMeasured === "number" && telemetry.transportMeasured > 0 ? `${telemetry.backendAttempts} \xB7 ${t("telemetryMeasuredCount", { count: telemetry.transportMeasured })}` : t("telemetryUnknown");
|
|
1390
|
+
const lowCount = profile?.check.low ?? 0;
|
|
1201
1391
|
const meanScore = profile && profile.check.scoreCount > 0 ? Math.round(profile.check.scoreSum / profile.check.scoreCount * 10) / 10 : null;
|
|
1202
1392
|
const completeTotal = profile ? profile.complete.satisfied + profile.complete.unsatisfied + profile.complete.insufficient : 0;
|
|
1203
1393
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "decision-analysis", role: "region", "aria-label": t("analysisTitle"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "decision-analysis-inner", children: [
|
|
@@ -1261,6 +1451,30 @@ function AnalysisView({ sessionId, t }) {
|
|
|
1261
1451
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("completeUnsatisfied"), value: profile.complete.unsatisfied, pct: share(profile.complete.unsatisfied, completeTotal), tone: "warn" }),
|
|
1262
1452
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("completeInsufficient"), value: profile.complete.insufficient, pct: share(profile.complete.insufficient, completeTotal), tone: "muted" })
|
|
1263
1453
|
] })
|
|
1454
|
+
] }),
|
|
1455
|
+
checkpoint && checkpoint.attempts + checkpoint.skipped > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("article", { className: "decision-card", children: [
|
|
1456
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CardHead, { title: t("cardCheckpoint"), total: checkpoint.attempts, unit: t("cardTimes") }),
|
|
1457
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "decision-card-stats", children: [
|
|
1458
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("checkpointOk"), value: Math.max(0, checkpoint.attempts - checkpoint.concern - checkpoint.uncertain - checkpoint.error) }),
|
|
1459
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("checkpointConcern"), value: checkpoint.concern, tone: "warn" }),
|
|
1460
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("checkpointUncertain"), value: checkpoint.uncertain, tone: "muted" }),
|
|
1461
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("logEvalFailed"), value: checkpoint.error, tone: "muted" }),
|
|
1462
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("checkpointSkipped"), value: checkpoint.skipped, tone: "muted" })
|
|
1463
|
+
] }),
|
|
1464
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "decision-muted decision-analysis-note", children: t("checkpointProfileNote") })
|
|
1465
|
+
] }),
|
|
1466
|
+
telemetry && telemetry.measured + telemetry.usageMeasured + (telemetry.transportMeasured ?? 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("article", { className: "decision-card", children: [
|
|
1467
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CardHead, { title: t("telemetryTitle"), total: telemetry.measured, unit: t("cardTimes") }),
|
|
1468
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "decision-card-stats", children: [
|
|
1469
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("telemetryCoverage"), value: measuredTotal > 0 ? `${telemetry.measured}/${measuredTotal}` : t("telemetryUnknown") }),
|
|
1470
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("telemetryUsageCoverage"), value: measuredTotal > 0 ? `${telemetry.usageMeasured}/${measuredTotal}` : t("telemetryUnknown") }),
|
|
1471
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("telemetryMeanLatency"), value: latency(telemetry.measured > 0 ? telemetry.latencyMsSum / telemetry.measured : null) }),
|
|
1472
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("telemetryP95Latency"), value: latency(telemetry.measured > 0 ? telemetry.latencyMsP95 : null) }),
|
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("telemetryInputTokens"), value: telemetry.usageMeasured > 0 ? telemetry.inputTokens : t("telemetryUnknown") }),
|
|
1474
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("telemetryOutputTokens"), value: telemetry.usageMeasured > 0 ? telemetry.outputTokens : t("telemetryUnknown") }),
|
|
1475
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stat, { label: t("telemetryBackendAttempts"), value: transport })
|
|
1476
|
+
] }),
|
|
1477
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "decision-muted decision-analysis-note", children: t("telemetryNote") })
|
|
1264
1478
|
] })
|
|
1265
1479
|
] })
|
|
1266
1480
|
] }),
|
|
@@ -1278,8 +1492,28 @@ function AnalysisView({ sessionId, t }) {
|
|
|
1278
1492
|
annotations.rated === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "decision-muted", children: t("analysisAccuracyEmpty") }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "decision-muted decision-rate-summary", children: t("rateSummary", { rated: annotations.rated, good: annotations.good, bad: annotations.bad, unsure: annotations.unsure }) })
|
|
1279
1493
|
] }),
|
|
1280
1494
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "decision-analysis-section", children: [
|
|
1281
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.
|
|
1282
|
-
|
|
1495
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "decision-analysis-log-head", children: [
|
|
1496
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { children: t("log") }),
|
|
1497
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1498
|
+
"button",
|
|
1499
|
+
{
|
|
1500
|
+
type: "button",
|
|
1501
|
+
className: "decision-log-filter",
|
|
1502
|
+
"aria-pressed": lowOnly,
|
|
1503
|
+
disabled: !analysis || lowCount === 0,
|
|
1504
|
+
title: t("logLowOnlyHint"),
|
|
1505
|
+
onClick: () => {
|
|
1506
|
+
setLowOnly((value) => !value);
|
|
1507
|
+
setLogPage(1);
|
|
1508
|
+
},
|
|
1509
|
+
children: [
|
|
1510
|
+
t("logLowOnly"),
|
|
1511
|
+
lowCount > 0 ? ` \xB7 ${lowCount}` : ""
|
|
1512
|
+
]
|
|
1513
|
+
}
|
|
1514
|
+
)
|
|
1515
|
+
] }),
|
|
1516
|
+
!rows || rows.total === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "decision-empty", role: "status", children: lowOnly ? t("logLowEmpty") : t("analysisLogTruncated") }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1283
1517
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DecisionLogList, { entries: rows.entries, ratings, onRate: (id, rating) => void annotate(id, rating), t, newestFirst: false }),
|
|
1284
1518
|
rows.pages > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("nav", { className: "decision-pager", "aria-label": t("log"), children: [
|
|
1285
1519
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", disabled: rows.page <= 1, onClick: () => setLogPage((page) => Math.max(1, page - 1)), children: t("pagerPrev") }),
|
|
@@ -1308,6 +1542,13 @@ var DEFAULT_KEEP_PREFIXES = ["mcp__openviking"];
|
|
|
1308
1542
|
var DEFAULT_MAX_CANDIDATES = 20;
|
|
1309
1543
|
var DEFAULT_THRESHOLD = 0.7;
|
|
1310
1544
|
var DEFAULT_BATCH_MODE = "auto";
|
|
1545
|
+
var CHECKPOINT_DEFAULTS = { enabled: false, heartbeatSteps: 6, failureThreshold: 3, timeoutMs: 1500 };
|
|
1546
|
+
var checkpointFieldsOf = (settings) => ({
|
|
1547
|
+
enabled: settings?.enabled === true,
|
|
1548
|
+
heartbeatSteps: String(settings?.heartbeatSteps ?? CHECKPOINT_DEFAULTS.heartbeatSteps),
|
|
1549
|
+
failureThreshold: String(settings?.failureThreshold ?? CHECKPOINT_DEFAULTS.failureThreshold),
|
|
1550
|
+
timeoutMs: String(settings?.timeoutMs ?? CHECKPOINT_DEFAULTS.timeoutMs)
|
|
1551
|
+
});
|
|
1311
1552
|
var DEFAULT_RUBRIC = [
|
|
1312
1553
|
"\u660E\u663E\u7B54\u975E\u6240\u95EE\uFF0C\u6216\u5B58\u5728\u4E25\u91CD\u9057\u6F0F / \u81EA\u76F8\u77DB\u76FE",
|
|
1313
1554
|
"\u57FA\u672C\u7B54\u5230\u95EE\u9898\uFF0C\u4F46\u6709\u53EF\u5BDF\u89C9\u7684\u9057\u6F0F\u6216\u4E0D\u4E25\u8C28",
|
|
@@ -1411,6 +1652,7 @@ function ConfigForm({ t, fetchFn = fetch }) {
|
|
|
1411
1652
|
const [narrowOn, setNarrowOn] = (0, import_react4.useState)(true);
|
|
1412
1653
|
const [completeOn, setCompleteOn] = (0, import_react4.useState)(true);
|
|
1413
1654
|
const [completeMode, setCompleteMode] = (0, import_react4.useState)("observe");
|
|
1655
|
+
const [checkpoint, setCheckpoint] = (0, import_react4.useState)(() => checkpointFieldsOf());
|
|
1414
1656
|
const [key, setKey] = (0, import_react4.useState)("");
|
|
1415
1657
|
const [busy, setBusy] = (0, import_react4.useState)(false);
|
|
1416
1658
|
const [advancedDirty, setAdvancedDirty] = (0, import_react4.useState)(false);
|
|
@@ -1431,6 +1673,7 @@ function ConfigForm({ t, fetchFn = fetch }) {
|
|
|
1431
1673
|
setCheckMode(value.checkSettings?.mode ?? "observe");
|
|
1432
1674
|
setNarrowMode(value.narrowSettings?.mode ?? "enforce");
|
|
1433
1675
|
setCompleteMode(value.completeSettings?.mode ?? "observe");
|
|
1676
|
+
setCheckpoint(checkpointFieldsOf(value.checkpointSettings));
|
|
1434
1677
|
setKeepPrefixes(prefixesText(value.narrowSettings));
|
|
1435
1678
|
setMaxCandidates(String(maxCandidatesOf(value.narrowSettings)));
|
|
1436
1679
|
setThreshold(String(thresholdOf(value.narrowSettings)));
|
|
@@ -1536,6 +1779,13 @@ function ConfigForm({ t, fetchFn = fetch }) {
|
|
|
1536
1779
|
mode: completeMode,
|
|
1537
1780
|
minConditions: clampNumber(thresholds.minConditions, THRESHOLD_DEFAULTS.minConditions, 2, 20, true),
|
|
1538
1781
|
minConfidence: clampNumber(thresholds.completeMin, THRESHOLD_DEFAULTS.completeMin, 0, 1)
|
|
1782
|
+
},
|
|
1783
|
+
checkpointSettings: {
|
|
1784
|
+
...config.checkpointSettings,
|
|
1785
|
+
enabled: checkpoint.enabled,
|
|
1786
|
+
heartbeatSteps: clampNumber(checkpoint.heartbeatSteps, CHECKPOINT_DEFAULTS.heartbeatSteps, 2, 100, true),
|
|
1787
|
+
failureThreshold: clampNumber(checkpoint.failureThreshold, CHECKPOINT_DEFAULTS.failureThreshold, 2, 10, true),
|
|
1788
|
+
timeoutMs: clampNumber(checkpoint.timeoutMs, CHECKPOINT_DEFAULTS.timeoutMs, 100, 1e4, true)
|
|
1539
1789
|
}
|
|
1540
1790
|
})
|
|
1541
1791
|
});
|
|
@@ -1544,7 +1794,8 @@ function ConfigForm({ t, fetchFn = fetch }) {
|
|
|
1544
1794
|
gateSettings: value.gateSettings ?? previous.gateSettings,
|
|
1545
1795
|
checkSettings: value.checkSettings ?? previous.checkSettings,
|
|
1546
1796
|
narrowSettings: value.narrowSettings ?? previous.narrowSettings,
|
|
1547
|
-
completeSettings: value.completeSettings ?? previous.completeSettings
|
|
1797
|
+
completeSettings: value.completeSettings ?? previous.completeSettings,
|
|
1798
|
+
checkpointSettings: value.checkpointSettings ?? previous.checkpointSettings
|
|
1548
1799
|
}));
|
|
1549
1800
|
applyAdvanced(value);
|
|
1550
1801
|
setAdvancedDirty(false);
|
|
@@ -1955,6 +2206,84 @@ ${url}`)) return;
|
|
|
1955
2206
|
] })
|
|
1956
2207
|
] })
|
|
1957
2208
|
] }),
|
|
2209
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "decision-field-block decision-field-block-wide", children: [
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "decision-subhead", children: t("checkpointSettings") }),
|
|
2211
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2212
|
+
Toggle,
|
|
2213
|
+
{
|
|
2214
|
+
label: t("checkpointEnabled"),
|
|
2215
|
+
checked: checkpoint.enabled,
|
|
2216
|
+
disabled: !canEdit,
|
|
2217
|
+
onChange: (enabled) => {
|
|
2218
|
+
setCheckpoint((previous) => ({ ...previous, enabled }));
|
|
2219
|
+
setAdvancedDirty(true);
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
),
|
|
2223
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "decision-muted", children: t("checkpointHint") }),
|
|
2224
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "decision-threshold-grid", children: [
|
|
2225
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "decision-field decision-field-inline", children: [
|
|
2226
|
+
t("checkpointHeartbeatLabel"),
|
|
2227
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2228
|
+
"input",
|
|
2229
|
+
{
|
|
2230
|
+
className: "decision-narrow-cap",
|
|
2231
|
+
type: "number",
|
|
2232
|
+
min: 2,
|
|
2233
|
+
max: 100,
|
|
2234
|
+
step: 1,
|
|
2235
|
+
value: checkpoint.heartbeatSteps,
|
|
2236
|
+
disabled: !canEdit || !checkpoint.enabled,
|
|
2237
|
+
onChange: (event) => {
|
|
2238
|
+
setCheckpoint((previous) => ({ ...previous, heartbeatSteps: event.target.value }));
|
|
2239
|
+
setAdvancedDirty(true);
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
),
|
|
2243
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { className: "decision-muted", children: t("checkpointHeartbeatHint") })
|
|
2244
|
+
] }),
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "decision-field decision-field-inline", children: [
|
|
2246
|
+
t("checkpointFailureLabel"),
|
|
2247
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2248
|
+
"input",
|
|
2249
|
+
{
|
|
2250
|
+
className: "decision-narrow-cap",
|
|
2251
|
+
type: "number",
|
|
2252
|
+
min: 2,
|
|
2253
|
+
max: 10,
|
|
2254
|
+
step: 1,
|
|
2255
|
+
value: checkpoint.failureThreshold,
|
|
2256
|
+
disabled: !canEdit || !checkpoint.enabled,
|
|
2257
|
+
onChange: (event) => {
|
|
2258
|
+
setCheckpoint((previous) => ({ ...previous, failureThreshold: event.target.value }));
|
|
2259
|
+
setAdvancedDirty(true);
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
),
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { className: "decision-muted", children: t("checkpointFailureHint") })
|
|
2264
|
+
] }),
|
|
2265
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "decision-field decision-field-inline", children: [
|
|
2266
|
+
t("checkpointTimeoutLabel"),
|
|
2267
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2268
|
+
"input",
|
|
2269
|
+
{
|
|
2270
|
+
className: "decision-narrow-cap",
|
|
2271
|
+
type: "number",
|
|
2272
|
+
min: 100,
|
|
2273
|
+
max: 1e4,
|
|
2274
|
+
step: 1,
|
|
2275
|
+
value: checkpoint.timeoutMs,
|
|
2276
|
+
disabled: !canEdit || !checkpoint.enabled,
|
|
2277
|
+
onChange: (event) => {
|
|
2278
|
+
setCheckpoint((previous) => ({ ...previous, timeoutMs: event.target.value }));
|
|
2279
|
+
setAdvancedDirty(true);
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
),
|
|
2283
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { className: "decision-muted", children: t("checkpointTimeoutHint") })
|
|
2284
|
+
] })
|
|
2285
|
+
] })
|
|
2286
|
+
] }),
|
|
1958
2287
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "decision-field-block decision-field-block-wide", children: [
|
|
1959
2288
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "decision-subhead", children: t("advancedRubric") }),
|
|
1960
2289
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "decision-field", children: [
|
|
@@ -2155,6 +2484,14 @@ var css = `
|
|
|
2155
2484
|
real quality dip. */
|
|
2156
2485
|
.decision-log-muted-verdict{font-weight:600;color:var(--dsw-alias-label-tertiary,#9aa5b1)}
|
|
2157
2486
|
.decision-log-muted .decision-log-time{opacity:.75}
|
|
2487
|
+
/* Every low self-check row gets an amber accent and a badge, even when the score
|
|
2488
|
+
is low-confidence noise. The noise row keeps its muted verdict and dashed
|
|
2489
|
+
accent, so it is findable without reading as a real quality dip. */
|
|
2490
|
+
.decision-log-item.decision-log-low{border-left-color:#c98a1e}
|
|
2491
|
+
.decision-log-item.decision-log-low.decision-log-muted{border-left-style:dashed}
|
|
2492
|
+
.decision-log-badge{display:inline-block;margin-right:.35rem;padding:0 .38rem;border:1px solid transparent;border-radius:999px;font-size:.68rem;font-weight:600;line-height:1.6;vertical-align:.05em}
|
|
2493
|
+
.decision-log-badge-low{color:#8a5a12;background:rgba(201,138,30,.16);border-color:rgba(201,138,30,.4)}
|
|
2494
|
+
.decision-log-badge-noise{color:var(--dsw-alias-label-secondary,#59636e);background:var(--dsw-alias-bg-layer-1,#f2f4f6);border-color:var(--dsw-alias-border-l2,#dce1e6)}
|
|
2158
2495
|
|
|
2159
2496
|
.decision-status{display:flex;align-items:center;gap:.5rem;margin-top:.7rem;font-size:.82rem}
|
|
2160
2497
|
.decision-status-dot{width:8px;height:8px;border-radius:50%;flex:0 0 auto;background:#9aa5b1}
|
|
@@ -2265,6 +2602,20 @@ var css = `
|
|
|
2265
2602
|
.decision-analysis-switch:focus-visible{outline:2px solid var(--decision-analysis-accent);outline-offset:2px}
|
|
2266
2603
|
.decision-analysis-section{border-top:1px solid var(--dsw-alias-border-l2,#eceff1);margin-top:1.1rem;padding-top:1rem}
|
|
2267
2604
|
.decision-analysis-section>h3{font-size:.92rem;margin:0 0 .6rem}
|
|
2605
|
+
/* Section header with the low-score-only filter on the right. Keeping the
|
|
2606
|
+
filter next to the log heading makes the affordance discoverable exactly
|
|
2607
|
+
where a long list is being scanned. */
|
|
2608
|
+
.decision-analysis-log-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem;margin-bottom:.6rem}
|
|
2609
|
+
.decision-analysis-log-head>h3{font-size:.92rem;margin:0}
|
|
2610
|
+
.decision-log-filter{flex:0 0 auto;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2,#ccd3da);border-radius:999px;background:transparent;color:var(--dsw-alias-label-secondary,#59636e);padding:.24rem .7rem;font:inherit;font-size:.76rem;line-height:1.3;white-space:nowrap;cursor:pointer;transition:color .15s,border-color .15s,background .15s}
|
|
2611
|
+
.decision-log-filter:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eef1f3);color:var(--dsw-alias-label-primary,#202124)}
|
|
2612
|
+
.decision-log-filter[aria-pressed="true"]{border-color:#c98a1e;color:#8a5a12;background:rgba(201,138,30,.12)}
|
|
2613
|
+
.decision-log-filter:disabled{opacity:.5;cursor:default}
|
|
2614
|
+
.decision-log-filter:focus-visible{outline:2px solid var(--decision-analysis-accent);outline-offset:2px}
|
|
2615
|
+
@media (prefers-color-scheme:dark){
|
|
2616
|
+
.decision-log-badge-low{color:#e0a83e;background:rgba(224,168,62,.14);border-color:rgba(224,168,62,.4)}
|
|
2617
|
+
.decision-log-filter[aria-pressed="true"]{border-color:#e0a83e;color:#e0a83e;background:rgba(224,168,62,.14)}
|
|
2618
|
+
}
|
|
2268
2619
|
.decision-analysis-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:.7rem}
|
|
2269
2620
|
.decision-analysis-trend{max-width:26rem}
|
|
2270
2621
|
.decision-analysis-note{margin:.5rem 0 0}
|