Skip to content

Conversation

@TornadoDragon
Copy link
Contributor

@TornadoDragon TornadoDragon commented Feb 9, 2026

AgentScope-Java Version

1.0.9-SNAPSHOT

Description

Add support for frontend tool calls in agui and update the examples.

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

@TornadoDragon TornadoDragon requested a review from a team February 9, 2026 05:50
@cla-assistant
Copy link

cla-assistant bot commented Feb 9, 2026

CLA assistant check
All committers have signed the CLA.

@gemini-code-assist
Copy link

Summary of Changes

Hello @TornadoDragon, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the AgentScope AG-UI by enabling agents to interact with the client-side browser environment through a new frontend tool calling mechanism. This expands the capabilities of agents, allowing them to perform actions like retrieving browser information, accessing local storage, or reading the clipboard, directly from the user's interface. The changes include new client-side JavaScript for tool management and execution, UI updates to display these tools, and backend logic to integrate these frontend tools seamlessly with the agent's existing toolkit.

Highlights

  • Frontend Tool Call Support: Introduced comprehensive support for frontend tool calls within the AG-UI, allowing agents to invoke browser-side functionalities directly.
  • New Frontend Tools Manager: Added a new JavaScript module (frontend-tools.js) that defines preset browser-interaction tools (e.g., get browser info, local storage, clipboard, current time, page info) and manages their execution.
  • Dynamic Tool Merging: Implemented logic in the AguiRequestProcessor to dynamically merge frontend tool definitions with the agent's existing toolkit, supporting various merging strategies (agent-only, frontend-only, merge with frontend priority).
  • Enhanced AG-UI User Interface: Updated the index.html to include a dedicated 'Frontend Tools Panel' for displaying and managing available client-side tools, complete with quick-add preset buttons.
  • Core Toolkit Extension: Extended the core Toolkit class with a new addToolToGroup method, facilitating more granular control over tool organization.
Changelog
  • agentscope-core/src/main/java/io/agentscope/core/tool/Toolkit.java
    • Added addToolToGroup(String toolName, String groupName) method to Toolkit for programmatic tool group management.
  • agentscope-examples/agui/src/main/resources/static/index.html
    • Introduced a new 'Frontend Tools Panel' UI element with associated CSS styling.
    • Integrated frontend-tools.js for managing client-side tools.
    • Modified agent run logic to pass frontend tool definitions to the backend.
    • Implemented client-side handling for tool call events, including execution and result reporting for frontend tools.
    • Added event listeners and rendering logic for the frontend tools panel, including preset tool buttons.
  • agentscope-examples/agui/src/main/resources/static/js/frontend-tools.js
    • New file: frontend-tools.js.
    • Defines preset frontend tools (e.g., browser info, local storage, clipboard) with their JSON schemas and execution handlers.
    • Introduces FrontendToolsManager class for client-side management, execution, and state tracking of frontend tools.
  • agentscope-extensions/agentscope-extensions-agui/src/main/java/io/agentscope/core/agui/processor/AguiRequestProcessor.java
    • Added logic to AguiRequestProcessor to handle merging of frontend tools with backend agent tools.
    • Implemented mergeToolsForAgent to support different tool merging strategies (AGENT_ONLY, FRONTEND_ONLY, MERGE_FRONTEND_PRIORITY).
    • Extended extractLatestUserMessage to include 'tool' role messages for proper conversation flow after tool execution.
    • Introduced AguiToolConverter for converting frontend tool definitions to backend ToolSchema objects.
Activity
  • The pull request description includes a checklist for code quality and documentation, indicating the author's intention for thoroughness. No other specific activity (comments, reviews) was provided in the context.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces frontend tool call support, a significant feature. The implementation is mostly solid, but there are a few critical bugs in the JavaScript logic for handling tool results that would prevent the feature from working correctly. Additionally, there's significant code duplication in the main HTML file that should be refactored to improve maintainability. I've also noted some smaller issues regarding API clarity in both the Java and JavaScript code. Addressing these points will make the new feature more robust and the codebase easier to maintain.

