fix: 修复热点摘要超长上下文并统一 Windows 启动文档
为 http_request 增加响应体截断与头部精简,避免门户首页触发 LLM 上下文超限;同时新增政务/媒体及教育批量 Agent 脚本,并将 Windows 启停说明合并为唯一指南,补充本次超时故障复盘与标准重启流程。 Made-with: Cursor
This commit is contained in:
@@ -67,11 +67,74 @@ def _resolve_path_under_workspace(file_path: str) -> Tuple[Optional[Path], Optio
|
||||
return p, None
|
||||
|
||||
|
||||
_HTTP_RESPONSE_HEADER_ALLOWLIST = frozenset(
|
||||
{
|
||||
"content-type",
|
||||
"content-length",
|
||||
"content-encoding",
|
||||
"date",
|
||||
"last-modified",
|
||||
"location",
|
||||
"server",
|
||||
"cache-control",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _compact_http_response_headers(response: httpx.Response) -> Dict[str, str]:
|
||||
"""减少 Set-Cookie 等大字段进入 LLM 上下文。"""
|
||||
out: Dict[str, str] = {}
|
||||
for key, value in response.headers.multi_items():
|
||||
lk = key.lower()
|
||||
if lk in ("set-cookie", "cookie"):
|
||||
continue
|
||||
if lk in _HTTP_RESPONSE_HEADER_ALLOWLIST:
|
||||
out[key] = value if len(value) <= 2048 else value[:2048] + "..."
|
||||
if not out:
|
||||
n = 0
|
||||
for key, value in response.headers.multi_items():
|
||||
lk = key.lower()
|
||||
if lk in ("set-cookie", "cookie"):
|
||||
continue
|
||||
if n >= 12:
|
||||
break
|
||||
out[key] = value if len(value) <= 512 else value[:512] + "..."
|
||||
n += 1
|
||||
return out
|
||||
|
||||
|
||||
def _truncate_http_body_for_tool(body: Any, max_chars: int) -> Tuple[Any, bool, Optional[str]]:
|
||||
"""
|
||||
将 HTTP 正文限制在 max_chars 字符以内,避免门户首页等大 HTML 撑爆模型 context。
|
||||
返回 (可能被截断后的 body, 是否截断, 说明文案)
|
||||
"""
|
||||
if max_chars <= 0:
|
||||
max_chars = 32_000
|
||||
note: Optional[str] = None
|
||||
if isinstance(body, str):
|
||||
if len(body) <= max_chars:
|
||||
return body, False, None
|
||||
note = (
|
||||
f"正文已截断:原始约 {len(body)} 字符,仅保留前 {max_chars} 字符。"
|
||||
"门户/频道首页通常过大,摘要请优先使用具体文章页 URL。"
|
||||
)
|
||||
return body[:max_chars], True, note
|
||||
try:
|
||||
serialized = json.dumps(body, ensure_ascii=False)
|
||||
except (TypeError, ValueError):
|
||||
serialized = str(body)
|
||||
if len(serialized) <= max_chars:
|
||||
return body, False, None
|
||||
note = f"JSON 响应已截断:序列化长度约 {len(serialized)} 字符,仅保留前 {max_chars} 字符。"
|
||||
return serialized[:max_chars], True, note
|
||||
|
||||
|
||||
async def http_request_tool(
|
||||
url: str,
|
||||
method: str = "GET",
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
body: Any = None
|
||||
body: Any = None,
|
||||
max_body_chars: Optional[int] = None,
|
||||
) -> str:
|
||||
"""
|
||||
HTTP请求工具
|
||||
@@ -81,12 +144,18 @@ async def http_request_tool(
|
||||
method: HTTP方法 (GET, POST, PUT, DELETE)
|
||||
headers: 请求头
|
||||
body: 请求体(POST/PUT时使用)
|
||||
max_body_chars: 响应正文写入工具结果的最大字符数;默认读取配置 HTTP_REQUEST_MAX_BODY_CHARS
|
||||
|
||||
Returns:
|
||||
JSON格式的响应结果
|
||||
"""
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
limit = max_body_chars
|
||||
if limit is None:
|
||||
limit = int(getattr(settings, "HTTP_REQUEST_MAX_BODY_CHARS", 32_000) or 32_000)
|
||||
limit = max(4096, min(limit, 200_000))
|
||||
|
||||
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
||||
method_upper = method.upper()
|
||||
|
||||
if method_upper == "GET":
|
||||
@@ -103,15 +172,20 @@ async def http_request_tool(
|
||||
# 尝试解析JSON响应
|
||||
try:
|
||||
response_body = response.json()
|
||||
except:
|
||||
except Exception:
|
||||
response_body = response.text
|
||||
|
||||
result = {
|
||||
|
||||
truncated_body, truncated, trunc_note = _truncate_http_body_for_tool(response_body, limit)
|
||||
result: Dict[str, Any] = {
|
||||
"status_code": response.status_code,
|
||||
"headers": dict(response.headers),
|
||||
"body": response_body
|
||||
"headers": _compact_http_response_headers(response),
|
||||
"body": truncated_body,
|
||||
}
|
||||
|
||||
if truncated:
|
||||
result["body_truncated"] = True
|
||||
if trunc_note:
|
||||
result["truncation_note"] = trunc_note
|
||||
|
||||
return json.dumps(result, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
logger.error(f"HTTP请求工具执行失败: {str(e)}")
|
||||
@@ -1036,7 +1110,14 @@ HTTP_REQUEST_SCHEMA = {
|
||||
"body": {
|
||||
"type": "object",
|
||||
"description": "请求体(POST/PUT时使用,可选)"
|
||||
}
|
||||
},
|
||||
"max_body_chars": {
|
||||
"type": "integer",
|
||||
"description": (
|
||||
"响应正文写入结果的最大字符数(可选)。"
|
||||
"门户首页等大 HTML 默认会按平台配置截断;摘要单篇文章可适当调大(如 80000),仍可能受模型总上下文限制。"
|
||||
),
|
||||
},
|
||||
},
|
||||
"required": ["url", "method"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user