* 🐛 fix(bot): read Feishu chat history, decode WeChat voice and gate personal-file visibility toggles
- Feishu/Lark (LOBE-13803): inject the current `{ platform, channelId }` into the
bot platform prompt so `readMessages` no longer asks the user for a group ID;
explain `230027` and friends with the exact scope to add (`im:message.group_msg`);
surface Lark `permission_violations` in API errors; map unicode reactions to
Feishu `emoji_type` and track `reaction_id` so step swaps replace instead of
stacking; decide the no-@mention exemption from real chat membership
(`user_count`/`bot_count`, fail closed) instead of who has spoken.
- WeChat (LOBE-13407): decode SILK voice to WAV on download via `silk-wasm` so
the attachment is playable in the browser and usable by audio models.
- ResourceManager: only offer "Make private" / "Publish to workspace" for the
creator's own files inside a workspace; personal-mode rows default to
`visibility = 'public'` and were wrongly offered the toggle.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V5Mi6LJCFiMnej3MPAjMpJ
* 🐛 fix(feishu): read the newest history page and bound solo-chat cache staleness
Address the Codex review on #19323:
- `readMessages` and the chat-SDK `fetchMessages` asked Feishu for history
without `sort_type`, which defaults to ascending — in any chat past the
page cap the model got the chat's oldest messages instead of what was just
said. Request `ByCreateTimeDesc` (kept on every cursor page) and flip the
page so the documented chronological order still holds; `forward` maps to
ascending.
- A cached "solo" verdict kept the bot answering every unmentioned message for
10 minutes after someone joined the chat. Positive verdicts now expire after
60 s; only "shared" verdicts keep the 10-minute TTL.
- Without agent-runtime Redis the verdict was never cached, costing a blocking
Feishu request per inbound message. Fall back to a bounded process-local
cache with the same TTLs.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V5Mi6LJCFiMnej3MPAjMpJ
* 🐛 fix(bot): skip membership lookups for addressed messages and keep the reaction id until deletion succeeds
Second Codex round on #19323:
- `onSubscribedMessage` only consults `isSoloBotConversation` when a DM or
@mention has not already settled the question, so a lapsed cache never puts
a platform round-trip in front of a direct message.
- The Feishu final reaction clear forgot the tracked `reaction_id` before the
remote delete ran; a transient failure left the reaction visible with
nothing to retry with. Delete the tracker entry only after removal succeeds.
- Fix the `result.messages` possibly-undefined type error CI caught in
`service.test.ts`.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V5Mi6LJCFiMnej3MPAjMpJ
* 🐛 fix(bot): keep every placed Feishu reaction id until removal succeeds and scope Slack history injection
Third Codex round on #19323:
- Feishu reaction tracker keeps a list of ids per message, in Redis or a
bounded process-local cache when agent-runtime Redis is absent (local runs
used to stack every step reaction). A swap that adds the next reaction but
fails to remove the previous one keeps both ids; the final clear retries
removal in place before handing leftovers back to the tracker, since neither
the bridge nor the queue callback retries it. Legacy bare-id keys still read.
- `chatComposition` shares the same bounded memory cache helper.
- New optional `PlatformClient.extractConversationId`: Slack declines for reply
threads, so the injected current conversation never points `readMessages`
(channel history only) at the parent channel of a thread.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V5Mi6LJCFiMnej3MPAjMpJ
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* 💄 style: refresh AIHubMix branding and links
- Correct brand casing to AIHubMix in all user-facing text (provider card,
18 locale files, docs pages, READMEs)
- Update third-party proxy table: official logo, direct console token link
- Add the missing 'Obtain OpenAI API Key' section to the English README
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* 💄 style: update AIHubMix table model examples to GPT-5.6 and Claude Fable 5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: YuTengjing <ytj2713151713@gmail.com>
* 📝 docs: fix outdated content across the docs site
Audited docs/ against the current codebase and fixed stale content that
drifted after major refactors (Clerk/NextAuth → Better Auth, src/server →
apps/server, src/{config,envs,locales} → packages/*, model-bank updates).
- self-hosting/auth: mark removed NextAuth/Clerk pages with deprecation
warnings; fix microsoft/zitadel alias claims and the Logto callback path
- environment-variables & advanced: correct wrong defaults (S3_SET_ACL,
AI_IMAGE_DEFAULT_IMAGE_NUM, index/proxy URLs), drop non-existent env vars
and fictional feature flags, fix OIDC config guidance
- development: update refactored paths, Better Auth, .mjs configs, remove
the MSW section (msw is not a dependency)
- providers & model examples: replace retired model ids with in-bank ones;
fix comfyui frontmatter corruption
- usage: rename Moderator→Orchestrator, GTD→Task, correct shortcut keys,
channel capability tables, Feishu/Lark WebSocket mode
- platform/migration: fix dead links, docker service name, npx/npm → bun
EN and zh-CN pairs updated together.
* 📝 docs: fix Logto callback path and AUTH_SECRET deprecation guidance
- Revert Logto/Sealos callback URLs to /api/auth/callback/logto to match
the runtime SSO redirectURI override
- Narrow legacy auth Callout: AUTH_SECRET remains required for Better Auth;
mark NEXT_AUTH_SECRET as deprecated in zh-CN
* 📝 docs: refresh agent skills for locales, env, auth, and agentRun paths
Align OSS agent guidance with post-refactor layout:
- packages/locales/src/default + bun run i18n
- packages/env/src for env schemas (@/envs alias)
- spa-auth shell + src/routes/auth segments
- chat agentRun/transports/hetero instead of aiChat
* 📝 docs: document APP_URL as required for Better Auth base URL
Self-hosted auth uses appEnv.APP_URL as baseURL, not request-header
auto-detection. NEXT_PUBLIC_AUTH_URL remains deprecated.
* 📝 docs: note self-host search provider setup for web search
Built-in lobe-web-browsing needs no client plugin, but self-hosted
servers still require SEARCH_PROVIDERS / SEARXNG_URL (default SearXNG).
* 📝 docs: point feature guide welcome UI at AgentHome
Opening message/questions on the agent chat page live in
src/features/AgentHome, not Onboarding WelcomeMessage.
* ✨ feat(composio): add Composio integration layer as Klavis replacement
- Add @composio/core SDK client factory (src/libs/composio)
- Add COMPOSIO_API_KEY server config + enableComposio flag
- Add COMPOSIO_APP_TYPES const with 21 curated apps (appSlug-based)
- Add lambda/composio tRPC router (createConnection, deleteConnection, getConnection, updateComposioPlugin)
- Add tools/composio tRPC router (executeAction, listActions, getActions)
- Add ComposioService with executeComposioTool + getComposioManifests
- Add composioStore Zustand slice (7 files: types, initialState, action, selectors, index, test)
- Wire composioStore into ToolStore state and action tree
- Add composioStoreSelectors to tool selectors index
- Add handleComposioInstall to AgentManagerRuntime
- Extend CustomPluginParams with composio field
- Add enableComposio to GlobalServerConfig types
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* 🔥 refactor(klavis): remove Klavis integration and migrate all references to Composio
- Delete all Klavis source files (libs, config, const, routers, services, store, UI components)
- Rename KlavisX components to ComposioX equivalents
- Replace all Klavis store selectors, types, and action names with Composio counterparts
- Fix authConfigId to be server-side managed (auto-fetch/create from Composio API)
- Update DB customParams.klavis → customParams.composio throughout
- Fix ToolSource type: 'klavis' → 'composio'
- Fix TaskTemplateSkillSource: 'klavis' → 'composio'
- Fix RecommendedSkillType.Klavis → RecommendedSkillType.Composio
- Remove klavis npm package dependency
- Update builtin-tool-creds: connectKlavisService → connectComposioService
- Update RuntimeExecutors: KLAVIS_SERVICES_LIST → COMPOSIO_SERVICES_LIST
- All Composio-related type errors: 0 remaining
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* 🐛 fix(composio): complete the klavis→composio migration and wire the OAuth callback
The composio branch had renamed the klavis modules but left consumers
half-migrated, so the OAuth connect link did not work end-to-end. Finish it:
- Add the missing OAuth callback route `/api/composio/oauth/callback` (Composio
uses managed auth, so it only lands the user back and closes the popup; the
opener then polls getConnection and syncs tools). Allowlist it as a public
cross-site redirect landing in the proxy define-config.
- Remove leftover `import { type Klavis } from 'composio'` (non-existent package)
and type the prop as `string`.
- Fix undefined `oauthUrl` → `redirectUrl` in every OAuth popup opener.
- Map `serverName` to `appSlug` (API) / `label` (display); unify every
createComposioConnection call to `{ appSlug, identifier, label }`.
- Compare against the `ComposioServerStatus` enum instead of the `'ACTIVE'`
string literal.
- Use the renamed store fields `composioServers` / `isComposioServersInit`.
- executeComposioTool: `toolName` → `toolSlug`.
- Rename onboarding `KlavisServerItem.tsx` → `ComposioServerItem.tsx` to match
its import.
* 🐛 fix(composio): use connectedAccounts.link for Composio-managed OAuth
`connectedAccounts.initiate` is no longer supported for Composio-managed OAuth
auth configs (HTTP 400), which broke connecting apps like Gmail. Switch to
`connectedAccounts.link` (POST /api/v3/connected_accounts/link) — same
`{ callbackUrl }` options and `{ id, redirectUrl }` result, so it is a drop-in.
Also treat Composio's `status=failed` callback query param as a failed
authorization in the OAuth callback page.
* 🐛 fix(composio): correct tool sync, execution, callback build, and list dedup
Four fixes found while testing the Composio integration end-to-end:
- listActions: use `getRawComposioTools` (raw defs with slug/inputParameters)
instead of `tools.get()` (provider-wrapped, name/params under `.function`).
The wrapped shape left every synced tool with an empty name, so they all
collapsed to `${identifier}____` and the LLM rejected the request with
"Tool names must be unique."
- tools.execute: pass `dangerouslySkipVersionCheck: true` (manual execution
otherwise throws ComposioToolVersionRequiredError when the toolkit version
resolves to "latest"). Applied to both the executeAction router and the
ComposioService used by the agent runtime.
- OAuth callback route: escape only `<`/`>`/`&` for the inline-script payload;
the previous regex embedded literal U+2028/U+2029 line separators which broke
the regex literal at build time ("Unterminated regular expression").
- installed-plugin selectors: filter out `customParams.composio` (was still
checking the old `customParams.klavis`), so a connected Composio app no longer
shows up twice in the skill picker / tool discovery list.
* ✨ feat(composio): pin auth config id per toolkit via env
Add `COMPOSIO_AUTH_CONFIG_IDS` (JSON map of `identifier -> authConfigId`) so a
pre-created Composio auth config (e.g. a custom/white-label OAuth app set up in
the dashboard) can be used directly per toolkit. `createConnection` now resolves
the pinned auth config first, then falls back to discovering an existing one for
the toolkit (matched case-insensitively), and only auto-creates a
Composio-managed config when nothing is configured.
* 🐛 fix(composio): update plugin invoke test to composio + sort tool initialState imports
- action.test.ts: the action was renamed invokeKlavisTypePlugin → invokeComposioTypePlugin
(Klavis is being removed); update the test to call the composio action and drop
the klavis-era naming/mock field.
- store/tool/initialState.ts: order the composioStore import before connector to
satisfy simple-import-sort/imports.
* 🐛 fix(composio): stop client deleting remote connections by static allowlist
useFetchUserComposioConnections no longer deletes remote connections/plugins
for identifiers outside the compile-time COMPOSIO_APP_TYPES list — an outdated
client bundle would silently destroy a legitimate connection. Unknown
identifiers are now only hidden locally.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 🐛 fix(composio): resolve connectedAccountId server-side in executeAction
executeAction now takes `identifier` and looks up the connectedAccountId from
the caller's own user-scoped plugin record (PluginModel), instead of trusting a
connectedAccountId supplied by the client — which would let a user drive
another user's connection. Callers (callComposioTool, composioExecutor) pass
identifier accordingly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 🐛 fix(composio): enable plugin only after OAuth succeeds
Move enablePluginForAgent into the ACTIVE and post-auth-success branches so a
cancelled/timed-out authorization no longer leaves an enabled-but-unauthorized
Composio tool on the agent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 🔥 fix(composio): drop dead OAuth callback postMessage
The lobe-composio-oauth postMessage had no consumer — the OAuth wait uses
polling + window.closed detection. Remove it and its escaping helpers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 🐛 fix(composio): resolve type-check errors after canary merge
- Guard authConfigId to a definite string before persisting/returning it
(createConnection), fixing the string|undefined assignment in both the
server router and the composio store server object.
- Replace leftover KLAVIS_SERVER_TYPES with COMPOSIO_APP_TYPES in AgentTool.
- Update SkillAuthRow test to a composio source/provider (klavis is removed
from TaskTemplateSkillSource).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* ♻️ refactor(composio): remove leftover klavis naming after migration
Klavis is deprecated and fully replaced by Composio. The migration kept the
underlying composio wiring but left klavis-named identifiers, comments, prompt
tags, i18n keys, and files throughout. Sweep them to composio:
- Code identifiers/comments across ~70 files (isKlavisEnabled→isComposioEnabled,
allKlavisServers→allComposioServers, klavisManifests→composioManifests, etc.)
- LLM prompt tags (<klavis_tools>→<composio_tools>, KLAVIS_SERVICES_LIST→
COMPOSIO_SERVICES_LIST) — kept consistent across definition and substitution
- i18n keys tools.klavis.*→tools.composio.* + user-facing "Klavis"→"Composio"
brand strings, in default setting.ts and all locale setting.json files
- Rename useKlavisOAuth→useComposioOAuth, useKlavisServerActions→
useComposioServerActions (+ imports)
- klavis.ai homepage URLs → composio.dev
- Remove the dead `klavis` npm peerDependency; swap .env.example Klavis section
for Composio; update product docs
Changelog history left untouched. Pure rename — no behavior change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 🐛 fix(composio): remove duplicate composio key in CustomPluginParams
The klavis→composio rename collapsed the deprecated klavis param block onto
the live composio one, producing a duplicate `composio` property. The klavis
shape (instanceId/serverName/serverUrl/isAuthenticated) is dead — no code reads
it — so drop it and keep the live composio shape.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 🐛 fix(composio): let pending/errored connections re-authorize or be deleted
A Composio connection link (lk_...) expires after a while. Previously a
pending/errored row only offered to reopen the stored — now expired —
redirectUrl, and the delete action existed only for ACTIVE connections, so an
expired link left the tool permanently stuck: unauthenticatable and
unremovable.
- Add reauthorizeComposioConnection store action: best-effort delete the stale
connection, then mint a fresh link (replaces the record in place)
- Settings skill item + chat toolbar item: PENDING/ERROR now render a ··· menu
with Re-authorize (fresh link) and Delete
- Onboarding: pending/errored row click re-mints a fresh link instead of
reopening the stale one
- i18n: add tools.composio.reauthorize (en-US + zh-CN)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 🐛 fix(composio): return auth link instead of opening popup from agent
connectComposioService runs from the agent's response, which carries no user
gesture, so window.open was blocked by the browser and the flow always failed
with "Authorization was cancelled or timed out". Instead of opening the popup
ourselves, return the authorization redirectUrl in the tool result so the agent
can surface a clickable link — the user's click is a real gesture and completes
the OAuth normally. Drops the now-unused popup/poll helper.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 💄 fix(composio): match pending toolbar item to sibling authorize affordance
The ··· dropdown I added to the chat-toolbar Composio item was a bare icon
(inconsistent color/size with the app's standard menus), its popup was
mis-anchored/offset, and replacing the visible "authorize" cue with a ···
made an un-authorized (pending) row look connected.
Match the sibling LobehubSkillServerItem instead: render a clickable
"Re-authorize" text + external-link icon for PENDING/ERROR. Clicking re-mints a
fresh link (the prior one may have expired) and opens it. No dropdown, so no
offset; the explicit affordance makes it clear the row still needs auth. Delete
stays on the settings page (siblings have no inline delete here either).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- New docs/usage/agent/{codex,claude-code}.{mdx,zh-CN.mdx} cover how to
delegate the Codex and Claude Code CLIs from the LobeHub desktop app
(install, sign-in, working-directory pinning, in-chat tool renderers,
resume behavior, execution targets, limitations).
- Rename docs/usage/getting-started/image-generation.{mdx,zh-CN.mdx} to
generation.{mdx,zh-CN.mdx} and expand to cover the Video workspace
alongside Image.
- Update <Card> links in sibling resource/vision docs to point at the
new /generation slug.
✨ feat(bot): add iMessage Desktop bridge with Labs gate
Desktop-side BlueBubbles bridge for the iMessage channel:
- Bridge runtime (ImessageBridgeCtr/Srv) + gateway message_api_request routing;
chat-adapter-imessage api lists all webhooks instead of the 500-prone url
filter (first-time save no longer fails).
- iMessage channel UI: desktopDeviceId + webhookSecret are auto-filled/generated
(not user fields); a single "Save Configuration" persists both the cloud
provider and the local bridge via a post-save extension point — no separate
"Save Bridge" button.
- Gated behind the `enableImessage` Labs preference (off → "Coming Soon").
- Group local-testing bot skills into per-channel folders + add iMessage
bridge/outbound regression scripts.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* 🐛 fix(conversation): animate only the last assistant block markdown streaming
Switch `withMarkdownStreamingState` from disabling the first block to
disabling every block except the last one. The previous logic let middle
blocks keep `animated=true` during generation, so any remount mid-stream
replayed the typewriter from scratch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* 🔥 chore(hotkey): remove clearCurrentMessages shortcut
Drop the Alt+Shift+Backspace binding from the chat scope. The eraser
button in ActionBar still works; only the keyboard shortcut, registry
entry, hotkey i18n and docs row are gone.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: support Line
* chore: update Line docs
* feat: support line platform
* chore: update markdown files
* fix: lint error
* fix: home padding block
* fix: slack not respond to text commands
* feat: add slack slash commands instructions
* chore: add slack validate in test connections
* chore: update slack docs
* chore: remove text commands for slack
* ✨ docs: add screenshots to Telegram channel guide
* 📝 docs: Remove "feature in development" callout and developer mode requirement from channels documentation.
* docs: Migrate Telegram channel images to local assets and update CDN cache.
* docs: Add screenshots to channel setup guides for various platforms.
* chore: Update documentation image paths from GitHub user attachments to local blog assets.
---------
Co-authored-by: Rdmclin2 <rdmclin2@gmail.com>