Commit Graph
45 Commits
Author SHA1 Message Date
chengyongruandXubin Ren b51da93cbb feat(agent): add SelfTool for runtime self-inspection and configuration
Add a built-in tool that lets the agent inspect and modify its own
runtime state (model, iterations, context window, etc.).

Key features:
- inspect: view current config, usage stats, and subagent status
- modify: adjust parameters at runtime (protected by type/range validation)
- Subagent observability: inspect running subagent tasks (phase,
  iteration, tool events, errors) — subagents are no longer a black box
- Watchdog corrects out-of-bounds values on each iteration
- Enabled by default in read-only mode (self_modify: false)
- All changes are in-memory only; restart restores defaults
- Comprehensive test suite (90 tests)

Includes a self-awareness skill (always-on) with progressive disclosure:
SKILL.md for core rules, references/examples.md for detailed scenarios.
2026-04-16 23:44:26 +08:00
1304ff78cc perf(tools): cache ToolRegistry.get_definitions() between mutations
get_definitions() sorts tools on every LLM iteration for prompt cache
stability.  Cache the sorted result and invalidate on register/unregister
so the sort only runs when the tool set actually changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 21:52:36 +08:00
yeyitechandXubin Ren ee061f0595 fix(web): serialize duckduckgo search calls 2026-04-14 14:10:06 +08:00
Xubin RenandXubin Ren 49355b2bd6 test(tools): lock non-object parameter validation
Add focused registry coverage so the new read_file/read_write parameter guard stays actionable without changing generic validation behavior for other tools.

Made-with: Cursor
2026-04-13 09:55:05 +08:00
haosenwang1018andXubin Ren 92ef594b6a fix(mcp): hint on stdio protocol pollution 2026-04-13 09:41:55 +08:00
Xubin RenandXubin Ren 5dc238c7ef fix(shell): allow read-only copies from internal state files
Keep the new exec guard focused on writes to history.jsonl and .dream_cursor while still allowing read-only copy operations out of those files.

