chatccc 0.2.72 → 0.2.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/__tests__/im-skills.test.ts +26 -1
- package/src/im-skills.ts +31 -0
package/package.json
CHANGED
|
@@ -3,7 +3,12 @@ import { join } from "node:path";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { afterEach, describe, expect, it } from "vitest";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
buildImSkillsPrompt,
|
|
8
|
+
buildImSkillsPromptCached,
|
|
9
|
+
clearImSkillsPromptCache,
|
|
10
|
+
exportSkillSubDocs,
|
|
11
|
+
} from "../im-skills.ts";
|
|
7
12
|
|
|
8
13
|
let tempRoot: string | null = null;
|
|
9
14
|
|
|
@@ -97,4 +102,24 @@ describe("IM skills prompt rendering", () => {
|
|
|
97
102
|
expect(prompt).toContain("[ChatCCC IM skill: wechat-skill]");
|
|
98
103
|
expect(exported.length).toBeGreaterThanOrEqual(2);
|
|
99
104
|
});
|
|
105
|
+
|
|
106
|
+
it("exports cached prompt helpers used by session startup", async () => {
|
|
107
|
+
tempRoot = await mkdtemp(join(tmpdir(), "chatccc-im-skills-cache-"));
|
|
108
|
+
const skillDir = join(tempRoot, "feishu-skill");
|
|
109
|
+
await mkdir(skillDir);
|
|
110
|
+
await writeFile(join(skillDir, "skill.md"), "cwd={{cwd}}", "utf-8");
|
|
111
|
+
|
|
112
|
+
const input = {
|
|
113
|
+
skillsDir: tempRoot,
|
|
114
|
+
variables: { cwd: "C:/first", session_id: "sid_cache" },
|
|
115
|
+
};
|
|
116
|
+
const first = await buildImSkillsPromptCached(input);
|
|
117
|
+
await writeFile(join(skillDir, "skill.md"), "cwd={{cwd}} changed", "utf-8");
|
|
118
|
+
const cached = await buildImSkillsPromptCached(input);
|
|
119
|
+
clearImSkillsPromptCache("sid_cache");
|
|
120
|
+
const refreshed = await buildImSkillsPromptCached(input);
|
|
121
|
+
|
|
122
|
+
expect(cached).toBe(first);
|
|
123
|
+
expect(refreshed).toContain("changed");
|
|
124
|
+
});
|
|
100
125
|
});
|
package/src/im-skills.ts
CHANGED
|
@@ -70,6 +70,37 @@ export async function buildImSkillsPrompt(input: BuildImSkillsPromptInput): Prom
|
|
|
70
70
|
.join("\n\n");
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// 会话级缓存:相同 session_id + cwd 的渲染结果完全相同,避免每轮重复读文件+渲染
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
const promptCache = new Map<string, string>();
|
|
78
|
+
|
|
79
|
+
function promptCacheKey(input: BuildImSkillsPromptInput): string {
|
|
80
|
+
const names = input.enabledSkillNames
|
|
81
|
+
? [...input.enabledSkillNames].sort().join(",")
|
|
82
|
+
: "*";
|
|
83
|
+
const { session_id, cwd } = input.variables;
|
|
84
|
+
return `${input.skillsDir ?? DEFAULT_IM_SKILLS_DIR}|${names}|${session_id}|${cwd}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** 带会话级缓存的 buildImSkillsPrompt。同 session + 同 cwd 时直接返回缓存的渲染结果。 */
|
|
88
|
+
export async function buildImSkillsPromptCached(input: BuildImSkillsPromptInput): Promise<string> {
|
|
89
|
+
const key = promptCacheKey(input);
|
|
90
|
+
const cached = promptCache.get(key);
|
|
91
|
+
if (cached !== undefined) return cached;
|
|
92
|
+
const result = await buildImSkillsPrompt(input);
|
|
93
|
+
promptCache.set(key, result);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** 清除指定会话的缓存(如 /cd 后 cwd 变了,旧 key 不再需要) */
|
|
98
|
+
export function clearImSkillsPromptCache(sessionId: string): void {
|
|
99
|
+
for (const key of promptCache.keys()) {
|
|
100
|
+
if (key.includes(`|${sessionId}|`)) promptCache.delete(key);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
73
104
|
/**
|
|
74
105
|
* 渲染技能目录下的子文档(skill.md 除外)并写入 outputDir。
|
|
75
106
|
* 返回写入的文件路径列表。通常在会话初始化时调用,写入的文档供 Agent 按需读取。
|