Skip to content

fix(agent): avoid global trace scans#1946

Merged
zerob13 merged 3 commits into
devfrom
codex/fix-runtime-history-trace-scan
Jul 11, 2026
Merged

fix(agent): avoid global trace scans#1946
zerob13 merged 3 commits into
devfrom
codex/fix-runtime-history-trace-scan

Conversation

@zerob13

@zerob13 zerob13 commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Runtime history and Trace diagnostics

  • make full-session and single-message runtime history reads trace-free
  • keep exact trace counts on the indexed UI pagination projection
  • add native query-plan coverage and a 0/10k/100k unrelated-trace scale benchmark
  • replace the Trace dialog request button grid with a compact selector and two-row diagnostic summary
  • document the confirmed issue, implementation decision, and benchmark results

Plugins, Remote channels, and agent availability

  • make RemoteControlPresenter the only static remote channel catalog authority and derive supportsCronDelivery from REMOTE_DELIVERY_CHANNELS
  • remove stale supportsNotifications metadata and the three renderer-owned fallback catalogs
  • add a Pinia cache for plugin items, remote descriptors, and remote status; keep the last successful snapshot on refresh failure and use optimistic enable/disable with rollback
  • replace the Plugins Hub with a localized unavailable state while an ACP agent is selected
  • remove the incomplete per-agent enabledPluginIds contract and generic plugin-scope panel while retaining DeepChat agent-scoped Skills and normal MCP policies
  • remove the low-value raw capability badge block from official plugin details
  • translate the ACP availability copy across all 20 locales and clean completed SDD plan/task artifacts while retaining current contract specs

Root cause

Runtime history

DeepChatMessagesTable.getBySession() joined a subquery that grouped the entire deepchat_message_traces table before filtering messages to the requested session. Runtime context, predicates, compaction, and Tape paths therefore paid for UI/debug metadata whose cost grew with global trace retention.

Plugins and Remote channels

The remote channel descriptor had one main-process definition and three renderer fallback copies. They had already drifted, and the unused supportsNotifications flag no longer described Cron delivery capability. On IPC failure, the fallbacks also converted a contract failure into a fake complete catalog.

enabledPluginIds exposed a per-agent plugin policy even though plugin installation, process lifecycle, and status remained global. It filtered only some plugin-owned MCP and Skill contributions, so the UI promised a scope boundary the runtime did not implement. ACP agents use an external runtime, so DeepChat plugin controls cannot affect them.

Impact

Runtime history now reads only deepchat_messages through the existing session index. UI history continues to expose accurate trace counts per paged message, while full trace payloads remain loaded only by explicit diagnostics. No schema migration, new index, preload contract, or IPC change is required.

Remote descriptors now come from main only. Renderer state is a cache of successful main-process data, not a second static catalog. Failed refreshes keep the current snapshot, and optimistic plugin/remote state changes roll back on failure. Cron delivery options use the main-derived capability flag, so Telegram, Feishu, Discord, and Weixin remain eligible while QQBot is excluded.

Concern Authority / behavior
Remote channel catalog RemoteControlPresenter.listRemoteChannels()
Cron delivery support supportsCronDelivery, derived from REMOTE_DELIVERY_CHANNELS
Catalog/detail/sidebar state shared renderer memory cache populated from main
DeepChat plugin availability global plugin enablement
DeepChat Skills and normal MCP existing per-agent allow-lists
ACP Plugins Hub unavailable state; no child controls rendered

UI structure

Before:

Plugins Hub (every selected agent)
├── Plugins / Skills / MCP
├── Catalog from main or renderer fallback copies
├── Current agent scope
│   ├── Plugins
│   ├── Skills
│   └── MCP
└── Plugin detail
    ├── Runtime
    └── Capabilities: runtime.manage / mcp.register / ...

After:

DeepChat agent / no selection
└── Plugins Hub
    ├── Plugins / Skills / MCP
    ├── Main-owned remote catalog
    ├── Cached + optimistic renderer state
    └── Plugin detail
        └── Runtime

ACP agent
└── Plugins unavailable
    └── Select a DeepChat agent

The Trace dialog now uses the existing accessible Select primitive. Its compact summary is fixed to two rows:

  • request selector, provider, and model
  • integrity status and API endpoint

Integrity warnings remain on a separate line when present.

Validation

Runtime-history validation

  • pnpm run format
  • pnpm run i18n
  • pnpm run lint
  • pnpm run typecheck:node
  • pnpm run typecheck:web
  • focused runtime/message-store tests: 214 passed, 4 native-ABI skips
  • context, compaction, and Tape tests: 108 passed, 10 unrelated native-feature skips
  • Electron-native correctness/query-plan tests: 5 passed
  • Electron-native scale benchmark: 1 passed
  • Trace dialog component tests: 13 passed
  • repository-wide main suite: 3,359 passed; 6 failures remain in untouched debug-fixture and agent-session integration tests

Plugin/Remote validation

  • pnpm run format
  • pnpm run i18n
  • pnpm run lint
  • pnpm run typecheck
  • focused main tests: 319 passed
  • focused renderer tests: 122 passed
  • focused i18n validation: 3 keys across 20 locales; every non-English value is localized
  • git diff --check

Observed warmed median getBySession() latency for a fixed 1,000-message session:

Unrelated global traces Median Ratio
0 0.287 ms 1.000x
10,000 0.300 ms 1.045x
100,000 0.275 ms 0.959x

Closes #1945

Summary by CodeRabbit

  • New Features

    • Plugins Hub now displays a clear unavailable state when an ACP agent is selected and restores normally for DeepChat agents.
    • Agent-specific Skills and MCP enablement is supported while plugin availability remains global.
    • Plugin and remote-channel settings now update more smoothly and preserve existing data when refreshes fail.
    • Remote channels now expose cron-delivery support information.
    • Trace diagnostics use a compact request selector.
  • Bug Fixes

    • Runtime message history loads without scanning unrelated trace data, improving performance for larger histories.
  • Documentation

    • Updated architecture and feature specifications to reflect agent-scoped Skills/MCP behavior and ACP plugin boundaries.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 48dd42bd-8679-4372-b502-064bfc664711

📥 Commits

Reviewing files that changed from the base of the PR and between 092ea13 and e8569ea.

📒 Files selected for processing (24)
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/pages/plugins/OfficialPluginDetailPage.vue
  • src/types/i18n.d.ts
  • test/renderer/components/OfficialPluginDetailPage.test.ts
  • test/renderer/components/PluginsCatalogPage.test.ts
✅ Files skipped from review due to trivial changes (1)
  • src/renderer/src/i18n/ko-KR/settings.json
🚧 Files skipped from review as they are similar to previous changes (20)
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • test/renderer/components/OfficialPluginDetailPage.test.ts
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/da-DK/settings.json
  • src/types/i18n.d.ts
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
  • test/renderer/components/PluginsCatalogPage.test.ts
  • src/renderer/src/pages/plugins/OfficialPluginDetailPage.vue

📝 Walkthrough

Walkthrough

The PR revises agent extension policies to use skills and MCP servers instead of per-agent plugin IDs, adds ACP-specific Plugins Hub availability behavior, centralizes plugin and remote state, removes trace aggregation from runtime history reads, and updates related contracts, UI, localization, and tests.

Changes

Agent extension and runtime behavior

Layer / File(s) Summary
Architecture and contracts
docs/architecture/..., docs/features/plugins-hub/..., src/shared/contracts/..., src/shared/types/...
Specifications and public contracts remove agent-level plugin enablement, define Skills/MCP policy semantics, document ACP availability, and update remote-channel descriptors.
Runtime skill and MCP policy
src/main/presenter/agentRuntimePresenter/..., src/main/presenter/mcpPresenter/..., src/main/presenter/toolPresenter/...
Runtime and tool flows pass enabled skill names and MCP server IDs; plugin-owned skills and MCP servers are no longer filtered by agent plugin-ID policy.
Trace-free runtime history
src/main/presenter/sqlitePresenter/tables/deepchatMessages.ts, test/main/presenter/sqlitePresenter/..., test/main/performance/...
Session and single-message runtime reads stop aggregating trace counts, while paged projections retain counts and query-plan/scale tests validate the separation.
Plugin catalog and remote UI state
src/renderer/src/stores/pluginCatalog.ts, src/renderer/src/pages/plugins/..., src/renderer/src/components/WindowSideBar.vue, src/renderer/settings/components/...
A shared Pinia store manages plugin and remote state, optimistic mutations guard against stale refreshes, and remote-channel metadata drives catalog, sidebar, settings, and cron-delivery views.
ACP availability and diagnostic UI
src/renderer/src/pages/plugins/PluginsHubPage.vue, src/renderer/src/components/trace/TraceDialog.vue, src/renderer/src/i18n/..., src/types/i18n.d.ts
ACP selection replaces the Plugins Hub routes with an unavailable state, locale keys are updated, and trace request history uses a compact selector.
Behavior validation
test/main/..., test/renderer/..., test/e2e/...
Tests cover updated policy inheritance, plugin-owned tool access, remote descriptor capabilities, optimistic catalog behavior, ACP route restoration, trace-free history, and component state preservation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AgentStore
  participant PluginsHubPage
  participant PluginCatalogStore
  participant PluginClient
  AgentStore->>PluginsHubPage: selected agent changes
  PluginsHubPage->>PluginsHubPage: determine ACP availability
  PluginsHubPage->>PluginCatalogStore: use shared catalog state
  PluginCatalogStore->>PluginClient: load plugins and remote status
  PluginClient-->>PluginCatalogStore: catalog and status snapshot
  PluginCatalogStore-->>PluginsHubPage: current plugin and remote state
Loading

Possibly related PRs

  • ThinkInAIXYZ/deepchat#1853: Continues the agent-scoped extensions work and overlaps on replacing plugin-ID policy plumbing with Skills/MCP policy.
  • ThinkInAIXYZ/deepchat#1613: Overlaps on isolating plugin-owned MCP servers from normal MCP settings and selection flows.
  • ThinkInAIXYZ/deepchat#1908: Overlaps directly on forwarding skill and plugin policy values through agent runtime tool calls.

Suggested reviewers: deepinfect

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also includes extensive plugins/ACP, remote-channel, i18n, and UI/store changes unrelated to #1945. Split the runtime-trace fix from the plugins/ACP/remote-channel work into separate PRs, keeping this one limited to #1945.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main fix: avoiding global trace scans in runtime history reads.
Linked Issues check ✅ Passed The runtime-history changes match #1945: getBySession is trace-free, trace counts remain in paged reads, and regression/scale tests were added.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-runtime-history-trace-scan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zerob13 zerob13 marked this pull request as ready for review July 11, 2026 13:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/renderer/components/PluginsCatalogPage.test.ts (1)

188-201: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the console.warn call, not just its suppression.

The spy is created and restored but never asserted against, so this test doesn't verify that a warning is actually logged on IPC failure — only that the catalog is retained. Compare with the equivalent test in WindowSideBar.test.ts (lines 1893-1896), which asserts warn was called with a specific message.

✏️ Suggested addition
     expect(wrapper.findAll('article')).toHaveLength(2)
+    expect(warn).toHaveBeenCalled()
     warn.mockRestore()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/renderer/components/PluginsCatalogPage.test.ts` around lines 188 - 201,
Update the test case “keeps the current remote catalog when the IPC refresh
fails” to assert that the console.warn spy is called with the expected IPC
refresh failure message after loadCatalog rejects. Keep the existing
catalog-retention assertions and cleanup unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/renderer/src/pages/plugins/OfficialPluginDetailPage.vue`:
- Around line 185-188: Update the runtime details row in
OfficialPluginDetailPage so its <dt> uses a dedicated translation label for the
runtime state/status instead of settings.plugins.runtime. Keep the section
header unchanged and add or reuse the appropriate settings.plugins state/status
translation key.

---

Nitpick comments:
In `@test/renderer/components/PluginsCatalogPage.test.ts`:
- Around line 188-201: Update the test case “keeps the current remote catalog
when the IPC refresh fails” to assert that the console.warn spy is called with
the expected IPC refresh failure message after loadCatalog rejects. Keep the
existing catalog-retention assertions and cleanup unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6f6d9fb6-b2d6-4894-8873-b2c59684fc04

📥 Commits

Reviewing files that changed from the base of the PR and between 1a57d15 and 092ea13.

