Commit Graph

371 Commits

Author SHA1 Message Date
red person
38bfa85ad0 Reject invalid Tailscale discovery JSON (#1556)
* Reject invalid Tailscale discovery JSON

* Guard nested Tailscale IP shapes
2026-06-03 14:11:31 +09:00
red person
ab7145de83 Mask short webhook CLI tokens (#1558) 2026-06-03 14:11:28 +09:00
red person
9e91a172e7 Handle missing gallery album images (#1563) 2026-06-03 14:11:24 +09:00
red person
04e7441d78 Skip invalid contacts CLI rows (#1569) 2026-06-03 14:11:21 +09:00
red person
89b04675e2 Handle missing calendar CLI relation (#1574) 2026-06-03 14:11:17 +09:00
Afonso Coutinho
1453458519 fix: is_public_blocked_tool crashes on a truthy non-string tool name (#1620)
* fix: is_public_blocked_tool crashes on a truthy non-string tool name

* fix: is_public_blocked_tool fails closed (blocks) on a malformed non-string tool name
2026-06-03 14:11:14 +09:00
Afonso Coutinho
04f8aa1833 fix: _lookup_bandwidth crashes on a truthy non-string gpu_name (#1641) 2026-06-03 14:11:10 +09:00
red person
d1309f3bd6 Ignore non-object settings scrub inputs (#1645) 2026-06-03 14:11:05 +09:00
red person
b409b20940 Handle non-string src search queries (#1646) 2026-06-03 14:11:02 +09:00
red person
ade755b184 Let preset set replace corrupt entries (#1650) 2026-06-03 14:10:58 +09:00
red person
40e1d6e876 Reject non-PNG signature export data (#1651) 2026-06-03 14:10:54 +09:00
red person
558d6ddf24 Ignore invalid background job store rows (#1261) 2026-06-03 14:07:14 +09:00
red person
34efabdec8 Ignore invalid integration rows (#1404) 2026-06-03 14:07:11 +09:00
red person
43dc346255 Ignore invalid companion auth shapes (#1405) 2026-06-03 14:07:07 +09:00
red person
5fba1735c2 Ignore invalid editor draft payloads (#1533) 2026-06-03 14:07:03 +09:00
red person
d7a6cadbe2 Skip invalid memory extractor rows (#1535) 2026-06-03 14:07:00 +09:00
red person
d8f5c04340 Skip invalid ownerless JSON rows (#1540) 2026-06-03 14:06:57 +09:00
red person
ee8c049f9e Skip invalid skill extractor rows (#1546) 2026-06-03 14:06:53 +09:00
red person
815bdf57d5 Ignore non-string task CLI previews (#1559) 2026-06-03 14:06:49 +09:00
red person
347b193af8 Ignore non-string docs CLI content lengths (#1561) 2026-06-03 14:06:46 +09:00
red person
3b9c601498 Skip invalid personal CLI index rows (#1571) 2026-06-03 14:06:42 +09:00
Afonso Coutinho
1571d8bba0 fix: agent_tools._truncate crashes on non-string input (#1624)
* fix: agent_tools._truncate crashes on non-string input

* fix: agent_tools._truncate returns a string for non-string input, not the raw value
2026-06-03 14:06:39 +09:00
Afonso Coutinho
3a741edbf1 fix: visual_report markdown helpers crash on a non-string input (#1633) 2026-06-03 14:06:35 +09:00
red person
8af1f85665 Ignore non-string email thread bodies (#1654) 2026-06-03 14:06:31 +09:00
Afonso Coutinho
a54d34149a Parse standard Gmail quote attribution dates
Allow Gmail quote attribution parsing to handle standard US weekday/month/day/year comma patterns while preserving existing formats, with JS regression coverage.
2026-06-03 13:45:56 +09:00
Afonso Coutinho
46999debdb Decode email headers without injected spaces
Use email.header.make_header for MIME header decoding so adjacent encoded/plain header parts preserve RFC spacing, with regression coverage.
2026-06-03 13:45:33 +09:00
Afonso Coutinho
f29c827e6e Merge search analytics defaults in services copy
Make services.search.analytics tolerate missing counters in older or partial analytics files by merging loaded data over defaults, with regression coverage.
2026-06-03 13:45:07 +09:00
Afonso Coutinho
10e797a1aa Normalize scheduled email offsets before storage
Normalize scheduled email send_at values with timezone offsets or Z suffixes to naive UTC before storing, matching the poller's lexicographic comparison format and preventing early/late sends.
2026-06-03 13:44:18 +09:00
Afonso Coutinho
28dbd5346c Treat non-string research summaries as low quality
Filter malformed non-string research summaries instead of letting the broad exception path classify them as usable, with regression coverage.
2026-06-03 13:42:24 +09:00
Afonso Coutinho
a880b17624 Skip malformed personal keyword index rows
Make personal keyword retrieval tolerate corrupted non-dict index entries and missing chunk lists, with regression coverage.
2026-06-03 13:42:05 +09:00
Mubashir R
61d62a3cb8 Fix memory bullet extraction in service copy
Fix services.memory bullet-list extraction by grouping the bullet/number regex before the capture, and cover both memory manager copies in the regression test.
2026-06-03 13:41:46 +09:00
Marius Popa
4ec53a296a Fix document editor scrollbar and line-number sync
Fixes #1501
Fixes #1496
2026-06-03 13:40:19 +09:00
Afonso Coutinho
13f0171ce8 fix: extract_youtube_id crashes on a non-string url instead of returning None (#1689) 2026-06-03 13:38:11 +09:00
Afonso Coutinho
35b9509da3 fix: memory entry validation crashes on a non-dict row from memory.json (#1691) 2026-06-03 13:38:02 +09:00
Afonso Coutinho
f0b172020e fix: require_privilege 500s on a non-dict privileges blob from auth.json (#1693) 2026-06-03 13:37:54 +09:00
Rolly Calma
933c461f38 fix: use running loop for shell stream deadlines (#1694) 2026-06-03 13:37:46 +09:00
Afonso Coutinho
02ff2e3cb0 fix: updating a calendar event ignores user timezone and shifts the time (#1695) 2026-06-03 13:37:39 +09:00
Afonso Coutinho
667b739af4 fix: reply-all Cc builder crashes on a non-string To or Cc field (#1700) 2026-06-03 13:37:22 +09:00
Afonso Coutinho
19e62208d2 fix: streaming drops providers that emit SSE data lines with no space (#1701) 2026-06-03 13:37:14 +09:00
Afonso Coutinho
3da4edb442 fix: token usage dropped when it rides on a non-empty finish delta (#1703) 2026-06-03 13:36:57 +09:00
Afonso Coutinho
9dd9bb8a3f fix: memory recall crashes on a non-dict row from the vector store (#1705) 2026-06-03 13:35:09 +09:00
Afonso Coutinho
86d3af743a fix: docs RAG query crashes on a non-dict row from the index (#1706) 2026-06-03 13:35:01 +09:00
Afonso Coutinho
076607c9b9 fix: archive browser model filter is suffix-only and drops matching models (#1709) 2026-06-03 13:34:54 +09:00
Afonso Coutinho
56123e052b fix: compacting a chat with image attachments destroys the attachment (#1710) 2026-06-03 13:34:47 +09:00
Afonso Coutinho
f6f86c4b34 fix: research source extraction crashes on a non-dict finding (#1714) 2026-06-03 13:34:40 +09:00
Afonso Coutinho
29e19f326a fix: _resolve_user_upload_path crashes on a non-dict resolve_upload result (#1715) 2026-06-03 13:34:33 +09:00
Afonso Coutinho
55c7a4a546 fix: computeSnap throws when ctx.otherLayers is not an array (#1716) 2026-06-03 13:34:25 +09:00
Mubashir R
319ba50a44 fix: validate client-supplied image _endpoint to prevent SSRF (gallery proxies) (#1718)
POST /api/image/harmonize and POST /api/image/inpaint read an `_endpoint` from
the request body and issue server-side httpx POSTs to it with no validation. A
caller can set `_endpoint` to http://169.254.169.254/ (cloud instance metadata)
or any internal/loopback address the server can reach, turning these routes into
an SSRF primitive.

routes/embedding_routes.py already runs its user-supplied endpoint through
src.url_safety.check_outbound_url; these two routes were missing the same guard.
Validate `_endpoint` the same way before any outbound request: non-HTTP(S)
schemes and the link-local metadata range are always rejected, and
IMAGE_BLOCK_PRIVATE_IPS=true blocks private/loopback for full lockdown (the
local-first default still allows LAN diffusion servers).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 13:34:17 +09:00
Mubashir R
535d05c142 fix: SearchService.search() calls comprehensive_web_search incorrectly (broken public API) (#1720)
SearchService.search() did:

    raw_results = await comprehensive_web_search(
        query, max_results=10 * depth, fetch_content=fetch_content)

comprehensive_web_search is a synchronous function whose count knob is
`max_pages` (not `max_results`) and which has no `fetch_content` parameter, so
the call raised TypeError on argument binding; `await` on its non-coroutine
return would also fail. It returns a context string, or a (context, sources)
tuple with return_sources=True — not the list of dicts the wrapper iterates.

The method is exported in services/search/__init__.py and services/__init__.py
with a usage example in its docstring, so any caller of the documented public
API hit an immediate crash. Call it correctly via asyncio.to_thread with
max_pages + return_sources=True and use the returned source list as the rows.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 13:33:56 +09:00
lekt8
126e91e8b9 Don't attempt the same (url, model) route twice in the fallback chains (#1733)
The fallback helpers (llm_call_with_fallback, llm_call_async_with_fallback,
stream_llm_with_fallback) build their candidate list as the primary target
followed by the configured fallbacks. Callers prepend the session's live
(url, model) to default_model_fallbacks, so if the user also lists their current
model among the fallbacks — a common misconfiguration — the chain re-attempts
the very route that just failed: a wasted round-trip (and, for the streaming
path, a spurious 'fallback' notice for a switch that didn't actually happen).

Add a small _dedupe_candidates() helper that filters malformed entries and drops
a later repeat of an already-seen (url, model), preserving order (first wins,
keeping its headers). Apply it in all three fallback chains.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 13:33:50 +09:00