MCPcopy Create free account
hub / github.com/Noumena-Network/code / hasPermissionsToUseTool

Function hasPermissionsToUseTool

src/utils/permissions/permissions.ts:477–962  ·  view source on GitHub ↗
(
  tool,
  input,
  context,
  assistantMessage,
  toolUseID,
)

Source from the content-addressed store, hash-verified

475}
476
477export const hasPermissionsToUseTool: CanUseToolFn = async (
478 tool,
479 input,
480 context,
481 assistantMessage,
482 toolUseID,
483): Promise<PermissionDecision> => {
484 const result = await hasPermissionsToUseToolInner(tool, input, context)
485
486
487 // Reset consecutive denials on any allowed tool use in auto mode.
488 // This ensures that a successful tool use (even one auto-allowed by rules)
489 // breaks the consecutive denial streak.
490 if (result.behavior === 'allow') {
491 const appState = context.getAppState()
492 if (feature('TRANSCRIPT_CLASSIFIER')) {
493 const currentDenialState =
494 context.localDenialTracking ?? appState.denialTracking
495 if (
496 appState.toolPermissionContext.mode === 'auto' &&
497 currentDenialState &&
498 currentDenialState.consecutiveDenials > 0
499 ) {
500 const newDenialState = recordSuccess(currentDenialState)
501 persistDenialState(context, newDenialState)
502 }
503 }
504 return result
505 }
506
507 // Apply dontAsk mode transformation: convert 'ask' to 'deny'
508 // This is done at the end so it can't be bypassed by early returns
509 if (result.behavior === 'ask') {
510 const appState = context.getAppState()
511
512 if (appState.toolPermissionContext.mode === 'dontAsk') {
513 return {
514 behavior: 'deny',
515 decisionReason: {
516 type: 'mode',
517 mode: 'dontAsk',
518 },
519 message: DONT_ASK_REJECT_MESSAGE(tool.name),
520 }
521 }
522 // Apply auto mode: use AI classifier instead of prompting user
523 // Check this BEFORE shouldAvoidPermissionPrompts so classifiers work in headless mode
524 if (
525 feature('TRANSCRIPT_CLASSIFIER') &&
526 (appState.toolPermissionContext.mode === 'auto' ||
527 (appState.toolPermissionContext.mode === 'plan' &&
528 (autoModeStateModule?.isAutoModeActive() ?? false)))
529 ) {
530 // Non-classifier-approvable safetyCheck decisions stay immune to ALL
531 // auto-approve paths: the acceptEdits fast-path, the safe-tool allowlist,
532 // and the classifier. Step 1g only guards bypassPermissions; this guards
533 // auto. classifierApprovable safetyChecks (sensitive-file paths) fall
534 // through to the classifier — the fast-paths below naturally don't fire

Callers 10

recheckPermissionFunction · 0.85
assertAllowedFunction · 0.85
assertDeniedFunction · 0.85
canUseToolFunction · 0.85
getCanUseToolFnFunction · 0.85
createCanUseToolMethod · 0.85
useCanUseToolFunction · 0.85
recheckPermissionFunction · 0.85

Calls 15

recordSuccessFunction · 0.85
persistDenialStateFunction · 0.85
DONT_ASK_REJECT_MESSAGEFunction · 0.85
isInProtectedNamespaceFunction · 0.85
setClassifierCheckingFunction · 0.85
classifyYoloActionFunction · 0.85
clearClassifierCheckingFunction · 0.85
isInternalBuildFunction · 0.85

Tested by 2

assertAllowedFunction · 0.68
assertDeniedFunction · 0.68