feat(FN-1050): add per-agent custom instructions support

- Add instructionsPath and instructionsText fields to Agent type and AgentStore
- Create agent-instructions resolver module in engine with priority-based resolution
- Wire custom instructions into executor, triage, reviewer, and merger agents
- Add PATCH /agents/:id/instructions API endpoint with file and text support
- Add instructions editor UI to dashboard agent detail config tab
- Add comprehensive tests for instructions resolver and AgentStore integration
- Add changeset for published package bump
This commit is contained in:
gsxdsm
2026-04-07 15:17:08 -07:00
parent f34c86345c
commit 0f0ddc02fb
14 changed files with 775 additions and 13 deletions

View File

@@ -76,9 +76,9 @@ interface AgentData {
totalInputTokens?: number;
totalOutputTokens?: number;
lastError?: string;
instructionsPath?: string;
instructionsText?: string;
}
/** Per-agent write lock for serialization */
interface AgentLock {
promise: Promise<unknown>;
}
@@ -136,6 +136,8 @@ export class AgentStore extends EventEmitter {
...(input.reportsTo && { reportsTo: input.reportsTo }),
...(input.runtimeConfig && { runtimeConfig: input.runtimeConfig }),
...(input.permissions && { permissions: input.permissions }),
...(input.instructionsPath && { instructionsPath: input.instructionsPath }),
...(input.instructionsText && { instructionsText: input.instructionsText }),
};
await this.writeAgent(agent);
@@ -214,6 +216,8 @@ export class AgentStore extends EventEmitter {
...(updates.lastError !== undefined && { lastError: updates.lastError }),
...(updates.totalInputTokens !== undefined && { totalInputTokens: updates.totalInputTokens }),
...(updates.totalOutputTokens !== undefined && { totalOutputTokens: updates.totalOutputTokens }),
...(updates.instructionsPath !== undefined && { instructionsPath: updates.instructionsPath }),
...(updates.instructionsText !== undefined && { instructionsText: updates.instructionsText }),
};
await this.writeAgent(updated);
@@ -767,6 +771,8 @@ export class AgentStore extends EventEmitter {
totalInputTokens: data.totalInputTokens,
totalOutputTokens: data.totalOutputTokens,
lastError: data.lastError,
instructionsPath: data.instructionsPath,
instructionsText: data.instructionsText,
};
}
@@ -791,6 +797,8 @@ export class AgentStore extends EventEmitter {
totalInputTokens: agent.totalInputTokens,
totalOutputTokens: agent.totalOutputTokens,
lastError: agent.lastError,
instructionsPath: agent.instructionsPath,
instructionsText: agent.instructionsText,
};
// Write atomically using temp file