Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Human action confirmation #592

Copy link
Copy link
@ssu-atl

Description

@ssu-atl
Issue body actions

Hello adk-java team.

Q1:
I noticed that boolean and advance action confirmation for tool calls is available in the adk-python, but not quite yet in adk-java. I also stumble across #531 which looks like there are some ongoing work to support this feature.

Was wondering whether this feature will be coming in the next release of adk-java and when that will be?

Q2:
Are there alternative ways currently to implement HITL tool confirmation in adk-java, if so what would be the recommended approach?

I did manage to replicate similar behaviour as the feature in adk-python using a before tool callback hook.

public class ConfirmationToolCallback implements Callbacks.BeforeToolCallback {

    private final String toolName;

    public ConfirmationToolCallback(String functionName) {
        this.toolName = functionName;
    }

    @Override
    public Maybe<Map<String, Object>> call(InvocationContext invocationContext, BaseTool baseTool, Map<String, Object> input, ToolContext toolContext) {
        if (!toolName.equals(baseTool.name())) {
            return Maybe.empty();
        }

        boolean hasApproveFunctionResponse = invocationContext.userContent()
                .map(userContent -> userContent.parts().stream()
                        .flatMap(Collection::stream)
                        .map(Part::functionResponse)
                        .anyMatch(response -> response.flatMap(FunctionResponse::name).orElse("").equals("approved_function_call")))
                .orElse(false);

        if (!hasApproveFunctionResponse) {
            invocationContext.sessionService()
                    .appendEvent(invocationContext.session(),
                            Event.builder().author(invocationContext.agent().name()).content(
                                    Content.fromParts(
                                            Part.builder()
                                                    .functionCall(
                                                            FunctionCall.builder()
                                                                    .id(UUID.randomUUID().toString())
                                                                    .name("approved_function_call")
                                                                    .build()
                                                    )
                                                    .build()
                                    )
                            ).build()
                    );
            return Maybe.just(Map.of("error", "Please approve or reject the tool call"));
        }

        return Maybe.empty();
    }
}

and the user would confirm and resume the execution using

runner.runAsync(USER_ID, session.id(), Content.fromParts(
    Part.builder()
        functionResponse(
             FunctionResponse.builder()
                  .id(functionId)
                  .name("approved_function_call")
                  .response(Map.of("confirmed", true))
                  .build()
          )
    .build()
));

However, I'm not sure if this is heading down the right path or I should use session state to manage the HITL flows.

Thanks in advance!

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requestedFurther information is requested

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.