Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ src/agent_box/
- `WEIXIN_ACCOUNT_ID` — weixin_sdk account id (from login)
- `QQBOT_APP_ID` — QQ Bot application ID
- `QQBOT_CLIENT_SECRET` — QQ Bot client secret
- `GLM_API_KEY` — ZhipuAI (GLM) API key for voice-to-text. Empty skips QQ voice transcription (falls back to file path only).
- `GLM_API_KEY` — ZhipuAI (GLM) API key for voice-to-text (fallback). QQ voice messages prefer the platform-provided `asr_refer_text`; this key is used only when that field is absent.
- `GLM_ASR_MODEL` — GLM ASR model id (default: `glm-asr-2512`)
- `PROJECTS_DIR` — where project folders live (default: `data/projects`)
- `ROUTER_MODEL` — model override for router (optional)
Expand Down
26 changes: 22 additions & 4 deletions src/agent_box/channels/qq.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,18 +591,36 @@ async def _download_atts(
) -> list[tuple[str, str, str | None]]:
"""Download each attachment. Returns list of (label, local_path, transcription).

transcription is populated for audio attachments when ASR is configured
and succeeds; otherwise None.
Voice attachments prefer the platform-provided ``asr_refer_text`` (QQ's
own ASR result) — when present, no download or transcoding is needed.
Falls back to downloading the audio and running GLM ASR.
"""
results: list[tuple[str, str, str | None]] = []
for att in atts:
url = _normalize_url(att.get("url") or "")
label = self._att_label(att)
local = ""
transcription: str | None = None
if url:

# Voice: prefer QQ platform ASR text (no download/transcode needed)
if label == "语音":
asr_text = (att.get("asr_refer_text") or "").strip()
if asr_text:
transcription = asr_text
log.info(
"QQ voice: using platform asr_refer_text (%d chars)",
len(asr_text),
)
else:
log.debug(
"QQ voice attachment has no asr_refer_text; keys=%s",
list(att.keys()),
)

# Download when no platform transcription (voice fallback or non-voice)
if url and transcription is None:
local = await self._download_image(url, att.get("filename")) or ""
# Transcribe voice attachments when ASR is available
# Fall back to GLM ASR for voice when platform text unavailable
if label == "语音" and local and self._asr is not None:
transcription = await self._asr.transcribe(local)
results.append((label, local, transcription))
Expand Down
Loading