404 Commits

Author SHA1 Message Date
Xubin Ren
dadf453097 Merge origin/main into fix/sanitize-messages-non-claude
Resolved conflict in azure_openai_provider.py by keeping main's
Responses API implementation (role alternation not needed for the
Responses API input format).

Made-with: Cursor
2026-04-09 04:45:45 +00:00
whs
b4c7cd654e fix: use effective session key for _active_tasks in unified mode 2026-04-09 11:09:25 +08:00
whs
985f9c443b tests: add unified_session coverage for /new and consolidation 2026-04-09 11:09:25 +08:00
whs
743e73da3f feat(session): add unified_session config to share one session across all channels 2026-04-09 11:09:25 +08:00
chensp
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
Rohit_Dayanand123
3cc2ebeef7 Added bug fix to Dingtalk by zipping html to prevent raw failure 2026-04-09 10:49:00 +08:00
Leo fu
42624f5bf3 test: update expected token display to match consistent 1000 divisor
The test fixtures use 65536 as context_window_tokens. With the divisor
corrected from 1024 to 1000, the display changes from 64k to 65k.
2026-04-09 10:40:20 +08:00
Xubin Ren
61dd5ac13a test(discord): cover streamed reply overflow
Lock the Discord streaming path with a regression test for final chunk splitting so oversized replies stay safe to merge and ship.

Made-with: Cursor
2026-04-09 00:24:11 +08:00
SHLE1
e49b6c0c96 fix(discord): enable streaming replies 2026-04-09 00:24:11 +08:00
Xubin Ren
715f2a79be fix(version): fall back to pyproject in source checkouts
Keep importlib.metadata as the primary source for installed packages, but avoid PackageNotFoundError when nanobot is imported directly from a source tree.

Made-with: Cursor
2026-04-08 23:47:36 +08:00
Xubin Ren
6bf101c79b fix(hook): keep composite hooks backward compatible
Avoid AttributeError regressions when hooks define their own __init__ or when a CompositeHook wraps another composite.

Made-with: Cursor
2026-04-08 23:41:31 +08:00
Xubin Ren
142cb46956 fix(cron): preserve manual run state and merged history
Keep manual runs from flipping the scheduler's running flag, rebuild merged run history records from action logs, and avoid delaying sub-second jobs to a one-second floor. Add regression coverage for disabled/manual runs, merged history persistence, and sub-second timers.

Made-with: Cursor
2026-04-08 23:34:47 +08:00
xinnan.hou
0f1e3aa151 fix 2026-04-08 23:34:47 +08:00
Xubin Ren
d084d10dc2 feat(openai): auto-route direct reasoning requests with responses fallback 2026-04-08 15:21:08 +00:00
Xubin Ren
c092896922 fix(tool-hint): handle quoted paths in exec hints
Preserve path folding for quoted exec command paths with spaces so hint previews do not fall back to mid-path truncation. Add regression coverage for quoted Unix and Windows path cases.

Made-with: Cursor
2026-04-08 23:05:52 +08:00
chengyongru
b16865722b fix(tool-hint): fold paths in exec commands and deduplicate by formatted string
1. exec tool hints previously used val[:40] blind character truncation,
   cutting paths mid-segment. Now detects file paths via regex and
   abbreviates them with abbreviate_path. Supports Windows, Unix
   absolute, and ~/ home paths.

2. Deduplication now compares fully formatted hint strings instead of
   tool names alone. Fixes ls /Desktop and ls /Downloads being
   incorrectly merged as "ls /Desktop × 2".

Co-authored-by: xzq.xu <zhiqiang.xu@nodeskai.com>
2026-04-08 23:05:52 +08:00
kronk307
e21ba5f667 feat(telegram): add location/geo support
Forward static location pins as [location: lat, lon] content so the
agent can respond to geo messages and pass coordinates to MCP tools.

Closes HKUDS/nanobot#2909
2026-04-08 02:32:19 +08:00
Xubin Ren
edb821e10d feat(agent): prompt behavior directives, tool descriptions, and loop robustness 2026-04-08 02:22:25 +08:00
Xubin 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 Ren
63acfc4f2f test: fix trailing-space mismatch and add regression tests for normal models
- Fix assertion in streaming dict fallback test (trailing space in data
  not reflected in expected value).
