♻️ refactor(topic): drop legacy session→agentId compatibility from topic queries#15378
Conversation
…c queries Topic ownership is fully migrated to `topics.agentId`, so the `agentsToSessions` lookup that mapped a legacy `sessionId` back to an agent is no longer reachable in practice. Remove it from the agent query, count, and batch-delete paths — they now match `topics.agentId` directly. - `query()`: drop the `agentsToSessions` pre-query and the `sessionId` OR branch; keep the inbox fully-orphan fallback (all owner columns null), which is unrelated to session linkage. - `count()` / `batchDeleteByAgentId()`: match `topics.agentId` only. - Remove the now-unused `agentsToSessions` import. Tests updated to assert session-only legacy topics are no longer matched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ae8f13be7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## canary #15378 +/- ##
==========================================
- Coverage 71.17% 71.16% -0.01%
==========================================
Files 3200 3200
Lines 319838 319779 -59
Branches 34962 34948 -14
==========================================
- Hits 227634 227572 -62
- Misses 92032 92035 +3
Partials 172 172
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
…ed sessionId Topic ownership is `topics.agentId`, so the topic ranking and recent-topic queries no longer need to expose or resolve a legacy `sessionId`. - `TopicModel.rank()` now selects `topics.agentId` instead of `sessionId`; `TopicRankItem.sessionId` → `agentId`. - `TopicModel.queryRecent()` stops selecting `sessionId`. - `recentTopics` TRPC procedure: drop the `agentsToSessions` batch resolve and the `after()` runtime agentId backfill — both keyed off the legacy session mapping. Agent topics now map straight through `topic.agentId`. - Topic ranking UI navigates to `SESSION_CHAT_TOPIC_URL(agentId, topicId)` (`/agent/:aid/:topicId`), falling back to the inbox agent id when a topic has no agentId, replacing the old `/agent?session=...` query-param link. Rank test asserts `agentId`; the broader `getTopics` session-resolution path is intentionally left untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lete The integration tests (topic.integration.test.ts) showed this compatibility is still load-bearing: the topic write path (createTopic / batchCreateTopics / updateTopic) persists `sessionId` with `agentId = null`, so dropping the read-side session→agentId resolution made freshly-created topics unqueryable/undeletable by agentId. Revert the read-side removal from `query()` / `count()` / `batchDeleteByAgentId()` (and their tests) until the write path is migrated to store `agentId` directly. The agent-centric `rank()` / `queryRecent()` / `recentTopics` surface changes are kept. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d paths Topic ownership is fully migrated to `topics.agentId` (old data backfilled, new app no longer depends on sessionId), so the legacy session resolution in the topic read paths is dead and can go. - `query()` / `count()` / `batchDeleteByAgentId()`: match `topics.agentId` directly; drop the `agentsToSessions` lookup + `topics.sessionId` OR branch. The inbox fully-orphan fallback (all owner columns null) is kept. - `getTopics` TRPC procedure: drop the `after()` runtime agentId backfill and the now-unused `AgentMigrationRepo` wiring / `after` import. The sessionId→ agentId reverse-resolution of the query *filter* is kept for clients that still pass a sessionId. - Update topic integration + model tests to agent-native fixtures; remove the legacy-session and runtime-migration cases that exercised the removed path. The write path (createTopic/batchCreate/updateTopic) is intentionally left unchanged per scope; no data migration is performed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ansition Restore the `after()` runtime migration in `getTopics` (and the `AgentMigrationRepo` wiring / `after` import). The read paths no longer resolve sessionId, but the backfill is still needed to migrate straggler legacy (sessionId-only) topics over the transition window; a legacy topic is backfilled on first query and becomes agentId-queryable thereafter. Restore the migration integration tests, adjusted: they assert the agentId backfill happens after the query rather than expecting legacy rows in the first (now agentId-only) response. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Restore the recentTopics session→agentId backfill removed earlier: re-select `sessionId` in `queryRecent` (internal only — not exposed in the RecentTopic response) and re-add the `batchResolveAgentIdFromSessions` resolution + the `after()` migrateAgentId backfill. Like the getTopics backfill, this keeps migrating straggler legacy (sessionId-only) topics during the transition. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Revert the migration/backfill comments to their original wording so the restored getTopics/recentTopics blocks are byte-identical to canary, and drop the extra queryRecent select comment. No logic change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t-native rank The assistant usage ranking was session-centric (SessionModel.rank joining agentsToSessions, returning a sessionId; UI linked /agent?session=...). Rework it as agent-native: - Add `AgentRankItem` type (id = agentId); remove `SessionRankItem`. - Add `AgentModel.rank`: count topics grouped by `topics.agentId`, joined to agents for avatar/title, ordered by count. Mirrors the recents filter (real agents + inbox, excluding other virtual agents). No sessions involved. - Add `agent.rankAgents` TRPC procedure + `agentService.rankAgents`; remove `session.rankSessions`, `sessionService.rankSessions`, `SessionModel.rank/_rank`. - AssistantsRank UI: navigate to `SESSION_CHAT_URL(agentId)` → `/agent/:aid`, resolving the inbox title via the store's inboxAgentId. Move the rank tests from session.test.ts to agent.test.ts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# 🚀 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
💻 变更类型 | Change Type
🔀 变更说明 | Description of Change
Topic & assistant ownership is
topics.agentId/ agents, so the legacy session→agentId compatibility in the read paths is removed and the rankings become agent-native. Runtime backfills are kept as the transition bridge.Topic read paths (
packages/database+src/server)query()/count()/batchDeleteByAgentId()— matchtopics.agentIddirectly; drop theagentsToSessionslookup +topics.sessionIdOR branch. Inbox fully-orphan fallback kept.TopicModel.rank()→ returnsagentId(TopicRankItem.sessionId→agentId); UI links/agent/:aid/:topicId.getTopics/recentTopics— keep theirafter()agentId backfill migrations (transition bridge for straggler session-only rows);queryRecentselectssessionIdonly internally for that backfill (not exposed).Assistant ranking → agent-native (NEW)
SessionModel.rank(joinedagentsToSessions, returned a sessionId) withAgentModel.rank: counts topics grouped bytopics.agentId, joined to agents, filtered to real agents + inbox (excluding other virtual agents).SessionRankItem→AgentRankItem(idis the agentId).session.rankSessions/sessionService.rankSessions→agent.rankAgents/agentService.rankAgents.AssistantsRankUI navigates to/agent/:aid(was/agent?session=...), resolving the inbox title via the store's inboxAgentId.Scope note
createTopic/batchCreate/updateTopic) intentionally unchanged; no one-off data migration (runtime backfills handle stragglers).Independent of the group-by-status work (#15366) — based on
canary.✅ 测试 | How to Test
topic.integration.test.ts— 27 passed / 1 skipped.topic.query/topic.stats/topic.deletegreen;TopicModel.rankassertsagentId; newAgentModel.ranktests inagent.test.ts(ranking, virtual-agent exclusion w/ inbox, user isolation, limit). The 3session.test.ts > queryByKeywordfailures are pre-existing (BM25 /pg_searchnot in the test DB), unrelated to this PR.type-checkclean on touched files.🤖 Generated with Claude Code