feat(athena): add temperature support to council member schema
Allow per-member temperature overrides in council config. Adds temperature field to CouncilMemberSchema (0-2 range), CouncilMemberConfig type, and auto-generated JSON schema. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
4bc4b36e75
commit
8db2648339
@ -3156,6 +3156,179 @@
|
|||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"council-member": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"variant": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"skills": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 2
|
||||||
|
},
|
||||||
|
"top_p": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 1
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt_append": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"tools": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"disable": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"subagent",
|
||||||
|
"primary",
|
||||||
|
"all"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9A-Fa-f]{6}$"
|
||||||
|
},
|
||||||
|
"permission": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"edit": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bash": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"webfetch": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"task": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"doom_loop": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"external_directory": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"maxTokens": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"thinking": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"enabled",
|
||||||
|
"disabled"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"budgetTokens": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"reasoningEffort": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"low",
|
||||||
|
"medium",
|
||||||
|
"high",
|
||||||
|
"xhigh"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textVerbosity": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"low",
|
||||||
|
"medium",
|
||||||
|
"high"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"providerOptions": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
"athena": {
|
"athena": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -3344,6 +3517,11 @@
|
|||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
|||||||
@ -2,6 +2,7 @@ export interface CouncilMemberConfig {
|
|||||||
model: string
|
model: string
|
||||||
variant?: string
|
variant?: string
|
||||||
name?: string
|
name?: string
|
||||||
|
temperature?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CouncilConfig {
|
export interface CouncilConfig {
|
||||||
|
|||||||
@ -20,6 +20,7 @@ describe("CouncilMemberSchema", () => {
|
|||||||
model: "openai/gpt-5.3-codex",
|
model: "openai/gpt-5.3-codex",
|
||||||
variant: "high",
|
variant: "high",
|
||||||
name: "analyst-a",
|
name: "analyst-a",
|
||||||
|
temperature: 0.3,
|
||||||
}
|
}
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
@ -110,11 +111,48 @@ describe("CouncilMemberSchema", () => {
|
|||||||
//#then
|
//#then
|
||||||
expect(parsed.variant).toBeUndefined()
|
expect(parsed.variant).toBeUndefined()
|
||||||
expect(parsed.name).toBeUndefined()
|
expect(parsed.name).toBeUndefined()
|
||||||
|
expect(parsed.temperature).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("accepts member config with temperature", () => {
|
||||||
|
//#given
|
||||||
|
const config = { model: "openai/gpt-5.3-codex", temperature: 0.5 }
|
||||||
|
|
||||||
|
//#when
|
||||||
|
const result = CouncilMemberSchema.safeParse(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(result.success).toBe(true)
|
||||||
|
if (result.success) {
|
||||||
|
expect(result.data.temperature).toBe(0.5)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("rejects temperature below 0", () => {
|
||||||
|
//#given
|
||||||
|
const config = { model: "openai/gpt-5.3-codex", temperature: -0.1 }
|
||||||
|
|
||||||
|
//#when
|
||||||
|
const result = CouncilMemberSchema.safeParse(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(result.success).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("rejects temperature above 2", () => {
|
||||||
|
//#given
|
||||||
|
const config = { model: "openai/gpt-5.3-codex", temperature: 2.1 }
|
||||||
|
|
||||||
|
//#when
|
||||||
|
const result = CouncilMemberSchema.safeParse(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(result.success).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("rejects member config with unknown fields", () => {
|
test("rejects member config with unknown fields", () => {
|
||||||
//#given
|
//#given
|
||||||
const config = { model: "openai/gpt-5.3-codex", temperature: 0.2 }
|
const config = { model: "openai/gpt-5.3-codex", unknownField: true }
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = CouncilMemberSchema.safeParse(config)
|
const result = CouncilMemberSchema.safeParse(config)
|
||||||
|
|||||||
@ -14,6 +14,7 @@ export const CouncilMemberSchema = z.object({
|
|||||||
model: ModelStringSchema,
|
model: ModelStringSchema,
|
||||||
variant: z.string().optional(),
|
variant: z.string().optional(),
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
|
temperature: z.number().min(0).max(2).optional(),
|
||||||
}).strict()
|
}).strict()
|
||||||
|
|
||||||
export const CouncilConfigSchema = z.object({
|
export const CouncilConfigSchema = z.object({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user