Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions signalwire/signalwire/ai_chat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@

__all__ = [
"AIChatClient",
"ChatGateway",
"GatewayRejection",
"AIChatError",
"AuthenticationError",
"ChatGateway",
"ChatInProgressError",
"ChatLog",
"ChatResponse",
"ConversationInfo",
"ConversationNotFoundError",
"GatewayRejection",
"RateLimitError",
"SummaryError",
]
19 changes: 12 additions & 7 deletions signalwire/signalwire/ai_chat/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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] = []
Expand Down Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions signalwire/signalwire/core/function_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions signalwire/signalwire/search/document_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions signalwire/signalwire/search/search_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down