-
Notifications
You must be signed in to change notification settings - Fork 132
Add action summary feature for tool calls #1339
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
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
23dfa41
Add action summary feature for tool calls
openhands-agent f581cb9
Add enable_action_summaries parameter to conversation initialization
openhands-agent 0f94d49
Remove set_enable_action_summaries method
openhands-agent 314802e
Simplify action summary by always enabling summary field
openhands-agent 2578bed
Make summary field optional and non-blocking
openhands-agent d3c4907
Add examples of good summaries to action summary field description
openhands-agent 3314a05
Generate default summary when LLM doesn't provide one
openhands-agent 680386f
Remove redundant assertion for summary field
openhands-agent 295fd35
Merge main into feature/action-summary
openhands-agent e6c9f4f
Add assertion check for summary field in integration tests
openhands-agent 8260b82
Merge branch 'main' into feature/action-summary
xingyaoww 8e8575f
revert unrelated changes
xingyaoww eebcf21
Remove unnecessary tests for action summary feature
openhands-agent 19927a1
Merge branch 'main' into feature/action-summary
xingyaoww 225c0eb
Increase MCP test timeout to 120s for CI environments
openhands-agent File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,6 +41,7 @@ | |
| ActionT = TypeVar("ActionT", bound=Action) | ||
| ObservationT = TypeVar("ObservationT", bound=Observation) | ||
| _action_types_with_risk: dict[type, type] = {} | ||
| _action_types_with_summary: dict[type, type] = {} | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice with the caching! |
||
|
|
||
|
|
||
| def _camel_to_snake(name: str) -> str: | ||
|
|
@@ -364,17 +365,18 @@ def _get_tool_schema( | |
| action_type: type[Schema] | None = None, | ||
| ) -> dict[str, Any]: | ||
| action_type = action_type or self.action_type | ||
| action_type_with_risk = create_action_type_with_risk(action_type) | ||
|
|
||
| # Apply security risk enhancement if enabled | ||
| add_security_risk_prediction = add_security_risk_prediction and ( | ||
| self.annotations is None or (not self.annotations.readOnlyHint) | ||
| ) | ||
| schema = ( | ||
| action_type_with_risk.to_mcp_schema() | ||
| if add_security_risk_prediction | ||
| else action_type.to_mcp_schema() | ||
| ) | ||
| return schema | ||
| if add_security_risk_prediction: | ||
| action_type = create_action_type_with_risk(action_type) | ||
|
|
||
| # Always add summary field for transparency and explainability | ||
| action_type = _create_action_type_with_summary(action_type) | ||
|
|
||
| return action_type.to_mcp_schema() | ||
|
|
||
| def to_openai_tool( | ||
| self, | ||
|
|
@@ -391,14 +393,19 @@ def to_openai_tool( | |
| action_type: Optionally override the action_type to use for the schema. | ||
| This is useful for MCPTool to use a dynamically created action type | ||
| based on the tool's input schema. | ||
|
|
||
| Note: | ||
| Summary field is always added to the schema for transparency and | ||
| explainability of agent actions. | ||
| """ | ||
| return ChatCompletionToolParam( | ||
| type="function", | ||
| function=ChatCompletionToolParamFunctionChunk( | ||
| name=self.name, | ||
| description=self.description, | ||
| parameters=self._get_tool_schema( | ||
| add_security_risk_prediction, action_type | ||
| add_security_risk_prediction, | ||
| action_type, | ||
| ), | ||
| ), | ||
| ) | ||
|
|
@@ -412,14 +419,23 @@ def to_responses_tool( | |
|
|
||
| For Responses API, function tools expect top-level keys: | ||
| { "type": "function", "name": ..., "description": ..., "parameters": ... } | ||
|
|
||
| Args: | ||
| add_security_risk_prediction: Whether to add a `security_risk` field | ||
| action_type: Optional override for the action type | ||
|
|
||
| Note: | ||
| Summary field is always added to the schema for transparency and | ||
| explainability of agent actions. | ||
| """ | ||
|
|
||
| return { | ||
| "type": "function", | ||
| "name": self.name, | ||
| "description": self.description, | ||
| "parameters": self._get_tool_schema( | ||
| add_security_risk_prediction, action_type | ||
| add_security_risk_prediction, | ||
| action_type, | ||
| ), | ||
| "strict": False, | ||
| } | ||
|
|
@@ -479,3 +495,38 @@ def create_action_type_with_risk(action_type: type[Schema]) -> type[Schema]: | |
| ) | ||
| _action_types_with_risk[action_type] = action_type_with_risk | ||
| return action_type_with_risk | ||
|
|
||
|
|
||
| def _create_action_type_with_summary(action_type: type[Schema]) -> type[Schema]: | ||
| """Create a new action type with summary field for LLM to predict. | ||
|
|
||
| This dynamically adds a 'summary' field to the action schema, allowing | ||
| the LLM to provide a brief explanation of what each action does. | ||
|
|
||
| Args: | ||
| action_type: The original action type to enhance | ||
|
|
||
| Returns: | ||
| A new type that includes the summary field | ||
| """ | ||
| action_type_with_summary = _action_types_with_summary.get(action_type) | ||
| if action_type_with_summary: | ||
| return action_type_with_summary | ||
|
|
||
| action_type_with_summary = type( | ||
| f"{action_type.__name__}WithSummary", | ||
| (action_type,), | ||
| { | ||
| "summary": Field( | ||
| default=None, | ||
| description=( | ||
| "A concise summary (approximately 10 words) describing what " | ||
| "this specific action does. Focus on the key operation and target. " | ||
| "Example: 'List all Python files in current directory'" | ||
| ), | ||
| ), | ||
| "__annotations__": {"summary": str | None}, | ||
| }, | ||
| ) | ||
| _action_types_with_summary[action_type] = action_type_with_summary | ||
| return action_type_with_summary | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.