📒 Files selected for processing (76)
  • docs/architecture/agent-scoped-extensions/plan.md
  • docs/architecture/agent-scoped-extensions/spec.md
  • docs/architecture/agent-scoped-extensions/tasks.md
  • docs/architecture/plugin-availability-boundary/spec.md
  • docs/features/plugins-hub/plan.md
  • docs/features/plugins-hub/spec.md
  • docs/features/plugins-hub/tasks.md
  • docs/issues/runtime-history-global-trace-aggregation/spec.md
  • src/main/presenter/agentRepository/index.ts
  • src/main/presenter/agentRuntimePresenter/dispatch.ts
  • src/main/presenter/agentRuntimePresenter/index.ts
  • src/main/presenter/agentRuntimePresenter/types.ts
  • src/main/presenter/mcpPresenter/index.ts
  • src/main/presenter/mcpPresenter/toolManager.ts
  • src/main/presenter/remoteControlPresenter/index.ts
  • src/main/presenter/skillPresenter/skillTools.ts
  • src/main/presenter/sqlitePresenter/tables/deepchatMessages.ts
  • src/main/presenter/toolPresenter/agentTools/agentToolManager.ts
  • src/main/presenter/toolPresenter/index.ts
  • src/renderer/settings/components/CronJobsSettings.vue
  • src/renderer/settings/components/RemoteSettings.vue
  • src/renderer/src/components/WindowSideBar.vue
  • src/renderer/src/components/trace/TraceDialog.vue
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/pages/plugins/AgentExtensionPolicyPanel.vue
  • src/renderer/src/pages/plugins/OfficialPluginDetailPage.vue
  • src/renderer/src/pages/plugins/PluginsCatalogPage.vue
  • src/renderer/src/pages/plugins/PluginsHubPage.vue
  • src/renderer/src/stores/pluginCatalog.ts
  • src/shared/contracts/domainSchemas.ts
  • src/shared/types/agent-interface.d.ts
  • src/shared/types/presenters/core.presenter.d.ts
  • src/shared/types/presenters/remote-control.presenter.d.ts
  • src/shared/types/presenters/tool.presenter.d.ts
  • src/types/i18n.d.ts
  • test/e2e/specs/11-remote-control-readonly-route.smoke.spec.ts
  • test/main/performance/memory/messageHistoryTraceScale.perf.ts
  • test/main/presenter/agentRepository.test.ts
  • test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts
  • test/main/presenter/agentRuntimePresenter/messageStore.test.ts
  • test/main/presenter/mcpPresenter.test.ts
  • test/main/presenter/mcpPresenter/toolManager.test.ts
  • test/main/presenter/remoteControlPresenter/remoteControlPresenter.test.ts
  • test/main/presenter/skillPresenter/skillTools.test.ts
  • test/main/presenter/sqlitePresenter/deepchatMessagesTable.test.ts
  • test/main/presenter/toolPresenter/toolPresenter.test.ts
  • test/main/routes/dispatcher.test.ts
  • test/renderer/api/clients.test.ts
  • test/renderer/components/AgentExtensionPolicyPanel.test.ts
  • test/renderer/components/OfficialPluginDetailPage.test.ts
  • test/renderer/components/PluginPageWrappers.test.ts
  • test/renderer/components/PluginsCatalogPage.test.ts
  • test/renderer/components/PluginsHubPage.test.ts
  • test/renderer/components/RemoteSettings.test.ts
  • test/renderer/components/WindowSideBar.test.ts
  • test/renderer/components/trace/TraceDialog.test.ts
  • test/renderer/stores/pluginCatalogStore.test.ts
💤 Files with no reviewable changes (13)
  • docs/features/plugins-hub/plan.md
  • docs/architecture/agent-scoped-extensions/tasks.md
  • src/main/presenter/agentRuntimePresenter/types.ts
  • src/shared/types/presenters/tool.presenter.d.ts
  • docs/features/plugins-hub/tasks.md
  • docs/architecture/agent-scoped-extensions/plan.md
  • src/renderer/src/pages/plugins/AgentExtensionPolicyPanel.vue
  • test/renderer/components/AgentExtensionPolicyPanel.test.ts
  • test/renderer/components/PluginPageWrappers.test.ts
  • src/shared/types/agent-interface.d.ts
  • src/shared/contracts/domainSchemas.ts
  • src/main/presenter/agentRepository/index.ts
  • src/shared/types/presenters/core.presenter.d.ts

Comment thread src/renderer/src/pages/plugins/OfficialPluginDetailPage.vue
@zerob13 zerob13 merged commit 71d667c into dev Jul 11, 2026
4 checks passed
@zhangmo8 zhangmo8 deleted the codex/fix-runtime-history-trace-scan branch July 13, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Runtime history reads aggregate the global trace table / 运行时历史读取聚合全局 trace 表

1 participant