The mock streamed pre-tool assistant text on the Responses path without `phase: "commentary"`, the field the API sets and the transport reads, so the draft-proof scenario ran green while never exercising the preamble lane on that transport. Proven live on Telegram: the preamble now renders as the status headline, and as a commentary line when progress.commentary is on.
A progress draft only exists while the agent is working, and OpenClaw's exec
returns instantly for a mock tool call, so the whole turn finished in ~86ms —
inside the 1.5s draft gate. No draft was created, which is correct behavior but
proves nothing about rendering.
The draft-proof scenario now holds its final answer (MOCK_DRAFTPROOF_FINAL_DELAY_MS,
default 6s) so the turn straddles the gate. That is what made the live Discord
recording possible: draft created, edited with the status headline above the
tool line, replaced by the final answer, then deleted.
Three gates my own changes broke:
- docs/channels/telegram.md needed a blank line before </Note>; I formatted the
TypeScript but never ran the docs formatter over the pages I edited.
- The mock harness matched a literal with a regex, which oxlint's prefer-includes
rejects.
- Widening resolveChannelPreviewStreamMode's defaultMode to StreamingMode and
adding rendersRollingLinesNatively changes the exported plugin-SDK surface, so
the API baseline hash had to be regenerated.
Proving headline-plus-tool-line composition needs assistant text emitted
*before* a tool call: that leading text is what gets tagged as commentary and
rendered as the draft's status headline. The mock could only echo a single token,
so the draft path was unreachable without a live model.
Trigger `OPENCLAW_E2E_DRAFTPROOF` now serves two turns — preamble plus a shell
call, then the final answer — on both /v1/responses and /v1/chat/completions.
Only the completions transport tags commentary today, which is why the
completions path matters here.
Used to record the draft live on real Telegram: one message carrying the
headline above the tool line, the final answer, then the draft edited to its
receipt.
Fail build and copy generators with ETIMEDOUT after 600000ms and terminate the complete managed process tree. Keep the timeout policy in the bundled-assets caller while preserving the shared helper for distinct callers such as #111349.
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* feat(cli): run agent exec against the ambient config, composed in memory
Exec previously ignored the operator's config entirely, so a one-shot turn
could not reach configured providers, credentials, or agentRuntime harness
selection. It now layers config the way other folder-scoped coding CLIs do.
The composed config is published as this process's runtime snapshot rather
than serialized to a temp file and re-read through OPENCLAW_CONFIG_PATH. The
snapshot is the only in-process config cache, so the file only ever fed it --
while writing env-substituted provider keys to disk where the run's own exec
tool could read them.
* fix(cli): resolve exec stored credentials from the configured agent dir
* chore(scripts): allow agent exec the file-scoped config loader at its process boundary
* test(cli): cover the exec credential default and pinned-config flags
* fix(scripts): keep format-docs output tails UTF-8 safe
When formatter (oxfmt) error output exceeds the 16 KiB tail cap and the
retained byte window starts inside a multibyte UTF-8 character, the
diagnostic tail would begin with a replacement character (�).
Add a decodeUtf8Tail helper that skips leading UTF-8 continuation bytes
before decoding the byte suffix, matching the existing pattern in
scripts/run-additional-boundary-checks.mjs (#109167).
Keep the existing 16 KiB cap and ASCII behavior unchanged.
* refactor(scripts): share UTF-8-safe output tails
Co-authored-by: 陈志强0668000989 <chen.zhiqiang1@xydigit.com>
* test(scripts): prove real formatter UTF-8 failures
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(e2e): bound Docker stats sample lines
* fix(e2e): format Docker stats line cap proof
* fix docker stats CRLF line cap
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(codex): restore connected apps for token-authenticated runs
* fix(codex): keep app inventory protocol types private
* fix(codex): align native runtime with Codex 0.146.0
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): clean up latest app-server integration
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): keep internal protocol types private
* fix(ci): repair current main Codex landing gates
* fix(ci): format inherited code mode matrix
* fix(codex): reconcile native app-server contracts with main
Prepare a verified GitHub-hosted mainline merge while preserving the reviewed Codex 0.146.0 fixes and canonical OpenAI authentication.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): keep QA evidence in its owning plugin
Resolve the current-main Code Mode test rename without resurrecting the retired core test path.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): enforce canonical OpenAI app-server auth
Reject retired provider aliases without runtime compatibility, direct operators to the doctor migration, and remove the redundant OpenAI API-key predicate.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* chore(codex): reconcile latest main dependency graph
Preserve current main dependency changes while preparing the original Codex PR for an ancestry-preserving signed mainline merge.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): unify bundled Codex 0.146 runtimes
Keep the ACP adapter on the same 0.146.0 Codex release as the managed runtime, remove obsolete 0.145.0 platform artifacts and unused semver compatibility, and preserve the latest main dependency upgrades.
Co-authored-by: Steven Lee <stevenlee@openai.com>
---------
Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(protocol): make Swift drift checks non-mutating
* test(protocol): cover core Swift gateway frames
* docs(protocol): clarify Swift model update flow
* docs(agents): standardize canonical record guards
* refactor(model-catalog): use canonical record guard
* refactor(scripts): use canonical record guard
* refactor(ui): use canonical record guard
* refactor(codex): use canonical record guard
* refactor(agents): use canonical record guard
* refactor(sessions): use canonical record guard
* refactor(doctor): use canonical record guard
* refactor(infra): use canonical record guard
* feat(ui): move settings save feedback to sidebar
* test(ui): support stateful config writes in mock gateway
* test(ui): add save indicator to memory sidebar test
* feat(config): require docs decisions for root settings
* feat(ui): link settings pages to guides
* refactor(ui): keep model providers page compact
* fix(ui): style page subtitles and carry base hints in mock dev