agentscope-ai / agentscope-ai/QwenPaw
[Bug]: ACP `trusted: true` silently falls back to interactive prompts — `_pick_allow_option` only matches `allow_*` optionIds
- Lenguaje dominante
- Python
- Estrellas
- 34.9k
- Forks
- 3.1k
- Merge medio
- 1 d 15 h
- PR fusionados (30 d)
- 225
Descripción
**Environment**: QwenPaw 2.2.0 (desktop, macOS arm64); still present on `main` as of 2026-09-05.
**Root cause** (`src/qwenpaw/acp/client.py:32-38, 113-130`):
```python
_ALLOW_OPTION_PREFERENCE = ("allow_once", "allow_always", "allow", "yes", "approve")
# exact lowercase match on optionId; fallback: substring "allow" in id
```
The `trusted` branch of `request_permission` exists and is logically correct, but auto-approval depends on `_pick_allow_option`. ACP agents are free to choose their own optionIds — e.g. **kimi-code uses `approve_once` / `approve_always` / `reject`** (verified via strings in kimi-code 0.27.0 and 0.41.0 binaries). Exact matching fails (`"approve" != "approve_once"`), and the substring fallback `"allow" in "approve_always"` is also False → `_pick_allow_option` returns `None` → trusted sessions silently degrade to interactive prompting. Users see a permission dialog on every single tool call despite `"trusted": true`.
Note: kimi-code's options DO carry spec-compliant `kind` values (`allow_once` / `allow_always`) — matching by `kind` instead of `id` is the robust approach.
**Additional observation**: the response path has a symmetric problem. When the selected optionId is not in QwenPaw's known vocabulary, the outcome parsing falls through to `default: rejected` — so a proxy translating IDs must translate both directions. Matching by `kind` would fix both directions at once.
**Suggested fix**:
1. Prefer matching by ACP option `kind` (`allow_always` > `allow_once`), falling back to id heuristics; and/or
2. Extend `_ALLOW_OPTION_PREFERENCE` with `"approve_always"`, `"approve_once"` and widen the substring fallback to `"approve"`.
**Minimal repro**:
1. Configure an ACP runner with `"trusted": true` whose permission optionIds use the `approve_*` vocabulary (e.g. kimi-code).
2. Trigger any tool call requiring permission.
3. Expected: auto-approved without user interaction. Actual: interactive permission request is surfaced on every tool call.
**Workaround (verified in production)**: a stdio wrapper adapter around the runner's ACP entrypoint that bidirectionally translates `approve_*` ↔ `allow_*` optionIds. With the adapter in place and `trusted: true`, non-dangerous requests are auto-approved with zero interactive prompts.
在聊天中引用
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.