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
98 lines
3.3 KiB
Go
98 lines
3.3 KiB
Go
package runtime
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
core "git-ssh.u1680832.nyat.app/weichen/Agent-System-Core.git"
|
|
)
|
|
|
|
// 问题一回归(run_b520bf2e3037):事实核查修正轮触发时,现场那段正式总结必须
|
|
// 降级进过程时间线;修正轮的收尾才是最终答复——否则前端按「最后一个过程部件」
|
|
// 切分后,用户只看到修正流水账,看不到原总结。
|
|
func TestFactCheckDemotesPriorSummary(t *testing.T) {
|
|
rc := &fakeRunCtx{
|
|
ctx: context.Background(),
|
|
prof: core.AgentProfile{Model: core.ModelRoute{Chat: "test-model", Lightweight: "lite-model"}},
|
|
verify: true,
|
|
execArtifact: &core.Artifact{ID: "art_0123456789ab", Name: "报告.md"},
|
|
execArtifactContent: []byte("# 报告\n\n准确率 95%。"),
|
|
}
|
|
turns := padTurns(
|
|
textDeltaTurn("", toolCall("make_report", `{"content":"准确率 95%"}`)),
|
|
textDeltaTurn("已完成。## 产出物\n\n结构完整的用户总结。"),
|
|
textDeltaTurn("已修正并重新登记。"),
|
|
)
|
|
r := &LLMRunner{Stream: scriptStream(turns, nil), VerifyStream: passedStream()}
|
|
if err := r.Execute(rc); err != nil {
|
|
t.Fatalf("Execute: %v", err)
|
|
}
|
|
var summary *core.Part
|
|
visible := []string{}
|
|
sawFactCheck := false
|
|
for i := range rc.assistant {
|
|
p := rc.assistant[i]
|
|
if p.Type == core.PartText && strings.Contains(p.Text, "结构完整的用户总结") {
|
|
summary = &rc.assistant[i]
|
|
}
|
|
if p.Type == core.PartText && !p.Process {
|
|
visible = append(visible, p.Text)
|
|
}
|
|
if p.Check != nil && !p.Check.Passed && strings.Contains(p.Check.Reason, "事实核查") {
|
|
sawFactCheck = true
|
|
}
|
|
}
|
|
if summary == nil {
|
|
t.Fatal("prior summary text missing")
|
|
}
|
|
if !summary.Process {
|
|
t.Fatalf("prior summary not demoted to process: %+v", *summary)
|
|
}
|
|
if !sawFactCheck {
|
|
t.Fatal("fact check note missing")
|
|
}
|
|
if len(visible) != 1 || visible[0] != "已修正并重新登记。" {
|
|
t.Fatalf("visible final texts = %v, want only the continuation closing", visible)
|
|
}
|
|
}
|
|
|
|
// 同源跳过提示不再作为用户可见正文追加(原先经 StopDecision.Notice 顶掉正式总结),
|
|
// 改记为通过态检查行留在过程时间线。
|
|
func TestVerifierSkipIsCheckNotFinalText(t *testing.T) {
|
|
rc := &fakeRunCtx{
|
|
ctx: context.Background(),
|
|
prof: core.AgentProfile{Model: core.ModelRoute{Chat: "test-model"}}, // 轻量回落=主模型 → 同源跳过
|
|
verify: true,
|
|
}
|
|
turns := padTurns(textDeltaTurn("总结完成。"))
|
|
r := &LLMRunner{Stream: scriptStream(turns, nil)} // 无 VerifyStream
|
|
if err := r.Execute(rc); err != nil {
|
|
t.Fatalf("Execute: %v", err)
|
|
}
|
|
skipCheck, noticeText := false, false
|
|
visible := []string{}
|
|
for _, p := range rc.assistant {
|
|
if p.Check != nil && p.Check.Passed && strings.Contains(p.Check.Reason, "同源模型验证") {
|
|
skipCheck = true
|
|
}
|
|
if p.Type == core.PartText {
|
|
if strings.Contains(p.Text, verifierUnavailableNotice) {
|
|
noticeText = true
|
|
}
|
|
if !p.Process {
|
|
visible = append(visible, p.Text)
|
|
}
|
|
}
|
|
}
|
|
if !skipCheck {
|
|
t.Fatal("same-source skip not recorded as a passing check")
|
|
}
|
|
if noticeText {
|
|
t.Fatal("skip notice leaked into message text parts")
|
|
}
|
|
if len(visible) != 1 || visible[0] != "总结完成。" {
|
|
t.Fatalf("visible final texts = %v", visible)
|
|
}
|
|
}
|