Skip to content

Fix status cold-path plugin metadata scans#80614

Closed
flashosophy wants to merge 4 commits into
openclaw:mainfrom
flashosophy:codex/status-fast-path
Closed

Fix status cold-path plugin metadata scans#80614
flashosophy wants to merge 4 commits into
openclaw:mainfrom
flashosophy:codex/status-fast-path

Conversation

@flashosophy

Copy link
Copy Markdown
Contributor

Summary

  • Keeps non-deep openclaw status session-summary rendering on a shallow path by disabling manifest model-id normalization in status-only model parsing.
  • Threads allowManifestNormalization through persisted model-ref resolvers so status callers can avoid plugin metadata loads without changing normal model selection behavior.
  • Caches CLI-provider detection per config object during status rendering.
  • Reuses per-agent session rows for the global recent-session list instead of rebuilding every session store.

Closes #80611.
Related: #79129.

Root cause

Plain openclaw status rendered session model/runtime labels by repeatedly entering plugin metadata/model normalization paths. On a 2026.5.7 npm-global install, this made default status take ~20s while openclaw gateway status was ~1.3s.

The slow path was not the gateway probe. It came from status summary/model/runtime labeling:

  • persisted/configured model refs could still manifest-normalize even when status disabled plugin normalization;
  • runtime label rendering repeatedly checked CLI-provider status;
  • global recent-session rows were rebuilt from stores already read for per-agent rows.

Local behavior proof

On the affected stable install before the patch:

openclaw status              real 20.32
openclaw gateway status      real 1.29

After applying the same fix locally to the installed stable dist through a managed patch:

openclaw status              real 2.27
openclaw gateway status      real 1.27

The source checkout based on v2026.5.7 also built and ran with the fix before rebasing this PR onto current main.

Validation

Run on this PR branch after rebasing onto current origin/main:

pnpm exec oxfmt --check --threads=1 \
  src/agents/model-selection.ts \
  src/commands/status.summary.runtime.ts \
  src/commands/status.summary.ts \
  src/status/agent-runtime-label.ts \
  src/commands/status.summary.runtime.test.ts \
  src/commands/status.summary.test.ts

pnpm exec vitest run \
  src/commands/status.summary.test.ts \
  src/commands/status.summary.runtime.test.ts \
  src/status/status-message.test.ts

pnpm build

Results:

  • formatting: passed
  • targeted tests: 3 files passed, 21 tests passed
  • build: passed

Notes

pnpm build updated extensions/canvas/src/host/a2ui/.bundle.hash locally as a generated artifact; that unrelated generated change was reverted and is not part of this PR.

AI-assisted: yes.

Keep non-deep status rendering on the cold path by skipping manifest normalization for status-only model parsing, caching CLI-provider checks per config object, and reusing per-agent session rows instead of rebuilding them for the global recent list.

Agent: Eva

Constraint: openclaw status must stay a shallow local health read unless --deep asks for slower plugin/model probing.

Rejected: process-global plugin metadata caching | broader and staler than needed for the status cold path.

Confidence: high

Scope-risk: narrow

Directive: Keep expensive plugin/model normalization out of default status rendering.

Tested: pending on rebased branch.

Not-tested: beta release adoption.

Co-authored-by: OmX <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations agents Agent runtime and tooling size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 11, 2026
@clawsweeper

clawsweeper Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge.

Summary
The PR disables status-only manifest normalization, caches CLI-provider checks during status rendering, reuses session rows for global status sessions, and adds stale task health to CLI, gateway, SDK, and docs surfaces.

Reproducibility: yes. source-backed: the PR body gives before/after timing output for the affected 2026.5.7 install, and current main still has the status model parsing path that can manifest-normalize without an explicit allowManifestNormalization: false. I did not rerun the live timing locally in this read-only review.

Real behavior proof
Sufficient (live_output): The PR body includes copied before/after timing output from an affected stable install showing improved openclaw status behavior after the fix.

