mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-13 19:20:04 +00:00
049c81d53b0c2282eabf1edca2d90d58ad1f60f0
3423 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
049c81d53b | 🔖 chore(release): release version v2.2.1 [skip ci] | ||
|
|
49d191d2a7 | 🐛 fix: unify TypeScript peer resolution on 6.x (#15263) | ||
|
|
bcc31ca331 |
✨ feat(bot): add hidden iMessage backend foundation (#15227)
* ✨ feat(bot): add hidden iMessage backend foundation * 🐛 fix(bot): align iMessage search totals and attachment timeout * ♻️ refactor(bot): derive gateway runtime user from provider * ✨ feat(device): add message API calls |
||
|
|
2ee53bcd60 |
⬆️ chore(deps): bump @lobehub/ui to 5.15.1 (#15214)
5.15.1 adds `&[data-has-header] { padding-block-start: 0 }` and
`&[data-has-footer] { padding-block-end: 0 }` on the menu popup, so the
4px block padding the slot content used to bleed into no longer exists.
Drop the `margin-block-*: -4px` compensations on the Plus menu's tools
search box, stats footer, and knowledge "view more" button to avoid
content being clipped by the popup's `overflow: hidden`.
|
||
|
|
46f884d5ed |
chore(llm-generation-tracing): pre-allocate tracingId + recordFeedback router (#15146)
* ✨ feat(llm-generation-tracing): pre-allocate tracingId + recordFeedback router Wire up the per-call feedback loop foundation. 1. **Pre-allocate tracingId (plan A2)** - `TracingOptions.tracingId?: string` — optional caller-supplied UUID. - `LLMGenerationTracingService.record` generates one via `randomUUID()` when the caller doesn't supply one, so the id is always known before DB insert. - `LlmGenerationTracingModel.record` accepts an optional `id` and forwards it to the insert (Drizzle still autogens when omitted). - `aiChat.outputJSON` allocates the id up-front, threads it through `tracing.tracingId`, and returns `{ data, tracingId }` so the client can wire feedback against the id even though `service.record` runs inside Next's `after()`. - `aiChatService.generateJSON` consumers (InputEditor, supervisor) unwrap the envelope. 2. **New `llmGenerationTracingRouter.recordFeedback`** - Scenario-agnostic feedback endpoint at `lambda.llmGenerationTracing`. - Validates `{ tracingId (uuid), signal (positive|negative|neutral), source, score?, data? }` and forwards to `LLMGenerationTracingService.recordFeedback`. Follow-up issues already filed: - LOBE-9488 — `@lobehub/editor` AutoCompletePlugin needs `onAccept`/`onReject`/`onCancel` callbacks before the client side can capture Tab/Esc/keep-typing signals against the returned tracingId. - LOBE-9489 — session-level signal modeling (multi-suggestion typing sessions) — deferred until per-row feedback data lands. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * 🐛 fix(llm-generation-tracing): surface feedback write failures instead of silent ok The recordFeedback mutation used to always return `{ ok: true }` even when the underlying write was silently dropped — `LLMGenerationTracingService` swallowed both DB-init/update throws and the no-op case where the WHERE clause (id + userId) matched zero rows. Callers couldn't tell "persisted" from "lost", which would skew tracing-feedback metrics and prevent reasoned retry/error handling. Fix: - `LlmGenerationTracingModel.updateFeedback` now returns `{ updated: boolean }` (via `.returning({ id })`), so the caller knows whether the WHERE clause actually matched a row. - `LLMGenerationTracingService.recordFeedback` throws a typed `LLMGenerationFeedbackError` with `kind: 'not_found' | 'db_failure'` instead of swallowing — stops logging-only behaviour for DB errors and promotes the 0-rows case to an explicit signal. - `llmGenerationTracingRouter.recordFeedback` catches that error and translates to `TRPCError({ code: 'NOT_FOUND' })` for stale-id and `INTERNAL_SERVER_ERROR` for DB outages — `{ ok: true }` only flows back when a row was actually patched. Tests: - Model: assert `{ updated: true/false }` for happy / cross-user / missing-id - Service: assert throws on both not_found scenarios - Router: assert TRPCError code translation for both error kinds Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ✨ feat(input-completion): wire Tab/Esc/typing feedback to recordFeedback - bump @lobehub/editor to ^4.12.0 for AutoComplete onSuggestion{Accepted,Rejected} - add llmGenerationTracingService wrapping lambda.llmGenerationTracing.recordFeedback - InputEditor: map suggestionId→tracingId, fire positive on accept, negative on esc, neutral on typing/cursor-move/blur/other; recode IME-driven escape as neutral/autocomplete_ime so CJK input doesn't poison the signal Closes LOBE-9488 * ♻️ refactor(input-completion): fold recordTracingFeedback into aiChatService Single trpc mutation didn't warrant a dedicated service file; aiChatService already owns the paired `outputJSON` call that mints the tracingId, so recordTracingFeedback belongs alongside it. * 💄 style(llm-generation-tracing): tag task-handoff scenario + prompt version (#15191) * 💄 style(QueueTray): use borderless variant for queued file preview Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ✨ feat(llm-generation-tracing): tag task-handoff scenario + prompt version Task topic handoff was tracing as scenario=unknown / promptVersion=v0 because the generateObject call only set metadata.trigger and that trigger isn't in the registry. Add a TaskHandoff scenario const, version the prompt next to its definition, and pass tracing options explicitly at the call site (mirroring followUpAction). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(llm-generation-tracing): validate caller-supplied tracingId as UUID The `outputJSON` route echoed `tracing.tracingId` back to clients without checking the shape. Because the surrounding `tracing` record is free-form, a malformed value passed request validation, then failed DB insertion on the uuid PK and was later rejected by `recordFeedback` (`z.string().uuid()`), so callers could receive a tracingId unusable for the feedback flow. Tighten `StructureOutputSchema.tracing` to a `z.object({ tracingId: uuid }).catchall(unknown)` so the validation happens at the request boundary; the route can then drop the redundant `typeof === 'string'` guard. --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
cce14911d1 |
✨ feat: per-call llm_generation_tracing observability (#15124)
* ✨ feat(database): add llm_generation_tracing schema + tracing package (LOBE-9462) Foundation layer for per-call observability of `generateObject` calls. - New Drizzle table `llm_generation_tracing` with identity / context / model / result / usage / storage / feedback / audit columns and full single-column index coverage (Postgres bitmap-scan friendly). Migration 0103 is idempotent (CREATE TABLE/INDEX IF NOT EXISTS) for safe re-runs. - `LlmGenerationTracingModel` with `record` / `updateFeedback` / `findById` / `listRecent`, all userId-scoped to prevent cross-user leaks. - New package `@lobechat/llm-generation-tracing` mirroring agent-tracing's shape: `ITracingStore` interface, `FileTracingStore` (local/dev, scenario subfolders + latest.json symlink), `computePromptHash` (6-char sha256 of systemPrompt + schema), and `TRACING_SCENARIO_REGISTRY` + `resolveScenario` with explicit scenario override. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ✨ feat(model-runtime): wire llm_generation_tracing into ModelRuntime.generateObject (LOBE-9462) Per-call interception layer — one hook covers all generateObject callers. - New `onGenerateObjectComplete` hook on `ModelRuntimeHooks`: always fires (success or failure) with latency, usage, output/error. Fixes the gap where `onGenerateObjectFinal` only fires when the runtime invokes `onUsage`. - `S3TracingStore` (zstd level 3, key `llm-generation-tracing/{scenario}/{v}-{hash}/{date}/{id}.json.zst`) and `LLMGenerationTracingService` that does DB insert → store.save → patch storage_key. Store failures preserve the row with `metadata.store_error`. - `createLLMGenerationTracingHook` + `mergeModelRuntimeHooks` wired into `initModelRuntimeFromDB`; tracing runs alongside business (billing) hooks via `next/server.after()` when available, microtask fallback otherwise. Unknown metadata keys (e.g. `parent_memory_trace_key`) pass through. - Memory extractor accepts `parentMemoryTraceKey` option for the job-level backlink. Follow-up-action caller given an explicit `scenario: 'follow_up'` metadata override — it was the only OSS caller missing trigger metadata. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ✅ test(llm-generation-tracing): type vi.fn mocks so tsgo accepts mock.calls indexing The hook + service tests destructured `mock.calls[0][0]` and accessed nested fields, which tsgo flagged as TS2493 / TS18046 because `vi.fn()` defaults to a zero-arg signature. Add explicit type parameters to the mocks so tsgo can infer the call tuple, and cast `call.payload` at the access point. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(model-runtime): move mergeModelRuntimeHooks into the package It's a generic utility for composing `ModelRuntimeHooks` instances — same import surface as `ModelRuntime` and the hooks interface — so it belongs alongside them rather than tucked under a server-side consumer. - New `packages/model-runtime/src/core/mergeHooks.ts` exports `mergeModelRuntimeHooks` and is re-exported from the package index. - Move the unit tests to `packages/model-runtime/src/core/mergeHooks.test.ts`, including a new case covering the "a throws → b is skipped" load-bearing semantics. - `src/server/services/llmGenerationTracing/hook.ts` drops the local copy and the consumer (`src/server/modules/ModelRuntime/index.ts`) imports from `@lobechat/model-runtime`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(llm-generation-tracing): version lives with the prompt, not in a central table `promptVersion` was baked into `TRACING_SCENARIO_REGISTRY`, far from any prompt definition — editing a prompt + forgetting to bump the entry in a completely different file was an obvious foot-gun. - Registry is now `Record<string, string>` mapping trigger → scenario only; it's the stable concern that rarely changes. - `resolveScenario` always passes `promptVersion` through from the caller, defaulting to `UNKNOWN_PROMPT_VERSION` ('v0') when absent. - Each call site declares its own `*_PROMPT_VERSION` constant next to the prompt it describes. `followUpAction` ships the first one: `FOLLOW_UP_PROMPT_VERSION` in `prompts/index.ts`, threaded through `metadata.promptVersion` at the `generateObject` call. Other callers can add the same constant when they next touch their prompts. The 6-char prompt hash on the row still catches forgotten bumps. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ✨ feat(input-completion): wire prompt-version metadata at the auto-complete call site Aligns input auto-complete with the FOLLOW_UP_PROMPT_VERSION convention so each prompt iteration is recordable as the chat-side tracing lands. - `INPUT_COMPLETION_PROMPT_VERSION = 'v1.0'` declared next to `chainInputCompletion` — bump together with the prompt body. - `fetchPresetTaskResult` accepts optional `metadata` and forwards it to `getChatCompletion`; the existing chat path already plumbs metadata to `ModelRuntime.chat` options. - `InputEditor` call site passes `{ scenario: 'input_completion', promptVersion }`. Note: `llm_generation_tracing` currently only fires from `onGenerateObjectComplete`. Input completion is a `chat` call, so this metadata is forward-looking until a chat-side tracing hook lands. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * 🐛 fix(llm-generation-tracing): collapse bucketDir path.join args to silence turbopack glob warning Turbopack's static analyzer treats `path.join(root, dyn1, dyn2)` as a multi-segment glob pattern and warned that it could match ~12k files in the project. Compose the relative subdir as a single string first, so `path.join` only sees one dynamic segment. Behavior unchanged — the resulting path is identical. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ✨ feat(input-completion): route auto-complete through generateObject for tracing Auto-complete is the first preset-task caller migrated to the structured- output path so it lands in `llm_generation_tracing` via the existing `onGenerateObjectComplete` hook. No new server hook, no global chat-side tracing. - `chainInputCompletion` now returns `{ messages, schema }` with a minimal `{ completion: string }` schema and a stable `INPUT_COMPLETION_SCHEMA_NAME` constant. JSON wrapping costs ~15-30 tokens against a 100-token completion budget — negligible for the observability win. - `StructureOutputSchema` / `StructureOutputParams` accept optional `metadata`; `aiChatRouter.outputJSON` merges caller metadata over the default trigger so `{ scenario, promptVersion, schemaName }` reach `ModelRuntime.generateObject` options unchanged. - `IStructureSchema.description` is now optional to match the zod schema — previously the TS type was stricter than runtime validation accepted. - `InputEditor` switches from `chatService.fetchPresetTaskResult` to `aiChatService.generateJSON`, reading `response.completion`. Streaming is dropped because auto-complete already buffers the full result before inserting; no UX change. - Reverts the unused `metadata` field that was added to `fetchPresetTaskResult` in the previous commit — no current caller needs it now that input completion uses the generateObject path. Bumps `INPUT_COMPLETION_PROMPT_VERSION` to v2.0 because the system prompt gained an "output the completion field" instruction. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(aiGeneration): extract the runtime-init + generateObject dance into a service Every server-side caller that produces structured output was repeating the same two-step ritual: `initModelRuntimeFromDB(...)` → `runtime.generateObject(payload, { metadata })`. `AiGenerationService` collapses it into one call so future cross-cutting concerns (default metadata, retry, observability hooks) have one place to land. - New `src/server/services/aiGeneration/index.ts` exposes `generateObject<T>(input, options)` and is unit-tested for provider resolution + payload/metadata pass-through. - `aiChatRouter.outputJSON` and `FollowUpActionService.extract` migrated to the service (other callers move organically when next touched). - Drops the unused `keyVaultsPayload` field from `StructureOutputParams` and the placeholder at the InputEditor call site — key vaults are server-resolved from DB, the client never supplies them. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(tracing): centralize TRACING_SCENARIOS const + inject AiGenerationService via trpc ctx - New `packages/const/src/llmGenerationTracing.ts` exports `TRACING_SCENARIOS` + `TracingScenario` type — the single directory where every known scenario name lives. Adds `@lobechat/const` as a workspace dep on llm-generation- tracing so `TRACING_SCENARIO_REGISTRY` can reference the same literals. - Callers (FollowUpActionService, InputEditor) replace `'follow_up'` / `'input_completion'` string literals with `TRACING_SCENARIOS.FollowUp` / `.InputCompletion`, so a typo or a rename fails the type-check instead of silently drifting on the row. - `AiGenerationService` is now injected into the `aiChatProcedure` ctx middleware alongside `aiChatService`; `outputJSON` consumes it via `ctx.aiGenerationService` instead of new-ing it inside the handler. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ✨ feat(llm-generation-tracing): add lt/llm-tracing CLI + drop local-only storage_key - Add `lt` / `llm-tracing` CLI under @lobechat/llm-generation-tracing with `list` (recent records, --scenario filter, --json) and `inspect` (by tracing_id prefix or latest, --full, --json). - `FileTracingStore.save` now returns `{ key: null }` so dev DB rows leave `storage_key` empty instead of recording a non-resolvable local path; S3 store remains the source of truth for the real key. Add helpers `findByTracingId` / `getLatest` used by the CLI. - Wire `agentId` and `topicId` into `input_completion` tracing metadata from the chat input auto-complete call site. - Default `FileTracingStore` whenever NODE_ENV=development (drop the ENABLE_LLM_GENERATION_TRACING_LOCAL opt-in env var). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * 💄 style(llm-generation-tracing): prettier CLI output (tree + colors) Mirror the @lobechat/agent-tracing viewer style: - Inline ANSI color helpers (dim/bold/cyan/magenta/green/yellow/red). - Compact single-line header with id, scenario, version, model, status, time — replaces the multi-line bullet list. - Tree structure with `├─`/`└─` connectors instead of `── section ──` banners. - input arrays render per-message (role + char count + preview) rather than dumping raw JSON. - Small single-key outputs (e.g. `{ completion: "怎么样" }`) collapse to inline `key: "value"`. - `lt list` switches to a colored, properly padded table. Default view stays compact; --full expands system_prompt / input / schema bodies. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(llm-generation-tracing): split `tracing` config out of `metadata` `options.metadata` was overloaded — half tracing-specific structured fields (scenario / promptVersion / schemaName / agentId / topicId / ...), half free-form jsonb passthrough. Callers couldn't tell which was which, and the inputHint was always auto-extracted (useless when the prompt wraps the user's text in a template). This commit introduces a dedicated `tracing` option: - Add `TracingOptions` to @lobechat/llm-generation-tracing — the typed shape callers import (agentId / topicId / inputHint / scenario / promptVersion / schemaName / systemPrompt / parentTracingId / metadata). - Add loose `tracing?: Record<string, unknown>` to GenerateObjectOptions and StructureOutputParams / StructureOutputSchema so the field flows through the runtime + TRPC. - Tracing hook now reads `context.options.tracing` for structured fields; it still falls back to `metadata.trigger` for the cross-cutting trigger string (ModelRuntime itself uses metadata.trigger for timing logs, so trigger stays on metadata). - Service `record()` accepts an explicit `inputHint`; otherwise falls back to auto-extraction from the first user message. Always truncated. - Free-form jsonb fields move to `tracing.metadata` (was unknown-key passthrough on `metadata`). - Call sites updated: - FollowUpAction now passes `tracing: { scenario, promptVersion, schemaName, topicId }` (previously `metadata`). - InputCompletion now passes `tracing: { agentId, topicId, inputHint: input, scenario, promptVersion, schemaName }` — `inputHint` is the user's actual typed text, not the wrapper prompt's first user message. - `aiChat.outputJSON` router forwards both metadata and tracing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update inputCompletion.ts * 🐛 fix(llm-generation-tracing): stop duplicating provider into the row's metadata jsonb `provider` is already a first-class column on the `llm_generation_tracing` row, so auto-stamping it into the `metadata` jsonb column on every call was pure noise. The hook now writes the caller-supplied `tracing.metadata` verbatim — empty/undefined when the caller had nothing to add. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
b50acaca40 | 🐛 fix: pin baseline-browser-mapping (#15130) | ||
|
|
8cd03c8013 |
⚡️ perf: warm route chunks after idle (#15109)
* ⚡️ perf: warm route chunks after idle * 🐛 fix: normalize platform route chunk ids * ⚡️ perf: refine route chunk preloading * 🔧 chore: keep desktop renderer preload unchanged * ⚡️ perf: skip renderer chunks in route warmup * ⚡️ perf: preload agent route dynamic chunks * ⚡️ perf: align route preload deployment urls * ⚡️ perf: coalesce stable vendor chunks * ⚡️ perf: group shared data runtime chunks * ⚡️ perf: group model runtime chunks * ⚡️ perf: trim initial route preloads * ⚡️ perf: limit idle route micro preloads * ⚡️ perf: strip tiny html modulepreloads * ⚡️ perf: prune redundant route chunk imports * ⚡️ perf: enable rolldown devtools * ⚡️ perf: gate vite devtools output * ⚡️ perf: optimize react-scan integration and update global types Signed-off-by: Innei <tukon479@gmail.com> * ⚡️ perf: support cloud route chunk preload --------- Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
8a6545f799 |
🐛 fix(docker): make prepare script tolerant when git is unavailable (#15129)
The `prepare` script runs `git config core.hooksPath .githooks`, which fails inside Docker build where neither `.git` nor `git` exists, causing `pnpm i` to abort. Guard with `git rev-parse --git-dir` and a `|| true` fallback so the script silently no-ops outside a git working tree while still installing the local hook path for normal development. |
||
|
|
56cbf7a3f3 |
🐛 fix: prevent scrollbar from overlapping ScrollArea content (#15060)
🐛 fix: update @lobehub/ui to version 5.14.1 and add disableContentFit to ScrollArea components Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
0911c2a94c |
♻️ refactor: load models through model bank slot (#14877)
* ♻️ refactor: load models through model bank slot * ♻️ refactor: remove static LobeHub model cards * ♻️ refactor: share OpenAI image parameters * 🐛 fix: load async LobeHub model config in server paths * 🐛 fix: repair model bank CI follow-ups * 🐛 fix: avoid repeated model bank fallback loads * 🐛 fix: resolve business model config import in browser * 🐛 fix: align Nano Banana 2 resolution default * ♻️ refactor: move model loader slot under client * ✅ test: move model bank aiModels spec out of build entries * 🐛 fix: use business model config for mixed provider parsing * ♻️ refactor: consolidate model bank provider utilities * 🐛 fix: preserve Nano Banana 2 raw resolution * 🐛 fix: avoid generated locale sync for raw resolution * 🌐 style: add Nano Banana 2 resolution locales * 🌐 style: add online LobeHub model locales * 🐛 fix: guard optional model provider loaders * 🐛 fix: prevent sitemap build from hanging * 🐛 fix: clear sitemap timeout after model load |
||
|
|
67cd059340 | 🔨 chore: replace husky with native git hooks (#14941) | ||
|
|
d35ee849dd |
chore: streamline issue triage to core business labels (1-3 per issue) (#14962)
* refactor: streamline issue triage labels --------- Co-authored-by: lobehubbot <i@lobehub.com> |
||
|
|
46818e9571 |
🚀 release: v2.2.0 (#14915)
# 🚀 LobeHub Release (20260518) **Release Date:** May 18, 2026 **Since v2.1.58:** 208 merged PRs · 209 commits · 16 contributors > v2.2.0 introduces the **Chief Agent Operator** — an agent that runs itself end-to-end. It self-iterates against its own output, assembles sub-agent teams on demand through the heterogeneous runtime, and drives a unified task system that knows when to pause for a human. Self-review, AssistantGroup, and tasks/scheduling all converge into one operator surface. --- ## ✨ Highlights ### 🎩 Chief Agent Operator - **Self-iteration exits Lab** — Agent Signal's self-review pipeline ships proposal actions straight into briefs and auto-executes the approved follow-ups, with prompts hardened against eval. The operator now critiques and re-runs its own work without a human in the loop. (#14769, #14583, #14647, #14882) - **Auto-formed agent teams** — Heterogeneous AssistantGroup gains Monitor-style signal callbacks, read-only SubAgent threads with breadcrumb headers, and a thread switcher. The operator dispatches sub-agents and you can step into any branch to see what the team is doing. (#14859, #14658, #14845, #14715) - **Task system as the operator's runway** — Claude Code surfaces task tools, AskUserQuestion freeform notes, and a dedicated `waitingForHuman` topic status; `lobe-task` exposes `setTaskSchedule`; the scheduler is hardened (maxExecutions cap, sub-10min heartbeat block, race-free SchedulerForm). Long-running operator runs no longer go silent and stop themselves when human input is needed. (#14870, #14639, #14713, #14865, #14853) ### 🚀 Cloud & runtime - **Cloud Claude Code V3** — Repo picker, GitHub token flow, and sandbox-aware context bring cloud-hosted Claude Code to feature parity with local; cloud sandbox completion now triggers the task lifecycle end-to-end. (#14568, #14822, #14681) - **Heterogeneous agent multi-replica safety** — Subagent threads, ingest refresh, and parallel-tool counts now survive replica swaps without losing parent_id or rolling back tool state. (#14897, #14631, #14806, #14838) - **Built-in tool lifecycle hooks** — `onBeforeCall` / `onAfterCall` land on the built-in tool runtime; sub-agent dispatch moves to `lobe-agent`; self-iteration aligns with the shared inspector pattern. (#14719, #14715, #14827) - **Knowledge base RAG unified** — Client and server share one `KnowledgeBaseSearchService`; KB files preserved on `NoSuchKey` instead of silently lost. (#14673, #14501) ### 💬 Workspace experience - **Home daily brief + recommendations** — The home screen opens with a linkable welcome, paired input hint, and a recommendations module sourced from the operator's hetero action library. (#14589, #14645, #14770) - **Chat mode + redesigned action bar** — The chat input gains a Chat/Agent mode toggle and a re-pitched action bar with icon-and-color action tag chips. (#14774, #14903, #14846) - **Documents tree, optimistic** — Document tree creates, deletes, and inline renames now apply optimistically; the agent-documents index hides web crawls and switches to a table layout. (#14714, #14292) - **Branded MCP inspectors** — Linear MCP tool calls render with the same branded inspector as the built-in Linear skill; CC MCP and built-in skills now share inspector code. (#14864, #14884) - **Bot identity gating** — Device tools are gated by sender identity, the activator bypass is closed, and Slack mpim plus Discord DM regressions are fixed. (#14634, #14664, #14733) --- ## 🏗️ Core Agent & Signal Pipeline ### Self-iteration & Agent Signal - Self-iteration graduates out of Lab, with service, tool, name, and concept structure unified across `agent-signal`, `prompts`, `database`, and `builtin-tool-self-iteration`. (#14699, #14769) - Self-review now proposes actions to briefs and auto-executes the approved set, with eval-verified prompt hardening. (#14583, #14657, #14647) - Self-iteration built-in tool aligns with the shared runtime + inspector patterns. (#14827) - Agent Signal prompts adapt their response language and avoid blocking agent execution. (#14890, #14775, #14882) - Receipt descriptions now carry an Agent Signal marker, and self-review hinted skill documents route correctly. (#14764, #14895) ### Heterogeneous agent runtime - Subagent threads render read-only with a breadcrumb header and thread switcher; SUBAGENT badge dropped, indentation tightened. (#14658, #14845, #14783) - Multi-replica safety: ingest refresh restores tools/model from DB to fix parent_id breaks; new-step assistants sync across replicas; subagent-tagged events no longer leak into the main gateway handler. (#14897, #14631, #14838) - Fetch-triggering events are deferred to keep parallel tool counts from rolling back. (#14806) - AskUserQuestion is wired for Claude Code, with auto-decline disabled and a freeform note input on the cloud side; `waitingForHuman` is a first-class topic status. (#14639, #14629, #14870) - AssistantGroup gains Monitor-style signal callbacks; project skills surface in the working sidebar and markdown preview. (#14859, #14896) - Cloud Claude Code V3 — repo picker, GitHub token, sandbox context; credentials alert and disabled input when not configured. (#14568, #14822) - Cloud sandbox completion now triggers the task lifecycle end-to-end. (#14681) ### Agent runtime & context engine - Built-in tool runtime gets `onBeforeCall` / `onAfterCall` lifecycle hooks. (#14719) - `CompletionLifecycle`, `HumanInterventionHandler`, and `stepPresentation` are extracted from the runtime monolith. (#14441) - Per-tool timeout is honored end-to-end for client tool dispatch. (#14817) - Compression budget accounts for `tool_calls`, reasoning content, and tool defs; `call_llm` forwards tools into the budget. (#14813, #14837) - Pre-flight context check now fails fast for OpenAI-compatible providers. (#14824) - Malformed `tool_call` names are recovered instead of finishing the step silently. (#14577) - Sub-agent dispatch moves from `lobe-gtd` to `lobe-agent`. (#14715) - Hidden built-in tools now appear in the system prompt @-mention list. (#14823) ### Agent tracing & operations - New `agent_operations` table and runtime persistence for every hetero-agent operation. (#14416, #14736) - `signOperationJwt` issues 4-hour signed operation tokens. (#14586) - S3 trace snapshots are zstd-compressed; DB `trace_s3_key` aligns with the `.json.zst` suffix; legacy `.json` fallback preserved on fetch. (#14807, #14860, #14826) --- ## 📱 Platform & Integrations ### Bot / Channels - Device tools are gated by sender identity. (#14634) - Activator bypass closed and device-access checks converged. (#14664) - Slack mpim supported; Discord DM regression fixed; Slack connect + slash commands repaired. (#14733, #14591) - Bot channels, bot watch, bot callback service, and system bot reliability fixes. (#14847, #14796, #14570, #14784, #14649) - Online Messager scaffolding. (#14755) ### Onboarding - Home daily brief with linkable welcome and paired input hint. (#14589) - Recommendations module sourced from the hetero agent action library. (#14645) - Chat onboarding passes request triggers via metadata and preserves the resume request. (#14770, #14798) - Discovery turn progress gated by phase, with a reminder on stalled discovery. (#14842, #14833) - FullNameStep back button rejoins the shared prefix; ModeSwitch hidden in production. (#14898, #14760) - Agent marketplace folds into the web onboarding tool. (#14578, #14672) - Onboarding interests stored as keys instead of free text; early-exit skips marketplace and drops CJK prompts. (#14624, #14598) ### Model providers - Gemini 3.1 Flash-Lite cards; Gemini schema sanitizer drops non-compliant `enum` / `required`; zero `cachedContentTokenCount` handled in usage conversion. (#14604, #14740, #14567) - DeepSeek-V4 model cards and pricing restored to official rates. (#14110, #14911) - ernie-5.1 and spark-x2-flash support; Grok 4.3 `reasoning_effort` support. (#14643, #14731, #14642) - SiliconCloud catalog synced with API; duplicates removed; reasoning params adjusted. (#14464) - Minimax derives `max_tokens` from context window to avoid `ExceededContextWindow`. (#14814) - aihubmix uses the full models endpoint for a complete list; stale empty-apiKey test dropped. (#14511, #14669) - Stream parse errors are enriched with provider + model context. (#14636) - Visual content parts are consumed in the server runtime; video image references move to a JSON object. (#14637, #14900) - Google function call magic `thoughtSignature` now attaches to every part, not just the last turn. (#14904) - Service model assignments settings added; model extend-param options removed. (#14712, #14607) ### Built-in tools & knowledge base - `lobe-task` exposes `setTaskSchedule`; task scheduler hardened (maxExecutions cap, sub-10min heartbeat blocked, SchedulerForm race fix, rapid automation-mode toggle stabilized). (#14713, #14865, #14853, #14801) - KnowledgeBaseSearchService shares RAG runtime across client and server. (#14673) - KB files preserved on `NoSuchKey` and orphan documents/tasks cleaned. (#14501) - Document tree gets optimistic create/delete + inline rename. (#14714) - agent-documents index hides web crawls and switches to a table layout. (#14292) - `lobe-clarify` and SKILL.md frontmatter parsing/edit validation are unified. (#14566) - AnalyzeVisualMedia inspector + Portal HTML preview refactor; HTML preview restored for AssistantGroup messages. (#14777, #14811) - Branded inspector shared between CC MCP and built-in Linear skill. (#14884, #14864) --- ## 🖥️ CLI & User Experience ### Chat & Conversation - Chat mode toggle and redesigned chat input action bar. (#14774) - Action tag chips switch to icon + colored label; ActionDropdown closes on sibling-open and focus-out; submenu uses native header/footer slots. (#14903, #14802, #14901) - Action bar padding equalized around the send button; skeleton shows in action bar while config loads. (#14846, #14656) - `useCmdEnterToSend` is respected in thread & task inputs; send button enables after pasting into thread/comment input. (#14850, #14816) - TopicChatDrawer state preserved during close animation. (#14803) - Only the last assistant block animates during markdown streaming. (#14906) - Right working panel no longer auto-collapses on chat mount; home agent config fetched so knowledge toggles reflect in UI. (#14883, #14834) ### Tasks - Task scheduler, hotkey, comment, and TodoList polish. (#14707) - Add Subtask button & card baseline aligned; activity card stop run; task agent manager polish. (#14848, #14559, #14569) - Task template skeleton CLS reduced; task page placeholder copy refreshed. (#14788, #14704) - Task agent model snapshotted into `task.config` at create time. (#14670) - User-feedback card, task card polish, and Run-now context menu in markdown. (#14727) - Inline skill auth in recommended task templates. (#14676) ### Navigation & Layout - Tab bar gains a Chrome-style divider between inactive tabs. (#14892) - SideBarDrawer & header layout polish; nav ActionIcon sizing unified; TodoList encapsulation improved. (#14762, #14692) - Desktop header icons, sidebar density, and task menus polished. (#14724) - Standardized header action icon sizes. (#14717) - Chat topic title length increased; copy session ID added to topic dropdown menu. (#14659, #14595) - Heterogeneous agent topic rows regain indentation. (#14783) ### Other polish - Usage token details shortened; tool execution time formatted as `Xmin Ys`. (#14849, #14641) - Tool arguments display gets word-wrap toggle; long tool-call params wrap instead of truncate. (#14706, #14640) - Editor stops showing per-line placeholder once content is present. (#14852) - Visible divider between queued messages; intervention confirmation bar polished. (#14593, #14587) - Credit top-up copy refreshed; auth captcha retry copy refreshed; brief recommendations layout polished. (#14821, #14561, #14871) --- ## 🔧 Tooling & Developer Experience - Dev-only feature flag override panel. (#14565) - `__DEV__` define replaces `process.env.NODE_ENV` in the SPA. (#14696) - Agent-settings drops Meta/Documents tabs and restores `inputTemplate`. (#14874) - `local-system` forwards all `grepContent` params and moves the executor to `/client`. (#14888) - `lobe-task` and `setTaskSchedule` exposed. (#14713) - Memory user-memory benchmark agent config and source-id extraction schemas. (#14779, #14778) - CLI man page drops stale cron entry; `clearMessages` hotkey removed. (#14709, #14906) - Skill docs simplified; cloud heteroContext gains sandbox TTL + public-repo fork push guide. (#14785, #14761) --- ## 🔒 Security & Reliability - **Security:** Sensitive comments and examples sanitized from the production JS bundle. (#14557) - **Security:** Inactive OIDC access rejected. (#14674) - **Security:** CASC `new Function()` template replaced with safe string builders. (#14751) - **Security:** Sign-in captcha flow removed in favor of safer flow. (#14573) - **Security:** Desktop local file previews restricted to safe roots. (#14789) - **Security:** Image binary capped at 3.75 MB so base64 payload stays under the Anthropic 5 MB limit. (#14711) - **Reliability:** Neon/Node pools get error listeners to prevent Lambda crashes. (#14606) - **Reliability:** `paradedb.match(...)` replaces hardcoded normalizer in memory search. (#14590) - **Reliability:** `PlaceholderVariablesProcessor` errors carry diagnostic context. (#14741) - **Reliability:** File storage upload checks are serialized; multiple account link bug fixed. (#14829, #14562) - **Reliability:** `ScrollShadow` replaced with `ScrollArea` to fix a React infinite render loop (error code 185). (#14689) - **Reliability:** Embedding token cap enforced — long memory queries are limited and truncated before search. (#14757) - **Reliability:** Embed binary blob guard + oversized output cap in `local-system.readFile`. (#14602) - **Reliability:** Windows npm CLI shims resolved before spawning agents. (#14772, #14720) - **Reliability:** Vite pinned to 8.0.12 to avoid the rolldown 1.0.1 preload regression; desktop runtime externals split from native deps. (#14804, #14776) - **Reliability:** Old lobehub cron job removed; WeChat URL rules dropped from web crawler. (#14630, #14633) --- ## 👥 Contributors Huge thanks to **16 contributors** who shipped **208 merged PRs** this cycle. @hezhijie0327 · @sxjeru · @hardy-one · @Bianzinan · @brone1323 · @YuSaZh · @Wxh16144 · @arvinxx · @Innei · @tjx666 · @Neko · @LiJian · @Rdmclin2 · @sudongyuer · @AmAzing129 · @rivertwilight Plus @lobehubbot for maintenance translations. --- **Full Changelog**: https://github.com/lobehub/lobe-chat/compare/v2.1.58...v2.2.0 |
||
|
|
eb39f193c9 |
♻️ refactor(chat-input): adopt native submenu header/footer slots for skill menu (#14901)
* ♻️ refactor(chat-input): adopt native submenu header/footer slots for skill menu The skill menu in the Plus dropdown pinned its search bar and stats footer as faux menu items held by position:sticky CSS hacks (data-fixed-menu-footer / data-skill-menu-search / data-skill-stats). @lobehub/ui 5.14.0 adds native header/footer slots to submenu popups, so move the search bar and stats row onto those slots and drop the hacks. * ♻️ refactor(knowledge-controls): integrate footer into useControls and update PlusAction to utilize new structure Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
df8111aca0 |
🐛 fix(build): pin vite to 8.0.12 to avoid rolldown 1.0.1 preload regression (#14804)
Vite 8.0.13 bumps rolldown to 1.0.1, which ships a new chunk-optimization dedupe pass (rolldown #9305) with an unsound sibling-dynamic-entry handling — see rolldown #9350 (open). This causes preload-deps entries (m.f in __vite__mapDeps) to be dropped, leaving null slots; at runtime any dynamic import that hits the shrunken table fires import(null) and throws "Failed to resolve module specifier 'null'", taking down every tRPC call that flows through src/libs/trpc/client/lambda.ts headers (await import('@/services/_auth')). Because the repo runs with lockfile=false + resolution-mode=highest, ^8.0.9 silently floats to 8.0.13 on every fresh Vercel build. Pin exactly to 8.0.12 (which uses rolldown 1.0.0) until rolldown 1.0.2 / Vite 8.0.14 lands a fix. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
b5871d327a | 🐛 fix: preserve resume request trigger (#14798) | ||
|
|
1914ae6d43 |
🐛 fix(desktop): restrict local file previews (#14789)
* 🐛 fix(desktop): restrict local file previews * 🐛 fix(desktop): close TOCTOU in localfile protocol handler * 🐛 fix(desktop): guard approveWorkspaceRoots against undefined input App.test.ts StoreManager mock returned undefined for unknown keys, causing TypeError when approveWorkspaceRoots tried to call .map(). Added default parameter and updated mock to return defaultValue. * ✅ test: stabilize ci dependency resolution |
||
|
|
9075d5dfd3 |
refactor: merge agent marketplace into web onboarding
* ✨ feat(desktop): open-in-app + agent files tab + localfile protocol Bundle three related desktop features: - Open-in-app: IPC contract, main-process detector/launcher/icon-extractor, renderer service, OpenInAppButton + hook, agent header / portal / files-tab integration, user preference (defaultOpenInApp). - Agent files tab: working sidebar files tab with file tracking, store wiring, i18n, reveal-in-tree action in Review/FileItem. - LocalFile protocol: serve binary images via localfile:// for inline preview in the review panel. * 🐛 fix: add explicit type annotation for ref parameter in Files test Fix TS7031: Binding element 'ref' implicitly has an 'any' type. This error was caught by tsgo type-check in CI. * 🐛 fix: address codex review feedback (P1 reveal retry + P2 WebStorm Windows detection) * 🐛 fix(open-in-app): avoid process.platform reference in renderer The Electron renderer sandbox does not expose `process`, so reading `process.platform` in the useOpenInApp hook crashes with a ReferenceError on app launch. Use the `window.lobeEnv.platform` value already exposed via preload contextBridge instead. * 🐛 fix(conversation): keep assistant runtime errors outside workflow collapse When an assistant block carries a runtime error, render the error in the answer segment instead of letting it fold into the workflow collapse with the surrounding tool calls. * ✨ feat(portal): add file viewer tab strip and local file protocol improvements - Add tabbed interface for local file portal viewer - Extend LocalFileProtocolManager with audio MIME type support - Add portal actions for file navigation and tab management - Improve OpenInAppButton and conversation header integration - Update working sidebar resources section - Add comprehensive portal action tests * ✨ feat(agent-sidebar): redesign Review panel and refine Files explorer - Review: drop antd Collapse, replace with a linear disclosure list (hairline dividers, no rounded cards, chevron-left, role=button rows). Add motion height/opacity expand animation. Compact row spacing. Move hover-revealed copy/reveal/revert into an absolute Flexbox with a gradient mask so they overlay the right edge without taking layout. - Files: extract useGitWorkingTreeFiles hook + tests; surface git status entries in the working tree explorer. - ExplorerTree: share folder icon style; minor type tweak. - Locales: new chat strings for the above. * 🐛 fix(test): add missing chatConfigByIdSelectors mock to WorkingSidebar test |
||
|
|
b125565597 | 🔖 chore(release): release version v2.1.58 [skip ci] | ||
|
|
dcc9f78091 |
♻️ refactor(builtin-tool): move sub-agent dispatch from lobe-gtd to lobe-agent (#14715)
* ♻️ refactor(builtin-tool): move sub-agent dispatch from lobe-gtd to lobe-agent
Move the `execTask` / `execTasks` capability out of `packages/builtin-tool-gtd/`
and into `packages/builtin-tool-lobe-agent/`, renaming the public APIs to
`callSubAgent` / `callSubAgents`. The "subtask" naming inside GTD overlapped
with the new lobe-task tool's task model and conflated planning with
sub-agent dispatch.
- API names: `execTask` → `callSubAgent`, `execTasks` → `callSubAgents`
- TS types: `ExecTaskParams` → `CallSubAgentParams`, etc.; introduce
`SubAgentTask` to replace `ExecTaskItem`
- Client UI (Inspector / Render / Streaming) ported under
`packages/builtin-tool-lobe-agent/src/client/`
- Central registries (`packages/builtin-tools/src/{inspectors,renders,streamings}.ts`)
updated to register lobe-agent
- GTD `meta.description` and system role no longer mention async tasks;
they point to lobe-agent for sub-agent dispatch
- `isSubTask` filtering in `agentConfigResolver` now excludes `lobe-agent`
(new owner of sub-agent dispatch) instead of `lobe-gtd`
- i18n: new `builtins.lobe-agent.apiName.callSubAgent*` and
`workflow.toolDisplayName.callSubAgent*` keys in default/zh-CN/en-US
Kept the executor's emitted `state.type` values (`execTask` / `execTasks` /
`execClientTask` / `execClientTasks`) unchanged so the agent-runtime
instruction layer (`exec_task` / `exec_tasks` / `exec_client_task*`) and all
downstream tests / heterogeneous executors (`builtin-tool-agent-management`,
server `agentManagement` runtime) continue to work without modification.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ♻️ refactor(chat): rename isSubTask flag to isSubAgent
After moving sub-agent dispatch from lobe-gtd to lobe-agent, the flag name
no longer matches what it controls. Rename `isSubTask` → `isSubAgent` across
the chat / agent runtime layer and update related comments and test labels.
- `agentConfigResolver` context field + filter helper
- `streamingExecutor.internal_createAgentState` + `executeClientAgent`
signatures and call sites
- `createAgentExecutors` (exec_task / exec_client_task handlers) and
`GroupOrchestrationExecutors` (batch_exec_async_tasks)
- `chatService.createAssistantMessageStream` `resolvedAgentConfig` docs
- Test descriptions and assertions in `agentConfigResolver.test.ts` and
`streamingExecutor.test.ts`
No behavior change — the flag's filter target (`lobe-agent` identifier) is
unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ♻️ refactor(agent-runtime): rename exec_task wire identifiers to exec_sub_agent
Bring the agent-runtime "wire" naming in line with the lobe-agent
callSubAgent / callSubAgents API rename. Three layers are renamed in lockstep
to keep the bridge between tool executors and the runtime consistent:
1. Tool-emitted state.type discriminators
- 'execTask' → 'execSubAgent'
- 'execTasks' → 'execSubAgents'
- 'execClientTask' → 'execClientSubAgent'
- 'execClientTasks' → 'execClientSubAgents'
2. AgentInstruction.type and matching TS interfaces
- 'exec_task' / 'exec_tasks' / 'exec_client_task' / 'exec_client_tasks'
→ 'exec_sub_agent' / 'exec_sub_agents' / 'exec_client_sub_agent' /
'exec_client_sub_agents'
- AgentInstructionExecTask → AgentInstructionExecSubAgent (and the three
siblings)
- ExecTaskItem → SubAgentTask
3. AgentRuntimeContext.phase + matching payload types
- 'task_result' → 'sub_agent_result'
- 'tasks_batch_result' → 'sub_agents_batch_result'
- TaskResultPayload → SubAgentResultPayload
- TasksBatchResultPayload → SubAgentsBatchResultPayload
Also renames the operation-type discriminator 'execClientTask' /
'execClientTasks' to 'execClientSubAgent' / 'execClientSubAgents' and updates
its locale string in default / zh-CN / en-US.
Tests / fixtures / mocks updated in lockstep:
- packages/agent-runtime/src/agents/{GeneralChatAgent.ts,__tests__/...}
- packages/builtin-tool-{lobe-agent,agent-management}/src/...
- src/server/services/toolExecution/serverRuntimes/agentManagement.ts
- packages/agent-mock/src/cases/builtins/todo-write-stress.ts (helper renamed
to callSubAgent)
- src/store/chat/agents/createAgentExecutors.ts + exec-task / exec-tasks tests
+ fixtures/mockInstructions.ts (createExecSubAgent[s]Instruction)
- src/store/chat/slices/aiChat/actions/streamingExecutor.ts (phase check)
- packages/conversation-flow/src/__tests__/fixtures/**/*.json (8 fixtures
retargeted from lobe-gtd/execTask[s] to lobe-agent/callSubAgent[s] with the
new state.type wire values)
No behavior change — the agent runtime, executors and tests all go through
the same code paths; only the strings on the wire change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ♻️ refactor(builtin-tool): absorb GTD tool (plan + todo) into lobe-agent
Delete `packages/builtin-tool-gtd/` and fold its full surface — plan, todo,
ExecutionRuntime, all client UI (Inspector / Render / Streaming /
Intervention / SortableTodoList) and the system role — into
`packages/builtin-tool-lobe-agent/`. Single `lobe-agent` identifier now
owns: plan + todo management, sub-agent dispatch, and visual media analysis.
Also restructures the lobe-agent package so the executor lives under
`./client/` alongside the UI it ships with, and drops the dedicated
`./executor` export — consumers go through `./client` for everything
client-side.
Package-level changes:
- DELETE `packages/builtin-tool-gtd/` entirely.
- `packages/builtin-tool-lobe-agent/`
- Move `src/executor/` → `src/client/executor/`. Drop `./executor` from
`package.json` exports; expose `lobeAgentExecutor` via `./client` only.
- Rename `GTDExecutionRuntime` → `PlanExecutionRuntime` and place under
`src/client/executor/PlanRuntime/`. Re-export from package root so the
server runtime can consume it without pulling in client UI deps.
- Extend `LobeAgentExecutor` with `createPlan` / `updatePlan` /
`createTodos` / `updateTodos` / `clearTodos`, all delegated to the
shared runtime.
- Add Plan + Todo API entries to the manifest (with their original
descriptions, humanIntervention, renderDisplayControl).
- Move all GTD client UI verbatim:
`Inspector/{ClearTodos,CreatePlan,CreateTodos,UpdatePlan,UpdateTodos}`,
`Render/{CreatePlan,TodoList}`, `Streaming/CreatePlan`,
`Intervention/{AddTodo,ClearTodos,CreatePlan}`,
`components/SortableTodoList`. Register them in
`LobeAgentInspectors / Renders / Streamings`, add new
`LobeAgentInterventions`.
- Merge GTD system role into lobe-agent's (`<plan_and_todos>` plus the
existing `<sub_agents>` and `<run_in_client>` sections).
- `package.json`: pick up `@lobechat/prompts` dep and `@lobehub/editor` +
`antd` + `lucide-react` peer-deps inherited from GTD.
Central registries (`packages/builtin-tools/src/*`) and consumers:
- Remove every `GTDManifest / Inspectors / Renders / Streamings /
Interventions` import + registration; existing `LobeAgent*` registrations
now cover them.
- Replace `[GTDManifest.identifier]: GTDInterventions` with
`[LobeAgentManifest.identifier]: LobeAgentInterventions`.
- Drop `@lobechat/builtin-tool-gtd` workspace dep from
`packages/builtin-tools/package.json`, `packages/builtin-agents/package.json`
and root `package.json`.
- Remove `gtdExecutor` from `src/store/tool/slices/builtin/executors/index.ts`;
switch `lobeAgentExecutor` import to `/client`.
- Replace `serverRuntimes/gtd.ts` with a service factory
`serverRuntimes/lobeAgentPlan.ts` (`createServerPlanRuntimeService`).
`serverRuntimes/lobeAgent.ts` instantiates `PlanExecutionRuntime` with
that service so the registry exposes one runtime per `lobe-agent`
identifier covering both visual analysis and plan/todo.
- `services/chat/mecha/contextEngineering.ts`: gate plan/todo injection on
`LobeAgentIdentifier` instead of `GTDIdentifier`.
- `agentConfigResolver.test.ts`: switch fixture plugin IDs to
`LobeAgentIdentifier`.
- `packages/const/src/recommendedSkill.ts`: drop the standalone `lobe-gtd`
recommendation — `lobe-agent` already covers it via `defaultToolIds`.
i18n migration (default + zh-CN + en-US; other locales regenerate on
`pnpm i18n`):
- `builtins.lobe-gtd.*` → `builtins.lobe-agent.*` in `plugin.ts/json`.
- `lobe-gtd.*` (tool namespace) → `lobe-agent.*` in `tool.ts/json`.
- Remove `tools.builtins.lobe-gtd.{description,readme,title}` from
`setting.ts/json` (lobe-agent has its own meta now).
- Update all client component `t(...)` keys to the new namespace.
Mocks / fixtures / tests:
- `packages/agent-mock/src/cases/builtins/todo-write-stress.ts`: all
`identifier: 'lobe-gtd'` → `'lobe-agent'`; helper comments updated.
- `packages/types/src/stepContext.ts`: comment refers to
`builtin-tool-lobe-agent` (the only consumer of `StepContextTodoItem`).
- `packages/model-runtime/src/core/streams/google/google-ai.test.ts`:
function-call names from `lobe-gtd____createPlan` etc. → `lobe-agent____*`.
- `src/store/chat/slices/message/selectors/dbMessage.test.ts`: same.
- `src/features/DevPanel/RenderGallery/fixtures/lobe-gtd.ts` deleted; its
plan/todo fixtures are folded into `fixtures/lobe-agent.ts` alongside the
existing `callSubAgent[s]` ones.
- Replace `console.log` → `console.info` in moved client components to
satisfy lobe-agent's stricter ESLint rules (GTD package allowed
`console.log`; lobe-agent inherits the repo-wide `no-console` rule).
No behavior change for end users: `lobe-agent` now owns all the APIs,
identifiers, and UI that previously lived in `lobe-gtd`, but as a single
consolidated package under a single tool identifier.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ♻️ refactor(context-engine): drop residual GTD naming, rename to PlanInjector / TodoInjector
Follow-up to
|
||
|
|
d3f8f760b2 | ⬆️ chore: bump @lobehub/ui to 5.10.5 | ||
|
|
457d112a74 |
🐛 fix: remove the old cron job from lobehub (#14630)
* fix: remove the old cron job from lobehub * fix: add some ts back |
||
|
|
0516184b45 | 🔖 chore(release): release version v2.1.57 [skip ci] | ||
|
|
4ebd8f7f7c |
♻️ refactor(onboarding): extract language and privacy as shared prefix steps (#14538)
* ♻️ refactor(onboarding): extract language and privacy as shared prefix steps Move the language-selection and privacy/telemetry consent out of the classic flow into a shared prefix that runs at /onboarding before branching into either the agent or classic experience. Welcome decoration is merged with language selection on a single screen, dropping the total step count by one. Shared-prefix completion is derived from raw stored settings (s.settings.general.responseLanguage and telemetry), so no new schema fields are introduced and existing consumers that rely on the merged-default telemetry value are unaffected. Branch routing remains automatic (feature flag + isDesktop check) and is now encapsulated in deriveOnboardingBranchPath. Both branch routes guard against entering before the shared prefix is complete. MAX_ONBOARDING_STEPS drops from 5 to 3 (FullName, Interests, ProSettings). * ♻️ refactor(onboarding): use original Telemetry + ResponseLanguage as shared steps Revert the merged welcome+language design. The shared prefix now reuses the original two classic steps as-is: - Step 1: TelemetryStep (welcome decoration + privacy/telemetry consent) - Step 2: ResponseLanguageStep (language selection) Also suppress the mode-switch + skip footer on the bare /onboarding path so it only appears once the user has entered the agent or classic branch. * 🐛 fix(onboarding): persist shared-prefix step in URL to survive locale-triggered remounts Use react-router's useSearchParams to keep the active shared step in the URL (?step=2). Local useState was lost when switching language for the first time because i18next's first-time resource load triggers a remount up the tree; the URL param survives any remount. * 🐛 fix(onboarding): unblock branch redirect when user accepts default telemetry Derive commonStepsCompleted from responseLanguage alone. setSettings strips fields whose value matches DEFAULT_COMMON_SETTINGS, so accepting the default telemetry: true left s.settings.general.telemetry undefined and the derive selector never flipped to true — the redirect to the branch never fired. Step 2 (language) implies step 1 was completed because the flow is sequential, so checking responseLanguage alone is sufficient and robust against the default-strip behavior. * 🐛 fix(onboarding): redirect after step 2 by deriving completion from responseLanguage only setSettings strips fields that match defaultSettings, so writing telemetry=true (the default) never persists to s.settings.general. That made commonStepsCompleted permanently false even after the user finished both steps, blocking the redirect to the branch flow. Drop telemetry from the derive check. Step 1 completion is already tracked via the URL ?step=2 marker; step 2 completion is the only event that needs to flip commonStepsCompleted, signalled by writing responseLanguage (which always differs from the default since DEFAULT_COMMON_SETTINGS has no responseLanguage entry). * 🔨 chore(scripts): add reset-onboarding script for redoing the flow Takes an email, clears users.onboarding, agent_onboarding, full_name, interests and removes responseLanguage + telemetry from user_settings.general so the user re-enters the shared-prefix onboarding from step 1. Usage: pnpm workflow:reset-onboarding <email> bunx tsx scripts/resetOnboarding/index.ts <email> * 🐛 fix(signup): add refs for email and password inputs to improve focus handling Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(onboarding): skip responseLanguage auto-fill while onboarding is in progress useInitUserState's onSuccess callback auto-fills general.responseLanguage from navigator.language whenever the field is missing. For new users this fired immediately after signup, which made commonStepsCompleted (which derives from responseLanguage being set) flip to true on first load, and CommonOnboardingPage's early-redirect skipped past the shared prefix straight into /onboarding/agent. Gate the auto-fill on onboarding.finishedAt or agentOnboarding.finishedAt being set, so legacy users who finished onboarding without responseLanguage still get the safety-net detection, but in-progress users keep the field undefined until they explicitly choose it on the language step. * 🐛 fix(onboarding): refresh welcome message locale until conversation starts ensureWelcomeMessage previously only created the welcome on first call and skipped on subsequent ones, leaving stale welcomes locked to the locale that was active when the topic was first created. After the shared-prefix refactor users pick their language earlier than they used to, so the welcome that was generated during the auto-detect phase never gets re-translated. Now the welcome content is rewritten in-place to match the current responseLanguage as long as no user reply has been recorded yet (message count <= 1). Once the conversation has started, the welcome is left as part of the chat history. * 🐛 fix(onboarding): update welcome message handling to render client-side and avoid persisting during onboarding Signed-off-by: Innei <tukon479@gmail.com> * Refactor onboarding user profile handling: remove responseLanguage field - Removed responseLanguage from SaveUserQuestionInput and related schemas. - Updated onboarding logic to no longer save or request responseLanguage. - Adjusted related components and services to reflect the removal of responseLanguage. - Enhanced user info handling to include displayName and fullName from OAuth. - Updated tests to align with the new onboarding structure. Signed-off-by: Innei <tukon479@gmail.com> * refactor(onboarding): update locale handling to use i18n's resolved language Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(onboarding): remap legacy 5-step classic currentStep on shared-prefix mount Mid-flow legacy users with persisted currentStep authored under the old 5-step classic flow (Telemetry, FullName, Interests, Language, ProSettings) would silently skip required profile steps after the renumbering: old step 2 (FullName) rendered Interests, old step 3 (Interests) rendered ProSettings. Apply a one-time remap (2->1, 3->2, >=4->MAX) when Common mounts, gated by isUserStateInit and onboarding.finishedAt absence so it fires only for in-flight legacy users. Idempotent for new-schema values. * refactor(onboarding): implement AGENT_ONBOARDING_ENABLED master switch for onboarding flow Signed-off-by: Innei <tukon479@gmail.com> * refactor(onboarding): standardize AGENT_ONBOARDING_ENABLED naming in tests Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
03621d0664 |
✨ feat(explorer-tree): add generic ExplorerTree component built on @pierre/trees (#14094)
* ✨ feat(explorer-tree): introduce generic ExplorerTree component Scaffold a reusable tree component at `src/features/ExplorerTree/` built on top of `@pierre/trees`. The component exposes a typed `ExplorerTreeNode<TData>[]` input (tree or flat+parentId), path-driven identity hidden behind an adapter, and a minimal imperative handle (startRenaming, focus, select, setExpanded, getSelectedIds). Wired v1 capabilities: - multi-select (default* + onChange), uncontrolled + ref - DnD abstracted as `onMove(MoveEvent)` with canDrag/canDrop gates - declarative right-click menu via `getContextMenuItems` rendered through the library's `renderContextMenu` slot - inline rename via `canRename`/`onCommitRename`/`onRenameError` - trailing row decorations via `getRowDecoration` - built-in icon set driven by file extensions Old `src/features/FileTree/` is tagged `@deprecated` so consumers can migrate gradually (SkillStore, LibraryHierarchy, WorkingSidebar). No consumers migrated in this PR — that is tracked as a follow-up. Design spec: docs/superpowers/specs/2026-04-23-explorer-tree-design.md * 📝 docs: add ResourceManager ExplorerTree refactor design * ♻️ refactor(explorer-tree): use id-based tree contracts * ♻️ refactor(explorer-tree): narrow transitional tree types * ♻️ refactor(explorer-tree): align transitional prop contracts * ♻️ refactor(explorer-tree): remove future-only transitional types * ♻️ refactor(explorer-tree): support controlled id state * 🐛 fix(explorer-tree): suppress controlled sync feedback * 🐛 fix(explorer-tree): reconcile controlled ids on stable paths * ✨ feat(resource): add tree snapshot derivation * ✨ feat(resource): add tree mutation helpers * 🐛 fix(resource): harden tree mutation rollback boundaries * ✨ feat(resource): add tree controller * 🐛 fix(resource): guard tree controller request ordering * ✨ feat(resource): add tree route and bridge modules * 🐛 fix(resource): harden tree route bridge boundaries * ♻️ refactor(explorer-tree): expose row host events * ♻️ refactor(resource): wire hierarchy to ExplorerTree * ♻️ refactor(resource): remove global tree store * 🐛 fix(resource): revalidate tree mutations by source parent * 🐛 fix(spa): prebundle explorer tree dependency * ♻️ refactor(sharedRendererConfig): remove unused dependencies '@pierre/trees' and '@pierre/trees/react' Signed-off-by: Innei <tukon479@gmail.com> * ♻️ revert(resource): remove business integration, keep ExplorerTree component only Revert all ResourceManager business integration while preserving the generic ExplorerTree component implementation: - Restore ResourceManager component files to canary state - Restore src/store/tree/ (deleted by integration commit) - Remove src/features/ResourceManager/tree/ (controller, mutations, bridge) - Keep src/features/ExplorerTree/ (generic component) - Keep @pierre/trees dependency in package.json * ✨ feat(agent): integrate ExplorerTree into agent documents section - Replace flat document list with ExplorerTree for 'documents' filter tab - Convert flat AgentDocument[] to tree nodes via parentId/fileType - Add tree node click handler (navigate/open) and context menu (delete) - Fix height chain: ResourcesSection flex:1 -> AgentDocumentsGroup -> ExplorerTree - Style ExplorerTree via --trees-*-override CSS vars (transparent bg, relaxed density, theme tokens) * ♻️ refactor(resource-manager): remove outdated ExplorerTree design document Signed-off-by: Innei <tukon479@gmail.com> * ✨ feat(agent-documents): wire context menu and DnD via base-ui imperative API - Replace nested antd Menu surface with @lobehub/ui showContextMenu, capturing right-click on the tree host directly so menu actions (rename, create, delete) survive base-ui focus restoration - Fix DnD root drop by routing canDrop through directoryPath instead of hoveredPath, so dragging a nested file onto empty root no longer treats the hovered file row as the target zone * ♻️ refactor(DocumentExplorerToolbar): adjust padding styles for better layout Signed-off-by: Innei <tukon479@gmail.com> * ✨ feat(useDocumentTreeOps): integrate confirmModal for delete confirmation Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(ExplorerTree): cast through unknown to satisfy antd MenuItem types * ✨ feat(AgentDocumentsGroup.test): add mock for DocumentExplorerTree and update tests for document count Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
9b5cea7391 |
♻️ refactor: merge agent-marketplace into web-onboarding package (#14514)
* ♻️ refactor: merge agent-marketplace into web-onboarding package Move the standalone `builtin-tool-agent-marketplace` package into `builtin-tool-web-onboarding/src/agentMarketplace/` as a sub-module to reduce package sprawl and consolidate related onboarding tooling. Also adds locale-aware fetching for onboarding agent templates: - Accept optional `locale` param in `getOnboardingFull` TRPC endpoint - Pass normalized i18next locale from the client fetcher - Add unit test for locale resolution * ♻️ refactor: integrate FollowUpChips into ChatItem and update GroupMessage components Signed-off-by: Innei <tukon479@gmail.com> * fix: address Codex review feedback for PR #14514 - Make getOnboardingFull input schema optional with default to preserve backward compatibility for callers that invoke .query() without arguments - Parameterize SWR cache key by resolved locale to prevent cross-locale cache pollution in the PickAgents marketplace component * chore: remove accidentally pushed .kagura directory and add to .gitignore --------- Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
5e1a35f259 |
🐛 fix(conversation): reduce streaming re-renders with reference stabilization and self-subscribing components (#14470)
* 🐛 fix(conversation): reduce streaming re-renders with reference stabilization and self-subscribing components - Add stabilizeReferences utility to pin unchanged subtrees to previous identity after parse() - Make Tool, Tools, and MessageContent self-subscribe via store selectors instead of receiving data as props - Stabilize handleExpandedChange and expandedKeys in WorkflowCollapse with useCallback/useMemo - Add selectors: findBlockById, getToolsInBlock, getToolInBlock, getBlockContent, getBlockHasTools * 🔧 chore(agent-mock): update todo-write-stress test case * feat: refactor todo-write-stress case to utilize lobe-gtd API for task management and enhance workflow with structured plans and todos - Updated tool steps to replace previous bash commands and file operations with lobe-gtd API calls for creating and updating todos and plans. - Introduced structured plans for various phases of the migration process, enhancing clarity and organization. - Implemented a breathing step to simulate processing between tool-call batches. - Enhanced the overall flow of the todo-write-stress case to reflect a more realistic and organized task management approach. refactor: optimize ContentBlocksScroll component with virtualized list for improved performance - Added CSS styles to enable content visibility auto for off-screen workflow items, preserving React state while optimizing rendering. - Updated Flexbox component to conditionally apply virtualized list styles based on the variant prop, enhancing layout performance. Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(conversation): remove virtualized list styles to improve rendering performance Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(conversation): address codex streaming review feedback * ♻️ refactor(conversation): use query structural sharing helper --------- Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
f30d9da5a9 |
✨ feat(agent-mock): add agent mock devtools with playback & fixture viewer (#14436)
* 📦 feat(agent-mock): scaffold package skeleton * 🔧 chore(agent-mock): align deps + add vitest config * ✨ feat(agent-mock): add core types * ✨ feat(agent-mock): add chunkSplitter with code-point safety * ✨ feat(agent-mock): map ExecutionSnapshot → MockEvent[] * ✨ feat(agent-mock): add defineCase / llmStep / toolStep / errorStep DSL * ✨ feat(agent-mock): add snapshotToMockCase helper * ✨ feat(agent-mock): add todo-write-stress builtin case + registry * ✨ feat(agent-mock): add generator registry + tool-stress generator * ✨ feat(agent-mock): add 4 more builtin cases (long-reasoning, mixed, error, subagent) * ✨ feat(agent-mock): add subagent-tree + long-reasoning generators * ✨ feat(agent-mock): add MockPlayer state machine + step navigation * ✨ feat(agent-mock): add __agentMockSilent flag + signal bridge guard * ✨ feat(agent-mock): add executeMockStream with side-effect gating * ✨ feat(agent-mock): add dev-only devClearMockTopics TRPC procedure * ✨ feat(agent-mock): add dev API to list/read .agent-tracing snapshots * ✨ feat(agent-mock): add agentMockStore zustand * ✨ feat(agent-mock): add useMockCases hook * ✨ feat(agent-mock): add useAgentMockPlayer hook * ✨ feat(agent-mock): add useMockTopicCleanup hook * ✨ feat(agent-mock): add Fab entry component * ✨ feat(agent-mock): add Modal shell with tab bar * ✨ feat(agent-mock): add CaseList sidebar with search + groups * ✨ feat(agent-mock): add MiniBar floating playback controls * ✨ feat(agent-mock): add StatusGrid component * ✨ feat(agent-mock): add Controls (play/pause/step/speed) * ✨ feat(agent-mock): add ProgressBar * ✨ feat(agent-mock): add TargetPicker * ✨ feat(agent-mock): compose PlayerPanel * ✨ feat(agent-mock): add TimelinePanel + virtualized EventRow * ✨ feat(agent-mock): add read-only FixtureViewer with copy button * ✨ feat(agent-mock): add SettingsPanel with toggles + clear topics * ♻️ refactor(agent-mock): address quality review (stable itemContent, type-safe error handling, clipboard catch) * ✨ feat(agent-mock): wire entry component (FAB + Modal + MiniBar) * ✨ feat(agent-mock): mount AgentMockDevtools in SPAGlobalProvider * ♻️ refactor(agent-mock): switch Modal to imperative createModal API * 🐛 fix(agent-mock): use close() + onOpenChangeComplete to preserve motion exit animation * work Signed-off-by: Innei <tukon479@gmail.com> * minify Signed-off-by: Innei <tukon479@gmail.com> * 💄 refactor(agent-mock): rebuild devtools UI/UX with mono palette and IA reorg Replace the in-modal sidebar + tab strip + MiniBar with a Fab-anchored draggable Popover (case picker, transport, replay/loop, scrubbable progress, stop, Open DevTools) and a token-driven Modal layout (two-row header, Segmented view tabs, StatsStrip, sticky TransportBar). Wire EventRow and the progress bars to seekToEventIndex (resolves the prior TODO), swap alert() for toast.warning, persist loop and popover position to localStorage. * work Signed-off-by: Innei <tukon479@gmail.com> * 🧹 chore(agent-mock): remove replay debug logs * 👷 build: add @google/genai to pnpm allowBuilds Fixes ERR_PNPM_IGNORED_BUILDS in CI — pnpm v11 blocks install when a dependency with install scripts is not in the allowBuilds list. * 🐛 fix: resolve TS type errors in useAgentMockPlayer - parentMessageId: coerce `undefined` to `null` to match `string | null` - threadId: coerce `null` to `undefined` for cancelOperations param * ♻️ refactor: revert ConversationArea & sync-import AgentMockDevtools - ConversationArea: restore messageMapKey(context), avoid needless field spread - SPAGlobalProvider: switch AgentMockDevtools to sync import (dev-only, no need to lazy) --------- Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
c744eab116 | ✨ feat(agent-signal,database,app,server): agent signal activities during nightly self-reflection will now push to briefs (#14437) | ||
|
|
aa3d245cfd | ♻️ refactor(server,prompts,builtin-tool-skill-maintainer): correct context passing, skill format, chained (#14397) | ||
|
|
b5d7696dbd | ✨ feat: add visual understanding tool (#14378) | ||
|
|
c401d1b97f | Merge remote-tracking branch 'origin/main' into sync/main-to-canary-20260501-25207007930 | ||
|
|
eddb0c991b | 🔖 chore(release): release version v2.1.56 [skip ci] | ||
|
|
3cb06e07e3 |
💄 style(taskDetail): force daily briefs for scheduled tasks; switch activity timestamps to absolute date (#14367)
* ✨ feat(brief): always synthesize a brief on scheduled-task ticks Heartbeat ticks remain mid-loop nudges and are still skipped, but schedule-mode tasks now bypass both the trivial-content rule gate and the LLM emit-vote so each scheduled run produces a daily brief. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 💄 style(taskDetail): switch activity timestamps to absolute date once gap exceeds one day Adds formatActivityTime helper to @lobechat/utils/time: relative phrasing under 24h, localized date (e.g. "4月29日" / "Apr 29") afterwards, with the full datetime exposed via the native title attribute on hover. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(brief): fork chainGenerateBrief prompt so scheduled ticks always produce a brief The default prompt instructs the LLM to pair `emit=false` with an empty title, so even after we bypassed the emit-vote for scheduled tasks the downstream `!title || !summary` guard could still drop the brief and silently break the "every schedule tick must produce a brief" contract. chainGenerateBrief now takes a forceEmit flag; when true it swaps to a scheduled-tick prompt that removes the skip branch and mandates a non-empty title/summary, including the "no new activity today" path. synthesizeTopicBrief passes forceEmit=true for schedule-mode tasks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Update @google/genai version to ~1.50.1 * 💄 style(conversation): stack TodoProgress + QueueTray as a floating overlay above ChatInput Move TodoProgress out of normal flow and render it together with QueueTray inside ChatInput as a single absolute-positioned overlay anchored to the input's top edge. The overlay no longer pushes ChatList up; instead it sits as a "cover layer" above the scroll viewport. To keep chat content reachable above the overlay, expose the overlay's measured height via the conversation input store (ResizeObserver in ChatInput) and have VList consume it as `paddingBottom = max(24, height + 12)` — the +12 compensates for ChatInput's `marginTop: -12`. BackBottom also reads the same height via a new `bottomOffset` prop so the back-to-bottom button lifts above the overlay instead of being occluded. QueueTray sits on top, TodoProgress below; TodoProgress squares its top corners (`topAttached`) when QueueTray is present so the two panels fuse into a clean stack with no notches at the seams. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ✅ test(utils): make formatActivityTime title assertion timezone-independent The test hardcoded `2026-05-01 13:00:00` (UTC+8 author tz), so it failed in UTC CI as `2026-05-01 05:00:00`. Derive the expected title via the same dayjs format the implementation uses so the assertion holds regardless of the runner's timezone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ✅ test(conversation): include chatInputOverlayHeight in store mock state The store always initializes chatInputOverlayHeight to 0 via inputInitialState, so the State type rightly keeps it required. The selectors test mock simply missed the field after the slice gained it; supply 0 to match the real initial state instead of weakening the type to optional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ♻️ refactor(brief): split judge from generate, persist decision on task topic Split the brief-emission flow into two independent stages so judgment and copy-generation are no longer entangled in a single LLM call (which made the scheduled-tick fork necessary in the first place). - Rule layer (`shouldEmitTopicBrief`) goes three-state: `'yes' | 'no' | 'unknown'`. Conclusive cases (error / review-handled / review-configured / heartbeat / trivial-non-scheduled / scheduled) bypass the LLM entirely; only manual + non-trivial topics fall through to `'unknown'`. - New `chainJudgeBriefEmit` (small chain, returns `{emit, reason}`) is invoked ONLY on the `'unknown'` branch. Title/summary copy is no longer in scope for this call. - `chainGenerateBrief` drops the `forceEmit` fork and the `emit` field — it now assumes the caller has already decided to emit and just produces `{title, summary}`. Saves tokens on skip paths since we never draft copy for a brief that won't be persisted. - Every decision (rule or LLM) is persisted to `taskTopics.handoff.briefDecision` via a new `updateBriefDecision` model method using `jsonb_set + COALESCE` so existing handoff fields aren't disturbed. Gives operators a per-topic audit trail of why a brief was or wasn't produced. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ♻️ refactor(brief): emit on errors, defer heartbeat to LLM judge Two follow-up tweaks to the rule layer (`shouldEmitTopicBrief`): - `reason === 'error'` is no longer a hard skip — the user must be told the run failed. Returns `{emit: 'yes', reason: 'execution-error'}` so once the error path is folded into `synthesizeTopicBrief` (separate consolidation refactor) the verdict is correct without further changes. Currently dead code: `onTopicComplete` still builds an urgent error brief inline at the `else if (reason === 'error')` branch. - Heartbeat ticks change from a hard `'no'` to `'unknown'`. Most ticks are mid-loop noise but the occasional one warrants surfacing, and only the LLM can read the content to tell. Heartbeat is at minimum 10 min so the added judge call per tick is acceptable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
c9b44935ed |
⏪ revert: revert pnpm v11 migration (#14372)
* Revert "👷 build: disable pnpm gvs for desktop ci (#14357)" This reverts commit |
||
|
|
1d9b6099bd |
👷 build(repo): migrate to pnpm v11 and consolidate workspace config (#14316)
* 👷 build(repo): migrate to pnpm v11 and consolidate workspace config Made-with: Cursor * 👷 fix pnpm v11 install config |
||
|
|
5fc7eea754 |
🐛 fix: inject skill instruction into tool system role (#14342)
* ✨ feat: inject skill instruction into tool system role Consume the `instruction` field from market SDK's `listTools` response and pass it as `systemRole` on the tool manifest, so the LLM receives skill-level guidance documentation via `<tool.instructions>` in the system prompt. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: update market-sdk --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
719a554456 | 🔖 chore(release): release version v2.1.55 [skip ci] | ||
|
|
9e20cd6b3a | 🔖 chore(release): release version v2.1.54 [skip ci] | ||
|
|
71cfba9906 | 🔖 chore(release): release version v2.1.55 [skip ci] | ||
|
|
990942fb45 |
✨ feat(agent-marketplace): fetch onboarding templates from market API (#14286)
* ✨ feat(agent-marketplace): implement onboarding agent marketplace picker Adds a new builtin tool `@lobechat/builtin-tool-agent-marketplace` that opens a categorized agent picker UI during web onboarding. The picker fetches the live curated catalog from the marketplace API (`/api/v1/agents/onboarding-full`) via a TRPC procedure that injects the trust-token, and lets the user select template agents to install. Highlights: - Self-contained marketplace package with manifest, system role, executor, and ExecutionRuntime - React intervention component with category sidebar, skeleton loading state, and avatar/empty/error UI; all user-visible strings i18n-driven - Dependency-inverted fetcher: package exports `setAgentTemplatesFetcher`, app registers a TRPC-backed implementation in AgentOnboardingPage - New TRPC `market.agent.getOnboardingFull` proxies the upstream API with trust-token authentication; client never sees secrets - Splits the existing `saveUserQuestion` intervention into agent identity and user profile cards for clearer onboarding approval UX - Wires marketplace into `builtin-tools` registry, executor map, and onboarding metrics; web-onboarding agent system prompt updated to reference the picker Closes LOBE-7801 * ✨ feat(onboarding): enhance early exit handling and marketplace integration in onboarding flow Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(agent-marketplace): register server runtime, scope picks per-topic, and harden onboarding handoff prompts The summary phase silently skipped the marketplace handoff because the server toolExecution registry had no runtime for `lobe-agent-marketplace`, so every `showAgentMarketplace` call returned "not implemented" and the agent fell through to `finishOnboarding`. The runtime-injected phase guidance and action hints also instructed the agent to call finishOnboarding directly after the summary, contradicting the new system role. - Register `agentMarketplaceRuntime` in `src/server/services/toolExecution/serverRuntimes` so the executor can actually run. - Scope the in-memory `picks` map by `topicId` and reject a second `showAgentMarketplace` call in the same conversation with a clear "already opened, finish on next turn" message. - Tighten the success content to instruct the model to STOP the current turn after opening the picker and run closing + finishOnboarding on the FOLLOWING user turn. - Update `OnboardingActionHintInjector`, `PHASE_GUIDANCE.summary`, `toolSystemRole` and `web-onboarding/systemRole` so all four prompt layers agree: open the picker exactly once during summary, do not call finishOnboarding in the same turn, and do not call the submit/skip/cancel APIs ourselves. - Stop treating short affirmations like "好的" / "行" / "ok" as early-exit signals; they are confirmation of the summary and should let the picker handoff proceed normally. Verified end-to-end with `bun run agent-evals run onboarding/web-onboarding-v3 --case-id fe-intj-crud-v1 --model deepseek-v4-pro`: hard assertions all pass, judge moves from 7/10 (premature finishOnboarding in same turn) to 8/10 with picker opened once and finishOnboarding deferred to the next turn. * fix(ci): attempt 1 for PR #14286 Auto-generated by pr-dispatcher (task: 01KQBY8GAC1MNQCJ6T6X5DEP2F, attempt: 1). Co-Authored-By: Claude <noreply@anthropic.com> * 🐛 fix(agent-marketplace): wire picker submit + fix marketplace-already-opened detection The marketplace picker confirm flow was sending the user's selection back as a synthetic user message, and the action hint kept telling the model to open the marketplace again — leading to a death loop where the agent re-opened the picker instead of summarizing + persisting + finishing onboarding. Two issues: 1. Pick confirm forwarded the selection as a user message instead of forking the agents and resuming from the tool result. Wire `prepareCustomInteractionSubmit` into the intervention's submit branch so it runs `installMarketplaceAgents` client-side and returns a descriptive `toolResultContent`. Plumb a `createUserMessage: false` + `toolResultContent` option through `submitToolInteraction` (slice + chat store): when set, skip the synthetic user message, override the tool message content, and resume runtime from the tool message (`parentMessageType: 'tool'`) so the LLM sees the install result and continues from there. 2. `OnboardingActionHintInjector.marketplaceAlreadyOpened` read `msg.tool_calls`, but this provider runs in pipeline phase 4.5 (virtual tail guidance) BEFORE `ToolCallProcessor` (phase 5) converts DB-shape `tools` → OpenAI-shape `tool_calls`. Detection always returned false → the hint kept saying "call showAgentMarketplace" → death loop. Fix: match on `tools[].apiName` (with `tool_calls` kept as a fallback). Also rewrote the Summary-phase hints to reflect the new flow (picker resolves directly via tool result, no synthetic user reply needed). Includes intervention bar portal-target plumbing for approval actions. * ✨ feat(onboarding): wire marketplace picker analytics on agent onboarding page Mount AnalyticsBridge under AgentOnboardingPage to inject useAnalytics() into setOnboardingAnalyticsClient, so onboarding_marketplace_shown/picked events emit through PostHog instead of being silently dropped. Adds spm fields to align with onboardingFeedback's telemetry shape. * ♻️ refactor: move DEFAULT_ONBOARDING_MODEL to business-const Made-with: Cursor * ✨ test(customInteractionHandlers): add tests for persisting marketplace picks and resolutions Signed-off-by: Innei <tukon479@gmail.com> * ✨ feat(onboarding): enhance agent marketplace integration with metadata persistence Signed-off-by: Innei <tukon479@gmail.com> * ✨ feat(agent): add web onboarding agent selectors and integrate into Actions and Usage components Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
2eb7ee824f |
✨ feat: support Line (#14207)
* feat: support Line * chore: update Line docs * feat: support line platform * chore: update markdown files * fix: lint error * fix: home padding block |
||
|
|
682657ba50 | 🔖 chore(release): release version v2.1.54 [skip ci] | ||
|
|
e326400dbe | Merge remote-tracking branch 'origin/main' into canary | ||
|
|
a4235d3f68 |
⬆️ chore: upgrade desktop Electron to 41.3.0 (#14223)
* ⬆️ chore: upgrade desktop electron to 41.3.0 * 🐛 fix: patch ant design icons vitest resolution * 🐛 fix: require fixed ant design icons version |
||
|
|
376976849b | 🔖 chore(release): release version v2.1.53 [skip ci] | ||
|
|
a52104552a |
🚀 release: 20260427 (#14217)
# 🚀 LobeHub v2.1.53 (20260427) **Release Date:** April 27, 2026 **Since v2.1.52:** 194 merged PRs · 17 contributors > Introduce Heterogeneous Agent — Claude Code and Codex run as first-class desktop runtimes, paired with a new Agent Signal package, sharper desktop UX, and a wave of flagship model additions. --- ## ✨ Highlights - **Introduce Heterogeneous Agent** — Claude Code and Codex run as first-class desktop agents: subagent rendering, partial-message streaming, multi-turn resume, terminal error surfacing, rich tool inspectors, and runtime polish. (#14162, #13754, #14067, #14001, #13970, #13942) - **Screen capture & Quick Chat tray** — New desktop screen capture overlay (macOS permission-gated) with Quick Chat tray and upload pipeline improvements; chat input auto-focuses on overlay mount. (#13818, #14097, #14105) - **Desktop topic & tab UX** — Dedicated topic popup window with cross-window sync, Cmd+W/Cmd+T tab shortcuts, TabBar polish, recent working directories expanded to 20, and human approval notifications. (#13957, #13983, #13972, #14036, #14092) - **Git workflow built-in** — One-click pull/push from the branch chip, ahead/behind badge, and submodule/worktree repo detection. (#14041, #13980, #13978) - **Agent Signal package** — New `@lobechat/agent-signal` runtime for dynamic memory feedback signals, with OTel metrics and self-iteration in Lab. (#14157, #14170, #14159, #14169, #14187) - **New models** — Claude Opus 4.7 with `xhigh` effort tier, GPT-5.5, DeepSeek V4 Flash/Pro with reasoning slider, Kimi K2.6, MiMo-V2.5/Pro, gpt-image-2, Qwen3.6 Flash/Plus, and Pixverse-c1. (#13903, #14147, #14114, #14004, #14089, #14039, #13923) - **New providers** — OpenCode Zen, OpenCode Go, and Azure OpenAI Router runtime. (#13943, #14064, #13823) - **Mobile settings overhaul** — Full settings menu and responsive profile layout for mobile. (#14019) --- ## 🏗️ Heterogeneous Agent - Claude Code runtime, working-directory awareness, and sidebar polish. (#13970) - CC subagent rendering with persistent streamed text; parallel-tool orphan fix. (#14001, #13968, #14024) - Per-step usage persisted to each step assistant message. (#13964) - Per-phase workflow expand defaults; full-expand toggle with three-level expansion. (#14171, #13906) - Hetero-mode actions bar; tool inspector polish. (#13963, #14034, #14030) - Codex desktop integration with rich tool rendering and devtools preview. (#14067, #14100) - Codex terminal error surfacing and CLI output tracing. (#14166) - Tighten `isCanUseVision` default and add aggregator fallback. (#14172) - Persist `ccSessionId` in topic metadata for CC multi-turn resume. (#13902) - CC account card, topic filter, and integration polish. (#13955, #13942, #13950) - Token-level deltas streamed via `--include-partial-messages`. (#13929) --- ## 🧠 Agent Signal & Self-Iteration - New `@lobechat/agent-signal` package with dynamic feedback signals. (#14157) - AgentSignalRuntime wired through agent-tracing and observability-otel metrics. (#14170, #14159) - Self-iteration feature flag added to Lab; front-side flag check. (#14169, #14186) - Signal policy for receiving memory feedback dynamically. (#14187) --- ## 💬 Conversation - Queue follow-up sends during running CC turns. (#14179) - Persist per-topic chat scroll position; pin user message + fold long messages. (#14191, #14056) - Inline resend when editing last user message. (#14080) - Disable first-block markdown streaming to prevent flicker. (#14193, #13904) - Prevent Markdown stream replay when vlist remounts streaming items. (#14086) - Stop repinning after manual scroll; unify scroll-to-user + spacer hooks. (#14099, #14132) --- ## 📱 Platforms & Integrations ### Desktop / Electron - Screen capture overlay, Quick Chat tray, and upload pipeline improvements. (#13818) - macOS permission gate for screen capture; auto-focus chat panel input. (#14097, #14105) - Dedicated topic popup window with cross-window sync. (#13957) - TabBar polish: `+` button for new topic, dark theme blend, close icon by default. (#13972, #14203, #13973) - Recent working directories expanded from 5 to 20; submodule/worktree repo detection. (#14036, #13978) - Cmd+W / Cmd+T tab shortcuts and global shortcut consolidation. (#13983, #13880) - Linux icon configuration; human approval desktop notifications. (#14042, #14092) ### Git Workflow - One-click pull/push from branch chip; ahead/behind badge with refactored GitCtr. (#14041, #13980) ### Mobile - Full settings menu and responsive profile layout. (#14019) - Agent route added to mobile router; mobile agent topic route registered. (#14103, #14158) - Session list skeleton row layout corrected. (#14040) ### Bot / Messaging - DM strategy support; bot emoji and markdown render optimization. (#14201, #14091, #14140) - Slack webhook fix; bot platform setup guide reference. (#14052, #14121) --- ## 🤖 Models & Providers ### New models - **Claude Opus 4.7** with `xhigh` effort tier; strip temperature/top_p. (#13903, #13909) - **GPT-5.5**. (#14147) - **DeepSeek V4** Flash/Pro cards with reasoning slider; cache-hit and Pro discount pricing. (#14114, #14209, #14196, #14131) - **Kimi K2.6** model with LobeHub-hosted card. (#14004, #14006) - **MiMo-V2.5 / V2.5-Pro**. (#14089) - **gpt-image-2**, **Qwen3.6 Flash/Plus**, **Pixverse-c1**. (#14039, #13923) ### New providers - **OpenCode Zen** and **OpenCode Go** with env-var support. (#13943, #14064) - **Azure OpenAI Router** runtime support. (#13823) - Model alias mapping for image and video runtimes. (#13896) - Seedance video models migrated to Dreamina. (#14144) ### Runtime reliability - Sanitize invalid tool_call arguments to unbreak strict providers. (#14033) - Tolerate null `function.name` in streaming tool_call deltas. (#14139) - Preserve Gemini 3 `thoughtSignature` in `call_tools_batch` normalization. (#14032) - Downgrade `image_url` parts when target model lacks vision. (#14029) - Preserve Cloudflare provider error context. (#14136) - Use `safety_identifier` for OpenAI Responses API. (#14148) - Unwrap underlying PG error in `formatErrorEventData`. (#14038) --- ## 🖥️ User Experience - **Onboarding** — Preset agent naming suggestions, structured hunk ops for `updateDocument`, persona analytics snapshot, footer promotion pipeline, wrap-up button. (#13931, #13989, #13930, #13853, #13934) - **Document workflow** — Agent documents promoted as primary workspace panel; history management and compare workflow; web-crawl docs associated with agent documents. (#13924, #13725, #13893) - **cmdk** — Agent identity surfaced on topic search results; topic/message search scoped to current agent. (#14204, #13960) - **Floating chat panel** and workspace improvements. (#13887) - **Topic completion status** with dropdown action and filter. (#14005) --- ## 🔧 Tooling - Redis-backed feature flag provider for runtime config. (#14098) - Vite upgraded to 8.0.0 with Rolldown strict execution order. (#12720, #14058) - `@lobechat/model-bank` automated npm release with provenance. (#14015, #14017, #14018) - Skill activation fallback when `activateTools` cannot find identifier. (#14010) - Cron tool: timezone and existing jobs injected into system prompt; clarified `lobe-gtd` and `lobe-cron` descriptions. (#14012, #14013) --- ## 🔒 Security & Reliability - **Security:** uuid bumped to v14 (advisory). (#14083) - **Security:** validate avatar URL and scope old-avatar deletion to owner. (#13982) - **Security:** clear OIDC sessions on better-auth signout; return 401 (not 500) for expired OIDC JWT. (#13916, #14014) - **Reliability:** scope pending-approval check to current assistant turn. (#14182) - **Reliability:** sanitize heterogeneous-agent attachment cache filenames. (#13937) - **Reliability:** reduce subagent task status error noise. (#14026) --- ## 👥 Contributors Huge thanks to **17 contributors** who shipped **194 merged PRs** this week. @Hardy · @shaun0927 · @hezhijie0327 · @sxjeru · @arvinxx · @Innei · @tjx666 · @LiJian · @Neko · @Rdmclin2 · @AmAzing129 · @sudongyuer · @CanisMinor · @rivertwilight Plus @lobehubbot and renovate[bot] for maintenance. --- **Full Changelog**: https://github.com/lobehub/lobehub/compare/v2.1.52...v2.1.53 |
||
|
|
196c0a7650 | 🔨 chore: sync tsgo version (#14181) | ||
|
|
01f6858cc1 |
🔥 feat(heterogeneous-agent): remove lab flag for GA rollout (#14162)
* 🧹 chore: remove unused desktop upload IPC * 🔥 feat(heterogeneous-agent): remove lab flag for GA rollout External CLI agents (Claude Code, Codex) are now always available on desktop without the lab toggle. Drops the `enableHeterogeneousAgent` preference, selector, settings switch, locale strings, and menu-item gating. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ⬆️ chore(deps): bump @lobehub/ui to ^5.9.6 and @lobehub/editor to ^4.9.3 Unpin from exact versions so future patch/minor releases roll in automatically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |