mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix: preserve auto-captured skill updates
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { captureEnv } from "../../test-utils/env.js";
|
||||
import { createTrackedTempDirs } from "../../test-utils/tracked-temp-dirs.js";
|
||||
import { inspectSkillProposal, listSkillProposals } from "../workshop/service.js";
|
||||
import {
|
||||
applySkillProposal,
|
||||
inspectSkillProposal,
|
||||
listSkillProposals,
|
||||
} from "../workshop/service.js";
|
||||
import { runSkillResearchAutoCapture } from "./autocapture.js";
|
||||
|
||||
const tempDirs = createTrackedTempDirs();
|
||||
@@ -88,4 +94,61 @@ describe("skill research auto-capture", () => {
|
||||
|
||||
expect((await listSkillProposals({ workspaceDir })).proposals).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("preserves existing skill content when auto-capturing an update", async () => {
|
||||
const workspaceDir = await makeWorkspace();
|
||||
const skillFile = path.join(workspaceDir, "skills", "github-pr-workflow", "SKILL.md");
|
||||
await fs.mkdir(path.dirname(skillFile), { recursive: true });
|
||||
await fs.writeFile(
|
||||
skillFile,
|
||||
[
|
||||
"---",
|
||||
'name: "github-pr-workflow"',
|
||||
'description: "Existing GitHub PR workflow."',
|
||||
"---",
|
||||
"",
|
||||
"# GitHub PR Workflow",
|
||||
"",
|
||||
"- Preserve this original review checklist.",
|
||||
"",
|
||||
].join("\n"),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
await runSkillResearchAutoCapture({
|
||||
event: {
|
||||
success: true,
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content:
|
||||
"From now on, when working on GitHub PRs, always check CI before final response.",
|
||||
},
|
||||
],
|
||||
},
|
||||
ctx: { workspaceDir, agentId: "main" },
|
||||
config: {
|
||||
skills: {
|
||||
workshop: {
|
||||
autonomous: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const proposals = await listSkillProposals({ workspaceDir });
|
||||
expect(proposals.proposals).toHaveLength(1);
|
||||
expect(proposals.proposals[0]).toMatchObject({
|
||||
kind: "update",
|
||||
status: "pending",
|
||||
skillKey: "github-pr-workflow",
|
||||
});
|
||||
|
||||
await applySkillProposal({ workspaceDir, proposalId: proposals.proposals[0].id });
|
||||
const updatedSkill = await fs.readFile(skillFile, "utf8");
|
||||
expect(updatedSkill).toContain("Preserve this original review checklist.");
|
||||
expect(updatedSkill).toContain("always check CI before final response");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,6 +17,12 @@ type SkillResearchAgentContext = {
|
||||
|
||||
const log = createSubsystemLogger("skills/research");
|
||||
|
||||
function buildAutoCaptureUpdateContent(existingSkill: string, capturedContent: string): string {
|
||||
return [existingSkill.trimEnd(), "", "## Captured Update", "", capturedContent.trim(), ""].join(
|
||||
"\n",
|
||||
);
|
||||
}
|
||||
|
||||
export async function runSkillResearchAutoCapture(params: {
|
||||
event: SkillResearchAgentEndEvent;
|
||||
ctx: SkillResearchAgentContext;
|
||||
@@ -73,7 +79,7 @@ export async function runSkillResearchAutoCapture(params: {
|
||||
config: params.config,
|
||||
agentId: params.ctx.agentId,
|
||||
skillName: proposal.skillName,
|
||||
content: proposal.content,
|
||||
content: buildAutoCaptureUpdateContent(existingSkill, proposal.content),
|
||||
createdBy: "skill-workshop",
|
||||
goal: proposal.goal,
|
||||
evidence: proposal.evidence,
|
||||
|
||||
Reference in New Issue
Block a user