2715 Commits

Author SHA1 Message Date
Xubin Ren
081482b20f docs: refresh README opening positioning 2026-06-01 05:29:11 +08:00
Xubin Ren
ff80998423 docs: tighten README positioning bullets 2026-06-01 05:26:18 +08:00
Xubin Ren
b60e507010 docs: sharpen README positioning 2026-06-01 05:19:14 +08:00
Xubin Ren
76e857269d docs: update README news through May 30 2026-06-01 05:14:53 +08:00
Xubin Ren
be2e0172d1 fix(agent): extend sustained goal iteration budget 2026-06-01 04:00:15 +08:00
Xubin Ren
cba9ff1f57 fix(webui): simplify rendered source links 2026-06-01 00:00:37 +08:00
Xubin Ren
33a13b701b feat(webui): render source links with favicons 2026-06-01 00:00:37 +08:00
Xubin Ren
34386fe676 fix(webui): stabilize streaming output and settings i18n 2026-06-01 00:00:37 +08:00
Xubin Ren
31722120b7 feat(webui): polish native host experience 2026-06-01 00:00:37 +08:00
Xubin Ren
15c6abc991 test(webui): assert code block language fallback 2026-05-31 15:42:40 +08:00
Flinn-X
bdb3a2ded7 fix(webui): handle undefined language in code blocks
When fenced code blocks have no language specifier, react-syntax-highlighter
receives undefined for the language prop, causing a white screen crash.

- CodeBlock.tsx: fallback to 'text' when language is undefined
- MarkdownTextRenderer.tsx: defensive fallback at fence rendering site
- Added test cases for both components

Fixes #4116
2026-05-31 15:42:40 +08:00
hamb1y
a3241c33ba Require auth for WebSocket token issuance 2026-05-31 15:15:54 +08:00
chengyongru
15c2bd25b3 refactor(heartbeat): remove Completed section and tighten section gating
- Remove ## Completed section from HEARTBEAT.md template; completed
  tasks should be deleted, not accumulated
- Change in_active_section from tri-state (None/True/False) to bool
  (True/False) so stray text before any ## heading no longer triggers
  heartbeat
