Skip to content

perf(tui): defer EmbeddedTuiBackend import, drop dead warmup helpers#84701

Merged
RomneyDa merged 5 commits into
mainfrom
defer-remote-tui-loading
May 21, 2026
Merged

perf(tui): defer EmbeddedTuiBackend import, drop dead warmup helpers#84701
RomneyDa merged 5 commits into
mainfrom
defer-remote-tui-loading

Conversation

@RomneyDa

@RomneyDa RomneyDa commented May 20, 2026

Copy link
Copy Markdown
Member

Stacked on #84686. Follow-ups from #84686 (comment).

A further improvement on TUI load speed

BEFORE

image

AFTER

image

Changes

1. Defer EmbeddedTuiBackend import (src/tui/tui.ts)
The static import pulled gateway server-side modules (server-model-catalog, session-reset-service, sessions-patch, etc.) into every TUI process at module-eval. Remote-mode TUI never constructs an embedded backend, so the import is now gated behind opts.local via await import().

2. Remove dead helpers (src/agents/context.ts, -117 lines)
shouldEagerWarmContextWindowCache, isLikelyOpenClawCliProcess, getCommandPathFromArgv, SKIP_EAGER_WARMUP_PRIMARY_COMMANDS had no production callers after #84686 moved warmup into EmbeddedTuiBackend.start(). Deleted them, the corresponding test, and 4 now-unused imports.

Audited, no change needed

  • lookupContextTokens warmup: every call site is either gateway-server-side (session-utils.ts) or passes allowAsyncLoad: false (commands/sessions.ts, cron/isolated-agent/run.ts). Cannot leak into remote TUI.
  • Channel state probes (package-state-probes, persisted-auth-state, configured-state): only reached via applyPluginAutoEnable / isChannelConfigured, none of which is called from runTui() on the remote path.
  • materializeRuntimeConfig defaults with manifestRegistry: undefined: applyContextPruningDefaults and applyModelDefaults fall through resolveBundledProviderPolicySurface, which has a direct bundled-surface fallback; they return config unchanged when no policy applies. Remote TUI's gateway/session/agent-ID view is untouched.

Verification

  • pnpm tsgo:core --noEmit clean
  • pnpm build clean (no INEFFECTIVE_DYNAMIC_IMPORT)
  • node scripts/run-vitest.mjs src/tui/tui.test.ts src/tui/embedded-backend.test.ts src/agents/context.lookup.test.ts src/config/io.meta.test.ts src/config/runtime-snapshot.test.ts — 100/100 pass
  • oxlint + oxfmt clean on changed files

Real behavior proof

  • Behavior addressed: static EmbeddedTuiBackend import evaluates gateway server-side modules on remote TUI startup; dead CLI-argv helpers carried over from the pre-deferred warmup design.
  • Real environment tested: verified statically that embedded-backend.js has no other prod static importer; zero remaining references to deleted helpers across src, scripts, test, extensions.
  • Exact steps or command run after this patch: pnpm tsgo:core --noEmit; pnpm build; targeted vitest run above; node scripts/run-oxlint.mjs src/agents/context.ts src/agents/context.lookup.test.ts src/tui/tui.ts; pnpm format:check.
  • Evidence after fix: typecheck clean; build clean; 100 targeted tests pass; lint and format clean.
  • Observed result after fix: remote TUI module graph no longer references embedded-backend.js or its gateway-side fanout; local TUI behavior unchanged.
  • What was not tested: end-to-end manual cold-start timing for openclaw tui against a warm gateway; --local mode regression check.

RomneyDa added 4 commits May 20, 2026 12:51
Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config
…d backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.
@openclaw-barnacle openclaw-barnacle Bot added size: XS maintainer Maintainer-authored PR labels May 20, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Workflow note: Future ClawSweeper reviews update this same comment in place.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

Summary
The branch defers EmbeddedTuiBackend loading to local TUI mode and removes now-unused eager context-cache warmup helper code and its test.

