Maintainer edit: keep capability-specific allowed_dir boundaries active even when the outer workspace scope is full access, and cover Dream plus ordinary full-access filesystem behavior.
maintainer edit: simplify the exact-file allowlist follow-up by removing unused read-side state and keeping the exact path helper private to workspace_policy.
maintainer edit: Dream write tools used file paths as directory roots, so a missing canonical memory file could be treated as a parent directory. Add exact-file allowlist support and keep skills/ as the only Dream write directory.
The shell safety guard in _guard_command() checked extracted absolute
paths only against cwd_path (the command's working directory). When
cwd was a subdirectory like ~/.nanobot/workspace/obsidian_notes, any
absolute path referencing the broader workspace (e.g. a sibling
directory or the workspace root itself) was incorrectly blocked with
"path outside working dir".
Fix: pass the workspace_root from _prepare_command() into
_guard_command() and check absolute paths against it as a fallback
when they are outside cwd_path. Paths truly outside the workspace
root are still blocked.
Added tests:
- test_exec_allows_workspace_paths_from_subdirectory
- test_exec_blocks_outside_paths_from_subdirectory
Maintainer edit: after #4314 moved shared tool config models to nanobot.config_base, keep FileToolsConfig on the new dependency boundary so the PR passes the architecture guard.
Maintainer edit: subagents rebuilt their scoped ToolsConfig without carrying tools.file, which re-enabled built-in file tools after the parent agent disabled them. Preserve the file config and add loader/subagent coverage for the disabled path.
maintainer edit: handle prompt sessions that report Connection closed outside McpError, and match reconnect registration prefixes with the same sanitization used by MCP wrapper names.
On Windows, cmd.exe /c treats newlines as command separators, silently
dropping code after the first line in `python -c "..."` commands. This
causes multi-line inline Python to produce no output with exit code 0.
Detect multi-line `python -c` commands on Windows, parse them into exec
args via `_split_python_c_args`, and use `create_subprocess_exec` to
bypass cmd.exe entirely. Same principle as Codex's Rust `Command::args()`.
Applied to both the direct execution path and the session spawn path.
Added unit tests for the parser and the exec-vs-shell branching logic.
Replace asyncio.sleep(0.05) with an asyncio.Event + patched Lock.acquire
to guarantee the waiting task has reached the lock before asserting. Add
a test confirming LongTaskTool and CompleteGoalTool ContextVars are
isolated, and document the design intent in _GoalToolsMixin.
Add two new image generation providers:
- `openai` — uses the standalone OpenAI Images API
(`/v1/images/generations`) with an API key. Supports DALL-E
and gpt-image-* models, with automatic parameter adjustment
(gpt-image models don't accept response_format or n).
- `openai_codex` — uses the Codex Responses API with the
`image_generation` tool, authenticated via OAuth subscription
token. The same mechanism ChatGPT uses internally.
Also remove the API key pre-check in ImageGenerationTool so
providers that handle their own auth fallback (like Codex OAuth)
can work without a configured key.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Drop the legacy unified-diff patch parameter and all related parsing/
generation logic (_parse_patch, _generate_patch, _apply_hunks, etc.).
The tool now accepts only the structured `edits` array, eliminating the
intermediate diff-string round-trip.
Also update file_edit_events tracking and tests to work exclusively
with edits.
Benchmark (zhipu glm-5.1, edits mode): 15/15 cases passed.