* feat(mcp): surface OAuth-required server tests
* fix(mcp): show connection failure details in status cards
---------
Co-authored-by: RockChinQ <[email protected]>
Use eight securely random recovery-code characters with concurrency-safe online throttling. Preserve existing keys and verify recovery through browser and real SQLite integration tests.
Co-authored-by: [email protected] <[email protected]>
Co-authored-by: dadachann <[email protected]>
create_bot inserts the Bot row first and only then instantiates the
adapter via platform_mgr.load_bot. When the adapter constructor raises
(e.g. KeyError on a missing credential key), the insert is already
committed and nothing removes the row: the HTTP layer returns 500 but
a permanently disabled orphan bot stays in the DB. Callers never
receive the bot uuid, so they cannot compensate by deleting it, and
load_bots_from_db skips enable=False bots, so the orphan is never
loaded or surfaced anywhere.
Wrap load_bot in try/except and delete the inserted row before
re-raising. Add a regression test asserting the DELETE is issued when
the adapter constructor fails.
WecomMessageConverter.yiri2target() always emits {'media_id': ...} for
image/voice/file parts (never 'media'), matching the correct usage
already in reply_message(). send_message(), the entry point plugins
use via PluginToRuntimeAction.SEND_MESSAGE, instead read
content['media'], which is never set, so any image/voice/file part
raises KeyError and aborts the send.
Refs #1687
Signed-off-by: Amir Fathi <[email protected]>
* fix(cloud): provision login workspace just in time
* fix(oauth): send callback URI during code exchange
* fix(oauth): preserve callback URI through browser exchange
* fix(oauth): negotiate redirect-bound codes
---------
Co-authored-by: dadachann <[email protected]>
* fix(cloud): launch new accounts through Space
* style: format Cloud entry URL
* fix(cloud): wait for launch workspace projection
---------
Co-authored-by: dadachann <[email protected]>
* fix(monitoring): restore SQLite token statistics
Allow the monitored SQLite strftime bucket expression through the tenant SQL guard and preserve structured backend errors in the token dashboard. Add persistence and frontend regressions.\n\nVerified-by: independent-review
* test(runtime): accept reconcile timeout in capacity stub
Keep the PostgreSQL capacity probe aligned with the runtime handler contract and assert the bounded reconcile timeout.
---------
Co-authored-by: dadachann <[email protected]>
The LINE adapter passed text through as a single Plain component,
ignoring the mention payload (mentions[].index/length/isSelf) that the
Line Messaging API includes in the webhook. As a result:
- At(target=bot_account_id) never appeared in the message chain, so the
'at-bot' group respond rule silently dropped every @bot mention.
- The bot only replied when the message happened to match the prefix
rule (e.g. starting with 'ai').
Now LINEMessageConverter reads message.message.mention and builds the
chain per mention position:
- Bot mention (isSelf) -> At(target=bot_account_id) so AtBotRule matches
the same way as other adapters (dingtalk/lark etc.).
- Other mentions -> At(target=<line user id>, display=<mention text>).
At.__str__ already prepends '@', so the display text carries no
double '@' and the rendered text (prefix/regexp rules, quotes,
session context) is byte-identical to before.
- Missing/out-of-bounds mentions are skipped defensively.
target2yiri becomes an instance method (like wechatpad/aiocqhttp) so
the converters can hold bot_account_id; LINEAdapter passes it in from
its own config.
execute_func_call returns list[ContentElement] for MCP tools, but the
runner assigned that list directly to the tool-message content. The
OpenAI chat-completions spec requires tool-message content to be a
string, so OpenAI-compatible endpoints return HTTP 500 when the raw
list is sent.
Serialize the list to a string before building the tool message, using
ContentElement.__str__ which returns the text payload for text elements
and a human-readable placeholder for images and files. Fixes#2457.