fix: bound chat latency and clarify blackjack flow
This commit is contained in:
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "jwebot-kernel"
|
||||
version = "0.6.1a0+1015"
|
||||
version = "0.6.2a0+1015"
|
||||
description = "Stable routing and extension authority for JWeBot"
|
||||
requires-python = ">=3.9"
|
||||
dependencies = [
|
||||
"jwebot-config==0.6.1a0+1015",
|
||||
"jwebot-sdk==0.6.1a0+1015",
|
||||
"jwebot-official-extensions==0.6.1a0+1015",
|
||||
"jwebot-config==0.6.2a0+1015",
|
||||
"jwebot-sdk==0.6.2a0+1015",
|
||||
"jwebot-official-extensions==0.6.2a0+1015",
|
||||
"tomli>=2; python_version < '3.11'",
|
||||
]
|
||||
|
||||
|
||||
@@ -107,4 +107,4 @@ __all__ = [
|
||||
"verify_installed_release_signature",
|
||||
]
|
||||
|
||||
__version__ = "0.6.1a0+1015"
|
||||
__version__ = "0.6.2a0+1015"
|
||||
|
||||
@@ -92,6 +92,10 @@ MAX_REPLY_CHARS = 900
|
||||
MAX_CONTEXT_TURNS = 6
|
||||
MAX_OUTBOX_ATTEMPTS = 3
|
||||
DIRECT_CHAT_GENERATION_WORKERS = 2
|
||||
DIRECT_API_SOCKET_TIMEOUT_SECONDS = 18.0
|
||||
DIRECT_API_WALL_TIMEOUT_SECONDS = 30.0
|
||||
DIRECT_API_MAX_RESPONSE_BYTES = 2_000_000
|
||||
DIRECT_API_READ_CHUNK_BYTES = 65_536
|
||||
FAST_ACKNOWLEDGEMENT = "喵......"
|
||||
PROFILE_MIN_AUTOMATIC_OBSERVATIONS = 3
|
||||
PROFILE_MAX_FACTS = 12
|
||||
@@ -626,6 +630,59 @@ def deepseek_response_content(raw: bytes) -> str:
|
||||
return str(content)
|
||||
|
||||
|
||||
def read_direct_api_response(
|
||||
response: Any,
|
||||
*,
|
||||
wall_timeout_seconds: float = DIRECT_API_WALL_TIMEOUT_SECONDS,
|
||||
max_bytes: int = DIRECT_API_MAX_RESPONSE_BYTES,
|
||||
) -> bytes:
|
||||
"""Read an SSE response with an absolute deadline, not an idle timeout."""
|
||||
|
||||
deadline = time.monotonic() + wall_timeout_seconds
|
||||
chunks: list[bytes] = []
|
||||
total = 0
|
||||
stream_tail = b""
|
||||
done_marker = re.compile(
|
||||
rb"(?:^|\r?\n)data:\s*\[DONE\]\s*(?:\r?\n|$)"
|
||||
)
|
||||
socket_connection = getattr(
|
||||
getattr(getattr(response, "fp", None), "raw", None),
|
||||
"_sock",
|
||||
None,
|
||||
)
|
||||
read_chunk = getattr(response, "read1", response.read)
|
||||
while True:
|
||||
remaining = deadline - time.monotonic()
|
||||
if remaining <= 0:
|
||||
raise DeepSeekUnavailable("direct API exceeded total timeout")
|
||||
if socket_connection is not None:
|
||||
socket_connection.settimeout(
|
||||
max(
|
||||
0.001,
|
||||
min(DIRECT_API_SOCKET_TIMEOUT_SECONDS, remaining),
|
||||
)
|
||||
)
|
||||
try:
|
||||
chunk = read_chunk(
|
||||
min(DIRECT_API_READ_CHUNK_BYTES, max_bytes - total + 1)
|
||||
)
|
||||
except (TimeoutError, OSError) as error:
|
||||
raise DeepSeekUnavailable("direct API transport failure") from error
|
||||
if not chunk:
|
||||
break
|
||||
if not isinstance(chunk, bytes):
|
||||
raise DeepSeekUnavailable("direct API returned invalid bytes")
|
||||
total += len(chunk)
|
||||
if total > max_bytes:
|
||||
raise DeepSeekUnavailable("direct API response exceeded size limit")
|
||||
chunks.append(chunk)
|
||||
stream_scan = stream_tail + chunk
|
||||
if done_marker.search(stream_scan):
|
||||
break
|
||||
stream_tail = stream_scan[-64:]
|
||||
return b"".join(chunks)
|
||||
|
||||
|
||||
def load_environment_file(path: Path = ENVIRONMENT_FILE) -> None:
|
||||
"""Load the active generated profile, then the legacy compatibility file."""
|
||||
|
||||
@@ -3422,8 +3479,11 @@ class DeepSeekClient:
|
||||
method="POST",
|
||||
)
|
||||
try:
|
||||
with urllib.request.urlopen(request, timeout=18) as response:
|
||||
raw = response.read(2_000_000)
|
||||
with urllib.request.urlopen(
|
||||
request,
|
||||
timeout=DIRECT_API_SOCKET_TIMEOUT_SECONDS,
|
||||
) as response:
|
||||
raw = read_direct_api_response(response)
|
||||
except urllib.error.HTTPError as error:
|
||||
raise DeepSeekUnavailable(f"direct API HTTP {error.code}") from error
|
||||
except (urllib.error.URLError, TimeoutError, OSError) as error:
|
||||
|
||||
Reference in New Issue
Block a user