Switching agents/sessions while a run is streaming left the TUI blank on return:
the run keeps executing, but its result never appears. Root cause is delivery
scoping, not client rendering — global-session runs are delivered per agent
(server-chat.ts resolveSessionDeliveryKey -> `agent:<id>:global`), so once the
client switches to another agent it stops receiving the backgrounded run's
events entirely. A purely client-side store therefore has nothing to retain, and
chat.history rebuilds only from PERSISTED messages (an in-flight run's text is
not yet persisted), so switch-back shows neither the live run nor a result.
Fix (gateway-sourced snapshot; additive, no protocol break):
- chat-abort.ts: resolveInFlightRunSnapshot() returns the active run for a
session+agent from the authoritative gateway state (chatAbortControllers +
chatRunBuffers). Only projectSessionActive, non-aborted runs are returned, so a
completed run (already in history) is not duplicated; the shared "global"
session is scoped by agentId. The active run is matched
by the requested OR the canonical store key (an abort entry can hold either),
mirroring sessions.list's active-run projection, so a run started under a
different-but-equivalent session key is still restored. The run is returned even with no buffered text:
some runtimes (Codex) withhold incremental assistant text and only emit the
reply at completion, so there is nothing to show mid-run, but the client should
still adopt the run and show `streaming` (not idle) and finalize cleanly.
- server-methods/chat.ts: chat.history includes an additive `inFlightRun`
({ runId, text }) for the requested session+agent.
- tui-session-actions.ts: loadHistory renders any buffered partial and re-adopts
activeChatRunId + `streaming` status, so resumed delivery continues the run and
its completion is owned by the client rather than an unowned error path.
Works across runtimes (Codex/embedded) and for /agent and /session switches
because the run state comes from the gateway on return, not from client event
capture. Supersedes the earlier client-side live-run-store attempt, which
real-gateway testing proved inert (the backgrounded run's events are never
delivered to the switched-away client).
- node scripts/run-vitest.mjs run src/gateway/chat-abort.test.ts src/tui/tui-session-actions.test.ts -> 57 passed
- node scripts/run-vitest.mjs run src/tui/ -> all passed
- gateway chat.history coverage (server-methods + server.chat suites) -> 263 passed
- tsgo -p tsconfig.core.json clean; oxfmt/oxlint clean
- Verified on a real gateway: /agent switch-back now shows `streaming` and the
result lands cleanly (Codex gpt-5.x).
Adds regression coverage for Google Vertex API-key model config planning when the credential comes from an env-backed auth profile. This keeps the planner-level guard around the Vertex static catalog rows that fixed#88816 on main.
Verification:
- `node scripts/run-vitest.mjs src/agents/models-config.applies-config-env-vars.test.ts extensions/google/provider-catalog.test.ts extensions/google/provider-models.test.ts`
- `./node_modules/.bin/oxfmt --check --threads=1 src/agents/models-config.applies-config-env-vars.test.ts extensions/ollama/src/stream.ts extensions/qa-lab/src/mantis/slack-desktop-smoke.runtime.ts extensions/qa-lab/src/mantis/telegram-desktop-builder.runtime.ts extensions/qa-lab/src/mantis/visual-task.runtime.ts`
- `git diff --check`
- `pnpm deadcode:dependencies`
CI note: PR CI had an unrelated `check-dependencies` failure for `ui/package.json: three`; the PR diff is one `src/agents` test file.
Refs #88816
Routes MiniMax OAuth device-code and token polling directly to account-hosted OAuth2 endpoints for global and CN regions, avoiding guarded-fetch cross-origin redirect body stripping. Keeps provider API base URLs unchanged and adds regression coverage for both endpoint pairs.
Proof: local minimax OAuth tests, oxfmt check, lint, autoreview clean, official MiniMax CLI/source check, live MiniMax endpoint probes, and CI run 26729242892 on 6bfe20eb06.
Co-authored-by: Matt Schleder <schledermatthew@gmail.com>
Fixes#88520.
Adds focused regression coverage for the embedded attempt trajectory recorder cleanup boundary so a stalled trajectory flush resolves after the cleanup timeout and logs pending write details instead of rejecting attempt cleanup.
Verification:
- node scripts/run-vitest.mjs src/agents/run-cleanup-timeout.test.ts
- git diff --check origin/main...origin/pr/88802
- PR CI green: https://github.com/openclaw/openclaw/actions/runs/26727232564
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Retire isolated cron session MCP runtimes on timeout and dispose so orphaned MCP servers do not accumulate after cron cleanup. Bound MCP session disposal to 5 seconds and force-close hung transports, including streamable-HTTP DELETE hangs, to prefer gateway availability over unbounded teardown.
Fixes#87821.
PR: #87981.
Proof: latest Real behavior proof check passed after body fix; local autoreview clean with focused cron/gateway/MCP tests covering 108 tests.
Co-authored-by: 忻役 <xinyi@mininglamp.com>
Co-authored-by: Jerry-Xin <jerryxin0@gmail.com>