* Fix CreateSkillPayloadTool array schema missing items field
The payload parameter's anyOf array variant lacked an items field,
causing Gemini API to reject the tool declaration with 400 Bad Request:
'parameters.properties[payload].any_of[1].items: missing field.'
Add items: {type: object} to the array variant to satisfy the Gemini
API requirement for array type schemas.
Fixes#6279
* Fix TypeError when OpenAI-compatible API returns null choices
Some providers (e.g. OpenRouter) may return a completion where
choices is None rather than an empty list — for instance on rate
limiting, content filtering, or transient errors. The existing code
used len(completion.choices) which throws TypeError on None.
Replace all len(...choices) == 0 checks with 'not ... .choices' which
handles both None and empty list. Affects _query_stream, _parse_openai_completion,
and _extract_reasoning_content.
Fixes#6252
Fixes#6294
QQ official bot receives emoji/sticker messages as raw XML-like tags:
`<faceType=4,faceId="",ext="eyJ0ZXh0IjoiW+a7oeWktOmXruWPt10ifQ==">`
This made the LLM unable to understand the emoji content.
Changes:
- Added `_parse_face_message()` method to parse face message format
- Decode base64 `ext` field to get emoji description text
- Replace face tags with `[表情:描述]` format for readability
Example:
- Input: `<faceType=4,faceId="",ext="eyJ0ZXh0IjoiW+a7oeWktOmXruWPt10ifQ==">`
- Output: `[表情:[满头问号]]`
Co-authored-by: ccsang <ccsang@users.noreply.github.com>
1. Fix missing spaces in cron job wake prompt string concatenation.
Python implicit string concatenation produced:
"...scheduled taskProceed..." and "...conversation.After..."
which sent garbled instructions to the LLM agent, causing unreliable
cron job execution.
2. Replace deprecated datetime.utcnow() with
datetime.now(datetime.timezone.utc) in JWT generation.
utcnow() is deprecated since Python 3.12 and returns naive datetime
which can cause incorrect token expiry on non-UTC systems.
Closes#6103Closes#6165
Co-authored-by: easonysliu <easonysliu@tencent.com>
* fix: update scrollbar styles to follow theme variables
* fix: update theme colors to use CSS variables for consistency
* fix: change login button color to primary for better visibility
* fix: update theme colors for Dark and Light themes; change login button color to secondary
* fix: update border and theme colors for consistency in DarkTheme
* fix: update sidebar list class to conditionally hide scrollbar in mini sidebar mode
* fix: simplify button visibility logic and remove unnecessary leftPadding style
* fix: refactor language switcher to use grouped menu for better UX
* fix: update theme colors to use primary color for consistency across components
* fix: add preview text for template output in multiple languages
In _handle_api_error(), when a 429 rate-limit is encountered, the code
calls available_api_keys.remove(chosen_key). If the same key was already
removed in a previous retry iteration (e.g. the key rotated back to the
same value), this raises ValueError which crashes the entire LLM request
with an opaque error instead of a proper retry/fallback.
Add a membership check before calling remove() to prevent the crash.
Co-authored-by: easonysliu <easonysliu@tencent.com>
* Add binding for local temp directory in YAML
Bind the local temp directory to the sandbox for file access.
* Update compose-with-shipyard.yml
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: Soulter <37870767+Soulter@users.noreply.github.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Updated the quick start command from 'astrbot' to 'astrbot run' across all
language versions of README documentation for consistency and correctness.
Co-authored-by: DroidKali <DroidKali@users.noreply.github.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(qqofficial): fix streaming message delivery for C2C
* fix(qqofficial): rewrite send_streaming for C2C vs non-C2C split
* fix(qqofficial): add _extract_response_message_id for safe id extraction
* fix(qqofficial): flush stream segment on tool-call break signal
* fix(qqofficial): downgrade rich-media to non-stream send in C2C
* fix(qqofficial): auto-append \n to final stream chunk (state=10)
* fix(qqofficial): propagate stream param to all _send_with_markdown_fallback call sites
* fix(qqofficial): retry on STREAM_MARKDOWN_NEWLINE_ERROR with newline fix
* fix(qqofficial): handle None/non-dict response in post_c2c_message gracefully
* fix(qqofficial): remove msg_id from video/file media payloads in send_by_session
QQ API rejects msg_id on proactive media (video/file, msg_type=7) messages
sent via the tool-call path, returning "请求参数msg_id无效或越权". The
msg_id passive-reply credential is consumed by the first send and cannot be
reused for subsequent media uploads in the same session.
Remove msg_id from the payload after setting msg_type=7 for video and file
sends, for both FRIEND_MESSAGE (C2C) and GROUP_MESSAGE paths.
* fix(qqofficial): replace deprecated get_event_loop() with get_running_loop()
asyncio.get_event_loop() is deprecated since Python 3.10 and raises a
DeprecationWarning (or errors) when called from inside a running coroutine
without a current event loop set on the thread. Replace both call-sites
in the streaming throttle logic with asyncio.get_running_loop(), which is
the correct API to use inside an already-running async context.
Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
---------
Co-authored-by: 2ndelement <2ndelement@users.noreply.github.com>
Co-authored-by: Claude Sonnet <noreply@anthropic.com>