Nanobot

Nanobot patches shutdown, image hints and provider fallback at once

Nanobot has three open runtime corrections: bound MCP and exec cleanup to the live event loop, move Gemini Flash image hints onto the API’s accepted field, and fall back from incompatible Responses endpoints to Chat Completions. The common news is tighter contracts at three external boundaries.

← Back to homeOriginal source ↗

HKUDS/nanobot PR #5215 is the inspected primary source: “fix(gateway): close agent resources deterministically on stop.” The two related records below were inspected as supporting context, not treated as independent confirmation.

The facts

- HKUDS/nanobot PR #5215 was created 2026-08-02T20:12:29Z and was open at inspection; its title is “fix(gateway): close agent resources deterministically on stop.” - HKUDS/nanobot PR #5216 was created 2026-08-02T20:31:06Z and was open at inspection; its title is “fix(image): send Gemini Flash hints via generationConfig.imageConfig.” - HKUDS/nanobot PR #5214 was created 2026-08-02T19:34:11Z and was open at inspection; its title is “fix(providers): fall back to chat completions on serde body rejections.” - The repository reported 46520 stars, 778 open issues, default branch main, and last push 2026-08-02T15:25:22Z. - The latest tagged-release baseline checked was v0.3.0 published 2026-07-25T08:08:47Z.

What changed

HKUDS/nanobot PR #5215 reports: Problem Stopping the gateway while an exec session or MCP subprocess is still running produces asyncio teardown noise in the shutdown log and can stall the stop: The gateway's shutdown path never closes agent resources explicitly. It relies on the agent loop task's own finally to run close_mcp() when that task is cancelled, but when the service stops with an in-flight exec session or MCP subprocess, that path can be skipped or cut short. The subprocess transport then outlives the event loop and is garbage-collected after loop.close(), producing the error above. In the worst case the subprocess is orphaned and the stop drags on until systemd's timeout kills the whole cgroup. Change Call agent.close_mcp() from

HKUDS/nanobot PR #5216 reports: fix(image): send Gemini Flash hints via generationConfig.imageConfig Summary Gemini Flash image models (gemini-3.1-flash-lite-image, gemini-2.5-flash-image, and other generateContent-based image models) fail with HTTP 400 INVALID_ARGUMENT whenever an aspect ratio or image size hint is supplied. The provider sends these hints under generationConfig.responseFormat.image, a legacy block whose aspectRatio / imageSize fields are enum-based on the live v1beta API and reject plain-string values such as "16:9" or "1K" — even though those are the documented values. Root cause _generate_gemini_flash currently builds the request as: The live API rejects this payload with: The enum in question (google.ai.generativelanguage.v1beta.ImageResponseFormat.AspectRatio) only accepts values such as ASPECT_RATIO_SIXTEEN_BY_NINE (and ImageSize accepts IMAGE_SIZE_ONE_K), so the plain-string values the code sends are always rejected. A request

HKUDS/nanobot PR #5214 reports: Problem Conversations routed through the OpenAI Responses API can fail terminally when the endpoint rejects the request body with a serde-style deserialization error, for example: This was observed with DeepSeek's new Responses endpoint for deepseek-v4-flash: after context consolidation rewrites the conversation into a more compact shape, the endpoint intermittently rejected the request. _should_fallback_from_responses_error did not classify these messages as compatibility errors, so the failure was treated as terminal — the conversation ended instead of falling back to Chat Completions. Root cause The request body itself was valid: wire-serializing the conversation through the OpenAI SDK produces input as a JSON array in every shape tested (full history and the post-consolidation shape). The rejection is a server-side

Why it matters

These are different features but one operating problem: the runtime must decide what still owns cleanup, which wire schema a provider actually accepts, and when a compatibility failure is eligible for fallback instead of ending the conversation. The operational test is whether persisted state, execution authority and visible user outcome describe the same event. Broad retries, hidden suppression or permission expansion can hide the symptom while making the boundary less trustworthy.

Current

The primary record was open when captured on 2026-08-03. The release baseline was v0.3.0 published 2026-07-25T08:08:47Z. Current repository metadata, pull requests, issues, release records, Google News discovery, Hacker News discovery, Lobsters, Metamesh and the rendered ClawCharts HTML row were checked. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/HKUDS/nanobot/pull/5215. Supporting records are https://github.com/HKUDS/nanobot/pull/5216 and https://github.com/HKUDS/nanobot/pull/5214. Their source bodies, timestamps and states were captured in the daily evidence bundle. Test counts, reproductions and deployment observations remain attributed to their authors unless explicitly identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Issue closure would not by itself prove a deployed fix. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Keep cleanup time-bounded and idempotent, constrain fallback to deserialization signatures, and preserve model-specific image capability tests rather than broad provider guesses. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently after intervention.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.