package lua import ( "os" "regexp" "strings" "testing" ) // ★ zcode 适配器**源码模板**必须真的能把 anthropic 基座合并进来。 // // 背景:此前适配器在**沙箱里自己读 anthropic.lua** ⇒ 必然失败(沙箱无 fs、 // 无 plugin_dir)且**静默降级** ⇒ 只有它自己定义的 2 个函数,缺 7 个 // ⇒ 每次调用内核报 "missing transform_response" ⇒ 渠道**完全不可用**。 // 该缺陷一直潜伏,因为 zcode 从来没有凭据 ⇒ 源未注册 ⇒ 从未被调用过。 // // ⚠️ **本判据的边界(务必如实理解)**:它在测试里**自己**做占位符替换, // // 所以它证明的是「**模板形态**正确 + 合并逻辑能吃下基座」, // 而**不能**证明「installZcodeAdapter 真的内联了非空基座」—— // 把安装处的 `asrc` 换成空串,本判据**不会**报红(已实测)。 // 安装接线由 internal/core 的端到端判据覆盖: // TestZcodeAdapterInjectsOfficialIdentityBlocks // TestZcodeAdapterKeepsAnthropicProtocolConversion(工具调用/图像块存活) // TestZcodeAdapterFailsLoudlyWithoutAnthropicBase(基座不可得 ⇒ 安装期报错) // 这三条**会**咬住"内联空基座"这个变异(已实测)。 // ⇒ 教训:判据自己复现被测逻辑时,必须说清它到底覆盖了哪一段。 func TestZcodeAdapterInheritsAnthropicBase(t *testing.T) { psrc, _ := os.ReadFile("plugins/channels.lua") s := string(psrc) diag := regexp.MustCompile(`(?s)local ZCODE_DIAG_SRC = \[===\[(.*?)\]===\]`).FindStringSubmatch(s)[1] ad := regexp.MustCompile(`(?s)local ZCODE_ADAPTER_SRC = \[===\[(.*?)\]===\]`).FindStringSubmatch(s)[1] asrc, err := bundledAdapters.ReadFile("adapters/anthropic.lua") if err != nil { t.Fatal(err) } full := "local Z = (function()\n" + diag + "\nend)()\n" + ad // ⚠ 占位符不等于"适配器里能读到基座":真正要验的是**装载后 9 个函数都在**。 // 故这里按 installZcodeAdapter 的同一手法内联,再逐函数断言。 if strings.Contains(full, "__INLINE_ANTHROPIC_SRC__") { full = strings.ReplaceAll(full, "__INLINE_ANTHROPIC_SRC__", quoteLua(string(asrc))) } else { t.Fatal("适配器源码必须有基座占位符(基座由插件主体内联;" + "适配器沙箱里读不到文件)") } vm := NewVM(t.TempDir()) defer vm.Stop() if err := vm.LoadAdapterSource("channels-zcode", full); err != nil { t.Fatalf("装载失败: %v", err) } want := []string{"transform_request", "transform_response", "transform_stream_chunk", "transform_error", "serialize_chunk", "serialize_close", "serialize_open_preamble", "serialize_response", "deserialize_request"} var lack []string for _, f := range want { if !vm.HasFn("channels-zcode", f) { lack = append(lack, f) } } if len(lack) > 0 { t.Fatalf("★ zcode 仍缺 %d 个函数(%v)⇒ 基座继承失败 ⇒ "+ "每次调用都会报 'missing ' ⇒ 渠道完全不可用", len(lack), lack) } // 行为验证:基座的 transform_response 必须真的能转换 anthropic 响应 out, err := vm.Transform("channels-zcode", "transform_response", `{"id":"m1","type":"message","role":"assistant","content":[{"type":"text","text":"hi"}],"stop_reason":"end_turn","usage":{"input_tokens":1,"output_tokens":2}}`) if err != nil { t.Fatalf("transform_response 调用失败: %v", err) } if !strings.Contains(out, "hi") { t.Errorf("基座 transform_response 未产出内容: %s", out) } t.Logf("✓ zcode 继承基座成功(9/9 函数),transform_response → %s", out) } func quoteLua(s string) string { var b strings.Builder b.WriteByte('"') for i := 0; i < len(s); i++ { switch c := s[i]; c { case '"': b.WriteString(`\"`) case '\\': b.WriteString(`\\`) case '\n': b.WriteString(`\n`) case '\r': b.WriteString(`\r`) default: b.WriteByte(c) } } b.WriteByte('"') return b.String() }