Reproducibility: yes. source-reproducible: the stacked base statically imports embedded-backend from the TUI module, and the PR head moves that import behind opts.local. I did not run an end-to-end cold-start timing reproduction in this read-only review.

PR rating
Overall: 🐚 platinum hermit
Proof: 🌊 off-meta tidepool
Patch quality: 🐚 platinum hermit
Summary: The patch is small, source-supported, and has no blocking findings; runtime smoke proof remains a maintainer validation choice for this protected stacked PR.

Rank-up moves:

  • none
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Real behavior proof
Not applicable: The external contributor proof gate does not apply to this member-authored maintainer-labeled PR; the body includes static/build/test evidence and explicitly notes the missing manual runtime timing checks.

Risk before merge

Maintainer options:

  1. Decide the mitigation before merge
    Review and land this import boundary with its stacked TUI startup parent, adding quick remote cold-start timing and local-mode smoke proof if maintainers want runtime confirmation.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge
Protected maintainer-labeled stacked PR needs maintainer review and landing coordination, not an automated repair lane.

Security
Cleared: The diff changes import timing and removes dead helper code; it does not alter dependencies, CI, secrets, permissions, or external code execution paths.

Review details

Best possible solution:

Review and land this import boundary with its stacked TUI startup parent, adding quick remote cold-start timing and local-mode smoke proof if maintainers want runtime confirmation.

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

Yes, source-reproducible: the stacked base statically imports embedded-backend from the TUI module, and the PR head moves that import behind opts.local. I did not run an end-to-end cold-start timing reproduction in this read-only review.

Is this the best way to solve the issue?

Yes, the proposed dynamic import is the narrow maintainable fix for this module-graph leak because it uses the existing local-mode branch and leaves gateway-mode connection behavior unchanged.

Label justifications:

  • P2: This is a focused TUI startup performance improvement with limited blast radius but real user-facing responsiveness impact.
  • rating: 🐚 platinum hermit: Current PR rating is 🐚 platinum hermit because proof is 🌊 off-meta tidepool, patch quality is 🐚 platinum hermit, and The patch is small, source-supported, and has no blocking findings; runtime smoke proof remains a maintainer validation choice for this protected stacked PR.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The external contributor proof gate does not apply to this member-authored maintainer-labeled PR; the body includes static/build/test evidence and explicitly notes the missing manual runtime timing checks.

What I checked:

  • Dynamic import boundary: At the PR head, src/tui/tui.ts no longer has the top-level EmbeddedTuiBackend import and imports ./embedded-backend.js only inside the opts.local branch. (src/tui/tui.ts:671, 828f81c612c4)
  • Base branch behavior: The stacked base still statically imported EmbeddedTuiBackend from the TUI module and constructed it through the ternary branch, which is the module-graph leak the PR narrows. (src/tui/tui.ts:31, f1115ceebdbf)
  • Warmup ownership after parent PR: The stacked base moves context cache warmup into EmbeddedTuiBackend.start(), so deleting the CLI argv eager-warmup gate in this PR does not remove the embedded-mode warmup path. (src/tui/embedded-backend.ts:142, f1115ceebdbf)
  • Deleted helper references: The PR head has no remaining references to shouldEagerWarmContextWindowCache, SKIP_EAGER_WARMUP_PRIMARY_COMMANDS, getCommandPathFromArgv, or isLikelyOpenClawCliProcess across the searched source/test/plugin paths. (src/agents/context.ts:143, 828f81c612c4)
  • Patch whitespace check: The PR diff has no whitespace errors under git diff --check. (828f81c612c4)
  • History/provenance sample: Available current-main history is shallow; blame and file log for the central TUI/context files point to a broad current-main boundary commit, while the stacked parent and this PR head commits are by Dallin Romney. (src/tui/tui.ts:444, 5de8f8e8a9c6)

