* fix: harden web fetch html conversion
* fix: consume malformed html tag tails
* fix: consume invalid html tag spans
* fix: preserve html scanner edge cases
* fix: preserve title-only html fallback
* fix: harden html scanner malformed tokens
* fix: close html scanner review gaps
* fix: keep malformed html raw text hidden
* fix: keep html scanner comment content hidden
* fix: skip unsupported html attribute values
* fix: skip raw text from opener end
* fix: drop malformed html tag tails
* fix: preserve trailing slash href links
* fix: close html scanner review gaps
* fix: preserve literal less-than text
* fix: bound html render context nesting
* fix: drop bogus html closing tags
* fix: handle abrupt html comments
* fix: remove dead html scanner branches
* fix: close quoted self-closing html tags
* fix: track anchor text incrementally
* fix: ignore quoted raw text markers
* fix: close title contexts through literal markup
* fix: close anchors through nested contexts
* fix: close nested HTML contexts consistently
* feat(secrets): resolve SecretRef model credentials at egress via process-local sentinels
SecretRef-managed model-provider credentials now travel as opaque
oc-sent-v1 sentinels through auth storage, stream options, and SDK
config; the guarded model fetch injects real values into headers and
URLs immediately before the SSRF-guarded send and fails closed on
unknown sentinels. packages/ai adapters converge on the host guarded
fetch where the SDK supports custom fetch and unwrap at construction
where it does not. Resolved values (and their percent-encoded forms)
register for exact-value log redaction. Kill switch:
OPENCLAW_SECRET_SENTINELS=off. Also fixes a pre-existing unhandled
rejection race in capNonOkResponseBodyLazily (pipeThrough writer leak).
* test(plugin-sdk): update public surface budget
The wrapper probes `crabbox --version` and `crabbox run --help` once each with a
snappy 5s timeout to enumerate providers before delegating. A cold Crabbox — the
first call right after a version bump, or one on a loaded machine — can exceed
that timeout while rendering `run --help` (52KB, emitted on stderr in 0.36) or
doing first-run init, and can emit nothing on that first call. When that happens
both guards fire and hard-exit the wrapper ("selected binary failed basic
--version/--help sanity checks" or "could not parse provider list from --help;
refusing to run"), which blocks ALL remote validation (`pnpm check:changed`,
remote `pnpm test` lanes) even though the binary is fine.
Retry each metadata probe once with a generous 20s timeout when the first attempt
is killed or returns empty. The warm path is unchanged (one ~instant probe); only
a slow/empty first probe pays for the retry, after which the sanity/provider-list
guards judge the recovered result. Add a regression test: a fake Crabbox whose
`run --help` is slower than the default probe timeout (and, like 0.36, writes help
to stderr) is now recovered by the retry instead of hard-failing.
* fix(state): close cached SQLite state and agent databases on process exit
* refactor(state): pair SQLite exit-close with cache lifecycle and rebind stale proxy-capture stores
* fix(cli): register debug-proxy finalize before the state DB exit hook
* refactor(state): narrow to agent-db and proxy-capture exit lifecycle after #100691 landed shared-state close
---------
Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
* fix(doctor): honor per-agent bootstrap profile in size check
* fix(doctor): thread defaultAgentId through structured bootstrap-size health check
The noteBootstrapFileSize note path was fixed in the previous commit.
This commit applies the same defaultAgentId threading to the registered
core/doctor/bootstrap-size health check in doctor-core-checks.ts, which
is used by doctor --lint and repair flows. Adds an integration regression
test that places a 15 000-char AGENTS.md between the per-agent budget
(10 000) and the defaults budget (20 000) and asserts that a truncation
warning is emitted -- the test fails on main (defaults budget wins, no
warning) and passes after this patch (per-agent budget wins, warning).
Also updates three fixHint strings in the health check to name the
per-agent knob before the defaults fallback, matching the note-path tip
text from the previous commit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(doctor): preserve total-budget remediation guidance
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* improve(diagnostics-otel): tune duration/context histogram bucket boundaries
The openclaw.run.duration_ms, openclaw.harness.duration_ms, and
openclaw.context.tokens histograms used the SDK default bucket
boundaries. The default duration buckets top out at 10s, so agent runs —
which routinely take minutes — all collapse into the +Inf overflow
bucket, making p95/p99 latency meaningless without collector-side
reconfiguration.
Add explicit_bucket_boundaries advice via named constants, matching the
existing GEN_AI_*_BUCKETS convention in this file:
- AGENT_DURATION_MS_BUCKETS (1s … 1h) for the run and harness duration
histograms, which share the same range.
- CONTEXT_TOKENS_BUCKETS on a token scale (1k … 2M). openclaw.context.tokens
records context-window limit/used token counts (e.g. 128000), so the
boundaries must cover real context sizes rather than small integers.
Adds a test asserting the three histograms advertise the expected
boundaries and that run/harness share the same set.
* fix(diagnostics-otel): preserve prior histogram buckets
---------
Co-authored-by: Harry Chen <zhiling.chen@binance.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>