Commit Graph

691 Commits

Author SHA1 Message Date
Shaw
49bf73b228 fix(forms): keep PDF-form export from dropping values when the label has '*' (#1407)
parse_markdown_to_values — the read-back path for export-pdf, the export
preview, and prepare-signed-reply — matched the bold field label with [^*]+, so
it could not match a label containing '*' (the near-universal required-field
marker: "Email *", "State *", "Signature *"). The value then stayed empty, so
the exported PDF and the signed-reply attachment came out blank for that field
with no error — a whole form of required fields could export completely empty.

Match the label non-greedily (.+?) so '*' in labels is tolerated while still
splitting at the first ':**' / '**[', which also preserves a value that itself
contains ':**'.

Adds tests/test_form_markdown_roundtrip.py (render -> parse roundtrip): asterisk
text/choice/signature labels survive (fail before, pass after); plain labels and
colon-bearing values are unaffected.

Co-authored-by: NubsCarson <nubs@nubs.site>
2026-06-03 14:24:07 +09:00
Shaw
43ed3f7148 fix(contacts): parse Apple/iCloud item-grouped vCard EMAIL/TEL properties (#1438)
_parse_vcards matched property names with a bare line.startswith("EMAIL") /
"TEL" / "FN:" / "UID:". RFC 6350 property groups — emitted by default by Apple
Contacts / iCloud and many CardDAV servers — prefix the name with a group token,
e.g. item1.EMAIL;type=pref:jane@example.com. Those lines never matched, so emails
and phone numbers from any Apple-synced or Apple-exported address book were
silently dropped (breaking contact search by email, composer autocomplete, and
vCard/CSV export round-trips).

Strip an optional leading group token before matching and value extraction;
no-op for non-grouped lines.

Adds tests/test_contacts_vcard_parse.py (grouped + plain) — the grouped case
fails before this change and passes after.

Co-authored-by: NubsCarson <nubs@nubs.site>
2026-06-03 14:24:04 +09:00
ghreprimand
3eed73e11e Guard session message persistence after delete (#1451)
Co-authored-by: ghreprimand <203024559+ghreprimand@users.noreply.github.com>
2026-06-03 14:24:01 +09:00
Afonso Coutinho
f19265742c fix: SMTP envelope recipients split on commas inside display names (#1464) 2026-06-03 14:23:58 +09:00
Alexandre Teixeira
1c2ec288dd Check cudart before llama.cpp CUDA build (#1466) 2026-06-03 14:23:55 +09:00
Afonso Coutinho
b55c970ec5 fix: sports-hint ranking penalty fires on 'transport'/'passport' substrings (#1473)
* fix: sports-hint ranking penalty fires on 'transport'/'passport' substrings

* Apply word-boundary sports-hint fix to src/search/ranking.py as well
2026-06-03 14:23:52 +09:00
lekt8
ffb8fd16bc Disable pip cache for Cookbook dependency installs (off the home disk) (#1477)
Cookbook dependency installs (vLLM and friends) build large wheels; pip's
default cache lives under $HOME/.cache/pip, so on a small home filesystem the
build dies mid-way with "[Errno 28] No space left on device" (issue #1219) and
the dependency ends up "installed" but unusable (issue #1459).

Add `--no-cache-dir` to the dependency pip-install command (the maintainer's
suggested PIP_CACHE_DIR= workaround, made the default) via a small
_pip_install_no_cache() helper applied at the install chokepoint. Consistent
with the existing --no-cache-dir on the llama-cpp-python build. Idempotent;
non-pip-install serve commands are untouched.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 14:23:49 +09:00
Paulo Victor Cordeiro
1feb2ae7d5 fix: close AsyncExitStack on MCP init/tool-discovery failure (#1493)
If session.initialize() or list_tools() raises after the stdio
subprocess or SSE connection is already open, the AsyncExitStack is
never closed — leaking the child process or HTTP connection. Wrap the
setup phase in try/except to aclose() the stack before re-raising.
2026-06-03 14:23:46 +09:00
ghreprimand
8c4ea484a9 Cap inline attachment context across files (#1498)
Co-authored-by: ghreprimand <203024559+ghreprimand@users.noreply.github.com>
2026-06-03 14:23:43 +09:00
Ernest Hysa
a91321d1d8 Scope core.* module stubs to the test, not the module (#1513)
Three test files (test_auth_regressions, test_auth_event_loop,
test_null_owner_gates) install stubs for core.database / core.auth /
src.endpoint_resolver at module-import time, so they outlive the
file and are still present in sys.modules when later-collected test
files try to import the real modules. The stubs are minimal (a
handful of MagicMock attrs) so the import chain that follows fails
with ImportError on the very next real import.

test_companion_pairing also leaks, with a twist: its _DBStub
subclass returns a MagicMock for *any* attribute including dunders,
so the next test that does `from core.database import *` reads
`__all__` as a MagicMock and dies with 'Item in __all__ must be
str, not MagicMock'.

Move the stub installation into an autouse fixture per file and
register each stub with monkeypatch.setitem so sys.modules is
restored to its pre-test state on teardown. Tighten _DBStub to
refuse dunder names so __all__ stays undefined. _CAPTURED is
cleared per test so the mint-token assertions see a fresh dict.

Before: 3 test files fail at collection time (test_chat_image_routing,
test_context_compactor, test_webhook_ssrf_resilience). After: 0
collection errors. 1365/1370 pass, 1 skip, 4 unrelated pre-existing
failures (verified against origin/main baseline).

Out of scope: test_task_scheduler_session_delivery::
test_session_delivery_survives_empty_database also fails in the
full suite due to order-dependent state from a different test
file. That's a separate leak with a different root cause.
2026-06-03 14:23:40 +09:00
Afonso Coutinho
0dd67143f1 fix: PDF attach uses lstrip(chars) that eats body text, not the marker helper (#1541) 2026-06-03 14:23:37 +09:00
Afonso Coutinho
6e1df4ddc6 fix: POST /api/contacts/add crashes on JSON null name/email (None.strip()) (#1544) 2026-06-03 14:23:34 +09:00
Afonso Coutinho
f93755e7a4 fix: params_b crashes the whole ranking on a malformed parameter_count (#1550) 2026-06-03 14:23:30 +09:00
Lucas Daniel
398892cced fix(settings): catch PermissionError in load_settings + error-path tests (#1570)
PermissionError was not in the except tuple so an unreadable settings.json
would crash the app instead of falling back to defaults. Added alongside the
existing FileNotFoundError/JSONDecodeError/ValueError catches.

Also adds test_settings_error_paths.py covering all four failure modes:
missing file, corrupted JSON, wrong type, and permission denied.
2026-06-03 14:23:27 +09:00
Mahdi Salmanzade
cbf8103cba fix(login): keep inputs >=16px on touch so iOS doesn't zoom on focus (#1632)
The login page has its own inline <style> and doesn't load static/style.css,
so it never inherited the main app's touch-device rule that pins text inputs
to 16px. Its fields are 0.95rem (~15.2px) and the dynamically-inserted 2FA
input is 14px, so iOS Safari zooms the whole page when either is focused -
on the very first screen every user sees.

Add a `@media (hover: none) and (pointer: coarse)` rule raising
`input:not(.remember-check)` to 16px, mirroring the main app's approach.
!important also lifts the 2FA input, which pins font-size:14px inline.
Desktop is unchanged (inputs stay 0.95rem).
2026-06-03 14:23:24 +09:00
Afonso Coutinho
9bd11fd6e7 fix: Mixtral and Ministral models render with no provider logo (#1640) 2026-06-03 14:23:21 +09:00
danielroytel
39848a168b fix: recognize Gemma 4 as a thinking model and add context entry (#1642)
Gemma 4 returns reasoning_content in streaming responses via
llama-server, but the model wasn't listed in _THINKING_MODEL_PATTERNS,
causing reasoning tokens to be mishandled. Add "gemma" to the pattern
list and register Gemma 4's 128K context window in KNOWN_CONTEXT_WINDOWS
so the agent loop budgets context correctly.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-03 14:23:18 +09:00
Afonso Coutinho
b45611e9c5 fix: _strip_reasoning_prose discards the answer when reasoning trails it (#1643) 2026-06-03 14:23:15 +09:00
Afonso Coutinho
3e33cf6439 Anchor shell-verb intent patterns to imperative or can-you position (#1664) 2026-06-03 14:23:10 +09:00
Afonso Coutinho
8a0b79bc84 fix: deep research runs the prompt's example queries when the model echoes them (#1666) 2026-06-03 14:23:07 +09:00
Afonso Coutinho
26d040d116 fix: gallery records raw instead of display dimensions for EXIF-rotated photos (#1667) 2026-06-03 14:23:04 +09:00
Afonso Coutinho
b396252af6 fix: monthly tasks scheduled for day 29-31 skip every short month (#1668) 2026-06-03 14:23:01 +09:00
Afonso Coutinho
7f80d33210 fix: services research lists junk no-content pages as cited sources (#1669) 2026-06-03 14:22:58 +09:00
Afonso Coutinho
eae8797e08 fix: web search content blocks numbered by fetch completion order break citations (#1672) 2026-06-03 14:22:55 +09:00
Ethan
202df9dcde Fix HTTP 500 in history routes: order ChatMessage by timestamp, not created_at (#1673)
The mark-stopped, update-last-meta, and merge-last-assistant handlers in
routes/history_routes.py ordered ChatMessage queries by
DbChatMessage.created_at. ChatMessage does not inherit TimestampMixin and
has only a `timestamp` column, so SQLAlchemy raised AttributeError at
query-build time -> HTTP 500 on Stop, last-message metadata updates, and
Continue/merge. Each handler mutates in-memory history before the failing
query, so a failed request also silently diverged the in-memory view from
the database.

Order by DbChatMessage.timestamp (already used elsewhere in the file and
covered by the ix_messages_session_time index). Add a regression test
pinning the model column reality, the corrected query, and a guard against
re-introducing created_at.

Fixes #1659

Co-authored-by: Ethan <23321960+0xLeathery@users.noreply.github.com>
2026-06-03 14:22:51 +09:00
Afonso Coutinho
fbb52a73a0 fix: re-importing an ICS file duplicates every tz-aware timed event (#1683) 2026-06-03 14:22:49 +09:00
Afonso Coutinho
1161040efe fix: visual report drops photos whose URL slug contains icon or logo (#1685) 2026-06-03 14:22:45 +09:00
Afonso Coutinho
3d00c85636 fix: hwfit native quant labels miss the cost maps and over-estimate VRAM (#1690) 2026-06-03 14:22:42 +09:00
red person
77b92020c0 Ignore non-string markdown table rows (#1648) 2026-06-03 14:17:02 +09:00
red person
648900612e Ignore non-string calendar date inputs (#1649) 2026-06-03 14:16:58 +09:00
red person
100fd72e7a Ignore censor preference storage errors (#1652) 2026-06-03 14:16:55 +09:00
red person
12652581cb Ignore invalid model sort inputs (#1653) 2026-06-03 14:16:52 +09:00
red person
116ade4630 Ignore non-string signature fold metadata (#1655) 2026-06-03 14:16:48 +09:00
Afonso Coutinho
96d59d2ff9 fix: _parse_dt does not understand 'tonight' so event start/end breaks (#1488) 2026-06-03 14:14:41 +09:00
Shaw
eb5727abda fix(agent): coerce non-object tool-call arguments instead of crashing (#1370)
A native function/tool call whose `arguments` field is valid JSON but not an
object — a bare array like ["ls -la"], or a string/number/bool/null — parsed
fine in function_call_to_tool_block and then every branch called args.get(...),
raising AttributeError ('list'/'str' object has no attribute 'get'). That
propagated out of the streamed agent loop (no surrounding try/except at the
call site in stream_agent_loop) and aborted the user's entire turn. Weaker and
local models routinely emit malformed args like this.

Coerce non-dict parsed arguments to {} (mirrors the existing empty-arguments
behavior), so the tool runs with empty args instead of killing the stream.

Adds tests/test_function_call_non_object_args.py covering array/string/number/
bool/null arguments — they fail before this change and pass after.
2026-06-03 14:14:37 +09:00
Denis Kutuzov (Rybak27)
ec3b8b42ae fix: auto-naming for 24h time format (#1374)
* fix: auto-naming for 24h time format

needs_auto_name() required AM/PM suffix for default
frontend-generated names like 'deepseek-v4-flash 17:46:02'.
Frontend uses toLocaleTimeString() which outputs 24h
format in most locales — so the regex never matched and
auto-naming silently skipped.

Made AM/PM optional and added re.IGNORECASE for 'am'/'pm'.

* test: add regression tests for needs_auto_name (24h + 12h + custom)

---------

Co-authored-by: Calculator Dev <dev@calculator.local>
2026-06-03 14:14:34 +09:00
ghreprimand
41d2767b30 Replace task scheduler utcnow calls (#1456)
Co-authored-by: ghreprimand <203024559+ghreprimand@users.noreply.github.com>
2026-06-03 14:14:30 +09:00
Marius Oppedal Ringsby
4f03f5ccdd Replace cleanup service datetime.utcnow calls (#1494)
datetime.utcnow() is deprecated in Python 3.12 and removed in 3.14.
Swap the five calls in src/cleanup_service.py for a local _utcnow()
helper returning naive UTC, matching the naive DateTime columns the
archive/delete cutoffs compare against (same approach as the
task-scheduler and core-database slices). Add a regression test
asserting the helper stays naive so the cutoff math can't hit a
naive/aware TypeError.

Part of #1116
2026-06-03 14:14:27 +09:00
ghreprimand
6fd52cf317 Replace webhook manager datetime.utcnow calls (#1499)
Co-authored-by: ghreprimand <203024559+ghreprimand@users.noreply.github.com>
2026-06-03 14:14:23 +09:00
Alexandre Teixeira
c639daa7a2 Add companion pairing route response tests (#920) 2026-06-03 14:14:20 +09:00
Alexandre Teixeira
83a7965a28 Add atomic IO durability tests (#1622) 2026-06-03 14:14:16 +09:00
red person
ba6da17a92 Ignore non-object prefs JSON (#1257) 2026-06-03 14:12:45 +09:00
red person
84d54d9853 Ignore non-object embedding endpoint config (#1260) 2026-06-03 14:12:41 +09:00
red person
42ef4b6502 Skip invalid research CLI records (#1394) 2026-06-03 14:12:38 +09:00
red person
0e27a574b7 Reject invalid theme CLI prefs (#1396) 2026-06-03 14:12:35 +09:00
red person
56cd8add18 Fall back from invalid preset stores (#1402) 2026-06-03 14:12:31 +09:00
Prantik Pratim Medhi
4aabc068ed fix(ui): use raw data for 'Copy Chat' to avoid extra newlines (#1391)
- Prefer dataset.raw (original markdown) over innerText in _serializeChatTranscript.
- This prevents HTML-to-text artifacts and redundant newlines added by the browser.
2026-06-03 14:12:28 +09:00
Stephen Purdue
85bc18b7d8 fix: fixed minor consistency issues within MemoryManager (#1353) 2026-06-03 14:12:24 +09:00
Lucas Daniel
6419bf2cdf fix(docker): invoke setup.py on first container start (#1657)
setup.py initialises auth.json and .env on a fresh install but was never
called by the Docker entrypoint, leaving new deployments without admin
credentials or a working config.

Adds a single gosu-wrapped call to setup.py before the final exec drop.
setup.py is fully idempotent (skips existing files) so subsequent starts
are unaffected. || true ensures a setup failure never blocks the app from
starting.

Fixes #1476
2026-06-03 14:12:20 +09:00
Wes Huber
b30f02a3f0 fix(tests): align broken test assertions with current behavior (#1791)
* fix(tests): align broken test assertions with current behavior

- test_readme_native_quickstart_uses_loopback: README warning text
  moved from --host prefix to bind-to phrasing; update assertion
- test_sanitize_merges_consecutive_user_messages: consecutive user
  messages ARE merged and orphan tool messages ARE dropped by the
  adjacency repair pass; update expected counts and values

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(tests): update cookbook status poll assertion for stopped state

The cookbookRunning.js ternary now handles a 'stopped' status
alongside 'error', so the exact string match in the test no longer
holds. Relax the assertion to check for the error branch presence
instead of the full ternary expression.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-03 14:12:17 +09:00