refactor(agent): process_bootstrap/markdown_tables/onboarding pass-2 — inline _pad_to_width, fold proxy bypass and pool guard, pack signatures
This commit is contained in:
@@ -28,14 +28,9 @@ def _disp_width(s: str) -> int:
|
||||
return max(wcswidth(s), 0)
|
||||
|
||||
|
||||
def _pad_to_width(s: str, target: int) -> str:
|
||||
return s + " " * max(0, target - _disp_width(s))
|
||||
|
||||
|
||||
def split_table_row(row: str) -> List[str]:
|
||||
"""Split ``| a | b | c |`` into ``["a", "b", "c"]`` with trims."""
|
||||
s = row.strip().removeprefix("|").removesuffix("|")
|
||||
return [c.strip() for c in s.split("|")]
|
||||
return [c.strip() for c in row.strip().removeprefix("|").removesuffix("|").split("|")]
|
||||
|
||||
|
||||
def is_table_divider(row: str) -> bool:
|
||||
@@ -66,14 +61,12 @@ def _render_block(rows: List[List[str]], available_width: int | None = None) ->
|
||||
ncols = max(len(r) for r in rows)
|
||||
rows = [r + [""] * (ncols - len(r)) for r in rows]
|
||||
widths = [max(_MIN_COL_WIDTH, *(_disp_width(r[c]) for r in rows)) for c in range(ncols)]
|
||||
|
||||
# `| ` + cell + ` ` per column, plus the closing `|`.
|
||||
horizontal_width = sum(widths) + 3 * ncols + 1
|
||||
if available_width is not None and horizontal_width > max(available_width, 20):
|
||||
if available_width is not None and sum(widths) + 3 * ncols + 1 > max(available_width, 20):
|
||||
return _render_vertical(rows, ncols, available_width)
|
||||
|
||||
def _row(cells: List[str]) -> str:
|
||||
return "| " + " | ".join(_pad_to_width(c, widths[k]) for k, c in enumerate(cells)) + " |"
|
||||
return "| " + " | ".join(c + " " * max(0, widths[k] - _disp_width(c)) for k, c in enumerate(cells)) + " |"
|
||||
|
||||
out = [_row(rows[0]), "|" + "|".join("-" * (w + 2) for w in widths) + "|"]
|
||||
out.extend(_row(r) for r in rows[1:])
|
||||
@@ -90,11 +83,8 @@ def _hard_break(word: str, w: int) -> List[str]:
|
||||
out.append(buf)
|
||||
buf, bw = ch, cw
|
||||
else:
|
||||
buf += ch
|
||||
bw += cw
|
||||
if buf:
|
||||
out.append(buf)
|
||||
return out
|
||||
buf, bw = buf + ch, bw + cw
|
||||
return out + [buf] if buf else out
|
||||
|
||||
|
||||
def _wrap_to_width(text: str, width: int) -> List[str]:
|
||||
@@ -108,7 +98,6 @@ def _wrap_to_width(text: str, width: int) -> List[str]:
|
||||
words = text.split()
|
||||
if not words:
|
||||
return [""]
|
||||
|
||||
lines: List[str] = []
|
||||
current, current_w = "", 0
|
||||
|
||||
@@ -145,18 +134,14 @@ def _render_vertical(rows: List[List[str]], ncols: int, available_width: int) ->
|
||||
"""
|
||||
if not rows:
|
||||
return []
|
||||
headers = rows[0] + [""] * (ncols - len(rows[0]))
|
||||
labels = [h or f"Column {i + 1}" for i, h in enumerate(headers)]
|
||||
labels = [h or f"Column {i + 1}" for i, h in enumerate(rows[0] + [""] * (ncols - len(rows[0])))]
|
||||
separator = "─" * (max(20, min(40, available_width - 2)) if available_width else 30)
|
||||
indent = " "
|
||||
cont_budget = max(10, available_width - _disp_width(indent))
|
||||
|
||||
cont_budget = max(10, available_width - 2) # continuation lines are indented two spaces
|
||||
out: List[str] = []
|
||||
for ri, row in enumerate(rows[1:]):
|
||||
if ri > 0:
|
||||
out.append(separator)
|
||||
for ci in range(ncols):
|
||||
label = labels[ci]
|
||||
for ci, label in enumerate(labels):
|
||||
value = row[ci] if ci < len(row) else ""
|
||||
if not value:
|
||||
out.append(f"{label}:")
|
||||
@@ -166,7 +151,7 @@ def _render_vertical(rows: List[List[str]], ncols: int, available_width: int) ->
|
||||
# Re-flow continuation text at the wider continuation budget.
|
||||
for cl in _wrap_to_width(" ".join(wrapped[1:]), cont_budget) if len(wrapped) > 1 else ():
|
||||
if cl.strip():
|
||||
out.append(f"{indent}{cl}")
|
||||
out.append(f" {cl}")
|
||||
return out
|
||||
|
||||
|
||||
@@ -179,7 +164,6 @@ def realign_markdown_tables(text: str, available_width: int | None = None) -> st
|
||||
"""
|
||||
if "|" not in text:
|
||||
return text
|
||||
|
||||
lines = text.split("\n")
|
||||
out: List[str] = []
|
||||
i, n = 0, len(lines)
|
||||
|
||||
+4
-9
@@ -76,17 +76,13 @@ def busy_input_hint_cli(mode: str) -> str:
|
||||
|
||||
|
||||
def tool_progress_hint_gateway() -> str:
|
||||
return (
|
||||
"💡 First-time tip — that tool took a while and I'm streaming every step. If the progress messages "
|
||||
"feel noisy, send `/verbose` to cycle modes (all → new → off). This notice won't appear again."
|
||||
)
|
||||
return ("💡 First-time tip — that tool took a while and I'm streaming every step. If the progress messages "
|
||||
"feel noisy, send `/verbose` to cycle modes (all → new → off). This notice won't appear again.")
|
||||
|
||||
|
||||
def tool_progress_hint_cli() -> str:
|
||||
return (
|
||||
"(tip) That tool ran for a while. Use /verbose to cycle tool-progress "
|
||||
"display modes (all -> new -> off -> verbose). This tip only shows once."
|
||||
)
|
||||
return ("(tip) That tool ran for a while. Use /verbose to cycle tool-progress "
|
||||
"display modes (all -> new -> off -> verbose). This tip only shows once.")
|
||||
|
||||
|
||||
def openclaw_residue_hint_cli() -> str:
|
||||
@@ -162,7 +158,6 @@ def mark_seen(config_path: Path, flag: str) -> bool:
|
||||
except Exception as e: # pragma: no cover — dependency issue
|
||||
logger.debug("onboarding: failed to import yaml/utils: %s", e)
|
||||
return False
|
||||
|
||||
try:
|
||||
cfg: dict = {}
|
||||
if config_path.exists():
|
||||
|
||||
+16
-44
@@ -30,15 +30,12 @@ def _interleave_addrinfos(addrinfos: list[tuple]) -> list[tuple]:
|
||||
seen: set[tuple] = set()
|
||||
for addrinfo in addrinfos:
|
||||
family, socktype, proto, _canonname, sockaddr = addrinfo
|
||||
marker = (family, socktype, proto, sockaddr)
|
||||
if marker not in seen:
|
||||
seen.add(marker)
|
||||
if (family, socktype, proto, sockaddr) not in seen:
|
||||
seen.add((family, socktype, proto, sockaddr))
|
||||
queues.setdefault(family, []).append(addrinfo)
|
||||
interleaved: list[tuple] = []
|
||||
while any(queues.values()):
|
||||
for queue in queues.values():
|
||||
if queue:
|
||||
interleaved.append(queue.pop(0))
|
||||
interleaved.extend(queue.pop(0) for queue in queues.values() if queue)
|
||||
return interleaved
|
||||
|
||||
|
||||
@@ -49,12 +46,8 @@ def _quiet_unregister(selector, sock) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def _happy_eyeballs_create_connection(
|
||||
address: tuple[str, int],
|
||||
timeout: Optional[float],
|
||||
source_address: Optional[tuple[str, int]] = None,
|
||||
socket_options=(),
|
||||
):
|
||||
def _happy_eyeballs_create_connection(address: tuple[str, int], timeout: Optional[float],
|
||||
source_address: Optional[tuple[str, int]] = None, socket_options=()):
|
||||
"""RFC 8305-style connect: staggered non-blocking attempts across families.
|
||||
|
||||
``socket.create_connection`` tries addresses serially, so broken-but-
|
||||
@@ -101,7 +94,6 @@ def _happy_eyeballs_create_connection(
|
||||
now = time.monotonic()
|
||||
if deadline is not None and now >= deadline:
|
||||
raise socket.timeout("timed out")
|
||||
|
||||
if pending and now >= next_launch:
|
||||
try:
|
||||
winner = start_attempt(pending.pop(0))
|
||||
@@ -113,12 +105,10 @@ def _happy_eyeballs_create_connection(
|
||||
if winner is not None:
|
||||
break
|
||||
next_launch = now + _HAPPY_EYEBALLS_DELAY_SECONDS
|
||||
|
||||
wait_timeout = None if deadline is None else max(0.0, deadline - now)
|
||||
if pending:
|
||||
until_launch = max(0.0, next_launch - now)
|
||||
wait_timeout = until_launch if wait_timeout is None else min(wait_timeout, until_launch)
|
||||
|
||||
for key, _mask in selector.select(wait_timeout):
|
||||
candidate = key.fileobj
|
||||
error_code = candidate.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
|
||||
@@ -136,7 +126,6 @@ def _happy_eyeballs_create_connection(
|
||||
|
||||
if winner is None:
|
||||
raise last_error if last_error is not None else OSError(f"Could not connect to {host}:{port}")
|
||||
|
||||
_quiet_unregister(selector, winner)
|
||||
active.discard(winner)
|
||||
winner.settimeout(timeout)
|
||||
@@ -160,22 +149,17 @@ class _HappyEyeballsSyncBackend:
|
||||
def _default_backend(self):
|
||||
if self._fallback is None:
|
||||
from httpcore import SyncBackend
|
||||
|
||||
self._fallback = SyncBackend()
|
||||
return self._fallback
|
||||
|
||||
def connect_tcp(
|
||||
self, host: str, port: int, timeout: Optional[float] = None,
|
||||
local_address: Optional[str] = None, socket_options=None,
|
||||
):
|
||||
def connect_tcp(self, host: str, port: int, timeout: Optional[float] = None, local_address: Optional[str] = None,
|
||||
socket_options=None):
|
||||
from httpcore import ConnectError, ConnectTimeout
|
||||
from httpcore._backends.sync import SyncStream
|
||||
|
||||
source_address = None if local_address is None else (local_address, 0)
|
||||
try:
|
||||
sock = _happy_eyeballs_create_connection(
|
||||
(host, port), timeout, source_address=source_address, socket_options=socket_options or ()
|
||||
)
|
||||
sock = _happy_eyeballs_create_connection((host, port), timeout, source_address=source_address,
|
||||
socket_options=socket_options or ())
|
||||
except socket.timeout as exc:
|
||||
raise ConnectTimeout(str(exc)) from exc
|
||||
except OSError as exc:
|
||||
@@ -201,11 +185,8 @@ def _enable_happy_eyeballs(transport, skip_pool_types: tuple = ()) -> None:
|
||||
serial backend. Pools of ``skip_pool_types`` (proxies) are left alone.
|
||||
"""
|
||||
pool = getattr(transport, "_pool", None)
|
||||
if pool is None or not hasattr(pool, "_network_backend"):
|
||||
return
|
||||
if skip_pool_types and isinstance(pool, skip_pool_types):
|
||||
return
|
||||
pool._network_backend = _HappyEyeballsSyncBackend()
|
||||
if pool is not None and hasattr(pool, "_network_backend") and not (skip_pool_types and isinstance(pool, skip_pool_types)):
|
||||
pool._network_backend = _HappyEyeballsSyncBackend()
|
||||
|
||||
|
||||
def enable_happy_eyeballs_on_client(client) -> None:
|
||||
@@ -217,14 +198,11 @@ def enable_happy_eyeballs_on_client(client) -> None:
|
||||
"""
|
||||
try:
|
||||
import httpcore
|
||||
|
||||
proxy_pool_types = tuple(
|
||||
t for t in (getattr(httpcore, "HTTPProxy", None), getattr(httpcore, "SOCKSProxy", None)) if t is not None
|
||||
)
|
||||
t for t in (getattr(httpcore, "HTTPProxy", None), getattr(httpcore, "SOCKSProxy", None)) if t is not None)
|
||||
except Exception:
|
||||
return
|
||||
transports = [getattr(client, "_transport", None), *(getattr(client, "_mounts", None) or {}).values()]
|
||||
for transport in transports:
|
||||
for transport in (getattr(client, "_transport", None), *(getattr(client, "_mounts", None) or {}).values()):
|
||||
_enable_happy_eyeballs(transport, proxy_pool_types)
|
||||
|
||||
|
||||
@@ -232,8 +210,7 @@ def _load_openai_cls() -> type:
|
||||
"""Import and cache ``openai.OpenAI``."""
|
||||
global _OPENAI_CLS_CACHE
|
||||
if _OPENAI_CLS_CACHE is None:
|
||||
from openai import OpenAI as _cls
|
||||
_OPENAI_CLS_CACHE = _cls
|
||||
from openai import OpenAI as _OPENAI_CLS_CACHE
|
||||
return _OPENAI_CLS_CACHE
|
||||
|
||||
|
||||
@@ -303,14 +280,10 @@ def _get_proxy_for_base_url(base_url: Optional[str]) -> Optional[str]:
|
||||
"""Env-configured proxy unless NO_PROXY excludes this base URL."""
|
||||
proxy = _get_proxy_from_env()
|
||||
host = base_url_hostname(base_url) if proxy and base_url else ""
|
||||
if not host:
|
||||
return proxy
|
||||
try:
|
||||
if urllib.request.proxy_bypass_environment(host):
|
||||
return None
|
||||
return None if host and urllib.request.proxy_bypass_environment(host) else proxy
|
||||
except Exception:
|
||||
pass
|
||||
return proxy
|
||||
return proxy
|
||||
|
||||
|
||||
def build_keepalive_http_client(base_url: str = "", *, async_mode: bool = False, verify: Any = True) -> Optional[Any]:
|
||||
@@ -324,7 +297,6 @@ def build_keepalive_http_client(base_url: str = "", *, async_mode: bool = False,
|
||||
"""
|
||||
try:
|
||||
import httpx
|
||||
|
||||
proxy = _get_proxy_for_base_url(base_url)
|
||||
limits = httpx.Limits(max_keepalive_connections=20, max_connections=100, keepalive_expiry=20.0)
|
||||
timeout = httpx.Timeout(connect=15.0, read=None, write=15.0, pool=10.0) # read=None for SSE streaming
|
||||
|
||||
Reference in New Issue
Block a user