

























@@ -69,144 +69,25 @@ If the command is running from a source checkout, prefer measuring the built
6969runtime with `node dist/entry.js ...` after `pnpm build`; `pnpm openclaw ...`
7070also measures source-runner overhead.
717172-## Temporary CLI debug timing
72+## CLI startup and command profiling
737374-OpenClaw keeps `src/cli/debug-timing.ts` as a small helper for local
75-investigation. It is intentionally not wired into CLI startup, command routing,
76-or any command by default. Use it only while debugging a slow command, then
77-remove the import and spans before landing the behavior change.
78-79-Use this when a command is slow and you need a quick phase breakdown before
80-deciding whether to use a CPU profiler or fix a specific subsystem.
81-82-### Add temporary spans
83-84-Add the helper near the code you are investigating. For example, while debugging
85-`openclaw models list`, a temporary patch in
86-`src/commands/models/list.list-command.ts` might look like this:
87-88-```ts
89-// Temporary debugging only. Remove before landing.
90-import { createCliDebugTiming } from "../../cli/debug-timing.js";
91-92-const timing = createCliDebugTiming({ command: "models list" });
93-94-const authStore = timing.time("debug:models:list:auth_store", () => ensureAuthProfileStore());
95-96-const loaded = await timing.timeAsync(
97-"debug:models:list:registry",
98- () => loadListModelRegistry(cfg, { sourceConfig }),
99- (result) => ({
100- models: result.models.length,
101- discoveredKeys: result.discoveredKeys.size,
102- }),
103-);
104-```
105-106-Guidelines:
107-108-- Prefix temporary phase names with `debug:`.
109-- Add only a few spans around suspected slow sections.
110-- Prefer broad phases such as `registry`, `auth_store`, or `rows` over helper
111- names.
112-- Use `time()` for synchronous work and `timeAsync()` for promises.
113-- Keep stdout clean. The helper writes to stderr, so command JSON output stays
114- parseable.
115-- Remove temporary imports and spans before opening the final fix PR.
116-- Include the timing output or a short summary in the issue or PR that explains
117- the optimization.
118-119-### Run with readable output
120-121-Readable mode is best for live debugging:
122-123-```bash
124-OPENCLAW_DEBUG_TIMING=1 pnpm openclaw models list --all --provider moonshot
125-```
126-127-Example output from a temporary `models list` investigation:
128-129-```text
130-OpenClaw CLI debug timing: models list
131- 0ms +0ms start all=true json=false local=false plain=false provider="moonshot"
132- 2ms +2ms debug:models:list:import_runtime duration=2ms
133- 17ms +14ms debug:models:list:load_config duration=14ms sourceConfig=true
134- 20.3s +20.3s debug:models:list:auth_store duration=20.3s
135- 20.3s +0ms debug:models:list:resolve_agent_dir duration=0ms agentDir=true
136- 20.3s +0ms debug:models:list:resolve_provider_filter duration=0ms
137- 25.3s +5.0s debug:models:list:ensure_models_json duration=5.0s
138- 31.2s +5.9s debug:models:list:load_model_registry duration=5.9s models=869 availableKeys=38 discoveredKeys=868 availabilityError=false
139- 31.2s +0ms debug:models:list:resolve_configured_entries duration=0ms entries=1
140- 31.2s +0ms debug:models:list:build_configured_lookup duration=0ms entries=1
141- 33.6s +2.4s debug:models:list:read_registry_models duration=2.4s models=871
142- 35.2s +1.5s debug:models:list:append_discovered_rows duration=1.5s seenKeys=0 rows=0
143- 36.9s +1.7s debug:models:list:append_catalog_supplement_rows duration=1.7s seenKeys=5 rows=5
144-145-Model Input Ctx Local Auth Tags
146-moonshot/kimi-k2-thinking text 256k no no
147-moonshot/kimi-k2-thinking-turbo text 256k no no
148-moonshot/kimi-k2-turbo text 250k no no
149-moonshot/kimi-k2.5 text+image 256k no no
150-moonshot/kimi-k2.6 text+image 256k no no
151-152- 36.9s +0ms debug:models:list:print_model_table duration=0ms rows=5
153- 36.9s +0ms complete rows=5
154-```
155-156-Findings from this output:
157-158-| Phase | Time | What it means |
159-| ---------------------------------------- | ---------: | ------------------------------------------------------------------------------------------------------- |
160-| `debug:models:list:auth_store` | 20.3s | The auth-profile store load is the largest cost and should be investigated first. |
161-| `debug:models:list:ensure_models_json` | 5.0s | Syncing `models.json` is expensive enough to inspect for caching or skip conditions. |
162-| `debug:models:list:load_model_registry` | 5.9s | Registry construction and provider availability work are also meaningful costs. |
163-| `debug:models:list:read_registry_models` | 2.4s | Reading all registry models is not free and may matter for `--all`. |
164-| row append phases | 3.2s total | Building five displayed rows still takes several seconds, so the filtering path deserves a closer look. |
165-| `debug:models:list:print_model_table` | 0ms | Rendering is not the bottleneck. |
166-167-Those findings are enough to guide the next patch without keeping timing code in
168-production paths.
169-170-### Run with JSON output
171-172-Use JSON mode when you want to save or compare timing data:
74+Use the checked-in startup benchmark when a command feels slow:
1737517476```bash
175-OPENCLAW_DEBUG_TIMING=json pnpm openclaw models list --all --provider moonshot \
176-2> .artifacts/models-list-timing.jsonl
77+pnpm test:startup:bench:smoke
78+pnpm tsx scripts/bench-cli-startup.ts --preset real --case status --runs 3
79+pnpm tsx scripts/bench-cli-startup.ts --preset real --cpu-prof-dir .artifacts/cli-cpu
17780```
17881179-Each stderr line is one JSON object:
180-181-```json
182-{
183-"command": "models list",
184-"phase": "debug:models:list:registry",
185-"elapsedMs": 31200,
186-"deltaMs": 5900,
187-"durationMs": 5900,
188-"models": 869,
189-"discoveredKeys": 868
190-}
191-```
192-193-### Clean up before landing
194-195-Before opening the final PR:
82+For one-off profiling through the normal source runner, set
83+`OPENCLAW_RUN_NODE_CPU_PROF_DIR`:
1968419785```bash
198-rg 'createCliDebugTiming|debug:[a-z0-9_-]+:' src/commands src/cli \
199- --glob '!src/cli/debug-timing.*' \
200- --glob '!*.test.ts'
86+OPENCLAW_RUN_NODE_CPU_PROF_DIR=.artifacts/cli-cpu pnpm openclaw status
20187```
20288203-The command should return no temporary instrumentation call sites unless the PR
204-is explicitly adding a permanent diagnostics surface. For normal performance
205-fixes, keep only the behavior change, tests, and a short note with the timing
206-evidence.
207-208-For deeper CPU hotspots, use Node profiling (`--cpu-prof`) or an external
209-profiler instead of adding more timing wrappers.
89+The source runner adds Node CPU profile flags and writes a `.cpuprofile` for the
90+command. Use this before adding temporary instrumentation to command code.
2109121192## Gateway watch mode
21293此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。