Why: the Q3 compiler maps core.WorkflowDef prompt steps onto squad graph steps; the rendered prompt text needs a first-class carrier in the step task brief (until now only leader delegations had a briefing channel). Evidence: TestStepBriefRendersIntoTaskFile asserts the section presence, body, and position (after targets, before the context table); full squad suite green (SELF), CI authoritative (GATE). Impact: additive StepSpec field brief + writeTaskFile section; no behavior change when Brief is empty. Refs: Q3 plan WP1 (2026-10-07-agent-stack-q2q3-plans.md); Dev task card .task/feature-agent-stack-q3.md
42 lines
1.4 KiB
Go
42 lines
1.4 KiB
Go
package squad
|
||
|
||
import (
|
||
"context"
|
||
"strings"
|
||
"testing"
|
||
)
|
||
|
||
// brief_test.go — Q3 WP1a:StepSpec.Brief 渲染进 TASK.md「任务指令」节。
|
||
|
||
func TestStepBriefRendersIntoTaskFile(t *testing.T) {
|
||
rec := &promptRecordingBackend{prompts: map[string][]string{}}
|
||
engine := newRecordingEngine(t, rec, []StepSpec{
|
||
{ID: "s1", Role: "researcher", Title: "起草", Targets: []string{"output.md"},
|
||
Brief: "写一份关于「太空电梯」的简报,篇幅:短。\n必须包含单独一行「核对标记:P4」。"},
|
||
})
|
||
res, err := engine.Run(context.Background(), Goal{Text: "带任务指令"}, RunOptions{})
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if res.Status != RunCompleted {
|
||
t.Fatalf("status = %s err = %v", res.Status, res.Error)
|
||
}
|
||
var prompt string
|
||
for _, p := range rec.prompts["01_researcher"] {
|
||
prompt += p
|
||
}
|
||
if !strings.Contains(prompt, "## 任务指令") {
|
||
t.Fatalf("TASK.md 缺任务指令节:%q", prompt)
|
||
}
|
||
if !strings.Contains(prompt, "核对标记:P4") {
|
||
t.Fatalf("任务指令正文缺失:%q", prompt)
|
||
}
|
||
// 指令节在期望产出之后、上下文表之前。
|
||
iOut := strings.Index(prompt, "期望产出")
|
||
iBrief := strings.Index(prompt, "## 任务指令")
|
||
iCtx := strings.Index(prompt, "## 任务上下文资源")
|
||
if !(iOut < iBrief && iBrief < iCtx) {
|
||
t.Fatalf("任务指令节位置错误:%d/%d/%d", iOut, iBrief, iCtx)
|
||
}
|
||
}
|