- Add two regression tests proving that models with reasoning_content
  (e.g. DeepSeek-R1) and standard models (no reasoning fields) are
  completely unaffected by the reasoning fallback.

Made-with: Cursor
2026-04-08 00:59:39 +08:00
moranfong
9e7c07ac89 test(provider): add StepFun reasoning field fallback tests
Add comprehensive tests for the StepFun Plan API compatibility fix:
- _parse dict branch: content and reasoning_content fallback to reasoning
- _parse SDK object branch: same fallback for pydantic response objects
- _parse_chunks dict branch: reasoning field handled in streaming mode
- _parse_chunks SDK branch: reasoning fallback for SDK delta objects
- Precedence tests: reasoning_content field takes priority over reasoning

Refs: fix(provider): support StepFun Plan API reasoning field fallback
2026-04-08 00:59:39 +08:00
Xubin 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'Brien
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
Xubin Ren
ce7986e492 fix(memory): add timestamp and cap to recent history injection 2026-04-08 00:03:11 +08:00
Xubin Ren
05d8062c70 test: add regression tests for unprocessed history injection in system prompt
Made-with: Cursor
2026-04-07 23:41:05 +08:00
Xubin Ren
1e8a6663ca test(anthropic): add regression tests for thinking modes incl. adaptive
Also update schema comment to mention 'adaptive' as a valid value.

Made-with: Cursor
2026-04-07 22:53:43 +08:00
Xubin Ren
423aab09dd test(cron): add regression test for running service picking up external adds
Co-authored-by: chengyongru
Made-with: Cursor
2026-04-07 22:48:40 +08:00
xinnan.hou
a982d9f9be add reload jobs test 2026-04-07 22:48:40 +08:00
Xubin Ren
82dec12f66 refactor: extract tool hint formatting to utils/tool_hints.py
- Move _tool_hint implementation from loop.py to nanobot/utils/tool_hints.py
- Keep thin delegation in AgentLoop._tool_hint for backward compat
- Update test imports to test format_tool_hints directly

Made-with: Cursor
2026-04-07 15:15:07 +08:00
chengyongru
3e3a7654f8 fix(agent): address code review findings for tool hint enhancement
- C1: Fix IndexError on empty list arguments via _get_args() helper
- I1: Remove redundant branch in _fmt_known
- I2: Export abbreviate_path from nanobot.utils.__init__
- I3: Fix _abbreviate_url negative-budget format consistency
- S1: Move FORMATS to class-level _TOOL_HINT_FORMATS constant
- S2: Add list_dir to FORMATS registry (ls path)
- G1-G5: Add tests for empty list args, None args, URL edge cases,
  mixed folding groups, and list_dir format
2026-04-07 15:15:07 +08:00
chengyongru
b1d3c00deb test(feishu): add compatibility tests for new tool hint format 2026-04-07 15:15:07 +08:00
chengyongru
238a9303d0 test: update tool_hint assertion to match new format 2026-04-07 15:15:07 +08:00
chengyongru
8ca9960077 feat(agent): rewrite _tool_hint with registry, path abbreviation, and call folding 2026-04-07 15:15:07 +08:00
chengyongru
f452af6c62 feat(utils): add abbreviate_path for smart path/URL truncation 2026-04-07 15:15:07 +08:00
Xubin Ren
02597c3ec9 fix(runner): silent retry on empty response before finalization 2026-04-07 15:03:41 +08:00
Xubin Ren
0355f20919 test: add regression tests for _resolve_mentions
7 tests covering: single mention, dual IDs, no-id skip, multiple mentions,
no mentions, empty text, and key-not-in-text edge case.

Made-with: Cursor
2026-04-07 14:03:55 +08:00
Xubin Ren
075bdd5c3c refactor: move SafeFileHistory to module level + add regression tests
- Promote _SafeFileHistory to module-level SafeFileHistory for testability
- Add 5 regression tests: surrogates, normal text, emoji, mixed CJK, multi-surrogates

