agentscope-ai / agentscope-ai/QwenPaw
feat: add tool_call_format config for compact tool call display in IM channels
- Vorherrschende Sprache
- TypeScript
- Sterne
- 35k
- Forks
- 3.1k
- Ø Merge
- 1 T. 13 Std.
- Gemergte PRs (30 T.)
- 228
Beschreibung
## 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
Beitragsleitfaden
Rechercherichtung
Start in src/qwenpaw/app/channels/renderer.py by reading ChannelDisplayConfig and the _fmt_tool_call function. Trace how the per-channel channels.feishu configuration reaches the renderer, then verify the full, name_only, and compact outputs across the markdown and emoji cases shown in the issue. Done means the default remains unchanged and each configured mode produces its documented format.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- backend
- Issue-Typ
- Feature
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Aktiv
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 76/100