Next step before merge
A focused automated repair can correct the shared-store aggregation regression while preserving the status performance fix.

Security
Cleared: No concrete security or supply-chain issue found; the diff does not change workflows, dependencies, install scripts, package resolution, downloads, or secret handling.

Review findings

  • [P2] Deduplicate shared session stores — src/commands/status.summary.ts:264
Review details

Best possible solution:

Land the status cold-path optimization after rebuilding global session rows once per unique store without agentIdOverride, with shared-store regression coverage; split the task-health surface unless maintainers explicitly want it in this PR.

Do we have a high-confidence way to reproduce the issue?

Yes, source-backed: the PR body gives before/after timing output for the affected 2026.5.7 install, and current main still has the status model parsing path that can manifest-normalize without an explicit allowManifestNormalization: false. I did not rerun the live timing locally in this read-only review.

Is this the best way to solve the issue?

No, not as submitted: the manifest-normalization and CLI-provider-cache pieces are narrow, but the global session aggregation change breaks shared-store semantics. The safer repair is to reuse loaded stores without reusing per-agent-overridden rows for the global list.

Full review comments:

  • [P2] Deduplicate shared session stores — src/commands/status.summary.ts:264
    When session.store lacks {agentId}, every agent resolves to the same store file. Appending rows already built with agentIdOverride makes global sessions.count and sessions.recent include each stored session once per configured agent, with shared rows stamped as the current agent. Build the global rows once per unique store without the override, or dedupe by store/key.
    Confidence: 0.92

Overall correctness: patch is incorrect
Overall confidence: 0.9

Acceptance criteria:

  • pnpm test src/commands/status.summary.test.ts src/commands/status.summary.runtime.test.ts src/status/status-message.test.ts
  • pnpm exec oxfmt --check --threads=1 src/commands/status.summary.ts src/commands/status.summary.test.ts src/commands/status.summary.runtime.ts src/commands/status.summary.runtime.test.ts src/status/agent-runtime-label.ts src/agents/model-selection.ts
  • pnpm build
  • If task-health changes remain in the branch, also run pnpm test src/commands/tasks.test.ts src/gateway/server-methods/tasks.test.ts

What I checked:

  • PR head proof and scope: The PR body reports live before/after timings on an affected 2026.5.7 install: openclaw status improved from 20.32s to 2.27s while openclaw gateway status stayed about 1.3s, and the head patch includes status cold-path changes plus separate task-health changes. (837c1af00688)
  • Current-main status model parsing still enters manifest normalization: Current main passes allowPluginNormalization: false for status model parsing but does not pass allowManifestNormalization: false into parseModelRef for configured or persisted status model refs. (src/commands/status.summary.runtime.ts:35, 726ecc4987e7)
  • Model normalization contract: parseModelRef normalizes through normalizeProviderModelId; manifest normalization is controlled separately from plugin normalization, so disabling plugin normalization alone does not keep status parsing off the manifest-normalization path. (src/agents/model-selection-normalize.ts:39, 726ecc4987e7)
  • Current-main global status aggregation contract: Current main builds per-agent rows with agentIdOverride, then builds the global recent list from each unique store path without the override, preserving one global row per stored session key. (src/commands/status.summary.ts:257, 726ecc4987e7)
  • Shared session stores are supported: When session.store does not include {agentId}, resolveStorePath returns the same resolved path for every agent; current tests also document shared stores with both agent:main:* and agent:ops:* keys as legitimate. (src/config/sessions/paths.ts:294, 726ecc4987e7)
  • Shared-store regression in the PR diff: The PR replaces the unique-store global pass with allSessionsByAgent.push(...sessions), where sessions were already built with agentIdOverride; a shared store is therefore counted once per configured agent in the global status list. (src/commands/status.summary.ts:264, 837c1af00688)

