agentscope-ai / agentscope-ai/QwenPaw

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

Offen
#7,436 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
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

Beitragsleitfaden öffnen

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

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.