feat(adapter): agent instructions file support and docs:dev script
Add instructionsFilePath config to Claude and Codex adapters, allowing agents to load external instruction files appended to the system prompt. Claude uses --append-system-prompt-file; Codex prepends file contents to the prompt. Add docs:dev script for local Mintlify preview. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,8 @@
|
||||
"db:migrate": "pnpm --filter @paperclip/db migrate",
|
||||
"secrets:migrate-inline-env": "tsx scripts/migrate-inline-env-secrets.ts",
|
||||
"db:backup": "./scripts/backup-db.sh",
|
||||
"paperclip": "node cli/node_modules/tsx/dist/cli.mjs cli/src/index.ts"
|
||||
"paperclip": "node cli/node_modules/tsx/dist/cli.mjs cli/src/index.ts",
|
||||
"docs:dev": "cd docs && npx mintlify dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.3",
|
||||
|
||||
@@ -267,6 +267,8 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
||||
const chrome = asBoolean(config.chrome, false);
|
||||
const maxTurns = asNumber(config.maxTurnsPerRun, 0);
|
||||
const dangerouslySkipPermissions = asBoolean(config.dangerouslySkipPermissions, false);
|
||||
const instructionsFilePath = asString(config.instructionsFilePath, "").trim();
|
||||
const instructionsFileDir = instructionsFilePath ? `${path.dirname(instructionsFilePath)}/` : "";
|
||||
|
||||
const runtimeConfig = await buildClaudeRuntimeConfig({
|
||||
runId,
|
||||
@@ -321,6 +323,13 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
||||
if (model) args.push("--model", model);
|
||||
if (effort) args.push("--effort", effort);
|
||||
if (maxTurns > 0) args.push("--max-turns", String(maxTurns));
|
||||
if (instructionsFilePath) {
|
||||
args.push("--append-system-prompt-file", instructionsFilePath);
|
||||
args.push(
|
||||
"--append-system-prompt",
|
||||
`The above agent instructions were loaded from ${instructionsFilePath}. Resolve any relative file references from ${instructionsFileDir}.`,
|
||||
);
|
||||
}
|
||||
args.push("--add-dir", skillsDir);
|
||||
if (extraArgs.length > 0) args.push(...extraArgs);
|
||||
return args;
|
||||
|
||||
@@ -230,8 +230,30 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
||||
`[paperclip] Codex session "${runtimeSessionId}" was saved for cwd "${runtimeSessionCwd}" and will not be resumed in "${cwd}".\n`,
|
||||
);
|
||||
}
|
||||
const instructionsFilePath = asString(config.instructionsFilePath, "").trim();
|
||||
let instructionsPrefix = "";
|
||||
if (instructionsFilePath) {
|
||||
try {
|
||||
const instructionsContents = await fs.readFile(instructionsFilePath, "utf8");
|
||||
const instructionsDir = `${path.dirname(instructionsFilePath)}/`;
|
||||
instructionsPrefix =
|
||||
`${instructionsContents}\n\n` +
|
||||
`The above agent instructions were loaded from ${instructionsFilePath}. ` +
|
||||
`Resolve any relative file references from ${instructionsDir}.\n\n`;
|
||||
await onLog(
|
||||
"stderr",
|
||||
`[paperclip] Loaded agent instructions file: ${instructionsFilePath}\n`,
|
||||
);
|
||||
} catch (err) {
|
||||
const reason = err instanceof Error ? err.message : String(err);
|
||||
await onLog(
|
||||
"stderr",
|
||||
`[paperclip] Warning: could not read agent instructions file "${instructionsFilePath}": ${reason}\n`,
|
||||
);
|
||||
}
|
||||
}
|
||||
const template = sessionId ? promptTemplate : bootstrapTemplate;
|
||||
const prompt = renderTemplate(template, {
|
||||
const renderedPrompt = renderTemplate(template, {
|
||||
agentId: agent.id,
|
||||
companyId: agent.companyId,
|
||||
runId,
|
||||
@@ -240,6 +262,7 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
||||
run: { id: runId, source: "on_demand" },
|
||||
context,
|
||||
});
|
||||
const prompt = `${instructionsPrefix}${renderedPrompt}`;
|
||||
|
||||
const buildArgs = (resumeSessionId: string | null) => {
|
||||
const args = ["exec", "--json"];
|
||||
|
||||
Reference in New Issue
Block a user