- Add test cases for stray pre-heading text and ## Notes section
- Update docs/chat-commands.md to reference ## Active Tasks
2026-05-31 15:15:37 +08:00
Xubin Ren
2671c8fe55 fix(heartbeat): ignore completed-only heartbeat entries 2026-05-31 15:15:37 +08:00
04cb
e3df310309 fix(heartbeat): skip when HEARTBEAT.md has no tasks and fail closed on delivery (#4111) 2026-05-31 15:15:37 +08:00
Xubin Ren
2b4c984e9a fix(matrix): align SAS verification message flow 2026-05-31 01:00:14 +08:00
mytechdream
68712fc489 fix(matrix): handle SAS device verification 2026-05-31 01:00:14 +08:00
Xubin Ren
0cc58a80a4 test(agent): cover process_direct session locking 2026-05-30 23:45:37 +08:00
04cb
e29c9c3906 fix(agent): acquire per-session lock in process_direct (#4080) 2026-05-30 23:45:37 +08:00
Xubin Ren
3dcf511c84
feat(webui): refine output timeline and model controls (#4108)
* feat(webui): refine output timeline and composer queue

* feat(webui): add provider model picker

* fix(webui): polish model settings and heartbeat checks

* chore: keep heartbeat changes out of webui pr

* refactor(webui): isolate settings routes

* fix(providers): align minimax anthropic test

* fix(providers): keep minimax anthropic base sdk-compatible

* fix(providers): normalize anthropic base urls
2026-05-30 23:45:26 +08:00
chengyongru
b2e43955e3 fix: add regression tests for bare-dict coercion, update stale comment 2026-05-30 15:35:04 +08:00
chengyongru
98be0de919 fix(test): increase yield_time_ms in test_write_stdin_can_close_stdin for Windows CI stability 2026-05-30 15:35:04 +08:00
04cb
13ab092cea feat(dream): add enabled toggle to skip Dream job registration (#3885) 2026-05-30 15:35:04 +08:00
04cb
5fe57f8afa fix(providers): coerce typeless Anthropic content blocks to text (#3993) 2026-05-30 15:35:04 +08:00
chengyongru
288146315e fix(security): normalize IPv6-mapped IPv4 in loopback check, add tests
- Apply _normalize_addr in _is_allowed_loopback_target so
  ::ffff:127.0.0.1 is correctly identified as loopback
- Add test for contains_internal_url with IPv6-mapped addresses
- Add test for whitelist + IPv6-mapped CGNAT interaction
2026-05-30 15:34:49 +08:00
yorkhellen
13dec9d2c2 fix(security): normalize IPv6-mapped IPv4 addresses in SSRF checks
::ffff:127.0.0.1 and ::ffff:169.254.169.254 are IPv6Address objects
that match neither the IPv4 blocklists (127.0.0.0/8, 169.254.0.0/16)
nor the IPv6 ones (::1/128), allowing SSRF bypass via DNS responses
that return IPv6-mapped IPv4 addresses.

Add _normalize_addr() to convert ipv4_mapped IPv6 addresses to their
IPv4 form before blocklist/allowlist matching.
2026-05-30 15:34:49 +08:00
Xubin Ren
1d4000560d fix(matrix): reject boolean media sizes 2026-05-30 15:34:19 +08:00
hinotoi-agent
4dd89f4c46 fix(matrix): bound inbound media downloads 2026-05-30 15:34:19 +08:00
chengyongru
7c86223643 fix(exec): bypass cmd.exe for multi-line python -c commands on Windows
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.
2026-05-30 01:02:40 +08:00
Xubin Ren
8e421eb976 refactor(webui): clarify websocket routing 2026-05-29 17:26:58 +08:00
Xubin Ren
9ed5643d93 refactor(webui): isolate signed media serving 2026-05-29 17:26:58 +08:00
Xubin Ren
4a0035ef8f fix(webui): support video byte ranges 2026-05-29 17:26:58 +08:00
Xubin Ren
a71e6a0ae8 fix(webui): persist markdown video previews 2026-05-29 17:26:58 +08:00
Xubin Ren
57563b671f fix(apps): recover stale npm installs 2026-05-29 17:26:58 +08:00
Xubin Ren
d7bc1bcfb5 fix(apps): use registry logos 2026-05-29 17:26:58 +08:00
Xubin Ren
c1357e86de feat(apps): add extension registry source 2026-05-29 17:26:58 +08:00
Xubin Ren
232df45126 fix(msteams): trust official Teams service hosts 2026-05-29 16:46:46 +08:00
hinotoi-agent
5734c17ee0 fix(msteams): trust service URLs before replies 2026-05-29 16:46:46 +08:00
04cb
9d3fe7c34b fix(providers): surface clear arrearage warning on quota/billing errors (#3006) 2026-05-29 15:31:17 +08:00
chengyongru
672fabe5be refactor(agent): move document media logic out of AgentLoop into document.py
Extract is_image_file() and reference_non_image_attachments() from
AgentLoop private static methods into nanobot/utils/document.py where
they belong alongside extract_documents(). Simplify config lookup by
removing dead isinstance(dict) branch.
2026-05-29 15:31:03 +08:00
hanyuanling
ec4f9e9857 Add document extraction channel toggle 2026-05-29 15:31:03 +08:00
Xubin Ren
404b68cdd4 feat(webui): add context window setting 2026-05-29 13:09:08 +08:00
Xubin Ren
3a420136bb
feat(webui): add project workspaces and access controls (#4007)
* feat(webui): add project workspaces and access controls

* feat(webui): add project workspaces and access controls

* refactor(tools): centralize workspace access resolution

* refactor(webui): remove unused workspace host state

* fix(webui): hide estimated file edit label

* fix(webui): clarify file edit deletion feedback

* fix(webui): label deleted file activity

* fix(webui): flatten file edit activity rows

* fix(core): remove path-only patch deletion

* fix(core): keep apply patch non-destructive

* refactor(webui): trim workspace host plumbing

* fix(tools): register exec with tools config
2026-05-29 03:42:53 +08:00
chengyongru
84428136e6 test: harden timing-fragile test and add cross-tool ContextVar isolation test
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.
2026-05-28 22:54:46 +08:00
hamb1y
0df60416ba fix(agent): address session and streaming concurrency bugs 2026-05-28 22:54:46 +08:00
chengyongru
1a4ae8994d fix(tests): update monkeypatch path for evaluate_response
The import was moved to module top in nanobot/cli/commands.py,
so tests must patch nanobot.cli.commands.evaluate_response instead
of nanobot.utils.evaluator.evaluate_response.
2026-05-28 20:20:28 +08:00
chengyongru
fe2af64e04 refactor(heartbeat): migrate heartbeat service to cron-based auto-registration
Remove standalone nanobot/heartbeat/ service and replace it with an
auto-registered system cron job on gateway startup. Key behaviors preserved:

- HeartbeatConfig (enabled, interval_s, keep_recent_messages) remains in
  GatewayConfig for backward compatibility.
- On startup, if enabled, a system cron job "heartbeat" is registered with
  schedule derived from interval_s.
- HEARTBEAT.md is checked on each tick; empty/template-identical files skip
  to avoid wasting LLM calls.
- Post-run evaluate_response and session history truncation
  (keep_recent_messages) are retained.
- Delivery target selection, deliverable filtering, and preamble guidance
  are preserved.

Files removed:
- nanobot/heartbeat/__init__.py
- nanobot/heartbeat/service.py
- tests/heartbeat/*
- tests/agent/test_heartbeat_service.py

Templates and docs updated to reflect cron-based usage.
2026-05-28 20:20:28 +08:00
hamb1y
7d09f1cd9e Add Discord model slash command 2026-05-28 15:48:50 +08:00
yeounhyeok
ac8bef76f6 fix(provider): honor NANOBOT_STREAM_IDLE_TIMEOUT_S in Codex provider
Every other streaming provider (anthropic, bedrock, openai_compat,
litellm) reads NANOBOT_STREAM_IDLE_TIMEOUT_S with a 90s default. The
Codex provider hardcoded 60s in _request_codex, so it could not be
tuned the same way and aborted streams sooner than its peers.

Read the same env var with the same default and pass it as the httpx
client timeout. The variable name and int parsing match anthropic /
openai_compat / bedrock verbatim.

#4009 normalized the error response when the timeout fires; this PR
fixes the timeout knob itself.
2026-05-28 02:17:15 +08:00
Xubin Ren
1cfc3ef165
docs(contribution): update maintainers information 2026-05-27 18:16:52 +08:00