Files
Agent-Native/runtime/loop_serial_partition_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

73 lines
2.2 KiB
Go

package runtime
import (
"context"
"encoding/json"
"sync"
"testing"
"git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/llm"
"git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/tools"
)
// orderTool 记录自己的执行序号(并发安全)。
type orderTool struct {
name string
mu sync.Mutex
seq []string
}
func (o *orderTool) Name() string { return o.name }
func (o *orderTool) Description() string { return o.name }
func (o *orderTool) Parameters() json.RawMessage { return json.RawMessage(`{"type":"object"}`) }
func (o *orderTool) Execute(ctx context.Context, _ json.RawMessage) (tools.Result, error) {
id := o.name
if call, ok := ToolCallFromContext(ctx); ok {
id = call.ID
}
o.mu.Lock()
o.seq = append(o.seq, id)
o.mu.Unlock()
return tools.Result{Content: "ran " + id}, nil
}
// TestLoopSerialToolsKeepOrder 并行模式下 SerialTools 命中的调用按声明顺序执行
// (互斥不保序不够:卡片流等有先后依赖),未命中的并发执行。
func TestLoopSerialToolsKeepOrder(t *testing.T) {
cards := &orderTool{name: "card"}
reads := &orderTool{name: "read"}
reg := tools.NewRegistry(t.TempDir())
reg.Register(cards)
reg.Register(reads)
res, err := Run(context.Background(), Config{
Model: "fake", Tools: reg,
ToolExecution: ExecParallel,
SerialTools: map[string]bool{"card": true},
Stream: script(
llm.Message{Role: llm.RoleAssistant, StopReason: llm.StopToolCalls, ToolCalls: []llm.ToolCall{
{ID: "s1", Name: "card", Arguments: `{}`},
{ID: "p1", Name: "read", Arguments: `{}`},
{ID: "s2", Name: "card", Arguments: `{}`},
{ID: "s3", Name: "card", Arguments: `{}`},
}},
llm.Message{Role: llm.RoleAssistant, Content: "done", StopReason: llm.StopEnd},
),
}, llm.Message{Role: llm.RoleUser, Content: "go"})
if err != nil {
t.Fatal(err)
}
cards.mu.Lock()
got := append([]string(nil), cards.seq...)
cards.mu.Unlock()
if len(got) != 3 || got[0] != "s1" || got[1] != "s2" || got[2] != "s3" {
t.Fatalf("card executions must follow declaration order s1→s2→s3, got %v", got)
}
reads.mu.Lock()
nRead := len(reads.seq)
reads.mu.Unlock()
if nRead != 1 {
t.Fatalf("read executions = %d", nRead)
}
_ = res
}