@duke-dsh-plugins/dsh-agent-approval 1.4.2 → 1.6.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 +9 -7
- package/client.js +324 -106
- package/index.js +544 -81
- package/package.json +2 -2
- package/typert.host.js +121 -19
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duke-dsh-plugins/dsh-agent-approval",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Agent-decided approvals for DeepSeek Harness: a workspace-write base permission mode where an independent approval subagent
|
|
3
|
+
"version": "1.6.0",
|
|
4
|
+
"description": "Agent-decided approvals for DeepSeek Harness: a workspace-write base permission mode where an independent approval judge (an isolated subagent, or the TypeSafe Jev decision model via direct API) evaluates every sandbox escalation (risky operations are rejected), with a configurable approval model and a per-session audit trail in the conversation window's 审批 tab.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/MoonlitDropOfBlood/dsh-agent-approval.git"
|
package/typert.host.js
CHANGED
|
@@ -41,6 +41,15 @@ const modelRouteSchema = z
|
|
|
41
41
|
})
|
|
42
42
|
.readonly();
|
|
43
43
|
|
|
44
|
+
const jevConfigSchema = z
|
|
45
|
+
.object({
|
|
46
|
+
apiKey: z.string(),
|
|
47
|
+
endpoint: z.string(),
|
|
48
|
+
model: z.string(),
|
|
49
|
+
confidence: z.number(),
|
|
50
|
+
})
|
|
51
|
+
.readonly();
|
|
52
|
+
|
|
44
53
|
const enabledSessionSchema = z
|
|
45
54
|
.object({
|
|
46
55
|
id: z.string(),
|
|
@@ -63,10 +72,10 @@ const ruleSchema = z
|
|
|
63
72
|
const stateValueSchema = z
|
|
64
73
|
.object({
|
|
65
74
|
model: modelRouteSchema,
|
|
75
|
+
jev: jevConfigSchema,
|
|
66
76
|
timeoutMs: z.number(),
|
|
67
77
|
enabledSessions: z.array(enabledSessionSchema).readonly(),
|
|
68
78
|
rules: z.array(ruleSchema).readonly(),
|
|
69
|
-
records: z.array(recordSchema).readonly(),
|
|
70
79
|
})
|
|
71
80
|
.readonly();
|
|
72
81
|
|
|
@@ -76,6 +85,12 @@ const setModelValueSchema = z
|
|
|
76
85
|
})
|
|
77
86
|
.readonly();
|
|
78
87
|
|
|
88
|
+
const setJevValueSchema = z
|
|
89
|
+
.object({
|
|
90
|
+
jev: jevConfigSchema,
|
|
91
|
+
})
|
|
92
|
+
.readonly();
|
|
93
|
+
|
|
79
94
|
const setTimeoutValueSchema = z
|
|
80
95
|
.object({
|
|
81
96
|
timeoutMs: z.number(),
|
|
@@ -94,9 +109,10 @@ const rulesValueSchema = z
|
|
|
94
109
|
})
|
|
95
110
|
.readonly();
|
|
96
111
|
|
|
97
|
-
const
|
|
112
|
+
const sessionRecordsValueSchema = z
|
|
98
113
|
.object({
|
|
99
|
-
|
|
114
|
+
records: z.array(recordSchema).readonly(),
|
|
115
|
+
enabled: z.boolean(),
|
|
100
116
|
})
|
|
101
117
|
.readonly();
|
|
102
118
|
|
|
@@ -152,11 +168,12 @@ function okResult(valueSchema) {
|
|
|
152
168
|
|
|
153
169
|
const stateResultSchema = okResult(stateValueSchema);
|
|
154
170
|
const setModelResultSchema = okResult(setModelValueSchema);
|
|
171
|
+
const setJevResultSchema = okResult(setJevValueSchema);
|
|
155
172
|
const setTimeoutResultSchema = okResult(setTimeoutValueSchema);
|
|
156
173
|
const toggleResultSchema = okResult(toggleValueSchema);
|
|
157
174
|
const addRuleResultSchema = okResult(rulesValueSchema);
|
|
158
175
|
const removeRuleResultSchema = okResult(rulesValueSchema);
|
|
159
|
-
const
|
|
176
|
+
const sessionRecordsResultSchema = okResult(sessionRecordsValueSchema);
|
|
160
177
|
const directoryResultSchema = okResult(directoryValueSchema);
|
|
161
178
|
|
|
162
179
|
// ---- per-invocation parameter schemas ----------------------------------------
|
|
@@ -166,6 +183,13 @@ const _agentApproval_setModel_parameter_0$schema = z.object({
|
|
|
166
183
|
model: z.string(),
|
|
167
184
|
});
|
|
168
185
|
|
|
186
|
+
const _agentApproval_setJevConfig_parameter_0$schema = z.object({
|
|
187
|
+
apiKey: z.string(),
|
|
188
|
+
endpoint: z.string(),
|
|
189
|
+
model: z.string(),
|
|
190
|
+
confidence: z.number(),
|
|
191
|
+
});
|
|
192
|
+
|
|
169
193
|
const _agentApproval_setApprovalTimeout_parameter_0$schema = z.object({
|
|
170
194
|
timeoutMs: z.number(),
|
|
171
195
|
});
|
|
@@ -186,6 +210,10 @@ const _agentApproval_removeRule_parameter_0$schema = z.object({
|
|
|
186
210
|
id: z.string(),
|
|
187
211
|
});
|
|
188
212
|
|
|
213
|
+
const _agentApproval_sessionRecords_parameter_0$schema = z.object({
|
|
214
|
+
sessionId: z.string(),
|
|
215
|
+
});
|
|
216
|
+
|
|
189
217
|
export const TYPERT = {
|
|
190
218
|
package: "@duke-dsh-plugins/dsh-agent-approval",
|
|
191
219
|
face: "host",
|
|
@@ -230,6 +258,31 @@ export const TYPERT = {
|
|
|
230
258
|
},
|
|
231
259
|
sourceLocation: { file: "index.js", line: 1, column: 1 },
|
|
232
260
|
},
|
|
261
|
+
{
|
|
262
|
+
id: "dsh-agent-approval#agentApproval/setJevConfig",
|
|
263
|
+
service: "agentApproval",
|
|
264
|
+
namespace: "agentApproval",
|
|
265
|
+
method: "setJevConfig",
|
|
266
|
+
invocation: { kind: "direct" },
|
|
267
|
+
parameters: [
|
|
268
|
+
{
|
|
269
|
+
name: "request",
|
|
270
|
+
wire: "request",
|
|
271
|
+
source: "json",
|
|
272
|
+
codec: {
|
|
273
|
+
mode: "strict",
|
|
274
|
+
typeSymbol: "dsh-agent-approval#AgentApprovalSetJevRequest",
|
|
275
|
+
schema: _agentApproval_setJevConfig_parameter_0$schema,
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
],
|
|
279
|
+
result: {
|
|
280
|
+
mode: "strict",
|
|
281
|
+
typeSymbol: "dsh-agent-approval#AgentApprovalSetJevResult",
|
|
282
|
+
schema: setJevResultSchema,
|
|
283
|
+
},
|
|
284
|
+
sourceLocation: { file: "index.js", line: 1, column: 1 },
|
|
285
|
+
},
|
|
233
286
|
{
|
|
234
287
|
id: "dsh-agent-approval#agentApproval/setApprovalTimeout",
|
|
235
288
|
service: "agentApproval",
|
|
@@ -331,16 +384,27 @@ export const TYPERT = {
|
|
|
331
384
|
sourceLocation: { file: "index.js", line: 1, column: 1 },
|
|
332
385
|
},
|
|
333
386
|
{
|
|
334
|
-
id: "dsh-agent-approval#agentApproval/
|
|
387
|
+
id: "dsh-agent-approval#agentApproval/sessionRecords",
|
|
335
388
|
service: "agentApproval",
|
|
336
389
|
namespace: "agentApproval",
|
|
337
|
-
method: "
|
|
390
|
+
method: "sessionRecords",
|
|
338
391
|
invocation: { kind: "direct" },
|
|
339
|
-
parameters: [
|
|
392
|
+
parameters: [
|
|
393
|
+
{
|
|
394
|
+
name: "request",
|
|
395
|
+
wire: "request",
|
|
396
|
+
source: "json",
|
|
397
|
+
codec: {
|
|
398
|
+
mode: "strict",
|
|
399
|
+
typeSymbol: "dsh-agent-approval#AgentApprovalSessionRecordsRequest",
|
|
400
|
+
schema: _agentApproval_sessionRecords_parameter_0$schema,
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
],
|
|
340
404
|
result: {
|
|
341
405
|
mode: "strict",
|
|
342
|
-
typeSymbol: "dsh-agent-approval#
|
|
343
|
-
schema:
|
|
406
|
+
typeSymbol: "dsh-agent-approval#AgentApprovalSessionRecordsResult",
|
|
407
|
+
schema: sessionRecordsResultSchema,
|
|
344
408
|
},
|
|
345
409
|
sourceLocation: { file: "index.js", line: 1, column: 1 },
|
|
346
410
|
},
|
|
@@ -363,7 +427,7 @@ export const TYPERT = {
|
|
|
363
427
|
services: [
|
|
364
428
|
{
|
|
365
429
|
description:
|
|
366
|
-
"Agent-approval permission mode service: pins enabled sessions to a workspace-write base, judges every sandbox escalation with an independent approval subagent (fail closed),
|
|
430
|
+
"Agent-approval permission mode service: pins enabled sessions to a workspace-write base, judges every sandbox escalation with an independent approval subagent (fail closed), appends the audit trail to each session's own log, and exposes model config to the DeepSeek Harness web UI.",
|
|
367
431
|
summary: "Agent-approval permission mode service.",
|
|
368
432
|
tags: [],
|
|
369
433
|
jsDoc:
|
|
@@ -375,17 +439,25 @@ export const TYPERT = {
|
|
|
375
439
|
kind: "method",
|
|
376
440
|
name: "getState",
|
|
377
441
|
signature: "@Remote('getState') async getState(): Promise<AgentApprovalStateResult>",
|
|
378
|
-
summary: "Snapshot for the Settings page
|
|
442
|
+
summary: "Snapshot for the Settings page (model route, Jev backend, timeout, enabled sessions, rules).",
|
|
379
443
|
jsDoc:
|
|
380
|
-
"/**\n * Return the judge model route, timeout, enabled sessions (id + session-list title + workspace cwd), and the
|
|
444
|
+
"/**\n * Return the judge model route, the TypeSafe Jev backend settings, timeout, enabled sessions (id + session-list title + workspace cwd), and the rule table.\n * @returns success or a business failure.\n */",
|
|
381
445
|
},
|
|
382
446
|
{
|
|
383
447
|
kind: "method",
|
|
384
448
|
name: "setModel",
|
|
385
449
|
signature: "@Remote('setModel') async setModel(request: AgentApprovalSetModelRequest): Promise<AgentApprovalSetModelResult>",
|
|
386
|
-
summary: "Set the judge model route (empty strings = inherit the requesting session's).",
|
|
450
|
+
summary: "Set the judge model route (empty strings = inherit the requesting session's; provider 'typesafe' selects the Jev backend).",
|
|
451
|
+
jsDoc:
|
|
452
|
+
"/**\n * Set provider/model used by the approval judge; empty strings clear the override. The synthetic provider 'typesafe' routes judging through the TypeSafe Jev HTTP API instead of a harness subagent.\n * @param request - { provider, model }.\n * @returns the stored route.\n */",
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
kind: "method",
|
|
456
|
+
name: "setJevConfig",
|
|
457
|
+
signature: "@Remote('setJevConfig') async setJevConfig(request: AgentApprovalSetJevRequest): Promise<AgentApprovalSetJevResult>",
|
|
458
|
+
summary: "Set the TypeSafe Jev backend settings (API key, endpoint, model, confidence gate; persisted).",
|
|
387
459
|
jsDoc:
|
|
388
|
-
"/**\n *
|
|
460
|
+
"/**\n * Update the Jev backend settings used when the judge provider is 'typesafe'. Only provided fields change; confidence (the fail-closed gate) is clamped to [0.01, 0.99].\n * @param request - { apiKey, endpoint, model, confidence }.\n * @returns the stored Jev settings.\n */",
|
|
389
461
|
},
|
|
390
462
|
{
|
|
391
463
|
kind: "method",
|
|
@@ -421,11 +493,11 @@ export const TYPERT = {
|
|
|
421
493
|
},
|
|
422
494
|
{
|
|
423
495
|
kind: "method",
|
|
424
|
-
name: "
|
|
425
|
-
signature: "@Remote('
|
|
426
|
-
summary: "
|
|
496
|
+
name: "sessionRecords",
|
|
497
|
+
signature: "@Remote('sessionRecords') async sessionRecords(request: AgentApprovalSessionRecordsRequest): Promise<AgentApprovalSessionRecordsResult>",
|
|
498
|
+
summary: "Fold one live session's audit records out of its own durable log.",
|
|
427
499
|
jsDoc:
|
|
428
|
-
"/**\n *
|
|
500
|
+
"/**\n * Fold the agent-approval/record events of one live session (chronological) plus the current enabled state. Records follow the session: persisted in its log, restored with it, gone when it is deleted.\n * @param request - { sessionId }.\n * @returns the session's records, or session-not-live.\n */",
|
|
429
501
|
},
|
|
430
502
|
{
|
|
431
503
|
kind: "method",
|
|
@@ -447,6 +519,21 @@ export const TYPERT = {
|
|
|
447
519
|
declaration:
|
|
448
520
|
"export interface AgentApprovalModelRoute {\n readonly provider: string;\n readonly model: string;\n}",
|
|
449
521
|
},
|
|
522
|
+
{
|
|
523
|
+
name: "AgentApprovalJevConfig",
|
|
524
|
+
declaration:
|
|
525
|
+
"export interface AgentApprovalJevConfig {\n readonly apiKey: string;\n readonly endpoint: string;\n readonly model: string;\n readonly confidence: number;\n}",
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
name: "AgentApprovalSetJevRequest",
|
|
529
|
+
declaration:
|
|
530
|
+
"export interface AgentApprovalSetJevRequest {\n readonly apiKey: string;\n readonly endpoint: string;\n readonly model: string;\n readonly confidence: number;\n}",
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
name: "AgentApprovalSetJevResult",
|
|
534
|
+
declaration:
|
|
535
|
+
"export type AgentApprovalSetJevResult = { ok: true; value: { readonly jev: AgentApprovalJevConfig } } | { ok: false; error: { code: string; message?: string } };",
|
|
536
|
+
},
|
|
450
537
|
{
|
|
451
538
|
name: "AgentApprovalEnabledSession",
|
|
452
539
|
declaration:
|
|
@@ -465,7 +552,22 @@ export const TYPERT = {
|
|
|
465
552
|
{
|
|
466
553
|
name: "AgentApprovalStateValue",
|
|
467
554
|
declaration:
|
|
468
|
-
"export interface AgentApprovalStateValue {\n readonly model: AgentApprovalModelRoute;\n readonly
|
|
555
|
+
"export interface AgentApprovalStateValue {\n readonly model: AgentApprovalModelRoute;\n readonly jev: AgentApprovalJevConfig;\n readonly timeoutMs: number;\n readonly enabledSessions: readonly AgentApprovalEnabledSession[];\n readonly rules: readonly AgentApprovalRule[];\n}",
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
name: "AgentApprovalSessionRecordsRequest",
|
|
559
|
+
declaration:
|
|
560
|
+
"export interface AgentApprovalSessionRecordsRequest {\n readonly sessionId: string;\n}",
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
name: "AgentApprovalSessionRecordsValue",
|
|
564
|
+
declaration:
|
|
565
|
+
"export interface AgentApprovalSessionRecordsValue {\n readonly records: readonly AgentApprovalRecord[];\n readonly enabled: boolean;\n}",
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
name: "AgentApprovalSessionRecordsResult",
|
|
569
|
+
declaration:
|
|
570
|
+
"export type AgentApprovalSessionRecordsResult = { ok: true; value: AgentApprovalSessionRecordsValue } | { ok: false; error: { code: string; message?: string } };",
|
|
469
571
|
},
|
|
470
572
|
{
|
|
471
573
|
name: "AgentApprovalStateResult",
|