refactor(schema): dedupe custom agent override with ref
This commit is contained in:
parent
818fdc490c
commit
d7ab5c4d7b
@ -3155,223 +3155,7 @@
|
|||||||
"pattern": "^(?!(?:[bB][uU][iI][lL][dD]|[pP][lL][aA][nN]|[sS][iI][sS][yY][pP][hH][uU][sS]|[hH][eE][pP][hH][aA][eE][sS][tT][uU][sS]|[sS][iI][sS][yY][pP][hH][uU][sS]-[jJ][uU][nN][iI][oO][rR]|[oO][pP][eE][nN][cC][oO][dD][eE]-[bB][uU][iI][lL][dD][eE][rR]|[pP][rR][oO][mM][eE][tT][hH][eE][uU][sS]|[mM][eE][tT][iI][sS]|[mM][oO][mM][uU][sS]|[oO][rR][aA][cC][lL][eE]|[lL][iI][bB][rR][aA][rR][iI][aA][nN]|[eE][xX][pP][lL][oO][rR][eE]|[mM][uU][lL][tT][iI][mM][oO][dD][aA][lL]-[lL][oO][oO][kK][eE][rR]|[aA][tT][lL][aA][sS])$).+"
|
"pattern": "^(?!(?:[bB][uU][iI][lL][dD]|[pP][lL][aA][nN]|[sS][iI][sS][yY][pP][hH][uU][sS]|[hH][eE][pP][hH][aA][eE][sS][tT][uU][sS]|[sS][iI][sS][yY][pP][hH][uU][sS]-[jJ][uU][nN][iI][oO][rR]|[oO][pP][eE][nN][cC][oO][dD][eE]-[bB][uU][iI][lL][dD][eE][rR]|[pP][rR][oO][mM][eE][tT][hH][eE][uU][sS]|[mM][eE][tT][iI][sS]|[mM][oO][mM][uU][sS]|[oO][rR][aA][cC][lL][eE]|[lL][iI][bB][rR][aA][rR][iI][aA][nN]|[eE][xX][pP][lL][oO][rR][eE]|[mM][uU][lL][tT][iI][mM][oO][dD][aA][lL]-[lL][oO][oO][kK][eE][rR]|[aA][tT][lL][aA][sS])$).+"
|
||||||
},
|
},
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
"type": "object",
|
"$ref": "#/$defs/agentOverrideConfig"
|
||||||
"properties": {
|
|
||||||
"model": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fallback_models": {
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"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",
|
|
||||||
"propertyNames": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"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",
|
|
||||||
"propertyNames": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"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",
|
|
||||||
"propertyNames": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"additionalProperties": {}
|
|
||||||
},
|
|
||||||
"ultrawork": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"model": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"variant": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"compaction": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"model": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"variant": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"categories": {
|
"categories": {
|
||||||
@ -4070,5 +3854,226 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false,
|
||||||
|
"$defs": {
|
||||||
|
"agentOverrideConfig": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fallback_models": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"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",
|
||||||
|
"propertyNames": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"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",
|
||||||
|
"propertyNames": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"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",
|
||||||
|
"propertyNames": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"additionalProperties": {}
|
||||||
|
},
|
||||||
|
"ultrawork": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"variant": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"compaction": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"variant": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,17 +1,53 @@
|
|||||||
import * as z from "zod"
|
import * as z from "zod"
|
||||||
import { OhMyOpenCodeConfigSchema } from "../src/config/schema"
|
import { OhMyOpenCodeConfigSchema } from "../src/config/schema"
|
||||||
|
|
||||||
|
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
||||||
|
return typeof value === "object" && value !== null ? (value as Record<string, unknown>) : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function dedupeCustomAgentOverrideSchema(schema: Record<string, unknown>): Record<string, unknown> {
|
||||||
|
const rootProperties = asRecord(schema.properties)
|
||||||
|
const agentsSchema = asRecord(rootProperties?.agents)
|
||||||
|
const builtInAgentProps = asRecord(agentsSchema?.properties)
|
||||||
|
const customAgentsSchema = asRecord(rootProperties?.custom_agents)
|
||||||
|
const customAdditionalProperties = asRecord(customAgentsSchema?.additionalProperties)
|
||||||
|
|
||||||
|
if (!builtInAgentProps || !customAgentsSchema || !customAdditionalProperties) {
|
||||||
|
return schema
|
||||||
|
}
|
||||||
|
|
||||||
|
const referenceAgentSchema = asRecord(
|
||||||
|
builtInAgentProps.build
|
||||||
|
?? builtInAgentProps.oracle
|
||||||
|
?? builtInAgentProps.explore,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!referenceAgentSchema) {
|
||||||
|
return schema
|
||||||
|
}
|
||||||
|
|
||||||
|
const defs = asRecord(schema.$defs) ?? {}
|
||||||
|
defs.agentOverrideConfig = referenceAgentSchema
|
||||||
|
schema.$defs = defs
|
||||||
|
|
||||||
|
customAgentsSchema.additionalProperties = { $ref: "#/$defs/agentOverrideConfig" }
|
||||||
|
|
||||||
|
return schema
|
||||||
|
}
|
||||||
|
|
||||||
export function createOhMyOpenCodeJsonSchema(): Record<string, unknown> {
|
export function createOhMyOpenCodeJsonSchema(): Record<string, unknown> {
|
||||||
const jsonSchema = z.toJSONSchema(OhMyOpenCodeConfigSchema, {
|
const jsonSchema = z.toJSONSchema(OhMyOpenCodeConfigSchema, {
|
||||||
target: "draft-7",
|
target: "draft-7",
|
||||||
unrepresentable: "any",
|
unrepresentable: "any",
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
const schema = {
|
||||||
$schema: "http://json-schema.org/draft-07/schema#",
|
$schema: "http://json-schema.org/draft-07/schema#",
|
||||||
$id: "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json",
|
$id: "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json",
|
||||||
title: "Oh My OpenCode Configuration",
|
title: "Oh My OpenCode Configuration",
|
||||||
description: "Configuration schema for oh-my-opencode plugin",
|
description: "Configuration schema for oh-my-opencode plugin",
|
||||||
...jsonSchema,
|
...jsonSchema,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return dedupeCustomAgentOverrideSchema(schema)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,9 @@ describe("schema document generation", () => {
|
|||||||
const customAgentsSchema = asRecord(rootProperties?.custom_agents)
|
const customAgentsSchema = asRecord(rootProperties?.custom_agents)
|
||||||
const customPropertyNames = asRecord(customAgentsSchema?.propertyNames)
|
const customPropertyNames = asRecord(customAgentsSchema?.propertyNames)
|
||||||
const customAdditionalProperties = asRecord(customAgentsSchema?.additionalProperties)
|
const customAdditionalProperties = asRecord(customAgentsSchema?.additionalProperties)
|
||||||
const customAgentProperties = asRecord(customAdditionalProperties?.properties)
|
const defs = asRecord(schema.$defs)
|
||||||
|
const sharedAgentOverrideSchema = asRecord(defs?.agentOverrideConfig)
|
||||||
|
const sharedAgentProperties = asRecord(sharedAgentOverrideSchema?.properties)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(agentsSchema).toBeDefined()
|
expect(agentsSchema).toBeDefined()
|
||||||
@ -26,8 +28,10 @@ describe("schema document generation", () => {
|
|||||||
expect(customPropertyNames?.pattern).toContain("[bB][uU][iI][lL][dD]")
|
expect(customPropertyNames?.pattern).toContain("[bB][uU][iI][lL][dD]")
|
||||||
expect(customPropertyNames?.pattern).toContain("[pP][lL][aA][nN]")
|
expect(customPropertyNames?.pattern).toContain("[pP][lL][aA][nN]")
|
||||||
expect(customAdditionalProperties).toBeDefined()
|
expect(customAdditionalProperties).toBeDefined()
|
||||||
expect(customAgentProperties?.model).toEqual({ type: "string" })
|
expect(customAdditionalProperties?.$ref).toBe("#/$defs/agentOverrideConfig")
|
||||||
expect(customAgentProperties?.temperature).toEqual(
|
expect(sharedAgentOverrideSchema).toBeDefined()
|
||||||
|
expect(sharedAgentProperties?.model).toEqual({ type: "string" })
|
||||||
|
expect(sharedAgentProperties?.temperature).toEqual(
|
||||||
expect.objectContaining({ type: "number" }),
|
expect.objectContaining({ type: "number" }),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user