requestMessages.push({
id: 'tool-result-' + Date.now() + '-' + Math.random(),
role: 'tool',
content: result.content,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

There is a bug here when constructing the tool result message. The result object from pendingToolResults has an output property containing the tool's return value, not a content property. This will result in content being undefined in the request. It should be JSON.stringify(result.output) to match the implementation in sendToolResultMessage.

Suggested change
content: result.content,
content: JSON.stringify(result.output),

id: 'tool-result-' + Date.now() + '-' + Math.random(),
role: 'tool',
content: JSON.stringify(result.output),
toolCallId: result.toolCallId

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The property name for the tool call ID should be tool_call_id to match the snake_case convention expected by the backend and defined in the AguiMessage model. Using toolCallId will likely cause deserialization issues on the server.

Suggested change
toolCallId: result.toolCallId
tool_call_id: result.toolCallId

Comment on lines 695 to 701
onToolCallEnd: (toolCallId) => {
// Tool call completed
// Tool call completed - if it's a frontend tool, execute it
const pendingCall = frontendTools.getPendingCall(toolCallId);
if (pendingCall) {
executeFrontendTool(pendingCall.toolCallId, pendingCall.toolName, pendingCall.parsedArgs);
}
},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The onToolCallEnd callback now executes the frontend tool. However, the sendToolResultMessage function, which is called after tool execution, has significant code duplication with the sendMessage function. Both functions set up and execute a client.run call with nearly identical callbacks. This duplication makes the code harder to maintain.

Consider refactoring the client.run logic into a shared function that can be called by both sendMessage and sendToolResultMessage to avoid repeating the same setup and event handling logic.

case FRONTEND_ONLY -> {

// remove all tool
toolkit.removeToolGroups(toolkit.getActiveGroups());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In FRONTEND_ONLY mode, the goal is to replace all of the agent's tools with those from the frontend. However, toolkit.removeToolGroups(toolkit.getActiveGroups()) only removes active tool groups. Any tools in inactive groups will remain in the toolkit's registry (though their groups will be empty after the next line). This could lead to unexpected behavior and doesn't fully enforce the FRONTEND_ONLY policy.

To correctly clear all tools, you should ensure all groups are removed, not just the active ones. The Toolkit API may need to be extended to support this cleanly (e.g., with a clear() or getAllGroupNames() method).

Comment on lines 561 to 562
* @param groupName Group name
* @param toolName Tool name

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The order of @param tags in the Javadoc does not match the method signature's parameter order. For better readability and consistency, the Javadoc should reflect the (String toolName, String groupName) order.

Suggested change
* @param groupName Group name
* @param toolName Tool name
* @param toolName Tool name
* @param groupName Group name

Comment on lines +765 to +769
setTimeout(() => {
if (!isRunning) {
sendToolResultMessage();
}
}, 500);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using setTimeout with a fixed delay of 500ms to trigger sending tool results is a code smell. It introduces an arbitrary delay and can be unreliable. If the goal is to batch results from multiple tool calls, there might be a more deterministic approach. For example, you could wait for all tool calls in a given turn to complete before sending the results back. The current implementation might be sensitive to timing issues.

let requestMessages = [...messageHistory];
pendingResults.forEach(result => {
requestMessages.push({
id: 'tool-result-' + Date.now() + '-' + Math.random(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using Math.random() to generate part of a message ID is not a robust way to ensure uniqueness, as collisions are possible, although unlikely in this specific context. For a more production-ready example, consider using a library that generates UUIDs (e.g., crypto.randomUUID() which is available in modern browsers/Node.js) or a simple incrementing counter to guarantee unique IDs within the session.

@codecov
Copy link

codecov bot commented Feb 9, 2026

Codecov Report

❌ Patch coverage is 0% with 28 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...cope/core/agui/processor/AguiRequestProcessor.java 0.00% 26 Missing ⚠️
...src/main/java/io/agentscope/core/tool/Toolkit.java 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

* @param toolName Tool name
* @param groupName Group name
*/
public void addToolToGroup(String toolName, String groupName) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add this?

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.

2 participants