From 2918739489dcd54e401f115e015d922351133a29 Mon Sep 17 00:00:00 2001 From: pewdiepie-archdaemon Date: Wed, 1 Jul 2026 11:12:55 +0000 Subject: [PATCH] Fix merged test regressions --- routes/chat_routes.py | 8 +++++--- routes/email_routes.py | 2 ++ routes/model_routes.py | 2 ++ routes/upload_routes.py | 2 ++ src/tools/calendar.py | 7 +++++++ static/js/tasks.js | 2 +- tests/test_calendar_recurrence.py | 2 +- tests/test_cookbook_cpu_only_serve.py | 2 +- tests/test_cookbook_dependency_completion_regression.py | 4 ++-- tests/test_upload_error_surfaced.py | 2 +- 10 files changed, 24 insertions(+), 9 deletions(-) diff --git a/routes/chat_routes.py b/routes/chat_routes.py index 35605fcf3..f7b4cc862 100644 --- a/routes/chat_routes.py +++ b/routes/chat_routes.py @@ -1359,9 +1359,11 @@ def setup_chat_routes( elif chunk.startswith("event: "): yield chunk elif chunk == "data: [DONE]\n\n": - if full_response: + _has_tool_events = bool((last_metrics or {}).get("tool_events")) + if full_response or _has_tool_events: + _response_to_save = full_response or "Done." _saved_id = save_assistant_response( - sess, session_manager, session, full_response, last_metrics, + sess, session_manager, session, _response_to_save, last_metrics, character_name=ctx.preset.character_name, web_sources=web_sources, rag_sources=ctx.rag_sources, @@ -1371,7 +1373,7 @@ def setup_chat_routes( if _saved_id: yield f'data: {json.dumps({"type": "message_saved", "id": _saved_id})}\n\n' run_post_response_tasks( - sess, session_manager, session, message, full_response, + sess, session_manager, session, message, _response_to_save, last_metrics, ctx.uprefs, memory_manager, memory_vector, webhook_manager, incognito=incognito, compare_mode=compare_mode, character_name=ctx.preset.character_name, diff --git a/routes/email_routes.py b/routes/email_routes.py index cdbdfe032..7c3af62e2 100644 --- a/routes/email_routes.py +++ b/routes/email_routes.py @@ -2388,6 +2388,8 @@ def setup_email_routes(): owner: str = Depends(require_owner), ): """Read email body. Cached for 30m, sync IMAP work runs in a thread.""" + mark_seen = True if mark_seen is True or str(mark_seen).lower() == "true" else False + full = True if full is True or str(full).lower() == "true" else False fixture_result = _fixture_email_read(uid, folder, owner) if fixture_result is not None: return fixture_result diff --git a/routes/model_routes.py b/routes/model_routes.py index bab782802..e29f2112a 100644 --- a/routes/model_routes.py +++ b/routes/model_routes.py @@ -218,6 +218,8 @@ def _default_endpoint_needs_assignment( return True if current_default_id not in enabled_endpoint_ids: return True + if current_default_endpoint is None: + return False if not (current_default_model or "").strip(): return True visible = _endpoint_visible_model_ids(current_default_endpoint) diff --git a/routes/upload_routes.py b/routes/upload_routes.py index 7df194e9a..1bd402ac8 100644 --- a/routes/upload_routes.py +++ b/routes/upload_routes.py @@ -137,6 +137,8 @@ def setup_upload_routes(upload_handler): session_id: Optional[str] = Form(None), ): """Upload files with enhanced security and organization.""" + if not isinstance(session_id, str): + session_id = None if not files: raise HTTPException(400, "No files uploaded") diff --git a/src/tools/calendar.py b/src/tools/calendar.py index 9cd994d8a..c1ebc43c8 100644 --- a/src/tools/calendar.py +++ b/src/tools/calendar.py @@ -254,6 +254,7 @@ async def do_manage_calendar(content: str, owner: Optional[str] = None) -> Dict: "calendar_href": ev.calendar_id, "event_type": ev.event_type or "", "importance": ev.importance or "normal", + "rrule": ev.rrule or "", }) if not events: response_text = f"No events between {start_dt.date().isoformat()} and {end_dt.date().isoformat()}." @@ -268,6 +269,8 @@ async def do_manage_calendar(content: str, owner: Optional[str] = None) -> Dict: line += f" #{ev['event_type']}" if ev.get("importance") and ev["importance"] != "normal": line += f" !{ev['importance']}" + if ev.get("rrule"): + line += f" repeats({ev['rrule']})" if ev.get("location"): line += f" @ {ev['location']}" if ev.get("calendar"): @@ -480,6 +483,10 @@ async def do_manage_calendar(content: str, owner: Optional[str] = None) -> Dict: ev.event_type = _tag or None if args.get("importance") is not None: ev.importance = args["importance"] + if args.get("rrule") is not None: + ev.rrule = args.get("rrule") or "" + elif str(args.get("repeat") or "").strip().lower() in {"none", "no", "off", "false", "single"}: + ev.rrule = "" is_caldav = ev.calendar and ev.calendar.source == "caldav" if is_caldav: ev.caldav_sync_pending = "update" diff --git a/static/js/tasks.js b/static/js/tasks.js index 4172a429b..69c6bb1c1 100644 --- a/static/js/tasks.js +++ b/static/js/tasks.js @@ -1017,7 +1017,7 @@ function _showTaskDropdown(anchor, items) { const dd = document.createElement('div'); dd.className = 'task-dropdown'; dd._anchor = anchor; - dd.style.cssText = 'position:fixed;z-index:100000;background:var(--panel);border:1px solid var(--border);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,0.3);padding:4px;min-width:120px;'; + dd.style.cssText = `position:fixed;z-index:${topPortalZ()};background:var(--panel);border:1px solid var(--border);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,0.3);padding:4px;min-width:120px;`; items.forEach(item => { const btn = document.createElement('button'); btn.style.cssText = 'display:flex;align-items:center;gap:8px;width:100%;text-align:left;padding:6px 10px;border:none;background:none;color:var(--fg);font-size:11px;font-family:inherit;cursor:pointer;border-radius:4px;transition:background 0.1s;'; diff --git a/tests/test_calendar_recurrence.py b/tests/test_calendar_recurrence.py index 798bc7ba7..51106df52 100644 --- a/tests/test_calendar_recurrence.py +++ b/tests/test_calendar_recurrence.py @@ -86,7 +86,7 @@ def test_expand_non_recurring_returns_single(): def test_expand_rrule_skips_deleted_occurrence_exdate(): - cal = _import_calendar_helpers() + cal = import_calendar_routes() ev = _make_event( dtstart=datetime(2026, 7, 1, 14, 0), dtend=datetime(2026, 7, 1, 15, 0), diff --git a/tests/test_cookbook_cpu_only_serve.py b/tests/test_cookbook_cpu_only_serve.py index 3de0c0f2d..900c775fe 100644 --- a/tests/test_cookbook_cpu_only_serve.py +++ b/tests/test_cookbook_cpu_only_serve.py @@ -102,7 +102,7 @@ def test_local_windows_platform_comes_from_backend_host_state(): assert "platform: _envState.hostPlatform || _envState.platform || ''" not in text assert 'return "windows" if IS_WINDOWS else ""' in routes assert 'env["hostPlatform"] = _client_host_platform()' in routes - assert "return _state_for_client({})" in routes + assert "client_state = _state_for_client({})" in routes assert 'env.pop("hostPlatform", None)' in routes assert "delete env.hostPlatform;" in running diff --git a/tests/test_cookbook_dependency_completion_regression.py b/tests/test_cookbook_dependency_completion_regression.py index 8bca23b90..53cfa93c5 100644 --- a/tests/test_cookbook_dependency_completion_regression.py +++ b/tests/test_cookbook_dependency_completion_regression.py @@ -35,8 +35,8 @@ def test_windows_session_commands_use_shared_powershell_wrapper_and_local_log_di assert "host ? '$env:TEMP\\\\odysseus-sessions' : '$env:TEMP\\\\odysseus-tmux'" in source assert "function _winPowerShellCmd(task, ps)" in source assert "const command = `powershell -Command \"${ps}\"`;" in source - assert "if (!task.remoteHost) return command;" in source - assert "return `ssh ${_sshPrefix(_getPort(task))}${task.remoteHost} ${_shQuote(command)}`;" in source + assert "if (!host) return command;" in source + assert "return `ssh ${_sshPrefix(_getPort(task))}${host} ${_shQuote(command)}`;" in source def test_dep_install_success_recognized_from_exit_sentinel(): diff --git a/tests/test_upload_error_surfaced.py b/tests/test_upload_error_surfaced.py index 1eb267999..4e5be7763 100644 --- a/tests/test_upload_error_surfaced.py +++ b/tests/test_upload_error_surfaced.py @@ -17,7 +17,7 @@ SRC = Path(__file__).resolve().parent.parent / "static/js/fileHandler.js" def _upload_pending_body() -> str: text = SRC.read_text(encoding="utf-8") - start = text.index("export async function uploadPending()") + start = text.index("export async function uploadPending(") rest = text[start:] m = re.search(r"\n(export |function )", rest[1:]) return rest[: m.start() + 1] if m else rest