* feat(#2454): PR 2 — cmdAgentSkills fallback reads installed agent prompt When no agent_skills config entry exists for a given agent type (the common case on AGENTS-native runtimes), cmdAgentSkills previously returned empty output. Workflows that inject ${AGENT_SKILLS_*} into subagent dispatch prompts then carried nothing — the persona was lost. The fallback: resolve the runtime's agents directory via checkAgentsInstalled and read <agentsDir>/<agentType>.md. The installed agent prompt content (now present for kimi-code via the flat-skills install layout) flows into the dispatch prompt so the persona survives even without explicit config opt-in. This is the reporter's suggested fix #2 from #2454. The fallback triggers for ALL runtimes (not just kimi-code) when no config entry exists — it is strictly additive (returns content the previous empty path could not). If the agent file is not found on disk, the block stays empty (same as before). * docs(changeset): Phase 3 agent-skills fallback Added (#2510) * docs(changeset): backfill PR #2521 for Phase 3 (#2510)
This commit is contained in:
33
src/init.cts
33
src/init.cts
@@ -2258,13 +2258,44 @@ function cmdAgentSkills(
|
||||
const projectRoot = findProjectRoot(cwd);
|
||||
const { config, source, degraded } = loadConfigResolved(projectRoot);
|
||||
const diagnostics = { warnings: [] as string[] };
|
||||
const block = buildAgentSkillsBlock(
|
||||
let block = buildAgentSkillsBlock(
|
||||
config,
|
||||
agentType,
|
||||
projectRoot,
|
||||
diagnostics,
|
||||
);
|
||||
|
||||
// #2454: Agent prompt fallback for AGENTS-native runtimes where named
|
||||
// subagents are NOT dispatchable (kimi-code, kimi, opencode, kilo, etc.).
|
||||
// On these runtimes, workflows inject ${AGENT_SKILLS_*} into the dispatch
|
||||
// prompt of a built-in subagent (coder/explore/plan). If no
|
||||
// model_profile_overrides or agent_skills config entry exists, the block
|
||||
// is empty — but the agent's prompt CONTENT is installed on disk at the
|
||||
// runtime's agents directory. Read it as a fallback so the persona survives
|
||||
// the dispatch even without explicit config opt-in.
|
||||
//
|
||||
// GATED to non-claude runtimes: Claude Code supports named subagent dispatch
|
||||
// and its ${AGENT_SKILLS_*} contract is a skills-injection path, not a
|
||||
// persona fallback. Triggering the fallback for claude would change the
|
||||
// documented "unconfigured → empty block" contract that agent-skills tests
|
||||
// pin.
|
||||
if (!block) {
|
||||
const runtime = (config && (config['runtime'] as string)) || process.env['GSD_RUNTIME'] || 'claude';
|
||||
if (runtime !== 'claude') {
|
||||
const agentCheck = checkAgentsInstalled(runtime) as unknown as { agents_dir?: string } | null;
|
||||
const agentsDir = agentCheck?.agents_dir;
|
||||
if (typeof agentsDir === 'string' && agentsDir.length > 0) {
|
||||
const agentFile = path.join(agentsDir, `${agentType}.md`);
|
||||
try {
|
||||
const content = platformReadSync(agentFile);
|
||||
if (content && content.length > 0) {
|
||||
block = content;
|
||||
}
|
||||
} catch { /* agent file not found — fall through to empty block */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute configured + reason for diagnostic output.
|
||||
const agentSkillsMap = (config && config['agent_skills'] && typeof config['agent_skills'] === 'object')
|
||||
? config['agent_skills'] as Record<string, unknown>
|
||||
|
||||
Reference in New Issue
Block a user