Files
Agent-Native/runtime/loop_cache_contract_test.go
T
weichen 6ddd3da8df Enable canonical versioned Go module consumption
Why: Allow consumers to download an immutable module revision without nested source checkouts or local path replacements.

Evidence: SELF package tests and the prior canonical-path rejection are recorded in the Dev dependency-workspace task card; remote consumption is replayed against the committed candidate.

Impact: Change the module identity and its Go imports while preserving API behavior. Existing historical submodule revisions remain buildable.

Refs: Versioned dependencies U1/U3; feature/dependency-workspace
2026-10-13 15:36:10 +00:00

71 lines
2.4 KiB
Go

package runtime
import (
"context"
"encoding/json"
"strings"
"testing"
"git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/llm"
"git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/tools"
)
// ---- N2 WP1:前缀稳定契约(缓存友好的机器钉住:同一注册序列 → 逐字节确定)----
type contractTool struct {
name, desc string
deferred bool
}
func (t contractTool) Name() string { return t.name }
func (t contractTool) Description() string { return t.desc }
func (t contractTool) Parameters() json.RawMessage { return json.RawMessage(`{"type":"object","properties":{}}`) }
func (t contractTool) Execute(_ context.Context, _ json.RawMessage) (tools.Result, error) {
return tools.Result{Content: "ok"}, nil
}
func (t contractTool) Exposure() string {
if t.deferred {
return tools.ExposureDeferred
}
return tools.ExposureDirect
}
func buildContractRegistry() *tools.Registry {
reg := tools.NewRegistry("")
reg.Register(contractTool{name: "read_file", desc: "读文件"})
reg.Register(contractTool{name: "write_file", desc: "写文件"})
reg.Register(contractTool{name: "grep", desc: "搜索", deferred: true})
return reg
}
func TestSystemTextDeterministicAcrossIdenticalBuilds(t *testing.T) {
a := systemText(Config{SystemPrompt: "sys", Tools: buildContractRegistry()})
b := systemText(Config{SystemPrompt: "sys", Tools: buildContractRegistry()})
if a != b {
t.Fatalf("同一注册序列的系统文本必须逐字节一致:\n%q\nvs\n%q", a, b)
}
// 契约内容:直接工具全在清单内且按注册序;deferred 工具不进入清单。
idx := strings.Index(a, "read_file")
if idx < 0 || strings.Index(a, "write_file") < idx {
t.Fatalf("直接工具须按注册序出现:%q", a)
}
if strings.Contains(a, "grep") {
t.Fatalf("deferred 工具不得出现在系统文本:%q", a)
}
// 元工具注入位置确定(tool_search/call_tool 存在且在 Decls 中)。
decls := buildContractRegistry().Decls()
names := []string{}
for _, d := range decls {
names = append(names, d.Name)
}
if len(names) != 4 || names[0] != "read_file" || names[1] != "write_file" {
t.Fatalf("Decls 顺序契约:%v", names)
}
if names[2] != "tool_search" && names[3] != "tool_search" {
if names[2] != "call_tool" && names[3] != "call_tool" {
t.Fatalf("元工具缺失:%v", names)
}
}
var _ = llm.ToolDecl{} // 保持导入面稳定
}