Commit Graph
416 Commits
Author SHA1 Message Date
chengyongru 39348dfafe refactor(agent): remove dead lifecycle scaffolding 2026-07-27 12:00:06 +08:00
Xubin Ren c1899e2cb4 fix(mcp): decode URI-encoded schema refs 2026-07-27 01:14:41 +08:00
amplifierplus 9aae7485d6 fix(mcp): normalize local schema refs 2026-07-27 01:14:41 +08:00
Xubin Ren cf6ca13b6d fix(exec): preserve bwrap workspace masking 2026-07-27 00:31:00 +08:00
yu-xin-c 01a11b3980 feat(exec): allow extra bwrap bind roots 2026-07-27 00:31:00 +08:00
Xubin Ren 3a400e0207 feat(agent): support inline subagent consultation 2026-07-24 19:13:51 +08:00
AxelRay 78f4c132d9 fix(exec): extract absolute paths after equals sign in shell guard (#4594) 2026-07-23 23:58:01 +08:00
KDB 648fc92673 fix(exec): retain stale sessions after cleanup failure
Only remove idle exec sessions after process termination succeeds so later cleanup and shutdown paths can retry failed kills.
2026-07-23 23:55:00 +08:00
Xubin Ren 1616fa9f14 feat(image): apply generation settings live 2026-07-23 12:42:24 +08:00
chengyongru c22efb5f7a feat(agent): make model presets session-scoped (#4866) 2026-07-23 00:38:49 +08:00
chengyongru b189a37648 fix(agent): preserve agent-owned state in project workspaces (#4945) 2026-07-22 17:25:22 +08:00
chengyongru 80085085d9 fix(exec): retain failed owner session cleanup 2026-07-22 15:28:34 +08:00
yorkhellen 7b1d81a868 fix(subagent): cascade exec session termination on /stop
cancel_by_session() only cancelled asyncio tasks, leaving child
processes from exec sessions orphaned. Since each SubagentManager
now owns a dedicated ExecSessionManager, terminate those sessions
by owner_session_key after cancelling tasks.

Add ExecSessionManager.terminate_by_owner() to kill all sessions
for a given owner, and call it from cancel_by_session().
2026-07-22 15:28:34 +08:00
amplifierplus cdb2df4982 fix(files): reject oversized reads before loading 2026-07-21 15:02:27 +08:00
chengyongru d5658dbc91 fix: preserve background operator in allowlist segments
Maintainer edit: keep a top-level trailing '&' in the segment being matched so background execution cannot be checked as if the ampersand were absent. Redirection forms like 2>&1 and &> remain untouched.
2026-07-21 13:50:24 +08:00
chengyongru ab6ceef1a1 refactor: simplify ampersand segment check
Maintainer edit: keep the single-ampersand guard behavior, but fold the redirect exceptions into one condition instead of carrying temporary previous/next character variables.
2026-07-21 13:50:24 +08:00
chengyongru 12c52c11d3 fix: treat single ampersand as shell segment
Maintainer edit: single '&' backgrounds the preceding command and starts another top-level shell segment, so allowPatterns must split it the same way as ';', '|', '&&', and '||'. Keep fd redirections such as 2>&1 and &> intact.
2026-07-21 13:50:24 +08:00
michaelxer f4a7079e65 fix(security): use re.fullmatch per segment instead of re.search
Fixes chengyongru's review concern: re.search is more permissive
than the original re.fullmatch behavior for single-segment commands.
Using re.fullmatch per segment preserves backward compatibility while
still fixing the chained-command bypass.
2026-07-21 13:50:24 +08:00
michaelxer bbca32fea9 fix(security): validate each shell segment against exec.allowPatterns
Guard against shell-chain bypass where an attacker appends '&& malicious'
after an allowlisted prefix. The allowlist check now splits the command
on top-level chaining operators (&&, ||, ;, |) and requires every segment
to match at least one allowPattern independently.

Fixes #4521
2026-07-21 13:50:24 +08:00
KDB 8981995474 fix(exec): clean up sessions on shutdown 2026-07-21 13:48:51 +08:00
adabarbulescu d4f5abe004 fix: preserve real cancellation in MCP paths 2026-07-18 17:36:35 +08:00
yu-xin-c 995cc44e89 fix(exec): isolate exec session managers 2026-07-18 17:35:56 +08:00
chengyongru 681edfa6f3 fix(providers): honor Codex proxy config consistently 2026-07-15 20:01:48 +08:00
Brian Noah 86f6558707 fix: catch asyncio.CancelledError in close_mcp shutdown
When an MCP server (e.g. stdio browser-agent subprocess) does not
terminate within the AsyncExitStack.aclose() timeout, asyncio raises
CancelledError. The existing exception handler only caught RuntimeError
and BaseExceptionGroup, so CancelledError escaped the except block and
crashed nanobot with exit code 1 on every shutdown.

Add asyncio.CancelledError to the caught exception tuple so the error
is logged at debug level and shutdown completes cleanly.

Stack trace from the crash:

Traceback (most recent call last):
  File ".../nanobot/agent/loop.py", line 1194, in close_mcp
    await stack.aclose()
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ".../asyncio/__main__.py", line ?, in <module>
  File ".../nanobot/agent/loop.py", line ?, in close_mcp
    ...
RuntimeError: ... (or BaseExceptionGroup) not caught
SystemExit: 1
2026-07-14 16:17:35 +08:00
chengyongru 1643aa7ef5 fix(shell): narrow PowerShell UTF-8 configuration
Avoid changing native pipeline input encoding and consolidate real PowerShell checks to reduce Windows runner startup flakiness.
2026-07-14 13:50:02 +08:00
chengyongru 61afbffc89 fix(shell): configure PowerShell UTF-8 output 2026-07-14 13:50:02 +08:00
adabarbulescu 9cdf17f5d5 Fix Windows exec UTF-16 output decoding 2026-07-14 13:50:02 +08:00
Xubin Ren fe0717b385 feat(webui): add guided setup flows
* feat(channels): add guided setup flows

* test(channels): preserve setup config values

* fix(channels): reflect saved setup state

* refactor(channels): simplify setup state metadata

* fix(channels): harden setup lifecycle

* refactor(channels): centralize setup contracts

* fix(channels): route setup actions through webui shim

* fix(channels): adapt settings for compact screens

* fix(models): preserve default preset display

* feat(models): add curated Codex catalog

* fix(webui): stop attached gateway on interrupt

* fix(webui): simplify apps catalog

* docs(webui): clarify apps and runtime features

* feat(settings): add guided capability setup

* fix(webui): harden setup and managed services

* test: keep managed runtime checks portable

* test: scope POSIX runtime coverage

* fix(webui): simplify file settings

* feat(files): bundle document reading

* fix(webui): harden setup request boundaries

* fix(webui): prevent channel setup status squeeze

* fix(settings): group provider compatibility aliases

* refactor(settings): remove redundant setup surfaces

* fix(webui): harden guided setup lifecycle

* fix(webui): preserve channel setup compatibility
2026-07-13 13:11:46 +08:00
chengyongru c339ce8bba refactor(agent): remove obsolete MCP prompt annotations 2026-07-12 00:35:17 +08:00
chengyongru 93de413432 feat(agent): expose request routing metadata through my 2026-07-12 00:35:17 +08:00
chengyongru e206ee4e70 refactor(agent): remove legacy image mode prompt injection 2026-07-12 00:35:17 +08:00
chengyongru 2eb7398f34 fix(agent): close runtime context persistence gaps 2026-07-12 00:35:17 +08:00
chengyongru f75d3519db feat(agent): add persistent runtime context providers 2026-07-12 00:35:17 +08:00
chengyongru 7f8c3453e1 refactor(agent): gate sustained goals behind explicit /goal
Replace the legacy long-goal skill contract with command-scoped goal tools and runtime guidance. Keep goal state durable across continuations while restricting create and replace mutations to explicit user /goal turns.
2026-07-12 00:35:17 +08:00
Xubin Ren edf78e7054 fix(mcp): keep transport cleanup in owner tasks 2026-07-11 11:45:20 +08:00
flyzstu f3d1b9ca2d fix(mcp): defer stale stack cleanup during reconnect 2026-07-11 11:45:20 +08:00
chengyongru 7675364eae fix(tools): enforce edit_file line hints 2026-07-11 01:14:50 +08:00
chengyongru 052fdc132d feat(tools): guard edit_file target lines 2026-07-11 01:14:50 +08:00
Eric Yang 9a1d1e64c7 fix(shell): harden kill path and add zombie reap tests
Skip process.kill() when returncode is already set so generic exception
handlers after a successful communicate() cannot raise ProcessLookupError.
Suppress race kill failures and still run the safety-net reap.

Add unit and integration coverage for owned-PID reaping on normal exit,
timeout, exception, and exec-session kill/poll paths.
2026-07-10 20:19:44 +08:00
Eric Yang bda0c099ab fix(shell): guard _reap_pid on os.waitpid availability
Windows CI runs Unix-path unit tests by patching _IS_WINDOWS=False while
still on win32, where os.WNOHANG/os.waitpid do not exist. Use capability
checks so reaping is a no-op on platforms without waitpid rather than
trusting the (mockable) platform flag.
2026-07-10 20:19:44 +08:00
Eric Yang ef14d1ea92 fix(shell): remove unused os import in exec_session
Ruff F401 failed CI on the zombie-reap PR; reaping uses shell._reap_pid
so os is not needed in this module.
2026-07-10 20:19:44 +08:00
Eric Yang c9e014fdea fix(shell): reap zombie processes on all subprocess exit paths
The previous fix (dbcc7cb5) only added os.waitpid() to _kill_process(),
covering the timeout/cancel path of one-shot exec. Zombies continued to
accumulate because several other exit paths never reaped children:

- _ExecSession.kill(): sent SIGKILL + process.wait(5s) but had no
  os.waitpid() fallback if the wait timed out
- ExecTool.execute() generic exception handler: leaked the subprocess
  if communicate() raised an unexpected error
- Normal completion paths: relied entirely on asyncio's child-watcher,
  which can miss exits inside Docker containers (pidfd/SIGCHLD gaps)

Changes:
- Extract _reap_pid() helper for consistent, safe os.waitpid(WNOHANG)
- Add _reap_pid() fallback to _ExecSession.kill() via try/finally
- Add _reap_pid() safety-net after normal process exit in both
  ExecTool.execute() and _ExecSession.poll()
- Kill + reap subprocess in the generic except Exception handler
- Add periodic zombie reaper background task (every 30s) in the
  gateway as a last line of defense
2026-07-10 20:19:44 +08:00
NOKIAO 87602a74ea narrower cert path 2026-07-10 19:32:23 +08:00
NOKIAO ad55f3ce37 添加红帽系Linux的证书路径支持 2026-07-10 19:32:23 +08:00
chengyongru 21f58cbabf refactor(agent): make resolver sole runtime owner 2026-07-10 17:54:34 +08:00
chengyongru af85c356b8 refactor(agent): capture subagent runtime before spawn 2026-07-10 17:54:34 +08:00
chengyongru 198fd9f869 refactor(agent): capture runtime at turn admission 2026-07-10 17:54:34 +08:00
chengyongru 42d7ad34a4 refactor(agent): unify request context routing 2026-07-10 17:54:34 +08:00
chengyongru bb3b449e09 refactor(agent): capture original user text per turn 2026-07-10 17:54:34 +08:00
chengyongru 8559458258 refactor(agent): add turn hook factories 2026-07-08 21:02:12 +08:00