1736 Commits

Author SHA1 Message Date
flobo3
67e6f8cc7a fix(docker): strip Windows CRLF from entrypoint.sh 2026-04-07 13:32:01 +08:00
Jiajun Xie
5ee96721f7 ci: add ruff lint check for unused imports and variables
Add CI step to detect unused imports (F401) and unused variables (F841)
with ruff. Clean up existing violations:

- Remove unused Consolidator import in agent/__init__.py
- Remove unused re import in agent/loop.py
- Remove unused Path import in channels/feishu.py
- Remove unused ContentRepositoryConfigError import in channels/matrix.py
- Remove unused field and CommandHandler imports in channels/telegram.py
- Remove unused exception variable in channels/weixin.py
2026-04-07 13:30:49 +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
Leo fu
44c7992095 fix(filesystem): correct write success message from bytes to characters
len(content) counts Unicode code points, not UTF-8 bytes. For non-ASCII
content such as Chinese or emoji, the reported count would be lower than
the actual bytes written to disk, which is misleading to the agent.
2026-04-07 13:22:00 +08:00
bahtya
cefeddab8e fix(matrix): correct e2eeEnabled camelCase alias mapping
The pydantic to_camel function generates 'e2EeEnabled' (treating 'ee'
as a word boundary) for the field 'e2ee_enabled'. Users writing
'e2eeEnabled' in their config get the default value instead.

Fix: add explicit alias='e2eeEnabled' to override the incorrect
auto-generated alias. Both 'e2eeEnabled' and 'e2ee_enabled' now work.

Fixes #2851
2026-04-07 13:20:55 +08:00
Xubin Ren
bf459c7887 fix(docker): fix volume mount path and add permission error guidance 2026-04-06 13:15:40 +00:00
Xubin Ren
4dac0a8930 docs: update nanobot docs badge 2026-04-06 11:55:47 +00:00
Xubin Ren
a30e84bfd1 docs: update v0.1.5 release news 2026-04-06 11:46:16 +00:00
Xubin Ren
6269876bc7 docs: update v0.1.5 release news 2026-04-06 11:45:37 +00:00
Xubin Ren
bc2253c83f docs: update v0.1.5 release news 2026-04-06 11:45:08 +00:00
Xubin Ren
b719da7400 fix(feishu): use RawRequest for bot info API 2026-04-06 11:39:23 +00:00
Xubin Ren
79234d237e chore: bump version to 0.1.5 v0.1.5 2026-04-06 11:26:07 +00:00
Xubin Ren
1243c08745 docs: update news section 2026-04-06 11:22:20 +00: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
yanghan-cyber
e528e6dd96 fix(status): parse actual Tavily API response structure
The Tavily /usage endpoint returns a nested "account" object with
plan_usage/plan_limit/search_usage/etc fields, not the flat structure
with used/limit/breakdown that was assumed. This caused all usage
values to be None.
2026-04-06 19:17:55 +08:00
yanghan-cyber
84f0571e0d fix(status): use correct AgentLoop attribute for web search config
The /status command tried to access web search config via
`loop.config.tools.web.search`, but AgentLoop has no `config` attribute.
This caused the search usage lookup to silently return None, so web
search provider usage was never displayed.

Fix: use `loop.web_config.search` which is the actual attribute
set during AgentLoop.__init__.
2026-04-06 19:17:55 +08:00
Xubin Ren
f65f788ab1
Merge PR #2762: fix: make app-layer retry classification structured
fix: make app-layer retry classification structured (408/409/timeout/connection)
2026-04-06 16:47:49 +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
d108879b48 security: bind api port to localhost by default
Prevents accidental exposure to the public internet. Users who need
external access can change to 0.0.0.0:8900:8900 explicitly.

Made-with: Cursor
2026-04-06 16:20:20 +08:00
Xubin Ren
634261f07a fix: correct api-workspace path for non-root container user
The Dockerfile runs as user nanobot (HOME=/home/nanobot), not root.

