LLMs sometimes pass "" for optional parameters instead of omitting them.
Previously, passing url: "" to skill_install would match the explicit-URL
branch and attempt to fetch from an empty string, producing an invalid URL
error instead of falling back to the catalog lookup.
Fix by adding .filter(|s| !s.is_empty()) so an empty url is treated the
same as a missing field.
A unit test verifies the parameter filtering behaviour directly; the full
execute path (catalog lookup + install) requires a real catalog and database
and cannot be covered at the unit level.
* fix(web): handle Safari IME composition Enter key
Safari sets e.isComposing=false on the keydown event that ends IME
composition, unlike Chrome/Firefox. This caused pressing Enter to confirm
CJK input to immediately send the message.
Track composition state manually via compositionstart/compositionend and
guard the send condition with both e.isComposing and _isComposing.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
* fix(web): improve Safari IME comment with WebKit bug reference
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---------
Co-authored-by: Claude Sonnet 4.6 <[email protected]>
LLMs sometimes pass "" for optional parameters instead of omitting
them. Previously, passing timezone: "" or from_timezone: "" to the
time tool would trigger a parse error ("Unknown timezone ''") rather
than falling back to the context timezone or UTC.
Fix by adding .filter(|s| !s.is_empty()) after .as_str() in
resolve_timezone_for_output and optional_timezone, so empty strings
are treated the same as a missing field.
The same pattern exists in routine.rs (cron trigger timezone and
schedule fields), where "" produces "invalid IANA timezone: ''" or a
cron parse error. That will be addressed separately once routine.rs
has a test harness in place.
Regression tests added for the now and convert operations with
empty timezone strings.
Closes#1127
* fix(safety): allow empty string tool params
* fix(safety): preserve heuristic checks and add path context to tool validation
This follow-up refactor addresses PR review feedback by restoring
heuristic checks (whitespace ratio, character repetition) for tool
parameter validation and improving error reporting.
Changes:
- Restored heuristic warnings in validate_non_empty_input so they apply
to both user input and tool parameters (when non-empty).
- Refactored check_strings to recursively build and pass JSON paths
(e.g., "metadata.tags[1]").
- Updated validation errors to use the specific JSON path as the field
name instead of the generic "input".
- Added regression tests for whitespace/repetition warnings and JSON
path reporting in tool parameters.
This ensures the safety layer remains semantically neutral about empty
strings (fixing the memory_tree path: "" issue) while maintaining
rigorous protection and providing better developer ergonomics.
* style: run cargo fmt
When running as a launchd/systemd daemon, stdin is /dev/null.
rustyline reads EOF immediately and the REPL thread was sending
a /quit message, causing the agent to shut down right after
startup — making service mode non-functional on both macOS and Linux.
Fix: check std::io::stdin().is_terminal() before sending /quit on
EOF. In daemon mode (no TTY) the REPL thread exits silently, leaving
other channels (gateway, telegram, …) running as expected.
Fixes#723
Co-authored-by: Claude Sonnet 4.6 <[email protected]>
Co-authored-by: Zaki Manian <[email protected]>