Files
Agent-Native/runtime/promptx/promptx_test.go
T
weichen b73611939e Add the SKILL.md skills system and the promptx system-prompt assembler
Why: roles had no way to carry operational know-how into executions
(RoleSpec.Skills never reached the backend), and the system prompt was
assembled ad hoc with no environment facts or skill index.

Evidence: go vet ./... clean; go test ./... 12 packages ok. Skills
cases cover directory-authoritative naming, optional frontmatter
description extraction, invalid dir skipping, root priority on name
clash, missing-root tolerance, fail-closed unknown-skill loads, 64 KiB
body / 200-byte description caps, load_skill registration only when
skills exist, and end-to-end adapter wiring (index in system prompt,
declared-skill validation failing closed on ghost skills, workspace
.agent/skills auto-merge). promptx cases pin section order, sorted
index, reasoning-profile sentence, and env defaults.

Impact: new runtime/skills + runtime/promptx packages; native.Options
gains SkillsRoots; adapters/native system prompt now composes
instructions + environment (date/model/workspace/profile) + declared
skills + index + deliverables; declared-but-missing skills fail the
step (configuration error, not silent).

Refs: plan B6; RoleSpec.Skills plumbing lands with the squad batch.
2026-10-01 05:46:41 +00:00

63 lines
1.9 KiB
Go

package promptx
import (
"strings"
"testing"
)
func TestComposeSections(t *testing.T) {
out := Compose(Parts{
Instructions: "你是审校员",
SkillsDeclared: []string{"docx-author"},
SkillsIndex: []IndexEntry{
{Name: "xlsx-author", Description: "表格交付"},
{Name: "docx-author", Description: "文档交付"},
},
Deliverables: []string{"output.md"},
Env: EnvFacts{Date: "2026-10-01(周四)", Model: "m1", WorkspaceRoot: "/w", Profile: "workspace"},
})
for _, want := range []string{
"你是审校员",
"## Environment",
"date: 2026-10-01(周四)",
"model: m1",
"workspace: /w",
"tool profile: workspace",
"## Skills",
"Declared for this task",
"docx-author",
"- docx-author — 文档交付", // 索引按名排序
"- xlsx-author — 表格交付",
"Deliverable files: output.md.",
"Use workspace tools to write those files.",
} {
if !strings.Contains(out, want) {
t.Errorf("missing %q in composed prompt:\n%s", want, out)
}
}
// 排序断言:docx 行在 xlsx 行之前。
if strings.Index(out, "- docx-author") > strings.Index(out, "- xlsx-author") {
t.Errorf("index must be sorted by name:\n%s", out)
}
}
func TestComposeReasoningProfileAndMinimal(t *testing.T) {
out := Compose(Parts{Deliverables: []string{"out.md"}, Env: EnvFacts{Profile: "reasoning"}})
if !strings.Contains(out, "Reply with the deliverable text only. Tools are disabled.") {
t.Fatalf("reasoning sentence missing:\n%s", out)
}
if strings.Contains(out, "## Environment") && !strings.Contains(out, "date:") {
t.Fatalf("unexpected env block:\n%s", out)
}
if strings.Contains(out, "## Skills") {
t.Fatalf("no skills should render no skill block:\n%s", out)
}
}
func TestComposeEnvDefaultsToDate(t *testing.T) {
out := Compose(Parts{Deliverables: []string{"o.md"}})
if !strings.Contains(out, "date: ") {
t.Fatalf("env should default to today's date:\n%s", out)
}
}