Files
magpie/internal/provider/zcode_blocked_test.go
T
yetone 986a4474fe zcode: the Start Plan's 405 block is said for what it is, not only as a firewall (#425: ZCode 405 Method Not Allowed on GLM-5.3-Flash from DeepSeek Harness, while zcode2api works with the same account) — zcode.z.ai answers a Start Plan request it turns away with 405 "request has been blocked due to unusual activity" (code 3012 "method not allowed"), which magpie read as Alibaba Cloud's firewall blocking the address and told the user to wait or switch network. zcode2api's own write-ups (a137460387/zcode2api "3012 的根因与修复", gakiyukr/zcode2api-plus request.go) find the endpoint checks what a request carries and takes only one with ZCode's own system prompt, which zcode2api injects; magpie's endpoint, method and protocol are the same as theirs, and magpie doesn't pretend to be ZCode. On a Start Plan account the 405 / 3012 / block page now reads "ZCode's Start Plan turns away requests that don't come from the ZCode app itself, and magpie doesn't pretend to be it; it can also be a network block of this IP. Use an account with a GLM Coding Plan, or add another provider to this group", in place of the generic hint, to the agent and in the trace, where the Routing page gives it on its own line in English or Chinese; the group still goes on to its next member. A Coding Plan account and every other provider keep the generic hint. Requests, headers and prompts are unchanged. TestZCodeStartBlockedSaid and routing-zcode-blocked.test.cjs fail without the change. go vet, go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui ./... pass (TestUserPath, a load flake, passes alone); routing-zcode-blocked, routing-blocked, routing-wb-refused, click-scroll, old-webkit pass.
2026-10-01 20:45:11 +08:00

46 lines
2.3 KiB
Go

package provider
import (
"net/http"
"strings"
"testing"
)
// zcodeBlockPage is the page zcode.z.ai answers a Start Plan request it
// turns away with (#425).
const zcodeBlockPage = `<!DOCTYPE html><html><head><title>405</title></head><body>
<h1>Sorry, your request has been blocked due to unusual activity.</h1>
<a href="https://errors.aliyun.com/error/405?code=blocked">errors.aliyun.com</a></body></html>`
// The Start Plan's block is said for what it is (#425): ZCode turns away
// requests that aren't its app's own, or the network blocked the address,
// and what to use instead; not only the firewall. A Coding Plan account,
// and any other provider, keep the generic hint.
func TestZCodeStartBlockedSaid(t *testing.T) {
say := func(p Provider, status int, body string) string {
return p.Explain(p.Name+": "+APIError([]byte(body), "405 Method Not Allowed"), status, []byte(body))
}
start := zcodeProvider("trial@example.com", "Start Plan", zcodeKey{JWT: "a.b.c"})
if got, want := say(start, http.StatusMethodNotAllowed, zcodeBlockPage), "ZCode: 405 Method Not Allowed — "+ZCodeStartBlockedHint; got != want {
t.Fatalf("Start Plan block:\n got %q\nwant %q", got, want)
}
if got := say(start, http.StatusMethodNotAllowed, `{"code":3012,"msg":"method not allowed"}`); !strings.HasSuffix(got, " — "+ZCodeStartBlockedHint) || strings.Contains(got, BlockedHint) {
t.Fatalf("Start Plan 3012: %q", got)
}
if got := say(start, http.StatusTooManyRequests, `{"code":1302,"msg":"rate limited"}`); strings.Contains(got, ZCodeStartBlockedHint) {
t.Fatalf("a rate limit got the block hint: %q", got)
}
if !EdgeBlocked([]byte(say(start, http.StatusMethodNotAllowed, zcodeBlockPage))) {
t.Fatal("the Start Plan's hint, relayed, isn't taken as a block")
}
plan := zcodeProvider("pro@example.com", "GLM Coding Plan", zcodeKey{Key: "id.secret", Base: "https://api.z.ai/api/anthropic"})
if got, want := say(plan, http.StatusMethodNotAllowed, zcodeBlockPage), "ZCode: 405 Method Not Allowed — "+BlockedHint; got != want {
t.Fatalf("Coding Plan block:\n got %q\nwant %q", got, want)
}
other := Provider{ID: "za", Name: "ZA"}
if got, want := say(other, http.StatusMethodNotAllowed, zcodeBlockPage), "ZA: 405 Method Not Allowed — "+BlockedHint; got != want {
t.Fatalf("another provider:\n got %q\nwant %q", got, want)
}
}