Files
swarm-zap/hooks/model-skill-injector/handler.ts

69 lines
1.8 KiB
TypeScript

import * as fs from "fs";
import * as path from "path";
const handler = async (event) => {
if (event.type !== "agent" || event.action !== "bootstrap") return;
const cfg = event.context?.cfg;
const workspaceDir = event.context?.workspaceDir;
if (!workspaceDir) return;
// Resolve active model string
const modelRaw: string =
(typeof cfg?.agents?.defaults?.model === "string"
? cfg.agents.defaults.model
: cfg?.agents?.defaults?.model?.primary) ?? "";
const model = modelRaw.toLowerCase();
// Detect model family by model name (provider-agnostic)
let family: "anthropic" | "openai" | "generic";
if (model.includes("claude")) {
family = "anthropic";
} else if (model.includes("gpt")) {
family = "openai";
} else {
family = "generic";
}
const hintsDir = path.join(
workspaceDir,
"skills",
"llm-tool-best-practices",
"hints"
);
const hintsFile = path.join(hintsDir, `${family}.md`);
let content: string;
try {
content = fs.readFileSync(hintsFile, "utf8");
} catch {
// Hints file missing — skip silently
console.warn(
`[model-skill-injector] Hints file not found: ${hintsFile} (family=${family}, model=${modelRaw})`
);
return;
}
// Inject as a virtual bootstrap file
const bootstrapFiles = event.context?.bootstrapFiles;
if (!Array.isArray(bootstrapFiles)) return;
// Remove any previous injection (idempotent on re-runs)
const existing = bootstrapFiles.findIndex((f) => f.name === "MODEL_HINTS.md");
if (existing !== -1) bootstrapFiles.splice(existing, 1);
bootstrapFiles.push({
name: "MODEL_HINTS.md",
content,
// Mark virtual so it doesn't try to read from disk
virtual: true,
});
console.log(
`[model-skill-injector] Injected ${family} hints (model=${modelRaw})`
);
};
export default handler;