mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
canary
3447 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4a11ed9887 |
♻️ refactor(auth): migrate auth pages to a standalone lightweight SPA (#15689)
* ✨ feat(oidc): add interaction details endpoint * ✨ feat(auth-spa): scaffold standalone auth SPA shell and build pipeline * 🐛 fix(auth-spa): address review findings in AuthShell copies * ✨ feat(auth-spa): add spa-auth html route handler * ♻️ refactor(auth-spa): migrate simple auth pages into auth SPA * 🔒 fix(auth-spa): validate locale segment in spa-auth route * ♻️ refactor(auth-spa): move verify-im route to main SPA * 🔒 fix(auth-spa): sanitize callbackUrl, fix signup form wiring, add router error element * ♻️ refactor(auth-spa): migrate oauth pages into auth SPA * 🐛 fix(auth-spa): address oauth migration review findings * ♻️ refactor(auth): route auth pages to standalone SPA and drop Next auth tree * 🔒 fix(auth): validate locale before middleware rewrite * 🔥 chore(auth-spa): drop unused messenger i18n namespace from auth shell * ⚡️ perf(build): share one react vendor bundle across web/mobile/auth SPA builds Build react core (react, react-dom, react-dom/client, react/jsx-runtime) once as a self-contained ESM bundle under /_spa/vendor-shared, then mark those specifiers external in every SPA build and map them via rolldown output.paths to the same hashed URLs, so the auth page warms the main app's react cache. react-router-dom stays per-build: apps use ~19K of it after tree shaking while a shared bundle must export all 252K. Also split auth i18n namespaces into per-locale chunks, keep locale runtime helpers out of the default locale chunk, and group packages/const into app-const so vendor-ai-runtime no longer captures it. * ♻️ refactor(spa): extract shared SPA html serving helpers Both the main SPA and auth SPA route handlers duplicated the Vite dev asset rewriting, analytics config assembly and html template rendering. Move them into src/server/spaHtml.ts; the desktop umami block becomes an opt-in flag only the main SPA enables. * 🐛 fix(auth-spa): bundle default locale resources and disable i18n suspense to fix signin mount loop * ✨ feat(auth-spa): wrap auth shell with BusinessAuthProvider slot * 👷 build(spa): support custom vite dev origin and mark SPA entries side-effectful * 🔥 chore: drop dead /welcome entry from nextjsOnlyRoutes * 🐛 fix(auth-spa): forward referral to signup and fix error boundary dark-mode contrast * ♻️ refactor(spa): lift NextThemeProvider above RouterProvider so route error boundaries are theme-aware * update |
||
|
|
35b6bc55b8 |
🐛 fix: workspace error (#15701)
feat: support workspace (page author, copyTo/transferTo, notifications, i18n & fixes) Squashed 13 commits from fix/workspace-error for clean rebase onto main's submodule base. |
||
|
|
365dd1ff64 |
⚡️ perf(build): remove sitemap generation to cut static export time (#15702)
* ⚡️ perf(build): remove sitemap generation to cut static export time
The sitemap accounted for 772 of 827 prerendered pages, each fetching
marketplace data at build time. Static generation drops from 28.2s to
0.3s and total next build from ~59s to ~32s.
* Redirect legacy sitemap URLs to the landing site
* Redirect sitemap index to landing sitemap
|
||
|
|
6c8976b641 |
Update dependency vitest to v3.2.6 [SECURITY] (#15698)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> |
||
|
|
671bc26e0d |
Update opentelemetry-js-contrib monorepo (#13582)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> |
||
|
|
309c25cb44 |
Update dependency code-inspector-plugin to v1.3.6 (#14612)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> |
||
|
|
c65cf8c2a0 |
Update dependency @opentelemetry/auto-instrumentations-node to ^0.76.0 [SECURITY] (#14686)
Update dependency @opentelemetry/auto-instrumentations-node to ^0.75.0 [SECURITY] Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> |
||
|
|
94ea3f6a34 |
🚀 release: 20260610 (#15647)
# 🚀 LobeHub Release (20260610) **Release Date:** June 10, 2026 **Since v2.2.2:** 131 merged PRs · 13 contributors > This weekly release strengthens agent collaboration across cloud, desktop, CLI, and workspace flows, with steadier runtime behavior and a broader foundation for workspace-scoped data. --- ## ✨ Highlights - **Agent execution across devices** — Unifies per-device working directories, project skill discovery, and sub-agent suspend/resume behavior across server, QStash, and device RPC flows. (#15543, #15566, #15481, #15620, #15591) - **Connector and sandbox platform** — Expands connector permissions, custom OAuth MCP connector onboarding, sandbox provider support, and user-uploaded file sync into cloud sandbox runs. (#15463, #15546, #15184, #15550) - **Desktop and CLI reliability** — Fixes desktop cold-start, auto-update, Windows build, CLI skill discovery, and `lh connect` agent dispatch paths. (#15547, #15525, #15527, #15562, #15632, #15634) - **Pages and sharing** — Refreshes topic sharing, improves Page Editor layout behavior, and routes Page Agent tool execution through the server-side editor path. (#15581, #15556, #15588, #15023, #15610) - **Model availability and provider updates** — Adds user-scoped LobeHub model availability, Claude Fable 5, Qwen thinking preservation, and MiniMax M3 updates. (#15590, #15639, #13494, #15376) --- ## 🏗️ Core Product & Architecture ### Agent Runtime & Heterogeneous Agents - Improves sub-agent lifecycle handling, including async suspend/resume, queue-mode QStash resume delivery, and blocking nested sub-agent calls. (#15481, #15620, #15575) - Stabilizes heterogeneous agent ingestion and streaming with raw stream dumps, per-turn usage, image forwarding on regenerate, and duplicate-text fixes. (#15602, #15577, #15592, #15585) - Adds execution-device and working-directory controls across device RPC, legacy defaults, and remote-spawned Claude Code sessions. (#15543, #15566, #15591, #15572) - Improves runtime diagnostics and compatibility, including Gemini multimodal output capture, abort stream semantics, and trace quality analysis. (#15535, #13677, #15508) --- ## 📱 Platforms, Integrations & UX ### Connectors, Sandbox & Tools - Ships API-level connector tool permissions, custom OAuth MCP connector onboarding, and connector-first runtime execution. (#15463, #15546) - Adds sandbox provider support, cloud sandbox file sync, and safer external URL file input handling with SSRF validation. (#15184, #15550, #12657) - Improves tool visibility and execution with pinned app-fixed tools, ANSI output rendering, gateway-tunneled MCP calls, and automatic headless tool runs. (#15509, #15516, #15469, #15492) ### Desktop, CLI & Web UX - Restores desktop startup and reload behavior, preserves IPC error causes, and keeps the tab bar new-tab action visible across routes. (#15547, #15597, #15638) - Fixes desktop update and build stability for browser quit guards, macOS update signing, and Windows Visual Studio detection. (#15525, #15527, #15562) - Shows the plan-limit upgrade UI on desktop builds. (#15628) - Adds the Agent Run delivery checker and fixes CLI device dispatch plus skill list/search output. (#15489, #15634, #15632) - Refreshes onboarding, auth source preservation, topic UI states, referral/Fable campaign copy, and chat-input control bar behavior. (#15629, #15544, #15573, #15614, #15616, #15617, #15622, #15643) --- ## 🔒 Security, Reliability & Rollout Notes - External URL file input now includes SSRF validation for safer Google file handling. (#12657) - Database workspace-scope migrations are part of this release; self-hosted operators should run the normal migration path before serving the updated app. (#15446, #15465, #15468, #15472) - The release branch was re-cut from `canary` and includes the latest `main` release-version commit so `v2.2.2` is the verified compare base. --- ## 👥 Contributors @ONLY-yours, @sxjeru, @hardy-one, @xujingli, @hezhijie0327, @Coooolfan, @arvinxx, @tjx666, @Innei, @rivertwilight, @rdmclin2, @cy948, @AmAzing129 **Full Changelog**: https://github.com/lobehub/lobehub/compare/v2.2.2...release/weekly-20260610-recut-3 |
||
|
|
e692448346 |
🔨 chore(deps): pin @lobehub/editor to stable ^4.17.1 (#15600)
Switch from the pkg.pr.new preview snapshot back to the published 4.17.1 release. |
||
|
|
71030c6e21 | ♻️ refactor(auth): remove email harmony plugin (#15589) | ||
|
|
69cefce3d9 | 🐛 fix(page-editor): align table bleed with controllers (#15588) | ||
|
|
ccb33fa48c |
✨ feat: workspace backend service slice (#15560)
Backend-only slice of the workspace feature (server routers/services, database models with workspaceId threading, openapi middleware, business/server stubs, const/types). Excludes all UI (features/routes/store/hooks). Deploys dark behind the workspace feature flag. Includes open-source stub fixes: workspaceCreds router stub, ChargeParams workspaceId, usage.ts null-coalesce, DBMessageItem.workspaceId. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
eae47f527c |
✨ feat(markdown): render GitHub / Linear / external links as rich chips (#15561)
* ✨ feat(heterogeneous-agents): default Codex exec to bypass approvals/sandbox Switch the default Codex execution mode from --full-auto to --dangerously-bypass-approvals-and-sandbox, and share the execution-mode constants from @lobechat/heterogeneous-agents/spawn so the desktop driver and spawnAgent stay in sync. An explicit execution flag in extraArgs still wins. Also fix the Codex adapter step tracking so consecutive agent_message items stay in one step, stale tool completions don't start a new step, and turn completion drains pending tools before emitting stream_end + agent_runtime_end. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ✨ feat(shared-tool-ui): unwrap shell-wrapper commands in RunCommand UI Codex execs commands wrapped as `/bin/zsh -lc '...'`; surface the inner command in the RunCommand inspector and render. Also switch Unix glob fallback from `find` to `fast-glob` to preserve globstar semantics. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ✨ feat(markdown): render GitHub / Linear / external links as rich chips Add a markdown Link plugin that rewrites anchor elements into rich inline chips: GitHub repo/PR/issue/commit/user, Linear issues, npm packages, Figma files, mailto, and any other external link (favicon + full URL). Citation, footnote, anchor and relative links keep the default renderer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ⬆️ chore(deps): bump @lobehub/editor to 4.17.0 and @lobehub/ui to 5.15.10 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
dfdf844761 |
🐛 fix(desktop): bump node-gyp to 12.x so Windows build finds Visual Studio 2026 (#15562)
GitHub redirects the `windows-2025` runner to the new `windows-2025-vs2026` image, which ships Visual Studio 2026. node-gyp 11.5.0 only recognizes VS 2019/2022, so `electron-builder install-app-deps` fails to rebuild the native `get-windows` module with "Could not find any Visual Studio installation". node-gyp 12.x adds VS 2026 detection. Override it in both the root workspace and the isolated apps/desktop install. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
dbf743cc12 |
✨ feat(verify): Agent Run delivery checker system (#15489)
* 🗃️ feat(database): add verify system tables for agent run delivery checker Implement the database layer for the Agent Run delivery checker (Verify System). Reuse / definition layer: - verify_criteria: a single reusable pass/fail standard (atomic unit), carrying its verifier config + onFail default and bound to a document for judging guidance (iteration history reuses document_history; no version columns) - verify_rubrics: a named group that aggregates criteria — the reusable unit - verify_rubric_criteria: junction, which criteria a rubric aggregates (criteria are reusable across rubrics) Mounted onto an agent via the existing agency config jsonb: - agencyConfig.verifyRubricId: a reusable rubric (criteria template) - agencyConfig.verifyCriteriaIds: ad-hoc one-off criteria A run's plan instantiates the union of both. No dedicated bindings table. Snapshot + result layer: - agent_operations.verify_plan (jsonb) + verify_plan_confirmed_at: the per-run immutable check-item snapshot lives ON the operation (1:1 — auto-repair spawns a new operation), instead of a separate plans table - agent_operations.verify_status: denormalized rollup for list-page badges - verify_check_results: per-criterion result with the Toulmin model (verdict/confidence as columns, narrative in a typed toulmin jsonb), N:1 verifier_tracing_id for batch judging, FP/FN flags for the data flywheel; relates to the plan via operation_id + stable check_item_id Ref: LOBE-10019 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ✨ feat(verify): add Agent Run delivery checker backend + frontend module Implements the verify system on top of the schema (PR #15480): - models: verifyCriterion / verifyRubric (+junction) / verifyCheckResult; agentOperation verify plan/status methods - services/verify: AI plan generation (auto-create criteria), executor with LLM Toulmin judge (per-criterion + batch), program placeholder, agent & auto-repair spawner seams, rollup chokepoint, feedback fp/fn, completion lifecycle bridge - lambda verify router (criteria/rubric CRUD, plan, results, feedback) - frontend feature module: service, SWR hooks, CheckerDock state machine, RunArtifact, verify i18n namespace - tracing scenarios: VerifyPlanGen / VerifyJudge Live UI mount (dock/artifact into chat) pending server operationId source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 🐛 fix(verify): persist delivery-checker verdicts via async tracing backfill The LLM judge produced valid verdicts but they were never persisted, leaving every run stuck at `verifying`. Two root causes: 1. FK ordering: `writeVerdict` stamped `verifier_tracing_id` synchronously, but the `llm_generation_tracing` row is written asynchronously (best-effort, after the response) — so the hard FK was violated every time and the verdict write was rolled back. Now the verdict is written with a null link, and the tracing id is backfilled by an `onPersisted` callback that fires only after the tracing row commits (still non-blocking). If tracing is disabled the link simply stays null. 2. Verdict parse: the judge JSON schema is non-strict, so the provider returns optional Toulmin fields as explicit `null`. The Zod validator used `.optional()` (accepts undefined, not null), so any null failed the whole `safeParse` and discarded the batch. Switched to `.nullish()`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(cli): add `verify` command for the delivery checker Adds `lh verify` covering the full delivery-checker chain — criteria & rubric CRUD, per-run plan (generate/state/confirm/skip), execute (LLM judge), results, and feedback — calling the `verify` lambda router. Enables end-to-end backend testing of the verify system. Also adds the missing `tool-runtime` / `prompts` / `const` workspace entries to the CLI's `pnpm-workspace.yaml` so the standalone package installs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 💄 feat(verify): add verify message role + delivery-checker card UI Make the delivery-checker renderable in chat: - Fix the `features/Verify` components so they compile: flatten the `verify` locale to the repo's flat-dotted-key convention (keySeparator: false), import `Flexbox`/`TextArea` from `@lobehub/ui` (react-layout-kit is no longer a dep), and the token cast. - Add a `verify` UI message role + a `VerifyMessage` card that renders the Run Artifact + checker dock from `metadata.verifyOperationId`, wired into the message renderer switch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): add lobe-agent `generateVerifyPlan` tool (server runtime) Lets an agent set up the delivery checker for its run: the agent calls `generateVerifyPlan` early (per the new `<delivery_checker>` system-role guidance), which instantiates the rubric / ad-hoc criteria into a frozen plan on the current `agent_operations` row. Executed server-side only — the executor is dispatched via `runtime[apiName]` with `operationId` threaded through the tool execution context; the client `BaseExecutor` gracefully no-ops it. Also registers the metadata fields (`verifyOperationId`/`verifyRound`) on the message metadata zod schema so the role='verify' card can carry its operation id. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): surface role=verify card on run completion (LOBE-10051) Connect the delivery checker to the conversation: when an Agent Run with a verify plan completes, `CompletionLifecycle` inserts a persisted `role='verify'` message (parented to the assistant, carrying `metadata.verifyOperationId`) that renders the checker card. Self-guarded — no plan → no card, failures never affect the run. `role='verify'` behaves like a `user` leaf message everywhere it flows (persistence + conversation-flow pass it through unchanged); only the context-engine treats it specially: a new `VerifyMessageProcessor` drops it from the model context (UI-only card, not a valid model role). Adds `verify` to `CreateMessageRoleType`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 💄 feat(verify): merge run-artifact + checker into one card The role=verify message rendered two stacked cards (Run Artifact summary + Delivery Checker) that duplicated the check-item list. Merge into a single card: the `Run Artifact · Round N` header, then the checker results + actions, then the snapshot note. RunArtifact/CheckerDock gain an `embedded` prop (header-only / body-only, no card chrome) and VerifyMessage composes them under one border. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): derive generateVerifyPlan rubric from agencyConfig A real agent calls `generateVerifyPlan` with just a `goal` and doesn't know rubric ids. When `rubricId`/`criteriaIds` params are absent, derive the mounted rubric + ad-hoc criteria from the executing agent's `agencyConfig.verifyRubricId / verifyCriteriaIds`. Params still win when given. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 🐛 fix(cli): surface agent gateway WebSocket close code + reason The `onclose` handler logged `String(event)` → the useless "[object CloseEvent]". Surface `event.code` (+ `event.reason` when present) so a gateway disconnect before completion is actually diagnosable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 💄 fix(verify): rename "Run Artifact" → "Verification", drop failed red border - The kicker said "Run Artifact" — it's automated verification, not an artifact. Renamed to "Verification · Round N". - Removed the red error border on a failed check — a normal card reads better. - Fixes a render crash (`useVerifyState is not defined`): the border removal left a dangling reference after the import was dropped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(cli): poll run status when the agent stream drops When the live stream (gateway WebSocket / SSE) closes before the run finishes, the run is still executing server-side — so instead of hard-exiting, fall back to polling `aiAgent.getOperationStatus` every 10s until the run reaches a terminal state (or is no longer tracked). Pairs with surfacing the WS close code/reason. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 💄 feat(verify): add Render for generateVerifyPlan tool call The generateVerifyPlan tool call rendered as the default param/result dump. Add a Render that lists the generated delivery checks (title + gate/auto-fill tag), and surface the items on the tool state so the Render can read them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): auto-confirm generated plan so checks run on completion The agent generated a plan but it stayed `planned`/unconfirmed, so the completion hook (which gates on a confirmed plan) never ran the checks — the card was stuck at "awaiting confirmation" with no pass/fail. In the headless agent flow there's no one to click Confirm, so `generateVerifyPlan` now auto-confirms the plan it generates; the checks then run automatically on completion. (An interactive "review before run" gate is a future enhancement.) Also: the verify card header disappeared in the draft/planned phase (`phaseToArtifact.draft` was null). Give it a header so the card always shows its "Verification · Round N" heading. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 🐛 fix(agent-tracing): only count opaque/presentational attrs as structural noise The first structuralNoiseRatio charged ALL markup (every <...> tag) as noise, which over-penalized legitimately structured results 3x. Grounding against real web-search output (`<item title="…" url="…">snippet</item>`) showed the tags and the title=/url= attributes ARE the signal the model reads. Now only opaque/presentational attribute names (id, class, style, data-*, aria-*, role, on*) count as noise; semantic element tags and content-bearing attributes (title, url, href, name…) are kept. On a 57-op user-interrupted sample this drops web-search noise 42%→0% and overall estimated waste 16%→5%, leaving large-payload (readDocument) and high error-rate tools as the real signal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): model-authored criteria with name/description/instruction-in-document + agent verifier Restructure the generateVerifyPlan tool to a createDocument-style full-create flow and wire up the agent verifier path: - criteria now = title + description (required one-liner) + instruction (required detailed rubric); instruction lives in a linked document (verify_criteria.documentId), description is a new verify_criteria column (migration 0111). verifierConfig no longer holds description/instruction. - generateVerifyPlan creates verify_criteria + a rubric, snapshots the plan onto the operation and confirms it; judge resolves the instruction from the document. - agent-type checks run as verifier sub-agents (execAgent + isolated thread) whose onComplete hook parses a VERDICT and writes it back to verify_check_results (renamed AgentVerifierSpawner → VerifierAgentRunner). - UI: custom Inspector for the tool header; check list shows per-verifier-type icons (llm/agent/program) + description + required/optional tag; i18n en/zh. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ⚡️ perf(verify): run program/llm/agent checks concurrently on completion The three verifier kinds are independent; previously the agent spawn waited for the batched LLM judge to finish. Run them via Promise.all so agent sub-agents start immediately alongside the LLM batch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): dedicated builtin verify-agent + writeback tool, role=verify message, portal check editor - Add `@lobechat/builtin-tool-verify` (submitVerifyResult) + builtin `verify-agent`; agent-type checks now run as the dedicated verify agent (not the user's agent), which investigates and writes its verdict back via the tool during its run. - Verifier inherits the parent run's model/provider (builtin default may be unconfigured locally). - role=verify completion message no longer requires an assistantMessageId, so the delivery-checker card always surfaces when a plan exists. - Portal editor for verify checks (title/description/instruction/verifier/onFail). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 🐛 fix(verify): restrict verify-agent to its writeback tool; fix running loader icon Root cause of stuck `running` agent checks: the verify-agent ran in agent mode and inherited all default tools (web-browsing, cloud-sandbox, skills, activator), so it went off web-searching/crawling to "investigate" and never called submitVerifyResult. - Run the verify-agent in chat mode (enableAgentMode: false, searchMode: off) — the strict whitelist — and whitelist `lobe-verify` for chat mode so the verifier gets ONLY its writeback tool. - Sharpen the verify systemRole: judge from the provided deliverable/instruction (no external tools), always reach a verdict, and always call submitVerifyResult. - CheckerDock: running check now uses the standard RingLoadingIcon (warning ring), matching the app's loader instead of a blue spinner. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): auto-repair loop — re-run the agent with failure feedback on failed checks When required checks fail with onFail=auto_repair, automatically run a second iteration instead of ending at `failed`: - createRepairRunner: re-runs the SAME agent in the same topic with the failure feedback as the prompt, re-snapshots the plan onto the repair operation and confirms it so it re-verifies on completion (the next round). Capped at MAX_REPAIR_ROUNDS via parent-chain depth to prevent runaway loops. - maybeAutoRepair: fires only once every required check has a terminal result, so it works for inline LLM checks (triggered from lifecycle) and async agent checks (triggered from the verify tool's writeback path). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): open check result detail in portal & rename artifact→result - add a VerifyResult portal view: clicking any check row opens that result's detail (verdict, confidence, Toulmin sections, suggestion) on the right; agent checks expose their execution trace from inside the panel - CheckerDock rows are all clickable now (chevron affordance), status shown by icon only; verify card uses colorBgElevated - rename the run-result surface from "artifact" to "result" everywhere: RunArtifact → RunResult, phaseToArtifact → phaseToResult, and all `artifact.*` i18n keys → `result.*` - ship verify namespace zh-CN / en-US locales Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): enrich check result portal — criterion stepper, richer detail view Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): rubric run-policy config + repair feedback on the verify card Auto-repair feedback now lives on the failed round's role=verify message (content), and the VerifyMessageProcessor surfaces it into the repair run's context as a tagged user turn — so the repair op runs off history via a new execAgent `suppressUserMessage` path instead of injecting a synthetic user message. createVerifyMessage is awaited before verification to avoid a race. maxRepairRounds becomes a rubric-level config: new `verify_rubrics.config` jsonb column, read live at repair time via the plan's sourceRubricId. Adds a RubricConfig portal panel (reachable from the plan card's settings affordance) to view/edit it, wired through the verify store + TRPC. Verify domain types/vocab/config are extracted from the DB schema into @lobechat/types as the single source of truth; schema and consumers import from there. Tests: VerifyMessageProcessor dual behavior; VerifyRubricModel config round-trip; MessageModel.findVerifyMessageByOperationId. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 🗃️ refactor(verify): squash the 3 verify migrations into one Collapse 0110 (tables) + 0111 (criteria.description) + 0112 (rubrics.config) into a single regenerated 0110_add_verify_tables so the PR ships one clean, idempotent migration. No schema change vs the three combined. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(cli): verify rubric run-policy config commands + shrink judging-rule editor font CLI: `verify rubric create --max-repair-rounds`, `verify rubric view`, and `verify rubric update` exercise the rubric config endpoints end-to-end; adds a mocked command test. UI: judging-rule editor font 16px → 14px. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(verify): editable rubric name in the config panel + default 3 repair rounds Add a name (title) field to the RubricConfig portal, persisted via a new updateRubricTitle store action + service (optimistic + debounced, alongside the config write-back). Bump DEFAULT_MAX_REPAIR_ROUNDS 2 → 3. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ♻️ refactor(verify): extract generateVerifyPlan into installable lobe-delivery-checker tool Move the delivery-checker plan-creation flow out of the always-on lobe-agent tool into a new standalone, installable builtin tool `lobe-delivery-checker` (Skill Store, opt-in per agent — not loaded by default). lobe-agent no longer ships generateVerifyPlan. - new packages/builtin-tool-lobe-delivery-checker (manifest/types/systemRole + client Render/Inspector/Portal moved wholesale from lobe-agent) - new serverRuntimes/lobeDeliveryChecker.ts (generateVerifyPlan moved out of lobeAgent.ts), registered alongside verifyResult - registered installable in builtin-tools (no hidden/discoverable:false, not in defaultToolIds/alwaysOnToolIds/runtimeManagedToolIds); renders/inspectors/ portals/identifiers wired; lobe-agent portal entries removed - i18n keys moved builtins.lobe-agent.verifyPlan.* → builtins.lobe-delivery-checker.* Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ✨ feat(agent): add `custom` tool mode; verify agent uses it instead of chat-mode Chat mode's contract is to strip ALL user/agent plugins (strict KB/memory/web allow-list) — so the verify sub-agent couldn't get its writeback tool without a leaky blanket rule. Introduce a third tool mode `custom` where the toolset is EXACTLY the agent's declared plugins (no always-on, no defaults, no activator), for focused builtin sub-agents. - chatConfig.toolMode: 'agent' | 'chat' | 'custom' (overrides enableAgentMode) - AgentToolsEngine: custom branch (defaultToolIds = plugins, rules = plugins-on, allowExplicitActivation only in agent mode); chatModeRules restored to strict - verify agent → toolMode: 'custom'; lobe-verify dropped from chatModeAllowedToolIds - test: custom mode enables exactly the declared plugin, no always-on / defaults Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
20cea3a6bf |
✨ feat(page-agent): execute tools server-side via HeadlessEditor (#15023)
* ✨ feat(page-agent): execute tools server-side via HeadlessEditor Page-agent tools (initPage / editTitle / getPageContent / modifyNodes / replaceText) now run on the server against a `@lobehub/editor/headless` instance and persist through `DocumentService.updateDocument`, instead of executing inside the renderer's Lexical instance. The renderer applies the resulting snapshot via the builtin-tool `onAfterCall` hook, so the document store stays in sync without an extra fetch. This makes page-agent execution independent of the client lifecycle (editor unmount, tab switch, network blip), gives us full server-side tracing for free (OTel gen-ai + agent-signal + documentHistories), and exposes a `silent-no-op` / `unexpected-mutation` invariant when the exported editorData hash diverges from what the handler reported. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * 🐛 fix(page-agent): decouple EditorRuntime from @lobehub/editor side-effecting bundle EditorRuntime statically imported LITEXML_*_COMMAND from @lobehub/editor, which pulls ReactSlashPlugin and crashes Node (`document is not defined`) in any server-side test that transitively touched the runtime. The same import also dispatched the wrong command identity on HeadlessEditor's kernel — pnpm resolves @lobehub/editor to a different module copy than the headless bundle, so dispatchCommand would silently no-op server-side. Introduce a LiteXMLAdapter strategy: renderer wires command dispatch against the live editor; server wires HeadlessEditor.applyLiteXMLBatch / applyLiteXML so the correct headless-bundle symbols are used. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * 🐛 fix(page-agent): restore client-side mutate handlers on PageEditor mount The main commit dropped `setBeforeMutateHandler`/`setAfterMutateHandler` under the assumption that page-agent tools always execute server-side. But the chat-store path (`invokeBuiltinTool` → `PageAgentExecutor.modifyNodes` → `EditorRuntime.modifyNodes`) still routes through the client-bound runtime whenever the LLM dispatcher is the chat slice — it does not consult `manifest.executors`. Without the handlers, that path mutates the live editor but skips both `documentHistoryQueueService.enqueueEditorSnapshot` (loses undo baseline) and `commitEditorMutation(saveSource: 'llm_call')` (row never persists). Re-wire both handlers. Server-runtime path is unaffected: it instantiates its own `EditorRuntime` against `HeadlessEditor` and never sees the client's StoreUpdater wiring, so the two paths can coexist without double-writing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(editor-runtime): split client / server entries so renderer gets adapter for free Renderer call sites shouldn't have to opt in to the obvious default (dispatch LITEXML_*_COMMAND on the live editor). Split the package into two entries: - `@lobechat/editor-runtime` — renderer entry; constructor auto-wires the LiteXML adapter from `@lobehub/editor`. Static-importing this from Node still crashes (ReactSlashPlugin), so it's the right shape for the browser only. - `@lobechat/editor-runtime/server` — server-safe entry; exports the bare class without touching `@lobehub/editor`. Callers (currently only the page-agent server runtime) supply their own HeadlessEditor- backed adapter. Drops the renderer-side setLiteXMLAdapter patch and a stale comment block in StoreUpdater. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(page-agent): drop LiteXMLAdapter, dispatch commands directly `@lobehub/editor` 4.16.1 ships the LiteXML command identities through the side-effect-free `@lobehub/editor/litexml-commands` subpath, so a single command object is shared across the browser and node bundles and can be imported in Node without pulling the DOM-dependent editor bundle. `EditorRuntime` now imports `LITEXML_MODIFY_COMMAND` / `LITEXML_APPLY_COMMAND` from that subpath and dispatches them straight onto the editor kernel. This removes the `LiteXMLAdapter` strategy object (`setLiteXMLAdapter` / `getLiteXMLAdapter`) — a leaky abstraction whose only purpose was to keep the crash-on-Node command import out of the shared base. - editor-runtime: dispatch `LITEXML_*_COMMAND` directly; delete the adapter interface, field, setter and runtime-throw guard. - Collapse the client/server entry split (its sole reason — isolating the DOM-crashing import — is gone); both entries now re-export the isomorphic base. - pageAgent server runtime: drop the HeadlessEditor-backed adapter wiring. - Bump `@lobehub/editor` to ^4.16.1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ♻️ refactor(editor-runtime): drop redundant /server entry Now that `EditorRuntime` is isomorphic (LiteXML commands come from the DOM-free `@lobehub/editor/litexml-commands` subpath), the `./server` entry is byte-for-byte identical to the root `.` entry. Remove it and point the only consumer (pageAgent server runtime) at the root entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
a28fd30719 |
✨ feat: suppport sandbox provider (#15184)
* ✨ feat(cloud-sandbox): add Onlyboxes provider support for self-hosted sandbox (#15136) - Add `SANDBOX_PROVIDER` env var (market | onlyboxes) to select sandbox backend - Add Onlyboxes-specific env vars: `ONLYBOXES_BASE_URL`, `ONLYBOXES_API_TOKEN`, `ONLYBOXES_LEASE_TTL_SEC` - Create `SandboxService` abstraction layer with `MarketSandboxService` and `OnlyboxesSandboxService` implementations - Add `createSandboxService` factory that routes to configured provider - Migrate `execInSandbox` and `exportFile` t * ✨ feat(sandbox): improve Onlyboxes export flow * 🐛 fix(sandbox): pass presigned upload headers to Onlyboxes * ✅ test(sandbox): import tool runtime package * 🐛 fix(sandbox): preserve Market export errors * 🐛 fix(sandbox): allow empty docker env defaults * 🔒 fix: redact sandbox auth params in logs * 🐛 fix: address sandbox provider review comments * 🔐 feat: use onlyboxes jit tokens * 📝 docs: clarify cloud sandbox provider config * 🐛 fix: align cloud sandbox timeout defaults * 🐛 fix(sandbox): lower default Onlyboxes lease TTL to 15 minutes * 🐛 fix(sandbox): cap Onlyboxes task wait time * ♻️ refactor: split sandbox env config |
||
|
|
248a4dcab5 | 🔖 chore(release): release version v2.2.2 [skip ci] | ||
|
|
6532cd1ee0 |
🚀 release: 20260604 (#15447)
# 🚀 LobeHub Release (20260604) **Release Date:** June 4, 2026 **Since v2.2.1:** 88 merged PRs · 11 contributors > This week brings Execution Devices out of the lab — run agents and Claude Code on any configured local or remote machine — alongside Claude Opus 4.8, token-usage analytics, and Page sharing. --- ## ✨ Highlights - **Execution Devices** — Pick where an agent runs. Desktop and CLI devices auto-register with a stable machine ID, route through the gateway by channel, and surface a device switcher in the chat input. Run remote Claude Code on a configured device, with a recent-directory picker you can drag to reorder. (#15300, #15315, #15322, #15343, #15351, #15371) - **Claude Opus 4.8** — Day-one support for Anthropic's latest model. (#15314) - **Token-usage analytics** — A new token-usage mode on the activity heatmap, backed by a denormalized topic usage/cost rollup so totals stay accurate without recomputing from messages. (#15365, #15417, #15425) - **Page sharing** — Share a Page through a dedicated document share flow, plus new Workspace and Agent share tables. (#15309, #15439) - **Self-iteration agents** — Agent Signal's execAgent migration lands a server-runtime bridge, async memory writer, and a registered self-iteration tool package, with a CLI trigger command for testing. (#15360, #15364, #15392) - **Knowledge search** — BM25 search now extends to file-backed documents, and the portal ships an editable CodeMirror viewer for local files with document highlighting. (#15247, #15298) --- ## 🏗️ Core Agent & Architecture ### Agent Signal & Runtime - **execAgent migration** — Server-runtime bridge, completion projection, async memory writer, and removal of the legacy `executeSelfIteration` path. (#15392) - Registered the self-iteration builtin tool package and restored the three mode-specific self-iteration agent slugs. (#15202, #15364) - Added a CLI trigger command with a golden-snapshot fixture for Agent Signal. (#15360) - **Skill priority** — Agent Builder now emits a skill-priority instruction with matching server runtime. (#15409) - Retry empty LLM completions instead of silently finishing the turn. (#15355) - Classify topic/agent/session foreign-key violations as `ConversationParentMissing` for clearer recovery. (#15408) - Persist canonical nested usage/performance on assistant messages, and re-link orphan tool messages at the raw bucket write boundary. (#15359, #15438) - Guard `createAgent` against LLM double-encoded array fields. (#15381) --- ## 🖥️ Execution Devices & Gateway - Auto-register desktop and CLI devices with a stable machine ID, and add the `@lobechat/device-identity` package. (#15300, #15321) - New Devices settings page behind the Execution Device Switcher lab, with a device switcher shown for all agents in the chat input. (#15315, #15371) - `connectionId` + channel routing across the gateway client and device list; preset the local device on the first LLM request for the 本机 target. (#15322, #15435) - Run remote Claude Code on a configured device, with drag-to-reorder recent-directory management and client renders for device tool results. (#15343, #15351, #15437) - Preserve content and state across gateway tool calls, and prevent duplicate streaming from stale reconnects. (#15114, #15354) --- ## 🖥️ CLI & Desktop - Preserve content/state for connect local file and shell tools; render the `runCommand` tool result card. (#15441, #15442) - New `lh topic view` command; CLI now auto-registers its device on login, matching desktop. (#15340, #15377) - Resolve CLI tools from the shell `PATH`, and clarify local command session handling. (#15368, #15389) - Relocate visual-ref helpers to `@lobechat/const` to fix a renderer crash; upload `.blockmap` files to S3 for differential updates. (#15326, #15369) - Fix a market OAuth expiry that triggered the wrong re-login modal, and kill dev child processes on parent shutdown. (#15246, #15290) --- ## 🗂️ Pages, Library & Knowledge - Document share flow with business slot stubs, plus Workspace and Agent share tables. (#15309, #15439) - Export Agent profiles as Markdown, preserving an empty agent prompt on export. (#15312, #15316) - Editable CodeMirror viewer for local files with document highlighting; BM25 search extended to file-backed documents. (#15247, #15298) - Default new Agent-doc files to `.md` and preserve IME composition; refresh folder data on slug switch and dedupe breadcrumb fetches. (#15335, #15427) --- ## 💬 Chat & User Experience - Group-by-status mode for the Topic sidebar; dropped the legacy session→agentId compatibility path from Topic queries. (#15366, #15378) - Restore editor focus after the file picker closes, and close the skill dropdown before navigating to settings. (#15391, #15394) - Strip markdown tokens from fallback Topic titles; keep an open ActionBar popup when hovering another message. (#15303, #15372) - Stabilize home starter loading and stop transliterating model names in the home starter; show artifact source while streaming. (#15310, #15324, #15386) - Group the sidebar spacer with recents and agents. (#15373) --- ## 📊 Analytics, Tasks & Notifications - Token-usage mode on the activity heatmap, backed by a denormalized topic usage/cost rollup. (#15365, #15417, #15425) - Push: new `PushChannel`, receipt cron, and `pushToken` tRPC API. (#15233) - Tasks now support file and image attachments. (#15141) --- ## 🧩 Models & Providers - Support Claude Opus 4.8 and configurable model routing with starters. (#15314, #15384) - MiniMax M3: new model entry and an Anthropic video runtime. (#15380, #15403) - Add `intern-s2-preview` with `thinking_mode`, and `step-3.7-flash` support. (#15308, #15317) - Block disabling the official provider; fix default provider setup in business mode. (#15379, #15382) --- ## 🎨 UI & Modals - Migrate modals to `@lobehub/ui/base-ui` (LOBE-9711 + eval batch), including the create-custom-model and feedback/changelog modals. (#15401, #15416) - Restructure confirmModal title and content across deletion flows; polish the service-model form and migrate its Switch to base-ui. (#15426, #15440) - Wrap the BlueBubbles bridge config into a connection card; update `@lobehub/ui` to v5.15.5. (#15325, #15342) --- ## 🔒 Reliability - Replace hardcoded `session_context` values with template variables in credentials. (#15352) - Point `CHANGELOG_URL` to `/changelog`. (#15428) --- ## 👥 Contributors Huge thanks to **11 contributors** who shipped **88 merged PRs** this cycle. @hezhijie0327 · @qybaihe · @sxjeru · @arvinxx · @Innei · @tjx666 · @LiJian · @sudongyuer · @cy948 · @rivertwilight · @AmAzing129 Plus @lobehubbot and renovate[bot] for maintenance. --- **Full Changelog**: v2.2.1...release/weekly-20260604 |
||
|
|
d9673c3c41 |
♻️ refactor(agent-signal): execAgent migration — serverRuntime bridge + completion projection + async memoryWriter + executeSelfIteration removal (#15392)
* 🚧 wip(agent-signal): S1 — self-iteration tools as static primitives, no side-channel Rewrite all three self-iteration execAgent tool surfaces (review / reflection / feedback-intent) as static, named primitives instead of reusing the dynamic createServerToolSet / createToolSet factory (which carries the legacy reserveOperation / receipt / completeOperation side channel the migration removes). Package (builtin-tool-agent-signal): - AgentSignalToolService.invoke (generic bag) → AgentSignalRuntimeService, a narrow named DB-primitive seam (skillManagement precedent). Artifact recorders echo their input; reads/mutations route to one primitive each. The runtime carries no dedupe / receipt / operation-state side channel — idempotency and receipt projection live on the completion path, not the tool call. Server primitives (pure live-DB reads + writes, keyed to api names): - review/server.ts createReviewRuntimePrimitives — proposal lifecycle + resource tools, parameterized by window scalars from the operation marker, reusing the existing snapshot/preflight/projection/brief helpers. - tools/runtimePrimitives.ts createResourceRuntimePrimitives — the skill-read / skill-write / writeMemory surface shared by reflection and feedback-intent. - No context blob and no getEvidenceDigest: evidence is embedded in the agent prompt, so tools only touch live state. serverRuntimes: agentSignalReview / agentSignalReflection / agentSignalFeedbackIntent thin factories wiring ToolExecutionContext → primitives → package runtime, all registered. createServerToolSet / createToolSet left untouched (legacy executeSelfIteration path, removed in S4). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 🚧 wip(agent-signal): S2 — completion-path receipt projection from finalState Replace the in-runtime receipt accumulator with finalState-driven projection on the completion path. finalState is only in hand inside the completion lifecycle (S3 final snapshots are write-only — get() is a null stub; the operation row has no messages; prod webhook hooks strip finalState), so receipts must be projected from the one point state exists. - CompletionLifecycle.emitSignalEvents: extract the compact, kind-tagged tool outcomes from the terminal state (extractSelfIterationCompletionPayload) and carry them on the agent.execution.completed payload — only for marked self-iteration runs, never the full message history. - completionPolicy: forward the payload to onSelfIterationCompleted. - completion/buildSelfIterationReceipts: project mutations + artifacts into user-visible receipts, mirroring the legacy createReceipts kind/status/target mapping. Deterministic receipt ids (sourceId + tool call id) → idempotent re-projection; the store dedupes by id. - completion/selfIterationCompletionHandler: build + persist receipts. - orchestrator: wire the handler into createDefaultAgentSignalPolicies. - agent-signal source type: add an opaque selfIteration field to the agent.execution.completed payload. Inert until the dispatch side stamps the operation marker (S3 / S4): without a marker the extractor returns undefined and the handler no-ops. Tests: buildSelfIterationReceipts (5) + extractCompletionPayload (4); completion policy + CompletionLifecycle + orchestrator suites green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 🚧 wip(agent-signal): S3 part 1 — completion-side memory receipt support (inert) Foundation for migrating the memory writer to the async execAgent path: teach the completion path to project a memory receipt from a finished memory-writer run. Inert until the dispatch side stamps a kind:'memory' marker (part 2). - completion routing is now keyed on the operation MARKER (the selfIteration payload), not the agent slug — a memory writer runs as the user's own agent, so a slug check would miss it. completionPolicy gates on payload presence; agentId loosened to string. - extractCompletionPayload: for a kind:'memory' run, synthesize a writeMemory mutation from the run's finalState (the memory builtin tool results are not kind-tagged, so extractMutations finds nothing) via resolveMemoryActionResultFromState. - buildSelfIterationReceipts: a memory run surfaces as just its action receipt, no aggregate review summary. - extract the pure memory finalState parsers into a dependency-light ./memoryActionResult module so the completion lifecycle can reuse them without dragging the heavy memory-runner module (ModelRuntime/AgentService/…) into its graph. userMemory re-exports them for backward compat. - bump a too-tight (5s) timeout on the real-orchestration integration test. Tests: completion (12) + completionPolicy (8) + userMemory (12) green; agentSignal policies + orchestrator suites (138) green; type-check clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ♻️ refactor(agent-signal): S3 — migrate memoryWriter to async execAgent + completion receipt Flip the memory-writer action from a blocking executeSync run to an async queued operation (autoStart) stamped with an agent-signal `memory` marker. The user-visible "memory saved" receipt is no longer projected synchronously from the action result — it is projected on the completion path from the run's finalState (extractMemoryMutations → buildSelfIterationReceipts), so the receipt appears a few seconds later once the run completes. - userMemory.ts: add `dispatch` path enqueuing via createOperation(autoStart), stamping appContext.agentSignal so completion can project the receipt. - receiptService.ts: drop the synchronous memory receipt projection (would duplicate the async one, with a premature empty target). - types.ts: add `agentSignal` marker to OperationCreationParams.appContext. - tests: cover the memory-kind completion loop end-to-end (single memory receipt, correct target + anchor, no aggregate summary). Note: the memory run uses createOperation (not execAgent), so it never synthesises a user message and cannot recurse into analyzeIntent — no suppressSignal needed on this path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 🚧 wip(agent-signal): S4 step 0 — forward agentSignal marker through execAgent Foundation for migrating self-iteration onto execAgent: let a background run carry its agent-signal marker so the S2 completion path can project receipts. - Move AgentSignalOperationMarker / AgentSignalOperationKind into @lobechat/types (ExecAgentAppContext can now reference it); operationMarker.ts re-exports the type and keeps the runtime parse/validate helpers. - ExecAgentAppContext: add `agentSignal?` field. - execAgent: forward `appContext.agentSignal` into createOperation's appContext (it was dropped by the curated passthrough), so it lands in state.metadata.agentSignal — the key the completion extractor reads. No behaviour change yet: nothing sets appContext.agentSignal on the execAgent path until the self-iteration dispatch helper lands. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 🚧 wip(agent-signal): S4 step 0b — self-iteration execAgent dispatch helper Shared primitive for migrating the 3 self-iteration modes off the hand-rolled runtime onto async execAgent (used by reflection/feedback/nightly-review next). - enqueueSelfIterationRun(): create an isolated thread (when anchored), then execAgent the builtin slug with suppressSignal + the agent-signal marker on appContext, autoStart, headless. Returns immediately (fire-and-forget). - marker: add `agentId` (the reviewed user agent). A slug run resolves the operation agentId to the builtin agent, so receipts must attribute to the reviewed agent carried on the marker. - buildSelfIterationReceipts: attribute to `marker.agentId ?? agentId` (memory runs leave it unset and fall back to the run agentId — unchanged). Not wired into the mode handlers yet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ♻️ refactor(agent-signal): S4 — migrate executeSelfIteration to async execAgent Replace the hand-rolled `executeSelfIteration` runtime (new AgentRuntime + custom call_llm executor + 6 closure side-channels) with the standard async `execAgent` queue path. nightly-review / self-reflection / self-feedback-intent now enqueue via `enqueueSelfIterationRun → execAgent` and project their receipts/briefs on the `agent.execution.completed` completion path. - Delete `execute.ts` (1500 lines) + `execute.test.ts`; gut the three server adapters (review/reflection/feedback) to drop the synchronous run path and the legacy receipt/runtime wiring. - `aiAgent`: background runs execute under a builtin slug but attribute their resource tools + receipts to the *reviewed* user agent via the run marker. - Drop the orchestrator's `writeDailyBrief` default — nightly review writes its brief in-run via the builtin review serverRuntime primitive. - Add `ReviewRunStatus.Dispatched` for enqueued background runs. - Completion-path debug logging across CompletionLifecycle / completionPolicy / completion handler. Part of LOBE-9434 (S4 · LOBE-9876). * 🐛 fix(agent-signal): make execAgent resolve builtin slugs + give self-iteration agents a mini model Live-testing the S4 self-iteration → execAgent path surfaced two gaps that kept background runs (nightly-review / self-reflection / self-feedback-intent) from ever dispatching: - execAgent threw `Agent not found: <slug>` when addressed purely by a builtin slug (the self-iteration dispatch path) because getAgentConfig only resolves persisted rows. Lazily materialize the virtual builtin row via AgentModel.getBuiltinAgent — mirrors the inbox/task precedent — then re-resolve. - The three self-iteration builtin agents had no `persist` model, so runs fell back to the user's default chat model. Give them `persist: { DEFAULT_MINI_MODEL, DEFAULT_MINI_PROVIDER }` (gpt-5.4-mini), matching the legacy executeSelfIteration behavior. Verified live: self-reflection now dispatches, the async operation reaches `done`, and a `review` completion receipt is projected on the completion path. Adds two execAgent.builtinRuntime tests (builtin-slug materialization + unknown-id still throws). Part of LOBE-9434 (S4). * 🚨 fix(agent-signal): use type-only import for createServerSelfReviewBriefWriter After the S4 gutting, review/server.ts only uses createServerSelfReviewBriefWriter in a `ReturnType<typeof ...>` position — split it into a type-only import to satisfy @typescript-eslint/consistent-type-imports (the lone lint:ts error). * 🐛 fix(agent-signal): carry tool apiName in result content so action receipts project The agent runtime persists tool messages with only content/role/tool_call_id (no message-level apiName), so the completion extractor's `message.apiName` read was always undefined in live runs — buildSelfIterationReceipts then dropped every mutation via `if (!apiName) return []`, so durable skill/proposal writes produced no action receipt (only the summary survived; memory was exempt via a hard-coded apiName). Fix the extraction channel, not the shared runtime: - ExecutionRuntime stamps `apiName` into the result content alongside `kind`. - extractFromFinalState reads apiName from the content (message.apiName fallback). Tests reworked to the real persisted shape (apiName in content, no message-level apiName) — the prior mocks hid the bug. Part of LOBE-9434 (S4). * 🐛 fix(agent-signal): persist run marker to operation metadata for server tools Self-iteration server tools (nightly-review etc.) read the run marker from `agent_operations.metadata` via readAgentSignalMarker, but recordStart only persisted a trimmed appContext and never wrote metadata — so in live runs the marker was always undefined and review/proposal writes fell back to a 1970 window/localDate + operationId source (non-idempotent). recordStart now persists `metadata: { agentSignal }` from appContext.agentSignal, so the tool path matches the completion path (which reads it from finalState). Part of LOBE-9434 (S4). --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
c50d790feb | 🔨 chore: pin Vitest 3.2.4 (#15383) | ||
|
|
4d840e9071 |
✨ feat(push): add PushChannel, receipt cron, and pushToken tRPC API (#15233)
Send-side machinery for mobile push notifications (LOBE-8771), stacked on top of the schema PR (#15186). ### tRPC - `pushToken.register` / `pushToken.unregister` exposed on both `MobileRouter` and `LambdaRouter`. ### `PushChannel` - Structurally compatible with cloud's `NotificationChannel` so cloud can register it without casts. - Fans a single notification out to all of a user's tokens, chunks via `expo-server-sdk`, respects the 600 msg/sec project limit with 100ms throttle between chunks. - Embeds `(ticketId, expoToken)` pairs in `providerMessageId` for receipt reconciliation. - Returns `no_tokens` / `invalid_tokens` / `rate_limited` / `all_send_failed` so callers can distinguish. ### `processPushReceipts` - Pure helper to be called by cloud's Vercel cron (companion PR). - Polls Expo receipts in parallel (`Promise.all` across chunks), updates `notification_deliveries` in bulk, prunes `push_tokens` rows flagged `DeviceNotRegistered`. - Configurable lookback window + min-age guard (default: 24h / 15min). ### Dev tooling - `/api/dev/test-push` (404s in production) lets you fire a real push directly to a user's registered tokens, bypassing `NotificationService`. Useful for end-to-end verification before cloud submodule sync. ### Types - `NotificationSettings` gains an optional `push` channel. Tests: 21 added (router 7, PushChannel 7, processPushReceipts 7). Linear: https://linear.app/lobehub/issue/LOBE-8771 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
0139c054a2 |
⬆️ chore: update @lobehub/ui to v5.15.5 (#15325)
Bump @lobehub/ui from the pkg.pr.new preview to the released v5.15.5, and switch the community user list search inputs from antd Input.Search to @lobehub/ui SearchBar to align height with the status Select. |
||
|
|
049c81d53b | 🔖 chore(release): release version v2.2.1 [skip ci] | ||
|
|
9945cecf87 |
✨ feat(portal): editable CodeMirror viewer for LocalFile + Document highlight (#15298)
* ✨ feat(portal): editable CodeMirror viewer for LocalFile + Document highlight Replace the read-only Highlighter in the LocalFile portal preview and the Document portal highlight mode with a shared `CodeEditorPane` powered by `@lobehub/editor/codemirror`. Pane supports inline editing, Cmd/Ctrl+S to save, lobeTheme tokens, and language-aware syntax highlighting. LocalFile flow - Track per-path edit buffers + save action in the chat portal store (`dirtyLocalFileContents`, `setLocalFileBuffer`, `saveLocalFile`). - Show a filled dot on the tab close button when the file is dirty; hovering still reveals the X. Closing a dirty tab (via X or the context menu's "Close") prompts a confirmation modal via `confirmModal` from `@lobehub/ui/base-ui`. - After save, mutate the SWR cache to the just-saved content before clearing the buffer so CodeMirror does not see a stale `value` prop and reset the cursor. Document flow - For non-markdown documents (`getDocumentRenderMode` → `highlight`), render `CodeEditorPane` with a local edit buffer keyed by `documentId`. - Save calls `documentService.updateDocument({ saveSource: 'manual' })`, mutates the document-meta SWR cache, then clears the buffer. Bump `@lobehub/editor` to ^4.15.0 to pick up the new `@lobehub/editor/codemirror` subpath export. * 🐛 fix(portal): force read-only on truncated local file previews When a file exceeds MAX_PREVIEW_CHARS the preview only holds the first 500k character prefix. Editing and saving against that prefix would silently overwrite the rest of the file with the truncated content. Pass `readOnly={truncated}` to the editor, ignore any stale buffer when truncated, and short-circuit handleSave so Cmd/Ctrl+S is a no-op in this mode. * ♻️ refactor(portal): drop MAX_PREVIEW_CHARS truncation for local files Always pass the full file content to the editor instead of slicing at 500k characters. The truncation existed only to avoid losing data when saving the previously-Highlighter-rendered prefix, but with full content available the editor can both display and persist the file safely. Removes the `truncated` / `truncatedLabel` plumbing, the truncated banner, and the associated read-only short-circuit in handleSave. * ✅ test(portal): update document body highlight editor test |
||
|
|
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> |