Commit Graph
5297 Commits
Author SHA1 Message Date
RuochenPan 2871b34dbd chore: merge upstream master into local sandbox branch 2026-09-15 15:36:53 +08:00
Soulter ab42c0d9b7 chore: bump version to 4.28.1 (#10085) v4.28.1 2026-09-14 23:11:06 +08:00
氕氙 02fef48c26 fix: preserve input image geometry under CUA sandbox and warn on oversized images (#10071)
* fix: skip input image resize under CUA sandbox to keep pixel coordinates 1:1

* feat: warn when CUA passthrough images may exceed provider upload limits

* fix: keep configured montage cap for animated inputs under CUA sandbox
2026-09-14 23:27:50 +09:00
玲因 e79c0d7aa0 fix: reduce Telegram log spam from polling and conflict errors (#10027) (#10046)
Telegram long-polling floods the log in two ways:

1. python-telegram-bot performs getUpdates through httpx, which logs every request at INFO level. httpx/httpcore were missing from LogManager._NOISY_LOGGER_LEVELS, so those per-request lines (one every ~10s) leaked through.

2. _on_polling_error logged a full traceback for every polling error, including non-network errors such as Conflict (two bot instances polling the same token). Log a concise one-line message for non-network errors and keep the traceback only for NetworkError, which still needs it for recovery.
2026-09-14 22:27:33 +08:00
Wei Chengqian 7ee03f2293 fix: preserve OpenAI endpoint resolution for empty api_base (#10079) 2026-09-14 21:48:46 +08:00
Soulter 56cbc4a4a6 feat: optimize model selection with source filters and sticky groups (#10084)
* feat: group model selection by provider source

* feat: optimize model selector with source filters and sticky groups

* fix: align model filter borders and hide single-source filter
2026-09-14 21:43:02 +08:00
Yufeng He 31d798944d fix(qqofficial): always send the state=10 closing frame in C2C streaming (#10069)
* fix(qqofficial): always send the state=10 closing frame in C2C streaming

QQ's C2C streaming protocol ends a stream with a state=10 frame whose
content must end with \n. AstrBot only sent it while unsent text
remained in the buffer: once the throttled middle frames had flushed
the full reply and the generator ended with an empty tail, no closing
frame went out at all. QQ then timed the stream out and rolled the
whole message back to the first packet, which is why a full 850-char
reply ended up displaying only its first few characters (#10066), and
why some streams hang in "generating" forever.

Close every open segment: when the stream is open (a frame id exists)
but the tail buffer is empty, send a minimal "\n" closing frame; when
nothing was ever sent (no id), keep sending nothing. The tool_call
break path closes the same way through a shared helper so an empty
segment cannot orphan its stream either.

Regression tests pin both paths against a fake _post_send: empty tail
after a middle flush, and break arriving on an empty but open segment.

* fix(qqofficial): treat an empty-Plain tail as empty for the closing frame

Review on #10069: a buffer holding only Plain("") components has a
truthy chain, so the "\n" fallback was skipped, _post_send_one rejected
the empty parsed content, and no state=10 frame went out for an opened
stream. Check for sendable content (non-empty text or a non-Plain
component) instead of chain non-emptiness. Regression test pins the
empty-Plain tail after a middle flush.
2026-09-14 21:30:35 +08:00
Soulter d524b8708a fix: standardize provider user agents with the AstrBot version (#10082) 2026-09-14 21:24:00 +08:00
氕氙 bd046ed299 feat: adaptively prepare model input images in the local process stage (#9703)
* refactor: prepare model images in the local process stage

Prepare current input images before agent construction and after the request hook. Keep original attachments intact and preserve existing tool image behavior.

Reuse the compression toggle for PNG stills and animation montages, with event-owned working files and portable history serialization.

Validation: 2571 Linux tests, 495 Windows regression tests, dashboard build, and live text/JPEG/GIF calls with agnes-3.0-flash.

* test: read source files as UTF-8 in image boundary check

* fix: avoid blanket PNG conversion of model input images
2026-09-14 01:43:09 +08:00
Soulter 4007d645c9 fix: use selected model in webchat side threads (#10065) 2026-09-13 20:07:24 +08:00
Soulter 7ec39bdef0 fix: support plugin updates through URL and file installation (#10053)
* fix: support updating installed plugins from uploaded archives

* fix: update existing plugins through URL installation

* fix: skip temporary directories during plugin discovery

* fix: stage plugin installs and backups in system temp

* test: align dashboard plugin installer mock with staging API
2026-09-12 15:05:58 +08:00
w31rd c264e1d92a feat: unify /new and /reset behavior (#10004)
* feat: unify new and reset conversation behavior

* fix(i18n): align conversation isolation labels

* fix(i18n): clarify group conversation permission hints

* feat: centralize conversation command permissions

* fix(i18n): clarify administrator-only command permissions

* docs: correct conversation command permission instructions

* test: isolate conversation restart command registration

* feat: follow conversation isolation for restart permissions
2026-09-12 14:19:58 +08:00
Soulter 11cab79dc7 feat(dashboard): show desktop update download progress (#10050) 2026-09-12 13:57:12 +08:00
Wei Chengqian fae2c120ef feat(chatui): paginate chat history (#9667)
* feat(dashboard): add chat history pagination and reasoning blocks (#9652)

* refactor(dashboard): remove reasoning char count and loading text

* feat(dashboard): load earlier messages on scroll up

* refactor(dashboard): remove reasoning retry label

* refactor(dashboard): remove thread panel pagination and lazy reasoning

Restore the thread panel to pre-#9652 behavior: full history without
pagination and inline reasoning content. Reverts the out-of-scope thread
additions while keeping main-session pagination and reasoning lazy-loading.

* chore: retrigger smoke test

* fix(dashboard): pause automatic history loading after failure

* feat(dashboard): show progress while loading earlier messages

* fix(dashboard): show reasoning loading errors and retry action

* style(dashboard): align chat loading errors with chat UI

* style(dashboard): make chat loading errors more compact

* refactor(chat): retain complete message content in history pages

* refactor(dashboard): expand reasoning directly from history pages

* refactor(api): remove lazy chat message retrieval endpoint
2026-09-12 13:56:22 +08:00
Soulter 72928aa7c9 fix: preserve image attachment paths after event cleanup (#10042)
* fix: preserve image attachment paths after event cleanup

* fix: retain local image references when normalization fails

* revert: undo local image reference normalization change
2026-09-12 12:31:10 +08:00
beeminesandbeemines f2ead2922e fix: restore session model fallback for proactive agents (#10028)
Co-authored-by: beemines <182060364+beemines@users.noreply.github.com>
2026-09-12 11:16:38 +08:00
Lukas BuckandSoulter 8b5f38885e fix(kb): space out concurrent waiters in the URL cleaning RateLimiter (#10015)
* fix(kb): space out concurrent waiters in the URL cleaning RateLimiter

URL content cleaning processes all chunks with asyncio.gather and a
shared RateLimiter. Every coroutine read the same last_call_time
before sleeping, so they all woke up at the same moment and fired
their requests together; the configured RPM did not bound that burst
and larger documents could trip the upstream limit.

Reserve the next release slot under a lock (sleeping outside it), so
waiters are released one interval apart, in order. Idle time is still
credited and max_rpm=0 still disables limiting.

Fixes #9995

* fix(kb): reserve RateLimiter slots under a lock so waiters do not burst

The first commit only carried the test; this adds the RateLimiter change
it exercises. Each waiter now reserves the next release slot under an
asyncio.Lock and sleeps until that slot, so concurrent callers are
released one interval apart instead of waking up together.

* fix(kb): preserve rate limit spacing after event loop stalls

---------

Co-authored-by: Soulter <905617992@qq.com>
2026-09-10 23:42:17 +08:00
若月千鸮 0f445f5eff fix(agent): deliver skills-like fallback replies when streaming (#10025)
* fix(agent): deliver skills-like fallback replies when streaming

* fix(agent): limit fallback fix to missing streaming events
2026-09-10 23:34:33 +08:00
PyuraMazo 0d40d34185 feat: enhance slider robustness (#10037)
* fix: validate numeric config bounds if slider exists

* feat: add min/max labels to slider
2026-09-10 23:33:04 +08:00
Soulter da1bc7df55 fix(ci): exclude temporary dashboard artifacts from PyPI source packages (#10036) 2026-09-10 23:25:42 +08:00
Soulter c6eefb5544 perf(dashboard): reduce bundled font and diagram assets (#10034) 2026-09-10 23:04:59 +08:00
Soulter 5cc5617233 feat(chatui): reuse Shiki for workspace code previews (#10023) 2026-09-10 23:01:57 +08:00
NayukiChiba 32a751394c fix(lark): Ensure Lark private messages are delivered reliably by falling back from rejected open IDs to known chat IDs without duplicating successful sends. (#10018)
* fix(lark): fall back to private chat ID when open ID send fails

Private file sends can fail with error 230101 when addressed by open ID,
even though the same file can be delivered to the private chat ID.

Persist private open ID to chat ID mappings from incoming messages,
scoped by platform and app ID, while preserving existing session IDs.
Keep open ID as the primary recipient and retry each rejected message
once with its known private chat ID, reusing the content and UUID.
Do not resend successful components or retry transport exceptions.

Propagate proactive send and attachment upload failures to callers so
failed deliveries are not reported as successful. Preserve the existing
boolean failure handling for replies.

Refs: #9989

* test(lark): cover private chat fallback and delivery failures

Reproduce rejected open ID file sends and verify that the same uploaded
file is retried once with the private chat ID and original UUID.

Cover successful primary sends, mixed message chains, failed deliveries,
upload failures, group routing, transport timeouts, and reply behavior.
Verify stored routes survive adapter recreation, remain scoped to the
bot, and cannot be overwritten by group messages.

Isolate sender-name tests from persistent route storage and supply the
platform and app identity required by route persistence.

Validation: 26 related tests passed; ruff format and ruff check passed.
Live Feishu API validation remains pending application credentials.

Refs: #9989
2026-09-10 22:53:17 +08:00
Soulter 48024574c8 feat(chatui): refine settings, composer and streaming experience (#10021)
* feat(chatui): refine settings, composer and streaming experience

* style(chatui): compact composer and narrow message layouts

* style(chatui): align composer gutters and remove excess height

* style(chatui): give composer editing area more height

* fix(chatui): preserve reading width when side panels open
2026-09-10 22:08:02 +08:00
Soulter 6fb50cae91 feat(webchat): enable reasoning display by default (#10020)
* feat(webchat): enable reasoning display by default

* fix(webchat): sync reasoning flag expectations and API docs
2026-09-10 10:36:24 +08:00
DFGHJ43 5935430b1d fix: correct At/AtAll branch order in message outline (#9993)
* fix: correct At/AtAll branch order in message outline

Original logic checked At first and then AtAll. However, because AtAll is a subclass of At, the AtAll branch would never be executed. This change moves AtAll before At to ensure the code behaves correctly.

* test: assert AtAll outline renders as [At:全体成员]
2026-09-10 00:34:25 +08:00
WangPan59and王磐 5195ec694c fix: resolve field loss, error code swallowing, and parameter validation issues in web search tool (#9979)
* feat: 优化网络搜索工具并更新单元测试

* fix: 修复 Code Review 指出的两个问题

---------

Co-authored-by: 王磐 <wangpan.com>
2026-09-10 00:25:21 +08:00
Sekken 312ec36d55 fix(webui): fall back to WebChat session titles in conversation history (#9983)
WebChat generates its title on the platform session, while the conversation history reads the conversation title column, so WebChat rows were listed as untitled. Fall back to the session display name when a conversation has no title, and let conversation search match session titles as well.
2026-09-10 00:15:52 +08:00
玲因 67b8725ee8 fix: batch console log rendering to avoid UI freeze (#9988) (#9990)
Entering the Data & Logs -> Logs page froze the WebUI for seconds because ConsoleDisplayer rendered each historical log line with a separate appendChild plus a forced synchronous reflow (scrollTop = scrollHeight) per line, and used innerText which triggers a style recalc on every assignment.

Batch the rendered lines into a DocumentFragment and append it once, scroll to the bottom a single time, and use textContent instead of innerText. This collapses O(n) reflows into one and eliminates the main-thread freeze.
2026-09-09 23:51:47 +08:00
Wei Chengqian 6dde01b7e9 fix: resolve persisted current conversation before deletion (#10003) 2026-09-09 23:48:45 +08:00
Soulter ee98243825 perf: improve provider dialog (#10007) 2026-09-09 23:47:29 +08:00
Yufeng He 5f12620118 fix(cron): record active-agent job failure when the runner ends in ERROR (#9987)
_run_job marked a cron job "completed" unless an exception escaped, but
_woke_main_agent never checked the agent runner's terminal state: a run
that dies with a malformed function call at max steps ends in
AgentState.ERROR with no exception, so cron_jobs showed
status=completed, last_error=NULL, and the user only ever saw the
intermediate messages (#9980).

_woke_main_agent now raises when the runner ends in AgentState.ERROR
(carrying the final error text when there is one) and when the main
agent fails to build at all; _run_job's existing handler records both as
failed with last_error. The runner base class gains a read-only `state`
property so callers no longer reach into `_state`.

Tests: two regression cases on _run_job (ERROR terminal state, build
failure) asserting status=failed with the detail in last_error; both red
on current master and green here. Existing fake runners in the file got
the state attribute the runner contract now documents.

Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
2026-09-09 22:43:27 +08:00
若月千鸮 25374205b6 fix(cron): honor session context compression settings (#9992)
* fix(cron): honor session context compression settings

* fix(agent): share session compression config across wakeups
2026-09-09 17:32:01 +08:00
KazusaUwU 6494ac22e5 fix(dashboard): reject stale WebUI assets in desktop-managed mode (#9898) 2026-09-09 11:44:06 +09:00
RuochenPan 7de4e55c0e test: synchronize watchdog log rotation assertions 2026-09-09 09:39:59 +08:00
RuochenPan 20ad3dcde2 test: wait for watchdog retry without fixed sleeps 2026-09-09 09:30:16 +08:00
RuochenPan 2995920a90 test: check sandbox file readability across platforms 2026-09-09 09:18:33 +08:00
RuochenPan eb4fd7ee12 fix: skip missing default roots in local grep 2026-09-09 09:03:32 +08:00
RuochenPan 3bdfb1eef2 fix: revoke local shell sessions when admin access is removed 2026-09-09 08:56:03 +08:00
RuochenPan 3589ad5d99 fix: block shared-path attacks on local runtime file exchange
Sandboxed processes can write to shared temp roots, so a named session
log there could be replaced with a symlink to a host file that host-side
reads and appends would follow. Keep managed shell output on an anonymous
temporary file handle instead of a named path.

Also stop _resolve_path_from_sandbox from consulting a booter under the
local runtime: workspace and local-file checks already enforce caller
permissions, and the fallback branch probed the host shell without them.
Reject such paths with FileNotFoundError instead.
2026-09-08 17:54:18 +08:00
RuochenPan 721cd89695 fix: revoke local shell sessions when permissions change 2026-09-08 15:44:02 +08:00
RuochenPan 390c213fe3 fix: preserve read-only Python virtualenv access in local sandboxes 2026-09-08 11:58:34 +08:00
RuochenPan 20f9f1280b fix: use a portable sandbox startup probe 2026-09-08 11:23:28 +08:00
RuochenPan ec6921c065 fix: report local sandbox startup failures 2026-09-08 11:17:09 +08:00
RuochenPan 1807e6ff1b ci: enable bubblewrap user namespaces on Ubuntu runners 2026-09-08 11:08:55 +08:00
RuochenPan 7a1aa9c965 fix: restore local sandbox DNS and approved file access 2026-09-08 10:49:22 +08:00
RuochenPan 97ffa739bc chore: remove redundant local permission hint 2026-09-08 10:11:23 +08:00
RuochenPan b0d5a5d111 fix: restrict local file sending and align Windows permission tests 2026-09-08 09:55:17 +08:00
RuochenPan 8ceb6a4f64 fix: use supported local permission defaults on Windows 2026-09-08 09:41:25 +08:00
RuochenPan a6e207aeea chore: merge latest upstream master 2026-09-08 09:06:24 +08:00