When LLM passes a directory path to astrbot_file_read_tool, the tool previously
returned Error: [Errno 13] Permission denied, misleading the LLM into thinking
it was a permissions issue. The real cause: _probe_local_file() calls open('rb')
on the path, which fails on directories with Errno 13 on Windows. This is caught
by except PermissionError and displayed as-is.
Fix: Add os.path.isdir() check in FileReadTool.call() before any file I/O, at
the earliest safe point after path normalization and permission validation.
Returns a clear message: '<path> is a directory, not a file. Use a file path
instead, or use astrbot_execute_shell to list directory contents.'
Changes:
- astrbot/core/tools/computer_tools/fs.py: add isdir guard
- tests/test_computer_fs_tools.py: add test_file_read_tool_rejects_directory_with_clear_message
* fix: preserve assistant messages with reasoning_content in sanitize pass
When _sanitize_assistant_messages encounters an assistant message with empty content and no tool_calls but with reasoning_content, keep it with content set to empty string instead of dropping it. Reasoning models (DeepSeek V4, MiMo, etc.) require this history for subsequent turn validation.
* Update astrbot/core/provider/sources/openai_source.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
* fix: default to empty TokenUsage when completion.usage is None
When completion.usage is None (e.g. certain proxy/streaming edge cases), llm_response.usage stayed unset (None). Plugins accessing .input_tokens on it would crash with AttributeError.
Always assign llm_response.usage — extract from completion.usage if present, otherwise fall back to a zeroed TokenUsage().
Closes#8605
---------
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: renchonghan <renchonghan@users.noreply.github.com>
* sanitize orphaned tool_result blocks in Anthropic provider
Sanitize tool_result blocks and merge consecutive messages with the same role to comply with Anthropic API requirements.
* Fix content handling in message merging logic
* fix: sanitize anthropic assistant messages
* fix: validate anthropic tool result ordering
---------
Co-authored-by: Soulter <905617992@qq.com>
Only mark installed plugins as updatable when the marketplace version is a known newer version, including pre-release-to-stable transitions. Conflict resolution also keeps per-plugin marketplace source lookup from current master.
* fix: reliably kill shell process tree on Windows timeout
Fixes#8809
* fix: remove redundant import and wrap taskkill in try/except
- Remove 'import subprocess as _sp' (subprocess already imported at top)
- Use subprocess.run directly with DEVNULL for stdout/stderr
- Wrap taskkill in try/except to avoid masking original TimeoutExpired
- If taskkill fails, cleanup failures don't prevent proc.wait() or re-raise
https://buymeacoffee.com/muhamedfazalps
* style: apply ruff formatting to local.py
* test: fix shell component tests to match Popen-based implementation
The tests were monkeypatching subprocess.run but the implementation
now uses subprocess.Popen + communicate() for timeout handling.
Updated tests to mock Popen instead.
Fixes CI Unit Tests failure
* fix: harden windows shell timeout cleanup
---------
Co-authored-by: Soulter <905617992@qq.com>
- Add At component handling in _parse_to_qqofficial method
- Convert At(qq=openid) to <@openid> plain_text format
- Maintain original message chain order by appending
- Skip At(qq='all') since QQ Official API may not support it
Closes#8982
- Add ExaWebSearchTool (web_search_exa) with keyword/semantic search,
category filters, domain restrictions, and date range support
- Add ExaGetContentsTool (exa_get_contents) for extracting web page content
- Add _exa_search() and _exa_get_contents() API helpers hitting
https://api.exa.ai/search and https://api.exa.ai/contents
- Add _EXA_KEY_ROTATOR for multi-key rotation
- Register Exa tools in _apply_web_search_tools() dispatch
- Add Exa to WEB_SEARCH_CITATION_TOOL_NAMES for citation support
- Add websearch_exa_key config default and provider option
- Add i18n metadata for en-US, zh-CN, ru-RU
- Add Exa section to docs (en + zh)
- Add 6 unit tests covering search, contents, error handling, and
legacy config migration
Closes#5621