Likely related people:

  • RomneyDa: Authored the stacked parent commit that moved context warmup into embedded TUI startup and authored this follow-up that defers the embedded backend import and deletes the now-dead helper path. (role: stack owner and recent area contributor; confidence: high; commits: f1115ceebdbf, df101c2d9935, 828f81c612c4; files: src/tui/tui.ts, src/tui/embedded-backend.ts, src/agents/context.ts)
  • Ayaan Zaidi: The available local history is shallow, but blame for the relevant current-main TUI and context files points to a broad recent commit by this author, making them a weak routing signal for the existing code surface. (role: current-main area contributor; confidence: low; commits: 5de8f8e8a9c6; files: src/tui/tui.ts, src/tui/embedded-backend.ts, src/agents/context.ts)

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

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels May 20, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 🥚 common Frosted Lint Imp

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🥚 common.
Trait: keeps receipts.
Image traits: location CI tidepool; accessory little merge flag; palette plum, gold, and soft gray; mood watchful; pose nestled inside a glowing shell; shell frosted glass shell; lighting bright celebratory glints; background little resolved-comment flags.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Frosted Lint Imp in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S and removed size: XS labels May 20, 2026
@RomneyDa RomneyDa changed the title perf(tui): defer EmbeddedTuiBackend import until local mode perf(tui): defer EmbeddedTuiBackend import, drop dead warmup helpers May 20, 2026
@RomneyDa RomneyDa force-pushed the no-plugin-validation-tui-side branch from f1115ce to 835fc2f Compare May 20, 2026 22:23
Base automatically changed from no-plugin-validation-tui-side to main May 21, 2026 00:43
@RomneyDa RomneyDa merged commit b79effe into main May 21, 2026
144 of 146 checks passed
@RomneyDa RomneyDa deleted the defer-remote-tui-loading branch May 21, 2026 00:43
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
galiniliev pushed a commit to galiniliev/openclaw that referenced this pull request May 25, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
…penclaw#84701)

* perf(tui): skip plugin-aware config validation on remote TUI startup

Cold `openclaw tui` against a remote gateway was synchronously calling
loadPluginMetadataSnapshot() via getRuntimeConfig() -> loadConfig() ->
validateConfigObjectWithPlugins(), pulling the full plugin metadata
snapshot (200k+ file reads) onto the TUI's event loop. The TUI itself
never consumes plugin metadata in remote mode; it queries the gateway
over RPC. The work was being done purely to validate the config and
then thrown away.

Thread an opt-in `skipPluginValidation` flag through getRuntimeConfig()
and loadConfig() (createConfigIO already supports pluginValidation: "skip";
it just wasn't reachable from the runtime entrypoints). The TUI passes
skipPluginValidation: !isLocalMode so:

- Remote-mode TUI: no plugin metadata load, no event-loop freeze after
  first render
- Embedded (--local) mode: unchanged; the in-process agent runtime
  still gets a fully validated config

* remove verbose comments

* perf(tui): move context cache warmup from module top-level to embedded backend

agents/context.ts fired ensureContextWindowCacheLoaded() unconditionally
at module-eval time for non-skip-listed CLI commands. The TUI transitively
imports this module, so the warmup ran on every TUI startup including
remote-mode, cascading into ensureOpenClawModelsJson -> resolveImplicitProviders
-> runProviderCatalog and dominating the cold-start freeze (CPU profile
showed ~55s of resolveProviderSyntheticAuthWithPlugin, lstat, open, etc.).

It also pre-emptively called getRuntimeConfig() without skipPluginValidation,
pinning the full snapshot and nullifying the skip flag added on this branch.

Remove the top-level side effect and trigger the warmup explicitly from
EmbeddedTuiBackend.start(), which only runs when an in-process agent
runtime actually needs the cache.

* perf(tui): defer EmbeddedTuiBackend import until local mode

* refactor(agents): remove dead context-cache warmup helpers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant