Commit Graph

106 Commits

Author SHA1 Message Date
Rdmclin2 6313b37662 📝 docs: improve Feishu/Lark setup and refresh translations (#19349)
* 📝 docs: clarify Feishu and Lark event subscription setup

* 📝 docs: add Feishu and Lark quick-create guides

* 📝 docs: version Feishu and Lark setup screenshots

* 📝 docs: use durable versioned setup screenshot URLs

* 🌐 chore: refresh translations and screenshot references after rebase

* 🌐 chore: sync translations and assets with latest canary

* 🌐 fix: correct Dutch and Portuguese agent labels

* 📝 docs: host channel screenshots through persistent file links
2026-09-10 23:34:50 +08:00
Rdmclin2 4bf05e2499 🐛 fix(bot): surface budget scope and headroom in bot failure replies (#19336)
* 🐛 fix(bot): surface budget scope and headroom in bot failure replies

Carry the budget context of an InsufficientBudgetForModel error from the
runtime lifecycle event through the hook payload into the bot reply, and
render a scope-aware message (member allowance vs. workspace pool) with
the remaining and required credits instead of the generic
"Agent Execution Failed".

LOBE-13726

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RKPxmeT4DrAdKP3RUCYzgp

* 🌐 style: update i18n

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RKPxmeT4DrAdKP3RUCYzgp

* 🔒 fix(bot): stop quoting the billed allowance in budget replies

Runs mentioned from a shared channel are billed to the bot owner, so a
reply that quoted availableCredits / requiredCredits published the
owner's balance to every channel member. Keep the scope-aware copy and
drop the amounts line; a regression test asserts no figure is rendered.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RKPxmeT4DrAdKP3RUCYzgp

* 💬 fix(bot): address the bot owner and split plan-limit copy in budget replies

Runs are billed to the bot owner, not to whoever mentioned the bot, so the
budget copy no longer calls the reader the payer ("your budget") and
points at the bot owner / workspace admin instead. FreePlanLimit and
SubscriptionPlanLimit get their own copy (the allowance itself is
exhausted, so the fix is the plan, not a cheaper model), and the
budgetTypeAtError scope refinement now applies to all three admission
codes since the workspace gate throws SubscriptionPlanLimit when a run
can't be priced upfront.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RKPxmeT4DrAdKP3RUCYzgp

* 💬 fix(bot): cover both meanings of SubscriptionPlanLimit in the reply

Per the error taxonomy the code fires when the paid-plan allowance is
reached OR when the plan tier does not cover the requested model, so the
copy no longer claims the credits are spent and offers upgrade / top-up /
custom API as the remedies.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RKPxmeT4DrAdKP3RUCYzgp

* 👷 build: serialize build scripts so editor postinstalls stop racing on lexical

Three peer-variant copies of @lobehub/editor patch the same hoisted
lexical files in postinstall; run concurrently they read each other's
half-written output and fail with "Patch context mismatch". Only the
allowBuilds packages run scripts, so childConcurrency: 1 costs seconds.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RKPxmeT4DrAdKP3RUCYzgp

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 23:30:38 +08:00
Rdmclin2 3412626de9 🐛 fix: keep the resource tree and connector list in sync with their scope (#19156)
* 🐛 fix: keep the resource tree and connector list in sync with their scope

Three scope/staleness fixes that share the same shape — a client store
holding on to rows the current context no longer owns.

- LOBE-13804: `useFileItemDropdown` refreshed the tree with the explorer's
  current folder, but the sidebar navigates into a folder on click, so
  "open it, then delete it" refreshed the deleted folder while the parent
  list kept the row until a reload. Tree store gains `dropNodes`, which
  drops the rows where they actually live, purges the removed subtree's
  caches, and revalidates only the parents that were hit. Explorer bulk
  delete now syncs the tree too, and deleting the folder the explorer sits
  in steps out to the parent instead of stranding a dead route.
- T-392: connector fetches wrote their result without checking the scope
  they were issued in, so a personal `list` still in flight could land
  after the workspace switch and pin the wrong list for the session.
  Capture `getActiveWorkspaceId()` before the request and discard a stale
  response, mirroring the builtin slice.
- LOBE-13805: drop the permanently disabled workspace settings reset entry
  and its locale keys.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHwD8Ev5t7y3xDiBTc9m8K

* 🌐 chore(i18n): run the translation workflow

Regenerated after the rebase. Backfills keys other iterations left
untranslated and drops entries whose source keys are gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHwD8Ev5t7y3xDiBTc9m8K

* 🐛 fix: step out of a deleted folder's whole subtree, not just the folder

Review follow-up on the sidebar delete fix.

`handleDeleted` compared the deleted row against the explorer's selection
directly, so it only fired when the explorer was parked in the folder being
deleted. Deleting an *ancestor* — the sidebar renders the whole path, so
that is one click away — left the explorer exactly where the guard exists to
prevent: an empty list under a breadcrumb naming a folder that no longer
exists. Opening a document inside the deleted folder had the same shape.

Adds `hierarchySubtreeHoldsSelection`, which walks the loaded subtree and
answers whether the selection sits anywhere inside it. A selection under a
folder the sidebar never expanded is invisible to the walk and the explorer
stays put, matching how the rest of the tree treats folders it has not
fetched.

`onDeleted` now fires before `dropNodes` rather than after: the purge forgets
the subtree synchronously, so a caller that has to inspect what is about to
disappear could not see it. The fallback parent key is captured before the
callback runs, so the ordering carries no other meaning.

Also covers the two behaviours that shipped untested — the explorer's bulk
delete syncing the tree, and the folder-refresh path when the deleted set is
only known to the server — and documents why a discarded connector response
deliberately leaves the init flag alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHwD8Ev5t7y3xDiBTc9m8K

* 🐛 fix: don't yank the user back when a slow delete finally lands

Codex review follow-up (P2).

`handleDeleted` read the selection and library from the closure the context
menu captured when it was rendered. The delete is async, so a user who opens
another folder — or another library — while the request is still in flight
was navigated back to the deleted folder's old parent once it resolved,
after they had already moved on.

The decision now moves into `resolveDeletedFolderRedirect`, a pure function
over a snapshot the caller reads at call time: the component keeps the live
library and selection in a ref updated each commit, and skips entirely when
the row has unmounted, which is itself proof the user navigated away.

Making it pure also lets the delayed-delete case be tested directly, which
the component-level logic could not be.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHwD8Ev5t7y3xDiBTc9m8K

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 21:27:06 +08:00
Rdmclin2 35471de251 🐛 fix(task): load the full task list and virtualize the Tasks page (#19108)
* 🐛 fix(task): load the full task list and virtualize the Tasks page

The Tasks page only ever received the first server page (50 newest by
creation) and had no pagination, so a workspace past 50 tasks silently
dropped its older rows — e.g. a private task assigned to the viewer showed
under "Private" but not under "All" (LOBE-13779).

- `useFetchTaskList` gains `complete`: fetch every page (100/page, merged
  and de-duplicated by id) up to a 1000-row ceiling; the Tasks page opts in,
  embedded overviews keep the single page.
- `TaskList` renders through `react-virtuoso` on the page's own scroller:
  group headers and rows are flattened into one virtual list, collapse
  state lives in the list, and a truncation notice covers the ceiling.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJXLhkz7QpDyRVFTjLt4JJ

* 🌐 style: update i18n

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJXLhkz7QpDyRVFTjLt4JJ

* 🐛 fix(task): stable page order, gate the full fetch to the ordinary tab

Codex review round 1:
- `seq` breaks `createdAt` / `updatedAt` ties in every task list ordering
  (list, group prefetch, ranked group windows) so consecutive offset pages
  never repeat or skip a row; regression test pages through five rows that
  share a timestamp.
- The Tasks page only runs the full `complete` fetch on the ordinary tab;
  the scheduled and "My tasks" tabs render their own paginated collections.
- Restore the hand-authored zh-CN goal-acceptance copy the i18n sweep
  rewrote.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJXLhkz7QpDyRVFTjLt4JJ

* ♻️ refactor(task): walk the full task list with a keyset cursor

Codex review round 2: fixed-offset pages can repeat or skip a row when a
task is deleted (or created) between two page reads. `task.list` now takes
an `after: { at, seq }` cursor — rows strictly after that position in the
list's `(orderBy, seq)` order — and the Tasks page walks pages sequentially
from the last row it holds, so concurrent changes shift nothing.
Regression tests cover a delete between pages (model + store) and a cursor
on the `updatedAt` ordering.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJXLhkz7QpDyRVFTjLt4JJ

* ♻️ refactor(task): walk the full list only in the list view

Codex review round 3: the kanban view fetches its own server groups, so the
ordinary tab now walks every page only in list mode and keeps the single
page the empty-hero decision needs otherwise. `complete` joins the SWR key
and the store's query-scope guard, so the walked list and the single page
never serve each other from a shared entry or the shared store field.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJXLhkz7QpDyRVFTjLt4JJ

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 23:08:45 +08:00
Rdmclin2 a4caede6f5 ✨ feat(task): member assign notifications, mentions & tool assignee (#19035)
* ✨ feat: workspace task assignment & comment notifications with member mentions

- notify the assignee when a workspace task is assigned to them
- notify participants on task comment activity and workspace member @mentions
- task builtin tool: assigneeUserId support with dual (agent + member) assignee model
- workspace member directory exposes email for assignee resolution

* 🌐 style: update i18n

* 🐛 fix(task): retain notifications after the response and gate them by task access

Codex review round 1 on #19035:
- deliver assignment / comment pings through after() with try/catch instead of
  bare void calls (serverless keeps the work alive, rejections are logged);
  same lifecycle in the tool server runtime
- re-authorize comment-ping recipients against the task before delivery:
  private tasks never leak to members who cannot open them, and creator /
  assignee rows are re-checked for active membership (shared helper
  filterActiveWorkspaceMemberIds)
- listWorkspaceMembers: optional query + limit (default 50, max 100) on both
  the server runtime and the client executor, header announces the cap; the
  tool description only promises IM identities where available
- My tasks: hideCompleted is sent as a server status filter and ordering is
  pinned to the updatedAt-desc page order, so cuts happen before pagination

* 🐛 fix(task): unwrap native Slack/Discord mentions in the member directory query

Codex review round 2 on #19035: `<@U123>`, `<@U123|name>`, `<@4521>` and
`<@!4521>` are folded to the bare platform id (and a leading @ stripped) in
normalizeMemberQuery before matching, so the deterministic resolution the tool
description promises works when the model passes a mention through verbatim.

* 🐛 fix(task): scope member directory lookups to the workspace and push search into SQL

Codex review round 3 on #19035:
- MessengerAccountLinkModel.findByUserIds takes a scope: only identities
  active under the current workspace (or personal scope) are exposed, so a
  member's IM handles linked elsewhere never reach coworkers' tool output
- WorkspaceMemberModel.searchAssignableMembers applies the role gate, the
  query (id / name / handle / email / workspace-scoped IM identity) and the
  limit in SQL with a separate count; the runtime decorates only the page
- My tasks / scheduled: use the comparator token that renders a page
  newest-first (compareTaskItems inverts orderDirection for date columns)

* ✅ test(task): fix test-file type errors flagged by the OSS type-check

- integration test: otherUserId is string | undefined at the insert sites
- member directory test: seed the owner row directly (addMember is typed to
  non-owner roles)

* 🐛 fix(task): render every fetched row in the paginated task collections

Codex review round 4 on #19035 (LOBE-13749): with showSubTasks off, TaskList
folded a sub-task away whenever its parent shared the page, so a server page
came back sparse while total still counted the hidden rows. My tasks and the
scheduled tab now pin showSubTasks alongside the server page order; nesting
still tucks a child under a parent on the same page.
2026-09-02 17:55:01 +08:00
Rdmclin2 4471c7aafe ✨ feat: KB sidebar search/add button and comment image thumbnails (#19010)
* ✨ feat: KB sidebar search/add button and comment image thumbnails

* 🌐 style: update i18n

* 🐛 fix: gate the KB parent bypass on folder type and reveal after deferred upload

* ✨ feat: load sidebar search results incrementally and revalidate them with the tree

* 🐛 fix: hide stale sidebar search rows, reveal folder action on focus, localize Untitled
2026-09-02 11:56:23 +08:00
Rdmclin2 14b711e783 🐛 fix(page-editor): publish lock ownerId reliably and self-heal CONFLICT saves (#18848)
* 🐛 fix(page-editor): publish lock ownerId reliably and self-heal CONFLICT saves

The lockOwnerId dispatch in useDocumentLock lands before the document row
exists in the store, so the reducer drops it and every save goes out with an
undefined ownerId — the server then rejects the write as a CONFLICT against
the user's own lease. Republish the ownerId once the document is loaded,
retry a CONFLICT save once after reclaiming the same-user lease, and stop
surfacing save failures with the file-library network error copy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

* 🌐 chore(i18n): translate pending locale keys

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

* 🐛 fix(page-editor): guard the CONFLICT retry against a collaborator's newer version

A conflicting lease can belong to another member who saved and released it
before the recovery ran; reclaiming the now-free lease and resending the
stale payload would overwrite their save. Compare the server copy with the
session's last-known content and retry only on an exact match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

* 🐛 fix(page-editor): make the CONFLICT retry an atomic server-side version check

The client-side content comparison left a TOCTOU window between the fetch
and the reclaim, and ignored editorData-only collaborator changes. The
recovery now compares content AND editorData against the session's
last-known version and pins the retried save to that verified version via a
new optional expectedUpdatedAt predicate, which updateDocument re-checks
under FOR UPDATE inside the write transaction — an interleaved collaborator
save now fails the retry with CONFLICT instead of being overwritten.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

* 🐛 fix(page-editor): hand back the reclaimed lease when the CONFLICT retry fails

A failed CAS retry left this session holding the lease it had just
reclaimed, so the lock recovery read the tab as the legitimate holder,
cleared the save block, and reopened a stale editor. Release the lease
before rethrowing so the lock state reflects reality.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

* 🐛 fix(page-editor): add expectedUpdatedAt to the manual UpdateDocumentInput type

The tsgo lint step failed: the manually-maintained UpdateDocumentInput
interface lagged the zod schema, and the retry helper's version check did
not narrow `latest` for TypeScript.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

* 🐛 fix(page-editor): bind conflict recovery to the failed save's base version

The recovery compared the fetched server copy against the LIVE store
snapshot, so when an overlapping newer save from the same tab completed
while the older request was in flight, the check matched the newer version
and the retry replayed the older payload over it. Compare against the
immutable store snapshot captured when the failed save started instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

* 🐛 fix(page-editor): self-heal only plain content saves

A save carrying title/emoji or a history restore replays fields the
recovery's content+editorData comparison cannot vouch for — a
collaborator's metadata-only change would be silently overwritten by the
retry. Those saves keep the plain CONFLICT flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

* 🔧 chore(test): pin happy-dom below 20.12 to unblock CI

happy-dom 20.12.0 (released 2026-08-29T16:12Z) changed Web Animations
behavior in a way that makes motion-dom animation teardown reject with
unhandled 'AbortError: The animation was canceled' — every Test App shard
run after the release fails at exit despite all tests passing (canary flaps
identically). Pin to ~20.11.15 until happy-dom/motion settle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X64zT9QD5FHwJkekYAQgE

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 09:46:01 +08:00
Arvin Xu 3c551a9dfc ♻️ refactor(verify): unify acceptance criterion UI and remove lobe-delivery-checker (#18376)
* ♻️ refactor(verify): unify acceptance criterion UI and remove lobe-delivery-checker

- Add shared CriterionList / CriterionRow / CriterionRequiredChip and a single
  CriterionEditor + openCriterionEditModal under src/features/Verify/CriterionList
- Migrate the /goal intervention card, CreateGoalModal, TaskVerifyConfig,
  PendingAcceptanceCheckList, TaskAcceptance and GoalDetailPage to the shared
  row/editor, deleting the two duplicated criterion edit modals
- Unify the required chip to a blue info tag labelled 必选 (verify:criterion.*)
  and drop the divergent 必要/必需/必选 key trio across chat/plugin namespaces
- Delete the unused builtin-tool-lobe-delivery-checker package with its server
  runtime, registry entries, i18n keys and the orphaned createPlanFromCriteria

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* 📝 docs(acceptance): note stale-cache fingerprint of a cross-wired browser session

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ♻️ refactor(verify): apply acceptance review feedback on criterion editing

- Drop the pending-status icon and C{seq} anchor from goal-creation draft
  rows — those belong to the post-creation check list, not authoring
- Remove TaskVerifyConfig's edit mode (SortableList reorder, side drawer,
  Done button): every row now edits itself through the shared criterion
  modal, matching the goal-creation interaction; regenerate moves into the
  header overflow and add/save-as-template become always-visible footer
  actions
- Simplify the criterion edit modal title — no C{seq} interpolation

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* 📝 docs(acceptance): record ingest-side identifier/internal-id gap in probe patterns

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ♻️ refactor(verify): apply round-2 acceptance review feedback

- Keep the C{seq} anchor on goal-creation draft rows; only the pending
  status circle stays out of authoring
- Drop the at-rest delete button from task criterion rows — removal lives
  inside the editor modal
- Move save-as-template from the footer into the header overflow menu
- Show the verifier tag and required chip on goal-detail check rows

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ♻️ refactor(verify): fold task criterion row edit and delete into a per-row overflow

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 17:01:04 +08:00
Rdmclin2 26dc379af9 🐛 fix(agent-group): keep group membership lifecycle intact on transfer & delete (#18126)
* 🐛 fix(agent-group): keep group membership lifecycle intact on transfer & delete

A chat group's roster mixes two kinds of member: agents the group itself
built (its synthetic supervisor, plus members made in the group builder)
and standalone agents merely linked in. Only `duplicateGroup` knew the
difference; delete, roster removal, group transfer and agent transfer
each acted on every member alike, which cost:

- deleting a group stranded its own supervisor/members forever (`agents`
  has no FK to `chat_groups`, and `virtual: true` hides them from every
  list), and the cleanup ran outside the delete's transaction
- transferring an agent silently tore it out of every group, and for a
  supervisor left the group headless — the next read minted a blank
  replacement and the configured systemRole/model were gone
- transferring a group dragged referenced members into another scope,
  and evicted them from every OTHER group they belonged to

Put the judgement in one place (`resolveGroupMembershipType`) and have
all four paths read it. A group transfer now leaves referenced members
where they are and takes a clone instead, remapping the group's own
topics/threads/messages onto it — `agent_id` is ON DELETE CASCADE, so a
stale pointer would have taken the moved history with it. The async
backfill applies the same remap on the same rows it rewrites.

Also surfaced up front rather than after the fact: two read endpoints
(`agent.getGroupMembershipImpact`, `group.listReferencedMembers`) so the
UI can say what a move will do, and `role` is now a closed enum instead
of free text.

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

* 🐛 fix(test): use a role the closed set actually contains

`moderator` predates `GROUP_MEMBER_ROLES` and is not a member of it, so
these two cases stopped type-checking once `role` became an enum.
`assistant` is the valid non-default role, so they still prove a
non-default role round-trips rather than just re-asserting the default.

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

* 🐛 fix(agent-group): gate referenced-member details on member visibility

`listReferencedMembers` scoped only on the GROUP, so a caller who could
see the group could read the title and avatar of a member whose owner
had since flipped it back to `private` — a member the roster itself
hides from them (`memberAgentVisibility`). The pre-transfer warning
would have been the one surface that handed it out.

Apply `agentOwnership()` as well, the same predicate
`checkAgentsBeforeRemoval` and the roster reads use. A hidden member is
now under-reported rather than exposed, which is the right direction:
it is invisible to this caller everywhere else too.

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

* 🐛 fix(agent-group): guard left-behind members for the drain's duration

A slow-path group transfer registers the target-scope roster — members
that travelled plus the clones — as the job's covered agents. The
referenced members it left behind are not covered, and deliberately so:
that junction is what the migration badge reads, and an agent that never
moved should not advertise a migration.

But being uncovered also left them unguarded. Until the drain reaches a
topic, that topic's rows still carry `messages.agent_id = sourceAgentId`,
and the column is ON DELETE CASCADE — so the owner deleting their own
agent mid-drain silently took the moved group history with it, the very
rows the remap was about to rescue.

Guard the delete without touching the badge:
`hasPendingRemapForSourceAgents` reads `payload.agentIdRemap` of pending
transfer jobs, and `AgentModel.delete` now refuses on it.

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

* 🐛 fix(agent-group): refuse to clone a member the caller cannot see

A group transfer leaves referenced members behind and clones them into
the target scope — title, systemRole, model, params and plugins — via
`buildCopiedAgent`. When a member's owner had since flipped it back to
`private`, that clone handed the caller a full copy of an agent the
roster hides from them (`memberAgentVisibility`), and which
`listReferencedMembers` had just been fixed to withhold. Moving the
group was the way around both.

Pre-existing rather than new — the old path MOVED that agent into the
target scope outright, which is strictly worse — and only narrowed, not
closed, by the owner-only guard: `buildWorkspaceWhere` constrains
private rows to their author, so a workspace owner cannot see such a
member either.

Refuse, rather than clone a redacted shell (a member answering with a
blank systemRole is a silent behavior change) or drop the member
(leaving moved history pointed at an agent in the source scope, which
`messages.agent_id`'s cascade turns back into data loss). The error
names nobody: which member is hidden is the part being withheld.

`copyToWorkspace` duplicates members the same way and gets the same
guard. `duplicate` needs none — it re-links referenced members instead
of copying them, so no config crosses a scope.

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

* 🔒 fix(agent-group): check member visibility on locked rows, not a snapshot

Both guards ran against a read taken before the row lock, so an owner
committing `visibility = 'private'` in between was checked as public and
then cloned anyway — from that same stale snapshot. A narrow window, but
it defeated the guard entirely when it hit.

- transfer: the check moves BELOW the existing `FOR UPDATE` on the member
  agents, and the clone now reads the locked row rather than `memberRows`
- copy: the check moves INSIDE the transaction and takes its own
  `FOR UPDATE` on the referenced members first, since it had no lock at
  all on them

Once those rows are locked, a concurrent visibility update blocks until
this transaction ends, so what is checked is what gets cloned.

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

* 🔒 fix(agent-group): enforce single-group ownership, withhold hidden group ids

Two guards that were resting on something weaker than they looked.

`addAgentsToGroup` validated visibility but never rejected a `virtual`
agent, so the "an owned member belongs to exactly one group" invariant
that `resolveGroupMembershipType` leans on was enforced by the member
picker's query rather than by the write. Sending a known group-built
member or supervisor id would link it to a second group — and then
deleting either group deletes an agent the other still uses. Reject it
at the write.

`getGroupMembershipImpact` set `groupVisible: false` for a group the
caller cannot see, and withheld its title and avatar, but still returned
its id — so the preflight disclosed the existence and identifier of
another member's private group. Withhold the id with the rest. Done
where the refs are built, so the transfer error's `groups` payload stops
carrying them too.

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

* 🐛 fix(agent-group): the invariant is one group, not zero

The previous commit rejected every `virtual` agent at `addAgentsToGroup`,
which breaks the group agent builder: it creates `virtual: true` and adds
it through exactly this path, as that agent's first and only membership.

Reject only a virtual agent already on ANOTHER group's roster — which is
the actual invariant `resolveGroupMembershipType` needs, and the only
case where deleting one group would destroy an agent another still
lists.

Adds the test that should have caught it.

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

* 🔒 fix(agent-group): keep copy and transfer taking locks in the same order

My own TOCTOU fix put the referenced-member `FOR UPDATE` at the top of
`copyToWorkspace`'s transaction — ahead of the source-group lock. That
inverted the order `transferToWorkspace` uses (group, then member
agents), so a concurrent copy and transfer of the same group could each
hold what the other wanted and deadlock, instead of meeting the
pending-job guards that exist to serialize them.

Move the agent lock below the group lock. Same protection, one order.

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

* 🔒 fix(agent-group): keep builtin agents off group rosters

Builtins (Inbox, the agent builders) are provisioned per user and carry
`virtual: true`, exactly like a group's own members — so the membership
rules classify one as group-OWNED the moment it lands on a roster. And
`removeAgentsFromGroup` deletes owned members with no reserved-slug
protection, unlike the group-delete path. Adding your Inbox to a group
and then leaving the group deleted the Inbox.

Narrowing the previous virtual-agent rejection to "already in another
group" is what let a builtin through the door, since a builtin normally
sits on no roster at all.

Two layers, matching how `ChatGroupModel.delete` already handles this:
- `addAgentsToGroup` refuses a reserved builtin slug outright
- the removal delete gains the same reserved-slug backstop, for a row
  that reached the roster some other way

Both regression tests verified failing first: without the backstop the
Inbox row is gone; without the door check the add resolves.

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

* 🔒 fix(agent-group): a builtin is never a group-owned member

The previous commit closed the two paths that DELETE an owned member.
It left the one that rehomes them: `transferToWorkspace` rewrites
`userId`/`workspaceId` for every owned member, so a builtin on a roster
would have someone's Inbox moved into another scope.

Rather than a third call-site backstop, put the carve-out in the shared
judgement — which is what this whole change is about. A reserved builtin
slug now resolves to `referenced` ahead of every other rule, including
`supervisor`, in both the TS resolver and its SQL twin. Every owned path
inherits it: delete, roster removal, group transfer, agent transfer.

Call sites that partition a roster now pass `slug`.

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

* 🔨 chore(agent-group): drop the now-unused `not` import

Left over from the roster-eviction delete this branch removed.

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

* 🐛 fix(agent-group): classify referenced members with the same inputs everywhere

`listReferencedMembers` fed `resolveGroupMembershipType` a row without
`slug`, so a builtin on a roster read as merely `virtual` — owned — and
dropped out of the warning. The transfer path does pass `slug`, treats
the same row as referenced, and clones it. The warning therefore omitted
the one row the move was about to act on.

Carry `slug` here too. The shared judgement only helps if every caller
hands it the same facts.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 22:19:41 -07:00
Rdmclin2 e08bf97fbb ✨ feat: support agent copy (#18030)
Extends the async agent-history-job pipeline to duplicate an agent's chat
history: per-topic backfill, the same progressive gray-out UX as transfer,
and guards so a source agent cannot be transferred or deleted out from
under a pending copy.

Copies carry `metadata.copied` and keep their own token/cost figures —
consumption reports filter on the marker, while display and context-window
math keep reading the numbers.

The `payload` column this builds on ships separately in #18043.
2026-08-07 21:27:59 -07:00
Rdmclin2 af2e77b551 🐛 fix: workspace common issues & account deletion blocker locales (#17992)
* 🐛 fix: workspace common issues & account deletion workspace blocker locales

* 🐛 fix: resolve API docs link against active server origin on desktop

* ✅ test: raise copy regression above the 65,535 bind-parameter cap

* 🐛 fix: preserve copied updatedAt in cross-batch FK fixup updates

* 🐛 fix: narrow workspace id type in workspaceUserSettings procedure ctx

* 🐛 fix: route legacy chat-group sidebar assignments through ChatGroupModel

* 🐛 fix: gate legacy chat-group sidebar moves behind resource edit access

* 🐛 fix: honor chat-group edit locks in legacy sidebar move compat

* ✅ test: cover legacy chat-group sidebar moves (routing, edit gate, lock)
2026-08-06 22:48:45 -07:00
YuTengjing 84335703c3 🌐 style: i18n LobeHub scoped model descriptions (#17900) 2026-08-04 17:14:53 +08:00
Rdmclin2 c19240488a ✨ feat: support proactive messenger push and notification channel settings (#17791)
✨ feat: support proactive IM notifications
2026-08-03 11:29:41 -07:00
YuTengjing 6dfe6e485f ✨ feat: support Claude Opus 5 (#17582)
* ✨ feat: support Claude Opus 5

* 🔨 chore: sync online model locales

* 🐛 fix: respect disabled Bedrock thinking

* 🐛 fix: preserve disabled Bedrock thinking

* 🐛 fix: hide internal server error details
2026-07-25 02:22:33 +08:00
Rdmclin2 925ef8365c 🐛 fix: resource permission controls, chat-input hints & wechat push (#17468)
* 🐛 fix: resource/agent permission controls, use-only hints and wechat push improvements

* 🐛 fix: gate use-only notice on resolved access, not just !isAccessLoading

* ✅ test: align tests with model-profile exposure and post-rebase types

- update redaction tests: model identity is now part of the safe profile
  surface (use-only members see/switch the model in chat)
- complete upstream partial mocks broken by new hook/selector usages
- add missing acceptance.workspace.filters.empty.all locale key (type break
  from d1c8d3026c on canary)
- fix modelSelection policy test arg to match narrowed signature

* 🐛 fix: keep type-only hetero summary in redacted agent config

Use/view-only workspace members lost agencyConfig.heterogeneousProvider to
redaction, so the client rendered external-CLI agents (Claude Code / Codex)
as plain runtime agents with the LobeHub model selector and composer. Keep a
type-only heterogeneousProvider summary in the safe agency fields; args, env
and device bindings stay behind edit-level access.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ✅ test: fix ms-race flake in home agent list selector fixture

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 23:30:34 +08:00
YuTengjing 1afa265b3e 💄 style: update i18n (#17277)
* 💄 style: update i18n

* ✅ test: drop stale provider footer assertions left by footer removal
2026-07-17 02:15:18 +08:00
Arvin Xu 3d72010018 ✨ feat(home): replace the daily brief with a triaged home inbox (#17194)
* ✨ feat(home): replace the daily brief with a triaged home inbox

The home brief rendered every unresolved brief as one flat list of tall cards,
so a stuck decision and a week-old insight competed for the same space. Split
the feed by whether the user has to *do* something:

- Needs you — briefs blocking an agent (decide / review / fix), plus topics
  that finished while the user was away. Errors sink to the bottom: a stuck
  decision blocks work right now, a failed run has already stopped.
- Running — collapsed to one line; a healthy run needs nothing from you.
- Worth knowing — insight briefs, one line each.

Rows now carry the real task/topic status glyph from ExecutionStatus.ts (task
`paused` reads as "pending review", not "suspended") instead of the brief-type
icon, and the meta line names the task it belongs to. That needed the parent
task's identifier + name, so listUnresolvedEnriched selects them from the join
it already had.

Running / unread topics come from one topicService.queryTopics call. Deliberately
not HomeRepository.getUnreadCounts() — that one excludes cron/task-triggered
topics because it powers a sidebar badge, and those are exactly the ones an
agent inbox must surface.

Recommendations, DocumentPreviewModal and TopicChatDrawer used to render inside
DailyBrief; they are re-mounted in HomeInbox so artifact preview and "view run"
keep working.

* ✨ feat(home): make the inbox unread runs readable and actionable

Rework the home inbox unread section so a finished run is legible and
replyable without leaving the page, plus supporting cleanups.

- Surface each topic's last assistant reply: `queryTopics` gains an opt-in
  `withLastMessage` correlated subquery (last non-empty assistant message,
  truncated to 2000 chars with a trailing ellipsis).
- Unread section is now an expandable list in the news-list idiom: one row
  per run (ripple unread dot, agent avatar, title, time, chevron); opening a
  row reads it and drops the full reply inline. The expanded footer offers
  "view chat" (left, opens the topic drawer) and a filled "follow up" (right)
  that swaps in an inline reply editor and sends straight to the topic over the
  gateway — no drawer, no navigation.
- Client agent runs now persist `topics.status = 'running'` at run start, like
  the gateway/hetero transports already did, so a client-driven run shows up in
  the home inbox running card and the Fleet board instead of being invisible
  off the active conversation.
- Extract shared `UnreadDot` (ripple) and `CollapsibleContent` components,
  replacing the copy-pasted sidebar ripple dots and the bespoke task-run
  collapse; the collapse fade now scales with the clamp height.
- Running card shows a deduped stack of the busy agents' avatars.
- Section headings carry a count and each names itself (no nested headings,
  no single-section title suppression, no leading icon).
- InboxBriefCard: drop the empty meta row for a brief with no parent task and
  move its timestamp onto the title line.
- Loading state drops the fabricated "Needs you" group heading (bare skeletons
  + recommendations), and a topic-feed fetch failure now surfaces an inline
  error with retry instead of silently dropping the unread / running sections.
- Rename the insight section to "Daily brief" with a count and subtitle, and
  make it an expandable list: agent avatar leads each row, clicking reads it in
  place (title + avatar dim) and expands the finding's detail inline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:00:52 +08:00
Rdmclin2 6add26c6bc ✨ feat: add workspace RBAC control and resources management (#17172)
* ✨ feat: add workspace RBAC control and resources management

* 🐛 fix: gate connector syncTools and recursive document deletes; type-safe workspaceRole access

* 🐛 fix: preserve teammate files in narrowed KB clear-all; keep shared-agent rename collaborative

* 🐛 fix: read-only connector bootstrap for non-creators, KB delete file scoping, api_key:read gate

* 🐛 fix: gate connector getForEdit credential read behind creator/owner check

* 🐛 fix: caller-scoped workspace clear-all for all roles; surface API key tab to members

* 🐛 fix: creator-only verify run lazy creation; adapt tests to RBAC error semantics

* 🐛 fix: viewer read-only connector bootstrap; keep shared topic co-edit ungated

* 🐛 fix: hide workspace API key tab from viewers via useIsWorkspaceViewer slot

* 🐛 fix: keep shared-topic metadata co-editable

* 🐛 fix: workspace-scoped provider vault merge for co-owners; gate custom connector sync in UI

* 🐛 fix: gate skill re-import overwrites and KB file membership behind creator/owner

* 🐛 fix: block non-owner transfers that rehome teammates' rows across all cascade paths

* 🐛 fix: include linked sessions in agent transfer foreign-row guard

* 🐛 fix: gate agent connector bind/copy/mount/unbind/unmount behind creator-owner check

* 🐛 fix: gate generateDraftPlan behind verify-run owner check

* 🐛 fix: role-aware skill importer for write chain; revalidate resources after select-all delete

* 🐛 fix: resolve viewer writability without injected role; creator-scoped notebook folder deletes

* 🐛 fix: member-gate connector getForEdit credential read

* 🐛 fix: block non-owner agent/group deletes that cascade teammates' conversations
2026-07-14 20:44:35 +08:00
YuTengjing f7a0ecfbd3 🌐 chore(i18n): fill missing locale translations (#17041) 2026-07-11 19:51:12 +08:00
Rdmclin2 3395fb713f ✨ feat: support device share and optimize workspace (#16901)
Squash of:
- feat: support device share and optimize workspace
- 🐛 fix: grandfather legacy device ids in workspace device binding guard
- 🐛 fix: coerce workspace agents away from member-local execution

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 13:19:29 +08:00
Rdmclin2 0e6d1a759d ✨ feat: support workspace private resources with transfer and copyTo (#16729)
* feat: support workspace private resources with transfer and copyTo

Squashed 3 commits:
- feat: support workspace private resources with transfer and copyTo
- fix: test case and lint error
- fix: file download

* chore: update i18n files

* fix: test case
2026-07-05 12:31:21 +08:00
Rdmclin2 261c7652e5 🐛 fix: workspace problems (#16683)
* fix: workspace optimize

* feat: init market org profile on community

* chore: remove workspace profile

* chore: update community 成员页

* fix: commnity memeber table

* feat: support reserve onboarding

* chore: update i18n files

* feat: workspace ai model and divider scope

* chore: replace  workspace_memeber.role with rbac_user_roles

* fix: workspace ai provider lost

* chore: update i18n files

* fix: codex preview
2026-07-03 23:10:22 +08:00
Rdmclin2 335e4f5fbd feat: workspace private agents, viewer limit, onboarding (#16604)
* feat: workspace private agents, viewer limit, onboarding (squashed)

* fix: test case and private document

* fix: workspace private resource test case

* fix: test case

* chore: complement test case
2026-07-02 14:30:33 +08:00
Rdmclin2 ed10e2a8a5 ✨ feat: workspace member budget and audit log (#16530)
* feat: support workspace audit log and member budget control (squashed)

* 🐛 fix(business): add WorkspaceAuditLog open-source stub

The audit-log settings route imports `@/business/client/BusinessSettingPages/WorkspaceAuditLog`
but the open-source slot was missing, breaking the standalone build.

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

* fix: i18n keys

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-01 04:13:36 +08:00
YuTengjing 3b9f67f384 ✨ feat(chat): show model display name in message footer (#16421)
- Render `displayName` (fallback to `id`) for the model label below assistant messages
- Update GLM-5.2 Fast description copy
2026-06-29 14:50:52 +08:00
Rdmclin2 3498537aae feat: workspace device member access (#16333)
* chore: adjust workspace limit copy

* fix: device enroll memebership

* feat: support device manage

* fix: navigation route

* chore: optimize device list

* feat: add workspace auth

* fix: workspace device role auth

* feat: support inactive workspace lock

* feat: support workspace unsubscription cancelled

* chore: solo to free plan

* chore: update downgrade i18n files

* fix: billing issue

* chore: update i18n files
2026-06-27 01:33:33 +08:00
Rdmclin2 a50b6a83e7 ✨ feat: workspace billing system (squashed) (#16308)
* feat: workspace billing system (squashed)

* fix: lint error
2026-06-26 11:42:32 +08:00
Rdmclin2 60bed5782f chore: update i18n (#15712)
chore: update i18n files
2026-06-12 16:21:34 +08:00
Rdmclin2 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.
2026-06-12 16:08:31 +08:00
YuTengjing 7641cda958 💄 style: update i18n locales (#15630) 2026-06-10 14:02:02 +08:00
YuTengjing f042dd352e ✨ feat: support Claude Opus 4.8 (#15314) 2026-05-29 02:19:05 +08:00
Rdmclin2 0195f42daa 🐛 fix: onboarding im integration (#14988)
* feat: support onboarding messager

* chore: remove telegram CN screenshots

* feat: add feedback commands

* fix: bot feedback commands

* chore: optimize messenger intergration

* chore: update onboarding style

* feat: support wechat adapter attachments

* feat: support ai attachments

* chore: update i18n files

* fix: bot message image attachment
2026-05-19 22:51:38 +07:00
YuTengjing fd0d208152 💄 style(subscription): update budget recovery copy (#14875) 2026-05-19 11:44:27 +08:00
Rdmclin2 566b261a12 ✨ feat: support bot watch (#14796)
* feat: add whatsAPP and iMessage comming soon

* chore: update i18n

* feat: support watch keyword instruction

* feat: add cli and messager api for bot channels

* fix: test cases

* feat: add system prompt for messenger tool

* feat: add messenger mdx
2026-05-15 00:36:40 +07:00
Rdmclin2 6933ddc4e5 🔨 chore: Online Messager (#14755)
* feat: add line integration Banner

* chore: remove messenger lab switch

* feat: add messenger banner

* feat: add messenger promo

* chore: update i18n files
2026-05-13 14:17:07 +07:00
brone1323 a109d22c8d 🌐 i18n: add missing task-schedule and review strings to 16 locales (#14728)
🌐 i18n: add missing translations for task-schedule and review keys across 16 locales

Adds 14 missing i18n keys to all non-zh-CN locales (ar, bg-BG, de-DE,
es-ES, fa-IR, fr-FR, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, ru-RU,
tr-TR, vi-VN, zh-TW):

chat.json (11 keys):
- taskSchedule.summary.everyNHoursHalfPast
- taskSchedule.summary.hourlyHalfPast
- taskSchedule.timezoneSearchEmpty
- taskSchedule.timezoneSearchPlaceholder
- workingPanel.review.revert (and 7 sub-keys)

plugin.json (1 key):
- builtins.lobe-task.apiName.setTaskSchedule

setting.json (2 keys):
- serviceModel.modelAssignments.title
- serviceModel.optionalFeatures.title

These were added in recent commits but the automated i18n sync had not
yet propagated them to non-Chinese locales.
2026-05-12 22:13:31 +08:00
AmAzing- b5c4abcaef 🌐 i18n: update banner copy translations (#14623) 2026-05-10 10:28:50 +08:00
YuTengjing c374892fea 🐛 fix: add temporary email auth error locale (#14564) 2026-05-09 18:50:32 +08:00
Rdmclin2 e56ccf6a5c 🐛 fix: multiple account link (#14562)
* feat: avoid rebind link same account

* chore: update i18n locales

* feat: avoid discord account misslink

* feat: support slack account mis match

* fix: avoid claim conflict
2026-05-09 16:31:21 +07:00
CanisMinor 1c8ec2681c 💄 style: update brief template style (#14483)
Co-authored-by: YuTengjing <ytj2713151713@gmail.com>
2026-05-07 17:34:47 +08:00
Arvin Xu 2870cc73c2 ✨ feat(builtin-tool-task): add Inspector + Render, batch createTasks/runTasks (#14403)
* ✨ feat(builtin-tool-task): add Inspector + Render, batch createTasks/runTasks

Adds chip-style Inspector and per-API Render to the lobe-task tool, plus two
batch APIs (createTasks, runTasks) so an agent can plan or launch a set of
subtasks in a single call instead of calling createTask/runTask N times.

runTask/runTasks call taskService.run, actually triggering TaskRunnerService
and producing a topic+operationId — distinct from updateTaskStatus(running),
which only flips a flag. The system prompt now spells this out so the model
stops conflating the two. Already-running, missing-assignee, and per-item
failures surface back to the agent with clear messages.

Fixes LOBE-8438

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

* 🐛 fix(server,task): implement createTasks/runTask/runTasks in server runtime

The manifest exposes these APIs to the model, but only the client-side
executor was implemented. Server-side tool execution (src/server/services/
toolExecution/builtin.ts) throws "Builtin tool ... is not implemented" when
the runtime is missing a method, so production paths that route through the
server runtime would fail at runtime.

- Extracted createTaskImpl as a reusable closure so createTasks loops can
  reuse the parent-resolution + assignee-validation flow without copy-paste
- runTask / runTasks call taskCaller.run(...) which already routes to
  TaskRunnerService — same execution path as the UI/CLI run buttons
- runTasks continues past per-item failures and reports them in the summary
  (matching the client executor's behavior)
- Added 7 tests (20 total in this file) covering happy path, per-item
  failure, missing identifier, and current-task fallback

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

* 🐛 fix(task-drawer): hide topic feedback input until run terminates

Feedback can only steer the next run, so showing the input while the
topic is pending/running was misleading — gate it on terminal status
(completed/failed/canceled/timeout).

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 01:15:41 +08:00
Arvin Xu d5097c7964 💄 fix(builtin-tool-agent-documents): wire Inspectors into registry, switch to chip UI (#14404)
* 💄 fix(builtin-tool-agent-documents): wire Inspectors into registry, switch to chip UI

The Inspector components for lobe-agent-documents existed but were never
registered in packages/builtin-tools/src/inspectors.ts, so the chat UI fell
back to the default "(id:316c6ad5-10e7-46ff-8ccf-15f2359c19...)" header
that shows raw param dumps. Registering them is the root fix.

While in there, refactored all 9 inspectors to the chip pattern used by the
other builtin tools — full UUIDs are noisy in a one-line header, so document
ids are truncated to their first 8 chars (prefixed ids like agd_… are left
intact since they're already short). Each inspector now surfaces the most
useful per-API context: title chip when known (Read/Create), id chip + new
title (Rename/Copy), op count + success ratio (Modify), char count
(Replace), target scope + doc count (List), rule type (UpdateLoadRule),
red dashed line-through (Remove). Shared chip styles live in one
_styles.ts so the visual language stays consistent.

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

* 📝 docs(.agents/skills): add builtin-tool skill

Self-contained reference for building/extending lobe-* builtin tools —
SKILL.md entry point plus architecture / tool-design / ui deep-dives.
Sits alongside the other agent skills.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 00:56:06 +08:00
LobeHub Bot b49c1c15b7 🤖 style: update i18n (#14383)
💄 style: update i18n

Co-authored-by: canisminor1990 <17870709+canisminor1990@users.noreply.github.com>
2026-05-03 01:07:03 +08:00
Rdmclin2 346812ab88 🔨 chore: update i18n files & fix title skeleton (#14301)
* chore: update i18n files & fix title skeleton

* chore: update taskTemplate json

* chore: update i18n files
2026-04-29 13:23:26 +07:00
Tsuki 70e7e441b2 🔨 chore: premerge Task detail page UI (#13653)
* ✨ feat: add AgentTaskList component on agent welcome page (LOBE-6597)

- AgentTaskList with TaskListHeader, TaskItem, and styles
- Embedded in AgentWelcome below ToolAuthAlert
- Each task rendered as independent rounded card with status badge
- Status: green filled circle (Done), blue circle (In progress)
- Card width matches chat input (960px)
- i18n keys for taskList.title and taskList.viewAll
- Fix updateReview type to use TRPC-inferred type

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

* ✨ feat: add Tasks page at /agent/:aid/tasks with route, breadcrumb, and view toggle (LOBE-6597)

- Register tasks route in both desktopRouter.config.tsx and .desktop.tsx
- Thin route page at src/routes/(main)/agent/tasks/index.tsx
- Feature components in src/features/AgentTasks/: page, breadcrumb, header with list/kanban toggle, full task list
- Wire up "View All Tasks" navigation from AgentTaskList welcome card
- Add i18n keys (taskList.activeTasks, taskList.breadcrumb.task) and generate translations via pnpm i18n

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

* ✨ feat: add Task detail page at /agent/:aid/tasks/:taskId (LOBE-6597)

- Register :taskId child route in both desktopRouter configs
- TaskDetailPage with auto-save hint, breadcrumb, and scrollable content
- TaskDetailHeader: editable title (borderless Input), Run/Pause button, status/priority tags, delete
- TaskInstruction: click-to-edit Markdown with debounced auto-save
- TaskSubtasks: sub-issues list with status badges
- TaskActivities: timeline with topic/brief/comment icons
- TaskItem now navigates to detail page instead of just setting activeTaskId
- Add taskDetail.* i18n keys with generated translations

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

* ✨ feat: add TaskModelConfig, TaskScheduleConfig, and refine Task detail UI (LOBE-6597)

Add model/provider selector and periodic execution config to Task detail page.
Refine TaskDetailHeader, TaskInstruction with auto-save and i18n support.

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

* ✨ feat: refine Task detail UI with Linear-style design (LOBE-6597)

- Redesign SubTasks with collapsible header, progress circle, hover + click navigation
- Redesign Activities with agent avatar, comment input box, and Linear-style layout
- Add TaskParentBar showing parent task relationship with sibling navigation popover
- Add delete confirmation modal using App.useApp().modal.confirm
- Move ModelSelect to separate row below action bar
- Fix zustand selector recreation in ActivityItem
- Replace hardcoded colors with cssVar tokens

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

* ✨ feat: add Properties panel, parent link hover, activity icon, and lifecycle save status (LOBE-6597)

- Add TaskProperties sidebar with collapsible status/priority dropdowns
- Parent bar: clickable parent link with hover, sibling navigation popover on progress
- Activity title: add BotMessageSquare icon
- Fix lifecycle actions not updating taskSaveStatus (saving/saved indicator)
- Filter status dropdown to only user-selectable states (backlog/completed/canceled)
- Add test task creation script for dev

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

* ✨ feat: add recursive tree view for subtasks with Linear-style connecting lines (LOBE-6597)

- Add buildTaskTree utility to convert flat getTaskTree API response into nested tree
- Implement SubtaskTreeItem recursive component with CSS connecting lines (├─ and └─)
- Fetch full task tree via taskService.getTaskTree for nested subtask display
- Show loading spinner during tree fetch, fallback to flat list on error
- Remove padding-inline from AgentTaskList container

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

* 🐛 fix: address PR review — delete redirect, debounce cleanup, schedule resync (LOBE-6597)

- Redirect to task list after successful delete (P1)
- Clean up instruction debounce timer on unmount/task switch to prevent stale writes (P1)
- Resync TaskScheduleConfig local state when active task changes (P2)

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

* ♻️ refactor: use backend nested subtasks directly, remove buildTaskTree (LOBE-6597)

Backend now returns nested subtasks in task.detail (LOBE-6814).
Remove buildTaskTree utility, getTaskTree API call, and loading state.
Use TaskDetailSubtask from @lobechat/types instead of local interface.

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

* ⚡ perf: add optimistic update and save status for model config change (LOBE-6597)

updateTaskModelConfig now immediately reflects new model/provider in UI
via optimistic store dispatch, and tracks taskSaveStatus (saving/saved).

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

* ⚡ perf: skip redundant refreshTaskDetail on successful model config update (LOBE-6597)

Optimistic update is trusted on success — no need for full detail re-fetch.
Aligns with updateTask pattern. Refresh kept only in error path for revert.

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

* ✨ feat: use backend author info for activities, fix AgentTaskList after AgentHome refactor (LOBE-6597)

- Activity: use act.author (TaskDetailActivityAuthor) from backend instead of agentMap lookup (LOBE-7013)
- AgentTaskList: fix agentId from useParams instead of useAgentStore.activeAgentId (was undefined)
- AgentHome: integrate AgentTaskList into new AgentHome layout (replaces old AgentWelcome)

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

* ✨ feat: show participant avatars on task cards, use backend author for activities (LOBE-6597)

- TaskItem: display up to 3 participant avatars next to task title (LOBE-6805)
- Activity: use act.author from backend instead of agentMap lookup (LOBE-7013)
- AgentHome: integrate AgentTaskList into new AgentHome layout
- Revert AgentTaskList/TaskItem agentId back to useAgentStore (works correctly when mounted)

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

* ♻️ refactor: fix type safety, memoize participants filter, extract avatar styles (LOBE-6597)

- Use TaskParticipant type instead of `any` in filter/map
- Compute displayParticipants once with useMemo (was filtering twice per render)
- Move avatar overlap styles to CSS classes (was inline objects per render)

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

* 🔇 chore: hide kanban view toggle until implemented (LOBE-6597)

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

* ♻️ refactor: export TaskStatus/TaskPriority/TaskActivityType from @lobechat/types (LOBE-6597)

Replace hardcoded string/number types with shared type aliases:
- TaskStatus: 'backlog' | 'canceled' | 'completed' | 'failed' | 'paused' | 'running'
- TaskPriority: 0 | 1 | 2 | 3 | 4
- TaskActivityType: 'brief' | 'comment' | 'topic'

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

* style: update

* style: update

* style: update

* style: update

* style: update

* style: update

* style: update

* style: update

* style: update

* style: update

* ✨ feat: add Daily Brief module to homepage (#13851)

* ✨ feat: add Daily Brief module to homepage

Add a Daily Brief section below the chat input on the homepage that
displays unresolved briefs from the Agent Tasks system. Users can
resolve, comment, and provide feedback directly from the brief cards.

- Service: BriefService with listUnresolved, resolve, markRead, addComment
- Store: Independent Zustand store (src/store/brief/) with SWR data fetching
- Components: BriefCard, BriefCardActions (dynamic action buttons),
  BriefCardSummary (Markdown with expand/collapse), CommentInput (@lobehub/editor)
- Three action types: resolve (closes brief), comment (resolve with text),
  link (safe URL navigation with protocol validation)
- Fixed feedback button: adds task comment without resolving the brief
- Inline success state ("Feedback sent") with 1.5s auto-restore
- i18n: zh-CN + en-US translations
- Tests: 21 tests across service, store selectors, and components
- CLI: Register task and brief commands for local development

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

* ✨ feat: add agent avatars to Daily Brief cards

Display stacked agent avatars next to brief card titles using the
new `agents` data from Arvin's enriched listUnresolved API (#13489).

- Add AgentAvatarInfo type and agents field to BriefItem
- Render overlapping circular avatars (20px, -6px overlap)
- Use cssVar.colorBgContainer for border (dark mode compatible)
- Extract avatar style to function to avoid inline object creation

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

* ♻️ refactor: clean up Daily Brief components

- Extract duplicate success state JSX into reusable SuccessTag component
- Remove redundant comments that describe what code does
- Use DEFAULT_AVATAR from @lobechat/const instead of hardcoded emoji

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

* 🐛 fix: address PR review feedback for Daily Brief

- Use cssVar.colorBgBase instead of hardcoded #fff for primary button
  text color (dark mode contrast fix)
- Add submitting state to CommentInput to prevent duplicate submissions
  (disable buttons + show loading during async submit)

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

* 🌐 chore: generate i18n translations for Daily Brief

Run pnpm i18n to generate translations for all 18 locales.

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

* ♻️ refactor: use shared BriefType from @lobechat/types

Export BriefType union from packages/types and use it in
BRIEF_TYPE_COLOR and BRIEF_TYPE_ICON records for compile-time
key validation. Adding a new brief type now requires updating
the shared type, and TypeScript will flag missing mappings.

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

* style: update

* style: update

* style: update

---------

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

* style: update

* style: update

* style: update

* style: update

* fix: stopPropagation

* fix: i18n

* 🐛 fix: wire comment inputs to editor instance so Send actually submits

CommentInput in AgentTasks and DailyBrief used antd TextArea inside
@lobehub/editor's ChatInput while reading content via
editor.getDocument('markdown'). The TextArea was never connected to the
editor instance, so getDocument always returned empty and handleSubmit
short-circuited silently — Send appeared to do nothing (no network
request fired).

Replace the TextArea with <Editor editor={editor} type="text"
variant="chat" /> so useEditor() actually drives the editable surface.
Keep plain-text behavior via markdownOption={false} +
enablePasteMarkdown={false}, and bind Cmd/Ctrl+Enter submit via
onPressEnter.

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

* 🐛 fix: use participant.title after TaskParticipant schema rename (#13877)

PR #13877 renamed TaskParticipant.name → .title and added
.backgroundColor. Our branch's UI code (AgentAvatars, listViewOptions,
TaskList group header, Breadcrumb) was already written against the new
schema, but TaskProperties still read firstParticipant?.name — update
the last remaining call site so the type matches post-rebase.

backgroundColor is already plumbed through everywhere it applies within
#13877's scope; TaskActivities' TaskDetailActivityAuthor is a separate
type untouched by the PR and kept as-is.

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

* 🐛 fix: resolve type-check errors exposed after canary rebase

canary upgraded react-i18next to a version with typed i18n keys and
tightened @lobehub/editor's SendButton + IEditor APIs. Rebase pulled
these in, surfacing latent type errors in LOBE-6597 code.

- CommentInput: use editor.cleanDocument() (IEditor's actual API;
  clearContent never existed).
- TaskActivities / TaskLatestActivity / TaskTriggerTag: type t as
  TFunction<'chat'> so typed i18n accepts the known-literal keys used
  inside module-level helpers.
- TaskPriorityTag / TaskStatusTag / listViewOptions: add
  defaultValue: '' to dynamic-key t() calls (template literals and
  Record lookups) to match the broad-key i18n overload.
- BriefCardActions: swap unusable <SendButton> (no children, no
  iconPlacement) for <Button>; add defaultValue to the dynamic
  brief-action key lookup; drop stale @ts-ignore.
- DailyBrief/CommentInput: drop unsupported children on SendButton;
  keep label via title attribute.
- Recents/Item: type TYPE_ICON_MAP as Partial<Record<...>> so 'task'
  (rendered via TaskStatusIcon elsewhere) is a safe absent key.
- brief/slices/list/action: cast briefService.listUnresolved() result
  back to BriefItem[] (TRPC serialization widens BriefType to string).
- AgentTasks/TasksHeader: delete dead file — no importers and its
  ./style module was removed by an earlier refactor.

Also ran pnpm install to materialize the newly-extracted
@lobechat/agent-gateway-client workspace package (canary #13866),
clearing ~7 "cannot find module" errors.

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

* ♻️ refactor(builtin-tool-task): polish task tool paths (#13869)

* ✨ feat: navigate to task detail when clicking brief card header

Clicking the header row of a Daily Brief card (icon + title + time +
agent avatars) now jumps straight to the associated task, using the
brief's task-tree agent (with activeAgent / inbox as fallback).

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

* ✨ feat: show parent task ids as clickable breadcrumb trail

Walk the cached parent chain from taskDetailMap and insert each ancestor's
identifier as a link between the "任务" entry and the current task name in
the task detail breadcrumb.

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

* ✨ feat: add cross-agent /tasks page with View All Tasks on Daily Brief

- Register `/tasks` route in desktop (web + Electron) and mobile router configs
- `useFetchTaskList` supports `allAgents` mode via options object API to fetch
  tasks without agent filter; backend already supports optional assigneeAgentId
- `Breadcrumb` accepts optional `agentId`, renders "All tasks" crumb when absent
- `AgentTaskItem` navigation uses `task.assigneeAgentId` so clicks work from
  the cross-agent page (falls back to `activeAgentId` for unassigned tasks)
- Extract `useScenarioEnabledTools` hook to share layout effect between
  `/tasks/_layout` and `/agent/:aid/tasks/_layout`

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

* ♻️ refactor: use assigneeAgentId for task avatar instead of participants array

Replace AgentAvatars (took participants[]) with AssigneeAvatar (takes agentId,
resolves meta from agent store). This correctly represents that a task is
assigned to a single agent via assigneeAgentId/detail.agentId.

- New AssigneeAvatar component reads agent meta from agent store by ID
- TaskProperties reads activeTaskAgentId from task detail store
- listViewOptions uses task.assigneeAgentId directly for groupBy/sort
- Extract shared isInboxAgentId helper to eliminate 4x inline duplication
- Group headers resolve agent title at render time via AssigneeLabel component

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

* 🐛 fix: enable vertical scrolling on cross-agent tasks page

Add overflowY and flex to WideScreenContainer wrapper so the task list
can scroll when content exceeds viewport height.

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

* ✨ feat: add re-assign task agent with popover selector

- Add AssigneeAgentSelector component with Popover agent list
- Extract useAgentDisplayMeta hook for consistent agent name/avatar resolution
- Fix optimistic update mapping assigneeAgentId → agentId in task store
- Disable reassignment for running tasks with tooltip hint
- Integrate selector into task list and task detail property panel

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

* ✨ feat: reuse BriefCard in task detail activities & fix raw-id navigation

Render brief-type activities as full BriefCard (same as homepage) instead of
plain tree rows. Decouple BriefCardActions from useBriefStore for actions
lookup so it can be reused across pages. Fix infinite loading when navigating
to task detail via raw DB id (task_xxx) by storing detail under both the
identifier and the raw id key in taskDetailMap.

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

* ✨ feat: add TopicCard component for task detail activities

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

* ✨ feat: allow re-running completed tasks with dedicated button

Completed tasks now show a "Re-run" button (with rotate icon) instead of
hiding the action. The backend already supported this — only the frontend
selector gate needed updating.

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

* ✨ feat: add create task modal with markdown editor

Add a "+" button on the tasks list page that opens a Linear-style modal
for manually creating tasks. The modal features a title input, a markdown
editor (EditorCanvas), and a bottom toolbar with priority and assignee
selectors. Existing tag components (TaskStatusTag, TaskPriorityTag,
AssigneeAgentSelector) are extended with an `onChange` controlled mode
so they can be used in creation context where no task exists yet.

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

* 🐛 fix: suppress spurious updateTask on Task Detail page load

EditorDataMode was missing the contentChangeLockRef pattern that
DocumentIdMode already uses, causing Lexical's registerUpdateListener
to treat programmatic content hydration as a user edit and fire
onContentChange → updateTask on every page visit.

- Add contentChangeLockRef + lockIdRef staleness guard
- Extract loadContentWithLock to deduplicate lock/load/unlock logic
- Pass contentChangeLockRef to InternalEditor
- Remove unreachable dead code in loadEditorContent

Closes LOBE-7362

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

* ✨ feat: task detail comment CRUD and various UX improvements

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

* 🐛 fix: move canceled status group to the end of task list

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

* 💄 style: polish task detail layout, title, and run button

- Title switched to auto-sizing TextArea so long names wrap (like Linear)
- Reduce title font-size from 32px to 24px and tighten paddings
- Make "运行任务" button small-sized to match the denser header
- Add 120px bottom padding for end-of-content scroll breathing room
- Default EditorCanvas paddingBottom trimmed from 64 to 32

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

* 💄 style: refine task assignee, priority, and comment input

- Assignee block uses filled variant in dark mode for better contrast
- Urgent priority (level 1) renders in orange for quick scanning
- Comment input keeps SendButton slot reserved to prevent layout shift

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

* ✨ feat: task detail — inline subtasks, automation mode, chronological activity

- Inline subtask creation under a task via CreateTaskInlineEntry
  (parentTaskId/autoFocus/onCollapse/placeholder), refreshes parent on create
- Track agent-created tasks via createdByAgentId through service, router,
  types, and the builtin task executor
- Replace scheduler Segmented-only UI with an Enable switch + heartbeat/
  schedule mode; persist via automationMode on the task
- Sort detail activities oldest → newest for a natural timeline reading
- Reducer patches nested subtask entries on updateTaskDetail so in-place
  edits reflect in the parent's subtask tree

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

* 💄 style: render activate-tool chips as rounded pills

Switch inspector tool chips from monospace code tags to filled rounded
pills with ellipsis overflow, making multi-tool rows scan better in tight
headers.

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

* 🐛 fix: keep finished tool call out of loading state while siblings run

The message-level isAssistantMessageBusy flag stays true while sibling
tool calls are still running. Without guarding on this tool's own
result, a finished tool would flip back to "loading". Now a tool that
has a real result or error is never shown as calling.

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

* 💄 style: use small Segmented in schedule config popover

Keeps the automation mode switcher visually aligned with the denser
popover controls.

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

* ✨ feat: agent profile hover card on task activity author

- Extract shared AgentProfileCard + unified AgentProfilePopup (click / hover)
  with lazy agent fetch; move out of group sidebar path.
- Wire activity author avatar + name to a hover card; brighten title on hover;
  keep a small "agent" tag on the author row.
- Show inline skeletons (description + footer stats) while loading.
- Enrich subtask payload with assignee agent info for cleaner UI.

* ✨ feat: open task topic chat in side drawer

Click a topic row in the task detail activities to open a right-side drawer
showing the topic's full chat history. Messages stream in live via the existing
agent gateway pipeline (gateway events land in chatStore.dbMessagesMap keyed by
the topic context), so a running topic refreshes its drawer in real time without
a dedicated subscription.

Reuses the Conversation feature (ConversationProvider + ChatList) with an
isolated context (agentId + topicId + isolatedTopic), so the drawer never
touches the global active topic and multiple panels coexist cleanly.

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

* 💄 style: outline activate-tool chip with subtle border

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

* ✨ feat: show topic handoff summary on activity card

Pull `handoff.summary` through the task service into TaskDetailActivity and
render it under the title in TopicCard so completed topics surface what was
accomplished without opening the drawer.

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

* 🎸 chore: gate agent task feature behind agent_task flag

Hide every client-side entry point to the Agent Task feature when the
`agent_task` flag (default `isDev`, off in prod) is disabled:

- Sidebar: task tab in the agent sidebar nav
- Routes: `/agent/:aid/tasks/*` and `/tasks/*` layouts redirect to `/` when
  the flag is off (mobile router reuses the same layout)
- Home Recents: filter out `type='task'` items in both the list and the
  "all recents" drawer
- Daily Brief: skip fetch + hide the entire panel (all briefs link to tasks)

Backend TRPC / lifecycle stays on — the feature is already live for CLI
usage. Flag name mirrors `agent_onboarding` for consistency.

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

* 🐛 fix: prioritize includeTriggers in topic queries

* 🐛 fix: normalize task detail activity payloads

* ✨ feat: add Kanban board view for task list with drag-and-drop

LOBE-7493

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

* 💄 style: shorten schedule tag labels & fix time width in task cards

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

* update i18n

* 💄 style: hide task tool from user selectors

* 💄 style: hide task skill from user selectors

---------

Co-authored-by: canisminor1990 <i@canisminor.cc>
Co-authored-by: YuTengjing <ytj2713151713@gmail.com>
Co-authored-by: Arvin Xu <arvinx@foxmail.com>
2026-04-23 02:10:45 +08:00
YuTengjing c5db823a69 💄 style: add Kimi K2.6 to LobeHub-hosted card (#14006) 2026-04-21 11:40:15 +08:00
Neko 632a6383f0 ✨ feat(app): working panel, and many agent document feat (#13766) 2026-04-15 19:18:24 +08:00
Rdmclin2 5d135b3ae1 🔨 fix: layout sidebar en More (#13723)
* fix: layout sidebar en More

* chore: update i18n files
2026-04-11 00:46:53 +08:00
YuTengjing 147ff3976f ✨ feat: add Seedance 2.0 & 2.0 Fast video generation models (#13663) 2026-04-08 17:39:50 +08:00
Rdmclin2 965fc929e1 feat: add unified messaging tool for cross-platform communication (#13296)
* ✨ feat: add cross-platform message tool for AI bot channel operations

Implement a unified message tool (`lobe-message`) that provides AI with
messaging capabilities across Discord, Telegram, Slack, Google Chat,
and IRC through a single interface with platform-specific extensions.

Core APIs: sendMessage, readMessages, editMessage, deleteMessage,
searchMessages, reactToMessage, getReactions, pin/unpin management,
channel/member info, thread operations, and polls.

Architecture follows the established builtin-tool pattern:
- Package: @lobechat/builtin-tool-message (manifest, types, executor,
  ExecutionRuntime, client components)
- Registry: registered in builtin-tools (renders, inspectors,
  interventions, streamings)
- Server runtime: stub service ready for platform adapter integration

https://claude.ai/code/session_011sHc6R7V4cSYKere9RY1QM

* feat: implement platform specific message service

* chore: add wechat platform

* chore: update wechat api service

* chore: update protocol implementation

* chore: optimize  platform api test

* fix: lark domain error

* feat: support bot message cli

* chore: refactor adapter to service

* chore: optimize bot status fetch

* fix: bot status

* fix: channel nav ignore

* feat: message tool support bot manage

* feat: add lobe-message runtime

* feat: support direct message

* feat: add history limit

* chore: update const limit

* feat: optimize  server id message history limit

* chore: optimize system role & inject platform environment info

* chore: update  readMessages vibe

* fix: form body width 50%

* chore: optimize tool prompt

* chore: update i18n files

* chore: optimize read message system role and update bot message lh

* updage readMessage api rate limit

* chore: comatible for readMessages

* fix: feishu readMessage implementation error

* fix: test case

* chore: update i18n files

* fix: lint error

* chore: add timeout for conversaction case

* fix: message test case

* fix: vite gzip error

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-31 00:26:32 +08:00