Skip to content

[pull] main from lobehub:main#105

Open
pull[bot] wants to merge 3153 commits intoXMethues:mainfrom
lobehub:main
Open

[pull] main from lobehub:main#105
pull[bot] wants to merge 3153 commits intoXMethues:mainfrom
lobehub:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull bot commented Jan 27, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

@pull pull bot locked and limited conversation to collaborators Jan 27, 2026
@pull pull bot added ⤵️ pull merge-conflict Resolve conflicts manually labels Jan 27, 2026
arvinxx and others added 27 commits April 2, 2026 19:42
…hared UI (#13470)

* ♻️ refactor: unify tool content formatting with ComputerRuntime and shared UI components

Introduce `@lobechat/tool-runtime` with `ComputerRuntime` abstract class to ensure consistent
content formatting (via `formatCommandResult`, `formatFileContent`, etc.) across local-system,
cloud-sandbox, and skills packages. Create `@lobechat/shared-tool-ui` to share Render and
Inspector components, eliminating duplicated UI code across tool packages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: address review issues — state mapping for renders and IPC param denormalization

- Add legacy state field mappings in local-system executor (listResults, fileContent,
  searchResults) for backward compatibility with existing render components
- Add denormalizeParams in LocalSystemExecutionRuntime to map ComputerRuntime params
  back to IPC-expected field names (file_path, items, shell_id, etc.)
- Fix i18n type casting for dynamic translation keys in shared-tool-ui inspectors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ♻️ refactor: inject render capabilities via context, unify state shape for cross-package render reuse

- Add ToolRenderContext with injectable capabilities (openFile, openFolder,
  isLoading, displayRelativePath) to shared-tool-ui
- Update local-system render components (ReadLocalFile, ListFiles, SearchFiles,
  MoveLocalFiles, FileItem) to use context instead of direct Electron imports
- Enrich ReadFileState with render-compatible fields (filename, fileType,
  charCount, loc, totalCharCount)
- Cloud-sandbox now fully reuses local-system renders — renders degrade
  gracefully when capabilities are not provided (no open file buttons in sandbox)
- Remove executor-level state mapping hacks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: fix sandbox render bugs — SearchFiles, GrepContent, MoveFiles, GlobFiles

- SearchFiles: ensure results is always an array (not object passthrough)
- GrepContent: update formatGrepResults to support object matches
  `{path, content, lineNumber}` alongside string matches
- MoveFiles: render now handles both IPC format (items/oldPath/newPath) and
  ComputerRuntime format (operations/source/destination)
- GlobFiles: fallback totalCount to files.length when API returns 0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: unify SearchLocalFiles inspector with shared factory

SearchLocalFiles inspector now supports all keyword field variants
(keyword, keywords, query) and reads from unified state (results/totalCount).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: handle missing path in grep matches to avoid undefined display

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: improve render field compatibility for sandbox

- EditLocalFile render: support both file_path (IPC) and path (sandbox) args
- SearchFiles render: support keyword/keywords/query arg variants
- FileItem: derive name from path when not provided

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: add missing cloud-sandbox i18n key for noResults

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…buttons (#13495)

🐛 fix(electron): add nodrag to userinfo dropdown menus

Add `-webkit-app-region: no-drag` to ThemeButton and LangButton
dropdown popups to prevent Electron from capturing click events
when the dropdown appears in the titlebar drag region.

https://claude.ai/code/session_01K6FLLJ4PMhKWqbRmrGEZkS

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: YuTengjing <ytj2713151713@gmail.com>
* ♻️ refactor: remove @lobehub/chat-plugin-sdk dependency

Plugins have been deprecated. This removes the SDK entirely:

- Define built-in ToolManifest, ToolManifestSettings, ToolErrorType types
- Delete src/features/PluginsUI/ (plugin iframe rendering)
- Delete src/store/tool/slices/oldStore/ (deprecated plugin store)
- Delete src/server/services/pluginGateway/ (plugin gateway)
- Delete src/app/(backend)/webapi/plugin/gateway/ (plugin API route)
- Migrate all ~50 files from SDK imports to @lobechat/types
- Remove @lobehub/chat-plugin-sdk, @lobehub/chat-plugins-gateway deps
- Remove @swagger-api/apidom-reference override and patch

Fixes LOBE-6655

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: add missing getInstalledPlugins mock in customPlugin test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🔧 chore: increase Vercel build memory limit to 8192MB

The 6144MB limit was causing OOM during Vite SPA chunk rendering.
Aligned with other build commands that already use 8192MB.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ♻️ refactor: unify default tool type to builtin and fix CustomRender

- Remove `invokeDefaultTypePlugin` — default type now falls through to builtin in both server and client execution paths
- Fix `CustomRender` to actually render builtin tool components via `getBuiltinRender` instead of always returning null
- Increase SPA build memory limit from 7168MB to 8192MB to fix OOM

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ♻️ refactor: remove legacy plugin gateway and type-specific invocations

- Delete `runPluginApi`, `internal_callPluginApi`, `invokeMarkdownTypePlugin`, `invokeStandaloneTypePlugin`
- Remove plugin gateway endpoint (`/webapi/plugin/gateway`) from URL config
- Remove special `builtin → default` runtimeType mapping in plugin model
- Clean up unused imports and related tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: add 'builtin' to runtimeType union to fix type error

Use ToolManifestType instead of inline union for runtimeType fields
so that 'builtin' is included as a valid type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ✨ feat(cli): register task command and add kanban board view

Register the missing `registerTaskCommand` in program.ts so `lh task` commands are accessible. Add `--board` flag to `task list` that renders a kanban-style view grouping tasks by status columns (backlog, running, paused, completed, etc.) with color-coded borders.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* update

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 🐛 fix: stream tool call arguments incrementally in Response API

The tool_calling stream chunks contain accumulated arguments (not
deltas), but the Response API was treating each chunk as a complete
independent output_item — creating a new lifecycle (added → delta →
done) per token and incrementing output_index to 90+.

Fix: track active tool calls by call_id and compute true incremental
deltas by slicing off previously-seen content. Each tool call now
gets a single stable output_item with proper streaming deltas,
finalized only when the stream ends or tool execution begins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: clear stale tool-call state on LLM stream retry

When call_llm retries after a failed attempt, activeToolCalls may
contain entries from the failed stream that never received a
tool_end. Without clearing, finishActiveToolCalls would emit
phantom function_call done events and misalign output_index for
the successful attempt. Reset the map on stream_retry.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lable tools (#13417)

♻️ refactor: extract server tool discovery config builder
* ✨ feat: implement AI input auto-completion with ReactAutoCompletePlugin

Adds GitHub Copilot-style ghost text completion to the chat input,
powered by a configurable system agent (disabled by default).

Key changes:
- Add `inputCompletion` system agent config (type, default, selector, i18n)
- Create `chainInputCompletion` prompt chain (V2 few-shot, benchmarked)
- Mount `ReactAutoCompletePlugin` in InputEditor when enabled
- Wire `getMessages` through ChatInput store for conversation context
- Add settings UI in Service Model page with enable toggle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ✅ test: update systemAgent snapshot for inputCompletion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: restrict auto-complete context to visible user/assistant turns

Filter getMessages to use displayMessages (active visible thread)
instead of dbMessages (raw DB records including tool messages and
inactive branches). Also limit to last 10 user/assistant turns to
keep payload small and relevant.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ✨ feat: enable input completion by default

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ⚡️ perf: use non-streaming for input completion requests

Autocomplete needs the full result before displaying ghost text,
so streaming adds unnecessary overhead. Setting stream: false
reduces latency by avoiding SSE chunking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: revert stream:false for input completion

fetchPresetTaskResult uses fetchSSE internally which cannot handle
non-streaming JSON responses, causing the editor to freeze after
receiving the completion result.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ⚡️ perf: use non-streaming for input completion requests

Autocomplete waits for the full result before displaying ghost text.
fetchSSE handles non-streaming responses via its fallback path
(response.clone().text()), avoiding SSE chunking overhead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ⚡️ perf: skip contextEngineering for input completion

Call getChatCompletion directly instead of fetchPresetTaskResult
to avoid triggering agentDocument.getDocuments on every autocomplete
request. Input completion only needs a simple LLM call with the
prompt chain, not the full context engineering pipeline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ♻️ refactor: revert to fetchPresetTaskResult for input completion

Use the standard contextEngineering pipeline. The agentDocument
overhead will be addressed separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 docs: add SECURITY.md with vulnerability reporting policy

Define supported versions, reporting guidelines, response timeline, scope (in/out), and disclosure policy for security vulnerabilities.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
)

✨ feat: add Task store with service layer, selectors, and 4 slices (LOBE-6597)

Implement frontend Task system state management:
- Service layer wrapping all TRPC task/brief endpoints
- List slice: SWR fetch by agent, list/kanban view mode
- Detail slice: CRUD with optimistic updates, immer reducer
- Lifecycle slice: run/pause/cancel/complete/resume, heartbeat ping
- Config slice: checkpoint, review, brief ops (model config deferred to LOBE-6634)
- Selectors: list (kanban columns, display status), detail (field accessors, operation guards), activity (sorted/filtered)
- Types derived from TRPC inference (TaskListItem, TaskStatus)
- 118 tests across 9 test files

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…SS-to-RCE (#13529)

* 🔒 fix: sanitize HTML artifact content and sandbox iframe to prevent XSS-to-RCE

- Add sanitizeHTMLContent() using DOMPurify to strip dangerous tags (script, embed, object, etc.) and all on* event handler attributes
- Add sandbox="" attribute to HTML artifact iframe to block all script execution and parent frame access
- Replace doc.write() with srcDoc for cleaner rendering
- Extract shared FORBID_EVENT_HANDLERS list to DRY up SVG and HTML sanitization

Ref: GHSA-xq4x-622m-q8fq

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: correct import path from @lobehub/utils to @lobechat/utils

The package name is @lobechat/utils, not @lobehub/utils. This caused a build failure in Electron desktop app.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…fig incompatibility (#13524)

* 🐛 fix(model-runtime): resolve Vertex AI $ref schema error and toolConfig incompatibility

1. Dereference $ref in JSON Schema before sending to Google/Vertex AI — the memory
   tool manifest (from neko's recent refactor) uses $ref which Vertex AI rejects.
2. Skip includeServerSideToolInvocations for Vertex AI — only Google AI supports it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix(model-runtime): preserve sibling schema fields when resolving $ref

When a schema node has $ref plus sibling keys (e.g. description from
allOf unwrapping), the resolved definition now merges with those siblings
instead of dropping them. This preserves argument-level descriptions for
fields like timeIntent, improving tool-call quality.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ♻️ refactor: support minimal execAgent resume flow

* ♻️ refactor execAgent resume to caller-owned continuation context

* 📝 fix execAgent topic metadata comment

* 🚚 revert non-essential public execAgent resume changes

* 🚚 narrow execAgent resume changes to internal service scope

* 🚚 keep execAgent resume scoped to internal service

* 📝 restore taskId in execAgent runtime appContext

* ✨ add agent eval trajectory resume

* ♻️ route agent eval resume through workflow

* 🩹 tighten eval resume workflow semantics

* ♻️ refine agent eval resume semantics

* ♻️ simplify resume workflow dispatch

* wip: rm redundancy interfaces

* wip: trim code

* wip: remove unuse

* wip: add eval detail resume btn

* 🐛 fix: message chains

* 🐛 fix: incorrect steps & cost count

* 🐛 fix: should allow start from non-zero step

* 🐛 fix: batch resume

* 🐛 fix: import

* ♻️ restore retry visibility guard in eval case table

* 🐛 fix: should not check run status

* 🐛 fix agent eval resume test regressions

* 🐛 fix: allow retry pass@k trajectory

* 🐛 fix eval case thread messages during run

* 🐛 fix pass@k batch resume target resolution

* 🐛 fix eval resume thread state handling

* ♻️ simplify eval resume validation

* 🚑 fix lint:ts interface order

* wip: fix lint

* 🐛 enforce max steps per resumed eval thread

* 🐛 avoid topic-level max steps check for pass@k resumes
fix: slove the lobehub skill cant use activator to active
* ✨ support device binding in lh agent run

* ✅ align device binding tests with current behavior
* fix: add the cronjob tools executiors

* fix: should use mutate to refresh the cronjob when it changes && add it into backend runtime

* fix: add the lost deps

* fix: should await the delete servers
…#13525)

Bumps [electron](https://github.com/electron/electron) from 41.0.2 to 41.0.3.
- [Release notes](https://github.com/electron/electron/releases)
- [Commits](electron/electron@v41.0.2...v41.0.3)

---
updated-dependencies:
- dependency-name: electron
  dependency-version: 41.0.3
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Innei and others added 30 commits April 15, 2026 23:30
…is pending (#13847)

* 🐛 fix(conversation): improve workflow display when user intervention is pending

Made-with: Cursor

* 🐛 fix(builtin-tool-activator): add ActivatedToolInfo typing to requestedTools for tsgo compat

requestedTools was inferred as `{ identifier, name }[]` which lacks the
`avatar` property required by `ActivatedToolInfo`, causing tsgo errors.
💄 style(chat): tighten `execServerAgentRuntime` loading copy

Current text was trying to do too much in one line — status + two
separate user affordances — and read as an explanation, not a status.
Replaces it with a status-first line that mentions where the work is
happening and the single reassurance users actually need.

- EN: "Task is running in the server. You are safe to leave this page."
- zh-CN: "任务正在服务器运行,您可以放心离开此页面。"

Only en-US and zh-CN are edited; CI translates the rest from the
default file.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ests (#13838)

🌐 chore: translate non-English comments to English in lambda router tests

Translated all Chinese/CJK comments to English in 6 test files under
src/server/routers/lambda/__tests__/. Code logic and string literals
are unchanged; only explanatory comments were translated.

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* ✨ feat(builtin-tool-gtd): add server runtime for GTD tool

Implement server-side execution runtime so the GTD tool works when
agents run in a pure server context (bot platforms, async task workers,
QStash workflows). Previously only the client executor existed, which
relied on `useNotebookStore` and `notebookService` and would break on
the server.

- `packages/builtin-tool-gtd/src/ExecutionRuntime/index.ts`: pure
  `GTDExecutionRuntime` class with an injected service interface,
  covering createPlan/updatePlan/createTodos/updateTodos/clearTodos
  and execTask/execTasks. Since server runtime has no stepContext,
  todo state is read from / written back to the Plan document's
  `metadata.todos` field.
- `src/server/services/toolExecution/serverRuntimes/gtd.ts`: factory
  wiring `DocumentModel` + `TopicDocumentModel` into the runtime and
  registering under `GTDIdentifier`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ♻️ refactor(builtin-tool-gtd): share runtime logic between executor and server

Make the client executor a thin adapter over `GTDExecutionRuntime` so
all processing logic (todo reducer, plan CRUD flow, execTask state
builder, output formatting) lives in one place. Previously the server
runtime was a near-duplicate of the client executor.

- Expand `GTDRuntimeContext` with `currentTodos`, `messageId`, `signal`
  so both callers can thread their environment through:
  - client supplies `currentTodos` from stepContext / pluginState via
    `getTodosFromContext`, and `messageId` for execTask parentMessageId
  - server lets the runtime resolve todos from the plan document's
    metadata when `currentTodos` is not supplied
- Split service surface into `updatePlan` (user-facing: goal / desc /
  context — client routes through `useNotebookStore` to refresh SWR)
  vs `updatePlanMetadata` (silent todos sync — client stays on the
  raw `notebookService`)
- Runtime methods now return `BuiltinToolResult` (superset of
  `BuiltinServerRuntimeOutput`), so `stop: true` on execTask /
  execTasks is typed cleanly without `@ts-expect-error`

Net effect: `executor/index.ts` shrinks from 510 → 134 lines; the
server factory just maps models to the service interface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🐛 fix(toolEngineering): drop manifests missing `api` before feeding ToolsEngine

`ToolsEngine.convertManifestsToTools` calls `manifest.api.map(...)`
without a null check, so any manifest that is truthy but lacks a valid
`api` array crashes the entire tools build with "Cannot read properties
of undefined (reading 'map')". This takes down anything that touches
the tools pipeline on that agent — including TokenTag in ChatInput,
which is why users see the crash on the chat page load path.

Manifests are merged from 5 sources (installed plugins, builtin tools,
Klavis, LobeHub skills, caller-supplied extras), only some of which
filter falsy entries, and none validate `api`. Guard defensively at
the merge point and log the offending source + identifier so the
underlying bad data can be traced.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* improve style

* improve style
…13860)

* 🐛 fix(gateway): clean up paused server op after human approve/reject

In Gateway mode with userInterventionConfig.approvalMode='ask', the
paused execServerAgentRuntime op was never released — the loading
spinner kept spinning after the user approved, rejected, or
reject-and-continued, and reject-only silently did nothing on the
server.

- ToolAction.rejectToolCall now delegates to chatStore.rejectToolCalling
  so the Gateway resume op actually fires with decision='rejected';
  previously it only mutated local intervention state and the server's
  paused op waited forever.
- AgentRuntimeCoordinator treats waiting_for_human as end-of-stream so
  the coordinator emits agent_runtime_end when request_human_approve
  flips state, letting the client close the paused op via the normal
  terminal-event path.
- conversationControl adds #completeRunningServerOps as a fallback
  guard in the approve/reject/reject-continue Gateway branches — if
  the server-side signal is delayed or missing, the client still clears
  the orphan op before starting the resume op.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix(gateway): defer paused-op cleanup until resume starts successfully

If `executeGatewayAgent` failed (transient network/auth/server error),
the paused `execServerAgentRuntime` op was already marked completed
locally by the pre-call `#completeRunningServerOps`. Retries would
then see no running server op, miss `#hasRunningServerOp`, and fall
through to the non-Gateway client-mode path — while the backend was
still paused awaiting human input.

Snapshot the paused op IDs before the resume call and retire them
only inside the try block after `executeGatewayAgent` resolves. On
failure the running marker stays intact so a retry still lands on
the Gateway branch and can re-issue the resume.

The helper was renamed from `#completeRunningServerOps(context)` to
`#completeOpsById(ids)` to reflect the new contract: callers must
snapshot beforehand, not re-query at completion time (which would
incorrectly match the new resume op too).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix(gateway): avoid double reject dispatch in reject-and-continue

Now that `rejectToolCall` delegates to `chatStore.rejectToolCalling`,
the chained `await get().rejectToolCall(...)` inside
`rejectAndContinueToolCall` fired a full halting reject before the
continue call. In Gateway mode that meant two resume ops on the same
tool_call_id (`decision='rejected'` followed by
`decision='rejected_continue'`) racing server-side; in client mode it
duplicated reject bookkeeping that `chatStore.rejectAndContinueToolCalling`
already handles internally.

Drop the chained call and fire `onToolRejected` inline so hook
semantics are preserved. `chatStore.rejectAndContinueToolCalling` is
now the single entry point for both the rejection persist and the
continue dispatch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🐛 fix(gateway): route approve/reject via lab flag, not transient server op state

After the coordinator fix for `waiting_for_human` (#13860) the paused
`execServerAgentRuntime` op is marked `completed` client-side as soon
as the server emits `agent_runtime_end`. `startOperation` then runs
`cleanupCompletedOperations(30_000)`, which deletes any op completed
more than 30 seconds ago — so by the time the user sees the
InterventionBar and clicks approve/reject, the running (or recently
completed) server op is gone.

The previous `#hasRunningServerOp` check therefore kept returning
false against a live Gateway backend, flipping approve/reject into
the client-mode `internal_execAgentRuntime` branch and stranding the
server-side paused conversation.

Switch the helper to `#shouldUseGatewayResume`, which checks the same
`isGatewayModeEnabled()` lab flag used to route the initial send. The
signal now mirrors how the conversation was dispatched and survives
the op-cleanup window.

New regression test exercises the post-coordinator-fix state: the
paused `execServerAgentRuntime` op is explicitly `completed` before
the approve call runs, and we still expect the Gateway branch to
fire with `decision='approved'`.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nue (#13865)

* ♻️ refactor(chat): remove reject-only button, unify to rejected_continue

Server-side `decision='rejected'` and `decision='rejected_continue'`
share the exact same code path — both surface the rejection to the
LLM as user feedback. Having a separate "reject only" button added UI
complexity without behavioural difference.

- Remove the "仅拒绝" button from InterventionBar popover; the single
  "拒绝" button now calls `rejectAndContinueToolCall` directly
- `rejectToolCalling` Gateway branch sends `rejected_continue` instead
  of `rejected` so all rejection paths use one decision value

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update ApprovalActions.tsx

* ✨ feat(tool): add executors field to BuiltinToolManifest and dispatch page-agent to client

Add `executors?: ('client' | 'server')[]` to `BuiltinToolManifest` so
each builtin tool declares where it can run. The server-side dispatch
logic in `aiAgent/index.ts` now reads this field instead of hardcoding
per-identifier checks.

- `lobe-local-system`: `executors: ['client', 'server']` — runs on
  client via Electron IPC or server via Remote Device proxy
- `lobe-page-agent`: `executors: ['client']` — requires EditorRuntime,
  client-only
- Stdio MCP plugins still use the `customParams.mcp.type` heuristic
  (not manifest-driven)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…t` package (#13866)

* ♻️ refactor: extract agent-stream into @lobechat/agent-gateway-client package

Move the Agent Gateway WebSocket client from src/libs/agent-stream/ into
a standalone workspace package at packages/agent-gateway-client/. This
eliminates the duplicate AgentStreamEvent type in apps/cli and provides
a single source of truth for the Gateway WS protocol types shared by
SPA, server, and CLI consumers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* add agent-gateway-client

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: improve the skill execution error body back
…ler-tests (#13867)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* ♻️ refactor: createAgent uses agentModel.create directly

The createAgent router was still going through sessionModel.create,
which is a legacy path that doesn't pass all agent fields (like
agencyConfig) to the agents table. Switch to agentModel.create
which directly inserts into the agents table with full field support.

- Add CreateAgentSchema in types package for proper input validation
- Remove dependency on insertAgentSchema from database package
- Remove sessionId from CreateAgentResult

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🏷️ chore: mark session-based agent creation as deprecated

Add @deprecated JSDoc tags to the legacy session-based agent creation
path (session router, SessionService, SessionModel.create, session store,
insertAgentSchema). New code should use agent.createAgent / agentModel.create
directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: honor groupId when creating agents

Pass input.groupId as sessionGroupId to agentModel.create so that
agents created from a sidebar folder are correctly assigned to that group.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 🐛 fix: resolve type errors from createAgent refactor

- Remove sessionId fallback in AddAgent.tsx and ForkAndChat.tsx
- Use z.custom<T>() for agencyConfig and tts in CreateAgentSchema
  to match agentModel.create parameter types

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 🐛 fix: default execAgent approval mode to headless

Backend execAgent calls should run headlessly by default since only
frontend scenarios require manual human approval. This prevents cron
jobs and other server-side triggers from unexpectedly waiting for
human intervention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ✅ test: add regression test for headless approval default

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mpt (#13872)

Update `pageEditor.editorPlaceholder` from `Start writing your page. Press / to open the command menu` to `Press "/" for AI and commands.` across all supported locales and the default locale source.
…-pdf/svg

Picked from canary commit 9f61b58.
- Bump @react-pdf/renderer from ^4.3.2 to 4.4.1
- Pin @react-pdf/image to 3.0.4 via pnpm.overrides
* chore: update skills dir

* chore: remove unused recent fetch actions and components

* fix: recent delete functions

* chore: update comments
…o title (#13877)

* ♻️ refactor: add backgroundColor to TaskParticipant and rename name to title

Add backgroundColor field and rename name→title in TaskParticipant interface
to match agent avatar data. Add LobeAI fallback for inbox agent in
getAgentAvatarsByIds when avatar/title are missing.
* feat: add some lost lobe-kb builtin tools

* feat: add the list files and get file detail

* feat: add the list files and get file detail

* fix: update the search limit
* chore: add  ENABLE_BOT_IN_DEV swtich

* chore: add explicit judge
* update

* update

* 🔧 chore: update CLI build command in electron-builder and ensure proper newline in package.json

* Changed the CLI build command from 'npm run build' to 'npm run build:cli' in electron-builder.mjs.
* Added a newline at the end of package.json for consistency.

Signed-off-by: Innei <tukon479@gmail.com>

---------

Signed-off-by: Innei <tukon479@gmail.com>
Co-authored-by: Innei <tukon479@gmail.com>
#### 💻 Change Type

- [ ] ✨ feat
- [ ] 🐛 fix
- [ ] ♻️ refactor
- [ ] 💄 style
- [x] 👷 build
- [ ] ⚡️ perf
- [ ] ✅ test
- [ ] 📝 docs
- [ ] 🔨 chore

#### 🔗 Related Issue

- None

#### 🔀 Description of Change

- Extract the document history database changes from the feature branch
onto a branch based on main.
- Add the document history migration, schema, relations, model, and
database tests only.
- Exclude UI, router, and service-layer changes so the PR stays focused
on the database layer.

#### 🧪 How to Test

- Run: cd packages/database && bunx vitest run --silent=passed-only
src/models/__tests__/document.test.ts
src/models/__tests__/documentHistory.test.ts
- [x] Tested locally
- [x] Added or updated tests
- [ ] No tests needed

#### 📸 Screenshots / Videos

| Before | After |
| ------ | ----- |
| N/A | N/A |

#### 📝 Additional Information

- This PR intentionally targets main because the database migration
needs to land on the release branch first.
* 🔨 chore: update .vscode/settings.json (#13894)

* 🐛 fix(builtin-tool-local-system): honor glob scope in local system tool (#13875)

Made-with: Cursor

* 📝 docs: Update changelog docs and release skills (#13897)

- Update changelog documentation format across all historical changelog files
- Merge release-changelog-style skill into version-release skill
- Update changelog examples with improved formatting and structure

Made-with: Cursor

---------

Co-authored-by: YuTengjing <ytj2713151713@gmail.com>
Co-authored-by: Innei <i@innei.in>
# 🚀 LobeHub v2.1.50 (20260416)

**Release Date:** April 16, 2026\
**Since v2.1.49:** 107 commits · 101 merged PRs · 13 contributors

> This weekly release focuses on improving runtime stability and gateway
execution consistency, while making Home/Recents workflows faster to
navigate and easier to manage in daily use.

---

## ✨ Highlights

- **Server-side Human Approval Flow** — Agent runtime now supports more
reliable approve/reject/reject-continue handling in gateway mode,
reducing stalled execution paths in long-running tasks. (#13829, #13863,
#13873)

- **Message Gateway End-to-End Hardening** — Gateway message flow, queue
handling, tool callback routing, and stop interruption behavior were
strengthened for better execution continuity. (#13761, #13816, #13820,
#13815)

- **Client Tool Execution in Gateway Mode** — Client-executor tools now
run more predictably across gateway and desktop callers, with improved
executor dispatch behavior. (#13792, #13790)

- **Home / Recents / Sidebar Upgrade** — Sidebar layout, custom sort,
recents operations, and profile actions were improved to reduce
navigation friction in active sessions. (#13719, #13812, #13723, #13739,
#13878, #13734)

- **Agent Workspace and Documents Expansion** — Working panel and agent
document workflows were expanded and polished for better day-to-day
agent operations. (#13766, #13857)

- **Provider and Model Compatibility Improvements** — Added GLM-5.1
support and refined model/provider edge-case handling, including schema
and error-path fixes. (#13757, #13806, #13736, #13740)

---

## 🏗️ Core Agent & Architecture

### Agent runtime and intervention lifecycle

- Added server-side human approval and improved runtime coordination
across approve/reject decision paths. (#13829, #13863)
- Improved interrupted-task handling and operation lifecycle consistency
to reduce half-finished runtime states. (#13714)
- Refined error classification and payload propagation so downstream
surfaces receive clearer actionable errors. (#13736, #13740)

### Execution model and dispatch behavior

- Introduced executor-aware runtime behavior to better separate
client/server tool execution semantics. (#13758)
- Improved tool/plugin resolution and manifest handling to avoid runtime
failures on malformed inputs. (#13856, #13840, #13807)

---

## 📱 Gateway & Platform Integrations

- Added message gateway support and strengthened queue/error behavior
for more stable cross-channel execution. (#13761, #13816, #13820)
- Improved gateway callback pipeline with protocol and API additions for
`tool_execute` / `tool_result`. (#13762, #13764, #13765)
- Improved bot/channel reliability and DM/slash handling in
Discord-related paths. (#13805, #13724)

---

## 🖥️ CLI & User Experience

- Improved CLI reliability across message/topic operations and
build/minify-related paths. (#13731, #13888)
- Added image-to-video options and improved command behavior for
generation workflows. (#13788)
- Improved desktop runtime behavior for remote fetch and Linux
notification urgency handling. (#13789, #13782)

---

## 🔧 Tooling

- Extracted gateway stream client into `@lobechat/agent-gateway-client`
to centralize protocol usage and reduce duplication. (#13866)
- Improved built-in tool coverage and runtime support, including GTD
server runtime and missing lobe-kb tools. (#13854, #13876)
- Updated skill and frontmatter consistency in workflow tooling.
(#13730)

---

## 🔒 Security & Reliability

- **Security:** Strengthened API key WS auth behavior and safer
serverUrl forwarding in gateway-related auth paths. (#13824)
- **Reliability:** Reduced runtime stalls by improving gateway
stop/interrupt and approval-state routing behavior. (#13815, #13863,
#13873)
- **Reliability:** Added defensive guards for malformed tool manifests
and non-string content edge cases. (#13856, #13753)

---

## 👥 Contributors

**101 merged PRs** from **13 contributors** across **107 commits**.

### Community Contributors

- @arvinxx - Runtime, gateway, and execution reliability improvements
- @Innei - Navigation, workflow UX, and desktop/CLI refinements
- @rdmclin2 - Sidebar, recents, and channel behavior updates
- @ONLY-yours - Tooling/runtime fixes and model execution compatibility
- @tjx666 - Model support and release/tooling maintenance
- @nekomeowww - Memory and search-path stability fixes
- @cy948 - CLI indexing and command flow fixes
- @octo-patch - Local system runtime edge-case fixes
- @djthread - Desktop runtime request reliability improvements
- @rivertwilight - Documentation and changelog updates
- @sudongyuer - Subscription/mobile support improvements
- @Zhouguanyang - Provider/model configuration correctness fixes
- @lobehubbot - Translation and maintenance automation support

---

**Full Changelog**: v2.1.49...v2.1.50
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

⤵️ pull merge-conflict Resolve conflicts manually

Projects

None yet

Development

Successfully merging this pull request may close these issues.