agentscope-ai / agentscope-ai/QwenPaw

feat: add tool_call_format config for compact tool call display in IM channels

Open
#7,436 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
34.9k
Forks
3.1k
Avg merge
1d 15h
Merged PRs (30d)
225

Description

## Feature Request: Add `tool_call_format` config to control tool call display format

### Problem

Currently, tool call messages in channels (Feishu, DingTalk, etc.) always render with the full format:

```
🔧 **execute_shell_command**
```
{"command": "cd ~/.qwenpaw && python3 -c \"import json; ...\""}
```
```

This is **3 lines per tool call**, which becomes very noisy in IM channels where users want a lightweight progress trace — "I want to know you're alive, not see every argument."

The existing config fields (`show_tool_calls`, `show_tool_details`, `tool_call_max_length`) only control **visibility** and **truncation**, not the **format** itself. There's no way to get a compact single-line output like `🔧 **execute_shell_command**` without patching source code.

### Proposed Solution

Add a new config field `tool_call_format` to `ChannelDisplayConfig`:

```python
@dataclass
class ChannelDisplayConfig:
show_tool_details: bool = True
show_thinking: bool = True
show_tool_calls: bool = True
show_tool_results: bool = True
tool_call_max_length: int = 200
tool_result_max_length: int = 500
tool_call_format: str = "full" # NEW: "full" | "name_only" | "compact"
```

**Format modes:**

| Mode | Output | Use case |
|------|--------|----------|
| `"full"` (default) | `🔧 **name**` + code fence + args | Current behavior, no breaking change |
| `"name_only"` | `🔧 **name**` (single line, no args) | IM channels: lightweight progress trace |
| `"compact"` | `🔧 **name**: {first 80 chars}` | Balance between info and brevity |

**Implementation sketch** (in `renderer.py`):

```python
def _fmt_tool_call(
name: str,
args_preview: str,
style: RenderStyle,
) -> str:
fmt = getattr(style.display_config, "tool_call_format", "full")

if fmt == "name_only":
if style.use_emoji:
return f"🔧 **{name}**"
return f"**{name}**"

if fmt == "compact":
truncated = args_preview[:80] + ("..." if len(args_preview) > 80 else "")
if style.supports_markdown and style.use_emoji:
return f"🔧 **{name}**: `{truncated}`"
if style.supports_markdown:
return f"**{name}**: `{truncated}`"
return f"{name}: {truncated}"

# Default: "full" (current behavior)
if style.supports_markdown and style.use_emoji:
return f"🔧 **{name}**\n```\n{args_preview}\n```"
if style.supports_markdown:
return f"**{name}**\n```\n{args_preview}\n```"
if style.supports_code_fence:
return f"{name}\n```\n{args_preview}\n```"
return f"{name}: {args_preview}"
```

### Why not just `show_tool_details=false`?

I tried that approach. When `show_tool_details=false`, `args_preview` becomes `"..."`, but the code fence is still emitted:

```
🔧 **execute_shell_command**
```
...
```
```

That's still 3 lines with no information gain. The user wants **just the name** — a single line per tool call.

### Config usage

Per-channel config (e.g. `agent.json` → `channels.feishu`):

```json
{
"channels": {
"feishu": {
"tool_call_format": "name_only"
}
}
}
```

### Impact

- **Backward compatible**: Default is `"full"` (current behavior unchanged)
- **Per-channel**: Each channel can choose its own format
- **No global side effects**: Unlike `show_tool_details=false` which affects all channels

### Context

- QwenPaw version: v2.1.0 (installed via pip)
- Affected file: `src/qwenpaw/app/channels/renderer.py`, function `_fmt_tool_call`
- Related config: `ChannelDisplayConfig` in same file
- User scenario: Feishu (Lark) channel where tool call noise degrades mobile UX

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.