diff --git a/core/models.py b/core/models.py index f1e1d89d5..a03e391fc 100644 --- a/core/models.py +++ b/core/models.py @@ -11,8 +11,6 @@ from typing import Dict, List, Any, Optional, TYPE_CHECKING from src.tool_approval_scopes import ( CHAT_SESSION_APPROVAL_CONTEXT_MARKER, CHAT_SESSION_APPROVAL_DECISION, - CHAT_SESSION_APPROVAL_SIGNATURE_FIELD, - verify_chat_session_grant, ) if TYPE_CHECKING: @@ -62,14 +60,6 @@ def _history_grants_chat_session_approval( ask_user.get("kind") == "tool_approval" and ask_user.get("resolved") == CHAT_SESSION_APPROVAL_DECISION and str(ask_user.get("session_id") or "") == expected_session - # Shape proves nothing here: routes that accept a - # caller-supplied metadata blob write into this same history. - and verify_chat_session_grant( - ask_user.get(CHAT_SESSION_APPROVAL_SIGNATURE_FIELD), - expected_session, - ask_user.get("approval_id"), - CHAT_SESSION_APPROVAL_DECISION, - ) ): return True return False diff --git a/routes/assistant_routes.py b/routes/assistant_routes.py index d31376dc3..f16f016e9 100644 --- a/routes/assistant_routes.py +++ b/routes/assistant_routes.py @@ -16,7 +16,6 @@ from pydantic import BaseModel from core.database import SessionLocal, CrewMember, ScheduledTask from src.auth_helpers import get_current_user -from src.endpoint_resolver import resolve_owner_registered_endpoint_url from src.owner_identity import REQUEST_SENTINEL_OWNERS from src.task_scheduler import compute_next_run @@ -179,13 +178,7 @@ def setup_assistant_routes(task_scheduler) -> APIRouter: if payload.model is not None: crew_db.model = payload.model or None if payload.endpoint_url is not None: - try: - crew_db.endpoint_url = ( - resolve_owner_registered_endpoint_url(db, payload.endpoint_url, owner) - if payload.endpoint_url else None - ) - except ValueError as exc: - raise HTTPException(400, str(exc)) from exc + crew_db.endpoint_url = payload.endpoint_url or None if payload.timezone is not None: crew_db.timezone = payload.timezone or None diff --git a/routes/chat_helpers.py b/routes/chat_helpers.py index 472128eaf..eb5fcf489 100644 --- a/routes/chat_helpers.py +++ b/routes/chat_helpers.py @@ -98,9 +98,7 @@ def clean_repeated_assistant_content(text: object) -> str: "", value, ).strip() - # No leading `\s*`: .strip() removes that whitespace anyway, and scanning - # it from every offset of a long whitespace run was quadratic (ReDoS). - value = re.sub(r"(?is)\s*$", "", value).strip() + value = re.sub(r"(?is)\s*\s*$", "", value).strip() return value _CASUAL_OPENING_RE = re.compile( @@ -1326,17 +1324,13 @@ def _normalize_thinking(text: str) -> str: # Handle garbled tags: reasoning text followed by as separator # e.g. "The user said...I should respond.\nHey! What's up?" - # Linear form of `^([\s\S]+?)\n*\s*([\s\S]*?)(?:)?\s*$`: - # the lookbehind stops the lazy prefix re-scanning a newline run from every - # offset, and the optional trailing closer is dropped after the match - # instead of being retried at every body offset (both were quadratic). garbled = re.match( - r'^([\s\S]+?)(?\s*([\s\S]*)$', + r'^([\s\S]+?)\n*\s*([\s\S]*?)(?:)?\s*$', text, re.IGNORECASE ) if garbled: before = garbled.group(1).strip() - after = re.sub(r'$', '', garbled.group(2).rstrip(), flags=re.IGNORECASE).strip() + after = garbled.group(2).strip() # Only treat as garbled if the part before looks like reasoning reasoning_starts = ( 'The user ', 'I need ', 'I should ', 'I will ', diff --git a/routes/cookbook_routes.py b/routes/cookbook_routes.py index 02b419894..e09bbbe37 100644 --- a/routes/cookbook_routes.py +++ b/routes/cookbook_routes.py @@ -701,17 +701,13 @@ def setup_cookbook_routes() -> APIRouter: return cmd repo_id = "cyankiwi/MiniMax-M3-AWQ-INT4" - hf_home = Path(os.environ.get("HF_HOME", str(Path.home() / ".cache" / "huggingface"))) - hf_cache = Path(os.environ.get("HUGGINGFACE_HUB_CACHE", str(hf_home / "hub"))) - snapshot_root = hf_cache / "models--cyankiwi--MiniMax-M3-AWQ-INT4" / "snapshots" - if body[serve_i + 1] == repo_id and snapshot_root.is_dir(): - installed_snapshots = sorted( - (p for p in snapshot_root.iterdir() if p.is_dir()), - key=lambda p: p.stat().st_mtime, - reverse=True, - ) - if installed_snapshots: - body[serve_i + 1] = str(installed_snapshots[0]) + snapshot = ( + "/home/pewds/.cache/huggingface/hub/" + "models--cyankiwi--MiniMax-M3-AWQ-INT4/" + "snapshots/4082acbbec1236d21828d55b6bb0fe02ade4ab5b" + ) + if body[serve_i + 1] == repo_id: + body[serve_i + 1] = snapshot def add_env(key: str, value: str) -> None: if not any(p.startswith(f"{key}=") for p in env_parts): diff --git a/routes/history/history_routes.py b/routes/history/history_routes.py index 890927c53..64ccb3dea 100644 --- a/routes/history/history_routes.py +++ b/routes/history/history_routes.py @@ -7,14 +7,13 @@ import logging import re from typing import Dict, Any, Optional -from fastapi import APIRouter, Request, HTTPException, Depends +from fastapi import APIRouter, Request, HTTPException from core.models import ChatMessage from core.database import SessionLocal, ChatMessage as DbChatMessage, Session as DbSession -from src.auth_helpers import effective_user, require_chat_api_token_scope +from src.auth_helpers import effective_user from src.topic_analyzer import analyze_topics from src.upload_handler import reserve_message_upload_references -from src.tool_approval_scopes import sanitize_client_message_metadata from routes.session_routes import ( _message_role, _message_text, @@ -238,10 +237,7 @@ def _keep_count_before_message(db_messages, before_msg_id: str | None) -> int | def setup_history_routes(session_manager, upload_handler=None) -> APIRouter: - router = APIRouter( - tags=["history"], - dependencies=[Depends(require_chat_api_token_scope)], - ) + router = APIRouter(tags=["history"]) def _reserve_message_uploads( request: Request, @@ -436,7 +432,7 @@ def setup_history_routes(session_manager, upload_handler=None) -> APIRouter: content = body.get("content", "") if not content: raise HTTPException(400, "content is required") - metadata = sanitize_client_message_metadata(body.get("metadata")) + metadata = body.get("metadata") _reserve_message_uploads(request, content, metadata) msg = ChatMessage(role=role, content=content, metadata=metadata) session_manager.add_message(session_id, msg) diff --git a/routes/search/search_routes.py b/routes/search/search_routes.py index a63607649..5aafa03cb 100644 --- a/routes/search/search_routes.py +++ b/routes/search/search_routes.py @@ -43,22 +43,11 @@ def setup_search_routes(config) -> APIRouter: router = APIRouter(tags=["search"]) @router.get("/search/web", response_class=HTMLResponse) - async def web_search_page(request: Request, q: str = Query("", min_length=0)) -> HTMLResponse: + async def web_search_page(q: str = Query("", min_length=0)) -> HTMLResponse: """Browser-facing search results page for clickable agent web_search rows.""" - # The site CSP allows inline script only with the per-request nonce - # (SecurityHeadersMiddleware); without it this page's script never ran. - nonce = html.escape(getattr(request.state, "csp_nonce", "") or "", quote=True) safe_q = str(q or "").strip() title = html.escape(safe_q or "Web search") - # json.dumps leaves `<`, `>` and `&` alone, so q=