Likely related people:

  • vincentkoc: Recent GitHub history shows fix(status): show runtime in CLI sessions on the status summary path, and earlier task health/audit work in the task area that the PR touches. (role: recent status and task area contributor; confidence: high; commits: 46c99cff0b2f, c52fac836cc8, e57b3618fc8d; files: src/commands/status.summary.ts, src/commands/status.summary.runtime.ts, src/status/agent-runtime-label.ts)
  • steipete: Recent history shows status model-resolution fast-path work and several task audit/runtime refactors adjacent to the PR's status and task surfaces. (role: recent status model-resolution and task audit contributor; confidence: high; commits: e61eba11e671, 1fb44f0aadd4, 32ebaa37574e; files: src/commands/status.summary.runtime.ts, src/agents/model-selection.ts, src/tasks/task-registry.audit.ts)
  • tmimmanuel: GitHub history shows feat(gateway): add SDK task ledger RPCs, which introduced the gateway/SDK task summary surface extended by the PR's task-health commits. (role: gateway task ledger surface introducer; confidence: medium; commits: 2945948a5ee4; files: src/gateway/server-methods/tasks.ts, src/gateway/protocol/schema/tasks.ts, packages/sdk/src/types.ts)

Remaining risk / open question:

  • I did not run timing or test commands because this review was read-only; the performance reproduction is based on the PR's live-output proof plus source inspection.
  • The task-health gateway/SDK/docs changes are outside the stated status cold-path fix and may need to be split or explicitly accepted separately.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 447206623700.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 11, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 11, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime labels May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot added the docs Improvements or additions to documentation label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@anyech

anyech commented May 12, 2026

Copy link
Copy Markdown
Contributor

Adding a small independent data point from a separate 2026.5.7 installation. This is not validation of the PR head; it is a local source/runtime microcheck of the same cold path described in #80611/#80614.

  • Parsing the session stores themselves was cheap: 596 entries across two stores parsed in ~150–210 ms total.
  • The expensive part was status session-row enrichment before output: per-row resolveSessionModelRef was often ~120–250 ms, and resolveSessionRuntimeLabel often ~150–180 ms.
  • In an isolated parseModelRef microcheck with the installed 2026.5.7 code, 20 calls with { allowPluginNormalization: false } took ~2039 ms, while the same 20 calls with { allowPluginNormalization: false, allowManifestNormalization: false } took ~0 ms.
  • The runtime-label side showed the same metadata-scan shape: 10 calls to isCliProvider('oca', cfg) took ~1270 ms, while selectAgentHarness(...) was ~1 ms.

That independently corroborates the PR's status-specific direction: keep status-summary model parsing off manifest normalization and avoid repeated CLI-provider/plugin-metadata discovery while rendering session rows.

@shakkernerd

Copy link
Copy Markdown
Member

Thanks for the status-path analysis and the before/after timing proof.

I’m closing this as superseded by the current main metadata-reuse work rather than landing this branch as-is. The root problem identified here was real: plain status rendering could enter model/runtime labeling paths that repeatedly loaded plugin metadata. #82814 fixed the release-blocking metadata regression by threading prepared plugin metadata through the hot model/runtime/session paths instead of adding another local status-specific workaround.

Current main at f590439 no longer shows the status/metadata timeout shape in the quick command proof I reran:

  • openclaw status: 1.05s in an isolated home
  • plugins list --json: 0.69s in an isolated home

The broader landed proof for #82814 moved the original metadata regression from FAIL 3/3, ~10.6s turns, and 394 metadata scans to PASS 3/3, ~3.7-3.9s turns, and 28 scans.

I’m not landing this branch because it now overlaps the current-main fix and also carries extra status/task/session-row changes that are no longer the smallest safe patch for this regression. If a large-session openclaw status scaling problem still reproduces on current main, please file or refresh a narrower issue with the current SHA, session count, timings, and a trace showing the remaining hot path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui commands Command implementations docs Improvements or additions to documentation gateway Gateway runtime size: M triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Non-deep openclaw status repeatedly loads plugin metadata and takes ~20s on 2026.5.7

3 participants