MCPcopy Create free account
hub / github.com/MemTensor/MemOS / generate

Method generate

packages/memos-core/src/skill/generator.ts:195–334  ·  view source on GitHub ↗
(task: Task, chunks: Chunk[], evalResult: CreateEvalResult)

Source from the content-addressed store, hash-verified

193 }
194
195 async generate(task: Task, chunks: Chunk[], evalResult: CreateEvalResult): Promise<Skill> {
196 const conversationText = this.buildConversationText(chunks);
197
198 // ── Step 1: Generate SKILL.md (primary, largest output) ──
199 this.ctx.log.info(`SkillGenerator: Step 1/4 — generating SKILL.md for "${evalResult.suggestedName}"`);
200 let skillMdContent = await this.step1GenerateSkillMd(task, conversationText, evalResult);
201
202 const skillsStoreDir = path.join(this.ctx.stateDir, "skills-store");
203 const dirPath = path.join(skillsStoreDir, evalResult.suggestedName);
204 fs.mkdirSync(dirPath, { recursive: true });
205 fs.writeFileSync(path.join(dirPath, "SKILL.md"), skillMdContent, "utf-8");
206
207 // ── Step 2: Extract scripts (parallel with refs) ──
208 this.ctx.log.info(`SkillGenerator: Step 2/4 — extracting scripts and references`);
209 const [scripts, references] = await Promise.all([
210 this.step2ExtractScripts(skillMdContent, conversationText),
211 this.step2bExtractReferences(skillMdContent, conversationText),
212 ]);
213
214 if (scripts.length > 0) {
215 const scriptsDir = path.join(dirPath, "scripts");
216 fs.mkdirSync(scriptsDir, { recursive: true });
217 for (const s of scripts) {
218 fs.writeFileSync(path.join(scriptsDir, s.filename), s.content, "utf-8");
219 }
220 }
221
222 if (references.length > 0) {
223 const refsDir = path.join(dirPath, "references");
224 fs.mkdirSync(refsDir, { recursive: true });
225 for (const r of references) {
226 fs.writeFileSync(path.join(refsDir, r.filename), r.content, "utf-8");
227 }
228 }
229
230 // Ensure SKILL.md has companion files section
231 if (scripts.length > 0 || references.length > 0) {
232 const hasCompanionSection = /## Companion files|## 附属文件|## 辅助文件/.test(skillMdContent);
233 if (!hasCompanionSection) {
234 const companionLines: string[] = ["\n\n## Companion files\n"];
235 for (const s of scripts) {
236 companionLines.push(`- \`scripts/${s.filename}\` — automation script`);
237 }
238 for (const r of references) {
239 companionLines.push(`- \`references/${r.filename}\` — reference documentation`);
240 }
241 skillMdContent += companionLines.join("\n");
242 fs.writeFileSync(path.join(dirPath, "SKILL.md"), skillMdContent, "utf-8");
243 }
244 }
245
246 // ── Step 3: Generate evals ──
247 this.ctx.log.info(`SkillGenerator: Step 3/4 — generating eval test cases`);
248 const evals = await this.step3GenerateEvals(skillMdContent);
249
250 if (evals.length > 0) {
251 const evalsDir = path.join(dirPath, "evals");
252 fs.mkdirSync(evalsDir, { recursive: true });

Callers 1

handleNewSkillMethod · 0.45

Calls 15

buildConversationTextMethod · 0.95
step1GenerateSkillMdMethod · 0.95
step2ExtractScriptsMethod · 0.95
step3GenerateEvalsMethod · 0.95
verifyEvalsMethod · 0.95
parseDescriptionMethod · 0.95
allMethod · 0.80
mapMethod · 0.80
infoMethod · 0.65
embedMethod · 0.65
warnMethod · 0.65

Tested by

no test coverage detected