1172 Commits

Author SHA1 Message Date
chengyongru
515e418eb4 fix: block exact-file allowlist link escapes
maintainer edit: compare exact-file allowlist entries using logical paths and require the resolved target to stay at that canonical path, so symlinks or junctions cannot redirect canonical memory files to an external write target.
2026-06-18 00:03:26 +08:00
chengyongru
42ce294665 fix: preserve internal tool write scopes
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.
2026-06-18 00:03:26 +08:00
chengyongru
15f218e918 fix: enforce exact Dream memory file writes
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.
2026-06-18 00:03:26 +08:00
chengyongru
732992df4f Clarify filesystem workspace write policy 2026-06-18 00:03:26 +08:00
chengyongru
fc635377bc fix: avoid replaying older long turns
Treat the current live user message as the replay boundary for normal user turns, while keeping user-turn extension for history and consolidation paths that need it. Add regression coverage for the user-triggered long tool-turn case.
2026-06-18 00:03:22 +08:00
Xubin Ren
09962895fb fix(session): preserve user turns in replay history 2026-06-18 00:03:22 +08:00
chengyongru
ef6da0a94e Fix my tool model preset switching 2026-06-18 00:03:13 +08:00
Xubin Ren
bdf21c932b fix(anthropic): avoid sanitized tool id collisions 2026-06-18 00:03:08 +08:00
michaelxer
0023f6d998 fix(providers): remove custom cloud httpx client, let SDK handle proxy defaults
chengyongru reviewed #4367 and identified that the cloud  branch
created a bare httpx.AsyncClient that lacked the SDK's default settings
(follow_redirects, connection pool limits). Since the SDK's
DefaultAsyncHttpxClient already has trust_env=True and proper defaults,
the simplest fix is to let http_client stay None for cloud endpoints.

Also updated the test to match the new behavior (http_client is None).
2026-06-18 00:03:03 +08:00
michaelxer
72b8fc806f fix(providers): disable proxy for local endpoints, respect env proxy for cloud
When the host has HTTP_PROXY / HTTPS_PROXY / ALL_PROXY set, httpx routes
all traffic through the proxy — including requests to localhost or LAN
addresses that the proxy typically cannot reach.  This breaks local model
servers (Ollama, llama.cpp, vLLM) silently.

- Local endpoints: pass transport=httpx.AsyncHTTPTransport(proxy=None)
  so proxy env vars are ignored for local traffic.
- Cloud endpoints: pass trust_env=True so corporate/VPN proxies work
  without explicit configuration.

Fixes #4366
2026-06-18 00:03:03 +08:00
Haisam
bfe5b64022 fix: allow git commands in workspace subdirectories
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
2026-06-18 00:02:58 +08:00
chengyongru
4219911423 fix: recover failed Feishu streaming updates
Feishu CardKit content updates can fail without raising, leaving a blank Generating card while the final streamed response skips normal send. Reopen streaming mode and retry once, close blank cards when the first update fails, and fall back to a regular card when final updates still fail.
2026-06-18 00:02:54 +08:00
chengyongru
8ecc2d69c4 fix: log primary model error before fallback 2026-06-18 00:02:49 +08:00
chengyongru
0d4af68e63 fix: silence unroutable cli progress noise 2026-06-18 00:02:45 +08:00
Xubin Ren
c29601d303
Merge PR #4330: feat(webui): add automation management view
feat(webui): add automation management view
2026-06-17 01:55:39 +08:00
chengyongru
4c5e340186 feat(memory): enable idle auto compact by default 2026-06-17 00:48:06 +08:00
chengyongru
dcf76117ab fix(command): explain empty dream runs 2026-06-17 00:47:59 +08:00
chengyongru
072921893f fix: reuse token truncation helper
Maintainer edit: make token truncation include the suffix within the budget and route the consolidator through the shared helper so recent-history and archive truncation keep the same semantics.
2026-06-17 00:47:52 +08:00
w.antar
21d9072190 fix(tests): update recent history truncation to use token limits 2026-06-17 00:47:52 +08:00
w.antar
973a5ee507 fix(context): cap recent-history digest by tokens, not characters
The recent-history section injected into the system prompt was capped by character count (_MAX_HISTORY_CHARS = 32_000). Characters are a poor proxy for tokens: ~32k chars of English is ~8k tokens, but the same char count of CJK text or code can be far more, so the cap could let the section blow well past its intended size on non English/code-heavy histories.

Add a reusable truncate_text_to_tokens() helper (reusing the tiktoken
 cl100k_base encoder already used elsewhere, with a char-based fallback) and
  switch the digest cap to a token budget (_MAX_HISTORY_TOKENS = 8_000),
  matching the previous English-text size while holding regardless of
  content.
