* fix: exclude deepseek from local tool-calling keyword list
deepseek-r1 on Ollama returns HTTP 400 when tool schemas are sent.
The cloud API (api.deepseek.com) is already caught by the _API_HOSTS
check, so the generic 'deepseek' keyword match was only causing false
positives for local Ollama-served models.
* fix: add model no-tools blocklist and regression tests for deepseek-r1
The previous fix removed 'deepseek' from the keyword allow-list, but
_is_api_model is still True for localhost endpoints because 'localhost'
appears in _API_HOSTS — so the keyword change had no effect for Ollama.
Proper fix: add an explicit _model_no_tools blocklist ('deepseek-r1')
that overrides the endpoint URL check. The endpoint's supports_tools DB
flag still takes priority either way (True forces tools on, False forces
them off), so users can override per-endpoint when needed.
Also refined the deepseek allow-list: 'deepseek-v' and 'deepseek-chat'
cover the cloud models (v2, v3, chat) that do support tools, without
matching deepseek-r1 variants.
13 regression tests cover:
- deepseek-r1 on localhost/docker: no tools (was HTTP 400)
- deepseek-v3/chat on api.deepseek.com: tools enabled (no regression)
- endpoint_supports=True/False overrides both lists
- qwen/llama on localhost: unaffected
Two bugs in the export_ics path:
1. X-WR-CALNAME was written raw: calendar names containing commas,
semicolons or backslashes produced invalid ICS (RFC 5545 §3.3.11
requires those characters to be escaped as \, \; and \\).
Fix: wrap cal.name in the existing _ics_escape() helper, which is
already used for SUMMARY, DESCRIPTION, and LOCATION on the lines
immediately below.
2. DTSTART and DTEND on non-all-day events always emitted the naive
ISO string (e.g. 20260602T100000) regardless of CalendarEvent.is_utc.
Consumers treat a naive datetime as floating/local time, so UTC
events imported into Google Calendar or Apple Calendar shifted by
the user's timezone offset. Fix: append 'Z' when is_utc is True,
matching the pattern already used by the serialise_event() helper
at line 408.