feat: align z.ai headers with OpenClaw, enable OpenRouter caching
- z.ai now sends 3 exact OpenRouter attribution headers matching OpenClaw's source (HTTP-Referer, X-OpenRouter-Title, X-OpenRouter-Categories) with full category list for maximum free-tier eligibility - openrouter.ai requests include X-OpenRouter-Cache: true header to leverage OpenRouter's response caching and reduce latency/cost
This commit is contained in:
@@ -1290,6 +1290,27 @@ def forwarded_headers(request_headers, extra=None, browser_ua=False):
|
||||
headers.update(extra)
|
||||
return headers
|
||||
|
||||
|
||||
def _openrouter_extra():
|
||||
if not TARGET_URL:
|
||||
return {}
|
||||
if "z.ai" in TARGET_URL:
|
||||
return {
|
||||
"HTTP-Referer": "https://openclaw.ai",
|
||||
"X-OpenRouter-Title": "OpenClaw",
|
||||
"X-OpenRouter-Categories":
|
||||
"cli-agent,cloud-agent,programming-app,creative-writing,"
|
||||
"writing-assistant,general-chat,personal-agent",
|
||||
}
|
||||
if "openrouter.ai" in TARGET_URL:
|
||||
return {
|
||||
"HTTP-Referer": "https://chats-llm.com",
|
||||
"X-OpenRouter-Title": "Chats-LLM",
|
||||
"X-OpenRouter-Categories": "general-chat, ide-extension",
|
||||
"X-OpenRouter-Cache": "true",
|
||||
}
|
||||
return {}
|
||||
|
||||
_MAX_INPUT_ITEMS = 30
|
||||
_MAX_TOOL_OUTPUT_CHARS = 8000
|
||||
_COMPACT_KEEP_RECENT = 10
|
||||
@@ -4321,6 +4342,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
fwd = forwarded_headers(self.headers, {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {effective_key}",
|
||||
**_openrouter_extra(),
|
||||
}, browser_ua=True)
|
||||
print(f"[{self._session_id}] POST {target} model={model} stream={stream} items={len(input_data) if isinstance(input_data,list) else 1}", file=sys.stderr)
|
||||
chat_body_b = json.dumps(chat_body).encode()
|
||||
@@ -4947,6 +4969,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
fwd = forwarded_headers(self.headers, {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {r_key}",
|
||||
**_openrouter_extra(),
|
||||
}, browser_ua=True)
|
||||
print(f"[{self._session_id}] trying route '{route.get('name', r_url)}' model={r_model}", file=sys.stderr)
|
||||
req = urllib.request.Request(target, data=json.dumps(chat_body).encode(), headers=fwd)
|
||||
@@ -5209,6 +5232,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": API_KEY,
|
||||
"anthropic-version": "2023-06-01",
|
||||
**_openrouter_extra(),
|
||||
}),
|
||||
)
|
||||
self._forward(req, stream, model,
|
||||
@@ -5276,7 +5300,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
"threadId": thread_id,
|
||||
}
|
||||
|
||||
fwd = forwarded_headers(self.headers, headers_extra, browser_ua=True)
|
||||
fwd = forwarded_headers(self.headers, {**headers_extra, **_openrouter_extra()}, browser_ua=True)
|
||||
print(f"[{self._session_id}] POST {target} model={model} stream={stream} attempt={attempt} [command-code]", file=sys.stderr)
|
||||
req = urllib.request.Request(
|
||||
target,
|
||||
@@ -5810,7 +5834,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
req_body["reasoning_effort"] = REASONING_EFFORT
|
||||
|
||||
req_body_b = json.dumps(req_body).encode()
|
||||
fwd = forwarded_headers(self.headers, headers_extra, browser_ua=True)
|
||||
fwd = forwarded_headers(self.headers, {**headers_extra, **_openrouter_extra()}, browser_ua=True)
|
||||
print(f"[auto-sense] POST {target} model={model} attempt={attempt} schema={schema.hints()}", file=sys.stderr)
|
||||
|
||||
req = urllib.request.Request(target, data=req_body_b, headers=fwd)
|
||||
|
||||
Reference in New Issue
Block a user