Skip to content

feat: Add @RequiresConsent annotation for tool execution consent mana… #3848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

academey
Copy link

Summary

  • Implements @RequiresConsent annotation for human-in-the-loop tool execution
  • Adds comprehensive consent management framework with flexible strategies
  • Enhances AI safety by requiring user approval for sensitive operations

Details

This PR addresses issue #3813 by introducing a declarative way to require user consent before executing potentially sensitive tool operations. The implementation follows Spring AI's existing patterns and integrates seamlessly with the current tool calling mechanism.

Key Features:

  1. @RequiresConsent Annotation: Declarative consent requirements with customizable messages and levels
  2. Flexible Consent Levels: EVERY_TIME, SESSION, and REMEMBER options for different use cases
  3. ConsentManager Interface: Pluggable consent handling strategies (UI prompts, API calls, etc.)
  4. Parameter Substitution: Dynamic consent messages with parameter placeholders
  5. Category-based Consent: Group related tools for consent management

Implementation:

  • @RequiresConsent: Main annotation for marking tools requiring consent
  • ConsentManager: Strategy interface for handling consent requests
  • ConsentAwareToolCallback: Decorator pattern for enforcing consent
  • DefaultConsentManager: Reference implementation with in-memory storage
  • ConsentDeniedException: Proper error handling when consent is denied

Example Usage:

@Tool(description = "Deletes a book from the database")
@RequiresConsent(
    message = "The book {bookId} will be permanently deleted. Do you approve?",
    level = ConsentLevel.EVERY_TIME
)
public void deleteBook(String bookId) {
    // Implementation
}

Test Plan

  • Unit tests for ConsentAwareToolCallback
  • Unit tests for DefaultConsentManager
  • Integration tests demonstrating usage patterns
  • Tests for parameter substitution in consent messages
  • Tests for different consent levels and categories

Breaking Changes

None - this is a purely additive feature that doesn't affect existing functionality.

Future Enhancements

  • Auto-configuration support for ConsentManager beans
  • UI components for web-based consent prompts
  • Audit logging for consent decisions
  • Integration with Spring Security for consent policies

Fixes #3813

…gement

This commit introduces a comprehensive consent management framework for Spring AI
tool execution, allowing tools to require user approval before running potentially
sensitive operations.

Changes:
- Add @RequiresConsent annotation with configurable consent levels (EVERY_TIME, SESSION, REMEMBER)
- Implement ConsentManager interface for flexible consent handling strategies
- Add ConsentAwareToolCallback decorator to enforce consent requirements
- Provide DefaultConsentManager with in-memory consent storage
- Add ConsentAwareMethodToolCallbackProvider for seamless integration
- Include comprehensive test coverage for all components
- Add ConsentDeniedException for proper error handling

This feature enhances AI safety by enabling human-in-the-loop control for
critical tool operations like data deletion or financial transactions.

Example usage:
@tool(description = "Deletes a book")
@RequiresConsent(message = "Delete book {bookId}?", level = ConsentLevel.EVERY_TIME)
public void deleteBook(String bookId) { ... }

Fixes spring-projects#3813

Signed-off-by: academey <[email protected]>
Signed-off-by: Hyunjoon Park <[email protected]>
@academey academey force-pushed the feature/issue-3813-requires-consent branch from 9baf4c5 to aeb3b9d Compare July 18, 2025 12:08
@YunKuiLu
Copy link
Contributor

In the User-Controlled Tool Execution , it's also supports human-in-the-loop tool execution.

But you provided a higher-level way to support it, and if it simplifies development, it would make a good feature

However, I noticed that the PR doesn't include any changes related to internalToolExecutionEnabled=false. Could you confirm whether this needs to be modified in the PR?

@academey academey force-pushed the feature/issue-3813-requires-consent branch 3 times, most recently from aec9cf5 to 508451f Compare July 19, 2025 10:50
@academey
Copy link
Author

In the User-Controlled Tool Execution , it's also supports human-in-the-loop tool execution.

But you provided a higher-level way to support it, and if it simplifies development, it would make a good feature

However, I noticed that the PR doesn't include any changes related to internalToolExecutionEnabled=false. Could you confirm whether this needs to be modified in the PR?

@YunKuiLu Thank you for the excellent feedback! You're absolutely right. the @RequiresConsent feature should integrate with the existing User-Controlled Tool Execution mechanism.

So I've implemented the integration in commit. The key changes are

  1. Modified DefaultToolCallingManager.executeToolCall() to detect ConsentAwareToolCallback instances and handle them appropriately, even when internalToolExecutionEnabled=false.

  2. Added comprehensive tests in DefaultToolCallingManagerConsentTests to verify consent works correctly in manual execution mode.

This ensures that when users have manual tool execution enabled for human-in-the-loop control, they will still get consent prompts for tools marked with @RequiresConsent.

The implementation maintains backward compatibility while extending the consent framework to work seamlessly with both automatic and manual execution modes.

- Modified DefaultToolCallingManager to check for ConsentAwareToolCallback instances
- Updated ConsentAwareToolCallback to use ToolCallback interface correctly
- Added tests to verify consent works in manual execution mode

This ensures @RequiresConsent annotation is respected in both automatic and manual modes when internalToolExecutionEnabled=false.

Signed-off-by: Hyunjoon Park <[email protected]>
@academey academey force-pushed the feature/issue-3813-requires-consent branch from 508451f to 916a5c0 Compare July 19, 2025 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enhance Spring AI Tool Calling with @RequiresConsent
2 participants