Made-with: Cursor
2026-04-07 13:57:34 +08:00
04cb
f4904c4bdf fix(cron): add optional name parameter to separate job label from message (#2680) 2026-04-07 13:22:20 +08:00
Xubin Ren
dad9c07843 fix(tests): update Tavily usage tests to match actual API response shape
The _parse_tavily_usage implementation was updated to use the real
{account: {plan_usage, plan_limit, ...}} structure, but the tests
still used the old flat {used, limit, breakdown} format.

Made-with: Cursor
2026-04-06 19:17:55 +08:00
Xubin Ren
35f53a721d refactor: consolidate _parse_retry_after_headers into base class
Merge the three retry-after header parsers (base, OpenAI, Anthropic)
into a single _extract_retry_after_from_headers on LLMProvider that
handles retry-after-ms, case-insensitive lookup, and HTTP date.

Remove the per-provider _parse_retry_after_headers duplicates and
their now-unused email.utils / time imports. Add test for retry-after-ms.

Made-with: Cursor
2026-04-06 08:44:52 +00:00
Xubin Ren
aeba9a23e6 refactor: remove dead _error_response wrapper in Anthropic provider
Fold _error_response back into _handle_error to match OpenAI/Azure
convention. Update all call sites and tests accordingly.

Made-with: Cursor
2026-04-06 08:35:02 +00:00
Xubin Ren
b575aed20e Merge origin/main into fix/structured-retry-classification-main
Made-with: Cursor
2026-04-06 08:28:20 +00:00
Xubin Ren
ebf29d87ae fix: include byteplus providers, guard None reasoning_effort, merge extra_body
- Add byteplus and byteplus_coding_plan to thinking param providers
- Only send extra_body when reasoning_effort is explicitly set
- Use setdefault().update() to avoid clobbering existing extra_body
- Add 7 regression tests for thinking params

Made-with: Cursor
2026-04-06 16:12:08 +08:00
Ben Lenarts
d0527a8cf4 feat(email): add attachment extraction support
Save inbound email attachments to the media directory with configurable
MIME type filtering (glob patterns like "image/*"), per-attachment size
limits, and max attachment count. Filenames are sanitized to prevent
path traversal. Controlled by allowed_attachment_types — empty (default)
means disabled, non-empty enables extraction for matching types.
2026-04-06 15:09:44 +08:00
Xubin Ren
bdec2637ae test: add regression test for oversized stream-end splitting
Made-with: Cursor
2026-04-06 06:39:23 +00:00
Xubin Ren
c9d4b7b905 Merge remote-tracking branch 'origin/main' into pr-2449
Made-with: Cursor

# Conflicts:
#	nanobot/utils/evaluator.py
2026-04-06 06:30:11 +00:00
Xubin Ren
897d5a7e58 test: add regression tests for JID suffix classification and LID cache
Made-with: Cursor
2026-04-06 06:19:06 +00:00
Xubin Ren
35dde8a30e refactor: unify voice transcription config across all channels
- Move transcriptionProvider to global channels config (not per-channel)
- ChannelManager auto-resolves API key from matching provider config
- BaseChannel gets transcription_provider attribute, no more getattr hack
- Remove redundant transcription fields from WhatsAppConfig
- Update README: document transcriptionProvider, update provider table

Made-with: Cursor
2026-04-06 06:07:30 +00:00
Xubin Ren
7b7a3e5748 fix: media_paths NameError, import order, add error logging and tests
- Move media_paths assignment before voice message handling to prevent
  NameError at runtime
- Fix broken import layout in transcription.py (httpx/loguru after class)
- Add error logging to OpenAITranscriptionProvider matching Groq style
- Add regression tests for voice transcription and no-media fallback

Made-with: Cursor
2026-04-06 06:01:14 +00:00
Xubin Ren
c88d97c652 fix: fall back to heuristic when bot open_id fetch fails
If _fetch_bot_open_id returns None the exact-match path would silently
disable all @mention detection. Restore the old heuristic as a fallback.
Add 6 unit tests for _is_bot_mentioned covering both paths.

Made-with: Cursor
2026-04-06 13:49:38 +08:00