@jwilger/pi-development-system 0.37.0 → 0.38.1
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/package.json +1 -1
- package/src/context/turn-verifier.ts +33 -6
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
2
2
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { redactSecrets } from "../core/redact.ts";
|
|
4
|
-
import { summarizeOutput } from "../core/test-runner.ts";
|
|
5
|
-
import type { Phase } from "../core/types.ts";
|
|
4
|
+
import { exitCodeOf, summarizeOutput } from "../core/test-runner.ts";
|
|
5
|
+
import type { DevsysState, Phase } from "../core/types.ts";
|
|
6
6
|
import type { Jev } from "../jev/client.ts";
|
|
7
7
|
import { judgeTurn, type ToolEvidence } from "../jev/questions/turn.ts";
|
|
8
8
|
import type { SessionState } from "../state/session-state.ts";
|
|
@@ -44,12 +44,22 @@ export function asksUser(text: string): boolean {
|
|
|
44
44
|
return last !== undefined && /\?(?:\s*\([^()]{0,40}\))?[\s)"'*_`]*$/.test(last);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/** True when a scope.expansion departure already covers the slice: the remedy the note asks for exists. */
|
|
48
|
+
const expansionRecorded = (state: DevsysState, slice: string): boolean =>
|
|
49
|
+
state.openDepartures.some(
|
|
50
|
+
(d) =>
|
|
51
|
+
d.gate === "scope.expansion" &&
|
|
52
|
+
(d.scope.kind === "session" || (d.scope.kind === "slice" && d.scope.slice === slice)),
|
|
53
|
+
);
|
|
54
|
+
|
|
47
55
|
const claimMessage = (): string =>
|
|
48
56
|
"Development system: your last message claims something was run, passed or done, but no tool evidence in this run shows it. Run the verification now, or restate without the claim.";
|
|
49
57
|
|
|
50
58
|
const driftMessage = (slice: string): string =>
|
|
51
59
|
`Development system: your last message describes work beyond the active slice "${slice}". Either return to the slice, or call devsys_record_departure (gate scope.expansion) to record why the scope is growing.`;
|
|
52
60
|
|
|
61
|
+
const TARGET_MAX = 120;
|
|
62
|
+
|
|
53
63
|
const note = (content: string) => ({
|
|
54
64
|
type: "custom_message" as const,
|
|
55
65
|
customType: VERIFIER_ENTRY_TYPE,
|
|
@@ -79,11 +89,26 @@ export function registerTurnVerifier(deps: TurnVerifierDeps): void {
|
|
|
79
89
|
});
|
|
80
90
|
deps.pi.on("tool_result", (event) => {
|
|
81
91
|
const text = event.content.flatMap((c) => (c.type === "text" ? [c.text] : [])).join("\n");
|
|
82
|
-
const summary =
|
|
92
|
+
const summary = summarizeOutput(text);
|
|
93
|
+
const command = typeof event.input.command === "string" ? event.input.command : undefined;
|
|
94
|
+
// exitCodeOf sees through `npm test | tail`, which would otherwise show a failing run as exit 0.
|
|
95
|
+
const exitCode = exitCodeOf({
|
|
96
|
+
isError: event.isError,
|
|
97
|
+
text,
|
|
98
|
+
structured: event.structuredContent,
|
|
99
|
+
...(command === undefined ? {} : { command }),
|
|
100
|
+
});
|
|
101
|
+
// Name what ran or which file: a check that passes silently (`tsc --noEmit`) prints nothing.
|
|
102
|
+
const target = redactSecrets(
|
|
103
|
+
command ?? (typeof event.input.path === "string" ? event.input.path : ""),
|
|
104
|
+
)
|
|
105
|
+
.replace(/\s+/g, " ")
|
|
106
|
+
.slice(0, TARGET_MAX);
|
|
107
|
+
const described = target === "" ? summary : `${target} → ${summary}`;
|
|
83
108
|
const item: ToolEvidence =
|
|
84
109
|
event.toolName === "bash"
|
|
85
|
-
? { tool: "bash", summary, exitCode
|
|
86
|
-
: { tool: event.toolName, summary };
|
|
110
|
+
? { tool: "bash", summary: described, exitCode }
|
|
111
|
+
: { tool: event.toolName, summary: described };
|
|
87
112
|
evidence = [...evidence, item].slice(-MAX_EVIDENCE);
|
|
88
113
|
});
|
|
89
114
|
|
|
@@ -109,7 +134,9 @@ export function registerTurnVerifier(deps: TurnVerifierDeps): void {
|
|
|
109
134
|
if (!judged.ok) return undefined;
|
|
110
135
|
const entries = [
|
|
111
136
|
...(judged.value.unverifiedClaim >= VERIFIER_THRESHOLD ? [note(claimMessage())] : []),
|
|
112
|
-
...(judged.value.driftFromSlice >= VERIFIER_THRESHOLD &&
|
|
137
|
+
...(judged.value.driftFromSlice >= VERIFIER_THRESHOLD &&
|
|
138
|
+
state.activeSlice !== undefined &&
|
|
139
|
+
!expansionRecorded(state, state.activeSlice)
|
|
113
140
|
? [note(driftMessage(state.activeSlice))]
|
|
114
141
|
: []),
|
|
115
142
|
];
|