Made-with: Cursor
2026-04-12 16:38:55 +08:00
04cbandXubin Ren 3f59bd1443 fix(shell): reject LLM-supplied working_dir outside workspace (#2826) 2026-04-12 16:38:55 +08:00
04cbandXubin Ren 00fb491bc9 fix(shell): block exec writes to history.jsonl and cursor files (#2989) 2026-04-12 16:38:55 +08:00
Xubin Ren 09c238ca0f Merge origin/main into pr-2959
Resolve the config plumbing conflicts and keep disabled skill filtering consistent for subagent prompts after syncing with main.

Made-with: Cursor
2026-04-12 02:02:39 +00:00
Xubin RenandXubin Ren cf8381f517 feat(agent): enhance message injection handling and content merging 2026-04-11 21:43:23 +08:00
chengyongruandXubin Ren 36d2a11e73 feat(agent): mid-turn message injection for responsive follow-ups (#2985)
* feat(agent): add mid-turn message injection for responsive follow-ups

Allow user messages sent during an active agent turn to be injected
into the running LLM context instead of being queued behind a
per-session lock. Inspired by Claude Code's mid-turn queue drain
mechanism (query.ts:1547-1643).

Key design decisions:
- Messages are injected as natural user messages between iterations,
  no tool cancellation or special system prompt needed
- Two drain checkpoints: after tool execution and after final LLM
  response ("last-mile" to prevent dropping late arrivals)
- Bounded by MAX_INJECTION_CYCLES (5) to prevent consuming the
  iteration budget on rapid follow-ups
- had_injections flag bypasses _sent_in_turn suppression so follow-up
  responses are always delivered

Closes #1609

* fix(agent): harden mid-turn injection with streaming fix, bounded queue, and message safety

- Fix streaming protocol violation: Checkpoint 2 now checks for injections
  BEFORE calling on_stream_end, passing resuming=True when injections found
  so streaming channels (Feishu) don't prematurely finalize the card
- Bound pending queue to maxsize=20 with QueueFull handling
- Add warning log when injection batch exceeds _MAX_INJECTIONS_PER_TURN
- Re-publish leftover queue messages to bus in _dispatch finally block to
  prevent silent message loss on early exit (max_iterations, tool_error, cancel)
- Fix PEP 8 blank line before dataclass and logger.info indentation
- Add 12 new tests covering drain, checkpoints, cycle cap, queue routing,
  cleanup, and leftover re-publish
2026-04-11 21:43:23 +08:00
Xubin RenandGitHub e0b9edf985 Merge PR #3017: feat(tool): improve file editing and add notebook tool
feat(tool): improve file editing and add notebook tool
2026-04-11 18:02:25 +08:00
Xubin Ren 322142f7ad Merge origin/main into main 2026-04-11 09:32:05 +00:00
Xubin RenandXubin Ren b959ae6d89 test(web): cover Kagi search provider
Add focused coverage for the Kagi web search provider, including the request format and the DuckDuckGo fallback when no API key is configured.
2026-04-11 16:53:05 +08:00
worenidewen a167959027 fix(mcp): support multiple MCP servers by connecting each in isolated task
Each MCP server now connects in its own asyncio.Task to isolate anyio
cancel scopes and prevent 'exit cancel scope in different task' errors
when multiple servers (especially mixed transport types) are configured.

Changes:
- connect_mcp_servers() returns dict[str, AsyncExitStack] instead of None
- Each server runs in separate task via asyncio.gather()
- AgentLoop uses _mcp_stacks dict to track per-server stacks
- Tests updated to handle new API
2026-04-10 23:51:50 +08:00
Xubin Ren 651aeae656 improve file editing and add notebook tool
Enhance file tools with read tracking, PDF support, safer path handling,
smarter edit matching/diagnostics, and introduce notebook_edit with tests.
2026-04-10 15:44:50 +00:00
chenyahuiandXubin Ren 0e6331b66d feat(exec): support allowed_env_keys to pass specified env vars to subprocess
Add allowed_env_keys config field to selectively forward host environment variables (e.g. GOPATH, JAVA_HOME) into the sandboxed subprocess environment, while keeping the default allow-list unchanged.
2026-04-09 23:35:44 +08:00
yanghan-cyberandXubin Ren 10f6c875a5 fix(agent): deliver LLM errors to streaming channels and avoid polluting session context
When the LLM returns an error (e.g. 429 quota exceeded, stream timeout),
streaming channels silently drop the error message because `_streamed=True`
is set in metadata even though no content was actually streamed.

This change:
- Skips setting `_streamed` when stop_reason is "error", so error messages
  go through the normal channel.send() path and reach the user
- Stops appending error content to session history, preventing error
  messages from polluting subsequent conversation context
- Exposes stop_reason from _run_agent_loop to enable the above check
2026-04-09 23:10:46 +08:00
chenspandXubin Ren bfec06a2c1 Fix Windows exec env for Docker Desktop plugin discovery
nanobot's Windows exec environment was not forwarding ProgramFiles and related variables, so docker desktop start could not discover the desktop CLI plugin and reported unknown command. Forward the missing variables and add a regression test that covers the Windows env shape.
2026-04-09 10:55:53 +08:00
Xubin RenandXubin Ren ef0284a4e0 fix(exec): add Windows support for shell command execution
ExecTool hardcoded bash, breaking exec on Windows. Now uses cmd.exe
via COMSPEC on Windows with a curated minimal env (PATH, SYSTEMROOT,
etc.) that excludes secrets. bwrap sandbox gracefully skips on Windows.
2026-04-08 01:48:55 +08:00
Xubin RenandXubin Ren 8871a57b4c fix(mcp): forward prompt arg descriptions & standardise error format
- Propagate `description` from MCP prompt arguments into the JSON
  Schema so LLMs can better understand prompt parameters.
- Align generic-exception error message with tool/resource wrappers
  (drop redundant `{exc}` detail).
- Extend test fixture to mock `mcp.shared.exceptions.McpError`.
- Add tests for argument description forwarding and McpError handling.

Made-with: Cursor
2026-04-08 00:28:04 +08:00
Tim O'BrienandXubin Ren 7cc527cf65 feat(mcp): expose MCP resources and prompts as read-only tools
Add MCPResourceWrapper and MCPPromptWrapper classes that expose MCP
server resources and prompts as nanobot tools. Resources are read-only
tools that fetch content by URI, and prompts are read-only tools that
return filled prompt templates with optional arguments.

- MCPResourceWrapper: reads resource content (text and binary) via URI
- MCPPromptWrapper: gets prompt templates with typed arguments
- Both handle timeouts, cancellation, and MCP SDK 1.x error types
- Resources and prompts are registered during server connection
- Gracefully handles servers that don't support resources/prompts
2026-04-08 00:28:04 +08:00
chengyongruandXubin Ren 238a9303d0 test: update tool_hint assertion to match new format 2026-04-07 15:15:07 +08:00
Xubin RenandXubin Ren 7ffd93f48d refactor: move search_usage to utils/searchusage, remove brave stub
- Rename agent/tools/search_usage.py → utils/searchusage.py
  (not an LLM tool, matches utils/ naming convention)
- Remove redundant _fetch_brave_usage — handled by else branch
- Move test to tests/utils/test_searchusage.py

Made-with: Cursor
2026-04-06 13:37:55 +08:00
whsandXubin Ren bc0ff7f214 feat(status): add web search provider usage to /status command 2026-04-06 13:37:55 +08:00
Xubin RenandXubin Ren 28e0a76b80 fix: path_append must not clobber login shell PATH
Seeding PATH in the env before bash -l caused /etc/profile
to skip its default PATH setup, breaking standard commands.
Move path_append to an inline export so the login shell
establishes a proper base PATH first.

Add regression test: ls still works when path_append is set.

Made-with: Cursor
2026-04-06 13:20:53 +08:00
Ben LenartsandXubin Ren be6063a142 security: prevent exec tool from leaking process env vars to LLM
The exec tool previously passed the full parent process environment to
child processes, which meant LLM-generated commands could access secrets
stored in env vars (e.g. API keys from EnvironmentFile=).

Switch from subprocess_shell with inherited env to bash login shell
with a minimal environment (HOME, LANG, TERM only). The login shell
sources the user's profile for PATH setup, making the pathAppend
config option a fallback rather than the primary PATH mechanism.
2026-04-06 13:20:53 +08:00
Xubin Ren 9f96be6e9b fix(sandbox): mount media directory read-only inside bwrap sandbox 2026-04-05 19:08:38 +00:00
Xubin Ren cef0f3f988 refactor: replace podman-seccomp.json with minimal cap_add, harden bwrap, add sandbox tests 2026-04-05 19:03:06 +00:00
Jack LuandXubin Ren bcb8352235 refactor(agent): streamline hook method calls and enhance error logging
- Introduced a helper method `_for_each_hook_safe` to reduce code duplication in hook method implementations.
- Updated error logging to include the method name for better traceability.
- Improved the `SkillsLoader` class by adding a new method `_skill_entries_from_dir` to simplify skill listing logic.
- Enhanced skill loading and filtering logic, ensuring workspace skills take precedence over built-in ones.
- Added comprehensive tests for `SkillsLoader` to validate functionality and edge cases.
2026-04-06 02:51:10 +08:00
Xubin RenandXubin Ren 4b4d8b506d test: add regression test for DuckDuckGo asyncio.wait_for timeout guard
Made-with: Cursor
2026-04-06 02:21:51 +08:00
Xubin RenandXubin Ren 90caf5ce51 test: remove duplicate test_jina_422_falls_back_to_duckduckgo
The same test function name appeared twice; Python silently shadows the
first definition so it never ran.  Keep the version that also asserts
the request URL contains "s.jina.ai".

Made-with: Cursor
2026-04-06 02:06:00 +08:00
KimGLeeandXubin Ren f422de8084 fix(web-search): fix Jina search format and fallback 2026-04-06 02:06:00 +08:00
Xubin Ren 33bef8d508 Merge remote-tracking branch 'origin/main' into feat/search-tools
Made-with: Cursor
2026-04-04 14:37:59 +00:00
Xubin Ren 77a88446fb Merge remote-tracking branch 'origin/main' into pr-2722 2026-04-04 13:51:59 +00:00
Xubin RenandXubin Ren 05fe7d4fb1 fix(tools): isolate decorated tool schemas and add regression tests 2026-04-04 19:58:44 +08:00
Jack LuandXubin Ren e7798a28ee refactor(tools): streamline Tool class and add JSON Schema for parameters
Refactor Tool methods and type handling; introduce JSON Schema support for tool parameters (schema module, validation tests).

Made-with: Cursor
2026-04-04 19:58:44 +08:00
Xubin RenandXubin Ren 9840270f7f test(tools): cover media dir access under workspace restriction
Made-with: Cursor
2026-04-04 03:03:58 +08:00
Xubin Ren 15cc9b23b4 feat(agent): add built-in grep and glob search tools 2026-04-02 15:37:57 +00:00
Xubin Ren eefd7e60f2 Merge remote-tracking branch 'origin/main' into feat/runtime-hardening 2026-04-02 10:40:49 +00:00
Xubin RenandXubin Ren 485c75e065 test(exec): verify windows drive-root workspace guard 2026-04-02 04:00:03 +08:00
zhangxiaoyu.yorkandXubin Ren bc2e474079 Fix ExecTool to block root directory paths when restrict_to_workspace is enabled 2026-04-02 04:00:03 +08:00
Xubin Ren fbedf7ad77 feat: harden agent runtime for long-running tasks 2026-04-01 19:12:49 +00:00
pikaxinge 607fd8fd7e fix(cache): stabilize tool ordering and cache markers for MCP 2026-04-01 17:07:22 +00:00
chengyongruandXubin Ren 72acba5d27 refactor(tests): optimize unit test structure 2026-03-24 15:12:22 +08:00