mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-14 01:50:39 +09:00
fix: gate instructions file I/O and commandNotes on fresh sessions only
On resumed sessions, skipping --append-system-prompt-file (the original fix) left two secondary issues: - commandNotes still claimed the flag was injected, producing misleading onMeta logs on every resumed heartbeat - The instructions file was still read from disk and a combined temp file written on every resume, even though effectiveInstructionsFilePath was never consumed Hoist canResumeSession before the I/O block and gate both the disk operations and commandNotes construction on !canResumeSession / !sessionId. Adds three regression tests: commandNotes is populated on fresh sessions, empty on resume; and no agent-instructions.md is written on resume.
This commit is contained in:
parent
3cfbc350a0
commit
e3804f792d
2 changed files with 132 additions and 20 deletions
|
|
@ -335,12 +335,6 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
|||
const dangerouslySkipPermissions = asBoolean(config.dangerouslySkipPermissions, true);
|
||||
const instructionsFilePath = asString(config.instructionsFilePath, "").trim();
|
||||
const instructionsFileDir = instructionsFilePath ? `${path.dirname(instructionsFilePath)}/` : "";
|
||||
const commandNotes = instructionsFilePath
|
||||
? [
|
||||
`Injected agent instructions via --append-system-prompt-file ${instructionsFilePath} (with path directive appended)`,
|
||||
]
|
||||
: [];
|
||||
|
||||
const runtimeConfig = await buildClaudeRuntimeConfig({
|
||||
runId,
|
||||
agent,
|
||||
|
|
@ -369,11 +363,27 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
|||
const billingType = resolveClaudeBillingType(effectiveEnv);
|
||||
const skillsDir = await buildSkillsDir(config);
|
||||
|
||||
const runtimeSessionParams = parseObject(runtime.sessionParams);
|
||||
const runtimeSessionId = asString(runtimeSessionParams.sessionId, runtime.sessionId ?? "");
|
||||
const runtimeSessionCwd = asString(runtimeSessionParams.cwd, "");
|
||||
const canResumeSession =
|
||||
runtimeSessionId.length > 0 &&
|
||||
(runtimeSessionCwd.length === 0 || path.resolve(runtimeSessionCwd) === path.resolve(cwd));
|
||||
const sessionId = canResumeSession ? runtimeSessionId : null;
|
||||
if (runtimeSessionId && !canResumeSession) {
|
||||
await onLog(
|
||||
"stdout",
|
||||
`[paperclip] Claude session "${runtimeSessionId}" was saved for cwd "${runtimeSessionCwd}" and will not be resumed in "${cwd}".\n`,
|
||||
);
|
||||
}
|
||||
|
||||
// When instructionsFilePath is configured, create a combined temp file that
|
||||
// includes both the file content and the path directive, so we only need
|
||||
// --append-system-prompt-file (Claude CLI forbids using both flags together).
|
||||
// Skipped on resumed sessions — the instructions are already baked into the
|
||||
// session cache and re-injecting them wastes tokens.
|
||||
let effectiveInstructionsFilePath: string | undefined = instructionsFilePath;
|
||||
if (instructionsFilePath) {
|
||||
if (instructionsFilePath && !canResumeSession) {
|
||||
try {
|
||||
const instructionsContent = await fs.readFile(instructionsFilePath, "utf-8");
|
||||
const pathDirective = `\nThe above agent instructions were loaded from ${instructionsFilePath}. Resolve any relative file references from ${instructionsFileDir}.`;
|
||||
|
|
@ -388,21 +398,16 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
|||
);
|
||||
effectiveInstructionsFilePath = undefined;
|
||||
}
|
||||
} else if (canResumeSession) {
|
||||
effectiveInstructionsFilePath = undefined;
|
||||
}
|
||||
|
||||
const runtimeSessionParams = parseObject(runtime.sessionParams);
|
||||
const runtimeSessionId = asString(runtimeSessionParams.sessionId, runtime.sessionId ?? "");
|
||||
const runtimeSessionCwd = asString(runtimeSessionParams.cwd, "");
|
||||
const canResumeSession =
|
||||
runtimeSessionId.length > 0 &&
|
||||
(runtimeSessionCwd.length === 0 || path.resolve(runtimeSessionCwd) === path.resolve(cwd));
|
||||
const sessionId = canResumeSession ? runtimeSessionId : null;
|
||||
if (runtimeSessionId && !canResumeSession) {
|
||||
await onLog(
|
||||
"stdout",
|
||||
`[paperclip] Claude session "${runtimeSessionId}" was saved for cwd "${runtimeSessionCwd}" and will not be resumed in "${cwd}".\n`,
|
||||
);
|
||||
}
|
||||
const commandNotes =
|
||||
instructionsFilePath && !sessionId
|
||||
? [
|
||||
`Injected agent instructions via --append-system-prompt-file ${instructionsFilePath} (with path directive appended)`,
|
||||
]
|
||||
: [];
|
||||
const bootstrapPromptTemplate = asString(config.bootstrapPromptTemplate, "");
|
||||
const templateData = {
|
||||
agentId: agent.id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue