ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
detections / detections (push) Waiting to run
docs / links (push) Waiting to run
web / web (push) Waiting to run
103 lines
4.7 KiB
Go
103 lines
4.7 KiB
Go
package agent
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"unicode"
|
|
)
|
|
|
|
// A2: wrap-up / settlement 프롬프트 중국어화.
|
|
//
|
|
// 이 상수들은 run 또는 task 가 단계/시간 예산에 걸려 종료될 때 settlement 단계에서
|
|
// 주입되어, 사용자에게 그대로 노출되는 최종 요약을 직접 지시한다. 따라서 (1) 중국어로
|
|
// 작성되어야 하고, (2) 한글(Hangul) 잔재가 없어야 하며, (3) 도구 이름과
|
|
// "한 문장 순수 텍스트" 같은 지시 의미가 보존되어야 한다.
|
|
//
|
|
// DB 시드는 wrapup_prompt / task_timeout_wrapup_prompt 를 빈 문자열로 두고(db/db.go 의
|
|
// builtin 에이전트 INSERT 는 이 컬럼을 채우지 않는다), 비어 있으면 이 상수로 떨어진다.
|
|
// 즉 이 상수들이 wrap-up 문구의 유일한 원천이다.
|
|
func TestWrapupPromptsLocalizedToChinese(t *testing.T) {
|
|
all := map[string]string{
|
|
"settleWrapUpPrompt": settleWrapUpPrompt,
|
|
"plannerWrapUpDefault": plannerWrapUpDefault,
|
|
"mainAgentWrapUpDefault": mainAgentWrapUpDefault,
|
|
"genericWrapUpDefault": genericWrapUpDefault,
|
|
"workerTaskTimeoutDefault": workerTaskTimeoutDefault,
|
|
"plannerTaskTimeoutDefault": plannerTaskTimeoutDefault,
|
|
}
|
|
|
|
hasScript := func(s string, table *unicode.RangeTable) bool {
|
|
for _, r := range s {
|
|
if unicode.Is(table, r) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
for name, p := range all {
|
|
if !hasScript(p, unicode.Han) {
|
|
t.Errorf("%s: 한자가 전혀 없어 중국어화되지 않았다", name)
|
|
}
|
|
// 도구 이름은 ASCII 이므로, 번역이 끝났다면 한글(Hangul)이 하나도 없어야 한다.
|
|
if hasScript(p, unicode.Hangul) {
|
|
t.Errorf("%s: 한글 잔재가 남아 번역이 미완이다: %q", name, p)
|
|
}
|
|
}
|
|
|
|
// 도구 이름은 식별자이므로 번역하지 않고 그대로 보존되어야 한다.
|
|
// worker 계열(per-run·task-timeout)은 record_fact 로 결론을, report_finding 으로
|
|
// 취약점을 쓰고, 마지막에 한 문장 순수 텍스트로 요약하라는 지시를 유지한다.
|
|
mustContain := func(name, p string, subs ...string) {
|
|
for _, s := range subs {
|
|
if !strings.Contains(p, s) {
|
|
t.Errorf("%s: 지시 의미 %q 가 보존되어야 하는데 없다", name, s)
|
|
}
|
|
}
|
|
}
|
|
mustContain("settleWrapUpPrompt", settleWrapUpPrompt,
|
|
"insert_assets", "record_fact", "report_finding", "一句", "纯文本")
|
|
mustContain("workerTaskTimeoutDefault", workerTaskTimeoutDefault,
|
|
"insert_assets", "record_fact", "report_finding", "一句", "纯文本")
|
|
mustContain("genericWrapUpDefault", genericWrapUpDefault, "一句", "纯文本")
|
|
mustContain("mainAgentWrapUpDefault", mainAgentWrapUpDefault, "一句", "纯文本")
|
|
// planner 는 요약 문장을 내지 않고(판정만 하고 종료) 의도·목표·할일 도구를 유지한다.
|
|
mustContain("plannerWrapUpDefault", plannerWrapUpDefault, "add_intent", "prove_goal", "TodoWrite")
|
|
mustContain("plannerTaskTimeoutDefault", plannerTaskTimeoutDefault, "prove_goal")
|
|
}
|
|
|
|
// per-run 과 task-timeout 은 의미가 달라야 한다(특히 planner): per-run 은 "이번 라운드만
|
|
// 끝난다"이고 task-timeout 은 "작업 전체가 끝난다"이다. 상수 매핑이 바뀌어 섞이면 안 된다.
|
|
func TestWrapupDefaultsRouting(t *testing.T) {
|
|
if WrapupDefault("worker") != settleWrapUpPrompt {
|
|
t.Error("worker per-run 기본값이 settleWrapUpPrompt 가 아니다")
|
|
}
|
|
if WrapupDefault("planner") != plannerWrapUpDefault {
|
|
t.Error("planner per-run 기본값이 plannerWrapUpDefault 가 아니다")
|
|
}
|
|
if WrapupDefault("mainagent") != mainAgentWrapUpDefault {
|
|
t.Error("mainagent per-run 기본값이 mainAgentWrapUpDefault 가 아니다")
|
|
}
|
|
// 미등록 키(커스텀 에이전트)는 generic 으로 떨어진다.
|
|
if WrapupDefault("unknown-agent") != genericWrapUpDefault {
|
|
t.Error("미등록 키가 genericWrapUpDefault 로 떨어지지 않는다")
|
|
}
|
|
// task-timeout 은 worker/planner 에만 있고, 그 외는 빈 문자열(호출부가 per-run 으로 회귀).
|
|
if TaskTimeoutWrapupDefault("worker") != workerTaskTimeoutDefault {
|
|
t.Error("worker task-timeout 기본값이 workerTaskTimeoutDefault 가 아니다")
|
|
}
|
|
if TaskTimeoutWrapupDefault("planner") != plannerTaskTimeoutDefault {
|
|
t.Error("planner task-timeout 기본값이 plannerTaskTimeoutDefault 가 아니다")
|
|
}
|
|
if TaskTimeoutWrapupDefault("mainagent") != "" {
|
|
t.Error("mainagent 은 task-timeout 문구가 없어야 한다(빈 문자열)")
|
|
}
|
|
// per-run 과 task-timeout 문구가 동일하면 의미 구분이 사라진 것이다.
|
|
if workerTaskTimeoutDefault == settleWrapUpPrompt {
|
|
t.Error("worker 의 per-run 과 task-timeout 문구가 동일하다")
|
|
}
|
|
if plannerTaskTimeoutDefault == plannerWrapUpDefault {
|
|
t.Error("planner 의 per-run 과 task-timeout 문구가 동일하다")
|
|
}
|
|
}
|