Add optional directUserId field to ChannelModelOverrideParams so the
shared channels.modelByChannel resolver can match DM-specific config
entries. Callers pass sessionEntry.origin?.nativeDirectUserId.
Closes#53638
Co-authored-by: Thomas Zhengtao <thomas.zhengtao@gmail.com>
A concurrent atomic rewrite (write-temp + rename) of a memory-wiki source
page by the bridge re-export made fs-safe's opened-fd identity check fail
with `path-mismatch`, which the page write rethrew as a fatal "Refusing to
write" error and aborted the whole wiki_status / source-sync call. The race
is transient and benign: the file is replaced under the open handle and the
concurrent writer lands equivalent content.
Retry briefly on `path-mismatch` (the rename window closes sub-ms) and
rethrow unchanged on exhaustion, so persistent failures (directory
collision, not-file) and symlink/path-alias swaps still hard-fail exactly
as before. The identity guard is untouched; only the benign rename race is
retried, matching the sibling read path that already treats path-mismatch
as transient.
Extracts the guarded-write logic duplicated by source-page-shared.ts and
okf.ts into one writeGuardedVaultPage helper so both write paths get the
fix and the copy is removed.
Closes#92134
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
cron.add recomputed every job's next-run time via recomputeNextRuns after
appending the new job. recomputeNextRuns advances nextRunAtMs whenever
now >= nextRun, so an unrelated add advanced any sibling recurring job whose
slot was due but had not yet fired, discarding that occurrence with no error
and no log. lastRunAtMs stayed unchanged while nextRunAtMs jumped one interval
forward, so the run was silently lost.
Switch add and remove onto recomputeNextRunsForMaintenance plus
ensureLoaded(state, { skipRecompute: true }), matching every other ops.ts
caller (read ops, update, finalize, reload, startup). Maintenance recompute
backfills missing next-run times but never advances a present past-due slot,
preserving the invariant introduced for the timer/read/startup paths in
#13992 / #16156 / #17852.
Adds a regression test that fails on main (the due slot advances a full
interval) and passes with the fix.
A completed session (status: done/success) whose abort controller expires
during maintenance was incorrectly matched by markRestartAbortedMainSessions.
The matched activeRun's lifecycleGeneration matched the current generation
(no restart occurred), but entry.updatedAt < run.observedAt allowed the
entry to be marked as running+aborted, triggering a false restart recovery.
Fix: require that the timing condition (updatedAt < observedAt) only applies
for stale-generation runs (provenance: pre-restart). Current-generation runs
with observedAt after the session's updatedAt are maintenance-expired abort
controllers and must not reopen completed sessions.
Related to #95443
* fix(agents): restore model-fetch info logs
* docs(logging): document [model-fetch] default info-level visibility
[model-fetch] response metadata is always emitted at info level
regardless of OPENCLAW_DEBUG_MODEL_TRANSPORT, so users see basic
model transport hygiene (provider, API, model, status, latency)
without needing debug flags.
* docs(logging): clarify model-fetch start metadata visibility
normalizeAgentEventType checked the `phase:"end" || status==="completed"`
branch before the `failed/blocked` branch, but terminal tool/item events are
emitted with phase:"end" AND the real status, so failed and blocked tools were
normalized to tool.call.completed and the tool.call.failed branch was dead for
the item stream. SDK consumers filtering on tool.call.failed never saw tool
failures (they looked like successes). Reorder so failed/blocked is classified
before end/completed.
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(diagnostics-otel): keep full model id on spans (was collapsing to "unknown")
* test(diagnostics-otel): cover slash model span attribution
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>