2026-06-17 00:47:52 +08:00
yu-xin-c
846410f936 fix(providers): validate stream idle timeout config 2026-06-17 00:47:44 +08:00
Xubin Ren
7bec0f6e01 fix(api): honor skip-user persist through save boundary 2026-06-16 21:31:26 +08:00
04cb
d75f80437c fix(api): don't re-persist user turn on empty-response retry (#4079)
The non-streaming retry called process_direct again with the same
content, persisting a duplicate user turn. Pass persist_user_message=False
so the retry recovers a response without re-recording the user message.
2026-06-16 21:31:26 +08:00
Xubin Ren
25a55fe1c7 fix(providers): enable thinking for Kimi K2.7 models 2026-06-16 17:44:22 +08:00
chengyongru
0263dbd1c3 chore: trim automation ui cleanup 2026-06-16 15:10:51 +08:00
chengyongru
b24b5f19fc fix(cron): always require bound automation sessions 2026-06-16 14:16:12 +08:00
chengyongru
6239114c46 fix(cron): prevent unbound automation execution 2026-06-16 14:07:08 +08:00
chengyongru
27d869d3cc fix(agent): refresh goal continuation context 2026-06-16 11:19:24 +08:00
chengyongru
e6957de622 fix(webui): drop legacy automation setup state 2026-06-16 00:26:06 +08:00
chengyongru
3ce0cd972e fix(session): keep auto compact suffix on user turn 2026-06-15 19:03:37 +08:00
chengyongru
03c79817ac test(websocket): expect session refresh after turn end 2026-06-15 18:25:00 +08:00
chengyongru
848378d0db Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	webui/src/components/settings/SettingsView.tsx
2026-06-15 18:11:22 +08:00
chengyongru
167a53dc45 fix(webui): sort sessions by transcript activity 2026-06-15 17:44:26 +08:00
chengyongru
cbb4c0bad2 fix(webui): polish automation layout and session updates 2026-06-15 17:30:06 +08:00
chengyongru
f8bf6aea51 fix(webui): encode automation update values 2026-06-15 15:14:24 +08:00
Michael
9814a3b9fe
fix(api): forward real LLM usage in /v1/chat/completions response (#4310)
* fix(api): forward real LLM usage in /v1/chat/completions response

_chat_completion_response() hardcoded prompt_tokens/completion_tokens
to zero.  Now reads agent_loop._last_usage (set by process_direct
after every LLM call) and forwards the actual prompt/completion counts.

Streaming path is unchanged; usage is only surfaced in non-streaming
responses for now.

Fixes #4309

* fix: use defensive getattr for _last_usage and add it to all test mock agents

- Use getattr(agent_loop, '_last_usage', None) in server.py for safety
- Add _last_usage = {} to mock agents in test_api_attachment.py and test_api_stream.py
- Prevents AttributeError/500 when mock agents don't have the attribute

* fix(api): preserve provider total usage

---------

Co-authored-by: michaelxer <michaelxer@users.noreply.github.com>
Co-authored-by: Xubin Ren <52506698+Re-bin@users.noreply.github.com>
2026-06-15 15:13:11 +08:00
Stellar鱼
f85101f017
fix(memory): ignore malformed history entries (#4315) 2026-06-15 15:13:07 +08:00
Stellar鱼
a54e56c69e
fix(runner): ignore empty injected payloads (#4337) 2026-06-15 15:13:03 +08:00
chengyongru
44ce220af6 fix: preserve file tool toggle for subagents
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.
2026-06-15 02:55:18 +08:00
Nir Adler
df0f9f4d5c tools: add tools.file.enable to toggle built-in filesystem tools (default true) 2026-06-15 02:55:18 +08:00
chengyongru
5892c6913b fix(webui): allow content-only automation edits
Avoid resubmitting unchanged schedules from the automation edit dialog so completed one-time automations can still have their content updated. Treat unchanged schedules as already-valid on the backend while preserving validation for actual schedule changes.
2026-06-15 00:59:23 +08:00
chengyongru
8b42d0760e fix(webui): harden automation management API
Maintainer edit: redact external channel chat identifiers from the WebUI automation payload and reject malformed or unschedulable automation updates before they mutate cron jobs.
2026-06-14 22:19:28 +08:00
chengyongru
747f0a08c7 fix(webui): improve automation management 2026-06-14 18:24:59 +08:00
qcypggs
cb2620c877 Fix Codex image SSE handling 2026-06-14 12:52:40 +08:00
axelray-dev
ad89cbb24f test(providers): use real Fable model ID claude-fable-5 in tests
Replace placeholder claude-fable-1 with the actual API model ID.
2026-06-14 12:52:07 +08:00
axelray-dev
29d7186853 fix(providers): widen omit_temperature to cover opus-4-8 and fable
The temperature suppression was hardcoded to only match opus-4-7. Newer
Anthropic models (opus-4-8, fable) also reject the parameter with a 400.

Normalize model_name to lowercase before matching so mixed-case configs
do not fall through.  Add tests for opus-4-8 and fable across adaptive,
enabled, and no-thinking paths, plus a negative test confirming ordinary
models still send temperature.

Fixes #4333
2026-06-14 12:52:07 +08:00
chengyongru
17e3183598 fix(webui): simplify automation source display 2026-06-14 00:32:53 +08:00
chengyongru
5b10102629 fix(webui): avoid fake automation origins 2026-06-14 00:04:15 +08:00
chengyongru
43830b7162 fix(webui): localize automation runtime labels 2026-06-13 23:06:28 +08:00
chengyongru
e08462ca30 feat(webui): add automation management view 2026-06-13 23:06:28 +08:00