claude-token-saver 3.4.1 → 3.4.2
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/session-records.js +19 -1
package/package.json
CHANGED
package/src/session-records.js
CHANGED
|
@@ -32,6 +32,24 @@ function contentText(content) {
|
|
|
32
32
|
const MUTATING_TOOLS = new Set(['Edit', 'Write', 'NotebookEdit', 'Bash']);
|
|
33
33
|
const DELEGATION_TOOLS = new Set(['Task', 'Agent']);
|
|
34
34
|
|
|
35
|
+
// Permission rejections and harness policy denials arrive as is_error
|
|
36
|
+
// tool_results, but they encode the user's choice / the permission system's
|
|
37
|
+
// policy, not task difficulty — counting them poisons the rule-health error
|
|
38
|
+
// rate. Measured on a 14-day window: 6 user rejections + ~29 auto-mode
|
|
39
|
+
// classifier denials out of 142 is_error results (~25% of the numerator).
|
|
40
|
+
const REJECTION_RE = /doesn't want to proceed|tool use was rejected|doesn't want to take this action|denied by the claude code auto mode classifier|permission for this action was denied|requires approval/i;
|
|
41
|
+
|
|
42
|
+
function toolResultText(content) {
|
|
43
|
+
if (typeof content === 'string') return content;
|
|
44
|
+
if (!Array.isArray(content)) return '';
|
|
45
|
+
return content.map((b) => (b && typeof b.text === 'string' ? b.text : '')).join(' ');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isRealToolError(block) {
|
|
49
|
+
return block && block.type === 'tool_result' && block.is_error &&
|
|
50
|
+
!REJECTION_RE.test(toolResultText(block.content));
|
|
51
|
+
}
|
|
52
|
+
|
|
35
53
|
export async function collectSessionRecords(filePath, { includeContent = true } = {}) {
|
|
36
54
|
const records = new Map();
|
|
37
55
|
let depth = 0;
|
|
@@ -62,7 +80,7 @@ export async function collectSessionRecords(filePath, { includeContent = true }
|
|
|
62
80
|
// follows the assistant call — attribute them to that call's record.
|
|
63
81
|
if (lastRecord && Array.isArray(msg.content)) {
|
|
64
82
|
for (const b of msg.content) {
|
|
65
|
-
if (b
|
|
83
|
+
if (isRealToolError(b)) lastRecord.toolErrors += 1;
|
|
66
84
|
}
|
|
67
85
|
}
|
|
68
86
|
continue;
|