agentscope-ai / agentscope-ai/QwenPaw

[Feature]: Suppress final text response after tool calls in interactive channels

Abierto
#4,838 2 comentarios 0 reacciones 0 asignados Ver en GitHub
enhancement
Lenguaje dominante
Python
Estrellas
34.9k
Forks
3.1k
Merge medio
1 d 15 h
PR fusionados (30 d)
225

Descripción

# [Feature]: Support suppressing final text response after tool calls in interactive channels

## Summary

Add a channel-level configuration option to suppress the agent's final text response after tool execution completes. This would allow "silent" tool execution where only the tool's output is sent to the user, without the agent's conversational summary.

## Component(s) Affected

- [x] Core / Backend (app, agents, config, providers, utils, local_models)
- [ ] Console (frontend web UI)
- [x] Channels (DingTalk, Feishu, QQ, Discord, iMessage, etc.) — **Telegram, Console**
- [ ] Skills
- [ ] CLI
- [ ] Documentation (website)
- [ ] Tests
- [ ] CI/CD
- [ ] Scripts / Deploy

## Problem / Motivation

Currently, after any tool call completes, the ReAct agent loop sends the tool_result back to the LLM, which generates a final conversational response summarizing the result. This behaviour is hardcoded in `agentscope/_react_agent.py` and cannot be disabled per-channel.

**This blocks legitimate use cases:**

### 1. Voice Reply Pipelines (Primary Use Case)

Users building voice interaction flows (voice → transcribe → TTS → voice reply) receive:
- ✅ Audio file with spoken response
- ❌ Unwanted text caption duplicating the audio content

The text follow-up clutters chat interfaces and cannot be suppressed via prompt engineering ("don't write text, only use the tool") — LLMs consistently ignore this constraint.

### 2. Clean Automated Notifications

Similar to the cron job use case in [#2452](https://github.com/agentscope-ai/QwenPaw/issues/2452), but for **interactive** channels:
- Users bridging QwenPaw to external systems want clean data output
- Conversational filler ("I've completed the search for you...") consumes tokens and clutters logs
- Prompt engineering is unreliable across models

### 3. Multi-Modal Workflows

When a tool produces rich output (image, audio, document), the text summary is often redundant:
- Image generation → user sees the image, doesn't need "Here's your image"
- File creation → user receives the file, doesn't need "I've created the file"

## Related Issues

- **#2452** — [Feature]: Support suppressing Agent's conversational response after script execution in Cron jobs (open, since 2026-03-28)
- This request **generalizes [#2452](https://github.com/agentscope-ai/QwenPaw/issues/2452)** beyond cron jobs to interactive channels
- Same underlying problem: no way to bypass the final LLM response generation step

## Proposed Solution

### 1. Add Channel Configuration Option

Add `suppress_final_response: bool` to channel configs (similar to existing `filter_thinking` and `filter_tool_messages`):

```python
# config.py
class TelegramConfig(BaseChannelConfig):
suppress_final_response: bool = False # New option
filter_thinking: bool = True
filter_tool_messages: bool = True
```

### 2. Patch ReAct Agent Loop

In `agentscope/_react_agent.py`, after receiving tool_result but before sending to LLM for final response:

```python
# Pseudo-code
if channel_config.suppress_final_response and tool_result_received:
# Send tool output directly to channel, skip LLM final response
await channel.send(tool_result.output)
return
else:
# Existing behaviour: send to LLM for summarization
final_response = await llm.generate(tool_result)
await channel.send(final_response)
```

### 3. Console UI Toggle (Optional)

For the Console channel, add a per-session toggle in the chat interface to enable/disable this behaviour.

## Implementation Scope

| Component | Change Required |
|-----------|-----------------|
| `config.py` | Add `suppress_final_response` to channel configs |
| `agentscope/_react_agent.py` | Check flag before final LLM call |
| `channels/telegram.py` | Pass config to renderer |
| `channels/console.py` | Pass config to renderer |
| Other channels | Inherit default (False) |

## Alternatives Considered

### 1. Prompt Engineering
**Tried and failed.** Instructions like "only use the tool, don't write text" are consistently ignored by LLMs across providers (Qwen, GPT, Claude).

### 2. Post-Processing Filters
Existing `filter_tool_messages` only hides tool call metadata, not the final text response. Would need a new filter type that intercepts the final response — essentially the same as the proposed solution.

### 3. Skill-Level Suppression
Skills cannot control the agent loop. The final response happens after the skill returns, in the ReAct coordinator.

## Testing Plan

- [ ] Telegram channel with `suppress_final_response: true` sends only tool output
- [ ] Telegram channel with `suppress_final_response: false` (default) behaves as before
- [ ] Console channel supports the same toggle
- [ ] Other channels inherit default behaviour (no breaking changes)
- [ ] Multi-turn conversations work correctly when suppression is enabled

## Additional Context

**Real-world test case:** Telegram voice pipeline using Edge TTS

```
User: [sends voice message]
→ faster-whisper transcribes to text
→ Agent processes query
→ Edge TTS tool generates audio file
→ Telegram sends audio ✅
→ Telegram sends text caption "Here's your voice reply..." ❌
```

The text caption cannot be suppressed without this feature. We attempted platform-level patches to `agentscope/_react_agent.py` and `qwenpaw/runner/utils.py` but maintaining forked core files is unsustainable.

**Security considerations:** None — this is a presentation-layer feature, not a security boundary. Tool guard/approval systems remain unaffected.

---

## Priority

**Medium-High** — This blocks legitimate voice/multi-modal workflows and forces users to maintain forked core files.

---

*Note: I'm happy to contribute a PR if the maintainers can provide guidance on the preferred implementation approach.*

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.