fix(chat): pin composer, set reply language, and track model loading

This commit is contained in:
Jeffrey Wu
2026-09-07 12:00:27 +08:00
parent 5c61371d7e
commit f4e3f41c2c
9 changed files with 299 additions and 36 deletions
+28
View File
@@ -103,6 +103,34 @@ describe("SkillCatalog", () => {
it("discovers .agents and .pi skills without reading bodies into the catalog", async () => {
const root = await mkdtemp(path.join(tmpdir(), "studio-skills-")); await createSkill(root, ".agents/skills/one", "one", "First skill"); await createSkill(root, ".pi/skills/two", "two", "Second skill"); const catalog = new SkillCatalog(root, path.join(root, "agent-dir")); await catalog.reload(); expect(catalog.list().filter((item) => ["one", "two"].includes(item.name))).toHaveLength(2); expect(JSON.stringify(catalog.list())).not.toContain("SECRET BODY");
});
it("appends the Session language policy while preserving default prompts, skills and extensions", async () => {
const root = await mkdtemp(path.join(tmpdir(), "studio-language-"));
const agentDir = path.join(root, "agent-dir");
await createSkill(root, ".agents/skills/one", "one", "First skill");
await mkdir(path.join(root, ".pi/skills"), { recursive: true });
await writeFile(path.join(root, ".pi/APPEND_SYSTEM.md"), "Existing appended instruction");
const catalog = new SkillCatalog(root, agentDir);
await catalog.reload();
const extension = vi.fn();
const loader = await catalog.createSessionLoader(root, agentDir, [extension]);
expect(loader.getSystemPrompt()).toBeUndefined(); // Pi still builds its default Tool/Skill prompt.
expect(loader.getSystemPromptSource()).toBeUndefined();
const appended = loader.getAppendSystemPrompt();
expect(appended[0]).toBe("Existing appended instruction");
const policy = appended.at(-1)!;
expect(policy).toContain("默认使用中文回复,包括中文请求");
expect(policy).toContain("仅当首条用户输入中的自然语言请求明确为英文时");
expect(policy).toContain("Skill 名称、Skill XML/正文、命令、路径、代码和技术标识");
expect(policy).toContain("首条输入仅包含 Skill 内容或 Skill 名称,或自然语言无法明确判断时,选择中文");
expect(policy).toContain("当前 Session 内保持一致");
expect(policy).toContain("Reset 创建新 Session 后重新判断");
expect(loader.getSkills().skills.some((skill) => skill.name === "one")).toBe(true);
expect(extension).toHaveBeenCalledOnce();
await writeFile(path.join(root, ".pi/SYSTEM.md"), "Existing system prompt");
const next = await catalog.createSessionLoader(root, agentDir, []);
expect(next.getSystemPrompt()).toBe("Existing system prompt");
expect(next.getAppendSystemPrompt()).toEqual(appended);
});
it("loads path-delimited AGENT_SKILLS_DIRS and de-duplicates canonical paths", async () => {
const root = await mkdtemp(path.join(tmpdir(), "studio-skills-")); await mkdir(path.join(root, ".agents/skills"), { recursive: true }); await mkdir(path.join(root, ".pi/skills"), { recursive: true }); const extra = path.join(root, "extra"); await createSkill(root, "extra/custom", "custom", "Extra skill"); const catalog = new SkillCatalog(root, path.join(root, "agent-dir"), [extra, extra].join(path.delimiter)); await catalog.reload(); expect(catalog.list().filter((item) => item.name === "custom")).toHaveLength(1);
});