fix(image): deprecate legacy skill and clarify auth#52552
Conversation
Greptile SummaryThis PR deprecates the bundled
Confidence Score: 5/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: docs/gateway/configuration-reference.md
Line: 907-910
Comment:
**Duplicate "Typical values" bullet**
The new auth hint was inserted between two pre-existing "Typical values" sub-bullets that both list the same three examples. The second one (line 910) is now redundant and can be removed to avoid confusing readers.
```suggestion
- Typical values: `google/gemini-3-pro-image-preview` for the native Nano Banana-style flow, `fal/fal-ai/flux/dev` for fal, or `openai/gpt-image-1` for OpenAI Images.
- If you select a provider/model directly, configure the matching provider auth/API key too (for example `GEMINI_API_KEY` or `GOOGLE_API_KEY` for `google/*`, `OPENAI_API_KEY` for `openai/*`, `FAL_KEY` for `fal/*`).
- If omitted, `image_generate` can still infer a best-effort provider default from compatible auth-backed image-generation providers.
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "Merge branch 'main' into vincentkoc-code..." | Re-trigger Greptile |
1fa023c to
2e9034e
Compare
|
Landed via temp rebase onto main. Thanks @vincentkoc! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e9034e225
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| python3 {baseDir}/scripts/gen.py --size 1536x1024 --quality high --out-dir ./out/images | ||
| python3 {baseDir}/scripts/gen.py --model gpt-image-1.5 --background transparent --output-format webp | ||
|
|
||
| # DALL-E 3 (note: count is automatically limited to 1) | ||
| python3 {baseDir}/scripts/gen.py --model dall-e-3 --quality hd --size 1792x1024 --style vivid |
There was a problem hiding this comment.
Preserve OpenAI-only image flows before removing the legacy skill
Deleting this skill removes the only bundled path that supported OpenAI-specific image workflows such as transparent/WebP output and DALL-E 3 sizes/styles. The advertised replacement cannot reproduce those cases today: src/agents/tools/image-generate-tool.ts:56-108 exposes no background, output-format, style, or quality inputs and caps count at 4; src/agents/tools/image-generate-tool.ts:307-316 rejects OpenAI sizes outside the provider geometry; and extensions/openai/image-generation-provider.ts:43-101 only forwards { model, prompt, n, size } with 1024x1024|1024x1536|1536x1024. Users following the migration will lose working scenarios like dall-e-3 --size 1792x1024 --style vivid or gpt-image-1.5 --background transparent --output-format webp.
Useful? React with 👍 / 👎.
* fix(delivery-queue): increment retryCount on deferred entries when time budget exceeded When delivery recovery ran out of the 60s time budget, remaining pending entries were silently deferred to the next restart with no retryCount increment. This caused them to loop forever across restarts, never hitting MAX_RETRIES and never moving to failed/. Fix: call failDelivery() on each remaining entry before breaking out of the recovery loop (both the deadline check and the backoff-exceeds-deadline check). This increments retryCount so that entries eventually exhaust MAX_RETRIES and are permanently skipped. Fixes openclaw#24353 * fix(delivery-queue): break immediately on deadline instead of failing all remaining entries P1-C: After now >= deadline, the old code would iterate all remaining queue entries and call failDelivery() on each — O(n) work that nullified the maxRecoveryMs wall-clock cap on large queues. Fix: break out of the recovery loop immediately when the deadline is exceeded. Remaining entries are picked up on next startup unchanged (retryCount not incremented). The deadline means 'stop here', not 'fail everything remaining'. * fix(delivery-queue): align test assertion and JSDoc with 'next startup' log message * fix(browser): add ChildProcessWithoutNullStreams cast for @types/node compat The stdio tuple overload resolves differently across @types/node versions (v20 vs v24/v25). Cast the spawn() result to ChildProcessWithoutNullStreams to ensure proc.stderr?.on/off type-checks regardless of installed @types/node. * test(delivery-queue): align test assertion with 'next startup' log message * fix(delivery-queue): increment retryCount on deadline-deferred entries Codex P1: entries deferred by the recovery time budget kept retryCount=0 forever, so they could loop across restarts without ever reaching MAX_RETRIES. After breaking on deadline, call failDelivery() for all remaining entries so retryCount is incremented. Entries stay in queue until MAX_RETRIES is reached and they are pruned normally. Also updates the maxRecoveryMs test to assert retryCount=1 on deferred entries. * fix(ci): restore delivery queue branch checks * fix(plugins): make metadata generator formatter portable * fix(image): deprecate legacy skill and clarify auth * docs(image): remove duplicate typical values bullet * fix: harden image auth env lookups (openclaw#52552) (thanks @vincentkoc) * test(mattermost): cover directory discovery * test(msteams): cover store and live directory helpers * fix(mattermost): honor replyToMode off for threaded messages * perf(reply): lazy-load runner execution and memory * fix(plugins): remove metadata generator conflict markers * test(nextcloud-talk): cover inbound behavior branches * test(irc): cover inbound behavior branches * test: slim outbound test import graphs * perf: remove remaining unit thread pins * perf(reply): lazy-load usage cost resolution * test(googlechat): cover security normalization * perf(reply): lazy-load context token lookup * style(format): fix extension test drift * test: centralize cli runtime capture helpers * refactor: reuse shared cli runtime test mocks * fix: restore bundled plugin metadata generator * fix(telegram): add allow_sending_without_reply to prevent lost messages When a Telegram message that OpenClaw is replying to gets deleted before delivery, the Telegram API rejects the entire sendMessage call with "message to be replied not found". This causes the bot's response to be silently lost and stuck in the failed delivery queue permanently. Setting allow_sending_without_reply: true tells Telegram to deliver the message as a standalone message if the reply target no longer exists, instead of failing the entire request. Applied to all 6 locations across 4 source files where reply_to_message_id is set: - send.ts: buildTelegramReplyParams (both reply_parameters and plain reply) - bot/delivery.send.ts: buildTelegramSendParams - draft-stream.ts: draft stream reply params - bot-handlers.runtime.ts: error reply messages (file too large, media download failed) Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix(telegram): update test expectations for allow_sending_without_reply Update exact-match test assertions in send.test.ts to include the new allow_sending_without_reply: true parameter. Tests using objectContaining already pass, but several tests use exact object matching. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix: finish telegram reply fallback landing (openclaw#52524) (thanks @moltbot886) * refactor: extract single-provider plugin entry helper * refactor: add provider onboarding preset appliers * refactor: share parsed channel allowlist prompts * refactor: share channel setup status helpers * fix: export provider-entry plugin sdk subpath * style: format plugin sdk helper updates * fix(docs): code-verified fixes from deep reference audit - sdk-runtime.md: add missing required params (runId, timeoutMs) to runEmbeddedPiAgent example - sdk-provider-plugins.md: add missing onModelSelected hook (openclaw#22), clarify capabilities is data not callable, drop misleading '21' count * test: fix googlechat security typing drift * perf: remove stale unit isolated entry * refactor(outbound): split delivery queue storage and recovery * fix(docs): remaining code audit fixes - sdk-entrypoints.md: fix mislabeled 'Channel entry options' heading (should be 'Options' — these are definePluginEntry options, not channel-specific) - sdk-overview.md: add 4 missing API object fields (version, description, source, rootDir) from OpenClawPluginApi type * perf(reply): split usage line helpers * perf(reply): narrow queue imports * test(msteams): cover graph helpers * test(msteams): cover upload and webhook helpers * refactor: harden generated-file guards and provider ids * fix: restore main gate after type updates * fix(plugins): accept media-understanding id hints * test: default scoped vitest configs to no-isolate * test(msteams): cover poll and file-card helpers * test: fix provider config typing drift * perf: default channel vitest lanes to threads * perf(reply): lazy-load media path normalization * style(format): fix msteams test drift * refactor(plugins): move remaining channel and provider ownership out of src * refactor(plugins): finish provider and whatsapp cleanup * fix(gateway): pass process.env in status command probe auth to resolve SecretRef Fixes openclaw#52360 resolveGatewayProbeAuthSafe was called from status-all.ts without an env argument, causing the credential resolution chain to fall back to an empty object instead of process.env. This made env-backed SecretRef tokens (gateway.auth.token, Telegram botToken, etc.) appear unresolved in the status command path even when the runtime was healthy. Added process.env as default fallback in buildGatewayProbeCredentialPolicy and passed env explicitly from status-all.ts callers. Related: openclaw#33070, openclaw#38973, openclaw#39415, openclaw#46014, openclaw#49730 * fix(status): resolve only selected probe-auth branch and fix plain status path Address two Codex P1/P2 issues: 1. (P1) Plain 'openclaw status' and 'openclaw status --json' still went through the sync resolveGatewayProbeAuthSafe path in status.gateway-probe.ts, which cannot expand SecretRef objects. Switched to async resolveGatewayProbeAuthSafeWithSecretInputs. 2. (P2) status-all.ts was eagerly resolving both local and remote probe auth before deciding which to use. A stale SecretRef in the unused branch could abort the command. Collapsed to a single resolution call using the correct mode upfront. Updated status.scan.test.ts to use mockResolvedValue since resolveGatewayProbeAuthResolution is now async. * fix(status): await resolveGatewayProbeAuthResolution in scan.shared Function is now async after switching to resolveGatewayProbeAuthSafeWithSecretInputs. Missing await caused TS error: Property 'auth' does not exist on type 'Promise<...>'. * fix: finish gateway probe auth landing (openclaw#52513) (thanks @CodeForgeNet) * fix: finish gateway probe auth landing (openclaw#52513) (thanks @CodeForgeNet) * test: clear msteams gate drift for gateway probe auth landing (openclaw#52513) (thanks @CodeForgeNet) * fix(exec): return plain-text tool result on failure instead of raw JSON When an exec command fails (e.g. timeout), the tool previously rejected with an Error, which the tool adapter caught and wrapped in a JSON object ({ status, tool, error }). The model then received this raw JSON as the tool result and could parrot it verbatim to the user. Now exec failures resolve with a proper tool result containing the error as human-readable text in content[], matching the success path structure. The model sees plain text it can naturally incorporate into its reply. Also fixes a pre-existing format issue in update-cli.test.ts. Fixes openclaw#52484 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix: finish exec tool failure landing (openclaw#52508) (thanks @martingarramon) * fix(openshell): bundle upstream cli fallback * perf(reply): lazy-load session store writes * fix(build): restore plugin-sdk and line compat after refactor * refactor(kilocode): route shared model constants through core seam * refactor(plugin-sdk): route core provider and telegram seams through sdk barrels * fix(acp): preserve hidden thought chunks from gateway chat * fix(docs): rename 'Channel Options' to 'Options' in sdk-entrypoints This heading labels definePluginEntry options (generic, not channel-specific). Another agent reverted the previous fix during a merge. * fix(line): narrow plugin-sdk seams after refactor * test(voice-call): cover helper utilities * test(voice-call): cover manager and api helpers * fix(acp): preserve hidden thought replay on session load * test(voice-call): cover twilio and reaper helpers * docs(changelog): note ACP hidden thought replay fix * test(voice-call): cover utility and tailscale helpers * fix(ci): resync generated baselines and line runtime seam * fix(docs): remove duplicate '### Options' headings (MD024) * fix(ci): restore plugin manifests and boundary tests * style(docs): format sdk entrypoints doc * docs(config): refresh generated baseline * test(voice-call): cover outbound call flow helpers * fix(ci): repair tts and matrix refactor fallout * fix(ci): repair voice-call typing and provider contracts * fix(ci): satisfy voice-call typing and extension boundaries * Remove personal references from docs (openclaw#25260) * docs: remove personal references from AGENTS.md * docs: remove personal reference from sag skill * docs: note generic agent guidance cleanup * Update CHANGELOG.md --------- Co-authored-by: Josh Lehman <[email protected]> Co-authored-by: Vincent Koc <[email protected]> * fix(plugins): route keyed queue imports through core (openclaw#52608) * fix(matrix): preserve send aliases and voice intent * fix(build): repair stale plugin sdk surfaces * fix(plugin-sdk): export line runtime subpath * fix(auth): route copilot login through sdk seam * feat(web-search): add bundled Exa plugin (openclaw#52617) * test(msteams): await async setup status lines * fix(whatsapp): remove outbound runtime cycle * fix(plugin-sdk): fast-path root diagnostic subscriptions * fix(exa): align freshness typing and config docs * fix(matrix): avoid touching dropped room bindings * fix(web-search): align Exa plugin with current API * docs(tools): add DuckDuckGo Search provider page New page: tools/duckduckgo-search.md - Key-free fallback provider, no API key needed - Clear Warning about unofficial HTML-based integration - Limitations section covering bot-challenge risk and reliability - CardGroup showing good-for vs not-recommended-for use cases Updated: tools/web.md with DuckDuckGo in CardGroup and comparison table Updated: docs.json nav and redirect * test(telegram): align webhook grammy mock * docs(tools): add Exa Search page, align all search provider docs New page: tools/exa-search.md - Neural/keyword/hybrid search modes with content extraction - Tool parameters including contents (highlights, text, summary) - Search mode reference table Rewritten: tools/duckduckgo-search.md - Aligned to consistent template (Setup, Config, Tool parameters, Notes, Related) - Simplified from previous version Aligned across all providers: - Every search page now ends with a consistent ## Related section - Replaced 'See [Web tools]' with proper Related links - Added Exa + DuckDuckGo to web.md overview CardGroup and comparison table - Added Exa to docs.json nav and redirects * fix(telegram): inject media loader through bot deps * fix(ci): harden telegram seams and cap job timeouts * docs(tools): update Exa Search notes for current API behavior Add notes about default highlights contents, highlightScores/summary preservation from responses, description resolution order, and 100-result cap. * perf: add vitest test perf workflows * fix(ci): harden changed extension diff fallback * fix(telegram): harden grammy seams across tests * refactor: extract exec outcome and tool result helpers * test: isolate exec foreground failure coverage * fix(test): allow empty extension lane * perf: enable vitest fs module cache by default * fix(cli): route plugin logs to stderr during --json output * fix(cli): route deferred plugin logs to stderr in status --json * fix: keep status --json stdout clean (openclaw#52449) (thanks @cgdusek) * refactor(ci): collapse fast setup jobs into preflight * fix(exec): accept runtime failure kind in formatter * fix: include .env file vars in gateway service environment on install When building the gateway install plan, read and parse ~/.openclaw/.env (or $OPENCLAW_STATE_DIR/.env) and merge those key-value pairs into the service environment at the lowest priority — below config env vars, auth-profile refs, and the core service environment (HOME, PATH, OPENCLAW_*). This ensures that user-defined secrets stored in .env (e.g. BRAVE_API_KEY, OPENROUTER_API_KEY, DISCORD_BOT_TOKEN) are embedded in the LaunchAgent plist (macOS), systemd unit (Linux), and Scheduled Task (Windows) at install time, rather than relying solely on the gateway process loading them via dotenv.config() at startup. Previously, on macOS the LaunchAgent plist never included .env vars, which meant: - launchctl print did not show user secrets (hard to debug) - Child processes spawned before dotenv loaded had no access - If the same key existed in both .env and the plist, the stale plist value won via dotenv override:false semantics Dangerous host env vars (NODE_OPTIONS, LD_PRELOAD, etc.) are filtered using the same security policy applied to config env vars. Fixes openclaw#37101 Relates to openclaw#22663 * fix: normalize env var keys and isolate tests from real .env - Apply normalizeEnvVarKey({ portable: true }) before security filtering, matching the established pattern in env-vars.ts. Rejects non-portable key names (spaces, special chars) that would produce invalid plist/systemd syntax. - Isolate existing tests from the developer's real ~/.openclaw/.env by providing a temp HOME directory, preventing flaky failures when the test machine has a populated .env file. * fix: narrow exec exit failure kind typing * fix(test): isolate flaky extension lanes * feat(web-search): add DuckDuckGo bundled plugin (openclaw#52629) * feat(web-search): add DuckDuckGo bundled plugin * chore(changelog): restore main changelog * fix(web-search): harden DuckDuckGo challenge detection * refactor: split durable service env helpers * refactor: extract gateway install token helpers * fix(web-search): mark DuckDuckGo experimental * docs(tools): update DuckDuckGo Search for landed plugin code - Mark as experimental (not just unofficial) - Add region and safeSearch tool parameters (from DDG schema) - Add plugin config example for region/safeSearch defaults - Document auto-detection order (100 = last) - Note SafeSearch defaults to moderate - Verified against extensions/duckduckgo/src/ * fix(agents): deny local MEDIA paths for MCP results * Usage: include reset and deleted session archives (openclaw#43215) Merged via squash. Prepared head SHA: 49ed6c2 Co-authored-by: rcrick <[email protected]> Co-authored-by: frankekn <[email protected]> Reviewed-by: @frankekn * docs(tools): soften DDG wording (scrapes -> pulls/gathers) * fix(build): add stable memory-cli dist entry (openclaw#51759) Co-authored-by: oliviareid-svg <[email protected]> Co-authored-by: Frank <[email protected]> * refactor!: drop legacy CLAWDBOT env compatibility * refactor!: remove moltbot state-dir migration fallback * fix(gateway): preserve async hook ingress provenance * fix(ci): write dist build stamp after builds * perf: trim vitest hot imports and refresh manifests * fix(security): unwrap time dispatch wrappers * fix(plugin-sdk): fall back to src root alias files * fix(ci): skip docs-only preflight pnpm audit * docs(changelog): note time exec approval fix * docs: refresh plugin-sdk api baseline * fix(runtime): make dist-runtime staging idempotent * fix(media): bound remote error-body snippet reads * fix(gateway): gate internal command persistence mutations * fix: restrict remote marketplace plugin sources * fix(runtime): skip peer resolution for bundled plugin deps * docs(agents): prefer current test model examples * fix(exec): escape invisible approval filler chars * test(models): refresh example model fixtures * fix(security): unify dispatch wrapper approval hardening * fix(security): harden explicit-proxy SSRF pinning * fix: gate synology chat reply name matching * docs: clarify sessions_spawn ACP vs subagent policies * refactor(exec): split wrapper resolution modules * refactor(exec): make dispatch wrapper semantics spec-driven * refactor(exec): share wrapper trust planning * refactor(exec): rename wrapper plans for trust semantics * fix: include .npmrc in onboard docker build * test: trim docker live auth mounts * Docs: refresh config baseline for Synology Chat * refactor: clarify synology delivery identity names * refactor: centralize synology dangerous name matching * refactor: narrow synology legacy name lookup * refactor: audit synology dangerous name matching * refactor: dedupe synology config schema * fix: normalize scoped vitest filter paths * fix(voice-call): harden webhook pre-auth guards * fix(synology-chat): fail closed shared webhook paths * docs: credit nexrin in synology changelog * test: fix base vitest thread regressions * test: finish base vitest thread fixture fixes * test(voice-call): accept oversize webhook socket resets * test: honor env auth in gateway live probes * fix: harden plugin docker e2e * Docs: align MiniMax examples with M2.7 * fix(ci): restore stale guardrails and baselines * Test: isolate qr dashboard integration suite * Gateway: resolve fallback plugin context lazily * fix: bind bootstrap setup codes to node profile * fix(tlon): unify settings reconciliation semantics * refactor(synology-chat): type startup webhook path policy * docs(synology-chat): clarify multi-account webhook paths * refactor: unify minimax model and failover live policies * docs: sync minimax m2.7 references * fix: harden Windows Parallels smoke installs * docs: reorder unreleased changelog by user impact * refactor: remove embedded runner cwd mutation * Infra: support shell carrier allow-always approvals * refactor: centralize bootstrap profile handling * refactor: reuse canonical setup bootstrap profile * fix(plugin-sdk): resolve hashed diagnostic events chunks * fix(plugin-sdk): normalize hashed diagnostic event exports * test: fix ci env-sensitive assertions * fix(gateway): fail closed on unresolved discovery endpoints * feat: add slash plugin installs * fix(media): block remote-host file URLs in loaders * fix(media): harden secondary local path seams * test: harden no-isolate reply teardown * docs(changelog): add Windows media security fix * refactor(gateway): centralize discovery target handling * test: narrow live transcript scaffolding strip * test: fix ci docs drift and bun qr exit handling * fix(browser): enforce node browser proxy allowProfiles * refactor(media): share local file access guards * test: stabilize ci test harnesses * test: harden no-isolate test module resets * fix(plugins): preserve live hook registry during gateway runs * test: fix channel summary registry setup * test: harden isolated test mocks * chore(plugins): remove opik investigation checkpoints * ACPX: align pinned runtime version (openclaw#52730) * ACPX: align pinned runtime version * ACPX: drop version example from help text * test: stop leaking image workspace temp dirs * fix(android): gate canvas bridge to trusted pages (openclaw#52722) * fix(android): gate canvas bridge to trusted pages * fix(changelog): note android canvas bridge gating * Update apps/android/app/src/main/java/ai/openclaw/app/node/CanvasActionTrust.kt Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(android): snapshot canvas URL on UI thread --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * test: isolate base vitest thread blockers * fix: sync agent and autoreply e2e updates * test: harden no-isolate mocked module resets * docs: reorder unreleased changelog * fix(changelog): note windows media path guardrails (openclaw#52738) * fix: alphabetize web search provider listings * docs: clarify unreleased breaking changes * test: harden ci isolated mocks * fix: align websocket stream fallback types * test: finish no-isolate suite hardening * style: format image-generation runtime tests * fix(memory-core): register memory tools independently to prevent coupled failure (openclaw#52668) Merged via admin squash because current required CI failures are inherited from base and match latest `main` failures outside this PR's `memory-core` surface. Prepared head SHA: df7f968 Co-authored-by: artwalker <[email protected]> Reviewed-by: @frankekn * fix(status): recompute fallback context window (openclaw#51795) * fix(status): recompute fallback context window * fix(status): keep live context token caps on fallback * fix(status): preserve fallback runtime context windows * fix(status): preserve configured fallback context caps * fix(status): keep provider-aware transcript context lookups * fix(status): preserve explicit fallback context caps * fix(status): clamp fallback configured context caps * fix(status): keep raw runtime slash ids * fix(status): refresh plugin-sdk api baseline * fix(status): preserve fallback context lookup * test(status): refresh plugin-sdk api baseline * fix(status): keep runtime slash-id context lookup --------- Co-authored-by: create <[email protected]> Co-authored-by: Frank Yang <[email protected]> Co-authored-by: RichardCao <[email protected]> * fix(telegram): make buttons schema optional in message tool The Telegram plugin injects a `buttons` property into the message tool schema via `createMessageToolButtonsSchema()`, but without wrapping it in `Type.Optional()`. This causes TypeBox to include `buttons` in the JSON Schema `required` array. In isolated sessions (e.g. cron jobs) where no `currentChannel` is set, all plugin schemas are merged into the message tool. When the LLM calls the message tool without a `buttons` parameter, AJV validation fails with: `buttons: must have required property 'buttons'`. Wrap the buttons schema in `Type.Optional()` so it is not required. * fix: keep message-tool buttons optional for Telegram and Mattermost (openclaw#52589) (thanks @tylerliu612) * test: update codex test fixtures to gpt-5.4 * fix: repair runtime seams after rebase * fix: restore Telegram topic announce delivery (openclaw#51688) (thanks @mvanhorn) When `replyLike.text` or `replyLike.caption` is an unexpected non-string value (edge case from some Telegram API responses), the reply body was coerced to "[object Object]" via string concatenation. Add a `typeof === "string"` guard to gracefully fall back to empty string, matching the existing pattern used for `quoteText` in the same function. Co-authored-by: Penchan <[email protected]> * docs: sync generated release baselines * test: isolate pi embedded model thread fixtures * fix: restore provider runtime lazy boundary * fix: preserve Telegram reply context text (openclaw#50500) (thanks @p3nchan) * fix: guard Telegram reply context text (openclaw#50500) (thanks @p3nchan) * fix: preserve Telegram reply caption fallback (openclaw#50500) (thanks @p3nchan) --------- Co-authored-by: Ayaan Zaidi <[email protected]> * fix: harden gateway SIGTERM shutdown (openclaw#51242) (thanks @juliabush) * fix: increase shutdown timeout to avoid SIGTERM hang * fix(telegram): abort polling fetch on shutdown to prevent SIGTERM hang * fix(gateway): enforce hard exit on shutdown timeout for SIGTERM * fix: tighten gateway shutdown watchdog * fix: harden gateway SIGTERM shutdown (openclaw#51242) (thanks @juliabush) --------- Co-authored-by: Ayaan Zaidi <[email protected]> * build: prepare 2026.3.22-beta.1 * fix: restore provider runtime lazy boundary * test: add parallels npm update smoke * test: split pi embedded model thread fixtures * fix: stop browser server tests from launching real chrome * test: stabilize live provider docker probes * fix: restart windows gateway after npm update * test: isolate server-context browser harness imports * test: inject model runtime hooks for thread-safe tests * test: snapshot ci timeout investigation * test: target gemini 3.1 flash alias * test: stabilize trigger handling and hook e2e tests * build: prepare 2026.3.22 --------- Co-authored-by: Stephen Schoettler <[email protected]> Co-authored-by: Peter Steinberger <[email protected]> Co-authored-by: Vincent Koc <[email protected]> Co-authored-by: create <[email protected]> Co-authored-by: moltbot886 <[email protected]> Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: CodeForgeNet <[email protected]> Co-authored-by: Martin Garramon <[email protected]> Co-authored-by: François Martin <[email protected]> Co-authored-by: Josh Lehman <[email protected]> Co-authored-by: Charles Dusek <[email protected]> Co-authored-by: Kevin ONeill <[email protected]> Co-authored-by: Rick_Xu <[email protected]> Co-authored-by: rcrick <[email protected]> Co-authored-by: frankekn <[email protected]> Co-authored-by: oliviareid-svg <[email protected]> Co-authored-by: oliviareid-svg <[email protected]> Co-authored-by: Frank <[email protected]> Co-authored-by: scoootscooob <[email protected]> Co-authored-by: ruochen <[email protected]> Co-authored-by: Onur Solmaz <[email protected]> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Frank Yang <[email protected]> Co-authored-by: artwalker <[email protected]> Co-authored-by: RichardCao <[email protected]> Co-authored-by: RichardCao <[email protected]> Co-authored-by: liuyang <[email protected]> Co-authored-by: Ayaan Zaidi <[email protected]> Co-authored-by: Matt Van Horn <[email protected]> Co-authored-by: Penchan <[email protected]> Co-authored-by: Penchan <[email protected]> Co-authored-by: Julia Bush <[email protected]>
Summary
openai-image-genskill alongside the nativeimageandimage_generatepaths, and the native image-generation flow did not clearly tell users which provider auth they needed.openai-image-genskill, added provider-auth hints toimage_generate list, improved the no-config runtime error for image generation, and tightened the image docs around the native tool path.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
skills/openai-image-gensample workflow so native image work now points atimageandimage_generate.image_generate action="list"now shows auth env vars for each provider.agents.defaults.imageGenerationModel.primaryand show matching provider auth hints.openai/*,google/*,fal/*, or another provider-specific image model also requires that provider's auth/API key.Security Impact (required)
Yes, explain risk + mitigation:Repro + Verification
Environment
agents.defaults.imageGenerationModel, provider env vars such asGEMINI_API_KEY,OPENAI_API_KEY,FAL_KEYSteps
agents.defaults.imageGenerationModeland inspect the image-generation runtime failure path.image_generatewithaction="list"and inspect provider/model output.Expected
Actual
Evidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
image/image_generateregistration path, the image-generation runtime error path, and the bundled skill inventory; checked the resulting diff andgit diff --check.image_generate listwith provider auth hints, no configured image-generation model, CI skill-path regression after deleting the bundled Python skill.pnpm build,pnpm test, or runtime tool execution in this shell becausenode,pnpm,bun, andcorepackare unavailable here.Review Conversations
If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.
Compatibility / Migration
openai-image-genskill.imagefor analysis andimage_generatefor generation/editing.agents.defaults.imageGenerationModel.primary.image_generate action="list".Failure Recovery (if this breaks)
skills/openai-image-gen/*,src/agents/tools/image-generate-tool.ts,src/image-generation/runtime.ts, touched docs.image_generate list, or weaker error guidance when no image-generation model is configured.Risks and Mitigations
openai-image-gensample workflow lose that bundled entry point.