fix(athena): provider-aware config + better council error messages
Use parsed.providerID/modelID in council member description instead of raw model string (eliminates dead variable). Track skipped members with reasons and surface them in the missing-council guard prompt so users see why their council failed to register.
This commit is contained in:
parent
9d0bafbe10
commit
f0d0658eae
@ -203,8 +203,8 @@ export async function createBuiltinAgents(
|
|||||||
result["atlas"] = atlasConfig
|
result["atlas"] = atlasConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
if (councilConfig && councilConfig.members.length >= 2 && result["athena"]) {
|
if (councilConfig?.members && councilConfig.members.length >= 2 && result["athena"]) {
|
||||||
const { agents: councilAgents, registeredKeys } = registerCouncilMemberAgents(councilConfig)
|
const { agents: councilAgents, registeredKeys, skippedMembers } = registerCouncilMemberAgents(councilConfig)
|
||||||
for (const [key, config] of Object.entries(councilAgents)) {
|
for (const [key, config] of Object.entries(councilAgents)) {
|
||||||
result[key] = config
|
result[key] = config
|
||||||
}
|
}
|
||||||
@ -217,9 +217,9 @@ export async function createBuiltinAgents(
|
|||||||
prompt: (result["athena"].prompt ?? "") + councilTaskInstructions,
|
prompt: (result["athena"].prompt ?? "") + councilTaskInstructions,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result["athena"] = appendMissingCouncilPrompt(result["athena"])
|
result["athena"] = appendMissingCouncilPrompt(result["athena"], skippedMembers)
|
||||||
}
|
}
|
||||||
} else if (councilConfig && councilConfig.members.length >= 2 && !result["athena"]) {
|
} else if (councilConfig?.members && councilConfig.members.length >= 2 && !result["athena"]) {
|
||||||
log("[builtin-agents] Skipping council member registration — Athena is disabled")
|
log("[builtin-agents] Skipping council member registration — Athena is disabled")
|
||||||
} else if (result["athena"]) {
|
} else if (result["athena"]) {
|
||||||
result["athena"] = appendMissingCouncilPrompt(result["athena"])
|
result["athena"] = appendMissingCouncilPrompt(result["athena"])
|
||||||
|
|||||||
@ -42,9 +42,16 @@ After informing the user, **end your turn**. Do NOT try to work around this by u
|
|||||||
* Replaces Athena's prompt with a guard that tells the user to configure council members.
|
* Replaces Athena's prompt with a guard that tells the user to configure council members.
|
||||||
* Used when Athena is registered but no valid council config exists.
|
* Used when Athena is registered but no valid council config exists.
|
||||||
*/
|
*/
|
||||||
export function appendMissingCouncilPrompt(athenaConfig: AgentConfig): AgentConfig {
|
export function appendMissingCouncilPrompt(
|
||||||
return {
|
athenaConfig: AgentConfig,
|
||||||
...athenaConfig,
|
skippedMembers?: Array<{ name: string; reason: string }>,
|
||||||
prompt: (athenaConfig.prompt ?? "") + MISSING_COUNCIL_PROMPT,
|
): AgentConfig {
|
||||||
|
let prompt = (athenaConfig.prompt ?? "") + MISSING_COUNCIL_PROMPT
|
||||||
|
|
||||||
|
if (skippedMembers && skippedMembers.length > 0) {
|
||||||
|
const skipDetails = skippedMembers.map((m) => `- **${m.name}**: ${m.reason}`).join("\n")
|
||||||
|
prompt += `\n\n### Why Council Failed\n\nThe following members were skipped:\n${skipDetails}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { ...athenaConfig, prompt }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,25 +19,33 @@ function getCouncilMemberAgentKey(member: CouncilMemberConfig): string {
|
|||||||
* Each member becomes a separate agent callable via task(subagent_type="Council: <name>").
|
* Each member becomes a separate agent callable via task(subagent_type="Council: <name>").
|
||||||
* Returns a record of agent keys to configs and the list of registered keys.
|
* Returns a record of agent keys to configs and the list of registered keys.
|
||||||
*/
|
*/
|
||||||
|
type SkippedMember = { name: string; reason: string }
|
||||||
|
|
||||||
export function registerCouncilMemberAgents(
|
export function registerCouncilMemberAgents(
|
||||||
councilConfig: CouncilConfig
|
councilConfig: CouncilConfig
|
||||||
): { agents: Record<string, AgentConfig>; registeredKeys: string[] } {
|
): { agents: Record<string, AgentConfig>; registeredKeys: string[]; skippedMembers: SkippedMember[] } {
|
||||||
const agents: Record<string, AgentConfig> = {}
|
const agents: Record<string, AgentConfig> = {}
|
||||||
const registeredKeys: string[] = []
|
const registeredKeys: string[] = []
|
||||||
|
const skippedMembers: SkippedMember[] = []
|
||||||
|
|
||||||
for (const member of councilConfig.members) {
|
for (const member of councilConfig.members) {
|
||||||
const parsed = parseModelString(member.model)
|
const parsed = parseModelString(member.model)
|
||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
|
skippedMembers.push({
|
||||||
|
name: member.name,
|
||||||
|
reason: `Invalid model format: '${member.model}' (expected 'provider/model-id')`,
|
||||||
|
})
|
||||||
log("[council-member-agents] Skipping member with invalid model", { model: member.model })
|
log("[council-member-agents] Skipping member with invalid model", { model: member.model })
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = getCouncilMemberAgentKey(member)
|
const key = getCouncilMemberAgentKey(member)
|
||||||
const config = createCouncilMemberAgent(member.model)
|
|
||||||
|
|
||||||
const description = `Council member: ${member.name} (${member.model}). Independent read-only code analyst for Athena council. (OhMyOpenCode)`
|
|
||||||
|
|
||||||
if (agents[key]) {
|
if (agents[key]) {
|
||||||
|
skippedMembers.push({
|
||||||
|
name: member.name,
|
||||||
|
reason: `Duplicate name: '${member.name}' already registered`,
|
||||||
|
})
|
||||||
log("[council-member-agents] Skipping duplicate council member name", {
|
log("[council-member-agents] Skipping duplicate council member name", {
|
||||||
name: member.name,
|
name: member.name,
|
||||||
model: member.model,
|
model: member.model,
|
||||||
@ -46,6 +54,9 @@ export function registerCouncilMemberAgents(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const config = createCouncilMemberAgent(member.model)
|
||||||
|
const description = `Council member: ${member.name} (${parsed.providerID}/${parsed.modelID}). Independent read-only code analyst for Athena council. (OhMyOpenCode)`
|
||||||
|
|
||||||
agents[key] = {
|
agents[key] = {
|
||||||
...config,
|
...config,
|
||||||
description,
|
description,
|
||||||
@ -65,8 +76,8 @@ export function registerCouncilMemberAgents(
|
|||||||
|
|
||||||
if (registeredKeys.length < 2) {
|
if (registeredKeys.length < 2) {
|
||||||
log("[council-member-agents] Fewer than 2 valid council members after model parsing — disabling council mode")
|
log("[council-member-agents] Fewer than 2 valid council members after model parsing — disabling council mode")
|
||||||
return { agents: {}, registeredKeys: [] }
|
return { agents: {}, registeredKeys: [], skippedMembers }
|
||||||
}
|
}
|
||||||
|
|
||||||
return { agents, registeredKeys }
|
return { agents, registeredKeys, skippedMembers }
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user