agentscope-ai / agentscope-ai/agentscope-java

[Feature]: Built-in ask_user tool - model-initiated questions to the user (HITL ask direction)

Ouverte
#2,860 5 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Java
Étoiles
5.6k
Forks
1.3k
Merge moyen
4 j 12 h
PR mergées (30 j)
77

Description

## Feature: Built-in `ask_user` tool — let the model proactively ask the user structured questions (HITL "ask" direction)

### Problem

AgentScope's HITL is currently **one-directional**: the *user* decides whether a *tool* may run (permission ALLOW/DENY/ASK, `RequireUserConfirmEvent`, `GenerateReason.PERMISSION_ASKING`). There is no way for the **model** to proactively request *information* from the user during a run.

This is a standard capability in current coding-agent products:

| Product | Mechanism |
|---|---|
| OpenAI Codex CLI | `request_user_input` (id/header/question/isOther/isSecret/options, isBlocking + autoResolutionMs) |
| Claude Code / Agent SDK | `AskUserQuestion` tool (questions + choices, "type your own answer if none fit") |
| Cline | AskUserQuestion TUI (options + trailing free-text input row) |
| DeepSeek Harness | `ask_user_question` (questions/options/multi_select + custom free text) |

Open issues already asking for the "give new information to the agent" direction:
- agentscope-ai/agentscope#1120 — "[human in loop] how to interrupt the agent flow and give a confirm/**new information** to the agent to continue the flow"
- agentscope-ai/agentscope#926 — "[Feature]: human in loop wanted"
- agentscope-ai/agentscope-java#2168 — "[Bug]: Fail to continue Human-in-the-Loop"

### Proposed design

A framework-first-class, opt-in capability:

1. **New permission decision signal** — `PermissionBehavior.ASK_USER` + `PermissionDecision.askUser(...)`. It is produced only by a tool's own `checkPermissions()` (i.e. the bypass-immune tool-check phase), so it interrupts in **every** `PermissionMode` (incl. `BYPASS`), and is not registerable as a rule.
2. **Built-in `AskUserTool`** (registered by `HarnessAgent.Builder.enableAskUser()`) exposing a JSON-schema'd `ask_user` tool: `questions[] {id, header, question, type: single|multiple|free|secret, options[], required}`, batch questions in one tool call, `required` skip support.
3. **Distinct interrupt semantics** — `GenerateReason.ASK_USER_ASKING` (parallel to `PERMISSION_ASKING`), new `RequireUserAskEvent` (parallel to `RequireUserConfirmEvent`, carries the pending `ToolUseBlock`s with the questions). The tool is **never executed**; the framework pauses, the caller renders the questions, then resumes with answers.
4. **First-class resume** — new `AskUserResult` + `Msg.METADATA_ASK_USER_RESULTS` (parallel to `ConfirmResult` / `METADATA_CONFIRM_RESULTS`); the framework formats the answers into the `ask_user` tool result itself, so the next reasoning iteration reads the user's answers without re-executing the tool. Streaming gets `UserAskResultEvent` for correlation.

### Scope

- `agentscope-core`: decision signal, gate routing, new event(s), `GenerateReason`, resume payload handling (parallel to the existing `PERMISSION_ASKING` machinery).
- `agentscope-harness`: `AskUserTool` + `enableAskUser()` builder switch (opt-in, default off).
- Documentation + runnable example + tests (incl. BYPASS-mode interrupt, multi-question batch, skip semantics, resume-does-not-execute).

### Non-goals (for this PR)

- No AG-UI / protocol bridging (that's app-layer work).
- No secret masking policy, prompt-segment engineering, or question frequency limits — these are host-application concerns.

### API sketch

```java
HarnessAgent agent = HarnessAgent.builder()
.model(model)
.enableAskUser() // registers ask_user into the toolkit
.build();
```

```java
// call returns Msg with GenerateReason.ASK_USER_ASKING;
// subsequent agent.call(List.of(resumeMsg)) with
// Msg.METADATA_ASK_USER_RESULTS = List.of(new AskUserResult(toolCallId, answers))
// continues the run; the ask_user call is not executed.
```

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.