Some LLM providers return tool_calls[0].arguments as a list instead of
dict or str. Add handling to extract the first dict element from the list.
Fixes /new command warning: 'unexpected arguments type list'
SIGHUP and SIGPIPE are not available on Windows. Add hasattr() checks
before registering these signal handlers to prevent AttributeError on
Windows systems.
Fixes compatibility issue introduced in PR #1400.
Commit 0209ad5 moved `import lark_oapi as lark` inside the start()
method (lazy import) to suppress DeprecationWarnings. This had an
unintended side effect: the import now happens after the main asyncio
loop is already running, so lark_oapi's module-level
loop = asyncio.get_event_loop()
captures the running main loop. When the WebSocket thread then calls
loop.run_until_complete() inside Client.start(), Python raises:
RuntimeError: This event loop is already running
and the _connect/_disconnect coroutines are never awaited.
Fix: in run_ws(), create a fresh event loop with asyncio.new_event_loop(),
set it as the thread's current loop, and patch lark_oapi.ws.client.loop
to point to this dedicated loop before calling Client.start(). The loop
is closed on thread exit.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Feishu's GetMessageResource API only accepts 'image' or 'file' as the
type parameter. When downloading voice messages, nanobot was passing
'audio' which caused the API to reject the request with an error.
This fix converts 'audio' to 'file' in _download_file_sync method
before making the API call, allowing voice messages to be downloaded
and transcribed successfully.
Fixes voice message download failure in Feishu channel.
- test_context_prompt_cache: Update test to reflect merged runtime
context and user message (commit ad99d5a merged them into one)
- Remove test_cron_commands.py: cron add CLI command was removed
in commit c05cb2e (unified scheduling via cron tool)
The OpenAI Codex provider accepts reasoning_effort but silently
discards it. Wire it through as {"reasoning": {"effort": ...}} in
the request body so the config option actually takes effect.
- test_context_prompt_cache: Update test to reflect merged runtime
context and user message (commit ad99d5a merged them into one)
- Remove test_cron_commands.py: cron add CLI command was removed
in commit c05cb2e (unified scheduling via cron tool)
ReadFileTool had no file size check — reading a multi-GB file would
load everything into memory and crash the process. Now:
- Rejects files over ~512KB at the byte level (fast stat check)
- Truncates at 128K chars with a notice if content is too long
- Guides the agent to use exec with head/tail/grep for large files
This matches the protection already in ExecTool (10KB) and
WebFetchTool (50KB).
datetime.fromisoformat(at) raises ValueError for malformed strings,
which propagated uncaught and crashed the tool execution. Now catches
ValueError and returns a user-friendly error message instead.
When the LLM returns malformed tool arguments (e.g. a list or string
instead of a dict), validate_params would crash with AttributeError
in _validate() when calling val.items(). Now returns a clear
validation error instead of crashing.