pi-harness-runtime 1.1.402 → 1.1.404
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/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/connection-runtime/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/durable-review/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-sink/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/dist/auto-continue.d.ts +6 -0
- package/packages/jev-judge/dist/auto-continue.d.ts.map +1 -1
- package/packages/jev-judge/dist/auto-continue.js +13 -3
- package/packages/jev-judge/dist/auto-continue.js.map +1 -1
- package/packages/jev-judge/dist/question-risk.d.ts +8 -5
- package/packages/jev-judge/dist/question-risk.d.ts.map +1 -1
- package/packages/jev-judge/dist/question-risk.js +12 -7
- package/packages/jev-judge/dist/question-risk.js.map +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/jev-judge/src/auto-continue.ts +17 -3
- package/packages/jev-judge/src/question-risk.ts +12 -8
- package/packages/jev-judge/tests/auto-continue-context.test.ts +59 -0
- package/packages/jev-judge/tests/question-risk.test.ts +15 -2
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/logging/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/permission-mode/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/relay/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/voice-api/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
|
@@ -55,15 +55,18 @@ function matchPatterns(text, patterns, signals) {
|
|
|
55
55
|
*
|
|
56
56
|
* The rules:
|
|
57
57
|
*
|
|
58
|
-
* - A question
|
|
59
|
-
*
|
|
60
|
-
*
|
|
58
|
+
* - A question of kind "explicit" asks for an explicit human authorization.
|
|
59
|
+
* Jev never approves it on its own.
|
|
60
|
+
* - A question of kind "approval" is the agent proposing work. It stays
|
|
61
|
+
* auto-approvable as long as nothing in it is risky - that is the whole
|
|
62
|
+
* point of the timeout: routine, reversible work continues when the user
|
|
63
|
+
* is away.
|
|
61
64
|
* - A question that names a destructive action is destructive, and its
|
|
62
65
|
* reversibility cannot be proven - so it waits.
|
|
66
|
+
* - A question that reaches the outside world or touches a secret needs a
|
|
67
|
+
* human as well.
|
|
63
68
|
* - A question with an unknown kind or an empty text is uncertain, and an
|
|
64
69
|
* uncertain case waits for the human.
|
|
65
|
-
* - Only a routine question without a destructive or external signal is
|
|
66
|
-
* harmless enough for an autonomous decision.
|
|
67
70
|
*/
|
|
68
71
|
export function classifyQuestionRisk(input) {
|
|
69
72
|
const text = (input.text ?? "").toLowerCase();
|
|
@@ -72,8 +75,10 @@ export function classifyQuestionRisk(input) {
|
|
|
72
75
|
const destructive = matchPatterns(text, DESTRUCTIVE_PATTERNS, signals);
|
|
73
76
|
const external = matchPatterns(text, EXTERNAL_PATTERNS, signals);
|
|
74
77
|
const sensitive = matchPatterns(text, SENSITIVE_PATTERNS, signals);
|
|
75
|
-
//
|
|
76
|
-
|
|
78
|
+
// Only an explicitly demanded authorization blocks the autonomous
|
|
79
|
+
// decision. An "approval" question is the agent proposing work: it
|
|
80
|
+
// stays auto-approvable unless the wording names a risky action.
|
|
81
|
+
let requiresExplicitAuthorization = kind === "explicit";
|
|
77
82
|
// A destructive action never gets an autonomous approval.
|
|
78
83
|
if (destructive) {
|
|
79
84
|
requiresExplicitAuthorization = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"question-risk.js","sourceRoot":"","sources":["../src/question-risk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAoCH;;GAEG;AACH,MAAM,oBAAoB,GAAkB;IAC3C,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,4DAA4D,EAAE;IACzF,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,6BAA6B,EAAE;IACzD,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,gCAAgC,EAAE;IAC7D,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,0EAA0E,EAAE;IAC3G,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,4DAA4D,EAAE;IAC9F,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,uFAAuF,EAAE;IAC3H,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,oCAAoC,EAAE;IACpE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE;CAC/C,CAAC;AAEF;;GAEG;AACH,MAAM,iBAAiB,GAAkB;IACxC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,4BAA4B,EAAE;IAC7D,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,mCAAmC,EAAE;IAChE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,sCAAsC,EAAE;IACvE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,iHAAiH,EAAE;IACrJ,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,kEAAkE,EAAE;CAC9F,CAAC;AAEF;;GAEG;AACH,MAAM,kBAAkB,GAAkB;IACzC,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,qDAAqD,EAAE;CACvF,CAAC;AAEF,SAAS,aAAa,CACrB,IAAY,EACZ,QAAuB,EACvB,OAAiB;IAEjB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO,GAAG,IAAI,CAAC;QAChB,CAAC;IACF,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"question-risk.js","sourceRoot":"","sources":["../src/question-risk.ts"],"names":[],"mappings":"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"}
|
|
@@ -118,10 +118,17 @@ export interface DecisionPolicyResult {
|
|
|
118
118
|
export interface DecisionPolicyOptions {
|
|
119
119
|
/** The confidence an autonomous approval needs. */
|
|
120
120
|
confidenceThreshold?: number;
|
|
121
|
+
/** The confidence a cautious approval needs (lower than the approval threshold). */
|
|
122
|
+
cautionThreshold?: number;
|
|
121
123
|
/** The confidence of the proposed outcome. */
|
|
122
124
|
confidence?: number;
|
|
123
125
|
}
|
|
124
126
|
|
|
127
|
+
/** The confidence an autonomous approval needs by default. */
|
|
128
|
+
export const DEFAULT_PROCEED_THRESHOLD = 0.7;
|
|
129
|
+
/** The confidence a cautious approval needs by default. */
|
|
130
|
+
export const DEFAULT_CAUTION_THRESHOLD = 0.5;
|
|
131
|
+
|
|
125
132
|
/**
|
|
126
133
|
* Is the value a known outcome?
|
|
127
134
|
*
|
|
@@ -226,7 +233,13 @@ export function applyDecisionPolicy(
|
|
|
226
233
|
};
|
|
227
234
|
}
|
|
228
235
|
|
|
229
|
-
|
|
236
|
+
// The threshold belongs to the outcome: a cautious approval needs the
|
|
237
|
+
// caution threshold, the higher approval threshold is reserved for a
|
|
238
|
+
// full approval. The configured caution range must really proceed.
|
|
239
|
+
const threshold =
|
|
240
|
+
proposed === "proceed_with_caution"
|
|
241
|
+
? (options?.cautionThreshold ?? DEFAULT_CAUTION_THRESHOLD)
|
|
242
|
+
: (options?.confidenceThreshold ?? DEFAULT_PROCEED_THRESHOLD);
|
|
230
243
|
const confidence = options?.confidence;
|
|
231
244
|
if (typeof confidence === "number" && confidence < threshold) {
|
|
232
245
|
return {
|
|
@@ -307,8 +320,8 @@ export interface AutoContinueConfig extends JevJudgeConfig {
|
|
|
307
320
|
* Default configuration
|
|
308
321
|
*/
|
|
309
322
|
const DEFAULT_CONFIG = {
|
|
310
|
-
proceedThreshold:
|
|
311
|
-
cautionThreshold:
|
|
323
|
+
proceedThreshold: DEFAULT_PROCEED_THRESHOLD,
|
|
324
|
+
cautionThreshold: DEFAULT_CAUTION_THRESHOLD,
|
|
312
325
|
maxWaitMinutes: 30,
|
|
313
326
|
fallbackAction: "wait" as const,
|
|
314
327
|
};
|
|
@@ -435,6 +448,7 @@ export class AutoContinueJudge {
|
|
|
435
448
|
): AutoContinueDecision {
|
|
436
449
|
const policy = applyDecisionPolicy(decision.outcome, taskState.context, {
|
|
437
450
|
confidenceThreshold: this.config.proceedThreshold,
|
|
451
|
+
cautionThreshold: this.config.cautionThreshold,
|
|
438
452
|
confidence: decision.probability,
|
|
439
453
|
});
|
|
440
454
|
|
|
@@ -98,15 +98,18 @@ function matchPatterns(
|
|
|
98
98
|
*
|
|
99
99
|
* The rules:
|
|
100
100
|
*
|
|
101
|
-
* - A question
|
|
102
|
-
*
|
|
103
|
-
*
|
|
101
|
+
* - A question of kind "explicit" asks for an explicit human authorization.
|
|
102
|
+
* Jev never approves it on its own.
|
|
103
|
+
* - A question of kind "approval" is the agent proposing work. It stays
|
|
104
|
+
* auto-approvable as long as nothing in it is risky - that is the whole
|
|
105
|
+
* point of the timeout: routine, reversible work continues when the user
|
|
106
|
+
* is away.
|
|
104
107
|
* - A question that names a destructive action is destructive, and its
|
|
105
108
|
* reversibility cannot be proven - so it waits.
|
|
109
|
+
* - A question that reaches the outside world or touches a secret needs a
|
|
110
|
+
* human as well.
|
|
106
111
|
* - A question with an unknown kind or an empty text is uncertain, and an
|
|
107
112
|
* uncertain case waits for the human.
|
|
108
|
-
* - Only a routine question without a destructive or external signal is
|
|
109
|
-
* harmless enough for an autonomous decision.
|
|
110
113
|
*/
|
|
111
114
|
export function classifyQuestionRisk(
|
|
112
115
|
input: QuestionRiskInput,
|
|
@@ -119,9 +122,10 @@ export function classifyQuestionRisk(
|
|
|
119
122
|
const external = matchPatterns(text, EXTERNAL_PATTERNS, signals);
|
|
120
123
|
const sensitive = matchPatterns(text, SENSITIVE_PATTERNS, signals);
|
|
121
124
|
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
// Only an explicitly demanded authorization blocks the autonomous
|
|
126
|
+
// decision. An "approval" question is the agent proposing work: it
|
|
127
|
+
// stays auto-approvable unless the wording names a risky action.
|
|
128
|
+
let requiresExplicitAuthorization = kind === "explicit";
|
|
125
129
|
|
|
126
130
|
// A destructive action never gets an autonomous approval.
|
|
127
131
|
if (destructive) {
|
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
buildDecisionState,
|
|
14
14
|
createTaskState,
|
|
15
15
|
isEligibleForDecision,
|
|
16
|
+
DEFAULT_CAUTION_THRESHOLD,
|
|
17
|
+
DEFAULT_PROCEED_THRESHOLD,
|
|
16
18
|
MAX_LISTED_TASKS,
|
|
17
19
|
MAX_QUESTION_CHARS,
|
|
18
20
|
type DecisionContext,
|
|
@@ -138,6 +140,28 @@ describe("decision policy", () => {
|
|
|
138
140
|
expect(result.appliedRule).toBe("clarification-never-approved");
|
|
139
141
|
});
|
|
140
142
|
|
|
143
|
+
it("approves a benign approval question so the timeout can work", () => {
|
|
144
|
+
// The timeout exists for routine, reversible work: an agent that
|
|
145
|
+
// proposes work is not a hard authorization block.
|
|
146
|
+
const result = applyDecisionPolicy(
|
|
147
|
+
"approve",
|
|
148
|
+
context({
|
|
149
|
+
question: {
|
|
150
|
+
requestId: "q-1",
|
|
151
|
+
text: "Want me to implement the toggle buttons now?",
|
|
152
|
+
kind: "approval",
|
|
153
|
+
requiresExplicitAuthorization: false,
|
|
154
|
+
destructive: false,
|
|
155
|
+
reversible: true,
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
158
|
+
{ confidence: 0.9 },
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
expect(result.outcome).toBe("approve");
|
|
162
|
+
expect(result.appliedRule).toBeUndefined();
|
|
163
|
+
});
|
|
164
|
+
|
|
141
165
|
it("never approves an action that needs an explicit authorization", () => {
|
|
142
166
|
const result = applyDecisionPolicy(
|
|
143
167
|
"approve",
|
|
@@ -204,6 +228,41 @@ describe("decision policy", () => {
|
|
|
204
228
|
expect(result.appliedRule).toBe("confidence-below-threshold");
|
|
205
229
|
});
|
|
206
230
|
|
|
231
|
+
it("keeps the configured caution range out of the approval threshold", () => {
|
|
232
|
+
// A cautious approval needs the caution threshold, not the higher
|
|
233
|
+
// approval threshold: the configured range must really proceed.
|
|
234
|
+
const result = applyDecisionPolicy("proceed_with_caution", context(), {
|
|
235
|
+
confidence: 0.6,
|
|
236
|
+
confidenceThreshold: DEFAULT_PROCEED_THRESHOLD,
|
|
237
|
+
cautionThreshold: DEFAULT_CAUTION_THRESHOLD,
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
expect(result.outcome).toBe("proceed_with_caution");
|
|
241
|
+
expect(result.appliedRule).toBeUndefined();
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it("waits for a cautious approval below the caution threshold", () => {
|
|
245
|
+
const result = applyDecisionPolicy("proceed_with_caution", context(), {
|
|
246
|
+
confidence: 0.4,
|
|
247
|
+
confidenceThreshold: DEFAULT_PROCEED_THRESHOLD,
|
|
248
|
+
cautionThreshold: DEFAULT_CAUTION_THRESHOLD,
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
expect(result.outcome).toBe("wait");
|
|
252
|
+
expect(result.appliedRule).toBe("confidence-below-threshold");
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("keeps the approval threshold for a full approval", () => {
|
|
256
|
+
const result = applyDecisionPolicy("approve", context(), {
|
|
257
|
+
confidence: 0.6,
|
|
258
|
+
confidenceThreshold: DEFAULT_PROCEED_THRESHOLD,
|
|
259
|
+
cautionThreshold: DEFAULT_CAUTION_THRESHOLD,
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
expect(result.outcome).toBe("wait");
|
|
263
|
+
expect(result.appliedRule).toBe("confidence-below-threshold");
|
|
264
|
+
});
|
|
265
|
+
|
|
207
266
|
it("approves a low risk approval with a high confidence", () => {
|
|
208
267
|
const result = applyDecisionPolicy("approve", context(), {
|
|
209
268
|
confidence: 0.9,
|
|
@@ -25,14 +25,17 @@ describe("classifyQuestionRisk", () => {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
describe("a question that asks for permission", () => {
|
|
28
|
-
it("
|
|
28
|
+
it("keeps a benign approval question auto-approvable", () => {
|
|
29
29
|
const risk = classifyQuestionRisk({
|
|
30
30
|
kind: "approval",
|
|
31
31
|
text: "Want me to implement the toggle buttons now?",
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
// The timeout exists for routine, reversible work: the agent
|
|
35
|
+
// proposing work is not a hard authorization block.
|
|
36
|
+
expect(risk.requiresExplicitAuthorization).toBe(false);
|
|
35
37
|
expect(risk.destructive).toBe(false);
|
|
38
|
+
expect(risk.reversible).toBe(true);
|
|
36
39
|
});
|
|
37
40
|
|
|
38
41
|
it("needs an explicit authorization for an explicit question", () => {
|
|
@@ -43,6 +46,16 @@ describe("classifyQuestionRisk", () => {
|
|
|
43
46
|
|
|
44
47
|
expect(risk.requiresExplicitAuthorization).toBe(true);
|
|
45
48
|
});
|
|
49
|
+
|
|
50
|
+
it("needs an explicit authorization for a risky approval question", () => {
|
|
51
|
+
const risk = classifyQuestionRisk({
|
|
52
|
+
kind: "approval",
|
|
53
|
+
text: "Want me to remove the old config file now?",
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
expect(risk.requiresExplicitAuthorization).toBe(true);
|
|
57
|
+
expect(risk.destructive).toBe(true);
|
|
58
|
+
});
|
|
46
59
|
});
|
|
47
60
|
|
|
48
61
|
describe("a destructive action", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/provider-router",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.404",
|
|
4
4
|
"description": "Enhanced Provider Router for pi-harness-runtime — intelligent routing with capabilities, costs, and quotas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/provider-router.js",
|