* refactor(web): load channel configs without exposing secret values
- add a dedicated channel config API that returns sanitized config plus
configured secret metadata
- update channel config pages and forms to use secret presence for
placeholders, validation, reset, and save behavior
- refresh the channel settings layout and clean up related i18n copy
- add backend tests for the new channel config endpoint
* fix(config): restore missing strings import
- remove version details from the sidebar footer
- show the current app version as a badge in the config page header
- add a reusable Badge UI component for the new version label
* feat(provider): add Venice AI support and update related documentation
* revert(asr): restore asr files to previous commit
* feat(config): add Venice API base URL and local LM Studio configuration
* fix(config): update Venice API base URL to correct endpoint
* feat(updater): add web self-update endpoint and updater package
* feat(selfupgrade): when url empty, using GetTestReleaseAPIURL for test .
* feat(selfupgrade): only GetTestReleaseAPIURL .
* feat(upgrade): cli $0 update work well!
* fix(ci): fix ci err
* fix(test): fix ci test
* fix(ci): fix ci lint fmt err
* test(updater): add test for updater
* fix(ci): fix ci lint var copy err
* fix(ci): retry ci
* updater: require checksum verification, prefer API digest, verify SHA256, fix zip extraction, update tests
* fix(lint): lint fixed
* fix(lint): lint fixed2
* updater: stream download and verify sha256; add http client timeout and progress
Avoid double-download by streaming asset into temp file while computing SHA256 and verifying against checksum; replace http.Get with shared httpClient (2m timeout) to prevent hangs; add simple stderr progress display; remove unused helpers.
* feat: add load_image tool for local file vision
* fix: address load_image PR review feedback
- Exclude load_image from sub-agent tools via Unregister after Clone,
since RunToolLoop does not call resolveMediaRefs
- Add ToolRegistry.Unregister() method
- Fix scope collision: use channel:chatID instead of filename
- Add channel/chatID context resolution matching send_file pattern
- Add comment explaining iteration > 1 guard on resolveMediaRefs
- Remove emoji from ForUser for consistency with send_file
- Add load_image_test.go
* feat: enable load_image for subagents via MediaResolver in RunToolLoop
Instead of removing load_image from sub-agent tools (28f69e71), inject a
MediaResolver into the legacy RunToolLoop fallback path so media:// refs
are resolved to base64 before each LLM call — matching the main agent
loop behavior.
- Add MediaResolver field to ToolLoopConfig and call it on iteration > 1
- Add SubagentManager.SetMediaResolver() and wire it through runTask
- Remove ToolRegistry.Unregister() (no longer needed)
- Restore load_image in sub-agent tool set (revert Clone+Unregister)
- Add TestSubagentManager_SetMediaResolver_StoresResolver
* refactor(load_image): remove prompt parameter from tool schema
* test(tools): add success-path test for LoadImageTool
Add TestLoadImage_SuccessPath that creates a real PNG file with valid
magic bytes, calls Execute with WithToolContext, and verifies:
- result.IsError == false
- ToolResult.Media contains a media:// ref
- ToolResult.ForLLM contains the [image: marker
- media ref is resolvable in the store
Add explanatory comment in loop.go for why Media and ArtifactTags
coexist on non-ResponseHandled tool results (e.g. load_image).
* fix: preallocate slice in tests and add ResponseHandled guard in toolloop
Fix prealloc linter failure in load_image_test.go.
Prevent double-resolving media by checking ResponseHandled in toolloop.go.
* Register TTS tool if provider is available
---------
Co-authored-by: Reusu <admin@yumao.name>
Co-authored-by: 美電球 <hoshina@evaz.org>
- add backend APIs for searching and installing registry skills, including origin metadata and concurrency-safe workspace writes
- introduce /agent/hub as the default agent entry with marketplace search and install UI
- refactor the skills and tools pages with filtering, dialogs, detail views, import validation, and updated i18n
- expand backend tests for search, install, import, rollback, and concurrent requests
* fix(api): enhance model availability probing with backoff and caching mechanisms
* fix(lint): resolve gci and predeclared issues in model probe
* fix(api): address copilot review feedback on probe cache key and test stability
* fix(api): reduce probe cache key fragmentation
Addresses reviewer concerns regarding silent message loss by narrowing the
error swallowing logic in EditMessage:
- Excludes context.DeadlineExceeded and context.Canceled from being swallowed,
ensuring local timeouts before transmission still trigger a fallback send.
- Adds an explicit check for the 'message is not modified' error to safely
identify edits that have already landed on Telegram's servers.
- Narrowly targets confirmed post-connect dropouts (e.g., connection reset)
instead of broad network-ish string matching.
- Fixes the missing isPostConnectError definition and required errors import.
* feat(web): clarify model availability and status display
- Rename model availability field from configured to available across backend API and frontend usage
- Keep status as reason classification (configured/unconfigured/unreachable) and show unreachable in UI
- Preserve API key preview even when local service is unreachable
- Update backend tests to assert both availability and status semantics
* fix(web): clarify unreachable model status and wording
- Show unreachable status in model cards instead of API key preview when service is down
- Keep API key placeholder preview in model settings whenever an API key is already saved
- Rename model status wording from configured to available across backend, frontend, and i18n
- Update backend model status tests to match renamed status semantics
* style(web): standardize formatting in handleListModels function
* refactor(web): enforce status field as required to follow backend behavior
- centralize gateway log level resolution and normalization
- propagate debug flags to spawned launcher and gateway processes
- add a log level selector to the logs page
- cover the new behavior with backend and config tests
Treat SystemParts as an alternative representation of message Content
rather than an additive one. This prevents systematic overestimation
of system message tokens which could trigger premature context
pruning or summarization.
- Picks the maximum of Content vs. SystemParts to stay conservative.
- Adds a per-part overhead (20 chars) to account for JSON metadata.
- Streamlines the ReasoningContent counting logic.
Fixes a deficiency where structured blocks for cache-aware adapters
caused overestimated budgets or hidden overflows.
Load the Pico token from config before validating websocket proxy requests
when the launcher attaches to an existing gateway and the in-memory cache
is still empty
* feat(provider): add lmstudio vendor and local no-key behavior
* refactor(provider): consolidate protocol metadata and local tests
* fix(provider): sync lmstudio probing and model normalization
* test(web): format lmstudio model status cases for golines
reItalic (_text_) ran after reLink converted [text](url) to <a href>,
injecting <i> tags into URLs containing underscores (e.g. Google Flights
URL-safe base64 in the tfs param). Telegram silently dropped such malformed
<a> tags, causing only 1 of 3 links to appear in messages.
Fix: extract markdown links into placeholders before any formatting runs,
restore them as <a href> last — same pattern used for code blocks.
* feat(channels): Channel.Send and MediaSender.SendMedia return delivered message IDs
Change Channel.Send signature from (ctx, msg) error to (ctx, msg) ([]string, error)
and MediaSender.SendMedia similarly, so callers can capture platform message IDs
for threading, reactions, and history annotation.
Adapters that return real IDs: Telegram (per-chunk MessageID), Discord (Message.ID),
Slack Send (ts), QQ (sentMsg.ID), Matrix (EventID). Slack SendMedia returns nil
because UploadFileV2 does not expose the posted message timestamp in its response.
All other adapters return nil IDs.
preSend and sendWithRetry in manager.go updated to propagate ([]string, bool).
README examples updated for both English and Chinese docs.
* style: apply golangci-lint fixes (golines)
* docs: fix Send migration guide — restore old error-only signature in before/after example