Files
Agent-System-Backend/internal/squadadapter/orchestrate_native_test.go
T
weichen f1302ed5b3 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:47:16 +00:00

99 lines
3.4 KiB
Go

package squadadapter
import (
"context"
"fmt"
osexec "os/exec"
"strings"
"testing"
nativetools "git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/tools"
agentllm "git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/llm"
nativeadp "git-ssh.u1680832.nyat.app/weichen/Agent-Squad.git/adapters/native"
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/internal/skills"
core "git-ssh.u1680832.nyat.app/weichen/Agent-System-Core.git"
)
type orchFakeRc struct {
subagentFakeRc
dir string
}
func (f *orchFakeRc) AskHITL(card core.HITLCard) (core.HITLResponse, error) {
if len(card.Choices) > 0 {
return core.HITLResponse{ChoiceID: card.Choices[0].ID}, nil
}
return core.HITLResponse{ChoiceID: "approve"}, nil
}
// TestOrchestrateRunsOnKernelStub Q3 WP2 行为面:agent-system 退役后,
// Orchestrate 的四阶段骨架经 agent-native 内核(桩 Stream + write_file 落盘
// 交付物 + 种子技能 + Exec 白名单)跑通并产出交付物工件。
func TestOrchestrateRunsOnKernelStub(t *testing.T) {
skillsRoot := t.TempDir()
if _, serr := skills.Seed(skillsRoot); serr != nil {
t.Fatal(serr)
}
saved := AgentNativeOptions
AgentNativeOptions = func(Ctx) (nativeadp.Config, bool) {
py, _ := osexec.LookPath("python3")
return nativeadp.Config{DefaultModel: "stub", SkillsRoots: []string{skillsRoot},
Exec: &nativetools.ExecConfig{Bash: "/bin/bash", Python: py}, Stream: stubStream("# 交付\n\n这是内核桩后端产出的步骤交付物正文,长度超过五十个字符以满足最小质检要求。")}, true
}
defer func() { AgentNativeOptions = saved }()
rc := &orchFakeRc{dir: t.TempDir()}
dataDir := t.TempDir()
summary, err := Orchestrate(rc, dataDir, "生成一份示例目标简报")
t.Logf("summary = %q", summary)
if err != nil {
t.Fatalf("err = %v", err)
}
if !strings.Contains(summary, "completed") || !strings.Contains(summary, "完成 4") {
t.Fatalf("summary = %q", summary)
}
}
func stubStream(text string) agentllm.StreamFunc {
return func(_ context.Context, _ string, msgs []agentllm.Message, _ []agentllm.ToolDecl, _ agentllm.StreamOptions) <-chan agentllm.Event {
ch := make(chan agentllm.Event, 8)
go func() {
defer close(ch)
finish := func() {
ch <- agentllm.Event{Kind: agentllm.KindTextDelta, Text: text}
ch <- agentllm.Event{Kind: agentllm.KindMessageEnd, Message: agentllm.Message{Role: agentllm.RoleAssistant, Content: text}}
}
prompt := ""
for _, m := range msgs {
if m.Role == agentllm.RoleTool {
finish()
return
}
if m.Role == agentllm.RoleUser {
prompt = m.Content
}
}
i := strings.Index(prompt, "期望产出:[")
if i < 0 {
finish()
return
}
j := strings.Index(prompt[i:], "]")
if j < 0 {
finish()
return
}
targets := strings.Fields(prompt[i+len("期望产出:[") : i+j])
var calls []agentllm.ToolCall
for k, tgt := range targets {
args := fmt.Sprintf(`{"path":%q,"content":%q}`, tgt, text)
id := fmt.Sprintf("call_stub_%d", k+1)
ch <- agentllm.Event{Kind: agentllm.KindToolCallDelta, ToolIndex: k, ToolID: id, ToolName: "write_file", ArgumentsDelta: args}
calls = append(calls, agentllm.ToolCall{ID: id, Name: "write_file", Arguments: args})
}
ch <- agentllm.Event{Kind: agentllm.KindMessageEnd, Message: agentllm.Message{Role: agentllm.RoleAssistant, ToolCalls: calls, StopReason: agentllm.StopToolCalls}}
}()
return ch
}
}