diff --git a/signalwire/signalwire/ai_chat/__init__.py b/signalwire/signalwire/ai_chat/__init__.py index 7354276..ad0671a 100644 --- a/signalwire/signalwire/ai_chat/__init__.py +++ b/signalwire/signalwire/ai_chat/__init__.py @@ -26,15 +26,15 @@ __all__ = [ "AIChatClient", - "ChatGateway", - "GatewayRejection", "AIChatError", "AuthenticationError", + "ChatGateway", "ChatInProgressError", "ChatLog", "ChatResponse", "ConversationInfo", "ConversationNotFoundError", + "GatewayRejection", "RateLimitError", "SummaryError", ] diff --git a/signalwire/signalwire/ai_chat/gateway.py b/signalwire/signalwire/ai_chat/gateway.py index e2f4f5f..7912811 100644 --- a/signalwire/signalwire/ai_chat/gateway.py +++ b/signalwire/signalwire/ai_chat/gateway.py @@ -73,8 +73,8 @@ SERVICE_DEFAULT_CONVERSATION_TIMEOUT = 3600 # Caps chosen to be invisible to a real conversation and ruinous to a script. -DEFAULT_MAX_NEW_CONVERSATIONS = 60 # per window, per gateway -DEFAULT_MAX_TURNS = 200 # per conversation, ever +DEFAULT_MAX_NEW_CONVERSATIONS = 60 # per window, per gateway +DEFAULT_MAX_TURNS = 200 # per conversation, ever DEFAULT_WINDOW_SECONDS = 60 # Hosts that never need listing, so `pip install` → run → it works. @@ -160,8 +160,10 @@ def __init__( raise ValueError("config_url is required — it is what a key is scoped to.") self.config_url = config_url - self.key = key or os.environ.get("SIGNALWIRE_CHAT_GATEWAY_KEY") or ( - "pk_" + secrets.token_urlsafe(24) + self.key = ( + key + or os.environ.get("SIGNALWIRE_CHAT_GATEWAY_KEY") + or ("pk_" + secrets.token_urlsafe(24)) ) self.allowed_origins = {o.rstrip("/") for o in allowed_origins} self.handle_ttl = handle_ttl @@ -174,7 +176,9 @@ def __init__( self._owns_client = client is None if secret is None: - secret = os.environ.get("SIGNALWIRE_CHAT_GATEWAY_SECRET") or secrets.token_bytes(32) + secret = os.environ.get( + "SIGNALWIRE_CHAT_GATEWAY_SECRET" + ) or secrets.token_bytes(32) self._secret = secret.encode() if isinstance(secret, str) else secret self._mints: list[float] = [] @@ -341,8 +345,9 @@ def _charge_turn(self, conversation_id: str) -> None: # ── The proxied call ───────────────────────────────────────────── - def prepare(self, body: dict[str, Any], *, origin: str | None, - key: str | None) -> tuple[str, dict[str, Any], str | None]: + def prepare( + self, body: dict[str, Any], *, origin: str | None, key: str | None + ) -> tuple[str, dict[str, Any], str | None]: """Validate a browser request and build the upstream JSON-RPC call. Returns ``(method, params, minted_handle)`` — ``minted_handle`` is set diff --git a/signalwire/signalwire/core/function_result.py b/signalwire/signalwire/core/function_result.py index 23f3d28..72480d9 100644 --- a/signalwire/signalwire/core/function_result.py +++ b/signalwire/signalwire/core/function_result.py @@ -567,9 +567,7 @@ def hold( timeout, prompt = prompt, None if prompt is not None: - self.set_tool_response( - tool_result="status: on hold", tool_prompt=prompt - ) + self.set_tool_response(tool_result="status: on hold", tool_prompt=prompt) self.post_process = True # Clamp timeout to valid range diff --git a/signalwire/signalwire/search/document_processor.py b/signalwire/signalwire/search/document_processor.py index f8f9387..2e95958 100644 --- a/signalwire/signalwire/search/document_processor.py +++ b/signalwire/signalwire/search/document_processor.py @@ -1745,11 +1745,14 @@ def _chunk_from_json( # A new topic: remember its heading, and leave it alone - # it already names itself. current_heading = stripped.split("\n", 1)[0].strip() - elif current_heading and stripped.startswith("#"): + elif ( + current_heading + and stripped.startswith("#") + and current_heading.lower() not in chunk_text.lower() + ): # A subsection of that topic: give it the subject back. - if current_heading.lower() not in chunk_text.lower(): - chunk_text = f"{current_heading}\n\n{chunk_text}" - metadata["heading_context"] = current_heading + chunk_text = f"{current_heading}\n\n{chunk_text}" + metadata["heading_context"] = current_heading chunk = self._create_chunk( content=chunk_text, diff --git a/signalwire/signalwire/search/search_service.py b/signalwire/signalwire/search/search_service.py index d719371..c54a320 100644 --- a/signalwire/signalwire/search/search_service.py +++ b/signalwire/signalwire/search/search_service.py @@ -7,6 +7,8 @@ See LICENSE file in the project root for full license information. """ +from __future__ import annotations + import hashlib import json from collections.abc import Awaitable, Callable