fix(stage-ui): normalize spark:command tool schema (#1845)
This commit is contained in:
@@ -51,7 +51,7 @@
|
||||
},
|
||||
"inlinedDependencies": {
|
||||
"@electron-toolkit/preload": "3.0.2",
|
||||
"@moeru/eventa": "catalog:",
|
||||
"@moeru/eventa": "1.0.0-beta.5",
|
||||
"async-mutex": "0.5.0",
|
||||
"nanoid": [
|
||||
"5.1.11",
|
||||
|
||||
@@ -66,7 +66,7 @@ signIn:
|
||||
footer:
|
||||
prefix: Al continuar, aceptas nuestros
|
||||
terms: Términos
|
||||
and: "y"
|
||||
and: 'y'
|
||||
privacy: Política de Privacidad
|
||||
verifyEmail:
|
||||
title:
|
||||
|
||||
@@ -685,7 +685,7 @@ pages:
|
||||
empty: Здесь пока ничего нет. Добавьте одно ниже!
|
||||
add:
|
||||
title: Новый
|
||||
description: "Заполните новый сервер, затем нажмите кнопку «Сохранить и перезапустить» — он будет перемещен в «Конфигурация» выше."
|
||||
description: 'Заполните новый сервер, затем нажмите кнопку «Сохранить и перезапустить» — он будет перемещен в «Конфигурация» выше.'
|
||||
pending-badge: Не сохранено
|
||||
status:
|
||||
unknown: Не загружен
|
||||
@@ -902,7 +902,7 @@ pages:
|
||||
description: >-
|
||||
Провайдеры транскрипции (speech-to-text): Whisper.cpp, OpenAI, Azure Speech
|
||||
artistry:
|
||||
title: Artistry
|
||||
title: Artistry
|
||||
description: Поставщики моделей генерации и создания изображений, например ComfyUI, Replicate.
|
||||
items:
|
||||
comfyui:
|
||||
|
||||
@@ -685,7 +685,7 @@ pages:
|
||||
empty: 这里什么都还没有哦,在下面添加一个!
|
||||
add:
|
||||
title: 新建
|
||||
description: "填写新的服务器配置,然后点击「保存并重启」,完成后将会更新至上方的「已配置」"
|
||||
description: '填写新的服务器配置,然后点击「保存并重启」,完成后将会更新至上方的「已配置」'
|
||||
pending-badge: 未保存
|
||||
status:
|
||||
unknown: 未加载
|
||||
|
||||
@@ -178,13 +178,22 @@ export function normalizeNullableAnyOf(schema: JsonSchema): JsonSchema {
|
||||
const next: JsonSchema = { ...schema }
|
||||
|
||||
if (next.properties) {
|
||||
next.properties = Object.fromEntries(
|
||||
const properties = Object.fromEntries(
|
||||
Object.entries(next.properties).map(([key, value]) => {
|
||||
if (!isJsonSchema(value))
|
||||
return [key, value]
|
||||
return [key, normalizeNullableAnyOf(value)]
|
||||
}),
|
||||
)
|
||||
next.properties = properties
|
||||
|
||||
if (Array.isArray(next.required)) {
|
||||
const propertyNames = new Set(Object.keys(properties))
|
||||
next.required = next.required.filter(key => propertyNames.has(key))
|
||||
|
||||
if (next.required.length === 0)
|
||||
delete next.required
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(next.items)) {
|
||||
|
||||
@@ -59,9 +59,10 @@ describe('tools/character/orchestrator/spark-command', () => {
|
||||
testField: z.union([z.string(), z.null()]),
|
||||
}))
|
||||
const normalized = normalizeNullableAnyOf(schemaTestUnion as JsonSchema)
|
||||
const testField = normalized.properties?.testField as JsonSchema
|
||||
|
||||
expect((normalized.properties?.testField as JsonSchema).type).toEqual(['string', 'null'])
|
||||
expect((normalized.properties?.testField as JsonSchema).anyOf).toBeUndefined()
|
||||
expect(testField.type).toEqual(['string', 'null'])
|
||||
expect(testField.anyOf).toBeUndefined()
|
||||
})
|
||||
|
||||
it('deduplicates primitive types after normalization', async () => {
|
||||
@@ -69,9 +70,54 @@ describe('tools/character/orchestrator/spark-command', () => {
|
||||
testField: z.union([z.literal('force'), z.literal('soft'), z.literal(false)]),
|
||||
}))
|
||||
const normalized = normalizeNullableAnyOf(schemaTestUnion as JsonSchema)
|
||||
const testField = normalized.properties?.testField as JsonSchema
|
||||
|
||||
expect((normalized.properties?.testField as JsonSchema).type).toEqual(['string', 'boolean'])
|
||||
expect((normalized.properties?.testField as JsonSchema).anyOf).toBeUndefined()
|
||||
expect(testField.type).toEqual(['string', 'boolean'])
|
||||
expect(testField.anyOf).toBeUndefined()
|
||||
})
|
||||
|
||||
it('removes required keys that are not declared in sibling properties', () => {
|
||||
const normalized = normalizeNullableAnyOf({
|
||||
type: 'object',
|
||||
properties: {
|
||||
contexts: {
|
||||
anyOf: [
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
metadata: {
|
||||
anyOf: [
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
key: { type: 'string' },
|
||||
},
|
||||
required: ['key', 'value'],
|
||||
},
|
||||
},
|
||||
{ type: 'null' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type: 'null' },
|
||||
],
|
||||
},
|
||||
},
|
||||
required: ['contexts'],
|
||||
} as JsonSchema)
|
||||
|
||||
const contexts = getArraySchema(normalized.properties?.contexts as JsonSchema)
|
||||
const contextItem = contexts?.items as JsonSchema
|
||||
const metadata = getArraySchema(contextItem.properties?.metadata as JsonSchema)
|
||||
const metadataItem = metadata?.items as JsonSchema
|
||||
|
||||
expect(metadataItem.required).toEqual(['key'])
|
||||
})
|
||||
|
||||
it('should render sparkNotifyCommandItemSchema into correct schema', async () => {
|
||||
|
||||
Reference in New Issue
Block a user