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
66 lines
2.8 KiB
Go
66 lines
2.8 KiB
Go
package runmgr
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
core "git-ssh.u1680832.nyat.app/weichen/Agent-System-Core.git"
|
|
)
|
|
|
|
// 附件解析文本要落 inputs/<原名>.md 且跨轮可见:后续轮上下文里原件只剩占位时,
|
|
// 模型仍能读到原文(实测「根据纪要制定方案」轮 0 次读原件,只能编细节)。
|
|
func TestPersistInputTextsAndListWorkspaceInputs(t *testing.T) {
|
|
root := t.TempDir()
|
|
if _, err := StageWorkspaceInputs(root, "alice", "conv1", []WorkspaceFile{
|
|
{Name: "会议.docx", Content: []byte("bin")},
|
|
}, "", nil); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
long := strings.Repeat("会议结论先入库。", 40) // >200 字
|
|
docs := []core.ParsedDocument{{
|
|
Meta: core.DocMeta{Filename: "会议.docx"},
|
|
Blocks: []core.DocBlock{{Type: core.BlockPara, Text: long}},
|
|
}}
|
|
PersistInputTexts(root, "alice", "conv1", docs)
|
|
|
|
extracted := filepath.Join(root, "alice", "conv1", "inputs", "会议.md")
|
|
b, err := os.ReadFile(extracted)
|
|
if err != nil {
|
|
t.Fatalf("extracted text not written: %v", err)
|
|
}
|
|
if !strings.Contains(string(b), "会议结论先入库") {
|
|
t.Fatalf("extracted text wrong: %q", string(b)[:50])
|
|
}
|
|
|
|
// 短文本(解析失败/过短)与已是文本类的原件不写。
|
|
short := []core.ParsedDocument{{Meta: core.DocMeta{Filename: "短.docx"}, Blocks: []core.DocBlock{{Type: core.BlockPara, Text: "太短"}}}}
|
|
PersistInputTexts(root, "alice", "conv1", short)
|
|
textKind := []core.ParsedDocument{{Meta: core.DocMeta{Filename: "笔记.md"}, Blocks: []core.DocBlock{{Type: core.BlockPara, Text: long}}}}
|
|
PersistInputTexts(root, "alice", "conv1", textKind)
|
|
if _, err := os.Stat(filepath.Join(root, "alice", "conv1", "inputs", "短.md")); err == nil {
|
|
t.Fatal("short parse should not be persisted")
|
|
}
|
|
if _, err := os.Stat(filepath.Join(root, "alice", "conv1", "inputs", "笔记.md.md")); err == nil {
|
|
t.Fatal("text-kind originals should not get a duplicate extract")
|
|
}
|
|
|
|
// 跨轮列出:包含原件 + 解析文本,而不是只有本轮 staging。
|
|
got := ListWorkspaceInputs(root, "alice", "conv1", []string{"inputs/会议.docx"})
|
|
joined := strings.Join(got, ",")
|
|
if !strings.Contains(joined, "inputs/会议.docx") || !strings.Contains(joined, "inputs/会议.md") {
|
|
t.Fatalf("listing should include original + extracted: %v", got)
|
|
}
|
|
// 目录缺失时回落 staging 列表。
|
|
fallback := ListWorkspaceInputs(root, "alice", "nope", []string{"inputs/only.txt"})
|
|
if len(fallback) != 1 || fallback[0] != "inputs/only.txt" {
|
|
t.Fatalf("fallback listing broken: %v", fallback)
|
|
}
|
|
// root 未配置:全部 no-op。
|
|
PersistInputTexts("", "alice", "conv1", docs)
|
|
if got := ListWorkspaceInputs("", "alice", "conv1", []string{"inputs/a.txt"}); got[0] != "inputs/a.txt" {
|
|
t.Fatalf("unconfigured root should pass through staged: %v", got)
|
|
}
|
|
}
|