fix: restrict --system flag to known preset IDs (#1290)

This commit is contained in:
Devansh Jain
2026-03-05 20:50:45 -08:00
committed by GitHub
parent c95c4a4722
commit 638204ab3c
3 changed files with 51 additions and 24 deletions

View File

@@ -114,32 +114,62 @@ export const SYSTEM_PROMPTS: SystemPromptOption[] = [
},
];
/**
* Validate a system prompt preset ID.
*
* Known preset IDs are always accepted. Subagent names are only accepted
* when `allowSubagentNames` is true (internal subagent launches).
*
* @throws Error with a descriptive message listing valid options
*/
export async function validateSystemPromptPreset(
id: string,
opts?: { allowSubagentNames?: boolean },
): Promise<void> {
const validPresets = SYSTEM_PROMPTS.map((p) => p.id);
if (validPresets.includes(id)) return;
if (opts?.allowSubagentNames) {
const { getAllSubagentConfigs } = await import("./subagents");
const subagentConfigs = await getAllSubagentConfigs();
if (subagentConfigs[id]) return;
const allValid = [...validPresets, ...Object.keys(subagentConfigs)];
throw new Error(
`Invalid system prompt "${id}". Must be one of: ${allValid.join(", ")}.`,
);
}
throw new Error(
`Invalid system prompt "${id}". Must be one of: ${validPresets.join(", ")}.`,
);
}
/**
* Resolve a system prompt ID to its content.
*
* Resolution order:
* 1. If it matches an ID from SYSTEM_PROMPTS, use its content
* 2. If it matches a subagent name, use that subagent's system prompt
* 3. Otherwise, use the default system prompt
* 1. No input → default system prompt
* 2. Known preset ID → preset content
* 3. Subagent name → subagent's system prompt
* 4. Unknown → throws (callers should validate first via validateSystemPromptPreset)
*
* @param systemPromptPreset - The system prompt preset (e.g., "letta-claude") or subagent name (e.g., "explore")
* @returns The resolved system prompt content
* @throws Error if the ID doesn't match any preset or subagent
*/
export async function resolveSystemPrompt(
systemPromptPreset: string | undefined,
): Promise<string> {
// No input - use default
if (!systemPromptPreset) {
return SYSTEM_PROMPT;
}
// 1. Check if it matches a system prompt ID
const matchedPrompt = SYSTEM_PROMPTS.find((p) => p.id === systemPromptPreset);
if (matchedPrompt) {
return matchedPrompt.content;
}
// 2. Check if it matches a subagent name
const { getAllSubagentConfigs } = await import("./subagents");
const subagentConfigs = await getAllSubagentConfigs();
const matchedSubagent = subagentConfigs[systemPromptPreset];
@@ -147,6 +177,7 @@ export async function resolveSystemPrompt(
return matchedSubagent.systemPrompt;
}
// 3. Fall back to default
return SYSTEM_PROMPT;
throw new Error(
`Unknown system prompt "${systemPromptPreset}" — does not match any preset or subagent`,
);
}

View File

@@ -106,8 +106,7 @@ export const CLI_FLAG_CATALOG = {
mode: "both",
help: {
argLabel: "<id>",
description:
"System prompt ID or subagent name (applies to new or existing agent)",
description: "System prompt preset ID (applies to new or existing agent)",
},
},
"system-custom": { parser: { type: "string" }, mode: "both" },

View File

@@ -576,22 +576,19 @@ async function main(): Promise<void> {
process.exit(1);
}
// Validate system prompt preset if provided (can be a system prompt ID or subagent name)
// Validate system prompt preset if provided.
// Known preset IDs are always accepted. Subagent names are only accepted
// for internal subagent launches (LETTA_CODE_AGENT_ROLE=subagent).
if (systemPromptPreset) {
const { SYSTEM_PROMPTS } = await import("./agent/promptAssets");
const { getAllSubagentConfigs } = await import("./agent/subagents");
const validSystemPrompts = SYSTEM_PROMPTS.map((p) => p.id);
const subagentConfigs = await getAllSubagentConfigs();
const validSubagentNames = Object.keys(subagentConfigs);
const isValidSystemPrompt = validSystemPrompts.includes(systemPromptPreset);
const isValidSubagent = validSubagentNames.includes(systemPromptPreset);
if (!isValidSystemPrompt && !isValidSubagent) {
const allValid = [...validSystemPrompts, ...validSubagentNames];
const { validateSystemPromptPreset } = await import("./agent/promptAssets");
const allowSubagentNames = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
try {
await validateSystemPromptPreset(systemPromptPreset, {
allowSubagentNames,
});
} catch (err) {
console.error(
`Error: Invalid system prompt "${systemPromptPreset}". Must be one of: ${allValid.join(", ")}.`,
`Error: ${err instanceof Error ? err.message : String(err)}`,
);
process.exit(1);
}