dsh-llm-verifier 0.6.8 → 0.7.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/lib/{auto-DmyrNZXK.js → auto-b3qPKifm.js} +155 -6
- package/lib/auto-b3qPKifm.js.map +1 -0
- package/lib/client.js +3 -3
- package/lib/client.js.map +1 -1
- package/lib/core.js +3 -3
- package/lib/core.js.map +1 -1
- package/lib/index.js +16 -8
- package/lib/index.js.map +1 -1
- package/lib/replay.js +1 -1
- package/lib/types/auto.d.ts +19 -0
- package/lib/types/auto.d.ts.map +1 -1
- package/lib/types/auto.js +181 -12
- package/lib/types/auto.js.map +1 -1
- package/lib/types/core.js +3 -3
- package/lib/types/core.js.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +15 -5
- package/lib/types/index.js.map +1 -1
- package/lib/types/pricing.d.ts +1 -1
- package/lib/types/pricing.d.ts.map +1 -1
- package/lib/types/pricing.js +2 -1
- package/lib/types/pricing.js.map +1 -1
- package/package.json +1 -1
- package/src/auto.test.ts +82 -2
- package/src/auto.ts +181 -13
- package/src/core.ts +3 -3
- package/src/index.test.ts +46 -0
- package/src/index.ts +15 -5
- package/src/pricing.ts +2 -1
- package/lib/auto-DmyrNZXK.js.map +0 -1
|
@@ -361,7 +361,7 @@ function blockText$1(blocks) {
|
|
|
361
361
|
* @param blocks - content blocks of an `assistant/message` event.
|
|
362
362
|
* @returns The joined text, trimmed.
|
|
363
363
|
*/
|
|
364
|
-
function narrativeText(blocks) {
|
|
364
|
+
function narrativeText$1(blocks) {
|
|
365
365
|
const parts = [];
|
|
366
366
|
const visit = (items) => {
|
|
367
367
|
for (const block of items) if (block.type === "text") parts.push(block.text);
|
|
@@ -433,7 +433,7 @@ function buildEvidenceIndex(events) {
|
|
|
433
433
|
}
|
|
434
434
|
} else if (event.type === "assistant/message") {
|
|
435
435
|
const blocks = event.data?.message?.content ?? event.data?.content;
|
|
436
|
-
const text = narrativeText(Array.isArray(blocks) ? blocks : []);
|
|
436
|
+
const text = narrativeText$1(Array.isArray(blocks) ? blocks : []);
|
|
437
437
|
if (text) narration = {
|
|
438
438
|
seq: event.seq,
|
|
439
439
|
text
|
|
@@ -1770,13 +1770,22 @@ const PASSIVE_TOOLS = /* @__PURE__ */ new Set([
|
|
|
1770
1770
|
"glob",
|
|
1771
1771
|
"grep",
|
|
1772
1772
|
"web_search",
|
|
1773
|
+
"web_fetch",
|
|
1773
1774
|
"ssh_list",
|
|
1774
1775
|
"job_list",
|
|
1775
1776
|
"job_output",
|
|
1776
1777
|
"list_agents",
|
|
1778
|
+
"list_subagent_models",
|
|
1779
|
+
"list_mcp_resources",
|
|
1780
|
+
"list_mcp_resource_templates",
|
|
1781
|
+
"read_mcp_resource",
|
|
1777
1782
|
"get_goal",
|
|
1778
1783
|
"skill",
|
|
1779
|
-
"mcp__codegraph__codegraph_explore"
|
|
1784
|
+
"mcp__codegraph__codegraph_explore",
|
|
1785
|
+
"ask_user_question",
|
|
1786
|
+
"todo_write",
|
|
1787
|
+
"present",
|
|
1788
|
+
"run_code"
|
|
1780
1789
|
]);
|
|
1781
1790
|
const VERIFIER_TOOLS = /* @__PURE__ */ new Set([
|
|
1782
1791
|
"verifier_compare",
|
|
@@ -1790,7 +1799,6 @@ const CONSEQUENTIAL_TOOLS = /* @__PURE__ */ new Set([
|
|
|
1790
1799
|
"write",
|
|
1791
1800
|
"pwsh",
|
|
1792
1801
|
"bash",
|
|
1793
|
-
"run_code",
|
|
1794
1802
|
"codex_image_generate",
|
|
1795
1803
|
"ssh_exec",
|
|
1796
1804
|
"ssh_upload",
|
|
@@ -1993,6 +2001,126 @@ function hasPendingSubagents(events, taskStartSeq) {
|
|
|
1993
2001
|
}
|
|
1994
2002
|
return pendingContinuable.size > 0 || pendingJobs.size > 0 || anonymousPendingCount > 0;
|
|
1995
2003
|
}
|
|
2004
|
+
function parseArgumentsObject(value) {
|
|
2005
|
+
if (typeof value === "string") try {
|
|
2006
|
+
const parsed = JSON.parse(value);
|
|
2007
|
+
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
2008
|
+
} catch {
|
|
2009
|
+
return {};
|
|
2010
|
+
}
|
|
2011
|
+
return typeof value === "object" && value !== null ? value : {};
|
|
2012
|
+
}
|
|
2013
|
+
const USER_QUESTION_PATTERNS = [
|
|
2014
|
+
/[??]\s*["'))』」]*\s*$/u,
|
|
2015
|
+
/(?:请|麻烦您?)(?:告知|确认|指示|选择|提供|决定|回复)/u,
|
|
2016
|
+
/(?:等待|静待|等)(?:您的|你的|您|你|用户)?(?:确认|指示|回复|决定|指令|反馈|选择|输入)/u,
|
|
2017
|
+
/(?:如果您?|如|若)(?:希望|需要|想)(?:继续|执行).*(?:请|告诉我|告知)/u,
|
|
2018
|
+
/(?:是否|要不要|可否)(?:需要我?|继续|同意|允许|采用).*[??]?/u,
|
|
2019
|
+
/(?:暂时|先|已)?暂停(?:工作|执行|后续).*(?:等|指示|确认|决定|用户)/u,
|
|
2020
|
+
/\b(?:please\s+(?:confirm|let\s+me\s+know|advise|choose|select|provide|indicate|tell\s+me|reply))\b/iu,
|
|
2021
|
+
/\b(?:waiting\s+for|awaiting)\s+(?:your\s+|user\s+)?(?:input|instructions?|reply|response|confirmation|decision|guidance|feedback)\b/iu,
|
|
2022
|
+
/\b(?:would\s+you\s+like|should\s+i|do\s+you\s+want\s+me\s+to|how\s+would\s+you\s+like|which\s+(?:option|approach|strategy)\s+do\s+you\s+prefer)\b/iu,
|
|
2023
|
+
/\b(?:let\s+me\s+know\s+(?:how|what|if|whether|when))\b/iu,
|
|
2024
|
+
/\b(?:paused?\s+(?:work|execution|here|for\s+now)|stopping\s+here)\b/iu
|
|
2025
|
+
];
|
|
2026
|
+
function isAwaitingUserText(text) {
|
|
2027
|
+
const trimmed = text.trim();
|
|
2028
|
+
if (!trimmed) return false;
|
|
2029
|
+
const lastLine = trimmed.split("\n").filter((l) => l.trim()).at(-1) ?? "";
|
|
2030
|
+
return USER_QUESTION_PATTERNS.some((p) => p.test(lastLine) || p.test(trimmed));
|
|
2031
|
+
}
|
|
2032
|
+
function narrativeText(blocks) {
|
|
2033
|
+
if (typeof blocks === "string") return blocks.trim();
|
|
2034
|
+
if (!Array.isArray(blocks)) return "";
|
|
2035
|
+
const parts = [];
|
|
2036
|
+
for (const block of blocks) if (block?.type === "text" && typeof block.text === "string") parts.push(block.text);
|
|
2037
|
+
else if (block?.type === "tool-result") parts.push(blockText(block.content));
|
|
2038
|
+
return parts.join("\n").trim();
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Whether the agent has paused to ask the user a question, obtain confirmation, or await user instructions.
|
|
2042
|
+
*
|
|
2043
|
+
* During task execution, an agent may legitimately pause to ask the operator a question
|
|
2044
|
+
* (e.g. calling `ask_user_question`, pausing/blocking a goal, or concluding a turn with prose
|
|
2045
|
+
* awaiting user guidance). Gating or steering in this state forces the model to keep executing,
|
|
2046
|
+
* overriding the user interaction boundary and locking the user out of providing guidance.
|
|
2047
|
+
*
|
|
2048
|
+
* Returns undefined when the work has already reached its delivery phase (all todos completed
|
|
2049
|
+
* with verification evidence), because in that state the agent is delivering the task rather than
|
|
2050
|
+
* pausing for input.
|
|
2051
|
+
*/
|
|
2052
|
+
function inspectUserInteractionPause(events, taskStartSeq, currentTurn) {
|
|
2053
|
+
const delivery = inspectDeliveryPhase(events);
|
|
2054
|
+
if (delivery?.todosComplete && delivery.verification !== void 0) return;
|
|
2055
|
+
let turnEvents = events;
|
|
2056
|
+
if (currentTurn !== void 0) {
|
|
2057
|
+
const turnStartIndex = events.findLastIndex((e) => e.type === "turn/start" && e.data.turn === currentTurn);
|
|
2058
|
+
if (turnStartIndex >= 0) turnEvents = events.slice(turnStartIndex);
|
|
2059
|
+
else {
|
|
2060
|
+
const byTurn = events.filter((e) => e.data?.turn === currentTurn);
|
|
2061
|
+
if (byTurn.length > 0) turnEvents = byTurn;
|
|
2062
|
+
}
|
|
2063
|
+
} else {
|
|
2064
|
+
const lastTurnStart = events.findLastIndex((e) => e.type === "turn/start");
|
|
2065
|
+
if (lastTurnStart >= 0) turnEvents = events.slice(lastTurnStart);
|
|
2066
|
+
}
|
|
2067
|
+
let lastAskUserSeq = -1;
|
|
2068
|
+
for (const event of turnEvents) if (event.type === "tool/call") {
|
|
2069
|
+
if (event.data.name === "ask_user_question") lastAskUserSeq = Math.max(lastAskUserSeq, event.seq);
|
|
2070
|
+
} else if (CODE_DISPATCH_TYPES.has(event.type)) {
|
|
2071
|
+
if (event.data?.name === "ask_user_question") lastAskUserSeq = Math.max(lastAskUserSeq, event.seq);
|
|
2072
|
+
}
|
|
2073
|
+
if (lastAskUserSeq >= 0) {
|
|
2074
|
+
if (!turnEvents.some((event) => {
|
|
2075
|
+
if (event.seq <= lastAskUserSeq) return false;
|
|
2076
|
+
if (event.type === "tool/call") return isConsequential(event.data.name);
|
|
2077
|
+
if (CODE_DISPATCH_TYPES.has(event.type)) {
|
|
2078
|
+
const data = event.data;
|
|
2079
|
+
return data ? isConsequential(data.name) : false;
|
|
2080
|
+
}
|
|
2081
|
+
return false;
|
|
2082
|
+
})) return {
|
|
2083
|
+
paused: true,
|
|
2084
|
+
reason: "ask_user_question in current turn"
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2087
|
+
const taskEvents = events.filter((e) => e.seq >= taskStartSeq);
|
|
2088
|
+
let goalPhase;
|
|
2089
|
+
for (const event of taskEvents) if (event.type === "tool/call") {
|
|
2090
|
+
const call = event;
|
|
2091
|
+
if (call.data.name === "update_goal") {
|
|
2092
|
+
const args = parseArgumentsObject(call.data.arguments);
|
|
2093
|
+
if (args.action === "pause") goalPhase = "paused";
|
|
2094
|
+
else if (args.action === "blocked") goalPhase = "blocked";
|
|
2095
|
+
else if (args.action === "resume") goalPhase = "active";
|
|
2096
|
+
else if (args.action === "complete") goalPhase = "complete";
|
|
2097
|
+
}
|
|
2098
|
+
} else if (CODE_DISPATCH_TYPES.has(event.type)) {
|
|
2099
|
+
const data = event.data;
|
|
2100
|
+
if (data?.name === "update_goal") {
|
|
2101
|
+
const args = parseArgumentsObject(data.arguments);
|
|
2102
|
+
if (args.action === "pause") goalPhase = "paused";
|
|
2103
|
+
else if (args.action === "blocked") goalPhase = "blocked";
|
|
2104
|
+
else if (args.action === "resume") goalPhase = "active";
|
|
2105
|
+
else if (args.action === "complete") goalPhase = "complete";
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
if (goalPhase === "paused" || goalPhase === "blocked") return {
|
|
2109
|
+
paused: true,
|
|
2110
|
+
reason: "goal is " + goalPhase
|
|
2111
|
+
};
|
|
2112
|
+
const lastAssistant = turnEvents.filter((e) => e.type === "assistant/message").at(-1);
|
|
2113
|
+
if (lastAssistant && lastAssistant.type === "assistant/message") {
|
|
2114
|
+
const content = lastAssistant.data.message?.content ?? [];
|
|
2115
|
+
if (!content.some((b) => b.type === "tool-call")) {
|
|
2116
|
+
const text = narrativeText(content);
|
|
2117
|
+
if (text && isAwaitingUserText(text)) return {
|
|
2118
|
+
paused: true,
|
|
2119
|
+
reason: "assistant awaiting user instructions"
|
|
2120
|
+
};
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
1996
2124
|
function analyzeAutoTask(events, policy, sessionId) {
|
|
1997
2125
|
const taskStartSeq = latestDirectUserSeq(events);
|
|
1998
2126
|
if (taskStartSeq === void 0) return {
|
|
@@ -2003,6 +2131,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2003
2131
|
hasManualSessionVerification: false,
|
|
2004
2132
|
manualVerificationAccepted: false,
|
|
2005
2133
|
pendingSubagents: false,
|
|
2134
|
+
pendingUserInteraction: false,
|
|
2006
2135
|
eligible: false,
|
|
2007
2136
|
reason: "no-direct-user-task"
|
|
2008
2137
|
};
|
|
@@ -2061,6 +2190,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2061
2190
|
}, policy.threshold) && !stale(verdict.toSeq);
|
|
2062
2191
|
});
|
|
2063
2192
|
const pendingSubagents = hasPendingSubagents(events, taskStartSeq);
|
|
2193
|
+
const pendingUserInteraction = inspectUserInteractionPause(events, taskStartSeq) !== void 0;
|
|
2064
2194
|
if (policy.mode === "manual") return {
|
|
2065
2195
|
taskStartSeq,
|
|
2066
2196
|
toolCalls,
|
|
@@ -2069,6 +2199,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2069
2199
|
hasManualSessionVerification,
|
|
2070
2200
|
manualVerificationAccepted,
|
|
2071
2201
|
pendingSubagents,
|
|
2202
|
+
pendingUserInteraction,
|
|
2072
2203
|
eligible: false,
|
|
2073
2204
|
reason: "manual-mode"
|
|
2074
2205
|
};
|
|
@@ -2080,6 +2211,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2080
2211
|
hasManualSessionVerification,
|
|
2081
2212
|
manualVerificationAccepted,
|
|
2082
2213
|
pendingSubagents,
|
|
2214
|
+
pendingUserInteraction,
|
|
2083
2215
|
eligible: false,
|
|
2084
2216
|
reason: "already-verified"
|
|
2085
2217
|
};
|
|
@@ -2091,9 +2223,22 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2091
2223
|
hasManualSessionVerification,
|
|
2092
2224
|
manualVerificationAccepted,
|
|
2093
2225
|
pendingSubagents: true,
|
|
2226
|
+
pendingUserInteraction,
|
|
2094
2227
|
eligible: false,
|
|
2095
2228
|
reason: "pending-subagents"
|
|
2096
2229
|
};
|
|
2230
|
+
if (pendingUserInteraction) return {
|
|
2231
|
+
taskStartSeq,
|
|
2232
|
+
toolCalls,
|
|
2233
|
+
completedToolResults,
|
|
2234
|
+
consequentialToolCalls,
|
|
2235
|
+
hasManualSessionVerification,
|
|
2236
|
+
manualVerificationAccepted,
|
|
2237
|
+
pendingSubagents,
|
|
2238
|
+
pendingUserInteraction: true,
|
|
2239
|
+
eligible: false,
|
|
2240
|
+
reason: "user-interaction-paused"
|
|
2241
|
+
};
|
|
2097
2242
|
if (consequentialToolCalls === 0) return {
|
|
2098
2243
|
taskStartSeq,
|
|
2099
2244
|
toolCalls,
|
|
@@ -2102,6 +2247,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2102
2247
|
hasManualSessionVerification,
|
|
2103
2248
|
manualVerificationAccepted,
|
|
2104
2249
|
pendingSubagents,
|
|
2250
|
+
pendingUserInteraction,
|
|
2105
2251
|
eligible: false,
|
|
2106
2252
|
reason: "no-consequential-work"
|
|
2107
2253
|
};
|
|
@@ -2113,6 +2259,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2113
2259
|
hasManualSessionVerification,
|
|
2114
2260
|
manualVerificationAccepted,
|
|
2115
2261
|
pendingSubagents,
|
|
2262
|
+
pendingUserInteraction,
|
|
2116
2263
|
eligible: false,
|
|
2117
2264
|
reason: "no-completed-evidence"
|
|
2118
2265
|
};
|
|
@@ -2124,6 +2271,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2124
2271
|
hasManualSessionVerification,
|
|
2125
2272
|
manualVerificationAccepted,
|
|
2126
2273
|
pendingSubagents,
|
|
2274
|
+
pendingUserInteraction,
|
|
2127
2275
|
eligible: false,
|
|
2128
2276
|
reason: "insufficient-tool-evidence"
|
|
2129
2277
|
};
|
|
@@ -2135,6 +2283,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2135
2283
|
hasManualSessionVerification,
|
|
2136
2284
|
manualVerificationAccepted,
|
|
2137
2285
|
pendingSubagents,
|
|
2286
|
+
pendingUserInteraction,
|
|
2138
2287
|
eligible: true,
|
|
2139
2288
|
reason: policy.mode + "-eligible"
|
|
2140
2289
|
};
|
|
@@ -2302,6 +2451,6 @@ function selectRouteFeedbackDetail(candidates, result, maxChars = MAX_ROUTE_FEED
|
|
|
2302
2451
|
].join("\n"));
|
|
2303
2452
|
}
|
|
2304
2453
|
//#endregion
|
|
2305
|
-
export {
|
|
2454
|
+
export { semanticDecision as A, resolveCacheFile as B, inspectDeliveryPhase as C, nextDiagnosticCycleId as D, latestDirectUserSeq as E, extractSession as F, sanitizeVerifierText as I, sessionEvents as L, semanticRouteHint as M, verificationFailed as N, parseSemanticRoute as O, verificationVerdict as P, ScoreCache as R, estimateRoutedCalls as S, itemBudget as T, stableHash as V, analyzeStructuredRoute as _, compareRouteFeedbackDetail as a, buildSemanticRoutePrompt as b, inspectUserInteractionPause as c, selectRouteFeedbackDetail as d, sessionAccepted as f, RECOVERY_FAILURE_CONTEXT_CHARS as g, MAX_ROUTED_CHECKPOINTS as h, automaticFeedback as i, semanticReferencesVisible as j, routedRepeats as k, isAwaitingUserText as l, AutoVerifierRouter as m, PROPOSAL_FEEDBACK_NOTE as n, failedAcceptanceCriteria as o, topScoreIndices as p, analyzeAutoTask as r, hasPendingSubagents as s, MAX_ROUTE_FEEDBACK_CHARS as t, isSubagentSession as u, boundDecision as v, inspectRecoverySignal as w, buildSemanticRouteView as x, buildEvidenceIndex as y, SingleFlight as z };
|
|
2306
2455
|
|
|
2307
|
-
//# sourceMappingURL=auto-
|
|
2456
|
+
//# sourceMappingURL=auto-b3qPKifm.js.map
|