Made-with: Cursor
2026-04-06 16:20:20 +08:00
dengjingren
d99331ad31 feat(docker): add nanobot-api service with isolated workspace
- Add nanobot-api service (OpenAI-compatible HTTP API on port 8900)
- Uses isolated workspace (/root/.nanobot/api-workspace) to avoid
  session/memory conflicts with nanobot-gateway

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 16:20:20 +08: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
PlayDustinDB
bd94454b91 feat(think): adjust thinking method for dashscope and modelark 2026-04-06 16:12:08 +08:00
Xubin Ren
c0e161de23 docs: add attachment example to email config JSON
Made-with: Cursor
2026-04-06 15:09:44 +08:00
Xubin Ren
b98a0aabfc style: fix stdlib import ordering in email.py
Made-with: Cursor
2026-04-06 15:09:44 +08:00
Ben Lenarts
0c4b1a4a0e docs(email): document attachment extraction options in README 2026-04-06 15:09:44 +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
9174a85b4e
Merge PR #2520: fix(telegram): split oversized final streamed replies
fix(telegram): split oversized final streamed replies
2026-04-06 14:41:00 +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
09ec9991e1 Merge remote-tracking branch 'origin/main' into pr-2520
Made-with: Cursor

# Conflicts:
#	nanobot/channels/telegram.py
2026-04-06 06:37:54 +00:00
Xubin Ren
b92d54140d
Merge PR #2449: fix: cron reminder notifications being suppressed
fix: cron reminder notifications being suppressed
2026-04-06 14:33:20 +08: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
219c9c6137
Merge PR #2531: fix(whatsapp): detect phone vs LID by JID suffix, not field name
fix(whatsapp): detect phone vs LID by JID suffix, not field name
2026-04-06 14:21:06 +08: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
722ffe0654 Merge remote-tracking branch 'origin/main' into pr-2531
Made-with: Cursor

# Conflicts:
#	nanobot/channels/whatsapp.py
2026-04-06 06:17:56 +00:00
Xubin Ren
4c6a4321e0
Merge PR #2530: feat: unify voice message transcription via OpenAI/Groq Whisper
feat: unify voice message transcription via OpenAI/Groq Whisper
2026-04-06 14:16:09 +08:00
Xubin Ren
019eaff225 simplify: remove transcription fallback, respect explicit config
Configured provider is the only one used — no silent fallback.

Made-with: Cursor
2026-04-06 06:13:43 +00:00
Xubin Ren
3bf1fa5225 feat: auto-fallback to other transcription provider on failure
When the primary transcription provider fails (bad key, API error, etc.),
automatically try the other provider if its API key is available.

Made-with: Cursor
2026-04-06 06:10:08 +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
413740f585 Merge remote-tracking branch 'origin/main' into pr-2530
Made-with: Cursor

# Conflicts:
#	nanobot/channels/whatsapp.py
2026-04-06 05:59:31 +00:00
Xubin Ren
71061a0c82 fix: return on login failure, use loguru format strings, fix import order
- Add missing return after failed password login to prevent starting
  sync loop with no credentials
- Replace f-strings in logger calls with loguru {} placeholders
- Fix stdlib import order (asyncio before json)

Made-with: Cursor
2026-04-06 13:57:57 +08:00
Lim Ding Wen
c40801c8f9 fix(matrix): fix e2ee authentication 2026-04-06 13:57:57 +08:00
Xubin Ren
f82b5a1b02 fix: graceful fallback when langfuse is not installed
- Use import importlib.util (not bare importlib) for find_spec
- Warn and fall back to standard openai instead of crashing with
  ImportError when LANGFUSE_SECRET_KEY is set but langfuse is missing

Made-with: Cursor
2026-04-06 13:53:42 +08:00
lang07123
4e06e12ab6 feat(provider): 添加 Langfuse 观测平台的集成支持
feat(provider): 添加 Langfuse 观测平台的集成支持
2026-04-06 13:53:42 +08: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
有泉
1b368a33dc fix(feishu): match bot's own open_id in _is_bot_mentioned to prevent cross-bot false positives
Previously, _is_bot_mentioned used a heuristic (no user_id + open_id
prefix "ou_") which caused other bots in the same group to falsely
think they were mentioned. Now fetches the bot's own open_id via
GET /open-apis/bot/v3/info at startup and does an exact match.
2026-04-06 13:49:38 +08:00
Xubin Ren
424b9fc262 refactor: extract _kill_process helper to DRY timeout/cancel cleanup
Made-with: Cursor
2026-04-06 13:47:09 +08:00