Skip to content

Commit b605517

Browse files
EBrownclaude
andcommitted
fix: reasoning token double-count and permission disabled() specificity
- Token total: remove reasoningTokens from total computation since it's a subset of outputTokens (from completion_tokens_details). Adding both was double-counting reasoning tokens for models like o1/o3. - Permission disabled(): use specificity scoring instead of findLast() so that a specific allow rule (e.g. permission: "edit") beats a catch-all deny (permission: "*"). Consistent with evaluate() fix. Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 21e7a01 commit b605517

2 files changed

Lines changed: 19 additions & 4 deletions

File tree

packages/opencode/src/permission/next.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,22 @@ export namespace PermissionNext {
267267
for (const tool of tools) {
268268
const permission = EDIT_TOOLS.includes(tool) ? "edit" : tool
269269

270-
const rule = ruleset.findLast((r) => Wildcard.match(permission, r.permission))
271-
if (!rule) continue
272-
if (rule.pattern === "*" && rule.action === "deny") result.add(tool)
270+
// Use specificity scoring (consistent with evaluate()) so that a
271+
// specific allow like { permission: "edit" } beats a catch-all
272+
// deny like { permission: "*" }.
273+
let bestRule: Rule | undefined
274+
let bestSpecificity = -1
275+
for (const r of ruleset) {
276+
if (!Wildcard.match(permission, r.permission)) continue
277+
const nonWild = r.permission.replace(/\*/g, "")
278+
const specificity = nonWild.length + (r.permission.includes("*") ? 0 : 100)
279+
if (specificity >= bestSpecificity) {
280+
bestSpecificity = specificity
281+
bestRule = r
282+
}
283+
}
284+
if (!bestRule) continue
285+
if (bestRule.pattern === "*" && bestRule.action === "deny") result.add(tool)
273286
}
274287
return result
275288
}

packages/opencode/src/session/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,9 @@ export namespace Session {
818818
// mismatches across providers. Some providers (OpenRouter, Copilot)
819819
// include cached tokens in totalTokens differently than Anthropic,
820820
// causing inflated counts and premature compaction (#3314).
821-
const total = adjustedInputTokens + outputTokens + reasoningTokens + cacheReadInputTokens + cacheWriteInputTokens
821+
// Note: reasoningTokens is a subset of outputTokens (from
822+
// completion_tokens_details), so it must NOT be added separately.
823+
const total = adjustedInputTokens + outputTokens + cacheReadInputTokens + cacheWriteInputTokens
822824

823825
const tokens = {
824826
total,

0 commit comments

Comments
 (0)